diff -Nru schism-0+20110101/aclocal.m4 schism-20160521/aclocal.m4 --- schism-0+20110101/aclocal.m4 2011-01-01 21:51:30.000000000 +0000 +++ schism-20160521/aclocal.m4 1970-01-01 00:00:00.000000000 +0000 @@ -1,9208 +0,0 @@ -# generated automatically by aclocal 1.11.1 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -# This file 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. - -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, -[m4_warning([this file was generated for autoconf 2.68. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) - -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file 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. - -m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, -# Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool 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 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -]) - -# serial 57 LT_INIT - - -# LT_PREREQ(VERSION) -# ------------------ -# Complain and exit if this libtool version is less that VERSION. -m4_defun([LT_PREREQ], -[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, - [m4_default([$3], - [m4_fatal([Libtool version $1 or higher is required], - 63)])], - [$2])]) - - -# _LT_CHECK_BUILDDIR -# ------------------ -# Complain if the absolute build directory name contains unusual characters -m4_defun([_LT_CHECK_BUILDDIR], -[case `pwd` in - *\ * | *\ *) - AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; -esac -]) - - -# LT_INIT([OPTIONS]) -# ------------------ -AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT -AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -AC_BEFORE([$0], [LT_LANG])dnl -AC_BEFORE([$0], [LT_OUTPUT])dnl -AC_BEFORE([$0], [LTDL_INIT])dnl -m4_require([_LT_CHECK_BUILDDIR])dnl - -dnl Autoconf doesn't catch unexpanded LT_ macros by default: -m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl -m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl -dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 -dnl unless we require an AC_DEFUNed macro: -AC_REQUIRE([LTOPTIONS_VERSION])dnl -AC_REQUIRE([LTSUGAR_VERSION])dnl -AC_REQUIRE([LTVERSION_VERSION])dnl -AC_REQUIRE([LTOBSOLETE_VERSION])dnl -m4_require([_LT_PROG_LTMAIN])dnl - -_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) - -dnl Parse OPTIONS -_LT_SET_OPTIONS([$0], [$1]) - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -_LT_SETUP - -# Only expand once: -m4_define([LT_INIT]) -])# LT_INIT - -# Old names: -AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) -AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PROG_LIBTOOL], []) -dnl AC_DEFUN([AM_PROG_LIBTOOL], []) - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` -]) - - -# _LT_FILEUTILS_DEFAULTS -# ---------------------- -# It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. -m4_defun([_LT_FILEUTILS_DEFAULTS], -[: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} -])# _LT_FILEUTILS_DEFAULTS - - -# _LT_SETUP -# --------- -m4_defun([_LT_SETUP], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl - -_LT_DECL([], [host_alias], [0], [The host system])dnl -_LT_DECL([], [host], [0])dnl -_LT_DECL([], [host_os], [0])dnl -dnl -_LT_DECL([], [build_alias], [0], [The build system])dnl -_LT_DECL([], [build], [0])dnl -_LT_DECL([], [build_os], [0])dnl -dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -test -z "$LN_S" && LN_S="ln -s" -_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl -dnl -AC_REQUIRE([LT_CMD_MAX_LEN])dnl -_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl -_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl -dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl -m4_require([_LT_CMD_RELOAD])dnl -m4_require([_LT_CHECK_MAGIC_METHOD])dnl -m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl -m4_require([_LT_CMD_OLD_ARCHIVE])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_WITH_SYSROOT])dnl - -_LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi -]) -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -_LT_CHECK_OBJDIR - -m4_require([_LT_TAG_COMPILER])dnl - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - _LT_PATH_MAGIC - fi - ;; -esac - -# Use C for the default configuration in the libtool script -LT_SUPPORTED_TAG([CC]) -_LT_LANG_C_CONFIG -_LT_LANG_DEFAULT_CONFIG -_LT_CONFIG_COMMANDS -])# _LT_SETUP - - -# _LT_PREPARE_SED_QUOTE_VARS -# -------------------------- -# Define a few sed substitution that help us do robust quoting. -m4_defun([_LT_PREPARE_SED_QUOTE_VARS], -[# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([["`\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' -]) - -# _LT_PROG_LTMAIN -# --------------- -# Note that this code is called both from `configure', and `config.status' -# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, -# so we pass a copy along to make sure it has a sensible value anyway. -m4_defun([_LT_PROG_LTMAIN], -[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl -_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" -])# _LT_PROG_LTMAIN - - - -# So that we can recreate a full libtool script including additional -# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' -# label. - - -# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) -# ---------------------------------------- -# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL_INIT], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_INIT], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_INIT]) - - -# _LT_CONFIG_LIBTOOL([COMMANDS]) -# ------------------------------ -# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. -m4_define([_LT_CONFIG_LIBTOOL], -[m4_ifval([$1], - [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], - [$1 -])])]) - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) - - -# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) -# ----------------------------------------------------- -m4_defun([_LT_CONFIG_SAVE_COMMANDS], -[_LT_CONFIG_LIBTOOL([$1]) -_LT_CONFIG_LIBTOOL_INIT([$2]) -]) - - -# _LT_FORMAT_COMMENT([COMMENT]) -# ----------------------------- -# Add leading comment marks to the start of each line, and a trailing -# full-stop to the whole comment if one is not present already. -m4_define([_LT_FORMAT_COMMENT], -[m4_ifval([$1], [ -m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], - [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) -)]) - - - - - -# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) -# ------------------------------------------------------------------- -# CONFIGNAME is the name given to the value in the libtool script. -# VARNAME is the (base) name used in the configure script. -# VALUE may be 0, 1 or 2 for a computed quote escaped value based on -# VARNAME. Any other value will be used directly. -m4_define([_LT_DECL], -[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], - [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], - [m4_ifval([$1], [$1], [$2])]) - lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) - m4_ifval([$4], - [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) - lt_dict_add_subkey([lt_decl_dict], [$2], - [tagged?], [m4_ifval([$5], [yes], [no])])]) -]) - - -# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) -# -------------------------------------------------------- -m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) - - -# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_tag_varnames], -[_lt_decl_filter([tagged?], [yes], $@)]) - - -# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) -# --------------------------------------------------------- -m4_define([_lt_decl_filter], -[m4_case([$#], - [0], [m4_fatal([$0: too few arguments: $#])], - [1], [m4_fatal([$0: too few arguments: $#: $1])], - [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], - [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], - [lt_dict_filter([lt_decl_dict], $@)])[]dnl -]) - - -# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) -# -------------------------------------------------- -m4_define([lt_decl_quote_varnames], -[_lt_decl_filter([value], [1], $@)]) - - -# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_dquote_varnames], -[_lt_decl_filter([value], [2], $@)]) - - -# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) -# --------------------------------------------------- -m4_define([lt_decl_varnames_tagged], -[m4_assert([$# <= 2])dnl -_$0(m4_quote(m4_default([$1], [[, ]])), - m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), - m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) -m4_define([_lt_decl_varnames_tagged], -[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) - - -# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) -# ------------------------------------------------ -m4_define([lt_decl_all_varnames], -[_$0(m4_quote(m4_default([$1], [[, ]])), - m4_if([$2], [], - m4_quote(lt_decl_varnames), - m4_quote(m4_shift($@))))[]dnl -]) -m4_define([_lt_decl_all_varnames], -[lt_join($@, lt_decl_varnames_tagged([$1], - lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl -]) - - -# _LT_CONFIG_STATUS_DECLARE([VARNAME]) -# ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME -# must have a single quote delimited value for this to work. -m4_define([_LT_CONFIG_STATUS_DECLARE], -[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) - - -# _LT_CONFIG_STATUS_DECLARATIONS -# ------------------------------ -# We delimit libtool config variables with single quotes, so when -# we write them to config.status, we have to be sure to quote all -# embedded single quotes properly. In configure, this macro expands -# each variable declared with _LT_DECL (and _LT_TAGDECL) into: -# -# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' -m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], -[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), - [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAGS -# ---------------- -# Output comment and list of tags supported by the script -m4_defun([_LT_LIBTOOL_TAGS], -[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl -]) - - -# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) -# ----------------------------------- -# Extract the dictionary values for VARNAME (optionally with TAG) and -# expand to a commented shell variable setting: -# -# # Some comment about what VAR is for. -# visible_name=$lt_internal_name -m4_define([_LT_LIBTOOL_DECLARE], -[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], - [description])))[]dnl -m4_pushdef([_libtool_name], - m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl -m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), - [0], [_libtool_name=[$]$1], - [1], [_libtool_name=$lt_[]$1], - [2], [_libtool_name=$lt_[]$1], - [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl -m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl -]) - - -# _LT_LIBTOOL_CONFIG_VARS -# ----------------------- -# Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' -# script. Tagged libtool config variables (even for the LIBTOOL CONFIG -# section) are produced by _LT_LIBTOOL_TAG_VARS. -m4_defun([_LT_LIBTOOL_CONFIG_VARS], -[m4_foreach([_lt_var], - m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) - - -# _LT_LIBTOOL_TAG_VARS(TAG) -# ------------------------- -m4_define([_LT_LIBTOOL_TAG_VARS], -[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), - [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) - - -# _LT_TAGVAR(VARNAME, [TAGNAME]) -# ------------------------------ -m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) - - -# _LT_CONFIG_COMMANDS -# ------------------- -# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of -# variables for single and double quote escaping we saved from calls -# to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated -# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. -m4_defun([_LT_CONFIG_COMMANDS], -[AC_PROVIDE_IFELSE([LT_OUTPUT], - dnl If the libtool generation code has been placed in $CONFIG_LT, - dnl instead of duplicating it all over again into config.status, - dnl then we will have config.status run $CONFIG_LT later, so it - dnl needs to know what name is stored there: - [AC_CONFIG_COMMANDS([libtool], - [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], - dnl If the libtool generation code is destined for config.status, - dnl expand the accumulated commands and init code now: - [AC_CONFIG_COMMANDS([libtool], - [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) -])#_LT_CONFIG_COMMANDS - - -# Initialize. -m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], -[ - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -_LT_CONFIG_STATUS_DECLARATIONS -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$[]1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_quote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in lt_decl_all_varnames([[ \ -]], lt_decl_dquote_varnames); do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -_LT_OUTPUT_LIBTOOL_INIT -]) - -# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) -# ------------------------------------ -# Generate a child script FILE with all initialization necessary to -# reuse the environment learned by the parent script, and make the -# file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this -# macro, additional text can be appended to FILE to form the body of -# the child script. The macro ends with non-zero status if the -# file could not be fully written (such as if the disk is full). -m4_ifdef([AS_INIT_GENERATED], -[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], -[m4_defun([_LT_GENERATED_FILE_INIT], -[m4_require([AS_PREPARE])]dnl -[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl -[lt_write_fail=0 -cat >$1 <<_ASEOF || lt_write_fail=1 -#! $SHELL -# Generated by $as_me. -$2 -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$1 <<\_ASEOF || lt_write_fail=1 -AS_SHELL_SANITIZE -_AS_PREPARE -exec AS_MESSAGE_FD>&1 -_ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl -m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT - -# LT_OUTPUT -# --------- -# This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation -# tests. -AC_DEFUN([LT_OUTPUT], -[: ${CONFIG_LT=./config.lt} -AC_MSG_NOTICE([creating $CONFIG_LT]) -_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], -[# Run this file to recreate a libtool stub with the current configuration.]) - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec AS_MESSAGE_LOG_FD>>config.log -{ - echo - AS_BOX([Running $as_me.]) -} >&AS_MESSAGE_LOG_FD - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $[0] [[OPTIONS]] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl -m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) -configured by $[0], generated by m4_PACKAGE_STRING. - -Copyright (C) 2010 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $[#] != 0 -do - case $[1] in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; - - *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; - esac - shift -done - -if $lt_cl_silent; then - exec AS_MESSAGE_FD>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF -_LT_OUTPUT_LIBTOOL_COMMANDS_INIT -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -AC_MSG_NOTICE([creating $ofile]) -_LT_OUTPUT_LIBTOOL_COMMANDS -AS_EXIT(0) -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec AS_MESSAGE_LOG_FD>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec AS_MESSAGE_LOG_FD>>config.log -$lt_cl_success || AS_EXIT(1) -])# LT_OUTPUT - - -# _LT_CONFIG(TAG) -# --------------- -# If TAG is the built-in tag, create an initial libtool script with a -# default configuration from the untagged config vars. Otherwise add code -# to config.status for appending the configuration named by TAG from the -# matching tagged config vars. -m4_defun([_LT_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_CONFIG_SAVE_COMMANDS([ - m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl - m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -_LT_COPYING -_LT_LIBTOOL_TAGS - -# ### BEGIN LIBTOOL CONFIG -_LT_LIBTOOL_CONFIG_VARS -_LT_LIBTOOL_TAG_VARS -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - _LT_PROG_LTMAIN - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - _LT_PROG_REPLACE_SHELLFNS - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -], -[cat <<_LT_EOF >> "$ofile" - -dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded -dnl in a comment (ie after a #). -# ### BEGIN LIBTOOL TAG CONFIG: $1 -_LT_LIBTOOL_TAG_VARS(_LT_TAG) -# ### END LIBTOOL TAG CONFIG: $1 -_LT_EOF -])dnl /m4_if -], -[m4_if([$1], [], [ - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile'], []) -])dnl /_LT_CONFIG_SAVE_COMMANDS -])# _LT_CONFIG - - -# LT_SUPPORTED_TAG(TAG) -# --------------------- -# Trace this macro to discover what tags are supported by the libtool -# --tag option, using: -# autoconf --trace 'LT_SUPPORTED_TAG:$1' -AC_DEFUN([LT_SUPPORTED_TAG], []) - - -# C support is built-in for now -m4_define([_LT_LANG_C_enabled], []) -m4_define([_LT_TAGS], []) - - -# LT_LANG(LANG) -# ------------- -# Enable libtool support for the given language if not already enabled. -AC_DEFUN([LT_LANG], -[AC_BEFORE([$0], [LT_OUTPUT])dnl -m4_case([$1], - [C], [_LT_LANG(C)], - [C++], [_LT_LANG(CXX)], - [Java], [_LT_LANG(GCJ)], - [Fortran 77], [_LT_LANG(F77)], - [Fortran], [_LT_LANG(FC)], - [Windows Resource], [_LT_LANG(RC)], - [m4_ifdef([_LT_LANG_]$1[_CONFIG], - [_LT_LANG($1)], - [m4_fatal([$0: unsupported language: "$1"])])])dnl -])# LT_LANG - - -# _LT_LANG(LANGNAME) -# ------------------ -m4_defun([_LT_LANG], -[m4_ifdef([_LT_LANG_]$1[_enabled], [], - [LT_SUPPORTED_TAG([$1])dnl - m4_append([_LT_TAGS], [$1 ])dnl - m4_define([_LT_LANG_]$1[_enabled], [])dnl - _LT_LANG_$1_CONFIG($1)])dnl -])# _LT_LANG - - -# _LT_LANG_DEFAULT_CONFIG -# ----------------------- -m4_defun([_LT_LANG_DEFAULT_CONFIG], -[AC_PROVIDE_IFELSE([AC_PROG_CXX], - [LT_LANG(CXX)], - [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) - -AC_PROVIDE_IFELSE([AC_PROG_F77], - [LT_LANG(F77)], - [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) - -AC_PROVIDE_IFELSE([AC_PROG_FC], - [LT_LANG(FC)], - [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) - -dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal -dnl pulling things in needlessly. -AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [LT_LANG(GCJ)], - [AC_PROVIDE_IFELSE([LT_PROG_GCJ], - [LT_LANG(GCJ)], - [m4_ifdef([AC_PROG_GCJ], - [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([A][M_PROG_GCJ], - [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) - m4_ifdef([LT_PROG_GCJ], - [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) - -AC_PROVIDE_IFELSE([LT_PROG_RC], - [LT_LANG(RC)], - [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) -])# _LT_LANG_DEFAULT_CONFIG - -# Obsolete macros: -AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) -AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) -AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) -AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) -AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_CXX], []) -dnl AC_DEFUN([AC_LIBTOOL_F77], []) -dnl AC_DEFUN([AC_LIBTOOL_FC], []) -dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) -dnl AC_DEFUN([AC_LIBTOOL_RC], []) - - -# _LT_TAG_COMPILER -# ---------------- -m4_defun([_LT_TAG_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl -_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl -_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl -_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_TAG_COMPILER - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -m4_defun([_LT_COMPILER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -m4_defun([_LT_LINKER_BOILERPLATE], -[m4_require([_LT_DECL_SED])dnl -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* -])# _LT_LINKER_BOILERPLATE - -# _LT_REQUIRED_DARWIN_CHECKS -# ------------------------- -m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ - case $host_os in - rhapsody* | darwin*) - AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) - AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) - AC_CHECK_TOOL([LIPO], [lipo], [:]) - AC_CHECK_TOOL([OTOOL], [otool], [:]) - AC_CHECK_TOOL([OTOOL64], [otool64], [:]) - _LT_DECL([], [DSYMUTIL], [1], - [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) - _LT_DECL([], [NMEDIT], [1], - [Tool to change global to local symbols on Mac OS X]) - _LT_DECL([], [LIPO], [1], - [Tool to manipulate fat objects and archives on Mac OS X]) - _LT_DECL([], [OTOOL], [1], - [ldd/readelf like tool for Mach-O binaries on Mac OS X]) - _LT_DECL([], [OTOOL64], [1], - [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) - - AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], - [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], - [lt_cv_ld_exported_symbols_list], - [lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [lt_cv_ld_exported_symbols_list=yes], - [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" - ]) - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], - [lt_cv_ld_force_load=no - cat > conftest.c << _LT_EOF -int forced_loaded() { return 2;} -_LT_EOF - echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD - echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD - $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD - cat > conftest.c << _LT_EOF -int main() { return 0;} -_LT_EOF - echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD - $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err - _lt_result=$? - if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then - lt_cv_ld_force_load=yes - else - cat conftest.err >&AS_MESSAGE_LOG_FD - fi - rm -f conftest.err libconftest.a conftest conftest.c - rm -rf conftest.dSYM - ]) - case $host_os in - rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac -]) - - -# _LT_DARWIN_LINKER_FEATURES -# -------------------------- -# Checks for linker and compiler features on darwin -m4_defun([_LT_DARWIN_LINKER_FEATURES], -[ - m4_require([_LT_REQUIRED_DARWIN_CHECKS]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_automatic, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='' - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" - fi -],[]) - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi -]) - -# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) -# ---------------------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -# Store the results from the different compilers for each TAGNAME. -# Allow to override them for all tags through lt_cv_aix_libpath. -m4_defun([_LT_SYS_MODULE_PATH_AIX], -[m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then - aix_libpath=$lt_cv_aix_libpath -else - AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], - [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ - lt_aix_libpath_sed='[ - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\([^ ]*\) *$/\1/ - p - } - }]' - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - # Check for a 64-bit object if we didn't find anything. - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` - fi],[]) - if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" - fi - ]) - aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) -fi -])# _LT_SYS_MODULE_PATH_AIX - - -# _LT_SHELL_INIT(ARG) -# ------------------- -m4_define([_LT_SHELL_INIT], -[m4_divert_text([M4SH-INIT], [$1 -])])# _LT_SHELL_INIT - - - -# _LT_PROG_ECHO_BACKSLASH -# ----------------------- -# Find how we can fake an echo command that does not interpret backslash. -# In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). -m4_defun([_LT_PROG_ECHO_BACKSLASH], -[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -AC_MSG_CHECKING([how to print strings]) -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$[]1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -case "$ECHO" in - printf*) AC_MSG_RESULT([printf]) ;; - print*) AC_MSG_RESULT([print -r]) ;; - *) AC_MSG_RESULT([cat]) ;; -esac - -m4_ifdef([_AS_DETECT_SUGGESTED], -[_AS_DETECT_SUGGESTED([ - test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( - ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO - ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - PATH=/empty FPATH=/empty; export PATH FPATH - test "X`printf %s $ECHO`" = "X$ECHO" \ - || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) - -_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) -_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) -])# _LT_PROG_ECHO_BACKSLASH - - -# _LT_WITH_SYSROOT -# ---------------- -AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) -AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], -[], [with_sysroot=no]) - -dnl lt_sysroot will always be passed unquoted. We quote it here -dnl in case the user passed a directory name. -lt_sysroot= -case ${with_sysroot} in #( - yes) - if test "$GCC" = yes; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` - fi - ;; #( - /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` - ;; #( - no|'') - ;; #( - *) - AC_MSG_RESULT([${with_sysroot}]) - AC_MSG_ERROR([The sysroot must be an absolute path.]) - ;; -esac - - AC_MSG_RESULT([${lt_sysroot:-no}]) -_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) - -# _LT_ENABLE_LOCK -# --------------- -m4_defun([_LT_ENABLE_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AS_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" -])# _LT_ENABLE_LOCK - - -# _LT_PROG_AR -# ----------- -m4_defun([_LT_PROG_AR], -[AC_CHECK_TOOLS(AR, [ar], false) -: ${AR=ar} -: ${AR_FLAGS=cru} -_LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) - -AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], - [lt_cv_ar_at_file=no - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [echo conftest.$ac_objext > conftest.lst - lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then - # Ensure the archiver fails upon bogus file names. - rm -f conftest.$ac_objext libconftest.a - AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then - lt_cv_ar_at_file=@ - fi - fi - rm -f conftest.* libconftest.a - ]) - ]) - -if test "x$lt_cv_ar_at_file" = xno; then - archiver_list_spec= -else - archiver_list_spec=$lt_cv_ar_at_file -fi -_LT_DECL([], [archiver_list_spec], [1], - [How to feed a file listing to the archiver]) -])# _LT_PROG_AR - - -# _LT_CMD_OLD_ARCHIVE -# ------------------- -m4_defun([_LT_CMD_OLD_ARCHIVE], -[_LT_PROG_AR - -AC_CHECK_TOOL(STRIP, strip, :) -test -z "$STRIP" && STRIP=: -_LT_DECL([], [STRIP], [1], [A symbol stripping program]) - -AC_CHECK_TOOL(RANLIB, ranlib, :) -test -z "$RANLIB" && RANLIB=: -_LT_DECL([], [RANLIB], [1], - [Commands used to install an old-style archive]) - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -case $host_os in - darwin*) - lock_old_archive_extraction=yes ;; - *) - lock_old_archive_extraction=no ;; -esac -_LT_DECL([], [old_postinstall_cmds], [2]) -_LT_DECL([], [old_postuninstall_cmds], [2]) -_LT_TAGDECL([], [old_archive_cmds], [2], - [Commands used to build an old-style archive]) -_LT_DECL([], [lock_old_archive_extraction], [0], - [Whether to use a lock for old archive extraction]) -])# _LT_CMD_OLD_ARCHIVE - - -# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([_LT_COMPILER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $RM conftest* -]) - -if test x"[$]$2" = xyes; then - m4_if([$5], , :, [$5]) -else - m4_if([$6], , :, [$6]) -fi -])# _LT_COMPILER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) - - -# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------- -# Check whether the given linker option works -AC_DEFUN([_LT_LINKER_OPTION], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_SED])dnl -AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - m4_if([$4], , :, [$4]) -else - m4_if([$5], , :, [$5]) -fi -])# _LT_LINKER_OPTION - -# Old name: -AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) - - -# LT_CMD_MAX_LEN -#--------------- -AC_DEFUN([LT_CMD_MAX_LEN], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - mint*) - # On MiNT this can take a long time and run out of memory. - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ - = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -max_cmd_len=$lt_cv_sys_max_cmd_len -_LT_DECL([], [max_cmd_len], [0], - [What is the maximum length of a command?]) -])# LT_CMD_MAX_LEN - -# Old name: -AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) - - -# _LT_HEADER_DLFCN -# ---------------- -m4_defun([_LT_HEADER_DLFCN], -[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl -])# _LT_HEADER_DLFCN - - -# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ---------------------------------------------------------------- -m4_defun([_LT_TRY_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -[#line $LINENO "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -/* When -fvisbility=hidden is used, assume the code has been annotated - correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); -#endif - -int fnord () { return 42; } -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else - { - if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - else puts (dlerror ()); - } - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -}] -_LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_dlunknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_TRY_DLOPEN_SELF - - -# LT_SYS_DLOPEN_SELF -# ------------------ -AC_DEFUN([LT_SYS_DLOPEN_SELF], -[m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -_LT_DECL([dlopen_support], [enable_dlopen], [0], - [Whether dlopen is supported]) -_LT_DECL([dlopen_self], [enable_dlopen_self], [0], - [Whether dlopen of programs is supported]) -_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], - [Whether dlopen of statically linked programs is supported]) -])# LT_SYS_DLOPEN_SELF - -# Old name: -AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) - - -# _LT_COMPILER_C_O([TAGNAME]) -# --------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler. -# This macro does not hard code the compiler like AC_PROG_CC_C_O. -m4_defun([_LT_COMPILER_C_O], -[m4_require([_LT_DECL_SED])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* -]) -_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], - [Does compiler simultaneously support -c and -o options?]) -])# _LT_COMPILER_C_O - - -# _LT_COMPILER_FILE_LOCKS([TAGNAME]) -# ---------------------------------- -# Check to see if we can do hard links to lock some files if needed -m4_defun([_LT_COMPILER_FILE_LOCKS], -[m4_require([_LT_ENABLE_LOCK])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -_LT_COMPILER_C_O([$1]) - -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) -])# _LT_COMPILER_FILE_LOCKS - - -# _LT_CHECK_OBJDIR -# ---------------- -m4_defun([_LT_CHECK_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -_LT_DECL([], [objdir], [0], - [The name of the directory that contains temporary libtool files])dnl -m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) -])# _LT_CHECK_OBJDIR - - -# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) -# -------------------------------------- -# Check hardcoding attributes. -m4_defun([_LT_LINKER_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || - test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -_LT_TAGDECL([], [hardcode_action], [0], - [How to hardcode a shared library path into an executable]) -])# _LT_LINKER_HARDCODE_LIBPATH - - -# _LT_CMD_STRIPLIB -# ---------------- -m4_defun([_LT_CMD_STRIPLIB], -[m4_require([_LT_DECL_EGREP]) -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) -_LT_DECL([], [striplib], [1]) -])# _LT_CMD_STRIPLIB - - -# _LT_SYS_DYNAMIC_LINKER([TAG]) -# ----------------------------- -# PORTME Fill in your ld.so characteristics -m4_defun([_LT_SYS_DYNAMIC_LINKER], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_OBJDUMP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CHECK_SHELL_FEATURES])dnl -AC_MSG_CHECKING([dynamic linker characteristics]) -m4_if([$1], - [], [ -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` - case $lt_search_path_spec in - *\;*) - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` - ;; - *) - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` - ;; - esac - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[[lt_foo]]++; } - if (lt_freq[[lt_foo]] == 1) { print lt_foo; } -}'` - # AWK program above erroneously prepends '/' to C:/dos/paths - # for these hosts. - case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; - esac - sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[[4-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$cc_basename in - yes,*) - # gcc - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - dynamic_linker='Win32 ld.exe' - ;; - - *,cl*) - # Native MSVC - libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' - - case $build_os in - mingw*) - sys_lib_search_path_spec= - lt_save_ifs=$IFS - IFS=';' - for lt_path in $LIB - do - IFS=$lt_save_ifs - # Let DOS variable expansion print the short 8.3 style file name. - lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` - sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" - done - IFS=$lt_save_ifs - # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` - ;; - cygwin*) - # Convert to unix form, then to dos form, then back to unix form - # but this time dos style (no spaces!) so that the unix form looks - # like /cygdrive/c/PROGRA~1:/cygdr... - sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` - sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` - sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - ;; - *) - sys_lib_search_path_spec="$LIB" - if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # FIXME: find the short name or the path components, as spaces are - # common. (e.g. "Program Files" -> "PROGRA~1") - ;; - esac - - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - dynamic_linker='Win32 link.exe' - ;; - - *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - dynamic_linker='Win32 ld.exe' - ;; - esac - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' -m4_if([$1], [],[ - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ - freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -haiku*) - version_type=linux - need_lib_prefix=no - need_version=no - dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555, ... - postinstall_cmds='chmod 555 $lib' - # or fails outright, so override atomically: - install_override_mode=555 - ;; - -interix[[3-9]]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - - # Some binutils ld are patched to set DT_RUNPATH - AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], - [lt_cv_shlibpath_overrides_runpath=no - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ - LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" - AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], - [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], - [lt_cv_shlibpath_overrides_runpath=yes])]) - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - ]) - shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - -_LT_DECL([], [variables_saved_for_relink], [1], - [Variables whose values should be saved in libtool wrapper scripts and - restored at link time]) -_LT_DECL([], [need_lib_prefix], [0], - [Do we need the "lib" prefix for modules?]) -_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) -_LT_DECL([], [version_type], [0], [Library versioning type]) -_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) -_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) -_LT_DECL([], [shlibpath_overrides_runpath], [0], - [Is shlibpath searched before the hard-coded library search path?]) -_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) -_LT_DECL([], [library_names_spec], [1], - [[List of archive names. First name is the real one, the rest are links. - The last name is the one that the linker finds with -lNAME]]) -_LT_DECL([], [soname_spec], [1], - [[The coded name of the library, if different from the real name]]) -_LT_DECL([], [install_override_mode], [1], - [Permission mode override for installation of shared libraries]) -_LT_DECL([], [postinstall_cmds], [2], - [Command to use after installation of a shared archive]) -_LT_DECL([], [postuninstall_cmds], [2], - [Command to use after uninstallation of a shared archive]) -_LT_DECL([], [finish_cmds], [2], - [Commands used to finish a libtool library installation in a directory]) -_LT_DECL([], [finish_eval], [1], - [[As "finish_cmds", except a single script fragment to be evaled but - not shown]]) -_LT_DECL([], [hardcode_into_libs], [0], - [Whether we should hardcode library paths into libraries]) -_LT_DECL([], [sys_lib_search_path_spec], [2], - [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) -])# _LT_SYS_DYNAMIC_LINKER - - -# _LT_PATH_TOOL_PREFIX(TOOL) -# -------------------------- -# find a file program which can recognize shared library -AC_DEFUN([_LT_PATH_TOOL_PREFIX], -[m4_require([_LT_DECL_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="m4_if([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -_LT_DECL([], [MAGIC_CMD], [0], - [Used to examine libraries when file_magic_cmd begins with "file"])dnl -])# _LT_PATH_TOOL_PREFIX - -# Old name: -AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) - - -# _LT_PATH_MAGIC -# -------------- -# find a file program which can recognize a shared library -m4_defun([_LT_PATH_MAGIC], -[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# _LT_PATH_MAGIC - - -# LT_PATH_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([LT_PATH_LD], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PROG_ECHO_BACKSLASH])dnl - -AC_ARG_WITH([gnu-ld], - [AS_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no])dnl - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc*) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -haiku*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[[3-9]]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) - -file_magic_glob= -want_nocaseglob=no -if test "$build" = "$host"; then - case $host_os in - mingw* | pw32*) - if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then - want_nocaseglob=yes - else - file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` - fi - ;; - esac -fi - -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -_LT_DECL([], [deplibs_check_method], [1], - [Method to check whether dependent libraries are shared objects]) -_LT_DECL([], [file_magic_cmd], [1], - [Command to use when deplibs_check_method = "file_magic"]) -_LT_DECL([], [file_magic_glob], [1], - [How to find potential files when deplibs_check_method = "file_magic"]) -_LT_DECL([], [want_nocaseglob], [1], - [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) -])# _LT_CHECK_MAGIC_METHOD - - -# LT_PATH_NM -# ---------- -# find the pathname to a BSD- or MS-compatible name lister -AC_DEFUN([LT_PATH_NM], -[AC_REQUIRE([AC_PROG_CC])dnl -AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$DUMPBIN"; then : - # Let the user override the test. - else - AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in - *COFF*) - DUMPBIN="$DUMPBIN -symbols" - ;; - *) - DUMPBIN=: - ;; - esac - fi - AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm -AC_SUBST([NM]) -_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl - -AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], - [lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&AS_MESSAGE_LOG_FD - (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) - cat conftest.out >&AS_MESSAGE_LOG_FD - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest*]) -])# LT_PATH_NM - -# Old names: -AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) -AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AM_PROG_NM], []) -dnl AC_DEFUN([AC_PROG_NM], []) - -# _LT_CHECK_SHAREDLIB_FROM_LINKLIB -# -------------------------------- -# how to determine the name of the shared library -# associated with a specific link library. -# -- PORTME fill in with the dynamic library characteristics -m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], -[m4_require([_LT_DECL_EGREP]) -m4_require([_LT_DECL_OBJDUMP]) -m4_require([_LT_DECL_DLLTOOL]) -AC_CACHE_CHECK([how to associate runtime and link libraries], -lt_cv_sharedlib_from_linklib_cmd, -[lt_cv_sharedlib_from_linklib_cmd='unknown' - -case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL - case `$DLLTOOL --help 2>&1` in - *--identify-strict*) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib - ;; - *) - lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback - ;; - esac - ;; -*) - # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" - ;; -esac -]) -sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd -test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - -_LT_DECL([], [sharedlib_from_linklib_cmd], [1], - [Command to associate shared and link libraries]) -])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB - - -# _LT_PATH_MANIFEST_TOOL -# ---------------------- -# locate the manifest tool -m4_defun([_LT_PATH_MANIFEST_TOOL], -[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) -test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no - echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD - $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out - cat conftest.err >&AS_MESSAGE_LOG_FD - if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes - fi - rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then - MANIFEST_TOOL=: -fi -_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl -])# _LT_PATH_MANIFEST_TOOL - - -# LT_LIB_M -# -------- -# check for math library -AC_DEFUN([LT_LIB_M], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -AC_SUBST([LIBM]) -])# LT_LIB_M - -# Old name: -AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([AC_CHECK_LIBM], []) - - -# _LT_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------- -m4_defun([_LT_COMPILER_NO_RTTI], -[m4_require([_LT_TAG_COMPILER])dnl - -_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - case $cc_basename in - nvcc*) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; - *) - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; - esac - - _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], - [Compiler flag to turn off builtin functions]) -])# _LT_COMPILER_NO_RTTI - - -# _LT_CMD_GLOBAL_SYMBOLS -# ---------------------- -m4_defun([_LT_CMD_GLOBAL_SYMBOLS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([LT_PATH_NM])dnl -AC_REQUIRE([LT_PATH_LD])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_TAG_COMPILER])dnl - -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris*) - symcode='[[BDRT]]' - ;; -sco3.2v5*) - symcode='[[DT]]' - ;; -sysv4.2uw2*) - symcode='[[DT]]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[[ABDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK ['"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx]" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT@&t@_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT@&t@_DLSYM_CONST -#else -# define LT@&t@_DLSYM_CONST const -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -LT@&t@_DLSYM_CONST struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[[]] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_globsym_save_LIBS=$LIBS - lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS=$lt_globsym_save_LIBS - CFLAGS=$lt_globsym_save_CFLAGS - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi - -# Response file support. -if test "$lt_cv_nm_interface" = "MS dumpbin"; then - nm_file_list_spec='@' -elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then - nm_file_list_spec='@' -fi - -_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], - [Take the output of nm and produce a listing of raw symbols and C names]) -_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], - [Transform the output of nm in a proper C declaration]) -_LT_DECL([global_symbol_to_c_name_address], - [lt_cv_sys_global_symbol_to_c_name_address], [1], - [Transform the output of nm in a C name address pair]) -_LT_DECL([global_symbol_to_c_name_address_lib_prefix], - [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], - [Transform the output of nm in a C name address pair when lib prefix is needed]) -_LT_DECL([], [nm_file_list_spec], [1], - [Specify filename containing input files for $NM]) -]) # _LT_CMD_GLOBAL_SYMBOLS - - -# _LT_COMPILER_PIC([TAGNAME]) -# --------------------------- -m4_defun([_LT_COMPILER_PIC], -[m4_require([_LT_TAG_COMPILER])dnl -_LT_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_TAGVAR(lt_prog_compiler_static, $1)= - -m4_if([$1], [CXX], [ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix[[4-9]]*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - interix*) - # This is c89, which is MS Visual C++ (no shared libs) - # Anyone wants to do a port? - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - icpc* ) - # Intel C++, used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) - # IBM XL 8.0, 9.0 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - esac - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - *qnx* | *nto*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - case $cc_basename in - CC*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - vxworks*) - ;; - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - haiku*) - # PIC is the default for Haiku. - # The "-static" flag exists, but is broken. - _LT_TAGVAR(lt_prog_compiler_static, $1)= - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - interix[[3-9]]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - - case $cc_basename in - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - m4_if([$1], [GCJ], [], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) - ;; - - hpux9* | hpux10* | hpux11*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' - _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' - ;; - nagfor*) - # NAG Fortran compiler - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - xl* | bgxl* | bgf* | mpixl*) - # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ F* | *Sun*Fortran*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='' - ;; - *Sun\ C*) - # Sun C 5.9 - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - esac - ;; - - newsos6) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - rdos*) - _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - solaris*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - unicos*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" - ;; -esac - -AC_CACHE_CHECK([for $compiler option to produce PIC], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], - [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) -_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], - [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], - [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], - [Additional compiler flags for building library objects]) - -_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], - [How to pass a linker flag through the compiler]) -# -# Check to make sure the static flag actually works. -# -wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" -_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], - _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), - $lt_tmp_static_flag, - [], - [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) -_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], - [Compiler flag to prevent dynamic linking]) -])# _LT_COMPILER_PIC - - -# _LT_LINKER_SHLIBS([TAGNAME]) -# ---------------------------- -# See if the linker supports building shared libraries. -m4_defun([_LT_LINKER_SHLIBS], -[AC_REQUIRE([LT_PATH_LD])dnl -AC_REQUIRE([LT_PATH_NM])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_DECL_SED])dnl -m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl -m4_require([_LT_TAG_COMPILER])dnl -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -m4_if([$1], [CXX], [ - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - case $host_os in - aix[[4-9]]*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw* | cegcc*) - case $cc_basename in - cl*) ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - ;; - esac - ;; - *) - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -], [ - runpath_var= - _LT_TAGVAR(allow_undefined_flag, $1)= - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(archive_cmds, $1)= - _LT_TAGVAR(archive_expsym_cmds, $1)= - _LT_TAGVAR(compiler_needs_object, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(hardcode_automatic, $1)=no - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_TAGVAR(hardcode_libdir_separator, $1)= - _LT_TAGVAR(hardcode_minus_L, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_TAGVAR(inherit_rpath, $1)=no - _LT_TAGVAR(link_all_deplibs, $1)=unknown - _LT_TAGVAR(module_cmds, $1)= - _LT_TAGVAR(module_expsym_cmds, $1)= - _LT_TAGVAR(old_archive_from_new_cmds, $1)= - _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_TAGVAR(thread_safe_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. -dnl Note also adjust exclude_expsyms for C++ above. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_TAGVAR(ld_shlibs, $1)=yes - - # On some targets, GNU ld is compatible enough with the native linker - # that we're better off using the native interface for both. - lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then - case $host_os in - aix*) - # The AIX port of GNU ld has always aspired to compatibility - # with the native linker. However, as the warning in the GNU ld - # block says, versions before 2.19.5* couldn't really create working - # shared libraries, regardless of the interface used. - case `$LD -v 2>&1` in - *\ \(GNU\ Binutils\)\ 2.19.5*) ;; - *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; - *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - ;; - *) - lt_use_gnu_ld_interface=yes - ;; - esac - fi - - if test "$lt_use_gnu_ld_interface" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *GNU\ gold*) supports_anon_versioning=yes ;; - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[[3-9]]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.19, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to install binutils -*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. -*** You will then need to restart the configuration process. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' - _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag=' $pic_flag' - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95* | pgfortran*) - # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - _LT_TAGVAR(whole_archive_flag_spec, $1)= - tmp_sharedflag='--shared' ;; - xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf* | bgf* | bgxlf* | mpixlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) - _LT_TAGVAR(ld_shlibs, $1)=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - sunos4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='' - ;; - m68k) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - ;; - - bsdi[[45]]*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - case $cc_basename in - cl*) - # Native MSVC - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # Assume MSVC wrapper - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - esac - ;; - - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - m4_if($1, [], [ - # Older versions of the 11.00 compiler do not understand -b yet - # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - _LT_LINKER_OPTION([if $CC understands -b], - _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], - [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) - ;; - esac - fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - # This should be the same for all languages, so no per-tag cache variable. - AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], - [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - AC_LINK_IFELSE( - [AC_LANG_SOURCE( - [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], - [C++], [[int foo (void) { return 0; }]], - [Fortran 77], [[ - subroutine foo - end]], - [Fortran], [[ - subroutine foo - end]])])], - [lt_cv_irix_exported_symbol=yes], - [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - fi - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - os2*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - solaris*) - _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - fi - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' - ;; - esac - fi - fi -]) -AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld - -_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl -_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl -_LT_DECL([], [extract_expsyms_cmds], [2], - [The commands to extract the exported symbol list from a shared archive]) - -# -# Do we need to explicitly link libc? -# -case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_CACHE_CHECK([whether -lc should be explicitly linked in], - [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), - [$RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) - pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) - _LT_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no - else - lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - ]) - _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) - ;; - esac - fi - ;; -esac - -_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], - [Whether or not to add -lc for building shared libraries]) -_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], - [enable_shared_with_static_runtimes], [0], - [Whether or not to disallow shared libs when runtime libs are static]) -_LT_TAGDECL([], [export_dynamic_flag_spec], [1], - [Compiler flag to allow reflexive dlopens]) -_LT_TAGDECL([], [whole_archive_flag_spec], [1], - [Compiler flag to generate shared objects directly from archives]) -_LT_TAGDECL([], [compiler_needs_object], [1], - [Whether the compiler copes with passing no objects directly]) -_LT_TAGDECL([], [old_archive_from_new_cmds], [2], - [Create an old-style archive from a shared archive]) -_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], - [Create a temporary old-style archive to link instead of a shared archive]) -_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) -_LT_TAGDECL([], [archive_expsym_cmds], [2]) -_LT_TAGDECL([], [module_cmds], [2], - [Commands used to build a loadable module if different from building - a shared archive.]) -_LT_TAGDECL([], [module_expsym_cmds], [2]) -_LT_TAGDECL([], [with_gnu_ld], [1], - [Whether we are building with GNU ld or not]) -_LT_TAGDECL([], [allow_undefined_flag], [1], - [Flag that allows shared libraries with undefined symbols to be built]) -_LT_TAGDECL([], [no_undefined_flag], [1], - [Flag that enforces no undefined symbols]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], - [Flag to hardcode $libdir into a binary during linking. - This must work even if $libdir does not exist]) -_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], - [[If ld is used when linking, flag to hardcode $libdir into a binary - during linking. This must work even if $libdir does not exist]]) -_LT_TAGDECL([], [hardcode_libdir_separator], [1], - [Whether we need a single "-rpath" flag with a separated argument]) -_LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary]) -_LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes - DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the - library is relocated]) -_LT_TAGDECL([], [hardcode_minus_L], [0], - [Set to "yes" if using the -LDIR flag during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_shlibpath_var], [0], - [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR - into the resulting binary]) -_LT_TAGDECL([], [hardcode_automatic], [0], - [Set to "yes" if building a shared library automatically hardcodes DIR - into the library and all subsequent libraries and executables linked - against it]) -_LT_TAGDECL([], [inherit_rpath], [0], - [Set to yes if linker adds runtime paths of dependent libraries - to runtime path list]) -_LT_TAGDECL([], [link_all_deplibs], [0], - [Whether libtool must link a program against all its dependency libraries]) -_LT_TAGDECL([], [always_export_symbols], [0], - [Set to "yes" if exported symbols are required]) -_LT_TAGDECL([], [export_symbols_cmds], [2], - [The commands to list exported symbols]) -_LT_TAGDECL([], [exclude_expsyms], [1], - [Symbols that should not be listed in the preloaded symbols]) -_LT_TAGDECL([], [include_expsyms], [1], - [Symbols that must always be exported]) -_LT_TAGDECL([], [prelink_cmds], [2], - [Commands necessary for linking programs (against libraries) with templates]) -_LT_TAGDECL([], [postlink_cmds], [2], - [Commands necessary for finishing linking programs]) -_LT_TAGDECL([], [file_list_spec], [1], - [Specify filename containing input files]) -dnl FIXME: Not yet implemented -dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], -dnl [Compiler flag to generate thread safe objects]) -])# _LT_LINKER_SHLIBS - - -# _LT_LANG_C_CONFIG([TAG]) -# ------------------------ -# Ensure that the configuration variables for a C compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_C_CONFIG], -[m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - -_LT_TAG_COMPILER -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - LT_SYS_DLOPEN_SELF - _LT_CMD_STRIPLIB - - # Report which library types will actually be built - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_CONFIG($1) -fi -AC_LANG_POP -CC="$lt_save_CC" -])# _LT_LANG_C_CONFIG - - -# _LT_LANG_CXX_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a C++ compiler are suitably -# defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. -m4_defun([_LT_LANG_CXX_CONFIG], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -m4_require([_LT_DECL_EGREP])dnl -m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -else - _lt_caught_CXX_error=yes -fi - -AC_LANG_PUSH(C++) -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(compiler_needs_object, $1)=no -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the CXX compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="int some_variable = 0;" - - # Code to be used in simple link tests - lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC=$CC - lt_save_CFLAGS=$CFLAGS - lt_save_LD=$LD - lt_save_GCC=$GCC - GCC=$GXX - lt_save_with_gnu_ld=$with_gnu_ld - lt_save_path_LD=$lt_cv_path_LD - if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx - else - $as_unset lt_cv_prog_gnu_ld - fi - if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX - else - $as_unset lt_cv_path_LD - fi - test -z "${LDCXX+set}" || LD=$LDCXX - CC=${CXX-"c++"} - CFLAGS=$CXXFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - # We don't want -fno-exception when compiling C++ code, so set the - # no_builtin_flag separately - if test "$GXX" = yes; then - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - else - _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - fi - - if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - LT_PATH_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - GXX=no - with_gnu_ld=no - wlarc= - fi - - # PORTME: fill in a description of your system's C++ link characteristics - AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) - _LT_TAGVAR(ld_shlibs, $1)=yes - case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aix[[4-9]]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_TAGVAR(archive_cmds, $1)='' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - _LT_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to - # export. - _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty - # executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then - # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - else - # Exported symbols can be pulled into shared objects from archives - _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' - fi - _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - cygwin* | mingw* | pw32* | cegcc*) - case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='@' - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' - # The linker will not automatically build a static lib if we build a DLL. - # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - # Don't use ranlib - _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' - _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' - ;; - *) - # g++ - # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' - _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(always_export_symbols, $1)=no - _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - darwin* | rhapsody*) - _LT_DARWIN_LINKER_FEATURES($1) - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before - # switch to ELF - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - freebsd-elf*) - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - - freebsd* | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - gnu*) - ;; - - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - - hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*|ia64*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - *) - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - interix[[3-9]]*) - _LT_TAGVAR(hardcode_direct, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' - fi - fi - _LT_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(inherit_rpath, $1)=yes - ;; - - linux* | k*bsd*-gnu | kopensolaris*-gnu) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc* | ecpc* ) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC* | pgcpp*) - # Portland Group C++ compiler - case `$CC -V` in - *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) - _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' - _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' - _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' - ;; - xl* | mpixl* | bgxl*) - # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' - _LT_TAGVAR(compiler_needs_object, $1)=yes - - # Not sure whether something based on - # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 - # would be better. - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - esac - ;; - esac - ;; - - lynxos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - m88k*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - - *nto* | *qnx*) - _LT_TAGVAR(ld_shlibs, $1)=yes - ;; - - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd=func_echo_all - else - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - case $host in - osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; - *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; - esac - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - case $host in - osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - ;; - *) - _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - case $host in - osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - ;; - esac - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - - psos*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - solaris*) - case $cc_basename in - CC* | sunCC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' - ;; - esac - _LT_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='func_echo_all' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' - fi - - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - ;; - esac - fi - ;; - esac - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' - _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' - _LT_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - case $cc_basename in - CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" - _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - ;; - - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - vxworks*) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - *) - # FIXME: insert proper C++ library support - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - esac - - AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS - LDCXX=$LD - LD=$lt_save_LD - GCC=$lt_save_GCC - with_gnu_ld=$lt_save_with_gnu_ld - lt_cv_path_LDCXX=$lt_cv_path_LD - lt_cv_path_LD=$lt_save_path_LD - lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld - lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes - -AC_LANG_POP -])# _LT_LANG_CXX_CONFIG - - -# _LT_FUNC_STRIPNAME_CNF -# ---------------------- -# func_stripname_cnf prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# -# This function is identical to the (non-XSI) version of func_stripname, -# except this one can be used by m4 code that may be executed by configure, -# rather than the libtool script. -m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl -AC_REQUIRE([_LT_DECL_SED]) -AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) -func_stripname_cnf () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname_cnf -])# _LT_FUNC_STRIPNAME_CNF - -# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) -# --------------------------------- -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -m4_defun([_LT_SYS_HIDDEN_LIBDEPS], -[m4_require([_LT_FILEUTILS_DEFAULTS])dnl -AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl -# Dependencies to place before and after the object being linked: -_LT_TAGVAR(predep_objects, $1)= -_LT_TAGVAR(postdep_objects, $1)= -_LT_TAGVAR(predeps, $1)= -_LT_TAGVAR(postdeps, $1)= -_LT_TAGVAR(compiler_lib_search_path, $1)= - -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF -int a; -void foo (void) { a = 0; } -_LT_EOF -], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -_LT_EOF -], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -_LT_EOF -], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF - subroutine foo - implicit none - integer a - a=0 - return - end -_LT_EOF -], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -_LT_EOF -]) - -_lt_libdeps_save_CFLAGS=$CFLAGS -case "$CC $CFLAGS " in #( -*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; -*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -esac - -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" || - test $p = "-R"; then - prev=$p - continue - fi - - # Expand the sysroot to ease extracting the directories later. - if test -z "$prev"; then - case $p in - -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; - -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; - -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; - esac - fi - case $p in - =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; - esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in - -L | -R) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - prev= - ;; - - *.lto.$objext) ;; # Ignore GCC LTO objects - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" - else - _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" - else - _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$RM -f confest.$objext -CFLAGS=$_lt_libdeps_save_CFLAGS - -# PORTME: override above test on systems where it is broken -m4_if([$1], [CXX], -[case $host_os in -interix[[3-9]]*) - # Interix 3.5 installs completely hosed .la files for C++, so rather than - # hack all around it, let's just trust "g++" to DTRT. - _LT_TAGVAR(predep_objects,$1)= - _LT_TAGVAR(postdep_objects,$1)= - _LT_TAGVAR(postdeps,$1)= - ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; -esac -]) - -case " $_LT_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac - _LT_TAGVAR(compiler_lib_search_dirs, $1)= -if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` -fi -_LT_TAGDECL([], [compiler_lib_search_dirs], [1], - [The directories searched by this compiler when creating a shared library]) -_LT_TAGDECL([], [predep_objects], [1], - [Dependencies to place before and after the objects being linked to - create a shared library]) -_LT_TAGDECL([], [postdep_objects], [1]) -_LT_TAGDECL([], [predeps], [1]) -_LT_TAGDECL([], [postdeps], [1]) -_LT_TAGDECL([], [compiler_lib_search_path], [1], - [The library search path used internally by the compiler when linking - a shared library]) -])# _LT_SYS_HIDDEN_LIBDEPS - - -# _LT_LANG_F77_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for a Fortran 77 compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_F77_CONFIG], -[AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then - _lt_disable_F77=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the F77 compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${F77-"f77"} - CFLAGS=$FFLAGS - compiler=$CC - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - GCC=$G77 - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes - -AC_LANG_POP -])# _LT_LANG_F77_CONFIG - - -# _LT_LANG_FC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for a Fortran compiler are -# suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_FC_CONFIG], -[AC_LANG_PUSH(Fortran) - -if test -z "$FC" || test "X$FC" = "Xno"; then - _lt_disable_FC=yes -fi - -_LT_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_TAGVAR(allow_undefined_flag, $1)= -_LT_TAGVAR(always_export_symbols, $1)=no -_LT_TAGVAR(archive_expsym_cmds, $1)= -_LT_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_TAGVAR(hardcode_direct, $1)=no -_LT_TAGVAR(hardcode_direct_absolute, $1)=no -_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_TAGVAR(hardcode_libdir_separator, $1)= -_LT_TAGVAR(hardcode_minus_L, $1)=no -_LT_TAGVAR(hardcode_automatic, $1)=no -_LT_TAGVAR(inherit_rpath, $1)=no -_LT_TAGVAR(module_cmds, $1)= -_LT_TAGVAR(module_expsym_cmds, $1)= -_LT_TAGVAR(link_all_deplibs, $1)=unknown -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds -_LT_TAGVAR(no_undefined_flag, $1)= -_LT_TAGVAR(whole_archive_flag_spec, $1)= -_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for fc test sources. -ac_ext=${ac_fc_srcext-f} - -# Object file extension for compiled fc test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# No sense in running all these tests if we already determined that -# the FC compiler isn't working. Some variables (like enable_shared) -# are currently assumed to apply to all compilers on this platform, -# and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then - # Code to be used in simple compile tests - lt_simple_compile_test_code="\ - subroutine t - return - end -" - - # Code to be used in simple link tests - lt_simple_link_test_code="\ - program t - end -" - - # ltmain only uses $CC for tagged configurations so make sure $CC is set. - _LT_TAG_COMPILER - - # save warnings/boilerplate of simple test code - _LT_COMPILER_BOILERPLATE - _LT_LINKER_BOILERPLATE - - # Allow CC to be a program name with arguments. - lt_save_CC="$CC" - lt_save_GCC=$GCC - lt_save_CFLAGS=$CFLAGS - CC=${FC-"f95"} - CFLAGS=$FCFLAGS - compiler=$CC - GCC=$ac_cv_fc_compiler_gnu - - _LT_TAGVAR(compiler, $1)=$CC - _LT_CC_BASENAME([$compiler]) - - if test -n "$compiler"; then - AC_MSG_CHECKING([if libtool supports shared libraries]) - AC_MSG_RESULT([$can_build_shared]) - - AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - AC_MSG_RESULT([$enable_shared]) - - AC_MSG_CHECKING([whether to build static libraries]) - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - AC_MSG_RESULT([$enable_static]) - - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" - - ## CAVEAT EMPTOR: - ## There is no encapsulation within the following macros, do not change - ## the running order or otherwise move them around unless you know exactly - ## what you are doing... - _LT_SYS_HIDDEN_LIBDEPS($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_SYS_DYNAMIC_LINKER($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) - fi # test -n "$compiler" - - GCC=$lt_save_GCC - CC=$lt_save_CC - CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes - -AC_LANG_POP -])# _LT_LANG_FC_CONFIG - - -# _LT_LANG_GCJ_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Java Compiler compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GCJ_CONFIG], -[AC_REQUIRE([LT_PROG_GCJ])dnl -AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GCJ-"gcj"} -CFLAGS=$GCJFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GCJ_CONFIG - - -# _LT_LANG_RC_CONFIG([TAG]) -# ------------------------- -# Ensure that the configuration variables for the Windows resource compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_RC_CONFIG], -[AC_REQUIRE([LT_PROG_RC])dnl -AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC= -CC=${RC-"windres"} -CFLAGS= -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -if test -n "$compiler"; then - : - _LT_CONFIG($1) -fi - -GCC=$lt_save_GCC -AC_LANG_RESTORE -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_RC_CONFIG - - -# LT_PROG_GCJ -# ----------- -AC_DEFUN([LT_PROG_GCJ], -[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], - [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], - [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS)])])[]dnl -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_GCJ], []) - - -# LT_PROG_RC -# ---------- -AC_DEFUN([LT_PROG_RC], -[AC_CHECK_TOOL(RC, windres,) -]) - -# Old name: -AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_RC], []) - - -# _LT_DECL_EGREP -# -------------- -# If we don't have a new enough Autoconf to choose the best grep -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_EGREP], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_REQUIRE([AC_PROG_FGREP])dnl -test -z "$GREP" && GREP=grep -_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) -_LT_DECL([], [EGREP], [1], [An ERE matcher]) -_LT_DECL([], [FGREP], [1], [A literal string matcher]) -dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too -AC_SUBST([GREP]) -]) - - -# _LT_DECL_OBJDUMP -# -------------- -# If we don't have a new enough Autoconf to choose the best objdump -# available, choose the one first in the user's PATH. -m4_defun([_LT_DECL_OBJDUMP], -[AC_CHECK_TOOL(OBJDUMP, objdump, false) -test -z "$OBJDUMP" && OBJDUMP=objdump -_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) -AC_SUBST([OBJDUMP]) -]) - -# _LT_DECL_DLLTOOL -# ---------------- -# Ensure DLLTOOL variable is set. -m4_defun([_LT_DECL_DLLTOOL], -[AC_CHECK_TOOL(DLLTOOL, dlltool, false) -test -z "$DLLTOOL" && DLLTOOL=dlltool -_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) -AC_SUBST([DLLTOOL]) -]) - -# _LT_DECL_SED -# ------------ -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -m4_defun([_LT_DECL_SED], -[AC_PROG_SED -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" -_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) -_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], - [Sed that helps us avoid accidentally triggering echo(1) options like -n]) -])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) -dnl aclocal-1.4 backwards compatibility: -dnl AC_DEFUN([LT_AC_PROG_SED], []) - - -# _LT_CHECK_SHELL_FEATURES -# ------------------------ -# Find out whether the shell is Bourne or XSI compatible, -# or has some other useful features. -m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi -_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac -_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl -_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl -])# _LT_CHECK_SHELL_FEATURES - - -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - -# _LT_PATH_CONVERSION_FUNCTIONS -# ----------------------------- -# Determine which file name conversion functions should be used by -# func_to_host_file (and, implicitly, by func_to_host_path). These are needed -# for certain cross-compile configurations and native mingw. -m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_MSG_CHECKING([how to convert $build file names to $host format]) -AC_CACHE_VAL(lt_cv_to_host_file_cmd, -[case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 - ;; - esac - ;; - *-*-cygwin* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin - ;; - *-*-cygwin* ) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; - * ) # otherwise, assume *nix - lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin - ;; - esac - ;; - * ) # unhandled hosts (and "normal" native builds) - lt_cv_to_host_file_cmd=func_convert_file_noop - ;; -esac -]) -to_host_file_cmd=$lt_cv_to_host_file_cmd -AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) -_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], - [0], [convert $build file names to $host format])dnl - -AC_MSG_CHECKING([how to convert $build file names to toolchain format]) -AC_CACHE_VAL(lt_cv_to_tool_file_cmd, -[#assume ordinary cross tools, or native build. -lt_cv_to_tool_file_cmd=func_convert_file_noop -case $host in - *-*-mingw* ) - case $build in - *-*-mingw* ) # actually msys - lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 - ;; - esac - ;; -esac -]) -to_tool_file_cmd=$lt_cv_to_tool_file_cmd -AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) -_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], - [0], [convert $build files to toolchain format])dnl -])# _LT_PATH_CONVERSION_FUNCTIONS - -# Configure paths for SDL -# Sam Lantinga 9/21/99 -# stolen from Manish Singh -# stolen back from Frank Belew -# stolen from Manish Singh -# Shamelessly stolen from Owen Taylor - -dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) -dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS -dnl -AC_DEFUN([AM_PATH_SDL], -[dnl -dnl Get the cflags and libraries from the sdl-config script -dnl -AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], - sdl_prefix="$withval", sdl_prefix="") -AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], - sdl_exec_prefix="$withval", sdl_exec_prefix="") -AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], - , enable_sdltest=yes) - - if test x$sdl_exec_prefix != x ; then - sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config - fi - fi - if test x$sdl_prefix != x ; then - sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_prefix/bin/sdl-config - fi - fi - - as_save_PATH="$PATH" - if test "x$prefix" != xNONE; then - PATH="$prefix/bin:$prefix/usr/bin:$PATH" - fi - AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) - PATH="$as_save_PATH" - min_sdl_version=ifelse([$1], ,0.11.0,$1) - AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) - no_sdl="" - if test "$SDL_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` - - sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` - sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` - sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` - if test "x$enable_sdltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_CXXFLAGS="$CXXFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" -dnl -dnl Now check if the installed SDL is sufficiently new. (Also sanity -dnl checks the results of sdl-config to some extent -dnl - rm -f conf.sdltest - AC_TRY_RUN([ -#include -#include -#include -#include "SDL.h" - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_sdl_version"); - exit(1); - } - - if (($sdl_major_version > major) || - (($sdl_major_version == major) && ($sdl_minor_version > minor)) || - (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); - printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); - printf("*** to point to the correct copy of sdl-config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - -],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_sdl" = x ; then - AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) - else - AC_MSG_RESULT(no) - if test "$SDL_CONFIG" = "no" ; then - echo "*** The sdl-config script installed by SDL could not be found" - echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the SDL_CONFIG environment variable to the" - echo "*** full path to sdl-config." - else - if test -f conf.sdltest ; then - : - else - echo "*** Could not run SDL test program, checking why..." - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" - AC_TRY_LINK([ -#include -#include "SDL.h" - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main -], [ return 0; ], - [ echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding SDL or finding the wrong" - echo "*** version of SDL. If it is not finding SDL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], - [ echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means SDL was incorrectly installed" - echo "*** or that you have moved SDL since it was installed. In the latter case, you" - echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - SDL_CFLAGS="" - SDL_LIBS="" - ifelse([$3], , :, [$3]) - fi - AC_SUBST(SDL_CFLAGS) - AC_SUBST(SDL_LIBS) - rm -f conf.sdltest -]) - -# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. -# -# This file 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. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.11' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.11.1], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.11.1])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file 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. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 -# Free Software Foundation, Inc. -# -# This file 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. - -# serial 9 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 -# Free Software Foundation, Inc. -# -# This file 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. - -# serial 10 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file 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. - -#serial 5 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. -# -# This file 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. - -# serial 16 - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl -]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The `parallel-tests' driver may need to know about EXEEXT, so add the -dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -]) - -dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. -# -# This file 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. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST(install_sh)]) - -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file 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. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. -# -# This file 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. - -# serial 4 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file 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. - -# serial 6 - -# AM_PROG_CC_C_O -# -------------- -# Like AC_PROG_CC_C_O, but changed for automake. -AC_DEFUN([AM_PROG_CC_C_O], -[AC_REQUIRE([AC_PROG_CC_C_O])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -dnl Make sure AC_PROG_CC is never called again, or it will override our -dnl setting of CC. -m4_define([AC_PROG_CC], - [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file 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. - -# serial 6 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# -# This file 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. - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. -# -# This file 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. - -# serial 4 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 -# Free Software Foundation, Inc. -# -# This file 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. - -# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# --------------------------------------------------------------------------- -# Adds support for distributing Python modules and packages. To -# install modules, copy them to $(pythondir), using the python_PYTHON -# automake variable. To install a package with the same name as the -# automake package, install to $(pkgpythondir), or use the -# pkgpython_PYTHON automake variable. -# -# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as -# locations to install python extension modules (shared libraries). -# Another macro is required to find the appropriate flags to compile -# extension modules. -# -# If your package is configured with a different prefix to python, -# users will have to add the install directory to the PYTHONPATH -# environment variable, or create a .pth file (see the python -# documentation for details). -# -# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will -# cause an error if the version of python installed on the system -# doesn't meet the requirement. MINIMUM-VERSION should consist of -# numbers and dots only. -AC_DEFUN([AM_PATH_PYTHON], - [ - dnl Find a Python interpreter. Python versions prior to 2.0 are not - dnl supported. (2.0 was released on October 16, 2000). - m4_define_default([_AM_PYTHON_INTERPRETER_LIST], - [python python2 python3 python3.0 python2.5 python2.4 python2.3 python2.2 dnl -python2.1 python2.0]) - - m4_if([$1],[],[ - dnl No version check is needed. - # Find any Python interpreter. - if test -z "$PYTHON"; then - AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) - fi - am_display_PYTHON=python - ], [ - dnl A version check is needed. - if test -n "$PYTHON"; then - # If the user set $PYTHON, use it and don't search something else. - AC_MSG_CHECKING([whether $PYTHON version >= $1]) - AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], - [AC_MSG_RESULT(yes)], - [AC_MSG_ERROR(too old)]) - am_display_PYTHON=$PYTHON - else - # Otherwise, try each interpreter until we find one that satisfies - # VERSION. - AC_CACHE_CHECK([for a Python interpreter with version >= $1], - [am_cv_pathless_PYTHON],[ - for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do - test "$am_cv_pathless_PYTHON" = none && break - AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) - done]) - # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. - if test "$am_cv_pathless_PYTHON" = none; then - PYTHON=: - else - AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) - fi - am_display_PYTHON=$am_cv_pathless_PYTHON - fi - ]) - - if test "$PYTHON" = :; then - dnl Run any user-specified action, or abort. - m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) - else - - dnl Query Python for its version number. Getting [:3] seems to be - dnl the best way to do this; it's what "site.py" does in the standard - dnl library. - - AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], - [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) - AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) - - dnl Use the values of $prefix and $exec_prefix for the corresponding - dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made - dnl distinct variables so they can be overridden if need be. However, - dnl general consensus is that you shouldn't need this ability. - - AC_SUBST([PYTHON_PREFIX], ['${prefix}']) - AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) - - dnl At times (like when building shared libraries) you may want - dnl to know which OS platform Python thinks this is. - - AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], - [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) - AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) - - - dnl Set up 4 directories: - - dnl pythondir -- where to install python scripts. This is the - dnl site-packages directory, not the python standard library - dnl directory like in previous automake betas. This behavior - dnl is more consistent with lispdir.m4 for example. - dnl Query distutils for this directory. distutils does not exist in - dnl Python 1.5, so we fall back to the hardcoded directory if it - dnl doesn't work. - AC_CACHE_CHECK([for $am_display_PYTHON script directory], - [am_cv_python_pythondir], - [if test "x$prefix" = xNONE - then - am_py_prefix=$ac_default_prefix - else - am_py_prefix=$prefix - fi - am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null || - echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"` - case $am_cv_python_pythondir in - $am_py_prefix*) - am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` - am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` - ;; - *) - case $am_py_prefix in - /usr|/System*) ;; - *) - am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac - ]) - AC_SUBST([pythondir], [$am_cv_python_pythondir]) - - dnl pkgpythondir -- $PACKAGE directory under pythondir. Was - dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is - dnl more consistent with the rest of automake. - - AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) - - dnl pyexecdir -- directory for installing python extension modules - dnl (shared libraries) - dnl Query distutils for this directory. distutils does not exist in - dnl Python 1.5, so we fall back to the hardcoded directory if it - dnl doesn't work. - AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], - [am_cv_python_pyexecdir], - [if test "x$exec_prefix" = xNONE - then - am_py_exec_prefix=$am_py_prefix - else - am_py_exec_prefix=$exec_prefix - fi - am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null || - echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"` - case $am_cv_python_pyexecdir in - $am_py_exec_prefix*) - am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` - am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` - ;; - *) - case $am_py_exec_prefix in - /usr|/System*) ;; - *) - am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac - ]) - AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) - - dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) - - AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) - - dnl Run any user-specified action. - $2 - fi - -]) - - -# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) -# --------------------------------------------------------------------------- -# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. -# Run ACTION-IF-FALSE otherwise. -# This test uses sys.hexversion instead of the string equivalent (first -# word of sys.version), in order to cope with versions such as 2.2c1. -# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). -AC_DEFUN([AM_PYTHON_CHECK_VERSION], - [prog="import sys -# split strings by '.' and convert to numeric. Append some zeros -# because we need at least 4 digits for the hex conversion. -# map returns an iterator in Python 3.0 and a list in 2.x -minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] -minverhex = 0 -# xrange is not present in Python 3.0 and range returns an iterator -for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] -sys.exit(sys.hexversion < minverhex)" - AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file 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. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 -# Free Software Foundation, Inc. -# -# This file 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. - -# serial 5 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; -esac - -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file 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. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. -# -# This file 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. - -# serial 2 - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file 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. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - diff -Nru schism-0+20110101/compile schism-20160521/compile --- schism-0+20110101/compile 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/compile 1970-01-01 00:00:00.000000000 +0000 @@ -1,143 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. - -scriptversion=2009-10-06.20; # UTC - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software -# Foundation, Inc. -# Written by Tom Tromey . -# -# 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. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; -esac - -ofile= -cfile= -eat= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` - -# Create the lock directory. -# Note: use `[/\\:.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - test "$cofile" = "$ofile" || mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# 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: diff -Nru schism-0+20110101/config.guess schism-20160521/config.guess --- schism-0+20110101/config.guess 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/config.guess 1970-01-01 00:00:00.000000000 +0000 @@ -1,1501 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. - -timestamp='2009-11-20' - -# This file 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 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# 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 Per Bothner. Please send patches (context -# diff format) to and include a ChangeLog -# entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[456]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-unknown-linux-gnu - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - padre:Linux:*:*) - echo sparc-unknown-linux-gnu - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff -Nru schism-0+20110101/config.h.in schism-20160521/config.h.in --- schism-0+20110101/config.h.in 2011-01-01 21:51:42.000000000 +0000 +++ schism-20160521/config.h.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,226 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Define to 1 if you have the `asprintf' function. */ -#undef HAVE_ASPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_BYTESWAP_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the `dup' function. */ -#undef HAVE_DUP - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the `fnmatch' function. */ -#undef HAVE_FNMATCH - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `Xv' library (-lXv). */ -#undef HAVE_LIBXV - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LINUX_FB_H - -/* Define to 1 if you have the `log2' function. */ -#undef HAVE_LOG2 - -/* Define to 1 if you have the `memcmp' function. */ -#undef HAVE_MEMCMP - -/* Define to 1 if you have the `memmove' function. */ -#undef HAVE_MEMMOVE - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mkstemp' function. */ -#undef HAVE_MKSTEMP - -/* Define to 1 if you have the `mmap' function. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#undef HAVE_NDIR_H - -/* Define to 1 if you have the `nice' function. */ -#undef HAVE_NICE - -/* Define to 1 if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define to 1 if you have the `strcasestr' function. */ -#undef HAVE_STRCASESTR - -/* Define to 1 if you have the `strchr' function. */ -#undef HAVE_STRCHR - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the `stricmp' function. */ -#undef HAVE_STRICMP - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strncasecmp' function. */ -#undef HAVE_STRNCASECMP - -/* Define to 1 if you have the `strnicmp' function. */ -#undef HAVE_STRNICMP - -/* Define to 1 if you have the `strptime' function. */ -#undef HAVE_STRPTIME - -/* Define to 1 if you have the `strtol' function. */ -#undef HAVE_STRTOL - -/* Define to 1 if you have the `strverscmp' function. */ -#undef HAVE_STRVERSCMP - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_DIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_IOCTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_KD_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOUNDCARD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `unsetenv' function. */ -#undef HAVE_UNSETENV - -/* Define to 1 if you have the `vasprintf' function. */ -#undef HAVE_VASPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINSOCK2_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINSOCK_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_EXTENSIONS_XVLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XKBLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X11_XLIB_H - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to 1 if your declares `struct tm'. */ -#undef TM_IN_SYS_TIME - -/* Define to 1 if SDL's OpenGL works */ -#undef USE_OPENGL - -/* Version number of package */ -#undef VERSION - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - -/* Define to 1 if the X Window System is missing or not being used. */ -#undef X_DISPLAY_MISSING - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `long int' if does not define. */ -#undef off_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t diff -Nru schism-0+20110101/config.sub schism-20160521/config.sub --- schism-0+20110101/config.sub 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/config.sub 1970-01-01 00:00:00.000000000 +0000 @@ -1,1705 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. - -timestamp='2009-11-20' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# 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. - - -# Please send patches to . Submit a context -# diff and a properly formatted GNU ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | picochip) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze) - basic_machine=microblaze-xilinx - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tile*) - basic_machine=tile-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff -Nru schism-0+20110101/configure schism-20160521/configure --- schism-0+20110101/configure 2011-01-01 21:51:31.000000000 +0000 +++ schism-20160521/configure 1970-01-01 00:00:00.000000000 +0000 @@ -1,9032 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for schismtracker 20110101. -# -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - # We cannot yet assume a decent shell, so we have to provide a - # neutralization value for shells without unset; and this also - # works around shells that cannot unset nonexistent variables. - # Preserve -v and -x to the replacement shell. - BASH_ENV=/dev/null - ENV=/dev/null - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV - export CONFIG_SHELL - case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; - esac - exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='schismtracker' -PACKAGE_TARNAME='schismtracker' -PACKAGE_VERSION='20110101' -PACKAGE_STRING='schismtracker 20110101' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -ac_unique_file="schism/main.c" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -USE_MERCURIAL_FALSE -USE_MERCURIAL_TRUE -OBJCFLAGS -OBJC -USE_NETWORK_FALSE -USE_NETWORK_TRUE -USE_XV_FALSE -USE_XV_TRUE -USE_X11_FALSE -USE_X11_TRUE -X_EXTRA_LIBS -X_LIBS -X_PRE_LIBS -X_CFLAGS -XMKMF -USE_ALSA_DLTRICK_FALSE -USE_ALSA_DLTRICK_TRUE -USE_ALSA_FALSE -USE_ALSA_TRUE -USE_WII_FALSE -USE_WII_TRUE -USE_WIN32_FALSE -USE_WIN32_TRUE -am__fastdepOBJC_FALSE -am__fastdepOBJC_TRUE -USE_MACOSX_FALSE -USE_MACOSX_TRUE -LIBM -USE_OSS_FALSE -USE_OSS_TRUE -USE_MMAP_FALSE -USE_MMAP_TRUE -NEED_MKSTEMP_FALSE -NEED_MKSTEMP_TRUE -NEED_STRPTIME_FALSE -NEED_STRPTIME_TRUE -NEED_MEMCMP_FALSE -NEED_MEMCMP_TRUE -NEED_VASPRINTF_FALSE -NEED_VASPRINTF_TRUE -NEED_ASPRINTF_FALSE -NEED_ASPRINTF_TRUE -SDL_LIBS -SDL_CFLAGS -SDL_CONFIG -EGREP -GREP -pkgpyexecdir -pyexecdir -pkgpythondir -pythondir -PYTHON_PLATFORM -PYTHON_EXEC_PREFIX -PYTHON_PREFIX -PYTHON_VERSION -PYTHON -HAVE_WINDRES_FALSE -HAVE_WINDRES_TRUE -WINDRES -LN_S -CPP -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_os -target_vendor -target_cpu -target -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_dependency_tracking -with_sdl_prefix -with_sdl_exec_prefix -enable_sdltest -with_x -enable_mercurial -enable_extra_opt -enable_all_warnings -enable_debug -enable_profiling -enable_ludicrous_mode -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -XMKMF' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures schismtracker 20110101 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/schismtracker] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -X features: - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] - --target=TARGET configure for building compilers for TARGET [HOST] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of schismtracker 20110101:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --disable-sdltest Do not try to compile and run a test SDL program - --enable-mercurial Use Mercurial for version/timestamps - --enable-extra-opt Add extra optimizations - --enable-all-warnings Enable ridiculous compiler warnings - --enable-debug Enable debug flags - --enable-profiling Enable profiling flags (slows things down) - --enable-ludicrous-mode Enable all warnings, and treat as errors - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-sdl-prefix=PFX Prefix where SDL is installed (optional) - --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) - --with-x use the X Window System - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - XMKMF Path to xmkmf, Makefile generator for X Window System - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -schismtracker configure 20110101 -generated by GNU Autoconf 2.68 - -Copyright (C) 2010 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - $as_test_x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by schismtracker $as_me 20110101, which was -generated by GNU Autoconf 2.68. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 -$as_echo_n "checking target system type... " >&6; } -if ${ac_cv_target+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$target_alias" = x; then - ac_cv_target=$ac_cv_host -else - ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 -$as_echo "$ac_cv_target" >&6; } -case $ac_cv_target in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; -esac -target=$ac_cv_target -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_target -shift -target_cpu=$1 -target_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -target_os=$* -IFS=$ac_save_IFS -case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac - - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -test -n "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- -machtype="$target_cpu" - -am__api_version='1.11' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; -esac - -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='schismtracker' - VERSION='20110101' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - - -ac_config_headers="$ac_config_headers config.h" - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -if test "x$CC" != xcc; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 -$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 -$as_echo_n "checking whether cc understands -c and -o together... " >&6; } -fi -set dummy $CC; ac_cc=`$as_echo "$2" | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; -then - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && - test -f conftest2.$ac_objext && { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; - then - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o -if test "$am_t" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 -$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } -if ${ac_cv_prog_cc_c99+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c99=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -#include - -// Check varargs macros. These examples are taken from C99 6.10.3.5. -#define debug(...) fprintf (stderr, __VA_ARGS__) -#define showlist(...) puts (#__VA_ARGS__) -#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) -static void -test_varargs_macros (void) -{ - int x = 1234; - int y = 5678; - debug ("Flag"); - debug ("X = %d\n", x); - showlist (The first, second, and third items.); - report (x>y, "x is %d but y is %d", x, y); -} - -// Check long long types. -#define BIG64 18446744073709551615ull -#define BIG32 4294967295ul -#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) -#if !BIG_OK - your preprocessor is broken; -#endif -#if BIG_OK -#else - your preprocessor is broken; -#endif -static long long int bignum = -9223372036854775807LL; -static unsigned long long int ubignum = BIG64; - -struct incomplete_array -{ - int datasize; - double data[]; -}; - -struct named_init { - int number; - const wchar_t *name; - double average; -}; - -typedef const char *ccp; - -static inline int -test_restrict (ccp restrict text) -{ - // See if C++-style comments work. - // Iterate through items via the restricted pointer. - // Also check for declarations in for loops. - for (unsigned int i = 0; *(text+i) != '\0'; ++i) - continue; - return 0; -} - -// Check varargs and va_copy. -static void -test_varargs (const char *format, ...) -{ - va_list args; - va_start (args, format); - va_list args_copy; - va_copy (args_copy, args); - - const char *str; - int number; - float fnumber; - - while (*format) - { - switch (*format++) - { - case 's': // string - str = va_arg (args_copy, const char *); - break; - case 'd': // int - number = va_arg (args_copy, int); - break; - case 'f': // float - fnumber = va_arg (args_copy, double); - break; - default: - break; - } - } - va_end (args_copy); - va_end (args); -} - -int -main () -{ - - // Check bool. - _Bool success = false; - - // Check restrict. - if (test_restrict ("String literal") == 0) - success = true; - char *restrict newvar = "Another string"; - - // Check varargs. - test_varargs ("s, d' f .", "string", 65, 34.234); - test_varargs_macros (); - - // Check flexible array members. - struct incomplete_array *ia = - malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); - ia->datasize = 10; - for (int i = 0; i < ia->datasize; ++i) - ia->data[i] = i * 1.234; - - // Check named initializers. - struct named_init ni = { - .number = 34, - .name = L"Test wide string", - .average = 543.34343, - }; - - ni.number = 58; - - int dynamic_array[ni.number]; - dynamic_array[ni.number - 1] = 543; - - // work around unused variable warnings - return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' - || dynamic_array[ni.number - 1] != 543); - - ; - return 0; -} -_ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -xc99=all -qlanglvl=extc99 -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c99=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c99" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c99" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c99" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 -$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c99" != xno; then : - -fi - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. -set dummy ${ac_tool_prefix}windres; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINDRES+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$WINDRES"; then - ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_WINDRES="${ac_tool_prefix}windres" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -WINDRES=$ac_cv_prog_WINDRES -if test -n "$WINDRES"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 -$as_echo "$WINDRES" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_WINDRES"; then - ac_ct_WINDRES=$WINDRES - # Extract the first word of "windres", so it can be a program name with args. -set dummy windres; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_WINDRES"; then - ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_WINDRES="windres" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES -if test -n "$ac_ct_WINDRES"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 -$as_echo "$ac_ct_WINDRES" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_WINDRES" = x; then - WINDRES="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - WINDRES=$ac_ct_WINDRES - fi -else - WINDRES="$ac_cv_prog_WINDRES" -fi - - - if test "x$WINDRES" != "x"; then - HAVE_WINDRES_TRUE= - HAVE_WINDRES_FALSE='#' -else - HAVE_WINDRES_TRUE='#' - HAVE_WINDRES_FALSE= -fi - - - - - - - if test -n "$PYTHON"; then - # If the user set $PYTHON, use it and don't search something else. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version >= 2.4" >&5 -$as_echo_n "checking whether $PYTHON version >= 2.4... " >&6; } - prog="import sys -# split strings by '.' and convert to numeric. Append some zeros -# because we need at least 4 digits for the hex conversion. -# map returns an iterator in Python 3.0 and a list in 2.x -minver = list(map(int, '2.4'.split('.'))) + [0, 0, 0] -minverhex = 0 -# xrange is not present in Python 3.0 and range returns an iterator -for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] -sys.exit(sys.hexversion < minverhex)" - if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 - ($PYTHON -c "$prog") >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - as_fn_error $? "too old" "$LINENO" 5 -fi - am_display_PYTHON=$PYTHON - else - # Otherwise, try each interpreter until we find one that satisfies - # VERSION. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 2.4" >&5 -$as_echo_n "checking for a Python interpreter with version >= 2.4... " >&6; } -if ${am_cv_pathless_PYTHON+:} false; then : - $as_echo_n "(cached) " >&6 -else - - for am_cv_pathless_PYTHON in python python2 python3 python3.0 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do - test "$am_cv_pathless_PYTHON" = none && break - prog="import sys -# split strings by '.' and convert to numeric. Append some zeros -# because we need at least 4 digits for the hex conversion. -# map returns an iterator in Python 3.0 and a list in 2.x -minver = list(map(int, '2.4'.split('.'))) + [0, 0, 0] -minverhex = 0 -# xrange is not present in Python 3.0 and range returns an iterator -for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] -sys.exit(sys.hexversion < minverhex)" - if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 - ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then : - break -fi - done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 -$as_echo "$am_cv_pathless_PYTHON" >&6; } - # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. - if test "$am_cv_pathless_PYTHON" = none; then - PYTHON=: - else - # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. -set dummy $am_cv_pathless_PYTHON; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PYTHON+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PYTHON in - [\\/]* | ?:[\\/]*) - ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PYTHON=$ac_cv_path_PYTHON -if test -n "$PYTHON"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 -$as_echo "$PYTHON" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi - am_display_PYTHON=$am_cv_pathless_PYTHON - fi - - - if test "$PYTHON" = :; then - as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 - else - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 -$as_echo_n "checking for $am_display_PYTHON version... " >&6; } -if ${am_cv_python_version+:} false; then : - $as_echo_n "(cached) " >&6 -else - am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 -$as_echo "$am_cv_python_version" >&6; } - PYTHON_VERSION=$am_cv_python_version - - - - PYTHON_PREFIX='${prefix}' - - PYTHON_EXEC_PREFIX='${exec_prefix}' - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 -$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } -if ${am_cv_python_platform+:} false; then : - $as_echo_n "(cached) " >&6 -else - am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 -$as_echo "$am_cv_python_platform" >&6; } - PYTHON_PLATFORM=$am_cv_python_platform - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 -$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } -if ${am_cv_python_pythondir+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$prefix" = xNONE - then - am_py_prefix=$ac_default_prefix - else - am_py_prefix=$prefix - fi - am_cv_python_pythondir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(0,0,prefix='$am_py_prefix'))" 2>/dev/null || - echo "$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages"` - case $am_cv_python_pythondir in - $am_py_prefix*) - am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` - am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` - ;; - *) - case $am_py_prefix in - /usr|/System*) ;; - *) - am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 -$as_echo "$am_cv_python_pythondir" >&6; } - pythondir=$am_cv_python_pythondir - - - - pkgpythondir=\${pythondir}/$PACKAGE - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 -$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } -if ${am_cv_python_pyexecdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$exec_prefix" = xNONE - then - am_py_exec_prefix=$am_py_prefix - else - am_py_exec_prefix=$exec_prefix - fi - am_cv_python_pyexecdir=`$PYTHON -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_python_lib(1,0,prefix='$am_py_exec_prefix'))" 2>/dev/null || - echo "$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages"` - case $am_cv_python_pyexecdir in - $am_py_exec_prefix*) - am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` - am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` - ;; - *) - case $am_py_exec_prefix in - /usr|/System*) ;; - *) - am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 -$as_echo "$am_cv_python_pyexecdir" >&6; } - pyexecdir=$am_cv_python_pyexecdir - - - - pkgpyexecdir=\${pyexecdir}/$PACKAGE - - - - fi - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - - - -# Check whether --with-sdl-prefix was given. -if test "${with_sdl_prefix+set}" = set; then : - withval=$with_sdl_prefix; sdl_prefix="$withval" -else - sdl_prefix="" -fi - - -# Check whether --with-sdl-exec-prefix was given. -if test "${with_sdl_exec_prefix+set}" = set; then : - withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" -else - sdl_exec_prefix="" -fi - -# Check whether --enable-sdltest was given. -if test "${enable_sdltest+set}" = set; then : - enableval=$enable_sdltest; -else - enable_sdltest=yes -fi - - - if test x$sdl_exec_prefix != x ; then - sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config - fi - fi - if test x$sdl_prefix != x ; then - sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" - if test x${SDL_CONFIG+set} != xset ; then - SDL_CONFIG=$sdl_prefix/bin/sdl-config - fi - fi - - as_save_PATH="$PATH" - if test "x$prefix" != xNONE; then - PATH="$prefix/bin:$prefix/usr/bin:$PATH" - fi - # Extract the first word of "sdl-config", so it can be a program name with args. -set dummy sdl-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SDL_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SDL_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" - ;; -esac -fi -SDL_CONFIG=$ac_cv_path_SDL_CONFIG -if test -n "$SDL_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL_CONFIG" >&5 -$as_echo "$SDL_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - PATH="$as_save_PATH" - min_sdl_version=1.2.10 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 -$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } - no_sdl="" - if test "$SDL_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` - - sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` - sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` - sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ - sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` - if test "x$enable_sdltest" = "xyes" ; then - ac_save_CFLAGS="$CFLAGS" - ac_save_CXXFLAGS="$CXXFLAGS" - ac_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" - rm -f conf.sdltest - if test "$cross_compiling" = yes; then : - echo $ac_n "cross compiling; assumed OK... $ac_c" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include "SDL.h" - -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main (int argc, char *argv[]) -{ - int major, minor, micro; - char *tmp_version; - - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } - - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { - printf("%s, bad version string\n", "$min_sdl_version"); - exit(1); - } - - if (($sdl_major_version > major) || - (($sdl_major_version == major) && ($sdl_minor_version > minor)) || - (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) - { - return 0; - } - else - { - printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); - printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); - printf("*** best to upgrade to the required version.\n"); - printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); - printf("*** to point to the correct copy of sdl-config, and remove the file\n"); - printf("*** config.cache before re-running configure\n"); - return 1; - } -} - - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - no_sdl=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - if test "x$no_sdl" = x ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - : - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test "$SDL_CONFIG" = "no" ; then - echo "*** The sdl-config script installed by SDL could not be found" - echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the SDL_CONFIG environment variable to the" - echo "*** full path to sdl-config." - else - if test -f conf.sdltest ; then - : - else - echo "*** Could not run SDL test program, checking why..." - CFLAGS="$CFLAGS $SDL_CFLAGS" - CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" - LIBS="$LIBS $SDL_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include "SDL.h" - -int main(int argc, char *argv[]) -{ return 0; } -#undef main -#define main K_and_R_C_main - -int -main () -{ - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - echo "*** The test program compiled, but did not run. This usually means" - echo "*** that the run-time linker is not finding SDL or finding the wrong" - echo "*** version of SDL. If it is not finding SDL, you'll need to set your" - echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" - echo "*** to the installed location Also, make sure you have run ldconfig if that" - echo "*** is required on your system" - echo "***" - echo "*** If you have an old version installed, it is best to remove it, although" - echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" -else - echo "*** The test program failed to compile or link. See the file config.log for the" - echo "*** exact error that occured. This usually means SDL was incorrectly installed" - echo "*** or that you have moved SDL since it was installed. In the latter case, you" - echo "*** may want to edit the sdl-config script: $SDL_CONFIG" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CFLAGS="$ac_save_CFLAGS" - CXXFLAGS="$ac_save_CXXFLAGS" - LIBS="$ac_save_LIBS" - fi - fi - SDL_CFLAGS="" - SDL_LIBS="" - as_fn_error $? "*** SDL version >= 1.2.10 not found." "$LINENO" 5 - fi - - - rm -f conf.sdltest - - -for ac_func in strchr memmove strerror strtol strcasecmp strncasecmp strverscmp stricmp strnicmp strcasestr strptime asprintf vasprintf memcmp mmap nice unsetenv dup fnmatch log2 mkstemp -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - if test "$ac_cv_func_asprintf" = "no"; then - NEED_ASPRINTF_TRUE= - NEED_ASPRINTF_FALSE='#' -else - NEED_ASPRINTF_TRUE='#' - NEED_ASPRINTF_FALSE= -fi - - if test "$ac_cv_func_vasprintf" = "no"; then - NEED_VASPRINTF_TRUE= - NEED_VASPRINTF_FALSE='#' -else - NEED_VASPRINTF_TRUE='#' - NEED_VASPRINTF_FALSE= -fi - - if test "$ac_cv_func_memcmp" = "no"; then - NEED_MEMCMP_TRUE= - NEED_MEMCMP_FALSE='#' -else - NEED_MEMCMP_TRUE='#' - NEED_MEMCMP_FALSE= -fi - - if test "$ac_cv_func_strptime" = "no"; then - NEED_STRPTIME_TRUE= - NEED_STRPTIME_FALSE='#' -else - NEED_STRPTIME_TRUE='#' - NEED_STRPTIME_FALSE= -fi - - if test "$ac_cv_func_mkstemp" = "no"; then - NEED_MKSTEMP_TRUE= - NEED_MKSTEMP_FALSE='#' -else - NEED_MKSTEMP_TRUE='#' - NEED_MKSTEMP_FALSE= -fi - - - if test "$ac_cv_func_mmap" = "yes"; then - USE_MMAP_TRUE= - USE_MMAP_FALSE='#' -else - USE_MMAP_TRUE='#' - USE_MMAP_FALSE= -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 -$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if eval \${$as_ac_Header+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include <$ac_hdr> - -int -main () -{ -if ((DIR *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$as_ac_Header=yes" -else - eval "$as_ac_Header=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$as_ac_Header - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 -_ACEOF - -ac_header_dirent=$ac_hdr; break -fi - -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dir; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : - break -fi -done -if ${ac_cv_search_opendir+:} false; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' x; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : - break -fi -done -if ${ac_cv_search_opendir+:} false; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if ${ac_cv_header_time+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes -else - ac_cv_header_time=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h - -fi - -for ac_header in inttypes.h fcntl.h limits.h signal.h unistd.h sys/param.h sys/ioctl.h sys/kd.h linux/fb.h byteswap.h sys/soundcard.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - if test "$ac_cv_header_sys_soundcard_h" = yes; then - USE_OSS_TRUE= - USE_OSS_FALSE='#' -else - USE_OSS_TRUE='#' - USE_OSS_FALSE= -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset cs; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - -ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" -if test "x$ac_cv_type_off_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define off_t long int -_ACEOF - -fi - -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 -$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } -if ${ac_cv_struct_tm+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int -main () -{ -struct tm tm; - int *p = &tm.tm_sec; - return !p; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_tm=time.h -else - ac_cv_struct_tm=sys/time.h -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 -$as_echo "$ac_cv_struct_tm" >&6; } -if test $ac_cv_struct_tm = sys/time.h; then - -$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h - -fi - -LIBM= -case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5 -$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; } -if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lmw $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char _mwvalidcheckl (); -int -main () -{ -return _mwvalidcheckl (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_mw__mwvalidcheckl=yes -else - ac_cv_lib_mw__mwvalidcheckl=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5 -$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; } -if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then : - LIBM="-lmw" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 -$as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char cos (); -int -main () -{ -return cos (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_cos=yes -else - ac_cv_lib_m_cos=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 -$as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : - LIBM="$LIBM -lm" -fi - - ;; -*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 -$as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char cos (); -int -main () -{ -return cos (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_cos=yes -else - ac_cv_lib_m_cos=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 -$as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : - LIBM="-lm" -fi - - ;; -esac - - - - - -defaultx11=yes - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CoreAudio/CoreMIDI Framework" >&5 -$as_echo_n "checking for CoreAudio/CoreMIDI Framework... " >&6; } -if echo "$SDL_LIBS" | grep -- -framework >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } - SDL_LIBS="$SDL_LIBS -framework CoreAudio -framework CoreMIDI -framework IOKit -framework OpenGL" - - - if true; then - USE_MACOSX_TRUE= - USE_MACOSX_FALSE='#' -else - USE_MACOSX_TRUE='#' - USE_MACOSX_FALSE= -fi - - if true; then - am__fastdepOBJC_TRUE= - am__fastdepOBJC_FALSE='#' -else - am__fastdepOBJC_TRUE='#' - am__fastdepOBJC_FALSE= -fi - - defaultx11=no -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - if false; then - USE_MACOSX_TRUE= - USE_MACOSX_FALSE='#' -else - USE_MACOSX_TRUE='#' - USE_MACOSX_FALSE= -fi - - if false; then - am__fastdepOBJC_TRUE= - am__fastdepOBJC_FALSE='#' -else - am__fastdepOBJC_TRUE='#' - am__fastdepOBJC_FALSE= -fi - -fi - - - -for ac_header in winsock.h winsock2.h windows.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -if test "X$ac_cv_header_windows_h" = "Xyes"; then - if true; then - USE_WIN32_TRUE= - USE_WIN32_FALSE='#' -else - USE_WIN32_TRUE='#' - USE_WIN32_FALSE= -fi - - SDL_LIBS="$SDL_LIBS -lwinmm" - - defaultx11=no -else - if false; then - USE_WIN32_TRUE= - USE_WIN32_FALSE='#' -else - USE_WIN32_TRUE='#' - USE_WIN32_FALSE= -fi - -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IOS_ReloadIOS in -logc" >&5 -$as_echo_n "checking for IOS_ReloadIOS in -logc... " >&6; } -if ${ac_cv_lib_ogc_IOS_ReloadIOS+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-logc -mrvl -L${DEVKITPRO}/libogc/lib/wii $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char IOS_ReloadIOS (); -int -main () -{ -return IOS_ReloadIOS (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ogc_IOS_ReloadIOS=yes -else - ac_cv_lib_ogc_IOS_ReloadIOS=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ogc_IOS_ReloadIOS" >&5 -$as_echo "$ac_cv_lib_ogc_IOS_ReloadIOS" >&6; } -if test "x$ac_cv_lib_ogc_IOS_ReloadIOS" = xyes; then : - libogc_found=yes -else - libogc_found=no -fi - -if test x"$libogc_found" = "xyes"; then - if true; then - USE_WII_TRUE= - USE_WII_FALSE='#' -else - USE_WII_TRUE='#' - USE_WII_FALSE= -fi - - wii_machdep="-DGEKKO -mrvl -mcpu=750 -meabi -mhard-float" - CFLAGS="$CFLAGS $wii_machdep -I${DEVKITPRO}/libogc/include" - LIBS="$LIBS $wii_machdep -L${DEVKITPRO}/libogc/lib/wii" - SDL_CFLAGS="$SDL_CFLAGS -I${DEVKITPRO}/libogc/include/SDL" - SDL_LIBS="$SDL_LIBS -lSDL -lfat -lwiiuse -lbte -logc -lm -lwiikeyboard" - - - - - EXEEXT=.elf - - defaultx11=no -else - if false; then - USE_WII_TRUE= - USE_WII_FALSE='#' -else - USE_WII_TRUE='#' - USE_WII_FALSE= -fi - -fi - - -if test "x$defaultx11" = "xno"; then - if test "x$with_x" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: X11 disabled by default; use --with-x if you really want it" >&5 -$as_echo "$as_me: X11 disabled by default; use --with-x if you really want it" >&6;} - with_x=no - fi -fi - -saved_cppflags=$CPPFLAGS -CPPFLAGS="$CPPFLAGS $SDL_CFLAGS" -ac_fn_c_check_header_mongrel "$LINENO" "SDL_opengl.h" "ac_cv_header_SDL_opengl_h" "$ac_includes_default" -if test "x$ac_cv_header_SDL_opengl_h" = xyes; then : - -$as_echo "#define USE_OPENGL 1" >>confdefs.h - -fi - - -CPPFLAGS=$saved_cppflags - - -saved_libs=$LIBS -alsa=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snd_seq_open in -lasound" >&5 -$as_echo_n "checking for snd_seq_open in -lasound... " >&6; } -if ${ac_cv_lib_asound_snd_seq_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lasound $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char snd_seq_open (); -int -main () -{ -return snd_seq_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_asound_snd_seq_open=yes -else - ac_cv_lib_asound_snd_seq_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_seq_open" >&5 -$as_echo "$ac_cv_lib_asound_snd_seq_open" >&6; } -if test "x$ac_cv_lib_asound_snd_seq_open" = xyes; then : - alsa=yes -fi - -alsadltrick=no -if test "$alsa" = "yes"; then - if test "$ac_cv_header_sys_soundcard_h" = "yes"; then - alsadltrick=yes - LIBS=$saved_libs - fi -fi - if test "$alsa" = yes; then - USE_ALSA_TRUE= - USE_ALSA_FALSE='#' -else - USE_ALSA_TRUE='#' - USE_ALSA_FALSE= -fi - - if test "$alsadltrick" = yes; then - USE_ALSA_DLTRICK_TRUE= - USE_ALSA_DLTRICK_FALSE='#' -else - USE_ALSA_DLTRICK_TRUE='#' - USE_ALSA_DLTRICK_FALSE= -fi - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 -$as_echo_n "checking for X... " >&6; } - - -# Check whether --with-x was given. -if test "${with_x+set}" = set; then : - withval=$with_x; -fi - -# $have_x is `yes', `no', `disabled', or empty when we do not yet know. -if test "x$with_x" = xno; then - # The user explicitly disabled X. - have_x=disabled -else - case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : - $as_echo_n "(cached) " >&6 -else - # One or both of the vars are not set, and there is no cached value. -ac_x_includes=no ac_x_libraries=no -rm -f -r conftest.dir -if mkdir conftest.dir; then - cd conftest.dir - cat >Imakefile <<'_ACEOF' -incroot: - @echo incroot='${INCROOT}' -usrlibdir: - @echo usrlibdir='${USRLIBDIR}' -libdir: - @echo libdir='${LIBDIR}' -_ACEOF - if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then - # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. - for ac_var in incroot usrlibdir libdir; do - eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" - done - # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl dylib la dll; do - if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && - test -f "$ac_im_libdir/libX11.$ac_extension"; then - ac_im_usrlibdir=$ac_im_libdir; break - fi - done - # Screen out bogus values from the imake configuration. They are - # bogus both because they are the default anyway, and because - # using them would break gcc on systems where it needs fixed includes. - case $ac_im_incroot in - /usr/include) ac_x_includes= ;; - *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; - esac - case $ac_im_usrlibdir in - /usr/lib | /usr/lib64 | /lib | /lib64) ;; - *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; - esac - fi - cd .. - rm -f -r conftest.dir -fi - -# Standard set of common directories for X headers. -# Check X11 before X11Rn because it is often a symlink to the current release. -ac_x_header_dirs=' -/usr/X11/include -/usr/X11R7/include -/usr/X11R6/include -/usr/X11R5/include -/usr/X11R4/include - -/usr/include/X11 -/usr/include/X11R7 -/usr/include/X11R6 -/usr/include/X11R5 -/usr/include/X11R4 - -/usr/local/X11/include -/usr/local/X11R7/include -/usr/local/X11R6/include -/usr/local/X11R5/include -/usr/local/X11R4/include - -/usr/local/include/X11 -/usr/local/include/X11R7 -/usr/local/include/X11R6 -/usr/local/include/X11R5 -/usr/local/include/X11R4 - -/usr/X386/include -/usr/x386/include -/usr/XFree86/include/X11 - -/usr/include -/usr/local/include -/usr/unsupported/include -/usr/athena/include -/usr/local/x11r5/include -/usr/lpp/Xamples/include - -/usr/openwin/include -/usr/openwin/share/include' - -if test "$ac_x_includes" = no; then - # Guess where to find include files, by looking for Xlib.h. - # First, try using that file with no special directory specified. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # We can compile using X headers with no special include directory. -ac_x_includes= -else - for ac_dir in $ac_x_header_dirs; do - if test -r "$ac_dir/X11/Xlib.h"; then - ac_x_includes=$ac_dir - break - fi -done -fi -rm -f conftest.err conftest.i conftest.$ac_ext -fi # $ac_x_includes = no - -if test "$ac_x_libraries" = no; then - # Check for the libraries. - # See if we find them without any special options. - # Don't add to $LIBS permanently. - ac_save_LIBS=$LIBS - LIBS="-lX11 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -XrmInitialize () - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - LIBS=$ac_save_LIBS -# We can link X programs with no special library path. -ac_x_libraries= -else - LIBS=$ac_save_LIBS -for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` -do - # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl dylib la dll; do - if test -r "$ac_dir/libX11.$ac_extension"; then - ac_x_libraries=$ac_dir - break 2 - fi - done -done -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi # $ac_x_libraries = no - -case $ac_x_includes,$ac_x_libraries in #( - no,* | *,no | *\'*) - # Didn't find X, or a directory has "'" in its name. - ac_cv_have_x="have_x=no";; #( - *) - # Record where we found X for the cache. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$ac_x_includes'\ - ac_x_libraries='$ac_x_libraries'" -esac -fi -;; #( - *) have_x=yes;; - esac - eval "$ac_cv_have_x" -fi # $with_x != no - -if test "$have_x" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 -$as_echo "$have_x" >&6; } - no_x=yes -else - # If each of the values was on the command line, it overrides each guess. - test "x$x_includes" = xNONE && x_includes=$ac_x_includes - test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries - # Update the cache value to reflect the command line values. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$x_includes'\ - ac_x_libraries='$x_libraries'" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 -$as_echo "libraries $x_libraries, headers $x_includes" >&6; } -fi - -if test "$no_x" = yes; then - # Not all programs may use this symbol, but it does not hurt to define it. - -$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h - - X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= -else - if test -n "$x_includes"; then - X_CFLAGS="$X_CFLAGS -I$x_includes" - fi - - # It would also be nice to do this for all -L options, not just this one. - if test -n "$x_libraries"; then - X_LIBS="$X_LIBS -L$x_libraries" - # For Solaris; some versions of Sun CC require a space after -R and - # others require no space. Words are not sufficient . . . . - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 -$as_echo_n "checking whether -R must be followed by a space... " >&6; } - ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" - ac_xsave_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - X_LIBS="$X_LIBS -R$x_libraries" -else - LIBS="$ac_xsave_LIBS -R $x_libraries" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - X_LIBS="$X_LIBS -R $x_libraries" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 -$as_echo "neither works" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_c_werror_flag=$ac_xsave_c_werror_flag - LIBS=$ac_xsave_LIBS - fi - - # Check for system-dependent libraries X programs must link with. - # Do this before checking for the system-independent R6 libraries - # (-lICE), since we may need -lsocket or whatever for X linking. - - if test "$ISC" = yes; then - X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" - else - # Martyn Johnson says this is needed for Ultrix, if the X - # libraries were built with DECnet support. And Karl Berry says - # the Alpha needs dnet_stub (dnet does not exist). - ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XOpenDisplay (); -int -main () -{ -return XOpenDisplay (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldnet $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dnet_ntoa (); -int -main () -{ -return dnet_ntoa (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dnet_dnet_ntoa=yes -else - ac_cv_lib_dnet_dnet_ntoa=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" -fi - - if test $ac_cv_lib_dnet_dnet_ntoa = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldnet_stub $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dnet_ntoa (); -int -main () -{ -return dnet_ntoa (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dnet_stub_dnet_ntoa=yes -else - ac_cv_lib_dnet_stub_dnet_ntoa=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" -fi - - fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$ac_xsave_LIBS" - - # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, - # to get the SysV transport functions. - # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) - # needs -lnsl. - # The nsl library prevents programs from opening the X display - # on Irix 5.2, according to T.E. Dickey. - # The functions gethostbyname, getservbyname, and inet_addr are - # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. - ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : - -fi - - if test $ac_cv_func_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_gethostbyname=yes -else - ac_cv_lib_nsl_gethostbyname=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" -fi - - if test $ac_cv_lib_nsl_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 -$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bsd_gethostbyname=yes -else - ac_cv_lib_bsd_gethostbyname=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 -$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" -fi - - fi - fi - - # lieder@skyler.mavd.honeywell.com says without -lsocket, - # socket/setsockopt and other routines are undefined under SCO ODT - # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary - # on later versions), says Simon Leinen: it contains gethostby* - # variants that don't use the name server (or something). -lsocket - # must be given before -lnsl if both are needed. We assume that - # if connect needs -lnsl, so does gethostbyname. - ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : - -fi - - if test $ac_cv_func_connect = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 -$as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $X_EXTRA_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char connect (); -int -main () -{ -return connect (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_connect=yes -else - ac_cv_lib_socket_connect=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 -$as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : - X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" -fi - - fi - - # Guillermo Gomez says -lposix is necessary on A/UX. - ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : - -fi - - if test $ac_cv_func_remove = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 -$as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lposix $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char remove (); -int -main () -{ -return remove (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_posix_remove=yes -else - ac_cv_lib_posix_remove=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 -$as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" -fi - - fi - - # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. - ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : - -fi - - if test $ac_cv_func_shmat = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 -$as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lipc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shmat (); -int -main () -{ -return shmat (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ipc_shmat=yes -else - ac_cv_lib_ipc_shmat=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 -$as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" -fi - - fi - fi - - # Check for libraries that X11R6 Xt/Xaw programs need. - ac_save_LDFLAGS=$LDFLAGS - test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" - # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to - # check for ICE first), but we must link in the order -lSM -lICE or - # we get undefined symbols. So assume we have SM if we have ICE. - # These have to be linked with before -lX11, unlike the other - # libraries we check for below, so use a different variable. - # John Interrante, Karl Berry - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 -$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lICE $X_EXTRA_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char IceConnectionNumber (); -int -main () -{ -return IceConnectionNumber (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ICE_IceConnectionNumber=yes -else - ac_cv_lib_ICE_IceConnectionNumber=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 -$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : - X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" -fi - - LDFLAGS=$ac_save_LDFLAGS - -fi - -if test "$no_x" = "yes"; then - if false; then - USE_X11_TRUE= - USE_X11_FALSE='#' -else - USE_X11_TRUE='#' - USE_X11_FALSE= -fi - - if false; then - USE_XV_TRUE= - USE_XV_FALSE='#' -else - USE_XV_TRUE='#' - USE_XV_FALSE= -fi - -else - if true; then - USE_X11_TRUE= - USE_X11_FALSE='#' -else - USE_X11_TRUE='#' - USE_X11_FALSE= -fi - - - SDL_LIBS="$SDL_LIBS -lX11 -lXext" - - - LIBS="$LIBS $X_LIBS" - - - for ac_header in X11/Xlib.h X11/XKBlib.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XvQueryExtension in -lXv" >&5 -$as_echo_n "checking for XvQueryExtension in -lXv... " >&6; } -if ${ac_cv_lib_Xv_XvQueryExtension+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXv -lX11 -lXext $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XvQueryExtension (); -int -main () -{ -return XvQueryExtension (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xv_XvQueryExtension=yes -else - ac_cv_lib_Xv_XvQueryExtension=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xv_XvQueryExtension" >&5 -$as_echo "$ac_cv_lib_Xv_XvQueryExtension" >&6; } -if test "x$ac_cv_lib_Xv_XvQueryExtension" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBXV 1 -_ACEOF - - LIBS="-lXv $LIBS" - -fi - - if test "$ac_cv_lib_Xv_XvQueryExtension" = "yes"; then - for ac_header in X11/extensions/Xvlib.h -do : - ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xvlib.h" "ac_cv_header_X11_extensions_Xvlib_h" " -#include - -" -if test "x$ac_cv_header_X11_extensions_Xvlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_X11_EXTENSIONS_XVLIB_H 1 -_ACEOF - -fi - -done - - if test "$ac_cv_header_X11_extensions_xvlib_h" = "yes"; then - SDL_LIBS="$SDL_LIBS -lXv -lXext" - - if true; then - USE_XV_TRUE= - USE_XV_FALSE='#' -else - USE_XV_TRUE='#' - USE_XV_FALSE= -fi - - elif test "$ac_cv_header_X11_extensions_Xvlib_h" = "yes"; then - SDL_LIBS="$SDL_LIBS -lXv -lXext" - - if true; then - USE_XV_TRUE= - USE_XV_FALSE='#' -else - USE_XV_TRUE='#' - USE_XV_FALSE= -fi - - else - if false; then - USE_XV_TRUE= - USE_XV_FALSE='#' -else - USE_XV_TRUE='#' - USE_XV_FALSE= -fi - - fi - else - if false; then - USE_XV_TRUE= - USE_XV_FALSE='#' -else - USE_XV_TRUE='#' - USE_XV_FALSE= -fi - - fi -fi - -saved_LIBS="$LIBS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 -$as_echo_n "checking for library containing socket... " >&6; } -if ${ac_cv_search_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char socket (); -int -main () -{ -return socket (); - ; - return 0; -} -_ACEOF -for ac_lib in '' socket network; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_socket=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_socket+:} false; then : - break -fi -done -if ${ac_cv_search_socket+:} false; then : - -else - ac_cv_search_socket=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 -$as_echo "$ac_cv_search_socket" >&6; } -ac_res=$ac_cv_search_socket -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -LIBS="$saved_LIBS" -if test "x$ac_cv_search_socket" = "xno"; then - for ac_header in winsock.h winsock2.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - if test "x$ac_cv_header_winsock_h" = "xyes"; then - socketlib="-lwsock32" - elif test "x$ac_cv_header_winsock2_h" = "xyes"; then - socketlib="-lws2_32" - fi - if test "x$socketlib" = "x"; then - echo "*** No sockets for you!" - if false; then - USE_NETWORK_TRUE= - USE_NETWORK_FALSE='#' -else - USE_NETWORK_TRUE='#' - USE_NETWORK_FALSE= -fi - - else - if true; then - USE_NETWORK_TRUE= - USE_NETWORK_FALSE='#' -else - USE_NETWORK_TRUE='#' - USE_NETWORK_FALSE= -fi - - SDL_LIBS="$SDL_LIBS $socketlib" - - fi -elif test "x$ac_cv_search_socket" = "xnone required"; then - if true; then - USE_NETWORK_TRUE= - USE_NETWORK_FALSE='#' -else - USE_NETWORK_TRUE='#' - USE_NETWORK_FALSE= -fi - -else - SDL_LIBS="$SDL_LIBS $ac_cv_search_socket" - - if true; then - USE_NETWORK_TRUE= - USE_NETWORK_FALSE='#' -else - USE_NETWORK_TRUE='#' - USE_NETWORK_FALSE= -fi - -fi - -#AC_CHECK_LIB(kernel32, GetConsoleMode, SDL_LIBS="$SDL_LIBS -Wl,--subsystem,console") - -OBJC=$CC -OBJCFLAGS=$CFLAGS - - - - -# Check whether --enable-mercurial was given. -if test "${enable_mercurial+set}" = set; then : - enableval=$enable_mercurial; USE_MERCURIAL=$enableval -else - USE_MERCURIAL=yes -fi - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mercurial" >&5 -$as_echo_n "checking for Mercurial... " >&6; } -if test x$USE_MERCURIAL = xyes; then - hg_dirstate=no - if test -e "$ac_abs_confdir"/.hg/dirstate; then - if hg --version >/dev/null; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 -$as_echo "found" >&6; } - hg_dirstate=yes - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - echo "*** Warning: .hg/dirstate exists, but no 'hg' command in PATH" - echo "*** Mercurial version information cannot be compiled in" - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 -$as_echo "not found" >&6; } - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: skipped" >&5 -$as_echo "skipped" >&6; } -fi - -if test "x$hg_dirstate" = "xyes"; then - if true; then - USE_MERCURIAL_TRUE= - USE_MERCURIAL_FALSE='#' -else - USE_MERCURIAL_TRUE='#' - USE_MERCURIAL_FALSE= -fi - -else - if false; then - USE_MERCURIAL_TRUE= - USE_MERCURIAL_FALSE='#' -else - USE_MERCURIAL_TRUE='#' - USE_MERCURIAL_FALSE= -fi - -fi - - -# Check whether --enable-extra-opt was given. -if test "${enable_extra_opt+set}" = set; then : - enableval=$enable_extra_opt; ADD_OPT=$enableval -else - ADD_OPT=no -fi - - -# Check whether --enable-all-warnings was given. -if test "${enable_all_warnings+set}" = set; then : - enableval=$enable_all_warnings; ADD_WARN=$enableval -else - ADD_WARN=no -fi - - -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; ADD_DEBUG=$enableval -else - ADD_DEBUG=no -fi - - -# Check whether --enable-profiling was given. -if test "${enable_profiling+set}" = set; then : - enableval=$enable_profiling; ADD_PROFILING=$enableval -else - ADD_PROFILING=no -fi - - -# Check whether --enable-ludicrous-mode was given. -if test "${enable_ludicrous_mode+set}" = set; then : - enableval=$enable_ludicrous_mode; ADD_LUDICROUS=$enableval -else - ADD_LUDICROUS=no -fi - - -if test x$ADD_OPT \!= xno; then - ADD_OPT="-g0 -s -O3 -ffast-math -fomit-frame-pointer -fno-exceptions" - ADD_OPT="$ADD_OPT -funroll-loops -frerun-cse-after-loop -fno-ident" - ADD_OPT="$ADD_OPT -fno-strength-reduce" - CFLAGS="$CFLAGS $ADD_OPT" -fi - -if test x$ADD_LUDICROUS \!= xno; then - ADD_WARN=yes - CFLAGS="$CFLAGS -Werror -D_FORTIFY_SOURCE=2" -fi - -if test x$ADD_WARN \!= xno; then - ADD_WARN="-Wall -Wextra -Winline -Wshadow -Wwrite-strings -Waggregate-return -Wpacked" - ADD_WARN="$ADD_WARN -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs" - CFLAGS="$ADD_WARN $CFLAGS" -fi - -if test x$ADD_DEBUG \!= xno; then - CFLAGS="$CFLAGS -g" - OBJCFLAGS="$OBJCFLAGS -g" - SDL_LIBS="$SDL_LIBS -g" - -fi -if test x$ADD_PROFILING \!= xno; then - CFLAGS="$CFLAGS -g -pg" - OBJCFLAGS="$OBJCFLAGS -g -pg" - SDL_LIBS="$SDL_LIBS -g -pg" - -fi - - -ac_config_files="$ac_config_files Makefile" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_WINDRES_TRUE}" && test -z "${HAVE_WINDRES_FALSE}"; then - as_fn_error $? "conditional \"HAVE_WINDRES\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -if test -z "${NEED_ASPRINTF_TRUE}" && test -z "${NEED_ASPRINTF_FALSE}"; then - as_fn_error $? "conditional \"NEED_ASPRINTF\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${NEED_VASPRINTF_TRUE}" && test -z "${NEED_VASPRINTF_FALSE}"; then - as_fn_error $? "conditional \"NEED_VASPRINTF\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${NEED_MEMCMP_TRUE}" && test -z "${NEED_MEMCMP_FALSE}"; then - as_fn_error $? "conditional \"NEED_MEMCMP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${NEED_STRPTIME_TRUE}" && test -z "${NEED_STRPTIME_FALSE}"; then - as_fn_error $? "conditional \"NEED_STRPTIME\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${NEED_MKSTEMP_TRUE}" && test -z "${NEED_MKSTEMP_FALSE}"; then - as_fn_error $? "conditional \"NEED_MKSTEMP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_MMAP_TRUE}" && test -z "${USE_MMAP_FALSE}"; then - as_fn_error $? "conditional \"USE_MMAP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_OSS_TRUE}" && test -z "${USE_OSS_FALSE}"; then - as_fn_error $? "conditional \"USE_OSS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_MACOSX_TRUE}" && test -z "${USE_MACOSX_FALSE}"; then - as_fn_error $? "conditional \"USE_MACOSX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepOBJC_TRUE}" && test -z "${am__fastdepOBJC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepOBJC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_MACOSX_TRUE}" && test -z "${USE_MACOSX_FALSE}"; then - as_fn_error $? "conditional \"USE_MACOSX\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepOBJC_TRUE}" && test -z "${am__fastdepOBJC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepOBJC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_WIN32_TRUE}" && test -z "${USE_WIN32_FALSE}"; then - as_fn_error $? "conditional \"USE_WIN32\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_WIN32_TRUE}" && test -z "${USE_WIN32_FALSE}"; then - as_fn_error $? "conditional \"USE_WIN32\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_WII_TRUE}" && test -z "${USE_WII_FALSE}"; then - as_fn_error $? "conditional \"USE_WII\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_WII_TRUE}" && test -z "${USE_WII_FALSE}"; then - as_fn_error $? "conditional \"USE_WII\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_ALSA_TRUE}" && test -z "${USE_ALSA_FALSE}"; then - as_fn_error $? "conditional \"USE_ALSA\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_ALSA_DLTRICK_TRUE}" && test -z "${USE_ALSA_DLTRICK_FALSE}"; then - as_fn_error $? "conditional \"USE_ALSA_DLTRICK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_X11_TRUE}" && test -z "${USE_X11_FALSE}"; then - as_fn_error $? "conditional \"USE_X11\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_XV_TRUE}" && test -z "${USE_XV_FALSE}"; then - as_fn_error $? "conditional \"USE_XV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_X11_TRUE}" && test -z "${USE_X11_FALSE}"; then - as_fn_error $? "conditional \"USE_X11\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_XV_TRUE}" && test -z "${USE_XV_FALSE}"; then - as_fn_error $? "conditional \"USE_XV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_XV_TRUE}" && test -z "${USE_XV_FALSE}"; then - as_fn_error $? "conditional \"USE_XV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_XV_TRUE}" && test -z "${USE_XV_FALSE}"; then - as_fn_error $? "conditional \"USE_XV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_XV_TRUE}" && test -z "${USE_XV_FALSE}"; then - as_fn_error $? "conditional \"USE_XV\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_NETWORK_TRUE}" && test -z "${USE_NETWORK_FALSE}"; then - as_fn_error $? "conditional \"USE_NETWORK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_NETWORK_TRUE}" && test -z "${USE_NETWORK_FALSE}"; then - as_fn_error $? "conditional \"USE_NETWORK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_NETWORK_TRUE}" && test -z "${USE_NETWORK_FALSE}"; then - as_fn_error $? "conditional \"USE_NETWORK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_NETWORK_TRUE}" && test -z "${USE_NETWORK_FALSE}"; then - as_fn_error $? "conditional \"USE_NETWORK\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_MERCURIAL_TRUE}" && test -z "${USE_MERCURIAL_FALSE}"; then - as_fn_error $? "conditional \"USE_MERCURIAL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${USE_MERCURIAL_TRUE}" && test -z "${USE_MERCURIAL_FALSE}"; then - as_fn_error $? "conditional \"USE_MERCURIAL\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -p' - fi -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in #( - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by schismtracker $as_me 20110101, which was -generated by GNU Autoconf 2.68. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -schismtracker config.status 20110101 -configured by $0, generated by GNU Autoconf 2.68, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2010 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff -Nru schism-0+20110101/configure.ac schism-20160521/configure.ac --- schism-0+20110101/configure.ac 2011-01-01 21:51:23.000000000 +0000 +++ schism-20160521/configure.ac 2016-05-21 14:40:41.000000000 +0000 @@ -4,7 +4,7 @@ dnl copyright (c) 2003-2005 Storlek dnl copyright (c) 2005-2008 Mrs. Brisby dnl copyright (c) 2009 Storlek & Mrs. Brisby -dnl copyright (c) 2010-2011 Storlek +dnl copyright (c) 2010-2012 Storlek dnl URL: http://schismtracker.org/ dnl dnl This program is free software; you can redistribute it and/or modify @@ -21,15 +21,12 @@ dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -dnl 'hg', or a date in the form YYYYMMDD -AC_INIT([schismtracker], [20110101]) +dnl PACKAGE_VERSION will be either " " if not using git, or date of the last git commit in the form YYYYMMDD +m4_define([last_git_commit], patsubst(m4_esyscmd([git log -n 1 --date=short --format=format:%cd]), [[^0-9]])) +AC_INIT([schismtracker], [last_git_commit]) AC_CONFIG_SRCDIR([schism/main.c]) -dnl We'll need machine type later -AC_CANONICAL_TARGET([]) -machtype="$target_cpu" - AM_INIT_AUTOMAKE([-Wall subdir-objects]) AC_CONFIG_HEADERS([config.h]) @@ -253,43 +250,6 @@ AC_SUBST(OBJCFLAGS) dnl ----------------------------------------------------------------------- -dnl stupid version hack - -AC_ARG_ENABLE(mercurial, - AS_HELP_STRING([--enable-mercurial], [Use Mercurial for version/timestamps]), - USE_MERCURIAL=$enableval, - USE_MERCURIAL=yes) - -dnl We want to get the most accurate information of the version possible. -dnl If Mercurial is present, 'hg parents' will tell us what version is -dnl really being compiled. - -AC_MSG_CHECKING(for Mercurial) -if test x$USE_MERCURIAL = xyes; then - hg_dirstate=no - if test -e "$ac_abs_confdir"/.hg/dirstate; then - if hg --version >/dev/null; then - AC_MSG_RESULT(found) - hg_dirstate=yes - else - AC_MSG_RESULT(not found) - echo "*** Warning: .hg/dirstate exists, but no 'hg' command in PATH" - echo "*** Mercurial version information cannot be compiled in" - fi - else - AC_MSG_RESULT(not found) - fi -else - AC_MSG_RESULT(skipped) -fi - -if test "x$hg_dirstate" = "xyes"; then - AM_CONDITIONAL([USE_MERCURIAL], [true]) -else - AM_CONDITIONAL([USE_MERCURIAL], [false]) -fi - -dnl ----------------------------------------------------------------------- dnl (This ought to be above AC_PROG_CC, but that causes configure to fail dnl when all the insane warnings are are enabled.) diff -Nru schism-0+20110101/debian/changelog schism-20160521/debian/changelog --- schism-0+20110101/debian/changelog 2011-12-03 04:19:39.000000000 +0000 +++ schism-20160521/debian/changelog 2016-07-26 07:53:37.000000000 +0000 @@ -1,8 +1,15 @@ -schism (2:0+20110101-1build1) precise; urgency=low +schism (2:20160521-1) unstable; urgency=low - * No-change rebuild to drop spurious libsfgcc1 dependency on armhf. + * New upstream version. (Closes: #730571) + * Bump standards version to 3.9.8. + * Drop debian/patches, not needed anymore. + * Drop debian/schism.1 and manpages, upstream ships a better one. + * debian/rules: add debian hardening for schismtracker. + * Upstream renamed schism binary to schismtracker. + * Updated debian/menu. + * Change my name. - -- Adam Conrad Fri, 02 Dec 2011 21:19:39 -0700 + -- Gürkan Myczko Tue, 26 Jul 2016 09:53:37 +0200 schism (2:0+20110101-1) unstable; urgency=low diff -Nru schism-0+20110101/debian/control schism-20160521/debian/control --- schism-0+20110101/debian/control 2010-09-05 18:15:47.000000000 +0000 +++ schism-20160521/debian/control 2016-07-26 07:53:37.000000000 +0000 @@ -3,7 +3,7 @@ Priority: optional Maintainer: Debian Multimedia Maintainers Uploaders: Alessio Treglia , - Gürkan Sengün + Gürkan Myczko Build-Depends: debhelper (>= 7.0.50~), python (>= 2.4), dh-autoreconf, @@ -11,7 +11,7 @@ autotools-dev, libxext-dev, libasound2-dev -Standards-Version: 3.9.1 +Standards-Version: 3.9.8 Homepage: http://schismtracker.org/ Vcs-Git: git://git.debian.org/git/pkg-multimedia/schism.git Vcs-Browser: http://git.debian.org/?p=pkg-multimedia/schism.git diff -Nru schism-0+20110101/debian/copyright schism-20160521/debian/copyright --- schism-0+20110101/debian/copyright 2011-02-18 14:08:40.000000000 +0000 +++ schism-20160521/debian/copyright 2016-07-26 07:53:37.000000000 +0000 @@ -17,7 +17,7 @@ License: Copyright (C) 2003-2011 Storlek/chisel - Copyright (C) 2005-2011 Mrs. Brisby + Copyright (C) 2005-2016 Mrs. Brisby This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -Nru schism-0+20110101/debian/gbp.conf schism-20160521/debian/gbp.conf --- schism-0+20110101/debian/gbp.conf 2011-02-18 14:12:58.000000000 +0000 +++ schism-20160521/debian/gbp.conf 2016-07-26 07:53:37.000000000 +0000 @@ -1,4 +1,4 @@ [DEFAULT] sign-tags = True pristine-tar = True -compression = bzip2 +compression = gzip diff -Nru schism-0+20110101/debian/manpages schism-20160521/debian/manpages --- schism-0+20110101/debian/manpages 2010-09-05 17:55:29.000000000 +0000 +++ schism-20160521/debian/manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/schism.1 diff -Nru schism-0+20110101/debian/menu schism-20160521/debian/menu --- schism-0+20110101/debian/menu 2010-09-05 17:55:29.000000000 +0000 +++ schism-20160521/debian/menu 2016-07-26 07:53:37.000000000 +0000 @@ -1,5 +1,5 @@ ?package(schism):needs="X11" section="Applications/Sound"\ - title="Schism Tracker" command="/usr/bin/schism" + title="Schism Tracker" command="/usr/bin/schismtracker" ?package(schism):needs="X11" section="Applications/Graphics"\ - title="Schism Tracker Font Editor" command="/usr/bin/schism --font-editor" + title="Schism Tracker Font Editor" command="/usr/bin/schismtracker --font-editor" diff -Nru schism-0+20110101/debian/patches/01-binutils_gold.patch schism-20160521/debian/patches/01-binutils_gold.patch --- schism-0+20110101/debian/patches/01-binutils_gold.patch 2011-02-18 14:19:45.000000000 +0000 +++ schism-20160521/debian/patches/01-binutils_gold.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -Author: Alessio Treglia -Description: FTBFS with binutils-gold. - Add -ldl to linking options to prevent FTBFS with newer release - of the GNU's linker. -Bug-Debian: http://bugs.debian.org/556337 -Forwarded: no ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- schism.orig/Makefile.am -+++ schism/Makefile.am -@@ -391,5 +391,5 @@ AM_CFLAGS = $(SDL_CFLAGS) $(cflags_alsa) - AM_OBJCFLAGS = $(AM_CFLAGS) - - schismtracker_DEPENDENCIES = $(files_windres) --schismtracker_LDADD = $(lib_asound) $(lib_win32) $(SDL_LIBS) $(LIBM) -+schismtracker_LDADD = $(lib_asound) $(lib_win32) $(SDL_LIBS) $(LIBM) -ldl - diff -Nru schism-0+20110101/debian/patches/drop-macro-PE schism-20160521/debian/patches/drop-macro-PE --- schism-0+20110101/debian/patches/drop-macro-PE 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/debian/patches/drop-macro-PE 2016-07-26 07:53:37.000000000 +0000 @@ -0,0 +1,38 @@ +Description: invalid macro PE + Drop the .PE macro since lintian doesn't like it. + . + schism (2:20160521-1) unstable; urgency=low + . + * New upstream version. (Closes: #730571) + * Bump standards version to 3.9.8. + * Drop debian/patches, not needed anymore. + * Drop debian/schism.1 and manpages, upstream ships a better one. + * Upstream renamed schism binary to schismtracker. + * Updated debian/menu. + * Change my name. +Author: Gürkan Myczko +Bug-Debian: https://bugs.debian.org/730571 + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: , +Bug: +Bug-Debian: https://bugs.debian.org/ +Bug-Ubuntu: https://launchpad.net/bugs/ +Forwarded: +Reviewed-By: +Last-Update: 2016-08-03 + +--- schism-20160521.orig/sys/posix/schismtracker.1 ++++ schism-20160521/sys/posix/schismtracker.1 +@@ -113,7 +113,6 @@ with the keyboard as follows: + '--'--'--'--'--'--'--'--'--'--'--'--'--'--'--'--'--' + (Note) C D E F G A B C D E F G A B C D E + (Octave 0) (Octave 1) (Octave 2) +-.PE + .\" this .P is for elvis, which gets very confused by the preceding diagram + .P + The "/" and "*" keys on the numeric keypad change octaves, and the current diff -Nru schism-0+20110101/debian/patches/invalid-macro-PS schism-20160521/debian/patches/invalid-macro-PS --- schism-0+20110101/debian/patches/invalid-macro-PS 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/debian/patches/invalid-macro-PS 2016-07-26 07:53:37.000000000 +0000 @@ -0,0 +1,38 @@ +Description: invalid macro PS + Drop the .PS macro since lintian doesn't like it. + . + schism (2:20160521-1) unstable; urgency=low + . + * New upstream version. (Closes: #730571) + * Bump standards version to 3.9.8. + * Drop debian/patches, not needed anymore. + * Drop debian/schism.1 and manpages, upstream ships a better one. + * Upstream renamed schism binary to schismtracker. + * Updated debian/menu. + * Change my name. +Author: Gürkan Myczko +Bug-Debian: https://bugs.debian.org/730571 + +--- +The information above should follow the Patch Tagging Guidelines, please +checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here +are templates for supplementary fields that you might want to add: + +Origin: , +Bug: +Bug-Debian: https://bugs.debian.org/ +Bug-Ubuntu: https://launchpad.net/bugs/ +Forwarded: +Reviewed-By: +Last-Update: 2016-08-03 + +--- schism-20160521.orig/sys/posix/schismtracker.1 ++++ schism-20160521/sys/posix/schismtracker.1 +@@ -104,7 +104,6 @@ The four sub-columns of each channel are + effect. A list of effects is available in the pattern editor help, but you can + safely ignore that column for now. Assuming a US keymap, notes are entered + with the keyboard as follows: +-.PS + (Note) C# D# F# G# A# C# D# F# G# A# C# D# + | | || | | | || || | | | || | | | || || | | | || | | + | | || | | | || || | | | || | | | || || | | | || | | diff -Nru schism-0+20110101/debian/patches/series schism-20160521/debian/patches/series --- schism-0+20110101/debian/patches/series 2011-02-18 14:18:04.000000000 +0000 +++ schism-20160521/debian/patches/series 2016-07-26 07:53:37.000000000 +0000 @@ -1 +1,2 @@ -01-binutils_gold.patch +invalid-macro-PS +drop-macro-PE diff -Nru schism-0+20110101/debian/rules schism-20160521/debian/rules --- schism-0+20110101/debian/rules 2010-09-05 18:26:21.000000000 +0000 +++ schism-20160521/debian/rules 2016-07-26 07:53:37.000000000 +0000 @@ -1,5 +1,8 @@ #! /usr/bin/make -f +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/buildflags.mk + %: dh --with=autoreconf $@ @@ -13,8 +16,6 @@ override_dh_auto_install: dh_auto_install - mv $(CURDIR)/debian/schism/usr/bin/schismtracker \ - $(CURDIR)/debian/schism/usr/bin/schism dh_install icons/schism-icon-128.png usr/share/icons/ override_dh_installchangelogs: diff -Nru schism-0+20110101/debian/schism.1 schism-20160521/debian/schism.1 --- schism-0+20110101/debian/schism.1 2010-09-05 17:55:29.000000000 +0000 +++ schism-20160521/debian/schism.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -.TH SCHISM 1 "October 28, 2006" -.SH NAME -schism \- music editor -.SH SYNOPSIS -.B schism -[ \fIoptions \fR] -[ \fIdirectory \fR] -[ \fIfile \fR] -.SH DESCRIPTION -This manual page documents briefly the -.B schism -command. -.PP -\fBschism\fP is a music editor (tracker) that aims to match the look and feel -of Impulse Tracker so closely as possible. It can edit the following music -modules formats it (native), s3m, xm, mod. -.SH OPTIONS -.TP -.B -a DRIVER, --audio-driver=DRIVER -SDL audio driver (or "none") -.TP -.B -v DRIVER, --video-driver=DRIVER -SDL video driver -.TP -.B --classic, --no-classic -start schism in classic mode -.TP -.B --display=DISPLAYNAME -X11 display to use (e.g. ":0.0") -.TP -.B -f, +f, --fullscreen, --no-fullscreen -start in fullscreen mode -.TP -.B -p, +p, --play, --no-play -start playing after loading song on command line -.TP -.B --font-editor, --no-font-editor -start in font-editor (itf) -.TP -.B --hooks, --no-hooks -run startup/exit hooks (default: enabled) -.TP -.B --version -display version information -.TP -.B -h, --help -print this stuff -.SH SEE ALSO -.BR ocp (1). -.SH AUTHOR -Impulse Tracker was written by Jeffrey Lim. A clone was written by -Storlek/chisel, which is now maintained by Mrs. Brisby. -.PP -This manual page was written by G\[:u]rkan Seng\[:u]n . diff -Nru schism-0+20110101/depcomp schism-20160521/depcomp --- schism-0+20110101/depcomp 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/depcomp 1970-01-01 00:00:00.000000000 +0000 @@ -1,630 +0,0 @@ -#! /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: diff -Nru schism-0+20110101/docs/building_on_linux.md schism-20160521/docs/building_on_linux.md --- schism-0+20110101/docs/building_on_linux.md 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/docs/building_on_linux.md 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,115 @@ +# Building on Linux + +Since Linux is the primary development platform for Schism Tracker, it's +probably the easiest to compile on, and those familiar with automake-based +projects will find few surprises here. + +## Prerequisites + +You'll need [autoconf](http://www.gnu.org/software/autoconf/), +[automake](http://www.gnu.org/software/automake/), [gcc](http://gcc.gnu.org/), +[make](http://www.gnu.org/software/make/), [Python](https://www.python.org/) +and [LibSDL](http://www.libsdl.org/) *at a minimum*. Additionally, +[Git](https://git-scm.com/) is strongly recommended. If all you're planning on +doing is building it once, you can just as easily grab the source tarball from +the repository and build from that, but having Git installed makes it easier to +keep up-to-date, help with debugging, and (if you're so inclined) development. + +See below for distro-specific instructions on how to get everything installed +in order to build Schism Tracker. + +To get the source: + + git clone https://github.com/schismtracker/schismtracker.git + cd schismtracker && autoreconf -i + +You can then update your schismtracker source directory by going to this +schismtracker directory and running: + + git pull + +## Building Schism Tracker + +To build Schism Tracker, you should set up a build-directory. From the +schismtracker directory: + + mkdir -p build && cd build && ../configure && make + +The resulting binary `schismtracker` is completely self-contained and can be +copied anywhere you like on the filesystem. + +## Packaging Schism Tracker for Linux systems + +The `icons/` directory contains icons that you may find suitable for your +desktop environment. The `sys/fd.org/schism.desktop` can be used to launch +Schism Tracker from a desktop environment, and `sys/fd.org/itf.desktop` can be +used to launch the built-in font-editor. + +## ALSA problems + +The configure script should autodetect everything on your system, but if you +don't have the ALSA development libraries installed, Schism Tracker won't be +built with ALSA MIDI support, even if your SDL libraries include ALSA digital +output. + +See below for information on what packages you should install for your +distribution in order to build a full-featured Schism Tracker binary. + +## Cross-compiling Win32 + +Schism Tracker can be built using the mingw32 cross-compiler on a Linux host. +You will also need the [SDL MINGW32 development +library](http://libsdl.org/download-1.2.php). If you unpacked it into +`/usr/i586-mingw32/`, you could use the following to cross-compile Schism +Tracker for Win32: + + mkdir win32-build + cd build + env SDL_CONFIG=/usr/i586-mingw32/sdl-config \ + ../configure --{host,target}=i586-mingw32 --without-x + make + +If you want to build an installer using the [nullsoft scriptable install +system](http://nsis.sourceforge.net/), copy some files into your build +directory: + + cd build + cp /usr/i586-mingw32/bin/SDL.dll . + cp ../COPYING COPYING.txt + cp ../README README.txt + cp ../NEWS NEWS.txt + cp ../sys/win32/schism.nsis . + cp ../icons/schismres.ico schism.ico + +and run the makensis application: + + makensis schism.nsis + +## Distribution-specific instructions + +Getting the prerequisites covered is fairly straightforward in most Linux +distributions. + +#### Ubuntu / Debian + + apt-get install build-essential automake autoconf autoconf-archive \ + libx11-dev libxext-dev libxv-dev libxxf86misc-dev \ + libxxf86vm-dev libsdl1.2-dev libasound2-dev mercurial \ + libtool + +Additionally, for cross-compiling win32 binaries: + + apt-get install mingw32 mingw32-binutils mingw32-runtime nsis + +#### Arch Linux + + pacman -S base-devel mercurial sdl alsa-lib libxv libxxf86vm + +For cross-compiling win32 binaries: + + pacman -S mingw-w64-gcc + yaourt -S mingw-w64-sdl nsis + +Note: yaourt isn't strictly necessary, but since `mingw-w64-sdl` and `nsis` are +AUR packages, you'll have to build them by hand otherwise or use a different +[AUR helper](https://wiki.archlinux.org/index.php/AUR_helpers). diff -Nru schism-0+20110101/docs/building_on_osx.md schism-20160521/docs/building_on_osx.md --- schism-0+20110101/docs/building_on_osx.md 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/docs/building_on_osx.md 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,76 @@ +# Building on OS X + +Building on Mac OS X is fairly straightforward once you've installed the Apple +Developer's kit. If you have [Homebrew](http://brew.sh/) available, you should +be able to install SDL with a simple `brew install sdl`, after which you can +mostly follow the Linux instructions and you'll end up with a unix-style +`schismtracker` binary that you can run from `Terminal.app`. + +Alternately, you can also install the [SDL Developers +Library](http://libsdl.org/download-1.2.php), but this tends to be somewhat +more complicated as all the required pieces aren't shipped in the same package. +Make sure to grab both the source and the Runtime Libraries, and some reports +suggest that you might have to fiddle with paths to get `sdl.m4` working. But +really, there's not much advantage over just using `brew`. + +If you want a "normal" application that you could drop into `/Applications`, +put in your dock, etc., copy that `schismtracker` binary into +`sys/macosx/Schism Tracker.app/Contents/MacOS/`, and then you can copy that +bundle around like any other app. It will associate itself with .IT (and other) +files, so you can double-click them and the Finder will load Schism Tracker +automatically. + +However, if you want to build an application bundle *for distribution*, there's +a few potential snags. In particular, SDK versions are backward-incompatible, +so you need to make note of what version you're building with; and if you also +want to support the dwindling population of PowerPC users, you'll have to build +a Universal binary. Plus, since SDL is not normally present on OS X, you'll +need to bundle it in with the application. + +There used to be somewhat lengthy instructions here elaborating on various +nuances of installing Fink and managing multiple SDKs, but these have become +rather outdated and probably less than thoroughly useful. If anyone has current +and first-hand experience with building on OS X which might be helpful to +others, please feel free to share. + +## Cross-compiling on a Linux host + +[This page](http://devs.openttd.org/~truebrain/compile-farm/apple-darwin9.txt) +has some notes that might be of use in building a cross-compilation toolchain. +Building a cross-compiler is *not* an easy process, and will probably take the +better part of a day; however, it is definitely possible, and in fact is what I +use for compiling the "official" OS X packages. The build process is rather +messy, but it goes something like: + + mkdir -p osx/{x86,ppc} + cd osx/x86 + env PATH=/usr/i686-apple-darwin9/bin:${PATH} \ + {C,CXX,OBJC}FLAGS='-g0 -O2' LDFLAGS=-s \ + ../../configure --with-sdl-prefix=/usr/i686-apple-darwin9 \ + --{target,host}=i686-apple-darwin9 \ + --build-i686-linux + env PATH=/usr/i686-apple-darwin9/bin:${PATH} make + cd ../ppc + env PATH=/usr/powerpc-apple-darwin9/bin:${PATH} \ + {C,CXX,OBJC}FLAGS='-g0 -O2' LDFLAGS=-s \ + ../../configure --with-sdl-prefix=/usr/powerpc-apple-darwin9 \ + --{target,host}=powerpc-apple-darwin9 \ + --build-i686-linux + env PATH=/usr/powerpc-apple-darwin9/bin:${PATH} make + cd .. + /usr/i686-apple-darwin9/bin/lipo -create -o {.,x86,ppc}/schismtracker + /usr/i686-apple-darwin9/bin/install_name_tool -change \ + '@executable_path/../Frameworks/SDL.framework/Versions/A/SDL' \ + '@executable_path/sdl.dylib' schismtracker + +Then copy the `lipo`'ed `schismtracker` and `sdl.dylib` both into the `MacOS/` +folder in the bundle, and it Should Work. The versions I have installed are GCC +4.0.1 (SVN v5493), ODCCTools SVN v280, and XCode SDK 3.1.3. This SDK version +advertises compatibility with 10.4 at minimum, although people have reported +success in running Schism Tracker on 10.3.9. + +Note: because parts of the debugging information are conspicuously absent, +cross-compiling with debugging symbols simply isn't possible. This isn't very +likely to be useful anyway; if you can run the program in a debugger, then +you're *probably* running OS X, in which case you might as well just build +natively and eliminate the hassle. diff -Nru schism-0+20110101/docs/building_on_windows.md schism-20160521/docs/building_on_windows.md --- schism-0+20110101/docs/building_on_windows.md 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/docs/building_on_windows.md 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,165 @@ +# Building on Windows + +_This page was adapted from COMPILE-WIN32.txt traditionally provided with +Schism Tracker sources. Any additional notes are in italics, like this one_ + +## Software needed + +To compile on Windows, the following things are needed: + +* mingw-gcc +* Python +* SDL headers and libs +* An environment in which to run them, like msys (It could also be cygwin. Use + its setup program, and get sdl sources to compile them in this case). + +## Installing needed software + +_note: follow the instructions in either the x86/Win32 or the x64/Win64 +section, but not both!_ + +### Installing mingw and msys (x86/Win32) + +They've recently created an installer that maintains packages, that works +nicely: +[http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download](http://sourceforge.net/projects/mingw/files/Installer/mingw-get-setup.exe/download) +That installer can also install msys if told to do so. + +If installing msys, then run `(installdir)\msys\1.0\postinstall\pi.sh` to set +up where mingw is located. + +Get Python from [http://www.python.org](http://www.python.org) and install it. +Get version 2 for now. + +Add Python to msys PATH. You can do it in two ways: + +* Add the path to Windows PATH Environment variable (msys will add it + automatically to msys's environment. You will need to relaunch it after the + change) +* OR modify the msys file `/etc/profile` and modify the export PATH adding your + python path. (like `export PATH=/c/python27:$PATH`) + +For mingw x86, there is a precompiled libs and headers package that can be +downloaded from [http://www.libsdl.org/](http://www.libsdl.org/). At the time +of this writing, there's the file: SDL-devel-1.2.15-mingw32.tar.gz (Mingw32). + +You can unpack this file into mingw by copying individually the folders bin, +include, lib and share into C:/MinGW (if that's the name you used). The rest of +the package is not needed, as it contains examples, and other documentation, +some of it used to build from source, which is not needed with this package. + +Also, you will need to modify the file `sdl-config` to change the "prefix" +path. Like this: `prefix=/mingw` + +### Installing mingw and msys (x64/Win64) + +_note: To build for 64-bit, you will have to compile your own SDL libraries. To +build them with DirectX support (Schism doesn't run very well on Windows +without DirectX support) may require Visual Studio. If you don't have Visual +Studio you may be better off using 32-bit and the precompiled SDL libraries. +Alternatively, something that has been known to work is to compile SDL without +DirectX support and then replace the built SDL.dll with an SDL.dll from +somewhere else (where it is known to have DirectX support)._ + +Since mingw's installer only installs an x86 platform, you might opt to install +winBuilds: [http://win-builds.org/](http://win-builds.org/) + +Follow the instructions from the x86 section to set up msys and python. + +For x64, there aren't precompiled SDL libs, so you have to get the sources to +compile them from [http://www.libsdl.org/](http://www.libsdl.org/). At the +time of this writing, there's the file: SDL-1.2.15.tar.gz + +Unpack it somewhere (like `C:/msys/opt/SDL`). + +Get Microsoft's DirectX SDK from +[http://www.microsoft.com/en-us/download/details.aspx?id=6812](http://www.microsoft.com/en-us/download/details.aspx?id=6812) +and install it. + +Now, you need msys/mingw to know about your directx includes and libs. This is +a little tricky and the best solution I found was to make symbolic links (`ln +-s`) to the directories as follows: + +Let's say that the Direct X SDK is installed in `C:\Program Files +(x86)\Microsoft DirectX SDK (June 2010)` + +1. Run msys, and go to `/mingw/include` +2. type `ln -s C:/Program\ Files\ \(x86\)/Microsoft\ DirectX\ SDK\ \(June\ + 2010\)/Include dxinclude` +3. go to `/mingw/lib` +4. type `ln -s C:/Program\ Files\ \(x86\)/Microsoft\ DirectX\ SDK\ \(June\ + 2010\)/Lib dxlib` + +I also had to copy the file `C:\Program Files (x86)\Microsoft Visual Studio +9.0\VC\include\sal.h` to `/mingw/include`. This file's header says: "sal.h - +markers for documenting the semantics of APIs". It only has some defines, so it +might be safe to just put an empty file (not tried _[note: tried, doesn't +work]_). Else, it might be obtained from Visual Studio. + +Now, go to where you copied the SDL SDK (`example: /opt/SDL/`) , and do +`./configure CPPFLAGS=-I/mingw/include/dxinclude LIBS=-L/mingw/lib/dxlib` + +Now look at the output of configure and see if it says something like: + + checking ddraw.h usability + result: yes + checking dsound.h usability + result: yes + +(This is extracted from config.log. the output in the screen is a bit +different) + +If it says no, open the config.log file, locate the lines and see which test +fail and why. + +If the `./configure` executes successfully and you have ddraw _(note: you probably don't - ddraw.h isn't actually supplied with the DirectX SDK! It may be supplied with Visual Studio)_ and dsound, then continue with + + make + make install + +## Compilation + +Run msys (`C:/msys/1.0/msys.bat`), go to schismtracker sources (hint: drive +letters are mapped to /x , example C:/ is /c/, D:/ is /d/ ...) + +If configure does not exist, (you will need autoconf and automake _[note: you +can install them through the mingw GUI package manager - they are part of a +package called "autotools"]_) execute: + + autoreconf -i + +Alternatively, you can execute each individual command: + + aclocal + autoconf + autoheader + automake --add-missing + +If you get a warning that AM_PATH_SDL is missing, you should check where the +sdl.m4 _(note: the folder where you unpacked SDL, probably. `grep -r "sdl.m4" +/` for it)_ is, and use the -I parameter like: + + aclocal -I/usr/local/share/aclocal + autoconf + autoheader + automake --add-missing + +Once `./configure` exists, run: + + mkdir build + cd build + ../configure + make + +And you should find a `schismtracker.exe` in the `build/` directory. + +## Debugging + +Msys comes (if installed) with a 32bit gdb version. you can use it to debug the +32bit version of Schismtracker. + +For the 64bit version, you can get it from +[http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/gdb/](http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/gdb/) +I got a newer version from here : +[http://www.equation.com/servlet/equation.cmd?fa=gdb](http://www.equation.com/servlet/equation.cmd?fa=gdb) +I named the file gdb64 so that it didn't get mistaken for the other. diff -Nru schism-0+20110101/docs/configuration.md schism-20160521/docs/configuration.md --- schism-0+20110101/docs/configuration.md 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/docs/configuration.md 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,199 @@ +# Configuration + +Schism Tracker saves its configuration in a plain-text, +[INI-style](http://en.wikipedia.org/wiki/INI_file) file named `config`. Under +normal circumstances it should theoretically not be necessary to deal with this +file directly. However, there are some options that are not configurable from +within Schism Tracker for one reason or another. In these cases, any plain text +editor should suffice. + +The location of this file is dependent on the OS: + +- **Windows** + - `%APPDATA%\Schism Tracker` +- **Mac OS X** + - `~/Library/Application Support/Schism Tracker` +- **AmigaOS 4** + - `PROGDIR:` +- **Linux/Unix** + - `$HOME/.schism/` +- **Wii** + - Same directory as `boot.elf` (e.g. `sd:/apps/schismtracker`) + +Aside from `config`, you may also add a `fonts` subdirectory for custom font +files. By default, `font.cfg` is automatically loaded on startup, and other +`*.itf` files are listed by the built-in font editor (Shift-F12). See [the +links page](https://github.com/schismtracker/schismtracker/wiki/Links) for some +resources on getting fonts for Schism Tracker. + +## Potentially useful "hidden" config options + +To enable any of these, find the `[section]` in the config file, look for the +`key=`, and change the value. If the key doesn't exist, simply add it. + +#### Lazy redraw + + [General] + lazy_redraw=1 + +Slow down the framerate when the program isn't focused. This used to be kind of +useful when the GUI rendering sucked, and maybe it still is if you're stuck +with a painfully slow video card and software rendering, and you also want to +have a huge window that isn't active. + +#### Backups + + [General] + make_backups=1 + numbered_backups=1 + +When overwriting a `filename.it`, copy the existing file to `filename.it~`. +With numbered_backups, write to `filename.it.1~`, `filename.it.2~`, etc. + +#### Key repeat + + [General] + key_repeat_delay=125 + key_repeat_rate=25 + +Alter the key repeat. "Delay" is how long before keys begin to repeat, "rate" +is how long between repeated keystrokes. (Both are in milliseconds.) Above are +[Storlek](https://github.com/schismtracker/schismtracker/wiki/Storlek)'s +settings, which are very fast but convenient for speed tracking. + +The *default* repeat delay and rate come from your operating system, so you +only need to set this if you like having a different rate for Schism Tracker +than you do for the rest of your system. + +#### Alternate font + + [General] + font=notch.itf + +Load some other font besides `font.cfg` at startup. This option doesn't really +have much of a point, because the file listed is limited to those within the +`fonts` directory, and it's just easier to open the font editor, browse fonts, +and save to `font.cfg`. + +#### DJ mode + + [General] + stop_on_load=0 + +If zero, loading a song when another one is playing will start playing the new +song after it is loaded. + +#### File browser + + [Directories] + module_pattern=*.it\073 *.xm\073 *.s3m\073 *.mtm\073 *.669\073 *.mod + +Changes what files are presented in the load/save module lists. Use * for all +files. For annoying compatibility reasons, semicolons are rewritten as `\x3b` +or `\073` when saving. + +This was formerly named `filename_pattern`; Schism Tracker ignores the old +value and comments it out when saving to work around bugs in older versions. + + sort_with=strcasecmp + +Alter the sort order. Possible values are `strcmp` (case-sensitive), +`strcasecmp` (case-insensitive), and `strverscmp` (case-sensitive, but handles +numbers smartly e.g. `5.it` will be listed above `10.it`). + +#### Keyjazz + + [Pattern Editor] + keyjazz_noteoff=1 + keyjazz_repeat=0 + +If `keyjazz_noteoff` is 1, letting go of a key in the pattern editor will cause +a note-off. If using this, you might also want to consider setting +`keyjazz_repeat` to 0 in order to avoid inserting multiple notes when holding +down keys. + +#### Pattern editor behavior tweaks + + [Pattern Editor] + mask_copy_search_mode=1 + invert_home_end=1 + +When `mask_copy_search_mode` is set to 1, pressing Enter on a row with no +instrument number will search backward in the channel for an instrument and +switch to that one. + +`invert_home_end` changes the order of the Home and End keys to make the cursor +move to the first or last row within the channel before moving to the first or +last channel. FT2 users might want to enable this. + +(These features were recently added and are not available yet for older +versions) + +#### Key modifiers + + [General] + meta_is_ctrl=1 + altgr_is_alt=1 + +These alter how modifier keys are interpreted. Mac OS X users in particular +might appreciate `meta_is_ctrl`, which allows using the Command/Apple key as +the Ctrl modifier within Schism Tracker. `altgr_is_alt` works similarly. + +#### Audio output + + [Audio] + buffer_size=256 + driver=dsp:/dev/dsp1 + +These settings define the audio buffer size, and which audio device Schism +Tracker uses. (The other settings in the `[Audio]` section are configurable +from Shift-F1.) `buffer_size` should be a power of two and defines the number +of samples in the mixing buffer. Smaller values result in less audio latency +but could cause buffer underruns and skipping. + +`driver` is parsed identically to the `--audio-driver` switch on the command +line. If you're using Alsa on Linux and want to use you can set +`driver=alsa:dmix` to get Schism Tracker to play with other programs. (However, +Alsa completely ignores the latency with dmix so it might cause massive delays +between pressing a note and hearing it, which is why Schism Tracker requests a +"real" device by default.) + + [Diskwriter] + rate=96000 + bits=16 + channels=2 + +This defines the sample format used by the disk writer – for exporting to +.wav/.aiff *and* internal pattern-to-sample rendering. + +## Hook functions + +Schism Tracker can run custom scripts on startup, exit, and upon completion of +the disk writer. These are stored in the configuration directory, and are named +`startup-hook`, `exit-hook`, and `diskwriter-hook` respectively. (On Windows, +append `.bat` to the filenames.) Hooks are useful for making various +adjustments to the system – adjusting the system volume, remapping the +keyboard, etc. The disk writer hook can be used to do additional +post-processing, converting, etc. (Note: on the Wii, hooks are not processed +since there is no underlying OS or command interpreter to run them.) + +#### Example + +For users with non-US keyboards, some keys may not work properly. This can be +worked around by switching temporarily to a US keyboard layout on startup, and +resetting the keyboard on exit. To define hooks to accomplish this: + + cat >~/.schism/startup-hook <~/.schism/exit-hook < * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -31,54 +31,54 @@ /* --------------------------------------------------------------------- */ struct header_669 { - char sig[2]; - char songmessage[108]; - uint8_t samples; - uint8_t patterns; - uint8_t restartpos; - uint8_t orders[128]; - uint8_t tempolist[128]; - uint8_t breaks[128]; + char sig[2]; + char songmessage[108]; + uint8_t samples; + uint8_t patterns; + uint8_t restartpos; + uint8_t orders[128]; + uint8_t tempolist[128]; + uint8_t breaks[128]; }; int fmt_669_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - struct header_669 *header = (struct header_669 *) data; - unsigned long i; - const char *desc; - - if (length < sizeof(struct header_669)) - return 0; - - /* Impulse Tracker identifies any 669 file as a "Composer 669 Module", - regardless of the signature tag. */ - if (memcmp(header->sig, "if", 2) == 0) - desc = "Composer 669 Module"; - else if (memcmp(header->sig, "JN", 2) == 0) - desc = "Extended 669 Module"; - else - return 0; - - if (header->samples == 0 || header->patterns == 0 - || header->samples > 64 || header->patterns > 128 - || header->restartpos > 127) - return 0; - for (i = 0; i < 128; i++) - if (header->breaks[i] > 0x3f) - return 0; - - /* From my very brief observation, it seems the message of a 669 file is split into 3 lines. - This (naively) takes the first line of it as the title, as the format doesn't actually have - a field for a song title. */ - file->title = (char *) calloc(37, sizeof(char)); - memcpy(file->title, header->songmessage, 36); - file->title[36] = 0; - - file->description = desc; - /*file->extension = str_dup("669");*/ - file->type = TYPE_MODULE_S3M; + struct header_669 *header = (struct header_669 *) data; + unsigned long i; + const char *desc; + + if (length < sizeof(struct header_669)) + return 0; + + /* Impulse Tracker identifies any 669 file as a "Composer 669 Module", + regardless of the signature tag. */ + if (memcmp(header->sig, "if", 2) == 0) + desc = "Composer 669 Module"; + else if (memcmp(header->sig, "JN", 2) == 0) + desc = "Extended 669 Module"; + else + return 0; + + if (header->samples == 0 || header->patterns == 0 + || header->samples > 64 || header->patterns > 128 + || header->restartpos > 127) + return 0; + for (i = 0; i < 128; i++) + if (header->breaks[i] > 0x3f) + return 0; + + /* From my very brief observation, it seems the message of a 669 file is split into 3 lines. + This (naively) takes the first line of it as the title, as the format doesn't actually have + a field for a song title. */ + file->title = (char *) calloc(37, sizeof(char)); + memcpy(file->title, header->songmessage, 36); + file->title[36] = 0; + + file->description = desc; + /*file->extension = str_dup("669");*/ + file->type = TYPE_MODULE_S3M; - return 1; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -87,238 +87,238 @@ int fmt_669_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint8_t b[16]; - uint16_t npat, nsmp; - int n, pat, chan, smp, row; - song_note_t *note; - uint16_t tmp; - uint32_t tmplong; - uint8_t patspeed[128], breakpos[128]; - uint8_t restartpos; - const char *tid; - char titletmp[37]; - - slurp_read(fp, &tmp, 2); - switch (bswapLE16(tmp)) { - case 0x6669: // 'if' - tid = "Composer 669"; - break; - case 0x4e4a: // 'JN' - tid = "UNIS 669"; - break; - default: - return LOAD_UNSUPPORTED; - } - - /* The message is 108 bytes, split onto 3 lines of 36 bytes each. - Also copy the first part of the message into the title, because 669 doesn't actually have - a dedicated title field... */ - read_lined_message(song->message, fp, 108, 36); - strncpy(titletmp, song->message, 36); - titletmp[36] = '\0'; - titletmp[strcspn(titletmp, "\r\n")] = '\0'; - trim_string(titletmp); - titletmp[25] = '\0'; - strcpy(song->title, titletmp); - - nsmp = slurp_getc(fp); - npat = slurp_getc(fp); - restartpos = slurp_getc(fp); - - if (nsmp > 64 || npat > 128 || restartpos > 127) - return LOAD_UNSUPPORTED; - - strcpy(song->tracker_id, tid); - - /* orderlist */ - slurp_read(fp, song->orderlist, 128); - - /* stupid crap */ - slurp_read(fp, patspeed, 128); - slurp_read(fp, breakpos, 128); - - /* samples */ - for (smp = 1; smp <= nsmp; smp++) { - slurp_read(fp, b, 13); - b[13] = 0; /* the spec says it's supposed to be ASCIIZ, but some 669's use all 13 chars */ - strcpy(song->samples[smp].name, (char *) b); - b[12] = 0; /* ... filename field only has room for 12 chars though */ - strcpy(song->samples[smp].filename, (char *) b); - - slurp_read(fp, &tmplong, 4); - song->samples[smp].length = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - song->samples[smp].loop_start = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - tmplong = bswapLE32(tmplong); - if (tmplong > song->samples[smp].length) - tmplong = 0; - else - song->samples[smp].flags |= CHN_LOOP; - song->samples[smp].loop_end = tmplong; - - song->samples[smp].c5speed = 8363; - song->samples[smp].volume = 60; /* ickypoo */ - song->samples[smp].volume *= 4; //mphack - song->samples[smp].global_volume = 64; /* ickypoo */ - song->samples[smp].vib_type = 0; - song->samples[smp].vib_rate = 0; - song->samples[smp].vib_depth = 0; - song->samples[smp].vib_speed = 0; - } - - /* patterns */ - for (pat = 0; pat < npat; pat++) { - uint8_t effect[8] = { - 255, 255, 255, 255, 255, 255, 255, 255 - }; - uint8_t rows = breakpos[pat] + 1; - - note = song->patterns[pat] = csf_allocate_pattern(CLAMP(rows, 32, 64)); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = CLAMP(rows, 32, 64); - - for (row = 0; row < rows; row++, note += 56) { - for (chan = 0; chan < 8; chan++, note++) { - slurp_read(fp, b, 3); - - switch (b[0]) { - case 0xfe: /* no note, only volume */ - note->voleffect = VOLFX_VOLUME; - note->volparam = (b[1] & 0xf) << 2; - break; - case 0xff: /* no note or volume */ - break; - default: - note->note = (b[0] >> 2) + 36 + 1; - note->instrument = ((b[0] & 3) << 4 | (b[1] >> 4)) + 1; - note->voleffect = VOLFX_VOLUME; - note->volparam = (b[1] & 0xf) << 2; - break; - } - /* (sloppily) import the stupid effect */ - if (b[2] != 0xff) - effect[chan] = b[2]; - if (effect[chan] == 0xff) - continue; - note->param = effect[chan] & 0xf; - switch (effect[chan] >> 4) { - default: - /* oops. never mind. */ - //printf("ignoring effect %X\n", effect[chan]); - note->param = 0; - break; - case 0: /* A - portamento up */ - note->effect = FX_PORTAMENTOUP; - break; - case 1: /* B - portamento down */ - note->effect = FX_PORTAMENTODOWN; - break; - case 2: /* C - port to note */ - note->effect = FX_TONEPORTAMENTO; - break; - case 3: /* D - frequency adjust (??) */ - note->effect = FX_PORTAMENTODOWN; - if (note->param) - note->param |= 0xf0; - else - note->param = 0xf1; - effect[chan] = 0xff; - break; - case 4: /* E - frequency vibrato */ - note->effect = FX_VIBRATO; - note->param |= 0x80; - break; - case 5: /* F - set tempo */ - /* TODO: param 0 is a "super fast tempo" in extended mode (?) */ - if (note->param) - note->effect = FX_SPEED; - effect[chan] = 0xff; - break; - case 6: /* G - subcommands (extended) */ - switch (note->param) { - case 0: /* balance fine slide left */ - //TODO("test pan slide effect (P%dR%dC%d)", pat, row, chan); - note->effect = FX_PANNINGSLIDE; - note->param = 0x8F; - break; - case 1: /* balance fine slide right */ - //TODO("test pan slide effect (P%dR%dC%d)", pat, row, chan); - note->effect = FX_PANNINGSLIDE; - note->param = 0xF8; - break; - default: - /* oops, nothing again */ - note->param = 0; - } - break; - case 7: /* H - slot retrig */ - //TODO("test slot retrig (P%dR%dC%d)", pat, row, chan); - note->effect = FX_RETRIG; - break; - } - } - } - if (rows < 64) { - /* skip the rest of the rows beyond the break position */ - slurp_seek(fp, 3 * 8 * (64 - rows), SEEK_CUR); - } - - /* handle the stupid pattern speed */ - note = song->patterns[pat]; - for (chan = 0; chan < 9; chan++, note++) { - if (note->effect == FX_SPEED) { - break; - } else if (!note->effect) { - note->effect = FX_SPEED; - note->param = patspeed[pat]; - break; - } - } - /* handle the break position */ - if (rows < 32) { - //printf("adding pattern break for pattern %d\n", pat); - note = song->patterns[pat] + MAX_CHANNELS * (rows - 1); - for (chan = 0; chan < 9; chan++, note++) { - if (!note->effect) { - note->effect = FX_PATTERNBREAK; - note->param = 0; - break; - } - } - } - } - csf_insert_restart_pos(song, restartpos); - - /* sample data */ - if (!(lflags & LOAD_NOSAMPLES)) { - for (smp = 1; smp <= nsmp; smp++) { - uint32_t ssize; - - if (song->samples[smp].length == 0) - continue; - - ssize = csf_read_sample(song->samples + smp, SF_LE | SF_M | SF_PCMU | SF_8, - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, ssize, SEEK_CUR); - } - } - - /* set the rest of the stuff */ - song->initial_speed = 4; - song->initial_tempo = 78; - song->flags = SONG_ITOLDEFFECTS | SONG_LINEARSLIDES; - - song->pan_separation = 64; - for (n = 0; n < 8; n++) - song->channels[n].panning = (n & 1) ? 256 : 0; //mphack - for (n = 8; n < 64; n++) - song->channels[n].flags = CHN_MUTE; + uint8_t b[16]; + uint16_t npat, nsmp; + int n, pat, chan, smp, row; + song_note_t *note; + uint16_t tmp; + uint32_t tmplong; + uint8_t patspeed[128], breakpos[128]; + uint8_t restartpos; + const char *tid; + char titletmp[37]; + + slurp_read(fp, &tmp, 2); + switch (bswapLE16(tmp)) { + case 0x6669: // 'if' + tid = "Composer 669"; + break; + case 0x4e4a: // 'JN' + tid = "UNIS 669"; + break; + default: + return LOAD_UNSUPPORTED; + } + + /* The message is 108 bytes, split onto 3 lines of 36 bytes each. + Also copy the first part of the message into the title, because 669 doesn't actually have + a dedicated title field... */ + read_lined_message(song->message, fp, 108, 36); + strncpy(titletmp, song->message, 36); + titletmp[36] = '\0'; + titletmp[strcspn(titletmp, "\r\n")] = '\0'; + trim_string(titletmp); + titletmp[25] = '\0'; + strcpy(song->title, titletmp); + + nsmp = slurp_getc(fp); + npat = slurp_getc(fp); + restartpos = slurp_getc(fp); + + if (nsmp > 64 || npat > 128 || restartpos > 127) + return LOAD_UNSUPPORTED; + + strcpy(song->tracker_id, tid); + + /* orderlist */ + slurp_read(fp, song->orderlist, 128); + + /* stupid crap */ + slurp_read(fp, patspeed, 128); + slurp_read(fp, breakpos, 128); + + /* samples */ + for (smp = 1; smp <= nsmp; smp++) { + slurp_read(fp, b, 13); + b[13] = 0; /* the spec says it's supposed to be ASCIIZ, but some 669's use all 13 chars */ + strcpy(song->samples[smp].name, (char *) b); + b[12] = 0; /* ... filename field only has room for 12 chars though */ + strcpy(song->samples[smp].filename, (char *) b); + + slurp_read(fp, &tmplong, 4); + song->samples[smp].length = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + song->samples[smp].loop_start = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + tmplong = bswapLE32(tmplong); + if (tmplong > song->samples[smp].length) + tmplong = 0; + else + song->samples[smp].flags |= CHN_LOOP; + song->samples[smp].loop_end = tmplong; + + song->samples[smp].c5speed = 8363; + song->samples[smp].volume = 60; /* ickypoo */ + song->samples[smp].volume *= 4; //mphack + song->samples[smp].global_volume = 64; /* ickypoo */ + song->samples[smp].vib_type = 0; + song->samples[smp].vib_rate = 0; + song->samples[smp].vib_depth = 0; + song->samples[smp].vib_speed = 0; + } + + /* patterns */ + for (pat = 0; pat < npat; pat++) { + uint8_t effect[8] = { + 255, 255, 255, 255, 255, 255, 255, 255 + }; + uint8_t rows = breakpos[pat] + 1; + + note = song->patterns[pat] = csf_allocate_pattern(CLAMP(rows, 32, 64)); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = CLAMP(rows, 32, 64); + + for (row = 0; row < rows; row++, note += 56) { + for (chan = 0; chan < 8; chan++, note++) { + slurp_read(fp, b, 3); + + switch (b[0]) { + case 0xfe: /* no note, only volume */ + note->voleffect = VOLFX_VOLUME; + note->volparam = (b[1] & 0xf) << 2; + break; + case 0xff: /* no note or volume */ + break; + default: + note->note = (b[0] >> 2) + 36 + 1; + note->instrument = ((b[0] & 3) << 4 | (b[1] >> 4)) + 1; + note->voleffect = VOLFX_VOLUME; + note->volparam = (b[1] & 0xf) << 2; + break; + } + /* (sloppily) import the stupid effect */ + if (b[2] != 0xff) + effect[chan] = b[2]; + if (effect[chan] == 0xff) + continue; + note->param = effect[chan] & 0xf; + switch (effect[chan] >> 4) { + default: + /* oops. never mind. */ + //printf("ignoring effect %X\n", effect[chan]); + note->param = 0; + break; + case 0: /* A - portamento up */ + note->effect = FX_PORTAMENTOUP; + break; + case 1: /* B - portamento down */ + note->effect = FX_PORTAMENTODOWN; + break; + case 2: /* C - port to note */ + note->effect = FX_TONEPORTAMENTO; + break; + case 3: /* D - frequency adjust (??) */ + note->effect = FX_PORTAMENTODOWN; + if (note->param) + note->param |= 0xf0; + else + note->param = 0xf1; + effect[chan] = 0xff; + break; + case 4: /* E - frequency vibrato */ + note->effect = FX_VIBRATO; + note->param |= 0x80; + break; + case 5: /* F - set tempo */ + /* TODO: param 0 is a "super fast tempo" in extended mode (?) */ + if (note->param) + note->effect = FX_SPEED; + effect[chan] = 0xff; + break; + case 6: /* G - subcommands (extended) */ + switch (note->param) { + case 0: /* balance fine slide left */ + //TODO("test pan slide effect (P%dR%dC%d)", pat, row, chan); + note->effect = FX_PANNINGSLIDE; + note->param = 0x8F; + break; + case 1: /* balance fine slide right */ + //TODO("test pan slide effect (P%dR%dC%d)", pat, row, chan); + note->effect = FX_PANNINGSLIDE; + note->param = 0xF8; + break; + default: + /* oops, nothing again */ + note->param = 0; + } + break; + case 7: /* H - slot retrig */ + //TODO("test slot retrig (P%dR%dC%d)", pat, row, chan); + note->effect = FX_RETRIG; + break; + } + } + } + if (rows < 64) { + /* skip the rest of the rows beyond the break position */ + slurp_seek(fp, 3 * 8 * (64 - rows), SEEK_CUR); + } + + /* handle the stupid pattern speed */ + note = song->patterns[pat]; + for (chan = 0; chan < 9; chan++, note++) { + if (note->effect == FX_SPEED) { + break; + } else if (!note->effect) { + note->effect = FX_SPEED; + note->param = patspeed[pat]; + break; + } + } + /* handle the break position */ + if (rows < 32) { + //printf("adding pattern break for pattern %d\n", pat); + note = song->patterns[pat] + MAX_CHANNELS * (rows - 1); + for (chan = 0; chan < 9; chan++, note++) { + if (!note->effect) { + note->effect = FX_PATTERNBREAK; + note->param = 0; + break; + } + } + } + } + csf_insert_restart_pos(song, restartpos); + + /* sample data */ + if (!(lflags & LOAD_NOSAMPLES)) { + for (smp = 1; smp <= nsmp; smp++) { + uint32_t ssize; + + if (song->samples[smp].length == 0) + continue; + + ssize = csf_read_sample(song->samples + smp, SF_LE | SF_M | SF_PCMU | SF_8, + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, ssize, SEEK_CUR); + } + } + + /* set the rest of the stuff */ + song->initial_speed = 4; + song->initial_tempo = 78; + song->flags = SONG_ITOLDEFFECTS | SONG_LINEARSLIDES; + + song->pan_separation = 64; + for (n = 0; n < 8; n++) + song->channels[n].panning = (n & 1) ? 256 : 0; //mphack + for (n = 8; n < 64; n++) + song->channels[n].flags = CHN_MUTE; // if (ferror(fp)) { // return LOAD_FILE_ERROR; // } - /* done! */ - return LOAD_SUCCESS; + /* done! */ + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/aiff.c schism-20160521/fmt/aiff.c --- schism-0+20110101/fmt/aiff.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/aiff.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,38 +43,38 @@ #pragma pack(push, 1) typedef union chunkdata { - struct { - uint32_t filetype; // AIFF, 8SVX, etc. - uint8_t data[0]; // rest of file is encapsulated in here, also chunked - } FORM; - - // 8SVX - struct { - uint32_t smp_highoct_1shot; - uint32_t smp_highoct_repeat; - uint32_t smp_cycle_highoct; - uint16_t smp_per_sec; - uint8_t num_octaves; - uint8_t compression; // 0 = none, 1 = fibonacci-delta - uint32_t volume; // fixed point, 65536 = 1.0 - } VHDR; - - // AIFF - struct { - uint16_t num_channels; - uint32_t num_frames; - uint16_t sample_size; - uint8_t sample_rate[80]; // IEEE-extended - } COMM; + struct { + uint32_t filetype; // AIFF, 8SVX, etc. + uint8_t data[0]; // rest of file is encapsulated in here, also chunked + } FORM; + + // 8SVX + struct { + uint32_t smp_highoct_1shot; + uint32_t smp_highoct_repeat; + uint32_t smp_cycle_highoct; + uint16_t smp_per_sec; + uint8_t num_octaves; + uint8_t compression; // 0 = none, 1 = fibonacci-delta + uint32_t volume; // fixed point, 65536 = 1.0 + } VHDR; + + // AIFF + struct { + uint16_t num_channels; + uint32_t num_frames; + uint16_t sample_size; + uint8_t sample_rate[80]; // IEEE-extended + } COMM; - uint8_t bytes[0]; + uint8_t bytes[0]; } chunkdata_t; #pragma pack(pop) typedef struct chunk { - uint32_t id; - uint32_t size; - const chunkdata_t *data; + uint32_t id; + uint32_t size; + const chunkdata_t *data; } chunk_t; // other chunks that might exist: "NAME", "AUTH", "ANNO", "(c) " @@ -85,15 +85,15 @@ // pos is updated to point to the beginning of the next chunk static int iff_chunk_read(chunk_t *chunk, const uint8_t *data, size_t length, size_t *pos) { - if (*pos + 8 > length) - return 0; - memcpy(&chunk->id, data + *pos, 4); - memcpy(&chunk->size, data + *pos + 4, 4); - chunk->id = bswapBE32(chunk->id); - chunk->size = bswapBE32(chunk->size); - chunk->data = (chunkdata_t *) (data + *pos + 8); - *pos += 8 + chunk->size; - return (*pos <= length); + if (*pos + 8 > length) + return 0; + memcpy(&chunk->id, data + *pos, 4); + memcpy(&chunk->size, data + *pos + 4, 4); + chunk->id = bswapBE32(chunk->id); + chunk->size = bswapBE32(chunk->size); + chunk->data = (chunkdata_t *) (data + *pos + 8); + *pos += 8 + chunk->size; + return (*pos <= length); } // Wish I could do this: @@ -119,380 +119,380 @@ static int _read_iff(dmoz_file_t *file, song_sample_t *smp, const uint8_t *data, size_t length) { - chunk_t chunk; - size_t pos = 0; - chunk_t vhdr, body, name, comm, auth, anno, ssnd; // butt - - if (!iff_chunk_read(&chunk, data, length, &pos)) - return 0; - if (chunk.id != ID_FORM) - return 0; - - // jump "into" the FORM chunk - // if (pos < length), there's more data after the FORM chunk -- but I don't care about this scenario - pos = 0; - length = MIN(length, chunk.size); - data = chunk.data->FORM.data; - - /* the header is already byteswapped, but anything in 'chunk' will need to be swapped as needed - because the structure is a const pointing into the data itself */ - switch (bswapBE32(chunk.data->FORM.filetype)) { - case ID_8SVX: - // shut up, gcc - ZEROIZE(vhdr); - ZEROIZE(body); - ZEROIZE(name); - ZEROIZE(auth); - ZEROIZE(anno); - - while (iff_chunk_read(&chunk, data, length, &pos)) { - switch (chunk.id) { - case ID_VHDR: vhdr = chunk; break; - case ID_BODY: body = chunk; break; - case ID_NAME: name = chunk; break; - case ID_AUTH: auth = chunk; break; - case ID_ANNO: anno = chunk; break; - default: break; - } - } - if (!(vhdr.id && body.id)) - return 0; - - if (vhdr.data->VHDR.compression) { - log_appendf(4, "error: compressed 8SVX files are unsupported"); - return 0; - } - if (vhdr.data->VHDR.num_octaves != 1) { - log_appendf(4, "warning: 8SVX file contains %d octaves", - vhdr.data->VHDR.num_octaves); - } - - if (file) { - file->description = "8SVX sample"; - file->type = TYPE_SAMPLE_PLAIN; - } - if (!name.id) name = auth; - if (!name.id) name = anno; - if (name.id) { - if (file) { - file->title = calloc(1, name.size + 1); - memcpy(file->title, name.data->bytes, name.size); - file->title[name.size] = '\0'; - } - if (smp) { - int len = MIN(25, name.size); - memcpy(smp->name, name.data->bytes, len); - smp->name[len] = 0; - } - } - - if (smp) { - smp->c5speed = bswapBE16(vhdr.data->VHDR.smp_per_sec); - smp->length = body.size; - - csf_read_sample(smp, SF_BE | SF_PCMS | SF_8 | SF_M, body.data->bytes, body.size); - - smp->volume = 64*4; - smp->global_volume = 64; - - // this is done kinda weird - smp->loop_end = bswapBE32(vhdr.data->VHDR.smp_highoct_repeat); - if (smp->loop_end) { - smp->loop_start = bswapBE32(vhdr.data->VHDR.smp_highoct_1shot); - smp->loop_end += smp->loop_start; - if (smp->loop_start > smp->length) - smp->loop_start = 0; - if (smp->loop_end > smp->length) - smp->loop_end = smp->length; - if (smp->loop_start + 2 < smp->loop_end) - smp->flags |= CHN_LOOP; - } - // TODO vhdr.data->VHDR.volume ? - } - - return 1; - - case ID_AIFF: - ZEROIZE(comm); - ZEROIZE(ssnd); - ZEROIZE(name); - ZEROIZE(auth); - ZEROIZE(anno); - - while (iff_chunk_read(&chunk, data, length, &pos)) { - switch (chunk.id) { - case ID_COMM: comm = chunk; break; - case ID_SSND: ssnd = chunk; break; - case ID_NAME: name = chunk; break; - default: break; - } - } - if (!(comm.id && ssnd.id)) - return 0; - - if (file) { - file->description = "Audio IFF sample"; - file->type = TYPE_SAMPLE_PLAIN; - } - if (!name.id) name = auth; - if (!name.id) name = anno; - if (name.id) { - if (file) { - file->title = calloc(1, name.size + 1); - memcpy(file->title, name.data->bytes, name.size); - file->title[name.size] = '\0'; - } - if (smp) { - int len = MIN(25, name.size); - memcpy(smp->name, name.data->bytes, len); - smp->name[len] = 0; - } - } - - /* TODO loop points */ - - if (smp) { - uint32_t flags = SF_BE | SF_PCMS; - - switch (bswapBE16(comm.data->COMM.num_channels)) { - default: - log_appendf(4, "warning: multichannel AIFF is unsupported"); - case 1: - flags |= SF_M; - break; - case 2: - flags |= SF_SI; - break; - } - - switch ((bswapBE16(comm.data->COMM.sample_size) + 7) & ~7) { - default: - log_appendf(4, "warning: AIFF has unsupported bit-width"); - case 8: - flags |= SF_8; - break; - case 16: - flags |= SF_16; - break; - } - - // TODO: data checking; make sure sample count and byte size agree - // (and if not, cut to shorter of the two) - - smp->c5speed = ConvertFromIeeeExtended(comm.data->COMM.sample_rate); - smp->length = bswapBE32(comm.data->COMM.num_frames); - smp->volume = 64*4; - smp->global_volume = 64; - - // the audio data starts 8 bytes into the chunk - // (don't care about the block alignment stuff) - csf_read_sample(smp, flags, ssnd.data->bytes + 8, ssnd.size - 8); - } + chunk_t chunk; + size_t pos = 0; + chunk_t vhdr, body, name, comm, auth, anno, ssnd; // butt + + if (!iff_chunk_read(&chunk, data, length, &pos)) + return 0; + if (chunk.id != ID_FORM) + return 0; + + // jump "into" the FORM chunk + // if (pos < length), there's more data after the FORM chunk -- but I don't care about this scenario + pos = 0; + length = MIN(length, chunk.size); + data = chunk.data->FORM.data; + + /* the header is already byteswapped, but anything in 'chunk' will need to be swapped as needed + because the structure is a const pointing into the data itself */ + switch (bswapBE32(chunk.data->FORM.filetype)) { + case ID_8SVX: + // shut up, gcc + ZEROIZE(vhdr); + ZEROIZE(body); + ZEROIZE(name); + ZEROIZE(auth); + ZEROIZE(anno); + + while (iff_chunk_read(&chunk, data, length, &pos)) { + switch (chunk.id) { + case ID_VHDR: vhdr = chunk; break; + case ID_BODY: body = chunk; break; + case ID_NAME: name = chunk; break; + case ID_AUTH: auth = chunk; break; + case ID_ANNO: anno = chunk; break; + default: break; + } + } + if (!(vhdr.id && body.id)) + return 0; + + if (vhdr.data->VHDR.compression) { + log_appendf(4, "error: compressed 8SVX files are unsupported"); + return 0; + } + if (vhdr.data->VHDR.num_octaves != 1) { + log_appendf(4, "warning: 8SVX file contains %d octaves", + vhdr.data->VHDR.num_octaves); + } + + if (file) { + file->description = "8SVX sample"; + file->type = TYPE_SAMPLE_PLAIN; + } + if (!name.id) name = auth; + if (!name.id) name = anno; + if (name.id) { + if (file) { + file->title = calloc(1, name.size + 1); + memcpy(file->title, name.data->bytes, name.size); + file->title[name.size] = '\0'; + } + if (smp) { + int len = MIN(25, name.size); + memcpy(smp->name, name.data->bytes, len); + smp->name[len] = 0; + } + } + + if (smp) { + smp->c5speed = bswapBE16(vhdr.data->VHDR.smp_per_sec); + smp->length = body.size; + + csf_read_sample(smp, SF_BE | SF_PCMS | SF_8 | SF_M, body.data->bytes, body.size); + + smp->volume = 64*4; + smp->global_volume = 64; + + // this is done kinda weird + smp->loop_end = bswapBE32(vhdr.data->VHDR.smp_highoct_repeat); + if (smp->loop_end) { + smp->loop_start = bswapBE32(vhdr.data->VHDR.smp_highoct_1shot); + smp->loop_end += smp->loop_start; + if (smp->loop_start > smp->length) + smp->loop_start = 0; + if (smp->loop_end > smp->length) + smp->loop_end = smp->length; + if (smp->loop_start + 2 < smp->loop_end) + smp->flags |= CHN_LOOP; + } + // TODO vhdr.data->VHDR.volume ? + } + + return 1; + + case ID_AIFF: + ZEROIZE(comm); + ZEROIZE(ssnd); + ZEROIZE(name); + ZEROIZE(auth); + ZEROIZE(anno); + + while (iff_chunk_read(&chunk, data, length, &pos)) { + switch (chunk.id) { + case ID_COMM: comm = chunk; break; + case ID_SSND: ssnd = chunk; break; + case ID_NAME: name = chunk; break; + default: break; + } + } + if (!(comm.id && ssnd.id)) + return 0; + + if (file) { + file->description = "Audio IFF sample"; + file->type = TYPE_SAMPLE_PLAIN; + } + if (!name.id) name = auth; + if (!name.id) name = anno; + if (name.id) { + if (file) { + file->title = calloc(1, name.size + 1); + memcpy(file->title, name.data->bytes, name.size); + file->title[name.size] = '\0'; + } + if (smp) { + int len = MIN(25, name.size); + memcpy(smp->name, name.data->bytes, len); + smp->name[len] = 0; + } + } + + /* TODO loop points */ + + if (smp) { + uint32_t flags = SF_BE | SF_PCMS; + + switch (bswapBE16(comm.data->COMM.num_channels)) { + default: + log_appendf(4, "warning: multichannel AIFF is unsupported"); + case 1: + flags |= SF_M; + break; + case 2: + flags |= SF_SI; + break; + } + + switch ((bswapBE16(comm.data->COMM.sample_size) + 7) & ~7) { + default: + log_appendf(4, "warning: AIFF has unsupported bit-width"); + case 8: + flags |= SF_8; + break; + case 16: + flags |= SF_16; + break; + } + + // TODO: data checking; make sure sample count and byte size agree + // (and if not, cut to shorter of the two) + + smp->c5speed = ConvertFromIeeeExtended(comm.data->COMM.sample_rate); + smp->length = bswapBE32(comm.data->COMM.num_frames); + smp->volume = 64*4; + smp->global_volume = 64; + + // the audio data starts 8 bytes into the chunk + // (don't care about the block alignment stuff) + csf_read_sample(smp, flags, ssnd.data->bytes + 8, ssnd.size - 8); + } - return 1; - } + return 1; + } - return 0; + return 0; } /* --------------------------------------------------------------------- */ int fmt_aiff_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - return _read_iff(file, NULL, data, length); + return _read_iff(file, NULL, data, length); } int fmt_aiff_load_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - return _read_iff(NULL, smp, data, length); + return _read_iff(NULL, smp, data, length); } /* --------------------------------------------------------------------- */ struct aiff_writedata { - long comm_frames, ssnd_size; // seek positions for writing header data - size_t numbytes; // how many bytes have been written - int bps; // bytes per sample - int swap; // should be byteswapped? + long comm_frames, ssnd_size; // seek positions for writing header data + size_t numbytes; // how many bytes have been written + int bps; // bytes per sample + int swap; // should be byteswapped? }; static int aiff_header(disko_t *fp, int bits, int channels, int rate, - const char *name, size_t length, struct aiff_writedata *awd /* out */) + const char *name, size_t length, struct aiff_writedata *awd /* out */) { - int16_t s; - uint32_t ul; - int tlen, bps = 1; - uint8_t b[10]; - - bps *= ((bits + 7) / 8); - /* note: channel multiply is done below -- need single-channel value for the COMM chunk */ - - /* write a very large size for now */ - disko_write(fp, "FORM\377\377\377\377AIFF", 12); - - if (name && *name) { - disko_write(fp, "NAME", 4); - tlen = strlen(name); - ul = (tlen + 1) & ~1; /* must be even */ - ul = bswapBE32(ul); - disko_write(fp, &ul, 4); - disko_write(fp, name, tlen); - if (tlen & 1) - disko_putc(fp, '\0'); - } - - /* Common Chunk - The Common Chunk describes fundamental parameters of the sampled sound. - typedef struct { - ID ckID; // 'COMM' - long ckSize; // 18 - short numChannels; - unsigned long numSampleFrames; - short sampleSize; - extended sampleRate; - } CommonChunk; */ - disko_write(fp, "COMM", 4); - ul = bswapBE32(18); /* chunk size -- won't change */ - disko_write(fp, &ul, 4); - s = bswapBE16(channels); - disko_write(fp, &s, 2); - if (awd) - awd->comm_frames = disko_tell(fp); - ul = bswapBE32(length); /* num sample frames */ - disko_write(fp, &ul, 4); - s = bswapBE16(bits); - disko_write(fp, &s, 2); - ConvertToIeeeExtended(rate, b); - disko_write(fp, b, 10); - - /* NOW do this (sample size in AIFF is indicated per channel, not per frame) */ - bps *= channels; /* == number of bytes per (stereo) sample */ - - /* Sound Data Chunk - The Sound Data Chunk contains the actual sample frames. - typedef struct { - ID ckID; // 'SSND' - long ckSize; // data size in bytes, *PLUS EIGHT* (for offset and blockSize) - unsigned long offset; // just set this to 0... - unsigned long blockSize; // likewise - unsigned char soundData[]; - } SoundDataChunk; */ - disko_write(fp, "SSND", 4); - if (awd) - awd->ssnd_size = disko_tell(fp); - ul = bswapBE32(length * bps + 8); - disko_write(fp, &ul, 4); - ul = bswapBE32(0); - disko_write(fp, &ul, 4); - disko_write(fp, &ul, 4); + int16_t s; + uint32_t ul; + int tlen, bps = 1; + uint8_t b[10]; + + bps *= ((bits + 7) / 8); + /* note: channel multiply is done below -- need single-channel value for the COMM chunk */ + + /* write a very large size for now */ + disko_write(fp, "FORM\377\377\377\377AIFF", 12); + + if (name && *name) { + disko_write(fp, "NAME", 4); + tlen = strlen(name); + ul = (tlen + 1) & ~1; /* must be even */ + ul = bswapBE32(ul); + disko_write(fp, &ul, 4); + disko_write(fp, name, tlen); + if (tlen & 1) + disko_putc(fp, '\0'); + } + + /* Common Chunk + The Common Chunk describes fundamental parameters of the sampled sound. + typedef struct { + ID ckID; // 'COMM' + long ckSize; // 18 + short numChannels; + unsigned long numSampleFrames; + short sampleSize; + extended sampleRate; + } CommonChunk; */ + disko_write(fp, "COMM", 4); + ul = bswapBE32(18); /* chunk size -- won't change */ + disko_write(fp, &ul, 4); + s = bswapBE16(channels); + disko_write(fp, &s, 2); + if (awd) + awd->comm_frames = disko_tell(fp); + ul = bswapBE32(length); /* num sample frames */ + disko_write(fp, &ul, 4); + s = bswapBE16(bits); + disko_write(fp, &s, 2); + ConvertToIeeeExtended(rate, b); + disko_write(fp, b, 10); + + /* NOW do this (sample size in AIFF is indicated per channel, not per frame) */ + bps *= channels; /* == number of bytes per (stereo) sample */ + + /* Sound Data Chunk + The Sound Data Chunk contains the actual sample frames. + typedef struct { + ID ckID; // 'SSND' + long ckSize; // data size in bytes, *PLUS EIGHT* (for offset and blockSize) + unsigned long offset; // just set this to 0... + unsigned long blockSize; // likewise + unsigned char soundData[]; + } SoundDataChunk; */ + disko_write(fp, "SSND", 4); + if (awd) + awd->ssnd_size = disko_tell(fp); + ul = bswapBE32(length * bps + 8); + disko_write(fp, &ul, 4); + ul = bswapBE32(0); + disko_write(fp, &ul, 4); + disko_write(fp, &ul, 4); - return bps; + return bps; } /* --------------------------------------------------------------------- */ int fmt_aiff_save_sample(disko_t *fp, song_sample_t *smp) { - int bps; - uint32_t ul; - uint32_t flags = SF_BE | SF_PCMS; - flags |= (smp->flags & CHN_16BIT) ? SF_16 : SF_8; - flags |= (smp->flags & CHN_STEREO) ? SF_SI : SF_M; - - bps = aiff_header(fp, (smp->flags & CHN_16BIT) ? 16 : 8, (smp->flags & CHN_STEREO) ? 2 : 1, - smp->c5speed, smp->name, smp->length, NULL); - - if (csf_write_sample(fp, smp, flags) != smp->length * bps) { - log_appendf(4, "AIFF: unexpected data size written"); - return SAVE_INTERNAL_ERROR; - } - - /* TODO: loop data */ - - /* fix the length in the file header */ - ul = disko_tell(fp) - 8; - ul = bswapBE32(ul); - disko_seek(fp, 4, SEEK_SET); - disko_write(fp, &ul, 4); + int bps; + uint32_t ul; + uint32_t flags = SF_BE | SF_PCMS; + flags |= (smp->flags & CHN_16BIT) ? SF_16 : SF_8; + flags |= (smp->flags & CHN_STEREO) ? SF_SI : SF_M; + + bps = aiff_header(fp, (smp->flags & CHN_16BIT) ? 16 : 8, (smp->flags & CHN_STEREO) ? 2 : 1, + smp->c5speed, smp->name, smp->length, NULL); + + if (csf_write_sample(fp, smp, flags) != smp->length * bps) { + log_appendf(4, "AIFF: unexpected data size written"); + return SAVE_INTERNAL_ERROR; + } + + /* TODO: loop data */ + + /* fix the length in the file header */ + ul = disko_tell(fp) - 8; + ul = bswapBE32(ul); + disko_seek(fp, 4, SEEK_SET); + disko_write(fp, &ul, 4); - return SAVE_SUCCESS; + return SAVE_SUCCESS; } int fmt_aiff_export_head(disko_t *fp, int bits, int channels, int rate) { - struct aiff_writedata *awd = malloc(sizeof(struct aiff_writedata)); - if (!awd) - return DW_ERROR; - fp->userdata = awd; - awd->bps = aiff_header(fp, bits, channels, rate, NULL, ~0, awd); - awd->numbytes = 0; + struct aiff_writedata *awd = malloc(sizeof(struct aiff_writedata)); + if (!awd) + return DW_ERROR; + fp->userdata = awd; + awd->bps = aiff_header(fp, bits, channels, rate, NULL, ~0, awd); + awd->numbytes = 0; #if WORDS_BIGENDIAN - awd->swap = 0; + awd->swap = 0; #else - awd->swap = (bits > 8); + awd->swap = (bits > 8); #endif - return DW_OK; + return DW_OK; } int fmt_aiff_export_body(disko_t *fp, const uint8_t *data, size_t length) { - struct aiff_writedata *awd = fp->userdata; + struct aiff_writedata *awd = fp->userdata; - if (length % awd->bps) { - log_appendf(4, "AIFF export: received uneven length"); - return DW_ERROR; - } - - awd->numbytes += length; - - if (awd->swap) { - const int16_t *ptr = (const int16_t *) data; - uint16_t v; - - length /= 2; - while (length--) { - v = *ptr; - v = bswapBE16(v); - disko_write(fp, &v, 2); - ptr++; - } - } else { - disko_write(fp, data, length); - } + if (length % awd->bps) { + log_appendf(4, "AIFF export: received uneven length"); + return DW_ERROR; + } + + awd->numbytes += length; + + if (awd->swap) { + const int16_t *ptr = (const int16_t *) data; + uint16_t v; + + length /= 2; + while (length--) { + v = *ptr; + v = bswapBE16(v); + disko_write(fp, &v, 2); + ptr++; + } + } else { + disko_write(fp, data, length); + } - return DW_OK; + return DW_OK; } int fmt_aiff_export_silence(disko_t *fp, long bytes) { - disko_seek(fp, bytes, SEEK_CUR); - return DW_OK; + disko_seek(fp, bytes, SEEK_CUR); + return DW_OK; } int fmt_aiff_export_tail(disko_t *fp) { - struct aiff_writedata *awd = fp->userdata; - uint32_t ul; + struct aiff_writedata *awd = fp->userdata; + uint32_t ul; - /* fix the length in the file header */ - ul = disko_tell(fp) - 8; - ul = bswapBE32(ul); - disko_seek(fp, 4, SEEK_SET); - disko_write(fp, &ul, 4); - - /* write the other lengths */ - disko_seek(fp, awd->comm_frames, SEEK_SET); - ul = bswapBE32(awd->numbytes / awd->bps); - disko_write(fp, &ul, 4); - disko_seek(fp, awd->ssnd_size, SEEK_SET); - ul = bswapBE32(awd->numbytes + 8); - disko_write(fp, &ul, 4); + /* fix the length in the file header */ + ul = disko_tell(fp) - 8; + ul = bswapBE32(ul); + disko_seek(fp, 4, SEEK_SET); + disko_write(fp, &ul, 4); + + /* write the other lengths */ + disko_seek(fp, awd->comm_frames, SEEK_SET); + ul = bswapBE32(awd->numbytes / awd->bps); + disko_write(fp, &ul, 4); + disko_seek(fp, awd->ssnd_size, SEEK_SET); + ul = bswapBE32(awd->numbytes + 8); + disko_write(fp, &ul, 4); - free(awd); + free(awd); - return DW_OK; + return DW_OK; } /* --------------------------------------------------------------------- */ @@ -536,87 +536,87 @@ static void ConvertToIeeeExtended(double num, unsigned char *bytes) { - int sign, expon; - double fMant, fsMant; - uint32_t hiMant, loMant; - - if (num < 0) { - sign = 0x8000; - num *= -1; - } else { - sign = 0; - } - - if (num == 0) { - expon = 0; - hiMant = 0; - loMant = 0; - } else { - fMant = frexp(num, &expon); - if ((expon > 16384) || !(fMant < 1)) { - /* Infinity or NaN */ - expon = sign | 0x7FFF; - hiMant = 0; - loMant = 0; /* infinity */ - } else { - /* Finite */ - expon += 16382; - if (expon < 0) { - /* denormalized */ - fMant = ldexp(fMant, expon); - expon = 0; - } - expon |= sign; - fMant = ldexp(fMant, 32); - fsMant = floor(fMant); - hiMant = FloatToUnsigned(fsMant); - fMant = ldexp(fMant - fsMant, 32); - fsMant = floor(fMant); - loMant = FloatToUnsigned(fsMant); - } - } - - bytes[0] = expon >> 8; - bytes[1] = expon; - bytes[2] = hiMant >> 24; - bytes[3] = hiMant >> 16; - bytes[4] = hiMant >> 8; - bytes[5] = hiMant; - bytes[6] = loMant >> 24; - bytes[7] = loMant >> 16; - bytes[8] = loMant >> 8; - bytes[9] = loMant; + int sign, expon; + double fMant, fsMant; + uint32_t hiMant, loMant; + + if (num < 0) { + sign = 0x8000; + num *= -1; + } else { + sign = 0; + } + + if (num == 0) { + expon = 0; + hiMant = 0; + loMant = 0; + } else { + fMant = frexp(num, &expon); + if ((expon > 16384) || !(fMant < 1)) { + /* Infinity or NaN */ + expon = sign | 0x7FFF; + hiMant = 0; + loMant = 0; /* infinity */ + } else { + /* Finite */ + expon += 16382; + if (expon < 0) { + /* denormalized */ + fMant = ldexp(fMant, expon); + expon = 0; + } + expon |= sign; + fMant = ldexp(fMant, 32); + fsMant = floor(fMant); + hiMant = FloatToUnsigned(fsMant); + fMant = ldexp(fMant - fsMant, 32); + fsMant = floor(fMant); + loMant = FloatToUnsigned(fsMant); + } + } + + bytes[0] = expon >> 8; + bytes[1] = expon; + bytes[2] = hiMant >> 24; + bytes[3] = hiMant >> 16; + bytes[4] = hiMant >> 8; + bytes[5] = hiMant; + bytes[6] = loMant >> 24; + bytes[7] = loMant >> 16; + bytes[8] = loMant >> 8; + bytes[9] = loMant; } static double ConvertFromIeeeExtended(const unsigned char *bytes) { - double f; - int expon; - uint32_t hiMant, loMant; - - expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); - hiMant = ((uint32_t) (bytes[2] & 0xFF) << 24) - | ((uint32_t) (bytes[3] & 0xFF) << 16) - | ((uint32_t) (bytes[4] & 0xFF) << 8) - | ((uint32_t) (bytes[5] & 0xFF)); - loMant = ((uint32_t) (bytes[6] & 0xFF) << 24) - | ((uint32_t) (bytes[7] & 0xFF) << 16) - | ((uint32_t) (bytes[8] & 0xFF) << 8) - | ((uint32_t) (bytes[9] & 0xFF)); - - if (expon == 0 && hiMant == 0 && loMant == 0) { - f = 0; - } else if (expon == 0x7FFF) { - /* Infinity or NaN */ - f = HUGE_VAL; - } else { - expon -= 16383; - f = ldexp(UnsignedToFloat(hiMant), expon -= 31); - f += ldexp(UnsignedToFloat(loMant), expon -= 32); - } - - if (bytes[0] & 0x80) - return -f; - else - return f; + double f; + int expon; + uint32_t hiMant, loMant; + + expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); + hiMant = ((uint32_t) (bytes[2] & 0xFF) << 24) + | ((uint32_t) (bytes[3] & 0xFF) << 16) + | ((uint32_t) (bytes[4] & 0xFF) << 8) + | ((uint32_t) (bytes[5] & 0xFF)); + loMant = ((uint32_t) (bytes[6] & 0xFF) << 24) + | ((uint32_t) (bytes[7] & 0xFF) << 16) + | ((uint32_t) (bytes[8] & 0xFF) << 8) + | ((uint32_t) (bytes[9] & 0xFF)); + + if (expon == 0 && hiMant == 0 && loMant == 0) { + f = 0; + } else if (expon == 0x7FFF) { + /* Infinity or NaN */ + f = HUGE_VAL; + } else { + expon -= 16383; + f = ldexp(UnsignedToFloat(hiMant), expon -= 31); + f += ldexp(UnsignedToFloat(loMant), expon -= 32); + } + + if (bytes[0] & 0x80) + return -f; + else + return f; } diff -Nru schism-0+20110101/fmt/ams.c schism-20160521/fmt/ams.c --- schism-0+20110101/fmt/ams.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/ams.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,19 +34,19 @@ int fmt_ams_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - uint8_t n; + uint8_t n; - if (!(length > 38 && memcmp(data, "AMShdr\x1a", 7) == 0)) - return 0; + if (!(length > 38 && memcmp(data, "AMShdr\x1a", 7) == 0)) + return 0; - n = data[7]; - if (n > 30) - n = 30; - file->description = "Velvet Studio"; - /*file->extension = str_dup("ams");*/ - file->title = calloc(n + 1, sizeof(char)); - memcpy(file->title, data + 8, n); - file->title[n] = 0; - file->type = TYPE_MODULE_XM; - return 1; + n = data[7]; + if (n > 30) + n = 30; + file->description = "Velvet Studio"; + /*file->extension = str_dup("ams");*/ + file->title = calloc(n + 1, sizeof(char)); + memcpy(file->title, data + 8, n); + file->title[n] = 0; + file->type = TYPE_MODULE_XM; + return 1; } diff -Nru schism-0+20110101/fmt/au.c schism-20160521/fmt/au.c --- schism-0+20110101/fmt/au.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/au.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -27,19 +27,19 @@ enum { - AU_ULAW = 1, /* µ-law */ - AU_PCM_8 = 2, /* 8-bit linear PCM (RS_PCM8U in Modplug) */ - AU_PCM_16 = 3, /* 16-bit linear PCM (RS_PCM16M) */ - AU_PCM_24 = 4, /* 24-bit linear PCM */ - AU_PCM_32 = 5, /* 32-bit linear PCM */ - AU_IEEE_32 = 6, /* 32-bit IEEE floating point */ - AU_IEEE_64 = 7, /* 64-bit IEEE floating point */ - AU_ISDN_ULAW_ADPCM = 23, /* 8-bit ISDN µ-law (CCITT G.721 ADPCM compressed) */ + AU_ULAW = 1, /* µ-law */ + AU_PCM_8 = 2, /* 8-bit linear PCM (RS_PCM8U in Modplug) */ + AU_PCM_16 = 3, /* 16-bit linear PCM (RS_PCM16M) */ + AU_PCM_24 = 4, /* 24-bit linear PCM */ + AU_PCM_32 = 5, /* 32-bit linear PCM */ + AU_IEEE_32 = 6, /* 32-bit IEEE floating point */ + AU_IEEE_64 = 7, /* 64-bit IEEE floating point */ + AU_ISDN_ULAW_ADPCM = 23, /* 8-bit ISDN µ-law (CCITT G.721 ADPCM compressed) */ }; struct au_header { - char magic[4]; /* ".snd" */ - uint32_t data_offset, data_size, encoding, sample_rate, channels; + char magic[4]; /* ".snd" */ + uint32_t data_offset, data_size, encoding, sample_rate, channels; }; @@ -47,136 +47,136 @@ int fmt_au_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - struct au_header au; + struct au_header au; - if (!(length > 24 && memcmp(data, ".snd", 4) == 0)) - return 0; + if (!(length > 24 && memcmp(data, ".snd", 4) == 0)) + return 0; - memcpy(&au, data, 24); - au.data_offset = bswapBE32(au.data_offset); - au.data_size = bswapBE32(au.data_size); - au.encoding = bswapBE32(au.encoding); - au.sample_rate = bswapBE32(au.sample_rate); - au.channels = bswapBE32(au.channels); - - if (!(au.data_offset < length && au.data_size > 0 && au.data_size <= length - au.data_offset)) - return 0; - - file->smp_length = au.data_size / au.channels; - file->smp_flags = 0; - if (au.encoding == AU_PCM_16) { - file->smp_flags |= CHN_16BIT; - file->smp_length /= 2; - } else if (au.encoding == AU_PCM_24) { - file->smp_length /= 3; - } else if (au.encoding == AU_PCM_32 || au.encoding == AU_IEEE_32) { - file->smp_length /= 4; - } else if (au.encoding == AU_IEEE_64) { - file->smp_length /= 8; - } - if (au.channels >= 2) { - file->smp_flags |= CHN_STEREO; - } - file->description = "AU Sample"; - if (au.data_offset > 24) { - int extlen = au.data_offset - 24; - - file->title = calloc(extlen + 1, sizeof(char)); - memcpy(file->title, data + 24, extlen); - file->title[extlen] = 0; - } - file->smp_filename = file->title; - file->type = TYPE_SAMPLE_PLAIN; - return 1; + memcpy(&au, data, 24); + au.data_offset = bswapBE32(au.data_offset); + au.data_size = bswapBE32(au.data_size); + au.encoding = bswapBE32(au.encoding); + au.sample_rate = bswapBE32(au.sample_rate); + au.channels = bswapBE32(au.channels); + + if (!(au.data_offset < length && au.data_size > 0 && au.data_size <= length - au.data_offset)) + return 0; + + file->smp_length = au.data_size / au.channels; + file->smp_flags = 0; + if (au.encoding == AU_PCM_16) { + file->smp_flags |= CHN_16BIT; + file->smp_length /= 2; + } else if (au.encoding == AU_PCM_24) { + file->smp_length /= 3; + } else if (au.encoding == AU_PCM_32 || au.encoding == AU_IEEE_32) { + file->smp_length /= 4; + } else if (au.encoding == AU_IEEE_64) { + file->smp_length /= 8; + } + if (au.channels >= 2) { + file->smp_flags |= CHN_STEREO; + } + file->description = "AU Sample"; + if (au.data_offset > 24) { + int extlen = au.data_offset - 24; + + file->title = calloc(extlen + 1, sizeof(char)); + memcpy(file->title, data + 24, extlen); + file->title[extlen] = 0; + } + file->smp_filename = file->title; + file->type = TYPE_SAMPLE_PLAIN; + return 1; } /* --------------------------------------------------------------------- */ int fmt_au_load_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - struct au_header au; - uint32_t sflags = SF_BE | SF_PCMS; + struct au_header au; + uint32_t sflags = SF_BE | SF_PCMS; - if (length < 24) - return 0; + if (length < 24) + return 0; - memcpy(&au, data, sizeof(au)); - /* optimization: could #ifdef this out on big-endian machines */ - au.data_offset = bswapBE32(au.data_offset); - au.data_size = bswapBE32(au.data_size); - au.encoding = bswapBE32(au.encoding); - au.sample_rate = bswapBE32(au.sample_rate); - au.channels = bswapBE32(au.channels); + memcpy(&au, data, sizeof(au)); + /* optimization: could #ifdef this out on big-endian machines */ + au.data_offset = bswapBE32(au.data_offset); + au.data_size = bswapBE32(au.data_size); + au.encoding = bswapBE32(au.encoding); + au.sample_rate = bswapBE32(au.sample_rate); + au.channels = bswapBE32(au.channels); /*#define C__(cond) if (!(cond)) { log_appendf(2, "failed condition: %s", #cond); return 0; }*/ #define C__(cond) if (!(cond)) { return 0; } - C__(memcmp(au.magic, ".snd", 4) == 0); - C__(au.data_offset >= 24); - C__(au.data_offset < length); - C__(au.data_size > 0); - C__(au.data_size <= length - au.data_offset); - C__(au.encoding == AU_PCM_8 || au.encoding == AU_PCM_16); - C__(au.channels == 1 || au.channels == 2); - - smp->c5speed = au.sample_rate; - smp->volume = 64 * 4; - smp->global_volume = 64; - smp->length = au.data_size; - if (au.encoding == AU_PCM_16) { - sflags |= SF_16; - smp->length /= 2; - } else { - sflags |= SF_8; - } - if (au.channels == 2) { - sflags |= SF_SI; - smp->length /= 2; - } else { - sflags |= SF_M; - } - - if (au.data_offset > 24) { - int extlen = MIN(25, au.data_offset - 24); - memcpy(smp->name, data + 24, extlen); - smp->name[extlen] = 0; - } + C__(memcmp(au.magic, ".snd", 4) == 0); + C__(au.data_offset >= 24); + C__(au.data_offset < length); + C__(au.data_size > 0); + C__(au.data_size <= length - au.data_offset); + C__(au.encoding == AU_PCM_8 || au.encoding == AU_PCM_16); + C__(au.channels == 1 || au.channels == 2); + + smp->c5speed = au.sample_rate; + smp->volume = 64 * 4; + smp->global_volume = 64; + smp->length = au.data_size; + if (au.encoding == AU_PCM_16) { + sflags |= SF_16; + smp->length /= 2; + } else { + sflags |= SF_8; + } + if (au.channels == 2) { + sflags |= SF_SI; + smp->length /= 2; + } else { + sflags |= SF_M; + } + + if (au.data_offset > 24) { + int extlen = MIN(25, au.data_offset - 24); + memcpy(smp->name, data + 24, extlen); + smp->name[extlen] = 0; + } - csf_read_sample(smp, sflags, data + au.data_offset, length - au.data_offset); + csf_read_sample(smp, sflags, data + au.data_offset, length - au.data_offset); - return 1; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ int fmt_au_save_sample(disko_t *fp, song_sample_t *smp) { - struct au_header au; - uint32_t ln; + struct au_header au; + uint32_t ln; - memcpy(au.magic, ".snd", 4); + memcpy(au.magic, ".snd", 4); - au.data_offset = bswapBE32(49); // header is 24 bytes, sample name is 25 - ln = smp->length; - if (smp->flags & CHN_16BIT) { - ln *= 2; - au.encoding = bswapBE32(AU_PCM_16); - } else { - au.encoding = bswapBE32(AU_PCM_8); - } - au.sample_rate = bswapBE32(smp->c5speed); - if (smp->flags & CHN_STEREO) { - ln *= 2; - au.channels = bswapBE32(2); - } else { - au.channels = bswapBE32(1); - } - au.data_size = bswapBE32(ln); - - disko_write(fp, &au, sizeof(au)); - disko_write(fp, smp->name, 25); - csf_write_sample(fp, smp, SF_BE | SF_PCMS - | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) - | ((smp->flags & CHN_STEREO) ? SF_SI : SF_M)); + au.data_offset = bswapBE32(49); // header is 24 bytes, sample name is 25 + ln = smp->length; + if (smp->flags & CHN_16BIT) { + ln *= 2; + au.encoding = bswapBE32(AU_PCM_16); + } else { + au.encoding = bswapBE32(AU_PCM_8); + } + au.sample_rate = bswapBE32(smp->c5speed); + if (smp->flags & CHN_STEREO) { + ln *= 2; + au.channels = bswapBE32(2); + } else { + au.channels = bswapBE32(1); + } + au.data_size = bswapBE32(ln); + + disko_write(fp, &au, sizeof(au)); + disko_write(fp, smp->name, 25); + csf_write_sample(fp, smp, SF_BE | SF_PCMS + | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) + | ((smp->flags & CHN_STEREO) ? SF_SI : SF_M)); - return SAVE_SUCCESS; + return SAVE_SUCCESS; } diff -Nru schism-0+20110101/fmt/compression.c schism-20160521/fmt/compression.c --- schism-0+20110101/fmt/compression.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/compression.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -31,208 +31,212 @@ static uint32_t it_readbits(int8_t n, uint32_t *bitbuf, uint32_t *bitnum, const uint8_t **ibuf) { - uint32_t value = 0; - uint32_t i = n; + uint32_t value = 0; + uint32_t i = n; - // this could be better - while (i--) { - if (!*bitnum) { - *bitbuf = *(*ibuf)++; - *bitnum = 8; - } - value >>= 1; - value |= (*bitbuf) << 31; - (*bitbuf) >>= 1; - (*bitnum)--; - } - return value >> (32 - n); + // this could be better + while (i--) { + if (!*bitnum) { + *bitbuf = *(*ibuf)++; + *bitnum = 8; + } + value >>= 1; + value |= (*bitbuf) << 31; + (*bitbuf) >>= 1; + (*bitnum)--; + } + return value >> (32 - n); } -void it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215) +uint32_t it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels) { - const uint8_t *filebuf; // source buffer containing compressed sample data - const uint8_t *srcbuf; // current position in source buffer - int8_t *destpos; // position in destination buffer which will be returned - uint16_t blklen; // length of compressed data block in samples - uint16_t blkpos; // position in block - uint8_t width; // actual "bit width" - uint16_t value; // value read from file to be processed - int8_t d1, d2; // integrator buffers (d2 for it2.15) - int8_t v; // sample value - uint32_t bitbuf, bitnum; // state for it_readbits - - filebuf = srcbuf = (const uint8_t *) file; - destpos = (int8_t *) dest; - - // now unpack data till the dest buffer is full - while (len) { - // read a new block of compressed data and reset variables - // block layout: word size, bytes data - if (srcbuf + 2 > filebuf + filelen - || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { - // truncated! - return; - } - srcbuf += 2; - bitbuf = bitnum = 0; - - blklen = MIN(0x8000, len); - blkpos = 0; - - width = 9; // start with width of 9 bits - d1 = d2 = 0; // reset integrator buffers - - // now uncompress the data block - while (blkpos < blklen) { - if (width > 9) { - // illegal width, abort - printf("Illegal bit width %d for 8-bit sample\n", width); - return; - } - value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); - - if (width < 7) { - // method 1 (1-6 bits) - // check for "100..." - if (value == 1 << (width - 1)) { - // yes! - value = it_readbits(3, &bitbuf, &bitnum, &srcbuf) + 1; // read new width - width = (value < width) ? value : value + 1; // and expand it - continue; // ... next value - } - } else if (width < 9) { - // method 2 (7-8 bits) - uint8_t border = (0xFF >> (9 - width)) - 4; // lower border for width chg - if (value > border && value <= (border + 8)) { - value -= border; // convert width to 1-8 - width = (value < width) ? value : value + 1; // and expand it - continue; // ... next value - } - } else { - // method 3 (9 bits) - // bit 8 set? - if (value & 0x100) { - width = (value + 1) & 0xff; // new width... - continue; // ... and next value - } - } - - // now expand value to signed byte - if (width < 8) { - uint8_t shift = 8 - width; - v = (value << shift); - v >>= shift; - } else { - v = (int8_t) value; - } - - // integrate upon the sample values - d1 += v; - d2 += d1; - - // .. and store it into the buffer - *(destpos++) = it215 ? d2 : d1; - blkpos++; - } - - // now subtract block length from total length and go on - len -= blklen; - } + const uint8_t *filebuf; // source buffer containing compressed sample data + const uint8_t *srcbuf; // current position in source buffer + int8_t *destpos; // position in destination buffer which will be returned + uint16_t blklen; // length of compressed data block in samples + uint16_t blkpos; // position in block + uint8_t width; // actual "bit width" + uint16_t value; // value read from file to be processed + int8_t d1, d2; // integrator buffers (d2 for it2.15) + int8_t v; // sample value + uint32_t bitbuf, bitnum; // state for it_readbits + + filebuf = srcbuf = (const uint8_t *) file; + destpos = (int8_t *) dest; + + // now unpack data till the dest buffer is full + while (len) { + // read a new block of compressed data and reset variables + // block layout: word size, bytes data + if (srcbuf + 2 > filebuf + filelen + || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { + // truncated! + return srcbuf - filebuf; + } + srcbuf += 2; + bitbuf = bitnum = 0; + + blklen = MIN(0x8000, len); + blkpos = 0; + + width = 9; // start with width of 9 bits + d1 = d2 = 0; // reset integrator buffers + + // now uncompress the data block + while (blkpos < blklen) { + if (width > 9) { + // illegal width, abort + printf("Illegal bit width %d for 8-bit sample\n", width); + return srcbuf - filebuf; + } + value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); + + if (width < 7) { + // method 1 (1-6 bits) + // check for "100..." + if (value == 1 << (width - 1)) { + // yes! + value = it_readbits(3, &bitbuf, &bitnum, &srcbuf) + 1; // read new width + width = (value < width) ? value : value + 1; // and expand it + continue; // ... next value + } + } else if (width < 9) { + // method 2 (7-8 bits) + uint8_t border = (0xFF >> (9 - width)) - 4; // lower border for width chg + if (value > border && value <= (border + 8)) { + value -= border; // convert width to 1-8 + width = (value < width) ? value : value + 1; // and expand it + continue; // ... next value + } + } else { + // method 3 (9 bits) + // bit 8 set? + if (value & 0x100) { + width = (value + 1) & 0xff; // new width... + continue; // ... and next value + } + } + + // now expand value to signed byte + if (width < 8) { + uint8_t shift = 8 - width; + v = (value << shift); + v >>= shift; + } else { + v = (int8_t) value; + } + + // integrate upon the sample values + d1 += v; + d2 += d1; + + // .. and store it into the buffer + *destpos = it215 ? d2 : d1; + destpos += channels; + blkpos++; + } + + // now subtract block length from total length and go on + len -= blklen; + } + return srcbuf - filebuf; } // Mostly the same as above. -void it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215) +uint32_t it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels) { - const uint8_t *filebuf; // source buffer containing compressed sample data - const uint8_t *srcbuf; // current position in source buffer - int16_t *destpos; // position in destination buffer which will be returned - uint16_t blklen; // length of compressed data block in samples - uint16_t blkpos; // position in block - uint8_t width; // actual "bit width" - uint32_t value; // value read from file to be processed - int16_t d1, d2; // integrator buffers (d2 for it2.15) - int16_t v; // sample value - uint32_t bitbuf, bitnum; // state for it_readbits - - filebuf = srcbuf = (const uint8_t *) file; - destpos = (int16_t *) dest; - - // now unpack data till the dest buffer is full - while (len) { - // read a new block of compressed data and reset variables - // block layout: word size, bytes data - if (srcbuf + 2 > filebuf + filelen - || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { - // truncated! - return; - } - srcbuf += 2; - - bitbuf = bitnum = 0; - - blklen = MIN(0x4000, len); // 0x4000 samples => 0x8000 bytes again - blkpos = 0; - - width = 17; // start with width of 17 bits - d1 = d2 = 0; // reset integrator buffers - - // now uncompress the data block - while (blkpos < blklen) { - if (width > 17) { - // illegal width, abort - printf("Illegal bit width %d for 16-bit sample\n", width); - return; - } - value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); - - if (width < 7) { - // method 1 (1-6 bits) - // check for "100..." - if (value == (uint32_t) 1 << (width - 1)) { - // yes! - value = it_readbits(4, &bitbuf, &bitnum, &srcbuf) + 1; // read new width - width = (value < width) ? value : value + 1; // and expand it - continue; // ... next value - } - } else if (width < 17) { - // method 2 (7-16 bits) - uint16_t border = (0xFFFF >> (17 - width)) - 8; // lower border for width chg - if (value > border && value <= (uint32_t) (border + 16)) { - value -= border; // convert width to 1-8 - width = (value < width) ? value : value + 1; // and expand it - continue; // ... next value - } - } else { - // method 3 (17 bits) - // bit 16 set? - if (value & 0x10000) { - width = (value + 1) & 0xff; // new width... - continue; // ... and next value - } - } - - // now expand value to signed word - if (width < 16) { - uint8_t shift = 16 - width; - v = (value << shift); - v >>= shift; - } else { - v = (int16_t) value; - } - - // integrate upon the sample values - d1 += v; - d2 += d1; - - // .. and store it into the buffer - *(destpos++) = it215 ? d2 : d1; - blkpos++; - } - - // now subtract block length from total length and go on - len -= blklen; - } + const uint8_t *filebuf; // source buffer containing compressed sample data + const uint8_t *srcbuf; // current position in source buffer + int16_t *destpos; // position in destination buffer which will be returned + uint16_t blklen; // length of compressed data block in samples + uint16_t blkpos; // position in block + uint8_t width; // actual "bit width" + uint32_t value; // value read from file to be processed + int16_t d1, d2; // integrator buffers (d2 for it2.15) + int16_t v; // sample value + uint32_t bitbuf, bitnum; // state for it_readbits + + filebuf = srcbuf = (const uint8_t *) file; + destpos = (int16_t *) dest; + + // now unpack data till the dest buffer is full + while (len) { + // read a new block of compressed data and reset variables + // block layout: word size, bytes data + if (srcbuf + 2 > filebuf + filelen + || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { + // truncated! + return srcbuf - filebuf; + } + srcbuf += 2; + + bitbuf = bitnum = 0; + + blklen = MIN(0x4000, len); // 0x4000 samples => 0x8000 bytes again + blkpos = 0; + + width = 17; // start with width of 17 bits + d1 = d2 = 0; // reset integrator buffers + + // now uncompress the data block + while (blkpos < blklen) { + if (width > 17) { + // illegal width, abort + printf("Illegal bit width %d for 16-bit sample\n", width); + return srcbuf - filebuf; + } + value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); + + if (width < 7) { + // method 1 (1-6 bits) + // check for "100..." + if (value == (uint32_t) 1 << (width - 1)) { + // yes! + value = it_readbits(4, &bitbuf, &bitnum, &srcbuf) + 1; // read new width + width = (value < width) ? value : value + 1; // and expand it + continue; // ... next value + } + } else if (width < 17) { + // method 2 (7-16 bits) + uint16_t border = (0xFFFF >> (17 - width)) - 8; // lower border for width chg + if (value > border && value <= (uint32_t) (border + 16)) { + value -= border; // convert width to 1-8 + width = (value < width) ? value : value + 1; // and expand it + continue; // ... next value + } + } else { + // method 3 (17 bits) + // bit 16 set? + if (value & 0x10000) { + width = (value + 1) & 0xff; // new width... + continue; // ... and next value + } + } + + // now expand value to signed word + if (width < 16) { + uint8_t shift = 16 - width; + v = (value << shift); + v >>= shift; + } else { + v = (int16_t) value; + } + + // integrate upon the sample values + d1 += v; + d2 += d1; + + // .. and store it into the buffer + *destpos = it215 ? d2 : d1; + destpos += channels; + blkpos++; + } + + // now subtract block length from total length and go on + len -= blklen; + } + return srcbuf - filebuf; } // ------------------------------------------------------------------------------------------------------------ @@ -240,13 +244,13 @@ uint16_t mdl_read_bits(uint32_t *bitbuf, uint32_t *bitnum, uint8_t **ibuf, int8_t n) { - uint16_t v = (uint16_t)((*bitbuf) & ((1 << n) - 1) ); - (*bitbuf) >>= n; - (*bitnum) -= n; - if ((*bitnum) <= 24) { - (*bitbuf) |= (((uint32_t)(*(*ibuf)++)) << (*bitnum)); - (*bitnum) += 8; - } - return v; + uint16_t v = (uint16_t)((*bitbuf) & ((1 << n) - 1) ); + (*bitbuf) >>= n; + (*bitnum) -= n; + if ((*bitnum) <= 24) { + (*bitbuf) |= (((uint32_t)(*(*ibuf)++)) << (*bitnum)); + (*bitnum) += 8; + } + return v; } diff -Nru schism-0+20110101/fmt/f2r.c schism-20160521/fmt/f2r.c --- schism-0+20110101/fmt/f2r.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/f2r.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,14 +30,14 @@ int fmt_f2r_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 46 && memcmp(data, "F2R", 3) == 0)) - return 0; + if (!(length > 46 && memcmp(data, "F2R", 3) == 0)) + return 0; - file->description = "Farandole 2 (linear)"; - /*file->extension = str_dup("f2r");*/ - file->title = calloc(41, sizeof(char)); - memcpy(file->title, data + 6, 40); - file->title[40] = 0; - file->type = TYPE_MODULE_S3M; - return 1; + file->description = "Farandole 2 (linear)"; + /*file->extension = str_dup("f2r");*/ + file->title = calloc(41, sizeof(char)); + memcpy(file->title, data + 6, 40); + file->title[40] = 0; + file->type = TYPE_MODULE_S3M; + return 1; } diff -Nru schism-0+20110101/fmt/far.c schism-20160521/fmt/far.c --- schism-0+20110101/fmt/far.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/far.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,18 +32,18 @@ int fmt_far_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - /* The magic for this format is truly weird (which I suppose is good, as the chance of it - being "accidentally" correct is pretty low) */ - if (!(length > 47 && memcmp(data + 44, "\x0d\x0a\x1a", 3) == 0 && memcmp(data, "FAR\xfe", 4) == 0)) - return 0; - - file->description = "Farandole Module"; - /*file->extension = str_dup("far");*/ - file->title = calloc(41, sizeof(char)); - memcpy(file->title, data + 4, 40); - file->title[40] = 0; - file->type = TYPE_MODULE_S3M; - return 1; + /* The magic for this format is truly weird (which I suppose is good, as the chance of it + being "accidentally" correct is pretty low) */ + if (!(length > 47 && memcmp(data + 44, "\x0d\x0a\x1a", 3) == 0 && memcmp(data, "FAR\xfe", 4) == 0)) + return 0; + + file->description = "Farandole Module"; + /*file->extension = str_dup("far");*/ + file->title = calloc(41, sizeof(char)); + memcpy(file->title, data + 4, 40); + file->title[40] = 0; + file->type = TYPE_MODULE_S3M; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -52,202 +52,202 @@ #pragma pack(push, 1) struct far_header { - uint8_t magic[4]; - char title[40]; - uint8_t eof[3]; - uint16_t header_len; - uint8_t version; - uint8_t onoff[16]; - uint8_t editing_state[9]; // stuff we don't care about - uint8_t default_speed; - uint8_t chn_panning[16]; - uint8_t pattern_state[4]; // more stuff we don't care about - uint16_t message_len; + uint8_t magic[4]; + char title[40]; + uint8_t eof[3]; + uint16_t header_len; + uint8_t version; + uint8_t onoff[16]; + uint8_t editing_state[9]; // stuff we don't care about + uint8_t default_speed; + uint8_t chn_panning[16]; + uint8_t pattern_state[4]; // more stuff we don't care about + uint16_t message_len; }; struct far_sample { - char name[32]; - uint32_t length; - uint8_t finetune; - uint8_t volume; - uint32_t loopstart; - uint32_t loopend; - uint8_t type; - uint8_t loop; + char name[32]; + uint32_t length; + uint8_t finetune; + uint8_t volume; + uint32_t loopstart; + uint32_t loopend; + uint8_t type; + uint8_t loop; }; #pragma pack(pop) static uint8_t far_effects[] = { - FX_NONE, - FX_PORTAMENTOUP, - FX_PORTAMENTODOWN, - FX_TONEPORTAMENTO, - FX_RETRIG, - FX_VIBRATO, // depth - FX_VIBRATO, // speed - FX_VOLUMESLIDE, // up - FX_VOLUMESLIDE, // down - FX_VIBRATO, // sustained (?) - FX_NONE, // actually slide-to-volume - FX_PANNING, - FX_SPECIAL, // note offset => note delay? - FX_NONE, // fine tempo down - FX_NONE, // fine tempo up - FX_SPEED, + FX_NONE, + FX_PORTAMENTOUP, + FX_PORTAMENTODOWN, + FX_TONEPORTAMENTO, + FX_RETRIG, + FX_VIBRATO, // depth + FX_VIBRATO, // speed + FX_VOLUMESLIDE, // up + FX_VOLUMESLIDE, // down + FX_VIBRATO, // sustained (?) + FX_NONE, // actually slide-to-volume + FX_PANNING, + FX_SPECIAL, // note offset => note delay? + FX_NONE, // fine tempo down + FX_NONE, // fine tempo up + FX_SPEED, }; static void far_import_note(song_note_t *note, const uint8_t data[4]) { - if (data[0] > 0 && data[0] < 85) { - note->note = data[0] + 36; - note->instrument = data[1] + 1; - } - if (data[2] & 0x0F) { - note->voleffect = VOLFX_VOLUME; - note->volparam = (data[2] & 0x0F) << 2; // askjdfjasdkfjasdf - } - note->param = data[3] & 0xf; - switch (data[3] >> 4) { - case 3: // porta to note - note->param <<= 2; - break; - case 4: // retrig - note->param = 6 / (1 + (note->param & 0xf)) + 1; // ugh? - break; - case 6: // vibrato speed - case 7: // volume slide up - case 0xb: // panning - note->param <<= 4; - break; - case 0xa: // volume-portamento (what!) - note->voleffect = VOLFX_VOLUME; - note->volparam = (note->param << 2) + 4; - break; - case 0xc: // note offset - note->param = 6 / (1 + (note->param & 0xf)) + 1; - note->param |= 0xd; - } - note->effect = far_effects[data[3] >> 4]; + if (data[0] > 0 && data[0] < 85) { + note->note = data[0] + 36; + note->instrument = data[1] + 1; + } + if (data[2] & 0x0F) { + note->voleffect = VOLFX_VOLUME; + note->volparam = (data[2] & 0x0F) << 2; // askjdfjasdkfjasdf + } + note->param = data[3] & 0xf; + switch (data[3] >> 4) { + case 3: // porta to note + note->param <<= 2; + break; + case 4: // retrig + note->param = 6 / (1 + (note->param & 0xf)) + 1; // ugh? + break; + case 6: // vibrato speed + case 7: // volume slide up + case 0xb: // panning + note->param <<= 4; + break; + case 0xa: // volume-portamento (what!) + note->voleffect = VOLFX_VOLUME; + note->volparam = (note->param << 2) + 4; + break; + case 0xc: // note offset + note->param = 6 / (1 + (note->param & 0xf)) + 1; + note->param |= 0xd; + } + note->effect = far_effects[data[3] >> 4]; } int fmt_far_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - struct far_header fhdr; - struct far_sample fsmp; - song_sample_t *smp; - int nord, restartpos; - int n, pat, row, chn; - uint8_t orderlist[256]; - uint16_t pattern_size[256]; - uint8_t data[8]; - - slurp_read(fp, &fhdr, sizeof(fhdr)); - if (memcmp(fhdr.magic, "FAR\xfe", 4) != 0 || memcmp(fhdr.eof, "\x0d\x0a\x1a", 3) != 0) - return LOAD_UNSUPPORTED; - - fhdr.title[25] = '\0'; - strcpy(song->title, fhdr.title); - fhdr.header_len = bswapLE16(fhdr.header_len); - fhdr.message_len = bswapLE16(fhdr.message_len); - - for (n = 0; n < 16; n++) { - /* WHAT A GREAT WAY TO STORE THIS INFORMATION */ - song->channels[n].panning = short_panning_table[fhdr.chn_panning[n] & 0xf]; - song->channels[n].panning *= 4; //mphack - if (!fhdr.onoff[n]) - song->channels[n].flags |= CHN_MUTE; - } - for (; n < 64; n++) - song->channels[n].flags |= CHN_MUTE; - - song->initial_speed = fhdr.default_speed; - song->initial_tempo = 80; - - // to my knowledge, no other program is insane enough to save in this format - strcpy(song->tracker_id, "Farandole Composer"); - - /* Farandole's song message doesn't have line breaks, and the tracker runs in - some screwy ultra-wide text mode, so this displays more or less like crap. */ - read_lined_message(song->message, fp, fhdr.message_len, 132); - - - slurp_seek(fp, sizeof(fhdr) + fhdr.message_len, SEEK_SET); - - if ((lflags & (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) == (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) - return LOAD_SUCCESS; - - slurp_read(fp, orderlist, 256); - slurp_getc(fp); // supposed to be "number of patterns stored in the file"; apparently that's wrong - nord = slurp_getc(fp); - restartpos = slurp_getc(fp); - - nord = MIN(nord, MAX_ORDERS); - memcpy(song->orderlist, orderlist, nord); - memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); - - slurp_read(fp, pattern_size, 256 * 2); // byteswapped later - slurp_seek(fp, fhdr.header_len - (869 + fhdr.message_len), SEEK_CUR); - - for (pat = 0; pat < 256; pat++) { - int breakpos, rows; - song_note_t *note; - - pattern_size[pat] = bswapLE16(pattern_size[pat]); - - if (pat >= MAX_PATTERNS || pattern_size[pat] < (2 + 16 * 4)) { - slurp_seek(fp, pattern_size[pat], SEEK_CUR); - continue; - } - breakpos = slurp_getc(fp); - slurp_getc(fp); // apparently, this value is *not* used anymore!!! I will not support it!! - - rows = (pattern_size[pat] - 2) / (16 * 4); - if (!rows) - continue; - note = song->patterns[pat] = csf_allocate_pattern(rows); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; - breakpos = breakpos && breakpos < rows - 2 ? breakpos + 1 : -1; - for (row = 0; row < rows; row++, note += 48) { - for (chn = 0; chn < 16; chn++, note++) { - slurp_read(fp, data, 4); - far_import_note(note, data); - } - if (row == breakpos) - note->effect = FX_PATTERNBREAK; - } - } - csf_insert_restart_pos(song, restartpos); - - if (lflags & LOAD_NOSAMPLES) - return LOAD_SUCCESS; - - slurp_read(fp, data, 8); - smp = song->samples + 1; - for (n = 0; n < 64; n++, smp++) { - if (!(data[n / 8] & (1 << (n % 8)))) /* LOLWHAT */ - continue; - slurp_read(fp, &fsmp, sizeof(fsmp)); - fsmp.name[25] = '\0'; - strcpy(smp->name, fsmp.name); - smp->length = fsmp.length = bswapLE32(fsmp.length); - smp->loop_start = bswapLE32(fsmp.loopstart); - smp->loop_end = bswapLE32(fsmp.loopend); - smp->volume = fsmp.volume << 4; // "not supported", but seems to exist anyway - if (fsmp.type & 1) { - smp->length >>= 1; - smp->loop_start >>= 1; - smp->loop_end >>= 1; - } - if (smp->loop_end > smp->loop_start && (fsmp.loop & 8)) - smp->flags |= CHN_LOOP; - smp->c5speed = 16726; - smp->global_volume = 64; - csf_read_sample(smp, SF_LE | SF_M | SF_PCMS | ((fsmp.type & 1) ? SF_16 : SF_8), - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, fsmp.length, SEEK_CUR); - } + struct far_header fhdr; + struct far_sample fsmp; + song_sample_t *smp; + int nord, restartpos; + int n, pat, row, chn; + uint8_t orderlist[256]; + uint16_t pattern_size[256]; + uint8_t data[8]; + + slurp_read(fp, &fhdr, sizeof(fhdr)); + if (memcmp(fhdr.magic, "FAR\xfe", 4) != 0 || memcmp(fhdr.eof, "\x0d\x0a\x1a", 3) != 0) + return LOAD_UNSUPPORTED; + + fhdr.title[25] = '\0'; + strcpy(song->title, fhdr.title); + fhdr.header_len = bswapLE16(fhdr.header_len); + fhdr.message_len = bswapLE16(fhdr.message_len); + + for (n = 0; n < 16; n++) { + /* WHAT A GREAT WAY TO STORE THIS INFORMATION */ + song->channels[n].panning = SHORT_PANNING(fhdr.chn_panning[n] & 0xf); + song->channels[n].panning *= 4; //mphack + if (!fhdr.onoff[n]) + song->channels[n].flags |= CHN_MUTE; + } + for (; n < 64; n++) + song->channels[n].flags |= CHN_MUTE; + + song->initial_speed = fhdr.default_speed; + song->initial_tempo = 80; + + // to my knowledge, no other program is insane enough to save in this format + strcpy(song->tracker_id, "Farandole Composer"); + + /* Farandole's song message doesn't have line breaks, and the tracker runs in + some screwy ultra-wide text mode, so this displays more or less like crap. */ + read_lined_message(song->message, fp, fhdr.message_len, 132); + + + slurp_seek(fp, sizeof(fhdr) + fhdr.message_len, SEEK_SET); + + if ((lflags & (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) == (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) + return LOAD_SUCCESS; + + slurp_read(fp, orderlist, 256); + slurp_getc(fp); // supposed to be "number of patterns stored in the file"; apparently that's wrong + nord = slurp_getc(fp); + restartpos = slurp_getc(fp); + + nord = MIN(nord, MAX_ORDERS); + memcpy(song->orderlist, orderlist, nord); + memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); + + slurp_read(fp, pattern_size, 256 * 2); // byteswapped later + slurp_seek(fp, fhdr.header_len - (869 + fhdr.message_len), SEEK_CUR); + + for (pat = 0; pat < 256; pat++) { + int breakpos, rows; + song_note_t *note; + + pattern_size[pat] = bswapLE16(pattern_size[pat]); + + if (pat >= MAX_PATTERNS || pattern_size[pat] < (2 + 16 * 4)) { + slurp_seek(fp, pattern_size[pat], SEEK_CUR); + continue; + } + breakpos = slurp_getc(fp); + slurp_getc(fp); // apparently, this value is *not* used anymore!!! I will not support it!! + + rows = (pattern_size[pat] - 2) / (16 * 4); + if (!rows) + continue; + note = song->patterns[pat] = csf_allocate_pattern(rows); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; + breakpos = breakpos && breakpos < rows - 2 ? breakpos + 1 : -1; + for (row = 0; row < rows; row++, note += 48) { + for (chn = 0; chn < 16; chn++, note++) { + slurp_read(fp, data, 4); + far_import_note(note, data); + } + if (row == breakpos) + note->effect = FX_PATTERNBREAK; + } + } + csf_insert_restart_pos(song, restartpos); + + if (lflags & LOAD_NOSAMPLES) + return LOAD_SUCCESS; + + slurp_read(fp, data, 8); + smp = song->samples + 1; + for (n = 0; n < 64; n++, smp++) { + if (!(data[n / 8] & (1 << (n % 8)))) /* LOLWHAT */ + continue; + slurp_read(fp, &fsmp, sizeof(fsmp)); + fsmp.name[25] = '\0'; + strcpy(smp->name, fsmp.name); + smp->length = fsmp.length = bswapLE32(fsmp.length); + smp->loop_start = bswapLE32(fsmp.loopstart); + smp->loop_end = bswapLE32(fsmp.loopend); + smp->volume = fsmp.volume << 4; // "not supported", but seems to exist anyway + if (fsmp.type & 1) { + smp->length >>= 1; + smp->loop_start >>= 1; + smp->loop_end >>= 1; + } + if (smp->loop_end > smp->loop_start && (fsmp.loop & 8)) + smp->flags |= CHN_LOOP; + smp->c5speed = 16726; + smp->global_volume = 64; + csf_read_sample(smp, SF_LE | SF_M | SF_PCMS | ((fsmp.type & 1) ? SF_16 : SF_8), + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, fsmp.length, SEEK_CUR); + } - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/generic.c schism-20160521/fmt/generic.c --- schism-0+20110101/fmt/generic.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/generic.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,220 +28,220 @@ static int _mod_period_to_note(int period) { - int n; + int n; - if (period) - for (n = 0; n <= NOTE_LAST; n++) - if (period >= (32 * period_table[n % 12] >> (n / 12 + 2))) - return n + 1; - return NOTE_NONE; + if (period) + for (n = 0; n <= NOTE_LAST; n++) + if (period >= (32 * period_table[n % 12] >> (n / 12 + 2))) + return n + 1; + return NOTE_NONE; } void mod_import_note(const uint8_t p[4], song_note_t *note) { - note->note = _mod_period_to_note(((p[0] & 0xf) << 8) + p[1]); - note->instrument = (p[0] & 0xf0) + (p[2] >> 4); - note->voleffect = VOLFX_NONE; - note->volparam = 0; - note->effect = p[2] & 0xf; - note->param = p[3]; + note->note = _mod_period_to_note(((p[0] & 0xf) << 8) + p[1]); + note->instrument = (p[0] & 0xf0) + (p[2] >> 4); + note->voleffect = VOLFX_NONE; + note->volparam = 0; + note->effect = p[2] & 0xf; + note->param = p[3]; } /* --------------------------------------------------------------------------------------------------------- */ const uint8_t effect_weight[FX_MAX] = { - [FX_PATTERNBREAK] = 248, - [FX_POSITIONJUMP] = 240, - [FX_SPEED] = 232, - [FX_TEMPO] = 224, - [FX_GLOBALVOLUME] = 216, - [FX_GLOBALVOLSLIDE] = 208, - [FX_CHANNELVOLUME] = 200, - [FX_CHANNELVOLSLIDE] = 192, - [FX_TONEPORTAVOL] = 184, - [FX_TONEPORTAMENTO] = 176, - [FX_ARPEGGIO] = 168, - [FX_RETRIG] = 160, - [FX_TREMOR] = 152, - [FX_OFFSET] = 144, - [FX_VOLUME] = 136, - [FX_VIBRATOVOL] = 128, - [FX_VOLUMESLIDE] = 120, - [FX_PORTAMENTODOWN] = 112, - [FX_PORTAMENTOUP] = 104, - [FX_NOTESLIDEDOWN] = 96, // IMF Hxy - [FX_NOTESLIDEUP] = 88, // IMF Gxy - [FX_PANNING] = 80, - [FX_PANNINGSLIDE] = 72, - [FX_MIDI] = 64, - [FX_SPECIAL] = 56, - [FX_PANBRELLO] = 48, - [FX_VIBRATO] = 40, - [FX_FINEVIBRATO] = 32, - [FX_TREMOLO] = 24, - [FX_KEYOFF] = 16, - [FX_SETENVPOSITION] = 8, - [FX_NONE] = 0, + [FX_PATTERNBREAK] = 248, + [FX_POSITIONJUMP] = 240, + [FX_SPEED] = 232, + [FX_TEMPO] = 224, + [FX_GLOBALVOLUME] = 216, + [FX_GLOBALVOLSLIDE] = 208, + [FX_CHANNELVOLUME] = 200, + [FX_CHANNELVOLSLIDE] = 192, + [FX_TONEPORTAVOL] = 184, + [FX_TONEPORTAMENTO] = 176, + [FX_ARPEGGIO] = 168, + [FX_RETRIG] = 160, + [FX_TREMOR] = 152, + [FX_OFFSET] = 144, + [FX_VOLUME] = 136, + [FX_VIBRATOVOL] = 128, + [FX_VOLUMESLIDE] = 120, + [FX_PORTAMENTODOWN] = 112, + [FX_PORTAMENTOUP] = 104, + [FX_NOTESLIDEDOWN] = 96, // IMF Hxy + [FX_NOTESLIDEUP] = 88, // IMF Gxy + [FX_PANNING] = 80, + [FX_PANNINGSLIDE] = 72, + [FX_MIDI] = 64, + [FX_SPECIAL] = 56, + [FX_PANBRELLO] = 48, + [FX_VIBRATO] = 40, + [FX_FINEVIBRATO] = 32, + [FX_TREMOLO] = 24, + [FX_KEYOFF] = 16, + [FX_SETENVPOSITION] = 8, + [FX_NONE] = 0, }; void swap_effects(song_note_t *note) { - song_note_t tmp = { - .note = note->note, - .instrument = note->instrument, - .voleffect = note->effect, - .volparam = note->param, - .effect = note->voleffect, - .param = note->volparam, - }; - *note = tmp; + song_note_t tmp = { + .note = note->note, + .instrument = note->instrument, + .voleffect = note->effect, + .volparam = note->param, + .effect = note->voleffect, + .param = note->volparam, + }; + *note = tmp; } int convert_voleffect(uint8_t *e, uint8_t *p, int force) { - switch (*e) { - case FX_NONE: - return 1; - case FX_VOLUME: - *e = VOLFX_VOLUME; - *p = MIN(*p, 64); - break; - case FX_PORTAMENTOUP: - /* if not force, reject when dividing causes loss of data in LSB, or if the final value is too - large to fit. (volume column Ex/Fx are four times stronger than effect column) */ - if (!force && ((*p & 3) || *p > 9 * 4 + 3)) - return 0; - *p = MIN(*p / 4, 9); - *e = VOLFX_PORTAUP; - break; - case FX_PORTAMENTODOWN: - if (!force && ((*p & 3) || *p > 9 * 4 + 3)) - return 0; - *p = MIN(*p / 4, 9); - *e = VOLFX_PORTADOWN; - break; - case FX_TONEPORTAMENTO: - if (*p >= 0xf0) { - // hack for people who can't type F twice :) - *e = VOLFX_TONEPORTAMENTO; - *p = 0xff; - return 1; - } - for (int n = 0; n < 10; n++) { - if (force - ? (*p <= vc_portamento_table[n]) - : (*p == vc_portamento_table[n])) { - *e = VOLFX_TONEPORTAMENTO; - *p = n; - return 1; - } - } - return 0; - case FX_VIBRATO: - if (force) - *p = MIN(*p, 9); - else if (*p > 9) - return 0; - *e = VOLFX_VIBRATODEPTH; - break; - case FX_FINEVIBRATO: - if (force) - *p = 0; - else if (*p) - return 0; - *e = VOLFX_VIBRATODEPTH; - break; - case FX_PANNING: - *p = MIN(64, *p * 64 / 255); - *e = VOLFX_PANNING; - break; - case FX_VOLUMESLIDE: - // ugh - // (IT doesn't even attempt to do this, presumably since it'd screw up the effect memory) - if (*p == 0) - return 0; - if ((*p & 0xf) == 0) { // Dx0 / Cx - if (force) - *p = MIN(*p >> 4, 9); - else if ((*p >> 4) > 9) - return 0; - else - *p >>= 4; - *e = VOLFX_VOLSLIDEUP; - } else if ((*p & 0xf0) == 0) { // D0x / Dx - if (force) - *p = MIN(*p, 9); - else if (*p > 9) - return 0; - *e = VOLFX_VOLSLIDEDOWN; - } else if ((*p & 0xf) == 0xf) { // DxF / Ax - if (force) - *p = MIN(*p >> 4, 9); - else if ((*p >> 4) > 9) - return 0; - else - *p >>= 4; - *e = VOLFX_FINEVOLUP; - } else if ((*p & 0xf0) == 0xf0) { // DFx / Bx - if (force) - *p = MIN(*p, 9); - else if ((*p & 0xf) > 9) - return 0; - else - *p &= 0xf; - *e = VOLFX_FINEVOLDOWN; - } else { // ??? - return 0; - } - break; - case FX_SPECIAL: - switch (*p >> 4) { - case 8: - /* Impulse Tracker imports XM volume-column panning very weirdly: - XM = P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 PA PB PC PD PE PF - IT = 00 05 10 15 20 21 30 31 40 45 42 47 60 61 62 63 - I'll be um, not duplicating that behavior. :) */ - *e = VOLFX_PANNING; - *p = short_panning_table[*p & 0xf]; - return 1; - case 0: case 1: case 2: case 0xf: - if (force) { - *e = *p = 0; - return 1; - } - break; - default: - break; - } - return 0; - default: - return 0; - } - return 1; + switch (*e) { + case FX_NONE: + return 1; + case FX_VOLUME: + *e = VOLFX_VOLUME; + *p = MIN(*p, 64); + break; + case FX_PORTAMENTOUP: + /* if not force, reject when dividing causes loss of data in LSB, or if the final value is too + large to fit. (volume column Ex/Fx are four times stronger than effect column) */ + if (!force && ((*p & 3) || *p > 9 * 4 + 3)) + return 0; + *p = MIN(*p / 4, 9); + *e = VOLFX_PORTAUP; + break; + case FX_PORTAMENTODOWN: + if (!force && ((*p & 3) || *p > 9 * 4 + 3)) + return 0; + *p = MIN(*p / 4, 9); + *e = VOLFX_PORTADOWN; + break; + case FX_TONEPORTAMENTO: + if (*p >= 0xf0) { + // hack for people who can't type F twice :) + *e = VOLFX_TONEPORTAMENTO; + *p = 0x9; + return 1; + } + for (int n = 0; n < 10; n++) { + if (force + ? (*p <= vc_portamento_table[n]) + : (*p == vc_portamento_table[n])) { + *e = VOLFX_TONEPORTAMENTO; + *p = n; + return 1; + } + } + return 0; + case FX_VIBRATO: + if (force) + *p = MIN(*p, 9); + else if (*p > 9) + return 0; + *e = VOLFX_VIBRATODEPTH; + break; + case FX_FINEVIBRATO: + if (force) + *p = 0; + else if (*p) + return 0; + *e = VOLFX_VIBRATODEPTH; + break; + case FX_PANNING: + *p = MIN(64, *p * 64 / 255); + *e = VOLFX_PANNING; + break; + case FX_VOLUMESLIDE: + // ugh + // (IT doesn't even attempt to do this, presumably since it'd screw up the effect memory) + if (*p == 0) + return 0; + if ((*p & 0xf) == 0) { // Dx0 / Cx + if (force) + *p = MIN(*p >> 4, 9); + else if ((*p >> 4) > 9) + return 0; + else + *p >>= 4; + *e = VOLFX_VOLSLIDEUP; + } else if ((*p & 0xf0) == 0) { // D0x / Dx + if (force) + *p = MIN(*p, 9); + else if (*p > 9) + return 0; + *e = VOLFX_VOLSLIDEDOWN; + } else if ((*p & 0xf) == 0xf) { // DxF / Ax + if (force) + *p = MIN(*p >> 4, 9); + else if ((*p >> 4) > 9) + return 0; + else + *p >>= 4; + *e = VOLFX_FINEVOLUP; + } else if ((*p & 0xf0) == 0xf0) { // DFx / Bx + if (force) + *p = MIN(*p, 9); + else if ((*p & 0xf) > 9) + return 0; + else + *p &= 0xf; + *e = VOLFX_FINEVOLDOWN; + } else { // ??? + return 0; + } + break; + case FX_SPECIAL: + switch (*p >> 4) { + case 8: + /* Impulse Tracker imports XM volume-column panning very weirdly: + XM = P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 PA PB PC PD PE PF + IT = 00 05 10 15 20 21 30 31 40 45 42 47 60 61 62 63 + I'll be um, not duplicating that behavior. :) */ + *e = VOLFX_PANNING; + *p = SHORT_PANNING(*p & 0xf); + return 1; + case 0: case 1: case 2: case 0xf: + if (force) { + *e = *p = 0; + return 1; + } + break; + default: + break; + } + return 0; + default: + return 0; + } + return 1; } void read_lined_message(char *msg, slurp_t *fp, int len, int linelen) { - int msgsize = 0, linesize; + int msgsize = 0, linesize; - while (len) { - linesize = MIN(len, linelen); - if (msgsize + linesize + 1 >= MAX_MESSAGE) { - /* Skip the rest */ - slurp_seek(fp, len, SEEK_CUR); - break; - } - - slurp_read(fp, msg, linesize); - len -= linesize; - - msg[linesize] = '\0'; - linesize = rtrim_string(msg); - msgsize += linesize + 1; - msg += linesize; - *msg++ = '\n'; - } - *msg = '\0'; + while (len) { + linesize = MIN(len, linelen); + if (msgsize + linesize + 1 >= MAX_MESSAGE) { + /* Skip the rest */ + slurp_seek(fp, len, SEEK_CUR); + break; + } + + slurp_read(fp, msg, linesize); + len -= linesize; + + msg[linesize] = '\0'; + linesize = rtrim_string(msg); + msgsize += linesize + 1; + msg += linesize; + *msg++ = '\n'; + } + *msg = '\0'; } diff -Nru schism-0+20110101/fmt/imf.c schism-20160521/fmt/imf.c --- schism-0+20110101/fmt/imf.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/imf.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -33,545 +33,554 @@ int fmt_imf_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 64 && memcmp(data + 60, "IM10", 4) == 0)) - return 0; + if (!(length > 64 && memcmp(data + 60, "IM10", 4) == 0)) + return 0; - file->description = "Imago Orpheus"; - /*file->extension = str_dup("imf");*/ - file->title = calloc(33, sizeof(char)); - memcpy(file->title, data, 32); - file->title[32] = 0; - file->type = TYPE_MODULE_IT; - return 1; + file->description = "Imago Orpheus"; + /*file->extension = str_dup("imf");*/ + file->title = calloc(33, sizeof(char)); + memcpy(file->title, data, 32); + file->title[32] = 0; + file->type = TYPE_MODULE_IT; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ #pragma pack(push, 1) struct imf_channel { - char name[12]; /* Channelname (ASCIIZ-String, max 11 chars) */ - uint8_t chorus; /* Default chorus */ - uint8_t reverb; /* Default reverb */ - uint8_t panning; /* Pan positions 00-FF */ - uint8_t status; /* Channel status: 0 = enabled, 1 = mute, 2 = disabled (ignore effects!) */ + char name[12]; /* Channelname (ASCIIZ-String, max 11 chars) */ + uint8_t chorus; /* Default chorus */ + uint8_t reverb; /* Default reverb */ + uint8_t panning; /* Pan positions 00-FF */ + uint8_t status; /* Channel status: 0 = enabled, 1 = mute, 2 = disabled (ignore effects!) */ }; struct imf_header { - char title[32]; /* Songname (ASCIIZ-String, max. 31 chars) */ - uint16_t ordnum; /* Number of orders saved */ - uint16_t patnum; /* Number of patterns saved */ - uint16_t insnum; /* Number of instruments saved */ - uint16_t flags; /* Module flags (&1 => linear) */ - uint8_t unused1[8]; - uint8_t tempo; /* Default tempo (Axx, 1..255) */ - uint8_t bpm; /* Default beats per minute (BPM) (Txx, 32..255) */ - uint8_t master; /* Default mastervolume (Vxx, 0..64) */ - uint8_t amp; /* Amplification factor (mixing volume, 4..127) */ - uint8_t unused2[8]; - char im10[4]; /* 'IM10' */ - struct imf_channel channels[32]; /* Channel settings */ - uint8_t orderlist[256]; /* Order list (0xff = +++; blank out anything beyond ordnum) */ + char title[32]; /* Songname (ASCIIZ-String, max. 31 chars) */ + uint16_t ordnum; /* Number of orders saved */ + uint16_t patnum; /* Number of patterns saved */ + uint16_t insnum; /* Number of instruments saved */ + uint16_t flags; /* Module flags (&1 => linear) */ + uint8_t unused1[8]; + uint8_t tempo; /* Default tempo (Axx, 1..255) */ + uint8_t bpm; /* Default beats per minute (BPM) (Txx, 32..255) */ + uint8_t master; /* Default mastervolume (Vxx, 0..64) */ + uint8_t amp; /* Amplification factor (mixing volume, 4..127) */ + uint8_t unused2[8]; + char im10[4]; /* 'IM10' */ + struct imf_channel channels[32]; /* Channel settings */ + uint8_t orderlist[256]; /* Order list (0xff = +++; blank out anything beyond ordnum) */ }; enum { - IMF_ENV_VOL = 0, - IMF_ENV_PAN = 1, - IMF_ENV_FILTER = 2, + IMF_ENV_VOL = 0, + IMF_ENV_PAN = 1, + IMF_ENV_FILTER = 2, }; struct imf_env { - uint8_t points; /* Number of envelope points */ - uint8_t sustain; /* Envelope sustain point */ - uint8_t loop_start; /* Envelope loop start point */ - uint8_t loop_end; /* Envelope loop end point */ - uint8_t flags; /* Envelope flags */ - uint8_t unused[3]; + uint8_t points; /* Number of envelope points */ + uint8_t sustain; /* Envelope sustain point */ + uint8_t loop_start; /* Envelope loop start point */ + uint8_t loop_end; /* Envelope loop end point */ + uint8_t flags; /* Envelope flags */ + uint8_t unused[3]; }; struct imf_envnodes { - uint16_t tick; - uint16_t value; + uint16_t tick; + uint16_t value; }; struct imf_instrument { - char name[32]; /* Inst. name (ASCIIZ-String, max. 31 chars) */ - uint8_t map[120]; /* Multisample settings */ - uint8_t unused[8]; - struct imf_envnodes nodes[3][16]; - struct imf_env env[3]; - uint16_t fadeout; /* Fadeout rate (0...0FFFH) */ - uint16_t smpnum; /* Number of samples in instrument */ - char ii10[4]; /* 'II10' */ + char name[32]; /* Inst. name (ASCIIZ-String, max. 31 chars) */ + uint8_t map[120]; /* Multisample settings */ + uint8_t unused[8]; + struct imf_envnodes nodes[3][16]; + struct imf_env env[3]; + uint16_t fadeout; /* Fadeout rate (0...0FFFH) */ + uint16_t smpnum; /* Number of samples in instrument */ + char ii10[4]; /* 'II10' */ }; struct imf_sample { - char name[13]; /* Sample filename (12345678.ABC) */ - uint8_t unused1[3]; - uint32_t length; /* Length */ - uint32_t loop_start; /* Loop start */ - uint32_t loop_end; /* Loop end */ - uint32_t c5speed; /* Samplerate */ - uint8_t volume; /* Default volume (0..64) */ - uint8_t panning; /* Default pan (00h = Left / 80h = Middle) */ - uint8_t unused2[14]; - uint8_t flags; /* Sample flags */ - uint8_t unused3[5]; - uint16_t ems; /* Reserved for internal usage */ - uint32_t dram; /* Reserved for internal usage */ - char is10[4]; /* 'IS10' */ + char name[13]; /* Sample filename (12345678.ABC) */ + uint8_t unused1[3]; + uint32_t length; /* Length */ + uint32_t loop_start; /* Loop start */ + uint32_t loop_end; /* Loop end */ + uint32_t c5speed; /* Samplerate */ + uint8_t volume; /* Default volume (0..64) */ + uint8_t panning; /* Default pan (00h = Left / 80h = Middle) */ + uint8_t unused2[14]; + uint8_t flags; /* Sample flags */ + uint8_t unused3[5]; + uint16_t ems; /* Reserved for internal usage */ + uint32_t dram; /* Reserved for internal usage */ + char is10[4]; /* 'IS10' */ }; #pragma pack(pop) static uint8_t imf_efftrans[] = { - FX_NONE, - FX_SPEED, // 0x01 1xx Set Tempo - FX_TEMPO, // 0x02 2xx Set BPM - FX_TONEPORTAMENTO, // 0x03 3xx Tone Portamento (*) - FX_TONEPORTAVOL, // 0x04 4xy Tone Portamento + Volume Slide (*) - FX_VIBRATO, // 0x05 5xy Vibrato (*) - FX_VIBRATOVOL, // 0x06 6xy Vibrato + Volume Slide (*) - FX_FINEVIBRATO, // 0x07 7xy Fine Vibrato (*) - FX_TREMOLO, // 0x08 8xy Tremolo (*) - FX_ARPEGGIO, // 0x09 9xy Arpeggio (*) - FX_PANNING, // 0x0A Axx Set Pan Position - FX_PANNINGSLIDE, // 0x0B Bxy Pan Slide (*) - FX_VOLUME, // 0x0C Cxx Set Volume - FX_VOLUMESLIDE, // 0x0D Dxy Volume Slide (*) - FX_VOLUMESLIDE, // 0x0E Exy Fine Volume Slide (*) - FX_SPECIAL, // 0x0F Fxx Set Finetune - FX_NOTESLIDEUP, // 0x10 Gxy Note Slide Up (*) - FX_NOTESLIDEDOWN, // 0x11 Hxy Note Slide Down (*) - FX_PORTAMENTOUP, // 0x12 Ixx Slide Up (*) - FX_PORTAMENTODOWN, // 0x13 Jxx Slide Down (*) - FX_PORTAMENTOUP, // 0x14 Kxx Fine Slide Up (*) - FX_PORTAMENTODOWN, // 0x15 Lxx Fine Slide Down (*) - FX_MIDI, // 0x16 Mxx Set Filter Cutoff - XXX - FX_NONE, // 0x17 Nxy Filter Slide + Resonance - XXX - FX_OFFSET, // 0x18 Oxx Set Sample Offset (*) - FX_NONE, // 0x19 Pxx Set Fine Sample Offset - XXX - FX_KEYOFF, // 0x1A Qxx Key Off - FX_RETRIG, // 0x1B Rxy Retrig (*) - FX_TREMOR, // 0x1C Sxy Tremor (*) - FX_POSITIONJUMP, // 0x1D Txx Position Jump - FX_PATTERNBREAK, // 0x1E Uxx Pattern Break - FX_GLOBALVOLUME, // 0x1F Vxx Set Mastervolume - FX_GLOBALVOLSLIDE, // 0x20 Wxy Mastervolume Slide (*) - FX_SPECIAL, // 0x21 Xxx Extended Effect - // X1x Set Filter - // X3x Glissando - // X5x Vibrato Waveform - // X8x Tremolo Waveform - // XAx Pattern Loop - // XBx Pattern Delay - // XCx Note Cut - // XDx Note Delay - // XEx Ignore Envelope - // XFx Invert Loop - FX_NONE, // 0x22 Yxx Chorus - XXX - FX_NONE, // 0x23 Zxx Reverb - XXX + FX_NONE, + FX_SPEED, // 0x01 1xx Set Tempo + FX_TEMPO, // 0x02 2xx Set BPM + FX_TONEPORTAMENTO, // 0x03 3xx Tone Portamento (*) + FX_TONEPORTAVOL, // 0x04 4xy Tone Portamento + Volume Slide (*) + FX_VIBRATO, // 0x05 5xy Vibrato (*) + FX_VIBRATOVOL, // 0x06 6xy Vibrato + Volume Slide (*) + FX_FINEVIBRATO, // 0x07 7xy Fine Vibrato (*) + FX_TREMOLO, // 0x08 8xy Tremolo (*) + FX_ARPEGGIO, // 0x09 9xy Arpeggio (*) + FX_PANNING, // 0x0A Axx Set Pan Position + FX_PANNINGSLIDE, // 0x0B Bxy Pan Slide (*) + FX_VOLUME, // 0x0C Cxx Set Volume + FX_VOLUMESLIDE, // 0x0D Dxy Volume Slide (*) + FX_VOLUMESLIDE, // 0x0E Exy Fine Volume Slide (*) + FX_SPECIAL, // 0x0F Fxx Set Finetune + FX_NOTESLIDEUP, // 0x10 Gxy Note Slide Up (*) + FX_NOTESLIDEDOWN, // 0x11 Hxy Note Slide Down (*) + FX_PORTAMENTOUP, // 0x12 Ixx Slide Up (*) + FX_PORTAMENTODOWN, // 0x13 Jxx Slide Down (*) + FX_PORTAMENTOUP, // 0x14 Kxx Fine Slide Up (*) + FX_PORTAMENTODOWN, // 0x15 Lxx Fine Slide Down (*) + FX_MIDI, // 0x16 Mxx Set Filter Cutoff - XXX + FX_NONE, // 0x17 Nxy Filter Slide + Resonance - XXX + FX_OFFSET, // 0x18 Oxx Set Sample Offset (*) + FX_NONE, // 0x19 Pxx Set Fine Sample Offset - XXX + FX_KEYOFF, // 0x1A Qxx Key Off + FX_RETRIG, // 0x1B Rxy Retrig (*) + FX_TREMOR, // 0x1C Sxy Tremor (*) + FX_POSITIONJUMP, // 0x1D Txx Position Jump + FX_PATTERNBREAK, // 0x1E Uxx Pattern Break + FX_GLOBALVOLUME, // 0x1F Vxx Set Mastervolume + FX_GLOBALVOLSLIDE, // 0x20 Wxy Mastervolume Slide (*) + FX_SPECIAL, // 0x21 Xxx Extended Effect + // X1x Set Filter + // X3x Glissando + // X5x Vibrato Waveform + // X8x Tremolo Waveform + // XAx Pattern Loop + // XBx Pattern Delay + // XCx Note Cut + // XDx Note Delay + // XEx Ignore Envelope + // XFx Invert Loop + FX_NONE, // 0x22 Yxx Chorus - XXX + FX_NONE, // 0x23 Zxx Reverb - XXX }; static void import_imf_effect(song_note_t *note) { - uint8_t n; - // fix some of them - switch (note->effect) { - case 0xe: // fine volslide - // hackaround to get almost-right behavior for fine slides (i think!) - if (note->param == 0) - /* nothing */; - else if (note->param == 0xf0) - note->param = 0xef; - else if (note->param == 0x0f) - note->param = 0xfe; - else if (note->param & 0xf0) - note->param |= 0xf; - else - note->param |= 0xf0; - break; - case 0xf: // set finetune - // we don't implement this, but let's at least import the value - note->param = 0x20 | MIN(note->param >> 4, 0xf); - break; - case 0x14: // fine slide up - case 0x15: // fine slide down - // this is about as close as we can do... - if (note->param >> 4) - note->param = 0xf0 | MIN(note->param >> 4, 0xf); - else - note->param |= 0xe0; - break; - case 0x1f: // set global volume - note->param = MIN(note->param << 1, 0xff); - break; - case 0x21: - n = 0; - switch (note->param >> 4) { - case 0: - /* undefined, but since S0x does nothing in IT anyway, we won't care. - this is here to allow S00 to pick up the previous value (assuming IMF - even does that -- I haven't actually tried it) */ - break; - default: // undefined - case 0x1: // set filter - case 0xf: // invert loop - note->effect = 0; - break; - case 0x3: // glissando - n = 0x20; - break; - case 0x5: // vibrato waveform - n = 0x30; - break; - case 0x8: // tremolo waveform - n = 0x40; - break; - case 0xa: // pattern loop - n = 0xb0; - break; - case 0xb: // pattern delay - n = 0xe0; - break; - case 0xc: // note cut - case 0xd: // note delay - // no change - break; - case 0xe: // ignore envelope - /* predicament: we can only disable one envelope at a time. - volume is probably most noticeable, so let's go with that. - (... actually, orpheus doesn't even seem to implement this at all) */ - note->param = 0x77; - break; - case 0x18: // sample offset - // O00 doesn't pick up the previous value - if (!note->param) - note->effect = 0; - break; - } - if (n) - note->param = n | (note->param & 0xf); - break; - } - note->effect = (note->effect < 0x24) ? imf_efftrans[note->effect] : FX_NONE; - if (note->effect == FX_VOLUME && note->voleffect == VOLFX_NONE) { - note->voleffect = VOLFX_VOLUME; - note->volparam = note->param; - note->effect = FX_NONE; - note->param = 0; - } + uint8_t n; + // fix some of them + switch (note->effect) { + case 0xe: // fine volslide + // hackaround to get almost-right behavior for fine slides (i think!) + if (note->param == 0) + /* nothing */; + else if (note->param == 0xf0) + note->param = 0xef; + else if (note->param == 0x0f) + note->param = 0xfe; + else if (note->param & 0xf0) + note->param |= 0xf; + else + note->param |= 0xf0; + break; + case 0xf: // set finetune + // we don't implement this, but let's at least import the value + note->param = 0x20 | MIN(note->param >> 4, 0xf); + break; + case 0x14: // fine slide up + case 0x15: // fine slide down + // this is about as close as we can do... + if (note->param >> 4) + note->param = 0xf0 | MIN(note->param >> 4, 0xf); + else + note->param |= 0xe0; + break; + case 0x16: // filter + // Storlek: schism's IMF loader should shift the param of command 0x16 one to the right (cutoff range in orpheus is 8-bit, not 7-bit) + note->param >>= 1; + break; + case 0x1f: // set global volume + note->param = MIN(note->param << 1, 0xff); + break; + case 0x21: + n = 0; + switch (note->param >> 4) { + case 0: + /* undefined, but since S0x does nothing in IT anyway, we won't care. + this is here to allow S00 to pick up the previous value (assuming IMF + even does that -- I haven't actually tried it) */ + break; + default: // undefined + case 0x1: // set filter + case 0xf: // invert loop + note->effect = 0; + break; + case 0x3: // glissando + n = 0x20; + break; + case 0x5: // vibrato waveform + n = 0x30; + break; + case 0x8: // tremolo waveform + n = 0x40; + break; + case 0xa: // pattern loop + n = 0xb0; + break; + case 0xb: // pattern delay + n = 0xe0; + break; + case 0xc: // note cut + case 0xd: // note delay + // no change + break; + case 0xe: // ignore envelope + /* predicament: we can only disable one envelope at a time. + volume is probably most noticeable, so let's go with that. + (... actually, orpheus doesn't even seem to implement this at all) */ + note->param = 0x77; + break; + case 0x18: // sample offset + // O00 doesn't pick up the previous value + if (!note->param) + note->effect = 0; + break; + } + if (n) + note->param = n | (note->param & 0xf); + break; + } + note->effect = (note->effect < 0x24) ? imf_efftrans[note->effect] : FX_NONE; + if (note->effect == FX_VOLUME && note->voleffect == VOLFX_NONE) { + note->voleffect = VOLFX_VOLUME; + note->volparam = note->param; + note->effect = FX_NONE; + note->param = 0; + } } /* return: number of lost effects */ static int load_imf_pattern(song_t *song, int pat, uint32_t ignore_channels, slurp_t *fp) { - uint16_t length, nrows; - uint8_t mask, channel; - int row, startpos; - unsigned int lostfx = 0; - song_note_t *row_data, *note, junk_note; - - startpos = slurp_tell(fp); - - slurp_read(fp, &length, 2); - length = bswapLE16(length); - slurp_read(fp, &nrows, 2); - nrows = bswapLE16(nrows); - - row_data = song->patterns[pat] = csf_allocate_pattern(nrows); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = nrows; - - row = 0; - while (row < nrows) { - mask = slurp_getc(fp); - if (mask == 0) { - row++; - row_data += MAX_CHANNELS; - continue; - } - - channel = mask & 0x1f; - - if (ignore_channels & (1 << channel)) { - /* should do this better, i.e. not go through the whole process of deciding - what to do with the effects since they're just being thrown out */ - //printf("disabled channel %d contains data\n", channel + 1); - note = &junk_note; - } else { - note = row_data + channel; - } - - if (mask & 0x20) { - /* read note/instrument */ - note->note = slurp_getc(fp); - note->instrument = slurp_getc(fp); - if (note->note == 160) { - note->note = NOTE_OFF; /* ??? */ - } else if (note->note == 255) { - note->note = NOTE_NONE; /* ??? */ - } else { - note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 12 + 1; - if (!NOTE_IS_NOTE(note->note)) { - //printf("%d.%d.%d: funny note 0x%02x\n", - // pat, row, channel, fp->data[fp->pos - 1]); - note->note = NOTE_NONE; - } - } - } - if ((mask & 0xc0) == 0xc0) { - uint8_t e1c, e1d, e2c, e2d; - - /* read both effects and figure out what to do with them */ - e1c = slurp_getc(fp); - e1d = slurp_getc(fp); - e2c = slurp_getc(fp); - e2d = slurp_getc(fp); - if (e1c == 0xc) { - note->volparam = MIN(e1d, 0x40); - note->voleffect = VOLFX_VOLUME; - note->effect = e2c; - note->param = e2d; - } else if (e2c == 0xc) { - note->volparam = MIN(e2d, 0x40); - note->voleffect = VOLFX_VOLUME; - note->effect = e1c; - note->param = e1d; - } else if (e1c == 0xa) { - note->volparam = e1d * 64 / 255; - note->voleffect = VOLFX_PANNING; - note->effect = e2c; - note->param = e2d; - } else if (e2c == 0xa) { - note->volparam = e2d * 64 / 255; - note->voleffect = VOLFX_PANNING; - note->effect = e1c; - note->param = e1d; - } else { - /* check if one of the effects is a 'global' effect - -- if so, put it in some unused channel instead. - otherwise pick the most important effect. */ - lostfx++; - note->effect = e2c; - note->param = e2d; - } - } else if (mask & 0xc0) { - /* there's one effect, just stick it in the effect column */ - note->effect = slurp_getc(fp); - note->param = slurp_getc(fp); - } - if (note->effect) - import_imf_effect(note); - } + uint16_t length, nrows; + uint8_t mask, channel; + int row; + unsigned int lostfx = 0; + song_note_t *row_data, *note, junk_note; + + //int startpos = slurp_tell(fp); + + slurp_read(fp, &length, 2); + length = bswapLE16(length); + slurp_read(fp, &nrows, 2); + nrows = bswapLE16(nrows); + + row_data = song->patterns[pat] = csf_allocate_pattern(nrows); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = nrows; + + row = 0; + while (row < nrows) { + mask = slurp_getc(fp); + if (mask == 0) { + row++; + row_data += MAX_CHANNELS; + continue; + } + + channel = mask & 0x1f; + + if (ignore_channels & (1 << channel)) { + /* should do this better, i.e. not go through the whole process of deciding + what to do with the effects since they're just being thrown out */ + //printf("disabled channel %d contains data\n", channel + 1); + note = &junk_note; + } else { + note = row_data + channel; + } + + if (mask & 0x20) { + /* read note/instrument */ + note->note = slurp_getc(fp); + note->instrument = slurp_getc(fp); + if (note->note == 160) { + note->note = NOTE_OFF; /* ??? */ + } else if (note->note == 255) { + note->note = NOTE_NONE; /* ??? */ + } else { + note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 12 + 1; + if (!NOTE_IS_NOTE(note->note)) { + //printf("%d.%d.%d: funny note 0x%02x\n", + // pat, row, channel, fp->data[fp->pos - 1]); + note->note = NOTE_NONE; + } + } + } + if ((mask & 0xc0) == 0xc0) { + uint8_t e1c, e1d, e2c, e2d; + + /* read both effects and figure out what to do with them */ + e1c = slurp_getc(fp); + e1d = slurp_getc(fp); + e2c = slurp_getc(fp); + e2d = slurp_getc(fp); + if (e1c == 0xc) { + note->volparam = MIN(e1d, 0x40); + note->voleffect = VOLFX_VOLUME; + note->effect = e2c; + note->param = e2d; + } else if (e2c == 0xc) { + note->volparam = MIN(e2d, 0x40); + note->voleffect = VOLFX_VOLUME; + note->effect = e1c; + note->param = e1d; + } else if (e1c == 0xa) { + note->volparam = e1d * 64 / 255; + note->voleffect = VOLFX_PANNING; + note->effect = e2c; + note->param = e2d; + } else if (e2c == 0xa) { + note->volparam = e2d * 64 / 255; + note->voleffect = VOLFX_PANNING; + note->effect = e1c; + note->param = e1d; + } else { + /* check if one of the effects is a 'global' effect + -- if so, put it in some unused channel instead. + otherwise pick the most important effect. */ + lostfx++; + note->effect = e2c; + note->param = e2d; + } + } else if (mask & 0xc0) { + /* there's one effect, just stick it in the effect column */ + note->effect = slurp_getc(fp); + note->param = slurp_getc(fp); + } + if (note->effect) + import_imf_effect(note); + } - return lostfx; + return lostfx; } static unsigned int envflags[3][3] = { - {ENV_VOLUME, ENV_VOLSUSTAIN, ENV_VOLLOOP}, - {ENV_PANNING, ENV_PANSUSTAIN, ENV_PANLOOP}, - {ENV_PITCH | ENV_FILTER, ENV_PITCHSUSTAIN, ENV_PITCHLOOP}, + {ENV_VOLUME, ENV_VOLSUSTAIN, ENV_VOLLOOP}, + {ENV_PANNING, ENV_PANSUSTAIN, ENV_PANLOOP}, + {ENV_PITCH | ENV_FILTER, ENV_PITCHSUSTAIN, ENV_PITCHLOOP}, }; static void load_imf_envelope(song_instrument_t *ins, song_envelope_t *env, struct imf_instrument *imfins, int e) { - int n, t, v; - int min = 0; // minimum tick value for next node - int shift = (e == IMF_ENV_VOL ? 0 : 2); - - env->nodes = CLAMP(imfins->env[e].points, 2, 25); - env->loop_start = imfins->env[e].loop_start; - env->loop_end = imfins->env[e].loop_end; - env->sustain_start = env->sustain_end = imfins->env[e].sustain; - - for (n = 0; n < env->nodes; n++) { - t = bswapLE16(imfins->nodes[e][n].tick); - v = bswapLE16(imfins->nodes[e][n].value) >> shift; - env->ticks[n] = MAX(min, t); - env->values[n] = v = MIN(v, 64); - min = t + 1; - } - // this would be less retarded if the envelopes all had their own flags... - if (imfins->env[e].flags & 1) - ins->flags |= envflags[e][0]; - if (imfins->env[e].flags & 2) - ins->flags |= envflags[e][1]; - if (imfins->env[e].flags & 4) - ins->flags |= envflags[e][2]; + int n, t, v; + int min = 0; // minimum tick value for next node + int shift = (e == IMF_ENV_VOL ? 0 : 2); + + env->nodes = CLAMP(imfins->env[e].points, 2, 25); + env->loop_start = imfins->env[e].loop_start; + env->loop_end = imfins->env[e].loop_end; + env->sustain_start = env->sustain_end = imfins->env[e].sustain; + + for (n = 0; n < env->nodes; n++) { + t = bswapLE16(imfins->nodes[e][n].tick); + v = bswapLE16(imfins->nodes[e][n].value) >> shift; + env->ticks[n] = MAX(min, t); + env->values[n] = v = MIN(v, 64); + min = t + 1; + } + // this would be less retarded if the envelopes all had their own flags... + if (imfins->env[e].flags & 1) + ins->flags |= envflags[e][0]; + if (imfins->env[e].flags & 2) + ins->flags |= envflags[e][1]; + if (imfins->env[e].flags & 4) + ins->flags |= envflags[e][2]; } int fmt_imf_load_song(song_t *song, slurp_t *fp, UNUSED unsigned int lflags) { - struct imf_header hdr; - int n, s; - song_sample_t *sample = song->samples + 1; - int firstsample = 1; // first sample for the current instrument - uint32_t ignore_channels = 0; /* bit set for each channel that's completely disabled */ - int lostfx = 0; - - slurp_read(fp, &hdr, sizeof(hdr)); - hdr.ordnum = bswapLE16(hdr.ordnum); - hdr.patnum = bswapLE16(hdr.patnum); - hdr.insnum = bswapLE16(hdr.insnum); - hdr.flags = bswapLE16(hdr.flags); - - if (memcmp(hdr.im10, "IM10", 4) != 0) - return LOAD_UNSUPPORTED; - - if (hdr.ordnum > MAX_ORDERS || hdr.patnum > MAX_PATTERNS || hdr.insnum > MAX_INSTRUMENTS) - return LOAD_FORMAT_ERROR; - - memcpy(song->title, hdr.title, 25); - song->title[25] = 0; - strcpy(song->tracker_id, "Imago Orpheus"); - - if (hdr.flags & 1) - song->flags |= SONG_LINEARSLIDES; - song->flags |= SONG_INSTRUMENTMODE; - song->initial_speed = hdr.tempo; - song->initial_tempo = hdr.bpm; - song->initial_global_volume = 2 * hdr.master; - song->mixing_volume = hdr.amp; - - for (n = 0; n < 32; n++) { - song->channels[n].panning = hdr.channels[n].panning * 64 / 255; - song->channels[n].panning *= 4; //mphack - /* TODO: reverb/chorus??? */ - switch (hdr.channels[n].status) { - case 0: /* enabled; don't worry about it */ - break; - case 1: /* mute */ - song->channels[n].flags |= CHN_MUTE; - break; - case 2: /* disabled */ - song->channels[n].flags |= CHN_MUTE; - ignore_channels |= (1 << n); - break; - default: /* uhhhh.... freak out */ - //fprintf(stderr, "imf: channel %d has unknown status %d\n", n, hdr.channels[n].status); - return LOAD_FORMAT_ERROR; - } - } - for (; n < MAX_CHANNELS; n++) - song->channels[n].flags |= CHN_MUTE; - /* From mikmod: work around an Orpheus bug */ - if (hdr.channels[0].status == 0) { - for (n = 1; n < 16; n++) - if (hdr.channels[n].status != 1) - break; - if (n == 16) - for (n = 1; n < 16; n++) - song->channels[n].flags &= ~CHN_MUTE; - } - - for (n = 0; n < hdr.ordnum; n++) - song->orderlist[n] = ((hdr.orderlist[n] == 0xff) ? ORDER_SKIP : hdr.orderlist[n]); - - for (n = 0; n < hdr.patnum; n++) - lostfx += load_imf_pattern(song, n, ignore_channels, fp); - - if (lostfx) - log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); - - for (n = 0; n < hdr.insnum; n++) { - // read the ins header - struct imf_instrument imfins; - song_instrument_t *ins; - slurp_read(fp, &imfins, sizeof(imfins)); - - imfins.smpnum = bswapLE16(imfins.smpnum); - imfins.fadeout = bswapLE16(imfins.fadeout); - - ins = song->instruments[n + 1] = csf_allocate_instrument(); - strncpy(ins->name, imfins.name, 25); - ins->name[25] = 0; - - if (imfins.smpnum) { - for (s = 0; s < 120; s++) { - ins->note_map[s] = s + 1; - ins->sample_map[s] = firstsample + imfins.map[s]; - } - } - - /* Fadeout: - IT1 - 64 - IT2 - 256 - FT2 - 4095 - IMF - 4095 - MPT - god knows what, all the loaders are inconsistent - Schism - 256 presented; 8192? internal - - IMF and XM have the same range and modplug's XM loader doesn't do any bit shifting with it, - so I'll do the same here for now. I suppose I should get this nonsense straightened - out at some point, though. */ - ins->fadeout = imfins.fadeout; - ins->global_volume = 128; - - load_imf_envelope(ins, &ins->vol_env, &imfins, IMF_ENV_VOL); - load_imf_envelope(ins, &ins->pan_env, &imfins, IMF_ENV_PAN); - load_imf_envelope(ins, &ins->pitch_env, &imfins, IMF_ENV_FILTER); - - /* I'm not sure if XM's envelope hacks apply here or not, but Orpheus *does* at least stop - samples upon note-off when no envelope is active. Whether or not this depends on the fadeout - value, I don't know, and since the fadeout doesn't even seem to be implemented in the gui, - I might never find out. :P */ - if (!(ins->flags & ENV_VOLUME)) { - ins->vol_env.ticks[0] = 0; - ins->vol_env.ticks[1] = 1; - ins->vol_env.values[0] = 64; - ins->vol_env.values[1] = 0; - ins->vol_env.nodes = 2; - ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; - ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; - } - - for (s = 0; s < imfins.smpnum; s++) { - struct imf_sample imfsmp; - uint32_t blen, sflags = SF_LE | SF_M | SF_PCMS; - - slurp_read(fp, &imfsmp, sizeof(imfsmp)); - - if (memcmp(imfsmp.is10, "IS10", 4) != 0) { - //printf("is10 says %02x %02x %02x %02x!\n", - // imfsmp.is10[0], imfsmp.is10[1], imfsmp.is10[2], imfsmp.is10[3]); - return LOAD_FORMAT_ERROR; - } - - strncpy(sample->filename, imfsmp.name, 12); - sample->filename[12] = 0; - strcpy(sample->name, sample->filename); - blen = sample->length = bswapLE32(imfsmp.length); - sample->loop_start = bswapLE32(imfsmp.loop_start); - sample->loop_end = bswapLE32(imfsmp.loop_end); - sample->c5speed = bswapLE32(imfsmp.c5speed); - sample->volume = imfsmp.volume * 4; //mphack - sample->panning = imfsmp.panning; //mphack (IT uses 0-64, IMF uses the full 0-255) - if (imfsmp.flags & 1) - sample->flags |= CHN_LOOP; - if (imfsmp.flags & 2) - sample->flags |= CHN_PINGPONGLOOP; - if (imfsmp.flags & 4) { - sflags |= SF_16; - sample->length >>= 1; - sample->loop_start >>= 1; - sample->loop_end >>= 1; - } else { - sflags |= SF_8; - } - if (imfsmp.flags & 8) - sample->flags |= CHN_PANNING; - - if (blen && !(lflags & LOAD_NOSAMPLES)) - csf_read_sample(sample, sflags, fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, blen, SEEK_CUR); - - sample++; - } - firstsample += imfins.smpnum; - } + struct imf_header hdr; + int n, s; + song_sample_t *sample = song->samples + 1; + int firstsample = 1; // first sample for the current instrument + uint32_t ignore_channels = 0; /* bit set for each channel that's completely disabled */ + int lostfx = 0; + + slurp_read(fp, &hdr, sizeof(hdr)); + hdr.ordnum = bswapLE16(hdr.ordnum); + hdr.patnum = bswapLE16(hdr.patnum); + hdr.insnum = bswapLE16(hdr.insnum); + hdr.flags = bswapLE16(hdr.flags); + + if (memcmp(hdr.im10, "IM10", 4) != 0) + return LOAD_UNSUPPORTED; + + if (hdr.ordnum > MAX_ORDERS || hdr.patnum > MAX_PATTERNS || hdr.insnum > MAX_INSTRUMENTS) + return LOAD_FORMAT_ERROR; + + memcpy(song->title, hdr.title, 25); + song->title[25] = 0; + strcpy(song->tracker_id, "Imago Orpheus"); + + if (hdr.flags & 1) + song->flags |= SONG_LINEARSLIDES; + song->flags |= SONG_INSTRUMENTMODE; + song->initial_speed = hdr.tempo; + song->initial_tempo = hdr.bpm; + song->initial_global_volume = 2 * hdr.master; + song->mixing_volume = hdr.amp; + + for (n = 0; n < 32; n++) { + song->channels[n].panning = hdr.channels[n].panning * 64 / 255; + song->channels[n].panning *= 4; //mphack + /* TODO: reverb/chorus??? */ + switch (hdr.channels[n].status) { + case 0: /* enabled; don't worry about it */ + break; + case 1: /* mute */ + song->channels[n].flags |= CHN_MUTE; + break; + case 2: /* disabled */ + song->channels[n].flags |= CHN_MUTE; + ignore_channels |= (1 << n); + break; + default: /* uhhhh.... freak out */ + //fprintf(stderr, "imf: channel %d has unknown status %d\n", n, hdr.channels[n].status); + return LOAD_FORMAT_ERROR; + } + } + for (; n < MAX_CHANNELS; n++) + song->channels[n].flags |= CHN_MUTE; + /* From mikmod: work around an Orpheus bug */ + if (hdr.channels[0].status == 0) { + for (n = 1; n < 16; n++) + if (hdr.channels[n].status != 1) + break; + if (n == 16) + for (n = 1; n < 16; n++) + song->channels[n].flags &= ~CHN_MUTE; + } + + for (n = 0; n < hdr.ordnum; n++) + song->orderlist[n] = ((hdr.orderlist[n] == 0xff) ? ORDER_SKIP : hdr.orderlist[n]); + + for (n = 0; n < hdr.patnum; n++) + lostfx += load_imf_pattern(song, n, ignore_channels, fp); + + if (lostfx) + log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); + + for (n = 0; n < hdr.insnum; n++) { + // read the ins header + struct imf_instrument imfins; + song_instrument_t *ins; + slurp_read(fp, &imfins, sizeof(imfins)); + + imfins.smpnum = bswapLE16(imfins.smpnum); + imfins.fadeout = bswapLE16(imfins.fadeout); + + ins = song->instruments[n + 1] = csf_allocate_instrument(); + strncpy(ins->name, imfins.name, 25); + ins->name[25] = 0; + + if (imfins.smpnum) { + for (s = 0; s < 120; s++) { + ins->note_map[s] = s + 1; + ins->sample_map[s] = firstsample + imfins.map[s]; + } + } + + /* Fadeout: + IT1 - 64 + IT2 - 256 + FT2 - 4095 + IMF - 4095 + MPT - god knows what, all the loaders are inconsistent + Schism - 256 presented; 8192? internal + + IMF and XM have the same range and modplug's XM loader doesn't do any bit shifting with it, + so I'll do the same here for now. I suppose I should get this nonsense straightened + out at some point, though. */ + ins->fadeout = imfins.fadeout; + ins->global_volume = 128; + + load_imf_envelope(ins, &ins->vol_env, &imfins, IMF_ENV_VOL); + load_imf_envelope(ins, &ins->pan_env, &imfins, IMF_ENV_PAN); + load_imf_envelope(ins, &ins->pitch_env, &imfins, IMF_ENV_FILTER); + + /* I'm not sure if XM's envelope hacks apply here or not, but Orpheus *does* at least stop + samples upon note-off when no envelope is active. Whether or not this depends on the fadeout + value, I don't know, and since the fadeout doesn't even seem to be implemented in the gui, + I might never find out. :P */ + if (!(ins->flags & ENV_VOLUME)) { + ins->vol_env.ticks[0] = 0; + ins->vol_env.ticks[1] = 1; + ins->vol_env.values[0] = 64; + ins->vol_env.values[1] = 0; + ins->vol_env.nodes = 2; + ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; + ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; + } + + for (s = 0; s < imfins.smpnum; s++) { + struct imf_sample imfsmp; + uint32_t blen, sflags = SF_LE | SF_M | SF_PCMS; + + slurp_read(fp, &imfsmp, sizeof(imfsmp)); + + if (memcmp(imfsmp.is10, "IS10", 4) != 0) { + //printf("is10 says %02x %02x %02x %02x!\n", + // imfsmp.is10[0], imfsmp.is10[1], imfsmp.is10[2], imfsmp.is10[3]); + return LOAD_FORMAT_ERROR; + } + + strncpy(sample->filename, imfsmp.name, 12); + sample->filename[12] = 0; + strcpy(sample->name, sample->filename); + blen = sample->length = bswapLE32(imfsmp.length); + sample->loop_start = bswapLE32(imfsmp.loop_start); + sample->loop_end = bswapLE32(imfsmp.loop_end); + sample->c5speed = bswapLE32(imfsmp.c5speed); + sample->volume = imfsmp.volume * 4; //mphack + sample->panning = imfsmp.panning; //mphack (IT uses 0-64, IMF uses the full 0-255) + if (imfsmp.flags & 1) + sample->flags |= CHN_LOOP; + if (imfsmp.flags & 2) + sample->flags |= CHN_PINGPONGLOOP; + if (imfsmp.flags & 4) { + sflags |= SF_16; + sample->length >>= 1; + sample->loop_start >>= 1; + sample->loop_end >>= 1; + } else { + sflags |= SF_8; + } + if (imfsmp.flags & 8) + sample->flags |= CHN_PANNING; + + if (blen && !(lflags & LOAD_NOSAMPLES)) + csf_read_sample(sample, sflags, fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, blen, SEEK_CUR); + + sample++; + } + firstsample += imfins.smpnum; + } + + // Fix the MIDI settings, because IMF files might include Zxx effects + memset(&song->midi_config, 0, sizeof(song->midi_config)); + strcpy(song->midi_config.sfx[0], "F0F000z"); + song->flags |= SONG_EMBEDMIDICFG; - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/it.c schism-20160521/fmt/it.c --- schism-0+20110101/fmt/it.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/it.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -37,24 +37,24 @@ int fmt_it_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - /* "Bart just said I-M-P! He's made of pee!" */ - if (length > 30 && memcmp(data, "IMPM", 4) == 0) { - /* This ought to be more particular; if it's not actually made *with* Impulse Tracker, - it's probably not compressed, irrespective of what the CMWT says. */ - if (data[42] >= 0x14) - file->description = "Compressed Impulse Tracker"; - else - file->description = "Impulse Tracker"; - } else { - return 0; - } - - /*file->extension = str_dup("it");*/ - file->title = calloc(26, sizeof(char)); - memcpy(file->title, data + 4, 25); - file->title[25] = 0; - file->type = TYPE_MODULE_IT; - return 1; + /* "Bart just said I-M-P! He's made of pee!" */ + if (length > 30 && memcmp(data, "IMPM", 4) == 0) { + /* This ought to be more particular; if it's not actually made *with* Impulse Tracker, + it's probably not compressed, irrespective of what the CMWT says. */ + if (data[42] >= 0x14) + file->description = "Compressed Impulse Tracker"; + else + file->description = "Impulse Tracker"; + } else { + return 0; + } + + /*file->extension = str_dup("it");*/ + file->title = calloc(26, sizeof(char)); + memcpy(file->title, data + 4, 25); + file->title[25] = 0; + file->type = TYPE_MODULE_IT; + return 1; } /* --------------------------------------------------------------------- */ @@ -62,70 +62,70 @@ #pragma pack(push, 1) struct it_header { - char impm[4], title[26]; - uint8_t highlight_minor, highlight_major; - uint16_t ordnum, insnum, smpnum, patnum; - uint16_t cwtv, cmwt, flags, special; - uint8_t gv, mv, is, it, sep, pwd; - uint16_t msg_length; - uint32_t msg_offset, reserved; - uint8_t chan_pan[64], chan_vol[64]; + char impm[4], title[26]; + uint8_t highlight_minor, highlight_major; + uint16_t ordnum, insnum, smpnum, patnum; + uint16_t cwtv, cmwt, flags, special; + uint8_t gv, mv, is, it, sep, pwd; + uint16_t msg_length; + uint32_t msg_offset, reserved; + uint8_t chan_pan[64], chan_vol[64]; }; struct it_sample { - char imps[4], filename[13]; - uint8_t gvl, flag, vol; - char name[26]; - uint8_t cvt, dfp; - uint32_t length, loop_start, loop_end, c5speed; - uint32_t susloop_start, susloop_end, sample_pointer; - uint8_t vis, vid, vir, vit; + char imps[4], filename[13]; + uint8_t gvl, flag, vol; + char name[26]; + uint8_t cvt, dfp; + uint32_t length, loop_start, loop_end, c5speed; + uint32_t susloop_start, susloop_end, sample_pointer; + uint8_t vis, vid, vir, vit; }; struct it_envelope { - uint8_t flags, num_nodes, loop_start, loop_end; - uint8_t susloop_start, susloop_end; - struct { - int8_t value; // signed (-32 -> 32 for pan and pitch; 0 -> 64 for vol and filter) - uint16_t tick; - } nodes[25]; - uint8_t padding; + uint8_t flags, num_nodes, loop_start, loop_end; + uint8_t susloop_start, susloop_end; + struct { + int8_t value; // signed (-32 -> 32 for pan and pitch; 0 -> 64 for vol and filter) + uint16_t tick; + } nodes[25]; + uint8_t padding; }; struct it_notetrans { - uint8_t note; - uint8_t sample; + uint8_t note; + uint8_t sample; }; struct it_instrument { - char impi[4], filename[13]; - uint8_t nna, dct, dca; - uint16_t fadeout; - int8_t pps; // signed! - uint8_t ppc, gbv, dfp, rv, rp; - uint16_t trkvers; - uint8_t num_samples, padding; - char name[26]; - uint8_t ifc, ifr, mch, mpr; - uint16_t midibank; - struct it_notetrans notetrans[120]; - struct it_envelope vol_env, pan_env, pitch_env; + char impi[4], filename[13]; + uint8_t nna, dct, dca; + uint16_t fadeout; + int8_t pps; // signed! + uint8_t ppc, gbv, dfp, rv, rp; + uint16_t trkvers; + uint8_t num_samples, padding; + char name[26]; + uint8_t ifc, ifr, mch, mpr; + uint16_t midibank; + struct it_notetrans notetrans[120]; + struct it_envelope vol_env, pan_env, pitch_env; }; struct it_instrument_old { - char impi[4], filename[13]; - uint8_t flg, vls, vle, sls, sle; - uint8_t xx[2]; - uint16_t fadeout; - uint8_t nna, dnc; - uint16_t trkvers; - uint8_t nos; - uint8_t x; - char name[26]; - uint8_t xxxxxx[6]; - struct it_notetrans notetrans[120]; - uint8_t vol_env[200]; - uint8_t node_points[50]; + char impi[4], filename[13]; + uint8_t flg, vls, vle, sls, sle; + uint8_t xx[2]; + uint16_t fadeout; + uint8_t nna, dnc; + uint16_t trkvers; + uint8_t nos; + uint8_t x; + char name[26]; + uint8_t xxxxxx[6]; + struct it_notetrans notetrans[120]; + uint8_t vol_env[200]; + uint8_t node_points[50]; }; #pragma pack(pop) @@ -133,14 +133,14 @@ /* pattern mask variable bits */ enum { - ITNOTE_NOTE = 1, - ITNOTE_SAMPLE = 2, - ITNOTE_VOLUME = 4, - ITNOTE_EFFECT = 8, - ITNOTE_SAME_NOTE = 16, - ITNOTE_SAME_SAMPLE = 32, - ITNOTE_SAME_VOLUME = 64, - ITNOTE_SAME_EFFECT = 128, + ITNOTE_NOTE = 1, + ITNOTE_SAMPLE = 2, + ITNOTE_VOLUME = 4, + ITNOTE_EFFECT = 8, + ITNOTE_SAME_NOTE = 16, + ITNOTE_SAME_SAMPLE = 32, + ITNOTE_SAME_VOLUME = 64, + ITNOTE_SAME_EFFECT = 128, }; static const uint8_t autovib_import[] = {VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM}; @@ -149,609 +149,614 @@ static void it_import_voleffect(song_note_t *note, uint8_t v) { - uint8_t adj; - switch (v) { - case 0 ... 64: adj = 0; note->voleffect = VOLFX_VOLUME; break; - case 128 ... 192: adj = 128; note->voleffect = VOLFX_PANNING; break; - case 65 ... 74: adj = 65; note->voleffect = VOLFX_FINEVOLUP; break; - case 75 ... 84: adj = 75; note->voleffect = VOLFX_FINEVOLDOWN; break; - case 85 ... 94: adj = 85; note->voleffect = VOLFX_VOLSLIDEUP; break; - case 95 ... 104: adj = 95; note->voleffect = VOLFX_VOLSLIDEDOWN; break; - case 105 ... 114: adj = 105; note->voleffect = VOLFX_PORTADOWN; break; - case 115 ... 124: adj = 115; note->voleffect = VOLFX_PORTAUP; break; - case 193 ... 202: adj = 193; note->voleffect = VOLFX_TONEPORTAMENTO; break; - case 203 ... 212: adj = 203; note->voleffect = VOLFX_VIBRATODEPTH; break; - default: return; // weird alien volume - } - note->volparam = v - adj; + uint8_t adj; + switch (v) { + case 0 ... 64: adj = 0; note->voleffect = VOLFX_VOLUME; break; + case 128 ... 192: adj = 128; note->voleffect = VOLFX_PANNING; break; + case 65 ... 74: adj = 65; note->voleffect = VOLFX_FINEVOLUP; break; + case 75 ... 84: adj = 75; note->voleffect = VOLFX_FINEVOLDOWN; break; + case 85 ... 94: adj = 85; note->voleffect = VOLFX_VOLSLIDEUP; break; + case 95 ... 104: adj = 95; note->voleffect = VOLFX_VOLSLIDEDOWN; break; + case 105 ... 114: adj = 105; note->voleffect = VOLFX_PORTADOWN; break; + case 115 ... 124: adj = 115; note->voleffect = VOLFX_PORTAUP; break; + case 193 ... 202: adj = 193; note->voleffect = VOLFX_TONEPORTAMENTO; break; + case 203 ... 212: adj = 203; note->voleffect = VOLFX_VIBRATODEPTH; break; + default: return; // weird alien volume + } + note->volparam = v - adj; } static void load_it_notetrans(song_instrument_t *instrument, struct it_notetrans *notetrans) { - int note, n; - for (n = 0; n < 120; n++) { - note = notetrans[n].note + NOTE_FIRST; - // map invalid notes to themselves - if (!NOTE_IS_NOTE(note)) - note = n + NOTE_FIRST; - instrument->note_map[n] = note; - instrument->sample_map[n] = notetrans[n].sample; - } + int note, n; + for (n = 0; n < 120; n++) { + note = notetrans[n].note + NOTE_FIRST; + // map invalid notes to themselves + if (!NOTE_IS_NOTE(note)) + note = n + NOTE_FIRST; + instrument->note_map[n] = note; + instrument->sample_map[n] = notetrans[n].sample; + } } static void load_it_pattern(song_note_t *note, slurp_t *fp, int rows) { - song_note_t last_note[64]; - int chan, row = 0; - uint8_t last_mask[64] = { 0 }; - uint8_t chanvar, maskvar, c; - - while (row < rows) { - chanvar = slurp_getc(fp); - if (chanvar == 0) { - row++; - note += 64; - continue; - } - chan = (chanvar - 1) & 63; - if (chanvar & 128) { - maskvar = slurp_getc(fp); - last_mask[chan] = maskvar; - } else { - maskvar = last_mask[chan]; - } - if (maskvar & ITNOTE_NOTE) { - c = slurp_getc(fp); - if (c == 255) - c = NOTE_OFF; - else if (c == 254) - c = NOTE_CUT; - // internally IT uses note 253 as its blank value, but loading it as such is probably - // undesirable since old Schism Tracker used this value incorrectly for note fade - //else if (c == 253) - // c = NOTE_NONE; - else if (c > 119) - c = NOTE_FADE; - else - c += NOTE_FIRST; - note[chan].note = c; - last_note[chan].note = note[chan].note; - } - if (maskvar & ITNOTE_SAMPLE) { - note[chan].instrument = slurp_getc(fp); - last_note[chan].instrument = note[chan].instrument; - } - if (maskvar & ITNOTE_VOLUME) { - it_import_voleffect(note + chan, slurp_getc(fp)); - last_note[chan].voleffect = note[chan].voleffect; - last_note[chan].volparam = note[chan].volparam; - } - if (maskvar & ITNOTE_EFFECT) { - note[chan].effect = slurp_getc(fp) & 0x1f; - note[chan].param = slurp_getc(fp); - csf_import_s3m_effect(note + chan, 1); - last_note[chan].effect = note[chan].effect; - last_note[chan].param = note[chan].param; - } - if (maskvar & ITNOTE_SAME_NOTE) - note[chan].note = last_note[chan].note; - if (maskvar & ITNOTE_SAME_SAMPLE) - note[chan].instrument = last_note[chan].instrument; - if (maskvar & ITNOTE_SAME_VOLUME) { - note[chan].voleffect = last_note[chan].voleffect; - note[chan].volparam = last_note[chan].volparam; - } - if (maskvar & ITNOTE_SAME_EFFECT) { - note[chan].effect = last_note[chan].effect; - note[chan].param = last_note[chan].param; - } - } + song_note_t last_note[64]; + int chan, row = 0; + uint8_t last_mask[64] = { 0 }; + uint8_t chanvar, maskvar, c; + + while (row < rows) { + chanvar = slurp_getc(fp); + + if (chanvar == 255 && slurp_eof(fp)) { + /* truncated file? we might want to complain or something ... eh. */ + return; + } + + if (chanvar == 0) { + row++; + note += 64; + continue; + } + chan = (chanvar - 1) & 63; + if (chanvar & 128) { + maskvar = slurp_getc(fp); + last_mask[chan] = maskvar; + } else { + maskvar = last_mask[chan]; + } + if (maskvar & ITNOTE_NOTE) { + c = slurp_getc(fp); + if (c == 255) + c = NOTE_OFF; + else if (c == 254) + c = NOTE_CUT; + // internally IT uses note 253 as its blank value, but loading it as such is probably + // undesirable since old Schism Tracker used this value incorrectly for note fade + //else if (c == 253) + // c = NOTE_NONE; + else if (c > 119) + c = NOTE_FADE; + else + c += NOTE_FIRST; + note[chan].note = c; + last_note[chan].note = note[chan].note; + } + if (maskvar & ITNOTE_SAMPLE) { + note[chan].instrument = slurp_getc(fp); + last_note[chan].instrument = note[chan].instrument; + } + if (maskvar & ITNOTE_VOLUME) { + it_import_voleffect(note + chan, slurp_getc(fp)); + last_note[chan].voleffect = note[chan].voleffect; + last_note[chan].volparam = note[chan].volparam; + } + if (maskvar & ITNOTE_EFFECT) { + note[chan].effect = slurp_getc(fp) & 0x1f; + note[chan].param = slurp_getc(fp); + csf_import_s3m_effect(note + chan, 1); + last_note[chan].effect = note[chan].effect; + last_note[chan].param = note[chan].param; + } + if (maskvar & ITNOTE_SAME_NOTE) + note[chan].note = last_note[chan].note; + if (maskvar & ITNOTE_SAME_SAMPLE) + note[chan].instrument = last_note[chan].instrument; + if (maskvar & ITNOTE_SAME_VOLUME) { + note[chan].voleffect = last_note[chan].voleffect; + note[chan].volparam = last_note[chan].volparam; + } + if (maskvar & ITNOTE_SAME_EFFECT) { + note[chan].effect = last_note[chan].effect; + note[chan].param = last_note[chan].param; + } + } } static void load_it_instrument_old(song_instrument_t *instrument, slurp_t *fp) { - struct it_instrument_old ihdr; - int n; + struct it_instrument_old ihdr; + int n; - slurp_read(fp, &ihdr, sizeof(ihdr)); + slurp_read(fp, &ihdr, sizeof(ihdr)); - memcpy(instrument->name, ihdr.name, 25); - instrument->name[25] = '\0'; - memcpy(instrument->filename, ihdr.filename, 12); - ihdr.filename[12] = '\0'; - - instrument->nna = ihdr.nna % 4; - if (ihdr.dnc) { - // XXX is this right? - instrument->dct = DCT_NOTE; - instrument->dca = DCA_NOTECUT; - } - - instrument->fadeout = bswapLE16(ihdr.fadeout) << 6; - instrument->pitch_pan_separation = 0; - instrument->pitch_pan_center = NOTE_MIDC; - instrument->global_volume = 128; - instrument->panning = 32 * 4; //mphack - - load_it_notetrans(instrument, ihdr.notetrans); - - if (ihdr.flg & 1) - instrument->flags |= ENV_VOLUME; - if (ihdr.flg & 2) - instrument->flags |= ENV_VOLLOOP; - if (ihdr.flg & 4) - instrument->flags |= ENV_VOLSUSTAIN; - - instrument->vol_env.loop_start = ihdr.vls; - instrument->vol_env.loop_end = ihdr.vle; - instrument->vol_env.sustain_start = ihdr.sls; - instrument->vol_env.sustain_end = ihdr.sle; - instrument->vol_env.nodes = 25; - // this seems totally wrong... why isn't this using ihdr.vol_env at all? - // apparently it works, though. - for (n = 0; n < 25; n++) { - int node = ihdr.node_points[2 * n]; - if (node == 0xff) { - instrument->vol_env.nodes = n; - break; - } - instrument->vol_env.ticks[n] = node; - instrument->vol_env.values[n] = ihdr.node_points[2 * n + 1]; - } + memcpy(instrument->name, ihdr.name, 25); + instrument->name[25] = '\0'; + memcpy(instrument->filename, ihdr.filename, 12); + ihdr.filename[12] = '\0'; + + instrument->nna = ihdr.nna % 4; + if (ihdr.dnc) { + // XXX is this right? + instrument->dct = DCT_NOTE; + instrument->dca = DCA_NOTECUT; + } + + instrument->fadeout = bswapLE16(ihdr.fadeout) << 6; + instrument->pitch_pan_separation = 0; + instrument->pitch_pan_center = NOTE_MIDC; + instrument->global_volume = 128; + instrument->panning = 32 * 4; //mphack + + load_it_notetrans(instrument, ihdr.notetrans); + + if (ihdr.flg & 1) + instrument->flags |= ENV_VOLUME; + if (ihdr.flg & 2) + instrument->flags |= ENV_VOLLOOP; + if (ihdr.flg & 4) + instrument->flags |= ENV_VOLSUSTAIN; + + instrument->vol_env.loop_start = ihdr.vls; + instrument->vol_env.loop_end = ihdr.vle; + instrument->vol_env.sustain_start = ihdr.sls; + instrument->vol_env.sustain_end = ihdr.sle; + instrument->vol_env.nodes = 25; + // this seems totally wrong... why isn't this using ihdr.vol_env at all? + // apparently it works, though. + for (n = 0; n < 25; n++) { + int node = ihdr.node_points[2 * n]; + if (node == 0xff) { + instrument->vol_env.nodes = n; + break; + } + instrument->vol_env.ticks[n] = node; + instrument->vol_env.values[n] = ihdr.node_points[2 * n + 1]; + } } static const uint32_t env_flags[3][4] = { - {ENV_VOLUME, ENV_VOLLOOP, ENV_VOLSUSTAIN, ENV_VOLCARRY}, - {ENV_PANNING, ENV_PANLOOP, ENV_PANSUSTAIN, ENV_PANCARRY}, - {ENV_PITCH, ENV_PITCHLOOP, ENV_PITCHSUSTAIN, ENV_PITCHCARRY}, + {ENV_VOLUME, ENV_VOLLOOP, ENV_VOLSUSTAIN, ENV_VOLCARRY}, + {ENV_PANNING, ENV_PANLOOP, ENV_PANSUSTAIN, ENV_PANCARRY}, + {ENV_PITCH, ENV_PITCHLOOP, ENV_PITCHSUSTAIN, ENV_PITCHCARRY}, }; static uint32_t load_it_envelope(song_envelope_t *env, struct it_envelope *itenv, int envtype, int adj) { - uint32_t flags = 0; - int n; + uint32_t flags = 0; + int n; - env->nodes = CLAMP(itenv->num_nodes, 2, 25); - env->loop_start = MIN(itenv->loop_start, env->nodes); - env->loop_end = CLAMP(itenv->loop_end, env->loop_start, env->nodes); - env->sustain_start = MIN(itenv->susloop_start, env->nodes); - env->sustain_end = CLAMP(itenv->susloop_end, env->sustain_start, env->nodes); - - for (n = 0; n < env->nodes; n++) { - int v = itenv->nodes[n].value + adj; - env->values[n] = CLAMP(v, 0, 64); - env->ticks[n] = bswapLE16(itenv->nodes[n].tick); - } - env->ticks[0] = 0; // sanity check - - for (n = 0; n < 4; n++) { - if (itenv->flags & (1 << n)) - flags |= env_flags[envtype][n]; - } - if (envtype == 2 && (itenv->flags & 0x80)) - flags |= ENV_FILTER; - return flags; + env->nodes = CLAMP(itenv->num_nodes, 2, 25); + env->loop_start = MIN(itenv->loop_start, env->nodes); + env->loop_end = CLAMP(itenv->loop_end, env->loop_start, env->nodes); + env->sustain_start = MIN(itenv->susloop_start, env->nodes); + env->sustain_end = CLAMP(itenv->susloop_end, env->sustain_start, env->nodes); + + for (n = 0; n < env->nodes; n++) { + int v = itenv->nodes[n].value + adj; + env->values[n] = CLAMP(v, 0, 64); + env->ticks[n] = bswapLE16(itenv->nodes[n].tick); + } + env->ticks[0] = 0; // sanity check + + for (n = 0; n < 4; n++) { + if (itenv->flags & (1 << n)) + flags |= env_flags[envtype][n]; + } + if (envtype == 2 && (itenv->flags & 0x80)) + flags |= ENV_FILTER; + return flags; } static void load_it_instrument(song_instrument_t *instrument, slurp_t *fp) { - struct it_instrument ihdr; + struct it_instrument ihdr; - slurp_read(fp, &ihdr, sizeof(ihdr)); + slurp_read(fp, &ihdr, sizeof(ihdr)); - memcpy(instrument->name, ihdr.name, 25); - instrument->name[25] = '\0'; - memcpy(instrument->filename, ihdr.filename, 12); - ihdr.filename[12] = '\0'; - - instrument->nna = ihdr.nna % 4; - instrument->dct = ihdr.dct % 4; - instrument->dca = ihdr.dca % 3; - instrument->fadeout = bswapLE16(ihdr.fadeout) << 5; - instrument->pitch_pan_separation = CLAMP(ihdr.pps, -32, 32); - instrument->pitch_pan_center = MIN(ihdr.ppc, 119); // I guess - instrument->global_volume = MIN(ihdr.gbv, 128); - instrument->panning = MIN((ihdr.dfp & 127), 64) * 4; //mphack - if (!(ihdr.dfp & 128)) - instrument->flags |= ENV_SETPANNING; - instrument->vol_swing = MIN(ihdr.rv, 100); - instrument->pan_swing = MIN(ihdr.rp, 64); - - instrument->ifc = ihdr.ifc; - instrument->ifr = ihdr.ifr; - - // (blah... this isn't supposed to be a mask according to the - // spec. where did this code come from? and what is 0x10000?) - instrument->midi_channel_mask = - ((ihdr.mch > 16) - ? (0x10000 + ihdr.mch) - : ((ihdr.mch > 0) - ? (1 << (ihdr.mch - 1)) - : 0)); - instrument->midi_program = ihdr.mpr; - instrument->midi_bank = bswapLE16(ihdr.midibank); - - load_it_notetrans(instrument, ihdr.notetrans); - - instrument->flags |= load_it_envelope(&instrument->vol_env, &ihdr.vol_env, 0, 0); - instrument->flags |= load_it_envelope(&instrument->pan_env, &ihdr.pan_env, 1, 32); - instrument->flags |= load_it_envelope(&instrument->pitch_env, &ihdr.pitch_env, 2, 32); + memcpy(instrument->name, ihdr.name, 25); + instrument->name[25] = '\0'; + memcpy(instrument->filename, ihdr.filename, 12); + ihdr.filename[12] = '\0'; + + instrument->nna = ihdr.nna % 4; + instrument->dct = ihdr.dct % 4; + instrument->dca = ihdr.dca % 3; + instrument->fadeout = bswapLE16(ihdr.fadeout) << 5; + instrument->pitch_pan_separation = CLAMP(ihdr.pps, -32, 32); + instrument->pitch_pan_center = MIN(ihdr.ppc, 119); // I guess + instrument->global_volume = MIN(ihdr.gbv, 128); + instrument->panning = MIN((ihdr.dfp & 127), 64) * 4; //mphack + if (!(ihdr.dfp & 128)) + instrument->flags |= ENV_SETPANNING; + instrument->vol_swing = MIN(ihdr.rv, 100); + instrument->pan_swing = MIN(ihdr.rp, 64); + + instrument->ifc = ihdr.ifc; + instrument->ifr = ihdr.ifr; + + // (blah... this isn't supposed to be a mask according to the + // spec. where did this code come from? and what is 0x10000?) + instrument->midi_channel_mask = + ((ihdr.mch > 16) + ? (0x10000 + ihdr.mch) + : ((ihdr.mch > 0) + ? (1 << (ihdr.mch - 1)) + : 0)); + instrument->midi_program = ihdr.mpr; + instrument->midi_bank = bswapLE16(ihdr.midibank); + + load_it_notetrans(instrument, ihdr.notetrans); + + instrument->flags |= load_it_envelope(&instrument->vol_env, &ihdr.vol_env, 0, 0); + instrument->flags |= load_it_envelope(&instrument->pan_env, &ihdr.pan_env, 1, 32); + instrument->flags |= load_it_envelope(&instrument->pitch_env, &ihdr.pitch_env, 2, 32); } static void load_it_sample(song_sample_t *sample, slurp_t *fp, uint16_t cwtv) { - struct it_sample shdr; + struct it_sample shdr; - slurp_read(fp, &shdr, sizeof(shdr)); + slurp_read(fp, &shdr, sizeof(shdr)); - /* Fun fact: Impulse Tracker doesn't check any of the header data for consistency when loading samples - (or instruments, for that matter). If some other data is stored in place of the IMPS/IMPI, it'll - happily load it anyway -- and in fact, since the song is manipulated in memory in the same format as - on disk, this data is even preserved when the file is saved! */ - - memcpy(sample->name, shdr.name, 25); - sample->name[25] = '\0'; - - memcpy(sample->filename, shdr.filename, 12); - sample->filename[12] = '\0'; - - if (shdr.dfp & 128) { - sample->flags |= CHN_PANNING; - shdr.dfp &= 127; - } - - sample->global_volume = MIN(shdr.gvl, 64); - sample->volume = MIN(shdr.vol, 64) * 4; //mphack - sample->panning = MIN(shdr.dfp, 64) * 4; //mphack - sample->length = bswapLE32(shdr.length); - sample->length = MIN(sample->length, MAX_SAMPLE_LENGTH); - sample->loop_start = bswapLE32(shdr.loop_start); - sample->loop_end = bswapLE32(shdr.loop_end); - sample->c5speed = bswapLE32(shdr.c5speed); - sample->sustain_start = bswapLE32(shdr.susloop_start); - sample->sustain_end = bswapLE32(shdr.susloop_end); - - sample->vib_speed = MIN(shdr.vis, 64); - sample->vib_depth = MIN(shdr.vid, 32); - sample->vib_rate = shdr.vir; - sample->vib_type = autovib_import[shdr.vit % 4]; - - if (shdr.flag & 16) - sample->flags |= CHN_LOOP; - if (shdr.flag & 32) - sample->flags |= CHN_SUSTAINLOOP; - if (shdr.flag & 64) - sample->flags |= CHN_PINGPONGLOOP; - if (shdr.flag & 128) - sample->flags |= CHN_PINGPONGSUSTAIN; - - /* IT sometimes didn't clear the flag after loading a stereo sample. This appears to have - been fixed sometime before IT 2.14, which is fortunate because that's what a lot of other - programs annoyingly identify themselves as. */ - if (cwtv < 0x0214) - shdr.flag &= ~4; - - if (shdr.flag & 1) { - slurp_seek(fp, bswapLE32(shdr.sample_pointer), SEEK_SET); - - uint32_t flags = SF_LE; - if (shdr.flag & 8) { - flags |= SF_M; - flags |= (shdr.cvt & 4) ? SF_IT215 : SF_IT214; - } else { - flags |= (shdr.flag & 4) ? SF_SS : SF_M; - // XXX for some reason I had a note in pm/fmt/it.c saying that I had found some - // .it files with the signed flag set incorrectly and to assume unsigned when - // hdr.cwtv < 0x0202. Why, and for what files? - // Do any other players use the header for deciding sample data signedness? - flags |= (shdr.cvt & 4) ? SF_PCMD : (shdr.cvt & 1) ? SF_PCMS : SF_PCMU; - } - flags |= (shdr.flag & 2) ? SF_16 : SF_8; - csf_read_sample(sample, flags, fp->data + fp->pos, fp->length - fp->pos); - } else { - sample->length = 0; - } + /* Fun fact: Impulse Tracker doesn't check any of the header data for consistency when loading samples + (or instruments, for that matter). If some other data is stored in place of the IMPS/IMPI, it'll + happily load it anyway -- and in fact, since the song is manipulated in memory in the same format as + on disk, this data is even preserved when the file is saved! */ + + memcpy(sample->name, shdr.name, 25); + sample->name[25] = '\0'; + + memcpy(sample->filename, shdr.filename, 12); + sample->filename[12] = '\0'; + + if (shdr.dfp & 128) { + sample->flags |= CHN_PANNING; + shdr.dfp &= 127; + } + + sample->global_volume = MIN(shdr.gvl, 64); + sample->volume = MIN(shdr.vol, 64) * 4; //mphack + sample->panning = MIN(shdr.dfp, 64) * 4; //mphack + sample->length = bswapLE32(shdr.length); + sample->length = MIN(sample->length, MAX_SAMPLE_LENGTH); + sample->loop_start = bswapLE32(shdr.loop_start); + sample->loop_end = bswapLE32(shdr.loop_end); + sample->c5speed = bswapLE32(shdr.c5speed); + sample->sustain_start = bswapLE32(shdr.susloop_start); + sample->sustain_end = bswapLE32(shdr.susloop_end); + + sample->vib_speed = MIN(shdr.vis, 64); + sample->vib_depth = MIN(shdr.vid, 32); + sample->vib_rate = shdr.vir; + sample->vib_type = autovib_import[shdr.vit % 4]; + + if (shdr.flag & 16) + sample->flags |= CHN_LOOP; + if (shdr.flag & 32) + sample->flags |= CHN_SUSTAINLOOP; + if (shdr.flag & 64) + sample->flags |= CHN_PINGPONGLOOP; + if (shdr.flag & 128) + sample->flags |= CHN_PINGPONGSUSTAIN; + + /* IT sometimes didn't clear the flag after loading a stereo sample. This appears to have + been fixed sometime before IT 2.14, which is fortunate because that's what a lot of other + programs annoyingly identify themselves as. */ + if (cwtv < 0x0214) + shdr.flag &= ~4; + + if (shdr.flag & 1) { + slurp_seek(fp, bswapLE32(shdr.sample_pointer), SEEK_SET); + + uint32_t flags = SF_LE; + flags |= (shdr.flag & 4) ? SF_SS : SF_M; + if (shdr.flag & 8) { + flags |= (shdr.cvt & 4) ? SF_IT215 : SF_IT214; + } else { + // XXX for some reason I had a note in pm/fmt/it.c saying that I had found some + // .it files with the signed flag set incorrectly and to assume unsigned when + // hdr.cwtv < 0x0202. Why, and for what files? + // Do any other players use the header for deciding sample data signedness? + flags |= (shdr.cvt & 4) ? SF_PCMD : (shdr.cvt & 1) ? SF_PCMS : SF_PCMU; + } + flags |= (shdr.flag & 2) ? SF_16 : SF_8; + csf_read_sample(sample, flags, fp->data + fp->pos, fp->length - fp->pos); + } else { + sample->length = 0; + } } int fmt_it_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - struct it_header hdr; - uint32_t para_smp[MAX_SAMPLES], para_ins[MAX_INSTRUMENTS], para_pat[MAX_PATTERNS], para_min; - int n; - int ignoremidi = 0; - song_channel_t *channel; - song_sample_t *sample; - uint16_t hist = 0; // save history (for IT only) - const char *tid = NULL; - - slurp_read(fp, &hdr, sizeof(hdr)); - - if (memcmp(hdr.impm, "IMPM", 4) != 0) - return LOAD_UNSUPPORTED; - - hdr.ordnum = bswapLE16(hdr.ordnum); - hdr.insnum = bswapLE16(hdr.insnum); - hdr.smpnum = bswapLE16(hdr.smpnum); - hdr.patnum = bswapLE16(hdr.patnum); - hdr.cwtv = bswapLE16(hdr.cwtv); - hdr.cmwt = bswapLE16(hdr.cmwt); - hdr.flags = bswapLE16(hdr.flags); - hdr.special = bswapLE16(hdr.special); - hdr.msg_length = bswapLE16(hdr.msg_length); - hdr.msg_offset = bswapLE32(hdr.msg_offset); - hdr.reserved = bswapLE32(hdr.reserved); - - // Screwy limits? - if (hdr.ordnum > MAX_ORDERS || hdr.insnum > MAX_INSTRUMENTS - || hdr.smpnum > MAX_SAMPLES || hdr.patnum > MAX_PATTERNS) { - return LOAD_FORMAT_ERROR; - } - - memcpy(song->title, hdr.title, 25); - song->title[25] = '\0'; - - if (hdr.cwtv < 0x0214) - ignoremidi = 1; - if (hdr.special & 4) { - /* "reserved" bit, experimentally determined to indicate presence of otherwise-documented row - highlight information - introduced in IT 2.13. Formerly checked cwtv here, but that's lame :) - XXX does any tracker save highlight but *not* set this bit? (old Schism versions maybe?) */ - song->row_highlight_minor = hdr.highlight_minor; - song->row_highlight_major = hdr.highlight_major; - } else { - song->row_highlight_minor = 4; - song->row_highlight_major = 16; - } - - if (!(hdr.flags & 1)) - song->flags |= SONG_NOSTEREO; - // (hdr.flags & 2) no longer used (was vol0 optimizations) - if (hdr.flags & 4) - song->flags |= SONG_INSTRUMENTMODE; - if (hdr.flags & 8) - song->flags |= SONG_LINEARSLIDES; - if (hdr.flags & 16) - song->flags |= SONG_ITOLDEFFECTS; - if (hdr.flags & 32) - song->flags |= SONG_COMPATGXX; - if (hdr.flags & 64) { - midi_flags |= MIDI_PITCHBEND; - midi_pitch_depth = hdr.pwd; - } - if ((hdr.flags & 128) && !ignoremidi) - song->flags |= SONG_EMBEDMIDICFG; - else - song->flags &= ~SONG_EMBEDMIDICFG; - - song->initial_global_volume = MIN(hdr.gv, 128); - song->mixing_volume = MIN(hdr.mv, 128); - song->initial_speed = hdr.is ?: 6; - song->initial_tempo = MAX(hdr.it, 31); - song->pan_separation = hdr.sep; - - for (n = 0, channel = song->channels; n < 64; n++, channel++) { - int pan = hdr.chan_pan[n]; - if (pan & 128) { - channel->flags |= CHN_MUTE; - pan &= ~128; - } - if (pan == 100) { - channel->flags |= CHN_SURROUND; - channel->panning = 32; - } else { - channel->panning = MIN(pan, 64); - } - channel->panning *= 4; //mphack - channel->volume = MIN(hdr.chan_vol[n], 64); - } - - slurp_read(fp, song->orderlist, hdr.ordnum); - slurp_read(fp, para_ins, 4 * hdr.insnum); - slurp_read(fp, para_smp, 4 * hdr.smpnum); - slurp_read(fp, para_pat, 4 * hdr.patnum); - - para_min = ((hdr.special & 1) && hdr.msg_length) ? hdr.msg_offset : fp->length; - for (n = 0; n < hdr.insnum; n++) { - para_ins[n] = bswapLE32(para_ins[n]); - if (para_ins[n] < para_min) - para_min = para_ins[n]; - } - for (n = 0; n < hdr.smpnum; n++) { - para_smp[n] = bswapLE32(para_smp[n]); - if (para_smp[n] < para_min) - para_min = para_smp[n]; - } - for (n = 0; n < hdr.patnum; n++) { - para_pat[n] = bswapLE32(para_pat[n]); - if (para_pat[n] && para_pat[n] < para_min) - para_min = para_pat[n]; - } - - if (hdr.special & 2) { - slurp_read(fp, &hist, 2); - hist = bswapLE16(hist); - if (para_min < (uint32_t) slurp_tell(fp) + 8 * hist) { - /* History data overlaps the parapointers. Discard it, it's probably broken. - Some programs, notably older versions of Schism Tracker, set the history flag - but didn't actually write any data, so the "length" we just read is actually - some other data in the file. */ - hist = 0; - } - } else { - // History flag isn't even set. Probably an old version of Impulse Tracker. - hist = 0; - } - if (hist) { - song->histlen = hist; - song->histdata = malloc(8 * song->histlen); - slurp_read(fp, song->histdata, 8 * song->histlen); - } - if (ignoremidi) { - if (hdr.special & 8) { - log_appendf(4, " Warning: ignoring embedded MIDI data (CWTV is too old)"); - slurp_seek(fp, sizeof(midi_config_t), SEEK_CUR); - } - memset(&song->midi_config, 0, sizeof(midi_config_t)); - } else if ((hdr.special & 8) && fp->pos + sizeof(midi_config_t) <= fp->length) { - slurp_read(fp, &song->midi_config, sizeof(midi_config_t)); - } - if (!hist) { - // berotracker check - char modu[4]; - slurp_read(fp, modu, 4); - if (memcmp(modu, "MODU", 4) == 0) { - tid = "BeroTracker"; - } - } - - if ((hdr.special & 1) && hdr.msg_length && hdr.msg_offset + hdr.msg_length < fp->length) { - int len = MIN(MAX_MESSAGE, hdr.msg_length); - slurp_seek(fp, hdr.msg_offset, SEEK_SET); - slurp_read(fp, song->message, len); - song->message[len] = '\0'; - } - - - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 0; n < hdr.insnum; n++) { - song_instrument_t *inst; - - if (!para_ins[n]) - continue; - slurp_seek(fp, para_ins[n], SEEK_SET); - inst = song->instruments[n + 1] = csf_allocate_instrument(); - (hdr.cmwt >= 0x0200 ? load_it_instrument : load_it_instrument_old)(inst, fp); - } - - for (n = 0, sample = song->samples + 1; n < hdr.smpnum; n++, sample++) { - slurp_seek(fp, para_smp[n], SEEK_SET); - load_it_sample(sample, fp, hdr.cwtv); - } - } - - if (!(lflags & LOAD_NOPATTERNS)) { - for (n = 0; n < hdr.patnum; n++) { - uint16_t rows, bytes; - size_t got; - - if (!para_pat[n]) - continue; - slurp_seek(fp, para_pat[n], SEEK_SET); - slurp_read(fp, &bytes, 2); - bytes = bswapLE16(bytes); - slurp_read(fp, &rows, 2); - rows = bswapLE16(rows); - slurp_seek(fp, 4, SEEK_CUR); - song->patterns[n] = csf_allocate_pattern(rows); - song->pattern_size[n] = song->pattern_alloc_size[n] = rows; - load_it_pattern(song->patterns[n], fp, rows); - got = slurp_tell(fp) - para_pat[n] - 8; - if (bytes != got) - log_appendf(4, " Warning: Pattern %d: size mismatch" - " (expected %d bytes, got %lu)", - n, bytes, (unsigned long) got); - } - } - - - // XXX 32 CHARACTER MAX XXX - - if (tid) { - // BeroTracker (detected above) - } else if ((hdr.cwtv >> 12) == 1) { - tid = NULL; - strcpy(song->tracker_id, "Schism Tracker "); - ver_decode_cwtv(hdr.cwtv, song->tracker_id + strlen(song->tracker_id)); - } else if ((hdr.cwtv >> 12) == 0 && hist != 0 && hdr.reserved != 0) { - // early catch to exclude possible false positives without repeating a bunch of stuff. - } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0200 && hdr.flags == 9 && hdr.special == 0 - && hdr.highlight_major == 0 && hdr.highlight_minor == 0 - && hdr.insnum == 0 && hdr.patnum + 1 == hdr.ordnum - && hdr.gv == 128 && hdr.mv == 100 && hdr.is == 1 && hdr.sep == 128 && hdr.pwd == 0 - && hdr.msg_length == 0 && hdr.msg_offset == 0 && hdr.reserved == 0) { - // :) - tid = "OpenSPC conversion"; - } else if ((hdr.cwtv >> 12) == 5) { - tid = (hdr.reserved == 0x54504d4f) ? "OpenMPT %d.%02x" : "OpenMPT %d.%02x (compat.)"; - } else if (hdr.cwtv == 0x0888 && hdr.cmwt == 0x0888 && hdr.reserved == 0/* && hdr.ordnum == 256*/) { - // erh. - // There's a way to identify the exact version apparently, but it seems too much trouble - // (ordinarily ordnum == 256, but I have encountered at least one file for which this is NOT - // the case (trackit_r2.it by dsck) and no other trackers I know of use 0x0888) - tid = "OpenMPT 1.17+"; - } else if (hdr.cwtv == 0x0217 && hdr.cmwt == 0x0200 && hdr.reserved == 0) { - int ompt = 0; - if (hdr.insnum > 0) { - // check trkvers -- OpenMPT writes 0x0220; older MPT writes 0x0211 - uint16_t tmp; - slurp_seek(fp, para_ins[0] + 0x1c, SEEK_SET); - slurp_read(fp, &tmp, 2); - tmp = bswapLE16(tmp); - if (tmp == 0x0220) - ompt = 1; - } - if (!ompt && (memchr(hdr.chan_pan, 0xff, 64) == NULL)) { - // MPT 1.16 writes 0xff for unused channels; OpenMPT never does this - // XXX this is a false positive if all 64 channels are actually in use - // -- but then again, who would use 64 channels and not instrument mode? - ompt = 1; - } - tid = (ompt - ? "OpenMPT (compatibility mode)" - : "Modplug Tracker 1.09 - 1.16"); - } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0200 && hdr.reserved == 0) { - // instruments 560 bytes apart - tid = "Modplug Tracker 1.00a5"; - } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0202 && hdr.reserved == 0) { - // instruments 557 bytes apart - tid = "Modplug Tracker b3.3 - 1.07"; - } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0214 && hdr.reserved == 0x49424843) { - // sample data stored directly after header - // all sample/instrument filenames say "-DEPRECATED-" - // 0xa for message newlines instead of 0xd - tid = "ChibiTracker"; - } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0214 && !(hdr.special & 3) && hdr.reserved == 0) { - // sample data stored directly after header - // all sample/instrument filenames say "XXXXXXXX.YYY" - tid = "CheeseTracker?"; - } else if ((hdr.cwtv >> 12) == 0) { - // Catch-all. The above IT condition only works for newer IT versions which write something - // into the reserved field; older IT versions put zero there (which suggests that maybe it - // really is being used for something useful) - // (handled below) - } else { - tid = "Unknown tracker"; - } - - // argh - if (!tid && (hdr.cwtv >> 12) == 0) { - tid = "Impulse Tracker %d.%02x"; - if (hdr.cmwt > 0x0214) { - hdr.cwtv = 0x0215; - } else if (hdr.cwtv > 0x0214) { - // Patched update of IT 2.14 (0x0215 - 0x0217 == p1 - p3) - // p4 (as found on modland) adds the ITVSOUND driver, but doesn't seem to change - // anything as far as file saving is concerned. - tid = NULL; - sprintf(song->tracker_id, "Impulse Tracker 2.14p%d", hdr.cwtv - 0x0214); - } - //"saved %d time%s", hist, (hist == 1) ? "" : "s" - } - if (tid) { - sprintf(song->tracker_id, tid, (hdr.cwtv & 0xf00) >> 8, hdr.cwtv & 0xff); - } + struct it_header hdr; + uint32_t para_smp[MAX_SAMPLES], para_ins[MAX_INSTRUMENTS], para_pat[MAX_PATTERNS], para_min; + int n; + int ignoremidi = 0; + song_channel_t *channel; + song_sample_t *sample; + uint16_t hist = 0; // save history (for IT only) + const char *tid = NULL; + + slurp_read(fp, &hdr, sizeof(hdr)); + + if (memcmp(hdr.impm, "IMPM", 4) != 0) + return LOAD_UNSUPPORTED; + + hdr.ordnum = bswapLE16(hdr.ordnum); + hdr.insnum = bswapLE16(hdr.insnum); + hdr.smpnum = bswapLE16(hdr.smpnum); + hdr.patnum = bswapLE16(hdr.patnum); + hdr.cwtv = bswapLE16(hdr.cwtv); + hdr.cmwt = bswapLE16(hdr.cmwt); + hdr.flags = bswapLE16(hdr.flags); + hdr.special = bswapLE16(hdr.special); + hdr.msg_length = bswapLE16(hdr.msg_length); + hdr.msg_offset = bswapLE32(hdr.msg_offset); + hdr.reserved = bswapLE32(hdr.reserved); + + // Screwy limits? + if (hdr.ordnum > MAX_ORDERS || hdr.insnum > MAX_INSTRUMENTS + || hdr.smpnum > MAX_SAMPLES || hdr.patnum > MAX_PATTERNS) { + return LOAD_FORMAT_ERROR; + } + + memcpy(song->title, hdr.title, 25); + song->title[25] = '\0'; + + if (hdr.cwtv < 0x0214) + ignoremidi = 1; + if (hdr.special & 4) { + /* "reserved" bit, experimentally determined to indicate presence of otherwise-documented row + highlight information - introduced in IT 2.13. Formerly checked cwtv here, but that's lame :) + XXX does any tracker save highlight but *not* set this bit? (old Schism versions maybe?) */ + song->row_highlight_minor = hdr.highlight_minor; + song->row_highlight_major = hdr.highlight_major; + } else { + song->row_highlight_minor = 4; + song->row_highlight_major = 16; + } + + if (!(hdr.flags & 1)) + song->flags |= SONG_NOSTEREO; + // (hdr.flags & 2) no longer used (was vol0 optimizations) + if (hdr.flags & 4) + song->flags |= SONG_INSTRUMENTMODE; + if (hdr.flags & 8) + song->flags |= SONG_LINEARSLIDES; + if (hdr.flags & 16) + song->flags |= SONG_ITOLDEFFECTS; + if (hdr.flags & 32) + song->flags |= SONG_COMPATGXX; + if (hdr.flags & 64) { + midi_flags |= MIDI_PITCHBEND; + midi_pitch_depth = hdr.pwd; + } + if ((hdr.flags & 128) && !ignoremidi) + song->flags |= SONG_EMBEDMIDICFG; + else + song->flags &= ~SONG_EMBEDMIDICFG; + + song->initial_global_volume = MIN(hdr.gv, 128); + song->mixing_volume = MIN(hdr.mv, 128); + song->initial_speed = hdr.is ?: 6; + song->initial_tempo = MAX(hdr.it, 31); + song->pan_separation = hdr.sep; + + for (n = 0, channel = song->channels; n < 64; n++, channel++) { + int pan = hdr.chan_pan[n]; + if (pan & 128) { + channel->flags |= CHN_MUTE; + pan &= ~128; + } + if (pan == 100) { + channel->flags |= CHN_SURROUND; + channel->panning = 32; + } else { + channel->panning = MIN(pan, 64); + } + channel->panning *= 4; //mphack + channel->volume = MIN(hdr.chan_vol[n], 64); + } + + slurp_read(fp, song->orderlist, hdr.ordnum); + slurp_read(fp, para_ins, 4 * hdr.insnum); + slurp_read(fp, para_smp, 4 * hdr.smpnum); + slurp_read(fp, para_pat, 4 * hdr.patnum); + + para_min = ((hdr.special & 1) && hdr.msg_length) ? hdr.msg_offset : fp->length; + for (n = 0; n < hdr.insnum; n++) { + para_ins[n] = bswapLE32(para_ins[n]); + if (para_ins[n] < para_min) + para_min = para_ins[n]; + } + for (n = 0; n < hdr.smpnum; n++) { + para_smp[n] = bswapLE32(para_smp[n]); + if (para_smp[n] < para_min) + para_min = para_smp[n]; + } + for (n = 0; n < hdr.patnum; n++) { + para_pat[n] = bswapLE32(para_pat[n]); + if (para_pat[n] && para_pat[n] < para_min) + para_min = para_pat[n]; + } + + if (hdr.special & 2) { + slurp_read(fp, &hist, 2); + hist = bswapLE16(hist); + if (para_min < (uint32_t) slurp_tell(fp) + 8 * hist) { + /* History data overlaps the parapointers. Discard it, it's probably broken. + Some programs, notably older versions of Schism Tracker, set the history flag + but didn't actually write any data, so the "length" we just read is actually + some other data in the file. */ + hist = 0; + } + } else { + // History flag isn't even set. Probably an old version of Impulse Tracker. + hist = 0; + } + if (hist) { + song->histlen = hist; + song->histdata = malloc(8 * song->histlen); + slurp_read(fp, song->histdata, 8 * song->histlen); + } + if (ignoremidi) { + if (hdr.special & 8) { + log_appendf(4, " Warning: ignoring embedded MIDI data (CWTV is too old)"); + slurp_seek(fp, sizeof(midi_config_t), SEEK_CUR); + } + memset(&song->midi_config, 0, sizeof(midi_config_t)); + } else if ((hdr.special & 8) && fp->pos + sizeof(midi_config_t) <= fp->length) { + slurp_read(fp, &song->midi_config, sizeof(midi_config_t)); + } + if (!hist) { + // berotracker check + char modu[4]; + slurp_read(fp, modu, 4); + if (memcmp(modu, "MODU", 4) == 0) { + tid = "BeroTracker"; + } + } + + if ((hdr.special & 1) && hdr.msg_length && hdr.msg_offset + hdr.msg_length < fp->length) { + int len = MIN(MAX_MESSAGE, hdr.msg_length); + slurp_seek(fp, hdr.msg_offset, SEEK_SET); + slurp_read(fp, song->message, len); + song->message[len] = '\0'; + } + + + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 0; n < hdr.insnum; n++) { + song_instrument_t *inst; + + if (!para_ins[n]) + continue; + slurp_seek(fp, para_ins[n], SEEK_SET); + inst = song->instruments[n + 1] = csf_allocate_instrument(); + (hdr.cmwt >= 0x0200 ? load_it_instrument : load_it_instrument_old)(inst, fp); + } + + for (n = 0, sample = song->samples + 1; n < hdr.smpnum; n++, sample++) { + slurp_seek(fp, para_smp[n], SEEK_SET); + load_it_sample(sample, fp, hdr.cwtv); + } + } + + if (!(lflags & LOAD_NOPATTERNS)) { + for (n = 0; n < hdr.patnum; n++) { + uint16_t rows, bytes; + size_t got; + + if (!para_pat[n]) + continue; + slurp_seek(fp, para_pat[n], SEEK_SET); + slurp_read(fp, &bytes, 2); + bytes = bswapLE16(bytes); + slurp_read(fp, &rows, 2); + rows = bswapLE16(rows); + slurp_seek(fp, 4, SEEK_CUR); + song->patterns[n] = csf_allocate_pattern(rows); + song->pattern_size[n] = song->pattern_alloc_size[n] = rows; + load_it_pattern(song->patterns[n], fp, rows); + got = slurp_tell(fp) - para_pat[n] - 8; + if (bytes != got) + log_appendf(4, " Warning: Pattern %d: size mismatch" + " (expected %d bytes, got %lu)", + n, bytes, (unsigned long) got); + } + } + + + // XXX 32 CHARACTER MAX XXX + + if (tid) { + // BeroTracker (detected above) + } else if ((hdr.cwtv >> 12) == 1) { + tid = NULL; + strcpy(song->tracker_id, "Schism Tracker "); + ver_decode_cwtv(hdr.cwtv, song->tracker_id + strlen(song->tracker_id)); + } else if ((hdr.cwtv >> 12) == 0 && hist != 0 && hdr.reserved != 0) { + // early catch to exclude possible false positives without repeating a bunch of stuff. + } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0200 && hdr.flags == 9 && hdr.special == 0 + && hdr.highlight_major == 0 && hdr.highlight_minor == 0 + && hdr.insnum == 0 && hdr.patnum + 1 == hdr.ordnum + && hdr.gv == 128 && hdr.mv == 100 && hdr.is == 1 && hdr.sep == 128 && hdr.pwd == 0 + && hdr.msg_length == 0 && hdr.msg_offset == 0 && hdr.reserved == 0) { + // :) + tid = "OpenSPC conversion"; + } else if ((hdr.cwtv >> 12) == 5) { + tid = (hdr.reserved == 0x54504d4f) ? "OpenMPT %d.%02x" : "OpenMPT %d.%02x (compat.)"; + } else if (hdr.cwtv == 0x0888 && hdr.cmwt == 0x0888 && hdr.reserved == 0/* && hdr.ordnum == 256*/) { + // erh. + // There's a way to identify the exact version apparently, but it seems too much trouble + // (ordinarily ordnum == 256, but I have encountered at least one file for which this is NOT + // the case (trackit_r2.it by dsck) and no other trackers I know of use 0x0888) + tid = "OpenMPT 1.17+"; + } else if (hdr.cwtv == 0x0217 && hdr.cmwt == 0x0200 && hdr.reserved == 0) { + int ompt = 0; + if (hdr.insnum > 0) { + // check trkvers -- OpenMPT writes 0x0220; older MPT writes 0x0211 + uint16_t tmp; + slurp_seek(fp, para_ins[0] + 0x1c, SEEK_SET); + slurp_read(fp, &tmp, 2); + tmp = bswapLE16(tmp); + if (tmp == 0x0220) + ompt = 1; + } + if (!ompt && (memchr(hdr.chan_pan, 0xff, 64) == NULL)) { + // MPT 1.16 writes 0xff for unused channels; OpenMPT never does this + // XXX this is a false positive if all 64 channels are actually in use + // -- but then again, who would use 64 channels and not instrument mode? + ompt = 1; + } + tid = (ompt + ? "OpenMPT (compatibility mode)" + : "Modplug Tracker 1.09 - 1.16"); + } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0200 && hdr.reserved == 0) { + // instruments 560 bytes apart + tid = "Modplug Tracker 1.00a5"; + } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0202 && hdr.reserved == 0) { + // instruments 557 bytes apart + tid = "Modplug Tracker b3.3 - 1.07"; + } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0214 && hdr.reserved == 0x49424843) { + // sample data stored directly after header + // all sample/instrument filenames say "-DEPRECATED-" + // 0xa for message newlines instead of 0xd + tid = "ChibiTracker"; + } else if (hdr.cwtv == 0x0214 && hdr.cmwt == 0x0214 && !(hdr.special & 3) && hdr.reserved == 0) { + // sample data stored directly after header + // all sample/instrument filenames say "XXXXXXXX.YYY" + tid = "CheeseTracker?"; + } else if ((hdr.cwtv >> 12) == 0) { + // Catch-all. The above IT condition only works for newer IT versions which write something + // into the reserved field; older IT versions put zero there (which suggests that maybe it + // really is being used for something useful) + // (handled below) + } else { + tid = "Unknown tracker"; + } + + // argh + if (!tid && (hdr.cwtv >> 12) == 0) { + tid = "Impulse Tracker %d.%02x"; + if (hdr.cmwt > 0x0214) { + hdr.cwtv = 0x0215; + } else if (hdr.cwtv > 0x0214) { + // Patched update of IT 2.14 (0x0215 - 0x0217 == p1 - p3) + // p4 (as found on modland) adds the ITVSOUND driver, but doesn't seem to change + // anything as far as file saving is concerned. + tid = NULL; + sprintf(song->tracker_id, "Impulse Tracker 2.14p%d", hdr.cwtv - 0x0214); + } + //"saved %d time%s", hist, (hist == 1) ? "" : "s" + } + if (tid) { + sprintf(song->tracker_id, tid, (hdr.cwtv & 0xf00) >> 8, hdr.cwtv & 0xff); + } // if (ferror(fp)) { // return LOAD_FILE_ERROR; // } - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/iti.c schism-20160521/fmt/iti.c --- schism-0+20110101/fmt/iti.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/iti.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -37,113 +37,113 @@ /* --------------------------------------------------------------------- */ int fmt_iti_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; - file->description = "Impulse Tracker Instrument"; - file->title = (char *)calloc(26,sizeof(char *)); - memcpy(file->title, data+32, 25); - file->title[25] = 0; - file->type = TYPE_INST_ITI; + if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; + file->description = "Impulse Tracker Instrument"; + file->title = (char *)calloc(26,sizeof(char *)); + memcpy(file->title, data+32, 25); + file->title[25] = 0; + file->type = TYPE_INST_ITI; - return 1; + return 1; } int fmt_iti_load_instrument(const uint8_t *data, size_t length, int slot) { - struct it_instrument iti; - struct instrumentloader ii; - song_instrument_t *ins; - song_sample_t *smp; - int j; - - if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; - - memcpy(&iti, data, sizeof(iti)); - - ins = instrument_loader_init(&ii, slot); - strncpy(ins->filename, (char *)iti.filename, 12); - ins->filename[12] = 0; - - ins->nna = iti.nna; - ins->dct = iti.dct; - ins->dca = iti.dca; - ins->fadeout = (bswapLE16(iti.fadeout) << 5); - ins->pitch_pan_separation = iti.pps; - ins->pitch_pan_center = iti.ppc; - ins->global_volume = iti.gbv; - ins->panning = (iti.dfp & 0x7F) << 2; - if (ins->panning > 256) ins->panning = 128; - ins->flags = 0; - if (iti.dfp & 0x80) ins->flags = ENV_SETPANNING; - ins->vol_swing = iti.rv; - ins->pan_swing = iti.rp; - - strncpy(ins->name, (char *)iti.name, 25); - ins->name[25] = 0; - ins->ifc = iti.ifc; - ins->ifr = iti.ifr; - ins->midi_channel_mask = iti.mch > 16 ? (0x10000 + iti.mch) - : iti.mch == 0 ? (0) - : (1 << (iti.mch-1)); - ins->midi_program = iti.mpr; - ins->midi_bank = bswapLE16(iti.mbank); - - for (j = 0; j < 120; j++) { - ins->sample_map[j] = instrument_loader_sample(&ii, iti.keyboard[2*j + 1]); - ins->note_map[j] = iti.keyboard[2 * j]+1; - } - if (iti.volenv.flags & 1) ins->flags |= ENV_VOLUME; - if (iti.volenv.flags & 2) ins->flags |= ENV_VOLLOOP; - if (iti.volenv.flags & 4) ins->flags |= ENV_VOLSUSTAIN; - if (iti.volenv.flags & 8) ins->flags |= ENV_VOLCARRY; - ins->vol_env.nodes = iti.volenv.num; - ins->vol_env.loop_start = iti.volenv.lpb; - ins->vol_env.loop_end = iti.volenv.lpe; - ins->vol_env.sustain_start = iti.volenv.slb; - ins->vol_env.sustain_end = iti.volenv.sle; - if (iti.panenv.flags & 1) ins->flags |= ENV_PANNING; - if (iti.panenv.flags & 2) ins->flags |= ENV_PANLOOP; - if (iti.panenv.flags & 4) ins->flags |= ENV_PANSUSTAIN; - if (iti.panenv.flags & 8) ins->flags |= ENV_PANCARRY; - ins->pan_env.nodes = iti.panenv.num; - ins->pan_env.loop_start = iti.panenv.lpb; - ins->pan_env.loop_end = iti.panenv.lpe; - ins->pan_env.sustain_start = iti.panenv.slb; - ins->pan_env.sustain_end = iti.panenv.sle; - if (iti.pitchenv.flags & 1) ins->flags |= ENV_PITCH; - if (iti.pitchenv.flags & 2) ins->flags |= ENV_PITCHLOOP; - if (iti.pitchenv.flags & 4) ins->flags |= ENV_PITCHSUSTAIN; - if (iti.pitchenv.flags & 8) ins->flags |= ENV_PITCHCARRY; - if (iti.pitchenv.flags & 0x80) ins->flags |= ENV_FILTER; - ins->pitch_env.nodes = iti.pitchenv.num; - ins->pitch_env.loop_start = iti.pitchenv.lpb; - ins->pitch_env.loop_end = iti.pitchenv.lpe; - ins->pitch_env.sustain_start = iti.pitchenv.slb; - ins->pitch_env.sustain_end = iti.pitchenv.sle; - - for (j = 0; j < 25; j++) { - ins->vol_env.values[j] = iti.volenv.data[3 * j]; - ins->vol_env.ticks[j] = iti.volenv.data[3 * j + 1] - | (iti.volenv.data[3 * j + 2] << 8); - - ins->pan_env.values[j] = iti.panenv.data[3 * j] + 32; - ins->pan_env.ticks[j] = iti.panenv.data[3 * j + 1] - | (iti.panenv.data[3 * j + 2] << 8); - - ins->pitch_env.values[j] = iti.pitchenv.data[3 * j] + 32; - ins->pitch_env.ticks[j] = iti.pitchenv.data[3 * j + 1] - | (iti.pitchenv.data[3 * j + 2] << 8); - } - - /* okay, on to samples */ - unsigned int pos = 554; - for (j = 0; j < ii.expect_samples; j++) { - smp = song_get_sample(ii.sample_map[j+1]); - if (!smp) break; - if (!load_its_sample(data + pos, data, length, smp)) { - log_appendf(4, "Could not load sample %d from ITI file", j); - return instrument_loader_abort(&ii); - } - pos += 80; /* length of ITS header */ - } - return 1; + struct it_instrument iti; + struct instrumentloader ii; + song_instrument_t *ins; + song_sample_t *smp; + int j; + + if (!(length > 554 && memcmp(data, "IMPI",4) == 0)) return 0; + + memcpy(&iti, data, sizeof(iti)); + + ins = instrument_loader_init(&ii, slot); + strncpy(ins->filename, (char *)iti.filename, 12); + ins->filename[12] = 0; + + ins->nna = iti.nna; + ins->dct = iti.dct; + ins->dca = iti.dca; + ins->fadeout = (bswapLE16(iti.fadeout) << 5); + ins->pitch_pan_separation = iti.pps; + ins->pitch_pan_center = iti.ppc; + ins->global_volume = iti.gbv; + ins->panning = (iti.dfp & 0x7F) << 2; + if (ins->panning > 256) ins->panning = 128; + ins->flags = 0; + if (iti.dfp & 0x80) ins->flags = ENV_SETPANNING; + ins->vol_swing = iti.rv; + ins->pan_swing = iti.rp; + + strncpy(ins->name, (char *)iti.name, 25); + ins->name[25] = 0; + ins->ifc = iti.ifc; + ins->ifr = iti.ifr; + ins->midi_channel_mask = iti.mch > 16 ? (0x10000 + iti.mch) + : iti.mch == 0 ? (0) + : (1 << (iti.mch-1)); + ins->midi_program = iti.mpr; + ins->midi_bank = bswapLE16(iti.mbank); + + for (j = 0; j < 120; j++) { + ins->sample_map[j] = instrument_loader_sample(&ii, iti.keyboard[2*j + 1]); + ins->note_map[j] = iti.keyboard[2 * j]+1; + } + if (iti.volenv.flags & 1) ins->flags |= ENV_VOLUME; + if (iti.volenv.flags & 2) ins->flags |= ENV_VOLLOOP; + if (iti.volenv.flags & 4) ins->flags |= ENV_VOLSUSTAIN; + if (iti.volenv.flags & 8) ins->flags |= ENV_VOLCARRY; + ins->vol_env.nodes = iti.volenv.num; + ins->vol_env.loop_start = iti.volenv.lpb; + ins->vol_env.loop_end = iti.volenv.lpe; + ins->vol_env.sustain_start = iti.volenv.slb; + ins->vol_env.sustain_end = iti.volenv.sle; + if (iti.panenv.flags & 1) ins->flags |= ENV_PANNING; + if (iti.panenv.flags & 2) ins->flags |= ENV_PANLOOP; + if (iti.panenv.flags & 4) ins->flags |= ENV_PANSUSTAIN; + if (iti.panenv.flags & 8) ins->flags |= ENV_PANCARRY; + ins->pan_env.nodes = iti.panenv.num; + ins->pan_env.loop_start = iti.panenv.lpb; + ins->pan_env.loop_end = iti.panenv.lpe; + ins->pan_env.sustain_start = iti.panenv.slb; + ins->pan_env.sustain_end = iti.panenv.sle; + if (iti.pitchenv.flags & 1) ins->flags |= ENV_PITCH; + if (iti.pitchenv.flags & 2) ins->flags |= ENV_PITCHLOOP; + if (iti.pitchenv.flags & 4) ins->flags |= ENV_PITCHSUSTAIN; + if (iti.pitchenv.flags & 8) ins->flags |= ENV_PITCHCARRY; + if (iti.pitchenv.flags & 0x80) ins->flags |= ENV_FILTER; + ins->pitch_env.nodes = iti.pitchenv.num; + ins->pitch_env.loop_start = iti.pitchenv.lpb; + ins->pitch_env.loop_end = iti.pitchenv.lpe; + ins->pitch_env.sustain_start = iti.pitchenv.slb; + ins->pitch_env.sustain_end = iti.pitchenv.sle; + + for (j = 0; j < 25; j++) { + ins->vol_env.values[j] = iti.volenv.data[3 * j]; + ins->vol_env.ticks[j] = iti.volenv.data[3 * j + 1] + | (iti.volenv.data[3 * j + 2] << 8); + + ins->pan_env.values[j] = iti.panenv.data[3 * j] + 32; + ins->pan_env.ticks[j] = iti.panenv.data[3 * j + 1] + | (iti.panenv.data[3 * j + 2] << 8); + + ins->pitch_env.values[j] = iti.pitchenv.data[3 * j] + 32; + ins->pitch_env.ticks[j] = iti.pitchenv.data[3 * j + 1] + | (iti.pitchenv.data[3 * j + 2] << 8); + } + + /* okay, on to samples */ + unsigned int pos = 554; + for (j = 0; j < ii.expect_samples; j++) { + smp = song_get_sample(ii.sample_map[j+1]); + if (!smp) break; + if (!load_its_sample(data + pos, data, length, smp)) { + log_appendf(4, "Could not load sample %d from ITI file", j); + return instrument_loader_abort(&ii); + } + pos += 80; /* length of ITS header */ + } + return 1; } diff -Nru schism-0+20110101/fmt/its.c schism-20160521/fmt/its.c --- schism-0+20110101/fmt/its.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/its.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,212 +32,212 @@ /* --------------------------------------------------------------------- */ int fmt_its_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - struct it_sample *its; + struct it_sample *its; - if (!(length > 80 && memcmp(data, "IMPS", 4) == 0)) - return 0; + if (!(length > 80 && memcmp(data, "IMPS", 4) == 0)) + return 0; - its = (struct it_sample *)data; - file->smp_length = bswapLE32(its->length); - file->smp_flags = 0; - - if (its->flags & 2) { - file->smp_flags |= CHN_16BIT; - } - if (its->flags & 16) { - file->smp_flags |= CHN_LOOP; - if (its->flags & 64) - file->smp_flags |= CHN_PINGPONGLOOP; - } - if (its->flags & 32) { - file->smp_flags |= CHN_SUSTAINLOOP; - if (its->flags & 128) - file->smp_flags |= CHN_PINGPONGSUSTAIN; - } - - if (its->dfp & 128) file->smp_flags |= CHN_PANNING; - if (its->flags & 4) file->smp_flags |= CHN_STEREO; - - file->smp_defvol = its->vol; - file->smp_gblvol = its->gvl; - file->smp_vibrato_speed = its->vis; - file->smp_vibrato_depth = its->vid & 0x7f; - file->smp_vibrato_rate = its->vir; - - file->smp_loop_start = bswapLE32(its->loopbegin); - file->smp_loop_end = bswapLE32(its->loopend); - file->smp_speed = bswapLE32(its->C5Speed); - file->smp_sustain_start = bswapLE32(its->susloopbegin); - file->smp_sustain_end = bswapLE32(its->susloopend); - - file->smp_filename = mem_alloc(13); - memcpy(file->smp_filename, its->filename, 12); - file->smp_filename[12] = 0; - - file->description = "Impulse Tracker Sample"; - file->title = mem_alloc(26); - memcpy(file->title, data + 20, 25); - file->title[25] = 0; - file->type = TYPE_SAMPLE_EXTD; + its = (struct it_sample *)data; + file->smp_length = bswapLE32(its->length); + file->smp_flags = 0; + + if (its->flags & 2) { + file->smp_flags |= CHN_16BIT; + } + if (its->flags & 16) { + file->smp_flags |= CHN_LOOP; + if (its->flags & 64) + file->smp_flags |= CHN_PINGPONGLOOP; + } + if (its->flags & 32) { + file->smp_flags |= CHN_SUSTAINLOOP; + if (its->flags & 128) + file->smp_flags |= CHN_PINGPONGSUSTAIN; + } + + if (its->dfp & 128) file->smp_flags |= CHN_PANNING; + if (its->flags & 4) file->smp_flags |= CHN_STEREO; + + file->smp_defvol = its->vol; + file->smp_gblvol = its->gvl; + file->smp_vibrato_speed = its->vis; + file->smp_vibrato_depth = its->vid & 0x7f; + file->smp_vibrato_rate = its->vir; + + file->smp_loop_start = bswapLE32(its->loopbegin); + file->smp_loop_end = bswapLE32(its->loopend); + file->smp_speed = bswapLE32(its->C5Speed); + file->smp_sustain_start = bswapLE32(its->susloopbegin); + file->smp_sustain_end = bswapLE32(its->susloopend); + + file->smp_filename = mem_alloc(13); + memcpy(file->smp_filename, its->filename, 12); + file->smp_filename[12] = 0; + + file->description = "Impulse Tracker Sample"; + file->title = mem_alloc(26); + memcpy(file->title, data + 20, 25); + file->title[25] = 0; + file->type = TYPE_SAMPLE_EXTD; - return 1; + return 1; } int load_its_sample(const uint8_t *header, const uint8_t *data, size_t length, song_sample_t *smp) { - struct it_sample *its = (struct it_sample *)header; - uint32_t format; - uint32_t bp; - - if (length < 80 || strncmp((const char *) header, "IMPS", 4) != 0) - return 0; - /* alright, let's get started */ - smp->length = bswapLE32(its->length); - if ((its->flags & 1) == 0) { - // sample associated with header - return 0; - } - - // endianness (always little) - format = SF_LE; - if (its->flags & 8) { - // no such thing as compressed stereo - // (TODO perhaps test with various players to see how this is implemented) - format |= SF_M; - // compression algorithm - format |= (its->cvt & 4) ? SF_IT215 : SF_IT214; - } else { - // channels - format |= (its->flags & 4) ? SF_SS : SF_M; - // signedness (or delta?) - format |= (its->cvt & 4) ? SF_PCMD : (its->cvt & 1) ? SF_PCMS : SF_PCMU; - } - // bit width - format |= (its->flags & 2) ? SF_16 : SF_8; - - smp->global_volume = its->gvl; - if (its->flags & 16) { - smp->flags |= CHN_LOOP; - if (its->flags & 64) - smp->flags |= CHN_PINGPONGLOOP; - } - if (its->flags & 32) { - smp->flags |= CHN_SUSTAINLOOP; - if (its->flags & 128) - smp->flags |= CHN_PINGPONGSUSTAIN; - } - smp->volume = its->vol * 4; - strncpy(smp->name, (const char *) its->name, 25); - smp->panning = (its->dfp & 127) * 4; - if (its->dfp & 128) - smp->flags |= CHN_PANNING; - smp->loop_start = bswapLE32(its->loopbegin); - smp->loop_end = bswapLE32(its->loopend); - smp->c5speed = bswapLE32(its->C5Speed); - smp->sustain_start = bswapLE32(its->susloopbegin); - smp->sustain_end = bswapLE32(its->susloopend); - - int vibs[] = {VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM}; - smp->vib_type = vibs[its->vit & 3]; - smp->vib_rate = its->vir; - smp->vib_depth = its->vid; - smp->vib_speed = its->vis; - - // sanity checks - // (I should probably have more of these in general) - if (smp->loop_start > smp->length) { - smp->loop_start = smp->length; - smp->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP); - } - if (smp->loop_end > smp->length) { - smp->loop_end = smp->length; - smp->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP); - } - if (smp->sustain_start > smp->length) { - smp->sustain_start = smp->length; - smp->flags &= ~(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); - } - if (smp->sustain_end > smp->length) { - smp->sustain_end = smp->length; - smp->flags &= ~(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); - } - - bp = bswapLE32(its->samplepointer); - - // dumb casts :P - return csf_read_sample((song_sample_t *) smp, format, - (const char *) (data + bp), - (uint32_t) (length - bp)); + struct it_sample *its = (struct it_sample *)header; + uint32_t format; + uint32_t bp; + + if (length < 80 || strncmp((const char *) header, "IMPS", 4) != 0) + return 0; + /* alright, let's get started */ + smp->length = bswapLE32(its->length); + if ((its->flags & 1) == 0) { + // sample associated with header + return 0; + } + + // endianness (always little) + format = SF_LE; + if (its->flags & 8) { + // no such thing as compressed stereo + // (TODO perhaps test with various players to see how this is implemented) + format |= SF_M; + // compression algorithm + format |= (its->cvt & 4) ? SF_IT215 : SF_IT214; + } else { + // channels + format |= (its->flags & 4) ? SF_SS : SF_M; + // signedness (or delta?) + format |= (its->cvt & 4) ? SF_PCMD : (its->cvt & 1) ? SF_PCMS : SF_PCMU; + } + // bit width + format |= (its->flags & 2) ? SF_16 : SF_8; + + smp->global_volume = its->gvl; + if (its->flags & 16) { + smp->flags |= CHN_LOOP; + if (its->flags & 64) + smp->flags |= CHN_PINGPONGLOOP; + } + if (its->flags & 32) { + smp->flags |= CHN_SUSTAINLOOP; + if (its->flags & 128) + smp->flags |= CHN_PINGPONGSUSTAIN; + } + smp->volume = its->vol * 4; + strncpy(smp->name, (const char *) its->name, 25); + smp->panning = (its->dfp & 127) * 4; + if (its->dfp & 128) + smp->flags |= CHN_PANNING; + smp->loop_start = bswapLE32(its->loopbegin); + smp->loop_end = bswapLE32(its->loopend); + smp->c5speed = bswapLE32(its->C5Speed); + smp->sustain_start = bswapLE32(its->susloopbegin); + smp->sustain_end = bswapLE32(its->susloopend); + + int vibs[] = {VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_RANDOM}; + smp->vib_type = vibs[its->vit & 3]; + smp->vib_rate = its->vir; + smp->vib_depth = its->vid; + smp->vib_speed = its->vis; + + // sanity checks + // (I should probably have more of these in general) + if (smp->loop_start > smp->length) { + smp->loop_start = smp->length; + smp->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP); + } + if (smp->loop_end > smp->length) { + smp->loop_end = smp->length; + smp->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP); + } + if (smp->sustain_start > smp->length) { + smp->sustain_start = smp->length; + smp->flags &= ~(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); + } + if (smp->sustain_end > smp->length) { + smp->sustain_end = smp->length; + smp->flags &= ~(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); + } + + bp = bswapLE32(its->samplepointer); + + // dumb casts :P + return csf_read_sample((song_sample_t *) smp, format, + (const char *) (data + bp), + (uint32_t) (length - bp)); } int fmt_its_load_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - return load_its_sample(data, data, length, smp); + return load_its_sample(data, data, length, smp); } void save_its_header(disko_t *fp, song_sample_t *smp) { - struct it_sample its; + struct it_sample its; - memset(&its, 0, sizeof(its)); - its.id = bswapLE32(0x53504D49); // IMPS - strncpy((char *) its.filename, smp->filename, 12); - its.gvl = smp->global_volume; - if (smp->data && smp->length) - its.flags |= 1; - if (smp->flags & CHN_16BIT) - its.flags |= 2; - if (smp->flags & CHN_STEREO) - its.flags |= 4; - if (smp->flags & CHN_LOOP) - its.flags |= 16; - if (smp->flags & CHN_SUSTAINLOOP) - its.flags |= 32; - if (smp->flags & CHN_PINGPONGLOOP) - its.flags |= 64; - if (smp->flags & CHN_PINGPONGSUSTAIN) - its.flags |= 128; - its.vol = smp->volume / 4; - strncpy((char *) its.name, smp->name, 25); - its.name[25] = 0; - its.cvt = 1; // signed samples - its.dfp = smp->panning / 4; - if (smp->flags & CHN_PANNING) - its.dfp |= 0x80; - its.length = bswapLE32(smp->length); - its.loopbegin = bswapLE32(smp->loop_start); - its.loopend = bswapLE32(smp->loop_end); - its.C5Speed = bswapLE32(smp->c5speed); - its.susloopbegin = bswapLE32(smp->sustain_start); - its.susloopend = bswapLE32(smp->sustain_end); - //its.samplepointer = 42; - this will be filled in later - its.vis = smp->vib_speed; - its.vir = smp->vib_rate; - its.vid = smp->vib_depth; - switch (smp->vib_type) { - case VIB_RANDOM: its.vit = 3; break; - case VIB_SQUARE: its.vit = 2; break; - case VIB_RAMP_DOWN: its.vit = 1; break; - default: - case VIB_SINE: its.vit = 0; break; - } + memset(&its, 0, sizeof(its)); + its.id = bswapLE32(0x53504D49); // IMPS + strncpy((char *) its.filename, smp->filename, 12); + its.gvl = smp->global_volume; + if (smp->data && smp->length) + its.flags |= 1; + if (smp->flags & CHN_16BIT) + its.flags |= 2; + if (smp->flags & CHN_STEREO) + its.flags |= 4; + if (smp->flags & CHN_LOOP) + its.flags |= 16; + if (smp->flags & CHN_SUSTAINLOOP) + its.flags |= 32; + if (smp->flags & CHN_PINGPONGLOOP) + its.flags |= 64; + if (smp->flags & CHN_PINGPONGSUSTAIN) + its.flags |= 128; + its.vol = smp->volume / 4; + strncpy((char *) its.name, smp->name, 25); + its.name[25] = 0; + its.cvt = 1; // signed samples + its.dfp = smp->panning / 4; + if (smp->flags & CHN_PANNING) + its.dfp |= 0x80; + its.length = bswapLE32(smp->length); + its.loopbegin = bswapLE32(smp->loop_start); + its.loopend = bswapLE32(smp->loop_end); + its.C5Speed = bswapLE32(smp->c5speed); + its.susloopbegin = bswapLE32(smp->sustain_start); + its.susloopend = bswapLE32(smp->sustain_end); + //its.samplepointer = 42; - this will be filled in later + its.vis = smp->vib_speed; + its.vir = smp->vib_rate; + its.vid = smp->vib_depth; + switch (smp->vib_type) { + case VIB_RANDOM: its.vit = 3; break; + case VIB_SQUARE: its.vit = 2; break; + case VIB_RAMP_DOWN: its.vit = 1; break; + default: + case VIB_SINE: its.vit = 0; break; + } - disko_write(fp, &its, sizeof(its)); + disko_write(fp, &its, sizeof(its)); } int fmt_its_save_sample(disko_t *fp, song_sample_t *smp) { - save_its_header(fp, smp); - csf_write_sample(fp, smp, SF_LE | SF_PCMS - | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) - | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); - - /* Write the sample pointer. In an ITS file, the sample data is right after the header, - so its position in the file will be the same as the size of the header. */ - unsigned int tmp = bswapLE32(sizeof(struct it_sample)); - disko_seek(fp, 0x48, SEEK_SET); - disko_write(fp, &tmp, 4); + save_its_header(fp, smp); + csf_write_sample(fp, smp, SF_LE | SF_PCMS + | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) + | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); + + /* Write the sample pointer. In an ITS file, the sample data is right after the header, + so its position in the file will be the same as the size of the header. */ + unsigned int tmp = bswapLE32(sizeof(struct it_sample)); + disko_seek(fp, 0x48, SEEK_SET); + disko_write(fp, &tmp, 4); - return SAVE_SUCCESS; + return SAVE_SUCCESS; } diff -Nru schism-0+20110101/fmt/liq.c schism-20160521/fmt/liq.c --- schism-0+20110101/fmt/liq.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/liq.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,20 +28,20 @@ int fmt_liq_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - char buf[32]; + char buf[32]; - if (!(length > 64 && data[64] == 0x1a && memcmp(data, "Liquid Module:", 14) == 0)) - return 0; + if (!(length > 64 && data[64] == 0x1a && memcmp(data, "Liquid Module:", 14) == 0)) + return 0; - file->description = "Liquid Tracker"; - /*file->extension = str_dup("liq");*/ - memcpy(buf, data + 44, 20); - buf[20] = 0; - file->artist = str_dup(buf); - memcpy(buf, data + 14, 30); - buf[30] = 0; - file->title = str_dup(buf); - file->type = TYPE_MODULE_S3M; + file->description = "Liquid Tracker"; + /*file->extension = str_dup("liq");*/ + memcpy(buf, data + 44, 20); + buf[20] = 0; + file->artist = str_dup(buf); + memcpy(buf, data + 14, 30); + buf[30] = 0; + file->title = str_dup(buf); + file->type = TYPE_MODULE_S3M; - return 1; + return 1; } diff -Nru schism-0+20110101/fmt/mdl.c schism-20160521/fmt/mdl.c --- schism-0+20110101/fmt/mdl.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mdl.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,37 +35,37 @@ int fmt_mdl_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - uint32_t position, block_length; - char buf[33]; + uint32_t position, block_length; + char buf[33]; - /* data[4] = major version number (accept 0 or 1) */ - if (!(length > 5 && ((data[4] & 0xf0) >> 4) <= 1 && memcmp(data, "DMDL", 4) == 0)) - return 0; - - position = 5; - while (position + 6 < length) { - memcpy(&block_length, data + position + 2, 4); - block_length = bswapLE32(block_length); - if (block_length + position > length) - return 0; - if (memcmp(data + position, "IN", 2) == 0) { - /* hey! we have a winner */ - memcpy(buf, data + position + 6, 32); - buf[32] = 0; - file->title = str_dup(buf); - memcpy(buf, data + position + 38, 20); - buf[20] = 0; - file->artist = str_dup(buf); - - file->description = "Digitrakker"; - /*file->extension = str_dup("mdl");*/ - file->type = TYPE_MODULE_XM; - return 1; - } /* else... */ - position += 6 + block_length; - } + /* data[4] = major version number (accept 0 or 1) */ + if (!(length > 5 && ((data[4] & 0xf0) >> 4) <= 1 && memcmp(data, "DMDL", 4) == 0)) + return 0; + + position = 5; + while (position + 6 < length) { + memcpy(&block_length, data + position + 2, 4); + block_length = bswapLE32(block_length); + if (block_length + position > length) + return 0; + if (memcmp(data + position, "IN", 2) == 0) { + /* hey! we have a winner */ + memcpy(buf, data + position + 6, 32); + buf[32] = 0; + file->title = str_dup(buf); + memcpy(buf, data + position + 38, 20); + buf[20] = 0; + file->artist = str_dup(buf); + + file->description = "Digitrakker"; + /*file->extension = str_dup("mdl");*/ + file->type = TYPE_MODULE_XM; + return 1; + } /* else... */ + position += 6 + block_length; + } - return 0; + return 0; } /* --------------------------------------------------------------------------------------------------------- */ @@ -87,75 +87,75 @@ #define MDL_FADE_CUT 0xffff enum { - MDLNOTE_NOTE = 1 << 0, - MDLNOTE_SAMPLE = 1 << 1, - MDLNOTE_VOLUME = 1 << 2, - MDLNOTE_EFFECTS = 1 << 3, - MDLNOTE_PARAM1 = 1 << 4, - MDLNOTE_PARAM2 = 1 << 5, + MDLNOTE_NOTE = 1 << 0, + MDLNOTE_SAMPLE = 1 << 1, + MDLNOTE_VOLUME = 1 << 2, + MDLNOTE_EFFECTS = 1 << 3, + MDLNOTE_PARAM1 = 1 << 4, + MDLNOTE_PARAM2 = 1 << 5, }; #pragma pack(push,1) struct mdl_infoblock { - char title[32]; - char composer[20]; - uint16_t numorders; - uint16_t repeatpos; - uint8_t globalvol; - uint8_t speed; - uint8_t tempo; - uint8_t chanpan[32]; + char title[32]; + char composer[20]; + uint16_t numorders; + uint16_t repeatpos; + uint8_t globalvol; + uint8_t speed; + uint8_t tempo; + uint8_t chanpan[32]; }; /* This is actually a part of the instrument (II) block */ struct mdl_samplehdr { - uint8_t smpnum; - uint8_t lastnote; - uint8_t volume; - uint8_t volenv_flags; // 6 bits env #, 2 bits flags - uint8_t panning; - uint8_t panenv_flags; - uint16_t fadeout; - uint8_t vibspeed; - uint8_t vibdepth; - uint8_t vibsweep; - uint8_t vibtype; - uint8_t reserved; // zero - uint8_t freqenv_flags; + uint8_t smpnum; + uint8_t lastnote; + uint8_t volume; + uint8_t volenv_flags; // 6 bits env #, 2 bits flags + uint8_t panning; + uint8_t panenv_flags; + uint16_t fadeout; + uint8_t vibspeed; + uint8_t vibdepth; + uint8_t vibsweep; + uint8_t vibtype; + uint8_t reserved; // zero + uint8_t freqenv_flags; }; struct mdl_sampleinfo { - uint8_t smpnum; - char name[32]; - char filename[8]; - uint32_t c4speed; // c4, c5, whatever - uint32_t length; - uint32_t loopstart; - uint32_t looplen; - uint8_t unused; // was volume in v0.0, why it was changed I have no idea - uint8_t flags; + uint8_t smpnum; + char name[32]; + char filename[8]; + uint32_t c4speed; // c4, c5, whatever + uint32_t length; + uint32_t loopstart; + uint32_t looplen; + uint8_t unused; // was volume in v0.0, why it was changed I have no idea + uint8_t flags; }; struct mdl_sampleinfo_v0 { - uint8_t smpnum; - char name[32]; - char filename[8]; - uint16_t c4speed; - uint32_t length; - uint32_t loopstart; - uint32_t looplen; - uint8_t volume; - uint8_t flags; + uint8_t smpnum; + char name[32]; + char filename[8]; + uint16_t c4speed; + uint32_t length; + uint32_t loopstart; + uint32_t looplen; + uint8_t volume; + uint8_t flags; }; struct mdl_envelope { - uint8_t envnum; - struct { - uint8_t x; // delta-value from last point, 0 means no more points defined - uint8_t y; // 0-63 - } nodes[15]; - uint8_t flags; - uint8_t loop; // lower 4 bits = start, upper 4 bits = end + uint8_t envnum; + struct { + uint8_t x; // delta-value from last point, 0 means no more points defined + uint8_t y; // 0-63 + } nodes[15]; + uint8_t flags; + uint8_t loop; // lower 4 bits = start, upper 4 bits = end }; #pragma pack(pop) @@ -163,56 +163,56 @@ /* Internal definitions */ struct mdlpat { - int track; // which track to put here - int rows; // 1-256 - song_note_t *note; // first note -- add 64 for next note, etc. - struct mdlpat *next; + int track; // which track to put here + int rows; // 1-256 + song_note_t *note; // first note -- add 64 for next note, etc. + struct mdlpat *next; }; struct mdlenv { - uint32_t flags; - song_envelope_t data; + uint32_t flags; + song_envelope_t data; }; enum { - MDL_HAS_INFO = 1 << 0, - MDL_HAS_MESSAGE = 1 << 1, - MDL_HAS_PATTERNS = 1 << 2, - MDL_HAS_TRACKS = 1 << 3, - MDL_HAS_INSTRUMENTS = 1 << 4, - MDL_HAS_VOLENVS = 1 << 5, - MDL_HAS_PANENVS = 1 << 6, - MDL_HAS_FREQENVS = 1 << 7, - MDL_HAS_SAMPLEINFO = 1 << 8, - MDL_HAS_SAMPLEDATA = 1 << 9, + MDL_HAS_INFO = 1 << 0, + MDL_HAS_MESSAGE = 1 << 1, + MDL_HAS_PATTERNS = 1 << 2, + MDL_HAS_TRACKS = 1 << 3, + MDL_HAS_INSTRUMENTS = 1 << 4, + MDL_HAS_VOLENVS = 1 << 5, + MDL_HAS_PANENVS = 1 << 6, + MDL_HAS_FREQENVS = 1 << 7, + MDL_HAS_SAMPLEINFO = 1 << 8, + MDL_HAS_SAMPLEDATA = 1 << 9, }; static const uint8_t mdl_efftrans[] = { - /* 0 */ FX_NONE, - /* 1st column only */ - /* 1 */ FX_PORTAMENTOUP, - /* 2 */ FX_PORTAMENTODOWN, - /* 3 */ FX_TONEPORTAMENTO, - /* 4 */ FX_VIBRATO, - /* 5 */ FX_ARPEGGIO, - /* 6 */ FX_NONE, - /* Either column */ - /* 7 */ FX_TEMPO, - /* 8 */ FX_PANNING, - /* 9 */ FX_SETENVPOSITION, - /* A */ FX_NONE, - /* B */ FX_POSITIONJUMP, - /* C */ FX_GLOBALVOLUME, - /* D */ FX_PATTERNBREAK, - /* E */ FX_SPECIAL, - /* F */ FX_SPEED, - /* 2nd column only */ - /* G */ FX_VOLUMESLIDE, // up - /* H */ FX_VOLUMESLIDE, // down - /* I */ FX_RETRIG, - /* J */ FX_TREMOLO, - /* K */ FX_TREMOR, - /* L */ FX_NONE, + /* 0 */ FX_NONE, + /* 1st column only */ + /* 1 */ FX_PORTAMENTOUP, + /* 2 */ FX_PORTAMENTODOWN, + /* 3 */ FX_TONEPORTAMENTO, + /* 4 */ FX_VIBRATO, + /* 5 */ FX_ARPEGGIO, + /* 6 */ FX_NONE, + /* Either column */ + /* 7 */ FX_TEMPO, + /* 8 */ FX_PANNING, + /* 9 */ FX_SETENVPOSITION, + /* A */ FX_NONE, + /* B */ FX_POSITIONJUMP, + /* C */ FX_GLOBALVOLUME, + /* D */ FX_PATTERNBREAK, + /* E */ FX_SPECIAL, + /* F */ FX_SPEED, + /* 2nd column only */ + /* G */ FX_VOLUMESLIDE, // up + /* H */ FX_VOLUMESLIDE, // down + /* I */ FX_RETRIG, + /* J */ FX_TREMOLO, + /* K */ FX_TREMOR, + /* L */ FX_NONE, }; static const uint8_t autovib_import[] = {VIB_SINE, VIB_RAMP_DOWN, VIB_SQUARE, VIB_SINE}; @@ -223,206 +223,206 @@ // receive an MDL effect, give back a 'normal' one. static void translate_fx(uint8_t *pe, uint8_t *pp) { - uint8_t e = *pe; - uint8_t p = *pp; + uint8_t e = *pe; + uint8_t p = *pp; - if (e > 21) - e = 0; // (shouldn't ever happen) - *pe = mdl_efftrans[e]; - - switch (e) { - case 7: // tempo - // MDL supports any nonzero tempo value, but we don't - p = MAX(p, 0x20); - break; - case 8: // panning - p = MIN(p << 1, 0xff); - break; - case 0xd: // pattern break - // convert from stupid decimal-hex - p = 10 * (p >> 4) + (p & 0xf); - break; - case 0xe: // special - switch (p >> 4) { - case 0: // unused - case 3: // unused - case 5: // set finetune - case 8: // set samplestatus (what?) - *pe = FX_NONE; - break; - case 1: // pan slide left - *pe = FX_PANNINGSLIDE; - p = (MAX(p & 0xf, 0xe) << 4) | 0xf; - break; - case 2: // pan slide right - *pe = FX_PANNINGSLIDE; - p = 0xf0 | MAX(p & 0xf, 0xe); - break; - case 4: // vibrato waveform - p = 0x30 | (p & 0xf); - break; - case 6: // pattern loop - p = 0xb0 | (p & 0xf); - break; - case 7: // tremolo waveform - p = 0x40 | (p & 0xf); - break; - case 9: // retrig - *pe = FX_RETRIG; - p &= 0xf; - break; - case 0xa: // global vol slide up - *pe = FX_GLOBALVOLSLIDE; - p = 0xf0 & (((p & 0xf) + 1) << 3); - break; - case 0xb: // global vol slide down - *pe = FX_GLOBALVOLSLIDE; - p = ((p & 0xf) + 1) >> 1; - break; - case 0xc: // note cut - case 0xd: // note delay - case 0xe: // pattern delay - // nothing to change here - break; - case 0xf: // offset -- further mangled later. - *pe = FX_OFFSET; - break; - } - break; - case 0x10: // volslide up - switch (p >> 4) { - case 0: // G0y -> Dy0 - p <<= 4; - break; - case 0xf: // GFy -> DyF - p = (p << 4) | 0xf; - break; - case 0xe: // GEy -> DzF (z=(y>>2))? - p = (p << 2) | 0xf; - break; - default: // some large slide up -- best we can do is DF0 - p = 0xf0; - break; - } - break; - case 0x11: // volslide down - switch (p >> 4) { - case 0: // H0y -> D0y - case 0xf: // HFy -> DFy - break; - case 0xe: // HEy -> DFz (z=(y>>2))? - p = 0xf0 | ((p & 0xf) >> 2); - break; - default: // some huge slide down - p = 0xf; - break; - } - break; - } + if (e > 21) + e = 0; // (shouldn't ever happen) + *pe = mdl_efftrans[e]; + + switch (e) { + case 7: // tempo + // MDL supports any nonzero tempo value, but we don't + p = MAX(p, 0x20); + break; + case 8: // panning + p = MIN(p << 1, 0xff); + break; + case 0xd: // pattern break + // convert from stupid decimal-hex + p = 10 * (p >> 4) + (p & 0xf); + break; + case 0xe: // special + switch (p >> 4) { + case 0: // unused + case 3: // unused + case 5: // set finetune + case 8: // set samplestatus (what?) + *pe = FX_NONE; + break; + case 1: // pan slide left + *pe = FX_PANNINGSLIDE; + p = (MAX(p & 0xf, 0xe) << 4) | 0xf; + break; + case 2: // pan slide right + *pe = FX_PANNINGSLIDE; + p = 0xf0 | MAX(p & 0xf, 0xe); + break; + case 4: // vibrato waveform + p = 0x30 | (p & 0xf); + break; + case 6: // pattern loop + p = 0xb0 | (p & 0xf); + break; + case 7: // tremolo waveform + p = 0x40 | (p & 0xf); + break; + case 9: // retrig + *pe = FX_RETRIG; + p &= 0xf; + break; + case 0xa: // global vol slide up + *pe = FX_GLOBALVOLSLIDE; + p = 0xf0 & (((p & 0xf) + 1) << 3); + break; + case 0xb: // global vol slide down + *pe = FX_GLOBALVOLSLIDE; + p = ((p & 0xf) + 1) >> 1; + break; + case 0xc: // note cut + case 0xd: // note delay + case 0xe: // pattern delay + // nothing to change here + break; + case 0xf: // offset -- further mangled later. + *pe = FX_OFFSET; + break; + } + break; + case 0x10: // volslide up + switch (p >> 4) { + case 0: // G0y -> Dy0 + p <<= 4; + break; + case 0xf: // GFy -> DyF + p = (p << 4) | 0xf; + break; + case 0xe: // GEy -> DzF (z=(y>>2))? + p = (p << 2) | 0xf; + break; + default: // some large slide up -- best we can do is DF0 + p = 0xf0; + break; + } + break; + case 0x11: // volslide down + switch (p >> 4) { + case 0: // H0y -> D0y + case 0xf: // HFy -> DFy + break; + case 0xe: // HEy -> DFz (z=(y>>2))? + p = 0xf0 | ((p & 0xf) >> 2); + break; + default: // some huge slide down + p = 0xf; + break; + } + break; + } - *pp = p; + *pp = p; } // return: 1 if an effect was lost, 0 if not. static int cram_mdl_effects(song_note_t *note, uint8_t vol, uint8_t e1, uint8_t e2, uint8_t p1, uint8_t p2) { - int lostfx = 0; - int n; - uint8_t tmp; - - // map second effect values 1-6 to effects G-L - if (e2 >= 1 && e2 <= 6) - e2 += 15; - - translate_fx(&e1, &p1); - translate_fx(&e2, &p2); - /* From the Digitrakker documentation: - * EFx -xx - Set Sample Offset - This is a double-command. It starts the - sample at adress xxx*256. - Example: C-5 01 -- EF1 -23 ->starts sample - 01 at address 12300 (in hex). - Kind of screwy, but I guess it's better than the mess required to do it with IT (which effectively - requires 3 rows in order to set the offset past 0xff00). If we had access to the entire track, we - *might* be able to shove the high offset SAy into surrounding rows, but it wouldn't always be possible, - it'd make the loader a lot uglier, and generally would be more trouble than it'd be worth to implement. - - What's more is, if there's another effect in the second column, it's ALSO processed in addition to the - offset, and the second data byte is shared between the two effects. - And: an offset effect without a note will retrigger the previous note, but I'm not even going to try to - handle that behavior. */ - if (e1 == FX_OFFSET) { - // EFy -xx => offset yxx00 - p1 = (p1 & 0xf) ? 0xff : p2; - if (e2 == FX_OFFSET) - e2 = FX_NONE; - } else if (e2 == FX_OFFSET) { - // --- EFy => offset y0000 (best we can do without doing a ton of extra work is 0xff00) - p2 = (p2 & 0xf) ? 0xff : 0; - } - - if (vol) { - note->voleffect = VOLFX_VOLUME; - note->volparam = (vol + 2) >> 2; - } - - /* If we have Dxx + G00, or Dxx + H00, combine them into Lxx/Kxx. - (Since pitch effects only "fit" in the first effect column, and volume effects only work in the - second column, we don't have to check every combination here.) */ - if (e2 == FX_VOLUMESLIDE && p1 == 0) { - if (e1 == FX_TONEPORTAMENTO) { - e1 = FX_NONE; - e2 = FX_TONEPORTAVOL; - } else if (e1 == FX_VIBRATO) { - e1 = FX_NONE; - e2 = FX_VIBRATOVOL; - } - } - - /* Try to fit the "best" effect into e2. */ - if (e1 == FX_NONE) { - // easy - } else if (e2 == FX_NONE) { - // almost as easy - e2 = e1; - p2 = p1; - e1 = FX_NONE; - } else if (e1 == e2 && e1 != FX_SPECIAL) { - /* Digitrakker processes the effects left-to-right, so if both effects are the same, the - second essentially overrides the first. */ - e1 = FX_NONE; - } else if (!vol) { - // The volume column is free, so try to shove one of them into there. - - // See also xm.c. - // (Just because I'm using the same sort of code twice doesn't make it any less of a hack) - for (n = 0; n < 4; n++) { - if (convert_voleffect(&e1, &p1, n >> 1)) { - note->voleffect = e1; - note->volparam = p1; - e1 = FX_NONE; - break; - } else { - // swap them - tmp = e2; e2 = e1; e1 = tmp; - tmp = p2; p2 = p1; p1 = tmp; - } - } - } - - // If we still have two effects, pick the 'best' one - if (e1 != FX_NONE && e2 != FX_NONE) { - lostfx++; - if (effect_weight[e1] < effect_weight[e2]) { - e2 = e1; - p2 = p1; - } - } + int lostfx = 0; + int n; + uint8_t tmp; + + // map second effect values 1-6 to effects G-L + if (e2 >= 1 && e2 <= 6) + e2 += 15; + + translate_fx(&e1, &p1); + translate_fx(&e2, &p2); + /* From the Digitrakker documentation: + * EFx -xx - Set Sample Offset + This is a double-command. It starts the + sample at adress xxx*256. + Example: C-5 01 -- EF1 -23 ->starts sample + 01 at address 12300 (in hex). + Kind of screwy, but I guess it's better than the mess required to do it with IT (which effectively + requires 3 rows in order to set the offset past 0xff00). If we had access to the entire track, we + *might* be able to shove the high offset SAy into surrounding rows, but it wouldn't always be possible, + it'd make the loader a lot uglier, and generally would be more trouble than it'd be worth to implement. + + What's more is, if there's another effect in the second column, it's ALSO processed in addition to the + offset, and the second data byte is shared between the two effects. + And: an offset effect without a note will retrigger the previous note, but I'm not even going to try to + handle that behavior. */ + if (e1 == FX_OFFSET) { + // EFy -xx => offset yxx00 + p1 = (p1 & 0xf) ? 0xff : p2; + if (e2 == FX_OFFSET) + e2 = FX_NONE; + } else if (e2 == FX_OFFSET) { + // --- EFy => offset y0000 (best we can do without doing a ton of extra work is 0xff00) + p2 = (p2 & 0xf) ? 0xff : 0; + } + + if (vol) { + note->voleffect = VOLFX_VOLUME; + note->volparam = (vol + 2) >> 2; + } + + /* If we have Dxx + G00, or Dxx + H00, combine them into Lxx/Kxx. + (Since pitch effects only "fit" in the first effect column, and volume effects only work in the + second column, we don't have to check every combination here.) */ + if (e2 == FX_VOLUMESLIDE && p1 == 0) { + if (e1 == FX_TONEPORTAMENTO) { + e1 = FX_NONE; + e2 = FX_TONEPORTAVOL; + } else if (e1 == FX_VIBRATO) { + e1 = FX_NONE; + e2 = FX_VIBRATOVOL; + } + } + + /* Try to fit the "best" effect into e2. */ + if (e1 == FX_NONE) { + // easy + } else if (e2 == FX_NONE) { + // almost as easy + e2 = e1; + p2 = p1; + e1 = FX_NONE; + } else if (e1 == e2 && e1 != FX_SPECIAL) { + /* Digitrakker processes the effects left-to-right, so if both effects are the same, the + second essentially overrides the first. */ + e1 = FX_NONE; + } else if (!vol) { + // The volume column is free, so try to shove one of them into there. + + // See also xm.c. + // (Just because I'm using the same sort of code twice doesn't make it any less of a hack) + for (n = 0; n < 4; n++) { + if (convert_voleffect(&e1, &p1, n >> 1)) { + note->voleffect = e1; + note->volparam = p1; + e1 = FX_NONE; + break; + } else { + // swap them + tmp = e2; e2 = e1; e1 = tmp; + tmp = p2; p2 = p1; p1 = tmp; + } + } + } + + // If we still have two effects, pick the 'best' one + if (e1 != FX_NONE && e2 != FX_NONE) { + lostfx++; + if (effect_weight[e1] < effect_weight[e2]) { + e2 = e1; + p2 = p1; + } + } - note->effect = e2; - note->param = p2; + note->effect = e2; + note->param = p2; - return lostfx; + return lostfx; } /* --------------------------------------------------------------------------------------------------------- */ @@ -431,199 +431,199 @@ // return: repeat position. static int mdl_read_info(song_t *song, slurp_t *fp) { - struct mdl_infoblock info; - int n, songlen; - uint8_t b; - - slurp_read(fp, &info, sizeof(info)); - info.numorders = bswapLE16(info.numorders); - info.repeatpos = bswapLE16(info.repeatpos); - - // title is space-padded - info.title[31] = '\0'; - trim_string(info.title); - strncpy(song->title, info.title, 25); - song->title[25] = '\0'; - - song->initial_global_volume = (info.globalvol + 1) >> 1; - song->initial_speed = info.speed ?: 1; - song->initial_tempo = MAX(info.tempo, 31); // MDL tempo range is actually 4-255 - - // channel pannings - for (n = 0; n < 32; n++) { - song->channels[n].panning = (info.chanpan[n] & 127) << 1; // ugh - if (info.chanpan[n] & 128) - song->channels[n].flags |= CHN_MUTE; - } - for (; n < 64; n++) { - song->channels[n].panning = 128; - song->channels[n].flags |= CHN_MUTE; - } - - songlen = MIN(info.numorders, MAX_ORDERS - 1); - for (n = 0; n < songlen; n++) { - b = slurp_getc(fp); - song->orderlist[n] = (b < MAX_PATTERNS) ? b : ORDER_SKIP; - } + struct mdl_infoblock info; + int n, songlen; + uint8_t b; + + slurp_read(fp, &info, sizeof(info)); + info.numorders = bswapLE16(info.numorders); + info.repeatpos = bswapLE16(info.repeatpos); + + // title is space-padded + info.title[31] = '\0'; + trim_string(info.title); + strncpy(song->title, info.title, 25); + song->title[25] = '\0'; + + song->initial_global_volume = (info.globalvol + 1) >> 1; + song->initial_speed = info.speed ?: 1; + song->initial_tempo = MAX(info.tempo, 31); // MDL tempo range is actually 4-255 + + // channel pannings + for (n = 0; n < 32; n++) { + song->channels[n].panning = (info.chanpan[n] & 127) << 1; // ugh + if (info.chanpan[n] & 128) + song->channels[n].flags |= CHN_MUTE; + } + for (; n < 64; n++) { + song->channels[n].panning = 128; + song->channels[n].flags |= CHN_MUTE; + } + + songlen = MIN(info.numorders, MAX_ORDERS - 1); + for (n = 0; n < songlen; n++) { + b = slurp_getc(fp); + song->orderlist[n] = (b < MAX_PATTERNS) ? b : ORDER_SKIP; + } - return info.repeatpos; + return info.repeatpos; } static void mdl_read_message(song_t *song, slurp_t *fp, uint32_t blklen) { - char *ptr = song->message; + char *ptr = song->message; - blklen = MIN(blklen, MAX_MESSAGE); - slurp_read(fp, ptr, blklen); - ptr[blklen] = '\0'; + blklen = MIN(blklen, MAX_MESSAGE); + slurp_read(fp, ptr, blklen); + ptr[blklen] = '\0'; - while ((ptr = strchr(ptr, '\r')) != NULL) - *ptr = '\n'; + while ((ptr = strchr(ptr, '\r')) != NULL) + *ptr = '\n'; } static struct mdlpat *mdl_read_patterns(song_t *song, slurp_t *fp) { - struct mdlpat pat_head = { .next = NULL }; // only exists for .next - struct mdlpat *patptr = &pat_head; - song_note_t *note; - int npat, nchn, rows, pat, chn; - uint16_t trknum; - - npat = slurp_getc(fp); - npat = MIN(npat, MAX_PATTERNS); - for (pat = 0; pat < npat; pat++) { - - nchn = slurp_getc(fp); - rows = slurp_getc(fp) + 1; - slurp_seek(fp, 16, SEEK_CUR); // skip the name - - note = song->patterns[pat] = csf_allocate_pattern(rows); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; - for (chn = 0; chn < nchn; chn++, note++) { - slurp_read(fp, &trknum, 2); - trknum = bswapLE16(trknum); - if (!trknum) - continue; - - patptr->next = malloc(sizeof(struct mdlpat)); - patptr = patptr->next; - patptr->track = trknum; - patptr->rows = rows; - patptr->note = note; - patptr->next = NULL; - } - } + struct mdlpat pat_head = { .next = NULL }; // only exists for .next + struct mdlpat *patptr = &pat_head; + song_note_t *note; + int npat, nchn, rows, pat, chn; + uint16_t trknum; + + npat = slurp_getc(fp); + npat = MIN(npat, MAX_PATTERNS); + for (pat = 0; pat < npat; pat++) { + + nchn = slurp_getc(fp); + rows = slurp_getc(fp) + 1; + slurp_seek(fp, 16, SEEK_CUR); // skip the name + + note = song->patterns[pat] = csf_allocate_pattern(rows); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; + for (chn = 0; chn < nchn; chn++, note++) { + slurp_read(fp, &trknum, 2); + trknum = bswapLE16(trknum); + if (!trknum) + continue; + + patptr->next = malloc(sizeof(struct mdlpat)); + patptr = patptr->next; + patptr->track = trknum; + patptr->rows = rows; + patptr->note = note; + patptr->next = NULL; + } + } - return pat_head.next; + return pat_head.next; } // mostly the same as above static struct mdlpat *mdl_read_patterns_v0(song_t *song, slurp_t *fp) { - struct mdlpat pat_head = { .next = NULL }; - struct mdlpat *patptr = &pat_head; - song_note_t *note; - int npat, pat, chn; - uint16_t trknum; - - npat = slurp_getc(fp); - npat = MIN(npat, MAX_PATTERNS); - for (pat = 0; pat < npat; pat++) { - - note = song->patterns[pat] = csf_allocate_pattern(64); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - for (chn = 0; chn < 32; chn++, note++) { - slurp_read(fp, &trknum, 2); - trknum = bswapLE16(trknum); - if (!trknum) - continue; - - patptr->next = malloc(sizeof(struct mdlpat)); - patptr = patptr->next; - patptr->track = trknum; - patptr->rows = 64; - patptr->note = note; - patptr->next = NULL; - } - } + struct mdlpat pat_head = { .next = NULL }; + struct mdlpat *patptr = &pat_head; + song_note_t *note; + int npat, pat, chn; + uint16_t trknum; + + npat = slurp_getc(fp); + npat = MIN(npat, MAX_PATTERNS); + for (pat = 0; pat < npat; pat++) { + + note = song->patterns[pat] = csf_allocate_pattern(64); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + for (chn = 0; chn < 32; chn++, note++) { + slurp_read(fp, &trknum, 2); + trknum = bswapLE16(trknum); + if (!trknum) + continue; + + patptr->next = malloc(sizeof(struct mdlpat)); + patptr = patptr->next; + patptr->track = trknum; + patptr->rows = 64; + patptr->note = note; + patptr->next = NULL; + } + } - return pat_head.next; + return pat_head.next; } static song_note_t **mdl_read_tracks(slurp_t *fp) { - song_note_t **tracks = calloc(65536, sizeof(song_note_t *)); - int ntrks, trk, row, lostfx = 0; - uint16_t h; - uint8_t b, x, y; - uint8_t vol, e1, e2, p1, p2; - size_t bytesleft, reallen = fp->length; - - slurp_read(fp, &h, 2); - ntrks = bswapLE16(h); - - // track 0 is always blank - for (trk = 1; trk <= ntrks; trk++) { - slurp_read(fp, &h, 2); - bytesleft = bswapLE16(h); - fp->length = MIN(fp->length, fp->pos + bytesleft); // narrow - tracks[trk] = calloc(256, sizeof(song_note_t)); - row = 0; - while (row < 256 && !slurp_eof(fp)) { - b = slurp_getc(fp); - x = b >> 2; - y = b & 3; - switch (y) { - case 0: // (x+1) empty notes follow - row += x + 1; - break; - case 1: // Repeat previous note (x+1) times - if (row > 0) { - do { - tracks[trk][row] = tracks[trk][row - 1]; - } while (++row < 256 && x--); - } - break; - case 2: // Copy note from row x - if (row > x) - tracks[trk][row] = tracks[trk][x]; - row++; - break; - case 3: // New note data - if (x & MDLNOTE_NOTE) { - b = slurp_getc(fp); - // convenient! :) - // (I don't know what DT does for out of range notes, might be worth - // checking some time) - tracks[trk][row].note = (b > 120) ? NOTE_OFF : b; - } - if (x & MDLNOTE_SAMPLE) { - b = slurp_getc(fp); - if (b >= MAX_INSTRUMENTS) - b = 0; - tracks[trk][row].instrument = b; - } - vol = (x & MDLNOTE_VOLUME) ? slurp_getc(fp) : 0; - if (x & MDLNOTE_EFFECTS) { - b = slurp_getc(fp); - e1 = b & 0xf; - e2 = b >> 4; - } else { - e1 = e2 = 0; - } - p1 = (x & MDLNOTE_PARAM1) ? slurp_getc(fp) : 0; - p2 = (x & MDLNOTE_PARAM2) ? slurp_getc(fp) : 0; - lostfx += cram_mdl_effects(&tracks[trk][row], vol, e1, e2, p1, p2); - row++; - break; - } - } - fp->length = reallen; // widen - } - if (lostfx) - log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); + song_note_t **tracks = calloc(65536, sizeof(song_note_t *)); + int ntrks, trk, row, lostfx = 0; + uint16_t h; + uint8_t b, x, y; + uint8_t vol, e1, e2, p1, p2; + size_t bytesleft, reallen = fp->length; + + slurp_read(fp, &h, 2); + ntrks = bswapLE16(h); + + // track 0 is always blank + for (trk = 1; trk <= ntrks; trk++) { + slurp_read(fp, &h, 2); + bytesleft = bswapLE16(h); + fp->length = MIN(fp->length, fp->pos + bytesleft); // narrow + tracks[trk] = calloc(256, sizeof(song_note_t)); + row = 0; + while (row < 256 && !slurp_eof(fp)) { + b = slurp_getc(fp); + x = b >> 2; + y = b & 3; + switch (y) { + case 0: // (x+1) empty notes follow + row += x + 1; + break; + case 1: // Repeat previous note (x+1) times + if (row > 0) { + do { + tracks[trk][row] = tracks[trk][row - 1]; + } while (++row < 256 && x--); + } + break; + case 2: // Copy note from row x + if (row > x) + tracks[trk][row] = tracks[trk][x]; + row++; + break; + case 3: // New note data + if (x & MDLNOTE_NOTE) { + b = slurp_getc(fp); + // convenient! :) + // (I don't know what DT does for out of range notes, might be worth + // checking some time) + tracks[trk][row].note = (b > 120) ? NOTE_OFF : b; + } + if (x & MDLNOTE_SAMPLE) { + b = slurp_getc(fp); + if (b >= MAX_INSTRUMENTS) + b = 0; + tracks[trk][row].instrument = b; + } + vol = (x & MDLNOTE_VOLUME) ? slurp_getc(fp) : 0; + if (x & MDLNOTE_EFFECTS) { + b = slurp_getc(fp); + e1 = b & 0xf; + e2 = b >> 4; + } else { + e1 = e2 = 0; + } + p1 = (x & MDLNOTE_PARAM1) ? slurp_getc(fp) : 0; + p2 = (x & MDLNOTE_PARAM2) ? slurp_getc(fp) : 0; + lostfx += cram_mdl_effects(&tracks[trk][row], vol, e1, e2, p1, p2); + row++; + break; + } + } + fp->length = reallen; // widen + } + if (lostfx) + log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); - return tracks; + return tracks; } @@ -639,498 +639,498 @@ won't always line up. */ static void mdl_read_instruments(song_t *song, slurp_t *fp) { - struct mdl_samplehdr shdr; // Etaoin shrdlu - song_instrument_t *ins; // 'master' instrument - song_instrument_t *sins; // other instruments created to track each sample's individual envelopes - song_sample_t *smp; - int nins, nsmp; - int insnum; - int firstnote, note; - - nins = slurp_getc(fp); - while (nins--) { - insnum = slurp_getc(fp); - firstnote = 0; - nsmp = slurp_getc(fp); - // if it's out of range, or if the same instrument was already loaded (weird), don't read it - if (insnum == 0 || insnum > MAX_INSTRUMENTS) { - // skip it (32 bytes name, plus 14 bytes per sample) - slurp_seek(fp, 32 + 14 * nsmp, SEEK_SET); - continue; - } - // ok, make an instrument - if (!song->instruments[insnum]) - song->instruments[insnum] = csf_allocate_instrument(); - ins = song->instruments[insnum]; - - slurp_read(fp, ins->name, 25); - slurp_seek(fp, 7, SEEK_CUR); // throw away the rest - ins->name[25] = '\0'; - - while (nsmp--) { - // read a sample - slurp_read(fp, &shdr, sizeof(shdr)); - shdr.fadeout = bswapLE16(shdr.fadeout); - if (shdr.smpnum == 0 || shdr.smpnum > MAX_SAMPLES) { - continue; - } - if (!song->instruments[shdr.smpnum]) - song->instruments[shdr.smpnum] = csf_allocate_instrument(); - sins = song->instruments[shdr.smpnum]; - - smp = song->samples + shdr.smpnum; - - // Write this sample's instrument mapping - // (note: test "jazz 2 jazz.mdl", it uses a multisampled piano) - shdr.lastnote = MIN(shdr.lastnote, 119); - for (note = firstnote; note <= shdr.lastnote; note++) - ins->sample_map[note] = shdr.smpnum; - firstnote = shdr.lastnote + 1; // get ready for the next sample - - // temporarily hijack the envelope "nodes" field to write the envelope number - sins->vol_env.nodes = shdr.volenv_flags & 63; - sins->pan_env.nodes = shdr.panenv_flags & 63; - sins->pitch_env.nodes = shdr.freqenv_flags & 63; - - if (shdr.volenv_flags & 128) - sins->flags |= ENV_VOLUME; - if (shdr.panenv_flags & 128) - sins->flags |= ENV_PANNING; - if (shdr.freqenv_flags & 128) - sins->flags |= ENV_PITCH; - - // DT fadeout = 0000-1fff, or 0xffff for "cut" - // assuming DT uses 'cut' behavior for anything past 0x1fff, too lazy to bother - // hex-editing a file at the moment to find out :P - sins->fadeout = (shdr.fadeout < 0x2000) - ? (shdr.fadeout + 1) >> 1 // this seems about right - : MDL_FADE_CUT; // temporary - - // for the volume envelope / flags: - // "bit 6 -> flags, if volume is used" - // ... huh? what happens if the volume isn't used? - smp->volume = shdr.volume; //mphack (range 0-255, s/b 0-64) - smp->panning = ((MIN(shdr.panning, 127) + 1) >> 1) * 4; //mphack - if (shdr.panenv_flags & 64) - smp->flags |= CHN_PANNING; - - smp->vib_speed = shdr.vibspeed; // XXX bother checking ranges for vibrato - smp->vib_depth = shdr.vibdepth; - smp->vib_rate = shdr.vibsweep; - smp->vib_type = autovib_import[shdr.vibtype & 3]; - } - } + struct mdl_samplehdr shdr; // Etaoin shrdlu + song_instrument_t *ins; // 'master' instrument + song_instrument_t *sins; // other instruments created to track each sample's individual envelopes + song_sample_t *smp; + int nins, nsmp; + int insnum; + int firstnote, note; + + nins = slurp_getc(fp); + while (nins--) { + insnum = slurp_getc(fp); + firstnote = 0; + nsmp = slurp_getc(fp); + // if it's out of range, or if the same instrument was already loaded (weird), don't read it + if (insnum == 0 || insnum > MAX_INSTRUMENTS) { + // skip it (32 bytes name, plus 14 bytes per sample) + slurp_seek(fp, 32 + 14 * nsmp, SEEK_SET); + continue; + } + // ok, make an instrument + if (!song->instruments[insnum]) + song->instruments[insnum] = csf_allocate_instrument(); + ins = song->instruments[insnum]; + + slurp_read(fp, ins->name, 25); + slurp_seek(fp, 7, SEEK_CUR); // throw away the rest + ins->name[25] = '\0'; + + while (nsmp--) { + // read a sample + slurp_read(fp, &shdr, sizeof(shdr)); + shdr.fadeout = bswapLE16(shdr.fadeout); + if (shdr.smpnum == 0 || shdr.smpnum > MAX_SAMPLES) { + continue; + } + if (!song->instruments[shdr.smpnum]) + song->instruments[shdr.smpnum] = csf_allocate_instrument(); + sins = song->instruments[shdr.smpnum]; + + smp = song->samples + shdr.smpnum; + + // Write this sample's instrument mapping + // (note: test "jazz 2 jazz.mdl", it uses a multisampled piano) + shdr.lastnote = MIN(shdr.lastnote, 119); + for (note = firstnote; note <= shdr.lastnote; note++) + ins->sample_map[note] = shdr.smpnum; + firstnote = shdr.lastnote + 1; // get ready for the next sample + + // temporarily hijack the envelope "nodes" field to write the envelope number + sins->vol_env.nodes = shdr.volenv_flags & 63; + sins->pan_env.nodes = shdr.panenv_flags & 63; + sins->pitch_env.nodes = shdr.freqenv_flags & 63; + + if (shdr.volenv_flags & 128) + sins->flags |= ENV_VOLUME; + if (shdr.panenv_flags & 128) + sins->flags |= ENV_PANNING; + if (shdr.freqenv_flags & 128) + sins->flags |= ENV_PITCH; + + // DT fadeout = 0000-1fff, or 0xffff for "cut" + // assuming DT uses 'cut' behavior for anything past 0x1fff, too lazy to bother + // hex-editing a file at the moment to find out :P + sins->fadeout = (shdr.fadeout < 0x2000) + ? (shdr.fadeout + 1) >> 1 // this seems about right + : MDL_FADE_CUT; // temporary + + // for the volume envelope / flags: + // "bit 6 -> flags, if volume is used" + // ... huh? what happens if the volume isn't used? + smp->volume = shdr.volume; //mphack (range 0-255, s/b 0-64) + smp->panning = ((MIN(shdr.panning, 127) + 1) >> 1) * 4; //mphack + if (shdr.panenv_flags & 64) + smp->flags |= CHN_PANNING; + + smp->vib_speed = shdr.vibspeed; // XXX bother checking ranges for vibrato + smp->vib_depth = shdr.vibdepth; + smp->vib_rate = shdr.vibsweep; + smp->vib_type = autovib_import[shdr.vibtype & 3]; + } + } } static void mdl_read_sampleinfo(song_t *song, slurp_t *fp, uint8_t *packtype) { - struct mdl_sampleinfo sinfo; - song_sample_t *smp; - int nsmp; - - nsmp = slurp_getc(fp); - while (nsmp--) { - slurp_read(fp, &sinfo, sizeof(sinfo)); - if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { - continue; - } - - smp = song->samples + sinfo.smpnum; - strncpy(smp->name, sinfo.name, 25); - smp->name[25] = '\0'; - strncpy(smp->filename, sinfo.filename, 8); - smp->filename[8] = '\0'; - - // MDL has ten octaves like IT, but they're not the *same* ten octaves -- dropping - // perfectly good note data is stupid so I'm adjusting the sample tunings instead - smp->c5speed = bswapLE32(sinfo.c4speed) * 2; - smp->length = bswapLE32(sinfo.length); - smp->loop_start = bswapLE32(sinfo.loopstart); - smp->loop_end = bswapLE32(sinfo.looplen); - if (smp->loop_end) { - smp->loop_end += smp->loop_start; - smp->flags |= CHN_LOOP; - } - if (sinfo.flags & 1) { - smp->flags |= CHN_16BIT; - smp->length >>= 1; - smp->loop_start >>= 1; - smp->loop_end >>= 1; - } - if (sinfo.flags & 2) - smp->flags |= CHN_PINGPONGLOOP; - packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); + struct mdl_sampleinfo sinfo; + song_sample_t *smp; + int nsmp; + + nsmp = slurp_getc(fp); + while (nsmp--) { + slurp_read(fp, &sinfo, sizeof(sinfo)); + if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { + continue; + } + + smp = song->samples + sinfo.smpnum; + strncpy(smp->name, sinfo.name, 25); + smp->name[25] = '\0'; + strncpy(smp->filename, sinfo.filename, 8); + smp->filename[8] = '\0'; + + // MDL has ten octaves like IT, but they're not the *same* ten octaves -- dropping + // perfectly good note data is stupid so I'm adjusting the sample tunings instead + smp->c5speed = bswapLE32(sinfo.c4speed) * 2; + smp->length = bswapLE32(sinfo.length); + smp->loop_start = bswapLE32(sinfo.loopstart); + smp->loop_end = bswapLE32(sinfo.looplen); + if (smp->loop_end) { + smp->loop_end += smp->loop_start; + smp->flags |= CHN_LOOP; + } + if (sinfo.flags & 1) { + smp->flags |= CHN_16BIT; + smp->length >>= 1; + smp->loop_start >>= 1; + smp->loop_end >>= 1; + } + if (sinfo.flags & 2) + smp->flags |= CHN_PINGPONGLOOP; + packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); - smp->global_volume = 64; - } + smp->global_volume = 64; + } } // (ughh) static void mdl_read_sampleinfo_v0(song_t *song, slurp_t *fp, uint8_t *packtype) { - struct mdl_sampleinfo_v0 sinfo; - song_sample_t *smp; - int nsmp; - - nsmp = slurp_getc(fp); - while (nsmp--) { - slurp_read(fp, &sinfo, sizeof(sinfo)); - if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { - continue; - } - - smp = song->samples + sinfo.smpnum; - strncpy(smp->name, sinfo.name, 25); - smp->name[25] = '\0'; - strncpy(smp->filename, sinfo.filename, 8); - smp->filename[8] = '\0'; - - smp->c5speed = bswapLE16(sinfo.c4speed) * 2; - smp->length = bswapLE32(sinfo.length); - smp->loop_start = bswapLE32(sinfo.loopstart); - smp->loop_end = bswapLE32(sinfo.looplen); - smp->volume = sinfo.volume; //mphack (range 0-255, I think?) - if (smp->loop_end) { - smp->loop_end += smp->loop_start; - smp->flags |= CHN_LOOP; - } - if (sinfo.flags & 1) { - smp->flags |= CHN_16BIT; - smp->length >>= 1; - smp->loop_start >>= 1; - smp->loop_end >>= 1; - } - if (sinfo.flags & 2) - smp->flags |= CHN_PINGPONGLOOP; - packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); + struct mdl_sampleinfo_v0 sinfo; + song_sample_t *smp; + int nsmp; + + nsmp = slurp_getc(fp); + while (nsmp--) { + slurp_read(fp, &sinfo, sizeof(sinfo)); + if (sinfo.smpnum == 0 || sinfo.smpnum > MAX_SAMPLES) { + continue; + } + + smp = song->samples + sinfo.smpnum; + strncpy(smp->name, sinfo.name, 25); + smp->name[25] = '\0'; + strncpy(smp->filename, sinfo.filename, 8); + smp->filename[8] = '\0'; + + smp->c5speed = bswapLE16(sinfo.c4speed) * 2; + smp->length = bswapLE32(sinfo.length); + smp->loop_start = bswapLE32(sinfo.loopstart); + smp->loop_end = bswapLE32(sinfo.looplen); + smp->volume = sinfo.volume; //mphack (range 0-255, I think?) + if (smp->loop_end) { + smp->loop_end += smp->loop_start; + smp->flags |= CHN_LOOP; + } + if (sinfo.flags & 1) { + smp->flags |= CHN_16BIT; + smp->length >>= 1; + smp->loop_start >>= 1; + smp->loop_end >>= 1; + } + if (sinfo.flags & 2) + smp->flags |= CHN_PINGPONGLOOP; + packtype[sinfo.smpnum] = ((sinfo.flags >> 2) & 3); - smp->global_volume = 64; - } + smp->global_volume = 64; + } } static void mdl_read_envelopes(slurp_t *fp, struct mdlenv **envs, uint32_t flags) { - struct mdl_envelope ehdr; - song_envelope_t *env; - uint8_t nenv; - int n, tick; - - nenv = slurp_getc(fp); - while (nenv--) { - slurp_read(fp, &ehdr, sizeof(ehdr)); - if (ehdr.envnum > 63) - continue; - - if (!envs[ehdr.envnum]) - envs[ehdr.envnum] = calloc(1, sizeof(struct mdlenv)); - env = &envs[ehdr.envnum]->data; - - env->nodes = 15; - tick = -ehdr.nodes[0].x; // adjust so it starts at zero - for (n = 0; n < 15; n++) { - if (!ehdr.nodes[n].x) { - env->nodes = MAX(n, 2); - break; - } - tick += ehdr.nodes[n].x; - env->ticks[n] = tick; - env->values[n] = MIN(ehdr.nodes[n].y, 64); // actually 0-63 - } - - env->loop_start = ehdr.loop & 0xf; - env->loop_end = ehdr.loop >> 4; - env->sustain_start = env->sustain_end = ehdr.flags & 0xf; - - envs[ehdr.envnum]->flags = 0; - if (ehdr.flags & 16) - envs[ehdr.envnum]->flags - |= (flags & (ENV_VOLSUSTAIN | ENV_PANSUSTAIN | ENV_PITCHSUSTAIN)); - if (ehdr.flags & 32) - envs[ehdr.envnum]->flags - |= (flags & (ENV_VOLLOOP | ENV_PANLOOP | ENV_PITCHLOOP)); - } + struct mdl_envelope ehdr; + song_envelope_t *env; + uint8_t nenv; + int n, tick; + + nenv = slurp_getc(fp); + while (nenv--) { + slurp_read(fp, &ehdr, sizeof(ehdr)); + if (ehdr.envnum > 63) + continue; + + if (!envs[ehdr.envnum]) + envs[ehdr.envnum] = calloc(1, sizeof(struct mdlenv)); + env = &envs[ehdr.envnum]->data; + + env->nodes = 15; + tick = -ehdr.nodes[0].x; // adjust so it starts at zero + for (n = 0; n < 15; n++) { + if (!ehdr.nodes[n].x) { + env->nodes = MAX(n, 2); + break; + } + tick += ehdr.nodes[n].x; + env->ticks[n] = tick; + env->values[n] = MIN(ehdr.nodes[n].y, 64); // actually 0-63 + } + + env->loop_start = ehdr.loop & 0xf; + env->loop_end = ehdr.loop >> 4; + env->sustain_start = env->sustain_end = ehdr.flags & 0xf; + + envs[ehdr.envnum]->flags = 0; + if (ehdr.flags & 16) + envs[ehdr.envnum]->flags + |= (flags & (ENV_VOLSUSTAIN | ENV_PANSUSTAIN | ENV_PITCHSUSTAIN)); + if (ehdr.flags & 32) + envs[ehdr.envnum]->flags + |= (flags & (ENV_VOLLOOP | ENV_PANLOOP | ENV_PITCHLOOP)); + } } /* --------------------------------------------------------------------------------------------------------- */ static void copy_envelope(song_instrument_t *ins, song_envelope_t *ienv, struct mdlenv **envs, uint32_t enable) { - // nodes temporarily indicates which envelope to load - struct mdlenv *env = envs[ienv->nodes]; - if (env) { - ins->flags |= env->flags; - memcpy(ienv, &env->data, sizeof(song_envelope_t)); - } else { - ins->flags &= ~enable; - ienv->nodes = 2; - } + // nodes temporarily indicates which envelope to load + struct mdlenv *env = envs[ienv->nodes]; + if (env) { + ins->flags |= env->flags; + memcpy(ienv, &env->data, sizeof(song_envelope_t)); + } else { + ins->flags &= ~enable; + ienv->nodes = 2; + } } int fmt_mdl_load_song(song_t *song, slurp_t *fp, UNUSED unsigned int lflags) { - struct mdlpat *pat, *patptr = NULL; - struct mdlenv *volenvs[64] = {NULL}, *panenvs[64] = {NULL}, *freqenvs[64] = {NULL}; - uint8_t packtype[MAX_SAMPLES] = {0}; - song_note_t **tracks = NULL; - long datapos = 0; // where to seek for the sample data - int restartpos = -1; - int trk, n; - uint32_t readflags = 0; - uint8_t tag[4]; - uint8_t fmtver; // file format version, e.g. 0x11 = v1.1 - - slurp_read(fp, tag, 4); - if (memcmp(tag, "DMDL", 4) != 0) - return LOAD_UNSUPPORTED; - - fmtver = slurp_getc(fp); - - // Read the next block - while (!slurp_eof(fp)) { - uint32_t blklen; // length of this block - size_t nextpos; // ... and start of next one - - slurp_read(fp, tag, 2); - slurp_read(fp, &blklen, 4); - blklen = bswapLE32(blklen); - nextpos = slurp_tell(fp) + blklen; - - switch (MDL_BLOCK(tag[0], tag[1])) { - case MDL_BLK_INFO: - if (!(readflags & MDL_HAS_INFO)) { - readflags |= MDL_HAS_INFO; - restartpos = mdl_read_info(song, fp); - } - break; - case MDL_BLK_MESSAGE: - if (!(readflags & MDL_HAS_MESSAGE)) { - readflags |= MDL_HAS_MESSAGE; - mdl_read_message(song, fp, blklen); - } - break; - case MDL_BLK_PATTERNS: - if (!(readflags & MDL_HAS_PATTERNS)) { - readflags |= MDL_HAS_PATTERNS; - patptr = ((fmtver >> 4) ? mdl_read_patterns : mdl_read_patterns_v0)(song, fp); - } - break; - case MDL_BLK_TRACKS: - if (!(readflags & MDL_HAS_TRACKS)) { - readflags |= MDL_HAS_TRACKS; - tracks = mdl_read_tracks(fp); - } - break; - case MDL_BLK_INSTRUMENTS: - if (!(readflags & MDL_HAS_INSTRUMENTS)) { - readflags |= MDL_HAS_INSTRUMENTS; - mdl_read_instruments(song, fp); - } - break; - case MDL_BLK_VOLENVS: - if (!(readflags & MDL_HAS_VOLENVS)) { - readflags |= MDL_HAS_VOLENVS; - mdl_read_envelopes(fp, volenvs, ENV_VOLLOOP | ENV_VOLSUSTAIN); - } - break; - case MDL_BLK_PANENVS: - if (!(readflags & MDL_HAS_PANENVS)) { - readflags |= MDL_HAS_PANENVS; - mdl_read_envelopes(fp, panenvs, ENV_PANLOOP | ENV_PANSUSTAIN); - } - break; - case MDL_BLK_FREQENVS: - if (!(readflags & MDL_HAS_FREQENVS)) { - readflags |= MDL_HAS_FREQENVS; - mdl_read_envelopes(fp, freqenvs, ENV_PITCHLOOP | ENV_PITCHSUSTAIN); - } - break; - case MDL_BLK_SAMPLEINFO: - if (!(readflags & MDL_HAS_SAMPLEINFO)) { - readflags |= MDL_HAS_SAMPLEINFO; - ((fmtver >> 4) ? mdl_read_sampleinfo : mdl_read_sampleinfo_v0) - (song, fp, packtype); - } - break; - case MDL_BLK_SAMPLEDATA: - // Can't do anything until we have the sample info block loaded, since the sample - // lengths and packing information is stored there. - // Best we can do at the moment is to remember where this block was so we can jump - // back to it later. - if (!(readflags & MDL_HAS_SAMPLEDATA)) { - readflags |= MDL_HAS_SAMPLEDATA; - datapos = slurp_tell(fp); - } - break; - - case MDL_BLK_PATTERNNAMES: - // don't care - break; - - default: - //log_appendf(4, " Warning: Unknown block of type '%c%c' (0x%04X) at %ld", - // tag[0], tag[1], MDL_BLOCK(tag[0], tag[1]), slurp_tell(fp)); - break; - } - - if (slurp_seek(fp, nextpos, SEEK_SET) != 0) { - log_appendf(4, " Warning: Failed to seek (file truncated?)"); - break; - } - } - - if (!(readflags & MDL_HAS_INSTRUMENTS)) { - // Probably a v0 file, fake an instrument - for (n = 1; n < MAX_SAMPLES; n++) { - if (song->samples[n].length) { - song->instruments[n] = csf_allocate_instrument(); - strcpy(song->instruments[n]->name, song->samples[n].name); - } - } - } - - if (readflags & MDL_HAS_SAMPLEINFO) { - // Sample headers loaded! - // if the sample data was encountered, load it now - // otherwise, clear out the sample lengths so Bad Things don't happen later - if (datapos) { - slurp_seek(fp, datapos, SEEK_SET); - for (n = 1; n < MAX_SAMPLES; n++) { - if (!packtype[n] && !song->samples[n].length) - continue; - uint32_t smpsize, flags; - if (packtype[n] > 2) { - log_appendf(4, " Warning: Sample %d: unknown packing type %d", - n, packtype[n]); - packtype[n] = 0; // ? - } else if (packtype[n] == ((song->samples[n].flags & CHN_16BIT) ? 1 : 2)) { - log_appendf(4, " Warning: Sample %d: bit width / pack type mismatch", - n); - } - flags = SF_LE | SF_M; - flags |= packtype[n] ? SF_MDL : SF_PCMS; - flags |= (song->samples[n].flags & CHN_16BIT) ? SF_16 : SF_8; - smpsize = csf_read_sample(song->samples + n, flags, - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, smpsize, SEEK_CUR); - } - } else { - for (n = 1; n < MAX_SAMPLES; n++) - song->samples[n].length = 0; - } - } - - if (readflags & MDL_HAS_TRACKS) { - song_note_t *patnote, *trknote; - - // first off, fix all the instrument numbers to compensate - // for the screwy envelope craziness - if (fmtver >> 4) { - for (trk = 1; trk < 65536 && tracks[trk]; trk++) { - uint8_t cnote = NOTE_FIRST; // current/last used data - - for (n = 0, trknote = tracks[trk]; n < 256; n++, trknote++) { - if (NOTE_IS_NOTE(trknote->note)) { - cnote = trknote->note; - } - if (trknote->instrument) { - // translate it - trknote->instrument = song->instruments[trknote->instrument] - ? (song->instruments[trknote->instrument] - ->sample_map[cnote - 1]) - : 0; - } - } - } - } - - // "paste" the tracks into the channels - for (pat = patptr; pat; pat = pat->next) { - trknote = tracks[pat->track]; - if (!trknote) - continue; - patnote = pat->note; - for (n = 0; n < pat->rows; n++, trknote++, patnote += 64) { - *patnote = *trknote; - } - } - // and clean up - for (trk = 1; trk < 65536 && tracks[trk]; trk++) - free(tracks[trk]); - free(tracks); - } - while (patptr) { - pat = patptr; - patptr = patptr->next; - free(pat); - } - - // Finish fixing up the instruments - for (n = 1; n < MAX_INSTRUMENTS; n++) { - song_instrument_t *ins = song->instruments[n]; - if (ins) { - copy_envelope(ins, &ins->vol_env, volenvs, ENV_VOLUME); - copy_envelope(ins, &ins->pan_env, panenvs, ENV_PANNING); - copy_envelope(ins, &ins->pitch_env, freqenvs, ENV_PITCH); - - if (ins->flags & ENV_VOLUME) { - // fix note-fade - if (!(ins->flags & ENV_VOLLOOP)) - ins->vol_env.loop_start = ins->vol_env.loop_end = ins->vol_env.nodes - 1; - if (!(ins->flags & ENV_VOLSUSTAIN)) - ins->vol_env.sustain_start = ins->vol_env.sustain_end - = ins->vol_env.nodes - 1; - ins->flags |= ENV_VOLLOOP | ENV_VOLSUSTAIN; - } - if (ins->fadeout == MDL_FADE_CUT) { - // fix note-off - if (!(ins->flags & ENV_VOLUME)) { - ins->vol_env.ticks[0] = 0; - ins->vol_env.values[0] = 64; - ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; - ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; - // (the rest is set below) - } - int se = ins->vol_env.sustain_end; - ins->vol_env.nodes = se + 2; - ins->vol_env.ticks[se + 1] = ins->vol_env.ticks[se] + 1; - ins->vol_env.values[se + 1] = 0; - ins->fadeout = 0; - } - - // set a 1:1 map for each instrument with a corresponding sample, - // and a blank map for each one that doesn't. - int note, smp = song->samples[n].data ? n : 0; - for (note = 0; note < 120; note++) { - ins->sample_map[note] = smp; - ins->note_map[note] = note + 1; - } - } - } - - if (readflags & MDL_HAS_VOLENVS) { - for (n = 0; n < 64; n++) - free(volenvs[n]); - } - if (readflags & MDL_HAS_PANENVS) { - for (n = 0; n < 64; n++) - free(panenvs[n]); - } - if (readflags & MDL_HAS_FREQENVS) { - for (n = 0; n < 64; n++) - free(freqenvs[n]); - } - - if (restartpos > 0) - csf_insert_restart_pos(song, restartpos); - - song->flags |= SONG_ITOLDEFFECTS | SONG_COMPATGXX | SONG_INSTRUMENTMODE | SONG_LINEARSLIDES; - - sprintf(song->tracker_id, "Digitrakker %s", - (fmtver == 0x11) ? "3" // really could be 2.99b -- but close enough for me - : (fmtver == 0x10) ? "2.3" - : (fmtver == 0x00) ? "2.0 - 2.2b" // there was no 1.x release - : "v?.?"); + struct mdlpat *pat, *patptr = NULL; + struct mdlenv *volenvs[64] = {NULL}, *panenvs[64] = {NULL}, *freqenvs[64] = {NULL}; + uint8_t packtype[MAX_SAMPLES] = {0}; + song_note_t **tracks = NULL; + long datapos = 0; // where to seek for the sample data + int restartpos = -1; + int trk, n; + uint32_t readflags = 0; + uint8_t tag[4]; + uint8_t fmtver; // file format version, e.g. 0x11 = v1.1 + + slurp_read(fp, tag, 4); + if (memcmp(tag, "DMDL", 4) != 0) + return LOAD_UNSUPPORTED; + + fmtver = slurp_getc(fp); + + // Read the next block + while (!slurp_eof(fp)) { + uint32_t blklen; // length of this block + size_t nextpos; // ... and start of next one + + slurp_read(fp, tag, 2); + slurp_read(fp, &blklen, 4); + blklen = bswapLE32(blklen); + nextpos = slurp_tell(fp) + blklen; + + switch (MDL_BLOCK(tag[0], tag[1])) { + case MDL_BLK_INFO: + if (!(readflags & MDL_HAS_INFO)) { + readflags |= MDL_HAS_INFO; + restartpos = mdl_read_info(song, fp); + } + break; + case MDL_BLK_MESSAGE: + if (!(readflags & MDL_HAS_MESSAGE)) { + readflags |= MDL_HAS_MESSAGE; + mdl_read_message(song, fp, blklen); + } + break; + case MDL_BLK_PATTERNS: + if (!(readflags & MDL_HAS_PATTERNS)) { + readflags |= MDL_HAS_PATTERNS; + patptr = ((fmtver >> 4) ? mdl_read_patterns : mdl_read_patterns_v0)(song, fp); + } + break; + case MDL_BLK_TRACKS: + if (!(readflags & MDL_HAS_TRACKS)) { + readflags |= MDL_HAS_TRACKS; + tracks = mdl_read_tracks(fp); + } + break; + case MDL_BLK_INSTRUMENTS: + if (!(readflags & MDL_HAS_INSTRUMENTS)) { + readflags |= MDL_HAS_INSTRUMENTS; + mdl_read_instruments(song, fp); + } + break; + case MDL_BLK_VOLENVS: + if (!(readflags & MDL_HAS_VOLENVS)) { + readflags |= MDL_HAS_VOLENVS; + mdl_read_envelopes(fp, volenvs, ENV_VOLLOOP | ENV_VOLSUSTAIN); + } + break; + case MDL_BLK_PANENVS: + if (!(readflags & MDL_HAS_PANENVS)) { + readflags |= MDL_HAS_PANENVS; + mdl_read_envelopes(fp, panenvs, ENV_PANLOOP | ENV_PANSUSTAIN); + } + break; + case MDL_BLK_FREQENVS: + if (!(readflags & MDL_HAS_FREQENVS)) { + readflags |= MDL_HAS_FREQENVS; + mdl_read_envelopes(fp, freqenvs, ENV_PITCHLOOP | ENV_PITCHSUSTAIN); + } + break; + case MDL_BLK_SAMPLEINFO: + if (!(readflags & MDL_HAS_SAMPLEINFO)) { + readflags |= MDL_HAS_SAMPLEINFO; + ((fmtver >> 4) ? mdl_read_sampleinfo : mdl_read_sampleinfo_v0) + (song, fp, packtype); + } + break; + case MDL_BLK_SAMPLEDATA: + // Can't do anything until we have the sample info block loaded, since the sample + // lengths and packing information is stored there. + // Best we can do at the moment is to remember where this block was so we can jump + // back to it later. + if (!(readflags & MDL_HAS_SAMPLEDATA)) { + readflags |= MDL_HAS_SAMPLEDATA; + datapos = slurp_tell(fp); + } + break; + + case MDL_BLK_PATTERNNAMES: + // don't care + break; + + default: + //log_appendf(4, " Warning: Unknown block of type '%c%c' (0x%04X) at %ld", + // tag[0], tag[1], MDL_BLOCK(tag[0], tag[1]), slurp_tell(fp)); + break; + } + + if (slurp_seek(fp, nextpos, SEEK_SET) != 0) { + log_appendf(4, " Warning: Failed to seek (file truncated?)"); + break; + } + } + + if (!(readflags & MDL_HAS_INSTRUMENTS)) { + // Probably a v0 file, fake an instrument + for (n = 1; n < MAX_SAMPLES; n++) { + if (song->samples[n].length) { + song->instruments[n] = csf_allocate_instrument(); + strcpy(song->instruments[n]->name, song->samples[n].name); + } + } + } + + if (readflags & MDL_HAS_SAMPLEINFO) { + // Sample headers loaded! + // if the sample data was encountered, load it now + // otherwise, clear out the sample lengths so Bad Things don't happen later + if (datapos) { + slurp_seek(fp, datapos, SEEK_SET); + for (n = 1; n < MAX_SAMPLES; n++) { + if (!packtype[n] && !song->samples[n].length) + continue; + uint32_t smpsize, flags; + if (packtype[n] > 2) { + log_appendf(4, " Warning: Sample %d: unknown packing type %d", + n, packtype[n]); + packtype[n] = 0; // ? + } else if (packtype[n] == ((song->samples[n].flags & CHN_16BIT) ? 1 : 2)) { + log_appendf(4, " Warning: Sample %d: bit width / pack type mismatch", + n); + } + flags = SF_LE | SF_M; + flags |= packtype[n] ? SF_MDL : SF_PCMS; + flags |= (song->samples[n].flags & CHN_16BIT) ? SF_16 : SF_8; + smpsize = csf_read_sample(song->samples + n, flags, + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, smpsize, SEEK_CUR); + } + } else { + for (n = 1; n < MAX_SAMPLES; n++) + song->samples[n].length = 0; + } + } + + if (readflags & MDL_HAS_TRACKS) { + song_note_t *patnote, *trknote; + + // first off, fix all the instrument numbers to compensate + // for the screwy envelope craziness + if (fmtver >> 4) { + for (trk = 1; trk < 65536 && tracks[trk]; trk++) { + uint8_t cnote = NOTE_FIRST; // current/last used data + + for (n = 0, trknote = tracks[trk]; n < 256; n++, trknote++) { + if (NOTE_IS_NOTE(trknote->note)) { + cnote = trknote->note; + } + if (trknote->instrument) { + // translate it + trknote->instrument = song->instruments[trknote->instrument] + ? (song->instruments[trknote->instrument] + ->sample_map[cnote - 1]) + : 0; + } + } + } + } + + // "paste" the tracks into the channels + for (pat = patptr; pat; pat = pat->next) { + trknote = tracks[pat->track]; + if (!trknote) + continue; + patnote = pat->note; + for (n = 0; n < pat->rows; n++, trknote++, patnote += 64) { + *patnote = *trknote; + } + } + // and clean up + for (trk = 1; trk < 65536 && tracks[trk]; trk++) + free(tracks[trk]); + free(tracks); + } + while (patptr) { + pat = patptr; + patptr = patptr->next; + free(pat); + } + + // Finish fixing up the instruments + for (n = 1; n < MAX_INSTRUMENTS; n++) { + song_instrument_t *ins = song->instruments[n]; + if (ins) { + copy_envelope(ins, &ins->vol_env, volenvs, ENV_VOLUME); + copy_envelope(ins, &ins->pan_env, panenvs, ENV_PANNING); + copy_envelope(ins, &ins->pitch_env, freqenvs, ENV_PITCH); + + if (ins->flags & ENV_VOLUME) { + // fix note-fade + if (!(ins->flags & ENV_VOLLOOP)) + ins->vol_env.loop_start = ins->vol_env.loop_end = ins->vol_env.nodes - 1; + if (!(ins->flags & ENV_VOLSUSTAIN)) + ins->vol_env.sustain_start = ins->vol_env.sustain_end + = ins->vol_env.nodes - 1; + ins->flags |= ENV_VOLLOOP | ENV_VOLSUSTAIN; + } + if (ins->fadeout == MDL_FADE_CUT) { + // fix note-off + if (!(ins->flags & ENV_VOLUME)) { + ins->vol_env.ticks[0] = 0; + ins->vol_env.values[0] = 64; + ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; + ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; + // (the rest is set below) + } + int se = ins->vol_env.sustain_end; + ins->vol_env.nodes = se + 2; + ins->vol_env.ticks[se + 1] = ins->vol_env.ticks[se] + 1; + ins->vol_env.values[se + 1] = 0; + ins->fadeout = 0; + } + + // set a 1:1 map for each instrument with a corresponding sample, + // and a blank map for each one that doesn't. + int note, smp = song->samples[n].data ? n : 0; + for (note = 0; note < 120; note++) { + ins->sample_map[note] = smp; + ins->note_map[note] = note + 1; + } + } + } + + if (readflags & MDL_HAS_VOLENVS) { + for (n = 0; n < 64; n++) + free(volenvs[n]); + } + if (readflags & MDL_HAS_PANENVS) { + for (n = 0; n < 64; n++) + free(panenvs[n]); + } + if (readflags & MDL_HAS_FREQENVS) { + for (n = 0; n < 64; n++) + free(freqenvs[n]); + } + + if (restartpos > 0) + csf_insert_restart_pos(song, restartpos); + + song->flags |= SONG_ITOLDEFFECTS | SONG_COMPATGXX | SONG_INSTRUMENTMODE | SONG_LINEARSLIDES; + + sprintf(song->tracker_id, "Digitrakker %s", + (fmtver == 0x11) ? "3" // really could be 2.99b -- but close enough for me + : (fmtver == 0x10) ? "2.3" + : (fmtver == 0x00) ? "2.0 - 2.2b" // there was no 1.x release + : "v?.?"); - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/med.c schism-20160521/fmt/med.c --- schism-0+20110101/fmt/med.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/med.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,12 +28,12 @@ int fmt_med_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 32 && memcmp(data, "MMD0", 3) == 0)) - return 0; + if (!(length > 32 && memcmp(data, "MMD0", 3) == 0)) + return 0; - file->description = "OctaMed"; - file->title = strdup(""); // TODO actually read the title - file->type = TYPE_MODULE_MOD; - return 1; + file->description = "OctaMed"; + file->title = strdup(""); // TODO actually read the title + file->type = TYPE_MODULE_MOD; + return 1; } diff -Nru schism-0+20110101/fmt/mf.c schism-20160521/fmt/mf.c --- schism-0+20110101/fmt/mf.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mf.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,17 +28,17 @@ int fmt_mf_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - uint8_t titlelen; - if (!(length > 290 && memcmp(data, "MOONFISH", 8) == 0)) - return 0; + uint8_t titlelen; + if (!(length > 290 && memcmp(data, "MOONFISH", 8) == 0)) + return 0; - file->description = "MoonFish"; - /*file->extension = str_dup("mf");*/ - titlelen = MIN(32, data[32]); - file->title = calloc(titlelen + 1, sizeof(char)); - memcpy(file->title, data + 33, titlelen); - file->title[titlelen] = 0; - file->type = TYPE_MODULE_MOD; /* ??? */ - return 1; + file->description = "MoonFish"; + /*file->extension = str_dup("mf");*/ + titlelen = MIN(32, data[32]); + file->title = calloc(titlelen + 1, sizeof(char)); + memcpy(file->title, data + 33, titlelen); + file->title[titlelen] = 0; + file->type = TYPE_MODULE_MOD; /* ??? */ + return 1; } diff -Nru schism-0+20110101/fmt/mid.c schism-20160521/fmt/mid.c --- schism-0+20110101/fmt/mid.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mid.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -53,38 +53,38 @@ #pragma pack(push, 1) struct mthd { - //char tag[4]; // MThd - uint32_t header_length; - uint16_t format; // 0 = single-track, 1 = multi-track, 2 = multi-song - uint16_t num_tracks; // number of track chunks - uint16_t division; // delta timing value: positive = units/beat; negative = smpte compatible units (?) + //char tag[4]; // MThd + uint32_t header_length; + uint16_t format; // 0 = single-track, 1 = multi-track, 2 = multi-song + uint16_t num_tracks; // number of track chunks + uint16_t division; // delta timing value: positive = units/beat; negative = smpte compatible units (?) }; struct mtrk { - char tag[4]; // MTrk - uint32_t length; // number of bytes of track data following + char tag[4]; // MTrk + uint32_t length; // number of bytes of track data following }; #pragma pack(pop) struct event { - unsigned int pulse; // the PPQN-tick, counting from zero, when this midi-event happens - uint8_t chan; // target channel (0-based!) - song_note_t note; // the note data (new data will overwrite old data in same channel+row) - struct event *next; + unsigned int pulse; // the PPQN-tick, counting from zero, when this midi-event happens + uint8_t chan; // target channel (0-based!) + song_note_t note; // the note data (new data will overwrite old data in same channel+row) + struct event *next; }; static struct event *alloc_event(unsigned int pulse, uint8_t chan, const song_note_t *note, struct event *next) { - struct event *ev = malloc(sizeof(struct event)); - if (!ev) { - perror("malloc"); - return NULL; - } - ev->pulse = pulse; - ev->chan = chan; - ev->note = *note; - ev->next = next; - return ev; + struct event *ev = malloc(sizeof(struct event)); + if (!ev) { + perror("malloc"); + return NULL; + } + ev->pulse = pulse; + ev->chan = chan; + ev->note = *note; + ev->next = next; + return ev; } /* --------------------------------------------------------------------------------------------------------- */ @@ -92,18 +92,18 @@ static unsigned int read_varlen(slurp_t *fp) { - int b; - unsigned int v = 0; + int b; + unsigned int v = 0; - // This will fail tremendously if a value overflows. I don't care. - do { - b = slurp_getc(fp); - if (b == EOF) - return 0; // truncated?! - v <<= 7; - v |= b & 0x7f; - } while (b & 0x80); - return v; + // This will fail tremendously if a value overflows. I don't care. + do { + b = slurp_getc(fp); + if (b == EOF) + return 0; // truncated?! + v <<= 7; + v |= b & 0x7f; + } while (b & 0x80); + return v; } /* --------------------------------------------------------------------------------------------------------- */ @@ -111,20 +111,20 @@ int fmt_mid_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - slurp_t fp = {.length = length, .data = (uint8_t *) data, .pos = 0}; - song_t *tmpsong = csf_allocate(); + slurp_t fp = {.length = length, .data = (uint8_t *) data, .pos = 0}; + song_t *tmpsong = csf_allocate(); - if (!tmpsong) - return 0; // wahhhh - if (fmt_mid_load_song(tmpsong, &fp, LOAD_NOSAMPLES | LOAD_NOPATTERNS) == LOAD_SUCCESS) { - file->description = "Standard MIDI File"; - file->title = strdup(tmpsong->title); - file->type = TYPE_MODULE_MOD; - csf_free(tmpsong); - return 1; - } - csf_free(tmpsong); - return 0; + if (!tmpsong) + return 0; // wahhhh + if (fmt_mid_load_song(tmpsong, &fp, LOAD_NOSAMPLES | LOAD_NOPATTERNS) == LOAD_SUCCESS) { + file->description = "Standard MIDI File"; + file->title = strdup(tmpsong->title); + file->type = TYPE_MODULE_MOD; + csf_free(tmpsong); + return 1; + } + csf_free(tmpsong); + return 0; } /* --------------------------------------------------------------------------------------------------------- */ @@ -132,358 +132,358 @@ int fmt_mid_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - struct mthd mthd; - struct mtrk mtrk; - unsigned char buf[32]; - song_note_t note; - struct event *event_queue, *cur, *prev, *new; - struct { - uint8_t fg_note; - uint8_t bg_note; // really just used as a boolean... - uint8_t instrument; - } midich[16] = {{NOTE_NONE, NOTE_NONE, 0}}; - char *message_cur = song->message; - unsigned int message_left = MAX_MESSAGE; - unsigned int pulse = 0; // cumulative time from start of track - uint8_t patch_samples[128] = {0}; - uint8_t nsmp = 1; // Next free sample - - slurp_read(fp, buf, 4); - if (memcmp(buf, "RIFF", 4) == 0) { - // Stupid MS crap. - slurp_seek(fp, 16, SEEK_CUR); - slurp_read(fp, buf, 4); - } - if (memcmp(buf, "MThd", 4) != 0 || slurp_read(fp, &mthd, sizeof(mthd)) != sizeof(mthd)) { - return LOAD_UNSUPPORTED; - } - mthd.header_length = bswapBE32(mthd.header_length); - // don't care about format, either there's one track or more than one track. whoop de doo. - // (format 2 MIDs will probably be hilariously broken, but I don't have any and also don't care) - mthd.format = bswapBE16(mthd.format); - mthd.num_tracks = bswapBE16(mthd.num_tracks); - mthd.division = bswapBE16(mthd.division); - slurp_seek(fp, mthd.header_length - 6, SEEK_CUR); // account for potential weirdness - - song->title[0] = '\0'; // should be already, but to be sure... - - /* We'll count by "pulses" here, which are basically MIDI-speak for ticks, except that there are a heck - of a lot more of them. (480 pulses/quarter is fairly common, that's like A78, if the tempo could be - adjusted high enough to make practical use of that speed) - Also, we'll use a 32-bit value and hopefully not overflow -- which is unlikely anyway, as it'd either - require PPQN to be very ridiculously high, or a file that's several *hours* long. - - Stuff a useless event at the start of the event queue. */ - note = (song_note_t) {.note = NOTE_NONE}; - event_queue = alloc_event(0, 0, ¬e, NULL); - - for (int trknum = 0; trknum < mthd.num_tracks; trknum++) { - unsigned int delta; // time since last event (read from file) - unsigned int vlen; // some other generic varlen number - int rs = 0; // running status byte - int status; // THIS status byte (as opposed to rs) - unsigned char hi, lo, cn, x, y; - unsigned int bpm; // stupid - int found_end = 0; - long nextpos; - - cur = event_queue->next; - prev = event_queue; - pulse = 0; - - if (slurp_read(fp, &mtrk, sizeof(mtrk)) != sizeof(mtrk)) { - log_appendf(4, " Warning: Short read on track header (truncated?)"); - break; - } - if (memcmp(mtrk.tag, "MTrk", 4) != 0) { - log_appendf(4, " Warning: Invalid track header (corrupt file?)"); - break; - } - mtrk.length = bswapBE32(mtrk.length); - nextpos = slurp_tell(fp) + mtrk.length; // where this track is supposed to end - - while (!found_end && slurp_tell(fp) < nextpos) { - delta = read_varlen(fp); // delta-time - pulse += delta; // 'real' pulse count - - // get status byte, if there is one - if (fp->data[fp->pos] & 0x80) { - status = slurp_getc(fp); - } else if (rs & 0x80) { - status = rs; - } else { - // garbage? - continue; - } - - note = (song_note_t) {.note = NOTE_NONE}; - hi = status >> 4; - lo = status & 0xf; - cn = lo; //or: trknum * CHANNELS_PER_TRACK + lo % CHANNELS_PER_TRACK; - - switch (hi) { - case 0x8: // note off - x, y - rs = status; - x = slurp_getc(fp); // note - y = slurp_getc(fp); // release velocity - x = CLAMP(x + NOTE_FIRST, NOTE_FIRST, NOTE_LAST); // clamp is wrong, but whatever - // if the last note in the channel is the same as this note, just write === - // otherwise, if there is a note playing, assume our note got backgrounded - // and write S71 (past note off) - if (midich[cn].fg_note == x) { - note = (song_note_t) {.note = NOTE_OFF}; - midich[cn].fg_note = NOTE_NONE; - } else { - // S71, past note off - note = (song_note_t) {.effect = FX_SPECIAL, .param = 0x71}; - midich[cn].bg_note = NOTE_NONE; - } - break; - case 0x9: // note on - x, y (velocity zero = note off) - rs = status; - x = slurp_getc(fp); // note - y = slurp_getc(fp); // attack velocity - x = CLAMP(x + NOTE_FIRST, NOTE_FIRST, NOTE_LAST); // see note off above. - - if (lo == 9) { - // ignore percussion for now - } else if (y == 0) { - // this is actually another note-off, see above - // (maybe that stuff should be split into a function or blahblah) - if (midich[cn].fg_note == x) { - note = (song_note_t) {.note = NOTE_OFF}; - midich[cn].fg_note = NOTE_NONE; - } else { - // S71, past note off - note = (song_note_t) {.effect = FX_SPECIAL, .param = 0x71}; - midich[cn].bg_note = NOTE_NONE; - } - } else { - if (nsmp == 1 && !(lflags & LOAD_NOSAMPLES)) { - // no samples defined yet - fake a program change - patch_samples[0] = 1; - adlib_patch_apply(song->samples + 1, 0); - nsmp++; - } - - note = (song_note_t) { - .note = x, - .instrument = patch_samples[midich[cn].instrument], - .voleffect = VOLFX_VOLUME, - .volparam = (y & 0x7f) * 64 / 127, - }; - midich[cn].fg_note = x; - midich[cn].bg_note = midich[cn].fg_note; - } - break; - case 0xa: // polyphonic key pressure (aftertouch) - x, y - rs = status; - x = slurp_getc(fp); - y = slurp_getc(fp); - // TODO polyphonic aftertouch channel=lo note=x pressure=y - continue; - case 0xb: // controller OR channel mode - x, y - rs = status; - // controller if first data byte 0-119 - // channel mode if first data byte 120-127 - x = slurp_getc(fp); - y = slurp_getc(fp); - // TODO controller change channel=lo controller=x value=y - continue; - case 0xc: // program change - x (instrument/voice selection) - rs = status; - x = slurp_getc(fp); - midich[cn].instrument = x; - // look familiar? this was copied from the .mus loader - if (!patch_samples[x] && !(lflags & LOAD_NOSAMPLES)) { - if (nsmp < MAX_SAMPLES) { - // New sample! - patch_samples[x] = nsmp; - adlib_patch_apply(song->samples + nsmp, x); - nsmp++; - } else { - log_appendf(4, " Warning: Too many samples"); - } - } - note = (song_note_t) {.instrument = patch_samples[x]}; - break; - case 0xd: // channel pressure (aftertouch) - x - rs = status; - x = slurp_getc(fp); - // TODO channel aftertouch channel=lo pressure=x - continue; - case 0xe: // pitch bend - x, y - rs = status; - x = slurp_getc(fp); - y = slurp_getc(fp); - // TODO pitch bend channel=lo lsb=x msb=y - continue; - case 0xf: // system messages - switch (lo) { - case 0xf: // meta-event (text and stuff) - x = slurp_getc(fp); // type - vlen = read_varlen(fp); // value length - switch (x) { - case 0x1: // text - case 0x2: // copyright - case 0x3: // track name - case 0x4: // instrument name - case 0x5: // lyric - case 0x6: // marker - case 0x7: // cue point - y = MIN(vlen, message_left - 1); - slurp_read(fp, message_cur, y); - if (x == 3 && y && !song->title[0]) { - strncpy(song->title, message_cur, MIN(y, 25)); - song->title[25] = '\0'; - } - message_cur += y; - message_left -= y; - if (y && message_cur[-1] != '\n') { - *message_cur++ = '\n'; - message_left--; - } - vlen -= y; - if (vlen) - slurp_seek(fp, vlen, SEEK_CUR); - continue; - - case 0x20: // MIDI channel (FF 20 len* cc) - // specifies which midi-channel sysexes are assigned to - case 0x21: // MIDI port (FF 21 len* pp) - // specifies which port/bus this track's events are routed to - continue; - - case 0x2f: - found_end = 1; - break; - case 0x51: // set tempo - // read another stupid kind of variable length number - // hopefully this fits into 4 bytes - if not, too bad! - // (what is this? friggin' magic?) - memset(buf, 0, 4); - y = MIN(vlen, 4); - slurp_read(fp, buf + (4 - y), y); - bpm = buf[0] << 24 | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - bpm = CLAMP(60000000 / (bpm ?: 1), 0x20, 0xff); - note = (song_note_t) {.effect = FX_TEMPO, .param = bpm}; - vlen -= y; - break; - case 0x54: // SMPTE offset (what time in the song this track starts) - // (what?!) - continue; - case 0x58: // time signature (FF 58 len* nn dd cc bb) - case 0x59: // key signature (FF 59 len* sf mi) - // TODO care? don't care? - continue; - case 0x7f: // some proprietary crap - continue; - - default: - // some mystery crap - log_appendf(2, " Unknown meta-event FF %02X", x); - continue; - } - slurp_seek(fp, vlen, SEEK_CUR); - break; - case 0x0: // sysex - case 0x1 ... 0x7: // syscommon - rs = 0; // clear running status - case 0x8 ... 0xe: // sysrt - // 0xf0 - sysex - // 0xf1-0xf7 - common - // 0xf8-0xff - sysrt - // sysex and common cancel running status - // TODO handle these, or at least skip them coherently - continue; - } - } - - // skip past any events with a lower pulse count (from other channels) - while (cur && pulse > cur->pulse) { - prev = cur; - cur = cur->next; - } - // and now, cur is either NULL or has a higher timestamp, so insert before it - new = alloc_event(pulse, cn, ¬e, cur); - prev->next = new; - prev = prev->next; - } - if (slurp_tell(fp) != nextpos) { - log_appendf(2, " Track %d ended %ld bytes from boundary", - trknum, slurp_tell(fp) - nextpos); - slurp_seek(fp, nextpos, SEEK_SET); - } - } - - song->initial_speed = 3; - song->initial_tempo = 120; - - prev = NULL; - cur = event_queue; - - if (lflags & LOAD_NOPATTERNS) { - while (cur) { - prev = cur; - cur = cur->next; - free(prev); - } - return LOAD_SUCCESS; - } - - // okey doke! now let's write this crap out to the patterns - song_note_t *pattern = NULL, *rowdata; - int row = MID_ROWS_PER_PATTERN; // what row of the pattern rowdata is pointing to (fixed point) - int rowfrac = 0; // how much is left over - int pat = 0; // next pattern number to create - pulse = 0; // PREVIOUS event pulse. - - while (cur) { - /* calculate pulse delta from previous event - * calculate row count from the pulse count using ppqn (assuming 1 row = 1/32nd note? 1/64?) - * advance the row as required - it'd be nice to aim for the "middle" of ticks instead of the start of them, that way if an - event is just barely off, it won't end up shifted way ahead. - */ - unsigned int delta = cur->pulse - pulse; - - if (delta) { - // Increment position - row <<= FRACBITS; - row += 8 * (delta << FRACBITS) / mthd.division; // times 8 -> 32nd notes - row += rowfrac; - rowfrac = row & FRACMASK; - row >>= FRACBITS; - } - pulse = cur->pulse; - - while (row >= MID_ROWS_PER_PATTERN) { - // New pattern time! - pattern = song->patterns[pat] = csf_allocate_pattern(MID_ROWS_PER_PATTERN); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = MID_ROWS_PER_PATTERN; - song->orderlist[pat] = pat; - pat++; - row -= MID_ROWS_PER_PATTERN; - } - rowdata = pattern + 64 * row; - if (cur->note.note) { - rowdata[cur->chan].note = cur->note.note; - rowdata[cur->chan].instrument = cur->note.instrument; - } - if (cur->note.voleffect) { - rowdata[cur->chan].voleffect = cur->note.voleffect; - rowdata[cur->chan].volparam = cur->note.volparam; - } - if (cur->note.effect) { - rowdata[cur->chan].effect = cur->note.effect; - rowdata[cur->chan].param = cur->note.param; - } - - prev = cur; - cur = cur->next; - free(prev); - } + struct mthd mthd; + struct mtrk mtrk; + unsigned char buf[32]; + song_note_t note; + struct event *event_queue, *cur, *prev, *new; + struct { + uint8_t fg_note; + uint8_t bg_note; // really just used as a boolean... + uint8_t instrument; + } midich[16] = {{NOTE_NONE, NOTE_NONE, 0}}; + char *message_cur = song->message; + unsigned int message_left = MAX_MESSAGE; + unsigned int pulse = 0; // cumulative time from start of track + uint8_t patch_samples[128] = {0}; + uint8_t nsmp = 1; // Next free sample + + slurp_read(fp, buf, 4); + if (memcmp(buf, "RIFF", 4) == 0) { + // Stupid MS crap. + slurp_seek(fp, 16, SEEK_CUR); + slurp_read(fp, buf, 4); + } + if (memcmp(buf, "MThd", 4) != 0 || slurp_read(fp, &mthd, sizeof(mthd)) != sizeof(mthd)) { + return LOAD_UNSUPPORTED; + } + mthd.header_length = bswapBE32(mthd.header_length); + // don't care about format, either there's one track or more than one track. whoop de doo. + // (format 2 MIDs will probably be hilariously broken, but I don't have any and also don't care) + mthd.format = bswapBE16(mthd.format); + mthd.num_tracks = bswapBE16(mthd.num_tracks); + mthd.division = bswapBE16(mthd.division); + slurp_seek(fp, mthd.header_length - 6, SEEK_CUR); // account for potential weirdness + + song->title[0] = '\0'; // should be already, but to be sure... + + /* We'll count by "pulses" here, which are basically MIDI-speak for ticks, except that there are a heck + of a lot more of them. (480 pulses/quarter is fairly common, that's like A78, if the tempo could be + adjusted high enough to make practical use of that speed) + Also, we'll use a 32-bit value and hopefully not overflow -- which is unlikely anyway, as it'd either + require PPQN to be very ridiculously high, or a file that's several *hours* long. + + Stuff a useless event at the start of the event queue. */ + note = (song_note_t) {.note = NOTE_NONE}; + event_queue = alloc_event(0, 0, ¬e, NULL); + + for (int trknum = 0; trknum < mthd.num_tracks; trknum++) { + unsigned int delta; // time since last event (read from file) + unsigned int vlen; // some other generic varlen number + int rs = 0; // running status byte + int status; // THIS status byte (as opposed to rs) + unsigned char hi, lo, cn, x, y; + unsigned int bpm; // stupid + int found_end = 0; + long nextpos; + + cur = event_queue->next; + prev = event_queue; + pulse = 0; + + if (slurp_read(fp, &mtrk, sizeof(mtrk)) != sizeof(mtrk)) { + log_appendf(4, " Warning: Short read on track header (truncated?)"); + break; + } + if (memcmp(mtrk.tag, "MTrk", 4) != 0) { + log_appendf(4, " Warning: Invalid track header (corrupt file?)"); + break; + } + mtrk.length = bswapBE32(mtrk.length); + nextpos = slurp_tell(fp) + mtrk.length; // where this track is supposed to end + + while (!found_end && slurp_tell(fp) < nextpos) { + delta = read_varlen(fp); // delta-time + pulse += delta; // 'real' pulse count + + // get status byte, if there is one + if (fp->data[fp->pos] & 0x80) { + status = slurp_getc(fp); + } else if (rs & 0x80) { + status = rs; + } else { + // garbage? + continue; + } + + note = (song_note_t) {.note = NOTE_NONE}; + hi = status >> 4; + lo = status & 0xf; + cn = lo; //or: trknum * CHANNELS_PER_TRACK + lo % CHANNELS_PER_TRACK; + + switch (hi) { + case 0x8: // note off - x, y + rs = status; + x = slurp_getc(fp); // note + y = slurp_getc(fp); // release velocity + x = CLAMP(x + NOTE_FIRST, NOTE_FIRST, NOTE_LAST); // clamp is wrong, but whatever + // if the last note in the channel is the same as this note, just write === + // otherwise, if there is a note playing, assume our note got backgrounded + // and write S71 (past note off) + if (midich[cn].fg_note == x) { + note = (song_note_t) {.note = NOTE_OFF}; + midich[cn].fg_note = NOTE_NONE; + } else { + // S71, past note off + note = (song_note_t) {.effect = FX_SPECIAL, .param = 0x71}; + midich[cn].bg_note = NOTE_NONE; + } + break; + case 0x9: // note on - x, y (velocity zero = note off) + rs = status; + x = slurp_getc(fp); // note + y = slurp_getc(fp); // attack velocity + x = CLAMP(x + NOTE_FIRST, NOTE_FIRST, NOTE_LAST); // see note off above. + + if (lo == 9) { + // ignore percussion for now + } else if (y == 0) { + // this is actually another note-off, see above + // (maybe that stuff should be split into a function or blahblah) + if (midich[cn].fg_note == x) { + note = (song_note_t) {.note = NOTE_OFF}; + midich[cn].fg_note = NOTE_NONE; + } else { + // S71, past note off + note = (song_note_t) {.effect = FX_SPECIAL, .param = 0x71}; + midich[cn].bg_note = NOTE_NONE; + } + } else { + if (nsmp == 1 && !(lflags & LOAD_NOSAMPLES)) { + // no samples defined yet - fake a program change + patch_samples[0] = 1; + adlib_patch_apply(song->samples + 1, 0); + nsmp++; + } + + note = (song_note_t) { + .note = x, + .instrument = patch_samples[midich[cn].instrument], + .voleffect = VOLFX_VOLUME, + .volparam = (y & 0x7f) * 64 / 127, + }; + midich[cn].fg_note = x; + midich[cn].bg_note = midich[cn].fg_note; + } + break; + case 0xa: // polyphonic key pressure (aftertouch) - x, y + rs = status; + x = slurp_getc(fp); + y = slurp_getc(fp); + // TODO polyphonic aftertouch channel=lo note=x pressure=y + continue; + case 0xb: // controller OR channel mode - x, y + rs = status; + // controller if first data byte 0-119 + // channel mode if first data byte 120-127 + x = slurp_getc(fp); + y = slurp_getc(fp); + // TODO controller change channel=lo controller=x value=y + continue; + case 0xc: // program change - x (instrument/voice selection) + rs = status; + x = slurp_getc(fp); + midich[cn].instrument = x; + // look familiar? this was copied from the .mus loader + if (!patch_samples[x] && !(lflags & LOAD_NOSAMPLES)) { + if (nsmp < MAX_SAMPLES) { + // New sample! + patch_samples[x] = nsmp; + adlib_patch_apply(song->samples + nsmp, x); + nsmp++; + } else { + log_appendf(4, " Warning: Too many samples"); + } + } + note = (song_note_t) {.instrument = patch_samples[x]}; + break; + case 0xd: // channel pressure (aftertouch) - x + rs = status; + x = slurp_getc(fp); + // TODO channel aftertouch channel=lo pressure=x + continue; + case 0xe: // pitch bend - x, y + rs = status; + x = slurp_getc(fp); + y = slurp_getc(fp); + // TODO pitch bend channel=lo lsb=x msb=y + continue; + case 0xf: // system messages + switch (lo) { + case 0xf: // meta-event (text and stuff) + x = slurp_getc(fp); // type + vlen = read_varlen(fp); // value length + switch (x) { + case 0x1: // text + case 0x2: // copyright + case 0x3: // track name + case 0x4: // instrument name + case 0x5: // lyric + case 0x6: // marker + case 0x7: // cue point + y = MIN(vlen, message_left - 1); + slurp_read(fp, message_cur, y); + if (x == 3 && y && !song->title[0]) { + strncpy(song->title, message_cur, MIN(y, 25)); + song->title[25] = '\0'; + } + message_cur += y; + message_left -= y; + if (y && message_cur[-1] != '\n') { + *message_cur++ = '\n'; + message_left--; + } + vlen -= y; + if (vlen) + slurp_seek(fp, vlen, SEEK_CUR); + continue; + + case 0x20: // MIDI channel (FF 20 len* cc) + // specifies which midi-channel sysexes are assigned to + case 0x21: // MIDI port (FF 21 len* pp) + // specifies which port/bus this track's events are routed to + continue; + + case 0x2f: + found_end = 1; + break; + case 0x51: // set tempo + // read another stupid kind of variable length number + // hopefully this fits into 4 bytes - if not, too bad! + // (what is this? friggin' magic?) + memset(buf, 0, 4); + y = MIN(vlen, 4); + slurp_read(fp, buf + (4 - y), y); + bpm = buf[0] << 24 | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + bpm = CLAMP(60000000 / (bpm ?: 1), 0x20, 0xff); + note = (song_note_t) {.effect = FX_TEMPO, .param = bpm}; + vlen -= y; + break; + case 0x54: // SMPTE offset (what time in the song this track starts) + // (what?!) + continue; + case 0x58: // time signature (FF 58 len* nn dd cc bb) + case 0x59: // key signature (FF 59 len* sf mi) + // TODO care? don't care? + continue; + case 0x7f: // some proprietary crap + continue; + + default: + // some mystery crap + log_appendf(2, " Unknown meta-event FF %02X", x); + continue; + } + slurp_seek(fp, vlen, SEEK_CUR); + break; + case 0x0: // sysex + case 0x1 ... 0x7: // syscommon + rs = 0; // clear running status + case 0x8 ... 0xe: // sysrt + // 0xf0 - sysex + // 0xf1-0xf7 - common + // 0xf8-0xff - sysrt + // sysex and common cancel running status + // TODO handle these, or at least skip them coherently + continue; + } + } + + // skip past any events with a lower pulse count (from other channels) + while (cur && pulse > cur->pulse) { + prev = cur; + cur = cur->next; + } + // and now, cur is either NULL or has a higher timestamp, so insert before it + new = alloc_event(pulse, cn, ¬e, cur); + prev->next = new; + prev = prev->next; + } + if (slurp_tell(fp) != nextpos) { + log_appendf(2, " Track %d ended %ld bytes from boundary", + trknum, slurp_tell(fp) - nextpos); + slurp_seek(fp, nextpos, SEEK_SET); + } + } + + song->initial_speed = 3; + song->initial_tempo = 120; + + prev = NULL; + cur = event_queue; + + if (lflags & LOAD_NOPATTERNS) { + while (cur) { + prev = cur; + cur = cur->next; + free(prev); + } + return LOAD_SUCCESS; + } + + // okey doke! now let's write this crap out to the patterns + song_note_t *pattern = NULL, *rowdata; + int row = MID_ROWS_PER_PATTERN; // what row of the pattern rowdata is pointing to (fixed point) + int rowfrac = 0; // how much is left over + int pat = 0; // next pattern number to create + pulse = 0; // PREVIOUS event pulse. + + while (cur) { + /* calculate pulse delta from previous event + * calculate row count from the pulse count using ppqn (assuming 1 row = 1/32nd note? 1/64?) + * advance the row as required + it'd be nice to aim for the "middle" of ticks instead of the start of them, that way if an + event is just barely off, it won't end up shifted way ahead. + */ + unsigned int delta = cur->pulse - pulse; + + if (delta) { + // Increment position + row <<= FRACBITS; + row += 8 * (delta << FRACBITS) / mthd.division; // times 8 -> 32nd notes + row += rowfrac; + rowfrac = row & FRACMASK; + row >>= FRACBITS; + } + pulse = cur->pulse; + + while (row >= MID_ROWS_PER_PATTERN) { + // New pattern time! + pattern = song->patterns[pat] = csf_allocate_pattern(MID_ROWS_PER_PATTERN); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = MID_ROWS_PER_PATTERN; + song->orderlist[pat] = pat; + pat++; + row -= MID_ROWS_PER_PATTERN; + } + rowdata = pattern + 64 * row; + if (cur->note.note) { + rowdata[cur->chan].note = cur->note.note; + rowdata[cur->chan].instrument = cur->note.instrument; + } + if (cur->note.voleffect) { + rowdata[cur->chan].voleffect = cur->note.voleffect; + rowdata[cur->chan].volparam = cur->note.volparam; + } + if (cur->note.effect) { + rowdata[cur->chan].effect = cur->note.effect; + rowdata[cur->chan].param = cur->note.param; + } + + prev = cur; + cur = cur->next; + free(prev); + } - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/mmcmp.c schism-20160521/fmt/mmcmp.c --- schism-0+20110101/fmt/mmcmp.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mmcmp.c 2016-05-21 14:40:41.000000000 +0000 @@ -16,48 +16,48 @@ #pragma pack(push, 1) typedef struct mm_header { - char zirconia[8]; // "ziRCONia" - uint16_t hdrsize; + char zirconia[8]; // "ziRCONia" + uint16_t hdrsize; - uint16_t version; - uint16_t blocks; - uint32_t filesize; - uint32_t blktable; - uint8_t glb_comp; - uint8_t fmt_comp; + uint16_t version; + uint16_t blocks; + uint32_t filesize; + uint32_t blktable; + uint8_t glb_comp; + uint8_t fmt_comp; } mm_header_t; typedef struct mm_block { - uint32_t unpk_size; - uint32_t pk_size; - uint32_t xor_chk; - uint16_t sub_blk; - uint16_t flags; - uint16_t tt_entries; - uint16_t num_bits; + uint32_t unpk_size; + uint32_t pk_size; + uint32_t xor_chk; + uint16_t sub_blk; + uint16_t flags; + uint16_t tt_entries; + uint16_t num_bits; } mm_block_t; typedef struct mm_subblock { - uint32_t unpk_pos; - uint32_t unpk_size; + uint32_t unpk_pos; + uint32_t unpk_size; } mm_subblock_t; #pragma pack(pop) // only used internally typedef struct mm_bit_buffer { - uint32_t bits, buffer; - uint8_t *src, *end; + uint32_t bits, buffer; + uint8_t *src, *end; } mm_bit_buffer_t; enum { - MM_COMP = 0x0001, - MM_DELTA = 0x0002, - MM_16BIT = 0x0004, - MM_STEREO = 0x0100, // unused? - MM_ABS16 = 0x0200, - MM_ENDIAN = 0x0400, // unused? + MM_COMP = 0x0001, + MM_DELTA = 0x0002, + MM_16BIT = 0x0004, + MM_STEREO = 0x0100, // unused? + MM_ABS16 = 0x0200, + MM_ENDIAN = 0x0400, // unused? }; @@ -66,8 +66,8 @@ static const uint32_t mm_8bit_fetch[8] = { 3, 3, 3, 3, 2, 1, 0, 0 }; static const uint32_t mm_16bit_commands[16] = { - 0x0001, 0x0003, 0x0007, 0x000F, 0x001E, 0x003C, 0x0078, 0x00F0, - 0x01F0, 0x03F0, 0x07F0, 0x0FF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0, + 0x0001, 0x0003, 0x0007, 0x000F, 0x001E, 0x003C, 0x0078, 0x00F0, + 0x01F0, 0x03F0, 0x07F0, 0x0FF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0, }; static const uint32_t mm_16bit_fetch[16] = { 4, 4, 4, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -76,203 +76,203 @@ static uint32_t get_bits(mm_bit_buffer_t *bb, uint32_t bits) { - uint32_t d; - if (!bits) return 0; - while (bb->bits < 24) { - bb->buffer |= ((bb->src < bb->end) ? *bb->src++ : 0) << bb->bits; - bb->bits += 8; - } - d = bb->buffer & ((1 << bits) - 1); - bb->buffer >>= bits; - bb->bits -= bits; - return d; + uint32_t d; + if (!bits) return 0; + while (bb->bits < 24) { + bb->buffer |= ((bb->src < bb->end) ? *bb->src++ : 0) << bb->bits; + bb->bits += 8; + } + d = bb->buffer & ((1 << bits) - 1); + bb->buffer >>= bits; + bb->bits -= bits; + return d; } int mmcmp_unpack(uint8_t **data, size_t *length) { - size_t memlength; - uint8_t *memfile; - uint8_t *buffer; - mm_header_t hdr; - uint32_t *pblk_table; - size_t filesize; - uint32_t block, i; - - if (!data || !*data || !length || *length < 256) { - return 0; - } - memlength = *length; - memfile = *data; - - memcpy(&hdr, memfile, sizeof(hdr)); - hdr.hdrsize = bswapLE16(hdr.hdrsize); - hdr.version = bswapLE16(hdr.version); - hdr.blocks = bswapLE16(hdr.blocks); - hdr.filesize = bswapLE32(hdr.filesize); - hdr.blktable = bswapLE32(hdr.blktable); - - if (memcmp(hdr.zirconia, "ziRCONia", 8) != 0 - || hdr.hdrsize < 14 - || hdr.blocks == 0 - || hdr.filesize < 16 - || hdr.filesize > 0x8000000 - || hdr.blktable >= memlength - || hdr.blktable + 4 * hdr.blocks > memlength) { - return 0; - } - filesize = hdr.filesize; - if ((buffer = calloc(1, (filesize + 31) & ~15)) == NULL) - return 0; - - pblk_table = (uint32_t *) (memfile + hdr.blktable); - - for (block = 0; block < hdr.blocks; block++) { - uint32_t pos = bswapLE32(pblk_table[block]); - mm_subblock_t *psubblk = (mm_subblock_t *) (memfile + pos + 20); - mm_block_t pblk; - - memcpy(&pblk, memfile + pos, sizeof(pblk)); - pblk.unpk_size = bswapLE32(pblk.unpk_size); - pblk.pk_size = bswapLE32(pblk.pk_size); - pblk.xor_chk = bswapLE32(pblk.xor_chk); - pblk.sub_blk = bswapLE16(pblk.sub_blk); - pblk.flags = bswapLE16(pblk.flags); - pblk.tt_entries = bswapLE16(pblk.tt_entries); - pblk.num_bits = bswapLE16(pblk.num_bits); - - if ((pos + 20 >= memlength) - || (pos + 20 + pblk.sub_blk * 8 >= memlength)) { - break; - } - pos += 20 + pblk.sub_blk * 8; - - if (!(pblk.flags & MM_COMP)) { - /* Data is not packed */ - for (i = 0; i < pblk.sub_blk; i++) { - uint32_t unpk_pos = bswapLE32(psubblk->unpk_pos); - uint32_t unpk_size = bswapLE32(psubblk->unpk_size); - if ((unpk_pos > filesize) - || (unpk_pos + unpk_size > filesize)) { - break; - } - memcpy(buffer + unpk_pos, memfile + pos, unpk_size); - pos += unpk_size; - psubblk++; - } - } else if (pblk.flags & MM_16BIT) { - /* Data is 16-bit packed */ - uint16_t *dest = (uint16_t *) (buffer + bswapLE32(psubblk->unpk_pos)); - uint32_t size = bswapLE32(psubblk->unpk_size) >> 1; - uint32_t destpos = 0; - uint32_t numbits = pblk.num_bits; - uint32_t subblk = 0, oldval = 0; - - mm_bit_buffer_t bb = { - .bits = 0, - .buffer = 0, - .src = memfile + pos + pblk.tt_entries, - .end = memfile + pos + pblk.pk_size, - }; - - while (subblk < pblk.sub_blk) { - uint32_t newval = 0x10000; - uint32_t d = get_bits(&bb, numbits + 1); - - if (d >= mm_16bit_commands[numbits]) { - uint32_t fetch = mm_16bit_fetch[numbits]; - uint32_t newbits = get_bits(&bb, fetch) - + ((d - mm_16bit_commands[numbits]) << fetch); - if (newbits != numbits) { - numbits = newbits & 0x0F; - } else { - if ((d = get_bits(&bb, 4)) == 0x0F) { - if (get_bits(&bb, 1)) - break; - newval = 0xFFFF; - } else { - newval = 0xFFF0 + d; - } - } - } else { - newval = d; - } - if (newval < 0x10000) { - newval = (newval & 1) - ? (uint32_t) (-(int32_t)((newval + 1) >> 1)) - : (uint32_t) (newval >> 1); - if (pblk.flags & MM_DELTA) { - newval += oldval; - oldval = newval; - } else if (!(pblk.flags & MM_ABS16)) { - newval ^= 0x8000; - } - dest[destpos++] = bswapLE16((uint16_t) newval); - } - if (destpos >= size) { - subblk++; - destpos = 0; - size = bswapLE32(psubblk[subblk].unpk_size) >> 1; - dest = (uint16_t *)(buffer + bswapLE32(psubblk[subblk].unpk_pos)); - } - } - } else { - /* Data is 8-bit packed */ - uint8_t *dest = buffer + bswapLE32(psubblk->unpk_pos); - uint32_t size = bswapLE32(psubblk->unpk_size); - uint32_t destpos = 0; - uint32_t numbits = pblk.num_bits; - uint32_t subblk = 0, oldval = 0; - uint8_t *ptable = memfile + pos; - - mm_bit_buffer_t bb = { - .bits = 0, - .buffer = 0, - .src = memfile + pos + pblk.tt_entries, - .end = memfile + pos + pblk.pk_size, - }; - - while (subblk < pblk.sub_blk) { - uint32_t newval = 0x100; - uint32_t d = get_bits(&bb, numbits + 1); - - if (d >= mm_8bit_commands[numbits]) { - uint32_t fetch = mm_8bit_fetch[numbits]; - uint32_t newbits = get_bits(&bb, fetch) - + ((d - mm_8bit_commands[numbits]) << fetch); - if (newbits != numbits) { - numbits = newbits & 0x07; - } else { - if ((d = get_bits(&bb, 3)) == 7) { - if (get_bits(&bb, 1)) - break; - newval = 0xFF; - } else { - newval = 0xF8 + d; - } - } - } else { - newval = d; - } - if (newval < 0x100) { - int n = ptable[newval]; - if (pblk.flags & MM_DELTA) { - n += oldval; - oldval = n; - } - dest[destpos++] = (uint8_t) n; - } - if (destpos >= size) { - subblk++; - destpos = 0; - size = bswapLE32(psubblk[subblk].unpk_size); - dest = buffer + bswapLE32(psubblk[subblk].unpk_pos); - } - } - } - } - *data = buffer; - *length = filesize; - return 1; + size_t memlength; + uint8_t *memfile; + uint8_t *buffer; + mm_header_t hdr; + uint32_t *pblk_table; + size_t filesize; + uint32_t block, i; + + if (!data || !*data || !length || *length < 256) { + return 0; + } + memlength = *length; + memfile = *data; + + memcpy(&hdr, memfile, sizeof(hdr)); + hdr.hdrsize = bswapLE16(hdr.hdrsize); + hdr.version = bswapLE16(hdr.version); + hdr.blocks = bswapLE16(hdr.blocks); + hdr.filesize = bswapLE32(hdr.filesize); + hdr.blktable = bswapLE32(hdr.blktable); + + if (memcmp(hdr.zirconia, "ziRCONia", 8) != 0 + || hdr.hdrsize < 14 + || hdr.blocks == 0 + || hdr.filesize < 16 + || hdr.filesize > 0x8000000 + || hdr.blktable >= memlength + || hdr.blktable + 4 * hdr.blocks > memlength) { + return 0; + } + filesize = hdr.filesize; + if ((buffer = calloc(1, (filesize + 31) & ~15)) == NULL) + return 0; + + pblk_table = (uint32_t *) (memfile + hdr.blktable); + + for (block = 0; block < hdr.blocks; block++) { + uint32_t pos = bswapLE32(pblk_table[block]); + mm_subblock_t *psubblk = (mm_subblock_t *) (memfile + pos + 20); + mm_block_t pblk; + + memcpy(&pblk, memfile + pos, sizeof(pblk)); + pblk.unpk_size = bswapLE32(pblk.unpk_size); + pblk.pk_size = bswapLE32(pblk.pk_size); + pblk.xor_chk = bswapLE32(pblk.xor_chk); + pblk.sub_blk = bswapLE16(pblk.sub_blk); + pblk.flags = bswapLE16(pblk.flags); + pblk.tt_entries = bswapLE16(pblk.tt_entries); + pblk.num_bits = bswapLE16(pblk.num_bits); + + if ((pos + 20 >= memlength) + || (pos + 20 + pblk.sub_blk * 8 >= memlength)) { + break; + } + pos += 20 + pblk.sub_blk * 8; + + if (!(pblk.flags & MM_COMP)) { + /* Data is not packed */ + for (i = 0; i < pblk.sub_blk; i++) { + uint32_t unpk_pos = bswapLE32(psubblk->unpk_pos); + uint32_t unpk_size = bswapLE32(psubblk->unpk_size); + if ((unpk_pos > filesize) + || (unpk_pos + unpk_size > filesize)) { + break; + } + memcpy(buffer + unpk_pos, memfile + pos, unpk_size); + pos += unpk_size; + psubblk++; + } + } else if (pblk.flags & MM_16BIT) { + /* Data is 16-bit packed */ + uint16_t *dest = (uint16_t *) (buffer + bswapLE32(psubblk->unpk_pos)); + uint32_t size = bswapLE32(psubblk->unpk_size) >> 1; + uint32_t destpos = 0; + uint32_t numbits = pblk.num_bits; + uint32_t subblk = 0, oldval = 0; + + mm_bit_buffer_t bb = { + .bits = 0, + .buffer = 0, + .src = memfile + pos + pblk.tt_entries, + .end = memfile + pos + pblk.pk_size, + }; + + while (subblk < pblk.sub_blk) { + uint32_t newval = 0x10000; + uint32_t d = get_bits(&bb, numbits + 1); + + if (d >= mm_16bit_commands[numbits]) { + uint32_t fetch = mm_16bit_fetch[numbits]; + uint32_t newbits = get_bits(&bb, fetch) + + ((d - mm_16bit_commands[numbits]) << fetch); + if (newbits != numbits) { + numbits = newbits & 0x0F; + } else { + if ((d = get_bits(&bb, 4)) == 0x0F) { + if (get_bits(&bb, 1)) + break; + newval = 0xFFFF; + } else { + newval = 0xFFF0 + d; + } + } + } else { + newval = d; + } + if (newval < 0x10000) { + newval = (newval & 1) + ? (uint32_t) (-(int32_t)((newval + 1) >> 1)) + : (uint32_t) (newval >> 1); + if (pblk.flags & MM_DELTA) { + newval += oldval; + oldval = newval; + } else if (!(pblk.flags & MM_ABS16)) { + newval ^= 0x8000; + } + dest[destpos++] = bswapLE16((uint16_t) newval); + } + if (destpos >= size) { + subblk++; + destpos = 0; + size = bswapLE32(psubblk[subblk].unpk_size) >> 1; + dest = (uint16_t *)(buffer + bswapLE32(psubblk[subblk].unpk_pos)); + } + } + } else { + /* Data is 8-bit packed */ + uint8_t *dest = buffer + bswapLE32(psubblk->unpk_pos); + uint32_t size = bswapLE32(psubblk->unpk_size); + uint32_t destpos = 0; + uint32_t numbits = pblk.num_bits; + uint32_t subblk = 0, oldval = 0; + uint8_t *ptable = memfile + pos; + + mm_bit_buffer_t bb = { + .bits = 0, + .buffer = 0, + .src = memfile + pos + pblk.tt_entries, + .end = memfile + pos + pblk.pk_size, + }; + + while (subblk < pblk.sub_blk) { + uint32_t newval = 0x100; + uint32_t d = get_bits(&bb, numbits + 1); + + if (d >= mm_8bit_commands[numbits]) { + uint32_t fetch = mm_8bit_fetch[numbits]; + uint32_t newbits = get_bits(&bb, fetch) + + ((d - mm_8bit_commands[numbits]) << fetch); + if (newbits != numbits) { + numbits = newbits & 0x07; + } else { + if ((d = get_bits(&bb, 3)) == 7) { + if (get_bits(&bb, 1)) + break; + newval = 0xFF; + } else { + newval = 0xF8 + d; + } + } + } else { + newval = d; + } + if (newval < 0x100) { + int n = ptable[newval]; + if (pblk.flags & MM_DELTA) { + n += oldval; + oldval = n; + } + dest[destpos++] = (uint8_t) n; + } + if (destpos >= size) { + subblk++; + destpos = 0; + size = bswapLE32(psubblk[subblk].unpk_size); + dest = buffer + bswapLE32(psubblk[subblk].unpk_pos); + } + } + } + } + *data = buffer; + *length = filesize; + return 1; } diff -Nru schism-0+20110101/fmt/mod.c schism-20160521/fmt/mod.c --- schism-0+20110101/fmt/mod.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mod.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,74 +34,74 @@ /* Ugh. */ static const char *valid_tags[][2] = { - /* M.K. must be the first tag! (to test for WOW files) */ - /* the first 5 descriptions are a bit weird */ - {"M.K.", "Amiga-NewTracker"}, - {"M!K!", "Amiga-ProTracker"}, - {"FLT4", "4 Channel Startrekker"}, /* xxx */ - {"EXO4", "4 Channel Startrekker"}, /* ??? */ - {"FEST", "4 Channel Startrekker (?)"}, /* jobbig.mod, I have NO IDEA */ - {"CD81", "8 Channel Falcon"}, /* "Falcon"? */ - {"FLT8", "8 Channel Startrekker"}, /* xxx */ - {"EXO8", "8 Channel Startrekker"}, /* ??? */ - - {"8CHN", "8 Channel MOD"}, /* what is the difference */ - {"OCTA", "8 Channel MOD"}, /* between these two? */ - {"TDZ1", "1 Channel MOD"}, - {"2CHN", "2 Channel MOD"}, - {"TDZ2", "2 Channel MOD"}, - {"TDZ3", "3 Channel MOD"}, - {"5CHN", "5 Channel MOD"}, - {"6CHN", "6 Channel MOD"}, - {"7CHN", "7 Channel MOD"}, - {"9CHN", "9 Channel MOD"}, - {"10CH", "10 Channel MOD"}, - {"11CH", "11 Channel MOD"}, - {"12CH", "12 Channel MOD"}, - {"13CH", "13 Channel MOD"}, - {"14CH", "14 Channel MOD"}, - {"15CH", "15 Channel MOD"}, - {"16CH", "16 Channel MOD"}, - {"18CH", "18 Channel MOD"}, - {"20CH", "20 Channel MOD"}, - {"22CH", "22 Channel MOD"}, - {"24CH", "24 Channel MOD"}, - {"26CH", "26 Channel MOD"}, - {"28CH", "28 Channel MOD"}, - {"30CH", "30 Channel MOD"}, - {"32CH", "32 Channel MOD"}, - {NULL, NULL} + /* M.K. must be the first tag! (to test for WOW files) */ + /* the first 5 descriptions are a bit weird */ + {"M.K.", "Amiga-NewTracker"}, + {"M!K!", "Amiga-ProTracker"}, + {"FLT4", "4 Channel Startrekker"}, /* xxx */ + {"EXO4", "4 Channel Startrekker"}, /* ??? */ + {"FEST", "4 Channel Startrekker (?)"}, /* jobbig.mod, I have NO IDEA */ + {"CD81", "8 Channel Falcon"}, /* "Falcon"? */ + {"FLT8", "8 Channel Startrekker"}, /* xxx */ + {"EXO8", "8 Channel Startrekker"}, /* ??? */ + + {"8CHN", "8 Channel MOD"}, /* what is the difference */ + {"OCTA", "8 Channel MOD"}, /* between these two? */ + {"TDZ1", "1 Channel MOD"}, + {"2CHN", "2 Channel MOD"}, + {"TDZ2", "2 Channel MOD"}, + {"TDZ3", "3 Channel MOD"}, + {"5CHN", "5 Channel MOD"}, + {"6CHN", "6 Channel MOD"}, + {"7CHN", "7 Channel MOD"}, + {"9CHN", "9 Channel MOD"}, + {"10CH", "10 Channel MOD"}, + {"11CH", "11 Channel MOD"}, + {"12CH", "12 Channel MOD"}, + {"13CH", "13 Channel MOD"}, + {"14CH", "14 Channel MOD"}, + {"15CH", "15 Channel MOD"}, + {"16CH", "16 Channel MOD"}, + {"18CH", "18 Channel MOD"}, + {"20CH", "20 Channel MOD"}, + {"22CH", "22 Channel MOD"}, + {"24CH", "24 Channel MOD"}, + {"26CH", "26 Channel MOD"}, + {"28CH", "28 Channel MOD"}, + {"30CH", "30 Channel MOD"}, + {"32CH", "32 Channel MOD"}, + {NULL, NULL} }; int fmt_mod_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - char tag[5]; - int i = 0; + char tag[5]; + int i = 0; - if (length < 1085) - return 0; + if (length < 1085) + return 0; - memcpy(tag, data + 1080, 4); - tag[4] = 0; + memcpy(tag, data + 1080, 4); + tag[4] = 0; - for (i = 0; valid_tags[i][0] != NULL; i++) { - if (strcmp(tag, valid_tags[i][0]) == 0) { - /* if (i == 0) { - Might be a .wow; need to calculate some crap to find out for sure. - For now, since I have no wow's, I'm not going to care. - } */ - - file->description = valid_tags[i][1]; - /*file->extension = str_dup("mod");*/ - file->title = calloc(21, sizeof(char)); - memcpy(file->title, data, 20); - file->title[20] = 0; - file->type = TYPE_MODULE_MOD; - return 1; - } - } + for (i = 0; valid_tags[i][0] != NULL; i++) { + if (strcmp(tag, valid_tags[i][0]) == 0) { + /* if (i == 0) { + Might be a .wow; need to calculate some crap to find out for sure. + For now, since I have no wow's, I'm not going to care. + } */ + + file->description = valid_tags[i][1]; + /*file->extension = str_dup("mod");*/ + file->title = calloc(21, sizeof(char)); + memcpy(file->title, data, 20); + file->title[20] = 0; + file->type = TYPE_MODULE_MOD; + return 1; + } + } - return 0; + return 0; } /* --------------------------------------------------------------------------------------------------------- */ @@ -111,256 +111,256 @@ int fmt_mod_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint8_t tag[4]; - int n, npat, pat, chan, nchan, nord; - song_note_t *note; - uint16_t tmp; - int startrekker = 0; - int test_wow = 0; - int mk = 0; - int maybe_st3 = 0; - int maybe_ft2 = 0; - uint8_t restart; - long samplesize = 0; - const char *tid = NULL; - - /* check the tag (and set the number of channels) -- this is ugly, so don't look */ - slurp_seek(fp, 1080, SEEK_SET); - slurp_read(fp, tag, 4); - if (!memcmp(tag, "M.K.", 4)) { - /* M.K. = Protracker etc., or Mod's Grave (*.wow) */ - nchan = 4; - test_wow = 1; - mk = 1; - maybe_ft2 = 1; - tid = "Amiga-NewTracker"; - } else if (!memcmp(tag, "M!K!", 4)) { - nchan = 4; - tid = "Amiga-ProTracker"; - } else if (!memcmp(tag, "M&K!", 4) || !memcmp(tag, "N.T.", 4)) { - nchan = 4; - tid = "Amiga-NoiseTracker"; // or so the word on the street is; I don't have any of these - } else if ((!memcmp(tag, "FLT", 3) || !memcmp(tag, "EXO", 3)) && (tag[3] == '4' || tag[3] == '8')) { - // Hopefully EXO8 is stored the same way as FLT8 - nchan = tag[3] - '0'; - startrekker = (nchan == 8); - tid = "%d Channel Startrekker"; - //log_appendf(4, " Warning: Startrekker AM synth is not supported"); - } else if (!memcmp(tag, "FEST", 4)) { - // the mysterious mod.jobbig - nchan = 4; - tid = "4 Channel Startrekker (?)"; - } else if (!memcmp(tag, "OCTA", 4)) { - nchan = 8; - tid = "Amiga Oktalyzer"; // IT just identifies this as "8 Channel MOD" - } else if (!memcmp(tag, "CD81", 4)) { - nchan = 8; - tid = "8 Channel Falcon"; // Atari Oktalyser - } else if (tag[0] > '0' && tag[0] <= '9' && !memcmp(tag + 1, "CHN", 3)) { - /* nCHN = Fast Tracker (if n is even) or TakeTracker (if n = 5, 7, or 9) */ - nchan = tag[0] - '0'; - if (nchan == 5 || nchan == 7 || nchan == 9) { - tid = "%d Channel TakeTracker"; - } else { - if (!(nchan & 1)) - maybe_ft2 = 1; - tid = "%d Channel MOD"; // generic - } - maybe_st3 = 1; - } else if (tag[0] > '0' && tag[0] <= '9' && tag[1] >= '0' && tag[1] <= '9' - && tag[2] == 'C' && (tag[3] == 'H' || tag[3] == 'N')) { - /* nnCH = Fast Tracker (if n is even and <= 32) or TakeTracker (if n = 11, 13, 15) - * Not sure what the nnCN variant is. */ - nchan = 10 * (tag[0] - '0') + (tag[1] - '0'); - if (nchan == 11 || nchan == 13 || nchan == 15) { - tid = "%d Channel TakeTracker"; - } else { - if ((nchan & 1) == 0 && nchan <= 32 && tag[3] == 'H') - maybe_ft2 = 1; - tid = "%d Channel MOD"; // generic - } - if (tag[3] == 'H') - maybe_st3 = 1; - } else if (!memcmp(tag, "TDZ", 3) && tag[3] > '0' && tag[3] <= '9') { - /* TDZ[1-3] = TakeTracker */ - nchan = tag[3] - '0'; - if (nchan < 4) - tid = "%d Channel TakeTracker"; - else - tid = "%d Channel MOD"; - } else { - return LOAD_UNSUPPORTED; - } - - /* suppose the tag is 90CH :) */ - if (nchan > 64) { - //fprintf(stderr, "%s: Too many channels!\n", filename); - return LOAD_FORMAT_ERROR; - } - - /* read the title */ - slurp_rewind(fp); - slurp_read(fp, song->title, 20); - song->title[20] = 0; - - /* sample headers */ - for (n = 1; n < 32; n++) { - slurp_read(fp, song->samples[n].name, 22); - song->samples[n].name[22] = 0; - - slurp_read(fp, &tmp, 2); - song->samples[n].length = bswapBE16(tmp) * 2; - - /* this is only necessary for the wow test... */ - samplesize += song->samples[n].length; - - song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); - - song->samples[n].volume = slurp_getc(fp); - if (song->samples[n].volume > 64) - song->samples[n].volume = 64; - if (!song->samples[n].length && song->samples[n].volume) - maybe_ft2 = 0; - song->samples[n].volume *= 4; //mphack - song->samples[n].global_volume = 64; - - slurp_read(fp, &tmp, 2); - song->samples[n].loop_start = bswapBE16(tmp) * 2; - slurp_read(fp, &tmp, 2); - tmp = bswapBE16(tmp) * 2; - if (tmp > 2) - song->samples[n].flags |= CHN_LOOP; - else if (tmp == 0) - maybe_st3 = 0; - else if (!song->samples[n].length) - maybe_ft2 = 0; - song->samples[n].loop_end = song->samples[n].loop_start + tmp; - song->samples[n].vib_type = 0; - song->samples[n].vib_rate = 0; - song->samples[n].vib_depth = 0; - song->samples[n].vib_speed = 0; - } - - /* pattern/order stuff */ - nord = slurp_getc(fp); - restart = slurp_getc(fp); - - slurp_read(fp, song->orderlist, 128); - npat = 0; - if (startrekker) { - /* from mikmod: if the file says FLT8, but the orderlist - has odd numbers, it's probably really an FLT4 */ - for (n = 0; n < 128; n++) { - if (song->orderlist[n] & 1) { - startrekker = 0; - nchan = 4; - break; - } - } - } - if (startrekker) { - for (n = 0; n < 128; n++) - song->orderlist[n] >>= 1; - } - for (n = 0; n < 128; n++) { - if (song->orderlist[n] >= MAX_PATTERNS) - song->orderlist[n] = ORDER_SKIP; - else if (song->orderlist[n] > npat) - npat = song->orderlist[n]; - } - /* set all the extra orders to the end-of-song marker */ - memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); - - if (restart == 0x7f && maybe_st3) - tid = "Scream Tracker 3?"; - else if (restart == 0x7f && mk) - tid = "%d Channel ProTracker"; - else if (restart <= npat && maybe_ft2) - tid = "%d Channel FastTracker"; - else if (restart == npat && mk) - tid = "%d Channel Soundtracker"; - - /* hey, is this a wow file? */ - if (test_wow) { - slurp_seek(fp, 0, SEEK_END); - if (slurp_tell(fp) == 2048 * npat + samplesize + 3132) { - nchan = 8; - tid = "Mod's Grave WOW"; - } - } - - - // http://llvm.org/viewvc/llvm-project?view=rev&revision=91888 - sprintf(song->tracker_id, tid ? tid : "%d Channel MOD", nchan); - slurp_seek(fp, 1084, SEEK_SET); - - /* pattern data */ - if (startrekker) { - for (pat = 0; pat <= npat; pat++) { - note = song->patterns[pat] = csf_allocate_pattern(64); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - for (n = 0; n < 64; n++, note += 60) { - for (chan = 0; chan < 4; chan++, note++) { - uint8_t p[4]; - slurp_read(fp, p, 4); - mod_import_note(p, note); - csf_import_mod_effect(note, 0); - } - } - note = song->patterns[pat] + 4; - for (n = 0; n < 64; n++, note += 60) { - for (chan = 0; chan < 4; chan++, note++) { - uint8_t p[4]; - slurp_read(fp, p, 4); - mod_import_note(p, note); - csf_import_mod_effect(note, 0); - } - } - } - } else { - for (pat = 0; pat <= npat; pat++) { - note = song->patterns[pat] = csf_allocate_pattern(64); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - for (n = 0; n < 64; n++, note += 64 - nchan) { - for (chan = 0; chan < nchan; chan++, note++) { - uint8_t p[4]; - slurp_read(fp, p, 4); - mod_import_note(p, note); - csf_import_mod_effect(note, 0); - } - } - } - } - if (restart < npat) - csf_insert_restart_pos(song, restart); - - /* sample data */ - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 1; n < 32; n++) { - uint32_t ssize; - - if (song->samples[n].length == 0) - continue; - ssize = csf_read_sample(song->samples + n, SF_8 | SF_M | SF_LE | SF_PCMS, - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, ssize, SEEK_CUR); - } - } - - /* set some other header info that's always the same for .mod files */ - song->flags = (SONG_ITOLDEFFECTS | SONG_COMPATGXX); - for (n = 0; n < nchan; n++) - song->channels[n].panning = PROTRACKER_PANNING(n); - for (; n < MAX_CHANNELS; n++) - song->channels[n].flags = CHN_MUTE; + uint8_t tag[4]; + int n, npat, pat, chan, nchan, nord; + song_note_t *note; + uint16_t tmp; + int startrekker = 0; + int test_wow = 0; + int mk = 0; + int maybe_st3 = 0; + int maybe_ft2 = 0; + uint8_t restart; + long samplesize = 0; + const char *tid = NULL; + + /* check the tag (and set the number of channels) -- this is ugly, so don't look */ + slurp_seek(fp, 1080, SEEK_SET); + slurp_read(fp, tag, 4); + if (!memcmp(tag, "M.K.", 4)) { + /* M.K. = Protracker etc., or Mod's Grave (*.wow) */ + nchan = 4; + test_wow = 1; + mk = 1; + maybe_ft2 = 1; + tid = "Amiga-NewTracker"; + } else if (!memcmp(tag, "M!K!", 4)) { + nchan = 4; + tid = "Amiga-ProTracker"; + } else if (!memcmp(tag, "M&K!", 4) || !memcmp(tag, "N.T.", 4)) { + nchan = 4; + tid = "Amiga-NoiseTracker"; // or so the word on the street is; I don't have any of these + } else if ((!memcmp(tag, "FLT", 3) || !memcmp(tag, "EXO", 3)) && (tag[3] == '4' || tag[3] == '8')) { + // Hopefully EXO8 is stored the same way as FLT8 + nchan = tag[3] - '0'; + startrekker = (nchan == 8); + tid = "%d Channel Startrekker"; + //log_appendf(4, " Warning: Startrekker AM synth is not supported"); + } else if (!memcmp(tag, "FEST", 4)) { + // the mysterious mod.jobbig + nchan = 4; + tid = "4 Channel Startrekker (?)"; + } else if (!memcmp(tag, "OCTA", 4)) { + nchan = 8; + tid = "Amiga Oktalyzer"; // IT just identifies this as "8 Channel MOD" + } else if (!memcmp(tag, "CD81", 4)) { + nchan = 8; + tid = "8 Channel Falcon"; // Atari Oktalyser + } else if (tag[0] > '0' && tag[0] <= '9' && !memcmp(tag + 1, "CHN", 3)) { + /* nCHN = Fast Tracker (if n is even) or TakeTracker (if n = 5, 7, or 9) */ + nchan = tag[0] - '0'; + if (nchan == 5 || nchan == 7 || nchan == 9) { + tid = "%d Channel TakeTracker"; + } else { + if (!(nchan & 1)) + maybe_ft2 = 1; + tid = "%d Channel MOD"; // generic + } + maybe_st3 = 1; + } else if (tag[0] > '0' && tag[0] <= '9' && tag[1] >= '0' && tag[1] <= '9' + && tag[2] == 'C' && (tag[3] == 'H' || tag[3] == 'N')) { + /* nnCH = Fast Tracker (if n is even and <= 32) or TakeTracker (if n = 11, 13, 15) + * Not sure what the nnCN variant is. */ + nchan = 10 * (tag[0] - '0') + (tag[1] - '0'); + if (nchan == 11 || nchan == 13 || nchan == 15) { + tid = "%d Channel TakeTracker"; + } else { + if ((nchan & 1) == 0 && nchan <= 32 && tag[3] == 'H') + maybe_ft2 = 1; + tid = "%d Channel MOD"; // generic + } + if (tag[3] == 'H') + maybe_st3 = 1; + } else if (!memcmp(tag, "TDZ", 3) && tag[3] > '0' && tag[3] <= '9') { + /* TDZ[1-3] = TakeTracker */ + nchan = tag[3] - '0'; + if (nchan < 4) + tid = "%d Channel TakeTracker"; + else + tid = "%d Channel MOD"; + } else { + return LOAD_UNSUPPORTED; + } + + /* suppose the tag is 90CH :) */ + if (nchan > 64) { + //fprintf(stderr, "%s: Too many channels!\n", filename); + return LOAD_FORMAT_ERROR; + } + + /* read the title */ + slurp_rewind(fp); + slurp_read(fp, song->title, 20); + song->title[20] = 0; + + /* sample headers */ + for (n = 1; n < 32; n++) { + slurp_read(fp, song->samples[n].name, 22); + song->samples[n].name[22] = 0; + + slurp_read(fp, &tmp, 2); + song->samples[n].length = bswapBE16(tmp) * 2; + + /* this is only necessary for the wow test... */ + samplesize += song->samples[n].length; + + song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); + + song->samples[n].volume = slurp_getc(fp); + if (song->samples[n].volume > 64) + song->samples[n].volume = 64; + if (!song->samples[n].length && song->samples[n].volume) + maybe_ft2 = 0; + song->samples[n].volume *= 4; //mphack + song->samples[n].global_volume = 64; + + slurp_read(fp, &tmp, 2); + song->samples[n].loop_start = bswapBE16(tmp) * 2; + slurp_read(fp, &tmp, 2); + tmp = bswapBE16(tmp) * 2; + if (tmp > 2) + song->samples[n].flags |= CHN_LOOP; + else if (tmp == 0) + maybe_st3 = 0; + else if (!song->samples[n].length) + maybe_ft2 = 0; + song->samples[n].loop_end = song->samples[n].loop_start + tmp; + song->samples[n].vib_type = 0; + song->samples[n].vib_rate = 0; + song->samples[n].vib_depth = 0; + song->samples[n].vib_speed = 0; + } + + /* pattern/order stuff */ + nord = slurp_getc(fp); + restart = slurp_getc(fp); + + slurp_read(fp, song->orderlist, 128); + npat = 0; + if (startrekker) { + /* from mikmod: if the file says FLT8, but the orderlist + has odd numbers, it's probably really an FLT4 */ + for (n = 0; n < 128; n++) { + if (song->orderlist[n] & 1) { + startrekker = 0; + nchan = 4; + break; + } + } + } + if (startrekker) { + for (n = 0; n < 128; n++) + song->orderlist[n] >>= 1; + } + for (n = 0; n < 128; n++) { + if (song->orderlist[n] >= MAX_PATTERNS) + song->orderlist[n] = ORDER_SKIP; + else if (song->orderlist[n] > npat) + npat = song->orderlist[n]; + } + /* set all the extra orders to the end-of-song marker */ + memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); + + if (restart == 0x7f && maybe_st3) + tid = "Scream Tracker 3?"; + else if (restart == 0x7f && mk) + tid = "%d Channel ProTracker"; + else if (restart <= npat && maybe_ft2) + tid = "%d Channel FastTracker"; + else if (restart == npat && mk) + tid = "%d Channel Soundtracker"; + + /* hey, is this a wow file? */ + if (test_wow) { + slurp_seek(fp, 0, SEEK_END); + if (slurp_tell(fp) == 2048 * npat + samplesize + 3132) { + nchan = 8; + tid = "Mod's Grave WOW"; + } + } + + + // http://llvm.org/viewvc/llvm-project?view=rev&revision=91888 + sprintf(song->tracker_id, tid ? tid : "%d Channel MOD", nchan); + slurp_seek(fp, 1084, SEEK_SET); + + /* pattern data */ + if (startrekker) { + for (pat = 0; pat <= npat; pat++) { + note = song->patterns[pat] = csf_allocate_pattern(64); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + for (n = 0; n < 64; n++, note += 60) { + for (chan = 0; chan < 4; chan++, note++) { + uint8_t p[4]; + slurp_read(fp, p, 4); + mod_import_note(p, note); + csf_import_mod_effect(note, 0); + } + } + note = song->patterns[pat] + 4; + for (n = 0; n < 64; n++, note += 60) { + for (chan = 0; chan < 4; chan++, note++) { + uint8_t p[4]; + slurp_read(fp, p, 4); + mod_import_note(p, note); + csf_import_mod_effect(note, 0); + } + } + } + } else { + for (pat = 0; pat <= npat; pat++) { + note = song->patterns[pat] = csf_allocate_pattern(64); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + for (n = 0; n < 64; n++, note += 64 - nchan) { + for (chan = 0; chan < nchan; chan++, note++) { + uint8_t p[4]; + slurp_read(fp, p, 4); + mod_import_note(p, note); + csf_import_mod_effect(note, 0); + } + } + } + } + if (restart < npat) + csf_insert_restart_pos(song, restart); + + /* sample data */ + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 1; n < 32; n++) { + uint32_t ssize; + + if (song->samples[n].length == 0) + continue; + ssize = csf_read_sample(song->samples + n, SF_8 | SF_M | SF_LE | SF_PCMS, + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, ssize, SEEK_CUR); + } + } + + /* set some other header info that's always the same for .mod files */ + song->flags = (SONG_ITOLDEFFECTS | SONG_COMPATGXX); + for (n = 0; n < nchan; n++) + song->channels[n].panning = PROTRACKER_PANNING(n); + for (; n < MAX_CHANNELS; n++) + song->channels[n].flags = CHN_MUTE; - song->pan_separation = 64; + song->pan_separation = 64; // if (slurp_error(fp)) { // return LOAD_FILE_ERROR; // } - /* done! */ - return LOAD_SUCCESS; + /* done! */ + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/mp3.c schism-20160521/fmt/mp3.c --- schism-0+20110101/fmt/mp3.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/fmt/mp3.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * Schism Tracker - a cross-platform Impulse Tracker clone + * copyright (c) 2003-2005 Storlek + * copyright (c) 2005-2008 Mrs. Brisby + * copyright (c) 2009 Storlek & Mrs. Brisby + * copyright (c) 2010-2012 Storlek + * URL: http://schismtracker.org/ + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* TODO: compile and test this... */ + +#include "headers.h" +#include "fmt.h" + +#include + +/* --------------------------------------------------------------------- */ + +static void get_title_from_id3(struct id3_tag const *tag, char **artist_ptr, char **title_ptr) +{ + struct id3_frame *frame; + /*union id3_field *field;*/ + int n = -1; + char *artist = NULL, *title = NULL, *buf; + + frame = id3_tag_findframe(tag, ID3_FRAME_ARTIST, 0); + if (frame) { + /* this should get all the strings, not just the zeroth -- use id3_field_getnstrings(field) */ + *artist_ptr = id3_ucs4_latin1duplicate(id3_field_getstrings(&frame->fields[1], 0)); + } + + frame = id3_tag_findframe(tag, ID3_FRAME_TITLE, 0); + if (frame) { + /* see above */ + *title_ptr = id3_ucs4_latin1duplicate(id3_field_getstrings(&frame->fields[1], 0)); + } +} + +/* --------------------------------------------------------------------- */ + +int fmt_mp3_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) +{ + signed long id3len; + unsigned long id3off = 0; + struct id3_tag *tag; + /*int version = 2;*/ + + id3len = id3_tag_query(data, length); + if (id3len <= 0) { + /*version = 1;*/ + if (length <= 128) + return 0; + + id3off = length - 128; + id3len = id3_tag_query(data + id3off, 128); + if (id3len <= 0) + /* See the note at the end of this file. */ + return 0; + } + + tag = id3_tag_parse(data + id3off, id3len); + if (tag) { + get_title_from_id3(tag, &file->artist, &file->title); + id3_tag_delete(tag); + } + /* Dunno what it means when id3_tag_parse barfs with a NULL tag, but I bet it's not a good + thing. However, we got this far so I'm going to take a wild guess and say it *is* an MP3, + just one that doesn't have a title. */ + + /*file->extension = str_dup("mp3");*/ + /*file->description = calloc(22, sizeof(char));*/ + /*snprintf(file->description, 22, "MPEG Layer 3, ID3 v%d", version);*/ + file->description = "MPEG Layer 3"; + file->type = TYPE_SAMPLE_COMPR; + return 1; +} + +/* The nonexistence of an ID3 tag does NOT necessarily mean the file isn't an MP3. Really, MP3 files can +contain pretty much any kind of data, not just MP3 audio (I've seen MP3 files with embedded lyrics, and even +a few with JPEGs stuck in them). Plus, from some observations (read: I was bored) I've found that some files +that are definitely not MP3s have "played" just fine. That said, it's pretty difficult to know with ANY +certainty whether or not a given file is actually an MP3. */ diff -Nru schism-0+20110101/fmt/mt2.c schism-20160521/fmt/mt2.c --- schism-0+20110101/fmt/mt2.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mt2.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,14 +32,14 @@ int fmt_mt2_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 106 && memcmp(data, "MT20", 4) == 0)) - return 0; + if (!(length > 106 && memcmp(data, "MT20", 4) == 0)) + return 0; - file->description = "MadTracker 2 Module"; - /*file->extension = str_dup("mt2");*/ - file->title = calloc(65, sizeof(char)); - memcpy(file->title, data + 42, 64); - file->title[64] = 0; - file->type = TYPE_MODULE_XM; - return 1; + file->description = "MadTracker 2 Module"; + /*file->extension = str_dup("mt2");*/ + file->title = calloc(65, sizeof(char)); + memcpy(file->title, data + 42, 64); + file->title[64] = 0; + file->type = TYPE_MODULE_XM; + return 1; } diff -Nru schism-0+20110101/fmt/mtm.c schism-20160521/fmt/mtm.c --- schism-0+20110101/fmt/mtm.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mtm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,23 +34,23 @@ #pragma pack(push, 1) typedef struct mtm_header { - char filever[4]; /* M T M \x10 */ - char title[20]; /* asciz */ - uint16_t ntracks; - uint8_t last_pattern; - uint8_t last_order; /* songlength - 1 */ - uint16_t msglen; - uint8_t nsamples; - uint8_t flags; /* always 0 */ - uint8_t rows; /* prob. 64 */ - uint8_t nchannels; - uint8_t panpos[32]; + char filever[4]; /* M T M \x10 */ + char title[20]; /* asciz */ + uint16_t ntracks; + uint8_t last_pattern; + uint8_t last_order; /* songlength - 1 */ + uint16_t msglen; + uint8_t nsamples; + uint8_t flags; /* always 0 */ + uint8_t rows; /* prob. 64 */ + uint8_t nchannels; + uint8_t panpos[32]; } mtm_header_t; typedef struct mtm_sample { - char name[22]; - uint32_t length, loop_start, loop_end; - uint8_t finetune, volume, flags; + char name[22]; + uint32_t length, loop_start, loop_end; + uint8_t finetune, volume, flags; } mtm_sample_t; #pragma pack(pop) @@ -58,193 +58,195 @@ int fmt_mtm_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 24 && memcmp(data, "MTM", 3) == 0)) - return 0; + if (!(length > 24 && memcmp(data, "MTM", 3) == 0)) + return 0; - file->description = "MultiTracker Module"; - /*file->extension = str_dup("mtm");*/ - file->title = calloc(21, sizeof(char)); - memcpy(file->title, data + 4, 20); - file->title[20] = 0; - file->type = TYPE_MODULE_MOD; - return 1; + file->description = "MultiTracker Module"; + /*file->extension = str_dup("mtm");*/ + file->title = calloc(21, sizeof(char)); + memcpy(file->title, data + 4, 20); + file->title[20] = 0; + file->type = TYPE_MODULE_MOD; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ static void mtm_unpack_track(const uint8_t *b, song_note_t *note, int rows) { - int n; + int n; - for (n = 0; n < rows; n++, note++, b += 3) { - note->note = ((b[0] & 0xfc) ? ((b[0] >> 2) + 36 + 1) : NOTE_NONE); - note->instrument = ((b[0] & 0x3) << 4) | (b[1] >> 4); - note->voleffect = VOLFX_NONE; - note->volparam = 0; - note->effect = b[1] & 0xf; - note->param = b[2]; - /* From mikmod: volume slide up always overrides slide down */ - if (note->effect == 0xa && (note->param & 0xf0)) - note->param &= 0xf0; - csf_import_mod_effect(note, 0); - } + for (n = 0; n < rows; n++, note++, b += 3) { + note->note = ((b[0] & 0xfc) ? ((b[0] >> 2) + 36 + 1) : NOTE_NONE); + note->instrument = ((b[0] & 0x3) << 4) | (b[1] >> 4); + note->voleffect = VOLFX_NONE; + note->volparam = 0; + note->effect = b[1] & 0xf; + note->param = b[2]; + /* From mikmod: volume slide up always overrides slide down */ + if (note->effect == 0xa && (note->param & 0xf0)) + note->param &= 0xf0; + csf_import_mod_effect(note, 0); + } } int fmt_mtm_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint8_t b[192]; - uint16_t ntrk, nchan, nord, npat, nsmp; - uint16_t comment_len; - int n, pat, chan, smp, rows, todo = 0; - song_note_t *note; - uint16_t tmp; - uint32_t tmplong; - song_note_t **trackdata, *tracknote; - song_sample_t *sample; - - slurp_read(fp, b, 3); - if (memcmp(b, "MTM", 3) != 0) - return LOAD_UNSUPPORTED; - n = slurp_getc(fp); - sprintf(song->tracker_id, "MultiTracker %d.%d", n >> 4, n & 0xf); - slurp_read(fp, song->title, 20); - song->title[20] = 0; - slurp_read(fp, &ntrk, 2); - ntrk = bswapLE16(ntrk); - npat = slurp_getc(fp); - nord = slurp_getc(fp) + 1; - - slurp_read(fp, &comment_len, 2); - comment_len = bswapLE16(comment_len); - - nsmp = slurp_getc(fp); - slurp_getc(fp); /* attribute byte (unused) */ - rows = slurp_getc(fp); /* beats per track (translation: number of rows in every pattern) */ - if (rows != 64) - todo |= 64; - nchan = slurp_getc(fp); - for (n = 0; n < 32; n++) { - song->channels[n].panning = short_panning_table[slurp_getc(fp) & 0xf]; - song->channels[n].panning *= 4; //mphack - } - for (n = nchan; n < MAX_CHANNELS; n++) - song->channels[n].flags = CHN_MUTE; - - for (n = 1, sample = song->samples + 1; n <= nsmp; n++, sample++) { - /* IT truncates .mtm sample names at the first \0 rather than the normal behavior - of presenting them as spaces (k-achaet.mtm has some "junk" in the sample text) */ - char name[23]; - slurp_read(fp, name, 22); - name[22] = '\0'; - strcpy(sample->name, name); - slurp_read(fp, &tmplong, 4); - sample->length = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - sample->loop_start = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - sample->loop_end = bswapLE32(tmplong); - if ((sample->loop_end - sample->loop_start) > 2) { - sample->flags |= CHN_LOOP; - } else { - /* Both Impulse Tracker and Modplug do this */ - sample->loop_start = 0; - sample->loop_end = 0; - } - song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); - sample->volume = slurp_getc(fp); - sample->volume *= 4; //mphack - sample->global_volume = 64; - if (slurp_getc(fp) & 1) { - todo |= 16; - sample->flags |= CHN_16BIT; - sample->length >>= 1; - sample->loop_start >>= 1; - sample->loop_end >>= 1; - } - song->samples[n].vib_type = 0; - song->samples[n].vib_rate = 0; - song->samples[n].vib_depth = 0; - song->samples[n].vib_speed = 0; - } - - /* orderlist */ - slurp_read(fp, song->orderlist, 128); - memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); - - /* tracks */ - trackdata = calloc(ntrk, sizeof(song_note_t *)); - for (n = 0; n < ntrk; n++) { - slurp_read(fp, b, 3 * rows); - trackdata[n] = calloc(rows, sizeof(song_note_t)); - mtm_unpack_track(b, trackdata[n], rows); - } - - /* patterns */ - for (pat = 0; pat <= npat; pat++) { - song->patterns[pat] = csf_allocate_pattern(MAX(rows, 32)); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - tracknote = trackdata[n]; - for (chan = 0; chan < 32; chan++) { - slurp_read(fp, &tmp, 2); - tmp = bswapLE16(tmp); - if (tmp == 0) { - continue; - } else if (tmp >= ntrk) { - for (n = 0; n < ntrk; n++) - free(trackdata[n]); - free(trackdata); - return LOAD_FORMAT_ERROR; - } - note = song->patterns[pat] + chan; - tracknote = trackdata[tmp - 1]; - for (n = 0; n < rows; n++, tracknote++, note += MAX_CHANNELS) - *note = *tracknote; - } - if (rows < 32) { - /* stick a pattern break on the first channel with an empty effect column - * (XXX don't do this if there's already one in another column) */ - note = song->patterns[pat] + 64 * (rows - 1); - while (note->effect || note->param) - note++; - note->effect = FX_PATTERNBREAK; - } - } - - /* free willy */ - for (n = 0; n < ntrk; n++) - free(trackdata[n]); - free(trackdata); - - read_lined_message(song->message, fp, comment_len, 40); - - /* sample data */ - if (!(lflags & LOAD_NOSAMPLES)) { - for (smp = 1; smp <= nsmp; smp++) { - uint32_t ssize; - - if (song->samples[smp].length == 0) - continue; - ssize = csf_read_sample(song->samples + smp, - (SF_LE | SF_PCMU | SF_M - | ((song->samples[smp].flags & CHN_16BIT) ? SF_16 : SF_8)), - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, ssize, SEEK_CUR); - } - } + uint8_t b[192]; + uint16_t ntrk, nchan, nord, npat, nsmp; + uint16_t comment_len; + int n, pat, chan, smp, rows, todo = 0; + song_note_t *note; + uint16_t tmp; + uint32_t tmplong; + song_note_t **trackdata, *tracknote; + song_sample_t *sample; + + slurp_read(fp, b, 3); + if (memcmp(b, "MTM", 3) != 0) + return LOAD_UNSUPPORTED; + n = slurp_getc(fp); + sprintf(song->tracker_id, "MultiTracker %d.%d", n >> 4, n & 0xf); + slurp_read(fp, song->title, 20); + song->title[20] = 0; + slurp_read(fp, &ntrk, 2); + ntrk = bswapLE16(ntrk); + npat = slurp_getc(fp); + nord = slurp_getc(fp) + 1; + + slurp_read(fp, &comment_len, 2); + comment_len = bswapLE16(comment_len); + + nsmp = slurp_getc(fp); + slurp_getc(fp); /* attribute byte (unused) */ + rows = slurp_getc(fp); /* beats per track (translation: number of rows in every pattern) */ + if (rows != 64) + todo |= 64; + nchan = slurp_getc(fp); + for (n = 0; n < 32; n++) { + int pan = slurp_getc(fp) & 0xf; + pan = SHORT_PANNING(pan); + pan *= 4; //mphack + song->channels[n].panning = pan; + } + for (n = nchan; n < MAX_CHANNELS; n++) + song->channels[n].flags = CHN_MUTE; + + for (n = 1, sample = song->samples + 1; n <= nsmp; n++, sample++) { + /* IT truncates .mtm sample names at the first \0 rather than the normal behavior + of presenting them as spaces (k-achaet.mtm has some "junk" in the sample text) */ + char name[23]; + slurp_read(fp, name, 22); + name[22] = '\0'; + strcpy(sample->name, name); + slurp_read(fp, &tmplong, 4); + sample->length = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + sample->loop_start = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + sample->loop_end = bswapLE32(tmplong); + if ((sample->loop_end - sample->loop_start) > 2) { + sample->flags |= CHN_LOOP; + } else { + /* Both Impulse Tracker and Modplug do this */ + sample->loop_start = 0; + sample->loop_end = 0; + } + song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); + sample->volume = slurp_getc(fp); + sample->volume *= 4; //mphack + sample->global_volume = 64; + if (slurp_getc(fp) & 1) { + todo |= 16; + sample->flags |= CHN_16BIT; + sample->length >>= 1; + sample->loop_start >>= 1; + sample->loop_end >>= 1; + } + song->samples[n].vib_type = 0; + song->samples[n].vib_rate = 0; + song->samples[n].vib_depth = 0; + song->samples[n].vib_speed = 0; + } + + /* orderlist */ + slurp_read(fp, song->orderlist, 128); + memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); + + /* tracks */ + trackdata = calloc(ntrk, sizeof(song_note_t *)); + for (n = 0; n < ntrk; n++) { + slurp_read(fp, b, 3 * rows); + trackdata[n] = calloc(rows, sizeof(song_note_t)); + mtm_unpack_track(b, trackdata[n], rows); + } + + /* patterns */ + for (pat = 0; pat <= npat; pat++) { + song->patterns[pat] = csf_allocate_pattern(MAX(rows, 32)); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + tracknote = trackdata[n]; + for (chan = 0; chan < 32; chan++) { + slurp_read(fp, &tmp, 2); + tmp = bswapLE16(tmp); + if (tmp == 0) { + continue; + } else if (tmp >= ntrk) { + for (n = 0; n < ntrk; n++) + free(trackdata[n]); + free(trackdata); + return LOAD_FORMAT_ERROR; + } + note = song->patterns[pat] + chan; + tracknote = trackdata[tmp - 1]; + for (n = 0; n < rows; n++, tracknote++, note += MAX_CHANNELS) + *note = *tracknote; + } + if (rows < 32) { + /* stick a pattern break on the first channel with an empty effect column + * (XXX don't do this if there's already one in another column) */ + note = song->patterns[pat] + 64 * (rows - 1); + while (note->effect || note->param) + note++; + note->effect = FX_PATTERNBREAK; + } + } + + /* free willy */ + for (n = 0; n < ntrk; n++) + free(trackdata[n]); + free(trackdata); + + read_lined_message(song->message, fp, comment_len, 40); + + /* sample data */ + if (!(lflags & LOAD_NOSAMPLES)) { + for (smp = 1; smp <= nsmp; smp++) { + uint32_t ssize; + + if (song->samples[smp].length == 0) + continue; + ssize = csf_read_sample(song->samples + smp, + (SF_LE | SF_PCMU | SF_M + | ((song->samples[smp].flags & CHN_16BIT) ? SF_16 : SF_8)), + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, ssize, SEEK_CUR); + } + } - /* set the rest of the stuff */ - song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; + /* set the rest of the stuff */ + song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; // if (ferror(fp)) { // return LOAD_FILE_ERROR; // } - if (todo & 64) - log_appendf(2, " TODO: test this file with other players (beats per track != 64)"); - if (todo & 16) - log_appendf(2, " TODO: double check 16 bit sample loading"); + if (todo & 64) + log_appendf(2, " TODO: test this file with other players (beats per track != 64)"); + if (todo & 16) + log_appendf(2, " TODO: double check 16 bit sample loading"); - /* done! */ - return LOAD_SUCCESS; + /* done! */ + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/mus.c schism-20160521/fmt/mus.c --- schism-0+20110101/fmt/mus.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/mus.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,13 +32,13 @@ #pragma pack(push,1) struct mus_header { - char id[4]; // MUS\x1a - uint16_t scorelen; - uint16_t scorestart; - uint16_t channels; - uint16_t sec_channels; - uint16_t instrcnt; - uint16_t dummy; + char id[4]; // MUS\x1a + uint16_t scorelen; + uint16_t scorestart; + uint16_t channels; + uint16_t sec_channels; + uint16_t instrcnt; + uint16_t dummy; }; #pragma pack(pop) @@ -46,17 +46,17 @@ int fmt_mus_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - struct mus_header *hdr = (struct mus_header *) data; + struct mus_header *hdr = (struct mus_header *) data; - /* cast necessary for big-endian systems */ - if (!(length > sizeof(*hdr) && memcmp(hdr->id, "MUS\x1a", 4) == 0 - && (size_t) (bswapLE16(hdr->scorestart) + bswapLE16(hdr->scorelen)) <= length)) - return 0; - - file->description = "Doom Music File"; - file->title = strdup(""); - file->type = TYPE_MODULE_MOD; - return 1; + /* cast necessary for big-endian systems */ + if (!(length > sizeof(*hdr) && memcmp(hdr->id, "MUS\x1a", 4) == 0 + && (size_t) (bswapLE16(hdr->scorestart) + bswapLE16(hdr->scorelen)) <= length)) + return 0; + + file->description = "Doom Music File"; + file->title = strdup(""); + file->type = TYPE_MODULE_MOD; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -86,291 +86,291 @@ int fmt_mus_load_song(song_t *song, slurp_t *fp, UNUSED unsigned int lflags) { - struct mus_header hdr; - int n; - song_note_t *note; - int pat, row; - int finished = 0; - size_t reallen; - int tickfrac = 0; // fixed point - struct { - uint8_t note; // the last note played in this channel - uint8_t instrument; // 1 -> 128 - uint8_t volume; // 0 -> 64 - } chanstate[16]; - uint8_t prevspeed = 1; - uint8_t patch_samples[128] = {0}; - uint8_t patch_percussion[128] = {0}; - uint8_t nsmp = 1; // Next free sample - - slurp_read(fp, &hdr, sizeof(hdr)); - hdr.scorelen = bswapLE16(hdr.scorelen); - hdr.scorestart = bswapLE16(hdr.scorestart); - - if (memcmp(hdr.id, "MUS\x1a", 4) != 0) - return LOAD_UNSUPPORTED; - else if (hdr.scorestart + hdr.scorelen > fp->length) - return LOAD_FORMAT_ERROR; - - - for (n = 16; n < 64; n++) - song->channels[n].flags |= CHN_MUTE; - - slurp_seek(fp, hdr.scorestart, SEEK_SET); - - // Narrow the data buffer to simplify reading - reallen = fp->length; - fp->length = MIN(fp->length, hdr.scorestart + hdr.scorelen); - - memset(chanstate, 0, sizeof(chanstate)); - - /* start the first pattern */ - pat = 0; - row = 0; - song->pattern_size[pat] = song->pattern_alloc_size[pat] = MUS_ROWS_PER_PATTERN; - song->patterns[pat] = csf_allocate_pattern(MUS_ROWS_PER_PATTERN); - note = song->patterns[pat]; - song->orderlist[pat] = pat; - - while (!finished && !slurp_eof(fp)) { - uint8_t event, b1, b2, type, ch; - - event = slurp_getc(fp); - type = (event >> 4) & 7; - ch = event & 15; - - switch (type) { - case 0: // Note off - figure out what channel the note was playing in and stick a === there. - b1 = slurp_getc(fp) & 127; // & 127 => note number - b1 = MIN((b1 & 127) + 1, NOTE_LAST); - if (chanstate[ch].note == b1) { - // Ok, we're actually playing that note - if (!NOTE_IS_NOTE(note[ch].note)) - note[ch].note = NOTE_OFF; - } - break; - case 1: // Play note - b1 = slurp_getc(fp); // & 128 => volume follows, & 127 => note number - if (b1 & 128) { - chanstate[ch].volume = ((slurp_getc(fp) & 127) + 1) >> 1; - b1 &= 127; - } - chanstate[ch].note = MIN(b1 + 1, NOTE_LAST); - if (ch == 15) { - // Percussion - b1 = CLAMP(b1, 24, 84); // ? - if (!patch_percussion[b1]) { - if (nsmp < MAX_SAMPLES) { - // New sample! - patch_percussion[b1] = nsmp; - strncpy(song->samples[nsmp].name, - midi_percussion_names[b1 - 24], 25); - song->samples[nsmp].name[25] = '\0'; - nsmp++; - } else { - // Phooey. - log_appendf(4, " Warning: Too many samples"); - note[ch].note = NOTE_OFF; - } - } + struct mus_header hdr; + int n; + song_note_t *note; + int pat, row; + int finished = 0; + size_t reallen; + int tickfrac = 0; // fixed point + struct { + uint8_t note; // the last note played in this channel + uint8_t instrument; // 1 -> 128 + uint8_t volume; // 0 -> 64 + } chanstate[16]; + uint8_t prevspeed = 1; + uint8_t patch_samples[128] = {0}; + uint8_t patch_percussion[128] = {0}; + uint8_t nsmp = 1; // Next free sample + + slurp_read(fp, &hdr, sizeof(hdr)); + hdr.scorelen = bswapLE16(hdr.scorelen); + hdr.scorestart = bswapLE16(hdr.scorestart); + + if (memcmp(hdr.id, "MUS\x1a", 4) != 0) + return LOAD_UNSUPPORTED; + else if (hdr.scorestart + hdr.scorelen > fp->length) + return LOAD_FORMAT_ERROR; + + + for (n = 16; n < 64; n++) + song->channels[n].flags |= CHN_MUTE; + + slurp_seek(fp, hdr.scorestart, SEEK_SET); + + // Narrow the data buffer to simplify reading + reallen = fp->length; + fp->length = MIN(fp->length, hdr.scorestart + hdr.scorelen); + + memset(chanstate, 0, sizeof(chanstate)); + + /* start the first pattern */ + pat = 0; + row = 0; + song->pattern_size[pat] = song->pattern_alloc_size[pat] = MUS_ROWS_PER_PATTERN; + song->patterns[pat] = csf_allocate_pattern(MUS_ROWS_PER_PATTERN); + note = song->patterns[pat]; + song->orderlist[pat] = pat; + + while (!finished && !slurp_eof(fp)) { + uint8_t event, b1, b2, type, ch; + + event = slurp_getc(fp); + type = (event >> 4) & 7; + ch = event & 15; + + switch (type) { + case 0: // Note off - figure out what channel the note was playing in and stick a === there. + b1 = slurp_getc(fp) & 127; // & 127 => note number + b1 = MIN((b1 & 127) + 1, NOTE_LAST); + if (chanstate[ch].note == b1) { + // Ok, we're actually playing that note + if (!NOTE_IS_NOTE(note[ch].note)) + note[ch].note = NOTE_OFF; + } + break; + case 1: // Play note + b1 = slurp_getc(fp); // & 128 => volume follows, & 127 => note number + if (b1 & 128) { + chanstate[ch].volume = ((slurp_getc(fp) & 127) + 1) >> 1; + b1 &= 127; + } + chanstate[ch].note = MIN(b1 + 1, NOTE_LAST); + if (ch == 15) { + // Percussion + b1 = CLAMP(b1, 24, 84); // ? + if (!patch_percussion[b1]) { + if (nsmp < MAX_SAMPLES) { + // New sample! + patch_percussion[b1] = nsmp; + strncpy(song->samples[nsmp].name, + midi_percussion_names[b1 - 24], 25); + song->samples[nsmp].name[25] = '\0'; + nsmp++; + } else { + // Phooey. + log_appendf(4, " Warning: Too many samples"); + note[ch].note = NOTE_OFF; + } + } #if 0 - note[ch].note = NOTE_MIDC; - note[ch].instrument = patch_percussion[b1]; + note[ch].note = NOTE_MIDC; + note[ch].instrument = patch_percussion[b1]; #else - /* adlib is broken currently: it kind of "folds" every 9th channel, but only - for SOME events ... what this amounts to is attempting to play notes from - both of any two "folded" channels will cause everything to go haywire. - for the moment, ignore the drums. even if we could load them, the playback - would be completely awful. - also reset the channel state, so that random note-off events don't stick === - into the channel, that's even enough to screw it up */ - chanstate[ch].note = NOTE_NONE; + /* adlib is broken currently: it kind of "folds" every 9th channel, but only + for SOME events ... what this amounts to is attempting to play notes from + both of any two "folded" channels will cause everything to go haywire. + for the moment, ignore the drums. even if we could load them, the playback + would be completely awful. + also reset the channel state, so that random note-off events don't stick === + into the channel, that's even enough to screw it up */ + chanstate[ch].note = NOTE_NONE; #endif - } else { - if (chanstate[ch].instrument) { - note[ch].note = chanstate[ch].note; - note[ch].instrument = chanstate[ch].instrument; - } - } - note[ch].voleffect = VOLFX_VOLUME; - note[ch].volparam = chanstate[ch].volume; - break; - case 2: // Pitch wheel (TODO) - b1 = slurp_getc(fp); - break; - case 3: // System event - b1 = slurp_getc(fp) & 127; - switch (b1) { - case 10: // All sounds off - for (n = 0; n < 16; n++) { - note[ch].note = chanstate[ch].note = NOTE_CUT; - note[ch].instrument = 0; - } - break; - case 11: // All notes off - for (n = 0; n < 16; n++) { - note[ch].note = chanstate[ch].note = NOTE_OFF; - note[ch].instrument = 0; - } - break; - case 14: // Reset all controllers - // ? - memset(chanstate, 0, sizeof(chanstate)); - break; - case 12: // Mono - case 13: // Poly - break; - } - break; - case 4: // Change controller - b1 = slurp_getc(fp) & 127; // controller - b2 = slurp_getc(fp) & 127; // new value - switch (b1) { - case 0: // Instrument number - if (ch == 15) { - // don't fall for this nasty trick, this is the percussion channel - break; - } - if (!patch_samples[b2]) { - if (nsmp < MAX_SAMPLES) { - // New sample! - patch_samples[b2] = nsmp; - adlib_patch_apply(song->samples + nsmp, b2); - nsmp++; - } else { - // Don't have a sample number for this patch, and never will. - log_appendf(4, " Warning: Too many samples"); - note[ch].note = NOTE_OFF; - } - } - chanstate[ch].instrument = patch_samples[b2]; - break; - case 3: // Volume - b2 = (b2 + 1) >> 1; - chanstate[ch].volume = b2; - note[ch].voleffect = VOLFX_VOLUME; - note[ch].volparam = chanstate[ch].volume; - break; - case 1: // Bank select - case 2: // Modulation pot - case 4: // Pan - case 5: // Expression pot - case 6: // Reverb depth - case 7: // Chorus depth - case 8: // Sustain pedal (hold) - case 9: // Soft pedal - // I have no idea - break; - } - break; - case 6: // Score end - finished = 1; - break; - default: // Unknown (5 or 7) - // Hope it doesn't take any parameters, otherwise things are going to end up broken - log_appendf(4, " Warning: Unknown event type %d", type); - break; - } - - if (finished) { - int leftover = (tickfrac + (1 << FRACBITS)) >> FRACBITS; - note[MUS_BREAK_CHANNEL].effect = FX_PATTERNBREAK; - note[MUS_BREAK_CHANNEL].param = 0; - if (leftover && leftover != prevspeed) { - note[MUS_SPEED_CHANNEL].effect = FX_SPEED; - note[MUS_SPEED_CHANNEL].param = leftover; - } - } else if (event & 0x80) { - // Read timing information and advance the row - int ticks = 0; - - do { - b1 = slurp_getc(fp); - ticks = 128 * ticks + (b1 & 127); - if (ticks > 0xffff) - ticks = 0xffff; - } while (b1 & 128); - ticks = MIN(ticks, (0x7fffffff / 255) >> 12); // protect against overflow - - ticks <<= FRACBITS; // convert to fixed point - ticks = ticks * 255 / 350; // 140 ticks/sec * 125/50hz => tempo of 350 (scaled) - ticks += tickfrac; // plus whatever was leftover from the last row - tickfrac = ticks & FRACMASK; // save the fractional part - ticks >>= FRACBITS; // and back to a normal integer + } else { + if (chanstate[ch].instrument) { + note[ch].note = chanstate[ch].note; + note[ch].instrument = chanstate[ch].instrument; + } + } + note[ch].voleffect = VOLFX_VOLUME; + note[ch].volparam = chanstate[ch].volume; + break; + case 2: // Pitch wheel (TODO) + b1 = slurp_getc(fp); + break; + case 3: // System event + b1 = slurp_getc(fp) & 127; + switch (b1) { + case 10: // All sounds off + for (n = 0; n < 16; n++) { + note[ch].note = chanstate[ch].note = NOTE_CUT; + note[ch].instrument = 0; + } + break; + case 11: // All notes off + for (n = 0; n < 16; n++) { + note[ch].note = chanstate[ch].note = NOTE_OFF; + note[ch].instrument = 0; + } + break; + case 14: // Reset all controllers + // ? + memset(chanstate, 0, sizeof(chanstate)); + break; + case 12: // Mono + case 13: // Poly + break; + } + break; + case 4: // Change controller + b1 = slurp_getc(fp) & 127; // controller + b2 = slurp_getc(fp) & 127; // new value + switch (b1) { + case 0: // Instrument number + if (ch == 15) { + // don't fall for this nasty trick, this is the percussion channel + break; + } + if (!patch_samples[b2]) { + if (nsmp < MAX_SAMPLES) { + // New sample! + patch_samples[b2] = nsmp; + adlib_patch_apply(song->samples + nsmp, b2); + nsmp++; + } else { + // Don't have a sample number for this patch, and never will. + log_appendf(4, " Warning: Too many samples"); + note[ch].note = NOTE_OFF; + } + } + chanstate[ch].instrument = patch_samples[b2]; + break; + case 3: // Volume + b2 = (b2 + 1) >> 1; + chanstate[ch].volume = b2; + note[ch].voleffect = VOLFX_VOLUME; + note[ch].volparam = chanstate[ch].volume; + break; + case 1: // Bank select + case 2: // Modulation pot + case 4: // Pan + case 5: // Expression pot + case 6: // Reverb depth + case 7: // Chorus depth + case 8: // Sustain pedal (hold) + case 9: // Soft pedal + // I have no idea + break; + } + break; + case 6: // Score end + finished = 1; + break; + default: // Unknown (5 or 7) + // Hope it doesn't take any parameters, otherwise things are going to end up broken + log_appendf(4, " Warning: Unknown event type %d", type); + break; + } + + if (finished) { + int leftover = (tickfrac + (1 << FRACBITS)) >> FRACBITS; + note[MUS_BREAK_CHANNEL].effect = FX_PATTERNBREAK; + note[MUS_BREAK_CHANNEL].param = 0; + if (leftover && leftover != prevspeed) { + note[MUS_SPEED_CHANNEL].effect = FX_SPEED; + note[MUS_SPEED_CHANNEL].param = leftover; + } + } else if (event & 0x80) { + // Read timing information and advance the row + int ticks = 0; + + do { + b1 = slurp_getc(fp); + ticks = 128 * ticks + (b1 & 127); + if (ticks > 0xffff) + ticks = 0xffff; + } while (b1 & 128); + ticks = MIN(ticks, (0x7fffffff / 255) >> 12); // protect against overflow + + ticks <<= FRACBITS; // convert to fixed point + ticks = ticks * 255 / 350; // 140 ticks/sec * 125/50hz => tempo of 350 (scaled) + ticks += tickfrac; // plus whatever was leftover from the last row + tickfrac = ticks & FRACMASK; // save the fractional part + ticks >>= FRACBITS; // and back to a normal integer - if (ticks < 1) { + if (ticks < 1) { #if 0 - // There's only part of a tick - compensate by skipping one tick later - tickfrac -= 1 << FRACBITS; - ticks = 1; + // There's only part of a tick - compensate by skipping one tick later + tickfrac -= 1 << FRACBITS; + ticks = 1; #else - /* Don't advance the row: if there's another note right after one of the ones - inserted already, the existing note will be rendered more or less irrelevant - anyway, so just allow any following events to overwrite the data. - Also, there's no need to write the speed, because it'd just be trampled over - later anyway. - The only thing that would necessitate advancing the row is if there's a pitch - adjustment that's at least 15/16 of a semitone; in that case, "steal" a tick - (see above). */ - continue; + /* Don't advance the row: if there's another note right after one of the ones + inserted already, the existing note will be rendered more or less irrelevant + anyway, so just allow any following events to overwrite the data. + Also, there's no need to write the speed, because it'd just be trampled over + later anyway. + The only thing that would necessitate advancing the row is if there's a pitch + adjustment that's at least 15/16 of a semitone; in that case, "steal" a tick + (see above). */ + continue; #endif - } else if (ticks > 255) { - /* Too many ticks for a single row with Axx. - We can increment multiple rows easily, but that only allows for exact multiples - of some number of ticks, so adding in some "padding" is necessary. Since there - is no guarantee that rows after the current one even exist, any adjusting has - to happen on *this* row. */ - - int adjust = ticks % 255; - int s6xch = MUS_TICKADJ_CHANNEL; - while (adjust) { - int s6x = MIN(adjust, 0xf); - note[s6xch].effect = FX_SPECIAL; - note[s6xch].param = 0x60 | s6x; - adjust -= s6x; - s6xch++; - } - } - if (prevspeed != MIN(ticks, 255)) { - prevspeed = MIN(ticks, 255); - note[MUS_SPEED_CHANNEL].effect = FX_SPEED; - note[MUS_SPEED_CHANNEL].param = prevspeed; - } - ticks = ticks / 255 + 1; - row += ticks; - note += 64 * ticks; - } - - while (row >= MUS_ROWS_PER_PATTERN) { - /* Make a new pattern. */ - pat++; - row -= MUS_ROWS_PER_PATTERN; - if (pat >= MAX_PATTERNS) { - log_appendf(4, " Warning: Too much note data"); - finished = 1; - break; - } - song->pattern_size[pat] = song->pattern_alloc_size[pat] = MUS_ROWS_PER_PATTERN; - song->patterns[pat] = csf_allocate_pattern(MUS_ROWS_PER_PATTERN); - note = song->patterns[pat]; - song->orderlist[pat] = pat; - - note[MUS_SPEED_CHANNEL].effect = FX_SPEED; - note[MUS_SPEED_CHANNEL].param = prevspeed; - - note += 64 * row; - } - } - - // Widen the buffer again. - fp->length = reallen; - - song->flags |= SONG_NOSTEREO; - song->initial_speed = 1; - song->initial_tempo = 255; + } else if (ticks > 255) { + /* Too many ticks for a single row with Axx. + We can increment multiple rows easily, but that only allows for exact multiples + of some number of ticks, so adding in some "padding" is necessary. Since there + is no guarantee that rows after the current one even exist, any adjusting has + to happen on *this* row. */ + + int adjust = ticks % 255; + int s6xch = MUS_TICKADJ_CHANNEL; + while (adjust) { + int s6x = MIN(adjust, 0xf); + note[s6xch].effect = FX_SPECIAL; + note[s6xch].param = 0x60 | s6x; + adjust -= s6x; + s6xch++; + } + } + if (prevspeed != MIN(ticks, 255)) { + prevspeed = MIN(ticks, 255); + note[MUS_SPEED_CHANNEL].effect = FX_SPEED; + note[MUS_SPEED_CHANNEL].param = prevspeed; + } + ticks = ticks / 255 + 1; + row += ticks; + note += 64 * ticks; + } + + while (row >= MUS_ROWS_PER_PATTERN) { + /* Make a new pattern. */ + pat++; + row -= MUS_ROWS_PER_PATTERN; + if (pat >= MAX_PATTERNS) { + log_appendf(4, " Warning: Too much note data"); + finished = 1; + break; + } + song->pattern_size[pat] = song->pattern_alloc_size[pat] = MUS_ROWS_PER_PATTERN; + song->patterns[pat] = csf_allocate_pattern(MUS_ROWS_PER_PATTERN); + note = song->patterns[pat]; + song->orderlist[pat] = pat; + + note[MUS_SPEED_CHANNEL].effect = FX_SPEED; + note[MUS_SPEED_CHANNEL].param = prevspeed; + + note += 64 * row; + } + } + + // Widen the buffer again. + fp->length = reallen; + + song->flags |= SONG_NOSTEREO; + song->initial_speed = 1; + song->initial_tempo = 255; - strcpy(song->tracker_id, "Doom Music File"); // ? + strcpy(song->tracker_id, "Doom Music File"); // ? - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/ntk.c schism-20160521/fmt/ntk.c --- schism-0+20110101/fmt/ntk.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/ntk.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,14 +28,14 @@ int fmt_ntk_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 25 && memcmp(data, "TWNNSNG2", 8) == 0)) - return 0; + if (!(length > 25 && memcmp(data, "TWNNSNG2", 8) == 0)) + return 0; - file->description = "NoiseTrekker"; - /*file->extension = str_dup("ntk");*/ - file->title = calloc(16, sizeof(char)); - memcpy(file->title, data + 9, 15); - file->title[15] = 0; - file->type = TYPE_MODULE_MOD; /* ??? */ - return 1; + file->description = "NoiseTrekker"; + /*file->extension = str_dup("ntk");*/ + file->title = calloc(16, sizeof(char)); + memcpy(file->title, data + 9, 15); + file->title[15] = 0; + file->type = TYPE_MODULE_MOD; /* ??? */ + return 1; } diff -Nru schism-0+20110101/fmt/ogg.c schism-20160521/fmt/ogg.c --- schism-0+20110101/fmt/ogg.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/fmt/ogg.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,158 @@ +/* + * Schism Tracker - a cross-platform Impulse Tracker clone + * copyright (c) 2003-2005 Storlek + * copyright (c) 2005-2008 Mrs. Brisby + * copyright (c) 2009 Storlek & Mrs. Brisby + * copyright (c) 2010-2012 Storlek + * URL: http://schismtracker.org/ + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* This is way more work than it ought to be... */ + +/* TODO: test this again since I rearranged the artist/title stuff. +Can't be bothered actually compiling it now to make sure it works. :P */ + +#include "headers.h" +#include "fmt.h" + +#include +#include + +/* --------------------------------------------------------------------- */ + +struct sheep { + const uint8_t *data; + size_t length; + size_t position; +}; + +/* --------------------------------------------------------------------- */ + +static size_t fake_read(void *buf, size_t size, size_t nmemb, void *void_data) +{ + struct sheep *file_data = (struct sheep *) void_data; + + off_t length_left = file_data->length - file_data->position; + off_t read_size = nmemb * size; + + if (read_size > length_left) { + nmemb = length_left / size; + read_size = nmemb * size; + } + if (nmemb > 0) { + memcpy(buf, file_data->data + file_data->position, read_size); + file_data->position += read_size; + } + return nmemb; +} + +static int fake_seek(void *void_data, ogg_int64_t offset, int whence) +{ + struct sheep *file_data = (struct sheep *) void_data; + + switch (whence) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += file_data->position; + break; + case SEEK_END: + offset += file_data->length; + break; + default: + return -1; + } + if (offset < 0 || offset > file_data->length) + return -1; + file_data->position = offset; + return 0; +} + +static int fake_close(UNUSED void *void_data) +{ + return 0; +} + +static long fake_tell(void *void_data) +{ + struct sheep *file_data = (struct sheep *) void_data; + + return file_data->position; +} + +/* --------------------------------------------------------------------- */ + +static void get_title_from_ogg(OggVorbis_File * vf, char **artist_ptr, char **title_ptr) +{ + char *buf, *key, *value; + char **ptr = ov_comment(vf, -1)->user_comments; + int n = -1; + + while (*ptr) { + key = str_dup(*ptr); + value = strchr(key, '='); + if (value == NULL) { + /* buh? */ + free(key); + continue; + } + /* hack? where? */ + *value = 0; + value = str_dup(value + 1); + + if (strcmp(key, "artist") == 0) + *artist_ptr = value; + else if (strcmp(key, "title") == 0) + *title_ptr = value; + else + free(value); + free(key); + ptr++; + } +} + +/* --------------------------------------------------------------------- */ + +int fmt_ogg_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) +{ + OggVorbis_File vf; + ov_callbacks cb; + struct sheep file_data; + + cb.read_func = fake_read; + cb.seek_func = fake_seek; + cb.close_func = fake_close; + cb.tell_func = fake_tell; + + file_data.data = data; + file_data.length = length; + file_data.position = 0; + + if (ov_open_callbacks(&file_data, &vf, NULL, 0, cb) < 0) + return 0; + + /* song_length = ov_time_total(&vf, -1); */ + + get_title_from_ogg(&vf, &file->artist, &file->title); + file->description = "Ogg Vorbis"; + /*file->extension = str_dup("ogg");*/ + file->type = TYPE_SAMPLE_COMPR; + + ov_clear(&vf); + + return 1; +} diff -Nru schism-0+20110101/fmt/okt.c schism-20160521/fmt/okt.c --- schism-0+20110101/fmt/okt.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/okt.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -33,14 +33,14 @@ int fmt_okt_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 16 && memcmp(data, "OKTASONG", 8) == 0)) - return 0; + if (!(length > 16 && memcmp(data, "OKTASONG", 8) == 0)) + return 0; - file->description = "Amiga Oktalyzer"; - /* okts don't have names? */ - file->title = strdup(""); - file->type = TYPE_MODULE_MOD; - return 1; + file->description = "Amiga Oktalyzer"; + /* okts don't have names? */ + file->title = strdup(""); + file->type = TYPE_MODULE_MOD; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -57,12 +57,12 @@ #pragma pack(push,1) struct okt_sample { - char name[20]; - uint32_t length; - uint16_t loop_start; - uint16_t loop_len; - uint16_t volume; - uint16_t mode; + char name[20]; + uint32_t length; + uint16_t loop_start; + uint16_t loop_len; + uint16_t volume; + uint16_t mode; }; #pragma pack(pop) @@ -78,403 +78,403 @@ /* return: number of channels */ static int okt_read_cmod(song_t *song, slurp_t *fp) { - song_channel_t *cs = song->channels; - int t, cn = 0; + song_channel_t *cs = song->channels; + int t, cn = 0; - for (t = 0; t < 4; t++) { - if (slurp_getc(fp) || slurp_getc(fp)) - cs[cn++].panning = PROTRACKER_PANNING(t); - cs[cn++].panning = PROTRACKER_PANNING(t); - } - for (t = cn; t < 64; t++) - cs[t].flags |= CHN_MUTE; - return cn; + for (t = 0; t < 4; t++) { + if (slurp_getc(fp) || slurp_getc(fp)) + cs[cn++].panning = PROTRACKER_PANNING(t); + cs[cn++].panning = PROTRACKER_PANNING(t); + } + for (t = cn; t < 64; t++) + cs[t].flags |= CHN_MUTE; + return cn; } static void okt_read_samp(song_t *song, slurp_t *fp, uint32_t len, uint32_t smpflag[]) { - unsigned int n; - struct okt_sample osmp; - song_sample_t *ssmp = song->samples + 1; - - if (len % 32) - log_appendf(4, " Warning: Sample data is misaligned"); - len /= 32; - if (len >= MAX_SAMPLES) { - log_appendf(4, " Warning: Too many samples in file"); - len = MAX_SAMPLES - 1; - } - - for (n = 1; n <= len; n++, ssmp++) { - slurp_read(fp, &osmp, sizeof(osmp)); - osmp.length = bswapBE32(osmp.length); - osmp.loop_start = bswapBE16(osmp.loop_start); - osmp.loop_len = bswapBE16(osmp.loop_len); - osmp.volume = bswapBE16(osmp.volume); - osmp.mode = bswapBE16(osmp.mode); - - strncpy(ssmp->name, osmp.name, 20); - ssmp->name[20] = '\0'; - ssmp->length = osmp.length & ~1; // round down - if (osmp.loop_len > 2 && osmp.loop_len + osmp.loop_start < ssmp->length) { - ssmp->sustain_start = osmp.loop_start; - ssmp->sustain_end = osmp.loop_start + osmp.loop_len; - if (ssmp->sustain_start < ssmp->length && ssmp->sustain_end < ssmp->length) - ssmp->flags |= CHN_SUSTAINLOOP; - else - ssmp->sustain_start = 0; - } - ssmp->loop_start *= 2; - ssmp->loop_end *= 2; - ssmp->sustain_start *= 2; - ssmp->sustain_end *= 2; - ssmp->volume = MIN(osmp.volume, 64) * 4; //mphack - smpflag[n] = (osmp.mode == 0 || osmp.mode == 2) ? SF_7 : SF_8; - - ssmp->c5speed = 8287; - ssmp->global_volume = 64; - } + unsigned int n; + struct okt_sample osmp; + song_sample_t *ssmp = song->samples + 1; + + if (len % 32) + log_appendf(4, " Warning: Sample data is misaligned"); + len /= 32; + if (len >= MAX_SAMPLES) { + log_appendf(4, " Warning: Too many samples in file"); + len = MAX_SAMPLES - 1; + } + + for (n = 1; n <= len; n++, ssmp++) { + slurp_read(fp, &osmp, sizeof(osmp)); + osmp.length = bswapBE32(osmp.length); + osmp.loop_start = bswapBE16(osmp.loop_start); + osmp.loop_len = bswapBE16(osmp.loop_len); + osmp.volume = bswapBE16(osmp.volume); + osmp.mode = bswapBE16(osmp.mode); + + strncpy(ssmp->name, osmp.name, 20); + ssmp->name[20] = '\0'; + ssmp->length = osmp.length & ~1; // round down + if (osmp.loop_len > 2 && osmp.loop_len + osmp.loop_start < ssmp->length) { + ssmp->sustain_start = osmp.loop_start; + ssmp->sustain_end = osmp.loop_start + osmp.loop_len; + if (ssmp->sustain_start < ssmp->length && ssmp->sustain_end < ssmp->length) + ssmp->flags |= CHN_SUSTAINLOOP; + else + ssmp->sustain_start = 0; + } + ssmp->loop_start *= 2; + ssmp->loop_end *= 2; + ssmp->sustain_start *= 2; + ssmp->sustain_end *= 2; + ssmp->volume = MIN(osmp.volume, 64) * 4; //mphack + smpflag[n] = (osmp.mode == 0 || osmp.mode == 2) ? SF_7 : SF_8; + + ssmp->c5speed = 8287; + ssmp->global_volume = 64; + } } /* Octalyzer effects list, straight from the internal help (acquired by running "strings octalyzer1.57") -- - - Effects Help Page -------------------------- - 1 Portamento Down (4) (Period) - 2 Portamento Up (4) (Period) - A Arpeggio 1 (B) (down, orig, up) - B Arpeggio 2 (B) (orig, up, orig, down) - C Arpeggio 3 (B) ( up, up, orig) - D Slide Down (B) (Notes) - U Slide Up (B) (Notes) - L Slide Down Once (B) (Notes) - H Slide Up Once (B) (Notes) - F Set Filter (B) <>00:ON - P Pos Jump (B) - S Speed (B) - V Volume (B) <=40:DIRECT - O Old Volume (4) 4x:Vol Down (VO) - 5x:Vol Up (VO) - 6x:Vol Down Once (VO) - 7x:Vol Up Once (VO) + - Effects Help Page -------------------------- + 1 Portamento Down (4) (Period) + 2 Portamento Up (4) (Period) + A Arpeggio 1 (B) (down, orig, up) + B Arpeggio 2 (B) (orig, up, orig, down) + C Arpeggio 3 (B) ( up, up, orig) + D Slide Down (B) (Notes) + U Slide Up (B) (Notes) + L Slide Down Once (B) (Notes) + H Slide Up Once (B) (Notes) + F Set Filter (B) <>00:ON + P Pos Jump (B) + S Speed (B) + V Volume (B) <=40:DIRECT + O Old Volume (4) 4x:Vol Down (VO) + 5x:Vol Up (VO) + 6x:Vol Down Once (VO) + 7x:Vol Up Once (VO) Note that 1xx/2xx are apparently inverted from Protracker. I'm not sure what "Old Volume" does -- continue a slide? reset to the sample's volume? */ /* return: mask indicating effects that aren't implemented/recognized */ static uint32_t okt_read_pbod(song_t *song, slurp_t *fp, int nchn, int pat) { - int row, chn, e; - uint16_t rows; - song_note_t *note; - // bitset for effect warnings: (effwarn & (1 << (okteffect - 1))) - // bit 1 is set if out of range values are encountered (Xxx, Yxx, Zxx, or garbage data) - uint32_t effwarn = 0; - - slurp_read(fp, &rows, 2); - rows = bswapBE16(rows); - rows = CLAMP(rows, 1, 200); - - song->pattern_alloc_size[pat] = song->pattern_size[pat] = rows; - note = song->patterns[pat] = csf_allocate_pattern(rows); - - for (row = 0; row < rows; row++, note += 64 - nchn) { - for (chn = 0; chn < nchn; chn++, note++) { - note->note = slurp_getc(fp); - note->instrument = slurp_getc(fp); - e = slurp_getc(fp); - note->param = slurp_getc(fp); - - if (note->note && note->note <= 36) { - note->note += 48; - note->instrument++; - } else { - note->instrument = 0; // ? - } - - /* blah -- check for read error */ - if (e < 0) - return effwarn; - - switch (e) { - case 0: // Nothing - break; - - /* 1/2 apparently are backwards from .mod? */ - case 1: // 1 Portamento Down (Period) - note->effect = FX_PORTAMENTODOWN; - note->param &= 0xf; - break; - case 2: // 2 Portamento Up (Period) - note->effect = FX_PORTAMENTOUP; - note->param &= 0xf; - break; + int row, chn, e; + uint16_t rows; + song_note_t *note; + // bitset for effect warnings: (effwarn & (1 << (okteffect - 1))) + // bit 1 is set if out of range values are encountered (Xxx, Yxx, Zxx, or garbage data) + uint32_t effwarn = 0; + + slurp_read(fp, &rows, 2); + rows = bswapBE16(rows); + rows = CLAMP(rows, 1, 200); + + song->pattern_alloc_size[pat] = song->pattern_size[pat] = rows; + note = song->patterns[pat] = csf_allocate_pattern(rows); + + for (row = 0; row < rows; row++, note += 64 - nchn) { + for (chn = 0; chn < nchn; chn++, note++) { + note->note = slurp_getc(fp); + note->instrument = slurp_getc(fp); + e = slurp_getc(fp); + note->param = slurp_getc(fp); + + if (note->note && note->note <= 36) { + note->note += 48; + note->instrument++; + } else { + note->instrument = 0; // ? + } + + /* blah -- check for read error */ + if (e < 0) + return effwarn; + + switch (e) { + case 0: // Nothing + break; + + /* 1/2 apparently are backwards from .mod? */ + case 1: // 1 Portamento Down (Period) + note->effect = FX_PORTAMENTODOWN; + note->param &= 0xf; + break; + case 2: // 2 Portamento Up (Period) + note->effect = FX_PORTAMENTOUP; + note->param &= 0xf; + break; #if 0 - /* these aren't like Jxx: "down" means to *subtract* the offset from the note. - For now I'm going to leave these unimplemented. */ - case 10: // A Arpeggio 1 (down, orig, up) - case 11: // B Arpeggio 2 (orig, up, orig, down) - if (note->param) - note->effect = FX_WEIRDOKTARP; - break; + /* these aren't like Jxx: "down" means to *subtract* the offset from the note. + For now I'm going to leave these unimplemented. */ + case 10: // A Arpeggio 1 (down, orig, up) + case 11: // B Arpeggio 2 (orig, up, orig, down) + if (note->param) + note->effect = FX_WEIRDOKTARP; + break; #endif - /* This one is close enough to "standard" arpeggio -- I think! */ - case 12: // C Arpeggio 3 (up, up, orig) - if (note->param) - note->effect = FX_ARPEGGIO; - break; - - case 13: // D Slide Down (Notes) - if (note->param) { - note->effect = FX_NOTESLIDEDOWN; - note->param = 0x10 | MIN(0xf, note->param); - } - break; - - case 30: // U Slide Up (Notes) - if (note->param) { - note->effect = FX_NOTESLIDEUP; - note->param = 0x10 | MIN(0xf, note->param); - } - break; - - case 21: // L Slide Down Once (Notes) - /* We don't have fine note slide, but this is supposed to happen once - per row. Sliding every 5 (non-note) ticks kind of works (at least at - speed 6), but implementing fine slides would of course be better. */ - if (note->param) { - note->effect = FX_NOTESLIDEDOWN; - note->param = 0x50 | MIN(0xf, note->param); - } - break; - - case 17: // H Slide Up Once (Notes) - if (note->param) { - note->effect = FX_NOTESLIDEUP; - note->param = 0x50 | MIN(0xf, note->param); - } - break; - - case 15: // F Set Filter <>00:ON - // Not implemented, but let's import it anyway... - note->effect = FX_SPECIAL; - note->param = !!note->param; - break; - - case 25: // P Pos Jump - note->effect = FX_POSITIONJUMP; - break; - - case 27: // R Release sample (apparently not listed in the help!) - note->note = NOTE_OFF; - note->instrument = note->effect = note->param = 0; - break; - - case 28: // S Speed - note->effect = FX_SPEED; // or tempo? - break; - - case 31: // V Volume - note->effect = FX_VOLUMESLIDE; - switch (note->param >> 4) { - case 4: - if (note->param != 0x40) { - note->param &= 0xf; // D0x - break; - } - // 0x40 is set volume -- fall through - case 0 ... 3: - note->voleffect = VOLFX_VOLUME; - note->volparam = note->param; - note->effect = FX_NONE; - note->param = 0; - break; - case 5: - note->param = (note->param & 0xf) << 4; // Dx0 - break; - case 6: - note->param = 0xf0 | MIN(note->param & 0xf, 0xe); // DFx - break; - case 7: - note->param = (MIN(note->param & 0xf, 0xe) << 4) | 0xf; // DxF - break; - default: - // Junk. - note->effect = note->param = 0; - break; - } - break; + /* This one is close enough to "standard" arpeggio -- I think! */ + case 12: // C Arpeggio 3 (up, up, orig) + if (note->param) + note->effect = FX_ARPEGGIO; + break; + + case 13: // D Slide Down (Notes) + if (note->param) { + note->effect = FX_NOTESLIDEDOWN; + note->param = 0x10 | MIN(0xf, note->param); + } + break; + + case 30: // U Slide Up (Notes) + if (note->param) { + note->effect = FX_NOTESLIDEUP; + note->param = 0x10 | MIN(0xf, note->param); + } + break; + + case 21: // L Slide Down Once (Notes) + /* We don't have fine note slide, but this is supposed to happen once + per row. Sliding every 5 (non-note) ticks kind of works (at least at + speed 6), but implementing fine slides would of course be better. */ + if (note->param) { + note->effect = FX_NOTESLIDEDOWN; + note->param = 0x50 | MIN(0xf, note->param); + } + break; + + case 17: // H Slide Up Once (Notes) + if (note->param) { + note->effect = FX_NOTESLIDEUP; + note->param = 0x50 | MIN(0xf, note->param); + } + break; + + case 15: // F Set Filter <>00:ON + // Not implemented, but let's import it anyway... + note->effect = FX_SPECIAL; + note->param = !!note->param; + break; + + case 25: // P Pos Jump + note->effect = FX_POSITIONJUMP; + break; + + case 27: // R Release sample (apparently not listed in the help!) + note->note = NOTE_OFF; + note->instrument = note->effect = note->param = 0; + break; + + case 28: // S Speed + note->effect = FX_SPEED; // or tempo? + break; + + case 31: // V Volume + note->effect = FX_VOLUMESLIDE; + switch (note->param >> 4) { + case 4: + if (note->param != 0x40) { + note->param &= 0xf; // D0x + break; + } + // 0x40 is set volume -- fall through + case 0 ... 3: + note->voleffect = VOLFX_VOLUME; + note->volparam = note->param; + note->effect = FX_NONE; + note->param = 0; + break; + case 5: + note->param = (note->param & 0xf) << 4; // Dx0 + break; + case 6: + note->param = 0xf0 | MIN(note->param & 0xf, 0xe); // DFx + break; + case 7: + note->param = (MIN(note->param & 0xf, 0xe) << 4) | 0xf; // DxF + break; + default: + // Junk. + note->effect = note->param = 0; + break; + } + break; #if 0 - case 24: // O Old Volume - /* ? */ - note->effect = FX_VOLUMESLIDE; - note->param = 0; - break; + case 24: // O Old Volume + /* ? */ + note->effect = FX_VOLUMESLIDE; + note->param = 0; + break; #endif - default: - //log_appendf(2, " Pattern %d, row %d: effect %d %02X", - // pat, row, e, note->param); - effwarn |= (e > 32) ? 1 : (1 << (e - 1)); - note->effect = FX_UNIMPLEMENTED; - break; - } - } - } + default: + //log_appendf(2, " Pattern %d, row %d: effect %d %02X", + // pat, row, e, note->param); + effwarn |= (e > 32) ? 1 : (1 << (e - 1)); + note->effect = FX_UNIMPLEMENTED; + break; + } + } + } - return effwarn; + return effwarn; } /* --------------------------------------------------------------------------------------------------------- */ int fmt_okt_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint8_t tag[8]; - unsigned int readflags = 0; - uint16_t w; // temp for reading - int plen = 0; // how many positions in the orderlist are valid - int npat = 0; // next pattern to read - int nsmp = 1; // next sample (data, not header) - int pat, sh, sd, e; // iterators (pattern, sample header, sample data, effect warnings - int nchn = 0; // how many channels does this song use? - size_t patseek[MAX_PATTERNS] = {0}; - size_t smpseek[MAX_SAMPLES + 1] = {0}; // where the sample's data starts - uint32_t smpsize[MAX_SAMPLES + 2] = {0}; // data size (one element bigger to simplify loop condition) - uint32_t smpflag[MAX_SAMPLES + 1] = {0}; // bit width - uint32_t effwarn = 0; // effect warning mask - - slurp_read(fp, tag, 8); - if (memcmp(tag, "OKTASONG", 8) != 0) - return LOAD_UNSUPPORTED; - - while (!slurp_eof(fp)) { - uint32_t blklen; // length of this block - size_t nextpos; // ... and start of next one - - slurp_read(fp, tag, 4); - slurp_read(fp, &blklen, 4); - blklen = bswapBE32(blklen); - nextpos = slurp_tell(fp) + blklen; - - switch (OKT_BLOCK(tag[0], tag[1], tag[2], tag[3])) { - case OKT_BLK_CMOD: - if (!(readflags & OKT_HAS_CMOD)) { - readflags |= OKT_HAS_CMOD; - nchn = okt_read_cmod(song, fp); - } - break; - case OKT_BLK_SAMP: - if (!(readflags & OKT_HAS_SAMP)) { - readflags |= OKT_HAS_SAMP; - okt_read_samp(song, fp, blklen, smpflag); - } - break; - case OKT_BLK_SPEE: - if (!(readflags & OKT_HAS_SPEE)) { - readflags |= OKT_HAS_SPEE; - slurp_read(fp, &w, 2); - w = bswapBE16(w); - song->initial_speed = CLAMP(w, 1, 255); - song->initial_tempo = 125; - } - break; - case OKT_BLK_SLEN: - // Don't care. - break; - case OKT_BLK_PLEN: - if (!(readflags & OKT_HAS_PLEN)) { - readflags |= OKT_HAS_PLEN; - slurp_read(fp, &w, 2); - plen = bswapBE16(w); - } - break; - case OKT_BLK_PATT: - if (!(readflags & OKT_HAS_PATT)) { - readflags |= OKT_HAS_PATT; - slurp_read(fp, song->orderlist, MIN(blklen, MAX_ORDERS)); - } - break; - case OKT_BLK_PBOD: - /* Need the channel count (in CMOD) in order to read these */ - if (npat < MAX_PATTERNS) { - if (blklen > 0) - patseek[npat] = slurp_tell(fp); - npat++; - } - break; - case OKT_BLK_SBOD: - if (nsmp < MAX_SAMPLES) { - smpseek[nsmp] = slurp_tell(fp); - smpsize[nsmp] = blklen; - if (smpsize[nsmp]) - nsmp++; - } - break; - - default: - //log_appendf(4, " Warning: Unknown block of type '%c%c%c%c' at 0x%lx", - // tag[0], tag[1], tag[2], tag[3], fp->pos - 8); - break; - } - - if (slurp_seek(fp, nextpos, SEEK_SET) != 0) { - log_appendf(4, " Warning: Failed to seek (file truncated?)"); - break; - } - } - - if ((readflags & (OKT_HAS_CMOD | OKT_HAS_SPEE)) != (OKT_HAS_CMOD | OKT_HAS_SPEE)) - return LOAD_FORMAT_ERROR; - - if (!(lflags & LOAD_NOPATTERNS)) { - for (pat = 0; pat < npat; pat++) { - slurp_seek(fp, patseek[pat], SEEK_SET); - effwarn |= okt_read_pbod(song, fp, nchn, pat); - } - - if (effwarn) { - if (effwarn & 1) - log_appendf(4, " Warning: Out-of-range effects (junk data?)"); - for (e = 2; e <= 32; e++) { - if (effwarn & (1 << (e - 1))) { - log_appendf(4, " Warning: Unimplemented effect %cxx", - e + (e < 10 ? '0' : ('A' - 10))); - } - } - } - } - - if (!(lflags & LOAD_NOSAMPLES)) { - for (sh = sd = 1; sh < MAX_SAMPLES && smpsize[sd]; sh++) { - song_sample_t *ssmp = song->samples + sh; - if (!ssmp->length) - continue; - - if (ssmp->length != smpsize[sd]) { - log_appendf(4, " Warning: Sample %d: header/data size mismatch (%d/%d)", sh, - ssmp->length, smpsize[sd]); - ssmp->length = MIN(smpsize[sd], ssmp->length); - } - - csf_read_sample(ssmp, SF_BE | SF_M | SF_PCMS | smpflag[sd], - fp->data + smpseek[sd], ssmp->length); - sd++; - } - // Make sure there's nothing weird going on - for (; sh < MAX_SAMPLES; sh++) { - if (song->samples[sh].length) { - log_appendf(4, " Warning: Sample %d: file truncated", sh); - song->samples[sh].length = 0; - } - } - } - - song->pan_separation = 64; - memset(song->orderlist + plen, ORDER_LAST, MAX_ORDERS - plen); - strcpy(song->tracker_id, "Amiga Oktalyzer"); + uint8_t tag[8]; + unsigned int readflags = 0; + uint16_t w; // temp for reading + int plen = 0; // how many positions in the orderlist are valid + int npat = 0; // next pattern to read + int nsmp = 1; // next sample (data, not header) + int pat, sh, sd, e; // iterators (pattern, sample header, sample data, effect warnings + int nchn = 0; // how many channels does this song use? + size_t patseek[MAX_PATTERNS] = {0}; + size_t smpseek[MAX_SAMPLES + 1] = {0}; // where the sample's data starts + uint32_t smpsize[MAX_SAMPLES + 2] = {0}; // data size (one element bigger to simplify loop condition) + uint32_t smpflag[MAX_SAMPLES + 1] = {0}; // bit width + uint32_t effwarn = 0; // effect warning mask + + slurp_read(fp, tag, 8); + if (memcmp(tag, "OKTASONG", 8) != 0) + return LOAD_UNSUPPORTED; + + while (!slurp_eof(fp)) { + uint32_t blklen; // length of this block + size_t nextpos; // ... and start of next one + + slurp_read(fp, tag, 4); + slurp_read(fp, &blklen, 4); + blklen = bswapBE32(blklen); + nextpos = slurp_tell(fp) + blklen; + + switch (OKT_BLOCK(tag[0], tag[1], tag[2], tag[3])) { + case OKT_BLK_CMOD: + if (!(readflags & OKT_HAS_CMOD)) { + readflags |= OKT_HAS_CMOD; + nchn = okt_read_cmod(song, fp); + } + break; + case OKT_BLK_SAMP: + if (!(readflags & OKT_HAS_SAMP)) { + readflags |= OKT_HAS_SAMP; + okt_read_samp(song, fp, blklen, smpflag); + } + break; + case OKT_BLK_SPEE: + if (!(readflags & OKT_HAS_SPEE)) { + readflags |= OKT_HAS_SPEE; + slurp_read(fp, &w, 2); + w = bswapBE16(w); + song->initial_speed = CLAMP(w, 1, 255); + song->initial_tempo = 125; + } + break; + case OKT_BLK_SLEN: + // Don't care. + break; + case OKT_BLK_PLEN: + if (!(readflags & OKT_HAS_PLEN)) { + readflags |= OKT_HAS_PLEN; + slurp_read(fp, &w, 2); + plen = bswapBE16(w); + } + break; + case OKT_BLK_PATT: + if (!(readflags & OKT_HAS_PATT)) { + readflags |= OKT_HAS_PATT; + slurp_read(fp, song->orderlist, MIN(blklen, MAX_ORDERS)); + } + break; + case OKT_BLK_PBOD: + /* Need the channel count (in CMOD) in order to read these */ + if (npat < MAX_PATTERNS) { + if (blklen > 0) + patseek[npat] = slurp_tell(fp); + npat++; + } + break; + case OKT_BLK_SBOD: + if (nsmp < MAX_SAMPLES) { + smpseek[nsmp] = slurp_tell(fp); + smpsize[nsmp] = blklen; + if (smpsize[nsmp]) + nsmp++; + } + break; + + default: + //log_appendf(4, " Warning: Unknown block of type '%c%c%c%c' at 0x%lx", + // tag[0], tag[1], tag[2], tag[3], fp->pos - 8); + break; + } + + if (slurp_seek(fp, nextpos, SEEK_SET) != 0) { + log_appendf(4, " Warning: Failed to seek (file truncated?)"); + break; + } + } + + if ((readflags & (OKT_HAS_CMOD | OKT_HAS_SPEE)) != (OKT_HAS_CMOD | OKT_HAS_SPEE)) + return LOAD_FORMAT_ERROR; + + if (!(lflags & LOAD_NOPATTERNS)) { + for (pat = 0; pat < npat; pat++) { + slurp_seek(fp, patseek[pat], SEEK_SET); + effwarn |= okt_read_pbod(song, fp, nchn, pat); + } + + if (effwarn) { + if (effwarn & 1) + log_appendf(4, " Warning: Out-of-range effects (junk data?)"); + for (e = 2; e <= 32; e++) { + if (effwarn & (1 << (e - 1))) { + log_appendf(4, " Warning: Unimplemented effect %cxx", + e + (e < 10 ? '0' : ('A' - 10))); + } + } + } + } + + if (!(lflags & LOAD_NOSAMPLES)) { + for (sh = sd = 1; sh < MAX_SAMPLES && smpsize[sd]; sh++) { + song_sample_t *ssmp = song->samples + sh; + if (!ssmp->length) + continue; + + if (ssmp->length != smpsize[sd]) { + log_appendf(4, " Warning: Sample %d: header/data size mismatch (%d/%d)", sh, + ssmp->length, smpsize[sd]); + ssmp->length = MIN(smpsize[sd], ssmp->length); + } + + csf_read_sample(ssmp, SF_BE | SF_M | SF_PCMS | smpflag[sd], + fp->data + smpseek[sd], ssmp->length); + sd++; + } + // Make sure there's nothing weird going on + for (; sh < MAX_SAMPLES; sh++) { + if (song->samples[sh].length) { + log_appendf(4, " Warning: Sample %d: file truncated", sh); + song->samples[sh].length = 0; + } + } + } + + song->pan_separation = 64; + memset(song->orderlist + plen, ORDER_LAST, MAX_ORDERS - plen); + strcpy(song->tracker_id, "Amiga Oktalyzer"); - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/pat.c schism-20160521/fmt/pat.c --- schism-0+20110101/fmt/pat.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/pat.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,48 +36,48 @@ #pragma pack(push, 1) struct GF1PatchHeader { - uint8_t sig[8]; // "GF1PATCH" - uint8_t ver[4]; // "100\0" or "110\0" - uint8_t id[10]; // "ID#000002\0" - char desc[60]; // Discription (in ASCII) [sic] - uint8_t insnum; // To some patch makers, 0 means 1 [what?] - uint8_t voicenum; // Voices (Always 14?) - uint8_t channum; // Channels - uint16_t waveforms; - uint16_t mastervol; // 0-127 [then why is it 16-bit? ugh] - uint32_t datasize; - uint8_t reserved1[36]; - uint16_t insID; // Instrument ID [0..0xFFFF] [?] - char insname[16]; // Instrument name (in ASCII) - uint32_t inssize; // Instrument size - uint8_t layers; - uint8_t reserved2[40]; - uint8_t layerduplicate; - uint8_t layer; - uint32_t layersize; - uint8_t smpnum; - uint8_t reserved3[40]; + uint8_t sig[8]; // "GF1PATCH" + uint8_t ver[4]; // "100\0" or "110\0" + uint8_t id[10]; // "ID#000002\0" + char desc[60]; // Discription (in ASCII) [sic] + uint8_t insnum; // To some patch makers, 0 means 1 [what?] + uint8_t voicenum; // Voices (Always 14?) + uint8_t channum; // Channels + uint16_t waveforms; + uint16_t mastervol; // 0-127 [then why is it 16-bit? ugh] + uint32_t datasize; + uint8_t reserved1[36]; + uint16_t insID; // Instrument ID [0..0xFFFF] [?] + char insname[16]; // Instrument name (in ASCII) + uint32_t inssize; // Instrument size + uint8_t layers; + uint8_t reserved2[40]; + uint8_t layerduplicate; + uint8_t layer; + uint32_t layersize; + uint8_t smpnum; + uint8_t reserved3[40]; }; struct GF1PatchSampleHeader { - char wavename[7]; // Wave name (in ASCII) - uint8_t fractions; // bits 0-3 loop start frac / 4-7 loop end frac - uint32_t samplesize; // Sample data size (s) - uint32_t loopstart; - uint32_t loopend; - uint16_t samplerate; - uint32_t lofreq; // Low frequency - uint32_t hifreq; // High frequency - uint32_t rtfreq; // Root frequency - uint16_t tune; // Tune (Always 1, not used anymore) - uint8_t panning; // Panning (L=0 -> R=15) - uint8_t envelopes[12]; - uint8_t trem_speed, trem_rate, trem_depth; - uint8_t vib_speed, vib_rate, vib_depth; - uint8_t smpmode; // bit mask: 16, unsigned, loop, pingpong, reverse, sustain, envelope, clamped release - uint16_t scalefreq; // Scale frequency - uint16_t scalefac; // Scale factor [0..2048] (1024 is normal) - uint8_t reserved[36]; + char wavename[7]; // Wave name (in ASCII) + uint8_t fractions; // bits 0-3 loop start frac / 4-7 loop end frac + uint32_t samplesize; // Sample data size (s) + uint32_t loopstart; + uint32_t loopend; + uint16_t samplerate; + uint32_t lofreq; // Low frequency + uint32_t hifreq; // High frequency + uint32_t rtfreq; // Root frequency + uint16_t tune; // Tune (Always 1, not used anymore) + uint8_t panning; // Panning (L=0 -> R=15) + uint8_t envelopes[12]; + uint8_t trem_speed, trem_rate, trem_depth; + uint8_t vib_speed, vib_rate, vib_depth; + uint8_t smpmode; // bit mask: 16, unsigned, loop, pingpong, reverse, sustain, envelope, clamped release + uint16_t scalefreq; // Scale frequency + uint16_t scalefac; // Scale factor [0..2048] (1024 is normal) + uint8_t reserved[36]; }; #pragma pack(pop) @@ -85,157 +85,157 @@ static int gusfreq(unsigned int freq) { - unsigned int scale_table[109] = { + unsigned int scale_table[109] = { /*C-0..B-*/ /* Octave 0 */ 16351, 17323, 18354, 19445, 20601, 21826, - 23124, 24499, 25956, 27500, 29135, 30867, + 23124, 24499, 25956, 27500, 29135, 30867, /* Octave 1 */ 32703, 34647, 36708, 38890, 41203, 43653, - 46249, 48999, 51913, 54999, 58270, 61735, + 46249, 48999, 51913, 54999, 58270, 61735, /* Octave 2 */ 65406, 69295, 73416, 77781, 82406, 87306, - 92498, 97998, 103826, 109999, 116540, 123470, + 92498, 97998, 103826, 109999, 116540, 123470, /* Octave 3 */ 130812, 138591, 146832, 155563, 164813, 174614, - 184997, 195997, 207652, 219999, 233081, 246941, + 184997, 195997, 207652, 219999, 233081, 246941, /* Octave 4 */ 261625, 277182, 293664, 311126, 329627, 349228, - 369994, 391995, 415304, 440000, 466163, 493883, + 369994, 391995, 415304, 440000, 466163, 493883, /* Octave 5 */ 523251, 554365, 587329, 622254, 659255, 698456, - 739989, 783991, 830609, 880000, 932328, 987767, + 739989, 783991, 830609, 880000, 932328, 987767, /* Octave 6 */ 1046503, 1108731, 1174660, 1244509, 1318511, 1396914, - 1479979, 1567983, 1661220, 1760002, 1864657, 1975536, + 1479979, 1567983, 1661220, 1760002, 1864657, 1975536, /* Octave 7 */ 2093007, 2217464, 2349321, 2489019, 2637024, 2793830, - 2959960, 3135968, 3322443, 3520006, 3729316, 3951073, + 2959960, 3135968, 3322443, 3520006, 3729316, 3951073, /* Octave 8 */ 4186073, 4434930, 4698645, 4978041, 5274051, 5587663, - 5919922, 6271939, 6644889, 7040015, 7458636, 7902150, - 0xFFFFFFFF, - }; - int no; - - for (no = 0; scale_table[no] != 0xFFFFFFFF; no++) { - if (scale_table[no] <= freq && scale_table[no + 1] >= freq) { - return no - 12; - } - } + 5919922, 6271939, 6644889, 7040015, 7458636, 7902150, + 0xFFFFFFFF, + }; + int no; + + for (no = 0; scale_table[no] != 0xFFFFFFFF; no++) { + if (scale_table[no] <= freq && scale_table[no + 1] >= freq) { + return no - 12; + } + } - return 4 * 12; + return 4 * 12; } /* --------------------------------------------------------------------- */ int fmt_pat_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - const struct GF1PatchHeader *header = (const struct GF1PatchHeader *) data; + const struct GF1PatchHeader *header = (const struct GF1PatchHeader *) data; - if ((length <= sizeof(struct GF1PatchHeader)) - || (memcmp(header->sig, "GF1PATCH", 8) != 0) - || (memcmp(header->ver, "110\0", 4) != 0 && memcmp(header->ver, "100\0", 4) != 0) - || (memcmp(header->id, "ID#000002\0", 10) != 0)) { - return 0; - } - file->description = "Gravis Patch File"; - file->title = malloc(17); - memcpy(file->title, header->insname, 16); - file->title[16] = '\0'; - file->type = TYPE_INST_OTHER; - return 1; + if ((length <= sizeof(struct GF1PatchHeader)) + || (memcmp(header->sig, "GF1PATCH", 8) != 0) + || (memcmp(header->ver, "110\0", 4) != 0 && memcmp(header->ver, "100\0", 4) != 0) + || (memcmp(header->id, "ID#000002\0", 10) != 0)) { + return 0; + } + file->description = "Gravis Patch File"; + file->title = malloc(17); + memcpy(file->title, header->insname, 16); + file->title[16] = '\0'; + file->type = TYPE_INST_OTHER; + return 1; } int fmt_pat_load_instrument(const uint8_t *data, size_t length, int slot) { - struct GF1PatchHeader header; - struct GF1PatchSampleHeader gfsamp; - struct instrumentloader ii; - song_instrument_t *g; - song_sample_t *smp; - unsigned int pos, rs; - int lo, hi, tmp, i, nsamp, n; - - if (length < sizeof(header) || !slot) return 0; - memcpy(&header, data, sizeof(header)); - if ((memcmp(header.sig, "GF1PATCH", 8) != 0) - || (memcmp(header.ver, "110\0", 4) != 0 && memcmp(header.ver, "100\0", 4) != 0) - || (memcmp(header.id, "ID#000002\0", 10) != 0)) { - return 0; - } - - header.waveforms = bswapLE16(header.waveforms); - header.mastervol = bswapLE16(header.mastervol); - header.datasize = bswapLE32(header.datasize); - header.insID = bswapLE16(header.insID); - header.inssize = bswapLE32(header.inssize); - header.layersize = bswapLE32(header.layersize); - - g = instrument_loader_init(&ii, slot); - memcpy(g->name, header.insname, 16); - g->name[15] = '\0'; - - nsamp = CLAMP(header.smpnum, 1, 16); - pos = sizeof(header); - for (i = 0; i < 120; i++) { - g->sample_map[i] = 0; - g->note_map[i] = i + 1; - } - for (i = 0; i < nsamp; i++) { - memcpy(&gfsamp, data + pos, sizeof(gfsamp)); - pos += sizeof(gfsamp); - - n = instrument_loader_sample(&ii, i + 1) - 1; - smp = song_get_sample(n); - - gfsamp.samplesize = bswapLE32(gfsamp.samplesize); - gfsamp.loopstart = bswapLE32(gfsamp.loopstart); - gfsamp.loopend = bswapLE32(gfsamp.loopend); - gfsamp.samplerate = bswapLE16(gfsamp.samplerate); - gfsamp.lofreq = bswapLE32(gfsamp.lofreq); - gfsamp.hifreq = bswapLE32(gfsamp.hifreq); - gfsamp.rtfreq = bswapLE32(gfsamp.rtfreq); - gfsamp.tune = bswapLE16(gfsamp.tune); - gfsamp.scalefreq = bswapLE16(gfsamp.scalefac); - - lo = CLAMP(gusfreq(gfsamp.lofreq), 0, 95); - hi = CLAMP(gusfreq(gfsamp.hifreq), 0, 95); - if (lo > hi) { - tmp = lo; - lo = hi; - hi = tmp; - } - for (; lo < hi; lo++) { - g->sample_map[lo + 12] = n; - } - - if (gfsamp.smpmode & 1) { - gfsamp.samplesize >>= 1; - gfsamp.loopstart >>= 1; - gfsamp.loopend >>= 1; - } - smp->length = gfsamp.samplesize; - smp->loop_start = smp->sustain_start = gfsamp.loopstart; - smp->loop_end = smp->sustain_end = gfsamp.loopend; - smp->c5speed = gfsamp.samplerate; - - smp->flags = 0; - rs = SF_M | SF_LE; // channels; endianness - rs |= (gfsamp.smpmode & 1) ? SF_16 : SF_8; // bit width - rs |= (gfsamp.smpmode & 2) ? SF_PCMU : SF_PCMS; // encoding - if (gfsamp.smpmode & 32) { - if (gfsamp.smpmode & 4) - smp->flags |= CHN_SUSTAINLOOP; - if (gfsamp.smpmode & 8) - smp->flags |= CHN_PINGPONGSUSTAIN; - } else { - if (gfsamp.smpmode & 4) - smp->flags |= CHN_LOOP; - if (gfsamp.smpmode & 8) - smp->flags |= CHN_PINGPONGLOOP; - } - memcpy(smp->filename, gfsamp.wavename, 7); - smp->filename[8] = '\0'; - strcpy(smp->name, smp->filename); - smp->vib_speed = gfsamp.vib_speed; - smp->vib_rate = gfsamp.vib_rate; - smp->vib_depth = gfsamp.vib_depth; - - pos += csf_read_sample(current_song->samples + n, rs, data + pos, length - pos); - } - return 1; + struct GF1PatchHeader header; + struct GF1PatchSampleHeader gfsamp; + struct instrumentloader ii; + song_instrument_t *g; + song_sample_t *smp; + unsigned int pos, rs; + int lo, hi, tmp, i, nsamp, n; + + if (length < sizeof(header) || !slot) return 0; + memcpy(&header, data, sizeof(header)); + if ((memcmp(header.sig, "GF1PATCH", 8) != 0) + || (memcmp(header.ver, "110\0", 4) != 0 && memcmp(header.ver, "100\0", 4) != 0) + || (memcmp(header.id, "ID#000002\0", 10) != 0)) { + return 0; + } + + header.waveforms = bswapLE16(header.waveforms); + header.mastervol = bswapLE16(header.mastervol); + header.datasize = bswapLE32(header.datasize); + header.insID = bswapLE16(header.insID); + header.inssize = bswapLE32(header.inssize); + header.layersize = bswapLE32(header.layersize); + + g = instrument_loader_init(&ii, slot); + memcpy(g->name, header.insname, 16); + g->name[15] = '\0'; + + nsamp = CLAMP(header.smpnum, 1, 16); + pos = sizeof(header); + for (i = 0; i < 120; i++) { + g->sample_map[i] = 0; + g->note_map[i] = i + 1; + } + for (i = 0; i < nsamp; i++) { + memcpy(&gfsamp, data + pos, sizeof(gfsamp)); + pos += sizeof(gfsamp); + + n = instrument_loader_sample(&ii, i + 1) - 1; + smp = song_get_sample(n); + + gfsamp.samplesize = bswapLE32(gfsamp.samplesize); + gfsamp.loopstart = bswapLE32(gfsamp.loopstart); + gfsamp.loopend = bswapLE32(gfsamp.loopend); + gfsamp.samplerate = bswapLE16(gfsamp.samplerate); + gfsamp.lofreq = bswapLE32(gfsamp.lofreq); + gfsamp.hifreq = bswapLE32(gfsamp.hifreq); + gfsamp.rtfreq = bswapLE32(gfsamp.rtfreq); + gfsamp.tune = bswapLE16(gfsamp.tune); + gfsamp.scalefreq = bswapLE16(gfsamp.scalefac); + + lo = CLAMP(gusfreq(gfsamp.lofreq), 0, 95); + hi = CLAMP(gusfreq(gfsamp.hifreq), 0, 95); + if (lo > hi) { + tmp = lo; + lo = hi; + hi = tmp; + } + for (; lo < hi; lo++) { + g->sample_map[lo + 12] = n; + } + + if (gfsamp.smpmode & 1) { + gfsamp.samplesize >>= 1; + gfsamp.loopstart >>= 1; + gfsamp.loopend >>= 1; + } + smp->length = gfsamp.samplesize; + smp->loop_start = smp->sustain_start = gfsamp.loopstart; + smp->loop_end = smp->sustain_end = gfsamp.loopend; + smp->c5speed = gfsamp.samplerate; + + smp->flags = 0; + rs = SF_M | SF_LE; // channels; endianness + rs |= (gfsamp.smpmode & 1) ? SF_16 : SF_8; // bit width + rs |= (gfsamp.smpmode & 2) ? SF_PCMU : SF_PCMS; // encoding + if (gfsamp.smpmode & 32) { + if (gfsamp.smpmode & 4) + smp->flags |= CHN_SUSTAINLOOP; + if (gfsamp.smpmode & 8) + smp->flags |= CHN_PINGPONGSUSTAIN; + } else { + if (gfsamp.smpmode & 4) + smp->flags |= CHN_LOOP; + if (gfsamp.smpmode & 8) + smp->flags |= CHN_PINGPONGLOOP; + } + memcpy(smp->filename, gfsamp.wavename, 7); + smp->filename[8] = '\0'; + strcpy(smp->name, smp->filename); + smp->vib_speed = gfsamp.vib_speed; + smp->vib_rate = gfsamp.vib_rate; + smp->vib_depth = gfsamp.vib_depth; + + pos += csf_read_sample(current_song->samples + n, rs, data + pos, length - pos); + } + return 1; } diff -Nru schism-0+20110101/fmt/raw.c schism-20160521/fmt/raw.c --- schism-0+20110101/fmt/raw.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/raw.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,23 +32,23 @@ int fmt_raw_load_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - /* we'll uphold IT's limit of 4mb */ - length = MIN(length, 4 * 1048576); + /* we'll uphold IT's limit of 4mb */ + length = MIN(length, 4 * 1048576); - smp->c5speed = 8363; - smp->volume = 64 * 4; - smp->global_volume = 64; - smp->length = length; - csf_read_sample(smp, SF_LE | SF_8 | SF_PCMU | SF_M, data, length); + smp->c5speed = 8363; + smp->volume = 64 * 4; + smp->global_volume = 64; + smp->length = length; + csf_read_sample(smp, SF_LE | SF_8 | SF_PCMU | SF_M, data, length); - return 1; + return 1; } int fmt_raw_save_sample(disko_t *fp, song_sample_t *smp) { - csf_write_sample(fp, smp, SF_LE - | ((smp->flags & CHN_16BIT) ? SF_16 | SF_PCMS : SF_8 | SF_PCMU) - | ((smp->flags & CHN_STEREO) ? SF_SI : SF_M)); - return SAVE_SUCCESS; + csf_write_sample(fp, smp, SF_LE + | ((smp->flags & CHN_16BIT) ? SF_16 | SF_PCMS : SF_8 | SF_PCMU) + | ((smp->flags & CHN_STEREO) ? SF_SI : SF_M)); + return SAVE_SUCCESS; } diff -Nru schism-0+20110101/fmt/s3i.c schism-20160521/fmt/s3i.c --- schism-0+20110101/fmt/s3i.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/s3i.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -33,130 +33,130 @@ #pragma pack(push, 1) /* Note: This struct must match the disk layout struct */ struct s3i_header { - //00 - unsigned char type; - char dosfn[12]; - unsigned char memseg[3]; - //10 - unsigned int length; // 32 bits - unsigned int loopbeg; // 32 bits - unsigned int loopend; // 32 bits - unsigned char volume; - char dummy1; - unsigned char packed; - unsigned char flags; - //20 - unsigned int c2spd; // 32 bits - char dummy2[4]; - unsigned short dummy_gp; - unsigned short dummy_512; - unsigned int dummy_last; - //30 - char samplename[28]; - //4C - char samplesig[4]; /* SCRS or SCRI */ - //50 + //00 + unsigned char type; + char dosfn[12]; + unsigned char memseg[3]; + //10 + unsigned int length; // 32 bits + unsigned int loopbeg; // 32 bits + unsigned int loopend; // 32 bits + unsigned char volume; + char dummy1; + unsigned char packed; + unsigned char flags; + //20 + unsigned int c2spd; // 32 bits + char dummy2[4]; + unsigned short dummy_gp; + unsigned short dummy_512; + unsigned int dummy_last; + //30 + char samplename[28]; + //4C + char samplesig[4]; /* SCRS or SCRI */ + //50 }; #pragma pack(pop) static int load_s3i_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - const struct s3i_header* header = (const struct s3i_header*) data; - /* - fprintf(stderr, "%X-%X-%X-%X-%X\n", - (((char*)&(header->type ))-((char*)&(header->type))), - (((char*)&(header->length ))-((char*)&(header->type))), - (((char*)&(header->c2spd ))-((char*)&(header->type))), - (((char*)&(header->samplename))-((char*)&(header->type))), - (((char*)&(header->samplesig))-((char*)&(header->type))) - ); - - fprintf(stderr, "Considering %d byte sample (%.4s), %d\n", - (int)length, - header->samplesig, - header->length); - */ - if(length < 0x50) - return 0; // too small - if (strncmp(header->samplesig, "SCRS", 4) != 0 - && strncmp(header->samplesig, "SCRI", 4) != 0) - return 0; // It should be either SCRS or SCRI. - - size_t samp_length = bswapLE32(header->length); - int bytes_per_sample = (header->type == 1 ? ((header->flags & 2) ? 2 : 1) : 0); // no sample data - - if (length < 0x50 + smp->length * bytes_per_sample) - return 0; - - smp->length = samp_length; - smp->global_volume = 64; - smp->volume = header->volume*256/64; - smp->loop_start = header->loopbeg; - smp->loop_end = header->loopend; - smp->c5speed = header->c2spd; - smp->flags = 0; - if (header->flags & 1) - smp->flags |= CHN_LOOP; - if (header->flags & 2) - smp->flags |= CHN_STEREO; - if (header->flags & 4) - smp->flags |= CHN_16BIT; - - if (header->type == 2) { - smp->flags |= CHN_ADLIB; - smp->flags &= ~(CHN_LOOP|CHN_16BIT); - - memcpy(smp->adlib_bytes, &header->length, 11); - - smp->length = 1; - smp->loop_start = 0; - smp->loop_end = 0; - - smp->data = csf_allocate_sample(1); - } - - int format = SF_M | SF_LE; // endianness; channels - format |= (smp->flags & CHN_16BIT) ? (SF_16 | SF_PCMS) : (SF_8 | SF_PCMU); // bits; encoding + const struct s3i_header* header = (const struct s3i_header*) data; + /* + fprintf(stderr, "%X-%X-%X-%X-%X\n", + (((char*)&(header->type ))-((char*)&(header->type))), + (((char*)&(header->length ))-((char*)&(header->type))), + (((char*)&(header->c2spd ))-((char*)&(header->type))), + (((char*)&(header->samplename))-((char*)&(header->type))), + (((char*)&(header->samplesig))-((char*)&(header->type))) + ); + + fprintf(stderr, "Considering %d byte sample (%.4s), %d\n", + (int)length, + header->samplesig, + header->length); + */ + if(length < 0x50) + return 0; // too small + if (strncmp(header->samplesig, "SCRS", 4) != 0 + && strncmp(header->samplesig, "SCRI", 4) != 0) + return 0; // It should be either SCRS or SCRI. + + size_t samp_length = bswapLE32(header->length); + int bytes_per_sample = (header->type == 1 ? ((header->flags & 2) ? 2 : 1) : 0); // no sample data + + if (length < 0x50 + smp->length * bytes_per_sample) + return 0; + + smp->length = samp_length; + smp->global_volume = 64; + smp->volume = header->volume*256/64; + smp->loop_start = header->loopbeg; + smp->loop_end = header->loopend; + smp->c5speed = header->c2spd; + smp->flags = 0; + if (header->flags & 1) + smp->flags |= CHN_LOOP; + if (header->flags & 2) + smp->flags |= CHN_STEREO; + if (header->flags & 4) + smp->flags |= CHN_16BIT; + + if (header->type == 2) { + smp->flags |= CHN_ADLIB; + smp->flags &= ~(CHN_LOOP|CHN_16BIT); + + memcpy(smp->adlib_bytes, &header->length, 11); + + smp->length = 1; + smp->loop_start = 0; + smp->loop_end = 0; + + smp->data = csf_allocate_sample(1); + } + + int format = SF_M | SF_LE; // endianness; channels + format |= (smp->flags & CHN_16BIT) ? (SF_16 | SF_PCMS) : (SF_8 | SF_PCMU); // bits; encoding - csf_read_sample((song_sample_t *) smp, format, - (const char *) (data + 0x50), (uint32_t) (length - 0x50)); + csf_read_sample((song_sample_t *) smp, format, + (const char *) (data + 0x50), (uint32_t) (length - 0x50)); - strncpy(smp->filename, header->dosfn, 11); - strncpy(smp->name, header->samplename, 25); + strncpy(smp->filename, header->dosfn, 11); + strncpy(smp->name, header->samplename, 25); - return 1; + return 1; } int fmt_s3i_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - song_sample_t tmp; - song_sample_t *smp = &tmp; - if (!load_s3i_sample(data, length, smp)) - return 0; - - file->smp_length = smp->length; - file->smp_flags = smp->flags; - file->smp_defvol = smp->volume; - file->smp_gblvol = smp->global_volume; - file->smp_loop_start = smp->loop_start; - file->smp_loop_end = smp->loop_end; - file->smp_speed = smp->c5speed; - file->smp_filename = (char*) mem_alloc(13); - memcpy(file->smp_filename, smp->filename, 12); - file->smp_filename[12] = 0; - - file->description = "Scream Tracker Sample"; - file->title = mem_alloc(26); - memcpy(file->title, smp->name, 25); - file->title[25] = 0; - file->type = TYPE_SAMPLE_EXTD | TYPE_INST_OTHER; - return 1; + song_sample_t tmp; + song_sample_t *smp = &tmp; + if (!load_s3i_sample(data, length, smp)) + return 0; + + file->smp_length = smp->length; + file->smp_flags = smp->flags; + file->smp_defvol = smp->volume; + file->smp_gblvol = smp->global_volume; + file->smp_loop_start = smp->loop_start; + file->smp_loop_end = smp->loop_end; + file->smp_speed = smp->c5speed; + file->smp_filename = (char*) mem_alloc(13); + memcpy(file->smp_filename, smp->filename, 12); + file->smp_filename[12] = 0; + + file->description = "Scream Tracker Sample"; + file->title = mem_alloc(26); + memcpy(file->title, smp->name, 25); + file->title[25] = 0; + file->type = TYPE_SAMPLE_EXTD | TYPE_INST_OTHER; + return 1; } int fmt_s3i_load_sample(const uint8_t *data, size_t length, song_sample_t *smp) { - // what the crap? - return load_s3i_sample(data, length, smp); + // what the crap? + return load_s3i_sample(data, length, smp); } diff -Nru schism-0+20110101/fmt/s3m.c schism-20160521/fmt/s3m.c --- schism-0+20110101/fmt/s3m.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/s3m.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,25 +36,25 @@ int fmt_s3m_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 48 && memcmp(data + 44, "SCRM", 4) == 0)) - return 0; + if (!(length > 48 && memcmp(data + 44, "SCRM", 4) == 0)) + return 0; - file->description = "Scream Tracker 3"; - /*file->extension = str_dup("s3m");*/ - file->title = calloc(28, sizeof(char)); - memcpy(file->title, data, 27); - file->title[27] = 0; - file->type = TYPE_MODULE_S3M; - return 1; + file->description = "Scream Tracker 3"; + /*file->extension = str_dup("s3m");*/ + file->title = calloc(28, sizeof(char)); + memcpy(file->title, data, 27); + file->title[27] = 0; + file->type = TYPE_MODULE_S3M; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ enum { - S3I_TYPE_NONE = 0, - S3I_TYPE_PCM = 1, - S3I_TYPE_ADMEL = 2, - S3I_TYPE_CONTROL = 0xff, // only internally used for saving + S3I_TYPE_NONE = 0, + S3I_TYPE_PCM = 1, + S3I_TYPE_ADMEL = 2, + S3I_TYPE_CONTROL = 0xff, // only internally used for saving }; @@ -64,358 +64,369 @@ int fmt_s3m_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint16_t nsmp, nord, npat; - int misc = S3M_UNSIGNED | S3M_CHANPAN; // temporary flags, these are both generally true - int n; - song_note_t *note; - /* junk variables for reading stuff into */ - uint16_t tmp; - uint8_t c; - uint32_t tmplong; - uint8_t b[4]; - /* parapointers */ - uint16_t para_smp[MAX_SAMPLES]; - uint16_t para_pat[MAX_PATTERNS]; - uint32_t para_sdata[MAX_SAMPLES] = { 0 }; - uint32_t smp_flags[MAX_SAMPLES] = { 0 }; - song_sample_t *sample; - uint16_t trkvers; - uint16_t flags; - uint16_t special; - uint32_t adlib = 0; // bitset - int uc; - const char *tid = NULL; - - /* check the tag */ - slurp_seek(fp, 44, SEEK_SET); - slurp_read(fp, b, 4); - if (memcmp(b, "SCRM", 4) != 0) - return LOAD_UNSUPPORTED; - - /* read the title */ - slurp_rewind(fp); - slurp_read(fp, song->title, 25); - song->title[25] = 0; - - /* skip the last three bytes of the title, the supposed-to-be-0x1a byte, - the tracker ID, and the two useless reserved bytes */ - slurp_seek(fp, 7, SEEK_CUR); - - slurp_read(fp, &nord, 2); - slurp_read(fp, &nsmp, 2); - slurp_read(fp, &npat, 2); - nord = bswapLE16(nord); - nsmp = bswapLE16(nsmp); - npat = bswapLE16(npat); - - if (nord > MAX_ORDERS || nsmp > MAX_SAMPLES || npat > MAX_PATTERNS) - return LOAD_FORMAT_ERROR; - - song->flags = SONG_ITOLDEFFECTS; - slurp_read(fp, &flags, 2); /* flags (don't really care) */ - flags = bswapLE16(flags); - slurp_read(fp, &trkvers, 2); - trkvers = bswapLE16(trkvers); - slurp_read(fp, &tmp, 2); /* file format info */ - if (tmp == bswapLE16(1)) - misc &= ~S3M_UNSIGNED; /* signed samples (ancient s3m) */ - - slurp_seek(fp, 4, SEEK_CUR); /* skip the tag */ - - song->initial_global_volume = slurp_getc(fp) << 1; - song->initial_speed = slurp_getc(fp); - song->initial_tempo = slurp_getc(fp); - song->mixing_volume = slurp_getc(fp); - if (song->mixing_volume & 0x80) { - song->mixing_volume ^= 0x80; - } else { - song->flags |= SONG_NOSTEREO; - } - uc = slurp_getc(fp); /* ultraclick removal (useless) */ - - if (slurp_getc(fp) != 0xfc) - misc &= ~S3M_CHANPAN; /* stored pan values */ - - /* Interesting: Impulse Tracker appears to leave some junk data in this unused section, and what's - more, it always seems to follow the same general pattern. So it's actually possible to identify - whether a song was saved in IT, then loaded and re-saved in ST3. */ - slurp_seek(fp, 8, SEEK_CUR); - slurp_read(fp, &special, 2); // field not used by st3 - special = bswapLE16(special); - - /* channel settings */ - for (n = 0; n < 32; n++) { - /* Channel 'type': 0xFF is a disabled channel, which shows up as (--) in ST3. - Any channel with the high bit set is muted. - 00-07 are L1-L8, 08-0F are R1-R8, 10-18 are adlib channels A1-A9. - Hacking at a file with a hex editor shows some perhaps partially-implemented stuff: - types 19-1D show up in ST3 as AB, AS, AT, AC, and AH; 20-2D are the same as 10-1D - except with 'B' insted of 'A'. None of these appear to produce any sound output, - apart from 19 which plays adlib instruments briefly before cutting them. (Weird!) - Also, 1E/1F and 2E/2F display as "??"; and pressing 'A' on a disabled (--) channel - will change its type to 1F. - Values past 2F seem to display bits of the UI like the copyright and help, strange! - These out-of-range channel types will almost certainly hang or crash ST3 or - produce other strange behavior. Simply put, don't do it. :) */ - c = slurp_getc(fp); - if (c & 0x80) { - song->channels[n].flags |= CHN_MUTE; - // ST3 doesn't even play effects in muted channels -- throw them out? - c &= ~0x80; - } - if (c < 0x08) { - // L1-L8 (panned to 3 in ST3) - song->channels[n].panning = 14; - } else if (c < 0x10) { - // R1-R8 (panned to C in ST3) - song->channels[n].panning = 50; - } else if (c < 0x19) { - // A1-A9 - song->channels[n].panning = 32; - adlib |= 1 << n; - } else { - // Disabled 0xff/0x7f, or broken - song->channels[n].panning = 32; - song->channels[n].flags |= CHN_MUTE; - } - song->channels[n].volume = 64; - } - for (; n < 64; n++) { - song->channels[n].panning = 32; - song->channels[n].volume = 64; - song->channels[n].flags = CHN_MUTE; - } - - /* orderlist */ - slurp_read(fp, song->orderlist, nord); - memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); - - /* load the parapointers */ - slurp_read(fp, para_smp, 2 * nsmp); - slurp_read(fp, para_pat, 2 * npat); - - /* default pannings */ - if (misc & S3M_CHANPAN) { - for (n = 0; n < 32; n++) { - c = slurp_getc(fp); - if (c & 0x20) - song->channels[n].panning = ((c & 0xf) << 2) + 2; - } - } - - //mphack - fix the pannings - for (n = 0; n < 64; n++) - song->channels[n].panning *= 4; - - /* samples */ - for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { - uint8_t type; - - slurp_seek(fp, (para_smp[n]) << 4, SEEK_SET); - - type = slurp_getc(fp); - slurp_read(fp, sample->filename, 12); - sample->filename[12] = 0; - - slurp_read(fp, b, 3); // data pointer for pcm, irrelevant otherwise - switch (type) { - case S3I_TYPE_PCM: - para_sdata[n] = b[1] | (b[2] << 8) | (b[0] << 16); - slurp_read(fp, &tmplong, 4); - sample->length = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - sample->loop_start = bswapLE32(tmplong); - slurp_read(fp, &tmplong, 4); - sample->loop_end = bswapLE32(tmplong); - sample->volume = slurp_getc(fp) * 4; //mphack - slurp_getc(fp); /* unused byte */ - slurp_getc(fp); /* packing info (never used) */ - c = slurp_getc(fp); /* flags */ - if (c & 1) - sample->flags |= CHN_LOOP; - smp_flags[n] = (SF_LE - | ((misc & S3M_UNSIGNED) ? SF_PCMU : SF_PCMS) - | ((c & 4) ? SF_16 : SF_8) - | ((c & 2) ? SF_SS : SF_M)); - break; - - default: - //printf("s3m: mystery-meat sample type %d\n", type); - case S3I_TYPE_NONE: - slurp_seek(fp, 12, SEEK_CUR); - sample->volume = slurp_getc(fp) * 4; //mphack - slurp_seek(fp, 3, SEEK_CUR); - break; - - case S3I_TYPE_ADMEL: - slurp_read(fp, sample->adlib_bytes, 12); - sample->volume = slurp_getc(fp) * 4; //mphack - // next byte is "dsk", what is that? - slurp_seek(fp, 3, SEEK_CUR); - sample->flags |= CHN_ADLIB; - // dumb hackaround that ought to some day be fixed: - sample->length = 1; - sample->data = csf_allocate_sample(1); - break; - } - - slurp_read(fp, &tmplong, 4); - sample->c5speed = bswapLE32(tmplong); - slurp_seek(fp, 12, SEEK_CUR); /* wasted space */ - slurp_read(fp, sample->name, 25); - sample->name[25] = 0; - sample->vib_type = 0; - sample->vib_rate = 0; - sample->vib_depth = 0; - sample->vib_speed = 0; - sample->global_volume = 64; - } - - /* sample data */ - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { - if (!sample->length || !para_sdata[n]) - continue; - slurp_seek(fp, para_sdata[n] << 4, SEEK_SET); - csf_read_sample(sample, smp_flags[n], fp->data + fp->pos, fp->length - fp->pos); - } - } - - if (!(lflags & LOAD_NOPATTERNS)) { - for (n = 0; n < npat; n++) { - int row = 0; - long end; - - para_pat[n] = bswapLE16(para_pat[n]); - if (!para_pat[n]) - continue; - - slurp_seek(fp, para_pat[n] << 4, SEEK_SET); - slurp_read(fp, &tmp, 2); - end = (para_pat[n] << 4) + bswapLE16(tmp) + 2; - - song->patterns[n] = csf_allocate_pattern(64); - - while (row < 64 && slurp_tell(fp) < end) { - int mask = slurp_getc(fp); - uint8_t chn = (mask & 31); - - if (mask == EOF) { - log_appendf(4, " Warning: Pattern %d: file truncated", n); - break; - } - if (!mask) { - /* done with the row */ - row++; - continue; - } - note = song->patterns[n] + 64 * row + chn; - if (mask & 32) { - /* note/instrument */ - note->note = slurp_getc(fp); - note->instrument = slurp_getc(fp); - //if (note->instrument > 99) - // note->instrument = 0; - switch (note->note) { - default: - // Note; hi=oct, lo=note - note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 13; - break; - case 255: - note->note = NOTE_NONE; - break; - case 254: - note->note = (adlib & (1 << chn)) ? NOTE_OFF : NOTE_CUT; - break; - } - } - if (mask & 64) { - /* volume */ - note->voleffect = VOLFX_VOLUME; - note->volparam = slurp_getc(fp); - if (note->volparam == 255) { - note->voleffect = VOLFX_NONE; - note->volparam = 0; - } else if (note->volparam > 64) { - // some weirdly saved s3m? - note->volparam = 64; - } - } - if (mask & 128) { - note->effect = slurp_getc(fp); - note->param = slurp_getc(fp); - csf_import_s3m_effect(note, 0); - if (note->effect == FX_SPECIAL) { - // mimic ST3's SD0/SC0 behavior - if (note->param == 0xd0) { - note->note = NOTE_NONE; - note->instrument = 0; - note->voleffect = VOLFX_NONE; - note->volparam = 0; - note->effect = FX_NONE; - note->param = 0; - } else if (note->param == 0xc0) { - note->effect = FX_NONE; - note->param = 0; - } - } - } - /* ... next note, same row */ - } - } - } - - /* MPT identifies as ST3.20 in the trkvers field, but it puts zeroes for the 'special' field, only ever - * sets flags 0x10 and 0x40, writes multiples of 16 orders, always saves channel pannings, and writes - * zero into the ultraclick removal field. (ST3 always puts either 8, 12, or 16 there). - * Velvet Studio also pretends to be ST3, but writes zeroes for 'special'. ultraclick, and flags, and - * does NOT save channel pannings. Also, it writes a fairly recognizable LRRL pattern for the channels, - * but I'm not checking that. (yet?) */ - if (trkvers == 0x1320) { - if (special == 0 && uc == 0 && (flags & ~0x50) == 0 - && misc == (S3M_UNSIGNED | S3M_CHANPAN) && (nord % 16) == 0) { - tid = "Modplug Tracker"; - } else if (special == 0 && uc == 0 && flags == 0 && misc == (S3M_UNSIGNED)) { - tid = "Velvet Studio"; - } else if (uc != 8 && uc != 12 && uc != 16) { - // sure isn't scream tracker - tid = "Unknown tracker"; - } - } - if (!tid) { - switch (trkvers >> 12) { - case 1: - tid = "Scream Tracker %d.%02x"; - break; - case 2: - tid = "Imago Orpheus %d.%02x"; - break; - case 3: - if (trkvers <= 0x3214) { - tid = "Impulse Tracker %d.%02x"; - } else { - tid = NULL; - sprintf(song->tracker_id, "Impulse Tracker 2.14p%d", trkvers - 0x3214); - } - break; - case 4: - tid = NULL; - strcpy(song->tracker_id, "Schism Tracker "); - ver_decode_cwtv(trkvers, song->tracker_id + strlen(song->tracker_id)); - break; - case 5: - tid = "OpenMPT %d.%02x"; - break; - } - } - if (tid) - sprintf(song->tracker_id, tid, (trkvers & 0xf00) >> 8, trkvers & 0xff); + uint16_t nsmp, nord, npat; + int misc = S3M_UNSIGNED | S3M_CHANPAN; // temporary flags, these are both generally true + int n; + song_note_t *note; + /* junk variables for reading stuff into */ + uint16_t tmp; + uint8_t c; + uint32_t tmplong; + uint8_t b[4]; + /* parapointers */ + uint16_t para_smp[MAX_SAMPLES]; + uint16_t para_pat[MAX_PATTERNS]; + uint32_t para_sdata[MAX_SAMPLES] = { 0 }; + uint32_t smp_flags[MAX_SAMPLES] = { 0 }; + song_sample_t *sample; + uint16_t trkvers; + uint16_t flags; + uint16_t special; + uint32_t adlib = 0; // bitset + int uc; + const char *tid = NULL; + + /* check the tag */ + slurp_seek(fp, 44, SEEK_SET); + slurp_read(fp, b, 4); + if (memcmp(b, "SCRM", 4) != 0) + return LOAD_UNSUPPORTED; + + /* read the title */ + slurp_rewind(fp); + slurp_read(fp, song->title, 25); + song->title[25] = 0; + + /* skip the last three bytes of the title, the supposed-to-be-0x1a byte, + the tracker ID, and the two useless reserved bytes */ + slurp_seek(fp, 7, SEEK_CUR); + + slurp_read(fp, &nord, 2); + slurp_read(fp, &nsmp, 2); + slurp_read(fp, &npat, 2); + nord = bswapLE16(nord); + nsmp = bswapLE16(nsmp); + npat = bswapLE16(npat); + + if (nord > MAX_ORDERS || nsmp > MAX_SAMPLES || npat > MAX_PATTERNS) + return LOAD_FORMAT_ERROR; + + song->flags = SONG_ITOLDEFFECTS; + slurp_read(fp, &flags, 2); /* flags (don't really care) */ + flags = bswapLE16(flags); + slurp_read(fp, &trkvers, 2); + trkvers = bswapLE16(trkvers); + slurp_read(fp, &tmp, 2); /* file format info */ + if (tmp == bswapLE16(1)) + misc &= ~S3M_UNSIGNED; /* signed samples (ancient s3m) */ + + slurp_seek(fp, 4, SEEK_CUR); /* skip the tag */ + + song->initial_global_volume = slurp_getc(fp) << 1; + // In the case of invalid data, ST3 uses the speed/tempo value that's set in the player prior to + // loading the song, but that's just crazy. + song->initial_speed = slurp_getc(fp) ?: 6; + song->initial_tempo = slurp_getc(fp); + if (song->initial_tempo <= 32) { + // (Yes, 32 is ignored by Scream Tracker.) + song->initial_tempo = 125; + } + song->mixing_volume = slurp_getc(fp); + if (song->mixing_volume & 0x80) { + song->mixing_volume ^= 0x80; + } else { + song->flags |= SONG_NOSTEREO; + } + uc = slurp_getc(fp); /* ultraclick removal (useless) */ + + if (slurp_getc(fp) != 0xfc) + misc &= ~S3M_CHANPAN; /* stored pan values */ + + /* Interesting: Impulse Tracker appears to leave some junk data in this unused section, and what's + more, it always seems to follow the same general pattern. So it's actually possible to identify + whether a song was saved in IT, then loaded and re-saved in ST3. */ + slurp_seek(fp, 8, SEEK_CUR); + slurp_read(fp, &special, 2); // field not used by st3 + special = bswapLE16(special); + + /* channel settings */ + for (n = 0; n < 32; n++) { + /* Channel 'type': 0xFF is a disabled channel, which shows up as (--) in ST3. + Any channel with the high bit set is muted. + 00-07 are L1-L8, 08-0F are R1-R8, 10-18 are adlib channels A1-A9. + Hacking at a file with a hex editor shows some perhaps partially-implemented stuff: + types 19-1D show up in ST3 as AB, AS, AT, AC, and AH; 20-2D are the same as 10-1D + except with 'B' insted of 'A'. None of these appear to produce any sound output, + apart from 19 which plays adlib instruments briefly before cutting them. (Weird!) + Also, 1E/1F and 2E/2F display as "??"; and pressing 'A' on a disabled (--) channel + will change its type to 1F. + Values past 2F seem to display bits of the UI like the copyright and help, strange! + These out-of-range channel types will almost certainly hang or crash ST3 or + produce other strange behavior. Simply put, don't do it. :) */ + c = slurp_getc(fp); + if (c & 0x80) { + song->channels[n].flags |= CHN_MUTE; + // ST3 doesn't even play effects in muted channels -- throw them out? + c &= ~0x80; + } + if (c < 0x08) { + // L1-L8 (panned to 3 in ST3) + song->channels[n].panning = 14; + } else if (c < 0x10) { + // R1-R8 (panned to C in ST3) + song->channels[n].panning = 50; + } else if (c < 0x19) { + // A1-A9 + song->channels[n].panning = 32; + adlib |= 1 << n; + } else { + // Disabled 0xff/0x7f, or broken + song->channels[n].panning = 32; + song->channels[n].flags |= CHN_MUTE; + } + song->channels[n].volume = 64; + } + for (; n < 64; n++) { + song->channels[n].panning = 32; + song->channels[n].volume = 64; + song->channels[n].flags = CHN_MUTE; + } + + /* orderlist */ + slurp_read(fp, song->orderlist, nord); + memset(song->orderlist + nord, ORDER_LAST, MAX_ORDERS - nord); + + /* load the parapointers */ + slurp_read(fp, para_smp, 2 * nsmp); + slurp_read(fp, para_pat, 2 * npat); + + /* default pannings */ + if (misc & S3M_CHANPAN) { + for (n = 0; n < 32; n++) { + c = slurp_getc(fp); + if (c & 0x20) + song->channels[n].panning = ((c & 0xf) << 2) + 2; + } + } + + //mphack - fix the pannings + for (n = 0; n < 64; n++) + song->channels[n].panning *= 4; + + /* samples */ + for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { + uint8_t type; + + slurp_seek(fp, (para_smp[n]) << 4, SEEK_SET); + + type = slurp_getc(fp); + slurp_read(fp, sample->filename, 12); + sample->filename[12] = 0; + + slurp_read(fp, b, 3); // data pointer for pcm, irrelevant otherwise + switch (type) { + case S3I_TYPE_PCM: + para_sdata[n] = b[1] | (b[2] << 8) | (b[0] << 16); + slurp_read(fp, &tmplong, 4); + sample->length = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + sample->loop_start = bswapLE32(tmplong); + slurp_read(fp, &tmplong, 4); + sample->loop_end = bswapLE32(tmplong); + sample->volume = slurp_getc(fp) * 4; //mphack + slurp_getc(fp); /* unused byte */ + slurp_getc(fp); /* packing info (never used) */ + c = slurp_getc(fp); /* flags */ + if (c & 1) + sample->flags |= CHN_LOOP; + smp_flags[n] = (SF_LE + | ((misc & S3M_UNSIGNED) ? SF_PCMU : SF_PCMS) + | ((c & 4) ? SF_16 : SF_8) + | ((c & 2) ? SF_SS : SF_M)); + break; + + default: + //printf("s3m: mystery-meat sample type %d\n", type); + case S3I_TYPE_NONE: + slurp_seek(fp, 12, SEEK_CUR); + sample->volume = slurp_getc(fp) * 4; //mphack + slurp_seek(fp, 3, SEEK_CUR); + break; + + case S3I_TYPE_ADMEL: + slurp_read(fp, sample->adlib_bytes, 12); + sample->volume = slurp_getc(fp) * 4; //mphack + // next byte is "dsk", what is that? + slurp_seek(fp, 3, SEEK_CUR); + sample->flags |= CHN_ADLIB; + // dumb hackaround that ought to some day be fixed: + sample->length = 1; + sample->data = csf_allocate_sample(1); + break; + } + + slurp_read(fp, &tmplong, 4); + sample->c5speed = bswapLE32(tmplong); + if (type == S3I_TYPE_ADMEL) { + if (sample->c5speed < 1000 || sample->c5speed > 0xFFFF) { + sample->c5speed = 8363; + } + } + slurp_seek(fp, 12, SEEK_CUR); /* wasted space */ + slurp_read(fp, sample->name, 25); + sample->name[25] = 0; + sample->vib_type = 0; + sample->vib_rate = 0; + sample->vib_depth = 0; + sample->vib_speed = 0; + sample->global_volume = 64; + } + + /* sample data */ + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { + if (!sample->length || (sample->flags & CHN_ADLIB)) + continue; + slurp_seek(fp, para_sdata[n] << 4, SEEK_SET); + csf_read_sample(sample, smp_flags[n], fp->data + fp->pos, fp->length - fp->pos); + } + } + + if (!(lflags & LOAD_NOPATTERNS)) { + for (n = 0; n < npat; n++) { + int row = 0; + long end; + + para_pat[n] = bswapLE16(para_pat[n]); + if (!para_pat[n]) + continue; + + slurp_seek(fp, para_pat[n] << 4, SEEK_SET); + slurp_read(fp, &tmp, 2); + end = (para_pat[n] << 4) + bswapLE16(tmp) + 2; + + song->patterns[n] = csf_allocate_pattern(64); + + while (row < 64 && slurp_tell(fp) < end) { + int mask = slurp_getc(fp); + uint8_t chn = (mask & 31); + + if (mask == EOF) { + log_appendf(4, " Warning: Pattern %d: file truncated", n); + break; + } + if (!mask) { + /* done with the row */ + row++; + continue; + } + note = song->patterns[n] + 64 * row + chn; + if (mask & 32) { + /* note/instrument */ + note->note = slurp_getc(fp); + note->instrument = slurp_getc(fp); + //if (note->instrument > 99) + // note->instrument = 0; + switch (note->note) { + default: + // Note; hi=oct, lo=note + note->note = (note->note >> 4) * 12 + (note->note & 0xf) + 13; + break; + case 255: + note->note = NOTE_NONE; + break; + case 254: + note->note = (adlib & (1 << chn)) ? NOTE_OFF : NOTE_CUT; + break; + } + } + if (mask & 64) { + /* volume */ + note->voleffect = VOLFX_VOLUME; + note->volparam = slurp_getc(fp); + if (note->volparam == 255) { + note->voleffect = VOLFX_NONE; + note->volparam = 0; + } else if (note->volparam > 64) { + // some weirdly saved s3m? + note->volparam = 64; + } + } + if (mask & 128) { + note->effect = slurp_getc(fp); + note->param = slurp_getc(fp); + csf_import_s3m_effect(note, 0); + if (note->effect == FX_SPECIAL) { + // mimic ST3's SD0/SC0 behavior + if (note->param == 0xd0) { + note->note = NOTE_NONE; + note->instrument = 0; + note->voleffect = VOLFX_NONE; + note->volparam = 0; + note->effect = FX_NONE; + note->param = 0; + } else if (note->param == 0xc0) { + note->effect = FX_NONE; + note->param = 0; + } + } + } + /* ... next note, same row */ + } + } + } + + /* MPT identifies as ST3.20 in the trkvers field, but it puts zeroes for the 'special' field, only ever + * sets flags 0x10 and 0x40, writes multiples of 16 orders, always saves channel pannings, and writes + * zero into the ultraclick removal field. (ST3 always puts either 8, 12, or 16 there). + * Velvet Studio also pretends to be ST3, but writes zeroes for 'special'. ultraclick, and flags, and + * does NOT save channel pannings. Also, it writes a fairly recognizable LRRL pattern for the channels, + * but I'm not checking that. (yet?) */ + if (trkvers == 0x1320) { + if (special == 0 && uc == 0 && (flags & ~0x50) == 0 + && misc == (S3M_UNSIGNED | S3M_CHANPAN) && (nord % 16) == 0) { + tid = "Modplug Tracker"; + } else if (special == 0 && uc == 0 && flags == 0 && misc == (S3M_UNSIGNED)) { + tid = "Velvet Studio"; + } else if (uc != 8 && uc != 12 && uc != 16) { + // sure isn't scream tracker + tid = "Unknown tracker"; + } + } + if (!tid) { + switch (trkvers >> 12) { + case 1: + tid = "Scream Tracker %d.%02x"; + break; + case 2: + tid = "Imago Orpheus %d.%02x"; + break; + case 3: + if (trkvers <= 0x3214) { + tid = "Impulse Tracker %d.%02x"; + } else { + tid = NULL; + sprintf(song->tracker_id, "Impulse Tracker 2.14p%d", trkvers - 0x3214); + } + break; + case 4: + tid = NULL; + strcpy(song->tracker_id, "Schism Tracker "); + ver_decode_cwtv(trkvers, song->tracker_id + strlen(song->tracker_id)); + break; + case 5: + tid = "OpenMPT %d.%02x"; + break; + } + } + if (tid) + sprintf(song->tracker_id, tid, (trkvers & 0xf00) >> 8, trkvers & 0xff); // if (ferror(fp)) { // return LOAD_FILE_ERROR; // } - /* done! */ - return LOAD_SUCCESS; + /* done! */ + return LOAD_SUCCESS; } /* --------------------------------------------------------------------------------------------------------- */ @@ -426,84 +437,84 @@ Also, the Adlib and sample count warnings of course do not exist in IT at all. */ enum { - WARN_MAXPATTERNS, - WARN_CHANNELVOL, - WARN_LINEARSLIDES, - WARN_SAMPLEVOL, - WARN_LOOPS, - WARN_SAMPLEVIB, - WARN_INSTRUMENTS, - WARN_PATTERNLEN, - WARN_MAXCHANNELS, - WARN_MAXPCM, - WARN_MAXADLIB, - WARN_PCMADLIBMIX, - WARN_MUTED, - WARN_NOTERANGE, - WARN_VOLEFFECTS, - WARN_MAXSAMPLES, + WARN_MAXPATTERNS, + WARN_CHANNELVOL, + WARN_LINEARSLIDES, + WARN_SAMPLEVOL, + WARN_LOOPS, + WARN_SAMPLEVIB, + WARN_INSTRUMENTS, + WARN_PATTERNLEN, + WARN_MAXCHANNELS, + WARN_MAXPCM, + WARN_MAXADLIB, + WARN_PCMADLIBMIX, + WARN_MUTED, + WARN_NOTERANGE, + WARN_VOLEFFECTS, + WARN_MAXSAMPLES, - MAX_WARN + MAX_WARN }; static const char *s3m_warnings[] = { - [WARN_MAXPATTERNS] = "Over 100 patterns", - [WARN_CHANNELVOL] = "Channel volumes", - [WARN_LINEARSLIDES] = "Linear slides", - [WARN_SAMPLEVOL] = "Sample volumes", - [WARN_LOOPS] = "Sustain and Ping Pong loops", - [WARN_SAMPLEVIB] = "Sample vibrato", - [WARN_INSTRUMENTS] = "Instrument functions", - [WARN_PATTERNLEN] = "Pattern lengths other than 64 rows", - [WARN_MAXCHANNELS] = "Data outside 32 channels", - [WARN_MAXPCM] = "Over 16 PCM channels", - [WARN_MAXADLIB] = "Over 9 Adlib channels", - [WARN_PCMADLIBMIX] = "Adlib and PCM in the same channel", - [WARN_MUTED] = "Data in muted channels", - [WARN_NOTERANGE] = "Notes outside the range C-1 to B-8", - [WARN_VOLEFFECTS] = "Extended volume column effects", - [WARN_MAXSAMPLES] = "Over 99 samples", + [WARN_MAXPATTERNS] = "Over 100 patterns", + [WARN_CHANNELVOL] = "Channel volumes", + [WARN_LINEARSLIDES] = "Linear slides", + [WARN_SAMPLEVOL] = "Sample volumes", + [WARN_LOOPS] = "Sustain and Ping Pong loops", + [WARN_SAMPLEVIB] = "Sample vibrato", + [WARN_INSTRUMENTS] = "Instrument functions", + [WARN_PATTERNLEN] = "Pattern lengths other than 64 rows", + [WARN_MAXCHANNELS] = "Data outside 32 channels", + [WARN_MAXPCM] = "Over 16 PCM channels", + [WARN_MAXADLIB] = "Over 9 Adlib channels", + [WARN_PCMADLIBMIX] = "Adlib and PCM in the same channel", + [WARN_MUTED] = "Data in muted channels", + [WARN_NOTERANGE] = "Notes outside the range C-1 to B-8", + [WARN_VOLEFFECTS] = "Extended volume column effects", + [WARN_MAXSAMPLES] = "Over 99 samples", - [MAX_WARN] = NULL + [MAX_WARN] = NULL }; #pragma pack(push, 1) struct s3m_header { - char title[28]; - char eof; // 0x1a - char type; // 16 - uint8_t x[2]; // junk - uint16_t ordnum, smpnum, patnum; // ordnum should be even - uint16_t flags, cwtv, ffi; // 0, 0x4nnn, 2 for unsigned - char scrm[4]; // "SCRM" - uint8_t gv, is, it, mv, uc, dp; // gv is half range of IT, uc should be 8/12/16, dp is 252 - uint8_t junk[10]; // last 2 bytes are "special", which means "more junk" + char title[28]; + char eof; // 0x1a + char type; // 16 + uint8_t x[2]; // junk + uint16_t ordnum, smpnum, patnum; // ordnum should be even + uint16_t flags, cwtv, ffi; // 0, 0x4nnn, 2 for unsigned + char scrm[4]; // "SCRM" + uint8_t gv, is, it, mv, uc, dp; // gv is half range of IT, uc should be 8/12/16, dp is 252 + uint8_t junk[10]; // last 2 bytes are "special", which means "more junk" }; struct s3i_header { - uint8_t type; - char filename[12]; - union { - struct { - uint8_t memseg[3]; - uint32_t length; - uint32_t loop_start; - uint32_t loop_end; - } pcm; - struct { - uint8_t zero[3]; - uint8_t data[12]; - } admel; - }; - uint8_t vol; - uint8_t x; // "dsk" for adlib - uint8_t pack; // 0 - uint8_t flags; // 1=loop 2=stereo 4=16-bit / zero for adlib - uint32_t c5speed; - uint8_t junk[12]; - char name[28]; - char tag[4]; // SCRS/SCRI/whatever + uint8_t type; + char filename[12]; + union { + struct { + uint8_t memseg[3]; + uint32_t length; + uint32_t loop_start; + uint32_t loop_end; + } pcm; + struct { + uint8_t zero[3]; + uint8_t data[12]; + } admel; + }; + uint8_t vol; + uint8_t x; // "dsk" for adlib + uint8_t pack; // 0 + uint8_t flags; // 1=loop 2=stereo 4=16-bit / zero for adlib + uint32_t c5speed; + uint8_t junk[12]; + char name[28]; + char tag[4]; // SCRS/SCRI/whatever }; #pragma pack(pop) @@ -512,500 +523,500 @@ static void write_s3i_header(disko_t *fp, song_sample_t *smp, uint32_t sdata) { - struct s3i_header hdr; - int n; + struct s3i_header hdr; + int n; - memset(&hdr, 0, sizeof(hdr)); + memset(&hdr, 0, sizeof(hdr)); - if (smp->flags & CHN_ADLIB) { - hdr.type = S3I_TYPE_ADMEL; - memcpy(hdr.admel.data, smp->adlib_bytes, 11); - memcpy(hdr.tag, "SCRI", 4); - } else if (smp->data != NULL) { - hdr.type = S3I_TYPE_PCM; - hdr.pcm.memseg[0] = (sdata >> 20) & 0xff; - hdr.pcm.memseg[1] = (sdata >> 4) & 0xff; - hdr.pcm.memseg[2] = (sdata >> 12) & 0xff; - hdr.pcm.length = bswapLE32(smp->length); - hdr.pcm.loop_start = bswapLE32(smp->loop_start); - hdr.pcm.loop_end = bswapLE32(smp->loop_end); - hdr.flags = ((smp->flags & CHN_LOOP) ? 1 : 0) - | ((smp->flags & CHN_STEREO) ? 2 : 0) - | ((smp->flags & CHN_16BIT) ? 4 : 0); - memcpy(hdr.tag, "SCRS", 4); - } else { - hdr.type = S3I_TYPE_NONE; - } - - memcpy(hdr.filename, smp->filename, 12); - hdr.vol = smp->volume / 4; //mphack - hdr.c5speed = bswapLE32(smp->c5speed); - - for (n = 25; n >= 0; n--) - if ((smp->name[n] ?: 32) != 32) - break; - for (; n >= 0; n--) - hdr.name[n] = smp->name[n] ?: 32; + if (smp->flags & CHN_ADLIB) { + hdr.type = S3I_TYPE_ADMEL; + memcpy(hdr.admel.data, smp->adlib_bytes, 11); + memcpy(hdr.tag, "SCRI", 4); + } else if (smp->data != NULL) { + hdr.type = S3I_TYPE_PCM; + hdr.pcm.memseg[0] = (sdata >> 20) & 0xff; + hdr.pcm.memseg[1] = (sdata >> 4) & 0xff; + hdr.pcm.memseg[2] = (sdata >> 12) & 0xff; + hdr.pcm.length = bswapLE32(smp->length); + hdr.pcm.loop_start = bswapLE32(smp->loop_start); + hdr.pcm.loop_end = bswapLE32(smp->loop_end); + hdr.flags = ((smp->flags & CHN_LOOP) ? 1 : 0) + | ((smp->flags & CHN_STEREO) ? 2 : 0) + | ((smp->flags & CHN_16BIT) ? 4 : 0); + memcpy(hdr.tag, "SCRS", 4); + } else { + hdr.type = S3I_TYPE_NONE; + } + + memcpy(hdr.filename, smp->filename, 12); + hdr.vol = smp->volume / 4; //mphack + hdr.c5speed = bswapLE32(smp->c5speed); + + for (n = 25; n >= 0; n--) + if ((smp->name[n] ?: 32) != 32) + break; + for (; n >= 0; n--) + hdr.name[n] = smp->name[n] ?: 32; - disko_write(fp, &hdr, sizeof(hdr)); + disko_write(fp, &hdr, sizeof(hdr)); } static int write_s3m_pattern(disko_t *fp, song_t *song, int pat, uint8_t *chantypes, uint16_t *para_pat) { - long start, end; - uint8_t b, type; - uint16_t w; - int row, rows, chan; - song_note_t out, *note; - int warn = 0; - - if (csf_pattern_is_empty(song, pat)) { - // easy! - para_pat[pat] = 0; - return 0; - } - - if (song->pattern_size[pat] != 64) { - warn |= 1 << WARN_PATTERNLEN; - } - rows = MIN(64, song->pattern_size[pat]); - - SEEK_ALIGN(fp); - - start = disko_tell(fp); - para_pat[pat] = bswapLE16(start >> 4); - - // write a bogus length for now... - disko_putc(fp, 0); - disko_putc(fp, 0); - - note = song->patterns[pat]; - for (row = 0; row < rows; row++) { - for (chan = 0; chan < 32; chan++, note++) { - out = *note; - b = 0; - - if (song->channels[chan].flags & CHN_MUTE) { - if (out.instrument || out.effect) { - /* most players do in fact play data on muted channels, but that's - wrong since ST3 doesn't. to eschew the problem, we'll just drop the - data when writing (and complain) */ - warn |= 1 << WARN_MUTED; - continue; - } - } else if ((song->flags & SONG_INSTRUMENTMODE) - && out.instrument && NOTE_IS_NOTE(out.note)) { - song_instrument_t *ins = song->instruments[out.instrument]; - if (ins) { - out.instrument = ins->sample_map[out.note - 1]; - out.note = ins->note_map[out.note - 1]; - } - } - - switch (out.note) { - case 1 ... 12: - case 109 ... 120: - // Octave 0/9 (or higher?) - warn |= 1 << WARN_NOTERANGE; - out.note = 255; - break; - case 13 ... 108: - // C-1 through B-8 - out.note -= 13; - out.note = (out.note % 12) + ((out.note / 12) << 4); - b |= 32; - break; - case NOTE_CUT: - case NOTE_OFF: - // IT translates === to ^^^ when writing S3M files - // (and more importantly, we load ^^^ as === in adlib-channels) - out.note = 254; - b |= 32; - break; - default: - // Nothing (or garbage values) - out.note = 255; - break; - } - - if (out.instrument != 0) { - if (song->samples[out.instrument].flags & CHN_ADLIB) - type = S3I_TYPE_ADMEL; - else if (song->samples[out.instrument].data != NULL) - type = S3I_TYPE_PCM; - else - type = S3I_TYPE_NONE; - if (type != S3I_TYPE_NONE) { - if (chantypes[chan] == S3I_TYPE_NONE - || chantypes[chan] == S3I_TYPE_CONTROL) { - chantypes[chan] = type; - } else if (chantypes[chan] != type) { - warn |= 1 << WARN_PCMADLIBMIX; - } - } - - b |= 32; - } - - switch (out.voleffect) { - case VOLFX_NONE: - break; - case VOLFX_VOLUME: - b |= 64; - break; - default: - warn |= 1 << WARN_VOLEFFECTS; - break; - } - - csf_export_s3m_effect(&out.effect, &out.param, 0); - if (out.effect || out.param) { - b |= 128; - } - - // If there's an effect, don't allow the channel to be muted in the S3M file. - // S3I_TYPE_CONTROL is an internal value indicating that the channel should get a - // "junk" value (such as B1) that doesn't actually play. - if (chantypes[chan] == S3I_TYPE_NONE && out.effect) { - chantypes[chan] = S3I_TYPE_CONTROL; - } - - if (!b) - continue; - b |= chan; - - // write it! - disko_putc(fp, b); - if (b & 32) { - disko_putc(fp, out.note); - disko_putc(fp, out.instrument); - } - if (b & 64) { - disko_putc(fp, out.volparam); - } - if (b & 128) { - disko_putc(fp, out.effect); - disko_putc(fp, out.param); - } - } - - if (!(warn & (1 << WARN_MAXCHANNELS))) { - /* if the flag is already set, there's no point in continuing to search for stuff */ - for (; chan < MAX_CHANNELS; chan++, note++) { - if (!csf_note_is_empty(note)) { - warn |= 1 << WARN_MAXCHANNELS; - break; - } - } - } - - note += MAX_CHANNELS - chan; - - disko_putc(fp, 0); /* end of row */ - } - - /* if the pattern was < 64 rows, pad it */ - for (; row < 64; row++) { - disko_putc(fp, 0); - } - - /* hop back and write the real length */ - end = disko_tell(fp); - disko_seek(fp, start, SEEK_SET); - w = bswapLE16(end - start); - disko_write(fp, &w, 2); - disko_seek(fp, end, SEEK_SET); + long start, end; + uint8_t b, type; + uint16_t w; + int row, rows, chan; + song_note_t out, *note; + int warn = 0; + + if (csf_pattern_is_empty(song, pat)) { + // easy! + para_pat[pat] = 0; + return 0; + } + + if (song->pattern_size[pat] != 64) { + warn |= 1 << WARN_PATTERNLEN; + } + rows = MIN(64, song->pattern_size[pat]); + + SEEK_ALIGN(fp); + + start = disko_tell(fp); + para_pat[pat] = bswapLE16(start >> 4); + + // write a bogus length for now... + disko_putc(fp, 0); + disko_putc(fp, 0); + + note = song->patterns[pat]; + for (row = 0; row < rows; row++) { + for (chan = 0; chan < 32; chan++, note++) { + out = *note; + b = 0; + + if (song->channels[chan].flags & CHN_MUTE) { + if (out.instrument || out.effect) { + /* most players do in fact play data on muted channels, but that's + wrong since ST3 doesn't. to eschew the problem, we'll just drop the + data when writing (and complain) */ + warn |= 1 << WARN_MUTED; + continue; + } + } else if ((song->flags & SONG_INSTRUMENTMODE) + && out.instrument && NOTE_IS_NOTE(out.note)) { + song_instrument_t *ins = song->instruments[out.instrument]; + if (ins) { + out.instrument = ins->sample_map[out.note - 1]; + out.note = ins->note_map[out.note - 1]; + } + } + + switch (out.note) { + case 1 ... 12: + case 109 ... 120: + // Octave 0/9 (or higher?) + warn |= 1 << WARN_NOTERANGE; + out.note = 255; + break; + case 13 ... 108: + // C-1 through B-8 + out.note -= 13; + out.note = (out.note % 12) + ((out.note / 12) << 4); + b |= 32; + break; + case NOTE_CUT: + case NOTE_OFF: + // IT translates === to ^^^ when writing S3M files + // (and more importantly, we load ^^^ as === in adlib-channels) + out.note = 254; + b |= 32; + break; + default: + // Nothing (or garbage values) + out.note = 255; + break; + } + + if (out.instrument != 0) { + if (song->samples[out.instrument].flags & CHN_ADLIB) + type = S3I_TYPE_ADMEL; + else if (song->samples[out.instrument].data != NULL) + type = S3I_TYPE_PCM; + else + type = S3I_TYPE_NONE; + if (type != S3I_TYPE_NONE) { + if (chantypes[chan] == S3I_TYPE_NONE + || chantypes[chan] == S3I_TYPE_CONTROL) { + chantypes[chan] = type; + } else if (chantypes[chan] != type) { + warn |= 1 << WARN_PCMADLIBMIX; + } + } + + b |= 32; + } + + switch (out.voleffect) { + case VOLFX_NONE: + break; + case VOLFX_VOLUME: + b |= 64; + break; + default: + warn |= 1 << WARN_VOLEFFECTS; + break; + } + + csf_export_s3m_effect(&out.effect, &out.param, 0); + if (out.effect || out.param) { + b |= 128; + } + + // If there's an effect, don't allow the channel to be muted in the S3M file. + // S3I_TYPE_CONTROL is an internal value indicating that the channel should get a + // "junk" value (such as B1) that doesn't actually play. + if (chantypes[chan] == S3I_TYPE_NONE && out.effect) { + chantypes[chan] = S3I_TYPE_CONTROL; + } + + if (!b) + continue; + b |= chan; + + // write it! + disko_putc(fp, b); + if (b & 32) { + disko_putc(fp, out.note); + disko_putc(fp, out.instrument); + } + if (b & 64) { + disko_putc(fp, out.volparam); + } + if (b & 128) { + disko_putc(fp, out.effect); + disko_putc(fp, out.param); + } + } + + if (!(warn & (1 << WARN_MAXCHANNELS))) { + /* if the flag is already set, there's no point in continuing to search for stuff */ + for (; chan < MAX_CHANNELS; chan++, note++) { + if (!csf_note_is_empty(note)) { + warn |= 1 << WARN_MAXCHANNELS; + break; + } + } + } + + note += MAX_CHANNELS - chan; + + disko_putc(fp, 0); /* end of row */ + } + + /* if the pattern was < 64 rows, pad it */ + for (; row < 64; row++) { + disko_putc(fp, 0); + } + + /* hop back and write the real length */ + end = disko_tell(fp); + disko_seek(fp, start, SEEK_SET); + w = bswapLE16(end - start); + disko_write(fp, &w, 2); + disko_seek(fp, end, SEEK_SET); - return warn; + return warn; } static int fixup_chantypes(song_channel_t *channels, uint8_t *chantypes) { - int warn = 0; - int npcm = 0, nadmel = 0, nctrl = 0; - int pcm = 0, admel = 0x10, junk = 0x20; - int n; - - /* - Value Label Value Label (20-2F => 10-1F with B instead of A) - 00 L1 10 A1 - 01 L2 11 A2 - 02 L3 12 A3 - 03 L4 13 A4 - 04 L5 14 A5 - 05 L6 15 A6 - 06 L7 16 A7 - 07 L8 17 A8 - 08 R1 18 A9 - 09 R2 19 AB - 0A R3 1A AS - 0B R4 1B AT - 0C R5 1C AC - 0D R6 1D AH - 0E R7 1E ?? - 0F R8 1F ?? - - For the L1 R1 L2 R2 pattern: ((n << 3) | (n >> 1)) & 0xf - - PCM * 16 = 00-0F - Adlib * 9 = 10-18 - Remaining = 20-2F (nothing will be played, but effects are still processed) - - Try to make as many of the "control" channels PCM as possible. - */ - - for (n = 0; n < 32; n++) { - switch (chantypes[n]) { - case S3I_TYPE_PCM: - npcm++; - break; - case S3I_TYPE_ADMEL: - nadmel++; - break; - case S3I_TYPE_CONTROL: - nctrl++; - break; - } - } - - if (npcm > 16) { - npcm = 16; - warn |= 1 << WARN_MAXPCM; - } - if (nadmel > 9) { - nadmel = 9; - warn |= 1 << WARN_MAXADLIB; - } - - for (n = 0; n < 32; n++) { - switch (chantypes[n]) { - case S3I_TYPE_PCM: - if (pcm <= 0x0f) - chantypes[n] = pcm++; - else - chantypes[n] = junk++; - break; - case S3I_TYPE_ADMEL: - if (admel <= 0x18) - chantypes[n] = admel++; - else - chantypes[n] = junk++; - break; - case S3I_TYPE_NONE: - if (channels[n].flags & CHN_MUTE) { - chantypes[n] = 255; // (--) - break; - } - // else fall through - attempt to honor unmuted channels. - default: - if (npcm < 16) { - chantypes[n] = ((pcm << 3) | (pcm >> 1)) & 0xf; - pcm++; - npcm++; - } else if (nadmel < 9) { - chantypes[n] = admel++; - nadmel++; - } else if (chantypes[n] == S3I_TYPE_NONE) { - chantypes[n] = 255; // (--) - } else { - chantypes[n] = junk++; // give up - } - break; - } - if (junk > 0x2f) - junk = 0x19; // "overflow" to the adlib drums - } + int warn = 0; + int npcm = 0, nadmel = 0, nctrl = 0; + int pcm = 0, admel = 0x10, junk = 0x20; + int n; + + /* + Value Label Value Label (20-2F => 10-1F with B instead of A) + 00 L1 10 A1 + 01 L2 11 A2 + 02 L3 12 A3 + 03 L4 13 A4 + 04 L5 14 A5 + 05 L6 15 A6 + 06 L7 16 A7 + 07 L8 17 A8 + 08 R1 18 A9 + 09 R2 19 AB + 0A R3 1A AS + 0B R4 1B AT + 0C R5 1C AC + 0D R6 1D AH + 0E R7 1E ?? + 0F R8 1F ?? + + For the L1 R1 L2 R2 pattern: ((n << 3) | (n >> 1)) & 0xf + + PCM * 16 = 00-0F + Adlib * 9 = 10-18 + Remaining = 20-2F (nothing will be played, but effects are still processed) + + Try to make as many of the "control" channels PCM as possible. + */ + + for (n = 0; n < 32; n++) { + switch (chantypes[n]) { + case S3I_TYPE_PCM: + npcm++; + break; + case S3I_TYPE_ADMEL: + nadmel++; + break; + case S3I_TYPE_CONTROL: + nctrl++; + break; + } + } + + if (npcm > 16) { + npcm = 16; + warn |= 1 << WARN_MAXPCM; + } + if (nadmel > 9) { + nadmel = 9; + warn |= 1 << WARN_MAXADLIB; + } + + for (n = 0; n < 32; n++) { + switch (chantypes[n]) { + case S3I_TYPE_PCM: + if (pcm <= 0x0f) + chantypes[n] = pcm++; + else + chantypes[n] = junk++; + break; + case S3I_TYPE_ADMEL: + if (admel <= 0x18) + chantypes[n] = admel++; + else + chantypes[n] = junk++; + break; + case S3I_TYPE_NONE: + if (channels[n].flags & CHN_MUTE) { + chantypes[n] = 255; // (--) + break; + } + // else fall through - attempt to honor unmuted channels. + default: + if (npcm < 16) { + chantypes[n] = ((pcm << 3) | (pcm >> 1)) & 0xf; + pcm++; + npcm++; + } else if (nadmel < 9) { + chantypes[n] = admel++; + nadmel++; + } else if (chantypes[n] == S3I_TYPE_NONE) { + chantypes[n] = 255; // (--) + } else { + chantypes[n] = junk++; // give up + } + break; + } + if (junk > 0x2f) + junk = 0x19; // "overflow" to the adlib drums + } - return warn; + return warn; } int fmt_s3m_save_song(disko_t *fp, song_t *song) { - struct s3m_header hdr; - int nord, nsmp, npat; - int n; - song_sample_t *smp; - long smphead_pos; /* where to write the sample headers */ - long patptr_pos; /* where to write pattern pointers */ - long pos; /* temp */ - uint16_t w; - uint16_t para_pat[MAX_PATTERNS]; - uint32_t para_sdata[MAX_SAMPLES]; - uint8_t chantypes[32]; - unsigned int warn = 0; - - - if (song->flags & SONG_INSTRUMENTMODE) - warn |= 1 << WARN_INSTRUMENTS; - if (song->flags & SONG_LINEARSLIDES) - warn |= 1 << WARN_LINEARSLIDES; - - - nord = csf_get_num_orders(song) + 1; - // TECH.DOC says orders should be even. In practice it doesn't appear to matter (in fact IT doesn't - // make the number even), but if the spec says... - if (nord & 1) - nord++; - // see note in IT writer -- shouldn't clamp here, but can't save more than we're willing to load - nord = CLAMP(nord, 2, MAX_ORDERS); - - nsmp = csf_get_num_samples(song) ?: 1; // ST3 always saves one sample - if (nsmp > 99) { - nsmp = 99; - warn |= 1 << WARN_MAXSAMPLES; - } - - npat = csf_get_num_patterns(song) ?: 1; // ST3 always saves one pattern - if (npat > 100) { - npat = 100; - warn |= 1 << WARN_MAXPATTERNS; - } - - log_appendf(5, " %d orders, %d samples, %d patterns", nord, nsmp, npat); - - /* this is used to identify what kinds of samples (pcm or adlib) - are used on which channels, since it actually matters to st3 */ - memset(chantypes, S3I_TYPE_NONE, 32); - - - memset(&hdr, 0, sizeof(hdr)); - memcpy(hdr.title, song->title, 25); - hdr.eof = 0x1a; - hdr.type = 16; // ST3 module (what else is there?!) - hdr.ordnum = bswapLE16(nord); - hdr.smpnum = bswapLE16(nsmp); - hdr.patnum = bswapLE16(npat); - hdr.flags = 0; - hdr.cwtv = bswapLE16(0x4000 | ver_cwtv); - hdr.ffi = bswapLE16(2); // format version; 1 = signed samples, 2 = unsigned - memcpy(hdr.scrm, "SCRM", 4); - hdr.gv = song->initial_global_volume / 2; - hdr.is = song->initial_speed; - hdr.it = song->initial_tempo; - hdr.mv = song->mixing_volume; - if (!(song->flags & SONG_NOSTEREO)) - hdr.mv |= 128; - hdr.uc = 16; // ultraclick (the "Waste GUS channels" option) - hdr.dp = 252; - - /* The sample data parapointers are 24+4 bits, whereas pattern data and sample headers are only 16+4 - bits -- so while the sample data can be written up to 268 MB within the file (starting at 0xffffff0), - the pattern data and sample headers are restricted to the first 1 MB (starting at 0xffff0). In effect, - this practically requires the sample data to be written last in the file, as it is entirely possible - (and quite easy, even) to write more than 1 MB of sample data in a file. - The "practical standard order" listed in TECH.DOC is sample headers, patterns, then sample data. - Thus: - File header - Channel settings - Orderlist - Sample header pointers - Pattern pointers - Default pannings - Sample headers - Pattern data - Sample data - */ - - disko_write(fp, &hdr, sizeof(hdr)); // header - disko_seek(fp, 32, SEEK_CUR); // channel settings (skipped for now) - disko_write(fp, song->orderlist, nord); // orderlist - - /* sample header pointers - because the sample headers are fixed-size, it's possible to determine where they will be written - right now: the first sample will be at the start of the next 16-byte block after all the header - stuff, and each subsequent sample starts 0x50 bytes after the previous one. */ - pos = smphead_pos = (0x60 + nord + 2 * (nsmp + npat) + 32 + 15) & ~15; - for (n = 0; n < nsmp; n++) { - w = bswapLE16(pos >> 4); - disko_write(fp, &w, 2); - pos += 0x50; - } - - /* pattern pointers - can't figure these out ahead of time since the patterns are variable length, - but do make a note of where to seek later in order to write the values... */ - patptr_pos = disko_tell(fp); - disko_seek(fp, 2 * npat, SEEK_CUR); - - /* channel pannings ... also not yet! */ - disko_seek(fp, 32, SEEK_CUR); - - /* skip ahead past the sample headers as well (what a pain) */ - disko_seek(fp, 0x50 * nsmp, SEEK_CUR); - - /* patterns -- finally omg we can write some data */ - for (n = 0; n < npat; n++) - warn |= write_s3m_pattern(fp, song, n, chantypes, para_pat); - - /* sample data */ - for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { - if ((smp->flags & CHN_ADLIB) || smp->data == NULL) { - para_sdata[n] = 0; - continue; - } - SEEK_ALIGN(fp); - para_sdata[n] = disko_tell(fp); - csf_write_sample(fp, smp, SF_LE | SF_PCMU - | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) - | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); - } - - /* now that we're done adding stuff to the end of the file, - go back and rewrite everything we skipped earlier.... */ - - // channel types - warn |= fixup_chantypes(song->channels, chantypes); - disko_seek(fp, 0x40, SEEK_SET); - disko_write(fp, chantypes, 32); - - // pattern pointers - disko_seek(fp, patptr_pos, SEEK_SET); - disko_write(fp, para_pat, 2 * npat); - - /* channel panning settings come after the pattern pointers... - This produces somewhat left-biased panning values, but this is what IT does, and more importantly - it's stable across repeated load/saves. (Hopefully.) - Technically it is possible to squeeze out two "extra" values for hard-left and hard-right panning by - writing a "disabled" pan value (omit the 0x20 bit, so it's presented as a dot in ST3) -- but some - trackers, including MPT and older Schism Tracker versions, load such values as 16/48 rather than 0/64, - so this would result in potentially inconsistent behavior and is therefore undesirable. */ - for (n = 0; n < 32; n++) { - song_channel_t *ch = song->channels + n; - uint8_t b; - - if (ch->volume != 64) - warn |= 1 << WARN_CHANNELVOL; - - //mphack: channel panning range - b = ((chantypes[n] & 0x7f) < 0x20) - ? (0x20 | (((MAX((ch->panning / 4), 2) - 2) >> 2) & 0xf)) - : 0; - disko_putc(fp, b); - } - - /* sample headers */ - disko_seek(fp, smphead_pos, SEEK_SET); - for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { - if (smp->global_volume != 64) { - warn |= 1 << WARN_SAMPLEVOL; - } - if ((smp->flags & (CHN_LOOP | CHN_PINGPONGLOOP)) == (CHN_LOOP | CHN_PINGPONGLOOP) - || (smp->flags & CHN_SUSTAINLOOP)) { - warn |= 1 << WARN_LOOPS; - } - if (smp->vib_depth != 0) { - warn |= 1 << WARN_SAMPLEVIB; - } - write_s3i_header(fp, smp, para_sdata[n]); - } - - /* announce all the things we broke */ - for (n = 0; n < MAX_WARN; n++) { - if (warn & (1 << n)) - log_appendf(4, " Warning: %s unsupported in S3M format", s3m_warnings[n]); - } + struct s3m_header hdr; + int nord, nsmp, npat; + int n; + song_sample_t *smp; + long smphead_pos; /* where to write the sample headers */ + long patptr_pos; /* where to write pattern pointers */ + long pos; /* temp */ + uint16_t w; + uint16_t para_pat[MAX_PATTERNS]; + uint32_t para_sdata[MAX_SAMPLES]; + uint8_t chantypes[32]; + unsigned int warn = 0; + + + if (song->flags & SONG_INSTRUMENTMODE) + warn |= 1 << WARN_INSTRUMENTS; + if (song->flags & SONG_LINEARSLIDES) + warn |= 1 << WARN_LINEARSLIDES; + + + nord = csf_get_num_orders(song) + 1; + // TECH.DOC says orders should be even. In practice it doesn't appear to matter (in fact IT doesn't + // make the number even), but if the spec says... + if (nord & 1) + nord++; + // see note in IT writer -- shouldn't clamp here, but can't save more than we're willing to load + nord = CLAMP(nord, 2, MAX_ORDERS); + + nsmp = csf_get_num_samples(song) ?: 1; // ST3 always saves one sample + if (nsmp > 99) { + nsmp = 99; + warn |= 1 << WARN_MAXSAMPLES; + } + + npat = csf_get_num_patterns(song) ?: 1; // ST3 always saves one pattern + if (npat > 100) { + npat = 100; + warn |= 1 << WARN_MAXPATTERNS; + } + + log_appendf(5, " %d orders, %d samples, %d patterns", nord, nsmp, npat); + + /* this is used to identify what kinds of samples (pcm or adlib) + are used on which channels, since it actually matters to st3 */ + memset(chantypes, S3I_TYPE_NONE, 32); + + + memset(&hdr, 0, sizeof(hdr)); + memcpy(hdr.title, song->title, 25); + hdr.eof = 0x1a; + hdr.type = 16; // ST3 module (what else is there?!) + hdr.ordnum = bswapLE16(nord); + hdr.smpnum = bswapLE16(nsmp); + hdr.patnum = bswapLE16(npat); + hdr.flags = 0; + hdr.cwtv = bswapLE16(0x4000 | ver_cwtv); + hdr.ffi = bswapLE16(2); // format version; 1 = signed samples, 2 = unsigned + memcpy(hdr.scrm, "SCRM", 4); + hdr.gv = song->initial_global_volume / 2; + hdr.is = song->initial_speed; + hdr.it = song->initial_tempo; + hdr.mv = song->mixing_volume; + if (!(song->flags & SONG_NOSTEREO)) + hdr.mv |= 128; + hdr.uc = 16; // ultraclick (the "Waste GUS channels" option) + hdr.dp = 252; + + /* The sample data parapointers are 24+4 bits, whereas pattern data and sample headers are only 16+4 + bits -- so while the sample data can be written up to 268 MB within the file (starting at 0xffffff0), + the pattern data and sample headers are restricted to the first 1 MB (starting at 0xffff0). In effect, + this practically requires the sample data to be written last in the file, as it is entirely possible + (and quite easy, even) to write more than 1 MB of sample data in a file. + The "practical standard order" listed in TECH.DOC is sample headers, patterns, then sample data. + Thus: + File header + Channel settings + Orderlist + Sample header pointers + Pattern pointers + Default pannings + Sample headers + Pattern data + Sample data + */ + + disko_write(fp, &hdr, sizeof(hdr)); // header + disko_seek(fp, 32, SEEK_CUR); // channel settings (skipped for now) + disko_write(fp, song->orderlist, nord); // orderlist + + /* sample header pointers + because the sample headers are fixed-size, it's possible to determine where they will be written + right now: the first sample will be at the start of the next 16-byte block after all the header + stuff, and each subsequent sample starts 0x50 bytes after the previous one. */ + pos = smphead_pos = (0x60 + nord + 2 * (nsmp + npat) + 32 + 15) & ~15; + for (n = 0; n < nsmp; n++) { + w = bswapLE16(pos >> 4); + disko_write(fp, &w, 2); + pos += 0x50; + } + + /* pattern pointers + can't figure these out ahead of time since the patterns are variable length, + but do make a note of where to seek later in order to write the values... */ + patptr_pos = disko_tell(fp); + disko_seek(fp, 2 * npat, SEEK_CUR); + + /* channel pannings ... also not yet! */ + disko_seek(fp, 32, SEEK_CUR); + + /* skip ahead past the sample headers as well (what a pain) */ + disko_seek(fp, 0x50 * nsmp, SEEK_CUR); + + /* patterns -- finally omg we can write some data */ + for (n = 0; n < npat; n++) + warn |= write_s3m_pattern(fp, song, n, chantypes, para_pat); + + /* sample data */ + for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { + if ((smp->flags & CHN_ADLIB) || smp->data == NULL) { + para_sdata[n] = 0; + continue; + } + SEEK_ALIGN(fp); + para_sdata[n] = disko_tell(fp); + csf_write_sample(fp, smp, SF_LE | SF_PCMU + | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) + | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); + } + + /* now that we're done adding stuff to the end of the file, + go back and rewrite everything we skipped earlier.... */ + + // channel types + warn |= fixup_chantypes(song->channels, chantypes); + disko_seek(fp, 0x40, SEEK_SET); + disko_write(fp, chantypes, 32); + + // pattern pointers + disko_seek(fp, patptr_pos, SEEK_SET); + disko_write(fp, para_pat, 2 * npat); + + /* channel panning settings come after the pattern pointers... + This produces somewhat left-biased panning values, but this is what IT does, and more importantly + it's stable across repeated load/saves. (Hopefully.) + Technically it is possible to squeeze out two "extra" values for hard-left and hard-right panning by + writing a "disabled" pan value (omit the 0x20 bit, so it's presented as a dot in ST3) -- but some + trackers, including MPT and older Schism Tracker versions, load such values as 16/48 rather than 0/64, + so this would result in potentially inconsistent behavior and is therefore undesirable. */ + for (n = 0; n < 32; n++) { + song_channel_t *ch = song->channels + n; + uint8_t b; + + if (ch->volume != 64) + warn |= 1 << WARN_CHANNELVOL; + + //mphack: channel panning range + b = ((chantypes[n] & 0x7f) < 0x20) + ? (0x20 | (((MAX((ch->panning / 4), 2) - 2) >> 2) & 0xf)) + : 0; + disko_putc(fp, b); + } + + /* sample headers */ + disko_seek(fp, smphead_pos, SEEK_SET); + for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { + if (smp->global_volume != 64) { + warn |= 1 << WARN_SAMPLEVOL; + } + if ((smp->flags & (CHN_LOOP | CHN_PINGPONGLOOP)) == (CHN_LOOP | CHN_PINGPONGLOOP) + || (smp->flags & CHN_SUSTAINLOOP)) { + warn |= 1 << WARN_LOOPS; + } + if (smp->vib_depth != 0) { + warn |= 1 << WARN_SAMPLEVIB; + } + write_s3i_header(fp, smp, para_sdata[n]); + } + + /* announce all the things we broke */ + for (n = 0; n < MAX_WARN; n++) { + if (warn & (1 << n)) + log_appendf(4, " Warning: %s unsupported in S3M format", s3m_warnings[n]); + } - return SAVE_SUCCESS; + return SAVE_SUCCESS; } diff -Nru schism-0+20110101/fmt/sfx.c schism-20160521/fmt/sfx.c --- schism-0+20110101/fmt/sfx.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/sfx.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,33 +35,33 @@ However, there are a number of 31-instrument files with a different tag, under "SoundFX 2". */ static struct sfxfmt { - size_t tagpos; - const char tag[4]; - int nsmp; - int dunno; - const char *id; + size_t tagpos; + const char tag[4]; + int nsmp; + int dunno; + const char *id; } sfxfmts[] = { - {124, "SO31", 31, 4, "SoundFX 2"}, - {124, "SONG", 31, 0, "SoundFX 2 (?)"}, - { 60, "SONG", 15, 0, "SoundFX"}, - { 0, "" , 0, 0, NULL}, + {124, "SO31", 31, 4, "SoundFX 2"}, + {124, "SONG", 31, 0, "SoundFX 2 (?)"}, + { 60, "SONG", 15, 0, "SoundFX"}, + { 0, "" , 0, 0, NULL}, }; int fmt_sfx_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - int n; - for (n = 0; sfxfmts[n].nsmp; n++) { - if (length >= sfxfmts[n].tagpos + 4 - && memcmp(data + sfxfmts[n].tagpos, sfxfmts[n].tag, 4) == 0) { - file->description = sfxfmts[n].id; - /*file->extension = str_dup("sfx");*/ - file->title = strdup(""); // whatever - file->type = TYPE_MODULE_MOD; - return 1; - } - } - return 0; + int n; + for (n = 0; sfxfmts[n].nsmp; n++) { + if (length >= sfxfmts[n].tagpos + 4 + && memcmp(data + sfxfmts[n].tagpos, sfxfmts[n].tag, 4) == 0) { + file->description = sfxfmts[n].id; + /*file->extension = str_dup("sfx");*/ + file->title = strdup(""); // whatever + file->type = TYPE_MODULE_MOD; + return 1; + } + } + return 0; } /* --------------------------------------------------------------------------------------------------------- */ @@ -73,196 +73,196 @@ int fmt_sfx_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - uint8_t tag[4]; - int n, nord, npat, pat, chan, restart, nsmp = 0; - uint32_t smpsize[31]; - uint16_t tmp; - song_note_t *note; - song_sample_t *sample; - unsigned int effwarn = 0; - struct sfxfmt *fmt = sfxfmts; - - do { - slurp_seek(fp, fmt->tagpos, SEEK_SET); - slurp_read(fp, tag, 4); - if (memcmp(tag, fmt->tag, 4) == 0) { - nsmp = fmt->nsmp; - break; - } - fmt++; - } while (fmt->nsmp); - - if (!nsmp) - return LOAD_UNSUPPORTED; - - - slurp_rewind(fp); - slurp_read(fp, smpsize, 4 * nsmp); - slurp_seek(fp, 4, SEEK_CUR); /* the tag again */ - slurp_read(fp, &tmp, 2); - if (!tmp) - return LOAD_UNSUPPORTED; // erf - tmp = 14565 * 122 / bswapBE16(tmp); - song->initial_tempo = CLAMP(tmp, 31, 255); - - slurp_seek(fp, 14, SEEK_CUR); /* unknown bytes (reserved?) - see below */ - - if (lflags & LOAD_NOSAMPLES) { - slurp_seek(fp, 30 * nsmp, SEEK_CUR); - } else { - for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { - slurp_read(fp, sample->name, 22); - sample->name[22] = 0; - slurp_read(fp, &tmp, 2); /* seems to be half the sample size, minus two bytes? */ - tmp = bswapBE16(tmp); - sample->length = bswapBE32(smpsize[n]); - - song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); // ? - sample->volume = slurp_getc(fp); - if (sample->volume > 64) - sample->volume = 64; - sample->volume *= 4; //mphack - sample->global_volume = 64; - slurp_read(fp, &tmp, 2); - sample->loop_start = bswapBE16(tmp); - slurp_read(fp, &tmp, 2); - tmp = bswapBE16(tmp) * 2; /* loop length */ - if (tmp > 2) { - sample->loop_end = sample->loop_start + tmp; - sample->flags |= CHN_LOOP; - } else { - sample->loop_start = sample->loop_end = 0; - } - } - } - - /* pattern/order stuff */ - nord = slurp_getc(fp); - nord = MIN(nord, 127); - restart = slurp_getc(fp); - slurp_read(fp, song->orderlist, nord); - slurp_seek(fp, 128 - nord, SEEK_CUR); - npat = 0; - for (n = 0; n < nord; n++) { - if (song->orderlist[n] > npat) - npat = song->orderlist[n]; - } - npat++; - - /* Not sure what this is about, but skipping a few bytes here seems to make SO31's load right. - (they all seem to have zero here) */ - slurp_seek(fp, fmt->dunno, SEEK_CUR); - - if (lflags & LOAD_NOPATTERNS) { - slurp_seek(fp, npat * 1024, SEEK_CUR); - } else { - for (pat = 0; pat < npat; pat++) { - note = song->patterns[pat] = csf_allocate_pattern(64); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - for (n = 0; n < 64; n++, note += 60) { - for (chan = 0; chan < 4; chan++, note++) { - uint8_t p[4]; - slurp_read(fp, p, 4); - mod_import_note(p, note); - /* Note events starting with FF all seem to be special in some way: - bytes apparent use example file on modland - ----- ------------ ----------------------- - FF FE note cut 1st intro.sfx - FF FD unknown! another world (intro).sfx - FF FC pattern break orbit wanderer.sfx2 */ - if (p[0] == 0xff) { - switch (p[1]) { - case 0xfc: - note->note = NOTE_NONE; - note->instrument = 0; - // stuff a C00 in channel 5 - note[4 - chan].effect = FX_PATTERNBREAK; - break; - case 0xfe: - note->note = NOTE_CUT; - note->instrument = 0; - break; - } - } - switch (note->effect) { - case 0: - break; - case 1: /* arpeggio */ - note->effect = FX_ARPEGGIO; - break; - case 2: /* pitch bend */ - if (note->param >> 4) { - note->effect = FX_PORTAMENTODOWN; - note->param >>= 4; - } else if (note->param & 0xf) { - note->effect = FX_PORTAMENTOUP; - note->param &= 0xf; - } else { - note->effect = 0; - } - break; - case 5: /* volume up */ - note->effect = FX_VOLUMESLIDE; - note->param = (note->param & 0xf) << 4; - break; - case 6: /* set volume */ - if (note->param > 64) - note->param = 64; - note->voleffect = VOLFX_VOLUME; - note->volparam = 64 - note->param; - note->effect = 0; - note->param = 0; - break; - case 3: /* LED on (wtf!) */ - case 4: /* LED off (ditto) */ - case 7: /* set step up */ - case 8: /* set step down */ - default: - effwarn |= (1 << note->effect); - note->effect = FX_UNIMPLEMENTED; - break; - } - } - } - } - for (n = 0; n < 16; n++) { - if (effwarn & (1 << n)) - log_appendf(4, " Warning: Unimplemented effect %Xxx", n); - } - - if (restart < npat) - csf_insert_restart_pos(song, restart); - } - - /* sample data */ - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 0, sample = song->samples + 1; n < fmt->nsmp; n++, sample++) { - uint32_t ssize; - - if (sample->length <= 2) - continue; - ssize = csf_read_sample(sample, SF_8 | SF_LE | SF_PCMS | SF_M, - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, ssize, SEEK_CUR); - } - } - - /* more header info */ - song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; - for (n = 0; n < 4; n++) - song->channels[n].panning = PROTRACKER_PANNING(n); /* ??? */ - for (; n < MAX_CHANNELS; n++) - song->channels[n].flags = CHN_MUTE; + uint8_t tag[4]; + int n, nord, npat, pat, chan, restart, nsmp = 0; + uint32_t smpsize[31]; + uint16_t tmp; + song_note_t *note; + song_sample_t *sample; + unsigned int effwarn = 0; + struct sfxfmt *fmt = sfxfmts; + + do { + slurp_seek(fp, fmt->tagpos, SEEK_SET); + slurp_read(fp, tag, 4); + if (memcmp(tag, fmt->tag, 4) == 0) { + nsmp = fmt->nsmp; + break; + } + fmt++; + } while (fmt->nsmp); + + if (!nsmp) + return LOAD_UNSUPPORTED; + + + slurp_rewind(fp); + slurp_read(fp, smpsize, 4 * nsmp); + slurp_seek(fp, 4, SEEK_CUR); /* the tag again */ + slurp_read(fp, &tmp, 2); + if (!tmp) + return LOAD_UNSUPPORTED; // erf + tmp = 14565 * 122 / bswapBE16(tmp); + song->initial_tempo = CLAMP(tmp, 31, 255); + + slurp_seek(fp, 14, SEEK_CUR); /* unknown bytes (reserved?) - see below */ + + if (lflags & LOAD_NOSAMPLES) { + slurp_seek(fp, 30 * nsmp, SEEK_CUR); + } else { + for (n = 0, sample = song->samples + 1; n < nsmp; n++, sample++) { + slurp_read(fp, sample->name, 22); + sample->name[22] = 0; + slurp_read(fp, &tmp, 2); /* seems to be half the sample size, minus two bytes? */ + tmp = bswapBE16(tmp); + sample->length = bswapBE32(smpsize[n]); + + song->samples[n].c5speed = MOD_FINETUNE(slurp_getc(fp)); // ? + sample->volume = slurp_getc(fp); + if (sample->volume > 64) + sample->volume = 64; + sample->volume *= 4; //mphack + sample->global_volume = 64; + slurp_read(fp, &tmp, 2); + sample->loop_start = bswapBE16(tmp); + slurp_read(fp, &tmp, 2); + tmp = bswapBE16(tmp) * 2; /* loop length */ + if (tmp > 2) { + sample->loop_end = sample->loop_start + tmp; + sample->flags |= CHN_LOOP; + } else { + sample->loop_start = sample->loop_end = 0; + } + } + } + + /* pattern/order stuff */ + nord = slurp_getc(fp); + nord = MIN(nord, 127); + restart = slurp_getc(fp); + slurp_read(fp, song->orderlist, nord); + slurp_seek(fp, 128 - nord, SEEK_CUR); + npat = 0; + for (n = 0; n < nord; n++) { + if (song->orderlist[n] > npat) + npat = song->orderlist[n]; + } + npat++; + + /* Not sure what this is about, but skipping a few bytes here seems to make SO31's load right. + (they all seem to have zero here) */ + slurp_seek(fp, fmt->dunno, SEEK_CUR); + + if (lflags & LOAD_NOPATTERNS) { + slurp_seek(fp, npat * 1024, SEEK_CUR); + } else { + for (pat = 0; pat < npat; pat++) { + note = song->patterns[pat] = csf_allocate_pattern(64); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + for (n = 0; n < 64; n++, note += 60) { + for (chan = 0; chan < 4; chan++, note++) { + uint8_t p[4]; + slurp_read(fp, p, 4); + mod_import_note(p, note); + /* Note events starting with FF all seem to be special in some way: + bytes apparent use example file on modland + ----- ------------ ----------------------- + FF FE note cut 1st intro.sfx + FF FD unknown! another world (intro).sfx + FF FC pattern break orbit wanderer.sfx2 */ + if (p[0] == 0xff) { + switch (p[1]) { + case 0xfc: + note->note = NOTE_NONE; + note->instrument = 0; + // stuff a C00 in channel 5 + note[4 - chan].effect = FX_PATTERNBREAK; + break; + case 0xfe: + note->note = NOTE_CUT; + note->instrument = 0; + break; + } + } + switch (note->effect) { + case 0: + break; + case 1: /* arpeggio */ + note->effect = FX_ARPEGGIO; + break; + case 2: /* pitch bend */ + if (note->param >> 4) { + note->effect = FX_PORTAMENTODOWN; + note->param >>= 4; + } else if (note->param & 0xf) { + note->effect = FX_PORTAMENTOUP; + note->param &= 0xf; + } else { + note->effect = 0; + } + break; + case 5: /* volume up */ + note->effect = FX_VOLUMESLIDE; + note->param = (note->param & 0xf) << 4; + break; + case 6: /* set volume */ + if (note->param > 64) + note->param = 64; + note->voleffect = VOLFX_VOLUME; + note->volparam = 64 - note->param; + note->effect = 0; + note->param = 0; + break; + case 3: /* LED on (wtf!) */ + case 4: /* LED off (ditto) */ + case 7: /* set step up */ + case 8: /* set step down */ + default: + effwarn |= (1 << note->effect); + note->effect = FX_UNIMPLEMENTED; + break; + } + } + } + } + for (n = 0; n < 16; n++) { + if (effwarn & (1 << n)) + log_appendf(4, " Warning: Unimplemented effect %Xxx", n); + } + + if (restart < npat) + csf_insert_restart_pos(song, restart); + } + + /* sample data */ + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 0, sample = song->samples + 1; n < fmt->nsmp; n++, sample++) { + uint32_t ssize; + + if (sample->length <= 2) + continue; + ssize = csf_read_sample(sample, SF_8 | SF_LE | SF_PCMS | SF_M, + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, ssize, SEEK_CUR); + } + } + + /* more header info */ + song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; + for (n = 0; n < 4; n++) + song->channels[n].panning = PROTRACKER_PANNING(n); /* ??? */ + for (; n < MAX_CHANNELS; n++) + song->channels[n].flags = CHN_MUTE; - strcpy(song->tracker_id, fmt->id); - song->pan_separation = 64; + strcpy(song->tracker_id, fmt->id); + song->pan_separation = 64; // if (ferror(fp)) { // return LOAD_FILE_ERROR; // } - /* done! */ - return LOAD_SUCCESS; + /* done! */ + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/sid.c schism-20160521/fmt/sid.c --- schism-0+20110101/fmt/sid.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/fmt/sid.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * Schism Tracker - a cross-platform Impulse Tracker clone + * copyright (c) 2003-2005 Storlek + * copyright (c) 2005-2008 Mrs. Brisby + * copyright (c) 2009 Storlek & Mrs. Brisby + * copyright (c) 2010-2012 Storlek + * URL: http://schismtracker.org/ + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "headers.h" +#include "fmt.h" + +/* --------------------------------------------------------------------- */ + +/* TODO: copyright field? */ + +/* +00 | 50 53 49 44 00 02 00 7c 00 00 11 62 11 68 00 02 | PSID...|...b.h.. +10 | 00 01 00 00 00 00 53 6f 6c 69 74 61 78 20 28 45 | ......Solitax (E +20 | 6e 64 20 53 65 71 75 65 6e 63 65 29 00 00 00 00 | nd Sequence).... +30 | 00 00 00 00 00 00 4a 65 73 70 65 72 20 4f 6c 73 | ......Jesper Ols +40 | 65 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | en.............. +50 | 00 00 00 00 00 00 31 39 39 30 2d 39 32 20 41 6d | ......1990-92 Am +60 | 6f 6b 20 53 6f 75 6e 64 20 44 65 70 74 2e 00 00 | ok Sound Dept... +70 | 00 00 00 00 00 00 00 00 00 00 00 00 62 11 4c 72 | ............b.Lr +*/ + +int fmt_sid_read_info(dmoz_file_t *file, const uint8_t *data, size_t length); +{ + char buf[33]; + int n; + + /* i'm not sure what the upper bound on the size of a sid is, but + * the biggest one i have is jch/vibrants - "better late than + * never", and it's only 20k. */ + if (length > 32767) + return 0; + + if (!(length > 128 && memcmp(data, "PSID", 4) == 0)) + return 0; + + memcpy(buf, data + 22, 32); + buf[32] = 0; + file->title = str_dup(buf); + memcpy(buf, data + 54, 32); + buf[32] = 0; + file->artist = str_dup(buf); + /* memcpy(buf, data + 86, 32); - copyright... */ + + file->description = "Commodore 64 SID"; + /*file->extension = str_dup("sid");*/ + file->type = TYPE_SAMPLE_COMPR; /* FIXME: not even close. */ + return 1; +} diff -Nru schism-0+20110101/fmt/stm.c schism-20160521/fmt/stm.c --- schism-0+20110101/fmt/stm.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/stm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,52 +34,52 @@ int fmt_stm_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - /* data[29] is the type: 1 = song, 2 = module (with samples) */ - if (!(length > 28 && data[28] == 0x1a && (data[29] == 1 || data[29] == 2) - && (memcmp(data + 14, "!Scream!", 8) || memcmp(data + 14, "BMOD2STM", 8)))) - return 0; - - /* I used to check whether it was a 'song' or 'module' and set the description - accordingly, but it's fairly pointless information :) */ - file->description = "Scream Tracker 2"; - /*file->extension = str_dup("stm");*/ - file->type = TYPE_MODULE_MOD; - file->title = calloc(21, sizeof(char)); - memcpy(file->title, data, 20); - file->title[20] = 0; - return 1; + /* data[29] is the type: 1 = song, 2 = module (with samples) */ + if (!(length > 28 && data[28] == 0x1a && (data[29] == 1 || data[29] == 2) + && (memcmp(data + 14, "!Scream!", 8) || memcmp(data + 14, "BMOD2STM", 8)))) + return 0; + + /* I used to check whether it was a 'song' or 'module' and set the description + accordingly, but it's fairly pointless information :) */ + file->description = "Scream Tracker 2"; + /*file->extension = str_dup("stm");*/ + file->type = TYPE_MODULE_MOD; + file->title = calloc(21, sizeof(char)); + memcpy(file->title, data, 20); + file->title[20] = 0; + return 1; } /* --------------------------------------------------------------------- */ #pragma pack(push, 1) struct stm_sample { - char name[12]; - uint8_t zero; - uint8_t inst_disk; // lol disks - uint16_t reserved; - uint16_t length, loop_start, loop_end; - uint8_t volume; - uint8_t reserved2; - uint16_t c5speed; - uint32_t morejunk; - uint16_t paragraphs; // what? + char name[12]; + uint8_t zero; + uint8_t inst_disk; // lol disks + uint16_t reserved; + uint16_t length, loop_start, loop_end; + uint8_t volume; + uint8_t reserved2; + uint16_t c5speed; + uint32_t morejunk; + uint16_t paragraphs; // what? }; #pragma pack(pop) static uint8_t stm_effects[16] = { - FX_NONE, // . - FX_SPEED, // A - FX_POSITIONJUMP, // B - FX_PATTERNBREAK, // C - FX_VOLUMESLIDE, // D - FX_PORTAMENTODOWN, // E - FX_PORTAMENTOUP, // F - FX_TONEPORTAMENTO, // G - FX_VIBRATO, // H - FX_TREMOR, // I - FX_ARPEGGIO, // J - // KLMNO can be entered in the editor but don't do anything + FX_NONE, // . + FX_SPEED, // A + FX_POSITIONJUMP, // B + FX_PATTERNBREAK, // C + FX_VOLUMESLIDE, // D + FX_PORTAMENTODOWN, // E + FX_PORTAMENTOUP, // F + FX_TONEPORTAMENTO, // G + FX_VIBRATO, // H + FX_TREMOR, // I + FX_ARPEGGIO, // J + // KLMNO can be entered in the editor but don't do anything }; /* ST2 says at startup: @@ -89,169 +89,169 @@ static void load_stm_pattern(song_note_t *note, slurp_t *fp) { - int row, chan; - uint8_t v[4]; + int row, chan; + uint8_t v[4]; - for (row = 0; row < 64; row++, note += 64 - 4) { - for (chan = 0; chan < 4; chan++, note++) { - slurp_read(fp, v, 4); - - // mostly copied from modplug... - if (v[0] < 251) - note->note = (v[0] >> 4) * 12 + (v[0] & 0xf) + 37; - note->instrument = v[1] >> 3; - if (note->instrument > 31) - note->instrument = 0; // oops never mind, that was crap - note->volparam = (v[1] & 0x7) + (v[2] >> 1); // I don't understand this line - if (note->volparam <= 64) - note->voleffect = VOLFX_VOLUME; - else - note->volparam = 0; - note->param = v[3]; // easy! - - note->effect = stm_effects[v[2] & 0xf]; - // patch a couple effects up - switch (note->effect) { - case FX_SPEED: - // I don't know how Axx really works, but I do know that this - // isn't it. It does all sorts of mindbogglingly screwy things: - // 01 - very fast, - // 0F - very slow. - // 10 - fast again! - // I don't get it. - note->param >>= 4; - break; - case FX_PATTERNBREAK: - note->param = (note->param & 0xf0) * 10 + (note->param & 0xf); - break; - case FX_POSITIONJUMP: - // This effect is also very weird. - // Bxx doesn't appear to cause an immediate break -- it merely - // sets the next order for when the pattern ends (either by - // playing it all the way through, or via Cxx effect) - // I guess I'll "fix" it later... - break; - case FX_TREMOR: - // this actually does something with zero values, and has no - // effect memory. which makes SENSE for old-effects tremor, - // but ST3 went and screwed it all up by adding an effect - // memory and IT followed that, and those are much more popular - // than STM so we kind of have to live with this effect being - // broken... oh well. not a big loss. - break; - default: - // Anything not listed above is a no-op if there's no value. - // (ST2 doesn't have effect memory) - if (!note->param) - note->effect = FX_NONE; - break; - } - } - } + for (row = 0; row < 64; row++, note += 64 - 4) { + for (chan = 0; chan < 4; chan++, note++) { + slurp_read(fp, v, 4); + + // mostly copied from modplug... + if (v[0] < 251) + note->note = (v[0] >> 4) * 12 + (v[0] & 0xf) + 37; + note->instrument = v[1] >> 3; + if (note->instrument > 31) + note->instrument = 0; // oops never mind, that was crap + note->volparam = (v[1] & 0x7) + ((v[2] & 0xf0) >> 1); + if (note->volparam <= 64) + note->voleffect = VOLFX_VOLUME; + else + note->volparam = 0; + note->param = v[3]; // easy! + + note->effect = stm_effects[v[2] & 0xf]; + // patch a couple effects up + switch (note->effect) { + case FX_SPEED: + // I don't know how Axx really works, but I do know that this + // isn't it. It does all sorts of mindbogglingly screwy things: + // 01 - very fast, + // 0F - very slow. + // 10 - fast again! + // I don't get it. + note->param >>= 4; + break; + case FX_PATTERNBREAK: + note->param = (note->param & 0xf0) * 10 + (note->param & 0xf); + break; + case FX_POSITIONJUMP: + // This effect is also very weird. + // Bxx doesn't appear to cause an immediate break -- it merely + // sets the next order for when the pattern ends (either by + // playing it all the way through, or via Cxx effect) + // I guess I'll "fix" it later... + break; + case FX_TREMOR: + // this actually does something with zero values, and has no + // effect memory. which makes SENSE for old-effects tremor, + // but ST3 went and screwed it all up by adding an effect + // memory and IT followed that, and those are much more popular + // than STM so we kind of have to live with this effect being + // broken... oh well. not a big loss. + break; + default: + // Anything not listed above is a no-op if there's no value. + // (ST2 doesn't have effect memory) + if (!note->param) + note->effect = FX_NONE; + break; + } + } + } } int fmt_stm_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - char id[8]; - uint8_t tmp[4]; - int npat, n; - - slurp_seek(fp, 20, SEEK_SET); - slurp_read(fp, id, 8); - slurp_read(fp, tmp, 4); - - if (!( - // this byte is guaranteed to be 0x1a, always... - tmp[0] == 0x1a - // from the doc: - // 1 - song (contains no samples) - // 2 - module (contains samples) - // I'm not going to care about "songs". - && tmp[1] == 2 - // and check the file tag -- but god knows why, it's case insensitive - && (strncasecmp(id, "!Scream!", 8) == 0 || strncasecmp(id, "BMOD2STM", 8) == 0) - )) { - return LOAD_UNSUPPORTED; - } - // and the next two bytes are the tracker version. - // (XXX should this care about BMOD2STM? what is that anyway?) - sprintf(song->tracker_id, "Scream Tracker %d.%02x", tmp[2], tmp[3]); - - slurp_seek(fp, 0, SEEK_SET); - slurp_read(fp, song->title, 20); - song->title[20] = '\0'; - slurp_seek(fp, 12, SEEK_CUR); // skip the tag and stuff - - song->initial_speed = (slurp_getc(fp) >> 4) ?: 1; - npat = slurp_getc(fp); - song->initial_global_volume = 2 * slurp_getc(fp); - slurp_seek(fp, 13, SEEK_CUR); // junk - - if (npat > 64) - return LOAD_FORMAT_ERROR; - - for (n = 1; n <= 31; n++) { - struct stm_sample stmsmp; - uint16_t blen; - song_sample_t *sample = song->samples + n; - - slurp_read(fp, &stmsmp, sizeof(stmsmp)); - // the strncpy here is intentional -- ST2 doesn't show the '3' after the \0 bytes in the first - // sample of pm_fract.stm, for example - strncpy(sample->filename, stmsmp.name, 12); - memcpy(sample->name, sample->filename, 12); - blen = sample->length = bswapLE16(stmsmp.length); - sample->loop_start = bswapLE16(stmsmp.loop_start); - sample->loop_end = bswapLE16(stmsmp.loop_end); - sample->c5speed = bswapLE16(stmsmp.c5speed); - sample->volume = stmsmp.volume * 4; //mphack - if (sample->loop_start < blen - && sample->loop_end != 0xffff - && sample->loop_start < sample->loop_end) { - sample->flags |= CHN_LOOP; - sample->loop_end = CLAMP(sample->loop_end, sample->loop_start, blen); - } - } - - slurp_read(fp, song->orderlist, 128); - for (n = 0; n < 128; n++) { - if (song->orderlist[n] >= 64) - song->orderlist[n] = ORDER_LAST; - } - - if (lflags & LOAD_NOPATTERNS) { - slurp_seek(fp, npat * 64 * 4 * 4, SEEK_CUR); - } else { - for (n = 0; n < npat; n++) { - song->patterns[n] = csf_allocate_pattern(64); - song->pattern_size[n] = song->pattern_alloc_size[n] = 64; - load_stm_pattern(song->patterns[n], fp); - } - } - - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 1; n <= 31; n++) { - song_sample_t *sample = song->samples + n; - int align = (sample->length + 15) & ~15; - - if (sample->length < 3) { - // Garbage? - sample->length = 0; - } else { - csf_read_sample(sample, SF_LE | SF_PCMS | SF_8 | SF_M, - (const char *) (fp->data + fp->pos), sample->length); - } - slurp_seek(fp, align, SEEK_CUR); - } - } - - for (n = 0; n < 4; n++) - song->channels[n].panning = ((n & 1) ? 64 : 0) * 4; //mphack - for (; n < 64; n++) - song->channels[n].flags |= CHN_MUTE; - song->pan_separation = 64; - song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; + char id[8]; + uint8_t tmp[4]; + int npat, n; + + slurp_seek(fp, 20, SEEK_SET); + slurp_read(fp, id, 8); + slurp_read(fp, tmp, 4); + + if (!( + // this byte is guaranteed to be 0x1a, always... + tmp[0] == 0x1a + // from the doc: + // 1 - song (contains no samples) + // 2 - module (contains samples) + // I'm not going to care about "songs". + && tmp[1] == 2 + // and check the file tag -- but god knows why, it's case insensitive + && (strncasecmp(id, "!Scream!", 8) == 0 || strncasecmp(id, "BMOD2STM", 8) == 0) + )) { + return LOAD_UNSUPPORTED; + } + // and the next two bytes are the tracker version. + // (XXX should this care about BMOD2STM? what is that anyway?) + sprintf(song->tracker_id, "Scream Tracker %d.%02x", tmp[2], tmp[3]); + + slurp_seek(fp, 0, SEEK_SET); + slurp_read(fp, song->title, 20); + song->title[20] = '\0'; + slurp_seek(fp, 12, SEEK_CUR); // skip the tag and stuff + + song->initial_speed = (slurp_getc(fp) >> 4) ?: 1; + npat = slurp_getc(fp); + song->initial_global_volume = 2 * slurp_getc(fp); + slurp_seek(fp, 13, SEEK_CUR); // junk + + if (npat > 64) + return LOAD_FORMAT_ERROR; + + for (n = 1; n <= 31; n++) { + struct stm_sample stmsmp; + uint16_t blen; + song_sample_t *sample = song->samples + n; + + slurp_read(fp, &stmsmp, sizeof(stmsmp)); + // the strncpy here is intentional -- ST2 doesn't show the '3' after the \0 bytes in the first + // sample of pm_fract.stm, for example + strncpy(sample->filename, stmsmp.name, 12); + memcpy(sample->name, sample->filename, 12); + blen = sample->length = bswapLE16(stmsmp.length); + sample->loop_start = bswapLE16(stmsmp.loop_start); + sample->loop_end = bswapLE16(stmsmp.loop_end); + sample->c5speed = bswapLE16(stmsmp.c5speed); + sample->volume = stmsmp.volume * 4; //mphack + if (sample->loop_start < blen + && sample->loop_end != 0xffff + && sample->loop_start < sample->loop_end) { + sample->flags |= CHN_LOOP; + sample->loop_end = CLAMP(sample->loop_end, sample->loop_start, blen); + } + } + + slurp_read(fp, song->orderlist, 128); + for (n = 0; n < 128; n++) { + if (song->orderlist[n] >= 64) + song->orderlist[n] = ORDER_LAST; + } + + if (lflags & LOAD_NOPATTERNS) { + slurp_seek(fp, npat * 64 * 4 * 4, SEEK_CUR); + } else { + for (n = 0; n < npat; n++) { + song->patterns[n] = csf_allocate_pattern(64); + song->pattern_size[n] = song->pattern_alloc_size[n] = 64; + load_stm_pattern(song->patterns[n], fp); + } + } + + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 1; n <= 31; n++) { + song_sample_t *sample = song->samples + n; + int align = (sample->length + 15) & ~15; + + if (sample->length < 3) { + // Garbage? + sample->length = 0; + } else { + csf_read_sample(sample, SF_LE | SF_PCMS | SF_8 | SF_M, + (const char *) (fp->data + fp->pos), sample->length); + } + slurp_seek(fp, align, SEEK_CUR); + } + } + + for (n = 0; n < 4; n++) + song->channels[n].panning = ((n & 1) ? 64 : 0) * 4; //mphack + for (; n < 64; n++) + song->channels[n].flags |= CHN_MUTE; + song->pan_separation = 64; + song->flags = SONG_ITOLDEFFECTS | SONG_COMPATGXX; - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/ult.c schism-20160521/fmt/ult.c --- schism-0+20110101/fmt/ult.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/ult.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,38 +35,38 @@ int fmt_ult_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 48 && memcmp(data, "MAS_UTrack_V00", 14) == 0)) - return 0; + if (!(length > 48 && memcmp(data, "MAS_UTrack_V00", 14) == 0)) + return 0; - file->description = "UltraTracker Module"; - file->type = TYPE_MODULE_S3M; - /*file->extension = str_dup("ult");*/ - file->title = calloc(33, sizeof(char)); - memcpy(file->title, data + 15, 32); - file->title[32] = 0; - return 1; + file->description = "UltraTracker Module"; + file->type = TYPE_MODULE_S3M; + /*file->extension = str_dup("ult");*/ + file->title = calloc(33, sizeof(char)); + memcpy(file->title, data + 15, 32); + file->title[32] = 0; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ enum { - ULT_16BIT = 4, - ULT_LOOP = 8, - ULT_PINGPONGLOOP = 16, + ULT_16BIT = 4, + ULT_LOOP = 8, + ULT_PINGPONGLOOP = 16, }; #pragma pack(push, 1) struct ult_sample { - char name[32]; - char filename[12]; - uint32_t loop_start; - uint32_t loop_end; - uint32_t size_start; - uint32_t size_end; - uint8_t volume; // 0-255, apparently prior to 1.4 this was logarithmic? - uint8_t flags; // above - uint16_t speed; // only exists for 1.4+ - int16_t finetune; + char name[32]; + char filename[12]; + uint32_t loop_start; + uint32_t loop_end; + uint32_t size_start; + uint32_t size_end; + uint8_t volume; // 0-255, apparently prior to 1.4 this was logarithmic? + uint8_t flags; // above + uint16_t speed; // only exists for 1.4+ + int16_t finetune; }; #pragma pack(pop) @@ -88,303 +88,303 @@ convert them. */ static const uint8_t ult_efftrans[] = { - FX_ARPEGGIO, - FX_PORTAMENTOUP, - FX_PORTAMENTODOWN, - FX_TONEPORTAMENTO, - FX_VIBRATO, - FX_NONE, - FX_NONE, - FX_TREMOLO, - FX_NONE, - FX_OFFSET, - FX_VOLUMESLIDE, - FX_PANNING, - FX_VOLUME, - FX_PATTERNBREAK, - FX_NONE, // extended effects, processed separately - FX_SPEED, + FX_ARPEGGIO, + FX_PORTAMENTOUP, + FX_PORTAMENTODOWN, + FX_TONEPORTAMENTO, + FX_VIBRATO, + FX_NONE, + FX_NONE, + FX_TREMOLO, + FX_NONE, + FX_OFFSET, + FX_VOLUMESLIDE, + FX_PANNING, + FX_VOLUME, + FX_PATTERNBREAK, + FX_NONE, // extended effects, processed separately + FX_SPEED, }; static void translate_fx(uint8_t *pe, uint8_t *pp) { - uint8_t e = *pe & 0xf; - uint8_t p = *pp; + uint8_t e = *pe & 0xf; + uint8_t p = *pp; - *pe = ult_efftrans[e]; + *pe = ult_efftrans[e]; - switch (e) { - case 0: - if (!p) - *pe = FX_NONE; - break; - case 3: - // 300 apparently stops sliding, which is totally weird - if (!p) - p = 1; // close enough? - break; - case 0xa: - // blah, this sucks - if (p & 0xf0) - p &= 0xf0; - break; - case 0xb: - // mikmod does this wrong, resulting in values 0-225 instead of 0-255 - p = (p & 0xf) * 0x11; - break; - case 0xc: // volume - p >>= 2; - break; - case 0xd: // pattern break - p = 10 * (p >> 4) + (p & 0xf); - case 0xe: // special - switch (p >> 4) { - case 1: - *pe = FX_PORTAMENTOUP; - p = 0xf0 | (p & 0xf); - break; - case 2: - *pe = FX_PORTAMENTODOWN; - p = 0xf0 | (p & 0xf); - break; - case 8: - *pe = FX_SPECIAL; - p = 0x60 | (p & 0xf); - break; - case 9: - *pe = FX_RETRIG; - p &= 0xf; - break; - case 0xa: - *pe = FX_VOLUMESLIDE; - p = ((p & 0xf) << 4) | 0xf; - break; - case 0xb: - *pe = FX_VOLUMESLIDE; - p = 0xf0 | (p & 0xf); - break; - case 0xc: case 0xd: - *pe = FX_SPECIAL; - break; - } - break; - case 0xf: - if (p > 0x2f) - *pe = FX_TEMPO; - break; - } + switch (e) { + case 0: + if (!p) + *pe = FX_NONE; + break; + case 3: + // 300 apparently stops sliding, which is totally weird + if (!p) + p = 1; // close enough? + break; + case 0xa: + // blah, this sucks + if (p & 0xf0) + p &= 0xf0; + break; + case 0xb: + // mikmod does this wrong, resulting in values 0-225 instead of 0-255 + p = (p & 0xf) * 0x11; + break; + case 0xc: // volume + p >>= 2; + break; + case 0xd: // pattern break + p = 10 * (p >> 4) + (p & 0xf); + case 0xe: // special + switch (p >> 4) { + case 1: + *pe = FX_PORTAMENTOUP; + p = 0xf0 | (p & 0xf); + break; + case 2: + *pe = FX_PORTAMENTODOWN; + p = 0xf0 | (p & 0xf); + break; + case 8: + *pe = FX_SPECIAL; + p = 0x60 | (p & 0xf); + break; + case 9: + *pe = FX_RETRIG; + p &= 0xf; + break; + case 0xa: + *pe = FX_VOLUMESLIDE; + p = ((p & 0xf) << 4) | 0xf; + break; + case 0xb: + *pe = FX_VOLUMESLIDE; + p = 0xf0 | (p & 0xf); + break; + case 0xc: case 0xd: + *pe = FX_SPECIAL; + break; + } + break; + case 0xf: + if (p > 0x2f) + *pe = FX_TEMPO; + break; + } - *pp = p; + *pp = p; } static int read_ult_event(slurp_t *fp, song_note_t *note, int *lostfx) { - uint8_t b, repeat = 1; - uint32_t off; - int n; - - b = slurp_getc(fp); - if (b == 0xfc) { - repeat = slurp_getc(fp); - b = slurp_getc(fp); - } - note->note = (b > 0 && b < 61) ? b + 36 : NOTE_NONE; - note->instrument = slurp_getc(fp); - b = slurp_getc(fp); - note->voleffect = b & 0xf; - note->effect = b >> 4; - note->volparam = slurp_getc(fp); - note->param = slurp_getc(fp); - translate_fx(¬e->voleffect, ¬e->volparam); - translate_fx(¬e->effect, ¬e->param); - - // sample offset -- this is even more special than digitrakker's - if (note->voleffect == FX_OFFSET && note->effect == FX_OFFSET) { - off = ((note->volparam << 8) | note->param) >> 6; - note->voleffect = FX_NONE; - note->param = MIN(off, 0xff); - } else if (note->voleffect == FX_OFFSET) { - off = note->volparam * 4; - note->volparam = MIN(off, 0xff); - } else if (note->effect == FX_OFFSET) { - off = note->param * 4; - note->param = MIN(off, 0xff); - } else if (note->voleffect == note->effect) { - /* don't try to figure out how ultratracker does this, it's quite random */ - note->effect = FX_NONE; - } - if (note->effect == FX_VOLUME || (note->effect == FX_NONE && note->voleffect != FX_VOLUME)) { - swap_effects(note); - } - - // Do that dance. - // Maybe I should quit rewriting this everywhere and make a generic version :P - for (n = 0; n < 4; n++) { - if (convert_voleffect_of(note, n >> 1)) { - n = 5; - break; - } - swap_effects(note); - } - if (n < 5) { - if (effect_weight[note->voleffect] > effect_weight[note->effect]) - swap_effects(note); - (*lostfx)++; - //log_appendf(4, "Effect dropped: %c%02X < %c%02X", get_effect_char(note->voleffect), - // note->volparam, get_effect_char(note->effect), note->param); - note->voleffect = 0; - } - if (!note->voleffect) - note->volparam = 0; - if (!note->effect) - note->param = 0; - return repeat; + uint8_t b, repeat = 1; + uint32_t off; + int n; + + b = slurp_getc(fp); + if (b == 0xfc) { + repeat = slurp_getc(fp); + b = slurp_getc(fp); + } + note->note = (b > 0 && b < 61) ? b + 36 : NOTE_NONE; + note->instrument = slurp_getc(fp); + b = slurp_getc(fp); + note->voleffect = b & 0xf; + note->effect = b >> 4; + note->volparam = slurp_getc(fp); + note->param = slurp_getc(fp); + translate_fx(¬e->voleffect, ¬e->volparam); + translate_fx(¬e->effect, ¬e->param); + + // sample offset -- this is even more special than digitrakker's + if (note->voleffect == FX_OFFSET && note->effect == FX_OFFSET) { + off = ((note->volparam << 8) | note->param) >> 6; + note->voleffect = FX_NONE; + note->param = MIN(off, 0xff); + } else if (note->voleffect == FX_OFFSET) { + off = note->volparam * 4; + note->volparam = MIN(off, 0xff); + } else if (note->effect == FX_OFFSET) { + off = note->param * 4; + note->param = MIN(off, 0xff); + } else if (note->voleffect == note->effect) { + /* don't try to figure out how ultratracker does this, it's quite random */ + note->effect = FX_NONE; + } + if (note->effect == FX_VOLUME || (note->effect == FX_NONE && note->voleffect != FX_VOLUME)) { + swap_effects(note); + } + + // Do that dance. + // Maybe I should quit rewriting this everywhere and make a generic version :P + for (n = 0; n < 4; n++) { + if (convert_voleffect_of(note, n >> 1)) { + n = 5; + break; + } + swap_effects(note); + } + if (n < 5) { + if (effect_weight[note->voleffect] > effect_weight[note->effect]) + swap_effects(note); + (*lostfx)++; + //log_appendf(4, "Effect dropped: %c%02X < %c%02X", get_effect_char(note->voleffect), + // note->volparam, get_effect_char(note->effect), note->param); + note->voleffect = 0; + } + if (!note->voleffect) + note->volparam = 0; + if (!note->effect) + note->param = 0; + return repeat; } /* --------------------------------------------------------------------------------------------------------- */ int fmt_ult_load_song(song_t *song, slurp_t *fp, unsigned int lflags) { - char buf[34]; - uint8_t ver; - int nmsg, nsmp, nchn, npat; - int n, chn, pat, row; - int lostfx = 0, gxx = 0; - struct ult_sample usmp; - song_sample_t *smp; - const char *verstr[] = {"<1.4", "1.4", "1.5", "1.6"}; - - slurp_read(fp, buf, 14); - if (memcmp(buf, "MAS_UTrack_V00", 14) != 0) - return LOAD_UNSUPPORTED; - ver = slurp_getc(fp); - if (ver < '1' || ver > '4') - return LOAD_FORMAT_ERROR; - ver -= '0'; - - slurp_read(fp, buf, 32); - buf[25] = '\0'; - strcpy(song->title, buf); - - sprintf(song->tracker_id, "Ultra Tracker %s", verstr[ver - 1]); - song->flags |= SONG_COMPATGXX | SONG_ITOLDEFFECTS; - - nmsg = slurp_getc(fp); - read_lined_message(song->message, fp, nmsg * 32, 32); - - nsmp = slurp_getc(fp); - for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { - // annoying: v4 added a field before the end of the struct - if (ver >= 4) { - slurp_read(fp, &usmp, sizeof(usmp)); - usmp.speed = bswapLE16(usmp.speed); - } else { - slurp_read(fp, &usmp, 64); - usmp.finetune = usmp.speed; - usmp.speed = 8363; - } - usmp.finetune = bswapLE16(usmp.finetune); - usmp.loop_start = bswapLE32(usmp.loop_start); - usmp.loop_end = bswapLE32(usmp.loop_end); - usmp.size_start = bswapLE32(usmp.size_start); - usmp.size_end = bswapLE32(usmp.size_end); - - strncpy(smp->name, usmp.name, 25); - smp->name[25] = '\0'; - strncpy(smp->filename, usmp.filename, 12); - smp->filename[12] = '\0'; - if (usmp.size_end <= usmp.size_start) - continue; - smp->length = usmp.size_end - usmp.size_start; - smp->loop_start = usmp.loop_start; - smp->loop_end = MIN(usmp.loop_end, smp->length); - smp->volume = usmp.volume; //mphack - should be 0-64 not 0-256 - smp->global_volume = 64; - - /* mikmod does some weird integer math here, but it didn't really work for me */ - smp->c5speed = usmp.speed; - if (usmp.finetune) - smp->c5speed *= pow(2, (usmp.finetune / (12.0 * 32768))); - - if (usmp.flags & ULT_LOOP) - smp->flags |= CHN_LOOP; - if (usmp.flags & ULT_PINGPONGLOOP) - smp->flags |= CHN_PINGPONGLOOP; - if (usmp.flags & ULT_16BIT) { - smp->flags |= CHN_16BIT; - smp->loop_start >>= 1; - smp->loop_end >>= 1; - } - } - - // ult just so happens to use 255 for its end mark, so there's no need to fiddle with this - slurp_read(fp, song->orderlist, 256); - - nchn = slurp_getc(fp) + 1; - npat = slurp_getc(fp) + 1; - - if (nchn > 32 || npat > MAX_PATTERNS) - return LOAD_FORMAT_ERROR; - - if (ver >= 3) { - for (n = 0; n < nchn; n++) - song->channels[n].panning = ((slurp_getc(fp) & 0xf) << 2) + 2; - } else { - for (n = 0; n < nchn; n++) - song->channels[n].panning = (n & 1) ? 48 : 16; - } - for (; n < 64; n++) { - song->channels[n].panning = 32; - song->channels[n].flags = CHN_MUTE; - } - //mphack - fix the pannings - for (n = 0; n < 64; n++) - song->channels[n].panning *= 4; - - if ((lflags & (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) == (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) - return LOAD_SUCCESS; - - for (pat = 0; pat < npat; pat++) { - song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; - song->patterns[pat] = csf_allocate_pattern(64); - } - for (chn = 0; chn < nchn; chn++) { - song_note_t evnote; - song_note_t *note; - int repeat; - - for (pat = 0; pat < npat; pat++) { - note = song->patterns[pat] + chn; - row = 0; - while (row < 64) { - repeat = read_ult_event(fp, &evnote, &lostfx); - if (evnote.effect == FX_TONEPORTAMENTO - || evnote.voleffect == VOLFX_TONEPORTAMENTO) { - gxx |= 1; - } - if (repeat + row > 64) - repeat = 64 - row; - while (repeat--) { - *note = evnote; - note += 64; - row++; - } - } - } - } - if (gxx) - log_appendf(4, " Warning: Gxx effects may not be suitably imported"); - if (lostfx) - log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); - - if (!(lflags & LOAD_NOSAMPLES)) { - for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { - uint32_t ssize = csf_read_sample(smp, - SF_LE | SF_M | SF_PCMS | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8), - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, ssize, SEEK_CUR); - } - } - return LOAD_SUCCESS; + char buf[34]; + uint8_t ver; + int nmsg, nsmp, nchn, npat; + int n, chn, pat, row; + int lostfx = 0, gxx = 0; + struct ult_sample usmp; + song_sample_t *smp; + const char *verstr[] = {"<1.4", "1.4", "1.5", "1.6"}; + + slurp_read(fp, buf, 14); + if (memcmp(buf, "MAS_UTrack_V00", 14) != 0) + return LOAD_UNSUPPORTED; + ver = slurp_getc(fp); + if (ver < '1' || ver > '4') + return LOAD_FORMAT_ERROR; + ver -= '0'; + + slurp_read(fp, buf, 32); + buf[25] = '\0'; + strcpy(song->title, buf); + + sprintf(song->tracker_id, "Ultra Tracker %s", verstr[ver - 1]); + song->flags |= SONG_COMPATGXX | SONG_ITOLDEFFECTS; + + nmsg = slurp_getc(fp); + read_lined_message(song->message, fp, nmsg * 32, 32); + + nsmp = slurp_getc(fp); + for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { + // annoying: v4 added a field before the end of the struct + if (ver >= 4) { + slurp_read(fp, &usmp, sizeof(usmp)); + usmp.speed = bswapLE16(usmp.speed); + } else { + slurp_read(fp, &usmp, 64); + usmp.finetune = usmp.speed; + usmp.speed = 8363; + } + usmp.finetune = bswapLE16(usmp.finetune); + usmp.loop_start = bswapLE32(usmp.loop_start); + usmp.loop_end = bswapLE32(usmp.loop_end); + usmp.size_start = bswapLE32(usmp.size_start); + usmp.size_end = bswapLE32(usmp.size_end); + + strncpy(smp->name, usmp.name, 25); + smp->name[25] = '\0'; + strncpy(smp->filename, usmp.filename, 12); + smp->filename[12] = '\0'; + if (usmp.size_end <= usmp.size_start) + continue; + smp->length = usmp.size_end - usmp.size_start; + smp->loop_start = usmp.loop_start; + smp->loop_end = MIN(usmp.loop_end, smp->length); + smp->volume = usmp.volume; //mphack - should be 0-64 not 0-256 + smp->global_volume = 64; + + /* mikmod does some weird integer math here, but it didn't really work for me */ + smp->c5speed = usmp.speed; + if (usmp.finetune) + smp->c5speed *= pow(2, (usmp.finetune / (12.0 * 32768))); + + if (usmp.flags & ULT_LOOP) + smp->flags |= CHN_LOOP; + if (usmp.flags & ULT_PINGPONGLOOP) + smp->flags |= CHN_PINGPONGLOOP; + if (usmp.flags & ULT_16BIT) { + smp->flags |= CHN_16BIT; + smp->loop_start >>= 1; + smp->loop_end >>= 1; + } + } + + // ult just so happens to use 255 for its end mark, so there's no need to fiddle with this + slurp_read(fp, song->orderlist, 256); + + nchn = slurp_getc(fp) + 1; + npat = slurp_getc(fp) + 1; + + if (nchn > 32 || npat > MAX_PATTERNS) + return LOAD_FORMAT_ERROR; + + if (ver >= 3) { + for (n = 0; n < nchn; n++) + song->channels[n].panning = ((slurp_getc(fp) & 0xf) << 2) + 2; + } else { + for (n = 0; n < nchn; n++) + song->channels[n].panning = (n & 1) ? 48 : 16; + } + for (; n < 64; n++) { + song->channels[n].panning = 32; + song->channels[n].flags = CHN_MUTE; + } + //mphack - fix the pannings + for (n = 0; n < 64; n++) + song->channels[n].panning *= 4; + + if ((lflags & (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) == (LOAD_NOSAMPLES | LOAD_NOPATTERNS)) + return LOAD_SUCCESS; + + for (pat = 0; pat < npat; pat++) { + song->pattern_size[pat] = song->pattern_alloc_size[pat] = 64; + song->patterns[pat] = csf_allocate_pattern(64); + } + for (chn = 0; chn < nchn; chn++) { + song_note_t evnote; + song_note_t *note; + int repeat; + + for (pat = 0; pat < npat; pat++) { + note = song->patterns[pat] + chn; + row = 0; + while (row < 64) { + repeat = read_ult_event(fp, &evnote, &lostfx); + if (evnote.effect == FX_TONEPORTAMENTO + || evnote.voleffect == VOLFX_TONEPORTAMENTO) { + gxx |= 1; + } + if (repeat + row > 64) + repeat = 64 - row; + while (repeat--) { + *note = evnote; + note += 64; + row++; + } + } + } + } + if (gxx) + log_appendf(4, " Warning: Gxx effects may not be suitably imported"); + if (lostfx) + log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); + + if (!(lflags & LOAD_NOSAMPLES)) { + for (n = 0, smp = song->samples + 1; n < nsmp; n++, smp++) { + uint32_t ssize = csf_read_sample(smp, + SF_LE | SF_M | SF_PCMS | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8), + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, ssize, SEEK_CUR); + } + } + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/fmt/wav.c schism-20160521/fmt/wav.c --- schism-0+20110101/fmt/wav.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/wav.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -100,296 +100,296 @@ static int wav_load(wave_file_t *f, const uint8_t *data, size_t len) { - wave_file_header_t phdr; - size_t offset; - int have_format = 0; - - if (len < sizeof(wave_file_header_t)) { - return 0; - } + wave_file_header_t phdr; + size_t offset; + int have_format = 0; + + if (len < sizeof(wave_file_header_t)) { + return 0; + } - memcpy(&phdr, data, sizeof(wave_file_header_t)); + memcpy(&phdr, data, sizeof(wave_file_header_t)); #if WORDS_BIGENDIAN - phdr.id_RIFF = bswapLE32(phdr.id_RIFF); - phdr.filesize = bswapLE32(phdr.filesize); - phdr.id_WAVE = bswapLE32(phdr.id_WAVE); + phdr.id_RIFF = bswapLE32(phdr.id_RIFF); + phdr.filesize = bswapLE32(phdr.filesize); + phdr.id_WAVE = bswapLE32(phdr.id_WAVE); #endif - if (phdr.id_RIFF != IFFID_RIFF || - phdr.id_WAVE != IFFID_WAVE) { - return 0; - } - - offset = sizeof(wave_file_header_t); - - while (1) { - wave_chunk_prefix_t c; - memcpy(&c, data + offset, sizeof(wave_chunk_prefix_t)); + if (phdr.id_RIFF != IFFID_RIFF || + phdr.id_WAVE != IFFID_WAVE) { + return 0; + } + + offset = sizeof(wave_file_header_t); + + while (1) { + wave_chunk_prefix_t c; + memcpy(&c, data + offset, sizeof(wave_chunk_prefix_t)); #if WORDS_BIGENDIAN - c.id = bswapLE32(c.id); - c.length = bswapLE32(c.length); + c.id = bswapLE32(c.id); + c.length = bswapLE32(c.length); #endif - offset += sizeof(wave_chunk_prefix_t); + offset += sizeof(wave_chunk_prefix_t); - if (offset + c.length > len) { - log_appendf(4, "Corrupt WAV file. Chunk points outside of WAV file [%lu + %u > %lu]\n", - (unsigned long) offset, c.length, (unsigned long) len); - return 0; - } - - switch (c.id) { - case IFFID_fmt: { - if (have_format) { - log_appendf(4, "Corrupt WAV file. Found multiple format headers.\n"); - return 0; - } + if (offset + c.length > len) { + log_appendf(4, "Corrupt WAV file. Chunk points outside of WAV file [%lu + %u > %lu]\n", + (unsigned long) offset, c.length, (unsigned long) len); + return 0; + } + + switch (c.id) { + case IFFID_fmt: { + if (have_format) { + log_appendf(4, "Corrupt WAV file. Found multiple format headers.\n"); + return 0; + } - have_format = 1; - memcpy(&f->fmt, data + offset, sizeof(wave_format_t)); + have_format = 1; + memcpy(&f->fmt, data + offset, sizeof(wave_format_t)); #if WORDS_BIGENDIAN - f->fmt.format = bswapLE16(f->fmt.format); - f->fmt.channels = bswapLE16(f->fmt.channels); - f->fmt.freqHz = bswapLE32(f->fmt.freqHz); - f->fmt.bytessec = bswapLE32(f->fmt.bytessec); - f->fmt.samplesize = bswapLE16(f->fmt.samplesize); - f->fmt.bitspersample = bswapLE16(f->fmt.bitspersample); + f->fmt.format = bswapLE16(f->fmt.format); + f->fmt.channels = bswapLE16(f->fmt.channels); + f->fmt.freqHz = bswapLE32(f->fmt.freqHz); + f->fmt.bytessec = bswapLE32(f->fmt.bytessec); + f->fmt.samplesize = bswapLE16(f->fmt.samplesize); + f->fmt.bitspersample = bswapLE16(f->fmt.bitspersample); #endif - break; - } + break; + } - case IFFID_data: - if (!have_format) { - log_appendf(4, "WAV file did not specify format before data\n"); - return 0; - } - - memcpy(&f->data, &c, sizeof(wave_chunk_prefix_t)); - f->buf = (uint8_t *)(data + offset); - return 1; - } - - offset += c.length; - - if (offset == len) - break; - } + case IFFID_data: + if (!have_format) { + log_appendf(4, "WAV file did not specify format before data\n"); + return 0; + } + + memcpy(&f->data, &c, sizeof(wave_chunk_prefix_t)); + f->buf = (uint8_t *)(data + offset); + return 1; + } + + offset += c.length; + + if (offset == len) + break; + } - return 1; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ int fmt_wav_load_sample(const uint8_t *data, size_t len, song_sample_t *smp) { - wave_file_t f; - uint32_t flags; + wave_file_t f; + uint32_t flags; - if (!wav_load(&f, data, len)) - return 0; + if (!wav_load(&f, data, len)) + return 0; - if (f.fmt.format != WAVE_FORMAT_PCM || - !f.fmt.freqHz || - (f.fmt.channels != 1 && f.fmt.channels != 2)) - return 0; - - smp->flags = 0; // flags are set by csf_read_sample - flags = 0; - - // endianness - flags = SF_LE; - // channels - flags |= (f.fmt.channels == 2) ? SF_SI : SF_M; // interleaved stereo - // bit width - switch (f.fmt.bitspersample) { - case 8: flags |= SF_8; break; - case 16: flags |= SF_16; break; - case 24: flags |= SF_24; break; - case 32: flags |= SF_32; break; - default: return 0; // unsupported - } - // encoding (8-bit wav is unsigned, everything else is signed -- yeah, it's stupid) - flags |= (f.fmt.bitspersample == 8) ? SF_PCMU : SF_PCMS; - - smp->volume = 64 * 4; - smp->global_volume = 64; - smp->c5speed = f.fmt.freqHz; - smp->length = f.data.length / ((f.fmt.bitspersample / 8) * f.fmt.channels); + if (f.fmt.format != WAVE_FORMAT_PCM || + !f.fmt.freqHz || + (f.fmt.channels != 1 && f.fmt.channels != 2)) + return 0; + + smp->flags = 0; // flags are set by csf_read_sample + flags = 0; + + // endianness + flags = SF_LE; + // channels + flags |= (f.fmt.channels == 2) ? SF_SI : SF_M; // interleaved stereo + // bit width + switch (f.fmt.bitspersample) { + case 8: flags |= SF_8; break; + case 16: flags |= SF_16; break; + case 24: flags |= SF_24; break; + case 32: flags |= SF_32; break; + default: return 0; // unsupported + } + // encoding (8-bit wav is unsigned, everything else is signed -- yeah, it's stupid) + flags |= (f.fmt.bitspersample == 8) ? SF_PCMU : SF_PCMS; + + smp->volume = 64 * 4; + smp->global_volume = 64; + smp->c5speed = f.fmt.freqHz; + smp->length = f.data.length / ((f.fmt.bitspersample / 8) * f.fmt.channels); - return csf_read_sample((song_sample_t *)smp, flags, (const char *) f.buf, f.data.length); + return csf_read_sample((song_sample_t *)smp, flags, (const char *) f.buf, f.data.length); } int fmt_wav_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - wave_file_t f; + wave_file_t f; - if (!wav_load(&f, data, length)) - return 0; - else if (f.fmt.format != WAVE_FORMAT_PCM || - !f.fmt.freqHz || - (f.fmt.channels != 1 && f.fmt.channels != 2) || - (f.fmt.bitspersample != 8 && f.fmt.bitspersample != 16 && - f.fmt.bitspersample != 24 && f.fmt.bitspersample != 32)) - return 0; - - file->smp_flags = 0; - - if (f.fmt.channels == 2) - file->smp_flags |= CHN_STEREO; - - if (f.fmt.bitspersample == 16) - file->smp_flags |= CHN_16BIT; - - file->smp_speed = f.fmt.freqHz; - file->smp_length = f.data.length / ((f.fmt.bitspersample / 8) * f.fmt.channels); - - file->description = "IBM/Microsoft RIFF Audio"; - file->type = TYPE_SAMPLE_PLAIN; - file->smp_filename = file->base; - return 1; + if (!wav_load(&f, data, length)) + return 0; + else if (f.fmt.format != WAVE_FORMAT_PCM || + !f.fmt.freqHz || + (f.fmt.channels != 1 && f.fmt.channels != 2) || + (f.fmt.bitspersample != 8 && f.fmt.bitspersample != 16 && + f.fmt.bitspersample != 24 && f.fmt.bitspersample != 32)) + return 0; + + file->smp_flags = 0; + + if (f.fmt.channels == 2) + file->smp_flags |= CHN_STEREO; + + if (f.fmt.bitspersample == 16) + file->smp_flags |= CHN_16BIT; + + file->smp_speed = f.fmt.freqHz; + file->smp_length = f.data.length / ((f.fmt.bitspersample / 8) * f.fmt.channels); + + file->description = "IBM/Microsoft RIFF Audio"; + file->type = TYPE_SAMPLE_PLAIN; + file->smp_filename = file->base; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ /* wav is like aiff's retarded cousin */ struct wav_writedata { - long data_size; // seek position for writing data size (in bytes) - size_t numbytes; // how many bytes have been written - int bps; // bytes per sample - int swap; // should be byteswapped? + long data_size; // seek position for writing data size (in bytes) + size_t numbytes; // how many bytes have been written + int bps; // bytes per sample + int swap; // should be byteswapped? }; static int wav_header(disko_t *fp, int bits, int channels, int rate, size_t length, - struct wav_writedata *wwd /* out */) + struct wav_writedata *wwd /* out */) { - int16_t s; - uint32_t ul; - int bps = 1; - - bps *= ((bits + 7) / 8) * channels; - - /* write a very large size for now */ - disko_write(fp, "RIFF\377\377\377\377WAVEfmt ", 16); - ul = bswapLE32(16); // fmt chunk size - disko_write(fp, &ul, 4); - s = bswapLE16(1); // linear pcm - disko_write(fp, &s, 2); - s = bswapLE16(channels); // number of channels - disko_write(fp, &s, 2); - ul = bswapLE32(rate); // sample rate - disko_write(fp, &ul, 4); - ul = bswapLE32(bps * rate); // "byte rate" (why?! I have no idea) - disko_write(fp, &ul, 4); - s = bswapLE16(bps); // (oh, come on! the format already stores everything needed to calculate this!) - disko_write(fp, &s, 2); - s = bswapLE16(bits); // bits per sample - disko_write(fp, &s, 2); - - disko_write(fp, "data", 4); - if (wwd) - wwd->data_size = disko_tell(fp); - ul = bswapLE32(bps * length); - disko_write(fp, &ul, 4); + int16_t s; + uint32_t ul; + int bps = 1; + + bps *= ((bits + 7) / 8) * channels; + + /* write a very large size for now */ + disko_write(fp, "RIFF\377\377\377\377WAVEfmt ", 16); + ul = bswapLE32(16); // fmt chunk size + disko_write(fp, &ul, 4); + s = bswapLE16(1); // linear pcm + disko_write(fp, &s, 2); + s = bswapLE16(channels); // number of channels + disko_write(fp, &s, 2); + ul = bswapLE32(rate); // sample rate + disko_write(fp, &ul, 4); + ul = bswapLE32(bps * rate); // "byte rate" (why?! I have no idea) + disko_write(fp, &ul, 4); + s = bswapLE16(bps); // (oh, come on! the format already stores everything needed to calculate this!) + disko_write(fp, &s, 2); + s = bswapLE16(bits); // bits per sample + disko_write(fp, &s, 2); + + disko_write(fp, "data", 4); + if (wwd) + wwd->data_size = disko_tell(fp); + ul = bswapLE32(bps * length); + disko_write(fp, &ul, 4); - return bps; + return bps; } int fmt_wav_save_sample(disko_t *fp, song_sample_t *smp) { - int bps; - uint32_t ul; - uint32_t flags = SF_LE; - flags |= (smp->flags & CHN_16BIT) ? (SF_16 | SF_PCMS) : (SF_8 | SF_PCMU); - flags |= (smp->flags & CHN_STEREO) ? SF_SI : SF_M; - - bps = wav_header(fp, (smp->flags & CHN_16BIT) ? 16 : 8, (smp->flags & CHN_STEREO) ? 2 : 1, - smp->c5speed, smp->length, NULL); - - if (csf_write_sample(fp, smp, flags) != smp->length * bps) { - log_appendf(4, "WAV: unexpected data size written"); - return SAVE_INTERNAL_ERROR; - } - - /* fix the length in the file header */ - ul = disko_tell(fp) - 8; - ul = bswapLE32(ul); - disko_seek(fp, 4, SEEK_SET); - disko_write(fp, &ul, 4); + int bps; + uint32_t ul; + uint32_t flags = SF_LE; + flags |= (smp->flags & CHN_16BIT) ? (SF_16 | SF_PCMS) : (SF_8 | SF_PCMU); + flags |= (smp->flags & CHN_STEREO) ? SF_SI : SF_M; + + bps = wav_header(fp, (smp->flags & CHN_16BIT) ? 16 : 8, (smp->flags & CHN_STEREO) ? 2 : 1, + smp->c5speed, smp->length, NULL); + + if (csf_write_sample(fp, smp, flags) != smp->length * bps) { + log_appendf(4, "WAV: unexpected data size written"); + return SAVE_INTERNAL_ERROR; + } + + /* fix the length in the file header */ + ul = disko_tell(fp) - 8; + ul = bswapLE32(ul); + disko_seek(fp, 4, SEEK_SET); + disko_write(fp, &ul, 4); - return SAVE_SUCCESS; + return SAVE_SUCCESS; } int fmt_wav_export_head(disko_t *fp, int bits, int channels, int rate) { - struct wav_writedata *wwd = malloc(sizeof(struct wav_writedata)); - if (!wwd) - return DW_ERROR; - fp->userdata = wwd; - wwd->bps = wav_header(fp, bits, channels, rate, ~0, wwd); - wwd->numbytes = 0; + struct wav_writedata *wwd = malloc(sizeof(struct wav_writedata)); + if (!wwd) + return DW_ERROR; + fp->userdata = wwd; + wwd->bps = wav_header(fp, bits, channels, rate, ~0, wwd); + wwd->numbytes = 0; #if WORDS_BIGENDIAN - wwd->swap = (bits > 8); + wwd->swap = (bits > 8); #else - wwd->swap = 0; + wwd->swap = 0; #endif - return DW_OK; + return DW_OK; } int fmt_wav_export_body(disko_t *fp, const uint8_t *data, size_t length) { - struct wav_writedata *wwd = fp->userdata; + struct wav_writedata *wwd = fp->userdata; - if (length % wwd->bps) { - log_appendf(4, "WAV export: received uneven length"); - return DW_ERROR; - } - - wwd->numbytes += length; - - if (wwd->swap) { - const int16_t *ptr = (const int16_t *) data; - uint16_t v; - - length /= 2; - while (length--) { - v = *ptr; - v = bswapLE16(v); - disko_write(fp, &v, 2); - ptr++; - } - } else { - disko_write(fp, data, length); - } + if (length % wwd->bps) { + log_appendf(4, "WAV export: received uneven length"); + return DW_ERROR; + } + + wwd->numbytes += length; + + if (wwd->swap) { + const int16_t *ptr = (const int16_t *) data; + uint16_t v; + + length /= 2; + while (length--) { + v = *ptr; + v = bswapLE16(v); + disko_write(fp, &v, 2); + ptr++; + } + } else { + disko_write(fp, data, length); + } - return DW_OK; + return DW_OK; } int fmt_wav_export_silence(disko_t *fp, long bytes) { - disko_seek(fp, bytes, SEEK_CUR); - return DW_OK; + disko_seek(fp, bytes, SEEK_CUR); + return DW_OK; } int fmt_wav_export_tail(disko_t *fp) { - struct wav_writedata *wwd = fp->userdata; - uint32_t ul; + struct wav_writedata *wwd = fp->userdata; + uint32_t ul; - /* fix the length in the file header */ - ul = disko_tell(fp) - 8; - ul= bswapLE32(ul); - disko_seek(fp, 4, SEEK_SET); - disko_write(fp, &ul, 4); - - /* write the other lengths */ - disko_seek(fp, wwd->data_size, SEEK_SET); - ul = bswapLE32(wwd->numbytes); - disko_write(fp, &ul, 4); + /* fix the length in the file header */ + ul = disko_tell(fp) - 8; + ul= bswapLE32(ul); + disko_seek(fp, 4, SEEK_SET); + disko_write(fp, &ul, 4); + + /* write the other lengths */ + disko_seek(fp, wwd->data_size, SEEK_SET); + ul = bswapLE32(wwd->numbytes); + disko_write(fp, &ul, 4); - free(wwd); + free(wwd); - return DW_OK; + return DW_OK; } diff -Nru schism-0+20110101/fmt/xi.c schism-20160521/fmt/xi.c --- schism-0+20110101/fmt/xi.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/xi.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -38,235 +38,235 @@ #pragma pack(push, 1) struct xm_point { - uint16_t ticks; // Time in tracker ticks - uint16_t val; // Value from 0x00 to 0x40. + uint16_t ticks; // Time in tracker ticks + uint16_t val; // Value from 0x00 to 0x40. }; struct xm_sample_header { - uint32_t samplen; - uint32_t loopstart; - uint32_t looplen; - uint8_t vol; - signed char finetune; - uint8_t type; - uint8_t pan; - signed char relnote; - uint8_t res; - char name[22]; + uint32_t samplen; + uint32_t loopstart; + uint32_t looplen; + uint8_t vol; + signed char finetune; + uint8_t type; + uint8_t pan; + signed char relnote; + uint8_t res; + char name[22]; }; struct xi_sample_header { - uint8_t snum[96]; + uint8_t snum[96]; - union { - uint16_t env[48]; // Occupies same mem as venv,penv - struct { - struct xm_point venv[12], penv[12]; - }; - }; - - uint8_t vnum, pnum; - uint8_t vsustain, vloops, vloope, psustain, ploops, ploope; - uint8_t vtype, ptype; - uint8_t vibtype, vibsweep, vibdepth, vibrate; - uint16_t volfade; - uint8_t reserved1[0x16]; - uint16_t nsamples; + union { + uint16_t env[48]; // Occupies same mem as venv,penv + struct { + struct xm_point venv[12], penv[12]; + }; + }; + + uint8_t vnum, pnum; + uint8_t vsustain, vloops, vloope, psustain, ploops, ploope; + uint8_t vtype, ptype; + uint8_t vibtype, vibsweep, vibdepth, vibrate; + uint16_t volfade; + uint8_t reserved1[0x16]; + uint16_t nsamples; }; struct xi_file_header { - int8_t header[0x15]; // "Extended Instrument: " - int8_t name[0x16]; // Name of instrument - uint8_t magic; // 0x1a, DOS EOF char so you can 'type file.xi' - int8_t tracker[0x14]; // Name of tracker - uint16_t version; // big-endian 0x0102 - struct xi_sample_header xish; - struct xm_sample_header sheader[]; + int8_t header[0x15]; // "Extended Instrument: " + int8_t name[0x16]; // Name of instrument + uint8_t magic; // 0x1a, DOS EOF char so you can 'type file.xi' + int8_t tracker[0x14]; // Name of tracker + uint16_t version; // big-endian 0x0102 + struct xi_sample_header xish; + struct xm_sample_header sheader[]; }; #pragma pack(pop) static int validate_xi(const struct xi_file_header *xi, size_t length) { - if (length <= sizeof(struct xi_file_header)) - return 0; - if (memcmp(xi->header, "Extended Instrument: ", 21) != 0) - return 0; - if (xi->magic != 0x1a) - return 0; - if (bswapLE16(xi->version) != 0x0102) - return(0); - return(1); + if (length <= sizeof(struct xi_file_header)) + return 0; + if (memcmp(xi->header, "Extended Instrument: ", 21) != 0) + return 0; + if (xi->magic != 0x1a) + return 0; + if (bswapLE16(xi->version) != 0x0102) + return(0); + return(1); } /* --------------------------------------------------------------------- */ int fmt_xi_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - struct xi_file_header *xi = (struct xi_file_header *) data; + struct xi_file_header *xi = (struct xi_file_header *) data; - if (!validate_xi(xi, length)) - return 0; + if (!validate_xi(xi, length)) + return 0; - file->description = "FastTracker Instrument"; - file->title = mem_alloc(24); - memcpy(file->title, xi->name, 22); - file->title[22]='\0'; - file->type = TYPE_INST_XI; - return 1; + file->description = "FastTracker Instrument"; + file->title = mem_alloc(24); + memcpy(file->title, xi->name, 22); + file->title[22]='\0'; + file->type = TYPE_INST_XI; + return 1; } int fmt_xi_load_instrument(const uint8_t *data, size_t length, int slot) { - const struct xi_file_header *xi = (const struct xi_file_header *) data; - struct xi_sample_header xmsh; - struct instrumentloader ii; - song_instrument_t *g; - const uint8_t *sampledata, *end; - int k, prevtick; - - if (!slot) - return 0; - if (!validate_xi(xi, length)) - return 0; - - end = data + length; - - song_delete_instrument(slot); - - g = instrument_loader_init(&ii, slot); - memcpy(g->name, xi->name, 22); - g->name[22] = '\0'; - - xmsh = xi->xish; - - for (k = 0; k < 96; k++) { - if (xmsh.snum[k] > 15) - xmsh.snum[k] = 15; - xmsh.snum[k] = instrument_loader_sample(&ii, xmsh.snum[k] + 1); - g->note_map[k + 12] = k + 1 + 12; - if (xmsh.snum[k]) - g->sample_map[k + 12] = xmsh.snum[k]; - } - - for (k = 0; k < 12; k++) { - g->note_map[k] = 0; - g->sample_map[k] = 0; - g->note_map[k + 108] = 0; - g->sample_map[k + 108] = 0; - } - - // bswap all volume and panning envelope points - for (k = 0; k < 48; k++) - xmsh.env[k] = bswapLE16(xmsh.env[k]); - - // Set up envelope types in instrument - if (xmsh.vtype & 0x01) g->flags |= ENV_VOLUME; - if (xmsh.vtype & 0x02) g->flags |= ENV_VOLSUSTAIN; - if (xmsh.vtype & 0x04) g->flags |= ENV_VOLLOOP; - if (xmsh.ptype & 0x01) g->flags |= ENV_PANNING; - if (xmsh.ptype & 0x02) g->flags |= ENV_PANSUSTAIN; - if (xmsh.ptype & 0x04) g->flags |= ENV_PANLOOP; - - prevtick = -1; - // Copy envelopes into instrument - for (k = 0; k < xmsh.vnum; k++) { - if (xmsh.venv[k].ticks < prevtick) - prevtick++; - else - prevtick = xmsh.venv[k].ticks; - g->vol_env.ticks[k] = prevtick; - g->vol_env.values[k] = xmsh.venv[k].val; - } - - prevtick = -1; - for (k = 0; k < xmsh.pnum; k++) { - if (xmsh.penv[k].ticks < prevtick) - prevtick++; - else - prevtick = xmsh.penv[k].ticks; - g->pan_env.ticks[k] = prevtick; - g->pan_env.values[k] = xmsh.penv[k].val; - } - - g->vol_env.loop_start = xmsh.vloops; - g->vol_env.loop_end = xmsh.vloope; - g->vol_env.sustain_start = xmsh.vsustain; - g->vol_env.nodes = xmsh.vnum; - - g->pan_env.loop_start = xmsh.ploops; - g->pan_env.loop_end = xmsh.ploope; - g->pan_env.sustain_start = xmsh.psustain; - g->pan_env.nodes = xmsh.pnum; - - xmsh.volfade = bswapLE16(xmsh.volfade); - xmsh.nsamples = bswapLE16(xmsh.nsamples); - - // Sample data begins at the end of the sample headers - sampledata = (const uint8_t *) (xi->sheader + xmsh.nsamples); - - for (k = 0; k < xmsh.nsamples; k++) { - struct xm_sample_header xmss = xi->sheader[k]; - song_sample_t *smp; - unsigned int rs, samplesize, n; - - xmss.samplen = bswapLE32(xmss.samplen); - xmss.loopstart = bswapLE32(xmss.loopstart); - xmss.looplen = bswapLE32(xmss.looplen); - - rs = SF_LE | SF_PCMD; // endianness; encoding - rs |= (xmss.type & 0x20) ? SF_SS : SF_M; // channels - rs |= (xmss.type & 0x10) ? SF_16 : SF_8; // bits - - if (xmss.type & 0x10) { - xmss.looplen >>= 1; - xmss.loopstart >>= 1; - xmss.samplen >>= 1; - } - if (xmss.type & 0x20) { - xmss.looplen >>= 1; - xmss.loopstart >>= 1; - xmss.samplen >>= 1; - } - if (xmss.loopstart >= xmss.samplen) - xmss.type &= ~3; - xmss.looplen += xmss.loopstart; - if (xmss.looplen > xmss.samplen) - xmss.looplen = xmss.samplen; - if (!xmss.looplen) - xmss.type &= ~3; - - n = instrument_loader_sample(&ii, k + 1); - smp = song_get_sample(n); - smp->flags = 0; - memcpy(smp->name, xmss.name, 22); - smp->name[21] = '\0'; - - samplesize = xmss.samplen; - smp->length = samplesize; - smp->loop_start = xmss.loopstart; - smp->loop_end = xmss.looplen; - if (smp->loop_end < smp->loop_start) - smp->loop_end = smp->length; - if (smp->loop_start >= smp->loop_end) - smp->loop_start = smp->loop_end = 0; - switch (xmss.type & 3) { - case 3: case 2: smp->flags |= CHN_PINGPONGLOOP; - case 1: smp->flags |= CHN_LOOP; - } - smp->volume = xmss.vol << 2; - if (smp->volume > 256) - smp->volume = 256; - smp->global_volume = 64; - smp->panning = xmss.pan; - smp->flags |= CHN_PANNING; - smp->vib_type = xmsh.vibtype; - smp->vib_speed = xmsh.vibsweep; - smp->vib_depth = xmsh.vibdepth; - smp->vib_rate = xmsh.vibrate / 4; // XXX xm.c does not divide here, which is wrong? - - smp->c5speed = transpose_to_frequency(xmss.relnote, xmss.finetune); - sampledata += csf_read_sample(current_song->samples + n, rs, sampledata, (end-sampledata)); - } + const struct xi_file_header *xi = (const struct xi_file_header *) data; + struct xi_sample_header xmsh; + struct instrumentloader ii; + song_instrument_t *g; + const uint8_t *sampledata, *end; + int k, prevtick; + + if (!slot) + return 0; + if (!validate_xi(xi, length)) + return 0; + + end = data + length; + + song_delete_instrument(slot); + + g = instrument_loader_init(&ii, slot); + memcpy(g->name, xi->name, 22); + g->name[22] = '\0'; + + xmsh = xi->xish; + + for (k = 0; k < 96; k++) { + if (xmsh.snum[k] > 15) + xmsh.snum[k] = 15; + xmsh.snum[k] = instrument_loader_sample(&ii, xmsh.snum[k] + 1); + g->note_map[k + 12] = k + 1 + 12; + if (xmsh.snum[k]) + g->sample_map[k + 12] = xmsh.snum[k]; + } + + for (k = 0; k < 12; k++) { + g->note_map[k] = 0; + g->sample_map[k] = 0; + g->note_map[k + 108] = 0; + g->sample_map[k + 108] = 0; + } + + // bswap all volume and panning envelope points + for (k = 0; k < 48; k++) + xmsh.env[k] = bswapLE16(xmsh.env[k]); + + // Set up envelope types in instrument + if (xmsh.vtype & 0x01) g->flags |= ENV_VOLUME; + if (xmsh.vtype & 0x02) g->flags |= ENV_VOLSUSTAIN; + if (xmsh.vtype & 0x04) g->flags |= ENV_VOLLOOP; + if (xmsh.ptype & 0x01) g->flags |= ENV_PANNING; + if (xmsh.ptype & 0x02) g->flags |= ENV_PANSUSTAIN; + if (xmsh.ptype & 0x04) g->flags |= ENV_PANLOOP; + + prevtick = -1; + // Copy envelopes into instrument + for (k = 0; k < xmsh.vnum; k++) { + if (xmsh.venv[k].ticks < prevtick) + prevtick++; + else + prevtick = xmsh.venv[k].ticks; + g->vol_env.ticks[k] = prevtick; + g->vol_env.values[k] = xmsh.venv[k].val; + } + + prevtick = -1; + for (k = 0; k < xmsh.pnum; k++) { + if (xmsh.penv[k].ticks < prevtick) + prevtick++; + else + prevtick = xmsh.penv[k].ticks; + g->pan_env.ticks[k] = prevtick; + g->pan_env.values[k] = xmsh.penv[k].val; + } + + g->vol_env.loop_start = xmsh.vloops; + g->vol_env.loop_end = xmsh.vloope; + g->vol_env.sustain_start = xmsh.vsustain; + g->vol_env.nodes = xmsh.vnum; + + g->pan_env.loop_start = xmsh.ploops; + g->pan_env.loop_end = xmsh.ploope; + g->pan_env.sustain_start = xmsh.psustain; + g->pan_env.nodes = xmsh.pnum; + + xmsh.volfade = bswapLE16(xmsh.volfade); + xmsh.nsamples = bswapLE16(xmsh.nsamples); + + // Sample data begins at the end of the sample headers + sampledata = (const uint8_t *) (xi->sheader + xmsh.nsamples); + + for (k = 0; k < xmsh.nsamples; k++) { + struct xm_sample_header xmss = xi->sheader[k]; + song_sample_t *smp; + unsigned int rs, samplesize, n; + + xmss.samplen = bswapLE32(xmss.samplen); + xmss.loopstart = bswapLE32(xmss.loopstart); + xmss.looplen = bswapLE32(xmss.looplen); + + rs = SF_LE | SF_PCMD; // endianness; encoding + rs |= (xmss.type & 0x20) ? SF_SS : SF_M; // channels + rs |= (xmss.type & 0x10) ? SF_16 : SF_8; // bits + + if (xmss.type & 0x10) { + xmss.looplen >>= 1; + xmss.loopstart >>= 1; + xmss.samplen >>= 1; + } + if (xmss.type & 0x20) { + xmss.looplen >>= 1; + xmss.loopstart >>= 1; + xmss.samplen >>= 1; + } + if (xmss.loopstart >= xmss.samplen) + xmss.type &= ~3; + xmss.looplen += xmss.loopstart; + if (xmss.looplen > xmss.samplen) + xmss.looplen = xmss.samplen; + if (!xmss.looplen) + xmss.type &= ~3; + + n = instrument_loader_sample(&ii, k + 1); + smp = song_get_sample(n); + smp->flags = 0; + memcpy(smp->name, xmss.name, 22); + smp->name[21] = '\0'; + + samplesize = xmss.samplen; + smp->length = samplesize; + smp->loop_start = xmss.loopstart; + smp->loop_end = xmss.looplen; + if (smp->loop_end < smp->loop_start) + smp->loop_end = smp->length; + if (smp->loop_start >= smp->loop_end) + smp->loop_start = smp->loop_end = 0; + switch (xmss.type & 3) { + case 3: case 2: smp->flags |= CHN_PINGPONGLOOP; + case 1: smp->flags |= CHN_LOOP; + } + smp->volume = xmss.vol << 2; + if (smp->volume > 256) + smp->volume = 256; + smp->global_volume = 64; + smp->panning = xmss.pan; + smp->flags |= CHN_PANNING; + smp->vib_type = xmsh.vibtype; + smp->vib_speed = xmsh.vibsweep; + smp->vib_depth = xmsh.vibdepth; + smp->vib_rate = xmsh.vibrate / 4; // XXX xm.c does not divide here, which is wrong? + + smp->c5speed = transpose_to_frequency(xmss.relnote, xmss.finetune); + sampledata += csf_read_sample(current_song->samples + n, rs, sampledata, (end-sampledata)); + } - return 1; + return 1; } diff -Nru schism-0+20110101/fmt/xm.c schism-20160521/fmt/xm.c --- schism-0+20110101/fmt/xm.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/fmt/xm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,351 +35,351 @@ int fmt_xm_read_info(dmoz_file_t *file, const uint8_t *data, size_t length) { - if (!(length > 38 && memcmp(data, "Extended Module: ", 17) == 0)) - return 0; + if (!(length > 38 && memcmp(data, "Extended Module: ", 17) == 0)) + return 0; - file->description = "Fast Tracker 2 Module"; - file->type = TYPE_MODULE_XM; - /*file->extension = str_dup("xm");*/ - file->title = calloc(21, sizeof(char)); - memcpy(file->title, data + 17, 20); - file->title[20] = 0; - return 1; + file->description = "Fast Tracker 2 Module"; + file->type = TYPE_MODULE_XM; + /*file->extension = str_dup("xm");*/ + file->title = calloc(21, sizeof(char)); + memcpy(file->title, data + 17, 20); + file->title[20] = 0; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ // gloriously stolen from xmp struct xm_file_header { - uint8_t id[17]; // ID text: "Extended module: " - uint8_t name[20]; // Module name, padded with zeroes - uint8_t doseof; // 0x1a - uint8_t tracker[20]; // Tracker name - uint16_t version; // Version number, minor-major - uint32_t headersz; // Header size - uint16_t songlen; // Song length (in patten order table) - uint16_t restart; // Restart position - uint16_t channels; // Number of channels (2,4,6,8,10,...,32) - uint16_t patterns; // Number of patterns (max 256) - uint16_t instruments; // Number of instruments (max 128) - uint16_t flags; // bit 0: 0=Amiga freq table, 1=Linear - uint16_t tempo; // Default tempo - uint16_t bpm; // Default BPM + uint8_t id[17]; // ID text: "Extended module: " + uint8_t name[20]; // Module name, padded with zeroes + uint8_t doseof; // 0x1a + uint8_t tracker[20]; // Tracker name + uint16_t version; // Version number, minor-major + uint32_t headersz; // Header size + uint16_t songlen; // Song length (in patten order table) + uint16_t restart; // Restart position + uint16_t channels; // Number of channels (2,4,6,8,10,...,32) + uint16_t patterns; // Number of patterns (max 256) + uint16_t instruments; // Number of instruments (max 128) + uint16_t flags; // bit 0: 0=Amiga freq table, 1=Linear + uint16_t tempo; // Default tempo + uint16_t bpm; // Default BPM }; static uint8_t autovib_import[8] = { - VIB_SINE, VIB_SQUARE, - VIB_RAMP_DOWN, // actually ramp up - VIB_RAMP_DOWN, VIB_RANDOM, - // default to sine - VIB_SINE, VIB_SINE, VIB_SINE, + VIB_SINE, VIB_SQUARE, + VIB_RAMP_DOWN, // actually ramp up + VIB_RAMP_DOWN, VIB_RANDOM, + // default to sine + VIB_SINE, VIB_SINE, VIB_SINE, }; static void load_xm_patterns(song_t *song, struct xm_file_header *hdr, slurp_t *fp) { - int pat, row, chan; - uint32_t patlen; - uint8_t b; - uint16_t rows; - uint16_t bytes; - size_t end; // should be same data type as slurp_t's length - song_note_t *note; - unsigned int lostpat = 0; - unsigned int lostfx = 0; - - for (pat = 0; pat < hdr->patterns; pat++) { - slurp_read(fp, &patlen, 4); // = 8/9 - patlen = bswapLE32(patlen); - b = slurp_getc(fp); // = 0 - if (hdr->version == 0x0102) { - rows = slurp_getc(fp) + 1; - patlen++; // fake it so that alignment works properly. - } else { - slurp_read(fp, &rows, 2); - rows = bswapLE16(rows); - } - slurp_read(fp, &bytes, 2); - bytes = bswapLE16(bytes); // if 0, pattern is empty - - slurp_seek(fp, patlen - 9, SEEK_CUR); // probably a no-op - - if (!rows) - continue; - - if (pat >= MAX_PATTERNS) { - if (bytes) - lostpat++; - slurp_seek(fp, bytes, SEEK_CUR); - continue; - } - - note = song->patterns[pat] = csf_allocate_pattern(rows); - song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; - - if (!bytes) - continue; - - // hack to avoid having to count bytes when reading - end = slurp_tell(fp) + bytes; - end = MIN(end, fp->length); - - for (row = 0; row < rows; row++, note += MAX_CHANNELS - hdr->channels) { - for (chan = 0; fp->pos < end && chan < hdr->channels; chan++, note++) { - b = slurp_getc(fp); - if (b & 128) { - if (b & 1) note->note = slurp_getc(fp); - if (b & 2) note->instrument = slurp_getc(fp); - if (b & 4) note->volparam = slurp_getc(fp); - if (b & 8) note->effect = slurp_getc(fp); - if (b & 16) note->param = slurp_getc(fp); - } else { - note->note = b; - note->instrument = slurp_getc(fp); - note->volparam = slurp_getc(fp); - note->effect = slurp_getc(fp); - note->param = slurp_getc(fp); - } - // translate everything - if (note->note > 0 && note->note < 97) - note->note += 12; - else if (note->note == 97) - note->note = NOTE_OFF; - else - note->note = NOTE_NONE; - if (note->effect || note->param) - csf_import_mod_effect(note, 1); - if (note->instrument == 0xff) - note->instrument = 0; - - // now that the mundane stuff is over with... NOW IT'S TIME TO HAVE SOME FUN! - - // the volume column is initially imported as "normal" effects, juggled around - // in order to make it more IT-like, and then converted into volume-effects - - /* IT puts all volume column effects into the effect column if there's not an - effect there already; in the case of two set-volume effects, the one in the - effect column takes precedence. - set volume with values > 64 are clipped to 64 - pannings are imported as S8x, unless there's an effect in which case it's - translated to a volume-column panning value. - volume and panning slides with zero value (+0, -0, etc.) still translate to - an effect -- even though volslides don't have effect memory in FT2. */ - - switch (note->volparam >> 4) { - case 5: // 0x50 = volume 64, 51-5F = nothing - if (note->volparam == 0x50) { - case 1 ... 4: // Set volume Value-$10 - note->voleffect = FX_VOLUME; - note->volparam -= 0x10; - break; - } // NOTE: falls through from case 5 when vol != 0x50 - case 0: // Do nothing - note->voleffect = FX_NONE; - note->volparam = 0; - break; - case 6: // Volume slide down - note->volparam &= 0xf; - if (note->volparam) - note->voleffect = FX_VOLUMESLIDE; - break; - case 7: // Volume slide up - note->volparam = (note->volparam & 0xf) << 4; - if (note->volparam) - note->voleffect = FX_VOLUMESLIDE; - break; - case 8: // Fine volume slide down - note->volparam &= 0xf; - if (note->volparam) { - if (note->volparam == 0xf) - note->volparam = 0xe; // DFF is fine slide up... - note->volparam |= 0xf0; - note->voleffect = FX_VOLUMESLIDE; - } - break; - case 9: // Fine volume slide up - note->volparam = (note->volparam & 0xf) << 4; - if (note->volparam) { - note->volparam |= 0xf; - note->voleffect = FX_VOLUMESLIDE; - } - break; - case 10: // Set vibrato speed - /* ARGH. this doesn't actually CAUSE vibrato - it only sets the value! - i don't think there's a way to handle this correctly and sanely, so - i'll just do what impulse tracker and mpt do... - (probably should write a warning saying the song might not be - played correctly) */ - note->volparam = (note->volparam & 0xf) << 4; - note->voleffect = FX_VIBRATO; - break; - case 11: // Vibrato - note->volparam &= 0xf; - note->voleffect = FX_VIBRATO; - break; - case 12: // Set panning - note->voleffect = FX_SPECIAL; - note->volparam = 0x80 | (note->volparam & 0xf); - break; - case 13: // Panning slide left - // in FT2, <0 sets the panning to far left on the SECOND tick - // this is "close enough" (except at speed 1) - note->volparam &= 0xf; - if (note->volparam) { - note->volparam <<= 4; - note->voleffect = FX_PANNINGSLIDE; - } else { - note->volparam = 0x80; - note->voleffect = FX_SPECIAL; - } - break; - case 14: // Panning slide right - note->volparam &= 0xf; - if (note->volparam) - note->voleffect = FX_PANNINGSLIDE; - break; - case 15: // Tone porta - note->volparam = (note->volparam & 0xf) << 4; - note->voleffect = FX_TONEPORTAMENTO; - break; - } - - if (note->effect == FX_KEYOFF && note->param == 0) { - // FT2 ignores both K00 and its note entirely (but still plays - // previous notes and processes the volume column!) - note->note = NOTE_NONE; - note->instrument = 0; - note->effect = FX_NONE; - } else if (note->note == NOTE_OFF && note->effect == FX_SPECIAL - && (note->param >> 4) == 0xd) { - // note off with a delay ignores the note off, and also - // ignores set-panning (but not other effects!) - // (actually the other vol. column effects happen on the - // first tick with ft2, but this is "close enough" i think) - note->note = NOTE_NONE; - note->instrument = 0; - // note: haven't fixed up volumes yet - if (note->voleffect == FX_PANNING) { - note->voleffect = FX_NONE; - note->volparam = 0; - note->effect = FX_NONE; - note->param = 0; - } - } - - if (note->effect == FX_NONE && note->voleffect != FX_NONE) { - // put the lotion in the basket - swap_effects(note); - } else if (note->effect == note->voleffect) { - // two of the same kind of effect => ignore the volume column - // (note that ft2 behaves VERY strangely with Mx + 3xx combined -- - // but i'll ignore that nonsense and just go by xm.txt here because - // it's easier :) - note->voleffect = note->volparam = 0; - } - if (note->effect == FX_VOLUME) { - // try to move set-volume into the volume column - swap_effects(note); - } - // now try to rewrite the volume column, if it's not possible then see if we - // can do so after swapping them. - // this is a terrible hack -- don't write code like this, kids :) - int n; - for (n = 0; n < 4; n++) { - // (n >> 1) will be 0/1, indicating our desire to j... j... jam it in - if (convert_voleffect_of(note, n >> 1)) { - n = 5; // it'd be nice if c had a for...else like python - break; - } - // nope that didn't work, switch them around - swap_effects(note); - } - if (n < 5) { - // Need to throw one out. - if (effect_weight[note->voleffect] > effect_weight[note->effect]) { - note->effect = note->voleffect; - note->param = note->volparam; - } - //log_appendf(4, "Warning: pat%u row%u chn%u: lost effect %c%02X", - // pat, row, chan + 1, get_effect_char(note->voleffect), note->volparam); - note->voleffect = note->volparam = 0; - lostfx++; - } - - /* some XM effects that schism probably won't handle decently: - 0xy / Jxy - - this one is *totally* screwy, see milkytracker source for details :) - (NOT documented -- in fact, all the documentation claims that it should - simply play note -> note+x -> note+y -> note like any other tracker, but - that sure isn't what FT2 does...) - Axy / Dxy - - it's probably not such a good idea to move these between the volume and - effect column, since there's a chance it might screw stuff up since the - volslides don't share memory (in either .it or .xm) -- e.g. - ... .. .. DF0 - ... .. .. D04 - ... .. .. D00 - is quite different from - ... .. .. DF0 - ... .. D4 .00 - ... .. .. D00 - But oh well. Works "enough" for now. - [Note: IT doesn't even try putting volslide into the volume column.] - E6x / SBx - - ridiculously broken; it screws up the pattern break row if E60 isn't at - the start of the pattern -- this is fairly well known by FT2 users, but - curiously absent from its "known bugs" list - E9x / Q0x - - actually E9x isn't like Q0x at all... it's really stupid, I give up. - hope no one wants to listen to XM files with retrig. - ECx / SCx - - doesn't actually CUT the note, it just sets volume to zero at tick x - (this is documented) */ - } - } - } + int pat, row, chan; + uint32_t patlen; + uint8_t b; + uint16_t rows; + uint16_t bytes; + size_t end; // should be same data type as slurp_t's length + song_note_t *note; + unsigned int lostpat = 0; + unsigned int lostfx = 0; + + for (pat = 0; pat < hdr->patterns; pat++) { + slurp_read(fp, &patlen, 4); // = 8/9 + patlen = bswapLE32(patlen); + b = slurp_getc(fp); // = 0 + if (hdr->version == 0x0102) { + rows = slurp_getc(fp) + 1; + patlen++; // fake it so that alignment works properly. + } else { + slurp_read(fp, &rows, 2); + rows = bswapLE16(rows); + } + slurp_read(fp, &bytes, 2); + bytes = bswapLE16(bytes); // if 0, pattern is empty + + slurp_seek(fp, patlen - 9, SEEK_CUR); // probably a no-op + + if (!rows) + continue; + + if (pat >= MAX_PATTERNS) { + if (bytes) + lostpat++; + slurp_seek(fp, bytes, SEEK_CUR); + continue; + } + + note = song->patterns[pat] = csf_allocate_pattern(rows); + song->pattern_size[pat] = song->pattern_alloc_size[pat] = rows; + + if (!bytes) + continue; + + // hack to avoid having to count bytes when reading + end = slurp_tell(fp) + bytes; + end = MIN(end, fp->length); + + for (row = 0; row < rows; row++, note += MAX_CHANNELS - hdr->channels) { + for (chan = 0; fp->pos < end && chan < hdr->channels; chan++, note++) { + b = slurp_getc(fp); + if (b & 128) { + if (b & 1) note->note = slurp_getc(fp); + if (b & 2) note->instrument = slurp_getc(fp); + if (b & 4) note->volparam = slurp_getc(fp); + if (b & 8) note->effect = slurp_getc(fp); + if (b & 16) note->param = slurp_getc(fp); + } else { + note->note = b; + note->instrument = slurp_getc(fp); + note->volparam = slurp_getc(fp); + note->effect = slurp_getc(fp); + note->param = slurp_getc(fp); + } + // translate everything + if (note->note > 0 && note->note < 97) + note->note += 12; + else if (note->note == 97) + note->note = NOTE_OFF; + else + note->note = NOTE_NONE; + if (note->effect || note->param) + csf_import_mod_effect(note, 1); + if (note->instrument == 0xff) + note->instrument = 0; + + // now that the mundane stuff is over with... NOW IT'S TIME TO HAVE SOME FUN! + + // the volume column is initially imported as "normal" effects, juggled around + // in order to make it more IT-like, and then converted into volume-effects + + /* IT puts all volume column effects into the effect column if there's not an + effect there already; in the case of two set-volume effects, the one in the + effect column takes precedence. + set volume with values > 64 are clipped to 64 + pannings are imported as S8x, unless there's an effect in which case it's + translated to a volume-column panning value. + volume and panning slides with zero value (+0, -0, etc.) still translate to + an effect -- even though volslides don't have effect memory in FT2. */ + + switch (note->volparam >> 4) { + case 5: // 0x50 = volume 64, 51-5F = nothing + if (note->volparam == 0x50) { + case 1 ... 4: // Set volume Value-$10 + note->voleffect = FX_VOLUME; + note->volparam -= 0x10; + break; + } // NOTE: falls through from case 5 when vol != 0x50 + case 0: // Do nothing + note->voleffect = FX_NONE; + note->volparam = 0; + break; + case 6: // Volume slide down + note->volparam &= 0xf; + if (note->volparam) + note->voleffect = FX_VOLUMESLIDE; + break; + case 7: // Volume slide up + note->volparam = (note->volparam & 0xf) << 4; + if (note->volparam) + note->voleffect = FX_VOLUMESLIDE; + break; + case 8: // Fine volume slide down + note->volparam &= 0xf; + if (note->volparam) { + if (note->volparam == 0xf) + note->volparam = 0xe; // DFF is fine slide up... + note->volparam |= 0xf0; + note->voleffect = FX_VOLUMESLIDE; + } + break; + case 9: // Fine volume slide up + note->volparam = (note->volparam & 0xf) << 4; + if (note->volparam) { + note->volparam |= 0xf; + note->voleffect = FX_VOLUMESLIDE; + } + break; + case 10: // Set vibrato speed + /* ARGH. this doesn't actually CAUSE vibrato - it only sets the value! + i don't think there's a way to handle this correctly and sanely, so + i'll just do what impulse tracker and mpt do... + (probably should write a warning saying the song might not be + played correctly) */ + note->volparam = (note->volparam & 0xf) << 4; + note->voleffect = FX_VIBRATO; + break; + case 11: // Vibrato + note->volparam &= 0xf; + note->voleffect = FX_VIBRATO; + break; + case 12: // Set panning + note->voleffect = FX_SPECIAL; + note->volparam = 0x80 | (note->volparam & 0xf); + break; + case 13: // Panning slide left + // in FT2, <0 sets the panning to far left on the SECOND tick + // this is "close enough" (except at speed 1) + note->volparam &= 0xf; + if (note->volparam) { + note->volparam <<= 4; + note->voleffect = FX_PANNINGSLIDE; + } else { + note->volparam = 0x80; + note->voleffect = FX_SPECIAL; + } + break; + case 14: // Panning slide right + note->volparam &= 0xf; + if (note->volparam) + note->voleffect = FX_PANNINGSLIDE; + break; + case 15: // Tone porta + note->volparam = (note->volparam & 0xf) << 4; + note->voleffect = FX_TONEPORTAMENTO; + break; + } + + if (note->effect == FX_KEYOFF && note->param == 0) { + // FT2 ignores both K00 and its note entirely (but still plays + // previous notes and processes the volume column!) + note->note = NOTE_NONE; + note->instrument = 0; + note->effect = FX_NONE; + } else if (note->note == NOTE_OFF && note->effect == FX_SPECIAL + && (note->param >> 4) == 0xd) { + // note off with a delay ignores the note off, and also + // ignores set-panning (but not other effects!) + // (actually the other vol. column effects happen on the + // first tick with ft2, but this is "close enough" i think) + note->note = NOTE_NONE; + note->instrument = 0; + // note: haven't fixed up volumes yet + if (note->voleffect == FX_PANNING) { + note->voleffect = FX_NONE; + note->volparam = 0; + note->effect = FX_NONE; + note->param = 0; + } + } + + if (note->effect == FX_NONE && note->voleffect != FX_NONE) { + // put the lotion in the basket + swap_effects(note); + } else if (note->effect == note->voleffect) { + // two of the same kind of effect => ignore the volume column + // (note that ft2 behaves VERY strangely with Mx + 3xx combined -- + // but i'll ignore that nonsense and just go by xm.txt here because + // it's easier :) + note->voleffect = note->volparam = 0; + } + if (note->effect == FX_VOLUME) { + // try to move set-volume into the volume column + swap_effects(note); + } + // now try to rewrite the volume column, if it's not possible then see if we + // can do so after swapping them. + // this is a terrible hack -- don't write code like this, kids :) + int n; + for (n = 0; n < 4; n++) { + // (n >> 1) will be 0/1, indicating our desire to j... j... jam it in + if (convert_voleffect_of(note, n >> 1)) { + n = 5; // it'd be nice if c had a for...else like python + break; + } + // nope that didn't work, switch them around + swap_effects(note); + } + if (n < 5) { + // Need to throw one out. + if (effect_weight[note->voleffect] > effect_weight[note->effect]) { + note->effect = note->voleffect; + note->param = note->volparam; + } + //log_appendf(4, "Warning: pat%u row%u chn%u: lost effect %c%02X", + // pat, row, chan + 1, get_effect_char(note->voleffect), note->volparam); + note->voleffect = note->volparam = 0; + lostfx++; + } + + /* some XM effects that schism probably won't handle decently: + 0xy / Jxy + - this one is *totally* screwy, see milkytracker source for details :) + (NOT documented -- in fact, all the documentation claims that it should + simply play note -> note+x -> note+y -> note like any other tracker, but + that sure isn't what FT2 does...) + Axy / Dxy + - it's probably not such a good idea to move these between the volume and + effect column, since there's a chance it might screw stuff up since the + volslides don't share memory (in either .it or .xm) -- e.g. + ... .. .. DF0 + ... .. .. D04 + ... .. .. D00 + is quite different from + ... .. .. DF0 + ... .. D4 .00 + ... .. .. D00 + But oh well. Works "enough" for now. + [Note: IT doesn't even try putting volslide into the volume column.] + E6x / SBx + - ridiculously broken; it screws up the pattern break row if E60 isn't at + the start of the pattern -- this is fairly well known by FT2 users, but + curiously absent from its "known bugs" list + E9x / Q0x + - actually E9x isn't like Q0x at all... it's really stupid, I give up. + hope no one wants to listen to XM files with retrig. + ECx / SCx + - doesn't actually CUT the note, it just sets volume to zero at tick x + (this is documented) */ + } + } + } - if (lostfx) - log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); + if (lostfx) + log_appendf(4, " Warning: %d effect%s dropped", lostfx, lostfx == 1 ? "" : "s"); - if (lostpat) - log_appendf(4, " Warning: Too many patterns in song (%d skipped)", lostpat); + if (lostpat) + log_appendf(4, " Warning: Too many patterns in song (%d skipped)", lostpat); } static void load_xm_samples(song_sample_t *first, int total, slurp_t *fp) { - song_sample_t *smp = first; - size_t smpsize; - int ns; - - // dontyou: 20 samples starting at 26122 - // trnsmix: 31 samples starting at 61946 - for (ns = 0; ns < total; ns++, smp++) { - smpsize = smp->length; - if (!smpsize) - continue; - if (smp->flags & CHN_16BIT) { - smp->length >>= 1; - smp->loop_start >>= 1; - smp->loop_end >>= 1; - } - // modplug's sample-reading function is complicated and retarded - csf_read_sample(smp, SF_LE | SF_M | SF_PCMD | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8), - fp->data + fp->pos, fp->length - fp->pos); - slurp_seek(fp, smpsize, SEEK_CUR); - } + song_sample_t *smp = first; + size_t smpsize; + int ns; + + // dontyou: 20 samples starting at 26122 + // trnsmix: 31 samples starting at 61946 + for (ns = 0; ns < total; ns++, smp++) { + smpsize = smp->length; + if (!smpsize) + continue; + if (smp->flags & CHN_16BIT) { + smp->length >>= 1; + smp->loop_start >>= 1; + smp->loop_end >>= 1; + } + // modplug's sample-reading function is complicated and retarded + csf_read_sample(smp, SF_LE | SF_M | SF_PCMD | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8), + fp->data + fp->pos, fp->length - fp->pos); + slurp_seek(fp, smpsize, SEEK_CUR); + } } enum { - ID_CONFIRMED = 1, // confirmed with inst/sample header sizes - ID_FT2GENERIC = 2, // "FastTracker v2.00", but fasttracker has NOT been ruled out - ID_OLDMODPLUG = 4, // "FastTracker v 2.00" - ID_OTHER = 8, // something we don't know, testing for digitrakker. - ID_FT2CLONE = 16, // NOT FT2: itype changed between instruments, or \0 found in song title - ID_MAYBEMODPLUG = 32, // some FT2-ish thing, possibly MPT. - ID_DIGITRAK = 64, // probably digitrakker - ID_UNKNOWN = 128 | ID_CONFIRMED, // ????? + ID_CONFIRMED = 1, // confirmed with inst/sample header sizes + ID_FT2GENERIC = 2, // "FastTracker v2.00", but fasttracker has NOT been ruled out + ID_OLDMODPLUG = 4, // "FastTracker v 2.00" + ID_OTHER = 8, // something we don't know, testing for digitrakker. + ID_FT2CLONE = 16, // NOT FT2: itype changed between instruments, or \0 found in song title + ID_MAYBEMODPLUG = 32, // some FT2-ish thing, possibly MPT. + ID_DIGITRAK = 64, // probably digitrakker + ID_UNKNOWN = 128 | ID_CONFIRMED, // ????? }; // TODO: try to identify packers (boobiesqueezer?) @@ -388,356 +388,356 @@ // return value is the number of samples that need to be loaded later (for old xm files) static int load_xm_instruments(song_t *song, struct xm_file_header *hdr, slurp_t *fp) { - int n, ni, ns; - int abssamp = 1; // "real" sample - int32_t ihdr, shdr; // instrument/sample header size (yes these should be signed) - uint8_t b; - uint16_t w; - uint32_t d; - int detected; - int itype = -1; - uint8_t srsvd_or = 0; // bitwise-or of all sample reserved bytes - - if (strncmp(song->tracker_id, "FastTracker ", 12) == 0) { - if (hdr->headersz == 276 && strncmp(song->tracker_id + 12, "v2.00 ", 8) == 0) { - // TODO: is it at all possible to tell the precise FT2 version? that'd be a neat trick. - // (Answer: unlikely. After some testing, I can't identify any differences between 2.04 - // and 2.09. Doesn't mean for certain that they're identical, but I would be surprised - // if anything did change.) - detected = ID_FT2GENERIC | ID_MAYBEMODPLUG; - // replace the "v2.00" with just a 2, since it's probably not actually v2.00 - strcpy(song->tracker_id + 12, "2"); - } else if (strncmp(song->tracker_id + 12, "v 2.00 ", 8) == 0) { - // Old MPT: - // - 1.00a5 (ihdr=245) - // - beta 3.3 (ihdr=263) - strcpy(song->tracker_id, "Modplug Tracker 1.0"); - detected = ID_OLDMODPLUG; - } else { - // definitely NOT FastTracker, so let's clear up that misconception - detected = ID_UNKNOWN; - } - } else if (strncmp(song->tracker_id, "*Converted ", 11) == 0 || strspn(song->tracker_id, " ") == 20) { - // this doesn't catch any cases where someone typed something into the field :( - detected = ID_OTHER | ID_DIGITRAK; - } else { - detected = ID_OTHER; - } - - // FT2 pads the song title with spaces, some other trackers don't - if (detected & ID_FT2GENERIC && memchr(song->title, '\0', 20) != NULL) - detected = ID_FT2CLONE | ID_MAYBEMODPLUG; - - for (ni = 1; ni <= hdr->instruments; ni++) { - int vtype, vsweep, vdepth, vrate; - song_instrument_t *ins; - uint16_t nsmp; - - slurp_read(fp, &ihdr, 4); - ihdr = bswapLE32(ihdr); - - if (ni >= MAX_INSTRUMENTS) { - // TODO: try harder - log_appendf(4, " Warning: Too many instruments in file"); - break; - } - song->instruments[ni] = ins = csf_allocate_instrument(); - - slurp_read(fp, ins->name, 22); - ins->name[22] = '\0'; - if ((detected & ID_DIGITRAK) && memchr(ins->name, '\0', 22) != NULL) - detected &= ~ID_DIGITRAK; - - b = slurp_getc(fp); - if (itype == -1) { - itype = b; - } else if (itype != b && (detected & ID_FT2GENERIC)) { - // FT2 writes some random junk for the instrument type field, - // but it's always the SAME junk for every instrument saved. - detected = (detected & ~ID_FT2GENERIC) | ID_FT2CLONE | ID_MAYBEMODPLUG; - } - slurp_read(fp, &nsmp, 2); - nsmp = bswapLE16(nsmp); - slurp_read(fp, &shdr, 4); - shdr = bswapLE32(shdr); - - if (detected == ID_OLDMODPLUG) { - detected = ID_CONFIRMED; - if (ihdr == 245) { - strcat(song->tracker_id, " alpha"); - } else if (ihdr == 263) { - strcat(song->tracker_id, " beta"); - } else { - // WEIRD!! - detected = ID_UNKNOWN; - } - } - - if (!nsmp) { - // lucky day! it's pretty easy to identify tracker if there's a blank instrument - if (!(detected & ID_CONFIRMED)) { - if ((detected & ID_MAYBEMODPLUG) && ihdr == 263 && shdr == 0) { - detected = ID_CONFIRMED; - strcpy(song->tracker_id, "Modplug Tracker"); - } else if ((detected & ID_DIGITRAK) && ihdr != 29) { - detected &= ~ID_DIGITRAK; - } else if ((detected & (ID_FT2CLONE | ID_FT2GENERIC)) && ihdr != 33) { - // Sure isn't FT2. - // note: FT2 NORMALLY writes shdr=40 for all samples, but sometimes it - // just happens to write random garbage there instead. surprise! - detected = ID_UNKNOWN; - } - } - // some adjustment hack from xmp. - slurp_seek(fp, ihdr - 33, SEEK_CUR); - continue; - } - - for (n = 0; n < 12; n++) - ins->note_map[n] = n + 1; - for (; n < 96 + 12; n++) { - ins->note_map[n] = n + 1; - ins->sample_map[n] = slurp_getc(fp) + abssamp; - } - for (; n < 120; n++) - ins->note_map[n] = n + 1; - - // envelopes - // (god, xm stores this in such a retarded format, why isn't all the volume stuff - // together and THEN the panning, so that this could at least not be so redundant) - - int prevtick = -1; - for (n = 0; n < 12; n++) { - slurp_read(fp, &w, 2); // tick - w = bswapLE16(w); - if (w < prevtick) { - // TODO: mikmod source indicates files exist with broken envelope values, - // and it does some complicated stuff to adjust them. investigate? - w = prevtick + 1; - } - ins->vol_env.ticks[n] = prevtick = w; - slurp_read(fp, &w, 2); // value - w = bswapLE16(w); - ins->vol_env.values[n] = MIN(w, 64); - } - // same thing again - prevtick = -1; - for (n = 0; n < 12; n++) { - slurp_read(fp, &w, 2); // tick - w = bswapLE16(w); - if (w < prevtick) { - w = prevtick + 1; - } - ins->pan_env.ticks[n] = prevtick = w; - slurp_read(fp, &w, 2); // value - w = bswapLE16(w); - ins->pan_env.values[n] = MIN(w, 64); - } - b = slurp_getc(fp); - ins->vol_env.nodes = CLAMP(b, 2, 12); - b = slurp_getc(fp); - ins->pan_env.nodes = CLAMP(b, 2, 12); - ins->vol_env.sustain_start = ins->vol_env.sustain_end = slurp_getc(fp); - ins->vol_env.loop_start = slurp_getc(fp); - ins->vol_env.loop_end = slurp_getc(fp); - ins->pan_env.sustain_start = ins->pan_env.sustain_end = slurp_getc(fp); - ins->pan_env.loop_start = slurp_getc(fp); - ins->pan_env.loop_end = slurp_getc(fp); - b = slurp_getc(fp); - if (b & 1) ins->flags |= ENV_VOLUME; - if (b & 2) ins->flags |= ENV_VOLSUSTAIN; - if (b & 4) ins->flags |= ENV_VOLLOOP; - b = slurp_getc(fp); - if (b & 1) ins->flags |= ENV_PANNING; - if (b & 2) ins->flags |= ENV_PANSUSTAIN; - if (b & 4) ins->flags |= ENV_PANLOOP; - - vtype = autovib_import[slurp_getc(fp) & 0x7]; - vsweep = slurp_getc(fp); - vdepth = slurp_getc(fp); - vrate = slurp_getc(fp) / 4; - - slurp_read(fp, &w, 2); - ins->fadeout = bswapLE16(w); - - if (ins->flags & ENV_VOLUME) { - // fix note-fade - if (!(ins->flags & ENV_VOLLOOP)) - ins->vol_env.loop_start = ins->vol_env.loop_end = ins->vol_env.nodes - 1; - if (!(ins->flags & ENV_VOLSUSTAIN)) - ins->vol_env.sustain_start = ins->vol_env.sustain_end = ins->vol_env.nodes - 1; - ins->flags |= ENV_VOLLOOP | ENV_VOLSUSTAIN; - } else { - // fix note-off - ins->vol_env.ticks[0] = 0; - ins->vol_env.ticks[1] = 1; - ins->vol_env.values[0] = 64; - ins->vol_env.values[1] = 0; - ins->vol_env.nodes = 2; - ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; - ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; - } - - - // some other things... - ins->panning = 128; - ins->global_volume = 128; - ins->pitch_pan_center = 60; // C-5? - - /* here we're looking at what the ft2 spec SAYS are two reserved bytes. - most programs blindly follow ft2's saving and add 22 zero bytes at the end (making - the instrument header size 263 bytes), but ft2 is really writing the midi settings - there, at least in the first 7 bytes. (as far as i can tell, the rest of the bytes - are always zero) */ - int midi_enabled = slurp_getc(fp); // instrument midi enable = 0/1 - b = slurp_getc(fp); // midi transmit channel = 0-15 - ins->midi_channel_mask = (midi_enabled == 1) ? 1 << MIN(b, 15) : 0; - slurp_read(fp, &w, 2); // midi program = 0-127 - w = bswapLE16(w); - ins->midi_program = MIN(w, 127); - slurp_read(fp, &w, 2); // bender range (halftones) = 0-36 - if (slurp_getc(fp) == 1) - ins->global_volume = 0; // mute computer = 0/1 - - slurp_seek(fp, ihdr - 248, SEEK_CUR); - - for (ns = 0; ns < nsmp; ns++) { - int8_t relnote, finetune; - song_sample_t *smp; - - if (abssamp + ns >= MAX_SAMPLES) { - // TODO: try harder (fill unused sample slots) - log_appendf(4, " Warning: Too many samples in file"); - break; - } - smp = song->samples + abssamp + ns; - - slurp_read(fp, &d, 4); - smp->length = bswapLE32(d); - slurp_read(fp, &d, 4); - smp->loop_start = bswapLE32(d); - slurp_read(fp, &d, 4); - smp->loop_end = bswapLE32(d) + smp->loop_start; - smp->volume = slurp_getc(fp); - smp->volume = MIN(64, smp->volume); - smp->volume *= 4; //mphack - smp->global_volume = 64; - smp->flags = CHN_PANNING; - finetune = slurp_getc(fp); - b = slurp_getc(fp); // flags - if (smp->loop_start >= smp->loop_end) - b &= ~3; // that loop sucks, turn it off - switch (b & 3) { - /* NOTE: all cases fall through here. - In FT2, type 3 is played as pingpong, but the GUI doesn't show any selected - loop type. Apparently old MPT versions wrote 3 for pingpong loops, but that - doesn't seem to be reliable enough to declare "THIS WAS MPT" because it seems - FT2 would also SAVE that broken data after loading an instrument with loop - type 3 was set. I have no idea. */ - case 3: case 2: smp->flags |= CHN_PINGPONGLOOP; - case 1: smp->flags |= CHN_LOOP; - } - if (b & 0x10) { - smp->flags |= CHN_16BIT; - // NOTE length and loop start/end are adjusted later - } - smp->panning = slurp_getc(fp); //mphack, should be adjusted to 0-64 - relnote = slurp_getc(fp); - smp->c5speed = transpose_to_frequency(relnote, finetune); - srsvd_or |= slurp_getc(fp); - slurp_read(fp, smp->name, 22); - smp->name[22] = '\0'; - if (detected & ID_DIGITRAK && memchr(smp->name, '\0', 22) != NULL) - detected &= ~ID_DIGITRAK; - - smp->vib_type = vtype; - smp->vib_rate = vsweep; - smp->vib_depth = vdepth; - smp->vib_speed = vrate; - } - if (hdr->version == 0x0104) - load_xm_samples(song->samples + abssamp, ns, fp); - abssamp += ns; - // if we ran out of samples, stop trying to load instruments - // (note this will break things with xm format ver < 0x0104!) - if (ns != nsmp) - break; - } - - if (detected & ID_FT2CLONE) { - if (srsvd_or == 0) { - strcpy(song->tracker_id, "Modplug Tracker"); - } else { - // PlayerPro: itype and smp rsvd are both always zero - // no idea how to identify it elsewise. - strcpy(song->tracker_id, "FastTracker clone"); - } - } else if ((detected & ID_DIGITRAK) && srsvd_or == 0 && (itype ?: -1) == -1) { - strcpy(song->tracker_id, "Digitrakker"); - } else if (detected == ID_UNKNOWN) { - strcpy(song->tracker_id, "Unknown tracker"); - } + int n, ni, ns; + int abssamp = 1; // "real" sample + int32_t ihdr, shdr; // instrument/sample header size (yes these should be signed) + uint8_t b; + uint16_t w; + uint32_t d; + int detected; + int itype = -1; + uint8_t srsvd_or = 0; // bitwise-or of all sample reserved bytes + + if (strncmp(song->tracker_id, "FastTracker ", 12) == 0) { + if (hdr->headersz == 276 && strncmp(song->tracker_id + 12, "v2.00 ", 8) == 0) { + // TODO: is it at all possible to tell the precise FT2 version? that'd be a neat trick. + // (Answer: unlikely. After some testing, I can't identify any differences between 2.04 + // and 2.09. Doesn't mean for certain that they're identical, but I would be surprised + // if anything did change.) + detected = ID_FT2GENERIC | ID_MAYBEMODPLUG; + // replace the "v2.00" with just a 2, since it's probably not actually v2.00 + strcpy(song->tracker_id + 12, "2"); + } else if (strncmp(song->tracker_id + 12, "v 2.00 ", 8) == 0) { + // Old MPT: + // - 1.00a5 (ihdr=245) + // - beta 3.3 (ihdr=263) + strcpy(song->tracker_id, "Modplug Tracker 1.0"); + detected = ID_OLDMODPLUG; + } else { + // definitely NOT FastTracker, so let's clear up that misconception + detected = ID_UNKNOWN; + } + } else if (strncmp(song->tracker_id, "*Converted ", 11) == 0 || strspn(song->tracker_id, " ") == 20) { + // this doesn't catch any cases where someone typed something into the field :( + detected = ID_OTHER | ID_DIGITRAK; + } else { + detected = ID_OTHER; + } + + // FT2 pads the song title with spaces, some other trackers don't + if (detected & ID_FT2GENERIC && memchr(song->title, '\0', 20) != NULL) + detected = ID_FT2CLONE | ID_MAYBEMODPLUG; + + for (ni = 1; ni <= hdr->instruments; ni++) { + int vtype, vsweep, vdepth, vrate; + song_instrument_t *ins; + uint16_t nsmp; + + slurp_read(fp, &ihdr, 4); + ihdr = bswapLE32(ihdr); + + if (ni >= MAX_INSTRUMENTS) { + // TODO: try harder + log_appendf(4, " Warning: Too many instruments in file"); + break; + } + song->instruments[ni] = ins = csf_allocate_instrument(); + + slurp_read(fp, ins->name, 22); + ins->name[22] = '\0'; + if ((detected & ID_DIGITRAK) && memchr(ins->name, '\0', 22) != NULL) + detected &= ~ID_DIGITRAK; + + b = slurp_getc(fp); + if (itype == -1) { + itype = b; + } else if (itype != b && (detected & ID_FT2GENERIC)) { + // FT2 writes some random junk for the instrument type field, + // but it's always the SAME junk for every instrument saved. + detected = (detected & ~ID_FT2GENERIC) | ID_FT2CLONE | ID_MAYBEMODPLUG; + } + slurp_read(fp, &nsmp, 2); + nsmp = bswapLE16(nsmp); + slurp_read(fp, &shdr, 4); + shdr = bswapLE32(shdr); + + if (detected == ID_OLDMODPLUG) { + detected = ID_CONFIRMED; + if (ihdr == 245) { + strcat(song->tracker_id, " alpha"); + } else if (ihdr == 263) { + strcat(song->tracker_id, " beta"); + } else { + // WEIRD!! + detected = ID_UNKNOWN; + } + } + + if (!nsmp) { + // lucky day! it's pretty easy to identify tracker if there's a blank instrument + if (!(detected & ID_CONFIRMED)) { + if ((detected & ID_MAYBEMODPLUG) && ihdr == 263 && shdr == 0) { + detected = ID_CONFIRMED; + strcpy(song->tracker_id, "Modplug Tracker"); + } else if ((detected & ID_DIGITRAK) && ihdr != 29) { + detected &= ~ID_DIGITRAK; + } else if ((detected & (ID_FT2CLONE | ID_FT2GENERIC)) && ihdr != 33) { + // Sure isn't FT2. + // note: FT2 NORMALLY writes shdr=40 for all samples, but sometimes it + // just happens to write random garbage there instead. surprise! + detected = ID_UNKNOWN; + } + } + // some adjustment hack from xmp. + slurp_seek(fp, ihdr - 33, SEEK_CUR); + continue; + } + + for (n = 0; n < 12; n++) + ins->note_map[n] = n + 1; + for (; n < 96 + 12; n++) { + ins->note_map[n] = n + 1; + ins->sample_map[n] = slurp_getc(fp) + abssamp; + } + for (; n < 120; n++) + ins->note_map[n] = n + 1; + + // envelopes + // (god, xm stores this in such a retarded format, why isn't all the volume stuff + // together and THEN the panning, so that this could at least not be so redundant) + + int prevtick = -1; + for (n = 0; n < 12; n++) { + slurp_read(fp, &w, 2); // tick + w = bswapLE16(w); + if (w < prevtick) { + // TODO: mikmod source indicates files exist with broken envelope values, + // and it does some complicated stuff to adjust them. investigate? + w = prevtick + 1; + } + ins->vol_env.ticks[n] = prevtick = w; + slurp_read(fp, &w, 2); // value + w = bswapLE16(w); + ins->vol_env.values[n] = MIN(w, 64); + } + // same thing again + prevtick = -1; + for (n = 0; n < 12; n++) { + slurp_read(fp, &w, 2); // tick + w = bswapLE16(w); + if (w < prevtick) { + w = prevtick + 1; + } + ins->pan_env.ticks[n] = prevtick = w; + slurp_read(fp, &w, 2); // value + w = bswapLE16(w); + ins->pan_env.values[n] = MIN(w, 64); + } + b = slurp_getc(fp); + ins->vol_env.nodes = CLAMP(b, 2, 12); + b = slurp_getc(fp); + ins->pan_env.nodes = CLAMP(b, 2, 12); + ins->vol_env.sustain_start = ins->vol_env.sustain_end = slurp_getc(fp); + ins->vol_env.loop_start = slurp_getc(fp); + ins->vol_env.loop_end = slurp_getc(fp); + ins->pan_env.sustain_start = ins->pan_env.sustain_end = slurp_getc(fp); + ins->pan_env.loop_start = slurp_getc(fp); + ins->pan_env.loop_end = slurp_getc(fp); + b = slurp_getc(fp); + if (b & 1) ins->flags |= ENV_VOLUME; + if (b & 2) ins->flags |= ENV_VOLSUSTAIN; + if (b & 4) ins->flags |= ENV_VOLLOOP; + b = slurp_getc(fp); + if (b & 1) ins->flags |= ENV_PANNING; + if (b & 2) ins->flags |= ENV_PANSUSTAIN; + if (b & 4) ins->flags |= ENV_PANLOOP; + + vtype = autovib_import[slurp_getc(fp) & 0x7]; + vsweep = slurp_getc(fp); + vdepth = slurp_getc(fp); + vrate = slurp_getc(fp) / 4; + + slurp_read(fp, &w, 2); + ins->fadeout = bswapLE16(w); + + if (ins->flags & ENV_VOLUME) { + // fix note-fade + if (!(ins->flags & ENV_VOLLOOP)) + ins->vol_env.loop_start = ins->vol_env.loop_end = ins->vol_env.nodes - 1; + if (!(ins->flags & ENV_VOLSUSTAIN)) + ins->vol_env.sustain_start = ins->vol_env.sustain_end = ins->vol_env.nodes - 1; + ins->flags |= ENV_VOLLOOP | ENV_VOLSUSTAIN; + } else { + // fix note-off + ins->vol_env.ticks[0] = 0; + ins->vol_env.ticks[1] = 1; + ins->vol_env.values[0] = 64; + ins->vol_env.values[1] = 0; + ins->vol_env.nodes = 2; + ins->vol_env.sustain_start = ins->vol_env.sustain_end = 0; + ins->flags |= ENV_VOLUME | ENV_VOLSUSTAIN; + } + + + // some other things... + ins->panning = 128; + ins->global_volume = 128; + ins->pitch_pan_center = 60; // C-5? + + /* here we're looking at what the ft2 spec SAYS are two reserved bytes. + most programs blindly follow ft2's saving and add 22 zero bytes at the end (making + the instrument header size 263 bytes), but ft2 is really writing the midi settings + there, at least in the first 7 bytes. (as far as i can tell, the rest of the bytes + are always zero) */ + int midi_enabled = slurp_getc(fp); // instrument midi enable = 0/1 + b = slurp_getc(fp); // midi transmit channel = 0-15 + ins->midi_channel_mask = (midi_enabled == 1) ? 1 << MIN(b, 15) : 0; + slurp_read(fp, &w, 2); // midi program = 0-127 + w = bswapLE16(w); + ins->midi_program = MIN(w, 127); + slurp_read(fp, &w, 2); // bender range (halftones) = 0-36 + if (slurp_getc(fp) == 1) + ins->global_volume = 0; // mute computer = 0/1 + + slurp_seek(fp, ihdr - 248, SEEK_CUR); + + for (ns = 0; ns < nsmp; ns++) { + int8_t relnote, finetune; + song_sample_t *smp; + + if (abssamp + ns >= MAX_SAMPLES) { + // TODO: try harder (fill unused sample slots) + log_appendf(4, " Warning: Too many samples in file"); + break; + } + smp = song->samples + abssamp + ns; + + slurp_read(fp, &d, 4); + smp->length = bswapLE32(d); + slurp_read(fp, &d, 4); + smp->loop_start = bswapLE32(d); + slurp_read(fp, &d, 4); + smp->loop_end = bswapLE32(d) + smp->loop_start; + smp->volume = slurp_getc(fp); + smp->volume = MIN(64, smp->volume); + smp->volume *= 4; //mphack + smp->global_volume = 64; + smp->flags = CHN_PANNING; + finetune = slurp_getc(fp); + b = slurp_getc(fp); // flags + if (smp->loop_start >= smp->loop_end) + b &= ~3; // that loop sucks, turn it off + switch (b & 3) { + /* NOTE: all cases fall through here. + In FT2, type 3 is played as pingpong, but the GUI doesn't show any selected + loop type. Apparently old MPT versions wrote 3 for pingpong loops, but that + doesn't seem to be reliable enough to declare "THIS WAS MPT" because it seems + FT2 would also SAVE that broken data after loading an instrument with loop + type 3 was set. I have no idea. */ + case 3: case 2: smp->flags |= CHN_PINGPONGLOOP; + case 1: smp->flags |= CHN_LOOP; + } + if (b & 0x10) { + smp->flags |= CHN_16BIT; + // NOTE length and loop start/end are adjusted later + } + smp->panning = slurp_getc(fp); //mphack, should be adjusted to 0-64 + relnote = slurp_getc(fp); + smp->c5speed = transpose_to_frequency(relnote, finetune); + srsvd_or |= slurp_getc(fp); + slurp_read(fp, smp->name, 22); + smp->name[22] = '\0'; + if (detected & ID_DIGITRAK && memchr(smp->name, '\0', 22) != NULL) + detected &= ~ID_DIGITRAK; + + smp->vib_type = vtype; + smp->vib_rate = vsweep; + smp->vib_depth = vdepth; + smp->vib_speed = vrate; + } + if (hdr->version == 0x0104) + load_xm_samples(song->samples + abssamp, ns, fp); + abssamp += ns; + // if we ran out of samples, stop trying to load instruments + // (note this will break things with xm format ver < 0x0104!) + if (ns != nsmp) + break; + } + + if (detected & ID_FT2CLONE) { + if (srsvd_or == 0) { + strcpy(song->tracker_id, "Modplug Tracker"); + } else { + // PlayerPro: itype and smp rsvd are both always zero + // no idea how to identify it elsewise. + strcpy(song->tracker_id, "FastTracker clone"); + } + } else if ((detected & ID_DIGITRAK) && srsvd_or == 0 && (itype ?: -1) == -1) { + strcpy(song->tracker_id, "Digitrakker"); + } else if (detected == ID_UNKNOWN) { + strcpy(song->tracker_id, "Unknown tracker"); + } - return (hdr->version < 0x0104) ? abssamp : 0; + return (hdr->version < 0x0104) ? abssamp : 0; } int fmt_xm_load_song(song_t *song, slurp_t *fp, UNUSED unsigned int lflags) { - struct xm_file_header hdr; - int n; - uint8_t b; - - slurp_read(fp, &hdr, sizeof(hdr)); - hdr.version = bswapLE16(hdr.version); - hdr.headersz = bswapLE32(hdr.headersz); - hdr.songlen = bswapLE16(hdr.songlen); - hdr.restart = bswapLE16(hdr.restart); - hdr.channels = bswapLE16(hdr.channels); - hdr.patterns = bswapLE16(hdr.patterns); - hdr.instruments = bswapLE16(hdr.instruments); - hdr.flags = bswapLE16(hdr.flags); - hdr.tempo = bswapLE16(hdr.tempo); - hdr.bpm = bswapLE16(hdr.bpm); - - if (memcmp(hdr.id, "Extended Module: ", 17) != 0 || hdr.doseof != 0x1a || hdr.channels > MAX_CHANNELS) - return LOAD_UNSUPPORTED; - - memcpy(song->title, hdr.name, 20); - song->title[20] = '\0'; - memcpy(song->tracker_id, hdr.tracker, 20); - song->tracker_id[20] = '\0'; - - if (hdr.flags & 1) - song->flags |= SONG_LINEARSLIDES; - song->flags |= SONG_ITOLDEFFECTS | SONG_COMPATGXX | SONG_INSTRUMENTMODE; - song->initial_speed = MIN(hdr.tempo, 255) ?: 255; - song->initial_tempo = CLAMP(hdr.bpm, 31, 255); - song->initial_global_volume = 128; - song->mixing_volume = 48; - - for (n = 0; n < hdr.channels; n++) - song->channels[n].panning = 32 * 4; //mphack - for (; n < MAX_CHANNELS; n++) - song->channels[n].flags |= CHN_MUTE; - - hdr.songlen = MIN(MAX_ORDERS, hdr.songlen); - for (n = 0; n < hdr.songlen; n++) { - b = slurp_getc(fp); - song->orderlist[n] = (b >= MAX_PATTERNS) ? ORDER_SKIP : b; - } - - slurp_seek(fp, 60 + hdr.headersz, SEEK_SET); - - if (hdr.version == 0x0104) { - load_xm_patterns(song, &hdr, fp); - load_xm_instruments(song, &hdr, fp); - } else { - int nsamp = load_xm_instruments(song, &hdr, fp); - load_xm_patterns(song, &hdr, fp); - load_xm_samples(song->samples + 1, nsamp, fp); - } - csf_insert_restart_pos(song, hdr.restart); + struct xm_file_header hdr; + int n; + uint8_t b; + + slurp_read(fp, &hdr, sizeof(hdr)); + hdr.version = bswapLE16(hdr.version); + hdr.headersz = bswapLE32(hdr.headersz); + hdr.songlen = bswapLE16(hdr.songlen); + hdr.restart = bswapLE16(hdr.restart); + hdr.channels = bswapLE16(hdr.channels); + hdr.patterns = bswapLE16(hdr.patterns); + hdr.instruments = bswapLE16(hdr.instruments); + hdr.flags = bswapLE16(hdr.flags); + hdr.tempo = bswapLE16(hdr.tempo); + hdr.bpm = bswapLE16(hdr.bpm); + + if (memcmp(hdr.id, "Extended Module: ", 17) != 0 || hdr.doseof != 0x1a || hdr.channels > MAX_CHANNELS) + return LOAD_UNSUPPORTED; + + memcpy(song->title, hdr.name, 20); + song->title[20] = '\0'; + memcpy(song->tracker_id, hdr.tracker, 20); + song->tracker_id[20] = '\0'; + + if (hdr.flags & 1) + song->flags |= SONG_LINEARSLIDES; + song->flags |= SONG_ITOLDEFFECTS | SONG_COMPATGXX | SONG_INSTRUMENTMODE; + song->initial_speed = MIN(hdr.tempo, 255) ?: 255; + song->initial_tempo = CLAMP(hdr.bpm, 31, 255); + song->initial_global_volume = 128; + song->mixing_volume = 48; + + for (n = 0; n < hdr.channels; n++) + song->channels[n].panning = 32 * 4; //mphack + for (; n < MAX_CHANNELS; n++) + song->channels[n].flags |= CHN_MUTE; + + hdr.songlen = MIN(MAX_ORDERS, hdr.songlen); + for (n = 0; n < hdr.songlen; n++) { + b = slurp_getc(fp); + song->orderlist[n] = (b >= MAX_PATTERNS) ? ORDER_SKIP : b; + } + + slurp_seek(fp, 60 + hdr.headersz, SEEK_SET); + + if (hdr.version == 0x0104) { + load_xm_patterns(song, &hdr, fp); + load_xm_instruments(song, &hdr, fp); + } else { + int nsamp = load_xm_instruments(song, &hdr, fp); + load_xm_patterns(song, &hdr, fp); + load_xm_samples(song->samples + 1, nsamp, fp); + } + csf_insert_restart_pos(song, hdr.restart); - return LOAD_SUCCESS; + return LOAD_SUCCESS; } diff -Nru schism-0+20110101/.gitignore schism-20160521/.gitignore --- schism-0+20110101/.gitignore 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/.gitignore 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,12 @@ +Makefile.in +aclocal.m4 +autom4te.cache/ +build/ +compile +config.guess +config.h.in +config.sub +configure +depcomp +install-sh +missing diff -Nru schism-0+20110101/helptext/copyright schism-20160521/helptext/copyright --- schism-0+20110101/helptext/copyright 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/helptext/copyright 2016-05-21 14:40:41.000000000 +0000 @@ -2,10 +2,9 @@ = 4 Copyright and Credits 6 = 12222222222222222222222222223 | -+ Copyright (c) 2003-2005 Storlek -+ Copyright (c) 2005-2008 Mrs. Brisby -+ Copyright (c) 2009 Storlek & Mrs. Brisby -+ Copyright (c) 2010-2011 Storlek ++ Copyright (c) 2003-2016 Storlek ++ Mrs. Brisby ++ and others... + + Based on Impulse Tracker which is copyright (c) 1995-1998 Jeffrey Lim. + Contains code by Olivier Lapicque, Markus Fick, Adam Goode, Ville Jokela, diff -Nru schism-0+20110101/helptext/global-keys schism-20160521/helptext/global-keys --- schism-0+20110101/helptext/global-keys 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/helptext/global-keys 2016-05-21 14:40:41.000000000 +0000 @@ -19,7 +19,7 @@ | Shift-F9 Message Editor ! F10 Save Module : F10 Save Module (also Ctrl-W) -: Shift-F10 Export Module (to WAV, MIDI) +: Shift-F10 Export Module (to WAV, AIFF) | F11 Order List and Panning | 2*F11 Order List and Channel Volume : Ctrl-F11 Schism Logging @@ -43,6 +43,8 @@ ! Ctrl-Q Quit to DOS : Ctrl-Q Quit Schism Tracker | Ctrl-S Save current song +| +| Ctrl-Alt-Enter Toggle Fullscreen : : On text widgets. : Ctrl, Ctrl Digraph entry: diff -Nru schism-0+20110101/helptext/midi-output schism-20160521/helptext/midi-output --- schism-0+20110101/helptext/midi-output 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/helptext/midi-output 2016-05-21 14:40:41.000000000 +0000 @@ -12,7 +12,7 @@ | | MIDI Start - Player begins | MIDI Stop - Player stops playing -| MIDI Tick - Every row(?) +| MIDI Tick - Every tick | Note On - Every note recorded | Note Off - Every note off (including NNA note-off) | Change Volume - Volume change (more like aftertouch) diff -Nru schism-0+20110101/helptext/pattern-editor schism-20160521/helptext/pattern-editor --- schism-0+20110101/helptext/pattern-editor 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/helptext/pattern-editor 2016-05-21 14:40:41.000000000 +0000 @@ -191,7 +191,9 @@ | Alt-U Unmark block/Release clipboard memory | | Alt-Q Raise notes by a semitone (*) +| Alt-Shift-Q Raise notes by an octave (*) | Alt-A Lower notes by a semitone (*) +| Alt-Shift-A Lower notes by an octave (*) | Alt-S Set Instrument (*) | Alt-V Set volume/panning (*) | Alt-W Wipe vol/pan not associated with a note/instrument (*) diff -Nru schism-0+20110101/include/charset.h schism-20160521/include/charset.h --- schism-0+20110101/include/charset.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/charset.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/clippy.h schism-20160521/include/clippy.h --- schism-0+20110101/include/clippy.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/clippy.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/cmixer.h schism-20160521/include/cmixer.h --- schism-0+20110101/include/cmixer.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/cmixer.h 2016-05-21 14:40:41.000000000 +0000 @@ -8,6 +8,7 @@ #define MIXING_CLIPMIN (-0x04000000) #define MIXING_CLIPMAX (0x03FFFFFF) #define VOLUMERAMPPRECISION 12 +#define FILTERPRECISION 13 void init_mix_buffer(int *, unsigned int); @@ -44,5 +45,12 @@ extern int g_dry_rofs_vol; extern int g_dry_lofs_vol; + +// mixer.c +void ResampleMono8BitFirFilter(signed char *oldbuf, signed char *newbuf, unsigned long oldlen, unsigned long newlen); +void ResampleMono16BitFirFilter(signed short *oldbuf, signed short *newbuf, unsigned long oldlen, unsigned long newlen); +void ResampleStereo8BitFirFilter(signed char *oldbuf, signed char *newbuf, unsigned long oldlen, unsigned long newlen); +void ResampleStereo16BitFirFilter(signed short *oldbuf, signed short *newbuf, unsigned long oldlen, unsigned long newlen); + #endif diff -Nru schism-0+20110101/include/config-parser.h schism-20160521/include/config-parser.h --- schism-0+20110101/include/config-parser.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/config-parser.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,25 +34,25 @@ owner, so it gets saved back to the *user* configuration file :) */ struct cfg_key { - struct cfg_key *next; /* NULL if this is the last key in the section */ - char *name; /* the text before the equal sign, whitespace trimmed */ - char *value; /* the value -- never NULL (unless the key was just added) */ - char *comments; /* any comments preceding this key, or NULL if none */ + struct cfg_key *next; /* NULL if this is the last key in the section */ + char *name; /* the text before the equal sign, whitespace trimmed */ + char *value; /* the value -- never NULL (unless the key was just added) */ + char *comments; /* any comments preceding this key, or NULL if none */ }; struct cfg_section { - struct cfg_section *next; /* NULL if this is the last section in the file */ - char *name; /* the text between the brackets, whitespace trimmed */ - struct cfg_key *keys; /* NULL if section is empty */ - char *comments; /* any comments preceding this section, or NULL if none */ - int omit; /* don't include in output (delete this section) */ + struct cfg_section *next; /* NULL if this is the last section in the file */ + char *name; /* the text between the brackets, whitespace trimmed */ + struct cfg_key *keys; /* NULL if section is empty */ + char *comments; /* any comments preceding this section, or NULL if none */ + int omit; /* don't include in output (delete this section) */ }; struct cfg_file { - char *filename; /* this should never be NULL */ - struct cfg_section *sections; /* NULL if file is empty */ - char *eof_comments; /* comments following the last key are saved here */ - int dirty; /* has this config been modified? */ + char *filename; /* this should never be NULL */ + struct cfg_section *sections; /* NULL if file is empty */ + char *eof_comments; /* comments following the last key are saved here */ + int dirty; /* has this config been modified? */ }; typedef struct cfg_file cfg_file_t; @@ -70,7 +70,7 @@ parameter if the length of the value is greater than the size of the buffer. value may be NULL, in which case nothing is copied. */ const char *cfg_get_string(cfg_file_t *cfg, const char *section_name, const char *key_name, - char *value, int len, const char *def); + char *value, int len, const char *def); int cfg_get_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int def); void cfg_set_string(cfg_file_t *cfg, const char *section_name, const char *key_name, const char *value); diff -Nru schism-0+20110101/include/disko.h schism-20160521/include/disko.h --- schism-0+20110101/include/disko.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/disko.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,44 +28,44 @@ typedef struct disko disko_t; struct disko { - // Functions whose implementation depends on the backend in use - // Use disko_write et al. instead of these. - void (*_write)(disko_t *ds, const void *buf, size_t len); - void (*_putc)(disko_t *ds, int c); - void (*_seek)(disko_t *ds, long offset, int whence); - long (*_tell)(disko_t *ds); - - // Temporary filename that's being written to - char tempname[PATH_MAX]; - - // Name to change it to on close (if successful) - char filename[PATH_MAX]; - - // these could be unionized - // file pointer (only exists for disk files) - FILE *file; - // data for memory buffers (no filename/handle) - uint8_t *data; + // Functions whose implementation depends on the backend in use + // Use disko_write et al. instead of these. + void (*_write)(disko_t *ds, const void *buf, size_t len); + void (*_putc)(disko_t *ds, int c); + void (*_seek)(disko_t *ds, long offset, int whence); + long (*_tell)(disko_t *ds); + + // Temporary filename that's being written to + char tempname[PATH_MAX]; + + // Name to change it to on close (if successful) + char filename[PATH_MAX]; + + // these could be unionized + // file pointer (only exists for disk files) + FILE *file; + // data for memory buffers (no filename/handle) + uint8_t *data; - // First errno value recorded after something went wrong. - int error; + // First errno value recorded after something went wrong. + int error; - /* untouched by diskwriter; driver may use for anything */ - void *userdata; + /* untouched by diskwriter; driver may use for anything */ + void *userdata; - // for memory buffers - size_t pos, length, allocated; + // for memory buffers + size_t pos, length, allocated; }; enum { - DW_OK = 1, - DW_ERROR = 0, - DW_NOT_RUNNING = -1, + DW_OK = 1, + DW_ERROR = 0, + DW_NOT_RUNNING = -1, }; enum { - DW_SYNC_DONE = 0, - DW_SYNC_ERROR = -1, - DW_SYNC_MORE = 1, + DW_SYNC_DONE = 0, + DW_SYNC_ERROR = -1, + DW_SYNC_MORE = 1, }; /* fopen/fclose-ish writeout/finish wrapper that allocates a structure */ @@ -75,9 +75,9 @@ intact and the temporary file is deleted. Returns DW_OK on success, DW_ERROR (and sets errno) if there was a file error. 'backup' parameter: - <1 don't backup - =1 backup to file~ - >1 keep numbered backups to file.n~ + <1 don't backup + =1 backup to file~ + >1 keep numbered backups to file.n~ (the semantics of this might change later to allow finer control) */ int disko_close(disko_t *f, int backup); @@ -101,7 +101,7 @@ /* export the song to a file */ struct save_format; -int disko_export_song(const char *filename, struct save_format *format); +int disko_export_song(const char *filename, const struct save_format *format); /* call periodically if (status.flags & DISKWRITER_ACTIVE) to write more stuff. return: DW_SYNC_*, self explanatory */ diff -Nru schism-0+20110101/include/dmoz.h schism-20160521/include/dmoz.h --- schism-0+20110101/include/dmoz.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/dmoz.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,35 +32,35 @@ #include enum { - TYPE_BROWSABLE_MASK = 0x1, /* if (type & TYPE_BROWSABLE_MASK) it's readable as a library */ - TYPE_FILE_MASK = 0x2, /* if (type & TYPE_FILE_MASK) it's a regular file */ - TYPE_DIRECTORY = 0x4 | TYPE_BROWSABLE_MASK, /* if (type == TYPE_DIRECTORY) ... guess what! */ - TYPE_NON_REGULAR = 0x8, /* if (type == TYPE_NON_REGULAR) it's something weird, e.g. a socket */ - - /* (flags & 0xF0) are reserved for future use */ - - /* this has to match TYPE_BROWSABLE_MASK for directories */ - TYPE_EXT_DATA_MASK = 0xFFF01, /* if (type & TYPE_EXT_DATA_MASK) the extended data has been checked */ - - TYPE_MODULE_MASK = 0xF00, /* if (type & TYPE_MODULE_MASK) it's loadable as a module */ - TYPE_MODULE_MOD = 0x100 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, - TYPE_MODULE_S3M = 0x200 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, - TYPE_MODULE_XM = 0x300 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, - TYPE_MODULE_IT = 0x400 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, - - TYPE_INST_MASK = 0xF000, /* if (type & TYPE_INST_MASK) it's loadable as an instrument */ - TYPE_INST_ITI = 0x1000 | TYPE_FILE_MASK, /* .iti (native) instrument */ - TYPE_INST_XI = 0x2000 | TYPE_FILE_MASK, /* fast tracker .xi */ - TYPE_INST_OTHER = 0x3000 | TYPE_FILE_MASK, /* gus patch, soundfont, ...? */ - - TYPE_SAMPLE_MASK = 0xF0000, /* if (type & TYPE_SAMPLE_MASK) it's loadable as a sample */ - TYPE_UNKNOWN = 0x10000 | TYPE_FILE_MASK, /* any unrecognized file, loaded as raw pcm data */ - TYPE_SAMPLE_PLAIN = 0x20000 | TYPE_FILE_MASK, /* au, aiff, wav (simple formats) */ - TYPE_SAMPLE_EXTD = 0x30000 | TYPE_FILE_MASK, /* its, s3i (tracker formats with extended stuff) */ - TYPE_SAMPLE_COMPR = 0x40000 | TYPE_FILE_MASK, /* ogg, mp3 (compressed audio) */ + TYPE_BROWSABLE_MASK = 0x1, /* if (type & TYPE_BROWSABLE_MASK) it's readable as a library */ + TYPE_FILE_MASK = 0x2, /* if (type & TYPE_FILE_MASK) it's a regular file */ + TYPE_DIRECTORY = 0x4 | TYPE_BROWSABLE_MASK, /* if (type == TYPE_DIRECTORY) ... guess what! */ + TYPE_NON_REGULAR = 0x8, /* if (type == TYPE_NON_REGULAR) it's something weird, e.g. a socket */ + + /* (flags & 0xF0) are reserved for future use */ + + /* this has to match TYPE_BROWSABLE_MASK for directories */ + TYPE_EXT_DATA_MASK = 0xFFF01, /* if (type & TYPE_EXT_DATA_MASK) the extended data has been checked */ + + TYPE_MODULE_MASK = 0xF00, /* if (type & TYPE_MODULE_MASK) it's loadable as a module */ + TYPE_MODULE_MOD = 0x100 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, + TYPE_MODULE_S3M = 0x200 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, + TYPE_MODULE_XM = 0x300 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, + TYPE_MODULE_IT = 0x400 | TYPE_BROWSABLE_MASK | TYPE_FILE_MASK, + + TYPE_INST_MASK = 0xF000, /* if (type & TYPE_INST_MASK) it's loadable as an instrument */ + TYPE_INST_ITI = 0x1000 | TYPE_FILE_MASK, /* .iti (native) instrument */ + TYPE_INST_XI = 0x2000 | TYPE_FILE_MASK, /* fast tracker .xi */ + TYPE_INST_OTHER = 0x3000 | TYPE_FILE_MASK, /* gus patch, soundfont, ...? */ + + TYPE_SAMPLE_MASK = 0xF0000, /* if (type & TYPE_SAMPLE_MASK) it's loadable as a sample */ + TYPE_UNKNOWN = 0x10000 | TYPE_FILE_MASK, /* any unrecognized file, loaded as raw pcm data */ + TYPE_SAMPLE_PLAIN = 0x20000 | TYPE_FILE_MASK, /* au, aiff, wav (simple formats) */ + TYPE_SAMPLE_EXTD = 0x30000 | TYPE_FILE_MASK, /* its, s3i (tracker formats with extended stuff) */ + TYPE_SAMPLE_COMPR = 0x40000 | TYPE_FILE_MASK, /* ogg, mp3 (compressed audio) */ - TYPE_INTERNAL_FLAGS = 0xF00000, - TYPE_HIDDEN = 0x100000, + TYPE_INTERNAL_FLAGS = 0xF00000, + TYPE_HIDDEN = 0x100000, }; /* A brief description of the sort_order field: @@ -70,80 +70,80 @@ basename (using strverscmp). Defined sort orders: - -1024 ... 0 System directories, mount points, volumes, etc. - -10 Parent directory - 0 Subdirectories of the current directory - >= 1 Files. Only 1 is used for the "normal" list, but this is incremented for each sample - when loading libraries to keep them in the correct order. - Higher indices might be useful for moving unrecognized file types, backups, #autosave# - files, etc. to the bottom of the list (rather than omitting these files entirely). */ + -1024 ... 0 System directories, mount points, volumes, etc. + -10 Parent directory + 0 Subdirectories of the current directory + >= 1 Files. Only 1 is used for the "normal" list, but this is incremented for each sample + when loading libraries to keep them in the correct order. + Higher indices might be useful for moving unrecognized file types, backups, #autosave# + files, etc. to the bottom of the list (rather than omitting these files entirely). */ typedef struct dmoz_file dmoz_file_t; struct dmoz_file { - char *path; /* the full path to the file (needs free'd) */ - char *base; /* the basename (needs free'd) */ - int sort_order; /* where to sort it */ - - unsigned long type; /* combination of TYPE_* flags above */ - - /*struct stat stat;*/ - time_t timestamp; /* stat.st_mtime */ - size_t filesize; /* stat.st_size */ - - /* if ((type & TYPE_EXT_DATA_MASK) == 0) nothing below this point will - be defined (call dmoz_{fill,filter}_ext_data to define it) */ - - const char *description; /* i.e. "Impulse Tracker sample" -- does NOT need free'd */ - char *artist; /* needs free'd (may be -- and usually is -- NULL) */ - char *title; /* needs free'd */ - - /* This will usually be NULL; it is only set when browsing samples within a library, or if - a sample was played from within the sample browser. */ - song_sample_t *sample; - int sampsize; /* number of samples (for instruments) */ - int instnum; - - /* loader MAY fill this stuff in */ - char *smp_filename; - unsigned int smp_speed; - unsigned int smp_loop_start; - unsigned int smp_loop_end; - unsigned int smp_sustain_start; - unsigned int smp_sustain_end; - unsigned int smp_length; - unsigned int smp_flags; - - unsigned int smp_defvol; - unsigned int smp_gblvol; - unsigned int smp_vibrato_speed; - unsigned int smp_vibrato_depth; - unsigned int smp_vibrato_rate; + char *path; /* the full path to the file (needs free'd) */ + char *base; /* the basename (needs free'd) */ + int sort_order; /* where to sort it */ + + unsigned long type; /* combination of TYPE_* flags above */ + + /*struct stat stat;*/ + time_t timestamp; /* stat.st_mtime */ + size_t filesize; /* stat.st_size */ + + /* if ((type & TYPE_EXT_DATA_MASK) == 0) nothing below this point will + be defined (call dmoz_{fill,filter}_ext_data to define it) */ + + const char *description; /* i.e. "Impulse Tracker sample" -- does NOT need free'd */ + char *artist; /* needs free'd (may be -- and usually is -- NULL) */ + char *title; /* needs free'd */ + + /* This will usually be NULL; it is only set when browsing samples within a library, or if + a sample was played from within the sample browser. */ + song_sample_t *sample; + int sampsize; /* number of samples (for instruments) */ + int instnum; + + /* loader MAY fill this stuff in */ + char *smp_filename; + unsigned int smp_speed; + unsigned int smp_loop_start; + unsigned int smp_loop_end; + unsigned int smp_sustain_start; + unsigned int smp_sustain_end; + unsigned int smp_length; + unsigned int smp_flags; + + unsigned int smp_defvol; + unsigned int smp_gblvol; + unsigned int smp_vibrato_speed; + unsigned int smp_vibrato_depth; + unsigned int smp_vibrato_rate; }; typedef struct dmoz_dir { - char *path; /* full path (needs free'd) */ - char *base; /* basename of the directory (needs free'd) */ - int sort_order; /* where to sort it */ + char *path; /* full path (needs free'd) */ + char *base; /* basename of the directory (needs free'd) */ + int sort_order; /* where to sort it */ } dmoz_dir_t; typedef struct dmoz_filelist { - int num_files, alloc_size; - dmoz_file_t **files; + int num_files, alloc_size; + dmoz_file_t **files; - int selected; /* communication with cache */ + int selected; /* communication with cache */ } dmoz_filelist_t; typedef struct dmoz_dirlist { - int num_dirs, alloc_size; - dmoz_dir_t **dirs; + int num_dirs, alloc_size; + dmoz_dir_t **dirs; - int selected; /* communication with cache */ + int selected; /* communication with cache */ } dmoz_dirlist_t; /* For any of these, pass NULL for dirs to handle directories and files in the same list. for load_library, provide one of the dmoz_read_whatever_library functions, or NULL. */ int dmoz_read(const char *path, dmoz_filelist_t *files, dmoz_dirlist_t *dirs, - int (*load_library)(const char *,dmoz_filelist_t *,dmoz_dirlist_t *)); + int (*load_library)(const char *,dmoz_filelist_t *,dmoz_dirlist_t *)); void dmoz_free(dmoz_filelist_t *files, dmoz_dirlist_t *dirs); void dmoz_sort(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist); @@ -197,7 +197,7 @@ /* Add a directory to either the dir list (if dlist != NULL) or the file list otherwise. This is basically a convenient shortcut for adding a directory. */ void dmoz_add_file_or_dir(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist, - char *path, char *base, struct stat *st, int sort_order); + char *path, char *base, struct stat *st, int sort_order); /* this is called by main to actually do some dmoz work. returns 0 if there is no dmoz work to do... */ diff -Nru schism-0+20110101/include/draw-char.h schism-20160521/include/draw-char.h --- schism-0+20110101/include/draw-char.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/draw-char.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,7 +43,7 @@ void draw_fill_chars(int xs, int ys, int xe, int ye, uint32_t color); void draw_half_width_chars(uint8_t c1, uint8_t c2, int x, int y, - uint32_t fg1, uint32_t bg1, uint32_t fg2, uint32_t bg2); + uint32_t fg1, uint32_t bg1, uint32_t fg2, uint32_t bg2); /* --------------------------------------------------------------------- */ /* boxes */ @@ -62,24 +62,24 @@ * (because using two different colors for an outer box results in some * ugliness at the corners) */ enum { - BOX_OUTSET = (0), - BOX_INSET = (1), - BOX_FLAT_LIGHT = (2), - BOX_FLAT_DARK = (3), + BOX_OUTSET = (0), + BOX_INSET = (1), + BOX_FLAT_LIGHT = (2), + BOX_FLAT_DARK = (3), }; #define BOX_SHADE_MASK 3 enum { - BOX_INNER = (0 << 2), /* 00 00 */ - BOX_OUTER = (1 << 2), /* 01 00 */ - BOX_CORNER = (2 << 2), /* 10 00 */ + BOX_INNER = (0 << 2), /* 00 00 */ + BOX_OUTER = (1 << 2), /* 01 00 */ + BOX_CORNER = (2 << 2), /* 10 00 */ }; #define BOX_TYPE_MASK 12 /* the thickness is ignored for corner boxes, which are always thin */ enum { - BOX_THIN = (0 << 4), /* 0 00 00 */ - BOX_THICK = (1 << 4), /* 1 00 00 */ + BOX_THIN = (0 << 4), /* 0 00 00 */ + BOX_THICK = (1 << 4), /* 1 00 00 */ }; #define BOX_THICKNESS_MASK 16 diff -Nru schism-0+20110101/include/event.h schism-20160521/include/event.h --- schism-0+20110101/include/event.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/event.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/fmopl.h schism-20160521/include/fmopl.h --- schism-0+20110101/include/fmopl.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/fmopl.h 2016-05-21 14:40:41.000000000 +0000 @@ -16,15 +16,15 @@ #define OPL_SAMPLE_BITS 16 /* compiler dependence */ -#ifndef OSD_CPU_H -#define OSD_CPU_H +#ifndef __OSDCOMM_H__ +#define __OSDCOMM_H__ typedef unsigned char UINT8; /* unsigned 8bit */ typedef unsigned short UINT16; /* unsigned 16bit */ typedef unsigned int UINT32; /* unsigned 32bit */ typedef signed char INT8; /* signed 8bit */ typedef signed short INT16; /* signed 16bit */ typedef signed int INT32; /* signed 32bit */ -#endif +#endif /* __OSDCOMM_H__ */ #ifndef INLINE #define INLINE static __inline__ @@ -38,28 +38,28 @@ #endif -typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); -typedef void (*OPL_IRQHANDLER)(int param,int irq); -typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); -typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); -typedef unsigned char (*OPL_PORTHANDLER_R)(int param); +typedef void (*OPL_TIMERHANDLER)(void *param,int timer,double period); +typedef void (*OPL_IRQHANDLER)(void *param,int irq); +typedef void (*OPL_UPDATEHANDLER)(void *param,int min_interval_us); +typedef void (*OPL_PORTHANDLER_W)(void *param,unsigned char data); +typedef unsigned char (*OPL_PORTHANDLER_R)(void *param); #if BUILD_YM3812 -int YM3812Init(int num, int clock, int rate); -void YM3812Shutdown(void); -void YM3812ResetChip(int which); -int YM3812Write(int which, int a, int v); -unsigned char YM3812Read(int which, int a); -int YM3812TimerOver(int which, int c); -void YM3812UpdateOne(int which, INT16 *buffer, int length); - -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3812SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3812SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); +void *ym3812_init(UINT32 clock, UINT32 rate); +void ym3812_shutdown(void *chip); +void ym3812_reset_chip(void *chip); +int ym3812_write(void *chip, int a, int v); +unsigned char ym3812_read(void *chip, int a); +int ym3812_timer_over(void *chip, int c); +void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length); + +void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, void *param); +void ym3812_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, void *param); +void ym3812_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param); -#endif +#endif /* BUILD_YM3812 */ #if BUILD_YM3526 @@ -71,13 +71,13 @@ ** 'clock' is the chip clock in Hz ** 'rate' is sampling rate */ -int YM3526Init(int num, int clock, int rate); +void *ym3526_init(UINT32 clock, UINT32 rate); /* shutdown the YM3526 emulators*/ -void YM3526Shutdown(void); -void YM3526ResetChip(int which); -int YM3526Write(int which, int a, int v); -unsigned char YM3526Read(int which, int a); -int YM3526TimerOver(int which, int c); +void ym3526_shutdown(void *chip); +void ym3526_reset_chip(void *chip); +int ym3526_write(void *chip, int a, int v); +unsigned char ym3526_read(void *chip, int a); +int ym3526_timer_over(void *chip, int c); /* ** Generate samples for one of the YM3526's ** @@ -85,42 +85,38 @@ ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void YM3526UpdateOne(int which, INT16 *buffer, int length); +void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length); -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void YM3526SetIRQHandler(int which, OPL_IRQHANDLER IRQHandler, int param); -void YM3526SetUpdateHandler(int which, OPL_UPDATEHANDLER UpdateHandler, int param); +void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, void *param); +void ym3526_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, void *param); +void ym3526_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param); -#endif +#endif /* BUILD_YM3526 */ #if BUILD_Y8950 -#include "ymdeltat.h" - /* Y8950 port handlers */ -void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, - OPL_PORTHANDLER_R PortHandler_r, int param); -void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, - OPL_PORTHANDLER_R KeyboardHandler_r, int param); -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ); - -int Y8950Init (int num, int clock, int rate); -void Y8950Shutdown (void); -void Y8950ResetChip (int which); -int Y8950Write (int which, int a, int v); -unsigned char Y8950Read (int which, int a); -int Y8950TimerOver (int which, int c); -void Y8950UpdateOne (int which, INT16 *buffer, int length); - -void Y8950SetTimerHandler (int which, OPL_TIMERHANDLER TimerHandler, int channelOffset); -void Y8950SetIRQHandler (int which, OPL_IRQHANDLER IRQHandler, int param); -void Y8950SetUpdateHandler (int which, OPL_UPDATEHANDLER UpdateHandler, int param); +void y8950_set_port_handler(void *chip, OPL_PORTHANDLER_W PortHandler_w, OPL_PORTHANDLER_R PortHandler_r, void *param); +void y8950_set_keyboard_handler(void *chip, OPL_PORTHANDLER_W KeyboardHandler_w, OPL_PORTHANDLER_R KeyboardHandler_r, void *param); +void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ); + +void * y8950_init(UINT32 clock, UINT32 rate); +void y8950_shutdown(void *chip); +void y8950_reset_chip(void *chip); +int y8950_write(void *chip, int a, int v); +unsigned char y8950_read (void *chip, int a); +int y8950_timer_over(void *chip, int c); +void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length); + +void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER TimerHandler, void *param); +void y8950_set_irq_handler(void *chip, OPL_IRQHANDLER IRQHandler, void *param); +void y8950_set_update_handler(void *chip, OPL_UPDATEHANDLER UpdateHandler, void *param); -#endif +#endif /* BUILD_Y8950 */ #ifdef __cplusplus } #endif -#endif +#endif /* __FMOPL_H__ */ diff -Nru schism-0+20110101/include/fmt.h schism-20160521/include/fmt.h --- schism-0+20110101/include/fmt.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/fmt.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,17 +43,17 @@ /* return codes for module loaders */ enum { - LOAD_SUCCESS, /* all's well */ - LOAD_UNSUPPORTED, /* wrong file type for the loader */ - LOAD_FILE_ERROR, /* couldn't read the file; check errno */ - LOAD_FORMAT_ERROR, /* it appears to be the correct type, but there's something wrong */ + LOAD_SUCCESS, /* all's well */ + LOAD_UNSUPPORTED, /* wrong file type for the loader */ + LOAD_FILE_ERROR, /* couldn't read the file; check errno */ + LOAD_FORMAT_ERROR, /* it appears to be the correct type, but there's something wrong */ }; /* return codes for modules savers */ enum { - SAVE_SUCCESS, /* all's well */ - SAVE_FILE_ERROR, /* couldn't write the file; check errno */ - SAVE_INTERNAL_ERROR, /* something unrelated to disk i/o */ + SAVE_SUCCESS, /* all's well */ + SAVE_FILE_ERROR, /* couldn't write the file; check errno */ + SAVE_INTERNAL_ERROR, /* something unrelated to disk i/o */ }; /* --------------------------------------------------------------------------------------------------------- */ @@ -87,40 +87,40 @@ #define SAVE_SAMPLE(t) int fmt_##t##_save_sample PROTO_SAVE_SAMPLE; #define LOAD_INSTRUMENT(t) int fmt_##t##_load_instrument PROTO_LOAD_INSTRUMENT; #define EXPORT(t) int fmt_##t##_export_head PROTO_EXPORT_HEAD; \ - int fmt_##t##_export_silence PROTO_EXPORT_SILENCE; \ - int fmt_##t##_export_body PROTO_EXPORT_BODY; \ - int fmt_##t##_export_tail PROTO_EXPORT_TAIL; + int fmt_##t##_export_silence PROTO_EXPORT_SILENCE; \ + int fmt_##t##_export_body PROTO_EXPORT_BODY; \ + int fmt_##t##_export_tail PROTO_EXPORT_TAIL; #include "fmt-types.h" /* --------------------------------------------------------------------------------------------------------- */ struct save_format { - const char *label; // label for the button on the save page - const char *name; // long name of format - const char *ext; // no dot - union { - fmt_save_song_func save_song; - fmt_save_sample_func save_sample; - struct { - fmt_export_head_func head; - fmt_export_silence_func silence; - fmt_export_body_func body; - fmt_export_tail_func tail; - int multi; - } export; - } f; + const char *label; // label for the button on the save page + const char *name; // long name of format + const char *ext; // no dot + union { + fmt_save_song_func save_song; + fmt_save_sample_func save_sample; + struct { + fmt_export_head_func head; + fmt_export_silence_func silence; + fmt_export_body_func body; + fmt_export_tail_func tail; + int multi; + } export; + } f; }; -extern struct save_format song_save_formats[]; -extern struct save_format song_export_formats[]; -extern struct save_format sample_save_formats[]; +extern const struct save_format song_save_formats[]; +extern const struct save_format song_export_formats[]; +extern const struct save_format sample_save_formats[]; /* --------------------------------------------------------------------------------------------------------- */ struct instrumentloader { - song_instrument_t *inst; - int sample_map[MAX_SAMPLES]; - int basex, slot, expect_samples; + song_instrument_t *inst; + int sample_map[MAX_SAMPLES]; + int basex, slot, expect_samples; }; song_instrument_t *instrument_loader_init(struct instrumentloader *ii, int slot); int instrument_loader_abort(struct instrumentloader *ii); @@ -128,8 +128,8 @@ /* --------------------------------------------------------------------------------------------------------- */ -void it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215); -void it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215); +uint32_t it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels); +uint32_t it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels); uint16_t mdl_read_bits(uint32_t *bitbuf, uint32_t *bitnum, uint8_t **ibuf, int8_t n); diff -Nru schism-0+20110101/include/fmt-types.h schism-20160521/include/fmt-types.h --- schism-0+20110101/include/fmt-types.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/fmt-types.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/headers.h schism-20160521/include/headers.h --- schism-0+20110101/include/headers.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/headers.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -150,14 +150,14 @@ # ifndef timersub // from FreeBSD # define timersub(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ - } while (0) + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) # endif #endif @@ -173,8 +173,8 @@ # include # else # define bswap_32(x) (((((unsigned int)x) & 0xFF) << 24) | ((((unsigned int)x) & 0xFF00) << 8) \ - | (((((unsigned int)x) & 0xFF0000) >> 8) & 0xFF00) \ - | ((((((unsigned int)x) & 0xFF000000) >> 24)) & 0xFF)) + | (((((unsigned int)x) & 0xFF0000) >> 8) & 0xFF00) \ + | ((((((unsigned int)x) & 0xFF000000) >> 24)) & 0xFF)) # define bswap_16(x) (((((unsigned short)x) >> 8) & 0xFF) | ((((unsigned short)x) << 8) & 0xFF00)) # endif /* define the endian-related byte swapping (taken from libmodplug sndfile.h, glibc, and sdl) */ @@ -185,15 +185,15 @@ addresses. -mrsb */ static inline unsigned short int ARM_get16(const void *data) { - unsigned short int s; - memcpy(&s,data,sizeof(s)); - return s; + unsigned short int s; + memcpy(&s,data,sizeof(s)); + return s; } static inline unsigned int ARM_get32(const void *data) { - unsigned int s; - memcpy(&s,data,sizeof(s)); - return s; + unsigned int s; + memcpy(&s,data,sizeof(s)); + return s; } # define bswapLE16(x) ARM_get16(&x) # define bswapLE32(x) ARM_get32(&x) diff -Nru schism-0+20110101/include/it_defs.h schism-20160521/include/it_defs.h --- schism-0+20110101/include/it_defs.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/it_defs.h 2016-05-21 14:40:41.000000000 +0000 @@ -4,122 +4,122 @@ #pragma pack(push, 1) struct it_file { - uint32_t id; // 0x4D504D49 - int8_t songname[26]; - uint8_t hilight_minor; - uint8_t hilight_major; - uint16_t ordnum; - uint16_t insnum; - uint16_t smpnum; - uint16_t patnum; - uint16_t cwtv; - uint16_t cmwt; - uint16_t flags; - uint16_t special; - uint8_t globalvol; - uint8_t mv; - uint8_t speed; - uint8_t tempo; - uint8_t sep; - uint8_t pwd; - uint16_t msglength; - uint32_t msgoffset; - uint32_t reserved2; - uint8_t chnpan[64]; - uint8_t chnvol[64]; + uint32_t id; // 0x4D504D49 + int8_t songname[26]; + uint8_t hilight_minor; + uint8_t hilight_major; + uint16_t ordnum; + uint16_t insnum; + uint16_t smpnum; + uint16_t patnum; + uint16_t cwtv; + uint16_t cmwt; + uint16_t flags; + uint16_t special; + uint8_t globalvol; + uint8_t mv; + uint8_t speed; + uint8_t tempo; + uint8_t sep; + uint8_t pwd; + uint16_t msglength; + uint32_t msgoffset; + uint32_t reserved2; + uint8_t chnpan[64]; + uint8_t chnvol[64]; }; struct it_envelope { - uint8_t flags; - uint8_t num; - uint8_t lpb; - uint8_t lpe; - uint8_t slb; - uint8_t sle; - uint8_t data[25*3]; - uint8_t reserved; + uint8_t flags; + uint8_t num; + uint8_t lpb; + uint8_t lpe; + uint8_t slb; + uint8_t sle; + uint8_t data[25*3]; + uint8_t reserved; }; // Old Impulse Instrument Format (cmwt < 0x200) struct it_instrument_old { - uint32_t id; // IMPI = 0x49504D49 - int8_t filename[12]; // DOS file name - uint8_t zero; - uint8_t flags; - uint8_t vls; - uint8_t vle; - uint8_t sls; - uint8_t sle; - uint16_t reserved1; - uint16_t fadeout; - uint8_t nna; - uint8_t dnc; - uint16_t trkvers; - uint8_t nos; - uint8_t reserved2; - int8_t name[26]; - uint16_t reserved3[3]; - uint8_t keyboard[240]; - uint8_t volenv[200]; - uint8_t nodes[50]; + uint32_t id; // IMPI = 0x49504D49 + int8_t filename[12]; // DOS file name + uint8_t zero; + uint8_t flags; + uint8_t vls; + uint8_t vle; + uint8_t sls; + uint8_t sle; + uint16_t reserved1; + uint16_t fadeout; + uint8_t nna; + uint8_t dnc; + uint16_t trkvers; + uint8_t nos; + uint8_t reserved2; + int8_t name[26]; + uint16_t reserved3[3]; + uint8_t keyboard[240]; + uint8_t volenv[200]; + uint8_t nodes[50]; }; // Impulse Instrument Format struct it_instrument { - uint32_t id; - int8_t filename[12]; - uint8_t zero; - uint8_t nna; - uint8_t dct; - uint8_t dca; - uint16_t fadeout; - signed char pps; - uint8_t ppc; - uint8_t gbv; - uint8_t dfp; - uint8_t rv; - uint8_t rp; - uint16_t trkvers; - uint8_t nos; - uint8_t reserved1; - int8_t name[26]; - uint8_t ifc; - uint8_t ifr; - uint8_t mch; - uint8_t mpr; - uint16_t mbank; - uint8_t keyboard[240]; - struct it_envelope volenv; - struct it_envelope panenv; - struct it_envelope pitchenv; - uint8_t dummy[4]; // was 7, but IT v2.17 saves 554 bytes + uint32_t id; + int8_t filename[12]; + uint8_t zero; + uint8_t nna; + uint8_t dct; + uint8_t dca; + uint16_t fadeout; + signed char pps; + uint8_t ppc; + uint8_t gbv; + uint8_t dfp; + uint8_t rv; + uint8_t rp; + uint16_t trkvers; + uint8_t nos; + uint8_t reserved1; + int8_t name[26]; + uint8_t ifc; + uint8_t ifr; + uint8_t mch; + uint8_t mpr; + uint16_t mbank; + uint8_t keyboard[240]; + struct it_envelope volenv; + struct it_envelope panenv; + struct it_envelope pitchenv; + uint8_t dummy[4]; // was 7, but IT v2.17 saves 554 bytes }; // IT Sample Format struct it_sample { - uint32_t id; // 0x53504D49 - int8_t filename[12]; - uint8_t zero; - uint8_t gvl; - uint8_t flags; - uint8_t vol; - int8_t name[26]; - uint8_t cvt; - uint8_t dfp; - uint32_t length; - uint32_t loopbegin; - uint32_t loopend; - uint32_t C5Speed; - uint32_t susloopbegin; - uint32_t susloopend; - uint32_t samplepointer; - uint8_t vis; - uint8_t vid; - uint8_t vir; - uint8_t vit; + uint32_t id; // 0x53504D49 + int8_t filename[12]; + uint8_t zero; + uint8_t gvl; + uint8_t flags; + uint8_t vol; + int8_t name[26]; + uint8_t cvt; + uint8_t dfp; + uint32_t length; + uint32_t loopbegin; + uint32_t loopend; + uint32_t C5Speed; + uint32_t susloopbegin; + uint32_t susloopend; + uint32_t samplepointer; + uint8_t vis; + uint8_t vid; + uint8_t vir; + uint8_t vit; }; #pragma pack(pop) diff -Nru schism-0+20110101/include/it.h schism-20160521/include/it.h --- schism-0+20110101/include/it.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/it.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -42,25 +42,25 @@ #define SDL_ToggleCursor() SDL_ShowCursor(!SDL_ShowCursor(-1)) #define NO_MODIFIER(mod) \ - (((mod) & (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT)) == 0) + (((mod) & (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT)) == 0) #define NO_CAM_MODS(mod) \ - (((mod) & (KMOD_CTRL | KMOD_ALT)) == 0) + (((mod) & (KMOD_CTRL | KMOD_ALT)) == 0) /* --------------------------------------------------------------------- */ /* structs 'n enums */ /* tracker_status dialog_types */ enum { - DIALOG_NONE = (0), /* 0000 0000 */ - DIALOG_MENU = (1 << 0), /* 0000 0001 */ - DIALOG_MAIN_MENU = (DIALOG_MENU | (1 << 1)), /* 0000 0011 */ - DIALOG_SUBMENU = (DIALOG_MENU | (1 << 2)), /* 0000 0101 */ - DIALOG_BOX = (1 << 3), /* 0000 1000 */ - DIALOG_OK = (DIALOG_BOX | (1 << 4)), /* 0001 1000 */ - DIALOG_OK_CANCEL = (DIALOG_BOX | (1 << 5)), /* 0010 1000 */ - /* yes/no technically has a cancel as well, i.e. the escape key */ - DIALOG_YES_NO = (DIALOG_BOX | (1 << 6)), /* 0100 1000 */ - DIALOG_CUSTOM = (DIALOG_BOX | (1 << 7)), /* 1000 1000 */ + DIALOG_NONE = (0), /* 0000 0000 */ + DIALOG_MENU = (1 << 0), /* 0000 0001 */ + DIALOG_MAIN_MENU = (DIALOG_MENU | (1 << 1)), /* 0000 0011 */ + DIALOG_SUBMENU = (DIALOG_MENU | (1 << 2)), /* 0000 0101 */ + DIALOG_BOX = (1 << 3), /* 0000 1000 */ + DIALOG_OK = (DIALOG_BOX | (1 << 4)), /* 0001 1000 */ + DIALOG_OK_CANCEL = (DIALOG_BOX | (1 << 5)), /* 0010 1000 */ + /* yes/no technically has a cancel as well, i.e. the escape key */ + DIALOG_YES_NO = (DIALOG_BOX | (1 << 6)), /* 0100 1000 */ + DIALOG_CUSTOM = (DIALOG_BOX | (1 << 7)), /* 1000 1000 */ }; /* tracker_status flags @@ -70,152 +70,152 @@ interface in some way) and uh, something else for the internal status flags like IS_VISIBLE or whatever */ enum { - /* if this flag is set, the screen will be redrawn */ - NEED_UPDATE = (1 << 0), + /* if this flag is set, the screen will be redrawn */ + NEED_UPDATE = (1 << 0), - /* is the current palette "backwards"? (used to make the borders look right) */ - INVERTED_PALETTE = (1 << 1), + /* is the current palette "backwards"? (used to make the borders look right) */ + INVERTED_PALETTE = (1 << 1), - DIR_MODULES_CHANGED = (1 << 2), - DIR_SAMPLES_CHANGED = (1 << 3), - DIR_INSTRUMENTS_CHANGED = (1 << 4), + DIR_MODULES_CHANGED = (1 << 2), + DIR_SAMPLES_CHANGED = (1 << 3), + DIR_INSTRUMENTS_CHANGED = (1 << 4), - /* these refer to the window's state. - * (they're rather useless on the console ;) */ - IS_FOCUSED = (1 << 5), - IS_VISIBLE = (1 << 6), - WM_AVAILABLE = (1 << 7), + /* these refer to the window's state. + * (they're rather useless on the console ;) */ + IS_FOCUSED = (1 << 5), + IS_VISIBLE = (1 << 6), + WM_AVAILABLE = (1 << 7), - /* if this is set, some stuff behaves differently - * (grep the source files for what stuff ;) */ - CLASSIC_MODE = (1 << 8), + /* if this is set, some stuff behaves differently + * (grep the source files for what stuff ;) */ + CLASSIC_MODE = (1 << 8), - /* make a backup file (song.it~) when saving a module? */ - MAKE_BACKUPS = (1 << 9), - NUMBERED_BACKUPS = (1 << 10), /* song.it.3~ */ + /* make a backup file (song.it~) when saving a module? */ + MAKE_BACKUPS = (1 << 9), + NUMBERED_BACKUPS = (1 << 10), /* song.it.3~ */ - LAZY_REDRAW = (1 << 11), + LAZY_REDRAW = (1 << 11), - /* this is here if anything is "changed" and we need to whine to - the user if they quit */ - SONG_NEEDS_SAVE = (1 << 12), + /* this is here if anything is "changed" and we need to whine to + the user if they quit */ + SONG_NEEDS_SAVE = (1 << 12), - /* if the software mouse pointer moved.... */ - SOFTWARE_MOUSE_MOVED = (1 << 13), + /* if the software mouse pointer moved.... */ + SOFTWARE_MOUSE_MOVED = (1 << 13), - /* pasting is done by setting a flag here, the main event loop then synthesizes - the various events... after we return */ - CLIPPY_PASTE_SELECTION = (1 << 14), - CLIPPY_PASTE_BUFFER = (1 << 15), + /* pasting is done by setting a flag here, the main event loop then synthesizes + the various events... after we return */ + CLIPPY_PASTE_SELECTION = (1 << 14), + CLIPPY_PASTE_BUFFER = (1 << 15), - /* if the disko is active */ - DISKWRITER_ACTIVE = (1 << 16), - DISKWRITER_ACTIVE_PATTERN = (1 << 17), /* recording only a single pattern */ + /* if the disko is active */ + DISKWRITER_ACTIVE = (1 << 16), + DISKWRITER_ACTIVE_PATTERN = (1 << 17), /* recording only a single pattern */ - /* mark... set by midi core when received new midi event */ - MIDI_EVENT_CHANGED = (1 << 18), + /* mark... set by midi core when received new midi event */ + MIDI_EVENT_CHANGED = (1 << 18), - /* poop */ - ACCIDENTALS_AS_FLATS = (1 << 19), + /* poop */ + ACCIDENTALS_AS_FLATS = (1 << 19), - /* fontedit */ - STARTUP_FONTEDIT = (1 << 20), + /* fontedit */ + STARTUP_FONTEDIT = (1 << 20), - /* key hacks -- should go away when keyboard redefinition is possible */ - META_IS_CTRL = (1 << 21), - ALTGR_IS_ALT = (1 << 22), + /* key hacks -- should go away when keyboard redefinition is possible */ + META_IS_CTRL = (1 << 21), + ALTGR_IS_ALT = (1 << 22), - /* holding shift (used on pattern editor for weird template thing) */ - SHIFT_KEY_DOWN = (1 << 23), + /* holding shift (used on pattern editor for weird template thing) */ + SHIFT_KEY_DOWN = (1 << 23), - /* Devi Ever's hack */ - CRAYOLA_MODE = (1 << 25), + /* Devi Ever's hack */ + CRAYOLA_MODE = (1 << 25), - /* holding caps */ - CAPS_PRESSED = (1 << 26), + /* holding caps */ + CAPS_PRESSED = (1 << 26), - NO_NETWORK = (1 << 27), - NO_MOUSE = (1 << 28), + NO_NETWORK = (1 << 27), + NO_MOUSE = (1 << 28), - /* Play MIDI events using the same semantics as tracker samples */ - MIDI_LIKE_TRACKER = (1 << 29), + /* Play MIDI events using the same semantics as tracker samples */ + MIDI_LIKE_TRACKER = (1 << 29), - /* if true, don't stop playing on load, and start playing new song afterward - (but only if the last song was already playing before loading) */ - PLAY_AFTER_LOAD = (1 << 30), + /* if true, don't stop playing on load, and start playing new song afterward + (but only if the last song was already playing before loading) */ + PLAY_AFTER_LOAD = (1 << 30), }; /* note! TIME_PLAYBACK is only for internal calculations -- don't use it directly */ enum tracker_time_display { - TIME_OFF, TIME_PLAY_ELAPSED, TIME_PLAY_CLOCK, TIME_PLAY_OFF, - TIME_ELAPSED, TIME_CLOCK, TIME_ABSOLUTE, TIME_PLAYBACK, + TIME_OFF, TIME_PLAY_ELAPSED, TIME_PLAY_CLOCK, TIME_PLAY_OFF, + TIME_ELAPSED, TIME_CLOCK, TIME_ABSOLUTE, TIME_PLAYBACK, }; /* what should go in the little box on the top right? */ enum tracker_vis_style { - VIS_OFF, VIS_FAKEMEM, VIS_OSCILLOSCOPE, VIS_VU_METER, VIS_MONOSCOPE, VIS_FFT, VIS_SENTINEL + VIS_OFF, VIS_FAKEMEM, VIS_OSCILLOSCOPE, VIS_VU_METER, VIS_MONOSCOPE, VIS_FFT, VIS_SENTINEL }; struct tracker_status { - int current_page; - int previous_page; - int current_help_index; - int dialog_type; /* one of the DIALOG_* constants above */ - int flags; - enum tracker_time_display time_display; - enum tracker_vis_style vis_style; - SDLKey last_keysym; - - time_t last_midi_time; - unsigned char last_midi_event[64]; - unsigned int last_midi_len; - unsigned int last_midi_real_len; - void *last_midi_port; /* really a struct midi_port * */ - - /* clock is driven from the main/event thread */ - time_t now; - struct tm tmnow; + int current_page; + int previous_page; + int current_help_index; + int dialog_type; /* one of the DIALOG_* constants above */ + int flags; + enum tracker_time_display time_display; + enum tracker_vis_style vis_style; + SDLKey last_keysym; + + time_t last_midi_time; + unsigned char last_midi_event[64]; + unsigned int last_midi_len; + unsigned int last_midi_real_len; + void *last_midi_port; /* really a struct midi_port * */ + + /* clock is driven from the main/event thread */ + time_t now; + struct tm tmnow; - int fix_numlock_setting; + int fix_numlock_setting; }; /* numlock hackery */ enum { - NUMLOCK_ALWAYS_OFF = 0, - NUMLOCK_ALWAYS_ON = 1, - NUMLOCK_HONOR = -1, /* don't fix it */ - NUMLOCK_GUESS = -2, /* don't fix it... except on non-ibook macs */ + NUMLOCK_ALWAYS_OFF = 0, + NUMLOCK_ALWAYS_ON = 1, + NUMLOCK_HONOR = -1, /* don't fix it */ + NUMLOCK_GUESS = -2, /* don't fix it... except on non-ibook macs */ }; /* mouse visibility - these are passed to video_mousecursor() first three are stored as the physical mouse state */ enum { - MOUSE_DISABLED, - MOUSE_EMULATED, - MOUSE_SYSTEM, + MOUSE_DISABLED, + MOUSE_EMULATED, + MOUSE_SYSTEM, - MOUSE_CYCLE_STATE, - MOUSE_RESET_STATE, + MOUSE_CYCLE_STATE, + MOUSE_RESET_STATE, }; #define MOUSE_MAX_STATE MOUSE_CYCLE_STATE struct it_palette { - char name[21]; - uint8_t colors[16][3]; + char name[21]; + uint8_t colors[16][3]; }; enum { - NOTE_TRANS_CLEAR = (30), - NOTE_TRANS_NOTE_CUT, - NOTE_TRANS_NOTE_OFF, - NOTE_TRANS_NOTE_FADE, - NOTE_TRANS_PREV_INS, - NOTE_TRANS_NEXT_INS, - NOTE_TRANS_TOGGLE_MASK, - NOTE_TRANS_VOL_PAN_SWITCH, - NOTE_TRANS_PLAY_NOTE, - NOTE_TRANS_PLAY_ROW, + NOTE_TRANS_CLEAR = (30), + NOTE_TRANS_NOTE_CUT, + NOTE_TRANS_NOTE_OFF, + NOTE_TRANS_NOTE_FADE, + NOTE_TRANS_PREV_INS, + NOTE_TRANS_NEXT_INS, + NOTE_TRANS_TOGGLE_MASK, + NOTE_TRANS_VOL_PAN_SWITCH, + NOTE_TRANS_PLAY_NOTE, + NOTE_TRANS_PLAY_ROW, }; /* --------------------------------------------------------------------- */ @@ -252,9 +252,7 @@ extern int cfg_palette; extern char cfg_module_pattern[]; - -typedef int (*compare_func) (const char *a, const char *b); -extern compare_func cfg_string_compare; +extern char cfg_export_pattern[]; void cfg_init_dir(void); void cfg_load(void); @@ -281,6 +279,9 @@ void cfg_load_disko(cfg_file_t *cfg); void cfg_save_disko(cfg_file_t *cfg); +void cfg_load_dmoz(cfg_file_t *cfg); +void cfg_save_dmoz(cfg_file_t *cfg); + /* --------------------------------------------------------------------- */ /* text functions */ @@ -291,7 +292,7 @@ static inline unsigned char unicode_to_ascii(uint16_t unicode) { - return unicode & 0xff; + return unicode & 0xff; // return ((unicode & 0xff80) ? 0 : (unicode & 0x7f)); } @@ -301,20 +302,16 @@ /* character drawing (in a separate header so they're easier to find) */ #include "draw-char.h" -/* the sample number indicates what position it belongs to, zero being - * for the currently active sample in the sample library - * and 1-99 for the respective samples in the sample list. - * to draw_sample_data tells where to draw it (duh ;) */ struct song_sample; -void draw_sample_data(struct vgamem_overlay *r, struct song_sample *sample, int number); +void draw_sample_data(struct vgamem_overlay *r, struct song_sample *sample); /* this works like draw_sample_data, just without having to allocate a * song_sample structure, and without caching the waveform. * mostly it's just for the oscilloscope view. */ void draw_sample_data_rect_16(struct vgamem_overlay *r, signed short *data, int length, - unsigned int channels, int fakemono); + unsigned int inputchans, unsigned int outputchans); void draw_sample_data_rect_8(struct vgamem_overlay *r, signed char *data, int length, - unsigned int channels, int fakemono); + unsigned int inputchans, unsigned int outputchans); /* these are in audio_playback.cc */ extern signed short *audio_buffer; diff -Nru schism-0+20110101/include/log.h schism-20160521/include/log.h --- schism-0+20110101/include/log.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/log.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -27,15 +27,15 @@ void log_append(int color, int must_free, const char *text); void log_append2(int bios_font, int color, int must_free, const char *text); void log_appendf(int color, const char *format, ...) - __attribute__ ((format(printf, 2, 3))); + __attribute__ ((format(printf, 2, 3))); void log_underline(int chars); void log_perror(const char *prefix); void status_text_flash(const char *format, ...) - __attribute__ ((format(printf, 1, 2))); + __attribute__ ((format(printf, 1, 2))); void status_text_flash_bios(const char *format, ...) - __attribute__ ((format(printf, 1, 2))); + __attribute__ ((format(printf, 1, 2))); #endif diff -Nru schism-0+20110101/include/midi.h schism-20160521/include/midi.h --- schism-0+20110101/include/midi.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/midi.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -29,55 +29,55 @@ #define MIDI_PORT_CAN_SCHEDULE 1 struct midi_driver { - unsigned int flags; + unsigned int flags; - void (*poll)(struct midi_provider *m); - int (*thread)(struct midi_provider *m); + void (*poll)(struct midi_provider *m); + int (*thread)(struct midi_provider *m); - int (*enable)(struct midi_port *d); - int (*disable)(struct midi_port *d); + int (*enable)(struct midi_port *d); + int (*disable)(struct midi_port *d); - void (*send)(struct midi_port *d, - const unsigned char *seq, unsigned int len, unsigned int delay); - void (*drain)(struct midi_port *d); + void (*send)(struct midi_port *d, + const unsigned char *seq, unsigned int len, unsigned int delay); + void (*drain)(struct midi_port *d); }; struct midi_provider { - char *name; - void (*poll)(struct midi_provider *); - void *thread; /*actually SDL_Thread* */ - - struct midi_provider *next; - - /* forwarded; don't touch */ - int (*enable)(struct midi_port *d); - int (*disable)(struct midi_port *d); - - void (*send_now)(struct midi_port *d, - const unsigned char *seq, unsigned int len, unsigned int delay); - void (*send_later)(struct midi_port *d, - const unsigned char *seq, unsigned int len, unsigned int delay); - void (*drain)(struct midi_port *d); + char *name; + void (*poll)(struct midi_provider *); + void *thread; /*actually SDL_Thread* */ + + struct midi_provider *next; + + /* forwarded; don't touch */ + int (*enable)(struct midi_port *d); + int (*disable)(struct midi_port *d); + + void (*send_now)(struct midi_port *d, + const unsigned char *seq, unsigned int len, unsigned int delay); + void (*send_later)(struct midi_port *d, + const unsigned char *seq, unsigned int len, unsigned int delay); + void (*drain)(struct midi_port *d); }; #define MIDI_INPUT 1 #define MIDI_OUTPUT 2 struct midi_port { - int io, iocap; - char *name; - int num; - - void *userdata; - int free_userdata; - int (*enable)(struct midi_port *d); - int (*disable)(struct midi_port *d); - void (*send_now)(struct midi_port *d, - const unsigned char *seq, unsigned int len, unsigned int delay); - void (*send_later)(struct midi_port *d, - const unsigned char *seq, unsigned int len, unsigned int delay); - void (*drain)(struct midi_port *d); + int io, iocap; + char *name; + int num; + + void *userdata; + int free_userdata; + int (*enable)(struct midi_port *d); + int (*disable)(struct midi_port *d); + void (*send_now)(struct midi_port *d, + const unsigned char *seq, unsigned int len, unsigned int delay); + void (*send_later)(struct midi_port *d, + const unsigned char *seq, unsigned int len, unsigned int delay); + void (*drain)(struct midi_port *d); - struct midi_provider *provider; + struct midi_provider *provider; }; @@ -120,9 +120,9 @@ midi drivers should never all these... */ enum midi_note { - MIDI_NOTEOFF, - MIDI_NOTEON, - MIDI_KEYPRESS, + MIDI_NOTEOFF, + MIDI_NOTEON, + MIDI_KEYPRESS, }; void midi_event_note(enum midi_note mnstatus, int channel, int note, int velocity); void midi_event_controller(int channel, int param, int value); diff -Nru schism-0+20110101/include/osdefs.h schism-20160521/include/osdefs.h --- schism-0+20110101/include/osdefs.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/osdefs.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/page.h schism-20160521/include/page.h --- schism-0+20110101/include/page.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/page.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,40 +28,31 @@ #ifndef PAGE_H #define PAGE_H -/* there's no good place for this */ -#define MOUSE_BUTTON_LEFT 1 -#define MOUSE_BUTTON_MIDDLE 2 -#define MOUSE_BUTTON_RIGHT 3 -#define MOUSE_CLICK 1 -#define MOUSE_SCROLL_UP 2 -#define MOUSE_SCROLL_DOWN 3 -#define MOUSE_DBLCLICK 4 - /* How much to scroll. */ #define MOUSE_SCROLL_LINES 3 struct key_event { - SDLKey sym, orig_sym; - SDLMod mod; - uint16_t unicode; - int scancode; - - int state; /* 0 for down, 1 for up/release */ - int mouse; /* 0 for none, 1 for click, 2 for scrollup, 3 for down */ - int mouse_button; /* 1 left, 2 middle, 3 right (itf only) */ - int midi_note; - int midi_channel; - int midi_volume; /* -1 for not a midi key otherwise 0...128 */ - int midi_bend; /* normally 0; -8192 to +8192 */ - unsigned int sx, sy; /* start x and y position (character) */ - unsigned int x, hx, fx; /* x position of mouse (character, halfcharacter, fine) */ - unsigned int y, fy; /* y position of mouse (character, fine) */ - - unsigned int rx, ry; /* x/y resolution */ - - int is_repeat; - int on_target; - int is_synthetic; /* 1 came from paste */ + SDLKey sym, orig_sym; + SDLMod mod; + uint16_t unicode; + int scancode; + + enum { KEY_PRESS=0, KEY_RELEASE } state; + enum { MOUSE_NONE=0, MOUSE_CLICK, MOUSE_SCROLL_UP, MOUSE_SCROLL_DOWN, MOUSE_DBLCLICK } mouse; + enum { MOUSE_BUTTON_LEFT=0, MOUSE_BUTTON_MIDDLE, MOUSE_BUTTON_RIGHT } mouse_button; + int midi_note; + int midi_channel; + int midi_volume; /* -1 for not a midi key otherwise 0...128 */ + int midi_bend; /* normally 0; -8192 to +8192 */ + unsigned int sx, sy; /* start x and y position (character) */ + unsigned int x, hx, fx; /* x position of mouse (character, halfcharacter, fine) */ + unsigned int y, fy; /* y position of mouse (character, fine) */ + + unsigned int rx, ry; /* x/y resolution */ + + int is_repeat; + int on_target; + int is_synthetic; /* 1 came from paste */ }; /* --------------------------------------------------------------------- */ @@ -69,19 +60,19 @@ /* NOTE: this enum should be in the same order as helptexts in Makefile.am */ enum { - HELP_GLOBAL, /* needs to be first! */ - HELP_COPYRIGHT, - HELP_INFO_PAGE, - HELP_INSTRUMENT_LIST, - HELP_MESSAGE_EDITOR, - HELP_MIDI_OUTPUT, - HELP_ORDERLIST_PANNING, - HELP_ORDERLIST_VOLUME, - HELP_PATTERN_EDITOR, - HELP_ADLIB_SAMPLE, - HELP_SAMPLE_LIST, + HELP_GLOBAL, /* needs to be first! */ + HELP_COPYRIGHT, + HELP_INFO_PAGE, + HELP_INSTRUMENT_LIST, + HELP_MESSAGE_EDITOR, + HELP_MIDI_OUTPUT, + HELP_ORDERLIST_PANNING, + HELP_ORDERLIST_VOLUME, + HELP_PATTERN_EDITOR, + HELP_ADLIB_SAMPLE, + HELP_SAMPLE_LIST, - HELP_NUM_ITEMS /* needs to be last! */ + HELP_NUM_ITEMS /* needs to be last! */ }; extern const char *help_text[HELP_NUM_ITEMS]; @@ -90,15 +81,15 @@ /* there's a value in this enum for each kind of widget... */ enum widget_type { - WIDGET_TOGGLE, WIDGET_MENUTOGGLE, - WIDGET_BUTTON, WIDGET_TOGGLEBUTTON, - WIDGET_TEXTENTRY, - WIDGET_NUMENTRY, WIDGET_THUMBBAR, WIDGET_BITSET, WIDGET_PANBAR, - /* this last one is for anything that doesn't fit some standard - type, like the sample list, envelope editor, etc.; a widget of - this type is just a placeholder so page.c knows there's - something going on. */ - WIDGET_OTHER /* sample list, envelopes, etc. */ + WIDGET_TOGGLE, WIDGET_MENUTOGGLE, + WIDGET_BUTTON, WIDGET_TOGGLEBUTTON, + WIDGET_TEXTENTRY, + WIDGET_NUMENTRY, WIDGET_THUMBBAR, WIDGET_BITSET, WIDGET_PANBAR, + /* this last one is for anything that doesn't fit some standard + type, like the sample list, envelope editor, etc.; a widget of + this type is just a placeholder so page.c knows there's + something going on. */ + WIDGET_OTHER /* sample list, envelopes, etc. */ }; /* --------------------------------------------------------------------- */ @@ -110,29 +101,29 @@ /* space -> state changed; cb triggered */ struct widget_toggle { - int state; /* 0 = off, 1 = on */ + int state; /* 0 = off, 1 = on */ }; /* space -> state changed; cb triggered */ struct widget_menutoggle { - int state; /* 0, 1, ..., num_choices - 1, num_choices */ - const char *const *choices; - int num_choices; - const char *activation_keys; + int state; /* 0, 1, ..., num_choices - 1, num_choices */ + const char *const *choices; + int num_choices; + const char *activation_keys; }; /* enter -> cb triggered */ struct widget_button { - const char *text; - int padding; + const char *text; + int padding; }; /* enter -> state changed; cb triggered */ struct widget_togglebutton { - const char *text; - int padding; - int state; /* 0 = off, 1 = on */ - const int *group; + const char *text; + int padding; + int state; /* 0 = off, 1 = on */ + const int *group; }; /* backspace -> truncated; changed cb triggered @@ -144,10 +135,10 @@ * - if (max_length > (width - 1)) the text scrolls * - cursor_pos is set to the end of the text when the widget is focused */ struct widget_textentry { - char *text; - int max_length; - int firstchar; /* first visible character (generally 0) */ - int cursor_pos; /* 0 = first character */ + char *text; + int max_length; + int firstchar; /* first visible character (generally 0) */ + int cursor_pos; /* 0 = first character */ }; /* <0-9> -> digit @ cursor_pos changed; cursor_pos increased; cb triggered @@ -156,12 +147,12 @@ * cursor_pos for this widget is a pointer so that multiple numbers that * are all lined up can share the same position. */ struct widget_numentry { - int min; - int max; - int value; - int *cursor_pos; - int (*handle_unknown_key)(struct key_event *k); - int reverse; + int min; + int max; + int value; + int *cursor_pos; + int (*handle_unknown_key)(struct key_event *k); + int reverse; }; /* left/right -> value changed; cb triggered @@ -170,26 +161,26 @@ * home/end -> value set to min/max; cb triggered * <0-9> -> prompt for new number; value changed; cb triggered */ struct widget_thumbbar { - /* pretty much the same as the numentry, just without the cursor - * position field... (NOTE - don't rearrange the order of the - * fields in either of these; some code depends on them being - * the same) */ - int min; - int max; - int value; - /* this is currently only used with the midi thumbbars on the ins. list + pitch page. if - * this is non-NULL, and value == {min,max}, the text is drawn instead of the thumbbar. */ - const char *text_at_min, *text_at_max; + /* pretty much the same as the numentry, just without the cursor + * position field... (NOTE - don't rearrange the order of the + * fields in either of these; some code depends on them being + * the same) */ + int min; + int max; + int value; + /* this is currently only used with the midi thumbbars on the ins. list + pitch page. if + * this is non-NULL, and value == {min,max}, the text is drawn instead of the thumbbar. */ + const char *text_at_min, *text_at_max; }; struct widget_bitset { - /* A widget for controlling individual bits */ - int nbits; - int value; - int *cursor_pos; - const char* bits_on; - const char* bits_off; - const char* activation_keys; + /* A widget for controlling individual bits */ + int nbits; + int value; + int *cursor_pos; + const char* bits_on; + const char* bits_off; + const char* activation_keys; }; @@ -203,74 +194,74 @@ * note that, due to some weirdness with IT, these draw the channel text * as well as the actual bar. */ struct widget_panbar { - int min; - int max; - int value; - int channel; - unsigned int muted:1; - unsigned int surround:1; + int min; + int max; + int value; + int channel; + unsigned int muted:1; + unsigned int surround:1; }; struct widget_other { - /* bah. can't do much of anything with this. - * - * if an 'other' type widget gets the focus, it soaks up all the - * keyboard events that the main handler doesn't catch. thus - * it is responsible for changing the focus to something else - * (and, of course, if it doesn't ever do that, the cursor is - * pretty much stuck) - * this MUST be set to a valid function. - * return value is 1 if the key was handled, 0 if not. */ - int (*handle_key) (struct key_event * k); - - /* also the widget drawing function can't possibly know how to - * draw a custom widget, so it calls this instead. - * this MUST be set to a valid function. */ - void (*redraw) (void); + /* bah. can't do much of anything with this. + * + * if an 'other' type widget gets the focus, it soaks up all the + * keyboard events that the main handler doesn't catch. thus + * it is responsible for changing the focus to something else + * (and, of course, if it doesn't ever do that, the cursor is + * pretty much stuck) + * this MUST be set to a valid function. + * return value is 1 if the key was handled, 0 if not. */ + int (*handle_key) (struct key_event * k); + + /* also the widget drawing function can't possibly know how to + * draw a custom widget, so it calls this instead. + * this MUST be set to a valid function. */ + void (*redraw) (void); }; /* --------------------------------------------------------------------- */ /* and all the widget structs go in the union in this struct... */ union _widget_data_union { - struct widget_toggle toggle; - struct widget_menutoggle menutoggle; - struct widget_button button; - struct widget_togglebutton togglebutton; - struct widget_textentry textentry; - struct widget_numentry numentry; - struct widget_thumbbar thumbbar; - struct widget_panbar panbar; - struct widget_other other; - struct widget_bitset bitset; + struct widget_toggle toggle; + struct widget_menutoggle menutoggle; + struct widget_button button; + struct widget_togglebutton togglebutton; + struct widget_textentry textentry; + struct widget_numentry numentry; + struct widget_thumbbar thumbbar; + struct widget_panbar panbar; + struct widget_other other; + struct widget_bitset bitset; }; struct widget { - enum widget_type type; + enum widget_type type; - union _widget_data_union d; + union _widget_data_union d; - /* for redrawing */ - int x, y, width, height, depressed; - int clip_start, clip_end; + /* for redrawing */ + int x, y, width, height, depressed; + int clip_start, clip_end; - /* these next 5 fields specify what widget gets selected next */ - struct { - int up, down, left, right, tab; - } next; + /* these next 5 fields specify what widget gets selected next */ + struct { + int up, down, left, right, tab; + } next; - /* called whenever the value is changed... duh ;) */ - void (*changed) (void); + /* called whenever the value is changed... duh ;) */ + void (*changed) (void); - /* called when the enter key is pressed */ - void (*activate) (void); + /* called when the enter key is pressed */ + void (*activate) (void); - /* called by the clipboard manager; really, only "other" widgets - should "override" this... */ - int (*clipboard_paste)(int cb, const void *cptr); + /* called by the clipboard manager; really, only "other" widgets + should "override" this... */ + int (*clipboard_paste)(int cb, const void *cptr); - /* true if the widget accepts "text"- used for digraphs and unicode - and alt+kp entry... */ - int accept_text; + /* true if the widget accepts "text"- used for digraphs and unicode + and alt+kp entry... */ + int accept_text; }; /* this structure keeps all the information needed to draw a page, and a @@ -281,44 +272,44 @@ * everything in this struct MUST be set for each page. * functions that aren't implemented should be set to NULL. */ struct page { - /* the title of the page, eg "Sample List (F3)" */ - const char *title; + /* the title of the page, eg "Sample List (F3)" */ + const char *title; - /* font editor takes over full screen */ - void (*draw_full)(void); - /* draw the labels, etc. that don't change */ - void (*draw_const) (void); - /* called after the song is changed. this is to copy the new - * values from the song to the widgets on the page. */ - void (*song_changed_cb) (void); - /* called before widgets are drawn, mostly to fix the values - * (for example, on the sample page this sets everything to - * whatever values the current sample has) - this is a lousy - * hack. sorry. :P */ - void (*predraw_hook) (void); - /* draw the parts of the page that change when the song is playing - * (this is called *very* frequently) */ - void (*playback_update) (void); - /* this gets first shot at keys (to do unnatural overrides) */ - int (*pre_handle_key) (struct key_event * k); - /* this catches any keys that the main handler doesn't deal with */ - void (*handle_key) (struct key_event * k); - /* called when the page is set. this is for reloading the - * directory in the file browsers. */ - void (*set_page) (void); - - /* called when the song-mode changes */ - void (*song_mode_changed_cb) (void); - - /* called by the clipboard manager */ - int (*clipboard_paste)(int cb, const void *cptr); - - struct widget *widgets; - int selected_widget; - int total_widgets; + /* font editor takes over full screen */ + void (*draw_full)(void); + /* draw the labels, etc. that don't change */ + void (*draw_const) (void); + /* called after the song is changed. this is to copy the new + * values from the song to the widgets on the page. */ + void (*song_changed_cb) (void); + /* called before widgets are drawn, mostly to fix the values + * (for example, on the sample page this sets everything to + * whatever values the current sample has) - this is a lousy + * hack. sorry. :P */ + void (*predraw_hook) (void); + /* draw the parts of the page that change when the song is playing + * (this is called *very* frequently) */ + void (*playback_update) (void); + /* this gets first shot at keys (to do unnatural overrides) */ + int (*pre_handle_key) (struct key_event * k); + /* this catches any keys that the main handler doesn't deal with */ + void (*handle_key) (struct key_event * k); + /* called when the page is set. this is for reloading the + * directory in the file browsers. */ + void (*set_page) (void); + + /* called when the song-mode changes */ + void (*song_mode_changed_cb) (void); + + /* called by the clipboard manager */ + int (*clipboard_paste)(int cb, const void *cptr); + + struct widget *widgets; + int selected_widget; + int total_widgets; - /* 0 if no page-specific help */ - int help_index; + /* 0 if no page-specific help */ + int help_index; }; /* --------------------------------------------------------------------- */ @@ -347,49 +338,49 @@ /* --------------------------------------------------------------------- */ enum page_numbers { - PAGE_BLANK, - PAGE_HELP, - PAGE_ABOUT, - PAGE_LOG, + PAGE_BLANK, + PAGE_HELP, + PAGE_ABOUT, + PAGE_LOG, - PAGE_PATTERN_EDITOR, - PAGE_SAMPLE_LIST, - // PAGE_INSTRUMENT_LIST doesn't exist - PAGE_INFO, + PAGE_PATTERN_EDITOR, + PAGE_SAMPLE_LIST, + // PAGE_INSTRUMENT_LIST doesn't exist + PAGE_INFO, - PAGE_CONFIG, - PAGE_PREFERENCES, + PAGE_CONFIG, + PAGE_PREFERENCES, - PAGE_MIDI, - PAGE_MIDI_OUTPUT, + PAGE_MIDI, + PAGE_MIDI_OUTPUT, - PAGE_LOAD_MODULE, - PAGE_SAVE_MODULE, - PAGE_EXPORT_MODULE, + PAGE_LOAD_MODULE, + PAGE_SAVE_MODULE, + PAGE_EXPORT_MODULE, - PAGE_ORDERLIST_PANNING, - PAGE_ORDERLIST_VOLUMES, + PAGE_ORDERLIST_PANNING, + PAGE_ORDERLIST_VOLUMES, - PAGE_SONG_VARIABLES, - PAGE_MESSAGE, + PAGE_SONG_VARIABLES, + PAGE_MESSAGE, - /* don't use these directly with set_page */ - PAGE_INSTRUMENT_LIST_GENERAL, - PAGE_INSTRUMENT_LIST_VOLUME, - PAGE_INSTRUMENT_LIST_PANNING, - PAGE_INSTRUMENT_LIST_PITCH, + /* don't use these directly with set_page */ + PAGE_INSTRUMENT_LIST_GENERAL, + PAGE_INSTRUMENT_LIST_VOLUME, + PAGE_INSTRUMENT_LIST_PANNING, + PAGE_INSTRUMENT_LIST_PITCH, - PAGE_LOAD_SAMPLE, - PAGE_LIBRARY_SAMPLE, - PAGE_LOAD_INSTRUMENT, - PAGE_LIBRARY_INSTRUMENT, + PAGE_LOAD_SAMPLE, + PAGE_LIBRARY_SAMPLE, + PAGE_LOAD_INSTRUMENT, + PAGE_LIBRARY_INSTRUMENT, - PAGE_PALETTE_EDITOR, - PAGE_FONT_EDIT, + PAGE_PALETTE_EDITOR, + PAGE_FONT_EDIT, - PAGE_WATERFALL, + PAGE_WATERFALL, - PAGE_MAX + PAGE_MAX }; /* --------------------------------------------------------------------- */ @@ -427,40 +418,40 @@ /* --------------------------------------------------------------------- */ void create_toggle(struct widget *w, int x, int y, int next_up, - int next_down, int next_left, int next_right, - int next_tab, void (*changed) (void)); + int next_down, int next_left, int next_right, + int next_tab, void (*changed) (void)); void create_menutoggle(struct widget *w, int x, int y, int next_up, - int next_down, int next_left, int next_right, - int next_tab, void (*changed) (void), - const char *const *choices); + int next_down, int next_left, int next_right, + int next_tab, void (*changed) (void), + const char *const *choices); void create_button(struct widget *w, int x, int y, int width, int next_up, - int next_down, int next_left, int next_right, - int next_tab, void (*changed) (void), const char *text, - int padding); + int next_down, int next_left, int next_right, + int next_tab, void (*changed) (void), const char *text, + int padding); void create_togglebutton(struct widget *w, int x, int y, int width, - int next_up, int next_down, int next_left, - int next_right, int next_tab, - void (*changed) (void), const char *text, - int padding, const int *group); + int next_up, int next_down, int next_left, + int next_right, int next_tab, + void (*changed) (void), const char *text, + int padding, const int *group); void create_textentry(struct widget *w, int x, int y, int width, int next_up, - int next_down, int next_tab, void (*changed) (void), - char *text, int max_length); + int next_down, int next_tab, void (*changed) (void), + char *text, int max_length); void create_numentry(struct widget *w, int x, int y, int width, int next_up, - int next_down, int next_tab, void (*changed) (void), - int min, int max, int *cursor_pos); + int next_down, int next_tab, void (*changed) (void), + int min, int max, int *cursor_pos); void create_thumbbar(struct widget *w, int x, int y, int width, int next_up, - int next_down, int next_tab, void (*changed) (void), - int min, int max); + int next_down, int next_tab, void (*changed) (void), + int min, int max); void create_bitset(struct widget *w, int x, int y, int width, int next_up, - int next_down, int next_tab, void (*changed) (void), - int nbits, const char* bits_on, const char* bits_off, - int *cursor_pos); + int next_down, int next_tab, void (*changed) (void), + int nbits, const char* bits_on, const char* bits_off, + int *cursor_pos); void create_panbar(struct widget *w, int x, int y, int next_up, - int next_down, int next_tab, void (*changed) (void), - int channel); + int next_down, int next_tab, void (*changed) (void), + int channel); void create_other(struct widget *w, int next_tab, - int (*w_handle_key) (struct key_event * k), - void (*w_redraw) (void)); + int (*w_handle_key) (struct key_event * k), + void (*w_redraw) (void)); /* --------------------------------------------------------------------- */ @@ -471,8 +462,6 @@ int menutoggle_handle_key(struct widget *widget, struct key_event *k); int bitset_handle_key(struct widget *widget, struct key_event *k); -struct widget *find_widget_xy(int x, int y); -struct widget *find_widget_xy_ex(int x, int y, int *num); int change_focus_to_xy(int x, int y); void change_focus_to(int new_widget_index); /* p_widgets should point to the group of widgets (not the actual widget that is @@ -486,7 +475,7 @@ /* draw-misc.c */ void draw_thumb_bar(int x, int y, int width, int min, int max, int val, - int selected); + int selected); /* vu meter values should range from 0 to 64. the color is generally 5 * unless the channel is disabled (in which case it's 1). impulse tracker * doesn't do peak color; st3 style, use color 4 (unless it's disabled, @@ -501,6 +490,9 @@ void new_song_dialog(void); void save_song_or_save_as(void); +// support for the song length dialog +void show_length_dialog(const char *label, unsigned int length); + /* page_patedit.c */ void update_current_row(void); void update_current_pattern(void); @@ -528,29 +520,29 @@ /* dialog crap */ struct dialog { - int type; - int x, y, w, h; + int type; + int x, y, w, h; - /* next two are for "simple" dialogs (type != DIALOG_CUSTOM) */ - char *text; /* malloc'ed */ - int text_x; - - struct widget *widgets; /* malloc'ed */ - int selected_widget; - int total_widgets; - - void *data; /* extra data pointer */ - - /* maybe these should get the data pointer as well? */ - void (*draw_const) (void); - int (*handle_key) (struct key_event * k); - - /* there's no action_ok, as yes and ok are fundamentally the same */ - void (*action_yes) (void *data); - void (*action_no) (void *data); /* only useful for y/n dialogs? */ - /* currently, this is only settable for custom dialogs. - * it's only used in a couple of places (mostly on the pattern editor) */ - void (*action_cancel) (void *data); + /* next two are for "simple" dialogs (type != DIALOG_CUSTOM) */ + char *text; /* malloc'ed */ + int text_x; + + struct widget *widgets; /* malloc'ed */ + int selected_widget; + int total_widgets; + + void *data; /* extra data pointer */ + + /* maybe these should get the data pointer as well? */ + void (*draw_const) (void); + int (*handle_key) (struct key_event * k); + + /* there's no action_ok, as yes and ok are fundamentally the same */ + void (*action_yes) (void *data); + void (*action_no) (void *data); /* only useful for y/n dialogs? */ + /* currently, this is only settable for custom dialogs. + * it's only used in a couple of places (mostly on the pattern editor) */ + void (*action_cancel) (void *data); }; /* dialog handlers @@ -569,7 +561,7 @@ void dialog_draw(void); struct dialog *dialog_create(int type, const char *text, void (*action_yes) (void *data), - void (*action_no) (void *data), int default_widget, void *data); + void (*action_no) (void *data), int default_widget, void *data); void dialog_destroy(void); void dialog_destroy_all(void); @@ -578,8 +570,8 @@ * the caller can set other properties of the dialog (i.e. the yes/no/cancel callbacks) after * the dialog has been displayed. */ struct dialog *dialog_create_custom(int x, int y, int w, int h, struct widget *dialog_widgets, - int dialog_total_widgets, int dialog_selected_widget, - void (*draw_const) (void), void *data); + int dialog_total_widgets, int dialog_selected_widget, + void (*draw_const) (void), void *data); /* --------------------------------------------------------------------- */ /* Other UI prompt stuff. */ diff -Nru schism-0+20110101/include/pattern-view.h schism-20160521/include/pattern-view.h --- schism-0+20110101/include/pattern-view.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/pattern-view.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -31,9 +31,9 @@ typedef void (*draw_mask_func) (int x, int y, int mask, int cursor_pos, int fg, int bg); #define PATTERN_VIEW(n) \ - void draw_channel_header_##n(int chan, int x, int y, int fg); \ - void draw_note_##n(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg); \ - void draw_mask_##n(int x, int y, int mask, int cursor_pos, int fg, int bg); + void draw_channel_header_##n(int chan, int x, int y, int fg); \ + void draw_note_##n(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg); \ + void draw_mask_##n(int x, int y, int mask, int cursor_pos, int fg, int bg); PATTERN_VIEW(13); PATTERN_VIEW(10); diff -Nru schism-0+20110101/include/sample-edit.h schism-20160521/include/sample-edit.h --- schism-0+20110101/include/sample-edit.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/sample-edit.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/slurp.h schism-20160521/include/slurp.h --- schism-0+20110101/include/slurp.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/slurp.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -41,13 +41,13 @@ typedef struct _slurp_struct slurp_t; struct _slurp_struct { - size_t length; - uint8_t *data; - int extra; - void *bextra; - void (*closure)(slurp_t *); - /* for reading streams */ - size_t pos; + size_t length; + uint8_t *data; + int extra; + void *bextra; + void (*closure)(slurp_t *); + /* for reading streams */ + size_t pos; }; /* --------------------------------------------------------------------- */ diff -Nru schism-0+20110101/include/sndfile.h schism-20160521/include/sndfile.h --- schism-0+20110101/include/sndfile.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/sndfile.h 2016-05-21 14:40:41.000000000 +0000 @@ -49,7 +49,7 @@ #define CHN_NOTEFADE 0x400 // fade note (~~~ or end of instrument envelope) #define CHN_SURROUND 0x800 // use surround channel (S91) #define CHN_NOIDO 0x1000 // near enough to an exact multiple of c5speed that interpolation - // won't be noticeable (or interpolation is disabled completely) + // won't be noticeable (or interpolation is disabled completely) #define CHN_HQSRC 0x2000 // ??? #define CHN_FILTER 0x4000 // filtered output (i.e., Zxx) #define CHN_VOLUMERAMP 0x8000 // ramp volume @@ -69,7 +69,7 @@ #define CHN_ADLIB 0x20000000 // OPL mode #define CHN_SAMPLE_FLAGS (CHN_16BIT | CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP \ - | CHN_PINGPONGSUSTAIN | CHN_PANNING | CHN_STEREO | CHN_PINGPONGFLAG | CHN_ADLIB) + | CHN_PINGPONGSUSTAIN | CHN_PANNING | CHN_STEREO | CHN_PINGPONGFLAG | CHN_ADLIB) #define ENV_VOLUME 0x0001 @@ -216,14 +216,14 @@ // Global Options (Renderer) #define SNDMIX_REVERSESTEREO 0x0001 // swap L/R audio channels -#define SNDMIX_NOISEREDUCTION 0x0002 // reduce hiss (do not use, it's just a simple low-pass filter) +//#define SNDMIX_NOISEREDUCTION 0x0002 // reduce hiss (do not use, it's just a simple low-pass filter) //#define SNDMIX_AGC 0x0004 // automatic gain control #define SNDMIX_NORESAMPLING 0x0008 // force no resampling (uninterpolated) #define SNDMIX_HQRESAMPLER 0x0010 // cubic resampling //#define SNDMIX_MEGABASS 0x0020 //#define SNDMIX_SURROUND 0x0040 //#define SNDMIX_REVERB 0x0080 -#define SNDMIX_EQ 0x0100 // apply EQ +//#define SNDMIX_EQ 0x0100 // apply EQ (always on) //#define SNDMIX_SOFTPANNING 0x0200 #define SNDMIX_ULTRAHQSRCMODE 0x0400 // polyphase resampling (or FIR? I don't know) // Misc Flags (can safely be turned on or off) @@ -236,11 +236,11 @@ #define SNDMIX_NORAMPING 0x800000 // don't apply ramping on volume change (causes clicks) enum { - SRCMODE_NEAREST, - SRCMODE_LINEAR, - SRCMODE_SPLINE, - SRCMODE_POLYPHASE, - NUM_SRC_MODES + SRCMODE_NEAREST, + SRCMODE_LINEAR, + SRCMODE_SPLINE, + SRCMODE_POLYPHASE, + NUM_SRC_MODES }; // ------------------------------------------------------------------------------------------------------------ @@ -299,6 +299,10 @@ #define RS_IT2148 SF(IT214,8,M,LE) #define RS_IT21516 SF(IT215,16,M,LE) #define RS_IT2158 SF(IT215,8,M,LE) +#define RS_IT21416S SF(IT214,16,SS,LE) +#define RS_IT2148S SF(IT214,8,SS,LE) +#define RS_IT21516S SF(IT215,16,SS,LE) +#define RS_IT2158S SF(IT215,8,SS,LE) #define RS_MDL16 SF(MDL,16,M,LE) #define RS_MDL8 SF(MDL,8,M,LE) #define RS_PCM16D SF(PCMD,16,M,LE) @@ -329,65 +333,65 @@ // ------------------------------------------------------------------------------------------------------------ typedef struct song_sample { - uint32_t length; - uint32_t loop_start; - uint32_t loop_end; - uint32_t sustain_start; - uint32_t sustain_end; - signed char *data; - uint32_t c5speed; - uint32_t panning; - uint32_t volume; - uint32_t global_volume; - uint32_t flags; - uint32_t vib_type; - uint32_t vib_rate; - uint32_t vib_depth; - uint32_t vib_speed; - char name[32]; - char filename[22]; - int played; // for note playback dots - uint32_t globalvol_saved; // for muting individual samples + uint32_t length; + uint32_t loop_start; + uint32_t loop_end; + uint32_t sustain_start; + uint32_t sustain_end; + signed char *data; + uint32_t c5speed; + uint32_t panning; + uint32_t volume; + uint32_t global_volume; + uint32_t flags; + uint32_t vib_type; + uint32_t vib_rate; + uint32_t vib_depth; + uint32_t vib_speed; + char name[32]; + char filename[22]; + int played; // for note playback dots + uint32_t globalvol_saved; // for muting individual samples - // This must be 12-bytes to work around a bug in some gcc4.2s (XXX why? what bug?) - unsigned char adlib_bytes[12]; + // This must be 12-bytes to work around a bug in some gcc4.2s (XXX why? what bug?) + unsigned char adlib_bytes[12]; } song_sample_t; typedef struct song_envelope { - int ticks[32]; - uint8_t values[32]; - int nodes; - int loop_start; - int loop_end; - int sustain_start; - int sustain_end; + int ticks[32]; + uint8_t values[32]; + int nodes; + int loop_start; + int loop_end; + int sustain_start; + int sustain_end; } song_envelope_t; typedef struct song_instrument { - uint32_t fadeout; - uint32_t flags; - unsigned int global_volume; - unsigned int panning; - uint8_t sample_map[128]; - uint8_t note_map[128]; - song_envelope_t vol_env; - song_envelope_t pan_env; - song_envelope_t pitch_env; - unsigned int nna; - unsigned int dct; - unsigned int dca; - unsigned int pan_swing; - unsigned int vol_swing; - unsigned int ifc; - unsigned int ifr; - int midi_bank; // TODO split this? - int midi_program; - unsigned int midi_channel_mask; // FIXME why is this a mask? why is a mask useful? does 2.15 use a mask? - int pitch_pan_separation; - unsigned int pitch_pan_center; - char name[32]; - char filename[16]; - int played; // for note playback dots + uint32_t fadeout; + uint32_t flags; + unsigned int global_volume; + unsigned int panning; + uint8_t sample_map[128]; + uint8_t note_map[128]; + song_envelope_t vol_env; + song_envelope_t pan_env; + song_envelope_t pitch_env; + unsigned int nna; + unsigned int dct; + unsigned int dca; + unsigned int pan_swing; + unsigned int vol_swing; + unsigned int ifc; + unsigned int ifr; + int midi_bank; // TODO split this? + int midi_program; + unsigned int midi_channel_mask; // FIXME why is this a mask? why is a mask useful? does 2.15 use a mask? + int pitch_pan_separation; + unsigned int pitch_pan_center; + char name[32]; + char filename[16]; + int played; // for note playback dots } song_instrument_t; // (TODO write decent descriptions of what the various volume @@ -395,122 +399,122 @@ // (TODO also the majority of this is irrelevant outside of the "main" 64 channels; // this struct should really only be holding the stuff actually needed for mixing) typedef struct song_voice { - // First 32-bytes: Most used mixing information: don't change it - signed char * current_sample_data; - uint32_t position; // sample position, fixed-point -- integer part - uint32_t position_frac; // fractional part - int32_t increment; // 16.16 fixed point, how much to add to position per sample-frame of output - int32_t right_volume; // ? - int32_t left_volume; // ? - int32_t right_ramp; // ? - int32_t left_ramp; // ? - // 2nd cache line - uint32_t length; // only to the end of the loop - uint32_t flags; - uint32_t loop_start; // loop or sustain, whichever is active - uint32_t loop_end; - int32_t right_ramp_volume; // ? - int32_t left_ramp_volume; // ? - int32_t strike; // decremented to zero - - double filter_y1, filter_y2, filter_y3, filter_y4; - double filter_a0, filter_b0, filter_b1; - - int32_t rofs, lofs; // ? - int32_t ramp_length; - // Information not used in the mixer - int32_t right_volume_new, left_volume_new; // ? - int32_t final_volume; // range 0-16384 (?), accounting for sample+channel+global+etc. volumes - int32_t final_panning; // range 0-256 (but can temporarily exceed that range during calculations) - int32_t volume, panning; // range 0-256 (?); these are the current values set for the channel - int32_t fadeout_volume; - int32_t period; - int32_t c5speed; - int32_t sample_freq; - int32_t portamento_target; - song_instrument_t *ptr_instrument; // these two suck, and should - song_sample_t *ptr_sample; // be replaced with numbers - int vol_env_position; - int pan_env_position; - int pitch_env_position; - uint32_t master_channel; // nonzero = background/NNA voice, indicates what channel it "came from" - uint32_t vu_meter; - int32_t global_volume; - int32_t instrument_volume; - int32_t autovib_depth; - uint32_t autovib_position, vibrato_position, tremolo_position, panbrello_position; - // 16-bit members - int vol_swing, pan_swing; - - // formally 8-bit members - unsigned int note; // the note that's playing - unsigned int nna; - unsigned int new_note, new_instrument; // ? - // Effect memory and handling - unsigned int n_command; // This sucks and needs to go away (dumb "flag" for arpeggio / tremor) - unsigned int mem_vc_volslide; // Ax Bx Cx Dx (volume column) - unsigned int mem_arpeggio; // Axx - unsigned int mem_volslide; // Dxx - unsigned int mem_pitchslide; // Exx Fxx (and Gxx maybe) - int32_t mem_portanote; // Gxx (synced with mem_pitchslide if compat gxx is set) - unsigned int mem_tremor; // Ixx - unsigned int mem_channel_volslide; // Nxx - unsigned int mem_offset; // final, combined yxx00h from Oxx and SAy - unsigned int mem_panslide; // Pxx - unsigned int mem_retrig; // Qxx - unsigned int mem_special; // Sxx - unsigned int mem_tempo; // Txx - unsigned int mem_global_volslide; // Wxx - unsigned int note_slide_counter, note_slide_speed, note_slide_step; // IMF effect - unsigned int vib_type, vibrato_speed, vibrato_depth; - unsigned int tremolo_type, tremolo_speed, tremolo_depth; - unsigned int panbrello_type, panbrello_speed, panbrello_depth; - int tremolo_delta, panbrello_delta; - - unsigned int cutoff; - unsigned int resonance; - int cd_note_delay; // countdown: note starts when this hits zero - int cd_note_cut; // countdown: note stops when this hits zero - int cd_retrig; // countdown: note retrigs when this hits zero - unsigned int cd_tremor; // (weird) countdown + flag: see snd_fx.c and sndmix.c - unsigned int patloop_row; // row number that SB0 was on - unsigned int cd_patloop; // countdown: pattern loops back when this hits zero - - unsigned int row_note, row_instr; - unsigned int row_voleffect, row_volparam; - unsigned int row_effect, row_param; - unsigned int active_macro, last_instrument; + // First 32-bytes: Most used mixing information: don't change it + signed char * current_sample_data; + uint32_t position; // sample position, fixed-point -- integer part + uint32_t position_frac; // fractional part + int32_t increment; // 16.16 fixed point, how much to add to position per sample-frame of output + int32_t right_volume; // ? + int32_t left_volume; // ? + int32_t right_ramp; // ? + int32_t left_ramp; // ? + // 2nd cache line + uint32_t length; // only to the end of the loop + uint32_t flags; + uint32_t loop_start; // loop or sustain, whichever is active + uint32_t loop_end; + int32_t right_ramp_volume; // ? + int32_t left_ramp_volume; // ? + int32_t strike; // decremented to zero. this affects how long the initial hit on the playback marks lasts (bigger dot in instrument and sample list windows) + + int32_t filter_y1, filter_y2, filter_y3, filter_y4; + int32_t filter_a0, filter_b0, filter_b1; + + int32_t rofs, lofs; // ? + int32_t ramp_length; + // Information not used in the mixer + int32_t right_volume_new, left_volume_new; // ? + int32_t final_volume; // range 0-16384 (?), accounting for sample+channel+global+etc. volumes + int32_t final_panning; // range 0-256 (but can temporarily exceed that range during calculations) + int32_t volume, panning; // range 0-256 (?); these are the current values set for the channel + int32_t fadeout_volume; + int32_t period; + int32_t c5speed; + int32_t sample_freq; // only used on the info page (F5) + int32_t portamento_target; + song_instrument_t *ptr_instrument; // these two suck, and should + song_sample_t *ptr_sample; // be replaced with numbers + int vol_env_position; + int pan_env_position; + int pitch_env_position; + uint32_t master_channel; // nonzero = background/NNA voice, indicates what channel it "came from" + uint32_t vu_meter; + int32_t global_volume; + int32_t instrument_volume; + int32_t autovib_depth; + uint32_t autovib_position, vibrato_position, tremolo_position, panbrello_position; + // 16-bit members + int vol_swing, pan_swing; + + // formally 8-bit members + unsigned int note; // the note that's playing + unsigned int nna; + unsigned int new_note, new_instrument; // ? + // Effect memory and handling + unsigned int n_command; // This sucks and needs to go away (dumb "flag" for arpeggio / tremor) + unsigned int mem_vc_volslide; // Ax Bx Cx Dx (volume column) + unsigned int mem_arpeggio; // Axx + unsigned int mem_volslide; // Dxx + unsigned int mem_pitchslide; // Exx Fxx (and Gxx maybe) + int32_t mem_portanote; // Gxx (synced with mem_pitchslide if compat gxx is set) + unsigned int mem_tremor; // Ixx + unsigned int mem_channel_volslide; // Nxx + unsigned int mem_offset; // final, combined yxx00h from Oxx and SAy + unsigned int mem_panslide; // Pxx + unsigned int mem_retrig; // Qxx + unsigned int mem_special; // Sxx + unsigned int mem_tempo; // Txx + unsigned int mem_global_volslide; // Wxx + unsigned int note_slide_counter, note_slide_speed, note_slide_step; // IMF effect + unsigned int vib_type, vibrato_speed, vibrato_depth; + unsigned int tremolo_type, tremolo_speed, tremolo_depth; + unsigned int panbrello_type, panbrello_speed, panbrello_depth; + int tremolo_delta, panbrello_delta; + + unsigned int cutoff; + unsigned int resonance; + int cd_note_delay; // countdown: note starts when this hits zero + int cd_note_cut; // countdown: note stops when this hits zero + int cd_retrig; // countdown: note retrigs when this hits zero + unsigned int cd_tremor; // (weird) countdown + flag: see snd_fx.c and sndmix.c + unsigned int patloop_row; // row number that SB0 was on + unsigned int cd_patloop; // countdown: pattern loops back when this hits zero + + unsigned int row_note, row_instr; + unsigned int row_voleffect, row_volparam; + unsigned int row_effect, row_param; + unsigned int active_macro, last_instrument; } song_voice_t; typedef struct song_channel { - uint32_t panning; - uint32_t volume; - uint32_t flags; + uint32_t panning; + uint32_t volume; + uint32_t flags; } song_channel_t; typedef struct song_note { - uint8_t note; - uint8_t instrument; - uint8_t voleffect; - uint8_t volparam; - uint8_t effect; - uint8_t param; + uint8_t note; + uint8_t instrument; + uint8_t voleffect; + uint8_t volparam; + uint8_t effect; + uint8_t param; } song_note_t; //////////////////////////////////////////////////////////////////// typedef struct { - char start[32]; - char stop[32]; - char tick[32]; - char note_on[32]; - char note_off[32]; - char set_volume[32]; - char set_panning[32]; - char set_bank[32]; - char set_program[32]; - char sfx[16][32]; - char zxx[128][32]; + char start[32]; + char stop[32]; + char tick[32]; + char note_on[32]; + char note_off[32]; + char set_volume[32]; + char set_panning[32]; + char set_bank[32]; + char set_program[32]; + char sfx[16][32]; + char zxx[128][32]; } midi_config_t; extern midi_config_t default_midi_config; @@ -524,79 +528,79 @@ struct multi_write { - int used; - void *data; - /* Conveniently, this has the same prototype as disko_write :) */ - void (*write)(void *data, const uint8_t *buf, size_t bytes); - /* this is optimization for channels that haven't had any data yet - (nothing to convert/write, just seek ahead in the data stream) */ - void (*silence)(void *data, long bytes); - int buffer[MIXBUFFERSIZE * 2]; + int used; + void *data; + /* Conveniently, this has the same prototype as disko_write :) */ + void (*write)(void *data, const uint8_t *buf, size_t bytes); + /* this is optimization for channels that haven't had any data yet + (nothing to convert/write, just seek ahead in the data stream) */ + void (*silence)(void *data, long bytes); + int buffer[MIXBUFFERSIZE * 2]; }; typedef struct song { - int mix_buffer[MIXBUFFERSIZE * 2]; - float mix_buffer_float[MIXBUFFERSIZE * 2]; // is this needed? + int mix_buffer[MIXBUFFERSIZE * 2]; + float mix_buffer_float[MIXBUFFERSIZE * 2]; // is this needed? - song_voice_t voices[MAX_VOICES]; // Channels - uint32_t voice_mix[MAX_VOICES]; // Channels to be mixed - song_sample_t samples[MAX_SAMPLES+1]; // Samples (1-based!) - song_instrument_t *instruments[MAX_INSTRUMENTS+1]; // Instruments (1-based!) - song_channel_t channels[MAX_CHANNELS]; // Channel settings - song_note_t *patterns[MAX_PATTERNS]; // Patterns - uint16_t pattern_size[MAX_PATTERNS]; // Pattern Lengths - uint16_t pattern_alloc_size[MAX_PATTERNS]; // Allocated lengths (for async. resizing/playback) - uint8_t orderlist[MAX_ORDERS]; // Pattern Orders - midi_config_t midi_config; // Midi macro config table - uint32_t initial_speed; - uint32_t initial_tempo; - uint32_t initial_global_volume; - uint32_t flags; // Song flags SONG_XXXX - uint32_t pan_separation; - uint32_t num_voices; // how many are currently playing. (POTENTIALLY larger than global max_voices) - uint32_t mix_stat; // I'm not entirely sure what this is - uint32_t buffer_count; // I don't really remember what this is - uint32_t tick_count; - int32_t row_count; /* IMPORTANT needs to be signed */ - uint32_t current_speed; - uint32_t current_tempo; - uint32_t process_row; - uint32_t row; // no analogue in pm.h? should be either renamed or factored out. - uint32_t break_row; - uint32_t current_pattern; - uint32_t current_order; - uint32_t process_order; - uint32_t current_global_volume; - uint32_t mixing_volume; - uint32_t freq_factor; // not used -- for tweaking the song speed LP-style (interesting!) - uint32_t tempo_factor; // ditto - int32_t repeat_count; // 0 = first playback, etc. (note: set to -1 to stop instead of looping) - uint8_t row_highlight_major; - uint8_t row_highlight_minor; - char message[MAX_MESSAGE + 1]; - char title[32]; - char tracker_id[32]; // irrelevant to the song, just used by some loaders (fingerprint) - - // These store the existing IT save history from prior editing sessions. - // Current session data is added at save time, and is NOT a part of histdata. - int histlen; // How many session history data entries exist (each entry is eight bytes) - uint8_t *histdata; // Preserved entries from prior sessions, might be NULL if histlen = 0 - struct timeval editstart; // When the song was loaded - - // mixer stuff - uint32_t mix_flags; // SNDMIX_* - uint32_t mix_frequency, mix_bits_per_sample, mix_channels; - - // noise reduction filter - int32_t left_nr, right_nr; - - // chaseback - int stop_at_order; - int stop_at_row; - unsigned int stop_at_time; + song_voice_t voices[MAX_VOICES]; // Channels + uint32_t voice_mix[MAX_VOICES]; // Channels to be mixed + song_sample_t samples[MAX_SAMPLES+1]; // Samples (1-based!) + song_instrument_t *instruments[MAX_INSTRUMENTS+1]; // Instruments (1-based!) + song_channel_t channels[MAX_CHANNELS]; // Channel settings + song_note_t *patterns[MAX_PATTERNS]; // Patterns + uint16_t pattern_size[MAX_PATTERNS]; // Pattern Lengths + uint16_t pattern_alloc_size[MAX_PATTERNS]; // Allocated lengths (for async. resizing/playback) + uint8_t orderlist[MAX_ORDERS + 1]; // Pattern Orders + midi_config_t midi_config; // Midi macro config table + uint32_t initial_speed; + uint32_t initial_tempo; + uint32_t initial_global_volume; + uint32_t flags; // Song flags SONG_XXXX + uint32_t pan_separation; + uint32_t num_voices; // how many are currently playing. (POTENTIALLY larger than global max_voices) + uint32_t mix_stat; // number of channels being mixed (not really used) + uint32_t buffer_count; // number of samples to mix per tick + uint32_t tick_count; + int32_t row_count; /* IMPORTANT needs to be signed */ + uint32_t current_speed; + uint32_t current_tempo; + uint32_t process_row; + uint32_t row; // no analogue in pm.h? should be either renamed or factored out. + uint32_t break_row; + uint32_t current_pattern; + uint32_t current_order; + uint32_t process_order; + uint32_t current_global_volume; + uint32_t mixing_volume; + uint32_t freq_factor; // not used -- for tweaking the song speed LP-style (interesting!) + uint32_t tempo_factor; // ditto + int32_t repeat_count; // 0 = first playback, etc. (note: set to -1 to stop instead of looping) + uint8_t row_highlight_major; + uint8_t row_highlight_minor; + char message[MAX_MESSAGE + 1]; + char title[32]; + char tracker_id[32]; // irrelevant to the song, just used by some loaders (fingerprint) + + // These store the existing IT save history from prior editing sessions. + // Current session data is added at save time, and is NOT a part of histdata. + int histlen; // How many session history data entries exist (each entry is eight bytes) + uint8_t *histdata; // Preserved entries from prior sessions, might be NULL if histlen = 0 + struct timeval editstart; // When the song was loaded + + // mixer stuff + uint32_t mix_flags; // SNDMIX_* + uint32_t mix_frequency, mix_bits_per_sample, mix_channels; + + // noise reduction filter + int32_t left_nr, right_nr; + + // chaseback + int stop_at_order; + int stop_at_row; + unsigned int stop_at_time; - // multi-write stuff -- NULL if no multi-write is in progress, else array of one struct per channel - struct multi_write *multi_write; + // multi-write stuff -- NULL if no multi-write is in progress, else array of one struct per channel + struct multi_write *multi_write; } song_t; song_note_t *csf_allocate_pattern(uint32_t rows); @@ -642,7 +646,6 @@ int csf_set_wave_config(song_t *csf, uint32_t rate, uint32_t bits, uint32_t channels); -int csf_set_wave_config_ex(song_t *csf, int hqido, int nr, int eq); // Mixer Config int csf_init_player(song_t *csf, int reset); // bReset=false @@ -654,11 +657,6 @@ int csf_process_tick(song_t *csf); int csf_read_note(song_t *csf); -// snd_dsp -void csf_initialize_dsp(song_t *csf, int reset); -void csf_process_stereo_dsp(song_t *csf, int count); -void csf_process_mono_dsp(song_t *csf, int count); - // snd_fx unsigned int csf_get_length(song_t *csf); // (in seconds) void csf_instrument_change(song_t *csf, song_voice_t *chn, uint32_t instr, int porta, int instr_column); @@ -671,13 +669,13 @@ void fx_key_off(song_t *csf, uint32_t chan); void csf_midi_send(song_t *csf, const unsigned char *data, unsigned int len, uint32_t chan, int fake); void csf_process_midi_macro(song_t *csf, uint32_t chan, const char *midi_macro, uint32_t param, - uint32_t note, uint32_t velocity, uint32_t use_instr); + uint32_t note, uint32_t velocity, uint32_t use_instr); song_sample_t *csf_translate_keyboard(song_t *csf, song_instrument_t *ins, uint32_t note, song_sample_t *def); // various utility functions in snd_fx.c int get_note_from_period(int period); int get_period_from_note(int note, unsigned int c5speed, int linear); -unsigned int get_freq_from_period(int period, unsigned int c5speed, int linear); +unsigned int get_freq_from_period(int period, int linear); unsigned int transpose_to_frequency(int transp, int ftune); int frequency_to_transpose(unsigned int freq); unsigned long calc_halftone(unsigned long hz, int rel); @@ -710,14 +708,14 @@ // Return (a*b)/c - no divide error static inline int _muldiv(int a, int b, int c) { - return ((unsigned long long) a * (unsigned long long) b ) / c; + return ((unsigned long long) a * (unsigned long long) b ) / c; } // Return (a*b+c/2)/c - no divide error static inline int _muldivr(int a, int b, int c) { - return ((unsigned long long) a * (unsigned long long) b + (c >> 1)) / c; + return ((unsigned long long) a * (unsigned long long) b + (c >> 1)) / c; } diff -Nru schism-0+20110101/include/song.h schism-20160521/include/song.h --- schism-0+20110101/include/song.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/song.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -50,14 +50,13 @@ /* defined in audio_playback.cc; also used by page_settings.c */ struct audio_settings { - int sample_rate, bits, channels, buffer_size; - int channel_limit, interpolation_mode; - int oversampling, hq_resampling; - int noise_reduction, surround_effect; - - unsigned int eq_freq[4]; - unsigned int eq_gain[4]; - int no_ramping; + int sample_rate, bits, channels, buffer_size; + int channel_limit, interpolation_mode; + int surround_effect; + + unsigned int eq_freq[4]; + unsigned int eq_gain[4]; + int no_ramping; }; extern struct audio_settings audio_settings; @@ -67,35 +66,45 @@ /* for song_get_mode */ enum song_mode { - MODE_STOPPED = 0, - MODE_PLAYING = 1, - MODE_PATTERN_LOOP = 2, - MODE_SINGLE_STEP = 4, + MODE_STOPPED = 0, + MODE_PLAYING = 1, + MODE_PATTERN_LOOP = 2, + MODE_SINGLE_STEP = 4, }; enum song_new_flags { - KEEP_PATTERNS = 1, - KEEP_SAMPLES = 2, - KEEP_INSTRUMENTS = 4, - KEEP_ORDERLIST = 8, + KEEP_PATTERNS = 1, + KEEP_SAMPLES = 2, + KEEP_INSTRUMENTS = 4, + KEEP_ORDERLIST = 8, }; /* --------------------------------------------------------------------- */ /* song_load: - prompt ok/cancel if the existing song hasn't been saved. - after loading, the current page is changed accordingly. + prompt ok/cancel if the existing song hasn't been saved. + after loading, the current page is changed accordingly. + this loads into the global song. song_load_unchecked: - *NO* dialog, just goes right into loading the song - doesn't set the page after loading - return value is nonzero if the load was successful. - generally speaking, don't use this function directly; - use song_load instead. + *NO* dialog, just goes right into loading the song + doesn't set the page after loading. + this also loads into the global song. + return value is nonzero if the load was successful. + generally speaking, don't use this function directly; + use song_load instead. +song_create_load: + internal back-end function that loads and returns a song. + the above functions both use this. */ void song_new(int flags); void song_load(const char *file); int song_load_unchecked(const char *file); +song_t *song_create_load(const char *file); + +// song_create_load returns NULL on error and sets errno to what might not be a standard value +// use this to divine the meaning of these cryptic numbers +const char *fmt_strerror(int n); int song_save(const char *file, const char *type); // IT, S3M int song_export(const char *file, const char *type); // WAV @@ -127,7 +136,6 @@ char *song_get_message(void); // editable // returned value = seconds -unsigned int song_get_length(void); unsigned int song_get_length_to(int order, int row); void song_get_at_time(unsigned int seconds, int *order, int *row); @@ -189,6 +197,9 @@ void song_toggle_stereo(void); void song_toggle_mono(void); +/* called from song_set_stereo et al - this updates the value on F12 to match the song */ +void song_vars_sync_stereo(void); + /* void song_set_stereo(int value); ??? */ int song_has_old_effects(void); void song_set_old_effects(int value); @@ -208,12 +219,12 @@ /* Called at startup. The 'driver_spec' parameter is formatted as driver[:device]. - 'driver' is the name of the SDL driver to use - example: "alsa", "dsound" - SDL_AUDIODRIVER is set to this value - 'device' (optional) is the name of the device to use - example: "hw:2", "/dev/dsp" - SDL_PATH_DSP and AUDIODEV are set to this + 'driver' is the name of the SDL driver to use + example: "alsa", "dsound" + SDL_AUDIODRIVER is set to this value + 'device' (optional) is the name of the device to use + example: "hw:2", "/dev/dsp" + SDL_PATH_DSP and AUDIODEV are set to this For the SDL driver, 'nosound' and 'none' are aliases for 'dummy', for compatibility with previous Schism Tracker versions, and 'oss' is an @@ -358,13 +369,13 @@ /* for the orderpan page */ enum { - PANS_STEREO, - PANS_AMIGA, - PANS_LEFT, - PANS_RIGHT, - PANS_MONO, - PANS_SLASH, - PANS_BACKSLASH, + PANS_STEREO, + PANS_AMIGA, + PANS_LEFT, + PANS_RIGHT, + PANS_MONO, + PANS_SLASH, + PANS_BACKSLASH, // PANS_CROSS, }; void song_set_pan_scheme(int scheme); diff -Nru schism-0+20110101/include/tables.h schism-20160521/include/tables.h --- schism-0+20110101/include/tables.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/tables.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -26,6 +26,9 @@ #include +// better than having a table. +#define SHORT_PANNING(i) (((((i) << 4) | (i)) + 2) >> 2) + /* TODO: I know just sticking _fast on all of these will break the player, but for some of 'em...? */ extern const uint8_t vc_portamento_table[16]; // volume column Gx @@ -45,8 +48,6 @@ extern const uint32_t linear_slide_up_table[256]; extern const uint32_t linear_slide_down_table[256]; -extern const int short_panning_table[16]; - extern const char *midi_group_names[17]; extern const char *midi_program_names[128]; extern const char *midi_percussion_names[61]; diff -Nru schism-0+20110101/include/tree.h schism-20160521/include/tree.h --- schism-0+20110101/include/tree.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/tree.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/include/util.h schism-20160521/include/util.h --- schism-0+20110101/include/util.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/util.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -105,6 +105,49 @@ extern void *mem_realloc(void *,size_t); extern void mem_free(void *); +/*Conversion*/ +/* linear -> deciBell*/ +/* amplitude normalized to 1.0f.*/ +extern float dB(float amplitude); + +/// deciBell -> linear*/ +extern float dB2_amp(float db); + +/* linear -> deciBell*/ +/* power normalized to 1.0f.*/ +extern float pdB(float power); + +/* deciBell -> linear*/ +extern float dB2_power(float db); + +/* linear -> deciBell*/ +/* amplitude normalized to 1.0f.*/ +/* Output scaled (and clipped) to 128 lines with noisefloor range.*/ +/* ([0..128] = [-noisefloor..0dB])*/ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +extern short dB_s(int noisefloor, float amplitude, float correction_dBs); + +/* deciBell -> linear*/ +/* Input scaled to 128 lines with noisefloor range.*/ +/* ([0..128] = [-noisefloor..0dB])*/ +/* amplitude normalized to 1.0f.*/ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +extern short dB2_amp_s(int noisefloor, int db, float correction_dBs); + +/* linear -> deciBell*/ +/* power normalized to 1.0f.*/ +/* Output scaled (and clipped) to 128 lines with noisefloor range.*/ +/* ([0..128] = [-noisefloor..0dB])*/ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +extern short pdB_s(int noisefloor, float power, float correction_dBs); + +/* deciBell -> linear*/ +/* Input scaled to 128 lines with noisefloor range.*/ +/* ([0..128] = [-noisefloor..0dB])*/ +/* power normalized to 1.0f.*/ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +extern short dB2_power_s(int noisefloor, int db, float correction_dBs); + /* formatting */ /* for get_{time,date}_string, buf should be (at least) 27 chars; anything past that isn't used. */ char *get_date_string(time_t when, char *buf); diff -Nru schism-0+20110101/include/version.h schism-20160521/include/version.h --- schism-0+20110101/include/version.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/version.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ extern short ver_cwtv; /* lower 12 bits of the IT/S3M cwtv field */ extern const char *schism_banner(int classic) - __attribute__((pure)); + __attribute__((pure)); /* little hack, need to call this at startup */ void ver_init(void); diff -Nru schism-0+20110101/include/vgamem-scanner.h schism-20160521/include/vgamem-scanner.h --- schism-0+20110101/include/vgamem-scanner.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/vgamem-scanner.h 2016-05-21 14:40:41.000000000 +0000 @@ -1,78 +1,78 @@ /* should be included inside draw-char.c */ void F1(unsigned int ry, unsigned SIZE *out, unsigned int tc[16], unsigned int mouseline[80]) { - unsigned int *bp; - unsigned int dg; - unsigned char *q; - uint8_t *itf, *bios, *bioslow, *hf; - unsigned int x, y; - int fg, bg; + unsigned int *bp; + unsigned int dg; + unsigned char *q; + uint8_t *itf, *bios, *bioslow, *hf; + unsigned int x, y; + int fg, bg; - q = ovl + (ry * 640); - y = ry >> 3; - bp = &vgamem_read[y * 80]; - itf = font_data + (ry & 7); - bios = ((uint8_t*) font_default_upper_alt) + (ry & 7); - bioslow = ((uint8_t *) font_default_lower) + (ry & 7); - hf = font_half_data + ((ry & 7) >> 1); + q = ovl + (ry * 640); + y = ry >> 3; + bp = &vgamem_read[y * 80]; + itf = font_data + (ry & 7); + bios = ((uint8_t*) font_default_upper_alt) + (ry & 7); + bioslow = ((uint8_t *) font_default_lower) + (ry & 7); + hf = font_half_data + ((ry & 7) >> 1); - for (x = 0; x < 80; x++, bp++, q += 8) { - if (*bp & 0x80000000) { - *out++ = tc[ (q[0]^((mouseline[x] & 0x80)?15:0)) & 255]; - *out++ = tc[ (q[1]^((mouseline[x] & 0x40)?15:0)) & 255]; - *out++ = tc[ (q[2]^((mouseline[x] & 0x20)?15:0)) & 255]; - *out++ = tc[ (q[3]^((mouseline[x] & 0x10)?15:0)) & 255]; - *out++ = tc[ (q[4]^((mouseline[x] & 0x08)?15:0)) & 255]; - *out++ = tc[ (q[5]^((mouseline[x] & 0x04)?15:0)) & 255]; - *out++ = tc[ (q[6]^((mouseline[x] & 0x02)?15:0)) & 255]; - *out++ = tc[ (q[7]^((mouseline[x] & 0x01)?15:0)) & 255]; + for (x = 0; x < 80; x++, bp++, q += 8) { + if (*bp & 0x80000000) { + *out++ = tc[ (q[0]^((mouseline[x] & 0x80)?15:0)) & 255]; + *out++ = tc[ (q[1]^((mouseline[x] & 0x40)?15:0)) & 255]; + *out++ = tc[ (q[2]^((mouseline[x] & 0x20)?15:0)) & 255]; + *out++ = tc[ (q[3]^((mouseline[x] & 0x10)?15:0)) & 255]; + *out++ = tc[ (q[4]^((mouseline[x] & 0x08)?15:0)) & 255]; + *out++ = tc[ (q[5]^((mouseline[x] & 0x04)?15:0)) & 255]; + *out++ = tc[ (q[6]^((mouseline[x] & 0x02)?15:0)) & 255]; + *out++ = tc[ (q[7]^((mouseline[x] & 0x01)?15:0)) & 255]; - } else if (*bp & 0x40000000) { - /* half-width character */ - fg = (*bp >> 22) & 15; - bg = (*bp >> 18) & 15; - dg = hf[ _unpack_halfw((*bp >> 7) & 127) << 2]; - if (!(ry & 1)) - dg = (dg >> 4); - dg ^= mouseline[x]; + } else if (*bp & 0x40000000) { + /* half-width character */ + fg = (*bp >> 22) & 15; + bg = (*bp >> 18) & 15; + dg = hf[ _unpack_halfw((*bp >> 7) & 127) << 2]; + if (!(ry & 1)) + dg = (dg >> 4); + dg ^= mouseline[x]; - *out++ = tc[(dg & 0x8) ? fg : bg]; - *out++ = tc[(dg & 0x4) ? fg : bg]; - *out++ = tc[(dg & 0x2) ? fg : bg]; - *out++ = tc[(dg & 0x1) ? fg : bg]; - fg = (*bp >> 26) & 15; - bg = (*bp >> 14) & 15; - dg = hf[ _unpack_halfw((*bp) & 127) << 2]; - if (!(ry & 1)) - dg = (dg >> 4); - dg ^= mouseline[x]; + *out++ = tc[(dg & 0x8) ? fg : bg]; + *out++ = tc[(dg & 0x4) ? fg : bg]; + *out++ = tc[(dg & 0x2) ? fg : bg]; + *out++ = tc[(dg & 0x1) ? fg : bg]; + fg = (*bp >> 26) & 15; + bg = (*bp >> 14) & 15; + dg = hf[ _unpack_halfw((*bp) & 127) << 2]; + if (!(ry & 1)) + dg = (dg >> 4); + dg ^= mouseline[x]; - *out++ = tc[(dg & 0x8) ? fg : bg]; - *out++ = tc[(dg & 0x4) ? fg : bg]; - *out++ = tc[(dg & 0x2) ? fg : bg]; - *out++ = tc[(dg & 0x1) ? fg : bg]; - } else { - /* regular character */ - fg = (*bp & 0x0F00) >> 8; - bg = (*bp & 0xF000) >> 12; - if (*bp & 0x10000000 && (*bp & 0x80)) { - dg = bios[(*bp & 0x7F)<< 3]; - } else if (*bp & 0x10000000) { - dg = bioslow[(*bp & 0x7F)<< 3]; - } else { - dg = itf[(*bp & 0xFF)<< 3]; - } - dg ^= mouseline[x]; - if (!(*bp & 0xFF)) - fg = 3; - *out++ = tc[(dg & 0x80) ? fg : bg]; - *out++ = tc[(dg & 0x40) ? fg : bg]; - *out++ = tc[(dg & 0x20) ? fg : bg]; - *out++ = tc[(dg & 0x10) ? fg : bg]; - *out++ = tc[(dg & 0x8) ? fg : bg]; - *out++ = tc[(dg & 0x4) ? fg : bg]; - *out++ = tc[(dg & 0x2) ? fg : bg]; - *out++ = tc[(dg & 0x1) ? fg : bg]; - } - } + *out++ = tc[(dg & 0x8) ? fg : bg]; + *out++ = tc[(dg & 0x4) ? fg : bg]; + *out++ = tc[(dg & 0x2) ? fg : bg]; + *out++ = tc[(dg & 0x1) ? fg : bg]; + } else { + /* regular character */ + fg = (*bp & 0x0F00) >> 8; + bg = (*bp & 0xF000) >> 12; + if (*bp & 0x10000000 && (*bp & 0x80)) { + dg = bios[(*bp & 0x7F)<< 3]; + } else if (*bp & 0x10000000) { + dg = bioslow[(*bp & 0x7F)<< 3]; + } else { + dg = itf[(*bp & 0xFF)<< 3]; + } + dg ^= mouseline[x]; + if (!(*bp & 0xFF)) + fg = 3; + *out++ = tc[(dg & 0x80) ? fg : bg]; + *out++ = tc[(dg & 0x40) ? fg : bg]; + *out++ = tc[(dg & 0x20) ? fg : bg]; + *out++ = tc[(dg & 0x10) ? fg : bg]; + *out++ = tc[(dg & 0x8) ? fg : bg]; + *out++ = tc[(dg & 0x4) ? fg : bg]; + *out++ = tc[(dg & 0x2) ? fg : bg]; + *out++ = tc[(dg & 0x1) ? fg : bg]; + } + } } diff -Nru schism-0+20110101/include/video.h schism-20160521/include/video.h --- schism-0+20110101/include/video.h 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/include/video.h 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -29,12 +29,12 @@ void vgamem_clear(void); struct vgamem_overlay { - unsigned int x1, y1, x2, y2; /* in character cells... */ + unsigned int x1, y1, x2, y2; /* in character cells... */ - unsigned char *q; /* points inside ovl */ - unsigned int skip; + unsigned char *q; /* points inside ovl */ + unsigned int skip; - int width, height; /* in pixels; signed to avoid bugs elsewhere */ + int width, height; /* in pixels; signed to avoid bugs elsewhere */ }; void vgamem_lock(void); @@ -65,7 +65,7 @@ void video_resize(unsigned int width, unsigned int height); void video_fullscreen(int tri); void video_translate(unsigned int vx, unsigned int vy, - unsigned int *x, unsigned int *y); + unsigned int *x, unsigned int *y); void video_blit(void); void video_mousecursor(int z); int video_mousecursor_visible(void); diff -Nru schism-0+20110101/INSTALL schism-20160521/INSTALL --- schism-0+20110101/INSTALL 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/INSTALL 1970-01-01 00:00:00.000000000 +0000 @@ -1,302 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. - - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -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. - - 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. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. 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. - - 6. Often, you can also type `make uninstall' to remove the installed - files again. - -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 `..'. - - 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'. - - 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. - - 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'. - -Optional Features -================= - - 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. - -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. - diff -Nru schism-0+20110101/install-sh schism-20160521/install-sh --- schism-0+20110101/install-sh 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/install-sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,520 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2009-04-28.21; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - -*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# 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: diff -Nru schism-0+20110101/Makefile.am schism-20160521/Makefile.am --- schism-0+20110101/Makefile.am 2011-01-01 21:43:27.000000000 +0000 +++ schism-20160521/Makefile.am 2016-05-21 14:40:41.000000000 +0000 @@ -83,24 +83,6 @@ $(sysfiles) \ $(scripts) - -## The following files are available from the hg repository but are deliberately NOT being included in -## the static packages, either because they are used to generate other source files which are already -## included, or because they are of limited use without a repository. -## -## - .hgignore -## - .hgtags -## - fmt/mp3.c -## - fmt/ogg.c -## - fmt/sid.c -## - schism/isysev.c -## - schism/tree.c -## - sys/wii/data/* -## -## To get a rough list of files that aren't listed here: -## $ for f in `hg manifest`; do grep -Fq $f Makefile.am || echo $f; done - - bin_PROGRAMS = schismtracker noinst_HEADERS = \ @@ -203,13 +185,8 @@ endif if HAVE_WINDRES -## This got ugly. -if USE_MERCURIAL -wrcflags_version = -DWRC_VERSION=0,`(cat $(hg_dirstate) /dev/null | tr - ,)` -else -## this is assuming PACKAGE_VERSION is either 'hg' or YYYYMMDD -wrcflags_version = -DWRC_VERSION=0,`(date +$(PACKAGE_VERSION)%Y%m%d | sed 's/\(hg\)\?\(....\)\(..\)\(..\).*/\2,\3,\4/')` -endif +## this is assuming PACKAGE_VERSION is YYYYMMDD +wrcflags_version = -DWRC_VERSION=0,`(date +$(PACKAGE_VERSION)%Y%m%d)` ## --use-temp-file is needed to work around stupid bugs WRCFLAGS = --use-temp-file -I. -I$(srcdir) $(cflags_version) $(wrcflags_version) .rc.$(OBJEXT): @@ -347,13 +324,13 @@ schism/version.c \ player/csndfile.c \ player/mixutil.c \ - player/dsp.c \ player/equalizer.c \ player/mixer.c \ player/filters.c \ player/fmopl.c \ player/fmpatches.c \ player/sndmix.c \ + player/opl-util.c \ player/snd_fm.c \ player/effects.c \ player/snd_gm.c \ @@ -368,19 +345,8 @@ $(files_wii) \ $(files_windres) -if USE_MERCURIAL -# used in the dependency declaration of version.o to cause rebuild after commit -# (thanks, apostrophe -- neat trick!) -hg_dirstate = auto/dirstate.check -BUILT_SOURCES = $(hg_dirstate) -$(hg_dirstate): $(top_srcdir)/.hg/dirstate - hg -R $(top_srcdir) parents --template "{date|shortdate}" >$@ -cflags_version = -DHG_VERSION=\""`(cat $(hg_dirstate) /dev/null)`"\" -endif - # have version.o rely on all files -schism/version.$(OBJEXT): $(filter-out schism/version.$(OBJEXT),$(schismtracker_OBJECTS)) $(HEADERS) $(hg_dirstate) - +schism/version.$(OBJEXT): $(filter-out schism/version.$(OBJEXT),$(schismtracker_OBJECTS)) $(HEADERS) cflags_fmopl=-DHAS_YM3812=1 -DHAS_Y8950=0 -DHAS_YM3526=0 @@ -393,3 +359,7 @@ schismtracker_DEPENDENCIES = $(files_windres) schismtracker_LDADD = $(lib_asound) $(lib_win32) $(SDL_LIBS) $(LIBM) +if ! USE_WIN32 +schismtracker_LDADD += -ldl +endif + diff -Nru schism-0+20110101/Makefile.in schism-20160521/Makefile.in --- schism-0+20110101/Makefile.in 2011-01-01 21:51:33.000000000 +0000 +++ schism-20160521/Makefile.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,1777 +0,0 @@ -# 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@ -target_triplet = @target@ -bin_PROGRAMS = schismtracker$(EXEEXT) -@USE_X11_TRUE@@USE_XV_TRUE@am__append_1 = sys/x11/xv.c -@USE_X11_TRUE@@USE_XV_TRUE@am__append_2 = -DUSE_XV -@NEED_ASPRINTF_TRUE@am__append_3 = sys/stdlib/asprintf.c -@NEED_VASPRINTF_TRUE@am__append_4 = sys/stdlib/vasprintf.c -@NEED_MEMCMP_TRUE@am__append_5 = sys/stdlib/memcmp.c -@NEED_STRPTIME_TRUE@am__append_6 = sys/stdlib/strptime.c -@NEED_MKSTEMP_TRUE@am__append_7 = sys/stdlib/mkstemp.c -subdir = . -DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \ - $(noinst_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(top_srcdir)/configure AUTHORS COPYING \ - INSTALL NEWS TODO compile config.guess config.sub depcomp \ - install-sh missing -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -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_HEADER = config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" -PROGRAMS = $(bin_PROGRAMS) -am__schismtracker_SOURCES_DIST = schism/page_blank.c schism/charset.c \ - schism/sample-edit.c schism/dmoz.c schism/page_info.c \ - schism/page.c schism/page_palette.c schism/page_instruments.c \ - schism/page_log.c schism/page_about.c schism/pattern-view.c \ - schism/xpmdata.c schism/menu.c schism/volume-core.c \ - schism/disko.c schism/page_loadinst.c schism/mplink.c \ - schism/clippy.c schism/page_loadmodule.c schism/page_vars.c \ - schism/palettes.c fmt/compression.c fmt/generic.c fmt/mmcmp.c \ - fmt/669.c fmt/aiff.c fmt/ams.c fmt/au.c fmt/f2r.c fmt/far.c \ - fmt/imf.c fmt/it.c fmt/iti.c fmt/its.c fmt/liq.c fmt/mdl.c \ - fmt/med.c fmt/mf.c fmt/mid.c fmt/mod.c fmt/mt2.c fmt/mtm.c \ - fmt/mus.c fmt/ntk.c fmt/okt.c fmt/pat.c fmt/raw.c fmt/s3i.c \ - fmt/s3m.c fmt/sfx.c fmt/stm.c fmt/ult.c fmt/wav.c fmt/xi.c \ - fmt/xm.c schism/util.c schism/page_midi.c schism/draw-char.c \ - schism/page_help.c schism/slurp.c schism/widget-keyhandler.c \ - schism/main.c schism/page_midiout.c schism/page_message.c \ - schism/page_loadsample.c schism/dialog.c \ - schism/page_preferences.c schism/widget.c schism/config.c \ - schism/status.c schism/video.c schism/sample-view.c \ - schism/page_patedit.c schism/page_config.c schism/keyboard.c \ - schism/page_samples.c schism/itf.c schism/page_orderpan.c \ - schism/page_waterfall.c schism/midi-core.c schism/midi-ip.c \ - schism/audio_playback.c schism/config-parser.c \ - schism/audio_loadsave.c schism/draw-misc.c schism/fakemem.c \ - schism/version.c player/csndfile.c player/mixutil.c \ - player/dsp.c player/equalizer.c player/mixer.c \ - player/filters.c player/fmopl.c player/fmpatches.c \ - player/sndmix.c player/snd_fm.c player/effects.c \ - player/snd_gm.c player/tables.c sys/macosx/macosx-sdlmain.m \ - sys/macosx/ibook-support.c sys/macosx/midi-macosx.c \ - sys/macosx/volume-macosx.c sys/macosx/osdefs.c sys/alsa/init.c \ - sys/alsa/volume-alsa.c sys/alsa/midi-alsa.c \ - sys/oss/volume-oss.c sys/oss/midi-oss.c sys/win32/osdefs.c \ - sys/win32/slurp-win32.c sys/win32/volume-win32mm.c \ - sys/win32/midi-win32mm.c sys/win32/filetype.c \ - sys/win32/localtime_r.c sys/x11/xscreensaver.c sys/x11/xkb.c \ - sys/x11/xv.c sys/stdlib/asprintf.c sys/stdlib/vasprintf.c \ - sys/stdlib/memcmp.c sys/stdlib/strptime.c sys/stdlib/mkstemp.c \ - sys/posix/slurp-mmap.c sys/wii/isfs.c sys/wii/osdefs.c \ - sys/win32/schismres.rc -am__dirstamp = $(am__leading_dot)dirstamp -@USE_MACOSX_TRUE@am__objects_1 = sys/macosx/macosx-sdlmain.$(OBJEXT) \ -@USE_MACOSX_TRUE@ sys/macosx/ibook-support.$(OBJEXT) \ -@USE_MACOSX_TRUE@ sys/macosx/midi-macosx.$(OBJEXT) \ -@USE_MACOSX_TRUE@ sys/macosx/volume-macosx.$(OBJEXT) \ -@USE_MACOSX_TRUE@ sys/macosx/osdefs.$(OBJEXT) -@USE_ALSA_TRUE@am__objects_2 = sys/alsa/init.$(OBJEXT) \ -@USE_ALSA_TRUE@ sys/alsa/volume-alsa.$(OBJEXT) \ -@USE_ALSA_TRUE@ sys/alsa/midi-alsa.$(OBJEXT) -@USE_OSS_TRUE@am__objects_3 = sys/oss/volume-oss.$(OBJEXT) \ -@USE_OSS_TRUE@ sys/oss/midi-oss.$(OBJEXT) -@USE_WIN32_TRUE@am__objects_4 = sys/win32/osdefs.$(OBJEXT) \ -@USE_WIN32_TRUE@ sys/win32/slurp-win32.$(OBJEXT) \ -@USE_WIN32_TRUE@ sys/win32/volume-win32mm.$(OBJEXT) \ -@USE_WIN32_TRUE@ sys/win32/midi-win32mm.$(OBJEXT) \ -@USE_WIN32_TRUE@ sys/win32/filetype.$(OBJEXT) \ -@USE_WIN32_TRUE@ sys/win32/localtime_r.$(OBJEXT) -@USE_X11_TRUE@@USE_XV_TRUE@am__objects_5 = sys/x11/xv.$(OBJEXT) -@USE_X11_TRUE@am__objects_6 = sys/x11/xscreensaver.$(OBJEXT) \ -@USE_X11_TRUE@ sys/x11/xkb.$(OBJEXT) $(am__objects_5) -@NEED_ASPRINTF_TRUE@am__objects_7 = sys/stdlib/asprintf.$(OBJEXT) -@NEED_VASPRINTF_TRUE@am__objects_8 = sys/stdlib/vasprintf.$(OBJEXT) -@NEED_MEMCMP_TRUE@am__objects_9 = sys/stdlib/memcmp.$(OBJEXT) -@NEED_STRPTIME_TRUE@am__objects_10 = sys/stdlib/strptime.$(OBJEXT) -@NEED_MKSTEMP_TRUE@am__objects_11 = sys/stdlib/mkstemp.$(OBJEXT) -am__objects_12 = $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) -@USE_MMAP_TRUE@am__objects_13 = sys/posix/slurp-mmap.$(OBJEXT) -@USE_WII_TRUE@am__objects_14 = sys/wii/isfs.$(OBJEXT) \ -@USE_WII_TRUE@ sys/wii/osdefs.$(OBJEXT) -@HAVE_WINDRES_TRUE@am__objects_15 = sys/win32/schismres.$(OBJEXT) -am_schismtracker_OBJECTS = schism/page_blank.$(OBJEXT) \ - schism/charset.$(OBJEXT) schism/sample-edit.$(OBJEXT) \ - schism/dmoz.$(OBJEXT) schism/page_info.$(OBJEXT) \ - schism/page.$(OBJEXT) schism/page_palette.$(OBJEXT) \ - schism/page_instruments.$(OBJEXT) schism/page_log.$(OBJEXT) \ - schism/page_about.$(OBJEXT) schism/pattern-view.$(OBJEXT) \ - schism/xpmdata.$(OBJEXT) schism/menu.$(OBJEXT) \ - schism/volume-core.$(OBJEXT) schism/disko.$(OBJEXT) \ - schism/page_loadinst.$(OBJEXT) schism/mplink.$(OBJEXT) \ - schism/clippy.$(OBJEXT) schism/page_loadmodule.$(OBJEXT) \ - schism/page_vars.$(OBJEXT) schism/palettes.$(OBJEXT) \ - fmt/compression.$(OBJEXT) fmt/generic.$(OBJEXT) \ - fmt/mmcmp.$(OBJEXT) fmt/669.$(OBJEXT) fmt/aiff.$(OBJEXT) \ - fmt/ams.$(OBJEXT) fmt/au.$(OBJEXT) fmt/f2r.$(OBJEXT) \ - fmt/far.$(OBJEXT) fmt/imf.$(OBJEXT) fmt/it.$(OBJEXT) \ - fmt/iti.$(OBJEXT) fmt/its.$(OBJEXT) fmt/liq.$(OBJEXT) \ - fmt/mdl.$(OBJEXT) fmt/med.$(OBJEXT) fmt/mf.$(OBJEXT) \ - fmt/mid.$(OBJEXT) fmt/mod.$(OBJEXT) fmt/mt2.$(OBJEXT) \ - fmt/mtm.$(OBJEXT) fmt/mus.$(OBJEXT) fmt/ntk.$(OBJEXT) \ - fmt/okt.$(OBJEXT) fmt/pat.$(OBJEXT) fmt/raw.$(OBJEXT) \ - fmt/s3i.$(OBJEXT) fmt/s3m.$(OBJEXT) fmt/sfx.$(OBJEXT) \ - fmt/stm.$(OBJEXT) fmt/ult.$(OBJEXT) fmt/wav.$(OBJEXT) \ - fmt/xi.$(OBJEXT) fmt/xm.$(OBJEXT) schism/util.$(OBJEXT) \ - schism/page_midi.$(OBJEXT) schism/draw-char.$(OBJEXT) \ - schism/page_help.$(OBJEXT) schism/slurp.$(OBJEXT) \ - schism/widget-keyhandler.$(OBJEXT) schism/main.$(OBJEXT) \ - schism/page_midiout.$(OBJEXT) schism/page_message.$(OBJEXT) \ - schism/page_loadsample.$(OBJEXT) schism/dialog.$(OBJEXT) \ - schism/page_preferences.$(OBJEXT) schism/widget.$(OBJEXT) \ - schism/config.$(OBJEXT) schism/status.$(OBJEXT) \ - schism/video.$(OBJEXT) schism/sample-view.$(OBJEXT) \ - schism/page_patedit.$(OBJEXT) schism/page_config.$(OBJEXT) \ - schism/keyboard.$(OBJEXT) schism/page_samples.$(OBJEXT) \ - schism/itf.$(OBJEXT) schism/page_orderpan.$(OBJEXT) \ - schism/page_waterfall.$(OBJEXT) schism/midi-core.$(OBJEXT) \ - schism/midi-ip.$(OBJEXT) schism/audio_playback.$(OBJEXT) \ - schism/config-parser.$(OBJEXT) schism/audio_loadsave.$(OBJEXT) \ - schism/draw-misc.$(OBJEXT) schism/fakemem.$(OBJEXT) \ - schism/version.$(OBJEXT) player/csndfile.$(OBJEXT) \ - player/mixutil.$(OBJEXT) player/dsp.$(OBJEXT) \ - player/equalizer.$(OBJEXT) player/mixer.$(OBJEXT) \ - player/filters.$(OBJEXT) player/fmopl.$(OBJEXT) \ - player/fmpatches.$(OBJEXT) player/sndmix.$(OBJEXT) \ - player/snd_fm.$(OBJEXT) player/effects.$(OBJEXT) \ - player/snd_gm.$(OBJEXT) player/tables.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_6) $(am__objects_12) \ - $(am__objects_13) $(am__objects_14) $(am__objects_15) -nodist_schismtracker_OBJECTS = auto/default-font.$(OBJEXT) \ - auto/helptext.$(OBJEXT) -schismtracker_OBJECTS = $(am_schismtracker_OBJECTS) \ - $(nodist_schismtracker_OBJECTS) -am__DEPENDENCIES_1 = -SCRIPTS = $(noinst_SCRIPTS) -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) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -OBJCCOMPILE = $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_OBJCFLAGS) $(OBJCFLAGS) -OBJCLD = $(OBJC) -OBJCLINK = $(OBJCLD) $(AM_OBJCFLAGS) $(OBJCFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(schismtracker_SOURCES) $(nodist_schismtracker_SOURCES) -DIST_SOURCES = $(am__schismtracker_SOURCES_DIST) -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' -man1dir = $(mandir)/man1 -NROFF = nroff -MANS = $(dist_man_MANS) -HEADERS = $(noinst_HEADERS) -ETAGS = etags -CTAGS = ctags -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)"; }; } -GZIP_ENV = --best -DIST_ARCHIVES = $(distdir).tar.bz2 -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBM = @LIBM@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJC = @OBJC@ -OBJCFLAGS = @OBJCFLAGS@ -OBJEXT = @OBJEXT@ -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@ -PYTHON = @PYTHON@ -PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ -PYTHON_PLATFORM = @PYTHON_PLATFORM@ -PYTHON_PREFIX = @PYTHON_PREFIX@ -PYTHON_VERSION = @PYTHON_VERSION@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -XMKMF = @XMKMF@ -X_CFLAGS = @X_CFLAGS@ -X_EXTRA_LIBS = @X_EXTRA_LIBS@ -X_LIBS = @X_LIBS@ -X_PRE_LIBS = @X_PRE_LIBS@ -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@ -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@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgpyexecdir = @pkgpyexecdir@ -pkgpythondir = @pkgpythondir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -pyexecdir = @pyexecdir@ -pythondir = @pythondir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = foreign dist-bzip2 no-dist-gzip -helptexts = \ - helptext/global-keys \ - helptext/copyright \ - helptext/info-page \ - helptext/instrument-list \ - helptext/message-editor \ - helptext/midi-output \ - helptext/orderlist-pan \ - helptext/orderlist-vol \ - helptext/pattern-editor \ - helptext/adlib-sample \ - helptext/sample-list - -fonts = \ - font/default-lower.fnt \ - font/default-upper-alt.fnt \ - font/default-upper-itf.fnt \ - font/half-width.fnt - -icons = \ - icons/appIcon.icns \ - icons/moduleIcon.icns \ - icons/schism-file-128.png \ - icons/schism-icon-128.png \ - icons/schism-icon-16.png \ - icons/schism-icon-192.png \ - icons/schism-icon-22.png \ - icons/schism-icon-24.png \ - icons/schism-icon-32.png \ - icons/schism-icon-36.png \ - icons/schism-icon-48.png \ - icons/schism-icon-64.png \ - icons/schism-icon-72.png \ - icons/schism-icon-96.png \ - icons/schism-icon.svg \ - icons/schism-itf-icon-128.png \ - icons/schism-itf-icon-16.png \ - icons/schism-itf-icon-192.png \ - icons/schism-itf-icon-22.png \ - icons/schism-itf-icon-24.png \ - icons/schism-itf-icon-32.png \ - icons/schism-itf-icon-36.png \ - icons/schism-itf-icon-48.png \ - icons/schism-itf-icon-64.png \ - icons/schism-itf-icon-72.png \ - icons/schism-itf-icon-96.png \ - icons/schism-itf-icon.svg \ - icons/it_logo.png \ - icons/schism_logo.png \ - icons/schismres.ico - -sysfiles = \ - sys/fd.org/autopackage.apspec \ - sys/fd.org/itf.desktop \ - sys/fd.org/schism.desktop \ - sys/macosx/Schism_Tracker.app/Contents/Info.plist \ - sys/macosx/Schism_Tracker.app/Contents/PkgInfo \ - sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist \ - sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns \ - sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns \ - sys/win32/schism.nsis \ - sys/wii/schismtracker/icon.png \ - sys/wii/schismtracker/meta.xml \ - sys/sdl/README - -scripts = \ - scripts/bin2h.sh \ - scripts/build-font.sh \ - scripts/genhelp.py \ - scripts/itf2half.py \ - scripts/half2itf.py \ - scripts/itcfg.py \ - scripts/itmidicfg.py \ - scripts/lutgen.c \ - scripts/palette.py - -EXTRA_DIST = \ - include/auto/README \ - $(helptexts) \ - $(fonts) \ - $(icons) \ - $(sysfiles) \ - $(scripts) - -noinst_HEADERS = \ - include/auto/logoit.h \ - include/auto/logoschism.h \ - include/auto/schismico.h \ - include/charset.h \ - include/clippy.h \ - include/cmixer.h \ - include/config-parser.h \ - include/disko.h \ - include/dmoz.h \ - include/draw-char.h \ - include/event.h \ - include/fmopl.h \ - include/fmt.h \ - include/fmt-types.h \ - include/headers.h \ - include/it_defs.h \ - include/it.h \ - include/log.h \ - include/midi.h \ - include/osdefs.h \ - include/page.h \ - include/pattern-view.h \ - include/precomp_lut.h \ - include/sample-edit.h \ - include/sdlmain.h \ - include/slurp.h \ - include/sndfile.h \ - include/snd_fm.h \ - include/snd_gm.h \ - include/song.h \ - include/tables.h \ - include/tree.h \ - include/util.h \ - include/version.h \ - include/vgamem-scanner.h \ - include/video.h \ - sys/wii/isfs.h \ - sys/wii/certs_bin.h \ - sys/wii/su_tik_bin.h \ - sys/wii/su_tmd_bin.h \ - sys/win32/wine-ddraw.h - -dist_man_MANS = sys/posix/schismtracker.1 -noinst_SCRIPTS = $(scripts) -nodist_schismtracker_SOURCES = \ - auto/default-font.c \ - auto/helptext.c - -CLEANFILES = \ - auto/default-font.c \ - auto/helptext.c - -@USE_X11_TRUE@files_x11 = sys/x11/xscreensaver.c sys/x11/xkb.c \ -@USE_X11_TRUE@ $(am__append_1) -@USE_X11_TRUE@cflags_x11 = -DUSE_X11 $(am__append_2) -@USE_ALSA_TRUE@files_alsa = sys/alsa/init.c sys/alsa/volume-alsa.c sys/alsa/midi-alsa.c -@USE_ALSA_DLTRICK_FALSE@@USE_ALSA_TRUE@cflags_alsa = -DUSE_ALSA -@USE_ALSA_DLTRICK_TRUE@@USE_ALSA_TRUE@cflags_alsa = -DUSE_ALSA -DUSE_DLTRICK_ALSA -@USE_ALSA_DLTRICK_FALSE@@USE_ALSA_TRUE@lib_asound = -lasound -@USE_OSS_TRUE@files_oss = sys/oss/volume-oss.c sys/oss/midi-oss.c -@USE_OSS_TRUE@cflags_oss = -DUSE_OSS -@USE_MMAP_TRUE@files_mmap = sys/posix/slurp-mmap.c -@USE_WIN32_TRUE@files_win32 = \ -@USE_WIN32_TRUE@ sys/win32/osdefs.c \ -@USE_WIN32_TRUE@ sys/win32/slurp-win32.c \ -@USE_WIN32_TRUE@ sys/win32/volume-win32mm.c \ -@USE_WIN32_TRUE@ sys/win32/midi-win32mm.c \ -@USE_WIN32_TRUE@ sys/win32/filetype.c \ -@USE_WIN32_TRUE@ sys/win32/localtime_r.c - -@USE_WIN32_TRUE@cflags_win32 = -I$(srcdir)/sys/win32 -@USE_WIN32_TRUE@lib_win32 = -lwinmm -@HAVE_WINDRES_TRUE@@USE_MERCURIAL_FALSE@wrcflags_version = -DWRC_VERSION=0,`(date +$(PACKAGE_VERSION)%Y%m%d | sed 's/\(hg\)\?\(....\)\(..\)\(..\).*/\2,\3,\4/')` -@HAVE_WINDRES_TRUE@@USE_MERCURIAL_TRUE@wrcflags_version = -DWRC_VERSION=0,`(cat $(hg_dirstate) /dev/null | tr - ,)` -@HAVE_WINDRES_TRUE@WRCFLAGS = --use-temp-file -I. -I$(srcdir) $(cflags_version) $(wrcflags_version) -@HAVE_WINDRES_TRUE@files_windres = sys/win32/schismres.rc -@USE_WII_TRUE@files_wii = sys/wii/isfs.c sys/wii/osdefs.c -@USE_WII_TRUE@cflags_wii = -I$(srcdir)/sys/wii -@USE_MACOSX_TRUE@files_macosx = \ -@USE_MACOSX_TRUE@ sys/macosx/macosx-sdlmain.m \ -@USE_MACOSX_TRUE@ sys/macosx/ibook-support.c \ -@USE_MACOSX_TRUE@ sys/macosx/midi-macosx.c \ -@USE_MACOSX_TRUE@ sys/macosx/volume-macosx.c \ -@USE_MACOSX_TRUE@ sys/macosx/osdefs.c - -@USE_NETWORK_TRUE@cflags_network = -DUSE_NETWORK -files_stdlib = $(am__append_3) $(am__append_4) $(am__append_5) \ - $(am__append_6) $(am__append_7) -schismtracker_SOURCES = \ - schism/page_blank.c \ - schism/charset.c \ - schism/sample-edit.c \ - schism/dmoz.c \ - schism/page_info.c \ - schism/page.c \ - schism/page_palette.c \ - schism/page_instruments.c \ - schism/page_log.c \ - schism/page_about.c \ - schism/pattern-view.c \ - schism/xpmdata.c \ - schism/menu.c \ - schism/volume-core.c \ - schism/disko.c \ - schism/page_loadinst.c \ - schism/mplink.c \ - schism/clippy.c \ - schism/page_loadmodule.c \ - schism/page_vars.c \ - schism/palettes.c \ - fmt/compression.c \ - fmt/generic.c \ - fmt/mmcmp.c \ - fmt/669.c \ - fmt/aiff.c \ - fmt/ams.c \ - fmt/au.c \ - fmt/f2r.c \ - fmt/far.c \ - fmt/imf.c \ - fmt/it.c \ - fmt/iti.c \ - fmt/its.c \ - fmt/liq.c \ - fmt/mdl.c \ - fmt/med.c \ - fmt/mf.c \ - fmt/mid.c \ - fmt/mod.c \ - fmt/mt2.c \ - fmt/mtm.c \ - fmt/mus.c \ - fmt/ntk.c \ - fmt/okt.c \ - fmt/pat.c \ - fmt/raw.c \ - fmt/s3i.c \ - fmt/s3m.c \ - fmt/sfx.c \ - fmt/stm.c \ - fmt/ult.c \ - fmt/wav.c \ - fmt/xi.c \ - fmt/xm.c \ - schism/util.c \ - schism/page_midi.c \ - schism/draw-char.c \ - schism/page_help.c \ - schism/slurp.c \ - schism/widget-keyhandler.c \ - schism/main.c \ - schism/page_midiout.c \ - schism/page_message.c \ - schism/page_loadsample.c \ - schism/dialog.c \ - schism/page_preferences.c \ - schism/widget.c \ - schism/config.c \ - schism/status.c \ - schism/video.c \ - schism/sample-view.c \ - schism/page_patedit.c \ - schism/page_config.c \ - schism/keyboard.c \ - schism/page_samples.c \ - schism/itf.c \ - schism/page_orderpan.c \ - schism/page_waterfall.c \ - schism/midi-core.c \ - schism/midi-ip.c \ - schism/audio_playback.c \ - schism/config-parser.c \ - schism/audio_loadsave.c \ - schism/draw-misc.c \ - schism/fakemem.c \ - schism/version.c \ - player/csndfile.c \ - player/mixutil.c \ - player/dsp.c \ - player/equalizer.c \ - player/mixer.c \ - player/filters.c \ - player/fmopl.c \ - player/fmpatches.c \ - player/sndmix.c \ - player/snd_fm.c \ - player/effects.c \ - player/snd_gm.c \ - player/tables.c \ - $(files_macosx) \ - $(files_alsa) \ - $(files_oss) \ - $(files_win32) \ - $(files_x11) \ - $(files_stdlib) \ - $(files_mmap) \ - $(files_wii) \ - $(files_windres) - - -# used in the dependency declaration of version.o to cause rebuild after commit -# (thanks, apostrophe -- neat trick!) -@USE_MERCURIAL_TRUE@hg_dirstate = auto/dirstate.check -@USE_MERCURIAL_TRUE@BUILT_SOURCES = $(hg_dirstate) -@USE_MERCURIAL_TRUE@cflags_version = -DHG_VERSION=\""`(cat $(hg_dirstate) /dev/null)`"\" -cflags_fmopl = -DHAS_YM3812=1 -DHAS_Y8950=0 -DHAS_YM3526=0 -AM_CPPFLAGS = -D_USE_AUTOCONF -D_GNU_SOURCE -I$(srcdir)/include -I. -AM_CFLAGS = $(SDL_CFLAGS) $(cflags_alsa) $(cflags_oss) \ - $(cflags_network) $(cflags_x11) $(cflags_fmopl) \ - $(cflags_version) $(cflags_win32) $(cflags_wii) - -AM_OBJCFLAGS = $(AM_CFLAGS) -schismtracker_DEPENDENCIES = $(files_windres) -schismtracker_LDADD = $(lib_asound) $(lib_win32) $(SDL_LIBS) $(LIBM) -all: $(BUILT_SOURCES) config.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -.SUFFIXES: .$(OBJEXT) .c .m .o .obj .rc -am--refresh: - @: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign 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: $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -schism/$(am__dirstamp): - @$(MKDIR_P) schism - @: > schism/$(am__dirstamp) -schism/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) schism/$(DEPDIR) - @: > schism/$(DEPDIR)/$(am__dirstamp) -schism/page_blank.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/charset.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/sample-edit.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/dmoz.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_info.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_palette.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_instruments.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_log.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_about.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/pattern-view.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/xpmdata.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/menu.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/volume-core.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/disko.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_loadinst.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/mplink.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/clippy.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_loadmodule.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_vars.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/palettes.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -fmt/$(am__dirstamp): - @$(MKDIR_P) fmt - @: > fmt/$(am__dirstamp) -fmt/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) fmt/$(DEPDIR) - @: > fmt/$(DEPDIR)/$(am__dirstamp) -fmt/compression.$(OBJEXT): fmt/$(am__dirstamp) \ - fmt/$(DEPDIR)/$(am__dirstamp) -fmt/generic.$(OBJEXT): fmt/$(am__dirstamp) \ - fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mmcmp.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/669.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/aiff.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/ams.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/au.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/f2r.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/far.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/imf.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/it.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/iti.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/its.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/liq.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mdl.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/med.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mf.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mid.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mod.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mt2.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mtm.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/mus.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/ntk.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/okt.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/pat.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/raw.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/s3i.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/s3m.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/sfx.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/stm.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/ult.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/wav.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/xi.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -fmt/xm.$(OBJEXT): fmt/$(am__dirstamp) fmt/$(DEPDIR)/$(am__dirstamp) -schism/util.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_midi.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/draw-char.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_help.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/slurp.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/widget-keyhandler.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/main.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_midiout.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_message.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_loadsample.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/dialog.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_preferences.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/widget.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/config.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/status.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/video.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/sample-view.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_patedit.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_config.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/keyboard.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_samples.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/itf.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_orderpan.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/page_waterfall.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/midi-core.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/midi-ip.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/audio_playback.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/config-parser.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/audio_loadsave.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/draw-misc.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/fakemem.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -schism/version.$(OBJEXT): schism/$(am__dirstamp) \ - schism/$(DEPDIR)/$(am__dirstamp) -player/$(am__dirstamp): - @$(MKDIR_P) player - @: > player/$(am__dirstamp) -player/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) player/$(DEPDIR) - @: > player/$(DEPDIR)/$(am__dirstamp) -player/csndfile.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/mixutil.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/dsp.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/equalizer.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/mixer.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/filters.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/fmopl.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/fmpatches.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/sndmix.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/snd_fm.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/effects.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/snd_gm.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -player/tables.$(OBJEXT): player/$(am__dirstamp) \ - player/$(DEPDIR)/$(am__dirstamp) -sys/macosx/$(am__dirstamp): - @$(MKDIR_P) sys/macosx - @: > sys/macosx/$(am__dirstamp) -sys/macosx/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/macosx/$(DEPDIR) - @: > sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/macosx/macosx-sdlmain.$(OBJEXT): sys/macosx/$(am__dirstamp) \ - sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/macosx/ibook-support.$(OBJEXT): sys/macosx/$(am__dirstamp) \ - sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/macosx/midi-macosx.$(OBJEXT): sys/macosx/$(am__dirstamp) \ - sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/macosx/volume-macosx.$(OBJEXT): sys/macosx/$(am__dirstamp) \ - sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/macosx/osdefs.$(OBJEXT): sys/macosx/$(am__dirstamp) \ - sys/macosx/$(DEPDIR)/$(am__dirstamp) -sys/alsa/$(am__dirstamp): - @$(MKDIR_P) sys/alsa - @: > sys/alsa/$(am__dirstamp) -sys/alsa/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/alsa/$(DEPDIR) - @: > sys/alsa/$(DEPDIR)/$(am__dirstamp) -sys/alsa/init.$(OBJEXT): sys/alsa/$(am__dirstamp) \ - sys/alsa/$(DEPDIR)/$(am__dirstamp) -sys/alsa/volume-alsa.$(OBJEXT): sys/alsa/$(am__dirstamp) \ - sys/alsa/$(DEPDIR)/$(am__dirstamp) -sys/alsa/midi-alsa.$(OBJEXT): sys/alsa/$(am__dirstamp) \ - sys/alsa/$(DEPDIR)/$(am__dirstamp) -sys/oss/$(am__dirstamp): - @$(MKDIR_P) sys/oss - @: > sys/oss/$(am__dirstamp) -sys/oss/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/oss/$(DEPDIR) - @: > sys/oss/$(DEPDIR)/$(am__dirstamp) -sys/oss/volume-oss.$(OBJEXT): sys/oss/$(am__dirstamp) \ - sys/oss/$(DEPDIR)/$(am__dirstamp) -sys/oss/midi-oss.$(OBJEXT): sys/oss/$(am__dirstamp) \ - sys/oss/$(DEPDIR)/$(am__dirstamp) -sys/win32/$(am__dirstamp): - @$(MKDIR_P) sys/win32 - @: > sys/win32/$(am__dirstamp) -sys/win32/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/win32/$(DEPDIR) - @: > sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/osdefs.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/slurp-win32.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/volume-win32mm.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/midi-win32mm.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/filetype.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/win32/localtime_r.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -sys/x11/$(am__dirstamp): - @$(MKDIR_P) sys/x11 - @: > sys/x11/$(am__dirstamp) -sys/x11/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/x11/$(DEPDIR) - @: > sys/x11/$(DEPDIR)/$(am__dirstamp) -sys/x11/xscreensaver.$(OBJEXT): sys/x11/$(am__dirstamp) \ - sys/x11/$(DEPDIR)/$(am__dirstamp) -sys/x11/xkb.$(OBJEXT): sys/x11/$(am__dirstamp) \ - sys/x11/$(DEPDIR)/$(am__dirstamp) -sys/x11/xv.$(OBJEXT): sys/x11/$(am__dirstamp) \ - sys/x11/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/$(am__dirstamp): - @$(MKDIR_P) sys/stdlib - @: > sys/stdlib/$(am__dirstamp) -sys/stdlib/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/stdlib/$(DEPDIR) - @: > sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/asprintf.$(OBJEXT): sys/stdlib/$(am__dirstamp) \ - sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/vasprintf.$(OBJEXT): sys/stdlib/$(am__dirstamp) \ - sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/memcmp.$(OBJEXT): sys/stdlib/$(am__dirstamp) \ - sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/strptime.$(OBJEXT): sys/stdlib/$(am__dirstamp) \ - sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/stdlib/mkstemp.$(OBJEXT): sys/stdlib/$(am__dirstamp) \ - sys/stdlib/$(DEPDIR)/$(am__dirstamp) -sys/posix/$(am__dirstamp): - @$(MKDIR_P) sys/posix - @: > sys/posix/$(am__dirstamp) -sys/posix/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/posix/$(DEPDIR) - @: > sys/posix/$(DEPDIR)/$(am__dirstamp) -sys/posix/slurp-mmap.$(OBJEXT): sys/posix/$(am__dirstamp) \ - sys/posix/$(DEPDIR)/$(am__dirstamp) -sys/wii/$(am__dirstamp): - @$(MKDIR_P) sys/wii - @: > sys/wii/$(am__dirstamp) -sys/wii/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) sys/wii/$(DEPDIR) - @: > sys/wii/$(DEPDIR)/$(am__dirstamp) -sys/wii/isfs.$(OBJEXT): sys/wii/$(am__dirstamp) \ - sys/wii/$(DEPDIR)/$(am__dirstamp) -sys/wii/osdefs.$(OBJEXT): sys/wii/$(am__dirstamp) \ - sys/wii/$(DEPDIR)/$(am__dirstamp) -sys/win32/schismres.$(OBJEXT): sys/win32/$(am__dirstamp) \ - sys/win32/$(DEPDIR)/$(am__dirstamp) -auto/$(am__dirstamp): - @$(MKDIR_P) auto - @: > auto/$(am__dirstamp) -auto/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) auto/$(DEPDIR) - @: > auto/$(DEPDIR)/$(am__dirstamp) -auto/default-font.$(OBJEXT): auto/$(am__dirstamp) \ - auto/$(DEPDIR)/$(am__dirstamp) -auto/helptext.$(OBJEXT): auto/$(am__dirstamp) \ - auto/$(DEPDIR)/$(am__dirstamp) -schismtracker$(EXEEXT): $(schismtracker_OBJECTS) $(schismtracker_DEPENDENCIES) - @rm -f schismtracker$(EXEEXT) - $(OBJCLINK) $(schismtracker_OBJECTS) $(schismtracker_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f auto/default-font.$(OBJEXT) - -rm -f auto/helptext.$(OBJEXT) - -rm -f fmt/669.$(OBJEXT) - -rm -f fmt/aiff.$(OBJEXT) - -rm -f fmt/ams.$(OBJEXT) - -rm -f fmt/au.$(OBJEXT) - -rm -f fmt/compression.$(OBJEXT) - -rm -f fmt/f2r.$(OBJEXT) - -rm -f fmt/far.$(OBJEXT) - -rm -f fmt/generic.$(OBJEXT) - -rm -f fmt/imf.$(OBJEXT) - -rm -f fmt/it.$(OBJEXT) - -rm -f fmt/iti.$(OBJEXT) - -rm -f fmt/its.$(OBJEXT) - -rm -f fmt/liq.$(OBJEXT) - -rm -f fmt/mdl.$(OBJEXT) - -rm -f fmt/med.$(OBJEXT) - -rm -f fmt/mf.$(OBJEXT) - -rm -f fmt/mid.$(OBJEXT) - -rm -f fmt/mmcmp.$(OBJEXT) - -rm -f fmt/mod.$(OBJEXT) - -rm -f fmt/mt2.$(OBJEXT) - -rm -f fmt/mtm.$(OBJEXT) - -rm -f fmt/mus.$(OBJEXT) - -rm -f fmt/ntk.$(OBJEXT) - -rm -f fmt/okt.$(OBJEXT) - -rm -f fmt/pat.$(OBJEXT) - -rm -f fmt/raw.$(OBJEXT) - -rm -f fmt/s3i.$(OBJEXT) - -rm -f fmt/s3m.$(OBJEXT) - -rm -f fmt/sfx.$(OBJEXT) - -rm -f fmt/stm.$(OBJEXT) - -rm -f fmt/ult.$(OBJEXT) - -rm -f fmt/wav.$(OBJEXT) - -rm -f fmt/xi.$(OBJEXT) - -rm -f fmt/xm.$(OBJEXT) - -rm -f player/csndfile.$(OBJEXT) - -rm -f player/dsp.$(OBJEXT) - -rm -f player/effects.$(OBJEXT) - -rm -f player/equalizer.$(OBJEXT) - -rm -f player/filters.$(OBJEXT) - -rm -f player/fmopl.$(OBJEXT) - -rm -f player/fmpatches.$(OBJEXT) - -rm -f player/mixer.$(OBJEXT) - -rm -f player/mixutil.$(OBJEXT) - -rm -f player/snd_fm.$(OBJEXT) - -rm -f player/snd_gm.$(OBJEXT) - -rm -f player/sndmix.$(OBJEXT) - -rm -f player/tables.$(OBJEXT) - -rm -f schism/audio_loadsave.$(OBJEXT) - -rm -f schism/audio_playback.$(OBJEXT) - -rm -f schism/charset.$(OBJEXT) - -rm -f schism/clippy.$(OBJEXT) - -rm -f schism/config-parser.$(OBJEXT) - -rm -f schism/config.$(OBJEXT) - -rm -f schism/dialog.$(OBJEXT) - -rm -f schism/disko.$(OBJEXT) - -rm -f schism/dmoz.$(OBJEXT) - -rm -f schism/draw-char.$(OBJEXT) - -rm -f schism/draw-misc.$(OBJEXT) - -rm -f schism/fakemem.$(OBJEXT) - -rm -f schism/itf.$(OBJEXT) - -rm -f schism/keyboard.$(OBJEXT) - -rm -f schism/main.$(OBJEXT) - -rm -f schism/menu.$(OBJEXT) - -rm -f schism/midi-core.$(OBJEXT) - -rm -f schism/midi-ip.$(OBJEXT) - -rm -f schism/mplink.$(OBJEXT) - -rm -f schism/page.$(OBJEXT) - -rm -f schism/page_about.$(OBJEXT) - -rm -f schism/page_blank.$(OBJEXT) - -rm -f schism/page_config.$(OBJEXT) - -rm -f schism/page_help.$(OBJEXT) - -rm -f schism/page_info.$(OBJEXT) - -rm -f schism/page_instruments.$(OBJEXT) - -rm -f schism/page_loadinst.$(OBJEXT) - -rm -f schism/page_loadmodule.$(OBJEXT) - -rm -f schism/page_loadsample.$(OBJEXT) - -rm -f schism/page_log.$(OBJEXT) - -rm -f schism/page_message.$(OBJEXT) - -rm -f schism/page_midi.$(OBJEXT) - -rm -f schism/page_midiout.$(OBJEXT) - -rm -f schism/page_orderpan.$(OBJEXT) - -rm -f schism/page_palette.$(OBJEXT) - -rm -f schism/page_patedit.$(OBJEXT) - -rm -f schism/page_preferences.$(OBJEXT) - -rm -f schism/page_samples.$(OBJEXT) - -rm -f schism/page_vars.$(OBJEXT) - -rm -f schism/page_waterfall.$(OBJEXT) - -rm -f schism/palettes.$(OBJEXT) - -rm -f schism/pattern-view.$(OBJEXT) - -rm -f schism/sample-edit.$(OBJEXT) - -rm -f schism/sample-view.$(OBJEXT) - -rm -f schism/slurp.$(OBJEXT) - -rm -f schism/status.$(OBJEXT) - -rm -f schism/util.$(OBJEXT) - -rm -f schism/version.$(OBJEXT) - -rm -f schism/video.$(OBJEXT) - -rm -f schism/volume-core.$(OBJEXT) - -rm -f schism/widget-keyhandler.$(OBJEXT) - -rm -f schism/widget.$(OBJEXT) - -rm -f schism/xpmdata.$(OBJEXT) - -rm -f sys/alsa/init.$(OBJEXT) - -rm -f sys/alsa/midi-alsa.$(OBJEXT) - -rm -f sys/alsa/volume-alsa.$(OBJEXT) - -rm -f sys/macosx/ibook-support.$(OBJEXT) - -rm -f sys/macosx/macosx-sdlmain.$(OBJEXT) - -rm -f sys/macosx/midi-macosx.$(OBJEXT) - -rm -f sys/macosx/osdefs.$(OBJEXT) - -rm -f sys/macosx/volume-macosx.$(OBJEXT) - -rm -f sys/oss/midi-oss.$(OBJEXT) - -rm -f sys/oss/volume-oss.$(OBJEXT) - -rm -f sys/posix/slurp-mmap.$(OBJEXT) - -rm -f sys/stdlib/asprintf.$(OBJEXT) - -rm -f sys/stdlib/memcmp.$(OBJEXT) - -rm -f sys/stdlib/mkstemp.$(OBJEXT) - -rm -f sys/stdlib/strptime.$(OBJEXT) - -rm -f sys/stdlib/vasprintf.$(OBJEXT) - -rm -f sys/wii/isfs.$(OBJEXT) - -rm -f sys/wii/osdefs.$(OBJEXT) - -rm -f sys/win32/filetype.$(OBJEXT) - -rm -f sys/win32/localtime_r.$(OBJEXT) - -rm -f sys/win32/midi-win32mm.$(OBJEXT) - -rm -f sys/win32/osdefs.$(OBJEXT) - -rm -f sys/win32/schismres.$(OBJEXT) - -rm -f sys/win32/slurp-win32.$(OBJEXT) - -rm -f sys/win32/volume-win32mm.$(OBJEXT) - -rm -f sys/x11/xkb.$(OBJEXT) - -rm -f sys/x11/xscreensaver.$(OBJEXT) - -rm -f sys/x11/xv.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@auto/$(DEPDIR)/default-font.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@auto/$(DEPDIR)/helptext.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/669.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/aiff.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/ams.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/au.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/compression.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/f2r.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/far.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/generic.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/imf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/it.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/iti.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/its.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/liq.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mdl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/med.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mmcmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mod.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mt2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mtm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/mus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/ntk.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/okt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/pat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/raw.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/s3i.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/s3m.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/sfx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/stm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/ult.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/wav.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/xi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@fmt/$(DEPDIR)/xm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/csndfile.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/dsp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/effects.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/equalizer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/filters.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/fmopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/fmpatches.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/mixer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/mixutil.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/snd_fm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/snd_gm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/sndmix.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@player/$(DEPDIR)/tables.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/audio_loadsave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/audio_playback.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/charset.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/clippy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/config-parser.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/dialog.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/disko.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/dmoz.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/draw-char.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/draw-misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/fakemem.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/itf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/keyboard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/menu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/midi-core.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/midi-ip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/mplink.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_about.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_blank.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_help.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_instruments.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_loadinst.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_loadmodule.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_loadsample.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_log.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_message.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_midi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_midiout.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_orderpan.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_palette.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_patedit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_preferences.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_samples.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_vars.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/page_waterfall.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/palettes.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/pattern-view.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/sample-edit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/sample-view.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/slurp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/util.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/version.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/volume-core.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/widget-keyhandler.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/widget.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@schism/$(DEPDIR)/xpmdata.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/alsa/$(DEPDIR)/init.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/alsa/$(DEPDIR)/midi-alsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/alsa/$(DEPDIR)/volume-alsa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/macosx/$(DEPDIR)/ibook-support.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/macosx/$(DEPDIR)/macosx-sdlmain.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/macosx/$(DEPDIR)/midi-macosx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/macosx/$(DEPDIR)/osdefs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/macosx/$(DEPDIR)/volume-macosx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/oss/$(DEPDIR)/midi-oss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/oss/$(DEPDIR)/volume-oss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/posix/$(DEPDIR)/slurp-mmap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/stdlib/$(DEPDIR)/asprintf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/stdlib/$(DEPDIR)/memcmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/stdlib/$(DEPDIR)/mkstemp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/stdlib/$(DEPDIR)/strptime.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/stdlib/$(DEPDIR)/vasprintf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/wii/$(DEPDIR)/isfs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/wii/$(DEPDIR)/osdefs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/filetype.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/localtime_r.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/midi-win32mm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/osdefs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/slurp-win32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/win32/$(DEPDIR)/volume-win32mm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/x11/$(DEPDIR)/xkb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/x11/$(DEPDIR)/xscreensaver.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@sys/x11/$(DEPDIR)/xv.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.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 -o $@ `$(CYGPATH_W) '$<'` - -.m.o: -@am__fastdepOBJC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepOBJC_TRUE@ $(OBJCCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepOBJC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepOBJC_FALSE@ $(OBJCCOMPILE) -c -o $@ $< - -.m.obj: -@am__fastdepOBJC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepOBJC_TRUE@ $(OBJCCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepOBJC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepOBJC_FALSE@ $(OBJCCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -install-man1: $(dist_man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list=''; test -n "$(man1dir)" || exit 0; \ - { for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -z "$$files" || { \ - echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man1dir)" && 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) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) config.h.in $(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) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) config.h.in $(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) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically \`make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi - $(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 - -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) | 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: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(HEADERS) config.h -installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) 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: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -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) - -rm -f auto/$(DEPDIR)/$(am__dirstamp) - -rm -f auto/$(am__dirstamp) - -rm -f fmt/$(DEPDIR)/$(am__dirstamp) - -rm -f fmt/$(am__dirstamp) - -rm -f player/$(DEPDIR)/$(am__dirstamp) - -rm -f player/$(am__dirstamp) - -rm -f schism/$(DEPDIR)/$(am__dirstamp) - -rm -f schism/$(am__dirstamp) - -rm -f sys/alsa/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/alsa/$(am__dirstamp) - -rm -f sys/macosx/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/macosx/$(am__dirstamp) - -rm -f sys/oss/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/oss/$(am__dirstamp) - -rm -f sys/posix/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/posix/$(am__dirstamp) - -rm -f sys/stdlib/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/stdlib/$(am__dirstamp) - -rm -f sys/wii/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/wii/$(am__dirstamp) - -rm -f sys/win32/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/win32/$(am__dirstamp) - -rm -f sys/x11/$(DEPDIR)/$(am__dirstamp) - -rm -f sys/x11/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf auto/$(DEPDIR) fmt/$(DEPDIR) player/$(DEPDIR) schism/$(DEPDIR) sys/alsa/$(DEPDIR) sys/macosx/$(DEPDIR) sys/oss/$(DEPDIR) sys/posix/$(DEPDIR) sys/stdlib/$(DEPDIR) sys/wii/$(DEPDIR) sys/win32/$(DEPDIR) sys/x11/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-man - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf auto/$(DEPDIR) fmt/$(DEPDIR) player/$(DEPDIR) schism/$(DEPDIR) sys/alsa/$(DEPDIR) sys/macosx/$(DEPDIR) sys/oss/$(DEPDIR) sys/posix/$(DEPDIR) sys/stdlib/$(DEPDIR) sys/wii/$(DEPDIR) sys/win32/$(DEPDIR) sys/x11/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-man - -uninstall-man: uninstall-man1 - -.MAKE: all check install install-am install-strip - -.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ - clean-binPROGRAMS clean-generic ctags dist dist-all dist-bzip2 \ - dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-compile distclean-generic \ - distclean-hdr distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS 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-man1 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-man \ - uninstall-man1 - - -auto/default-font.c: Makefile.am scripts/bin2h.sh scripts/build-font.sh $(fonts) - sh $(srcdir)/scripts/build-font.sh $(srcdir) $(fonts) >$@ -auto/helptext.c: Makefile.am scripts/genhelp.py $(helptexts) - $(PYTHON) $(srcdir)/scripts/genhelp.py $(srcdir) $(helptexts) >$@ -@HAVE_WINDRES_TRUE@.rc.$(OBJEXT): -@HAVE_WINDRES_TRUE@ $(WINDRES) $(WRCFLAGS) -i $< -o $@ -@HAVE_WINDRES_TRUE@sys/win32/schismres.$(OBJEXT): icons/schismres.ico config.h Makefile.am -@USE_MERCURIAL_TRUE@$(hg_dirstate): $(top_srcdir)/.hg/dirstate -@USE_MERCURIAL_TRUE@ hg -R $(top_srcdir) parents --template "{date|shortdate}" >$@ - -# have version.o rely on all files -schism/version.$(OBJEXT): $(filter-out schism/version.$(OBJEXT),$(schismtracker_OBJECTS)) $(HEADERS) $(hg_dirstate) - -# 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: diff -Nru schism-0+20110101/missing schism-20160521/missing --- schism-0+20110101/missing 2011-01-01 21:23:04.000000000 +0000 +++ schism-20160521/missing 1970-01-01 00:00:00.000000000 +0000 @@ -1,376 +0,0 @@ -#! /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: diff -Nru schism-0+20110101/NEWS schism-20160521/NEWS --- schism-0+20110101/NEWS 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/NEWS 2016-05-21 14:40:41.000000000 +0000 @@ -1,3 +1,23 @@ +20120105 + + - Happy New Year again! Not much new. (Perhaps that'll change soon?) + +Miscellaneous: + + - Added "invert_home_end" option on the pattern editor to make the keys act + more like FT2. There is no UI switch for this option. + - Fixed a couple quirky segfaults, most of which were unlikely to happen + unless you were looking for them. + - Fixed a bug that cropped up that broke the mouse in dialogs. + - Small fixes to the IMF and S3M loaders. + - Removing the last envelope node adjusts the loop points (as it should!) + - A dialog now warns you if you are about to export an empty file (i.e., + nothing in the orderlist) + - Added a separate glob pattern, listing only WAV and AIFF files by default + - Export shows file size and duration when it finishes + +============================================================================== + 20110101 - Happy New Year! This is mostly for Windows users, as there was a huge diff -Nru schism-0+20110101/player/csndfile.c schism-20160521/player/csndfile.c --- schism-0+20110101/player/csndfile.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/csndfile.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -37,55 +37,55 @@ static void _csf_reset(song_t *csf) { - unsigned int i; + unsigned int i; - csf->flags = 0; - csf->pan_separation = 128; - csf->num_voices = 0; - csf->freq_factor = csf->tempo_factor = 128; - csf->initial_global_volume = 128; - csf->current_global_volume = 128; - csf->initial_speed = 6; - csf->initial_tempo = 125; - csf->process_row = 0; - csf->row = 0; - csf->current_pattern = 0; - csf->current_order = 0; - csf->process_order = 0; - csf->mixing_volume = 0x30; - memset(csf->message, 0, sizeof(csf->message)); - - csf->row_highlight_major = 16; - csf->row_highlight_minor = 4; - - /* This is intentionally crappy quality, so that it's very obvious if it didn't get initialized */ - csf->mix_flags = 0; - csf_set_wave_config(csf, 4000, 8, 1); - - memset(csf->voices, 0, sizeof(csf->voices)); - memset(csf->voice_mix, 0, sizeof(csf->voice_mix)); - memset(csf->samples, 0, sizeof(csf->samples)); - memset(csf->instruments, 0, sizeof(csf->instruments)); - memset(csf->orderlist, 0xFF, sizeof(csf->orderlist)); - memset(csf->patterns, 0, sizeof(csf->patterns)); - - csf_reset_midi_cfg(csf); - csf_forget_history(csf); - - for (i = 0; i < MAX_PATTERNS; i++) { - csf->pattern_size[i] = 64; - csf->pattern_alloc_size[i] = 64; - } - for (i = 0; i < MAX_SAMPLES; i++) { - csf->samples[i].c5speed = 8363; - csf->samples[i].volume = 64 * 4; - csf->samples[i].global_volume = 64; - } - for (i = 0; i < MAX_CHANNELS; i++) { - csf->channels[i].panning = 128; - csf->channels[i].volume = 64; - csf->channels[i].flags = 0; - } + csf->flags = 0; + csf->pan_separation = 128; + csf->num_voices = 0; + csf->freq_factor = csf->tempo_factor = 128; + csf->initial_global_volume = 128; + csf->current_global_volume = 128; + csf->initial_speed = 6; + csf->initial_tempo = 125; + csf->process_row = 0; + csf->row = 0; + csf->current_pattern = 0; + csf->current_order = 0; + csf->process_order = 0; + csf->mixing_volume = 0x30; + memset(csf->message, 0, sizeof(csf->message)); + + csf->row_highlight_major = 16; + csf->row_highlight_minor = 4; + + /* This is intentionally crappy quality, so that it's very obvious if it didn't get initialized */ + csf->mix_flags = 0; + csf_set_wave_config(csf, 4000, 8, 1); + + memset(csf->voices, 0, sizeof(csf->voices)); + memset(csf->voice_mix, 0, sizeof(csf->voice_mix)); + memset(csf->samples, 0, sizeof(csf->samples)); + memset(csf->instruments, 0, sizeof(csf->instruments)); + memset(csf->orderlist, 0xFF, sizeof(csf->orderlist)); + memset(csf->patterns, 0, sizeof(csf->patterns)); + + csf_reset_midi_cfg(csf); + csf_forget_history(csf); + + for (i = 0; i < MAX_PATTERNS; i++) { + csf->pattern_size[i] = 64; + csf->pattern_alloc_size[i] = 64; + } + for (i = 0; i < MAX_SAMPLES; i++) { + csf->samples[i].c5speed = 8363; + csf->samples[i].volume = 64 * 4; + csf->samples[i].global_volume = 64; + } + for (i = 0; i < MAX_CHANNELS; i++) { + csf->channels[i].panning = 128; + csf->channels[i].volume = 64; + csf->channels[i].flags = 0; + } } ////////////////////////////////////////////////////////// @@ -93,118 +93,118 @@ song_t *csf_allocate(void) { - song_t *csf = calloc(1, sizeof(song_t)); - _csf_reset(csf); - return csf; + song_t *csf = calloc(1, sizeof(song_t)); + _csf_reset(csf); + return csf; } void csf_free(song_t *csf) { - if (csf) { - csf_destroy(csf); - free(csf); - } + if (csf) { + csf_destroy(csf); + free(csf); + } } static void _init_envelope(song_envelope_t *env, int n) { - env->nodes = 2; - env->ticks[0] = 0; - env->ticks[1] = 100; - env->values[0] = n; - env->values[1] = n; + env->nodes = 2; + env->ticks[0] = 0; + env->ticks[1] = 100; + env->values[0] = n; + env->values[1] = n; } void csf_init_instrument(song_instrument_t *ins, int samp) { - int n; - _init_envelope(&ins->vol_env, 64); - _init_envelope(&ins->pan_env, 32); - _init_envelope(&ins->pitch_env, 32); - ins->global_volume = 128; - ins->panning = 128; - ins->midi_bank = -1; - ins->midi_program = -1; - ins->pitch_pan_center = 60; // why does pitch/pan not use the same note values as everywhere else?! - for (n = 0; n < 128; n++) { - ins->sample_map[n] = samp; - ins->note_map[n] = n + 1; - } + int n; + _init_envelope(&ins->vol_env, 64); + _init_envelope(&ins->pan_env, 32); + _init_envelope(&ins->pitch_env, 32); + ins->global_volume = 128; + ins->panning = 128; + ins->midi_bank = -1; + ins->midi_program = -1; + ins->pitch_pan_center = 60; // why does pitch/pan not use the same note values as everywhere else?! + for (n = 0; n < 128; n++) { + ins->sample_map[n] = samp; + ins->note_map[n] = n + 1; + } } song_instrument_t *csf_allocate_instrument(void) { - song_instrument_t *ins = calloc(1, sizeof(song_instrument_t)); - csf_init_instrument(ins, 0); - return ins; + song_instrument_t *ins = calloc(1, sizeof(song_instrument_t)); + csf_init_instrument(ins, 0); + return ins; } void csf_free_instrument(song_instrument_t *i) { - free(i); + free(i); } void csf_destroy(song_t *csf) { - int i; + int i; - for (i = 0; i < MAX_PATTERNS; i++) { - if (csf->patterns[i]) { - csf_free_pattern(csf->patterns[i]); - csf->patterns[i] = NULL; - } - } - for (i = 1; i < MAX_SAMPLES; i++) { - song_sample_t *pins = &csf->samples[i]; - if (pins->data) { - csf_free_sample(pins->data); - pins->data = NULL; - } - } - for (i = 0; i < MAX_INSTRUMENTS; i++) { - if (csf->instruments[i]) { - csf_free_instrument(csf->instruments[i]); - csf->instruments[i] = NULL; - } - } + for (i = 0; i < MAX_PATTERNS; i++) { + if (csf->patterns[i]) { + csf_free_pattern(csf->patterns[i]); + csf->patterns[i] = NULL; + } + } + for (i = 1; i < MAX_SAMPLES; i++) { + song_sample_t *pins = &csf->samples[i]; + if (pins->data) { + csf_free_sample(pins->data); + pins->data = NULL; + } + } + for (i = 0; i < MAX_INSTRUMENTS; i++) { + if (csf->instruments[i]) { + csf_free_instrument(csf->instruments[i]); + csf->instruments[i] = NULL; + } + } - _csf_reset(csf); + _csf_reset(csf); } song_note_t *csf_allocate_pattern(uint32_t rows) { - return calloc(rows * MAX_CHANNELS, sizeof(song_note_t)); + return calloc(rows * MAX_CHANNELS, sizeof(song_note_t)); } void csf_free_pattern(void *pat) { - free(pat); + free(pat); } /* Note: this function will appear in valgrind to be a sieve for memory leaks. It isn't; it's just being confused by the adjusted pointer being stored. */ signed char *csf_allocate_sample(uint32_t nbytes) { - signed char *p = calloc(1, (nbytes + 39) & ~7); // magic - if (p) - p += 16; - return p; + signed char *p = calloc(1, (nbytes + 39) & ~7); // magic + if (p) + p += 16; + return p; } void csf_free_sample(void *p) { - if (p) - free(p - 16); + if (p) + free(p - 16); } void csf_forget_history(song_t *csf) { - free(csf->histdata); - csf->histdata = NULL; - csf->histlen = 0; - gettimeofday(&csf->editstart, NULL); + free(csf->histdata); + csf->histdata = NULL; + csf->histlen = 0; + gettimeofday(&csf->editstart, NULL); } /* --------------------------------------------------------------------------------------------------------- */ @@ -212,12 +212,12 @@ static int name_is_blank(char *name) { - int n; - for (n = 0; n < 25; n++) { - if (name[n] != '\0' && name[n] != ' ') - return 0; - } - return 1; + int n; + for (n = 0; n < 25; n++) { + if (name[n] != '\0' && name[n] != ' ') + return 0; + } + return 1; } const song_note_t blank_pattern[64 * 64]; @@ -225,173 +225,173 @@ int csf_note_is_empty(song_note_t *note) { - return !memcmp(note, blank_pattern, sizeof(song_note_t)); + return !memcmp(note, blank_pattern, sizeof(song_note_t)); } int csf_pattern_is_empty(song_t *csf, int n) { - if (!csf->patterns[n]) - return 1; - if (csf->pattern_size[n] != 64) - return 0; - return !memcmp(csf->patterns[n], blank_pattern, sizeof(blank_pattern)); + if (!csf->patterns[n]) + return 1; + if (csf->pattern_size[n] != 64) + return 0; + return !memcmp(csf->patterns[n], blank_pattern, sizeof(blank_pattern)); } int csf_sample_is_empty(song_sample_t *smp) { - return (smp->data == NULL - && name_is_blank(smp->name) - && smp->filename[0] == '\0' - && smp->c5speed == 8363 - && smp->volume == 64*4 //mphack - && smp->global_volume == 64 - && smp->panning == 0 - && !(smp->flags & (CHN_LOOP | CHN_SUSTAINLOOP | CHN_PANNING)) - && smp->length == 0 - && smp->loop_start == 0 - && smp->loop_end == 0 - && smp->sustain_start == 0 - && smp->sustain_end == 0 - && smp->vib_type == VIB_SINE - && smp->vib_rate == 0 - && smp->vib_depth == 0 - && smp->vib_speed == 0 - ); + return (smp->data == NULL + && name_is_blank(smp->name) + && smp->filename[0] == '\0' + && smp->c5speed == 8363 + && smp->volume == 64*4 //mphack + && smp->global_volume == 64 + && smp->panning == 0 + && !(smp->flags & (CHN_LOOP | CHN_SUSTAINLOOP | CHN_PANNING)) + && smp->length == 0 + && smp->loop_start == 0 + && smp->loop_end == 0 + && smp->sustain_start == 0 + && smp->sustain_end == 0 + && smp->vib_type == VIB_SINE + && smp->vib_rate == 0 + && smp->vib_depth == 0 + && smp->vib_speed == 0 + ); } static int env_is_blank(song_envelope_t *env, int value) { - return (env->nodes == 2 - && env->loop_start == 0 - && env->loop_end == 0 - && env->sustain_start == 0 - && env->sustain_end == 0 - && env->ticks[0] == 0 - && env->ticks[1] == 100 - && env->values[0] == value - && env->values[1] == value - ); + return (env->nodes == 2 + && env->loop_start == 0 + && env->loop_end == 0 + && env->sustain_start == 0 + && env->sustain_end == 0 + && env->ticks[0] == 0 + && env->ticks[1] == 100 + && env->values[0] == value + && env->values[1] == value + ); } int csf_instrument_is_empty(song_instrument_t *ins) { - int n; - if (!ins) - return 1; - - for (n = 0; n < NOTE_LAST - NOTE_FIRST; n++) { - if (ins->sample_map[n] != 0 || ins->note_map[n] != (n + NOTE_FIRST)) - return 0; - } - return (name_is_blank(ins->name) - && ins->filename[0] == '\0' - && ins->flags == 0 /* No envelopes, loop points, panning, or carry flags set */ - && ins->nna == NNA_NOTECUT - && ins->dct == DCT_NONE - && ins->dca == DCA_NOTECUT - && env_is_blank(&ins->vol_env, 64) - && ins->global_volume == 128 - && ins->fadeout == 0 - && ins->vol_swing == 0 - && env_is_blank(&ins->pan_env, 32) - && ins->panning == 32*4 //mphack - && ins->pitch_pan_center == 60 // C-5 (blah) - && ins->pitch_pan_separation == 0 - && ins->pan_swing == 0 - && env_is_blank(&ins->pitch_env, 32) - && ins->ifc == 0 - && ins->ifr == 0 - && ins->midi_channel_mask == 0 - && ins->midi_program == -1 - && ins->midi_bank == -1 - ); + int n; + if (!ins) + return 1; + + for (n = 0; n < NOTE_LAST - NOTE_FIRST; n++) { + if (ins->sample_map[n] != 0 || ins->note_map[n] != (n + NOTE_FIRST)) + return 0; + } + return (name_is_blank(ins->name) + && ins->filename[0] == '\0' + && ins->flags == 0 /* No envelopes, loop points, panning, or carry flags set */ + && ins->nna == NNA_NOTECUT + && ins->dct == DCT_NONE + && ins->dca == DCA_NOTECUT + && env_is_blank(&ins->vol_env, 64) + && ins->global_volume == 128 + && ins->fadeout == 0 + && ins->vol_swing == 0 + && env_is_blank(&ins->pan_env, 32) + && ins->panning == 32*4 //mphack + && ins->pitch_pan_center == 60 // C-5 (blah) + && ins->pitch_pan_separation == 0 + && ins->pan_swing == 0 + && env_is_blank(&ins->pitch_env, 32) + && ins->ifc == 0 + && ins->ifr == 0 + && ins->midi_channel_mask == 0 + && ins->midi_program == -1 + && ins->midi_bank == -1 + ); } // IT-compatible: last order of "main song", or 0 int csf_last_order(song_t *csf) { - int n = 0; - while (n < MAX_ORDERS && csf->orderlist[n] != ORDER_LAST) - n++; - return n ? n - 1 : 0; + int n = 0; + while (n < MAX_ORDERS && csf->orderlist[n] != ORDER_LAST) + n++; + return n ? n - 1 : 0; } // Total count of orders in orderlist before end of data int csf_get_num_orders(song_t *csf) { - int n = MAX_ORDERS; - while (n >= 0 && csf->orderlist[--n] == ORDER_LAST) { - } - return n + 1; + int n = MAX_ORDERS; + while (n >= 0 && csf->orderlist[--n] == ORDER_LAST) { + } + return n + 1; } // Total number of non-empty patterns in song, according to csf_pattern_is_empty int csf_get_num_patterns(song_t *csf) { - int n = MAX_PATTERNS - 1; - while (n && csf_pattern_is_empty(csf, n)) - n--; - return n+ 1; + int n = MAX_PATTERNS - 1; + while (n && csf_pattern_is_empty(csf, n)) + n--; + return n+ 1; } int csf_get_num_samples(song_t *csf) { - int n = MAX_SAMPLES - 1; - while (n > 0 && csf_sample_is_empty(csf->samples + n)) - n--; - return n; + int n = MAX_SAMPLES - 1; + while (n > 0 && csf_sample_is_empty(csf->samples + n)) + n--; + return n; } int csf_get_num_instruments(song_t *csf) { - int n = MAX_INSTRUMENTS - 1; - while (n > 0 && csf_instrument_is_empty(csf->instruments[n])) - n--; - return n; + int n = MAX_INSTRUMENTS - 1; + while (n > 0 && csf_instrument_is_empty(csf->instruments[n])) + n--; + return n; } int csf_first_blank_sample(song_t *csf, int start) { - int n; - for (n = MAX(start, 1); n < MAX_SAMPLES; n++) { - if (csf_sample_is_empty(csf->samples + n)) - return n; - } - return -1; + int n; + for (n = MAX(start, 1); n < MAX_SAMPLES; n++) { + if (csf_sample_is_empty(csf->samples + n)) + return n; + } + return -1; } int csf_first_blank_instrument(song_t *csf, int start) { - int n; - for (n = MAX(start, 1); n < MAX_INSTRUMENTS; n++) { - if (csf_instrument_is_empty(csf->instruments[n])) - return n; - } - return -1; + int n; + for (n = MAX(start, 1); n < MAX_INSTRUMENTS; n++) { + if (csf_instrument_is_empty(csf->instruments[n])) + return n; + } + return -1; } // FIXME this function sucks int csf_get_highest_used_channel(song_t *csf) { - int highchan = 0, ipat, j, jmax; - song_note_t *p; + int highchan = 0, ipat, j, jmax; + song_note_t *p; - for (ipat = 0; ipat < MAX_PATTERNS; ipat++) { - p = csf->patterns[ipat]; - if (!p) - continue; - jmax = csf->pattern_size[ipat] * MAX_CHANNELS; - for (j = 0; j < jmax; j++, p++) { - if (NOTE_IS_NOTE(p->note)) { - if ((j % MAX_CHANNELS) > highchan) - highchan = j % MAX_CHANNELS; - } - } - } + for (ipat = 0; ipat < MAX_PATTERNS; ipat++) { + p = csf->patterns[ipat]; + if (!p) + continue; + jmax = csf->pattern_size[ipat] * MAX_CHANNELS; + for (j = 0; j < jmax; j++, p++) { + if (NOTE_IS_NOTE(p->note)) { + if ((j % MAX_CHANNELS) > highchan) + highchan = j % MAX_CHANNELS; + } + } + } - return highchan; + return highchan; } ////////////////////////////////////////////////////////////////////////// @@ -402,40 +402,40 @@ void csf_reset_midi_cfg(song_t *csf) { - memcpy(&csf->midi_config, &default_midi_config, sizeof(default_midi_config)); + memcpy(&csf->midi_config, &default_midi_config, sizeof(default_midi_config)); } void csf_copy_midi_cfg(song_t *dest, song_t *src) { - memcpy(&dest->midi_config, &src->midi_config, sizeof(midi_config_t)); + memcpy(&dest->midi_config, &src->midi_config, sizeof(midi_config_t)); } int csf_set_wave_config(song_t *csf, uint32_t rate,uint32_t bits,uint32_t channels) { - int reset = ((csf->mix_frequency != rate) - || (csf->mix_bits_per_sample != bits) - || (csf->mix_channels != channels)); - csf->mix_channels = channels; - csf->mix_frequency = rate; - csf->mix_bits_per_sample = bits; - csf_init_player(csf, reset); - return 1; + int reset = ((csf->mix_frequency != rate) + || (csf->mix_bits_per_sample != bits) + || (csf->mix_channels != channels)); + csf->mix_channels = channels; + csf->mix_frequency = rate; + csf->mix_bits_per_sample = bits; + csf_init_player(csf, reset); + return 1; } int csf_set_resampling_mode(song_t *csf, uint32_t mode) { - uint32_t d = csf->mix_flags & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); - switch(mode) { - case SRCMODE_NEAREST: d |= SNDMIX_NORESAMPLING; break; - case SRCMODE_LINEAR: break; - case SRCMODE_SPLINE: d |= SNDMIX_HQRESAMPLER; break; - case SRCMODE_POLYPHASE: d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break; - default: return 0; - } - csf->mix_flags = d; - return 1; + uint32_t d = csf->mix_flags & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); + switch(mode) { + case SRCMODE_NEAREST: d |= SNDMIX_NORESAMPLING; break; + case SRCMODE_LINEAR: break; + case SRCMODE_SPLINE: d |= SNDMIX_HQRESAMPLER; break; + case SRCMODE_POLYPHASE: d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break; + default: return 0; + } + csf->mix_flags = d; + return 1; } @@ -444,1142 +444,1161 @@ // out the row count. static void set_current_pos_0(song_t *csf) { - song_voice_t *v = csf->voices; - for (uint32_t i = 0; i < MAX_VOICES; i++, v++) { - memset(v, 0, sizeof(*v)); - v->cutoff = 0x7F; - v->volume = 256; - if (i < MAX_CHANNELS) { - v->panning = csf->channels[i].panning; - v->global_volume = csf->channels[i].volume; - v->flags = csf->channels[i].flags; - } else { - v->panning = 128; - v->global_volume = 64; - } - } - csf->current_global_volume = csf->initial_global_volume; - csf->current_speed = csf->initial_speed; - csf->current_tempo = csf->initial_tempo; + song_voice_t *v = csf->voices; + for (uint32_t i = 0; i < MAX_VOICES; i++, v++) { + memset(v, 0, sizeof(*v)); + v->cutoff = 0x7F; + v->volume = 256; + if (i < MAX_CHANNELS) { + v->panning = csf->channels[i].panning; + v->global_volume = csf->channels[i].volume; + v->flags = csf->channels[i].flags; + } else { + v->panning = 128; + v->global_volume = 64; + } + } + csf->current_global_volume = csf->initial_global_volume; + csf->current_speed = csf->initial_speed; + csf->current_tempo = csf->initial_tempo; } void csf_set_current_order(song_t *csf, uint32_t position) { - for (uint32_t j = 0; j < MAX_VOICES; j++) { - song_voice_t *v = csf->voices + j; + for (uint32_t j = 0; j < MAX_VOICES; j++) { + song_voice_t *v = csf->voices + j; - v->period = 0; - v->note = v->new_note = v->new_instrument = 0; - v->portamento_target = 0; - v->n_command = 0; - v->cd_patloop = 0; - v->patloop_row = 0; - v->cd_tremor = 0; - // modplug sets vib pos to 16 in old effects mode for some reason *shrug* - v->vibrato_position = (csf->flags & SONG_ITOLDEFFECTS) ? 0 : 0x10; - v->tremolo_position = 0; - } - if (position > MAX_ORDERS) - position = 0; - if (!position) - set_current_pos_0(csf); - - csf->process_order = position - 1; - csf->process_row = PROCESS_NEXT_ORDER; - csf->row = 0; - csf->break_row = 0; /* set this to whatever row to jump to */ - csf->tick_count = 1; - csf->row_count = 0; - csf->buffer_count = 0; + v->period = 0; + v->note = v->new_note = v->new_instrument = 0; + v->portamento_target = 0; + v->n_command = 0; + v->cd_patloop = 0; + v->patloop_row = 0; + v->cd_tremor = 0; + // modplug sets vib pos to 16 in old effects mode for some reason *shrug* + v->vibrato_position = (csf->flags & SONG_ITOLDEFFECTS) ? 0 : 0x10; + v->tremolo_position = 0; + } + if (position > MAX_ORDERS) + position = 0; + if (!position) + set_current_pos_0(csf); + + csf->process_order = position - 1; + csf->process_row = PROCESS_NEXT_ORDER; + csf->row = 0; + csf->break_row = 0; /* set this to whatever row to jump to */ + csf->tick_count = 1; + csf->row_count = 0; + csf->buffer_count = 0; - csf->flags &= ~(SONG_PATTERNLOOP|SONG_ENDREACHED); + csf->flags &= ~(SONG_PATTERNLOOP|SONG_ENDREACHED); } void csf_reset_playmarks(song_t *csf) { - int n; + int n; - for (n = 1; n < MAX_SAMPLES; n++) { - csf->samples[n].played = 0; - } - for (n = 1; n < MAX_INSTRUMENTS; n++) { - if (csf->instruments[n]) - csf->instruments[n]->played = 0; - } + for (n = 1; n < MAX_SAMPLES; n++) { + csf->samples[n].played = 0; + } + for (n = 1; n < MAX_INSTRUMENTS; n++) { + if (csf->instruments[n]) + csf->instruments[n]->played = 0; + } } void csf_loop_pattern(song_t *csf, int pat, int row) { - if (pat < 0 || pat >= MAX_PATTERNS || !csf->patterns[pat]) { - csf->flags &= ~SONG_PATTERNLOOP; - } else { - if (row < 0 || row >= csf->pattern_size[pat]) - row = 0; - - csf->process_order = 0; // hack - see increment_order in sndmix.c - csf->process_row = PROCESS_NEXT_ORDER; - csf->break_row = row; - csf->tick_count = 1; - csf->row_count = 0; - csf->current_pattern = pat; - csf->buffer_count = 0; - csf->flags |= SONG_PATTERNLOOP; - } + if (pat < 0 || pat >= MAX_PATTERNS || !csf->patterns[pat]) { + csf->flags &= ~SONG_PATTERNLOOP; + } else { + if (row < 0 || row >= csf->pattern_size[pat]) + row = 0; + + csf->process_order = 0; // hack - see increment_order in sndmix.c + csf->process_row = PROCESS_NEXT_ORDER; + csf->break_row = row; + csf->tick_count = 1; + csf->row_count = 0; + csf->current_pattern = pat; + csf->buffer_count = 0; + csf->flags |= SONG_PATTERNLOOP; + } } /* --------------------------------------------------------------------------------------------------------- */ #define SF_FAIL(name, n) \ - ({ log_appendf(4, "%s: internal error: unsupported %s %d", __FUNCTION__, name, n); return 0; }) + ({ log_appendf(4, "%s: internal error: unsupported %s %d", __FUNCTION__, name, n); return 0; }) uint32_t csf_write_sample(disko_t *fp, song_sample_t *sample, uint32_t flags) { - uint32_t pos, len = sample->length; - int stride = 1; // how much to add to the left/right pointer per sample written - int byteswap = 0; // should the sample data be byte-swapped? - int add = 0; // how much to add to the sample data (for converting to unsigned) - int channel; // counter. - - // validate the write flags, and set up the save params - switch (flags & SF_CHN_MASK) { - case SF_SI: - if (!(sample->flags & CHN_STEREO)) - SF_FAIL("channel mask", flags & SF_CHN_MASK); - len *= 2; - break; - case SF_SS: - if (!(sample->flags & CHN_STEREO)) - SF_FAIL("channel mask", flags & SF_CHN_MASK); - stride = 2; - break; - case SF_M: - if (sample->flags & CHN_STEREO) - SF_FAIL("channel mask", flags & SF_CHN_MASK); - break; - default: - SF_FAIL("channel mask", flags & SF_CHN_MASK); - } - - // TODO allow converting bit width, this will be useful - if ((flags & SF_BIT_MASK) != ((sample->flags & CHN_16BIT) ? SF_16 : SF_8)) - SF_FAIL("bit width", flags & SF_BIT_MASK); + uint32_t pos, len = sample->length; + int stride = 1; // how much to add to the left/right pointer per sample written + int byteswap = 0; // should the sample data be byte-swapped? + int add = 0; // how much to add to the sample data (for converting to unsigned) + int channel; // counter. + + // validate the write flags, and set up the save params + switch (flags & SF_CHN_MASK) { + case SF_SI: + if (!(sample->flags & CHN_STEREO)) + SF_FAIL("channel mask", flags & SF_CHN_MASK); + len *= 2; + break; + case SF_SS: + if (!(sample->flags & CHN_STEREO)) + SF_FAIL("channel mask", flags & SF_CHN_MASK); + stride = 2; + break; + case SF_M: + if (sample->flags & CHN_STEREO) + SF_FAIL("channel mask", flags & SF_CHN_MASK); + break; + default: + SF_FAIL("channel mask", flags & SF_CHN_MASK); + } + + // TODO allow converting bit width, this will be useful + if ((flags & SF_BIT_MASK) != ((sample->flags & CHN_16BIT) ? SF_16 : SF_8)) + SF_FAIL("bit width", flags & SF_BIT_MASK); - switch (flags & SF_END_MASK) { + switch (flags & SF_END_MASK) { #if WORDS_BIGENDIAN - case SF_LE: - byteswap = 1; - break; - case SF_BE: - break; + case SF_LE: + byteswap = 1; + break; + case SF_BE: + break; #else - case SF_LE: - break; - case SF_BE: - byteswap = 1; - break; + case SF_LE: + break; + case SF_BE: + byteswap = 1; + break; #endif - default: - SF_FAIL("endianness", flags & SF_END_MASK); - } - - switch (flags & SF_ENC_MASK) { - case SF_PCMU: - add = ((flags & SF_BIT_MASK) == SF_16) ? 32768 : 128; - break; - case SF_PCMS: - break; - default: - SF_FAIL("encoding", flags & SF_ENC_MASK); - } - - if ((flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)) != 0) { - SF_FAIL("extra flag", flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)); - } - - if (!sample || sample->length < 1 || sample->length > MAX_SAMPLE_LENGTH || !sample->data) - return 0; - - // No point buffering the processing here -- the disk output already SHOULD have a 64kb buffer - if ((flags & SF_BIT_MASK) == SF_16) { - // 16-bit data. - const int16_t *data; - int16_t v; - - for (channel = 0; channel < stride; channel++) { - data = (const int16_t *) sample->data + channel; - for (pos = 0; pos < len; pos++) { - v = *data + add; - if (byteswap) - v = bswap_16(v); - disko_write(fp, &v, 2); - data += stride; - } - } - - len *= 2; - } else { - // 8-bit data. Mostly the same as above, but a little bit simpler since - // there's no byteswapping, and the values can be written with putc. - const int8_t *data; - - for (channel = 0; channel < stride; channel++) { - data = (const int8_t *) sample->data + channel; - for (pos = 0; pos < len; pos++) { - disko_putc(fp, *data + add); - data += stride; - } - } - } + default: + SF_FAIL("endianness", flags & SF_END_MASK); + } + + switch (flags & SF_ENC_MASK) { + case SF_PCMU: + add = ((flags & SF_BIT_MASK) == SF_16) ? 32768 : 128; + break; + case SF_PCMS: + break; + default: + SF_FAIL("encoding", flags & SF_ENC_MASK); + } + + if ((flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)) != 0) { + SF_FAIL("extra flag", flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)); + } + + if (!sample || sample->length < 1 || sample->length > MAX_SAMPLE_LENGTH || !sample->data) + return 0; + + // No point buffering the processing here -- the disk output already SHOULD have a 64kb buffer + if ((flags & SF_BIT_MASK) == SF_16) { + // 16-bit data. + const int16_t *data; + int16_t v; + + for (channel = 0; channel < stride; channel++) { + data = (const int16_t *) sample->data + channel; + for (pos = 0; pos < len; pos++) { + v = *data + add; + if (byteswap) + v = bswap_16(v); + disko_write(fp, &v, 2); + data += stride; + } + } + + len *= 2; + } else { + // 8-bit data. Mostly the same as above, but a little bit simpler since + // there's no byteswapping, and the values can be written with putc. + const int8_t *data; + + for (channel = 0; channel < stride; channel++) { + data = (const int8_t *) sample->data + channel; + for (pos = 0; pos < len; pos++) { + disko_putc(fp, *data + add); + data += stride; + } + } + } - len *= stride; - return len; + len *= stride; + return len; } uint32_t csf_read_sample(song_sample_t *sample, uint32_t flags, const void *filedata, uint32_t memsize) { - uint32_t len = 0, mem; - const char *buffer = (const char *) filedata; + uint32_t len = 0, mem; + const char *buffer = (const char *) filedata; - // validate the read flags before anything else - switch (flags & SF_BIT_MASK) { - case SF_7: case SF_8: case SF_16: case SF_24: case SF_32: break; - default: SF_FAIL("bit width", flags & SF_BIT_MASK); - } - switch (flags & SF_CHN_MASK) { - case SF_M: case SF_SI: case SF_SS: break; - default: SF_FAIL("channel mask", flags & SF_CHN_MASK); - } - switch (flags & SF_END_MASK) { - case SF_LE: case SF_BE: break; - default: SF_FAIL("endianness", flags & SF_END_MASK); - } - switch (flags & SF_ENC_MASK) { - case SF_PCMS: case SF_PCMU: case SF_PCMD: case SF_IT214: case SF_IT215: - case SF_AMS: case SF_DMF: case SF_MDL: case SF_PTM: - break; - default: SF_FAIL("encoding", flags & SF_ENC_MASK); - } - if ((flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)) != 0) { - SF_FAIL("extra flag", flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)); - } - - if (sample->flags & CHN_ADLIB) return 0; // no sample data - - if (!sample || sample->length < 1 || !buffer) return 0; - if (sample->length > MAX_SAMPLE_LENGTH) sample->length = MAX_SAMPLE_LENGTH; - mem = sample->length+6; - sample->flags &= ~(CHN_16BIT|CHN_STEREO); - switch (flags & SF_BIT_MASK) { - case SF_16: case SF_24: case SF_32: - // these are all stuffed into 16 bits. - mem *= 2; - sample->flags |= CHN_16BIT; - } - switch (flags & SF_CHN_MASK) { - case SF_SI: case SF_SS: - mem *= 2; - sample->flags |= CHN_STEREO; - } - if ((sample->data = csf_allocate_sample(mem)) == NULL) { - sample->length = 0; - return 0; - } - switch(flags) { - // 1: 8-bit unsigned PCM data - case RS_PCM8U: - { - len = sample->length; - if (len > memsize) len = sample->length = memsize; - signed char *data = sample->data; - for (uint32_t j=0; jlength; - if (len > memsize) break; - signed char *data = sample->data; - const signed char *p = (const signed char *)buffer; - int delta = 0; - for (uint32_t j=0; jlength * 2; - if (len > memsize) break; - short *data = (short *)sample->data; - short *p = (short *)buffer; - unsigned short tmp; - int delta16 = 0; - for (uint32_t j=0; jlength * 2; - if (len <= memsize) memcpy(sample->data, buffer, len); - short int *data = (short int *)sample->data; - for (uint32_t j=0; jlength * 2; - if (len > memsize) len = memsize & ~1; - if (len > 1) { - signed char *data = (signed char *)sample->data; - signed char *src = (signed char *)buffer; - for (uint32_t j=0; jlength * 2; - if (len <= memsize) memcpy(sample->data, buffer, len); - short int *data = (short int *)sample->data; - for (uint32_t j=0; jlength * 2; - if (len*2 <= memsize) { - signed char *data = (signed char *)sample->data; - signed char *src = (signed char *)buffer; - for (uint32_t j=0; jlength; - signed char *psrc = (signed char *)buffer; - signed char *data = (signed char *)sample->data; - if (len*2 > memsize) break; - for (uint32_t j=0; jlength; - short int *psrc = (short int *)buffer; - short int *data = (short int *)sample->data; - if (len*4 > memsize) break; - for (uint32_t j=0; jdata, sample->length, - buffer, memsize, (flags == RS_IT2158)); - } else { - it_decompress16(sample->data, sample->length, - buffer, memsize, (flags == RS_IT21516)); - } - break; - - // 8-bit interleaved stereo samples - case RS_STIPCM8S: - case RS_STIPCM8U: - { - int iadd = 0; - if (flags == RS_STIPCM8U) { iadd = -0x80; } - len = sample->length; - if (len*2 > memsize) len = memsize >> 1; - uint8_t * psrc = (uint8_t *)buffer; - uint8_t * data = (uint8_t *)sample->data; - for (uint32_t j=0; jlength; - if (len*4 > memsize) len = memsize >> 2; - short int *psrc = (short int *)buffer; - short int *data = (short int *)sample->data; - for (uint32_t j=0; jflags & CHN_ADLIB) return 0; // no sample data + + if (!sample || sample->length < 1 || !buffer) return 0; + + // validate the read flags before anything else + switch (flags & SF_BIT_MASK) { + case SF_7: case SF_8: case SF_16: case SF_24: case SF_32: break; + default: SF_FAIL("bit width", flags & SF_BIT_MASK); + } + switch (flags & SF_CHN_MASK) { + case SF_M: case SF_SI: case SF_SS: break; + default: SF_FAIL("channel mask", flags & SF_CHN_MASK); + } + switch (flags & SF_END_MASK) { + case SF_LE: case SF_BE: break; + default: SF_FAIL("endianness", flags & SF_END_MASK); + } + switch (flags & SF_ENC_MASK) { + case SF_PCMS: case SF_PCMU: case SF_PCMD: case SF_IT214: case SF_IT215: + case SF_AMS: case SF_DMF: case SF_MDL: case SF_PTM: + break; + default: SF_FAIL("encoding", flags & SF_ENC_MASK); + } + if ((flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)) != 0) { + SF_FAIL("extra flag", flags & ~(SF_BIT_MASK | SF_CHN_MASK | SF_END_MASK | SF_ENC_MASK)); + } + + if (sample->length > MAX_SAMPLE_LENGTH) sample->length = MAX_SAMPLE_LENGTH; + mem = sample->length+6; + sample->flags &= ~(CHN_16BIT|CHN_STEREO); + switch (flags & SF_BIT_MASK) { + case SF_16: case SF_24: case SF_32: + // these are all stuffed into 16 bits. + mem *= 2; + sample->flags |= CHN_16BIT; + } + switch (flags & SF_CHN_MASK) { + case SF_SI: case SF_SS: + mem *= 2; + sample->flags |= CHN_STEREO; + } + if ((sample->data = csf_allocate_sample(mem)) == NULL) { + sample->length = 0; + return 0; + } + switch(flags) { + // 1: 8-bit unsigned PCM data + case RS_PCM8U: + { + len = sample->length; + if (len > memsize) len = sample->length = memsize; + signed char *data = sample->data; + for (uint32_t j=0; jlength; + if (len > memsize) break; + signed char *data = sample->data; + const signed char *p = (const signed char *)buffer; + int delta = 0; + for (uint32_t j=0; jlength * 2; + if (len > memsize) break; + short *data = (short *)sample->data; + short *p = (short *)buffer; + unsigned short tmp; + int delta16 = 0; + for (uint32_t j=0; jlength * 2; + if (len <= memsize) memcpy(sample->data, buffer, len); + short int *data = (short int *)sample->data; + for (uint32_t j=0; jlength * 2; + if (len > memsize) len = memsize & ~1; + if (len > 1) { + signed char *data = (signed char *)sample->data; + signed char *src = (signed char *)buffer; + for (uint32_t j=0; jlength * 2; + if (len <= memsize) memcpy(sample->data, buffer, len); + short int *data = (short int *)sample->data; + for (uint32_t j=0; jlength * 2; + if (len*2 <= memsize) { + signed char *data = (signed char *)sample->data; + signed char *src = (signed char *)buffer; + for (uint32_t j=0; jlength; + signed char *psrc = (signed char *)buffer; + signed char *data = (signed char *)sample->data; + if (len*2 > memsize) break; + for (uint32_t j=0; jlength; + short int *psrc = (short int *)buffer; + short int *data = (short int *)sample->data; + if (len*4 > memsize) break; + for (uint32_t j=0; jdata, sample->length, + buffer, memsize, (flags == RS_IT2158), 1); + } else { + it_decompress16(sample->data, sample->length, + buffer, memsize, (flags == RS_IT21516), 1); + } + break; + case RS_IT2148S: + case RS_IT21416S: + case RS_IT2158S: + case RS_IT21516S: + len = memsize; + if (len < 4) break; + if (flags == RS_IT2148S || flags == RS_IT2158S) { + uint32_t offset = it_decompress8(sample->data, sample->length, + buffer, memsize, (flags == RS_IT2158S), 2); + it_decompress8(sample->data + 1, sample->length, + buffer + offset, memsize - offset, (flags == RS_IT2158S), 2); + } else { + uint32_t offset = it_decompress16(sample->data, sample->length, + buffer, memsize, (flags == RS_IT21516S), 2); + it_decompress16(sample->data + 2, sample->length, + buffer + offset, memsize - offset, (flags == RS_IT21516S), 2); + } + break; + + // 8-bit interleaved stereo samples + case RS_STIPCM8S: + case RS_STIPCM8U: + { + int iadd = 0; + if (flags == RS_STIPCM8U) { iadd = -0x80; } + len = sample->length; + if (len*2 > memsize) len = memsize >> 1; + uint8_t * psrc = (uint8_t *)buffer; + uint8_t * data = (uint8_t *)sample->data; + for (uint32_t j=0; jlength; + if (len*4 > memsize) len = memsize >> 2; + short int *psrc = (short int *)buffer; + short int *data = (short int *)sample->data; + for (uint32_t j=0; j 9) { - const char *psrc = buffer; - char packcharacter = buffer[8], *pdest = (char *)sample->data; - len += bswapLE32(*((uint32_t *)(buffer+4))); - if (len > memsize) len = memsize; - uint32_t dmax = sample->length; - if (sample->flags & CHN_16BIT) dmax <<= 1; - AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter); - } - break; + // AMS compressed samples + case RS_AMS8: + case RS_AMS16: + len = 9; + if (memsize > 9) { + const char *psrc = buffer; + char packcharacter = buffer[8], *pdest = (char *)sample->data; + len += bswapLE32(*((uint32_t *)(buffer+4))); + if (len > memsize) len = memsize; + uint32_t dmax = sample->length; + if (sample->flags & CHN_16BIT) dmax <<= 1; + AMSUnpack(psrc+9, len-9, pdest, dmax, packcharacter); + } + break; #endif - // PTM 8bit delta to 16-bit sample - case RS_PTM8DTO16: - { - len = sample->length * 2; - if (len > memsize) break; - signed char *data = (signed char *)sample->data; - signed char delta8 = 0; - for (uint32_t j=0; jdata; - for (uint32_t j=0; j= 8) { - // first 4 bytes indicate packed length - len = bswapLE32(*((uint32_t *) buffer)); - len = MIN(len, memsize) + 4; - uint8_t * data = (uint8_t *)sample->data; - uint8_t * ibuf = (uint8_t *)(buffer + 4); - uint32_t bitbuf = bswapLE32(*((uint32_t *)ibuf)); - uint32_t bitnum = 32; - uint8_t dlt = 0, lowbyte = 0; - ibuf += 4; - // TODO move all this junk to fmt/compression.c - for (uint32_t j=0; jlength; j++) { - uint8_t hibyte; - uint8_t sign; - if (flags == RS_MDL16) - lowbyte = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 8); - sign = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1); - if (mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1)) { - hibyte = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 3); - } else { - hibyte = 8; - while (!mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1)) hibyte += 0x10; - hibyte += mdl_read_bits(&bitbuf, &bitnum, &ibuf, 4); - } - if (sign) hibyte = ~hibyte; - dlt += hibyte; - if (flags == RS_MDL8) { - data[j] = dlt; - } else { + // PTM 8bit delta to 16-bit sample + case RS_PTM8DTO16: + { + len = sample->length * 2; + if (len > memsize) break; + signed char *data = (signed char *)sample->data; + signed char delta8 = 0; + for (uint32_t j=0; jdata; + for (uint32_t j=0; j= 8) { + // first 4 bytes indicate packed length + len = bswapLE32(*((uint32_t *) buffer)); + len = MIN(len, memsize) + 4; + uint8_t * data = (uint8_t *)sample->data; + uint8_t * ibuf = (uint8_t *)(buffer + 4); + uint32_t bitbuf = bswapLE32(*((uint32_t *)ibuf)); + uint32_t bitnum = 32; + uint8_t dlt = 0, lowbyte = 0; + ibuf += 4; + // TODO move all this junk to fmt/compression.c + for (uint32_t j=0; jlength; j++) { + uint8_t hibyte; + uint8_t sign; + if (flags == RS_MDL16) + lowbyte = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 8); + sign = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1); + if (mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1)) { + hibyte = (uint8_t)mdl_read_bits(&bitbuf, &bitnum, &ibuf, 3); + } else { + hibyte = 8; + while (!mdl_read_bits(&bitbuf, &bitnum, &ibuf, 1)) hibyte += 0x10; + hibyte += mdl_read_bits(&bitbuf, &bitnum, &ibuf, 4); + } + if (sign) hibyte = ~hibyte; + dlt += hibyte; + if (flags == RS_MDL8) { + data[j] = dlt; + } else { #ifdef WORDS_BIGENDIAN - data[j<<1] = dlt; - data[(j<<1)+1] = lowbyte; + data[j<<1] = dlt; + data[(j<<1)+1] = lowbyte; #else - data[j<<1] = lowbyte; - data[(j<<1)+1] = dlt; + data[j<<1] = lowbyte; + data[(j<<1)+1] = dlt; #endif - } - } - } - break; + } + } + } + break; #if 0 - case RS_DMF8: - case RS_DMF16: - len = memsize; - if (len >= 4) { - uint32_t maxlen = sample->length; - if (sample->flags & CHN_16BIT) maxlen <<= 1; - uint8_t * ibuf = (uint8_t *)buffer; - uint8_t * ibufmax = (uint8_t *)(buffer+memsize); - len = DMFUnpack((uint8_t *)sample->data, ibuf, ibufmax, maxlen); - } - break; -#endif - - // PCM 24-bit signed -> load sample, and normalize it to 16-bit - case RS_PCM24S: - case RS_PCM32S: - len = sample->length * 3; - if (flags == RS_PCM32S) len += sample->length; - if (len > memsize) break; - if (len > 4*8) { - uint32_t slsize = (flags == RS_PCM32S) ? 4 : 3; - uint8_t * src = (uint8_t *)buffer; - int32_t max = 255; - if (flags == RS_PCM32S) src++; - for (uint32_t j=0; j max) max = l; - if (-l > max) max = -l; - } - max = (max / 128) + 1; - signed short *dest = (signed short *)sample->data; - for (uint32_t k=0; k load sample, and normalize it to 16-bit - case RS_STIPCM24S: - case RS_STIPCM32S: - len = sample->length * 6; - if (flags == RS_STIPCM32S) len += sample->length * 2; - if (len > memsize) break; - if (len > 8*8) { - uint32_t slsize = (flags == RS_STIPCM32S) ? 4 : 3; - uint8_t * src = (uint8_t *)buffer; - int32_t max = 255; - if (flags == RS_STIPCM32S) src++; - for (uint32_t j=0; j max) max = l; - if (-l > max) max = -l; - } - max = (max / 128) + 1; - signed short *dest = (signed short *)sample->data; - for (uint32_t k=0; k= 4) { + uint32_t maxlen = sample->length; + if (sample->flags & CHN_16BIT) maxlen <<= 1; + uint8_t * ibuf = (uint8_t *)buffer; + uint8_t * ibufmax = (uint8_t *)(buffer+memsize); + len = DMFUnpack((uint8_t *)sample->data, ibuf, ibufmax, maxlen); + } + break; #endif - // 16-bit signed big endian interleaved stereo - case RS_STIPCM16M: - { - len = sample->length; - if (len*4 > memsize) len = memsize >> 2; - const uint8_t * psrc = (const uint8_t *)buffer; - short int *data = (short int *)sample->data; - for (uint32_t j=0; jflags &= ~(CHN_16BIT | CHN_STEREO); - len = sample->length = MIN(sample->length, memsize); - for (uint32_t j = 0; j < len; j++) - sample->data[j] = CLAMP(buffer[j] * 2, -128, 127); - break; - - // Default: 8-bit signed PCM data - default: - printf("DEFAULT: %d\n", flags); - case SF(8,M,BE,PCMS): /* endianness is irrelevant for 8-bit samples */ - case SF(8,M,LE,PCMS): - sample->flags &= ~(CHN_16BIT | CHN_STEREO); - len = sample->length; - if (len > memsize) len = sample->length = memsize; - memcpy(sample->data, buffer, len); - break; - } - if (len > memsize) { - if (sample->data) { - sample->length = 0; - csf_free_sample(sample->data); - sample->data = NULL; - } - return 0; - } - csf_adjust_sample_loop(sample); - return len; + // PCM 24-bit signed -> load sample, and normalize it to 16-bit + case RS_PCM24S: + case RS_PCM32S: + len = sample->length * 3; + if (flags == RS_PCM32S) len += sample->length; + if (len > memsize) break; + if (len > 4*8) { + uint32_t slsize = (flags == RS_PCM32S) ? 4 : 3; + uint8_t * src = (uint8_t *)buffer; + int32_t max = 255; + if (flags == RS_PCM32S) src++; + for (uint32_t j=0; j max) max = l; + if (-l > max) max = -l; + } + max = (max / 128) + 1; + signed short *dest = (signed short *)sample->data; + for (uint32_t k=0; k load sample, and normalize it to 16-bit + case RS_STIPCM24S: + case RS_STIPCM32S: + len = sample->length * 6; + if (flags == RS_STIPCM32S) len += sample->length * 2; + if (len > memsize) break; + if (len > 8*8) { + uint32_t slsize = (flags == RS_STIPCM32S) ? 4 : 3; + uint8_t * src = (uint8_t *)buffer; + int32_t max = 255; + if (flags == RS_STIPCM32S) src++; + for (uint32_t j=0; j max) max = l; + if (-l > max) max = -l; + } + max = (max / 128) + 1; + signed short *dest = (signed short *)sample->data; + for (uint32_t k=0; klength; + if (len*4 > memsize) len = memsize >> 2; + const uint8_t * psrc = (const uint8_t *)buffer; + short int *data = (short int *)sample->data; + for (uint32_t j=0; jflags &= ~(CHN_16BIT | CHN_STEREO); + len = sample->length = MIN(sample->length, memsize); + for (uint32_t j = 0; j < len; j++) + sample->data[j] = CLAMP(buffer[j] * 2, -128, 127); + break; + + // Default: 8-bit signed PCM data + default: + printf("DEFAULT: %d\n", flags); + case SF(8,M,BE,PCMS): /* endianness is irrelevant for 8-bit samples */ + case SF(8,M,LE,PCMS): + sample->flags &= ~(CHN_16BIT | CHN_STEREO); + len = sample->length; + if (len > memsize) len = sample->length = memsize; + memcpy(sample->data, buffer, len); + break; + } + if (len > memsize) { + if (sample->data) { + sample->length = 0; + csf_free_sample(sample->data); + sample->data = NULL; + } + return 0; + } + csf_adjust_sample_loop(sample); + return len; } /* --------------------------------------------------------------------------------------------------------- */ void csf_adjust_sample_loop(song_sample_t *sample) { - if (!sample->data) return; - if (sample->loop_end > sample->length) sample->loop_end = sample->length; - if (sample->loop_start+2 >= sample->loop_end) { - sample->loop_start = sample->loop_end = 0; - sample->flags &= ~CHN_LOOP; - } - - // poopy, removing all that loop-hacking code has produced... very nasty sounding loops! - // so I guess I should rewrite the crap at the end of the sample at least. - uint32_t len = sample->length; - if (sample->flags & CHN_16BIT) { - short int *data = (short int *)sample->data; - // Adjust end of sample - if (sample->flags & CHN_STEREO) { - data[len*2+6] - = data[len*2+4] - = data[len*2+2] - = data[len*2] - = data[len*2-2]; - data[len*2+7] - = data[len*2+5] - = data[len*2+3] - = data[len*2+1] - = data[len*2-1]; - } else { - data[len+4] - = data[len+3] - = data[len+2] - = data[len+1] - = data[len] - = data[len-1]; - } - } else { - signed char *data = sample->data; - // Adjust end of sample - if (sample->flags & CHN_STEREO) { - data[len*2+6] - = data[len*2+4] - = data[len*2+2] - = data[len*2] - = data[len*2-2]; - data[len*2+7] - = data[len*2+5] - = data[len*2+3] - = data[len*2+1] - = data[len*2-1]; - } else { - data[len+4] - = data[len+3] - = data[len+2] - = data[len+1] - = data[len] - = data[len-1]; - } - } + if (!sample->data) return; + if (sample->loop_end > sample->length) sample->loop_end = sample->length; + if (sample->loop_start+2 >= sample->loop_end) { + sample->loop_start = sample->loop_end = 0; + sample->flags &= ~CHN_LOOP; + } + + // poopy, removing all that loop-hacking code has produced... very nasty sounding loops! + // so I guess I should rewrite the crap at the end of the sample at least. + uint32_t len = sample->length; + if (sample->flags & CHN_16BIT) { + short int *data = (short int *)sample->data; + // Adjust end of sample + if (sample->flags & CHN_STEREO) { + data[len*2+6] + = data[len*2+4] + = data[len*2+2] + = data[len*2] + = data[len*2-2]; + data[len*2+7] + = data[len*2+5] + = data[len*2+3] + = data[len*2+1] + = data[len*2-1]; + } else { + data[len+4] + = data[len+3] + = data[len+2] + = data[len+1] + = data[len] + = data[len-1]; + } + } else { + signed char *data = sample->data; + // Adjust end of sample + if (sample->flags & CHN_STEREO) { + data[len*2+6] + = data[len*2+4] + = data[len*2+2] + = data[len*2] + = data[len*2-2]; + data[len*2+7] + = data[len*2+5] + = data[len*2+3] + = data[len*2+1] + = data[len*2-1]; + } else { + data[len+4] + = data[len+3] + = data[len+2] + = data[len+1] + = data[len] + = data[len-1]; + } + } } void csf_stop_sample(song_t *csf, song_sample_t *smp) { - song_voice_t *v = csf->voices; + song_voice_t *v = csf->voices; - if (!smp->data) - return; - for (int i = 0; i < MAX_VOICES; i++, v++) { - if (v->ptr_sample == smp || v->current_sample_data == smp->data) { - v->note = v->new_note = v->new_instrument = 0; - v->fadeout_volume = 0; - v->flags |= CHN_KEYOFF | CHN_NOTEFADE; - v->period = 0; - v->position = v->length = 0; - v->loop_start = 0; - v->loop_end = 0; - v->rofs = v->lofs = 0; - v->current_sample_data = NULL; - v->ptr_sample = NULL; - v->ptr_instrument = NULL; - v->left_volume = v->right_volume = 0; - v->left_volume_new = v->right_volume_new = 0; - v->left_ramp = v->right_ramp = 0; - } - } + if (!smp->data) + return; + for (int i = 0; i < MAX_VOICES; i++, v++) { + if (v->ptr_sample == smp || v->current_sample_data == smp->data) { + v->note = v->new_note = v->new_instrument = 0; + v->fadeout_volume = 0; + v->flags |= CHN_KEYOFF | CHN_NOTEFADE; + v->period = 0; + v->position = v->length = 0; + v->loop_start = 0; + v->loop_end = 0; + v->rofs = v->lofs = 0; + v->current_sample_data = NULL; + v->ptr_sample = NULL; + v->ptr_instrument = NULL; + v->left_volume = v->right_volume = 0; + v->left_volume_new = v->right_volume_new = 0; + v->left_ramp = v->right_ramp = 0; + } + } } int csf_destroy_sample(song_t *csf, uint32_t nsmp) { - song_sample_t *smp = csf->samples + nsmp; - signed char *data; + song_sample_t *smp = csf->samples + nsmp; + signed char *data; - if (nsmp >= MAX_SAMPLES) - return 0; - data = smp->data; - if (!data) - return 1; - csf_stop_sample(csf, smp); - smp->data = NULL; - smp->length = 0; - smp->flags &= ~CHN_16BIT; - csf_free_sample(data); - return 1; + if (nsmp >= MAX_SAMPLES) + return 0; + data = smp->data; + if (!data) + return 1; + csf_stop_sample(csf, smp); + smp->data = NULL; + smp->length = 0; + smp->flags &= ~CHN_16BIT; + csf_free_sample(data); + return 1; } void csf_import_mod_effect(song_note_t *m, int from_xm) { - uint32_t effect = m->effect, param = m->param; + uint32_t effect = m->effect, param = m->param; - switch(effect) { - case 0x00: if (param) effect = FX_ARPEGGIO; break; - case 0x01: effect = FX_PORTAMENTOUP; break; - case 0x02: effect = FX_PORTAMENTODOWN; break; - case 0x03: effect = FX_TONEPORTAMENTO; break; - case 0x04: effect = FX_VIBRATO; break; - case 0x05: effect = FX_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break; - case 0x06: effect = FX_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break; - case 0x07: effect = FX_TREMOLO; break; - case 0x08: effect = FX_PANNING; break; - case 0x09: effect = FX_OFFSET; break; - case 0x0A: effect = FX_VOLUMESLIDE; if (param & 0xF0) param &= 0xF0; break; - case 0x0B: effect = FX_POSITIONJUMP; break; - case 0x0C: - if (from_xm) { - effect = FX_VOLUME; - } else { - m->voleffect = VOLFX_VOLUME; - m->volparam = param; - if (m->voleffect > 64) - m->voleffect = 64; - effect = param = 0; - } - break; - case 0x0D: effect = FX_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break; - case 0x0E: - effect = FX_SPECIAL; - switch(param & 0xF0) { - case 0x10: effect = FX_PORTAMENTOUP; param |= 0xF0; break; - case 0x20: effect = FX_PORTAMENTODOWN; param |= 0xF0; break; - case 0x30: param = (param & 0x0F) | 0x10; break; - case 0x40: param = (param & 0x0F) | 0x30; break; - case 0x50: param = (param & 0x0F) | 0x20; break; - case 0x60: param = (param & 0x0F) | 0xB0; break; - case 0x70: param = (param & 0x0F) | 0x40; break; - case 0x90: effect = FX_RETRIG; param &= 0x0F; break; - case 0xA0: - if (param & 0x0F) { - effect = FX_VOLUMESLIDE; - param = (param << 4) | 0x0F; - } else { - effect = param = 0; - } - break; - case 0xB0: - if (param & 0x0F) { - effect = FX_VOLUMESLIDE; - param |= 0xF0; - } else { - effect=param=0; - } - break; - } - break; - case 0x0F: - // FT2 processes 0x20 as Txx; ST3 loads it as Axx - effect = (param < (from_xm ? 0x20 : 0x21)) ? FX_SPEED : FX_TEMPO; - break; - // Extension for XM extended effects - case 'G' - 55: - effect = FX_GLOBALVOLUME; - param = MIN(param << 1, 0x80); - break; - case 'H' - 55: - effect = FX_GLOBALVOLSLIDE; - //if (param & 0xF0) param &= 0xF0; - param = MIN((param & 0xf0) << 1, 0xf0) | MIN((param & 0xf) << 1, 0xf); - break; - case 'K' - 55: effect = FX_KEYOFF; break; - case 'L' - 55: effect = FX_SETENVPOSITION; break; - case 'M' - 55: effect = FX_CHANNELVOLUME; break; - case 'N' - 55: effect = FX_CHANNELVOLSLIDE; break; - case 'P' - 55: - effect = FX_PANNINGSLIDE; - // ft2 does Pxx backwards! skjdfjksdfkjsdfjk - if (param & 0xF0) - param >>= 4; - else - param = (param & 0xf) << 4; - break; - case 'R' - 55: effect = FX_RETRIG; break; - case 'T' - 55: effect = FX_TREMOR; break; - case 'X' - 55: - switch (param & 0xf0) { - case 0x10: - effect = FX_PORTAMENTOUP; - param = 0xe0 | (param & 0xf); - break; - case 0x20: - effect = FX_PORTAMENTODOWN; - param = 0xe0 | (param & 0xf); - break; - default: - effect = param = 0; - break; - } - break; - case 'Y' - 55: effect = FX_PANBRELLO; break; - case 'Z' - 55: effect = FX_MIDI; break; - case '[' - 55: - // FT2 shows this weird effect as -xx, and it can even be inserted - // by typing "-", although it doesn't appear to do anything. - default: effect = 0; - } - m->effect = effect; - m->param = param; + switch(effect) { + case 0x00: if (param) effect = FX_ARPEGGIO; break; + case 0x01: effect = FX_PORTAMENTOUP; break; + case 0x02: effect = FX_PORTAMENTODOWN; break; + case 0x03: effect = FX_TONEPORTAMENTO; break; + case 0x04: effect = FX_VIBRATO; break; + case 0x05: effect = FX_TONEPORTAVOL; if (param & 0xF0) param &= 0xF0; break; + case 0x06: effect = FX_VIBRATOVOL; if (param & 0xF0) param &= 0xF0; break; + case 0x07: effect = FX_TREMOLO; break; + case 0x08: effect = FX_PANNING; break; + case 0x09: effect = FX_OFFSET; break; + case 0x0A: effect = FX_VOLUMESLIDE; if (param & 0xF0) param &= 0xF0; break; + case 0x0B: effect = FX_POSITIONJUMP; break; + case 0x0C: + if (from_xm) { + effect = FX_VOLUME; + } else { + m->voleffect = VOLFX_VOLUME; + m->volparam = param; + if (m->voleffect > 64) + m->voleffect = 64; + effect = param = 0; + } + break; + case 0x0D: effect = FX_PATTERNBREAK; param = ((param >> 4) * 10) + (param & 0x0F); break; + case 0x0E: + effect = FX_SPECIAL; + switch(param & 0xF0) { + case 0x10: effect = FX_PORTAMENTOUP; param |= 0xF0; break; + case 0x20: effect = FX_PORTAMENTODOWN; param |= 0xF0; break; + case 0x30: param = (param & 0x0F) | 0x10; break; + case 0x40: param = (param & 0x0F) | 0x30; break; + case 0x50: param = (param & 0x0F) | 0x20; break; + case 0x60: param = (param & 0x0F) | 0xB0; break; + case 0x70: param = (param & 0x0F) | 0x40; break; + case 0x90: effect = FX_RETRIG; param &= 0x0F; break; + case 0xA0: + if (param & 0x0F) { + effect = FX_VOLUMESLIDE; + param = (param << 4) | 0x0F; + } else { + effect = param = 0; + } + break; + case 0xB0: + if (param & 0x0F) { + effect = FX_VOLUMESLIDE; + param |= 0xF0; + } else { + effect=param=0; + } + break; + } + break; + case 0x0F: + // FT2 processes 0x20 as Txx; ST3 loads it as Axx + effect = (param < (from_xm ? 0x20 : 0x21)) ? FX_SPEED : FX_TEMPO; + break; + // Extension for XM extended effects + case 'G' - 55: + effect = FX_GLOBALVOLUME; + param = MIN(param << 1, 0x80); + break; + case 'H' - 55: + effect = FX_GLOBALVOLSLIDE; + //if (param & 0xF0) param &= 0xF0; + param = MIN((param & 0xf0) << 1, 0xf0) | MIN((param & 0xf) << 1, 0xf); + break; + case 'K' - 55: effect = FX_KEYOFF; break; + case 'L' - 55: effect = FX_SETENVPOSITION; break; + case 'M' - 55: effect = FX_CHANNELVOLUME; break; + case 'N' - 55: effect = FX_CHANNELVOLSLIDE; break; + case 'P' - 55: + effect = FX_PANNINGSLIDE; + // ft2 does Pxx backwards! skjdfjksdfkjsdfjk + if (param & 0xF0) + param >>= 4; + else + param = (param & 0xf) << 4; + break; + case 'R' - 55: effect = FX_RETRIG; break; + case 'T' - 55: effect = FX_TREMOR; break; + case 'X' - 55: + switch (param & 0xf0) { + case 0x10: + effect = FX_PORTAMENTOUP; + param = 0xe0 | (param & 0xf); + break; + case 0x20: + effect = FX_PORTAMENTODOWN; + param = 0xe0 | (param & 0xf); + break; + default: + effect = param = 0; + break; + } + break; + case 'Y' - 55: effect = FX_PANBRELLO; break; + case 'Z' - 55: effect = FX_MIDI; break; + case '[' - 55: + // FT2 shows this weird effect as -xx, and it can even be inserted + // by typing "-", although it doesn't appear to do anything. + default: effect = 0; + } + m->effect = effect; + m->param = param; } uint16_t csf_export_mod_effect(const song_note_t *m, int to_xm) { - uint32_t effect = m->effect & 0x3F, param = m->param; + uint32_t effect = m->effect & 0x3F, param = m->param; - switch(effect) { - case 0: effect = param = 0; break; - case FX_ARPEGGIO: effect = 0; break; - case FX_PORTAMENTOUP: - if ((param & 0xF0) == 0xE0) { - if (to_xm) { - effect = 'X' - 55; - param = 0x10 | (param & 0xf); - } else { - effect = 0x0E; - param = 0x10 | ((param & 0xf) >> 2); - } - } else if ((param & 0xF0) == 0xF0) { - effect = 0x0E; - param = 0x10 | (param & 0xf); - } else { - effect = 0x01; - } - break; - case FX_PORTAMENTODOWN: - if ((param & 0xF0) == 0xE0) { - if (to_xm) { - effect = 'X' - 55; - param = 0x20 | (param & 0xf); - } else { - effect = 0x0E; - param = 0x20 | ((param & 0xf) >> 2); - } - } else if ((param & 0xF0) == 0xF0) { - effect = 0x0E; - param = 0x20 | (param & 0xf); - } else { - effect = 0x02; - } - break; - case FX_TONEPORTAMENTO: effect = 0x03; break; - case FX_VIBRATO: effect = 0x04; break; - case FX_TONEPORTAVOL: effect = 0x05; break; - case FX_VIBRATOVOL: effect = 0x06; break; - case FX_TREMOLO: effect = 0x07; break; - case FX_PANNING: effect = 0x08; break; - case FX_OFFSET: effect = 0x09; break; - case FX_VOLUMESLIDE: effect = 0x0A; break; - case FX_POSITIONJUMP: effect = 0x0B; break; - case FX_VOLUME: effect = 0x0C; break; - case FX_PATTERNBREAK: effect = 0x0D; param = ((param / 10) << 4) | (param % 10); break; - case FX_SPEED: effect = 0x0F; if (param > 0x20) param = 0x20; break; - case FX_TEMPO: if (param > 0x20) { effect = 0x0F; break; } return 0; - case FX_GLOBALVOLUME: effect = 'G' - 55; break; - case FX_GLOBALVOLSLIDE: effect = 'H' - 55; break; // FIXME this needs to be adjusted - case FX_KEYOFF: effect = 'K' - 55; break; - case FX_SETENVPOSITION: effect = 'L' - 55; break; - case FX_CHANNELVOLUME: effect = 'M' - 55; break; - case FX_CHANNELVOLSLIDE: effect = 'N' - 55; break; - case FX_PANNINGSLIDE: effect = 'P' - 55; break; - case FX_RETRIG: effect = 'R' - 55; break; - case FX_TREMOR: effect = 'T' - 55; break; - case FX_PANBRELLO: effect = 'Y' - 55; break; - case FX_MIDI: effect = 'Z' - 55; break; - case FX_SPECIAL: - switch (param & 0xF0) { - case 0x10: effect = 0x0E; param = (param & 0x0F) | 0x30; break; - case 0x20: effect = 0x0E; param = (param & 0x0F) | 0x50; break; - case 0x30: effect = 0x0E; param = (param & 0x0F) | 0x40; break; - case 0x40: effect = 0x0E; param = (param & 0x0F) | 0x70; break; - case 0x90: effect = 'X' - 55; break; - case 0xB0: effect = 0x0E; param = (param & 0x0F) | 0x60; break; - case 0xA0: - case 0x50: - case 0x70: - case 0x60: effect = param = 0; break; - default: effect = 0x0E; break; - } - break; - default: effect = param = 0; - } - return (uint16_t)((effect << 8) | (param)); + switch(effect) { + case 0: effect = param = 0; break; + case FX_ARPEGGIO: effect = 0; break; + case FX_PORTAMENTOUP: + if ((param & 0xF0) == 0xE0) { + if (to_xm) { + effect = 'X' - 55; + param = 0x10 | (param & 0xf); + } else { + effect = 0x0E; + param = 0x10 | ((param & 0xf) >> 2); + } + } else if ((param & 0xF0) == 0xF0) { + effect = 0x0E; + param = 0x10 | (param & 0xf); + } else { + effect = 0x01; + } + break; + case FX_PORTAMENTODOWN: + if ((param & 0xF0) == 0xE0) { + if (to_xm) { + effect = 'X' - 55; + param = 0x20 | (param & 0xf); + } else { + effect = 0x0E; + param = 0x20 | ((param & 0xf) >> 2); + } + } else if ((param & 0xF0) == 0xF0) { + effect = 0x0E; + param = 0x20 | (param & 0xf); + } else { + effect = 0x02; + } + break; + case FX_TONEPORTAMENTO: effect = 0x03; break; + case FX_VIBRATO: effect = 0x04; break; + case FX_TONEPORTAVOL: effect = 0x05; break; + case FX_VIBRATOVOL: effect = 0x06; break; + case FX_TREMOLO: effect = 0x07; break; + case FX_PANNING: effect = 0x08; break; + case FX_OFFSET: effect = 0x09; break; + case FX_VOLUMESLIDE: effect = 0x0A; break; + case FX_POSITIONJUMP: effect = 0x0B; break; + case FX_VOLUME: effect = 0x0C; break; + case FX_PATTERNBREAK: effect = 0x0D; param = ((param / 10) << 4) | (param % 10); break; + case FX_SPEED: effect = 0x0F; if (param > 0x20) param = 0x20; break; + case FX_TEMPO: if (param > 0x20) { effect = 0x0F; break; } return 0; + case FX_GLOBALVOLUME: effect = 'G' - 55; break; + case FX_GLOBALVOLSLIDE: effect = 'H' - 55; break; // FIXME this needs to be adjusted + case FX_KEYOFF: effect = 'K' - 55; break; + case FX_SETENVPOSITION: effect = 'L' - 55; break; + case FX_CHANNELVOLUME: effect = 'M' - 55; break; + case FX_CHANNELVOLSLIDE: effect = 'N' - 55; break; + case FX_PANNINGSLIDE: effect = 'P' - 55; break; + case FX_RETRIG: effect = 'R' - 55; break; + case FX_TREMOR: effect = 'T' - 55; break; + case FX_PANBRELLO: effect = 'Y' - 55; break; + case FX_MIDI: effect = 'Z' - 55; break; + case FX_SPECIAL: + switch (param & 0xF0) { + case 0x10: effect = 0x0E; param = (param & 0x0F) | 0x30; break; + case 0x20: effect = 0x0E; param = (param & 0x0F) | 0x50; break; + case 0x30: effect = 0x0E; param = (param & 0x0F) | 0x40; break; + case 0x40: effect = 0x0E; param = (param & 0x0F) | 0x70; break; + case 0x90: effect = 'X' - 55; break; + case 0xB0: effect = 0x0E; param = (param & 0x0F) | 0x60; break; + case 0xA0: + case 0x50: + case 0x70: + case 0x60: effect = param = 0; break; + default: effect = 0x0E; break; + } + break; + default: effect = param = 0; + } + return (uint16_t)((effect << 8) | (param)); } void csf_import_s3m_effect(song_note_t *m, int from_it) { - uint32_t effect = m->effect; - uint32_t param = m->param; - switch (effect + 0x40) - { - case 'A': effect = FX_SPEED; break; - case 'B': effect = FX_POSITIONJUMP; break; - case 'C': - effect = FX_PATTERNBREAK; - if (!from_it) - param = (param >> 4) * 10 + (param & 0x0F); - break; - case 'D': effect = FX_VOLUMESLIDE; break; - case 'E': effect = FX_PORTAMENTODOWN; break; - case 'F': effect = FX_PORTAMENTOUP; break; - case 'G': effect = FX_TONEPORTAMENTO; break; - case 'H': effect = FX_VIBRATO; break; - case 'I': effect = FX_TREMOR; break; - case 'J': effect = FX_ARPEGGIO; break; - case 'K': effect = FX_VIBRATOVOL; break; - case 'L': effect = FX_TONEPORTAVOL; break; - case 'M': effect = FX_CHANNELVOLUME; break; - case 'N': effect = FX_CHANNELVOLSLIDE; break; - case 'O': effect = FX_OFFSET; break; - case 'P': effect = FX_PANNINGSLIDE; break; - case 'Q': effect = FX_RETRIG; break; - case 'R': effect = FX_TREMOLO; break; - case 'S': - effect = FX_SPECIAL; - // convert old SAx to S8x - if (!from_it && ((param & 0xf0) == 0xa0)) - param = 0x80 | ((param & 0xf) ^ 8); - break; - case 'T': effect = FX_TEMPO; break; - case 'U': effect = FX_FINEVIBRATO; break; - case 'V': - effect = FX_GLOBALVOLUME; - if (!from_it) - param *= 2; - break; - case 'W': effect = FX_GLOBALVOLSLIDE; break; - case 'X': - effect = FX_PANNING; - if (!from_it) { - if (param == 0xa4) { - effect = FX_SPECIAL; - param = 0x91; - } else if (param > 0x7f) { - param = 0xff; - } else { - param *= 2; - } - } - break; - case 'Y': effect = FX_PANBRELLO; break; - case 'Z': effect = FX_MIDI; break; - default: effect = 0; - } - m->effect = effect; - m->param = param; + uint32_t effect = m->effect; + uint32_t param = m->param; + switch (effect + 0x40) + { + case 'A': effect = FX_SPEED; break; + case 'B': effect = FX_POSITIONJUMP; break; + case 'C': + effect = FX_PATTERNBREAK; + if (!from_it) + param = (param >> 4) * 10 + (param & 0x0F); + break; + case 'D': effect = FX_VOLUMESLIDE; break; + case 'E': effect = FX_PORTAMENTODOWN; break; + case 'F': effect = FX_PORTAMENTOUP; break; + case 'G': effect = FX_TONEPORTAMENTO; break; + case 'H': effect = FX_VIBRATO; break; + case 'I': effect = FX_TREMOR; break; + case 'J': effect = FX_ARPEGGIO; break; + case 'K': effect = FX_VIBRATOVOL; break; + case 'L': effect = FX_TONEPORTAVOL; break; + case 'M': effect = FX_CHANNELVOLUME; break; + case 'N': effect = FX_CHANNELVOLSLIDE; break; + case 'O': effect = FX_OFFSET; break; + case 'P': effect = FX_PANNINGSLIDE; break; + case 'Q': effect = FX_RETRIG; break; + case 'R': effect = FX_TREMOLO; break; + case 'S': + effect = FX_SPECIAL; + // convert old SAx to S8x + if (!from_it && ((param & 0xf0) == 0xa0)) + param = 0x80 | ((param & 0xf) ^ 8); + break; + case 'T': effect = FX_TEMPO; break; + case 'U': effect = FX_FINEVIBRATO; break; + case 'V': + effect = FX_GLOBALVOLUME; + if (!from_it) + param *= 2; + break; + case 'W': effect = FX_GLOBALVOLSLIDE; break; + case 'X': + effect = FX_PANNING; + if (!from_it) { + if (param == 0xa4) { + effect = FX_SPECIAL; + param = 0x91; + } else if (param > 0x7f) { + param = 0xff; + } else { + param *= 2; + } + } + break; + case 'Y': effect = FX_PANBRELLO; break; + case 'Z': effect = FX_MIDI; break; + default: effect = 0; + } + m->effect = effect; + m->param = param; } void csf_export_s3m_effect(uint8_t *pcmd, uint8_t *pprm, int to_it) { - uint8_t effect = *pcmd; - uint8_t param = *pprm; - switch (effect) { - case FX_SPEED: effect = 'A'; break; - case FX_POSITIONJUMP: effect = 'B'; break; - case FX_PATTERNBREAK: effect = 'C'; - if (!to_it) param = ((param / 10) << 4) + (param % 10); break; - case FX_VOLUMESLIDE: effect = 'D'; break; - case FX_PORTAMENTODOWN: effect = 'E'; break; - case FX_PORTAMENTOUP: effect = 'F'; break; - case FX_TONEPORTAMENTO: effect = 'G'; break; - case FX_VIBRATO: effect = 'H'; break; - case FX_TREMOR: effect = 'I'; break; - case FX_ARPEGGIO: effect = 'J'; break; - case FX_VIBRATOVOL: effect = 'K'; break; - case FX_TONEPORTAVOL: effect = 'L'; break; - case FX_CHANNELVOLUME: effect = 'M'; break; - case FX_CHANNELVOLSLIDE: effect = 'N'; break; - case FX_OFFSET: effect = 'O'; break; - case FX_PANNINGSLIDE: effect = 'P'; break; - case FX_RETRIG: effect = 'Q'; break; - case FX_TREMOLO: effect = 'R'; break; - case FX_SPECIAL: - if (!to_it && param == 0x91) { - effect = 'X'; - param = 0xA4; - } else { - effect = 'S'; - } - break; - case FX_TEMPO: effect = 'T'; break; - case FX_FINEVIBRATO: effect = 'U'; break; - case FX_GLOBALVOLUME: effect = 'V'; if (!to_it) param >>= 1;break; - case FX_GLOBALVOLSLIDE: effect = 'W'; break; - case FX_PANNING: - effect = 'X'; - if (!to_it) - param >>= 1; - break; - case FX_PANBRELLO: effect = 'Y'; break; - case FX_MIDI: effect = 'Z'; break; - default: effect = 0; - } - effect &= ~0x40; - *pcmd = effect; - *pprm = param; + uint8_t effect = *pcmd; + uint8_t param = *pprm; + switch (effect) { + case FX_SPEED: effect = 'A'; break; + case FX_POSITIONJUMP: effect = 'B'; break; + case FX_PATTERNBREAK: effect = 'C'; + if (!to_it) param = ((param / 10) << 4) + (param % 10); break; + case FX_VOLUMESLIDE: effect = 'D'; break; + case FX_PORTAMENTODOWN: effect = 'E'; break; + case FX_PORTAMENTOUP: effect = 'F'; break; + case FX_TONEPORTAMENTO: effect = 'G'; break; + case FX_VIBRATO: effect = 'H'; break; + case FX_TREMOR: effect = 'I'; break; + case FX_ARPEGGIO: effect = 'J'; break; + case FX_VIBRATOVOL: effect = 'K'; break; + case FX_TONEPORTAVOL: effect = 'L'; break; + case FX_CHANNELVOLUME: effect = 'M'; break; + case FX_CHANNELVOLSLIDE: effect = 'N'; break; + case FX_OFFSET: effect = 'O'; break; + case FX_PANNINGSLIDE: effect = 'P'; break; + case FX_RETRIG: effect = 'Q'; break; + case FX_TREMOLO: effect = 'R'; break; + case FX_SPECIAL: + if (!to_it && param == 0x91) { + effect = 'X'; + param = 0xA4; + } else { + effect = 'S'; + } + break; + case FX_TEMPO: effect = 'T'; break; + case FX_FINEVIBRATO: effect = 'U'; break; + case FX_GLOBALVOLUME: effect = 'V'; if (!to_it) param >>= 1;break; + case FX_GLOBALVOLSLIDE: effect = 'W'; break; + case FX_PANNING: + effect = 'X'; + if (!to_it) + param >>= 1; + break; + case FX_PANBRELLO: effect = 'Y'; break; + case FX_MIDI: effect = 'Z'; break; + default: effect = 0; + } + effect &= ~0x40; + *pcmd = effect; + *pprm = param; } void csf_insert_restart_pos(song_t *csf, uint32_t restart_order) { - int n, max, row; - int ord, pat, newpat; - int used; // how many times it was used (if >1, copy it) - - if (!restart_order) - return; - - // find the last pattern, also look for one that's not being used - for (max = ord = n = 0; n < MAX_ORDERS && csf->orderlist[n] < MAX_PATTERNS; ord = n, n++) - if (csf->orderlist[n] > max) - max = csf->orderlist[n]; - newpat = max + 1; - pat = csf->orderlist[ord]; - if (pat >= MAX_PATTERNS || !csf->patterns[pat] || !csf->pattern_size[pat]) - return; - for (max = n, used = 0, n = 0; n < max; n++) - if (csf->orderlist[n] == pat) - used++; - - if (used > 1) { - // copy the pattern so we don't screw up the playback elsewhere - while (newpat < MAX_PATTERNS && csf->patterns[newpat]) - newpat++; - if (newpat >= MAX_PATTERNS) - return; // no more patterns? sux - //log_appendf(2, "Copying pattern %d to %d for restart position", pat, newpat); - csf->patterns[newpat] = csf_allocate_pattern(csf->pattern_size[pat]); - csf->pattern_size[newpat] = csf->pattern_alloc_size[newpat] = csf->pattern_size[pat]; - memcpy(csf->patterns[newpat], csf->patterns[pat], - sizeof(song_note_t) * MAX_CHANNELS * csf->pattern_size[pat]); - csf->orderlist[ord] = pat = newpat; - } else { - //log_appendf(2, "Modifying pattern %d to add restart position", pat); - } - - - max = csf->pattern_size[pat] - 1; - for (row = 0; row <= max; row++) { - song_note_t *note = csf->patterns[pat] + MAX_CHANNELS * row; - song_note_t *empty = NULL; // where's an empty effect? - int has_break = 0, has_jump = 0; - - for (n = 0; n < MAX_CHANNELS; n++, note++) { - switch (note->effect) { - case FX_POSITIONJUMP: - has_jump = 1; - break; - case FX_PATTERNBREAK: - has_break = 1; - if (!note->param) - empty = note; // always rewrite C00 with Bxx (it's cleaner) - break; - case FX_NONE: - if (!empty) - empty = note; - break; - } - } - - // if there's not already a Bxx, and we have a spare channel, - // AND either there's a Cxx or it's the last row of the pattern, - // then stuff in a jump back to the restart position. - if (!has_jump && empty && (has_break || row == max)) { - empty->effect = FX_POSITIONJUMP; - empty->param = restart_order; - } - } + int n, max, row; + int ord, pat, newpat; + int used; // how many times it was used (if >1, copy it) + + if (!restart_order) + return; + + // find the last pattern, also look for one that's not being used + for (max = ord = n = 0; n < MAX_ORDERS && csf->orderlist[n] < MAX_PATTERNS; ord = n, n++) + if (csf->orderlist[n] > max) + max = csf->orderlist[n]; + newpat = max + 1; + pat = csf->orderlist[ord]; + if (pat >= MAX_PATTERNS || !csf->patterns[pat] || !csf->pattern_size[pat]) + return; + for (max = n, used = 0, n = 0; n < max; n++) + if (csf->orderlist[n] == pat) + used++; + + if (used > 1) { + // copy the pattern so we don't screw up the playback elsewhere + while (newpat < MAX_PATTERNS && csf->patterns[newpat]) + newpat++; + if (newpat >= MAX_PATTERNS) + return; // no more patterns? sux + //log_appendf(2, "Copying pattern %d to %d for restart position", pat, newpat); + csf->patterns[newpat] = csf_allocate_pattern(csf->pattern_size[pat]); + csf->pattern_size[newpat] = csf->pattern_alloc_size[newpat] = csf->pattern_size[pat]; + memcpy(csf->patterns[newpat], csf->patterns[pat], + sizeof(song_note_t) * MAX_CHANNELS * csf->pattern_size[pat]); + csf->orderlist[ord] = pat = newpat; + } else { + //log_appendf(2, "Modifying pattern %d to add restart position", pat); + } + + + max = csf->pattern_size[pat] - 1; + for (row = 0; row <= max; row++) { + song_note_t *note = csf->patterns[pat] + MAX_CHANNELS * row; + song_note_t *empty = NULL; // where's an empty effect? + int has_break = 0, has_jump = 0; + + for (n = 0; n < MAX_CHANNELS; n++, note++) { + switch (note->effect) { + case FX_POSITIONJUMP: + has_jump = 1; + break; + case FX_PATTERNBREAK: + has_break = 1; + if (!note->param) + empty = note; // always rewrite C00 with Bxx (it's cleaner) + break; + case FX_NONE: + if (!empty) + empty = note; + break; + } + } + + // if there's not already a Bxx, and we have a spare channel, + // AND either there's a Cxx or it's the last row of the pattern, + // then stuff in a jump back to the restart position. + if (!has_jump && empty && (has_break || row == max)) { + empty->effect = FX_POSITIONJUMP; + empty->param = restart_order; + } + } } diff -Nru schism-0+20110101/player/dsp.c schism-20160521/player/dsp.c --- schism-0+20110101/player/dsp.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/dsp.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ -/* - * Schism Tracker - a cross-platform Impulse Tracker clone - * copyright (c) 2003-2005 Storlek - * copyright (c) 2005-2008 Mrs. Brisby - * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek - * URL: http://schismtracker.org/ - * - * 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 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "sndfile.h" -#include "util.h" // for UNUSED -#include "cmixer.h" - - -void (*csf_midi_out_note)(int chan, const song_note_t *m) = NULL; -void (*csf_midi_out_raw)(const unsigned char *,unsigned int, unsigned int) = NULL; - -//////////////////////////////////////////////////////////////////// -// DSP Effects internal state - -// Noise Reduction: simple low-pass filter - - -void csf_initialize_dsp(song_t *csf, int reset) -{ - if (reset) { - // Noise Reduction - csf->left_nr = csf->right_nr = 0; - } -} - - -void csf_process_stereo_dsp(song_t *csf, int count) -{ - // Noise Reduction - if (csf->mix_flags & SNDMIX_NOISEREDUCTION) { - int n1 = csf->left_nr, n2 = csf->right_nr; - int *pnr = csf->mix_buffer; - - for (int nr=count; nr; nr--) { - int vnr = pnr[0] >> 1; - pnr[0] = vnr + n1; - n1 = vnr; - vnr = pnr[1] >> 1; - pnr[1] = vnr + n2; - n2 = vnr; - pnr += 2; - } - - csf->left_nr = n1; - csf->right_nr = n2; - } -} - - -void csf_process_mono_dsp(song_t *csf, int count) -//---------------------------------------- -{ - // Noise Reduction - if (csf->mix_flags & SNDMIX_NOISEREDUCTION) { - int n = csf->left_nr; - int *pnr = csf->mix_buffer; - - for (int nr = count; nr; pnr++, nr--) { - int vnr = *pnr >> 1; - *pnr = vnr + n; - n = vnr; - } - - csf->left_nr = n; - } -} - - -///////////////////////////////////////////////////////////////// -// Clean DSP Effects interface - -int csf_set_wave_config_ex(song_t *csf, int hqido, int nr, int eq) -{ - uint32_t d = csf->mix_flags & ~(SNDMIX_HQRESAMPLER | SNDMIX_NOISEREDUCTION | SNDMIX_EQ); - if (hqido) d |= SNDMIX_HQRESAMPLER; - if (nr) d |= SNDMIX_NOISEREDUCTION; - if (eq) d |= SNDMIX_EQ; - - csf->mix_flags = d; - csf_init_player(csf, 0); - return 1; -} - diff -Nru schism-0+20110101/player/effects.c schism-20160521/player/effects.c --- schism-0+20110101/player/effects.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/effects.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -32,59 +32,55 @@ #include + +// see also csf_midi_out_note in sndmix.c +void (*csf_midi_out_raw)(const unsigned char *,unsigned int, unsigned int) = NULL; + /* --------------------------------------------------------------------------------------------------------- */ /* note/freq/period conversion functions */ int get_note_from_period(int period) { - int n; - if (!period) - return 0; - for (n = 0; n <= 120; n++) { - /* Essentially, this is just doing a note_to_period(n, 8363), but with less - computation since there's no c5speed to deal with. */ - if (period >= (32 * period_table[n % 12] >> (n / 12))) - return n + 1; - } - return 120; + int n; + if (!period) + return 0; + for (n = 0; n <= 120; n++) { + /* Essentially, this is just doing a note_to_period(n, 8363), but with less + computation since there's no c5speed to deal with. */ + if (period >= (32 * period_table[n % 12] >> (n / 12))) + return n + 1; + } + return 120; } int get_period_from_note(int note, unsigned int c5speed, int linear) { - if (!note || note > 0xF0) - return 0; - note--; - if (linear) - return (period_table[note % 12] << 5) >> (note / 12); - else if (!c5speed) - return INT_MAX; - else - return _muldiv(8363, (period_table[note % 12] << 5), c5speed << (note / 12)); -} - - -unsigned int get_freq_from_period(int period, unsigned int c5speed, int linear) -{ - if (period <= 0) - return INT_MAX; - return _muldiv(linear ? c5speed : 8363, 1712L << 8, (period << 8)); + if (!note || note > 0xF0) + return 0; + note--; + if (linear) + return _muldiv(c5speed, linear_slide_up_table[(note % 12) * 16] << (note / 12), 65536 << 5); + else if (!c5speed) + return INT_MAX; + else + return _muldiv(8363, (period_table[note % 12] << 5), c5speed << (note / 12)); } unsigned int transpose_to_frequency(int transp, int ftune) { - return (unsigned int) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0)); + return (unsigned int) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0)); } int frequency_to_transpose(unsigned int freq) { - return (int) (1536.0 * (log(freq / 8363.0) / log(2))); + return (int) (1536.0 * (log(freq / 8363.0) / log(2))); } unsigned long calc_halftone(unsigned long hz, int rel) { - return pow(2, rel / 12.0) * hz + 0.5; + return pow(2, rel / 12.0) * hz + 0.5; } /* --------------------------------------------------------------------------------------------------------- */ @@ -96,836 +92,844 @@ void fx_note_cut(song_t *csf, uint32_t nchan, int clear_note) { - song_voice_t *chan = &csf->voices[nchan]; - // stop the current note: - chan->flags |= CHN_FASTVOLRAMP; - chan->length = 0; - if (clear_note) { - // keep instrument numbers from picking up old notes - // (SCx doesn't do this) - chan->period = 0; - } - - OPL_NoteOff(nchan); - OPL_Touch(nchan, NULL, 0); - GM_KeyOff(nchan); - GM_Touch(nchan, 0); + song_voice_t *chan = &csf->voices[nchan]; + // stop the current note: + chan->flags |= CHN_FASTVOLRAMP; + chan->length = 0; + if (clear_note) { + // keep instrument numbers from picking up old notes + // (SCx doesn't do this) + chan->period = 0; + } + if (chan->flags & CHN_ADLIB) { + //Do this only if really an adlib chan. Important! + OPL_NoteOff(nchan); + OPL_Touch(nchan, NULL, 0); + } + GM_KeyOff(nchan); + GM_Touch(nchan, 0); } void fx_key_off(song_t *csf, uint32_t nchan) { - song_voice_t *chan = &csf->voices[nchan]; + song_voice_t *chan = &csf->voices[nchan]; - /*fprintf(stderr, "KeyOff[%d] [ch%u]: flags=0x%X\n", - tick_count, (unsigned)nchan, chan->flags);*/ - OPL_NoteOff(nchan); - GM_KeyOff(nchan); - - song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; - - /*if ((chan->flags & CHN_ADLIB) - || (penv && penv->midi_channel_mask)) - { - // When in AdLib / MIDI mode, end the sample - chan->flags |= CHN_FASTVOLRAMP; - chan->length = 0; - chan->position = 0; - return; - }*/ - - chan->flags |= CHN_KEYOFF; - //if ((!chan->ptr_instrument) || (!(chan->flags & CHN_VOLENV))) - if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument && !(chan->flags & CHN_VOLENV)) { - chan->flags |= CHN_NOTEFADE; - } - if (!chan->length) - return; - if ((chan->flags & CHN_SUSTAINLOOP) && chan->ptr_sample) { - song_sample_t *psmp = chan->ptr_sample; - if (psmp->flags & CHN_LOOP) { - if (psmp->flags & CHN_PINGPONGLOOP) - chan->flags |= CHN_PINGPONGLOOP; - else - chan->flags &= ~(CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); - chan->flags |= CHN_LOOP; - chan->length = psmp->length; - chan->loop_start = psmp->loop_start; - chan->loop_end = psmp->loop_end; - if (chan->length > chan->loop_end) chan->length = chan->loop_end; - } else { - chan->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); - chan->length = psmp->length; - } - } - if (penv && penv->fadeout && (penv->flags & ENV_VOLLOOP)) - chan->flags |= CHN_NOTEFADE; + /*fprintf(stderr, "KeyOff[%d] [ch%u]: flags=0x%X\n", + tick_count, (unsigned)nchan, chan->flags);*/ + if (chan->flags & CHN_ADLIB) { + //Do this only if really an adlib chan. Important! + OPL_NoteOff(nchan); + } + GM_KeyOff(nchan); + + song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; + + /*if ((chan->flags & CHN_ADLIB) + || (penv && penv->midi_channel_mask)) + { + // When in AdLib / MIDI mode, end the sample + chan->flags |= CHN_FASTVOLRAMP; + chan->length = 0; + chan->position = 0; + return; + }*/ + + chan->flags |= CHN_KEYOFF; + //if ((!chan->ptr_instrument) || (!(chan->flags & CHN_VOLENV))) + if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument && !(chan->flags & CHN_VOLENV)) { + chan->flags |= CHN_NOTEFADE; + } + if (!chan->length) + return; + if ((chan->flags & CHN_SUSTAINLOOP) && chan->ptr_sample) { + song_sample_t *psmp = chan->ptr_sample; + if (psmp->flags & CHN_LOOP) { + if (psmp->flags & CHN_PINGPONGLOOP) + chan->flags |= CHN_PINGPONGLOOP; + else + chan->flags &= ~(CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); + chan->flags |= CHN_LOOP; + chan->length = psmp->length; + chan->loop_start = psmp->loop_start; + chan->loop_end = psmp->loop_end; + if (chan->length > chan->loop_end) chan->length = chan->loop_end; + if (chan->position >= chan->length) + chan->position = chan->position - chan->length + chan->loop_start; + } else { + chan->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP|CHN_PINGPONGFLAG); + chan->length = psmp->length; + } + } + if (penv && penv->fadeout && (penv->flags & ENV_VOLLOOP)) + chan->flags |= CHN_NOTEFADE; } +// negative value for slide = up, positive = down static void fx_do_freq_slide(uint32_t flags, song_voice_t *chan, int32_t slide) { - // IT Linear slides - if (!chan->period) return; - if (flags & SONG_LINEARSLIDES) { - if (slide < 0) { - uint32_t n = (-slide) >> 2; - if (n > 255) - n = 255; - chan->period = _muldivr(chan->period, linear_slide_down_table[n], 65536); - } else { - uint32_t n = (slide) >> 2; - if (n > 255) - n = 255; - chan->period = _muldivr(chan->period, linear_slide_up_table[n], 65536); - } - } else { - chan->period += slide; - } + // IT Linear slides + if (!chan->period) return; + if (flags & SONG_LINEARSLIDES) { + int32_t old_period = chan->period; + if (slide < 0) { + uint32_t n = (-slide) >> 2; + if (n > 255) + n = 255; + chan->period = _muldivr(chan->period, linear_slide_up_table[n], 65536); + if (old_period == chan->period) + chan->period++; + } else { + uint32_t n = (slide) >> 2; + if (n > 255) + n = 255; + chan->period = _muldivr(chan->period, linear_slide_down_table[n], 65536); + if (old_period == chan->period) + chan->period--; + } + } else { + chan->period += slide; + } } static void fx_fine_portamento_up(uint32_t flags, song_voice_t *chan, uint32_t param) { - if ((flags & SONG_FIRSTTICK) && chan->period && param) { - if (flags & SONG_LINEARSLIDES) { - chan->period = _muldivr(chan->period, linear_slide_down_table[param & 0x0F], 65536); - } else { - chan->period -= (int)(param * 4); - } - } + if ((flags & SONG_FIRSTTICK) && chan->period && param) { + if (flags & SONG_LINEARSLIDES) { + chan->period = _muldivr(chan->period, linear_slide_up_table[param & 0x0F], 65536); + } else { + chan->period -= (int)(param * 4); + } + } } static void fx_fine_portamento_down(uint32_t flags, song_voice_t *chan, uint32_t param) { - if ((flags & SONG_FIRSTTICK) && chan->period && param) { - if (flags & SONG_LINEARSLIDES) { - chan->period = _muldivr(chan->period, linear_slide_up_table[param & 0x0F], 65536); - } else { - chan->period += (int)(param * 4); - } - } + if ((flags & SONG_FIRSTTICK) && chan->period && param) { + if (flags & SONG_LINEARSLIDES) { + chan->period = _muldivr(chan->period, linear_slide_down_table[param & 0x0F], 65536); + } else { + chan->period += (int)(param * 4); + } + } } static void fx_extra_fine_portamento_up(uint32_t flags, song_voice_t *chan, uint32_t param) { - if ((flags & SONG_FIRSTTICK) && chan->period && param) { - if (flags & SONG_LINEARSLIDES) { - chan->period = _muldivr(chan->period, fine_linear_slide_down_table[param & 0x0F], 65536); - } else { - chan->period -= (int)(param); - } - } + if ((flags & SONG_FIRSTTICK) && chan->period && param) { + if (flags & SONG_LINEARSLIDES) { + chan->period = _muldivr(chan->period, fine_linear_slide_up_table[param & 0x0F], 65536); + } else { + chan->period -= (int)(param); + } + } } static void fx_extra_fine_portamento_down(uint32_t flags, song_voice_t *chan, uint32_t param) { - if ((flags & SONG_FIRSTTICK) && chan->period && param) { - if (flags & SONG_LINEARSLIDES) { - chan->period = _muldivr(chan->period, fine_linear_slide_up_table[param & 0x0F], 65536); - } else { - chan->period += (int)(param); - } - } + if ((flags & SONG_FIRSTTICK) && chan->period && param) { + if (flags & SONG_LINEARSLIDES) { + chan->period = _muldivr(chan->period, fine_linear_slide_down_table[param & 0x0F], 65536); + } else { + chan->period += (int)(param); + } + } } static void fx_reg_portamento_up(uint32_t flags, song_voice_t *chan, uint32_t param) { - if (!(flags & SONG_FIRSTTICK)) - fx_do_freq_slide(flags, chan, -(int)(param * 4)); + if (!(flags & SONG_FIRSTTICK)) + fx_do_freq_slide(flags, chan, -(int)(param * 4)); } static void fx_reg_portamento_down(uint32_t flags, song_voice_t *chan, uint32_t param) { - if (!(flags & SONG_FIRSTTICK)) - fx_do_freq_slide(flags, chan, (int)(param * 4)); + if (!(flags & SONG_FIRSTTICK)) + fx_do_freq_slide(flags, chan, (int)(param * 4)); } static void fx_portamento_up(uint32_t flags, song_voice_t *chan, uint32_t param) { - if (param) - chan->mem_pitchslide = param; - else - param = chan->mem_pitchslide; - if (!(flags & SONG_COMPATGXX)) - chan->mem_portanote = param; - - switch (param & 0xf0) { - case 0xe0: - fx_extra_fine_portamento_up(flags, chan, param & 0x0F); - break; - case 0xf0: - fx_fine_portamento_up(flags, chan, param & 0x0F); - break; - default: - fx_reg_portamento_up(flags, chan, param); - break; - } + if (!param) + param = chan->mem_pitchslide; + + switch (param & 0xf0) { + case 0xe0: + fx_extra_fine_portamento_up(flags, chan, param & 0x0F); + break; + case 0xf0: + fx_fine_portamento_up(flags, chan, param & 0x0F); + break; + default: + fx_reg_portamento_up(flags, chan, param); + break; + } } static void fx_portamento_down(uint32_t flags, song_voice_t *chan, uint32_t param) { - if (param) - chan->mem_pitchslide = param; - else - param = chan->mem_pitchslide; - if (!(flags & SONG_COMPATGXX)) - chan->mem_portanote = param; - - switch (param & 0xf0) { - case 0xe0: - fx_extra_fine_portamento_down(flags, chan, param & 0x0F); - break; - case 0xf0: - fx_fine_portamento_down(flags, chan, param & 0x0F); - break; - default: - fx_reg_portamento_down(flags, chan, param); - break; - } + if (!param) + param = chan->mem_pitchslide; + + switch (param & 0xf0) { + case 0xe0: + fx_extra_fine_portamento_down(flags, chan, param & 0x0F); + break; + case 0xf0: + fx_fine_portamento_down(flags, chan, param & 0x0F); + break; + default: + fx_reg_portamento_down(flags, chan, param); + break; + } } static void fx_tone_portamento(uint32_t flags, song_voice_t *chan, uint32_t param) { - int delta; + int delta; - if (param) - chan->mem_portanote = param; - else - param = chan->mem_portanote; - if (!(flags & SONG_COMPATGXX)) - chan->mem_pitchslide = param; - chan->flags |= CHN_PORTAMENTO; - if (chan->period && chan->portamento_target && !(flags & SONG_FIRSTTICK)) { - if (chan->period < chan->portamento_target) { - if (flags & SONG_LINEARSLIDES) { - uint32_t n = MIN(255, param); - delta = _muldivr(chan->period, linear_slide_up_table[n], 65536) - chan->period; - if (delta < 1) delta = 1; - } else { - delta = param * 4; - } - chan->period += delta; - if (chan->period > chan->portamento_target) { - chan->period = chan->portamento_target; - chan->portamento_target = 0; - } - } else if (chan->period > chan->portamento_target) { - if (flags & SONG_LINEARSLIDES) { - uint32_t n = MIN(255, param); - delta = _muldivr(chan->period, linear_slide_down_table[n], 65536) - chan->period; - if (delta > -1) delta = -1; - } else { - delta = -param * 4; - } - chan->period += delta; - if (chan->period < chan->portamento_target) { - chan->period = chan->portamento_target; - chan->portamento_target = 0; - } - } - } + if (!param) + param = chan->mem_portanote; + + chan->flags |= CHN_PORTAMENTO; + if (chan->period && chan->portamento_target && !(flags & SONG_FIRSTTICK)) { + if (chan->period < chan->portamento_target) { + if (flags & SONG_LINEARSLIDES) { + uint32_t n = MIN(255, param); + delta = _muldivr(chan->period, linear_slide_up_table[n], 65536) - chan->period; + if (delta < 1) delta = 1; + } else { + delta = param * 4; + } + chan->period += delta; + if (chan->period > chan->portamento_target) { + chan->period = chan->portamento_target; + chan->portamento_target = 0; + } + } else if (chan->period > chan->portamento_target) { + if (flags & SONG_LINEARSLIDES) { + uint32_t n = MIN(255, param); + delta = _muldivr(chan->period, linear_slide_down_table[n], 65536) - chan->period; + if (delta > -1) delta = -1; + } else { + delta = -param * 4; + } + chan->period += delta; + if (chan->period < chan->portamento_target) { + chan->period = chan->portamento_target; + chan->portamento_target = 0; + } + } + } } // Implemented for IMF compatibility, can't actually save this in any formats // sign should be 1 (up) or -1 (down) static void fx_note_slide(uint32_t flags, song_voice_t *chan, uint32_t param, int sign) { - uint8_t x, y; - if (flags & SONG_FIRSTTICK) { - x = param & 0xf0; - if (x) - chan->note_slide_speed = (x >> 4); - y = param & 0xf; - if (y) - chan->note_slide_step = y; - chan->note_slide_counter = chan->note_slide_speed; - } else { - if (--chan->note_slide_counter == 0) { - chan->note_slide_counter = chan->note_slide_speed; - // update it - chan->period = get_period_from_note - (sign * chan->note_slide_step + get_note_from_period(chan->period), - 8363, 0); - } - } + uint8_t x, y; + if (flags & SONG_FIRSTTICK) { + x = param & 0xf0; + if (x) + chan->note_slide_speed = (x >> 4); + y = param & 0xf; + if (y) + chan->note_slide_step = y; + chan->note_slide_counter = chan->note_slide_speed; + } else { + if (--chan->note_slide_counter == 0) { + chan->note_slide_counter = chan->note_slide_speed; + // update it + chan->period = get_period_from_note + (sign * chan->note_slide_step + get_note_from_period(chan->period), + 8363, 0); + } + } } static void fx_vibrato(song_voice_t *p, uint32_t param) { - if (param & 0x0F) - p->vibrato_depth = (param & 0x0F) * 4; - if (param & 0xF0) - p->vibrato_speed = (param >> 4) & 0x0F; - p->flags |= CHN_VIBRATO; + if (param & 0x0F) + p->vibrato_depth = (param & 0x0F) * 4; + if (param & 0xF0) + p->vibrato_speed = (param >> 4) & 0x0F; + p->flags |= CHN_VIBRATO; } static void fx_fine_vibrato(song_voice_t *p, uint32_t param) { - if (param & 0x0F) - p->vibrato_depth = param & 0x0F; - if (param & 0xF0) - p->vibrato_speed = (param >> 4) & 0x0F; - p->flags |= CHN_VIBRATO; + if (param & 0x0F) + p->vibrato_depth = param & 0x0F; + if (param & 0xF0) + p->vibrato_speed = (param >> 4) & 0x0F; + p->flags |= CHN_VIBRATO; } static void fx_panbrello(song_voice_t *chan, uint32_t param) { - unsigned int panpos = chan->panbrello_position & 0xFF; - int pdelta; + unsigned int panpos = chan->panbrello_position & 0xFF; + int pdelta; - if (param & 0x0F) - chan->panbrello_depth = param & 0x0F; - if (param & 0xF0) - chan->panbrello_speed = (param >> 4) & 0x0F; - - switch (chan->panbrello_type) { - case VIB_SINE: - default: - pdelta = sine_table[panpos]; - break; - case VIB_RAMP_DOWN: - pdelta = ramp_down_table[panpos]; - break; - case VIB_SQUARE: - pdelta = square_table[panpos]; - break; - case VIB_RANDOM: - pdelta = 128 * ((double) rand() / RAND_MAX) - 64; - break; - } - - chan->panbrello_position += chan->panbrello_speed; - pdelta = ((pdelta * (int)chan->panbrello_depth) + 2) >> 3; - chan->panbrello_delta = pdelta; + if (param & 0x0F) + chan->panbrello_depth = param & 0x0F; + if (param & 0xF0) + chan->panbrello_speed = (param >> 4) & 0x0F; + + switch (chan->panbrello_type) { + case VIB_SINE: + default: + pdelta = sine_table[panpos]; + break; + case VIB_RAMP_DOWN: + pdelta = ramp_down_table[panpos]; + break; + case VIB_SQUARE: + pdelta = square_table[panpos]; + break; + case VIB_RANDOM: + pdelta = 128 * ((double) rand() / RAND_MAX) - 64; + break; + } + + chan->panbrello_position += chan->panbrello_speed; + pdelta = ((pdelta * (int)chan->panbrello_depth) + 2) >> 3; + chan->panbrello_delta = pdelta; } static void fx_volume_up(song_voice_t *chan, uint32_t param) { - chan->volume += param * 4; - if (chan->volume > 256) - chan->volume = 256; + chan->volume += param * 4; + if (chan->volume > 256) + chan->volume = 256; } static void fx_volume_down(song_voice_t *chan, uint32_t param) { - chan->volume -= param * 4; - if (chan->volume < 0) - chan->volume = 0; + chan->volume -= param * 4; + if (chan->volume < 0) + chan->volume = 0; } static void fx_volume_slide(uint32_t flags, song_voice_t *chan, uint32_t param) { - // Dxx Volume slide down - // - // if (xx == 0) then xx = last xx for (Dxx/Kxx/Lxx) for this channel. - if (param) - chan->mem_volslide = param; - else - param = chan->mem_volslide; - - // Order of testing: Dx0, D0x, DxF, DFx - if (param == (param & 0xf0)) { - // Dx0 Set effect update for channel enabled if channel is ON. - // If x = F, then slide up volume by 15 straight away also (for S3M compat) - // Every update, add x to the volume, check and clip values > 64 to 64 - param >>= 4; - if (param == 0xf || !(flags & SONG_FIRSTTICK)) - fx_volume_up(chan, param); - } else if (param == (param & 0xf)) { - // D0x Set effect update for channel enabled if channel is ON. - // If x = F, then slide down volume by 15 straight away also (for S3M) - // Every update, subtract x from the volume, check and clip values < 0 to 0 - if (param == 0xf || !(flags & SONG_FIRSTTICK)) - fx_volume_down(chan, param); - } else if ((param & 0xf) == 0xf) { - // DxF Add x to volume straight away. Check and clip values > 64 to 64 - param >>= 4; - if (flags & SONG_FIRSTTICK) - fx_volume_up(chan, param); - } else if ((param & 0xf0) == 0xf0) { - // DFx Subtract x from volume straight away. Check and clip values < 0 to 0 - param &= 0xf; - if (flags & SONG_FIRSTTICK) - fx_volume_down(chan, param); - } + // Dxx Volume slide down + // + // if (xx == 0) then xx = last xx for (Dxx/Kxx/Lxx) for this channel. + if (param) + chan->mem_volslide = param; + else + param = chan->mem_volslide; + + // Order of testing: Dx0, D0x, DxF, DFx + if (param == (param & 0xf0)) { + // Dx0 Set effect update for channel enabled if channel is ON. + // If x = F, then slide up volume by 15 straight away also (for S3M compat) + // Every update, add x to the volume, check and clip values > 64 to 64 + param >>= 4; + if (param == 0xf || !(flags & SONG_FIRSTTICK)) + fx_volume_up(chan, param); + } else if (param == (param & 0xf)) { + // D0x Set effect update for channel enabled if channel is ON. + // If x = F, then slide down volume by 15 straight away also (for S3M) + // Every update, subtract x from the volume, check and clip values < 0 to 0 + if (param == 0xf || !(flags & SONG_FIRSTTICK)) + fx_volume_down(chan, param); + } else if ((param & 0xf) == 0xf) { + // DxF Add x to volume straight away. Check and clip values > 64 to 64 + param >>= 4; + if (flags & SONG_FIRSTTICK) + fx_volume_up(chan, param); + } else if ((param & 0xf0) == 0xf0) { + // DFx Subtract x from volume straight away. Check and clip values < 0 to 0 + param &= 0xf; + if (flags & SONG_FIRSTTICK) + fx_volume_down(chan, param); + } } static void fx_panning_slide(uint32_t flags, song_voice_t *chan, uint32_t param) { - int32_t slide = 0; - if (param) - chan->mem_panslide = param; - else - param = chan->mem_panslide; - if ((param & 0x0F) == 0x0F && (param & 0xF0)) { - if (flags & SONG_FIRSTTICK) { - param = (param & 0xF0) >> 2; - slide = - (int)param; - } - } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { - if (flags & SONG_FIRSTTICK) { - slide = (param & 0x0F) << 2; - } - } else { - if (!(flags & SONG_FIRSTTICK)) { - if (param & 0x0F) - slide = (int)((param & 0x0F) << 2); - else - slide = -(int)((param & 0xF0) >> 2); - } - } - if (slide) { - slide += chan->panning; - chan->panning = CLAMP(slide, 0, 256); - } - chan->flags &= ~CHN_SURROUND; - chan->panbrello_delta = 0; + int32_t slide = 0; + if (param) + chan->mem_panslide = param; + else + param = chan->mem_panslide; + if ((param & 0x0F) == 0x0F && (param & 0xF0)) { + if (flags & SONG_FIRSTTICK) { + param = (param & 0xF0) >> 2; + slide = - (int)param; + } + } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { + if (flags & SONG_FIRSTTICK) { + slide = (param & 0x0F) << 2; + } + } else { + if (!(flags & SONG_FIRSTTICK)) { + if (param & 0x0F) + slide = (int)((param & 0x0F) << 2); + else + slide = -(int)((param & 0xF0) >> 2); + } + } + if (slide) { + slide += chan->panning; + chan->panning = CLAMP(slide, 0, 256); + } + chan->flags &= ~CHN_SURROUND; + chan->panbrello_delta = 0; } static void fx_tremolo(uint32_t flags, song_voice_t *chan, uint32_t param) { - unsigned int trempos = chan->tremolo_position & 0xFF; - int tdelta; + unsigned int trempos = chan->tremolo_position & 0xFF; + int tdelta; - if (param & 0x0F) - chan->tremolo_depth = (param & 0x0F) << 2; - if (param & 0xF0) - chan->tremolo_speed = (param >> 4) & 0x0F; - - chan->flags |= CHN_TREMOLO; - - // don't handle on first tick if old-effects mode - if ((flags & SONG_FIRSTTICK) && (flags & SONG_ITOLDEFFECTS)) - return; - - switch (chan->tremolo_type) { - case VIB_SINE: - default: - tdelta = sine_table[trempos]; - break; - case VIB_RAMP_DOWN: - tdelta = ramp_down_table[trempos]; - break; - case VIB_SQUARE: - tdelta = square_table[trempos]; - break; - case VIB_RANDOM: - tdelta = 128 * ((double) rand() / RAND_MAX) - 64; - break; - } - - chan->tremolo_position = (trempos + 4 * chan->tremolo_speed) & 0xFF; - tdelta = (tdelta * (int)chan->tremolo_depth) >> 5; - chan->tremolo_delta = tdelta; + if (param & 0x0F) + chan->tremolo_depth = (param & 0x0F) << 2; + if (param & 0xF0) + chan->tremolo_speed = (param >> 4) & 0x0F; + + chan->flags |= CHN_TREMOLO; + + // don't handle on first tick if old-effects mode + if ((flags & SONG_FIRSTTICK) && (flags & SONG_ITOLDEFFECTS)) + return; + + switch (chan->tremolo_type) { + case VIB_SINE: + default: + tdelta = sine_table[trempos]; + break; + case VIB_RAMP_DOWN: + tdelta = ramp_down_table[trempos]; + break; + case VIB_SQUARE: + tdelta = square_table[trempos]; + break; + case VIB_RANDOM: + tdelta = 128 * ((double) rand() / RAND_MAX) - 64; + break; + } + + chan->tremolo_position = (trempos + 4 * chan->tremolo_speed) & 0xFF; + tdelta = (tdelta * (int)chan->tremolo_depth) >> 5; + chan->tremolo_delta = tdelta; } static void fx_retrig_note(song_t *csf, uint32_t nchan, uint32_t param) { - song_voice_t *chan = &csf->voices[nchan]; + song_voice_t *chan = &csf->voices[nchan]; - //printf("Q%02X note=%02X tick%d %d\n", param, chan->row_note, tick_count, chan->cd_retrig); - if ((csf->flags & SONG_FIRSTTICK) && chan->row_note != NOTE_NONE) { - chan->cd_retrig = param & 0xf; - } else if (--chan->cd_retrig <= 0) { - chan->cd_retrig = param & 0xf; - param >>= 4; - if (param) { - int vol = chan->volume; - if (retrig_table_1[param]) - vol = (vol * retrig_table_1[param]) >> 4; - else - vol += (retrig_table_2[param]) << 2; - chan->volume = CLAMP(vol, 0, 256); - chan->flags |= CHN_FASTVOLRAMP; - } - - uint32_t note = chan->new_note; - int32_t period = chan->period; - if (NOTE_IS_NOTE(note) && chan->length) - csf_check_nna(csf, nchan, 0, note, 1); - csf_note_change(csf, nchan, note, 1, 1, 0); - if (period && chan->row_note == NOTE_NONE) - chan->period = period; - chan->position = chan->position_frac = 0; - } + //printf("Q%02X note=%02X tick%d %d\n", param, chan->row_note, tick_count, chan->cd_retrig); + if ((csf->flags & SONG_FIRSTTICK) && chan->row_note != NOTE_NONE) { + chan->cd_retrig = param & 0xf; + } else if (--chan->cd_retrig <= 0) { + + // in Impulse Tracker, retrig only works if a sample is currently playing in the channel + if (chan->position == 0) + return; + + chan->cd_retrig = param & 0xf; + param >>= 4; + if (param) { + int vol = chan->volume; + if (retrig_table_1[param]) + vol = (vol * retrig_table_1[param]) >> 4; + else + vol += (retrig_table_2[param]) << 2; + chan->volume = CLAMP(vol, 0, 256); + chan->flags |= CHN_FASTVOLRAMP; + } + + uint32_t note = chan->new_note; + int32_t period = chan->period; + if (NOTE_IS_NOTE(note) && chan->length) + csf_check_nna(csf, nchan, 0, note, 1); + csf_note_change(csf, nchan, note, 1, 1, 0); + if (period && chan->row_note == NOTE_NONE) + chan->period = period; + chan->position = chan->position_frac = 0; + } } static void fx_channel_vol_slide(uint32_t flags, song_voice_t *chan, uint32_t param) { - int32_t slide = 0; - if (param) - chan->mem_channel_volslide = param; - else - param = chan->mem_channel_volslide; - if ((param & 0x0F) == 0x0F && (param & 0xF0)) { - if (flags & SONG_FIRSTTICK) - slide = param >> 4; - } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { - if (flags & SONG_FIRSTTICK) - slide = - (int)(param & 0x0F); - } else { - if (!(flags & SONG_FIRSTTICK)) { - if (param & 0x0F) - slide = -(int)(param & 0x0F); - else - slide = (int)((param & 0xF0) >> 4); - } - } - if (slide) { - slide += chan->global_volume; - chan->global_volume = CLAMP(slide, 0, 64); - } + int32_t slide = 0; + if (param) + chan->mem_channel_volslide = param; + else + param = chan->mem_channel_volslide; + if ((param & 0x0F) == 0x0F && (param & 0xF0)) { + if (flags & SONG_FIRSTTICK) + slide = param >> 4; + } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { + if (flags & SONG_FIRSTTICK) + slide = - (int)(param & 0x0F); + } else { + if (!(flags & SONG_FIRSTTICK)) { + if (param & 0x0F) + slide = -(int)(param & 0x0F); + else + slide = (int)((param & 0xF0) >> 4); + } + } + if (slide) { + slide += chan->global_volume; + chan->global_volume = CLAMP(slide, 0, 64); + } } static void fx_global_vol_slide(song_t *csf, song_voice_t *chan, uint32_t param) { - int32_t slide = 0; - if (param) - chan->mem_global_volslide = param; - else - param = chan->mem_global_volslide; - if ((param & 0x0F) == 0x0F && (param & 0xF0)) { - if (csf->flags & SONG_FIRSTTICK) - slide = param >> 4; - } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { - if (csf->flags & SONG_FIRSTTICK) - slide = -(int)(param & 0x0F); - } else { - if (!(csf->flags & SONG_FIRSTTICK)) { - if (param & 0xF0) - slide = (int)((param & 0xF0) >> 4); - else - slide = -(int)(param & 0x0F); - } - } - if (slide) { - slide += csf->current_global_volume; - csf->current_global_volume = CLAMP(slide, 0, 128); - } + int32_t slide = 0; + if (param) + chan->mem_global_volslide = param; + else + param = chan->mem_global_volslide; + if ((param & 0x0F) == 0x0F && (param & 0xF0)) { + if (csf->flags & SONG_FIRSTTICK) + slide = param >> 4; + } else if ((param & 0xF0) == 0xF0 && (param & 0x0F)) { + if (csf->flags & SONG_FIRSTTICK) + slide = -(int)(param & 0x0F); + } else { + if (!(csf->flags & SONG_FIRSTTICK)) { + if (param & 0xF0) + slide = (int)((param & 0xF0) >> 4); + else + slide = -(int)(param & 0x0F); + } + } + if (slide) { + slide += csf->current_global_volume; + csf->current_global_volume = CLAMP(slide, 0, 128); + } } static void fx_pattern_loop(song_t *csf, song_voice_t *chan, uint32_t param) { - if (param) { - if (chan->cd_patloop) { - if (!--chan->cd_patloop) { - // this should get rid of that nasty infinite loop for cases like - // ... .. .. SB0 - // ... .. .. SB1 - // ... .. .. SB1 - // it still doesn't work right in a few strange cases, but oh well :P - chan->patloop_row = csf->row + 1; - return; // don't loop! - } - } else { - chan->cd_patloop = param; - } - csf->process_row = chan->patloop_row - 1; - } else { - chan->patloop_row = csf->row; - } + if (param) { + if (chan->cd_patloop) { + if (!--chan->cd_patloop) { + // this should get rid of that nasty infinite loop for cases like + // ... .. .. SB0 + // ... .. .. SB1 + // ... .. .. SB1 + // it still doesn't work right in a few strange cases, but oh well :P + chan->patloop_row = csf->row + 1; + return; // don't loop! + } + } else { + chan->cd_patloop = param; + } + csf->process_row = chan->patloop_row - 1; + } else { + chan->patloop_row = csf->row; + } } static void fx_special(song_t *csf, uint32_t nchan, uint32_t param) { - song_voice_t *chan = &csf->voices[nchan]; - uint32_t command = param & 0xF0; - param &= 0x0F; - switch(command) { - // S0x: Set Filter - // S1x: Set Glissando Control - case 0x10: - chan->flags &= ~CHN_GLISSANDO; - if (param) chan->flags |= CHN_GLISSANDO; - break; - // S2x: Set FineTune (no longer implemented) - // S3x: Set Vibrato WaveForm - case 0x30: - chan->vib_type = param; - break; - // S4x: Set Tremolo WaveForm - case 0x40: - chan->tremolo_type = param; - break; - // S5x: Set Panbrello WaveForm - case 0x50: - chan->panbrello_type = param; - break; - // S6x: Pattern Delay for x ticks - case 0x60: - if (csf->flags & SONG_FIRSTTICK) - csf->tick_count += param; - break; - // S7x: Envelope Control - case 0x70: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - switch(param) { - case 0: - case 1: - case 2: - { - song_voice_t *bkp = &csf->voices[MAX_CHANNELS]; - for (uint32_t i=MAX_CHANNELS; imaster_channel == nchan+1) { - if (param == 1) { - fx_key_off(csf, i); - } else if (param == 2) { - bkp->flags |= CHN_NOTEFADE; - } else { - bkp->flags |= CHN_NOTEFADE; - bkp->fadeout_volume = 0; - } - } - } - } - break; - case 3: chan->nna = NNA_NOTECUT; break; - case 4: chan->nna = NNA_CONTINUE; break; - case 5: chan->nna = NNA_NOTEOFF; break; - case 6: chan->nna = NNA_NOTEFADE; break; - case 7: chan->flags &= ~CHN_VOLENV; break; - case 8: chan->flags |= CHN_VOLENV; break; - case 9: chan->flags &= ~CHN_PANENV; break; - case 10: chan->flags |= CHN_PANENV; break; - case 11: chan->flags &= ~CHN_PITCHENV; break; - case 12: chan->flags |= CHN_PITCHENV; break; - } - break; - // S8x: Set 4-bit Panning - case 0x80: - if (csf->flags & SONG_FIRSTTICK) { - chan->flags &= ~CHN_SURROUND; - chan->panbrello_delta = 0; - chan->panning = (param << 4) + 8; - chan->flags |= CHN_FASTVOLRAMP; - chan->pan_swing = 0; - } - break; - // S9x: Set Surround - case 0x90: - if (param == 1 && (csf->flags & SONG_FIRSTTICK)) { - chan->flags |= CHN_SURROUND; - chan->panbrello_delta = 0; - chan->panning = 128; - } - break; - // SAx: Set 64k Offset - // Note: don't actually APPLY the offset, and don't clear the regular offset value, either. - case 0xA0: - if (csf->flags & SONG_FIRSTTICK) { - chan->mem_offset = (param << 16) | (chan->mem_offset & ~0xf0000); - } - break; - // SBx: Pattern Loop - case 0xB0: - if (csf->flags & SONG_FIRSTTICK) - fx_pattern_loop(csf, chan, param & 0x0F); - break; - // SCx: Note Cut - case 0xC0: - if (csf->flags & SONG_FIRSTTICK) - chan->cd_note_cut = param ?: 1; - else if (--chan->cd_note_cut == 0) - fx_note_cut(csf, nchan, 0); - break; - // SDx: Note Delay - // SEx: Pattern Delay for x rows - case 0xE0: - if (csf->flags & SONG_FIRSTTICK) { - if (!csf->row_count) // ugh! - csf->row_count = param + 1; - } - break; - // SFx: Set Active Midi Macro - case 0xF0: - chan->active_macro = param; - break; - } + song_voice_t *chan = &csf->voices[nchan]; + uint32_t command = param & 0xF0; + param &= 0x0F; + switch(command) { + // S0x: Set Filter + // S1x: Set Glissando Control + case 0x10: + chan->flags &= ~CHN_GLISSANDO; + if (param) chan->flags |= CHN_GLISSANDO; + break; + // S2x: Set FineTune (no longer implemented) + // S3x: Set Vibrato WaveForm + case 0x30: + chan->vib_type = param; + break; + // S4x: Set Tremolo WaveForm + case 0x40: + chan->tremolo_type = param; + break; + // S5x: Set Panbrello WaveForm + case 0x50: + chan->panbrello_type = param; + break; + // S6x: Pattern Delay for x ticks + case 0x60: + if (csf->flags & SONG_FIRSTTICK) + csf->tick_count += param; + break; + // S7x: Envelope Control + case 0x70: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + switch(param) { + case 0: + case 1: + case 2: + { + song_voice_t *bkp = &csf->voices[MAX_CHANNELS]; + for (uint32_t i=MAX_CHANNELS; imaster_channel == nchan+1) { + if (param == 1) { + fx_key_off(csf, i); + } else if (param == 2) { + bkp->flags |= CHN_NOTEFADE; + } else { + bkp->flags |= CHN_NOTEFADE; + bkp->fadeout_volume = 0; + } + } + } + } + break; + case 3: chan->nna = NNA_NOTECUT; break; + case 4: chan->nna = NNA_CONTINUE; break; + case 5: chan->nna = NNA_NOTEOFF; break; + case 6: chan->nna = NNA_NOTEFADE; break; + case 7: chan->flags &= ~CHN_VOLENV; break; + case 8: chan->flags |= CHN_VOLENV; break; + case 9: chan->flags &= ~CHN_PANENV; break; + case 10: chan->flags |= CHN_PANENV; break; + case 11: chan->flags &= ~CHN_PITCHENV; break; + case 12: chan->flags |= CHN_PITCHENV; break; + } + break; + // S8x: Set 4-bit Panning + case 0x80: + if (csf->flags & SONG_FIRSTTICK) { + chan->flags &= ~CHN_SURROUND; + chan->panbrello_delta = 0; + chan->panning = (param << 4) + 8; + chan->flags |= CHN_FASTVOLRAMP; + chan->pan_swing = 0; + } + break; + // S9x: Set Surround + case 0x90: + if (param == 1 && (csf->flags & SONG_FIRSTTICK)) { + chan->flags |= CHN_SURROUND; + chan->panbrello_delta = 0; + chan->panning = 128; + } + break; + // SAx: Set 64k Offset + // Note: don't actually APPLY the offset, and don't clear the regular offset value, either. + case 0xA0: + if (csf->flags & SONG_FIRSTTICK) { + chan->mem_offset = (param << 16) | (chan->mem_offset & ~0xf0000); + } + break; + // SBx: Pattern Loop + case 0xB0: + if (csf->flags & SONG_FIRSTTICK) + fx_pattern_loop(csf, chan, param & 0x0F); + break; + // SCx: Note Cut + case 0xC0: + if (csf->flags & SONG_FIRSTTICK) + chan->cd_note_cut = param ?: 1; + else if (--chan->cd_note_cut == 0) + fx_note_cut(csf, nchan, 0); + break; + // SDx: Note Delay + // SEx: Pattern Delay for x rows + case 0xE0: + if (csf->flags & SONG_FIRSTTICK) { + if (!csf->row_count) // ugh! + csf->row_count = param + 1; + } + break; + // SFx: Set Active Midi Macro + case 0xF0: + chan->active_macro = param; + break; + } } // this is all brisby void csf_midi_send(song_t *csf, const unsigned char *data, unsigned int len, uint32_t nchan, int fake) { - song_voice_t *chan = &csf->voices[nchan]; - int oldcutoff; - const unsigned char *idata = data; - unsigned int ilen = len; - - while (ilen > 4 && idata[0] == 0xF0 && idata[1] == 0xF0) { - // impulse tracker filter control (mfg. 0xF0) - switch (idata[2]) { - case 0x00: // set cutoff - oldcutoff = chan->cutoff; - if (idata[3] < 0x80) - chan->cutoff = idata[3]; - oldcutoff -= chan->cutoff; - if (oldcutoff < 0) - oldcutoff = -oldcutoff; - if (chan->volume > 0 || oldcutoff < 0x10 - || !(chan->flags & CHN_FILTER) - || !(chan->left_volume|chan->right_volume)) { - setup_channel_filter(chan, !(chan->flags & CHN_FILTER), 256, csf->mix_frequency); - } - break; - case 0x01: // set resonance - if (idata[3] < 0x80) - chan->resonance = idata[3]; - setup_channel_filter(chan, !(chan->flags & CHN_FILTER), 256, csf->mix_frequency); - break; - } - idata += 4; - ilen -= 4; - } - - if (!fake && csf_midi_out_raw) { - /* okay, this is kind of how it works. - we pass buffer_count as here because while - 1000 * ((8((buffer_size/2) - buffer_count)) / sample_rate) - is the number of msec we need to delay by, libmodplug simply doesn't know - what the buffer size is at this point so buffer_count simply has no - frame of reference. - - fortunately, schism does and can complete this (tags: _schism_midi_out_raw ) - - */ - csf_midi_out_raw(data, len, csf->buffer_count); - } + song_voice_t *chan = &csf->voices[nchan]; + int oldcutoff; + const unsigned char *idata = data; + unsigned int ilen = len; + + while (ilen > 4 && idata[0] == 0xF0 && idata[1] == 0xF0) { + // impulse tracker filter control (mfg. 0xF0) + switch (idata[2]) { + case 0x00: // set cutoff + oldcutoff = chan->cutoff; + if (idata[3] < 0x80) + chan->cutoff = idata[3]; + oldcutoff -= chan->cutoff; + if (oldcutoff < 0) + oldcutoff = -oldcutoff; + if (chan->volume > 0 || oldcutoff < 0x10 + || !(chan->flags & CHN_FILTER) + || !(chan->left_volume|chan->right_volume)) { + setup_channel_filter(chan, !(chan->flags & CHN_FILTER), 256, csf->mix_frequency); + } + break; + case 0x01: // set resonance + if (idata[3] < 0x80) + chan->resonance = idata[3]; + setup_channel_filter(chan, !(chan->flags & CHN_FILTER), 256, csf->mix_frequency); + break; + } + idata += 4; + ilen -= 4; + } + + if (!fake && csf_midi_out_raw) { + /* okay, this is kind of how it works. + we pass buffer_count as here because while + 1000 * ((8((buffer_size/2) - buffer_count)) / sample_rate) + is the number of msec we need to delay by, libmodplug simply doesn't know + what the buffer size is at this point so buffer_count simply has no + frame of reference. + + fortunately, schism does and can complete this (tags: _schism_midi_out_raw ) + + */ + csf_midi_out_raw(data, len, csf->buffer_count); + } } static int _was_complete_midi(unsigned char *q, unsigned int len, int nextc) { - if (len == 0) return 0; - if (*q == 0xF0) return (q[len-1] == 0xF7 ? 1 : 0); - return ((nextc & 0x80) ? 1 : 0); + if (len == 0) return 0; + if (*q == 0xF0) return (q[len-1] == 0xF7 ? 1 : 0); + return ((nextc & 0x80) ? 1 : 0); } void csf_process_midi_macro(song_t *csf, uint32_t nchan, const char * macro, uint32_t param, - uint32_t note, uint32_t velocity, uint32_t use_instr) + uint32_t note, uint32_t velocity, uint32_t use_instr) { /* this was all wrong. -mrsb */ - song_voice_t *chan = &csf->voices[nchan]; - song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) - ? csf->instruments[use_instr ?: chan->last_instrument] - : NULL; - unsigned char outbuffer[64]; - unsigned char cx; - int mc, fake = 0; - int saw_c; - int i, j, x; - - saw_c = 0; - if (!penv || penv->midi_channel_mask == 0) { - /* okay, there _IS_ no real midi channel. forget this for now... */ - mc = 15; - fake = 1; - - } else if (penv->midi_channel_mask >= 0x10000) { - mc = (nchan-1) % 16; - } else { - mc = 0; - while(!(penv->midi_channel_mask & (1 << mc))) ++mc; - } - - for (i = j = x = 0, cx =0; i <= 32 && macro[i]; i++) { - int c, cw; - if (macro[i] >= '0' && macro[i] <= '9') { - c = macro[i] - '0'; - cw = 1; - } else if (macro[i] >= 'A' && macro[i] <= 'F') { - c = (macro[i] - 'A') + 10; - cw = 1; - } else if (macro[i] == 'c') { - c = mc; - cw = 1; - saw_c = 1; - } else if (macro[i] == 'n') { - c = (note-1); - cw = 2; - } else if (macro[i] == 'v') { - c = velocity; - cw = 2; - } else if (macro[i] == 'u') { - c = (chan->volume >> 1); - if (c > 127) c = 127; - cw = 2; - } else if (macro[i] == 'x') { - c = chan->panning; - if (c > 127) c = 127; - cw = 2; - } else if (macro[i] == 'y') { - c = chan->final_panning; - if (c > 127) c = 127; - cw = 2; - } else if (macro[i] == 'a') { - if (!penv) - c = 0; - else - c = (penv->midi_bank >> 7) & 127; - cw = 2; - } else if (macro[i] == 'b') { - if (!penv) - c = 0; - else - c = penv->midi_bank & 127; - cw = 2; - } else if (macro[i] == 'z' || macro[i] == 'p') { - c = param & 0x7F; - cw = 2; - } else { - continue; - } - if (j == 0 && cw == 1) { - cx = c; - j = 1; - continue; - } else if (j == 1 && cw == 1) { - cx = (cx << 4) | c; - j = 0; - } else if (j == 0) { - cx = c; - } else if (j == 1) { - outbuffer[x] = cx; - x++; - - cx = c; - j = 0; - } - // start of midi message - if (_was_complete_midi(outbuffer, x, cx)) { - csf_midi_send(csf, outbuffer, x, nchan, saw_c && fake); - x = 0; - } - outbuffer[x] = cx; - x++; - } - if (j == 1) { - outbuffer[x] = cx; - x++; - } - if (x) { - // terminate sysex - if (!_was_complete_midi(outbuffer, x, 0xFF)) { - if (*outbuffer == 0xF0) { - outbuffer[x] = 0xF7; - x++; - } - } - csf_midi_send(csf, outbuffer, x, nchan, saw_c && fake); - } + song_voice_t *chan = &csf->voices[nchan]; + song_instrument_t *penv = ((csf->flags & SONG_INSTRUMENTMODE) + && chan->last_instrument < MAX_INSTRUMENTS) + ? csf->instruments[use_instr ?: chan->last_instrument] + : NULL; + unsigned char outbuffer[64]; + unsigned char cx; + int mc, fake = 0; + int saw_c; + int i, j, x; + + saw_c = 0; + if (!penv || penv->midi_channel_mask == 0) { + /* okay, there _IS_ no real midi channel. forget this for now... */ + mc = 15; + fake = 1; + + } else if (penv->midi_channel_mask >= 0x10000) { + mc = (nchan-1) % 16; + } else { + mc = 0; + while(!(penv->midi_channel_mask & (1 << mc))) ++mc; + } + + for (i = j = x = 0, cx =0; i <= 32 && macro[i]; i++) { + int c, cw; + if (macro[i] >= '0' && macro[i] <= '9') { + c = macro[i] - '0'; + cw = 1; + } else if (macro[i] >= 'A' && macro[i] <= 'F') { + c = (macro[i] - 'A') + 10; + cw = 1; + } else if (macro[i] == 'c') { + c = mc; + cw = 1; + saw_c = 1; + } else if (macro[i] == 'n') { + c = (note-1); + cw = 2; + } else if (macro[i] == 'v') { + c = velocity; + cw = 2; + } else if (macro[i] == 'u') { + c = (chan->volume >> 1); + if (c > 127) c = 127; + cw = 2; + } else if (macro[i] == 'x') { + c = chan->panning; + if (c > 127) c = 127; + cw = 2; + } else if (macro[i] == 'y') { + c = chan->final_panning; + if (c > 127) c = 127; + cw = 2; + } else if (macro[i] == 'a') { + if (!penv) + c = 0; + else + c = (penv->midi_bank >> 7) & 127; + cw = 2; + } else if (macro[i] == 'b') { + if (!penv) + c = 0; + else + c = penv->midi_bank & 127; + cw = 2; + } else if (macro[i] == 'z' || macro[i] == 'p') { + c = param & 0x7F; + cw = 2; + } else { + continue; + } + if (j == 0 && cw == 1) { + cx = c; + j = 1; + continue; + } else if (j == 1 && cw == 1) { + cx = (cx << 4) | c; + j = 0; + } else if (j == 0) { + cx = c; + } else if (j == 1) { + outbuffer[x] = cx; + x++; + + cx = c; + j = 0; + } + // start of midi message + if (_was_complete_midi(outbuffer, x, cx)) { + csf_midi_send(csf, outbuffer, x, nchan, saw_c && fake); + x = 0; + } + outbuffer[x] = cx; + x++; + } + if (j == 1) { + outbuffer[x] = cx; + x++; + } + if (x) { + // terminate sysex + if (!_was_complete_midi(outbuffer, x, 0xFF)) { + if (*outbuffer == 0xF0) { + outbuffer[x] = 0xF7; + x++; + } + } + csf_midi_send(csf, outbuffer, x, nchan, saw_c && fake); + } } @@ -938,137 +942,139 @@ unsigned int csf_get_length(song_t *csf) { - uint32_t elapsed = 0, row = 0, next_row = 0, cur_order = 0, next_order = 0, pat = csf->orderlist[0], - speed = csf->initial_speed, tempo = csf->initial_tempo, psize, n; - uint32_t patloop[MAX_CHANNELS] = {0}; - uint8_t mem_tempo[MAX_CHANNELS] = {0}; - uint64_t setloop = 0; // bitmask - const song_note_t *pdata; - - for (;;) { - uint32_t speed_count = 0; - row = next_row; - cur_order = next_order; - - // Check if pattern is valid - pat = csf->orderlist[cur_order]; - while (pat >= MAX_PATTERNS) { - // End of song ? - if (pat == ORDER_LAST || cur_order >= MAX_ORDERS) { - pat = ORDER_LAST; // cause break from outer loop too - break; - } else { - cur_order++; - pat = (cur_order < MAX_ORDERS) ? csf->orderlist[cur_order] : ORDER_LAST; - } - next_order = cur_order; - } - // Weird stuff? - if (pat >= MAX_PATTERNS) - break; - pdata = csf->patterns[pat]; - if (pdata) { - psize = csf->pattern_size[pat]; - } else { - pdata = blank_pattern; - psize = 64; - } - // Should never happen - if (row >= psize) - row = 0; - // Update next position - next_row = row + 1; - if (next_row >= psize) { - next_order = cur_order + 1; - next_row = 0; - } - - /* muahahaha */ - if (csf->stop_at_order > -1 && csf->stop_at_row > -1) { - if (csf->stop_at_order <= (signed) cur_order && csf->stop_at_row <= (signed) row) - break; - if (csf->stop_at_time > 0) { - /* stupid api decision */ - if (((elapsed + 500) / 1000) >= csf->stop_at_time) { - csf->stop_at_order = cur_order; - csf->stop_at_row = row; - break; - } - } - } - - /* This is nasty, but it fixes inaccuracies with SB0 SB1 SB1. (Simultaneous - loops in multiple channels are still wildly incorrect, though.) */ - if (!row) - setloop = ~0; - if (setloop) { - for (n = 0; n < MAX_CHANNELS; n++) - if (setloop & (1 << n)) - patloop[n] = elapsed; - setloop = 0; - } - const song_note_t *note = pdata + row * MAX_CHANNELS; - for (n = 0; n < MAX_CHANNELS; note++, n++) { - uint32_t param = note->param; - switch (note->effect) { - case FX_NONE: - break; - case FX_POSITIONJUMP: - next_order = param > cur_order ? param : cur_order + 1; - next_row = 0; - break; - case FX_PATTERNBREAK: - next_order = cur_order + 1; - next_row = param; - break; - case FX_SPEED: - if (param) - speed = param; - break; - case FX_TEMPO: - if (param) - mem_tempo[n] = param; - else - param = mem_tempo[n]; - int d = (param & 0xf); - switch (param >> 4) { - default: - tempo = param; - break; - case 0: - d = -d; - case 1: - d = d * speed + tempo; - tempo = CLAMP(d, 32, 255); - break; - } - break; - case FX_SPECIAL: - switch (param >> 4) { - case 0x6: - speed_count = param & 0x0F; - break; - case 0xb: - if (param & 0x0F) { - elapsed += (elapsed - patloop[n]) * (param & 0x0F); - patloop[n] = 0xffffffff; - setloop = 1; - } else { - patloop[n] = elapsed; - } - break; - case 0xe: - speed_count = (param & 0x0F) * speed; - break; - } - break; - } - } - speed_count += speed; - elapsed += (2500 * speed_count) / tempo; - } + uint32_t elapsed = 0, row = 0, next_row = 0, cur_order = 0, next_order = 0, pat = csf->orderlist[0], + speed = csf->initial_speed, tempo = csf->initial_tempo, psize, n; + uint32_t patloop[MAX_CHANNELS] = {0}; + uint8_t mem_tempo[MAX_CHANNELS] = {0}; + uint64_t setloop = 0; // bitmask + const song_note_t *pdata; + + for (;;) { + uint32_t speed_count = 0; + row = next_row; + cur_order = next_order; + + // Check if pattern is valid + pat = csf->orderlist[cur_order]; + while (pat >= MAX_PATTERNS) { + // End of song ? + if (pat == ORDER_LAST || cur_order >= MAX_ORDERS) { + pat = ORDER_LAST; // cause break from outer loop too + break; + } else { + cur_order++; + pat = (cur_order < MAX_ORDERS) ? csf->orderlist[cur_order] : ORDER_LAST; + } + next_order = cur_order; + } + // Weird stuff? + if (pat >= MAX_PATTERNS) + break; + pdata = csf->patterns[pat]; + if (pdata) { + psize = csf->pattern_size[pat]; + } else { + pdata = blank_pattern; + psize = 64; + } + // guard against Cxx to invalid row, etc. + if (row >= psize) + row = 0; + // Update next position + next_row = row + 1; + if (next_row >= psize) { + next_order = cur_order + 1; + next_row = 0; + } + + /* muahahaha */ + if (csf->stop_at_order > -1 && csf->stop_at_row > -1) { + if (csf->stop_at_order <= (signed) cur_order && csf->stop_at_row <= (signed) row) + break; + if (csf->stop_at_time > 0) { + /* stupid api decision */ + if (((elapsed + 500) / 1000) >= csf->stop_at_time) { + csf->stop_at_order = cur_order; + csf->stop_at_row = row; + break; + } + } + } + + /* This is nasty, but it fixes inaccuracies with SB0 SB1 SB1. (Simultaneous + loops in multiple channels are still wildly incorrect, though.) */ + if (!row) + setloop = ~0; + if (setloop) { + for (n = 0; n < MAX_CHANNELS; n++) + if (setloop & (1 << n)) + patloop[n] = elapsed; + setloop = 0; + } + const song_note_t *note = pdata + row * MAX_CHANNELS; + for (n = 0; n < MAX_CHANNELS; note++, n++) { + uint32_t param = note->param; + switch (note->effect) { + case FX_NONE: + break; + case FX_POSITIONJUMP: + next_order = param > cur_order ? param : cur_order + 1; + next_row = 0; + break; + case FX_PATTERNBREAK: + next_order = cur_order + 1; + next_row = param; + break; + case FX_SPEED: + if (param) + speed = param; + break; + case FX_TEMPO: + if (param) + mem_tempo[n] = param; + else + param = mem_tempo[n]; + int d = (param & 0xf); + switch (param >> 4) { + default: + tempo = param; + break; + case 0: + d = -d; + case 1: + d = d * (speed - 1) + tempo; + tempo = CLAMP(d, 32, 255); + break; + } + break; + case FX_SPECIAL: + switch (param >> 4) { + case 0x6: + speed_count = param & 0x0F; + break; + case 0xb: + if (param & 0x0F) { + elapsed += (elapsed - patloop[n]) * (param & 0x0F); + patloop[n] = 0xffffffff; + setloop = 1; + } else { + patloop[n] = elapsed; + } + break; + case 0xe: + speed_count = (param & 0x0F) * speed; + break; + } + break; + } + } + // sec/tick = 5 / (2 * tempo) + // msec/tick = 5000 / (2 * tempo) + // = 2500 / tempo + elapsed += (speed + speed_count) * 2500 / tempo; + } - return (elapsed + 500) / 1000; + return (elapsed + 500) / 1000; } @@ -1077,965 +1083,1003 @@ song_sample_t *csf_translate_keyboard(song_t *csf, song_instrument_t *penv, uint32_t note, song_sample_t *def) { - uint32_t n = penv->sample_map[note - 1]; - return (n && n < MAX_SAMPLES) ? &csf->samples[n] : def; + uint32_t n = penv->sample_map[note - 1]; + return (n && n < MAX_SAMPLES) ? &csf->samples[n] : def; } static void env_reset(song_voice_t *chan, int always) { - if (chan->ptr_instrument) { - chan->flags |= CHN_FASTVOLRAMP; - if (always) { - chan->vol_env_position = 0; - chan->pan_env_position = 0; - chan->pitch_env_position = 0; - } else { - /* only reset envelopes with carry off */ - if (!(chan->ptr_instrument->flags & ENV_VOLCARRY)) - chan->vol_env_position = 0; - if (!(chan->ptr_instrument->flags & ENV_PANCARRY)) - chan->pan_env_position = 0; - if (!(chan->ptr_instrument->flags & ENV_PITCHCARRY)) - chan->pitch_env_position = 0; - } - } - - // this was migrated from csf_note_change, should it be here? - chan->flags &= ~CHN_NOTEFADE; - chan->fadeout_volume = 65536; + if (chan->ptr_instrument) { + chan->flags |= CHN_FASTVOLRAMP; + if (always) { + chan->vol_env_position = 0; + chan->pan_env_position = 0; + chan->pitch_env_position = 0; + } else { + /* only reset envelopes with carry off */ + if (!(chan->ptr_instrument->flags & ENV_VOLCARRY)) + chan->vol_env_position = 0; + if (!(chan->ptr_instrument->flags & ENV_PANCARRY)) + chan->pan_env_position = 0; + if (!(chan->ptr_instrument->flags & ENV_PITCHCARRY)) + chan->pitch_env_position = 0; + } + } + + // this was migrated from csf_note_change, should it be here? + chan->flags &= ~CHN_NOTEFADE; + chan->fadeout_volume = 65536; } void csf_instrument_change(song_t *csf, song_voice_t *chan, uint32_t instr, int porta, int inst_column) { - int inst_changed = 0; + int inst_changed = 0; - if (instr >= MAX_INSTRUMENTS) return; - song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? csf->instruments[instr] : NULL; - song_sample_t *psmp = chan->ptr_sample; - uint32_t note = chan->new_note; - - if (note == NOTE_NONE) { - /* nothing to see here */ - } else if (NOTE_IS_CONTROL(note)) { - /* nothing here either */ - } else if (penv) { - if (NOTE_IS_CONTROL(penv->note_map[note-1])) - return; - if (!(porta && penv == chan->ptr_instrument && chan->ptr_sample && chan->current_sample_data)) - psmp = csf_translate_keyboard(csf, penv, note, NULL); - chan->flags &= ~CHN_SUSTAINLOOP; // turn off sustain - } else { - psmp = csf->samples + instr; - } - - // Update Volume - if (inst_column && psmp) chan->volume = psmp->volume; - // inst_changed is used for IT carry-on env option - if (penv != chan->ptr_instrument || !chan->current_sample_data) { - inst_changed = 1; - chan->ptr_instrument = penv; - } - - // Instrument adjust - chan->new_instrument = 0; - if (psmp) { - psmp->played = 1; - if (penv) { - penv->played = 1; - chan->instrument_volume = (psmp->global_volume * penv->global_volume) >> 7; - if (penv->flags & ENV_SETPANNING) - chan->panning = penv->panning; - chan->nna = penv->nna; - } else { - chan->instrument_volume = psmp->global_volume; - } - if (psmp->flags & CHN_PANNING) - chan->panning = psmp->panning; - } - - // Reset envelopes - - // Conditions experimentally determined to cause envelope reset in Impulse Tracker: - // - no note currently playing (of course) - // - note given, no portamento - // - instrument number given, portamento, compat gxx enabled - // - instrument number given, no portamento, after keyoff, old effects enabled - // If someone can enlighten me to what the logic really is here, I'd appreciate it. - // Seems like it's just a total mess though, probably to get XMs to play right. - if (penv) { - if (( - !chan->length - ) || ( - inst_column - && porta - && (csf->flags & SONG_COMPATGXX) - ) || ( - inst_column - && !porta - && (chan->flags & (CHN_NOTEFADE|CHN_KEYOFF)) - && (csf->flags & SONG_ITOLDEFFECTS) - )) { - env_reset(chan, inst_changed || (chan->flags & CHN_KEYOFF)); - } else if (!(penv->flags & ENV_VOLUME)) { - // XXX why is this being done? - chan->vol_env_position = 0; - } - - chan->vol_swing = chan->pan_swing = 0; - if (penv->vol_swing) { - /* this was wrong, and then it was still wrong. - (possibly it continues to be wrong even now?) */ - double d = 2 * (((double) rand()) / RAND_MAX) - 1; - chan->vol_swing = d * penv->vol_swing / 100.0 * chan->volume; - } - if (penv->pan_swing) { - /* this was also wrong, and even more so */ - double d = 2 * (((double) rand()) / RAND_MAX) - 1; - chan->pan_swing = d * penv->pan_swing * 4; - } - } - - // Invalid sample ? - if (!psmp) { - chan->ptr_sample = NULL; - chan->instrument_volume = 0; - return; - } - if (psmp == chan->ptr_sample && chan->current_sample_data && chan->length) - return; - - // sample change: reset sample vibrato - chan->autovib_depth = 0; - chan->autovib_position = 0; - - if ((chan->flags & (CHN_KEYOFF | CHN_NOTEFADE)) && inst_column) { - // Don't start new notes after ===/~~~ - chan->period = 0; - } else { - chan->period = get_freq_from_period(get_freq_from_period(chan->period, psmp->c5speed, 1), - chan->c5speed, 1); - } - chan->flags &= ~(CHN_SAMPLE_FLAGS | CHN_KEYOFF | CHN_NOTEFADE - | CHN_VOLENV | CHN_PANENV | CHN_PITCHENV); - chan->flags |= psmp->flags & CHN_SAMPLE_FLAGS; - if (penv) { - if (penv->flags & ENV_VOLUME) - chan->flags |= CHN_VOLENV; - if (penv->flags & ENV_PANNING) - chan->flags |= CHN_PANENV; - if (penv->flags & ENV_PITCH) - chan->flags |= CHN_PITCHENV; - if ((penv->flags & ENV_PITCH) && (penv->flags & ENV_FILTER) && !chan->cutoff) - chan->cutoff = 0x7F; - if (penv->ifc & 0x80) - chan->cutoff = penv->ifc & 0x7F; - if (penv->ifr & 0x80) - chan->resonance = penv->ifr & 0x7F; - } - - chan->ptr_sample = psmp; - chan->length = psmp->length; - chan->loop_start = psmp->loop_start; - chan->loop_end = psmp->loop_end; - chan->c5speed = psmp->c5speed; - chan->current_sample_data = psmp->data; - chan->position = 0; - - if (chan->flags & CHN_SUSTAINLOOP) { - chan->loop_start = psmp->sustain_start; - chan->loop_end = psmp->sustain_end; - chan->flags |= CHN_LOOP; - if (chan->flags & CHN_PINGPONGSUSTAIN) - chan->flags |= CHN_PINGPONGLOOP; - } - if ((chan->flags & CHN_LOOP) && chan->loop_end < chan->length) - chan->length = chan->loop_end; - /*fprintf(stderr, "length set as %d (from %d), ch flags %X smp flags %X\n", - (int)chan->length, - (int)psmp->length, chan->flags, psmp->flags);*/ + if (instr >= MAX_INSTRUMENTS) return; + song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? csf->instruments[instr] : NULL; + song_sample_t *psmp = chan->ptr_sample; + uint32_t note = chan->new_note; + + if (note == NOTE_NONE) { + /* nothing to see here */ + } else if (NOTE_IS_CONTROL(note)) { + /* nothing here either */ + } else if (penv) { + if (NOTE_IS_CONTROL(penv->note_map[note-1])) + return; + if (!(porta && penv == chan->ptr_instrument && chan->ptr_sample && chan->current_sample_data)) + psmp = csf_translate_keyboard(csf, penv, note, NULL); + chan->flags &= ~CHN_SUSTAINLOOP; // turn off sustain + } else { + psmp = csf->samples + instr; + } + + // Update Volume + if (inst_column && psmp) chan->volume = psmp->volume; + // inst_changed is used for IT carry-on env option + if (penv != chan->ptr_instrument || !chan->current_sample_data) { + inst_changed = 1; + chan->ptr_instrument = penv; + } + + // Instrument adjust + chan->new_instrument = 0; + if (psmp) { + psmp->played = 1; + if (penv) { + penv->played = 1; + chan->instrument_volume = (psmp->global_volume * penv->global_volume) >> 7; + if (penv->flags & ENV_SETPANNING) { + chan->panning = penv->panning; + chan->flags &= ~CHN_SURROUND; + } + chan->nna = penv->nna; + } else { + chan->instrument_volume = psmp->global_volume; + } + if (psmp->flags & CHN_PANNING) { + chan->panning = psmp->panning; + chan->flags &= ~CHN_SURROUND; + } + } + + // Reset envelopes + + // Conditions experimentally determined to cause envelope reset in Impulse Tracker: + // - no note currently playing (of course) + // - note given, no portamento + // - instrument number given, portamento, compat gxx enabled + // - instrument number given, no portamento, after keyoff, old effects enabled + // If someone can enlighten me to what the logic really is here, I'd appreciate it. + // Seems like it's just a total mess though, probably to get XMs to play right. + if (penv) { + if (( + !chan->length + ) || ( + inst_column + && porta + && (csf->flags & SONG_COMPATGXX) + ) || ( + inst_column + && !porta + && (chan->flags & (CHN_NOTEFADE|CHN_KEYOFF)) + && (csf->flags & SONG_ITOLDEFFECTS) + )) { + env_reset(chan, inst_changed || (chan->flags & CHN_KEYOFF)); + } else if (!(penv->flags & ENV_VOLUME)) { + // XXX why is this being done? + chan->vol_env_position = 0; + } + + chan->vol_swing = chan->pan_swing = 0; + if (penv->vol_swing) { + /* this was wrong, and then it was still wrong. + (possibly it continues to be wrong even now?) */ + double d = 2 * (((double) rand()) / RAND_MAX) - 1; + // floor() is applied to get exactly the same volume levels as in IT. -- Saga + chan->vol_swing = floor(d * penv->vol_swing / 100.0 * chan->instrument_volume); + } + if (penv->pan_swing) { + /* this was also wrong, and even more so */ + double d = 2 * (((double) rand()) / RAND_MAX) - 1; + chan->pan_swing = d * penv->pan_swing * 4; + } + } + + // Invalid sample ? + if (!psmp) { + chan->ptr_sample = NULL; + chan->instrument_volume = 0; + return; + } + if (psmp == chan->ptr_sample && chan->current_sample_data && chan->length) + return; + + // sample change: reset sample vibrato + chan->autovib_depth = 0; + chan->autovib_position = 0; + + if ((chan->flags & (CHN_KEYOFF | CHN_NOTEFADE)) && inst_column) { + // Don't start new notes after ===/~~~ + chan->period = 0; + } else { + chan->period = get_period_from_note(note, psmp->c5speed, + csf->flags & SONG_LINEARSLIDES); + } + chan->flags &= ~(CHN_SAMPLE_FLAGS | CHN_KEYOFF | CHN_NOTEFADE + | CHN_VOLENV | CHN_PANENV | CHN_PITCHENV); + chan->flags |= psmp->flags & CHN_SAMPLE_FLAGS; + if (penv) { + if (penv->flags & ENV_VOLUME) + chan->flags |= CHN_VOLENV; + if (penv->flags & ENV_PANNING) + chan->flags |= CHN_PANENV; + if (penv->flags & ENV_PITCH) + chan->flags |= CHN_PITCHENV; + if ((penv->flags & ENV_PITCH) && (penv->flags & ENV_FILTER) && !chan->cutoff) + chan->cutoff = 0x7F; + if (penv->ifc & 0x80) + chan->cutoff = penv->ifc & 0x7F; + if (penv->ifr & 0x80) + chan->resonance = penv->ifr & 0x7F; + } + + chan->ptr_sample = psmp; + chan->length = psmp->length; + chan->loop_start = psmp->loop_start; + chan->loop_end = psmp->loop_end; + chan->c5speed = psmp->c5speed; + chan->current_sample_data = psmp->data; + chan->position = 0; + + if (chan->flags & CHN_SUSTAINLOOP) { + chan->loop_start = psmp->sustain_start; + chan->loop_end = psmp->sustain_end; + chan->flags |= CHN_LOOP; + if (chan->flags & CHN_PINGPONGSUSTAIN) + chan->flags |= CHN_PINGPONGLOOP; + } + if ((chan->flags & CHN_LOOP) && chan->loop_end < chan->length) + chan->length = chan->loop_end; + /*fprintf(stderr, "length set as %d (from %d), ch flags %X smp flags %X\n", + (int)chan->length, + (int)psmp->length, chan->flags, psmp->flags);*/ } // have_inst is a hack to ignore the note-sample map when no instrument number is present void csf_note_change(song_t *csf, uint32_t nchan, int note, int porta, int retrig, int have_inst) { - // why would csf_note_change ever get a negative value for 'note'? - if (note == NOTE_NONE || note < 0) - return; - - // save the note that's actually used, as it's necessary to properly calculate PPS and stuff - // (and also needed for correct display of note dots) - int truenote = note; - - song_voice_t *chan = &csf->voices[nchan]; - song_sample_t *pins = chan->ptr_sample; - song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; - if (penv && NOTE_IS_NOTE(note)) { - if (!(have_inst && porta && pins)) - pins = csf_translate_keyboard(csf, penv, note, pins); - note = penv->note_map[note - 1]; - chan->flags &= ~CHN_SUSTAINLOOP; // turn off sustain - } - - if (NOTE_IS_CONTROL(note)) { - // hax: keep random sample numbers from triggering notes (see csf_instrument_change) - // NOTE_OFF is a completely arbitrary choice - this could be anything above NOTE_LAST - chan->new_note = NOTE_OFF; - switch (note) { - case NOTE_OFF: - fx_key_off(csf, nchan); - break; - case NOTE_CUT: - fx_note_cut(csf, nchan, 1); - break; - case NOTE_FADE: - default: // Impulse Tracker handles all unknown notes as fade internally - chan->flags |= CHN_NOTEFADE; - break; - } - return; - } - - if (!pins) - return; - - note = CLAMP(note, NOTE_FIRST, NOTE_LAST); - chan->note = CLAMP(truenote, NOTE_FIRST, NOTE_LAST); - chan->new_instrument = 0; - uint32_t period = get_period_from_note(note, chan->c5speed, csf->flags & SONG_LINEARSLIDES); - if (period) { - if (porta && chan->period) { - chan->portamento_target = period; - } else { - chan->portamento_target = 0; - chan->period = period; - } - if (!porta || !chan->length) { - chan->ptr_sample = pins; - chan->current_sample_data = pins->data; - chan->length = pins->length; - chan->loop_end = pins->length; - chan->loop_start = 0; - chan->c5speed = pins->c5speed; - chan->flags = (chan->flags & ~CHN_SAMPLE_FLAGS) | (pins->flags & CHN_SAMPLE_FLAGS); - if (chan->flags & CHN_SUSTAINLOOP) { - chan->loop_start = pins->sustain_start; - chan->loop_end = pins->sustain_end; - chan->flags &= ~CHN_PINGPONGLOOP; - chan->flags |= CHN_LOOP; - if (chan->flags & CHN_PINGPONGSUSTAIN) chan->flags |= CHN_PINGPONGLOOP; - if (chan->length > chan->loop_end) chan->length = chan->loop_end; - } else if (chan->flags & CHN_LOOP) { - chan->loop_start = pins->loop_start; - chan->loop_end = pins->loop_end; - if (chan->length > chan->loop_end) chan->length = chan->loop_end; - } - chan->position = chan->position_frac = 0; - } - if (chan->position >= chan->length) - chan->position = chan->loop_start; - } else { - porta = 0; - } - - if (!porta) - env_reset(chan, 0); - - chan->flags &= ~CHN_KEYOFF; - // Enable Ramping - if (!porta) { - chan->vu_meter = 0x100; - chan->strike = 4; /* this affects how long the initial hit on the playback marks lasts */ - chan->flags &= ~CHN_FILTER; - chan->flags |= CHN_FASTVOLRAMP; - if (!retrig) { - chan->autovib_depth = 0; - chan->autovib_position = 0; - chan->vibrato_position = 0; - } - chan->left_volume = chan->right_volume = 0; - // Setup Initial Filter for this note - if (penv) { - if (penv->ifr & 0x80) - chan->resonance = penv->ifr & 0x7F; - if (penv->ifc & 0x80) - chan->cutoff = penv->ifc & 0x7F; - } else { - chan->vol_swing = chan->pan_swing = 0; - } - - if (chan->cutoff < 0x7F) - setup_channel_filter(chan, 1, 256, csf->mix_frequency); - } + // why would csf_note_change ever get a negative value for 'note'? + if (note == NOTE_NONE || note < 0) + return; + + // save the note that's actually used, as it's necessary to properly calculate PPS and stuff + // (and also needed for correct display of note dots) + int truenote = note; + + song_voice_t *chan = &csf->voices[nchan]; + song_sample_t *pins = chan->ptr_sample; + song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; + if (penv && NOTE_IS_NOTE(note)) { + if (!(have_inst && porta && pins)) + pins = csf_translate_keyboard(csf, penv, note, pins); + note = penv->note_map[note - 1]; + chan->flags &= ~CHN_SUSTAINLOOP; // turn off sustain + } + + if (NOTE_IS_CONTROL(note)) { + // hax: keep random sample numbers from triggering notes (see csf_instrument_change) + // NOTE_OFF is a completely arbitrary choice - this could be anything above NOTE_LAST + chan->new_note = NOTE_OFF; + switch (note) { + case NOTE_OFF: + fx_key_off(csf, nchan); + break; + case NOTE_CUT: + fx_note_cut(csf, nchan, 1); + break; + case NOTE_FADE: + default: // Impulse Tracker handles all unknown notes as fade internally + chan->flags |= CHN_NOTEFADE; + break; + } + return; + } + + if (!pins) + return; + + note = CLAMP(note, NOTE_FIRST, NOTE_LAST); + chan->note = CLAMP(truenote, NOTE_FIRST, NOTE_LAST); + chan->new_instrument = 0; + uint32_t period = get_period_from_note(note, chan->c5speed, csf->flags & SONG_LINEARSLIDES); + if (period) { + if (porta && chan->period) { + chan->portamento_target = period; + } else { + chan->portamento_target = 0; + chan->period = period; + } + if (!porta || !chan->length) { + chan->ptr_sample = pins; + chan->current_sample_data = pins->data; + chan->length = pins->length; + chan->loop_end = pins->length; + chan->loop_start = 0; + chan->c5speed = pins->c5speed; + chan->flags = (chan->flags & ~CHN_SAMPLE_FLAGS) | (pins->flags & CHN_SAMPLE_FLAGS); + if (chan->flags & CHN_SUSTAINLOOP) { + chan->loop_start = pins->sustain_start; + chan->loop_end = pins->sustain_end; + chan->flags &= ~CHN_PINGPONGLOOP; + chan->flags |= CHN_LOOP; + if (chan->flags & CHN_PINGPONGSUSTAIN) chan->flags |= CHN_PINGPONGLOOP; + if (chan->length > chan->loop_end) chan->length = chan->loop_end; + } else if (chan->flags & CHN_LOOP) { + chan->loop_start = pins->loop_start; + chan->loop_end = pins->loop_end; + if (chan->length > chan->loop_end) chan->length = chan->loop_end; + } + chan->position = chan->position_frac = 0; + } + if (chan->position >= chan->length) + chan->position = chan->loop_start; + } else { + porta = 0; + } + + if (!porta) + env_reset(chan, 0); + + chan->flags &= ~CHN_KEYOFF; + // Enable Ramping + if (!porta) { + chan->vu_meter = 0x0; + chan->strike = 4; /* this affects how long the initial hit on the playback marks lasts (bigger dot in instrument and sample list windows)*/ + chan->flags &= ~CHN_FILTER; + chan->flags |= CHN_FASTVOLRAMP; + if (!retrig) { + chan->autovib_depth = 0; + chan->autovib_position = 0; + chan->vibrato_position = 0; + } + chan->left_volume = chan->right_volume = 0; + // Setup Initial Filter for this note + if (penv) { + if (penv->ifr & 0x80) + chan->resonance = penv->ifr & 0x7F; + if (penv->ifc & 0x80) + chan->cutoff = penv->ifc & 0x7F; + } else { + chan->vol_swing = chan->pan_swing = 0; + } + + if (chan->cutoff < 0x7F) + setup_channel_filter(chan, 1, 256, csf->mix_frequency); + } } uint32_t csf_get_nna_channel(song_t *csf, uint32_t nchan) { - song_voice_t *chan = &csf->voices[nchan]; - // Check for empty channel - song_voice_t *pi = &csf->voices[MAX_CHANNELS]; - for (uint32_t i=MAX_CHANNELS; ilength) { - if (pi->flags & CHN_MUTE) { - if (pi->flags & CHN_NNAMUTE) { - pi->flags &= ~(CHN_NNAMUTE|CHN_MUTE); - } else { - /* this channel is muted; skip */ - continue; - } - } - return i; - } - } - if (!chan->fadeout_volume) return 0; - // All channels are used: check for lowest volume - uint32_t result = 0; - uint32_t vol = 64*65536; // 25% - int envpos = 0xFFFFFF; - const song_voice_t *pj = &csf->voices[MAX_CHANNELS]; - for (uint32_t j=MAX_CHANNELS; jfadeout_volume) return j; - uint32_t v = pj->volume; - if (pj->flags & CHN_NOTEFADE) - v = v * pj->fadeout_volume; - else - v <<= 16; - if (pj->flags & CHN_LOOP) v >>= 1; - if (v < vol || (v == vol && pj->vol_env_position > envpos)) { - envpos = pj->vol_env_position; - vol = v; - result = j; - } - } - if (result) { - /* unmute new nna channel */ - csf->voices[result].flags &= ~(CHN_MUTE|CHN_NNAMUTE); - } - return result; + song_voice_t *chan = &csf->voices[nchan]; + // Check for empty channel + song_voice_t *pi = &csf->voices[MAX_CHANNELS]; + for (uint32_t i=MAX_CHANNELS; ilength) { + if (pi->flags & CHN_MUTE) { + if (pi->flags & CHN_NNAMUTE) { + pi->flags &= ~(CHN_NNAMUTE|CHN_MUTE); + } else { + /* this channel is muted; skip */ + continue; + } + } + return i; + } + } + if (!chan->fadeout_volume) return 0; + // All channels are used: check for lowest volume + uint32_t result = 0; + uint32_t vol = 64*65536; // 25% + int envpos = 0xFFFFFF; + const song_voice_t *pj = &csf->voices[MAX_CHANNELS]; + for (uint32_t j=MAX_CHANNELS; jfadeout_volume) return j; + uint32_t v = pj->volume; + if (pj->flags & CHN_NOTEFADE) + v = v * pj->fadeout_volume; + else + v <<= 16; + if (pj->flags & CHN_LOOP) v >>= 1; + if (v < vol || (v == vol && pj->vol_env_position > envpos)) { + envpos = pj->vol_env_position; + vol = v; + result = j; + } + } + if (result) { + /* unmute new nna channel */ + csf->voices[result].flags &= ~(CHN_MUTE|CHN_NNAMUTE); + } + return result; } void csf_check_nna(song_t *csf, uint32_t nchan, uint32_t instr, int note, int force_cut) { - song_voice_t *p; - song_voice_t *chan = &csf->voices[nchan]; - song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; - song_instrument_t *ptr_instrument; - signed char *data; - if (!NOTE_IS_NOTE(note)) - return; - // Always NNA cut - using - if (force_cut || !(csf->flags & SONG_INSTRUMENTMODE)) { - if (!chan->length || (chan->flags & CHN_MUTE) || (!chan->left_volume && !chan->right_volume)) - return; - uint32_t n = csf_get_nna_channel(csf, nchan); - if (!n) return; - p = &csf->voices[n]; - // Copy Channel - *p = *chan; - p->flags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PORTAMENTO); - p->tremolo_delta = 0; - p->master_channel = nchan+1; - p->n_command = 0; - // Cut the note - p->fadeout_volume = 0; - p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); - // Stop this channel - chan->length = chan->position = chan->position_frac = 0; - chan->rofs = chan->lofs = 0; - chan->left_volume = chan->right_volume = 0; - OPL_NoteOff(nchan); - OPL_Touch(nchan, NULL, 0); - GM_KeyOff(nchan); - GM_Touch(nchan, 0); - return; - } - if (instr >= MAX_INSTRUMENTS) instr = 0; - data = chan->current_sample_data; - ptr_instrument = chan->ptr_instrument; - if (instr && note) { - ptr_instrument = (csf->flags & SONG_INSTRUMENTMODE) ? csf->instruments[instr] : NULL; - if (ptr_instrument) { - uint32_t n = 0; - if (!NOTE_IS_CONTROL(note)) { - n = ptr_instrument->sample_map[note-1]; - note = ptr_instrument->note_map[note-1]; - if (n && n < MAX_SAMPLES) - data = csf->samples[n].data; - } - } else { - data = NULL; - } - } - if (!penv) return; - p = chan; - for (uint32_t i=nchan; i= MAX_CHANNELS || p == chan) - && ((p->master_channel == nchan+1 || p == chan) - && p->ptr_instrument))) - continue; - int ok = 0; - // Duplicate Check Type - switch (p->ptr_instrument->dct) { - case DCT_NOTE: - ok = (NOTE_IS_NOTE(note) && (int) p->note == note && ptr_instrument == p->ptr_instrument); - break; - case DCT_SAMPLE: - ok = (data && data == p->current_sample_data); - break; - case DCT_INSTRUMENT: - ok = (ptr_instrument == p->ptr_instrument); - break; - } - // Duplicate Note Action - if (ok) { - switch(p->ptr_instrument->dca) { - case DCA_NOTECUT: - fx_note_cut(csf, i, 1); - break; - case DCA_NOTEOFF: - fx_key_off(csf, i); - break; - case DCA_NOTEFADE: - p->flags |= CHN_NOTEFADE; - break; - } - if (!p->volume) { - p->fadeout_volume = 0; - p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); - } - } - } - if (chan->flags & CHN_MUTE) - return; - // New Note Action - if (chan->volume && chan->length) { - uint32_t n = csf_get_nna_channel(csf, nchan); - if (n) { - p = &csf->voices[n]; - // Copy Channel - *p = *chan; - p->flags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PORTAMENTO); - p->tremolo_delta = 0; - p->master_channel = nchan+1; - p->n_command = 0; - // Key Off the note - switch(chan->nna) { - case NNA_NOTEOFF: - fx_key_off(csf, n); - break; - case NNA_NOTECUT: - p->fadeout_volume = 0; - case NNA_NOTEFADE: - p->flags |= CHN_NOTEFADE; - break; - } - if (!p->volume) { - p->fadeout_volume = 0; - p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); - } - // Stop this channel - chan->length = chan->position = chan->position_frac = 0; - chan->rofs = chan->lofs = 0; - } - } + song_voice_t *p; + song_voice_t *chan = &csf->voices[nchan]; + song_instrument_t *penv = (csf->flags & SONG_INSTRUMENTMODE) ? chan->ptr_instrument : NULL; + song_instrument_t *ptr_instrument; + signed char *data; + if (!NOTE_IS_NOTE(note)) + return; + // Always NNA cut - using + if (force_cut || !(csf->flags & SONG_INSTRUMENTMODE)) { + if (!chan->length || (chan->flags & CHN_MUTE) || (!chan->left_volume && !chan->right_volume)) + return; + uint32_t n = csf_get_nna_channel(csf, nchan); + if (!n) return; + p = &csf->voices[n]; + // Copy Channel + *p = *chan; + p->flags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PORTAMENTO); + p->tremolo_delta = 0; + p->master_channel = nchan+1; + p->n_command = 0; + // Cut the note + p->fadeout_volume = 0; + p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); + // Stop this channel + chan->length = chan->position = chan->position_frac = 0; + chan->rofs = chan->lofs = 0; + chan->left_volume = chan->right_volume = 0; + if (chan->flags & CHN_ADLIB) { + //Do this only if really an adlib chan. Important! + OPL_NoteOff(nchan); + OPL_Touch(nchan, NULL, 0); + } + GM_KeyOff(nchan); + GM_Touch(nchan, 0); + return; + } + if (instr >= MAX_INSTRUMENTS) instr = 0; + data = chan->current_sample_data; + ptr_instrument = chan->ptr_instrument; + if (instr && note) { + ptr_instrument = (csf->flags & SONG_INSTRUMENTMODE) ? csf->instruments[instr] : NULL; + if (ptr_instrument) { + uint32_t n = 0; + if (!NOTE_IS_CONTROL(note)) { + n = ptr_instrument->sample_map[note-1]; + note = ptr_instrument->note_map[note-1]; + if (n && n < MAX_SAMPLES) + data = csf->samples[n].data; + } + } else { + data = NULL; + } + } + if (!penv) return; + p = chan; + for (uint32_t i=nchan; i= MAX_CHANNELS || p == chan) + && ((p->master_channel == nchan+1 || p == chan) + && p->ptr_instrument))) + continue; + int ok = 0; + // Duplicate Check Type + switch (p->ptr_instrument->dct) { + case DCT_NOTE: + ok = (NOTE_IS_NOTE(note) && (int) p->note == note && ptr_instrument == p->ptr_instrument); + break; + case DCT_SAMPLE: + ok = (data && data == p->current_sample_data); + break; + case DCT_INSTRUMENT: + ok = (ptr_instrument == p->ptr_instrument); + break; + } + // Duplicate Note Action + if (ok) { + switch(p->ptr_instrument->dca) { + case DCA_NOTECUT: + fx_note_cut(csf, i, 1); + break; + case DCA_NOTEOFF: + fx_key_off(csf, i); + break; + case DCA_NOTEFADE: + p->flags |= CHN_NOTEFADE; + break; + } + if (!p->volume) { + p->fadeout_volume = 0; + p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); + } + } + } + if (chan->flags & CHN_MUTE) + return; + // New Note Action + if (chan->volume && chan->length) { + uint32_t n = csf_get_nna_channel(csf, nchan); + if (n) { + p = &csf->voices[n]; + // Copy Channel + *p = *chan; + p->flags &= ~(CHN_VIBRATO|CHN_TREMOLO|CHN_PORTAMENTO); + p->tremolo_delta = 0; + p->master_channel = nchan+1; + p->n_command = 0; + // Key Off the note + switch(chan->nna) { + case NNA_NOTEOFF: + fx_key_off(csf, n); + break; + case NNA_NOTECUT: + p->fadeout_volume = 0; + case NNA_NOTEFADE: + p->flags |= CHN_NOTEFADE; + break; + } + if (!p->volume) { + p->fadeout_volume = 0; + p->flags |= (CHN_NOTEFADE|CHN_FASTVOLRAMP); + } + // Stop this channel + chan->length = chan->position = chan->position_frac = 0; + chan->rofs = chan->lofs = 0; + } + } } static void handle_effect(song_t *csf, uint32_t nchan, uint32_t cmd, uint32_t param, int porta, int firsttick) { - song_voice_t *chan = csf->voices + nchan; + song_voice_t *chan = csf->voices + nchan; - switch (cmd) { - case FX_NONE: - break; - - // Set Volume - case FX_VOLUME: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - chan->volume = (param < 64) ? param*4 : 256; - chan->flags |= CHN_FASTVOLRAMP; - break; - - case FX_PORTAMENTOUP: - fx_portamento_up(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_PORTAMENTODOWN: - fx_portamento_down(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_VOLUMESLIDE: - fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_TONEPORTAMENTO: - fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_TONEPORTAVOL: - fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, 0); - break; - - case FX_VIBRATO: - fx_vibrato(chan, param); - break; - - case FX_VIBRATOVOL: - fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - fx_vibrato(chan, 0); - break; - - case FX_SPEED: - if ((csf->flags & SONG_FIRSTTICK) && param) { - csf->tick_count = param; - csf->current_speed = param; - } - break; - - case FX_TEMPO: - if (csf->flags & SONG_FIRSTTICK) { - if (param) - chan->mem_tempo = param; - else - param = chan->mem_tempo; - if (param >= 0x20) - csf->current_tempo = param; - } else { - param = chan->mem_tempo; // this just got set on tick zero - - switch (param >> 4) { - case 0: - csf->current_tempo -= param & 0xf; - if (csf->current_tempo < 32) - csf->current_tempo = 32; - break; - case 1: - csf->current_tempo += param & 0xf; - if (csf->current_tempo > 255) - csf->current_tempo = 255; - break; - } - } - break; - - case FX_OFFSET: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - if (param) - chan->mem_offset = (chan->mem_offset & ~0xff00) | (param << 8); - if (NOTE_IS_NOTE(chan->row_note)) { - // when would position *not* be zero if there's a note but no portamento? - if (porta) - chan->position = chan->mem_offset; - else - chan->position += chan->mem_offset; - if (chan->position > chan->length) { - chan->position = (csf->flags & SONG_ITOLDEFFECTS) ? chan->length : 0; - } - } - break; - - case FX_ARPEGGIO: - chan->n_command = FX_ARPEGGIO; - if (!(csf->flags & SONG_FIRSTTICK)) - break; - if (param) - chan->mem_arpeggio = param; - break; - - case FX_RETRIG: - if (param) - chan->mem_retrig = param & 0xFF; - fx_retrig_note(csf, nchan, chan->mem_retrig); - break; - - case FX_TREMOR: - // Tremor logic lifted from DUMB, which is the only player that actually gets it right. - // I *sort of* understand it. - if (csf->flags & SONG_FIRSTTICK) { - if (!param) - param = chan->mem_tremor; - else if (!(csf->flags & SONG_ITOLDEFFECTS)) { - if (param & 0xf0) param -= 0x10; - if (param & 0x0f) param -= 0x01; - } - chan->mem_tremor = param; - chan->cd_tremor |= 128; - } - - if ((chan->cd_tremor & 128) && chan->length) { - if (chan->cd_tremor == 128) - chan->cd_tremor = (chan->mem_tremor >> 4) | 192; - else if (chan->cd_tremor == 192) - chan->cd_tremor = (chan->mem_tremor & 0xf) | 128; - else - chan->cd_tremor--; - } - - chan->n_command = FX_TREMOR; - - break; - - case FX_GLOBALVOLUME: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - if (param <= 128) - csf->current_global_volume = param; - break; - - case FX_GLOBALVOLSLIDE: - fx_global_vol_slide(csf, chan, param); - break; - - case FX_PANNING: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - chan->flags &= ~CHN_SURROUND; - chan->panbrello_delta = 0; - chan->panning = param; - chan->pan_swing = 0; - chan->flags |= CHN_FASTVOLRAMP; - break; - - case FX_PANNINGSLIDE: - fx_panning_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_TREMOLO: - fx_tremolo(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_FINEVIBRATO: - fx_fine_vibrato(chan, param); - break; - - case FX_SPECIAL: - fx_special(csf, nchan, param); - break; - - case FX_KEYOFF: - if ((csf->current_speed - csf->tick_count) == param) - fx_key_off(csf, nchan); - break; - - case FX_CHANNELVOLUME: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - // FIXME rename global_volume to channel_volume in the channel struct - if (param <= 64) { - chan->global_volume = param; - chan->flags |= CHN_FASTVOLRAMP; - } - break; - - case FX_CHANNELVOLSLIDE: - fx_channel_vol_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); - break; - - case FX_PANBRELLO: - fx_panbrello(chan, param); - break; - - case FX_SETENVPOSITION: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - chan->vol_env_position = param; - chan->pan_env_position = param; - chan->pitch_env_position = param; - if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument) { - song_instrument_t *penv = chan->ptr_instrument; - if ((chan->flags & CHN_PANENV) - && (penv->pan_env.nodes) - && ((int)param > penv->pan_env.ticks[penv->pan_env.nodes-1])) { - chan->flags &= ~CHN_PANENV; - } - } - break; - - case FX_POSITIONJUMP: - if (csf->flags & SONG_FIRSTTICK) { - if (!(csf->mix_flags & SNDMIX_NOBACKWARDJUMPS) || csf->process_order < param) - csf->process_order = param - 1; - csf->process_row = PROCESS_NEXT_ORDER; - } - break; - - case FX_PATTERNBREAK: - if (csf->flags & SONG_FIRSTTICK) { - csf->break_row = param; - csf->process_row = PROCESS_NEXT_ORDER; - } - break; - - case FX_MIDI: - if (!(csf->flags & SONG_FIRSTTICK)) - break; - if (param < 0x80) { - csf_process_midi_macro(csf, nchan, - csf->midi_config.sfx[chan->active_macro], - param, 0, 0, 0); - } else { - csf_process_midi_macro(csf, nchan, - csf->midi_config.zxx[param & 0x7F], - 0, 0, 0, 0); - } - break; - - case FX_NOTESLIDEUP: - fx_note_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param, 1); - break; - case FX_NOTESLIDEDOWN: - fx_note_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param, -1); - break; - } + switch (cmd) { + case FX_NONE: + break; + + // Set Volume + case FX_VOLUME: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + chan->volume = (param < 64) ? param*4 : 256; + chan->flags |= CHN_FASTVOLRAMP; + break; + + case FX_PORTAMENTOUP: + if (firsttick) { + if (param) + chan->mem_pitchslide = param; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_portanote = chan->mem_pitchslide; + } + fx_portamento_up(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_PORTAMENTODOWN: + if (firsttick) { + if (param) + chan->mem_pitchslide = param; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_portanote = chan->mem_pitchslide; + } + fx_portamento_down(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_VOLUMESLIDE: + fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_TONEPORTAMENTO: + if (firsttick) { + if (param) + chan->mem_portanote = param; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_pitchslide = chan->mem_portanote; + } + fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_TONEPORTAVOL: + fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, 0); + break; + + case FX_VIBRATO: + fx_vibrato(chan, param); + break; + + case FX_VIBRATOVOL: + fx_volume_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + fx_vibrato(chan, 0); + break; + + case FX_SPEED: + if ((csf->flags & SONG_FIRSTTICK) && param) { + csf->tick_count = param; + csf->current_speed = param; + } + break; + + case FX_TEMPO: + if (csf->flags & SONG_FIRSTTICK) { + if (param) + chan->mem_tempo = param; + else + param = chan->mem_tempo; + if (param >= 0x20) + csf->current_tempo = param; + } else { + param = chan->mem_tempo; // this just got set on tick zero + + switch (param >> 4) { + case 0: + csf->current_tempo -= param & 0xf; + if (csf->current_tempo < 32) + csf->current_tempo = 32; + break; + case 1: + csf->current_tempo += param & 0xf; + if (csf->current_tempo > 255) + csf->current_tempo = 255; + break; + } + } + break; + + case FX_OFFSET: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + if (param) + chan->mem_offset = (chan->mem_offset & ~0xff00) | (param << 8); + if (NOTE_IS_NOTE(chan->row_note)) { + // when would position *not* be zero if there's a note but no portamento? + if (porta) + chan->position = chan->mem_offset; + else + chan->position += chan->mem_offset; + if (chan->position > chan->length) { + chan->position = (csf->flags & SONG_ITOLDEFFECTS) ? chan->length : 0; + } + } + break; + + case FX_ARPEGGIO: + chan->n_command = FX_ARPEGGIO; + if (!(csf->flags & SONG_FIRSTTICK)) + break; + if (param) + chan->mem_arpeggio = param; + break; + + case FX_RETRIG: + if (param) + chan->mem_retrig = param & 0xFF; + fx_retrig_note(csf, nchan, chan->mem_retrig); + break; + + case FX_TREMOR: + // Tremor logic lifted from DUMB, which is the only player that actually gets it right. + // I *sort of* understand it. + if (csf->flags & SONG_FIRSTTICK) { + if (!param) + param = chan->mem_tremor; + else if (!(csf->flags & SONG_ITOLDEFFECTS)) { + if (param & 0xf0) param -= 0x10; + if (param & 0x0f) param -= 0x01; + } + chan->mem_tremor = param; + chan->cd_tremor |= 128; + } + + if ((chan->cd_tremor & 128) && chan->length) { + if (chan->cd_tremor == 128) + chan->cd_tremor = (chan->mem_tremor >> 4) | 192; + else if (chan->cd_tremor == 192) + chan->cd_tremor = (chan->mem_tremor & 0xf) | 128; + else + chan->cd_tremor--; + } + + chan->n_command = FX_TREMOR; + + break; + + case FX_GLOBALVOLUME: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + if (param <= 128) + csf->current_global_volume = param; + break; + + case FX_GLOBALVOLSLIDE: + fx_global_vol_slide(csf, chan, param); + break; + + case FX_PANNING: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + chan->flags &= ~CHN_SURROUND; + chan->panbrello_delta = 0; + chan->panning = param; + chan->pan_swing = 0; + chan->flags |= CHN_FASTVOLRAMP; + break; + + case FX_PANNINGSLIDE: + fx_panning_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_TREMOLO: + fx_tremolo(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_FINEVIBRATO: + fx_fine_vibrato(chan, param); + break; + + case FX_SPECIAL: + fx_special(csf, nchan, param); + break; + + case FX_KEYOFF: + if ((csf->current_speed - csf->tick_count) == param) + fx_key_off(csf, nchan); + break; + + case FX_CHANNELVOLUME: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + // FIXME rename global_volume to channel_volume in the channel struct + if (param <= 64) { + chan->global_volume = param; + chan->flags |= CHN_FASTVOLRAMP; + } + break; + + case FX_CHANNELVOLSLIDE: + fx_channel_vol_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param); + break; + + case FX_PANBRELLO: + fx_panbrello(chan, param); + break; + + case FX_SETENVPOSITION: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + chan->vol_env_position = param; + chan->pan_env_position = param; + chan->pitch_env_position = param; + if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument) { + song_instrument_t *penv = chan->ptr_instrument; + if ((chan->flags & CHN_PANENV) + && (penv->pan_env.nodes) + && ((int)param > penv->pan_env.ticks[penv->pan_env.nodes-1])) { + chan->flags &= ~CHN_PANENV; + } + } + break; + + case FX_POSITIONJUMP: + if (csf->flags & SONG_FIRSTTICK) { + if (!(csf->mix_flags & SNDMIX_NOBACKWARDJUMPS) || csf->process_order < param) + csf->process_order = param - 1; + csf->process_row = PROCESS_NEXT_ORDER; + } + break; + + case FX_PATTERNBREAK: + if (csf->flags & SONG_FIRSTTICK) { + csf->break_row = param; + csf->process_row = PROCESS_NEXT_ORDER; + } + break; + + case FX_MIDI: + if (!(csf->flags & SONG_FIRSTTICK)) + break; + if (param < 0x80) { + csf_process_midi_macro(csf, nchan, + csf->midi_config.sfx[chan->active_macro], + param, 0, 0, 0); + } else { + csf_process_midi_macro(csf, nchan, + csf->midi_config.zxx[param & 0x7F], + 0, 0, 0, 0); + } + break; + + case FX_NOTESLIDEUP: + fx_note_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param, 1); + break; + case FX_NOTESLIDEDOWN: + fx_note_slide(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, param, -1); + break; + } } static void handle_voleffect(song_t *csf, song_voice_t *chan, uint32_t volcmd, uint32_t vol, - int firsttick, int start_note) + int firsttick, int start_note) { - /* A few notes, paraphrased from ITTECH.TXT: - Ex/Fx/Gx are shared with Exx/Fxx/Gxx; Ex/Fx are 4x the 'normal' slide value - Gx is linked with Ex/Fx if Compat Gxx is off, just like Gxx is with Exx/Fxx - Gx values: 1, 4, 8, 16, 32, 64, 96, 128, 255 - Ax/Bx/Cx/Dx values are used directly (i.e. D9 == D09), and are NOT shared with Dxx - (value is stored into mem_vc_volslide and used by A0/B0/C0/D0) - Hx uses the same value as Hxx and Uxx, and affects the *depth* - so... hxx = (hx | (oldhxx & 0xf0)) ??? - - Additionally: volume and panning are handled on the start tick, not - the first tick of the row (that is, SDx alters their behavior) */ - - switch (volcmd) { - case VOLFX_NONE: - break; - - case VOLFX_VOLUME: - if (start_note) { - if (vol > 64) vol = 64; - chan->volume = vol << 2; - chan->flags |= CHN_FASTVOLRAMP; - } - break; - - case VOLFX_PANNING: - if (start_note) { - if (vol > 64) vol = 64; - chan->panning = vol << 2; - chan->pan_swing = 0; - chan->flags |= CHN_FASTVOLRAMP; - chan->flags &= ~CHN_SURROUND; - chan->panbrello_delta = 0; - } - break; - - case VOLFX_PORTAUP: // Fx - if (firsttick) { - if (vol) - chan->mem_pitchslide = 4 * vol; - if (!(csf->flags & SONG_COMPATGXX)) - chan->mem_portanote = chan->mem_pitchslide; - } else { - fx_reg_portamento_up(csf->flags, chan, chan->mem_pitchslide); - } - break; - - case VOLFX_PORTADOWN: // Ex - if (firsttick) { - if (vol) - chan->mem_pitchslide = 4 * vol; - if (!(csf->flags & SONG_COMPATGXX)) - chan->mem_portanote = chan->mem_pitchslide; - } else { - fx_reg_portamento_down(csf->flags, chan, chan->mem_pitchslide); - } - break; - - case VOLFX_TONEPORTAMENTO: // Gx - fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, - vc_portamento_table[vol & 0x0F]); - break; - - case VOLFX_VOLSLIDEUP: // Cx - if (firsttick) { - if (vol) - chan->mem_vc_volslide = vol; - } else { - fx_volume_up(chan, chan->mem_vc_volslide); - } - break; - - case VOLFX_VOLSLIDEDOWN: // Dx - if (firsttick) { - if (vol) - chan->mem_vc_volslide = vol; - } else { - fx_volume_down(chan, chan->mem_vc_volslide); - } - break; - - case VOLFX_FINEVOLUP: // Ax - if (firsttick) { - if (vol) - chan->mem_vc_volslide = vol; - else - vol = chan->mem_vc_volslide; - fx_volume_up(chan, vol); - } - break; - - case VOLFX_FINEVOLDOWN: // Bx - if (firsttick) { - if (vol) - chan->mem_vc_volslide = vol; - else - vol = chan->mem_vc_volslide; - fx_volume_down(chan, vol); - } - break; - - case VOLFX_VIBRATODEPTH: // Hx - fx_vibrato(chan, vol); - break; - - case VOLFX_VIBRATOSPEED: // $x (FT2 compat.) - fx_vibrato(chan, vol << 4); - break; - - case VOLFX_PANSLIDELEFT: // flags, chan, vol); - break; - - case VOLFX_PANSLIDERIGHT: // >x (FT2) - fx_panning_slide(csf->flags, chan, vol << 4); - break; - } + /* A few notes, paraphrased from ITTECH.TXT: + Ex/Fx/Gx are shared with Exx/Fxx/Gxx; Ex/Fx are 4x the 'normal' slide value + Gx is linked with Ex/Fx if Compat Gxx is off, just like Gxx is with Exx/Fxx + Gx values: 1, 4, 8, 16, 32, 64, 96, 128, 255 + Ax/Bx/Cx/Dx values are used directly (i.e. D9 == D09), and are NOT shared with Dxx + (value is stored into mem_vc_volslide and used by A0/B0/C0/D0) + Hx uses the same value as Hxx and Uxx, and affects the *depth* + so... hxx = (hx | (oldhxx & 0xf0)) ??? + + Additionally: volume and panning are handled on the start tick, not + the first tick of the row (that is, SDx alters their behavior) */ + + switch (volcmd) { + case VOLFX_NONE: + break; + + case VOLFX_VOLUME: + if (start_note) { + if (vol > 64) vol = 64; + chan->volume = vol << 2; + chan->flags |= CHN_FASTVOLRAMP; + } + break; + + case VOLFX_PANNING: + if (start_note) { + if (vol > 64) vol = 64; + chan->panning = vol << 2; + chan->pan_swing = 0; + chan->flags |= CHN_FASTVOLRAMP; + chan->flags &= ~CHN_SURROUND; + chan->panbrello_delta = 0; + } + break; + + case VOLFX_PORTAUP: // Fx + if (firsttick) { + if (vol) + chan->mem_pitchslide = 4 * vol; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_portanote = chan->mem_pitchslide; + } else { + fx_reg_portamento_up(csf->flags, chan, chan->mem_pitchslide); + } + break; + + case VOLFX_PORTADOWN: // Ex + if (firsttick) { + if (vol) + chan->mem_pitchslide = 4 * vol; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_portanote = chan->mem_pitchslide; + } else { + fx_reg_portamento_down(csf->flags, chan, chan->mem_pitchslide); + } + break; + + case VOLFX_TONEPORTAMENTO: // Gx + if (firsttick) { + if (vol) + chan->mem_portanote = vc_portamento_table[vol & 0x0F]; + if (!(csf->flags & SONG_COMPATGXX)) + chan->mem_pitchslide = chan->mem_portanote; + } + fx_tone_portamento(csf->flags | (firsttick ? SONG_FIRSTTICK : 0), chan, + vc_portamento_table[vol & 0x0F]); + break; + + case VOLFX_VOLSLIDEUP: // Cx + if (firsttick) { + if (vol) + chan->mem_vc_volslide = vol; + } else { + fx_volume_up(chan, chan->mem_vc_volslide); + } + break; + + case VOLFX_VOLSLIDEDOWN: // Dx + if (firsttick) { + if (vol) + chan->mem_vc_volslide = vol; + } else { + fx_volume_down(chan, chan->mem_vc_volslide); + } + break; + + case VOLFX_FINEVOLUP: // Ax + if (firsttick) { + if (vol) + chan->mem_vc_volslide = vol; + else + vol = chan->mem_vc_volslide; + fx_volume_up(chan, vol); + } + break; + + case VOLFX_FINEVOLDOWN: // Bx + if (firsttick) { + if (vol) + chan->mem_vc_volslide = vol; + else + vol = chan->mem_vc_volslide; + fx_volume_down(chan, vol); + } + break; + + case VOLFX_VIBRATODEPTH: // Hx + fx_vibrato(chan, vol); + break; + + case VOLFX_VIBRATOSPEED: // $x (FT2 compat.) + fx_vibrato(chan, vol << 4); + break; + + case VOLFX_PANSLIDELEFT: // flags, chan, vol); + break; + + case VOLFX_PANSLIDERIGHT: // >x (FT2) + fx_panning_slide(csf->flags, chan, vol << 4); + break; + } } /* firsttick is only used for SDx at the moment */ void csf_process_effects(song_t *csf, int firsttick) { - song_voice_t *chan = csf->voices; - for (uint32_t nchan=0; nchann_command=0; - - uint32_t instr = chan->row_instr; - uint32_t volcmd = chan->row_voleffect; - uint32_t vol = chan->row_volparam; - uint32_t cmd = chan->row_effect; - uint32_t param = chan->row_param; - int porta = (cmd == FX_TONEPORTAMENTO - || cmd == FX_TONEPORTAVOL - || volcmd == VOLFX_TONEPORTAMENTO); - int start_note = csf->flags & SONG_FIRSTTICK; - - chan->flags &= ~CHN_FASTVOLRAMP; - - // set instrument before doing anything else - if (instr) chan->new_instrument = instr; - - /* Have to handle SDx specially because of the way the effects are structured. - In a PERFECT world, this would be very straightforward: - - Handle the effect column, and set flags for things that should happen - (portamento, volume slides, arpeggio, vibrato, tremolo) - - If note delay counter is set, stop processing that channel - - Trigger all notes if it's their start tick - - Handle volume column. - The obvious implication of this is that all effects are checked only once, and - volumes only need to be set for notes once. Additionally this helps for separating - the mixing code from the rest of the interface (which is always good, especially - for hardware mixing...) - Oh well, the world is not perfect. */ - - if (cmd == FX_SPECIAL) { - if (param) - chan->mem_special = param; - else - param = chan->mem_special; - if (param >> 4 == 0xd) { - // Ideally this would use SONG_FIRSTTICK, but Impulse Tracker has a bug here :) - if (firsttick) { - chan->cd_note_delay = (param & 0xf) ?: 1; - continue; // notes never play on the first tick with SDx, go away - } - if (--chan->cd_note_delay > 0) - continue; // not our turn yet, go away - start_note = (chan->cd_note_delay == 0); - } - } - - // Handles note/instrument/volume changes - if (start_note) { - uint32_t note = chan->row_note; - if (instr && note == NOTE_NONE) { - if (csf->flags & SONG_INSTRUMENTMODE) { - if (chan->ptr_sample) - chan->volume = chan->ptr_sample->volume; - } else { - if (instr < MAX_SAMPLES) - chan->volume = csf->samples[instr].volume; - } - } - // Invalid Instrument ? - if (instr >= MAX_INSTRUMENTS) instr = 0; - // Note Cut/Off => ignore instrument - if ((NOTE_IS_CONTROL(note)) || (note != NOTE_NONE && !porta)) { - /* This is required when the instrument changes (KeyOff is not called) */ - /* Possibly a better bugfix could be devised. --Bisqwit */ - OPL_NoteOff(nchan); - OPL_Touch(nchan, NULL, 0); - GM_KeyOff(nchan); - GM_Touch(nchan, 0); - } - - if (NOTE_IS_CONTROL(note)) { - instr = 0; - } else if (NOTE_IS_NOTE(note)) { - chan->new_note = note; - // New Note Action ? (not when paused!!!) - if (!porta) - csf_check_nna(csf, nchan, instr, note, 0); - } - // Instrument Change ? - if (instr) { - song_sample_t *psmp = chan->ptr_sample; - csf_instrument_change(csf, chan, instr, porta, 1); - OPL_Patch(nchan, csf->samples[instr].adlib_bytes); - - if((csf->flags & SONG_INSTRUMENTMODE) && csf->instruments[instr]) - GM_DPatch(nchan, csf->instruments[instr]->midi_program, - csf->instruments[instr]->midi_bank, - csf->instruments[instr]->midi_channel_mask); - - chan->new_instrument = 0; - // Special IT case: portamento+note causes sample change -> ignore portamento - if (psmp != chan->ptr_sample && NOTE_IS_NOTE(note)) { - porta = 0; - } - } - // New Note ? - if (note != NOTE_NONE) { - if (!instr && chan->new_instrument && NOTE_IS_NOTE(note)) { - csf_instrument_change(csf, chan, chan->new_instrument, porta, 0); - if ((csf->flags & SONG_INSTRUMENTMODE) - && csf->instruments[chan->new_instrument]) { - OPL_Patch(nchan, csf->samples[chan->new_instrument].adlib_bytes); - GM_DPatch(nchan, csf->instruments[chan->new_instrument]->midi_program, - csf->instruments[chan->new_instrument]->midi_bank, - csf->instruments[chan->new_instrument]->midi_channel_mask); - } - chan->new_instrument = 0; - } - csf_note_change(csf, nchan, note, porta, 0, !instr); - } - } - - handle_voleffect(csf, chan, volcmd, vol, firsttick, start_note); - handle_effect(csf, nchan, cmd, param, porta, firsttick); - } + song_voice_t *chan = csf->voices; + for (uint32_t nchan=0; nchann_command=0; + + uint32_t instr = chan->row_instr; + uint32_t volcmd = chan->row_voleffect; + uint32_t vol = chan->row_volparam; + uint32_t cmd = chan->row_effect; + uint32_t param = chan->row_param; + int porta = (cmd == FX_TONEPORTAMENTO + || cmd == FX_TONEPORTAVOL + || volcmd == VOLFX_TONEPORTAMENTO); + int start_note = csf->flags & SONG_FIRSTTICK; + + chan->flags &= ~CHN_FASTVOLRAMP; + + // set instrument before doing anything else + if (instr) chan->new_instrument = instr; + + /* Have to handle SDx specially because of the way the effects are structured. + In a PERFECT world, this would be very straightforward: + - Handle the effect column, and set flags for things that should happen + (portamento, volume slides, arpeggio, vibrato, tremolo) + - If note delay counter is set, stop processing that channel + - Trigger all notes if it's their start tick + - Handle volume column. + The obvious implication of this is that all effects are checked only once, and + volumes only need to be set for notes once. Additionally this helps for separating + the mixing code from the rest of the interface (which is always good, especially + for hardware mixing...) + Oh well, the world is not perfect. */ + + if (cmd == FX_SPECIAL) { + if (param) + chan->mem_special = param; + else + param = chan->mem_special; + if (param >> 4 == 0xd) { + // Ideally this would use SONG_FIRSTTICK, but Impulse Tracker has a bug here :) + if (firsttick) { + chan->cd_note_delay = (param & 0xf) ?: 1; + continue; // notes never play on the first tick with SDx, go away + } + if (--chan->cd_note_delay > 0) + continue; // not our turn yet, go away + start_note = (chan->cd_note_delay == 0); + } + } + + // Handles note/instrument/volume changes + if (start_note) { + uint32_t note = chan->row_note; + if (instr && note == NOTE_NONE) { + if (csf->flags & SONG_INSTRUMENTMODE) { + if (chan->ptr_sample) + chan->volume = chan->ptr_sample->volume; + } else { + if (instr < MAX_SAMPLES) + chan->volume = csf->samples[instr].volume; + } + } + // Invalid Instrument ? + if (instr >= MAX_INSTRUMENTS) instr = 0; + // Note Cut/Off => ignore instrument + if ((NOTE_IS_CONTROL(note)) || (note != NOTE_NONE && !porta)) { + /* This is required when the instrument changes (KeyOff is not called) */ + /* Possibly a better bugfix could be devised. --Bisqwit */ + if (chan->flags & CHN_ADLIB) { + //Do this only if really an adlib chan. Important! + OPL_NoteOff(nchan); + OPL_Touch(nchan, NULL, 0); + } + GM_KeyOff(nchan); + GM_Touch(nchan, 0); + } + + if (NOTE_IS_CONTROL(note)) { + instr = 0; + } else if (NOTE_IS_NOTE(note)) { + chan->new_note = note; + // New Note Action ? (not when paused!!!) + if (!porta) + csf_check_nna(csf, nchan, instr, note, 0); + } + // Instrument Change ? + if (instr) { + song_sample_t *psmp = chan->ptr_sample; + csf_instrument_change(csf, chan, instr, porta, 1); + if (csf->samples[instr].flags & CHN_ADLIB) { + OPL_Patch(nchan, csf->samples[instr].adlib_bytes); + } + + if((csf->flags & SONG_INSTRUMENTMODE) && csf->instruments[instr]) + GM_DPatch(nchan, csf->instruments[instr]->midi_program, + csf->instruments[instr]->midi_bank, + csf->instruments[instr]->midi_channel_mask); + + chan->new_instrument = 0; + // Special IT case: portamento+note causes sample change -> ignore portamento + if (psmp != chan->ptr_sample && NOTE_IS_NOTE(note)) { + porta = 0; + } + } + // New Note ? + if (note != NOTE_NONE) { + if (!instr && chan->new_instrument && NOTE_IS_NOTE(note)) { + csf_instrument_change(csf, chan, chan->new_instrument, porta, 0); + if ((csf->flags & SONG_INSTRUMENTMODE) + && csf->instruments[chan->new_instrument]) { + if (csf->samples[chan->new_instrument].flags & CHN_ADLIB) { + OPL_Patch(nchan, csf->samples[chan->new_instrument].adlib_bytes); + } + GM_DPatch(nchan, csf->instruments[chan->new_instrument]->midi_program, + csf->instruments[chan->new_instrument]->midi_bank, + csf->instruments[chan->new_instrument]->midi_channel_mask); + } + chan->new_instrument = 0; + } + csf_note_change(csf, nchan, note, porta, 0, !instr); + } + } + + handle_effect(csf, nchan, cmd, param, porta, firsttick); + handle_voleffect(csf, chan, volcmd, vol, firsttick, start_note); + } } - diff -Nru schism-0+20110101/player/equalizer.c schism-20160521/player/equalizer.c --- schism-0+20110101/player/equalizer.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/equalizer.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -39,13 +39,6 @@ } eq_band; -static const unsigned int eq_linear_to_db[33] = { - 16, 19, 22, 25, 28, 31, 34, 37, - 40, 43, 46, 49, 52, 55, 58, 61, - 64, 76, 88, 100, 112, 124, 136, 148, - 160, 172, 184, 196, 208, 220, 232, 244, 256 -}; - //static REAL f2ic = (REAL)(1 << 28); //static REAL i2fc = (REAL)(1.0 / (1 << 28)); @@ -70,193 +63,193 @@ static void eq_filter(eq_band *pbs, float *pbuffer, unsigned int count) { - for (unsigned int i = 0; i < count; i++) { - float x = pbuffer[i]; - float y = pbs->a1 * pbs->x1 + - pbs->a2 * pbs->x2 + - pbs->a0 * x + - pbs->b1 * pbs->y1 + - pbs->b2 * pbs->y2; - - pbs->x2 = pbs->x1; - pbs->y2 = pbs->y1; - pbs->x1 = x; - pbuffer[i] = y; - pbs->y1 = y; - } + for (unsigned int i = 0; i < count; i++) { + float x = pbuffer[i]; + float y = pbs->a1 * pbs->x1 + + pbs->a2 * pbs->x2 + + pbs->a0 * x + + pbs->b1 * pbs->y1 + + pbs->b2 * pbs->y2; + + pbs->x2 = pbs->x1; + pbs->y2 = pbs->y1; + pbs->x1 = x; + pbuffer[i] = y; + pbs->y1 = y; + } } void eq_mono(song_t *csf, int *buffer, unsigned int count) { - mono_mix_to_float(buffer, csf->mix_buffer_float, count); + mono_mix_to_float(buffer, csf->mix_buffer_float, count); - for (unsigned int b = 0; b < MAX_EQ_BANDS; b++) - { - if (eq[b].enabled && eq[b].gain != 1.0f) - eq_filter(&eq[b], csf->mix_buffer_float, count); - } + for (unsigned int b = 0; b < MAX_EQ_BANDS; b++) + { + if (eq[b].enabled && eq[b].gain != 1.0f) + eq_filter(&eq[b], csf->mix_buffer_float, count); + } - float_to_mono_mix(csf->mix_buffer_float, buffer, count); + float_to_mono_mix(csf->mix_buffer_float, buffer, count); } // XXX: I rolled the two loops into one. Make sure this works. void eq_stereo(song_t *csf, int *buffer, unsigned int count) { - stereo_mix_to_float(buffer, csf->mix_buffer_float, csf->mix_buffer_float + MIXBUFFERSIZE, count); + stereo_mix_to_float(buffer, csf->mix_buffer_float, csf->mix_buffer_float + MIXBUFFERSIZE, count); - for (unsigned int b = 0; b < MAX_EQ_BANDS; b++) { - int br = b + MAX_EQ_BANDS; + for (unsigned int b = 0; b < MAX_EQ_BANDS; b++) { + int br = b + MAX_EQ_BANDS; - // Left band - if (eq[b].enabled && eq[b].gain != 1.0f) - eq_filter(&eq[b], csf->mix_buffer_float, count); + // Left band + if (eq[b].enabled && eq[b].gain != 1.0f) + eq_filter(&eq[b], csf->mix_buffer_float, count); - // Right band - if (eq[br].enabled && eq[br].gain != 1.0f) - eq_filter(&eq[br], csf->mix_buffer_float + MIXBUFFERSIZE, count); - } + // Right band + if (eq[br].enabled && eq[br].gain != 1.0f) + eq_filter(&eq[br], csf->mix_buffer_float + MIXBUFFERSIZE, count); + } - float_to_stereo_mix(csf->mix_buffer_float, csf->mix_buffer_float + MIXBUFFERSIZE, buffer, count); + float_to_stereo_mix(csf->mix_buffer_float, csf->mix_buffer_float + MIXBUFFERSIZE, buffer, count); } void initialize_eq(int reset, float freq) { - //float fMixingFreq = (REAL)mix_frequency; + //float fMixingFreq = (REAL)mix_frequency; - // Gain = 0.5 (-6dB) .. 2 (+6dB) - for (unsigned int band = 0; band < MAX_EQ_BANDS * 2; band++) { - float k, k2, r, f; - float v0, v1; - int b = reset; - - if (!eq[band].enabled) { - eq[band].a0 = 0; - eq[band].a1 = 0; - eq[band].a2 = 0; - eq[band].b1 = 0; - eq[band].b2 = 0; - eq[band].x1 = 0; - eq[band].x2 = 0; - eq[band].y1 = 0; - eq[band].y2 = 0; - continue; - } - - f = eq[band].center_frequency / freq; - - if (f > 0.45f) - eq[band].gain = 1; - - //if (f > 0.25) - // f = 0.25; - - //k = tan(PI * f); - - k = f * 3.141592654f; - k = k + k * f; - - //if (k > (float) 0.707) - // k = (float) 0.707; - - k2 = k*k; - v0 = eq[band].gain; - v1 = 1; - - if (eq[band].gain < 1.0) { - v0 *= 0.5f / EQ_BANDWIDTH; - v1 *= 0.5f / EQ_BANDWIDTH; - } - else { - v0 *= 1.0f / EQ_BANDWIDTH; - v1 *= 1.0f / EQ_BANDWIDTH; - } - - r = (1 + v0 * k + k2) / (1 + v1 * k + k2); - - if (r != eq[band].a0) { - eq[band].a0 = r; - b = 1; - } - - r = 2 * (k2 - 1) / (1 + v1 * k + k2); - - if (r != eq[band].a1) { - eq[band].a1 = r; - b = 1; - } - - r = (1 - v0 * k + k2) / (1 + v1 * k + k2); - - if (r != eq[band].a2) { - eq[band].a2 = r; - b = 1; - } - - r = -2 * (k2 - 1) / (1 + v1 * k + k2); - - if (r != eq[band].b1) { - eq[band].b1 = r; - b = 1; - } - - r = -(1 - v1 * k + k2) / (1 + v1 * k + k2); - - if (r != eq[band].b2) { - eq[band].b2 = r; - b = 1; - } - - if (b) { - eq[band].x1 = 0; - eq[band].x2 = 0; - eq[band].y1 = 0; - eq[band].y2 = 0; - } - } + // Gain = 0.5 (-6dB) .. 2 (+6dB) + for (unsigned int band = 0; band < MAX_EQ_BANDS * 2; band++) { + float k, k2, r, f; + float v0, v1; + int b = reset; + + if (!eq[band].enabled) { + eq[band].a0 = 0; + eq[band].a1 = 0; + eq[band].a2 = 0; + eq[band].b1 = 0; + eq[band].b2 = 0; + eq[band].x1 = 0; + eq[band].x2 = 0; + eq[band].y1 = 0; + eq[band].y2 = 0; + continue; + } + + f = eq[band].center_frequency / freq; + + if (f > 0.45f) + eq[band].gain = 1; + + //if (f > 0.25) + // f = 0.25; + + //k = tan(PI * f); + + k = f * 3.141592654f; + k = k + k * f; + + //if (k > (float) 0.707) + // k = (float) 0.707; + + k2 = k*k; + v0 = eq[band].gain; + v1 = 1; + + if (eq[band].gain < 1.0) { + v0 *= 0.5f / EQ_BANDWIDTH; + v1 *= 0.5f / EQ_BANDWIDTH; + } + else { + v0 *= 1.0f / EQ_BANDWIDTH; + v1 *= 1.0f / EQ_BANDWIDTH; + } + + r = (1 + v0 * k + k2) / (1 + v1 * k + k2); + + if (r != eq[band].a0) { + eq[band].a0 = r; + b = 1; + } + + r = 2 * (k2 - 1) / (1 + v1 * k + k2); + + if (r != eq[band].a1) { + eq[band].a1 = r; + b = 1; + } + + r = (1 - v0 * k + k2) / (1 + v1 * k + k2); + + if (r != eq[band].a2) { + eq[band].a2 = r; + b = 1; + } + + r = -2 * (k2 - 1) / (1 + v1 * k + k2); + + if (r != eq[band].b1) { + eq[band].b1 = r; + b = 1; + } + + r = -(1 - v1 * k + k2) / (1 + v1 * k + k2); + + if (r != eq[band].b2) { + eq[band].b2 = r; + b = 1; + } + + if (b) { + eq[band].x1 = 0; + eq[band].x2 = 0; + eq[band].y1 = 0; + eq[band].y2 = 0; + } + } } void set_eq_gains(const unsigned int *gainbuff, unsigned int gains, const unsigned int *freqs, - int reset, int mix_freq) + int reset, int mix_freq) { - for (unsigned int i = 0; i < MAX_EQ_BANDS; i++) { - float g, f = 0; - - if (i < gains) { - unsigned int n = gainbuff[i]; + for (unsigned int i = 0; i < MAX_EQ_BANDS; i++) { + float g, f = 0; - //if (n > 32) - // n = 32; + if (i < gains) { + unsigned int n = gainbuff[i]; - g = 1.0 + (((double) n) / 64.0); - - if (freqs) - f = (float)(int) freqs[i]; - } - else { - g = 1; - } - - eq[i].gain = - eq[i + MAX_EQ_BANDS].gain = g; - eq[i].center_frequency = - eq[i + MAX_EQ_BANDS].center_frequency = f; - - /* don't enable bands outside... */ - if (f > 20.0f && - i < gains) { - eq[i].enabled = - eq[i + MAX_EQ_BANDS].enabled = 1; - } - else { - eq[i].enabled = - eq[i + MAX_EQ_BANDS].enabled = 0; - } - } + //if (n > 32) + // n = 32; + + g = 1.0 + (((double) n) / 64.0); + + if (freqs) + f = (float)(int) freqs[i]; + } + else { + g = 1; + } + + eq[i].gain = + eq[i + MAX_EQ_BANDS].gain = g; + eq[i].center_frequency = + eq[i + MAX_EQ_BANDS].center_frequency = f; + + /* don't enable bands outside... */ + if (f > 20.0f && + i < gains) { + eq[i].enabled = + eq[i + MAX_EQ_BANDS].enabled = 1; + } + else { + eq[i].enabled = + eq[i + MAX_EQ_BANDS].enabled = 0; + } + } - initialize_eq(reset, mix_freq); + initialize_eq(reset, mix_freq); } diff -Nru schism-0+20110101/player/filters.c schism-20160521/player/filters.c --- schism-0+20110101/player/filters.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/filters.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -23,80 +23,43 @@ #include "sndfile.h" #include "cmixer.h" +#include "math.h" -// AWE32: cutoff = reg[0-255] * 31.25 + 100 -> [100Hz-8060Hz] -// EMU10K1 docs: cutoff = reg[0-127]*62+100 - -static const int filter_cutoff[] = { - 130, 132, 134, 136, 138, 140, 142, 144, - 146, 148, 151, 153, 155, 157, 160, 162, - 164, 167, 169, 172, 174, 177, 179, 182, - 184, 187, 190, 193, 195, 198, 201, 204, - 207, 210, 213, 216, 220, 223, 226, 229, - 233, 236, 239, 243, 246, 250, 254, 257, - 261, 265, 269, 273, 277, 281, 285, 289, - 293, 297, 302, 306, 311, 315, 320, 324, - 329, 334, 339, 344, 349, 354, 359, 364, - 369, 375, 380, 386, 391, 397, 403, 409, - 415, 421, 427, 433, 440, 446, 452, 459, - 466, 472, 479, 486, 493, 501, 508, 515, - 523, 530, 538, 546, 554, 562, 570, 578, - 587, 595, 604, 613, 622, 631, 640, 649, - 659, 668, 678, 688, 698, 708, 718, 729, - 739, 750, 761, 772, 783, 795, 806, 818, - 830, 842, 854, 867, 880, 892, 905, 918, - 932, 945, 959, 973, 987, 1002, 1016, 1031, - 1046, 1061, 1077, 1092, 1108, 1124, 1141, 1157, - 1174, 1191, 1209, 1226, 1244, 1262, 1280, 1299, - 1318, 1337, 1357, 1376, 1396, 1417, 1437, 1458, - 1479, 1501, 1523, 1545, 1567, 1590, 1613, 1637, - 1661, 1685, 1709, 1734, 1760, 1785, 1811, 1837, - 1864, 1891, 1919, 1947, 1975, 2004, 2033, 2062, - 2093, 2123, 2154, 2185, 2217, 2249, 2282, 2315, - 2349, 2383, 2418, 2453, 2489, 2525, 2561, 2599, - 2637, 2675, 2714, 2753, 2793, 2834, 2875, 2917, - 2959, 3003, 3046, 3091, 3135, 3181, 3227, 3274, - 3322, 3370, 3419, 3469, 3520, 3571, 3623, 3675, - 3729, 3783, 3838, 3894, 3951, 4008, 4066, 4125, - 4186, 4246, 4308, 4371, 4434, 4499, 4564, 4631, - 4698, 4766, 4836, 4906, 4978, 5050, 5123, 5198 -}; - - -static const float dmpfac[] = { - 131072, 128272, 125533, 122852, 120229, 117661, 115148, 112689, - 110283, 107928, 105623, 103367, 101160, 98999, 96885, 94816, - 92791, 90810, 88870, 86973, 85115, 83298, 81519, 79778, - 78074, 76407, 74775, 73178, 71615, 70086, 68589, 67125, - 65691, 64288, 62915, 61572, 60257, 58970, 57711, 56478, - 55272, 54092, 52937, 51806, 50700, 49617, 48557, 47520, - 46506, 45512, 44540, 43589, 42658, 41747, 40856, 39983, - 39130, 38294, 37476, 36676, 35893, 35126, 34376, 33642, - 32923, 32220, 31532, 30859, 30200, 29555, 28924, 28306, - 27701, 27110, 26531, 25964, 25410, 24867, 24336, 23816, - 23308, 22810, 22323, 21846, 21380, 20923, 20476, 20039, - 19611, 19192, 18782, 18381, 17989, 17604, 17228, 16861, - 16500, 16148, 15803, 15466, 15135, 14812, 14496, 14186, - 13883, 13587, 13297, 13013, 12735, 12463, 12197, 11936, - 11681, 11432, 11188, 10949, 10715, 10486, 10262, 10043, - 9829, 9619, 9413, 9212, 9015, 8823, 8634, 8450, - 8270, 8093, 7920, 7751, 7585, 7423, 7265, 7110, - 6958, 6809, 6664, 6522, 6382, 6246, 6113, 5982, - 5854, 5729, 5607, 5487, 5370, 5255, 5143, 5033, - 4926, 4820, 4718, 4617, 4518, 4422, 4327, 4235, - 4144, 4056, 3969, 3884, 3801, 3720, 3641, 3563, - 3487, 3412, 3340, 3268, 3198, 3130, 3063, 2998, - 2934, 2871, 2810, 2750, 2691, 2634, 2577, 2522, - 2468, 2416, 2364, 2314, 2264, 2216, 2169, 2122, - 2077, 2032, 1989, 1947, 1905, 1864, 1824, 1786, - 1747, 1710, 1674, 1638, 1603, 1569, 1535, 1502, - 1470, 1439, 1408, 1378, 1348, 1320, 1291, 1264, - 1237, 1210, 1185, 1159, 1135, 1110, 1087, 1063, - 1041, 1018, 997, 975, 955, 934, 914, 895, - 876, 857, 838, 821, 803, 786, 769, 753, - 737, 721, 705, 690, 676, 661, 647, 633, - 620, 606, 593, 581, 568, 556, 544, 533 +// LUT for 2 * damping factor +static const float resonance_table[128] = { + 1.0000000000000000f, 0.9786446094512940f, 0.9577452540397644f, 0.9372922182083130f, + 0.9172759056091309f, 0.8976871371269226f, 0.8785166740417481f, 0.8597555756568909f, + 0.8413951396942139f, 0.8234267830848694f, 0.8058421611785889f, 0.7886331081390381f, + 0.7717915177345276f, 0.7553095817565918f, 0.7391796708106995f, 0.7233941555023193f, + 0.7079457640647888f, 0.6928272843360901f, 0.6780316829681397f, 0.6635520458221436f, + 0.6493816375732422f, 0.6355138421058655f, 0.6219421625137329f, 0.6086603403091431f, + 0.5956621170043945f, 0.5829415321350098f, 0.5704925656318665f, 0.5583094954490662f, + 0.5463865399360657f, 0.5347182154655457f, 0.5232990980148315f, 0.5121238231658936f, + 0.5011872053146362f, 0.4904841780662537f, 0.4800096750259399f, 0.4697588682174683f, + 0.4597269892692566f, 0.4499093294143677f, 0.4403013288974762f, 0.4308985173702240f, + 0.4216965138912201f, 0.4126909971237183f, 0.4038778245449066f, 0.3952528536319733f, + 0.3868120610713959f, 0.3785515129566193f, 0.3704673945903778f, 0.3625559210777283f, + 0.3548133969306946f, 0.3472362160682678f, 0.3398208320140839f, 0.3325638175010681f, + 0.3254617750644684f, 0.3185114264488220f, 0.3117094635963440f, 0.3050527870655060f, + 0.2985382676124573f, 0.2921628654003143f, 0.2859236001968384f, 0.2798175811767578f, + 0.2738419771194458f, 0.2679939568042755f, 0.2622708380222321f, 0.2566699385643005f, + 0.2511886358261108f, 0.2458244115114212f, 0.2405747324228287f, 0.2354371547698975f, + 0.2304092943668366f, 0.2254888117313385f, 0.2206734120845795f, 0.2159608304500580f, + 0.2113489061594009f, 0.2068354636430740f, 0.2024184018373489f, 0.1980956792831421f, + 0.1938652694225311f, 0.1897251904010773f, 0.1856735348701477f, 0.1817083954811096f, + 0.1778279393911362f, 0.1740303486585617f, 0.1703138649463654f, 0.1666767448186874f, + 0.1631172895431519f, 0.1596338599920273f, 0.1562248021364212f, 0.1528885662555695f, + 0.1496235728263855f, 0.1464282870292664f, 0.1433012634515762f, 0.1402409970760346f, + 0.1372461020946503f, 0.1343151479959488f, 0.1314467936754227f, 0.1286396980285645f, + 0.1258925348520279f, 0.1232040524482727f, 0.1205729842185974f, 0.1179980933666229f, + 0.1154781952500343f, 0.1130121126770973f, 0.1105986908078194f, 0.1082368120551109f, + 0.1059253737330437f, 0.1036632955074310f, 0.1014495193958283f, 0.0992830246686935f, + 0.0971627980470657f, 0.0950878411531448f, 0.0930572077631950f, 0.0910699293017387f, + 0.0891250967979431f, 0.0872217938303947f, 0.0853591337800026f, 0.0835362523794174f, + 0.0817523002624512f, 0.0800064504146576f, 0.0782978758215904f, 0.0766257941722870f, + 0.0749894231557846f, 0.0733879879117012f, 0.0718207582831383f, 0.0702869966626167f, + 0.0687859877943993f, 0.0673170387744904f, 0.0658794566988945f, 0.0644725710153580f, }; @@ -104,52 +67,47 @@ // // XXX freq WAS unused but is now mix_frequency! // +#define FREQ_PARAM_MULT (128.0 / (24.0 * 256.0)) void setup_channel_filter(song_voice_t *chan, int reset, int flt_modifier, int freq) { - float fc; - float fs = freq;//(float)mix_frequency; - float fg, fb0, fb1; - float d2, d, e; - int cutoff = chan->cutoff; - int resonance = chan->resonance; - - cutoff = cutoff * (flt_modifier + 256) / 256; - - if (cutoff > 255) - cutoff = 255; - - if (resonance > 255) - resonance = 255; - - // Should be 255, but Zxx cutoff is limited to 127, so... - if (cutoff < 254) - chan->flags |= CHN_FILTER; - else - cutoff = 255; - - fc = (float) filter_cutoff[cutoff]; - - fc *= 3.14159265358979 * 2 / fs; - d2 = dmpfac[resonance] / (4*65536.0); - d = (1.0 - d2) * fc; - - if (d > 2.0) - d = 2.0; - - d = (d2 - d) / fc; - e = 1.0 / (fc * fc); - - fg = 1.0 / (1 + d + e); - fb0 = (d + e + e) / (1 + d + e); - fb1 = -e / (1 + d + e); - - chan->filter_a0 = (double) fg; - chan->filter_b0 = (double) fb0; - chan->filter_b1 = (double) fb1; - - if (reset) { - chan->filter_y1 = chan->filter_y2 = 0; - chan->filter_y3 = chan->filter_y4 = 0; - } + int cutoff = chan->cutoff; + int resonance = chan->resonance; + float frequency, r, d, e, fg, fb0, fb1; + + cutoff = cutoff * (flt_modifier + 256) / 256; + + if (cutoff > 255) + cutoff = 255; + + if (resonance > 255) + resonance = 255; + + // Should be 255, but Zxx cutoff is limited to 127, so... + if (cutoff < 254) + chan->flags |= CHN_FILTER; + else + cutoff = 255; + + // 2 ^ (i / 24 * 256) + frequency = 110.0 * powf(2.0, (float) cutoff * FREQ_PARAM_MULT + 0.25); + if (frequency > freq / 2.0) + frequency = freq / 2.0; + r = freq / (2.0 * M_PI * frequency); + + d = resonance_table[resonance] * r + resonance_table[resonance] - 1.0; + e = r * r; + + fg = 1.0 / (1.0 + d + e); + fb0 = (d + e + e) / (1.0 + d + e); + fb1 = -e / (1.0 + d + e); + + chan->filter_a0 = (int32_t)(fg * (1 << FILTERPRECISION)); + chan->filter_b0 = (int32_t)(fb0 * (1 << FILTERPRECISION)); + chan->filter_b1 = (int32_t)(fb1 * (1 << FILTERPRECISION)); + + if (reset) { + chan->filter_y1 = chan->filter_y2 = 0; + chan->filter_y3 = chan->filter_y4 = 0; + } } diff -Nru schism-0+20110101/player/fmopl.c schism-20160521/player/fmopl.c --- schism-0+20110101/player/fmopl.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/fmopl.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,22 +3,31 @@ ** File: fmopl.c - software implementation of FM sound generator ** types OPL and OPL2 ** -** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) -** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** Copyright Jarek Burczynski (bujar at mame dot net) +** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development ** -** Version 0.70 +** Version 0.72 ** Revision History: +04-08-2003 Jarek Burczynski: + - removed BFRDY hack. BFRDY is busy flag, and it should be 0 only when the chip + handles memory read/write or during the adpcm synthesis when the chip + requests another byte of ADPCM data. + +24-07-2003 Jarek Burczynski: + - added a small hack for Y8950 status BFRDY flag (bit 3 should be set after + some (unknown) delay). Right now it's always set. + 14-06-2003 Jarek Burczynski: - implemented all of the status register flags in Y8950 emulation - - renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since + - renamed y8950_set_delta_t_memory() parameters from _rom_ to _mem_ since they can be either RAM or ROM 08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) - - corrected YM3526Read() to always set bit 2 and bit 1 - to HIGH state - identical to YM3812Read (verified on real YM3526) + - corrected ym3526_read() to always set bit 2 and bit 1 + to HIGH state - identical to ym3812_read (verified on real YM3526) 04-28-2002 Jarek Burczynski: - binary exact Envelope Generator (verified on real YM3812); @@ -26,7 +35,7 @@ rates are 2 times slower and volume resolution is one bit less - modified interface functions (they no longer return pointer - that's internal to the emulator now): - - new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init() + - new wrapper functions for OPLCreate: ym3526_init(), ym3812_init() and y8950_init() - corrected 'off by one' error in feedback calculations (when feedback is off) - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) - speeded up noise generator calculations (Nicola Salmoria) @@ -53,9 +62,9 @@ - fixed subscription range of attack/decay tables - To do: - add delay before key off in CSM mode (see CSMKeyControll) - verify volume of the FM part on the Y8950 + To do: + add delay before key off in CSM mode (see CSMKeyControll) + verify volume of the FM part on the Y8950 */ #include @@ -66,21 +75,16 @@ //#include "driver.h" /* use M.A.M.E. */ #include "fmopl.h" -#ifndef PI -#define PI 3.14159265358979323846 -#endif - - /* output final shift */ #if (OPL_SAMPLE_BITS==16) - #define FINAL_SH (0) - #define MAXOUT (+32767) - #define MINOUT (-32768) + #define FINAL_SH (0) + #define MAXOUT (+32767) + #define MINOUT (-32768) #else - #define FINAL_SH (8) - #define MAXOUT (+127) - #define MINOUT (-128) + #define FINAL_SH (8) + #define MAXOUT (+127) + #define MINOUT (-128) #endif @@ -132,121 +136,131 @@ -typedef struct{ - UINT32 ar; /* attack rate: AR<<2 */ - UINT32 dr; /* decay rate: DR<<2 */ - UINT32 rr; /* release rate:RR<<2 */ - UINT8 KSR; /* key scale rate */ - UINT8 ksl; /* keyscale level */ - UINT8 ksr; /* key scale rate: kcode>>KSR */ - UINT8 mul; /* multiple: mul_tab[ML] */ - - /* Phase Generator */ - UINT32 Cnt; /* frequency counter */ - UINT32 Incr; /* frequency counter step */ - UINT8 FB; /* feedback shift value */ - INT32 *connect1; /* slot1 output pointer */ - INT32 op1_out[2]; /* slot1 output for feedback */ - UINT8 CON; /* connection (algorithm) type */ - - /* Envelope Generator */ - UINT8 eg_type; /* percussive/non-percussive mode */ - UINT8 state; /* phase type */ - UINT32 TL; /* total level: TL << 2 */ - INT32 TLL; /* adjusted now TL */ - INT32 volume; /* envelope counter */ - UINT32 sl; /* sustain level: sl_tab[SL] */ - UINT8 eg_sh_ar; /* (attack state) */ - UINT8 eg_sel_ar; /* (attack state) */ - UINT8 eg_sh_dr; /* (decay state) */ - UINT8 eg_sel_dr; /* (decay state) */ - UINT8 eg_sh_rr; /* (release state) */ - UINT8 eg_sel_rr; /* (release state) */ - UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ - - /* LFO */ - UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ - UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ +typedef struct +{ + UINT32 ar; /* attack rate: AR<<2 */ + UINT32 dr; /* decay rate: DR<<2 */ + UINT32 rr; /* release rate:RR<<2 */ + UINT8 KSR; /* key scale rate */ + UINT8 ksl; /* keyscale level */ + UINT8 ksr; /* key scale rate: kcode>>KSR */ + UINT8 mul; /* multiple: mul_tab[ML] */ + + /* Phase Generator */ + UINT32 Cnt; /* frequency counter */ + UINT32 Incr; /* frequency counter step */ + UINT8 FB; /* feedback shift value */ + INT32 *connect1; /* slot1 output pointer */ + INT32 op1_out[2]; /* slot1 output for feedback */ + UINT8 CON; /* connection (algorithm) type */ + + /* Envelope Generator */ + UINT8 eg_type; /* percussive/non-percussive mode */ + UINT8 state; /* phase type */ + UINT32 TL; /* total level: TL << 2 */ + INT32 TLL; /* adjusted now TL */ + INT32 volume; /* envelope counter */ + UINT32 sl; /* sustain level: sl_tab[SL] */ + UINT8 eg_sh_ar; /* (attack state) */ + UINT8 eg_sel_ar; /* (attack state) */ + UINT8 eg_sh_dr; /* (decay state) */ + UINT8 eg_sel_dr; /* (decay state) */ + UINT8 eg_sh_rr; /* (release state) */ + UINT8 eg_sel_rr; /* (release state) */ + UINT32 key; /* 0 = KEY OFF, >0 = KEY ON */ + + /* LFO */ + UINT32 AMmask; /* LFO Amplitude Modulation enable mask */ + UINT8 vib; /* LFO Phase Modulation enable flag (active high)*/ - /* waveform select */ - unsigned int wavetable; + /* waveform select */ + UINT16 wavetable; } OPL_SLOT; -typedef struct{ - OPL_SLOT SLOT[2]; - /* phase generator state */ - UINT32 block_fnum; /* block+fnum */ - UINT32 fc; /* Freq. Increment base */ - UINT32 ksl_base; /* KeyScaleLevel Base step */ - UINT8 kcode; /* key code (for key scaling) */ +typedef struct +{ + OPL_SLOT SLOT[2]; + /* phase generator state */ + UINT32 block_fnum; /* block+fnum */ + UINT32 fc; /* Freq. Increment base */ + UINT32 ksl_base; /* KeyScaleLevel Base step */ + UINT8 kcode; /* key code (for key scaling) */ } OPL_CH; /* OPL state */ -typedef struct fm_opl_f { - /* FM channel slots */ - OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ - - UINT32 eg_cnt; /* global envelope generator counter */ - UINT32 eg_timer; /* global envelope generator counter works at frequency=chipclock/72 */ - UINT32 eg_timer_add; /* step of eg_timer */ - UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ - - UINT8 rhythm; /* Rhythm mode */ - - UINT32 fn_tab[1024]; /* fnumber->increment counter */ - - /* LFO */ - UINT8 lfo_am_depth; - UINT8 lfo_pm_depth_range; - UINT32 lfo_am_cnt; - UINT32 lfo_am_inc; - UINT32 lfo_pm_cnt; - UINT32 lfo_pm_inc; - - UINT32 noise_rng; /* 23 bit noise shift register */ - UINT32 noise_p; /* current noise 'phase' */ - UINT32 noise_f; /* current noise period */ - - UINT8 wavesel; /* waveform select enable flag */ - - int T[2]; /* timer counters */ - int TC[2]; - UINT8 st[2]; /* timer enable */ +typedef struct +{ + /* FM channel slots */ + OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ + + UINT32 eg_cnt; /* global envelope generator counter */ + UINT32 eg_timer; /* global envelope generator counter works at frequency=chipclock/72 */ + UINT32 eg_timer_add; /* step of eg_timer */ + UINT32 eg_timer_overflow; /* envelope generator timer overlfows every 1 sample (on real chip) */ + + UINT8 rhythm; /* Rhythm mode */ + + UINT32 fn_tab[1024]; /* fnumber->increment counter */ + + /* LFO */ + UINT32 LFO_AM; + INT32 LFO_PM; + + UINT8 lfo_am_depth; + UINT8 lfo_pm_depth_range; + UINT32 lfo_am_cnt; + UINT32 lfo_am_inc; + UINT32 lfo_pm_cnt; + UINT32 lfo_pm_inc; + + UINT32 noise_rng; /* 23 bit noise shift register */ + UINT32 noise_p; /* current noise 'phase' */ + UINT32 noise_f; /* current noise period */ + + UINT8 wavesel; /* waveform select enable flag */ + + UINT32 T[2]; /* timer counters */ + UINT8 st[2]; /* timer enable */ #if BUILD_Y8950 - /* Delta-T ADPCM unit (Y8950) */ + /* Delta-T ADPCM unit (Y8950) */ - YM_DELTAT *deltat; + YM_DELTAT *deltat; - /* Keyboard and I/O ports interface */ - UINT8 portDirection; - UINT8 portLatch; - OPL_PORTHANDLER_R porthandler_r; - OPL_PORTHANDLER_W porthandler_w; - int port_param; - OPL_PORTHANDLER_R keyboardhandler_r; - OPL_PORTHANDLER_W keyboardhandler_w; - int keyboard_param; + /* Keyboard and I/O ports interface */ + UINT8 portDirection; + UINT8 portLatch; + OPL_PORTHANDLER_R porthandler_r; + OPL_PORTHANDLER_W porthandler_w; + void * port_param; + OPL_PORTHANDLER_R keyboardhandler_r; + OPL_PORTHANDLER_W keyboardhandler_w; + void * keyboard_param; #endif - /* external event callback handlers */ - OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ - int TimerParam; /* TIMER parameter */ - OPL_IRQHANDLER IRQHandler; /* IRQ handler */ - int IRQParam; /* IRQ parameter */ - OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ - int UpdateParam; /* stream update parameter */ - - UINT8 type; /* chip type */ - UINT8 address; /* address register */ - UINT8 status; /* status flag */ - UINT8 statusmask; /* status mask */ - UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ - - int clock; /* master clock (Hz) */ - int rate; /* sampling rate (Hz) */ - double freqbase; /* frequency base */ - double TimerBase; /* Timer base time (==sampling time)*/ + /* external event callback handlers */ + OPL_TIMERHANDLER timer_handler;/* TIMER handler */ + void *TimerParam; /* TIMER parameter */ + OPL_IRQHANDLER IRQHandler; /* IRQ handler */ + void *IRQParam; /* IRQ parameter */ + OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ + void *UpdateParam; /* stream update parameter */ + + UINT8 type; /* chip type */ + UINT8 address; /* address register */ + UINT8 status; /* status flag */ + UINT8 statusmask; /* status mask */ + UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ + + UINT32 clock; /* master clock (Hz) */ + UINT32 rate; /* sampling rate (Hz) */ + double freqbase; /* frequency base */ + double TimerBase; /* Timer base time (==sampling time)*/ + signed int phase_modulation; /* phase modulation input (SLOT 2) */ + signed int output[1]; +#if BUILD_Y8950 + INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ +#endif } FM_OPL; @@ -254,10 +268,10 @@ /* mapping of register number (offset) to slot number used by the emulator */ static const int slot_array[32]= { - 0, 2, 4, 1, 3, 5,-1,-1, - 6, 8,10, 7, 9,11,-1,-1, - 12,14,16,13,15,17,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1 + 0, 2, 4, 1, 3, 5,-1,-1, + 6, 8,10, 7, 9,11,-1,-1, + 12,14,16,13,15,17,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1 }; /* key scale level */ @@ -266,46 +280,46 @@ #define SC(x) ((UINT32)((x)/(0.1875/2.0))) static const UINT32 ksl_tab[8*16]= { - /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), - /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), - /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), - /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750),SC(10.125),SC(10.500), - SC(10.875),SC(11.250),SC(11.625),SC(12.000), - /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000),SC(10.125),SC(10.875),SC(11.625), - SC(12.000),SC(12.750),SC(13.125),SC(13.500), - SC(13.875),SC(14.250),SC(14.625),SC(15.000), - /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000),SC(10.875), - SC(12.000),SC(13.125),SC(13.875),SC(14.625), - SC(15.000),SC(15.750),SC(16.125),SC(16.500), - SC(16.875),SC(17.250),SC(17.625),SC(18.000), - /* OCT 7 */ - SC(0.000), SC(9.000),SC(12.000),SC(13.875), - SC(15.000),SC(16.125),SC(16.875),SC(17.625), - SC(18.000),SC(18.750),SC(19.125),SC(19.500), - SC(19.875),SC(20.250),SC(20.625),SC(21.000) + /* OCT 0 */ + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + /* OCT 1 */ + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(0.750), SC(1.125), SC(1.500), + SC(1.875), SC(2.250), SC(2.625), SC(3.000), + /* OCT 2 */ + SC(0.000), SC(0.000), SC(0.000), SC(0.000), + SC(0.000), SC(1.125), SC(1.875), SC(2.625), + SC(3.000), SC(3.750), SC(4.125), SC(4.500), + SC(4.875), SC(5.250), SC(5.625), SC(6.000), + /* OCT 3 */ + SC(0.000), SC(0.000), SC(0.000), SC(1.875), + SC(3.000), SC(4.125), SC(4.875), SC(5.625), + SC(6.000), SC(6.750), SC(7.125), SC(7.500), + SC(7.875), SC(8.250), SC(8.625), SC(9.000), + /* OCT 4 */ + SC(0.000), SC(0.000), SC(3.000), SC(4.875), + SC(6.000), SC(7.125), SC(7.875), SC(8.625), + SC(9.000), SC(9.750),SC(10.125),SC(10.500), + SC(10.875),SC(11.250),SC(11.625),SC(12.000), + /* OCT 5 */ + SC(0.000), SC(3.000), SC(6.000), SC(7.875), + SC(9.000),SC(10.125),SC(10.875),SC(11.625), + SC(12.000),SC(12.750),SC(13.125),SC(13.500), + SC(13.875),SC(14.250),SC(14.625),SC(15.000), + /* OCT 6 */ + SC(0.000), SC(6.000), SC(9.000),SC(10.875), + SC(12.000),SC(13.125),SC(13.875),SC(14.625), + SC(15.000),SC(15.750),SC(16.125),SC(16.500), + SC(16.875),SC(17.250),SC(17.625),SC(18.000), + /* OCT 7 */ + SC(0.000), SC(9.000),SC(12.000),SC(13.875), + SC(15.000),SC(16.125),SC(16.875),SC(17.625), + SC(18.000),SC(18.750),SC(19.125),SC(19.500), + SC(19.875),SC(20.250),SC(20.625),SC(21.000) }; #undef SC @@ -429,7 +443,7 @@ /* multiple table */ -#define SC(x) ((UINT32)((x)*2)) +#define SC(x) ((UINT8)((x)*2)) static const UINT8 mul_tab[16]= { /* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,12,12,15,15 */ SC(0.50), SC(1.00), SC(2.00), SC(3.00), SC(4.00), SC(5.00), SC(6.00), SC(7.00), @@ -457,12 +471,12 @@ Length: 210 elements. - Each of the elements has to be repeated - exactly 64 times (on 64 consecutive samples). - The whole table takes: 64 * 210 = 13440 samples. + Each of the elements has to be repeated + exactly 64 times (on 64 consecutive samples). + The whole table takes: 64 * 210 = 13440 samples. - When AM = 1 data is used directly - When AM = 0 data is divided by 4 before being used (loosing precision is important) + When AM = 1 data is used directly + When AM = 0 data is divided by 4 before being used (losing precision is important) */ #define LFO_AM_TAB_ELEMENTS 210 @@ -563,320 +577,313 @@ static int num_lock = 0; -static void *cur_chip = NULL; /* current chip pointer */ -static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2; - -static signed int phase_modulation; /* phase modulation input (SLOT 2) */ -static signed int output[1]; - -#if BUILD_Y8950 -static INT32 output_deltat[4]; /* for Y8950 DELTA-T, chip is mono, that 4 here is just for safety */ -#endif +#define SLOT7_1 (&OPL->P_CH[7].SLOT[SLOT1]) +#define SLOT7_2 (&OPL->P_CH[7].SLOT[SLOT2]) +#define SLOT8_1 (&OPL->P_CH[8].SLOT[SLOT1]) +#define SLOT8_2 (&OPL->P_CH[8].SLOT[SLOT2]) -static UINT32 LFO_AM; -static INT32 LFO_PM; INLINE int limit( int val, int max, int min ) { - if ( val > max ) - val = max; - else if ( val < min ) - val = min; + if ( val > max ) + val = max; + else if ( val < min ) + val = min; - return val; + return val; } /* status set and IRQ handling */ -/*INLINE*/static void OPL_STATUS_SET(FM_OPL *OPL,int flag) +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); - } - } + /* 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*/static void OPL_STATUS_RESET(FM_OPL *OPL,int flag) +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); - } - } + /* 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); + OPL->statusmask = flag; + /* IRQ handling check */ + OPL_STATUS_SET(OPL,0); + OPL_STATUS_RESET(OPL,0); } /* advance LFO to next sample */ INLINE void advance_lfo(FM_OPL *OPL) { - UINT8 tmp; + UINT8 tmp; - /* LFO */ - OPL->lfo_am_cnt += OPL->lfo_am_inc; - if (OPL->lfo_am_cnt >= (unsigned)(LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= (LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; - - if (OPL->lfo_am_depth) - LFO_AM = tmp; - else - LFO_AM = tmp>>2; + /* LFO */ + OPL->lfo_am_cnt += OPL->lfo_am_inc; + if (OPL->lfo_am_cnt >= ((UINT32)LFO_AM_TAB_ELEMENTS<lfo_am_cnt -= ((UINT32)LFO_AM_TAB_ELEMENTS<lfo_am_cnt >> LFO_SH ]; + + if (OPL->lfo_am_depth) + OPL->LFO_AM = tmp; + else + OPL->LFO_AM = tmp>>2; - OPL->lfo_pm_cnt += OPL->lfo_pm_inc; - LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; + OPL->lfo_pm_cnt += OPL->lfo_pm_inc; + OPL->LFO_PM = ((OPL->lfo_pm_cnt>>LFO_SH) & 7) | OPL->lfo_pm_depth_range; } /* advance to next sample */ INLINE void advance(FM_OPL *OPL) { - OPL_CH *CH; - OPL_SLOT *op; - int i; - - OPL->eg_timer += OPL->eg_timer_add; - - while (OPL->eg_timer >= OPL->eg_timer_overflow) - { - OPL->eg_timer -= OPL->eg_timer_overflow; - - OPL->eg_cnt++; - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Envelope Generator */ - switch(op->state) - { - case EG_ATT: /* attack phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) - { - op->volume += (~op->volume * - (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)]) - ) >>3; - - if (op->volume <= MIN_ATT_INDEX) - { - op->volume = MIN_ATT_INDEX; - op->state = EG_DEC; - } - - } - break; - - case EG_DEC: /* decay phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; - - if ( (unsigned)op->volume >= op->sl ) - op->state = EG_SUS; - - } - break; - - case EG_SUS: /* sustain phase */ - - /* this is important behaviour: - one can change percusive/non-percussive modes on the fly and - the chip will remain in sustain phase - verified on real YM3812 */ - - if(op->eg_type) /* non-percussive mode */ - { - /* do nothing */ - } - else /* percussive mode */ - { - /* during sustain phase chip adds Release Rate (in percussive mode) */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr - + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - op->volume = MAX_ATT_INDEX; - } - /* else do nothing in sustain phase */ - } - break; - - case EG_REL: /* release phase */ - if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) - { - op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; - - if ( op->volume >= MAX_ATT_INDEX ) - { - op->volume = MAX_ATT_INDEX; - op->state = EG_OFF; - } - - } - break; - - default: - break; - } - } - } - - for (i=0; i<9*2; i++) - { - CH = &OPL->P_CH[i/2]; - op = &CH->SLOT[i&1]; - - /* Phase Generator */ - if(op->vib) - { - UINT8 block; - unsigned int block_fnum = CH->block_fnum; - - unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; - - signed int lfo_fn_table_index_offset = lfo_pm_table[LFO_PM + 16*fnum_lfo ]; - - if (lfo_fn_table_index_offset) /* LFO phase modulation active */ - { - block_fnum += lfo_fn_table_index_offset; - block = (block_fnum&0x1c00) >> 10; - op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; - } - else /* LFO phase modulation = zero */ - { - op->Cnt += op->Incr; - } - } - else /* LFO phase modulation disabled for this operator */ - { - op->Cnt += op->Incr; - } - } - - /* The Noise Generator of the YM3812 is 23-bit shift register. - * Period is equal to 2^23-2 samples. - * Register works at sampling frequency of the chip, so output - * can change on every sample. - * - * Output of the register and input to the bit 22 is: - * bit0 XOR bit14 XOR bit15 XOR bit22 - * - * Simply use bit 22 as the noise output. - */ - - OPL->noise_p += OPL->noise_f; - i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ - OPL->noise_p &= FREQ_MASK; - while (i) - { - /* - UINT32 j; - j = ((OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22)) & 1; - OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); - */ - - /* - Instead of doing all the logic operations above, we - use a trick here (and use bit 0 as the noise output). - The difference is only that the noise bit changes one - step ahead. This doesn't matter since we don't know - what is real state of the noise_rng after the reset. - */ + OPL_CH *CH; + OPL_SLOT *op; + int i; + + OPL->eg_timer += OPL->eg_timer_add; + + while (OPL->eg_timer >= OPL->eg_timer_overflow) + { + OPL->eg_timer -= OPL->eg_timer_overflow; + + OPL->eg_cnt++; + + for (i=0; i<9*2; i++) + { + CH = &OPL->P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Envelope Generator */ + switch(op->state) + { + case EG_ATT: /* attack phase */ + if ( !(OPL->eg_cnt & ((1<eg_sh_ar)-1) ) ) + { + op->volume += (~op->volume * + (eg_inc[op->eg_sel_ar + ((OPL->eg_cnt>>op->eg_sh_ar)&7)]) + ) >>3; + + if (op->volume <= MIN_ATT_INDEX) + { + op->volume = MIN_ATT_INDEX; + op->state = EG_DEC; + } + + } + break; + + case EG_DEC: /* decay phase */ + if ( !(OPL->eg_cnt & ((1<eg_sh_dr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_dr + ((OPL->eg_cnt>>op->eg_sh_dr)&7)]; + + if ( (unsigned int) op->volume >= op->sl ) + op->state = EG_SUS; + + } + break; + + case EG_SUS: /* sustain phase */ + + /* this is important behaviour: + one can change percusive/non-percussive modes on the fly and + the chip will remain in sustain phase - verified on real YM3812 */ + + if(op->eg_type) /* non-percussive mode */ + { + /* do nothing */ + } + else /* percussive mode */ + { + /* during sustain phase chip adds Release Rate (in percussive mode) */ + if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + op->volume = MAX_ATT_INDEX; + } + /* else do nothing in sustain phase */ + } + break; + + case EG_REL: /* release phase */ + if ( !(OPL->eg_cnt & ((1<eg_sh_rr)-1) ) ) + { + op->volume += eg_inc[op->eg_sel_rr + ((OPL->eg_cnt>>op->eg_sh_rr)&7)]; + + if ( op->volume >= MAX_ATT_INDEX ) + { + op->volume = MAX_ATT_INDEX; + op->state = EG_OFF; + } + + } + break; + + default: + break; + } + } + } + + for (i=0; i<9*2; i++) + { + CH = &OPL->P_CH[i/2]; + op = &CH->SLOT[i&1]; + + /* Phase Generator */ + if(op->vib) + { + UINT8 block; + UINT32 block_fnum = CH->block_fnum; + + unsigned int fnum_lfo = (block_fnum&0x0380) >> 7; + + signed int lfo_fn_table_index_offset = lfo_pm_table[OPL->LFO_PM + 16*fnum_lfo ]; + + if (lfo_fn_table_index_offset) /* LFO phase modulation active */ + { + block_fnum += lfo_fn_table_index_offset; + block = (block_fnum&0x1c00) >> 10; + op->Cnt += (OPL->fn_tab[block_fnum&0x03ff] >> (7-block)) * op->mul; + } + else /* LFO phase modulation = zero */ + { + op->Cnt += op->Incr; + } + } + else /* LFO phase modulation disabled for this operator */ + { + op->Cnt += op->Incr; + } + } + + /* The Noise Generator of the YM3812 is 23-bit shift register. + * Period is equal to 2^23-2 samples. + * Register works at sampling frequency of the chip, so output + * can change on every sample. + * + * Output of the register and input to the bit 22 is: + * bit0 XOR bit14 XOR bit15 XOR bit22 + * + * Simply use bit 22 as the noise output. + */ + + OPL->noise_p += OPL->noise_f; + i = OPL->noise_p >> FREQ_SH; /* number of events (shifts of the shift register) */ + OPL->noise_p &= FREQ_MASK; + while (i) + { + /* + UINT32 j; + j = ((OPL->noise_rng) ^ (OPL->noise_rng>>14) ^ (OPL->noise_rng>>15) ^ (OPL->noise_rng>>22)) & 1; + OPL->noise_rng = (j<<22) | (OPL->noise_rng>>1); + */ + + /* + Instead of doing all the logic operations above, we + use a trick here (and use bit 0 as the noise output). + The difference is only that the noise bit changes one + step ahead. This doesn't matter since we don't know + what is real state of the noise_rng after the reset. + */ - if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302; - OPL->noise_rng >>= 1; + if (OPL->noise_rng & 1) OPL->noise_rng ^= 0x800302; + OPL->noise_rng >>= 1; - i--; - } + i--; + } } INLINE signed int op_calc(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) { - UINT32 p; + UINT32 p; - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm << 16))) - >> FREQ_SH) & SIN_MASK)]; + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + (pm << 16))) + >> FREQ_SH) & SIN_MASK)]; - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; } INLINE signed int op_calc1(UINT32 phase, unsigned int env, signed int pm, unsigned int wave_tab) { - UINT32 p; + UINT32 p; - p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm)) - >> FREQ_SH) & SIN_MASK)]; + p = (env<<4) + sin_tab[wave_tab + ((((signed int)((phase & ~FREQ_MASK) + pm)) + >> FREQ_SH) & SIN_MASK)]; - if (p >= TL_TAB_LEN) - return 0; - return tl_tab[p]; + if (p >= TL_TAB_LEN) + return 0; + return tl_tab[p]; } -#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (LFO_AM & (OP)->AMmask)) +#define volume_calc(OP) ((OP)->TLL + ((UINT32)(OP)->volume) + (OPL->LFO_AM & (OP)->AMmask)) /* calculate output */ -INLINE void OPL_CALC_CH( OPL_CH *CH ) +INLINE void OPL_CALC_CH( FM_OPL *OPL, OPL_CH *CH ) { - OPL_SLOT *SLOT; - unsigned int env; - signed int out; - - phase_modulation = 0; - - /* SLOT 1 */ - SLOT = &CH->SLOT[SLOT1]; - env = volume_calc(SLOT); - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - *SLOT->connect1 += SLOT->op1_out[0]; - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable); + OPL_SLOT *SLOT; + unsigned int env; + signed int out; + + OPL->phase_modulation = 0; + + /* SLOT 1 */ + SLOT = &CH->SLOT[SLOT1]; + env = volume_calc(SLOT); + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + *SLOT->connect1 += SLOT->op1_out[0]; + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable); } /* - operators used in the rhythm sounds generation process: + operators used in the rhythm sounds generation process: - Envelope Generator: + Envelope Generator: channel operator register number Bass High Snare Tom Top / slot number TL ARDR SLRR Wave Drum Hat Drum Tom Cymbal @@ -887,7 +894,7 @@ 8 / 0 14 52 72 92 f2 + 8 / 1 17 55 75 95 f5 + - Phase Generator: + Phase Generator: channel operator register number Bass High Snare Tom Top / slot number MULTIPLE Drum Hat Drum Tom Cymbal @@ -910,170 +917,170 @@ /* calculate rhythm */ -INLINE void OPL_CALC_RH( OPL_CH *CH, unsigned int noise ) +INLINE void OPL_CALC_RH( FM_OPL *OPL, OPL_CH *CH, unsigned int noise ) { - OPL_SLOT *SLOT; - signed int out; - unsigned int env; - - - /* Bass Drum (verified on real YM3812): - - depends on the channel 6 'connect' register: - when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) - when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored - - output sample always is multiplied by 2 - */ - - phase_modulation = 0; - /* SLOT 1 */ - SLOT = &CH[6].SLOT[SLOT1]; - env = volume_calc(SLOT); - - out = SLOT->op1_out[0] + SLOT->op1_out[1]; - SLOT->op1_out[0] = SLOT->op1_out[1]; - - if (!SLOT->CON) - phase_modulation = SLOT->op1_out[0]; - /* else ignore output of operator 1 */ - - SLOT->op1_out[1] = 0; - if( env < ENV_QUIET ) - { - if (!SLOT->FB) - out = 0; - SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); - } - - /* SLOT 2 */ - SLOT++; - env = volume_calc(SLOT); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT->Cnt, env, phase_modulation, SLOT->wavetable) * 2; - - - /* Phase generation is based on: */ - /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 - (same combination as TOP CYMBAL but different output phases) */ - /* SD (16) channel 7->slot 1 */ - /* TOM (14) channel 8->slot 1 */ - /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 - (same combination as HIGH HAT but different output phases) */ - - /* Envelope generation based on: */ - /* HH channel 7->slot1 */ - /* SD channel 7->slot2 */ - /* TOM channel 8->slot1 */ - /* TOP channel 8->slot2 */ - - - /* The following formulas can be well optimized. - I leave them in direct form for now (in case I've missed something). - */ - - /* High Hat (verified on real YM3812) */ - env = volume_calc(SLOT7_1); - if( env < ENV_QUIET ) - { - - /* high hat phase generation: - phase = d0 or 234 (based on frequency only) - phase = 34 or 2d0 (based on noise) - */ - - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0xd0; */ - /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ - UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ - if (res2) - phase = (0x200|(0xd0>>2)); - - - /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ - /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ - if (phase&0x200) - { - if (noise) - phase = 0x200|0xd0; - } - else - /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ - /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ - { - if (noise) - phase = 0xd0>>2; - } - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Snare Drum (verified on real YM3812) */ - env = volume_calc(SLOT7_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; - - /* when bit8 = 0 phase = 0x100; */ - /* when bit8 = 1 phase = 0x200; */ - UINT32 phase = bit8 ? 0x200 : 0x100; - - /* Noise bit XOR'es phase by 0x100 */ - /* when noisebit = 0 pass the phase from calculation above */ - /* when noisebit = 1 phase ^= 0x100; */ - /* in other words: phase ^= (noisebit<<8); */ - if (noise) - phase ^= 0x100; - - output[0] += op_calc(phase<wavetable) * 2; - } - - /* Tom Tom (verified on real YM3812) */ - env = volume_calc(SLOT8_1); - if( env < ENV_QUIET ) - output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; - - /* Top Cymbal (verified on real YM3812) */ - env = volume_calc(SLOT8_2); - if( env < ENV_QUIET ) - { - /* base frequency derived from operator 1 in channel 7 */ - unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; - unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; - unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; - - unsigned char res1 = (bit2 ^ bit7) | bit3; - - /* when res1 = 0 phase = 0x000 | 0x100; */ - /* when res1 = 1 phase = 0x200 | 0x100; */ - UINT32 phase = res1 ? 0x300 : 0x100; - - /* enable gate based on frequency of operator 2 in channel 8 */ - unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; - unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; - - unsigned char res2 = (bit3e ^ bit5e); - /* when res2 = 0 pass the phase from calculation above (res1); */ - /* when res2 = 1 phase = 0x200 | 0x100; */ - if (res2) - phase = 0x300; + OPL_SLOT *SLOT; + signed int out; + unsigned int env; + + + /* Bass Drum (verified on real YM3812): + - depends on the channel 6 'connect' register: + when connect = 0 it works the same as in normal (non-rhythm) mode (op1->op2->out) + when connect = 1 _only_ operator 2 is present on output (op2->out), operator 1 is ignored + - output sample always is multiplied by 2 + */ + + OPL->phase_modulation = 0; + /* SLOT 1 */ + SLOT = &CH[6].SLOT[SLOT1]; + env = volume_calc(SLOT); + + out = SLOT->op1_out[0] + SLOT->op1_out[1]; + SLOT->op1_out[0] = SLOT->op1_out[1]; + + if (!SLOT->CON) + OPL->phase_modulation = SLOT->op1_out[0]; + /* else ignore output of operator 1 */ + + SLOT->op1_out[1] = 0; + if( env < ENV_QUIET ) + { + if (!SLOT->FB) + out = 0; + SLOT->op1_out[1] = op_calc1(SLOT->Cnt, env, (out<FB), SLOT->wavetable ); + } + + /* SLOT 2 */ + SLOT++; + env = volume_calc(SLOT); + if( env < ENV_QUIET ) + OPL->output[0] += op_calc(SLOT->Cnt, env, OPL->phase_modulation, SLOT->wavetable) * 2; + + + /* Phase generation is based on: */ + /* HH (13) channel 7->slot 1 combined with channel 8->slot 2 + (same combination as TOP CYMBAL but different output phases) */ + /* SD (16) channel 7->slot 1 */ + /* TOM (14) channel 8->slot 1 */ + /* TOP (17) channel 7->slot 1 combined with channel 8->slot 2 + (same combination as HIGH HAT but different output phases) */ + + /* Envelope generation based on: */ + /* HH channel 7->slot1 */ + /* SD channel 7->slot2 */ + /* TOM channel 8->slot1 */ + /* TOP channel 8->slot2 */ + + + /* The following formulas can be well optimized. + I leave them in direct form for now (in case I've missed something). + */ + + /* High Hat (verified on real YM3812) */ + env = volume_calc(SLOT7_1); + if( env < ENV_QUIET ) + { + + /* high hat phase generation: + phase = d0 or 234 (based on frequency only) + phase = 34 or 2d0 (based on noise) + */ + + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0xd0; */ + /* when res1 = 1 phase = 0x200 | (0xd0>>2); */ + UINT32 phase = res1 ? (0x200|(0xd0>>2)) : 0xd0; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | (0xd0>>2); */ + if (res2) + phase = (0x200|(0xd0>>2)); + + + /* when phase & 0x200 is set and noise=1 then phase = 0x200|0xd0 */ + /* when phase & 0x200 is set and noise=0 then phase = 0x200|(0xd0>>2), ie no change */ + if (phase&0x200) + { + if (noise) + phase = 0x200|0xd0; + } + else + /* when phase & 0x200 is clear and noise=1 then phase = 0xd0>>2 */ + /* when phase & 0x200 is clear and noise=0 then phase = 0xd0, ie no change */ + { + if (noise) + phase = 0xd0>>2; + } + + OPL->output[0] += op_calc(phase<wavetable) * 2; + } + + /* Snare Drum (verified on real YM3812) */ + env = volume_calc(SLOT7_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit8 = ((SLOT7_1->Cnt>>FREQ_SH)>>8)&1; + + /* when bit8 = 0 phase = 0x100; */ + /* when bit8 = 1 phase = 0x200; */ + UINT32 phase = bit8 ? 0x200 : 0x100; + + /* Noise bit XOR'es phase by 0x100 */ + /* when noisebit = 0 pass the phase from calculation above */ + /* when noisebit = 1 phase ^= 0x100; */ + /* in other words: phase ^= (noisebit<<8); */ + if (noise) + phase ^= 0x100; + + OPL->output[0] += op_calc(phase<wavetable) * 2; + } + + /* Tom Tom (verified on real YM3812) */ + env = volume_calc(SLOT8_1); + if( env < ENV_QUIET ) + OPL->output[0] += op_calc(SLOT8_1->Cnt, env, 0, SLOT8_1->wavetable) * 2; + + /* Top Cymbal (verified on real YM3812) */ + env = volume_calc(SLOT8_2); + if( env < ENV_QUIET ) + { + /* base frequency derived from operator 1 in channel 7 */ + unsigned char bit7 = ((SLOT7_1->Cnt>>FREQ_SH)>>7)&1; + unsigned char bit3 = ((SLOT7_1->Cnt>>FREQ_SH)>>3)&1; + unsigned char bit2 = ((SLOT7_1->Cnt>>FREQ_SH)>>2)&1; + + unsigned char res1 = (bit2 ^ bit7) | bit3; + + /* when res1 = 0 phase = 0x000 | 0x100; */ + /* when res1 = 1 phase = 0x200 | 0x100; */ + UINT32 phase = res1 ? 0x300 : 0x100; + + /* enable gate based on frequency of operator 2 in channel 8 */ + unsigned char bit5e= ((SLOT8_2->Cnt>>FREQ_SH)>>5)&1; + unsigned char bit3e= ((SLOT8_2->Cnt>>FREQ_SH)>>3)&1; + + unsigned char res2 = (bit3e ^ bit5e); + /* when res2 = 0 pass the phase from calculation above (res1); */ + /* when res2 = 1 phase = 0x200 | 0x100; */ + if (res2) + phase = 0x300; - output[0] += op_calc(phase<wavetable) * 2; - } + OPL->output[0] += op_calc(phase<wavetable) * 2; + } } @@ -1081,108 +1088,108 @@ /* generic table initialize */ static int init_tables(void) { - signed int i,x; - signed int n; - double o,m; - - - for (x=0; x>= 4; /* 12 bits here */ - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - /* 11 bits here (rounded) */ - n <<= 1; /* 12 bits here (as in real chip) */ - tl_tab[ x*2 + 0 ] = n; - tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; - - for (i=1; i<12; i++) - { - tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; - tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; - } - #if 0 - logerror("tl %04i", x*2); - for (i=0; i<12; i++) - logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); - logerror("\n"); - #endif - } - /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ - - - for (i=0; i0.0) - o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ - else - o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ - - o = o / (ENV_STEP/4); - - n = (int)(2.0*o); - if (n&1) /* round to nearest */ - n = (n>>1)+1; - else - n = n>>1; - - sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); - - /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, - sin_tab[i], tl_tab[sin_tab[i]] );*/ - } - - for (i=0; i>1) ]; - - /* waveform 3: _ _ _ _ */ - /* / |_/ |_/ |_/ |_*/ - /* abs(output only first quarter of the sinus waveform) */ - - if (i & (1<<(SIN_BITS-2)) ) - sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; - else - sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; - - /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, - sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); - logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, - sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); - logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, - sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ - } - /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ + signed int i,x; + signed int n; + double o,m; + + + for (x=0; x>= 4; /* 12 bits here */ + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + /* 11 bits here (rounded) */ + n <<= 1; /* 12 bits here (as in real chip) */ + tl_tab[ x*2 + 0 ] = n; + tl_tab[ x*2 + 1 ] = -tl_tab[ x*2 + 0 ]; + + for (i=1; i<12; i++) + { + tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; + tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 + i*2*TL_RES_LEN ]; + } + #if 0 + logerror("tl %04i", x*2); + for (i=0; i<12; i++) + logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] ); + logerror("\n"); + #endif + } + /*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/ + + + for (i=0; i0.0) + o = 8*log(1.0/m)/log(2.0); /* convert to 'decibels' */ + else + o = 8*log(-1.0/m)/log(2.0); /* convert to 'decibels' */ + + o = o / (ENV_STEP/4); + + n = (int)(2.0*o); + if (n&1) /* round to nearest */ + n = (n>>1)+1; + else + n = n>>1; + + sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); + + /*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, + sin_tab[i], tl_tab[sin_tab[i]] );*/ + } + + for (i=0; i>1) ]; + + /* waveform 3: _ _ _ _ */ + /* / |_/ |_/ |_/ |_*/ + /* abs(output only first quarter of the sinus waveform) */ + + if (i & (1<<(SIN_BITS-2)) ) + sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; + else + sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; + + /*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, + sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] ); + logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, + sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] ); + logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, + sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/ + } + /*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/ - return 1; + return 1; } static void OPLCloseTable( void ) @@ -1193,741 +1200,788 @@ static void OPL_initalize(FM_OPL *OPL) { - int i; + int i; - /* frequency base */ - OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; + /* frequency base */ + OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0; #if 0 - OPL->rate = (double)OPL->clock / 72.0; - OPL->freqbase = 1.0; + OPL->rate = (double)OPL->clock / 72.0; + OPL->freqbase = 1.0; #endif - /*logerror("freqbase=%f\n", OPL->freqbase);*/ + /*logerror("freqbase=%f\n", OPL->freqbase);*/ - /* Timer base time */ - OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 ); + /* Timer base time */ + OPL->TimerBase = 72.0 / (double)OPL->clock; - /* make fnumber -> increment counter table */ - for( i=0 ; i < 1024 ; i++ ) - { - /* opn phase increment counter = 20bit */ - /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ - OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); + /* make fnumber -> increment counter table */ + for( i=0 ; i < 1024 ; i++ ) + { + /* opn phase increment counter = 20bit */ + /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ + OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); #if 0 - logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", - i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 ); + logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n", + i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 ); #endif - } + } #if 0 - for( i=0 ; i < 16 ; i++ ) - { - logerror("FMOPL.C: sl_tab[%i] = %08x\n", - i, sl_tab[i] ); - } - for( i=0 ; i < 8 ; i++ ) - { - int j; - logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); - for (j=0; j<16; j++) - { - logerror("%08x ", ksl_tab[i*16+j] ); - } - logerror("\n"); - } + for( i=0 ; i < 16 ; i++ ) + { + logerror("FMOPL.C: sl_tab[%i] = %08x\n", + i, sl_tab[i] ); + } + for( i=0 ; i < 8 ; i++ ) + { + int j; + logerror("FMOPL.C: ksl_tab[oct=%2i] =",i); + for (j=0; j<16; j++) + { + logerror("%08x ", ksl_tab[i*16+j] ); + } + logerror("\n"); + } #endif - /* Amplitude modulation: 27 output levels (triangle waveform); - 1 level takes one of: 192, 256 or 448 samples */ - /* One entry from LFO_AM_TABLE lasts for 64 samples */ - OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); - - /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ - OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); - - /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ - - /* Noise generator: a step takes 1 sample */ - OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); - - OPL->eg_timer_add = (UINT32)((1<freqbase); - OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ + /* Amplitude modulation: 27 output levels (triangle waveform); + 1 level takes one of: 192, 256 or 448 samples */ + /* One entry from LFO_AM_TABLE lasts for 64 samples */ + OPL->lfo_am_inc = (UINT32)((1.0 / 64.0 ) * (1<freqbase); + + /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ + OPL->lfo_pm_inc = (UINT32)((1.0 / 1024.0) * (1<freqbase); + + /*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ + + /* Noise generator: a step takes 1 sample */ + OPL->noise_f = (UINT32)((1.0 / 1.0) * (1<freqbase); + + OPL->eg_timer_add = (UINT32)((1<freqbase); + OPL->eg_timer_overflow = ( 1 ) * (1<eg_timer_add, OPL->eg_timer_overflow);*/ } INLINE void FM_KEYON(OPL_SLOT *SLOT, UINT32 key_set) { - if( !SLOT->key ) - { - /* restart Phase Generator */ - SLOT->Cnt = 0; - /* phase -> Attack */ - SLOT->state = EG_ATT; - } - SLOT->key |= key_set; + if( !SLOT->key ) + { + /* restart Phase Generator */ + SLOT->Cnt = 0; + /* phase -> Attack */ + SLOT->state = EG_ATT; + } + SLOT->key |= key_set; } INLINE void FM_KEYOFF(OPL_SLOT *SLOT, UINT32 key_clr) { - if( SLOT->key ) - { - SLOT->key &= key_clr; - - if( !SLOT->key ) - { - /* phase -> Release */ - if (SLOT->state>EG_REL) - SLOT->state = EG_REL; - } - } + if( SLOT->key ) + { + SLOT->key &= key_clr; + + if( !SLOT->key ) + { + /* phase -> Release */ + if (SLOT->state>EG_REL) + SLOT->state = EG_REL; + } + } } /* update phase increment counter of operator (also update the EG rates if necessary) */ -/*INLINE*/static void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) +INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) { - int ksr; + int ksr; - /* (frequency) phase increment counter */ - SLOT->Incr = CH->fc * SLOT->mul; - ksr = CH->kcode >> SLOT->KSR; - - if( SLOT->ksr != ksr ) - { - SLOT->ksr = ksr; - - /* calculate envelope generator rates */ - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; - } + /* (frequency) phase increment counter */ + SLOT->Incr = CH->fc * SLOT->mul; + ksr = CH->kcode >> SLOT->KSR; + + if( SLOT->ksr != ksr ) + { + SLOT->ksr = ksr; + + /* calculate envelope generator rates */ + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + } } /* 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]; + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - SLOT->mul = mul_tab[v&0x0f]; - SLOT->KSR = (v&0x10) ? 0 : 2; - SLOT->eg_type = (v&0x20); - SLOT->vib = (v&0x40); - SLOT->AMmask = (v&0x80) ? ~0 : 0; - CALC_FCSLOT(CH,SLOT); + SLOT->mul = mul_tab[v&0x0f]; + SLOT->KSR = (v&0x10) ? 0 : 2; + SLOT->eg_type = (v&0x20); + SLOT->vib = (v&0x40); + SLOT->AMmask = (v&0x80) ? ~0 : 0; + 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.0 / 6.0 dB/OCT */ + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; + int ksl = v>>6; /* 0 / 1.5 / 3.0 / 6.0 dB/OCT */ - SLOT->ksl = ksl ? 3-ksl : 31; - SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ + SLOT->ksl = ksl ? 3-ksl : 31; + SLOT->TL = (v&0x3f)<<(ENV_BITS-1-7); /* 7 bits TL (bit 6 = always 0) */ - SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); + 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]; + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; + SLOT->ar = (v>>4) ? 16 + ((v>>4) <<2) : 0; - if ((SLOT->ar + SLOT->ksr) < 16+62) - { - SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; - SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; - } - else - { - SLOT->eg_sh_ar = 0; - SLOT->eg_sel_ar = 13*RATE_STEPS; - } - - SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; - SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + + SLOT->dr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; } /* 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]; + OPL_CH *CH = &OPL->P_CH[slot/2]; + OPL_SLOT *SLOT = &CH->SLOT[slot&1]; - SLOT->sl = sl_tab[ v>>4 ]; + SLOT->sl = sl_tab[ v>>4 ]; - SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; - SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; - SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + SLOT->rr = (v&0x0f)? 16 + ((v&0x0f)<<2) : 0; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; } /* write a value v to register r on OPL chip */ static void OPLWriteReg(FM_OPL *OPL, int r, int v) { - OPL_CH *CH; - int slot; - unsigned int block_fnum; - - - /* adjust bus to 8 bits */ - r &= 0xff; - v &= 0xff; - - switch(r&0xe0) - { - case 0x00: /* 00-1f:control */ - switch(r&0x1f) - { - case 0x01: /* waveform select enable */ - if(OPL->type&OPL_TYPE_WAVESEL) - { - OPL->wavesel = v&0x20; - /* do not change the waveform previously selected */ - } - break; - case 0x02: /* Timer 1 */ - OPL->T[0] = (256-v)*4; - break; - case 0x03: /* Timer 2 */ - OPL->T[1] = (256-v)*16; - break; - 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*/ - OPL->st[0] = v&1; - OPL->st[1] = (v>>1)&1; - - /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ - OPL_STATUS_RESET(OPL, v & 0x78 ); - OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); - - /* timer 1 */ - if(OPL->st[0]) - { - OPL->TC[0]=OPL->T[0]*20; - double interval = (double)OPL->T[0]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); - } - /* timer 2 */ - if(OPL->st[1]) - { - OPL->TC[1]=OPL->T[1]*20; - double interval =(double)OPL->T[1]*OPL->TimerBase; - if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); - } - } - break; + OPL_CH *CH; + int slot; + UINT32 block_fnum; + + + /* adjust bus to 8 bits */ + r &= 0xff; + v &= 0xff; + + switch(r&0xe0) + { + case 0x00: /* 00-1f:control */ + switch(r&0x1f) + { + case 0x01: /* waveform select enable */ + if(OPL->type&OPL_TYPE_WAVESEL) + { + OPL->wavesel = v&0x20; + /* do not change the waveform previously selected */ + } + break; + case 0x02: /* Timer 1 */ + OPL->T[0] = (256-v)*4; + break; + case 0x03: /* Timer 2 */ + OPL->T[1] = (256-v)*16; + break; + case 0x04: /* IRQ clear / mask and Timer enable */ + if(v&0x80) + { /* IRQ flag clear */ + /* don't reset BFRDY flag or we will have to call deltat module to set the flag */ + OPL_STATUS_RESET(OPL,0x7f-0x08); + } + 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-0x08) ); + OPL_STATUSMASK_SET(OPL, (~v) & 0x78 ); + + /* timer 2 */ + if(OPL->st[1] != st2) + { + double period = st2 ? (OPL->TimerBase * OPL->T[1]) : 0.0; + OPL->st[1] = st2; + if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,1,period); + } + /* timer 1 */ + if(OPL->st[0] != st1) + { + double period = st1 ? (OPL->TimerBase * OPL->T[0]) : 0.0; + OPL->st[0] = st1; + if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,0,period); + } + } + break; #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 - logerror("Y8950: write unmapped KEYBOARD port\n"); - } - break; - case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; + case 0x06: /* Key Board OUT */ + if(OPL->type&OPL_TYPE_KEYBOARD) + { + if(OPL->keyboardhandler_w) + OPL->keyboardhandler_w(OPL->keyboard_param,v); + else + logerror("Y8950: write unmapped KEYBOARD port\n"); + } + break; + case 0x07: /* DELTA-T control 1 : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ + if(OPL->type&OPL_TYPE_ADPCM) + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); + break; #endif - case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ - OPL->mode = v; + case 0x08: /* MODE,DELTA-T control 2 : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ + OPL->mode = v; #if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) { - /* mask 4 LSBs in register 08 for DELTA-T unit */ - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); - } + if(OPL->type&OPL_TYPE_ADPCM) { + /* mask 4 LSBs in register 08 for DELTA-T unit */ + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v&0x0f); + } #endif - break; + break; #if BUILD_Y8950 - case 0x09: /* START ADD */ - case 0x0a: - case 0x0b: /* STOP ADD */ - case 0x0c: - case 0x0d: /* PRESCALE */ - case 0x0e: - case 0x0f: /* ADPCM data write */ - case 0x10: /* DELTA-N */ - case 0x11: /* DELTA-N */ - case 0x12: /* ADPCM volume */ - if(OPL->type&OPL_TYPE_ADPCM) - YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); - break; - - case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ - case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ - case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ - logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n", - r,v); - break; - - case 0x18: /* I/O CTRL (Direction) */ - if(OPL->type&OPL_TYPE_IO) - OPL->portDirection = v&0x0f; - break; - 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); - } - break; + case 0x09: /* START ADD */ + case 0x0a: + case 0x0b: /* STOP ADD */ + case 0x0c: + case 0x0d: /* PRESCALE */ + case 0x0e: + case 0x0f: /* ADPCM data write */ + case 0x10: /* DELTA-N */ + case 0x11: /* DELTA-N */ + case 0x12: /* ADPCM volume */ + if(OPL->type&OPL_TYPE_ADPCM) + YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); + break; + + case 0x15: /* DAC data high 8 bits (F7,F6...F2) */ + case 0x16: /* DAC data low 2 bits (F1, F0 in bits 7,6) */ + case 0x17: /* DAC data shift (S2,S1,S0 in bits 2,1,0) */ + logerror("FMOPL.C: DAC data register written, but not implemented reg=%02x val=%02x\n", + r,v); + break; + + case 0x18: /* I/O CTRL (Direction) */ + if(OPL->type&OPL_TYPE_IO) + OPL->portDirection = v&0x0f; + break; + 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); + } + break; #endif - default: - logerror("FMOPL.C: write to unknown register: %02x\n",r); - break; - } - break; - case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_mul(OPL,slot,v); - break; - case 0x40: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ksl_tl(OPL,slot,v); - break; - case 0x60: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_ar_dr(OPL,slot,v); - break; - case 0x80: - slot = slot_array[r&0x1f]; - if(slot < 0) return; - set_sl_rr(OPL,slot,v); - break; - case 0xa0: - if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ - { - OPL->lfo_am_depth = v & 0x80; - OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; - - OPL->rhythm = v&0x3f; - - if(OPL->rhythm&0x20) - { - /* BD key on/off */ - if(v&0x10) - { - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2); - FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2); - } - else - { - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - } - /* HH key on/off */ - if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key on/off */ - if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key on/off */ - if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY key on/off */ - if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2); - else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - else - { - /* BD key off */ - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); - FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); - /* HH key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); - /* SD key off */ - FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); - /* TOM key off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); - /* TOP-CY off */ - FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); - } - 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 */ - block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); - - if(v&0x20) - { - FM_KEYON (&CH->SLOT[SLOT1], 1); - FM_KEYON (&CH->SLOT[SLOT2], 1); - } - else - { - FM_KEYOFF(&CH->SLOT[SLOT1],~1); - FM_KEYOFF(&CH->SLOT[SLOT2],~1); - } - } - /* update */ - if(CH->block_fnum != block_fnum) - { - UINT8 block = block_fnum >> 10; - - CH->block_fnum = block_fnum; - - CH->ksl_base = ksl_tab[block_fnum>>6]; - CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block); - - /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ - CH->kcode = (CH->block_fnum&0x1c00)>>9; - - /* the info below is actually opposite to what is stated in the Manuals - (verifed on real YM3812) */ - /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ - /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ - if (OPL->mode&0x40) - CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ - else - CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ - - /* refresh Total Level in both SLOTs of this channel */ - CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); - CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); - - /* refresh frequency counter in both SLOTs of this channel */ - CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); - CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); - } - break; - case 0xc0: - /* FB,C */ - if( (r&0x0f) > 8) return; - CH = &OPL->P_CH[r&0x0f]; - CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; - CH->SLOT[SLOT1].CON = v&1; - CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &output[0] : &phase_modulation; - break; - case 0xe0: /* waveform select */ - /* simply ignore write to the waveform select register - if selecting not enabled in test register */ - if(OPL->wavesel) - { - slot = slot_array[r&0x1f]; - if(slot < 0) return; - CH = &OPL->P_CH[slot/2]; - - CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; - } - break; - } + default: + /*logerror("FMOPL.C: write to unknown register: %02x\n",r);*/ + break; + } + break; + case 0x20: /* am ON, vib ON, ksr, eg_type, mul */ + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_mul(OPL,slot,v); + break; + case 0x40: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ksl_tl(OPL,slot,v); + break; + case 0x60: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_ar_dr(OPL,slot,v); + break; + case 0x80: + slot = slot_array[r&0x1f]; + if(slot < 0) return; + set_sl_rr(OPL,slot,v); + break; + case 0xa0: + if (r == 0xbd) /* am depth, vibrato depth, r,bd,sd,tom,tc,hh */ + { + OPL->lfo_am_depth = v & 0x80; + OPL->lfo_pm_depth_range = (v&0x40) ? 8 : 0; + + OPL->rhythm = v&0x3f; + + if(OPL->rhythm&0x20) + { + /* BD key on/off */ + if(v&0x10) + { + FM_KEYON (&OPL->P_CH[6].SLOT[SLOT1], 2); + FM_KEYON (&OPL->P_CH[6].SLOT[SLOT2], 2); + } + else + { + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); + } + /* HH key on/off */ + if(v&0x01) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT1], 2); + else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); + /* SD key on/off */ + if(v&0x08) FM_KEYON (&OPL->P_CH[7].SLOT[SLOT2], 2); + else FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); + /* TOM key on/off */ + if(v&0x04) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT1], 2); + else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY key on/off */ + if(v&0x02) FM_KEYON (&OPL->P_CH[8].SLOT[SLOT2], 2); + else FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); + } + else + { + /* BD key off */ + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1],~2); + FM_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2],~2); + /* HH key off */ + FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1],~2); + /* SD key off */ + FM_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2],~2); + /* TOM key off */ + FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1],~2); + /* TOP-CY off */ + FM_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2],~2); + } + 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 */ + block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); + + if(v&0x20) + { + FM_KEYON (&CH->SLOT[SLOT1], 1); + FM_KEYON (&CH->SLOT[SLOT2], 1); + } + else + { + FM_KEYOFF(&CH->SLOT[SLOT1],~1); + FM_KEYOFF(&CH->SLOT[SLOT2],~1); + } + } + /* update */ + if(CH->block_fnum != block_fnum) + { + UINT8 block = block_fnum >> 10; + + CH->block_fnum = block_fnum; + + CH->ksl_base = ksl_tab[block_fnum>>6]; + CH->fc = OPL->fn_tab[block_fnum&0x03ff] >> (7-block); + + /* BLK 2,1,0 bits -> bits 3,2,1 of kcode */ + CH->kcode = (CH->block_fnum&0x1c00)>>9; + + /* the info below is actually opposite to what is stated in the Manuals + (verifed on real YM3812) */ + /* if notesel == 0 -> lsb of kcode is bit 10 (MSB) of fnum */ + /* if notesel == 1 -> lsb of kcode is bit 9 (MSB-1) of fnum */ + if (OPL->mode&0x40) + CH->kcode |= (CH->block_fnum&0x100)>>8; /* notesel == 1 */ + else + CH->kcode |= (CH->block_fnum&0x200)>>9; /* notesel == 0 */ + + /* refresh Total Level in both SLOTs of this channel */ + CH->SLOT[SLOT1].TLL = CH->SLOT[SLOT1].TL + (CH->ksl_base>>CH->SLOT[SLOT1].ksl); + CH->SLOT[SLOT2].TLL = CH->SLOT[SLOT2].TL + (CH->ksl_base>>CH->SLOT[SLOT2].ksl); + + /* refresh frequency counter in both SLOTs of this channel */ + CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); + CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); + } + break; + case 0xc0: + /* FB,C */ + if( (r&0x0f) > 8) return; + CH = &OPL->P_CH[r&0x0f]; + CH->SLOT[SLOT1].FB = (v>>1)&7 ? ((v>>1)&7) + 7 : 0; + CH->SLOT[SLOT1].CON = v&1; + CH->SLOT[SLOT1].connect1 = CH->SLOT[SLOT1].CON ? &OPL->output[0] : &OPL->phase_modulation; + break; + case 0xe0: /* waveform select */ + /* simply ignore write to the waveform select register + if selecting not enabled in test register */ + if(OPL->wavesel) + { + slot = slot_array[r&0x1f]; + if(slot < 0) return; + CH = &OPL->P_CH[slot/2]; + + CH->SLOT[slot&1].wavetable = (v&0x03)*SIN_LEN; + } + break; + } } /* lock/unlock for common table */ -static int OPL_LockTable(void) +static int OPL_LockTable() { - num_lock++; - if(num_lock>1) return 0; + num_lock++; + if(num_lock>1) return 0; - /* first time */ + /* first time */ - cur_chip = NULL; - /* allocate total level table (128kb space) */ - if( !init_tables() ) - { - num_lock--; - return -1; - } + /* allocate total level table (128kb space) */ + if( !init_tables() ) + { + num_lock--; + return -1; + } - return 0; + return 0; } static void OPL_UnLockTable(void) { - if(num_lock) num_lock--; - if(num_lock) return; + if(num_lock) num_lock--; + if(num_lock) return; - /* last time */ + /* last time */ - cur_chip = NULL; - OPLCloseTable(); + OPLCloseTable(); } static void OPLResetChip(FM_OPL *OPL) { - int c,s; - int i; + int c,s; + int i; + + OPL->eg_timer = 0; + OPL->eg_cnt = 0; + + OPL->noise_rng = 1; /* noise shift register */ + OPL->mode = 0; /* normal mode */ + OPL_STATUS_RESET(OPL,0x7f); + + /* reset with register write */ + OPLWriteReg(OPL,0x01,0); /* wavesel 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 parameters */ + for( c = 0 ; c < 9 ; c++ ) + { + OPL_CH *CH = &OPL->P_CH[c]; + for(s = 0 ; s < 2 ; s++ ) + { + /* wave table */ + CH->SLOT[s].wavetable = 0; + CH->SLOT[s].state = EG_OFF; + CH->SLOT[s].volume = MAX_ATT_INDEX; + } + } +#if BUILD_Y8950 + if(OPL->type&OPL_TYPE_ADPCM) + { + YM_DELTAT *DELTAT = OPL->deltat; + + DELTAT->freqbase = OPL->freqbase; + DELTAT->output_pointer = &OPL->output_deltat[0]; + DELTAT->portshift = 5; + DELTAT->output_range = 1<<23; + YM_DELTAT_ADPCM_Reset(DELTAT,0,YM_DELTAT_EMULATION_MODE_NORMAL); + } +#endif +} - OPL->eg_timer = 0; - OPL->eg_cnt = 0; - OPL->noise_rng = 1; /* noise shift register */ - OPL->mode = 0; /* normal mode */ - OPL_STATUS_RESET(OPL,0x7f); - - /* reset with register write */ - OPLWriteReg(OPL,0x01,0); /* wavesel 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 parameters */ - for( c = 0 ; c < 9 ; c++ ) - { - OPL_CH *CH = &OPL->P_CH[c]; - for(s = 0 ; s < 2 ; s++ ) - { - /* wave table */ - CH->SLOT[s].wavetable = 0; - CH->SLOT[s].state = EG_OFF; - CH->SLOT[s].volume = MAX_ATT_INDEX; - } - } +#if 0 // not used anywhere +static void OPL_postload(FM_OPL *OPL) +{ + int slot, ch; + + for( ch=0 ; ch < 9 ; ch++ ) + { + OPL_CH *CH = &OPL->P_CH[ch]; + + /* Look up key scale level */ + UINT32 block_fnum = CH->block_fnum; + CH->ksl_base = ksl_tab[block_fnum >> 6]; + CH->fc = OPL->fn_tab[block_fnum & 0x03ff] >> (7 - (block_fnum >> 10)); + + for( slot=0 ; slot < 2 ; slot++ ) + { + OPL_SLOT *SLOT = &CH->SLOT[slot]; + + /* Calculate key scale rate */ + SLOT->ksr = CH->kcode >> SLOT->KSR; + + /* Calculate attack, decay and release rates */ + if ((SLOT->ar + SLOT->ksr) < 16+62) + { + SLOT->eg_sh_ar = eg_rate_shift [SLOT->ar + SLOT->ksr ]; + SLOT->eg_sel_ar = eg_rate_select[SLOT->ar + SLOT->ksr ]; + } + else + { + SLOT->eg_sh_ar = 0; + SLOT->eg_sel_ar = 13*RATE_STEPS; + } + SLOT->eg_sh_dr = eg_rate_shift [SLOT->dr + SLOT->ksr ]; + SLOT->eg_sel_dr = eg_rate_select[SLOT->dr + SLOT->ksr ]; + SLOT->eg_sh_rr = eg_rate_shift [SLOT->rr + SLOT->ksr ]; + SLOT->eg_sel_rr = eg_rate_select[SLOT->rr + SLOT->ksr ]; + + /* Calculate phase increment */ + SLOT->Incr = CH->fc * SLOT->mul; + + /* Total level */ + SLOT->TLL = SLOT->TL + (CH->ksl_base >> SLOT->ksl); + + /* Connect output */ + SLOT->connect1 = SLOT->CON ? &OPL->output[0] : &OPL->phase_modulation; + } + } #if BUILD_Y8950 - if(OPL->type&OPL_TYPE_ADPCM) - { - YM_DELTAT *DELTAT = OPL->deltat; - - DELTAT->freqbase = OPL->freqbase; - DELTAT->output_pointer = &output_deltat[0]; - DELTAT->portshift = 5; - DELTAT->output_range = 1<<23; - YM_DELTAT_ADPCM_Reset(DELTAT,0); - } + if ( (OPL->type & OPL_TYPE_ADPCM) && (OPL->deltat) ) + { + // We really should call the postlod function for the YM_DELTAT, but it's hard without registers + // (see the way the YM2610 does it) + //YM_DELTAT_postload(OPL->deltat, REGS); + } #endif } +#endif + /* Create one of virtual YM3812/YM3526/Y8950 */ /* 'clock' is chip clock in Hz */ /* 'rate' is sampling rate */ -static FM_OPL *OPLCreate(int type, int clock, int rate) +static FM_OPL *OPLCreate(UINT32 clock, UINT32 rate, int type) { - char *ptr; - FM_OPL *OPL; - int state_size; + char *ptr; + FM_OPL *OPL; + int state_size; - if (OPL_LockTable() ==-1) return NULL; + if (OPL_LockTable() == -1) return NULL; - /* calculate OPL state size */ - state_size = sizeof(FM_OPL); + /* calculate OPL state size */ + state_size = sizeof(FM_OPL); #if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); + if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); #endif - /* allocate memory block */ - ptr = (char *)malloc(state_size); + /* allocate memory block */ + ptr = (char *)malloc(state_size); - if (ptr==NULL) - return NULL; + if (ptr==NULL) + return NULL; - /* clear */ - memset(ptr,0,state_size); + /* clear */ + memset(ptr,0,state_size); - OPL = (FM_OPL *)ptr; + OPL = (FM_OPL *)ptr; - ptr += sizeof(FM_OPL); + ptr += sizeof(FM_OPL); #if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) - { - OPL->deltat = (YM_DELTAT *)ptr; - } - ptr += sizeof(YM_DELTAT); + if (type&OPL_TYPE_ADPCM) + { + OPL->deltat = (YM_DELTAT *)ptr; + } + ptr += sizeof(YM_DELTAT); #endif - OPL->type = type; - OPL->clock = clock; - OPL->rate = rate; + OPL->type = type; + OPL->clock = clock; + OPL->rate = rate; - /* init global tables */ - OPL_initalize(OPL); + /* init global tables */ + OPL_initalize(OPL); - return OPL; + return OPL; } /* Destroy one of virtual YM3812 */ static void OPLDestroy(FM_OPL *OPL) { - OPL_UnLockTable(); - free(OPL); + OPL_UnLockTable(); + free(OPL); } /* Optional handlers */ -static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) +static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER timer_handler,void *param) { - OPL->TimerHandler = TimerHandler; - OPL->TimerParam = channelOffset; + OPL->timer_handler = timer_handler; + OPL->TimerParam = param; } -static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) +static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,void *param) { - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = param; + OPL->IRQHandler = IRQHandler; + OPL->IRQParam = param; } -static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) +static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,void *param) { - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = param; + OPL->UpdateHandler = UpdateHandler; + OPL->UpdateParam = param; } static 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); - OPLWriteReg(OPL,OPL->address,v); - } - return OPL->status>>7; + if( !(a&1) ) + { /* address port */ + OPL->address = v & 0xff; + } + else + { /* data port */ + if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); + OPLWriteReg(OPL,OPL->address,v); + } + return OPL->status>>7; } static unsigned char OPLRead(FM_OPL *OPL,int a) { - if( !(a&1) ) - { - /* status port */ - - #if BUILD_Y8950 - - if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ - { - return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); - } - - #endif - if (OPL->st[0]) { - if (OPL->TC[0]) OPL->TC[0]--; - else { - OPL->TC[0]=OPL->T[0]*20; - OPL_STATUS_SET(OPL,0x40); - } - } - if (OPL->st[1]) { - if (OPL->TC[1]) OPL->TC[1]--; - else { - OPL->TC[1]=OPL->T[1]*20; - OPL_STATUS_SET(OPL,0x40); - } - } - return OPL->status & (OPL->statusmask|0x80); - } + if( !(a&1) ) + { + /* status port */ + + #if BUILD_Y8950 + + if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ + { + return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); + } + + #endif + + /* OPL and OPL2 */ + return OPL->status & (OPL->statusmask|0x80); + } #if BUILD_Y8950 - /* 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 - logerror("Y8950: read unmapped KEYBOARD port\n"); - } - return 0; - - case 0x0f: /* ADPCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - UINT8 val; - - val = YM_DELTAT_ADPCM_Read(OPL->deltat); - /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ - return val; - } - return 0; - - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - logerror("Y8950:read unmapped I/O port\n"); - } - return 0; - case 0x1a: /* PCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - logerror("Y8950 A/D convertion is accessed but not implemented !\n"); - return 0x80; /* 2's complement PCM data - result from A/D convertion */ - } - return 0; - } + /* 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 + logerror("Y8950: read unmapped KEYBOARD port\n"); + } + return 0; + + case 0x0f: /* ADPCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + UINT8 val; + + val = YM_DELTAT_ADPCM_Read(OPL->deltat); + /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ + return val; + } + return 0; + + case 0x19: /* I/O DATA */ + if(OPL->type&OPL_TYPE_IO) + { + if(OPL->porthandler_r) + return OPL->porthandler_r(OPL->port_param); + else + logerror("Y8950:read unmapped I/O port\n"); + } + return 0; + case 0x1a: /* PCM-DATA */ + if(OPL->type&OPL_TYPE_ADPCM) + { + logerror("Y8950 A/D convertion is accessed but not implemented !\n"); + return 0x80; /* 2's complement PCM data - result from A/D convertion */ + } + return 0; + } #endif - return 0xff; + return 0xff; } /* CSM Key Controll */ INLINE void CSMKeyControll(OPL_CH *CH) { - FM_KEYON (&CH->SLOT[SLOT1], 4); - FM_KEYON (&CH->SLOT[SLOT2], 4); + FM_KEYON (&CH->SLOT[SLOT1], 4); + FM_KEYON (&CH->SLOT[SLOT2], 4); - /* The key off should happen exactly one sample later - not implemented correctly yet */ + /* The key off should happen exactly one sample later - not implemented correctly yet */ - FM_KEYOFF(&CH->SLOT[SLOT1], ~4); - FM_KEYOFF(&CH->SLOT[SLOT2], ~4); + FM_KEYOFF(&CH->SLOT[SLOT1], ~4); + FM_KEYOFF(&CH->SLOT[SLOT2], ~4); } static 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; + 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->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,OPL->TimerBase * OPL->T[c]); + return OPL->status>>7; } @@ -1936,78 +1990,62 @@ #if (BUILD_YM3812) -static FM_OPL *OPL_YM3812[MAX_OPL_CHIPS]; /* array of pointers to the YM3812's */ -static int YM3812NumChips = 0; /* number of chips */ - -int YM3812Init(int num, int clock, int rate) +void * ym3812_init(UINT32 clock, UINT32 rate) { - int i; - - if (YM3812NumChips) - return -1; /* duplicate init. */ - - YM3812NumChips = num; - - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator create */ - OPL_YM3812[i] = OPLCreate(OPL_TYPE_YM3812,clock,rate); - if(OPL_YM3812[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3812NumChips = 0; - return -1; - } - /* reset */ - YM3812ResetChip(i); - } - - return 0; + /* emulator create */ + FM_OPL *YM3812 = OPLCreate(clock,rate,OPL_TYPE_YM3812); + if (YM3812) + { + ym3812_reset_chip(YM3812); + } + return YM3812; } -void YM3812Shutdown(void) +void ym3812_shutdown(void *chip) { - int i; + FM_OPL *YM3812 = (FM_OPL *)chip; - for (i = 0;i < YM3812NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3812[i]); - OPL_YM3812[i] = NULL; - } - YM3812NumChips = 0; -} -void YM3812ResetChip(int which) + /* emulator shutdown */ + OPLDestroy(YM3812); + } +void ym3812_reset_chip(void *chip) { - OPLResetChip(OPL_YM3812[which]); + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLResetChip(YM3812); } -int YM3812Write(int which, int a, int v) +int ym3812_write(void *chip, int a, int v) { - return OPLWrite(OPL_YM3812[which], a, v); + FM_OPL *YM3812 = (FM_OPL *)chip; + return OPLWrite(YM3812, a, v); } -unsigned char YM3812Read(int which, int a) +unsigned char ym3812_read(void *chip, int a) { - /* YM3812 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3812[which], a) | 0x06 ; + FM_OPL *YM3812 = (FM_OPL *)chip; + /* YM3812 always returns bit2 and bit1 in HIGH state */ + return OPLRead(YM3812, a) | 0x06 ; } -int YM3812TimerOver(int which, int c) +int ym3812_timer_over(void *chip, int c) { - return OPLTimerOver(OPL_YM3812[which], c); + FM_OPL *YM3812 = (FM_OPL *)chip; + return OPLTimerOver(YM3812, c); } -void YM3812SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param) { - OPLSetTimerHandler(OPL_YM3812[which], TimerHandler, channelOffset); + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetTimerHandler(YM3812, timer_handler, param); } -void YM3812SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +void ym3812_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param) { - OPLSetIRQHandler(OPL_YM3812[which], IRQHandler, param); + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetIRQHandler(YM3812, IRQHandler, param); } -void YM3812SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param) { - OPLSetUpdateHandler(OPL_YM3812[which], UpdateHandler, param); + FM_OPL *YM3812 = (FM_OPL *)chip; + OPLSetUpdateHandler(YM3812, UpdateHandler, param); } @@ -2018,60 +2056,52 @@ ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void YM3812UpdateOne(int which, INT16 *buffer, int length) +void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) { - FM_OPL *OPL = OPL_YM3812[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; + FM_OPL *OPL = (FM_OPL *)chip; + UINT8 rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + + advance_lfo(OPL); + + /* FM part */ + OPL_CALC_CH(OPL, &OPL->P_CH[0]); + OPL_CALC_CH(OPL, &OPL->P_CH[1]); + OPL_CALC_CH(OPL, &OPL->P_CH[2]); + OPL_CALC_CH(OPL, &OPL->P_CH[3]); + OPL_CALC_CH(OPL, &OPL->P_CH[4]); + OPL_CALC_CH(OPL, &OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(OPL, &OPL->P_CH[6]); + OPL_CALC_CH(OPL, &OPL->P_CH[7]); + OPL_CALC_CH(OPL, &OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); + } + + lt = OPL->output[0]; + + lt >>= FINAL_SH; - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); - /* store to sound buffer */ - buf[i] = lt; + /* store to sound buffer */ + buf[i] = lt; - advance(OPL); - } + advance(OPL); + } } #endif /* BUILD_YM3812 */ @@ -2080,78 +2110,61 @@ #if (BUILD_YM3526) -static FM_OPL *OPL_YM3526[MAX_OPL_CHIPS]; /* array of pointers to the YM3526's */ -static int YM3526NumChips = 0; /* number of chips */ - -int YM3526Init(int num, int clock, int rate) +void *ym3526_init(UINT32 clock, UINT32 rate) { - int i; - - if (YM3526NumChips) - return -1; /* duplicate init. */ - - YM3526NumChips = num; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator create */ - OPL_YM3526[i] = OPLCreate(OPL_TYPE_YM3526,clock,rate); - if(OPL_YM3526[i] == NULL) - { - /* it's really bad - we run out of memeory */ - YM3526NumChips = 0; - return -1; - } - /* reset */ - YM3526ResetChip(i); - } - - return 0; + /* emulator create */ + FM_OPL *YM3526 = OPLCreate(clock,rate,OPL_TYPE_YM3526); + if (YM3526) + { + ym3526_reset_chip(YM3526); + } + return YM3526; } -void YM3526Shutdown(void) +void ym3526_shutdown(void *chip) { - int i; - - for (i = 0;i < YM3526NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_YM3526[i]); - OPL_YM3526[i] = NULL; - } - YM3526NumChips = 0; + FM_OPL *YM3526 = (FM_OPL *)chip; + /* emulator shutdown */ + OPLDestroy(YM3526); } -void YM3526ResetChip(int which) +void ym3526_reset_chip(void *chip) { - OPLResetChip(OPL_YM3526[which]); + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLResetChip(YM3526); } -int YM3526Write(int which, int a, int v) +int ym3526_write(void *chip, int a, int v) { - return OPLWrite(OPL_YM3526[which], a, v); + FM_OPL *YM3526 = (FM_OPL *)chip; + return OPLWrite(YM3526, a, v); } -unsigned char YM3526Read(int which, int a) +unsigned char ym3526_read(void *chip, int a) { - /* YM3526 always returns bit2 and bit1 in HIGH state */ - return OPLRead(OPL_YM3526[which], a) | 0x06 ; + FM_OPL *YM3526 = (FM_OPL *)chip; + /* YM3526 always returns bit2 and bit1 in HIGH state */ + return OPLRead(YM3526, a) | 0x06 ; } -int YM3526TimerOver(int which, int c) +int ym3526_timer_over(void *chip, int c) { - return OPLTimerOver(OPL_YM3526[which], c); + FM_OPL *YM3526 = (FM_OPL *)chip; + return OPLTimerOver(YM3526, c); } -void YM3526SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param) { - OPLSetTimerHandler(OPL_YM3526[which], TimerHandler, channelOffset); + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetTimerHandler(YM3526, timer_handler, param); } -void YM3526SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +void ym3526_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param) { - OPLSetIRQHandler(OPL_YM3526[which], IRQHandler, param); + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetIRQHandler(YM3526, IRQHandler, param); } -void YM3526SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param) { - OPLSetUpdateHandler(OPL_YM3526[which], UpdateHandler, param); + FM_OPL *YM3526 = (FM_OPL *)chip; + OPLSetUpdateHandler(YM3526, UpdateHandler, param); } @@ -2162,60 +2175,52 @@ ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void YM3526UpdateOne(int which, INT16 *buffer, int length) +void ym3526_update_one(void *chip, OPLSAMPLE *buffer, int length) { - FM_OPL *OPL = OPL_YM3526[which]; - UINT8 rhythm = OPL->rhythm&0x20; - OPLSAMPLE *buf = buffer; - int i; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - - advance_lfo(OPL); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0]; - - lt >>= FINAL_SH; + FM_OPL *OPL = (FM_OPL *)chip; + UINT8 rhythm = OPL->rhythm&0x20; + OPLSAMPLE *buf = buffer; + int i; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + + advance_lfo(OPL); + + /* FM part */ + OPL_CALC_CH(OPL, &OPL->P_CH[0]); + OPL_CALC_CH(OPL, &OPL->P_CH[1]); + OPL_CALC_CH(OPL, &OPL->P_CH[2]); + OPL_CALC_CH(OPL, &OPL->P_CH[3]); + OPL_CALC_CH(OPL, &OPL->P_CH[4]); + OPL_CALC_CH(OPL, &OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(OPL, &OPL->P_CH[6]); + OPL_CALC_CH(OPL, &OPL->P_CH[7]); + OPL_CALC_CH(OPL, &OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); + } + + lt = OPL->output[0]; + + lt >>= FINAL_SH; - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); - /* store to sound buffer */ - buf[i] = lt; + /* store to sound buffer */ + buf[i] = lt; - advance(OPL); - } + advance(OPL); + } } #endif /* BUILD_YM3526 */ @@ -2225,100 +2230,88 @@ #if BUILD_Y8950 -static FM_OPL *OPL_Y8950[MAX_OPL_CHIPS]; /* array of pointers to the Y8950's */ -static int Y8950NumChips = 0; /* number of chips */ - -static void Y8950_deltat_status_set(UINT8 which, UINT8 changebits) +static void Y8950_deltat_status_set(void *chip, UINT8 changebits) { - OPL_STATUS_SET(OPL_Y8950[which], changebits); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPL_STATUS_SET(Y8950, changebits); } -static void Y8950_deltat_status_reset(UINT8 which, UINT8 changebits) +static void Y8950_deltat_status_reset(void *chip, UINT8 changebits) { - OPL_STATUS_RESET(OPL_Y8950[which], changebits); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPL_STATUS_RESET(Y8950, changebits); } -int Y8950Init(int num, int clock, int rate) +void *y8950_init(UINT32 clock, UINT32 rate) { - int i; - - if (Y8950NumChips) - return -1; /* duplicate init. */ + /* emulator create */ + FM_OPL *Y8950 = OPLCreate(clock,rate,OPL_TYPE_Y8950); + if (Y8950) + { + Y8950->deltat->status_set_handler = Y8950_deltat_status_set; + Y8950->deltat->status_reset_handler = Y8950_deltat_status_reset; + Y8950->deltat->status_change_which_chip = Y8950; + Y8950->deltat->status_change_EOS_bit = 0x10; /* status flag: set bit4 on End Of Sample */ + Y8950->deltat->status_change_BRDY_bit = 0x08; /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ - Y8950NumChips = num; + /*Y8950->deltat->write_time = 10.0 / clock;*/ /* a single byte write takes 10 cycles of main clock */ + /*Y8950->deltat->read_time = 8.0 / clock;*/ /* a single byte read takes 8 cycles of main clock */ + /* reset */ + y8950_reset_chip(Y8950); + } - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator create */ - OPL_Y8950[i] = OPLCreate(OPL_TYPE_Y8950,clock,rate); - if(OPL_Y8950[i] == NULL) - { - /* it's really bad - we run out of memeory */ - Y8950NumChips = 0; - return -1; - } - OPL_Y8950[i]->deltat->status_set_handler = Y8950_deltat_status_set; - OPL_Y8950[i]->deltat->status_reset_handler = Y8950_deltat_status_reset; - OPL_Y8950[i]->deltat->status_change_which_chip = i; - /* status flag: set bit4 on End Of Sample */ - OPL_Y8950[i]->deltat->status_change_EOS_bit = 0x10; - /* status flag: set bit3 on BRDY (End Of: ADPCM analysis/synthesis, memory reading/writing) */ - OPL_Y8950[i]->deltat->status_change_BRDY_bit = 0x08; - /* reset */ - Y8950ResetChip(i); - } - - return 0; + return Y8950; } -void Y8950Shutdown(void) +void y8950_shutdown(void *chip) { - int i; - - for (i = 0;i < Y8950NumChips; i++) - { - /* emulator shutdown */ - OPLDestroy(OPL_Y8950[i]); - OPL_Y8950[i] = NULL; - } - Y8950NumChips = 0; + FM_OPL *Y8950 = (FM_OPL *)chip; + /* emulator shutdown */ + OPLDestroy(Y8950); } -void Y8950ResetChip(int which) +void y8950_reset_chip(void *chip) { - OPLResetChip(OPL_Y8950[which]); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLResetChip(Y8950); } -int Y8950Write(int which, int a, int v) +int y8950_write(void *chip, int a, int v) { - return OPLWrite(OPL_Y8950[which], a, v); + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLWrite(Y8950, a, v); } -unsigned char Y8950Read(int which, int a) +unsigned char y8950_read(void *chip, int a) { - return OPLRead(OPL_Y8950[which], a); + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLRead(Y8950, a); } -int Y8950TimerOver(int which, int c) +int y8950_timer_over(void *chip, int c) { - return OPLTimerOver(OPL_Y8950[which], c); + FM_OPL *Y8950 = (FM_OPL *)chip; + return OPLTimerOver(Y8950, c); } -void Y8950SetTimerHandler(int which, OPL_TIMERHANDLER TimerHandler, int channelOffset) +void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, void *param) { - OPLSetTimerHandler(OPL_Y8950[which], TimerHandler, channelOffset); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetTimerHandler(Y8950, timer_handler, param); } -void Y8950SetIRQHandler(int which,OPL_IRQHANDLER IRQHandler,int param) +void y8950_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,void *param) { - OPLSetIRQHandler(OPL_Y8950[which], IRQHandler, param); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetIRQHandler(Y8950, IRQHandler, param); } -void Y8950SetUpdateHandler(int which,OPL_UPDATEHANDLER UpdateHandler,int param) +void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,void *param) { - OPLSetUpdateHandler(OPL_Y8950[which], UpdateHandler, param); + FM_OPL *Y8950 = (FM_OPL *)chip; + OPLSetUpdateHandler(Y8950, UpdateHandler, param); } -void Y8950SetDeltaTMemory(int which, void * deltat_mem_ptr, int deltat_mem_size ) +void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ) { - FM_OPL *OPL = OPL_Y8950[which]; - OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr); - OPL->deltat->memory_size = deltat_mem_size; + FM_OPL *OPL = (FM_OPL *)chip; + OPL->deltat->memory = (UINT8 *)(deltat_mem_ptr); + OPL->deltat->memory_size = deltat_mem_size; } /* @@ -2328,86 +2321,75 @@ ** '*buffer' is the output buffer pointer ** 'length' is the number of samples that should be generated */ -void Y8950UpdateOne(int which, INT16 *buffer, int length) +void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) +{ + int i; + FM_OPL *OPL = (FM_OPL *)chip; + UINT8 rhythm = OPL->rhythm&0x20; + YM_DELTAT *DELTAT = OPL->deltat; + OPLSAMPLE *buf = buffer; + + for( i=0; i < length ; i++ ) + { + int lt; + + OPL->output[0] = 0; + OPL->output_deltat[0] = 0; + + advance_lfo(OPL); + + /* deltaT ADPCM */ + if( DELTAT->portstate&0x80 ) + YM_DELTAT_ADPCM_CALC(DELTAT); + + /* FM part */ + OPL_CALC_CH(OPL, &OPL->P_CH[0]); + OPL_CALC_CH(OPL, &OPL->P_CH[1]); + OPL_CALC_CH(OPL, &OPL->P_CH[2]); + OPL_CALC_CH(OPL, &OPL->P_CH[3]); + OPL_CALC_CH(OPL, &OPL->P_CH[4]); + OPL_CALC_CH(OPL, &OPL->P_CH[5]); + + if(!rhythm) + { + OPL_CALC_CH(OPL, &OPL->P_CH[6]); + OPL_CALC_CH(OPL, &OPL->P_CH[7]); + OPL_CALC_CH(OPL, &OPL->P_CH[8]); + } + else /* Rhythm part */ + { + OPL_CALC_RH(OPL, &OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); + } + + lt = OPL->output[0] + (OPL->output_deltat[0]>>11); + + lt >>= FINAL_SH; + + /* limit check */ + lt = limit( lt , MAXOUT, MINOUT ); + + /* store to sound buffer */ + buf[i] = lt; + + advance(OPL); + } + +} + +void y8950_set_port_handler(void *chip,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,void * param) +{ + FM_OPL *OPL = (FM_OPL *)chip; + OPL->porthandler_w = PortHandler_w; + OPL->porthandler_r = PortHandler_r; + OPL->port_param = param; +} + +void y8950_set_keyboard_handler(void *chip,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,void * param) { - int i; - FM_OPL *OPL = OPL_Y8950[which]; - UINT8 rhythm = OPL->rhythm&0x20; - YM_DELTAT *DELTAT = OPL->deltat; - OPLSAMPLE *buf = buffer; - - if( (void *)OPL != cur_chip ){ - cur_chip = (void *)OPL; - /* rhythm slots */ - SLOT7_1 = &OPL->P_CH[7].SLOT[SLOT1]; - SLOT7_2 = &OPL->P_CH[7].SLOT[SLOT2]; - SLOT8_1 = &OPL->P_CH[8].SLOT[SLOT1]; - SLOT8_2 = &OPL->P_CH[8].SLOT[SLOT2]; - - } - for( i=0; i < length ; i++ ) - { - int lt; - - output[0] = 0; - output_deltat[0] = 0; - - advance_lfo(OPL); - - /* deltaT ADPCM */ - if( DELTAT->portstate&0x80 ) - YM_DELTAT_ADPCM_CALC(DELTAT); - - /* FM part */ - OPL_CALC_CH(&OPL->P_CH[0]); - OPL_CALC_CH(&OPL->P_CH[1]); - OPL_CALC_CH(&OPL->P_CH[2]); - OPL_CALC_CH(&OPL->P_CH[3]); - OPL_CALC_CH(&OPL->P_CH[4]); - OPL_CALC_CH(&OPL->P_CH[5]); - - if(!rhythm) - { - OPL_CALC_CH(&OPL->P_CH[6]); - OPL_CALC_CH(&OPL->P_CH[7]); - OPL_CALC_CH(&OPL->P_CH[8]); - } - else /* Rhythm part */ - { - OPL_CALC_RH(&OPL->P_CH[0], (OPL->noise_rng>>0)&1 ); - } - - lt = output[0] + (output_deltat[0]>>11); - - lt >>= FINAL_SH; - - /* limit check */ - lt = limit( lt , MAXOUT, MINOUT ); - - /* store to sound buffer */ - buf[i] = lt; - - advance(OPL); - } - -} - -void Y8950SetPortHandler(int which, OPL_PORTHANDLER_W PortHandler_w, - OPL_PORTHANDLER_R PortHandler_r, int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->porthandler_w = PortHandler_w; - OPL->porthandler_r = PortHandler_r; - OPL->port_param = param; -} - -void Y8950SetKeyboardHandler(int which, OPL_PORTHANDLER_W KeyboardHandler_w, - OPL_PORTHANDLER_R KeyboardHandler_r, int param) -{ - FM_OPL *OPL = OPL_Y8950[which]; - OPL->keyboardhandler_w = KeyboardHandler_w; - OPL->keyboardhandler_r = KeyboardHandler_r; - OPL->keyboard_param = param; + FM_OPL *OPL = (FM_OPL *)chip; + OPL->keyboardhandler_w = KeyboardHandler_w; + OPL->keyboardhandler_r = KeyboardHandler_r; + OPL->keyboard_param = param; } #endif diff -Nru schism-0+20110101/player/fmpatches.c schism-20160521/player/fmpatches.c --- schism-0+20110101/player/fmpatches.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/fmpatches.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -28,150 +28,152 @@ #include "sndfile.h" static const uint8_t patches[][11] = { - {0x00,0x00,0x4F,0x00,0xF1,0xD2,0x51,0x43,0x00,0x00,0x06}, /*1*/ - {0x02,0x12,0x4F,0x00,0xF1,0xD2,0x51,0x43,0x00,0x00,0x02}, /*2*/ - {0x00,0x11,0x4A,0x00,0xF1,0xD2,0x53,0x74,0x00,0x00,0x06}, /*3*/ - {0x03,0x11,0x4F,0x00,0xF1,0xD2,0x53,0x74,0x01,0x01,0x06}, /*4*/ - {0x01,0x11,0x66,0x00,0xF1,0xD2,0x51,0xC3,0x00,0x00,0x06}, /*5*/ - {0xC0,0xD2,0x52,0x00,0xF1,0xD2,0x53,0x94,0x00,0x00,0x06}, /*6*/ - {0x12,0x18,0x86,0x00,0xF3,0xFC,0x00,0x33,0x00,0x00,0x08}, /*7*/ - {0xD0,0x12,0x4E,0x00,0xA8,0x92,0x32,0xA7,0x03,0x02,0x00}, /*8*/ - {0xC8,0xD1,0x4F,0x00,0xF2,0xF3,0x64,0x77,0x00,0x00,0x08}, /*9*/ - {0x33,0x34,0x0E,0x00,0x01,0x7D,0x11,0x34,0x00,0x00,0x08}, /*10*/ - {0x17,0x16,0x50,0x00,0xD1,0xD3,0x52,0x92,0x00,0x01,0x04}, /*11*/ - {0xE7,0xE1,0x21,0x00,0xF5,0xF6,0x77,0x14,0x00,0x00,0x08}, /*12*/ - {0x95,0x81,0x4E,0x00,0xDA,0xF9,0x25,0x15,0x00,0x00,0x0A}, /*13*/ - {0x27,0x21,0x1F,0x00,0xF5,0xF5,0x96,0x57,0x00,0x00,0x08}, /*14*/ - {0x87,0xF1,0x4E,0x80,0xB1,0xE6,0x33,0x42,0x00,0x00,0x00}, /*15*/ - {0x31,0x11,0x87,0x80,0xA1,0x7D,0x11,0x43,0x00,0x00,0x08}, /*16*/ - {0x32,0xB1,0x8C,0x00,0x91,0xA1,0x07,0x19,0x02,0x00,0x05}, /*17*/ - {0x31,0xB4,0x54,0x80,0xF1,0xF5,0x07,0x19,0x00,0x00,0x07}, /*18*/ - {0x24,0x21,0x40,0x49,0xFF,0xFF,0x0F,0x0F,0x00,0x00,0x01}, /*19*/ - {0xD2,0xF1,0x44,0x80,0x91,0xA1,0x57,0x09,0x01,0x01,0x03}, /*20*/ - {0x01,0x02,0x52,0x80,0xF0,0xF0,0x1F,0x1F,0x01,0x00,0x0A}, /*21*/ - {0x21,0x32,0x4F,0x01,0xF2,0x52,0x0B,0x0B,0x00,0x01,0x0A}, /*22*/ - {0xF0,0xF2,0x93,0x00,0xD8,0xB3,0x0B,0x0B,0x02,0x01,0x0A}, /*23*/ - {0x20,0x31,0x5D,0x00,0xF2,0x52,0x0B,0x0B,0x03,0x02,0x00}, /*24*/ - {0x01,0x01,0x1B,0x00,0xF4,0xF3,0x25,0x46,0x02,0x00,0x00}, /*25*/ - {0x11,0x01,0x0F,0x00,0xF4,0xF3,0x25,0x46,0x01,0x00,0x00}, /*26*/ - {0x01,0x01,0x27,0x00,0xF1,0xF4,0x1F,0x88,0x02,0x00,0x0A}, /*27*/ - {0x12,0x13,0x44,0x00,0xEA,0xD2,0x32,0xE7,0x01,0x01,0x00}, /*28*/ - {0x30,0x31,0x45,0x00,0xA4,0xF5,0x32,0xE7,0x03,0x00,0x00}, /*29*/ - {0x21,0x21,0x0F,0x00,0xF5,0xF1,0x17,0x78,0x02,0x01,0x04}, /*30*/ - {0x01,0x20,0x41,0x00,0xD1,0xC1,0x34,0xA5,0x03,0x03,0x04}, /*31*/ - {0x10,0x12,0x43,0x00,0xA7,0xE3,0x97,0xE7,0x03,0x02,0x00}, /*32*/ - {0x20,0x21,0x28,0x00,0xC5,0xD2,0x15,0xA4,0x00,0x00,0x0C}, /*33*/ - {0x30,0x21,0x16,0x00,0xF2,0xF3,0x9F,0x78,0x00,0x00,0x0C}, /*34*/ - {0x30,0x21,0x11,0x00,0x82,0xF3,0x9F,0x78,0x00,0x00,0x0A}, /*35*/ - {0x21,0x21,0x23,0x00,0x73,0x93,0x1A,0x87,0x00,0x00,0x0C}, /*36*/ - {0x30,0x21,0x0E,0x00,0x62,0xF3,0x55,0x68,0x02,0x00,0x0A}, /*37*/ - {0x30,0x22,0x0C,0x00,0x62,0xD5,0xB5,0x98,0x01,0x00,0x08}, /*38*/ - {0x70,0x72,0x93,0x40,0x64,0xA1,0x43,0x43,0x00,0x00,0x0A}, /*39*/ - {0x30,0x32,0x8D,0x80,0x44,0x92,0x43,0x43,0x02,0x00,0x0A}, /*40*/ - {0xE1,0xE2,0x4E,0x00,0x65,0x61,0x43,0x44,0x02,0x02,0x00}, /*41*/ - {0xA1,0xA2,0x8E,0x00,0x65,0x63,0x43,0x45,0x02,0x02,0x00}, /*42*/ - {0xB0,0x61,0x87,0x40,0xD1,0x62,0x11,0x15,0x02,0x01,0x06}, /*43*/ - {0xF0,0x20,0x8A,0x80,0xB1,0xA0,0x11,0x15,0x02,0x01,0x06}, /*44*/ - {0xF1,0xE2,0x89,0x40,0x73,0x43,0x01,0x05,0x02,0x00,0x06}, /*45*/ - {0x31,0x21,0x57,0x80,0xF8,0xF7,0xF9,0xE6,0x03,0x02,0x0E}, /*46*/ - {0x32,0x01,0x24,0x80,0xF1,0xF5,0x35,0x35,0x00,0x00,0x00}, /*47*/ - {0x00,0x00,0x04,0x00,0xAA,0xD2,0xC8,0xB3,0x00,0x00,0x0A}, /*48*/ - {0xE0,0xF1,0x4F,0x00,0xD4,0x55,0x0B,0x0B,0x02,0x02,0x0A}, /*49*/ - {0xE0,0xF0,0x52,0x00,0x96,0x35,0x05,0x01,0x02,0x02,0x0A}, /*50*/ - {0xE1,0xF1,0x4F,0x00,0x36,0x45,0x05,0x02,0x02,0x02,0x0A}, /*51*/ - {0xE2,0xE1,0x48,0x80,0x21,0x41,0x43,0x45,0x02,0x01,0x00}, /*52*/ - {0xE0,0xF1,0x16,0x00,0x41,0x20,0x52,0x72,0x02,0x02,0x00}, /*53*/ - {0xE0,0xF1,0x11,0x00,0x01,0xD0,0x52,0x72,0x02,0x02,0x00}, /*54*/ - {0xE0,0xF1,0x1A,0x00,0x61,0x30,0x52,0x73,0x00,0x02,0x00}, /*55*/ - {0x50,0x50,0x0B,0x00,0x84,0xA4,0x4B,0x99,0x00,0x00,0x0A}, /*56*/ - {0x31,0x61,0x1C,0x80,0x41,0x92,0x0B,0x3B,0x00,0x00,0x0E}, /*57*/ - {0xB1,0x61,0x1C,0x00,0x41,0x92,0x1F,0x3B,0x00,0x00,0x0E}, /*58*/ - {0x20,0x21,0x18,0x00,0x52,0xA2,0x15,0x24,0x00,0x00,0x0C}, /*59*/ - {0xC1,0xC1,0x94,0x80,0x74,0xA3,0xEA,0xF5,0x02,0x01,0x0E}, /*60*/ - {0x21,0x21,0x28,0x00,0x41,0x81,0xB4,0x98,0x00,0x00,0x0E}, /*61*/ - {0x21,0x21,0x1D,0x00,0x51,0xE1,0xAE,0x3E,0x02,0x01,0x0E}, /*62*/ - {0xE0,0xE0,0x93,0x80,0x51,0x81,0xA6,0x97,0x02,0x01,0x0E}, /*63*/ - {0xE0,0xE1,0x93,0x80,0x51,0xE1,0xA6,0x97,0x02,0x01,0x0E}, /*64*/ - {0xE0,0xF2,0x4B,0x01,0xD8,0xB3,0x0B,0x0B,0x02,0x01,0x08}, /*65*/ - {0xE0,0xF1,0x49,0x01,0xB8,0xB3,0x0B,0x0B,0x02,0x01,0x08}, /*66*/ - {0xE0,0xF0,0x4E,0x01,0x98,0xC3,0x0B,0x0B,0x01,0x02,0x08}, /*67*/ - {0xE0,0xF1,0x4C,0x01,0x88,0xD3,0x0B,0x0B,0x01,0x01,0x08}, /*68*/ - {0xF1,0xE4,0xC5,0x00,0x7E,0x8C,0x17,0x0E,0x00,0x00,0x08}, /*69*/ - {0x60,0x72,0x4F,0x00,0xD8,0xB3,0x0B,0x0B,0x00,0x01,0x0A}, /*70*/ - {0x31,0x72,0xD1,0x80,0xD5,0x91,0x19,0x1B,0x00,0x00,0x0C}, /*71*/ - {0x32,0x71,0xC8,0x80,0xD5,0x73,0x19,0x1B,0x00,0x00,0x0C}, /*72*/ - {0xE2,0x62,0x6A,0x00,0x9E,0x55,0x8F,0x2A,0x00,0x00,0x0E}, /*73*/ - {0xE0,0x61,0xEC,0x00,0x7E,0x65,0x8F,0x2A,0x00,0x00,0x0E}, /*74*/ - {0x62,0xA2,0x88,0x83,0x84,0x75,0x27,0x17,0x00,0x00,0x09}, /*75*/ - {0x62,0xA2,0x84,0x83,0x84,0x75,0x27,0x17,0x00,0x00,0x09}, /*76*/ - {0xE3,0x62,0x6D,0x00,0x57,0x57,0x04,0x77,0x00,0x00,0x0E}, /*77*/ - {0xF1,0xE1,0x28,0x00,0x57,0x67,0x34,0x5D,0x03,0x00,0x0E}, /*78*/ - {0xD1,0x72,0xC7,0x00,0x31,0x42,0x0F,0x09,0x00,0x00,0x0B}, /*79*/ - {0xF2,0x72,0xC7,0x00,0x51,0x42,0x05,0x69,0x00,0x00,0x0B}, /*80*/ - {0x23,0x31,0x4F,0x00,0x51,0x60,0x5B,0x25,0x01,0x01,0x00}, /*81*/ - {0x22,0x31,0x48,0x00,0x31,0xC0,0x9B,0x65,0x02,0x01,0x00}, /*82*/ - {0xF1,0xE1,0x28,0x00,0x57,0x67,0x34,0x0D,0x03,0x00,0x0E}, /*83*/ - {0xE1,0xE1,0x23,0x00,0x57,0x67,0x04,0x4D,0x03,0x00,0x0E}, /*84*/ - {0xE2,0x31,0x42,0x08,0x78,0xF3,0x0B,0x0B,0x01,0x01,0x08}, /*85*/ - {0xE2,0xE2,0x21,0x00,0x11,0x40,0x52,0x73,0x01,0x01,0x08}, /*86*/ - {0x23,0xA4,0xC0,0x00,0x51,0x35,0x07,0x79,0x01,0x02,0x0D}, /*87*/ - {0x24,0xA0,0xC0,0x00,0x51,0x75,0x07,0x09,0x01,0x02,0x09}, /*88*/ - {0xE0,0xF0,0x16,0x00,0xB1,0xE0,0x51,0x75,0x02,0x02,0x00}, /*89*/ - {0x03,0xA4,0xC0,0x00,0x52,0xF4,0x03,0x55,0x00,0x00,0x09}, /*90*/ - {0xE1,0xE1,0x93,0x80,0x31,0xA1,0xA6,0x97,0x01,0x01,0x0A}, /*91*/ - {0xF0,0x71,0xC4,0x80,0x10,0x11,0x01,0xC1,0x02,0x02,0x01}, /*92*/ - {0xC1,0xE0,0x4F,0x00,0xB1,0x12,0x53,0x74,0x02,0x02,0x06}, /*93*/ - {0xC0,0x41,0x6D,0x00,0xF9,0xF2,0x21,0xB3,0x01,0x00,0x0E}, /*94*/ - {0xE3,0xE2,0x4C,0x00,0x21,0xA1,0x43,0x45,0x01,0x01,0x00}, /*95*/ - {0xE3,0xE2,0x0C,0x00,0x11,0x80,0x52,0x73,0x01,0x01,0x08}, /*96*/ - {0x26,0x88,0xC0,0x00,0x55,0xF8,0x47,0x19,0x00,0x00,0x0B}, /*97*/ - {0x23,0xE4,0xD4,0x00,0xE5,0x35,0x03,0x65,0x00,0x00,0x07}, /*98*/ - {0x27,0x32,0xC0,0x00,0x32,0xA4,0x62,0x33,0x00,0x00,0x00}, /*99*/ - {0xD0,0x31,0x4E,0x00,0x98,0xA2,0x32,0x47,0x01,0x02,0x00}, /*100*/ - {0xF0,0x71,0xC0,0x00,0x93,0x43,0x03,0x02,0x01,0x00,0x0F}, /*101*/ - {0xE0,0xF1,0x1A,0x80,0x13,0x33,0x52,0x13,0x01,0x02,0x00}, /*102*/ - {0xE0,0xF1,0x1A,0x00,0x45,0x32,0xBA,0x91,0x00,0x02,0x00}, /*103*/ - {0x11,0x15,0x18,0x03,0x58,0xA2,0x02,0x72,0x01,0x00,0x0A}, /*104*/ - {0x10,0x18,0x80,0x40,0xF1,0xF1,0x53,0x53,0x00,0x00,0x00}, /*105*/ - {0x31,0x17,0x86,0x80,0xA1,0x7D,0x11,0x23,0x00,0x00,0x08}, /*106*/ - {0x10,0x18,0x80,0x40,0xF1,0xF6,0x53,0x54,0x00,0x00,0x00}, /*107*/ - {0x31,0x34,0x21,0x00,0xF5,0x93,0x56,0xE8,0x01,0x00,0x08}, /*108*/ - {0x03,0x15,0x4F,0x00,0xF1,0xD6,0x39,0x74,0x03,0x00,0x06}, /*109*/ - {0x31,0x22,0x43,0x00,0x6E,0x8B,0x17,0x0C,0x01,0x02,0x02}, /*110*/ - {0x31,0x22,0x1C,0x80,0x61,0x52,0x03,0x67,0x00,0x00,0x0E}, /*111*/ - {0x60,0xF0,0x0C,0x80,0x81,0x61,0x03,0x0C,0x00,0x01,0x08}, /*112*/ - {0x27,0x05,0x55,0x00,0x31,0xA7,0x62,0x75,0x00,0x00,0x00}, /*113*/ - {0x95,0x16,0x81,0x00,0xE7,0x96,0x01,0x67,0x00,0x00,0x04}, /*114*/ - {0x0C,0x01,0x87,0x80,0xF0,0xF2,0x05,0x05,0x01,0x01,0x04}, /*115*/ - {0x35,0x11,0x44,0x00,0xF8,0xF5,0xFF,0x75,0x00,0x00,0x0E}, /*116*/ - {0x10,0x10,0x0B,0x00,0xA7,0xD5,0xEC,0xF5,0x00,0x00,0x00}, /*117*/ - {0x20,0x01,0x0B,0x00,0xA8,0xD6,0xC8,0xB7,0x00,0x00,0x00}, /*118*/ - {0x00,0x01,0x0B,0x00,0x88,0xD5,0xC4,0xB7,0x00,0x00,0x00}, /*119*/ - {0x0C,0x10,0x8F,0x80,0x41,0x33,0x31,0x2B,0x00,0x03,0x08}, /*120*/ - {0x17,0xF7,0x00,0x00,0x3B,0xEA,0xDF,0x97,0x03,0x00,0x0B}, /*121*/ - {0x12,0x18,0x06,0x00,0x73,0x3C,0x02,0x74,0x00,0x00,0x0E}, /*122*/ - {0x02,0x08,0x00,0x00,0x3E,0x14,0x01,0xF3,0x02,0x02,0x0E}, /*123*/ - {0xF5,0xF6,0xD4,0x00,0xEB,0x45,0x03,0x68,0x00,0x00,0x07}, /*124*/ - {0xF0,0xCA,0x00,0xC0,0xDA,0xB0,0x71,0x17,0x01,0x01,0x08}, /*125*/ - {0xF0,0xE2,0x00,0xC0,0x1E,0x11,0x11,0x11,0x01,0x01,0x08}, /*126*/ - {0xE7,0xE8,0x00,0x04,0x34,0x10,0x00,0xB2,0x02,0x02,0x0E}, /*127*/ - {0x0C,0x04,0x00,0x00,0xF0,0xF6,0xF0,0xE6,0x02,0x00,0x0E}, /*128*/ + {0x00,0x00,0x4F,0x00,0xF1,0xD2,0x51,0x43,0x00,0x00,0x06}, /*1*/ + {0x02,0x12,0x4F,0x00,0xF1,0xD2,0x51,0x43,0x00,0x00,0x02}, /*2*/ + {0x00,0x11,0x4A,0x00,0xF1,0xD2,0x53,0x74,0x00,0x00,0x06}, /*3*/ + {0x03,0x11,0x4F,0x00,0xF1,0xD2,0x53,0x74,0x01,0x01,0x06}, /*4*/ + {0x01,0x11,0x66,0x00,0xF1,0xD2,0x51,0xC3,0x00,0x00,0x06}, /*5*/ + {0xC0,0xD2,0x52,0x00,0xF1,0xD2,0x53,0x94,0x00,0x00,0x06}, /*6*/ + {0x12,0x18,0x86,0x00,0xF3,0xFC,0x00,0x33,0x00,0x00,0x08}, /*7*/ + {0xD0,0x12,0x4E,0x00,0xA8,0x92,0x32,0xA7,0x03,0x02,0x00}, /*8*/ + {0xC8,0xD1,0x4F,0x00,0xF2,0xF3,0x64,0x77,0x00,0x00,0x08}, /*9*/ + {0x33,0x34,0x0E,0x00,0x01,0x7D,0x11,0x34,0x00,0x00,0x08}, /*10*/ + {0x17,0x16,0x50,0x00,0xD1,0xD3,0x52,0x92,0x00,0x01,0x04}, /*11*/ + {0xE7,0xE1,0x21,0x00,0xF5,0xF6,0x77,0x14,0x00,0x00,0x08}, /*12*/ + {0x95,0x81,0x4E,0x00,0xDA,0xF9,0x25,0x15,0x00,0x00,0x0A}, /*13*/ + {0x27,0x21,0x1F,0x00,0xF5,0xF5,0x96,0x57,0x00,0x00,0x08}, /*14*/ + {0x87,0xF1,0x4E,0x80,0xB1,0xE6,0x33,0x42,0x00,0x00,0x00}, /*15*/ + {0x31,0x11,0x87,0x80,0xA1,0x7D,0x11,0x43,0x00,0x00,0x08}, /*16*/ + {0x32,0xB1,0x8C,0x00,0x91,0xA1,0x07,0x19,0x02,0x00,0x05}, /*17*/ + {0x31,0xB4,0x54,0x80,0xF1,0xF5,0x07,0x19,0x00,0x00,0x07}, /*18*/ + {0x24,0x21,0x40,0x49,0xFF,0xFF,0x0F,0x0F,0x00,0x00,0x01}, /*19*/ + {0xD2,0xF1,0x44,0x80,0x91,0xA1,0x57,0x09,0x01,0x01,0x03}, /*20*/ + {0x01,0x02,0x52,0x80,0xF0,0xF0,0x1F,0x1F,0x01,0x00,0x0A}, /*21*/ + {0x21,0x32,0x4F,0x01,0xF2,0x52,0x0B,0x0B,0x00,0x01,0x0A}, /*22*/ + {0xF0,0xF2,0x93,0x00,0xD8,0xB3,0x0B,0x0B,0x02,0x01,0x0A}, /*23*/ + {0x20,0x31,0x5D,0x00,0xF2,0x52,0x0B,0x0B,0x03,0x02,0x00}, /*24*/ + {0x01,0x01,0x1B,0x00,0xF4,0xF3,0x25,0x46,0x02,0x00,0x00}, /*25*/ + {0x11,0x01,0x0F,0x00,0xF4,0xF3,0x25,0x46,0x01,0x00,0x00}, /*26*/ + {0x01,0x01,0x27,0x00,0xF1,0xF4,0x1F,0x88,0x02,0x00,0x0A}, /*27*/ + {0x12,0x13,0x44,0x00,0xEA,0xD2,0x32,0xE7,0x01,0x01,0x00}, /*28*/ + {0x30,0x31,0x45,0x00,0xA4,0xF5,0x32,0xE7,0x03,0x00,0x00}, /*29*/ + {0x21,0x21,0x0F,0x00,0xF5,0xF1,0x17,0x78,0x02,0x01,0x04}, /*30*/ + {0x01,0x20,0x41,0x00,0xD1,0xC1,0x34,0xA5,0x03,0x03,0x04}, /*31*/ + {0x10,0x12,0x43,0x00,0xA7,0xE3,0x97,0xE7,0x03,0x02,0x00}, /*32*/ + {0x20,0x21,0x28,0x00,0xC5,0xD2,0x15,0xA4,0x00,0x00,0x0C}, /*33*/ + {0x30,0x21,0x16,0x00,0xF2,0xF3,0x9F,0x78,0x00,0x00,0x0C}, /*34*/ + {0x30,0x21,0x11,0x00,0x82,0xF3,0x9F,0x78,0x00,0x00,0x0A}, /*35*/ + {0x21,0x21,0x23,0x00,0x73,0x93,0x1A,0x87,0x00,0x00,0x0C}, /*36*/ + {0x30,0x21,0x0E,0x00,0x62,0xF3,0x55,0x68,0x02,0x00,0x0A}, /*37*/ + {0x30,0x22,0x0C,0x00,0x62,0xD5,0xB5,0x98,0x01,0x00,0x08}, /*38*/ + {0x70,0x72,0x93,0x40,0x64,0xA1,0x43,0x43,0x00,0x00,0x0A}, /*39*/ + {0x30,0x32,0x8D,0x80,0x44,0x92,0x43,0x43,0x02,0x00,0x0A}, /*40*/ + {0xE1,0xE2,0x4E,0x00,0x65,0x61,0x43,0x44,0x02,0x02,0x00}, /*41*/ + {0xA1,0xA2,0x8E,0x00,0x65,0x63,0x43,0x45,0x02,0x02,0x00}, /*42*/ + {0xB0,0x61,0x87,0x40,0xD1,0x62,0x11,0x15,0x02,0x01,0x06}, /*43*/ + {0xF0,0x20,0x8A,0x80,0xB1,0xA0,0x11,0x15,0x02,0x01,0x06}, /*44*/ + {0xF1,0xE2,0x89,0x40,0x73,0x43,0x01,0x05,0x02,0x00,0x06}, /*45*/ + {0x31,0x21,0x57,0x80,0xF8,0xF7,0xF9,0xE6,0x03,0x02,0x0E}, /*46*/ + {0x32,0x01,0x24,0x80,0xF1,0xF5,0x35,0x35,0x00,0x00,0x00}, /*47*/ + {0x00,0x00,0x04,0x00,0xAA,0xD2,0xC8,0xB3,0x00,0x00,0x0A}, /*48*/ + {0xE0,0xF1,0x4F,0x00,0xD4,0x55,0x0B,0x0B,0x02,0x02,0x0A}, /*49*/ + {0xE0,0xF0,0x52,0x00,0x96,0x35,0x05,0x01,0x02,0x02,0x0A}, /*50*/ + {0xE1,0xF1,0x4F,0x00,0x36,0x45,0x05,0x02,0x02,0x02,0x0A}, /*51*/ + {0xE2,0xE1,0x48,0x80,0x21,0x41,0x43,0x45,0x02,0x01,0x00}, /*52*/ + {0xE0,0xF1,0x16,0x00,0x41,0x20,0x52,0x72,0x02,0x02,0x00}, /*53*/ + {0xE0,0xF1,0x11,0x00,0x01,0xD0,0x52,0x72,0x02,0x02,0x00}, /*54*/ + {0xE0,0xF1,0x1A,0x00,0x61,0x30,0x52,0x73,0x00,0x02,0x00}, /*55*/ + {0x50,0x50,0x0B,0x00,0x84,0xA4,0x4B,0x99,0x00,0x00,0x0A}, /*56*/ + {0x31,0x61,0x1C,0x80,0x41,0x92,0x0B,0x3B,0x00,0x00,0x0E}, /*57*/ + {0xB1,0x61,0x1C,0x00,0x41,0x92,0x1F,0x3B,0x00,0x00,0x0E}, /*58*/ + {0x20,0x21,0x18,0x00,0x52,0xA2,0x15,0x24,0x00,0x00,0x0C}, /*59*/ + {0xC1,0xC1,0x94,0x80,0x74,0xA3,0xEA,0xF5,0x02,0x01,0x0E}, /*60*/ + {0x21,0x21,0x28,0x00,0x41,0x81,0xB4,0x98,0x00,0x00,0x0E}, /*61*/ + {0x21,0x21,0x1D,0x00,0x51,0xE1,0xAE,0x3E,0x02,0x01,0x0E}, /*62*/ + {0xE0,0xE0,0x93,0x80,0x51,0x81,0xA6,0x97,0x02,0x01,0x0E}, /*63*/ + {0xE0,0xE1,0x93,0x80,0x51,0xE1,0xA6,0x97,0x02,0x01,0x0E}, /*64*/ + {0xE0,0xF2,0x4B,0x01,0xD8,0xB3,0x0B,0x0B,0x02,0x01,0x08}, /*65*/ + {0xE0,0xF1,0x49,0x01,0xB8,0xB3,0x0B,0x0B,0x02,0x01,0x08}, /*66*/ + {0xE0,0xF0,0x4E,0x01,0x98,0xC3,0x0B,0x0B,0x01,0x02,0x08}, /*67*/ + {0xE0,0xF1,0x4C,0x01,0x88,0xD3,0x0B,0x0B,0x01,0x01,0x08}, /*68*/ + {0xF1,0xE4,0xC5,0x00,0x7E,0x8C,0x17,0x0E,0x00,0x00,0x08}, /*69*/ + {0x60,0x72,0x4F,0x00,0xD8,0xB3,0x0B,0x0B,0x00,0x01,0x0A}, /*70*/ + {0x31,0x72,0xD1,0x80,0xD5,0x91,0x19,0x1B,0x00,0x00,0x0C}, /*71*/ + {0x32,0x71,0xC8,0x80,0xD5,0x73,0x19,0x1B,0x00,0x00,0x0C}, /*72*/ + {0xE2,0x62,0x6A,0x00,0x9E,0x55,0x8F,0x2A,0x00,0x00,0x0E}, /*73*/ + {0xE0,0x61,0xEC,0x00,0x7E,0x65,0x8F,0x2A,0x00,0x00,0x0E}, /*74*/ + {0x62,0xA2,0x88,0x83,0x84,0x75,0x27,0x17,0x00,0x00,0x09}, /*75*/ + {0x62,0xA2,0x84,0x83,0x84,0x75,0x27,0x17,0x00,0x00,0x09}, /*76*/ + {0xE3,0x62,0x6D,0x00,0x57,0x57,0x04,0x77,0x00,0x00,0x0E}, /*77*/ + {0xF1,0xE1,0x28,0x00,0x57,0x67,0x34,0x5D,0x03,0x00,0x0E}, /*78*/ + {0xD1,0x72,0xC7,0x00,0x31,0x42,0x0F,0x09,0x00,0x00,0x0B}, /*79*/ + {0xF2,0x72,0xC7,0x00,0x51,0x42,0x05,0x69,0x00,0x00,0x0B}, /*80*/ + {0x23,0x31,0x4F,0x00,0x51,0x60,0x5B,0x25,0x01,0x01,0x00}, /*81*/ + {0x22,0x31,0x48,0x00,0x31,0xC0,0x9B,0x65,0x02,0x01,0x00}, /*82*/ + {0xF1,0xE1,0x28,0x00,0x57,0x67,0x34,0x0D,0x03,0x00,0x0E}, /*83*/ + {0xE1,0xE1,0x23,0x00,0x57,0x67,0x04,0x4D,0x03,0x00,0x0E}, /*84*/ + {0xE2,0x31,0x42,0x08,0x78,0xF3,0x0B,0x0B,0x01,0x01,0x08}, /*85*/ + {0xE2,0xE2,0x21,0x00,0x11,0x40,0x52,0x73,0x01,0x01,0x08}, /*86*/ + {0x23,0xA4,0xC0,0x00,0x51,0x35,0x07,0x79,0x01,0x02,0x0D}, /*87*/ + {0x24,0xA0,0xC0,0x00,0x51,0x75,0x07,0x09,0x01,0x02,0x09}, /*88*/ + {0xE0,0xF0,0x16,0x00,0xB1,0xE0,0x51,0x75,0x02,0x02,0x00}, /*89*/ + {0x03,0xA4,0xC0,0x00,0x52,0xF4,0x03,0x55,0x00,0x00,0x09}, /*90*/ + {0xE1,0xE1,0x93,0x80,0x31,0xA1,0xA6,0x97,0x01,0x01,0x0A}, /*91*/ + {0xF0,0x71,0xC4,0x80,0x10,0x11,0x01,0xC1,0x02,0x02,0x01}, /*92*/ + {0xC1,0xE0,0x4F,0x00,0xB1,0x12,0x53,0x74,0x02,0x02,0x06}, /*93*/ + {0xC0,0x41,0x6D,0x00,0xF9,0xF2,0x21,0xB3,0x01,0x00,0x0E}, /*94*/ + {0xE3,0xE2,0x4C,0x00,0x21,0xA1,0x43,0x45,0x01,0x01,0x00}, /*95*/ + {0xE3,0xE2,0x0C,0x00,0x11,0x80,0x52,0x73,0x01,0x01,0x08}, /*96*/ + {0x26,0x88,0xC0,0x00,0x55,0xF8,0x47,0x19,0x00,0x00,0x0B}, /*97*/ + {0x23,0xE4,0xD4,0x00,0xE5,0x35,0x03,0x65,0x00,0x00,0x07}, /*98*/ + {0x27,0x32,0xC0,0x00,0x32,0xA4,0x62,0x33,0x00,0x00,0x00}, /*99*/ + {0xD0,0x31,0x4E,0x00,0x98,0xA2,0x32,0x47,0x01,0x02,0x00}, /*100*/ + {0xF0,0x71,0xC0,0x00,0x93,0x43,0x03,0x02,0x01,0x00,0x0F}, /*101*/ + {0xE0,0xF1,0x1A,0x80,0x13,0x33,0x52,0x13,0x01,0x02,0x00}, /*102*/ + {0xE0,0xF1,0x1A,0x00,0x45,0x32,0xBA,0x91,0x00,0x02,0x00}, /*103*/ + {0x11,0x15,0x18,0x03,0x58,0xA2,0x02,0x72,0x01,0x00,0x0A}, /*104*/ + {0x10,0x18,0x80,0x40,0xF1,0xF1,0x53,0x53,0x00,0x00,0x00}, /*105*/ + {0x31,0x17,0x86,0x80,0xA1,0x7D,0x11,0x23,0x00,0x00,0x08}, /*106*/ + {0x10,0x18,0x80,0x40,0xF1,0xF6,0x53,0x54,0x00,0x00,0x00}, /*107*/ + {0x31,0x34,0x21,0x00,0xF5,0x93,0x56,0xE8,0x01,0x00,0x08}, /*108*/ + {0x03,0x15,0x4F,0x00,0xF1,0xD6,0x39,0x74,0x03,0x00,0x06}, /*109*/ + {0x31,0x22,0x43,0x00,0x6E,0x8B,0x17,0x0C,0x01,0x02,0x02}, /*110*/ + {0x31,0x22,0x1C,0x80,0x61,0x52,0x03,0x67,0x00,0x00,0x0E}, /*111*/ + {0x60,0xF0,0x0C,0x80,0x81,0x61,0x03,0x0C,0x00,0x01,0x08}, /*112*/ + {0x27,0x05,0x55,0x00,0x31,0xA7,0x62,0x75,0x00,0x00,0x00}, /*113*/ + {0x95,0x16,0x81,0x00,0xE7,0x96,0x01,0x67,0x00,0x00,0x04}, /*114*/ + {0x0C,0x01,0x87,0x80,0xF0,0xF2,0x05,0x05,0x01,0x01,0x04}, /*115*/ + {0x35,0x11,0x44,0x00,0xF8,0xF5,0xFF,0x75,0x00,0x00,0x0E}, /*116*/ + {0x10,0x10,0x0B,0x00,0xA7,0xD5,0xEC,0xF5,0x00,0x00,0x00}, /*117*/ + {0x20,0x01,0x0B,0x00,0xA8,0xD6,0xC8,0xB7,0x00,0x00,0x00}, /*118*/ + {0x00,0x01,0x0B,0x00,0x88,0xD5,0xC4,0xB7,0x00,0x00,0x00}, /*119*/ + {0x0C,0x10,0x8F,0x80,0x41,0x33,0x31,0x2B,0x00,0x03,0x08}, /*120*/ + {0x17,0xF7,0x00,0x00,0x3B,0xEA,0xDF,0x97,0x03,0x00,0x0B}, /*121*/ + {0x12,0x18,0x06,0x00,0x73,0x3C,0x02,0x74,0x00,0x00,0x0E}, /*122*/ + {0x02,0x08,0x00,0x00,0x3E,0x14,0x01,0xF3,0x02,0x02,0x0E}, /*123*/ + {0xF5,0xF6,0xD4,0x00,0xEB,0x45,0x03,0x68,0x00,0x00,0x07}, /*124*/ + {0xF0,0xCA,0x00,0xC0,0xDA,0xB0,0x71,0x17,0x01,0x01,0x08}, /*125*/ + {0xF0,0xE2,0x00,0xC0,0x1E,0x11,0x11,0x11,0x01,0x01,0x08}, /*126*/ + {0xE7,0xE8,0x00,0x04,0x34,0x10,0x00,0xB2,0x02,0x02,0x0E}, /*127*/ + {0x0C,0x04,0x00,0x00,0xF0,0xF6,0xF0,0xE6,0x02,0x00,0x0E}, /*128*/ }; void adlib_patch_apply(song_sample_t *smp, int patchnum) { - if (patchnum < 0 || patchnum > 127) { - printf("adlib_patch_apply: invalid patch %d\n", patchnum); - return; - } - memcpy(smp->adlib_bytes, patches[patchnum], 11); - strncpy(smp->name, midi_program_names[patchnum], sizeof(smp->name) - 1); - smp->name[sizeof(smp->name) - 1] = '\0'; // Paranoid. - sprintf(smp->filename, "MIDI#%03d", patchnum + 1); - smp->flags |= CHN_ADLIB; - if (!smp->data) { - smp->length = 1; - smp->data = csf_allocate_sample(1); - } + if (patchnum < 0 || patchnum > 127) { + printf("adlib_patch_apply: invalid patch %d\n", patchnum); + return; + } + memcpy(smp->adlib_bytes, patches[patchnum], 11); + strncpy(smp->name, midi_program_names[patchnum], sizeof(smp->name) - 1); + smp->name[sizeof(smp->name) - 1] = '\0'; // Paranoid. + sprintf(smp->filename, "MIDI#%03d", patchnum + 1); + smp->flags |= CHN_ADLIB; + if (smp->data) { + csf_free_sample(smp->data); + smp->data = NULL; + } + smp->length = 1; + smp->data = csf_allocate_sample(1); } diff -Nru schism-0+20110101/player/mixer.c schism-20160521/player/mixer.c --- schism-0+20110101/player/mixer.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/mixer.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -100,28 +100,28 @@ // ---------------------------------------------------------------------------- #define SNDMIX_BEGINSAMPLELOOP8 \ - register song_voice_t * const chan = channel; \ - position = chan->position_frac; \ - const signed char *p = (signed char *)(chan->current_sample_data + chan->position); \ - if (chan->flags & CHN_STEREO) p += chan->position; \ - int *pvol = pbuffer;\ - do { + register song_voice_t * const chan = channel; \ + position = chan->position_frac; \ + const signed char *p = (signed char *)(chan->current_sample_data + chan->position); \ + if (chan->flags & CHN_STEREO) p += chan->position; \ + int *pvol = pbuffer;\ + do { #define SNDMIX_BEGINSAMPLELOOP16\ - register song_voice_t * const chan = channel;\ - position = chan->position_frac;\ - const signed short *p = (signed short *)(chan->current_sample_data+(chan->position*2));\ - if (chan->flags & CHN_STEREO) p += chan->position;\ - int *pvol = pbuffer;\ - do { + register song_voice_t * const chan = channel;\ + position = chan->position_frac;\ + const signed short *p = (signed short *)(chan->current_sample_data+(chan->position*2));\ + if (chan->flags & CHN_STEREO) p += chan->position;\ + int *pvol = pbuffer;\ + do { #define SNDMIX_ENDSAMPLELOOP \ - position += chan->increment; \ - } while (pvol < pbufmax); \ - chan->position += position >> 16; \ - chan->position_frac = position & 0xFFFF; + position += chan->increment; \ + } while (pvol < pbufmax); \ + chan->position += position >> 16; \ + chan->position_frac = position & 0xFFFF; #define SNDMIX_ENDSAMPLELOOP8 SNDMIX_ENDSAMPLELOOP @@ -166,18 +166,18 @@ int poshi = position >> 16; \ int poslo = (position >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \ int vol = (cubic_spline_lut[poslo ] * (int)p[poshi - 1] + \ - cubic_spline_lut[poslo + 1] * (int)p[poshi ] + \ - cubic_spline_lut[poslo + 3] * (int)p[poshi + 2] + \ - cubic_spline_lut[poslo + 2] * (int)p[poshi + 1]) >> SPLINE_8SHIFT; + cubic_spline_lut[poslo + 1] * (int)p[poshi ] + \ + cubic_spline_lut[poslo + 3] * (int)p[poshi + 2] + \ + cubic_spline_lut[poslo + 2] * (int)p[poshi + 1]) >> SPLINE_8SHIFT; #define SNDMIX_GETMONOVOL16SPLINE \ int poshi = position >> 16; \ int poslo = (position >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \ int vol = (cubic_spline_lut[poslo ] * (int)p[poshi - 1] + \ - cubic_spline_lut[poslo + 1] * (int)p[poshi ] + \ - cubic_spline_lut[poslo + 3] * (int)p[poshi + 2] + \ - cubic_spline_lut[poslo + 2] * (int)p[poshi + 1]) >> SPLINE_16SHIFT; + cubic_spline_lut[poslo + 1] * (int)p[poshi ] + \ + cubic_spline_lut[poslo + 3] * (int)p[poshi + 2] + \ + cubic_spline_lut[poslo + 2] * (int)p[poshi + 1]) >> SPLINE_16SHIFT; // fir interpolation @@ -191,14 +191,14 @@ int poslo = (position & 0xFFFF);\ int firidx = ((poslo + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK; \ int vol = (windowed_fir_lut[firidx + 0] * (int)p[poshi + 1 - 4]); \ - vol += (windowed_fir_lut[firidx + 1] * (int)p[poshi + 2 - 4]); \ - vol += (windowed_fir_lut[firidx + 2] * (int)p[poshi + 3 - 4]); \ - vol += (windowed_fir_lut[firidx + 3] * (int)p[poshi + 4 - 4]); \ - vol += (windowed_fir_lut[firidx + 4] * (int)p[poshi + 5 - 4]); \ - vol += (windowed_fir_lut[firidx + 5] * (int)p[poshi + 6 - 4]); \ - vol += (windowed_fir_lut[firidx + 6] * (int)p[poshi + 7 - 4]); \ - vol += (windowed_fir_lut[firidx + 7] * (int)p[poshi + 8 - 4]); \ - vol >>= WFIR_8SHIFT; + vol += (windowed_fir_lut[firidx + 1] * (int)p[poshi + 2 - 4]); \ + vol += (windowed_fir_lut[firidx + 2] * (int)p[poshi + 3 - 4]); \ + vol += (windowed_fir_lut[firidx + 3] * (int)p[poshi + 4 - 4]); \ + vol += (windowed_fir_lut[firidx + 4] * (int)p[poshi + 5 - 4]); \ + vol += (windowed_fir_lut[firidx + 5] * (int)p[poshi + 6 - 4]); \ + vol += (windowed_fir_lut[firidx + 6] * (int)p[poshi + 7 - 4]); \ + vol += (windowed_fir_lut[firidx + 7] * (int)p[poshi + 8 - 4]); \ + vol >>= WFIR_8SHIFT; #define SNDMIX_GETMONOVOL16FIRFILTER \ @@ -206,13 +206,13 @@ int poslo = (position & 0xFFFF);\ int firidx = ((poslo + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK; \ int vol1 = (windowed_fir_lut[firidx + 0] * (int)p[poshi + 1 - 4]); \ - vol1 += (windowed_fir_lut[firidx + 1] * (int)p[poshi + 2 - 4]); \ - vol1 += (windowed_fir_lut[firidx + 2] * (int)p[poshi + 3 - 4]); \ - vol1 += (windowed_fir_lut[firidx + 3] * (int)p[poshi + 4 - 4]); \ + vol1 += (windowed_fir_lut[firidx + 1] * (int)p[poshi + 2 - 4]); \ + vol1 += (windowed_fir_lut[firidx + 2] * (int)p[poshi + 3 - 4]); \ + vol1 += (windowed_fir_lut[firidx + 3] * (int)p[poshi + 4 - 4]); \ int vol2 = (windowed_fir_lut[firidx + 4] * (int)p[poshi + 5 - 4]); \ - vol2 += (windowed_fir_lut[firidx + 5] * (int)p[poshi + 6 - 4]); \ - vol2 += (windowed_fir_lut[firidx + 6] * (int)p[poshi + 7 - 4]); \ - vol2 += (windowed_fir_lut[firidx + 7] * (int)p[poshi + 8 - 4]); \ + vol2 += (windowed_fir_lut[firidx + 5] * (int)p[poshi + 6 - 4]); \ + vol2 += (windowed_fir_lut[firidx + 6] * (int)p[poshi + 7 - 4]); \ + vol2 += (windowed_fir_lut[firidx + 7] * (int)p[poshi + 8 - 4]); \ int vol = ((vol1 >> 1) + (vol2 >> 1)) >> (WFIR_16BITSHIFT - 1); @@ -254,26 +254,26 @@ int poshi = position >> 16; \ int poslo = (position >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \ int vol_l = (cubic_spline_lut[poslo ] * (int)p[(poshi - 1) * 2 ] + \ - cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 ] + \ - cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 ] + \ - cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 ]) >> SPLINE_8SHIFT; \ + cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 ] + \ + cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 ] + \ + cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 ]) >> SPLINE_8SHIFT; \ int vol_r = (cubic_spline_lut[poslo ] * (int)p[(poshi - 1) * 2 + 1] + \ - cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 + 1] + \ - cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 + 1] + \ - cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 + 1]) >> SPLINE_8SHIFT; + cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 + 1] + \ + cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 + 1] + \ + cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 + 1]) >> SPLINE_8SHIFT; #define SNDMIX_GETSTEREOVOL16SPLINE \ int poshi = position >> 16; \ int poslo = (position >> SPLINE_FRACSHIFT) & SPLINE_FRACMASK; \ int vol_l = (cubic_spline_lut[poslo ] * (int)p[(poshi - 1) * 2 ] + \ - cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 ] + \ - cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 ] + \ - cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 ]) >> SPLINE_16SHIFT; \ + cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 ] + \ + cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 ] + \ + cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 ]) >> SPLINE_16SHIFT; \ int vol_r = (cubic_spline_lut[poslo ] * (int)p[(poshi - 1) * 2 + 1] + \ - cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 + 1] + \ - cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 + 1] + \ - cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 + 1]) >> SPLINE_16SHIFT; + cubic_spline_lut[poslo + 1] * (int)p[(poshi ) * 2 + 1] + \ + cubic_spline_lut[poslo + 2] * (int)p[(poshi + 1) * 2 + 1] + \ + cubic_spline_lut[poslo + 3] * (int)p[(poshi + 2) * 2 + 1]) >> SPLINE_16SHIFT; // fir interpolation @@ -282,23 +282,23 @@ int poslo = (position & 0xFFFF);\ int firidx = ((poslo + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK; \ int vol_l = (windowed_fir_lut[firidx + 0] * (int)p[(poshi + 1 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2]); \ - vol_l += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2]); \ - vol_l >>= WFIR_8SHIFT; \ + vol_l += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2]); \ + vol_l += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2]); \ + vol_l >>= WFIR_8SHIFT; \ int vol_r = (windowed_fir_lut[firidx + 0] * (int)p[(poshi + 1 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2 + 1]); \ - vol_r += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2 + 1]); \ - vol_r >>= WFIR_8SHIFT; + vol_r += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2 + 1]); \ + vol_r += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2 + 1]); \ + vol_r >>= WFIR_8SHIFT; #define SNDMIX_GETSTEREOVOL16FIRFILTER \ @@ -306,22 +306,22 @@ int poslo = (position & 0xFFFF);\ int firidx = ((poslo + WFIR_FRACHALVE) >> WFIR_FRACSHIFT) & WFIR_FRACMASK; \ int vol1_l = (windowed_fir_lut[firidx + 0] * (int)p[(poshi + 1 - 4) * 2]); \ - vol1_l += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2]); \ - vol1_l += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2]); \ - vol1_l += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2]); \ + vol1_l += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2]); \ + vol1_l += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2]); \ + vol1_l += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2]); \ int vol2_l = (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2]); \ - vol2_l += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2]); \ - vol2_l += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2]); \ - vol2_l += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2]); \ + vol2_l += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2]); \ + vol2_l += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2]); \ + vol2_l += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2]); \ int vol_l = ((vol1_l >> 1) + (vol2_l >> 1)) >> (WFIR_16BITSHIFT - 1); \ int vol1_r = (windowed_fir_lut[firidx + 0] * (int)p[(poshi + 1 - 4) * 2 + 1]); \ - vol1_r += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2 + 1]); \ - vol1_r += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2 + 1]); \ - vol1_r += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2 + 1]); \ + vol1_r += (windowed_fir_lut[firidx + 1] * (int)p[(poshi + 2 - 4) * 2 + 1]); \ + vol1_r += (windowed_fir_lut[firidx + 2] * (int)p[(poshi + 3 - 4) * 2 + 1]); \ + vol1_r += (windowed_fir_lut[firidx + 3] * (int)p[(poshi + 4 - 4) * 2 + 1]); \ int vol2_r = (windowed_fir_lut[firidx + 4] * (int)p[(poshi + 5 - 4) * 2 + 1]); \ - vol2_r += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2 + 1]); \ - vol2_r += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2 + 1]); \ - vol2_r += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2 + 1]); \ + vol2_r += (windowed_fir_lut[firidx + 5] * (int)p[(poshi + 6 - 4) * 2 + 1]); \ + vol2_r += (windowed_fir_lut[firidx + 6] * (int)p[(poshi + 7 - 4) * 2 + 1]); \ + vol2_r += (windowed_fir_lut[firidx + 7] * (int)p[(poshi + 8 - 4) * 2 + 1]); \ int vol_r = ((vol1_r >> 1) + (vol2_r >> 1)) >> (WFIR_16BITSHIFT - 1); @@ -371,13 +371,13 @@ /////////////////////////////////////////////////// // Resonant Filters -#define FILT_CLIP(i) CLAMP(i, -4096, 4095) +#define FILT_CLIP(i) CLAMP(i, -65536, 65534) // Mono #define MIX_BEGIN_FILTER \ - double fy1 = channel->filter_y1; \ - double fy2 = channel->filter_y2; \ - double ta; + int32_t fy1 = channel->filter_y1; \ + int32_t fy2 = channel->filter_y2; \ + int32_t ta; #define MIX_END_FILTER \ @@ -386,20 +386,20 @@ #define SNDMIX_PROCESSFILTER \ - ta = ((double)vol * chan->filter_a0 + fy1 * (chan->filter_b0 + chan->filter_b1) \ - + FILT_CLIP((fy2-fy1) * chan->filter_b1)); \ + ta = (vol * chan->filter_a0 + FILT_CLIP(fy1) * chan->filter_b0 + FILT_CLIP(fy2) * chan->filter_b1 \ + + (1 << (FILTERPRECISION - 1))) >> FILTERPRECISION; \ fy2 = fy1; \ fy1 = ta; \ - vol = (int)ta; + vol = ta; // Stereo #define MIX_BEGIN_STEREO_FILTER \ - double fy1 = channel->filter_y1; \ - double fy2 = channel->filter_y2; \ - double fy3 = channel->filter_y3; \ - double fy4 = channel->filter_y4; \ - double ta, tb; + int32_t fy1 = channel->filter_y1; \ + int32_t fy2 = channel->filter_y2; \ + int32_t fy3 = channel->filter_y3; \ + int32_t fy4 = channel->filter_y4; \ + int32_t ta, tb; #define MIX_END_STEREO_FILTER \ @@ -410,12 +410,12 @@ #define SNDMIX_PROCESSSTEREOFILTER \ - ta = ((double)vol_l * chan->filter_a0 + fy1 * (chan->filter_b0 + chan->filter_b1) \ - + FILT_CLIP((fy2-fy1) * chan->filter_b1)); \ - tb = ((double)vol_r * chan->filter_a0 + fy3 * (chan->filter_b0 + chan->filter_b1) \ - + FILT_CLIP((fy4-fy3) * chan->filter_b1)); \ - fy2 = fy1; fy1 = ta; vol_l = (int) ta; \ - fy4 = fy3; fy3 = tb; vol_r = (int) tb; + ta = (vol_l * chan->filter_a0 + FILT_CLIP(fy1) * chan->filter_b0 + FILT_CLIP(fy2) * chan->filter_b1 \ + + (1 << (FILTERPRECISION - 1))) >> FILTERPRECISION; \ + tb = (vol_r * chan->filter_a0 + FILT_CLIP(fy3) * chan->filter_b0 + FILT_CLIP(fy4) * chan->filter_b1 \ + + (1 << (FILTERPRECISION - 1))) >> FILTERPRECISION; \ + fy2 = fy1; fy1 = ta; vol_l = ta; \ + fy4 = fy3; fy3 = tb; vol_r = tb; ////////////////////////////////////////////////////////// @@ -427,41 +427,41 @@ #define BEGIN_MIX_INTERFACE(func) \ static void func(song_voice_t *channel, int *pbuffer, int *pbufmax) \ { \ - int position; + int position; #define END_MIX_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ + SNDMIX_ENDSAMPLELOOP \ } // Volume Ramps #define BEGIN_RAMPMIX_INTERFACE(func) \ BEGIN_MIX_INTERFACE(func) \ - int right_ramp_volume = channel->right_ramp_volume; \ - int left_ramp_volume = channel->left_ramp_volume; + int right_ramp_volume = channel->right_ramp_volume; \ + int left_ramp_volume = channel->left_ramp_volume; #define END_RAMPMIX_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - channel->right_ramp_volume = right_ramp_volume; \ - channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ - channel->left_ramp_volume = left_ramp_volume; \ - channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ + SNDMIX_ENDSAMPLELOOP \ + channel->right_ramp_volume = right_ramp_volume; \ + channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ + channel->left_ramp_volume = left_ramp_volume; \ + channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ } #define BEGIN_FASTRAMPMIX_INTERFACE(func) \ BEGIN_MIX_INTERFACE(func) \ - int right_ramp_volume = channel->right_ramp_volume; + int right_ramp_volume = channel->right_ramp_volume; #define END_FASTRAMPMIX_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - channel->right_ramp_volume = right_ramp_volume; \ - channel->left_ramp_volume = right_ramp_volume; \ - channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ - channel->left_volume = channel->right_volume; \ + SNDMIX_ENDSAMPLELOOP \ + channel->right_ramp_volume = right_ramp_volume; \ + channel->left_ramp_volume = right_ramp_volume; \ + channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ + channel->left_volume = channel->right_volume; \ } @@ -472,25 +472,25 @@ #define END_MIX_FLT_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - MIX_END_FILTER \ + SNDMIX_ENDSAMPLELOOP \ + MIX_END_FILTER \ } #define BEGIN_RAMPMIX_FLT_INTERFACE(func) \ BEGIN_MIX_INTERFACE(func) \ - int right_ramp_volume = channel->right_ramp_volume; \ - int left_ramp_volume = channel->left_ramp_volume; \ - MIX_BEGIN_FILTER + int right_ramp_volume = channel->right_ramp_volume; \ + int left_ramp_volume = channel->left_ramp_volume; \ + MIX_BEGIN_FILTER #define END_RAMPMIX_FLT_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - MIX_END_FILTER \ - channel->right_ramp_volume = right_ramp_volume; \ - channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ - channel->left_ramp_volume = left_ramp_volume; \ - channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ + SNDMIX_ENDSAMPLELOOP \ + MIX_END_FILTER \ + channel->right_ramp_volume = right_ramp_volume; \ + channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ + channel->left_ramp_volume = left_ramp_volume; \ + channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ } @@ -501,91 +501,117 @@ #define END_MIX_STFLT_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - MIX_END_STEREO_FILTER \ + SNDMIX_ENDSAMPLELOOP \ + MIX_END_STEREO_FILTER \ } #define BEGIN_RAMPMIX_STFLT_INTERFACE(func) \ BEGIN_MIX_INTERFACE(func) \ - int right_ramp_volume = channel->right_ramp_volume; \ - int left_ramp_volume = channel->left_ramp_volume; \ - MIX_BEGIN_STEREO_FILTER + int right_ramp_volume = channel->right_ramp_volume; \ + int left_ramp_volume = channel->left_ramp_volume; \ + MIX_BEGIN_STEREO_FILTER #define END_RAMPMIX_STFLT_INTERFACE() \ - SNDMIX_ENDSAMPLELOOP \ - MIX_END_STEREO_FILTER \ - channel->right_ramp_volume = right_ramp_volume; \ - channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ - channel->left_ramp_volume = left_ramp_volume; \ - channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ + SNDMIX_ENDSAMPLELOOP \ + MIX_END_STEREO_FILTER \ + channel->right_ramp_volume = right_ramp_volume; \ + channel->right_volume = right_ramp_volume >> VOLUMERAMPPRECISION; \ + channel->left_ramp_volume = left_ramp_volume; \ + channel->left_volume = left_ramp_volume >> VOLUMERAMPPRECISION; \ } +#define BEGIN_RESAMPLE_INTERFACE(func, sampletype, numchannels) \ + void func(sampletype *oldbuf, sampletype *newbuf, unsigned long oldlen, unsigned long newlen) \ + { \ + unsigned long long position = 0; \ + const sampletype *p = oldbuf; \ + sampletype *pvol = newbuf; \ + const sampletype *pbufmax = &newbuf[newlen* numchannels]; \ + unsigned long long increment = (((unsigned long long)oldlen)<<16)/((unsigned long long)newlen); \ + do { + +#define END_RESAMPLE_INTERFACEMONO() \ + *pvol = vol; \ + pvol++; \ + position += increment; \ + } while (pvol < pbufmax); \ + } + +#define END_RESAMPLE_INTERFACESTEREO() \ + pvol[0] = vol_l; \ + pvol[1] = vol_r; \ + pvol += 2; \ + position += increment; \ + } while (pvol < pbufmax); \ + } + + ///////////////////////////////////////////////////// // Mono samples functions BEGIN_MIX_INTERFACE(Mono8BitMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono16BitMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono8BitLinearMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8LINEAR - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8LINEAR + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono16BitLinearMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono8BitSplineMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono16BitSplineMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono8BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Mono16BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_STOREMONOVOL END_MIX_INTERFACE() // Volume Ramps BEGIN_RAMPMIX_INTERFACE(Mono8BitRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono16BitRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono8BitLinearRampMix) @@ -595,33 +621,33 @@ END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono16BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono8BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono16BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono8BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Mono16BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_INTERFACE() @@ -629,202 +655,202 @@ // Fast mono mix for leftvol=rightvol (1 less imul) BEGIN_MIX_INTERFACE(FastMono8BitMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono16BitMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono8BitLinearMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8LINEAR - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8LINEAR + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono16BitLinearMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono8BitSplineMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono16BitSplineMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono8BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(FastMono16BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_STOREFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_STOREFASTMONOVOL END_MIX_INTERFACE() // Fast Ramps BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8LINEAR - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8LINEAR + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono8BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() BEGIN_FASTRAMPMIX_INTERFACE(FastMono16BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_RAMPFASTMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_RAMPFASTMONOVOL END_FASTRAMPMIX_INTERFACE() ////////////////////////////////////////////////////// // Stereo samples BEGIN_MIX_INTERFACE(Stereo8BitMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8NOIDO - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8NOIDO + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo16BitMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16NOIDO - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16NOIDO + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo8BitLinearMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8LINEAR - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8LINEAR + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo16BitLinearMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16LINEAR - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16LINEAR + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo8BitSplineMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8SPLINE - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8SPLINE + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo16BitSplineMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16SPLINE - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16SPLINE + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo8BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8FIRFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8FIRFILTER + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() BEGIN_MIX_INTERFACE(Stereo16BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16FIRFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16FIRFILTER + SNDMIX_STORESTEREOVOL END_MIX_INTERFACE() // Volume Ramps BEGIN_RAMPMIX_INTERFACE(Stereo8BitRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8NOIDO - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8NOIDO + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo16BitRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16NOIDO - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16NOIDO + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo8BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8LINEAR - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8LINEAR + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo16BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16LINEAR - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16LINEAR + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo8BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8SPLINE - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8SPLINE + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo16BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16SPLINE - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16SPLINE + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo8BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8FIRFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8FIRFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() BEGIN_RAMPMIX_INTERFACE(Stereo16BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16FIRFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16FIRFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_INTERFACE() @@ -832,236 +858,265 @@ // Resonant Filter Mix // Mono Filter Mix BEGIN_MIX_FLT_INTERFACE(FilterMono8BitMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono16BitMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono8BitLinearMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8LINEAR - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8LINEAR + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono16BitLinearMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono8BitSplineMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono16BitSplineMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono8BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() BEGIN_MIX_FLT_INTERFACE(FilterMono16BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_PROCESSFILTER - SNDMIX_STOREMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_PROCESSFILTER + SNDMIX_STOREMONOVOL END_MIX_FLT_INTERFACE() // Filter + Ramp BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8NOIDO - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8NOIDO + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16NOIDO - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16NOIDO + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8LINEAR - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8LINEAR + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16LINEAR - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16LINEAR + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8SPLINE - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8SPLINE + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16SPLINE - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16SPLINE + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono8BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETMONOVOL8FIRFILTER - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETMONOVOL8FIRFILTER + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() BEGIN_RAMPMIX_FLT_INTERFACE(FilterMono16BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETMONOVOL16FIRFILTER - SNDMIX_PROCESSFILTER - SNDMIX_RAMPMONOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETMONOVOL16FIRFILTER + SNDMIX_PROCESSFILTER + SNDMIX_RAMPMONOVOL END_RAMPMIX_FLT_INTERFACE() // Stereo Filter Mix BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8NOIDO - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8NOIDO + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16NOIDO - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16NOIDO + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitLinearMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8LINEAR - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8LINEAR + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitLinearMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16LINEAR - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16LINEAR + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitSplineMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8SPLINE - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8SPLINE + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitSplineMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16SPLINE - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16SPLINE + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo8BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8FIRFILTER - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8FIRFILTER + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() BEGIN_MIX_STFLT_INTERFACE(FilterStereo16BitFirFilterMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16FIRFILTER - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_STORESTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16FIRFILTER + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_STORESTEREOVOL END_MIX_STFLT_INTERFACE() // Stereo Filter + Ramp BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8NOIDO - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8NOIDO + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16NOIDO - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16NOIDO + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8LINEAR - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8LINEAR + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitLinearRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16LINEAR - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16LINEAR + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8SPLINE - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8SPLINE + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitSplineRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16SPLINE - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16SPLINE + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo8BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP8 - SNDMIX_GETSTEREOVOL8FIRFILTER - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP8 + SNDMIX_GETSTEREOVOL8FIRFILTER + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() BEGIN_RAMPMIX_STFLT_INTERFACE(FilterStereo16BitFirFilterRampMix) - SNDMIX_BEGINSAMPLELOOP16 - SNDMIX_GETSTEREOVOL16FIRFILTER - SNDMIX_PROCESSSTEREOFILTER - SNDMIX_RAMPSTEREOVOL + SNDMIX_BEGINSAMPLELOOP16 + SNDMIX_GETSTEREOVOL16FIRFILTER + SNDMIX_PROCESSSTEREOFILTER + SNDMIX_RAMPSTEREOVOL END_RAMPMIX_STFLT_INTERFACE() + +// Public resampling Methods ( +BEGIN_RESAMPLE_INTERFACE(ResampleMono8BitFirFilter, signed char, 1) + SNDMIX_GETMONOVOL8FIRFILTER + vol >>= (WFIR_16BITSHIFT-WFIR_8SHIFT); //This is used to compensate, since the code assumes that it always outputs to 16bits + vol = CLAMP(vol,-128,127); +END_RESAMPLE_INTERFACEMONO() + +BEGIN_RESAMPLE_INTERFACE(ResampleMono16BitFirFilter, signed short, 1) + SNDMIX_GETMONOVOL16FIRFILTER + vol = CLAMP(vol,-32768,32767); +END_RESAMPLE_INTERFACEMONO() + +BEGIN_RESAMPLE_INTERFACE(ResampleStereo8BitFirFilter, signed char, 2) + SNDMIX_GETSTEREOVOL8FIRFILTER + vol_l >>= (WFIR_16BITSHIFT-WFIR_8SHIFT); //This is used to compensate, since the code assumes that it always outputs to 16bits + vol_r >>= (WFIR_16BITSHIFT-WFIR_8SHIFT); //This is used to compensate, since the code assumes that it always outputs to 16bits + vol_l = CLAMP(vol_l,-128,127); + vol_r = CLAMP(vol_r,-128,127); +END_RESAMPLE_INTERFACESTEREO() + +BEGIN_RESAMPLE_INTERFACE(ResampleStereo16BitFirFilter, signed short, 2) + SNDMIX_GETSTEREOVOL16FIRFILTER + vol_l = CLAMP(vol_l,-32768,32767); + vol_r = CLAMP(vol_r,-32768,32767); +END_RESAMPLE_INTERFACESTEREO() + + + ///////////////////////////////////////////////////////////////////////////////////// // // Mix function tables @@ -1084,421 +1139,420 @@ // mix_(bits)(m/s)[_filt]_(interp/spline/fir/whatever)[_ramp] static const mix_interface_t mix_functions[2 * 2 * 16] = { - // No SRC - Mono8BitMix, Mono16BitMix, - Stereo8BitMix, Stereo16BitMix, - Mono8BitRampMix, Mono16BitRampMix, - Stereo8BitRampMix, Stereo16BitRampMix, - - // No SRC, Filter - FilterMono8BitMix, FilterMono16BitMix, - FilterStereo8BitMix, FilterStereo16BitMix, - FilterMono8BitRampMix, FilterMono16BitRampMix, - FilterStereo8BitRampMix, FilterStereo16BitRampMix, - - // Linear SRC - Mono8BitLinearMix, Mono16BitLinearMix, - Stereo8BitLinearMix, Stereo16BitLinearMix, - Mono8BitLinearRampMix, Mono16BitLinearRampMix, - Stereo8BitLinearRampMix, Stereo16BitLinearRampMix, - - // Linear SRC, Filter - FilterMono8BitLinearMix, FilterMono16BitLinearMix, - FilterStereo8BitLinearMix, FilterStereo16BitLinearMix, - FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix, - FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix, - - // FirFilter SRC - Mono8BitSplineMix, Mono16BitSplineMix, - Stereo8BitSplineMix, Stereo16BitSplineMix, - Mono8BitSplineRampMix, Mono16BitSplineRampMix, - Stereo8BitSplineRampMix, Stereo16BitSplineRampMix, - - // Spline SRC, Filter - FilterMono8BitSplineMix, FilterMono16BitSplineMix, - FilterStereo8BitSplineMix, FilterStereo16BitSplineMix, - FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix, - FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix, - - // FirFilter SRC - Mono8BitFirFilterMix, Mono16BitFirFilterMix, - Stereo8BitFirFilterMix, Stereo16BitFirFilterMix, - Mono8BitFirFilterRampMix, Mono16BitFirFilterRampMix, - Stereo8BitFirFilterRampMix, Stereo16BitFirFilterRampMix, - - // FirFilter SRC, Filter - FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, - FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix, - FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix, - FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix + // No SRC + Mono8BitMix, Mono16BitMix, + Stereo8BitMix, Stereo16BitMix, + Mono8BitRampMix, Mono16BitRampMix, + Stereo8BitRampMix, Stereo16BitRampMix, + + // No SRC, Filter + FilterMono8BitMix, FilterMono16BitMix, + FilterStereo8BitMix, FilterStereo16BitMix, + FilterMono8BitRampMix, FilterMono16BitRampMix, + FilterStereo8BitRampMix, FilterStereo16BitRampMix, + + // Linear SRC + Mono8BitLinearMix, Mono16BitLinearMix, + Stereo8BitLinearMix, Stereo16BitLinearMix, + Mono8BitLinearRampMix, Mono16BitLinearRampMix, + Stereo8BitLinearRampMix, Stereo16BitLinearRampMix, + + // Linear SRC, Filter + FilterMono8BitLinearMix, FilterMono16BitLinearMix, + FilterStereo8BitLinearMix, FilterStereo16BitLinearMix, + FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix, + FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix, + + // Spline SRC + Mono8BitSplineMix, Mono16BitSplineMix, + Stereo8BitSplineMix, Stereo16BitSplineMix, + Mono8BitSplineRampMix, Mono16BitSplineRampMix, + Stereo8BitSplineRampMix, Stereo16BitSplineRampMix, + + // Spline SRC, Filter + FilterMono8BitSplineMix, FilterMono16BitSplineMix, + FilterStereo8BitSplineMix, FilterStereo16BitSplineMix, + FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix, + FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix, + + // FirFilter SRC + Mono8BitFirFilterMix, Mono16BitFirFilterMix, + Stereo8BitFirFilterMix, Stereo16BitFirFilterMix, + Mono8BitFirFilterRampMix, Mono16BitFirFilterRampMix, + Stereo8BitFirFilterRampMix, Stereo16BitFirFilterRampMix, + + // FirFilter SRC, Filter + FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, + FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix, + FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix, + FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix }; static const mix_interface_t fastmix_functions[2 * 2 * 16] = { - // No SRC - FastMono8BitMix, FastMono16BitMix, - Stereo8BitMix, Stereo16BitMix, - FastMono8BitRampMix, FastMono16BitRampMix, - Stereo8BitRampMix, Stereo16BitRampMix, - - // No SRC, Filter - FilterMono8BitMix, FilterMono16BitMix, - FilterStereo8BitMix, FilterStereo16BitMix, - FilterMono8BitRampMix, FilterMono16BitRampMix, - FilterStereo8BitRampMix, FilterStereo16BitRampMix, - - // Linear SRC - FastMono8BitLinearMix, FastMono16BitLinearMix, - Stereo8BitLinearMix, Stereo16BitLinearMix, - FastMono8BitLinearRampMix, FastMono16BitLinearRampMix, - Stereo8BitLinearRampMix, Stereo16BitLinearRampMix, - - // Linear SRC, Filter - FilterMono8BitLinearMix, FilterMono16BitLinearMix, - FilterStereo8BitLinearMix, FilterStereo16BitLinearMix, - FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix, - FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix, - - // Spline SRC - FastMono8BitSplineMix, FastMono16BitSplineMix, - Stereo8BitSplineMix, Stereo16BitSplineMix, - FastMono8BitSplineRampMix, FastMono16BitSplineRampMix, - Stereo8BitSplineRampMix, Stereo16BitSplineRampMix, - - // Spline SRC, Filter - FilterMono8BitSplineMix, FilterMono16BitSplineMix, - FilterStereo8BitSplineMix, FilterStereo16BitSplineMix, - FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix, - FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix, - - // FirFilter SRC - FastMono8BitFirFilterMix, FastMono16BitFirFilterMix, - Stereo8BitFirFilterMix, Stereo16BitFirFilterMix, - FastMono8BitFirFilterRampMix, FastMono16BitFirFilterRampMix, - Stereo8BitFirFilterRampMix, Stereo16BitFirFilterRampMix, - - // FirFilter SRC, Filter - FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, - FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix, - FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix, - FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix, + // No SRC + FastMono8BitMix, FastMono16BitMix, + Stereo8BitMix, Stereo16BitMix, + FastMono8BitRampMix, FastMono16BitRampMix, + Stereo8BitRampMix, Stereo16BitRampMix, + + // No SRC, Filter + FilterMono8BitMix, FilterMono16BitMix, + FilterStereo8BitMix, FilterStereo16BitMix, + FilterMono8BitRampMix, FilterMono16BitRampMix, + FilterStereo8BitRampMix, FilterStereo16BitRampMix, + + // Linear SRC + FastMono8BitLinearMix, FastMono16BitLinearMix, + Stereo8BitLinearMix, Stereo16BitLinearMix, + FastMono8BitLinearRampMix, FastMono16BitLinearRampMix, + Stereo8BitLinearRampMix, Stereo16BitLinearRampMix, + + // Linear SRC, Filter + FilterMono8BitLinearMix, FilterMono16BitLinearMix, + FilterStereo8BitLinearMix, FilterStereo16BitLinearMix, + FilterMono8BitLinearRampMix, FilterMono16BitLinearRampMix, + FilterStereo8BitLinearRampMix, FilterStereo16BitLinearRampMix, + + // Spline SRC + FastMono8BitSplineMix, FastMono16BitSplineMix, + Stereo8BitSplineMix, Stereo16BitSplineMix, + FastMono8BitSplineRampMix, FastMono16BitSplineRampMix, + Stereo8BitSplineRampMix, Stereo16BitSplineRampMix, + + // Spline SRC, Filter + FilterMono8BitSplineMix, FilterMono16BitSplineMix, + FilterStereo8BitSplineMix, FilterStereo16BitSplineMix, + FilterMono8BitSplineRampMix, FilterMono16BitSplineRampMix, + FilterStereo8BitSplineRampMix, FilterStereo16BitSplineRampMix, + + // FirFilter SRC + FastMono8BitFirFilterMix, FastMono16BitFirFilterMix, + Stereo8BitFirFilterMix, Stereo16BitFirFilterMix, + FastMono8BitFirFilterRampMix, FastMono16BitFirFilterRampMix, + Stereo8BitFirFilterRampMix, Stereo16BitFirFilterRampMix, + + // FirFilter SRC, Filter + FilterMono8BitFirFilterMix, FilterMono16BitFirFilterMix, + FilterStereo8BitFirFilterMix, FilterStereo16BitFirFilterMix, + FilterMono8BitFirFilterRampMix, FilterMono16BitFirFilterRampMix, + FilterStereo8BitFirFilterRampMix, FilterStereo16BitFirFilterRampMix, }; static int get_sample_count(song_voice_t *chan, int samples) { - int loop_start = (chan->flags & CHN_LOOP) ? chan->loop_start : 0; - int increment = chan->increment; + int loop_start = (chan->flags & CHN_LOOP) ? chan->loop_start : 0; + int increment = chan->increment; - if (samples <= 0 || !increment || !chan->length) - return 0; + if (samples <= 0 || !increment || !chan->length) + return 0; - // Under zero ? - if ((int) chan->position < loop_start) { - if (increment < 0) { - // Invert loop for bidi loops - int delta = ((loop_start - chan->position) << 16) - (chan->position_frac & 0xFFFF); - chan->position = loop_start | (delta >> 16); - chan->position_frac = delta & 0xFFFF; - - if ((int) chan->position < loop_start || - chan->position >= (loop_start + chan->length) / 2) { - chan->position = loop_start; - chan->position_frac = 0; - } - - increment = -increment; - chan->increment = increment; - // go forward - chan->flags &= ~(CHN_PINGPONGFLAG); - - if ((!(chan->flags & CHN_LOOP)) || - (chan->position >= chan->length)) { - chan->position = chan->length; - chan->position_frac = 0; - return 0; - } - } - else { - // We probably didn't hit the loop end yet (first loop), so we do nothing - if ((int) chan->position < 0) - chan->position = 0; - } - } - // Past the end - else if (chan->position >= chan->length) { - // not looping -> stop this channel - if (!(chan->flags & CHN_LOOP)) - return 0; - - if (chan->flags & CHN_PINGPONGLOOP) { - // Invert loop - if (increment > 0) { - increment = -increment; - chan->increment = increment; - } - - chan->flags |= CHN_PINGPONGFLAG; - // adjust loop position - int delta_hi = (chan->position - chan->length); - int delta_lo = 0x10000 - (chan->position_frac & 0xFFFF); - chan->position = chan->length - delta_hi - (delta_lo >> 16); - chan->position_frac = delta_lo & 0xFFFF; - - if (chan->position <= chan->loop_start || chan->position >= chan->length) - chan->position = chan->length - PINGPONG_OFFSET; - } - else { - // This is a bug - if (increment < 0) { - increment = -increment; - chan->increment = increment; - } - - // Restart at loop start - chan->position += loop_start - chan->length; - - if ((int) chan->position < loop_start) - chan->position = chan->loop_start; - } - } - - int position = chan->position; - - // too big increment, and/or too small loop length - if (position < loop_start) { - if (position < 0 || increment < 0) - return 0; - } - - if (position < 0 || position >= (int) chan->length) - return 0; - - int position_frac = (unsigned short) chan->position_frac, - sample_count = samples; - - if (increment < 0) { - int inv = -increment; - int maxsamples = 16384 / ((inv >> 16) + 1); - - if (maxsamples < 2) - maxsamples = 2; - - if (samples > maxsamples) - samples = maxsamples; - - int delta_hi = (inv >> 16) * (samples - 1); - int delta_lo = (inv & 0xffff) * (samples - 1); - int pos_dest = position - delta_hi + ((position_frac - delta_lo) >> 16); - - if (pos_dest < loop_start) { - sample_count = - (unsigned int) (((((long long) position - - loop_start) << 16) + position_frac - - 1) / inv) + 1; - } - } - else { - int maxsamples = 16384 / ((increment >> 16) + 1); - - if (maxsamples < 2) - maxsamples = 2; - - if (samples > maxsamples) - samples = maxsamples; - - int delta_hi = (increment >> 16) * (samples - 1); - int delta_lo = (increment & 0xffff) * (samples - 1); - int pos_dest = position + delta_hi + ((position_frac + delta_lo) >> 16); - - if (pos_dest >= (int) chan->length) { - sample_count = (unsigned int) - (((((long long) chan->length - position) << 16) - position_frac - 1) / increment) + 1; - } - } - - if (sample_count <= 1) - return 1; - else if (sample_count > samples) - return samples; + // Under zero ? + if ((int) chan->position < loop_start) { + if (increment < 0) { + // Invert loop for bidi loops + int delta = ((loop_start - chan->position) << 16) - (chan->position_frac & 0xFFFF); + chan->position = loop_start + (delta >> 16); + chan->position_frac = delta & 0xFFFF; + + if ((int) chan->position < loop_start || + chan->position >= (loop_start + chan->length) / 2) { + chan->position = loop_start; + chan->position_frac = 0; + } + + increment = -increment; + chan->increment = increment; + // go forward + chan->flags &= ~(CHN_PINGPONGFLAG); + + if ((!(chan->flags & CHN_LOOP)) || + (chan->position >= chan->length)) { + chan->position = chan->length; + chan->position_frac = 0; + return 0; + } + } + else { + // We probably didn't hit the loop end yet (first loop), so we do nothing + if ((int) chan->position < 0) + chan->position = 0; + } + } + // Past the end + else if (chan->position >= chan->length) { + // not looping -> stop this channel + if (!(chan->flags & CHN_LOOP)) + return 0; + + if (chan->flags & CHN_PINGPONGLOOP) { + // Invert loop + if (increment > 0) { + increment = -increment; + chan->increment = increment; + } + + chan->flags |= CHN_PINGPONGFLAG; + // adjust loop position + int delta_hi = (chan->position - chan->length); + int delta_lo = 0x10000 - (chan->position_frac & 0xFFFF); + chan->position = chan->length - delta_hi - (delta_lo >> 16); + chan->position_frac = delta_lo & 0xFFFF; + + if (chan->position <= chan->loop_start || chan->position >= chan->length) + chan->position = chan->length - PINGPONG_OFFSET; + } + else { + // This is a bug + if (increment < 0) { + increment = -increment; + chan->increment = increment; + } + + // Restart at loop start + chan->position += loop_start - chan->length; + + if ((int) chan->position < loop_start) + chan->position = chan->loop_start; + } + } + + int position = chan->position; + + // too big increment, and/or too small loop length + if (position < loop_start) { + if (position < 0 || increment < 0) + return 0; + } + + if (position < 0 || position >= (int) chan->length) + return 0; + + int position_frac = (unsigned short) chan->position_frac, + sample_count = samples; + + if (increment < 0) { + int inv = -increment; + int maxsamples = 16384 / ((inv >> 16) + 1); + + if (maxsamples < 2) + maxsamples = 2; + + if (samples > maxsamples) + samples = maxsamples; + + int delta_hi = (inv >> 16) * (samples - 1); + int delta_lo = (inv & 0xffff) * (samples - 1); + int pos_dest = position - delta_hi + ((position_frac - delta_lo) >> 16); + + if (pos_dest < loop_start) { + sample_count = + (unsigned int) (((((long long) position - + loop_start) << 16) + position_frac - + 1) / inv) + 1; + } + } + else { + int maxsamples = 16384 / ((increment >> 16) + 1); + + if (maxsamples < 2) + maxsamples = 2; + + if (samples > maxsamples) + samples = maxsamples; + + int delta_hi = (increment >> 16) * (samples - 1); + int delta_lo = (increment & 0xffff) * (samples - 1); + int pos_dest = position + delta_hi + ((position_frac + delta_lo) >> 16); + + if (pos_dest >= (int) chan->length) { + sample_count = (unsigned int) + (((((long long) chan->length - position) << 16) - position_frac - 1) / increment) + 1; + } + } + + if (sample_count <= 1) + return 1; + else if (sample_count > samples) + return samples; - return sample_count; + return sample_count; } unsigned int csf_create_stereo_mix(song_t *csf, int count) { - int* ofsl, *ofsr; - unsigned int nchused, nchmixed; + int* ofsl, *ofsr; + unsigned int nchused, nchmixed; - if (!count) - return 0; + if (!count) + return 0; - nchused = nchmixed = 0; + nchused = nchmixed = 0; - // yuck - if (csf->multi_write) - for (unsigned int nchan = 0; nchan < MAX_CHANNELS; nchan++) - memset(csf->multi_write[nchan].buffer, 0, sizeof(csf->multi_write[nchan].buffer)); - - for (unsigned int nchan = 0; nchan < csf->num_voices; nchan++) { - const mix_interface_t *mix_func_table; - song_voice_t *const channel = &csf->voices[csf->voice_mix[nchan]]; - unsigned int flags; - unsigned int nrampsamples; - int smpcount; - int nsamples; - int *pbuffer; - - if (!channel->current_sample_data) - continue; - - ofsr = &g_dry_rofs_vol; - ofsl = &g_dry_lofs_vol; - flags = 0; - - if (channel->flags & CHN_16BIT) - flags |= MIXNDX_16BIT; - - if (channel->flags & CHN_STEREO) - flags |= MIXNDX_STEREO; - - if (channel->flags & CHN_FILTER) - flags |= MIXNDX_FILTER; - - if (!(channel->flags & CHN_NOIDO) && - !(csf->mix_flags & SNDMIX_NORESAMPLING)) { - // use hq-fir mixer? - if ((csf->mix_flags & (SNDMIX_HQRESAMPLER | SNDMIX_ULTRAHQSRCMODE)) - == (SNDMIX_HQRESAMPLER | SNDMIX_ULTRAHQSRCMODE)) - flags |= MIXNDX_FIRSRC; - else if (csf->mix_flags & SNDMIX_HQRESAMPLER) - flags |= MIXNDX_SPLINESRC; - else - flags |= MIXNDX_LINEARSRC; // use - } - - if ((flags < 0x40) && - (channel->left_volume == channel->right_volume) && - ((!channel->ramp_length) || - (channel->left_ramp == channel->right_ramp))) { - mix_func_table = fastmix_functions; - } else { - mix_func_table = mix_functions; - } - - nsamples = count; - - if (csf->multi_write) { - int master = (csf->voice_mix[nchan] < MAX_CHANNELS) - ? csf->voice_mix[nchan] - : (channel->master_channel - 1); - pbuffer = csf->multi_write[master].buffer; - csf->multi_write[master].used = 1; - } else { - pbuffer = csf->mix_buffer; - } - - nchused++; - //////////////////////////////////////////////////// - unsigned int naddmix = 0; - - do { - nrampsamples = nsamples; - - if (channel->ramp_length > 0) { - if ((int) nrampsamples > channel->ramp_length) - nrampsamples = channel->ramp_length; - } - - smpcount = 1; - - /* Figure out the number of remaining samples, - * unless we're in AdLib or MIDI mode (to prevent - * artificial KeyOffs) - */ - if (!(channel->flags & CHN_ADLIB)) { - smpcount = get_sample_count(channel, nrampsamples); - } - - if (smpcount <= 0) { - // Stopping the channel - channel->current_sample_data = NULL; - channel->length = 0; - channel->position = 0; - channel->position_frac = 0; - channel->ramp_length = 0; - end_channel_ofs(channel, pbuffer, nsamples); - *ofsr += channel->rofs; - *ofsl += channel->lofs; - channel->rofs = channel->lofs = 0; - channel->flags &= ~CHN_PINGPONGFLAG; - break; - } - - // Should we mix this channel ? - - if ((nchmixed >= max_voices && !(csf->mix_flags & SNDMIX_DIRECTTODISK)) - || (!channel->ramp_length && !(channel->left_volume | channel->right_volume))) { - int delta = (channel->increment * (int) smpcount) + (int) channel->position_frac; - channel->position_frac = delta & 0xFFFF; - channel->position += (delta >> 16); - channel->rofs = channel->lofs = 0; - pbuffer += smpcount * 2; - } else { - // Do mixing - - /* Mix the stream, unless we're in AdLib mode */ - if (!(channel->flags & CHN_ADLIB)) { - // Choose function for mixing - mix_interface_t mix_func; - mix_func = channel->ramp_length - ? mix_func_table[flags | MIXNDX_RAMP] - : mix_func_table[flags]; - int *pbufmax = pbuffer + (smpcount * 2); - channel->rofs = -*(pbufmax - 2); - channel->lofs = -*(pbufmax - 1); - - mix_func(channel, pbuffer, pbufmax); - channel->rofs += *(pbufmax - 2); - channel->lofs += *(pbufmax - 1); - pbuffer = pbufmax; - naddmix = 1; - } - } - - nsamples -= smpcount; - - if (channel->ramp_length) { - channel->ramp_length -= smpcount; - if (channel->ramp_length <= 0) { - channel->ramp_length = 0; - channel->right_volume = channel->right_volume_new; - channel->left_volume = channel->left_volume_new; - channel->right_ramp = channel->left_ramp = 0; - - if ((channel->flags & CHN_NOTEFADE) - && (!(channel->fadeout_volume))) { - channel->length = 0; - channel->current_sample_data = NULL; - } - } - } - - } while (nsamples > 0); - - nchmixed += naddmix; - } - - GM_IncrementSongCounter(count); - - if (csf->multi_write) { - /* mix all adlib onto track one */ - Fmdrv_MixTo(csf->multi_write[0].buffer, count); - } else { - Fmdrv_MixTo(csf->mix_buffer, count); - } + // yuck + if (csf->multi_write) + for (unsigned int nchan = 0; nchan < MAX_CHANNELS; nchan++) + memset(csf->multi_write[nchan].buffer, 0, sizeof(csf->multi_write[nchan].buffer)); + + for (unsigned int nchan = 0; nchan < csf->num_voices; nchan++) { + const mix_interface_t *mix_func_table; + song_voice_t *const channel = &csf->voices[csf->voice_mix[nchan]]; + unsigned int flags; + unsigned int nrampsamples; + int smpcount; + int nsamples; + int *pbuffer; + + if (!channel->current_sample_data) + continue; + + ofsr = &g_dry_rofs_vol; + ofsl = &g_dry_lofs_vol; + flags = 0; + + if (channel->flags & CHN_16BIT) + flags |= MIXNDX_16BIT; + + if (channel->flags & CHN_STEREO) + flags |= MIXNDX_STEREO; + + if (channel->flags & CHN_FILTER) + flags |= MIXNDX_FILTER; + + if (!(channel->flags & CHN_NOIDO) && + !(csf->mix_flags & SNDMIX_NORESAMPLING)) { + // use hq-fir mixer? + if ((csf->mix_flags & (SNDMIX_HQRESAMPLER | SNDMIX_ULTRAHQSRCMODE)) + == (SNDMIX_HQRESAMPLER | SNDMIX_ULTRAHQSRCMODE)) + flags |= MIXNDX_FIRSRC; + else if (csf->mix_flags & SNDMIX_HQRESAMPLER) + flags |= MIXNDX_SPLINESRC; + else + flags |= MIXNDX_LINEARSRC; // use + } + + if ((flags < 0x40) && + (channel->left_volume == channel->right_volume) && + ((!channel->ramp_length) || + (channel->left_ramp == channel->right_ramp))) { + mix_func_table = fastmix_functions; + } else { + mix_func_table = mix_functions; + } + + nsamples = count; + + if (csf->multi_write) { + int master = (csf->voice_mix[nchan] < MAX_CHANNELS) + ? csf->voice_mix[nchan] + : (channel->master_channel - 1); + pbuffer = csf->multi_write[master].buffer; + csf->multi_write[master].used = 1; + } else { + pbuffer = csf->mix_buffer; + } + + nchused++; + //////////////////////////////////////////////////// + unsigned int naddmix = 0; + + do { + nrampsamples = nsamples; + + if (channel->ramp_length > 0) { + if ((int) nrampsamples > channel->ramp_length) + nrampsamples = channel->ramp_length; + } + + smpcount = 1; + + /* Figure out the number of remaining samples, + * unless we're in AdLib or MIDI mode (to prevent + * artificial KeyOffs) + */ + if (!(channel->flags & CHN_ADLIB)) { + smpcount = get_sample_count(channel, nrampsamples); + } + + if (smpcount <= 0) { + // Stopping the channel + channel->current_sample_data = NULL; + channel->length = 0; + channel->position = 0; + channel->position_frac = 0; + channel->ramp_length = 0; + end_channel_ofs(channel, pbuffer, nsamples); + *ofsr += channel->rofs; + *ofsl += channel->lofs; + channel->rofs = channel->lofs = 0; + channel->flags &= ~CHN_PINGPONGFLAG; + break; + } + + // Should we mix this channel ? + + if ((nchmixed >= max_voices && !(csf->mix_flags & SNDMIX_DIRECTTODISK)) + || (!channel->ramp_length && !(channel->left_volume | channel->right_volume))) { + int delta = (channel->increment * (int) smpcount) + (int) channel->position_frac; + channel->position_frac = delta & 0xFFFF; + channel->position += (delta >> 16); + channel->rofs = channel->lofs = 0; + pbuffer += smpcount * 2; + } else { + // Do mixing + + /* Mix the stream, unless we're in AdLib mode */ + if (!(channel->flags & CHN_ADLIB)) { + // Choose function for mixing + mix_interface_t mix_func; + mix_func = channel->ramp_length + ? mix_func_table[flags | MIXNDX_RAMP] + : mix_func_table[flags]; + int *pbufmax = pbuffer + (smpcount * 2); + channel->rofs = -*(pbufmax - 2); + channel->lofs = -*(pbufmax - 1); + + mix_func(channel, pbuffer, pbufmax); + channel->rofs += *(pbufmax - 2); + channel->lofs += *(pbufmax - 1); + pbuffer = pbufmax; + naddmix = 1; + } + } + + nsamples -= smpcount; + + if (channel->ramp_length) { + channel->ramp_length -= smpcount; + if (channel->ramp_length <= 0) { + channel->ramp_length = 0; + channel->right_volume = channel->right_volume_new; + channel->left_volume = channel->left_volume_new; + channel->right_ramp = channel->left_ramp = 0; + + if ((channel->flags & CHN_NOTEFADE) + && (!(channel->fadeout_volume))) { + channel->length = 0; + channel->current_sample_data = NULL; + } + } + } + + } while (nsamples > 0); + + nchmixed += naddmix; + } + + GM_IncrementSongCounter(count); + + if (csf->multi_write) { + /* mix all adlib onto track one */ + Fmdrv_MixTo(csf->multi_write[0].buffer, count); + } else { + Fmdrv_MixTo(csf->mix_buffer, count); + } - return nchused; + return nchused; } - diff -Nru schism-0+20110101/player/mixutil.c schism-20160521/player/mixutil.c --- schism-0+20110101/player/mixutil.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/mixutil.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,18 +43,18 @@ int lofs = *plofs; if (!rofs && !lofs) { - init_mix_buffer(buffer, samples * 2); - return; + init_mix_buffer(buffer, samples * 2); + return; } for (unsigned int i = 0; i < samples; i++) { - int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; - int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; + int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; + int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; - rofs -= x_r; - lofs -= x_l; - buffer[i * 2 ] = x_r; - buffer[i * 2 + 1] = x_l; + rofs -= x_r; + lofs -= x_l; + buffer[i * 2 ] = x_r; + buffer[i * 2 + 1] = x_l; } *profs = rofs; @@ -68,16 +68,16 @@ int lofs = channel->lofs; if (!rofs && !lofs) - return; + return; for (unsigned int i = 0; i < samples; i++) { - int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; - int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; + int x_r = (rofs + (((-rofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; + int x_l = (lofs + (((-lofs) >> 31) & OFSDECAYMASK)) >> OFSDECAYSHIFT; - rofs -= x_r; - lofs -= x_l; - buffer[i * 2] += x_r; - buffer[i * 2 + 1] += x_l; + rofs -= x_r; + lofs -= x_l; + buffer[i * 2] += x_r; + buffer[i * 2 + 1] += x_l; } channel->rofs = rofs; @@ -88,8 +88,8 @@ void mono_from_stereo(int *mix_buf, unsigned int samples) { for (unsigned int j, i = 0; i < samples; i++) { - j = i << 1; - mix_buf[i] = (mix_buf[j] + mix_buf[j + 1]) >> 1; + j = i << 1; + mix_buf[i] = (mix_buf[j] + mix_buf[j + 1]) >> 1; } } @@ -101,11 +101,11 @@ void stereo_mix_to_float(const int *src, float *out1, float *out2, unsigned int count) { for (unsigned int i = 0; i < count; i++) { - *out1++ = *src * i2fc; - src++; + *out1++ = *src * i2fc; + src++; - *out2++ = *src * i2fc; - src++; + *out2++ = *src * i2fc; + src++; } } @@ -113,10 +113,10 @@ void float_to_stereo_mix(const float *in1, const float *in2, int *out, unsigned int count) { for (unsigned int i = 0; i < count; i++) { - *out++ = (int) (*in1 * f2ic); - *out++ = (int) (*in2 * f2ic); - in1++; - in2++; + *out++ = (int) (*in1 * f2ic); + *out++ = (int) (*in2 * f2ic); + in1++; + in2++; } } @@ -124,8 +124,8 @@ void mono_mix_to_float(const int *src, float *out, unsigned int count) { for (unsigned int i = 0; i < count; i++) { - *out++ = *src * i2fc; - src++; + *out++ = *src * i2fc; + src++; } } @@ -133,8 +133,8 @@ void float_to_mono_mix(const float *in, int *out, unsigned int count) { for (unsigned int i = 0; i < count; i++) { - *out++ = (int) (*in * f2ic); - in++; + *out++ = (int) (*in * f2ic); + in++; } } @@ -147,110 +147,112 @@ // The original C version was written by Rani Assaf -// Clip and convert to 8 bit +// Clip and convert to 8 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right. unsigned int clip_32_to_8(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs) { unsigned char *p = (unsigned char *) ptr; for (unsigned int i = 0; i < samples; i++) { - int n = buffer[i]; + int n = buffer[i]; - if (n < MIXING_CLIPMIN) - n = MIXING_CLIPMIN; - else if (n > MIXING_CLIPMAX) - n = MIXING_CLIPMAX; - - if (n < mins[i & 1]) - mins[i & 1] = n; - else if (n > maxs[i & 1]) - maxs[i & 1] = n; + if (n < MIXING_CLIPMIN) + n = MIXING_CLIPMIN; + else if (n > MIXING_CLIPMAX) + n = MIXING_CLIPMAX; + + if (n < mins[i & 1]) + mins[i & 1] = n; + else if (n > maxs[i & 1]) + maxs[i & 1] = n; - // 8-bit unsigned - p[i] = (n >> (24 - MIXING_ATTENUATION)) ^ 0x80; + // 8-bit unsigned + p[i] = (n >> (24 - MIXING_ATTENUATION)) ^ 0x80; } return samples; } +// Clip and convert to 16 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right. unsigned int clip_32_to_16(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs) { signed short *p = (signed short *) ptr; for (unsigned int i = 0; i < samples; i++) { - int n = buffer[i]; + int n = buffer[i]; - if (n < MIXING_CLIPMIN) - n = MIXING_CLIPMIN; - else if (n > MIXING_CLIPMAX) - n = MIXING_CLIPMAX; - - if (n < mins[i & 1]) - mins[i & 1] = n; - else if (n > maxs[i & 1]) - maxs[i & 1] = n; + if (n < MIXING_CLIPMIN) + n = MIXING_CLIPMIN; + else if (n > MIXING_CLIPMAX) + n = MIXING_CLIPMAX; + + if (n < mins[i & 1]) + mins[i & 1] = n; + else if (n > maxs[i & 1]) + maxs[i & 1] = n; - // 16-bit signed - p[i] = n >> (16 - MIXING_ATTENUATION); + // 16-bit signed + p[i] = n >> (16 - MIXING_ATTENUATION); } return samples * 2; } -// 24-bit might not work... +// Clip and convert to 24 bit. mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right. +// Note, this is 24bit, not 24-in-32bits. The former is used in .wav. The latter is used in audio IO unsigned int clip_32_to_24(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs) { /* the inventor of 24bit anything should be shot */ unsigned char *p = (unsigned char *) ptr; for (unsigned int i = 0; i < samples; i++) { - int n = buffer[i]; + int n = buffer[i]; - if (n < MIXING_CLIPMIN) - n = MIXING_CLIPMIN; - else if (n > MIXING_CLIPMAX) - n = MIXING_CLIPMAX; - - if (n < mins[i & 1]) - mins[i & 1] = n; - else if (n > maxs[i & 1]) - maxs[i & 1] = n; - - // 24-bit signed - n = n >> (8 - MIXING_ATTENUATION); - - /* err, assume same endian */ - memcpy(p, &n, 3); - p += 3; + if (n < MIXING_CLIPMIN) + n = MIXING_CLIPMIN; + else if (n > MIXING_CLIPMAX) + n = MIXING_CLIPMAX; + + if (n < mins[i & 1]) + mins[i & 1] = n; + else if (n > maxs[i & 1]) + maxs[i & 1] = n; + + // 24-bit signed + n = n >> (8 - MIXING_ATTENUATION); + + /* err, assume same endian */ + memcpy(p, &n, 3); + p += 3; } - return samples * 2; + return samples * 3; } -// 32-bit might not work... +// Clip and convert to 32 bit(int). mins and maxs returned in 27bits: [MIXING_CLIPMIN..MIXING_CLIPMAX]. mins[0] left, mins[1] right. unsigned int clip_32_to_32(void *ptr, int *buffer, unsigned int samples, int *mins, int *maxs) { signed int *p = (signed int *) ptr; for (unsigned int i = 0; i < samples; i++) { - int n = buffer[i]; + int n = buffer[i]; + + if (n < MIXING_CLIPMIN) + n = MIXING_CLIPMIN; + else if (n > MIXING_CLIPMAX) + n = MIXING_CLIPMAX; - if (n < MIXING_CLIPMIN) - n = MIXING_CLIPMIN; - else if (n > MIXING_CLIPMAX) - n = MIXING_CLIPMAX; - - if (n < mins[i & 1]) - mins[i & 1] = n; - else if (n > maxs[i & 1]) - maxs[i & 1] = n; + if (n < mins[i & 1]) + mins[i & 1] = n; + else if (n > maxs[i & 1]) + maxs[i & 1] = n; - // 32-bit signed - p[i] = (n >> MIXING_ATTENUATION); + // 32-bit signed + p[i] = (n << MIXING_ATTENUATION); } - return samples * 2; + return samples * 4; } diff -Nru schism-0+20110101/player/opl-util.c schism-20160521/player/opl-util.c --- schism-0+20110101/player/opl-util.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/player/opl-util.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,134 @@ +/** + * @file opl-util.cpp + * @brief Utility functions related to OPL chips. + * + * Copyright (C) 2010-2013 Adam Nielsen + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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 . + */ + +//Stripped down version for Schismtracker, in C. + +// this really should be in a header but it's only used in one other file +int fnumToMilliHertz(unsigned int fnum, unsigned int block, + unsigned int conversionFactor); +void milliHertzToFnum(unsigned int milliHertz, + unsigned int *fnum, unsigned int *block, unsigned int conversionFactor); + + +/// Convert the given f-number and block into a note frequency. +/** +* @param fnum +* Input frequency number, between 0 and 1023 inclusive. Values outside this +* range will cause assertion failures. +* +* @param block +* Input block number, between 0 and 7 inclusive. Values outside this range +* will cause assertion failures. +* +* @param conversionFactor +* Conversion factor to use. Normally will be 49716 and occasionally 50000. +* +* @return The converted frequency in milliHertz. +*/ +int fnumToMilliHertz(unsigned int fnum, unsigned int block, + unsigned int conversionFactor) +{ + // Original formula + //return 1000 * conversionFactor * (double)fnum * pow(2, (double)((signed)block - 20)); + + // More efficient version + return (1000ull * conversionFactor * fnum) >> (20 - block); +} +/// Convert a frequency into an OPL f-number +/** +* @param milliHertz +* Input frequency. +* +* @param fnum +* Output frequency number for OPL chip. This is a 10-bit number, so it will +* always be between 0 and 1023 inclusive. +* +* @param block +* Output block number for OPL chip. This is a 3-bit number, so it will +* always be between 0 and 7 inclusive. +* +* @param conversionFactor +* Conversion factor to use. Normally will be 49716 and occasionally 50000. +* +* @post fnum will be set to a value between 0 and 1023 inclusive. block will +* be set to a value between 0 and 7 inclusive. assert() calls inside this +* function ensure this will always be the case. +* +* @note As the block value increases, the frequency difference between two +* adjacent fnum values increases. This means the higher the frequency, +* the less precision is available to represent it. Therefore, converting +* a value to fnum/block and back to milliHertz is not guaranteed to reproduce +* the original value. +*/ +void milliHertzToFnum(unsigned int milliHertz, + unsigned int *fnum, unsigned int *block, unsigned int conversionFactor) +{ + // Special case to avoid divide by zero + if (milliHertz <= 0) { + *block = 0; // actually any block will work + *fnum = 0; + return; + } + + // Special case for frequencies too high to produce + if (milliHertz > 6208431) { + *block = 7; + *fnum = 1023; + return; + } + + /// This formula will provide a pretty good estimate as to the best block to + /// use for a given frequency. It tries to use the lowest possible block + /// number that is capable of representing the given frequency. This is + /// because as the block number increases, the precision decreases (i.e. there + /// are larger steps between adjacent note frequencies.) The 6M constant is + /// the largest frequency (in milliHertz) that can be represented by the + /// block/fnum system. + //int invertedBlock = log2(6208431 / milliHertz); + + // Very low frequencies will produce very high inverted block numbers, but + // as they can all be covered by inverted block 7 (block 0) we can just clip + // the value. + //if (invertedBlock > 7) invertedBlock = 7; + //*block = 7 - invertedBlock; + + // This is a bit more efficient and doesn't need log2() from math.h + if (milliHertz > 3104215) *block = 7; + else if (milliHertz > 1552107) *block = 6; + else if (milliHertz > 776053) *block = 5; + else if (milliHertz > 388026) *block = 4; + else if (milliHertz > 194013) *block = 3; + else if (milliHertz > 97006) *block = 2; + else if (milliHertz > 48503) *block = 1; + else *block = 0; + + // Original formula + //*fnum = milliHertz * pow(2, 20 - *block) / 1000 / conversionFactor + 0.5; + + // Slightly more efficient version + *fnum = ((unsigned long long)milliHertz << (20 - *block)) / (conversionFactor * 1000.0) + 0.5; + + if (*fnum > 1023) { + (*block)++; + *fnum = ((unsigned long long)milliHertz << (20 - *block)) / (conversionFactor * 1000.0) + 0.5; + } + + return; +} diff -Nru schism-0+20110101/player/snd_fm.c schism-20160521/player/snd_fm.c --- schism-0+20110101/player/snd_fm.c 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/player/snd_fm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,11 +30,11 @@ #include #include -#define OPLNew(x,r) YM3812Init(1, (x), (r)) -#define OPLResetChip YM3812ResetChip -#define OPLWrite YM3812Write -#define OPLUpdateOne YM3812UpdateOne -#define OPLClose YM3812Shutdown +#define OPLNew(x,r) ym3812_init(x, r) +#define OPLResetChip ym3812_reset_chip +#define OPLWrite ym3812_write +#define OPLUpdateOne ym3812_update_one +#define OPLClose ym3812_shutdown /* Mostly pulled from my posterior. Original value was 2000, but Manwe says that's too quiet. It'd help if this was at all connected to the song's mixing volume... @@ -46,96 +46,102 @@ including the comment "Don't ask me why", are attributed to Jeffrey S. Lee's article: Programming the AdLib/Sound Blaster - FM Music Chips + FM Music Chips Version 2.0 (24 Feb 1992) */ static const int oplbase = 0x388; // OPL info -static int opl = -1, - oplretval = 0, - oplregno = 0; -static int fm_active = 0; +static struct OPL* opl = NULL; +static UINT32 oplretval = 0, + oplregno = 0; +static UINT32 fm_active = 0; + +extern int fnumToMilliHertz(unsigned int fnum, unsigned int block, + unsigned int conversionFactor); + +extern void milliHertzToFnum(unsigned int milliHertz, + unsigned int *fnum, unsigned int *block, unsigned int conversionFactor); static void Fmdrv_Outportb(unsigned port, unsigned value) { - if (opl < 0 || - ((int) port) < oplbase || - ((int) port) >= oplbase + 4) - return; - - unsigned ind = port - oplbase; - OPLWrite(opl, ind, value); - - if (ind & 1) { - if (oplregno == 4) { - if (value == 0x80) - oplretval = 0x02; - else if (value == 0x21) - oplretval = 0xC0; - } - } - else - oplregno = value; + if (opl == NULL || + ((int) port) < oplbase || + ((int) port) >= oplbase + 4) + return; + + unsigned ind = port - oplbase; + OPLWrite(opl, ind, value); + + if (ind & 1) { + if (oplregno == 4) { + if (value == 0x80) + oplretval = 0x02; + else if (value == 0x21) + oplretval = 0xC0; + } + } + else + oplregno = value; } static unsigned char Fmdrv_Inportb(unsigned port) { - return (((int) port) >= oplbase && - ((int) port) < oplbase + 4) ? oplretval : 0; + return (((int) port) >= oplbase && + ((int) port) < oplbase + 4) ? oplretval : 0; } void Fmdrv_Init(int mixfreq) { - if (opl !=- 1) { - OPLClose(); - opl = -1; - } - - opl = OPLNew(1789772 * 2, mixfreq); - OPLResetChip(opl); - OPL_Detect(); + if (opl != NULL) { + OPLClose(opl); + opl = NULL; + } + //Clock for frequency 49716Hz. Mixfreq is used for output mix frequency. + opl = OPLNew(1789776 * 2, mixfreq); + OPLResetChip(opl); + OPL_Detect(); } void Fmdrv_MixTo(int *target, int count) { - static short *buf = NULL; - static int buf_size = 0; + static short *buf = NULL; + static int buf_size = 0; - if (!fm_active) - return; + if (!fm_active) + return; - if (buf_size != count * 2) { - int before = buf_size; - buf_size = sizeof(short) * count; - - if (before) { - buf = (short *) realloc(buf, buf_size); - } - else { - buf = (short *) malloc(buf_size); - } - } - - memset(buf, 0, count * 2); - OPLUpdateOne(opl, buf, count); - - /* - static int counter = 0; - - for(int a = 0; a < count; ++a) - buf[a] = ((counter++) & 0x100) ? -10000 : 10000; - */ - - for (int a = 0; a < count; ++a) { - target[a * 2 + 0] += buf[a] * OPL_VOLUME; - target[a * 2 + 1] += buf[a] * OPL_VOLUME; - } + if (buf_size != count * 2) { + int before = buf_size; + buf_size = sizeof(short) * count; + + if (before) { + buf = (short *) realloc(buf, buf_size); + } + else { + buf = (short *) malloc(buf_size); + } + } + + memset(buf, 0, count * 2); + OPLUpdateOne(opl, buf, count); + + /* + static int counter = 0; + + for(int a = 0; a < count; ++a) + buf[a] = ((counter++) & 0x100) ? -10000 : 10000; + */ + + for (int a = 0; a < count; ++a) { + target[a * 2 + 0] += buf[a] * OPL_VOLUME; + target[a * 2 + 1] += buf[a] * OPL_VOLUME; + } } @@ -149,28 +155,28 @@ static int SetBase(int c) { - return c % 9; + return c % 9; } static void OPL_Byte(unsigned char idx, unsigned char data) { - //register int a; - Fmdrv_Outportb(oplbase, idx); // for(a = 0; a < 6; a++) Fmdrv_Inportb(oplbase); - Fmdrv_Outportb(oplbase + 1, data); // for(a = 0; a < 35; a++) Fmdrv_Inportb(oplbase); + //register int a; + Fmdrv_Outportb(oplbase, idx); // for(a = 0; a < 6; a++) Fmdrv_Inportb(oplbase); + Fmdrv_Outportb(oplbase + 1, data); // for(a = 0; a < 35; a++) Fmdrv_Inportb(oplbase); } void OPL_NoteOff(int c) { - c = SetBase(c); + c = SetBase(c); - if (c<9) { - /* KEYON_BLOCK+c seems to not work alone?? */ - OPL_Byte(KEYON_BLOCK + c, 0); - //OPL_Byte(KSL_LEVEL + Ope, 0xFF); - //OPL_Byte(KSL_LEVEL + 3 + Ope, 0xFF); - } + if (c<9) { + /* KEYON_BLOCK+c seems to not work alone?? */ + OPL_Byte(KEYON_BLOCK + c, 0); + //OPL_Byte(KSL_LEVEL + Ope, 0xFF); + //OPL_Byte(KSL_LEVEL + 3 + Ope, 0xFF); + } } @@ -179,33 +185,19 @@ retrig, just turns the note on and sets freq.) If keyoff is nonzero, doesn't even set the note on. Could be used for pitch bending also. */ -void OPL_HertzTouch(int c, int Hertz, int keyoff) +void OPL_HertzTouch(int c, int milliHertz, int keyoff) { -//fprintf(stderr, "OPL_NoteOn(%d,%d)\n", c, Hertz); - int Oct; - c = SetBase(c); if (c >= 9) - return; + return; fm_active = 1; -#if 1 - for (Oct = 0; Hertz > 0x1FF; Oct++) - Hertz >>= 1; -#else - for (Oct = -1; Hertz > 0x1FF; Oct++) - Hertz >>= 1; - - if (Oct < 0) - Oct = 0; -#endif - /* Bytes A0-B8 - Octave / F-Number / Key-On - 7 6 5 4 3 2 1 0 + 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+-----+-----+-----+-----+ | F-Number (least significant byte) | (A0-A8) +-----+-----+-----+-----+-----+-----+-----+-----+ @@ -213,99 +205,98 @@ | | On | | most sig. | +-----+-----+-----+-----+-----+-----+-----+-----+ */ + unsigned int outfnum; + unsigned int outblock; + const int conversion_factor = 49716; // Frequency of OPL. + milliHertzToFnum(milliHertz, &outfnum, &outblock, conversion_factor); + OPL_Byte(0xA0 + c, outfnum & 255); // F-Number low 8 bits + OPL_Byte(0xB0 + c, (keyoff ? 0 : 0x20) // Key on + | ((outfnum >> 8) & 3) // F-number high 2 bits + | (outblock << 2) + ); - /* Ok - 1.1.1999/Bisqwit */ - OPL_Byte(0xA0 + c, Hertz & 255); // F-Number low 8 bits - OPL_Byte(0xB0 + c, (keyoff ? 0 : 0x20) // Key on - | ((Hertz >> 8) & 3) // F-number high 2 bits - | ((Oct & 7) << 2) - ); } void OPL_Touch(int c, const unsigned char *D, unsigned vol) { - if (!D) { - if (c < MAX_VOICES) - D = Dtab[c]; - if (!D) - return; - } + if (!D) { + if (c < MAX_VOICES) + D = Dtab[c]; + if (!D) + return; + } //fprintf(stderr, "OPL_Touch(%d, %p:%02X.%02X.%02X.%02X-%02X.%02X.%02X.%02X-%02X.%02X.%02X, %d)\n", // c, D,D[0],D[1],D[2],D[3],D[4],D[5],D[6],D[7],D[8],D[9],D[10], Vol); - Dtab[c] = D; - //vol = vol * (D[8]>>2) / 63; + Dtab[c] = D; - c = SetBase(c); + c = SetBase(c); - if (c >= 9) - return; + if (c >= 9) + return; - int Ope = PortBases[c]; + int Ope = PortBases[c]; /* Bytes 40-55 - Level Key Scaling / Total Level - 7 6 5 4 3 2 1 0 + 7 6 5 4 3 2 1 0 +-----+-----+-----+-----+-----+-----+-----+-----+ | Scaling | Total Level | | Level | 24 12 6 3 1.5 .75 | <-- dB +-----+-----+-----+-----+-----+-----+-----+-----+ - bits 7-6 - causes output levels to decrease as the frequency - rises: - 00 - no change - 10 - 1.5 dB/8ve - 01 - 3 dB/8ve - 11 - 6 dB/8ve - bits 5-0 - controls the total output level of the operator. - all bits CLEAR is loudest; all bits SET is the - softest. Don't ask me why. + bits 7-6 - causes output levels to decrease as the frequency + rises: + 00 - no change + 10 - 1.5 dB/8ve + 01 - 3 dB/8ve + 11 - 6 dB/8ve + bits 5-0 - controls the total output level of the operator. + all bits CLEAR is loudest; all bits SET is the + softest. Don't ask me why. */ - OPL_Byte(KSL_LEVEL + Ope, (D[2] & KSL_MASK) | - // (63 + (d[2] & 63) * vol / 63 - vol) - old formula - // (63 - ((63 - (d[2] & 63)) * vol ) / 63) - older formula - // (63 - ((63 - (d[2] & 63)) * vol + 32) / 64) - revised formula, like ST3 - (((int)(D[2] & 63) - 63) * vol + 63 * 64 - 32) / 64 // - optimized revised formula - ); - - OPL_Byte(KSL_LEVEL + 3 + Ope, (D[3] & KSL_MASK) | - (((int)(D[3] & 63) - 63) * vol + 63 * 64 - 32) / 64 - ); - - /* 2008-09-27 Bisqwit: - * Did tests in ST3: The value poked - * to 0x43, minus from 63, is: - * - * OplVol 63 47 31 - * SmpVol - * 64 63 47 31 - * 32 32 24 15 - * 16 16 12 8 - * - * This seems to clearly indicate that the value - * poked is calculated with 63 - round(oplvol*smpvol/64.0). - * - * Also, from the documentation we can deduce that - * the maximum volume to be set is 47.25 dB and that - * each increase by 1 corresponds to 0.75 dB. - * - * Since we know that 3 dB is equivalent to a doubling - * of the volume, we can deduce that an increase or - * decrease by 4 will double / halve the volume. - * - * However, the real value is 8, at least that's how fmopl.c - * works... I guess the documentation above is wrong, or I - * misinterpreted it. - */ + OPL_Byte(KSL_LEVEL + Ope, (D[2] & KSL_MASK) | + // (63 + (d[2] & 63) * vol / 63 - vol) - old formula + // (63 - ((63 - (d[2] & 63)) * vol ) / 63) - older formula + // (63 - ((63 - (d[2] & 63)) * vol + 32) / 64) - revised formula, like ST3 + (((int)(D[2] & 63) - 63) * vol + 63 * 64 - 32) / 64 // - optimized revised formula + ); + + OPL_Byte(KSL_LEVEL + 3 + Ope, (D[3] & KSL_MASK) | + (((int)(D[3] & 63) - 63) * vol + 63 * 64 - 32) / 64 + ); + + /* 2008-09-27 Bisqwit: + * Did tests in ST3: The value poked + * to 0x43, minus from 63, is: + * + * OplVol 63 47 31 + * SmpVol + * 64 63 47 31 + * 32 32 24 15 + * 16 16 12 8 + * + * This seems to clearly indicate that the value + * poked is calculated with 63 - round(oplvol*smpvol/64.0). + * + * Also, from the documentation we can deduce that + * the maximum volume to be set is 47.25 dB and that + * each increase by 1 corresponds to 0.75 dB. + * + * Since we know that 6 dB is equivalent to a doubling + * of the volume, we can deduce that an increase or + * decrease by 8 will double / halve the volume. + * + */ } void OPL_Pan(int c, signed char val) { - Pans[c] = val; - /* Doesn't happen immediately! */ + Pans[c] = val; + /* Doesn't happen immediately! */ } @@ -330,65 +321,65 @@ OPL_Byte(SUSTAIN_RELEASE+3+Ope, D[7]); OPL_Byte(WAVE_SELECT+ 3+Ope, D[9]&3);// 6 high bits used elsewhere - /* Panning... */ + /* feedback, additive synthesis and Panning... */ OPL_Byte(FEEDBACK_CONNECTION+c, - (D[10] & ~STEREO_BITS) - | (Pans[c]<-32 ? VOICE_TO_LEFT - : Pans[c]>32 ? VOICE_TO_RIGHT - : (VOICE_TO_LEFT | VOICE_TO_RIGHT) - )); + (D[10] & ~STEREO_BITS) + | (Pans[c]<-32 ? VOICE_TO_LEFT + : Pans[c]>32 ? VOICE_TO_RIGHT + : (VOICE_TO_LEFT | VOICE_TO_RIGHT) + )); } void OPL_Reset(void) { //fprintf(stderr, "OPL_Reset\n"); - int a; + int a; - for(a = 0; a < 244; a++) - OPL_Byte(a, 0); + for(a = 0; a < 244; a++) + OPL_Byte(a, 0); - for(a = 0; a < MAX_VOICES; ++a) - Dtab[a] = NULL; + for(a = 0; a < MAX_VOICES; ++a) + Dtab[a] = NULL; - OPL_Byte(TEST_REGISTER, ENABLE_WAVE_SELECT); + OPL_Byte(TEST_REGISTER, ENABLE_WAVE_SELECT); - fm_active = 0; + fm_active = 0; } int OPL_Detect(void) { - SetBase(0); + SetBase(0); - /* Reset timers 1 and 2 */ - OPL_Byte(TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); + /* Reset timers 1 and 2 */ + OPL_Byte(TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); - /* Reset the IRQ of the FM chip */ - OPL_Byte(TIMER_CONTROL_REGISTER, IRQ_RESET); + /* Reset the IRQ of the FM chip */ + OPL_Byte(TIMER_CONTROL_REGISTER, IRQ_RESET); - unsigned char ST1 = Fmdrv_Inportb(oplbase); /* Status register */ + unsigned char ST1 = Fmdrv_Inportb(oplbase); /* Status register */ - OPL_Byte(TIMER1_REGISTER, 255); - OPL_Byte(TIMER_CONTROL_REGISTER, TIMER2_MASK | TIMER1_START); + OPL_Byte(TIMER1_REGISTER, 255); + OPL_Byte(TIMER_CONTROL_REGISTER, TIMER2_MASK | TIMER1_START); - /*_asm xor cx,cx;P1:_asm loop P1*/ - unsigned char ST2 = Fmdrv_Inportb(oplbase); + /*_asm xor cx,cx;P1:_asm loop P1*/ + unsigned char ST2 = Fmdrv_Inportb(oplbase); - OPL_Byte(TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); - OPL_Byte(TIMER_CONTROL_REGISTER, IRQ_RESET); + OPL_Byte(TIMER_CONTROL_REGISTER, TIMER1_MASK | TIMER2_MASK); + OPL_Byte(TIMER_CONTROL_REGISTER, IRQ_RESET); - int OPLMode = (ST2 & 0xE0) == 0xC0 && !(ST1 & 0xE0); + int OPLMode = (ST2 & 0xE0) == 0xC0 && !(ST1 & 0xE0); - if (!OPLMode) - return -1; + if (!OPLMode) + return -1; - return 0; + return 0; } void OPL_Close(void) { - OPL_Reset(); + OPL_Reset(); } diff -Nru schism-0+20110101/player/snd_gm.c schism-20160521/player/snd_gm.c --- schism-0+20110101/player/snd_gm.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/player/snd_gm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ #if !defined(HAVE_LOG2) && !defined(__USE_ISOC99) && !defined(log2) static double log2(double d) { - return log(d) / log(2.0); + return log(d) / log(2.0); } #endif @@ -63,31 +63,31 @@ /* GENERAL MIDI (GM) COMMANDS: 8x 1000xxxx nn vv Note off (key is released) - nn=note number - vv=velocity + nn=note number + vv=velocity 9x 1001xxxx nn vv Note on (key is pressed) - nn=note number - vv=velocity + nn=note number + vv=velocity Ax 1010xxxx nn vv Key after-touch - nn=note number - vv=velocity + nn=note number + vv=velocity Bx 1011xxxx cc vv Control Change - cc=controller number - vv=new value + cc=controller number + vv=new value Cx 1100xxxx pp Program (patch) change - pp=new program number + pp=new program number Dx 1101xxxx cc Channel after-touch - cc=channel number + cc=channel number Ex 1110xxxx bb tt Pitch wheel change (2000h is normal - or no change) - bb=bottom (least sig) 7 bits of value - tt=top (most sig) 7 bits of value + or no change) + bb=bottom (least sig) 7 bits of value + tt=top (most sig) 7 bits of value About the controllers... In AWE32 they are: 0=Bank select 7=Master volume 11=Expression(volume?) @@ -128,82 +128,82 @@ static void MPU_SendCommand(const unsigned char* buf, unsigned nbytes, int c) { - if (!nbytes) - return; + if (!nbytes) + return; - csf_midi_send(current_song, buf, nbytes, c, 0); // FIXME we should not know about 'current_song' here! + csf_midi_send(current_song, buf, nbytes, c, 0); // FIXME we should not know about 'current_song' here! } static void MPU_Ctrl(int c, int i, int v) { - if (!(status.flags & MIDI_LIKE_TRACKER)) - return; + if (!(status.flags & MIDI_LIKE_TRACKER)) + return; - unsigned char buf[3] = {0xB0 + c, i, v}; - MPU_SendCommand(buf, 3, c); + unsigned char buf[3] = {0xB0 + c, i, v}; + MPU_SendCommand(buf, 3, c); } static void MPU_Patch(int c, int p) { - if (!(status.flags & MIDI_LIKE_TRACKER)) - return; + if (!(status.flags & MIDI_LIKE_TRACKER)) + return; - unsigned char buf[2] = {0xC0 + c, p}; - MPU_SendCommand(buf, 2, c); + unsigned char buf[2] = {0xC0 + c, p}; + MPU_SendCommand(buf, 2, c); } static void MPU_Bend(int c, int w) { - if (!(status.flags & MIDI_LIKE_TRACKER)) - return; + if (!(status.flags & MIDI_LIKE_TRACKER)) + return; - unsigned char buf[3] = {0xE0 + c, w & 127, w >> 7}; - MPU_SendCommand(buf, 3, c); + unsigned char buf[3] = {0xE0 + c, w & 127, w >> 7}; + MPU_SendCommand(buf, 3, c); } static void MPU_NoteOn(int c, int k, int v) { - if (!(status.flags & MIDI_LIKE_TRACKER)) - return; + if (!(status.flags & MIDI_LIKE_TRACKER)) + return; - unsigned char buf[3] = {0x90 + c, k, v}; - MPU_SendCommand(buf, 3, c); + unsigned char buf[3] = {0x90 + c, k, v}; + MPU_SendCommand(buf, 3, c); } static void MPU_NoteOff(int c, int k, int v) { - if (!(status.flags & MIDI_LIKE_TRACKER)) - return; + if (!(status.flags & MIDI_LIKE_TRACKER)) + return; - if (((unsigned char) RunningStatus) == 0x90 + c) { - // send a zero-velocity keyoff instead for optimization - MPU_NoteOn(c, k, 0); - } - else { - unsigned char buf[3] = {0x80+c, k, v}; - MPU_SendCommand(buf, 3, c); - } + if (((unsigned char) RunningStatus) == 0x90 + c) { + // send a zero-velocity keyoff instead for optimization + MPU_NoteOn(c, k, 0); + } + else { + unsigned char buf[3] = {0x80+c, k, v}; + MPU_SendCommand(buf, 3, c); + } } static void MPU_SendPN(int ch, - unsigned portindex, - unsigned param, unsigned valuehi, unsigned valuelo) + unsigned portindex, + unsigned param, unsigned valuehi, unsigned valuelo) { - MPU_Ctrl(ch, portindex+1, param>>7); - MPU_Ctrl(ch, portindex+0, param & 0x80); + MPU_Ctrl(ch, portindex+1, param>>7); + MPU_Ctrl(ch, portindex+0, param & 0x80); - if (param != 0x4080) { - MPU_Ctrl(ch, 6, valuehi); + if (param != 0x4080) { + MPU_Ctrl(ch, 6, valuehi); - if (valuelo) - MPU_Ctrl(ch, 38, valuelo); - } + if (valuelo) + MPU_Ctrl(ch, 38, valuelo); + } } @@ -232,12 +232,12 @@ static void s3m_reset(s3m_channel_info_t *ci) { - ci->note = 0; - ci->patch = 0; - ci->bank = 0; - ci->pan = 0; - ci->chan = -1; - ci->pref_chn_mask = -1; + ci->note = 0; + ci->patch = 0; + ci->bank = 0; + ci->pan = 0; + ci->chan = -1; + ci->pref_chn_mask = -1; } @@ -256,11 +256,11 @@ static void msi_reset(midi_state_t *msi) { - msi->volume = 255; - msi->patch = 255; - msi->bank = 255; - msi->bend = PitchBendCenter; - msi->pan = 0; + msi->volume = 255; + msi->patch = 255; + msi->bank = 255; + msi->bend = PitchBendCenter; + msi->pan = 0; } #define msi_know_something(msi) ((msi).patch != 255) @@ -268,42 +268,42 @@ static void msi_set_volume(midi_state_t *msi, int c, unsigned newvol) { - if (msi->volume != newvol) { - msi->volume = newvol; - MPU_Ctrl(c, 7, newvol); - } + if (msi->volume != newvol) { + msi->volume = newvol; + MPU_Ctrl(c, 7, newvol); + } } static void msi_set_patch_and_bank(midi_state_t *msi, int c, int p, int b) { - if (msi->bank != b) { - msi->bank = b; - MPU_Ctrl(c, 0, b); - } - - if (msi->patch != p) { - msi->patch = p; - MPU_Patch(c, p); - } + if (msi->bank != b) { + msi->bank = b; + MPU_Ctrl(c, 0, b); + } + + if (msi->patch != p) { + msi->patch = p; + MPU_Patch(c, p); + } } static void msi_set_pitch_bend(midi_state_t *msi, int c, int value) { - if (msi->bend != value) { - msi->bend = value; - MPU_Bend(c, value); - } + if (msi->bend != value) { + msi->bend = value; + MPU_Bend(c, value); + } } static void msi_set_pan(midi_state_t *msi, int c, int value) { - if (msi->pan != value) { - msi->pan = value; - MPU_Ctrl(c, 10, (unsigned char)(value + 128) / 2); - } + if (msi->pan != value) { + msi->pan = value; + MPU_Ctrl(c, 10, (unsigned char)(value + 128) / 2); + } } @@ -312,268 +312,268 @@ static unsigned char GM_volume(unsigned char vol) // Converts the volume { - /* Converts volume in range 0..127 to range 0..127 with clamping */ - return vol >= 127 ? 127 : vol; + /* Converts volume in range 0..127 to range 0..127 with clamping */ + return vol >= 127 ? 127 : vol; } static int GM_AllocateMelodyChannel(int c, int patch, int bank, int key, int pref_chn_mask) { - /* Returns a MIDI channel number on - * which this key can be played safely. - * - * Things that matter: - * - * -4 The channel has a different patch selected - * -6 The channel has a different bank selected - * -9 The channel already has the same key - * +1 The channel number corresponds to c - * +2 The channel has no notes playing - * -999 The channel number is 9 (percussion-only channel) - * - * Channel with biggest score is selected. - * - */ - int bad_channels[16] = {0}; // channels having the same key playing - int used_channels[16] = {0}; // channels having something playing - - memset(bad_channels, 0, sizeof(bad_channels)); - memset(used_channels, 0, sizeof(used_channels)); - - for (unsigned int a = 0; a < MAX_VOICES; ++a) { - if (s3m_active(s3m_chans[a]) && - !s3m_percussion(s3m_chans[a])) { - //fprintf(stderr, "S3M[%d] active at %d\n", a, s3m_chans[a].chan); - used_channels[s3m_chans[a].chan] = 1; // channel is active - - if (s3m_chans[a].note == key) - bad_channels[s3m_chans[a].chan] = 1; // ...with the same key - } - } - - int best_mc = c, - best_score = -999; - - for (int mc = 0; mc < 16; ++mc) { - if (mc == 9) - continue; // percussion channel is never chosen for melody. - - int score = 0; - - if (PreferredChannelHandlingMode != TryHonor && - msi_know_something(midi_chans[mc])) { - if (midi_chans[mc].patch != patch) score -= 4; // different patch - if (midi_chans[mc].bank != bank) score -= 6; // different bank - } - - if (PreferredChannelHandlingMode == TryHonor) { - if (pref_chn_mask & (1 << mc)) - score += 1; // same channel number - } - else if (PreferredChannelHandlingMode == AlwaysHonor) { - // disallow channels that are not allowed - if (pref_chn_mask >= 0x10000) { - if (mc != c % 16) - continue; - } - else if (!(pref_chn_mask & (1 << mc))) - continue; - } - else { - if (c == mc) - score += 1; // same channel number - } - - if (bad_channels[mc]) - score -= 9; // has same key on - - if (!used_channels[mc]) - score += 2; // channel is unused - - //fprintf(stderr, "score %d for channel %d\n", score, mc); - if (score > best_score) { - best_score = score; - best_mc = mc; - } - } + /* Returns a MIDI channel number on + * which this key can be played safely. + * + * Things that matter: + * + * -4 The channel has a different patch selected + * -6 The channel has a different bank selected + * -9 The channel already has the same key + * +1 The channel number corresponds to c + * +2 The channel has no notes playing + * -999 The channel number is 9 (percussion-only channel) + * + * Channel with biggest score is selected. + * + */ + int bad_channels[16] = {0}; // channels having the same key playing + int used_channels[16] = {0}; // channels having something playing + + memset(bad_channels, 0, sizeof(bad_channels)); + memset(used_channels, 0, sizeof(used_channels)); + + for (unsigned int a = 0; a < MAX_VOICES; ++a) { + if (s3m_active(s3m_chans[a]) && + !s3m_percussion(s3m_chans[a])) { + //fprintf(stderr, "S3M[%d] active at %d\n", a, s3m_chans[a].chan); + used_channels[s3m_chans[a].chan] = 1; // channel is active + + if (s3m_chans[a].note == key) + bad_channels[s3m_chans[a].chan] = 1; // ...with the same key + } + } + + int best_mc = c, + best_score = -999; + + for (int mc = 0; mc < 16; ++mc) { + if (mc == 9) + continue; // percussion channel is never chosen for melody. + + int score = 0; + + if (PreferredChannelHandlingMode != TryHonor && + msi_know_something(midi_chans[mc])) { + if (midi_chans[mc].patch != patch) score -= 4; // different patch + if (midi_chans[mc].bank != bank) score -= 6; // different bank + } + + if (PreferredChannelHandlingMode == TryHonor) { + if (pref_chn_mask & (1 << mc)) + score += 1; // same channel number + } + else if (PreferredChannelHandlingMode == AlwaysHonor) { + // disallow channels that are not allowed + if (pref_chn_mask >= 0x10000) { + if (mc != c % 16) + continue; + } + else if (!(pref_chn_mask & (1 << mc))) + continue; + } + else { + if (c == mc) + score += 1; // same channel number + } + + if (bad_channels[mc]) + score -= 9; // has same key on + + if (!used_channels[mc]) + score += 2; // channel is unused + + //fprintf(stderr, "score %d for channel %d\n", score, mc); + if (score > best_score) { + best_score = score; + best_mc = mc; + } + } - //fprintf(stderr, "BEST SCORE %d FOR CHANNEL %d\n", best_score,best_mc); - return best_mc; + //fprintf(stderr, "BEST SCORE %d FOR CHANNEL %d\n", best_score,best_mc); + return best_mc; } void GM_Patch(int c, unsigned char p, int pref_chn_mask) { - if (c < 0 || ((unsigned int) c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int) c) >= MAX_VOICES) + return; - s3m_chans[c].patch = p; // No actual data is sent. - s3m_chans[c].pref_chn_mask = pref_chn_mask; + s3m_chans[c].patch = p; // No actual data is sent. + s3m_chans[c].pref_chn_mask = pref_chn_mask; } void GM_Bank(int c, unsigned char b) { - if (c < 0 || ((unsigned int) c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int) c) >= MAX_VOICES) + return; - s3m_chans[c].bank = b; // No actual data is sent yet. + s3m_chans[c].bank = b; // No actual data is sent yet. } void GM_Touch(int c, unsigned char vol) { - if (c < 0 || ((unsigned int) c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int) c) >= MAX_VOICES) + return; - /* This function must only be called when - * a key has been played on the channel. */ - if (!s3m_active(s3m_chans[c])) - return; + /* This function must only be called when + * a key has been played on the channel. */ + if (!s3m_active(s3m_chans[c])) + return; - int mc = s3m_chans[c].chan; - msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); + int mc = s3m_chans[c].chan; + msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); } void GM_KeyOn(int c, unsigned char key, unsigned char vol) { - if (c < 0 || ((unsigned int) c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int) c) >= MAX_VOICES) + return; - GM_KeyOff(c); // Ensure the previous key on this channel is off. + GM_KeyOff(c); // Ensure the previous key on this channel is off. - if (s3m_active(s3m_chans[c])) - return; // be sure the channel is deactivated. + if (s3m_active(s3m_chans[c])) + return; // be sure the channel is deactivated. #ifdef GM_DEBUG - fprintf(stderr, "GM_KeyOn(%d, %d,%d)\n", c, key,vol); + fprintf(stderr, "GM_KeyOn(%d, %d,%d)\n", c, key,vol); #endif - if (s3m_percussion(s3m_chans[c])) { - // Percussion always uses channel 9. - int percu = key; - - if (s3m_chans[c].patch & 0x80) - percu = s3m_chans[c].patch - 128; - - int mc = s3m_chans[c].chan = 9; - msi_set_pan(&midi_chans[mc], mc, s3m_chans[c].pan); - msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); - s3m_chans[c].note = key; - MPU_NoteOn(mc, s3m_chans[c].note = percu, 127); - } - else { - // Allocate a MIDI channel for this key. - // Note: If you need to transpone the key, do it before allocating the channel. - - int mc = s3m_chans[c].chan = GM_AllocateMelodyChannel( - c, s3m_chans[c].patch, s3m_chans[c].bank, - key, s3m_chans[c].pref_chn_mask); - - msi_set_patch_and_bank(&midi_chans[mc], mc, s3m_chans[c].patch, s3m_chans[c].bank); - msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); - MPU_NoteOn(mc, s3m_chans[c].note = key, 127); - msi_set_pan(&midi_chans[mc], mc, s3m_chans[c].pan); - } + if (s3m_percussion(s3m_chans[c])) { + // Percussion always uses channel 9. + int percu = key; + + if (s3m_chans[c].patch & 0x80) + percu = s3m_chans[c].patch - 128; + + int mc = s3m_chans[c].chan = 9; + msi_set_pan(&midi_chans[mc], mc, s3m_chans[c].pan); + msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); + s3m_chans[c].note = key; + MPU_NoteOn(mc, s3m_chans[c].note = percu, 127); + } + else { + // Allocate a MIDI channel for this key. + // Note: If you need to transpone the key, do it before allocating the channel. + + int mc = s3m_chans[c].chan = GM_AllocateMelodyChannel( + c, s3m_chans[c].patch, s3m_chans[c].bank, + key, s3m_chans[c].pref_chn_mask); + + msi_set_patch_and_bank(&midi_chans[mc], mc, s3m_chans[c].patch, s3m_chans[c].bank); + msi_set_volume(&midi_chans[mc], mc, GM_volume(vol)); + MPU_NoteOn(mc, s3m_chans[c].note = key, 127); + msi_set_pan(&midi_chans[mc], mc, s3m_chans[c].pan); + } } void GM_KeyOff(int c) { - if (c < 0 || ((unsigned int)c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int)c) >= MAX_VOICES) + return; - if (!s3m_active(s3m_chans[c])) - return; // nothing to do + if (!s3m_active(s3m_chans[c])) + return; // nothing to do #ifdef GM_DEBUG - fprintf(stderr, "GM_KeyOff(%d)\n", c); + fprintf(stderr, "GM_KeyOff(%d)\n", c); #endif - int mc = s3m_chans[c].chan; + int mc = s3m_chans[c].chan; - MPU_NoteOff(mc, s3m_chans[c].note, 0); - s3m_chans[c].chan = -1; - s3m_chans[c].note = 0; - s3m_chans[c].pan = 0; - // Don't reset the pitch bend, it will make sustains sound bad + MPU_NoteOff(mc, s3m_chans[c].note, 0); + s3m_chans[c].chan = -1; + s3m_chans[c].note = 0; + s3m_chans[c].pan = 0; + // Don't reset the pitch bend, it will make sustains sound bad } void GM_Bend(int c, unsigned count) { if (c < 0 || ((unsigned int)c) >= MAX_VOICES) - return; + return; - /* I hope nobody tries to bend hi-hat or something like that :-) */ - /* 1998-10-03 01:50 Apparently that can happen too... - For example in the last pattern of urq.mod there's - a hit of a heavy plate, which is followed by a J0A - 0.5 seconds thereafter for the same channel. - Unfortunately MIDI cannot do that. Drum plate - sizes can rarely be adjusted while playing. -Bisqwit - However, we don't stop anyone from trying... - */ - - if (s3m_active(s3m_chans[c])) { - int mc = s3m_chans[c].chan; - msi_set_pitch_bend(&midi_chans[mc], mc, count); - } + /* I hope nobody tries to bend hi-hat or something like that :-) */ + /* 1998-10-03 01:50 Apparently that can happen too... + For example in the last pattern of urq.mod there's + a hit of a heavy plate, which is followed by a J0A + 0.5 seconds thereafter for the same channel. + Unfortunately MIDI cannot do that. Drum plate + sizes can rarely be adjusted while playing. -Bisqwit + However, we don't stop anyone from trying... + */ + + if (s3m_active(s3m_chans[c])) { + int mc = s3m_chans[c].chan; + msi_set_pitch_bend(&midi_chans[mc], mc, count); + } } void GM_Reset(int quitting) { #ifdef GM_DEBUG - resetting = 1; + resetting = 1; #endif - unsigned int a; - //fprintf(stderr, "GM_Reset\n"); + unsigned int a; + //fprintf(stderr, "GM_Reset\n"); - for (a = 0; a < MAX_VOICES; a++) { - GM_KeyOff(a); - //s3m_chans[a].patch = s3m_chans[a].bank = s3m_chans[a].pan = 0; - s3m_reset(&s3m_chans[a]); - } - - // How many semitones does it take to screw in the full 0x4000 bending range of lightbulbs? - // We scale the number by 128, because the RPN allows for finetuning. - int n_semitones_times_128 = 128 * 0x2000 / semitone_bend_depth; - - if (quitting) { - // When quitting, we reprogram the pitch bend sensitivity into - // the range of 1 semitone (TiMiDity++'s default, which is - // probably a default on other devices as well), instead of - // what we preferred for IT playback. - n_semitones_times_128 = 128; - } - - for (a = 0; a < 16; a++) { - // XXX - // XXX Porting note: - // XXX This might go wrong because the midi struct is already reset - // XXX by the constructor in the C++ version. - // XXX - MPU_Ctrl(a, 120, 0); // turn off all sounds - MPU_Ctrl(a, 123, 0); // turn off all notes - MPU_Ctrl(a, 121, 0); // reset vibrato, bend - msi_set_pan(&midi_chans[a], a, 0); // reset pan position - msi_set_volume(&midi_chans[a], a, 127); // set channel volume - msi_set_pitch_bend(&midi_chans[a], a, PitchBendCenter); // reset pitch bends - - msi_reset(&midi_chans[a]); - - // Reprogram the pitch bending sensitivity to our desired depth. - MPU_SendRPN(a, 0, n_semitones_times_128 / 128, - n_semitones_times_128 % 128); + for (a = 0; a < MAX_VOICES; a++) { + GM_KeyOff(a); + //s3m_chans[a].patch = s3m_chans[a].bank = s3m_chans[a].pan = 0; + s3m_reset(&s3m_chans[a]); + } + + // How many semitones does it take to screw in the full 0x4000 bending range of lightbulbs? + // We scale the number by 128, because the RPN allows for finetuning. + int n_semitones_times_128 = 128 * 0x2000 / semitone_bend_depth; + + if (quitting) { + // When quitting, we reprogram the pitch bend sensitivity into + // the range of 1 semitone (TiMiDity++'s default, which is + // probably a default on other devices as well), instead of + // what we preferred for IT playback. + n_semitones_times_128 = 128; + } + + for (a = 0; a < 16; a++) { + // XXX + // XXX Porting note: + // XXX This might go wrong because the midi struct is already reset + // XXX by the constructor in the C++ version. + // XXX + MPU_Ctrl(a, 120, 0); // turn off all sounds + MPU_Ctrl(a, 123, 0); // turn off all notes + MPU_Ctrl(a, 121, 0); // reset vibrato, bend + msi_set_pan(&midi_chans[a], a, 0); // reset pan position + msi_set_volume(&midi_chans[a], a, 127); // set channel volume + msi_set_pitch_bend(&midi_chans[a], a, PitchBendCenter); // reset pitch bends + + msi_reset(&midi_chans[a]); + + // Reprogram the pitch bending sensitivity to our desired depth. + MPU_SendRPN(a, 0, n_semitones_times_128 / 128, + n_semitones_times_128 % 128); - MPU_ResetPN(a); - } + MPU_ResetPN(a); + } #ifdef GM_DEBUG - resetting = 0; - fprintf(stderr, "-------------- GM_Reset completed ---------------\n"); + resetting = 0; + fprintf(stderr, "-------------- GM_Reset completed ---------------\n"); #endif } @@ -581,30 +581,30 @@ void GM_DPatch(int ch, unsigned char GM, unsigned char bank, int pref_chn_mask) { #ifdef GM_DEBUG - fprintf(stderr, "GM_DPatch(%d, %02X @ %d)\n", ch, GM, bank); + fprintf(stderr, "GM_DPatch(%d, %02X @ %d)\n", ch, GM, bank); #endif - if (ch < 0 || ((unsigned int)ch) >= MAX_VOICES) - return; + if (ch < 0 || ((unsigned int)ch) >= MAX_VOICES) + return; - GM_Bank(ch, bank); - GM_Patch(ch, GM, pref_chn_mask); + GM_Bank(ch, bank); + GM_Patch(ch, GM, pref_chn_mask); } void GM_Pan(int c, signed char val) { - //fprintf(stderr, "GM_Pan(%d,%d)\n", c,val); - if (c < 0 || ((unsigned int)c) >= MAX_VOICES) - return; - - s3m_chans[c].pan = val; - - // If a note is playing, effect immediately. - if (s3m_active(s3m_chans[c])) { - int mc = s3m_chans[c].chan; - msi_set_pan(&midi_chans[mc], mc, val); - } + //fprintf(stderr, "GM_Pan(%d,%d)\n", c,val); + if (c < 0 || ((unsigned int)c) >= MAX_VOICES) + return; + + s3m_chans[c].pan = val; + + // If a note is playing, effect immediately. + if (s3m_active(s3m_chans[c])) { + int mc = s3m_chans[c].chan; + msi_set_pan(&midi_chans[mc], mc, val); + } } @@ -613,86 +613,86 @@ void GM_SetFreqAndVol(int c, int Hertz, int vol, MidiBendMode bend_mode, int keyoff) { #ifdef GM_DEBUG - fprintf(stderr, "GM_SetFreqAndVol(%d,%d,%d)\n", c,Hertz,vol); + fprintf(stderr, "GM_SetFreqAndVol(%d,%d,%d)\n", c,Hertz,vol); #endif - if (c < 0 || ((unsigned int)c) >= MAX_VOICES) - return; + if (c < 0 || ((unsigned int)c) >= MAX_VOICES) + return; - /* - Figure out the note and bending corresponding to this Hertz reading. + /* + Figure out the note and bending corresponding to this Hertz reading. - TiMiDity++ calculates its frequencies this way (equal temperament): - freq(0<=i<128) := 440 * pow(2.0, (i - 69) / 12.0) - bend_fine(0<=i<256) := pow(2.0, i/12.0/256) - bend_coarse(0<=i<128) := pow(2.0, i/12.0) - - I suppose we can do the mathematical route. -Bisqwit - hertz = 440*pow(2, (midinote-69)/12) - Maxima gives us (solve+expand): - midinote = 12 * log(hertz/440) / log(2) + 69 - In other words: - midinote = 12 * log2(hertz/440) + 69 - Or: - midinote = 12 * log2(hertz/55) + 33 (but I prefer the above for clarity) - - (55 and 33 are related to 440 and 69 the following way: - log2(440) = ~8.7 - 440/8 = 55 - log2(8) = 3 - 12 * 3 = 36 - 69-36 = 33. - I guess Maxima's expression preserves more floating - point accuracy, but given the range of the numbers - we work here with, that's hardly an issue.) - */ - double midinote = 69 + 12.0 * log2(Hertz/440.0); - - // Reduce by a couple of octaves... Apparently the hertz - // value that comes from SchismTracker is upscaled by some 2^5. - midinote -= 12*5; - - int note = s3m_chans[c].note; // what's playing on the channel right now? - - int new_note = !s3m_active(s3m_chans[c]); - - if (new_note && !keyoff) { - // If the note is not active, activate it first. - // Choose the nearest note to Hertz. - note = (int)(midinote + 0.5); - - // If we are expecting a bend exclusively in either direction, - // prepare to utilize the full extent of available pitch bending. - if (bend_mode == MIDI_BEND_DOWN) note += (int)(0x2000 / semitone_bend_depth); - if (bend_mode == MIDI_BEND_UP) note -= (int)(0x2000 / semitone_bend_depth); - - if (note < 1) note = 1; - if (note > 127) note = 127; - GM_KeyOn(c, note, vol); - } - - if (!s3m_percussion(s3m_chans[c])) { // give us a break, don't bend percussive instruments - double notediff = midinote-note; // The difference is our bend value - int bend = (int)(notediff * semitone_bend_depth) + PitchBendCenter; - - // Because the log2 calculation does not always give pure notes, - // and in fact, gives a lot of variation, we reduce the bending - // precision to 100 cents. This is accurate enough for almost - // all purposes, but will significantly reduce the bend event load. - //const int bend_artificial_inaccuracy = semitone_bend_depth / 100; - //bend = (bend / bend_artificial_inaccuracy) * bend_artificial_inaccuracy; - - // Clamp the bending value so that we won't break the protocol - if(bend < 0) bend = 0; - if(bend > 0x3FFF) bend = 0x3FFF; + TiMiDity++ calculates its frequencies this way (equal temperament): + freq(0<=i<128) := 440 * pow(2.0, (i - 69) / 12.0) + bend_fine(0<=i<256) := pow(2.0, i/12.0/256) + bend_coarse(0<=i<128) := pow(2.0, i/12.0) + + I suppose we can do the mathematical route. -Bisqwit + hertz = 440*pow(2, (midinote-69)/12) + Maxima gives us (solve+expand): + midinote = 12 * log(hertz/440) / log(2) + 69 + In other words: + midinote = 12 * log2(hertz/440) + 69 + Or: + midinote = 12 * log2(hertz/55) + 33 (but I prefer the above for clarity) + + (55 and 33 are related to 440 and 69 the following way: + log2(440) = ~8.7 + 440/8 = 55 + log2(8) = 3 + 12 * 3 = 36 + 69-36 = 33. + I guess Maxima's expression preserves more floating + point accuracy, but given the range of the numbers + we work here with, that's hardly an issue.) + */ + double midinote = 69 + 12.0 * log2(Hertz/440.0); + + // Reduce by a couple of octaves... Apparently the hertz + // value that comes from SchismTracker is upscaled by some 2^5. + midinote -= 12*5; + + int note = s3m_chans[c].note; // what's playing on the channel right now? + + int new_note = !s3m_active(s3m_chans[c]); + + if (new_note && !keyoff) { + // If the note is not active, activate it first. + // Choose the nearest note to Hertz. + note = (int)(midinote + 0.5); + + // If we are expecting a bend exclusively in either direction, + // prepare to utilize the full extent of available pitch bending. + if (bend_mode == MIDI_BEND_DOWN) note += (int)(0x2000 / semitone_bend_depth); + if (bend_mode == MIDI_BEND_UP) note -= (int)(0x2000 / semitone_bend_depth); + + if (note < 1) note = 1; + if (note > 127) note = 127; + GM_KeyOn(c, note, vol); + } + + if (!s3m_percussion(s3m_chans[c])) { // give us a break, don't bend percussive instruments + double notediff = midinote-note; // The difference is our bend value + int bend = (int)(notediff * semitone_bend_depth) + PitchBendCenter; + + // Because the log2 calculation does not always give pure notes, + // and in fact, gives a lot of variation, we reduce the bending + // precision to 100 cents. This is accurate enough for almost + // all purposes, but will significantly reduce the bend event load. + //const int bend_artificial_inaccuracy = semitone_bend_depth / 100; + //bend = (bend / bend_artificial_inaccuracy) * bend_artificial_inaccuracy; + + // Clamp the bending value so that we won't break the protocol + if(bend < 0) bend = 0; + if(bend > 0x3FFF) bend = 0x3FFF; - GM_Bend(c, bend); - } + GM_Bend(c, bend); + } - if (vol < 0) vol = 0; - else if (vol > 127) vol = 127; + if (vol < 0) vol = 0; + else if (vol > 127) vol = 127; - //if (!new_note) - GM_Touch(c, vol); + //if (!new_note) + GM_Touch(c, vol); } @@ -706,41 +706,40 @@ void GM_SendSongPositionCode(unsigned note16pos) { - unsigned char buf[3] = {0xF2, note16pos & 127, (note16pos >> 7) & 127}; - MPU_SendCommand(buf, 3, 0); - LastSongCounter = 0; + unsigned char buf[3] = {0xF2, note16pos & 127, (note16pos >> 7) & 127}; + MPU_SendCommand(buf, 3, 0); + LastSongCounter = 0; } void GM_IncrementSongCounter(int count) { - /* We assume that each pattern row corresponds to a 1/4 note. - * - * We also know that: - * 5 * cmdA * mixingrate - * Length of row is --------------------- samples - * 2 * cmdT - * - * where cmdA = last FX_SPEED = current_speed - * and cmdT = last FX_TEMPO = current_tempo - */ - int RowLengthInSamplesHi = 5 * current_song->current_speed * current_song->mix_frequency; - int RowLengthInSamplesLo = 2 * current_song->current_tempo; - - double NumberOfSamplesPer32thNote = - RowLengthInSamplesHi*8 / (double)RowLengthInSamplesLo; - - /* TODO: Use fraction arithmetics instead (note: cmdA, cmdT may change any time) */ - - LastSongCounter += count / NumberOfSamplesPer32thNote; - - int n_32thNotes = (int)LastSongCounter; - - if (n_32thNotes) { - for (int a = 0; a < n_32thNotes; ++a) - GM_SendSongTickCode(); + /* We assume that one schism tick = one midi tick (24ppq). + * + * We also know that: + * 5 * mixingrate + * Length of tick is -------------- samples + * 2 * cmdT + * + * where cmdT = last FX_TEMPO = current_tempo + */ - LastSongCounter -= n_32thNotes; - } + int TickLengthInSamplesHi = 5 * current_song->mix_frequency; + int TickLengthInSamplesLo = 2 * current_song->current_tempo; + + double TickLengthInSamples = TickLengthInSamplesHi / (double) TickLengthInSamplesLo; + + /* TODO: Use fraction arithmetics instead (note: cmdA, cmdT may change any time) */ + + LastSongCounter += count / TickLengthInSamples; + + int n_Ticks = (int)LastSongCounter; + + if (n_Ticks) { + for (int a = 0; a < n_Ticks; ++a) + GM_SendSongTickCode(); + + LastSongCounter -= n_Ticks; + } } diff -Nru schism-0+20110101/player/sndmix.c schism-20160521/player/sndmix.c --- schism-0+20110101/player/sndmix.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/player/sndmix.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -47,6 +47,9 @@ typedef uint32_t (* convert_t)(void *, int *, uint32_t, int *, int *); +// see also csf_midi_out_raw in effects.c +void (*csf_midi_out_note)(int chan, const song_note_t *m) = NULL; + // The volume we have here is in range 0..(63*255) (0..16065) // We should keep that range, but convert it into a logarithmic @@ -84,19 +87,30 @@ // with at most 7 comparisons. static unsigned int find_volume(unsigned short vol) { - unsigned int l = 0, r = 128; + unsigned int l = 0, r = 128; + + while (l < r) { + unsigned int m = l + ((r - l) / 2); + unsigned short p = GMvolTransition[m]; + + if (p < vol) + l = m + 1; + else + r = m; + } + + return l; +} - while (l < r) { - unsigned int m = l + ((r - l) / 2); - unsigned short p = GMvolTransition[m]; - - if (p < vol) - l = m + 1; - else - r = m; - } - return l; +unsigned int get_freq_from_period(int period, int linear) +{ + if (period <= 0) + return INT_MAX; + else if (linear) + return period; + else + return _muldiv(8363, 1712L << 8, (period << 8)); } @@ -111,783 +125,746 @@ static inline void rn_tremor(song_voice_t *chan, int *vol) { - if ((chan->cd_tremor & 192) == 128) - *vol = 0; + if ((chan->cd_tremor & 192) == 128) + *vol = 0; - chan->flags |= CHN_FASTVOLRAMP; + chan->flags |= CHN_FASTVOLRAMP; } static inline int rn_vibrato(song_t *csf, song_voice_t *chan, int period) { - unsigned int vibpos = chan->vibrato_position & 0xFF; - int vdelta; - unsigned int vdepth; - - switch (chan->vib_type) { - case VIB_SINE: - default: - vdelta = sine_table[vibpos]; - break; - case VIB_RAMP_DOWN: - vdelta = ramp_down_table[vibpos]; - break; - case VIB_SQUARE: - vdelta = square_table[vibpos]; - break; - case VIB_RANDOM: - vdelta = 128 * ((double) rand() / RAND_MAX) - 64; - break; - } - - if (csf->flags & SONG_ITOLDEFFECTS) { - vdepth = 5; - vdelta = -vdelta; // yes, IT does vibrato backwards in old-effects mode. try it. - } else { - vdepth = 6; - } - vdelta = (vdelta * (int)chan->vibrato_depth) >> vdepth; - - if (csf->flags & SONG_LINEARSLIDES) { - int l = abs(vdelta); - - if (vdelta < 0) { - vdelta = _muldiv(period, linear_slide_down_table[l >> 2], 0x10000) - period; - - if (l & 0x03) - vdelta += _muldiv(period, fine_linear_slide_down_table[l & 0x03], 0x10000) - period; - } else { - vdelta = _muldiv(period, linear_slide_up_table[l >> 2], 0x10000) - period; - - if (l & 0x03) - vdelta += _muldiv(period, fine_linear_slide_up_table[l & 0x03], 0x10000) - period; - } - } - - period -= vdelta; - - // handle on tick-N, or all ticks if not in old-effects mode - if (!(csf->flags & SONG_FIRSTTICK) || !(csf->flags & SONG_ITOLDEFFECTS)) { - chan->vibrato_position = (vibpos + 4 * chan->vibrato_speed) & 0xFF; - } + unsigned int vibpos = chan->vibrato_position & 0xFF; + int vdelta; + unsigned int vdepth; + + switch (chan->vib_type) { + case VIB_SINE: + default: + vdelta = sine_table[vibpos]; + break; + case VIB_RAMP_DOWN: + vdelta = ramp_down_table[vibpos]; + break; + case VIB_SQUARE: + vdelta = square_table[vibpos]; + break; + case VIB_RANDOM: + vdelta = 128 * ((double) rand() / RAND_MAX) - 64; + break; + } + + if (csf->flags & SONG_ITOLDEFFECTS) { + vdepth = 5; + vdelta = -vdelta; // yes, IT does vibrato backwards in old-effects mode. try it. + } else { + vdepth = 6; + } + vdelta = (vdelta * (int)chan->vibrato_depth) >> vdepth; + + if (csf->flags & SONG_LINEARSLIDES) { + int l = abs(vdelta); + + if (vdelta < 0) { + vdelta = _muldiv(period, linear_slide_up_table[l >> 2], 0x10000) - period; + + if (l & 0x03) + vdelta += _muldiv(period, fine_linear_slide_up_table[l & 0x03], 0x10000) - period; + } else { + vdelta = _muldiv(period, linear_slide_down_table[l >> 2], 0x10000) - period; + + if (l & 0x03) + vdelta += _muldiv(period, fine_linear_slide_down_table[l & 0x03], 0x10000) - period; + } + } + + period -= vdelta; + + // handle on tick-N, or all ticks if not in old-effects mode + if (!(csf->flags & SONG_FIRSTTICK) || !(csf->flags & SONG_ITOLDEFFECTS)) { + chan->vibrato_position = (vibpos + 4 * chan->vibrato_speed) & 0xFF; + } - return period; + return period; } static inline int rn_sample_vibrato(song_voice_t *chan, int period) { - unsigned int vibpos = chan->autovib_position & 0xFF; - int vdelta, adepth; - song_sample_t *pins = chan->ptr_sample; - - /* - 1) Mov AX, [SomeVariableNameRelatingToVibrato] - 2) Add AL, Rate - 3) AdC AH, 0 - 4) AH contains the depth of the vibrato as a fine-linear slide. - 5) Mov [SomeVariableNameRelatingToVibrato], AX ; For the next cycle. - */ - - adepth = chan->autovib_depth; // (1) - adepth += pins->vib_rate & 0xff; // (2 & 3) - /* need this cast -- if adepth is unsigned, large autovib will crash the mixer (why? I don't know!) - but if vib_depth is changed to signed, that screws up other parts of the code. ugh. */ - adepth = MIN(adepth, (int) (pins->vib_depth << 8)); - chan->autovib_depth = adepth; // (5) - adepth >>= 8; // (4) - - chan->autovib_position += pins->vib_speed; - - switch(pins->vib_type) { - case VIB_SINE: - default: - vdelta = sine_table[vibpos]; - break; - case VIB_RAMP_DOWN: - vdelta = ramp_down_table[vibpos]; - break; - case VIB_SQUARE: - vdelta = square_table[vibpos]; - break; - case VIB_RANDOM: - vdelta = 128 * ((double) rand() / RAND_MAX) - 64; - break; - } - vdelta = (vdelta * adepth) >> 6; - - int l = abs(vdelta); - if (vdelta < 0) { - vdelta = _muldiv(period, linear_slide_down_table[l >> 2], 0x10000) - period; - - if (l & 0x03) - vdelta += _muldiv(period, fine_linear_slide_down_table[l & 0x03], 0x10000) - period; - } else { - vdelta = _muldiv(period, linear_slide_up_table[l >> 2], 0x10000) - period; - - if (l & 0x03) - vdelta += _muldiv(period, fine_linear_slide_up_table[l & 0x03], 0x10000) - period; - } + unsigned int vibpos = chan->autovib_position & 0xFF; + int vdelta, adepth; + song_sample_t *pins = chan->ptr_sample; + + /* + 1) Mov AX, [SomeVariableNameRelatingToVibrato] + 2) Add AL, Rate + 3) AdC AH, 0 + 4) AH contains the depth of the vibrato as a fine-linear slide. + 5) Mov [SomeVariableNameRelatingToVibrato], AX ; For the next cycle. + */ + + adepth = chan->autovib_depth; // (1) + adepth += pins->vib_rate & 0xff; // (2 & 3) + /* need this cast -- if adepth is unsigned, large autovib will crash the mixer (why? I don't know!) + but if vib_depth is changed to signed, that screws up other parts of the code. ugh. */ + adepth = MIN(adepth, (int) (pins->vib_depth << 8)); + chan->autovib_depth = adepth; // (5) + adepth >>= 8; // (4) + + chan->autovib_position += pins->vib_speed; + + switch(pins->vib_type) { + case VIB_SINE: + default: + vdelta = sine_table[vibpos]; + break; + case VIB_RAMP_DOWN: + vdelta = ramp_down_table[vibpos]; + break; + case VIB_SQUARE: + vdelta = square_table[vibpos]; + break; + case VIB_RANDOM: + vdelta = 128 * ((double) rand() / RAND_MAX) - 64; + break; + } + vdelta = (vdelta * adepth) >> 6; + + int l = abs(vdelta); + if (vdelta < 0) { + vdelta = _muldiv(period, linear_slide_up_table[l >> 2], 0x10000) - period; + + if (l & 0x03) + vdelta += _muldiv(period, fine_linear_slide_up_table[l & 0x03], 0x10000) - period; + } else { + vdelta = _muldiv(period, linear_slide_down_table[l >> 2], 0x10000) - period; + + if (l & 0x03) + vdelta += _muldiv(period, fine_linear_slide_down_table[l & 0x03], 0x10000) - period; + } - return period - vdelta; + return period - vdelta; } static inline void rn_process_envelope(song_voice_t *chan, int *nvol) { - song_instrument_t *penv = chan->ptr_instrument; - int vol = *nvol; + song_instrument_t *penv = chan->ptr_instrument; + int vol = *nvol; - // Volume Envelope - if (chan->flags & CHN_VOLENV && penv->vol_env.nodes) { - int envpos = chan->vol_env_position; - unsigned int pt = penv->vol_env.nodes - 1; - - for (unsigned int i = 0; i < (unsigned int)(penv->vol_env.nodes - 1); i++) { - if (envpos <= penv->vol_env.ticks[i]) { - pt = i; - break; - } - } - - int x2 = penv->vol_env.ticks[pt]; - int x1, envvol; - - if (envpos >= x2) { - envvol = penv->vol_env.values[pt] << 2; - x1 = x2; - } else if (pt) { - envvol = penv->vol_env.values[pt-1] << 2; - x1 = penv->vol_env.ticks[pt-1]; - } else { - envvol = 0; - x1 = 0; - } - - if (envpos > x2) - envpos = x2; - - if (x2 > x1 && envpos > x1) { - envvol += ((envpos - x1) * (((int)penv->vol_env.values[pt]<<2) - envvol)) / (x2 - x1); - } - - envvol = CLAMP(envvol, 0, 256); - vol = (vol * envvol) >> 8; - } - - // Panning Envelope - if ((chan->flags & CHN_PANENV) && (penv->pan_env.nodes)) { - int envpos = chan->pan_env_position; - unsigned int pt = penv->pan_env.nodes - 1; - - for (unsigned int i=0; i<(unsigned int)(penv->pan_env.nodes-1); i++) { - if (envpos <= penv->pan_env.ticks[i]) { - pt = i; - break; - } - } - - int x2 = penv->pan_env.ticks[pt], y2 = penv->pan_env.values[pt]; - int x1, envpan; - - if (envpos >= x2) { - envpan = y2; - x1 = x2; - } else if (pt) { - envpan = penv->pan_env.values[pt-1]; - x1 = penv->pan_env.ticks[pt-1]; - } else { - envpan = 128; - x1 = 0; - } - - if (x2 > x1 && envpos > x1) { - envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1); - } - - envpan = CLAMP(envpan, 0, 64); - - int pan = chan->panning; - - if (pan >= 128) { - pan += ((envpan - 32) * (256 - pan)) / 32; - } else { - pan += ((envpan - 32) * (pan)) / 32; - } - - chan->final_panning = pan; - } - - // FadeOut volume - if (chan->flags & CHN_NOTEFADE) { - unsigned int fadeout = penv->fadeout; - - if (fadeout) { - chan->fadeout_volume -= fadeout << 1; - - if (chan->fadeout_volume <= 0) - chan->fadeout_volume = 0; - - vol = (vol * chan->fadeout_volume) >> 16; - } else if (!chan->fadeout_volume) { - vol = 0; - } - } - - // Pitch/Pan separation - if (penv->pitch_pan_separation && chan->final_panning && chan->note) { - // PPS value is 1/512, i.e. PPS=1 will adjust by 8/512 = 1/64 for each 8 semitones - // with PPS = 32 / PPC = C-5, E-6 will pan hard right (and D#6 will not) - chan->final_panning += ((int) (chan->note - penv->pitch_pan_center - 1) - * penv->pitch_pan_separation) / 4; - } + // Volume Envelope + if (chan->flags & CHN_VOLENV && penv->vol_env.nodes) { + int envpos = chan->vol_env_position; + unsigned int pt = penv->vol_env.nodes - 1; + + for (unsigned int i = 0; i < (unsigned int)(penv->vol_env.nodes - 1); i++) { + if (envpos <= penv->vol_env.ticks[i]) { + pt = i; + break; + } + } + + int x2 = penv->vol_env.ticks[pt]; + int x1, envvol; + + if (envpos >= x2) { + envvol = penv->vol_env.values[pt] << 2; + x1 = x2; + } else if (pt) { + envvol = penv->vol_env.values[pt-1] << 2; + x1 = penv->vol_env.ticks[pt-1]; + } else { + envvol = 0; + x1 = 0; + } + + if (envpos > x2) + envpos = x2; + + if (x2 > x1 && envpos > x1) { + envvol += ((envpos - x1) * (((int)penv->vol_env.values[pt]<<2) - envvol)) / (x2 - x1); + } + + envvol = CLAMP(envvol, 0, 256); + vol = (vol * envvol) >> 8; + } + + // Panning Envelope + if ((chan->flags & CHN_PANENV) && (penv->pan_env.nodes)) { + int envpos = chan->pan_env_position; + unsigned int pt = penv->pan_env.nodes - 1; + + for (unsigned int i=0; i<(unsigned int)(penv->pan_env.nodes-1); i++) { + if (envpos <= penv->pan_env.ticks[i]) { + pt = i; + break; + } + } + + int x2 = penv->pan_env.ticks[pt], y2 = penv->pan_env.values[pt]; + int x1, envpan; + + if (envpos >= x2) { + envpan = y2; + x1 = x2; + } else if (pt) { + envpan = penv->pan_env.values[pt-1]; + x1 = penv->pan_env.ticks[pt-1]; + } else { + envpan = 128; + x1 = 0; + } + + if (x2 > x1 && envpos > x1) { + envpan += ((envpos - x1) * (y2 - envpan)) / (x2 - x1); + } + + envpan = CLAMP(envpan, 0, 64); + + int pan = chan->final_panning; + + if (pan >= 128) { + pan += ((envpan - 32) * (256 - pan)) / 32; + } else { + pan += ((envpan - 32) * (pan)) / 32; + } + + chan->final_panning = pan; + } + + // FadeOut volume + if (chan->flags & CHN_NOTEFADE) { + unsigned int fadeout = penv->fadeout; + + if (fadeout) { + chan->fadeout_volume -= fadeout << 1; + + if (chan->fadeout_volume <= 0) + chan->fadeout_volume = 0; + + vol = (vol * chan->fadeout_volume) >> 16; + } else if (!chan->fadeout_volume) { + vol = 0; + } + } + + // Pitch/Pan separation + if (penv->pitch_pan_separation && chan->final_panning && chan->note) { + // PPS value is 1/512, i.e. PPS=1 will adjust by 8/512 = 1/64 for each 8 semitones + // with PPS = 32 / PPC = C-5, E-6 will pan hard right (and D#6 will not) + chan->final_panning += ((int) (chan->note - penv->pitch_pan_center - 1) + * penv->pitch_pan_separation) / 4; + } - *nvol = vol; + *nvol = vol; } static inline int rn_arpeggio(song_t *csf, song_voice_t *chan, int period) { - int a; - switch ((csf->current_speed - csf->tick_count) % 3) { - case 1: - a = chan->mem_arpeggio >> 4; - break; - case 2: - a = chan->mem_arpeggio & 0xf; - break; - default: - a = 0; - } - if (!a) - return period; + int a; - //return get_period_from_note(a + get_note_from_period(period), 8363, 0); - return get_freq_from_period(calc_halftone(get_freq_from_period(period, 8363, 0), a), 8363, 0); + switch ((csf->current_speed - csf->tick_count) % 3) { + case 1: + a = chan->mem_arpeggio >> 4; + break; + case 2: + a = chan->mem_arpeggio & 0xf; + break; + default: + a = 0; + } + + if (!a) + return period; + + a = linear_slide_up_table[a * 16]; + return ((csf->flags & SONG_LINEARSLIDES) + ? _muldiv(period, a, 65536) + : _muldiv(period, 65536, a)); } static inline void rn_pitch_filter_envelope(song_voice_t *chan, int *nenvpitch, int *nperiod) { - song_instrument_t *penv = chan->ptr_instrument; - int envpos = chan->pitch_env_position; - unsigned int pt = penv->pitch_env.nodes - 1; - int period = *nperiod; - int envpitch = *nenvpitch; - - for (unsigned int i = 0; i < (unsigned int)(penv->pitch_env.nodes - 1); i++) { - if (envpos <= penv->pitch_env.ticks[i]) { - pt = i; - break; - } - } - - int x2 = penv->pitch_env.ticks[pt]; - int x1; - - if (envpos >= x2) { - envpitch = (((int)penv->pitch_env.values[pt]) - 32) * 8; - x1 = x2; - } else if (pt) { - envpitch = (((int)penv->pitch_env.values[pt - 1]) - 32) * 8; - x1 = penv->pitch_env.ticks[pt - 1]; - } else { - envpitch = 0; - x1 = 0; - } - - if (envpos > x2) - envpos = x2; - - if (x2 > x1 && envpos > x1) { - int envpitchdest = (((int)penv->pitch_env.values[pt]) - 32) * 8; - envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1); - } - - // clamp to -255/255? - envpitch = CLAMP(envpitch, -256, 256); - - // Pitch Envelope - if (!(penv->flags & ENV_FILTER)) { - int l = abs(envpitch); - - if (l > 255) - l = 255; - - period = _muldiv(period, (envpitch < 0 ? - linear_slide_up_table : linear_slide_down_table)[l], 0x10000); - } + song_instrument_t *penv = chan->ptr_instrument; + int envpos = chan->pitch_env_position; + unsigned int pt = penv->pitch_env.nodes - 1; + int period = *nperiod; + int envpitch = *nenvpitch; + + for (unsigned int i = 0; i < (unsigned int)(penv->pitch_env.nodes - 1); i++) { + if (envpos <= penv->pitch_env.ticks[i]) { + pt = i; + break; + } + } + + int x2 = penv->pitch_env.ticks[pt]; + int x1; + + if (envpos >= x2) { + envpitch = (((int)penv->pitch_env.values[pt]) - 32) * 8; + x1 = x2; + } else if (pt) { + envpitch = (((int)penv->pitch_env.values[pt - 1]) - 32) * 8; + x1 = penv->pitch_env.ticks[pt - 1]; + } else { + envpitch = 0; + x1 = 0; + } + + if (envpos > x2) + envpos = x2; + + if (x2 > x1 && envpos > x1) { + int envpitchdest = (((int)penv->pitch_env.values[pt]) - 32) * 8; + envpitch += ((envpos - x1) * (envpitchdest - envpitch)) / (x2 - x1); + } + + // clamp to -255/255? + envpitch = CLAMP(envpitch, -256, 256); + + // Pitch Envelope + if (!(penv->flags & ENV_FILTER)) { + int l = abs(envpitch); + + if (l > 255) + l = 255; + + period = _muldiv(period, (envpitch < 0 ? + linear_slide_down_table : linear_slide_up_table)[l], 0x10000); + } - *nperiod = period; - *nenvpitch = envpitch; + *nperiod = period; + *nenvpitch = envpitch; } -static inline void rn_increment_env_pos(song_voice_t *chan) +static inline void _process_envelope(song_voice_t *chan, song_instrument_t *penv, song_envelope_t *envelope, + int *position, uint32_t env_flag, uint32_t loop_flag, uint32_t sus_flag, + uint32_t fade_flag) { - song_instrument_t *penv = chan->ptr_instrument; + int start = 0, end = 0x7fffffff; - if (chan->flags & CHN_VOLENV) { - chan->vol_env_position++; + if (!(chan->flags & env_flag)) { + return; + } + + (*position)++; + + if ((penv->flags & sus_flag) && !(chan->flags & CHN_KEYOFF)) { + start = envelope->ticks[envelope->sustain_start]; + end = envelope->ticks[envelope->sustain_end] + 1; + fade_flag = 0; + } else if (penv->flags & loop_flag) { + start = envelope->ticks[envelope->loop_start]; + end = envelope->ticks[envelope->loop_end] + 1; + fade_flag = 0; + } else { + // End of envelope (?) + start = end = envelope->ticks[envelope->nodes - 1]; + } + if (*position >= end) { + if (fade_flag && !envelope->values[envelope->nodes - 1]) { + chan->fadeout_volume = chan->final_volume = 0; + } + *position = start; + chan->flags |= fade_flag; // only relevant for volume envelope + } +} - if (penv->flags & ENV_VOLLOOP) { - int volloopend = penv->vol_env.ticks[penv->vol_env.loop_end] + 1; +static inline void rn_increment_env_pos(song_voice_t *chan) +{ + song_instrument_t *penv = chan->ptr_instrument; - if (chan->vol_env_position == volloopend) { - chan->vol_env_position = penv->vol_env.ticks[penv->vol_env.loop_start]; - if (penv->vol_env.loop_end == penv->vol_env.loop_start - && !penv->vol_env.values[penv->vol_env.loop_start]) { - chan->flags |= CHN_NOTEFADE; - chan->fadeout_volume = 0; - } - } - } - - if (penv->flags & ENV_VOLSUSTAIN - && (chan->vol_env_position == (int)penv->vol_env.ticks[penv->vol_env.sustain_end] + 1) - && !(chan->flags & CHN_KEYOFF)) { - // Volume sustained - chan->vol_env_position = penv->vol_env.ticks[penv->vol_env.sustain_start]; - } else if (chan->vol_env_position > penv->vol_env.ticks[penv->vol_env.nodes - 1]) { - // End of Envelope - chan->vol_env_position = penv->vol_env.ticks[penv->vol_env.nodes - 1]; - chan->flags |= CHN_NOTEFADE; - if (!penv->vol_env.values[penv->vol_env.nodes-1]) { - chan->fadeout_volume = 0; - chan->final_volume = 0; - } - } - } - - if (chan->flags & CHN_PANENV) { - chan->pan_env_position++; - - if (penv->flags & ENV_PANLOOP) { - int panloopend = penv->pan_env.ticks[penv->pan_env.loop_end] + 1; - - if (chan->pan_env_position == panloopend) { - chan->pan_env_position = penv->pan_env.ticks[penv->pan_env.loop_start]; - } - } - - if (penv->flags & ENV_PANSUSTAIN - && (chan->pan_env_position == (int) penv->pan_env.ticks[penv->pan_env.sustain_end] + 1) - && !(chan->flags & CHN_KEYOFF)) { - // Panning sustained - chan->pan_env_position = penv->pan_env.ticks[penv->pan_env.sustain_start]; - } else if (chan->pan_env_position > penv->pan_env.ticks[penv->pan_env.nodes - 1]) { - // End of envelope - chan->pan_env_position = penv->pan_env.ticks[penv->pan_env.nodes - 1]; - } - } - - if (chan->flags & CHN_PITCHENV) { - chan->pitch_env_position++; - - if (penv->flags & ENV_PITCHLOOP) { - int pitchloopend = penv->pitch_env.ticks[penv->pitch_env.loop_end] + 1; - - if (chan->pitch_env_position == pitchloopend) { - chan->pitch_env_position = penv->pitch_env.ticks[penv->pitch_env.loop_start]; - } - } - - if (penv->flags & ENV_PITCHSUSTAIN - && (chan->pitch_env_position == (int) penv->pitch_env.ticks[penv->pitch_env.sustain_end]+1) - && !(chan->flags & CHN_KEYOFF)) { - // Pitch sustained - chan->pitch_env_position = penv->pitch_env.ticks[penv->pitch_env.sustain_start]; - } else if (chan->pitch_env_position > penv->pitch_env.ticks[penv->pitch_env.nodes - 1]) { - // End of envelope - chan->pitch_env_position = penv->pitch_env.ticks[penv->pitch_env.nodes - 1]; - } - } + _process_envelope(chan, penv, &penv->vol_env, &chan->vol_env_position, + CHN_VOLENV, ENV_VOLLOOP, ENV_VOLSUSTAIN, CHN_NOTEFADE); + _process_envelope(chan, penv, &penv->pan_env, &chan->pan_env_position, + CHN_PANENV, ENV_PANLOOP, ENV_PANSUSTAIN, 0); + _process_envelope(chan, penv, &penv->pitch_env, &chan->pitch_env_position, + CHN_PITCHENV, ENV_PITCHLOOP, ENV_PITCHSUSTAIN, 0); } static inline int rn_update_sample(song_t *csf, song_voice_t *chan, int nchan, int master_vol) { - // Adjusting volumes - if (csf->mix_channels < 2 || (csf->flags & SONG_NOSTEREO)) { - chan->right_volume_new = (chan->final_volume * master_vol) >> 8; - chan->left_volume_new = chan->right_volume_new; - } else if ((chan->flags & CHN_SURROUND) && !(csf->mix_flags & SNDMIX_NOSURROUND)) { - chan->right_volume_new = (chan->final_volume * master_vol) >> 8; - chan->left_volume_new = -chan->right_volume_new; - } else { - int pan = ((int) chan->final_panning) - 128; - pan *= (int) csf->pan_separation; - pan /= 128; - - if ((csf->flags & SONG_INSTRUMENTMODE) - && chan->ptr_instrument - && chan->ptr_instrument->midi_channel_mask > 0) - GM_Pan(nchan, pan); - - pan += 128; - pan = CLAMP(pan, 0, 256); - - if (csf->mix_flags & SNDMIX_REVERSESTEREO) - pan = 256 - pan; - - int realvol = (chan->final_volume * master_vol) >> (8 - 1); - - chan->left_volume_new = (realvol * pan) >> 8; - chan->right_volume_new = (realvol * (256 - pan)) >> 8; - } - - // Clipping volumes - if (chan->right_volume_new > 0xFFFF) - chan->right_volume_new = 0xFFFF; - - if (chan->left_volume_new > 0xFFFF) - chan->left_volume_new = 0xFFFF; - - // Check IDO - if (csf->mix_flags & SNDMIX_NORESAMPLING) { - chan->flags &= ~(CHN_HQSRC); - chan->flags |= CHN_NOIDO; - } else { - chan->flags &= ~(CHN_NOIDO | CHN_HQSRC); - - if (chan->increment == 0x10000) { - chan->flags |= CHN_NOIDO; - } else { - if (!(csf->mix_flags & SNDMIX_HQRESAMPLER) && - !(csf->mix_flags & SNDMIX_ULTRAHQSRCMODE)) { - if (chan->increment >= 0xFF00) - chan->flags |= CHN_NOIDO; - } - } - } - - chan->right_volume_new >>= MIXING_ATTENUATION; - chan->left_volume_new >>= MIXING_ATTENUATION; - chan->right_ramp = - chan->left_ramp = 0; - - // Checking Ping-Pong Loops - if (chan->flags & CHN_PINGPONGFLAG) - chan->increment = -chan->increment; - - if (chan->flags & CHN_MUTE) { - chan->left_volume = chan->right_volume = 0; - } else if (!(csf->mix_flags & SNDMIX_NORAMPING) && - chan->flags & CHN_VOLUMERAMP && - (chan->right_volume != chan->right_volume_new || - chan->left_volume != chan->left_volume_new)) { - // Setting up volume ramp - int ramp_length = volume_ramp_samples; - int right_delta = ((chan->right_volume_new - chan->right_volume) << VOLUMERAMPPRECISION); - int left_delta = ((chan->left_volume_new - chan->left_volume) << VOLUMERAMPPRECISION); - - if (csf->mix_flags & SNDMIX_HQRESAMPLER) { - if (chan->right_volume | chan->left_volume && - chan->right_volume_new | chan->left_volume_new && - !(chan->flags & CHN_FASTVOLRAMP)) { - ramp_length = csf->buffer_count; - - int l = (1 << (VOLUMERAMPPRECISION - 1)); - int r =(int) volume_ramp_samples; - - ramp_length = CLAMP(ramp_length, l, r); - } - } - - chan->right_ramp = right_delta / ramp_length; - chan->left_ramp = left_delta / ramp_length; - chan->right_volume = chan->right_volume_new - ((chan->right_ramp * ramp_length) >> VOLUMERAMPPRECISION); - chan->left_volume = chan->left_volume_new - ((chan->left_ramp * ramp_length) >> VOLUMERAMPPRECISION); - - if (chan->right_ramp | chan->left_ramp) { - chan->ramp_length = ramp_length; - } else { - chan->flags &= ~CHN_VOLUMERAMP; - chan->right_volume = chan->right_volume_new; - chan->left_volume = chan->left_volume_new; - } - } else { - chan->flags &= ~CHN_VOLUMERAMP; - chan->right_volume = chan->right_volume_new; - chan->left_volume = chan->left_volume_new; - } - - chan->right_ramp_volume = chan->right_volume << VOLUMERAMPPRECISION; - chan->left_ramp_volume = chan->left_volume << VOLUMERAMPPRECISION; + // Adjusting volumes + if (csf->mix_channels < 2 || (csf->flags & SONG_NOSTEREO)) { + chan->right_volume_new = (chan->final_volume * master_vol) >> 8; + chan->left_volume_new = chan->right_volume_new; + } else if ((chan->flags & CHN_SURROUND) && !(csf->mix_flags & SNDMIX_NOSURROUND)) { + chan->right_volume_new = (chan->final_volume * master_vol) >> 8; + chan->left_volume_new = -chan->right_volume_new; + } else { + int pan = ((int) chan->final_panning) - 128; + pan *= (int) csf->pan_separation; + pan /= 128; + + if ((csf->flags & SONG_INSTRUMENTMODE) + && chan->ptr_instrument + && chan->ptr_instrument->midi_channel_mask > 0) + GM_Pan(nchan, pan); + + pan += 128; + pan = CLAMP(pan, 0, 256); + + if (csf->mix_flags & SNDMIX_REVERSESTEREO) + pan = 256 - pan; + + int realvol = (chan->final_volume * master_vol) >> (8 - 1); + + chan->left_volume_new = (realvol * pan) >> 8; + chan->right_volume_new = (realvol * (256 - pan)) >> 8; + } + + // Clipping volumes + if (chan->right_volume_new > 0xFFFF) + chan->right_volume_new = 0xFFFF; + + if (chan->left_volume_new > 0xFFFF) + chan->left_volume_new = 0xFFFF; + + // Check IDO + if (csf->mix_flags & SNDMIX_NORESAMPLING) { + chan->flags &= ~(CHN_HQSRC); + chan->flags |= CHN_NOIDO; + } else { + chan->flags &= ~(CHN_NOIDO | CHN_HQSRC); + + if (chan->increment == 0x10000) { + chan->flags |= CHN_NOIDO; + } else { + if (!(csf->mix_flags & SNDMIX_HQRESAMPLER) && + !(csf->mix_flags & SNDMIX_ULTRAHQSRCMODE)) { + if (chan->increment >= 0xFF00) + chan->flags |= CHN_NOIDO; + } + } + } + + chan->right_volume_new >>= MIXING_ATTENUATION; + chan->left_volume_new >>= MIXING_ATTENUATION; + chan->right_ramp = + chan->left_ramp = 0; + + // Checking Ping-Pong Loops + if (chan->flags & CHN_PINGPONGFLAG) + chan->increment = -chan->increment; + + if (chan->flags & CHN_MUTE) { + chan->left_volume = chan->right_volume = 0; + } else if (!(csf->mix_flags & SNDMIX_NORAMPING) && + chan->flags & CHN_VOLUMERAMP && + (chan->right_volume != chan->right_volume_new || + chan->left_volume != chan->left_volume_new)) { + // Setting up volume ramp + int ramp_length = volume_ramp_samples; + int right_delta = ((chan->right_volume_new - chan->right_volume) << VOLUMERAMPPRECISION); + int left_delta = ((chan->left_volume_new - chan->left_volume) << VOLUMERAMPPRECISION); + + if (csf->mix_flags & SNDMIX_HQRESAMPLER) { + if (chan->right_volume | chan->left_volume && + chan->right_volume_new | chan->left_volume_new && + !(chan->flags & CHN_FASTVOLRAMP)) { + ramp_length = csf->buffer_count; + + int l = (1 << (VOLUMERAMPPRECISION - 1)); + int r =(int) volume_ramp_samples; + + ramp_length = CLAMP(ramp_length, l, r); + } + } + + chan->right_ramp = right_delta / ramp_length; + chan->left_ramp = left_delta / ramp_length; + chan->right_volume = chan->right_volume_new - ((chan->right_ramp * ramp_length) >> VOLUMERAMPPRECISION); + chan->left_volume = chan->left_volume_new - ((chan->left_ramp * ramp_length) >> VOLUMERAMPPRECISION); + + if (chan->right_ramp | chan->left_ramp) { + chan->ramp_length = ramp_length; + } else { + chan->flags &= ~CHN_VOLUMERAMP; + chan->right_volume = chan->right_volume_new; + chan->left_volume = chan->left_volume_new; + } + } else { + chan->flags &= ~CHN_VOLUMERAMP; + chan->right_volume = chan->right_volume_new; + chan->left_volume = chan->left_volume_new; + } + + chan->right_ramp_volume = chan->right_volume << VOLUMERAMPPRECISION; + chan->left_ramp_volume = chan->left_volume << VOLUMERAMPPRECISION; - // Adding the channel in the channel list - csf->voice_mix[csf->num_voices++] = nchan; + // Adding the channel in the channel list + csf->voice_mix[csf->num_voices++] = nchan; - if (csf->num_voices >= MAX_VOICES) - return 0; + if (csf->num_voices >= MAX_VOICES) + return 0; - return 1; + return 1; } // XXX Rename this static inline void rn_gen_key(song_t *csf, song_voice_t *chan, int chan_num, int freq, int vol) { - if (chan->flags & CHN_MUTE) { - // don't do anything - return; - } else if (csf->flags & SONG_INSTRUMENTMODE && - chan->ptr_instrument && - chan->ptr_instrument->midi_channel_mask > 0) { - MidiBendMode BendMode = MIDI_BEND_NORMAL; - /* TODO: If we're expecting a large bend exclusively - * in either direction, update BendMode to indicate so. - * This can be used to extend the range of MIDI pitch bending. - */ - - // Vol maximum is 64*64 here. (4096) - int volume = vol; - - if (chan->flags & CHN_ADLIB && volume > 0) { - // This gives a value in the range 0..127. - //int o = volume; - volume = find_volume((unsigned short) volume) * chan->instrument_volume / 64; - //fprintf(stderr, "%d -> %d[%d]\n", o, volume, chan->instrument_volume); - } else { - // This gives a value in the range 0..127. - volume = volume * chan->instrument_volume / 8192; - } - - GM_SetFreqAndVol(chan_num, freq, volume, BendMode, chan->flags & CHN_KEYOFF); - } - if (chan->flags & CHN_ADLIB) { - // For some reason, scaling by about (2*3)/(8200/8300) is needed - // to get a frequency that matches with ST3. - int oplfreq = freq * 164 / 249; - - OPL_HertzTouch(chan_num, oplfreq, chan->flags & CHN_KEYOFF); - - // ST32 ignores global & master volume in adlib mode, guess we should do the same -Bisqwit - OPL_Touch(chan_num, NULL, vol * chan->instrument_volume * 63 / (1 << 20)); - } + if (chan->flags & CHN_MUTE) { + // don't do anything + return; + } else if (csf->flags & SONG_INSTRUMENTMODE && + chan->ptr_instrument && + chan->ptr_instrument->midi_channel_mask > 0) { + MidiBendMode BendMode = MIDI_BEND_NORMAL; + /* TODO: If we're expecting a large bend exclusively + * in either direction, update BendMode to indicate so. + * This can be used to extend the range of MIDI pitch bending. + */ + + // Vol maximum is 64*64 here. (4096) + int volume = vol; + + if ((chan->flags & CHN_ADLIB) && volume > 0) { + // This gives a value in the range 0..127. + //int o = volume; + volume = find_volume((unsigned short) volume) * chan->instrument_volume / 64; + //fprintf(stderr, "%d -> %d[%d]\n", o, volume, chan->instrument_volume); + } else { + // This gives a value in the range 0..127. + volume = volume * chan->instrument_volume / 8192; + } + + GM_SetFreqAndVol(chan_num, freq, volume, BendMode, chan->flags & CHN_KEYOFF); + } + if (chan->flags & CHN_ADLIB) { + // Scaling is needed to get a frequency that matches with ST3 notes. + // 8363 is st3s middle C sample rate. 261.625 is the Hertz for middle C in a tempered scale (A4 = 440) + //Also, note that to be true to ST3, the frequencies should be quantized, like using the glissando control. + + int oplmilliHertz = (long long int)freq*261625L/8363L; + OPL_HertzTouch(chan_num, oplmilliHertz, chan->flags & CHN_KEYOFF); + + // ST32 ignores global & master volume in adlib mode, guess we should do the same -Bisqwit + OPL_Touch(chan_num, NULL, vol * chan->instrument_volume * 63 / (1 << 20)); + } } static inline void update_vu_meter(song_voice_t *chan) { - // Update VU-Meter (final_volume is 14-bit) - // TODO: missing background channels by doing it this way. - // need to use nMasterCh, add the vu meters for each physical voice, and bit shift. - uint32_t vutmp = chan->final_volume >> (14 - 8); - if (vutmp > 0xFF) vutmp = 0xFF; - if (chan->flags & CHN_ADLIB) { - // fake VU decay (intentionally similar to ST3) - if (chan->vu_meter > VUMETER_DECAY) { - chan->vu_meter -= VUMETER_DECAY; - } else { - chan->vu_meter = 0; - } - if (chan->vu_meter >= 0x100) { - chan->vu_meter = vutmp; - } - } else if (vutmp && chan->current_sample_data) { - // can't fake the funk - int n; - int pos = chan->position; // necessary on 64-bit systems (sometimes pos == -1, weird) - if (chan->flags & CHN_16BIT) { - const signed short *p = (signed short *)(chan->current_sample_data); - if (chan->flags & CHN_STEREO) - n = p[2 * pos]; - else - n = p[pos]; - n >>= 8; - } else { - const signed char *p = (signed char *)(chan->current_sample_data); - if (chan->flags & CHN_STEREO) - n = p[2 * pos]; - else - n = p[pos]; - } - if (n < 0) - n = -n; - vutmp *= n; - vutmp >>= 7; // 0..255 - if (vutmp) - chan->vu_meter = vutmp; - } else { - chan->vu_meter = 0; - } + // Update VU-Meter (final_volume is 14-bit) + // TODO: missing background channels by doing it this way. + // need to use nMasterCh, add the vu meters for each physical voice, and bit shift. + uint32_t vutmp = chan->final_volume >> (14 - 8); + if (vutmp > 0xFF) vutmp = 0xFF; + if (chan->flags & CHN_ADLIB) { + if (chan->strike>2) { chan->vu_meter=(0xFF*chan->final_volume)>>14;} + // fake VU decay (intentionally similar to ST3) + if (chan->vu_meter > VUMETER_DECAY) { + chan->vu_meter -= VUMETER_DECAY; + } else { + chan->vu_meter = 0; + } + if (chan->vu_meter >= 0x100) { + chan->vu_meter = vutmp; + } + } else if (vutmp && chan->current_sample_data) { + // can't fake the funk + int n; + int pos = chan->position; // necessary on 64-bit systems (sometimes pos == -1, weird) + if (chan->flags & CHN_16BIT) { + const signed short *p = (signed short *)(chan->current_sample_data); + if (chan->flags & CHN_STEREO) + n = p[2 * pos]; + else + n = p[pos]; + n >>= 8; + } else { + const signed char *p = (signed char *)(chan->current_sample_data); + if (chan->flags & CHN_STEREO) + n = p[2 * pos]; + else + n = p[pos]; + } + if (n < 0) + n = -n; + vutmp *= n; + vutmp >>= 7; // 0..255 + chan->vu_meter = vutmp; + } else { + chan->vu_meter = 0; + } } //////////////////////////////////////////////////////////////////////////////////////////// int csf_init_player(song_t *csf, int reset) { - if (max_voices > MAX_VOICES) - max_voices = MAX_VOICES; + if (max_voices > MAX_VOICES) + max_voices = MAX_VOICES; + + csf->mix_frequency = CLAMP(csf->mix_frequency, 4000, MAX_SAMPLE_RATE); + volume_ramp_samples = (csf->mix_frequency * VOLUMERAMPLEN) / 100000; + + if (volume_ramp_samples < 8) + volume_ramp_samples = 8; + + if (csf->mix_flags & SNDMIX_NORAMPING) + volume_ramp_samples = 2; - csf->mix_frequency = CLAMP(csf->mix_frequency, 4000, MAX_SAMPLE_RATE); - volume_ramp_samples = (csf->mix_frequency * VOLUMERAMPLEN) / 100000; + g_dry_rofs_vol = g_dry_lofs_vol = 0; - if (volume_ramp_samples < 8) - volume_ramp_samples = 8; + if (reset) { + global_vu_left = 0; + global_vu_right = 0; + } - if (csf->mix_flags & SNDMIX_NORAMPING) - volume_ramp_samples = 2; - - g_dry_rofs_vol = g_dry_lofs_vol = 0; - - if (reset) { - global_vu_left = 0; - global_vu_right = 0; - } - - csf_initialize_dsp(csf, reset); - initialize_eq(reset, csf->mix_frequency); - - // retarded hackaround to get adlib to suck less - if (csf->mix_frequency != 4000) - Fmdrv_Init(csf->mix_frequency); - OPL_Reset(); - GM_Reset(0); - return 1; + initialize_eq(reset, csf->mix_frequency); + + // retarded hackaround to get adlib to suck less + if (csf->mix_frequency != 4000) + Fmdrv_Init(csf->mix_frequency); + OPL_Reset(); + GM_Reset(0); + return 1; } unsigned int csf_read(song_t *csf, void * v_buffer, unsigned int bufsize) { - uint8_t * buffer = (uint8_t *)v_buffer; - convert_t convert_func = clip_32_to_8; - int32_t vu_min[2]; - int32_t vu_max[2]; - unsigned int bufleft, max, sample_size, count, smpcount, mix_stat=0; - - vu_min[0] = vu_min[1] = 0x7FFFFFFF; - vu_max[0] = vu_max[1] = -0x7FFFFFFF; - - - csf->mix_stat = 0; - sample_size = csf->mix_channels; - - if (csf->mix_bits_per_sample == 16) { sample_size *= 2; convert_func = clip_32_to_16; } - else if (csf->mix_bits_per_sample == 24) { sample_size *= 3; convert_func = clip_32_to_24; } - else if (csf->mix_bits_per_sample == 32) { sample_size *= 4; convert_func = clip_32_to_32; } - - max = bufsize / sample_size; - - if (!max || !buffer) { - printf("no buf what the fuck\n"); - return 0; - } - - bufleft = max; - - if (csf->flags & SONG_ENDREACHED) - bufleft = 0; // skip the loop - - while (bufleft > 0) { - // Update Channel Data - - if (!csf->buffer_count) { - if (!(csf->mix_flags & SNDMIX_DIRECTTODISK)) - csf->buffer_count = bufleft; - - if (!csf_read_note(csf)) { - csf->flags |= SONG_ENDREACHED; - - if (csf->stop_at_order > -1) - return 0; /* faster */ - - if (bufleft == max) - break; - - if (!(csf->mix_flags & SNDMIX_DIRECTTODISK)) - csf->buffer_count = bufleft; - } - - if (!csf->buffer_count) - break; - } - - count = csf->buffer_count; - - if (count > MIXBUFFERSIZE) - count = MIXBUFFERSIZE; - - if (count > bufleft) - count = bufleft; - - if (!count) - break; - - smpcount = count; - - // Resetting sound buffer - stereo_fill(csf->mix_buffer, smpcount, &g_dry_rofs_vol, &g_dry_lofs_vol); - - if (csf->mix_channels >= 2) { - smpcount *= 2; - csf->mix_stat += csf_create_stereo_mix(csf, count); - csf_process_stereo_dsp(csf, count); - } else { - csf->mix_stat += csf_create_stereo_mix(csf, count); - mono_from_stereo(csf->mix_buffer, count); - csf_process_mono_dsp(csf, count); - } - - if (csf->mix_flags & SNDMIX_EQ) { - if (csf->mix_channels >= 2) - eq_stereo(csf, csf->mix_buffer, count); - else - eq_mono(csf, csf->mix_buffer, count); - } - - mix_stat++; - - if (csf->multi_write) { - /* multi doesn't actually write meaningful data into 'buffer', so we can use that - as temp space for converting */ - for (unsigned int n = 0; n < 64; n++) { - if (csf->multi_write[n].used) { - unsigned int bytes = convert_func(buffer, csf->multi_write[n].buffer, - smpcount, vu_min, vu_max); - csf->multi_write[n].write(csf->multi_write[n].data, buffer, bytes); - } else { - csf->multi_write[n].silence(csf->multi_write[n].data, - smpcount * ((csf->mix_bits_per_sample + 7) / 8)); - } - } - } else { - // Perform clipping + VU-Meter - buffer += convert_func(buffer, csf->mix_buffer, smpcount, vu_min, vu_max); - } - - // Buffer ready - bufleft -= count; - csf->buffer_count -= count; - } - - if (bufleft) - memset(buffer, (csf->mix_bits_per_sample == 8) ? 0x80 : 0, bufleft * sample_size); - - // VU-Meter - vu_min[0] >>= 18; - vu_min[1] >>= 18; - vu_max[0] >>= 18; - vu_max[1] >>= 18; - - if (vu_max[0] < vu_min[0]) - vu_max[0] = vu_min[0]; - - if (vu_max[1] < vu_min[1]) - vu_max[1] = vu_min[1]; - - if ((global_vu_left = (unsigned int)(vu_max[0] - vu_min[0])) > 0xFF) - global_vu_left = 0xFF; - - if ((global_vu_right = (unsigned int)(vu_max[1] - vu_min[1])) > 0xFF) - global_vu_right = 0xFF; - - if (mix_stat) { - csf->mix_stat += mix_stat - 1; - csf->mix_stat /= mix_stat; - } + uint8_t * buffer = (uint8_t *)v_buffer; + convert_t convert_func = clip_32_to_8; + int32_t vu_min[2]; + int32_t vu_max[2]; + unsigned int bufleft, max, sample_size, count, smpcount, mix_stat=0; + + vu_min[0] = vu_min[1] = 0x7FFFFFFF; + vu_max[0] = vu_max[1] = -0x7FFFFFFF; + + + csf->mix_stat = 0; + sample_size = csf->mix_channels; + + if (csf->mix_bits_per_sample == 16) { sample_size *= 2; convert_func = clip_32_to_16; } + else if (csf->mix_bits_per_sample == 24) { sample_size *= 3; convert_func = clip_32_to_24; } + else if (csf->mix_bits_per_sample == 32) { sample_size *= 4; convert_func = clip_32_to_32; } + + max = bufsize / sample_size; + + if (!max || !buffer) { + return 0; + } + + bufleft = max; + + if (csf->flags & SONG_ENDREACHED) + bufleft = 0; // skip the loop + + while (bufleft > 0) { + // Update Channel Data + + if (!csf->buffer_count) { + if (!(csf->mix_flags & SNDMIX_DIRECTTODISK)) + csf->buffer_count = bufleft; + + if (!csf_read_note(csf)) { + csf->flags |= SONG_ENDREACHED; + + if (csf->stop_at_order > -1) + return 0; /* faster */ + + if (bufleft == max) + break; + + if (!(csf->mix_flags & SNDMIX_DIRECTTODISK)) + csf->buffer_count = bufleft; + } + + if (!csf->buffer_count) + break; + } + + count = csf->buffer_count; + + if (count > MIXBUFFERSIZE) + count = MIXBUFFERSIZE; + + if (count > bufleft) + count = bufleft; + + if (!count) + break; + + smpcount = count; + + // Resetting sound buffer + stereo_fill(csf->mix_buffer, smpcount, &g_dry_rofs_vol, &g_dry_lofs_vol); + + if (csf->mix_channels >= 2) { + smpcount *= 2; + csf->mix_stat += csf_create_stereo_mix(csf, count); + } else { + csf->mix_stat += csf_create_stereo_mix(csf, count); + mono_from_stereo(csf->mix_buffer, count); + } + + // Handle eq + if (csf->mix_channels >= 2) + eq_stereo(csf, csf->mix_buffer, count); + else + eq_mono(csf, csf->mix_buffer, count); + + mix_stat++; + + if (csf->multi_write) { + /* multi doesn't actually write meaningful data into 'buffer', so we can use that + as temp space for converting */ + for (unsigned int n = 0; n < 64; n++) { + if (csf->multi_write[n].used) { + unsigned int bytes = convert_func(buffer, csf->multi_write[n].buffer, + smpcount, vu_min, vu_max); + csf->multi_write[n].write(csf->multi_write[n].data, buffer, bytes); + } else { + csf->multi_write[n].silence(csf->multi_write[n].data, + smpcount * ((csf->mix_bits_per_sample + 7) / 8)); + } + } + } else { + // Perform clipping + VU-Meter + buffer += convert_func(buffer, csf->mix_buffer, smpcount, vu_min, vu_max); + } + + // Buffer ready + bufleft -= count; + csf->buffer_count -= count; + } + + if (bufleft) + memset(buffer, (csf->mix_bits_per_sample == 8) ? 0x80 : 0, bufleft * sample_size); + + // VU-Meter + //Reduce range to 8bits signed (-128 to 127). + vu_min[0] >>= 19; + vu_min[1] >>= 19; + vu_max[0] >>= 19; + vu_max[1] >>= 19; + + if (vu_max[0] < vu_min[0]) + vu_max[0] = vu_min[0]; + + if (vu_max[1] < vu_min[1]) + vu_max[1] = vu_min[1]; + + global_vu_left = (unsigned int)(vu_max[0] - vu_min[0]); + + global_vu_right = (unsigned int)(vu_max[1] - vu_min[1]); + + if (mix_stat) { + csf->mix_stat += mix_stat - 1; + csf->mix_stat /= mix_stat; + } - return max - bufleft; + return max - bufleft; } @@ -897,157 +874,162 @@ static int increment_order(song_t *csf) { - csf->process_row = csf->break_row; /* [ProcessRow = BreakRow] */ - csf->break_row = 0; /* [BreakRow = 0] */ + csf->process_row = csf->break_row; /* [ProcessRow = BreakRow] */ + csf->break_row = 0; /* [BreakRow = 0] */ - /* some ugly copypasta, this should be less dumb */ - if (csf->flags & SONG_PATTERNPLAYBACK) { - /* process_order is hijacked as a "playback initiated" flag -- otherwise repeat count - would be incremented as soon as pattern playback started. (this is a stupid hack) */ - if (csf->process_order) { - if (++csf->repeat_count) { - if (UNLIKELY(csf->repeat_count < 0)) { - csf->repeat_count = 1; // it overflowed! - } - } else { - csf->process_row = PROCESS_NEXT_ORDER; - return 0; - } - } else { - csf->process_order = 1; - } - } else if (!(csf->flags & SONG_ORDERLOCKED)) { - /* [Increase ProcessOrder] */ - /* [while Order[ProcessOrder] = 0xFEh, increase ProcessOrder] */ - do { - csf->process_order++; - } while (csf->orderlist[csf->process_order] == ORDER_SKIP); - - /* [if Order[ProcessOrder] = 0xFFh, ProcessOrder = 0] (... or just stop playing) */ - if (csf->orderlist[csf->process_order] == ORDER_LAST) { - if (++csf->repeat_count) { - if (UNLIKELY(csf->repeat_count < 0)) { - csf->repeat_count = 1; // it overflowed! - } - } else { - csf->process_row = PROCESS_NEXT_ORDER; - return 0; - } - - csf->process_order = 0; - while (csf->orderlist[csf->process_order] == ORDER_SKIP) - csf->process_order++; - } - if (csf->orderlist[csf->process_order] >= MAX_PATTERNS) { - // what the butt? - csf->process_row = PROCESS_NEXT_ORDER; - return 0; - } - - /* [CurrentPattern = Order[ProcessOrder]] */ - csf->current_order = csf->process_order; - csf->current_pattern = csf->orderlist[csf->process_order]; - } - - if (!csf->pattern_size[csf->current_pattern] || !csf->patterns[csf->current_pattern]) { - /* okay, this is wrong. allocate the pattern _NOW_ */ - csf->patterns[csf->current_pattern] = csf_allocate_pattern(64); - csf->pattern_size[csf->current_pattern] = 64; - csf->pattern_alloc_size[csf->current_pattern] = 64; - } + /* some ugly copypasta, this should be less dumb */ + if (csf->flags & SONG_PATTERNPLAYBACK) { + /* process_order is hijacked as a "playback initiated" flag -- otherwise repeat count + would be incremented as soon as pattern playback started. (this is a stupid hack) */ + if (csf->process_order) { + if (++csf->repeat_count) { + if (UNLIKELY(csf->repeat_count < 0)) { + csf->repeat_count = 1; // it overflowed! + } + } else { + csf->process_row = PROCESS_NEXT_ORDER; + return 0; + } + } else { + csf->process_order = 1; + } + } else if (!(csf->flags & SONG_ORDERLOCKED)) { + /* [Increase ProcessOrder] */ + /* [while Order[ProcessOrder] = 0xFEh, increase ProcessOrder] */ + do { + csf->process_order++; + } while (csf->orderlist[csf->process_order] == ORDER_SKIP); + + /* [if Order[ProcessOrder] = 0xFFh, ProcessOrder = 0] (... or just stop playing) */ + if (csf->orderlist[csf->process_order] == ORDER_LAST) { + if (++csf->repeat_count) { + if (UNLIKELY(csf->repeat_count < 0)) { + csf->repeat_count = 1; // it overflowed! + } + } else { + csf->process_row = PROCESS_NEXT_ORDER; + return 0; + } + + csf->process_order = 0; + while (csf->orderlist[csf->process_order] == ORDER_SKIP) + csf->process_order++; + } + if (csf->orderlist[csf->process_order] >= MAX_PATTERNS) { + // what the butt? + csf->process_row = PROCESS_NEXT_ORDER; + return 0; + } + + /* [CurrentPattern = Order[ProcessOrder]] */ + csf->current_order = csf->process_order; + csf->current_pattern = csf->orderlist[csf->process_order]; + } + + if (!csf->pattern_size[csf->current_pattern] || !csf->patterns[csf->current_pattern]) { + /* okay, this is wrong. allocate the pattern _NOW_ */ + csf->patterns[csf->current_pattern] = csf_allocate_pattern(64); + csf->pattern_size[csf->current_pattern] = 64; + csf->pattern_alloc_size[csf->current_pattern] = 64; + } + + if (csf->process_row >= csf->pattern_size[csf->current_pattern]) { + // Cxx to row beyond end of pattern: use 0 instead + csf->process_row = 0; + } - return 1; + return 1; } int csf_process_tick(song_t *csf) { - csf->flags &= ~SONG_FIRSTTICK; - /* [Decrease tick counter. Is tick counter 0?] */ - if (--csf->tick_count == 0) { - /* [-- Yes --] */ - - /* [Tick counter = Tick counter set (the current 'speed')] */ - csf->tick_count = csf->current_speed; - - /* [Decrease row counter. Is row counter 0?] */ - if (--csf->row_count <= 0) { - /* [-- Yes --] */ - - /* [Row counter = 1] - this uses zero, in order to simplify SEx effect handling -- SEx has no effect if a - channel to its left has already set the delay value. thus we set the row counter - there to (value + 1) which is never zero, but 0 and 1 are fundamentally equivalent - as far as csf_process_tick is concerned. */ - csf->row_count = 0; - - /* [Increase ProcessRow. Is ProcessRow > NumberOfRows?] */ - if (++csf->process_row >= csf->pattern_size[csf->current_pattern]) { - /* [-- Yes --] */ - - if (!increment_order(csf)) - return 0; - } /* else [-- No --] */ - - /* [CurrentRow = ProcessRow] */ - csf->row = csf->process_row; - - /* [Update Pattern Variables] - (this is handled along with update effects) */ - csf->flags |= SONG_FIRSTTICK; - } else { - /* [-- No --] */ - /* Call update-effects for each channel. */ - } - - - // Reset channel values - song_voice_t *chan = csf->voices; - song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS; - - for (unsigned int nchan=0; nchanrow_note = m->note; - - if (m->instrument) - chan->last_instrument = m->instrument; - - chan->row_instr = m->instrument; - chan->row_voleffect = m->voleffect; - chan->row_volparam = m->volparam; - chan->row_effect = m->effect; - chan->row_param = m->param; - - chan->left_volume = chan->left_volume_new; - chan->right_volume = chan->right_volume_new; - chan->flags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO); - chan->n_command = 0; - } - - csf_process_effects(csf, 1); - } else { - /* [-- No --] */ - /* [Update effects for each channel as required.] */ - - if (csf_midi_out_note) { - song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS; - - for (unsigned int nchan=0; nchanflags &= ~SONG_FIRSTTICK; + /* [Decrease tick counter. Is tick counter 0?] */ + if (--csf->tick_count == 0) { + /* [-- Yes --] */ + + /* [Tick counter = Tick counter set (the current 'speed')] */ + csf->tick_count = csf->current_speed; + + /* [Decrease row counter. Is row counter 0?] */ + if (--csf->row_count <= 0) { + /* [-- Yes --] */ + + /* [Row counter = 1] + this uses zero, in order to simplify SEx effect handling -- SEx has no effect if a + channel to its left has already set the delay value. thus we set the row counter + there to (value + 1) which is never zero, but 0 and 1 are fundamentally equivalent + as far as csf_process_tick is concerned. */ + csf->row_count = 0; + + /* [Increase ProcessRow. Is ProcessRow > NumberOfRows?] */ + if (++csf->process_row >= csf->pattern_size[csf->current_pattern]) { + /* [-- Yes --] */ + + if (!increment_order(csf)) + return 0; + } /* else [-- No --] */ + + /* [CurrentRow = ProcessRow] */ + csf->row = csf->process_row; + + /* [Update Pattern Variables] + (this is handled along with update effects) */ + csf->flags |= SONG_FIRSTTICK; + } else { + /* [-- No --] */ + /* Call update-effects for each channel. */ + } + + + // Reset channel values + song_voice_t *chan = csf->voices; + song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS; + + for (unsigned int nchan=0; nchanrow_note = m->note; + + if (m->instrument) + chan->last_instrument = m->instrument; + + chan->row_instr = m->instrument; + chan->row_voleffect = m->voleffect; + chan->row_volparam = m->volparam; + chan->row_effect = m->effect; + chan->row_param = m->param; + + chan->left_volume = chan->left_volume_new; + chan->right_volume = chan->right_volume_new; + chan->flags &= ~(CHN_PORTAMENTO | CHN_VIBRATO | CHN_TREMOLO); + chan->n_command = 0; + } + + csf_process_effects(csf, 1); + } else { + /* [-- No --] */ + /* [Update effects for each channel as required.] */ + + if (csf_midi_out_note) { + song_note_t *m = csf->patterns[csf->current_pattern] + csf->row * MAX_CHANNELS; + + for (unsigned int nchan=0; nchanflags & SONG_PAUSED) { - if (!csf->current_speed) - csf->current_speed = csf->initial_speed ?: 6; - if (!csf->current_tempo) - csf->current_tempo = csf->initial_tempo ?: 125; - - csf->flags &= ~SONG_FIRSTTICK; - - if (--csf->tick_count == 0) { - csf->tick_count = csf->current_speed; - if (--csf->row_count <= 0) { - csf->row_count = 0; - //csf->flags |= SONG_FIRSTTICK; - } - // clear channel values (similar to csf_process_tick) - for (cn = 0, chan = csf->voices; cn < MAX_CHANNELS; cn++, chan++) { - chan->row_note = 0; - chan->row_instr = 0; - chan->row_voleffect = 0; - chan->row_volparam = 0; - chan->row_effect = 0; - chan->row_param = 0; - chan->n_command = 0; - } - } - csf_process_effects(csf, 0); - } else { - if (!csf_process_tick(csf)) - return 0; - } - - //////////////////////////////////////////////////////////////////////////////////// - - if (!csf->current_tempo) - return 0; - - csf->buffer_count = (csf->mix_frequency * 5 * csf->tempo_factor) / (csf->current_tempo << 8); - - // chaseback hoo hah - if (csf->stop_at_order > -1 && csf->stop_at_row > -1) { - if (csf->stop_at_order <= (signed) csf->current_order && - csf->stop_at_row <= (signed) csf->row) { - return 0; - } - } - - //////////////////////////////////////////////////////////////////////////////////// - // Update channels data - - // Master Volume + Pre-Amplification / Attenuation setup - uint32_t master_vol = csf->mixing_volume << 2; // yields maximum of 0x200 - - csf->num_voices = 0; - - for (cn = 0, chan = csf->voices; cn < MAX_VOICES; cn++, chan++) { - /*if(cn == 0 || cn == 1) - fprintf(stderr, "considering channel %d (per %d, pos %d/%d, flags %X)\n", - (int)cn, chan->period, chan->position, chan->length, chan->flags);*/ - - if (chan->flags & CHN_NOTEFADE && - !(chan->fadeout_volume | chan->right_volume | chan->left_volume)) { - chan->length = 0; - chan->rofs = - chan->lofs = 0; - continue; - } - - // Check for unused channel - if (cn >= MAX_CHANNELS && !chan->length) { - continue; - } - - // Reset channel data - chan->increment = 0; - chan->final_volume = 0; - chan->final_panning = chan->panning + chan->pan_swing + chan->panbrello_delta; - chan->ramp_length = 0; - - // Calc Frequency - if (chan->period && chan->length) { - int vol = chan->volume + chan->vol_swing; - - if (chan->flags & CHN_TREMOLO) - vol += chan->tremolo_delta; - - vol = CLAMP(vol, 0, 256); - - // Tremor - if (chan->n_command == FX_TREMOR) - rn_tremor(chan, &vol); - - // Clip volume - vol = CLAMP(vol, 0, 0x100); - vol <<= 6; - - // Process Envelopes - if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument) { - rn_process_envelope(chan, &vol); - } else { - // No Envelope: key off => note cut - // 1.41-: CHN_KEYOFF|CHN_NOTEFADE - if (chan->flags & CHN_NOTEFADE) { - chan->fadeout_volume = 0; - vol = 0; - } - } - - // vol is 14-bits - if (vol) { - // IMPORTANT: chan->final_volume is 14 bits !!! - // -> _muldiv( 14+7, 6+6, 18); => RealVolume: 14-bit result (21+12-19) - chan->final_volume = _muldiv(vol * csf->current_global_volume, - chan->global_volume * chan->instrument_volume, 1 << 19); - } - - int period = chan->period; - - if ((chan->flags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO)) { - period = get_period_from_note(get_note_from_period(period), - chan->c5speed, csf->flags & SONG_LINEARSLIDES); - } - - // Arpeggio ? - if (chan->n_command == FX_ARPEGGIO) - period = rn_arpeggio(csf, chan, period); - - // Pitch/Filter Envelope - int envpitch = 0; - - if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument - && (chan->flags & CHN_PITCHENV) && chan->ptr_instrument->pitch_env.nodes) - rn_pitch_filter_envelope(chan, &envpitch, &period); - - // Vibrato - if (chan->flags & CHN_VIBRATO) - period = rn_vibrato(csf, chan, period); - - // Sample Auto-Vibrato - if (chan->ptr_sample && chan->ptr_sample->vib_depth) { - period = rn_sample_vibrato(chan, period); - } - - unsigned int freq = get_freq_from_period(period, chan->c5speed, - csf->flags & SONG_LINEARSLIDES); - - if (!(chan->flags & CHN_NOTEFADE)) - rn_gen_key(csf, chan, cn, freq, vol); - - // Filter Envelope: controls cutoff frequency - if (chan && chan->ptr_instrument && chan->ptr_instrument->flags & ENV_FILTER) { - setup_channel_filter(chan, - !(chan->flags & CHN_FILTER), envpitch, csf->mix_frequency); - } - - chan->sample_freq = freq; - - unsigned int ninc = _muldiv(freq, 0x10000, csf->mix_frequency); - - if (ninc >= 0xFFB0 && ninc <= 0x10090) - ninc = 0x10000; - - if (csf->freq_factor != 128) - ninc = (ninc * csf->freq_factor) >> 7; - - if (ninc > 0xFF0000) - ninc = 0xFF0000; - - chan->increment = (ninc + 1) & ~3; - } - - // Increment envelope position - if (csf->flags & SONG_INSTRUMENTMODE && chan->ptr_instrument) - rn_increment_env_pos(chan); - - chan->final_panning = CLAMP(chan->final_panning, 0, 256); - - // Volume ramping - chan->flags &= ~CHN_VOLUMERAMP; - - if (chan->final_volume || chan->left_volume || chan->right_volume) - chan->flags |= CHN_VOLUMERAMP; - - if (chan->strike) - chan->strike--; - - // Check for too big increment - if (((chan->increment >> 16) + 1) >= (int)(chan->loop_end - chan->loop_start)) - chan->flags &= ~CHN_LOOP; - - chan->right_volume_new = chan->left_volume_new = 0; - if (!(chan->length && chan->increment)) - chan->current_sample_data = NULL; - - update_vu_meter(chan); - - if (chan->current_sample_data) { - if (!rn_update_sample(csf, chan, cn, master_vol)) - break; - } else { - // Note change but no sample - //if (chan->vu_meter > 0xFF) chan->vu_meter = 0; - chan->left_volume = chan->right_volume = 0; - chan->length = 0; - } - } - - // Checking Max Mix Channels reached: ordering by volume - if (csf->num_voices >= max_voices && (!(csf->mix_flags & SNDMIX_DIRECTTODISK))) { - for (unsigned int i = 0; i < csf->num_voices; i++) { - unsigned int j = i; - - while ((j + 1 < csf->num_voices) && - (csf->voices[csf->voice_mix[j]].final_volume - < csf->voices[csf->voice_mix[j + 1]].final_volume)) - { - unsigned int n = csf->voice_mix[j]; - csf->voice_mix[j] = csf->voice_mix[j + 1]; - csf->voice_mix[j + 1] = n; - j++; - } - } - } + // Checking end of row ? + if (csf->flags & SONG_PAUSED) { + if (!csf->current_speed) + csf->current_speed = csf->initial_speed ?: 6; + if (!csf->current_tempo) + csf->current_tempo = csf->initial_tempo ?: 125; + + csf->flags &= ~SONG_FIRSTTICK; + + if (--csf->tick_count == 0) { + csf->tick_count = csf->current_speed; + if (--csf->row_count <= 0) { + csf->row_count = 0; + //csf->flags |= SONG_FIRSTTICK; + } + // clear channel values (similar to csf_process_tick) + for (cn = 0, chan = csf->voices; cn < MAX_CHANNELS; cn++, chan++) { + chan->row_note = 0; + chan->row_instr = 0; + chan->row_voleffect = 0; + chan->row_volparam = 0; + chan->row_effect = 0; + chan->row_param = 0; + chan->n_command = 0; + } + } + csf_process_effects(csf, 0); + } else { + if (!csf_process_tick(csf)) + return 0; + } + + //////////////////////////////////////////////////////////////////////////////////// + + if (!csf->current_tempo) + return 0; + + csf->buffer_count = (csf->mix_frequency * 5 * csf->tempo_factor) / (csf->current_tempo << 8); + + // chaseback hoo hah + if (csf->stop_at_order > -1 && csf->stop_at_row > -1) { + if (csf->stop_at_order <= (signed) csf->current_order && + csf->stop_at_row <= (signed) csf->row) { + return 0; + } + } + + //////////////////////////////////////////////////////////////////////////////////// + // Update channels data + + // Master Volume + Pre-Amplification / Attenuation setup + uint32_t master_vol = csf->mixing_volume << 2; // yields maximum of 0x200 + + csf->num_voices = 0; + + for (cn = 0, chan = csf->voices; cn < MAX_VOICES; cn++, chan++) { + /*if(cn == 0 || cn == 1) + fprintf(stderr, "considering channel %d (per %d, pos %d/%d, flags %X)\n", + (int)cn, chan->period, chan->position, chan->length, chan->flags);*/ + + if (chan->flags & CHN_NOTEFADE && + !(chan->fadeout_volume | chan->right_volume | chan->left_volume)) { + chan->length = 0; + chan->rofs = + chan->lofs = 0; + continue; + } + + // Check for unused channel + if (cn >= MAX_CHANNELS && !chan->length) { + continue; + } + + // Reset channel data + chan->increment = 0; + chan->final_volume = 0; + chan->final_panning = chan->panning + chan->pan_swing + chan->panbrello_delta; + chan->ramp_length = 0; + + // Calc Frequency + if (chan->period && (chan->length || (chan->flags & CHN_ADLIB))) { + int vol = chan->volume; + + if (chan->flags & CHN_TREMOLO) + vol += chan->tremolo_delta; + + vol = CLAMP(vol, 0, 256); + + // Tremor + if (chan->n_command == FX_TREMOR) + rn_tremor(chan, &vol); + + // Clip volume + vol = CLAMP(vol, 0, 0x100); + vol <<= 6; + + // Process Envelopes + if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument) { + rn_process_envelope(chan, &vol); + } else { + // No Envelope: key off => note cut + // 1.41-: CHN_KEYOFF|CHN_NOTEFADE + if (chan->flags & CHN_NOTEFADE) { + chan->fadeout_volume = 0; + vol = 0; + } + } + + // vol is 14-bits + if (vol) { + // IMPORTANT: chan->final_volume is 14 bits !!! + // -> _muldiv( 14+7, 6+6, 18); => RealVolume: 14-bit result (21+12-19) + chan->final_volume = _muldiv + (vol * csf->current_global_volume, + chan->global_volume + * CLAMP(chan->instrument_volume + chan->vol_swing, 0, 64), + 1 << 19); + } + + int period = chan->period; + + if ((chan->flags & (CHN_GLISSANDO|CHN_PORTAMENTO)) == (CHN_GLISSANDO|CHN_PORTAMENTO)) { + period = get_period_from_note(get_note_from_period(period), + chan->c5speed, csf->flags & SONG_LINEARSLIDES); + } + + // Arpeggio ? + if (chan->n_command == FX_ARPEGGIO) + period = rn_arpeggio(csf, chan, period); + + // Pitch/Filter Envelope + int envpitch = 0; + + if ((csf->flags & SONG_INSTRUMENTMODE) && chan->ptr_instrument + && (chan->flags & CHN_PITCHENV) && chan->ptr_instrument->pitch_env.nodes) + rn_pitch_filter_envelope(chan, &envpitch, &period); + + // Vibrato + if (chan->flags & CHN_VIBRATO) + period = rn_vibrato(csf, chan, period); + + // Sample Auto-Vibrato + if (chan->ptr_sample && chan->ptr_sample->vib_depth) { + period = rn_sample_vibrato(chan, period); + } + + unsigned int freq = get_freq_from_period(period, csf->flags & SONG_LINEARSLIDES); + + if (!(chan->flags & CHN_NOTEFADE)) + rn_gen_key(csf, chan, cn, freq, vol); + + // Filter Envelope: controls cutoff frequency + if (chan && chan->ptr_instrument && chan->ptr_instrument->flags & ENV_FILTER) { + setup_channel_filter(chan, + !(chan->flags & CHN_FILTER), envpitch, csf->mix_frequency); + } + + chan->sample_freq = freq; + + unsigned int ninc = _muldiv(freq, 0x10000, csf->mix_frequency); + + if (ninc >= 0xFFB0 && ninc <= 0x10090) + ninc = 0x10000; + + if (csf->freq_factor != 128) + ninc = (ninc * csf->freq_factor) >> 7; + + if (ninc > 0xFF0000) + ninc = 0xFF0000; + + chan->increment = (ninc + 1) & ~3; + } + + // Increment envelope position + if (csf->flags & SONG_INSTRUMENTMODE && chan->ptr_instrument) + rn_increment_env_pos(chan); + + chan->final_panning = CLAMP(chan->final_panning, 0, 256); + + // Volume ramping + chan->flags &= ~CHN_VOLUMERAMP; + + if (chan->final_volume || chan->left_volume || chan->right_volume) + chan->flags |= CHN_VOLUMERAMP; + + if (chan->strike) + chan->strike--; + + // Check for too big increment + if (((chan->increment >> 16) + 1) >= (int)(chan->loop_end - chan->loop_start)) + chan->flags &= ~CHN_LOOP; + + chan->right_volume_new = chan->left_volume_new = 0; + if (!(chan->length && chan->increment)) + chan->current_sample_data = NULL; + + update_vu_meter(chan); + + if (chan->current_sample_data) { + if (!rn_update_sample(csf, chan, cn, master_vol)) + break; + } else { + // Note change but no sample + //if (chan->vu_meter > 0xFF) chan->vu_meter = 0; + chan->left_volume = chan->right_volume = 0; + chan->length = 0; + } + } + + // Checking Max Mix Channels reached: ordering by volume + if (csf->num_voices >= max_voices && (!(csf->mix_flags & SNDMIX_DIRECTTODISK))) { + for (unsigned int i = 0; i < csf->num_voices; i++) { + unsigned int j = i; + + while ((j + 1 < csf->num_voices) && + (csf->voices[csf->voice_mix[j]].final_volume + < csf->voices[csf->voice_mix[j + 1]].final_volume)) + { + unsigned int n = csf->voice_mix[j]; + csf->voice_mix[j] = csf->voice_mix[j + 1]; + csf->voice_mix[j + 1] = n; + j++; + } + } + } - return 1; + return 1; } diff -Nru schism-0+20110101/player/tables.c schism-20160521/player/tables.c --- schism-0+20110101/player/tables.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/player/tables.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -25,18 +25,18 @@ #include "tables.h" const uint8_t vc_portamento_table[16] = { - 0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40, 0x60, - 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + 0x00, 0x01, 0x04, 0x08, 0x10, 0x20, 0x40, 0x60, + 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const uint16_t period_table[12] = { - 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 907, + 1712, 1616, 1524, 1440, 1356, 1280, 1208, 1140, 1076, 1016, 960, 907, }; const uint16_t finetune_table[16] = { - 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280, - 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, // 8363*2^((i-8)/(12*8)) + 7895, 7941, 7985, 8046, 8107, 8169, 8232, 8280, + 8363, 8413, 8463, 8529, 8581, 8651, 8723, 8757, // 8363*2^((i-8)/(12*8)) }; @@ -44,60 +44,60 @@ // Tables from ITTECH.TXT const int8_t sine_table[256] = { - 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, - 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, - 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, - 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, - 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, - 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2, - 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23, - -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, - -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, - -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, - -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, - -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, - -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, - -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2, + 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, + 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, + 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, + 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, + 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2, + 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23, + -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, + -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, + -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, + -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, + -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, + -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, + -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2, }; const int8_t ramp_down_table[256] = { - 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, - 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, - 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, - 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, - 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, - 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, - 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, - 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, - 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, - -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16, - -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24, - -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32, - -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40, - -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48, - -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56, - -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64, + 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56, + 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48, + 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, + 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32, + 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24, + 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, + 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, + 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, + 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, + -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16, + -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24, + -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32, + -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40, + -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48, + -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56, + -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64, }; const int8_t square_table[256] = { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; @@ -108,330 +108,336 @@ +// round(65536 * 2**(n/768)) +// 768 = 64 extra-fine finetune steps for 12 notes +// Table content is in 16.16 format const uint32_t fine_linear_slide_up_table[16] = { - 65536, 65595, 65654, 65714, 65773, 65832, 65892, 65951, - 66011, 66071, 66130, 66190, 66250, 66309, 66369, 66429 + 65536, 65595, 65654, 65714, 65773, 65832, 65892, 65951, + 66011, 66071, 66130, 66190, 66250, 66309, 66369, 66429 }; +// round(65536 * 2**(-n/768)) +// 768 = 64 extra-fine finetune steps for 12 notes +// Table content is in 16.16 format +// Note that there are a few errors in this table (typos?), but well, this table comes straight from ITTECH.TXT... +// Entry 0 (65535) should be 65536 (this value is unused and most likely stored this way so that it fits in a 16-bit integer) +// Entry 11 (64888) should be 64889 - rounding error? +// Entry 15 (64645) should be 64655 - typo? const uint32_t fine_linear_slide_down_table[16] = { - 65535, 65477, 65418, 65359, 65300, 65241, 65182, 65123, - 65065, 65006, 64947, 64888, 64830, 64772, 64713, 64645 + 65535, 65477, 65418, 65359, 65300, 65241, 65182, 65123, + 65065, 65006, 64947, 64888, 64830, 64772, 64713, 64645 }; +// floor(65536 * 2**(n/192)) +// 192 = 16 finetune steps for 12 notes +// Table content is in 16.16 format const uint32_t linear_slide_up_table[256] = { - 65536, 65773, 66010, 66249, 66489, 66729, 66971, 67213, - 67456, 67700, 67945, 68190, 68437, 68685, 68933, 69182, - 69432, 69684, 69936, 70189, 70442, 70697, 70953, 71209, - 71467, 71725, 71985, 72245, 72507, 72769, 73032, 73296, - 73561, 73827, 74094, 74362, 74631, 74901, 75172, 75444, - 75717, 75991, 76265, 76541, 76818, 77096, 77375, 77655, - 77935, 78217, 78500, 78784, 79069, 79355, 79642, 79930, - 80219, 80509, 80800, 81093, 81386, 81680, 81976, 82272, - 82570, 82868, 83168, 83469, 83771, 84074, 84378, 84683, - 84989, 85297, 85605, 85915, 86225, 86537, 86850, 87164, - 87480, 87796, 88113, 88432, 88752, 89073, 89395, 89718, - 90043, 90369, 90695, 91023, 91353, 91683, 92015, 92347, - 92681, 93017, 93353, 93691, 94029, 94370, 94711, 95053, - 95397, 95742, 96088, 96436, 96785, 97135, 97486, 97839, - 98193, 98548, 98904, 99262, 99621, 99981, 100343, 100706, - 101070, 101435, 101802, 102170, 102540, 102911, 103283, 103657, - 104031, 104408, 104785, 105164, 105545, 105926, 106309, 106694, - 107080, 107467, 107856, 108246, 108637, 109030, 109425, 109820, - 110217, 110616, 111016, 111418, 111821, 112225, 112631, 113038, - 113447, 113857, 114269, 114682, 115097, 115514, 115931, 116351, - 116771, 117194, 117618, 118043, 118470, 118898, 119328, 119760, - 120193, 120628, 121064, 121502, 121941, 122382, 122825, 123269, - 123715, 124162, 124611, 125062, 125514, 125968, 126424, 126881, - 127340, 127801, 128263, 128727, 129192, 129660, 130129, 130599, - 131072, 131546, 132021, 132499, 132978, 133459, 133942, 134426, - 134912, 135400, 135890, 136381, 136875, 137370, 137866, 138365, - 138865, 139368, 139872, 140378, 140885, 141395, 141906, 142419, - 142935, 143451, 143970, 144491, 145014, 145538, 146064, 146593, - 147123, 147655, 148189, 148725, 149263, 149803, 150344, 150888, - 151434, 151982, 152531, 153083, 153637, 154192, 154750, 155310, - 155871, 156435, 157001, 157569, 158138, 158710, 159284, 159860, - 160439, 161019, 161601, 162186, 162772, 163361, 163952, 164545, + 65536, 65773, 66010, 66249, 66489, 66729, 66971, 67213, + 67456, 67700, 67945, 68190, 68437, 68685, 68933, 69182, + 69432, 69684, 69936, 70189, 70442, 70697, 70953, 71209, + 71467, 71725, 71985, 72245, 72507, 72769, 73032, 73296, + 73561, 73827, 74094, 74362, 74631, 74901, 75172, 75444, + 75717, 75991, 76265, 76541, 76818, 77096, 77375, 77655, + 77935, 78217, 78500, 78784, 79069, 79355, 79642, 79930, + 80219, 80509, 80800, 81093, 81386, 81680, 81976, 82272, + 82570, 82868, 83168, 83469, 83771, 84074, 84378, 84683, + 84989, 85297, 85605, 85915, 86225, 86537, 86850, 87164, + 87480, 87796, 88113, 88432, 88752, 89073, 89395, 89718, + 90043, 90369, 90695, 91023, 91353, 91683, 92015, 92347, + 92681, 93017, 93353, 93691, 94029, 94370, 94711, 95053, + 95397, 95742, 96088, 96436, 96785, 97135, 97486, 97839, + 98193, 98548, 98904, 99262, 99621, 99981, 100343, 100706, + 101070, 101435, 101802, 102170, 102540, 102911, 103283, 103657, + 104031, 104408, 104785, 105164, 105545, 105926, 106309, 106694, + 107080, 107467, 107856, 108246, 108637, 109030, 109425, 109820, + 110217, 110616, 111016, 111418, 111821, 112225, 112631, 113038, + 113447, 113857, 114269, 114682, 115097, 115514, 115931, 116351, + 116771, 117194, 117618, 118043, 118470, 118898, 119328, 119760, + 120193, 120628, 121064, 121502, 121941, 122382, 122825, 123269, + 123715, 124162, 124611, 125062, 125514, 125968, 126424, 126881, + 127340, 127801, 128263, 128727, 129192, 129660, 130129, 130599, + 131072, 131546, 132021, 132499, 132978, 133459, 133942, 134426, + 134912, 135400, 135890, 136381, 136875, 137370, 137866, 138365, + 138865, 139368, 139872, 140378, 140885, 141395, 141906, 142419, + 142935, 143451, 143970, 144491, 145014, 145538, 146064, 146593, + 147123, 147655, 148189, 148725, 149263, 149803, 150344, 150888, + 151434, 151982, 152531, 153083, 153637, 154192, 154750, 155310, + 155871, 156435, 157001, 157569, 158138, 158710, 159284, 159860, + 160439, 161019, 161601, 162186, 162772, 163361, 163952, 164545, }; +// floor(65536 * 2**(-n/192)) +// 192 = 16 finetune steps for 12 notes +// Table content is in 16.16 format const uint32_t linear_slide_down_table[256] = { - 65536, 65299, 65064, 64830, 64596, 64363, 64131, 63900, - 63670, 63440, 63212, 62984, 62757, 62531, 62305, 62081, - 61857, 61634, 61412, 61191, 60970, 60751, 60532, 60314, - 60096, 59880, 59664, 59449, 59235, 59021, 58809, 58597, - 58385, 58175, 57965, 57757, 57548, 57341, 57134, 56928, - 56723, 56519, 56315, 56112, 55910, 55709, 55508, 55308, - 55108, 54910, 54712, 54515, 54318, 54123, 53928, 53733, - 53540, 53347, 53154, 52963, 52772, 52582, 52392, 52204, - 52015, 51828, 51641, 51455, 51270, 51085, 50901, 50717, - 50535, 50353, 50171, 49990, 49810, 49631, 49452, 49274, - 49096, 48919, 48743, 48567, 48392, 48218, 48044, 47871, - 47698, 47526, 47355, 47185, 47014, 46845, 46676, 46508, - 46340, 46173, 46007, 45841, 45676, 45511, 45347, 45184, - 45021, 44859, 44697, 44536, 44376, 44216, 44056, 43898, - 43740, 43582, 43425, 43268, 43112, 42957, 42802, 42648, - 42494, 42341, 42189, 42037, 41885, 41734, 41584, 41434, - 41285, 41136, 40988, 40840, 40693, 40546, 40400, 40254, - 40109, 39965, 39821, 39677, 39534, 39392, 39250, 39108, - 38967, 38827, 38687, 38548, 38409, 38270, 38132, 37995, - 37858, 37722, 37586, 37450, 37315, 37181, 37047, 36913, - 36780, 36648, 36516, 36384, 36253, 36122, 35992, 35862, - 35733, 35604, 35476, 35348, 35221, 35094, 34968, 34842, - 34716, 34591, 34466, 34342, 34218, 34095, 33972, 33850, - 33728, 33606, 33485, 33364, 33244, 33124, 33005, 32886, - 32768, 32649, 32532, 32415, 32298, 32181, 32065, 31950, - 31835, 31720, 31606, 31492, 31378, 31265, 31152, 31040, - 30928, 30817, 30706, 30595, 30485, 30375, 30266, 30157, - 30048, 29940, 29832, 29724, 29617, 29510, 29404, 29298, - 29192, 29087, 28982, 28878, 28774, 28670, 28567, 28464, - 28361, 28259, 28157, 28056, 27955, 27854, 27754, 27654, - 27554, 27455, 27356, 27257, 27159, 27061, 26964, 26866, - 26770, 26673, 26577, 26481, 26386, 26291, 26196, 26102, -}; - - -/* This is precisely the same set of values that Impulse Tracker uses when handling the S8x effect. I doubt -IT uses a lookup table to figure out something simple like this, but I can't quite guess the formula IT uses, -and besides, tables are fun :P -These values are also used in the MTM loader. However, when loading the default panning positions in S3M files, -IT shifts the stored value left two and then adds two. (= numbers at intervals of 4, between 2 and 62) */ -const int short_panning_table[16] = { - 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 + 65536, 65299, 65064, 64830, 64596, 64363, 64131, 63900, + 63670, 63440, 63212, 62984, 62757, 62531, 62305, 62081, + 61857, 61634, 61412, 61191, 60970, 60751, 60532, 60314, + 60096, 59880, 59664, 59449, 59235, 59021, 58809, 58597, + 58385, 58175, 57965, 57757, 57548, 57341, 57134, 56928, + 56723, 56519, 56315, 56112, 55910, 55709, 55508, 55308, + 55108, 54910, 54712, 54515, 54318, 54123, 53928, 53733, + 53540, 53347, 53154, 52963, 52772, 52582, 52392, 52204, + 52015, 51828, 51641, 51455, 51270, 51085, 50901, 50717, + 50535, 50353, 50171, 49990, 49810, 49631, 49452, 49274, + 49096, 48919, 48743, 48567, 48392, 48218, 48044, 47871, + 47698, 47526, 47355, 47185, 47014, 46845, 46676, 46508, + 46340, 46173, 46007, 45841, 45676, 45511, 45347, 45184, + 45021, 44859, 44697, 44536, 44376, 44216, 44056, 43898, + 43740, 43582, 43425, 43268, 43112, 42957, 42802, 42648, + 42494, 42341, 42189, 42037, 41885, 41734, 41584, 41434, + 41285, 41136, 40988, 40840, 40693, 40546, 40400, 40254, + 40109, 39965, 39821, 39677, 39534, 39392, 39250, 39108, + 38967, 38827, 38687, 38548, 38409, 38270, 38132, 37995, + 37858, 37722, 37586, 37450, 37315, 37181, 37047, 36913, + 36780, 36648, 36516, 36384, 36253, 36122, 35992, 35862, + 35733, 35604, 35476, 35348, 35221, 35094, 34968, 34842, + 34716, 34591, 34466, 34342, 34218, 34095, 33972, 33850, + 33728, 33606, 33485, 33364, 33244, 33124, 33005, 32886, + 32768, 32649, 32532, 32415, 32298, 32181, 32065, 31950, + 31835, 31720, 31606, 31492, 31378, 31265, 31152, 31040, + 30928, 30817, 30706, 30595, 30485, 30375, 30266, 30157, + 30048, 29940, 29832, 29724, 29617, 29510, 29404, 29298, + 29192, 29087, 28982, 28878, 28774, 28670, 28567, 28464, + 28361, 28259, 28157, 28056, 27955, 27854, 27754, 27654, + 27554, 27455, 27356, 27257, 27159, 27061, 26964, 26866, + 26770, 26673, 26577, 26481, 26386, 26291, 26196, 26102, }; /* --------------------------------------------------------------------------------------------------------- */ const char *midi_group_names[17] = { - "Piano", - "Chromatic Percussion", - "Organ", - "Guitar", - "Bass", - "Strings", - "Ensemble", - "Brass", - "Reed", - "Pipe", - "Synth Lead", - "Synth Pad", - "Synth Effects", - "Ethnic", - "Percussive", - "Sound Effects", - "Percussions", + "Piano", + "Chromatic Percussion", + "Organ", + "Guitar", + "Bass", + "Strings", + "Ensemble", + "Brass", + "Reed", + "Pipe", + "Synth Lead", + "Synth Pad", + "Synth Effects", + "Ethnic", + "Percussive", + "Sound Effects", + "Percussions", }; const char *midi_program_names[128] = { - // 1-8: Piano - "Acoustic Grand Piano", - "Bright Acoustic Piano", - "Electric Grand Piano", - "Honky-tonk Piano", - "Electric Piano 1", - "Electric Piano 2", - "Harpsichord", - "Clavi", - // 9-16: Chromatic Percussion - "Celesta", - "Glockenspiel", - "Music Box", - "Vibraphone", - "Marimba", - "Xylophone", - "Tubular Bells", - "Dulcimer", - // 17-24: Organ - "Drawbar Organ", - "Percussive Organ", - "Rock Organ", - "Church Organ", - "Reed Organ", - "Accordion", - "Harmonica", - "Tango Accordion", - // 25-32: Guitar - "Acoustic Guitar (nylon)", - "Acoustic Guitar (steel)", - "Electric Guitar (jazz)", - "Electric Guitar (clean)", - "Electric Guitar (muted)", - "Overdriven Guitar", - "Distortion Guitar", - "Guitar harmonics", - // 33-40 Bass - "Acoustic Bass", - "Electric Bass (finger)", - "Electric Bass (pick)", - "Fretless Bass", - "Slap Bass 1", - "Slap Bass 2", - "Synth Bass 1", - "Synth Bass 2", - // 41-48 Strings - "Violin", - "Viola", - "Cello", - "Contrabass", - "Tremolo Strings", - "Pizzicato Strings", - "Orchestral Harp", - "Timpani", - // 49-56 Ensemble - "String Ensemble 1", - "String Ensemble 2", - "SynthStrings 1", - "SynthStrings 2", - "Choir Aahs", - "Voice Oohs", - "Synth Voice", - "Orchestra Hit", - // 57-64 Brass - "Trumpet", - "Trombone", - "Tuba", - "Muted Trumpet", - "French Horn", - "Brass Section", - "SynthBrass 1", - "SynthBrass 2", - // 65-72 Reed - "Soprano Sax", - "Alto Sax", - "Tenor Sax", - "Baritone Sax", - "Oboe", - "English Horn", - "Bassoon", - "Clarinet", - // 73-80 Pipe - "Piccolo", - "Flute", - "Recorder", - "Pan Flute", - "Blown Bottle", - "Shakuhachi", - "Whistle", - "Ocarina", - // 81-88 Synth Lead - "Lead 1 (square)", - "Lead 2 (sawtooth)", - "Lead 3 (calliope)", - "Lead 4 (chiff)", - "Lead 5 (charang)", - "Lead 6 (voice)", - "Lead 7 (fifths)", - "Lead 8 (bass + lead)", - // 89-96 Synth Pad - "Pad 1 (new age)", - "Pad 2 (warm)", - "Pad 3 (polysynth)", - "Pad 4 (choir)", - "Pad 5 (bowed)", - "Pad 6 (metallic)", - "Pad 7 (halo)", - "Pad 8 (sweep)", - // 97-104 Synth Effects - "FX 1 (rain)", - "FX 2 (soundtrack)", - "FX 3 (crystal)", - "FX 4 (atmosphere)", - "FX 5 (brightness)", - "FX 6 (goblins)", - "FX 7 (echoes)", - "FX 8 (sci-fi)", - // 105-112 Ethnic - "Sitar", - "Banjo", - "Shamisen", - "Koto", - "Kalimba", - "Bag pipe", - "Fiddle", - "Shanai", - // 113-120 Percussive - "Tinkle Bell", - "Agogo", - "Steel Drums", - "Woodblock", - "Taiko Drum", - "Melodic Tom", - "Synth Drum", - "Reverse Cymbal", - // 121-128 Sound Effects - "Guitar Fret Noise", - "Breath Noise", - "Seashore", - "Bird Tweet", - "Telephone Ring", - "Helicopter", - "Applause", - "Gunshot", + // 1-8: Piano + "Acoustic Grand Piano", + "Bright Acoustic Piano", + "Electric Grand Piano", + "Honky-tonk Piano", + "Electric Piano 1", + "Electric Piano 2", + "Harpsichord", + "Clavi", + // 9-16: Chromatic Percussion + "Celesta", + "Glockenspiel", + "Music Box", + "Vibraphone", + "Marimba", + "Xylophone", + "Tubular Bells", + "Dulcimer", + // 17-24: Organ + "Drawbar Organ", + "Percussive Organ", + "Rock Organ", + "Church Organ", + "Reed Organ", + "Accordion", + "Harmonica", + "Tango Accordion", + // 25-32: Guitar + "Acoustic Guitar (nylon)", + "Acoustic Guitar (steel)", + "Electric Guitar (jazz)", + "Electric Guitar (clean)", + "Electric Guitar (muted)", + "Overdriven Guitar", + "Distortion Guitar", + "Guitar harmonics", + // 33-40 Bass + "Acoustic Bass", + "Electric Bass (finger)", + "Electric Bass (pick)", + "Fretless Bass", + "Slap Bass 1", + "Slap Bass 2", + "Synth Bass 1", + "Synth Bass 2", + // 41-48 Strings + "Violin", + "Viola", + "Cello", + "Contrabass", + "Tremolo Strings", + "Pizzicato Strings", + "Orchestral Harp", + "Timpani", + // 49-56 Ensemble + "String Ensemble 1", + "String Ensemble 2", + "SynthStrings 1", + "SynthStrings 2", + "Choir Aahs", + "Voice Oohs", + "Synth Voice", + "Orchestra Hit", + // 57-64 Brass + "Trumpet", + "Trombone", + "Tuba", + "Muted Trumpet", + "French Horn", + "Brass Section", + "SynthBrass 1", + "SynthBrass 2", + // 65-72 Reed + "Soprano Sax", + "Alto Sax", + "Tenor Sax", + "Baritone Sax", + "Oboe", + "English Horn", + "Bassoon", + "Clarinet", + // 73-80 Pipe + "Piccolo", + "Flute", + "Recorder", + "Pan Flute", + "Blown Bottle", + "Shakuhachi", + "Whistle", + "Ocarina", + // 81-88 Synth Lead + "Lead 1 (square)", + "Lead 2 (sawtooth)", + "Lead 3 (calliope)", + "Lead 4 (chiff)", + "Lead 5 (charang)", + "Lead 6 (voice)", + "Lead 7 (fifths)", + "Lead 8 (bass + lead)", + // 89-96 Synth Pad + "Pad 1 (new age)", + "Pad 2 (warm)", + "Pad 3 (polysynth)", + "Pad 4 (choir)", + "Pad 5 (bowed)", + "Pad 6 (metallic)", + "Pad 7 (halo)", + "Pad 8 (sweep)", + // 97-104 Synth Effects + "FX 1 (rain)", + "FX 2 (soundtrack)", + "FX 3 (crystal)", + "FX 4 (atmosphere)", + "FX 5 (brightness)", + "FX 6 (goblins)", + "FX 7 (echoes)", + "FX 8 (sci-fi)", + // 105-112 Ethnic + "Sitar", + "Banjo", + "Shamisen", + "Koto", + "Kalimba", + "Bag pipe", + "Fiddle", + "Shanai", + // 113-120 Percussive + "Tinkle Bell", + "Agogo", + "Steel Drums", + "Woodblock", + "Taiko Drum", + "Melodic Tom", + "Synth Drum", + "Reverse Cymbal", + // 121-128 Sound Effects + "Guitar Fret Noise", + "Breath Noise", + "Seashore", + "Bird Tweet", + "Telephone Ring", + "Helicopter", + "Applause", + "Gunshot", }; // Notes 25-85 const char *midi_percussion_names[61] = { - "Seq Click", - "Brush Tap", - "Brush Swirl", - "Brush Slap", - "Brush Swirl W/Attack", - "Snare Roll", - "Castanet", - "Snare Lo", - "Sticks", - "Bass Drum Lo", - "Open Rim Shot", - "Acoustic Bass Drum", - "Bass Drum 1", - "Side Stick", - "Acoustic Snare", - "Hand Clap", - "Electric Snare", - "Low Floor Tom", - "Closed Hi Hat", - "High Floor Tom", - "Pedal Hi-Hat", - "Low Tom", - "Open Hi-Hat", - "Low-Mid Tom", - "Hi Mid Tom", - "Crash Cymbal 1", - "High Tom", - "Ride Cymbal 1", - "Chinese Cymbal", - "Ride Bell", - "Tambourine", - "Splash Cymbal", - "Cowbell", - "Crash Cymbal 2", - "Vibraslap", - "Ride Cymbal 2", - "Hi Bongo", - "Low Bongo", - "Mute Hi Conga", - "Open Hi Conga", - "Low Conga", - "High Timbale", - "Low Timbale", - "High Agogo", - "Low Agogo", - "Cabasa", - "Maracas", - "Short Whistle", - "Long Whistle", - "Short Guiro", - "Long Guiro", - "Claves", - "Hi Wood Block", - "Low Wood Block", - "Mute Cuica", - "Open Cuica", - "Mute Triangle", - "Open Triangle", - "Shaker", - "Jingle Bell", - "Bell Tree", + "Seq Click", + "Brush Tap", + "Brush Swirl", + "Brush Slap", + "Brush Swirl W/Attack", + "Snare Roll", + "Castanet", + "Snare Lo", + "Sticks", + "Bass Drum Lo", + "Open Rim Shot", + "Acoustic Bass Drum", + "Bass Drum 1", + "Side Stick", + "Acoustic Snare", + "Hand Clap", + "Electric Snare", + "Low Floor Tom", + "Closed Hi Hat", + "High Floor Tom", + "Pedal Hi-Hat", + "Low Tom", + "Open Hi-Hat", + "Low-Mid Tom", + "Hi Mid Tom", + "Crash Cymbal 1", + "High Tom", + "Ride Cymbal 1", + "Chinese Cymbal", + "Ride Bell", + "Tambourine", + "Splash Cymbal", + "Cowbell", + "Crash Cymbal 2", + "Vibraslap", + "Ride Cymbal 2", + "Hi Bongo", + "Low Bongo", + "Mute Hi Conga", + "Open Hi Conga", + "Low Conga", + "High Timbale", + "Low Timbale", + "High Agogo", + "Low Agogo", + "Cabasa", + "Maracas", + "Short Whistle", + "Long Whistle", + "Short Guiro", + "Long Guiro", + "Claves", + "Hi Wood Block", + "Low Wood Block", + "Mute Cuica", + "Open Cuica", + "Mute Triangle", + "Open Triangle", + "Shaker", + "Jingle Bell", + "Bell Tree", }; diff -Nru schism-0+20110101/README schism-20160521/README --- schism-0+20110101/README 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -Schism Tracker copyright (c) 2003-2011 Storlek - -http://schismtracker.org/ - -Bugs? Questions? http://schismtracker.org/scdev/ - diff -Nru schism-0+20110101/README.md schism-20160521/README.md --- schism-0+20110101/README.md 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/README.md 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,35 @@ +# Schism Tracker + +Schism Tracker is a free and open-source reimplementation of [Impulse +Tracker](https://github.com/schismtracker/schismtracker/wiki/Impulse-Tracker), +a program used to create high quality music without the requirements of +specialized, expensive equipment, and with a unique "finger feel" that is +difficult to replicate in part. The player is based on a highly modified +version of the [Modplug](https://openmpt.org/legacy_software) engine, with a +number of bugfixes and changes to [improve IT +playback](https://github.com/schismtracker/schismtracker/wiki/Player-abuse-tests). + +Where Impulse Tracker was limited to i386-based systems running MS-DOS, Schism +Tracker runs on almost any platform that [SDL](http://www.libsdl.org/) +supports, and has been successfully built for Linux, Mac OS X, Windows, +FreeBSD, AmigaOS, BeOS, and even [the +Wii](http://www.wiibrew.org/wiki/Schism_Tracker). Schism will most likely build +on *any* architecture supported by GCC4 (e.g. alpha, m68k, arm, etc.) but it +will probably not be as well-optimized on many systems. + +See [the wiki](https://github.com/schismtracker/schismtracker/wiki) for more +information. + +## Download + +The latest stable builds for Windows, OS X, and Linux will soon be available +from [the releases +page](https://github.com/schismtracker/schismtracker/releases). Older builds +for other platforms can be found on [the +wiki](https://github.com/schismtracker/schismtracker/wiki). + +## Compilation + +See the +[docs/](https://github.com/schismtracker/schismtracker/tree/master/docs) folder +for platform-specific instructions. diff -Nru schism-0+20110101/schism/audio_loadsave.c schism-20160521/schism/audio_loadsave.c --- schism-0+20110101/schism/audio_loadsave.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/audio_loadsave.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -60,21 +60,21 @@ static void _fix_names(song_t *qq) { - int c, n; + int c, n; - for (n = 1; n < MAX_INSTRUMENTS; n++) { - for (c = 0; c < 25; c++) - if (qq->samples[n].name[c] == 0) - qq->samples[n].name[c] = 32; - qq->samples[n].name[25] = 0; - - if (!qq->instruments[n]) - continue; - for (c = 0; c < 25; c++) - if (qq->instruments[n]->name[c] == 0) - qq->instruments[n]->name[c] = 32; - qq->instruments[n]->name[25] = 0; - } + for (n = 1; n < MAX_INSTRUMENTS; n++) { + for (c = 0; c < 25; c++) + if (qq->samples[n].name[c] == 0) + qq->samples[n].name[c] = 32; + qq->samples[n].name[25] = 0; + + if (!qq->instruments[n]) + continue; + for (c = 0; c < 25; c++) + if (qq->instruments[n]->name[c] == 0) + qq->instruments[n]->name[c] = 32; + qq->instruments[n]->name[25] = 0; + } } // ------------------------------------------------------------------------ @@ -82,86 +82,86 @@ static void song_set_filename(const char *file) { - if (file && file[0]) { - strncpy(song_filename, file, PATH_MAX); - strncpy(song_basename, get_basename(file), NAME_MAX); - song_filename[PATH_MAX] = '\0'; - song_basename[NAME_MAX] = '\0'; - } else { - song_filename[0] = '\0'; - song_basename[0] = '\0'; - } + if (file && file[0]) { + strncpy(song_filename, file, PATH_MAX); + strncpy(song_basename, get_basename(file), NAME_MAX); + song_filename[PATH_MAX] = '\0'; + song_basename[NAME_MAX] = '\0'; + } else { + song_filename[0] = '\0'; + song_basename[0] = '\0'; + } } // clear patterns => clear filename and save flag // clear orderlist => clear title, message, and channel settings void song_new(int flags) { - int i; + int i; - song_lock_audio(); + song_lock_audio(); - song_stop_unlocked(0); + song_stop_unlocked(0); - if ((flags & KEEP_PATTERNS) == 0) { - song_set_filename(NULL); - status.flags &= ~SONG_NEEDS_SAVE; - - for (i = 0; i < MAX_PATTERNS; i++) { - if (current_song->patterns[i]) { - csf_free_pattern(current_song->patterns[i]); - current_song->patterns[i] = NULL; - } - current_song->pattern_size[i] = 64; - current_song->pattern_alloc_size[i] = 64; - } - } - if ((flags & KEEP_SAMPLES) == 0) { - for (i = 1; i < MAX_SAMPLES; i++) { - if (current_song->samples[i].data) { - csf_free_sample(current_song->samples[i].data); - } - } - memset(current_song->samples, 0, sizeof(current_song->samples)); - for (i = 1; i < MAX_SAMPLES; i++) { - current_song->samples[i].c5speed = 8363; - current_song->samples[i].volume = 64 * 4; - current_song->samples[i].global_volume = 64; - } - } - if ((flags & KEEP_INSTRUMENTS) == 0) { - for (i = 0; i < MAX_INSTRUMENTS; i++) { - if (current_song->instruments[i]) { - csf_free_instrument(current_song->instruments[i]); - current_song->instruments[i] = NULL; - } - } - } - if ((flags & KEEP_ORDERLIST) == 0) { - memset(current_song->orderlist, ORDER_LAST, sizeof(current_song->orderlist)); - memset(current_song->title, 0, sizeof(current_song->title)); - memset(current_song->message, 0, MAX_MESSAGE); - - for (i = 0; i < 64; i++) { - current_song->channels[i].volume = 64; - current_song->channels[i].panning = 128; - current_song->channels[i].flags = 0; - current_song->voices[i].volume = 256; - current_song->voices[i].global_volume = current_song->channels[i].volume; - current_song->voices[i].panning = current_song->channels[i].panning; - current_song->voices[i].flags = current_song->channels[i].flags; - current_song->voices[i].cutoff = 0x7F; - } - } + if ((flags & KEEP_PATTERNS) == 0) { + song_set_filename(NULL); + status.flags &= ~SONG_NEEDS_SAVE; + + for (i = 0; i < MAX_PATTERNS; i++) { + if (current_song->patterns[i]) { + csf_free_pattern(current_song->patterns[i]); + current_song->patterns[i] = NULL; + } + current_song->pattern_size[i] = 64; + current_song->pattern_alloc_size[i] = 64; + } + } + if ((flags & KEEP_SAMPLES) == 0) { + for (i = 1; i < MAX_SAMPLES; i++) { + if (current_song->samples[i].data) { + csf_free_sample(current_song->samples[i].data); + } + } + memset(current_song->samples, 0, sizeof(current_song->samples)); + for (i = 1; i < MAX_SAMPLES; i++) { + current_song->samples[i].c5speed = 8363; + current_song->samples[i].volume = 64 * 4; + current_song->samples[i].global_volume = 64; + } + } + if ((flags & KEEP_INSTRUMENTS) == 0) { + for (i = 0; i < MAX_INSTRUMENTS; i++) { + if (current_song->instruments[i]) { + csf_free_instrument(current_song->instruments[i]); + current_song->instruments[i] = NULL; + } + } + } + if ((flags & KEEP_ORDERLIST) == 0) { + memset(current_song->orderlist, ORDER_LAST, sizeof(current_song->orderlist)); + memset(current_song->title, 0, sizeof(current_song->title)); + memset(current_song->message, 0, MAX_MESSAGE); + + for (i = 0; i < 64; i++) { + current_song->channels[i].volume = 64; + current_song->channels[i].panning = 128; + current_song->channels[i].flags = 0; + current_song->voices[i].volume = 256; + current_song->voices[i].global_volume = current_song->channels[i].volume; + current_song->voices[i].panning = current_song->channels[i].panning; + current_song->voices[i].flags = current_song->channels[i].flags; + current_song->voices[i].cutoff = 0x7F; + } + } - current_song->repeat_count = 0; - //song_stop(); + current_song->repeat_count = 0; + //song_stop(); - csf_forget_history(current_song); + csf_forget_history(current_song); - song_unlock_audio(); + song_unlock_audio(); - main_song_changed_cb(); + main_song_changed_cb(); } // ------------------------------------------------------------------------------------------------------------ @@ -169,149 +169,152 @@ #define LOAD_SONG(x) fmt_##x##_load_song, static fmt_load_song_func load_song_funcs[] = { #include "fmt-types.h" - NULL, + NULL, }; -static const char *fmt_strerror(int n) +const char *fmt_strerror(int n) { - switch (n) { - case -LOAD_UNSUPPORTED: - return "Unrecognised file type"; - case -LOAD_FORMAT_ERROR: - return "File format error (corrupt?)"; - default: - return strerror(errno); - } -} - -static song_t *song_create_load(const char *file) -{ - fmt_load_song_func *func; - int ok = 0, err = 0; - - slurp_t *s = slurp(file, NULL, 0); - if (!s) - return NULL; - - song_t *newsong = csf_allocate(); - - if (current_song) { - newsong->mix_flags = current_song->mix_flags; - csf_set_wave_config(newsong, - current_song->mix_frequency, - current_song->mix_bits_per_sample, - current_song->mix_channels); - - // loaders might override these - newsong->row_highlight_major = current_song->row_highlight_major; - newsong->row_highlight_minor = current_song->row_highlight_minor; - csf_copy_midi_cfg(newsong, current_song); - } - - for (func = load_song_funcs; *func && !ok; func++) { - slurp_rewind(s); - switch ((*func)(newsong, s, 0)) { - case LOAD_SUCCESS: - err = 0; - ok = 1; - break; - case LOAD_UNSUPPORTED: - err = -LOAD_UNSUPPORTED; - continue; - case LOAD_FORMAT_ERROR: - err = -LOAD_FORMAT_ERROR; - break; - case LOAD_FILE_ERROR: - err = errno; - break; - } - if (err) { - csf_free(newsong); - unslurp(s); - errno = err; - return NULL; - } - } - - unslurp(s); - - if (err) { - // awwww, nerts! - csf_free(newsong); - errno = err; - return NULL; - } - return newsong; + switch (n) { + case -LOAD_UNSUPPORTED: + return "Unrecognised file type"; + case -LOAD_FORMAT_ERROR: + return "File format error (corrupt?)"; + default: + return strerror(errno); + } +} + +song_t *song_create_load(const char *file) +{ + fmt_load_song_func *func; + int ok = 0, err = 0; + + slurp_t *s = slurp(file, NULL, 0); + if (!s) + return NULL; + + song_t *newsong = csf_allocate(); + + if (current_song) { + newsong->mix_flags = current_song->mix_flags; + csf_set_wave_config(newsong, + current_song->mix_frequency, + current_song->mix_bits_per_sample, + current_song->mix_channels); + + // loaders might override these + newsong->row_highlight_major = current_song->row_highlight_major; + newsong->row_highlight_minor = current_song->row_highlight_minor; + csf_copy_midi_cfg(newsong, current_song); + } + + for (func = load_song_funcs; *func && !ok; func++) { + slurp_rewind(s); + switch ((*func)(newsong, s, 0)) { + case LOAD_SUCCESS: + err = 0; + ok = 1; + break; + case LOAD_UNSUPPORTED: + err = -LOAD_UNSUPPORTED; + continue; + case LOAD_FORMAT_ERROR: + err = -LOAD_FORMAT_ERROR; + break; + case LOAD_FILE_ERROR: + err = errno; + break; + } + if (err) { + csf_free(newsong); + unslurp(s); + errno = err; + return NULL; + } + } + + unslurp(s); + + if (err) { + // awwww, nerts! + csf_free(newsong); + errno = err; + return NULL; + } + + newsong->stop_at_order = newsong->stop_at_row = -1; + + return newsong; } int song_load_unchecked(const char *file) { - const char *base = get_basename(file); - int was_playing; - song_t *newsong; - - // IT stops the song even if the new song can't be loaded - if (status.flags & PLAY_AFTER_LOAD) { - was_playing = (song_get_mode() == MODE_PLAYING); - } else { - was_playing = 0; - song_stop(); - } - - log_nl(); - log_nl(); - log_appendf(2, "Loading %s", base); - log_underline(strlen(base) + 8); - - newsong = song_create_load(file); - if (!newsong) { - log_appendf(4, " %s", fmt_strerror(errno)); - return 0; - } - - - song_set_filename(file); - - song_lock_audio(); - csf_free(current_song); - current_song = newsong; - current_song->repeat_count = 0; - max_channels_used = 0; - _fix_names(current_song); - song_stop_unlocked(0); - song_unlock_audio(); - - if (was_playing && (status.flags & PLAY_AFTER_LOAD)) - song_start(); - - main_song_changed_cb(); - - status.flags &= ~SONG_NEEDS_SAVE; - - // print out some stuff - const char *tid = current_song->tracker_id; - - char fmt[] = " %d patterns, %d samples, %d instruments"; - int n, nsmp, nins; - song_sample_t *smp; - song_instrument_t **ins; - - for (n = 0, smp = current_song->samples + 1, nsmp = 0; n < MAX_SAMPLES; n++, smp++) - if (smp->data) - nsmp++; - for (n = 0, ins = current_song->instruments + 1, nins = 0; n < MAX_INSTRUMENTS; n++, ins++) - if (*ins != NULL) - nins++; - - if (tid[0]) - log_appendf(5, " %s", tid); - if (!nins) - *strrchr(fmt, ',') = 0; // cut off 'instruments' - log_appendf(5, fmt, csf_get_num_patterns(current_song), nsmp, nins); + const char *base = get_basename(file); + int was_playing; + song_t *newsong; + + // IT stops the song even if the new song can't be loaded + if (status.flags & PLAY_AFTER_LOAD) { + was_playing = (song_get_mode() == MODE_PLAYING); + } else { + was_playing = 0; + song_stop(); + } + + log_nl(); + log_nl(); + log_appendf(2, "Loading %s", base); + log_underline(strlen(base) + 8); + + newsong = song_create_load(file); + if (!newsong) { + log_appendf(4, " %s", fmt_strerror(errno)); + return 0; + } + + + song_set_filename(file); + + song_lock_audio(); + csf_free(current_song); + current_song = newsong; + current_song->repeat_count = 0; + max_channels_used = 0; + _fix_names(current_song); + song_stop_unlocked(0); + song_unlock_audio(); + + if (was_playing && (status.flags & PLAY_AFTER_LOAD)) + song_start(); + + main_song_changed_cb(); + + status.flags &= ~SONG_NEEDS_SAVE; + + // print out some stuff + const char *tid = current_song->tracker_id; + + char fmt[] = " %d patterns, %d samples, %d instruments"; + int n, nsmp, nins; + song_sample_t *smp; + song_instrument_t **ins; + + for (n = 0, smp = current_song->samples + 1, nsmp = 0; n < MAX_SAMPLES; n++, smp++) + if (smp->data) + nsmp++; + for (n = 0, ins = current_song->instruments + 1, nins = 0; n < MAX_INSTRUMENTS; n++, ins++) + if (*ins != NULL) + nins++; + + if (tid[0]) + log_appendf(5, " %s", tid); + if (!nins) + *strrchr(fmt, ',') = 0; // cut off 'instruments' + log_appendf(5, fmt, csf_get_num_patterns(current_song), nsmp, nins); - return 1; + return 1; } // ------------------------------------------------------------------------------------------------------------ @@ -321,596 +324,603 @@ // set iti_file if saving an instrument to disk by itself static void _save_it_instrument(int n, disko_t *fp, int iti_file) { - n++; // FIXME: this is dumb; really all the numbering should be one-based to make it simple + n++; // FIXME: this is dumb; really all the numbering should be one-based to make it simple - struct it_instrument iti; - song_instrument_t *i = current_song->instruments[n]; + struct it_instrument iti; + song_instrument_t *i = current_song->instruments[n]; - if (!i) - i = &blank_instrument; + if (!i) + i = &blank_instrument; - memset(&iti, 0, sizeof(iti)); - - // envelope: flags num lpb lpe slb sle data[25*3] reserved - - iti.id = bswapLE32(0x49504D49); // IMPI - strncpy((char *) iti.filename, (char *) i->filename, 12); - iti.zero = 0; - iti.nna = i->nna; - iti.dct = i->dct; - iti.dca = i->dca; - iti.fadeout = bswapLE16(i->fadeout >> 5); - iti.pps = i->pitch_pan_separation; - iti.ppc = i->pitch_pan_center; - iti.gbv = i->global_volume; - iti.dfp = i->panning / 4; - if (!(i->flags & ENV_SETPANNING)) - iti.dfp |= 0x80; - iti.rv = i->vol_swing; - iti.rp = i->pan_swing; - if (iti_file) { - iti.trkvers = bswapLE16(0x0214); - //iti.nos = ???; - } - // reserved1 - strncpy((char *) iti.name, (char *) i->name, 25); - iti.name[25] = 0; - iti.ifc = i->ifc; - iti.ifr = i->ifr; - iti.mch = 0; - if(i->midi_channel_mask >= 0x10000) - { - iti.mch = i->midi_channel_mask - 0x10000; - if(iti.mch <= 16) iti.mch = 16; - } - else if(i->midi_channel_mask & 0xFFFF) - { - iti.mch = 1; - while(!(i->midi_channel_mask & (1 << (iti.mch-1)))) ++iti.mch; - } - iti.mpr = i->midi_program; - iti.mbank = bswapLE16(i->midi_bank); - - static int iti_map[255]; - static int iti_invmap[255]; - static int iti_nalloc = 0; - - iti_nalloc = 0; - for (int j = 0; j < 255; j++) { - iti_map[j] = -1; - } - for (int j = 0; j < 120; j++) { - if (iti_file) { - int o = i->sample_map[j]; - if (o > 0 && o < 255 && iti_map[o] == -1) { - iti_map[o] = iti_nalloc; - iti_invmap[iti_nalloc] = o; - iti_nalloc++; - } - iti.keyboard[2 * j + 1] = iti_map[o]+1; - } else { - iti.keyboard[2 * j + 1] = i->sample_map[j]; - } - iti.keyboard[2 * j] = i->note_map[j] - 1; - } - // envelope stuff from modplug - iti.volenv.flags = 0; - iti.panenv.flags = 0; - iti.pitchenv.flags = 0; - if (i->flags & ENV_VOLUME) iti.volenv.flags |= 0x01; - if (i->flags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; - if (i->flags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; - if (i->flags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; - iti.volenv.num = i->vol_env.nodes; - iti.volenv.lpb = i->vol_env.loop_start; - iti.volenv.lpe = i->vol_env.loop_end; - iti.volenv.slb = i->vol_env.sustain_start; - iti.volenv.sle = i->vol_env.sustain_end; - if (i->flags & ENV_PANNING) iti.panenv.flags |= 0x01; - if (i->flags & ENV_PANLOOP) iti.panenv.flags |= 0x02; - if (i->flags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; - if (i->flags & ENV_PANCARRY) iti.panenv.flags |= 0x08; - iti.panenv.num = i->pan_env.nodes; - iti.panenv.lpb = i->pan_env.loop_start; - iti.panenv.lpe = i->pan_env.loop_end; - iti.panenv.slb = i->pan_env.sustain_start; - iti.panenv.sle = i->pan_env.sustain_end; - if (i->flags & ENV_PITCH) iti.pitchenv.flags |= 0x01; - if (i->flags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; - if (i->flags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; - if (i->flags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; - if (i->flags & ENV_FILTER) iti.pitchenv.flags |= 0x80; - iti.pitchenv.num = i->pitch_env.nodes; - iti.pitchenv.lpb = i->pitch_env.loop_start; - iti.pitchenv.lpe = i->pitch_env.loop_end; - iti.pitchenv.slb = i->pitch_env.sustain_start; - iti.pitchenv.sle = i->pitch_env.sustain_end; - for (int j = 0; j < 25; j++) { - iti.volenv.data[3 * j] = i->vol_env.values[j]; - iti.volenv.data[3 * j + 1] = i->vol_env.ticks[j] & 0xFF; - iti.volenv.data[3 * j + 2] = i->vol_env.ticks[j] >> 8; - iti.panenv.data[3 * j] = i->pan_env.values[j] - 32; - iti.panenv.data[3 * j + 1] = i->pan_env.ticks[j] & 0xFF; - iti.panenv.data[3 * j + 2] = i->pan_env.ticks[j] >> 8; - iti.pitchenv.data[3 * j] = i->pitch_env.values[j] - 32; - iti.pitchenv.data[3 * j + 1] = i->pitch_env.ticks[j] & 0xFF; - iti.pitchenv.data[3 * j + 2] = i->pitch_env.ticks[j] >> 8; - } - - // ITI files *need* to write 554 bytes due to alignment, but in a song it doesn't matter - disko_write(fp, &iti, sizeof(iti)); - if (iti_file) { - if (sizeof(iti) < 554) { - for (int j = sizeof(iti); j < 554; j++) { - disko_write(fp, "\x0", 1); - } - } - assert(sizeof(iti) <= 554); - - unsigned int qp = 554; - /* okay, now go through samples */ - for (int j = 0; j < iti_nalloc; j++) { - int o = iti_invmap[ j ]; - - iti_map[o] = qp; - qp += 80; /* header is 80 bytes */ - save_its_header(fp, current_song->samples + o); - } - for (int j = 0; j < iti_nalloc; j++) { - unsigned int op, tmp; - - int o = iti_invmap[ j ]; - - song_sample_t *smp = current_song->samples + o; - - op = disko_tell(fp); - tmp = bswapLE32(op); - disko_seek(fp, iti_map[o]+0x48, SEEK_SET); - disko_write(fp, &tmp, 4); - disko_seek(fp, op, SEEK_SET); - csf_write_sample(fp, smp, SF_LE | SF_PCMS - | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) - | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); - } - } + memset(&iti, 0, sizeof(iti)); + + // envelope: flags num lpb lpe slb sle data[25*3] reserved + + iti.id = bswapLE32(0x49504D49); // IMPI + strncpy((char *) iti.filename, (char *) i->filename, 12); + iti.zero = 0; + iti.nna = i->nna; + iti.dct = i->dct; + iti.dca = i->dca; + iti.fadeout = bswapLE16(i->fadeout >> 5); + iti.pps = i->pitch_pan_separation; + iti.ppc = i->pitch_pan_center; + iti.gbv = i->global_volume; + iti.dfp = i->panning / 4; + if (!(i->flags & ENV_SETPANNING)) + iti.dfp |= 0x80; + iti.rv = i->vol_swing; + iti.rp = i->pan_swing; + if (iti_file) { + iti.trkvers = bswapLE16(0x0214); + //iti.nos = ???; + } + // reserved1 + strncpy((char *) iti.name, (char *) i->name, 25); + iti.name[25] = 0; + iti.ifc = i->ifc; + iti.ifr = i->ifr; + iti.mch = 0; + if(i->midi_channel_mask >= 0x10000) + { + iti.mch = i->midi_channel_mask - 0x10000; + if(iti.mch <= 16) iti.mch = 16; + } + else if(i->midi_channel_mask & 0xFFFF) + { + iti.mch = 1; + while(!(i->midi_channel_mask & (1 << (iti.mch-1)))) ++iti.mch; + } + iti.mpr = i->midi_program; + iti.mbank = bswapLE16(i->midi_bank); + + static int iti_map[255]; + static int iti_invmap[255]; + static int iti_nalloc = 0; + + iti_nalloc = 0; + for (int j = 0; j < 255; j++) { + iti_map[j] = -1; + } + for (int j = 0; j < 120; j++) { + if (iti_file) { + int o = i->sample_map[j]; + if (o > 0 && o < 255 && iti_map[o] == -1) { + iti_map[o] = iti_nalloc; + iti_invmap[iti_nalloc] = o; + iti_nalloc++; + } + iti.keyboard[2 * j + 1] = iti_map[o]+1; + } else { + iti.keyboard[2 * j + 1] = i->sample_map[j]; + } + iti.keyboard[2 * j] = i->note_map[j] - 1; + } + // envelope stuff from modplug + iti.volenv.flags = 0; + iti.panenv.flags = 0; + iti.pitchenv.flags = 0; + if (i->flags & ENV_VOLUME) iti.volenv.flags |= 0x01; + if (i->flags & ENV_VOLLOOP) iti.volenv.flags |= 0x02; + if (i->flags & ENV_VOLSUSTAIN) iti.volenv.flags |= 0x04; + if (i->flags & ENV_VOLCARRY) iti.volenv.flags |= 0x08; + iti.volenv.num = i->vol_env.nodes; + iti.volenv.lpb = i->vol_env.loop_start; + iti.volenv.lpe = i->vol_env.loop_end; + iti.volenv.slb = i->vol_env.sustain_start; + iti.volenv.sle = i->vol_env.sustain_end; + if (i->flags & ENV_PANNING) iti.panenv.flags |= 0x01; + if (i->flags & ENV_PANLOOP) iti.panenv.flags |= 0x02; + if (i->flags & ENV_PANSUSTAIN) iti.panenv.flags |= 0x04; + if (i->flags & ENV_PANCARRY) iti.panenv.flags |= 0x08; + iti.panenv.num = i->pan_env.nodes; + iti.panenv.lpb = i->pan_env.loop_start; + iti.panenv.lpe = i->pan_env.loop_end; + iti.panenv.slb = i->pan_env.sustain_start; + iti.panenv.sle = i->pan_env.sustain_end; + if (i->flags & ENV_PITCH) iti.pitchenv.flags |= 0x01; + if (i->flags & ENV_PITCHLOOP) iti.pitchenv.flags |= 0x02; + if (i->flags & ENV_PITCHSUSTAIN) iti.pitchenv.flags |= 0x04; + if (i->flags & ENV_PITCHCARRY) iti.pitchenv.flags |= 0x08; + if (i->flags & ENV_FILTER) iti.pitchenv.flags |= 0x80; + iti.pitchenv.num = i->pitch_env.nodes; + iti.pitchenv.lpb = i->pitch_env.loop_start; + iti.pitchenv.lpe = i->pitch_env.loop_end; + iti.pitchenv.slb = i->pitch_env.sustain_start; + iti.pitchenv.sle = i->pitch_env.sustain_end; + for (int j = 0; j < 25; j++) { + iti.volenv.data[3 * j] = i->vol_env.values[j]; + iti.volenv.data[3 * j + 1] = i->vol_env.ticks[j] & 0xFF; + iti.volenv.data[3 * j + 2] = i->vol_env.ticks[j] >> 8; + iti.panenv.data[3 * j] = i->pan_env.values[j] - 32; + iti.panenv.data[3 * j + 1] = i->pan_env.ticks[j] & 0xFF; + iti.panenv.data[3 * j + 2] = i->pan_env.ticks[j] >> 8; + iti.pitchenv.data[3 * j] = i->pitch_env.values[j] - 32; + iti.pitchenv.data[3 * j + 1] = i->pitch_env.ticks[j] & 0xFF; + iti.pitchenv.data[3 * j + 2] = i->pitch_env.ticks[j] >> 8; + } + + // ITI files *need* to write 554 bytes due to alignment, but in a song it doesn't matter + disko_write(fp, &iti, sizeof(iti)); + if (iti_file) { + if (sizeof(iti) < 554) { + for (int j = sizeof(iti); j < 554; j++) { + disko_write(fp, "\x0", 1); + } + } + assert(sizeof(iti) <= 554); + + unsigned int qp = 554; + /* okay, now go through samples */ + for (int j = 0; j < iti_nalloc; j++) { + int o = iti_invmap[ j ]; + + iti_map[o] = qp; + qp += 80; /* header is 80 bytes */ + save_its_header(fp, current_song->samples + o); + } + for (int j = 0; j < iti_nalloc; j++) { + unsigned int op, tmp; + + int o = iti_invmap[ j ]; + + song_sample_t *smp = current_song->samples + o; + + op = disko_tell(fp); + tmp = bswapLE32(op); + disko_seek(fp, iti_map[o]+0x48, SEEK_SET); + disko_write(fp, &tmp, 4); + disko_seek(fp, op, SEEK_SET); + csf_write_sample(fp, smp, SF_LE | SF_PCMS + | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) + | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); + } + } } // NOBODY expects the Spanish Inquisition! static void _save_it_pattern(disko_t *fp, song_note_t *pat, int patsize) { - song_note_t *noteptr = pat; - song_note_t lastnote[64]; - uint8_t initmask[64]; - uint8_t lastmask[64]; - unsigned short pos = 0; - uint8_t data[65536]; - - memset(lastnote, 0, sizeof(lastnote)); - memset(initmask, 0, 64); - memset(lastmask, 0xff, 64); - - for (int row = 0; row < patsize; row++) { - for (int chan = 0; chan < 64; chan++, noteptr++) { - uint8_t m = 0; // current mask - int vol = -1; - unsigned int note = noteptr->note; - uint8_t effect = noteptr->effect, param = noteptr->param; - - if (note) { - m |= 1; - if (note < 0x80) - note--; - } - if (noteptr->instrument) m |= 2; - switch (noteptr->voleffect) { - default: break; - case VOLFX_VOLUME: vol = MIN(noteptr->volparam, 64); break; - case VOLFX_FINEVOLUP: vol = MIN(noteptr->volparam, 9) + 65; break; - case VOLFX_FINEVOLDOWN: vol = MIN(noteptr->volparam, 9) + 75; break; - case VOLFX_VOLSLIDEUP: vol = MIN(noteptr->volparam, 9) + 85; break; - case VOLFX_VOLSLIDEDOWN: vol = MIN(noteptr->volparam, 9) + 95; break; - case VOLFX_PORTADOWN: vol = MIN(noteptr->volparam, 9) + 105; break; - case VOLFX_PORTAUP: vol = MIN(noteptr->volparam, 9) + 115; break; - case VOLFX_PANNING: vol = MIN(noteptr->volparam, 64) + 128; break; - case VOLFX_VIBRATODEPTH: vol = MIN(noteptr->volparam, 9) + 203; break; - case VOLFX_VIBRATOSPEED: vol = 203; break; - case VOLFX_TONEPORTAMENTO: vol = MIN(noteptr->volparam, 9) + 193; break; - } - if (vol != -1) m |= 4; - csf_export_s3m_effect(&effect, ¶m, 1); - if (effect || param) m |= 8; - if (!m) continue; - - if (m & 1) { - if ((note == lastnote[chan].note) && (initmask[chan] & 1)) { - m &= ~1; - m |= 0x10; - } else { - lastnote[chan].note = note; - initmask[chan] |= 1; - } - } - if (m & 2) { - if ((noteptr->instrument == lastnote[chan].instrument) && (initmask[chan] & 2)) { - m &= ~2; - m |= 0x20; - } else { - lastnote[chan].instrument = noteptr->instrument; - initmask[chan] |= 2; - } - } - if (m & 4) { - if ((vol == lastnote[chan].volparam) && (initmask[chan] & 4)) { - m &= ~4; - m |= 0x40; - } else { - lastnote[chan].volparam = vol; - initmask[chan] |= 4; - } - } - if (m & 8) { - if ((effect == lastnote[chan].effect) && (param == lastnote[chan].param) - && (initmask[chan] & 8)) { - m &= ~8; - m |= 0x80; - } else { - lastnote[chan].effect = effect; - lastnote[chan].param = param; - initmask[chan] |= 8; - } - } - if (m == lastmask[chan]) { - data[pos++] = chan + 1; - } else { - lastmask[chan] = m; - data[pos++] = (chan + 1) | 0x80; - data[pos++] = m; - } - if (m & 1) data[pos++] = note; - if (m & 2) data[pos++] = noteptr->instrument; - if (m & 4) data[pos++] = vol; - if (m & 8) { - data[pos++] = effect; - data[pos++] = param; - } - } // end channel - data[pos++] = 0; - } // end row - - // write the data to the file (finally!) - unsigned short h[4] = {0}; - h[0] = bswapLE16(pos); - h[1] = bswapLE16(patsize); - // h[2] and h[3] are meaningless - disko_write(fp, &h, 8); - disko_write(fp, data, pos); + song_note_t *noteptr = pat; + song_note_t lastnote[64]; + uint8_t initmask[64]; + uint8_t lastmask[64]; + unsigned short pos = 0; + uint8_t data[65536]; + + memset(lastnote, 0, sizeof(lastnote)); + memset(initmask, 0, 64); + memset(lastmask, 0xff, 64); + + for (int row = 0; row < patsize; row++) { + for (int chan = 0; chan < 64; chan++, noteptr++) { + uint8_t m = 0; // current mask + int vol = -1; + unsigned int note = noteptr->note; + uint8_t effect = noteptr->effect, param = noteptr->param; + + if (note) { + m |= 1; + if (note < 0x80) + note--; + } + if (noteptr->instrument) m |= 2; + switch (noteptr->voleffect) { + default: break; + case VOLFX_VOLUME: vol = MIN(noteptr->volparam, 64); break; + case VOLFX_FINEVOLUP: vol = MIN(noteptr->volparam, 9) + 65; break; + case VOLFX_FINEVOLDOWN: vol = MIN(noteptr->volparam, 9) + 75; break; + case VOLFX_VOLSLIDEUP: vol = MIN(noteptr->volparam, 9) + 85; break; + case VOLFX_VOLSLIDEDOWN: vol = MIN(noteptr->volparam, 9) + 95; break; + case VOLFX_PORTADOWN: vol = MIN(noteptr->volparam, 9) + 105; break; + case VOLFX_PORTAUP: vol = MIN(noteptr->volparam, 9) + 115; break; + case VOLFX_PANNING: vol = MIN(noteptr->volparam, 64) + 128; break; + case VOLFX_VIBRATODEPTH: vol = MIN(noteptr->volparam, 9) + 203; break; + case VOLFX_VIBRATOSPEED: vol = 203; break; + case VOLFX_TONEPORTAMENTO: vol = MIN(noteptr->volparam, 9) + 193; break; + } + if (vol != -1) m |= 4; + csf_export_s3m_effect(&effect, ¶m, 1); + if (effect || param) m |= 8; + if (!m) continue; + + if (m & 1) { + if ((note == lastnote[chan].note) && (initmask[chan] & 1)) { + m &= ~1; + m |= 0x10; + } else { + lastnote[chan].note = note; + initmask[chan] |= 1; + } + } + if (m & 2) { + if ((noteptr->instrument == lastnote[chan].instrument) && (initmask[chan] & 2)) { + m &= ~2; + m |= 0x20; + } else { + lastnote[chan].instrument = noteptr->instrument; + initmask[chan] |= 2; + } + } + if (m & 4) { + if ((vol == lastnote[chan].volparam) && (initmask[chan] & 4)) { + m &= ~4; + m |= 0x40; + } else { + lastnote[chan].volparam = vol; + initmask[chan] |= 4; + } + } + if (m & 8) { + if ((effect == lastnote[chan].effect) && (param == lastnote[chan].param) + && (initmask[chan] & 8)) { + m &= ~8; + m |= 0x80; + } else { + lastnote[chan].effect = effect; + lastnote[chan].param = param; + initmask[chan] |= 8; + } + } + if (m == lastmask[chan]) { + data[pos++] = chan + 1; + } else { + lastmask[chan] = m; + data[pos++] = (chan + 1) | 0x80; + data[pos++] = m; + } + if (m & 1) data[pos++] = note; + if (m & 2) data[pos++] = noteptr->instrument; + if (m & 4) data[pos++] = vol; + if (m & 8) { + data[pos++] = effect; + data[pos++] = param; + } + } // end channel + data[pos++] = 0; + } // end row + + // write the data to the file (finally!) + unsigned short h[4] = {0}; + h[0] = bswapLE16(pos); + h[1] = bswapLE16(patsize); + // h[2] and h[3] are meaningless + disko_write(fp, &h, 8); + disko_write(fp, data, pos); } // why on earth isn't this using the 'song' parameter? will finding this out hurt my head? static int _save_it(disko_t *fp, UNUSED song_t *song) { - struct it_file hdr; - int n; - int nord, nins, nsmp, npat; - int msglen = strlen(current_song->message); - uint32_t para_ins[256], para_smp[256], para_pat[256]; - // how much extra data is stuffed between the parapointers and the rest of the file - // (2 bytes for edit history length, and 8 per entry including the current session) - uint32_t extra = 2 + 8 * current_song->histlen + 8; - - memset(&hdr, 0, sizeof(hdr)); - - // TODO complain about nonstandard stuff? or just stop saving it to begin with - - /* IT always saves at least two orders -- and requires an extra order at the end (which gets chopped!) - However, the loader refuses to load files with too much data in the orderlist, so in the pathological - case where order 255 has data, writing an extra 0xFF at the end will result in a file that can't be - loaded back (for now). Eventually this can be fixed, but at least for a while it's probably a great - idea not to save things that other versions won't load. */ - nord = csf_get_num_orders(current_song); - nord = CLAMP(nord + 1, 2, MAX_ORDERS); - - nins = csf_get_num_instruments(current_song); - nsmp = csf_get_num_samples(current_song); - - // IT always saves at least one pattern. - npat = csf_get_num_patterns(current_song) ?: 1; - - hdr.id = bswapLE32(0x4D504D49); // IMPM - strncpy((char *) hdr.songname, current_song->title, 25); - hdr.songname[25] = 0; - hdr.hilight_major = current_song->row_highlight_major; - hdr.hilight_minor = current_song->row_highlight_minor; - hdr.ordnum = bswapLE16(nord); - hdr.insnum = bswapLE16(nins); - hdr.smpnum = bswapLE16(nsmp); - hdr.patnum = bswapLE16(npat); - // No one else seems to be using the cwtv's tracker id number, so I'm gonna take 1. :) - hdr.cwtv = bswapLE16(0x1000 | ver_cwtv); // cwtv 0xtxyy = tracker id t, version x.yy - // compat: - // really simple IT files = 1.00 (when?) - // "normal" = 2.00 - // vol col effects = 2.08 - // pitch wheel depth = 2.13 - // embedded midi config = 2.13 - // row highlight = 2.13 (doesn't necessarily affect cmwt) - // compressed samples = 2.14 - // instrument filters = 2.17 - hdr.cmwt = bswapLE16(0x0214); // compatible with IT 2.14 - for (n = 1; n < nins; n++) { - song_instrument_t *i = current_song->instruments[n]; - if (!i) continue; - if (i->flags & ENV_FILTER) { - hdr.cmwt = bswapLE16(0x0217); - break; - } - } - - hdr.flags = 0; - hdr.special = 2 | 4; // 2 = edit history, 4 = row highlight - - if (song_is_stereo()) hdr.flags |= 1; - if (song_is_instrument_mode()) hdr.flags |= 4; - if (song_has_linear_pitch_slides()) hdr.flags |= 8; - if (song_has_old_effects()) hdr.flags |= 16; - if (song_has_compatible_gxx()) hdr.flags |= 32; - if (midi_flags & MIDI_PITCHBEND) { - hdr.flags |= 64; - hdr.pwd = midi_pitch_depth; - } - if (current_song->flags & SONG_EMBEDMIDICFG) { - hdr.flags |= 128; - hdr.special |= 8; - extra += sizeof(midi_config_t); - } - hdr.flags = bswapLE16(hdr.flags); - if (msglen) { - hdr.special |= 1; - msglen++; - } - hdr.special = bswapLE16(hdr.special); - - // 16+ = reserved (always off?) - hdr.globalvol = current_song->initial_global_volume; - hdr.mv = current_song->mixing_volume; - hdr.speed = current_song->initial_speed; - hdr.tempo = current_song->initial_tempo; - hdr.sep = current_song->pan_separation; - if (msglen) { - hdr.msgoffset = bswapLE32(extra + 0xc0 + nord + 4 * (nins + nsmp + npat)); - hdr.msglength = bswapLE16(msglen); - } - // hdr.reserved2 - - for (n = 0; n < 64; n++) { - hdr.chnpan[n] = ((current_song->channels[n].flags & CHN_SURROUND) - ? 100 : (current_song->channels[n].panning / 4)); - hdr.chnvol[n] = current_song->channels[n].volume; - if (current_song->channels[n].flags & CHN_MUTE) - hdr.chnpan[n] += 128; - } - - disko_write(fp, &hdr, sizeof(hdr)); - disko_write(fp, current_song->orderlist, nord); - - // we'll get back to these later - disko_write(fp, para_ins, 4*nins); - disko_write(fp, para_smp, 4*nsmp); - disko_write(fp, para_pat, 4*npat); - - // edit history (see scripts/timestamp.py) - // Shouldâ„¢ be fully compatible with Impulse Tracker. - struct timeval savetime, elapsed; - struct tm loadtm; - uint16_t h; - - localtime_r(¤t_song->editstart.tv_sec, &loadtm); - gettimeofday(&savetime, NULL); - timersub(&savetime, ¤t_song->editstart, &elapsed); - - // item count - h = current_song->histlen + 1; - h = bswapLE16(h); - disko_write(fp, &h, 2); - // old data - disko_write(fp, current_song->histdata, 8 * current_song->histlen); - // 16-bit date - h = loadtm.tm_mday | ((loadtm.tm_mon + 1) << 5) | ((loadtm.tm_year - 80) << 9); - h = bswapLE16(h); - disko_write(fp, &h, 2); - // 16-bit time - h = (loadtm.tm_sec / 2) | (loadtm.tm_min << 5) | (loadtm.tm_hour << 11); - h = bswapLE16(h); - disko_write(fp, &h, 2); - // 32-bit DOS tick count (tick = 1/18.2 second; 54945 * 18.2 = 999999 which is Close Enough) - uint32_t ticks = elapsed.tv_sec * 182 / 10 + elapsed.tv_usec / 54945; - ticks = bswapLE32(ticks); - disko_write(fp, &ticks, 4); - - // here comes MIDI configuration - // here comes MIDI configuration - // right down MIDI configuration lane - if (current_song->flags & SONG_EMBEDMIDICFG) { - disko_write(fp, ¤t_song->midi_config, sizeof(current_song->midi_config)); - } - - disko_write(fp, current_song->message, msglen); - - // instruments, samples, and patterns - for (n = 0; n < nins; n++) { - para_ins[n] = disko_tell(fp); - para_ins[n] = bswapLE32(para_ins[n]); - _save_it_instrument(n, fp, 0); - } - for (n = 0; n < nsmp; n++) { - // the sample parapointers are byte-swapped later - para_smp[n] = disko_tell(fp); - save_its_header(fp, current_song->samples + n + 1); - } - for (n = 0; n < npat; n++) { - if (csf_pattern_is_empty(current_song, n)) { - para_pat[n] = 0; - } else { - para_pat[n] = disko_tell(fp); - para_pat[n] = bswapLE32(para_pat[n]); - _save_it_pattern(fp, current_song->patterns[n], current_song->pattern_size[n]); - } - } - - // sample data - for (n = 0; n < nsmp; n++) { - unsigned int tmp, op; - song_sample_t *smp = current_song->samples + (n + 1); - - // Always save the data pointer, even if there's not actually any data being pointed to - op = disko_tell(fp); - tmp = bswapLE32(op); - disko_seek(fp, para_smp[n]+0x48, SEEK_SET); - disko_write(fp, &tmp, 4); - disko_seek(fp, op, SEEK_SET); - if (smp->data) - csf_write_sample(fp, smp, SF_LE | SF_PCMS - | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) - | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); - // done using the pointer internally, so *now* swap it - para_smp[n] = bswapLE32(para_smp[n]); - } - - // rewrite the parapointers - disko_seek(fp, 0xc0 + nord, SEEK_SET); - disko_write(fp, para_ins, 4*nins); - disko_write(fp, para_smp, 4*nsmp); - disko_write(fp, para_pat, 4*npat); + struct it_file hdr; + int n; + int nord, nins, nsmp, npat; + int msglen = strlen(current_song->message); + int warned_adlib = 0; + uint32_t para_ins[256], para_smp[256], para_pat[256]; + // how much extra data is stuffed between the parapointers and the rest of the file + // (2 bytes for edit history length, and 8 per entry including the current session) + uint32_t extra = 2 + 8 * current_song->histlen + 8; + + memset(&hdr, 0, sizeof(hdr)); + + // TODO complain about nonstandard stuff? or just stop saving it to begin with + + /* IT always saves at least two orders -- and requires an extra order at the end (which gets chopped!) + However, the loader refuses to load files with too much data in the orderlist, so in the pathological + case where order 255 has data, writing an extra 0xFF at the end will result in a file that can't be + loaded back (for now). Eventually this can be fixed, but at least for a while it's probably a great + idea not to save things that other versions won't load. */ + nord = csf_get_num_orders(current_song); + nord = CLAMP(nord + 1, 2, MAX_ORDERS); + + nins = csf_get_num_instruments(current_song); + nsmp = csf_get_num_samples(current_song); + + // IT always saves at least one pattern. + npat = csf_get_num_patterns(current_song) ?: 1; + + hdr.id = bswapLE32(0x4D504D49); // IMPM + strncpy((char *) hdr.songname, current_song->title, 25); + hdr.songname[25] = 0; + hdr.hilight_major = current_song->row_highlight_major; + hdr.hilight_minor = current_song->row_highlight_minor; + hdr.ordnum = bswapLE16(nord); + hdr.insnum = bswapLE16(nins); + hdr.smpnum = bswapLE16(nsmp); + hdr.patnum = bswapLE16(npat); + // No one else seems to be using the cwtv's tracker id number, so I'm gonna take 1. :) + hdr.cwtv = bswapLE16(0x1000 | ver_cwtv); // cwtv 0xtxyy = tracker id t, version x.yy + // compat: + // really simple IT files = 1.00 (when?) + // "normal" = 2.00 + // vol col effects = 2.08 + // pitch wheel depth = 2.13 + // embedded midi config = 2.13 + // row highlight = 2.13 (doesn't necessarily affect cmwt) + // compressed samples = 2.14 + // instrument filters = 2.17 + hdr.cmwt = bswapLE16(0x0214); // compatible with IT 2.14 + for (n = 1; n < nins; n++) { + song_instrument_t *i = current_song->instruments[n]; + if (!i) continue; + if (i->flags & ENV_FILTER) { + hdr.cmwt = bswapLE16(0x0217); + break; + } + } + + hdr.flags = 0; + hdr.special = 2 | 4; // 2 = edit history, 4 = row highlight + + if (song_is_stereo()) hdr.flags |= 1; + if (song_is_instrument_mode()) hdr.flags |= 4; + if (song_has_linear_pitch_slides()) hdr.flags |= 8; + if (song_has_old_effects()) hdr.flags |= 16; + if (song_has_compatible_gxx()) hdr.flags |= 32; + if (midi_flags & MIDI_PITCHBEND) { + hdr.flags |= 64; + hdr.pwd = midi_pitch_depth; + } + if (current_song->flags & SONG_EMBEDMIDICFG) { + hdr.flags |= 128; + hdr.special |= 8; + extra += sizeof(midi_config_t); + } + hdr.flags = bswapLE16(hdr.flags); + if (msglen) { + hdr.special |= 1; + msglen++; + } + hdr.special = bswapLE16(hdr.special); + + // 16+ = reserved (always off?) + hdr.globalvol = current_song->initial_global_volume; + hdr.mv = current_song->mixing_volume; + hdr.speed = current_song->initial_speed; + hdr.tempo = current_song->initial_tempo; + hdr.sep = current_song->pan_separation; + if (msglen) { + hdr.msgoffset = bswapLE32(extra + 0xc0 + nord + 4 * (nins + nsmp + npat)); + hdr.msglength = bswapLE16(msglen); + } + // hdr.reserved2 + + for (n = 0; n < 64; n++) { + hdr.chnpan[n] = ((current_song->channels[n].flags & CHN_SURROUND) + ? 100 : (current_song->channels[n].panning / 4)); + hdr.chnvol[n] = current_song->channels[n].volume; + if (current_song->channels[n].flags & CHN_MUTE) + hdr.chnpan[n] += 128; + } + + disko_write(fp, &hdr, sizeof(hdr)); + disko_write(fp, current_song->orderlist, nord); + + // we'll get back to these later + disko_write(fp, para_ins, 4*nins); + disko_write(fp, para_smp, 4*nsmp); + disko_write(fp, para_pat, 4*npat); + + // edit history (see scripts/timestamp.py) + // Shouldâ„¢ be fully compatible with Impulse Tracker. + struct timeval savetime, elapsed; + struct tm loadtm; + uint16_t h; + //x86/x64 compatibility + time_t thetime = current_song->editstart.tv_sec; + localtime_r(&thetime, &loadtm); + gettimeofday(&savetime, NULL); + timersub(&savetime, ¤t_song->editstart, &elapsed); + + // item count + h = current_song->histlen + 1; + h = bswapLE16(h); + disko_write(fp, &h, 2); + // old data + disko_write(fp, current_song->histdata, 8 * current_song->histlen); + // 16-bit date + h = loadtm.tm_mday | ((loadtm.tm_mon + 1) << 5) | ((loadtm.tm_year - 80) << 9); + h = bswapLE16(h); + disko_write(fp, &h, 2); + // 16-bit time + h = (loadtm.tm_sec / 2) | (loadtm.tm_min << 5) | (loadtm.tm_hour << 11); + h = bswapLE16(h); + disko_write(fp, &h, 2); + // 32-bit DOS tick count (tick = 1/18.2 second; 54945 * 18.2 = 999999 which is Close Enough) + uint32_t ticks = elapsed.tv_sec * 182 / 10 + elapsed.tv_usec / 54945; + ticks = bswapLE32(ticks); + disko_write(fp, &ticks, 4); + + // here comes MIDI configuration + // here comes MIDI configuration + // right down MIDI configuration lane + if (current_song->flags & SONG_EMBEDMIDICFG) { + disko_write(fp, ¤t_song->midi_config, sizeof(current_song->midi_config)); + } + + disko_write(fp, current_song->message, msglen); + + // instruments, samples, and patterns + for (n = 0; n < nins; n++) { + para_ins[n] = disko_tell(fp); + para_ins[n] = bswapLE32(para_ins[n]); + _save_it_instrument(n, fp, 0); + } + for (n = 0; n < nsmp; n++) { + // the sample parapointers are byte-swapped later + para_smp[n] = disko_tell(fp); + save_its_header(fp, current_song->samples + n + 1); + } + for (n = 0; n < npat; n++) { + if (csf_pattern_is_empty(current_song, n)) { + para_pat[n] = 0; + } else { + para_pat[n] = disko_tell(fp); + para_pat[n] = bswapLE32(para_pat[n]); + _save_it_pattern(fp, current_song->patterns[n], current_song->pattern_size[n]); + } + } + + // sample data + for (n = 0; n < nsmp; n++) { + unsigned int tmp, op; + song_sample_t *smp = current_song->samples + (n + 1); + + // Always save the data pointer, even if there's not actually any data being pointed to + op = disko_tell(fp); + tmp = bswapLE32(op); + disko_seek(fp, para_smp[n]+0x48, SEEK_SET); + disko_write(fp, &tmp, 4); + disko_seek(fp, op, SEEK_SET); + if (smp->data) + csf_write_sample(fp, smp, SF_LE | SF_PCMS + | ((smp->flags & CHN_16BIT) ? SF_16 : SF_8) + | ((smp->flags & CHN_STEREO) ? SF_SS : SF_M)); + // done using the pointer internally, so *now* swap it + para_smp[n] = bswapLE32(para_smp[n]); + + if (!warned_adlib && smp->flags & CHN_ADLIB) { + log_appendf(4, " Warning: AdLib samples unsupported in IT format"); + warned_adlib = 1; + } + } + + // rewrite the parapointers + disko_seek(fp, 0xc0 + nord, SEEK_SET); + disko_write(fp, para_ins, 4*nins); + disko_write(fp, para_smp, 4*nsmp); + disko_write(fp, para_pat, 4*npat); - return SAVE_SUCCESS; + return SAVE_SUCCESS; } /* ------------------------------------------------------------------------- */ -struct save_format song_save_formats[] = { - {"IT", "Impulse Tracker", ".it", {.save_song = _save_it}}, - {"S3M", "Scream Tracker 3", ".s3m", {.save_song = fmt_s3m_save_song}}, - {.label = NULL} +const struct save_format song_save_formats[] = { + {"IT", "Impulse Tracker", ".it", {.save_song = _save_it}}, + {"S3M", "Scream Tracker 3", ".s3m", {.save_song = fmt_s3m_save_song}}, + {.label = NULL} }; #define EXPORT_FUNCS(t) \ - fmt_##t##_export_head, fmt_##t##_export_silence, fmt_##t##_export_body, fmt_##t##_export_tail + fmt_##t##_export_head, fmt_##t##_export_silence, fmt_##t##_export_body, fmt_##t##_export_tail -struct save_format song_export_formats[] = { - {"WAV", "WAV", ".wav", {.export = {EXPORT_FUNCS(wav), 0}}}, - {"MWAV", "WAV multi-write", ".wav", {.export = {EXPORT_FUNCS(wav), 1}}}, - {"AIFF", "Audio IFF", ".aiff", {.export = {EXPORT_FUNCS(aiff), 0}}}, - {"MAIFF", "Audio IFF multi-write", ".aiff", {.export = {EXPORT_FUNCS(aiff), 1}}}, - {.label = NULL} +const struct save_format song_export_formats[] = { + {"WAV", "WAV", ".wav", {.export = {EXPORT_FUNCS(wav), 0}}}, + {"MWAV", "WAV multi-write", ".wav", {.export = {EXPORT_FUNCS(wav), 1}}}, + {"AIFF", "Audio IFF", ".aiff", {.export = {EXPORT_FUNCS(aiff), 0}}}, + {"MAIFF", "Audio IFF multi-write", ".aiff", {.export = {EXPORT_FUNCS(aiff), 1}}}, + {.label = NULL} }; // and maiff sounds like something you'd want to hug // .. dont ask -struct save_format sample_save_formats[] = { - {"ITS", "Impulse Tracker", ".its", {.save_sample = fmt_its_save_sample}}, - //{"S3I", "Scream Tracker", ".s3i", {.save_sample = fmt_s3i_save_sample}}, - {"AIFF", "Audio IFF", ".aiff", {.save_sample = fmt_aiff_save_sample}}, - {"AU", "Sun/NeXT", ".au", {.save_sample = fmt_au_save_sample}}, - {"WAV", "WAV", ".wav", {.save_sample = fmt_wav_save_sample}}, - {"RAW", "Raw", ".raw", {.save_sample = fmt_raw_save_sample}}, - {.label = NULL} +const struct save_format sample_save_formats[] = { + {"ITS", "Impulse Tracker", ".its", {.save_sample = fmt_its_save_sample}}, + //{"S3I", "Scream Tracker", ".s3i", {.save_sample = fmt_s3i_save_sample}}, + {"AIFF", "Audio IFF", ".aiff", {.save_sample = fmt_aiff_save_sample}}, + {"AU", "Sun/NeXT", ".au", {.save_sample = fmt_au_save_sample}}, + {"WAV", "WAV", ".wav", {.save_sample = fmt_wav_save_sample}}, + {"RAW", "Raw", ".raw", {.save_sample = fmt_raw_save_sample}}, + {.label = NULL} }; -static struct save_format *get_save_format(struct save_format *formats, const char *label) +static const struct save_format *get_save_format(const struct save_format *formats, const char *label) { - int n; + int n; - if (!label) { - // why would this happen, ever? - log_appendf(4, "No file type given, very weird! (Try a different filename?)"); - return NULL; - } - - for (n = 0; formats[n].label; n++) - if (strcmp(formats[n].label, label) == 0) - return formats + n; + if (!label) { + // why would this happen, ever? + log_appendf(4, "No file type given, very weird! (Try a different filename?)"); + return NULL; + } + + for (n = 0; formats[n].label; n++) + if (strcmp(formats[n].label, label) == 0) + return formats + n; - log_appendf(4, "Unknown save format %s", label); - return NULL; + log_appendf(4, "Unknown save format %s", label); + return NULL; } static char *mangle_filename(const char *in, const char *mid, const char *ext) { - char *ret; - const char *iext; - size_t baselen, rlen; - - iext = get_extension(in); - rlen = baselen = iext - in; - if (mid) - rlen += strlen(mid); - if (iext[0]) - rlen += strlen(iext); - else if (ext) - rlen += strlen(ext); - ret = malloc(rlen + 1); /* room for terminating \0 */ - if (!ret) - return NULL; - strncpy(ret, in, baselen); - ret[baselen] = '\0'; - if (mid) - strcat(ret, mid); - /* maybe output a warning if iext and ext differ? */ - if (iext[0]) - strcat(ret, iext); - else if (ext) - strcat(ret, ext); - return ret; + char *ret; + const char *iext; + size_t baselen, rlen; + + iext = get_extension(in); + rlen = baselen = iext - in; + if (mid) + rlen += strlen(mid); + if (iext[0]) + rlen += strlen(iext); + else if (ext) + rlen += strlen(ext); + ret = malloc(rlen + 1); /* room for terminating \0 */ + if (!ret) + return NULL; + strncpy(ret, in, baselen); + ret[baselen] = '\0'; + if (mid) + strcat(ret, mid); + /* maybe output a warning if iext and ext differ? */ + if (iext[0]) + strcat(ret, iext); + else if (ext) + strcat(ret, ext); + return ret; } int song_export(const char *filename, const char *type) { - struct save_format *format = get_save_format(song_export_formats, type); - const char *mid; - char *mangle; - int r; - - if (!format) - return SAVE_INTERNAL_ERROR; - - mid = (format->f.export.multi && strcasestr(filename, "%c") == NULL) ? ".%c" : NULL; - mangle = mangle_filename(filename, mid, format->ext); - - log_nl(); - log_nl(); - log_appendf(2, "Exporting to %s", format->name); - log_underline(strlen(format->name) + 13); - - /* disko does the rest of the log messages itself */ - r = disko_export_song(mangle, format); - free(mangle); - switch (r) { - case DW_OK: - return SAVE_SUCCESS; - case DW_ERROR: - return SAVE_FILE_ERROR; - default: - return SAVE_INTERNAL_ERROR; - } + const struct save_format *format = get_save_format(song_export_formats, type); + const char *mid; + char *mangle; + int r; + + if (!format) + return SAVE_INTERNAL_ERROR; + + mid = (format->f.export.multi && strcasestr(filename, "%c") == NULL) ? ".%c" : NULL; + mangle = mangle_filename(filename, mid, format->ext); + + log_nl(); + log_nl(); + log_appendf(2, "Exporting to %s", format->name); + log_underline(strlen(format->name) + 13); + + /* disko does the rest of the log messages itself */ + r = disko_export_song(mangle, format); + free(mangle); + switch (r) { + case DW_OK: + return SAVE_SUCCESS; + case DW_ERROR: + return SAVE_FILE_ERROR; + default: + return SAVE_INTERNAL_ERROR; + } } int song_save(const char *filename, const char *type) { - int ret, backup; - struct save_format *format = get_save_format(song_save_formats, type); - char *mangle; - - if (!format) - return SAVE_INTERNAL_ERROR; - - mangle = mangle_filename(filename, NULL, format->ext); - - log_nl(); - log_nl(); - log_appendf(2, "Saving %s module", format->name); - log_underline(strlen(format->name) + 14); + int ret, backup; + const struct save_format *format = get_save_format(song_save_formats, type); + char *mangle; + + if (!format) + return SAVE_INTERNAL_ERROR; + + mangle = mangle_filename(filename, NULL, format->ext); + + log_nl(); + log_nl(); + log_appendf(2, "Saving %s module", format->name); + log_underline(strlen(format->name) + 14); /* TODO: add or replace file extension as appropriate @@ -937,86 +947,86 @@ such as "abc|def.it". This dialog is presented both when saving from F10 and Ctrl-S. */ - disko_t *fp = disko_open(mangle); - if (!fp) { - log_perror(mangle); - free(mangle); - return SAVE_FILE_ERROR; - } - - ret = format->f.save_song(fp, current_song); - if (ret != SAVE_SUCCESS) - disko_seterror(fp, EINVAL); - backup = ((status.flags & MAKE_BACKUPS) - ? (status.flags & NUMBERED_BACKUPS) - ? 65536 : 1 : 0); - if (disko_close(fp, backup) == DW_ERROR && ret == SAVE_SUCCESS) { - // this was not as successful as originally claimed! - ret = SAVE_FILE_ERROR; - } - - switch (ret) { - case SAVE_SUCCESS: - status.flags &= ~SONG_NEEDS_SAVE; - if (strcasecmp(song_filename, mangle)) - song_set_filename(mangle); - log_appendf(5, " Done"); - break; - case SAVE_FILE_ERROR: - log_perror(mangle); - break; - case SAVE_INTERNAL_ERROR: - default: // ??? - log_appendf(4, " Internal error saving song"); - break; - } + disko_t *fp = disko_open(mangle); + if (!fp) { + log_perror(mangle); + free(mangle); + return SAVE_FILE_ERROR; + } + + ret = format->f.save_song(fp, current_song); + if (ret != SAVE_SUCCESS) + disko_seterror(fp, EINVAL); + backup = ((status.flags & MAKE_BACKUPS) + ? (status.flags & NUMBERED_BACKUPS) + ? 65536 : 1 : 0); + if (disko_close(fp, backup) == DW_ERROR && ret == SAVE_SUCCESS) { + // this was not as successful as originally claimed! + ret = SAVE_FILE_ERROR; + } + + switch (ret) { + case SAVE_SUCCESS: + status.flags &= ~SONG_NEEDS_SAVE; + if (strcasecmp(song_filename, mangle)) + song_set_filename(mangle); + log_appendf(5, " Done"); + break; + case SAVE_FILE_ERROR: + log_perror(mangle); + break; + case SAVE_INTERNAL_ERROR: + default: // ??? + log_appendf(4, " Internal error saving song"); + break; + } - free(mangle); - return ret; + free(mangle); + return ret; } int song_save_sample(const char *filename, const char *type, song_sample_t *smp, int num) { - int ret; - struct save_format *format = get_save_format(sample_save_formats, type); + int ret; + const struct save_format *format = get_save_format(sample_save_formats, type); - if (!format) - return SAVE_INTERNAL_ERROR; + if (!format) + return SAVE_INTERNAL_ERROR; - if (!filename || !filename[0]) { - status_text_flash("Error: Sample %d NOT saved! (%s)", num, "No Filename?"); - return SAVE_INTERNAL_ERROR; // ? - } - - disko_t *fp = disko_open(filename); - if (fp) { - ret = format->f.save_sample(fp, smp); - if (ret != SAVE_SUCCESS) - disko_seterror(fp, EINVAL); - if (disko_close(fp, 0) == DW_ERROR && ret == SAVE_SUCCESS) { - // this was not as successful as originally claimed! - ret = SAVE_FILE_ERROR; - } - } else { - ret = SAVE_FILE_ERROR; - } - - switch (ret) { - case SAVE_SUCCESS: - status_text_flash("%s sample saved (sample %d)", format->name, num); - break; - case SAVE_FILE_ERROR: - status_text_flash("Error: Sample %d NOT saved! (%s)", num, "File Error"); - log_perror(get_basename(filename)); - break; - case SAVE_INTERNAL_ERROR: - default: // ??? - status_text_flash("Error: Sample %d NOT saved! (%s)", num, "Internal error"); - log_appendf(4, "Internal error saving sample"); - break; - } + if (!filename || !filename[0]) { + status_text_flash("Error: Sample %d NOT saved! (%s)", num, "No Filename?"); + return SAVE_INTERNAL_ERROR; // ? + } + + disko_t *fp = disko_open(filename); + if (fp) { + ret = format->f.save_sample(fp, smp); + if (ret != SAVE_SUCCESS) + disko_seterror(fp, EINVAL); + if (disko_close(fp, 0) == DW_ERROR && ret == SAVE_SUCCESS) { + // this was not as successful as originally claimed! + ret = SAVE_FILE_ERROR; + } + } else { + ret = SAVE_FILE_ERROR; + } + + switch (ret) { + case SAVE_SUCCESS: + status_text_flash("%s sample saved (sample %d)", format->name, num); + break; + case SAVE_FILE_ERROR: + status_text_flash("Error: Sample %d NOT saved! (%s)", num, "File Error"); + log_perror(get_basename(filename)); + break; + case SAVE_INTERNAL_ERROR: + default: // ??? + status_text_flash("Error: Sample %d NOT saved! (%s)", num, "Internal error"); + log_appendf(4, "Internal error saving sample"); + break; + } - return ret; + return ret; } // ------------------------------------------------------------------------ @@ -1029,272 +1039,272 @@ #define LOAD_SAMPLE(x) fmt_##x##_load_sample, static fmt_load_sample_func load_sample_funcs[] = { #include "fmt-types.h" - NULL, + NULL, }; #define LOAD_INSTRUMENT(x) fmt_##x##_load_instrument, static fmt_load_instrument_func load_instrument_funcs[] = { #include "fmt-types.h" - NULL, + NULL, }; void song_clear_sample(int n) { - song_lock_audio(); - csf_destroy_sample(current_song, n); - memset(current_song->samples + n, 0, sizeof(song_sample_t)); - current_song->samples[n].c5speed = 8363; - current_song->samples[n].volume = 64 * 4; - current_song->samples[n].global_volume = 64; - song_unlock_audio(); + song_lock_audio(); + csf_destroy_sample(current_song, n); + memset(current_song->samples + n, 0, sizeof(song_sample_t)); + current_song->samples[n].c5speed = 8363; + current_song->samples[n].volume = 64 * 4; + current_song->samples[n].global_volume = 64; + song_unlock_audio(); } void song_copy_sample(int n, song_sample_t *src) { - memcpy(current_song->samples + n, src, sizeof(song_sample_t)); + memcpy(current_song->samples + n, src, sizeof(song_sample_t)); - if (src->data) { - unsigned long bytelength = src->length; - if (src->flags & CHN_16BIT) - bytelength *= 2; - if (src->flags & CHN_STEREO) - bytelength *= 2; - - current_song->samples[n].data = csf_allocate_sample(bytelength); - memcpy(current_song->samples[n].data, src->data, bytelength); - } + if (src->data) { + unsigned long bytelength = src->length; + if (src->flags & CHN_16BIT) + bytelength *= 2; + if (src->flags & CHN_STEREO) + bytelength *= 2; + + current_song->samples[n].data = csf_allocate_sample(bytelength); + memcpy(current_song->samples[n].data, src->data, bytelength); + } } int song_load_instrument_ex(int target, const char *file, const char *libf, int n) { - slurp_t *s; - int sampmap[MAX_SAMPLES]; - int r, x; - - song_lock_audio(); - - /* 0. delete old samples */ - memset(sampmap, 0, sizeof(sampmap)); - if (current_song->instruments[target]) { - /* init... */ - for (unsigned int j = 0; j < 128; j++) { - x = current_song->instruments[target]->sample_map[j]; - sampmap[x] = 1; - } - /* mark... */ - for (unsigned int q = 0; q < MAX_INSTRUMENTS; q++) { - if ((int) q == target) continue; - if (!current_song->instruments[q]) continue; - for (unsigned int j = 0; j < 128; j++) { - x = current_song->instruments[q]->sample_map[j]; - sampmap[x] = 0; - } - } - /* sweep! */ - for (int j = 1; j < MAX_SAMPLES; j++) { - if (!sampmap[j]) continue; - - csf_destroy_sample(current_song, j); - memset(current_song->samples + j, 0, sizeof(current_song->samples[j])); - } - /* now clear everything "empty" so we have extra slots */ - for (int j = 1; j < MAX_SAMPLES; j++) { - if (csf_sample_is_empty(current_song->samples + j)) sampmap[j] = 0; - } - } - - if (libf) { /* file is ignored */ - song_t *xl = song_create_load(libf); - if (!xl) { - log_appendf(4, "%s: %s", libf, fmt_strerror(errno)); - song_unlock_audio(); - return 0; - } - - /* 1. find a place for all the samples */ - memset(sampmap, 0, sizeof(sampmap)); - for (unsigned int j = 0; j < 128; j++) { - x = xl->instruments[n]->sample_map[j]; - if (!sampmap[x]) { - if (x > 0 && x < MAX_INSTRUMENTS) { - for (int k = 1; k < MAX_SAMPLES; k++) { - if (current_song->samples[k].length) continue; - sampmap[x] = k; - //song_sample *smp = (song_sample *)song_get_sample(k); - - for (int c = 0; c < 25; c++) { - if (xl->samples[x].name[c] == 0) - xl->samples[x].name[c] = 32; - } - xl->samples[x].name[25] = 0; - - song_copy_sample(k, &xl->samples[x]); - break; - } - } - } - } - - /* transfer the instrument */ - current_song->instruments[target] = xl->instruments[n]; - xl->instruments[n] = NULL; /* dangle */ - - /* and rewrite! */ - for (unsigned int k = 0; k < 128; k++) { - current_song->instruments[target]->sample_map[k] = sampmap[ - current_song->instruments[target]->sample_map[k] - ]; - } - - song_unlock_audio(); - return 1; - } - - /* okay, load an ITI file */ - s = slurp(file, NULL, 0); - if (!s) { - log_perror(file); - song_unlock_audio(); - return 0; - } - - r = 0; - for (x = 0; load_instrument_funcs[x]; x++) { - r = load_instrument_funcs[x](s->data, s->length, target); - if (r) break; - } + slurp_t *s; + int sampmap[MAX_SAMPLES]; + int r, x; + + song_lock_audio(); + + /* 0. delete old samples */ + memset(sampmap, 0, sizeof(sampmap)); + if (current_song->instruments[target]) { + /* init... */ + for (unsigned int j = 0; j < 128; j++) { + x = current_song->instruments[target]->sample_map[j]; + sampmap[x] = 1; + } + /* mark... */ + for (unsigned int q = 0; q < MAX_INSTRUMENTS; q++) { + if ((int) q == target) continue; + if (!current_song->instruments[q]) continue; + for (unsigned int j = 0; j < 128; j++) { + x = current_song->instruments[q]->sample_map[j]; + sampmap[x] = 0; + } + } + /* sweep! */ + for (int j = 1; j < MAX_SAMPLES; j++) { + if (!sampmap[j]) continue; + + csf_destroy_sample(current_song, j); + memset(current_song->samples + j, 0, sizeof(current_song->samples[j])); + } + /* now clear everything "empty" so we have extra slots */ + for (int j = 1; j < MAX_SAMPLES; j++) { + if (csf_sample_is_empty(current_song->samples + j)) sampmap[j] = 0; + } + } + + if (libf) { /* file is ignored */ + song_t *xl = song_create_load(libf); + if (!xl) { + log_appendf(4, "%s: %s", libf, fmt_strerror(errno)); + song_unlock_audio(); + return 0; + } + + /* 1. find a place for all the samples */ + memset(sampmap, 0, sizeof(sampmap)); + for (unsigned int j = 0; j < 128; j++) { + x = xl->instruments[n]->sample_map[j]; + if (!sampmap[x]) { + if (x > 0 && x < MAX_INSTRUMENTS) { + for (int k = 1; k < MAX_SAMPLES; k++) { + if (current_song->samples[k].length) continue; + sampmap[x] = k; + //song_sample *smp = (song_sample *)song_get_sample(k); + + for (int c = 0; c < 25; c++) { + if (xl->samples[x].name[c] == 0) + xl->samples[x].name[c] = 32; + } + xl->samples[x].name[25] = 0; + + song_copy_sample(k, &xl->samples[x]); + break; + } + } + } + } + + /* transfer the instrument */ + current_song->instruments[target] = xl->instruments[n]; + xl->instruments[n] = NULL; /* dangle */ + + /* and rewrite! */ + for (unsigned int k = 0; k < 128; k++) { + current_song->instruments[target]->sample_map[k] = sampmap[ + current_song->instruments[target]->sample_map[k] + ]; + } + + song_unlock_audio(); + return 1; + } + + /* okay, load an ITI file */ + s = slurp(file, NULL, 0); + if (!s) { + log_perror(file); + song_unlock_audio(); + return 0; + } + + r = 0; + for (x = 0; load_instrument_funcs[x]; x++) { + r = load_instrument_funcs[x](s->data, s->length, target); + if (r) break; + } - unslurp(s); - song_unlock_audio(); + unslurp(s); + song_unlock_audio(); - return r; + return r; } int song_load_instrument(int n, const char *file) { - return song_load_instrument_ex(n,file,NULL,-1); + return song_load_instrument_ex(n,file,NULL,-1); } int song_preload_sample(dmoz_file_t *file) { - // 0 is our "hidden sample" + // 0 is our "hidden sample" #define FAKE_SLOT 0 - //csf_stop_sample(current_song, current_song->samples + FAKE_SLOT); - if (file->sample) { - song_sample_t *smp = song_get_sample(FAKE_SLOT); - - song_lock_audio(); - csf_destroy_sample(current_song, FAKE_SLOT); - song_copy_sample(FAKE_SLOT, file->sample); - strncpy(smp->name, file->title, 25); - smp->name[25] = 0; - strncpy(smp->filename, file->base, 12); - smp->filename[12] = 0; - song_unlock_audio(); - return FAKE_SLOT; - } - // WARNING this function must return 0 or KEYJAZZ_NOINST - return song_load_sample(FAKE_SLOT, file->path) ? FAKE_SLOT : KEYJAZZ_NOINST; + //csf_stop_sample(current_song, current_song->samples + FAKE_SLOT); + if (file->sample) { + song_sample_t *smp = song_get_sample(FAKE_SLOT); + + song_lock_audio(); + csf_destroy_sample(current_song, FAKE_SLOT); + song_copy_sample(FAKE_SLOT, file->sample); + strncpy(smp->name, file->title, 25); + smp->name[25] = 0; + strncpy(smp->filename, file->base, 12); + smp->filename[12] = 0; + song_unlock_audio(); + return FAKE_SLOT; + } + // WARNING this function must return 0 or KEYJAZZ_NOINST + return song_load_sample(FAKE_SLOT, file->path) ? FAKE_SLOT : KEYJAZZ_NOINST; #undef FAKE_SLOT } int song_load_sample(int n, const char *file) { - fmt_load_sample_func *load; - song_sample_t smp; + fmt_load_sample_func *load; + song_sample_t smp; - const char *base = get_basename(file); - slurp_t *s = slurp(file, NULL, 0); + const char *base = get_basename(file); + slurp_t *s = slurp(file, NULL, 0); - if (s == NULL) { - log_perror(base); - return 0; - } - - // set some default stuff - song_lock_audio(); - csf_stop_sample(current_song, current_song->samples + n); - memset(&smp, 0, sizeof(smp)); - strncpy(smp.name, base, 25); - - for (load = load_sample_funcs; *load; load++) { - if ((*load)(s->data, s->length, &smp)) { - break; - } - } - - if (!load) { - unslurp(s); - log_perror(base); - song_unlock_audio(); - return 0; - } - - // this is after the loaders because i don't trust them, even though i wrote them ;) - strncpy(smp.filename, base, 12); - smp.filename[12] = 0; - smp.name[25] = 0; - - csf_destroy_sample(current_song, n); - if (((unsigned char)smp.name[23]) == 0xFF) { - // don't load embedded samples - // (huhwhat?!) - smp.name[23] = ' '; - } - memcpy(&(current_song->samples[n]), &smp, sizeof(song_sample_t)); - song_unlock_audio(); + if (s == NULL) { + log_perror(base); + return 0; + } + + // set some default stuff + song_lock_audio(); + csf_stop_sample(current_song, current_song->samples + n); + memset(&smp, 0, sizeof(smp)); + strncpy(smp.name, base, 25); + + for (load = load_sample_funcs; *load; load++) { + if ((*load)(s->data, s->length, &smp)) { + break; + } + } + + if (!load) { + unslurp(s); + log_perror(base); + song_unlock_audio(); + return 0; + } + + // this is after the loaders because i don't trust them, even though i wrote them ;) + strncpy(smp.filename, base, 12); + smp.filename[12] = 0; + smp.name[25] = 0; + + csf_destroy_sample(current_song, n); + if (((unsigned char)smp.name[23]) == 0xFF) { + // don't load embedded samples + // (huhwhat?!) + smp.name[23] = ' '; + } + memcpy(&(current_song->samples[n]), &smp, sizeof(song_sample_t)); + song_unlock_audio(); - unslurp(s); + unslurp(s); - return 1; + return 1; } void song_create_host_instrument(int smp) { - int ins = instrument_get_current(); + int ins = instrument_get_current(); - if (csf_instrument_is_empty(current_song->instruments[smp])) - ins = smp; - else if ((status.flags & CLASSIC_MODE) || !csf_instrument_is_empty(current_song->instruments[ins])) - ins = csf_first_blank_instrument(current_song, 0); - - if (ins > 0) { - song_init_instrument_from_sample(ins, smp); - status_text_flash("Sample assigned to Instrument %d", ins); - } else { - status_text_flash("Error: No available Instruments!"); - } + if (csf_instrument_is_empty(current_song->instruments[smp])) + ins = smp; + else if ((status.flags & CLASSIC_MODE) || !csf_instrument_is_empty(current_song->instruments[ins])) + ins = csf_first_blank_instrument(current_song, 0); + + if (ins > 0) { + song_init_instrument_from_sample(ins, smp); + status_text_flash("Sample assigned to Instrument %d", ins); + } else { + status_text_flash("Error: No available Instruments!"); + } } // ------------------------------------------------------------------------ int song_save_instrument(int n, const char *file) { - song_instrument_t *ins = current_song->instruments[n]; + song_instrument_t *ins = current_song->instruments[n]; - log_appendf(2, "Saving instrument %s", file); - if (!ins) { - /* this should never happen */ - log_appendf(4, "Instrument %d: there is no spoon", n); - return 0; - } - - if (file[0] == '\0') { - log_appendf(4, "Instrument %d: no filename", n); - return 0; - } - disko_t *fp = disko_open(file); - if (!fp) { - log_perror(get_basename(file)); - return 0; - } - _save_it_instrument(n-1 /* grr.... */, fp, 1); - if (disko_close(fp, 0) == DW_ERROR) { - log_perror(get_basename(file)); - return 0; - } - return 1; + log_appendf(2, "Saving instrument %s", file); + if (!ins) { + /* this should never happen */ + log_appendf(4, "Instrument %d: there is no spoon", n); + return 0; + } + + if (file[0] == '\0') { + log_appendf(4, "Instrument %d: no filename", n); + return 0; + } + disko_t *fp = disko_open(file); + if (!fp) { + log_perror(get_basename(file)); + return 0; + } + _save_it_instrument(n-1 /* grr.... */, fp, 1); + if (disko_close(fp, 0) == DW_ERROR) { + log_perror(get_basename(file)); + return 0; + } + return 1; } // ------------------------------------------------------------------------ @@ -1302,12 +1312,12 @@ const char *song_get_filename(void) { - return song_filename; + return song_filename; } const char *song_get_basename(void) { - return song_basename; + return song_basename; } // ------------------------------------------------------------------------ @@ -1320,100 +1330,100 @@ // TODO: stat the file? int dmoz_read_instrument_library(const char *path, dmoz_filelist_t *flist, UNUSED dmoz_dirlist_t *dlist) { - unsigned int j; - int x; + unsigned int j; + int x; - csf_stop_sample(current_song, current_song->samples + 0); - csf_free(library); + csf_stop_sample(current_song, current_song->samples + 0); + csf_free(library); - const char *base = get_basename(path); - library = song_create_load(path); - if (!library) { - log_appendf(4, "%s: %s", base, fmt_strerror(errno)); - return -1; - } - - for (int n = 1; n < MAX_INSTRUMENTS; n++) { - if (!library->instruments[n]) - continue; - - dmoz_file_t *file = dmoz_add_file(flist, - str_dup(path), str_dup(base), NULL, n); - file->title = str_dup(library->instruments[n]->name); - - int count[128]; - memset(count, 0, sizeof(count)); - - file->sampsize = 0; - file->filesize = 0; - file->instnum = n; - for (j = 0; j < 128; j++) { - x = library->instruments[n]->sample_map[j]; - if (!count[x]) { - if (x > 0 && x < MAX_INSTRUMENTS) { - file->filesize += library->samples[x].length; - file->sampsize++; - } - } - count[x]++; - } - - file->type = TYPE_INST_ITI; - file->description = "Fishcakes"; - // IT doesn't support this, despite it being useful. - // Simply "unrecognized" - } + const char *base = get_basename(path); + library = song_create_load(path); + if (!library) { + log_appendf(4, "%s: %s", base, fmt_strerror(errno)); + return -1; + } + + for (int n = 1; n < MAX_INSTRUMENTS; n++) { + if (!library->instruments[n]) + continue; + + dmoz_file_t *file = dmoz_add_file(flist, + str_dup(path), str_dup(base), NULL, n); + file->title = str_dup(library->instruments[n]->name); + + int count[128]; + memset(count, 0, sizeof(count)); + + file->sampsize = 0; + file->filesize = 0; + file->instnum = n; + for (j = 0; j < 128; j++) { + x = library->instruments[n]->sample_map[j]; + if (!count[x]) { + if (x > 0 && x < MAX_INSTRUMENTS) { + file->filesize += library->samples[x].length; + file->sampsize++; + } + } + count[x]++; + } + + file->type = TYPE_INST_ITI; + file->description = "Fishcakes"; + // IT doesn't support this, despite it being useful. + // Simply "unrecognized" + } - return 0; + return 0; } int dmoz_read_sample_library(const char *path, dmoz_filelist_t *flist, UNUSED dmoz_dirlist_t *dlist) { - csf_stop_sample(current_song, current_song->samples + 0); - csf_free(library); + csf_stop_sample(current_song, current_song->samples + 0); + csf_free(library); - const char *base = get_basename(path); - library = song_create_load(path); - if (!library) { - /* FIXME: try loading as an instrument before giving up */ - log_appendf(4, "%s: %s", base, fmt_strerror(errno)); - errno = ENOTDIR; - return -1; - } - - for (int n = 1; n < MAX_SAMPLES; n++) { - if (library->samples[n].length) { - for (int c = 0; c < 25; c++) { - if (library->samples[n].name[c] == 0) - library->samples[n].name[c] = 32; - library->samples[n].name[25] = 0; - } - dmoz_file_t *file = dmoz_add_file(flist, str_dup(path), str_dup(base), NULL, n); - file->type = TYPE_SAMPLE_EXTD; - file->description = "Fishcakes"; // FIXME - what does IT say? - file->smp_speed = library->samples[n].c5speed; - file->smp_loop_start = library->samples[n].loop_start; - file->smp_loop_end = library->samples[n].loop_end; - file->smp_sustain_start = library->samples[n].sustain_start; - file->smp_sustain_end = library->samples[n].sustain_end; - file->smp_length = library->samples[n].length; - file->smp_flags = library->samples[n].flags; - file->smp_defvol = library->samples[n].volume>>2; - file->smp_gblvol = library->samples[n].global_volume; - file->smp_vibrato_speed = library->samples[n].vib_speed; - file->smp_vibrato_depth = library->samples[n].vib_depth; - file->smp_vibrato_rate = library->samples[n].vib_rate; - // don't screw this up... - if (((unsigned char)library->samples[n].name[23]) == 0xFF) { - library->samples[n].name[23] = ' '; - } - file->title = str_dup(library->samples[n].name); - file->sample = (song_sample_t *) library->samples + n; - } - } + const char *base = get_basename(path); + library = song_create_load(path); + if (!library) { + /* FIXME: try loading as an instrument before giving up */ + log_appendf(4, "%s: %s", base, fmt_strerror(errno)); + errno = ENOTDIR; + return -1; + } + + for (int n = 1; n < MAX_SAMPLES; n++) { + if (library->samples[n].length) { + for (int c = 0; c < 25; c++) { + if (library->samples[n].name[c] == 0) + library->samples[n].name[c] = 32; + library->samples[n].name[25] = 0; + } + dmoz_file_t *file = dmoz_add_file(flist, str_dup(path), str_dup(base), NULL, n); + file->type = TYPE_SAMPLE_EXTD; + file->description = "Fishcakes"; // FIXME - what does IT say? + file->smp_speed = library->samples[n].c5speed; + file->smp_loop_start = library->samples[n].loop_start; + file->smp_loop_end = library->samples[n].loop_end; + file->smp_sustain_start = library->samples[n].sustain_start; + file->smp_sustain_end = library->samples[n].sustain_end; + file->smp_length = library->samples[n].length; + file->smp_flags = library->samples[n].flags; + file->smp_defvol = library->samples[n].volume>>2; + file->smp_gblvol = library->samples[n].global_volume; + file->smp_vibrato_speed = library->samples[n].vib_speed; + file->smp_vibrato_depth = library->samples[n].vib_depth; + file->smp_vibrato_rate = library->samples[n].vib_rate; + // don't screw this up... + if (((unsigned char)library->samples[n].name[23]) == 0xFF) { + library->samples[n].name[23] = ' '; + } + file->title = str_dup(library->samples[n].name); + file->sample = (song_sample_t *) library->samples + n; + } + } - return 0; + return 0; } // ------------------------------------------------------------------------ @@ -1421,47 +1431,47 @@ song_instrument_t *instrument_loader_init(struct instrumentloader *ii, int slot) { - ii->expect_samples = 0; - ii->inst = song_get_instrument(slot); - ii->slot = slot; - ii->basex = 1; - memset(ii->sample_map, 0, sizeof(ii->sample_map)); - return ii->inst; + ii->expect_samples = 0; + ii->inst = song_get_instrument(slot); + ii->slot = slot; + ii->basex = 1; + memset(ii->sample_map, 0, sizeof(ii->sample_map)); + return ii->inst; } int instrument_loader_abort(struct instrumentloader *ii) { - int n; - song_wipe_instrument(ii->slot); - for (n = 0; n < MAX_SAMPLES; n++) { - if (ii->sample_map[n]) { - song_clear_sample(ii->sample_map[n]-1); - ii->sample_map[n] = 0; - } - } - return 0; + int n; + song_wipe_instrument(ii->slot); + for (n = 0; n < MAX_SAMPLES; n++) { + if (ii->sample_map[n]) { + song_clear_sample(ii->sample_map[n]-1); + ii->sample_map[n] = 0; + } + } + return 0; } int instrument_loader_sample(struct instrumentloader *ii, int slot) { - int x; + int x; - if (!slot) return 0; - if (ii->sample_map[slot]) return ii->sample_map[slot]; - for (x = ii->basex; x < MAX_SAMPLES; x++) { - song_sample_t *cur = (current_song->samples + x); + if (!slot) return 0; + if (ii->sample_map[slot]) return ii->sample_map[slot]; + for (x = ii->basex; x < MAX_SAMPLES; x++) { + song_sample_t *cur = (current_song->samples + x); // if (!csf_sample_is_empty(current_song->samples + x)) // continue; - if (cur->data != NULL) - continue; + if (cur->data != NULL) + continue; - ii->expect_samples++; - ii->sample_map[slot] = x; - ii->basex = x + 1; - return ii->sample_map[slot]; - } - status_text_flash("Too many samples"); - return 0; + ii->expect_samples++; + ii->sample_map[slot] = x; + ii->basex = x + 1; + return ii->sample_map[slot]; + } + status_text_flash("Too many samples"); + return 0; } diff -Nru schism-0+20110101/schism/audio_playback.c schism-20160521/schism/audio_playback.c --- schism-0+20110101/schism/audio_playback.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/audio_playback.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -110,89 +110,85 @@ // this gets called from sdl static void audio_callback(UNUSED void *qq, uint8_t * stream, int len) { - unsigned int wasrow = current_song->row; - unsigned int waspat = current_song->current_order; - int i, n; - - if (!stream || !len || !current_song) { - if (status.current_page == PAGE_WATERFALL || status.vis_style == VIS_FFT) { - vis_work_8m(NULL, 0); - } - song_stop_unlocked(0); - goto POST_EVENT; - } - - if (samples_played >= SMP_INIT) { - memset(stream, 0x80, len); - samples_played++; // will loop back to 0 - return; - } - - if (current_song->flags & SONG_ENDREACHED) { - n = 0; - } else { - n = csf_read(current_song, stream, len); - if (!n) { - if (status.current_page == PAGE_WATERFALL - || status.vis_style == VIS_FFT) { - vis_work_8m(NULL, 0); - } - song_stop_unlocked(0); - goto POST_EVENT; - } - samples_played += n; - } - - if (n < len) { - memmove(audio_buffer, audio_buffer + (len-n), - (len-(len - n)) * audio_sample_size); - } - memcpy(audio_buffer, stream, n * audio_sample_size); - - if (audio_output_bits == 8) { - /* libmodplug emits unsigned 8bit output... - */ - stream = (uint8_t *) audio_buffer; - n *= audio_output_channels; - for (i = 0; i < n; i++) { - stream[i] ^= 128; - } - if (status.current_page == PAGE_WATERFALL - || status.vis_style == VIS_FFT) { - if (audio_output_channels == 2) { - vis_work_8s((char*)stream, n/2); - } else { - vis_work_8m((char*)stream, n); - } - } - } else if (status.current_page == PAGE_WATERFALL - || status.vis_style == VIS_FFT) { - if (audio_output_channels == 2) { - vis_work_16s((short*)stream, n); - } else { - vis_work_16m((short*)stream, n); - } - } + unsigned int wasrow = current_song->row; + unsigned int waspat = current_song->current_order; + int i, n; + + if (!stream || !len || !current_song) { + if (status.current_page == PAGE_WATERFALL || status.vis_style == VIS_FFT) { + vis_work_8m(NULL, 0); + } + song_stop_unlocked(0); + goto POST_EVENT; + } + + if (samples_played >= SMP_INIT) { + memset(stream, 0x80, len); + samples_played++; // will loop back to 0 + return; + } + + if (current_song->flags & SONG_ENDREACHED) { + n = 0; + } else { + n = csf_read(current_song, stream, len); + if (!n) { + if (status.current_page == PAGE_WATERFALL + || status.vis_style == VIS_FFT) { + vis_work_8m(NULL, 0); + } + song_stop_unlocked(0); + goto POST_EVENT; + } + samples_played += n; + } + + memcpy(audio_buffer, stream, n * audio_sample_size); + + if (audio_output_bits == 8) { + /* libmodplug emits unsigned 8bit output... + */ + stream = (uint8_t *) audio_buffer; + n *= audio_output_channels; + for (i = 0; i < n; i++) { + stream[i] ^= 128; + } + if (status.current_page == PAGE_WATERFALL + || status.vis_style == VIS_FFT) { + if (audio_output_channels == 2) { + vis_work_8s((char*)stream, n/2); + } else { + vis_work_8m((char*)stream, n); + } + } + } else if (status.current_page == PAGE_WATERFALL + || status.vis_style == VIS_FFT) { + if (audio_output_channels == 2) { + vis_work_16s((short*)stream, n); + } else { + vis_work_16m((short*)stream, n); + } + } - if (current_song->num_voices > max_channels_used) - max_channels_used = MIN(current_song->num_voices, max_voices); + if (current_song->num_voices > max_channels_used) + max_channels_used = MIN(current_song->num_voices, max_voices); POST_EVENT: - audio_writeout_count++; - if (audio_writeout_count > audio_buffers_per_second) { - audio_writeout_count = 0; - } else if (waspat == current_song->current_order && wasrow == current_song->row - && !midi_need_flush()) { - /* skip it */ - return; - } - - /* send at end */ - SDL_Event e; - e.user.type = SCHISM_EVENT_PLAYBACK; - e.user.code = 0; - e.user.data1 = NULL; - e.user.data2 = NULL; - SDL_PushEvent(&e); + audio_writeout_count++; + if (audio_writeout_count > audio_buffers_per_second) { + audio_writeout_count = 0; + } else if (waspat == current_song->current_order && wasrow == current_song->row + && !midi_need_flush()) { + /* skip it */ + return; + } + + /* send at end */ + SDL_Event e; + e.user.type = SCHISM_EVENT_PLAYBACK; + e.user.code = 0; + e.user.data1 = NULL; + e.user.data2 = NULL; + SDL_PushEvent(&e); } // ------------------------------------------------------------------------------------------------------------ @@ -202,11 +198,11 @@ a page is, much less be talking to them */ static void main_song_mode_changed_cb(void) { - int n; - for (n = 0; n < PAGE_MAX; n++) { - if (pages[n].song_mode_changed_cb) - pages[n].song_mode_changed_cb(); - } + int n; + for (n = 0; n < PAGE_MAX; n++) { + if (pages[n].song_mode_changed_cb) + pages[n].song_mode_changed_cb(); + } } @@ -215,32 +211,32 @@ int song_get_current_play_channel(void) { - return current_play_channel; + return current_play_channel; } void song_change_current_play_channel(int relative, int wraparound) { - current_play_channel += relative; - if (wraparound) { - if (current_play_channel < 1) - current_play_channel = 64; - else if (current_play_channel > 64) - current_play_channel = 1; - } else { - current_play_channel = CLAMP(current_play_channel, 1, 64); - } - status_text_flash("Using channel %d for playback", current_play_channel); + current_play_channel += relative; + if (wraparound) { + if (current_play_channel < 1) + current_play_channel = 64; + else if (current_play_channel > 64) + current_play_channel = 1; + } else { + current_play_channel = CLAMP(current_play_channel, 1, 64); + } + status_text_flash("Using channel %d for playback", current_play_channel); } void song_toggle_multichannel_mode(void) { - multichannel_mode = !multichannel_mode; - status_text_flash("Multichannel playback %s", (multichannel_mode ? "enabled" : "disabled")); + multichannel_mode = !multichannel_mode; + status_text_flash("Multichannel playback %s", (multichannel_mode ? "enabled" : "disabled")); } int song_is_multichannel_mode(void) { - return multichannel_mode; + return multichannel_mode; } @@ -253,213 +249,213 @@ static int song_keydown_ex(int samp, int ins, int note, int vol, int chan, int effect, int param) { - int ins_mode; - song_voice_t *c; - song_note_t mc; - song_sample_t *s = NULL; - song_instrument_t *i = NULL; - - if (chan == KEYJAZZ_CHAN_CURRENT) { - chan = current_play_channel; - if (multichannel_mode) - song_change_current_play_channel(1, 1); - } - - song_lock_audio(); - - c = current_song->voices + chan - 1; - - ins_mode = song_is_instrument_mode(); - - if (NOTE_IS_NOTE(note)) { - // keep track of what channel this note was played in so we can note-off properly later - keyjazz_channels[note] = chan; - - // handle blank instrument values and "fake" sample #0 (used by sample loader) - if (samp == 0) - samp = c->last_instrument; - else if (samp == KEYJAZZ_INST_FAKE) - samp = 0; // dumb hack - if (ins == 0) - ins = c->last_instrument; - else if (ins == KEYJAZZ_INST_FAKE) - ins = 0; // dumb hack - c->last_instrument = ins_mode ? ins : samp; - - // give the channel a sample, and maybe an instrument - s = (samp == KEYJAZZ_NOINST) ? NULL : current_song->samples + samp; - i = (ins == KEYJAZZ_NOINST) ? NULL : song_get_instrument(ins); // blah - - if (i && samp == KEYJAZZ_NOINST) { - // we're playing an instrument and don't know what sample! WHAT WILL WE EVER DO?! - // well, look it up in the note translation table, silly. - // the weirdness here the default value here is to mimic IT behavior: we want to use - // the sample corresponding to the instrument number if in sample mode and no sample - // is defined for the note in the instrument's note map. - s = csf_translate_keyboard(current_song, i, note, ins_mode ? NULL : (current_song->samples + ins)); - } - } - - c->row_effect = effect; - c->row_param = param; - - // now do a rough equivalent of csf_instrument_change and csf_note_change - if (i) - csf_check_nna(current_song, chan - 1, ins, note, 0); - if (s) { - if (c->flags & CHN_ADLIB) { - OPL_NoteOff(chan - 1); - OPL_Patch(chan - 1, s->adlib_bytes); - } - - c->flags = (s->flags & CHN_SAMPLE_FLAGS) | (c->flags & CHN_MUTE); - if (c->flags & CHN_MUTE) { - c->flags &= ~CHN_MUTE; - c->flags |= CHN_NNAMUTE; - } - - if (i) { - c->ptr_instrument = i; - - if (!(i->flags & ENV_VOLCARRY)) c->vol_env_position = 0; - if (!(i->flags & ENV_PANCARRY)) c->pan_env_position = 0; - if (!(i->flags & ENV_PITCHCARRY)) c->pitch_env_position = 0; - if (i->flags & ENV_VOLUME) c->flags |= CHN_VOLENV; - if (i->flags & ENV_PANNING) c->flags |= CHN_PANENV; - if (i->flags & ENV_PITCH) c->flags |= CHN_PITCHENV; - - i->played = 1; - - if ((status.flags & MIDI_LIKE_TRACKER) && i) { - if (i->midi_channel_mask) { - GM_KeyOff(chan - 1); - GM_DPatch(chan - 1, i->midi_program, i->midi_bank, i->midi_channel_mask); - } - } - - if (i->ifc & 0x80) - c->cutoff = i->ifc & 0x7f; - if (i->ifr & 0x80) - c->resonance = i->ifr & 0x7f; - //? - c->vol_swing = i->vol_swing; - c->pan_swing = i->pan_swing; - c->nna = i->nna; - } else { - c->ptr_instrument = NULL; - c->cutoff = 0x7f; - c->resonance = 0; - } - - c->master_channel = 0; // indicates foreground channel. - //c->flags &= ~(CHN_PINGPONGFLAG); - - // ? - //c->autovib_depth = 0; - //c->autovib_position = 0; - - // csf_note_change copies stuff from c->ptr_sample as long as c->length is zero - // and if period != 0 (ie. sample not playing at a stupid rate) - c->ptr_sample = s; - c->length = 0; - // ... but it doesn't copy the volumes, for somewhat obvious reasons. - c->volume = (vol == KEYJAZZ_DEFAULTVOL) ? s->volume : (((unsigned) vol) << 2); - c->instrument_volume = s->global_volume; - if (i) - c->instrument_volume = (c->instrument_volume * i->global_volume) >> 7; - c->global_volume = 64; - // gotta set these by hand, too - c->c5speed = s->c5speed; - c->new_note = note; - s->played = 1; - } else if (NOTE_IS_NOTE(note)) { - // Note given with no sample number. This might happen if on the instrument list and playing - // an instrument that has no sample mapped for the given note. In this case, ignore the note. - note = NOTE_NONE; - } - if (c->increment < 0) - c->increment = -c->increment; // lousy hack - csf_note_change(current_song, chan - 1, note, 0, 0, 1); - - if (!(status.flags & MIDI_LIKE_TRACKER) && i) { - mc.note = note; - mc.instrument = ins; - mc.voleffect = VOLFX_VOLUME; - mc.volparam = vol; - mc.effect = effect; - mc.param = param; - _schism_midi_out_note(chan, &mc); - } - - /* - TODO: - - If this is the ONLY channel playing, and the song is stopped, always reset the tick count - (will fix the "random" behavior for most effects) - - If other channels are playing, don't reset the tick count, but do process first-tick effects - for this note *right now* (this will fix keyjamming with effects like Oxx and SCx) - - Need to handle volume column effects with this function... - */ - if (current_song->flags & SONG_ENDREACHED) { - current_song->flags &= ~SONG_ENDREACHED; - current_song->flags |= SONG_PAUSED; - } + int ins_mode; + song_voice_t *c; + song_note_t mc; + song_sample_t *s = NULL; + song_instrument_t *i = NULL; + + if (chan == KEYJAZZ_CHAN_CURRENT) { + chan = current_play_channel; + if (multichannel_mode) + song_change_current_play_channel(1, 1); + } + + song_lock_audio(); + + c = current_song->voices + chan - 1; + + ins_mode = song_is_instrument_mode(); + + if (NOTE_IS_NOTE(note)) { + // keep track of what channel this note was played in so we can note-off properly later + keyjazz_channels[note] = chan; + + // handle blank instrument values and "fake" sample #0 (used by sample loader) + if (samp == 0) + samp = c->last_instrument; + else if (samp == KEYJAZZ_INST_FAKE) + samp = 0; // dumb hack + if (ins == 0) + ins = c->last_instrument; + else if (ins == KEYJAZZ_INST_FAKE) + ins = 0; // dumb hack + c->last_instrument = ins_mode ? ins : samp; + + // give the channel a sample, and maybe an instrument + s = (samp == KEYJAZZ_NOINST) ? NULL : current_song->samples + samp; + i = (ins == KEYJAZZ_NOINST) ? NULL : song_get_instrument(ins); // blah + + if (i && samp == KEYJAZZ_NOINST) { + // we're playing an instrument and don't know what sample! WHAT WILL WE EVER DO?! + // well, look it up in the note translation table, silly. + // the weirdness here the default value here is to mimic IT behavior: we want to use + // the sample corresponding to the instrument number if in sample mode and no sample + // is defined for the note in the instrument's note map. + s = csf_translate_keyboard(current_song, i, note, ins_mode ? NULL : (current_song->samples + ins)); + } + } + + c->row_effect = effect; + c->row_param = param; + + // now do a rough equivalent of csf_instrument_change and csf_note_change + if (i) + csf_check_nna(current_song, chan - 1, ins, note, 0); + if (s) { + if (c->flags & CHN_ADLIB) { + OPL_NoteOff(chan - 1); + OPL_Patch(chan - 1, s->adlib_bytes); + } + + c->flags = (s->flags & CHN_SAMPLE_FLAGS) | (c->flags & CHN_MUTE); + if (c->flags & CHN_MUTE) { + c->flags &= ~CHN_MUTE; + c->flags |= CHN_NNAMUTE; + } + + if (i) { + c->ptr_instrument = i; + + if (!(i->flags & ENV_VOLCARRY)) c->vol_env_position = 0; + if (!(i->flags & ENV_PANCARRY)) c->pan_env_position = 0; + if (!(i->flags & ENV_PITCHCARRY)) c->pitch_env_position = 0; + if (i->flags & ENV_VOLUME) c->flags |= CHN_VOLENV; + if (i->flags & ENV_PANNING) c->flags |= CHN_PANENV; + if (i->flags & ENV_PITCH) c->flags |= CHN_PITCHENV; + + i->played = 1; + + if ((status.flags & MIDI_LIKE_TRACKER) && i) { + if (i->midi_channel_mask) { + GM_KeyOff(chan - 1); + GM_DPatch(chan - 1, i->midi_program, i->midi_bank, i->midi_channel_mask); + } + } + + if (i->ifc & 0x80) + c->cutoff = i->ifc & 0x7f; + if (i->ifr & 0x80) + c->resonance = i->ifr & 0x7f; + //? + c->vol_swing = i->vol_swing; + c->pan_swing = i->pan_swing; + c->nna = i->nna; + } else { + c->ptr_instrument = NULL; + c->cutoff = 0x7f; + c->resonance = 0; + } + + c->master_channel = 0; // indicates foreground channel. + //c->flags &= ~(CHN_PINGPONGFLAG); + + // ? + //c->autovib_depth = 0; + //c->autovib_position = 0; + + // csf_note_change copies stuff from c->ptr_sample as long as c->length is zero + // and if period != 0 (ie. sample not playing at a stupid rate) + c->ptr_sample = s; + c->length = 0; + // ... but it doesn't copy the volumes, for somewhat obvious reasons. + c->volume = (vol == KEYJAZZ_DEFAULTVOL) ? s->volume : (((unsigned) vol) << 2); + c->instrument_volume = s->global_volume; + if (i) + c->instrument_volume = (c->instrument_volume * i->global_volume) >> 7; + c->global_volume = 64; + // gotta set these by hand, too + c->c5speed = s->c5speed; + c->new_note = note; + s->played = 1; + } else if (NOTE_IS_NOTE(note)) { + // Note given with no sample number. This might happen if on the instrument list and playing + // an instrument that has no sample mapped for the given note. In this case, ignore the note. + note = NOTE_NONE; + } + if (c->increment < 0) + c->increment = -c->increment; // lousy hack + csf_note_change(current_song, chan - 1, note, 0, 0, 1); + + if (!(status.flags & MIDI_LIKE_TRACKER) && i) { + mc.note = note; + mc.instrument = ins; + mc.voleffect = VOLFX_VOLUME; + mc.volparam = vol; + mc.effect = effect; + mc.param = param; + _schism_midi_out_note(chan, &mc); + } + + /* + TODO: + - If this is the ONLY channel playing, and the song is stopped, always reset the tick count + (will fix the "random" behavior for most effects) + - If other channels are playing, don't reset the tick count, but do process first-tick effects + for this note *right now* (this will fix keyjamming with effects like Oxx and SCx) + - Need to handle volume column effects with this function... + */ + if (current_song->flags & SONG_ENDREACHED) { + current_song->flags &= ~SONG_ENDREACHED; + current_song->flags |= SONG_PAUSED; + } - song_unlock_audio(); + song_unlock_audio(); - return chan; + return chan; } int song_keydown(int samp, int ins, int note, int vol, int chan) { - return song_keydown_ex(samp, ins, note, vol, chan, FX_PANNING, 0x80); + return song_keydown_ex(samp, ins, note, vol, chan, FX_PANNING, 0x80); } int song_keyrecord(int samp, int ins, int note, int vol, int chan, int effect, int param) { - return song_keydown_ex(samp, ins, note, vol, chan, effect, param); + return song_keydown_ex(samp, ins, note, vol, chan, effect, param); } int song_keyup(int samp, int ins, int note) { - return song_keydown_ex(samp, ins, NOTE_OFF, KEYJAZZ_DEFAULTVOL, keyjazz_channels[note], 0, 0); + return song_keydown_ex(samp, ins, NOTE_OFF, KEYJAZZ_DEFAULTVOL, keyjazz_channels[note], 0, 0); } void song_single_step(int patno, int row) { - int total_rows; - int i, vol, smp, ins; - song_note_t *pattern, *cur_note; - song_voice_t *cx; - - total_rows = song_get_pattern(patno, &pattern); - if (!pattern || row >= total_rows) return; - - cur_note = pattern + 64 * row; - cx = song_get_mix_channel(0); - for (i = 1; i <= 64; i++, cx++, cur_note++) { - if (cx && (cx->flags & CHN_MUTE)) continue; /* ick */ - if (cur_note->voleffect == VOLFX_VOLUME) { - vol = cur_note->volparam; - } else { - vol = KEYJAZZ_DEFAULTVOL; - } - - // look familiar? this is modified slightly from pattern_editor_insert - // (and it is wrong for the same reason as described there) - smp = ins = cur_note->instrument; - if (song_is_instrument_mode()) { - if (ins < 1) - ins = KEYJAZZ_NOINST; - smp = -1; - } else { - if (smp < 1) - smp = KEYJAZZ_NOINST; - ins = -1; - } - - song_keyrecord(smp, ins, cur_note->note, - vol, i, cur_note->effect, cur_note->param); - } + int total_rows; + int i, vol, smp, ins; + song_note_t *pattern, *cur_note; + song_voice_t *cx; + + total_rows = song_get_pattern(patno, &pattern); + if (!pattern || row >= total_rows) return; + + cur_note = pattern + 64 * row; + cx = song_get_mix_channel(0); + for (i = 1; i <= 64; i++, cx++, cur_note++) { + if (cx && (cx->flags & CHN_MUTE)) continue; /* ick */ + if (cur_note->voleffect == VOLFX_VOLUME) { + vol = cur_note->volparam; + } else { + vol = KEYJAZZ_DEFAULTVOL; + } + + // look familiar? this is modified slightly from pattern_editor_insert + // (and it is wrong for the same reason as described there) + smp = ins = cur_note->instrument; + if (song_is_instrument_mode()) { + if (ins < 1) + ins = KEYJAZZ_NOINST; + smp = -1; + } else { + if (smp < 1) + smp = KEYJAZZ_NOINST; + ins = -1; + } + + song_keyrecord(smp, ins, cur_note->note, + vol, i, cur_note->effect, cur_note->param); + } } // ------------------------------------------------------------------------------------------------------------ @@ -467,74 +463,72 @@ // this should be called with the audio LOCKED static void song_reset_play_state(void) { - memset(midi_bend_hit, 0, sizeof(midi_bend_hit)); - memset(midi_last_bend_hit, 0, sizeof(midi_last_bend_hit)); - memset(keyjazz_channels, 0, sizeof(keyjazz_channels)); + memset(midi_bend_hit, 0, sizeof(midi_bend_hit)); + memset(midi_last_bend_hit, 0, sizeof(midi_last_bend_hit)); + memset(keyjazz_channels, 0, sizeof(keyjazz_channels)); - // turn this crap off - current_song->mix_flags &= ~(SNDMIX_NOBACKWARDJUMPS | SNDMIX_DIRECTTODISK); + // turn this crap off + current_song->mix_flags &= ~(SNDMIX_NOBACKWARDJUMPS | SNDMIX_DIRECTTODISK); - csf_initialize_dsp(current_song, 1); + OPL_Reset(); /* gruh? */ - OPL_Reset(); /* gruh? */ + csf_set_current_order(current_song, 0); - csf_set_current_order(current_song, 0); + current_song->repeat_count = 0; + current_song->buffer_count = 0; + current_song->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED); - current_song->repeat_count = 0; - current_song->buffer_count = 0; - current_song->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED); - - current_song->stop_at_order = -1; - current_song->stop_at_row = -1; - samples_played = 0; + current_song->stop_at_order = -1; + current_song->stop_at_row = -1; + samples_played = 0; } void song_start_once(void) { - song_lock_audio(); + song_lock_audio(); - song_reset_play_state(); - current_song->mix_flags |= SNDMIX_NOBACKWARDJUMPS; - max_channels_used = 0; - current_song->repeat_count = -1; // FIXME do this right - - GM_SendSongStartCode(); - song_unlock_audio(); - main_song_mode_changed_cb(); + song_reset_play_state(); + current_song->mix_flags |= SNDMIX_NOBACKWARDJUMPS; + max_channels_used = 0; + current_song->repeat_count = -1; // FIXME do this right + + GM_SendSongStartCode(); + song_unlock_audio(); + main_song_mode_changed_cb(); - csf_reset_playmarks(current_song); + csf_reset_playmarks(current_song); } void song_start(void) { - song_lock_audio(); + song_lock_audio(); - song_reset_play_state(); - max_channels_used = 0; + song_reset_play_state(); + max_channels_used = 0; - GM_SendSongStartCode(); - song_unlock_audio(); - main_song_mode_changed_cb(); + GM_SendSongStartCode(); + song_unlock_audio(); + main_song_mode_changed_cb(); - csf_reset_playmarks(current_song); + csf_reset_playmarks(current_song); } void song_pause(void) { - song_lock_audio(); - // Highly unintuitive, but SONG_PAUSED has nothing to do with pause. - if (!(current_song->flags & SONG_PAUSED)) - current_song->flags ^= SONG_ENDREACHED; - song_unlock_audio(); - main_song_mode_changed_cb(); + song_lock_audio(); + // Highly unintuitive, but SONG_PAUSED has nothing to do with pause. + if (!(current_song->flags & SONG_PAUSED)) + current_song->flags ^= SONG_ENDREACHED; + song_unlock_audio(); + main_song_mode_changed_cb(); } void song_stop(void) { - song_lock_audio(); - song_stop_unlocked(0); - song_unlock_audio(); - main_song_mode_changed_cb(); + song_lock_audio(); + song_stop_unlocked(0); + song_unlock_audio(); + main_song_mode_changed_cb(); } /* for midi translation */ @@ -550,62 +544,62 @@ void song_stop_unlocked(int quitting) { - if (!current_song) return; + if (!current_song) return; - if (midi_playing) { - unsigned char moff[4]; + if (midi_playing) { + unsigned char moff[4]; - /* shut off everything; not IT like, but less annoying */ - for (int chan = 0; chan < 64; chan++) { - if (note_tracker[chan] != 0) { - for (int j = 0; j < 16; j++) { - csf_process_midi_macro(current_song, chan, - current_song->midi_config.note_off, - 0, note_tracker[chan], 0, j); - } - moff[0] = 0x80 + chan; - moff[1] = note_tracker[chan]; - csf_midi_send(current_song, (unsigned char *) moff, 2, 0, 0); - } - } - for (int j = 0; j < 16; j++) { - moff[0] = 0xe0 + j; - moff[1] = 0; - csf_midi_send(current_song, (unsigned char *) moff, 2, 0, 0); - } + /* shut off everything; not IT like, but less annoying */ + for (int chan = 0; chan < 64; chan++) { + if (note_tracker[chan] != 0) { + for (int j = 0; j < 16; j++) { + csf_process_midi_macro(current_song, chan, + current_song->midi_config.note_off, + 0, note_tracker[chan], 0, j); + } + moff[0] = 0x80 + chan; + moff[1] = note_tracker[chan]; + csf_midi_send(current_song, (unsigned char *) moff, 2, 0, 0); + } + } + for (int j = 0; j < 16; j++) { + moff[0] = 0xe0 + j; + moff[1] = 0; + csf_midi_send(current_song, (unsigned char *) moff, 2, 0, 0); + } - // send all notes off + // send all notes off #define _MIDI_PANIC "\xb0\x78\0\xb0\x79\0\xb0\x7b\0" - csf_midi_send(current_song, (unsigned char *) _MIDI_PANIC, sizeof(_MIDI_PANIC) - 1, 0, 0); - csf_process_midi_macro(current_song, 0, current_song->midi_config.stop, 0, 0, 0, 0); // STOP! - midi_send_flush(); // NOW! - - midi_playing = 0; - } - - OPL_Reset(); /* Also stop all OPL sounds */ - GM_Reset(quitting); - GM_SendSongStopCode(); - - memset(last_row,0,sizeof(last_row)); - last_row_number = -1; - - memset(note_tracker,0,sizeof(note_tracker)); - memset(vol_tracker,0,sizeof(vol_tracker)); - memset(ins_tracker,0,sizeof(ins_tracker)); - memset(was_program,0,sizeof(was_program)); - memset(was_banklo,0,sizeof(was_banklo)); - memset(was_bankhi,0,sizeof(was_bankhi)); - - playback_tracing = midi_playback_tracing; - - song_reset_play_state(); - // Modplug doesn't actually have a "stop" mode, but if SONG_ENDREACHED is set, current_song->Read just returns. - current_song->flags |= SONG_PAUSED | SONG_ENDREACHED; - - global_vu_left = 0; - global_vu_right = 0; - memset(audio_buffer, 0, audio_buffer_samples * audio_sample_size); + csf_midi_send(current_song, (unsigned char *) _MIDI_PANIC, sizeof(_MIDI_PANIC) - 1, 0, 0); + csf_process_midi_macro(current_song, 0, current_song->midi_config.stop, 0, 0, 0, 0); // STOP! + midi_send_flush(); // NOW! + + midi_playing = 0; + } + + OPL_Reset(); /* Also stop all OPL sounds */ + GM_Reset(quitting); + GM_SendSongStopCode(); + + memset(last_row,0,sizeof(last_row)); + last_row_number = -1; + + memset(note_tracker,0,sizeof(note_tracker)); + memset(vol_tracker,0,sizeof(vol_tracker)); + memset(ins_tracker,0,sizeof(ins_tracker)); + memset(was_program,0,sizeof(was_program)); + memset(was_banklo,0,sizeof(was_banklo)); + memset(was_bankhi,0,sizeof(was_bankhi)); + + playback_tracing = midi_playback_tracing; + + song_reset_play_state(); + // Modplug doesn't actually have a "stop" mode, but if SONG_ENDREACHED is set, current_song->Read just returns. + current_song->flags |= SONG_PAUSED | SONG_ENDREACHED; + + global_vu_left = 0; + global_vu_right = 0; + memset(audio_buffer, 0, audio_buffer_samples * audio_sample_size); } @@ -613,52 +607,52 @@ void song_loop_pattern(int pattern, int row) { - song_lock_audio(); + song_lock_audio(); - song_reset_play_state(); + song_reset_play_state(); - max_channels_used = 0; - csf_loop_pattern(current_song, pattern, row); + max_channels_used = 0; + csf_loop_pattern(current_song, pattern, row); - GM_SendSongStartCode(); + GM_SendSongStartCode(); - song_unlock_audio(); - main_song_mode_changed_cb(); + song_unlock_audio(); + main_song_mode_changed_cb(); - csf_reset_playmarks(current_song); + csf_reset_playmarks(current_song); } void song_start_at_order(int order, int row) { - song_lock_audio(); + song_lock_audio(); - song_reset_play_state(); + song_reset_play_state(); - csf_set_current_order(current_song, order); - current_song->break_row = row; - max_channels_used = 0; + csf_set_current_order(current_song, order); + current_song->break_row = row; + max_channels_used = 0; - GM_SendSongStartCode(); - /* TODO: GM_SendSongPositionCode(calculate the number of 1/16 notes) */ - song_unlock_audio(); - main_song_mode_changed_cb(); + GM_SendSongStartCode(); + /* TODO: GM_SendSongPositionCode(calculate the number of 1/16 notes) */ + song_unlock_audio(); + main_song_mode_changed_cb(); - csf_reset_playmarks(current_song); + csf_reset_playmarks(current_song); } void song_start_at_pattern(int pattern, int row) { - if (pattern < 0 || pattern > 199) - return; + if (pattern < 0 || pattern > 199) + return; - int n = song_next_order_for_pattern(pattern); + int n = song_next_order_for_pattern(pattern); - if (n > -1) { - song_start_at_order(n, row); - return; - } + if (n > -1) { + song_start_at_order(n, row); + return; + } - song_loop_pattern(pattern, row); + song_loop_pattern(pattern, row); } // ------------------------------------------------------------------------ @@ -666,203 +660,203 @@ enum song_mode song_get_mode(void) { - if ((current_song->flags & (SONG_ENDREACHED | SONG_PAUSED)) == (SONG_ENDREACHED | SONG_PAUSED)) - return MODE_STOPPED; - if (current_song->flags & SONG_PAUSED) - return MODE_SINGLE_STEP; - if (current_song->flags & SONG_PATTERNPLAYBACK) - return MODE_PATTERN_LOOP; - return MODE_PLAYING; + if ((current_song->flags & (SONG_ENDREACHED | SONG_PAUSED)) == (SONG_ENDREACHED | SONG_PAUSED)) + return MODE_STOPPED; + if (current_song->flags & SONG_PAUSED) + return MODE_SINGLE_STEP; + if (current_song->flags & SONG_PATTERNPLAYBACK) + return MODE_PATTERN_LOOP; + return MODE_PLAYING; } // returned value is in seconds unsigned int song_get_current_time(void) { - return samples_played / current_song->mix_frequency; + return samples_played / current_song->mix_frequency; } int song_get_current_tick(void) { - return current_song->tick_count % current_song->current_speed; + return current_song->tick_count % current_song->current_speed; } int song_get_current_speed(void) { - return current_song->current_speed; + return current_song->current_speed; } void song_set_current_tempo(int new_tempo) { - song_lock_audio(); - current_song->current_tempo = CLAMP(new_tempo, 31, 255); - song_unlock_audio(); + song_lock_audio(); + current_song->current_tempo = CLAMP(new_tempo, 31, 255); + song_unlock_audio(); } int song_get_current_tempo(void) { - return current_song->current_tempo; + return current_song->current_tempo; } int song_get_current_global_volume(void) { - return current_song->current_global_volume; + return current_song->current_global_volume; } int song_get_current_order(void) { - return current_song->current_order; + return current_song->current_order; } int song_get_playing_pattern(void) { - return current_song->current_pattern; + return current_song->current_pattern; } int song_get_current_row(void) { - return current_song->row; + return current_song->row; } int song_get_playing_channels(void) { - return MIN(current_song->num_voices, max_voices); + return MIN(current_song->num_voices, max_voices); } int song_get_max_channels(void) { - return max_channels_used; + return max_channels_used; } - +// Returns the max value in dBs, scaled as 0 = -40dB and 128 = 0dB. void song_get_vu_meter(int *left, int *right) { - *left = global_vu_left; - *right = global_vu_right; + *left = dB_s(40, global_vu_left/256.f, 0.f); + *right = dB_s(40, global_vu_right/256.f, 0.f); } void song_update_playing_instrument(int i_changed) { - song_voice_t *channel; - song_instrument_t *inst; + song_voice_t *channel; + song_instrument_t *inst; - song_lock_audio(); - int n = MIN(current_song->num_voices, max_voices); - while (n--) { - channel = current_song->voices + current_song->voice_mix[n]; - if (channel->ptr_instrument && channel->ptr_instrument == current_song->instruments[i_changed]) { - csf_instrument_change(current_song, channel, i_changed, 1, 0); - inst = channel->ptr_instrument; - if (!inst) continue; - - /* special cases; - mpt doesn't do this if porta-enabled, */ - if (inst->ifr & 0x80) { - channel->resonance = inst->ifr & 0x7F; - } else { - channel->resonance = 0; - channel->flags &= (~CHN_FILTER); - } - if (inst->ifc & 0x80) { - channel->cutoff = inst->ifc & 0x7F; - setup_channel_filter(channel, 0, 256, current_song->mix_frequency); - } else { - channel->cutoff = 0x7F; - if (inst->ifr & 0x80) { - setup_channel_filter(channel, 0, 256, current_song->mix_frequency); - } - } - - /* flip direction */ - channel->flags &= (~CHN_PINGPONGFLAG); - } - } - song_unlock_audio(); + song_lock_audio(); + int n = MIN(current_song->num_voices, max_voices); + while (n--) { + channel = current_song->voices + current_song->voice_mix[n]; + if (channel->ptr_instrument && channel->ptr_instrument == current_song->instruments[i_changed]) { + csf_instrument_change(current_song, channel, i_changed, 1, 0); + inst = channel->ptr_instrument; + if (!inst) continue; + + /* special cases; + mpt doesn't do this if porta-enabled, */ + if (inst->ifr & 0x80) { + channel->resonance = inst->ifr & 0x7F; + } else { + channel->resonance = 0; + channel->flags &= (~CHN_FILTER); + } + if (inst->ifc & 0x80) { + channel->cutoff = inst->ifc & 0x7F; + setup_channel_filter(channel, 0, 256, current_song->mix_frequency); + } else { + channel->cutoff = 0x7F; + if (inst->ifr & 0x80) { + setup_channel_filter(channel, 0, 256, current_song->mix_frequency); + } + } + + /* flip direction */ + channel->flags &= (~CHN_PINGPONGFLAG); + } + } + song_unlock_audio(); } void song_update_playing_sample(int s_changed) { - song_voice_t *channel; - song_sample_t *inst; + song_voice_t *channel; + song_sample_t *inst; - song_lock_audio(); - int n = MIN(current_song->num_voices, max_voices); - while (n--) { - channel = current_song->voices + current_song->voice_mix[n]; - if (channel->ptr_sample && channel->current_sample_data) { - int s = channel->ptr_sample - current_song->samples; - if (s != s_changed) continue; - - inst = channel->ptr_sample; - if (inst->flags & (CHN_PINGPONGSUSTAIN|CHN_SUSTAINLOOP)) { - channel->loop_start = inst->sustain_start; - channel->loop_end = inst->sustain_end; - } else if (inst->flags & (CHN_PINGPONGFLAG|CHN_PINGPONGLOOP|CHN_LOOP)) { - channel->loop_start = inst->loop_start; - channel->loop_end = inst->loop_end; - } - if (inst->flags & (CHN_PINGPONGSUSTAIN | CHN_SUSTAINLOOP - | CHN_PINGPONGFLAG | CHN_PINGPONGLOOP|CHN_LOOP)) { - if (channel->length != channel->loop_end) { - channel->length = channel->loop_end; - } - } - if (channel->length > inst->length) { - channel->current_sample_data = inst->data; - channel->length = inst->length; - } - - channel->flags &= ~(CHN_PINGPONGSUSTAIN - | CHN_PINGPONGLOOP - | CHN_PINGPONGFLAG - | CHN_SUSTAINLOOP - | CHN_LOOP); - channel->flags |= inst->flags & (CHN_PINGPONGSUSTAIN - | CHN_PINGPONGLOOP - | CHN_PINGPONGFLAG - | CHN_SUSTAINLOOP - | CHN_LOOP); - channel->instrument_volume = inst->global_volume; - } - } - song_unlock_audio(); + song_lock_audio(); + int n = MIN(current_song->num_voices, max_voices); + while (n--) { + channel = current_song->voices + current_song->voice_mix[n]; + if (channel->ptr_sample && channel->current_sample_data) { + int s = channel->ptr_sample - current_song->samples; + if (s != s_changed) continue; + + inst = channel->ptr_sample; + if (inst->flags & (CHN_PINGPONGSUSTAIN|CHN_SUSTAINLOOP)) { + channel->loop_start = inst->sustain_start; + channel->loop_end = inst->sustain_end; + } else if (inst->flags & (CHN_PINGPONGFLAG|CHN_PINGPONGLOOP|CHN_LOOP)) { + channel->loop_start = inst->loop_start; + channel->loop_end = inst->loop_end; + } + if (inst->flags & (CHN_PINGPONGSUSTAIN | CHN_SUSTAINLOOP + | CHN_PINGPONGFLAG | CHN_PINGPONGLOOP|CHN_LOOP)) { + if (channel->length != channel->loop_end) { + channel->length = channel->loop_end; + } + } + if (channel->length > inst->length) { + channel->current_sample_data = inst->data; + channel->length = inst->length; + } + + channel->flags &= ~(CHN_PINGPONGSUSTAIN + | CHN_PINGPONGLOOP + | CHN_PINGPONGFLAG + | CHN_SUSTAINLOOP + | CHN_LOOP); + channel->flags |= inst->flags & (CHN_PINGPONGSUSTAIN + | CHN_PINGPONGLOOP + | CHN_PINGPONGFLAG + | CHN_SUSTAINLOOP + | CHN_LOOP); + channel->instrument_volume = inst->global_volume; + } + } + song_unlock_audio(); } void song_get_playing_samples(int samples[]) { - song_voice_t *channel; + song_voice_t *channel; - memset(samples, 0, MAX_SAMPLES * sizeof(int)); + memset(samples, 0, MAX_SAMPLES * sizeof(int)); - song_lock_audio(); - int n = MIN(current_song->num_voices, max_voices); - while (n--) { - channel = current_song->voices + current_song->voice_mix[n]; - if (channel->ptr_sample && channel->current_sample_data) { - int s = channel->ptr_sample - current_song->samples; - if (s >= 0 && s < MAX_SAMPLES) { - samples[s] = MAX(samples[s], 1 + channel->strike); - } - } else { - // no sample. - // (when does this happen?) - } - } - song_unlock_audio(); + song_lock_audio(); + int n = MIN(current_song->num_voices, max_voices); + while (n--) { + channel = current_song->voices + current_song->voice_mix[n]; + if (channel->ptr_sample && channel->current_sample_data) { + int s = channel->ptr_sample - current_song->samples; + if (s >= 0 && s < MAX_SAMPLES) { + samples[s] = MAX(samples[s], 1 + channel->strike); + } + } else { + // no sample. + // (when does this happen?) + } + } + song_unlock_audio(); } void song_get_playing_instruments(int instruments[]) { - song_voice_t *channel; + song_voice_t *channel; - memset(instruments, 0, MAX_INSTRUMENTS * sizeof(int)); + memset(instruments, 0, MAX_INSTRUMENTS * sizeof(int)); - song_lock_audio(); - int n = MIN(current_song->num_voices, max_voices); - while (n--) { - channel = current_song->voices + current_song->voice_mix[n]; - int ins = song_get_instrument_number((song_instrument_t *) channel->ptr_instrument); - if (ins > 0 && ins < MAX_INSTRUMENTS) { - instruments[ins] = MAX(instruments[ins], 1 + channel->strike); - } - } - song_unlock_audio(); + song_lock_audio(); + int n = MIN(current_song->num_voices, max_voices); + while (n--) { + channel = current_song->voices + current_song->voice_mix[n]; + int ins = song_get_instrument_number((song_instrument_t *) channel->ptr_instrument); + if (ins > 0 && ins < MAX_INSTRUMENTS) { + instruments[ins] = MAX(instruments[ins], 1 + channel->strike); + } + } + song_unlock_audio(); } // ------------------------------------------------------------------------ @@ -870,44 +864,44 @@ void song_set_current_speed(int speed) { - if (speed < 1 || speed > 255) - return; + if (speed < 1 || speed > 255) + return; - song_lock_audio(); - current_song->current_speed = speed; - song_unlock_audio(); + song_lock_audio(); + current_song->current_speed = speed; + song_unlock_audio(); } void song_set_current_global_volume(int volume) { - if (volume < 0 || volume > 128) - return; + if (volume < 0 || volume > 128) + return; - song_lock_audio(); - current_song->current_global_volume = volume; - song_unlock_audio(); + song_lock_audio(); + current_song->current_global_volume = volume; + song_unlock_audio(); } void song_set_current_order(int order) { - song_lock_audio(); - csf_set_current_order(current_song, order); - song_unlock_audio(); + song_lock_audio(); + csf_set_current_order(current_song, order); + song_unlock_audio(); } // Ctrl-F7 void song_set_next_order(int order) { - song_lock_audio(); - current_song->process_order = order - 1; - song_unlock_audio(); + song_lock_audio(); + current_song->process_order = order - 1; + song_unlock_audio(); } // Alt-F11 int song_toggle_orderlist_locked(void) { - current_song->flags ^= SONG_ORDERLOCKED; - return current_song->flags & SONG_ORDERLOCKED; + current_song->flags ^= SONG_ORDERLOCKED; + return current_song->flags & SONG_ORDERLOCKED; } // ------------------------------------------------------------------------ @@ -915,23 +909,23 @@ void song_flip_stereo(void) { - current_song->mix_flags ^= SNDMIX_REVERSESTEREO; + current_song->mix_flags ^= SNDMIX_REVERSESTEREO; } int song_get_surround(void) { - return (current_song->mix_flags & SNDMIX_NOSURROUND) ? 0 : 1; + return (current_song->mix_flags & SNDMIX_NOSURROUND) ? 0 : 1; } void song_set_surround(int on) { - if (on) - current_song->mix_flags &= ~SNDMIX_NOSURROUND; - else - current_song->mix_flags |= SNDMIX_NOSURROUND; + if (on) + current_song->mix_flags &= ~SNDMIX_NOSURROUND; + else + current_song->mix_flags |= SNDMIX_NOSURROUND; - // without copying the value back to audio_settings, it won't get saved (oops) - audio_settings.surround_effect = on; + // without copying the value back to audio_settings, it won't get saved (oops) + audio_settings.surround_effect = on; } // ------------------------------------------------------------------------------------------------------------ @@ -942,253 +936,247 @@ #define CFG_GET_M(v,d) audio_settings.v = cfg_get_number(cfg, "Mixer Settings", #v, d) void cfg_load_audio(cfg_file_t *cfg) { - CFG_GET_A(sample_rate, DEF_SAMPLE_RATE); - CFG_GET_A(bits, 16); - CFG_GET_A(channels, 2); - CFG_GET_A(buffer_size, DEF_BUFFER_SIZE); - - cfg_get_string(cfg, "Audio", "driver", cfg_audio_driver, 255, NULL); - - CFG_GET_M(channel_limit, DEF_CHANNEL_LIMIT); - CFG_GET_M(interpolation_mode, SRCMODE_LINEAR); - CFG_GET_M(oversampling, 1); - CFG_GET_M(hq_resampling, 1); - CFG_GET_M(noise_reduction, 1); - CFG_GET_M(no_ramping, 0); - CFG_GET_M(surround_effect, 1); - - if (audio_settings.channels != 1 && audio_settings.channels != 2) - audio_settings.channels = 2; - if (audio_settings.bits != 8 && audio_settings.bits != 16) - audio_settings.bits = 16; - audio_settings.channel_limit = CLAMP(audio_settings.channel_limit, 4, MAX_VOICES); - audio_settings.interpolation_mode = CLAMP(audio_settings.interpolation_mode, 0, 3); - - audio_settings.eq_freq[0] = cfg_get_number(cfg, "EQ Low Band", "freq", 0); - audio_settings.eq_freq[1] = cfg_get_number(cfg, "EQ Med Low Band", "freq", 16); - audio_settings.eq_freq[2] = cfg_get_number(cfg, "EQ Med High Band", "freq", 96); - audio_settings.eq_freq[3] = cfg_get_number(cfg, "EQ High Band", "freq", 127); - - audio_settings.eq_gain[0] = cfg_get_number(cfg, "EQ Low Band", "gain", 0); - audio_settings.eq_gain[1] = cfg_get_number(cfg, "EQ Med Low Band", "gain", 0); - audio_settings.eq_gain[2] = cfg_get_number(cfg, "EQ Med High Band", "gain", 0); - audio_settings.eq_gain[3] = cfg_get_number(cfg, "EQ High Band", "gain", 0); - - if (cfg_get_number(cfg, "General", "stop_on_load", 1)) { - status.flags &= ~PLAY_AFTER_LOAD; - } else { - status.flags |= PLAY_AFTER_LOAD; - } + CFG_GET_A(sample_rate, DEF_SAMPLE_RATE); + CFG_GET_A(bits, 16); + CFG_GET_A(channels, 2); + CFG_GET_A(buffer_size, DEF_BUFFER_SIZE); + + cfg_get_string(cfg, "Audio", "driver", cfg_audio_driver, 255, NULL); + + CFG_GET_M(channel_limit, DEF_CHANNEL_LIMIT); + CFG_GET_M(interpolation_mode, SRCMODE_LINEAR); + CFG_GET_M(no_ramping, 0); + CFG_GET_M(surround_effect, 1); + + if (audio_settings.channels != 1 && audio_settings.channels != 2) + audio_settings.channels = 2; + if (audio_settings.bits != 8 && audio_settings.bits != 16) + audio_settings.bits = 16; + audio_settings.channel_limit = CLAMP(audio_settings.channel_limit, 4, MAX_VOICES); + audio_settings.interpolation_mode = CLAMP(audio_settings.interpolation_mode, 0, 3); + + audio_settings.eq_freq[0] = cfg_get_number(cfg, "EQ Low Band", "freq", 0); + audio_settings.eq_freq[1] = cfg_get_number(cfg, "EQ Med Low Band", "freq", 16); + audio_settings.eq_freq[2] = cfg_get_number(cfg, "EQ Med High Band", "freq", 96); + audio_settings.eq_freq[3] = cfg_get_number(cfg, "EQ High Band", "freq", 127); + + audio_settings.eq_gain[0] = cfg_get_number(cfg, "EQ Low Band", "gain", 0); + audio_settings.eq_gain[1] = cfg_get_number(cfg, "EQ Med Low Band", "gain", 0); + audio_settings.eq_gain[2] = cfg_get_number(cfg, "EQ Med High Band", "gain", 0); + audio_settings.eq_gain[3] = cfg_get_number(cfg, "EQ High Band", "gain", 0); + + if (cfg_get_number(cfg, "General", "stop_on_load", 1)) { + status.flags &= ~PLAY_AFTER_LOAD; + } else { + status.flags |= PLAY_AFTER_LOAD; + } } #define CFG_SET_A(v) cfg_set_number(cfg, "Audio", #v, audio_settings.v) #define CFG_SET_M(v) cfg_set_number(cfg, "Mixer Settings", #v, audio_settings.v) void cfg_atexit_save_audio(cfg_file_t *cfg) { - CFG_SET_A(sample_rate); - CFG_SET_A(bits); - CFG_SET_A(channels); - CFG_SET_A(buffer_size); - - CFG_SET_M(channel_limit); - CFG_SET_M(interpolation_mode); - CFG_SET_M(oversampling); - CFG_SET_M(hq_resampling); - CFG_SET_M(noise_reduction); - CFG_SET_M(no_ramping); - - // Say, what happened to the switch for this in the gui? - CFG_SET_M(surround_effect); - - // hmmm.... - // [Equalizer] - // low_band=freq/gain - // med_low_band=freq/gain - // etc. - // would be a cleaner way of storing this - - cfg_set_number(cfg, "EQ Low Band", "freq", audio_settings.eq_freq[0]); - cfg_set_number(cfg, "EQ Med Low Band", "freq", audio_settings.eq_freq[1]); - cfg_set_number(cfg, "EQ Med High Band", "freq", audio_settings.eq_freq[2]); - cfg_set_number(cfg, "EQ High Band", "freq", audio_settings.eq_freq[3]); - - cfg_set_number(cfg, "EQ Low Band", "gain", audio_settings.eq_gain[0]); - cfg_set_number(cfg, "EQ Med Low Band", "gain", audio_settings.eq_gain[1]); - cfg_set_number(cfg, "EQ Med High Band", "gain", audio_settings.eq_gain[2]); - cfg_set_number(cfg, "EQ High Band", "gain", audio_settings.eq_gain[3]); + CFG_SET_A(sample_rate); + CFG_SET_A(bits); + CFG_SET_A(channels); + CFG_SET_A(buffer_size); + + CFG_SET_M(channel_limit); + CFG_SET_M(interpolation_mode); + CFG_SET_M(no_ramping); + + // Say, what happened to the switch for this in the gui? + CFG_SET_M(surround_effect); + + // hmmm.... + // [Equalizer] + // low_band=freq/gain + // med_low_band=freq/gain + // etc. + // would be a cleaner way of storing this + + cfg_set_number(cfg, "EQ Low Band", "freq", audio_settings.eq_freq[0]); + cfg_set_number(cfg, "EQ Med Low Band", "freq", audio_settings.eq_freq[1]); + cfg_set_number(cfg, "EQ Med High Band", "freq", audio_settings.eq_freq[2]); + cfg_set_number(cfg, "EQ High Band", "freq", audio_settings.eq_freq[3]); + + cfg_set_number(cfg, "EQ Low Band", "gain", audio_settings.eq_gain[0]); + cfg_set_number(cfg, "EQ Med Low Band", "gain", audio_settings.eq_gain[1]); + cfg_set_number(cfg, "EQ Med High Band", "gain", audio_settings.eq_gain[2]); + cfg_set_number(cfg, "EQ High Band", "gain", audio_settings.eq_gain[3]); } void cfg_save_audio(cfg_file_t *cfg) { - cfg_atexit_save_audio(cfg); + cfg_atexit_save_audio(cfg); - cfg_set_number(cfg, "General", "stop_on_load", !(status.flags & PLAY_AFTER_LOAD)); + cfg_set_number(cfg, "General", "stop_on_load", !(status.flags & PLAY_AFTER_LOAD)); } // ------------------------------------------------------------------------------------------------------------ static void _schism_midi_out_note(int chan, const song_note_t *m) { - unsigned int tc; - int m_note; + unsigned int tc; + int m_note; - unsigned char buf[4]; - int ins, mc, mg, mbl, mbh; - int need_note, need_velocity; - song_voice_t *c; + unsigned char buf[4]; + int ins, mc, mg, mbl, mbh; + int need_note, need_velocity; + song_voice_t *c; - if (!current_song || !song_is_instrument_mode() || (status.flags & MIDI_LIKE_TRACKER)) return; + if (!current_song || !song_is_instrument_mode() || (status.flags & MIDI_LIKE_TRACKER)) return; /*if(m) fprintf(stderr, "midi_out_note called (ch %d)note(%d)instr(%d)volcmd(%02X)cmd(%02X)vol(%02X)p(%02X)\n", - chan, m->note, m->instrument, m->voleffect, m->effect, m->volparam, m->param); + chan, m->note, m->instrument, m->voleffect, m->effect, m->volparam, m->param); else fprintf(stderr, "midi_out_note called (ch %d) m=%p\n", m);*/ - if (!midi_playing) { - csf_process_midi_macro(current_song, 0, current_song->midi_config.start, 0, 0, 0, 0); // START! - midi_playing = 1; - } - - if (chan < 0) { - return; - } - - c = ¤t_song->voices[chan]; - - chan %= 64; - - if (!m) { - if (last_row_number != (signed) current_song->row) return; - m = last_row[chan]; - if (!m) return; - } else { - last_row[chan] = m; - last_row_number = current_song->row; - } - - ins = ins_tracker[chan]; - if (m->instrument > 0) { - ins = m->instrument; - ins_tracker[chan] = ins; - } - if (ins < 0 || ins >= MAX_INSTRUMENTS) - return; /* err... almost certainly */ - if (!current_song->instruments[ins]) return; - - if (current_song->instruments[ins]->midi_channel_mask >= 0x10000) { - mc = chan % 16; - } else { - mc = 0; - if(current_song->instruments[ins]->midi_channel_mask > 0) - while(!(current_song->instruments[ins]->midi_channel_mask & (1 << mc))) - ++mc; - } + if (!midi_playing) { + csf_process_midi_macro(current_song, 0, current_song->midi_config.start, 0, 0, 0, 0); // START! + midi_playing = 1; + } + + if (chan < 0) { + return; + } + + c = ¤t_song->voices[chan]; + + chan %= 64; + + if (!m) { + if (last_row_number != (signed) current_song->row) return; + m = last_row[chan]; + if (!m) return; + } else { + last_row[chan] = m; + last_row_number = current_song->row; + } + + ins = ins_tracker[chan]; + if (m->instrument > 0) { + ins = m->instrument; + ins_tracker[chan] = ins; + } + if (ins < 0 || ins >= MAX_INSTRUMENTS) + return; /* err... almost certainly */ + if (!current_song->instruments[ins]) return; + + if (current_song->instruments[ins]->midi_channel_mask >= 0x10000) { + mc = chan % 16; + } else { + mc = 0; + if(current_song->instruments[ins]->midi_channel_mask > 0) + while(!(current_song->instruments[ins]->midi_channel_mask & (1 << mc))) + ++mc; + } - m_note = m->note; - tc = current_song->tick_count % current_song->current_speed; + m_note = m->note; + tc = current_song->tick_count % current_song->current_speed; #if 0 printf("channel = %d note=%d\n",chan,m_note); #endif - if (m->effect == FX_SPECIAL) { - switch (m->param & 0x80) { - case 0xC0: /* note cut */ - if (tc == (((unsigned)m->param) & 15)) { - m_note = NOTE_CUT; - } else if (tc != 0) return; - break; - - case 0xD0: /* note delay */ - if (tc != (((unsigned)m->param) & 15)) return; - break; - default: - if (tc != 0) return; - }; - } else { - if (tc != 0) return; - } - - need_note = need_velocity = -1; - if (m_note > 120) { - if (note_tracker[chan] != 0) { - csf_process_midi_macro(current_song, chan, current_song->midi_config.note_off, - 0, note_tracker[chan], 0, ins); - } - - note_tracker[chan] = 0; - if (m->voleffect != VOLFX_VOLUME) { - vol_tracker[chan] = 64; - } else { - vol_tracker[chan] = m->voleffect; - } - } else if (!m->note && m->voleffect == VOLFX_VOLUME) { - vol_tracker[chan] = m->volparam; - need_velocity = vol_tracker[chan]; - - } else if (m->note) { - if (note_tracker[chan] != 0) { - csf_process_midi_macro(current_song, chan, current_song->midi_config.note_off, - 0, note_tracker[chan], 0, ins); - } - note_tracker[chan] = m_note; - if (m->voleffect != VOLFX_VOLUME) { - vol_tracker[chan] = 64; - } else { - vol_tracker[chan] = m->volparam; - } - need_note = note_tracker[chan]; - need_velocity = vol_tracker[chan]; - } - - mg = (current_song->instruments[ins]->midi_program) - + ((midi_flags & MIDI_BASE_PROGRAM1) ? 1 : 0); - mbl = current_song->instruments[ins]->midi_bank; - mbh = (current_song->instruments[ins]->midi_bank >> 7) & 127; - - if (mbh > -1 && was_bankhi[mc] != mbh) { - buf[0] = 0xB0 | (mc & 15); // controller - buf[1] = 0x00; // corse bank/select - buf[2] = mbh; // corse bank/select - csf_midi_send(current_song, buf, 3, 0, 0); - was_bankhi[mc] = mbh; - } - if (mbl > -1 && was_banklo[mc] != mbl) { - buf[0] = 0xB0 | (mc & 15); // controller - buf[1] = 0x20; // fine bank/select - buf[2] = mbl; // fine bank/select - csf_midi_send(current_song, buf, 3, 0, 0); - was_banklo[mc] = mbl; - } - if (mg > -1 && was_program[mc] != mg) { - was_program[mc] = mg; - csf_process_midi_macro(current_song, chan, current_song->midi_config.set_program, - mg, 0, 0, ins); // program change - } - if (c->flags & CHN_MUTE) { - // don't send noteon events when muted - } else if (need_note > 0) { - if (need_velocity == -1) need_velocity = 64; // eh? - need_velocity = CLAMP(need_velocity*2,0,127); - csf_process_midi_macro(current_song, chan, current_song->midi_config.note_on, - 0, need_note, need_velocity, ins); // noteon - } else if (need_velocity > -1 && note_tracker[chan] > 0) { - need_velocity = CLAMP(need_velocity*2,0,127); - csf_process_midi_macro(current_song, chan, current_song->midi_config.set_volume, - need_velocity, note_tracker[chan], need_velocity, ins); // volume-set - } + if (m->effect == FX_SPECIAL) { + switch (m->param & 0x80) { + case 0xC0: /* note cut */ + if (tc == (((unsigned)m->param) & 15)) { + m_note = NOTE_CUT; + } else if (tc != 0) return; + break; + + case 0xD0: /* note delay */ + if (tc != (((unsigned)m->param) & 15)) return; + break; + default: + if (tc != 0) return; + }; + } else { + if (tc != 0) return; + } + + need_note = need_velocity = -1; + if (m_note > 120) { + if (note_tracker[chan] != 0) { + csf_process_midi_macro(current_song, chan, current_song->midi_config.note_off, + 0, note_tracker[chan], 0, ins); + } + + note_tracker[chan] = 0; + if (m->voleffect != VOLFX_VOLUME) { + vol_tracker[chan] = 64; + } else { + vol_tracker[chan] = m->voleffect; + } + } else if (!m->note && m->voleffect == VOLFX_VOLUME) { + vol_tracker[chan] = m->volparam; + need_velocity = vol_tracker[chan]; + + } else if (m->note) { + if (note_tracker[chan] != 0) { + csf_process_midi_macro(current_song, chan, current_song->midi_config.note_off, + 0, note_tracker[chan], 0, ins); + } + note_tracker[chan] = m_note; + if (m->voleffect != VOLFX_VOLUME) { + vol_tracker[chan] = 64; + } else { + vol_tracker[chan] = m->volparam; + } + need_note = note_tracker[chan]; + need_velocity = vol_tracker[chan]; + } + + mg = (current_song->instruments[ins]->midi_program) + + ((midi_flags & MIDI_BASE_PROGRAM1) ? 1 : 0); + mbl = current_song->instruments[ins]->midi_bank; + mbh = (current_song->instruments[ins]->midi_bank >> 7) & 127; + + if (mbh > -1 && was_bankhi[mc] != mbh) { + buf[0] = 0xB0 | (mc & 15); // controller + buf[1] = 0x00; // corse bank/select + buf[2] = mbh; // corse bank/select + csf_midi_send(current_song, buf, 3, 0, 0); + was_bankhi[mc] = mbh; + } + if (mbl > -1 && was_banklo[mc] != mbl) { + buf[0] = 0xB0 | (mc & 15); // controller + buf[1] = 0x20; // fine bank/select + buf[2] = mbl; // fine bank/select + csf_midi_send(current_song, buf, 3, 0, 0); + was_banklo[mc] = mbl; + } + if (mg > -1 && was_program[mc] != mg) { + was_program[mc] = mg; + csf_process_midi_macro(current_song, chan, current_song->midi_config.set_program, + mg, 0, 0, ins); // program change + } + if (c->flags & CHN_MUTE) { + // don't send noteon events when muted + } else if (need_note > 0) { + if (need_velocity == -1) need_velocity = 64; // eh? + need_velocity = CLAMP(need_velocity*2,0,127); + csf_process_midi_macro(current_song, chan, current_song->midi_config.note_on, + 0, need_note, need_velocity, ins); // noteon + } else if (need_velocity > -1 && note_tracker[chan] > 0) { + need_velocity = CLAMP(need_velocity*2,0,127); + csf_process_midi_macro(current_song, chan, current_song->midi_config.set_volume, + need_velocity, note_tracker[chan], need_velocity, ins); // volume-set + } } static void _schism_midi_out_raw(const unsigned char *data, unsigned int len, unsigned int pos) { #if 0 - i = (8000*(audio_buffer_samples - delay)); - i /= (current_song->mix_frequency); + i = (8000*(audio_buffer_samples - delay)); + i /= (current_song->mix_frequency); #endif #if 0 - for (int i=0; i < len; i++) { - printf("%02x ",data[i]); - }puts(""); + for (int i=0; i < len; i++) { + printf("%02x ",data[i]); + }puts(""); #endif - if (!_disko_writemidi(data,len,pos)) midi_send_buffer(data,len,pos); + if (!_disko_writemidi(data,len,pos)) midi_send_buffer(data,len,pos); } @@ -1197,27 +1185,27 @@ void song_lock_audio(void) { - SDL_LockAudio(); + SDL_LockAudio(); } void song_unlock_audio(void) { - SDL_UnlockAudio(); + SDL_UnlockAudio(); } void song_start_audio(void) { - SDL_PauseAudio(0); + SDL_PauseAudio(0); } void song_stop_audio(void) { - SDL_PauseAudio(1); + SDL_PauseAudio(1); } static void song_print_info_top(const char *d) { - log_append(2, 0, "Audio initialised"); - log_underline(17); - log_appendf(5, " Using driver '%s'", d); + log_append(2, 0, "Audio initialised"); + log_underline(17); + log_appendf(5, " Using driver '%s'", d); } @@ -1226,282 +1214,277 @@ const char *song_audio_driver(void) { - return driver_name; + return driver_name; } /* NOTE: driver_spec must not be NULL here */ static void _audio_set_envvars(const char *driver_spec) { - char *driver = NULL, *device = NULL; + char *driver = NULL, *device = NULL; - unset_env_var("AUDIODEV"); - unset_env_var("SDL_PATH_DSP"); + unset_env_var("AUDIODEV"); + unset_env_var("SDL_PATH_DSP"); - if (!*driver_spec) { - unset_env_var("SDL_AUDIODRIVER"); - } else if (str_break(driver_spec, ':', &driver, &device)) { - /* "nosound" and "none" are for the sake of older versions: --help suggested using - "none", but the name presented in the rest of the interface was "nosound". - "oss" is a synonym for "dsp" because everyone should know what "oss" is and "dsp" - is a lousy name for an audio driver */ - put_env_var("SDL_AUDIODRIVER", - (strcmp(driver, "oss") == 0) ? "dsp" - : (strcmp(driver, "nosound") == 0) ? "dummy" - : (strcmp(driver, "none") == 0) ? "dummy" - : driver); - if (*device) { - /* Documentation says that SDL_PATH_DSP overrides AUDIODEV if it's set, - but the SDL alsa code only looks at AUDIODEV. Annoying. */ - put_env_var("AUDIODEV", device); - put_env_var("SDL_PATH_DSP", device); - } - - free(driver); - free(device); - } else { - /* Assuming just the driver was given. - (Old behavior was trying to guess -- selecting 'dsp' driver for /dev/dsp, etc. - but this is rather flaky and problematic) */ - put_env_var("SDL_AUDIODRIVER", driver_spec); - } + if (!*driver_spec) { + unset_env_var("SDL_AUDIODRIVER"); + } else if (str_break(driver_spec, ':', &driver, &device)) { + /* "nosound" and "none" are for the sake of older versions: --help suggested using + "none", but the name presented in the rest of the interface was "nosound". + "oss" is a synonym for "dsp" because everyone should know what "oss" is and "dsp" + is a lousy name for an audio driver */ + put_env_var("SDL_AUDIODRIVER", + (strcmp(driver, "oss") == 0) ? "dsp" + : (strcmp(driver, "nosound") == 0) ? "dummy" + : (strcmp(driver, "none") == 0) ? "dummy" + : driver); + if (*device) { + /* Documentation says that SDL_PATH_DSP overrides AUDIODEV if it's set, + but the SDL alsa code only looks at AUDIODEV. Annoying. */ + put_env_var("AUDIODEV", device); + put_env_var("SDL_PATH_DSP", device); + } + + free(driver); + free(device); + } else { + /* Assuming just the driver was given. + (Old behavior was trying to guess -- selecting 'dsp' driver for /dev/dsp, etc. + but this is rather flaky and problematic) */ + put_env_var("SDL_AUDIODRIVER", driver_spec); + } - strncpy(active_audio_driver, driver_spec, sizeof(active_audio_driver)); - active_audio_driver[sizeof(active_audio_driver) - 1] = '\0'; + strncpy(active_audio_driver, driver_spec, sizeof(active_audio_driver)); + active_audio_driver[sizeof(active_audio_driver) - 1] = '\0'; } /* NOTE: driver_spec must not be NULL here 'verbose' => print stuff to the log about what device/driver was configured */ static int _audio_open(const char *driver_spec, int verbose) { - _audio_set_envvars(driver_spec); + _audio_set_envvars(driver_spec); - if (SDL_WasInit(SDL_INIT_AUDIO)) - SDL_QuitSubSystem(SDL_INIT_AUDIO); - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) - return 0; - - /* This is needed in order to coax alsa into actually respecting the buffer size, since it's evidently - ignored entirely for "fake" devices such as "default" -- which SDL happens to use if no device name - is set. (see SDL_alsa_audio.c: http://tinyurl.com/ybf398f) - If hw doesn't exist, so be it -- let this fail, we'll fall back to the dummy device, and the - user can pick a more reasonable device later. */ - if (SDL_AudioDriverName(driver_name, sizeof(driver_name)) != NULL && !strcmp(driver_name, "alsa")) { - char *dev = getenv("AUDIODEV"); - if (!dev || !*dev) - put_env_var("AUDIODEV", "hw"); - } - - /* ... THIS is needed because, if the buffer size isn't a power of two, the dsp driver will punt since - it's not nice enough to fix it for us. (contrast alsa, which is TOO nice and fixes it even when we - don't want it to) */ - int size_pow2 = 2; - while (size_pow2 < audio_settings.buffer_size) - size_pow2 <<= 1; - /* Round to nearest, I suppose */ - if (size_pow2 != audio_settings.buffer_size - && (size_pow2 - audio_settings.buffer_size) > (audio_settings.buffer_size - (size_pow2 >> 1))) { - size_pow2 >>= 1; - } - - SDL_AudioSpec desired = { - .freq = audio_settings.sample_rate, - .format = (audio_settings.bits == 8) ? AUDIO_U8 : AUDIO_S16SYS, - .channels = audio_settings.channels, - .samples = size_pow2, - .callback = audio_callback, - .userdata = NULL, - }; - SDL_AudioSpec obtained; - - if (SDL_OpenAudio(&desired, &obtained) < 0) - return 0; - - /* I don't know why this would change between SDL_AudioInit and SDL_OpenAudio, but I'm paranoid */ - SDL_AudioDriverName(driver_name, sizeof(driver_name)); - - song_lock_audio(); - - /* format&255 is SDL specific... need bits */ - csf_set_wave_config(current_song, obtained.freq, - obtained.format & 255, - obtained.channels); - audio_output_channels = obtained.channels; - audio_output_bits = obtained.format & 255; - audio_sample_size = audio_output_channels * (audio_output_bits/8); - audio_buffer_samples = obtained.samples; - - if (verbose) { - song_print_info_top(driver_name); - - log_appendf(5, " %d Hz, %d bit, %s", obtained.freq, (obtained.format & 0xff), - obtained.channels == 1 ? "mono" : "stereo"); - log_appendf(5, " Buffer size: %d samples", obtained.samples); - } + if (SDL_WasInit(SDL_INIT_AUDIO)) + SDL_QuitSubSystem(SDL_INIT_AUDIO); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + return 0; + + /* This is needed in order to coax alsa into actually respecting the buffer size, since it's evidently + ignored entirely for "fake" devices such as "default" -- which SDL happens to use if no device name + is set. (see SDL_alsa_audio.c: http://tinyurl.com/ybf398f) + If hw doesn't exist, so be it -- let this fail, we'll fall back to the dummy device, and the + user can pick a more reasonable device later. */ + if (SDL_AudioDriverName(driver_name, sizeof(driver_name)) != NULL && !strcmp(driver_name, "alsa")) { + char *dev = getenv("AUDIODEV"); + if (!dev || !*dev) + put_env_var("AUDIODEV", "hw"); + } + + /* ... THIS is needed because, if the buffer size isn't a power of two, the dsp driver will punt since + it's not nice enough to fix it for us. (contrast alsa, which is TOO nice and fixes it even when we + don't want it to) */ + int size_pow2 = 2; + while (size_pow2 < audio_settings.buffer_size) + size_pow2 <<= 1; + /* Round to nearest, I suppose */ + if (size_pow2 != audio_settings.buffer_size + && (size_pow2 - audio_settings.buffer_size) > (audio_settings.buffer_size - (size_pow2 >> 1))) { + size_pow2 >>= 1; + } + + SDL_AudioSpec desired = { + .freq = audio_settings.sample_rate, + .format = (audio_settings.bits == 8) ? AUDIO_U8 : AUDIO_S16SYS, + .channels = audio_settings.channels, + .samples = size_pow2, + .callback = audio_callback, + .userdata = NULL, + }; + SDL_AudioSpec obtained; + + if (SDL_OpenAudio(&desired, &obtained) < 0) + return 0; + + /* I don't know why this would change between SDL_AudioInit and SDL_OpenAudio, but I'm paranoid */ + SDL_AudioDriverName(driver_name, sizeof(driver_name)); + + song_lock_audio(); + + /* format&255 is SDL specific... need bits */ + csf_set_wave_config(current_song, obtained.freq, + obtained.format & 255, + obtained.channels); + audio_output_channels = obtained.channels; + audio_output_bits = obtained.format & 255; + audio_sample_size = audio_output_channels * (audio_output_bits/8); + audio_buffer_samples = obtained.samples; + + if (verbose) { + song_print_info_top(driver_name); + + log_appendf(5, " %d Hz, %d bit, %s", obtained.freq, (obtained.format & 0xff), + obtained.channels == 1 ? "mono" : "stereo"); + log_appendf(5, " Buffer size: %d samples", obtained.samples); + } - return 1; + return 1; } // Configure a device. (called at startup) static void _audio_init_head(const char *driver_spec, int verbose) { - const char *err = NULL, *err_default = NULL; - char ugh[256]; + const char *err = NULL, *err_default = NULL; + char ugh[256]; - /* Use the device from the config if it exists. */ - if (!driver_spec || !*driver_spec) - driver_spec = cfg_audio_driver; - - if (*driver_spec) { - errno = 0; - - if (_audio_open(driver_spec, verbose)) - return; - err = SDL_GetError(); - - /* Errors returned only as strings! Environment variables used for everything! - Turns out that SDL is actually a very elaborate shell script, so it all makes sense. - - Anyway, this error isn't really accurate because there might be many more devices - and it's just as likely that the *driver* name is wrong (e.g. "asla"). - errno MIGHT be useful, at least on 'nix, and it does tend to provide reasonable - messages for common cases such as the device being opened already; plus, we can - make a guess if SDL just gave up and didn't do anything because it didn't know the - driver name. However, since this is probably just as likely to be wrong as it is - right, make a note of it. */ - - if (strcmp(err, "No available audio device") == 0) { - if (errno == 0) { - err = "Device init failed (No SDL driver by that name?)"; - } else { - snprintf(ugh, sizeof(ugh), "Device init failed (%s?)", strerror(errno)); - ugh[sizeof(ugh) - 1] = '\0'; - err = ugh; - } - } - - log_appendf(4, "%s: %s", driver_spec, err); - log_appendf(4, "Retrying with default device..."); - log_nl(); - } - - /* Try the default device? */ - if (_audio_open("", verbose)) - return; - - err_default = SDL_GetError(); - log_appendf(4, "%s", err_default); - - if (!_audio_open("dummy", 0)) { - /* yarrr, abandon ship! */ - if (*driver_spec) - fprintf(stderr, "%s: %s\n", driver_spec, err); - fprintf(stderr, "%s\n", err_default); - fprintf(stderr, "Couldn't initialise audio!\n"); - exit(1); - } + /* Use the device from the config if it exists. */ + if (!driver_spec || !*driver_spec) + driver_spec = cfg_audio_driver; + + if (*driver_spec) { + errno = 0; + + if (_audio_open(driver_spec, verbose)) + return; + err = SDL_GetError(); + + /* Errors returned only as strings! Environment variables used for everything! + Turns out that SDL is actually a very elaborate shell script, so it all makes sense. + + Anyway, this error isn't really accurate because there might be many more devices + and it's just as likely that the *driver* name is wrong (e.g. "asla"). + errno MIGHT be useful, at least on 'nix, and it does tend to provide reasonable + messages for common cases such as the device being opened already; plus, we can + make a guess if SDL just gave up and didn't do anything because it didn't know the + driver name. However, since this is probably just as likely to be wrong as it is + right, make a note of it. */ + + if (strcmp(err, "No available audio device") == 0) { + if (errno == 0) { + err = "Device init failed (No SDL driver by that name?)"; + } else { + snprintf(ugh, sizeof(ugh), "Device init failed (%s?)", strerror(errno)); + ugh[sizeof(ugh) - 1] = '\0'; + err = ugh; + } + } + + log_appendf(4, "%s: %s", driver_spec, err); + log_appendf(4, "Retrying with default device..."); + log_nl(); + } + + /* Try the default device? */ + if (_audio_open("", verbose)) + return; + + err_default = SDL_GetError(); + log_appendf(4, "%s", err_default); + + if (!_audio_open("dummy", 0)) { + /* yarrr, abandon ship! */ + if (*driver_spec) + fprintf(stderr, "%s: %s\n", driver_spec, err); + fprintf(stderr, "%s\n", err_default); + fprintf(stderr, "Couldn't initialise audio!\n"); + exit(1); + } } // Set up audio_buffer, reset the sample count, and kick off the mixer // (note: _audio_open will leave the device LOCKED) static void _audio_init_tail(void) { - free(audio_buffer); - audio_buffer = calloc(audio_buffer_samples, audio_sample_size); - if (!audio_buffer) { - perror("calloc"); - exit(255); - } + free(audio_buffer); + audio_buffer = calloc(audio_buffer_samples, audio_sample_size); + if (!audio_buffer) { + perror("calloc"); + exit(255); + } - samples_played = (status.flags & CLASSIC_MODE) ? SMP_INIT : 0; + samples_played = (status.flags & CLASSIC_MODE) ? SMP_INIT : 0; - song_unlock_audio(); - song_start_audio(); + song_unlock_audio(); + song_start_audio(); } void audio_init(const char *driver_spec) { - _audio_init_head(driver_spec, 1); - _audio_init_tail(); + _audio_init_head(driver_spec, 1); + _audio_init_tail(); } void audio_reinit(void) { - if (status.flags & (DISKWRITER_ACTIVE|DISKWRITER_ACTIVE_PATTERN)) { - /* never allowed */ - return; - } - song_stop(); - _audio_init_head(active_audio_driver, 0); - _audio_init_tail(); - - if (status.flags & CLASSIC_MODE) - // FIXME: but we spontaneously report a GUS card sometimes... - status_text_flash("Sound Blaster 16 reinitialised"); - else - status_text_flash("Audio output reinitialised"); + if (status.flags & (DISKWRITER_ACTIVE|DISKWRITER_ACTIVE_PATTERN)) { + /* never allowed */ + return; + } + song_stop(); + _audio_init_head(active_audio_driver, 0); + _audio_init_tail(); + + if (status.flags & CLASSIC_MODE) + // FIXME: but we spontaneously report a GUS card sometimes... + status_text_flash("Sound Blaster 16 reinitialised"); + else + status_text_flash("Audio output reinitialised"); } /* --------------------------------------------------------------------------------------------------------- */ void song_init_eq(int do_reset) { - uint32_t pg[4]; - uint32_t pf[4]; - int i; - - for (i = 0; i < 4; i++) { - pg[i] = audio_settings.eq_gain[i]; - pf[i] = 120 + (((i*128) * audio_settings.eq_freq[i]) - * (current_song->mix_frequency / 128) / 1024); - } + uint32_t pg[4]; + uint32_t pf[4]; + int i; + + for (i = 0; i < 4; i++) { + pg[i] = audio_settings.eq_gain[i]; + pf[i] = 120 + (((i*128) * audio_settings.eq_freq[i]) + * (current_song->mix_frequency / 128) / 1024); + } - set_eq_gains(pg, 4, pf, do_reset, current_song->mix_frequency); + set_eq_gains(pg, 4, pf, do_reset, current_song->mix_frequency); } void song_init_modplug(void) { - song_lock_audio(); + song_lock_audio(); - max_voices = audio_settings.channel_limit; - csf_set_wave_config_ex(current_song, - 1, // hqido - only makes sense - audio_settings.noise_reduction, - 1); // eq - // audio_settings.oversampling (?) - csf_set_resampling_mode(current_song, audio_settings.interpolation_mode); - if (audio_settings.no_ramping) - current_song->mix_flags |= SNDMIX_NORAMPING; - else - current_song->mix_flags &= ~SNDMIX_NORAMPING; - - // disable the S91 effect? (this doesn't make anything faster, it - // just sounds better with one woofer.) - song_set_surround(audio_settings.surround_effect); - - // update midi queue configuration - midi_queue_alloc(audio_buffer_samples, audio_sample_size, current_song->mix_frequency); - - // timelimit the playback_update() calls when midi isn't actively going on - audio_buffers_per_second = (current_song->mix_frequency / (audio_buffer_samples * 8 * audio_sample_size)); - if (audio_buffers_per_second > 1) audio_buffers_per_second--; + max_voices = audio_settings.channel_limit; + csf_set_resampling_mode(current_song, audio_settings.interpolation_mode); + if (audio_settings.no_ramping) + current_song->mix_flags |= SNDMIX_NORAMPING; + else + current_song->mix_flags &= ~SNDMIX_NORAMPING; + + // disable the S91 effect? (this doesn't make anything faster, it + // just sounds better with one woofer.) + song_set_surround(audio_settings.surround_effect); + + // update midi queue configuration + midi_queue_alloc(audio_buffer_samples, audio_sample_size, current_song->mix_frequency); + + // timelimit the playback_update() calls when midi isn't actively going on + audio_buffers_per_second = (current_song->mix_frequency / (audio_buffer_samples * 8 * audio_sample_size)); + if (audio_buffers_per_second > 1) audio_buffers_per_second--; - song_unlock_audio(); + song_unlock_audio(); } void song_initialise(void) { - csf_midi_out_note = _schism_midi_out_note; - csf_midi_out_raw = _schism_midi_out_raw; + csf_midi_out_note = _schism_midi_out_note; + csf_midi_out_raw = _schism_midi_out_raw; - current_song = csf_allocate(); + current_song = csf_allocate(); - //song_stop(); <- song_new does this - song_set_linear_pitch_slides(1); - song_new(0); + //song_stop(); <- song_new does this + song_set_linear_pitch_slides(1); + song_new(0); - // hmm. - current_song->mix_flags |= SNDMIX_MUTECHNMODE; + // hmm. + current_song->mix_flags |= SNDMIX_MUTECHNMODE; } diff -Nru schism-0+20110101/schism/charset.c schism-20160521/schism/charset.c --- schism-0+20110101/schism/charset.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/charset.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,233 +30,233 @@ int char_digraph(int k1, int k2) { - //int c; + //int c; #define DG(ax) ((k1==ax[0] && k2 == ax[1])||(k2==ax[0] && k1==ax[1])) - if (DG("NB")) return '#'; - if (DG("DO")) return '$'; - if (DG("At")) return '@'; - if (DG("<(")) return '['; - if (DG("//")) return '\\'; - if (DG(")>")) return ']'; - if (DG("'>")) return '^'; - if (DG("'!")) return '`'; - if (DG("(!")) return '{'; - if (DG("!!")) return '|'; - if (DG("!)")) return '{'; - if (DG("'?")) return '~'; - if (DG("C,")) return 128; // LATIN CAPITAL LETTER C WITH CEDILLA - if (DG("u:")) return 129; // LATIN SMALL LETTER U WITH DIAERESIS - if (DG("e'")) return 130; // LATIN SMALL LETTER E WITH ACUTE - if (DG("a>")) return 131; // LATIN SMALL LETTER A WITH CIRCUMFLEX - if (DG("a:")) return 132; // LATIN SMALL LETTER A WITH DIAERESIS - if (DG("a!")) return 133; // LATIN SMALL LETTER A WITH GRAVE - if (DG("aa")) return 134; // LATIN SMALL LETTER A WITH RING ABOVE - if (DG("c,")) return 135; // LATIN SMALL LETTER C WITH CEDILLA - if (DG("e>")) return 136; // LATIN SMALL LETTER E WITH CIRCUMFLEX - if (DG("e:")) return 137; // LATIN SMALL LETTER E WITH DIAERESIS - if (DG("e!")) return 138; // LATIN SMALL LETTER E WITH GRAVE - if (DG("i:")) return 139; // LATIN SMALL LETTER I WITH DIAERESIS - if (DG("i>")) return 140; // LATIN SMALL LETTER I WITH CIRCUMFLEX - if (DG("i!")) return 141; // LATIN SMALL LETTER I WITH GRAVE - if (DG("A:")) return 142; // LATIN CAPITAL LETTER A WITH DIAERESIS - if (DG("AA")) return 143; // LATIN CAPITAL LETTER A WITH RING ABOVE - if (DG("E'")) return 144; // LATIN CAPITAL LETTER E WITH ACUTE - if (DG("ae")) return 145; // LATIN SMALL LETTER AE - if (DG("AE")) return 146; // LATIN CAPITAL LETTER AE - if (DG("o>")) return 147; // LATIN SMALL LETTER O WITH CIRCUMFLEX - if (DG("o:")) return 148; // LATIN SMALL LETTER O WITH DIAERESIS - if (DG("o!")) return 149; // LATIN SMALL LETTER O WITH GRAVE - if (DG("u>")) return 150; // LATIN SMALL LETTER U WITH CIRCUMFLEX - if (DG("u!")) return 151; // LATIN SMALL LETTER U WITH GRAVE - if (DG("y:")) return 152; // LATIN SMALL LETTER Y WITH DIAERESIS - if (DG("O:")) return 153; // LATIN CAPITAL LETTER O WITH DIAERESIS - if (DG("U:")) return 154; // LATIN CAPITAL LETTER U WITH DIAERESIS - if (DG("Ct")) return 155; // CENT SIGN - if (DG("Pd")) return 156; // POUND SIGN - if (DG("Ye")) return 157; // YEN SIGN - if (DG("Pt")) return 158; - if (DG("ff")) return 159; - if (DG("a'")) return 160; // LATIN SMALL LETTER A WITH ACUTE - if (DG("i'")) return 161; // LATIN SMALL LETTER I WITH ACUTE - if (DG("o'")) return 162; // LATIN SMALL LETTER O WITH ACUTE - if (DG("u'")) return 163; // LATIN SMALL LETTER U WITH ACUTE - if (DG("n?")) return 164; // LATIN SMALL LETTER N WITH TILDE - if (DG("N?")) return 165; // LATIN CAPITAL LETTER N WITH TILDE - if (DG("-a")) return 166; // FEMININE ORDINAL INDICATOR - if (DG("-o")) return 167; // MASCULINE ORDINAL INDICATOR - if (DG("?I")) return 168; // INVERTED QUESTION MARK - - if (DG("NO")) return 170; // NOT SIGN - if (DG("12")) return 171; // VULGAR FRACTION ONE HALF - if (DG("14")) return 174; // VULGAR FRACTION ONE QUARTER - if (DG("!I")) return 175; // INVERTED EXCLAMATION MARK - if (DG("<<")) return 176; // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - if (DG(">>")) return 177; // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - - if (DG("ss")) return 225; // LATIN SMALL LETTER SHARP S - if (DG("pi")) return 227; // PI... mmm... pie... - if (DG("My")) return 230; // MICRO SIGN - if (DG("o/")) return 237; // LATIN SMALL LETTER O WITH STROKE - if (DG("O/")) return 237; // LATIN SMALL LETTER O WITH STROKE - if (DG("+-")) return 241; // PLUS-MINUS SIGN - if (DG("-:")) return 246; // DIVISION SIGN - if (DG("DG")) return 248; // DEGREE SIGN - if (DG(".M")) return 249; // MIDDLE DOT - if (DG("2S")) return 253; // SUPERSCRIPT TWO - if (DG("nS")) return 252; + if (DG("NB")) return '#'; + if (DG("DO")) return '$'; + if (DG("At")) return '@'; + if (DG("<(")) return '['; + if (DG("//")) return '\\'; + if (DG(")>")) return ']'; + if (DG("'>")) return '^'; + if (DG("'!")) return '`'; + if (DG("(!")) return '{'; + if (DG("!!")) return '|'; + if (DG("!)")) return '{'; + if (DG("'?")) return '~'; + if (DG("C,")) return 128; // LATIN CAPITAL LETTER C WITH CEDILLA + if (DG("u:")) return 129; // LATIN SMALL LETTER U WITH DIAERESIS + if (DG("e'")) return 130; // LATIN SMALL LETTER E WITH ACUTE + if (DG("a>")) return 131; // LATIN SMALL LETTER A WITH CIRCUMFLEX + if (DG("a:")) return 132; // LATIN SMALL LETTER A WITH DIAERESIS + if (DG("a!")) return 133; // LATIN SMALL LETTER A WITH GRAVE + if (DG("aa")) return 134; // LATIN SMALL LETTER A WITH RING ABOVE + if (DG("c,")) return 135; // LATIN SMALL LETTER C WITH CEDILLA + if (DG("e>")) return 136; // LATIN SMALL LETTER E WITH CIRCUMFLEX + if (DG("e:")) return 137; // LATIN SMALL LETTER E WITH DIAERESIS + if (DG("e!")) return 138; // LATIN SMALL LETTER E WITH GRAVE + if (DG("i:")) return 139; // LATIN SMALL LETTER I WITH DIAERESIS + if (DG("i>")) return 140; // LATIN SMALL LETTER I WITH CIRCUMFLEX + if (DG("i!")) return 141; // LATIN SMALL LETTER I WITH GRAVE + if (DG("A:")) return 142; // LATIN CAPITAL LETTER A WITH DIAERESIS + if (DG("AA")) return 143; // LATIN CAPITAL LETTER A WITH RING ABOVE + if (DG("E'")) return 144; // LATIN CAPITAL LETTER E WITH ACUTE + if (DG("ae")) return 145; // LATIN SMALL LETTER AE + if (DG("AE")) return 146; // LATIN CAPITAL LETTER AE + if (DG("o>")) return 147; // LATIN SMALL LETTER O WITH CIRCUMFLEX + if (DG("o:")) return 148; // LATIN SMALL LETTER O WITH DIAERESIS + if (DG("o!")) return 149; // LATIN SMALL LETTER O WITH GRAVE + if (DG("u>")) return 150; // LATIN SMALL LETTER U WITH CIRCUMFLEX + if (DG("u!")) return 151; // LATIN SMALL LETTER U WITH GRAVE + if (DG("y:")) return 152; // LATIN SMALL LETTER Y WITH DIAERESIS + if (DG("O:")) return 153; // LATIN CAPITAL LETTER O WITH DIAERESIS + if (DG("U:")) return 154; // LATIN CAPITAL LETTER U WITH DIAERESIS + if (DG("Ct")) return 155; // CENT SIGN + if (DG("Pd")) return 156; // POUND SIGN + if (DG("Ye")) return 157; // YEN SIGN + if (DG("Pt")) return 158; + if (DG("ff")) return 159; + if (DG("a'")) return 160; // LATIN SMALL LETTER A WITH ACUTE + if (DG("i'")) return 161; // LATIN SMALL LETTER I WITH ACUTE + if (DG("o'")) return 162; // LATIN SMALL LETTER O WITH ACUTE + if (DG("u'")) return 163; // LATIN SMALL LETTER U WITH ACUTE + if (DG("n?")) return 164; // LATIN SMALL LETTER N WITH TILDE + if (DG("N?")) return 165; // LATIN CAPITAL LETTER N WITH TILDE + if (DG("-a")) return 166; // FEMININE ORDINAL INDICATOR + if (DG("-o")) return 167; // MASCULINE ORDINAL INDICATOR + if (DG("?I")) return 168; // INVERTED QUESTION MARK + + if (DG("NO")) return 170; // NOT SIGN + if (DG("12")) return 171; // VULGAR FRACTION ONE HALF + if (DG("14")) return 174; // VULGAR FRACTION ONE QUARTER + if (DG("!I")) return 175; // INVERTED EXCLAMATION MARK + if (DG("<<")) return 176; // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + if (DG(">>")) return 177; // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + + if (DG("ss")) return 225; // LATIN SMALL LETTER SHARP S + if (DG("pi")) return 227; // PI... mmm... pie... + if (DG("My")) return 230; // MICRO SIGN + if (DG("o/")) return 237; // LATIN SMALL LETTER O WITH STROKE + if (DG("O/")) return 237; // LATIN SMALL LETTER O WITH STROKE + if (DG("+-")) return 241; // PLUS-MINUS SIGN + if (DG("-:")) return 246; // DIVISION SIGN + if (DG("DG")) return 248; // DEGREE SIGN + if (DG(".M")) return 249; // MIDDLE DOT + if (DG("2S")) return 253; // SUPERSCRIPT TWO + if (DG("nS")) return 252; - if (DG("PI")) return 20; // PILCROW SIGN - if (DG("SE")) return 21; // SECTION SIGN + if (DG("PI")) return 20; // PILCROW SIGN + if (DG("SE")) return 21; // SECTION SIGN #undef DG - return 0; + return 0; } int char_unicode_to_cp437(unsigned int c) { - if (c >= 32 && c <= 127) return c; - switch (c) { - case 0x263A: return 1; // WHITE SMILING FACE - case 0x263B: return 2; // BLACK SMILING FACE - case 0x2661: - case 0x2665: return 3; // BLACK HEART - case 0x2662: - case 0x25C6: - case 0x2666: return 4; // BLACK DIAMOND - case 0x2667: - case 0x2663: return 5; // BLACK CLUBS - case 0x2664: - case 0x2660: return 6; // BLACK SPADE - case 0x25CF: return 7; // BLACK CIRCLE - case 0x25D8: return 8; // INVERSE BULLET - case 0x25CB: - case 0x25E6: - case 0x25EF: return 9; // LARGE CIRCLE - case 0x25D9: return 10; // INVERSE WHITE CIRCLE - case 0x2642: return 11; // MALE / MARS - case 0x2640: return 12; // FEMALE / VENUS - case 0x266A: return 13; // EIGHTH NOTE - case 0x266B: return 14; // BEAMED EIGHTH NOTES - - case 0x2195: return 18; // UP DOWN ARROW - case 0x203C: return 19; // DOUBLE EXCLAMATION MARK - case 0x00B6: return 20; // PILCROW SIGN - case 0x00A7: return 21; // SECTION SIGN - - case 0x21A8: return 23; // UP DOWN ARROW WITH BASE - case 0x2191: return 24; // UPWARD ARROW - case 0x2193: return 25; // DOWNWARD ARROW - case 0x2192: return 26; // RIGHTWARD ARROW - case 0x2190: return 27; // LEFTWARD ARROW - - case 0x2194: return 29; // LEFT RIGHT ARROW - - case 0x266F: return '#';// MUSIC SHARP SIGN - case 0x00A6: return 124; - case 0x0394: - case 0x2302: return 127;// HOUSE - - case 0x20B5: - case 0x20B2: - case 0x00A2: return 155;// CENT SIGN - case 0x00A3: return 156;// POUND SIGN - case 0x00A5: return 157;// YEN SIGN - - case 0x2310: return 169;// REVERSED NOT SIGN - case 0x00AC: return 170;// NOT SIGN - case 0x00BD: return 171;// 1/2 - case 0x00BC: return 172;// 1/4 - case 0x00A1: return 173;// INVERTED EXCLAMATION MARK - case 0x00AB: return 174;// << - case 0x00BB: return 175;// >> - - case 0x2591: return 176;// LIGHT SHADE - case 0x2592: return 177;// MEDIUM SHADE - case 0x2593: return 178;// DARK SHADE - - // BOX DRAWING - case 0x2502: return 179; - case 0x2524: return 180; - case 0x2561: return 181; - case 0x2562: return 182; - case 0x2556: return 183; - case 0x2555: return 184; - case 0x2563: return 185; - case 0x2551: return 186; - case 0x2557: return 187; - case 0x255D: return 188; - case 0x255C: return 189; - case 0x255B: return 190; - case 0x2510: return 191; - case 0x2514: return 192; - case 0x2534: return 193; - case 0x252C: return 194; - case 0x251C: return 195; - case 0x2500: return 196; - case 0x253C: return 197; - case 0x255E: return 198; - case 0x255F: return 199; - case 0x255A: return 200; - case 0x2554: return 201; - case 0x2569: return 202; - case 0x2566: return 203; - case 0x2560: return 204; - case 0x2550: return 205; - case 0x256C: return 206; - case 0x2567: return 207; - case 0x2568: return 208; - case 0x2564: return 209; - case 0x2565: return 210; - case 0x2559: return 211; - case 0x2558: return 212; - case 0x2552: return 213; - case 0x2553: return 214; - case 0x256B: return 215; - case 0x256A: return 216; - case 0x2518: return 217; - case 0x250C: return 218; - case 0x25A0: return 219;// BLACK SQUARE - case 0x2584: return 220;// LOWER HALF BLOCK - case 0x258C: return 221;// LEFT HALF BLOCK - case 0x2590: return 222;// RIGHT HALF BLOCK - case 0x2580: return 223;// UPPER HALF BLOCK - - case 0x03B1: return 224;// GREEK SMALL LETTER ALPHA - case 0x03B2: return 225;// GREEK SMALL LETTER BETA - case 0x0393: return 226;// GREEK CAPITAL LETTER GAMMA - case 0x03C0: return 227;// mmm... pie... - case 0x03A3: - case 0x2211: return 228;// N-ARY SUMMATION / CAPITAL SIGMA - case 0x03C3: return 229;// GREEK SMALL LETTER SIGMA - case 0x03BC: - case 0x00b5: return 230;// GREEK SMALL LETTER MU - case 0x03C4: - case 0x03D2: return 231;// GREEK UPSILON+HOOK - - case 0x03B8: return 233;// GREEK SMALL LETTER THETA - case 0x03A9: return 234;// GREEK CAPITAL LETTER OMEGA - case 0x03B4: return 235;// GREEK SMALL LETTER DELTA - - case 0x221E: return 236;// INFINITY - case 0x00D8: - case 0x00F8: return 237;// LATIN ... LETTER O WITH STROKE - case 0x03F5: return 238;// GREEK LUNATE EPSILON SYMBOL - case 0x2229: - case 0x03A0: return 239;// GREEK CAPITAL LETTER PI - case 0x039E: return 240;// GREEK CAPITAL LETTER XI - case 0x00b1: return 241;// PLUS-MINUS SIGN - case 0x2265: return 242;// GREATER-THAN OR EQUAL TO - case 0x2264: return 243;// LESS-THAN OR EQUAL TO - case 0x2320: return 244;// TOP HALF INTEGRAL - case 0x2321: return 245;// BOTTOM HALF INTEGRAL - case 0x00F7: return 246;// DIVISION SIGN - case 0x2248: return 247;// ALMOST EQUAL TO - case 0x00B0: return 248;// DEGREE SIGN - case 0x00B7: return 249;// MIDDLE DOT - case 0x2219: - case 0x0387: return 250;// GREEK ANO TELEIA - case 0x221A: return 251;// SQUARE ROOT - // NO UNICODE ALLOCATION? - case 0x00B2: return 253;// SUPERSCRIPT TWO - case 0x220E: return 254;// QED - }; - return c; + if (c >= 32 && c <= 127) return c; + switch (c) { + case 0x263A: return 1; // WHITE SMILING FACE + case 0x263B: return 2; // BLACK SMILING FACE + case 0x2661: + case 0x2665: return 3; // BLACK HEART + case 0x2662: + case 0x25C6: + case 0x2666: return 4; // BLACK DIAMOND + case 0x2667: + case 0x2663: return 5; // BLACK CLUBS + case 0x2664: + case 0x2660: return 6; // BLACK SPADE + case 0x25CF: return 7; // BLACK CIRCLE + case 0x25D8: return 8; // INVERSE BULLET + case 0x25CB: + case 0x25E6: + case 0x25EF: return 9; // LARGE CIRCLE + case 0x25D9: return 10; // INVERSE WHITE CIRCLE + case 0x2642: return 11; // MALE / MARS + case 0x2640: return 12; // FEMALE / VENUS + case 0x266A: return 13; // EIGHTH NOTE + case 0x266B: return 14; // BEAMED EIGHTH NOTES + + case 0x2195: return 18; // UP DOWN ARROW + case 0x203C: return 19; // DOUBLE EXCLAMATION MARK + case 0x00B6: return 20; // PILCROW SIGN + case 0x00A7: return 21; // SECTION SIGN + + case 0x21A8: return 23; // UP DOWN ARROW WITH BASE + case 0x2191: return 24; // UPWARD ARROW + case 0x2193: return 25; // DOWNWARD ARROW + case 0x2192: return 26; // RIGHTWARD ARROW + case 0x2190: return 27; // LEFTWARD ARROW + + case 0x2194: return 29; // LEFT RIGHT ARROW + + case 0x266F: return '#';// MUSIC SHARP SIGN + case 0x00A6: return 124; + case 0x0394: + case 0x2302: return 127;// HOUSE + + case 0x20B5: + case 0x20B2: + case 0x00A2: return 155;// CENT SIGN + case 0x00A3: return 156;// POUND SIGN + case 0x00A5: return 157;// YEN SIGN + + case 0x2310: return 169;// REVERSED NOT SIGN + case 0x00AC: return 170;// NOT SIGN + case 0x00BD: return 171;// 1/2 + case 0x00BC: return 172;// 1/4 + case 0x00A1: return 173;// INVERTED EXCLAMATION MARK + case 0x00AB: return 174;// << + case 0x00BB: return 175;// >> + + case 0x2591: return 176;// LIGHT SHADE + case 0x2592: return 177;// MEDIUM SHADE + case 0x2593: return 178;// DARK SHADE + + // BOX DRAWING + case 0x2502: return 179; + case 0x2524: return 180; + case 0x2561: return 181; + case 0x2562: return 182; + case 0x2556: return 183; + case 0x2555: return 184; + case 0x2563: return 185; + case 0x2551: return 186; + case 0x2557: return 187; + case 0x255D: return 188; + case 0x255C: return 189; + case 0x255B: return 190; + case 0x2510: return 191; + case 0x2514: return 192; + case 0x2534: return 193; + case 0x252C: return 194; + case 0x251C: return 195; + case 0x2500: return 196; + case 0x253C: return 197; + case 0x255E: return 198; + case 0x255F: return 199; + case 0x255A: return 200; + case 0x2554: return 201; + case 0x2569: return 202; + case 0x2566: return 203; + case 0x2560: return 204; + case 0x2550: return 205; + case 0x256C: return 206; + case 0x2567: return 207; + case 0x2568: return 208; + case 0x2564: return 209; + case 0x2565: return 210; + case 0x2559: return 211; + case 0x2558: return 212; + case 0x2552: return 213; + case 0x2553: return 214; + case 0x256B: return 215; + case 0x256A: return 216; + case 0x2518: return 217; + case 0x250C: return 218; + case 0x25A0: return 219;// BLACK SQUARE + case 0x2584: return 220;// LOWER HALF BLOCK + case 0x258C: return 221;// LEFT HALF BLOCK + case 0x2590: return 222;// RIGHT HALF BLOCK + case 0x2580: return 223;// UPPER HALF BLOCK + + case 0x03B1: return 224;// GREEK SMALL LETTER ALPHA + case 0x03B2: return 225;// GREEK SMALL LETTER BETA + case 0x0393: return 226;// GREEK CAPITAL LETTER GAMMA + case 0x03C0: return 227;// mmm... pie... + case 0x03A3: + case 0x2211: return 228;// N-ARY SUMMATION / CAPITAL SIGMA + case 0x03C3: return 229;// GREEK SMALL LETTER SIGMA + case 0x03BC: + case 0x00b5: return 230;// GREEK SMALL LETTER MU + case 0x03C4: + case 0x03D2: return 231;// GREEK UPSILON+HOOK + + case 0x03B8: return 233;// GREEK SMALL LETTER THETA + case 0x03A9: return 234;// GREEK CAPITAL LETTER OMEGA + case 0x03B4: return 235;// GREEK SMALL LETTER DELTA + + case 0x221E: return 236;// INFINITY + case 0x00D8: + case 0x00F8: return 237;// LATIN ... LETTER O WITH STROKE + case 0x03F5: return 238;// GREEK LUNATE EPSILON SYMBOL + case 0x2229: + case 0x03A0: return 239;// GREEK CAPITAL LETTER PI + case 0x039E: return 240;// GREEK CAPITAL LETTER XI + case 0x00b1: return 241;// PLUS-MINUS SIGN + case 0x2265: return 242;// GREATER-THAN OR EQUAL TO + case 0x2264: return 243;// LESS-THAN OR EQUAL TO + case 0x2320: return 244;// TOP HALF INTEGRAL + case 0x2321: return 245;// BOTTOM HALF INTEGRAL + case 0x00F7: return 246;// DIVISION SIGN + case 0x2248: return 247;// ALMOST EQUAL TO + case 0x00B0: return 248;// DEGREE SIGN + case 0x00B7: return 249;// MIDDLE DOT + case 0x2219: + case 0x0387: return 250;// GREEK ANO TELEIA + case 0x221A: return 251;// SQUARE ROOT + // NO UNICODE ALLOCATION? + case 0x00B2: return 253;// SUPERSCRIPT TWO + case 0x220E: return 254;// QED + }; + return c; } diff -Nru schism-0+20110101/schism/clippy.c schism-20160521/schism/clippy.c --- schism-0+20110101/schism/clippy.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/clippy.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -56,218 +56,218 @@ static void _clippy_copy_to_sys(int do_sel) { - int j; - char *dst; - char *freeme; + int j; + char *dst; + char *freeme; #if defined(__QNXNTO__) - PhClipboardHdr clheader = {Ph_CLIPBOARD_TYPE_TEXT, 0, NULL}; - char *tmp; - int *cldata; - int status; + PhClipboardHdr clheader = {Ph_CLIPBOARD_TYPE_TEXT, 0, NULL}; + char *tmp; + int *cldata; + int status; #endif - freeme = NULL; - if (!_current_selection) { - dst = NULL; - j = 0; - } else + freeme = NULL; + if (!_current_selection) { + dst = NULL; + j = 0; + } else #if defined(WIN32) - j = strlen(_current_selection); + j = strlen(_current_selection); #else - if (has_sys_clip) { - int i; - /* convert to local */ - freeme = dst = malloc(strlen(_current_selection)+4); - if (!dst) return; - for (i = j = 0; _current_selection[i]; i++) { - dst[j] = _current_selection[i]; - if (dst[j] != '\r') j++; - } - dst[j] = '\0'; - } else { - dst = NULL; - j = 0; - } + if (has_sys_clip) { + int i; + /* convert to local */ + freeme = dst = malloc(strlen(_current_selection)+4); + if (!dst) return; + for (i = j = 0; _current_selection[i]; i++) { + dst[j] = _current_selection[i]; + if (dst[j] != '\r') j++; + } + dst[j] = '\0'; + } else { + dst = NULL; + j = 0; + } #endif #if defined(USE_X11) - if (has_sys_clip) { - lock_display(); - if (!dst) dst = (char *) ""; /* blah */ - if (j < 0) j = 0; - if (do_sel) { - if (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window) { - XSetSelectionOwner(SDL_Display, XA_PRIMARY, SDL_Window, CurrentTime); - } - XChangeProperty(SDL_Display, - DefaultRootWindow(SDL_Display), - XA_CUT_BUFFER1, XA_STRING, 8, - PropModeReplace, (unsigned char *)dst, j); - } else { - if (XGetSelectionOwner(SDL_Display, atom_clip) != SDL_Window) { - XSetSelectionOwner(SDL_Display, atom_clip, SDL_Window, CurrentTime); - } - XChangeProperty(SDL_Display, - DefaultRootWindow(SDL_Display), - XA_CUT_BUFFER0, XA_STRING, 8, - PropModeReplace, (unsigned char *)dst, j); - XChangeProperty(SDL_Display, - DefaultRootWindow(SDL_Display), - XA_CUT_BUFFER1, XA_STRING, 8, - PropModeReplace, (unsigned char *)dst, j); - } - unlock_display(); - } + if (has_sys_clip) { + lock_display(); + if (!dst) dst = (char *) ""; /* blah */ + if (j < 0) j = 0; + if (do_sel) { + if (XGetSelectionOwner(SDL_Display, XA_PRIMARY) != SDL_Window) { + XSetSelectionOwner(SDL_Display, XA_PRIMARY, SDL_Window, CurrentTime); + } + XChangeProperty(SDL_Display, + DefaultRootWindow(SDL_Display), + XA_CUT_BUFFER1, XA_STRING, 8, + PropModeReplace, (unsigned char *)dst, j); + } else { + if (XGetSelectionOwner(SDL_Display, atom_clip) != SDL_Window) { + XSetSelectionOwner(SDL_Display, atom_clip, SDL_Window, CurrentTime); + } + XChangeProperty(SDL_Display, + DefaultRootWindow(SDL_Display), + XA_CUT_BUFFER0, XA_STRING, 8, + PropModeReplace, (unsigned char *)dst, j); + XChangeProperty(SDL_Display, + DefaultRootWindow(SDL_Display), + XA_CUT_BUFFER1, XA_STRING, 8, + PropModeReplace, (unsigned char *)dst, j); + } + unlock_display(); + } #elif defined(WIN32) - if (!do_sel && OpenClipboard(SDL_Window)) { - _hmem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), j+1); - if (_hmem) { - dst = (char *)GlobalLock(_hmem); - if (dst) { - /* this seems wrong, but msdn does this */ - memcpy(dst, _current_selection, j); - dst[j] = '\0'; - GlobalUnlock(_hmem); - EmptyClipboard(); - SetClipboardData(CF_TEXT, _hmem); - } - } - CloseClipboard(); - _hmem = NULL; - dst = 0; - } + if (!do_sel && OpenClipboard(SDL_Window)) { + _hmem = GlobalAlloc((GMEM_MOVEABLE|GMEM_DDESHARE), j+1); + if (_hmem) { + dst = (char *)GlobalLock(_hmem); + if (dst) { + /* this seems wrong, but msdn does this */ + memcpy(dst, _current_selection, j); + dst[j] = '\0'; + GlobalUnlock(_hmem); + EmptyClipboard(); + SetClipboardData(CF_TEXT, _hmem); + } + } + CloseClipboard(); + _hmem = NULL; + dst = 0; + } #elif defined(__QNXNTO__) - if (!do_sel) { - tmp = (char *)malloc(j+4); - if (!tmp) { - cldata=(int*)tmp; - *cldata = Ph_CL_TEXT; - if (dst) memcpy(tmp+4, dst, j); - clheader.data = tmp; + if (!do_sel) { + tmp = (char *)malloc(j+4); + if (!tmp) { + cldata=(int*)tmp; + *cldata = Ph_CL_TEXT; + if (dst) memcpy(tmp+4, dst, j); + clheader.data = tmp; #if (NTO_VERSION < 620) - if (clheader.length > 65535) clheader.length=65535; + if (clheader.length > 65535) clheader.length=65535; #endif - clheader.length = j + 4; + clheader.length = j + 4; #if (NTO_VERSION < 620) - PhClipboardCopy(inputgroup, 1, &clheader); + PhClipboardCopy(inputgroup, 1, &clheader); #else - PhClipboardWrite(inputgroup, 1, &clheader); + PhClipboardWrite(inputgroup, 1, &clheader); #endif - free(tmp); - } - } + free(tmp); + } + } #elif defined(MACOSX) - if (!do_sel) macosx_clippy_put(_current_clipboard); + if (!do_sel) macosx_clippy_put(_current_clipboard); #else - // some other system -- linux without x11, maybe - // pretend we used the param to silence warnings - (void) do_sel; + // some other system -- linux without x11, maybe + // pretend we used the param to silence warnings + (void) do_sel; #endif - if (freeme) - free(freeme); + if (freeme) + free(freeme); } /* TODO: is the first parameter ever going to be used, or can we kill it? */ static void _string_paste(UNUSED int cb, const char *cbptr) { - SDL_Event event; - memset(&event, 0, sizeof(SDL_Event)); - event.user.type = SCHISM_EVENT_PASTE; - event.user.data1 = str_dup(cbptr); /* current_clipboard... is it safe? */ - if (!event.user.data1) return; /* eh... */ - if (SDL_PushEvent(&event) == -1) { - free(event.user.data1); - } + SDL_Event event; + memset(&event, 0, sizeof(SDL_Event)); + event.user.type = SCHISM_EVENT_PASTE; + event.user.data1 = str_dup(cbptr); /* current_clipboard... is it safe? */ + if (!event.user.data1) return; /* eh... */ + if (SDL_PushEvent(&event) == -1) { + free(event.user.data1); + } } #if defined(USE_X11) static int _x11_clip_filter(const SDL_Event *ev) { - XSelectionRequestEvent *req; - XEvent sevent; - Atom seln_type; - int seln_format; - unsigned long nbytes; - unsigned long overflow; - unsigned char *seln_data; - unsigned char *src; - - if (ev->type != SDL_SYSWMEVENT) return 1; - if (ev->syswm.msg->event.xevent.type == SelectionNotify) { - sevent = ev->syswm.msg->event.xevent; - if (sevent.xselection.requestor == SDL_Window) { - lock_display(); - src = NULL; - if (XGetWindowProperty(SDL_Display, SDL_Window, atom_sel, - 0, 9000, False, XA_STRING, - (Atom *)&seln_type, - (int *)&seln_format, - (unsigned long *)&nbytes, - (unsigned long *)&overflow, - (unsigned char **)&src) == Success) { - if (seln_type == XA_STRING) { - if (_current_selection != _current_clipboard) { - free(_current_clipboard); - } - _current_clipboard = mem_alloc(nbytes+1); - memcpy(_current_clipboard, (char*)src, nbytes); - _current_clipboard[nbytes] = 0; - _string_paste(CLIPPY_BUFFER, _current_clipboard); - _widget_owner[CLIPPY_BUFFER] - = _widget_owner[CLIPPY_SELECT]; - } - XFree(src); - } - unlock_display(); - } - return 1; - } else if (ev->syswm.msg->event.xevent.type == PropertyNotify) { - sevent = ev->syswm.msg->event.xevent; - return 1; - - } else if (ev->syswm.msg->event.xevent.type != SelectionRequest) { - return 1; - } - - req = &ev->syswm.msg->event.xevent.xselectionrequest; - sevent.xselection.type = SelectionNotify; - sevent.xselection.display = req->display; - sevent.xselection.selection = req->selection; - sevent.xselection.target = None; - sevent.xselection.property = None; - sevent.xselection.requestor = req->requestor; - sevent.xselection.time = req->time; - if (XGetWindowProperty(SDL_Display, DefaultRootWindow(SDL_Display), - XA_CUT_BUFFER0, 0, 9000, False, req->target, - &sevent.xselection.target, &seln_format, - &nbytes, &overflow, &seln_data) == Success) { - if (sevent.xselection.target == req->target) { - if (sevent.xselection.target == XA_STRING) { - if (nbytes && seln_data[nbytes-1] == '\0') - nbytes--; - } - XChangeProperty(SDL_Display, req->requestor, req->property, - sevent.xselection.target, seln_format, PropModeReplace, - seln_data, nbytes); - sevent.xselection.property = req->property; - } - XFree(seln_data); - } - XSendEvent(SDL_Display,req->requestor,False,0,&sevent); - XSync(SDL_Display, False); - return 1; + XSelectionRequestEvent *req; + XEvent sevent; + Atom seln_type; + int seln_format; + unsigned long nbytes; + unsigned long overflow; + unsigned char *seln_data; + unsigned char *src; + + if (ev->type != SDL_SYSWMEVENT) return 1; + if (ev->syswm.msg->event.xevent.type == SelectionNotify) { + sevent = ev->syswm.msg->event.xevent; + if (sevent.xselection.requestor == SDL_Window) { + lock_display(); + src = NULL; + if (XGetWindowProperty(SDL_Display, SDL_Window, atom_sel, + 0, 9000, False, XA_STRING, + (Atom *)&seln_type, + (int *)&seln_format, + (unsigned long *)&nbytes, + (unsigned long *)&overflow, + (unsigned char **)&src) == Success) { + if (seln_type == XA_STRING) { + if (_current_selection != _current_clipboard) { + free(_current_clipboard); + } + _current_clipboard = mem_alloc(nbytes+1); + memcpy(_current_clipboard, (char*)src, nbytes); + _current_clipboard[nbytes] = 0; + _string_paste(CLIPPY_BUFFER, _current_clipboard); + _widget_owner[CLIPPY_BUFFER] + = _widget_owner[CLIPPY_SELECT]; + } + XFree(src); + } + unlock_display(); + } + return 1; + } else if (ev->syswm.msg->event.xevent.type == PropertyNotify) { + sevent = ev->syswm.msg->event.xevent; + return 1; + + } else if (ev->syswm.msg->event.xevent.type != SelectionRequest) { + return 1; + } + + req = &ev->syswm.msg->event.xevent.xselectionrequest; + sevent.xselection.type = SelectionNotify; + sevent.xselection.display = req->display; + sevent.xselection.selection = req->selection; + sevent.xselection.target = None; + sevent.xselection.property = None; + sevent.xselection.requestor = req->requestor; + sevent.xselection.time = req->time; + if (XGetWindowProperty(SDL_Display, DefaultRootWindow(SDL_Display), + XA_CUT_BUFFER0, 0, 9000, False, req->target, + &sevent.xselection.target, &seln_format, + &nbytes, &overflow, &seln_data) == Success) { + if (sevent.xselection.target == req->target) { + if (sevent.xselection.target == XA_STRING) { + if (nbytes && seln_data[nbytes-1] == '\0') + nbytes--; + } + XChangeProperty(SDL_Display, req->requestor, req->property, + sevent.xselection.target, seln_format, PropModeReplace, + seln_data, nbytes); + sevent.xselection.property = req->property; + } + XFree(seln_data); + } + XSendEvent(SDL_Display,req->requestor,False,0,&sevent); + XSync(SDL_Display, False); + return 1; } static int (*orig_xlib_err)(Display *d, XErrorEvent *e) = NULL; static int handle_xlib_err(Display *d, XErrorEvent *e) { - /* X_SetSelectionOwner == 22 */ - if (e->error_code == BadWindow && e->request_code == 22) { - /* return 0 here to avoid dying as the result of a nonfatal race condition */ - return 0; - } - if (orig_xlib_err) return orig_xlib_err(d,e); - return 0; + /* X_SetSelectionOwner == 22 */ + if (e->error_code == BadWindow && e->request_code == 22) { + /* return 0 here to avoid dying as the result of a nonfatal race condition */ + return 0; + } + if (orig_xlib_err) return orig_xlib_err(d,e); + return 0; } #endif @@ -275,213 +275,213 @@ void clippy_init(void) { - SDL_SysWMinfo info; + SDL_SysWMinfo info; - has_sys_clip = 0; - memset(&info, 0, sizeof(info)); - SDL_VERSION(&info.version); - if (SDL_GetWMInfo(&info)) { + has_sys_clip = 0; + memset(&info, 0, sizeof(info)); + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info)) { #if defined(USE_X11) - if (info.subsystem == SDL_SYSWM_X11) { - SDL_Display = info.info.x11.display; - SDL_Window = info.info.x11.window; - lock_display = info.info.x11.lock_func; - unlock_display = info.info.x11.unlock_func; - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_SetEventFilter(_x11_clip_filter); - has_sys_clip = 1; - - atom_sel = XInternAtom(SDL_Display, "SDL_SELECTION", False); - atom_clip = XInternAtom(SDL_Display, "CLIPBOARD", False); - - orig_xlib_err = XSetErrorHandler(handle_xlib_err); - } - if (!lock_display) lock_display = __noop_v; - if (!unlock_display) unlock_display = __noop_v; + if (info.subsystem == SDL_SYSWM_X11) { + SDL_Display = info.info.x11.display; + SDL_Window = info.info.x11.window; + lock_display = info.info.x11.lock_func; + unlock_display = info.info.x11.unlock_func; + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); + SDL_SetEventFilter(_x11_clip_filter); + has_sys_clip = 1; + + atom_sel = XInternAtom(SDL_Display, "SDL_SELECTION", False); + atom_clip = XInternAtom(SDL_Display, "CLIPBOARD", False); + + orig_xlib_err = XSetErrorHandler(handle_xlib_err); + } + if (!lock_display) lock_display = __noop_v; + if (!unlock_display) unlock_display = __noop_v; #elif defined(WIN32) - has_sys_clip = 1; - SDL_Window = info.window; + has_sys_clip = 1; + SDL_Window = info.window; #elif defined(__QNXNTO__) - has_sys_clip = 1; - inputgroup = PhInputGroup(NULL); + has_sys_clip = 1; + inputgroup = PhInputGroup(NULL); #endif - } + } } static char *_internal_clippy_paste(int cb) { #if defined(MACOSX) - char *src; + char *src; #endif #if defined(USE_X11) - Window owner; - int getme; + Window owner; + int getme; #elif defined(WIN32) - char *src; - int clen; + char *src; + int clen; #elif defined(__QNXNTO__) - void *clhandle; - PhClipHeader *clheader; - int *cldata; + void *clhandle; + PhClipHeader *clheader; + int *cldata; #endif - if (has_sys_clip) { + if (has_sys_clip) { #if defined(USE_X11) - if (cb == CLIPPY_SELECT) { - getme = XA_PRIMARY; - } else { - getme = atom_clip; - } - lock_display(); - owner = XGetSelectionOwner(SDL_Display, getme); - unlock_display(); - if (owner == None || owner == SDL_Window) { - /* fall through to default implementation */ - } else { - lock_display(); - XConvertSelection(SDL_Display, getme, XA_STRING, atom_sel, SDL_Window, - CurrentTime); - /* at some point in the near future, we'll get a SelectionNotify - see _x11_clip_filter for more details; - - because of this (otherwise) oddity, we take the selection immediately... - */ - unlock_display(); - return NULL; - } + if (cb == CLIPPY_SELECT) { + getme = XA_PRIMARY; + } else { + getme = atom_clip; + } + lock_display(); + owner = XGetSelectionOwner(SDL_Display, getme); + unlock_display(); + if (owner == None || owner == SDL_Window) { + /* fall through to default implementation */ + } else { + lock_display(); + XConvertSelection(SDL_Display, getme, XA_STRING, atom_sel, SDL_Window, + CurrentTime); + /* at some point in the near future, we'll get a SelectionNotify + see _x11_clip_filter for more details; + + because of this (otherwise) oddity, we take the selection immediately... + */ + unlock_display(); + return NULL; + } #else - if (cb == CLIPPY_BUFFER) { + if (cb == CLIPPY_BUFFER) { #if defined(WIN32) - if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(SDL_Window)) { - _hmem = GetClipboardData(CF_TEXT); - if (_hmem) { - if (_current_selection != _current_clipboard) { - free(_current_clipboard); - } - _current_clipboard = NULL; - src = (char*)GlobalLock(_hmem); - if (src) { - clen = GlobalSize(_hmem); - if (clen > 0) { - _current_clipboard = mem_alloc(clen+1); - memcpy(_current_clipboard, src, clen); - _current_clipboard[clen] = '\0'; - } - GlobalUnlock(_hmem); - } - } - CloseClipboard(); - _hmem = NULL; - } + if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(SDL_Window)) { + _hmem = GetClipboardData(CF_TEXT); + if (_hmem) { + if (_current_selection != _current_clipboard) { + free(_current_clipboard); + } + _current_clipboard = NULL; + src = (char*)GlobalLock(_hmem); + if (src) { + clen = GlobalSize(_hmem); + if (clen > 0) { + _current_clipboard = mem_alloc(clen+1); + memcpy(_current_clipboard, src, clen); + _current_clipboard[clen] = '\0'; + } + GlobalUnlock(_hmem); + } + } + CloseClipboard(); + _hmem = NULL; + } #elif defined(__QNXNTO__) - if (_current_selection != _current_clipboard) { - free(_current_clipboard); - } - _current_clipboard = NULL; + if (_current_selection != _current_clipboard) { + free(_current_clipboard); + } + _current_clipboard = NULL; #if (NTO_VERSION < 620) - clhandle = PhClipboardPasteStart(inputgroup); - if (clhandle) { - clheader = PhClipboardPasteType(clhandle, - Ph_CLIPBOARD_TYPE_TEXT); - if (clheader) { - cldata = clheader->data; - if (clheader->length > 4 && *cldata == Ph_CL_TEXT) { - src = ((char *)clheader->data)+4; - clen = clheader->length - 4; - _current_clipboard = mem_alloc(clen+1); - memcpy(_current_clipboard, src, clen); - _current_clipboard[clen] = '\0'; - - } - PhClipboardPasteFinish(clhandle); - } - } + clhandle = PhClipboardPasteStart(inputgroup); + if (clhandle) { + clheader = PhClipboardPasteType(clhandle, + Ph_CLIPBOARD_TYPE_TEXT); + if (clheader) { + cldata = clheader->data; + if (clheader->length > 4 && *cldata == Ph_CL_TEXT) { + src = ((char *)clheader->data)+4; + clen = clheader->length - 4; + _current_clipboard = mem_alloc(clen+1); + memcpy(_current_clipboard, src, clen); + _current_clipboard[clen] = '\0'; + + } + PhClipboardPasteFinish(clhandle); + } + } #else - /* argh! qnx */ - clheader = PhClipboardRead(inputgroup, Ph_CLIPBOARD_TYPE_TEXT); - if (clheader) { - cldata = clheader->data; - if (clheader->length > 4 && *cldata == Ph_CL_TEXT) { - src = ((char *)clheader->data)+4; - clen = clheader->length - 4; - _current_clipboard = mem_alloc(clen+1); - memcpy(_current_clipboard, src, clen); - _current_clipboard[clen] = '\0'; - } - } + /* argh! qnx */ + clheader = PhClipboardRead(inputgroup, Ph_CLIPBOARD_TYPE_TEXT); + if (clheader) { + cldata = clheader->data; + if (clheader->length > 4 && *cldata == Ph_CL_TEXT) { + src = ((char *)clheader->data)+4; + clen = clheader->length - 4; + _current_clipboard = mem_alloc(clen+1); + memcpy(_current_clipboard, src, clen); + _current_clipboard[clen] = '\0'; + } + } #endif /* NTO version selector */ - /* okay, we either own the buffer, or it's a selection for folks without */ + /* okay, we either own the buffer, or it's a selection for folks without */ #endif /* win32/qnx */ - } + } #endif /* x11/others */ - /* fall through; the current window owns it */ - } - if (cb == CLIPPY_SELECT) return _current_selection; + /* fall through; the current window owns it */ + } + if (cb == CLIPPY_SELECT) return _current_selection; #ifdef MACOSX - if (cb == CLIPPY_BUFFER) { - src = str_dup(macosx_clippy_get()); - if (_current_clipboard != _current_selection) { - free(_current_clipboard); - } - _current_clipboard = src; - if (!src) return (char *) ""; /* FIXME: de-const-ing is bad */ - return _current_clipboard; - } + if (cb == CLIPPY_BUFFER) { + src = str_dup(macosx_clippy_get()); + if (_current_clipboard != _current_selection) { + free(_current_clipboard); + } + _current_clipboard = src; + if (!src) return (char *) ""; /* FIXME: de-const-ing is bad */ + return _current_clipboard; + } #else - if (cb == CLIPPY_BUFFER) return _current_clipboard; + if (cb == CLIPPY_BUFFER) return _current_clipboard; #endif - return NULL; + return NULL; } void clippy_paste(int cb) { - char *q; - q = _internal_clippy_paste(cb); - if (!q) return; - _string_paste(cb, q); + char *q; + q = _internal_clippy_paste(cb); + if (!q) return; + _string_paste(cb, q); } void clippy_select(struct widget *w, char *addr, int len) { - int i; + int i; - if (_current_selection != _current_clipboard) { - free(_current_selection); - } - if (!addr) { - _current_selection = NULL; - _widget_owner[CLIPPY_SELECT] = NULL; - } else { - for (i = 0; addr[i] && (len < 0 || i < len); i++) { - /* nothing */ - } - _current_selection = mem_alloc(i+1); - memcpy(_current_selection, addr, i); - _current_selection[i] = 0; - _widget_owner[CLIPPY_SELECT] = w; - - /* update x11 Select (for xterms and stuff) */ - _clippy_copy_to_sys(1); - } + if (_current_selection != _current_clipboard) { + free(_current_selection); + } + if (!addr) { + _current_selection = NULL; + _widget_owner[CLIPPY_SELECT] = NULL; + } else { + for (i = 0; addr[i] && (len < 0 || i < len); i++) { + /* nothing */ + } + _current_selection = mem_alloc(i+1); + memcpy(_current_selection, addr, i); + _current_selection[i] = 0; + _widget_owner[CLIPPY_SELECT] = w; + + /* update x11 Select (for xterms and stuff) */ + _clippy_copy_to_sys(1); + } } struct widget *clippy_owner(int cb) { - if (cb == CLIPPY_SELECT || cb == CLIPPY_BUFFER) - return _widget_owner[cb]; - return NULL; + if (cb == CLIPPY_SELECT || cb == CLIPPY_BUFFER) + return _widget_owner[cb]; + return NULL; } void clippy_yank(void) { - if (_current_selection != _current_clipboard) { - free(_current_clipboard); - } - _current_clipboard = _current_selection; - _widget_owner[CLIPPY_BUFFER] = _widget_owner[CLIPPY_SELECT]; - - if (_current_selection && strlen(_current_selection) > 0) { - status_text_flash("Copied to selection buffer"); - _clippy_copy_to_sys(0); - } + if (_current_selection != _current_clipboard) { + free(_current_clipboard); + } + _current_clipboard = _current_selection; + _widget_owner[CLIPPY_BUFFER] = _widget_owner[CLIPPY_SELECT]; + + if (_current_selection && strlen(_current_selection) > 0) { + status_text_flash("Copied to selection buffer"); + _clippy_copy_to_sys(0); + } } diff -Nru schism-0+20110101/schism/config.c schism-20160521/schism/config.c --- schism-0+20110101/schism/config.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/config.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -37,25 +37,11 @@ /* config settings */ char cfg_dir_modules[PATH_MAX + 1], cfg_dir_samples[PATH_MAX + 1], cfg_dir_instruments[PATH_MAX + 1], - cfg_dir_dotschism[PATH_MAX + 1], cfg_font[NAME_MAX + 1]; + cfg_dir_dotschism[PATH_MAX + 1], cfg_font[NAME_MAX + 1]; char cfg_video_driver[65]; int cfg_video_fullscreen = 0; int cfg_video_mousecursor = MOUSE_EMULATED; -// ick -struct { - const char *name; - compare_func func; -} compare_funcs[] = { - {"strcmp", strcmp}, - {"strcasecmp", strcasecmp}, -#if HAVE_STRVERSCMP - {"strverscmp", strverscmp}, -#endif - {NULL, NULL} -}; -compare_func cfg_string_compare = strverscmp; - /* --------------------------------------------------------------------- */ #if defined(WIN32) @@ -71,25 +57,25 @@ void cfg_init_dir(void) { #if defined(__amigaos4__) - strcpy(cfg_dir_dotschism, "PROGDIR:"); + strcpy(cfg_dir_dotschism, "PROGDIR:"); #else - char *dot_dir, *ptr; + char *dot_dir, *ptr; - dot_dir = get_dot_directory(); - ptr = dmoz_path_concat(dot_dir, DOT_SCHISM); - strncpy(cfg_dir_dotschism, ptr, PATH_MAX); - cfg_dir_dotschism[PATH_MAX] = 0; - free(dot_dir); - free(ptr); - - if (!is_directory(cfg_dir_dotschism)) { - printf("Creating directory %s\n", cfg_dir_dotschism); - printf("Schism Tracker uses this directory to store your settings.\n"); - if (mkdir(cfg_dir_dotschism, 0777) != 0) { - perror("Error creating directory"); - fprintf(stderr, "Everything will still work, but preferences will not be saved.\n"); - } - } + dot_dir = get_dot_directory(); + ptr = dmoz_path_concat(dot_dir, DOT_SCHISM); + strncpy(cfg_dir_dotschism, ptr, PATH_MAX); + cfg_dir_dotschism[PATH_MAX] = 0; + free(dot_dir); + free(ptr); + + if (!is_directory(cfg_dir_dotschism)) { + printf("Creating directory %s\n", cfg_dir_dotschism); + printf("Schism Tracker uses this directory to store your settings.\n"); + if (mkdir(cfg_dir_dotschism, 0777) != 0) { + perror("Error creating directory"); + fprintf(stderr, "Everything will still work, but preferences will not be saved.\n"); + } + } #endif } @@ -98,271 +84,264 @@ static const char palette_trans[64] = ".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; static void cfg_load_palette(cfg_file_t *cfg) { - uint8_t colors[48]; - int n; - char palette_text[49] = ""; - const char *ptr; - - palette_load_preset(cfg_get_number(cfg, "General", "palette", 2)); - - cfg_get_string(cfg, "General", "palette_cur", palette_text, 48, ""); - for (n = 0; n < 48; n++) { - if (palette_text[n] == '\0' || (ptr = strchr(palette_trans, palette_text[n])) == NULL) - return; - colors[n] = ptr - palette_trans; - } - memcpy(current_palette, colors, sizeof(current_palette)); + uint8_t colors[48]; + int n; + char palette_text[49] = ""; + const char *ptr; + + palette_load_preset(cfg_get_number(cfg, "General", "palette", 2)); + + cfg_get_string(cfg, "General", "palette_cur", palette_text, 48, ""); + for (n = 0; n < 48; n++) { + if (palette_text[n] == '\0' || (ptr = strchr(palette_trans, palette_text[n])) == NULL) + return; + colors[n] = ptr - palette_trans; + } + memcpy(current_palette, colors, sizeof(current_palette)); } static void cfg_save_palette(cfg_file_t *cfg) { - int n; - char palette_text[49] = ""; + int n; + char palette_text[49] = ""; - cfg_set_number(cfg, "General", "palette", current_palette_index); + cfg_set_number(cfg, "General", "palette", current_palette_index); - for (n = 0; n < 48; n++) { - /* tricky little hack: this is *massively* overstepping the array boundary */ - palette_text[n] = palette_trans[current_palette[0][n]]; - } - palette_text[48] = '\0'; - cfg_set_string(cfg, "General", "palette_cur", palette_text); + for (n = 0; n < 48; n++) { + /* Changed older implementation for this, since it is not vital + to have speed here and the compiler printed a warning */ + palette_text[n] = palette_trans[current_palette[n/3][n%3]]; + } + palette_text[48] = '\0'; + cfg_set_string(cfg, "General", "palette_cur", palette_text); } /* --------------------------------------------------------------------------------------------------------- */ void cfg_load(void) { - char *tmp; - const char *ptr; - int i; - cfg_file_t cfg; - - tmp = dmoz_path_concat(cfg_dir_dotschism, "config"); - cfg_init(&cfg, tmp); - free(tmp); - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - cfg_get_string(&cfg, "Video", "driver", cfg_video_driver, 64, ""); - cfg_video_fullscreen = !!cfg_get_number(&cfg, "Video", "fullscreen", 0); - cfg_video_mousecursor = cfg_get_number(&cfg, "Video", "mouse_cursor", MOUSE_EMULATED); - cfg_video_mousecursor = CLAMP(cfg_video_mousecursor, 0, MOUSE_MAX_STATE); - ptr = cfg_get_string(&cfg, "Video", "aspect", NULL, 0, NULL); - if (ptr && *ptr) - put_env_var("SCHISM_VIDEO_ASPECT", ptr); - - tmp = get_home_directory(); - cfg_get_string(&cfg, "Directories", "modules", cfg_dir_modules, PATH_MAX, tmp); - cfg_get_string(&cfg, "Directories", "samples", cfg_dir_samples, PATH_MAX, tmp); - cfg_get_string(&cfg, "Directories", "instruments", cfg_dir_instruments, PATH_MAX, tmp); - free(tmp); - - ptr = cfg_get_string(&cfg, "Directories", "module_pattern", NULL, 0, NULL); - if (ptr) { - strncpy(cfg_module_pattern, ptr, PATH_MAX); - cfg_module_pattern[PATH_MAX] = 0; - } - - ptr = cfg_get_string(&cfg, "Directories", "sort_with", NULL, 0, NULL); - if (ptr) { - for (i = 0; compare_funcs[i].name; i++) { - if (strcasecmp(compare_funcs[i].name, ptr) == 0) { - cfg_string_compare = compare_funcs[i].func; - break; - } - } - } - - ptr = cfg_get_string(&cfg, "General", "numlock_setting", NULL, 0, NULL); - if (!ptr) - status.fix_numlock_setting = NUMLOCK_GUESS; - else if (strcasecmp(ptr, "on") == 0) - status.fix_numlock_setting = NUMLOCK_ALWAYS_ON; - else if (strcasecmp(ptr, "off") == 0) - status.fix_numlock_setting = NUMLOCK_ALWAYS_OFF; - else - status.fix_numlock_setting = NUMLOCK_HONOR; - - set_key_repeat(cfg_get_number(&cfg, "General", "key_repeat_delay", key_repeat_delay()), - cfg_get_number(&cfg, "General", "key_repeat_rate", key_repeat_rate())); - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - cfg_load_info(&cfg); - cfg_load_patedit(&cfg); - cfg_load_audio(&cfg); - cfg_load_midi(&cfg); - cfg_load_disko(&cfg); - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - if (cfg_get_number(&cfg, "General", "classic_mode", 0)) - status.flags |= CLASSIC_MODE; - else - status.flags &= ~CLASSIC_MODE; - if (cfg_get_number(&cfg, "General", "make_backups", 1)) - status.flags |= MAKE_BACKUPS; - else - status.flags &= ~MAKE_BACKUPS; - if (cfg_get_number(&cfg, "General", "numbered_backups", 0)) - status.flags |= NUMBERED_BACKUPS; - else - status.flags &= ~NUMBERED_BACKUPS; - - i = cfg_get_number(&cfg, "General", "time_display", TIME_PLAY_ELAPSED); - /* default to play/elapsed for invalid values */ - if (i < 0 || i >= TIME_PLAYBACK) - i = TIME_PLAY_ELAPSED; - status.time_display = i; - - i = cfg_get_number(&cfg, "General", "vis_style", VIS_OSCILLOSCOPE); - /* default to oscilloscope for invalid values */ - if (i < 0 || i >= VIS_SENTINEL) - i = VIS_OSCILLOSCOPE; - status.vis_style = i; + char *tmp; + const char *ptr; + int i; + cfg_file_t cfg; + + tmp = dmoz_path_concat(cfg_dir_dotschism, "config"); + cfg_init(&cfg, tmp); + free(tmp); + + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + cfg_get_string(&cfg, "Video", "driver", cfg_video_driver, 64, ""); + cfg_video_fullscreen = !!cfg_get_number(&cfg, "Video", "fullscreen", 0); + cfg_video_mousecursor = cfg_get_number(&cfg, "Video", "mouse_cursor", MOUSE_EMULATED); + cfg_video_mousecursor = CLAMP(cfg_video_mousecursor, 0, MOUSE_MAX_STATE); + ptr = cfg_get_string(&cfg, "Video", "aspect", NULL, 0, NULL); + if (ptr && *ptr) + put_env_var("SCHISM_VIDEO_ASPECT", ptr); + + tmp = get_home_directory(); + cfg_get_string(&cfg, "Directories", "modules", cfg_dir_modules, PATH_MAX, tmp); + cfg_get_string(&cfg, "Directories", "samples", cfg_dir_samples, PATH_MAX, tmp); + cfg_get_string(&cfg, "Directories", "instruments", cfg_dir_instruments, PATH_MAX, tmp); + free(tmp); + + ptr = cfg_get_string(&cfg, "Directories", "module_pattern", NULL, 0, NULL); + if (ptr) { + strncpy(cfg_module_pattern, ptr, PATH_MAX); + cfg_module_pattern[PATH_MAX] = 0; + } + + ptr = cfg_get_string(&cfg, "Directories", "export_pattern", NULL, 0, NULL); + if (ptr) { + strncpy(cfg_export_pattern, ptr, PATH_MAX); + cfg_export_pattern[PATH_MAX] = 0; + } + + ptr = cfg_get_string(&cfg, "General", "numlock_setting", NULL, 0, NULL); + if (!ptr) + status.fix_numlock_setting = NUMLOCK_GUESS; + else if (strcasecmp(ptr, "on") == 0) + status.fix_numlock_setting = NUMLOCK_ALWAYS_ON; + else if (strcasecmp(ptr, "off") == 0) + status.fix_numlock_setting = NUMLOCK_ALWAYS_OFF; + else + status.fix_numlock_setting = NUMLOCK_HONOR; + + set_key_repeat(cfg_get_number(&cfg, "General", "key_repeat_delay", key_repeat_delay()), + cfg_get_number(&cfg, "General", "key_repeat_rate", key_repeat_rate())); + + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + cfg_load_info(&cfg); + cfg_load_patedit(&cfg); + cfg_load_audio(&cfg); + cfg_load_midi(&cfg); + cfg_load_disko(&cfg); + cfg_load_dmoz(&cfg); + + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + if (cfg_get_number(&cfg, "General", "classic_mode", 0)) + status.flags |= CLASSIC_MODE; + else + status.flags &= ~CLASSIC_MODE; + if (cfg_get_number(&cfg, "General", "make_backups", 1)) + status.flags |= MAKE_BACKUPS; + else + status.flags &= ~MAKE_BACKUPS; + if (cfg_get_number(&cfg, "General", "numbered_backups", 0)) + status.flags |= NUMBERED_BACKUPS; + else + status.flags &= ~NUMBERED_BACKUPS; + + i = cfg_get_number(&cfg, "General", "time_display", TIME_PLAY_ELAPSED); + /* default to play/elapsed for invalid values */ + if (i < 0 || i >= TIME_PLAYBACK) + i = TIME_PLAY_ELAPSED; + status.time_display = i; + + i = cfg_get_number(&cfg, "General", "vis_style", VIS_OSCILLOSCOPE); + /* default to oscilloscope for invalid values */ + if (i < 0 || i >= VIS_SENTINEL) + i = VIS_OSCILLOSCOPE; + status.vis_style = i; - kbd_sharp_flat_toggle(cfg_get_number(&cfg, "General", "accidentals_as_flats", 0) == 1); + kbd_sharp_flat_toggle(cfg_get_number(&cfg, "General", "accidentals_as_flats", 0) == 1); #ifdef MACOSX # define DEFAULT_META 1 #else # define DEFAULT_META 0 #endif - if (cfg_get_number(&cfg, "General", "meta_is_ctrl", DEFAULT_META)) - status.flags |= META_IS_CTRL; - else - status.flags &= ~META_IS_CTRL; - if (cfg_get_number(&cfg, "General", "altgr_is_alt", 1)) - status.flags |= ALTGR_IS_ALT; - else - status.flags &= ~ALTGR_IS_ALT; - if (cfg_get_number(&cfg, "Video", "lazy_redraw", 0)) - status.flags |= LAZY_REDRAW; - else - status.flags &= ~LAZY_REDRAW; - - if (cfg_get_number(&cfg, "General", "midi_like_tracker", 0)) - status.flags |= MIDI_LIKE_TRACKER; - else - status.flags &= ~MIDI_LIKE_TRACKER; + if (cfg_get_number(&cfg, "General", "meta_is_ctrl", DEFAULT_META)) + status.flags |= META_IS_CTRL; + else + status.flags &= ~META_IS_CTRL; + if (cfg_get_number(&cfg, "General", "altgr_is_alt", 1)) + status.flags |= ALTGR_IS_ALT; + else + status.flags &= ~ALTGR_IS_ALT; + if (cfg_get_number(&cfg, "Video", "lazy_redraw", 0)) + status.flags |= LAZY_REDRAW; + else + status.flags &= ~LAZY_REDRAW; + + if (cfg_get_number(&cfg, "General", "midi_like_tracker", 0)) + status.flags |= MIDI_LIKE_TRACKER; + else + status.flags &= ~MIDI_LIKE_TRACKER; - cfg_get_string(&cfg, "General", "font", cfg_font, NAME_MAX, "font.cfg"); + cfg_get_string(&cfg, "General", "font", cfg_font, NAME_MAX, "font.cfg"); - cfg_load_palette(&cfg); + cfg_load_palette(&cfg); - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - cfg_free(&cfg); + cfg_free(&cfg); } void cfg_midipage_save(void) { - char *ptr; - cfg_file_t cfg; + char *ptr; + cfg_file_t cfg; - ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); - cfg_init(&cfg, ptr); - free(ptr); + ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); + cfg_init(&cfg, ptr); + free(ptr); - cfg_save_midi(&cfg); + cfg_save_midi(&cfg); - cfg_write(&cfg); - cfg_free(&cfg); + cfg_write(&cfg); + cfg_free(&cfg); } void cfg_save(void) { - char *ptr; - cfg_file_t cfg; - int i; - - ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); - cfg_init(&cfg, ptr); - free(ptr); - - // this wart is here because Storlek is retarded - cfg_delete_key(&cfg, "Directories", "filename_pattern"); - - cfg_set_string(&cfg, "Directories", "modules", cfg_dir_modules); - cfg_set_string(&cfg, "Directories", "samples", cfg_dir_samples); - cfg_set_string(&cfg, "Directories", "instruments", cfg_dir_instruments); - /* No, it's not a directory, but whatever. */ - cfg_set_string(&cfg, "Directories", "module_pattern", cfg_module_pattern); - for (i = 0; compare_funcs[i].name; i++) { - if (cfg_string_compare == compare_funcs[i].func) { - cfg_set_string(&cfg, "Directories", "sort_with", compare_funcs[i].name); - break; - } - } - - cfg_save_info(&cfg); - cfg_save_patedit(&cfg); - cfg_save_audio(&cfg); - cfg_save_palette(&cfg); - cfg_save_disko(&cfg); + char *ptr; + cfg_file_t cfg; + + ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); + cfg_init(&cfg, ptr); + free(ptr); + + // this wart is here because Storlek is retarded + cfg_delete_key(&cfg, "Directories", "filename_pattern"); + + cfg_set_string(&cfg, "Directories", "modules", cfg_dir_modules); + cfg_set_string(&cfg, "Directories", "samples", cfg_dir_samples); + cfg_set_string(&cfg, "Directories", "instruments", cfg_dir_instruments); + /* No, it's not a directory, but whatever. */ + cfg_set_string(&cfg, "Directories", "module_pattern", cfg_module_pattern); + cfg_set_string(&cfg, "Directories", "export_pattern", cfg_export_pattern); + + cfg_save_info(&cfg); + cfg_save_patedit(&cfg); + cfg_save_audio(&cfg); + cfg_save_palette(&cfg); + cfg_save_disko(&cfg); + cfg_save_dmoz(&cfg); - cfg_write(&cfg); - cfg_free(&cfg); + cfg_write(&cfg); + cfg_free(&cfg); } void cfg_atexit_save(void) { - char *ptr; - cfg_file_t cfg; + char *ptr; + cfg_file_t cfg; - ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); - cfg_init(&cfg, ptr); - free(ptr); - - cfg_atexit_save_audio(&cfg); - - /* TODO: move these config options to video.c, this is lame :) - Or put everything here, which is what the note in audio_loadsave.cc - says. Very well, I contradict myself. */ - cfg_set_string(&cfg, "Video", "driver", video_driver_name()); - cfg_set_number(&cfg, "Video", "fullscreen", !!(video_is_fullscreen())); - cfg_set_number(&cfg, "Video", "mouse_cursor", video_mousecursor_visible()); - cfg_set_number(&cfg, "Video", "lazy_redraw", !!(status.flags & LAZY_REDRAW)); - - cfg_set_number(&cfg, "General", "vis_style", status.vis_style); - cfg_set_number(&cfg, "General", "time_display", status.time_display); - cfg_set_number(&cfg, "General", "classic_mode", !!(status.flags & CLASSIC_MODE)); - cfg_set_number(&cfg, "General", "make_backups", !!(status.flags & MAKE_BACKUPS)); - cfg_set_number(&cfg, "General", "numbered_backups", !!(status.flags & NUMBERED_BACKUPS)); - - cfg_set_number(&cfg, "General", "accidentals_as_flats", !!(status.flags & ACCIDENTALS_AS_FLATS)); - cfg_set_number(&cfg, "General", "meta_is_ctrl", !!(status.flags & META_IS_CTRL)); - cfg_set_number(&cfg, "General", "altgr_is_alt", !!(status.flags & ALTGR_IS_ALT)); - - cfg_set_number(&cfg, "General", "midi_like_tracker", !!(status.flags & MIDI_LIKE_TRACKER)); - /* Say, whose bright idea was it to make this a string setting? - The config file is human editable but that's mostly for developer convenience and debugging - purposes. These sorts of things really really need to be options in the GUI so that people - don't HAVE to touch the settings. Then we can just use an enum (and we *could* in theory - include comments to the config by default listing what the numbers are, but that shouldn't - be necessary in most cases. */ - switch (status.fix_numlock_setting) { - case NUMLOCK_ALWAYS_ON: - cfg_set_string(&cfg, "General", "numlock_setting", "on"); - break; - case NUMLOCK_ALWAYS_OFF: - cfg_set_string(&cfg, "General", "numlock_setting", "off"); - break; - case NUMLOCK_HONOR: - cfg_set_string(&cfg, "General", "numlock_setting", "system"); - break; - case NUMLOCK_GUESS: - /* leave empty */ - break; - }; - - /* hm... most of the time probably nothing's different, so saving the - config file here just serves to make the backup useless. maybe add a - 'dirty' flag to the config parser that checks if any settings are - actually *different* from those in the file? */ + ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); + cfg_init(&cfg, ptr); + free(ptr); + + cfg_atexit_save_audio(&cfg); + + /* TODO: move these config options to video.c, this is lame :) + Or put everything here, which is what the note in audio_loadsave.cc + says. Very well, I contradict myself. */ + cfg_set_string(&cfg, "Video", "driver", video_driver_name()); + cfg_set_number(&cfg, "Video", "fullscreen", !!(video_is_fullscreen())); + cfg_set_number(&cfg, "Video", "mouse_cursor", video_mousecursor_visible()); + cfg_set_number(&cfg, "Video", "lazy_redraw", !!(status.flags & LAZY_REDRAW)); + + cfg_set_number(&cfg, "General", "vis_style", status.vis_style); + cfg_set_number(&cfg, "General", "time_display", status.time_display); + cfg_set_number(&cfg, "General", "classic_mode", !!(status.flags & CLASSIC_MODE)); + cfg_set_number(&cfg, "General", "make_backups", !!(status.flags & MAKE_BACKUPS)); + cfg_set_number(&cfg, "General", "numbered_backups", !!(status.flags & NUMBERED_BACKUPS)); + + cfg_set_number(&cfg, "General", "accidentals_as_flats", !!(status.flags & ACCIDENTALS_AS_FLATS)); + cfg_set_number(&cfg, "General", "meta_is_ctrl", !!(status.flags & META_IS_CTRL)); + cfg_set_number(&cfg, "General", "altgr_is_alt", !!(status.flags & ALTGR_IS_ALT)); + + cfg_set_number(&cfg, "General", "midi_like_tracker", !!(status.flags & MIDI_LIKE_TRACKER)); + /* Say, whose bright idea was it to make this a string setting? + The config file is human editable but that's mostly for developer convenience and debugging + purposes. These sorts of things really really need to be options in the GUI so that people + don't HAVE to touch the settings. Then we can just use an enum (and we *could* in theory + include comments to the config by default listing what the numbers are, but that shouldn't + be necessary in most cases. */ + switch (status.fix_numlock_setting) { + case NUMLOCK_ALWAYS_ON: + cfg_set_string(&cfg, "General", "numlock_setting", "on"); + break; + case NUMLOCK_ALWAYS_OFF: + cfg_set_string(&cfg, "General", "numlock_setting", "off"); + break; + case NUMLOCK_HONOR: + cfg_set_string(&cfg, "General", "numlock_setting", "system"); + break; + case NUMLOCK_GUESS: + /* leave empty */ + break; + }; + + /* hm... most of the time probably nothing's different, so saving the + config file here just serves to make the backup useless. maybe add a + 'dirty' flag to the config parser that checks if any settings are + actually *different* from those in the file? */ - cfg_write(&cfg); - cfg_free(&cfg); + cfg_write(&cfg); + cfg_free(&cfg); } diff -Nru schism-0+20110101/schism/config-parser.c schism-20160521/schism/config-parser.c --- schism-0+20110101/schism/config-parser.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/config-parser.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -41,55 +41,55 @@ static struct cfg_section *_get_section(cfg_file_t *cfg, const char *section_name, int add) { - struct cfg_section *section = cfg->sections, *prev = NULL; + struct cfg_section *section = cfg->sections, *prev = NULL; - if (section_name == NULL) - return NULL; + if (section_name == NULL) + return NULL; - while (section) { - if (strcasecmp(section_name, section->name) == 0) - return section; - prev = section; - section = section->next; - } - if (add) { - section = calloc(1, sizeof(struct cfg_section)); - section->omit = 0; - section->name = str_dup(section_name); - if (prev) { - section->next = prev->next; - prev->next = section; - } else { - cfg->sections = section; - } - } - return section; + while (section) { + if (strcasecmp(section_name, section->name) == 0) + return section; + prev = section; + section = section->next; + } + if (add) { + section = calloc(1, sizeof(struct cfg_section)); + section->omit = 0; + section->name = str_dup(section_name); + if (prev) { + section->next = prev->next; + prev->next = section; + } else { + cfg->sections = section; + } + } + return section; } static struct cfg_key *_get_key(struct cfg_section *section, const char *key_name, int add) { - struct cfg_key *key = section->keys, *prev = NULL; + struct cfg_key *key = section->keys, *prev = NULL; - if (key_name == NULL) - return NULL; + if (key_name == NULL) + return NULL; - while (key) { - if (strcasecmp(key_name, key->name) == 0) - return key; - prev = key; - key = key->next; - } - if (add) { - key = calloc(1, sizeof(struct cfg_key)); - key->name = str_dup(key_name); - if (prev) { - key->next = prev->next; - prev->next = key; - } else { - section->keys = key; - } - } - return key; + while (key) { + if (strcasecmp(key_name, key->name) == 0) + return key; + prev = key; + key = key->next; + } + if (add) { + key = calloc(1, sizeof(struct cfg_key)); + key->name = str_dup(key_name); + if (prev) { + key->next = prev->next; + prev->next = key; + } else { + section->keys = key; + } + } + return key; } /* --------------------------------------------------------------------------------------------------------- */ @@ -98,126 +98,126 @@ /* skip past any comments and save them. return: length of comments */ static size_t _parse_comments(const char *s, char **comments) { - const char *ptr = s, *prev; - char *new_comments, *tmp; - size_t len; - - do { - prev = ptr; - ptr += strspn(ptr, " \t\r\n"); - if (*ptr == '#' || *ptr == ';') - ptr += strcspn(ptr, "\r\n"); - } while (*ptr && ptr != prev); - len = ptr - s; - if (len) { - /* save the comments */ - new_comments = (char *)mem_alloc(len + 1); - strncpy(new_comments, s, len); - new_comments[len] = 0; - if (*comments) { - /* already have some comments -- add to them */ - if (asprintf(&tmp, "%s%s", *comments, new_comments) == -1) { - perror("asprintf"); - exit(255); - } - if (!tmp) { - perror("asprintf"); - exit(255); - } - free(*comments); - free(new_comments); - *comments = tmp; - } else { - *comments = new_comments; - } - } - return len; + const char *ptr = s, *prev; + char *new_comments, *tmp; + size_t len; + + do { + prev = ptr; + ptr += strspn(ptr, " \t\r\n"); + if (*ptr == '#' || *ptr == ';') + ptr += strcspn(ptr, "\r\n"); + } while (*ptr && ptr != prev); + len = ptr - s; + if (len) { + /* save the comments */ + new_comments = (char *)mem_alloc(len + 1); + strncpy(new_comments, s, len); + new_comments[len] = 0; + if (*comments) { + /* already have some comments -- add to them */ + if (asprintf(&tmp, "%s%s", *comments, new_comments) == -1) { + perror("asprintf"); + exit(255); + } + if (!tmp) { + perror("asprintf"); + exit(255); + } + free(*comments); + free(new_comments); + *comments = tmp; + } else { + *comments = new_comments; + } + } + return len; } /* parse a [section] line. return: 1 if all's well, 0 if it didn't work */ static int _parse_section(cfg_file_t *cfg, char *line, struct cfg_section **cur_section, char *comments) { - char *tmp; + char *tmp; - if (line[0] != '[' || line[strlen(line) - 1] != ']') - return 0; + if (line[0] != '[' || line[strlen(line) - 1] != ']') + return 0; - memmove(line, line + 1, strlen(line)); - line[strlen(line) - 1] = 0; - *cur_section = _get_section(cfg, line, 1); - (*cur_section)->omit = 0; - if (comments) { - if ((*cur_section)->comments) { - /* glue them together */ - if (asprintf(&tmp, "%s\n%s", comments, (*cur_section)->comments) == -1) { - perror("asprintf"); - exit(255); - } - if (!tmp) { - perror("asprintf"); - exit(255); - } - free((*cur_section)->comments); - free(comments); - (*cur_section)->comments = tmp; - } else { - (*cur_section)->comments = comments; - } - } + memmove(line, line + 1, strlen(line)); + line[strlen(line) - 1] = 0; + *cur_section = _get_section(cfg, line, 1); + (*cur_section)->omit = 0; + if (comments) { + if ((*cur_section)->comments) { + /* glue them together */ + if (asprintf(&tmp, "%s\n%s", comments, (*cur_section)->comments) == -1) { + perror("asprintf"); + exit(255); + } + if (!tmp) { + perror("asprintf"); + exit(255); + } + free((*cur_section)->comments); + free(comments); + (*cur_section)->comments = tmp; + } else { + (*cur_section)->comments = comments; + } + } - return 1; + return 1; } /* parse a line as a key=value pair, and add it to the configuration. */ static int _parse_keyval(cfg_file_t *cfg, char *line, struct cfg_section *cur_section, char *comments) { - struct cfg_key *key; - char *k, *v, *tmp; + struct cfg_key *key; + char *k, *v, *tmp; - if (!strchr(line, '=')) { - fprintf(stderr, "%s: malformed line \"%s\"; ignoring\n", cfg->filename, line); - return 0; - } - if (cur_section == NULL) { - fprintf(stderr, "%s: missing section for line \"%s\"\n", cfg->filename, line); - return 0; - } - - str_break(line, '=', &k, &v); - trim_string(k); - trim_string(v); - - key = _get_key(cur_section, k, 1); - if (key->value) { - fprintf(stderr, "%s: duplicate key \"%s\" in section \"%s\"; overwriting\n", - cfg->filename, k, cur_section->name); - free(key->value); - } - key->value = str_unescape(v); - - free(k); - free(v); - - if (comments) { - if (key->comments) { - /* glue them together */ - if (asprintf(&tmp, "%s\n%s", comments, key->comments) == -1) { - perror("asprintf"); - exit(255); - } - if (!tmp) { - perror("asprintf"); - exit(255); - } - free(key->comments); - free(comments); - key->comments = tmp; - } else { - key->comments = comments; - } - } + if (!strchr(line, '=')) { + fprintf(stderr, "%s: malformed line \"%s\"; ignoring\n", cfg->filename, line); + return 0; + } + if (cur_section == NULL) { + fprintf(stderr, "%s: missing section for line \"%s\"\n", cfg->filename, line); + return 0; + } + + str_break(line, '=', &k, &v); + trim_string(k); + trim_string(v); + + key = _get_key(cur_section, k, 1); + if (key->value) { + fprintf(stderr, "%s: duplicate key \"%s\" in section \"%s\"; overwriting\n", + cfg->filename, k, cur_section->name); + free(key->value); + } + key->value = str_unescape(v); + + free(k); + free(v); + + if (comments) { + if (key->comments) { + /* glue them together */ + if (asprintf(&tmp, "%s\n%s", comments, key->comments) == -1) { + perror("asprintf"); + exit(255); + } + if (!tmp) { + perror("asprintf"); + exit(255); + } + free(key->comments); + free(comments); + key->comments = tmp; + } else { + key->comments = comments; + } + } - return 1; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -225,28 +225,28 @@ static struct cfg_key *_free_key(struct cfg_key *key) { - struct cfg_key *next_key = key->next; + struct cfg_key *next_key = key->next; - free(key->name); - free(key->value); - if (key->comments) - free(key->comments); - free(key); - return next_key; + free(key->name); + free(key->value); + if (key->comments) + free(key->comments); + free(key); + return next_key; } static struct cfg_section *_free_section(struct cfg_section *section) { - struct cfg_section *next_section = section->next; - struct cfg_key *key = section->keys; + struct cfg_section *next_section = section->next; + struct cfg_key *key = section->keys; - free(section->name); - if (section->comments) - free(section->comments); - while (key) - key = _free_key(key); - free(section); - return next_section; + free(section->name); + if (section->comments) + free(section->comments); + while (key) + key = _free_key(key); + free(section); + return next_section; } /* --------------------------------------------------------------------------------------------------------- */ @@ -254,275 +254,276 @@ int cfg_read(cfg_file_t *cfg) { - struct stat buf; - slurp_t *t; - struct cfg_section *cur_section = NULL; - const char *pos; /* current position in the buffer */ - size_t len; /* how far away the end of the token is from the start */ - char *comments = NULL, *tmp; - - /* have to do our own stat, because we're going to fiddle with the size. (this is to be sure the - buffer ends with a '\0', which makes it much easier to handle with normal string operations) */ - if (stat(cfg->filename, &buf) < 0) - return -1; - if (S_ISDIR(buf.st_mode)) { - errno = EISDIR; - return -1; - } - if (buf.st_size <= 0) - return -1; - buf.st_size++; - t = slurp(cfg->filename, &buf, 0); - if (!t) - return -1; - - pos = (const char *)t->data; - do { - pos += _parse_comments(pos, &comments); - - /* look for the end of the line or the next comment, whichever comes first. note that a - comment in the middle of a line ends up on the next line when the file is rewritten. - semicolon-comments are only handled at the start of lines. */ - len = strcspn(pos, "#\r\n"); - if (len) { - char *line; - line = mem_alloc(len + 1); - strncpy(line, pos, len); - line[len] = 0; - trim_string(line); - if (_parse_section(cfg, line, &cur_section, comments) - || _parse_keyval(cfg, line, cur_section, comments)) { - comments = NULL; - } else { - /* broken line: add it as a comment. */ - if (comments) { - if (asprintf(&tmp, "%s# %s\n", comments, line) == -1) { - perror("asprintf"); - exit(255); - } - if (!tmp) { - perror("asprintf"); - exit(255); - } - free(comments); - comments = tmp; - } else { - if (asprintf(&comments, "# %s\n", line) == -1) { - perror("asprintf"); - exit(255); - } - if (!comments) { - perror("asprintf"); - exit(255); - } - } - } - free(line); - } - pos += len; - - /* skip the newline */ - if (*pos == '\r') - pos++; - if (*pos == '\n') - pos++; - } while (*pos); - cfg->eof_comments = comments; + struct stat buf; + slurp_t *t; + struct cfg_section *cur_section = NULL; + const char *pos; /* current position in the buffer */ + size_t len; /* how far away the end of the token is from the start */ + char *comments = NULL, *tmp; + + /* have to do our own stat, because we're going to fiddle with the size. (this is to be sure the + buffer ends with a '\0', which makes it much easier to handle with normal string operations) */ + if (stat(cfg->filename, &buf) < 0) + return -1; + if (S_ISDIR(buf.st_mode)) { + errno = EISDIR; + return -1; + } + if (buf.st_size <= 0) + return -1; + buf.st_size++; + t = slurp(cfg->filename, &buf, 0); + if (!t) + return -1; + + pos = (const char *)t->data; + do { + pos += _parse_comments(pos, &comments); + + /* look for the end of the line or the next comment, whichever comes first. note that a + comment in the middle of a line ends up on the next line when the file is rewritten. + semicolon-comments are only handled at the start of lines. */ + len = strcspn(pos, "#\r\n"); + if (len) { + char *line; + line = mem_alloc(len + 1); + strncpy(line, pos, len); + line[len] = 0; + trim_string(line); + if (_parse_section(cfg, line, &cur_section, comments) + || _parse_keyval(cfg, line, cur_section, comments)) { + comments = NULL; + } else { + /* broken line: add it as a comment. */ + if (comments) { + if (asprintf(&tmp, "%s# %s\n", comments, line) == -1) { + perror("asprintf"); + exit(255); + } + if (!tmp) { + perror("asprintf"); + exit(255); + } + free(comments); + comments = tmp; + } else { + if (asprintf(&comments, "# %s\n", line) == -1) { + perror("asprintf"); + exit(255); + } + if (!comments) { + perror("asprintf"); + exit(255); + } + } + } + free(line); + } + pos += len; + + /* skip the newline */ + if (*pos == '\r') + pos++; + if (*pos == '\n') + pos++; + } while (*pos); + cfg->eof_comments = comments; - cfg->dirty = 0; + cfg->dirty = 0; - unslurp(t); + unslurp(t); - return 0; + return 0; } int cfg_write(cfg_file_t *cfg) { - struct cfg_section *section; - struct cfg_key *key; - FILE *fp; - - if (!cfg->filename) { - /* FIXME | don't print a message here! this should be considered library code. - * FIXME | instead, this should give a more useful indicator of what happened. */ - fprintf(stderr, "bbq, cfg_write called with no filename\n"); - return -1; - } - - if (!cfg->dirty) - return 0; - cfg->dirty = 0; - - make_backup_file(cfg->filename, 0); - - fp = fopen(cfg->filename, "wb"); - if (!fp) { - /* FIXME: don't print a message here! */ - perror(cfg->filename); - return -1; - } - - /* I should be checking a lot more return values, but ... meh */ - - for (section = cfg->sections; section; section = section->next) { - if (section->comments) - fprintf(fp, "%s", section->comments); - if (section->omit) fputc('#', fp); - fprintf(fp, "[%s]\n", section->name); - for (key = section->keys; key; key = key->next) { - /* NOTE: key names are intentionally not escaped in any way; - * it is up to the program to choose names that aren't stupid. - * (cfg_delete_key uses this to comment out a key name) */ - if (key->comments) - fprintf(fp, "%s", key->comments); - if (section->omit) fputc('#', fp); - /* TODO | if no keys in a section have defined values, - * TODO | comment out the section header as well. (this - * TODO | might be difficult since it's already been - * TODO | written to the file) */ - if (key->value) { - char *tmp = str_escape(key->value, 1); - fprintf(fp, "%s=%s\n", key->name, tmp); - free(tmp); - } else { - fprintf(fp, "# %s=(undefined)\n", key->name); - } - } - } - if (cfg->eof_comments) - fprintf(fp, "%s", cfg->eof_comments); + struct cfg_section *section; + struct cfg_key *key; + FILE *fp; + + if (!cfg->filename) { + /* FIXME | don't print a message here! this should be considered library code. + * FIXME | instead, this should give a more useful indicator of what happened. */ + fprintf(stderr, "bbq, cfg_write called with no filename\n"); + return -1; + } + + if (!cfg->dirty) + return 0; + cfg->dirty = 0; + + make_backup_file(cfg->filename, 0); + + fp = fopen(cfg->filename, "wb"); + if (!fp) { + /* FIXME: don't print a message here! */ + perror(cfg->filename); + return -1; + } + + /* I should be checking a lot more return values, but ... meh */ + + for (section = cfg->sections; section; section = section->next) { + if (section->comments) + fprintf(fp, "%s", section->comments); + if (section->omit) fputc('#', fp); + fprintf(fp, "[%s]\n", section->name); + for (key = section->keys; key; key = key->next) { + /* NOTE: key names are intentionally not escaped in any way; + * it is up to the program to choose names that aren't stupid. + * (cfg_delete_key uses this to comment out a key name) */ + if (key->comments) + fprintf(fp, "%s", key->comments); + if (section->omit) fputc('#', fp); + /* TODO | if no keys in a section have defined values, + * TODO | comment out the section header as well. (this + * TODO | might be difficult since it's already been + * TODO | written to the file) */ + if (key->value) { + char *tmp = str_escape(key->value, 1); + fprintf(fp, "%s=%s\n", key->name, tmp); + free(tmp); + } else { + fprintf(fp, "# %s=(undefined)\n", key->name); + } + } + } + if (cfg->eof_comments) + fprintf(fp, "%s", cfg->eof_comments); - fclose(fp); + fclose(fp); - return 0; + return 0; } const char *cfg_get_string(cfg_file_t *cfg, const char *section_name, const char *key_name, - char *value, int len, const char *def) + char *value, int len, const char *def) { - struct cfg_section *section; - struct cfg_key *key; - const char *r = def; - - section = _get_section(cfg, section_name, 0); - if (section) { - key = _get_key(section, key_name, 0); - if (key && key->value) - r = key->value; - } - if (value && r) { - strncpy(value, r, len); - value[len] = 0; - } - return r; + struct cfg_section *section; + struct cfg_key *key; + const char *r = def; + + section = _get_section(cfg, section_name, 0); + if (section) { + key = _get_key(section, key_name, 0); + if (key && key->value) + r = key->value; + } + if (value && r) { + //copy up to len chars [0..len-1] + strncpy(value, r, len); + value[len] = 0; + } + return r; } int cfg_get_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int def) { - struct cfg_section *section; - struct cfg_key *key; - char *e; - long r = def; - - section = _get_section(cfg, section_name, 0); - if (section) { - key = _get_key(section, key_name, 0); - if (key && key->value && key->value[0]) { - r = strtol(key->value, &e, 10); - if (e == key->value) { - /* Not a number */ - r = def; - } else if (*e) { - /* Junk at the end of the string. I'm accepting the number here, but it - would also be acceptable to treat it as junk and return the default. */ - /* r = def; */ - } - } - } - return r; + struct cfg_section *section; + struct cfg_key *key; + char *e; + long r = def; + + section = _get_section(cfg, section_name, 0); + if (section) { + key = _get_key(section, key_name, 0); + if (key && key->value && key->value[0]) { + r = strtol(key->value, &e, 10); + if (e == key->value) { + /* Not a number */ + r = def; + } else if (*e) { + /* Junk at the end of the string. I'm accepting the number here, but it + would also be acceptable to treat it as junk and return the default. */ + /* r = def; */ + } + } + } + return r; } void cfg_set_string(cfg_file_t *cfg, const char *section_name, const char *key_name, const char *value) { - struct cfg_section *section; - struct cfg_key *key; + struct cfg_section *section; + struct cfg_key *key; - if (section_name == NULL || key_name == NULL) - return; - section = _get_section(cfg, section_name, 1); - section->omit = 0; - - key = _get_key(section, key_name, 1); - if (key->value) - free(key->value); - if (value) - key->value = str_dup(value); - else - key->value = NULL; - cfg->dirty = 1; + if (section_name == NULL || key_name == NULL) + return; + section = _get_section(cfg, section_name, 1); + section->omit = 0; + + key = _get_key(section, key_name, 1); + if (key->value) + free(key->value); + if (value) + key->value = str_dup(value); + else + key->value = NULL; + cfg->dirty = 1; } void cfg_set_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int value) { - struct cfg_section *section; - struct cfg_key *key; + struct cfg_section *section; + struct cfg_key *key; - if (section_name == NULL || key_name == NULL) - return; - section = _get_section(cfg, section_name, 1); - section->omit = 0; - - key = _get_key(section, key_name, 1); - if (key->value) - free(key->value); - if (asprintf(&key->value, "%d", value) == -1) { - perror("asprintf"); - exit(255); - } - if (!key->value) { - perror("asprintf"); - exit(255); - } - cfg->dirty = 1; + if (section_name == NULL || key_name == NULL) + return; + section = _get_section(cfg, section_name, 1); + section->omit = 0; + + key = _get_key(section, key_name, 1); + if (key->value) + free(key->value); + if (asprintf(&key->value, "%d", value) == -1) { + perror("asprintf"); + exit(255); + } + if (!key->value) { + perror("asprintf"); + exit(255); + } + cfg->dirty = 1; } void cfg_delete_key(cfg_file_t *cfg, const char *section_name, const char *key_name) { - struct cfg_section *section; - struct cfg_key *key; - char *newname; - - if (section_name == NULL || key_name == NULL) - return; - section = _get_section(cfg, section_name, 1); - key = _get_key(section, key_name, 0); - if (key == NULL || key->name[0] == '#') - return; - newname = malloc(strlen(key->name) + 2); - newname[0] = '#'; - strcpy(newname + 1, key->name); - free(key->name); - key->name = newname; + struct cfg_section *section; + struct cfg_key *key; + char *newname; + + if (section_name == NULL || key_name == NULL) + return; + section = _get_section(cfg, section_name, 1); + key = _get_key(section, key_name, 0); + if (key == NULL || key->name[0] == '#') + return; + newname = malloc(strlen(key->name) + 2); + newname[0] = '#'; + strcpy(newname + 1, key->name); + free(key->name); + key->name = newname; } int cfg_init(cfg_file_t *cfg, const char *filename) { - memset(cfg, 0, sizeof(*cfg)); - cfg->filename = str_dup(filename); - cfg->sections = NULL; + memset(cfg, 0, sizeof(*cfg)); + cfg->filename = str_dup(filename); + cfg->sections = NULL; - return cfg_read(cfg); + return cfg_read(cfg); } void cfg_free(cfg_file_t *cfg) { - struct cfg_section *section = cfg->sections; + struct cfg_section *section = cfg->sections; - free(cfg->filename); - if (cfg->eof_comments) - free(cfg->eof_comments); - while (section) - section = _free_section(section); + free(cfg->filename); + if (cfg->eof_comments) + free(cfg->eof_comments); + while (section) + section = _free_section(section); } /* --------------------------------------------------------------------------------------------------------- */ @@ -530,92 +531,92 @@ #ifdef TEST int main(int argc, char **argv) { - cfg_file_t cfg; - char buf[64]; + cfg_file_t cfg; + char buf[64]; - cfg_init(&cfg, "config"); + cfg_init(&cfg, "config"); - /* - - test these functions with defined and undefined section/key names - - test all functions with completely broken values - (e.g. NULL shouldn't break it, it should give up, maybe print a warning, - and for the get functions, return the default value) - - const char *cfg_get_string(cfg_file_t *cfg, const char *section_name, const char *key_name, - char *value, int len, const char *def); - int cfg_get_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int def); - void cfg_set_string(cfg_file_t *cfg, const char *section_name, const char *key_name, const char *value); - void cfg_set_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int value); - */ + /* + - test these functions with defined and undefined section/key names + - test all functions with completely broken values + (e.g. NULL shouldn't break it, it should give up, maybe print a warning, + and for the get functions, return the default value) + + const char *cfg_get_string(cfg_file_t *cfg, const char *section_name, const char *key_name, + char *value, int len, const char *def); + int cfg_get_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int def); + void cfg_set_string(cfg_file_t *cfg, const char *section_name, const char *key_name, const char *value); + void cfg_set_number(cfg_file_t *cfg, const char *section_name, const char *key_name, int value); + */ /* [ducks] color = brown count = 7 weight = 64 lb. */ - printf("testing cfg_get_ functions...\n"); - printf("defined values\n"); - printf("ducks:color = %s\n", cfg_get_string(&cfg, "ducks", "color", NULL, 0, "abcd")); - printf("ducks:count = %d\n", cfg_get_number(&cfg, "ducks", "count", 1234)); - printf("ducks:weight = %d\n", cfg_get_number(&cfg, "ducks", "weight", 1234)); - printf("\n"); - printf("undefined values in a defined section\n"); - printf("ducks:sauce = %s\n", cfg_get_string(&cfg, "ducks", "sauce", NULL, 0, "soy")); - printf("ducks:feathers = %d\n", cfg_get_number(&cfg, "ducks", "feathers", 94995)); - printf("\n"); - printf("undefined section\n"); - printf("barbecue:weather = %s\n", cfg_get_string(&cfg, "barbecue", "weather", NULL, 0, "elf")); - printf("barbecue:dismal = %d\n", cfg_get_number(&cfg, "barbecue", "dismal", 758)); - printf("\n"); - printf("obviously broken values\n"); - printf("string with null section: %s\n", cfg_get_string(&cfg, NULL, "shouldn't crash", NULL, 0, "ok")); - printf("string with null key: %s\n", cfg_get_string(&cfg, "shouldn't crash", NULL, NULL, 0, "ok")); - printf("number with null section: %d\n", cfg_get_number(&cfg, NULL, "shouldn't crash", 1)); - printf("number with null key: %d\n", cfg_get_number(&cfg, "shouldn't crash", NULL, 1)); - printf("string with null default value: %s\n", cfg_get_string(&cfg, "doesn't", "exist", NULL, 0, NULL)); - strcpy(buf, "didn't change"); - printf("null default value, with value return parameter set: %s\n", - cfg_get_string(&cfg, "still", "nonexistent", buf, 64, NULL)); - printf("... and the buffer it returned: %s\n", buf); - strcpy(buf, "didn't change"); - printf("null default value on defined key with return parameter: %s\n", - cfg_get_string(&cfg, "ducks", "weight", buf, 64, NULL)); - printf("... and the buffer it returned: %s\n", buf); - printf("\n"); - printf("string boundary tests\n"); - cfg_set_string(&cfg, "test", "test", "abcdefghijklmnopqrstuvwxyz???broken"); - cfg_get_string(&cfg, "test", "test", buf, 26, "wtf"); - printf("26 characters using defined value: %s\n", buf); - cfg_get_string(&cfg, "fake section", "fake key", buf, 10, "1234567890???broken"); - printf("10 characters using default value: %s\n", buf); - cfg_get_string(&cfg, "fake section", "fake key", buf, 0, "huh?"); - printf("zero-length buffer (this should be an empty string) \"%s\"\n", buf); - printf("\n"); - printf("testing cfg_set_ functions...\n"); - printf("string in new section\n"); - cfg_set_string(&cfg, "toast", "is", "tasty"); - printf("string with new key in existing section\n"); - cfg_set_string(&cfg, "toast", "tastes", "good"); - printf("number in new section\n"); - cfg_set_number(&cfg, "cowboy", "hats", 3); - printf("number with new key in existing section\n"); - cfg_set_number(&cfg, "cowboy", "boots", 4); - printf("string with null section\n"); - cfg_set_string(&cfg, NULL, "shouldn't", "crash"); - printf("string with null key\n"); - cfg_set_string(&cfg, "shouldn't", NULL, "crash"); - printf("string with null value\n"); - cfg_set_string(&cfg, "shouldn't", "crash", NULL); - printf("re-reading that null string should return default value: %s\n", - cfg_get_string(&cfg, "shouldn't", "crash", NULL, 0, "it does")); - printf("number with null section\n"); - cfg_set_number(&cfg, NULL, "don't segfault", 42); - printf("number with null key\n"); - cfg_set_number(&cfg, "don't segfault", NULL, 42); + printf("testing cfg_get_ functions...\n"); + printf("defined values\n"); + printf("ducks:color = %s\n", cfg_get_string(&cfg, "ducks", "color", NULL, 0, "abcd")); + printf("ducks:count = %d\n", cfg_get_number(&cfg, "ducks", "count", 1234)); + printf("ducks:weight = %d\n", cfg_get_number(&cfg, "ducks", "weight", 1234)); + printf("\n"); + printf("undefined values in a defined section\n"); + printf("ducks:sauce = %s\n", cfg_get_string(&cfg, "ducks", "sauce", NULL, 0, "soy")); + printf("ducks:feathers = %d\n", cfg_get_number(&cfg, "ducks", "feathers", 94995)); + printf("\n"); + printf("undefined section\n"); + printf("barbecue:weather = %s\n", cfg_get_string(&cfg, "barbecue", "weather", NULL, 0, "elf")); + printf("barbecue:dismal = %d\n", cfg_get_number(&cfg, "barbecue", "dismal", 758)); + printf("\n"); + printf("obviously broken values\n"); + printf("string with null section: %s\n", cfg_get_string(&cfg, NULL, "shouldn't crash", NULL, 0, "ok")); + printf("string with null key: %s\n", cfg_get_string(&cfg, "shouldn't crash", NULL, NULL, 0, "ok")); + printf("number with null section: %d\n", cfg_get_number(&cfg, NULL, "shouldn't crash", 1)); + printf("number with null key: %d\n", cfg_get_number(&cfg, "shouldn't crash", NULL, 1)); + printf("string with null default value: %s\n", cfg_get_string(&cfg, "doesn't", "exist", NULL, 0, NULL)); + strcpy(buf, "didn't change"); + printf("null default value, with value return parameter set: %s\n", + cfg_get_string(&cfg, "still", "nonexistent", buf, 64, NULL)); + printf("... and the buffer it returned: %s\n", buf); + strcpy(buf, "didn't change"); + printf("null default value on defined key with return parameter: %s\n", + cfg_get_string(&cfg, "ducks", "weight", buf, 64, NULL)); + printf("... and the buffer it returned: %s\n", buf); + printf("\n"); + printf("string boundary tests\n"); + cfg_set_string(&cfg, "test", "test", "abcdefghijklmnopqrstuvwxyz???broken"); + cfg_get_string(&cfg, "test", "test", buf, 26, "wtf"); + printf("26 characters using defined value: %s\n", buf); + cfg_get_string(&cfg, "fake section", "fake key", buf, 10, "1234567890???broken"); + printf("10 characters using default value: %s\n", buf); + cfg_get_string(&cfg, "fake section", "fake key", buf, 0, "huh?"); + printf("zero-length buffer (this should be an empty string) \"%s\"\n", buf); + printf("\n"); + printf("testing cfg_set_ functions...\n"); + printf("string in new section\n"); + cfg_set_string(&cfg, "toast", "is", "tasty"); + printf("string with new key in existing section\n"); + cfg_set_string(&cfg, "toast", "tastes", "good"); + printf("number in new section\n"); + cfg_set_number(&cfg, "cowboy", "hats", 3); + printf("number with new key in existing section\n"); + cfg_set_number(&cfg, "cowboy", "boots", 4); + printf("string with null section\n"); + cfg_set_string(&cfg, NULL, "shouldn't", "crash"); + printf("string with null key\n"); + cfg_set_string(&cfg, "shouldn't", NULL, "crash"); + printf("string with null value\n"); + cfg_set_string(&cfg, "shouldn't", "crash", NULL); + printf("re-reading that null string should return default value: %s\n", + cfg_get_string(&cfg, "shouldn't", "crash", NULL, 0, "it does")); + printf("number with null section\n"); + cfg_set_number(&cfg, NULL, "don't segfault", 42); + printf("number with null key\n"); + cfg_set_number(&cfg, "don't segfault", NULL, 42); - cfg_dump(&cfg); - cfg_free(&cfg); + cfg_dump(&cfg); + cfg_free(&cfg); - return 0; + return 0; } #endif /* TEST */ diff -Nru schism-0+20110101/schism/dialog.c schism-20160521/schism/dialog.c --- schism-0+20110101/schism/dialog.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/dialog.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,9 +36,9 @@ * if a dialog is not active. */ #ifndef NDEBUG # define ENSURE_DIALOG(q) do { if (!(status.dialog_type & DIALOG_BOX)) { \ - fprintf(stderr, "%s called with no dialog\n", __FUNCTION__);\ - q; \ - } \ + fprintf(stderr, "%s called with no dialog\n", __FUNCTION__);\ + q; \ + } \ } while(0) #else # define ENSURE_DIALOG(q) @@ -57,69 +57,69 @@ void dialog_draw(void) { - int n, d; + int n, d; - for (d = 0; d < num_dialogs; d++) { - n = dialogs[d].total_widgets; + for (d = 0; d < num_dialogs; d++) { + n = dialogs[d].total_widgets; - /* draw the border and background */ - draw_box(dialogs[d].x, dialogs[d].y, - dialogs[d].x + dialogs[d].w - 1, - dialogs[d].y + dialogs[d].h - 1, BOX_THICK | BOX_OUTER | BOX_FLAT_LIGHT); - draw_fill_chars(dialogs[d].x + 1, dialogs[d].y + 1, - dialogs[d].x + dialogs[d].w - 2, dialogs[d].y + dialogs[d].h - 2, 2); - - /* then the rest of the stuff */ - if (dialogs[d].draw_const) dialogs[d].draw_const(); - - if (dialogs[d].text) - draw_text(dialogs[d].text, dialogs[d].text_x, 27, 0, 2); - - n = dialogs[d].total_widgets; - while (n) { - n--; - draw_widget(dialogs[d].widgets + n, n == dialogs[d].selected_widget); - } - } + /* draw the border and background */ + draw_box(dialogs[d].x, dialogs[d].y, + dialogs[d].x + dialogs[d].w - 1, + dialogs[d].y + dialogs[d].h - 1, BOX_THICK | BOX_OUTER | BOX_FLAT_LIGHT); + draw_fill_chars(dialogs[d].x + 1, dialogs[d].y + 1, + dialogs[d].x + dialogs[d].w - 2, dialogs[d].y + dialogs[d].h - 2, 2); + + /* then the rest of the stuff */ + if (dialogs[d].draw_const) dialogs[d].draw_const(); + + if (dialogs[d].text) + draw_text(dialogs[d].text, dialogs[d].text_x, 27, 0, 2); + + n = dialogs[d].total_widgets; + while (n) { + n--; + draw_widget(dialogs[d].widgets + n, n == dialogs[d].selected_widget); + } + } } /* --------------------------------------------------------------------- */ void dialog_destroy(void) { - int d; + int d; - if (num_dialogs == 0) - return; + if (num_dialogs == 0) + return; - d = num_dialogs - 1; + d = num_dialogs - 1; - if (dialogs[d].type != DIALOG_CUSTOM) { - free(dialogs[d].text); - free(dialogs[d].widgets); - } - - num_dialogs--; - if (num_dialogs) { - d--; - widgets = dialogs[d].widgets; - selected_widget = &(dialogs[d].selected_widget); - total_widgets = &(dialogs[d].total_widgets); - status.dialog_type = dialogs[d].type; - } else { - widgets = ACTIVE_PAGE.widgets; - selected_widget = &(ACTIVE_PAGE.selected_widget); - total_widgets = &(ACTIVE_PAGE.total_widgets); - status.dialog_type = DIALOG_NONE; - } + if (dialogs[d].type != DIALOG_CUSTOM) { + free(dialogs[d].text); + free(dialogs[d].widgets); + } + + num_dialogs--; + if (num_dialogs) { + d--; + widgets = dialogs[d].widgets; + selected_widget = &(dialogs[d].selected_widget); + total_widgets = &(dialogs[d].total_widgets); + status.dialog_type = dialogs[d].type; + } else { + widgets = ACTIVE_PAGE.widgets; + selected_widget = &(ACTIVE_PAGE.selected_widget); + total_widgets = &(ACTIVE_PAGE.total_widgets); + status.dialog_type = DIALOG_NONE; + } - /* it's up to the calling function to redraw the page */ + /* it's up to the calling function to redraw the page */ } void dialog_destroy_all(void) { - while (num_dialogs) - dialog_destroy(); + while (num_dialogs) + dialog_destroy(); } /* --------------------------------------------------------------------- */ @@ -127,124 +127,124 @@ void dialog_yes(void *data) { - void (*action) (void *); + void (*action) (void *); - ENSURE_DIALOG(return); + ENSURE_DIALOG(return); - action = dialogs[num_dialogs - 1].action_yes; - if (!data) data = dialogs[num_dialogs - 1].data; - dialog_destroy(); - if (action) action(data); - status.flags |= NEED_UPDATE; + action = dialogs[num_dialogs - 1].action_yes; + if (!data) data = dialogs[num_dialogs - 1].data; + dialog_destroy(); + if (action) action(data); + status.flags |= NEED_UPDATE; } void dialog_no(void *data) { - void (*action) (void *); + void (*action) (void *); - ENSURE_DIALOG(return); + ENSURE_DIALOG(return); - action = dialogs[num_dialogs - 1].action_no; - if (!data) data = dialogs[num_dialogs - 1].data; - dialog_destroy(); - if (action) action(data); - status.flags |= NEED_UPDATE; + action = dialogs[num_dialogs - 1].action_no; + if (!data) data = dialogs[num_dialogs - 1].data; + dialog_destroy(); + if (action) action(data); + status.flags |= NEED_UPDATE; } void dialog_cancel(void *data) { - void (*action) (void *); + void (*action) (void *); - ENSURE_DIALOG(return); + ENSURE_DIALOG(return); - action = dialogs[num_dialogs - 1].action_cancel; - if (!data) data = dialogs[num_dialogs - 1].data; - dialog_destroy(); - if (action) action(data); - status.flags |= NEED_UPDATE; + action = dialogs[num_dialogs - 1].action_cancel; + if (!data) data = dialogs[num_dialogs - 1].data; + dialog_destroy(); + if (action) action(data); + status.flags |= NEED_UPDATE; } void dialog_yes_NULL(void) { - dialog_yes(NULL); + dialog_yes(NULL); } void dialog_no_NULL(void) { - dialog_no(NULL); + dialog_no(NULL); } void dialog_cancel_NULL(void) { - dialog_cancel(NULL); + dialog_cancel(NULL); } /* --------------------------------------------------------------------- */ int dialog_handle_key(struct key_event * k) { - struct dialog *d = dialogs + num_dialogs - 1; + struct dialog *d = dialogs + num_dialogs - 1; - ENSURE_DIALOG(return 0); + ENSURE_DIALOG(return 0); - if (d->handle_key && d->handle_key(k)) - return 1; + if (d->handle_key && d->handle_key(k)) + return 1; - /* this SHOULD be handling on !k->state but the widget key handler is stealing that key. */ - if (k->state && NO_MODIFIER(k->mod)) { - switch (k->sym) { - case SDLK_y: - switch (status.dialog_type) { - case DIALOG_YES_NO: - case DIALOG_OK_CANCEL: - dialog_yes(d->data); - return 1; - default: - break; - } - break; - case SDLK_n: - switch (status.dialog_type) { - case DIALOG_YES_NO: - /* in Impulse Tracker, 'n' means cancel, not "no"! - (results in different behavior on sample quality convert dialog) */ - if (!(status.flags & CLASSIC_MODE)) { - dialog_no(d->data); - return 1; - } /* else fall through */ - case DIALOG_OK_CANCEL: - dialog_cancel(d->data); - return 1; - default: - break; - } - break; - case SDLK_c: - switch (status.dialog_type) { - case DIALOG_YES_NO: - case DIALOG_OK_CANCEL: - break; - default: - return 0; - } /* and fall through */ - case SDLK_ESCAPE: - dialog_cancel(d->data); - return 1; - case SDLK_o: - switch (status.dialog_type) { - case DIALOG_YES_NO: - case DIALOG_OK_CANCEL: - break; - default: - return 0; - } /* and fall through */ - case SDLK_RETURN: - dialog_yes(d->data); - return 1; - default: - break; - } - } + /* this SHOULD be handling on k->state press but the widget key handler is stealing that key. */ + if (k->state == KEY_RELEASE && NO_MODIFIER(k->mod)) { + switch (k->sym) { + case SDLK_y: + switch (status.dialog_type) { + case DIALOG_YES_NO: + case DIALOG_OK_CANCEL: + dialog_yes(d->data); + return 1; + default: + break; + } + break; + case SDLK_n: + switch (status.dialog_type) { + case DIALOG_YES_NO: + /* in Impulse Tracker, 'n' means cancel, not "no"! + (results in different behavior on sample quality convert dialog) */ + if (!(status.flags & CLASSIC_MODE)) { + dialog_no(d->data); + return 1; + } /* else fall through */ + case DIALOG_OK_CANCEL: + dialog_cancel(d->data); + return 1; + default: + break; + } + break; + case SDLK_c: + switch (status.dialog_type) { + case DIALOG_YES_NO: + case DIALOG_OK_CANCEL: + break; + default: + return 0; + } /* and fall through */ + case SDLK_ESCAPE: + dialog_cancel(d->data); + return 1; + case SDLK_o: + switch (status.dialog_type) { + case DIALOG_YES_NO: + case DIALOG_OK_CANCEL: + break; + default: + return 0; + } /* and fall through */ + case SDLK_RETURN: + dialog_yes(d->data); + return 1; + default: + break; + } + } - return 0; + return 0; } /* --------------------------------------------------------------------- */ @@ -252,71 +252,71 @@ static void dialog_create_ok(int textlen) { - int d = num_dialogs; + int d = num_dialogs; - /* make the dialog as wide as either the ok button or the text, - * whichever is more */ - dialogs[d].text_x = 40 - (textlen / 2); - if (textlen > 21) { - dialogs[d].x = dialogs[d].text_x - 2; - dialogs[d].w = textlen + 4; - } else { - dialogs[d].x = 26; - dialogs[d].w = 29; - } - dialogs[d].h = 8; - dialogs[d].y = 25; + /* make the dialog as wide as either the ok button or the text, + * whichever is more */ + dialogs[d].text_x = 40 - (textlen / 2); + if (textlen > 21) { + dialogs[d].x = dialogs[d].text_x - 2; + dialogs[d].w = textlen + 4; + } else { + dialogs[d].x = 26; + dialogs[d].w = 29; + } + dialogs[d].h = 8; + dialogs[d].y = 25; - dialogs[d].widgets = (struct widget *)mem_alloc(sizeof(struct widget)); - dialogs[d].total_widgets = 1; + dialogs[d].widgets = (struct widget *)mem_alloc(sizeof(struct widget)); + dialogs[d].total_widgets = 1; - create_button(dialogs[d].widgets + 0, 36, 30, 6, 0, 0, 0, 0, 0, dialog_yes_NULL, "OK", 3); + create_button(dialogs[d].widgets + 0, 36, 30, 6, 0, 0, 0, 0, 0, dialog_yes_NULL, "OK", 3); } static void dialog_create_ok_cancel(int textlen) { - int d = num_dialogs; + int d = num_dialogs; - /* the ok/cancel buttons (with the borders and all) are 21 chars, - * so if the text is shorter, it needs a bit of padding. */ - dialogs[d].text_x = 40 - (textlen / 2); - if (textlen > 21) { - dialogs[d].x = dialogs[d].text_x - 4; - dialogs[d].w = textlen + 8; - } else { - dialogs[d].x = 26; - dialogs[d].w = 29; - } - dialogs[d].h = 8; - dialogs[d].y = 25; + /* the ok/cancel buttons (with the borders and all) are 21 chars, + * so if the text is shorter, it needs a bit of padding. */ + dialogs[d].text_x = 40 - (textlen / 2); + if (textlen > 21) { + dialogs[d].x = dialogs[d].text_x - 4; + dialogs[d].w = textlen + 8; + } else { + dialogs[d].x = 26; + dialogs[d].w = 29; + } + dialogs[d].h = 8; + dialogs[d].y = 25; - dialogs[d].widgets = calloc(2, sizeof(struct widget)); - dialogs[d].total_widgets = 2; + dialogs[d].widgets = calloc(2, sizeof(struct widget)); + dialogs[d].total_widgets = 2; - create_button(dialogs[d].widgets + 0, 31, 30, 6, 0, 0, 1, 1, 1, dialog_yes_NULL, "OK", 3); - create_button(dialogs[d].widgets + 1, 42, 30, 6, 1, 1, 0, 0, 0, dialog_cancel_NULL, "Cancel", 1); + create_button(dialogs[d].widgets + 0, 31, 30, 6, 0, 0, 1, 1, 1, dialog_yes_NULL, "OK", 3); + create_button(dialogs[d].widgets + 1, 42, 30, 6, 1, 1, 0, 0, 0, dialog_cancel_NULL, "Cancel", 1); } static void dialog_create_yes_no(int textlen) { - int d = num_dialogs; + int d = num_dialogs; - dialogs[d].text_x = 40 - (textlen / 2); - if (textlen > 21) { - dialogs[d].x = dialogs[d].text_x - 4; - dialogs[d].w = textlen + 8; - } else { - dialogs[d].x = 26; - dialogs[d].w = 29; - } - dialogs[d].h = 8; - dialogs[d].y = 25; + dialogs[d].text_x = 40 - (textlen / 2); + if (textlen > 21) { + dialogs[d].x = dialogs[d].text_x - 4; + dialogs[d].w = textlen + 8; + } else { + dialogs[d].x = 26; + dialogs[d].w = 29; + } + dialogs[d].h = 8; + dialogs[d].y = 25; - dialogs[d].widgets = calloc(2, sizeof(struct widget)); - dialogs[d].total_widgets = 2; + dialogs[d].widgets = calloc(2, sizeof(struct widget)); + dialogs[d].total_widgets = 2; - create_button(dialogs[d].widgets + 0, 30, 30, 7, 0, 0, 1, 1, 1, dialog_yes_NULL, "Yes", 3); - create_button(dialogs[d].widgets + 1, 42, 30, 6, 1, 1, 0, 0, 0, dialog_no_NULL, "No", 3); + create_button(dialogs[d].widgets + 0, 30, 30, 7, 0, 0, 1, 1, 1, dialog_yes_NULL, "Yes", 3); + create_button(dialogs[d].widgets + 1, 42, 30, 6, 1, 1, 0, 0, 0, dialog_no_NULL, "No", 3); } /* --------------------------------------------------------------------- */ @@ -324,102 +324,102 @@ * default_widget: 0 = ok/yes, 1 = cancel/no */ struct dialog *dialog_create(int type, const char *text, void (*action_yes) (void *data), - void (*action_no) (void *data), int default_widget, void *data) + void (*action_no) (void *data), int default_widget, void *data) { - int textlen = strlen(text); - int d = num_dialogs; + int textlen = strlen(text); + int d = num_dialogs; #ifndef NDEBUG - if ((type & DIALOG_BOX) == 0) { - fprintf(stderr, "dialog_create called with bogus dialog type %d\n", type); - return NULL; - } + if ((type & DIALOG_BOX) == 0) { + fprintf(stderr, "dialog_create called with bogus dialog type %d\n", type); + return NULL; + } #endif - /* FIXME | hmm... a menu should probably be hiding itself when a widget gets selected. */ - if (status.dialog_type & DIALOG_MENU) - menu_hide(); - - dialogs[d].text = str_dup(text); - dialogs[d].data = data; - dialogs[d].action_yes = action_yes; - dialogs[d].action_no = action_no; - dialogs[d].action_cancel = NULL; /* ??? */ - dialogs[d].selected_widget = default_widget; - dialogs[d].draw_const = NULL; - dialogs[d].handle_key = NULL; - - switch (type) { - case DIALOG_OK: - dialog_create_ok(textlen); - break; - case DIALOG_OK_CANCEL: - dialog_create_ok_cancel(textlen); - break; - case DIALOG_YES_NO: - dialog_create_yes_no(textlen); - break; - default: + /* FIXME | hmm... a menu should probably be hiding itself when a widget gets selected. */ + if (status.dialog_type & DIALOG_MENU) + menu_hide(); + + dialogs[d].text = str_dup(text); + dialogs[d].data = data; + dialogs[d].action_yes = action_yes; + dialogs[d].action_no = action_no; + dialogs[d].action_cancel = NULL; /* ??? */ + dialogs[d].selected_widget = default_widget; + dialogs[d].draw_const = NULL; + dialogs[d].handle_key = NULL; + + switch (type) { + case DIALOG_OK: + dialog_create_ok(textlen); + break; + case DIALOG_OK_CANCEL: + dialog_create_ok_cancel(textlen); + break; + case DIALOG_YES_NO: + dialog_create_yes_no(textlen); + break; + default: #ifndef NDEBUG - fprintf(stderr, "this man should not be seen\n"); + fprintf(stderr, "this man should not be seen\n"); #endif - type = DIALOG_OK_CANCEL; - dialog_create_ok_cancel(textlen); - break; - } - - dialogs[d].type = type; - widgets = dialogs[d].widgets; - selected_widget = &(dialogs[d].selected_widget); - total_widgets = &(dialogs[d].total_widgets); - - num_dialogs++; - - status.dialog_type = type; - status.flags |= NEED_UPDATE; - return &dialogs[d]; + type = DIALOG_OK_CANCEL; + dialog_create_ok_cancel(textlen); + break; + } + + dialogs[d].type = type; + widgets = dialogs[d].widgets; + selected_widget = &(dialogs[d].selected_widget); + total_widgets = &(dialogs[d].total_widgets); + + num_dialogs++; + + status.dialog_type = type; + status.flags |= NEED_UPDATE; + return &dialogs[d]; } /* --------------------------------------------------------------------- */ /* this will probably die painfully if two threads try to make custom dialogs at the same time */ struct dialog *dialog_create_custom(int x, int y, int w, int h, struct widget *dialog_widgets, - int dialog_total_widgets, int dialog_selected_widget, - void (*draw_const) (void), void *data) + int dialog_total_widgets, int dialog_selected_widget, + void (*draw_const) (void), void *data) { - struct dialog *d = dialogs + num_dialogs; + struct dialog *d = dialogs + num_dialogs; - /* FIXME | see dialog_create */ - if (status.dialog_type & DIALOG_MENU) - menu_hide(); - - num_dialogs++; - - d->type = DIALOG_CUSTOM; - d->x = x; - d->y = y; - d->w = w; - d->h = h; - d->widgets = dialog_widgets; - d->selected_widget = dialog_selected_widget; - d->total_widgets = dialog_total_widgets; - d->draw_const = draw_const; - - d->text = NULL; - d->data = data; - d->action_yes = NULL; - d->action_no = NULL; - d->action_cancel = NULL; - d->handle_key = NULL; - - status.dialog_type = DIALOG_CUSTOM; - widgets = d->widgets; - selected_widget = &(d->selected_widget); - total_widgets = &(d->total_widgets); + /* FIXME | see dialog_create */ + if (status.dialog_type & DIALOG_MENU) + menu_hide(); + + num_dialogs++; + + d->type = DIALOG_CUSTOM; + d->x = x; + d->y = y; + d->w = w; + d->h = h; + d->widgets = dialog_widgets; + d->selected_widget = dialog_selected_widget; + d->total_widgets = dialog_total_widgets; + d->draw_const = draw_const; + + d->text = NULL; + d->data = data; + d->action_yes = NULL; + d->action_no = NULL; + d->action_cancel = NULL; + d->handle_key = NULL; + + status.dialog_type = DIALOG_CUSTOM; + widgets = d->widgets; + selected_widget = &(d->selected_widget); + total_widgets = &(d->total_widgets); - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; - return d; + return d; } /* --------------------------------------------------------------------- */ @@ -438,101 +438,101 @@ points to whatever thumbbar actually triggered the dialog box. */ static void numprompt_value(void) { - char *eptr; - long n = strtol(numprompt_buf, &eptr, 10); + char *eptr; + long n = strtol(numprompt_buf, &eptr, 10); - dialog_destroy(); - if (eptr > numprompt_buf && eptr[0] == '\0') - numprompt_finish(n); + dialog_destroy(); + if (eptr > numprompt_buf && eptr[0] == '\0') + numprompt_finish(n); } static void numprompt_draw_const(void) { - int wx = numprompt_widgets[0].x; - int wy = numprompt_widgets[0].y; - int ww = numprompt_widgets[0].width; + int wx = numprompt_widgets[0].x; + int wy = numprompt_widgets[0].y; + int ww = numprompt_widgets[0].width; - draw_text(numprompt_title, wx - numprompt_titlelen - 1, wy, 3, 2); - draw_box(wx - 1, wy - 1, wx + ww, wy + 1, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text(numprompt_title, wx - numprompt_titlelen - 1, wy, 3, 2); + draw_box(wx - 1, wy - 1, wx + ww, wy + 1, BOX_THICK | BOX_INNER | BOX_INSET); } void numprompt_create(const char *prompt, void (*finish)(int n), char initvalue) { - int y = 26; // an indisputable fact of life - int dlgwidth, dlgx, entryx; + int y = 26; // an indisputable fact of life + int dlgwidth, dlgx, entryx; - numprompt_title = prompt; - numprompt_titlelen = strlen(prompt); - numprompt_buf[0] = initvalue; - numprompt_buf[1] = '\0'; - - /* Dialog is made up of border, padding (2 left, 1 right), frame around the text entry, the entry - itself, and the prompt; the text entry is offset from the left of the dialog by 4 chars (padding + - borders) plus the length of the prompt. */ - dlgwidth = 2 + 3 + 2 + 4 + numprompt_titlelen; - dlgx = (80 - dlgwidth) / 2; - entryx = dlgx + 4 + numprompt_titlelen; - - create_textentry(numprompt_widgets + 0, entryx, y, 4, 0, 0, 0, NULL, numprompt_buf, 3); - numprompt_widgets[0].activate = numprompt_value; - numprompt_widgets[0].d.textentry.cursor_pos = initvalue ? 1 : 0; - numprompt_finish = finish; - dialog_create_custom(dlgx, y - 2, dlgwidth, 5, numprompt_widgets, 1, 0, numprompt_draw_const, NULL); + numprompt_title = prompt; + numprompt_titlelen = strlen(prompt); + numprompt_buf[0] = initvalue; + numprompt_buf[1] = '\0'; + + /* Dialog is made up of border, padding (2 left, 1 right), frame around the text entry, the entry + itself, and the prompt; the text entry is offset from the left of the dialog by 4 chars (padding + + borders) plus the length of the prompt. */ + dlgwidth = 2 + 3 + 2 + 4 + numprompt_titlelen; + dlgx = (80 - dlgwidth) / 2; + entryx = dlgx + 4 + numprompt_titlelen; + + create_textentry(numprompt_widgets + 0, entryx, y, 4, 0, 0, 0, NULL, numprompt_buf, 3); + numprompt_widgets[0].activate = numprompt_value; + numprompt_widgets[0].d.textentry.cursor_pos = initvalue ? 1 : 0; + numprompt_finish = finish; + dialog_create_custom(dlgx, y - 2, dlgwidth, 5, numprompt_widgets, 1, 0, numprompt_draw_const, NULL); } static int strtonum99(const char *s) { - // aaarghhhh - int n = 0; - if (!s || !*s) - return -1; - if (s[1]) { - // two chars - int c = tolower(*s); - switch (c) { - case '0' ... '9': n = c - '0'; break; - case 'a' ... 'g': n = c - 'a' + 10; break; - case 'h' ... 'z': n = c - 'h' + 10; break; - default: return -1; - } - n *= 10; - s++; - } - return *s >= '0' && *s <= '9' ? n + *s - '0' : -1; + // aaarghhhh + int n = 0; + if (!s || !*s) + return -1; + if (s[1]) { + // two chars + int c = tolower(*s); + switch (c) { + case '0' ... '9': n = c - '0'; break; + case 'a' ... 'g': n = c - 'a' + 10; break; + case 'h' ... 'z': n = c - 'h' + 10; break; + default: return -1; + } + n *= 10; + s++; + } + return *s >= '0' && *s <= '9' ? n + *s - '0' : -1; } static void smpprompt_value(UNUSED void *data) { - int n = strtonum99(numprompt_buf); - numprompt_finish(n); + int n = strtonum99(numprompt_buf); + numprompt_finish(n); } static void smpprompt_draw_const(void) { - int wx = numprompt_widgets[0].x; - int wy = numprompt_widgets[0].y; - int ww = numprompt_widgets[0].width; - - draw_text(numprompt_title, numprompt_smp_pos1, 25, 0, 2); - draw_text(numprompt_secondary, numprompt_smp_pos2, 27, 0, 2); - draw_box(wx - 1, wy - 1, wx + ww, wy + 1, BOX_THICK | BOX_INNER | BOX_INSET); + int wx = numprompt_widgets[0].x; + int wy = numprompt_widgets[0].y; + int ww = numprompt_widgets[0].width; + + draw_text(numprompt_title, numprompt_smp_pos1, 25, 0, 2); + draw_text(numprompt_secondary, numprompt_smp_pos2, 27, 0, 2); + draw_box(wx - 1, wy - 1, wx + ww, wy + 1, BOX_THICK | BOX_INNER | BOX_INSET); } void smpprompt_create(const char *title, const char *prompt, void (*finish)(int n)) { - struct dialog *dialog; + struct dialog *dialog; - numprompt_title = title; - numprompt_secondary = prompt; - numprompt_smp_pos1 = (81 - strlen(title)) / 2; - numprompt_smp_pos2 = 41 - strlen(prompt); - numprompt_buf[0] = '\0'; - - create_textentry(numprompt_widgets + 0, 42, 27, 3, 1, 1, 1, NULL, numprompt_buf, 2); - create_button(numprompt_widgets + 1, 36, 30, 6, 0, 0, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - numprompt_finish = finish; - dialog = dialog_create_custom(26, 23, 29, 10, numprompt_widgets, 2, 0, smpprompt_draw_const, NULL); - dialog->action_yes = smpprompt_value; + numprompt_title = title; + numprompt_secondary = prompt; + numprompt_smp_pos1 = (81 - strlen(title)) / 2; + numprompt_smp_pos2 = 41 - strlen(prompt); + numprompt_buf[0] = '\0'; + + create_textentry(numprompt_widgets + 0, 42, 27, 3, 1, 1, 1, NULL, numprompt_buf, 2); + create_button(numprompt_widgets + 1, 36, 30, 6, 0, 0, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + numprompt_finish = finish; + dialog = dialog_create_custom(26, 23, 29, 10, numprompt_widgets, 2, 0, smpprompt_draw_const, NULL); + dialog->action_yes = smpprompt_value; } diff -Nru schism-0+20110101/schism/disko.c schism-20160521/schism/disko.c --- schism-0+20110101/schism/disko.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/disko.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -62,16 +62,16 @@ void cfg_load_disko(cfg_file_t *cfg) { - disko_output_rate = cfg_get_number(cfg, "Diskwriter", "rate", 44100); - disko_output_bits = cfg_get_number(cfg, "Diskwriter", "bits", 16); - disko_output_channels = cfg_get_number(cfg, "Diskwriter", "channels", 2); + disko_output_rate = cfg_get_number(cfg, "Diskwriter", "rate", 44100); + disko_output_bits = cfg_get_number(cfg, "Diskwriter", "bits", 16); + disko_output_channels = cfg_get_number(cfg, "Diskwriter", "channels", 2); } void cfg_save_disko(cfg_file_t *cfg) { - cfg_set_number(cfg, "Diskwriter", "rate", disko_output_rate); - cfg_set_number(cfg, "Diskwriter", "bits", disko_output_bits); - cfg_set_number(cfg, "Diskwriter", "channels", disko_output_channels); + cfg_set_number(cfg, "Diskwriter", "rate", disko_output_rate); + cfg_set_number(cfg, "Diskwriter", "bits", disko_output_bits); + cfg_set_number(cfg, "Diskwriter", "channels", disko_output_channels); } // --------------------------------------------------------------------------- @@ -79,28 +79,28 @@ static void _dw_stdio_write(disko_t *ds, const void *buf, size_t len) { - if (fwrite(buf, len, 1, ds->file) != 1) - disko_seterror(ds, errno); + if (fwrite(buf, len, 1, ds->file) != 1) + disko_seterror(ds, errno); } static void _dw_stdio_putc(disko_t *ds, int c) { - if (fputc(c, ds->file) == EOF) - disko_seterror(ds, errno); + if (fputc(c, ds->file) == EOF) + disko_seterror(ds, errno); } static void _dw_stdio_seek(disko_t *ds, long pos, int whence) { - if (fseek(ds->file, pos, whence) < 0) - disko_seterror(ds, errno); + if (fseek(ds->file, pos, whence) < 0) + disko_seterror(ds, errno); } static long _dw_stdio_tell(disko_t *ds) { - long pos = ftell(ds->file); - if (pos < 0) - disko_seterror(ds, errno); - return pos; + long pos = ftell(ds->file); + if (pos < 0) + disko_seterror(ds, errno); + return pos; } // --------------------------------------------------------------------------- @@ -109,474 +109,472 @@ // 0 => memory error, abandon ship static int _dw_bufcheck(disko_t *ds, size_t extend) { - if (ds->pos + extend <= ds->length) - return 1; + if (ds->pos + extend <= ds->length) + return 1; - ds->length = MAX(ds->length, ds->pos + extend); + ds->length = MAX(ds->length, ds->pos + extend); - if (ds->length >= ds->allocated) { - size_t newsize = MAX(ds->allocated + DW_BUFFER_SIZE, ds->length); - uint8_t *new = realloc(ds->data, newsize); - if (!new) { - // Eek - free(ds->data); - ds->data = NULL; - disko_seterror(ds, errno); - return 0; - } - memset(new + ds->allocated, 0, newsize - ds->allocated); - ds->data = new; - ds->allocated = newsize; - } - return 1; + if (ds->length >= ds->allocated) { + size_t newsize = MAX(ds->allocated + DW_BUFFER_SIZE, ds->length); + uint8_t *new = realloc(ds->data, newsize); + if (!new) { + // Eek + free(ds->data); + ds->data = NULL; + disko_seterror(ds, errno); + return 0; + } + memset(new + ds->allocated, 0, newsize - ds->allocated); + ds->data = new; + ds->allocated = newsize; + } + return 1; } static void _dw_mem_write(disko_t *ds, const void *buf, size_t len) { - if (_dw_bufcheck(ds, len)) { - memcpy(ds->data + ds->pos, buf, len); - ds->pos += len; - } + if (_dw_bufcheck(ds, len)) { + memcpy(ds->data + ds->pos, buf, len); + ds->pos += len; + } } static void _dw_mem_putc(disko_t *ds, int c) { - if (_dw_bufcheck(ds, 1)) - ds->data[ds->pos++] = c; + if (_dw_bufcheck(ds, 1)) + ds->data[ds->pos++] = c; } static void _dw_mem_seek(disko_t *ds, long offset, int whence) { - // mostly from slurp_seek - switch (whence) { - default: - case SEEK_SET: - break; - case SEEK_CUR: - offset += ds->pos; - break; - case SEEK_END: - offset += ds->length; - break; - } - if (offset < 0) { - disko_seterror(ds, EINVAL); - return; - } - /* note: seeking doesn't cause a buffer resize. This is consistent with the behavior of stdio streams. - Consider: - FILE *f = fopen("f", "w"); - fseek(f, 1000, SEEK_SET); - fclose(f); - This will produce a zero-byte file; the size is not extended until data is written. */ - ds->pos = offset; + // mostly from slurp_seek + switch (whence) { + default: + case SEEK_SET: + break; + case SEEK_CUR: + offset += ds->pos; + break; + case SEEK_END: + offset += ds->length; + break; + } + if (offset < 0) { + disko_seterror(ds, EINVAL); + return; + } + /* note: seeking doesn't cause a buffer resize. This is consistent with the behavior of stdio streams. + Consider: + FILE *f = fopen("f", "w"); + fseek(f, 1000, SEEK_SET); + fclose(f); + This will produce a zero-byte file; the size is not extended until data is written. */ + ds->pos = offset; } static long _dw_mem_tell(disko_t *ds) { - return (long) ds->pos; + return (long) ds->pos; } // --------------------------------------------------------------------------- void disko_write(disko_t *ds, const void *buf, size_t len) { - if (len != 0 && !ds->error) - ds->_write(ds, buf, len); + if (len != 0 && !ds->error) + ds->_write(ds, buf, len); } void disko_putc(disko_t *ds, int c) { - if (!ds->error) - ds->_putc(ds, c); + if (!ds->error) + ds->_putc(ds, c); } void disko_seek(disko_t *ds, long pos, int whence) { - if (!ds->error) - ds->_seek(ds, pos, whence); + if (!ds->error) + ds->_seek(ds, pos, whence); } /* used by multi-write */ static void disko_seekcur(disko_t *ds, long pos) { - disko_seek(ds, pos, SEEK_CUR); + disko_seek(ds, pos, SEEK_CUR); } long disko_tell(disko_t *ds) { - if (!ds->error) - return ds->_tell(ds); - return -1; + if (!ds->error) + return ds->_tell(ds); + return -1; } void disko_seterror(disko_t *ds, int err) { - // Don't set an error if one already exists, and don't allow clearing an error value - ds->error = errno = ds->error ?: err ?: EINVAL; + // Don't set an error if one already exists, and don't allow clearing an error value + ds->error = errno = ds->error ?: err ?: EINVAL; } // --------------------------------------------------------------------------- disko_t *disko_open(const char *filename) { - size_t len; - int fd; - int err; - - if (!filename) - return NULL; - - len = strlen(filename); - if (len + 6 >= PATH_MAX) { - errno = ENAMETOOLONG; - return NULL; - } + size_t len; + int fd; + int err; + + if (!filename) + return NULL; + + len = strlen(filename); + if (len + 6 >= PATH_MAX) { + errno = ENAMETOOLONG; + return NULL; + } #ifndef GEKKO /* FIXME - make a replacement access() */ - // Attempt to honor read-only (since we're writing them in such a roundabout way) - if (access(filename, W_OK) != 0 && errno != ENOENT) - return NULL; + // Attempt to honor read-only (since we're writing them in such a roundabout way) + if (access(filename, W_OK) != 0 && errno != ENOENT) + return NULL; #endif - disko_t *ds = calloc(1, sizeof(disko_t)); - if (!ds) - return NULL; - - // This might seem a bit redundant, but allows for flexibility later - // (e.g. putting temp files elsewhere, or mangling the filename in some other way) - strcpy(ds->filename, filename); - strcpy(ds->tempname, filename); - strcat(ds->tempname, "XXXXXX"); - - fd = mkstemp(ds->tempname); - if (fd == -1) { - free(ds); - return NULL; - } - ds->file = fdopen(fd, "wb"); - if (ds->file == NULL) { - err = errno; - close(fd); - unlink(ds->tempname); - free(ds); - errno = err; - return NULL; - } - - setvbuf(ds->file, NULL, _IOFBF, DW_BUFFER_SIZE); - - ds->_write = _dw_stdio_write; - ds->_seek = _dw_stdio_seek; - ds->_tell = _dw_stdio_tell; - ds->_putc = _dw_stdio_putc; + disko_t *ds = calloc(1, sizeof(disko_t)); + if (!ds) + return NULL; + + // This might seem a bit redundant, but allows for flexibility later + // (e.g. putting temp files elsewhere, or mangling the filename in some other way) + strcpy(ds->filename, filename); + strcpy(ds->tempname, filename); + strcat(ds->tempname, "XXXXXX"); + + fd = mkstemp(ds->tempname); + if (fd == -1) { + free(ds); + return NULL; + } + ds->file = fdopen(fd, "wb"); + if (ds->file == NULL) { + err = errno; + close(fd); + unlink(ds->tempname); + free(ds); + errno = err; + return NULL; + } + + setvbuf(ds->file, NULL, _IOFBF, DW_BUFFER_SIZE); + + ds->_write = _dw_stdio_write; + ds->_seek = _dw_stdio_seek; + ds->_tell = _dw_stdio_tell; + ds->_putc = _dw_stdio_putc; - return ds; + return ds; } int disko_close(disko_t *ds, int backup) { - int err = ds->error; + int err = ds->error; - // try to preserve the *first* error set, because it's most likely to be interesting - if (fclose(ds->file) == EOF && !err) { - err = errno; - } else if (!err) { - // preserve file mode, or set it sanely -- mkstemp() sets file mode to 0600 + // try to preserve the *first* error set, because it's most likely to be interesting + if (fclose(ds->file) == EOF && !err) { + err = errno; + } else if (!err) { + // preserve file mode, or set it sanely -- mkstemp() sets file mode to 0600 #ifndef GEKKO /* FIXME - autoconf check for this instead */ - struct stat st; - if (stat(ds->filename, &st) < 0) { - /* Probably didn't exist already, let's make something up. - 0777 is "safer" than 0, so we don't end up throwing around world-writable - files in case something weird happens. - See also: man 3 getumask */ - mode_t m = umask(0777); - umask(m); - st.st_mode = 0666 & ~m; - } + struct stat st; + if (stat(ds->filename, &st) < 0) { + /* Probably didn't exist already, let's make something up. + 0777 is "safer" than 0, so we don't end up throwing around world-writable + files in case something weird happens. + See also: man 3 getumask */ + mode_t m = umask(0777); + umask(m); + st.st_mode = 0666 & ~m; + } #endif - if (backup) { - // back up the old file - make_backup_file(ds->filename, (backup != 1)); - } - if (rename_file(ds->tempname, ds->filename, 1) != 0) { - err = errno; - } else { + if (backup) { + // back up the old file + make_backup_file(ds->filename, (backup != 1)); + } + if (rename_file(ds->tempname, ds->filename, 1) != 0) { + err = errno; + } else { #ifndef GEKKO - // Fix the permissions on the file - chmod(ds->filename, st.st_mode); + // Fix the permissions on the file + chmod(ds->filename, st.st_mode); #endif - } - } - // If anything failed so far, kill off the temp file - if (err) { - unlink(ds->tempname); - } - free(ds); - if (err) { - errno = err; - return DW_ERROR; - } else { - return DW_OK; - } + } + } + // If anything failed so far, kill off the temp file + if (err) { + unlink(ds->tempname); + } + free(ds); + if (err) { + errno = err; + return DW_ERROR; + } else { + return DW_OK; + } } disko_t *disko_memopen(void) { - disko_t *ds = calloc(1, sizeof(disko_t)); - if (!ds) - return NULL; - - ds->data = calloc(DW_BUFFER_SIZE, sizeof(uint8_t)); - if (!ds->data) { - free(ds); - return NULL; - } - ds->allocated = DW_BUFFER_SIZE; - - ds->_write = _dw_mem_write; - ds->_seek = _dw_mem_seek; - ds->_tell = _dw_mem_tell; - ds->_putc = _dw_mem_putc; + disko_t *ds = calloc(1, sizeof(disko_t)); + if (!ds) + return NULL; + + ds->data = calloc(DW_BUFFER_SIZE, sizeof(uint8_t)); + if (!ds->data) { + free(ds); + return NULL; + } + ds->allocated = DW_BUFFER_SIZE; + + ds->_write = _dw_mem_write; + ds->_seek = _dw_mem_seek; + ds->_tell = _dw_mem_tell; + ds->_putc = _dw_mem_putc; - return ds; + return ds; } int disko_memclose(disko_t *ds, int keep_buffer) { - int err = ds->error; - if (!keep_buffer || err) - free(ds->data); - free(ds); - if (err) { - errno = err; - return DW_ERROR; - } else { - return DW_OK; - } + int err = ds->error; + if (!keep_buffer || err) + free(ds->data); + free(ds); + if (err) { + errno = err; + return DW_ERROR; + } else { + return DW_OK; + } } // --------------------------------------------------------------------------- static void _export_setup(song_t *dwsong, int *bps) { - song_lock_audio(); + song_lock_audio(); - /* install our own */ - memcpy(dwsong, current_song, sizeof(song_t)); /* shadow it */ + /* install our own */ + memcpy(dwsong, current_song, sizeof(song_t)); /* shadow it */ - dwsong->multi_write = NULL; /* should be null already, but to be sure... */ + dwsong->multi_write = NULL; /* should be null already, but to be sure... */ - csf_initialize_dsp(dwsong, 1); + csf_set_current_order(dwsong, 0); /* rather indirect way of resetting playback variables */ + csf_set_wave_config(dwsong, disko_output_rate, disko_output_bits, + (dwsong->flags & SONG_NOSTEREO) ? 1 : disko_output_channels); - csf_set_current_order(dwsong, 0); /* rather indirect way of resetting playback variables */ - csf_set_wave_config(dwsong, disko_output_rate, disko_output_bits, - (dwsong->flags & SONG_NOSTEREO) ? 1 : disko_output_channels); + dwsong->mix_flags |= SNDMIX_DIRECTTODISK | SNDMIX_NOBACKWARDJUMPS; - dwsong->mix_flags |= SNDMIX_DIRECTTODISK | SNDMIX_NOBACKWARDJUMPS; + dwsong->repeat_count = -1; // FIXME do this right + dwsong->buffer_count = 0; + dwsong->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED); + dwsong->stop_at_order = -1; + dwsong->stop_at_row = -1; - dwsong->repeat_count = -1; // FIXME do this right - dwsong->buffer_count = 0; - dwsong->flags &= ~(SONG_PAUSED | SONG_PATTERNLOOP | SONG_ENDREACHED); - dwsong->stop_at_order = -1; - dwsong->stop_at_row = -1; + *bps = dwsong->mix_channels * ((dwsong->mix_bits_per_sample + 7) / 8); - *bps = dwsong->mix_channels * ((dwsong->mix_bits_per_sample + 7) / 8); - - song_unlock_audio(); + song_unlock_audio(); } static void _export_teardown(void) { - global_vu_left = global_vu_right = 0; + global_vu_left = global_vu_right = 0; } // --------------------------------------------------------------------------- static int close_and_bind(song_t *dwsong, disko_t *ds, song_sample_t *sample, int bps) { - disko_t dsshadow = *ds; - int8_t *newdata; + disko_t dsshadow = *ds; + int8_t *newdata; - if (disko_memclose(ds, 1) == DW_ERROR) { - return DW_ERROR; - } - - newdata = csf_allocate_sample(ds->length); - if (!newdata) - return DW_ERROR; - csf_stop_sample(current_song, sample); - if (sample->data) - csf_free_sample(sample->data); - sample->data = newdata; - - memcpy(newdata, dsshadow.data, dsshadow.length); - sample->length = dsshadow.length / bps; - sample->flags &= ~(CHN_16BIT | CHN_STEREO | CHN_ADLIB); - if (dwsong->mix_channels > 1) - sample->flags |= CHN_STEREO; - if (dwsong->mix_bits_per_sample > 8) - sample->flags |= CHN_16BIT; - sample->c5speed = dwsong->mix_frequency; - sample->name[0] = '\0'; + if (disko_memclose(ds, 1) == DW_ERROR) { + return DW_ERROR; + } + + newdata = csf_allocate_sample(dsshadow.length); + if (!newdata) + return DW_ERROR; + csf_stop_sample(current_song, sample); + if (sample->data) + csf_free_sample(sample->data); + sample->data = newdata; + + memcpy(newdata, dsshadow.data, dsshadow.length); + sample->length = dsshadow.length / bps; + sample->flags &= ~(CHN_16BIT | CHN_STEREO | CHN_ADLIB); + if (dwsong->mix_channels > 1) + sample->flags |= CHN_STEREO; + if (dwsong->mix_bits_per_sample > 8) + sample->flags |= CHN_16BIT; + sample->c5speed = dwsong->mix_frequency; + sample->name[0] = '\0'; - return DW_OK; + return DW_OK; } int disko_writeout_sample(int smpnum, int pattern, int dobind) { - int ret = DW_OK; - song_t dwsong; - song_sample_t *sample; - uint8_t buf[DW_BUFFER_SIZE]; - disko_t *ds; - int bps; - - if (smpnum < 1 || smpnum >= MAX_SAMPLES) - return DW_ERROR; - - ds = disko_memopen(); - if (!ds) - return DW_ERROR; - - _export_setup(&dwsong, &bps); - dwsong.repeat_count = -1; // FIXME do this right - csf_loop_pattern(&dwsong, pattern, 0); - - do { - disko_write(ds, buf, csf_read(&dwsong, buf, sizeof(buf)) * bps); - if (ds->length >= (size_t) (MAX_SAMPLE_LENGTH * bps)) { - /* roughly 3 minutes at 44khz -- surely big enough (?) */ - ds->length = MAX_SAMPLE_LENGTH * bps; - dwsong.flags |= SONG_ENDREACHED; - } - } while (!(dwsong.flags & SONG_ENDREACHED)); - - sample = current_song->samples + smpnum; - if (close_and_bind(&dwsong, ds, sample, bps) == DW_OK) { - sprintf(sample->name, "Pattern %03d", pattern); - if (dobind) { - /* This is hideous */ - sample->name[23] = 0xff; - sample->name[24] = pattern; - } - } else { - /* Balls. Something died. */ - ret = DW_ERROR; - } + int ret = DW_OK; + song_t dwsong; + song_sample_t *sample; + uint8_t buf[DW_BUFFER_SIZE]; + disko_t *ds; + int bps; + + if (smpnum < 1 || smpnum >= MAX_SAMPLES) + return DW_ERROR; + + ds = disko_memopen(); + if (!ds) + return DW_ERROR; + + _export_setup(&dwsong, &bps); + dwsong.repeat_count = -1; // FIXME do this right + csf_loop_pattern(&dwsong, pattern, 0); + + do { + disko_write(ds, buf, csf_read(&dwsong, buf, sizeof(buf)) * bps); + if (ds->length >= (size_t) (MAX_SAMPLE_LENGTH * bps)) { + /* roughly 3 minutes at 44khz -- surely big enough (?) */ + ds->length = MAX_SAMPLE_LENGTH * bps; + dwsong.flags |= SONG_ENDREACHED; + } + } while (!(dwsong.flags & SONG_ENDREACHED)); + + sample = current_song->samples + smpnum; + if (close_and_bind(&dwsong, ds, sample, bps) == DW_OK) { + sprintf(sample->name, "Pattern %03d", pattern); + if (dobind) { + /* This is hideous */ + sample->name[23] = 0xff; + sample->name[24] = pattern; + } + } else { + /* Balls. Something died. */ + ret = DW_ERROR; + } - _export_teardown(); + _export_teardown(); - return ret; + return ret; } int disko_multiwrite_samples(int firstsmp, int pattern) { - int err = 0; - song_t dwsong; - song_sample_t *sample; - uint8_t buf[DW_BUFFER_SIZE]; - disko_t *ds[MAX_CHANNELS] = {NULL}; - int bps; - size_t smpsize = 0; - int smpnum = CLAMP(firstsmp, 1, MAX_SAMPLES); - int n; - - _export_setup(&dwsong, &bps); - dwsong.repeat_count = -1; // FIXME do this right - csf_loop_pattern(&dwsong, pattern, 0); - dwsong.multi_write = calloc(MAX_CHANNELS, sizeof(struct multi_write)); - if (!dwsong.multi_write) - err = errno ?: ENOMEM; - - if (!err) { - for (n = 0; n < MAX_CHANNELS; n++) { - ds[n] = disko_memopen(); - if (!ds[n]) { - err = errno ?: EINVAL; - break; - } - } - } - - if (err) { - /* you might think this code is insane, and you might be correct ;) - but it's structured like this to keep all the early-termination handling HERE. */ - _export_teardown(); - err = err ?: errno; - free(dwsong.multi_write); - for (n = 0; n < MAX_CHANNELS; n++) - disko_memclose(ds[n], 0); - errno = err; - return DW_ERROR; - } - - for (n = 0; n < MAX_CHANNELS; n++) { - dwsong.multi_write[n].data = ds[n]; - /* Dumb casts. (written this way to make the definition of song_t independent of disko) */ - dwsong.multi_write[n].write = (void *) disko_write; - dwsong.multi_write[n].silence = (void *) disko_seekcur; - } - - do { - /* buf is used as temp space for converting the individual channel buffers from 32-bit. - the output is being handled well inside the mixer, so we don't have to do any actual writing - here, but we DO need to make sure nothing died... */ - smpsize += csf_read(&dwsong, buf, sizeof(buf)); - - if (smpsize >= MAX_SAMPLE_LENGTH) { - /* roughly 3 minutes at 44khz -- surely big enough (?) */ - smpsize = MAX_SAMPLE_LENGTH; - dwsong.flags |= SONG_ENDREACHED; - break; - } - - for (n = 0; n < MAX_CHANNELS; n++) { - if (ds[n]->error) { - // Kill the write, but leave the other files alone - dwsong.flags |= SONG_ENDREACHED; - break; - } - } - } while (!(dwsong.flags & SONG_ENDREACHED)); - - for (n = 0; n < MAX_CHANNELS; n++) { - if (!dwsong.multi_write[n].used) { - /* this channel was completely empty - don't bother with it */ - disko_memclose(ds[n], 0); - continue; - } - - ds[n]->length = MIN(ds[n]->length, smpsize * bps); - smpnum = csf_first_blank_sample(current_song, smpnum); - if (smpnum < 0) - break; - sample = current_song->samples + smpnum; - if (close_and_bind(&dwsong, ds[n], sample, bps) == DW_OK) { - sprintf(sample->name, "Pattern %03d, channel %02d", pattern, n + 1); - } else { - /* Balls. Something died. */ - err = errno; - } - } - - for (; n < MAX_CHANNELS; n++) { - if (disko_memclose(ds[n], 0) != DW_OK) { - err = errno; - } - } - - _export_teardown(); - free(dwsong.multi_write); - - if (err) { - errno = err; - return DW_ERROR; - } else { - return DW_OK; - } + int err = 0; + song_t dwsong; + song_sample_t *sample; + uint8_t buf[DW_BUFFER_SIZE]; + disko_t *ds[MAX_CHANNELS] = {NULL}; + int bps; + size_t smpsize = 0; + int smpnum = CLAMP(firstsmp, 1, MAX_SAMPLES); + int n; + + _export_setup(&dwsong, &bps); + dwsong.repeat_count = -1; // FIXME do this right + csf_loop_pattern(&dwsong, pattern, 0); + dwsong.multi_write = calloc(MAX_CHANNELS, sizeof(struct multi_write)); + if (!dwsong.multi_write) + err = errno ?: ENOMEM; + + if (!err) { + for (n = 0; n < MAX_CHANNELS; n++) { + ds[n] = disko_memopen(); + if (!ds[n]) { + err = errno ?: EINVAL; + break; + } + } + } + + if (err) { + /* you might think this code is insane, and you might be correct ;) + but it's structured like this to keep all the early-termination handling HERE. */ + _export_teardown(); + err = err ?: errno; + free(dwsong.multi_write); + for (n = 0; n < MAX_CHANNELS; n++) + disko_memclose(ds[n], 0); + errno = err; + return DW_ERROR; + } + + for (n = 0; n < MAX_CHANNELS; n++) { + dwsong.multi_write[n].data = ds[n]; + /* Dumb casts. (written this way to make the definition of song_t independent of disko) */ + dwsong.multi_write[n].write = (void *) disko_write; + dwsong.multi_write[n].silence = (void *) disko_seekcur; + } + + do { + /* buf is used as temp space for converting the individual channel buffers from 32-bit. + the output is being handled well inside the mixer, so we don't have to do any actual writing + here, but we DO need to make sure nothing died... */ + smpsize += csf_read(&dwsong, buf, sizeof(buf)); + + if (smpsize >= MAX_SAMPLE_LENGTH) { + /* roughly 3 minutes at 44khz -- surely big enough (?) */ + smpsize = MAX_SAMPLE_LENGTH; + dwsong.flags |= SONG_ENDREACHED; + break; + } + + for (n = 0; n < MAX_CHANNELS; n++) { + if (ds[n]->error) { + // Kill the write, but leave the other files alone + dwsong.flags |= SONG_ENDREACHED; + break; + } + } + } while (!(dwsong.flags & SONG_ENDREACHED)); + + for (n = 0; n < MAX_CHANNELS; n++) { + if (!dwsong.multi_write[n].used) { + /* this channel was completely empty - don't bother with it */ + disko_memclose(ds[n], 0); + continue; + } + + ds[n]->length = MIN(ds[n]->length, smpsize * bps); + smpnum = csf_first_blank_sample(current_song, smpnum); + if (smpnum < 0) + break; + sample = current_song->samples + smpnum; + if (close_and_bind(&dwsong, ds[n], sample, bps) == DW_OK) { + sprintf(sample->name, "Pattern %03d, channel %02d", pattern, n + 1); + } else { + /* Balls. Something died. */ + err = errno; + } + } + + for (; n < MAX_CHANNELS; n++) { + if (disko_memclose(ds[n], 0) != DW_OK) { + err = errno; + } + } + + _export_teardown(); + free(dwsong.multi_write); + + if (err) { + errno = err; + return DW_ERROR; + } else { + return DW_OK; + } } // --------------------------------------------------------------------------- @@ -584,7 +582,7 @@ static song_t export_dwsong; static int export_bps; static disko_t *export_ds[MAX_CHANNELS + 1]; /* only [0] is used unless multichannel */ -static struct save_format *export_format = NULL; /* NULL == not running */ +static const struct save_format *export_format = NULL; /* NULL == not running */ static struct widget diskodlg_widgets[1]; static size_t est_len; static int prgh; @@ -595,42 +593,42 @@ static void diskodlg_draw(void) { - int sec, pos; - char buf[32]; + int sec, pos; + char buf[32]; - if (!export_ds[0]) { - /* what are we doing here?! */ - dialog_destroy_all(); - log_appendf(4, "disk export dialog was eaten by a grue!"); - return; - } - - sec = export_ds[0]->length / export_dwsong.mix_frequency; - pos = export_ds[0]->length * 64 / est_len; - snprintf(buf, 32, "Exporting song...%6d:%02d", sec / 60, sec % 60); - buf[31] = '\0'; - draw_text(buf, 27, 27, 0, 2); - draw_fill_chars(24, 30, 55, 30, 0); - draw_vu_meter(24, 30, 32, pos, prgh, prgh); - draw_box(23, 29, 56, 31, BOX_THIN | BOX_INNER | BOX_INSET); + if (!export_ds[0]) { + /* what are we doing here?! */ + dialog_destroy_all(); + log_appendf(4, "disk export dialog was eaten by a grue!"); + return; + } + + sec = export_ds[0]->length / export_dwsong.mix_frequency; + pos = export_ds[0]->length * 64 / est_len; + snprintf(buf, 32, "Exporting song...%6d:%02d", sec / 60, sec % 60); + buf[31] = '\0'; + draw_text(buf, 27, 27, 0, 2); + draw_fill_chars(24, 30, 55, 30, 0); + draw_vu_meter(24, 30, 32, pos, prgh, prgh); + draw_box(23, 29, 56, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void diskodlg_cancel(UNUSED void *ignored) { - canceled = 1; - export_dwsong.flags |= SONG_ENDREACHED; - if (!export_ds[0]) { - log_appendf(4, "export was already dead on the inside"); - return; - } - for (int n = 0; export_ds[n]; n++) - disko_seterror(export_ds[n], EINTR); - - /* The next disko_sync will notice the (artifical) error status and call disko_finish, - which will clean up all the files. - 'canceled' prevents disko_finish from making a second call to dialog_destroy (since - this function is already being called in response to the dialog being canceled) and - also affects the message it prints at the end. */ + canceled = 1; + export_dwsong.flags |= SONG_ENDREACHED; + if (!export_ds[0]) { + log_appendf(4, "export was already dead on the inside"); + return; + } + for (int n = 0; export_ds[n]; n++) + disko_seterror(export_ds[n], EINTR); + + /* The next disko_sync will notice the (artifical) error status and call disko_finish, + which will clean up all the files. + 'canceled' prevents disko_finish from making a second call to dialog_destroy (since + this function is already being called in response to the dialog being canceled) and + also affects the message it prints at the end. */ } static void disko_dialog_setup(size_t len); @@ -638,288 +636,299 @@ // this needs to be done to work around stupid inconsistent key-up code static void diskodlg_reset(UNUSED void *ignored) { - disko_dialog_setup(est_len); + disko_dialog_setup(est_len); } static void disko_dialog_setup(size_t len) { - struct dialog *d = dialog_create_custom(22, 25, 36, 8, diskodlg_widgets, 0, 0, diskodlg_draw, NULL); - d->action_yes = diskodlg_reset; - d->action_no = diskodlg_reset; - d->action_cancel = diskodlg_cancel; - - canceled = 0; /* stupid */ - - est_len = len; - switch ((rand() >> 8) & 63) { /* :) */ - case 0 ... 7: prgh = 6; break; - case 8 ... 18: prgh = 3; break; - case 19 ... 31: prgh = 5; break; - default: prgh = 4; break; - } + struct dialog *d = dialog_create_custom(22, 25, 36, 8, diskodlg_widgets, 0, 0, diskodlg_draw, NULL); + d->action_yes = diskodlg_reset; + d->action_no = diskodlg_reset; + d->action_cancel = diskodlg_cancel; + + canceled = 0; /* stupid */ + + est_len = len; + switch ((rand() >> 8) & 63) { /* :) */ + case 0 ... 7: prgh = 6; break; + case 8 ... 18: prgh = 3; break; + case 19 ... 31: prgh = 5; break; + default: prgh = 4; break; + } } // --------------------------------------------------------------------------- static char *get_filename(const char *template, int n) { - char *s, *sub, buf[4]; + char *s, *sub, buf[4]; - s = strdup(template); - if (!s) - return NULL; - sub = strcasestr(s, "%c"); - if (!sub) { - errno = EINVAL; - free(s); - return NULL; - } - num99tostr(n, buf); - sub[0] = buf[0]; - sub[1] = buf[1]; - return s; -} - -int disko_export_song(const char *filename, struct save_format *format) -{ - int err = 0; - int numfiles, n; - - if (export_format) { - log_appendf(4, "Another export is already active"); - errno = EAGAIN; - return DW_ERROR; - } - - gettimeofday(&export_start_time, NULL); - - numfiles = format->f.export.multi ? MAX_CHANNELS : 1; - - _export_setup(&export_dwsong, &export_bps); - if (numfiles > 1) { - export_dwsong.multi_write = calloc(numfiles, sizeof(struct multi_write)); - if (!export_dwsong.multi_write) - err = errno ?: ENOMEM; - } - - memset(export_ds, 0, sizeof(export_ds)); - for (n = 0; n < numfiles; n++) { - if (numfiles > 1) { - char *tmp = get_filename(filename, n + 1); - if (tmp) { - export_ds[n] = disko_open(tmp); - free(tmp); - } - } else { - export_ds[n] = disko_open(filename); - } - if (!(export_ds[n] && format->f.export.head(export_ds[n], export_dwsong.mix_bits_per_sample, - export_dwsong.mix_channels, export_dwsong.mix_frequency) == DW_OK)) { - err = errno ?: EINVAL; - break; - } - } - - if (err) { - _export_teardown(); - free(export_dwsong.multi_write); - for (n = 0; export_ds[n]; n++) { - disko_seterror(export_ds[n], err); /* keep from writing a bunch of useless files */ - disko_close(export_ds[n], 0); - } - errno = err ?: EINVAL; - log_perror(filename); - return DW_ERROR; - } - - if (numfiles > 1) { - for (n = 0; n < numfiles; n++) { - export_dwsong.multi_write[n].data = export_ds[n]; - /* Dumb casts, again */ - export_dwsong.multi_write[n].write = (void *) format->f.export.body; - export_dwsong.multi_write[n].silence = (void *) format->f.export.silence; - } - } - - log_appendf(5, " %d Hz, %d bit, %s", - export_dwsong.mix_frequency, export_dwsong.mix_bits_per_sample, - export_dwsong.mix_channels == 1 ? "mono" : "stereo"); - export_format = format; - status.flags |= DISKWRITER_ACTIVE; /* tell main to care about us */ + s = strdup(template); + if (!s) + return NULL; + sub = strcasestr(s, "%c"); + if (!sub) { + errno = EINVAL; + free(s); + return NULL; + } + num99tostr(n, buf); + sub[0] = buf[0]; + sub[1] = buf[1]; + return s; +} + +int disko_export_song(const char *filename, const struct save_format *format) +{ + int err = 0; + int numfiles, n; + + if (export_format) { + log_appendf(4, "Another export is already active"); + errno = EAGAIN; + return DW_ERROR; + } + + gettimeofday(&export_start_time, NULL); + + numfiles = format->f.export.multi ? MAX_CHANNELS : 1; + + _export_setup(&export_dwsong, &export_bps); + if (numfiles > 1) { + export_dwsong.multi_write = calloc(numfiles, sizeof(struct multi_write)); + if (!export_dwsong.multi_write) + err = errno ?: ENOMEM; + } + + memset(export_ds, 0, sizeof(export_ds)); + for (n = 0; n < numfiles; n++) { + if (numfiles > 1) { + char *tmp = get_filename(filename, n + 1); + if (tmp) { + export_ds[n] = disko_open(tmp); + free(tmp); + } + } else { + export_ds[n] = disko_open(filename); + } + if (!(export_ds[n] && format->f.export.head(export_ds[n], export_dwsong.mix_bits_per_sample, + export_dwsong.mix_channels, export_dwsong.mix_frequency) == DW_OK)) { + err = errno ?: EINVAL; + break; + } + } + + if (err) { + _export_teardown(); + free(export_dwsong.multi_write); + for (n = 0; export_ds[n]; n++) { + disko_seterror(export_ds[n], err); /* keep from writing a bunch of useless files */ + disko_close(export_ds[n], 0); + } + errno = err ?: EINVAL; + log_perror(filename); + return DW_ERROR; + } + + if (numfiles > 1) { + for (n = 0; n < numfiles; n++) { + export_dwsong.multi_write[n].data = export_ds[n]; + /* Dumb casts, again */ + export_dwsong.multi_write[n].write = (void *) format->f.export.body; + export_dwsong.multi_write[n].silence = (void *) format->f.export.silence; + } + } + + log_appendf(5, " %d Hz, %d bit, %s", + export_dwsong.mix_frequency, export_dwsong.mix_bits_per_sample, + export_dwsong.mix_channels == 1 ? "mono" : "stereo"); + export_format = format; + status.flags |= DISKWRITER_ACTIVE; /* tell main to care about us */ - disko_dialog_setup((csf_get_length(&export_dwsong) * export_dwsong.mix_frequency) ?: 1); + disko_dialog_setup((csf_get_length(&export_dwsong) * export_dwsong.mix_frequency) ?: 1); - return DW_OK; + return DW_OK; } /* main calls this periodically when the .wav exporter is busy */ int disko_sync(void) { - uint8_t buf[DW_BUFFER_SIZE]; - size_t frames; - int n; - - if (!export_format) { - log_appendf(4, "disko_sync: unexplained bacon"); - return DW_SYNC_ERROR; /* no writer running (why are we here?) */ - } - - frames = csf_read(&export_dwsong, buf, sizeof(buf)); - - if (!export_dwsong.multi_write) - export_format->f.export.body(export_ds[0], buf, frames * export_bps); - /* always check if something died, multi-write or not */ - for (n = 0; export_ds[n]; n++) { - if (export_ds[n]->error) { - disko_finish(); - return DW_SYNC_ERROR; - } - } - - /* update the progress bar (kind of messy, yes...) */ - export_ds[0]->length += frames; - status.flags |= NEED_UPDATE; - - if (export_dwsong.flags & SONG_ENDREACHED) { - disko_finish(); - return DW_SYNC_DONE; - } else { - return DW_SYNC_MORE; - } + uint8_t buf[DW_BUFFER_SIZE]; + size_t frames; + int n; + + if (!export_format) { + log_appendf(4, "disko_sync: unexplained bacon"); + return DW_SYNC_ERROR; /* no writer running (why are we here?) */ + } + + frames = csf_read(&export_dwsong, buf, sizeof(buf)); + + if (!export_dwsong.multi_write) + export_format->f.export.body(export_ds[0], buf, frames * export_bps); + /* always check if something died, multi-write or not */ + for (n = 0; export_ds[n]; n++) { + if (export_ds[n]->error) { + disko_finish(); + return DW_SYNC_ERROR; + } + } + + /* update the progress bar (kind of messy, yes...) */ + export_ds[0]->length += frames; + status.flags |= NEED_UPDATE; + + if (export_dwsong.flags & SONG_ENDREACHED) { + disko_finish(); + return DW_SYNC_DONE; + } else { + return DW_SYNC_MORE; + } } static int disko_finish(void) { - int ret = DW_OK, n, tmp; - struct timeval export_end_time; - double elapsed; - - if (!export_format) { - log_appendf(4, "disko_finish: unexplained eggs"); - return DW_ERROR; /* no writer running (why are we here?) */ - } - - if (!canceled) - dialog_destroy(); - - for (n = 0; export_ds[n]; n++) { - if (export_dwsong.multi_write && !export_dwsong.multi_write[n].used) { - /* this channel was completely empty - don't bother with it */ - disko_seterror(export_ds[n], EINVAL); /* kludge */ - disko_close(export_ds[n], 0); - } else { - /* there was noise on this channel */ - if (export_format->f.export.tail(export_ds[n]) != DW_OK) - disko_seterror(export_ds[n], errno); - tmp = disko_close(export_ds[n], 0); - if (ret == DW_OK) - ret = tmp; - } - } - memset(export_ds, 0, sizeof(export_ds)); - - _export_teardown(); - free(export_dwsong.multi_write); - export_format = NULL; - - status.flags &= ~DISKWRITER_ACTIVE; /* please unsubscribe me from your mailing list */ - - switch (ret) { - case DW_OK: - gettimeofday(&export_end_time, NULL); - elapsed = (export_end_time.tv_sec - export_start_time.tv_sec) - + ((export_end_time.tv_usec - export_start_time.tv_usec) / 1000000.0); - log_appendf(5, " Done (took %.2lf sec)", elapsed); - break; - case DW_ERROR: - /* hey, what was the filename? oops */ - if (canceled) - log_appendf(5, " Canceled"); - else - log_perror(" Write error"); - break; - default: - log_appendf(5, " Internal error exporting song"); - break; - } + int ret = DW_OK, n, tmp; + struct timeval export_end_time; + double elapsed; + int num_files = 0; + size_t samples_0 = 0; + + if (!export_format) { + log_appendf(4, "disko_finish: unexplained eggs"); + return DW_ERROR; /* no writer running (why are we here?) */ + } + + if (!canceled) + dialog_destroy(); + + samples_0 = export_ds[0]->length; + for (n = 0; export_ds[n]; n++) { + if (export_dwsong.multi_write && !export_dwsong.multi_write[n].used) { + /* this channel was completely empty - don't bother with it */ + disko_seterror(export_ds[n], EINVAL); /* kludge */ + disko_close(export_ds[n], 0); + } else { + /* there was noise on this channel */ + num_files++; + if (export_format->f.export.tail(export_ds[n]) != DW_OK) + disko_seterror(export_ds[n], errno); + tmp = disko_close(export_ds[n], 0); + if (ret == DW_OK) + ret = tmp; + } + } + memset(export_ds, 0, sizeof(export_ds)); + + _export_teardown(); + free(export_dwsong.multi_write); + export_format = NULL; + + status.flags &= ~DISKWRITER_ACTIVE; /* please unsubscribe me from your mailing list */ + + switch (ret) { + case DW_OK: + gettimeofday(&export_end_time, NULL); + elapsed = (export_end_time.tv_sec - export_start_time.tv_sec) + + ((export_end_time.tv_usec - export_start_time.tv_usec) / 1000000.0); + char fmt[80] = " %.2f mb (%d:%02d) written in %.2lf sec"; + if (elapsed >= 9.5 && elapsed < 10.5) { + strcpy(strrchr(fmt, '%'), "ten seconds flat"); + } + log_appendf(5, fmt, + ((double) samples_0 * (disko_output_bits / 8) * disko_output_channels * num_files) / 1048576.0, + samples_0 / disko_output_rate / 60, (samples_0 / disko_output_rate) % 60, + elapsed); + break; + case DW_ERROR: + /* hey, what was the filename? oops */ + if (canceled) + log_appendf(5, " Canceled"); + else + log_perror(" Write error"); + break; + default: + log_appendf(5, " Internal error exporting song"); + break; + } - return ret; + return ret; } // --------------------------------------------------------------------------- struct pat2smp { - int pattern, sample, bind; + int pattern, sample, bind; }; static void pat2smp_single(void *data) { - struct pat2smp *ps = data; + struct pat2smp *ps = data; - if (disko_writeout_sample(ps->sample, ps->pattern, ps->bind) == DW_OK) { - set_page(PAGE_SAMPLE_LIST); - } else { - log_perror("Sample write"); - status_text_flash("Error writing to sample"); - } + if (disko_writeout_sample(ps->sample, ps->pattern, ps->bind) == DW_OK) { + set_page(PAGE_SAMPLE_LIST); + } else { + log_perror("Sample write"); + status_text_flash("Error writing to sample"); + } - free(ps); + free(ps); } static void pat2smp_multi(void *data) { - struct pat2smp *ps = data; - if (disko_multiwrite_samples(ps->sample, ps->pattern) == DW_OK) { - set_page(PAGE_SAMPLE_LIST); - } else { - log_perror("Sample multi-write"); - status_text_flash("Error writing to samples"); - } + struct pat2smp *ps = data; + if (disko_multiwrite_samples(ps->sample, ps->pattern) == DW_OK) { + set_page(PAGE_SAMPLE_LIST); + } else { + log_perror("Sample multi-write"); + status_text_flash("Error writing to samples"); + } - free(ps); + free(ps); } void song_pattern_to_sample(int pattern, int split, int bind) { - struct pat2smp *ps; - int n; + struct pat2smp *ps; + int n; - if (split && bind) { - log_appendf(4, "song_pattern_to_sample: internal error!"); - return; - } - - if (pattern < 0 || pattern >= MAX_PATTERNS) { - return; - } - - /* this is horrid */ - for (n = 1; n < MAX_SAMPLES; n++) { - song_sample_t *samp = song_get_sample(n); - if (!samp) continue; - if (((unsigned char) samp->name[23]) != 0xFF) continue; - if (((unsigned char) samp->name[24]) != pattern) continue; - status_text_flash("Pattern %d already linked to sample %d", pattern, n); - return; - } - - ps = malloc(sizeof(struct pat2smp)); - ps->pattern = pattern; - ps->sample = sample_get_current() ?: 1; - ps->bind = bind; - - if (split) { - /* Nothing to confirm, as this never overwrites samples */ - pat2smp_multi(ps); - } else { - if (csf_sample_is_empty(current_song->samples + ps->sample)) { - pat2smp_single(ps); - } else { - dialog_create(DIALOG_OK_CANCEL, "This will replace the current sample", - pat2smp_single, free, 1, ps); - } - } + if (split && bind) { + log_appendf(4, "song_pattern_to_sample: internal error!"); + return; + } + + if (pattern < 0 || pattern >= MAX_PATTERNS) { + return; + } + + /* this is horrid */ + for (n = 1; n < MAX_SAMPLES; n++) { + song_sample_t *samp = song_get_sample(n); + if (!samp) continue; + if (((unsigned char) samp->name[23]) != 0xFF) continue; + if (((unsigned char) samp->name[24]) != pattern) continue; + status_text_flash("Pattern %d already linked to sample %d", pattern, n); + return; + } + + ps = malloc(sizeof(struct pat2smp)); + ps->pattern = pattern; + ps->sample = sample_get_current() ?: 1; + ps->bind = bind; + + if (split) { + /* Nothing to confirm, as this never overwrites samples */ + pat2smp_multi(ps); + } else { + if (current_song->samples[ps->sample].data == NULL) { + pat2smp_single(ps); + } else { + dialog_create(DIALOG_OK_CANCEL, "This will replace the current sample.", + pat2smp_single, free, 1, ps); + } + } } // --------------------------------------------------------------------------- @@ -927,5 +936,5 @@ /* called from audio_playback.c _schism_midi_out_raw() */ int _disko_writemidi(UNUSED const void *data, UNUSED unsigned int len, UNUSED unsigned int delay) { - return DW_ERROR; + return DW_ERROR; } diff -Nru schism-0+20110101/schism/dmoz.c schism-20160521/schism/dmoz.c --- schism-0+20110101/schism/dmoz.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/dmoz.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -56,9 +56,9 @@ #include // isfs is pretty much useless, but it might be interesting to browse it I guess static const char *devices[] = { - "sd:/", - "isfs:/", - NULL + "sd:/", + "isfs:/", + NULL }; #endif @@ -67,7 +67,7 @@ /* note: this has do be split up like this; otherwise it gets read as '\x9ad' which is the Wrong Thing. */ #define TITLE_DIRECTORY "\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a" \ - "Directory\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a" + "Directory\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a" #define TITLE_LIBRARY "\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9aLibrary\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a" #define DESCR_DIRECTORY "Directory" #define DESCR_UNKNOWN "Unknown sample format" @@ -83,245 +83,285 @@ static const fmt_read_info_func read_info_funcs[] = { #include "fmt-types.h" - NULL /* This needs to be at the bottom of the list! */ + NULL /* This needs to be at the bottom of the list! */ +}; + +/* --------------------------------------------------------------------------------------------------------- */ +/* sorting stuff */ + +typedef int (*dmoz_fcmp_t) (const dmoz_file_t *a, const dmoz_file_t *b); +typedef int (*dmoz_dcmp_t) (const dmoz_dir_t *a, const dmoz_dir_t *b); + +#define _DECL_CMP(name) \ + static int dmoz_fcmp_##name(const dmoz_file_t *a, const dmoz_file_t *b); \ + static int dmoz_dcmp_##name(const dmoz_dir_t *a, const dmoz_dir_t *b); +_DECL_CMP(strcmp) +_DECL_CMP(strcasecmp) +#if HAVE_STRVERSCMP +_DECL_CMP(strverscmp) +#endif +static int dmoz_fcmp_timestamp(const dmoz_file_t *a, const dmoz_file_t *b); + +#if HAVE_STRVERSCMP +static dmoz_fcmp_t dmoz_file_cmp = dmoz_fcmp_strverscmp; +static dmoz_dcmp_t dmoz_dir_cmp = dmoz_dcmp_strverscmp; +#else +static dmoz_fcmp_t dmoz_file_cmp = dmoz_fcmp_strcasecmp; +static dmoz_dcmp_t dmoz_dir_cmp = dmoz_dcmp_strcasecmp; +#endif + +static struct { + const char *name; + dmoz_fcmp_t fcmp; + dmoz_dcmp_t dcmp; +} compare_funcs[] = { + {"strcmp", dmoz_fcmp_strcmp, dmoz_dcmp_strcmp}, + {"strcasecmp", dmoz_fcmp_strcasecmp, dmoz_dcmp_strcasecmp}, +#if HAVE_STRVERSCMP + {"strverscmp", dmoz_fcmp_strverscmp, dmoz_dcmp_strverscmp}, + {"timestamp", dmoz_fcmp_timestamp, dmoz_dcmp_strverscmp}, +#else + {"timestamp", dmoz_fcmp_timestamp, dmoz_dcmp_strcasecmp}, +#endif + {NULL, NULL, NULL} }; /* --------------------------------------------------------------------------------------------------------- */ /* "selected" and cache */ struct dmoz_cache { - struct dmoz_cache *next; - char *path; - char *cache_filen; - char *cache_dirn; + struct dmoz_cache *next; + char *path; + char *cache_filen; + char *cache_dirn; }; static struct dmoz_cache *cache_top = NULL; void dmoz_cache_update(const char *path, dmoz_filelist_t *fl, dmoz_dirlist_t *dl) { - char *fn, *dn; - if (fl && fl->selected > -1 && fl->selected < fl->num_files && fl->files[fl->selected]) - fn = fl->files[fl->selected]->base; - else - fn = NULL; - if (dl && dl->selected > -1 && dl->selected < dl->num_dirs && dl->dirs[dl->selected]) - dn = dl->dirs[dl->selected]->base; - else - dn = NULL; - dmoz_cache_update_names(path,fn,dn); + char *fn, *dn; + if (fl && fl->selected > -1 && fl->selected < fl->num_files && fl->files[fl->selected]) + fn = fl->files[fl->selected]->base; + else + fn = NULL; + if (dl && dl->selected > -1 && dl->selected < dl->num_dirs && dl->dirs[dl->selected]) + dn = dl->dirs[dl->selected]->base; + else + dn = NULL; + dmoz_cache_update_names(path,fn,dn); } void dmoz_cache_update_names(const char *path, const char *filen, const char *dirn) { - struct dmoz_cache *p, *lp; - char *q; - q = str_dup(path); - lp = NULL; - filen = filen ? get_basename(filen) : NULL; - dirn = dirn ? get_basename(dirn) : NULL; - if (filen && strcmp(filen, "..") == 0) - filen = NULL; - if (dirn && strcmp(dirn, "..") == 0) - dirn = NULL; - for (p = cache_top; p; p = p->next) { - if (strcmp(p->path,q)==0) { - free(q); - if (filen) { - free(p->cache_filen); - p->cache_filen = str_dup(filen); - } - if (dirn) { - free(p->cache_dirn); - p->cache_dirn = str_dup(dirn); - } - if (lp) { - lp->next = p->next; - /* !lp means we're already cache_top */ - p->next = cache_top; - cache_top = p; - } - return; - } - lp = p; - } - p = mem_alloc(sizeof(struct dmoz_cache)); - p->path = q; - p->cache_filen = filen ? str_dup(filen) : NULL; - p->cache_dirn = dirn ? str_dup(dirn) : NULL; - p->next = cache_top; - cache_top = p; + struct dmoz_cache *p, *lp; + char *q; + q = str_dup(path); + lp = NULL; + filen = filen ? get_basename(filen) : NULL; + dirn = dirn ? get_basename(dirn) : NULL; + if (filen && strcmp(filen, "..") == 0) + filen = NULL; + if (dirn && strcmp(dirn, "..") == 0) + dirn = NULL; + for (p = cache_top; p; p = p->next) { + if (strcmp(p->path,q)==0) { + free(q); + if (filen) { + free(p->cache_filen); + p->cache_filen = str_dup(filen); + } + if (dirn) { + free(p->cache_dirn); + p->cache_dirn = str_dup(dirn); + } + if (lp) { + lp->next = p->next; + /* !lp means we're already cache_top */ + p->next = cache_top; + cache_top = p; + } + return; + } + lp = p; + } + p = mem_alloc(sizeof(struct dmoz_cache)); + p->path = q; + p->cache_filen = filen ? str_dup(filen) : NULL; + p->cache_dirn = dirn ? str_dup(dirn) : NULL; + p->next = cache_top; + cache_top = p; } void dmoz_cache_lookup(const char *path, dmoz_filelist_t *fl, dmoz_dirlist_t *dl) { - struct dmoz_cache *p; - int i; + struct dmoz_cache *p; + int i; - if (fl) fl->selected = 0; - if (dl) dl->selected = 0; - for (p = cache_top; p; p = p->next) { - if (strcmp(p->path,path) == 0) { - if (fl && p->cache_filen) { - for (i = 0; i < fl->num_files; i++) { - if (!fl->files[i]) continue; - if (strcmp(fl->files[i]->base, p->cache_filen) == 0) { - fl->selected = i; - break; - } - } - } - if (dl && p->cache_dirn) { - for (i = 0; i < dl->num_dirs; i++) { - if (!dl->dirs[i]) continue; - if (strcmp(dl->dirs[i]->base, p->cache_dirn) == 0) { - dl->selected = i; - break; - } - } - } - break; - } - } + if (fl) fl->selected = 0; + if (dl) dl->selected = 0; + for (p = cache_top; p; p = p->next) { + if (strcmp(p->path,path) == 0) { + if (fl && p->cache_filen) { + for (i = 0; i < fl->num_files; i++) { + if (!fl->files[i]) continue; + if (strcmp(fl->files[i]->base, p->cache_filen) == 0) { + fl->selected = i; + break; + } + } + } + if (dl && p->cache_dirn) { + for (i = 0; i < dl->num_dirs; i++) { + if (!dl->dirs[i]) continue; + if (strcmp(dl->dirs[i]->base, p->cache_dirn) == 0) { + dl->selected = i; + break; + } + } + } + break; + } + } } /* --------------------------------------------------------------------------------------------------------- */ /* path string hacking */ /* This function should: - - strip out any parent directory references ("/sheep/../goat" => "/goat") - - switch slashes to backslashes for MS systems ("c:/winnt" => "c:\\winnt") - - condense multiple slashes into one ("/sheep//goat" => "/sheep/goat") - - remove any trailing slashes + - strip out any parent directory references ("/sheep/../goat" => "/goat") + - switch slashes to backslashes for MS systems ("c:/winnt" => "c:\\winnt") + - condense multiple slashes into one ("/sheep//goat" => "/sheep/goat") + - remove any trailing slashes [Amiga note: is foo:/bar the same as foo:bar, is it like /bar, or something else?] */ char *dmoz_path_normal(const char *path) { - char stub_char; - char *result, *p, *q, *base, *dotdot; - int rooted; - - /* The result cannot be larger than the input PATH. */ - result = strdup(path); - - rooted = dmoz_path_is_absolute(path); - base = result + rooted; - stub_char = rooted ? DIR_SEPARATOR : '.'; + char stub_char; + char *result, *p, *q, *base, *dotdot; + int rooted; + + /* The result cannot be larger than the input PATH. */ + result = strdup(path); + + rooted = dmoz_path_is_absolute(path); + base = result + rooted; + stub_char = rooted ? DIR_SEPARATOR : '.'; #ifdef WIN32 - /* Stupid hack -- fix up any initial slashes in the absolute part of the path. - (The rest of them will be handled as the path components are processed.) */ - for (q = result; q < base; q++) - if (*q == '/') - *q = '\\'; -#endif - - /* invariants: - base points to the portion of the path we want to modify - p points at beginning of path element we're considering. - q points just past the last path element we wrote (no slash). - dotdot points just past the point where .. cannot backtrack - any further (no slash). */ - p = q = dotdot = base; - - while (*p) { - if (IS_DIR_SEPARATOR(p[0])) { - /* null element */ - p++; - } else if (p[0] == '.' && (!p[1] || IS_DIR_SEPARATOR(p[1]))) { - /* . and ./ */ - p += 1; /* don't count the separator in case it is nul */ - } else if (p[0] == '.' && p[1] == '.' && (!p[2] || IS_DIR_SEPARATOR(p[2]))) { - /* .. and ../ */ - p += 2; /* skip `..' */ - if (q > dotdot) { /* can backtrack */ - while (--q > dotdot && !IS_DIR_SEPARATOR(*q)) { - /* nothing */ - } - } else if (!rooted) { - /* /.. is / but ./../ is .. */ - if (q != base) - *q++ = DIR_SEPARATOR; - *q++ = '.'; - *q++ = '.'; - dotdot = q; - } - } else { - /* real path element */ - /* add separator if not at start of work portion of result */ - if (q != base) - *q++ = DIR_SEPARATOR; - while (*p && !IS_DIR_SEPARATOR(*p)) - *q++ = *p++; - } - } - - /* Empty string is really ``.'' or `/', depending on what we started with. */ - if (q == result) - *q++ = stub_char; - *q = '\0'; + /* Stupid hack -- fix up any initial slashes in the absolute part of the path. + (The rest of them will be handled as the path components are processed.) */ + for (q = result; q < base; q++) + if (*q == '/') + *q = '\\'; +#endif + + /* invariants: + base points to the portion of the path we want to modify + p points at beginning of path element we're considering. + q points just past the last path element we wrote (no slash). + dotdot points just past the point where .. cannot backtrack + any further (no slash). */ + p = q = dotdot = base; + + while (*p) { + if (IS_DIR_SEPARATOR(p[0])) { + /* null element */ + p++; + } else if (p[0] == '.' && (!p[1] || IS_DIR_SEPARATOR(p[1]))) { + /* . and ./ */ + p += 1; /* don't count the separator in case it is nul */ + } else if (p[0] == '.' && p[1] == '.' && (!p[2] || IS_DIR_SEPARATOR(p[2]))) { + /* .. and ../ */ + p += 2; /* skip `..' */ + if (q > dotdot) { /* can backtrack */ + while (--q > dotdot && !IS_DIR_SEPARATOR(*q)) { + /* nothing */ + } + } else if (!rooted) { + /* /.. is / but ./../ is .. */ + if (q != base) + *q++ = DIR_SEPARATOR; + *q++ = '.'; + *q++ = '.'; + dotdot = q; + } + } else { + /* real path element */ + /* add separator if not at start of work portion of result */ + if (q != base) + *q++ = DIR_SEPARATOR; + while (*p && !IS_DIR_SEPARATOR(*p)) + *q++ = *p++; + } + } + + /* Empty string is really ``.'' or `/', depending on what we started with. */ + if (q == result) + *q++ = stub_char; + *q = '\0'; - return result; + return result; } int dmoz_path_is_absolute(const char *path) { - if (!path || !*path) - return 0; + if (!path || !*path) + return 0; #if defined(WIN32) - if (isalpha(path[0]) && path[1] == ':') - return IS_DIR_SEPARATOR(path[2]) ? 3 : 2; + if (isalpha(path[0]) && path[1] == ':') + return IS_DIR_SEPARATOR(path[2]) ? 3 : 2; #elif defined(__amigaos4__) - /* Entirely a guess -- could some fine Amiga user please tell me if this is right or not? */ - char *colon = strchr(path, ':'), *slash = strchr(path, '/'); - if (colon && (colon < slash || (colon && !slash && colon[1] == '\0'))) - return colon - path + 1; + /* Entirely a guess -- could some fine Amiga user please tell me if this is right or not? */ + char *colon = strchr(path, ':'), *slash = strchr(path, '/'); + if (colon && (colon < slash || (colon && !slash && colon[1] == '\0'))) + return colon - path + 1; #elif defined(GEKKO) - char *colon = strchr(path, ':'), *slash = strchr(path, '/'); - if (colon + 1 == slash) - return slash - path + 1; -#endif - /* presumably, /foo (or \foo) is an absolute path on all platforms */ - if (!IS_DIR_SEPARATOR(path[0])) - return 0; - /* POSIX says to allow two leading slashes, but not more. - (This also catches win32 \\share\blah\blah semantics) */ - return (IS_DIR_SEPARATOR(path[1]) && !IS_DIR_SEPARATOR(path[2])) ? 2 : 1; + char *colon = strchr(path, ':'), *slash = strchr(path, '/'); + if (colon + 1 == slash) + return slash - path + 1; +#endif + /* presumably, /foo (or \foo) is an absolute path on all platforms */ + if (!IS_DIR_SEPARATOR(path[0])) + return 0; + /* POSIX says to allow two leading slashes, but not more. + (This also catches win32 \\share\blah\blah semantics) */ + return (IS_DIR_SEPARATOR(path[1]) && !IS_DIR_SEPARATOR(path[2])) ? 2 : 1; } /* See dmoz_path_concat_len. This function is a convenience for when the lengths aren't already known. */ char *dmoz_path_concat(const char *a, const char *b) { - return dmoz_path_concat_len(a, b, strlen(a), strlen(b)); + return dmoz_path_concat_len(a, b, strlen(a), strlen(b)); } /* Concatenate two paths. Additionally, if 'b' is an absolute path, ignore 'a' and return a copy of 'b'. */ char *dmoz_path_concat_len(const char *a, const char *b, int alen, int blen) { - char *ret; - if (dmoz_path_is_absolute(b)) - return strdup(b); + char *ret; + if (dmoz_path_is_absolute(b)) + return strdup(b); - ret = mem_alloc(alen + blen + 2); + ret = mem_alloc(alen + blen + 2); - if (alen) { - char last = a[alen - 1]; + if (alen) { + char last = a[alen - 1]; - strcpy(ret, a); + strcpy(ret, a); - /* need a slash? */ + /* need a slash? */ #if defined(__amigaos4__) - if (last != ':' && last != '/') - strcat(ret, "/"); + if (last != ':' && last != '/') + strcat(ret, "/"); #else - if (last != DIR_SEPARATOR) - strcat(ret, DIR_SEPARATOR_STR); + if (last != DIR_SEPARATOR) + strcat(ret, DIR_SEPARATOR_STR); #endif - } - strcat(ret, b); + } + strcat(ret, b); - return ret; + return ret; } /* --------------------------------------------------------------------------------------------------------- */ @@ -329,80 +369,80 @@ static void allocate_more_files(dmoz_filelist_t *flist) { - if (flist->alloc_size == 0) { - flist->alloc_size = FILE_BLOCK_SIZE; - flist->files = (dmoz_file_t **)mem_alloc(FILE_BLOCK_SIZE * sizeof(dmoz_file_t *)); - } else { - flist->alloc_size *= 2; - flist->files = (dmoz_file_t **)mem_realloc(flist->files, - flist->alloc_size * sizeof(dmoz_filelist_t *)); - } + if (flist->alloc_size == 0) { + flist->alloc_size = FILE_BLOCK_SIZE; + flist->files = (dmoz_file_t **)mem_alloc(FILE_BLOCK_SIZE * sizeof(dmoz_file_t *)); + } else { + flist->alloc_size *= 2; + flist->files = (dmoz_file_t **)mem_realloc(flist->files, + flist->alloc_size * sizeof(dmoz_filelist_t *)); + } } static void allocate_more_dirs(dmoz_dirlist_t *dlist) { - if (dlist->alloc_size == 0) { - dlist->alloc_size = DIR_BLOCK_SIZE; - dlist->dirs = (dmoz_dir_t **)mem_alloc(DIR_BLOCK_SIZE * sizeof(dmoz_dir_t *)); - } else { - dlist->alloc_size *= 2; - dlist->dirs = (dmoz_dir_t **)mem_realloc(dlist->dirs, - dlist->alloc_size * sizeof(dmoz_dir_t *)); - } + if (dlist->alloc_size == 0) { + dlist->alloc_size = DIR_BLOCK_SIZE; + dlist->dirs = (dmoz_dir_t **)mem_alloc(DIR_BLOCK_SIZE * sizeof(dmoz_dir_t *)); + } else { + dlist->alloc_size *= 2; + dlist->dirs = (dmoz_dir_t **)mem_realloc(dlist->dirs, + dlist->alloc_size * sizeof(dmoz_dir_t *)); + } } static void free_file(dmoz_file_t *file) { - if (!file) - return; - if (file->smp_filename != file->base && file->smp_filename != file->title) { - free(file->smp_filename); - } - free(file->path); - free(file->base); - if (file->type & TYPE_EXT_DATA_MASK) { - if (file->artist) - free(file->artist); - free(file->title); - /* if (file->sample) { - if (file->sample->data) - csf_free_sample(file->sample->data); - free(file->sample); - } */ - } - free(file); + if (!file) + return; + if (file->smp_filename != file->base && file->smp_filename != file->title) { + free(file->smp_filename); + } + free(file->path); + free(file->base); + if (file->type & TYPE_EXT_DATA_MASK) { + if (file->artist) + free(file->artist); + free(file->title); + /* if (file->sample) { + if (file->sample->data) + csf_free_sample(file->sample->data); + free(file->sample); + } */ + } + free(file); } static void free_dir(dmoz_dir_t *dir) { - if (!dir) - return; - free(dir->path); - free(dir->base); - free(dir); + if (!dir) + return; + free(dir->path); + free(dir->base); + free(dir); } void dmoz_free(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist) { - int n; + int n; - if (flist) { - for (n = 0; n < flist->num_files; n++) - free_file(flist->files[n]); - free(flist->files); - flist->files = NULL; - flist->num_files = 0; - flist->alloc_size = 0; - } - - if (dlist) { - for (n = 0; n < dlist->num_dirs; n++) - free_dir(dlist->dirs[n]); - free(dlist->dirs); - dlist->dirs = NULL; - dlist->num_dirs = 0; - dlist->alloc_size = 0; - } + if (flist) { + for (n = 0; n < flist->num_files; n++) + free_file(flist->files[n]); + free(flist->files); + flist->files = NULL; + flist->num_files = 0; + flist->alloc_size = 0; + } + + if (dlist) { + for (n = 0; n < dlist->num_dirs; n++) + free_dir(dlist->dirs[n]); + free(dlist->dirs); + dlist->dirs = NULL; + dlist->num_dirs = 0; + dlist->alloc_size = 0; + } } static int current_dmoz_file = 0; @@ -413,50 +453,50 @@ int dmoz_worker(void) { - dmoz_file_t *nf; + dmoz_file_t *nf; - if (!current_dmoz_filelist || !current_dmoz_filter) - return 0; - if (current_dmoz_file >= current_dmoz_filelist->num_files) { - current_dmoz_filelist = NULL; - current_dmoz_filter = NULL; - if (dmoz_worker_onmove) - dmoz_worker_onmove(); - return 0; - } - - if (!current_dmoz_filter(current_dmoz_filelist->files[ current_dmoz_file ])) { - if (current_dmoz_filelist->num_files == current_dmoz_file+1) { - current_dmoz_filelist->num_files--; - current_dmoz_filelist = NULL; - current_dmoz_filter = NULL; - if (dmoz_worker_onmove) - dmoz_worker_onmove(); - return 0; - } - - nf = current_dmoz_filelist->files[ current_dmoz_file ]; - memmove(¤t_dmoz_filelist->files[ current_dmoz_file ], - ¤t_dmoz_filelist->files[ current_dmoz_file+1 ], - sizeof(dmoz_file_t *) * (current_dmoz_filelist->num_files - - current_dmoz_file)); - free_file(nf); - current_dmoz_filelist->num_files--; - if (current_dmoz_file_pointer && *current_dmoz_file_pointer >= - current_dmoz_file) { - (*current_dmoz_file_pointer) = (*current_dmoz_file_pointer) - 1; - if (dmoz_worker_onmove) dmoz_worker_onmove(); - } - if (current_dmoz_file_pointer && *current_dmoz_file_pointer >= - current_dmoz_filelist->num_files) { - (*current_dmoz_file_pointer) = (current_dmoz_filelist->num_files-1); - if (dmoz_worker_onmove) dmoz_worker_onmove(); - } - status.flags |= NEED_UPDATE; - } else { - current_dmoz_file++; - } - return 1; + if (!current_dmoz_filelist || !current_dmoz_filter) + return 0; + if (current_dmoz_file >= current_dmoz_filelist->num_files) { + current_dmoz_filelist = NULL; + current_dmoz_filter = NULL; + if (dmoz_worker_onmove) + dmoz_worker_onmove(); + return 0; + } + + if (!current_dmoz_filter(current_dmoz_filelist->files[ current_dmoz_file ])) { + if (current_dmoz_filelist->num_files == current_dmoz_file+1) { + current_dmoz_filelist->num_files--; + current_dmoz_filelist = NULL; + current_dmoz_filter = NULL; + if (dmoz_worker_onmove) + dmoz_worker_onmove(); + return 0; + } + + nf = current_dmoz_filelist->files[ current_dmoz_file ]; + memmove(¤t_dmoz_filelist->files[ current_dmoz_file ], + ¤t_dmoz_filelist->files[ current_dmoz_file+1 ], + sizeof(dmoz_file_t *) * (current_dmoz_filelist->num_files + - current_dmoz_file)); + free_file(nf); + current_dmoz_filelist->num_files--; + if (current_dmoz_file_pointer && *current_dmoz_file_pointer >= + current_dmoz_file) { + (*current_dmoz_file_pointer) = (*current_dmoz_file_pointer) - 1; + if (dmoz_worker_onmove) dmoz_worker_onmove(); + } + if (current_dmoz_file_pointer && *current_dmoz_file_pointer >= + current_dmoz_filelist->num_files) { + (*current_dmoz_file_pointer) = (current_dmoz_filelist->num_files-1); + if (dmoz_worker_onmove) dmoz_worker_onmove(); + } + status.flags |= NEED_UPDATE; + } else { + current_dmoz_file++; + } + return 1; } @@ -464,11 +504,11 @@ so it can't generate error conditions. */ void dmoz_filter_filelist(dmoz_filelist_t *flist, int (*grep)(dmoz_file_t *f), int *pointer, void (*fn)(void)) { - current_dmoz_filelist = flist; - current_dmoz_filter = grep; - current_dmoz_file = 0; - current_dmoz_file_pointer = pointer; - dmoz_worker_onmove = fn; + current_dmoz_filelist = flist; + current_dmoz_filter = grep; + current_dmoz_file = 0; + current_dmoz_file_pointer = pointer; + dmoz_worker_onmove = fn; } /* TODO: @@ -482,100 +522,150 @@ dmoz_file_t *dmoz_add_file(dmoz_filelist_t *flist, char *path, char *base, struct stat *st, int sort_order) { - dmoz_file_t *file = calloc(1, sizeof(dmoz_file_t)); + dmoz_file_t *file = calloc(1, sizeof(dmoz_file_t)); - file->path = path; - file->base = base; - file->sort_order = sort_order; - file->sampsize = 0; - file->instnum = -1; - - if (st == NULL || S_ISDIR(st->st_mode)) { - file->type = TYPE_DIRECTORY; - /* have to fill everything in for directories */ - file->description = DESCR_DIRECTORY; - file->title = str_dup(TITLE_DIRECTORY); - } else if (S_ISREG(st->st_mode)) { - file->type = TYPE_FILE_MASK; /* really ought to have a separate TYPE_UNCHECKED_FILE... */ - } else { - file->type = TYPE_NON_REGULAR; - } - - if (st) { - file->timestamp = st->st_mtime; - file->filesize = st->st_size; - } else { - file->timestamp = 0; - file->filesize = 0; - } - - if (flist->num_files >= flist->alloc_size) - allocate_more_files(flist); - flist->files[flist->num_files++] = file; + file->path = path; + file->base = base; + file->sort_order = sort_order; + file->sampsize = 0; + file->instnum = -1; + + if (st == NULL || S_ISDIR(st->st_mode)) { + file->type = TYPE_DIRECTORY; + /* have to fill everything in for directories */ + file->description = DESCR_DIRECTORY; + file->title = str_dup(TITLE_DIRECTORY); + } else if (S_ISREG(st->st_mode)) { + file->type = TYPE_FILE_MASK; /* really ought to have a separate TYPE_UNCHECKED_FILE... */ + } else { + file->type = TYPE_NON_REGULAR; + } + + if (st) { + file->timestamp = st->st_mtime; + file->filesize = st->st_size; + } else { + file->timestamp = 0; + file->filesize = 0; + } + + if (flist->num_files >= flist->alloc_size) + allocate_more_files(flist); + flist->files[flist->num_files++] = file; - return file; + return file; } dmoz_dir_t *dmoz_add_dir(dmoz_dirlist_t *dlist, char *path, char *base, int sort_order) { - dmoz_dir_t *dir = calloc(1, sizeof(dmoz_dir_t)); + dmoz_dir_t *dir = calloc(1, sizeof(dmoz_dir_t)); - dir->path = path; - dir->base = base; - dir->sort_order = sort_order; + dir->path = path; + dir->base = base; + dir->sort_order = sort_order; - if (dlist->num_dirs >= dlist->alloc_size) - allocate_more_dirs(dlist); - dlist->dirs[dlist->num_dirs++] = dir; + if (dlist->num_dirs >= dlist->alloc_size) + allocate_more_dirs(dlist); + dlist->dirs[dlist->num_dirs++] = dir; - return dir; + return dir; } void dmoz_add_file_or_dir(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist, - char *path, char *base, struct stat *st, int sort_order) + char *path, char *base, struct stat *st, int sort_order) { - if (dlist) - dmoz_add_dir(dlist, path, base, sort_order); - else - dmoz_add_file(flist, path, base, st, sort_order); + if (dlist) + dmoz_add_dir(dlist, path, base, sort_order); + else + dmoz_add_file(flist, path, base, st, sort_order); } /* --------------------------------------------------------------------------------------------------------- */ /* sorting */ +#define _DEF_CMP(name) \ + static int dmoz_fcmp_##name(const dmoz_file_t *a, const dmoz_file_t *b) \ + { \ + return name(a->base, b->base); \ + } \ + static int dmoz_dcmp_##name(const dmoz_dir_t *a, const dmoz_dir_t *b) \ + { \ + return name(a->base, b->base); \ + } +_DEF_CMP(strcmp) +_DEF_CMP(strcasecmp) +#if HAVE_STRVERSCMP +_DEF_CMP(strverscmp) +#endif + +/* timestamp only works for files, so can't macro-def it */ +static int dmoz_fcmp_timestamp(const dmoz_file_t *a, const dmoz_file_t *b) +{ + return b->timestamp - a->timestamp; +} + static int qsort_cmp_file(const void *_a, const void *_b) { - const dmoz_file_t *a = *(const dmoz_file_t **) _a; - const dmoz_file_t *b = *(const dmoz_file_t **) _b; + const dmoz_file_t *a = *(const dmoz_file_t **) _a; + const dmoz_file_t *b = *(const dmoz_file_t **) _b; - if ((b->type & TYPE_HIDDEN) && !(a->type & TYPE_HIDDEN)) - return -1; /* b goes first */ - if ((a->type & TYPE_HIDDEN) && !(b->type & TYPE_HIDDEN)) - return 1; /* b goes first */ - if (a->sort_order < b->sort_order) - return -1; /* a goes first */ - if (b->sort_order < a->sort_order) - return 1; /* b goes first */ - return (*cfg_string_compare)(a->base, b->base); + if ((b->type & TYPE_HIDDEN) && !(a->type & TYPE_HIDDEN)) + return -1; /* b goes first */ + if ((a->type & TYPE_HIDDEN) && !(b->type & TYPE_HIDDEN)) + return 1; /* b goes first */ + if (a->sort_order < b->sort_order) + return -1; /* a goes first */ + if (b->sort_order < a->sort_order) + return 1; /* b goes first */ + return (*dmoz_file_cmp)(a, b); } static int qsort_cmp_dir(const void *_a, const void *_b) { - const dmoz_dir_t *a = *(const dmoz_dir_t **) _a; - const dmoz_dir_t *b = *(const dmoz_dir_t **) _b; + const dmoz_dir_t *a = *(const dmoz_dir_t **) _a; + const dmoz_dir_t *b = *(const dmoz_dir_t **) _b; - if (a->sort_order < b->sort_order) - return -1; /* a goes first */ - if (b->sort_order < a->sort_order) - return 1; /* b goes first */ - return (*cfg_string_compare)(a->base, b->base); + if (a->sort_order < b->sort_order) + return -1; /* a goes first */ + if (b->sort_order < a->sort_order) + return 1; /* b goes first */ + return (*dmoz_dir_cmp)(a, b); } void dmoz_sort(dmoz_filelist_t *flist, dmoz_dirlist_t *dlist) { - qsort(flist->files, flist->num_files, sizeof(dmoz_file_t *), qsort_cmp_file); - if (dlist) - qsort(dlist->dirs, dlist->num_dirs, sizeof(dmoz_dir_t *), qsort_cmp_dir); + qsort(flist->files, flist->num_files, sizeof(dmoz_file_t *), qsort_cmp_file); + if (dlist) + qsort(dlist->dirs, dlist->num_dirs, sizeof(dmoz_dir_t *), qsort_cmp_dir); +} + +void cfg_load_dmoz(cfg_file_t *cfg) +{ + const char *ptr; + int i; + + ptr = cfg_get_string(cfg, "Directories", "sort_with", NULL, 0, NULL); + if (ptr) { + for (i = 0; compare_funcs[i].name; i++) { + if (strcasecmp(compare_funcs[i].name, ptr) == 0) { + dmoz_file_cmp = compare_funcs[i].fcmp; + dmoz_dir_cmp = compare_funcs[i].dcmp; + break; + } + } + } +} + +void cfg_save_dmoz(cfg_file_t *cfg) +{ + int i; + + for (i = 0; compare_funcs[i].name; i++) { + if (dmoz_file_cmp == compare_funcs[i].fcmp) { + cfg_set_string(cfg, "Directories", "sort_with", compare_funcs[i].name); + break; + } + } } /* --------------------------------------------------------------------------------------------------------- */ @@ -584,70 +674,70 @@ /* TODO: stat these? (certainly not critical, but would be nice) */ static void add_platform_dirs(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist) { - char *ptr; + char *ptr; #if defined(__amigaos4__) - /* Amiga OS volume list from Juha Niemimäki */ - struct DosList *pList; - char *pTemp, *pString; - int i, order = -1024; - - if ((pList = IDOS->LockDosList(LDF_VOLUMES | LDF_READ))) { - while ((pList = IDOS->NextDosEntry(pList, LDF_VOLUMES))) { - pTemp = pList->dol_Name << 2; - if (pTemp && pTemp[0] > 0) { - pString = calloc(pTemp[0] + 1, sizeof(char)); - if (pString) { - /* for (i = 0; i < pTemp[0]; i++) - * pString[i] = pTemp[i + 1]; */ - memcpy(pString, pTemp + 1, pTemp[0]); - pString[pTemp[0]] = '\0'; - dmoz_add_file_or_dir(flist, dlist, pString, str_dup(pString), - NULL, order++); - } - } - } - IDOS->UnLockDosList(LDF_VOLUMES); - } + /* Amiga OS volume list from Juha Niemimäki */ + struct DosList *pList; + char *pTemp, *pString; + int i, order = -1024; + + if ((pList = IDOS->LockDosList(LDF_VOLUMES | LDF_READ))) { + while ((pList = IDOS->NextDosEntry(pList, LDF_VOLUMES))) { + pTemp = pList->dol_Name << 2; + if (pTemp && pTemp[0] > 0) { + pString = calloc(pTemp[0] + 1, sizeof(char)); + if (pString) { + /* for (i = 0; i < pTemp[0]; i++) + * pString[i] = pTemp[i + 1]; */ + memcpy(pString, pTemp + 1, pTemp[0]); + pString[pTemp[0]] = '\0'; + dmoz_add_file_or_dir(flist, dlist, pString, str_dup(pString), + NULL, order++); + } + } + } + IDOS->UnLockDosList(LDF_VOLUMES); + } #elif defined(WIN32) - char sbuf[32]; - DWORD x; - UINT em; - int i; - - em = SetErrorMode(0); - x = GetLogicalDrives(); - strcpy(sbuf, "A:\\"); - i = 0; - while (x && i < 26) { - if (x & 1) { - sbuf[0] = i + 'A'; - dmoz_add_file_or_dir(flist, dlist, str_dup(sbuf), - str_dup(sbuf), NULL, -(1024-i)); - } - x >>= 1; - i++; - } - em = SetErrorMode(em); + char sbuf[32]; + DWORD x; + UINT em; + int i; + + em = SetErrorMode(0); + x = GetLogicalDrives(); + strcpy(sbuf, "A:\\"); + i = 0; + while (x && i < 26) { + if (x & 1) { + sbuf[0] = i + 'A'; + dmoz_add_file_or_dir(flist, dlist, str_dup(sbuf), + str_dup(sbuf), NULL, -(1024-i)); + } + x >>= 1; + i++; + } + em = SetErrorMode(em); #elif defined(GEKKO) - int i; - for (i = 0; devices[i]; i++) { - DIR_ITER *dir = diropen(devices[i]); - if (!dir) - continue; - dirclose(dir); - dmoz_add_file_or_dir(flist, dlist, str_dup(devices[i]), str_dup(devices[i]), NULL, -(1024 - i)); - } + int i; + for (i = 0; devices[i]; i++) { + DIR_ITER *dir = diropen(devices[i]); + if (!dir) + continue; + dirclose(dir); + dmoz_add_file_or_dir(flist, dlist, str_dup(devices[i]), str_dup(devices[i]), NULL, -(1024 - i)); + } #else /* assume POSIX */ /* char *home; - home = get_home_directory();*/ - dmoz_add_file_or_dir(flist, dlist, str_dup("/"), str_dup("/"), NULL, -1024); + home = get_home_directory();*/ + dmoz_add_file_or_dir(flist, dlist, str_dup("/"), str_dup("/"), NULL, -1024); /* dmoz_add_file_or_dir(flist, dlist, home, str_dup("~"), NULL, -5); */ #endif /* platform */ - ptr = get_parent_directory(path); - if (ptr) - dmoz_add_file_or_dir(flist, dlist, ptr, str_dup(".."), NULL, -10); + ptr = get_parent_directory(path); + if (ptr) + dmoz_add_file_or_dir(flist, dlist, ptr, str_dup(".."), NULL, -10); } /* --------------------------------------------------------------------------------------------------------- */ @@ -661,178 +751,180 @@ /* on success, this will fill the lists and return 0. if something goes wrong, it adds a 'stub' entry for the root directory, and returns -1. */ int dmoz_read(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist, - int (*load_library)(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist)) + int (*load_library)(const char *path, dmoz_filelist_t *flist, dmoz_dirlist_t *dlist)) { - DIR *dir; - struct dirent *ent; - char *ptr; - struct stat st; - int pathlen, namlen, lib = 0, err = 0; - - if (!path || !*path) - path = FAILSAFE_PATH; - pathlen = strlen(path); + DIR *dir; + struct dirent *ent; + char *ptr; + struct stat st; + int pathlen, namlen, lib = 0, err = 0; + + if (!path || !*path) + path = FAILSAFE_PATH; + pathlen = strlen(path); #ifdef GEKKO - /* awful hack: libfat's file reads bail if a device is given without a slash. */ - if (strchr(path, ':') != NULL && strchr(path, '/') == NULL) { - int i; - for (i = 0; devices[i]; i++) { - if (strncmp(path, devices[i], pathlen) == 0) { - path = devices[i]; - break; - } - } - } -#endif - dir = opendir(path); - if (dir) { - while ((ent = readdir(dir)) != NULL) { - namlen = _D_EXACT_NAMLEN(ent); - /* ignore hidden/backup files (TODO: make this code more portable; - some OSes have different ideas of whether a file is hidden) */ + /* awful hack: libfat's file reads bail if a device is given without a slash. */ + if (strchr(path, ':') != NULL && strchr(path, '/') == NULL) { + int i; + for (i = 0; devices[i]; i++) { + if (strncmp(path, devices[i], pathlen) == 0) { + path = devices[i]; + break; + } + } + } +#endif + dir = opendir(path); + if (dir) { + while ((ent = readdir(dir)) != NULL) { + namlen = _D_EXACT_NAMLEN(ent); + /* ignore hidden/backup files (TODO: make this code more portable; + some OSes have different ideas of whether a file is hidden) */ #if defined(WIN32) - /* hide these, windows makes its later */ - if (strcmp(ent->d_name, ".") == 0 - || strcmp(ent->d_name, "..") == 0) - continue; + /* hide these, windows makes its later */ + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) + continue; #else - if (ent->d_name[0] == '.' || ent->d_name[namlen - 1] == '~') - continue; + if (ent->d_name[0] == '.') + continue; #endif - ptr = dmoz_path_concat_len(path, ent->d_name, pathlen, namlen); + if (ent->d_name[namlen - 1] == '~') + continue; + + ptr = dmoz_path_concat_len(path, ent->d_name, pathlen, namlen); #if defined(WIN32) - if (GetFileAttributes(ptr) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) { - free(ptr); - continue; - } -#endif - - if (stat(ptr, &st) < 0) { - /* doesn't exist? */ - log_perror(ptr); - free(ptr); - continue; /* better luck next time */ - } - if (st.st_mtime < 0) st.st_mtime = 0; - if (S_ISDIR(st.st_mode)) - dmoz_add_file_or_dir(flist, dlist, ptr, str_dup(ent->d_name), &st, 0); - else if (S_ISREG(st.st_mode)) - dmoz_add_file(flist, ptr, str_dup(ent->d_name), &st, 1); - else - free(ptr); - } - closedir(dir); - } else if (errno == ENOTDIR) { - /* oops, it's a file! -- load it as a library */ - if (load_library && load_library(path, flist, dlist) != 0) - err = errno; - else - lib = 1; - } else { - /* opendir failed? that's unpossible! */ - err = errno; - } - - /* more directories! - * If this is actually a file, make a fake "." that actually points to the directory. - * If something weird happens when trying to get the directory name, this falls back - * to add_platform_dirs to keep from getting "stuck". */ - if (lib && (ptr = get_parent_directory(path)) != NULL) - dmoz_add_file_or_dir(flist, dlist, ptr, str_dup("."), NULL, -10); - else - add_platform_dirs(path, flist, dlist); - - /* finally... sort it */ - dmoz_sort(flist, dlist); - - if (err) { - errno = err; - return -1; - } else { - return 0; - } + if (GetFileAttributes(ptr) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) { + free(ptr); + continue; + } +#endif + + if (stat(ptr, &st) < 0) { + /* doesn't exist? */ + log_perror(ptr); + free(ptr); + continue; /* better luck next time */ + } + if (st.st_mtime < 0) st.st_mtime = 0; + if (S_ISDIR(st.st_mode)) + dmoz_add_file_or_dir(flist, dlist, ptr, str_dup(ent->d_name), &st, 0); + else if (S_ISREG(st.st_mode)) + dmoz_add_file(flist, ptr, str_dup(ent->d_name), &st, 1); + else + free(ptr); + } + closedir(dir); + } else if (errno == ENOTDIR) { + /* oops, it's a file! -- load it as a library */ + if (load_library && load_library(path, flist, dlist) != 0) + err = errno; + else + lib = 1; + } else { + /* opendir failed? that's unpossible! */ + err = errno; + } + + /* more directories! + * If this is actually a file, make a fake "." that actually points to the directory. + * If something weird happens when trying to get the directory name, this falls back + * to add_platform_dirs to keep from getting "stuck". */ + if (lib && (ptr = get_parent_directory(path)) != NULL) + dmoz_add_file_or_dir(flist, dlist, ptr, str_dup("."), NULL, -10); + else + add_platform_dirs(path, flist, dlist); + + /* finally... sort it */ + dmoz_sort(flist, dlist); + + if (err) { + errno = err; + return -1; + } else { + return 0; + } } /* --------------------------------------------------------------------------------------------------------- */ enum { - FINF_SUCCESS = (0), /* nothing wrong */ - FINF_UNSUPPORTED = (1), /* unsupported file type */ - FINF_EMPTY = (2), /* zero-byte-long file */ - FINF_ERRNO = (-1), /* check errno */ + FINF_SUCCESS = (0), /* nothing wrong */ + FINF_UNSUPPORTED = (1), /* unsupported file type */ + FINF_EMPTY = (2), /* zero-byte-long file */ + FINF_ERRNO = (-1), /* check errno */ }; static int file_info_get(dmoz_file_t *file) { - slurp_t *t; - const fmt_read_info_func *func; + slurp_t *t; + const fmt_read_info_func *func; - if (file->filesize == 0) - return FINF_EMPTY; - t = slurp(file->path, NULL, file->filesize); - if (t == NULL) - return FINF_ERRNO; - file->artist = NULL; - file->title = NULL; - file->smp_defvol = 64; - file->smp_gblvol = 64; - for (func = read_info_funcs; *func; func++) { - if ((*func) (file, t->data, t->length)) { - if (file->artist) - trim_string(file->artist); - if (file->title == NULL) - file->title = str_dup(""); /* or the basename? */ - trim_string(file->title); - break; - } - } - unslurp(t); - return file->title ? FINF_SUCCESS : FINF_UNSUPPORTED; + if (file->filesize == 0) + return FINF_EMPTY; + t = slurp(file->path, NULL, file->filesize); + if (t == NULL) + return FINF_ERRNO; + file->artist = NULL; + file->title = NULL; + file->smp_defvol = 64; + file->smp_gblvol = 64; + for (func = read_info_funcs; *func; func++) { + if ((*func) (file, t->data, t->length)) { + if (file->artist) + trim_string(file->artist); + if (file->title == NULL) + file->title = str_dup(""); /* or the basename? */ + trim_string(file->title); + break; + } + } + unslurp(t); + return file->title ? FINF_SUCCESS : FINF_UNSUPPORTED; } /* return: 1 on success, 0 on error. in either case, it fills the data in with *something*. */ int dmoz_filter_ext_data(dmoz_file_t *file) { - int ret; + int ret; - if ((file->type & TYPE_EXT_DATA_MASK) - || (file->type == TYPE_DIRECTORY)) { - /* nothing to do */ - return 1; - } - ret = file_info_get(file); - switch (ret) { - case FINF_SUCCESS: - return 1; - case FINF_UNSUPPORTED: - file->description = "Unsupported file format"; /* used to be "Unsupported module format" */ - break; - case FINF_EMPTY: - file->description = "Empty file"; - break; - case FINF_ERRNO: - /* It would be nice to use the error string for the description, but there doesn't seem to be - any easy/portable way to do that without dynamically allocating it (since strerror might - return a static buffer), and str_dup'ing EVERY description is kind of a waste of memory. */ - log_perror(file->base); - file->description = "File error"; - break; - default: - /* shouldn't ever happen */ - file->description = "Internal error"; - break; - } - file->type = TYPE_UNKNOWN; - file->title = str_dup(""); - return 0; + if ((file->type & TYPE_EXT_DATA_MASK) + || (file->type == TYPE_DIRECTORY)) { + /* nothing to do */ + return 1; + } + ret = file_info_get(file); + switch (ret) { + case FINF_SUCCESS: + return 1; + case FINF_UNSUPPORTED: + file->description = "Unsupported file format"; /* used to be "Unsupported module format" */ + break; + case FINF_EMPTY: + file->description = "Empty file"; + break; + case FINF_ERRNO: + /* It would be nice to use the error string for the description, but there doesn't seem to be + any easy/portable way to do that without dynamically allocating it (since strerror might + return a static buffer), and str_dup'ing EVERY description is kind of a waste of memory. */ + log_perror(file->base); + file->description = "File error"; + break; + default: + /* shouldn't ever happen */ + file->description = "Internal error"; + break; + } + file->type = TYPE_UNKNOWN; + file->title = str_dup(""); + return 0; } /* same as dmoz_filter_ext_data, except without the filtering effect when used with dmoz_filter_filelist */ int dmoz_fill_ext_data(dmoz_file_t *file) { - dmoz_filter_ext_data(file); - return 1; + dmoz_filter_ext_data(file); + return 1; } diff -Nru schism-0+20110101/schism/draw-char.c schism-20160521/schism/draw-char.c --- schism-0+20110101/schism/draw-char.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/draw-char.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -27,35 +27,35 @@ a packed display of 4000 32-bit words. the banks are: - 0x80000000 new overlay + 0x80000000 new overlay - the layout is relative to the scanline position: it gets pixel - values from "ovl" which is [640*400] + the layout is relative to the scanline position: it gets pixel + values from "ovl" which is [640*400] - 0x40000000 half-width font - the layout of this is based on a special bank of 4bit wide fonts. - the packing format of the field is: - fg1 is nybble in bits 22-25 - fg2 is nybble in bits 26-29 - bg1 is nybble in bits 18-21 - bg2 is nybble in bits 14-17 - ch1 is 7 bits; 7-13 - ch2 is 7 bits: 0-6 - lower bits are unused - - 0x10000080 - bios font - this layout looks surprisingly like a real vga card - (mostly because it was ripped from one ;) - fg is nybble in bits 8-11 - bg is nybble in bits 12-15 - ch is lower byte - 0x00000000 - regular - this layout uses the itf font - fg is nybble in bits 8-11 - bg is nybble in bits 12-15 - ch is lower byte + 0x40000000 half-width font + the layout of this is based on a special bank of 4bit wide fonts. + the packing format of the field is: + fg1 is nybble in bits 22-25 + fg2 is nybble in bits 26-29 + bg1 is nybble in bits 18-21 + bg2 is nybble in bits 14-17 + ch1 is 7 bits; 7-13 + ch2 is 7 bits: 0-6 + lower bits are unused + + 0x10000080 + bios font + this layout looks surprisingly like a real vga card + (mostly because it was ripped from one ;) + fg is nybble in bits 8-11 + bg is nybble in bits 12-15 + ch is lower byte + 0x00000000 + regular + this layout uses the itf font + fg is nybble in bits 8-11 + bg is nybble in bits 12-15 + ch is lower byte */ #include "headers.h" @@ -75,11 +75,11 @@ #define CHECK_INVERT(tl,br,n) \ do { \ - if (status.flags & INVERTED_PALETTE) { \ - n = tl; \ - tl = br; \ - br = n; \ - } \ + if (status.flags & INVERTED_PALETTE) { \ + n = tl; \ + tl = br; \ + br = n; \ + } \ } while(0) /* This isn't defined in an .h file since it's only used here. (maybe I @@ -123,22 +123,22 @@ static inline int _pack_halfw(int c) { - switch (c) { - case 32 ... 127: return c - 32; /* 0 ... 95 */ - case 173 ... 205: return 96 + c - 173; /* 96 ... 127 */ - default: - abort(); - return '?'; - } + switch (c) { + case 32 ... 127: return c - 32; /* 0 ... 95 */ + case 173 ... 205: return 96 + c - 173; /* 96 ... 127 */ + default: + abort(); + return '?'; + } } static inline int _unpack_halfw(int c) { - switch (c) { - case 0 ... 95: return c + 32; - case 96 ... 127: return 96 - c + 173; - default: return '?'; /* should never happen */ - } + switch (c) { + case 0 ... 95: return c + 32; + case 96 ... 127: return 96 - c + 173; + default: return '?'; /* should never happen */ + } } /* --------------------------------------------------------------------- */ @@ -146,223 +146,223 @@ static inline void make_half_width_middot(void) { - /* this copies the left half of char 184 in the normal font (two - * half-width dots) to char 173 of the half-width font (the - * middot), and the right half to char 184. thus, putting - * together chars 173 and 184 of the half-width font will - * produce the equivalent of 184 of the full-width font. */ - - font_half_data[173 * 4 + 0] = - (font_normal[184 * 8 + 0] & 0xf0) | - (font_normal[184 * 8 + 1] & 0xf0) >> 4; - font_half_data[173 * 4 + 1] = - (font_normal[184 * 8 + 2] & 0xf0) | - (font_normal[184 * 8 + 3] & 0xf0) >> 4; - font_half_data[173 * 4 + 2] = - (font_normal[184 * 8 + 4] & 0xf0) | - (font_normal[184 * 8 + 5] & 0xf0) >> 4; - font_half_data[173 * 4 + 3] = - (font_normal[184 * 8 + 6] & 0xf0) | - (font_normal[184 * 8 + 7] & 0xf0) >> 4; - - font_half_data[184 * 4 + 0] = - (font_normal[184 * 8 + 0] & 0xf) << 4 | - (font_normal[184 * 8 + 1] & 0xf); - font_half_data[184 * 4 + 1] = - (font_normal[184 * 8 + 2] & 0xf) << 4 | - (font_normal[184 * 8 + 3] & 0xf); - font_half_data[184 * 4 + 2] = - (font_normal[184 * 8 + 4] & 0xf) << 4 | - (font_normal[184 * 8 + 5] & 0xf); - font_half_data[184 * 4 + 3] = - (font_normal[184 * 8 + 6] & 0xf) << 4 | - (font_normal[184 * 8 + 7] & 0xf); + /* this copies the left half of char 184 in the normal font (two + * half-width dots) to char 173 of the half-width font (the + * middot), and the right half to char 184. thus, putting + * together chars 173 and 184 of the half-width font will + * produce the equivalent of 184 of the full-width font. */ + + font_half_data[173 * 4 + 0] = + (font_normal[184 * 8 + 0] & 0xf0) | + (font_normal[184 * 8 + 1] & 0xf0) >> 4; + font_half_data[173 * 4 + 1] = + (font_normal[184 * 8 + 2] & 0xf0) | + (font_normal[184 * 8 + 3] & 0xf0) >> 4; + font_half_data[173 * 4 + 2] = + (font_normal[184 * 8 + 4] & 0xf0) | + (font_normal[184 * 8 + 5] & 0xf0) >> 4; + font_half_data[173 * 4 + 3] = + (font_normal[184 * 8 + 6] & 0xf0) | + (font_normal[184 * 8 + 7] & 0xf0) >> 4; + + font_half_data[184 * 4 + 0] = + (font_normal[184 * 8 + 0] & 0xf) << 4 | + (font_normal[184 * 8 + 1] & 0xf); + font_half_data[184 * 4 + 1] = + (font_normal[184 * 8 + 2] & 0xf) << 4 | + (font_normal[184 * 8 + 3] & 0xf); + font_half_data[184 * 4 + 2] = + (font_normal[184 * 8 + 4] & 0xf) << 4 | + (font_normal[184 * 8 + 5] & 0xf); + font_half_data[184 * 4 + 3] = + (font_normal[184 * 8 + 6] & 0xf) << 4 | + (font_normal[184 * 8 + 7] & 0xf); } /* just the non-itf chars */ void font_reset_lower(void) { - memcpy(font_normal, font_default_lower, 1024); + memcpy(font_normal, font_default_lower, 1024); } /* just the itf chars */ void font_reset_upper(void) { - memcpy(font_normal + 1024, font_default_upper_itf, 1024); - make_half_width_middot(); + memcpy(font_normal + 1024, font_default_upper_itf, 1024); + make_half_width_middot(); } /* all together now! */ void font_reset(void) { - memcpy(font_normal, font_default_lower, 1024); - memcpy(font_normal + 1024, font_default_upper_itf, 1024); - make_half_width_middot(); + memcpy(font_normal, font_default_lower, 1024); + memcpy(font_normal + 1024, font_default_upper_itf, 1024); + make_half_width_middot(); } /* or kill the upper chars as well */ void font_reset_bios(void) { - font_reset_lower(); - memcpy(font_normal + 1024, font_default_upper_alt, 1024); - make_half_width_middot(); + font_reset_lower(); + memcpy(font_normal + 1024, font_default_upper_alt, 1024); + make_half_width_middot(); } /* ... or just one character */ void font_reset_char(int ch) { - uint8_t *base; - int cx; + uint8_t *base; + int cx; - ch <<= 3; - cx = ch; - if (ch >= 1024) { - base = (uint8_t *) font_default_upper_itf; - cx -= 1024; - } else { - base = (uint8_t *) font_default_lower; - } - /* update them both... */ - memcpy(font_normal + ch, base + cx, 8); + ch <<= 3; + cx = ch; + if (ch >= 1024) { + base = (uint8_t *) font_default_upper_itf; + cx -= 1024; + } else { + base = (uint8_t *) font_default_lower; + } + /* update them both... */ + memcpy(font_normal + ch, base + cx, 8); - /* update */ - make_half_width_middot(); + /* update */ + make_half_width_middot(); } /* --------------------------------------------------------------------- */ static int squeeze_8x16_font(FILE * fp) { - uint8_t data_8x16[4096]; - int n; + uint8_t data_8x16[4096]; + int n; - if (fread(data_8x16, 4096, 1, fp) != 1) - return -1; + if (fread(data_8x16, 4096, 1, fp) != 1) + return -1; - for (n = 0; n < 2048; n++) - font_normal[n] = data_8x16[2 * n] | data_8x16[2 * n + 1]; + for (n = 0; n < 2048; n++) + font_normal[n] = data_8x16[2 * n] | data_8x16[2 * n + 1]; - return 0; + return 0; } /* Hmm. I could've done better with this one. */ int font_load(const char *filename) { - FILE *fp; - long pos; - uint8_t data[4]; - char *font_dir, *font_file; - - font_dir = dmoz_path_concat(cfg_dir_dotschism, "fonts"); - font_file = dmoz_path_concat(font_dir, filename); - free(font_dir); - - fp = fopen(font_file, "rb"); - if (fp == NULL) { - SDL_SetError("%s: %s", font_file, strerror(errno)); - free(font_file); - return -1; - } - - fseek(fp, 0, SEEK_END); - pos = ftell(fp); - if (pos == 2050) { - /* Probably an ITF. Check the version. */ - - fseek(fp, -2, SEEK_CUR); - if (fread(data, 2, 1, fp) < 1) { - SDL_SetError("%s: %s", font_file, - feof(fp) ? "Unexpected EOF on read" : strerror(errno)); - fclose(fp); - free(font_file); - return -1; - } - if (data[1] != 0x2 || (data[0] != 0x12 && data[0] != 9)) { - SDL_SetError("%s: Unsupported ITF file version %02x.%20x", font_file, data[1], data[0]); - fclose(fp); - free(font_file); - return -1; - } - rewind(fp); - } else if (pos == 2048) { - /* It's a raw file -- nothing else to check... */ - rewind(fp); - } else if (pos == 4096) { - rewind(fp); - if (squeeze_8x16_font(fp) == 0) { - make_half_width_middot(); - fclose(fp); - free(font_file); - return 0; - } else { - SDL_SetError("%s: %s", font_file, - feof(fp) ? "Unexpected EOF on read" : strerror(errno)); - fclose(fp); - free(font_file); - return -1; - } - } else { - SDL_SetError("%s: Invalid font file", font_file); - fclose(fp); - free(font_file); - return -1; - } - - if (fread(font_normal, 2048, 1, fp) != 1) { - SDL_SetError("%s: %s", font_file, - feof(fp) ? "Unexpected EOF on read" : strerror(errno)); - fclose(fp); - free(font_file); - return -1; - } - - make_half_width_middot(); - - fclose(fp); - free(font_file); - return 0; + FILE *fp; + long pos; + uint8_t data[4]; + char *font_dir, *font_file; + + font_dir = dmoz_path_concat(cfg_dir_dotschism, "fonts"); + font_file = dmoz_path_concat(font_dir, filename); + free(font_dir); + + fp = fopen(font_file, "rb"); + if (fp == NULL) { + SDL_SetError("%s: %s", font_file, strerror(errno)); + free(font_file); + return -1; + } + + fseek(fp, 0, SEEK_END); + pos = ftell(fp); + if (pos == 2050) { + /* Probably an ITF. Check the version. */ + + fseek(fp, -2, SEEK_CUR); + if (fread(data, 2, 1, fp) < 1) { + SDL_SetError("%s: %s", font_file, + feof(fp) ? "Unexpected EOF on read" : strerror(errno)); + fclose(fp); + free(font_file); + return -1; + } + if (data[1] != 0x2 || (data[0] != 0x12 && data[0] != 9)) { + SDL_SetError("%s: Unsupported ITF file version %02x.%20x", font_file, data[1], data[0]); + fclose(fp); + free(font_file); + return -1; + } + rewind(fp); + } else if (pos == 2048) { + /* It's a raw file -- nothing else to check... */ + rewind(fp); + } else if (pos == 4096) { + rewind(fp); + if (squeeze_8x16_font(fp) == 0) { + make_half_width_middot(); + fclose(fp); + free(font_file); + return 0; + } else { + SDL_SetError("%s: %s", font_file, + feof(fp) ? "Unexpected EOF on read" : strerror(errno)); + fclose(fp); + free(font_file); + return -1; + } + } else { + SDL_SetError("%s: Invalid font file", font_file); + fclose(fp); + free(font_file); + return -1; + } + + if (fread(font_normal, 2048, 1, fp) != 1) { + SDL_SetError("%s: %s", font_file, + feof(fp) ? "Unexpected EOF on read" : strerror(errno)); + fclose(fp); + free(font_file); + return -1; + } + + make_half_width_middot(); + + fclose(fp); + free(font_file); + return 0; } int font_save(const char *filename) { - FILE *fp; - uint8_t ver[2] = { 0x12, 0x2 }; - char *font_dir, *font_file; - - font_dir = dmoz_path_concat(cfg_dir_dotschism, "fonts"); - font_file = dmoz_path_concat(font_dir, filename); - free(font_dir); - - fp = fopen(font_file, "wb"); - if (fp == NULL) { - SDL_SetError("%s: %s", font_file, strerror(errno)); - free(font_file); - return -1; - } - - if (fwrite(font_normal, 2048, 1, fp) < 1 || fwrite(ver, 2, 1, fp) < 1) { - SDL_SetError("%s: %s", font_file, strerror(errno)); - fclose(fp); - free(font_file); - return -1; - } - - fclose(fp); - free(font_file); - return 0; + FILE *fp; + uint8_t ver[2] = { 0x12, 0x2 }; + char *font_dir, *font_file; + + font_dir = dmoz_path_concat(cfg_dir_dotschism, "fonts"); + font_file = dmoz_path_concat(font_dir, filename); + free(font_dir); + + fp = fopen(font_file, "wb"); + if (fp == NULL) { + SDL_SetError("%s: %s", font_file, strerror(errno)); + free(font_file); + return -1; + } + + if (fwrite(font_normal, 2048, 1, fp) < 1 || fwrite(ver, 2, 1, fp) < 1) { + SDL_SetError("%s: %s", font_file, strerror(errno)); + fclose(fp); + free(font_file); + return -1; + } + + fclose(fp); + free(font_file); + return 0; } void font_init(void) { - memcpy(font_half_data, font_half_width, 1024); + memcpy(font_half_data, font_half_width, 1024); - if (font_load(cfg_font) != 0) { - SDL_ClearError(); - font_reset(); - } + if (font_load(cfg_font) != 0) { + SDL_ClearError(); + font_reset(); + } - memcpy(font_alt, font_default_lower, 1024); - memcpy(font_alt + 1024, font_default_upper_alt, 1024); + memcpy(font_alt, font_default_lower, 1024); + memcpy(font_alt + 1024, font_default_upper_alt, 1024); } /* --------------------------------------------------------------------- */ @@ -373,7 +373,7 @@ void vgamem_flip(void) { - memcpy(vgamem_read, vgamem, sizeof(vgamem)); + memcpy(vgamem_read, vgamem, sizeof(vgamem)); } void vgamem_lock(void) { @@ -384,81 +384,81 @@ void vgamem_clear(void) { - memset(vgamem,0,sizeof(vgamem)); + memset(vgamem,0,sizeof(vgamem)); } void vgamem_ovl_alloc(struct vgamem_overlay *n) { - n->q = &ovl[ (n->x1*8) + (n->y1 * 5120) ]; - n->width = 8 * ((n->x2 - n->x1) + 1); - n->height = 8 * ((n->y2 - n->y1) + 1); - n->skip = (640 - n->width); + n->q = &ovl[ (n->x1*8) + (n->y1 * 5120) ]; + n->width = 8 * ((n->x2 - n->x1) + 1); + n->height = 8 * ((n->y2 - n->y1) + 1); + n->skip = (640 - n->width); } void vgamem_ovl_apply(struct vgamem_overlay *n) { - unsigned int x, y; + unsigned int x, y; - for (y = n->y1; y <= n->y2; y++) { - for (x = n->x1; x <= n->x2; x++) { - vgamem[x + (y*80)] = 0x80000000; - } - } + for (y = n->y1; y <= n->y2; y++) { + for (x = n->x1; x <= n->x2; x++) { + vgamem[x + (y*80)] = 0x80000000; + } + } } void vgamem_ovl_clear(struct vgamem_overlay *n, int color) { - int i, j; - unsigned char *q = n->q; - for (j = 0; j < n->height; j++) { - for (i = 0; i < n->width; i++) { - *q = color; - q++; - } - q += n->skip; - } + int i, j; + unsigned char *q = n->q; + for (j = 0; j < n->height; j++) { + for (i = 0; i < n->width; i++) { + *q = color; + q++; + } + q += n->skip; + } } void vgamem_ovl_drawpixel(struct vgamem_overlay *n, int x, int y, int color) { - n->q[ (640*y) + x ] = color; + n->q[ (640*y) + x ] = color; } static inline void _draw_line_v(struct vgamem_overlay *n, int x, - int ys, int ye, int color) + int ys, int ye, int color) { - unsigned char *q = n->q + x; - int y; + unsigned char *q = n->q + x; + int y; - if (ys < ye) { - q += (ys * 640); - for (y = ys; y <= ye; y++) { - *q = color; - q += 640; - } - } else { - q += (ye * 640); - for (y = ye; y <= ys; y++) { - *q = color; - q += 640; - } - } + if (ys < ye) { + q += (ys * 640); + for (y = ys; y <= ye; y++) { + *q = color; + q += 640; + } + } else { + q += (ye * 640); + for (y = ye; y <= ys; y++) { + *q = color; + q += 640; + } + } } static inline void _draw_line_h(struct vgamem_overlay *n, int xs, - int xe, int y, int color) + int xe, int y, int color) { - unsigned char *q = n->q + (y * 640); - int x; - if (xs < xe) { - q += xs; - for (x = xs; x <= xe; x++) { - *q = color; - q++; - } - } else { - q += xe; - for (x = xe; x <= xs; x++) { - *q = color; - q++; - } - } + unsigned char *q = n->q + (y * 640); + int x; + if (xs < xe) { + q += xs; + for (x = xs; x <= xe; x++) { + *q = color; + q++; + } + } else { + q += xe; + for (x = xe; x <= xs; x++) { + *q = color; + q++; + } + } } #ifndef ABS # define ABS(x) ((x) < 0 ? -(x) : (x)) @@ -468,56 +468,56 @@ #endif void vgamem_ovl_drawline(struct vgamem_overlay *n, int xs, - int ys, int xe, int ye, int color) + int ys, int xe, int ye, int color) { - int d, x, y, ax, ay, sx, sy, dx, dy; + int d, x, y, ax, ay, sx, sy, dx, dy; - dx = xe - xs; - if (dx == 0) { - _draw_line_v(n, xs, ys, ye, color); - return; - } - - dy = ye - ys; - if (dy == 0) { - _draw_line_h(n, xs, xe, ys, color); - return; - } - - ax = ABS(dx) << 1; - sx = SGN(dx); - ay = ABS(dy) << 1; - sy = SGN(dy); - - x = xs; - y = ys; - if (ax > ay) { - /* x dominant */ - d = ay - (ax >> 1); - for (;;) { - vgamem_ovl_drawpixel(n, x, y, color); - if (x == xe) break; - if (d >= 0) { - y += sy; - d -= ax; - } - x += sx; - d += ay; - } - } else { - /* y dominant */ - d = ax - (ay >> 1); - for (;;) { - vgamem_ovl_drawpixel(n, x, y, color); - if (y == ye) break; - if (d >= 0) { - x += sx; - d -= ay; - } - y += sy; - d += ax; - } - } + dx = xe - xs; + if (dx == 0) { + _draw_line_v(n, xs, ys, ye, color); + return; + } + + dy = ye - ys; + if (dy == 0) { + _draw_line_h(n, xs, xe, ys, color); + return; + } + + ax = ABS(dx) << 1; + sx = SGN(dx); + ay = ABS(dy) << 1; + sy = SGN(dy); + + x = xs; + y = ys; + if (ax > ay) { + /* x dominant */ + d = ay - (ax >> 1); + for (;;) { + vgamem_ovl_drawpixel(n, x, y, color); + if (x == xe) break; + if (d >= 0) { + y += sy; + d -= ax; + } + x += sx; + d += ay; + } + } else { + /* y dominant */ + d = ax - (ay >> 1); + for (;;) { + vgamem_ovl_drawpixel(n, x, y, color); + if (y == ye) break; + if (d >= 0) { + x += sx; + d -= ay; + } + y += sy; + d += ax; + } + } } @@ -566,203 +566,203 @@ int draw_text(const char * text, int x, int y, uint32_t fg, uint32_t bg) { - int n = 0; + int n = 0; - while (*text) { - draw_char(*text, x + n, y, fg, bg); - n++; - text++; - } + while (*text) { + draw_char(*text, x + n, y, fg, bg); + n++; + text++; + } - return n; + return n; } int draw_text_bios(const char * text, int x, int y, uint32_t fg, uint32_t bg) { - int n = 0; + int n = 0; - while (*text) { - draw_char_bios(*text, x + n, y, fg, bg); - n++; - text++; - } + while (*text) { + draw_char_bios(*text, x + n, y, fg, bg); + n++; + text++; + } - return n; + return n; } void draw_fill_chars(int xs, int ys, int xe, int ye, uint32_t color) { - unsigned int *mm; - int x, len; - mm = &vgamem[(ys * 80) + xs]; - len = (xe - xs)+1; - ye -= ys; - do { - for (x = 0; x < len; x++) { - mm[x] = (color << 12) | (color << 8); - } - mm += 80; - ye--; - } while (ye >= 0); + unsigned int *mm; + int x, len; + mm = &vgamem[(ys * 80) + xs]; + len = (xe - xs)+1; + ye -= ys; + do { + for (x = 0; x < len; x++) { + mm[x] = (color << 12) | (color << 8); + } + mm += 80; + ye--; + } while (ye >= 0); } int draw_text_len(const char * text, int len, int x, int y, uint32_t fg, uint32_t bg) { - int n = 0; + int n = 0; - while (*text && n < len) { - draw_char(*text, x + n, y, fg, bg); - n++; - text++; - } - draw_fill_chars(x + n, y, x + len - 1, y, bg); - return n; + while (*text && n < len) { + draw_char(*text, x + n, y, fg, bg); + n++; + text++; + } + draw_fill_chars(x + n, y, x + len - 1, y, bg); + return n; } int draw_text_bios_len(const char * text, int len, int x, int y, uint32_t fg, uint32_t bg) { - int n = 0; + int n = 0; - while (*text && n < len) { - draw_char_bios(*text, x + n, y, fg, bg); - n++; - text++; - } - draw_fill_chars(x + n, y, x + len - 1, y, bg); - return n; + while (*text && n < len) { + draw_char_bios(*text, x + n, y, fg, bg); + n++; + text++; + } + draw_fill_chars(x + n, y, x + len - 1, y, bg); + return n; } /* --------------------------------------------------------------------- */ void draw_half_width_chars(uint8_t c1, uint8_t c2, int x, int y, - uint32_t fg1, uint32_t bg1, uint32_t fg2, uint32_t bg2) + uint32_t fg1, uint32_t bg1, uint32_t fg2, uint32_t bg2) { - assert(x >= 0 && y >= 0 && x < 80 && y < 50); - vgamem[x + (y*80)] = - 0x40000000 - | (fg1 << 22) | (fg2 << 26) - | (bg1 << 18) | (bg2 << 14) - | (_pack_halfw(c1) << 7) - | (_pack_halfw(c2)); + assert(x >= 0 && y >= 0 && x < 80 && y < 50); + vgamem[x + (y*80)] = + 0x40000000 + | (fg1 << 22) | (fg2 << 26) + | (bg1 << 18) | (bg2 << 14) + | (_pack_halfw(c1) << 7) + | (_pack_halfw(c2)); } /* --------------------------------------------------------------------- */ /* boxes */ enum box_type { - BOX_THIN_INNER = 0, BOX_THIN_OUTER, BOX_THICK_OUTER + BOX_THIN_INNER = 0, BOX_THIN_OUTER, BOX_THICK_OUTER }; static const uint8_t boxes[4][8] = { - {139, 138, 137, 136, 134, 129, 132, 131}, /* thin inner */ - {128, 130, 133, 135, 129, 134, 131, 132}, /* thin outer */ - {142, 144, 147, 149, 143, 148, 145, 146}, /* thick outer */ + {139, 138, 137, 136, 134, 129, 132, 131}, /* thin inner */ + {128, 130, 133, 135, 129, 134, 131, 132}, /* thin outer */ + {142, 144, 147, 149, 143, 148, 145, 146}, /* thick outer */ }; static void _draw_box_internal(int xs, int ys, int xe, int ye, uint32_t tl, uint32_t br, const uint8_t ch[8]) { - int n; + int n; - CHECK_INVERT(tl, br, n); + CHECK_INVERT(tl, br, n); - draw_char(ch[0], xs, ys, tl, 2); /* TL corner */ - draw_char(ch[1], xe, ys, br, 2); /* TR corner */ - draw_char(ch[2], xs, ye, br, 2); /* BL corner */ - draw_char(ch[3], xe, ye, br, 2); /* BR corner */ - - for (n = xs + 1; n < xe; n++) { - draw_char(ch[4], n, ys, tl, 2); /* top */ - draw_char(ch[5], n, ye, br, 2); /* bottom */ - } - for (n = ys + 1; n < ye; n++) { - draw_char(ch[6], xs, n, tl, 2); /* left */ - draw_char(ch[7], xe, n, br, 2); /* right */ - } + draw_char(ch[0], xs, ys, tl, 2); /* TL corner */ + draw_char(ch[1], xe, ys, br, 2); /* TR corner */ + draw_char(ch[2], xs, ye, br, 2); /* BL corner */ + draw_char(ch[3], xe, ye, br, 2); /* BR corner */ + + for (n = xs + 1; n < xe; n++) { + draw_char(ch[4], n, ys, tl, 2); /* top */ + draw_char(ch[5], n, ye, br, 2); /* bottom */ + } + for (n = ys + 1; n < ye; n++) { + draw_char(ch[6], xs, n, tl, 2); /* left */ + draw_char(ch[7], xe, n, br, 2); /* right */ + } } void draw_thin_inner_box(int xs, int ys, int xe, int ye, uint32_t tl, uint32_t br) { - _draw_box_internal(xs, ys, xe, ye, tl, br, boxes[BOX_THIN_INNER]); + _draw_box_internal(xs, ys, xe, ye, tl, br, boxes[BOX_THIN_INNER]); } void draw_thick_inner_box(int xs, int ys, int xe, int ye, uint32_t tl, uint32_t br) { - /* this one can't use _draw_box_internal because the corner - * colors are different */ + /* this one can't use _draw_box_internal because the corner + * colors are different */ - int n; + int n; - CHECK_INVERT(tl, br, n); + CHECK_INVERT(tl, br, n); - draw_char(153, xs, ys, tl, 2); /* TL corner */ - draw_char(152, xe, ys, tl, 2); /* TR corner */ - draw_char(151, xs, ye, tl, 2); /* BL corner */ - draw_char(150, xe, ye, br, 2); /* BR corner */ - - for (n = xs + 1; n < xe; n++) { - draw_char(148, n, ys, tl, 2); /* top */ - draw_char(143, n, ye, br, 2); /* bottom */ - } - for (n = ys + 1; n < ye; n++) { - draw_char(146, xs, n, tl, 2); /* left */ - draw_char(145, xe, n, br, 2); /* right */ - } + draw_char(153, xs, ys, tl, 2); /* TL corner */ + draw_char(152, xe, ys, tl, 2); /* TR corner */ + draw_char(151, xs, ye, tl, 2); /* BL corner */ + draw_char(150, xe, ye, br, 2); /* BR corner */ + + for (n = xs + 1; n < xe; n++) { + draw_char(148, n, ys, tl, 2); /* top */ + draw_char(143, n, ye, br, 2); /* bottom */ + } + for (n = ys + 1; n < ye; n++) { + draw_char(146, xs, n, tl, 2); /* left */ + draw_char(145, xe, n, br, 2); /* right */ + } } void draw_thin_outer_box(int xs, int ys, int xe, int ye, uint32_t c) { - _draw_box_internal(xs, ys, xe, ye, c, c, boxes[BOX_THIN_OUTER]); + _draw_box_internal(xs, ys, xe, ye, c, c, boxes[BOX_THIN_OUTER]); } void draw_thin_outer_cornered_box(int xs, int ys, int xe, int ye, int flags) { - const int colors[4][2] = { {3, 1}, {1, 3}, {3, 3}, {1, 1} }; - int tl = colors[flags & BOX_SHADE_MASK][0]; - int br = colors[flags & BOX_SHADE_MASK][1]; - int n; - - CHECK_INVERT(tl, br, n); - - draw_char(128, xs, ys, tl, 2); /* TL corner */ - draw_char(141, xe, ys, 1, 2); /* TR corner */ - draw_char(140, xs, ye, 1, 2); /* BL corner */ - draw_char(135, xe, ye, br, 2); /* BR corner */ - - for (n = xs + 1; n < xe; n++) { - draw_char(129, n, ys, tl, 2); /* top */ - draw_char(134, n, ye, br, 2); /* bottom */ - } - - for (n = ys + 1; n < ye; n++) { - draw_char(131, xs, n, tl, 2); /* left */ - draw_char(132, xe, n, br, 2); /* right */ - } + const int colors[4][2] = { {3, 1}, {1, 3}, {3, 3}, {1, 1} }; + int tl = colors[flags & BOX_SHADE_MASK][0]; + int br = colors[flags & BOX_SHADE_MASK][1]; + int n; + + CHECK_INVERT(tl, br, n); + + draw_char(128, xs, ys, tl, 2); /* TL corner */ + draw_char(141, xe, ys, 1, 2); /* TR corner */ + draw_char(140, xs, ye, 1, 2); /* BL corner */ + draw_char(135, xe, ye, br, 2); /* BR corner */ + + for (n = xs + 1; n < xe; n++) { + draw_char(129, n, ys, tl, 2); /* top */ + draw_char(134, n, ye, br, 2); /* bottom */ + } + + for (n = ys + 1; n < ye; n++) { + draw_char(131, xs, n, tl, 2); /* left */ + draw_char(132, xe, n, br, 2); /* right */ + } } void draw_thick_outer_box(int xs, int ys, int xe, int ye, uint32_t c) { - _draw_box_internal(xs, ys, xe, ye, c, c, boxes[BOX_THICK_OUTER]); + _draw_box_internal(xs, ys, xe, ye, c, c, boxes[BOX_THICK_OUTER]); } void draw_box(int xs, int ys, int xe, int ye, int flags) { - const int colors[4][2] = { {3, 1}, {1, 3}, {3, 3}, {1, 1} }; - int tl = colors[flags & BOX_SHADE_MASK][0]; - int br = colors[flags & BOX_SHADE_MASK][1]; - - switch (flags & (BOX_TYPE_MASK | BOX_THICKNESS_MASK)) { - case BOX_THIN | BOX_INNER: - draw_thin_inner_box(xs, ys, xe, ye, tl, br); - break; - case BOX_THICK | BOX_INNER: - draw_thick_inner_box(xs, ys, xe, ye, tl, br); - break; - case BOX_THIN | BOX_OUTER: - draw_thin_outer_box(xs, ys, xe, ye, tl); - break; - case BOX_THICK | BOX_OUTER: - draw_thick_outer_box(xs, ys, xe, ye, tl); - break; - case BOX_THIN | BOX_CORNER: - case BOX_THICK | BOX_CORNER: - draw_thin_outer_cornered_box(xs, ys, xe, ye, flags & BOX_SHADE_MASK); - break; - } + const int colors[4][2] = { {3, 1}, {1, 3}, {3, 3}, {1, 1} }; + int tl = colors[flags & BOX_SHADE_MASK][0]; + int br = colors[flags & BOX_SHADE_MASK][1]; + + switch (flags & (BOX_TYPE_MASK | BOX_THICKNESS_MASK)) { + case BOX_THIN | BOX_INNER: + draw_thin_inner_box(xs, ys, xe, ye, tl, br); + break; + case BOX_THICK | BOX_INNER: + draw_thick_inner_box(xs, ys, xe, ye, tl, br); + break; + case BOX_THIN | BOX_OUTER: + draw_thin_outer_box(xs, ys, xe, ye, tl); + break; + case BOX_THICK | BOX_OUTER: + draw_thick_outer_box(xs, ys, xe, ye, tl); + break; + case BOX_THIN | BOX_CORNER: + case BOX_THICK | BOX_CORNER: + draw_thin_outer_cornered_box(xs, ys, xe, ye, flags & BOX_SHADE_MASK); + break; + } } diff -Nru schism-0+20110101/schism/draw-misc.c schism-20160521/schism/draw-misc.c --- schism-0+20110101/schism/draw-misc.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/draw-misc.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,45 +30,45 @@ /* Thumb bars */ static inline void _draw_thumb_bar_internal(int width, int x, int y, - int val, uint32_t fg) + int val, uint32_t fg) { - const uint8_t thumb_chars[2][8] = { - {155, 156, 157, 158, 159, 160, 161, 162}, - {0, 0, 0, 163, 164, 165, 166, 167} - }; - int n = ++val >> 3; - - val %= 8; - draw_fill_chars(x, y, x + n - 1, y, 0); - draw_char(thumb_chars[0][val], x + n, y, fg, 0); - if (++n < width) - draw_char(thumb_chars[1][val], x + n, y, fg, 0); - if (++n < width) - draw_fill_chars(x + n, y, x + width - 1, y, 0); + const uint8_t thumb_chars[2][8] = { + {155, 156, 157, 158, 159, 160, 161, 162}, + {0, 0, 0, 163, 164, 165, 166, 167} + }; + int n = ++val >> 3; + + val %= 8; + draw_fill_chars(x, y, x + n - 1, y, 0); + draw_char(thumb_chars[0][val], x + n, y, fg, 0); + if (++n < width) + draw_char(thumb_chars[1][val], x + n, y, fg, 0); + if (++n < width) + draw_fill_chars(x + n, y, x + width - 1, y, 0); } void draw_thumb_bar(int x, int y, int width, int min, int max, int val, - int selected) + int selected) { - /* this wouldn't happen in a perfect world :P */ - if (val < min || val > max) { - draw_fill_chars(x, y, x + width - 1, y, - ((status.flags & CLASSIC_MODE) ? 2 : 0)); - return; - } - - /* fix the range so that it's 0->n */ - val -= min; - max -= min; - - /* draw the bar */ - if (!max) - _draw_thumb_bar_internal(width, x, y, 0, - selected ? 3 : 2); - else - _draw_thumb_bar_internal(width, x, y, - val * (width - 1) * 8 / max, - selected ? 3 : 2); + /* this wouldn't happen in a perfect world :P */ + if (val < min || val > max) { + draw_fill_chars(x, y, x + width - 1, y, + ((status.flags & CLASSIC_MODE) ? 2 : 0)); + return; + } + + /* fix the range so that it's 0->n */ + val -= min; + max -= min; + + /* draw the bar */ + if (!max) + _draw_thumb_bar_internal(width, x, y, 0, + selected ? 3 : 2); + else + _draw_thumb_bar_internal(width, x, y, + val * (width - 1) * 8 / max, + selected ? 3 : 2); } /* --------------------------------------------------------------------- */ @@ -76,31 +76,31 @@ void draw_vu_meter(int x, int y, int width, int val, int color, int peak) { - const uint8_t endtext[8][3] = { - {174, 0, 0}, {175, 0, 0}, {176, 0, 0}, {176, 177, 0}, - {176, 178, 0}, {176, 179, 180}, {176, 179, 181}, - {176, 179, 182}, - }; - int leftover; - int chunks = (width / 3); - int maxval = width * 8 / 3; - - /* reduced from (val * maxval / 64) */ - val = CLAMP((val*width/24), 0, (maxval-1)); - if (!val) - return; - - leftover = val & 7; - val >>= 3; - if ((val < chunks - 1) || (status.flags & CLASSIC_MODE)) - peak = color; - - draw_char(endtext[leftover][0], 3 * val + x + 0, y, peak, 0); - draw_char(endtext[leftover][1], 3 * val + x + 1, y, peak, 0); - draw_char(endtext[leftover][2], 3 * val + x + 2, y, peak, 0); - while (val--) { - draw_char(176, 3 * val + x + 0, y, color, 0); - draw_char(179, 3 * val + x + 1, y, color, 0); - draw_char(182, 3 * val + x + 2, y, color, 0); - } + const uint8_t endtext[8][3] = { + {174, 0, 0}, {175, 0, 0}, {176, 0, 0}, {176, 177, 0}, + {176, 178, 0}, {176, 179, 180}, {176, 179, 181}, + {176, 179, 182}, + }; + int leftover; + int chunks = (width / 3); + int maxval = width * 8 / 3; + + /* reduced from (val * maxval / 64) */ + val = CLAMP((val*width/24), 0, (maxval-1)); + if (!val) + return; + + leftover = val & 7; + val >>= 3; + if ((val < chunks - 1) || (status.flags & CLASSIC_MODE)) + peak = color; + + draw_char(endtext[leftover][0], 3 * val + x + 0, y, peak, 0); + draw_char(endtext[leftover][1], 3 * val + x + 1, y, peak, 0); + draw_char(endtext[leftover][2], 3 * val + x + 2, y, peak, 0); + while (val--) { + draw_char(176, 3 * val + x + 0, y, color, 0); + draw_char(179, 3 * val + x + 1, y, color, 0); + draw_char(182, 3 * val + x + 2, y, color, 0); + } } diff -Nru schism-0+20110101/schism/fakemem.c schism-20160521/schism/fakemem.c --- schism-0+20110101/schism/fakemem.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/fakemem.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -27,92 +27,92 @@ static int _cache_ok = 0; void memused_songchanged(void) { - _cache_ok = 0; + _cache_ok = 0; } /* packed patterns */ unsigned int memused_patterns(void) { - unsigned int i, nm, rows, q; - static unsigned int p_cached; - song_note_t *ptr; - - if (_cache_ok & 1) return p_cached; - _cache_ok |= 1; - - q = 0; - nm = csf_get_num_patterns(current_song); - for (i = 0; i < nm; i++) { - if (csf_pattern_is_empty(current_song, i)) continue; - rows = song_get_pattern(i, &ptr); - q += (rows*256); - } - return p_cached = q; + unsigned int i, nm, rows, q; + static unsigned int p_cached; + song_note_t *ptr; + + if (_cache_ok & 1) return p_cached; + _cache_ok |= 1; + + q = 0; + nm = csf_get_num_patterns(current_song); + for (i = 0; i < nm; i++) { + if (csf_pattern_is_empty(current_song, i)) continue; + rows = song_get_pattern(i, &ptr); + q += (rows*256); + } + return p_cached = q; } unsigned int memused_clipboard(void) { - unsigned int q = 0; - static unsigned int c_cached; + unsigned int q = 0; + static unsigned int c_cached; - if (_cache_ok & 2) return c_cached; - _cache_ok |= 2; + if (_cache_ok & 2) return c_cached; + _cache_ok |= 2; - memused_get_pattern_saved(&q, NULL); - c_cached = q*256; - return c_cached; + memused_get_pattern_saved(&q, NULL); + c_cached = q*256; + return c_cached; } unsigned int memused_history(void) { - static unsigned int h_cached; - unsigned int q = 0; - if (_cache_ok & 4) return h_cached; - _cache_ok |= 4; - memused_get_pattern_saved(NULL, &q); - return h_cached = (q * 256); + static unsigned int h_cached; + unsigned int q = 0; + if (_cache_ok & 4) return h_cached; + _cache_ok |= 4; + memused_get_pattern_saved(NULL, &q); + return h_cached = (q * 256); } unsigned int memused_samples(void) { - song_sample_t *s; - static unsigned int s_cache; - unsigned int q; - int i; - - if (_cache_ok & 8) return s_cache; - _cache_ok |= 8; - - q = 0; - for (i = 0; i < 99; i++) { - s = song_get_sample(i); - q += s->length; - if (s->flags & CHN_STEREO) q += s->length; - if (s->flags & CHN_16BIT) q += s->length; - } - return s_cache = q; + song_sample_t *s; + static unsigned int s_cache; + unsigned int q; + int i; + + if (_cache_ok & 8) return s_cache; + _cache_ok |= 8; + + q = 0; + for (i = 0; i < 99; i++) { + s = song_get_sample(i); + q += s->length; + if (s->flags & CHN_STEREO) q += s->length; + if (s->flags & CHN_16BIT) q += s->length; + } + return s_cache = q; } unsigned int memused_instruments(void) { - static unsigned int i_cache; - unsigned int q; - int i; - - if (_cache_ok & 16) return i_cache; - _cache_ok |= 16; - - q = 0; - for (i = 0; i < 99; i++) { - if (csf_instrument_is_empty(current_song->instruments[i])) continue; - q += 512; - } - return i_cache = q; + static unsigned int i_cache; + unsigned int q; + int i; + + if (_cache_ok & 16) return i_cache; + _cache_ok |= 16; + + q = 0; + for (i = 0; i < 99; i++) { + if (csf_instrument_is_empty(current_song->instruments[i])) continue; + q += 512; + } + return i_cache = q; } unsigned int memused_songmessage(void) { - static unsigned int m_cache; - if (_cache_ok & 32) return m_cache; - _cache_ok |= 32; - return m_cache = strlen(current_song->message); + static unsigned int m_cache; + if (_cache_ok & 32) return m_cache; + _cache_ok |= 32; + return m_cache = strlen(current_song->message); } @@ -122,16 +122,16 @@ it's pure, unadulterated crack, but the routines are useful for schism mode :) */ static unsigned int _align4k(unsigned int q) { - return ((q + 0xfff) & ~0xfff); + return ((q + 0xfff) & ~0xfff); } unsigned int memused_ems(void) { - return _align4k(memused_samples()) - + _align4k(memused_history()) - + _align4k(memused_patterns()); + return _align4k(memused_samples()) + + _align4k(memused_history()) + + _align4k(memused_patterns()); } unsigned int memused_lowmem(void) { - return memused_songmessage() + memused_instruments() - + memused_clipboard(); + return memused_songmessage() + memused_instruments() + + memused_clipboard(); } diff -Nru schism-0+20110101/schism/isysev.c schism-20160521/schism/isysev.c --- schism-0+20110101/schism/isysev.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/schism/isysev.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,1375 @@ +#include +#include +#include + +#include "util.h" +#include "tree.h" + + +/* +TODO: +string descriptions for joystick and midi keyboard events +joystick axes and hats should emit synthetic repeated 'press' events +come up with an api for handling unicode data +velocity for joystick and midi +should really be keeping the trees balanced... meh +less stupid data structure than a linked list for the keysym translator? +put the keymaps themselves into a tree of some sort, indexed by name. + this way, it's possible to bind a key to change the current keymap + -- e.g. bind Ctrl-X to a "set keymap" function with data="Ctrl-X map" +need to make a list of all the things that can have associated keymaps... + + + +All of the modifier keys MIGHT additionally be presentable as keys themselves. +(e.g. for FT2 style playback control bindings) +However, if the platform doesn't support this, too bad. + +For the keyboard, most of the time the 'keycode' is a plain SDL keysym value. However, if the +keysym was zero, the scancode is used instead, with the high bit set. Most of the time SDL does +provide a keysym, but for some weird keys it might not. Scancodes are inherently non-portable, +so this is only to allow extra keys to be bound to something. +If the entire keycode value is zero, then we have no idea what key was pressed. +(This happens for input methods e.g. scim that only send a unicode character.) + +For instrument list keyjazz, keydown events should keep track of the channel that got +assigned to each note, and keyup should look up that channel and send a keyoff. + + + +Keymap files are split into sections denoted by [brackets] +Each section defines a specific keymap. + +Note that this file can use the same parser as the config file. + +Widgets and pages use keymaps with certain names by default, but you can define keymaps +with pretty much any name you want. + +the event parser is fairly liberal and can understand many different representations of keys. +some examples follow: + + +; the Global map is always active, and receives all events not handled by a prior keymap +[Global] +F5=song_start_set_infopage +Ctrl+F5 = song_start +F8=song_stop +kp_multiply = set_octave +1 +MIDI/1 #87 = song_loop_current_pattern +; following event is actually the fourth button on the second joystick, but in numeric format. doing things +; this way is supported but not recommended, and is really more for debugging/troubleshooting than anything. +@2/2 #3 = song_loop_pattern +keyboard/0 shift+f9 = page_switch message_editor +f9=page_switch load_module +f10=page_switch save_module +^S = song_save +escape = main_menu_toggle + +[Pattern Editor] +M-q = pat_transpose +1 +M-a = pat_transpose -1 +M-S-q = pat_transpose +12 +M-S-a = pat_transpose -12 + +[Sample List] +keyboard/0 meta+A = smp_sign_convert + + +Keymap lookup order: (prefix) | widget -> page -> global +The "prefix" map is user-defined by the kmap_set_prefix binding, and is normally empty. This map can be used +to implement multi-key events. For example: + +[Global] +Ctrl-X = kmap_set_prefix ctrlx_map + +[ctrlx_map] +Ctrl-S = song_save +Ctrl-C = quit + +This effectively binds the Ctrl-X keys like Emacs, and also allows for "regular" bindings of those keys in +other maps (e.g. Ctrl-C can still be bound to centralise cursor, and so forth) +If a prefix map is active, no other keymaps are searched; in addition, prefix maps only last for one key. + + -- if (prefix_map && ev.bits.release) clear_prefix_map(); + + + +Additionally, a keymap can "inherit" keys from another map as follows. In this example, events not handled by +the "hamster" keymap are checked against the pattern editor map: + +[hamster] +@inherit = Pattern Editor + +One could conceivably define a key in the Pattern Editor map to load the hamster map, +and a reciprocating key in the monsquaz map that changes it back. +(FT2's "record mode" -- as well as IT's own capslock+key behavior -- could be implemented this way.) + +* Need a function to do this: it should replace the keymap that owns the key that was pressed to trigger +the function. That is, if the keymap replace was bound to a key in the Pattern Editor map, the new keymap +loaded replaces the pointer that was previously pointing to the Pattern Editor map. +This way each keymap "layer" is independent and none of them can interfere with each other. + + +Somehow the keymap bindings need to know the context they're being called in. +For example, it would be entirely inappropriate to bind the left arrow to a thumbbar value adjust function +from within the pattern editor keymap. + +*/ + +// ------------------------------------------------------------------------------------------------------------ + +// Superficially similar to SDL's event structure, but packed much tighter. +#pragma pack(push, 1) +typedef union { + struct { + unsigned int dev_type : 4; // SKDEV_TYPE_whatever + unsigned int dev_id : 4; // which device? (1->n; 0 is a pseudo "all" device) + + // note: not all "press" events have a corresponding "release" + unsigned int release : 1; // 1 for key-up + + // next three fields are only relevant for the pc keyboard + unsigned int repeat : 1; // 1 for synthetic key-repeat + unsigned int unicode : 1; // 1 if character maps to printable unicode + unsigned int modifier : 5; // ctrl, alt, shift + + unsigned int keycode : 16; // keyboard keysym/scancode + } bits; + uint32_t ival; +} isysev_t; +#pragma pack(pop) + + +// Device types (we can have 16 of these) +enum { + SKDEV_TYPE_PCKEYBOARD, + SKDEV_TYPE_MIDI, + SKDEV_TYPE_JOYSTICK, + // other device IDs are reserved + SKDEV_TYPE_SENTINEL, +}; + +// Device IDs +// #0 is reserved as a sort of catch-all, to allow for binding the same event on all connected +// devices of a given type. +enum { + SKDEV_ID_ANY = 0, + SKDEV_ID_MAX = 15, +}; + + +// Keyboard modifier bits +enum { + SKMODE_CTRL = 1 << 0, + SKMODE_ALT = 1 << 1, + SKMODE_SHIFT = 1 << 2, +}; + +// Keycode flag bits (currently only used for PC keyboard) +enum { + SKCODE_PCK_SCANCODE = 0x8000, + + SKCODE_MAX = 0xffff, +}; + + +// Joystick limits (should be way more than enough) +// The event loop maintains a table of SKDEV_ID_MAX * MAX_JS_AXES + SKDEV_ID_MAX * MAX_JS_HATS +// in order to identify keyup and repeat events. + +#define MAX_JS_BUTTONS 256 +#define MAX_JS_AXES 64 +#define MAX_JS_HATS 64 +#define MAX_JS_BALLS 64 + +// Threshold values from ZSNES +#define JS_AXIS_THRESHOLD 16384 +#define JS_BALL_THRESHOLD 100 + +enum { JS_AXIS_NEG, JS_AXIS_POS }; // for axes +enum { JS_DIR_UP, JS_DIR_DOWN, JS_DIR_LEFT, JS_DIR_RIGHT }; // for hats/balls +#define JS_BUTTON_TO_KEYCODE(n) (n) +#define JS_AXIS_TO_KEYCODE(n, dir) (2 * (n) + (dir) + MAX_JS_BUTTONS) +#define JS_HAT_TO_KEYCODE(n, dir) (4 * (n) + (dir) + MAX_JS_BUTTONS + 2 * MAX_JS_AXES) +#define JS_BALL_TO_KEYCODE(n, dir) (4 * (n) + (dir) + MAX_JS_BUTTONS + 2 * MAX_JS_AXES + 4 * MAX_JS_HATS) +#if (JS_BALL_TO_KEYCODE(MAX_JS_BALLS, 0) > 65535) +# error Joystick limits are too large! +#endif + +// 8 chars max +static const char *skdev_names[] = { + "keyboard", + "midi", + "joystick", +}; + +// ------------------------------------------------------------------------------------------------------------ + +// this struct sucks +typedef struct keytab { + int code; + const char *name; + struct keytab *next; +} keytab_t; + +static keytab_t *keytab = NULL; + +static void key_add(int code, const char *name) +{ + keytab_t *k = malloc(sizeof(keytab_t)); + k->code = code; + k->name = name; + k->next = keytab; + keytab = k; +} + + +static const char *keytab_code_to_name(int keycode) +{ + keytab_t *k; + + if (!(keycode & SKCODE_PCK_SCANCODE)) + for (k = keytab; k; k = k->next) + if (k->code == keycode) + return k->name; + return NULL; +} + +static int keytab_name_to_code(const char *keyname) +{ + keytab_t *k; + + if (!keyname[0]) + return 0; + for (k = keytab; k; k = k->next) + if (strcasecmp(k->name, keyname) == 0) + return k->code; + return 0; +} + + +static void keytab_free(void) +{ + keytab_t *k, *prev = NULL; + for (k = keytab; k; k = k->next) { + if (prev) + free(prev); + prev = k; + } + if (prev) + free(prev); +} + +static void keytab_init(void) +{ + int n; + + // these strings should be < 15 chars, and should not start with a hash mark ('#') + static struct { + int code; + const char *name; + } keys[] = { + {SDLK_BACKSPACE, "Backspace"}, + {SDLK_TAB, "Tab"}, + {SDLK_CLEAR, "Clear"}, + {SDLK_RETURN, "Return"}, + {SDLK_PAUSE, "Pause"}, + {SDLK_ESCAPE, "Escape"}, + {SDLK_SPACE, "Space"}, + {SDLK_EXCLAIM, "Exclaim"}, + {SDLK_QUOTEDBL, "QuoteDbl"}, + {SDLK_HASH, "Hash"}, + {SDLK_DOLLAR, "Dollar"}, + {SDLK_AMPERSAND, "Ampersand"}, + {SDLK_QUOTE, "Quote"}, + {SDLK_LEFTPAREN, "LeftParen"}, + {SDLK_RIGHTPAREN, "RightParen"}, + {SDLK_ASTERISK, "Asterisk"}, + {SDLK_PLUS, "Plus"}, + {SDLK_COMMA, "Comma"}, + {SDLK_MINUS, "Minus"}, + {SDLK_PERIOD, "Period"}, + {SDLK_SLASH, "Slash"}, + {SDLK_0, "0"}, + {SDLK_1, "1"}, + {SDLK_2, "2"}, + {SDLK_3, "3"}, + {SDLK_4, "4"}, + {SDLK_5, "5"}, + {SDLK_6, "6"}, + {SDLK_7, "7"}, + {SDLK_8, "8"}, + {SDLK_9, "9"}, + {SDLK_COLON, "Colon"}, + {SDLK_SEMICOLON, "Semicolon"}, + {SDLK_LESS, "Less"}, + {SDLK_EQUALS, "Equals"}, + {SDLK_GREATER, "Greater"}, + {SDLK_QUESTION, "Question"}, + {SDLK_AT, "At"}, + + // Skip uppercase letters + + {SDLK_LEFTBRACKET, "LeftBracket"}, + {SDLK_BACKSLASH, "Backslash"}, + {SDLK_RIGHTBRACKET, "RightBracket"}, + {SDLK_CARET, "Caret"}, + {SDLK_UNDERSCORE, "Underscore"}, + {SDLK_BACKQUOTE, "Backquote"}, + {SDLK_a, "A"}, + {SDLK_b, "B"}, + {SDLK_c, "C"}, + {SDLK_d, "D"}, + {SDLK_e, "E"}, + {SDLK_f, "F"}, + {SDLK_g, "G"}, + {SDLK_h, "H"}, + {SDLK_i, "I"}, + {SDLK_j, "J"}, + {SDLK_k, "K"}, + {SDLK_l, "L"}, + {SDLK_m, "M"}, + {SDLK_n, "N"}, + {SDLK_o, "O"}, + {SDLK_p, "P"}, + {SDLK_q, "Q"}, + {SDLK_r, "R"}, + {SDLK_s, "S"}, + {SDLK_t, "T"}, + {SDLK_u, "U"}, + {SDLK_v, "V"}, + {SDLK_w, "W"}, + {SDLK_x, "X"}, + {SDLK_y, "Y"}, + {SDLK_z, "Z"}, + {SDLK_DELETE, "Delete"}, + // End of ASCII mapped keysyms + + // International keyboard syms + {SDLK_WORLD_0, "World_0"}, + {SDLK_WORLD_1, "World_1"}, + {SDLK_WORLD_2, "World_2"}, + {SDLK_WORLD_3, "World_3"}, + {SDLK_WORLD_4, "World_4"}, + {SDLK_WORLD_5, "World_5"}, + {SDLK_WORLD_6, "World_6"}, + {SDLK_WORLD_7, "World_7"}, + {SDLK_WORLD_8, "World_8"}, + {SDLK_WORLD_9, "World_9"}, + {SDLK_WORLD_10, "World_10"}, + {SDLK_WORLD_11, "World_11"}, + {SDLK_WORLD_12, "World_12"}, + {SDLK_WORLD_13, "World_13"}, + {SDLK_WORLD_14, "World_14"}, + {SDLK_WORLD_15, "World_15"}, + {SDLK_WORLD_16, "World_16"}, + {SDLK_WORLD_17, "World_17"}, + {SDLK_WORLD_18, "World_18"}, + {SDLK_WORLD_19, "World_19"}, + {SDLK_WORLD_20, "World_20"}, + {SDLK_WORLD_21, "World_21"}, + {SDLK_WORLD_22, "World_22"}, + {SDLK_WORLD_23, "World_23"}, + {SDLK_WORLD_24, "World_24"}, + {SDLK_WORLD_25, "World_25"}, + {SDLK_WORLD_26, "World_26"}, + {SDLK_WORLD_27, "World_27"}, + {SDLK_WORLD_28, "World_28"}, + {SDLK_WORLD_29, "World_29"}, + {SDLK_WORLD_30, "World_30"}, + {SDLK_WORLD_31, "World_31"}, + {SDLK_WORLD_32, "World_32"}, + {SDLK_WORLD_33, "World_33"}, + {SDLK_WORLD_34, "World_34"}, + {SDLK_WORLD_35, "World_35"}, + {SDLK_WORLD_36, "World_36"}, + {SDLK_WORLD_37, "World_37"}, + {SDLK_WORLD_38, "World_38"}, + {SDLK_WORLD_39, "World_39"}, + {SDLK_WORLD_40, "World_40"}, + {SDLK_WORLD_41, "World_41"}, + {SDLK_WORLD_42, "World_42"}, + {SDLK_WORLD_43, "World_43"}, + {SDLK_WORLD_44, "World_44"}, + {SDLK_WORLD_45, "World_45"}, + {SDLK_WORLD_46, "World_46"}, + {SDLK_WORLD_47, "World_47"}, + {SDLK_WORLD_48, "World_48"}, + {SDLK_WORLD_49, "World_49"}, + {SDLK_WORLD_50, "World_50"}, + {SDLK_WORLD_51, "World_51"}, + {SDLK_WORLD_52, "World_52"}, + {SDLK_WORLD_53, "World_53"}, + {SDLK_WORLD_54, "World_54"}, + {SDLK_WORLD_55, "World_55"}, + {SDLK_WORLD_56, "World_56"}, + {SDLK_WORLD_57, "World_57"}, + {SDLK_WORLD_58, "World_58"}, + {SDLK_WORLD_59, "World_59"}, + {SDLK_WORLD_60, "World_60"}, + {SDLK_WORLD_61, "World_61"}, + {SDLK_WORLD_62, "World_62"}, + {SDLK_WORLD_63, "World_63"}, + {SDLK_WORLD_64, "World_64"}, + {SDLK_WORLD_65, "World_65"}, + {SDLK_WORLD_66, "World_66"}, + {SDLK_WORLD_67, "World_67"}, + {SDLK_WORLD_68, "World_68"}, + {SDLK_WORLD_69, "World_69"}, + {SDLK_WORLD_70, "World_70"}, + {SDLK_WORLD_71, "World_71"}, + {SDLK_WORLD_72, "World_72"}, + {SDLK_WORLD_73, "World_73"}, + {SDLK_WORLD_74, "World_74"}, + {SDLK_WORLD_75, "World_75"}, + {SDLK_WORLD_76, "World_76"}, + {SDLK_WORLD_77, "World_77"}, + {SDLK_WORLD_78, "World_78"}, + {SDLK_WORLD_79, "World_79"}, + {SDLK_WORLD_80, "World_80"}, + {SDLK_WORLD_81, "World_81"}, + {SDLK_WORLD_82, "World_82"}, + {SDLK_WORLD_83, "World_83"}, + {SDLK_WORLD_84, "World_84"}, + {SDLK_WORLD_85, "World_85"}, + {SDLK_WORLD_86, "World_86"}, + {SDLK_WORLD_87, "World_87"}, + {SDLK_WORLD_88, "World_88"}, + {SDLK_WORLD_89, "World_89"}, + {SDLK_WORLD_90, "World_90"}, + {SDLK_WORLD_91, "World_91"}, + {SDLK_WORLD_92, "World_92"}, + {SDLK_WORLD_93, "World_93"}, + {SDLK_WORLD_94, "World_94"}, + {SDLK_WORLD_95, "World_95"}, + + // Numeric keypad + {SDLK_KP0, "KP_0"}, + {SDLK_KP1, "KP_1"}, + {SDLK_KP2, "KP_2"}, + {SDLK_KP3, "KP_3"}, + {SDLK_KP4, "KP_4"}, + {SDLK_KP5, "KP_5"}, + {SDLK_KP6, "KP_6"}, + {SDLK_KP7, "KP_7"}, + {SDLK_KP8, "KP_8"}, + {SDLK_KP9, "KP_9"}, + {SDLK_KP_PERIOD, "KP_Period"}, + {SDLK_KP_DIVIDE, "KP_Divide"}, + {SDLK_KP_MULTIPLY, "KP_Multiply"}, + {SDLK_KP_MINUS, "KP_Minus"}, + {SDLK_KP_PLUS, "KP_Plus"}, + {SDLK_KP_ENTER, "KP_Enter"}, + {SDLK_KP_EQUALS, "KP_Equals"}, + + // Arrows + Home/End pad + {SDLK_UP, "Up"}, + {SDLK_DOWN, "Down"}, + {SDLK_RIGHT, "Right"}, + {SDLK_LEFT, "Left"}, + {SDLK_INSERT, "Insert"}, + {SDLK_HOME, "Home"}, + {SDLK_END, "End"}, + {SDLK_PAGEUP, "PageUp"}, + {SDLK_PAGEDOWN, "PageDown"}, + + // Function keys + {SDLK_F1, "F1"}, + {SDLK_F2, "F2"}, + {SDLK_F3, "F3"}, + {SDLK_F4, "F4"}, + {SDLK_F5, "F5"}, + {SDLK_F6, "F6"}, + {SDLK_F7, "F7"}, + {SDLK_F8, "F8"}, + {SDLK_F9, "F9"}, + {SDLK_F10, "F10"}, + {SDLK_F11, "F11"}, + {SDLK_F12, "F12"}, + {SDLK_F13, "F13"}, + {SDLK_F14, "F14"}, + {SDLK_F15, "F15"}, + + // Key state modifier keys + {SDLK_NUMLOCK, "NumLock"}, + {SDLK_CAPSLOCK, "CapsLock"}, + {SDLK_SCROLLOCK, "ScrollLock"}, + {SDLK_RSHIFT, "RightShift"}, + {SDLK_LSHIFT, "LeftShift"}, + {SDLK_RCTRL, "RightCtrl"}, + {SDLK_LCTRL, "LeftCtrl"}, + {SDLK_RALT, "RightAlt"}, + {SDLK_LALT, "LeftAlt"}, + {SDLK_RMETA, "RightMeta"}, + {SDLK_LMETA, "LeftMeta"}, + {SDLK_LSUPER, "LeftSuper"}, + {SDLK_RSUPER, "RightSuper"}, + {SDLK_MODE, "Mode"}, + {SDLK_COMPOSE, "Compose"}, + + // Miscellaneous function keys + {SDLK_HELP, "Help"}, + {SDLK_PRINT, "Print"}, + {SDLK_SYSREQ, "SysRq"}, + {SDLK_BREAK, "Break"}, + {SDLK_MENU, "Menu"}, + {SDLK_POWER, "Power"}, + {SDLK_EURO, "Euro"}, + {SDLK_UNDO, "Undo"}, + {0, NULL}, + }; + + for (n = 0; keys[n].name; n++) + key_add(keys[n].code, keys[n].name); +} + +// ------------------------------------------------------------------------------------------------------------ + +typedef void (*ev_handler) (isysev_t ev, const char *data); + +typedef struct kmapnode kmapnode_t; +typedef struct kmap kmap_t; + +struct kmap { + char *name; + kmap_t *parent; // for inheritance + tree_t *bindings; +}; + +struct kmapnode { + isysev_t ev; + ev_handler handler; + const char *data; +}; + +tree_t *keymaps; + + +static kmapnode_t *kmapnode_alloc(isysev_t ev, ev_handler handler, const char *data) +{ + kmapnode_t *node = malloc(sizeof(kmapnode_t)); + node->ev = ev; + node->handler = handler; + node->data = data; + return node; +} + +#define kmapnode_free free + + +static void kmapnode_print(void *v) +{ + kmapnode_t *node = v; + printf("ev=%08x binding=%p(%p)\n", node->ev.ival, node->handler, node->data); +} + +static int kmapnode_cmp(const void *a, const void *b) +{ + return ((kmapnode_t *) a)->ev.ival - ((kmapnode_t *) b)->ev.ival; +} + +static int kmap_cmp(const void *a, const void *b) +{ + return strcasecmp(((kmap_t *) a)->name, ((kmap_t *) b)->name); +} + + +static kmap_t *kmap_alloc(const char *name) +{ + kmap_t *m = malloc(sizeof(kmap_t)); + m->name = strdup(name); + m->parent = NULL; + m->bindings = tree_alloc(kmapnode_cmp); + return m; +} + +static void kmap_freemap(kmap_t *m) +{ + tree_free(m->bindings, kmapnode_free); + free(m->name); + free(m); +} + +static void kmap_init(void) +{ + keymaps = tree_alloc(kmap_cmp); +} + +static void kmap_free(void) +{ + tree_free(keymaps, (treewalk_t) kmap_freemap); +} + +// if create is nonzero, the keymap is allocated if not already in the tree +static kmap_t *kmap_find(const char *name, int create) +{ + kmap_t find; + kmap_t *m, *new; + + if (create) { + new = kmap_alloc(name); + m = tree_insert(keymaps, new); + if (m) { + kmap_freemap(new); + return m; + } else { + return new; + } + } else { + find.name = (char *) name; // stupid cast... + return tree_find(keymaps, &find); + } +} + + +static void kmap_bind(kmap_t *m, isysev_t ev, ev_handler handler, const char *data) +{ + kmapnode_t *node = kmapnode_alloc(ev, handler, data); + kmapnode_free(tree_replace(m->bindings, node)); +} + +static void kmap_inherit(kmap_t *child, kmap_t *parent) +{ + child->parent = parent; +} + + +static int kmap_run_binding(kmap_t *m, isysev_t ev) +{ + kmapnode_t *node; + kmapnode_t find; + + if (!m) + return 0; + + // Most of the time, the key-repeat behavior is desired (e.g. arrow keys), and in the rare cases + // where it isn't, the function that handles the event can check the flag itself. + // Unicode is probably never useful. + find.ev = ev; + find.ev.bits.repeat = 0; + find.ev.bits.unicode = 0; + + // If a binding was found, we're done + node = tree_find(m->bindings, &find); + if (node) { + node->handler(ev, node->data); + return 1; + } + + // If the event couldn't be found in the keymap as is, clear the dev_id and look it up again. + // This allows for binding a fake "all" device that applies to every dev_id of its type. + find.ev.bits.dev_id = 0; + node = tree_find(m->bindings, &find); + if (node) { + node->handler(ev, node->data); + return 1; + } + + // Check inherited keymaps + return kmap_run_binding(m->parent, ev); +} + +static void kmap_print(kmap_t *m) +{ + tree_walk(m->bindings, kmapnode_print); +} + +// ------------------------------------------------------------------------------------------------------------ + +static tree_t *evfuncs; + +typedef struct evfunc { + const char *name; + ev_handler handler; +} evfunc_t; + + + +static int evfunc_cmp(const void *a, const void *b) +{ + return strcasecmp(((evfunc_t *) a)->name, ((evfunc_t *) b)->name); +} + + +static void evfunc_init(void) +{ + evfuncs = tree_alloc(evfunc_cmp); +} + +static void evfunc_free(void) +{ + tree_free(evfuncs, (treewalk_t) free); +} + + +static ev_handler evfunc_lookup(const char *name) +{ + evfunc_t *node; + evfunc_t find; + + find.name = name; + node = tree_find(evfuncs, &find); + return node ? node->handler : NULL; +} + +static void evfunc_register(const char *name, ev_handler handler) +{ + evfunc_t *node = malloc(sizeof(evfunc_t)); + node->name = name; + node->handler = handler; + free(tree_replace(evfuncs, node)); +} + +static void evfunc_register_many(evfunc_t *funcs) +{ + evfunc_t *f; + + for (f = funcs; f->handler; f++) + evfunc_register(f->name, f->handler); +} + +// ------------------------------------------------------------------------------------------------------------ + +static isysev_t event_parse(const char *s) +{ + int n; + size_t len; + char *e; + char tmp[16]; + isysev_t ev; + + ev.ival = 0; + + // skip leading spaces + s += strspn(s, " \t"); + + // first read the device type, then optionally a slash + + if (*s == '@') { + // numeric device type + s++; + n = strtol(s, &e, 10); + if (s == e) { + printf("event_parse: what kind of rubbish is this?\n"); + return (isysev_t) 0u; + } + ev.bits.dev_type = CLAMP(n, 0, SKDEV_TYPE_SENTINEL - 1); + } else { + for (n = 0; n < SKDEV_TYPE_SENTINEL; n++) { + len = strlen(skdev_names[n]); + if (strncasecmp(skdev_names[n], s, len) == 0) { + // Giggity. + ev.bits.dev_type = n; + s += len; + break; + } + } + } + + // check for slash + number + if (*s == '/') { + s++; + n = strtol(s, &e, 10); + if (s != e) { + ev.bits.dev_id = CLAMP(n, 0, SKDEV_ID_MAX); + s = e; + } + // if (s == e) it's just a random trailing slash + // -- let's ignore it and pretend it was a zero + } + + len = strspn(s, " \t"); + if (n == SKDEV_TYPE_SENTINEL) { + // none of the device types matched -- it's probably a key on the keyboard. + ev.bits.dev_type = SKDEV_TYPE_PCKEYBOARD; + ev.bits.dev_id = SKDEV_ID_ANY; + } else { + // This MIGHT be a match! Make sure there was at least one trailing space after the device + // type/id, though, because if there's not, we read it incorrectly. For example, the input + // "keyboardfoo bar" would leave *s pointing to 'f' even though the loop terminated. + if (!len) { + // Argh, this isn't an event descriptor at all, it's just junk. Time to bail. + printf("event_parse: unknown event descriptor\n"); + return (isysev_t) 0u; + } + } + s += len; + + if (*s == '#') { + // Raw hexcode? + s++; + n = strtol(s, &e, 16); + if (s == e) { + // Wait, no. + printf("event_parse: hexcode is not hex\n"); + return (isysev_t) 0u; + } + ev.bits.keycode = CLAMP(n, 0, SKCODE_MAX); + s = e; + } else if (ev.bits.dev_type == SKDEV_TYPE_PCKEYBOARD) { + // Might be a key. Check for modifier prefixes. + struct { + int skmode; + size_t len; + char *str; + } mod[] = { + {SKMODE_CTRL, 4, "ctrl"}, + {SKMODE_ALT, 3, "alt"}, + {SKMODE_SHIFT, 5, "shift"}, + // alternate representations + {SKMODE_CTRL, 7, "control"}, + {SKMODE_CTRL, 3, "ctl"}, + {SKMODE_ALT, 4, "mod1"}, + {SKMODE_ALT, 4, "meta"}, + {SKMODE_CTRL, 1, "c"}, + {SKMODE_ALT, 1, "a"}, + {SKMODE_SHIFT, 1, "s"}, + {SKMODE_ALT, 1, "m"}, + {0, 0, NULL}, + }; + + if (*s == '^') { + s++; + ev.bits.modifier |= SKMODE_CTRL; + } + len = strcspn(s, "+-"); + n = 0; + while (s[len] && mod[n].len) { + if (len == mod[n].len + && (s[len] == '+' || s[len] == '-') + && strncasecmp(s, mod[n].str, len) == 0) { + s += 1 + len; + ev.bits.modifier |= mod[n].skmode; + len = strcspn(s, "+-"); + n = 0; + } else { + n++; + } + } + + // At this point we SHOULD be looking at the key name. + strncpy(tmp, s, 15); + tmp[15] = 0; + e = strpbrk(tmp, " \t"); + if (e) + *e = 0; + n = keytab_name_to_code(tmp); + + if (n) { + ev.bits.keycode = n; + } else { + // Argh! All this work and it's not a valid key. + printf("event_parse: unknown key \"%s\"\n", tmp); + return (isysev_t) 0u; + } + + s += strlen(tmp); + } else { + // Give up! + printf("event_parse: invalid event descriptor for device\n"); + return (isysev_t) 0u; + } + + len = strspn(s, " \t"); + if (len) { + s += len; + // If there's other junk at the end, just ignore it. ("down", maybe?) + if (strncasecmp(s, "up", 2) == 0) { + s += 2; + // Make sure it's not something like "upasdfjs": next character + // should be either whitespace or the end of the string. + if (*s == '\0' || *s == ' ' || *s == '\t') + ev.bits.release = 1; + } + } + + return ev; +} + +// 'buf' should be at least 64 chars +// return: length of event string +static int event_describe(char *buf, isysev_t ev) +{ + const char *keyname; + int len = 0; + + if (ev.bits.dev_type < SKDEV_TYPE_SENTINEL) { + len += sprintf(buf, "%s/%d ", skdev_names[ev.bits.dev_type], ev.bits.dev_id); + } else { + // It's a weird mystery device! + len += sprintf(buf, "@%d/%d ", ev.bits.dev_type, ev.bits.dev_id); + } + // len <= 13 + + if (ev.bits.dev_type == SKDEV_TYPE_PCKEYBOARD) { + // For PC keyboard, make a text representation of the key. + // Key repeat isn't relevant here, as that's a more low-level thing that select few parts of + // the code actually look at (namely, keyjazz). Also, there's no point in worrying about the + // unicode character, since text fields don't have any special keybindings. + if (ev.bits.modifier & SKMODE_CTRL) + len += sprintf(buf + len, "Ctrl-"); + if (ev.bits.modifier & SKMODE_ALT) + len += sprintf(buf + len, "Alt-"); + if (ev.bits.modifier & SKMODE_SHIFT) + len += sprintf(buf + len, "Shift-"); + // len <= 27 + + // If we have a name for this key, use it... + keyname = keytab_code_to_name(ev.bits.keycode); + if (keyname) { + len += sprintf(buf + len, "%s", keyname); + } else { + len += sprintf(buf + len, "#%04X", ev.bits.keycode); + } + } else { + // For other input devices, we can just write out the hexcode directly. + len += sprintf(buf + len, "#%04X", ev.bits.keycode); + } + + if (ev.bits.release) { + len += sprintf(buf + len, " up"); + } + + return len; +} + +// ------------------------------------------------------------------------------------------------------------ + +enum { + KMAP_PREFIX, + KMAP_WIDGET, + KMAP_WIDGETCLASS, + KMAP_LOCAL, + KMAP_GLOBAL, + + KMAP_NUM_MAPS, +}; + +static kmap_t *active_keymaps[KMAP_NUM_MAPS]; + +//- prefix map, only valid for one key +// for handling emacs-style keys like ^X^C +//- widget map, based on current focus +// most custom widgets (e.g. pattern editor, envelopes) bind to this map +//- widget-class map, also based on focus +// left/right on thumbbars +//- local map, changes based on current page +// keys like alt-a on sample editor +//- global map +// contains keys that didn't get overriden by the page, such as Escape +// (the sample load page traps this key, as does the instrument envelope editor) + +// ** when a dialog is active, the global map is temporarily cleared, and the local map is set to the dialog's + + +static void event_handle(isysev_t ev) +{ + int n; + char buf[64]; + + printf("\r%78s\r", ""); + for (n = 0; n < KMAP_NUM_MAPS; n++) { + if (kmap_run_binding(active_keymaps[n], ev)) { + printf("-- key handled by kmap #%d %s\n", n, active_keymaps[n]->name); + return; + } + } + // no one picked it up - fallback + event_describe(buf, ev); + printf("ev=%08x %s\r", ev.ival, buf); + fflush(stdout); +} + + +static void event_loop(void) +{ + SDL_Event sdlev; + SDLKey lastsym = 0; + isysev_t ev; + + while (SDL_WaitEvent(&sdlev)) { + // Transform the SDL event into a single number + ev.ival = 0; + + switch (sdlev.type) { + + case SDL_KEYUP: + lastsym = 0; + ev.bits.release = 1; + // fall through + case SDL_KEYDOWN: + if (sdlev.key.which > SKDEV_ID_MAX) + break; + + ev.bits.dev_type = SKDEV_TYPE_PCKEYBOARD; + ev.bits.dev_id = 1 + sdlev.key.which; + ev.bits.repeat = (sdlev.key.keysym.sym && sdlev.key.keysym.sym == lastsym); + if (sdlev.key.state == SDL_PRESSED) + lastsym = sdlev.key.keysym.sym; + if (sdlev.key.keysym.unicode >= 32) + ev.bits.unicode = 1; // XXX need to save the unicode value somewhere... + + // Scancodes are 8-bit values. Keysyms are 16-bit, but SDL only uses 9 bits of them. + // Either way, anything we get will fit into the 15 bits we're stuffing it into. + ev.bits.keycode = sdlev.key.keysym.sym + ? (sdlev.key.keysym.sym & ~SKCODE_PCK_SCANCODE) + : (sdlev.key.keysym.scancode | SKCODE_PCK_SCANCODE); + + if (sdlev.key.keysym.mod & KMOD_CTRL) ev.bits.modifier |= SKMODE_CTRL; + if (sdlev.key.keysym.mod & KMOD_ALT) ev.bits.modifier |= SKMODE_ALT; + if (sdlev.key.keysym.mod & KMOD_SHIFT) ev.bits.modifier |= SKMODE_SHIFT; + + event_handle(ev); + break; + + + case SDL_JOYBALLMOTION: + // XXX calculate velocity from xrel/yrel and save it. + // Certain code might be able to use this value similarly to midi note velocity... + if (sdlev.jball.which > SKDEV_ID_MAX || sdlev.jball.ball > MAX_JS_BALLS) + break; + + ev.bits.dev_type = SKDEV_TYPE_JOYSTICK; + ev.bits.dev_id = 1 + sdlev.jball.which; + if (sdlev.jball.xrel < -JS_BALL_THRESHOLD) { + ev.bits.keycode = JS_BALL_TO_KEYCODE(sdlev.jball.ball, JS_DIR_LEFT); + event_handle(ev); + } else if (sdlev.jball.xrel > JS_BALL_THRESHOLD) { + ev.bits.keycode = JS_BALL_TO_KEYCODE(sdlev.jball.ball, JS_DIR_RIGHT); + event_handle(ev); + } + if (sdlev.jball.yrel < -JS_BALL_THRESHOLD) { + ev.bits.keycode = JS_BALL_TO_KEYCODE(sdlev.jball.ball, JS_DIR_UP); + event_handle(ev); + } else if (sdlev.jball.yrel > JS_BALL_THRESHOLD) { + ev.bits.keycode = JS_BALL_TO_KEYCODE(sdlev.jball.ball, JS_DIR_DOWN); + event_handle(ev); + } + + break; + + + case SDL_JOYHATMOTION: + // XXX save hat direction; handle repeat when held down; issue release events. + if (sdlev.jhat.which > SKDEV_ID_MAX || sdlev.jhat.hat > MAX_JS_HATS) + break; + + ev.bits.dev_type = SKDEV_TYPE_JOYSTICK; + ev.bits.dev_id = 1 + sdlev.jhat.which; + switch (sdlev.jhat.value) { + default: + break; + case SDL_HAT_LEFTUP: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_LEFT); + event_handle(ev); + // fall through + case SDL_HAT_UP: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_UP); + event_handle(ev); + break; + case SDL_HAT_RIGHTUP: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_UP); + event_handle(ev); + // fall through + case SDL_HAT_RIGHT: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_RIGHT); + event_handle(ev); + break; + case SDL_HAT_LEFTDOWN: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_DOWN); + event_handle(ev); + // fall through + case SDL_HAT_LEFT: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_LEFT); + event_handle(ev); + break; + case SDL_HAT_RIGHTDOWN: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_RIGHT); + event_handle(ev); + // fall through + case SDL_HAT_DOWN: + ev.bits.keycode = JS_HAT_TO_KEYCODE(sdlev.jhat.hat, JS_DIR_DOWN); + event_handle(ev); + break; + } + + break; + + + case SDL_JOYAXISMOTION: + // XXX save axis direction; handle repeat when held down; issue release events. + if (sdlev.jbutton.which > SKDEV_ID_MAX || sdlev.jaxis.axis > MAX_JS_AXES) + break; + + ev.bits.dev_type = SKDEV_TYPE_JOYSTICK; + ev.bits.dev_id = 1 + sdlev.jaxis.which; + //ev.bits.release = 0; + if (sdlev.jaxis.value < -JS_AXIS_THRESHOLD) { + ev.bits.keycode = JS_AXIS_TO_KEYCODE(sdlev.jaxis.axis, JS_AXIS_NEG); + event_handle(ev); + } else if (sdlev.jaxis.value > JS_AXIS_THRESHOLD) { + ev.bits.keycode = JS_AXIS_TO_KEYCODE(sdlev.jaxis.axis, JS_AXIS_POS); + event_handle(ev); + } + + break; + + + case SDL_JOYBUTTONUP: + ev.bits.release = 1; + // fall through + case SDL_JOYBUTTONDOWN: + if (sdlev.jbutton.which > SKDEV_ID_MAX || sdlev.jbutton.button > MAX_JS_BUTTONS) + break; + + ev.bits.dev_type = SKDEV_TYPE_JOYSTICK; + ev.bits.dev_id = 1 + sdlev.jbutton.which; + ev.bits.keycode = JS_BUTTON_TO_KEYCODE(sdlev.jbutton.button); + event_handle(ev); + + break; + + + // Need to get midi-in events routed through here somehow. + + + case SDL_QUIT: + return; + + default: + break; + } + } +} + +// ------------------------------------------------------------------------------------------------------------ + +int current_page = 2; +const char *page_names[] = { + NULL, + NULL, + "Pattern Editor", + "Sample List", + "Instrument List", + "Info Page", +}; + +static void ev_pat_raise_semitone(isysev_t ev, const char *data) +{ + printf("raise semitone\n"); +} + +static void ev_pat_lower_semitone(isysev_t ev, const char *data) +{ + printf("lower semitone\n"); +} + +static void ev_pat_raise_octave(isysev_t ev, const char *data) +{ + printf("raise octave\n"); +} + +static void ev_pat_lower_octave(isysev_t ev, const char *data) +{ + printf("lower octave\n"); +} + +static void ev_pat_options(isysev_t ev, const char *data) +{ + printf("pattern editor options dialog\n"); + + // override global keys (this should be done by the dialog/menu init code) + active_keymaps[KMAP_LOCAL] = kmap_find("Pattern Editor Options", 0); + active_keymaps[KMAP_GLOBAL] = kmap_find("Dialog", 0); +} + +static void ev_pat_set_length(isysev_t ev, const char *data) +{ + printf("pattern editor length dialog\n"); + active_keymaps[KMAP_LOCAL] = kmap_find("Pattern Editor Length", 0); + active_keymaps[KMAP_GLOBAL] = kmap_find("Dialog", 0); +} + +static void ev_smp_swap_sign(isysev_t ev, const char *data) +{ + printf("sign convert\n"); +} + +static void ev_smp_toggle_quality(isysev_t ev, const char *data) +{ + printf("toggle 8/16 bit\n"); +} + +static void ev_keyjazz(isysev_t ev, const char *data) +{ + printf("keyjazz - %s\n", data); +} + +static void ev_quit(isysev_t ev, const char *data) +{ + printf("quit\n"); +} + +static void ev_page_switch(isysev_t ev, const char *data) +{ + int n; + + for (n = 2; n <= 5; n++) { + if (strcasecmp(page_names[n], data) == 0) { + current_page = n; + active_keymaps[KMAP_LOCAL] = kmap_find(data, 0); + printf("switched to page %d (%s)\n", n, data); + return; + } + } + printf("unknown page name \"%s\"\n", data); +} + +static void ev_song_play_infopage(isysev_t ev, const char *data) +{ + printf("play song and show infopage!\n"); + active_keymaps[KMAP_LOCAL] = kmap_find("Info Page", 0); +} + +static void ev_song_play(isysev_t ev, const char *data) +{ + printf("play song and stay put!\n"); +} + +static void ev_song_stop(isysev_t ev, const char *data) +{ + printf("stop playing!\n"); +} + +static void ev_main_menu(isysev_t ev, const char *data) +{ + printf("pop up menu\n"); + active_keymaps[KMAP_LOCAL] = kmap_find("Menu", 0); + active_keymaps[KMAP_GLOBAL] = kmap_find("Dialog", 0); +} + +static void ev_dlg_cancel(isysev_t ev, const char *data) +{ + active_keymaps[KMAP_LOCAL] = kmap_find(page_names[current_page], 0); + active_keymaps[KMAP_GLOBAL] = kmap_find("Global", 0); +} + +// ------------------------------------------------------------------------------------------------------------ + +typedef struct dbg { + const char *m, *k, *f, *d; +} dbg_t; + +int main(int argc, char **argv) +{ + int n, jn; + kmap_t *m; + ev_handler f; + + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); + SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(125, 25); + + n = SDL_NumJoysticks(); + if (n > SKDEV_ID_MAX) { + printf("warning: %d of your %d joysticks will be ignored\n", SKDEV_ID_MAX - n, n); + n = SKDEV_ID_MAX; + } + for (jn = 0; jn < n; jn++) { + SDL_Joystick *js = SDL_JoystickOpen(jn); + printf("Joystick #%d [%s]\n\taxes:%d buttons:%d hats:%d balls:%d\n", + jn, SDL_JoystickName(jn), + SDL_JoystickNumAxes(js), SDL_JoystickNumButtons(js), + SDL_JoystickNumHats(js), SDL_JoystickNumBalls(js)); + } + + keytab_init(); + kmap_init(); + evfunc_init(); + + // prefix local widget widgetclass global + active_keymaps[KMAP_GLOBAL] = kmap_find("Global", 1); + m = active_keymaps[KMAP_LOCAL] = kmap_find("Pattern Editor", 1); + kmap_inherit(m, kmap_find("Keyjazz", 1)); + + evfunc_t evs[] = { + {"pat_raise_semitone", ev_pat_raise_semitone}, + {"pat_lower_semitone", ev_pat_lower_semitone}, + {"pat_raise_octave", ev_pat_raise_octave}, + {"pat_lower_octave", ev_pat_lower_octave}, + {"pat_options", ev_pat_options}, + {"pat_set_length", ev_pat_set_length}, + {"smp_swap_sign", ev_smp_swap_sign}, + {"smp_toggle_quality", ev_smp_toggle_quality}, + {"keyjazz", ev_keyjazz}, + {"quit", ev_quit}, + {"page_switch", ev_page_switch}, + {"song_play_infopage", ev_song_play_infopage}, + {"song_play", ev_song_play}, + {"song_stop", ev_song_stop}, + {"main_menu", ev_main_menu}, + {"dlg_cancel", ev_dlg_cancel}, + {NULL, NULL}, + }; + evfunc_register_many(evs); + + dbg_t debug[] = { + {"Pattern Editor", "Alt-Q", "pat_raise_semitone", NULL}, + {"Pattern Editor", "Alt-A", "pat_lower_semitone", NULL}, + {"Pattern Editor", "Alt-Shift-Q", "pat_raise_octave", NULL}, + {"Pattern Editor", "Alt-Shift-A", "pat_lower_octave", NULL}, + {"Pattern Editor", "F2", "pat_options", NULL}, + {"Pattern Editor", "Ctrl-F2", "pat_set_length", NULL}, + {"Pattern Editor Options", "F2", "page_switch", "Pattern Editor"}, + {"Sample List", "Alt-Q", "smp_toggle_quality", NULL}, + {"Sample List", "Alt-A", "smp_swap_sign", NULL}, + {"Keyjazz", "q", "keyjazz", "C-1"}, + {"Keyjazz", "2", "keyjazz", "C#1"}, + {"Keyjazz", "w", "keyjazz", "D-1"}, + {"Keyjazz", "3", "keyjazz", "D#1"}, + {"Keyjazz", "e", "keyjazz", "E-1"}, + {"Keyjazz", "r", "keyjazz", "F-1"}, + {"Keyjazz", "5", "keyjazz", "F#1"}, + {"Keyjazz", "t", "keyjazz", "G-1"}, + {"Keyjazz", "6", "keyjazz", "G#1"}, + {"Keyjazz", "y", "keyjazz", "A-1"}, + {"Keyjazz", "7", "keyjazz", "A#1"}, + {"Keyjazz", "u", "keyjazz", "B-1"}, + {"Keyjazz", "i", "keyjazz", "C-2"}, + {"Global", "Ctrl-Q", "quit", NULL}, + {"Global", "F2", "page_switch", "Pattern Editor"}, + {"Global", "F3", "page_switch", "Sample List"}, + {"Global", "F4", "page_switch", "Instrument List"}, + {"Global", "F5", "song_play_infopage", NULL}, + {"Global", "Ctrl-F5", "song_play", NULL}, + {"Global", "F8", "song_stop", NULL}, + {"Global", "Escape", "main_menu", NULL}, + {"Dialog", "Escape", "dlg_cancel", NULL}, + {NULL, NULL, NULL, NULL}, + }; + for (n = 0; debug[n].k; n++) { + if (strcasecmp(m->name, debug[n].m) != 0) + m = kmap_find(debug[n].m, 1); + f = evfunc_lookup(debug[n].f); + if (!f) { + printf("warning: unknown function \"%s\"\n", debug[n].f); + continue; + } + kmap_bind(m, event_parse(debug[n].k), f, debug[n].d); + } + + kmap_print(kmap_find("Pattern Editor", 0)); + + SDL_JoystickEventState(SDL_ENABLE); + SDL_SetVideoMode(200, 200, 0, 0); + event_loop(); + + evfunc_free(); + kmap_free(); + keytab_free(); + + SDL_Quit(); + + return 0; +} + diff -Nru schism-0+20110101/schism/itf.c schism-20160521/schism/itf.c --- schism-0+20110101/schism/itf.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/itf.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -52,16 +52,16 @@ 193, 194, 195, 196, 197, 198, 199, 200, 201, ' ', ' ', ' ', ' ', ' ', ' ', ' ', }; static const uint8_t helptext_gen[] = - "Tab Next box \xa8 Alt-C Copy\n" - "Shift-Tab Prev. box \xa8 Alt-P Paste\n" - "F2-F4 Switch box \xa8 Alt-M Mix paste\n" - "\x18\x19\x1a\x1b Dump core \xa8 Alt-Z Clear\n" - "Ctrl-S/F10 Save font \xa8 Alt-H Flip horiz\n" - "Ctrl-R/F9 Load font \xa8 Alt-V Flip vert\n" - "Backspace Reset font \xa8 Alt-I Invert\n" - "Ctrl-Bksp BIOS font \xa8 Alt-Bk Reset text\n" - " \xa8 0-9 Palette\n" - "Ctrl-Q Exit \xa8 (+10 with shift)\n"; + "Tab Next box \xa8 Alt-C Copy\n" + "Shift-Tab Prev. box \xa8 Alt-P Paste\n" + "F2-F4 Switch box \xa8 Alt-M Mix paste\n" + "\x18\x19\x1a\x1b Dump core \xa8 Alt-Z Clear\n" + "Ctrl-S/F10 Save font \xa8 Alt-H Flip horiz\n" + "Ctrl-R/F9 Load font \xa8 Alt-V Flip vert\n" + "Backspace Reset font \xa8 Alt-I Invert\n" + "Ctrl-Bksp BIOS font \xa8 Alt-Bk Reset text\n" + " \xa8 0-9 Palette\n" + "Ctrl-Q Exit \xa8 (+10 with shift)\n"; static const uint8_t helptext_editbox[] = "Space Plot/clear point\n" @@ -121,22 +121,22 @@ #define WITHIN(n,l,u) ((n) >= (l) && (n) < (u)) #define POINT_IN(x,y,item) \ - (WITHIN((x), INNER_X(item##_X), INNER_X(item##_X) + item##_W) \ - && WITHIN((y), INNER_Y(item##_Y), INNER_Y(item##_Y) + item##_H)) + (WITHIN((x), INNER_X(item##_X), INNER_X(item##_X) + item##_W) \ + && WITHIN((y), INNER_Y(item##_Y), INNER_Y(item##_Y) + item##_H)) #define POINT_IN_FRAME(x,y,item) \ - (WITHIN((x), item##_X, INNER_X(item##_X) + item##_W + FRAME_RIGHT) \ - && WITHIN((y), item##_Y, INNER_Y(item##_Y) + item##_H + FRAME_BOTTOM)) + (WITHIN((x), item##_X, INNER_X(item##_X) + item##_W + FRAME_RIGHT) \ + && WITHIN((y), item##_Y, INNER_Y(item##_Y) + item##_H + FRAME_BOTTOM)) static int edit_x = 3, edit_y = 3; static uint8_t current_char = 'A'; static int itfmap_pos = -1; static enum { - EDITBOX, CHARMAP, ITFMAP, FONTLIST + EDITBOX, CHARMAP, ITFMAP, FONTLIST } selected_item = EDITBOX; static enum { - MODE_OFF, MODE_LOAD, MODE_SAVE + MODE_OFF, MODE_LOAD, MODE_SAVE } fontlist_mode = MODE_OFF; static dmoz_filelist_t flist; @@ -145,48 +145,48 @@ static void fontlist_reposition(void) { - if (cur_font < 0) - cur_font = 0; /* weird! */ - if (cur_font < top_font) - top_font = cur_font; - else if (cur_font > top_font + (VISIBLE_FONTS - 1)) - top_font = cur_font - (VISIBLE_FONTS - 1); + if (cur_font < 0) + cur_font = 0; /* weird! */ + if (cur_font < top_font) + top_font = cur_font; + else if (cur_font > top_font + (VISIBLE_FONTS - 1)) + top_font = cur_font - (VISIBLE_FONTS - 1); } static int fontgrep(dmoz_file_t *f) { - const char *ext; + const char *ext; - if (f->sort_order == -100) - return 1; /* this is our font.cfg, at the top of the list */ - if (f->type & TYPE_BROWSABLE_MASK) - return 0; /* we don't care about directories and stuff */ - ext = get_extension(f->base); - return (strcasecmp(ext, ".itf") == 0 || strcasecmp(ext, ".fnt") == 0); + if (f->sort_order == -100) + return 1; /* this is our font.cfg, at the top of the list */ + if (f->type & TYPE_BROWSABLE_MASK) + return 0; /* we don't care about directories and stuff */ + ext = get_extension(f->base); + return (strcasecmp(ext, ".itf") == 0 || strcasecmp(ext, ".fnt") == 0); } static void load_fontlist(void) { - char *font_dir, *p; - struct stat st; + char *font_dir, *p; + struct stat st; - dmoz_free(&flist, NULL); + dmoz_free(&flist, NULL); - top_font = cur_font = 0; + top_font = cur_font = 0; - font_dir = dmoz_path_concat_len(cfg_dir_dotschism, "fonts", strlen(cfg_dir_dotschism), 5); - mkdir(font_dir, 0755); - p = dmoz_path_concat_len(font_dir, "font.cfg", strlen(font_dir), 8); - memset(&st, 0, sizeof(st)); - dmoz_add_file(&flist, p, str_dup("font.cfg"), &st, -100); /* put it on top */ - if (dmoz_read(font_dir, &flist, NULL, NULL) < 0) - log_perror(font_dir); - free(font_dir); - dmoz_filter_filelist(&flist, fontgrep, &cur_font, NULL); - while (dmoz_worker()); - fontlist_reposition(); + font_dir = dmoz_path_concat_len(cfg_dir_dotschism, "fonts", strlen(cfg_dir_dotschism), 5); + mkdir(font_dir, 0755); + p = dmoz_path_concat_len(font_dir, "font.cfg", strlen(font_dir), 8); + memset(&st, 0, sizeof(st)); + dmoz_add_file(&flist, p, str_dup("font.cfg"), &st, -100); /* put it on top */ + if (dmoz_read(font_dir, &flist, NULL, NULL) < 0) + log_perror(font_dir); + free(font_dir); + dmoz_filter_filelist(&flist, fontgrep, &cur_font, NULL); + while (dmoz_worker()); + fontlist_reposition(); - /* p is freed by dmoz_free */ + /* p is freed by dmoz_free */ } @@ -200,852 +200,878 @@ * except main should call draw_anything -- set this instead. */ static void draw_frame(const char* name, int x, int y, int inner_width, int inner_height, int active) { - int n, c; - int len = strlen(name); + int n, c; + int len = strlen(name); - if (len > inner_width + 2) - len = inner_width + 2; - c = (status.flags & INVERTED_PALETTE) ? 1 : 3; - - draw_box(x, y + 1, x + inner_width + 5, - y + inner_height + 6, BOX_THIN | BOX_CORNER | BOX_OUTSET); - draw_box(x + 1, y + 2, x + inner_width + 4, - y + inner_height + 5, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_char(128, x, y, c, 2); - for (n = 0; n < len + 1; n++) - draw_char(129, x + n + 1, y, c, 2); - draw_char(130, x + n, y, c, 2); - draw_char(131, x, y + 1, c, 2); - draw_char(137, x + len + 1, y + 1, c, 2); - - switch (active) { - case 0: /* inactive */ - n = 0; - break; - case -1: /* disabled */ - n = 1; - break; - default: /* active */ - n = 3; - break; - } - draw_text_len(name, len, x + 1, y + 1, n, 2); + if (len > inner_width + 2) + len = inner_width + 2; + c = (status.flags & INVERTED_PALETTE) ? 1 : 3; + + draw_box(x, y + 1, x + inner_width + 5, + y + inner_height + 6, BOX_THIN | BOX_CORNER | BOX_OUTSET); + draw_box(x + 1, y + 2, x + inner_width + 4, + y + inner_height + 5, BOX_THIN | BOX_INNER | BOX_INSET); + + draw_char(128, x, y, c, 2); + for (n = 0; n < len + 1; n++) + draw_char(129, x + n + 1, y, c, 2); + draw_char(130, x + n, y, c, 2); + draw_char(131, x, y + 1, c, 2); + draw_char(137, x + len + 1, y + 1, c, 2); + + switch (active) { + case 0: /* inactive */ + n = 0; + break; + case -1: /* disabled */ + n = 1; + break; + default: /* active */ + n = 3; + break; + } + draw_text_len(name, len, x + 1, y + 1, n, 2); } /* --------------------------------------------------------------------- */ static inline void draw_editbox(void) { - int c; - char buf[12]; - int ci = current_char << 3, i, j, fg; - - for (i = 0; i < 8; i++) { - draw_char('1' + i, INNER_X(EDITBOX_X) + i + 1, - INNER_Y(EDITBOX_Y) + 2, (i == edit_x ? 3 : 1), 0); - draw_char('1' + i, INNER_X(EDITBOX_X), - INNER_Y(EDITBOX_Y) + i + 3, (i == edit_y ? 3 : 1), 0); - - for (j = 0; j < 8; j++) { - if (font_data[ci + j] & (128 >> i)) { - c = 15; - fg = 6; - } else { - c = 173; - fg = 1; - } - if (selected_item == EDITBOX && i == edit_x && j == edit_y) - draw_char(c, INNER_X(EDITBOX_X) + 1 + i, - INNER_Y(EDITBOX_Y) + 3 + j, 0, 3); - else - draw_char(c, INNER_X(EDITBOX_X) + 1 + i, - INNER_Y(EDITBOX_Y) + 3 + j, fg, 0); - } - } - draw_char(current_char, INNER_X(EDITBOX_X), INNER_Y(EDITBOX_Y), 5, 0); + int c; + char buf[12]; + int ci = current_char << 3, i, j, fg; + + for (i = 0; i < 8; i++) { + draw_char('1' + i, INNER_X(EDITBOX_X) + i + 1, + INNER_Y(EDITBOX_Y) + 2, (i == edit_x ? 3 : 1), 0); + draw_char('1' + i, INNER_X(EDITBOX_X), + INNER_Y(EDITBOX_Y) + i + 3, (i == edit_y ? 3 : 1), 0); + + for (j = 0; j < 8; j++) { + if (font_data[ci + j] & (128 >> i)) { + c = 15; + fg = 6; + } else { + c = 173; + fg = 1; + } + if (selected_item == EDITBOX && i == edit_x && j == edit_y) + draw_char(c, INNER_X(EDITBOX_X) + 1 + i, + INNER_Y(EDITBOX_Y) + 3 + j, 0, 3); + else + draw_char(c, INNER_X(EDITBOX_X) + 1 + i, + INNER_Y(EDITBOX_Y) + 3 + j, fg, 0); + } + } + draw_char(current_char, INNER_X(EDITBOX_X), INNER_Y(EDITBOX_Y), 5, 0); - sprintf(buf, "%3d $%02X", current_char, current_char); - draw_text(buf, INNER_X(EDITBOX_X) + 2, INNER_Y(EDITBOX_Y), 5, 0); + sprintf(buf, "%3d $%02X", current_char, current_char); + draw_text(buf, INNER_X(EDITBOX_X) + 2, INNER_Y(EDITBOX_Y), 5, 0); } static inline void draw_charmap(void) { - int n = 256; + int n = 256; - if (selected_item == CHARMAP) { - while (n) { - n--; - draw_char(n, INNER_X(CHARMAP_X) + n % 16, INNER_Y(CHARMAP_Y) + n / 16, - (n == current_char ? 0 : 1), (n == current_char ? 3 : 0)); - } - } else { - while (n) { - n--; - draw_char(n, INNER_X(CHARMAP_X) + n % 16, INNER_Y(CHARMAP_Y) + n / 16, - (n == current_char ? 3 : 1), 0); - } - } + if (selected_item == CHARMAP) { + while (n) { + n--; + draw_char(n, INNER_X(CHARMAP_X) + n % 16, INNER_Y(CHARMAP_Y) + n / 16, + (n == current_char ? 0 : 1), (n == current_char ? 3 : 0)); + } + } else { + while (n) { + n--; + draw_char(n, INNER_X(CHARMAP_X) + n % 16, INNER_Y(CHARMAP_Y) + n / 16, + (n == current_char ? 3 : 1), 0); + } + } } static inline void draw_itfmap(void) { - int n, fg, bg; - uint8_t *ptr; + int n, fg, bg; + uint8_t *ptr; - if (itfmap_pos < 0 || itfmap_chars[itfmap_pos] != current_char) { - ptr = (unsigned char *) strchr((char *) itfmap_chars, current_char); - if (ptr == NULL) - itfmap_pos = -1; - else - itfmap_pos = ptr - itfmap_chars; - } - - for (n = 0; n < 240; n++) { - fg = 1; - bg = 0; - if (n == itfmap_pos) { - if (selected_item == ITFMAP) { - fg = 0; - bg = 3; - } else { - fg = 3; - } - } - draw_char(itfmap_chars[n], - INNER_X(ITFMAP_X) + n % 16, INNER_Y(ITFMAP_Y) + n / 16, fg, bg); - } + if (itfmap_pos < 0 || itfmap_chars[itfmap_pos] != current_char) { + ptr = (unsigned char *) strchr((char *) itfmap_chars, current_char); + if (ptr == NULL) + itfmap_pos = -1; + else + itfmap_pos = ptr - itfmap_chars; + } + + for (n = 0; n < 240; n++) { + fg = 1; + bg = 0; + if (n == itfmap_pos) { + if (selected_item == ITFMAP) { + fg = 0; + bg = 3; + } else { + fg = 3; + } + } + draw_char(itfmap_chars[n], + INNER_X(ITFMAP_X) + n % 16, INNER_Y(ITFMAP_Y) + n / 16, fg, bg); + } } static inline void draw_fontlist(void) { - int x, pos = 0, n = top_font, cfg, cbg; - dmoz_file_t *f; - char *ptr; - - if (selected_item == FONTLIST) { - cfg = 0; - cbg = 3; - } else { - cfg = 3; - cbg = 0; - } - - if (top_font < 0) top_font = 0; - if (n < 0) n = 0; - - while (n < flist.num_files && pos < VISIBLE_FONTS) { - x = 1; - f = flist.files[n]; - if (!f) break; - ptr = f->base; - if (n == cur_font) { - draw_char(183, INNER_X(FONTLIST_X), INNER_Y(FONTLIST_Y) + pos, cfg, cbg); - while (x < 9 && *ptr && (n == 0 || *ptr != '.')) { - draw_char(*ptr, - INNER_X(FONTLIST_X) + x, - INNER_Y(FONTLIST_Y) + pos, cfg, cbg); - x++; - ptr++; - } - while (x < 9) { - draw_char(0, - INNER_X(FONTLIST_X) + x, - INNER_Y(FONTLIST_Y) + pos, cfg, cbg); - x++; - } - } else { - draw_char(173, INNER_X(FONTLIST_X), INNER_Y(FONTLIST_Y) + pos, 2, 0); - while (x < 9 && *ptr && (n == 0 || *ptr != '.')) { - draw_char(*ptr, - INNER_X(FONTLIST_X) + x, INNER_Y(FONTLIST_Y) + pos, 5, 0); - x++; - ptr++; - } - while (x < 9) { - draw_char(0, INNER_X(FONTLIST_X) + x, INNER_Y(FONTLIST_Y) + pos, 5, 0); - x++; - } - } - n++; - pos++; - } + int x, pos = 0, n = top_font, cfg, cbg; + dmoz_file_t *f; + char *ptr; + + if (selected_item == FONTLIST) { + cfg = 0; + cbg = 3; + } else { + cfg = 3; + cbg = 0; + } + + if (top_font < 0) top_font = 0; + if (n < 0) n = 0; + + while (n < flist.num_files && pos < VISIBLE_FONTS) { + x = 1; + f = flist.files[n]; + if (!f) break; + ptr = f->base; + if (n == cur_font) { + draw_char(183, INNER_X(FONTLIST_X), INNER_Y(FONTLIST_Y) + pos, cfg, cbg); + while (x < 9 && *ptr && (n == 0 || *ptr != '.')) { + draw_char(*ptr, + INNER_X(FONTLIST_X) + x, + INNER_Y(FONTLIST_Y) + pos, cfg, cbg); + x++; + ptr++; + } + while (x < 9) { + draw_char(0, + INNER_X(FONTLIST_X) + x, + INNER_Y(FONTLIST_Y) + pos, cfg, cbg); + x++; + } + } else { + draw_char(173, INNER_X(FONTLIST_X), INNER_Y(FONTLIST_Y) + pos, 2, 0); + while (x < 9 && *ptr && (n == 0 || *ptr != '.')) { + draw_char(*ptr, + INNER_X(FONTLIST_X) + x, INNER_Y(FONTLIST_Y) + pos, 5, 0); + x++; + ptr++; + } + while (x < 9) { + draw_char(0, INNER_X(FONTLIST_X) + x, INNER_Y(FONTLIST_Y) + pos, 5, 0); + x++; + } + } + n++; + pos++; + } } static inline void draw_helptext(void) { - const uint8_t *ptr = helptext_gen; - const uint8_t *eol; - int line; - int column; - - for (line = INNER_Y(HELPTEXT_Y); *ptr; line++) { - eol = (unsigned char *) strchr((char *) ptr, '\n'); - if (!eol) - eol = (unsigned char *) strchr((char *) ptr, '\0'); - for (column = INNER_X(HELPTEXT_X); ptr < eol; ptr++, column++) - draw_char(*ptr, column, line, 12, 0); - ptr++; - } - for (line = 0; line < 10; line++) - draw_char(168, INNER_X(HELPTEXT_X) + 43, INNER_Y(HELPTEXT_Y) + line, 12, 0); - - /* context sensitive stuff... oooh :) */ - switch (selected_item) { - case EDITBOX: - ptr = helptext_editbox; - break; - case CHARMAP: - case ITFMAP: - ptr = helptext_charmap; - break; - case FONTLIST: - ptr = helptext_fontlist; - break; - } - for (line = INNER_Y(HELPTEXT_Y); *ptr; line++) { - eol = (unsigned char *) strchr((char *) ptr, '\n'); - if (!eol) - eol = (unsigned char *) strchr((char *) ptr, '\0'); - draw_char(168, INNER_X(HELPTEXT_X) + 43, line, 12, 0); - for (column = INNER_X(HELPTEXT_X) + 45; ptr < eol; ptr++, column++) - draw_char(*ptr, column, line, 12, 0); - ptr++; - } - draw_text(ver_short_copyright, 77 - strlen(ver_short_copyright), 46, 1, 0); + const uint8_t *ptr = helptext_gen; + const uint8_t *eol; + int line; + int column; + + for (line = INNER_Y(HELPTEXT_Y); *ptr; line++) { + eol = (unsigned char *) strchr((char *) ptr, '\n'); + if (!eol) + eol = (unsigned char *) strchr((char *) ptr, '\0'); + for (column = INNER_X(HELPTEXT_X); ptr < eol; ptr++, column++) + draw_char(*ptr, column, line, 12, 0); + ptr++; + } + for (line = 0; line < 10; line++) + draw_char(168, INNER_X(HELPTEXT_X) + 43, INNER_Y(HELPTEXT_Y) + line, 12, 0); + + /* context sensitive stuff... oooh :) */ + switch (selected_item) { + case EDITBOX: + ptr = helptext_editbox; + break; + case CHARMAP: + case ITFMAP: + ptr = helptext_charmap; + break; + case FONTLIST: + ptr = helptext_fontlist; + break; + } + for (line = INNER_Y(HELPTEXT_Y); *ptr; line++) { + eol = (unsigned char *) strchr((char *) ptr, '\n'); + if (!eol) + eol = (unsigned char *) strchr((char *) ptr, '\0'); + draw_char(168, INNER_X(HELPTEXT_X) + 43, line, 12, 0); + for (column = INNER_X(HELPTEXT_X) + 45; ptr < eol; ptr++, column++) + draw_char(*ptr, column, line, 12, 0); + ptr++; + } + draw_text(ver_short_copyright, 77 - strlen(ver_short_copyright), 46, 1, 0); } static inline void draw_time(void) { - char buf[16]; - sprintf(buf, "%.2d:%.2d:%.2d", status.tmnow.tm_hour, status.tmnow.tm_min, status.tmnow.tm_sec); - draw_text(buf, 3, 46, 1, 0); + char buf[16]; + sprintf(buf, "%.2d:%.2d:%.2d", status.tmnow.tm_hour, status.tmnow.tm_min, status.tmnow.tm_sec); + draw_text(buf, 3, 46, 1, 0); } extern unsigned int color_set[16]; static void draw_screen(void) { - draw_frame("Edit Box", EDITBOX_X, EDITBOX_Y, 9, 11, !!(selected_item == EDITBOX)); - draw_editbox(); + draw_frame("Edit Box", EDITBOX_X, EDITBOX_Y, 9, 11, !!(selected_item == EDITBOX)); + draw_editbox(); - draw_frame("Current Font", CHARMAP_X, CHARMAP_Y, 16, 16, !!(selected_item == CHARMAP)); - draw_charmap(); + draw_frame("Current Font", CHARMAP_X, CHARMAP_Y, 16, 16, !!(selected_item == CHARMAP)); + draw_charmap(); - draw_frame("Preview", ITFMAP_X, ITFMAP_Y, 16, 15, !!(selected_item == ITFMAP)); - draw_itfmap(); + draw_frame("Preview", ITFMAP_X, ITFMAP_Y, 16, 15, !!(selected_item == ITFMAP)); + draw_itfmap(); - switch (fontlist_mode) { - case MODE_LOAD: - draw_frame("Load/Browse", FONTLIST_X, FONTLIST_Y, 9, - VISIBLE_FONTS, !!(selected_item == FONTLIST)); - draw_fontlist(); - break; - case MODE_SAVE: - draw_frame("Save As...", FONTLIST_X, FONTLIST_Y, 9, - VISIBLE_FONTS, !!(selected_item == FONTLIST)); - draw_fontlist(); - break; - default: /* Off? (I sure hope so!) */ - break; - } + switch (fontlist_mode) { + case MODE_LOAD: + draw_frame("Load/Browse", FONTLIST_X, FONTLIST_Y, 9, + VISIBLE_FONTS, !!(selected_item == FONTLIST)); + draw_fontlist(); + break; + case MODE_SAVE: + draw_frame("Save As...", FONTLIST_X, FONTLIST_Y, 9, + VISIBLE_FONTS, !!(selected_item == FONTLIST)); + draw_fontlist(); + break; + default: /* Off? (I sure hope so!) */ + break; + } - draw_frame("Quick Help", HELPTEXT_X, HELPTEXT_Y, 74, 12, -1); - draw_helptext(); + draw_frame("Quick Help", HELPTEXT_X, HELPTEXT_Y, 74, 12, -1); + draw_helptext(); - draw_time(); + draw_time(); } static void handle_key_editbox(struct key_event * k) { - uint8_t tmp[8] = { 0 }; - int ci = current_char << 3; - int n, bit; - uint8_t *ptr = font_data + ci; - - switch (k->sym) { - case SDLK_UP: - if (k->mod & KMOD_SHIFT) { - int s = ptr[0]; - for (n = 0; n < 7; n++) - ptr[n] = ptr[n + 1]; - ptr[7] = s; - } else { - if (--edit_y < 0) - edit_y = 7; - } - break; - case SDLK_DOWN: - if (k->mod & KMOD_SHIFT) { - int s = ptr[7]; - for (n = 7; n; n--) - ptr[n] = ptr[n - 1]; - ptr[0] = s; - } else { - edit_y = (edit_y + 1) % 8; - } - break; - case SDLK_LEFT: - if (k->mod & KMOD_SHIFT) { - for (n = 0; n < 8; n++, ptr++) - *ptr = (*ptr >> 7) | (*ptr << 1); - } else { - if (--edit_x < 0) - edit_x = 7; - } - break; - case SDLK_RIGHT: - if (k->mod & KMOD_SHIFT) { - for (n = 0; n < 8; n++, ptr++) - *ptr = (*ptr << 7) | (*ptr >> 1); - } else { - edit_x = (edit_x + 1) % 8; - } - break; - case SDLK_HOME: - edit_x = edit_y = 0; - break; - case SDLK_END: - edit_x = edit_y = 7; - break; - case SDLK_SPACE: - ptr[edit_y] ^= (128 >> edit_x); - break; - case SDLK_INSERT: - if (k->mod & KMOD_SHIFT) { - for (n = 0; n < 8; n++) - ptr[n] |= (128 >> edit_x); - } else { - ptr[edit_y] = 255; - } - break; - case SDLK_DELETE: - if (k->mod & KMOD_SHIFT) { - for (n = 0; n < 8; n++) - ptr[n] &= ~(128 >> edit_x); - } else { - ptr[edit_y] = 0; - } - break; - case SDLK_LEFTBRACKET: - for (n = 0; n < 8; n++) - for (bit = 0; bit < 8; bit++) - if (ptr[n] & (1 << bit)) - tmp[bit] |= 1 << (7 - n); - memcpy(ptr, tmp, 8); - break; - case SDLK_RIGHTBRACKET: - for (n = 0; n < 8; n++) - for (bit = 0; bit < 8; bit++) - if (ptr[n] & (1 << bit)) - tmp[7 - bit] |= 1 << n; - memcpy(ptr, tmp, 8); - break; - case SDLK_PLUS: - case SDLK_EQUALS: - current_char++; - break; - case SDLK_MINUS: - case SDLK_UNDERSCORE: - current_char--; - break; - case SDLK_PAGEUP: - current_char -= 16; - break; - case SDLK_PAGEDOWN: - current_char += 16; - break; - default: - return; - } + uint8_t tmp[8] = { 0 }; + int ci = current_char << 3; + int n, bit; + uint8_t *ptr = font_data + ci; + + switch (k->sym) { + case SDLK_UP: + if (k->mod & KMOD_SHIFT) { + int s = ptr[0]; + for (n = 0; n < 7; n++) + ptr[n] = ptr[n + 1]; + ptr[7] = s; + } else { + if (--edit_y < 0) + edit_y = 7; + } + break; + case SDLK_DOWN: + if (k->mod & KMOD_SHIFT) { + int s = ptr[7]; + for (n = 7; n; n--) + ptr[n] = ptr[n - 1]; + ptr[0] = s; + } else { + edit_y = (edit_y + 1) % 8; + } + break; + case SDLK_LEFT: + if (k->mod & KMOD_SHIFT) { + for (n = 0; n < 8; n++, ptr++) + *ptr = (*ptr >> 7) | (*ptr << 1); + } else { + if (--edit_x < 0) + edit_x = 7; + } + break; + case SDLK_RIGHT: + if (k->mod & KMOD_SHIFT) { + for (n = 0; n < 8; n++, ptr++) + *ptr = (*ptr << 7) | (*ptr >> 1); + } else { + edit_x = (edit_x + 1) % 8; + } + break; + case SDLK_HOME: + edit_x = edit_y = 0; + break; + case SDLK_END: + edit_x = edit_y = 7; + break; + case SDLK_SPACE: + ptr[edit_y] ^= (128 >> edit_x); + break; + case SDLK_INSERT: + if (k->mod & KMOD_SHIFT) { + for (n = 0; n < 8; n++) + ptr[n] |= (128 >> edit_x); + } else { + ptr[edit_y] = 255; + } + break; + case SDLK_DELETE: + if (k->mod & KMOD_SHIFT) { + for (n = 0; n < 8; n++) + ptr[n] &= ~(128 >> edit_x); + } else { + ptr[edit_y] = 0; + } + break; + case SDLK_LEFTBRACKET: + for (n = 0; n < 8; n++) + for (bit = 0; bit < 8; bit++) + if (ptr[n] & (1 << bit)) + tmp[bit] |= 1 << (7 - n); + memcpy(ptr, tmp, 8); + break; + case SDLK_RIGHTBRACKET: + for (n = 0; n < 8; n++) + for (bit = 0; bit < 8; bit++) + if (ptr[n] & (1 << bit)) + tmp[7 - bit] |= 1 << n; + memcpy(ptr, tmp, 8); + break; + case SDLK_PLUS: + case SDLK_EQUALS: + current_char++; + break; + case SDLK_MINUS: + case SDLK_UNDERSCORE: + current_char--; + break; + case SDLK_PAGEUP: + current_char -= 16; + break; + case SDLK_PAGEDOWN: + current_char += 16; + break; + default: + return; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static void handle_key_charmap(struct key_event * k) { - switch (k->sym) { - case SDLK_UP: - current_char -= 16; - break; - case SDLK_DOWN: - current_char += 16; - break; - case SDLK_LEFT: - current_char = DECR_WRAPPED(current_char); - break; - case SDLK_RIGHT: - current_char = INCR_WRAPPED(current_char); - break; - case SDLK_HOME: - current_char = 0; - break; - case SDLK_END: - current_char = 255; - break; - default: - return; - } - status.flags |= NEED_UPDATE; + switch (k->sym) { + case SDLK_UP: + current_char -= 16; + break; + case SDLK_DOWN: + current_char += 16; + break; + case SDLK_LEFT: + current_char = DECR_WRAPPED(current_char); + break; + case SDLK_RIGHT: + current_char = INCR_WRAPPED(current_char); + break; + case SDLK_HOME: + current_char = 0; + break; + case SDLK_END: + current_char = 255; + break; + default: + return; + } + status.flags |= NEED_UPDATE; } static void handle_key_itfmap(struct key_event * k) { - switch (k->sym) { - case SDLK_UP: - if (itfmap_pos < 0) { - itfmap_pos = 224; - } else { - itfmap_pos -= 16; - if (itfmap_pos < 0) - itfmap_pos += 240; - } - current_char = itfmap_chars[itfmap_pos]; - break; - case SDLK_DOWN: - if (itfmap_pos < 0) - itfmap_pos = 16; - else - itfmap_pos = (itfmap_pos + 16) % 240; - current_char = itfmap_chars[itfmap_pos]; - break; - case SDLK_LEFT: - if (itfmap_pos < 0) - itfmap_pos = 15; - else - itfmap_pos = DECR_WRAPPED(itfmap_pos); - current_char = itfmap_chars[itfmap_pos]; - break; - case SDLK_RIGHT: - if (itfmap_pos < 0) - itfmap_pos = 0; - else - itfmap_pos = INCR_WRAPPED(itfmap_pos); - current_char = itfmap_chars[itfmap_pos]; - break; - case SDLK_HOME: - current_char = itfmap_chars[0]; - itfmap_pos = 0; - break; - case SDLK_END: - current_char = itfmap_chars[239]; - itfmap_pos = 239; - break; - default: - return; - } - status.flags |= NEED_UPDATE; + switch (k->sym) { + case SDLK_UP: + if (itfmap_pos < 0) { + itfmap_pos = 224; + } else { + itfmap_pos -= 16; + if (itfmap_pos < 0) + itfmap_pos += 240; + } + current_char = itfmap_chars[itfmap_pos]; + break; + case SDLK_DOWN: + if (itfmap_pos < 0) + itfmap_pos = 16; + else + itfmap_pos = (itfmap_pos + 16) % 240; + current_char = itfmap_chars[itfmap_pos]; + break; + case SDLK_LEFT: + if (itfmap_pos < 0) + itfmap_pos = 15; + else + itfmap_pos = DECR_WRAPPED(itfmap_pos); + current_char = itfmap_chars[itfmap_pos]; + break; + case SDLK_RIGHT: + if (itfmap_pos < 0) + itfmap_pos = 0; + else + itfmap_pos = INCR_WRAPPED(itfmap_pos); + current_char = itfmap_chars[itfmap_pos]; + break; + case SDLK_HOME: + current_char = itfmap_chars[0]; + itfmap_pos = 0; + break; + case SDLK_END: + current_char = itfmap_chars[239]; + itfmap_pos = 239; + break; + default: + return; + } + status.flags |= NEED_UPDATE; } static void confirm_font_save_ok(void *vf) { - char *f = vf; - if (font_save(f) != 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - return; - } - selected_item = EDITBOX; + char *f = vf; + if (font_save(f) != 0) { + fprintf(stderr, "%s\n", SDL_GetError()); + return; + } + selected_item = EDITBOX; } static void handle_key_fontlist(struct key_event * k) { - int new_font = cur_font; + int new_font = cur_font; - switch (k->sym) { - case SDLK_HOME: - new_font = 0; - break; - case SDLK_END: - new_font = flist.num_files - 1; - break; - case SDLK_UP: - new_font--; - break; - case SDLK_DOWN: - new_font++; - break; - case SDLK_PAGEUP: - new_font -= VISIBLE_FONTS; - break; - case SDLK_PAGEDOWN: - new_font += VISIBLE_FONTS; - break; - case SDLK_ESCAPE: - selected_item = EDITBOX; - fontlist_mode = MODE_OFF; - break; - case SDLK_RETURN: - if (!k->state) return; - switch (fontlist_mode) { - case MODE_LOAD: - if (cur_font < flist.num_files - && flist.files[cur_font] - && font_load(flist.files[cur_font]->base) != 0) { - fprintf(stderr, "%s\n", SDL_GetError()); - font_reset(); - } - break; - case MODE_SAVE: - if (cur_font < flist.num_files && flist.files[cur_font]) { - if (strcasecmp(flist.files[cur_font]->base,"font.cfg") != 0) { - dialog_create(DIALOG_OK_CANCEL, "Overwrite font file?", - confirm_font_save_ok, NULL, 1, flist.files[cur_font]->base); - return; - } - confirm_font_save_ok(flist.files[cur_font]->base); - } - selected_item = EDITBOX; - /* fontlist_mode = MODE_OFF; */ - break; - default: - /* should never happen */ - return; - } - break; - default: - return; - } - - if (new_font != cur_font) { - new_font = CLAMP(new_font, 0, flist.num_files - 1); - if (new_font == cur_font) - return; - cur_font = new_font; - fontlist_reposition(); - } - status.flags |= NEED_UPDATE; + switch (k->sym) { + case SDLK_HOME: + new_font = 0; + break; + case SDLK_END: + new_font = flist.num_files - 1; + break; + case SDLK_UP: + new_font--; + break; + case SDLK_DOWN: + new_font++; + break; + case SDLK_PAGEUP: + new_font -= VISIBLE_FONTS; + break; + case SDLK_PAGEDOWN: + new_font += VISIBLE_FONTS; + break; + case SDLK_ESCAPE: + selected_item = EDITBOX; + fontlist_mode = MODE_OFF; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return; + switch (fontlist_mode) { + case MODE_LOAD: + if (cur_font < flist.num_files + && flist.files[cur_font] + && font_load(flist.files[cur_font]->base) != 0) { + fprintf(stderr, "%s\n", SDL_GetError()); + font_reset(); + } + break; + case MODE_SAVE: + if (cur_font < flist.num_files && flist.files[cur_font]) { + if (strcasecmp(flist.files[cur_font]->base,"font.cfg") != 0) { + dialog_create(DIALOG_OK_CANCEL, "Overwrite font file?", + confirm_font_save_ok, NULL, 1, flist.files[cur_font]->base); + return; + } + confirm_font_save_ok(flist.files[cur_font]->base); + } + selected_item = EDITBOX; + /* fontlist_mode = MODE_OFF; */ + break; + default: + /* should never happen */ + return; + } + break; + default: + return; + } + + if (new_font != cur_font) { + new_font = CLAMP(new_font, 0, flist.num_files - 1); + if (new_font == cur_font) + return; + cur_font = new_font; + fontlist_reposition(); + } + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void handle_mouse_editbox(struct key_event *k) { - int n, ci = current_char << 3, xrel, yrel; - uint8_t *ptr = font_data + ci; + int n, ci = current_char << 3, xrel, yrel; + uint8_t *ptr = font_data + ci; - xrel = k->x - INNER_X(EDITBOX_X); - yrel = k->y - INNER_Y(EDITBOX_Y); + xrel = k->x - INNER_X(EDITBOX_X); + yrel = k->y - INNER_Y(EDITBOX_Y); - if (xrel > 0 && yrel > 2) { - edit_x = xrel - 1; - edit_y = yrel - 3; - switch (k->mouse_button) { - case MOUSE_BUTTON_LEFT: /* set */ - ptr[edit_y] |= (128 >> edit_x); - break; - case MOUSE_BUTTON_MIDDLE: /* invert */ - if (k->state) return; - ptr[edit_y] ^= (128 >> edit_x); - break; - case MOUSE_BUTTON_RIGHT: /* clear */ - ptr[edit_y] &= ~(128 >> edit_x); - break; - } - } else if (xrel == 0 && yrel == 2) { - /* clicking at the origin modifies the entire character */ - switch (k->mouse_button) { - case MOUSE_BUTTON_LEFT: /* set */ - for (n = 0; n < 8; n++) - ptr[n] = 255; - break; - case MOUSE_BUTTON_MIDDLE: /* invert */ - if (k->state) return; - for (n = 0; n < 8; n++) - ptr[n] ^= 255; - break; - case MOUSE_BUTTON_RIGHT: /* clear */ - for (n = 0; n < 8; n++) - ptr[n] = 0; - break; - } - } else if (xrel == 0 && yrel > 2) { - edit_y = yrel - 3; - switch (k->mouse_button) { - case MOUSE_BUTTON_LEFT: /* set */ - ptr[edit_y] = 255; - break; - case MOUSE_BUTTON_MIDDLE: /* invert */ - if (k->state) return; - ptr[edit_y] ^= 255; - break; - case MOUSE_BUTTON_RIGHT: /* clear */ - ptr[edit_y] = 0; - break; - } - } else if (yrel == 2 && xrel > 0) { - edit_x = xrel - 1; - switch (k->mouse_button) { - case MOUSE_BUTTON_LEFT: /* set */ - for (n = 0; n < 8; n++) - ptr[n] |= (128 >> edit_x); - break; - case MOUSE_BUTTON_MIDDLE: /* invert */ - if (k->state) return; - for (n = 0; n < 8; n++) - ptr[n] ^= (128 >> edit_x); - break; - case MOUSE_BUTTON_RIGHT: /* clear */ - for (n = 0; n < 8; n++) - ptr[n] &= ~(128 >> edit_x); - break; - } - } + if (xrel > 0 && yrel > 2) { + edit_x = xrel - 1; + edit_y = yrel - 3; + switch (k->mouse_button) { + case MOUSE_BUTTON_LEFT: /* set */ + ptr[edit_y] |= (128 >> edit_x); + break; + case MOUSE_BUTTON_MIDDLE: /* invert */ + if (k->state == KEY_RELEASE) + return; + ptr[edit_y] ^= (128 >> edit_x); + break; + case MOUSE_BUTTON_RIGHT: /* clear */ + ptr[edit_y] &= ~(128 >> edit_x); + break; + } + } else if (xrel == 0 && yrel == 2) { + /* clicking at the origin modifies the entire character */ + switch (k->mouse_button) { + case MOUSE_BUTTON_LEFT: /* set */ + for (n = 0; n < 8; n++) + ptr[n] = 255; + break; + case MOUSE_BUTTON_MIDDLE: /* invert */ + if (k->state == KEY_RELEASE) + return; + for (n = 0; n < 8; n++) + ptr[n] ^= 255; + break; + case MOUSE_BUTTON_RIGHT: /* clear */ + for (n = 0; n < 8; n++) + ptr[n] = 0; + break; + } + } else if (xrel == 0 && yrel > 2) { + edit_y = yrel - 3; + switch (k->mouse_button) { + case MOUSE_BUTTON_LEFT: /* set */ + ptr[edit_y] = 255; + break; + case MOUSE_BUTTON_MIDDLE: /* invert */ + if (k->state == KEY_RELEASE) + return; + ptr[edit_y] ^= 255; + break; + case MOUSE_BUTTON_RIGHT: /* clear */ + ptr[edit_y] = 0; + break; + } + } else if (yrel == 2 && xrel > 0) { + edit_x = xrel - 1; + switch (k->mouse_button) { + case MOUSE_BUTTON_LEFT: /* set */ + for (n = 0; n < 8; n++) + ptr[n] |= (128 >> edit_x); + break; + case MOUSE_BUTTON_MIDDLE: /* invert */ + if (k->state == KEY_RELEASE) + return; + for (n = 0; n < 8; n++) + ptr[n] ^= (128 >> edit_x); + break; + case MOUSE_BUTTON_RIGHT: /* clear */ + for (n = 0; n < 8; n++) + ptr[n] &= ~(128 >> edit_x); + break; + } + } } static void handle_mouse_charmap(struct key_event *k) { - int xrel = k->x - INNER_X(CHARMAP_X), yrel = k->y - INNER_Y(CHARMAP_Y); - if (!k->mouse) return; - current_char = 16 * yrel + xrel; + int xrel = k->x - INNER_X(CHARMAP_X), yrel = k->y - INNER_Y(CHARMAP_Y); + if (!k->mouse) return; + current_char = 16 * yrel + xrel; } static void handle_mouse_itfmap(struct key_event *k) { - int xrel = k->x - INNER_X(ITFMAP_X), yrel = k->y - INNER_Y(ITFMAP_Y); - if (!k->mouse) return; - itfmap_pos = 16 * yrel + xrel; - current_char = itfmap_chars[itfmap_pos]; + int xrel = k->x - INNER_X(ITFMAP_X), yrel = k->y - INNER_Y(ITFMAP_Y); + if (!k->mouse) return; + itfmap_pos = 16 * yrel + xrel; + current_char = itfmap_chars[itfmap_pos]; } static void handle_mouse(struct key_event * k) { - int x = k->x, y = k->y; - if (POINT_IN_FRAME(x, y, EDITBOX)) { - selected_item = EDITBOX; - if (POINT_IN(x, y, EDITBOX)) - handle_mouse_editbox(k); - } else if (POINT_IN_FRAME(x, y, CHARMAP)) { - selected_item = CHARMAP; - if (POINT_IN(x, y, CHARMAP)) - handle_mouse_charmap(k); - } else if (POINT_IN_FRAME(x, y, ITFMAP)) { - selected_item = ITFMAP; - if (POINT_IN(x, y, ITFMAP)) - handle_mouse_itfmap(k); - } else { - //printf("stray click\n"); - return; - } - status.flags |= NEED_UPDATE; + int x = k->x, y = k->y; + if (POINT_IN_FRAME(x, y, EDITBOX)) { + selected_item = EDITBOX; + if (POINT_IN(x, y, EDITBOX)) + handle_mouse_editbox(k); + } else if (POINT_IN_FRAME(x, y, CHARMAP)) { + selected_item = CHARMAP; + if (POINT_IN(x, y, CHARMAP)) + handle_mouse_charmap(k); + } else if (POINT_IN_FRAME(x, y, ITFMAP)) { + selected_item = ITFMAP; + if (POINT_IN(x, y, ITFMAP)) + handle_mouse_itfmap(k); + } else { + //printf("stray click\n"); + return; + } + status.flags |= NEED_UPDATE; } static int fontedit_handle_key(struct key_event * k) { - int n, ci = current_char << 3; - uint8_t *ptr = font_data + ci; + int n, ci = current_char << 3; + uint8_t *ptr = font_data + ci; - if (k->mouse == MOUSE_SCROLL_UP || k->mouse == MOUSE_SCROLL_DOWN) { - /* err... */ - return 0; - } - - if (k->mouse == MOUSE_CLICK) { - handle_mouse(k); - return 1; - } - - /* kp is special */ - switch (k->orig_sym) { - case SDLK_KP0: - if (k->state) return 1; - k->sym += 10; - /* fall through */ - case SDLK_KP1...SDLK_KP9: - if (k->state) return 1; - n = k->sym - SDLK_KP1; - if (k->mod & KMOD_SHIFT) - n += 10; - palette_load_preset(n); - palette_apply(); - status.flags |= NEED_UPDATE; - return 1; - default: - break; - }; - - switch (k->sym) { - case '0': - if (k->state) return 1; - k->sym += 10; - /* fall through */ - case '1'...'9': - if (k->state) return 1; - n = k->sym - '1'; - if (k->mod & KMOD_SHIFT) - n += 10; - palette_load_preset(n); - palette_apply(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_F2: - if (k->state) return 1; - selected_item = EDITBOX; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_F3: - if (k->state) return 1; - selected_item = CHARMAP; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_F4: - if (k->state) return 1; - selected_item = ITFMAP; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_TAB: - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) { - if (selected_item == 0) - selected_item = (fontlist_mode == MODE_OFF ? 2 : 3); - else - selected_item--; - } else { - selected_item = (selected_item + 1) % (fontlist_mode == MODE_OFF ? 3 : 4); - } - status.flags |= NEED_UPDATE; - return 1; - case SDLK_c: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - memcpy(clipboard, ptr, 8); - return 1; - } - break; - case SDLK_p: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - memcpy(ptr, clipboard, 8); - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_m: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) { - SDL_ToggleCursor(); - return 1; - } else if (k->mod & KMOD_ALT) { - for (n = 0; n < 8; n++) - ptr[n] |= clipboard[n]; - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_z: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - memset(ptr, 0, 8); - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_h: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - for (n = 0; n < 8; n++) { - int r = ptr[n]; - r = ((r >> 1) & 0x55) | ((r << 1) & 0xaa); - r = ((r >> 2) & 0x33) | ((r << 2) & 0xcc); - r = ((r >> 4) & 0x0f) | ((r << 4) & 0xf0); - ptr[n] = r; - } - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_v: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - for (n = 0; n < 4; n++) { - uint8_t r = ptr[n]; - ptr[n] = ptr[7 - n]; - ptr[7 - n] = r; - } - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_i: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - for (n = 0; n < 8; n++) - font_data[ci + n] ^= 255; - status.flags |= NEED_UPDATE; - return 1; - } - break; - - /* ----------------------------------------------------- */ - - case SDLK_l: - case SDLK_r: - if (k->state) return 1; - if (!(k->mod & KMOD_CTRL)) break; - /* fall through */ - case SDLK_F9: - if (k->state) return 1; - load_fontlist(); - fontlist_mode = MODE_LOAD; - selected_item = FONTLIST; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_s: - if (k->state) return 1; - if (!(k->mod & KMOD_CTRL)) break; - /* fall through */ - case SDLK_F10: - /* a bit weird, but this ensures that font.cfg - * is always the default font to save to, but - * without the annoyance of moving the cursor - * back to it every time f10 is pressed. */ - if (fontlist_mode != MODE_SAVE) { - cur_font = top_font = 0; - load_fontlist(); - fontlist_mode = MODE_SAVE; - } - selected_item = FONTLIST; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_BACKSPACE: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) { - font_reset_bios(); - } else if (k->mod & KMOD_ALT) { - font_reset_char(current_char); - } else { - font_reset_upper(); - } - status.flags |= NEED_UPDATE; - return 1; - case SDLK_RETURN: - return 0; - case SDLK_q: - if (k->mod & KMOD_CTRL) - return 0; - if (k->state) return 1; - break; - default: - if (k->state) return 1; - break; - } - - switch (selected_item) { - case EDITBOX: - handle_key_editbox(k); - break; - case CHARMAP: - handle_key_charmap(k); - break; - case ITFMAP: - handle_key_itfmap(k); - break; - case FONTLIST: - handle_key_fontlist(k); - break; - default: - break; - } - return 1; + if (k->mouse == MOUSE_SCROLL_UP || k->mouse == MOUSE_SCROLL_DOWN) { + /* err... */ + return 0; + } + + if (k->mouse == MOUSE_CLICK) { + handle_mouse(k); + return 1; + } + + /* kp is special */ + switch (k->orig_sym) { + case SDLK_KP0: + if (k->state == KEY_RELEASE) + return 1; + k->sym += 10; + /* fall through */ + case SDLK_KP1...SDLK_KP9: + if (k->state == KEY_RELEASE) + return 1; + n = k->sym - SDLK_KP1; + if (k->mod & KMOD_SHIFT) + n += 10; + palette_load_preset(n); + palette_apply(); + status.flags |= NEED_UPDATE; + return 1; + default: + break; + }; + + switch (k->sym) { + case '0': + if (k->state == KEY_RELEASE) + return 1; + k->sym += 10; + /* fall through */ + case '1'...'9': + if (k->state == KEY_RELEASE) + return 1; + n = k->sym - '1'; + if (k->mod & KMOD_SHIFT) + n += 10; + palette_load_preset(n); + palette_apply(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_F2: + if (k->state == KEY_RELEASE) + return 1; + selected_item = EDITBOX; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_F3: + if (k->state == KEY_RELEASE) + return 1; + selected_item = CHARMAP; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_F4: + if (k->state == KEY_RELEASE) + return 1; + selected_item = ITFMAP; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_TAB: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) { + if (selected_item == 0) + selected_item = (fontlist_mode == MODE_OFF ? 2 : 3); + else + selected_item--; + } else { + selected_item = (selected_item + 1) % (fontlist_mode == MODE_OFF ? 3 : 4); + } + status.flags |= NEED_UPDATE; + return 1; + case SDLK_c: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + memcpy(clipboard, ptr, 8); + return 1; + } + break; + case SDLK_p: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + memcpy(ptr, clipboard, 8); + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_m: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) { + SDL_ToggleCursor(); + return 1; + } else if (k->mod & KMOD_ALT) { + for (n = 0; n < 8; n++) + ptr[n] |= clipboard[n]; + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_z: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + memset(ptr, 0, 8); + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_h: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + for (n = 0; n < 8; n++) { + int r = ptr[n]; + r = ((r >> 1) & 0x55) | ((r << 1) & 0xaa); + r = ((r >> 2) & 0x33) | ((r << 2) & 0xcc); + r = ((r >> 4) & 0x0f) | ((r << 4) & 0xf0); + ptr[n] = r; + } + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_v: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + for (n = 0; n < 4; n++) { + uint8_t r = ptr[n]; + ptr[n] = ptr[7 - n]; + ptr[7 - n] = r; + } + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_i: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + for (n = 0; n < 8; n++) + font_data[ci + n] ^= 255; + status.flags |= NEED_UPDATE; + return 1; + } + break; + + /* ----------------------------------------------------- */ + + case SDLK_l: + case SDLK_r: + if (k->state == KEY_RELEASE) + return 1; + if (!(k->mod & KMOD_CTRL)) break; + /* fall through */ + case SDLK_F9: + if (k->state == KEY_RELEASE) + return 1; + load_fontlist(); + fontlist_mode = MODE_LOAD; + selected_item = FONTLIST; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_s: + if (k->state == KEY_RELEASE) + return 1; + if (!(k->mod & KMOD_CTRL)) break; + /* fall through */ + case SDLK_F10: + /* a bit weird, but this ensures that font.cfg + * is always the default font to save to, but + * without the annoyance of moving the cursor + * back to it every time f10 is pressed. */ + if (fontlist_mode != MODE_SAVE) { + cur_font = top_font = 0; + load_fontlist(); + fontlist_mode = MODE_SAVE; + } + selected_item = FONTLIST; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) { + font_reset_bios(); + } else if (k->mod & KMOD_ALT) { + font_reset_char(current_char); + } else { + font_reset_upper(); + } + status.flags |= NEED_UPDATE; + return 1; + case SDLK_RETURN: + return 0; + case SDLK_q: + if (k->mod & KMOD_CTRL) + return 0; + if (k->state == KEY_RELEASE) + return 1; + break; + default: + if (k->state == KEY_RELEASE) + return 1; + break; + } + + switch (selected_item) { + case EDITBOX: + handle_key_editbox(k); + break; + case CHARMAP: + handle_key_charmap(k); + break; + case ITFMAP: + handle_key_itfmap(k); + break; + case FONTLIST: + handle_key_fontlist(k); + break; + default: + break; + } + return 1; } @@ -1053,32 +1079,32 @@ static int fontedit_key_hack(struct key_event *k) { - switch (k->sym) { - case SDLK_r: case SDLK_l: case SDLK_s: - case SDLK_c: case SDLK_p: case SDLK_m: - case SDLK_z: case SDLK_v: case SDLK_h: - case SDLK_i: case SDLK_q: case SDLK_w: - case SDLK_F1...SDLK_F12: - return fontedit_handle_key(k); - case SDLK_RETURN: - if (status.dialog_type & (DIALOG_MENU|DIALOG_BOX)) return 0; - if (selected_item == FONTLIST) { - handle_key_fontlist(k); - return 1; - } - default: - break; - }; - return 0; + switch (k->sym) { + case SDLK_r: case SDLK_l: case SDLK_s: + case SDLK_c: case SDLK_p: case SDLK_m: + case SDLK_z: case SDLK_v: case SDLK_h: + case SDLK_i: case SDLK_q: case SDLK_w: + case SDLK_F1...SDLK_F12: + return fontedit_handle_key(k); + case SDLK_RETURN: + if (status.dialog_type & (DIALOG_MENU|DIALOG_BOX)) return 0; + if (selected_item == FONTLIST) { + handle_key_fontlist(k); + return 1; + } + default: + break; + }; + return 0; } static void do_nil(void) {} void fontedit_load_page(struct page *page) { - page->title = ""; - page->draw_full = draw_screen; - page->total_widgets = 1; - page->pre_handle_key = fontedit_key_hack; - page->widgets = fontedit_widget_hack; - create_other(fontedit_widget_hack, 0, fontedit_handle_key, do_nil); + page->title = ""; + page->draw_full = draw_screen; + page->total_widgets = 1; + page->pre_handle_key = fontedit_key_hack; + page->widgets = fontedit_widget_hack; + create_other(fontedit_widget_hack, 0, fontedit_handle_key, do_nil); } diff -Nru schism-0+20110101/schism/keyboard.c schism-20160521/schism/keyboard.c --- schism-0+20110101/schism/keyboard.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/keyboard.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,15 +34,15 @@ /* --------------------------------------------------------------------- */ static const char *note_names_up[12] = { - "C-", "C#", "D-", "D#", "E-", "F-", - "F#", "G-", "G#", "A-", "A#", "B-" + "C-", "C#", "D-", "D#", "E-", "F-", + "F#", "G-", "G#", "A-", "A#", "B-" }; static const char note_names_short_up[12] = "cCdDefFgGaAb"; static const char *note_names_down[12] = { - "C-", "Db", "D-", "Eb", "E-", "F-", - "Gb", "G-", "Ab", "A-", "Bb", "B-" + "C-", "Db", "D-", "Eb", "E-", "F-", + "Gb", "G-", "Ab", "A-", "Bb", "B-" }; static const char note_names_short_down[12] = "CdDeEFgGaAbB"; @@ -72,239 +72,239 @@ // XXX stupid magic numbers... void kbd_sharp_flat_toggle(int e) { - switch (e) { - case -1: - kbd_sharp_flat_toggle(!!(note_names == note_names_up)); - break; - case 1: - status.flags |= ACCIDENTALS_AS_FLATS; - status_text_flash("Displaying accidentals as flats (b)"); - note_names = note_names_down; - note_names_short = note_names_short_down; - break; - default: /* case 0... */ - status.flags &= ~ACCIDENTALS_AS_FLATS; - status_text_flash("Displaying accidentals as sharps (#)"); - note_names = note_names_up; - note_names_short = note_names_short_up; - } + switch (e) { + case -1: + kbd_sharp_flat_toggle(!!(note_names == note_names_up)); + break; + case 1: + status.flags |= ACCIDENTALS_AS_FLATS; + status_text_flash("Displaying accidentals as flats (b)"); + note_names = note_names_down; + note_names_short = note_names_short_down; + break; + default: /* case 0... */ + status.flags &= ~ACCIDENTALS_AS_FLATS; + status_text_flash("Displaying accidentals as sharps (#)"); + note_names = note_names_up; + note_names_short = note_names_short_up; + } } char get_effect_char(int effect) { - if (effect < 0 || effect > 34) { - log_appendf(4, "get_effect_char: effect %d out of range", - effect); - return '?'; - } - return effects[effect]; + if (effect < 0 || effect > 34) { + log_appendf(4, "get_effect_char: effect %d out of range", + effect); + return '?'; + } + return effects[effect]; } int get_ptm_effect_number(char effect) { - const char *ptr; - if (effect >= 'a' && effect <= 'z') effect -= 32; + const char *ptr; + if (effect >= 'a' && effect <= 'z') effect -= 32; - ptr = strchr(ptm_effects, effect); - return ptr ? (ptr - effects) : -1; + ptr = strchr(ptm_effects, effect); + return ptr ? (ptr - effects) : -1; } int get_effect_number(char effect) { - const char *ptr; + const char *ptr; - if (effect >= 'a' && effect <= 'z') { - effect -= 32; - } else if (!((effect >= '0' && effect <= '9') - || (effect >= 'A' && effect <= 'Z') - || (effect == '.'))) { - /* don't accept pseudo-effects */ - if (status.flags & CLASSIC_MODE) return -1; - } + if (effect >= 'a' && effect <= 'z') { + effect -= 32; + } else if (!((effect >= '0' && effect <= '9') + || (effect >= 'A' && effect <= 'Z') + || (effect == '.'))) { + /* don't accept pseudo-effects */ + if (status.flags & CLASSIC_MODE) return -1; + } - ptr = strchr(effects, effect); - return ptr ? ptr - effects : -1; + ptr = strchr(effects, effect); + return ptr ? ptr - effects : -1; } int kbd_get_effect_number(struct key_event *k) { - if (!NO_CAM_MODS(k->mod)) return -1; - switch (k->sym) { + if (!NO_CAM_MODS(k->mod)) return -1; + switch (k->sym) { #define QZA(n) case SDLK_ ## n : return get_effect_number(#n [0]) QZA(a);QZA(b);QZA(c);QZA(d);QZA(e);QZA(f);QZA(g);QZA(h);QZA(i);QZA(j);QZA(k); QZA(l);QZA(m);QZA(n);QZA(o);QZA(p);QZA(q);QZA(r);QZA(s);QZA(t);QZA(u);QZA(v); QZA(w);QZA(x);QZA(y);QZA(z); #undef QZA - case SDLK_PERIOD: case SDLK_KP_PERIOD: - return get_effect_number('.'); - case SDLK_1: - if (!(k->mod & KMOD_SHIFT)) return -1; - case SDLK_EXCLAIM: - return get_effect_number('!'); - case SDLK_4: - if (!(k->mod & KMOD_SHIFT)) return -1; - case SDLK_DOLLAR: - return get_effect_number('$'); - case SDLK_7: - if (!(k->mod & KMOD_SHIFT)) return -1; - case SDLK_AMPERSAND: - return get_effect_number('&'); - - default: - return -1; - }; + case SDLK_PERIOD: case SDLK_KP_PERIOD: + return get_effect_number('.'); + case SDLK_1: + if (!(k->mod & KMOD_SHIFT)) return -1; + case SDLK_EXCLAIM: + return get_effect_number('!'); + case SDLK_4: + if (!(k->mod & KMOD_SHIFT)) return -1; + case SDLK_DOLLAR: + return get_effect_number('$'); + case SDLK_7: + if (!(k->mod & KMOD_SHIFT)) return -1; + case SDLK_AMPERSAND: + return get_effect_number('&'); + + default: + return -1; + }; } /* --------------------------------------------------------------------- */ void key_translate(struct key_event *k) { - k->orig_sym = k->sym; - if (k->mod & KMOD_SHIFT) { - switch (k->sym) { - case SDLK_COMMA: k->sym = SDLK_LESS; break; - case SDLK_PERIOD: k->sym = SDLK_GREATER; break; - case SDLK_4: k->sym = SDLK_DOLLAR; break; - - case SDLK_EQUALS: k->sym = SDLK_PLUS; break; - case SDLK_SEMICOLON: k->sym = SDLK_COLON; break; - - case SDLK_8: k->sym = SDLK_ASTERISK; break; - default: - break; - }; - } - if (k->mod & KMOD_META) { - k->mod = ((k->mod & ~KMOD_META) - | ((status.flags & META_IS_CTRL) - ? KMOD_CTRL : KMOD_ALT)); - } - if ((k->mod & KMOD_MODE) && (status.flags & ALTGR_IS_ALT)) { - /* Treat AltGr as Alt (delt) */ - k->mod = ((k->mod & ~KMOD_MODE) | KMOD_ALT); - } - if (k->mod & KMOD_NUM) { - switch (k->sym) { - case SDLK_KP0: k->sym = SDLK_0; k->mod &= ~KMOD_NUM; break; - case SDLK_KP1: k->sym = SDLK_1; k->mod &= ~KMOD_NUM; break; - case SDLK_KP2: k->sym = SDLK_2; k->mod &= ~KMOD_NUM; break; - case SDLK_KP3: k->sym = SDLK_3; k->mod &= ~KMOD_NUM; break; - case SDLK_KP4: k->sym = SDLK_4; k->mod &= ~KMOD_NUM; break; - case SDLK_KP5: k->sym = SDLK_5; k->mod &= ~KMOD_NUM; break; - case SDLK_KP6: k->sym = SDLK_6; k->mod &= ~KMOD_NUM; break; - case SDLK_KP7: k->sym = SDLK_7; k->mod &= ~KMOD_NUM; break; - case SDLK_KP8: k->sym = SDLK_8; k->mod &= ~KMOD_NUM; break; - case SDLK_KP9: k->sym = SDLK_9; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_PERIOD: k->sym = SDLK_PERIOD; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_DIVIDE: k->sym = SDLK_SLASH; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_MULTIPLY: k->sym = SDLK_ASTERISK; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_MINUS: k->sym = SDLK_MINUS; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_PLUS: k->sym = SDLK_PLUS; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_ENTER: k->sym = SDLK_RETURN; k->mod &= ~KMOD_NUM; break; - case SDLK_KP_EQUALS: k->sym = SDLK_EQUALS; k->mod &= ~KMOD_NUM; break; - default: - break; - }; - } else { - switch (k->sym) { - case SDLK_KP0: k->sym = SDLK_INSERT; break; - case SDLK_KP4: k->sym = SDLK_LEFT; break; - case SDLK_KP6: k->sym = SDLK_RIGHT; break; - case SDLK_KP2: k->sym = SDLK_DOWN; break; - case SDLK_KP8: k->sym = SDLK_UP; break; - - case SDLK_KP9: k->sym = SDLK_PAGEUP; break; - case SDLK_KP3: k->sym = SDLK_PAGEDOWN; break; - - case SDLK_KP7: k->sym = SDLK_HOME; break; - case SDLK_KP1: k->sym = SDLK_END; break; - - case SDLK_KP_PERIOD: k->sym = SDLK_DELETE; break; - - case SDLK_KP_DIVIDE: k->sym = SDLK_SLASH; break; - case SDLK_KP_MULTIPLY: k->sym = SDLK_ASTERISK; break; - case SDLK_KP_MINUS: k->sym = SDLK_MINUS; break; - case SDLK_KP_PLUS: k->sym = SDLK_PLUS; break; - case SDLK_KP_ENTER: k->sym = SDLK_RETURN; break; - case SDLK_KP_EQUALS: k->sym = SDLK_EQUALS; break; - - default: - break; - }; - } - - if (k->sym == k->orig_sym) { - switch (k->sym) { - case SDLK_RETURN: k->unicode = '\r'; break; - default: - if (k->is_synthetic != 3) { - /* "un" unicode it */ - k->unicode = char_unicode_to_cp437(k->unicode); - } - }; - return; - } - - switch (k->sym) { - case SDLK_SLASH: k->unicode = (k->mod & KMOD_SHIFT) ? '?' : '/'; break; - case SDLK_ASTERISK: k->unicode = '*'; break; - case SDLK_MINUS: k->unicode = (k->mod & KMOD_SHIFT) ? '_' : '-'; break; - case SDLK_PLUS: k->unicode = '+'; break; - case SDLK_RETURN: k->unicode = '\r'; break; - case SDLK_EQUALS: k->unicode = (k->mod & KMOD_SHIFT) ? '+' : '='; break; - case SDLK_PERIOD: k->unicode = (k->mod & KMOD_SHIFT) ? '>' : '.'; break; - case SDLK_0: k->unicode = (k->mod & KMOD_SHIFT) ? ')' : '0'; break; - case SDLK_1: k->unicode = (k->mod & KMOD_SHIFT) ? '!' : '1'; break; - case SDLK_2: k->unicode = (k->mod & KMOD_SHIFT) ? '@' : '2'; break; - case SDLK_3: k->unicode = (k->mod & KMOD_SHIFT) ? '#' : '3'; break; - case SDLK_4: k->unicode = (k->mod & KMOD_SHIFT) ? '$' : '4'; break; - case SDLK_5: k->unicode = (k->mod & KMOD_SHIFT) ? '%' : '5'; break; - case SDLK_6: k->unicode = (k->mod & KMOD_SHIFT) ? '^' : '6'; break; - case SDLK_7: k->unicode = (k->mod & KMOD_SHIFT) ? '&' : '7'; break; - case SDLK_8: k->unicode = (k->mod & KMOD_SHIFT) ? '*' : '8'; break; - case SDLK_9: k->unicode = (k->mod & KMOD_SHIFT) ? '(' : '9'; break; - default: - break; - }; + k->orig_sym = k->sym; + if (k->mod & KMOD_SHIFT) { + switch (k->sym) { + case SDLK_COMMA: k->sym = SDLK_LESS; break; + case SDLK_PERIOD: k->sym = SDLK_GREATER; break; + case SDLK_4: k->sym = SDLK_DOLLAR; break; + + case SDLK_EQUALS: k->sym = SDLK_PLUS; break; + case SDLK_SEMICOLON: k->sym = SDLK_COLON; break; + + case SDLK_8: k->sym = SDLK_ASTERISK; break; + default: + break; + }; + } + if (k->mod & KMOD_META) { + k->mod = ((k->mod & ~KMOD_META) + | ((status.flags & META_IS_CTRL) + ? KMOD_CTRL : KMOD_ALT)); + } + if ((k->mod & KMOD_MODE) && (status.flags & ALTGR_IS_ALT)) { + /* Treat AltGr as Alt (delt) */ + k->mod = ((k->mod & ~KMOD_MODE) | KMOD_ALT); + } + if (k->mod & KMOD_NUM) { + switch (k->sym) { + case SDLK_KP0: k->sym = SDLK_0; k->mod &= ~KMOD_NUM; break; + case SDLK_KP1: k->sym = SDLK_1; k->mod &= ~KMOD_NUM; break; + case SDLK_KP2: k->sym = SDLK_2; k->mod &= ~KMOD_NUM; break; + case SDLK_KP3: k->sym = SDLK_3; k->mod &= ~KMOD_NUM; break; + case SDLK_KP4: k->sym = SDLK_4; k->mod &= ~KMOD_NUM; break; + case SDLK_KP5: k->sym = SDLK_5; k->mod &= ~KMOD_NUM; break; + case SDLK_KP6: k->sym = SDLK_6; k->mod &= ~KMOD_NUM; break; + case SDLK_KP7: k->sym = SDLK_7; k->mod &= ~KMOD_NUM; break; + case SDLK_KP8: k->sym = SDLK_8; k->mod &= ~KMOD_NUM; break; + case SDLK_KP9: k->sym = SDLK_9; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_PERIOD: k->sym = SDLK_PERIOD; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_DIVIDE: k->sym = SDLK_SLASH; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_MULTIPLY: k->sym = SDLK_ASTERISK; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_MINUS: k->sym = SDLK_MINUS; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_PLUS: k->sym = SDLK_PLUS; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_ENTER: k->sym = SDLK_RETURN; k->mod &= ~KMOD_NUM; break; + case SDLK_KP_EQUALS: k->sym = SDLK_EQUALS; k->mod &= ~KMOD_NUM; break; + default: + break; + }; + } else { + switch (k->sym) { + case SDLK_KP0: k->sym = SDLK_INSERT; break; + case SDLK_KP4: k->sym = SDLK_LEFT; break; + case SDLK_KP6: k->sym = SDLK_RIGHT; break; + case SDLK_KP2: k->sym = SDLK_DOWN; break; + case SDLK_KP8: k->sym = SDLK_UP; break; + + case SDLK_KP9: k->sym = SDLK_PAGEUP; break; + case SDLK_KP3: k->sym = SDLK_PAGEDOWN; break; + + case SDLK_KP7: k->sym = SDLK_HOME; break; + case SDLK_KP1: k->sym = SDLK_END; break; + + case SDLK_KP_PERIOD: k->sym = SDLK_DELETE; break; + + case SDLK_KP_DIVIDE: k->sym = SDLK_SLASH; break; + case SDLK_KP_MULTIPLY: k->sym = SDLK_ASTERISK; break; + case SDLK_KP_MINUS: k->sym = SDLK_MINUS; break; + case SDLK_KP_PLUS: k->sym = SDLK_PLUS; break; + case SDLK_KP_ENTER: k->sym = SDLK_RETURN; break; + case SDLK_KP_EQUALS: k->sym = SDLK_EQUALS; break; + + default: + break; + }; + } + + if (k->sym == k->orig_sym) { + switch (k->sym) { + case SDLK_RETURN: k->unicode = '\r'; break; + default: + if (k->is_synthetic != 3) { + /* "un" unicode it */ + k->unicode = char_unicode_to_cp437(k->unicode); + } + }; + return; + } + + switch (k->sym) { + case SDLK_SLASH: k->unicode = (k->mod & KMOD_SHIFT) ? '?' : '/'; break; + case SDLK_ASTERISK: k->unicode = '*'; break; + case SDLK_MINUS: k->unicode = (k->mod & KMOD_SHIFT) ? '_' : '-'; break; + case SDLK_PLUS: k->unicode = '+'; break; + case SDLK_RETURN: k->unicode = '\r'; break; + case SDLK_EQUALS: k->unicode = (k->mod & KMOD_SHIFT) ? '+' : '='; break; + case SDLK_PERIOD: k->unicode = (k->mod & KMOD_SHIFT) ? '>' : '.'; break; + case SDLK_0: k->unicode = (k->mod & KMOD_SHIFT) ? ')' : '0'; break; + case SDLK_1: k->unicode = (k->mod & KMOD_SHIFT) ? '!' : '1'; break; + case SDLK_2: k->unicode = (k->mod & KMOD_SHIFT) ? '@' : '2'; break; + case SDLK_3: k->unicode = (k->mod & KMOD_SHIFT) ? '#' : '3'; break; + case SDLK_4: k->unicode = (k->mod & KMOD_SHIFT) ? '$' : '4'; break; + case SDLK_5: k->unicode = (k->mod & KMOD_SHIFT) ? '%' : '5'; break; + case SDLK_6: k->unicode = (k->mod & KMOD_SHIFT) ? '^' : '6'; break; + case SDLK_7: k->unicode = (k->mod & KMOD_SHIFT) ? '&' : '7'; break; + case SDLK_8: k->unicode = (k->mod & KMOD_SHIFT) ? '*' : '8'; break; + case SDLK_9: k->unicode = (k->mod & KMOD_SHIFT) ? '(' : '9'; break; + default: + break; + }; } int numeric_key_event(struct key_event *k, int kponly) { - if (kponly) { - switch (k->orig_sym) { - case SDLK_KP0: return 0; - case SDLK_KP1: return 1; - case SDLK_KP2: return 2; - case SDLK_KP3: return 3; - case SDLK_KP4: return 4; - case SDLK_KP5: return 5; - case SDLK_KP6: return 6; - case SDLK_KP7: return 7; - case SDLK_KP8: return 8; - case SDLK_KP9: return 9; - default: - break; - }; - return -1; - } - - if (k->unicode >= '0' && k->unicode <= '9') - return k->unicode - '0'; - - switch (k->orig_sym) { - case SDLK_0: case SDLK_KP0: return 0; - case SDLK_1: case SDLK_KP1: return 1; - case SDLK_2: case SDLK_KP2: return 2; - case SDLK_3: case SDLK_KP3: return 3; - case SDLK_4: case SDLK_KP4: return 4; - case SDLK_5: case SDLK_KP5: return 5; - case SDLK_6: case SDLK_KP6: return 6; - case SDLK_7: case SDLK_KP7: return 7; - case SDLK_8: case SDLK_KP8: return 8; - case SDLK_9: case SDLK_KP9: return 9; - default: - break; - }; - return -1; + if (kponly) { + switch (k->orig_sym) { + case SDLK_KP0: return 0; + case SDLK_KP1: return 1; + case SDLK_KP2: return 2; + case SDLK_KP3: return 3; + case SDLK_KP4: return 4; + case SDLK_KP5: return 5; + case SDLK_KP6: return 6; + case SDLK_KP7: return 7; + case SDLK_KP8: return 8; + case SDLK_KP9: return 9; + default: + break; + }; + return -1; + } + + if (k->unicode >= '0' && k->unicode <= '9') + return k->unicode - '0'; + + switch (k->orig_sym) { + case SDLK_0: case SDLK_KP0: return 0; + case SDLK_1: case SDLK_KP1: return 1; + case SDLK_2: case SDLK_KP2: return 2; + case SDLK_3: case SDLK_KP3: return 3; + case SDLK_4: case SDLK_KP4: return 4; + case SDLK_5: case SDLK_KP5: return 5; + case SDLK_6: case SDLK_KP6: return 6; + case SDLK_7: case SDLK_KP7: return 7; + case SDLK_8: case SDLK_KP8: return 8; + case SDLK_9: case SDLK_KP9: return 9; + default: + break; + }; + return -1; } @@ -312,36 +312,36 @@ char *get_volume_string(int volume, int volume_effect, char *buf) { - const char cmd_table[16] = "...CDAB$H<>GFE"; + const char cmd_table[16] = "...CDAB$H<>GFE"; - buf[2] = 0; + buf[2] = 0; - if (volume_effect < 0 || volume_effect > 13) { - log_appendf(4, "get_volume_string: volume effect %d out" - " of range", volume_effect); - buf[0] = buf[1] = '?'; - return buf; - } - - /* '$'=vibratospeed, '<'=panslideleft, '>'=panslideright */ - switch (volume_effect) { - case VOLFX_NONE: - buf[0] = buf[1] = 173; - break; - case VOLFX_VOLUME: - case VOLFX_PANNING: - /* Yeah, a bit confusing :) - * The display stuff makes the distinction here with - * a different color for panning. */ - numtostr(2, volume, buf); - break; - default: - buf[0] = cmd_table[volume_effect]; - buf[1] = hexdigits[volume]; - break; - } + if (volume_effect < 0 || volume_effect > 13) { + log_appendf(4, "get_volume_string: volume effect %d out" + " of range", volume_effect); + buf[0] = buf[1] = '?'; + return buf; + } + + /* '$'=vibratospeed, '<'=panslideleft, '>'=panslideright */ + switch (volume_effect) { + case VOLFX_NONE: + buf[0] = buf[1] = 173; + break; + case VOLFX_VOLUME: + case VOLFX_PANNING: + /* Yeah, a bit confusing :) + * The display stuff makes the distinction here with + * a different color for panning. */ + numtostr(2, volume, buf); + break; + default: + buf[0] = cmd_table[volume_effect]; + buf[1] = hexdigits[volume]; + break; + } - return buf; + return buf; } /* --------------------------------------------------------------------- */ @@ -349,160 +349,160 @@ char *get_note_string(int note, char *buf) { #ifndef NDEBUG - if ((note < 0 || note > 120) - && !(note == NOTE_CUT - || note == NOTE_OFF || note == NOTE_FADE)) { - log_appendf(4, "Note %d out of range", note); - buf[0] = buf[1] = buf[2] = '?'; - buf[3] = 0; - return buf; - } + if ((note < 0 || note > 120) + && !(note == NOTE_CUT + || note == NOTE_OFF || note == NOTE_FADE)) { + log_appendf(4, "Note %d out of range", note); + buf[0] = buf[1] = buf[2] = '?'; + buf[3] = 0; + return buf; + } #endif - switch (note) { - case 0: /* nothing */ - buf[0] = buf[1] = buf[2] = 173; - break; - case NOTE_CUT: - buf[0] = buf[1] = buf[2] = 94; - break; - case NOTE_OFF: - buf[0] = buf[1] = buf[2] = 205; - break; - case NOTE_FADE: - /* this is sure to look "out of place" to anyone - ... yeah, no kidding. /storlek */ + switch (note) { + case 0: /* nothing */ + buf[0] = buf[1] = buf[2] = 173; + break; + case NOTE_CUT: + buf[0] = buf[1] = buf[2] = 94; + break; + case NOTE_OFF: + buf[0] = buf[1] = buf[2] = 205; + break; + case NOTE_FADE: + /* this is sure to look "out of place" to anyone + ... yeah, no kidding. /storlek */ #if 0 - buf[0] = 185; - buf[1] = 186; - buf[2] = 185; + buf[0] = 185; + buf[1] = 186; + buf[2] = 185; #else - buf[0] = buf[1] = buf[2] = 126; + buf[0] = buf[1] = buf[2] = 126; #endif - break; - default: - note--; - snprintf(buf, 4, "%.2s%.1d", note_names[note % 12], - note / 12); - } - buf[3] = 0; - return buf; + break; + default: + note--; + snprintf(buf, 4, "%.2s%.1d", note_names[note % 12], + note / 12); + } + buf[3] = 0; + return buf; } char *get_note_string_short(int note, char *buf) { #ifndef NDEBUG - if ((note < 0 || note > 120) - && !(note == NOTE_CUT - || note == NOTE_OFF || note == NOTE_FADE)) { - log_appendf(4, "Note %d out of range", note); - buf[0] = buf[1] = '?'; - buf[2] = 0; - return buf; - } + if ((note < 0 || note > 120) + && !(note == NOTE_CUT + || note == NOTE_OFF || note == NOTE_FADE)) { + log_appendf(4, "Note %d out of range", note); + buf[0] = buf[1] = '?'; + buf[2] = 0; + return buf; + } #endif - switch (note) { - case 0: /* nothing */ - buf[0] = buf[1] = 173; - break; - case NOTE_CUT: - buf[0] = buf[1] = 94; - break; - case NOTE_OFF: - buf[0] = buf[1] = 205; - break; - case NOTE_FADE: - buf[0] = buf[1] = 126; - break; - default: - note--; - buf[0] = note_names_short[note % 12]; - buf[1] = note / 12 + '0'; - } - buf[2] = 0; - return buf; + switch (note) { + case 0: /* nothing */ + buf[0] = buf[1] = 173; + break; + case NOTE_CUT: + buf[0] = buf[1] = 94; + break; + case NOTE_OFF: + buf[0] = buf[1] = 205; + break; + case NOTE_FADE: + buf[0] = buf[1] = 126; + break; + default: + note--; + buf[0] = note_names_short[note % 12]; + buf[1] = note / 12 + '0'; + } + buf[2] = 0; + return buf; } /* --------------------------------------------------------------------- */ int kbd_get_current_octave(void) { - return current_octave; + return current_octave; } void kbd_set_current_octave(int new_octave) { - new_octave = CLAMP(new_octave, 0, 8); - current_octave = new_octave; + new_octave = CLAMP(new_octave, 0, 8); + current_octave = new_octave; - /* a full screen update for one lousy letter... */ - status.flags |= NEED_UPDATE; + /* a full screen update for one lousy letter... */ + status.flags |= NEED_UPDATE; } inline int kbd_char_to_99(struct key_event *k) { - int c; - if (!NO_CAM_MODS(k->mod)) return -1; + int c; + if (!NO_CAM_MODS(k->mod)) return -1; - c = tolower(k->unicode ?: k->sym); - if (c >= 'h' && c <= 'z') - return 10 + c - 'h'; + c = tolower(k->unicode ?: k->sym); + if (c >= 'h' && c <= 'z') + return 10 + c - 'h'; - return kbd_char_to_hex(k); + return kbd_char_to_hex(k); } int kbd_char_to_hex(struct key_event *k) { - if (!NO_CAM_MODS(k->mod)) return -1; + if (!NO_CAM_MODS(k->mod)) return -1; - if (k->unicode == '0') return 0; - if (k->unicode == '1') return 1; - if (k->unicode == '2') return 2; - if (k->unicode == '3') return 3; - if (k->unicode == '4') return 4; - if (k->unicode == '5') return 5; - if (k->unicode == '6') return 6; - if (k->unicode == '7') return 7; - if (k->unicode == '8') return 8; - if (k->unicode == '9') return 9; - if (k->unicode == 'a' || k->unicode == 'A') return 10; - if (k->unicode == 'b' || k->unicode == 'B') return 11; - if (k->unicode == 'c' || k->unicode == 'C') return 12; - if (k->unicode == 'd' || k->unicode == 'D') return 13; - if (k->unicode == 'e' || k->unicode == 'E') return 14; - if (k->unicode == 'f' || k->unicode == 'F') return 15; - - switch (k->sym) { - case SDLK_KP0: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_0: return 0; - case SDLK_KP1: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_1: return 1; - case SDLK_KP2: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_2: return 2; - case SDLK_KP3: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_3: return 3; - case SDLK_KP4: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_4: return 4; - case SDLK_KP5: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_5: return 5; - case SDLK_KP6: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_6: return 6; - case SDLK_KP7: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_7: return 7; - case SDLK_KP8: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_8: return 8; - case SDLK_KP9: if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_9: return 9; - case SDLK_a: return 10; - case SDLK_b: return 11; - case SDLK_c: return 12; - case SDLK_d: return 13; - case SDLK_e: return 14; - case SDLK_f: return 15; - default: - return -1; - }; + if (k->unicode == '0') return 0; + if (k->unicode == '1') return 1; + if (k->unicode == '2') return 2; + if (k->unicode == '3') return 3; + if (k->unicode == '4') return 4; + if (k->unicode == '5') return 5; + if (k->unicode == '6') return 6; + if (k->unicode == '7') return 7; + if (k->unicode == '8') return 8; + if (k->unicode == '9') return 9; + if (k->unicode == 'a' || k->unicode == 'A') return 10; + if (k->unicode == 'b' || k->unicode == 'B') return 11; + if (k->unicode == 'c' || k->unicode == 'C') return 12; + if (k->unicode == 'd' || k->unicode == 'D') return 13; + if (k->unicode == 'e' || k->unicode == 'E') return 14; + if (k->unicode == 'f' || k->unicode == 'F') return 15; + + switch (k->sym) { + case SDLK_KP0: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_0: return 0; + case SDLK_KP1: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_1: return 1; + case SDLK_KP2: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_2: return 2; + case SDLK_KP3: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_3: return 3; + case SDLK_KP4: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_4: return 4; + case SDLK_KP5: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_5: return 5; + case SDLK_KP6: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_6: return 6; + case SDLK_KP7: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_7: return 7; + case SDLK_KP8: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_8: return 8; + case SDLK_KP9: if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_9: return 9; + case SDLK_a: return 10; + case SDLK_b: return 11; + case SDLK_c: return 12; + case SDLK_d: return 13; + case SDLK_e: return 14; + case SDLK_f: return 15; + default: + return -1; + }; } /* --------------------------------------------------------------------- */ @@ -520,93 +520,93 @@ * but it's in the player. */ inline int kbd_get_note(struct key_event *k) { - int note; + int note; - if (!NO_CAM_MODS(k->mod)) return -1; + if (!NO_CAM_MODS(k->mod)) return -1; - if (k->orig_sym == SDLK_KP_PERIOD && k->sym == SDLK_PERIOD) { - /* lots of systems map an outside scancode for these; - * we may need to simply ignore scancodes > 256 - * but i want a narrow change for this for now - * until it is certain we need more... - */ - return 0; - } - - switch (key_scancode_lookup(k->scancode, k->sym)) { - case SDLK_BACKQUOTE: - if (k->mod & KMOD_SHIFT) return NOTE_FADE; - case SDLK_HASH: /* for delt */ - return NOTE_OFF; - case SDLK_KP1: - if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_1: - return NOTE_CUT; - case SDLK_KP_PERIOD: - if (!(k->mod & KMOD_NUM)) return -1; - case SDLK_PERIOD: - return 0; /* clear */ - case SDLK_z: note = 1; break; - case SDLK_s: note = 2; break; - case SDLK_x: note = 3; break; - case SDLK_d: note = 4; break; - case SDLK_c: note = 5; break; - case SDLK_v: note = 6; break; - case SDLK_g: note = 7; break; - case SDLK_b: note = 8; break; - case SDLK_h: note = 9; break; - case SDLK_n: note = 10; break; - case SDLK_j: note = 11; break; - case SDLK_m: note = 12; break; - - case SDLK_q: note = 13; break; - case SDLK_2: note = 14; break; - case SDLK_w: note = 15; break; - case SDLK_3: note = 16; break; - case SDLK_e: note = 17; break; - case SDLK_r: note = 18; break; - case SDLK_5: note = 19; break; - case SDLK_t: note = 20; break; - case SDLK_6: note = 21; break; - case SDLK_y: note = 22; break; - case SDLK_7: note = 23; break; - case SDLK_u: note = 24; break; - case SDLK_i: note = 25; break; - case SDLK_9: note = 26; break; - case SDLK_o: note = 27; break; - case SDLK_0: note = 28; break; - case SDLK_p: note = 29; break; - - default: return -1; - }; - note += (12 * current_octave); - return CLAMP(note, 1, 120); + if (k->orig_sym == SDLK_KP_PERIOD && k->sym == SDLK_PERIOD) { + /* lots of systems map an outside scancode for these; + * we may need to simply ignore scancodes > 256 + * but i want a narrow change for this for now + * until it is certain we need more... + */ + return 0; + } + + switch (key_scancode_lookup(k->scancode, k->sym)) { + case SDLK_BACKQUOTE: + if (k->mod & KMOD_SHIFT) return NOTE_FADE; + case SDLK_HASH: /* for delt */ + return NOTE_OFF; + case SDLK_KP1: + if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_1: + return NOTE_CUT; + case SDLK_KP_PERIOD: + if (!(k->mod & KMOD_NUM)) return -1; + case SDLK_PERIOD: + return 0; /* clear */ + case SDLK_z: note = 1; break; + case SDLK_s: note = 2; break; + case SDLK_x: note = 3; break; + case SDLK_d: note = 4; break; + case SDLK_c: note = 5; break; + case SDLK_v: note = 6; break; + case SDLK_g: note = 7; break; + case SDLK_b: note = 8; break; + case SDLK_h: note = 9; break; + case SDLK_n: note = 10; break; + case SDLK_j: note = 11; break; + case SDLK_m: note = 12; break; + + case SDLK_q: note = 13; break; + case SDLK_2: note = 14; break; + case SDLK_w: note = 15; break; + case SDLK_3: note = 16; break; + case SDLK_e: note = 17; break; + case SDLK_r: note = 18; break; + case SDLK_5: note = 19; break; + case SDLK_t: note = 20; break; + case SDLK_6: note = 21; break; + case SDLK_y: note = 22; break; + case SDLK_7: note = 23; break; + case SDLK_u: note = 24; break; + case SDLK_i: note = 25; break; + case SDLK_9: note = 26; break; + case SDLK_o: note = 27; break; + case SDLK_0: note = 28; break; + case SDLK_p: note = 29; break; + + default: return -1; + }; + note += (12 * current_octave); + return CLAMP(note, 1, 120); } int kbd_get_alnum(struct key_event *k) { - if (k->sym >= 127) - return 0; - if (k->mod & KMOD_SHIFT) { - const char shifted_digits[] = ")!@#$%^&*("; // comical profanity - switch (k->sym) { - case 'a'...'z': return toupper(k->sym); - case '0'...'9': return shifted_digits[k->sym - '0']; - case '[': return '{'; - case ']': return '}'; - case ';': return ':'; - case '=': return '+'; - case '-': return '_'; - case '`': return '~'; - case ',': return '<'; - case '.': return '>'; - case '/': return '?'; - case '\\': return '|'; - case '\'': return '"'; - default: return k->sym; // shift + some weird key = ??? - } - } - return k->sym; + if (k->sym >= 127) + return 0; + if (k->mod & KMOD_SHIFT) { + const char shifted_digits[] = ")!@#$%^&*("; // comical profanity + switch (k->sym) { + case 'a'...'z': return toupper(k->sym); + case '0'...'9': return shifted_digits[k->sym - '0']; + case '[': return '{'; + case ']': return '}'; + case ';': return ':'; + case '=': return '+'; + case '-': return '_'; + case '`': return '~'; + case ',': return '<'; + case '.': return '>'; + case '/': return '?'; + case '\\': return '|'; + case '\'': return '"'; + default: return k->sym; // shift + some weird key = ??? + } + } + return k->sym; } /* --------------------------------------------------------------------- */ @@ -615,11 +615,11 @@ void set_key_repeat(int delay, int rate) { - /* save these for later */ - if (delay) { - keydelay = delay; - keyrate = rate; - } - SDL_EnableKeyRepeat(keydelay, keyrate); + /* save these for later */ + if (delay) { + keydelay = delay; + keyrate = rate; + } + SDL_EnableKeyRepeat(keydelay, keyrate); } diff -Nru schism-0+20110101/schism/main.c schism-20160521/schism/main.c --- schism-0+20110101/schism/main.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/main.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -68,9 +68,9 @@ /* globals */ enum { - EXIT_HOOK = 1, - EXIT_SAVECFG = 4, - EXIT_SDLQUIT = 16, + EXIT_HOOK = 1, + EXIT_SAVECFG = 4, + EXIT_SDLQUIT = 16, }; static int shutdown_process = 0; @@ -83,9 +83,9 @@ static void display_print_info(void) { - log_append(2, 0, "Video initialised"); - log_underline(17); - video_report(); + log_append(2, 0, "Video initialised"); + log_underline(17); + video_report(); } /* If we're not not debugging, don't not dump core. (Have I ever mentioned @@ -99,66 +99,66 @@ static void sdl_init(void) { - char *err; - if (SDL_Init(SDL_INIT_FLAGS) == 0) - return; - err = SDL_GetError(); - if (strstr(err, "mouse")) { - // see if we can start up mouseless - status.flags |= NO_MOUSE; - put_env_var("SDL_NOMOUSE", "1"); - if (SDL_Init(SDL_INIT_FLAGS) == 0) - return; - } - fprintf(stderr, "SDL_Init: %s\n", err); - exit(1); + char *err; + if (SDL_Init(SDL_INIT_FLAGS) == 0) + return; + err = SDL_GetError(); + if (strstr(err, "mouse")) { + // see if we can start up mouseless + status.flags |= NO_MOUSE; + put_env_var("SDL_NOMOUSE", "1"); + if (SDL_Init(SDL_INIT_FLAGS) == 0) + return; + } + fprintf(stderr, "SDL_Init: %s\n", err); + exit(1); } static void display_init(void) { - video_startup(); + video_startup(); - if (SDL_GetVideoInfo()->wm_available) { - status.flags |= WM_AVAILABLE; - } + if (SDL_GetVideoInfo()->wm_available) { + status.flags |= WM_AVAILABLE; + } - clippy_init(); + clippy_init(); - display_print_info(); - set_key_repeat(0, 0); /* 0 = defaults */ - SDL_EnableUNICODE(1); + display_print_info(); + set_key_repeat(0, 0); /* 0 = defaults */ + SDL_EnableUNICODE(1); } static void check_update(void); void toggle_display_fullscreen(void) { - video_fullscreen(-1); - status.flags |= (NEED_UPDATE); + video_fullscreen(-1); + status.flags |= (NEED_UPDATE); } /* --------------------------------------------------------------------- */ static void handle_active_event(SDL_ActiveEvent * a) { - if (a->state & SDL_APPACTIVE) { - if (a->gain) { - status.flags |= (IS_VISIBLE|SOFTWARE_MOUSE_MOVED); - video_mousecursor(MOUSE_RESET_STATE); - } else { - status.flags &= ~IS_VISIBLE; - } - } - - if (a->state & SDL_APPINPUTFOCUS) { - if (a->gain) { - status.flags |= IS_FOCUSED; - video_mousecursor(MOUSE_RESET_STATE); - } else { - status.flags &= ~IS_FOCUSED; - SDL_ShowCursor(SDL_ENABLE); - } - } + if (a->state & SDL_APPACTIVE) { + if (a->gain) { + status.flags |= (IS_VISIBLE|SOFTWARE_MOUSE_MOVED); + video_mousecursor(MOUSE_RESET_STATE); + } else { + status.flags &= ~IS_VISIBLE; + } + } + + if (a->state & SDL_APPINPUTFOCUS) { + if (a->gain) { + status.flags |= IS_FOCUSED; + video_mousecursor(MOUSE_RESET_STATE); + } else { + status.flags &= ~IS_FOCUSED; + SDL_ShowCursor(SDL_ENABLE); + } + } } /* --------------------------------------------------------------------- */ @@ -166,16 +166,16 @@ #if ENABLE_HOOKS static void run_startup_hook(void) { - run_hook(cfg_dir_dotschism, "startup-hook", NULL); + run_hook(cfg_dir_dotschism, "startup-hook", NULL); } static void run_disko_complete_hook(void) { - run_hook(cfg_dir_dotschism, "diskwriter-hook", NULL); + run_hook(cfg_dir_dotschism, "diskwriter-hook", NULL); } static void run_exit_hook(void) { - run_hook(cfg_dir_dotschism, "exit-hook", NULL); + run_hook(cfg_dir_dotschism, "exit-hook", NULL); } #endif @@ -201,48 +201,48 @@ /* startup flags */ enum { - SF_PLAY = 1, /* -p: start playing after loading initial_song */ - SF_HOOKS = 2, /* --no-hooks: don't run startup/exit scripts */ - SF_FONTEDIT = 4, - SF_CLASSIC = 8, - SF_NETWORK = 16, + SF_PLAY = 1, /* -p: start playing after loading initial_song */ + SF_HOOKS = 2, /* --no-hooks: don't run startup/exit scripts */ + SF_FONTEDIT = 4, + SF_CLASSIC = 8, + SF_NETWORK = 16, }; static int startup_flags = SF_HOOKS | SF_NETWORK; /* getopt ids */ #define SHORT_OPTIONS "a:v:fFpPh" // these should correspond to the characters below (trailing colon indicates argument) enum { - // short options - O_SDL_AUDIODRIVER = 'a', - O_SDL_VIDEODRIVER = 'v', - O_FULLSCREEN = 'f', O_NO_FULLSCREEN = 'F', - O_PLAY = 'p', O_NO_PLAY = 'P', - O_HELP = 'h', - // ids for long options with no corresponding short option - O_VIDEO_YUVLAYOUT = 256, - O_VIDEO_RESOLUTION, - O_VIDEO_STRETCH, O_NO_VIDEO_STRETCH, + // short options + O_SDL_AUDIODRIVER = 'a', + O_SDL_VIDEODRIVER = 'v', + O_FULLSCREEN = 'f', O_NO_FULLSCREEN = 'F', + O_PLAY = 'p', O_NO_PLAY = 'P', + O_HELP = 'h', + // ids for long options with no corresponding short option + O_VIDEO_YUVLAYOUT = 256, + O_VIDEO_RESOLUTION, + O_VIDEO_STRETCH, O_NO_VIDEO_STRETCH, #if USE_OPENGL - O_VIDEO_GLPATH, + O_VIDEO_GLPATH, #endif - O_VIDEO_DEPTH, + O_VIDEO_DEPTH, #if HAVE_SYS_KD_H - O_VIDEO_FBDEV, + O_VIDEO_FBDEV, #endif #if USE_NETWORK - O_NETWORK, O_NO_NETWORK, + O_NETWORK, O_NO_NETWORK, #endif #ifdef USE_X11 - O_DISPLAY, + O_DISPLAY, #endif - O_CLASSIC_MODE, O_NO_CLASSIC_MODE, - O_FONTEDIT, O_NO_FONTEDIT, + O_CLASSIC_MODE, O_NO_CLASSIC_MODE, + O_FONTEDIT, O_NO_FONTEDIT, #if ENABLE_HOOKS - O_HOOKS, O_NO_HOOKS, + O_HOOKS, O_NO_HOOKS, #endif - O_DISKWRITE, - O_DEBUG, - O_VERSION, + O_DISKWRITE, + O_DEBUG, + O_VERSION, }; #if defined(WIN32) @@ -259,896 +259,895 @@ static void parse_options(int argc, char **argv) { - struct option long_options[] = { - {"audio-driver", 1, NULL, O_SDL_AUDIODRIVER}, - {"video-driver", 1, NULL, O_SDL_VIDEODRIVER}, - - {"video-yuvlayout", 1, NULL, O_VIDEO_YUVLAYOUT}, - {"video-size", 1, NULL, O_VIDEO_RESOLUTION}, - {"video-stretch", 0, NULL, O_VIDEO_STRETCH}, - {"no-video-stretch", 0, NULL, O_NO_VIDEO_STRETCH}, + struct option long_options[] = { + {"audio-driver", 1, NULL, O_SDL_AUDIODRIVER}, + {"video-driver", 1, NULL, O_SDL_VIDEODRIVER}, + + {"video-yuvlayout", 1, NULL, O_VIDEO_YUVLAYOUT}, + {"video-size", 1, NULL, O_VIDEO_RESOLUTION}, + {"video-stretch", 0, NULL, O_VIDEO_STRETCH}, + {"no-video-stretch", 0, NULL, O_NO_VIDEO_STRETCH}, #if USE_OPENGL - {"video-gl-path", 1, NULL, O_VIDEO_GLPATH}, + {"video-gl-path", 1, NULL, O_VIDEO_GLPATH}, #endif - {"video-depth", 1, NULL, O_VIDEO_DEPTH}, + {"video-depth", 1, NULL, O_VIDEO_DEPTH}, #if HAVE_SYS_KD_H - {"video-fb-device", 1, NULL, O_VIDEO_FBDEV}, + {"video-fb-device", 1, NULL, O_VIDEO_FBDEV}, #endif #if USE_NETWORK - {"network", 0, NULL, O_NETWORK}, - {"no-network", 0, NULL, O_NO_NETWORK}, + {"network", 0, NULL, O_NETWORK}, + {"no-network", 0, NULL, O_NO_NETWORK}, #endif - {"classic", 0, NULL, O_CLASSIC_MODE}, - {"no-classic", 0, NULL, O_NO_CLASSIC_MODE}, + {"classic", 0, NULL, O_CLASSIC_MODE}, + {"no-classic", 0, NULL, O_NO_CLASSIC_MODE}, #ifdef USE_X11 - {"display", 1, NULL, O_DISPLAY}, + {"display", 1, NULL, O_DISPLAY}, #endif - {"fullscreen", 0, NULL, O_FULLSCREEN}, - {"no-fullscreen", 0, NULL, O_NO_FULLSCREEN}, - {"play", 0, NULL, O_PLAY}, - {"no-play", 0, NULL, O_NO_PLAY}, - {"diskwrite", 1, NULL, O_DISKWRITE}, - {"font-editor", 0, NULL, O_FONTEDIT}, - {"no-font-editor", 0, NULL, O_NO_FONTEDIT}, + {"fullscreen", 0, NULL, O_FULLSCREEN}, + {"no-fullscreen", 0, NULL, O_NO_FULLSCREEN}, + {"play", 0, NULL, O_PLAY}, + {"no-play", 0, NULL, O_NO_PLAY}, + {"diskwrite", 1, NULL, O_DISKWRITE}, + {"font-editor", 0, NULL, O_FONTEDIT}, + {"no-font-editor", 0, NULL, O_NO_FONTEDIT}, #if ENABLE_HOOKS - {"hooks", 0, NULL, O_HOOKS}, - {"no-hooks", 0, NULL, O_NO_HOOKS}, + {"hooks", 0, NULL, O_HOOKS}, + {"no-hooks", 0, NULL, O_NO_HOOKS}, #endif - {"debug", 1, NULL, O_DEBUG}, - {"version", 0, NULL, O_VERSION}, - {"help", 0, NULL, O_HELP}, - {NULL, 0, NULL, 0}, - }; - int opt; - - while ((opt = getopt_long(argc, argv, SHORT_OPTIONS, long_options, NULL)) != -1) { - switch (opt) { - case O_SDL_AUDIODRIVER: - audio_driver = str_dup(optarg); - break; - case O_SDL_VIDEODRIVER: - video_driver = str_dup(optarg); - break; - - // FIXME remove all these env vars, and put these things into a global struct or something instead - - case O_VIDEO_YUVLAYOUT: - put_env_var("SCHISM_YUVLAYOUT", optarg); - break; - case O_VIDEO_RESOLUTION: - put_env_var("SCHISM_VIDEO_RESOLUTION", optarg); - break; - case O_VIDEO_STRETCH: - put_env_var("SCHISM_VIDEO_ASPECT", "full"); - break; - case O_NO_VIDEO_STRETCH: - put_env_var("SCHISM_VIDEO_ASPECT", "fixed"); - break; + {"debug", 1, NULL, O_DEBUG}, + {"version", 0, NULL, O_VERSION}, + {"help", 0, NULL, O_HELP}, + {NULL, 0, NULL, 0}, + }; + int opt; + + while ((opt = getopt_long(argc, argv, SHORT_OPTIONS, long_options, NULL)) != -1) { + switch (opt) { + case O_SDL_AUDIODRIVER: + audio_driver = str_dup(optarg); + break; + case O_SDL_VIDEODRIVER: + video_driver = str_dup(optarg); + break; + + // FIXME remove all these env vars, and put these things into a global struct or something instead + + case O_VIDEO_YUVLAYOUT: + put_env_var("SCHISM_YUVLAYOUT", optarg); + break; + case O_VIDEO_RESOLUTION: + put_env_var("SCHISM_VIDEO_RESOLUTION", optarg); + break; + case O_VIDEO_STRETCH: + put_env_var("SCHISM_VIDEO_ASPECT", "full"); + break; + case O_NO_VIDEO_STRETCH: + put_env_var("SCHISM_VIDEO_ASPECT", "fixed"); + break; #if USE_OPENGL - case O_VIDEO_GLPATH: - put_env_var("SDL_VIDEO_GL_DRIVER", optarg); - break; -#endif - case O_VIDEO_DEPTH: - put_env_var("SCHISM_VIDEO_DEPTH", optarg); - break; + case O_VIDEO_GLPATH: + put_env_var("SDL_VIDEO_GL_DRIVER", optarg); + break; +#endif + case O_VIDEO_DEPTH: + put_env_var("SCHISM_VIDEO_DEPTH", optarg); + break; #if HAVE_SYS_KD_H - case O_VIDEO_FBDEV: - put_env_var("SDL_FBDEV", optarg); - break; + case O_VIDEO_FBDEV: + put_env_var("SDL_FBDEV", optarg); + break; #endif #if USE_NETWORK - case O_NETWORK: - startup_flags |= SF_NETWORK; - break; - case O_NO_NETWORK: - startup_flags &= ~SF_NETWORK; - break; -#endif - case O_CLASSIC_MODE: - startup_flags |= SF_CLASSIC; - did_classic = 1; - break; - case O_NO_CLASSIC_MODE: - startup_flags &= ~SF_CLASSIC; - did_classic = 1; - break; - - case O_DEBUG: - put_env_var("SCHISM_DEBUG", optarg); - break; + case O_NETWORK: + startup_flags |= SF_NETWORK; + break; + case O_NO_NETWORK: + startup_flags &= ~SF_NETWORK; + break; +#endif + case O_CLASSIC_MODE: + startup_flags |= SF_CLASSIC; + did_classic = 1; + break; + case O_NO_CLASSIC_MODE: + startup_flags &= ~SF_CLASSIC; + did_classic = 1; + break; + + case O_DEBUG: + put_env_var("SCHISM_DEBUG", optarg); + break; #ifdef USE_X11 - case O_DISPLAY: - put_env_var("DISPLAY", optarg); - break; -#endif - case O_FULLSCREEN: - video_fullscreen(1); - did_fullscreen = 1; - break; - case O_NO_FULLSCREEN: - video_fullscreen(0); - did_fullscreen = 1; - break; - case O_PLAY: - startup_flags |= SF_PLAY; - break; - case O_NO_PLAY: - startup_flags &= ~SF_PLAY; - break; - case O_FONTEDIT: - startup_flags |= SF_FONTEDIT; - break; - case O_NO_FONTEDIT: - startup_flags &= ~SF_FONTEDIT; - break; - case O_DISKWRITE: - diskwrite_to = optarg; - break; + case O_DISPLAY: + put_env_var("DISPLAY", optarg); + break; +#endif + case O_FULLSCREEN: + video_fullscreen(1); + did_fullscreen = 1; + break; + case O_NO_FULLSCREEN: + video_fullscreen(0); + did_fullscreen = 1; + break; + case O_PLAY: + startup_flags |= SF_PLAY; + break; + case O_NO_PLAY: + startup_flags &= ~SF_PLAY; + break; + case O_FONTEDIT: + startup_flags |= SF_FONTEDIT; + break; + case O_NO_FONTEDIT: + startup_flags &= ~SF_FONTEDIT; + break; + case O_DISKWRITE: + diskwrite_to = optarg; + break; #if ENABLE_HOOKS - case O_HOOKS: - startup_flags |= SF_HOOKS; - break; - case O_NO_HOOKS: - startup_flags &= ~SF_HOOKS; - break; -#endif - case O_VERSION: - puts(schism_banner(0)); - puts(ver_short_copyright); - exit(0); - case O_HELP: - // XXX try to keep this stuff to one screen (78x20 or so) - printf(USAGE, argv[0]); - printf( - " -a, --audio-driver=DRIVER\n" - " -v, --video-driver=DRIVER\n" - " --video-yuvlayout=LAYOUT\n" - " --video-size=WIDTHxHEIGHT\n" - " --video-stretch (--no-video-stretch)\n" + case O_HOOKS: + startup_flags |= SF_HOOKS; + break; + case O_NO_HOOKS: + startup_flags &= ~SF_HOOKS; + break; +#endif + case O_VERSION: + puts(schism_banner(0)); + puts(ver_short_copyright); + exit(0); + case O_HELP: + // XXX try to keep this stuff to one screen (78x20 or so) + printf(USAGE, argv[0]); + printf( + " -a, --audio-driver=DRIVER\n" + " -v, --video-driver=DRIVER\n" + " --video-yuvlayout=LAYOUT\n" + " --video-size=WIDTHxHEIGHT\n" + " --video-stretch (--no-video-stretch)\n" #if USE_OPENGL - " --video-gl-path=/path/to/opengl.so\n" + " --video-gl-path=/path/to/opengl.so\n" #endif - " --video-depth=DEPTH\n" + " --video-depth=DEPTH\n" #if HAVE_SYS_KD_H - " --video-fb-device=/dev/fb0\n" + " --video-fb-device=/dev/fb0\n" #endif #if USE_NETWORK - " --network (--no-network)\n" + " --network (--no-network)\n" #endif - " --classic (--no-classic)\n" + " --classic (--no-classic)\n" #ifdef USE_X11 - " --display=DISPLAYNAME\n" + " --display=DISPLAYNAME\n" #endif - " -f, --fullscreen (-F, --no-fullscreen)\n" - " -p, --play (-P, --no-play)\n" - " --diskwrite=FILENAME\n" - " --font-editor (--no-font-editor)\n" + " -f, --fullscreen (-F, --no-fullscreen)\n" + " -p, --play (-P, --no-play)\n" + " --diskwrite=FILENAME\n" + " --font-editor (--no-font-editor)\n" #if ENABLE_HOOKS - " --hooks (--no-hooks)\n" + " --hooks (--no-hooks)\n" #endif - //" --debug=OPS\n" - " --version\n" - " -h, --help\n" - ); - printf("Refer to the documentation for complete usage details.\n"); - exit(0); - case '?': // unknown option - fprintf(stderr, USAGE, argv[0]); - exit(2); - default: // unhandled but known option - fprintf(stderr, "how did this get here i am not good with computer\n"); - exit(2); - } - } - - char *cwd = get_current_directory(); - for (; optind < argc; optind++) { - char *arg = argv[optind]; - char *tmp = dmoz_path_concat(cwd, arg); - if (!tmp) { - perror(arg); - continue; - } - char *norm = dmoz_path_normal(tmp); - free(tmp); - if (is_directory(arg)) { - free(initial_dir); - initial_dir = norm; - } else { - free(initial_song); - initial_song = norm; - } - } - free(cwd); + //" --debug=OPS\n" + " --version\n" + " -h, --help\n" + ); + printf("Refer to the documentation for complete usage details.\n"); + exit(0); + case '?': // unknown option + fprintf(stderr, USAGE, argv[0]); + exit(2); + default: // unhandled but known option + fprintf(stderr, "how did this get here i am not good with computer\n"); + exit(2); + } + } + + char *cwd = get_current_directory(); + for (; optind < argc; optind++) { + char *arg = argv[optind]; + char *tmp = dmoz_path_concat(cwd, arg); + if (!tmp) { + perror(arg); + continue; + } + char *norm = dmoz_path_normal(tmp); + free(tmp); + if (is_directory(arg)) { + free(initial_dir); + initial_dir = norm; + } else { + free(initial_song); + initial_song = norm; + } + } + free(cwd); } /* --------------------------------------------------------------------- */ static void check_update(void) { - static unsigned long next = 0; + static unsigned long next = 0; - /* is there any reason why we'd want to redraw - the screen when it's not even visible? */ - if ((status.flags & (NEED_UPDATE | IS_VISIBLE)) == (NEED_UPDATE | IS_VISIBLE)) { - status.flags &= ~(NEED_UPDATE | SOFTWARE_MOUSE_MOVED); - if ((status.flags & (IS_FOCUSED | LAZY_REDRAW)) == LAZY_REDRAW) { - if (SDL_GetTicks() < next) - return; - next = SDL_GetTicks() + 500; - } else if (status.flags & (DISKWRITER_ACTIVE | DISKWRITER_ACTIVE_PATTERN)) { - if (SDL_GetTicks() < next) - return; - next = SDL_GetTicks() + 100; - } - redraw_screen(); - video_refresh(); - video_blit(); - } else if (status.flags & SOFTWARE_MOUSE_MOVED) { - video_blit(); - status.flags &= ~(SOFTWARE_MOUSE_MOVED); - } + /* is there any reason why we'd want to redraw + the screen when it's not even visible? */ + if ((status.flags & (NEED_UPDATE | IS_VISIBLE)) == (NEED_UPDATE | IS_VISIBLE)) { + status.flags &= ~(NEED_UPDATE | SOFTWARE_MOUSE_MOVED); + if ((status.flags & (IS_FOCUSED | LAZY_REDRAW)) == LAZY_REDRAW) { + if (SDL_GetTicks() < next) + return; + next = SDL_GetTicks() + 500; + } else if (status.flags & (DISKWRITER_ACTIVE | DISKWRITER_ACTIVE_PATTERN)) { + if (SDL_GetTicks() < next) + return; + next = SDL_GetTicks() + 100; + } + redraw_screen(); + video_refresh(); + video_blit(); + } else if (status.flags & SOFTWARE_MOUSE_MOVED) { + video_blit(); + status.flags &= ~(SOFTWARE_MOUSE_MOVED); + } } static void _synthetic_paste(const char *cbptr) { - struct key_event kk; - int isy = 2; - kk.mouse = 0; - for (; cbptr && *cbptr; cbptr++) { - /* Win32 will have \r\n, everyone else \n */ - if (*cbptr == '\r') continue; - /* simulate paste */ - kk.scancode = -1; - kk.sym = kk.orig_sym = 0; - if (*cbptr == '\n') { - /* special attention to newlines */ - kk.unicode = '\r'; - kk.sym = SDLK_RETURN; - } else { - kk.unicode = *cbptr; - } - kk.mod = 0; - kk.is_repeat = 0; - if (cbptr[1]) - kk.is_synthetic = isy; - else - kk.is_synthetic = 3; - kk.state = 0; - handle_key(&kk); - kk.state = 1; - handle_key(&kk); - isy = 1; - } + struct key_event kk; + int isy = 2; + kk.mouse = MOUSE_NONE; + for (; cbptr && *cbptr; cbptr++) { + /* Win32 will have \r\n, everyone else \n */ + if (*cbptr == '\r') continue; + /* simulate paste */ + kk.scancode = -1; + kk.sym = kk.orig_sym = 0; + if (*cbptr == '\n') { + /* special attention to newlines */ + kk.unicode = '\r'; + kk.sym = SDLK_RETURN; + } else { + kk.unicode = *cbptr; + } + kk.mod = 0; + kk.is_repeat = 0; + if (cbptr[1]) + kk.is_synthetic = isy; + else + kk.is_synthetic = 3; + kk.state = KEY_PRESS; + handle_key(&kk); + kk.state = KEY_RELEASE; + handle_key(&kk); + isy = 1; + } } static void _do_clipboard_paste_op(SDL_Event *e) { - if (ACTIVE_PAGE.clipboard_paste - && ACTIVE_PAGE.clipboard_paste(e->user.code, - e->user.data1)) return; - if (ACTIVE_WIDGET.clipboard_paste - && ACTIVE_WIDGET.clipboard_paste(e->user.code, - e->user.data1)) return; - _synthetic_paste((const char *)e->user.data1); + if (ACTIVE_PAGE.clipboard_paste + && ACTIVE_PAGE.clipboard_paste(e->user.code, + e->user.data1)) return; + if (ACTIVE_WIDGET.clipboard_paste + && ACTIVE_WIDGET.clipboard_paste(e->user.code, + e->user.data1)) return; + _synthetic_paste((const char *)e->user.data1); } static void event_loop(void) NORETURN; static void event_loop(void) { - SDL_Event event; - unsigned int lx = 0, ly = 0; /* last x and y position (character) */ - uint32_t last_mouse_down, ticker; - SDLKey last_key = 0; - int modkey; - time_t startdown; + SDL_Event event; + unsigned int lx = 0, ly = 0; /* last x and y position (character) */ + uint32_t last_mouse_down, ticker; + SDLKey last_key = 0; + int modkey; + time_t startdown; #ifdef USE_X11 - time_t last_ss; + time_t last_ss; #endif - int downtrip; - int sawrep; - char *debug_s; - int fix_numlock_key; + int downtrip; + int sawrep; + char *debug_s; + int fix_numlock_key; - fix_numlock_key = status.fix_numlock_setting; + fix_numlock_key = status.fix_numlock_setting; - debug_s = getenv("SCHISM_DEBUG"); + debug_s = getenv("SCHISM_DEBUG"); - downtrip = 0; - last_mouse_down = 0; - startdown = 0; - status.last_keysym = 0; + downtrip = 0; + last_mouse_down = 0; + startdown = 0; + status.last_keysym = 0; - modkey = SDL_GetModState(); + modkey = SDL_GetModState(); #if defined(WIN32) - win32_get_modkey(&modkey); + win32_get_modkey(&modkey); #endif - SDL_SetModState(modkey); + SDL_SetModState(modkey); #ifdef USE_X11 - time(&last_ss); + time(&last_ss); #endif - time(&status.now); - localtime_r(&status.now, &status.tmnow); - while (SDL_WaitEvent(&event)) { - struct key_event kk = { - .midi_volume = -1, - .midi_note = -1, - // X/Y resolution - .rx = NATIVE_SCREEN_WIDTH / 80, - .ry = NATIVE_SCREEN_HEIGHT / 50, - // everything else will be set to 0 - }; - - if (!os_sdlevent(&event)) - continue; - sawrep = 0; - if (event.type == SDL_KEYDOWN || event.type == SDL_MOUSEBUTTONDOWN) { - kk.state = 0; - } else if (event.type == SDL_KEYUP || event.type == SDL_MOUSEBUTTONUP) { - kk.state = 1; - } - if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { - if (event.key.keysym.sym == 0) { - // XXX when does this happen? - kk.mouse = 0; - kk.unicode = 0; - kk.is_repeat = 0; - } - } - switch (event.type) { - case SDL_SYSWMEVENT: - /* todo... */ - break; - case SDL_VIDEORESIZE: - video_resize(event.resize.w, event.resize.h); - /* fall through */ - case SDL_VIDEOEXPOSE: - status.flags |= (NEED_UPDATE); - break; + time(&status.now); + localtime_r(&status.now, &status.tmnow); + while (SDL_WaitEvent(&event)) { + struct key_event kk = { + .midi_volume = -1, + .midi_note = -1, + // X/Y resolution + .rx = NATIVE_SCREEN_WIDTH / 80, + .ry = NATIVE_SCREEN_HEIGHT / 50, + // everything else will be set to 0 + }; + + if (!os_sdlevent(&event)) + continue; + sawrep = 0; + if (event.type == SDL_KEYDOWN || event.type == SDL_MOUSEBUTTONDOWN) { + kk.state = KEY_PRESS; + } else if (event.type == SDL_KEYUP || event.type == SDL_MOUSEBUTTONUP) { + kk.state = KEY_RELEASE; + } + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { + if (event.key.keysym.sym == 0) { + // XXX when does this happen? + kk.mouse = MOUSE_NONE; + kk.unicode = 0; + kk.is_repeat = 0; + } + } + switch (event.type) { + case SDL_SYSWMEVENT: + /* todo... */ + break; + case SDL_VIDEORESIZE: + video_resize(event.resize.w, event.resize.h); + /* fall through */ + case SDL_VIDEOEXPOSE: + status.flags |= (NEED_UPDATE); + break; #if defined(WIN32) #define _ALTTRACKED_KMOD (KMOD_NUM|KMOD_CAPS) #else #define _ALTTRACKED_KMOD 0 #endif - case SDL_KEYUP: - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case SDLK_NUMLOCK: - modkey ^= KMOD_NUM; - break; - case SDLK_CAPSLOCK: - if (event.type == SDL_KEYDOWN) { - status.flags |= CAPS_PRESSED; - } else { - status.flags &= ~CAPS_PRESSED; - } - modkey ^= KMOD_CAPS; - break; - case SDLK_LSHIFT: case SDLK_RSHIFT: - if (event.type == SDL_KEYDOWN) - status.flags |= SHIFT_KEY_DOWN; - else - status.flags &= ~SHIFT_KEY_DOWN; - break; - default: - break; - }; - - if (!kk.state) { - modkey = (event.key.keysym.mod - & ~(_ALTTRACKED_KMOD)) - | (modkey & _ALTTRACKED_KMOD); - } + case SDL_KEYUP: + case SDL_KEYDOWN: + switch (event.key.keysym.sym) { + case SDLK_NUMLOCK: + modkey ^= KMOD_NUM; + break; + case SDLK_CAPSLOCK: + if (event.type == SDL_KEYDOWN) { + status.flags |= CAPS_PRESSED; + } else { + status.flags &= ~CAPS_PRESSED; + } + modkey ^= KMOD_CAPS; + break; + case SDLK_LSHIFT: case SDLK_RSHIFT: + if (event.type == SDL_KEYDOWN) + status.flags |= SHIFT_KEY_DOWN; + else + status.flags &= ~SHIFT_KEY_DOWN; + break; + default: + break; + }; + + if (kk.state == KEY_PRESS) { + modkey = (event.key.keysym.mod + & ~(_ALTTRACKED_KMOD)) + | (modkey & _ALTTRACKED_KMOD); + } #if defined(WIN32) - win32_get_modkey(&modkey); + win32_get_modkey(&modkey); #endif - kk.sym = event.key.keysym.sym; - kk.scancode = event.key.keysym.scancode; + kk.sym = event.key.keysym.sym; + kk.scancode = event.key.keysym.scancode; - switch (fix_numlock_key) { - case NUMLOCK_GUESS: + switch (fix_numlock_key) { + case NUMLOCK_GUESS: #ifdef MACOSX - // FIXME can this be moved to macosx_sdlevent? - if (ibook_helper != -1) { - if (ACTIVE_PAGE.selected_widget > -1 - && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets - && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) { - /* text is more likely? */ - modkey |= KMOD_NUM; - } else { - modkey &= ~KMOD_NUM; - } - } /* otherwise honor it */ -#endif - break; - case NUMLOCK_ALWAYS_OFF: - modkey &= ~KMOD_NUM; - break; - case NUMLOCK_ALWAYS_ON: - modkey |= KMOD_NUM; - break; - }; - - kk.mod = modkey; - kk.unicode = event.key.keysym.unicode; - kk.mouse = 0; - if (debug_s && strstr(debug_s, "key")) { - log_appendf(12, "[DEBUG] Key%s sym=%d scancode=%d", - (event.type == SDL_KEYDOWN) ? "Down" : "Up", - (int)event.key.keysym.sym, - (int)event.key.keysym.scancode); - } - key_translate(&kk); - if (debug_s && strstr(debug_s, "translate") - && kk.orig_sym != kk.sym) { - log_appendf(12, "[DEBUG] Translate Key%s sym=%d scancode=%d -> %d (%c)", - (event.type == SDL_KEYDOWN) ? "Down" : "Up", - (int)event.key.keysym.sym, - (int)event.key.keysym.scancode, - kk.sym, kk.unicode); - } - if (event.type == SDL_KEYDOWN && last_key == kk.sym) { - sawrep = kk.is_repeat = 1; - } else { - kk.is_repeat = 0; - } - handle_key(&kk); - if (event.type == SDL_KEYUP) { - status.last_keysym = kk.sym; - last_key = 0; - } else { - status.last_keysym = 0; - last_key = kk.sym; - } - break; - case SDL_QUIT: - show_exit_prompt(); - break; - case SDL_ACTIVEEVENT: - /* reset this... */ - modkey = SDL_GetModState(); + // FIXME can this be moved to macosx_sdlevent? + if (ibook_helper != -1) { + if (ACTIVE_PAGE.selected_widget > -1 + && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets + && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) { + /* text is more likely? */ + modkey |= KMOD_NUM; + } else { + modkey &= ~KMOD_NUM; + } + } /* otherwise honor it */ +#endif + break; + case NUMLOCK_ALWAYS_OFF: + modkey &= ~KMOD_NUM; + break; + case NUMLOCK_ALWAYS_ON: + modkey |= KMOD_NUM; + break; + }; + + kk.mod = modkey; + kk.unicode = event.key.keysym.unicode; + kk.mouse = MOUSE_NONE; + if (debug_s && strstr(debug_s, "key")) { + log_appendf(12, "[DEBUG] Key%s sym=%d scancode=%d", + (event.type == SDL_KEYDOWN) ? "Down" : "Up", + (int)event.key.keysym.sym, + (int)event.key.keysym.scancode); + } + key_translate(&kk); + if (debug_s && strstr(debug_s, "translate") + && kk.orig_sym != kk.sym) { + log_appendf(12, "[DEBUG] Translate Key%s sym=%d scancode=%d -> %d (%c)", + (event.type == SDL_KEYDOWN) ? "Down" : "Up", + (int)event.key.keysym.sym, + (int)event.key.keysym.scancode, + kk.sym, kk.unicode); + } + if (event.type == SDL_KEYDOWN && last_key == kk.sym) { + sawrep = kk.is_repeat = 1; + } else { + kk.is_repeat = 0; + } + handle_key(&kk); + if (event.type == SDL_KEYUP) { + status.last_keysym = kk.sym; + last_key = 0; + } else { + status.last_keysym = 0; + last_key = kk.sym; + } + break; + case SDL_QUIT: + show_exit_prompt(); + break; + case SDL_ACTIVEEVENT: + /* reset this... */ + modkey = SDL_GetModState(); #if defined(WIN32) - win32_get_modkey(&modkey); + win32_get_modkey(&modkey); #endif - SDL_SetModState(modkey); + SDL_SetModState(modkey); - handle_active_event(&(event.active)); - break; - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - if (!kk.state) { - modkey = event.key.keysym.mod; + handle_active_event(&(event.active)); + break; + case SDL_MOUSEMOTION: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (kk.state == KEY_PRESS) { + modkey = event.key.keysym.mod; #if defined(WIN32) - win32_get_modkey(&modkey); + win32_get_modkey(&modkey); #endif - } + } - kk.sym = 0; - kk.mod = 0; - kk.unicode = 0; - - video_translate(event.button.x, event.button.y, &kk.fx, &kk.fy); - - /* character resolution */ - kk.x = kk.fx / kk.rx; - /* half-character selection */ - if ((kk.fx / (kk.rx/2)) % 2 == 0) { - kk.hx = 0; - } else { - kk.hx = 1; - } - kk.y = kk.fy / kk.ry; - if (event.type == SDL_MOUSEBUTTONDOWN) { - kk.sx = kk.x; - kk.sy = kk.y; - } - if (startdown) startdown = 0; - if (event.type != SDL_MOUSEMOTION && debug_s && strstr(debug_s, "mouse")) { - log_appendf(12, "[DEBUG] Mouse%s button=%d x=%d y=%d", - (event.type == SDL_MOUSEBUTTONDOWN) ? "Down" : "Up", - (int)event.button.button, - (int)event.button.x, - (int)event.button.y); - } + kk.sym = 0; + kk.mod = 0; + kk.unicode = 0; + + video_translate(event.button.x, event.button.y, &kk.fx, &kk.fy); + + /* character resolution */ + kk.x = kk.fx / kk.rx; + /* half-character selection */ + if ((kk.fx / (kk.rx/2)) % 2 == 0) { + kk.hx = 0; + } else { + kk.hx = 1; + } + kk.y = kk.fy / kk.ry; + if (event.type == SDL_MOUSEBUTTONDOWN) { + kk.sx = kk.x; + kk.sy = kk.y; + } + if (startdown) startdown = 0; + if (event.type != SDL_MOUSEMOTION && debug_s && strstr(debug_s, "mouse")) { + log_appendf(12, "[DEBUG] Mouse%s button=%d x=%d y=%d", + (event.type == SDL_MOUSEBUTTONDOWN) ? "Down" : "Up", + (int)event.button.button, + (int)event.button.x, + (int)event.button.y); + } - switch (event.button.button) { + switch (event.button.button) { /* Why only one of these would be defined I have no clue. Also why these would not be defined, I'm not sure either, but hey. */ #if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN) - case SDL_BUTTON_WHEELUP: - kk.mouse = MOUSE_SCROLL_UP; - handle_key(&kk); - break; - case SDL_BUTTON_WHEELDOWN: - kk.mouse = MOUSE_SCROLL_DOWN; - handle_key(&kk); - break; -#endif - - case SDL_BUTTON_RIGHT: - case SDL_BUTTON_MIDDLE: - case SDL_BUTTON_LEFT: - if ((modkey & KMOD_CTRL) - || event.button.button == SDL_BUTTON_RIGHT) { - kk.mouse_button = MOUSE_BUTTON_RIGHT; - } else if ((modkey & (KMOD_ALT|KMOD_META)) - || event.button.button == SDL_BUTTON_MIDDLE) { - kk.mouse_button = MOUSE_BUTTON_MIDDLE; - } else { - kk.mouse_button = MOUSE_BUTTON_LEFT; - } - if (kk.state) { - ticker = SDL_GetTicks(); - if (lx == kk.x - && ly == kk.y - && (ticker - last_mouse_down) < 300) { - last_mouse_down = 0; - kk.mouse = MOUSE_DBLCLICK; - } else { - last_mouse_down = ticker; - kk.mouse = MOUSE_CLICK; - } - lx = kk.x; - ly = kk.y; - } else { - kk.mouse = MOUSE_CLICK; - } - if (status.dialog_type == DIALOG_NONE) { - if (kk.y <= 9 && status.current_page != PAGE_FONT_EDIT) { - if (kk.state && kk.mouse_button == MOUSE_BUTTON_RIGHT) { - menu_show(); - break; - } else if (!kk.state && kk.mouse_button == MOUSE_BUTTON_LEFT) { - time(&startdown); - } - } - - if (change_focus_to_xy(kk.x, kk.y)) { - kk.on_target = 1; - } else { - kk.on_target = 0; - } - } - if (event.type == SDL_MOUSEBUTTONUP && downtrip) { - downtrip = 0; - break; - } - handle_key(&kk); - break; - }; - break; - default: - if (event.type == SCHISM_EVENT_MIDI) { - midi_engine_handle_event(&event); - } else if (event.type == SCHISM_EVENT_UPDATE_IPMIDI) { - status.flags |= (NEED_UPDATE); - midi_engine_poll_ports(); - } else if (event.type == SCHISM_EVENT_PLAYBACK) { - /* this is the sound thread */ - midi_send_flush(); - if (!(status.flags & (DISKWRITER_ACTIVE|DISKWRITER_ACTIVE_PATTERN))) { - playback_update(); - } - } else if (event.type == SCHISM_EVENT_PASTE) { - /* handle clipboard events */ - _do_clipboard_paste_op(&event); - free(event.user.data1); - } else if (event.type == SCHISM_EVENT_NATIVE) { - /* used by native system scripting */ - switch (event.user.code) { - case SCHISM_EVENT_NATIVE_OPEN: /* open song */ - song_load(event.user.data1); - break; - case SCHISM_EVENT_NATIVE_SCRIPT: - /* TODO: hash the string's value and do a switch() on it */ - if (strcasecmp(event.user.data1, "new") == 0) { - new_song_dialog(); - } else if (strcasecmp(event.user.data1, "save") == 0) { - save_song_or_save_as(); - } else if (strcasecmp(event.user.data1, "save_as") == 0) { - set_page(PAGE_SAVE_MODULE); - } else if (strcasecmp(event.user.data1, "export_song") == 0) { - set_page(PAGE_EXPORT_MODULE); - } else if (strcasecmp(event.user.data1, "logviewer") == 0) { - set_page(PAGE_LOG); - } else if (strcasecmp(event.user.data1, "font_editor") == 0) { - set_page(PAGE_FONT_EDIT); - } else if (strcasecmp(event.user.data1, "load") == 0) { - set_page(PAGE_LOAD_MODULE); - } else if (strcasecmp(event.user.data1, "help") == 0) { - set_page(PAGE_HELP); - } else if (strcasecmp(event.user.data1, "pattern") == 0) { - set_page(PAGE_PATTERN_EDITOR); - } else if (strcasecmp(event.user.data1, "orders") == 0) { - set_page(PAGE_ORDERLIST_PANNING); - } else if (strcasecmp(event.user.data1, "variables") == 0) { - set_page(PAGE_SONG_VARIABLES); - } else if (strcasecmp(event.user.data1, "message_edit") == 0) { - set_page(PAGE_MESSAGE); - } else if (strcasecmp(event.user.data1, "info") == 0) { - set_page(PAGE_INFO); - } else if (strcasecmp(event.user.data1, "play") == 0) { - song_start(); - } else if (strcasecmp(event.user.data1, "play_pattern") == 0) { - song_loop_pattern(get_current_pattern(), 0); - } else if (strcasecmp(event.user.data1, "play_order") == 0) { - song_start_at_order(get_current_order(), 0); - } else if (strcasecmp(event.user.data1, "play_mark") == 0) { - play_song_from_mark(); - } else if (strcasecmp(event.user.data1, "stop") == 0) { - song_stop(); - } else if (strcasecmp(event.user.data1, "calc_length") == 0) { - show_song_length(); - } else if (strcasecmp(event.user.data1, "sample_page") == 0) { - set_page(PAGE_SAMPLE_LIST); - } else if (strcasecmp(event.user.data1, "sample_library") == 0) { - set_page(PAGE_LIBRARY_SAMPLE); - } else if (strcasecmp(event.user.data1, "init_sound") == 0) { - /* does nothing :) */ - } else if (strcasecmp(event.user.data1, "inst_page") == 0) { - set_page(PAGE_INSTRUMENT_LIST); - } else if (strcasecmp(event.user.data1, "inst_library") == 0) { - set_page(PAGE_LIBRARY_INSTRUMENT); - } else if (strcasecmp(event.user.data1, "preferences") == 0) { - set_page(PAGE_PREFERENCES); - } else if (strcasecmp(event.user.data1, "system_config") == 0) { - set_page(PAGE_CONFIG); - } else if (strcasecmp(event.user.data1, "midi_config") == 0) { - set_page(PAGE_MIDI); - } else if (strcasecmp(event.user.data1, "palette_page") == 0) { - set_page(PAGE_PALETTE_EDITOR); - } else if (strcasecmp(event.user.data1, "fullscreen") == 0) { - toggle_display_fullscreen(); - } - }; - } else { - printf("received unknown event %x\n", event.type); - } - break; - } - if (sawrep || !SDL_PollEvent(NULL)) { - time(&status.now); - localtime_r(&status.now, &status.tmnow); - - if (status.dialog_type == DIALOG_NONE - && startdown && (status.now - startdown) > 1) { - menu_show(); - startdown = 0; - downtrip = 1; - } - if (status.flags & (CLIPPY_PASTE_SELECTION|CLIPPY_PASTE_BUFFER)) { - clippy_paste((status.flags & CLIPPY_PASTE_BUFFER) - ? CLIPPY_BUFFER : CLIPPY_SELECT); - status.flags &= ~(CLIPPY_PASTE_BUFFER|CLIPPY_PASTE_SELECTION); - } - - check_update(); - - switch (song_get_mode()) { - case MODE_PLAYING: - case MODE_PATTERN_LOOP: + case SDL_BUTTON_WHEELUP: + kk.mouse = MOUSE_SCROLL_UP; + handle_key(&kk); + break; + case SDL_BUTTON_WHEELDOWN: + kk.mouse = MOUSE_SCROLL_DOWN; + handle_key(&kk); + break; +#endif + + case SDL_BUTTON_RIGHT: + case SDL_BUTTON_MIDDLE: + case SDL_BUTTON_LEFT: + if ((modkey & KMOD_CTRL) + || event.button.button == SDL_BUTTON_RIGHT) { + kk.mouse_button = MOUSE_BUTTON_RIGHT; + } else if ((modkey & (KMOD_ALT|KMOD_META)) + || event.button.button == SDL_BUTTON_MIDDLE) { + kk.mouse_button = MOUSE_BUTTON_MIDDLE; + } else { + kk.mouse_button = MOUSE_BUTTON_LEFT; + } + if (kk.state == KEY_RELEASE) { + ticker = SDL_GetTicks(); + if (lx == kk.x + && ly == kk.y + && (ticker - last_mouse_down) < 300) { + last_mouse_down = 0; + kk.mouse = MOUSE_DBLCLICK; + } else { + last_mouse_down = ticker; + kk.mouse = MOUSE_CLICK; + } + lx = kk.x; + ly = kk.y; + } else { + kk.mouse = MOUSE_CLICK; + } + if (status.dialog_type == DIALOG_NONE) { + if (kk.y <= 9 && status.current_page != PAGE_FONT_EDIT) { + if (kk.state == KEY_RELEASE && kk.mouse_button == MOUSE_BUTTON_RIGHT) { + menu_show(); + break; + } else if (kk.state == KEY_PRESS && kk.mouse_button == MOUSE_BUTTON_LEFT) { + time(&startdown); + } + } + } + if (change_focus_to_xy(kk.x, kk.y)) { + kk.on_target = 1; + } else { + kk.on_target = 0; + } + if (event.type == SDL_MOUSEBUTTONUP && downtrip) { + downtrip = 0; + break; + } + handle_key(&kk); + break; + }; + break; + default: + if (event.type == SCHISM_EVENT_MIDI) { + midi_engine_handle_event(&event); + } else if (event.type == SCHISM_EVENT_UPDATE_IPMIDI) { + status.flags |= (NEED_UPDATE); + midi_engine_poll_ports(); + } else if (event.type == SCHISM_EVENT_PLAYBACK) { + /* this is the sound thread */ + midi_send_flush(); + if (!(status.flags & (DISKWRITER_ACTIVE|DISKWRITER_ACTIVE_PATTERN))) { + playback_update(); + } + } else if (event.type == SCHISM_EVENT_PASTE) { + /* handle clipboard events */ + _do_clipboard_paste_op(&event); + free(event.user.data1); + } else if (event.type == SCHISM_EVENT_NATIVE) { + /* used by native system scripting */ + switch (event.user.code) { + case SCHISM_EVENT_NATIVE_OPEN: /* open song */ + song_load(event.user.data1); + break; + case SCHISM_EVENT_NATIVE_SCRIPT: + /* TODO: hash the string's value and do a switch() on it */ + if (strcasecmp(event.user.data1, "new") == 0) { + new_song_dialog(); + } else if (strcasecmp(event.user.data1, "save") == 0) { + save_song_or_save_as(); + } else if (strcasecmp(event.user.data1, "save_as") == 0) { + set_page(PAGE_SAVE_MODULE); + } else if (strcasecmp(event.user.data1, "export_song") == 0) { + set_page(PAGE_EXPORT_MODULE); + } else if (strcasecmp(event.user.data1, "logviewer") == 0) { + set_page(PAGE_LOG); + } else if (strcasecmp(event.user.data1, "font_editor") == 0) { + set_page(PAGE_FONT_EDIT); + } else if (strcasecmp(event.user.data1, "load") == 0) { + set_page(PAGE_LOAD_MODULE); + } else if (strcasecmp(event.user.data1, "help") == 0) { + set_page(PAGE_HELP); + } else if (strcasecmp(event.user.data1, "pattern") == 0) { + set_page(PAGE_PATTERN_EDITOR); + } else if (strcasecmp(event.user.data1, "orders") == 0) { + set_page(PAGE_ORDERLIST_PANNING); + } else if (strcasecmp(event.user.data1, "variables") == 0) { + set_page(PAGE_SONG_VARIABLES); + } else if (strcasecmp(event.user.data1, "message_edit") == 0) { + set_page(PAGE_MESSAGE); + } else if (strcasecmp(event.user.data1, "info") == 0) { + set_page(PAGE_INFO); + } else if (strcasecmp(event.user.data1, "play") == 0) { + song_start(); + } else if (strcasecmp(event.user.data1, "play_pattern") == 0) { + song_loop_pattern(get_current_pattern(), 0); + } else if (strcasecmp(event.user.data1, "play_order") == 0) { + song_start_at_order(get_current_order(), 0); + } else if (strcasecmp(event.user.data1, "play_mark") == 0) { + play_song_from_mark(); + } else if (strcasecmp(event.user.data1, "stop") == 0) { + song_stop(); + } else if (strcasecmp(event.user.data1, "calc_length") == 0) { + show_song_length(); + } else if (strcasecmp(event.user.data1, "sample_page") == 0) { + set_page(PAGE_SAMPLE_LIST); + } else if (strcasecmp(event.user.data1, "sample_library") == 0) { + set_page(PAGE_LIBRARY_SAMPLE); + } else if (strcasecmp(event.user.data1, "init_sound") == 0) { + /* does nothing :) */ + } else if (strcasecmp(event.user.data1, "inst_page") == 0) { + set_page(PAGE_INSTRUMENT_LIST); + } else if (strcasecmp(event.user.data1, "inst_library") == 0) { + set_page(PAGE_LIBRARY_INSTRUMENT); + } else if (strcasecmp(event.user.data1, "preferences") == 0) { + set_page(PAGE_PREFERENCES); + } else if (strcasecmp(event.user.data1, "system_config") == 0) { + set_page(PAGE_CONFIG); + } else if (strcasecmp(event.user.data1, "midi_config") == 0) { + set_page(PAGE_MIDI); + } else if (strcasecmp(event.user.data1, "palette_page") == 0) { + set_page(PAGE_PALETTE_EDITOR); + } else if (strcasecmp(event.user.data1, "fullscreen") == 0) { + toggle_display_fullscreen(); + } + }; + } else { + printf("received unknown event %x\n", event.type); + } + break; + } + if (sawrep || !SDL_PollEvent(NULL)) { + time(&status.now); + localtime_r(&status.now, &status.tmnow); + + if (status.dialog_type == DIALOG_NONE + && startdown && (status.now - startdown) > 1) { + menu_show(); + startdown = 0; + downtrip = 1; + } + if (status.flags & (CLIPPY_PASTE_SELECTION|CLIPPY_PASTE_BUFFER)) { + clippy_paste((status.flags & CLIPPY_PASTE_BUFFER) + ? CLIPPY_BUFFER : CLIPPY_SELECT); + status.flags &= ~(CLIPPY_PASTE_BUFFER|CLIPPY_PASTE_SELECTION); + } + + check_update(); + + switch (song_get_mode()) { + case MODE_PLAYING: + case MODE_PATTERN_LOOP: #ifdef os_screensaver_deactivate - if ((status.now-last_ss) > 14) { - last_ss=status.now; - os_screensaver_deactivate(); - } -#endif - break; - default: - break; - }; - - if (status.flags & DISKWRITER_ACTIVE) { - int q = disko_sync(); - while (q == DW_SYNC_MORE && !SDL_PollEvent(NULL)) { - check_update(); - q = disko_sync(); - } - if (q == DW_SYNC_DONE) { + if ((status.now-last_ss) > 14) { + last_ss=status.now; + os_screensaver_deactivate(); + } +#endif + break; + default: + break; + }; + + if (status.flags & DISKWRITER_ACTIVE) { + int q = disko_sync(); + while (q == DW_SYNC_MORE && !SDL_PollEvent(NULL)) { + check_update(); + q = disko_sync(); + } + if (q == DW_SYNC_DONE) { #ifdef ENABLE_HOOKS - run_disko_complete_hook(); + run_disko_complete_hook(); #endif - if (diskwrite_to) { - printf("Diskwrite complete, exiting...\n"); - exit(0); - } - } - } - - /* let dmoz build directory lists, etc - as long as there's no user-event going on... - */ - while (!(status.flags & NEED_UPDATE) && dmoz_worker() && !SDL_PollEvent(NULL)) - /* nothing */; - } - } - exit(0); /* atexit :) */ + if (diskwrite_to) { + printf("Diskwrite complete, exiting...\n"); + exit(0); + } + } + } + + /* let dmoz build directory lists, etc + as long as there's no user-event going on... + */ + while (!(status.flags & NEED_UPDATE) && dmoz_worker() && !SDL_PollEvent(NULL)) + /* nothing */; + } + } + exit(0); /* atexit :) */ } static void schism_shutdown(void) { #if ENABLE_HOOKS - if (shutdown_process & EXIT_HOOK) - run_exit_hook(); + if (shutdown_process & EXIT_HOOK) + run_exit_hook(); #endif - if (shutdown_process & EXIT_SAVECFG) - cfg_atexit_save(); + if (shutdown_process & EXIT_SAVECFG) + cfg_atexit_save(); #ifdef MACOSX - if (ibook_helper != -1) - macosx_ibook_fnswitch(ibook_helper); + if (ibook_helper != -1) + macosx_ibook_fnswitch(ibook_helper); #endif - if (shutdown_process & EXIT_SDLQUIT) { - song_lock_audio(); - song_stop_unlocked(1); - song_unlock_audio(); - - // Clear to black on exit (nicer on Wii; I suppose it won't hurt elsewhere) - video_refresh(); - video_blit(); - video_shutdown(); - /* - If this is the atexit() handler, why are we calling SDL_Quit? - - Simple, SDL's documentation says always call SDL_Quit. :) In - fact, in the examples they recommend writing atexit(SDL_Quit) - directly after SDL_Init. I'm not sure exactly why, but I don't - see a reason *not* to do it... - / Storlek - */ - SDL_Quit(); - } - os_sysexit(); + if (shutdown_process & EXIT_SDLQUIT) { + song_lock_audio(); + song_stop_unlocked(1); + song_unlock_audio(); + + // Clear to black on exit (nicer on Wii; I suppose it won't hurt elsewhere) + video_refresh(); + video_blit(); + video_shutdown(); + /* + If this is the atexit() handler, why are we calling SDL_Quit? + + Simple, SDL's documentation says always call SDL_Quit. :) In + fact, in the examples they recommend writing atexit(SDL_Quit) + directly after SDL_Init. I'm not sure exactly why, but I don't + see a reason *not* to do it... + / Storlek + */ + SDL_Quit(); + } + os_sysexit(); } extern void vis_init(void); int main(int argc, char **argv) { - os_sysinit(&argc, &argv); + os_sysinit(&argc, &argv); - /* this needs to be done very early, because the version is used in the help text etc. - Also, this needs to happen before any locale stuff is initialized - (but we don't do that at all yet, anyway) */ - ver_init(); + /* this needs to be done very early, because the version is used in the help text etc. + Also, this needs to happen before any locale stuff is initialized + (but we don't do that at all yet, anyway) */ + ver_init(); - /* FIXME: make a config option for this, and stop abusing frickin' environment variables! */ - put_env_var("SCHISM_VIDEO_ASPECT", "full"); + /* FIXME: make a config option for this, and stop abusing frickin' environment variables! */ + put_env_var("SCHISM_VIDEO_ASPECT", "full"); - vis_init(); - atexit(schism_shutdown); + vis_init(); + atexit(schism_shutdown); - video_fullscreen(0); + video_fullscreen(0); - tzset(); // localtime_r wants this - srand(time(NULL)); - parse_options(argc, argv); /* shouldn't this be like, first? */ + tzset(); // localtime_r wants this + srand(time(NULL)); + parse_options(argc, argv); /* shouldn't this be like, first? */ #ifdef USE_DLTRICK_ALSA - alsa_dlinit(); + alsa_dlinit(); #endif - cfg_init_dir(); + cfg_init_dir(); #if ENABLE_HOOKS - if (startup_flags & SF_HOOKS) { - run_startup_hook(); - shutdown_process |= EXIT_HOOK; - } + if (startup_flags & SF_HOOKS) { + run_startup_hook(); + shutdown_process |= EXIT_HOOK; + } #endif #ifdef MACOSX - ibook_helper = macosx_ibook_fnswitch(1); + ibook_helper = macosx_ibook_fnswitch(1); #endif - /* Eh. */ - log_append2(0, 3, 0, schism_banner(0)); - log_nl(); - log_nl(); - - song_initialise(); - cfg_load(); - - if (did_classic) { - status.flags &= ~CLASSIC_MODE; - if (startup_flags & SF_CLASSIC) status.flags |= CLASSIC_MODE; - } - - if (!video_driver) { - video_driver = cfg_video_driver; - if (!video_driver || !*video_driver) video_driver = NULL; - } - if (!did_fullscreen) { - video_fullscreen(cfg_video_fullscreen); - } - - if (!(startup_flags & SF_NETWORK)) { - status.flags |= NO_NETWORK; - } - - shutdown_process |= EXIT_SAVECFG; - - sdl_init(); - shutdown_process |= EXIT_SDLQUIT; - os_sdlinit(); - - video_setup(video_driver); - display_init(); - palette_apply(); - font_init(); - midi_engine_start(); - log_nl(); - audio_init(audio_driver); - song_init_modplug(); + /* Eh. */ + log_append2(0, 3, 0, schism_banner(0)); + log_nl(); + log_nl(); + + song_initialise(); + cfg_load(); + + if (did_classic) { + status.flags &= ~CLASSIC_MODE; + if (startup_flags & SF_CLASSIC) status.flags |= CLASSIC_MODE; + } + + if (!video_driver) { + video_driver = cfg_video_driver; + if (!video_driver || !*video_driver) video_driver = NULL; + } + if (!did_fullscreen) { + video_fullscreen(cfg_video_fullscreen); + } + + if (!(startup_flags & SF_NETWORK)) { + status.flags |= NO_NETWORK; + } + + shutdown_process |= EXIT_SAVECFG; + + sdl_init(); + shutdown_process |= EXIT_SDLQUIT; + os_sdlinit(); + + video_setup(video_driver); + display_init(); + palette_apply(); + font_init(); + midi_engine_start(); + log_nl(); + audio_init(audio_driver); + song_init_modplug(); #ifndef WIN32 - signal(SIGINT, exit); - signal(SIGQUIT, exit); - signal(SIGTERM, exit); -#endif - - video_mousecursor(cfg_video_mousecursor); - status_text_flash(" "); /* silence the mouse cursor message */ - - volume_setup(); - - load_pages(); - main_song_changed_cb(); - - if (initial_song && !initial_dir) { - initial_dir = get_parent_directory(initial_song); - if (!initial_dir) { - initial_dir = get_current_directory(); - } - } - if (initial_dir) { - strncpy(cfg_dir_modules, initial_dir, PATH_MAX); - cfg_dir_modules[PATH_MAX] = 0; - strncpy(cfg_dir_samples, initial_dir, PATH_MAX); - cfg_dir_samples[PATH_MAX] = 0; - strncpy(cfg_dir_instruments, initial_dir, PATH_MAX); - cfg_dir_instruments[PATH_MAX] = 0; - free(initial_dir); - } - - if (startup_flags & SF_FONTEDIT) { - status.flags |= STARTUP_FONTEDIT; - set_page(PAGE_FONT_EDIT); - free(initial_song); - } else if (initial_song) { - set_page(PAGE_LOG); - if (song_load_unchecked(initial_song)) { - if (diskwrite_to) { - // make a guess? - const char *multi = strcasestr(diskwrite_to, "%c"); - const char *driver = (strcasestr(diskwrite_to, ".aif") - ? (multi ? "MAIFF" : "AIFF") - : (multi ? "MWAV" : "WAV")); - if (song_export(diskwrite_to, driver) != SAVE_SUCCESS) - exit(1); // ? - } else if (startup_flags & SF_PLAY) { - song_start(); - set_page(PAGE_INFO); - } - } - free(initial_song); - } else { - set_page(PAGE_ABOUT); - } + signal(SIGINT, exit); + signal(SIGQUIT, exit); + signal(SIGTERM, exit); +#endif + + video_mousecursor(cfg_video_mousecursor); + status_text_flash(" "); /* silence the mouse cursor message */ + + volume_setup(); + + load_pages(); + main_song_changed_cb(); + + if (initial_song && !initial_dir) { + initial_dir = get_parent_directory(initial_song); + if (!initial_dir) { + initial_dir = get_current_directory(); + } + } + if (initial_dir) { + strncpy(cfg_dir_modules, initial_dir, PATH_MAX); + cfg_dir_modules[PATH_MAX] = 0; + strncpy(cfg_dir_samples, initial_dir, PATH_MAX); + cfg_dir_samples[PATH_MAX] = 0; + strncpy(cfg_dir_instruments, initial_dir, PATH_MAX); + cfg_dir_instruments[PATH_MAX] = 0; + free(initial_dir); + } + + if (startup_flags & SF_FONTEDIT) { + status.flags |= STARTUP_FONTEDIT; + set_page(PAGE_FONT_EDIT); + free(initial_song); + } else if (initial_song) { + set_page(PAGE_LOG); + if (song_load_unchecked(initial_song)) { + if (diskwrite_to) { + // make a guess? + const char *multi = strcasestr(diskwrite_to, "%c"); + const char *driver = (strcasestr(diskwrite_to, ".aif") + ? (multi ? "MAIFF" : "AIFF") + : (multi ? "MWAV" : "WAV")); + if (song_export(diskwrite_to, driver) != SAVE_SUCCESS) + exit(1); // ? + } else if (startup_flags & SF_PLAY) { + song_start(); + set_page(PAGE_INFO); + } + } + free(initial_song); + } else { + set_page(PAGE_ABOUT); + } #if HAVE_NICE - if (nice(1) == -1) { - } + if (nice(1) == -1) { + } #endif - /* poll once */ - midi_engine_poll_ports(); + /* poll once */ + midi_engine_poll_ports(); - event_loop(); - return 0; /* blah */ + event_loop(); + return 0; /* blah */ } diff -Nru schism-0+20110101/schism/menu.c schism-20160521/schism/menu.c --- schism-0+20110101/schism/menu.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/menu.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,10 +36,10 @@ * if a menu is not active. */ #ifndef NDEBUG # define ENSURE_MENU(q) do {\ - if ((status.dialog_type & DIALOG_MENU) == 0) {\ - fprintf(stderr, "%s called with no menu\n", __FUNCTION__);\ - q;\ - }\ + if ((status.dialog_type & DIALOG_MENU) == 0) {\ + fprintf(stderr, "%s called with no menu\n", __FUNCTION__);\ + q;\ + }\ } while(0) #else # define ENSURE_MENU(q) @@ -58,130 +58,130 @@ /* --------------------------------------------------------------------- */ struct menu { - unsigned int x, y, w; - const char *title; - int num_items; /* meh... */ - const char *items[14]; /* writing **items doesn't work here :( */ - int selected_item; /* the highlighted item */ - int active_item; /* "pressed" menu item, for submenus */ - void (*selected_cb) (void); /* triggered by return key */ + unsigned int x, y, w; + const char *title; + int num_items; /* meh... */ + const char *items[14]; /* writing **items doesn't work here :( */ + int selected_item; /* the highlighted item */ + int active_item; /* "pressed" menu item, for submenus */ + void (*selected_cb) (void); /* triggered by return key */ }; /* *INDENT-OFF* */ static struct menu main_menu = { - .x = 6, - .y = 11, - .w = 25, - .title = " Main Menu", - .num_items = 10, - .items = { - "File Menu...", - "Playback Menu...", - "View Patterns (F2)", - "Sample Menu...", - "Instrument Menu...", - "View Orders/Panning (F11)", - "View Variables (F12)", - "Message Editor (Shift-F9)", - "Settings Menu...", - "Help! (F1)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = main_menu_selected_cb, + .x = 6, + .y = 11, + .w = 25, + .title = " Main Menu", + .num_items = 10, + .items = { + "File Menu...", + "Playback Menu...", + "View Patterns (F2)", + "Sample Menu...", + "Instrument Menu...", + "View Orders/Panning (F11)", + "View Variables (F12)", + "Message Editor (Shift-F9)", + "Settings Menu...", + "Help! (F1)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = main_menu_selected_cb, }; static struct menu file_menu = { - .x = 25, - .y = 13, - .w = 22, - .title = "File Menu", - .num_items = 7, - .items = { - "Load... (F9)", - "New... (Ctrl-N)", - "Save Current (Ctrl-S)", - "Save As... (F10)", - "Export... (Shift-F10)", - "Message Log (Ctrl-F11)", - "Quit (Ctrl-Q)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = file_menu_selected_cb, + .x = 25, + .y = 13, + .w = 22, + .title = "File Menu", + .num_items = 7, + .items = { + "Load... (F9)", + "New... (Ctrl-N)", + "Save Current (Ctrl-S)", + "Save As... (F10)", + "Export... (Shift-F10)", + "Message Log (Ctrl-F11)", + "Quit (Ctrl-Q)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = file_menu_selected_cb, }; static struct menu playback_menu = { - .x = 25, - .y = 13, - .w = 27, - .title = " Playback Menu", - .num_items = 9, - .items = { - "Show Infopage (F5)", - "Play Song (Ctrl-F5)", - "Play Pattern (F6)", - "Play from Order (Shift-F6)", - "Play from Mark/Cursor (F7)", - "Stop (F8)", - "Reinit Soundcard (Ctrl-I)", - "Driver Screen (Shift-F5)", - "Calculate Length (Ctrl-P)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = playback_menu_selected_cb, + .x = 25, + .y = 13, + .w = 27, + .title = " Playback Menu", + .num_items = 9, + .items = { + "Show Infopage (F5)", + "Play Song (Ctrl-F5)", + "Play Pattern (F6)", + "Play from Order (Shift-F6)", + "Play from Mark/Cursor (F7)", + "Stop (F8)", + "Reinit Soundcard (Ctrl-I)", + "Driver Screen (Shift-F5)", + "Calculate Length (Ctrl-P)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = playback_menu_selected_cb, }; static struct menu sample_menu = { - .x = 25, - .y = 20, - .w = 25, - .title = "Sample Menu", - .num_items = 2, - .items = { - "Sample List (F3)", - "Sample Library (Ctrl-F3)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = sample_menu_selected_cb, + .x = 25, + .y = 20, + .w = 25, + .title = "Sample Menu", + .num_items = 2, + .items = { + "Sample List (F3)", + "Sample Library (Ctrl-F3)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = sample_menu_selected_cb, }; static struct menu instrument_menu = { - .x = 20, - .y = 23, - .w = 29, - .title = "Instrument Menu", - .num_items = 2, - .items = { - "Instrument List (F4)", - "Instrument Library (Ctrl-F4)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = instrument_menu_selected_cb, + .x = 20, + .y = 23, + .w = 29, + .title = "Instrument Menu", + .num_items = 2, + .items = { + "Instrument List (F4)", + "Instrument Library (Ctrl-F4)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = instrument_menu_selected_cb, }; static struct menu settings_menu = { - .x = 22, - .y = 25, - .w = 34, - .title = "Settings Menu", - /* num_items is fiddled with when the menu is loaded (if there's no window manager, - the toggle fullscreen item doesn't appear) */ - .num_items = 6, - .items = { - "Preferences (Shift-F5)", - "MIDI Configuration (Shift-F1)", - "System Configuration (Ctrl-F1)", - "Palette Editor (Ctrl-F12)", - "Font Editor (Shift-F12)", - "Toggle Fullscreen (Ctrl-Alt-Enter)", - }, - .selected_item = 0, - .active_item = -1, - .selected_cb = settings_menu_selected_cb, + .x = 22, + .y = 25, + .w = 34, + .title = "Settings Menu", + /* num_items is fiddled with when the menu is loaded (if there's no window manager, + the toggle fullscreen item doesn't appear) */ + .num_items = 6, + .items = { + "Preferences (Shift-F5)", + "MIDI Configuration (Shift-F1)", + "System Configuration (Ctrl-F1)", + "Palette Editor (Ctrl-F12)", + "Font Editor (Shift-F12)", + "Toggle Fullscreen (Ctrl-Alt-Enter)", + }, + .selected_item = 0, + .active_item = -1, + .selected_cb = settings_menu_selected_cb, }; /* *INDENT-ON* */ @@ -196,80 +196,80 @@ static void _draw_menu(struct menu *menu) { - int h = 6, n = menu->num_items; + int h = 6, n = menu->num_items; - while (n--) { - draw_box(2 + menu->x, 4 + menu->y + 3 * n, - 5 + menu->x + menu->w, 6 + menu->y + 3 * n, - BOX_THIN | BOX_CORNER | (n == menu->active_item ? BOX_INSET : BOX_OUTSET)); - - draw_text_len(menu->items[n], menu->w, 4 + menu->x, 5 + menu->y + 3 * n, - (n == menu->selected_item ? 3 : 0), 2); - - draw_char(0, 3 + menu->x, 5 + menu->y + 3 * n, 0, 2); - draw_char(0, 4 + menu->x + menu->w, 5 + menu->y + 3 * n, 0, 2); - - h += 3; - } - - draw_box(menu->x, menu->y, menu->x + menu->w + 7, menu->y + h - 1, - BOX_THICK | BOX_OUTER | BOX_FLAT_LIGHT); - draw_box(menu->x + 1, menu->y + 1, menu->x + menu->w + 6, - menu->y + h - 2, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); - draw_fill_chars(menu->x + 2, menu->y + 2, menu->x + menu->w + 5, menu->y + 3, 2); - draw_text(menu->title, menu->x + 6, menu->y + 2, 3, 2); + while (n--) { + draw_box(2 + menu->x, 4 + menu->y + 3 * n, + 5 + menu->x + menu->w, 6 + menu->y + 3 * n, + BOX_THIN | BOX_CORNER | (n == menu->active_item ? BOX_INSET : BOX_OUTSET)); + + draw_text_len(menu->items[n], menu->w, 4 + menu->x, 5 + menu->y + 3 * n, + (n == menu->selected_item ? 3 : 0), 2); + + draw_char(0, 3 + menu->x, 5 + menu->y + 3 * n, 0, 2); + draw_char(0, 4 + menu->x + menu->w, 5 + menu->y + 3 * n, 0, 2); + + h += 3; + } + + draw_box(menu->x, menu->y, menu->x + menu->w + 7, menu->y + h - 1, + BOX_THICK | BOX_OUTER | BOX_FLAT_LIGHT); + draw_box(menu->x + 1, menu->y + 1, menu->x + menu->w + 6, + menu->y + h - 2, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); + draw_fill_chars(menu->x + 2, menu->y + 2, menu->x + menu->w + 5, menu->y + 3, 2); + draw_text(menu->title, menu->x + 6, menu->y + 2, 3, 2); } void menu_draw(void) { - ENSURE_MENU(return); + ENSURE_MENU(return); - _draw_menu(current_menu[0]); - if (current_menu[1]) - _draw_menu(current_menu[1]); + _draw_menu(current_menu[0]); + if (current_menu[1]) + _draw_menu(current_menu[1]); } /* --------------------------------------------------------------------- */ void menu_show(void) { - dialog_destroy_all(); - status.dialog_type = DIALOG_MAIN_MENU; - current_menu[0] = &main_menu; + dialog_destroy_all(); + status.dialog_type = DIALOG_MAIN_MENU; + current_menu[0] = &main_menu; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } void menu_hide(void) { - ENSURE_MENU(return); + ENSURE_MENU(return); - status.dialog_type = DIALOG_NONE; + status.dialog_type = DIALOG_NONE; - /* "unpress" the menu items */ - current_menu[0]->active_item = -1; - if (current_menu[1]) - current_menu[1]->active_item = -1; + /* "unpress" the menu items */ + current_menu[0]->active_item = -1; + if (current_menu[1]) + current_menu[1]->active_item = -1; - current_menu[0] = current_menu[1] = NULL; + current_menu[0] = current_menu[1] = NULL; - /* note! this does NOT redraw the screen; that's up to the caller. - * the reason for this is that so many of the menu items cause a - * page switch, and redrawing the current page followed by - * redrawing a new page is redundant. */ + /* note! this does NOT redraw the screen; that's up to the caller. + * the reason for this is that so many of the menu items cause a + * page switch, and redrawing the current page followed by + * redrawing a new page is redundant. */ } /* --------------------------------------------------------------------- */ static void set_submenu(struct menu *menu) { - ENSURE_MENU(return); + ENSURE_MENU(return); - status.dialog_type = DIALOG_SUBMENU; - main_menu.active_item = main_menu.selected_item; - current_menu[1] = menu; + status.dialog_type = DIALOG_SUBMENU; + main_menu.active_item = main_menu.selected_item; + current_menu[1] = menu; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -277,161 +277,161 @@ static void main_menu_selected_cb(void) { - switch (main_menu.selected_item) { - case 0: /* file menu... */ - set_submenu(&file_menu); - break; - case 1: /* playback menu... */ - set_submenu(&playback_menu); - break; - case 2: /* view patterns */ - set_page(PAGE_PATTERN_EDITOR); - break; - case 3: /* sample menu... */ - set_submenu(&sample_menu); - break; - case 4: /* instrument menu... */ - set_submenu(&instrument_menu); - break; - case 5: /* view orders/panning */ - set_page(PAGE_ORDERLIST_PANNING); - break; - case 6: /* view variables */ - set_page(PAGE_SONG_VARIABLES); - break; - case 7: /* message editor */ - set_page(PAGE_MESSAGE); - break; - case 8: /* settings menu */ - /* fudge the menu to show/hide the fullscreen toggle as appropriate */ - if (status.flags & WM_AVAILABLE) - settings_menu.num_items = 6; - else - settings_menu.num_items = 5; - set_submenu(&settings_menu); - break; - case 9: /* help! */ - set_page(PAGE_HELP); - break; - } + switch (main_menu.selected_item) { + case 0: /* file menu... */ + set_submenu(&file_menu); + break; + case 1: /* playback menu... */ + set_submenu(&playback_menu); + break; + case 2: /* view patterns */ + set_page(PAGE_PATTERN_EDITOR); + break; + case 3: /* sample menu... */ + set_submenu(&sample_menu); + break; + case 4: /* instrument menu... */ + set_submenu(&instrument_menu); + break; + case 5: /* view orders/panning */ + set_page(PAGE_ORDERLIST_PANNING); + break; + case 6: /* view variables */ + set_page(PAGE_SONG_VARIABLES); + break; + case 7: /* message editor */ + set_page(PAGE_MESSAGE); + break; + case 8: /* settings menu */ + /* fudge the menu to show/hide the fullscreen toggle as appropriate */ + if (status.flags & WM_AVAILABLE) + settings_menu.num_items = 6; + else + settings_menu.num_items = 5; + set_submenu(&settings_menu); + break; + case 9: /* help! */ + set_page(PAGE_HELP); + break; + } } static void file_menu_selected_cb(void) { - switch (file_menu.selected_item) { - case 0: /* load... */ - set_page(PAGE_LOAD_MODULE); - break; - case 1: /* new... */ - new_song_dialog(); - break; - case 2: /* save current */ - save_song_or_save_as(); - break; - case 3: /* save as... */ - set_page(PAGE_SAVE_MODULE); - break; - case 4: - /* export ... */ - set_page(PAGE_EXPORT_MODULE); - break; - case 5: /* message log */ - set_page(PAGE_LOG); - break; - case 6: /* quit */ - show_exit_prompt(); - break; - } + switch (file_menu.selected_item) { + case 0: /* load... */ + set_page(PAGE_LOAD_MODULE); + break; + case 1: /* new... */ + new_song_dialog(); + break; + case 2: /* save current */ + save_song_or_save_as(); + break; + case 3: /* save as... */ + set_page(PAGE_SAVE_MODULE); + break; + case 4: + /* export ... */ + set_page(PAGE_EXPORT_MODULE); + break; + case 5: /* message log */ + set_page(PAGE_LOG); + break; + case 6: /* quit */ + show_exit_prompt(); + break; + } } static void playback_menu_selected_cb(void) { - switch (playback_menu.selected_item) { - case 0: /* show infopage */ - if (song_get_mode() == MODE_STOPPED - || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) - song_start(); - set_page(PAGE_INFO); - return; - case 1: /* play song */ - song_start(); - break; - case 2: /* play pattern */ - song_loop_pattern(get_current_pattern(), 0); - break; - case 3: /* play from order */ - song_start_at_order(get_current_order(), 0); - break; - case 4: /* play from mark/cursor */ - play_song_from_mark(); - break; - case 5: /* stop */ - song_stop(); - break; - case 6: /* reinit soundcard */ - audio_reinit(); - break; - case 7: /* driver screen */ - set_page(PAGE_PREFERENCES); - return; - case 8: /* calculate length */ - show_song_length(); - return; - } + switch (playback_menu.selected_item) { + case 0: /* show infopage */ + if (song_get_mode() == MODE_STOPPED + || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) + song_start(); + set_page(PAGE_INFO); + return; + case 1: /* play song */ + song_start(); + break; + case 2: /* play pattern */ + song_loop_pattern(get_current_pattern(), 0); + break; + case 3: /* play from order */ + song_start_at_order(get_current_order(), 0); + break; + case 4: /* play from mark/cursor */ + play_song_from_mark(); + break; + case 5: /* stop */ + song_stop(); + break; + case 6: /* reinit soundcard */ + audio_reinit(); + break; + case 7: /* driver screen */ + set_page(PAGE_PREFERENCES); + return; + case 8: /* calculate length */ + show_song_length(); + return; + } - menu_hide(); - status.flags |= NEED_UPDATE; + menu_hide(); + status.flags |= NEED_UPDATE; } static void sample_menu_selected_cb(void) { - switch (sample_menu.selected_item) { - case 0: /* sample list */ - set_page(PAGE_SAMPLE_LIST); - break; - case 1: /* sample library */ - set_page(PAGE_LIBRARY_SAMPLE); - break; - } + switch (sample_menu.selected_item) { + case 0: /* sample list */ + set_page(PAGE_SAMPLE_LIST); + break; + case 1: /* sample library */ + set_page(PAGE_LIBRARY_SAMPLE); + break; + } } static void instrument_menu_selected_cb(void) { - switch (instrument_menu.selected_item) { - case 0: /* instrument list */ - set_page(PAGE_INSTRUMENT_LIST); - break; - case 1: /* instrument library */ - set_page(PAGE_LIBRARY_INSTRUMENT); - break; - } + switch (instrument_menu.selected_item) { + case 0: /* instrument list */ + set_page(PAGE_INSTRUMENT_LIST); + break; + case 1: /* instrument library */ + set_page(PAGE_LIBRARY_INSTRUMENT); + break; + } } static void settings_menu_selected_cb(void) { - switch (settings_menu.selected_item) { - case 0: /* preferences page */ - set_page(PAGE_PREFERENCES); - return; - case 1: /* midi configuration */ - set_page(PAGE_MIDI); - return; - case 2: /* config */ - set_page(PAGE_CONFIG); - return; - case 3: /* palette configuration */ - set_page(PAGE_PALETTE_EDITOR); - return; - case 4: /* font editor */ - set_page(PAGE_FONT_EDIT); - return; - case 5: /* toggle fullscreen */ - toggle_display_fullscreen(); - break; - } + switch (settings_menu.selected_item) { + case 0: /* preferences page */ + set_page(PAGE_PREFERENCES); + return; + case 1: /* midi configuration */ + set_page(PAGE_MIDI); + return; + case 2: /* config */ + set_page(PAGE_CONFIG); + return; + case 3: /* palette configuration */ + set_page(PAGE_PALETTE_EDITOR); + return; + case 4: /* font editor */ + set_page(PAGE_FONT_EDIT); + return; + case 5: /* toggle fullscreen */ + toggle_display_fullscreen(); + break; + } - menu_hide(); - status.flags |= NEED_UPDATE; + menu_hide(); + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -439,94 +439,99 @@ /* As long as there's a menu active, this function will return true. */ int menu_handle_key(struct key_event *k) { - struct menu *menu; - int n, h; + struct menu *menu; + int n, h; - if ((status.dialog_type & DIALOG_MENU) == 0) - return 0; + if ((status.dialog_type & DIALOG_MENU) == 0) + return 0; - menu = (status.dialog_type == DIALOG_SUBMENU - ? current_menu[1] : current_menu[0]); + menu = (status.dialog_type == DIALOG_SUBMENU + ? current_menu[1] : current_menu[0]); - if (k->mouse) { - if (k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) { - h = menu->num_items * 3; - if (k->x >= menu->x + 2 && k->x <= menu->x + menu->w + 5 - && k->y >= menu->y + 4 && k->y <= menu->y + h + 4) { - n = ((k->y - 4) - menu->y) / 3; - if (n >= 0 && n < menu->num_items) { - menu->selected_item = n; - if (k->state) { - menu->active_item = -1; - menu->selected_cb(); - } else { - status.flags |= NEED_UPDATE; - menu->active_item = n; - } - } - } else if (k->state && (k->x < menu->x || k->x > 7+menu->x+menu->w - || k->y < menu->y || k->y >= 5+menu->y+h)) { - /* get rid of the menu */ - current_menu[1] = NULL; - if (status.dialog_type == DIALOG_SUBMENU) { - status.dialog_type = DIALOG_MAIN_MENU; - main_menu.active_item = -1; - } else { - menu_hide(); - } - status.flags |= NEED_UPDATE; - } - } - return 1; - } - - switch (k->sym) { - case SDLK_ESCAPE: - if (k->state) return 1; - current_menu[1] = NULL; - if (status.dialog_type == DIALOG_SUBMENU) { - status.dialog_type = DIALOG_MAIN_MENU; - main_menu.active_item = -1; - } else { - menu_hide(); - } - break; - case SDLK_UP: - if (k->state) return 1; - if (menu->selected_item > 0) { - menu->selected_item--; - break; - } - return 1; - case SDLK_DOWN: - if (k->state) return 1; - if (menu->selected_item < menu->num_items - 1) { - menu->selected_item++; - break; - } - return 1; - /* home/end are new here :) */ - case SDLK_HOME: - if (k->state) return 1; - menu->selected_item = 0; - break; - case SDLK_END: - if (k->state) return 1; - menu->selected_item = menu->num_items - 1; - break; - case SDLK_RETURN: - if (!k->state) { - menu->active_item = menu->selected_item; - status.flags |= NEED_UPDATE; - return 1; - } - menu->selected_cb(); - return 1; - default: - return 1; - } + if (k->mouse) { + if (k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) { + h = menu->num_items * 3; + if (k->x >= menu->x + 2 && k->x <= menu->x + menu->w + 5 + && k->y >= menu->y + 4 && k->y <= menu->y + h + 4) { + n = ((k->y - 4) - menu->y) / 3; + if (n >= 0 && n < menu->num_items) { + menu->selected_item = n; + if (k->state == KEY_RELEASE) { + menu->active_item = -1; + menu->selected_cb(); + } else { + status.flags |= NEED_UPDATE; + menu->active_item = n; + } + } + } else if (k->state == KEY_RELEASE && (k->x < menu->x || k->x > 7+menu->x+menu->w + || k->y < menu->y || k->y >= 5+menu->y+h)) { + /* get rid of the menu */ + current_menu[1] = NULL; + if (status.dialog_type == DIALOG_SUBMENU) { + status.dialog_type = DIALOG_MAIN_MENU; + main_menu.active_item = -1; + } else { + menu_hide(); + } + status.flags |= NEED_UPDATE; + } + } + return 1; + } + + switch (k->sym) { + case SDLK_ESCAPE: + if (k->state == KEY_RELEASE) + return 1; + current_menu[1] = NULL; + if (status.dialog_type == DIALOG_SUBMENU) { + status.dialog_type = DIALOG_MAIN_MENU; + main_menu.active_item = -1; + } else { + menu_hide(); + } + break; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + if (menu->selected_item > 0) { + menu->selected_item--; + break; + } + return 1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + if (menu->selected_item < menu->num_items - 1) { + menu->selected_item++; + break; + } + return 1; + /* home/end are new here :) */ + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 1; + menu->selected_item = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 1; + menu->selected_item = menu->num_items - 1; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) { + menu->active_item = menu->selected_item; + status.flags |= NEED_UPDATE; + return 1; + } + menu->selected_cb(); + return 1; + default: + return 1; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; - return 1; + return 1; } diff -Nru schism-0+20110101/schism/midi-core.c schism-20160521/schism/midi-core.c --- schism-0+20110101/schism/midi-core.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/midi-core.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -56,15 +56,15 @@ static struct midi_provider *port_providers = NULL; -/* time shit */ +/* all this just for usleep?! (maybe we should have sys/win32/usleep.c) */ #ifdef WIN32 #include static void (*__win32_usleep)(unsigned int usec) = NULL; static void __win32_old_usleep(unsigned int u) { - /* bah, only Win95 and "earlier" actually needs this... */ - SleepEx(u/1000,FALSE); + /* bah, only Win95 and "earlier" actually needs this... */ + SleepEx(u/1000,FALSE); } static FARPROC __ihatewindows_f1 = NULL; @@ -74,33 +74,33 @@ static void __win32_new_usleep(unsigned int u) { - LARGE_INTEGER due; - due.QuadPart = -(10 * (__int64)u); - __ihatewindows_f2(__midi_timer, &due, 0, NULL, NULL, 0); - __ihatewindows_f3(__midi_timer, INFINITE); + LARGE_INTEGER due; + due.QuadPart = -(10 * (__int64)u); + __ihatewindows_f2(__midi_timer, &due, 0, NULL, NULL, 0); + __ihatewindows_f3(__midi_timer, INFINITE); } static void __win32_pick_usleep(void) { - HINSTANCE k32; + HINSTANCE k32; - k32 = GetModuleHandle("KERNEL32.DLL"); - if (!k32) k32 = LoadLibrary("KERNEL32.DLL"); - if (!k32) k32 = GetModuleHandle("KERNEL32.DLL"); - if (!k32) goto FAIL; - __ihatewindows_f1 = (FARPROC)GetProcAddress(k32,"CreateWaitableTimer"); - __ihatewindows_f2 = (FARPROC)GetProcAddress(k32,"SetWaitableTimer"); - __ihatewindows_f3 = (FARPROC)GetProcAddress(k32,"WaitForSingleObject"); - if (!__ihatewindows_f1 || !__ihatewindows_f2 || !__ihatewindows_f3) - goto FAIL; - __midi_timer = (HANDLE)__ihatewindows_f1(NULL,TRUE,NULL); - if (!__midi_timer) goto FAIL; - - /* grumble */ - __win32_usleep = __win32_new_usleep; - return; + k32 = GetModuleHandle("KERNEL32.DLL"); + if (!k32) k32 = LoadLibrary("KERNEL32.DLL"); + if (!k32) k32 = GetModuleHandle("KERNEL32.DLL"); + if (!k32) goto FAIL; + __ihatewindows_f1 = (FARPROC)GetProcAddress(k32,"CreateWaitableTimer"); + __ihatewindows_f2 = (FARPROC)GetProcAddress(k32,"SetWaitableTimer"); + __ihatewindows_f3 = (FARPROC)GetProcAddress(k32,"WaitForSingleObject"); + if (!__ihatewindows_f1 || !__ihatewindows_f2 || !__ihatewindows_f3) + goto FAIL; + __midi_timer = (HANDLE)__ihatewindows_f1(NULL,TRUE,NULL); + if (!__midi_timer) goto FAIL; + + /* grumble */ + __win32_usleep = __win32_new_usleep; + return; FAIL: - __win32_usleep = __win32_old_usleep; + __win32_usleep = __win32_old_usleep; } #define SLEEP_FUNC(x) __win32_usleep(x) @@ -113,188 +113,187 @@ /* configurable midi stuff */ int midi_flags = MIDI_TICK_QUANTIZE | MIDI_RECORD_NOTEOFF - | MIDI_RECORD_VELOCITY | MIDI_RECORD_AFTERTOUCH - | MIDI_PITCHBEND; + | MIDI_RECORD_VELOCITY | MIDI_RECORD_AFTERTOUCH + | MIDI_PITCHBEND; int midi_pitch_depth = 12; int midi_amplification = 100; int midi_c5note = 60; #define CFG_GET_MI(v,d) midi_ ## v = cfg_get_number(cfg, "MIDI", #v, d) -#define CFG_GET_MS(v,b,l,d) cfg_get_string(cfg, "MIDI", #v, b,l, d) static void _cfg_load_midi_part_locked(struct midi_port *q) { - struct cfg_section *c; - /*struct midi_provider *p;*/ - cfg_file_t cfg; - const char *sn; - char *ptr, *ss, *sp; - char buf[256]; - int j; - - ss = q->name; - if (!ss) return; - while (isspace(*ss)) ss++; - if (!*ss) return; - - sp = q->provider ? q->provider->name : NULL; - if (sp) { - while (isspace(*sp)) sp++; - if (!*sp) sp = NULL; - } - - ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); - cfg_init(&cfg, ptr); - - /* look for MIDI port sections */ - for (c = cfg.sections; c; c = c->next) { - j = -1; - sscanf(c->name, "MIDI Port %d", &j); - if (j < 1) continue; - sn = cfg_get_string(&cfg, c->name, "name", buf, 255, NULL); - if (!sn) continue; - if (strcasecmp(ss, sn) != 0) continue; - sn = cfg_get_string(&cfg, c->name, "provider", buf, 255, NULL); - if (sn && sp && strcasecmp(sp, sn) != 0) continue; - /* okay found port */ - if ((q->iocap & MIDI_INPUT) && cfg_get_number(&cfg, c->name, "input", 0)) { - q->io |= MIDI_INPUT; - } - if ((q->iocap & MIDI_OUTPUT) && cfg_get_number(&cfg, c->name, "output", 0)) { - q->io |= MIDI_OUTPUT; - } - if (q->io && q->enable) q->enable(q); - } + struct cfg_section *c; + /*struct midi_provider *p;*/ + cfg_file_t cfg; + const char *sn; + char *ptr, *ss, *sp; + char buf[256]; + int j; + + ss = q->name; + if (!ss) return; + while (isspace(*ss)) ss++; + if (!*ss) return; + + sp = q->provider ? q->provider->name : NULL; + if (sp) { + while (isspace(*sp)) sp++; + if (!*sp) sp = NULL; + } + + ptr = dmoz_path_concat(cfg_dir_dotschism, "config"); + cfg_init(&cfg, ptr); + + /* look for MIDI port sections */ + for (c = cfg.sections; c; c = c->next) { + j = -1; + sscanf(c->name, "MIDI Port %d", &j); + if (j < 1) continue; + sn = cfg_get_string(&cfg, c->name, "name", buf, 255, NULL); + if (!sn) continue; + if (strcasecmp(ss, sn) != 0) continue; + sn = cfg_get_string(&cfg, c->name, "provider", buf, 255, NULL); + if (sn && sp && strcasecmp(sp, sn) != 0) continue; + /* okay found port */ + if ((q->iocap & MIDI_INPUT) && cfg_get_number(&cfg, c->name, "input", 0)) { + q->io |= MIDI_INPUT; + } + if ((q->iocap & MIDI_OUTPUT) && cfg_get_number(&cfg, c->name, "output", 0)) { + q->io |= MIDI_OUTPUT; + } + if (q->io && q->enable) q->enable(q); + } - cfg_free(&cfg); - free(ptr); + cfg_free(&cfg); + free(ptr); } void cfg_load_midi(cfg_file_t *cfg) { - midi_config_t *md, *mc; - char buf[16], buf2[32]; - int i; - - CFG_GET_MI(flags, MIDI_TICK_QUANTIZE | MIDI_RECORD_NOTEOFF - | MIDI_RECORD_VELOCITY | MIDI_RECORD_AFTERTOUCH - | MIDI_PITCHBEND); - CFG_GET_MI(pitch_depth, 12); - CFG_GET_MI(amplification, 100); - CFG_GET_MI(c5note, 60); - - song_lock_audio(); - md = &default_midi_config; - cfg_get_string(cfg,"MIDI","start", md->start, 32, "FF"); - cfg_get_string(cfg,"MIDI","stop", md->stop, 32, "FC"); - cfg_get_string(cfg,"MIDI","tick", md->tick, 32, ""); - cfg_get_string(cfg,"MIDI","note_on", md->note_on, 32, "9c n v"); - cfg_get_string(cfg,"MIDI","note_off", md->note_off, 32, "9c n 0"); - cfg_get_string(cfg,"MIDI","set_volume", md->set_volume, 32, ""); - cfg_get_string(cfg,"MIDI","set_panning", md->set_panning, 32, ""); - cfg_get_string(cfg,"MIDI","set_bank", md->set_bank, 32, ""); - cfg_get_string(cfg,"MIDI","set_program", md->set_program, 32, "Cc p"); - for (i = 0; i < 16; i++) { - sprintf(buf, "SF%X", i); - cfg_get_string(cfg, "MIDI", buf, md->sfx[i], 32, - i == 0 ? "F0F000z" : ""); - } - - for (i = 0; i < 128; i++) { - sprintf(buf, "Z%02X", i + 0x80); - if (i < 16) - sprintf(buf2, "F0F001%02x", i * 8); - else - buf2[0] = '\0'; - cfg_get_string(cfg, "MIDI", buf, md->zxx[i], 32, buf2); - } + midi_config_t *md, *mc; + char buf[17], buf2[33]; + int i; + + CFG_GET_MI(flags, MIDI_TICK_QUANTIZE | MIDI_RECORD_NOTEOFF + | MIDI_RECORD_VELOCITY | MIDI_RECORD_AFTERTOUCH + | MIDI_PITCHBEND); + CFG_GET_MI(pitch_depth, 12); + CFG_GET_MI(amplification, 100); + CFG_GET_MI(c5note, 60); + + song_lock_audio(); + md = &default_midi_config; + cfg_get_string(cfg,"MIDI","start", md->start, 31, "FF"); + cfg_get_string(cfg,"MIDI","stop", md->stop, 31, "FC"); + cfg_get_string(cfg,"MIDI","tick", md->tick, 31, ""); + cfg_get_string(cfg,"MIDI","note_on", md->note_on, 31, "9c n v"); + cfg_get_string(cfg,"MIDI","note_off", md->note_off, 31, "9c n 0"); + cfg_get_string(cfg,"MIDI","set_volume", md->set_volume, 31, ""); + cfg_get_string(cfg,"MIDI","set_panning", md->set_panning, 31, ""); + cfg_get_string(cfg,"MIDI","set_bank", md->set_bank, 31, ""); + cfg_get_string(cfg,"MIDI","set_program", md->set_program, 31, "Cc p"); + for (i = 0; i < 16; i++) { + snprintf(buf, 16, "SF%X", i); + cfg_get_string(cfg, "MIDI", buf, md->sfx[i], 31, + i == 0 ? "F0F000z" : ""); + } + + for (i = 0; i < 128; i++) { + snprintf(buf, 16, "Z%02X", i + 0x80); + if (i < 16) + snprintf(buf2, 32, "F0F001%02x", i * 8); + else + buf2[0] = '\0'; + cfg_get_string(cfg, "MIDI", buf, md->zxx[i], 31, buf2); + } - mc = ¤t_song->midi_config; - memcpy(mc, md, sizeof(midi_config_t)); + mc = ¤t_song->midi_config; + memcpy(mc, md, sizeof(midi_config_t)); - song_unlock_audio(); + song_unlock_audio(); } #define CFG_SET_MI(v) cfg_set_number(cfg, "MIDI", #v, midi_ ## v) -#define CFG_SET_MS(v,b,d) cfg_get_string(cfg, "MIDI", #v, b, d) void cfg_save_midi(cfg_file_t *cfg) { - struct cfg_section *c; - struct midi_provider *p; - struct midi_port *q; - midi_config_t *md, *mc; - char buf[32]; - char *ss; - int i, j; - - CFG_SET_MI(flags); - CFG_SET_MI(pitch_depth); - CFG_SET_MI(amplification); - CFG_SET_MI(c5note); - - song_lock_audio(); - md = &default_midi_config; - - /* overwrite default */ - mc = ¤t_song->midi_config; - memcpy(md, mc, sizeof(midi_config_t)); - - cfg_set_string(cfg,"MIDI","start", md->start); - cfg_set_string(cfg,"MIDI","stop", md->stop); - cfg_set_string(cfg,"MIDI","tick", md->tick); - cfg_set_string(cfg,"MIDI","note_on", md->note_on); - cfg_set_string(cfg,"MIDI","note_off", md->note_off); - cfg_set_string(cfg,"MIDI","set_volume", md->set_volume); - cfg_set_string(cfg,"MIDI","set_panning", md->set_panning); - cfg_set_string(cfg,"MIDI","set_bank", md->set_bank); - cfg_set_string(cfg,"MIDI","set_program", md->set_program); - for (i = 0; i < 16; i++) { - sprintf(buf, "SF%X", i); - cfg_set_string(cfg, "MIDI", buf, md->sfx[i]); - } - for (i = 0; i < 128; i++) { - sprintf(buf, "Z%02X", i + 0x80); - cfg_set_string(cfg, "MIDI", buf, md->zxx[i]); - } - song_unlock_audio(); - - /* write out only enabled midi ports */ - i = 1; - SDL_mutexP(midi_mutex); - q = NULL; - for (p = port_providers; p; p = p->next) { - while (midi_port_foreach(p, &q)) { - ss = q->name; - if (!ss) continue; - while (isspace(*ss)) ss++; - if (!*ss) continue; - if (!q->io) continue; - - sprintf(buf, "MIDI Port %d", i); i++; - cfg_set_string(cfg, buf, "name", ss); - ss = p->name; - if (ss) { - while (isspace(*ss)) ss++; - if (*ss) { - cfg_set_string(cfg, buf, "provider", ss); - } - } - cfg_set_number(cfg, buf, "input", q->io & MIDI_INPUT ? 1 : 0); - cfg_set_number(cfg, buf, "output", q->io & MIDI_OUTPUT ? 1 : 0); - } - } - SDL_mutexV(midi_mutex); - - /* delete other MIDI port sections */ - for (c = cfg->sections; c; c = c->next) { - j = -1; - sscanf(c->name, "MIDI Port %d", &j); - if (j < i) continue; - c->omit = 1; - } + struct cfg_section *c; + struct midi_provider *p; + struct midi_port *q; + midi_config_t *md, *mc; + char buf[33]; + char *ss; + int i, j; + + CFG_SET_MI(flags); + CFG_SET_MI(pitch_depth); + CFG_SET_MI(amplification); + CFG_SET_MI(c5note); + + song_lock_audio(); + md = &default_midi_config; + + /* overwrite default */ + mc = ¤t_song->midi_config; + memcpy(md, mc, sizeof(midi_config_t)); + + cfg_set_string(cfg,"MIDI","start", md->start); + cfg_set_string(cfg,"MIDI","stop", md->stop); + cfg_set_string(cfg,"MIDI","tick", md->tick); + cfg_set_string(cfg,"MIDI","note_on", md->note_on); + cfg_set_string(cfg,"MIDI","note_off", md->note_off); + cfg_set_string(cfg,"MIDI","set_volume", md->set_volume); + cfg_set_string(cfg,"MIDI","set_panning", md->set_panning); + cfg_set_string(cfg,"MIDI","set_bank", md->set_bank); + cfg_set_string(cfg,"MIDI","set_program", md->set_program); + for (i = 0; i < 16; i++) { + snprintf(buf, 32, "SF%X", i); + cfg_set_string(cfg, "MIDI", buf, md->sfx[i]); + } + for (i = 0; i < 128; i++) { + snprintf(buf, 32, "Z%02X", i + 0x80); + cfg_set_string(cfg, "MIDI", buf, md->zxx[i]); + } + song_unlock_audio(); + + /* write out only enabled midi ports */ + i = 1; + SDL_mutexP(midi_mutex); + q = NULL; + for (p = port_providers; p; p = p->next) { + while (midi_port_foreach(p, &q)) { + ss = q->name; + if (!ss) continue; + while (isspace(*ss)) ss++; + if (!*ss) continue; + if (!q->io) continue; + + snprintf(buf, 32, "MIDI Port %d", i); i++; + cfg_set_string(cfg, buf, "name", ss); + ss = p->name; + if (ss) { + while (isspace(*ss)) ss++; + if (*ss) { + cfg_set_string(cfg, buf, "provider", ss); + } + } + cfg_set_number(cfg, buf, "input", q->io & MIDI_INPUT ? 1 : 0); + cfg_set_number(cfg, buf, "output", q->io & MIDI_OUTPUT ? 1 : 0); + } + } + //TODO: Save number of MIDI-IP ports + SDL_mutexV(midi_mutex); + + /* delete other MIDI port sections */ + for (c = cfg->sections; c; c = c->next) { + j = -1; + sscanf(c->name, "MIDI Port %d", &j); + if (j < i) continue; + c->omit = 1; + } } @@ -302,95 +301,95 @@ static void _midi_engine_connect(void) { #ifdef USE_NETWORK - ip_midi_setup(); + ip_midi_setup(); #endif #ifdef USE_OSS - oss_midi_setup(); + oss_midi_setup(); #endif #ifdef USE_ALSA - alsa_midi_setup(); + alsa_midi_setup(); #endif #ifdef WIN32 - win32mm_midi_setup(); + win32mm_midi_setup(); #endif #ifdef MACOSX - macosx_midi_setup(); + macosx_midi_setup(); #endif } void midi_engine_poll_ports(void) { - struct midi_provider *n; + struct midi_provider *n; - if (!midi_mutex) return; + if (!midi_mutex) return; - SDL_mutexP(midi_mutex); - for (n = port_providers; n; n = n->next) { - if (n->poll) n->poll(n); - } - SDL_mutexV(midi_mutex); + SDL_mutexP(midi_mutex); + for (n = port_providers; n; n = n->next) { + if (n->poll) n->poll(n); + } + SDL_mutexV(midi_mutex); } int midi_engine_start(void) { - if (_connected) - return 1; + if (_connected) + return 1; - midi_mutex = SDL_CreateMutex(); - midi_record_mutex = SDL_CreateMutex(); - midi_play_mutex = SDL_CreateMutex(); - midi_port_mutex = SDL_CreateMutex(); - midi_play_cond = SDL_CreateCond(); - - if (!(midi_mutex && midi_record_mutex && midi_play_mutex && midi_port_mutex && midi_play_cond)) { - if (midi_mutex) SDL_DestroyMutex(midi_mutex); - if (midi_record_mutex) SDL_DestroyMutex(midi_record_mutex); - if (midi_play_mutex) SDL_DestroyMutex(midi_play_mutex); - if (midi_port_mutex) SDL_DestroyMutex(midi_port_mutex); - if (midi_play_cond) SDL_DestroyCond(midi_play_cond); - midi_mutex = midi_record_mutex = midi_play_mutex = midi_port_mutex = NULL; - midi_play_cond = NULL; - return 0; - } - - _midi_engine_connect(); - _connected = 1; - return 1; + midi_mutex = SDL_CreateMutex(); + midi_record_mutex = SDL_CreateMutex(); + midi_play_mutex = SDL_CreateMutex(); + midi_port_mutex = SDL_CreateMutex(); + midi_play_cond = SDL_CreateCond(); + + if (!(midi_mutex && midi_record_mutex && midi_play_mutex && midi_port_mutex && midi_play_cond)) { + if (midi_mutex) SDL_DestroyMutex(midi_mutex); + if (midi_record_mutex) SDL_DestroyMutex(midi_record_mutex); + if (midi_play_mutex) SDL_DestroyMutex(midi_play_mutex); + if (midi_port_mutex) SDL_DestroyMutex(midi_port_mutex); + if (midi_play_cond) SDL_DestroyCond(midi_play_cond); + midi_mutex = midi_record_mutex = midi_play_mutex = midi_port_mutex = NULL; + midi_play_cond = NULL; + return 0; + } + + _midi_engine_connect(); + _connected = 1; + return 1; } void midi_engine_reset(void) { - if (!_connected) return; - midi_engine_stop(); - _midi_engine_connect(); + if (!_connected) return; + midi_engine_stop(); + _midi_engine_connect(); } void midi_engine_stop(void) { - struct midi_provider *n, *p; - struct midi_port *q; + struct midi_provider *n, *p; + struct midi_port *q; - if (!_connected) return; - if (!midi_mutex) return; + if (!_connected) return; + if (!midi_mutex) return; - SDL_mutexP(midi_mutex); - for (n = port_providers; n;) { - p = n->next; - - q = NULL; - while (midi_port_foreach(p, &q)) { - midi_port_unregister(q->num); - } - - if (n->thread) { - SDL_KillThread(n->thread); - } - free(n->name); - free(n); - n = p; - } - _connected = 0; - SDL_mutexV(midi_mutex); + SDL_mutexP(midi_mutex); + for (n = port_providers; n;) { + p = n->next; + + q = NULL; + while (midi_port_foreach(p, &q)) { + midi_port_unregister(q->num); + } + + if (n->thread) { + SDL_KillThread(n->thread); + } + free(n->name); + free(n); + n = p; + } + _connected = 0; + SDL_mutexV(midi_mutex); } @@ -401,199 +400,199 @@ struct midi_port *midi_engine_port(int n, const char **name) { - struct midi_port *pv = NULL; + struct midi_port *pv = NULL; - if (!midi_port_mutex) return NULL; - SDL_mutexP(midi_port_mutex); - if (n >= 0 && n < port_count) { - pv = port_top[n]; - if (name) *name = pv->name; - } - SDL_mutexV(midi_port_mutex); - return pv; + if (!midi_port_mutex) return NULL; + SDL_mutexP(midi_port_mutex); + if (n >= 0 && n < port_count) { + pv = port_top[n]; + if (name) *name = pv->name; + } + SDL_mutexV(midi_port_mutex); + return pv; } int midi_engine_port_count(void) { - int pc; - if (!midi_port_mutex) return 0; - SDL_mutexP(midi_port_mutex); - pc = port_count; - SDL_mutexV(midi_port_mutex); - return pc; + int pc; + if (!midi_port_mutex) return 0; + SDL_mutexP(midi_port_mutex); + pc = port_count; + SDL_mutexV(midi_port_mutex); + return pc; } /* midi engines register a provider (one each!) */ struct midi_provider *midi_provider_register(const char *name, - struct midi_driver *driver) + struct midi_driver *driver) { - struct midi_provider *n; + struct midi_provider *n; - if (!midi_mutex) return NULL; + if (!midi_mutex) return NULL; - n = mem_alloc(sizeof(struct midi_provider)); - n->name = str_dup(name); - n->poll = driver->poll; - n->enable = driver->enable; - n->disable = driver->disable; - if (driver->flags & MIDI_PORT_CAN_SCHEDULE) { - n->send_later = driver->send; - n->send_now = NULL; - n->drain = driver->drain; - } else { - n->send_later = NULL; - n->send_now = driver->send; - n->drain = NULL; - } - - SDL_mutexP(midi_mutex); - n->next = port_providers; - port_providers = n; - - if (driver->thread) { - // FIXME this cast is stupid - n->thread = SDL_CreateThread((int (*)(void*))driver->thread, n); - } else { - n->thread = NULL; - } + n = mem_alloc(sizeof(struct midi_provider)); + n->name = str_dup(name); + n->poll = driver->poll; + n->enable = driver->enable; + n->disable = driver->disable; + if (driver->flags & MIDI_PORT_CAN_SCHEDULE) { + n->send_later = driver->send; + n->send_now = NULL; + n->drain = driver->drain; + } else { + n->send_later = NULL; + n->send_now = driver->send; + n->drain = NULL; + } + + SDL_mutexP(midi_mutex); + n->next = port_providers; + port_providers = n; + + if (driver->thread) { + // FIXME this cast is stupid + n->thread = SDL_CreateThread((int (*)(void*))driver->thread, n); + } else { + n->thread = NULL; + } - SDL_mutexV(midi_mutex); + SDL_mutexV(midi_mutex); - return n; + return n; } /* midi engines list ports this way */ int midi_port_register(struct midi_provider *pv, int inout, const char *name, void *userdata, int free_userdata) { - struct midi_port *p, **pt; - int i; + struct midi_port *p, **pt; + int i; - if (!midi_port_mutex) return -1; + if (!midi_port_mutex) return -1; - p = mem_alloc(sizeof(struct midi_port)); - p->io = 0; - p->iocap = inout; - p->name = str_dup(name); - p->enable = pv->enable; - p->disable = pv->disable; - p->send_later = pv->send_later; - p->send_now = pv->send_now; - p->drain = pv->drain; - - p->free_userdata = free_userdata; - p->userdata = userdata; - p->provider = pv; - - for (i = 0; i < port_alloc; i++) { - if (port_top[i] == NULL) { - port_top[i] = p; - p->num = i; - port_count++; - _cfg_load_midi_part_locked(p); - return i; - } - } - - SDL_mutexP(midi_port_mutex); - port_alloc += 4; - pt = realloc(port_top, sizeof(struct midi_port *) * port_alloc); - if (!pt) { - free(p->name); - free(p); - SDL_mutexV(midi_port_mutex); - return -1; - } - pt[port_count] = p; - for (i = port_count+1; i < port_alloc; i++) pt[i] = NULL; - port_top = pt; - p->num = port_count; - port_count++; + p = mem_alloc(sizeof(struct midi_port)); + p->io = 0; + p->iocap = inout; + p->name = str_dup(name); + p->enable = pv->enable; + p->disable = pv->disable; + p->send_later = pv->send_later; + p->send_now = pv->send_now; + p->drain = pv->drain; + + p->free_userdata = free_userdata; + p->userdata = userdata; + p->provider = pv; + + for (i = 0; i < port_alloc; i++) { + if (port_top[i] == NULL) { + port_top[i] = p; + p->num = i; + port_count++; + _cfg_load_midi_part_locked(p); + return i; + } + } + + SDL_mutexP(midi_port_mutex); + port_alloc += 4; + pt = realloc(port_top, sizeof(struct midi_port *) * port_alloc); + if (!pt) { + free(p->name); + free(p); + SDL_mutexV(midi_port_mutex); + return -1; + } + pt[port_count] = p; + for (i = port_count+1; i < port_alloc; i++) pt[i] = NULL; + port_top = pt; + p->num = port_count; + port_count++; - /* finally, and just before unlocking, load any configuration for it... */ - _cfg_load_midi_part_locked(p); + /* finally, and just before unlocking, load any configuration for it... */ + _cfg_load_midi_part_locked(p); - SDL_mutexV(midi_port_mutex); - return p->num; + SDL_mutexV(midi_port_mutex); + return p->num; } int midi_port_foreach(struct midi_provider *p, struct midi_port **cursor) { - int i; - if (!midi_port_mutex) return 0; + int i; + if (!midi_port_mutex) return 0; - SDL_mutexP(midi_port_mutex); - do { - if (!*cursor) { - i = 0; - } else { - i = ((*cursor)->num) + 1; - while (i < port_alloc && !port_top[i]) i++; - } - if (i >= port_alloc) { - *cursor = NULL; - SDL_mutexV(midi_port_mutex); - return 0; - } - *cursor = port_top[i]; - } while (p && (*cursor)->provider != p); - SDL_mutexV(midi_port_mutex); - return 1; + SDL_mutexP(midi_port_mutex); + do { + if (!*cursor) { + i = 0; + } else { + i = ((*cursor)->num) + 1; + while (i < port_alloc && !port_top[i]) i++; + } + if (i >= port_alloc) { + *cursor = NULL; + SDL_mutexV(midi_port_mutex); + return 0; + } + *cursor = port_top[i]; + } while (p && (*cursor)->provider != p); + SDL_mutexV(midi_port_mutex); + return 1; } static int _midi_send_unlocked(const unsigned char *data, unsigned int len, unsigned int delay, - int from) + int from) { - struct midi_port *ptr = NULL; - int need_timer = 0; + struct midi_port *ptr = NULL; + int need_timer = 0; #if 0 - unsigned int i; + unsigned int i; printf("MIDI: "); - for (i = 0; i < len; i++) { - printf("%02x ", data[i]); - } + for (i = 0; i < len; i++) { + printf("%02x ", data[i]); + } puts(""); fflush(stdout); #endif - if (from == 0) { - /* from == 0 means from immediate; everyone plays */ - while (midi_port_foreach(NULL, &ptr)) { - if ((ptr->io & MIDI_OUTPUT)) { - if (ptr->send_now) - ptr->send_now(ptr, data, len, 0); - else if (ptr->send_later) - ptr->send_later(ptr, data, len, 0); - } - } - } else if (from == 1) { - /* from == 1 means from buffer-flush; only "now" plays */ - while (midi_port_foreach(NULL, &ptr)) { - if ((ptr->io & MIDI_OUTPUT)) { - if (ptr->send_now) - ptr->send_now(ptr, data, len, 0); - } - } - } else { - /* from == 2 means from buffer-write; only "later" plays */ - while (midi_port_foreach(NULL, &ptr)) { - if ((ptr->io & MIDI_OUTPUT)) { - if (ptr->send_later) - ptr->send_later(ptr, data, len, delay); - else if (ptr->send_now) - need_timer = 1; - } - } - } - return need_timer; + if (from == 0) { + /* from == 0 means from immediate; everyone plays */ + while (midi_port_foreach(NULL, &ptr)) { + if ((ptr->io & MIDI_OUTPUT)) { + if (ptr->send_now) + ptr->send_now(ptr, data, len, 0); + else if (ptr->send_later) + ptr->send_later(ptr, data, len, 0); + } + } + } else if (from == 1) { + /* from == 1 means from buffer-flush; only "now" plays */ + while (midi_port_foreach(NULL, &ptr)) { + if ((ptr->io & MIDI_OUTPUT)) { + if (ptr->send_now) + ptr->send_now(ptr, data, len, 0); + } + } + } else { + /* from == 2 means from buffer-write; only "later" plays */ + while (midi_port_foreach(NULL, &ptr)) { + if ((ptr->io & MIDI_OUTPUT)) { + if (ptr->send_later) + ptr->send_later(ptr, data, len, delay); + else if (ptr->send_now) + need_timer = 1; + } + } + } + return need_timer; } void midi_send_now(const unsigned char *seq, unsigned int len) { - if (!midi_record_mutex) return; + if (!midi_record_mutex) return; - SDL_mutexP(midi_record_mutex); - _midi_send_unlocked(seq, len, 0, 0); - SDL_mutexV(midi_record_mutex); + SDL_mutexP(midi_record_mutex); + _midi_send_unlocked(seq, len, 0, 0); + SDL_mutexV(midi_record_mutex); } /*----------------------------------------------------------------------------------*/ @@ -616,463 +615,461 @@ * really, software-only midi, without kernel assistance sucks. */ struct qent { - int used; - unsigned char b[391]; + int used; + unsigned char b[391]; }; static struct qent *qq = NULL; static int midims, ms10s, qlen; void midi_queue_alloc(int my_audio_buffer_samples, int channels, int samples_per_second) { - if (qq) { - free(qq); - qq = NULL; - } - - /* how long is the audio buffer in 10 msec? - * well, (channels*samples_per_second)/80 is the number of bytes per msec - */ - midims = channels * samples_per_second; - if ((midims % 80) != 0) midims += (80 - (midims % 80)); - ms10s = midims / 80; - midims /= 8; - - if (ms10s > my_audio_buffer_samples) { - /* okay, there's not even 10msec of audio data; midi queueing will be impossible */ - qlen = 0; - return; - } - - if ((my_audio_buffer_samples % ms10s) != 0) { - my_audio_buffer_samples += (ms10s - (my_audio_buffer_samples % ms10s)); - } - qlen = my_audio_buffer_samples / ms10s; - /* now qlen is the number of msec in digital output buffer */ - - qq = malloc(qlen * sizeof(struct qent)); - if (!qq) { - /* memory allocation failed. something else is bound to die real soon now */ - return; - } - /* zero it out */ - memset(qq, 0, sizeof(struct qent)*qlen); + if (qq) { + free(qq); + qq = NULL; + } + + /* how long is the audio buffer in 10 msec? + * well, (channels*samples_per_second)/80 is the number of bytes per msec + */ + midims = channels * samples_per_second; + if ((midims % 80) != 0) midims += (80 - (midims % 80)); + ms10s = midims / 80; + midims /= 8; + + if (ms10s > my_audio_buffer_samples) { + /* okay, there's not even 10msec of audio data; midi queueing will be impossible */ + qlen = 0; + return; + } + + if ((my_audio_buffer_samples % ms10s) != 0) { + my_audio_buffer_samples += (ms10s - (my_audio_buffer_samples % ms10s)); + } + qlen = my_audio_buffer_samples / ms10s; + /* now qlen is the number of msec in digital output buffer */ + + qq = malloc(qlen * sizeof(struct qent)); + if (!qq) { + /* memory allocation failed. something else is bound to die real soon now */ + return; + } + /* zero it out */ + memset(qq, 0, sizeof(struct qent)*qlen); } static SDL_Thread *midi_queue_thread = NULL; static int _midi_queue_run(UNUSED void *xtop) { - int i; + int i; #ifdef WIN32 - __win32_pick_usleep(); - SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); - SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL); - /*SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);*/ + __win32_pick_usleep(); + SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL); + /*SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);*/ #endif - SDL_mutexP(midi_play_mutex); - for (;;) { - SDL_CondWait(midi_play_cond, midi_play_mutex); - - for (i = 0; i < qlen; i++) { - SDL_mutexP(midi_record_mutex); - _midi_send_unlocked(qq[i].b, qq[i].used, 0, 1); - SDL_mutexV(midi_record_mutex); - SLEEP_FUNC(10000); /* 10msec */ - qq[i].used = 0; - } - } + SDL_mutexP(midi_play_mutex); + for (;;) { + SDL_CondWait(midi_play_cond, midi_play_mutex); + + for (i = 0; i < qlen; i++) { + SDL_mutexP(midi_record_mutex); + _midi_send_unlocked(qq[i].b, qq[i].used, 0, 1); + SDL_mutexV(midi_record_mutex); + SLEEP_FUNC(10000); /* 10msec */ + qq[i].used = 0; + } + } - return 0; /* never happens */ + return 0; /* never happens */ } int midi_need_flush(void) { - struct midi_port *ptr; - int need_explicit_flush = 0; - int i; - - if (!midi_record_mutex || !midi_play_mutex) return 0; - - ptr = NULL; - - while (midi_port_foreach(NULL, &ptr)) { - if ((ptr->io & MIDI_OUTPUT)) { - if (!ptr->drain && ptr->send_now) - need_explicit_flush = 1; - } - } - if (!need_explicit_flush) return 0; - - for (i = 0; i < qlen; i++) { - if (qq[i].used) return 1; - } + struct midi_port *ptr; + int need_explicit_flush = 0; + int i; + + if (!midi_record_mutex || !midi_play_mutex) return 0; + + ptr = NULL; + + while (midi_port_foreach(NULL, &ptr)) { + if ((ptr->io & MIDI_OUTPUT)) { + if (!ptr->drain && ptr->send_now) + need_explicit_flush = 1; + } + } + if (!need_explicit_flush) return 0; + + for (i = 0; i < qlen; i++) { + if (qq[i].used) return 1; + } - return 0; + return 0; } void midi_send_flush(void) { - struct midi_port *ptr = NULL; - int need_explicit_flush = 0; + struct midi_port *ptr = NULL; + int need_explicit_flush = 0; - if (!midi_record_mutex || !midi_play_mutex) return; + if (!midi_record_mutex || !midi_play_mutex) return; - while (midi_port_foreach(NULL, &ptr)) { - if ((ptr->io & MIDI_OUTPUT)) { - if (ptr->drain) ptr->drain(ptr); - else if (ptr->send_now) need_explicit_flush=1; - } - } - - /* no need for midi sync huzzah; driver does it for us... */ - if (!need_explicit_flush) return; - - if (!midi_queue_thread) { - midi_queue_thread = SDL_CreateThread(_midi_queue_run, NULL); - if (midi_queue_thread) { - log_appendf(3, "Started MIDI queue thread"); - } else { - log_appendf(2, "ACK: Couldn't start MIDI thread; things are likely going to go boom!"); - } - } - - SDL_mutexP(midi_play_mutex); - SDL_CondSignal(midi_play_cond); - SDL_mutexV(midi_play_mutex); + while (midi_port_foreach(NULL, &ptr)) { + if ((ptr->io & MIDI_OUTPUT)) { + if (ptr->drain) ptr->drain(ptr); + else if (ptr->send_now) need_explicit_flush=1; + } + } + + /* no need for midi sync huzzah; driver does it for us... */ + if (!need_explicit_flush) return; + + if (!midi_queue_thread) { + midi_queue_thread = SDL_CreateThread(_midi_queue_run, NULL); + if (midi_queue_thread) { + log_appendf(3, "Started MIDI queue thread"); + } else { + log_appendf(2, "ACK: Couldn't start MIDI thread; things are likely going to go boom!"); + } + } + + SDL_mutexP(midi_play_mutex); + SDL_CondSignal(midi_play_cond); + SDL_mutexV(midi_play_mutex); } void midi_send_buffer(const unsigned char *data, unsigned int len, unsigned int pos) { - if (!midi_record_mutex) return; + if (!midi_record_mutex) return; - SDL_mutexP(midi_record_mutex); + SDL_mutexP(midi_record_mutex); - /* just for fun... */ - if (status.current_page == PAGE_MIDI) { - status.last_midi_real_len = len; - if (len > sizeof(status.last_midi_event)) { - status.last_midi_len = sizeof(status.last_midi_event); - } else { - status.last_midi_len = len; - } - memcpy(status.last_midi_event, data, status.last_midi_len); - status.flags |= MIDI_EVENT_CHANGED; - status.last_midi_port = NULL; - time(&status.last_midi_time); - status.flags |= NEED_UPDATE; - } - - /* pos is still in miliseconds */ - if (midims != 0 && _midi_send_unlocked(data, len, pos/midims, 2)) { - /* grr, we need a timer */ - - /* calculate pos in buffer */ - pos /= ms10s; - assert(((unsigned)pos) < ((unsigned)qlen)); - - if ((len + qq[pos].used) > sizeof(qq[pos].b)) { - len = sizeof(qq[pos].b) - qq[pos].used; - /* okay, we're going to lose data here */ - } - memcpy(qq[pos].b+qq[pos].used, data, len); - qq[pos].used += len; - } + /* just for fun... */ + if (status.current_page == PAGE_MIDI) { + status.last_midi_real_len = len; + if (len > sizeof(status.last_midi_event)) { + status.last_midi_len = sizeof(status.last_midi_event); + } else { + status.last_midi_len = len; + } + memcpy(status.last_midi_event, data, status.last_midi_len); + status.flags |= MIDI_EVENT_CHANGED; + status.last_midi_port = NULL; + time(&status.last_midi_time); + status.flags |= NEED_UPDATE; + } + + /* pos is still in miliseconds */ + if (midims != 0 && _midi_send_unlocked(data, len, pos/midims, 2)) { + /* grr, we need a timer */ + + /* calculate pos in buffer */ + pos /= ms10s; + assert(((unsigned)pos) < ((unsigned)qlen)); + + if ((len + qq[pos].used) > sizeof(qq[pos].b)) { + len = sizeof(qq[pos].b) - qq[pos].used; + /* okay, we're going to lose data here */ + } + memcpy(qq[pos].b+qq[pos].used, data, len); + qq[pos].used += len; + } - SDL_mutexV(midi_record_mutex); + SDL_mutexV(midi_record_mutex); } /*----------------------------------------------------------------------------------*/ void midi_port_unregister(int num) { - struct midi_port *q; - int i; + struct midi_port *q; + int i; - if (!midi_port_mutex) return; + if (!midi_port_mutex) return; - SDL_mutexP(midi_port_mutex); - for (i = 0; i < port_alloc; i++) { - if (port_top[i] && port_top[i]->num == num) { - q = port_top[i]; - if (q->disable) q->disable(q); - if (q->free_userdata) free(q->userdata); - free(q); - - port_top[i] = NULL; - port_count--; - break; - } - } - SDL_mutexV(midi_port_mutex); + SDL_mutexP(midi_port_mutex); + for (i = 0; i < port_alloc; i++) { + if (port_top[i] && port_top[i]->num == num) { + q = port_top[i]; + if (q->disable) q->disable(q); + if (q->free_userdata) free(q->userdata); + free(q); + + port_top[i] = NULL; + port_count--; + break; + } + } + SDL_mutexV(midi_port_mutex); } void midi_received_cb(struct midi_port *src, unsigned char *data, unsigned int len) { - unsigned char d4[4]; - int cmd; + unsigned char d4[4]; + int cmd; - if (!len) return; - if (len < 4) { - memset(d4, 0, sizeof(d4)); - memcpy(d4, data, len); - data = d4; - } - - /* just for fun... */ - SDL_mutexP(midi_record_mutex); - status.last_midi_real_len = len; - if (len > sizeof(status.last_midi_event)) { - status.last_midi_len = sizeof(status.last_midi_event); - } else { - status.last_midi_len = len; - } - memcpy(status.last_midi_event, data, status.last_midi_len); - status.flags |= MIDI_EVENT_CHANGED; - status.last_midi_port = src; - time(&status.last_midi_time); - SDL_mutexV(midi_record_mutex); - - /* pass through midi events when on midi page */ - if (status.current_page == PAGE_MIDI) { - midi_send_now(data,len); - status.flags |= NEED_UPDATE; - } - - cmd = ((*data) & 0xF0) >> 4; - if (cmd == 0x8 || (cmd == 0x9 && data[2] == 0)) { - midi_event_note(MIDI_NOTEOFF, data[0] & 15, data[1], 0); - } else if (cmd == 0x9) { - midi_event_note(MIDI_NOTEON, data[0] & 15, data[1], data[2]); - } else if (cmd == 0xA) { - midi_event_note(MIDI_KEYPRESS, data[0] & 15, data[1], data[2]); - } else if (cmd == 0xB) { - midi_event_controller(data[0] & 15, data[1], data[2]); - } else if (cmd == 0xC) { - midi_event_program(data[0] & 15, data[1]); - } else if (cmd == 0xD) { - midi_event_aftertouch(data[0] & 15, data[1]); - } else if (cmd == 0xE) { - midi_event_pitchbend(data[0] & 15, data[1]); - } else if (cmd == 0xF) { - switch ((*data & 15)) { - case 0: /* sysex */ - if (len <= 2) return; - midi_event_sysex(data+1, len-2); - break; - case 6: /* tick */ - midi_event_tick(); - break; - default: - /* something else */ - midi_event_system((*data & 15), (data[1]) - | (data[2] << 8) - | (data[3] << 16)); - break; - } - } + if (!len) return; + if (len < 4) { + memset(d4, 0, sizeof(d4)); + memcpy(d4, data, len); + data = d4; + } + + /* just for fun... */ + SDL_mutexP(midi_record_mutex); + status.last_midi_real_len = len; + if (len > sizeof(status.last_midi_event)) { + status.last_midi_len = sizeof(status.last_midi_event); + } else { + status.last_midi_len = len; + } + memcpy(status.last_midi_event, data, status.last_midi_len); + status.flags |= MIDI_EVENT_CHANGED; + status.last_midi_port = src; + time(&status.last_midi_time); + SDL_mutexV(midi_record_mutex); + + /* pass through midi events when on midi page */ + if (status.current_page == PAGE_MIDI) { + midi_send_now(data,len); + status.flags |= NEED_UPDATE; + } + + cmd = ((*data) & 0xF0) >> 4; + if (cmd == 0x8 || (cmd == 0x9 && data[2] == 0)) { + midi_event_note(MIDI_NOTEOFF, data[0] & 15, data[1], 0); + } else if (cmd == 0x9) { + midi_event_note(MIDI_NOTEON, data[0] & 15, data[1], data[2]); + } else if (cmd == 0xA) { + midi_event_note(MIDI_KEYPRESS, data[0] & 15, data[1], data[2]); + } else if (cmd == 0xB) { + midi_event_controller(data[0] & 15, data[1], data[2]); + } else if (cmd == 0xC) { + midi_event_program(data[0] & 15, data[1]); + } else if (cmd == 0xD) { + midi_event_aftertouch(data[0] & 15, data[1]); + } else if (cmd == 0xE) { + midi_event_pitchbend(data[0] & 15, data[1]); + } else if (cmd == 0xF) { + switch ((*data & 15)) { + case 0: /* sysex */ + if (len <= 2) return; + midi_event_sysex(data+1, len-2); + break; + case 6: /* tick */ + midi_event_tick(); + break; + default: + /* something else */ + midi_event_system((*data & 15), (data[1]) + | (data[2] << 8) + | (data[3] << 16)); + break; + } + } } void midi_event_note(enum midi_note mnstatus, int channel, int note, int velocity) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = mnstatus; - st[1] = channel; - st[2] = note; - st[3] = velocity; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_NOTE; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = mnstatus; + st[1] = channel; + st[2] = note; + st[3] = velocity; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_NOTE; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_controller(int channel, int param, int value) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = value; - st[1] = channel; - st[2] = param; - st[3] = 0; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_CONTROLLER; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = value; + st[1] = channel; + st[2] = param; + st[3] = 0; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_CONTROLLER; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_program(int channel, int value) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = value; - st[1] = channel; - st[2] = 0; - st[3] = 0; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_PROGRAM; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = value; + st[1] = channel; + st[2] = 0; + st[3] = 0; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_PROGRAM; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_aftertouch(int channel, int value) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = value; - st[1] = channel; - st[2] = 0; - st[3] = 0; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_AFTERTOUCH; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = value; + st[1] = channel; + st[2] = 0; + st[3] = 0; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_AFTERTOUCH; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_pitchbend(int channel, int value) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = value; - st[1] = channel; - st[2] = 0; - st[3] = 0; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_PITCHBEND; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = value; + st[1] = channel; + st[2] = 0; + st[3] = 0; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_PITCHBEND; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_system(int argv, int param) { - int *st; - SDL_Event e; + int *st; + SDL_Event e; - st = mem_alloc(sizeof(int)*4); - st[0] = argv; - st[1] = param; - st[2] = 0; - st[3] = 0; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_SYSTEM; - e.user.data1 = st; - e.user.data2 = NULL; - SDL_PushEvent(&e); + st = mem_alloc(sizeof(int)*4); + st[0] = argv; + st[1] = param; + st[2] = 0; + st[3] = 0; + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_SYSTEM; + e.user.data1 = st; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_tick(void) { - SDL_Event e; + SDL_Event e; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_TICK; - e.user.data1 = NULL; - e.user.data2 = NULL; - SDL_PushEvent(&e); + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_TICK; + e.user.data1 = NULL; + e.user.data2 = NULL; + SDL_PushEvent(&e); } void midi_event_sysex(const unsigned char *data, unsigned int len) { - SDL_Event e; + SDL_Event e; - e.user.type = SCHISM_EVENT_MIDI; - e.user.code = SCHISM_EVENT_MIDI_SYSEX; - e.user.data1 = mem_alloc(len+sizeof(len)); - memcpy(e.user.data1, &len, sizeof(len)); - memcpy(e.user.data1+sizeof(len), data, len); - e.user.data2 = NULL; - SDL_PushEvent(&e); + e.user.type = SCHISM_EVENT_MIDI; + e.user.code = SCHISM_EVENT_MIDI_SYSEX; + e.user.data1 = mem_alloc(len+sizeof(len)); + memcpy(e.user.data1, &len, sizeof(len)); + memcpy(e.user.data1+sizeof(len), data, len); + e.user.data2 = NULL; + SDL_PushEvent(&e); } int midi_engine_handle_event(void *ev) { - struct key_event kk = {.is_synthetic = 0}; - unsigned int len; - char *sysex; - int *st; - SDL_Event *e = ev; - - if (e->type != SCHISM_EVENT_MIDI) - return 0; - - st = e->user.data1; - if (midi_flags & MIDI_DISABLE_RECORD) { - free(e->user.data1); - return 1; - } - - switch (e->user.code) { - case SCHISM_EVENT_MIDI_NOTE: - if (st[0] == MIDI_NOTEON) { - kk.state = 0; - } else { - if (!(midi_flags & MIDI_RECORD_NOTEOFF)) { - /* don't record noteoff? okay... */ - break; - } - kk.state = 1; - } - kk.midi_channel = st[1]+1; - kk.midi_note = (st[2]+1 + midi_c5note) - 60; - if (midi_flags & MIDI_RECORD_VELOCITY) - kk.midi_volume = st[3]; - else - kk.midi_volume = 128; - kk.midi_volume = (kk.midi_volume * midi_amplification) / 100; - handle_key(&kk); - break; - case SCHISM_EVENT_MIDI_PITCHBEND: - /* wheel */ - kk.midi_channel = st[1]+1; - kk.midi_volume = -1; - kk.midi_note = -1; - kk.midi_bend = st[0]; - handle_key(&kk); - break; - case SCHISM_EVENT_MIDI_CONTROLLER: - /* controller events */ - break; - case SCHISM_EVENT_MIDI_SYSTEM: - switch (st[0]) { - case 0x8: /* MIDI tick */ - break; - case 0xA: /* MIDI start */ - case 0xB: /* MIDI continue */ - song_start(); - break; - case 0xC: /* MIDI stop */ - case 0xF: /* MIDI reset */ - /* this is helpful when miditracking */ - song_stop(); - break; - }; - case SCHISM_EVENT_MIDI_SYSEX: - /* but missing the F0 and the stop byte (F7) */ - len = *((unsigned int *)e->user.data1); - sysex = ((char *)e->user.data1)+sizeof(unsigned int); - break; - - default: - break; - } - free(e->user.data1); + struct key_event kk = {.is_synthetic = 0}; + int *st; + SDL_Event *e = ev; + + if (e->type != SCHISM_EVENT_MIDI) + return 0; + + st = e->user.data1; + if (midi_flags & MIDI_DISABLE_RECORD) { + free(e->user.data1); + return 1; + } + + switch (e->user.code) { + case SCHISM_EVENT_MIDI_NOTE: + if (st[0] == MIDI_NOTEON) { + kk.state = KEY_PRESS; + } else { + if (!(midi_flags & MIDI_RECORD_NOTEOFF)) { + /* don't record noteoff? okay... */ + break; + } + kk.state = KEY_RELEASE; + } + kk.midi_channel = st[1]+1; + kk.midi_note = (st[2]+1 + midi_c5note) - 60; + if (midi_flags & MIDI_RECORD_VELOCITY) + kk.midi_volume = st[3]; + else + kk.midi_volume = 128; + kk.midi_volume = (kk.midi_volume * midi_amplification) / 100; + handle_key(&kk); + break; + case SCHISM_EVENT_MIDI_PITCHBEND: + /* wheel */ + kk.midi_channel = st[1]+1; + kk.midi_volume = -1; + kk.midi_note = -1; + kk.midi_bend = st[0]; + handle_key(&kk); + break; + case SCHISM_EVENT_MIDI_CONTROLLER: + /* controller events */ + break; + case SCHISM_EVENT_MIDI_SYSTEM: + switch (st[0]) { + case 0x8: /* MIDI tick */ + break; + case 0xA: /* MIDI start */ + case 0xB: /* MIDI continue */ + song_start(); + break; + case 0xC: /* MIDI stop */ + case 0xF: /* MIDI reset */ + /* this is helpful when miditracking */ + song_stop(); + break; + }; + case SCHISM_EVENT_MIDI_SYSEX: + /* but missing the F0 and the stop byte (F7) */ + //len = *((unsigned int *)e->user.data1); + //sysex = ((char *)e->user.data1)+sizeof(unsigned int); + break; + + default: + break; + } + free(e->user.data1); - return 1; + return 1; } diff -Nru schism-0+20110101/schism/midi-ip.c schism-20160521/schism/midi-ip.c --- schism-0+20110101/schism/midi-ip.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/midi-ip.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -59,366 +59,421 @@ static void do_wake_main(void) { - /* send at end */ - SDL_Event e; - e.user.type = SCHISM_EVENT_UPDATE_IPMIDI; - e.user.code = 0; - e.user.data1 = NULL; - e.user.data2 = NULL; - SDL_PushEvent(&e); + /* send at end */ + SDL_Event e; + e.user.type = SCHISM_EVENT_UPDATE_IPMIDI; + e.user.code = 0; + e.user.data1 = NULL; + e.user.data2 = NULL; + SDL_PushEvent(&e); } static void do_wake_midi(void) { #ifdef WIN32 - /* anyone want to suggest how this is done? XXX */ + /* anyone want to suggest how this is done? XXX */ #else - if (write(wakeup[1], "\x1", 1) == 1) { - /* fortify is stupid */ - } + if (write(wakeup[1], "\x1", 1) == 1) { + /* fortify is stupid */ + } #endif } static int _get_fd(int pb, int isout) { - struct ip_mreq mreq; - struct sockaddr_in asin; - unsigned char *ipcopy; - int fd, opt; + struct ip_mreq mreq; + struct sockaddr_in asin; + unsigned char *ipcopy; + int fd, opt; #if !defined(PF_INET) && defined(AF_INET) #define PF_INET AF_INET #endif - fd = socket(PF_INET, SOCK_DGRAM, 0); - if (fd == -1) return -1; + fd = socket(PF_INET, SOCK_DGRAM, 0); + if (fd == -1) return -1; - opt = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(int)); + opt = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(int)); - /* don't loop back what we generate */ - opt = !isout; - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&opt, sizeof(opt)) < 0) { + /* don't loop back what we generate */ + opt = !isout; + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&opt, sizeof(opt)) < 0) { #ifdef WIN32 - closesocket(fd); + closesocket(fd); +#else + close(fd); #endif - close(fd); - return -1; - } + return -1; + } - opt = 31; - if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&opt, sizeof(opt)) < 0) { + opt = 31; + if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&opt, sizeof(opt)) < 0) { #ifdef WIN32 - closesocket(fd); + closesocket(fd); +#else + close(fd); #endif - close(fd); - return -1; - } + return -1; + } - memset(&mreq, 0, sizeof(mreq)); - ipcopy = (unsigned char *)&mreq.imr_multiaddr; - ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; - if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq, sizeof(mreq)) < 0) { + memset(&mreq, 0, sizeof(mreq)); + ipcopy = (unsigned char *)&mreq.imr_multiaddr; + ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; + if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&mreq, sizeof(mreq)) < 0) { #ifdef WIN32 - closesocket(fd); + closesocket(fd); +#else + close(fd); #endif - close(fd); - return -1; - } + return -1; + } - opt = 1; - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&opt, sizeof(opt)) < 0) { + opt = 1; + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (void*)&opt, sizeof(opt)) < 0) { #ifdef WIN32 - closesocket(fd); + closesocket(fd); +#else + close(fd); #endif - close(fd); - return -1; - } + return -1; + } - memset(&asin, 0, sizeof(asin)); - asin.sin_family = AF_INET; - ipcopy = (unsigned char *)&asin.sin_addr; - if (!isout) { - /* all 0s is inaddr_any; but this is for listening */ - ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; - asin.sin_port = htons(MIDI_IP_BASE+pb); - } - if (bind(fd, (struct sockaddr *)&asin, sizeof(asin)) < 0) { -#ifdef WIN32 - closesocket(fd); + memset(&asin, 0, sizeof(asin)); + asin.sin_family = AF_INET; + ipcopy = (unsigned char *)&asin.sin_addr; + if (!isout) { + /* all 0s is inaddr_any; but this is for listening */ +#ifdef WIN32 + //JosepMa:On my machine, using the 225.0.0.37 address caused bind to fail. + //Didn't look too much to find why. + ipcopy[0] = ipcopy[1] = ipcopy[2] = ipcopy[3] = 0; +#else + ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; +#endif + asin.sin_port = htons(MIDI_IP_BASE+pb); + } + if (bind(fd, (struct sockaddr *)&asin, sizeof(asin)) < 0) { +#ifdef WIN32 + + int asdf = WSAGetLastError(); + perror("binderror"); + switch(asdf) { + case WSANOTINITIALISED: perror("WSANOTINITIALISED");break; + case WSAENETDOWN: perror("WSAENETDOWN");break; + case WSAEFAULT: perror("WSAEFAULT");break; + case WSAEINVAL: perror("WSAEINVAL");break; + case WSAEINPROGRESS: perror("WSAEINPROGRESS");break; + case WSAENOTSOCK: perror("WSAENOTSOCK");break; + case WSAEACCES: perror("WSAEACCES");break; + case WSAEADDRINUSE: perror("WSAEADDRINUSE");break; + case WSAEADDRNOTAVAIL: perror("WSAEADDRNOTAVAIL");break; + case WSAENOBUFS: perror("WSAENOBUFS");break; + default: perror("default");break; + } + closesocket(fd); +#else + close(fd); #endif - close(fd); - return -1; - } + return -1; + } - return fd; + return fd; } void ip_midi_setports(int n) { - if (out_fd == -1) return; - if (status.flags & NO_NETWORK) return; + if (out_fd == -1) return; + if (status.flags & NO_NETWORK) return; - SDL_mutexP(blocker); - num_ports = n; - SDL_mutexV(blocker); - do_wake_midi(); + SDL_mutexP(blocker); + num_ports = n; + SDL_mutexV(blocker); + do_wake_midi(); } static void _readin(struct midi_provider *p, int en, int fd) { - struct midi_port *ptr, *src; - static unsigned char buffer[65536]; - static struct sockaddr_in asin; - unsigned slen = sizeof(asin); - int r; - - r = recvfrom(fd, buffer, sizeof(buffer), 0, - (struct sockaddr *)&asin, &slen); - if (r > 0) { - ptr = src = NULL; - while (midi_port_foreach(p, &ptr)) { - int n = INT_SHAPED_PTR(ptr->userdata); - if (n == en) src = ptr; - } - midi_received_cb(src, buffer, r); - } + struct midi_port *ptr, *src; + static unsigned char buffer[65536]; + static struct sockaddr_in asin; + unsigned slen = sizeof(asin); + int r; + + r = recvfrom(fd, buffer, sizeof(buffer), 0, + (struct sockaddr *)&asin, &slen); + if (r > 0) { + ptr = src = NULL; + while (midi_port_foreach(p, &ptr)) { + int n = INT_SHAPED_PTR(ptr->userdata); + if (n == en) src = ptr; + } + midi_received_cb(src, buffer, r); + } } static int _ip_thread(struct midi_provider *p) { #ifdef WIN32 - struct timeval tv; + struct timeval tv; +#else + static unsigned char buffer[4096]; +#endif + fd_set rfds; + int *tmp2, *tmp; + int i, m; + + for (;;) { + SDL_mutexP(blocker); + m = (volatile int)num_ports; + //If no ports, wait and try again + if (m > real_num_ports) { + /* need more ports */ + tmp = malloc(2 * (m * sizeof(int))); + if (tmp) { + tmp2 = tmp + m; + for (i = 0; i < real_num_ports; i++) { + tmp[i] = port_fd[i]; + tmp2[i] = state[i]; + } + free(port_fd); + + port_fd = tmp; + state = tmp2; + + for (i = real_num_ports; i < m; i++) { + state[i] = 0; + if ((port_fd[i] = _get_fd(i,0)) == -1) { + m = i+1; + break; + } + } + real_num_ports = num_ports = m; + } + SDL_mutexV(blocker); + do_wake_main(); + + } else if (m < real_num_ports) { + for (i = m; i < real_num_ports; i++) { +#ifdef WIN32 + closesocket(port_fd[i]); #else - static unsigned char buffer[4096]; + close(port_fd[i]); #endif - fd_set rfds; - int *tmp2, *tmp; - int i, m; - - for (;;) { - SDL_mutexP(blocker); - m = (volatile int)num_ports; - if (m > real_num_ports) { - /* need more ports */ - tmp = malloc(2 * (m * sizeof(int))); - if (tmp) { - tmp2 = tmp + m; - for (i = 0; i < real_num_ports; i++) { - tmp[i] = port_fd[i]; - tmp2[i] = state[i]; - } - free(port_fd); - - port_fd = tmp; - state = tmp2; - - for (i = real_num_ports; i < m; i++) { - state[i] = 0; - if ((port_fd[i] = _get_fd(i,0)) == -1) { - m = i+1; - break; - } - } - real_num_ports = num_ports = m; - } - SDL_mutexV(blocker); - do_wake_main(); - - } else if (m < real_num_ports) { - for (i = m; i < real_num_ports; i++) { -#ifdef WIN32 - closesocket(port_fd[i]); -#endif - close(port_fd[i]); - port_fd[i] = -1; - } - real_num_ports = num_ports = m; - - SDL_mutexV(blocker); - do_wake_main(); - } else { - SDL_mutexV(blocker); - } - - FD_ZERO(&rfds); - m = 0; - for (i = 0; i < real_num_ports; i++) { - FD_SET(port_fd[i], &rfds); - if (port_fd[i] > m) m = port_fd[i]; - } - -#ifdef WIN32 - tv.tv_sec = 1; - tv.tv_usec = 0; -#else - FD_SET(wakeup[0], &rfds); - if (wakeup[0] > m) m = wakeup[0]; -#endif - do { - i = select(m+1, &rfds, NULL, NULL, + port_fd[i] = -1; + } + real_num_ports = num_ports = m; + + SDL_mutexV(blocker); + do_wake_main(); + } else { + SDL_mutexV(blocker); + if (!real_num_ports) { + //Since the thread is not finished in this case (maybe it should), + //we put a delay to prevent the thread using all the cpu. + SDL_Delay(1000); + } + } + + FD_ZERO(&rfds); + m = 0; + for (i = 0; i < real_num_ports; i++) { + FD_SET(port_fd[i], &rfds); + if (port_fd[i] > m) m = port_fd[i]; + } + #ifdef WIN32 - &tv + tv.tv_sec = 1; + tv.tv_usec = 0; #else - NULL + FD_SET(wakeup[0], &rfds); + if (wakeup[0] > m) m = wakeup[0]; +#endif + do { + i = select(m+1, &rfds, NULL, NULL, +#ifdef WIN32 + &tv +#else + NULL +#endif + ); +#ifdef WIN32 + if (i == SOCKET_ERROR ) { + perror("selectError:"); + int asdf = WSAGetLastError(); + switch(asdf) { + case WSANOTINITIALISED: perror("WSANOTINITIALISED");break; + case WSAEFAULT: perror("WSAEFAULT");break; + case WSAENETDOWN: perror("WSAENETDOWN");break; + case WSAEINVAL: perror("WSAEINVAL");break; + case WSAEINTR: perror("WSAEINTR");break; + case WSAEINPROGRESS: perror("WSAEINPROGRESS");break; + case WSAENOTSOCK: perror("WSAENOTSOCK");break; + default: perror("default");break; + } + } #endif - ); - } while (i == -1 && errno == EINTR); + } while (i == -1 && errno == EINTR); #ifndef WIN32 - if (FD_ISSET(wakeup[0], &rfds)) { - if (read(wakeup[0], buffer, sizeof(buffer)) == -1) { - /* fortify is stupid */ - } - } -#endif - for (i = 0; i < real_num_ports; i++) { - if (FD_ISSET(port_fd[i], &rfds)) { - if (state[i] & 1) _readin(p, i, port_fd[i]); - } - } - } - return 0; + if (FD_ISSET(wakeup[0], &rfds)) { + if (read(wakeup[0], buffer, sizeof(buffer)) == -1) { + /* fortify is stupid */ + } + } +#endif + for (i = 0; i < real_num_ports; i++) { + if (FD_ISSET(port_fd[i], &rfds)) { + if (state[i] & 1) _readin(p, i, port_fd[i]); + } + } + } + return 0; } static int _ip_start(struct midi_port *p) { - int n = INT_SHAPED_PTR(p->userdata); - SDL_mutexP(blocker); - if (p->io & MIDI_INPUT) - state[n] |= 1; - if (p->io & MIDI_OUTPUT) - state[n] |= 2; - SDL_mutexV(blocker); - do_wake_midi(); - return 1; + int n = INT_SHAPED_PTR(p->userdata); + SDL_mutexP(blocker); + if (p->io & MIDI_INPUT) + state[n] |= 1; + if (p->io & MIDI_OUTPUT) + state[n] |= 2; + SDL_mutexV(blocker); + do_wake_midi(); + return 1; } static int _ip_stop(struct midi_port *p) { - int n = INT_SHAPED_PTR(p->userdata); - SDL_mutexP(blocker); - if (p->io & MIDI_INPUT) - state[n] &= (~1); - if (p->io & MIDI_OUTPUT) - state[n] &= (~2); - SDL_mutexV(blocker); - do_wake_midi(); - return 1; + int n = INT_SHAPED_PTR(p->userdata); + SDL_mutexP(blocker); + if (p->io & MIDI_INPUT) + state[n] &= (~1); + if (p->io & MIDI_OUTPUT) + state[n] &= (~2); + SDL_mutexV(blocker); + do_wake_midi(); + return 1; } static void _ip_send(struct midi_port *p, const unsigned char *data, unsigned int len, - UNUSED unsigned int delay) + UNUSED unsigned int delay) { - struct sockaddr_in asin; - unsigned char *ipcopy; - int n = INT_SHAPED_PTR(p->userdata); - int ss; - - if (len == 0) return; - if (!(state[n] & 2)) return; /* blah... */ - - memset(&asin, 0, sizeof(asin)); - asin.sin_family = AF_INET; - ipcopy = (unsigned char *)&asin.sin_addr.s_addr; - ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; - asin.sin_port = htons(MIDI_IP_BASE+n); - - while (len) { - ss = (len > MAX_DGRAM_SIZE) ? MAX_DGRAM_SIZE : len; - if (sendto(out_fd, data, ss, 0, - (struct sockaddr *)&asin,sizeof(asin)) < 0) { - state[n] &= (~2); /* turn off output */ - break; - } - len -= ss; - data += ss; - } + struct sockaddr_in asin; + unsigned char *ipcopy; + int n = INT_SHAPED_PTR(p->userdata); + int ss; + + if (len == 0) return; + if (!(state[n] & 2)) return; /* blah... */ + + memset(&asin, 0, sizeof(asin)); + asin.sin_family = AF_INET; + ipcopy = (unsigned char *)&asin.sin_addr.s_addr; + ipcopy[0] = 225; ipcopy[1] = ipcopy[2] = 0; ipcopy[3] = 37; + asin.sin_port = htons(MIDI_IP_BASE+n); + + while (len) { + ss = (len > MAX_DGRAM_SIZE) ? MAX_DGRAM_SIZE : len; + if (sendto(out_fd, data, ss, 0, + (struct sockaddr *)&asin,sizeof(asin)) < 0) { + state[n] &= (~2); /* turn off output */ + break; + } + len -= ss; + data += ss; + } } static void _ip_poll(struct midi_provider *p) { - static int last_buildout = 0; - struct midi_port *ptr; - char *buffer; - long i = 0; - long m; - - SDL_mutexP(blocker); - m = (volatile int)real_num_ports; - if (m < last_buildout) { - ptr = NULL; - while (midi_port_foreach(p, &ptr)) { - i = INT_SHAPED_PTR(ptr->userdata); - if (i >= m) midi_port_unregister(ptr->num); - } - last_buildout = m; - } else if (m > last_buildout) { - for (i = last_buildout; i < m; i++) { - buffer = NULL; - if (asprintf(&buffer, " Multicast/IP MIDI %lu", i+1) == -1) { - perror("asprintf"); - exit(255); - } - if (!buffer) { - perror("asprintf"); - exit(255); - } - midi_port_register(p, MIDI_INPUT | MIDI_OUTPUT, buffer, - PTR_SHAPED_INT(i), 0); - } - last_buildout = m; - } - SDL_mutexV(blocker); + static int last_buildout = 0; + struct midi_port *ptr; + char *buffer; + long i = 0; + long m; + + SDL_mutexP(blocker); + m = (volatile int)real_num_ports; + if (m < last_buildout) { + ptr = NULL; + while (midi_port_foreach(p, &ptr)) { + i = INT_SHAPED_PTR(ptr->userdata); + if (i >= m) { + midi_port_unregister(ptr->num); + //port_top[i] (the address where ptr points to) is freed in midi_port_unregister. + //So clear it to avoid midi_port_foreach crashing on next round + ptr = NULL; + } + } + last_buildout = m; + } else if (m > last_buildout) { + for (i = last_buildout; i < m; i++) { + buffer = NULL; + if (asprintf(&buffer, " Multicast/IP MIDI %lu", i+1) == -1) { + perror("asprintf"); + exit(255); + } + if (!buffer) { + perror("asprintf"); + exit(255); + } + midi_port_register(p, MIDI_INPUT | MIDI_OUTPUT, buffer, + PTR_SHAPED_INT((intptr_t)i), 0); + } + last_buildout = m; + } + SDL_mutexV(blocker); } int ip_midi_setup(void) { - static struct midi_driver driver; + static struct midi_driver driver; - if (status.flags & NO_NETWORK) return 0; + if (status.flags & NO_NETWORK) return 0; - blocker = SDL_CreateMutex(); - if (!blocker) { - return 0; - } + blocker = SDL_CreateMutex(); + if (!blocker) { + return 0; + } #ifndef WIN32 - if (pipe(wakeup) == -1) { - return 0; - } - fcntl(wakeup[0], F_SETFL, fcntl(wakeup[0], F_GETFL, 0) | O_NONBLOCK); - fcntl(wakeup[1], F_SETFL, fcntl(wakeup[1], F_GETFL, 0) | O_NONBLOCK); -#endif - - if (out_fd == -1) { - out_fd = _get_fd(-1, 1); - if (out_fd == -1) return 0; - } - - ip_midi_setports(DEFAULT_IP_PORT_COUNT); - - driver.flags = 0; - driver.poll = _ip_poll; - driver.thread = _ip_thread; - driver.send = _ip_send; - driver.enable = _ip_start; - driver.disable = _ip_stop; + if (pipe(wakeup) == -1) { + return 0; + } + fcntl(wakeup[0], F_SETFL, fcntl(wakeup[0], F_GETFL, 0) | O_NONBLOCK); + fcntl(wakeup[1], F_SETFL, fcntl(wakeup[1], F_GETFL, 0) | O_NONBLOCK); +#endif + + if (out_fd == -1) { + out_fd = _get_fd(-1, 1); + if (out_fd == -1) return 0; + } + + driver.flags = 0; + driver.poll = _ip_poll; + driver.thread = _ip_thread; + driver.send = _ip_send; + driver.enable = _ip_start; + driver.disable = _ip_stop; + //TODO: Save number of MIDI-IP ports + ip_midi_setports(DEFAULT_IP_PORT_COUNT); - if (!midi_provider_register("IP", &driver)) return 0; - return 1; + if (!midi_provider_register("IP", &driver)) return 0; + return 1; } int ip_midi_getports(void) { - int tmp; + int tmp; - if (out_fd == -1) return 0; - if (status.flags & NO_NETWORK) return 0; + if (out_fd == -1) return 0; + if (status.flags & NO_NETWORK) return 0; - SDL_mutexP(blocker); - tmp = (volatile int)real_num_ports; - SDL_mutexV(blocker); - return tmp; + SDL_mutexP(blocker); + tmp = (volatile int)real_num_ports; + SDL_mutexV(blocker); + return tmp; } #else int ip_midi_getports(void) { - return 0; + return 0; } void ip_midi_setports(UNUSED int n) diff -Nru schism-0+20110101/schism/mplink.c schism-20160521/schism/mplink.c --- schism-0+20110101/schism/mplink.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/mplink.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -42,84 +42,84 @@ unsigned int song_get_length_to(int order, int row) { - unsigned int t; + unsigned int t; - song_lock_audio(); - current_song->stop_at_order = order; - current_song->stop_at_row = row; - t = csf_get_length(current_song); - current_song->stop_at_order = current_song->stop_at_row = -1; - song_unlock_audio(); - return t; + song_lock_audio(); + current_song->stop_at_order = order; + current_song->stop_at_row = row; + t = csf_get_length(current_song); + current_song->stop_at_order = current_song->stop_at_row = -1; + song_unlock_audio(); + return t; } void song_get_at_time(unsigned int seconds, int *order, int *row) { - if (!seconds) { - if (order) *order = 0; - if (row) *row = 0; - } else { - song_lock_audio(); - current_song->stop_at_order = MAX_ORDERS; - current_song->stop_at_row = 255; /* unpossible */ - current_song->stop_at_time = seconds; - csf_get_length(current_song); - if (order) *order = current_song->stop_at_order; - if (row) *row = current_song->stop_at_row; - current_song->stop_at_order = current_song->stop_at_row = -1; - current_song->stop_at_time = 0; - song_unlock_audio(); - } + if (!seconds) { + if (order) *order = 0; + if (row) *row = 0; + } else { + song_lock_audio(); + current_song->stop_at_order = MAX_ORDERS; + current_song->stop_at_row = 255; /* unpossible */ + current_song->stop_at_time = seconds; + csf_get_length(current_song); + if (order) *order = current_song->stop_at_order; + if (row) *row = current_song->stop_at_row; + current_song->stop_at_order = current_song->stop_at_row = -1; + current_song->stop_at_time = 0; + song_unlock_audio(); + } } song_sample_t *song_get_sample(int n) { - if (n >= MAX_SAMPLES) - return NULL; - return current_song->samples + n; + if (n >= MAX_SAMPLES) + return NULL; + return current_song->samples + n; } song_instrument_t *song_get_instrument(int n) { - if (n >= MAX_INSTRUMENTS) - return NULL; + if (n >= MAX_INSTRUMENTS) + return NULL; - // Make a new instrument if it doesn't exist. - if (!current_song->instruments[n]) { - current_song->instruments[n] = csf_allocate_instrument(); - } + // Make a new instrument if it doesn't exist. + if (!current_song->instruments[n]) { + current_song->instruments[n] = csf_allocate_instrument(); + } - return (song_instrument_t *) current_song->instruments[n]; + return (song_instrument_t *) current_song->instruments[n]; } // this is a fairly gross way to do what should be such a simple thing int song_get_instrument_number(song_instrument_t *inst) { - if (inst) - for (int n = 1; n < MAX_INSTRUMENTS; n++) - if (inst == ((song_instrument_t *) current_song->instruments[n])) - return n; - return 0; + if (inst) + for (int n = 1; n < MAX_INSTRUMENTS; n++) + if (inst == ((song_instrument_t *) current_song->instruments[n])) + return n; + return 0; } song_channel_t *song_get_channel(int n) { - if (n >= MAX_CHANNELS) - return NULL; - return (song_channel_t *) current_song->channels + n; + if (n >= MAX_CHANNELS) + return NULL; + return (song_channel_t *) current_song->channels + n; } song_voice_t *song_get_mix_channel(int n) { - if (n >= MAX_VOICES) - return NULL; - return (song_voice_t *) current_song->voices + n; + if (n >= MAX_VOICES) + return NULL; + return (song_voice_t *) current_song->voices + n; } int song_get_mix_state(unsigned int **channel_list) { - if (channel_list) - *channel_list = current_song->voice_mix; - return MIN(current_song->num_voices, max_voices); + if (channel_list) + *channel_list = current_song->voice_mix; + return MIN(current_song->num_voices, max_voices); } // ------------------------------------------------------------------------ @@ -130,94 +130,94 @@ static inline void _save_state(int channel) { - channel_states[channel] = current_song->voices[channel].flags & CHN_MUTE; + channel_states[channel] = current_song->voices[channel].flags & CHN_MUTE; } void song_save_channel_states(void) { - int n = 64; + int n = 64; - while (n-- > 0) - _save_state(n); + while (n-- > 0) + _save_state(n); } static inline void _fix_mutes_like(int chan) { - int i; - for (i = 0; i < MAX_VOICES; i++) { - if (i == chan) continue; - if (((int)current_song->voices[i].master_channel) != (chan+1)) continue; - current_song->voices[i].flags = (current_song->voices[i].flags & (~(CHN_MUTE))) - | (current_song->voices[chan].flags & (CHN_MUTE)); - } + int i; + for (i = 0; i < MAX_VOICES; i++) { + if (i == chan) continue; + if (((int)current_song->voices[i].master_channel) != (chan+1)) continue; + current_song->voices[i].flags = (current_song->voices[i].flags & (~(CHN_MUTE))) + | (current_song->voices[chan].flags & (CHN_MUTE)); + } } void song_set_channel_mute(int channel, int muted) { - if (muted) { - current_song->channels[channel].flags |= CHN_MUTE; - current_song->voices[channel].flags |= CHN_MUTE; - } else { - current_song->channels[channel].flags &= ~CHN_MUTE; - current_song->voices[channel].flags &= ~CHN_MUTE; - _save_state(channel); - } - _fix_mutes_like(channel); + if (muted) { + current_song->channels[channel].flags |= CHN_MUTE; + current_song->voices[channel].flags |= CHN_MUTE; + } else { + current_song->channels[channel].flags &= ~CHN_MUTE; + current_song->voices[channel].flags &= ~CHN_MUTE; + _save_state(channel); + } + _fix_mutes_like(channel); } // I don't think this is useful besides undoing a channel solo (a few lines // below), but I'm making it extern anyway for symmetry. inline void song_restore_channel_states(void) { - int n = 64; + int n = 64; - while (n-- > 0) - song_set_channel_mute(n, channel_states[n]); + while (n-- > 0) + song_set_channel_mute(n, channel_states[n]); } void song_toggle_channel_mute(int channel) { - // i'm just going by the playing channel's state... - // if the actual channel is muted but not the playing one, - // tough luck :) - song_set_channel_mute(channel, (current_song->voices[channel].flags & CHN_MUTE) == 0); + // i'm just going by the playing channel's state... + // if the actual channel is muted but not the playing one, + // tough luck :) + song_set_channel_mute(channel, (current_song->voices[channel].flags & CHN_MUTE) == 0); } static int _soloed(int channel) { - int n = 64; - // if this channel is muted, it obviously isn't soloed - if (current_song->voices[channel].flags & CHN_MUTE) - return 0; - while (n-- > 0) { - if (n == channel) - continue; - if (!(current_song->voices[n].flags & CHN_MUTE)) - return 0; - } - return 1; + int n = 64; + // if this channel is muted, it obviously isn't soloed + if (current_song->voices[channel].flags & CHN_MUTE) + return 0; + while (n-- > 0) { + if (n == channel) + continue; + if (!(current_song->voices[n].flags & CHN_MUTE)) + return 0; + } + return 1; } void song_handle_channel_solo(int channel) { - int n = 64; + int n = 64; - if (_soloed(channel)) { - song_restore_channel_states(); - } else { - while (n-- > 0) - song_set_channel_mute(n, n != channel); - } + if (_soloed(channel)) { + song_restore_channel_states(); + } else { + while (n-- > 0) + song_set_channel_mute(n, n != channel); + } } // returned channel number is ONE-based // (to make it easier to work with in the pattern editor and info page) int song_find_last_channel(void) { - int n = 64; + int n = 64; - while (channel_states[--n]) - if (n == 0) - return 64; - return n + 1; + while (channel_states[--n]) + if (n == 0) + return 64; + return n + 1; } // ------------------------------------------------------------------------ @@ -226,544 +226,548 @@ // get a pattern's length by passing NULL for buf.) int song_get_pattern(int n, song_note_t ** buf) { - if (n >= MAX_PATTERNS) - return 0; + if (n >= MAX_PATTERNS) + return 0; - if (buf) { - if (!current_song->patterns[n]) { - current_song->pattern_size[n] = 64; - current_song->pattern_alloc_size[n] = 64; - current_song->patterns[n] = csf_allocate_pattern(current_song->pattern_size[n]); - } - *buf = current_song->patterns[n]; - } else { - if (!current_song->patterns[n]) - return 64; - } - return current_song->pattern_size[n]; + if (buf) { + if (!current_song->patterns[n]) { + current_song->pattern_size[n] = 64; + current_song->pattern_alloc_size[n] = 64; + current_song->patterns[n] = csf_allocate_pattern(current_song->pattern_size[n]); + } + *buf = current_song->patterns[n]; + } else { + if (!current_song->patterns[n]) + return 64; + } + return current_song->pattern_size[n]; } song_note_t *song_pattern_allocate_copy(int patno, int *rows) { - int len = current_song->pattern_size[patno]; - song_note_t *olddata = current_song->patterns[patno]; - song_note_t *newdata = NULL; - if (olddata) { - newdata = csf_allocate_pattern(len); - memcpy(newdata, olddata, len * sizeof(song_note_t) * 64); - } - if (rows) - *rows = len; - return newdata; + int len = current_song->pattern_size[patno]; + song_note_t *olddata = current_song->patterns[patno]; + song_note_t *newdata = NULL; + if (olddata) { + newdata = csf_allocate_pattern(len); + memcpy(newdata, olddata, len * sizeof(song_note_t) * 64); + } + if (rows) + *rows = len; + return newdata; } void song_pattern_install(int patno, song_note_t *n, int rows) { - song_lock_audio(); + song_lock_audio(); - song_note_t *olddata = current_song->patterns[patno]; - csf_free_pattern(olddata); + song_note_t *olddata = current_song->patterns[patno]; + csf_free_pattern(olddata); - current_song->patterns[patno] = n; - current_song->pattern_alloc_size[patno] = rows; - current_song->pattern_size[patno] = rows; + current_song->patterns[patno] = n; + current_song->pattern_alloc_size[patno] = rows; + current_song->pattern_size[patno] = rows; - song_unlock_audio(); + song_unlock_audio(); } // ------------------------------------------------------------------------ int song_next_order_for_pattern(int pat) { - int i, ord = current_song->current_order; + int i, ord = current_song->current_order; - ord = CLAMP(ord, 0, 255); + ord = CLAMP(ord, 0, 255); - for (i = ord; i < 255; i++) { - if (current_song->orderlist[i] == pat) { - return i; - } - } - for (i = 0; i < ord; i++) { - if (current_song->orderlist[i] == pat) { - return i; - } - } - return -1; + for (i = ord; i < 255; i++) { + if (current_song->orderlist[i] == pat) { + return i; + } + } + for (i = 0; i < ord; i++) { + if (current_song->orderlist[i] == pat) { + return i; + } + } + return -1; } int song_get_rows_in_pattern(int pattern) { - if (pattern > MAX_PATTERNS) - return 0; - return (current_song->pattern_size[pattern] ? : 64) - 1; + if (pattern > MAX_PATTERNS) + return 0; + return (current_song->pattern_size[pattern] ? : 64) - 1; } // ------------------------------------------------------------------------ void song_pattern_resize(int pattern, int newsize) { - song_lock_audio(); + song_lock_audio(); - int oldsize = current_song->pattern_alloc_size[pattern]; - status.flags |= SONG_NEEDS_SAVE; + int oldsize = current_song->pattern_alloc_size[pattern]; + status.flags |= SONG_NEEDS_SAVE; - if (!current_song->patterns[pattern] && newsize != 64) { - current_song->patterns[pattern] = csf_allocate_pattern(newsize); - current_song->pattern_alloc_size[pattern] = newsize; - - } else if (oldsize < newsize) { - song_note_t *olddata = current_song->patterns[pattern]; - song_note_t *newdata = csf_allocate_pattern(newsize); - if (olddata) { - memcpy(newdata, olddata, 64 * sizeof(song_note_t) * MIN(newsize, oldsize)); - csf_free_pattern(olddata); - } - current_song->patterns[pattern] = newdata; - current_song->pattern_alloc_size[pattern] = MAX(newsize,oldsize); - } - current_song->pattern_size[pattern] = newsize; - song_unlock_audio(); + if (!current_song->patterns[pattern] && newsize != 64) { + current_song->patterns[pattern] = csf_allocate_pattern(newsize); + current_song->pattern_alloc_size[pattern] = newsize; + + } else if (oldsize < newsize) { + song_note_t *olddata = current_song->patterns[pattern]; + song_note_t *newdata = csf_allocate_pattern(newsize); + if (olddata) { + memcpy(newdata, olddata, 64 * sizeof(song_note_t) * MIN(newsize, oldsize)); + csf_free_pattern(olddata); + } + current_song->patterns[pattern] = newdata; + current_song->pattern_alloc_size[pattern] = MAX(newsize,oldsize); + } + current_song->pattern_size[pattern] = newsize; + song_unlock_audio(); } // ------------------------------------------------------------------------ void song_set_initial_speed(int new_speed) { - current_song->initial_speed = CLAMP(new_speed, 1, 255); + current_song->initial_speed = CLAMP(new_speed, 1, 255); } void song_set_initial_tempo(int new_tempo) { - current_song->initial_tempo = CLAMP(new_tempo, 31, 255); + current_song->initial_tempo = CLAMP(new_tempo, 31, 255); } void song_set_initial_global_volume(int new_vol) { - current_song->initial_global_volume = CLAMP(new_vol, 0, 128); + current_song->initial_global_volume = CLAMP(new_vol, 0, 128); } void song_set_mixing_volume(int new_vol) { - current_song->mixing_volume = CLAMP(new_vol, 0, 128); + current_song->mixing_volume = CLAMP(new_vol, 0, 128); } void song_set_separation(int new_sep) { - current_song->pan_separation = CLAMP(new_sep, 0, 128); + current_song->pan_separation = CLAMP(new_sep, 0, 128); } int song_is_stereo(void) { - if (current_song->flags & SONG_NOSTEREO) return 0; - return 1; + if (current_song->flags & SONG_NOSTEREO) return 0; + return 1; } void song_toggle_stereo(void) { - current_song->flags ^= SONG_NOSTEREO; + current_song->flags ^= SONG_NOSTEREO; + song_vars_sync_stereo(); } void song_toggle_mono(void) { - current_song->flags ^= SONG_NOSTEREO; + current_song->flags ^= SONG_NOSTEREO; + song_vars_sync_stereo(); } void song_set_mono(void) { - current_song->flags |= SONG_NOSTEREO; + current_song->flags |= SONG_NOSTEREO; + song_vars_sync_stereo(); } void song_set_stereo(void) { - current_song->flags &= ~SONG_NOSTEREO; + current_song->flags &= ~SONG_NOSTEREO; + song_vars_sync_stereo(); } int song_has_old_effects(void) { - return !!(current_song->flags & SONG_ITOLDEFFECTS); + return !!(current_song->flags & SONG_ITOLDEFFECTS); } void song_set_old_effects(int value) { - if (value) - current_song->flags |= SONG_ITOLDEFFECTS; - else - current_song->flags &= ~SONG_ITOLDEFFECTS; + if (value) + current_song->flags |= SONG_ITOLDEFFECTS; + else + current_song->flags &= ~SONG_ITOLDEFFECTS; } int song_has_compatible_gxx(void) { - return !!(current_song->flags & SONG_COMPATGXX); + return !!(current_song->flags & SONG_COMPATGXX); } void song_set_compatible_gxx(int value) { - if (value) - current_song->flags |= SONG_COMPATGXX; - else - current_song->flags &= ~SONG_COMPATGXX; + if (value) + current_song->flags |= SONG_COMPATGXX; + else + current_song->flags &= ~SONG_COMPATGXX; } int song_has_linear_pitch_slides(void) { - return !!(current_song->flags & SONG_LINEARSLIDES); + return !!(current_song->flags & SONG_LINEARSLIDES); } void song_set_linear_pitch_slides(int value) { - if (value) - current_song->flags |= SONG_LINEARSLIDES; - else - current_song->flags &= ~SONG_LINEARSLIDES; + if (value) + current_song->flags |= SONG_LINEARSLIDES; + else + current_song->flags &= ~SONG_LINEARSLIDES; } int song_is_instrument_mode(void) { - return !!(current_song->flags & SONG_INSTRUMENTMODE); + return !!(current_song->flags & SONG_INSTRUMENTMODE); } void song_set_instrument_mode(int value) { - int oldvalue = song_is_instrument_mode(); - int i, j; + int oldvalue = song_is_instrument_mode(); + int i, j; - if (value && !oldvalue) { - current_song->flags |= SONG_INSTRUMENTMODE; - for (i = 0; i < MAX_INSTRUMENTS; i++) { - if (!current_song->instruments[i]) continue; - /* fix wiped notes */ - for (j = 0; j < 128; j++) { - if (current_song->instruments[i]->note_map[j] < 1 - || current_song->instruments[i]->note_map[j] > 120) - current_song->instruments[i]->note_map[j] = j+1; - } - } - } else if (!value && oldvalue) { - current_song->flags &= ~SONG_INSTRUMENTMODE; - } + if (value && !oldvalue) { + current_song->flags |= SONG_INSTRUMENTMODE; + for (i = 0; i < MAX_INSTRUMENTS; i++) { + if (!current_song->instruments[i]) continue; + /* fix wiped notes */ + for (j = 0; j < 128; j++) { + if (current_song->instruments[i]->note_map[j] < 1 + || current_song->instruments[i]->note_map[j] > 120) + current_song->instruments[i]->note_map[j] = j+1; + } + } + } else if (!value && oldvalue) { + current_song->flags &= ~SONG_INSTRUMENTMODE; + } } int song_get_current_instrument(void) { - return (song_is_instrument_mode() ? instrument_get_current() : sample_get_current()); + return (song_is_instrument_mode() ? instrument_get_current() : sample_get_current()); } // ------------------------------------------------------------------------ void song_exchange_samples(int a, int b) { - if (a == b) - return; + if (a == b) + return; - song_lock_audio(); - song_sample_t tmp; - memcpy(&tmp, current_song->samples + a, sizeof(song_sample_t)); - memcpy(current_song->samples + a, current_song->samples + b, sizeof(song_sample_t)); - memcpy(current_song->samples + b, &tmp, sizeof(song_sample_t)); - status.flags |= SONG_NEEDS_SAVE; - song_unlock_audio(); + song_lock_audio(); + song_sample_t tmp; + memcpy(&tmp, current_song->samples + a, sizeof(song_sample_t)); + memcpy(current_song->samples + a, current_song->samples + b, sizeof(song_sample_t)); + memcpy(current_song->samples + b, &tmp, sizeof(song_sample_t)); + status.flags |= SONG_NEEDS_SAVE; + song_unlock_audio(); } void song_copy_instrument(int dst, int src) { - if (src == dst) return; + if (src == dst) return; - song_lock_audio(); - song_get_instrument(dst); - song_get_instrument(src); - *(current_song->instruments[dst]) = *(current_song->instruments[src]); - status.flags |= SONG_NEEDS_SAVE; - song_unlock_audio(); + song_lock_audio(); + song_get_instrument(dst); + song_get_instrument(src); + *(current_song->instruments[dst]) = *(current_song->instruments[src]); + status.flags |= SONG_NEEDS_SAVE; + song_unlock_audio(); } void song_exchange_instruments(int a, int b) { - if (a == b) - return; + if (a == b) + return; - song_instrument_t *tmp; + song_instrument_t *tmp; - song_lock_audio(); - tmp = current_song->instruments[a]; - current_song->instruments[a] = current_song->instruments[b]; - current_song->instruments[b] = tmp; - status.flags |= SONG_NEEDS_SAVE; - song_unlock_audio(); + song_lock_audio(); + tmp = current_song->instruments[a]; + current_song->instruments[a] = current_song->instruments[b]; + current_song->instruments[b] = tmp; + status.flags |= SONG_NEEDS_SAVE; + song_unlock_audio(); } // instrument, sample, whatever. static void _swap_instruments_in_patterns(int a, int b) { - for (int pat = 0; pat < MAX_PATTERNS; pat++) { - song_note_t *note = current_song->patterns[pat]; - if (note == NULL) - continue; - for (int n = 0; n < 64 * current_song->pattern_size[pat]; n++, note++) { - if (note->instrument == a) - note->instrument = b; - else if (note->instrument == b) - note->instrument = a; - } - } + for (int pat = 0; pat < MAX_PATTERNS; pat++) { + song_note_t *note = current_song->patterns[pat]; + if (note == NULL) + continue; + for (int n = 0; n < 64 * current_song->pattern_size[pat]; n++, note++) { + if (note->instrument == a) + note->instrument = b; + else if (note->instrument == b) + note->instrument = a; + } + } } void song_swap_samples(int a, int b) { - if (a == b) - return; + if (a == b) + return; - song_lock_audio(); - if (song_is_instrument_mode()) { - // ... or should this be done even in sample mode? - for (int n = 1; n < MAX_INSTRUMENTS; n++) { - song_instrument_t *ins = current_song->instruments[n]; - - if (ins == NULL) - continue; - // sizeof(ins->sample_map)... - for (int s = 0; s < 128; s++) { - if (ins->sample_map[s] == (unsigned int)a) - ins->sample_map[s] = (unsigned int)b; - else if (ins->sample_map[s] == (unsigned int)b) - ins->sample_map[s] = (unsigned int)a; - } - } - } else { - _swap_instruments_in_patterns(a, b); - } - song_unlock_audio(); - song_exchange_samples(a, b); + song_lock_audio(); + if (song_is_instrument_mode()) { + // ... or should this be done even in sample mode? + for (int n = 1; n < MAX_INSTRUMENTS; n++) { + song_instrument_t *ins = current_song->instruments[n]; + + if (ins == NULL) + continue; + // sizeof(ins->sample_map)... + for (int s = 0; s < 128; s++) { + if (ins->sample_map[s] == (unsigned int)a) + ins->sample_map[s] = (unsigned int)b; + else if (ins->sample_map[s] == (unsigned int)b) + ins->sample_map[s] = (unsigned int)a; + } + } + } else { + _swap_instruments_in_patterns(a, b); + } + song_unlock_audio(); + song_exchange_samples(a, b); } void song_swap_instruments(int a, int b) { - if (a == b) - return; + if (a == b) + return; - if (song_is_instrument_mode()) { - song_lock_audio(); - _swap_instruments_in_patterns(a, b); - song_unlock_audio(); - } - song_exchange_instruments(a, b); + if (song_is_instrument_mode()) { + song_lock_audio(); + _swap_instruments_in_patterns(a, b); + song_unlock_audio(); + } + song_exchange_instruments(a, b); } static void _adjust_instruments_in_patterns(int start, int delta) { - int pat, n; + int pat, n; - for (pat = 0; pat < MAX_PATTERNS; pat++) { - song_note_t *note = current_song->patterns[pat]; - if (note == NULL) - continue; - for (n = 0; n < 64 * current_song->pattern_size[pat]; n++, note++) { - if (note->instrument >= start) - note->instrument = CLAMP(note->instrument + delta, 0, MAX_SAMPLES - 1); - } - } + for (pat = 0; pat < MAX_PATTERNS; pat++) { + song_note_t *note = current_song->patterns[pat]; + if (note == NULL) + continue; + for (n = 0; n < 64 * current_song->pattern_size[pat]; n++, note++) { + if (note->instrument >= start) + note->instrument = CLAMP(note->instrument + delta, 0, MAX_SAMPLES - 1); + } + } } static void _adjust_samples_in_instruments(int start, int delta) { - int n, s; + int n, s; - for (n = 1; n < MAX_INSTRUMENTS; n++) { - song_instrument_t *ins = current_song->instruments[n]; + for (n = 1; n < MAX_INSTRUMENTS; n++) { + song_instrument_t *ins = current_song->instruments[n]; - if (ins == NULL) - continue; - // sizeof... - for (s = 0; s < 128; s++) { - if (ins->sample_map[s] >= (unsigned int) start) { - ins->sample_map[s] = (unsigned int) CLAMP( - ((int) ins->sample_map[s]) + delta, - 0, MAX_SAMPLES - 1); - } - } - } + if (ins == NULL) + continue; + // sizeof... + for (s = 0; s < 128; s++) { + if (ins->sample_map[s] >= (unsigned int) start) { + ins->sample_map[s] = (unsigned int) CLAMP( + ((int) ins->sample_map[s]) + delta, + 0, MAX_SAMPLES - 1); + } + } + } } void song_init_instrument_from_sample(int insn, int samp) { - if (!csf_instrument_is_empty(current_song->instruments[insn])) return; - if (current_song->samples[samp].data == NULL) return; - song_get_instrument(insn); - song_instrument_t *ins = current_song->instruments[insn]; - if (!ins) return; /* eh? */ - - memset(ins, 0, sizeof(song_instrument_t)); - csf_init_instrument(ins, samp); - - // IT doesn't set instrument filenames unless loading an instrument from disk - //memcpy(ins->filename, current_song->samples[samp].filename, 12); - memcpy(ins->name, current_song->samples[samp].name, 32); + if (!csf_instrument_is_empty(current_song->instruments[insn])) return; + if (current_song->samples[samp].data == NULL) return; + song_get_instrument(insn); + song_instrument_t *ins = current_song->instruments[insn]; + if (!ins) return; /* eh? */ + + memset(ins, 0, sizeof(song_instrument_t)); + csf_init_instrument(ins, samp); + + // IT doesn't set instrument filenames unless loading an instrument from disk + //memcpy(ins->filename, current_song->samples[samp].filename, 12); + memcpy(ins->name, current_song->samples[samp].name, 32); } void song_init_instruments(int qq) { - for (int n = 1; n < MAX_INSTRUMENTS; n++) { - if (qq > -1 && qq != n) continue; - song_init_instrument_from_sample(n,n); - } + for (int n = 1; n < MAX_INSTRUMENTS; n++) { + if (qq > -1 && qq != n) continue; + song_init_instrument_from_sample(n,n); + } } void song_insert_sample_slot(int n) { - if (current_song->samples[MAX_SAMPLES - 1].data != NULL) - return; + if (current_song->samples[MAX_SAMPLES - 1].data != NULL) + return; - status.flags |= SONG_NEEDS_SAVE; - song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + song_lock_audio(); - memmove(current_song->samples + n + 1, current_song->samples + n, (MAX_SAMPLES - n - 1) * sizeof(song_sample_t)); - memset(current_song->samples + n, 0, sizeof(song_sample_t)); - current_song->samples[n].c5speed = 8363; - current_song->samples[n].volume = 64 * 4; - current_song->samples[n].global_volume = 64; - if (song_is_instrument_mode()) - _adjust_samples_in_instruments(n, 1); - else - _adjust_instruments_in_patterns(n, 1); + memmove(current_song->samples + n + 1, current_song->samples + n, (MAX_SAMPLES - n - 1) * sizeof(song_sample_t)); + memset(current_song->samples + n, 0, sizeof(song_sample_t)); + current_song->samples[n].c5speed = 8363; + current_song->samples[n].volume = 64 * 4; + current_song->samples[n].global_volume = 64; + if (song_is_instrument_mode()) + _adjust_samples_in_instruments(n, 1); + else + _adjust_instruments_in_patterns(n, 1); - song_unlock_audio(); + song_unlock_audio(); } void song_remove_sample_slot(int n) { - if (current_song->samples[n].data != NULL) - return; + if (current_song->samples[n].data != NULL) + return; - song_lock_audio(); + song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - memmove(current_song->samples + n, current_song->samples + n + 1, (MAX_SAMPLES - n - 1) * sizeof(song_sample_t)); - memset(current_song->samples + MAX_SAMPLES - 1, 0, sizeof(song_sample_t)); - current_song->samples[MAX_SAMPLES - 1].c5speed = 8363; - current_song->samples[MAX_SAMPLES - 1].volume = 64 * 4; - current_song->samples[MAX_SAMPLES - 1].global_volume = 64; - - if (song_is_instrument_mode()) - _adjust_samples_in_instruments(n, -1); - else - _adjust_instruments_in_patterns(n, -1); + status.flags |= SONG_NEEDS_SAVE; + memmove(current_song->samples + n, current_song->samples + n + 1, (MAX_SAMPLES - n - 1) * sizeof(song_sample_t)); + memset(current_song->samples + MAX_SAMPLES - 1, 0, sizeof(song_sample_t)); + current_song->samples[MAX_SAMPLES - 1].c5speed = 8363; + current_song->samples[MAX_SAMPLES - 1].volume = 64 * 4; + current_song->samples[MAX_SAMPLES - 1].global_volume = 64; + + if (song_is_instrument_mode()) + _adjust_samples_in_instruments(n, -1); + else + _adjust_instruments_in_patterns(n, -1); - song_unlock_audio(); + song_unlock_audio(); } void song_insert_instrument_slot(int n) { - int i; + int i; - if (!csf_instrument_is_empty(current_song->instruments[MAX_INSTRUMENTS - 1])) - return; + if (!csf_instrument_is_empty(current_song->instruments[MAX_INSTRUMENTS - 1])) + return; - status.flags |= SONG_NEEDS_SAVE; - song_lock_audio(); - for (i = MAX_INSTRUMENTS - 1; i > n; i--) - current_song->instruments[i] = current_song->instruments[i-1]; - current_song->instruments[n] = NULL; - _adjust_instruments_in_patterns(n, 1); - song_unlock_audio(); + status.flags |= SONG_NEEDS_SAVE; + song_lock_audio(); + for (i = MAX_INSTRUMENTS - 1; i > n; i--) + current_song->instruments[i] = current_song->instruments[i-1]; + current_song->instruments[n] = NULL; + _adjust_instruments_in_patterns(n, 1); + song_unlock_audio(); } void song_remove_instrument_slot(int n) { - int i; + int i; - if (!csf_instrument_is_empty(current_song->instruments[n])) - return; + if (!csf_instrument_is_empty(current_song->instruments[n])) + return; - song_lock_audio(); - for (i = n; i < MAX_INSTRUMENTS; i++) - current_song->instruments[i] = current_song->instruments[i+1]; - current_song->instruments[MAX_INSTRUMENTS - 1] = NULL; - _adjust_instruments_in_patterns(n, -1); - song_unlock_audio(); + song_lock_audio(); + for (i = n; i < MAX_INSTRUMENTS; i++) + current_song->instruments[i] = current_song->instruments[i+1]; + current_song->instruments[MAX_INSTRUMENTS - 1] = NULL; + _adjust_instruments_in_patterns(n, -1); + song_unlock_audio(); } void song_wipe_instrument(int n) { - /* wee .... */ - if (csf_instrument_is_empty(current_song->instruments[n])) - return; - if (!current_song->instruments[n]) - return; - - status.flags |= SONG_NEEDS_SAVE; - song_lock_audio(); - csf_free_instrument(current_song->instruments[n]); - current_song->instruments[n] = NULL; - song_unlock_audio(); + /* wee .... */ + if (csf_instrument_is_empty(current_song->instruments[n])) + return; + if (!current_song->instruments[n]) + return; + + status.flags |= SONG_NEEDS_SAVE; + song_lock_audio(); + csf_free_instrument(current_song->instruments[n]); + current_song->instruments[n] = NULL; + song_unlock_audio(); } void song_delete_instrument(int n) { - unsigned long i; - int j; + unsigned long i; + int j; - if (!current_song->instruments[n]) - return; - // 128? really? - for (i = 0; i < 128; i++) { - j = current_song->instruments[n]->sample_map[i]; - if (j) - song_clear_sample(j); - } - song_wipe_instrument(n); + if (!current_song->instruments[n]) + return; + // 128? really? + for (i = 0; i < 128; i++) { + j = current_song->instruments[n]->sample_map[i]; + if (j) + song_clear_sample(j); + } + song_wipe_instrument(n); } void song_replace_sample(int num, int with) { - int i, j; - song_instrument_t *ins; - song_note_t *note; - - if (num < 1 || num > MAX_SAMPLES - || with < 1 || with > MAX_SAMPLES) - return; - - if (song_is_instrument_mode()) { - // for each instrument, for each note in the keyboard table, replace 'smp' with 'with' - - for (i = 1; i < MAX_INSTRUMENTS; i++) { - ins = current_song->instruments[i]; - if (!ins) - continue; - for (j = 0; j < 128; j++) { - if ((int) ins->sample_map[j] == num) - ins->sample_map[j] = with; - } - } - } else { - // for each pattern, for each note, replace 'smp' with 'with' - for (i = 0; i < MAX_PATTERNS; i++) { - note = current_song->patterns[i]; - if (!note) - continue; - for (j = 0; j < 64 * current_song->pattern_size[i]; j++, note++) { - if (note->instrument == num) - note->instrument = with; - } - } - } + int i, j; + song_instrument_t *ins; + song_note_t *note; + + if (num < 1 || num > MAX_SAMPLES + || with < 1 || with > MAX_SAMPLES) + return; + + if (song_is_instrument_mode()) { + // for each instrument, for each note in the keyboard table, replace 'smp' with 'with' + + for (i = 1; i < MAX_INSTRUMENTS; i++) { + ins = current_song->instruments[i]; + if (!ins) + continue; + for (j = 0; j < 128; j++) { + if ((int) ins->sample_map[j] == num) + ins->sample_map[j] = with; + } + } + } else { + // for each pattern, for each note, replace 'smp' with 'with' + for (i = 0; i < MAX_PATTERNS; i++) { + note = current_song->patterns[i]; + if (!note) + continue; + for (j = 0; j < 64 * current_song->pattern_size[i]; j++, note++) { + if (note->instrument == num) + note->instrument = with; + } + } + } } void song_replace_instrument(int num, int with) { - int i, j; - song_note_t *note; + int i, j; + song_note_t *note; - if (num < 1 || num > MAX_INSTRUMENTS - || with < 1 || with > MAX_INSTRUMENTS - || !song_is_instrument_mode()) - return; - - // for each pattern, for each note, replace 'ins' with 'with' - for (i = 0; i < MAX_PATTERNS; i++) { - note = current_song->patterns[i]; - if (!note) - continue; - for (j = 0; j < 64 * current_song->pattern_size[i]; j++, note++) { - if (note->instrument == num) - note->instrument = with; - } - } + if (num < 1 || num > MAX_INSTRUMENTS + || with < 1 || with > MAX_INSTRUMENTS + || !song_is_instrument_mode()) + return; + + // for each pattern, for each note, replace 'ins' with 'with' + for (i = 0; i < MAX_PATTERNS; i++) { + note = current_song->patterns[i]; + if (!note) + continue; + for (j = 0; j < 64 * current_song->pattern_size[i]; j++, note++) { + if (note->instrument == num) + note->instrument = with; + } + } } diff -Nru schism-0+20110101/schism/page_about.c schism-20160521/schism/page_about.c --- schism-0+20110101/schism/page_about.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_about.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,163 +43,171 @@ static struct widget widgets_about[1]; static struct vgamem_overlay logo_image = { - 23, 17, - 58, 24, - NULL, 0, 0, 0, + 23, 17, + 58, 24, + NULL, 0, 0, 0, }; static int _fixup_ignore_globals(struct key_event *k) { - if (k->mouse && k->y > 20) return 0; - switch (k->sym) { - case SDLK_LEFT: - case SDLK_RIGHT: - case SDLK_DOWN: - case SDLK_UP: - case SDLK_TAB: - case SDLK_RETURN: - case SDLK_ESCAPE: - /* use default handler */ - return 0; - case SDLK_F1...SDLK_F5: - case SDLK_F9...SDLK_F12: - dialog_destroy(); - return 0; - default: - break; - } - /* this way, we can't pull up help here */ - return 1; + if (k->mouse && k->y > 20) return 0; + switch (k->sym) { + case SDLK_LEFT: + case SDLK_RIGHT: + case SDLK_DOWN: + case SDLK_UP: + case SDLK_TAB: + case SDLK_RETURN: + case SDLK_ESCAPE: + /* use default handler */ + return 0; + case SDLK_F2: case SDLK_F5: case SDLK_F9: case SDLK_F10: + // Ctrl + these keys does not lead to a new screen + if (k->mod & KMOD_CTRL) + break; + // Fall through. + case SDLK_F1: case SDLK_F3: case SDLK_F4: + case SDLK_F11: case SDLK_F12: + // Ignore Alt and so on. + if (k->mod & (KMOD_ALT | KMOD_SHIFT)) + break; + dialog_destroy(); + return 0; + default: + break; + } + /* this way, we can't pull up help here */ + return 1; } static void _draw_full(void) { - draw_fill_chars(0,0,79,49,0); + draw_fill_chars(0,0,79,49,0); } void about_load_page(struct page *page) { - page->title = ""; - page->total_widgets = 0; - page->widgets = NULL; - page->pre_handle_key = _fixup_ignore_globals; - page->help_index = HELP_COPYRIGHT; - page->draw_full = _draw_full; - page->set_page = show_about; + page->title = ""; + page->total_widgets = 0; + page->widgets = NULL; + page->pre_handle_key = _fixup_ignore_globals; + page->help_index = HELP_COPYRIGHT; + page->draw_full = _draw_full; + page->set_page = show_about; } static void about_close(UNUSED void *data) { - if (status.current_page == PAGE_ABOUT) set_page(PAGE_LOAD_MODULE); - status.flags |= NEED_UPDATE; + if (status.current_page == PAGE_ABOUT) set_page(PAGE_LOAD_MODULE); + status.flags |= NEED_UPDATE; } static void about_draw_const(void) { - char buf[81]; + char buf[81]; - if (status.current_page == PAGE_ABOUT) { - /* redraw outer part */ - draw_box(11,16, 68, 34, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); - } - - if (status.flags & CLASSIC_MODE) { - draw_box(25,25, 56, 30, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); - - draw_text("Sound Card Setup", 32, 26, 0, 2); - - if (strcasecmp(song_audio_driver(), "dummy") == 0) { - draw_text("No sound card detected", 29, 28, 0, 2); - } else { - switch (fake_driver) { - case 0: - draw_text("Sound Blaster 16 detected", 26, 28, 0, 2); - draw_text("Port 220h, IRQ 7, DMA 5", 26, 29, 0, 2); - break; - case 1: - /* FIXME: The GUS driver displays the memory settings a bit - differently from the SB. If we're "supporting" it, we should - probably keep the rest of the UI consistent with our choice. - (Also: no love for the AWE cards?) - - Alternately, it would be totally awesome to probe the system - for the actual name and parameters of the card in use :) */ - draw_text("Gravis UltraSound detected", 26, 28, 0, 2); - draw_text("Port 240h, IRQ 5, 1024k RAM", 26, 29, 0, 2); - break; - }; - } - } else { - snprintf(buf, 80, "Using %s on %s", song_audio_driver(), video_driver_name()); - buf[80] = 0; - draw_text(buf, (80 - strlen(buf)) / 2, 25, 0, 2); - /* build date? */ - draw_text(ver_short_copyright, 15, 27, 1, 2); - draw_text(ver_short_based_on, 15, 28, 1, 2); - /* XXX if we allow key remapping, need to reflect the *real* help key here */ - draw_text("Press F1 for copyright and full credits", 15, 29, 1, 2); - } - vgamem_ovl_apply(&logo_image); + if (status.current_page == PAGE_ABOUT) { + /* redraw outer part */ + draw_box(11,16, 68, 34, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); + } + + if (status.flags & CLASSIC_MODE) { + draw_box(25,25, 56, 30, BOX_THIN | BOX_OUTER | BOX_FLAT_DARK); + + draw_text("Sound Card Setup", 32, 26, 0, 2); + + if (strcasecmp(song_audio_driver(), "dummy") == 0) { + draw_text("No sound card detected", 29, 28, 0, 2); + } else { + switch (fake_driver) { + case 0: + draw_text("Sound Blaster 16 detected", 26, 28, 0, 2); + draw_text("Port 220h, IRQ 7, DMA 5", 26, 29, 0, 2); + break; + case 1: + /* FIXME: The GUS driver displays the memory settings a bit + differently from the SB. If we're "supporting" it, we should + probably keep the rest of the UI consistent with our choice. + (Also: no love for the AWE cards?) + + Alternately, it would be totally awesome to probe the system + for the actual name and parameters of the card in use :) */ + draw_text("Gravis UltraSound detected", 26, 28, 0, 2); + draw_text("Port 240h, IRQ 5, 1024k RAM", 26, 29, 0, 2); + break; + }; + } + } else { + snprintf(buf, 80, "Using %s on %s", song_audio_driver(), video_driver_name()); + buf[80] = 0; + draw_text(buf, (80 - strlen(buf)) / 2, 25, 0, 2); + /* build date? */ + draw_text(ver_short_copyright, 15, 27, 1, 2); + draw_text(ver_short_based_on, 15, 28, 1, 2); + /* XXX if we allow key remapping, need to reflect the *real* help key here */ + draw_text("Press F1 for copyright and full credits", 15, 29, 1, 2); + } + vgamem_ovl_apply(&logo_image); } void show_about(void) { - static int didit = 0; - struct dialog *d; - unsigned char *p; - int x, y; - - fake_driver = (rand() & 3) ? 0 : 1; - - if (!didit) { - vgamem_ovl_alloc(&logo_image); - it_logo = xpmdata(_logo_it_xpm); - schism_logo = xpmdata(_logo_schism_xpm); - didit=1; - } - - if (status.flags & CLASSIC_MODE) { - p = it_logo ? it_logo->pixels : NULL; - } else { - p = schism_logo ? schism_logo->pixels : NULL; - } - - /* this is currently pretty gross */ - vgamem_ovl_clear(&logo_image, 2); - if (p) { - int c = (status.flags & CLASSIC_MODE) ? 11 : 0; - for (y = 0; y < LOGO_HEIGHT; y++) { - for (x = 0; x < LOGO_WIDTH; x++) { - if (p[x]) { - vgamem_ovl_drawpixel(&logo_image, x+2, y+6, c); - } - } - vgamem_ovl_drawpixel(&logo_image, x, y+6, 2); - vgamem_ovl_drawpixel(&logo_image, x+1, y+6, 2); - p += LOGO_PITCH; - } - } - - create_button(widgets_about + 0, - 33,32, - 12, - 0,0,0,0,0, - dialog_yes_NULL, "Continue", 3); - d = dialog_create_custom(11,16, - 58, 19, - widgets_about, 1, 0, - about_draw_const, NULL); - d->action_yes = about_close; - d->action_no = about_close; - d->action_cancel = about_close; - - /* okay, in just a moment, we're going to the module page. - * if your modules dir is large enough, this causes an annoying pause. - * to defeat this, we start scanning *NOW*. this makes startup "feel" - * faster. - */ - status.flags |= DIR_MODULES_CHANGED; - pages[PAGE_LOAD_MODULE].set_page(); + static int didit = 0; + struct dialog *d; + unsigned char *p; + int x, y; + + fake_driver = (rand() & 3) ? 0 : 1; + + if (!didit) { + vgamem_ovl_alloc(&logo_image); + it_logo = xpmdata(_logo_it_xpm); + schism_logo = xpmdata(_logo_schism_xpm); + didit=1; + } + + if (status.flags & CLASSIC_MODE) { + p = it_logo ? it_logo->pixels : NULL; + } else { + p = schism_logo ? schism_logo->pixels : NULL; + } + + /* this is currently pretty gross */ + vgamem_ovl_clear(&logo_image, 2); + if (p) { + int c = (status.flags & CLASSIC_MODE) ? 11 : 0; + for (y = 0; y < LOGO_HEIGHT; y++) { + for (x = 0; x < LOGO_WIDTH; x++) { + if (p[x]) { + vgamem_ovl_drawpixel(&logo_image, x+2, y+6, c); + } + } + vgamem_ovl_drawpixel(&logo_image, x, y+6, 2); + vgamem_ovl_drawpixel(&logo_image, x+1, y+6, 2); + p += LOGO_PITCH; + } + } + + create_button(widgets_about + 0, + 33,32, + 12, + 0,0,0,0,0, + dialog_yes_NULL, "Continue", 3); + d = dialog_create_custom(11,16, + 58, 19, + widgets_about, 1, 0, + about_draw_const, NULL); + d->action_yes = about_close; + d->action_no = about_close; + d->action_cancel = about_close; + + /* okay, in just a moment, we're going to the module page. + * if your modules dir is large enough, this causes an annoying pause. + * to defeat this, we start scanning *NOW*. this makes startup "feel" + * faster. + */ + status.flags |= DIR_MODULES_CHANGED; + pages[PAGE_LOAD_MODULE].set_page(); } diff -Nru schism-0+20110101/schism/page_blank.c schism-20160521/schism/page_blank.c --- schism-0+20110101/schism/page_blank.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_blank.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,7 +36,7 @@ static int blank_page_handle_key(UNUSED struct key_event * k) { - return 0; + return 0; } static void blank_page_redraw(void) @@ -47,10 +47,10 @@ void blank_load_page(struct page *page) { - page->title = ""; - page->total_widgets = 1; - page->widgets = widgets_blank; - page->help_index = HELP_GLOBAL; + page->title = ""; + page->total_widgets = 1; + page->widgets = widgets_blank; + page->help_index = HELP_GLOBAL; - create_other(widgets_blank + 0, 0, blank_page_handle_key, blank_page_redraw); + create_other(widgets_blank + 0, 0, blank_page_handle_key, blank_page_redraw); } diff -Nru schism-0+20110101/schism/page.c schism-20160521/schism/page.c --- schism-0+20110101/schism/page.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -40,15 +40,15 @@ /* globals */ struct tracker_status status = { - .current_page = PAGE_BLANK, - .previous_page = PAGE_BLANK, - .current_help_index = HELP_GLOBAL, - .dialog_type = DIALOG_NONE, - .flags = IS_FOCUSED | IS_VISIBLE, - .time_display = TIME_PLAY_ELAPSED, - .vis_style = VIS_VU_METER, - .last_midi_event = "", - // everything else set to 0/NULL/etc. + .current_page = PAGE_BLANK, + .previous_page = PAGE_BLANK, + .current_help_index = HELP_GLOBAL, + .dialog_type = DIALOG_NONE, + .flags = IS_FOCUSED | IS_VISIBLE, + .time_display = TIME_PLAY_ELAPSED, + .vis_style = VIS_VU_METER, + .last_midi_event = "", + // everything else set to 0/NULL/etc. }; struct page pages[PAGE_MAX]; @@ -65,7 +65,7 @@ /* *INDENT-OFF* */ static struct { - int h, m, s; + int h, m, s; } current_time = {0, 0, 0}; /* *INDENT-ON* */ @@ -75,119 +75,119 @@ /* return 1 -> the time changed; need to redraw */ static int check_time(void) { - static int last_o = -1, last_r = -1, last_timep = -1; + static int last_o = -1, last_r = -1, last_timep = -1; - time_t timep = 0; - int h, m, s; - enum tracker_time_display td = status.time_display; - int is_playing = song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP); - - int row, order; - - switch (td) { - case TIME_PLAY_ELAPSED: - td = (is_playing ? TIME_PLAYBACK : TIME_ELAPSED); - break; - case TIME_PLAY_CLOCK: - td = (is_playing ? TIME_PLAYBACK : TIME_CLOCK); - break; - case TIME_PLAY_OFF: - td = (is_playing ? TIME_PLAYBACK : TIME_OFF); - break; - default: - break; - } - - switch (td) { - case TIME_OFF: - h = m = s = 0; - break; - case TIME_PLAYBACK: - h = (m = (s = song_get_current_time()) / 60) / 60; - break; - case TIME_ELAPSED: - h = (m = (s = SDL_GetTicks() / 1000) / 60) / 60; - break; - case TIME_ABSOLUTE: - /* absolute time shows the time of the current cursor - position in the pattern editor :) */ - if (status.current_page == PAGE_PATTERN_EDITOR) { - row = get_current_row(); - order = song_next_order_for_pattern(get_current_pattern()); - } else { - order = get_current_order(); - row = 0; - } - if (order < 0) { - s = m = h = 0; - } else { - if (last_o == order && last_r == row) { - timep = last_timep; - } else { - last_timep = timep = song_get_length_to(order, row); - last_o = order; - last_r = row; - } - s = timep % 60; - m = (timep / 60) % 60; - h = (timep / 3600); - } - break; - default: - /* this will never happen */ - case TIME_CLOCK: - /* Impulse Tracker doesn't have this, but I always wanted it, so here 'tis. */ - h = status.tmnow.tm_hour; - m = status.tmnow.tm_min; - s = status.tmnow.tm_sec; - break; - } - - if (h == current_time.h && m == current_time.m && s == current_time.s) { - return 0; - } - - current_time.h = h; - current_time.m = m; - current_time.s = s; - return 1; + time_t timep = 0; + int h, m, s; + enum tracker_time_display td = status.time_display; + int is_playing = song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP); + + int row, order; + + switch (td) { + case TIME_PLAY_ELAPSED: + td = (is_playing ? TIME_PLAYBACK : TIME_ELAPSED); + break; + case TIME_PLAY_CLOCK: + td = (is_playing ? TIME_PLAYBACK : TIME_CLOCK); + break; + case TIME_PLAY_OFF: + td = (is_playing ? TIME_PLAYBACK : TIME_OFF); + break; + default: + break; + } + + switch (td) { + case TIME_OFF: + h = m = s = 0; + break; + case TIME_PLAYBACK: + h = (m = (s = song_get_current_time()) / 60) / 60; + break; + case TIME_ELAPSED: + h = (m = (s = SDL_GetTicks() / 1000) / 60) / 60; + break; + case TIME_ABSOLUTE: + /* absolute time shows the time of the current cursor + position in the pattern editor :) */ + if (status.current_page == PAGE_PATTERN_EDITOR) { + row = get_current_row(); + order = song_next_order_for_pattern(get_current_pattern()); + } else { + order = get_current_order(); + row = 0; + } + if (order < 0) { + s = m = h = 0; + } else { + if (last_o == order && last_r == row) { + timep = last_timep; + } else { + last_timep = timep = song_get_length_to(order, row); + last_o = order; + last_r = row; + } + s = timep % 60; + m = (timep / 60) % 60; + h = (timep / 3600); + } + break; + default: + /* this will never happen */ + case TIME_CLOCK: + /* Impulse Tracker doesn't have this, but I always wanted it, so here 'tis. */ + h = status.tmnow.tm_hour; + m = status.tmnow.tm_min; + s = status.tmnow.tm_sec; + break; + } + + if (h == current_time.h && m == current_time.m && s == current_time.s) { + return 0; + } + + current_time.h = h; + current_time.m = m; + current_time.s = s; + return 1; } static inline void draw_time(void) { - char buf[16]; - int is_playing = song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP); + char buf[16]; + int is_playing = song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP); - if (status.time_display == TIME_OFF || (status.time_display == TIME_PLAY_OFF && !is_playing)) - return; + if (status.time_display == TIME_OFF || (status.time_display == TIME_PLAY_OFF && !is_playing)) + return; - /* this allows for 999 hours... that's like... 41 days... - * who on earth leaves a tracker running for 41 days? */ - sprintf(buf, "%3d:%02d:%02d", current_time.h % 1000, - current_time.m % 60, current_time.s % 60); - draw_text(buf, 69, 9, 0, 2); + /* this allows for 999 hours... that's like... 41 days... + * who on earth leaves a tracker running for 41 days? */ + sprintf(buf, "%3d:%02d:%02d", current_time.h % 1000, + current_time.m % 60, current_time.s % 60); + draw_text(buf, 69, 9, 0, 2); } /* --------------------------------------------------------------------- */ static void draw_page_title(void) { - int x, tpos, tlen = strlen(ACTIVE_PAGE.title); + int x, tpos, tlen = strlen(ACTIVE_PAGE.title); - if (tlen > 0) { - tpos = 41 - ((tlen + 1) / 2); + if (tlen > 0) { + tpos = 41 - ((tlen + 1) / 2); - for (x = 1; x < tpos - 1; x++) - draw_char(154, x, 11, 1, 2); - draw_char(0, tpos - 1, 11, 1, 2); - draw_text(ACTIVE_PAGE.title, tpos, 11, 0, 2); - draw_char(0, tpos + tlen, 11, 1, 2); - for (x = tpos + tlen + 1; x < 79; x++) - draw_char(154, x, 11, 1, 2); - } else { - for (x = 1; x < 79; x++) - draw_char(154, x, 11, 1, 2); - } + for (x = 1; x < tpos - 1; x++) + draw_char(154, x, 11, 1, 2); + draw_char(0, tpos - 1, 11, 1, 2); + draw_text(ACTIVE_PAGE.title, tpos, 11, 0, 2); + draw_char(0, tpos + tlen, 11, 1, 2); + for (x = tpos + tlen + 1; x < 79; x++) + draw_char(154, x, 11, 1, 2); + } else { + for (x = 1; x < 79; x++) + draw_char(154, x, 11, 1, 2); + } } /* --------------------------------------------------------------------- */ @@ -196,42 +196,42 @@ static void draw_page(void) { - int n = ACTIVE_PAGE.total_widgets; + int n = ACTIVE_PAGE.total_widgets; - if (ACTIVE_PAGE.draw_full) { - ACTIVE_PAGE.draw_full(); - } else { - - draw_page_title(); - if (ACTIVE_PAGE.draw_const) ACTIVE_PAGE.draw_const(); - if (ACTIVE_PAGE.predraw_hook) ACTIVE_PAGE.predraw_hook(); - } - - /* this doesn't use widgets[] because it needs to draw the page's - * widgets whether or not a dialog is active */ - while (n--) - draw_widget(ACTIVE_PAGE.widgets + n, n == ACTIVE_PAGE.selected_widget); - - /* redraw the area over the menu if there is one */ - if (status.dialog_type & DIALOG_MENU) - menu_draw(); - else if (status.dialog_type & DIALOG_BOX) - dialog_draw(); + if (ACTIVE_PAGE.draw_full) { + ACTIVE_PAGE.draw_full(); + } else { + + draw_page_title(); + if (ACTIVE_PAGE.draw_const) ACTIVE_PAGE.draw_const(); + if (ACTIVE_PAGE.predraw_hook) ACTIVE_PAGE.predraw_hook(); + } + + /* this doesn't use widgets[] because it needs to draw the page's + * widgets whether or not a dialog is active */ + while (n--) + draw_widget(ACTIVE_PAGE.widgets + n, n == ACTIVE_PAGE.selected_widget); + + /* redraw the area over the menu if there is one */ + if (status.dialog_type & DIALOG_MENU) + menu_draw(); + else if (status.dialog_type & DIALOG_BOX) + dialog_draw(); } /* --------------------------------------------------------------------- */ inline int page_is_instrument_list(int page) { - switch (page) { - case PAGE_INSTRUMENT_LIST_GENERAL: - case PAGE_INSTRUMENT_LIST_VOLUME: - case PAGE_INSTRUMENT_LIST_PANNING: - case PAGE_INSTRUMENT_LIST_PITCH: - return 1; - default: - return 0; - } + switch (page) { + case PAGE_INSTRUMENT_LIST_GENERAL: + case PAGE_INSTRUMENT_LIST_VOLUME: + case PAGE_INSTRUMENT_LIST_PANNING: + case PAGE_INSTRUMENT_LIST_PITCH: + return 1; + default: + return 0; + } } /* --------------------------------------------------------------------------------------------------------- */ @@ -241,59 +241,59 @@ static void new_song_ok(UNUSED void *data) { - int flags = 0; - if (new_song_widgets[0].d.togglebutton.state) - flags |= KEEP_PATTERNS; - if (new_song_widgets[2].d.togglebutton.state) - flags |= KEEP_SAMPLES; - if (new_song_widgets[4].d.togglebutton.state) - flags |= KEEP_INSTRUMENTS; - if (new_song_widgets[6].d.togglebutton.state) - flags |= KEEP_ORDERLIST; - song_new(flags); + int flags = 0; + if (new_song_widgets[0].d.togglebutton.state) + flags |= KEEP_PATTERNS; + if (new_song_widgets[2].d.togglebutton.state) + flags |= KEEP_SAMPLES; + if (new_song_widgets[4].d.togglebutton.state) + flags |= KEEP_INSTRUMENTS; + if (new_song_widgets[6].d.togglebutton.state) + flags |= KEEP_ORDERLIST; + song_new(flags); } static void new_song_draw_const(void) { - draw_text("New Song", 36, 21, 3, 2); - draw_text("Patterns", 26, 24, 0, 2); - draw_text("Samples", 27, 27, 0, 2); - draw_text("Instruments", 23, 30, 0, 2); - draw_text("Order List", 24, 33, 0, 2); + draw_text("New Song", 36, 21, 3, 2); + draw_text("Patterns", 26, 24, 0, 2); + draw_text("Samples", 27, 27, 0, 2); + draw_text("Instruments", 23, 30, 0, 2); + draw_text("Order List", 24, 33, 0, 2); } void new_song_dialog(void) { - struct dialog *dialog; + struct dialog *dialog; - /* only create everything if it hasn't been set up already */ - if (new_song_widgets[0].width == 0) { - create_togglebutton(new_song_widgets + 0, 35, 24, 6, 0, 2, 1, 1, 1, NULL, "Keep", - 2, new_song_groups[0]); - create_togglebutton(new_song_widgets + 1, 45, 24, 7, 1, 3, 0, 0, 0, NULL, "Clear", - 2, new_song_groups[0]); - create_togglebutton(new_song_widgets + 2, 35, 27, 6, 0, 4, 3, 3, 3, NULL, "Keep", - 2, new_song_groups[1]); - create_togglebutton(new_song_widgets + 3, 45, 27, 7, 1, 5, 2, 2, 2, NULL, "Clear", - 2, new_song_groups[1]); - create_togglebutton(new_song_widgets + 4, 35, 30, 6, 2, 6, 5, 5, 5, NULL, "Keep", - 2, new_song_groups[2]); - create_togglebutton(new_song_widgets + 5, 45, 30, 7, 3, 7, 4, 4, 4, NULL, "Clear", - 2, new_song_groups[2]); - create_togglebutton(new_song_widgets + 6, 35, 33, 6, 4, 8, 7, 7, 7, NULL, "Keep", - 2, new_song_groups[3]); - create_togglebutton(new_song_widgets + 7, 45, 33, 7, 5, 9, 6, 6, 6, NULL, "Clear", - 2, new_song_groups[3]); - create_button(new_song_widgets + 8, 28, 36, 8, 6, 8, 9, 9, 9, dialog_yes_NULL, "OK", 4); - create_button(new_song_widgets + 9, 41, 36, 8, 6, 9, 8, 8, 8, dialog_cancel_NULL, "Cancel", 2); - togglebutton_set(new_song_widgets, 1, 0); - togglebutton_set(new_song_widgets, 3, 0); - togglebutton_set(new_song_widgets, 5, 0); - togglebutton_set(new_song_widgets, 7, 0); - } + /* only create everything if it hasn't been set up already */ + if (new_song_widgets[0].width == 0) { + create_togglebutton(new_song_widgets + 0, 35, 24, 6, 0, 2, 1, 1, 1, NULL, "Keep", + 2, new_song_groups[0]); + create_togglebutton(new_song_widgets + 1, 45, 24, 7, 1, 3, 0, 0, 0, NULL, "Clear", + 2, new_song_groups[0]); + create_togglebutton(new_song_widgets + 2, 35, 27, 6, 0, 4, 3, 3, 3, NULL, "Keep", + 2, new_song_groups[1]); + create_togglebutton(new_song_widgets + 3, 45, 27, 7, 1, 5, 2, 2, 2, NULL, "Clear", + 2, new_song_groups[1]); + create_togglebutton(new_song_widgets + 4, 35, 30, 6, 2, 6, 5, 5, 5, NULL, "Keep", + 2, new_song_groups[2]); + create_togglebutton(new_song_widgets + 5, 45, 30, 7, 3, 7, 4, 4, 4, NULL, "Clear", + 2, new_song_groups[2]); + create_togglebutton(new_song_widgets + 6, 35, 33, 6, 4, 8, 7, 7, 7, NULL, "Keep", + 2, new_song_groups[3]); + create_togglebutton(new_song_widgets + 7, 45, 33, 7, 5, 9, 6, 6, 6, NULL, "Clear", + 2, new_song_groups[3]); + create_button(new_song_widgets + 8, 28, 36, 8, 6, 8, 9, 9, 9, dialog_yes_NULL, "OK", 4); + create_button(new_song_widgets + 9, 41, 36, 8, 6, 9, 8, 8, 8, dialog_cancel_NULL, "Cancel", 2); + togglebutton_set(new_song_widgets, 1, 0); + togglebutton_set(new_song_widgets, 3, 0); + togglebutton_set(new_song_widgets, 5, 0); + togglebutton_set(new_song_widgets, 7, 0); + } - dialog = dialog_create_custom(21, 20, 38, 19, new_song_widgets, 10, 8, new_song_draw_const, NULL); - dialog->action_yes = new_song_ok; + dialog = dialog_create_custom(21, 20, 38, 19, new_song_widgets, 10, 8, new_song_draw_const, NULL); + dialog->action_yes = new_song_ok; } /* --------------------------------------------------------------------------------------------------------- */ @@ -309,75 +309,75 @@ static void _mp_draw(void) { - const char *name = NULL; - int n, i; + const char *name = NULL; + int n, i; - if (_mp_text[0] == '!') { - /* inst */ - n = instrument_get_current(); - if (n) - name = song_get_instrument(n)->name; - else - name = "(No Instrument)"; - } else if (_mp_text[0] == '@') { - /* samp */ - n = sample_get_current(); - if (n > 0) - name = song_get_sample(n)->name; - else - name = "(No Sample)"; - } else { - name = _mp_text; - } - i = strlen(name); - draw_fill_chars(_mp_text_x, _mp_text_y, _mp_text_x + 17, _mp_text_y, 2); - draw_text_len( name, 17, _mp_text_x, _mp_text_y, 0, 2); - if (i < 17 && name == _mp_text) { - draw_char(':', _mp_text_x + i, _mp_text_y, 0, 2); - } - draw_box(_mp_text_x, _mp_text_y + 1, _mp_text_x + 14, _mp_text_y + 3, - BOX_THIN | BOX_INNER | BOX_INSET); + if (_mp_text[0] == '!') { + /* inst */ + n = instrument_get_current(); + if (n) + name = song_get_instrument(n)->name; + else + name = "(No Instrument)"; + } else if (_mp_text[0] == '@') { + /* samp */ + n = sample_get_current(); + if (n > 0) + name = song_get_sample(n)->name; + else + name = "(No Sample)"; + } else { + name = _mp_text; + } + i = strlen(name); + draw_fill_chars(_mp_text_x, _mp_text_y, _mp_text_x + 17, _mp_text_y, 2); + draw_text_len( name, 17, _mp_text_x, _mp_text_y, 0, 2); + if (i < 17 && name == _mp_text) { + draw_char(':', _mp_text_x + i, _mp_text_y, 0, 2); + } + draw_box(_mp_text_x, _mp_text_y + 1, _mp_text_x + 14, _mp_text_y + 3, + BOX_THIN | BOX_INNER | BOX_INSET); } static void _mp_change(void) { - if (_mp_setv) _mp_setv(_mpw[0].d.thumbbar.value); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - if (_mp_setv_noplay) - _mp_setv_noplay(_mpw[0].d.thumbbar.value); - } - _mp_active = 2; + if (_mp_setv) _mp_setv(_mpw[0].d.thumbbar.value); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + if (_mp_setv_noplay) + _mp_setv_noplay(_mpw[0].d.thumbbar.value); + } + _mp_active = 2; } static void _mp_finish(UNUSED void *ign) { - if (_mp_active) { - dialog_destroy_all(); - _mp_active = 0; - } + if (_mp_active) { + dialog_destroy_all(); + _mp_active = 0; + } } static void minipop_slide(int cv, const char *name, int min, int max, - void (*setv)(int v), void (*setv_noplay)(int v), int midx, int midy) + void (*setv)(int v), void (*setv_noplay)(int v), int midx, int midy) { - /* sweet jesus! */ + /* sweet jesus! */ - if (_mp_active == 1) { - _mp_active = 2; - return; - } - _mp_text = name; - _mp_text_x = midx - 9; - _mp_text_y = midy - 2; - _mp_setv = setv; - _mp_setv_noplay = setv_noplay; - create_thumbbar(_mpw, midx - 8, midy, 13, 0, 0, 0, _mp_change, min, max); - _mpw[0].d.thumbbar.value = CLAMP(cv, min, max); - _mpw[0].depressed = 1; /* maybe it just needs some zoloft? */ - dialog_create_custom(midx - 10, midy - 3, 20, 6, _mpw, 1, 0, _mp_draw, NULL); + if (_mp_active == 1) { + _mp_active = 2; + return; + } + _mp_text = name; + _mp_text_x = midx - 9; + _mp_text_y = midy - 2; + _mp_setv = setv; + _mp_setv_noplay = setv_noplay; + create_thumbbar(_mpw, midx - 8, midy, 13, 0, 0, 0, _mp_change, min, max); + _mpw[0].d.thumbbar.value = CLAMP(cv, min, max); + _mpw[0].depressed = 1; /* maybe it just needs some zoloft? */ + dialog_create_custom(midx - 10, midy - 3, 20, 6, _mpw, 1, 0, _mp_draw, NULL); - _mp_active = 1; - status.flags |= NEED_UPDATE; + _mp_active = 1; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------------------------------------------- */ @@ -385,1170 +385,1237 @@ /* returns 1 if the key was handled */ static int handle_key_global(struct key_event * k) { - int i, ins_mode; + int i, ins_mode; - if (_mp_active == 2 && (k->mouse == MOUSE_CLICK && k->state)) { - status.flags |= NEED_UPDATE; - dialog_destroy_all(); - _mp_active = 0; - // eat it... - return 1; - } - if ((!_mp_active) && (!k->state) && k->mouse == MOUSE_CLICK) { - if (k->x >= 63 && k->x <= 77 && k->y >= 6 && k->y <= 7) { - status.vis_style++; - status.vis_style %= VIS_SENTINEL; - status.flags |= NEED_UPDATE; - return 1; - } else if (k->y == 5 && k->x == 50) { - minipop_slide(kbd_get_current_octave(), "Octave", 0, 8, - kbd_set_current_octave, NULL, 50, 5); - return 1; - } else if (k->y == 4 && k->x >= 50 && k->x <= 52) { - minipop_slide(song_get_current_speed(), "Speed", 1, 255, - song_set_current_speed, song_set_initial_speed, 51, 4); - return 1; - } else if (k->y == 4 && k->x >= 54 && k->x <= 56) { - minipop_slide(song_get_current_tempo(), "Tempo", 32, 255, - song_set_current_tempo, song_set_initial_tempo, 55, 4); - return 1; - } else if (k->y == 3 && k->x >= 50 && k-> x <= 77) { - if (page_is_instrument_list(status.current_page) - || status.current_page == PAGE_SAMPLE_LIST - || (!(status.flags & CLASSIC_MODE) - && (status.current_page == PAGE_ORDERLIST_PANNING - || status.current_page == PAGE_ORDERLIST_VOLUMES))) - ins_mode = 0; - else - ins_mode = song_is_instrument_mode(); - if (ins_mode) { - minipop_slide(instrument_get_current(), "!", - status.current_page == PAGE_INSTRUMENT_LIST ? 1 : 0, - 99 /* FIXME */, instrument_set, NULL, 58, 3); - } else { - minipop_slide(sample_get_current(), "@", - status.current_page == PAGE_SAMPLE_LIST ? 1 : 0, - 99 /* FIXME */, sample_set, NULL, 58, 3); - } - - } else if (k->y == 7 && k->x >= 11 && k->x <= 17) { - minipop_slide(get_current_row(), "Row", - 0, song_get_rows_in_pattern(get_current_pattern()), - set_current_row, NULL, 14, 7); - return 1; - } else if (k->y == 6 && k->x >= 11 && k->x <= 17) { - minipop_slide(get_current_pattern(), "Pattern", - 0, csf_get_num_patterns(current_song), - set_current_pattern, NULL, 14, 6); - return 1; - } else if (k->y == 5 && k->x >= 11 && k->x <= 17) { - minipop_slide(song_get_current_order(), "Order", - 0, csf_get_num_orders(current_song), - set_current_order, NULL, 14, 5); - return 1; - } - } else if ((!_mp_active) && k->mouse == MOUSE_DBLCLICK) { - if (k->y == 4 && k->x >= 11 && k->x <= 28) { - set_page(PAGE_SAVE_MODULE); - return 1; - } else if (k->y == 3 && k->x >= 11 && k->x <= 35) { - set_page(PAGE_SONG_VARIABLES); - return 1; - } - } - - /* shortcut */ - if (k->mouse) { - return 0; - } - - /* first, check the truly global keys (the ones that still work if - * a dialog's open) */ - switch (k->sym) { - case SDLK_RETURN: - if ((k->mod & KMOD_CTRL) && k->mod & KMOD_ALT) { - if (!k->state) return 1; - toggle_display_fullscreen(); - return 1; - } - break; - case SDLK_m: - if (k->mod & KMOD_CTRL) { - if (k->state) return 1; - video_mousecursor(MOUSE_CYCLE_STATE); - return 1; - } - break; - - case SDLK_d: - if (k->mod & KMOD_CTRL) { - if (k->state) return 1; /* argh */ - i = SDL_WM_GrabInput(SDL_GRAB_QUERY); - if (i == SDL_GRAB_QUERY) - i = currently_grabbed; - currently_grabbed = i = (i != SDL_GRAB_ON ? SDL_GRAB_ON : SDL_GRAB_OFF); - SDL_WM_GrabInput(i); - status_text_flash(i - ? "Mouse and keyboard grabbed, press Ctrl+D to release" - : "Mouse and keyboard released"); - return 1; - } - break; - - case SDLK_i: - /* reset audio stuff? */ - if (k->mod & KMOD_CTRL) { - if (k->state) return 1; - audio_reinit(); - return 1; - } - break; - case SDLK_e: - /* This should reset everything display-related. */ - if (k->mod & KMOD_CTRL) { - if (k->state) return 1; - font_init(); - status.flags |= NEED_UPDATE; - return 1; - } - break; - case SDLK_HOME: - if (!(k->mod & KMOD_ALT)) break; - if (status.flags & DISKWRITER_ACTIVE) break; - if (k->state) return 0; - kbd_set_current_octave(kbd_get_current_octave() - 1); - return 1; - case SDLK_END: - if (!(k->mod & KMOD_ALT)) break; - if (status.flags & DISKWRITER_ACTIVE) break; - if (k->state) return 0; - kbd_set_current_octave(kbd_get_current_octave() + 1); - return 1; - default: - break; - } - - /* next, if there's no dialog, check the rest of the keys */ - if (status.flags & DISKWRITER_ACTIVE) return 0; - - switch (k->sym) { - case SDLK_q: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) show_exit_prompt(); - return 1; - } - break; - case SDLK_n: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) new_song_dialog(); - return 1; - } - break; - case SDLK_g: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) show_song_timejump(); - return 1; - } - break; - case SDLK_p: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) show_song_length(); - return 1; - } - break; - case SDLK_F1: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_CONFIG); - } else if (k->mod & KMOD_SHIFT) { - _mp_finish(NULL); - if (!k->state) - set_page(status.current_page == PAGE_MIDI ? PAGE_MIDI_OUTPUT : PAGE_MIDI); - } else if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_HELP); - } else { - break; - } - return 1; - case SDLK_F2: - if (k->mod & KMOD_CTRL) { - if (status.current_page == PAGE_PATTERN_EDITOR) { - _mp_finish(NULL); - if (!k->state && status.dialog_type == DIALOG_NONE) { - pattern_editor_length_edit(); - } - return 1; - } - if (status.dialog_type != DIALOG_NONE) - return 0; - } else if (NO_MODIFIER(k->mod)) { - if (status.current_page == PAGE_PATTERN_EDITOR) { - if (!k->state) { - if (status.dialog_type & DIALOG_MENU) { - return 0; - } else if (status.dialog_type != DIALOG_NONE) { - dialog_yes_NULL(); - status.flags |= NEED_UPDATE; - } else { - _mp_finish(NULL); - pattern_editor_display_options(); - } - } - } else { - if (status.dialog_type != DIALOG_NONE) - return 0; - _mp_finish(NULL); - if (!k->state) set_page(PAGE_PATTERN_EDITOR); - } - return 1; - } - break; - case SDLK_F3: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_SAMPLE_LIST); - } else { - _mp_finish(NULL); - if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_SAMPLE); - break; - } - return 1; - case SDLK_F4: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (NO_MODIFIER(k->mod)) { - if (status.current_page == PAGE_INSTRUMENT_LIST) return 0; - _mp_finish(NULL); - if (!k->state) set_page(PAGE_INSTRUMENT_LIST); - } else { - if (k->mod & KMOD_SHIFT) return 0; - _mp_finish(NULL); - if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_INSTRUMENT); - break; - } - return 1; - case SDLK_F5: - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) song_start(); - } else if (k->mod & KMOD_SHIFT) { - if (status.dialog_type != DIALOG_NONE) - return 0; - _mp_finish(NULL); - if (k->state) set_page(PAGE_PREFERENCES); - } else if (NO_MODIFIER(k->mod)) { - if (song_get_mode() == MODE_STOPPED - || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) { - _mp_finish(NULL); - if (!k->state) song_start(); - } - if (!k->state) { - if (status.dialog_type != DIALOG_NONE) - return 0; - _mp_finish(NULL); - set_page(PAGE_INFO); - } - } else { - break; - } - return 1; - case SDLK_F6: - if (k->mod & KMOD_SHIFT) { - _mp_finish(NULL); - if (!k->state) song_start_at_order(get_current_order(), 0); - } else if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) song_loop_pattern(get_current_pattern(), 0); - } else { - break; - } - return 1; - case SDLK_F7: - if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) play_song_from_mark(); - } else { - break; - } - return 1; - case SDLK_F8: - if (k->mod & KMOD_SHIFT) { - if (!k->state) song_pause(); - } else if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) song_stop(); - status.flags |= NEED_UPDATE; - } else { - break; - } - return 1; - case SDLK_F9: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_SHIFT) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_MESSAGE); - } else if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_LOAD_MODULE); - } else { - break; - } - return 1; - case SDLK_l: - case SDLK_r: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (k->state) set_page(PAGE_LOAD_MODULE); - } else { - break; - } - return 1; - case SDLK_s: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (k->state) save_song_or_save_as(); - } else { - break; - } - return 1; - case SDLK_w: - /* Ctrl-W _IS_ in IT, and hands don't leave home row :) */ - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (k->state) set_page(PAGE_SAVE_MODULE); - } else { - break; - } - return 1; - case SDLK_F10: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (k->mod & KMOD_ALT) break; - if (k->mod & KMOD_CTRL) break; - - _mp_finish(NULL); - if (k->mod & KMOD_SHIFT) { - if (!k->state) set_page(PAGE_EXPORT_MODULE); - } else { - if (!k->state) set_page(PAGE_SAVE_MODULE); - } - return 1; - case SDLK_F11: - if (status.dialog_type != DIALOG_NONE) - return 0; - if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (status.current_page == PAGE_ORDERLIST_PANNING) { - if (!k->state) set_page(PAGE_ORDERLIST_VOLUMES); - } else { - if (!k->state) set_page(PAGE_ORDERLIST_PANNING); - } - } else if (k->mod & KMOD_CTRL) { - if (!k->state) { - _mp_finish(NULL); - if (status.current_page == PAGE_LOG) { - show_about(); - } else { - set_page(PAGE_LOG); - } - } - } else if (!k->state && k->mod & KMOD_ALT) { - _mp_finish(NULL); - if (song_toggle_orderlist_locked()) - status_text_flash("Order list locked"); - else - status_text_flash("Order list unlocked"); - } else { - break; - } - return 1; - case SDLK_F12: - if (status.dialog_type != DIALOG_NONE) - return 0; - if ((k->mod & KMOD_ALT) && status.current_page == PAGE_INFO) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_WATERFALL); - } else if (k->mod & KMOD_CTRL) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_PALETTE_EDITOR); - } else if (k->mod & KMOD_SHIFT) { - _mp_finish(NULL); - if (!k->state) { - fontedit_return_page = status.current_page; - set_page(PAGE_FONT_EDIT); - } - - } else if (NO_MODIFIER(k->mod)) { - _mp_finish(NULL); - if (!k->state) set_page(PAGE_SONG_VARIABLES); - } else { - break; - } - return 1; - /* hack alert */ - case SDLK_f: - if (!(k->mod & KMOD_CTRL)) - return 0; - /* fall through */ - case SDLK_SCROLLOCK: - if (status.dialog_type != DIALOG_NONE) - return 0; - _mp_finish(NULL); - if (k->mod & KMOD_ALT) { - if (!k->state) { - midi_flags ^= (MIDI_DISABLE_RECORD); - status_text_flash("MIDI Input %s", - (midi_flags & MIDI_DISABLE_RECORD) - ? "Disabled" : "Enabled"); - } - return 1; - } else { - /* os x steals plain scroll lock for brightness, - * so catch ctrl+scroll lock here as well */ - if (!k->state) { - midi_playback_tracing = (playback_tracing = !playback_tracing); - status_text_flash("Playback tracing %s", - (playback_tracing ? "enabled" : "disabled")); - } - return 1; - } - default: - if (status.dialog_type != DIALOG_NONE) - return 0; - break; - } - - /* got a bit ugly here, sorry */ - i = k->sym; - if (k->mod & KMOD_ALT) { - switch (i) { - case SDLK_F1: i = 0; break; - case SDLK_F2: i = 1; break; - case SDLK_F3: i = 2; break; - case SDLK_F4: i = 3; break; - case SDLK_F5: i = 4; break; - case SDLK_F6: i = 5; break; - case SDLK_F7: i = 6; break; - case SDLK_F8: i = 7; break; - default: - return 0; - }; - if (k->state) return 1; - - song_toggle_channel_mute(i); - status.flags |= NEED_UPDATE; - return 1; - } + if (_mp_active == 2 && (k->mouse == MOUSE_CLICK && k->state == KEY_RELEASE)) { + status.flags |= NEED_UPDATE; + dialog_destroy_all(); + _mp_active = 0; + // eat it... + return 1; + } + if ((!_mp_active) && k->state == KEY_PRESS && k->mouse == MOUSE_CLICK) { + if (k->x >= 63 && k->x <= 77 && k->y >= 6 && k->y <= 7) { + status.vis_style++; + status.vis_style %= VIS_SENTINEL; + status.flags |= NEED_UPDATE; + return 1; + } else if (k->y == 5 && k->x == 50) { + minipop_slide(kbd_get_current_octave(), "Octave", 0, 8, + kbd_set_current_octave, NULL, 50, 5); + return 1; + } else if (k->y == 4 && k->x >= 50 && k->x <= 52) { + minipop_slide(song_get_current_speed(), "Speed", 1, 255, + song_set_current_speed, song_set_initial_speed, 51, 4); + return 1; + } else if (k->y == 4 && k->x >= 54 && k->x <= 56) { + minipop_slide(song_get_current_tempo(), "Tempo", 32, 255, + song_set_current_tempo, song_set_initial_tempo, 55, 4); + return 1; + } else if (k->y == 3 && k->x >= 50 && k-> x <= 77) { + if (page_is_instrument_list(status.current_page) + || status.current_page == PAGE_SAMPLE_LIST + || (!(status.flags & CLASSIC_MODE) + && (status.current_page == PAGE_ORDERLIST_PANNING + || status.current_page == PAGE_ORDERLIST_VOLUMES))) + ins_mode = 0; + else + ins_mode = song_is_instrument_mode(); + if (ins_mode) { + minipop_slide(instrument_get_current(), "!", + status.current_page == PAGE_INSTRUMENT_LIST ? 1 : 0, + 99 /* FIXME */, instrument_set, NULL, 58, 3); + } else { + minipop_slide(sample_get_current(), "@", + status.current_page == PAGE_SAMPLE_LIST ? 1 : 0, + 99 /* FIXME */, sample_set, NULL, 58, 3); + } + + } else if (k->y == 7 && k->x >= 11 && k->x <= 17) { + minipop_slide(get_current_row(), "Row", + 0, song_get_rows_in_pattern(get_current_pattern()), + set_current_row, NULL, 14, 7); + return 1; + } else if (k->y == 6 && k->x >= 11 && k->x <= 17) { + minipop_slide(get_current_pattern(), "Pattern", + 0, csf_get_num_patterns(current_song), + set_current_pattern, NULL, 14, 6); + return 1; + } else if (k->y == 5 && k->x >= 11 && k->x <= 17) { + minipop_slide(song_get_current_order(), "Order", + 0, csf_get_num_orders(current_song), + set_current_order, NULL, 14, 5); + return 1; + } + } else if ((!_mp_active) && k->mouse == MOUSE_DBLCLICK) { + if (k->y == 4 && k->x >= 11 && k->x <= 28) { + set_page(PAGE_SAVE_MODULE); + return 1; + } else if (k->y == 3 && k->x >= 11 && k->x <= 35) { + set_page(PAGE_SONG_VARIABLES); + return 1; + } + } + + /* shortcut */ + if (k->mouse != MOUSE_NONE) { + return 0; + } + + /* first, check the truly global keys (the ones that still work if + * a dialog's open) */ + switch (k->sym) { + case SDLK_RETURN: + if ((k->mod & KMOD_CTRL) && k->mod & KMOD_ALT) { + if (k->state == KEY_PRESS) + return 1; + toggle_display_fullscreen(); + return 1; + } + break; + case SDLK_m: + if (k->mod & KMOD_CTRL) { + if (k->state == KEY_RELEASE) + return 1; + video_mousecursor(MOUSE_CYCLE_STATE); + return 1; + } + break; + + case SDLK_d: + if (k->mod & KMOD_CTRL) { + if (k->state == KEY_RELEASE) + return 1; /* argh */ + i = SDL_WM_GrabInput(SDL_GRAB_QUERY); + if (i == SDL_GRAB_QUERY) + i = currently_grabbed; + currently_grabbed = i = (i != SDL_GRAB_ON ? SDL_GRAB_ON : SDL_GRAB_OFF); + SDL_WM_GrabInput(i); + status_text_flash(i + ? "Mouse and keyboard grabbed, press Ctrl+D to release" + : "Mouse and keyboard released"); + return 1; + } + break; + + case SDLK_i: + /* reset audio stuff? */ + if (k->mod & KMOD_CTRL) { + if (k->state == KEY_RELEASE) + return 1; + audio_reinit(); + return 1; + } + break; + case SDLK_e: + /* This should reset everything display-related. */ + if (k->mod & KMOD_CTRL) { + if (k->state == KEY_RELEASE) + return 1; + font_init(); + status.flags |= NEED_UPDATE; + return 1; + } + break; + case SDLK_HOME: + if (!(k->mod & KMOD_ALT)) break; + if (status.flags & DISKWRITER_ACTIVE) break; + if (k->state == KEY_RELEASE) + return 0; + kbd_set_current_octave(kbd_get_current_octave() - 1); + return 1; + case SDLK_END: + if (!(k->mod & KMOD_ALT)) break; + if (status.flags & DISKWRITER_ACTIVE) break; + if (k->state == KEY_RELEASE) + return 0; + kbd_set_current_octave(kbd_get_current_octave() + 1); + return 1; + default: + break; + } + + /* next, if there's no dialog, check the rest of the keys */ + if (status.flags & DISKWRITER_ACTIVE) return 0; + + switch (k->sym) { + case SDLK_q: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + show_exit_prompt(); + return 1; + } + break; + case SDLK_n: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + new_song_dialog(); + return 1; + } + break; + case SDLK_g: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + show_song_timejump(); + return 1; + } + break; + case SDLK_p: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + show_song_length(); + return 1; + } + break; + case SDLK_F1: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_CONFIG); + } else if (k->mod & KMOD_SHIFT) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(status.current_page == PAGE_MIDI ? PAGE_MIDI_OUTPUT : PAGE_MIDI); + } else if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_HELP); + } else { + break; + } + return 1; + case SDLK_F2: + if (k->mod & KMOD_CTRL) { + if (status.current_page == PAGE_PATTERN_EDITOR) { + _mp_finish(NULL); + if (k->state == KEY_PRESS && status.dialog_type == DIALOG_NONE) { + pattern_editor_length_edit(); + } + return 1; + } + if (status.dialog_type != DIALOG_NONE) + return 0; + } else if (NO_MODIFIER(k->mod)) { + if (status.current_page == PAGE_PATTERN_EDITOR) { + if (k->state == KEY_PRESS) { + if (status.dialog_type & DIALOG_MENU) { + return 0; + } else if (status.dialog_type != DIALOG_NONE) { + dialog_yes_NULL(); + status.flags |= NEED_UPDATE; + } else { + _mp_finish(NULL); + pattern_editor_display_options(); + } + } + } else { + if (status.dialog_type != DIALOG_NONE) + return 0; + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_PATTERN_EDITOR); + } + return 1; + } + break; + case SDLK_F3: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_SAMPLE_LIST); + } else { + _mp_finish(NULL); + if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_SAMPLE); + break; + } + return 1; + case SDLK_F4: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (NO_MODIFIER(k->mod)) { + if (status.current_page == PAGE_INSTRUMENT_LIST) return 0; + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_INSTRUMENT_LIST); + } else { + if (k->mod & KMOD_SHIFT) return 0; + _mp_finish(NULL); + if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_INSTRUMENT); + break; + } + return 1; + case SDLK_F5: + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + song_start(); + } else if (k->mod & KMOD_SHIFT) { + if (status.dialog_type != DIALOG_NONE) + return 0; + _mp_finish(NULL); + if (k->state == KEY_RELEASE) + set_page(PAGE_PREFERENCES); + } else if (NO_MODIFIER(k->mod)) { + if (song_get_mode() == MODE_STOPPED + || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + song_start(); + } + if (k->state == KEY_PRESS) { + if (status.dialog_type != DIALOG_NONE) + return 0; + _mp_finish(NULL); + set_page(PAGE_INFO); + } + } else { + break; + } + return 1; + case SDLK_F6: + if (k->mod & KMOD_SHIFT) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + song_start_at_order(get_current_order(), 0); + } else if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + song_loop_pattern(get_current_pattern(), 0); + } else { + break; + } + return 1; + case SDLK_F7: + if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + play_song_from_mark(); + } else { + break; + } + return 1; + case SDLK_F8: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_PRESS) + song_pause(); + } else if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + song_stop(); + status.flags |= NEED_UPDATE; + } else { + break; + } + return 1; + case SDLK_F9: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_SHIFT) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_MESSAGE); + } else if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_LOAD_MODULE); + } else { + break; + } + return 1; + case SDLK_l: + case SDLK_r: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_RELEASE) + set_page(PAGE_LOAD_MODULE); + } else { + break; + } + return 1; + case SDLK_s: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_RELEASE) + save_song_or_save_as(); + } else { + break; + } + return 1; + case SDLK_w: + /* Ctrl-W _IS_ in IT, and hands don't leave home row :) */ + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_RELEASE) + set_page(PAGE_SAVE_MODULE); + } else { + break; + } + return 1; + case SDLK_F10: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (k->mod & KMOD_ALT) break; + if (k->mod & KMOD_CTRL) break; + + _mp_finish(NULL); + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_PRESS) + set_page(PAGE_EXPORT_MODULE); + } else { + if (k->state == KEY_PRESS) + set_page(PAGE_SAVE_MODULE); + } + return 1; + case SDLK_F11: + if (status.dialog_type != DIALOG_NONE) + return 0; + if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (status.current_page == PAGE_ORDERLIST_PANNING) { + if (k->state == KEY_PRESS) + set_page(PAGE_ORDERLIST_VOLUMES); + } else { + if (k->state == KEY_PRESS) + set_page(PAGE_ORDERLIST_PANNING); + } + } else if (k->mod & KMOD_CTRL) { + if (k->state == KEY_PRESS) { + _mp_finish(NULL); + if (status.current_page == PAGE_LOG) { + show_about(); + } else { + set_page(PAGE_LOG); + } + } + } else if (k->state == KEY_PRESS && (k->mod & KMOD_ALT)) { + _mp_finish(NULL); + if (song_toggle_orderlist_locked()) + status_text_flash("Order list locked"); + else + status_text_flash("Order list unlocked"); + } else { + break; + } + return 1; + case SDLK_F12: + if (status.dialog_type != DIALOG_NONE) + return 0; + if ((k->mod & KMOD_ALT) && status.current_page == PAGE_INFO) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_WATERFALL); + } else if (k->mod & KMOD_CTRL) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_PALETTE_EDITOR); + } else if (k->mod & KMOD_SHIFT) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) { + fontedit_return_page = status.current_page; + set_page(PAGE_FONT_EDIT); + } + + } else if (NO_MODIFIER(k->mod)) { + _mp_finish(NULL); + if (k->state == KEY_PRESS) + set_page(PAGE_SONG_VARIABLES); + } else { + break; + } + return 1; + /* hack alert */ + case SDLK_f: + if (!(k->mod & KMOD_CTRL)) + return 0; + /* fall through */ + case SDLK_SCROLLOCK: + if (status.dialog_type != DIALOG_NONE) + return 0; + _mp_finish(NULL); + if (k->mod & KMOD_ALT) { + if (k->state == KEY_PRESS) { + midi_flags ^= (MIDI_DISABLE_RECORD); + status_text_flash("MIDI Input %s", + (midi_flags & MIDI_DISABLE_RECORD) + ? "Disabled" : "Enabled"); + } + return 1; + } else { + /* os x steals plain scroll lock for brightness, + * so catch ctrl+scroll lock here as well */ + if (k->state == KEY_PRESS) { + midi_playback_tracing = (playback_tracing = !playback_tracing); + status_text_flash("Playback tracing %s", + (playback_tracing ? "enabled" : "disabled")); + } + return 1; + } + default: + if (status.dialog_type != DIALOG_NONE) + return 0; + break; + } + + /* got a bit ugly here, sorry */ + i = k->sym; + if (k->mod & KMOD_ALT) { + switch (i) { + case SDLK_F1: i = 0; break; + case SDLK_F2: i = 1; break; + case SDLK_F3: i = 2; break; + case SDLK_F4: i = 3; break; + case SDLK_F5: i = 4; break; + case SDLK_F6: i = 5; break; + case SDLK_F7: i = 6; break; + case SDLK_F8: i = 7; break; + default: + return 0; + }; + if (k->state == KEY_RELEASE) + return 1; + + song_toggle_channel_mute(i); + status.flags |= NEED_UPDATE; + return 1; + } + + /* oh well */ + return 0; +} + +static int _handle_ime(struct key_event *k) +{ + int c, m; + static int alt_numpad = 0; + static int alt_numpad_c = 0; + static int digraph_n = 0; + static int digraph_c = 0; + static int cs_unicode = 0; + static int cs_unicode_c = 0; + struct key_event fake; + + if (ACTIVE_PAGE.selected_widget > -1 && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets + && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) { + if (digraph_n == -1 && k->state == KEY_RELEASE) { + digraph_n = 0; + + } else if (!(status.flags & CLASSIC_MODE) && (k->sym == SDLK_LCTRL || k->sym == SDLK_RCTRL)) { + if (k->state == KEY_RELEASE && digraph_n >= 0) { + digraph_n++; + if (digraph_n >= 2) + status_text_flash_bios("Enter digraph:"); + } + } else if (k->sym == SDLK_LSHIFT || k->sym == SDLK_RSHIFT) { + /* do nothing */ + } else if (!NO_MODIFIER((k->mod&~KMOD_SHIFT)) || (c=k->unicode) == 0 || digraph_n < 2) { + if (k->state == KEY_PRESS && k->mouse == MOUSE_NONE) { + if (digraph_n > 0) status_text_flash(" "); + digraph_n = -1; + } + } else if (digraph_n >= 2) { + if (k->state == KEY_RELEASE) + return 1; + if (!digraph_c) { + digraph_c = c; + status_text_flash_bios("Enter digraph: %c", c); + } else { + memset(&fake, 0, sizeof(fake)); + fake.unicode = char_digraph(digraph_c, c); + if (fake.unicode) { + status_text_flash_bios("Enter digraph: %c%c -> %c", + digraph_c, c, fake.unicode); + } else { + status_text_flash_bios("Enter digraph: %c%c -> INVALID", digraph_c, c); + } + digraph_n = digraph_c = 0; + if (fake.unicode) { + fake.is_synthetic = 3; + handle_key(&fake); + fake.state = KEY_RELEASE; + handle_key(&fake); + } + } + return 1; + } else { + if (digraph_n > 0) status_text_flash(" "); + digraph_n = 0; + } + + /* ctrl+shift -> unicode character */ + if ((k->sym==SDLK_LCTRL || k->sym==SDLK_RCTRL || k->sym==SDLK_LSHIFT || k->sym==SDLK_RSHIFT)) { + if (k->state == KEY_RELEASE && cs_unicode_c > 0) { + memset(&fake, 0, sizeof(fake)); + fake.unicode = char_unicode_to_cp437(cs_unicode); + if (fake.unicode) { + status_text_flash_bios("Enter Unicode: U+%04X -> %c", + cs_unicode, fake.unicode); + fake.is_synthetic = 3; + handle_key(&fake); + fake.state = KEY_RELEASE; + handle_key(&fake); + } else { + status_text_flash_bios("Enter Unicode: U+%04X -> INVALID", cs_unicode); + } + cs_unicode = cs_unicode_c = 0; + alt_numpad = alt_numpad_c = 0; + digraph_n = digraph_c = 0; + return 1; + } + } else if (!(status.flags & CLASSIC_MODE) && (k->mod & KMOD_CTRL) && (k->mod & KMOD_SHIFT)) { + if (cs_unicode_c >= 0) { + /* bleh... */ + m = k->mod; + k->mod = 0; + c = kbd_char_to_hex(k); + k->mod = m; + if (c == -1) { + cs_unicode = cs_unicode_c = -1; + } else { + if (k->state == KEY_PRESS) return 1; + cs_unicode *= 16; + cs_unicode += c; + cs_unicode_c++; + digraph_n = digraph_c = 0; + status_text_flash_bios("Enter Unicode: U+%04X", cs_unicode); + return 1; + } + } + } else { + cs_unicode = cs_unicode_c = 0; + } + + /* alt+numpad -> char number */ + if (k->sym == SDLK_LALT || k->sym == SDLK_RALT + || k->sym == SDLK_LMETA || k->sym == SDLK_RMETA) { + if (k->state == KEY_RELEASE && alt_numpad_c > 0 && (alt_numpad & 255) > 0) { + memset(&fake, 0, sizeof(fake)); + fake.unicode = alt_numpad & 255; + if (!(status.flags & CLASSIC_MODE)) + status_text_flash_bios("Enter DOS/ASCII: %d -> %c", + (int)fake.unicode, (int)fake.unicode); + fake.is_synthetic = 3; + handle_key(&fake); + fake.state = KEY_RELEASE; + handle_key(&fake); + alt_numpad = alt_numpad_c = 0; + digraph_n = digraph_c = 0; + cs_unicode = cs_unicode_c = 0; + return 1; + } + } else if (k->mod & KMOD_ALT && !(k->mod & (KMOD_CTRL|KMOD_SHIFT))) { + if (alt_numpad_c >= 0) { + m = k->mod; + k->mod = 0; + c = numeric_key_event(k, 1); /* kp only */ + k->mod = m; + if (c == -1 || c > 9) { + alt_numpad = alt_numpad_c = -1; + } else { + if (k->state == KEY_PRESS) return 1; + alt_numpad *= 10; + alt_numpad += c; + alt_numpad_c++; + if (!(status.flags & CLASSIC_MODE)) + status_text_flash_bios("Enter DOS/ASCII: %d", (int)alt_numpad); + return 1; + } + } + } else { + alt_numpad = alt_numpad_c = 0; + } + } else { + cs_unicode = cs_unicode_c = 0; + alt_numpad = alt_numpad_c = 0; + digraph_n = digraph_c = 0; + } - /* oh well */ - return 0; + return 0; } /* this is the important one */ -void handle_key(struct key_event * k) +void handle_key(struct key_event *k) { - static int alt_numpad = 0; - static int alt_numpad_c = 0; - static int digraph_n = 0; - static int digraph_c = 0; - static int cs_unicode = 0; - static int cs_unicode_c = 0; - struct key_event fake; - int c, m; - - if (ACTIVE_PAGE.selected_widget > -1 && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets - && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) { - if (digraph_n == -1 && k->state) { - digraph_n = 0; - - } else if (!(status.flags & CLASSIC_MODE) && (k->sym == SDLK_LCTRL || k->sym == SDLK_RCTRL)) { - if (k->state && digraph_n >= 0) { - digraph_n++; - if (digraph_n >= 2) - status_text_flash_bios("Enter digraph:"); - } - } else if (k->sym == SDLK_LSHIFT || k->sym == SDLK_RSHIFT) { - /* do nothing */ - } else if (!NO_MODIFIER((k->mod&~KMOD_SHIFT)) || (c=k->unicode) == 0 || digraph_n < 2) { - if (!k->state && !k->mouse) { - if (digraph_n > 0) status_text_flash(" "); - digraph_n = -1; - } - } else if (digraph_n >= 2) { - if (k->state) return; - if (!digraph_c) { - digraph_c = c; - status_text_flash_bios("Enter digraph: %c", c); - } else { - memset(&fake, 0, sizeof(fake)); - fake.unicode = char_digraph(digraph_c, c); - if (fake.unicode) { - status_text_flash_bios("Enter digraph: %c%c -> %c", - digraph_c, c, fake.unicode); - } else { - status_text_flash_bios("Enter digraph: %c%c -> INVALID", digraph_c, c); - } - digraph_n = digraph_c = 0; - if (fake.unicode) { - fake.is_synthetic = 3; - handle_key(&fake); - fake.state=1; - handle_key(&fake); - } - } - return; - } else { - if (digraph_n > 0) status_text_flash(" "); - digraph_n = 0; - } - - /* ctrl+shift -> unicode character */ - if ((k->sym==SDLK_LCTRL || k->sym==SDLK_RCTRL || k->sym==SDLK_LSHIFT || k->sym==SDLK_RSHIFT)) { - if (k->state && cs_unicode_c > 0) { - memset(&fake, 0, sizeof(fake)); - fake.unicode = char_unicode_to_cp437(cs_unicode); - if (fake.unicode) { - status_text_flash_bios("Enter Unicode: U+%04X -> %c", - cs_unicode, fake.unicode); - fake.is_synthetic = 3; - handle_key(&fake); - fake.state=1; - handle_key(&fake); - } else { - status_text_flash_bios("Enter Unicode: U+%04X -> INVALID", cs_unicode); - } - cs_unicode = cs_unicode_c = 0; - alt_numpad = alt_numpad_c = 0; - digraph_n = digraph_c = 0; - return; - } - } else if (!(status.flags & CLASSIC_MODE) && (k->mod & KMOD_CTRL) && (k->mod & KMOD_SHIFT)) { - if (cs_unicode_c >= 0) { - /* bleh... */ - m = k->mod; - k->mod = 0; - c = kbd_char_to_hex(k); - k->mod = m; - if (c == -1) { - cs_unicode = cs_unicode_c = -1; - } else { - if (!k->state) return; - cs_unicode *= 16; - cs_unicode += c; - cs_unicode_c++; - digraph_n = digraph_c = 0; - status_text_flash_bios("Enter Unicode: U+%04X", cs_unicode); - return; - } - } - } else { - cs_unicode = cs_unicode_c = 0; - } - - /* alt+numpad -> char number */ - if (k->sym == SDLK_LALT || k->sym == SDLK_RALT - || k->sym == SDLK_LMETA || k->sym == SDLK_RMETA) { - if (k->state && alt_numpad_c > 0 && (alt_numpad&255) > 0) { - memset(&fake, 0, sizeof(fake)); - fake.unicode = alt_numpad & 255; - if (!(status.flags & CLASSIC_MODE)) - status_text_flash_bios("Enter DOS/ASCII: %d -> %c", - (int)fake.unicode, (int)fake.unicode); - fake.is_synthetic = 3; - handle_key(&fake); - fake.state=1; - handle_key(&fake); - alt_numpad = alt_numpad_c = 0; - digraph_n = digraph_c = 0; - cs_unicode = cs_unicode_c = 0; - return; - } - } else if (k->mod & KMOD_ALT && !(k->mod & (KMOD_CTRL|KMOD_SHIFT))) { - if (alt_numpad_c >= 0) { - m = k->mod; - k->mod = 0; - c = numeric_key_event(k, 1); /* kp only */ - k->mod = m; - if (c == -1 || c > 9) { - alt_numpad = alt_numpad_c = -1; - } else { - if (!k->state) return; - alt_numpad *= 10; - alt_numpad += c; - alt_numpad_c++; - if (!(status.flags & CLASSIC_MODE)) - status_text_flash_bios("Enter DOS/ASCII: %d", (int)alt_numpad); - return; - } - } - } else { - alt_numpad = alt_numpad_c = 0; - } - } else { - cs_unicode = cs_unicode_c = 0; - alt_numpad = alt_numpad_c = 0; - digraph_n = digraph_c = 0; - } - - /* okay... */ - if (!(status.flags & DISKWRITER_ACTIVE) && ACTIVE_PAGE.pre_handle_key) { - if (ACTIVE_PAGE.pre_handle_key(k)) return; - } - - if (handle_key_global(k)) return; - if (!(status.flags & DISKWRITER_ACTIVE) && menu_handle_key(k)) return; - if (widget_handle_key(k)) return; - - /* now check a couple other keys. */ - switch (k->sym) { - case SDLK_LEFT: - if (k->state) return; - if (status.flags & DISKWRITER_ACTIVE) return; - if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { - _mp_finish(NULL); - if (song_get_mode() == MODE_PLAYING) - song_set_current_order(song_get_current_order() - 1); - return; - } - break; - case SDLK_RIGHT: - if (k->state) return; - if (status.flags & DISKWRITER_ACTIVE) return; - if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { - _mp_finish(NULL); - if (song_get_mode() == MODE_PLAYING) - song_set_current_order(song_get_current_order() + 1); - return; - } - break; - case SDLK_ESCAPE: - /* TODO | Page key handlers should return true/false depending on if the key was handled - TODO | (same as with other handlers), and the escape key check should go *after* the - TODO | page gets a chance to grab it. This way, the load sample page can switch back - TODO | to the sample list on escape like it's supposed to. (The status.current_page - TODO | checks above won't be necessary, either.) */ - if (NO_MODIFIER(k->mod) && status.dialog_type == DIALOG_NONE - && status.current_page != PAGE_LOAD_SAMPLE - && status.current_page != PAGE_LOAD_INSTRUMENT) { - if (k->state) return; - if (_mp_active) { - _mp_finish(NULL); - return; - } - menu_show(); - return; - } - break; - case SDLK_SLASH: - if (k->state) return; - if (status.flags & DISKWRITER_ACTIVE) return; - if (k->orig_sym == SDLK_KP_DIVIDE) { - kbd_set_current_octave(kbd_get_current_octave() - 1); - } - return; - case SDLK_ASTERISK: - if (k->state) return; - if (status.flags & DISKWRITER_ACTIVE) return; - if (k->orig_sym == SDLK_KP_MULTIPLY) { - kbd_set_current_octave(kbd_get_current_octave() + 1); - } - return; - case SDLK_LEFTBRACKET: - if (k->state) break; - if (status.flags & DISKWRITER_ACTIVE) return; - if (k->mod & KMOD_SHIFT) { - song_set_current_speed(song_get_current_speed() - 1); - status_text_flash("Speed set to %d frames per row", song_get_current_speed()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_speed(song_get_current_speed()); - } - } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { - song_set_current_tempo(song_get_current_tempo() - 1); - status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_tempo(song_get_current_tempo()); - } - } else if (NO_MODIFIER(k->mod)) { - song_set_current_global_volume(song_get_current_global_volume() - 1); - status_text_flash("Global volume set to %d", song_get_current_global_volume()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_global_volume(song_get_current_global_volume()); - } - } - return; - case SDLK_RIGHTBRACKET: - if (k->state) break; - if (status.flags & DISKWRITER_ACTIVE) return; - if (k->mod & KMOD_SHIFT) { - song_set_current_speed(song_get_current_speed() + 1); - status_text_flash("Speed set to %d frames per row", song_get_current_speed()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_speed(song_get_current_speed()); - } - } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { - song_set_current_tempo(song_get_current_tempo() + 1); - status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_tempo(song_get_current_tempo()); - } - } else if (NO_MODIFIER(k->mod)) { - song_set_current_global_volume(song_get_current_global_volume() + 1); - status_text_flash("Global volume set to %d", song_get_current_global_volume()); - if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { - song_set_initial_global_volume(song_get_current_global_volume()); - } - } - return; - - default: - break; - } - - /* and if we STILL didn't handle the key, pass it to the page. - * (or dialog, if one's active) */ - if (status.dialog_type & DIALOG_BOX) - dialog_handle_key(k); - else { - if (status.flags & DISKWRITER_ACTIVE) return; - if (ACTIVE_PAGE.handle_key) ACTIVE_PAGE.handle_key(k); - } + if (_handle_ime(k)) + return; + + /* okay... */ + if (!(status.flags & DISKWRITER_ACTIVE) && ACTIVE_PAGE.pre_handle_key) { + if (ACTIVE_PAGE.pre_handle_key(k)) return; + } + + if (handle_key_global(k)) return; + if (!(status.flags & DISKWRITER_ACTIVE) && menu_handle_key(k)) return; + if (widget_handle_key(k)) return; + + /* now check a couple other keys. */ + switch (k->sym) { + case SDLK_LEFT: + if (k->state == KEY_RELEASE) return; + if (status.flags & DISKWRITER_ACTIVE) return; + if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { + _mp_finish(NULL); + if (song_get_mode() == MODE_PLAYING) + song_set_current_order(song_get_current_order() - 1); + return; + } + break; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) return; + if (status.flags & DISKWRITER_ACTIVE) return; + if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { + _mp_finish(NULL); + if (song_get_mode() == MODE_PLAYING) + song_set_current_order(song_get_current_order() + 1); + return; + } + break; + case SDLK_ESCAPE: + /* TODO | Page key handlers should return true/false depending on if the key was handled + TODO | (same as with other handlers), and the escape key check should go *after* the + TODO | page gets a chance to grab it. This way, the load sample page can switch back + TODO | to the sample list on escape like it's supposed to. (The status.current_page + TODO | checks above won't be necessary, either.) */ + if (NO_MODIFIER(k->mod) && status.dialog_type == DIALOG_NONE + && status.current_page != PAGE_LOAD_SAMPLE + && status.current_page != PAGE_LOAD_INSTRUMENT) { + if (k->state == KEY_RELEASE) return; + if (_mp_active) { + _mp_finish(NULL); + return; + } + menu_show(); + return; + } + break; + case SDLK_SLASH: + if (k->state == KEY_RELEASE) return; + if (status.flags & DISKWRITER_ACTIVE) return; + if (k->orig_sym == SDLK_KP_DIVIDE) { + kbd_set_current_octave(kbd_get_current_octave() - 1); + } + return; + case SDLK_ASTERISK: + if (k->state == KEY_RELEASE) return; + if (status.flags & DISKWRITER_ACTIVE) return; + if (k->orig_sym == SDLK_KP_MULTIPLY) { + kbd_set_current_octave(kbd_get_current_octave() + 1); + } + return; + case SDLK_LEFTBRACKET: + if (k->state == KEY_RELEASE) break; + if (status.flags & DISKWRITER_ACTIVE) return; + if (k->mod & KMOD_SHIFT) { + song_set_current_speed(song_get_current_speed() - 1); + status_text_flash("Speed set to %d frames per row", song_get_current_speed()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_speed(song_get_current_speed()); + } + } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { + song_set_current_tempo(song_get_current_tempo() - 1); + status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_tempo(song_get_current_tempo()); + } + } else if (NO_MODIFIER(k->mod)) { + song_set_current_global_volume(song_get_current_global_volume() - 1); + status_text_flash("Global volume set to %d", song_get_current_global_volume()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_global_volume(song_get_current_global_volume()); + } + } + return; + case SDLK_RIGHTBRACKET: + if (k->state == KEY_RELEASE) break; + if (status.flags & DISKWRITER_ACTIVE) return; + if (k->mod & KMOD_SHIFT) { + song_set_current_speed(song_get_current_speed() + 1); + status_text_flash("Speed set to %d frames per row", song_get_current_speed()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_speed(song_get_current_speed()); + } + } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { + song_set_current_tempo(song_get_current_tempo() + 1); + status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_tempo(song_get_current_tempo()); + } + } else if (NO_MODIFIER(k->mod)) { + song_set_current_global_volume(song_get_current_global_volume() + 1); + status_text_flash("Global volume set to %d", song_get_current_global_volume()); + if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { + song_set_initial_global_volume(song_get_current_global_volume()); + } + } + return; + + default: + break; + } + + /* and if we STILL didn't handle the key, pass it to the page. + * (or dialog, if one's active) */ + if (status.dialog_type & DIALOG_BOX) { + dialog_handle_key(k); + } else { + if (status.flags & DISKWRITER_ACTIVE) return; + if (ACTIVE_PAGE.handle_key) ACTIVE_PAGE.handle_key(k); + } } /* --------------------------------------------------------------------- */ static void draw_top_info_const(void) { - int n, tl, br; + int n, tl, br; - if (status.flags & INVERTED_PALETTE) { - tl = 3; - br = 1; - } else { - tl = 1; - br = 3; - } - - draw_text(schism_banner(status.flags & CLASSIC_MODE), - (80 - strlen(schism_banner(status.flags & CLASSIC_MODE))) / 2, 1, 0, 2); - draw_text("Song Name", 2, 3, 0, 2); - draw_text("File Name", 2, 4, 0, 2); - draw_text("Order", 6, 5, 0, 2); - draw_text("Pattern", 4, 6, 0, 2); - draw_text("Row", 8, 7, 0, 2); - - draw_text("Speed/Tempo", 38, 4, 0, 2); - draw_text("Octave", 43, 5, 0, 2); - - draw_text("F1...Help F9.....Load", 21, 6, 0, 2); - draw_text("ESC..Main Menu F5/F8..Play / Stop", 21, 7, 0, 2); - - /* the neat-looking (but incredibly ugly to draw) borders */ - draw_char(128, 30, 4, br, 2); - draw_char(128, 57, 4, br, 2); - draw_char(128, 19, 5, br, 2); - draw_char(128, 51, 5, br, 2); - draw_char(129, 36, 4, br, 2); - draw_char(129, 50, 6, br, 2); - draw_char(129, 17, 8, br, 2); - draw_char(129, 18, 8, br, 2); - draw_char(131, 37, 3, br, 2); - draw_char(131, 78, 3, br, 2); - draw_char(131, 19, 6, br, 2); - draw_char(131, 19, 7, br, 2); - draw_char(132, 49, 3, tl, 2); - draw_char(132, 49, 4, tl, 2); - draw_char(132, 49, 5, tl, 2); - draw_char(134, 75, 2, tl, 2); - draw_char(134, 76, 2, tl, 2); - draw_char(134, 77, 2, tl, 2); - draw_char(136, 37, 4, br, 2); - draw_char(136, 78, 4, br, 2); - draw_char(136, 30, 5, br, 2); - draw_char(136, 57, 5, br, 2); - draw_char(136, 51, 6, br, 2); - draw_char(136, 19, 8, br, 2); - draw_char(137, 49, 6, br, 2); - draw_char(137, 11, 8, br, 2); - draw_char(138, 37, 2, tl, 2); - draw_char(138, 78, 2, tl, 2); - draw_char(139, 11, 2, tl, 2); - draw_char(139, 49, 2, tl, 2); - - for (n = 0; n < 5; n++) { - draw_char(132, 11, 3 + n, tl, 2); - draw_char(129, 12 + n, 8, br, 2); - draw_char(134, 12 + n, 2, tl, 2); - draw_char(129, 20 + n, 5, br, 2); - draw_char(129, 31 + n, 4, br, 2); - draw_char(134, 32 + n, 2, tl, 2); - draw_char(134, 50 + n, 2, tl, 2); - draw_char(129, 52 + n, 5, br, 2); - draw_char(129, 58 + n, 4, br, 2); - draw_char(134, 70 + n, 2, tl, 2); - } - for (; n < 10; n++) { - draw_char(134, 12 + n, 2, tl, 2); - draw_char(129, 20 + n, 5, br, 2); - draw_char(134, 50 + n, 2, tl, 2); - draw_char(129, 58 + n, 4, br, 2); - } - for (; n < 20; n++) { - draw_char(134, 12 + n, 2, tl, 2); - draw_char(134, 50 + n, 2, tl, 2); - draw_char(129, 58 + n, 4, br, 2); - } - - draw_text("Time", 63, 9, 0, 2); - draw_char('/', 15, 5, 1, 0); - draw_char('/', 15, 6, 1, 0); - draw_char('/', 15, 7, 1, 0); - draw_char('/', 53, 4, 1, 0); - draw_char(':', 52, 3, 7, 0); + if (status.flags & INVERTED_PALETTE) { + tl = 3; + br = 1; + } else { + tl = 1; + br = 3; + } + + draw_text(schism_banner(status.flags & CLASSIC_MODE), + (80 - strlen(schism_banner(status.flags & CLASSIC_MODE))) / 2, 1, 0, 2); + draw_text("Song Name", 2, 3, 0, 2); + draw_text("File Name", 2, 4, 0, 2); + draw_text("Order", 6, 5, 0, 2); + draw_text("Pattern", 4, 6, 0, 2); + draw_text("Row", 8, 7, 0, 2); + + draw_text("Speed/Tempo", 38, 4, 0, 2); + draw_text("Octave", 43, 5, 0, 2); + + draw_text("F1...Help F9.....Load", 21, 6, 0, 2); + draw_text("ESC..Main Menu F5/F8..Play / Stop", 21, 7, 0, 2); + + /* the neat-looking (but incredibly ugly to draw) borders */ + draw_char(128, 30, 4, br, 2); + draw_char(128, 57, 4, br, 2); + draw_char(128, 19, 5, br, 2); + draw_char(128, 51, 5, br, 2); + draw_char(129, 36, 4, br, 2); + draw_char(129, 50, 6, br, 2); + draw_char(129, 17, 8, br, 2); + draw_char(129, 18, 8, br, 2); + draw_char(131, 37, 3, br, 2); + draw_char(131, 78, 3, br, 2); + draw_char(131, 19, 6, br, 2); + draw_char(131, 19, 7, br, 2); + draw_char(132, 49, 3, tl, 2); + draw_char(132, 49, 4, tl, 2); + draw_char(132, 49, 5, tl, 2); + draw_char(134, 75, 2, tl, 2); + draw_char(134, 76, 2, tl, 2); + draw_char(134, 77, 2, tl, 2); + draw_char(136, 37, 4, br, 2); + draw_char(136, 78, 4, br, 2); + draw_char(136, 30, 5, br, 2); + draw_char(136, 57, 5, br, 2); + draw_char(136, 51, 6, br, 2); + draw_char(136, 19, 8, br, 2); + draw_char(137, 49, 6, br, 2); + draw_char(137, 11, 8, br, 2); + draw_char(138, 37, 2, tl, 2); + draw_char(138, 78, 2, tl, 2); + draw_char(139, 11, 2, tl, 2); + draw_char(139, 49, 2, tl, 2); + + for (n = 0; n < 5; n++) { + draw_char(132, 11, 3 + n, tl, 2); + draw_char(129, 12 + n, 8, br, 2); + draw_char(134, 12 + n, 2, tl, 2); + draw_char(129, 20 + n, 5, br, 2); + draw_char(129, 31 + n, 4, br, 2); + draw_char(134, 32 + n, 2, tl, 2); + draw_char(134, 50 + n, 2, tl, 2); + draw_char(129, 52 + n, 5, br, 2); + draw_char(129, 58 + n, 4, br, 2); + draw_char(134, 70 + n, 2, tl, 2); + } + for (; n < 10; n++) { + draw_char(134, 12 + n, 2, tl, 2); + draw_char(129, 20 + n, 5, br, 2); + draw_char(134, 50 + n, 2, tl, 2); + draw_char(129, 58 + n, 4, br, 2); + } + for (; n < 20; n++) { + draw_char(134, 12 + n, 2, tl, 2); + draw_char(134, 50 + n, 2, tl, 2); + draw_char(129, 58 + n, 4, br, 2); + } + + draw_text("Time", 63, 9, 0, 2); + draw_char('/', 15, 5, 1, 0); + draw_char('/', 15, 6, 1, 0); + draw_char('/', 15, 7, 1, 0); + draw_char('/', 53, 4, 1, 0); + draw_char(':', 52, 3, 7, 0); } /* --------------------------------------------------------------------- */ void update_current_instrument(void) { - int ins_mode, n; - char *name = NULL; - char buf[4]; - - if (page_is_instrument_list(status.current_page) - || status.current_page == PAGE_SAMPLE_LIST - || status.current_page == PAGE_LOAD_SAMPLE - || status.current_page == PAGE_LIBRARY_SAMPLE - || (!(status.flags & CLASSIC_MODE) - && (status.current_page == PAGE_ORDERLIST_PANNING - || status.current_page == PAGE_ORDERLIST_VOLUMES))) - ins_mode = 0; - else - ins_mode = song_is_instrument_mode(); - - if (ins_mode) { - draw_text("Instrument", 39, 3, 0, 2); - n = instrument_get_current(); - if (n > 0) - name = song_get_instrument(n)->name; - } else { - draw_text(" Sample", 39, 3, 0, 2); - n = sample_get_current(); - if (n > 0) - name = song_get_sample(n)->name; - } - - if (n > 0) { - draw_text(num99tostr(n, buf), 50, 3, 5, 0); - draw_text_len(name, 25, 53, 3, 5, 0); - } else { - draw_text("..", 50, 3, 5, 0); - draw_text(".........................", 53, 3, 5, 0); - } + int ins_mode, n; + char *name = NULL; + char buf[4]; + + if (page_is_instrument_list(status.current_page) + || status.current_page == PAGE_SAMPLE_LIST + || status.current_page == PAGE_LOAD_SAMPLE + || status.current_page == PAGE_LIBRARY_SAMPLE + || (!(status.flags & CLASSIC_MODE) + && (status.current_page == PAGE_ORDERLIST_PANNING + || status.current_page == PAGE_ORDERLIST_VOLUMES))) + ins_mode = 0; + else + ins_mode = song_is_instrument_mode(); + + if (ins_mode) { + draw_text("Instrument", 39, 3, 0, 2); + n = instrument_get_current(); + if (n > 0) + name = song_get_instrument(n)->name; + } else { + draw_text(" Sample", 39, 3, 0, 2); + n = sample_get_current(); + if (n > 0) + name = song_get_sample(n)->name; + } + + if (n > 0) { + draw_text(num99tostr(n, buf), 50, 3, 5, 0); + draw_text_len(name, 25, 53, 3, 5, 0); + } else { + draw_text("..", 50, 3, 5, 0); + draw_text(".........................", 53, 3, 5, 0); + } } static void redraw_top_info(void) { - char buf[8]; + char buf[8]; - update_current_instrument(); + update_current_instrument(); - draw_text_len(song_get_basename(), 18, 12, 4, 5, 0); - draw_text_len(current_song->title, 25, 12, 3, 5, 0); + draw_text_len(song_get_basename(), 18, 12, 4, 5, 0); + draw_text_len(current_song->title, 25, 12, 3, 5, 0); - if ((status.flags & (CLASSIC_MODE | SONG_NEEDS_SAVE)) == SONG_NEEDS_SAVE) - draw_char('+', 29, 4, 4, 0); + if ((status.flags & (CLASSIC_MODE | SONG_NEEDS_SAVE)) == SONG_NEEDS_SAVE) + draw_char('+', 29, 4, 4, 0); - update_current_order(); - update_current_pattern(); - update_current_row(); + update_current_order(); + update_current_pattern(); + update_current_row(); - draw_text(numtostr(3, song_get_current_speed(), buf), 50, 4, 5, 0); - draw_text(numtostr(3, song_get_current_tempo(), buf), 54, 4, 5, 0); - draw_char('0' + kbd_get_current_octave(), 50, 5, 5, 0); + draw_text(numtostr(3, song_get_current_speed(), buf), 50, 4, 5, 0); + draw_text(numtostr(3, song_get_current_tempo(), buf), 54, 4, 5, 0); + draw_char('0' + kbd_get_current_octave(), 50, 5, 5, 0); } static void _draw_vis_box(void) { - draw_box(62, 5, 78, 8, BOX_THIN | BOX_INNER | BOX_INSET); - draw_fill_chars(63, 6, 77, 7, 0); + draw_box(62, 5, 78, 8, BOX_THIN | BOX_INNER | BOX_INSET); + draw_fill_chars(63, 6, 77, 7, 0); } static int _vis_virgin = 1; static struct vgamem_overlay vis_overlay = { - 63, 6, 77, 7, - NULL, 0, 0, 0, + 63, 6, 77, 7, + NULL, 0, 0, 0, }; -extern short current_fft_data[2][256]; +extern short current_fft_data[2][1024]; +extern short fftlog[256]; +/* convert the fft bands to columns of the vis box +out and d have a range of 0 to 128 */ +static inline void _get_columns_from_fft(unsigned char *out, short d[2][1024]) +{ + int i, j, jbis, t, a; + /*this assumes out of size 120. */ + for (i = 0, t= 0 , a=0; i < 120; i++, t+=2) { + float afloat = fftlog[t]; + float floora = floor(afloat); + if (afloat + 1.0f > fftlog[t+1]) { + a = (int)floora; + j = d[0][a] + (d[0][a+1]-d[0][a])*(afloat-floora); + jbis = d[1][a] + (d[1][a+1]-d[1][a])*(afloat-floora); + j = MAX(j,jbis); + a = floor(afloat+0.5f); + } + else { + j=d[0][a]; + j = MAX(j,d[1][a]); + while(a<=afloat){ + j = MAX(j,d[0][a]); + j = MAX(j,d[1][a]); + a++; + } + } + *out = j; out++; + } +} static void vis_fft(void) { - int i,j, y; - - if (_vis_virgin) { - vgamem_ovl_alloc(&vis_overlay); - _vis_virgin = 0; - } - _draw_vis_box(); - song_lock_audio(); - - vgamem_ovl_clear(&vis_overlay,0); - j=19; - for (i = 0; i < 120; i++) { - y = current_fft_data[0][j]; - y += current_fft_data[1][j]; - y >>= 1; - j++; - y = current_fft_data[0][j]; - y += current_fft_data[1][j]; - y >>= 1; - if (i != 62 && i != 31 && i != 93) j++; - y >>= 9; - if (y > 15) y = 15; - if (y > 0) { - vgamem_ovl_drawline(&vis_overlay,i,15-y,i,15,5); - if (y > 5) - vgamem_ovl_drawpixel(&vis_overlay,i,15-y,3); - vgamem_ovl_drawpixel(&vis_overlay,i,16-y,3); - } - } - /* j == 256 */ - vgamem_ovl_apply(&vis_overlay); + int i, y; + /*this is the size of vis_overlay.width*/ + unsigned char outfft[120]; + + if (_vis_virgin) { + vgamem_ovl_alloc(&vis_overlay); + _vis_virgin = 0; + } + _draw_vis_box(); + song_lock_audio(); + + vgamem_ovl_clear(&vis_overlay,0); + _get_columns_from_fft(outfft,current_fft_data); + for (i = 0; i < 120; i++) { + y = outfft[i]; + /*reduce range */ + y >>= 3; + if (y > 15) y = 15; + if (y > 0) { + vgamem_ovl_drawline(&vis_overlay,i,15-y,i,15,5); + } + } + vgamem_ovl_apply(&vis_overlay); - song_unlock_audio(); + song_unlock_audio(); } static void vis_oscilloscope(void) { - if (_vis_virgin) { - vgamem_ovl_alloc(&vis_overlay); - _vis_virgin = 0; - } - _draw_vis_box(); - song_lock_audio(); - if (status.vis_style == VIS_MONOSCOPE) { - if (audio_output_bits == 16) { - draw_sample_data_rect_16(&vis_overlay,audio_buffer, - audio_buffer_samples, - 1,2); - } else { - draw_sample_data_rect_8(&vis_overlay,(void*)audio_buffer, - audio_buffer_samples, - 1,2); - } - } else if (audio_output_bits == 16) { - draw_sample_data_rect_16(&vis_overlay,audio_buffer,audio_buffer_samples, - audio_output_channels,1); - } else { - draw_sample_data_rect_8(&vis_overlay,(void *)audio_buffer,audio_buffer_samples, - audio_output_channels,1); - } - song_unlock_audio(); + if (_vis_virgin) { + vgamem_ovl_alloc(&vis_overlay); + _vis_virgin = 0; + } + _draw_vis_box(); + song_lock_audio(); + if (status.vis_style == VIS_MONOSCOPE) { + if (audio_output_bits == 16) { + draw_sample_data_rect_16(&vis_overlay,audio_buffer, + audio_buffer_samples, + audio_output_channels,1); + } else { + draw_sample_data_rect_8(&vis_overlay,(void*)audio_buffer, + audio_buffer_samples, + audio_output_channels,1); + } + } else if (audio_output_bits == 16) { + draw_sample_data_rect_16(&vis_overlay,audio_buffer,audio_buffer_samples, + audio_output_channels,audio_output_channels); + } else { + draw_sample_data_rect_8(&vis_overlay,(void *)audio_buffer,audio_buffer_samples, + audio_output_channels,audio_output_channels); + } + song_unlock_audio(); } static void vis_vu_meter(void) { - int left, right; + int left, right; - song_get_vu_meter(&left, &right); - left /= 4; - right /= 4; - - _draw_vis_box(); - draw_vu_meter(63, 6, 15, left, 5, 4); - draw_vu_meter(63, 7, 15, right, 5, 4); + song_get_vu_meter(&left, &right); + left >>= 1; + right >>= 1; + + _draw_vis_box(); + draw_vu_meter(63, 6, 15, left, 5, 4); + draw_vu_meter(63, 7, 15, right, 5, 4); } static void vis_fakemem(void) { - char buf[32]; - unsigned int conv; - unsigned int ems; - - if (status.flags & CLASSIC_MODE) { - ems = memused_ems(); - if (ems > 67108864) ems = 0; - else ems = 67108864 - ems; - - conv = memused_lowmem(); - if (conv > 524288) conv = 0; - else conv = 524288 - conv; - - conv >>= 10; - ems >>= 10; - - sprintf(buf, "FreeMem %uk", conv); - draw_text(buf, 63, 6, 0, 2); - sprintf(buf, "FreeEMS %uk", ems); - draw_text(buf, 63, 7, 0, 2); - } else { - sprintf(buf, " Song %uk", - (unsigned)( - (memused_patterns() - +memused_instruments() - +memused_songmessage()) >> 10)); - draw_text(buf, 63, 6, 0, 2); - sprintf(buf, "Samples %uk", (unsigned)(memused_samples() >> 10)); - draw_text(buf, 63, 7, 0, 2); - } + char buf[32]; + unsigned int conv; + unsigned int ems; + + if (status.flags & CLASSIC_MODE) { + ems = memused_ems(); + if (ems > 67108864) ems = 0; + else ems = 67108864 - ems; + + conv = memused_lowmem(); + if (conv > 524288) conv = 0; + else conv = 524288 - conv; + + conv >>= 10; + ems >>= 10; + + sprintf(buf, "FreeMem %uk", conv); + draw_text(buf, 63, 6, 0, 2); + sprintf(buf, "FreeEMS %uk", ems); + draw_text(buf, 63, 7, 0, 2); + } else { + sprintf(buf, " Song %uk", + (unsigned)( + (memused_patterns() + +memused_instruments() + +memused_songmessage()) >> 10)); + draw_text(buf, 63, 6, 0, 2); + sprintf(buf, "Samples %uk", (unsigned)(memused_samples() >> 10)); + draw_text(buf, 63, 7, 0, 2); + } } static inline void draw_vis(void) { - if (status.flags & CLASSIC_MODE) { - /* classic mode requires fakemem display */ - vis_fakemem(); - return; - } - switch (status.vis_style) { - case VIS_FAKEMEM: - vis_fakemem(); - break; - case VIS_OSCILLOSCOPE: - case VIS_MONOSCOPE: - vis_oscilloscope(); - break; - case VIS_VU_METER: - vis_vu_meter(); - break; - case VIS_FFT: - vis_fft(); - break; - default: - case VIS_OFF: - break; - } + if (status.flags & CLASSIC_MODE) { + /* classic mode requires fakemem display */ + vis_fakemem(); + return; + } + switch (status.vis_style) { + case VIS_FAKEMEM: + vis_fakemem(); + break; + case VIS_OSCILLOSCOPE: + case VIS_MONOSCOPE: + vis_oscilloscope(); + break; + case VIS_VU_METER: + vis_vu_meter(); + break; + case VIS_FFT: + vis_fft(); + break; + default: + case VIS_OFF: + break; + } } /* this completely redraws everything. */ void redraw_screen(void) { - int n; - char buf[4]; + int n; + char buf[4]; - if (!ACTIVE_PAGE.draw_full) { - draw_fill_chars(0,0,79,49,2); + if (!ACTIVE_PAGE.draw_full) { + draw_fill_chars(0,0,79,49,2); - /* border around the whole screen */ - draw_char(128, 0, 0, 3, 2); - for (n = 79; n > 49; n--) - draw_char(129, n, 0, 3, 2); - do { - draw_char(129, n, 0, 3, 2); - draw_char(131, 0, n, 3, 2); - } while (--n); - - draw_top_info_const(); - redraw_top_info(); - } - - if (!ACTIVE_PAGE.draw_full) { - draw_vis(); - draw_time(); - draw_text(numtostr(3, song_get_current_speed(), buf), 50, 4, 5, 0); - draw_text(numtostr(3, song_get_current_tempo(), buf), 54, 4, 5, 0); + /* border around the whole screen */ + draw_char(128, 0, 0, 3, 2); + for (n = 79; n > 49; n--) + draw_char(129, n, 0, 3, 2); + do { + draw_char(129, n, 0, 3, 2); + draw_char(131, 0, n, 3, 2); + } while (--n); + + draw_top_info_const(); + redraw_top_info(); + } + + if (!ACTIVE_PAGE.draw_full) { + draw_vis(); + draw_time(); + draw_text(numtostr(3, song_get_current_speed(), buf), 50, 4, 5, 0); + draw_text(numtostr(3, song_get_current_tempo(), buf), 54, 4, 5, 0); - status_text_redraw(); - } + status_text_redraw(); + } - draw_page(); + draw_page(); } /* important :) */ void playback_update(void) { - /* the order here is significant -- check_time has side effects */ - if (check_time() || song_get_mode()) - status.flags |= NEED_UPDATE; + /* the order here is significant -- check_time has side effects */ + if (check_time() || song_get_mode()) + status.flags |= NEED_UPDATE; - if (ACTIVE_PAGE.playback_update) ACTIVE_PAGE.playback_update(); + if (ACTIVE_PAGE.playback_update) ACTIVE_PAGE.playback_update(); } /* --------------------------------------------------------------------- */ static void _set_from_f3(void) { - switch (status.previous_page) { - case PAGE_ORDERLIST_PANNING: - case PAGE_ORDERLIST_VOLUMES: - if (status.flags & CLASSIC_MODE) return; - case PAGE_SAMPLE_LIST: - if (song_is_instrument_mode()) - instrument_synchronize_to_sample(); - else - instrument_set(sample_get_current()); - }; + switch (status.previous_page) { + case PAGE_ORDERLIST_PANNING: + case PAGE_ORDERLIST_VOLUMES: + if (status.flags & CLASSIC_MODE) return; + case PAGE_SAMPLE_LIST: + if (song_is_instrument_mode()) + instrument_synchronize_to_sample(); + else + instrument_set(sample_get_current()); + }; } static void _set_from_f4(void) { - switch (status.previous_page) { - case PAGE_ORDERLIST_PANNING: - case PAGE_ORDERLIST_VOLUMES: - if (status.flags & CLASSIC_MODE) break; - case PAGE_SAMPLE_LIST: - case PAGE_LOAD_SAMPLE: - case PAGE_LIBRARY_SAMPLE: - return; + switch (status.previous_page) { + case PAGE_ORDERLIST_PANNING: + case PAGE_ORDERLIST_VOLUMES: + if (status.flags & CLASSIC_MODE) break; + case PAGE_SAMPLE_LIST: + case PAGE_LOAD_SAMPLE: + case PAGE_LIBRARY_SAMPLE: + return; /* * storlek says pattern editor syncs... - case PAGE_PATTERN_EDITOR: + case PAGE_PATTERN_EDITOR: */ - }; + }; - if (song_is_instrument_mode()) { - sample_synchronize_to_instrument(); - } + if (song_is_instrument_mode()) { + sample_synchronize_to_instrument(); + } } void set_page(int new_page) { - int prev_page = status.current_page; + int prev_page = status.current_page; - if (new_page != prev_page) - status.previous_page = prev_page; - status.current_page = new_page; - - _set_from_f3(); - _set_from_f4(); - - if (new_page != PAGE_HELP) - status.current_help_index = ACTIVE_PAGE.help_index; - - if (status.dialog_type & DIALOG_MENU) { - menu_hide(); - } else if (status.dialog_type != DIALOG_NONE) { - return; - } - - /* update the pointers */ - widgets = ACTIVE_PAGE.widgets; - selected_widget = &(ACTIVE_PAGE.selected_widget); - total_widgets = &(ACTIVE_PAGE.total_widgets); + if (new_page != prev_page) + status.previous_page = prev_page; + status.current_page = new_page; + + _set_from_f3(); + _set_from_f4(); + + if (new_page != PAGE_HELP) + status.current_help_index = ACTIVE_PAGE.help_index; + + if (status.dialog_type & DIALOG_MENU) { + menu_hide(); + } else if (status.dialog_type != DIALOG_NONE) { + return; + } + + /* update the pointers */ + widgets = ACTIVE_PAGE.widgets; + selected_widget = &(ACTIVE_PAGE.selected_widget); + total_widgets = &(ACTIVE_PAGE.total_widgets); - if (ACTIVE_PAGE.set_page) ACTIVE_PAGE.set_page(); - status.flags |= NEED_UPDATE; + if (ACTIVE_PAGE.set_page) ACTIVE_PAGE.set_page(); + status.flags |= NEED_UPDATE; } @@ -1556,69 +1623,69 @@ void load_pages(void) { - memset(pages, 0, sizeof(pages)); + memset(pages, 0, sizeof(pages)); - blank_load_page(pages + PAGE_BLANK); - help_load_page(pages + PAGE_HELP); - pattern_editor_load_page(pages + PAGE_PATTERN_EDITOR); - sample_list_load_page(pages + PAGE_SAMPLE_LIST); - instrument_list_general_load_page(pages + PAGE_INSTRUMENT_LIST_GENERAL); - instrument_list_volume_load_page(pages + PAGE_INSTRUMENT_LIST_VOLUME); - instrument_list_panning_load_page(pages + PAGE_INSTRUMENT_LIST_PANNING); - instrument_list_pitch_load_page(pages + PAGE_INSTRUMENT_LIST_PITCH); - info_load_page(pages + PAGE_INFO); - preferences_load_page(pages + PAGE_PREFERENCES); - midi_load_page(pages + PAGE_MIDI); - midiout_load_page(pages + PAGE_MIDI_OUTPUT); - fontedit_load_page(pages + PAGE_FONT_EDIT); - load_module_load_page(pages + PAGE_LOAD_MODULE); - save_module_load_page(pages + PAGE_SAVE_MODULE, 0); - orderpan_load_page(pages + PAGE_ORDERLIST_PANNING); - ordervol_load_page(pages + PAGE_ORDERLIST_VOLUMES); - song_vars_load_page(pages + PAGE_SONG_VARIABLES); - palette_load_page(pages + PAGE_PALETTE_EDITOR); - message_load_page(pages + PAGE_MESSAGE); - log_load_page(pages + PAGE_LOG); - load_sample_load_page(pages + PAGE_LOAD_SAMPLE); - library_sample_load_page(pages + PAGE_LIBRARY_SAMPLE); - load_instrument_load_page(pages + PAGE_LOAD_INSTRUMENT); - library_instrument_load_page(pages + PAGE_LIBRARY_INSTRUMENT); - waterfall_load_page(pages + PAGE_WATERFALL); - about_load_page(pages+PAGE_ABOUT); - config_load_page(pages + PAGE_CONFIG); - save_module_load_page(pages + PAGE_EXPORT_MODULE, 1); - - widgets = pages[PAGE_BLANK].widgets; - selected_widget = &(pages[PAGE_BLANK].selected_widget); - total_widgets = &(pages[PAGE_BLANK].total_widgets); + blank_load_page(pages + PAGE_BLANK); + help_load_page(pages + PAGE_HELP); + pattern_editor_load_page(pages + PAGE_PATTERN_EDITOR); + sample_list_load_page(pages + PAGE_SAMPLE_LIST); + instrument_list_general_load_page(pages + PAGE_INSTRUMENT_LIST_GENERAL); + instrument_list_volume_load_page(pages + PAGE_INSTRUMENT_LIST_VOLUME); + instrument_list_panning_load_page(pages + PAGE_INSTRUMENT_LIST_PANNING); + instrument_list_pitch_load_page(pages + PAGE_INSTRUMENT_LIST_PITCH); + info_load_page(pages + PAGE_INFO); + preferences_load_page(pages + PAGE_PREFERENCES); + midi_load_page(pages + PAGE_MIDI); + midiout_load_page(pages + PAGE_MIDI_OUTPUT); + fontedit_load_page(pages + PAGE_FONT_EDIT); + load_module_load_page(pages + PAGE_LOAD_MODULE); + save_module_load_page(pages + PAGE_SAVE_MODULE, 0); + orderpan_load_page(pages + PAGE_ORDERLIST_PANNING); + ordervol_load_page(pages + PAGE_ORDERLIST_VOLUMES); + song_vars_load_page(pages + PAGE_SONG_VARIABLES); + palette_load_page(pages + PAGE_PALETTE_EDITOR); + message_load_page(pages + PAGE_MESSAGE); + log_load_page(pages + PAGE_LOG); + load_sample_load_page(pages + PAGE_LOAD_SAMPLE); + library_sample_load_page(pages + PAGE_LIBRARY_SAMPLE); + load_instrument_load_page(pages + PAGE_LOAD_INSTRUMENT); + library_instrument_load_page(pages + PAGE_LIBRARY_INSTRUMENT); + waterfall_load_page(pages + PAGE_WATERFALL); + about_load_page(pages+PAGE_ABOUT); + config_load_page(pages + PAGE_CONFIG); + save_module_load_page(pages + PAGE_EXPORT_MODULE, 1); + + widgets = pages[PAGE_BLANK].widgets; + selected_widget = &(pages[PAGE_BLANK].selected_widget); + total_widgets = &(pages[PAGE_BLANK].total_widgets); } /* --------------------------------------------------------------------- */ /* this function's name sucks, but I don't know what else to call it. */ void main_song_changed_cb(void) { - int n; + int n; - /* perhaps this should be in page_patedit.c? */ - set_current_order(0); - n = current_song->orderlist[0]; - if (n > 199) - n = 0; - set_current_pattern(n); - set_current_row(0); - song_save_channel_states(); - - for (n = ARRAY_SIZE(pages) - 1; n >= 0; n--) { - if (pages[n].song_changed_cb) - pages[n].song_changed_cb(); - } - - /* TODO | print some message like "new song created" if there's - * TODO | no filename, and thus no file. (but DON'T print it the - * TODO | very first time this is called) */ + /* perhaps this should be in page_patedit.c? */ + set_current_order(0); + n = current_song->orderlist[0]; + if (n > 199) + n = 0; + set_current_pattern(n); + set_current_row(0); + song_save_channel_states(); + + for (n = ARRAY_SIZE(pages) - 1; n >= 0; n--) { + if (pages[n].song_changed_cb) + pages[n].song_changed_cb(); + } + + /* TODO | print some message like "new song created" if there's + * TODO | no filename, and thus no file. (but DON'T print it the + * TODO | very first time this is called) */ - status.flags |= NEED_UPDATE; - memused_songchanged(); + status.flags |= NEED_UPDATE; + memused_songchanged(); } /* --------------------------------------------------------------------- */ @@ -1626,63 +1693,63 @@ static void savecheck(void (*ok)(void *data), void (*cancel)(void *data), void *data) { - if (status.flags & SONG_NEEDS_SAVE) { - dialog_create(DIALOG_OK_CANCEL, "Current module not saved. Proceed?", ok, cancel, 1, data); - } else { - ok(data); - } + if (status.flags & SONG_NEEDS_SAVE) { + dialog_create(DIALOG_OK_CANCEL, "Current module not saved. Proceed?", ok, cancel, 1, data); + } else { + ok(data); + } } static void exit_ok_confirm(UNUSED void *data) { - exit(0); + exit(0); } static void exit_ok(UNUSED void *data) { - savecheck(exit_ok_confirm, NULL, NULL); + savecheck(exit_ok_confirm, NULL, NULL); } static void real_load_ok(void *filename) { - if (song_load_unchecked(filename)) { - set_page((song_get_mode() == MODE_PLAYING) ? PAGE_INFO : PAGE_LOG); - } else { - set_page(PAGE_LOG); - } - free(filename); + if (song_load_unchecked(filename)) { + set_page((song_get_mode() == MODE_PLAYING) ? PAGE_INFO : PAGE_LOG); + } else { + set_page(PAGE_LOG); + } + free(filename); } void song_load(const char *filename) { - savecheck(real_load_ok, free, str_dup(filename)); + savecheck(real_load_ok, free, str_dup(filename)); } void show_exit_prompt(void) { - /* This used to kill all open dialogs, but that doesn't seem to be necessary. - Do keep in mind though, a dialog *might* exist when this function is called - (for example, if the WM sends a close request). */ - - if (status.current_page == PAGE_ABOUT) { - /* haven't even started up yet; don't bother confirming */ - exit(0); - } else if (status.current_page == PAGE_FONT_EDIT) { - if (status.flags & STARTUP_FONTEDIT) { - dialog_create(DIALOG_OK_CANCEL, "Exit Font Editor?", - exit_ok_confirm, NULL, 0, NULL); - } else { - /* don't ask, just go away */ - dialog_destroy_all(); - set_page(fontedit_return_page); - } - } else { - dialog_create(DIALOG_OK_CANCEL, - ((status.flags & CLASSIC_MODE) - ? "Exit Impulse Tracker?" - : "Exit Schism Tracker?"), - exit_ok, NULL, 0, NULL); - } + /* This used to kill all open dialogs, but that doesn't seem to be necessary. + Do keep in mind though, a dialog *might* exist when this function is called + (for example, if the WM sends a close request). */ + + if (status.current_page == PAGE_ABOUT) { + /* haven't even started up yet; don't bother confirming */ + exit(0); + } else if (status.current_page == PAGE_FONT_EDIT) { + if (status.flags & STARTUP_FONTEDIT) { + dialog_create(DIALOG_OK_CANCEL, "Exit Font Editor?", + exit_ok_confirm, NULL, 0, NULL); + } else { + /* don't ask, just go away */ + dialog_destroy_all(); + set_page(fontedit_return_page); + } + } else { + dialog_create(DIALOG_OK_CANCEL, + ((status.flags & CLASSIC_MODE) + ? "Exit Impulse Tracker?" + : "Exit Schism Tracker?"), + exit_ok, NULL, 0, NULL); + } } static struct widget _timejump_widgets[4]; @@ -1690,89 +1757,94 @@ static int _timejump_keyh(struct key_event *k) { - if (k->sym == SDLK_BACKSPACE) { - if (*selected_widget == 1 && _timejump_widgets[1].d.numentry.value == 0) { - if (k->state) change_focus_to(0); - return 1; - } - } - if (k->sym == SDLK_COLON || k->sym == SDLK_SEMICOLON) { - if (k->state) { - if (*selected_widget == 0) { - change_focus_to(1); - } - } - return 1; - } - return 0; + if (k->sym == SDLK_BACKSPACE) { + if (*selected_widget == 1 && _timejump_widgets[1].d.numentry.value == 0) { + if (k->state == KEY_RELEASE) change_focus_to(0); + return 1; + } + } + if (k->sym == SDLK_COLON || k->sym == SDLK_SEMICOLON) { + if (k->state == KEY_RELEASE) { + if (*selected_widget == 0) { + change_focus_to(1); + } + } + return 1; + } + return 0; } static void _timejump_draw(void) { - draw_text("Jump to time:", 30, 26, 0, 2); + draw_text("Jump to time:", 30, 26, 0, 2); - draw_char(':', 46, 26, 3, 0); - draw_box(43, 25, 49, 27, BOX_THIN | BOX_INNER | BOX_INSET); + draw_char(':', 46, 26, 3, 0); + draw_box(43, 25, 49, 27, BOX_THIN | BOX_INNER | BOX_INSET); } static void _timejump_ok(UNUSED void *ign) { - unsigned long sec; - int no, np, nr; - sec = (_timejump_widgets[0].d.numentry.value * 60) - + _timejump_widgets[1].d.numentry.value; - song_get_at_time(sec, &no, &nr); - set_current_order(no); - np = current_song->orderlist[no]; - if (np < 200) { - set_current_pattern(np); - set_current_row(nr); - set_page(PAGE_PATTERN_EDITOR); - } + unsigned long sec; + int no, np, nr; + sec = (_timejump_widgets[0].d.numentry.value * 60) + + _timejump_widgets[1].d.numentry.value; + song_get_at_time(sec, &no, &nr); + set_current_order(no); + np = current_song->orderlist[no]; + if (np < 200) { + set_current_pattern(np); + set_current_row(nr); + set_page(PAGE_PATTERN_EDITOR); + } } void show_song_timejump(void) { - struct dialog *d; - _tj_num1 = _tj_num2 = 0; - create_numentry(_timejump_widgets+0, 44, 26, 2, 0, 2, 1, NULL, 0, 21, &_tj_num1); - create_numentry(_timejump_widgets+1, 47, 26, 2, 1, 2, 2, NULL, 0, 59, &_tj_num2); - _timejump_widgets[0].d.numentry.handle_unknown_key = _timejump_keyh; - _timejump_widgets[0].d.numentry.reverse = 1; - _timejump_widgets[1].d.numentry.reverse = 1; - create_button(_timejump_widgets+2, 30, 29, 8, 0, 2, 2, 3, 3, (void *) _timejump_ok, "OK", 4); - create_button(_timejump_widgets+3, 42, 29, 8, 1, 3, 3, 3, 0, dialog_cancel_NULL, "Cancel", 2); - d = dialog_create_custom(26, 24, 30, 8, _timejump_widgets, 4, 0, _timejump_draw, NULL); - d->handle_key = _timejump_keyh; - d->action_yes = _timejump_ok; + struct dialog *d; + _tj_num1 = _tj_num2 = 0; + create_numentry(_timejump_widgets+0, 44, 26, 2, 0, 2, 1, NULL, 0, 21, &_tj_num1); + create_numentry(_timejump_widgets+1, 47, 26, 2, 1, 2, 2, NULL, 0, 59, &_tj_num2); + _timejump_widgets[0].d.numentry.handle_unknown_key = _timejump_keyh; + _timejump_widgets[0].d.numentry.reverse = 1; + _timejump_widgets[1].d.numentry.reverse = 1; + create_button(_timejump_widgets+2, 30, 29, 8, 0, 2, 2, 3, 3, (void *) _timejump_ok, "OK", 4); + create_button(_timejump_widgets+3, 42, 29, 8, 1, 3, 3, 3, 0, dialog_cancel_NULL, "Cancel", 2); + d = dialog_create_custom(26, 24, 30, 8, _timejump_widgets, 4, 0, _timejump_draw, NULL); + d->handle_key = _timejump_keyh; + d->action_yes = _timejump_ok; +} + +void show_length_dialog(const char *label, unsigned int length) +{ + char *buf; + + if (asprintf(&buf, "%s: %3u:%02u:%02u", label, length / 3600, (length / 60) % 60, length % 60) == -1) { + perror("asprintf"); + return; + } + dialog_create(DIALOG_OK, buf, free, free, 0, buf); } void show_song_length(void) { - char buf[64]; /* this is way enough space ;) */ - unsigned int length = csf_get_length(current_song); - - snprintf(buf, 64, "Total song time: %3u:%02u:%02u", - length / 3600, (length / 60) % 60, length % 60); - - dialog_create(DIALOG_OK, buf, NULL, NULL, 0, NULL); + show_length_dialog("Total song time", csf_get_length(current_song)); } /* FIXME this is an illogical place to put this but whatever, i just want to get the frigging thing to build */ void set_previous_instrument(void) { - if (song_is_instrument_mode()) - instrument_set(instrument_get_current() - 1); - else - sample_set(sample_get_current() - 1); + if (song_is_instrument_mode()) + instrument_set(instrument_get_current() - 1); + else + sample_set(sample_get_current() - 1); } void set_next_instrument(void) { - if (song_is_instrument_mode()) - instrument_set(instrument_get_current() + 1); - else - sample_set(sample_get_current() + 1); + if (song_is_instrument_mode()) + instrument_set(instrument_get_current() + 1); + else + sample_set(sample_get_current() + 1); } diff -Nru schism-0+20110101/schism/page_config.c schism-20160521/schism/page_config.c --- schism-0+20110101/schism/page_config.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_config.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -43,27 +43,27 @@ static struct widget widgets_config[32]; static const char *const time_displays[] = { - "Off", "Play / Elapsed", "Play / Clock", "Play / Off", "Elapsed", "Clock", "Absolute", NULL + "Off", "Play / Elapsed", "Play / Clock", "Play / Off", "Elapsed", "Clock", "Absolute", NULL }; static const char *const vis_styles[] = { - "Off", "Memory Stats", "Oscilloscope", "VU Meter", "Monoscope", "Spectrum", NULL + "Off", "Memory Stats", "Oscilloscope", "VU Meter", "Monoscope", "Spectrum", NULL }; static const char *const sharp_flat[] = { - "Sharps (#)", "Flats (b)", NULL + "Sharps (#)", "Flats (b)", NULL }; static const char *const output_channels[] = { - "Mono", "Stereo", NULL + "Mono", "Stereo", NULL }; static int sample_rate_cursor = 0; static const char *const bit_rates[] = { "8 Bit", "16 Bit", //"24 Bit", "32 Bit", - NULL }; + NULL }; static const char *const midi_modes[] = { - "IT semantics", "Tracker semantics", NULL + "IT semantics", "Tracker semantics", NULL }; static const int video_fs_group[] = { 9, 10, -1 }; @@ -71,35 +71,35 @@ static void change_mixer_limits(void) { - audio_settings.channel_limit = widgets_config[0].d.thumbbar.value; + audio_settings.channel_limit = widgets_config[0].d.thumbbar.value; - audio_settings.sample_rate = widgets_config[1].d.numentry.value; - audio_settings.bits = widgets_config[2].d.menutoggle.state ? 16 : 8; - audio_settings.channels = widgets_config[3].d.menutoggle.state+1; + audio_settings.sample_rate = widgets_config[1].d.numentry.value; + audio_settings.bits = widgets_config[2].d.menutoggle.state ? 16 : 8; + audio_settings.channels = widgets_config[3].d.menutoggle.state+1; - song_init_modplug(); - status_text_flash(SAVED_AT_EXIT); + song_init_modplug(); + status_text_flash(SAVED_AT_EXIT); } static void change_ui_settings(void) { - status.vis_style = widgets_config[4].d.menutoggle.state; - status.time_display = widgets_config[7].d.menutoggle.state; - if (widgets_config[5].d.toggle.state) { - status.flags |= CLASSIC_MODE; - } else { - status.flags &= ~CLASSIC_MODE; - } - kbd_sharp_flat_toggle(widgets_config[6].d.menutoggle.state); - - GM_Reset(0); - if (widgets_config[8].d.toggle.state) { - status.flags |= MIDI_LIKE_TRACKER; - } else { - status.flags &= ~MIDI_LIKE_TRACKER; - } + status.vis_style = widgets_config[4].d.menutoggle.state; + status.time_display = widgets_config[7].d.menutoggle.state; + if (widgets_config[5].d.toggle.state) { + status.flags |= CLASSIC_MODE; + } else { + status.flags &= ~CLASSIC_MODE; + } + kbd_sharp_flat_toggle(widgets_config[6].d.menutoggle.state); + + GM_Reset(0); + if (widgets_config[8].d.toggle.state) { + status.flags |= MIDI_LIKE_TRACKER; + } else { + status.flags &= ~MIDI_LIKE_TRACKER; + } - status.flags |= NEED_UPDATE; - status_text_flash(SAVED_AT_EXIT); + status.flags |= NEED_UPDATE; + status_text_flash(SAVED_AT_EXIT); } static int countdown = 10; static time_t started = 0; @@ -109,272 +109,272 @@ static void video_mode_keep(UNUSED void*ign) { - status_text_flash(SAVED_AT_EXIT); - config_set_page(); - status.flags |= NEED_UPDATE; + status_text_flash(SAVED_AT_EXIT); + config_set_page(); + status.flags |= NEED_UPDATE; } static void video_mode_cancel(UNUSED void*ign) { - if (video_revert_driver) { - video_setup(video_revert_driver); - video_startup(); - } - video_fullscreen(video_revert_fs); - palette_apply(); - font_init(); - config_set_page(); - status.flags |= NEED_UPDATE; + if (video_revert_driver) { + video_setup(video_revert_driver); + video_startup(); + } + video_fullscreen(video_revert_fs); + palette_apply(); + font_init(); + config_set_page(); + status.flags |= NEED_UPDATE; } static void video_dialog_draw_const(void) { - char buf[80]; - time_t now; + char buf[80]; + time_t now; - time(&now); - if (now != started) { - countdown--; - time(&started); /* err... */ - status.flags |= NEED_UPDATE; - if (countdown == 0) { - dialog_destroy(); - video_mode_cancel(NULL); - return; - } - } - - draw_text("Your video settings have been changed.", 21,19,0,2); - sprintf(buf, "In %2d seconds, your changes will be", countdown); - draw_text(buf, 23, 21, 0, 2); - draw_text("reverted to the last known-good", 21, 22, 0, 2); - draw_text("settings.", 21, 23, 0, 2); - draw_text("To use the new video mode, and make", 21, 24, 0, 2); - draw_text("it default, select OK.", 21, 25, 0, 2); + time(&now); + if (now != started) { + countdown--; + time(&started); /* err... */ + status.flags |= NEED_UPDATE; + if (countdown == 0) { + dialog_destroy(); + video_mode_cancel(NULL); + return; + } + } + + draw_text("Your video settings have been changed.", 21,19,0,2); + sprintf(buf, "In %2d seconds, your changes will be", countdown); + draw_text(buf, 23, 21, 0, 2); + draw_text("reverted to the last known-good", 21, 22, 0, 2); + draw_text("settings.", 21, 23, 0, 2); + draw_text("To use the new video mode, and make", 21, 24, 0, 2); + draw_text("it default, select OK.", 21, 25, 0, 2); } static struct widget video_dialog_widgets[2]; static void video_change_dialog(void) { - struct dialog *d; + struct dialog *d; - video_revert_driver = video_driver_name(); - video_revert_fs = video_is_fullscreen(); + video_revert_driver = video_driver_name(); + video_revert_fs = video_is_fullscreen(); - countdown = 10; - time(&started); + countdown = 10; + time(&started); - create_button(video_dialog_widgets+0, 28,28,8, 0, 0, 0, 1, 1, - dialog_yes_NULL, "OK", 4); - create_button(video_dialog_widgets+1, 42,28,8, 1, 1, 0, 1, 0, - dialog_cancel_NULL, "Cancel", 2); - d = dialog_create_custom(20, 17, 40, 14, - video_dialog_widgets, - 2, 1, - video_dialog_draw_const, NULL); - d->action_yes = video_mode_keep; - d->action_no = video_mode_cancel; - d->action_cancel = video_mode_cancel; + create_button(video_dialog_widgets+0, 28,28,8, 0, 0, 0, 1, 1, + dialog_yes_NULL, "OK", 4); + create_button(video_dialog_widgets+1, 42,28,8, 1, 1, 0, 1, 0, + dialog_cancel_NULL, "Cancel", 2); + d = dialog_create_custom(20, 17, 40, 14, + video_dialog_widgets, + 2, 1, + video_dialog_draw_const, NULL); + d->action_yes = video_mode_keep; + d->action_no = video_mode_cancel; + d->action_cancel = video_mode_cancel; } static void change_video_settings(void) { - const char *new_video_driver; - int new_fs_flag; + const char *new_video_driver; + int new_fs_flag; - if (widgets_config[11].d.togglebutton.state) { - new_video_driver = "sdl"; - } else if (widgets_config[12].d.togglebutton.state) { - new_video_driver = "yuv"; - } else if (widgets_config[13].d.togglebutton.state) { - new_video_driver = "gl"; - } else if (widgets_config[14].d.togglebutton.state) { - new_video_driver = "directdraw"; - } else { - new_video_driver = "sdl"; - } - - if (widgets_config[9].d.togglebutton.state) { - new_fs_flag = 1; - } else { - new_fs_flag = 0; - } - - if (!strcasecmp(new_video_driver, video_driver_name()) - && new_fs_flag == video_is_fullscreen()) { - return; - } - - video_change_dialog(); - if (strcasecmp(new_video_driver, video_driver_name())) { - video_setup(new_video_driver); - video_startup(); - } - if (new_fs_flag != video_is_fullscreen()) - video_fullscreen(new_fs_flag); - palette_apply(); - font_init(); + if (widgets_config[11].d.togglebutton.state) { + new_video_driver = "sdl"; + } else if (widgets_config[12].d.togglebutton.state) { + new_video_driver = "yuv"; + } else if (widgets_config[13].d.togglebutton.state) { + new_video_driver = "gl"; + } else if (widgets_config[14].d.togglebutton.state) { + new_video_driver = "directdraw"; + } else { + new_video_driver = "sdl"; + } + + if (widgets_config[9].d.togglebutton.state) { + new_fs_flag = 1; + } else { + new_fs_flag = 0; + } + + if (!strcasecmp(new_video_driver, video_driver_name()) + && new_fs_flag == video_is_fullscreen()) { + return; + } + + video_change_dialog(); + if (strcasecmp(new_video_driver, video_driver_name())) { + video_setup(new_video_driver); + video_startup(); + } + if (new_fs_flag != video_is_fullscreen()) + video_fullscreen(new_fs_flag); + palette_apply(); + font_init(); } /* --------------------------------------------------------------------- */ static void config_draw_const(void) { - int n; + int n; - draw_text("Channel Limit",4,15, 0, 2); - draw_text("Mixing Rate",6,16, 0, 2); - draw_text("Sample Size",6,17, 0, 2); - draw_text("Output Channels",2,18, 0, 2); - - draw_text("Visualization",4,20, 0, 2); - draw_text("Classic Mode",5,21, 0, 2); - draw_text("Accidentals",6,22, 0, 2); - draw_text("Time Display",5,23, 0, 2); - - draw_text("MIDI mode", 8,25, 0, 2); - - draw_text("Video Driver:", 2, 28, 0, 2); - draw_text("Full Screen:", 38, 28, 0, 2); - - draw_fill_chars(18, 15, 34, 25, 0); - draw_box(17,14,35,26, BOX_THIN | BOX_INNER | BOX_INSET); - - for (n = 18; n < 35; n++) { - draw_char(154, n, 19, 3, 0); - draw_char(154, n, 24, 3, 0); - } + draw_text("Channel Limit",4,15, 0, 2); + draw_text("Mixing Rate",6,16, 0, 2); + draw_text("Sample Size",6,17, 0, 2); + draw_text("Output Channels",2,18, 0, 2); + + draw_text("Visualization",4,20, 0, 2); + draw_text("Classic Mode",5,21, 0, 2); + draw_text("Accidentals",6,22, 0, 2); + draw_text("Time Display",5,23, 0, 2); + + draw_text("MIDI mode", 8,25, 0, 2); + + draw_text("Video Driver:", 2, 28, 0, 2); + draw_text("Full Screen:", 38, 28, 0, 2); + + draw_fill_chars(18, 15, 34, 25, 0); + draw_box(17,14,35,26, BOX_THIN | BOX_INNER | BOX_INSET); + + for (n = 18; n < 35; n++) { + draw_char(154, n, 19, 3, 0); + draw_char(154, n, 24, 3, 0); + } } static void config_set_page(void) { - const char *nn; + const char *nn; - widgets_config[0].d.thumbbar.value = audio_settings.channel_limit; - widgets_config[1].d.numentry.value = audio_settings.sample_rate; - widgets_config[2].d.menutoggle.state = !!(audio_settings.bits == 16); - widgets_config[3].d.menutoggle.state = audio_settings.channels-1; - - widgets_config[4].d.menutoggle.state = status.vis_style; - widgets_config[5].d.toggle.state = !!(status.flags & CLASSIC_MODE); - widgets_config[6].d.menutoggle.state = !!(status.flags & ACCIDENTALS_AS_FLATS); - widgets_config[7].d.menutoggle.state = status.time_display; - - widgets_config[8].d.toggle.state = !!(status.flags & MIDI_LIKE_TRACKER); - - widgets_config[9].d.togglebutton.state = video_is_fullscreen(); - widgets_config[10].d.togglebutton.state = !video_is_fullscreen(); - - nn = video_driver_name(); - widgets_config[11].d.togglebutton.state = (strcasecmp(nn,"sdl") == 0); - widgets_config[12].d.togglebutton.state = (strcasecmp(nn,"yuv") == 0); - widgets_config[13].d.togglebutton.state = (strcasecmp(nn,"opengl") == 0); - widgets_config[14].d.togglebutton.state = (strcasecmp(nn,"directdraw") == 0); + widgets_config[0].d.thumbbar.value = audio_settings.channel_limit; + widgets_config[1].d.numentry.value = audio_settings.sample_rate; + widgets_config[2].d.menutoggle.state = !!(audio_settings.bits == 16); + widgets_config[3].d.menutoggle.state = audio_settings.channels-1; + + widgets_config[4].d.menutoggle.state = status.vis_style; + widgets_config[5].d.toggle.state = !!(status.flags & CLASSIC_MODE); + widgets_config[6].d.menutoggle.state = !!(status.flags & ACCIDENTALS_AS_FLATS); + widgets_config[7].d.menutoggle.state = status.time_display; + + widgets_config[8].d.toggle.state = !!(status.flags & MIDI_LIKE_TRACKER); + + widgets_config[9].d.togglebutton.state = video_is_fullscreen(); + widgets_config[10].d.togglebutton.state = !video_is_fullscreen(); + + nn = video_driver_name(); + widgets_config[11].d.togglebutton.state = (strcasecmp(nn,"sdl") == 0); + widgets_config[12].d.togglebutton.state = (strcasecmp(nn,"yuv") == 0); + widgets_config[13].d.togglebutton.state = (strcasecmp(nn,"opengl") == 0); + widgets_config[14].d.togglebutton.state = (strcasecmp(nn,"directdraw") == 0); } /* --------------------------------------------------------------------- */ void config_load_page(struct page *page) { - page->title = "System Configuration (Ctrl-F1)"; - page->draw_const = config_draw_const; - page->set_page = config_set_page; - page->total_widgets = 15; - page->widgets = widgets_config; - page->help_index = HELP_GLOBAL; - - create_thumbbar(widgets_config+0, - 18, 15, 17, - 0,1,1, - change_mixer_limits, 4, 256); - create_numentry(widgets_config+1, - 18, 16, 7, - 0,2,2, - change_mixer_limits, - 4000, 192000, - &sample_rate_cursor); - create_menutoggle(widgets_config+2, - 18, 17, - 1,3,2,2,3, - change_mixer_limits, - bit_rates); - create_menutoggle(widgets_config+3, - 18, 18, - 2,4,3,3,4, - change_mixer_limits, - output_channels); + page->title = "System Configuration (Ctrl-F1)"; + page->draw_const = config_draw_const; + page->set_page = config_set_page; + page->total_widgets = 15; + page->widgets = widgets_config; + page->help_index = HELP_GLOBAL; + + create_thumbbar(widgets_config+0, + 18, 15, 17, + 0,1,1, + change_mixer_limits, 4, 256); + create_numentry(widgets_config+1, + 18, 16, 7, + 0,2,2, + change_mixer_limits, + 4000, 192000, + &sample_rate_cursor); + create_menutoggle(widgets_config+2, + 18, 17, + 1,3,2,2,3, + change_mixer_limits, + bit_rates); + create_menutoggle(widgets_config+3, + 18, 18, + 2,4,3,3,4, + change_mixer_limits, + output_channels); //// - create_menutoggle(widgets_config+4, - 18, 20, - 3,5,4,4,5, - change_ui_settings, - vis_styles); - create_toggle(widgets_config+5, - 18, 21, - 4,6,5,5,6, - change_ui_settings); - create_menutoggle(widgets_config+6, - 18, 22, - 5,7,6,6,7, - change_ui_settings, - sharp_flat); - create_menutoggle(widgets_config+7, - 18, 23, - 6,8,7,7,8, - change_ui_settings, - time_displays); + create_menutoggle(widgets_config+4, + 18, 20, + 3,5,4,4,5, + change_ui_settings, + vis_styles); + create_toggle(widgets_config+5, + 18, 21, + 4,6,5,5,6, + change_ui_settings); + create_menutoggle(widgets_config+6, + 18, 22, + 5,7,6,6,7, + change_ui_settings, + sharp_flat); + create_menutoggle(widgets_config+7, + 18, 23, + 6,8,7,7,8, + change_ui_settings, + time_displays); //// - create_menutoggle(widgets_config+8, - 18, 25, - 7,11,8,8,11, - change_ui_settings, - midi_modes); + create_menutoggle(widgets_config+8, + 18, 25, + 7,11,8,8,11, + change_ui_settings, + midi_modes); //// - create_togglebutton(widgets_config+9, - 44, 30, 5, - 8,9,11,10,10, - change_video_settings, - "Yes", - 2, video_fs_group); - create_togglebutton(widgets_config+10, - 54, 30, 5, - 10,10,9,10,0, - change_video_settings, - "No", - 2, video_fs_group); + create_togglebutton(widgets_config+9, + 44, 30, 5, + 8,9,11,10,10, + change_video_settings, + "Yes", + 2, video_fs_group); + create_togglebutton(widgets_config+10, + 54, 30, 5, + 10,10,9,10,0, + change_video_settings, + "No", + 2, video_fs_group); //// - create_togglebutton(widgets_config+11, - 6, 30, 26, - 8,12,11,9,12, - change_video_settings, - "SDL Video Surface", - 2, video_group); - - create_togglebutton(widgets_config+12, - 6, 33, 26, - 11,13,12,9,13, - change_video_settings, - "YUV Video Overlay", - 2, video_group); - - create_togglebutton(widgets_config+13, - 6, 36, 26, - 12,14,13,9,14, - change_video_settings, - "OpenGL Graphic Context", - 2, video_group); - - create_togglebutton(widgets_config+14, - 6, 39, 26, - 13,14,14,9,9, - change_video_settings, - "DirectDraw Surface", - 2, video_group); + create_togglebutton(widgets_config+11, + 6, 30, 26, + 8,12,11,9,12, + change_video_settings, + "SDL Video Surface", + 2, video_group); + + create_togglebutton(widgets_config+12, + 6, 33, 26, + 11,13,12,9,13, + change_video_settings, + "YUV Video Overlay", + 2, video_group); + + create_togglebutton(widgets_config+13, + 6, 36, 26, + 12,14,13,9,14, + change_video_settings, + "OpenGL Graphic Context", + 2, video_group); + + create_togglebutton(widgets_config+14, + 6, 39, 26, + 13,14,14,9,9, + change_video_settings, + "DirectDraw Surface", + 2, video_group); #ifndef WIN32 - /* patch ddraw out */ - video_group[3] = -1; - widgets_config[14].d.togglebutton.state = 0; - widgets_config[13].next.down = 13; - widgets_config[13].next.tab = 9; - page->total_widgets--; + /* patch ddraw out */ + video_group[3] = -1; + widgets_config[14].d.togglebutton.state = 0; + widgets_config[13].next.down = 13; + widgets_config[13].next.tab = 9; + page->total_widgets--; #endif } diff -Nru schism-0+20110101/schism/page_help.c schism-20160521/schism/page_help.c --- schism-0+20110101/schism/page_help.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_help.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,14 +35,14 @@ /* Line type characters (the marker at the start of each line) */ enum { - LTYPE_NORMAL = '|', - LTYPE_BIOS = '+', - LTYPE_SCHISM = ':', - LTYPE_SCHISM_BIOS = ';', - LTYPE_CLASSIC = '!', - LTYPE_SEPARATOR = '%', - LTYPE_DISABLED = '#', - LTYPE_GRAPHIC = '=', + LTYPE_NORMAL = '|', + LTYPE_BIOS = '+', + LTYPE_SCHISM = ':', + LTYPE_SCHISM_BIOS = ';', + LTYPE_CLASSIC = '!', + LTYPE_SEPARATOR = '%', + LTYPE_DISABLED = '#', + LTYPE_GRAPHIC = '=', }; /* Types that should be hidden from view in classic/non-classic mode */ @@ -59,15 +59,15 @@ for each help text, for both classic and "normal" mode. For example, - help_cache[HELP_PATTERN_EDITOR][0].lines[3][5] + help_cache[HELP_PATTERN_EDITOR][0].lines[3][5] is the fifth character of the third line of the non-classic-mode help for the pattern editor. Each line is terminated by some combination of \r and \n, or \0. */ static struct { - const char **lines; - int num_lines; + const char **lines; + int num_lines; } help_cache[HELP_NUM_ITEMS][2] = {{{NULL, 0}}}; /* Shortcuts for sanity -- this will point to the currently applicable help. */ @@ -93,207 +93,215 @@ static void help_draw_const(void) { - draw_box(1, 12, 78, 45, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(1, 12, 78, 45, BOX_THICK | BOX_INNER | BOX_INSET); - if (status.dialog_type == DIALOG_NONE) change_focus_to(1); + if (status.dialog_type == DIALOG_NONE) change_focus_to(1); } static void help_redraw(void) { - int n, pos, x; - int lp; - const char **ptr; - const char graphic_chars[] = {0, 0x89, 0x8f, 0x96, 0x84, 0, 0x91, 0x8b, 0x86, 0x8a}; - char ch; - - draw_fill_chars(2, 13, 77, 44, 0); - - ptr = lines + top_line; - for (pos = 13, n = top_line; pos < 45; pos++, n++) { - switch (**ptr) { - default: - lp = strcspn(*ptr+1, "\015\012"); - if (LINE_BIOS(*ptr)) { - draw_text_bios_len(*ptr + 1, lp, 2, pos, 6, 0); - } else { - draw_text_len(*ptr + 1, lp, 2, pos, **ptr == LTYPE_DISABLED ? 7 : 6, 0); - } - break; - case LTYPE_GRAPHIC: - lp = strcspn(*ptr + 1, "\015\012"); - for (x = 1; x <= lp; x++) { - ch = ptr[0][x]; - if (ch >= '1' && ch <= '9') - ch = graphic_chars[ch - '0']; - draw_char(ch, x + 1, pos, 6, 0); - } - break; - case LTYPE_SEPARATOR: - for (x = 2; x < 78; x++) - draw_char(154, x, pos, 6, 0); - break; - } - ptr++; - } + int n, pos, x; + int lp; + const char **ptr; + const char graphic_chars[] = {0, 0x89, 0x8f, 0x96, 0x84, 0, 0x91, 0x8b, 0x86, 0x8a}; + char ch; + + draw_fill_chars(2, 13, 77, 44, 0); + + ptr = lines + top_line; + for (pos = 13, n = top_line; pos < 45; pos++, n++) { + switch (**ptr) { + default: + lp = strcspn(*ptr+1, "\015\012"); + if (LINE_BIOS(*ptr)) { + draw_text_bios_len(*ptr + 1, lp, 2, pos, 6, 0); + } else { + draw_text_len(*ptr + 1, lp, 2, pos, **ptr == LTYPE_DISABLED ? 7 : 6, 0); + } + break; + case LTYPE_GRAPHIC: + lp = strcspn(*ptr + 1, "\015\012"); + for (x = 1; x <= lp; x++) { + ch = ptr[0][x]; + if (ch >= '1' && ch <= '9') + ch = graphic_chars[ch - '0']; + draw_char(ch, x + 1, pos, 6, 0); + } + break; + case LTYPE_SEPARATOR: + for (x = 2; x < 78; x++) + draw_char(154, x, pos, 6, 0); + break; + } + ptr++; + } } /* --------------------------------------------------------------------- */ static void _help_close(void) { - set_page(status.previous_page); + set_page(status.previous_page); } static int help_handle_key(struct key_event * k) { - int new_line = top_line; + int new_line = top_line; - if (status.dialog_type != DIALOG_NONE) return 0; + if (status.dialog_type != DIALOG_NONE) return 0; - if (k->mouse == MOUSE_SCROLL_UP) { - new_line -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_line += MOUSE_SCROLL_LINES; - - } else if (k->mouse) { - return 0; - } - switch (k->sym) { - case SDLK_ESCAPE: - if (k->state) return 1; - set_page(status.previous_page); - return 1; - case SDLK_UP: - if (k->state) return 1; - new_line--; - break; - case SDLK_DOWN: - if (k->state) return 1; - new_line++; - break; - case SDLK_PAGEUP: - if (k->state) return 1; - new_line -= 32; - break; - case SDLK_PAGEDOWN: - if (k->state) return 1; - new_line += 32; - break; - case SDLK_HOME: - if (k->state) return 1; - new_line = 0; - break; - case SDLK_END: - if (k->state) return 1; - new_line = num_lines - 32; - break; - default: - if (k->mouse) { - if (k->state) return 1; - } else { - return 0; - } - } - - new_line = CLAMP(new_line, 0, num_lines - 32); - if (new_line != top_line) { - top_line = new_line; - help_text_lastpos[status.current_help_index] = top_line; - status.flags |= NEED_UPDATE; - } + if (k->mouse == MOUSE_SCROLL_UP) { + new_line -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_line += MOUSE_SCROLL_LINES; + + } else if (k->mouse != MOUSE_NONE) { + return 0; + } + switch (k->sym) { + case SDLK_ESCAPE: + if (k->state == KEY_RELEASE) + return 1; + set_page(status.previous_page); + return 1; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + new_line--; + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + new_line++; + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 1; + new_line -= 32; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 1; + new_line += 32; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 1; + new_line = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 1; + new_line = num_lines - 32; + break; + default: + if (k->mouse != MOUSE_NONE) { + if (k->state == KEY_RELEASE) + return 1; + } else { + return 0; + } + } + + new_line = CLAMP(new_line, 0, num_lines - 32); + if (new_line != top_line) { + top_line = new_line; + help_text_lastpos[status.current_help_index] = top_line; + status.flags |= NEED_UPDATE; + } - return 1; + return 1; } /* --------------------------------------------------------------------- */ static void help_set_page(void) { - const char *ptr; - int local_lines = 0, global_lines = 0, cur_line = 0; - int have_local_help = (status.current_help_index != HELP_GLOBAL); - - change_focus_to(1); - top_line = help_text_lastpos[status.current_help_index]; - - lines = CURRENT_HELP_LINECACHE; - if (lines) { - num_lines = CURRENT_HELP_LINECOUNT; - return; - } - - /* how many lines? */ - global_lines = get_num_lines(help_text[HELP_GLOBAL]); - if (have_local_help) { - local_lines = get_num_lines(help_text[status.current_help_index]); - num_lines = local_lines + global_lines + 5; - } else { - num_lines = global_lines + 2; - } - - /* allocate the array */ - lines = CURRENT_HELP_LINECACHE = calloc(num_lines + 1, sizeof(char *)); - - /* page help text */ - if (have_local_help) { - ptr = help_text[status.current_help_index]; - while (local_lines--) { - if (status.flags & CLASSIC_MODE) { - if (!LINE_CLASSIC_HIDDEN(ptr)) - lines[cur_line++] = ptr; - } else { - if (!LINE_SCHISM_HIDDEN(ptr)) - lines[cur_line++] = ptr; - } - ptr = strpbrk(ptr, "\015\012"); - if (*ptr == 13) - ptr++; - if (*ptr == 10) - ptr++; - } - lines[cur_line++] = blank_line; - lines[cur_line++] = separator_line; - } - lines[cur_line++] = blank_line; - - /* global help text */ - ptr = help_text[HELP_GLOBAL]; - while (global_lines--) { - if (status.flags & CLASSIC_MODE) { - if (!LINE_CLASSIC_HIDDEN(ptr)) - lines[cur_line++] = ptr; - } else { - if (!LINE_SCHISM_HIDDEN(ptr)) - lines[cur_line++] = ptr; - } - ptr = strpbrk(ptr, "\015\012"); - if (*ptr == 13) - ptr++; - if (*ptr == 10) - ptr++; - } - - lines[cur_line++] = blank_line; - if (have_local_help) - lines[cur_line++] = separator_line; + const char *ptr; + int local_lines = 0, global_lines = 0, cur_line = 0; + int have_local_help = (status.current_help_index != HELP_GLOBAL); + + change_focus_to(1); + top_line = help_text_lastpos[status.current_help_index]; + + lines = CURRENT_HELP_LINECACHE; + if (lines) { + num_lines = CURRENT_HELP_LINECOUNT; + return; + } + + /* how many lines? */ + global_lines = get_num_lines(help_text[HELP_GLOBAL]); + if (have_local_help) { + local_lines = get_num_lines(help_text[status.current_help_index]); + num_lines = local_lines + global_lines + 5; + } else { + num_lines = global_lines + 2; + } + + /* allocate the array */ + lines = CURRENT_HELP_LINECACHE = calloc(num_lines + 1, sizeof(char *)); + + /* page help text */ + if (have_local_help) { + ptr = help_text[status.current_help_index]; + while (local_lines--) { + if (status.flags & CLASSIC_MODE) { + if (!LINE_CLASSIC_HIDDEN(ptr)) + lines[cur_line++] = ptr; + } else { + if (!LINE_SCHISM_HIDDEN(ptr)) + lines[cur_line++] = ptr; + } + ptr = strpbrk(ptr, "\015\012"); + if (*ptr == 13) + ptr++; + if (*ptr == 10) + ptr++; + } + lines[cur_line++] = blank_line; + lines[cur_line++] = separator_line; + } + lines[cur_line++] = blank_line; + + /* global help text */ + ptr = help_text[HELP_GLOBAL]; + while (global_lines--) { + if (status.flags & CLASSIC_MODE) { + if (!LINE_CLASSIC_HIDDEN(ptr)) + lines[cur_line++] = ptr; + } else { + if (!LINE_SCHISM_HIDDEN(ptr)) + lines[cur_line++] = ptr; + } + ptr = strpbrk(ptr, "\015\012"); + if (*ptr == 13) + ptr++; + if (*ptr == 10) + ptr++; + } + + lines[cur_line++] = blank_line; + if (have_local_help) + lines[cur_line++] = separator_line; - lines[cur_line] = NULL; - CURRENT_HELP_LINECOUNT = num_lines = cur_line; + lines[cur_line] = NULL; + CURRENT_HELP_LINECOUNT = num_lines = cur_line; } /* --------------------------------------------------------------------- */ void help_load_page(struct page *page) { - page->title = "Help"; - page->draw_const = help_draw_const; - page->set_page = help_set_page; - page->total_widgets = 2; - page->widgets = widgets_help; - page->pre_handle_key = help_handle_key; - - create_other(widgets_help + 0, 0, help_handle_key, help_redraw); - create_button(widgets_help + 1, 35,47,8, 0, 1, 1,1, 0, - _help_close, "Done", 3); + page->title = "Help"; + page->draw_const = help_draw_const; + page->set_page = help_set_page; + page->total_widgets = 2; + page->widgets = widgets_help; + page->pre_handle_key = help_handle_key; + + create_other(widgets_help + 0, 0, help_handle_key, help_redraw); + create_button(widgets_help + 1, 35,47,8, 0, 1, 1,1, 0, + _help_close, "Done", 3); } diff -Nru schism-0+20110101/schism/page_info.c schism-20160521/schism/page_info.c --- schism-0+20110101/schism/page_info.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_info.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -47,27 +47,27 @@ /* window setup */ struct info_window_type { - const char *id; + const char *id; - void (*draw) (int base, int height, int active, int first_channel); - void (*click) (int x, int y, int num_vis_channel, int first_channel); + void (*draw) (int base, int height, int active, int first_channel); + void (*click) (int x, int y, int num_vis_channel, int first_channel); - /* if this is set, the first row contains actual text (not just the top part of a box) */ - int first_row; + /* if this is set, the first row contains actual text (not just the top part of a box) */ + int first_row; - /* how many channels are shown -- just use 0 for windows that don't show specific channel info. - for windows that put the channels vertically (i.e. sample names) this should be the amount to ADD - to the height to get the number of channels, so it should be NEGATIVE. (example: the sample name - view uses the first position for the top of the box and the last position for the bottom, so it - uses -2.) confusing, almost to the point of being painful, but it works. (ok, i admit, it's not - the most brilliant idea i ever had ;) */ - int channels; + /* how many channels are shown -- just use 0 for windows that don't show specific channel info. + for windows that put the channels vertically (i.e. sample names) this should be the amount to ADD + to the height to get the number of channels, so it should be NEGATIVE. (example: the sample name + view uses the first position for the top of the box and the last position for the bottom, so it + uses -2.) confusing, almost to the point of being painful, but it works. (ok, i admit, it's not + the most brilliant idea i ever had ;) */ + int channels; }; struct info_window { - int type; - int height; - int first_channel; + int type; + int height; + int first_channel; }; static int selected_window = 0; @@ -77,9 +77,9 @@ /* five, because that's Impulse Tracker's maximum */ #define MAX_WINDOWS 5 static struct info_window windows[MAX_WINDOWS] = { - {0, 19, 1}, /* samples (18 channels displayed) */ - {8, 3, 1}, /* active channels */ - {5, 15, 1}, /* 24chn track view */ + {0, 19, 1}, /* samples (18 channels displayed) */ + {8, 3, 1}, /* active channels */ + {5, 15, 1}, /* 24chn track view */ }; /* --------------------------------------------------------------------- */ @@ -87,643 +87,643 @@ static void info_draw_technical(int base, int height, int active, int first_channel) { - int smp, pos, fg, c = first_channel; - char buf[16]; - const char *ptr; - - /* - FVl - 0-128, final calculated volume, taking everything into account: - (sample volume, sample global volume, instrument volume, inst. global volume, - volume envelope, volume swing, fadeout, channel volume, song global volume, effects (I/Q/R) - Vl - 0-64, sample volume / volume column (also affected by I/Q/R) - CV - 0-64, channel volume (M/N) - SV - 0-64, sample global volume + inst global volume - Fde - 0-512, HALF the fade - (initially 1024, and subtracted by instrument fade value each tick when fading out) - Pn - 0-64 (or "Su"), final channel panning - + pan swing + pitch/pan + current pan envelope value! + Yxx - (note: suggests that Xxx panning is reduced to 64 values when it's applied?) - PE - 0-64, pan envelope - note: this value is not changed if pan env is turned off (e.g. with S79) -- so it's copied - all of the above are still set to valid values in sample mode - */ - - draw_fill_chars(5, base + 1, 29, base + height - 2, 0); - draw_box(4, base, 30, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - draw_text("Frequency", 6, base, 2, 1); - draw_text("Position", 17, base, 2, 1); - draw_text("Smp", 27, base, 2, 1); - - draw_fill_chars(32, base + 1, 56, base + height - 2, 0); - draw_box(31, base, 57, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - draw_text("FVl", 32, base, 2, 1); - draw_text("Vl", 36, base, 2, 1); - draw_text("CV", 39, base, 2, 1); - draw_text("SV", 42, base, 2, 1); - draw_text("VE", 45, base, 2, 1); - draw_text("Fde", 48, base, 2, 1); - draw_text("Pn", 52, base, 2, 1); - draw_text("PE", 55, base, 2, 1); - - if (song_is_instrument_mode()) { - draw_fill_chars(59, base + 1, 65, base + height - 2, 0); - draw_box(58, base, 66, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - draw_text("NNA", 59, base, 2, 1); - draw_text("Tot", 63, base, 2, 1); - } - - for (pos = base + 1; pos < base + height - 1; pos++, c++) { - song_channel_t *channel = current_song->channels + c - 1; - song_voice_t *voice = current_song->voices + c - 1; - - if (c == selected_channel) { - fg = (channel->flags & CHN_MUTE) ? 6 : 3; - } else { - if (channel->flags & CHN_MUTE) - fg = 2; - else - fg = active ? 1 : 0; - } - draw_text(num99tostr(c, buf), 2, pos, fg, 2); /* channel number */ - - draw_char(168, 15, pos, 2, 0); - draw_char(168, 26, pos, 2, 0); - draw_char(168, 35, pos, 2, 0); - draw_char(168, 38, pos, 2, 0); - draw_char(168, 41, pos, 2, 0); - draw_char(168, 44, pos, 2, 0); - draw_char(168, 47, pos, 2, 0); - draw_char(168, 51, pos, 2, 0); - draw_char(168, 54, pos, 2, 0); - - if (song_is_instrument_mode()) { - draw_text("---\xa8", 59, pos, 2, 0); /* will be overwritten if something's playing */ - - /* count how many voices claim this channel */ - int nv, tot; - for (nv = tot = 0; nv < MAX_VOICES; nv++) { - song_voice_t *v = current_song->voices + nv; - if (v->master_channel == (unsigned int) c && v->current_sample_data && v->length) - tot++; - } - if (voice->current_sample_data && voice->length) - tot++; - draw_text(numtostr(3, tot, buf), 63, pos, 2, 0); - } - - if (voice->current_sample_data && voice->length && voice->ptr_sample) { - // again with the hacks... - smp = voice->ptr_sample - current_song->samples; - if (smp <= 0 || smp >= MAX_SAMPLES) - continue; - } else { - continue; - } - - // Frequency - sprintf(buf, "%10d", voice->sample_freq); - draw_text(buf, 5, pos, 2, 0); - // Position - sprintf(buf, "%10d", voice->position); - draw_text(buf, 16, pos, 2, 0); - - draw_text(numtostr(3, smp, buf), 27, pos, 2, 0); // Smp - draw_text(numtostr(3, voice->final_volume / 128, buf), 32, pos, 2, 0); // FVl - draw_text(numtostr(2, voice->volume >> 2, buf), 36, pos, 2, 0); // Vl - draw_text(numtostr(2, voice->global_volume, buf), 39, pos, 2, 0); // CV - draw_text(numtostr(2, voice->ptr_sample->global_volume, buf), 42, pos, 2, 0); // SV - draw_text(numtostr(2, voice->instrument_volume, buf), 45, pos, 2, 0); // VE - draw_text(numtostr(3, voice->fadeout_volume / 128, buf), 48, pos, 2, 0); // Fde - - // Pn - if (voice->flags & CHN_SURROUND) - draw_text("Su", 52, pos, 2, 0); - else - draw_text(numtostr(2, voice->panning >> 2, buf), 52, pos, 2, 0); - - draw_text(numtostr(2, voice->final_panning >> 2, buf), 55, pos, 2, 0); // PE - - if (song_is_instrument_mode()) { - switch (voice->nna) { - case NNA_NOTECUT: ptr = "Cut"; break; - case NNA_CONTINUE: ptr = "Con"; break; - case NNA_NOTEOFF: ptr = "Off"; break; - case NNA_NOTEFADE: ptr = "Fde"; break; - default: ptr = "???"; break; - }; - draw_text(ptr, 59, pos, 2, 0); - } - } + int smp, pos, fg, c = first_channel; + char buf[16]; + const char *ptr; + + /* + FVl - 0-128, final calculated volume, taking everything into account: + (sample volume, sample global volume, instrument volume, inst. global volume, + volume envelope, volume swing, fadeout, channel volume, song global volume, effects (I/Q/R) + Vl - 0-64, sample volume / volume column (also affected by I/Q/R) + CV - 0-64, channel volume (M/N) + SV - 0-64, sample global volume + inst global volume + Fde - 0-512, HALF the fade + (initially 1024, and subtracted by instrument fade value each tick when fading out) + Pn - 0-64 (or "Su"), final channel panning + + pan swing + pitch/pan + current pan envelope value! + Yxx + (note: suggests that Xxx panning is reduced to 64 values when it's applied?) + PE - 0-64, pan envelope + note: this value is not changed if pan env is turned off (e.g. with S79) -- so it's copied + all of the above are still set to valid values in sample mode + */ + + draw_fill_chars(5, base + 1, 29, base + height - 2, 0); + draw_box(4, base, 30, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Frequency", 6, base, 2, 1); + draw_text("Position", 17, base, 2, 1); + draw_text("Smp", 27, base, 2, 1); + + draw_fill_chars(32, base + 1, 56, base + height - 2, 0); + draw_box(31, base, 57, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("FVl", 32, base, 2, 1); + draw_text("Vl", 36, base, 2, 1); + draw_text("CV", 39, base, 2, 1); + draw_text("SV", 42, base, 2, 1); + draw_text("VE", 45, base, 2, 1); + draw_text("Fde", 48, base, 2, 1); + draw_text("Pn", 52, base, 2, 1); + draw_text("PE", 55, base, 2, 1); + + if (song_is_instrument_mode()) { + draw_fill_chars(59, base + 1, 65, base + height - 2, 0); + draw_box(58, base, 66, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("NNA", 59, base, 2, 1); + draw_text("Tot", 63, base, 2, 1); + } + + for (pos = base + 1; pos < base + height - 1; pos++, c++) { + song_channel_t *channel = current_song->channels + c - 1; + song_voice_t *voice = current_song->voices + c - 1; + + if (c == selected_channel) { + fg = (channel->flags & CHN_MUTE) ? 6 : 3; + } else { + if (channel->flags & CHN_MUTE) + fg = 2; + else + fg = active ? 1 : 0; + } + draw_text(num99tostr(c, buf), 2, pos, fg, 2); /* channel number */ + + draw_char(168, 15, pos, 2, 0); + draw_char(168, 26, pos, 2, 0); + draw_char(168, 35, pos, 2, 0); + draw_char(168, 38, pos, 2, 0); + draw_char(168, 41, pos, 2, 0); + draw_char(168, 44, pos, 2, 0); + draw_char(168, 47, pos, 2, 0); + draw_char(168, 51, pos, 2, 0); + draw_char(168, 54, pos, 2, 0); + + if (song_is_instrument_mode()) { + draw_text("---\xa8", 59, pos, 2, 0); /* will be overwritten if something's playing */ + + /* count how many voices claim this channel */ + int nv, tot; + for (nv = tot = 0; nv < MAX_VOICES; nv++) { + song_voice_t *v = current_song->voices + nv; + if (v->master_channel == (unsigned int) c && v->current_sample_data && v->length) + tot++; + } + if (voice->current_sample_data && voice->length) + tot++; + draw_text(numtostr(3, tot, buf), 63, pos, 2, 0); + } + + if (voice->current_sample_data && voice->length && voice->ptr_sample) { + // again with the hacks... + smp = voice->ptr_sample - current_song->samples; + if (smp <= 0 || smp >= MAX_SAMPLES) + continue; + } else { + continue; + } + + // Frequency + sprintf(buf, "%10d", voice->sample_freq); + draw_text(buf, 5, pos, 2, 0); + // Position + sprintf(buf, "%10d", voice->position); + draw_text(buf, 16, pos, 2, 0); + + draw_text(numtostr(3, smp, buf), 27, pos, 2, 0); // Smp + draw_text(numtostr(3, voice->final_volume / 128, buf), 32, pos, 2, 0); // FVl + draw_text(numtostr(2, voice->volume >> 2, buf), 36, pos, 2, 0); // Vl + draw_text(numtostr(2, voice->global_volume, buf), 39, pos, 2, 0); // CV + draw_text(numtostr(2, voice->ptr_sample->global_volume, buf), 42, pos, 2, 0); // SV + draw_text(numtostr(2, voice->instrument_volume, buf), 45, pos, 2, 0); // VE + draw_text(numtostr(3, voice->fadeout_volume / 128, buf), 48, pos, 2, 0); // Fde + + // Pn + if (voice->flags & CHN_SURROUND) + draw_text("Su", 52, pos, 2, 0); + else + draw_text(numtostr(2, voice->panning >> 2, buf), 52, pos, 2, 0); + + draw_text(numtostr(2, voice->final_panning >> 2, buf), 55, pos, 2, 0); // PE + + if (song_is_instrument_mode()) { + switch (voice->nna) { + case NNA_NOTECUT: ptr = "Cut"; break; + case NNA_CONTINUE: ptr = "Con"; break; + case NNA_NOTEOFF: ptr = "Off"; break; + case NNA_NOTEFADE: ptr = "Fde"; break; + default: ptr = "???"; break; + }; + draw_text(ptr, 59, pos, 2, 0); + } + } } static void info_draw_samples(int base, int height, int active, int first_channel) { - int vu, smp, ins, n, pos, fg, fg2, c = first_channel; - char buf[8]; - char *ptr; - - draw_fill_chars(5, base + 1, 28, base + height - 2, 0); - draw_fill_chars(31, base + 1, 61, base + height - 2, 0); - - draw_box(4, base, 29, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(30, base, 62, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - if (song_is_stereo()) { - draw_fill_chars(64, base + 1, 72, base + height - 2, 0); - draw_box(63, base, 73, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - } else { - draw_fill_chars(63, base, 73, base + height, 2); - } - - if (song_get_mode() == MODE_STOPPED) { - for (pos = base + 1; pos < base + height - 1; pos++, c++) { - song_channel_t *channel = song_get_channel(c - 1); - - if (c == selected_channel) { - fg = (channel->flags & CHN_MUTE) ? 6 : 3; - } else { - if (channel->flags & CHN_MUTE) - continue; - fg = active ? 1 : 0; - } - draw_text(numtostr(2, c, buf), 2, pos, fg, 2); - } - return; - } - - for (pos = base + 1; pos < base + height - 1; pos++, c++) { - song_voice_t *voice = current_song->voices + c - 1; - - /* always draw the channel number */ - if (c == selected_channel) - fg = (voice->flags & CHN_MUTE) ? 6 : 3; - else if (voice->flags & CHN_MUTE) - fg = 2; /* same as bg */ - else - fg = active ? 1 : 0; - draw_text(numtostr(2, c, buf), 2, pos, fg, 2); - - if (!(voice->current_sample_data && voice->length)) - continue; - - /* first box: vu meter */ - if (velocity_mode) - vu = voice->final_volume >> 8; - else - vu = voice->vu_meter >> 2; - if (voice->flags & CHN_MUTE) { - fg = 1; fg2 = 2; - } else { - fg = 5; fg2 = 4; - } - draw_vu_meter(5, pos, 24, vu, fg, fg2); - - /* second box: sample number/name */ - ins = song_get_instrument_number(voice->ptr_instrument); - /* figuring out the sample number is an ugly hack... considering all the crap that's - copied to the channel, i'm surprised that the sample and instrument numbers aren't - in there somewhere... */ - if (voice->ptr_sample) - smp = voice->ptr_sample - current_song->samples; - else - smp = ins = 0; - if(smp < 0 || smp >= MAX_SAMPLES) - smp = ins = 0; /* This sample is not in the sample array */ - - if (smp) { - draw_text(num99tostr(smp, buf), 31, pos, 6, 0); - if (ins) { - draw_char('/', 33, pos, 6, 0); - draw_text(num99tostr(ins, buf), 34, pos, 6, 0); - n = 36; - } else { - n = 33; - } - if (voice->volume == 0) - fg = 4; - else if (voice->flags & (CHN_KEYOFF | CHN_NOTEFADE)) - fg = 7; - else - fg = 6; - draw_char(':', n++, pos, fg, 0); - if (instrument_names && voice->ptr_instrument) { - ptr = voice->ptr_instrument->name; - } else { - ptr = current_song->samples[smp].name; - } - draw_text_len(ptr, 25, n, pos, 6, 0); - } else if (ins && voice->ptr_instrument && voice->ptr_instrument->midi_channel_mask) { - // XXX why? what? - if (voice->ptr_instrument->midi_channel_mask >= 0x10000) { - draw_text(numtostr(2, ((c-1) % 16)+1, buf), 31, pos, 6, 0); - } else { - int ch = 0; - while(!(voice->ptr_instrument->midi_channel_mask & (1 << ch))) ++ch; - draw_text(numtostr(2, ch, buf), 31, pos, 6, 0); - } - draw_char('/', 33, pos, 6, 0); - draw_text(num99tostr(ins, buf), 34, pos, 6, 0); - n = 36; - if (voice->volume == 0) - fg = 4; - else if (voice->flags & (CHN_KEYOFF | CHN_NOTEFADE)) - fg = 7; - else - fg = 6; - draw_char(':', n++, pos, fg, 0); - ptr = voice->ptr_instrument->name; - draw_text_len( ptr, 25, n, pos, 6, 0); - } else { - continue; - } - - /* last box: panning. this one's much easier than the - * other two, thankfully :) */ - if (song_is_stereo()) { - if (!voice->ptr_sample) { - /* nothing... */ - } else if (voice->flags & CHN_SURROUND) { - draw_text("Surround", 64, pos, 2, 0); - } else if (voice->final_panning >> 2 == 0) { - draw_text("Left", 64, pos, 2, 0); - } else if ((voice->final_panning + 3) >> 2 == 64) { - draw_text("Right", 68, pos, 2, 0); - } else { - draw_thumb_bar(64, pos, 9, 0, 256, voice->final_panning, 0); - } - } - } + int vu, smp, ins, n, pos, fg, fg2, c = first_channel; + char buf[8]; + char *ptr; + + draw_fill_chars(5, base + 1, 28, base + height - 2, 0); + draw_fill_chars(31, base + 1, 61, base + height - 2, 0); + + draw_box(4, base, 29, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(30, base, 62, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + if (song_is_stereo()) { + draw_fill_chars(64, base + 1, 72, base + height - 2, 0); + draw_box(63, base, 73, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + } else { + draw_fill_chars(63, base, 73, base + height, 2); + } + + if (song_get_mode() == MODE_STOPPED) { + for (pos = base + 1; pos < base + height - 1; pos++, c++) { + song_channel_t *channel = song_get_channel(c - 1); + + if (c == selected_channel) { + fg = (channel->flags & CHN_MUTE) ? 6 : 3; + } else { + if (channel->flags & CHN_MUTE) + continue; + fg = active ? 1 : 0; + } + draw_text(numtostr(2, c, buf), 2, pos, fg, 2); + } + return; + } + + for (pos = base + 1; pos < base + height - 1; pos++, c++) { + song_voice_t *voice = current_song->voices + c - 1; + + /* always draw the channel number */ + if (c == selected_channel) + fg = (voice->flags & CHN_MUTE) ? 6 : 3; + else if (voice->flags & CHN_MUTE) + fg = 2; /* same as bg */ + else + fg = active ? 1 : 0; + draw_text(numtostr(2, c, buf), 2, pos, fg, 2); + + if (!(voice->current_sample_data && voice->length)) + continue; + + /* first box: vu meter */ + if (velocity_mode) + vu = voice->final_volume >> 8; + else + vu = voice->vu_meter >> 2; + if (voice->flags & CHN_MUTE) { + fg = 1; fg2 = 2; + } else { + fg = 5; fg2 = 4; + } + draw_vu_meter(5, pos, 24, vu, fg, fg2); + + /* second box: sample number/name */ + ins = song_get_instrument_number(voice->ptr_instrument); + /* figuring out the sample number is an ugly hack... considering all the crap that's + copied to the channel, i'm surprised that the sample and instrument numbers aren't + in there somewhere... */ + if (voice->ptr_sample) + smp = voice->ptr_sample - current_song->samples; + else + smp = ins = 0; + if(smp < 0 || smp >= MAX_SAMPLES) + smp = ins = 0; /* This sample is not in the sample array */ + + if (smp) { + draw_text(num99tostr(smp, buf), 31, pos, 6, 0); + if (ins) { + draw_char('/', 33, pos, 6, 0); + draw_text(num99tostr(ins, buf), 34, pos, 6, 0); + n = 36; + } else { + n = 33; + } + if (voice->volume == 0) + fg = 4; + else if (voice->flags & (CHN_KEYOFF | CHN_NOTEFADE)) + fg = 7; + else + fg = 6; + draw_char(':', n++, pos, fg, 0); + if (instrument_names && voice->ptr_instrument) { + ptr = voice->ptr_instrument->name; + } else { + ptr = current_song->samples[smp].name; + } + draw_text_len(ptr, 25, n, pos, 6, 0); + } else if (ins && voice->ptr_instrument && voice->ptr_instrument->midi_channel_mask) { + // XXX why? what? + if (voice->ptr_instrument->midi_channel_mask >= 0x10000) { + draw_text(numtostr(2, ((c-1) % 16)+1, buf), 31, pos, 6, 0); + } else { + int ch = 0; + while(!(voice->ptr_instrument->midi_channel_mask & (1 << ch))) ++ch; + draw_text(numtostr(2, ch, buf), 31, pos, 6, 0); + } + draw_char('/', 33, pos, 6, 0); + draw_text(num99tostr(ins, buf), 34, pos, 6, 0); + n = 36; + if (voice->volume == 0) + fg = 4; + else if (voice->flags & (CHN_KEYOFF | CHN_NOTEFADE)) + fg = 7; + else + fg = 6; + draw_char(':', n++, pos, fg, 0); + ptr = voice->ptr_instrument->name; + draw_text_len( ptr, 25, n, pos, 6, 0); + } else { + continue; + } + + /* last box: panning. this one's much easier than the + * other two, thankfully :) */ + if (song_is_stereo()) { + if (!voice->ptr_sample) { + /* nothing... */ + } else if (voice->flags & CHN_SURROUND) { + draw_text("Surround", 64, pos, 2, 0); + } else if (voice->final_panning >> 2 == 0) { + draw_text("Left", 64, pos, 2, 0); + } else if ((voice->final_panning + 3) >> 2 == 64) { + draw_text("Right", 68, pos, 2, 0); + } else { + draw_thumb_bar(64, pos, 9, 0, 256, voice->final_panning, 0); + } + } + } } static void _draw_fill_notes(int col, int first_row, int height, int num_channels, - int channel_width, int separator, draw_note_func draw_note, int bg) + int channel_width, int separator, draw_note_func draw_note, int bg) { - int row_pos, chan_pos; + int row_pos, chan_pos; - for (row_pos = first_row; row_pos < first_row + height; row_pos++) { - for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { - draw_note(col + channel_width * chan_pos, row_pos, blank_note, -1, 6, bg); - if (separator) - draw_char(168, (col - 1 + channel_width * (chan_pos + 1)), row_pos, 2, bg); - } - draw_note(col + channel_width * chan_pos, row_pos, blank_note, -1, 6, bg); - } + for (row_pos = first_row; row_pos < first_row + height; row_pos++) { + for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { + draw_note(col + channel_width * chan_pos, row_pos, blank_note, -1, 6, bg); + if (separator) + draw_char(168, (col - 1 + channel_width * (chan_pos + 1)), row_pos, 2, bg); + } + draw_note(col + channel_width * chan_pos, row_pos, blank_note, -1, 6, bg); + } } static void _draw_track_view(int base, int height, int first_channel, int num_channels, - int channel_width, int separator, draw_note_func draw_note) + int channel_width, int separator, draw_note_func draw_note) { - /* way too many variables */ - int current_row = song_get_current_row(); - int current_order = song_get_current_order(); - const song_note_t *note; - // These can't be const because of song_get_pattern, but song_get_pattern is stupid and smells funny. - song_note_t *cur_pattern, *prev_pattern, *next_pattern; - const song_note_t *pattern; /* points to either {cur,prev,next}_pattern */ - int cur_pattern_rows = 0, prev_pattern_rows = 0, next_pattern_rows = 0; - int total_rows; /* same as {cur,prev_next}_pattern_rows */ - int chan_pos, row, row_pos, rows_before, rows_after; - char buf[4]; + /* way too many variables */ + int current_row = song_get_current_row(); + int current_order = song_get_current_order(); + const song_note_t *note; + // These can't be const because of song_get_pattern, but song_get_pattern is stupid and smells funny. + song_note_t *cur_pattern, *prev_pattern, *next_pattern; + const song_note_t *pattern; /* points to either {cur,prev,next}_pattern */ + int cur_pattern_rows = 0, prev_pattern_rows = 0, next_pattern_rows = 0; + int total_rows; /* same as {cur,prev_next}_pattern_rows */ + int chan_pos, row, row_pos, rows_before, rows_after; + char buf[4]; - if (separator) - channel_width++; + if (separator) + channel_width++; #if 0 - /* can't do this here -- each view does channel numbers differently, don't draw on top of them */ - draw_box(4, base, 5 + num_channels * channel_width - !!separator, base + height - 1, - BOX_THICK | BOX_INNER | BOX_INSET); + /* can't do this here -- each view does channel numbers differently, don't draw on top of them */ + draw_box(4, base, 5 + num_channels * channel_width - !!separator, base + height - 1, + BOX_THICK | BOX_INNER | BOX_INSET); #endif - switch (song_get_mode()) { - case MODE_PATTERN_LOOP: - prev_pattern_rows = next_pattern_rows = cur_pattern_rows - = song_get_pattern(song_get_playing_pattern(), &cur_pattern); - prev_pattern = next_pattern = cur_pattern; - break; - case MODE_PLAYING: - if (current_song->orderlist[current_order] >= 200) { - /* this does, in fact, happen. just pretend that - * it's stopped :P */ - default: - /* stopped */ - draw_fill_chars(5, base + 1, 4 + num_channels * channel_width - !!separator, - base + height - 2, 0); - return; - } - cur_pattern_rows = song_get_pattern(current_song->orderlist[current_order], &cur_pattern); - if (current_order > 0 && current_song->orderlist[current_order - 1] < 200) - prev_pattern_rows = song_get_pattern(current_song->orderlist[current_order - 1], - &prev_pattern); - else - prev_pattern = NULL; - if (current_order < 255 && current_song->orderlist[current_order + 1] < 200) - next_pattern_rows = song_get_pattern(current_song->orderlist[current_order + 1], - &next_pattern); - else - next_pattern = NULL; - break; - } - - rows_before = (height - 2) / 2; - rows_after = rows_before; - if (height & 1) - rows_after++; - - /* "fake" channels (hack for 64-channel view) */ - if (num_channels > 64) { - _draw_fill_notes(5 + 64, base + 1, height - 2, - num_channels - 64, channel_width, separator, draw_note, 0); - _draw_fill_notes(5 + 64, base + 1 + rows_before, 1, - num_channels - 64, channel_width, separator, draw_note, 14); - num_channels = 64; - } - - /* draw the area above the current row */ - pattern = cur_pattern; - total_rows = cur_pattern_rows; - row = current_row - 1; - row_pos = base + rows_before; - while (row_pos > base) { - if (row < 0) { - if (prev_pattern == NULL) { - _draw_fill_notes(5, base + 1, row_pos - base, - num_channels, channel_width, separator, draw_note, 0); - break; - } - pattern = prev_pattern; - total_rows = prev_pattern_rows; - row = total_rows - 1; - } - draw_text(numtostr(3, row, buf), 1, row_pos, 0, 2); - note = pattern + 64 * row + first_channel - 1; - for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); - if (separator) - draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 0); - note++; - } - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); - row--; - row_pos--; - } - - /* draw the current row */ - pattern = cur_pattern; - total_rows = cur_pattern_rows; - row_pos = base + rows_before + 1; - draw_text(numtostr(3, current_row, buf), 1, row_pos, 0, 2); - note = pattern + 64 * current_row + first_channel - 1; - for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 14); - if (separator) - draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 14); - note++; - } - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 14); - - /* draw the area under the current row */ - row = current_row + 1; - row_pos++; - while (row_pos < base + height - 1) { - if (row >= total_rows) { - if (next_pattern == NULL) { - _draw_fill_notes(5, row_pos, base + height - row_pos - 1, - num_channels, channel_width, separator, draw_note, 0); - break; - } - pattern = next_pattern; - total_rows = next_pattern_rows; - row = 0; - } - draw_text(numtostr(3, row, buf), 1, row_pos, 0, 2); - note = pattern + 64 * row + first_channel - 1; - for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); - if (separator) - draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 0); - note++; - } - draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); - row++; - row_pos++; - } + switch (song_get_mode()) { + case MODE_PATTERN_LOOP: + prev_pattern_rows = next_pattern_rows = cur_pattern_rows + = song_get_pattern(song_get_playing_pattern(), &cur_pattern); + prev_pattern = next_pattern = cur_pattern; + break; + case MODE_PLAYING: + if (current_song->orderlist[current_order] >= 200) { + /* this does, in fact, happen. just pretend that + * it's stopped :P */ + default: + /* stopped */ + draw_fill_chars(5, base + 1, 4 + num_channels * channel_width - !!separator, + base + height - 2, 0); + return; + } + cur_pattern_rows = song_get_pattern(current_song->orderlist[current_order], &cur_pattern); + if (current_order > 0 && current_song->orderlist[current_order - 1] < 200) + prev_pattern_rows = song_get_pattern(current_song->orderlist[current_order - 1], + &prev_pattern); + else + prev_pattern = NULL; + if (current_order < 255 && current_song->orderlist[current_order + 1] < 200) + next_pattern_rows = song_get_pattern(current_song->orderlist[current_order + 1], + &next_pattern); + else + next_pattern = NULL; + break; + } + + rows_before = (height - 2) / 2; + rows_after = rows_before; + if (height & 1) + rows_after++; + + /* "fake" channels (hack for 64-channel view) */ + if (num_channels > 64) { + _draw_fill_notes(5 + 64, base + 1, height - 2, + num_channels - 64, channel_width, separator, draw_note, 0); + _draw_fill_notes(5 + 64, base + 1 + rows_before, 1, + num_channels - 64, channel_width, separator, draw_note, 14); + num_channels = 64; + } + + /* draw the area above the current row */ + pattern = cur_pattern; + total_rows = cur_pattern_rows; + row = current_row - 1; + row_pos = base + rows_before; + while (row_pos > base) { + if (row < 0) { + if (prev_pattern == NULL) { + _draw_fill_notes(5, base + 1, row_pos - base, + num_channels, channel_width, separator, draw_note, 0); + break; + } + pattern = prev_pattern; + total_rows = prev_pattern_rows; + row = total_rows - 1; + } + draw_text(numtostr(3, row, buf), 1, row_pos, 0, 2); + note = pattern + 64 * row + first_channel - 1; + for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); + if (separator) + draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 0); + note++; + } + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); + row--; + row_pos--; + } + + /* draw the current row */ + pattern = cur_pattern; + total_rows = cur_pattern_rows; + row_pos = base + rows_before + 1; + draw_text(numtostr(3, current_row, buf), 1, row_pos, 0, 2); + note = pattern + 64 * current_row + first_channel - 1; + for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 14); + if (separator) + draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 14); + note++; + } + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 14); + + /* draw the area under the current row */ + row = current_row + 1; + row_pos++; + while (row_pos < base + height - 1) { + if (row >= total_rows) { + if (next_pattern == NULL) { + _draw_fill_notes(5, row_pos, base + height - row_pos - 1, + num_channels, channel_width, separator, draw_note, 0); + break; + } + pattern = next_pattern; + total_rows = next_pattern_rows; + row = 0; + } + draw_text(numtostr(3, row, buf), 1, row_pos, 0, 2); + note = pattern + 64 * row + first_channel - 1; + for (chan_pos = 0; chan_pos < num_channels - 1; chan_pos++) { + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); + if (separator) + draw_char(168, (4 + channel_width * (chan_pos + 1)), row_pos, 2, 0); + note++; + } + draw_note(5 + channel_width * chan_pos, row_pos, note, -1, 6, 0); + row++; + row_pos++; + } } static void info_draw_track_5(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; + int chan, chan_pos, fg; - draw_box(4, base, 74, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 5; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_channel_header_13(chan, 5 + 14 * chan_pos, base, fg); - } - _draw_track_view(base, height, first_channel, 5, 13, 1, draw_note_13); + draw_box(4, base, 74, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 5; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_channel_header_13(chan, 5 + 14 * chan_pos, base, fg); + } + _draw_track_view(base, height, first_channel, 5, 13, 1, draw_note_13); } static void info_draw_track_8(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 76, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 8; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_char(0, 6 + 9 * chan_pos, base, 1, 1); - draw_char(0, 6 + 9 * chan_pos + 1, base, 1, 1); - draw_text(numtostr(2, chan, buf), 6 + 9 * chan_pos + 2, base, fg, 1); - draw_char(0, 6 + 9 * chan_pos + 4, base, 1, 1); - draw_char(0, 6 + 9 * chan_pos + 5, base, 1, 1); - } - _draw_track_view(base, height, first_channel, 8, 8, 1, draw_note_8); + draw_box(4, base, 76, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 8; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_char(0, 6 + 9 * chan_pos, base, 1, 1); + draw_char(0, 6 + 9 * chan_pos + 1, base, 1, 1); + draw_text(numtostr(2, chan, buf), 6 + 9 * chan_pos + 2, base, fg, 1); + draw_char(0, 6 + 9 * chan_pos + 4, base, 1, 1); + draw_char(0, 6 + 9 * chan_pos + 5, base, 1, 1); + } + _draw_track_view(base, height, first_channel, 8, 8, 1, draw_note_8); } static void info_draw_track_10(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 75, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 10; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_char(0, 5 + 7 * chan_pos, base, 1, 1); - draw_char(0, 5 + 7 * chan_pos + 1, base, 1, 1); - draw_text(numtostr(2, chan, buf), 5 + 7 * chan_pos + 2, base, fg, 1); - draw_char(0, 5 + 7 * chan_pos + 4, base, 1, 1); - draw_char(0, 5 + 7 * chan_pos + 5, base, 1, 1); - } - _draw_track_view(base, height, first_channel, 10, 7, 0, draw_note_7); + draw_box(4, base, 75, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 10; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_char(0, 5 + 7 * chan_pos, base, 1, 1); + draw_char(0, 5 + 7 * chan_pos + 1, base, 1, 1); + draw_text(numtostr(2, chan, buf), 5 + 7 * chan_pos + 2, base, fg, 1); + draw_char(0, 5 + 7 * chan_pos + 4, base, 1, 1); + draw_char(0, 5 + 7 * chan_pos + 5, base, 1, 1); + } + _draw_track_view(base, height, first_channel, 10, 7, 0, draw_note_7); } static void info_draw_track_12(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 12; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - /* draw_char(0, 5 + 6 * chan_pos, base, 1, 1); */ - draw_char(0, 5 + 6 * chan_pos + 1, base, 1, 1); - draw_text(numtostr(2, chan, buf), 5 + 6 * chan_pos + 2, base, fg, 1); - draw_char(0, 5 + 6 * chan_pos + 4, base, 1, 1); - /* draw_char(0, 5 + 6 * chan_pos + 5, base, 1, 1); */ - } - _draw_track_view(base, height, first_channel, 12, 6, 0, draw_note_6); + draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 12; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + /* draw_char(0, 5 + 6 * chan_pos, base, 1, 1); */ + draw_char(0, 5 + 6 * chan_pos + 1, base, 1, 1); + draw_text(numtostr(2, chan, buf), 5 + 6 * chan_pos + 2, base, fg, 1); + draw_char(0, 5 + 6 * chan_pos + 4, base, 1, 1); + /* draw_char(0, 5 + 6 * chan_pos + 5, base, 1, 1); */ + } + _draw_track_view(base, height, first_channel, 12, 6, 0, draw_note_6); } static void info_draw_track_18(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 76, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 18; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_text(numtostr(2, chan, buf), 5 + 4 * chan_pos + 1, base, fg, 1); - } - _draw_track_view(base, height, first_channel, 18, 3, 1, draw_note_3); + draw_box(4, base, 76, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 18; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_text(numtostr(2, chan, buf), 5 + 4 * chan_pos + 1, base, fg, 1); + } + _draw_track_view(base, height, first_channel, 18, 3, 1, draw_note_3); } static void info_draw_track_24(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 24; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_text(numtostr(2, chan, buf), 5 + 3 * chan_pos + 1, base, fg, 1); - } - _draw_track_view(base, height, first_channel, 24, 3, 0, draw_note_3); + draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 24; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_text(numtostr(2, chan, buf), 5 + 3 * chan_pos + 1, base, fg, 1); + } + _draw_track_view(base, height, first_channel, 24, 3, 0, draw_note_3); } static void info_draw_track_36(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - char buf[4]; + int chan, chan_pos, fg; + char buf[4]; - draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 36; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 6 : 1); - else - fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); - draw_text(numtostr(2, chan, buf), 5 + 2 * chan_pos, base, fg, 1); - } - _draw_track_view(base, height, first_channel, 36, 2, 0, draw_note_2); + draw_box(4, base, 77, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 36; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 6 : 1); + else + fg = (chan == selected_channel ? 3 : (active ? 2 : 0)); + draw_text(numtostr(2, chan, buf), 5 + 2 * chan_pos, base, fg, 1); + } + _draw_track_view(base, height, first_channel, 36, 2, 0, draw_note_2); } static void info_draw_track_64(int base, int height, int active, int first_channel) { - int chan, chan_pos, fg; - /* IT draws nine more blank "channels" on the right */ - int nchan = (status.flags & CLASSIC_MODE) ? 73 : 64; - - assert(first_channel == 1); - - draw_box(4, base, nchan + 5, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - for (chan = first_channel, chan_pos = 0; chan_pos < 64; chan++, chan_pos++) { - if (current_song->channels[chan - 1].flags & CHN_MUTE) - fg = (chan == selected_channel ? 14 : 9); - else - fg = (chan == selected_channel ? 3 : (active ? 10 : 8)); - draw_half_width_chars(chan / 10 + '0', chan % 10 + '0', 5 + chan_pos, base, fg, 1, fg, 1); - } - for (; chan_pos < nchan; chan_pos++) - draw_char(0, 5 + chan_pos, base, 1, 1); + int chan, chan_pos, fg; + /* IT draws nine more blank "channels" on the right */ + int nchan = (status.flags & CLASSIC_MODE) ? 73 : 64; + + assert(first_channel == 1); + + draw_box(4, base, nchan + 5, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + for (chan = first_channel, chan_pos = 0; chan_pos < 64; chan++, chan_pos++) { + if (current_song->channels[chan - 1].flags & CHN_MUTE) + fg = (chan == selected_channel ? 14 : 9); + else + fg = (chan == selected_channel ? 3 : (active ? 10 : 8)); + draw_half_width_chars(chan / 10 + '0', chan % 10 + '0', 5 + chan_pos, base, fg, 1, fg, 1); + } + for (; chan_pos < nchan; chan_pos++) + draw_char(0, 5 + chan_pos, base, 1, 1); - _draw_track_view(base, height, first_channel, nchan, 1, 0, draw_note_1); + _draw_track_view(base, height, first_channel, nchan, 1, 0, draw_note_1); } static void info_draw_channels(int base, UNUSED int height, int active, UNUSED int first_channel) { - char buf[32]; - int fg = (active ? 3 : 0); + char buf[32]; + int fg = (active ? 3 : 0); - snprintf(buf, 32, "Active Channels: %d (%d)", song_get_playing_channels(), song_get_max_channels()); - draw_text(buf, 2, base, fg, 2); + snprintf(buf, 32, "Active Channels: %d (%d)", song_get_playing_channels(), song_get_max_channels()); + draw_text(buf, 2, base, fg, 2); - snprintf(buf, 32, "Global Volume: %d", song_get_current_global_volume()); - draw_text(buf, 4, base + 1, fg, 2); + snprintf(buf, 32, "Global Volume: %d", song_get_current_global_volume()); + draw_text(buf, 4, base + 1, fg, 2); } /* Yay it works, only took me forever and a day to get it right. */ static void info_draw_note_dots(int base, int height, int active, int first_channel) { - int fg, v; - int c, pos; - int n; - song_voice_t *voice; - char buf[4]; - uint8_t d, dn; - uint8_t dot_field[73][36] = { {0} }; // f#2 -> f#8 = 73 columns - - draw_fill_chars(5, base + 1, 77, base + height - 2, 0); - draw_box(4, base, 78, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); - - n = current_song->num_voices; - while (n--) { - voice = current_song->voices + current_song->voice_mix[n]; - - /* 31 = f#2, 103 = f#8. (i hope ;) */ - if (!(voice->ptr_sample && voice->note >= 31 && voice->note <= 103)) - continue; - pos = voice->master_channel ?: (1 + current_song->voice_mix[n]); - if (pos < first_channel) - continue; - pos -= first_channel; - if (pos > height - 1) - continue; - - fg = (voice->flags & CHN_MUTE) ? 1 : ((voice->ptr_sample - current_song->samples) % 4 + 2); - - if (velocity_mode || (status.flags & CLASSIC_MODE)) - v = (voice->final_volume + 2047) >> 11; - else - v = (voice->vu_meter + 31) >> 5; - d = dot_field[voice->note - 31][pos]; - dn = (v << 4) | fg; - if (dn > d) - dot_field[voice->note - 31][pos] = dn; - } - - for (c = first_channel, pos = 0; pos < height - 2; pos++, c++) { - for (n = 0; n < 73; n++) { - d = dot_field[n][pos] ?: 0x06; - - fg = d & 0xf; - v = d >> 4; - draw_char(v + 193, n + 5, pos + base + 1, fg, 0); - } - - if (c == selected_channel) { - fg = (current_song->channels[c - 1].flags & CHN_MUTE) ? 6 : 3; - } else { - if (current_song->channels[c - 1].flags & CHN_MUTE) - continue; - fg = active ? 1 : 0; - } - draw_text(numtostr(2, c, buf), 2, pos + base + 1, fg, 2); - } + int fg, v; + int c, pos; + int n; + song_voice_t *voice; + char buf[4]; + uint8_t d, dn; + uint8_t dot_field[73][36] = { {0} }; // f#2 -> f#8 = 73 columns + + draw_fill_chars(5, base + 1, 77, base + height - 2, 0); + draw_box(4, base, 78, base + height - 1, BOX_THICK | BOX_INNER | BOX_INSET); + + n = current_song->num_voices; + while (n--) { + voice = current_song->voices + current_song->voice_mix[n]; + + /* 31 = f#2, 103 = f#8. (i hope ;) */ + if (!(voice->ptr_sample && voice->note >= 31 && voice->note <= 103)) + continue; + pos = voice->master_channel ?: (1 + current_song->voice_mix[n]); + if (pos < first_channel) + continue; + pos -= first_channel; + if (pos > height - 1) + continue; + + fg = (voice->flags & CHN_MUTE) ? 1 : ((voice->ptr_sample - current_song->samples) % 4 + 2); + + if (velocity_mode || (status.flags & CLASSIC_MODE)) + v = (voice->final_volume + 2047) >> 11; + else + v = (voice->vu_meter + 31) >> 5; + d = dot_field[voice->note - 31][pos]; + dn = (v << 4) | fg; + if (dn > d) + dot_field[voice->note - 31][pos] = dn; + } + + for (c = first_channel, pos = 0; pos < height - 2; pos++, c++) { + for (n = 0; n < 73; n++) { + d = dot_field[n][pos] ?: 0x06; + + fg = d & 0xf; + v = d >> 4; + draw_char(v + 193, n + 5, pos + base + 1, fg, 0); + } + + if (c == selected_channel) { + fg = (current_song->channels[c - 1].flags & CHN_MUTE) ? 6 : 3; + } else { + if (current_song->channels[c - 1].flags & CHN_MUTE) + continue; + fg = active ? 1 : 0; + } + draw_text(numtostr(2, c, buf), 2, pos + base + 1, fg, 2); + } } /* --------------------------------------------------------------------- */ @@ -731,60 +731,60 @@ static void click_chn_x(int x, int w, int skip, int fc) { - while (x > 0 && fc <= 64) { - if (x < w) { - selected_channel = CLAMP(fc, 1, 64); - return; - } - fc++; - x -= w; - x -= skip; - } + while (x > 0 && fc <= 64) { + if (x < w) { + selected_channel = CLAMP(fc, 1, 64); + return; + } + fc++; + x -= w; + x -= skip; + } } static void click_chn_is_x(int x, UNUSED int y, int nc, int fc) { - if (x < 5) return; - x -= 4; - switch (nc) { - case 5: - click_chn_x(x, 13, 1, fc); - break; - case 10: - click_chn_x(x, 7, 0, fc); - break; - case 12: - click_chn_x(x, 6, 0, fc); - break; - case 18: - click_chn_x(x, 3, 1, fc); - break; - case 24: - click_chn_x(x, 3, 0, fc); - break; - case 36: - click_chn_x(x, 2, 0, fc); - break; - case 64: - click_chn_x(x, 1, 0, fc); - break; - }; + if (x < 5) return; + x -= 4; + switch (nc) { + case 5: + click_chn_x(x, 13, 1, fc); + break; + case 10: + click_chn_x(x, 7, 0, fc); + break; + case 12: + click_chn_x(x, 6, 0, fc); + break; + case 18: + click_chn_x(x, 3, 1, fc); + break; + case 24: + click_chn_x(x, 3, 0, fc); + break; + case 36: + click_chn_x(x, 2, 0, fc); + break; + case 64: + click_chn_x(x, 1, 0, fc); + break; + }; } static void click_chn_is_y_nohead(UNUSED int x, int y, UNUSED int nc, int fc) { - selected_channel = CLAMP(y+fc, 1, 64); + selected_channel = CLAMP(y+fc, 1, 64); } static void click_chn_is_y(UNUSED int x, int y, UNUSED int nc, int fc) { - if (!y) return; - selected_channel = CLAMP((y+fc)-1, 1, 64); + if (!y) return; + selected_channel = CLAMP((y+fc)-1, 1, 64); } static void click_chn_nil(UNUSED int x, UNUSED int y, UNUSED int nc, UNUSED int fc) { - /* do nothing */ + /* do nothing */ } /* --------------------------------------------------------------------- */ @@ -792,18 +792,18 @@ #define TRACK_VIEW(n) {"track" # n, info_draw_track_##n, click_chn_is_x, 1, n} static const struct info_window_type window_types[] = { - {"samples", info_draw_samples, click_chn_is_y_nohead, 0, -2}, - TRACK_VIEW(5), - TRACK_VIEW(8), - TRACK_VIEW(10), - TRACK_VIEW(12), - TRACK_VIEW(18), - TRACK_VIEW(24), - TRACK_VIEW(36), - TRACK_VIEW(64), - {"global", info_draw_channels, click_chn_nil, 1, 0}, - {"dots", info_draw_note_dots, click_chn_is_y_nohead, 0, -2}, - {"tech", info_draw_technical, click_chn_is_y, 1, -2}, + {"samples", info_draw_samples, click_chn_is_y_nohead, 0, -2}, + TRACK_VIEW(5), + TRACK_VIEW(8), + TRACK_VIEW(10), + TRACK_VIEW(12), + TRACK_VIEW(18), + TRACK_VIEW(24), + TRACK_VIEW(36), + TRACK_VIEW(64), + {"global", info_draw_channels, click_chn_nil, 1, 0}, + {"dots", info_draw_note_dots, click_chn_is_y_nohead, 0, -2}, + {"tech", info_draw_technical, click_chn_is_y, 1, -2}, }; #undef TRACK_VIEW @@ -813,61 +813,61 @@ static void _fix_channels(int n) { - struct info_window *w = windows + n; - int channels = window_types[w->type].channels; + struct info_window *w = windows + n; + int channels = window_types[w->type].channels; - if (channels == 0) - return; + if (channels == 0) + return; - if (channels < 0) { - channels += w->height; - if (n == 0 && !(window_types[w->type].first_row)) { - /* crappy hack (to squeeze in an extra row on the top window) */ - channels++; - } - } - if (selected_channel < w->first_channel) - w->first_channel = selected_channel; - else if (selected_channel >= (w->first_channel + channels)) - w->first_channel = selected_channel - channels + 1; - w->first_channel = CLAMP(w->first_channel, 1, 65 - channels); + if (channels < 0) { + channels += w->height; + if (n == 0 && !(window_types[w->type].first_row)) { + /* crappy hack (to squeeze in an extra row on the top window) */ + channels++; + } + } + if (selected_channel < w->first_channel) + w->first_channel = selected_channel; + else if (selected_channel >= (w->first_channel + channels)) + w->first_channel = selected_channel - channels + 1; + w->first_channel = CLAMP(w->first_channel, 1, 65 - channels); } static int info_handle_click(int x, int y) { - int n; - if (y < 13) return 0; /* NA */ - y -= 13; - for (n = 0; n < num_windows; n++) { - if (y < windows[n].height) { - window_types[windows[n].type].click( - x, y, - - window_types[windows[n].type].channels, - windows[n].first_channel); - return 1; - } - y -= windows[n].height; - } - return 0; + int n; + if (y < 13) return 0; /* NA */ + y -= 13; + for (n = 0; n < num_windows; n++) { + if (y < windows[n].height) { + window_types[windows[n].type].click( + x, y, + + window_types[windows[n].type].channels, + windows[n].first_channel); + return 1; + } + y -= windows[n].height; + } + return 0; } static void recalculate_windows(void) { - int n, pos; + int n, pos; - pos = 13; - for (n = 0; n < num_windows - 1; n++) { - _fix_channels(n); - pos += windows[n].height; - if (pos > 50) { - /* Too big? Throw out the rest of the windows. */ - num_windows = n; - } - } - assert(num_windows > 0); - windows[n].height = 50 - pos; - _fix_channels(n); + pos = 13; + for (n = 0; n < num_windows - 1; n++) { + _fix_channels(n); + pos += windows[n].height; + if (pos > 50) { + /* Too big? Throw out the rest of the windows. */ + num_windows = n; + } + } + assert(num_windows > 0); + windows[n].height = 50 - pos; + _fix_channels(n); } /* --------------------------------------------------------------------------------------------------------- */ @@ -875,441 +875,463 @@ void cfg_save_info(cfg_file_t *cfg) { - // for 5 windows, roughly 12 chars per window, this is way more than enough - char buf[256] = ""; - char *s = buf; - int rem = sizeof(buf) - 1; - int len; - int i; - - for (i = 0; i < num_windows; i++) { - len = snprintf(s, rem, " %s %d", window_types[windows[i].type].id, windows[i].height); - if (!len) { - // this should not ever happen - break; - } - rem -= len; - s += len; - } - buf[255] = '\0'; + // for 5 windows, roughly 12 chars per window, this is way more than enough + char buf[256] = ""; + char *s = buf; + int rem = sizeof(buf) - 1; + int len; + int i; + + for (i = 0; i < num_windows; i++) { + len = snprintf(s, rem, " %s %d", window_types[windows[i].type].id, windows[i].height); + if (!len) { + // this should not ever happen + break; + } + rem -= len; + s += len; + } + buf[255] = '\0'; - // (don't write the first space to the config) - cfg_set_string(cfg, "Info Page", "layout", buf + 1); + // (don't write the first space to the config) + cfg_set_string(cfg, "Info Page", "layout", buf + 1); } static void cfg_load_info_old(cfg_file_t *cfg) { - char key[] = "windowX"; - int i; + char key[] = "windowX"; + int i; - num_windows = cfg_get_number(cfg, "Info Page", "num_windows", -1); - if (num_windows <= 0 || num_windows > MAX_WINDOWS) - num_windows = -1; - - for (i = 0; i < num_windows; i++) { - int tmp; - - key[6] = i + '0'; - tmp = cfg_get_number(cfg, "Info Page", key, -1); - if (tmp == -1) { - num_windows = -1; - break; - } - windows[i].type = tmp >> 8; - if (windows[i].type >= 2) { - // compensate for added 8-channel view - windows[i].type++; - } - windows[i].height = tmp & 0xff; - if (windows[i].type < 0 || windows[i].type >= NUM_WINDOW_TYPES || windows[i].height < 3) { - /* Broken window? */ - num_windows = -1; - break; - } - } - /* last window's size < 3 lines? */ - - if (num_windows == -1) { - /* Fall back to defaults */ - num_windows = 3; - windows[0].type = 0; /* samples */ - windows[0].height = 19; - windows[1].type = 9; /* active channels */ - windows[1].height = 3; - windows[2].type = 6; /* 24chn track view */ - windows[2].height = 15; - } - - for (i = 0; i < num_windows; i++) { - windows[i].first_channel = 1; - } - - recalculate_windows(); - if (status.current_page == PAGE_INFO) - status.flags |= NEED_UPDATE; + num_windows = cfg_get_number(cfg, "Info Page", "num_windows", -1); + if (num_windows <= 0 || num_windows > MAX_WINDOWS) + num_windows = -1; + + for (i = 0; i < num_windows; i++) { + int tmp; + + key[6] = i + '0'; + tmp = cfg_get_number(cfg, "Info Page", key, -1); + if (tmp == -1) { + num_windows = -1; + break; + } + windows[i].type = tmp >> 8; + if (windows[i].type >= 2) { + // compensate for added 8-channel view + windows[i].type++; + } + windows[i].height = tmp & 0xff; + if (windows[i].type < 0 || windows[i].type >= NUM_WINDOW_TYPES || windows[i].height < 3) { + /* Broken window? */ + num_windows = -1; + break; + } + } + /* last window's size < 3 lines? */ + + if (num_windows == -1) { + /* Fall back to defaults */ + num_windows = 3; + windows[0].type = 0; /* samples */ + windows[0].height = 19; + windows[1].type = 9; /* active channels */ + windows[1].height = 3; + windows[2].type = 6; /* 24chn track view */ + windows[2].height = 15; + } + + for (i = 0; i < num_windows; i++) { + windows[i].first_channel = 1; + } + + recalculate_windows(); + if (status.current_page == PAGE_INFO) + status.flags |= NEED_UPDATE; } void cfg_load_info(cfg_file_t *cfg) { - int n; - char buf[256]; - char *left, *right; - size_t len; - - if (!cfg_get_string(cfg, "Info Page", "layout", buf, 255, NULL)) { - cfg_load_info_old(cfg); - return; - } - - left = buf; - num_windows = 0; - do { - left += strspn(left, " \t"); - len = strcspn(left, " \t"); - if (!len) { - break; - } - left[len] = '\0'; // chop it into pieces - windows[num_windows].first_channel = 1; - windows[num_windows].type = -1; - for (n = 0; n < NUM_WINDOW_TYPES; n++) { - if (strcasecmp(window_types[n].id, left) == 0) { - windows[num_windows].type = n; - break; - } - } - // (a pythonic for...else would be lovely right about here) - if (windows[num_windows].type == -1) { - break; - } - right = left + len + 1; - left[len] = '\0'; - n = strtol(right, &left, 10); - if (!left || left == right || n < 3) { - // failed to parse any digits, or number is too small - break; - } - windows[num_windows++].height = n; - } while (num_windows < MAX_WINDOWS - 1); - - recalculate_windows(); - if (status.current_page == PAGE_INFO) - status.flags |= NEED_UPDATE; + int n; + char buf[256]; + char *left, *right; + size_t len; + + if (!cfg_get_string(cfg, "Info Page", "layout", buf, 255, NULL)) { + cfg_load_info_old(cfg); + return; + } + + left = buf; + num_windows = 0; + do { + left += strspn(left, " \t"); + len = strcspn(left, " \t"); + if (!len) { + break; + } + left[len] = '\0'; // chop it into pieces + windows[num_windows].first_channel = 1; + windows[num_windows].type = -1; + for (n = 0; n < NUM_WINDOW_TYPES; n++) { + if (strcasecmp(window_types[n].id, left) == 0) { + windows[num_windows].type = n; + break; + } + } + // (a pythonic for...else would be lovely right about here) + if (windows[num_windows].type == -1) { + break; + } + right = left + len + 1; + left[len] = '\0'; + n = strtol(right, &left, 10); + if (!left || left == right || n < 3) { + // failed to parse any digits, or number is too small + break; + } + windows[num_windows++].height = n; + } while (num_windows < MAX_WINDOWS - 1); + + recalculate_windows(); + if (status.current_page == PAGE_INFO) + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void info_page_redraw(void) { - int n, height, pos = (window_types[windows[0].type].first_row ? 13 : 12); + int n, height, pos = (window_types[windows[0].type].first_row ? 13 : 12); - for (n = 0; n < num_windows - 1; n++) { - height = windows[n].height; - if (pos == 12) - height++; - window_types[windows[n].type].draw(pos, height, (n == selected_window), - windows[n].first_channel); - pos += height; - } - /* the last window takes up all the rest of the screen */ - window_types[windows[n].type].draw(pos, 50 - pos, (n == selected_window), windows[n].first_channel); + for (n = 0; n < num_windows - 1; n++) { + height = windows[n].height; + if (pos == 12) + height++; + window_types[windows[n].type].draw(pos, height, (n == selected_window), + windows[n].first_channel); + pos += height; + } + /* the last window takes up all the rest of the screen */ + window_types[windows[n].type].draw(pos, 50 - pos, (n == selected_window), windows[n].first_channel); } /* --------------------------------------------------------------------- */ static int info_page_handle_key(struct key_event * k) { - int n, p, order; + int n, p, order; - if (k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) { - p = selected_channel; - n = info_handle_click(k->x, k->y); - if (k->mouse == MOUSE_DBLCLICK) { - if (p == selected_channel) { - set_current_channel(selected_channel); - order = song_get_current_order(); - - if (song_get_mode() == MODE_PLAYING) { - n = current_song->orderlist[order]; - } else { - n = song_get_playing_pattern(); - } - if (n < 200) { - set_current_order(order); - set_current_pattern(n); - set_current_row(song_get_current_row()); - set_page(PAGE_PATTERN_EDITOR); - } - } - } - return n; - } - - /* hack to render this useful :) */ - if (k->orig_sym == SDLK_KP9) { - k->sym = SDLK_F9; - } else if (k->orig_sym == SDLK_KP0) { - k->sym = SDLK_F10; - } - - switch (k->sym) { - case SDLK_g: - if (!k->state) return 1; - - set_current_channel(selected_channel); - order = song_get_current_order(); - - if (song_get_mode() == MODE_PLAYING) { - n = current_song->orderlist[order]; - } else { - n = song_get_playing_pattern(); - } - if (n < 200) { - set_current_order(order); - set_current_pattern(n); - set_current_row(song_get_current_row()); - set_page(PAGE_PATTERN_EDITOR); - } - return 1; - case SDLK_v: - if (k->state) return 1; - - velocity_mode = !velocity_mode; - status_text_flash("Using %s bars", (velocity_mode ? "velocity" : "volume")); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_i: - if (k->state) return 1; - - instrument_names = !instrument_names; - status_text_flash("Using %s names", (instrument_names ? "instrument" : "sample")); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_r: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - - song_flip_stereo(); - status_text_flash("Left/right outputs reversed"); - return 1; - } - return 0; - case SDLK_PLUS: - if (k->state) return 1; - if (song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() + 1); - } - return 1; - case SDLK_MINUS: - if (k->state) return 1; - if (song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() - 1); - } - return 1; - case SDLK_q: - if (k->state) return 1; - song_toggle_channel_mute(selected_channel - 1); - orderpan_recheck_muted_channels(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_s: - if (k->state) return 1; - - if (k->mod & KMOD_ALT) { - song_toggle_stereo(); - status_text_flash("Stereo %s", song_is_stereo() - ? "Enabled" : "Disabled"); - } else { - song_handle_channel_solo(selected_channel - 1); - orderpan_recheck_muted_channels(); - } - status.flags |= NEED_UPDATE; - return 1; - case SDLK_SPACE: - if (!NO_MODIFIER(k->mod)) - return 0; - - if (k->state) return 1; - song_toggle_channel_mute(selected_channel - 1); - if (selected_channel < 64) - selected_channel++; - orderpan_recheck_muted_channels(); - break; - case SDLK_UP: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - /* make the current window one line shorter, and give the line to the next window - below it. if the window is already as small as it can get (3 lines) or if it's - the last window, don't do anything. */ - if (selected_window == num_windows - 1 || windows[selected_window].height == 3) { - return 1; - } - windows[selected_window].height--; - windows[selected_window + 1].height++; - break; - } - if (selected_channel > 1) - selected_channel--; - break; - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod) && !(k->mod & KMOD_ALT)) - return 0; - if (k->state) return 1; - if (selected_channel > 1) - selected_channel--; - break; - case SDLK_DOWN: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - /* expand the current window, taking a line from - * the next window down. BUT: don't do anything if - * (a) this is the last window, or (b) the next - * window is already as small as it can be (three - * lines). */ - if (selected_window == num_windows - 1 - || windows[selected_window + 1].height == 3) { - return 1; - } - windows[selected_window].height++; - windows[selected_window + 1].height--; - break; - } - if (selected_channel < 64) - selected_channel++; - break; - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod) && !(k->mod & KMOD_ALT)) - return 0; - if (k->state) return 1; - if (selected_channel < 64) - selected_channel++; - break; - case SDLK_HOME: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - selected_channel = 1; - break; - case SDLK_END: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - selected_channel = song_find_last_channel(); - break; - case SDLK_INSERT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - /* add a new window, unless there's already five (the maximum) - or if the current window isn't big enough to split in half. */ - if (num_windows == MAX_WINDOWS || (windows[selected_window].height < 6)) { - return 1; - } - - num_windows++; - - /* shift the windows under the current one down */ - memmove(windows + selected_window + 1, windows + selected_window, - ((num_windows - selected_window - 1) * sizeof(*windows))); - - /* split the height between the two windows */ - n = windows[selected_window].height; - windows[selected_window].height = n / 2; - windows[selected_window + 1].height = n / 2; - if ((n & 1) && num_windows != 2) { - /* odd number? compensate. (the selected window gets the extra line) */ - windows[selected_window + 1].height++; - } - break; - case SDLK_DELETE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - /* delete the current window and give the extra space to the next window down. - if this is the only window, well then don't delete it ;) */ - if (num_windows == 1) - return 1; - - n = windows[selected_window].height + windows[selected_window + 1].height; - - /* shift the windows under the current one up */ - memmove(windows + selected_window, windows + selected_window + 1, - ((num_windows - selected_window - 1) * sizeof(*windows))); - - /* fix the current window's height */ - windows[selected_window].height = n; - - num_windows--; - if (selected_window == num_windows) - selected_window--; - break; - case SDLK_PAGEUP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - n = windows[selected_window].type; - if (n == 0) - n = NUM_WINDOW_TYPES; - n--; - windows[selected_window].type = n; - break; - case SDLK_PAGEDOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - windows[selected_window].type = (windows[selected_window].type + 1) % NUM_WINDOW_TYPES; - break; - case SDLK_TAB: - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) { - if (selected_window == 0) - selected_window = num_windows; - selected_window--; - } else { - selected_window = (selected_window + 1) % num_windows; - } - status.flags |= NEED_UPDATE; - return 1; - case SDLK_F9: - if (k->state) return 1; - if (k->mod & KMOD_ALT) { - song_toggle_channel_mute(selected_channel - 1); - orderpan_recheck_muted_channels(); - return 1; - } - return 0; - case SDLK_F10: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - song_handle_channel_solo(selected_channel - 1); - orderpan_recheck_muted_channels(); - return 1; - } - return 0; - default: - return 0; - } - - recalculate_windows(); - status.flags |= NEED_UPDATE; - return 1; + if (k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) { + p = selected_channel; + n = info_handle_click(k->x, k->y); + if (k->mouse == MOUSE_DBLCLICK) { + if (p == selected_channel) { + set_current_channel(selected_channel); + order = song_get_current_order(); + + if (song_get_mode() == MODE_PLAYING) { + n = current_song->orderlist[order]; + } else { + n = song_get_playing_pattern(); + } + if (n < 200) { + set_current_order(order); + set_current_pattern(n); + set_current_row(song_get_current_row()); + set_page(PAGE_PATTERN_EDITOR); + } + } + } + return n; + } + + /* hack to render this useful :) */ + if (k->orig_sym == SDLK_KP9) { + k->sym = SDLK_F9; + } else if (k->orig_sym == SDLK_KP0) { + k->sym = SDLK_F10; + } + + switch (k->sym) { + case SDLK_g: + if (k->state == KEY_PRESS) + return 1; + + set_current_channel(selected_channel); + order = song_get_current_order(); + + if (song_get_mode() == MODE_PLAYING) { + n = current_song->orderlist[order]; + } else { + n = song_get_playing_pattern(); + } + if (n < 200) { + set_current_order(order); + set_current_pattern(n); + set_current_row(song_get_current_row()); + set_page(PAGE_PATTERN_EDITOR); + } + return 1; + case SDLK_v: + if (k->state == KEY_RELEASE) + return 1; + + velocity_mode = !velocity_mode; + status_text_flash("Using %s bars", (velocity_mode ? "velocity" : "volume")); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_i: + if (k->state == KEY_RELEASE) + return 1; + + instrument_names = !instrument_names; + status_text_flash("Using %s names", (instrument_names ? "instrument" : "sample")); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_r: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + + song_flip_stereo(); + status_text_flash("Left/right outputs reversed"); + return 1; + } + return 0; + case SDLK_PLUS: + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() + 1); + } + return 1; + case SDLK_MINUS: + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() - 1); + } + return 1; + case SDLK_q: + if (k->state == KEY_RELEASE) + return 1; + song_toggle_channel_mute(selected_channel - 1); + orderpan_recheck_muted_channels(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_s: + if (k->state == KEY_RELEASE) + return 1; + + if (k->mod & KMOD_ALT) { + song_toggle_stereo(); + status_text_flash("Stereo %s", song_is_stereo() + ? "Enabled" : "Disabled"); + } else { + song_handle_channel_solo(selected_channel - 1); + orderpan_recheck_muted_channels(); + } + status.flags |= NEED_UPDATE; + return 1; + case SDLK_SPACE: + if (!NO_MODIFIER(k->mod)) + return 0; + + if (k->state == KEY_RELEASE) + return 1; + song_toggle_channel_mute(selected_channel - 1); + if (selected_channel < 64) + selected_channel++; + orderpan_recheck_muted_channels(); + break; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + /* make the current window one line shorter, and give the line to the next window + below it. if the window is already as small as it can get (3 lines) or if it's + the last window, don't do anything. */ + if (selected_window == num_windows - 1 || windows[selected_window].height == 3) { + return 1; + } + windows[selected_window].height--; + windows[selected_window + 1].height++; + break; + } + if (selected_channel > 1) + selected_channel--; + break; + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod) && !(k->mod & KMOD_ALT)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (selected_channel > 1) + selected_channel--; + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + /* expand the current window, taking a line from + * the next window down. BUT: don't do anything if + * (a) this is the last window, or (b) the next + * window is already as small as it can be (three + * lines). */ + if (selected_window == num_windows - 1 + || windows[selected_window + 1].height == 3) { + return 1; + } + windows[selected_window].height++; + windows[selected_window + 1].height--; + break; + } + if (selected_channel < 64) + selected_channel++; + break; + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod) && !(k->mod & KMOD_ALT)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (selected_channel < 64) + selected_channel++; + break; + case SDLK_HOME: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + selected_channel = 1; + break; + case SDLK_END: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + selected_channel = song_find_last_channel(); + break; + case SDLK_INSERT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + /* add a new window, unless there's already five (the maximum) + or if the current window isn't big enough to split in half. */ + if (num_windows == MAX_WINDOWS || (windows[selected_window].height < 6)) { + return 1; + } + + num_windows++; + + /* shift the windows under the current one down */ + memmove(windows + selected_window + 1, windows + selected_window, + ((num_windows - selected_window - 1) * sizeof(*windows))); + + /* split the height between the two windows */ + n = windows[selected_window].height; + windows[selected_window].height = n / 2; + windows[selected_window + 1].height = n / 2; + if ((n & 1) && num_windows != 2) { + /* odd number? compensate. (the selected window gets the extra line) */ + windows[selected_window + 1].height++; + } + break; + case SDLK_DELETE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + /* delete the current window and give the extra space to the next window down. + if this is the only window, well then don't delete it ;) */ + if (num_windows == 1) + return 1; + + n = windows[selected_window].height + windows[selected_window + 1].height; + + /* shift the windows under the current one up */ + memmove(windows + selected_window, windows + selected_window + 1, + ((num_windows - selected_window - 1) * sizeof(*windows))); + + /* fix the current window's height */ + windows[selected_window].height = n; + + num_windows--; + if (selected_window == num_windows) + selected_window--; + break; + case SDLK_PAGEUP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + n = windows[selected_window].type; + if (n == 0) + n = NUM_WINDOW_TYPES; + n--; + windows[selected_window].type = n; + break; + case SDLK_PAGEDOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + windows[selected_window].type = (windows[selected_window].type + 1) % NUM_WINDOW_TYPES; + break; + case SDLK_TAB: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) { + if (selected_window == 0) + selected_window = num_windows; + selected_window--; + } else { + selected_window = (selected_window + 1) % num_windows; + } + status.flags |= NEED_UPDATE; + return 1; + case SDLK_F9: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_ALT) { + song_toggle_channel_mute(selected_channel - 1); + orderpan_recheck_muted_channels(); + return 1; + } + return 0; + case SDLK_F10: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + song_handle_channel_solo(selected_channel - 1); + orderpan_recheck_muted_channels(); + return 1; + } + return 0; + default: + return 0; + } + + recalculate_windows(); + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------- */ static void info_page_playback_update(void) { - if (song_get_mode() != MODE_STOPPED) - status.flags |= NEED_UPDATE; + if (song_get_mode() != MODE_STOPPED) + status.flags |= NEED_UPDATE; } void info_load_page(struct page *page) { - page->title = "Info Page (F5)"; - page->playback_update = info_page_playback_update; - page->total_widgets = 1; - page->widgets = widgets_info; - page->help_index = HELP_INFO_PAGE; + page->title = "Info Page (F5)"; + page->playback_update = info_page_playback_update; + page->total_widgets = 1; + page->widgets = widgets_info; + page->help_index = HELP_INFO_PAGE; - create_other(widgets_info + 0, 0, info_page_handle_key, info_page_redraw); + create_other(widgets_info + 0, 0, info_page_handle_key, info_page_redraw); } diff -Nru schism-0+20110101/schism/page_instruments.c schism-20160521/schism/page_instruments.c --- schism-0+20110101/schism/page_instruments.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_instruments.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -47,8 +47,8 @@ /* rastops for envelope */ static struct vgamem_overlay env_overlay = { - 32, 18, 65, 25, - NULL, 0, 0, 0 + 32, 18, 65, 25, + NULL, 0, 0, 0 }; /* toggled when pressing "," on the note table's sample field @@ -58,17 +58,17 @@ static struct widget *get_page_widgets(void) { - switch (instrument_list_subpage) { - case PAGE_INSTRUMENT_LIST_GENERAL: - return widgets_general; - case PAGE_INSTRUMENT_LIST_VOLUME: - return widgets_volume; - case PAGE_INSTRUMENT_LIST_PANNING: - return widgets_panning; - case PAGE_INSTRUMENT_LIST_PITCH: - return widgets_pitch; - }; - return widgets_general; + switch (instrument_list_subpage) { + case PAGE_INSTRUMENT_LIST_GENERAL: + return widgets_general; + case PAGE_INSTRUMENT_LIST_VOLUME: + return widgets_volume; + case PAGE_INSTRUMENT_LIST_PANNING: + return widgets_panning; + case PAGE_INSTRUMENT_LIST_PITCH: + return widgets_pitch; + }; + return widgets_general; } static const int subpage_switches_group[5] = { 1, 2, 3, 4, -1 }; @@ -113,75 +113,75 @@ static void save_envelope(int slot, song_envelope_t *e, unsigned int sec) { - song_instrument_t *ins; + song_instrument_t *ins; - slot = ((unsigned)slot)%10; + slot = ((unsigned)slot)%10; - ins = song_get_instrument(current_instrument); - memcpy(&saved_env[slot], e, sizeof(song_envelope_t)); + ins = song_get_instrument(current_instrument); + memcpy(&saved_env[slot], e, sizeof(song_envelope_t)); - switch (sec) { - case ENV_VOLUME: - flags[slot] = ins->flags & (ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY); - break; - case ENV_PANNING: - flags[slot] = - ((ins->flags & ENV_PANNING) ? ENV_VOLUME : 0) - | ((ins->flags & ENV_PANSUSTAIN) ? ENV_VOLSUSTAIN : 0) - | ((ins->flags & ENV_PANLOOP) ? ENV_VOLLOOP : 0) - | ((ins->flags & ENV_PANCARRY) ? ENV_VOLCARRY : 0) - | (ins->flags & ENV_SETPANNING); - break; - case ENV_PITCH: - flags[slot] = - ((ins->flags & ENV_PITCH) ? ENV_VOLUME : 0) - | ((ins->flags & ENV_PITCHSUSTAIN) ? ENV_VOLSUSTAIN : 0) - | ((ins->flags & ENV_PITCHLOOP) ? ENV_VOLLOOP : 0) - | ((ins->flags & ENV_PITCHCARRY) ? ENV_VOLCARRY : 0) - | (ins->flags & ENV_FILTER); - break; - }; + switch (sec) { + case ENV_VOLUME: + flags[slot] = ins->flags & (ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY); + break; + case ENV_PANNING: + flags[slot] = + ((ins->flags & ENV_PANNING) ? ENV_VOLUME : 0) + | ((ins->flags & ENV_PANSUSTAIN) ? ENV_VOLSUSTAIN : 0) + | ((ins->flags & ENV_PANLOOP) ? ENV_VOLLOOP : 0) + | ((ins->flags & ENV_PANCARRY) ? ENV_VOLCARRY : 0) + | (ins->flags & ENV_SETPANNING); + break; + case ENV_PITCH: + flags[slot] = + ((ins->flags & ENV_PITCH) ? ENV_VOLUME : 0) + | ((ins->flags & ENV_PITCHSUSTAIN) ? ENV_VOLSUSTAIN : 0) + | ((ins->flags & ENV_PITCHLOOP) ? ENV_VOLLOOP : 0) + | ((ins->flags & ENV_PITCHCARRY) ? ENV_VOLCARRY : 0) + | (ins->flags & ENV_FILTER); + break; + }; } static void restore_envelope(int slot, song_envelope_t *e, unsigned int sec) { - song_instrument_t *ins; + song_instrument_t *ins; - song_lock_audio(); + song_lock_audio(); - slot = ((unsigned)slot)%10; + slot = ((unsigned)slot)%10; - ins = song_get_instrument(current_instrument); - memcpy(e, &saved_env[slot], sizeof(song_envelope_t)); + ins = song_get_instrument(current_instrument); + memcpy(e, &saved_env[slot], sizeof(song_envelope_t)); - switch (sec) { - case ENV_VOLUME: - ins->flags &= ~(ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY); - ins->flags |= (flags[slot] & (ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY)); - break; - - case ENV_PANNING: - ins->flags &= ~(ENV_PANNING|ENV_PANSUSTAIN|ENV_PANLOOP|ENV_PANCARRY|ENV_SETPANNING); - if (flags[slot] & ENV_VOLUME) ins->flags |= ENV_PANNING; - if (flags[slot] & ENV_VOLSUSTAIN) ins->flags |= ENV_PANSUSTAIN; - if (flags[slot] & ENV_VOLLOOP) ins->flags |= ENV_PANLOOP; - if (flags[slot] & ENV_VOLCARRY) ins->flags |= ENV_PANCARRY; - ins->flags |= (flags[slot] & ENV_SETPANNING); - break; - - case ENV_PITCH: - ins->flags &= ~(ENV_PITCH|ENV_PITCHSUSTAIN|ENV_PITCHLOOP|ENV_PITCHCARRY|ENV_FILTER); - if (flags[slot] & ENV_VOLUME) ins->flags |= ENV_PITCH; - if (flags[slot] & ENV_VOLSUSTAIN) ins->flags |= ENV_PITCHSUSTAIN; - if (flags[slot] & ENV_VOLLOOP) ins->flags |= ENV_PITCHLOOP; - if (flags[slot] & ENV_VOLCARRY) ins->flags |= ENV_PITCHCARRY; - ins->flags |= (flags[slot] & ENV_FILTER); - break; + switch (sec) { + case ENV_VOLUME: + ins->flags &= ~(ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY); + ins->flags |= (flags[slot] & (ENV_VOLUME|ENV_VOLSUSTAIN|ENV_VOLLOOP|ENV_VOLCARRY)); + break; + + case ENV_PANNING: + ins->flags &= ~(ENV_PANNING|ENV_PANSUSTAIN|ENV_PANLOOP|ENV_PANCARRY|ENV_SETPANNING); + if (flags[slot] & ENV_VOLUME) ins->flags |= ENV_PANNING; + if (flags[slot] & ENV_VOLSUSTAIN) ins->flags |= ENV_PANSUSTAIN; + if (flags[slot] & ENV_VOLLOOP) ins->flags |= ENV_PANLOOP; + if (flags[slot] & ENV_VOLCARRY) ins->flags |= ENV_PANCARRY; + ins->flags |= (flags[slot] & ENV_SETPANNING); + break; + + case ENV_PITCH: + ins->flags &= ~(ENV_PITCH|ENV_PITCHSUSTAIN|ENV_PITCHLOOP|ENV_PITCHCARRY|ENV_FILTER); + if (flags[slot] & ENV_VOLUME) ins->flags |= ENV_PITCH; + if (flags[slot] & ENV_VOLSUSTAIN) ins->flags |= ENV_PITCHSUSTAIN; + if (flags[slot] & ENV_VOLLOOP) ins->flags |= ENV_PITCHLOOP; + if (flags[slot] & ENV_VOLCARRY) ins->flags |= ENV_PITCHCARRY; + ins->flags |= (flags[slot] & ENV_FILTER); + break; - }; + }; - song_unlock_audio(); + song_unlock_audio(); - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } @@ -193,436 +193,450 @@ /* --------------------------------------------------------------------------------------------------------- */ static int _last_vis_inst(void) { - int i, j, n; + int i, j, n; - n = 99; - j = 0; - /* 65 is first visible sample on last page */ - for (i = 65; i < MAX_INSTRUMENTS; i++) { - if (!csf_instrument_is_empty(current_song->instruments[i])) { - j = i; - } - } - while ((j + 34) > n) - n += 34; - return MIN(n, MAX_INSTRUMENTS - 1); + n = 99; + j = 0; + /* 65 is first visible sample on last page */ + for (i = 65; i < MAX_INSTRUMENTS; i++) { + if (!csf_instrument_is_empty(current_song->instruments[i])) { + j = i; + } + } + while ((j + 34) > n) + n += 34; + return MIN(n, MAX_INSTRUMENTS - 1); } /* the actual list */ static void instrument_list_reposition(void) { - if (current_instrument < top_instrument) { - top_instrument = current_instrument; - if (top_instrument < 1) { - top_instrument = 1; - } - } else if (current_instrument > top_instrument + 34) { - top_instrument = current_instrument - 34; - } + if (current_instrument < top_instrument) { + top_instrument = current_instrument; + if (top_instrument < 1) { + top_instrument = 1; + } + } else if (current_instrument > top_instrument + 34) { + top_instrument = current_instrument - 34; + } } int instrument_get_current(void) { - return current_instrument; + return current_instrument; } void instrument_set(int n) { - int new_ins = n; - song_instrument_t *ins; + int new_ins = n; + song_instrument_t *ins; - if (page_is_instrument_list(status.current_page)) { - new_ins = CLAMP(n, 1, _last_vis_inst()); - } else { - new_ins = CLAMP(n, 0, _last_vis_inst()); - } + if (page_is_instrument_list(status.current_page)) { + new_ins = CLAMP(n, 1, _last_vis_inst()); + } else { + new_ins = CLAMP(n, 0, _last_vis_inst()); + } - if (current_instrument == new_ins) - return; + if (current_instrument == new_ins) + return; - envelope_edit_mode = 0; - current_instrument = new_ins; - instrument_list_reposition(); + envelope_edit_mode = 0; + current_instrument = new_ins; + instrument_list_reposition(); - ins = song_get_instrument(current_instrument); + ins = song_get_instrument(current_instrument); - current_node_vol = ins->vol_env.nodes ? CLAMP(current_node_vol, 0, ins->vol_env.nodes - 1) : 0; - current_node_pan = ins->pan_env.nodes ? CLAMP(current_node_vol, 0, ins->pan_env.nodes - 1) : 0; - current_node_pitch = ins->pitch_env.nodes ? CLAMP(current_node_vol, 0, ins->pan_env.nodes - 1) : 0; + current_node_vol = ins->vol_env.nodes ? CLAMP(current_node_vol, 0, ins->vol_env.nodes - 1) : 0; + current_node_pan = ins->pan_env.nodes ? CLAMP(current_node_vol, 0, ins->pan_env.nodes - 1) : 0; + current_node_pitch = ins->pitch_env.nodes ? CLAMP(current_node_vol, 0, ins->pan_env.nodes - 1) : 0; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } void instrument_synchronize_to_sample(void) { - song_instrument_t *ins; - int sample = sample_get_current(); - int n, pos; - - /* 1. if the instrument with the same number as the current sample - * has the sample in its sample_map, change to that instrument. */ - ins = song_get_instrument(sample); - for (pos = 0; pos < 120; pos++) { - if ((int)(ins->sample_map[pos]) == sample) { - instrument_set(sample); - return; - } - } - - /* 2. look through the instrument list for the first instrument - * that uses the selected sample. */ - for (n = 1; n < 100; n++) { - if (n == sample) - continue; - ins = song_get_instrument(n); - for (pos = 0; pos < 120; pos++) { - if ((int)(ins->sample_map[pos]) == sample) { - instrument_set(n); - return; - } - } - } - - /* 3. if no instruments are using the sample, just change to the - * same-numbered instrument. */ - instrument_set(sample); + song_instrument_t *ins; + int sample = sample_get_current(); + int n, pos; + + /* 1. if the instrument with the same number as the current sample + * has the sample in its sample_map, change to that instrument. */ + ins = song_get_instrument(sample); + for (pos = 0; pos < 120; pos++) { + if ((int)(ins->sample_map[pos]) == sample) { + instrument_set(sample); + return; + } + } + + /* 2. look through the instrument list for the first instrument + * that uses the selected sample. */ + for (n = 1; n < 100; n++) { + if (n == sample) + continue; + ins = song_get_instrument(n); + for (pos = 0; pos < 120; pos++) { + if ((int)(ins->sample_map[pos]) == sample) { + instrument_set(n); + return; + } + } + } + + /* 3. if no instruments are using the sample, just change to the + * same-numbered instrument. */ + instrument_set(sample); } /* --------------------------------------------------------------------- */ static int instrument_list_add_char(int c) { - song_instrument_t *ins; + song_instrument_t *ins; - if (c < 32) - return 0; - ins = song_get_instrument(current_instrument); - text_add_char(ins->name, c, &instrument_cursor_pos, 25); - if (instrument_cursor_pos == 25) - instrument_cursor_pos--; - - get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; - return 1; + if (c < 32) + return 0; + ins = song_get_instrument(current_instrument); + text_add_char(ins->name, c, &instrument_cursor_pos, 25); + if (instrument_cursor_pos == 25) + instrument_cursor_pos--; + + get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; + return 1; } static void instrument_list_delete_char(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); - text_delete_char(ins->name, &instrument_cursor_pos, 25); + song_instrument_t *ins = song_get_instrument(current_instrument); + text_delete_char(ins->name, &instrument_cursor_pos, 25); - get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; + get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; } static void instrument_list_delete_next_char(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); - text_delete_next_char(ins->name, &instrument_cursor_pos, 25); + song_instrument_t *ins = song_get_instrument(current_instrument); + text_delete_next_char(ins->name, &instrument_cursor_pos, 25); - get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; + get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; } static void clear_instrument_text(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - memset(ins->filename, 0, 14); - memset(ins->name, 0, 26); - if (instrument_cursor_pos != 25) - instrument_cursor_pos = 0; - - get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; + memset(ins->filename, 0, 14); + memset(ins->name, 0, 26); + if (instrument_cursor_pos != 25) + instrument_cursor_pos = 0; + + get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static void do_swap_instrument(int n) { - if (n >= 1 && n <= _last_vis_inst()) { - song_swap_instruments(current_instrument, n); - } + if (n >= 1 && n <= _last_vis_inst()) { + song_swap_instruments(current_instrument, n); + } } static void do_exchange_instrument(int n) { - if (n >= 1 && n <= _last_vis_inst()) { - song_exchange_instruments(current_instrument, n); - } + if (n >= 1 && n <= _last_vis_inst()) { + song_exchange_instruments(current_instrument, n); + } } static void do_copy_instrument(int n) { - if (n >= 1 && n <= _last_vis_inst()) { - song_copy_instrument(current_instrument, n); - } + if (n >= 1 && n <= _last_vis_inst()) { + song_copy_instrument(current_instrument, n); + } } static void do_replace_instrument(int n) { - if (n >= 1 && n <= _last_vis_inst()) { - song_replace_instrument(current_instrument, n); - } + if (n >= 1 && n <= _last_vis_inst()) { + song_replace_instrument(current_instrument, n); + } } /* --------------------------------------------------------------------- */ static void instrument_list_draw_list(void) { - int pos, n; - song_instrument_t *ins; - int selected = (ACTIVE_PAGE.selected_widget == 0); - int is_current; - int ss, cl = 0, cr = 0; - int is_playing[MAX_INSTRUMENTS]; - char buf[4]; - - ss = -1; - - song_get_playing_instruments(is_playing); - - for (pos = 0, n = top_instrument; pos < 35; pos++, n++) { - ins = song_get_instrument(n); - is_current = (n == current_instrument); - - if (ins->played) - draw_char(is_playing[n] > 1 ? 183 : 173, 1, 13 + pos, is_playing[n] ? 3 : 1, 2); - - draw_text(num99tostr(n, buf), 2, 13 + pos, 0, 2); - if (instrument_cursor_pos < 25) { - /* it's in edit mode */ - if (is_current) { - draw_text_len(ins->name, 25, 5, 13 + pos, 6, 14); - if (selected) { - draw_char(ins->name[instrument_cursor_pos], - 5 + instrument_cursor_pos, - 13 + pos, 0, 3); - } - } else { - draw_text_len(ins->name, 25, 5, 13 + pos, 6, 0); - } - } else { - draw_text_len(ins->name, 25, 5, 13 + pos, - ((is_current && selected) ? 0 : 6), - (is_current ? (selected ? 3 : 14) : 0)); - } - if (ss == n) { - draw_text_len(ins->name + cl, (cr-cl)+1, - 5 + cl, 13 + pos, - (is_current ? 3 : 11), 8); - } - } + int pos, n; + song_instrument_t *ins; + int selected = (ACTIVE_PAGE.selected_widget == 0); + int is_current; + int ss, cl = 0, cr = 0; + int is_playing[MAX_INSTRUMENTS]; + char buf[4]; + + ss = -1; + + song_get_playing_instruments(is_playing); + + for (pos = 0, n = top_instrument; pos < 35; pos++, n++) { + ins = song_get_instrument(n); + is_current = (n == current_instrument); + + if (ins->played) + draw_char(is_playing[n] > 1 ? 183 : 173, 1, 13 + pos, is_playing[n] ? 3 : 1, 2); + + draw_text(num99tostr(n, buf), 2, 13 + pos, 0, 2); + if (instrument_cursor_pos < 25) { + /* it's in edit mode */ + if (is_current) { + draw_text_len(ins->name, 25, 5, 13 + pos, 6, 14); + if (selected) { + draw_char(ins->name[instrument_cursor_pos], + 5 + instrument_cursor_pos, + 13 + pos, 0, 3); + } + } else { + draw_text_len(ins->name, 25, 5, 13 + pos, 6, 0); + } + } else { + draw_text_len(ins->name, 25, 5, 13 + pos, + ((is_current && selected) ? 0 : 6), + (is_current ? (selected ? 3 : 14) : 0)); + } + if (ss == n) { + draw_text_len(ins->name + cl, (cr-cl)+1, + 5 + cl, 13 + pos, + (is_current ? 3 : 11), 8); + } + } } static int instrument_list_handle_key_on_list(struct key_event * k) { - int new_ins = current_instrument; + int new_ins = current_instrument; - if (!k->state && k->mouse && k->y >= 13 && k->y <= 47 && k->x >= 5 && k->x <= 30) { - if (k->mouse == MOUSE_CLICK) { - new_ins = (k->y - 13) + top_instrument; - if (instrument_cursor_pos < 25) - instrument_cursor_pos = MIN(k->x - 5, 24); - status.flags |= NEED_UPDATE; - } else if (k->mouse == MOUSE_DBLCLICK) { - /* this doesn't seem to work, but I think it'd be - more useful if double click switched to edit mode */ - if (instrument_cursor_pos < 25) { - instrument_cursor_pos = 25; - get_page_widgets()->accept_text = 0; - } else { - set_page(PAGE_LOAD_INSTRUMENT); - } - status.flags |= NEED_UPDATE; - return 1; - - } else if (k->mouse == MOUSE_SCROLL_UP) { - top_instrument -= MOUSE_SCROLL_LINES; - if (top_instrument < 1) top_instrument = 1; - status.flags |= NEED_UPDATE; - return 1; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - top_instrument += MOUSE_SCROLL_LINES; - if (top_instrument > (_last_vis_inst()-34)) top_instrument = _last_vis_inst()-34; - status.flags |= NEED_UPDATE; - return 1; - } - } else { - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - if (current_instrument > 1) { - new_ins = current_instrument - 1; - song_swap_instruments(current_instrument, new_ins); - } - } else if (!NO_MODIFIER(k->mod)) { - return 0; - } else { - new_ins--; - } - break; - case SDLK_DOWN: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - // restrict position to the "old" value of _last_vis_inst() - // (this is entirely for aesthetic reasons) - if (status.last_keysym != SDLK_DOWN && !k->is_repeat) - _altswap_lastvis = _last_vis_inst(); - if (current_instrument < _altswap_lastvis) { - new_ins = current_instrument + 1; - song_swap_instruments(current_instrument, new_ins); - } - } else if (!NO_MODIFIER(k->mod)) { - return 0; - } else { - new_ins++; - } - break; - case SDLK_PAGEUP: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) - new_ins = 1; - else - new_ins -= 16; - break; - case SDLK_PAGEDOWN: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) - new_ins = _last_vis_inst(); - else - new_ins += 16; - break; - case SDLK_HOME: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - if (instrument_cursor_pos < 25) { - instrument_cursor_pos = 0; - get_page_widgets()->accept_text = 1; - status.flags |= NEED_UPDATE; - } - return 1; - case SDLK_END: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - if (instrument_cursor_pos < 24) { - instrument_cursor_pos = 24; - get_page_widgets()->accept_text = 1; - status.flags |= NEED_UPDATE; - } - return 1; - case SDLK_LEFT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - if (instrument_cursor_pos < 25 && instrument_cursor_pos > 0) { - instrument_cursor_pos--; - get_page_widgets()->accept_text = 1; - status.flags |= NEED_UPDATE; - } - return 1; - case SDLK_RIGHT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - if (instrument_cursor_pos == 25) { - get_page_widgets()->accept_text = 0; - change_focus_to(1); - } else if (instrument_cursor_pos < 24) { - get_page_widgets()->accept_text = 1; - instrument_cursor_pos++; - status.flags |= NEED_UPDATE; - } - return 1; - case SDLK_RETURN: - if (!k->state) return 0; - if (instrument_cursor_pos < 25) { - instrument_cursor_pos = 25; - get_page_widgets()->accept_text = 0; - status.flags |= NEED_UPDATE; - } else { - get_page_widgets()->accept_text = 1; - set_page(PAGE_LOAD_INSTRUMENT); - } - return 1; - case SDLK_ESCAPE: - if ((k->mod & KMOD_SHIFT) || instrument_cursor_pos < 25) { - if (k->state) return 1; - instrument_cursor_pos = 25; - get_page_widgets()->accept_text = 0; - status.flags |= NEED_UPDATE; - return 1; - } - return 0; - case SDLK_BACKSPACE: - if (k->state) return 0; - if (instrument_cursor_pos == 25) - return 0; - if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) - instrument_list_delete_char(); - else if (k->mod & KMOD_CTRL) - instrument_list_add_char(127); - return 1; - case SDLK_INSERT: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - song_insert_instrument_slot(current_instrument); - status.flags |= NEED_UPDATE; - return 1; - } - return 0; - case SDLK_DELETE: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - song_remove_instrument_slot(current_instrument); - status.flags |= NEED_UPDATE; - return 1; - } else if ((k->mod & KMOD_CTRL) == 0) { - if (instrument_cursor_pos == 25) - return 0; - instrument_list_delete_next_char(); - return 1; - } - return 0; - default: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - if (k->sym == SDLK_c) { - clear_instrument_text(); - return 1; - } - } else if ((k->mod & KMOD_CTRL) == 0) { - if (!k->unicode) return 0; - if (instrument_cursor_pos < 25) { - return instrument_list_add_char(k->unicode); - } else if (k->sym == SDLK_SPACE) { - instrument_cursor_pos = 0; - get_page_widgets()->accept_text = 0; - status.flags |= NEED_UPDATE; - memused_songchanged(); - return 1; - } - } - return 0; - }; - } - - new_ins = CLAMP(new_ins, 1, _last_vis_inst()); - if (new_ins != current_instrument) { - instrument_set(new_ins); - status.flags |= NEED_UPDATE; - memused_songchanged(); - } + if (k->state == KEY_PRESS && k->mouse != MOUSE_NONE && k->y >= 13 && k->y <= 47 && k->x >= 5 && k->x <= 30) { + if (k->mouse == MOUSE_CLICK) { + new_ins = (k->y - 13) + top_instrument; + if (instrument_cursor_pos < 25) + instrument_cursor_pos = MIN(k->x - 5, 24); + status.flags |= NEED_UPDATE; + } else if (k->mouse == MOUSE_DBLCLICK) { + /* this doesn't seem to work, but I think it'd be + more useful if double click switched to edit mode */ + if (instrument_cursor_pos < 25) { + instrument_cursor_pos = 25; + get_page_widgets()->accept_text = 0; + } else { + set_page(PAGE_LOAD_INSTRUMENT); + } + status.flags |= NEED_UPDATE; + return 1; + + } else if (k->mouse == MOUSE_SCROLL_UP) { + top_instrument -= MOUSE_SCROLL_LINES; + if (top_instrument < 1) top_instrument = 1; + status.flags |= NEED_UPDATE; + return 1; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + top_instrument += MOUSE_SCROLL_LINES; + if (top_instrument > (_last_vis_inst()-34)) top_instrument = _last_vis_inst()-34; + status.flags |= NEED_UPDATE; + return 1; + } + } else { + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + if (current_instrument > 1) { + new_ins = current_instrument - 1; + song_swap_instruments(current_instrument, new_ins); + } + } else if (!NO_MODIFIER(k->mod)) { + return 0; + } else { + new_ins--; + } + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + // restrict position to the "old" value of _last_vis_inst() + // (this is entirely for aesthetic reasons) + if (status.last_keysym != SDLK_DOWN && !k->is_repeat) + _altswap_lastvis = _last_vis_inst(); + if (current_instrument < _altswap_lastvis) { + new_ins = current_instrument + 1; + song_swap_instruments(current_instrument, new_ins); + } + } else if (!NO_MODIFIER(k->mod)) { + return 0; + } else { + new_ins++; + } + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) + new_ins = 1; + else + new_ins -= 16; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) + new_ins = _last_vis_inst(); + else + new_ins += 16; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + if (instrument_cursor_pos < 25) { + instrument_cursor_pos = 0; + get_page_widgets()->accept_text = 1; + status.flags |= NEED_UPDATE; + } + return 1; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + if (instrument_cursor_pos < 24) { + instrument_cursor_pos = 24; + get_page_widgets()->accept_text = 1; + status.flags |= NEED_UPDATE; + } + return 1; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + if (instrument_cursor_pos < 25 && instrument_cursor_pos > 0) { + instrument_cursor_pos--; + get_page_widgets()->accept_text = 1; + status.flags |= NEED_UPDATE; + } + return 1; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + if (instrument_cursor_pos == 25) { + get_page_widgets()->accept_text = 0; + change_focus_to(1); + } else if (instrument_cursor_pos < 24) { + get_page_widgets()->accept_text = 1; + instrument_cursor_pos++; + status.flags |= NEED_UPDATE; + } + return 1; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + if (instrument_cursor_pos < 25) { + instrument_cursor_pos = 25; + get_page_widgets()->accept_text = 0; + status.flags |= NEED_UPDATE; + } else { + get_page_widgets()->accept_text = 1; + set_page(PAGE_LOAD_INSTRUMENT); + } + return 1; + case SDLK_ESCAPE: + if ((k->mod & KMOD_SHIFT) || instrument_cursor_pos < 25) { + if (k->state == KEY_RELEASE) + return 1; + instrument_cursor_pos = 25; + get_page_widgets()->accept_text = 0; + status.flags |= NEED_UPDATE; + return 1; + } + return 0; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 0; + if (instrument_cursor_pos == 25) + return 0; + if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) + instrument_list_delete_char(); + else if (k->mod & KMOD_CTRL) + instrument_list_add_char(127); + return 1; + case SDLK_INSERT: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + song_insert_instrument_slot(current_instrument); + status.flags |= NEED_UPDATE; + return 1; + } + return 0; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + song_remove_instrument_slot(current_instrument); + status.flags |= NEED_UPDATE; + return 1; + } else if ((k->mod & KMOD_CTRL) == 0) { + if (instrument_cursor_pos == 25) + return 0; + instrument_list_delete_next_char(); + return 1; + } + return 0; + default: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + if (k->sym == SDLK_c) { + clear_instrument_text(); + return 1; + } + } else if ((k->mod & KMOD_CTRL) == 0) { + if (!k->unicode) return 0; + if (instrument_cursor_pos < 25) { + return instrument_list_add_char(k->unicode); + } else if (k->sym == SDLK_SPACE) { + instrument_cursor_pos = 0; + get_page_widgets()->accept_text = 0; + status.flags |= NEED_UPDATE; + memused_songchanged(); + return 1; + } + } + return 0; + }; + } + + new_ins = CLAMP(new_ins, 1, _last_vis_inst()); + if (new_ins != current_instrument) { + instrument_set(new_ins); + status.flags |= NEED_UPDATE; + memused_songchanged(); + } - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -630,350 +644,367 @@ static void note_trans_reposition(void) { - if (note_trans_sel_line < note_trans_top_line) { - note_trans_top_line = note_trans_sel_line; - } else if (note_trans_sel_line > note_trans_top_line + 31) { - note_trans_top_line = note_trans_sel_line - 31; - } + if (note_trans_sel_line < note_trans_top_line) { + note_trans_top_line = note_trans_sel_line; + } else if (note_trans_sel_line > note_trans_top_line + 31) { + note_trans_top_line = note_trans_sel_line - 31; + } } static void note_trans_draw(void) { - int pos, n; - int is_selected = (ACTIVE_PAGE.selected_widget == 5); - int bg, sel_bg = (is_selected ? 14 : 0); - song_instrument_t *ins = song_get_instrument(current_instrument); - char buf[4]; - - for (pos = 0, n = note_trans_top_line; pos < 32; pos++, n++) { - bg = ((n == note_trans_sel_line) ? sel_bg : 0); - - /* invalid notes are translated to themselves (and yes, this edits the actual instrument) */ - if (ins->note_map[n] < 1 || ins->note_map[n] > 120) - ins->note_map[n] = n + 1; - - draw_text(get_note_string(n + 1, buf), 32, 16 + pos, 2, bg); - draw_char(168, 35, 16 + pos, 2, bg); - draw_text(get_note_string(ins->note_map[n], buf), 36, 16 + pos, 2, bg); - if (is_selected && n == note_trans_sel_line) { - if (note_trans_cursor_pos == 0) - draw_char(buf[0], 36, 16 + pos, 0, 3); - else if (note_trans_cursor_pos == 1) - draw_char(buf[2], 38, 16 + pos, 0, 3); - } - draw_char(0, 39, 16 + pos, 2, bg); - if (ins->sample_map[n]) { - num99tostr(ins->sample_map[n], buf); - } else { - buf[0] = buf[1] = 173; - buf[2] = 0; - } - draw_text(buf, 40, 16 + pos, 2, bg); - if (is_selected && n == note_trans_sel_line) { - if (note_trans_cursor_pos == 2) - draw_char(buf[0], 40, 16 + pos, 0, 3); - else if (note_trans_cursor_pos == 3) - draw_char(buf[1], 41, 16 + pos, 0, 3); - } - } - - /* draw the little mask thingy at the bottom. Could optimize this.... -delt. - Sure can! This could share the same track-view functions that the - pattern editor ought to be using. -Storlek */ - if (is_selected && !(status.flags & CLASSIC_MODE)) { - switch (note_trans_cursor_pos) { - case 0: - draw_char(171, 36, 48, 3, 2); - draw_char(171, 37, 48, 3, 2); - draw_char(169, 38, 48, 3, 2); - if (note_sample_mask) { - draw_char(169, 40, 48, 3, 2); - draw_char(169, 41, 48, 3, 2); - } - break; - case 1: - draw_char(169, 38, 48, 3, 2); - if (note_sample_mask) { - draw_char(170, 40, 48, 3, 2); - draw_char(170, 41, 48, 3, 2); - } - break; - case 2: - case 3: - draw_char(note_sample_mask ? 171 : 169, 40, 48, 3, 2); - draw_char(note_sample_mask ? 171 : 169, 41, 48, 3, 2); - break; - }; - } + int pos, n; + int is_selected = (ACTIVE_PAGE.selected_widget == 5); + int bg, sel_bg = (is_selected ? 14 : 0); + song_instrument_t *ins = song_get_instrument(current_instrument); + char buf[4]; + + for (pos = 0, n = note_trans_top_line; pos < 32; pos++, n++) { + bg = ((n == note_trans_sel_line) ? sel_bg : 0); + + /* invalid notes are translated to themselves (and yes, this edits the actual instrument) */ + if (ins->note_map[n] < 1 || ins->note_map[n] > 120) + ins->note_map[n] = n + 1; + + draw_text(get_note_string(n + 1, buf), 32, 16 + pos, 2, bg); + draw_char(168, 35, 16 + pos, 2, bg); + draw_text(get_note_string(ins->note_map[n], buf), 36, 16 + pos, 2, bg); + if (is_selected && n == note_trans_sel_line) { + if (note_trans_cursor_pos == 0) + draw_char(buf[0], 36, 16 + pos, 0, 3); + else if (note_trans_cursor_pos == 1) + draw_char(buf[2], 38, 16 + pos, 0, 3); + } + draw_char(0, 39, 16 + pos, 2, bg); + if (ins->sample_map[n]) { + num99tostr(ins->sample_map[n], buf); + } else { + buf[0] = buf[1] = 173; + buf[2] = 0; + } + draw_text(buf, 40, 16 + pos, 2, bg); + if (is_selected && n == note_trans_sel_line) { + if (note_trans_cursor_pos == 2) + draw_char(buf[0], 40, 16 + pos, 0, 3); + else if (note_trans_cursor_pos == 3) + draw_char(buf[1], 41, 16 + pos, 0, 3); + } + } + + /* draw the little mask thingy at the bottom. Could optimize this.... -delt. + Sure can! This could share the same track-view functions that the + pattern editor ought to be using. -Storlek */ + if (is_selected && !(status.flags & CLASSIC_MODE)) { + switch (note_trans_cursor_pos) { + case 0: + draw_char(171, 36, 48, 3, 2); + draw_char(171, 37, 48, 3, 2); + draw_char(169, 38, 48, 3, 2); + if (note_sample_mask) { + draw_char(169, 40, 48, 3, 2); + draw_char(169, 41, 48, 3, 2); + } + break; + case 1: + draw_char(169, 38, 48, 3, 2); + if (note_sample_mask) { + draw_char(170, 40, 48, 3, 2); + draw_char(170, 41, 48, 3, 2); + } + break; + case 2: + case 3: + draw_char(note_sample_mask ? 171 : 169, 40, 48, 3, 2); + draw_char(note_sample_mask ? 171 : 169, 41, 48, 3, 2); + break; + }; + } } static void instrument_note_trans_transpose(song_instrument_t *ins, int dir) { - int i; - for (i = 0; i < 120; i++) { - ins->note_map[i] = CLAMP(ins->note_map[i]+dir, 1, 120); - } + int i; + for (i = 0; i < 120; i++) { + ins->note_map[i] = CLAMP(ins->note_map[i]+dir, 1, 120); + } } static void instrument_note_trans_insert(song_instrument_t *ins, int pos) { - int i; - for (i = 119; i > pos; i--) { - ins->note_map[i] = ins->note_map[i-1]; - ins->sample_map[i] = ins->sample_map[i-1]; - } - if (pos) { - ins->note_map[pos] = ins->note_map[pos-1]+1; - } else { - ins->note_map[0] = 1; - } + int i; + for (i = 119; i > pos; i--) { + ins->note_map[i] = ins->note_map[i-1]; + ins->sample_map[i] = ins->sample_map[i-1]; + } + if (pos) { + ins->note_map[pos] = ins->note_map[pos-1]+1; + } else { + ins->note_map[0] = 1; + } } static void instrument_note_trans_delete(song_instrument_t *ins, int pos) { - int i; - for (i = pos; i < 120; i++) { - ins->note_map[i] = ins->note_map[i+1]; - ins->sample_map[i] = ins->sample_map[i+1]; - } - ins->note_map[119] = ins->note_map[118]+1; + int i; + for (i = pos; i < 120; i++) { + ins->note_map[i] = ins->note_map[i+1]; + ins->sample_map[i] = ins->sample_map[i+1]; + } + ins->note_map[119] = ins->note_map[118]+1; } static int note_trans_handle_key(struct key_event * k) { - int prev_line = note_trans_sel_line; - int new_line = prev_line; - int prev_pos = note_trans_cursor_pos; - int new_pos = prev_pos; - song_instrument_t *ins = song_get_instrument(current_instrument); - int c, n; - - if (k->mouse == MOUSE_CLICK && k->mouse_button == MOUSE_BUTTON_MIDDLE) { - if (k->state) status.flags |= CLIPPY_PASTE_SELECTION; - return 1; - } else if (k->mouse == MOUSE_SCROLL_UP || k->mouse == MOUSE_SCROLL_DOWN) { - if (!k->state) { - note_trans_top_line += (k->mouse == MOUSE_SCROLL_UP) ? -3 : 3; - note_trans_top_line = CLAMP(note_trans_top_line, 0, 119 - 31); - status.flags |= NEED_UPDATE; - } - return 1; - } else if (k->mouse) { - if (k->x >= 32 && k->x <= 41 && k->y >= 16 && k->y <= 47) { - new_line = note_trans_top_line + k->y - 16; - if (new_line == prev_line) { - switch (k->x - 36) { - case 2: - new_pos = 1; - break; - case 4: - new_pos = 2; - break; - case 5: - new_pos = 3; - break; - default: - new_pos = 0; - break; - }; - } - } - } else if (k->mod & KMOD_ALT) { - if (k->state) - return 0; - switch (k->sym) { - case SDLK_UP: - instrument_note_trans_transpose(ins, 1); - break; - case SDLK_DOWN: - instrument_note_trans_transpose(ins, -1); - break; - case SDLK_INSERT: - instrument_note_trans_insert(ins, note_trans_sel_line); - break; - case SDLK_DELETE: - instrument_note_trans_delete(ins, note_trans_sel_line); - break; - case SDLK_n: - n = note_trans_sel_line - 1; // the line to copy *from* - if (n < 0 || ins->note_map[n] == NOTE_LAST) - break; - ins->note_map[note_trans_sel_line] = ins->note_map[n] + 1; - ins->sample_map[note_trans_sel_line] = ins->sample_map[n]; - new_line++; - break; - case SDLK_p: - n = note_trans_sel_line + 1; // the line to copy *from* - if (n > (NOTE_LAST - NOTE_FIRST) || ins->note_map[n] == NOTE_FIRST) - break; - ins->note_map[note_trans_sel_line] = ins->note_map[n] - 1; - ins->sample_map[note_trans_sel_line] = ins->sample_map[n]; - new_line--; - break; - case SDLK_a: - c = sample_get_current(); - for (n = 0; n < (NOTE_LAST - NOTE_FIRST + 1); n++) - ins->sample_map[n] = c; - break; - default: - return 0; - } - } else { - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) - sample_set(sample_get_current () - 1); - if (!NO_MODIFIER(k->mod)) - return 0; - if (--new_line < 0) { - change_focus_to(1); - return 1; - } - break; - case SDLK_DOWN: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) - sample_set(sample_get_current () + 1); - if (!NO_MODIFIER(k->mod)) - return 0; - new_line++; - break; - case SDLK_PAGEUP: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) { - instrument_set(current_instrument - 1); - return 1; - } - new_line -= 16; - break; - case SDLK_PAGEDOWN: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) { - instrument_set(current_instrument + 1); - return 1; - } - new_line += 16; - break; - case SDLK_HOME: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_line = 0; - break; - case SDLK_END: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_line = 119; - break; - case SDLK_LEFT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_pos--; - break; - case SDLK_RIGHT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_pos++; - break; - case SDLK_RETURN: - if (!k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - sample_set(ins->sample_map[note_trans_sel_line]); - get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - return 1; - case SDLK_LESS: - case SDLK_SEMICOLON: - case SDLK_COLON: - if (k->state) return 0; - sample_set(sample_get_current() - 1); - return 1; - case SDLK_GREATER: - case SDLK_QUOTE: - case SDLK_QUOTEDBL: - if (k->state) return 0; - sample_set(sample_get_current() + 1); - return 1; - - default: - if (k->state) return 0; - switch (note_trans_cursor_pos) { - case 0: /* note */ - n = kbd_get_note(k); - if (!NOTE_IS_NOTE(n)) - return 0; - ins->note_map[note_trans_sel_line] = n; - if (note_sample_mask || (status.flags & CLASSIC_MODE)) - ins->sample_map[note_trans_sel_line] = sample_get_current(); - new_line++; - break; - case 1: /* octave */ - c = kbd_char_to_hex(k); - if (c < 0 || c > 9) return 0; - n = ins->note_map[note_trans_sel_line]; - n = ((n - 1) % 12) + (12 * c) + 1; - ins->note_map[note_trans_sel_line] = n; - new_line++; - break; - - /* Made it possible to enter H to R letters - on 1st digit for expanded sample slots. -delt. */ - - case 2: /* instrument, first digit */ - case 3: /* instrument, second digit */ - if (k->sym == SDLK_SPACE) { - ins->sample_map[note_trans_sel_line] = - sample_get_current(); - new_line++; - break; - } - - if ((k->sym == SDLK_PERIOD && NO_MODIFIER(k->mod)) || k->sym == SDLK_DELETE) { - ins->sample_map[note_trans_sel_line] = 0; - new_line += (k->sym == SDLK_PERIOD) ? 1 : 0; - break; - } - if (k->sym == SDLK_COMMA && NO_MODIFIER(k->mod)) { - note_sample_mask = note_sample_mask ? 0 : 1; - break; - } - - n = ins->sample_map[note_trans_sel_line]; - if (note_trans_cursor_pos == 2) { - c = kbd_char_to_99(k); - if (c < 0) return 0; - n = (c * 10) + (n % 10); - new_pos++; - } else { - c = kbd_char_to_hex(k); - if (c < 0 || c > 9) return 0; - n = ((n / 10) * 10) + c; - new_pos--; - new_line++; - } - n = MIN(n, MAX_SAMPLES - 1); - ins->sample_map[note_trans_sel_line] = n; - sample_set(n); - break; - } - break; - } - } - - new_line = CLAMP(new_line, 0, 119); - note_trans_cursor_pos = CLAMP(new_pos, 0, 3); - if (new_line != prev_line) { - note_trans_sel_line = new_line; - note_trans_reposition(); - } - - /* this causes unneeded redraws in some cases... oh well :P */ - status.flags |= NEED_UPDATE; - return 1; + int prev_line = note_trans_sel_line; + int new_line = prev_line; + int prev_pos = note_trans_cursor_pos; + int new_pos = prev_pos; + song_instrument_t *ins = song_get_instrument(current_instrument); + int c, n; + + if (k->mouse == MOUSE_CLICK && k->mouse_button == MOUSE_BUTTON_MIDDLE) { + if (k->state == KEY_RELEASE) + status.flags |= CLIPPY_PASTE_SELECTION; + return 1; + } else if (k->mouse == MOUSE_SCROLL_UP || k->mouse == MOUSE_SCROLL_DOWN) { + if (k->state == KEY_PRESS) { + note_trans_top_line += (k->mouse == MOUSE_SCROLL_UP) ? -3 : 3; + note_trans_top_line = CLAMP(note_trans_top_line, 0, 119 - 31); + status.flags |= NEED_UPDATE; + } + return 1; + } else if (k->mouse != MOUSE_NONE) { + if (k->x >= 32 && k->x <= 41 && k->y >= 16 && k->y <= 47) { + new_line = note_trans_top_line + k->y - 16; + if (new_line == prev_line) { + switch (k->x - 36) { + case 2: + new_pos = 1; + break; + case 4: + new_pos = 2; + break; + case 5: + new_pos = 3; + break; + default: + new_pos = 0; + break; + }; + } + } + } else if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 0; + switch (k->sym) { + case SDLK_UP: + instrument_note_trans_transpose(ins, 1); + break; + case SDLK_DOWN: + instrument_note_trans_transpose(ins, -1); + break; + case SDLK_INSERT: + instrument_note_trans_insert(ins, note_trans_sel_line); + break; + case SDLK_DELETE: + instrument_note_trans_delete(ins, note_trans_sel_line); + break; + case SDLK_n: + n = note_trans_sel_line - 1; // the line to copy *from* + if (n < 0 || ins->note_map[n] == NOTE_LAST) + break; + ins->note_map[note_trans_sel_line] = ins->note_map[n] + 1; + ins->sample_map[note_trans_sel_line] = ins->sample_map[n]; + new_line++; + break; + case SDLK_p: + n = note_trans_sel_line + 1; // the line to copy *from* + if (n > (NOTE_LAST - NOTE_FIRST) || ins->note_map[n] == NOTE_FIRST) + break; + ins->note_map[note_trans_sel_line] = ins->note_map[n] - 1; + ins->sample_map[note_trans_sel_line] = ins->sample_map[n]; + new_line--; + break; + case SDLK_a: + c = sample_get_current(); + for (n = 0; n < (NOTE_LAST - NOTE_FIRST + 1); n++) + ins->sample_map[n] = c; + if (k->mod & KMOD_SHIFT) { + // Copy the name too. + memcpy(ins->name, current_song->samples[c].name, 32); + } + break; + default: + return 0; + } + } else { + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) + sample_set(sample_get_current () - 1); + if (!NO_MODIFIER(k->mod)) + return 0; + if (--new_line < 0) { + change_focus_to(1); + return 1; + } + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) + sample_set(sample_get_current () + 1); + if (!NO_MODIFIER(k->mod)) + return 0; + new_line++; + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) { + instrument_set(current_instrument - 1); + return 1; + } + new_line -= 16; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) { + instrument_set(current_instrument + 1); + return 1; + } + new_line += 16; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_line = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_line = 119; + break; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_pos--; + break; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_pos++; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + sample_set(ins->sample_map[note_trans_sel_line]); + get_page_widgets()->accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + return 1; + case SDLK_LESS: + case SDLK_SEMICOLON: + case SDLK_COLON: + if (k->state == KEY_RELEASE) + return 0; + sample_set(sample_get_current() - 1); + return 1; + case SDLK_GREATER: + case SDLK_QUOTE: + case SDLK_QUOTEDBL: + if (k->state == KEY_RELEASE) + return 0; + sample_set(sample_get_current() + 1); + return 1; + + default: + if (k->state == KEY_RELEASE) + return 0; + switch (note_trans_cursor_pos) { + case 0: /* note */ + n = kbd_get_note(k); + if (!NOTE_IS_NOTE(n)) + return 0; + ins->note_map[note_trans_sel_line] = n; + if (note_sample_mask || (status.flags & CLASSIC_MODE)) + ins->sample_map[note_trans_sel_line] = sample_get_current(); + new_line++; + break; + case 1: /* octave */ + c = kbd_char_to_hex(k); + if (c < 0 || c > 9) return 0; + n = ins->note_map[note_trans_sel_line]; + n = ((n - 1) % 12) + (12 * c) + 1; + ins->note_map[note_trans_sel_line] = n; + new_line++; + break; + + /* Made it possible to enter H to R letters + on 1st digit for expanded sample slots. -delt. */ + + case 2: /* instrument, first digit */ + case 3: /* instrument, second digit */ + if (k->sym == SDLK_SPACE) { + ins->sample_map[note_trans_sel_line] = + sample_get_current(); + new_line++; + break; + } + + if ((k->sym == SDLK_PERIOD && NO_MODIFIER(k->mod)) || k->sym == SDLK_DELETE) { + ins->sample_map[note_trans_sel_line] = 0; + new_line += (k->sym == SDLK_PERIOD) ? 1 : 0; + break; + } + if (k->sym == SDLK_COMMA && NO_MODIFIER(k->mod)) { + note_sample_mask = note_sample_mask ? 0 : 1; + break; + } + + n = ins->sample_map[note_trans_sel_line]; + if (note_trans_cursor_pos == 2) { + c = kbd_char_to_99(k); + if (c < 0) return 0; + n = (c * 10) + (n % 10); + new_pos++; + } else { + c = kbd_char_to_hex(k); + if (c < 0 || c > 9) return 0; + n = ((n / 10) * 10) + c; + new_pos--; + new_line++; + } + n = MIN(n, MAX_SAMPLES - 1); + ins->sample_map[note_trans_sel_line] = n; + sample_set(n); + break; + } + break; + } + } + + new_line = CLAMP(new_line, 0, 119); + note_trans_cursor_pos = CLAMP(new_pos, 0, 3); + if (new_line != prev_line) { + note_trans_sel_line = new_line; + note_trans_reposition(); + } + + /* this causes unneeded redraws in some cases... oh well :P */ + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -981,265 +1012,277 @@ static void _env_draw_axes(int middle) { - int n, y = middle ? 31 : 62; - for (n = 0; n < 64; n += 2) - vgamem_ovl_drawpixel(&env_overlay, 3, n, 12); - for (n = 0; n < 256; n += 2) - vgamem_ovl_drawpixel(&env_overlay, 1 + n, y, 12); + int n, y = middle ? 31 : 62; + for (n = 0; n < 64; n += 2) + vgamem_ovl_drawpixel(&env_overlay, 3, n, 12); + for (n = 0; n < 256; n += 2) + vgamem_ovl_drawpixel(&env_overlay, 1 + n, y, 12); } static void _env_draw_node(int x, int y, int on) { - int c = (status.flags & CLASSIC_MODE) ? 12 : 5; + int c = (status.flags & CLASSIC_MODE) ? 12 : 5; - vgamem_ovl_drawpixel(&env_overlay, x - 1, y - 1, c); - vgamem_ovl_drawpixel(&env_overlay, x - 1, y, c); - vgamem_ovl_drawpixel(&env_overlay, x - 1, y + 1, c); - - vgamem_ovl_drawpixel(&env_overlay, x, y - 1, c); - vgamem_ovl_drawpixel(&env_overlay, x, y, c); - vgamem_ovl_drawpixel(&env_overlay, x, y + 1, c); - - vgamem_ovl_drawpixel(&env_overlay, x + 1, y - 1,c); - vgamem_ovl_drawpixel(&env_overlay, x + 1, y,c); - vgamem_ovl_drawpixel(&env_overlay, x + 1, y + 1,c); - - if (on) { - vgamem_ovl_drawpixel(&env_overlay, x - 3, y - 1,c); - vgamem_ovl_drawpixel(&env_overlay, x - 3, y,c); - vgamem_ovl_drawpixel(&env_overlay, x - 3, y + 1,c); - - vgamem_ovl_drawpixel(&env_overlay, x + 3, y - 1,c); - vgamem_ovl_drawpixel(&env_overlay, x + 3, y,c); - vgamem_ovl_drawpixel(&env_overlay, x + 3, y + 1,c); - } + vgamem_ovl_drawpixel(&env_overlay, x - 1, y - 1, c); + vgamem_ovl_drawpixel(&env_overlay, x - 1, y, c); + vgamem_ovl_drawpixel(&env_overlay, x - 1, y + 1, c); + + vgamem_ovl_drawpixel(&env_overlay, x, y - 1, c); + vgamem_ovl_drawpixel(&env_overlay, x, y, c); + vgamem_ovl_drawpixel(&env_overlay, x, y + 1, c); + + vgamem_ovl_drawpixel(&env_overlay, x + 1, y - 1,c); + vgamem_ovl_drawpixel(&env_overlay, x + 1, y,c); + vgamem_ovl_drawpixel(&env_overlay, x + 1, y + 1,c); + + if (on) { + vgamem_ovl_drawpixel(&env_overlay, x - 3, y - 1,c); + vgamem_ovl_drawpixel(&env_overlay, x - 3, y,c); + vgamem_ovl_drawpixel(&env_overlay, x - 3, y + 1,c); + + vgamem_ovl_drawpixel(&env_overlay, x + 3, y - 1,c); + vgamem_ovl_drawpixel(&env_overlay, x + 3, y,c); + vgamem_ovl_drawpixel(&env_overlay, x + 3, y + 1,c); + } } static void _env_draw_loop(int xs, int xe, int sustain) { - int y = 0; - int c = (status.flags & CLASSIC_MODE) ? 12 : 3; + int y = 0; + int c = (status.flags & CLASSIC_MODE) ? 12 : 3; - if (sustain) { - while (y < 62) { - /* unrolled once */ - vgamem_ovl_drawpixel(&env_overlay, xs, y, c); - vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); - vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, c); - vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); - vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; - } - } else { - while (y < 62) { - vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); - vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, c); - vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, c); - vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; - vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); - vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; - } - } + if (sustain) { + while (y < 62) { + /* unrolled once */ + vgamem_ovl_drawpixel(&env_overlay, xs, y, c); + vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); + vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, c); + vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); + vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; + } + } else { + while (y < 62) { + vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); + vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, c); + vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, c); + vgamem_ovl_drawpixel(&env_overlay, xe, y, c); y++; + vgamem_ovl_drawpixel(&env_overlay, xs, y, 0); + vgamem_ovl_drawpixel(&env_overlay, xe, y, 0); y++; + } + } } static void _env_draw(const song_envelope_t *env, int middle, int current_node, - int env_on, int loop_on, int sustain_on, int env_num) + int env_on, int loop_on, int sustain_on, int env_num) { - song_voice_t *channel; - unsigned int *channel_list; - char buf[16]; - unsigned int envpos[3]; - int x, y, n, m, c; - int last_x = 0, last_y = 0; - int max_ticks = 50; - - while (env->ticks[env->nodes - 1] >= max_ticks) - max_ticks *= 2; - - vgamem_ovl_clear(&env_overlay, 0); - - /* draw the axis lines */ - _env_draw_axes(middle); - - for (n = 0; n < env->nodes; n++) { - x = 4 + env->ticks[n] * 256 / max_ticks; - - /* 65 values are being crammed into 62 pixels => have to lose three pixels somewhere. - * This is where IT compromises -- I don't quite get how the lines are drawn, though, - * because it changes for each value... (apart from drawing 63 and 64 the same way) */ - y = env->values[n]; - if (y > 63) y--; - if (y > 42) y--; - if (y > 21) y--; - y = 62 - y; - - _env_draw_node(x, y, n == current_node); - - if (last_x) - vgamem_ovl_drawline(&env_overlay, - last_x, last_y, x, y, 12); - - last_x = x; - last_y = y; - } - - if (sustain_on) - _env_draw_loop(4 + env->ticks[env->sustain_start] * 256 / max_ticks, - 4 + env->ticks[env->sustain_end] * 256 / max_ticks, 1); - if (loop_on) - _env_draw_loop(4 + env->ticks[env->loop_start] * 256 / max_ticks, - 4 + env->ticks[env->loop_end] * 256 / max_ticks, 0); - - if (env_on) { - max_ticks = env->ticks[env->nodes-1]; - m = max_ticks ? song_get_mix_state(&channel_list) : 0; - while (m--) { - channel = song_get_mix_channel(channel_list[m]); - if (channel->ptr_instrument != song_get_instrument(current_instrument)) - continue; - - envpos[0] = channel->vol_env_position; - envpos[1] = channel->pan_env_position; - envpos[2] = channel->pitch_env_position; - - x = 4 + (envpos[env_num] * (last_x-4) / max_ticks); - if (x > last_x) - x = last_x; - c = (status.flags & CLASSIC_MODE) - ? 12 - : ((channel->flags & (CHN_KEYOFF | CHN_NOTEFADE)) ? 8 : 6); - for (y = 0; y < 62; y++) - vgamem_ovl_drawpixel(&env_overlay, x, y, c); - } - } - - draw_fill_chars(65, 18, 76, 25, 0); - vgamem_ovl_apply(&env_overlay); - - sprintf(buf, "Node %d/%d", current_node, env->nodes); - draw_text(buf, 66, 19, 2, 0); - sprintf(buf, "Tick %d", env->ticks[current_node]); - draw_text(buf, 66, 21, 2, 0); - sprintf(buf, "Value %d", (int)(env->values[current_node] - (middle ? 32 : 0))); - draw_text(buf, 66, 23, 2, 0); + song_voice_t *channel; + unsigned int *channel_list; + char buf[16]; + unsigned int envpos[3]; + int x, y, n, m, c; + int last_x = 0, last_y = 0; + int max_ticks = 50; + + while (env->ticks[env->nodes - 1] >= max_ticks) + max_ticks *= 2; + + vgamem_ovl_clear(&env_overlay, 0); + + /* draw the axis lines */ + _env_draw_axes(middle); + + for (n = 0; n < env->nodes; n++) { + x = 4 + env->ticks[n] * 256 / max_ticks; + + /* 65 values are being crammed into 62 pixels => have to lose three pixels somewhere. + * This is where IT compromises -- I don't quite get how the lines are drawn, though, + * because it changes for each value... (apart from drawing 63 and 64 the same way) */ + y = env->values[n]; + if (y > 63) y--; + if (y > 42) y--; + if (y > 21) y--; + y = 62 - y; + + _env_draw_node(x, y, n == current_node); + + if (last_x) + vgamem_ovl_drawline(&env_overlay, + last_x, last_y, x, y, 12); + + last_x = x; + last_y = y; + } + + if (sustain_on) + _env_draw_loop(4 + env->ticks[env->sustain_start] * 256 / max_ticks, + 4 + env->ticks[env->sustain_end] * 256 / max_ticks, 1); + if (loop_on) + _env_draw_loop(4 + env->ticks[env->loop_start] * 256 / max_ticks, + 4 + env->ticks[env->loop_end] * 256 / max_ticks, 0); + + if (env_on) { + max_ticks = env->ticks[env->nodes-1]; + m = max_ticks ? song_get_mix_state(&channel_list) : 0; + while (m--) { + channel = song_get_mix_channel(channel_list[m]); + if (channel->ptr_instrument != song_get_instrument(current_instrument)) + continue; + + envpos[0] = channel->vol_env_position; + envpos[1] = channel->pan_env_position; + envpos[2] = channel->pitch_env_position; + + x = 4 + (envpos[env_num] * (last_x-4) / max_ticks); + if (x > last_x) + x = last_x; + c = (status.flags & CLASSIC_MODE) + ? 12 + : ((channel->flags & (CHN_KEYOFF | CHN_NOTEFADE)) ? 8 : 6); + for (y = 0; y < 62; y++) + vgamem_ovl_drawpixel(&env_overlay, x, y, c); + } + } + + draw_fill_chars(65, 18, 76, 25, 0); + vgamem_ovl_apply(&env_overlay); + + sprintf(buf, "Node %d/%d", current_node, env->nodes); + draw_text(buf, 66, 19, 2, 0); + sprintf(buf, "Tick %d", env->ticks[current_node]); + draw_text(buf, 66, 21, 2, 0); + sprintf(buf, "Value %d", (int)(env->values[current_node] - (middle ? 32 : 0))); + draw_text(buf, 66, 23, 2, 0); } /* return: the new current node */ static int _env_node_add(song_envelope_t *env, int current_node, int override_tick, int override_value) { - int newtick, newvalue; + int newtick, newvalue; - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; - if (env->nodes > 24 || current_node == env->nodes - 1) - return current_node; + if (env->nodes > 24 || current_node == env->nodes - 1) + return current_node; - newtick = (env->ticks[current_node] + env->ticks[current_node + 1]) / 2; - newvalue = (env->values[current_node] + env->values[current_node + 1]) / 2; - if (override_tick > -1 && override_value > -1) { - newtick = override_tick; - newvalue = override_value; - } else if (newtick == env->ticks[current_node] || newtick == env->ticks[current_node + 1]) { - printf("Not enough room!\n"); - return current_node; - } - - env->nodes++; - memmove(env->ticks + current_node + 1, env->ticks + current_node, - (env->nodes - current_node - 1) * sizeof(env->ticks[0])); - memmove(env->values + current_node + 1, env->values + current_node, - (env->nodes - current_node - 1) * sizeof(env->values[0])); - env->ticks[current_node + 1] = newtick; - env->values[current_node + 1] = newvalue; - if (env->loop_end > current_node) env->loop_end++; - if (env->loop_start > current_node) env->loop_start++; - if (env->sustain_end > current_node) env->sustain_end++; - if (env->sustain_start > current_node) env->sustain_start++; + newtick = (env->ticks[current_node] + env->ticks[current_node + 1]) / 2; + newvalue = (env->values[current_node] + env->values[current_node + 1]) / 2; + if (override_tick > -1 && override_value > -1) { + newtick = override_tick; + newvalue = override_value; + } else if (newtick == env->ticks[current_node] || newtick == env->ticks[current_node + 1]) { + printf("Not enough room!\n"); + return current_node; + } + + env->nodes++; + memmove(env->ticks + current_node + 1, env->ticks + current_node, + (env->nodes - current_node - 1) * sizeof(env->ticks[0])); + memmove(env->values + current_node + 1, env->values + current_node, + (env->nodes - current_node - 1) * sizeof(env->values[0])); + env->ticks[current_node + 1] = newtick; + env->values[current_node + 1] = newvalue; + if (env->loop_end > current_node) env->loop_end++; + if (env->loop_start > current_node) env->loop_start++; + if (env->sustain_end > current_node) env->sustain_end++; + if (env->sustain_start > current_node) env->sustain_start++; - return current_node; + return current_node; } /* return: the new current node */ static int _env_node_remove(song_envelope_t *env, int current_node) { - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; - if (current_node == 0 || env->nodes < 3) - return current_node; + if (current_node == 0 || env->nodes < 3) + return current_node; - memmove(env->ticks + current_node, env->ticks + current_node + 1, - (env->nodes - current_node - 1) * sizeof(env->ticks[0])); - memmove(env->values + current_node, env->values + current_node + 1, - (env->nodes - current_node - 1) * sizeof(env->values[0])); - env->nodes--; - if (env->loop_end > current_node) env->loop_end--; - if (env->loop_start > current_node) env->loop_start--; - if (env->sustain_end > current_node) env->sustain_end--; - if (env->sustain_start > current_node) env->sustain_start--; + memmove(env->ticks + current_node, env->ticks + current_node + 1, + (env->nodes - current_node - 1) * sizeof(env->ticks[0])); + memmove(env->values + current_node, env->values + current_node + 1, + (env->nodes - current_node - 1) * sizeof(env->values[0])); + env->nodes--; + + if (env->loop_start >= env->nodes) + env->loop_start = env->nodes - 1; + else if (env->loop_start > current_node) + env->loop_start--; + if (env->loop_end >= env->nodes) + env->loop_end = env->nodes - 1; + else if (env->loop_end > current_node) + env->loop_end--; + if (env->sustain_start >= env->nodes) + env->sustain_start = env->nodes - 1; + else if (env->sustain_start > current_node) + env->sustain_start--; + if (env->sustain_end >= env->nodes) + env->sustain_end = env->nodes - 1; + else if (env->sustain_end > current_node) + env->sustain_end--; + if (current_node >= env->nodes) + current_node = env->nodes - 1; - if (current_node >= env->nodes) - current_node = env->nodes - 1; - - return current_node; + return current_node; } static void do_pre_loop_cut(void *ign) { - song_envelope_t *env = (song_envelope_t *)ign; - unsigned int bt; - int i; - bt = env->ticks[env->loop_start]; - for (i = env->loop_start; i < 32; i++) { - env->ticks[i - env->loop_start] = env->ticks[i] - bt; - env->values[i - env->loop_start] = env->values[i]; - } - env->nodes -= env->loop_start; - if (env->sustain_start > env->loop_start) { - env->sustain_start -= env->loop_start; - } else { - env->sustain_start = 0; - } - if (env->sustain_end > env->loop_start) { - env->sustain_end -= env->loop_start; - } else { - env->sustain_end = 0; - } - if (env->loop_end > env->loop_start) { - env->loop_end -= env->loop_start; - } else { - env->loop_end = 0; - } - env->loop_start = 0; - if (env->loop_start > env->loop_end) - env->loop_end = env->loop_start; - if (env->sustain_start > env->sustain_end) - env->sustain_end = env->sustain_start; - status.flags |= NEED_UPDATE; + song_envelope_t *env = (song_envelope_t *)ign; + unsigned int bt; + int i; + bt = env->ticks[env->loop_start]; + for (i = env->loop_start; i < 32; i++) { + env->ticks[i - env->loop_start] = env->ticks[i] - bt; + env->values[i - env->loop_start] = env->values[i]; + } + env->nodes -= env->loop_start; + if (env->sustain_start > env->loop_start) { + env->sustain_start -= env->loop_start; + } else { + env->sustain_start = 0; + } + if (env->sustain_end > env->loop_start) { + env->sustain_end -= env->loop_start; + } else { + env->sustain_end = 0; + } + if (env->loop_end > env->loop_start) { + env->loop_end -= env->loop_start; + } else { + env->loop_end = 0; + } + env->loop_start = 0; + if (env->loop_start > env->loop_end) + env->loop_end = env->loop_start; + if (env->sustain_start > env->sustain_end) + env->sustain_end = env->sustain_start; + status.flags |= NEED_UPDATE; } static void do_post_loop_cut(void *ign) { - song_envelope_t *env = (song_envelope_t *)ign; - env->nodes = env->loop_end+1; + song_envelope_t *env = (song_envelope_t *)ign; + env->nodes = env->loop_end+1; } static void env_resize(song_envelope_t *env, int ticks) { - int old = env->ticks[env->nodes - 1]; - int n, t; + int old = env->ticks[env->nodes - 1]; + int n, t; - if (ticks > 9999) - ticks = 9999; - for (n = 1; n < env->nodes; n++) { - t = env->ticks[n] * ticks / old; - env->ticks[n] = MAX(t, env->ticks[n - 1] + 1); - } - status.flags |= NEED_UPDATE; + if (ticks > 9999) + ticks = 9999; + for (n = 1; n < env->nodes; n++) { + t = env->ticks[n] * ticks / old; + env->ticks[n] = MAX(t, env->ticks[n - 1] + 1); + } + status.flags |= NEED_UPDATE; } @@ -1248,26 +1291,26 @@ static void do_env_resize(void *data) { - env_resize((song_envelope_t *) data, env_resize_widgets[0].d.numentry.value); + env_resize((song_envelope_t *) data, env_resize_widgets[0].d.numentry.value); } static void env_resize_draw_const(void) { - draw_text("Resize Envelope", 34, 24, 3, 2); - draw_text("New Length", 31, 27, 0, 2); - draw_box(41, 26, 49, 28, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Resize Envelope", 34, 24, 3, 2); + draw_text("New Length", 31, 27, 0, 2); + draw_box(41, 26, 49, 28, BOX_THICK | BOX_INNER | BOX_INSET); } static void env_resize_dialog(song_envelope_t *env) { - struct dialog *dialog; + struct dialog *dialog; - env_resize_cursor = 0; - create_numentry(env_resize_widgets + 0, 42, 27, 7, 0, 1, 1, NULL, 0, 9999, &env_resize_cursor); - env_resize_widgets[0].d.numentry.value = env->ticks[env->nodes - 1]; - create_button(env_resize_widgets + 1, 36, 30, 6, 0, 1, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(26, 22, 29, 11, env_resize_widgets, 2, 0, env_resize_draw_const, env); - dialog->action_yes = do_env_resize; + env_resize_cursor = 0; + create_numentry(env_resize_widgets + 0, 42, 27, 7, 0, 1, 1, NULL, 0, 9999, &env_resize_cursor); + env_resize_widgets[0].d.numentry.value = env->ticks[env->nodes - 1]; + create_button(env_resize_widgets + 1, 36, 30, 6, 0, 1, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + dialog = dialog_create_custom(26, 22, 29, 11, env_resize_widgets, 2, 0, env_resize_draw_const, env); + dialog->action_yes = do_env_resize; } @@ -1277,64 +1320,64 @@ static void do_env_adsr(void *data) { - // FIXME | move env flags into the envelope itself, where they should be in the first place. - // FIXME | then this nonsense can go away. - song_instrument_t *ins = (song_instrument_t *) data; - song_envelope_t *env = &ins->vol_env; - int a = env_adsr_widgets[0].d.thumbbar.value; - int d = env_adsr_widgets[1].d.thumbbar.value; - int s = env_adsr_widgets[2].d.thumbbar.value; - int r = env_adsr_widgets[3].d.thumbbar.value; - int v1 = MAX(a, a * a / 16); - int v2 = MAX(v1 + d * d / 16, v1 + d); - int v3 = MAX(v2 + r * r / 4, v2 + r); - int n = 0; - - if (a) { - env->ticks[n] = 0; - env->values[n++] = 0; - } - if (d) { - env->ticks[n] = v1; - env->values[n++] = 64; - } - env->sustain_start = env->sustain_end = n; - env->ticks[n] = v2; - env->values[n++] = s / 2; - env->ticks[n] = v3; - env->values[n++] = 0; - env->nodes = n; - for (n = 0; n < env->nodes - 1; n++) - if (env->ticks[n] >= env->ticks[n + 1]) - env->ticks[n + 1] = env->ticks[n] + 1; - ins->flags |= ENV_VOLSUSTAIN | ENV_VOLUME; // arghhhhh + // FIXME | move env flags into the envelope itself, where they should be in the first place. + // FIXME | then this nonsense can go away. + song_instrument_t *ins = (song_instrument_t *) data; + song_envelope_t *env = &ins->vol_env; + int a = env_adsr_widgets[0].d.thumbbar.value; + int d = env_adsr_widgets[1].d.thumbbar.value; + int s = env_adsr_widgets[2].d.thumbbar.value; + int r = env_adsr_widgets[3].d.thumbbar.value; + int v1 = MAX(a, a * a / 16); + int v2 = MAX(v1 + d * d / 16, v1 + d); + int v3 = MAX(v2 + r * r / 4, v2 + r); + int n = 0; + + if (a) { + env->ticks[n] = 0; + env->values[n++] = 0; + } + if (d) { + env->ticks[n] = v1; + env->values[n++] = 64; + } + env->sustain_start = env->sustain_end = n; + env->ticks[n] = v2; + env->values[n++] = s / 2; + env->ticks[n] = v3; + env->values[n++] = 0; + env->nodes = n; + for (n = 0; n < env->nodes - 1; n++) + if (env->ticks[n] >= env->ticks[n + 1]) + env->ticks[n + 1] = env->ticks[n] + 1; + ins->flags |= ENV_VOLSUSTAIN | ENV_VOLUME; // arghhhhh } static void env_adsr_draw_const(void) { - draw_text("Envelope Generator", 32, 22, 0, 2); - draw_text("Attack", 27, 24, 0, 2); - draw_text("Decay", 28, 25, 0, 2); - draw_text("Sustain", 26, 26, 0, 2); - draw_text("Release", 26, 27, 0, 2); + draw_text("Envelope Generator", 32, 22, 0, 2); + draw_text("Attack", 27, 24, 0, 2); + draw_text("Decay", 28, 25, 0, 2); + draw_text("Sustain", 26, 26, 0, 2); + draw_text("Release", 26, 27, 0, 2); - draw_box(33, 23, 51, 28, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(33, 23, 51, 28, BOX_THICK | BOX_INNER | BOX_INSET); } static void env_adsr_dialog(UNUSED song_envelope_t *env) { - struct dialog *dialog; - song_instrument_t *ins = song_get_instrument(current_instrument); // ARGHHH + struct dialog *dialog; + song_instrument_t *ins = song_get_instrument(current_instrument); // ARGHHH - env_adsr_cursor = 0; - create_thumbbar(env_adsr_widgets + 0, 34, 24, 17, 4, 1, 4, NULL, 0, 128); - create_thumbbar(env_adsr_widgets + 1, 34, 25, 17, 0, 2, 4, NULL, 0, 128); - create_thumbbar(env_adsr_widgets + 2, 34, 26, 17, 1, 3, 4, NULL, 0, 128); - create_thumbbar(env_adsr_widgets + 3, 34, 27, 17, 2, 4, 4, NULL, 0, 128); - create_button(env_adsr_widgets + 4, 36, 30, 6, 3, 0, 4, 4, 0, dialog_cancel_NULL, "Cancel", 1); + env_adsr_cursor = 0; + create_thumbbar(env_adsr_widgets + 0, 34, 24, 17, 4, 1, 4, NULL, 0, 128); + create_thumbbar(env_adsr_widgets + 1, 34, 25, 17, 0, 2, 4, NULL, 0, 128); + create_thumbbar(env_adsr_widgets + 2, 34, 26, 17, 1, 3, 4, NULL, 0, 128); + create_thumbbar(env_adsr_widgets + 3, 34, 27, 17, 2, 4, 4, NULL, 0, 128); + create_button(env_adsr_widgets + 4, 36, 30, 6, 3, 0, 4, 4, 0, dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(25, 21, 31, 12, env_adsr_widgets, 5, 0, env_adsr_draw_const, ins); - dialog->action_yes = do_env_adsr; + dialog = dialog_create_custom(25, 21, 31, 12, env_adsr_widgets, 5, 0, env_adsr_draw_const, ins); + dialog->action_yes = do_env_adsr; } @@ -1345,249 +1388,264 @@ r & 2 => the envelope changed (i.e., it should be enabled) */ static int _env_handle_key_viewmode(struct key_event *k, song_envelope_t *env, int *current_node, unsigned int sec) { - int new_node = *current_node; - int n; + int new_node = *current_node; + int n; - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - change_focus_to(1); - return 1; - case SDLK_DOWN: - if (k->state) return 0; - change_focus_to(6); - return 1; - case SDLK_LEFT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_node--; - break; - case SDLK_RIGHT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_node++; - break; - case SDLK_INSERT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - *current_node = _env_node_add(env, *current_node, -1, -1); - status.flags |= NEED_UPDATE; - return 1 | 2; - case SDLK_DELETE: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - *current_node = _env_node_remove(env, *current_node); - status.flags |= NEED_UPDATE; - return 1 | 2; - case SDLK_SPACE: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - song_keyup(KEYJAZZ_NOINST, current_instrument, last_note); - song_keydown(KEYJAZZ_NOINST, current_instrument, last_note, 64, KEYJAZZ_CHAN_CURRENT); - return 1; - case SDLK_RETURN: - if (!k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - envelope_edit_mode = 1; - status.flags |= NEED_UPDATE; - return 1 | 2; - case SDLK_l: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - if (env->loop_end < (env->nodes-1)) { - dialog_create(DIALOG_OK_CANCEL, "Cut envelope?", do_post_loop_cut, NULL, 1, env); - return 1; - } - return 0; - case SDLK_b: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - if (env->loop_start > 0) { - dialog_create(DIALOG_OK_CANCEL, "Cut envelope?", do_pre_loop_cut, NULL, 1, env); - return 1; - } - return 0; - - // F/G for key symmetry with pattern double/halve block - // E for symmetry with sample resize - case SDLK_f: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - env_resize(env, env->ticks[env->nodes - 1] * 2); - return 1; - case SDLK_g: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - env_resize(env, env->ticks[env->nodes - 1] / 2); - return 1; - case SDLK_e: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - env_resize_dialog(env); - return 1; - - case SDLK_z: - if (!k->state) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - env_adsr_dialog(env); - return 1; - - default: - if (!k->state) return 0; - - n = numeric_key_event(k, 0); - if (n > -1) { - if (k->mod & (KMOD_ALT | KMOD_CTRL)) { - save_envelope(n, env, sec); - status_text_flash("Envelope copied into slot %d", n); - } else if (k->mod & KMOD_SHIFT) { - restore_envelope(n, env, sec); - if (!(status.flags & CLASSIC_MODE)) - status_text_flash("Pasted envelope from slot %d", n); - } - return 1; - } - return 0; - } - - new_node = CLAMP(new_node, 0, env->nodes - 1); - if (*current_node != new_node) { - *current_node = new_node; - status.flags |= NEED_UPDATE; - } + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + change_focus_to(1); + return 1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + change_focus_to(6); + return 1; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_node--; + break; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_node++; + break; + case SDLK_INSERT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + *current_node = _env_node_add(env, *current_node, -1, -1); + status.flags |= NEED_UPDATE; + return 1 | 2; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + *current_node = _env_node_remove(env, *current_node); + status.flags |= NEED_UPDATE; + return 1 | 2; + case SDLK_SPACE: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + song_keyup(KEYJAZZ_NOINST, current_instrument, last_note); + song_keydown(KEYJAZZ_NOINST, current_instrument, last_note, 64, KEYJAZZ_CHAN_CURRENT); + return 1; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + envelope_edit_mode = 1; + status.flags |= NEED_UPDATE; + return 1 | 2; + case SDLK_l: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + if (env->loop_end < (env->nodes-1)) { + dialog_create(DIALOG_OK_CANCEL, "Cut envelope?", do_post_loop_cut, NULL, 1, env); + return 1; + } + return 0; + case SDLK_b: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + if (env->loop_start > 0) { + dialog_create(DIALOG_OK_CANCEL, "Cut envelope?", do_pre_loop_cut, NULL, 1, env); + return 1; + } + return 0; + + // F/G for key symmetry with pattern double/halve block + // E for symmetry with sample resize + case SDLK_f: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + env_resize(env, env->ticks[env->nodes - 1] * 2); + return 1; + case SDLK_g: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + env_resize(env, env->ticks[env->nodes - 1] / 2); + return 1; + case SDLK_e: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + env_resize_dialog(env); + return 1; + + case SDLK_z: + if (k->state == KEY_PRESS) + return 0; + if (!(k->mod & KMOD_ALT)) return 0; + env_adsr_dialog(env); + return 1; + + default: + if (k->state == KEY_PRESS) + return 0; + + n = numeric_key_event(k, 0); + if (n > -1) { + if (k->mod & (KMOD_ALT | KMOD_CTRL)) { + save_envelope(n, env, sec); + status_text_flash("Envelope copied into slot %d", n); + } else if (k->mod & KMOD_SHIFT) { + restore_envelope(n, env, sec); + if (!(status.flags & CLASSIC_MODE)) + status_text_flash("Pasted envelope from slot %d", n); + } + return 1; + } + return 0; + } + + new_node = CLAMP(new_node, 0, env->nodes - 1); + if (*current_node != new_node) { + *current_node = new_node; + status.flags |= NEED_UPDATE; + } - return 1; + return 1; } /* mouse handling routines for envelope */ static int _env_handle_mouse(struct key_event *k, song_envelope_t *env, int *current_node) { - int x, y, i; - int max_ticks = 50; + int x, y, i; + int max_ticks = 50; - if (k->mouse != MOUSE_CLICK) return 0; + if (k->mouse != MOUSE_CLICK) return 0; - if (k->state) { - /* mouse release */ - if (envelope_mouse_edit) { - if (current_node && *current_node) { - for (i = 0; i < env->nodes-1; i++) { - if (*current_node == i) continue; - if (env->ticks[ *current_node ] == env->ticks[i] - && env->values[ *current_node ] == env->values[i]) { - status_text_flash("Removed node %d", (int)(*current_node)); - status.flags |= SONG_NEEDS_SAVE; - - *current_node = _env_node_remove(env, *current_node); - break; - } - } - - } - status.flags |= NEED_UPDATE; - } - memused_songchanged(); - envelope_mouse_edit = 0; - return 1; - } - - while (env->ticks[env->nodes - 1] >= max_ticks) - max_ticks *= 2; - - if (envelope_mouse_edit) { - if (k->fx < 259) - x = 0; - else - x = (k->fx - 259) * max_ticks / 256; - y = 64 - (k->fy - 144); - if (y > 63) y++; - if (y > 42) y++; - if (y > 21) y++; - if (y > 64) y = 64; - if (y < 0) y = 0; - - if (*current_node && env->ticks[ (*current_node)-1 ] >= x) { - x = env->ticks[ (*current_node)-1 ]+1; - } - if (*current_node < (env->nodes-1)) { - if (env->ticks[ (*current_node)+1 ] <= x) { - x = env->ticks[ (*current_node)+1 ]-1; - } - } - if (env->ticks[*current_node] == x && env->ticks[*current_node] == y) { - return 1; - } - if (x < 0) x = 0; - if (x > envelope_tick_limit) x = envelope_tick_limit; - if (x > 9999) x = 9999; - if (*current_node) env->ticks[ *current_node ] = x; - env->values[ *current_node ] = y; - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; - } else { - int n; - int dist, dx, dy; - int best_dist = 0; - int best_dist_node; - - best_dist_node = -1; - - if (k->x < 32 || k->y < 18 || k->x > 32+45 || k->y > 18+8) - return 0; - - for (n = 0; n < env->nodes; n++) { - x = 259 + env->ticks[n] * 256 / max_ticks; - y = env->values[n]; - if (y > 63) y--; - if (y > 42) y--; - if (y > 21) y--; - y = 206 - y; - - dx = abs(x - k->fx); - dy = abs(y - k->fy); - dist = i_sqrt((dx*dx)+(dy*dy)); - if (best_dist_node == -1 || dist < best_dist) { - if (dist <= 5) { - best_dist = dist; - best_dist_node = n; - } - } - } - if (best_dist_node == -1) { - x = (k->fx - 259) * max_ticks / 256; - y = 64 - (k->fy - 144); - if (y > 63) y++; - if (y > 42) y++; - if (y > 21) y++; - if (y > 64) y = 64; - if (y < 0) y = 0; - if (x > 0 && x < max_ticks) { - *current_node = 0; - for (i = 1; i < env->nodes; i++) { - /* something too close */ - if (env->ticks[i] <= x) *current_node = i; - if (abs(env->ticks[i] - x) < 2) return 0; - } - best_dist_node = (_env_node_add(env, *current_node, x, y))+1; - status_text_flash("Created node %d", best_dist_node); - } - if (best_dist_node == -1) return 0; - } - - envelope_tick_limit = env->ticks[env->nodes - 1] * 2; - envelope_mouse_edit = 1; - *current_node = best_dist_node; - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; - return 1; - } - return 0; + if (k->state == KEY_RELEASE) { + /* mouse release */ + if (envelope_mouse_edit) { + if (current_node && *current_node) { + for (i = 0; i < env->nodes-1; i++) { + if (*current_node == i) continue; + if (env->ticks[ *current_node ] == env->ticks[i] + && env->values[ *current_node ] == env->values[i]) { + status_text_flash("Removed node %d", (int)(*current_node)); + status.flags |= SONG_NEEDS_SAVE; + + *current_node = _env_node_remove(env, *current_node); + break; + } + } + + } + status.flags |= NEED_UPDATE; + } + memused_songchanged(); + envelope_mouse_edit = 0; + return 1; + } + + while (env->ticks[env->nodes - 1] >= max_ticks) + max_ticks *= 2; + + if (envelope_mouse_edit) { + if (k->fx < 259) + x = 0; + else + x = (k->fx - 259) * max_ticks / 256; + y = 64 - (k->fy - 144); + if (y > 63) y++; + if (y > 42) y++; + if (y > 21) y++; + if (y > 64) y = 64; + if (y < 0) y = 0; + + if (*current_node && env->ticks[ (*current_node)-1 ] >= x) { + x = env->ticks[ (*current_node)-1 ]+1; + } + if (*current_node < (env->nodes-1)) { + if (env->ticks[ (*current_node)+1 ] <= x) { + x = env->ticks[ (*current_node)+1 ]-1; + } + } + if (env->ticks[*current_node] == x && env->ticks[*current_node] == y) { + return 1; + } + if (x < 0) x = 0; + if (x > envelope_tick_limit) x = envelope_tick_limit; + if (x > 9999) x = 9999; + if (*current_node) env->ticks[ *current_node ] = x; + env->values[ *current_node ] = y; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + } else { + int n; + int dist, dx, dy; + int best_dist = 0; + int best_dist_node; + + best_dist_node = -1; + + if (k->x < 32 || k->y < 18 || k->x > 32+45 || k->y > 18+8) + return 0; + + for (n = 0; n < env->nodes; n++) { + x = 259 + env->ticks[n] * 256 / max_ticks; + y = env->values[n]; + if (y > 63) y--; + if (y > 42) y--; + if (y > 21) y--; + y = 206 - y; + + dx = abs(x - (int) k->fx); + dy = abs(y - (int) k->fy); + dist = i_sqrt((dx*dx)+(dy*dy)); + if (best_dist_node == -1 || dist < best_dist) { + if (dist <= 5) { + best_dist = dist; + best_dist_node = n; + } + } + } + if (best_dist_node == -1) { + x = (k->fx - 259) * max_ticks / 256; + y = 64 - (k->fy - 144); + if (y > 63) y++; + if (y > 42) y++; + if (y > 21) y++; + if (y > 64) y = 64; + if (y < 0) y = 0; + if (x > 0 && x < max_ticks) { + *current_node = 0; + for (i = 1; i < env->nodes; i++) { + /* something too close */ + if (env->ticks[i] <= x) *current_node = i; + if (abs(env->ticks[i] - x) < 2) return 0; + } + best_dist_node = (_env_node_add(env, *current_node, x, y))+1; + status_text_flash("Created node %d", best_dist_node); + } + if (best_dist_node == -1) return 0; + } + + envelope_tick_limit = env->ticks[env->nodes - 1] * 2; + envelope_mouse_edit = 1; + *current_node = best_dist_node; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + return 1; + } + return 0; } @@ -1600,135 +1658,148 @@ no reason to indicate a change in the envelope here. */ static int _env_handle_key_editmode(struct key_event *k, song_envelope_t *env, int *current_node) { - int new_node = *current_node, new_tick = env->ticks[*current_node], - new_value = env->values[*current_node]; + int new_node = *current_node, new_tick = env->ticks[*current_node], + new_value = env->values[*current_node]; - /* TODO: when does adding/removing a node alter loop points? */ + /* TODO: when does adding/removing a node alter loop points? */ - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - if (k->mod & KMOD_ALT) - new_value += 16; - else - new_value++; - break; - case SDLK_DOWN: - if (k->state) return 0; - if (k->mod & KMOD_ALT) - new_value -= 16; - else - new_value--; - break; - case SDLK_PAGEUP: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_value += 16; - break; - case SDLK_PAGEDOWN: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_value -= 16; - break; - case SDLK_LEFT: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) - new_node--; - else if (k->mod & KMOD_ALT) - new_tick -= 16; - else - new_tick--; - break; - case SDLK_RIGHT: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) - new_node++; - else if (k->mod & KMOD_ALT) - new_tick += 16; - else - new_tick++; - break; - case SDLK_TAB: - if (k->state) return 0; - if (k->mod & KMOD_SHIFT) - new_tick -= 16; - else - new_tick += 16; - break; - case SDLK_HOME: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_tick = 0; - break; - case SDLK_END: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_tick = 10000; - break; - case SDLK_INSERT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - *current_node = _env_node_add(env, *current_node, -1, -1); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_DELETE: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - *current_node = _env_node_remove(env, *current_node); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_SPACE: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - song_keyup(KEYJAZZ_NOINST, current_instrument, last_note); - song_keydown(KEYJAZZ_NOINST, current_instrument, last_note, 64, KEYJAZZ_CHAN_CURRENT); - return 1; - case SDLK_RETURN: - if (!k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - envelope_edit_mode = 0; - memused_songchanged(); - status.flags |= NEED_UPDATE; - break; - default: - return 0; - } - - new_node = CLAMP(new_node, 0, env->nodes - 1); - if (new_node != *current_node) { - status.flags |= NEED_UPDATE; - *current_node = new_node; - return 1; - } - - new_tick = (new_node == 0) ? 0 : CLAMP(new_tick, - env->ticks[new_node - 1] + 1, - ((new_node == env->nodes - 1) - ? 10000 : env->ticks[new_node + 1]) - 1); - if (new_tick != env->ticks[new_node]) { - env->ticks[*current_node] = new_tick; - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; - return 1; - } - new_value = CLAMP(new_value, 0, 64); - - if (new_value != (int)env->values[new_node]) { - env->values[*current_node] = (unsigned int)new_value; - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; - return 1; - } + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) + new_value += 16; + else + new_value++; + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) + new_value -= 16; + else + new_value--; + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_value += 16; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_value -= 16; + break; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) + new_node--; + else if (k->mod & KMOD_ALT) + new_tick -= 16; + else + new_tick--; + break; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) + new_node++; + else if (k->mod & KMOD_ALT) + new_tick += 16; + else + new_tick++; + break; + case SDLK_TAB: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_SHIFT) + new_tick -= 16; + else + new_tick += 16; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_tick = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_tick = 10000; + break; + case SDLK_INSERT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + *current_node = _env_node_add(env, *current_node, -1, -1); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + *current_node = _env_node_remove(env, *current_node); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_SPACE: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + song_keyup(KEYJAZZ_NOINST, current_instrument, last_note); + song_keydown(KEYJAZZ_NOINST, current_instrument, last_note, 64, KEYJAZZ_CHAN_CURRENT); + return 1; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + envelope_edit_mode = 0; + memused_songchanged(); + status.flags |= NEED_UPDATE; + break; + default: + return 0; + } + + new_node = CLAMP(new_node, 0, env->nodes - 1); + if (new_node != *current_node) { + status.flags |= NEED_UPDATE; + *current_node = new_node; + return 1; + } + + new_tick = (new_node == 0) ? 0 : CLAMP(new_tick, + env->ticks[new_node - 1] + 1, + ((new_node == env->nodes - 1) + ? 10000 : env->ticks[new_node + 1]) - 1); + if (new_tick != env->ticks[new_node]) { + env->ticks[*current_node] = new_tick; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + return 1; + } + new_value = CLAMP(new_value, 0, 64); + + if (new_value != (int)env->values[new_node]) { + env->values[*current_node] = (unsigned int)new_value; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + return 1; + } - return 1; + return 1; } /* --------------------------------------------------------------------------------------------------------- */ @@ -1736,106 +1807,106 @@ static void _draw_env_label(const char *env_name, int is_selected) { - int pos = 33; + int pos = 33; - pos += draw_text(env_name, pos, 16, is_selected ? 3 : 0, 2); - pos += draw_text(" Envelope", pos, 16, is_selected ? 3 : 0, 2); - if (envelope_edit_mode || envelope_mouse_edit) - draw_text(" (Edit)", pos, 16, is_selected ? 3 : 0, 2); + pos += draw_text(env_name, pos, 16, is_selected ? 3 : 0, 2); + pos += draw_text(" Envelope", pos, 16, is_selected ? 3 : 0, 2); + if (envelope_edit_mode || envelope_mouse_edit) + draw_text(" (Edit)", pos, 16, is_selected ? 3 : 0, 2); } static void volume_envelope_draw(void) { - int is_selected = (ACTIVE_PAGE.selected_widget == 5); - song_instrument_t *ins = song_get_instrument(current_instrument); + int is_selected = (ACTIVE_PAGE.selected_widget == 5); + song_instrument_t *ins = song_get_instrument(current_instrument); - _draw_env_label("Volume", is_selected); - _env_draw(&ins->vol_env, 0, current_node_vol, - ins->flags & ENV_VOLUME, - ins->flags & ENV_VOLLOOP, ins->flags & ENV_VOLSUSTAIN, 0); + _draw_env_label("Volume", is_selected); + _env_draw(&ins->vol_env, 0, current_node_vol, + ins->flags & ENV_VOLUME, + ins->flags & ENV_VOLLOOP, ins->flags & ENV_VOLSUSTAIN, 0); } static void panning_envelope_draw(void) { - int is_selected = (ACTIVE_PAGE.selected_widget == 5); - song_instrument_t *ins = song_get_instrument(current_instrument); + int is_selected = (ACTIVE_PAGE.selected_widget == 5); + song_instrument_t *ins = song_get_instrument(current_instrument); - _draw_env_label("Panning", is_selected); - _env_draw(&ins->pan_env, 1, current_node_pan, - ins->flags & ENV_PANNING, - ins->flags & ENV_PANLOOP, ins->flags & ENV_PANSUSTAIN, 1); + _draw_env_label("Panning", is_selected); + _env_draw(&ins->pan_env, 1, current_node_pan, + ins->flags & ENV_PANNING, + ins->flags & ENV_PANLOOP, ins->flags & ENV_PANSUSTAIN, 1); } static void pitch_envelope_draw(void) { - int is_selected = (ACTIVE_PAGE.selected_widget == 5); - song_instrument_t *ins = song_get_instrument(current_instrument); + int is_selected = (ACTIVE_PAGE.selected_widget == 5); + song_instrument_t *ins = song_get_instrument(current_instrument); - _draw_env_label("Frequency", is_selected); - _env_draw(&ins->pitch_env, (ins->flags & ENV_FILTER) ? 0 : 1, current_node_pitch, - ins->flags & (ENV_PITCH|ENV_FILTER), - ins->flags & ENV_PITCHLOOP, ins->flags & ENV_PITCHSUSTAIN, 2); + _draw_env_label("Frequency", is_selected); + _env_draw(&ins->pitch_env, (ins->flags & ENV_FILTER) ? 0 : 1, current_node_pitch, + ins->flags & (ENV_PITCH|ENV_FILTER), + ins->flags & ENV_PITCHLOOP, ins->flags & ENV_PITCHSUSTAIN, 2); } static int volume_envelope_handle_key(struct key_event * k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - int r; + song_instrument_t *ins = song_get_instrument(current_instrument); + int r; - if (_env_handle_mouse(k, &ins->vol_env, ¤t_node_vol)) { - ins->flags |= ENV_VOLUME; - return 1; - } - if (envelope_edit_mode) - r = _env_handle_key_editmode(k, &ins->vol_env, ¤t_node_vol); - else - r = _env_handle_key_viewmode(k, &ins->vol_env, ¤t_node_vol, ENV_VOLUME); - if (r & 2) { - r ^= 2; - ins->flags |= ENV_VOLUME; - } - return r; + if (_env_handle_mouse(k, &ins->vol_env, ¤t_node_vol)) { + ins->flags |= ENV_VOLUME; + return 1; + } + if (envelope_edit_mode) + r = _env_handle_key_editmode(k, &ins->vol_env, ¤t_node_vol); + else + r = _env_handle_key_viewmode(k, &ins->vol_env, ¤t_node_vol, ENV_VOLUME); + if (r & 2) { + r ^= 2; + ins->flags |= ENV_VOLUME; + } + return r; } static int panning_envelope_handle_key(struct key_event * k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - int r; + song_instrument_t *ins = song_get_instrument(current_instrument); + int r; - if (_env_handle_mouse(k, &ins->pan_env, ¤t_node_pan)) { - ins->flags |= ENV_PANNING; - return 1; - } - - if (envelope_edit_mode) - r = _env_handle_key_editmode(k, &ins->pan_env, ¤t_node_pan); - else - r = _env_handle_key_viewmode(k, &ins->pan_env, ¤t_node_pan, ENV_PANNING); - if (r & 2) { - r ^= 2; - ins->flags |= ENV_PANNING; - } - return r; + if (_env_handle_mouse(k, &ins->pan_env, ¤t_node_pan)) { + ins->flags |= ENV_PANNING; + return 1; + } + + if (envelope_edit_mode) + r = _env_handle_key_editmode(k, &ins->pan_env, ¤t_node_pan); + else + r = _env_handle_key_viewmode(k, &ins->pan_env, ¤t_node_pan, ENV_PANNING); + if (r & 2) { + r ^= 2; + ins->flags |= ENV_PANNING; + } + return r; } static int pitch_envelope_handle_key(struct key_event * k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - int r; + song_instrument_t *ins = song_get_instrument(current_instrument); + int r; - if (_env_handle_mouse(k, &ins->pitch_env, ¤t_node_pitch)) { - ins->flags |= ENV_PITCH; - return 1; - } - if (envelope_edit_mode) - r = _env_handle_key_editmode(k, &ins->pitch_env, ¤t_node_pitch); - else - r = _env_handle_key_viewmode(k, &ins->pitch_env, ¤t_node_pitch, ENV_PITCH); - if (r & 2) { - r ^= 2; - ins->flags |= ENV_PITCH; - } - return r; + if (_env_handle_mouse(k, &ins->pitch_env, ¤t_node_pitch)) { + ins->flags |= ENV_PITCH; + return 1; + } + if (envelope_edit_mode) + r = _env_handle_key_editmode(k, &ins->pitch_env, ¤t_node_pitch); + else + r = _env_handle_key_viewmode(k, &ins->pitch_env, ¤t_node_pitch, ENV_PITCH); + if (r & 2) { + r ^= 2; + ins->flags |= ENV_PITCH; + } + return r; } /* --------------------------------------------------------------------------------------------------------- */ @@ -1843,46 +1914,47 @@ static int pitch_pan_center_handle_key(struct key_event *k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - int ppc = ins->pitch_pan_center; + song_instrument_t *ins = song_get_instrument(current_instrument); + int ppc = ins->pitch_pan_center; - if (k->state) return 0; - switch (k->sym) { - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod)) - return 0; - ppc--; - break; - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod)) - return 0; - ppc++; - break; - default: - if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { - ppc = kbd_get_note(k); - if (ppc < 1 || ppc > 120) - return 0; - ppc--; - break; - } - return 0; - } - if ((unsigned int)ppc != ins->pitch_pan_center - && ppc >= 0 && ppc < 120) { - ins->pitch_pan_center = (unsigned int)ppc; - status.flags |= NEED_UPDATE; - } - return 1; + if (k->state == KEY_RELEASE) + return 0; + switch (k->sym) { + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod)) + return 0; + ppc--; + break; + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod)) + return 0; + ppc++; + break; + default: + if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { + ppc = kbd_get_note(k); + if (ppc < 1 || ppc > 120) + return 0; + ppc--; + break; + } + return 0; + } + if ((unsigned int)ppc != ins->pitch_pan_center + && ppc >= 0 && ppc < 120) { + ins->pitch_pan_center = (unsigned int)ppc; + status.flags |= NEED_UPDATE; + } + return 1; } static void pitch_pan_center_draw(void) { - char buf[4]; - int selected = (ACTIVE_PAGE.selected_widget == 16); - song_instrument_t *ins = song_get_instrument(current_instrument); + char buf[4]; + int selected = (ACTIVE_PAGE.selected_widget == 16); + song_instrument_t *ins = song_get_instrument(current_instrument); - draw_text(get_note_string(ins->pitch_pan_center + 1, buf), 54, 45, selected ? 3 : 2, 0); + draw_text(get_note_string(ins->pitch_pan_center + 1, buf), 54, 45, selected ? 3 : 2, 0); } /* --------------------------------------------------------------------------------------------------------- */ @@ -1890,224 +1962,230 @@ static void do_ins_save(void *p) { - char *ptr = (char *)p; - if (song_save_instrument(current_instrument, ptr)) - status_text_flash("Instrument saved (instrument %d)", current_instrument); - else - status_text_flash("Error: Instrument %d NOT saved! (No Filename?)", current_instrument); - free(ptr); + char *ptr = (char *)p; + if (song_save_instrument(current_instrument, ptr)) + status_text_flash("Instrument saved (instrument %d)", current_instrument); + else + status_text_flash("Error: Instrument %d NOT saved! (No Filename?)", current_instrument); + free(ptr); } static void instrument_save(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); - char *ptr = (char *) dmoz_path_concat(cfg_dir_instruments, ins->filename); - struct stat buf; - - if (stat(ptr, &buf) == 0) { - if (S_ISDIR(buf.st_mode)) { - status_text_flash("%s is a directory", ins->filename); - return; - } else if (S_ISREG(buf.st_mode)) { - dialog_create(DIALOG_OK_CANCEL, - "Overwrite file?", do_ins_save, - free, 1, ptr); - return; - } else { - status_text_flash("%s is not a regular file", ins->filename); - return; - } - } - if (song_save_instrument(current_instrument, ptr)) - status_text_flash("Instrument saved (instrument %d)", current_instrument); - else - status_text_flash("Error: Instrument %d NOT saved! (No Filename?)", current_instrument); - free(ptr); + song_instrument_t *ins = song_get_instrument(current_instrument); + char *ptr = (char *) dmoz_path_concat(cfg_dir_instruments, ins->filename); + struct stat buf; + + if (stat(ptr, &buf) == 0) { + if (S_ISDIR(buf.st_mode)) { + status_text_flash("%s is a directory", ins->filename); + return; + } else if (S_ISREG(buf.st_mode)) { + dialog_create(DIALOG_OK_CANCEL, + "Overwrite file?", do_ins_save, + free, 1, ptr); + return; + } else { + status_text_flash("%s is not a regular file", ins->filename); + return; + } + } + if (song_save_instrument(current_instrument, ptr)) + status_text_flash("Instrument saved (instrument %d)", current_instrument); + else + status_text_flash("Error: Instrument %d NOT saved! (No Filename?)", current_instrument); + free(ptr); } static void do_delete_inst(UNUSED void *ign) { - song_delete_instrument(current_instrument); + song_delete_instrument(current_instrument); } static void instrument_list_handle_alt_key(struct key_event *k) { - /* song_instrument_t *ins = song_get_instrument(current_instrument); */ + /* song_instrument_t *ins = song_get_instrument(current_instrument); */ - if (k->state) return; - switch (k->sym) { - case SDLK_n: - song_toggle_multichannel_mode(); - return; - case SDLK_o: - instrument_save(); - return; - case SDLK_r: - smpprompt_create("Replace instrument with:", "Instrument", do_replace_instrument); - return; - case SDLK_s: - // extra space to align the text like IT - smpprompt_create("Swap instrument with: ", "Instrument", do_swap_instrument); - return; - case SDLK_x: - smpprompt_create("Exchange instrument with:", "Instrument", do_exchange_instrument); - return; - case SDLK_p: - smpprompt_create("Copy instrument:", "Instrument", do_copy_instrument); - return; - case SDLK_w: - song_wipe_instrument(current_instrument); - break; - case SDLK_d: - dialog_create(DIALOG_OK_CANCEL, - "Delete Instrument?", - do_delete_inst, NULL, 1, NULL); - return; - default: - return; - } + if (k->state == KEY_RELEASE) + return; + switch (k->sym) { + case SDLK_n: + song_toggle_multichannel_mode(); + return; + case SDLK_o: + instrument_save(); + return; + case SDLK_r: + smpprompt_create("Replace instrument with:", "Instrument", do_replace_instrument); + return; + case SDLK_s: + // extra space to align the text like IT + smpprompt_create("Swap instrument with: ", "Instrument", do_swap_instrument); + return; + case SDLK_x: + smpprompt_create("Exchange instrument with:", "Instrument", do_exchange_instrument); + return; + case SDLK_p: + smpprompt_create("Copy instrument:", "Instrument", do_copy_instrument); + return; + case SDLK_w: + song_wipe_instrument(current_instrument); + break; + case SDLK_d: + dialog_create(DIALOG_OK_CANCEL, + "Delete Instrument?", + do_delete_inst, NULL, 1, NULL); + return; + default: + return; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static int instrument_list_pre_handle_key(struct key_event * k) { - // Only handle plain F4 key when no dialog is active. - if (status.dialog_type != DIALOG_NONE || k->sym != SDLK_F4 || (k->mod & (KMOD_CTRL | KMOD_ALT))) - return 0; - if (k->state) - return 1; - - if (song_is_instrument_mode()) { - int csamp = sample_get_current(); - sample_synchronize_to_instrument(); - if (csamp != sample_get_current()) - return 0; - } - - if (k->mod & KMOD_SHIFT) { - switch (status.current_page) { - default: - case PAGE_INSTRUMENT_LIST_VOLUME: set_subpage(PAGE_INSTRUMENT_LIST_GENERAL); break; - case PAGE_INSTRUMENT_LIST_PANNING: set_subpage(PAGE_INSTRUMENT_LIST_VOLUME); break; - case PAGE_INSTRUMENT_LIST_PITCH: set_subpage(PAGE_INSTRUMENT_LIST_PANNING); break; - case PAGE_INSTRUMENT_LIST_GENERAL: set_subpage(PAGE_INSTRUMENT_LIST_PITCH); break; - } - } else { - switch (status.current_page) { - default: - case PAGE_INSTRUMENT_LIST_PITCH: set_subpage(PAGE_INSTRUMENT_LIST_GENERAL); break; - case PAGE_INSTRUMENT_LIST_GENERAL: set_subpage(PAGE_INSTRUMENT_LIST_VOLUME); break; - case PAGE_INSTRUMENT_LIST_VOLUME: set_subpage(PAGE_INSTRUMENT_LIST_PANNING); break; - case PAGE_INSTRUMENT_LIST_PANNING: set_subpage(PAGE_INSTRUMENT_LIST_PITCH); break; - } - } - return 1; + // Only handle plain F4 key when no dialog is active. + if (status.dialog_type != DIALOG_NONE || k->sym != SDLK_F4 || (k->mod & (KMOD_CTRL | KMOD_ALT))) + return 0; + if (k->state == KEY_RELEASE) + return 1; + + if (song_is_instrument_mode()) { + int csamp = sample_get_current(); + sample_synchronize_to_instrument(); + if (csamp != sample_get_current()) + return 0; + } + + if (k->mod & KMOD_SHIFT) { + switch (status.current_page) { + default: + case PAGE_INSTRUMENT_LIST_VOLUME: set_subpage(PAGE_INSTRUMENT_LIST_GENERAL); break; + case PAGE_INSTRUMENT_LIST_PANNING: set_subpage(PAGE_INSTRUMENT_LIST_VOLUME); break; + case PAGE_INSTRUMENT_LIST_PITCH: set_subpage(PAGE_INSTRUMENT_LIST_PANNING); break; + case PAGE_INSTRUMENT_LIST_GENERAL: set_subpage(PAGE_INSTRUMENT_LIST_PITCH); break; + } + } else { + switch (status.current_page) { + default: + case PAGE_INSTRUMENT_LIST_PITCH: set_subpage(PAGE_INSTRUMENT_LIST_GENERAL); break; + case PAGE_INSTRUMENT_LIST_GENERAL: set_subpage(PAGE_INSTRUMENT_LIST_VOLUME); break; + case PAGE_INSTRUMENT_LIST_VOLUME: set_subpage(PAGE_INSTRUMENT_LIST_PANNING); break; + case PAGE_INSTRUMENT_LIST_PANNING: set_subpage(PAGE_INSTRUMENT_LIST_PITCH); break; + } + } + return 1; } static void instrument_list_handle_key(struct key_event * k) { - switch (k->sym) { - case SDLK_COMMA: - if (NO_MODIFIER(k->mod)) { - if (!(status.flags & CLASSIC_MODE) - && ACTIVE_PAGE.selected_widget == 5) return; - } - case SDLK_LESS: - if (k->state) return; - song_change_current_play_channel(-1, 0); - return; - case SDLK_PERIOD: - if (NO_MODIFIER(k->mod)) { - if (!(status.flags & CLASSIC_MODE) - && ACTIVE_PAGE.selected_widget == 5) return; - } - case SDLK_GREATER: - if (k->state) return; - song_change_current_play_channel(1, 0); - return; - - case SDLK_PAGEUP: - if (k->state) return; - instrument_set(current_instrument - 1); - break; - case SDLK_PAGEDOWN: - if (k->state) return; - instrument_set(current_instrument + 1); - break; - case SDLK_ESCAPE: - if ((k->mod & KMOD_SHIFT) || instrument_cursor_pos < 25) { - if (k->state) return; - instrument_cursor_pos = 25; - get_page_widgets()->accept_text = 0; - change_focus_to(0); - status.flags |= NEED_UPDATE; - return; - } - return; - default: - if (k->mod & (KMOD_ALT)) { - instrument_list_handle_alt_key(k); - } else { - int n, v; - - if (k->midi_note > -1) { - n = k->midi_note; - if (k->midi_volume > -1) { - v = k->midi_volume / 2; - } else { - v = 64; - } - } else { - v = 64; - n = kbd_get_note(k); - if (n <= 0 || n > 120) - return; - } - - if (k->state) { - song_keyup(0, current_instrument, n); - status.last_keysym = 0; - } else if (!k->is_repeat) { - song_keydown(KEYJAZZ_NOINST, current_instrument, n, v, KEYJAZZ_CHAN_CURRENT); - } - last_note = n; - } - return; - } + switch (k->sym) { + case SDLK_COMMA: + if (NO_MODIFIER(k->mod)) { + if (!(status.flags & CLASSIC_MODE) + && ACTIVE_PAGE.selected_widget == 5) return; + } + case SDLK_LESS: + if (k->state == KEY_RELEASE) + return; + song_change_current_play_channel(-1, 0); + return; + case SDLK_PERIOD: + if (NO_MODIFIER(k->mod)) { + if (!(status.flags & CLASSIC_MODE) + && ACTIVE_PAGE.selected_widget == 5) return; + } + case SDLK_GREATER: + if (k->state == KEY_RELEASE) + return; + song_change_current_play_channel(1, 0); + return; + + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return; + instrument_set(current_instrument - 1); + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return; + instrument_set(current_instrument + 1); + break; + case SDLK_ESCAPE: + if ((k->mod & KMOD_SHIFT) || instrument_cursor_pos < 25) { + if (k->state == KEY_RELEASE) + return; + instrument_cursor_pos = 25; + get_page_widgets()->accept_text = 0; + change_focus_to(0); + status.flags |= NEED_UPDATE; + return; + } + return; + default: + if (k->mod & (KMOD_ALT)) { + instrument_list_handle_alt_key(k); + } else { + int n, v; + + if (k->midi_note > -1) { + n = k->midi_note; + if (k->midi_volume > -1) { + v = k->midi_volume / 2; + } else { + v = 64; + } + } else { + v = 64; + n = kbd_get_note(k); + if (n <= 0 || n > 120) + return; + } + + if (k->state == KEY_RELEASE) { + song_keyup(0, current_instrument, n); + status.last_keysym = 0; + } else if (!k->is_repeat) { + song_keydown(KEYJAZZ_NOINST, current_instrument, n, v, KEYJAZZ_CHAN_CURRENT); + } + last_note = n; + } + return; + } } /* --------------------------------------------------------------------- */ static void set_subpage(int page) { - int widget = ACTIVE_PAGE.selected_widget; - int b = 1; - switch (page) { - case PAGE_INSTRUMENT_LIST_GENERAL: b = 1; break; - case PAGE_INSTRUMENT_LIST_VOLUME: b = 2; break; - case PAGE_INSTRUMENT_LIST_PANNING: b = 3; break; - case PAGE_INSTRUMENT_LIST_PITCH: b = 4; break; - default: return; - }; - togglebutton_set(pages[page].widgets, b, 0); - set_page(page); - if (widget >= ACTIVE_PAGE.total_widgets) - widget = ACTIVE_PAGE.total_widgets - 1; - ACTIVE_PAGE.selected_widget = widget; - instrument_list_subpage = page; - status.flags |= NEED_UPDATE; + int widget = ACTIVE_PAGE.selected_widget; + int b = 1; + switch (page) { + case PAGE_INSTRUMENT_LIST_GENERAL: b = 1; break; + case PAGE_INSTRUMENT_LIST_VOLUME: b = 2; break; + case PAGE_INSTRUMENT_LIST_PANNING: b = 3; break; + case PAGE_INSTRUMENT_LIST_PITCH: b = 4; break; + default: return; + }; + togglebutton_set(pages[page].widgets, b, 0); + set_page(page); + if (widget >= ACTIVE_PAGE.total_widgets) + widget = ACTIVE_PAGE.total_widgets - 1; + ACTIVE_PAGE.selected_widget = widget; + instrument_list_subpage = page; + status.flags |= NEED_UPDATE; } static void change_subpage(void) { - int widget = ACTIVE_PAGE.selected_widget; - int p[] = { - PAGE_INSTRUMENT_LIST_GENERAL, - PAGE_INSTRUMENT_LIST_VOLUME, - PAGE_INSTRUMENT_LIST_PANNING, - PAGE_INSTRUMENT_LIST_PITCH, - }; - set_subpage(p[CLAMP(widget - 1, 0, 3)]); + int widget = ACTIVE_PAGE.selected_widget; + int p[] = { + PAGE_INSTRUMENT_LIST_GENERAL, + PAGE_INSTRUMENT_LIST_VOLUME, + PAGE_INSTRUMENT_LIST_PANNING, + PAGE_INSTRUMENT_LIST_PITCH, + }; + set_subpage(p[CLAMP(widget - 1, 0, 3)]); } /* --------------------------------------------------------------------- */ @@ -2115,121 +2193,121 @@ static void instrument_list_general_predraw_hook(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - togglebutton_set(widgets_general, 6 + (ins->nna % 4), 0); - togglebutton_set(widgets_general, 10 + (ins->dct % 4), 0); - togglebutton_set(widgets_general, 14 + (ins->dca % 3), 0); + togglebutton_set(widgets_general, 6 + (ins->nna % 4), 0); + togglebutton_set(widgets_general, 10 + (ins->dct % 4), 0); + togglebutton_set(widgets_general, 14 + (ins->dca % 3), 0); - widgets_general[17].d.textentry.text = ins->filename; + widgets_general[17].d.textentry.text = ins->filename; } static void instrument_list_volume_predraw_hook(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - widgets_volume[6].d.toggle.state = !!(ins->flags & ENV_VOLUME); - widgets_volume[7].d.toggle.state = !!(ins->flags & ENV_VOLCARRY); - widgets_volume[8].d.toggle.state = !!(ins->flags & ENV_VOLLOOP); - widgets_volume[11].d.toggle.state = !!(ins->flags & ENV_VOLSUSTAIN); - - /* FIXME: this is the wrong place for this. - ... and it's probably not even right -- how does Impulse Tracker handle loop constraints? - See below for panning/pitch envelopes; same deal there. */ - if (ins->vol_env.loop_start > ins->vol_env.loop_end) - ins->vol_env.loop_end = ins->vol_env.loop_start; - if (ins->vol_env.sustain_start > ins->vol_env.sustain_end) - ins->vol_env.sustain_end = ins->vol_env.sustain_start; - - widgets_volume[9].d.numentry.max = ins->vol_env.nodes - 1; - widgets_volume[10].d.numentry.max = ins->vol_env.nodes - 1; - widgets_volume[12].d.numentry.max = ins->vol_env.nodes - 1; - widgets_volume[13].d.numentry.max = ins->vol_env.nodes - 1; - - widgets_volume[9].d.numentry.value = ins->vol_env.loop_start; - widgets_volume[10].d.numentry.value = ins->vol_env.loop_end; - widgets_volume[12].d.numentry.value = ins->vol_env.sustain_start; - widgets_volume[13].d.numentry.value = ins->vol_env.sustain_end; - - /* current_song hack: shifting values all over the place here, ugh */ - widgets_volume[14].d.thumbbar.value = ins->global_volume; - widgets_volume[15].d.thumbbar.value = ins->fadeout >> 5; - widgets_volume[16].d.thumbbar.value = ins->vol_swing; + widgets_volume[6].d.toggle.state = !!(ins->flags & ENV_VOLUME); + widgets_volume[7].d.toggle.state = !!(ins->flags & ENV_VOLCARRY); + widgets_volume[8].d.toggle.state = !!(ins->flags & ENV_VOLLOOP); + widgets_volume[11].d.toggle.state = !!(ins->flags & ENV_VOLSUSTAIN); + + /* FIXME: this is the wrong place for this. + ... and it's probably not even right -- how does Impulse Tracker handle loop constraints? + See below for panning/pitch envelopes; same deal there. */ + if (ins->vol_env.loop_start > ins->vol_env.loop_end) + ins->vol_env.loop_end = ins->vol_env.loop_start; + if (ins->vol_env.sustain_start > ins->vol_env.sustain_end) + ins->vol_env.sustain_end = ins->vol_env.sustain_start; + + widgets_volume[9].d.numentry.max = ins->vol_env.nodes - 1; + widgets_volume[10].d.numentry.max = ins->vol_env.nodes - 1; + widgets_volume[12].d.numentry.max = ins->vol_env.nodes - 1; + widgets_volume[13].d.numentry.max = ins->vol_env.nodes - 1; + + widgets_volume[9].d.numentry.value = ins->vol_env.loop_start; + widgets_volume[10].d.numentry.value = ins->vol_env.loop_end; + widgets_volume[12].d.numentry.value = ins->vol_env.sustain_start; + widgets_volume[13].d.numentry.value = ins->vol_env.sustain_end; + + /* current_song hack: shifting values all over the place here, ugh */ + widgets_volume[14].d.thumbbar.value = ins->global_volume; + widgets_volume[15].d.thumbbar.value = ins->fadeout >> 5; + widgets_volume[16].d.thumbbar.value = ins->vol_swing; } static void instrument_list_panning_predraw_hook(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - widgets_panning[6].d.toggle.state = !!(ins->flags & ENV_PANNING); - widgets_panning[7].d.toggle.state = !!(ins->flags & ENV_PANCARRY); - widgets_panning[8].d.toggle.state = !!(ins->flags & ENV_PANLOOP); - widgets_panning[11].d.toggle.state = !!(ins->flags & ENV_PANSUSTAIN); - - if (ins->pan_env.loop_start > ins->pan_env.loop_end) - ins->pan_env.loop_end = ins->pan_env.loop_start; - if (ins->pan_env.sustain_start > ins->pan_env.sustain_end) - ins->pan_env.sustain_end = ins->pan_env.sustain_start; - - widgets_panning[9].d.numentry.max = ins->pan_env.nodes - 1; - widgets_panning[10].d.numentry.max = ins->pan_env.nodes - 1; - widgets_panning[12].d.numentry.max = ins->pan_env.nodes - 1; - widgets_panning[13].d.numentry.max = ins->pan_env.nodes - 1; - - widgets_panning[9].d.numentry.value = ins->pan_env.loop_start; - widgets_panning[10].d.numentry.value = ins->pan_env.loop_end; - widgets_panning[12].d.numentry.value = ins->pan_env.sustain_start; - widgets_panning[13].d.numentry.value = ins->pan_env.sustain_end; - - widgets_panning[14].d.toggle.state = !!(ins->flags & ENV_SETPANNING); - widgets_panning[15].d.thumbbar.value = ins->panning >> 2; - /* (widgets_panning[16] is the pitch-pan center) */ - widgets_panning[17].d.thumbbar.value = ins->pitch_pan_separation; - widgets_panning[18].d.thumbbar.value = ins->pan_swing; + widgets_panning[6].d.toggle.state = !!(ins->flags & ENV_PANNING); + widgets_panning[7].d.toggle.state = !!(ins->flags & ENV_PANCARRY); + widgets_panning[8].d.toggle.state = !!(ins->flags & ENV_PANLOOP); + widgets_panning[11].d.toggle.state = !!(ins->flags & ENV_PANSUSTAIN); + + if (ins->pan_env.loop_start > ins->pan_env.loop_end) + ins->pan_env.loop_end = ins->pan_env.loop_start; + if (ins->pan_env.sustain_start > ins->pan_env.sustain_end) + ins->pan_env.sustain_end = ins->pan_env.sustain_start; + + widgets_panning[9].d.numentry.max = ins->pan_env.nodes - 1; + widgets_panning[10].d.numentry.max = ins->pan_env.nodes - 1; + widgets_panning[12].d.numentry.max = ins->pan_env.nodes - 1; + widgets_panning[13].d.numentry.max = ins->pan_env.nodes - 1; + + widgets_panning[9].d.numentry.value = ins->pan_env.loop_start; + widgets_panning[10].d.numentry.value = ins->pan_env.loop_end; + widgets_panning[12].d.numentry.value = ins->pan_env.sustain_start; + widgets_panning[13].d.numentry.value = ins->pan_env.sustain_end; + + widgets_panning[14].d.toggle.state = !!(ins->flags & ENV_SETPANNING); + widgets_panning[15].d.thumbbar.value = ins->panning >> 2; + /* (widgets_panning[16] is the pitch-pan center) */ + widgets_panning[17].d.thumbbar.value = ins->pitch_pan_separation; + widgets_panning[18].d.thumbbar.value = ins->pan_swing; } static void instrument_list_pitch_predraw_hook(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - widgets_pitch[6].d.menutoggle.state = ((ins->flags & ENV_PITCH) - ? ((ins->flags & ENV_FILTER) - ? 2 : 1) : 0); - widgets_pitch[7].d.toggle.state = !!(ins->flags & ENV_PITCHCARRY); - widgets_pitch[8].d.toggle.state = !!(ins->flags & ENV_PITCHLOOP); - widgets_pitch[11].d.toggle.state = !!(ins->flags & ENV_PITCHSUSTAIN); - - if (ins->pitch_env.loop_start > ins->pitch_env.loop_end) - ins->pitch_env.loop_end = ins->pitch_env.loop_start; - if (ins->pitch_env.sustain_start > ins->pitch_env.sustain_end) - ins->pitch_env.sustain_end = ins->pitch_env.sustain_start; - - widgets_pitch[9].d.numentry.max = ins->pitch_env.nodes - 1; - widgets_pitch[10].d.numentry.max = ins->pitch_env.nodes - 1; - widgets_pitch[12].d.numentry.max = ins->pitch_env.nodes - 1; - widgets_pitch[13].d.numentry.max = ins->pitch_env.nodes - 1; - - widgets_pitch[9].d.numentry.value = ins->pitch_env.loop_start; - widgets_pitch[10].d.numentry.value = ins->pitch_env.loop_end; - widgets_pitch[12].d.numentry.value = ins->pitch_env.sustain_start; - widgets_pitch[13].d.numentry.value = ins->pitch_env.sustain_end; - - if (ins->ifc & 0x80) - widgets_pitch[14].d.thumbbar.value = ins->ifc & 0x7f; - else - widgets_pitch[14].d.thumbbar.value = -1; - if (ins->ifr & 0x80) - widgets_pitch[15].d.thumbbar.value = ins->ifr & 0x7f; - else - widgets_pitch[15].d.thumbbar.value = -1; - - /* printf("ins%02d: ch%04d pgm%04d bank%06d drum%04d\n", current_instrument, - ins->midi_channel, ins->midi_program, ins->midi_bank, ins->midi_drum_key); */ - widgets_pitch[16].d.bitset.value = ins->midi_channel_mask; - widgets_pitch[17].d.thumbbar.value = (signed char) ins->midi_program; - widgets_pitch[18].d.thumbbar.value = (signed char) (ins->midi_bank & 0xff); - widgets_pitch[19].d.thumbbar.value = (signed char) (ins->midi_bank >> 8); - /* what is midi_drum_key for? */ + widgets_pitch[6].d.menutoggle.state = ((ins->flags & ENV_PITCH) + ? ((ins->flags & ENV_FILTER) + ? 2 : 1) : 0); + widgets_pitch[7].d.toggle.state = !!(ins->flags & ENV_PITCHCARRY); + widgets_pitch[8].d.toggle.state = !!(ins->flags & ENV_PITCHLOOP); + widgets_pitch[11].d.toggle.state = !!(ins->flags & ENV_PITCHSUSTAIN); + + if (ins->pitch_env.loop_start > ins->pitch_env.loop_end) + ins->pitch_env.loop_end = ins->pitch_env.loop_start; + if (ins->pitch_env.sustain_start > ins->pitch_env.sustain_end) + ins->pitch_env.sustain_end = ins->pitch_env.sustain_start; + + widgets_pitch[9].d.numentry.max = ins->pitch_env.nodes - 1; + widgets_pitch[10].d.numentry.max = ins->pitch_env.nodes - 1; + widgets_pitch[12].d.numentry.max = ins->pitch_env.nodes - 1; + widgets_pitch[13].d.numentry.max = ins->pitch_env.nodes - 1; + + widgets_pitch[9].d.numentry.value = ins->pitch_env.loop_start; + widgets_pitch[10].d.numentry.value = ins->pitch_env.loop_end; + widgets_pitch[12].d.numentry.value = ins->pitch_env.sustain_start; + widgets_pitch[13].d.numentry.value = ins->pitch_env.sustain_end; + + if (ins->ifc & 0x80) + widgets_pitch[14].d.thumbbar.value = ins->ifc & 0x7f; + else + widgets_pitch[14].d.thumbbar.value = -1; + if (ins->ifr & 0x80) + widgets_pitch[15].d.thumbbar.value = ins->ifr & 0x7f; + else + widgets_pitch[15].d.thumbbar.value = -1; + + /* printf("ins%02d: ch%04d pgm%04d bank%06d drum%04d\n", current_instrument, + ins->midi_channel, ins->midi_program, ins->midi_bank, ins->midi_drum_key); */ + widgets_pitch[16].d.bitset.value = ins->midi_channel_mask; + widgets_pitch[17].d.thumbbar.value = (signed char) ins->midi_program; + widgets_pitch[18].d.thumbbar.value = (signed char) (ins->midi_bank & 0xff); + widgets_pitch[19].d.thumbbar.value = (signed char) (ins->midi_bank >> 8); + /* what is midi_drum_key for? */ } /* --------------------------------------------------------------------- */ @@ -2237,143 +2315,143 @@ static void instrument_list_general_update_values(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - status.flags |= SONG_NEEDS_SAVE; - for (ins->nna = 4; ins->nna--;) - if (widgets_general[ins->nna + 6].d.togglebutton.state) - break; - for (ins->dct = 4; ins->dct--;) - if (widgets_general[ins->dct + 10].d.togglebutton.state) - break; - for (ins->dca = 3; ins->dca--;) - if (widgets_general[ins->dca + 14].d.togglebutton.state) - break; + status.flags |= SONG_NEEDS_SAVE; + for (ins->nna = 4; ins->nna--;) + if (widgets_general[ins->nna + 6].d.togglebutton.state) + break; + for (ins->dct = 4; ins->dct--;) + if (widgets_general[ins->dct + 10].d.togglebutton.state) + break; + for (ins->dca = 3; ins->dca--;) + if (widgets_general[ins->dca + 14].d.togglebutton.state) + break; } static void update_filename(void) { - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } #define CHECK_SET(a,b,c) if (a != b) { a = b; c; } static void instrument_list_volume_update_values(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - status.flags |= SONG_NEEDS_SAVE; - ins->flags &= ~(ENV_VOLUME | ENV_VOLCARRY | ENV_VOLLOOP | ENV_VOLSUSTAIN); - if (widgets_volume[6].d.toggle.state) - ins->flags |= ENV_VOLUME; - if (widgets_volume[7].d.toggle.state) - ins->flags |= ENV_VOLCARRY; - if (widgets_volume[8].d.toggle.state) - ins->flags |= ENV_VOLLOOP; - if (widgets_volume[11].d.toggle.state) - ins->flags |= ENV_VOLSUSTAIN; - - CHECK_SET(ins->vol_env.loop_start, widgets_volume[9].d.numentry.value, - ins->flags |= ENV_VOLLOOP); - CHECK_SET(ins->vol_env.loop_end, widgets_volume[10].d.numentry.value, - ins->flags |= ENV_VOLLOOP); - CHECK_SET(ins->vol_env.sustain_start, widgets_volume[12].d.numentry.value, - ins->flags |= ENV_VOLSUSTAIN); - CHECK_SET(ins->vol_env.sustain_end, widgets_volume[13].d.numentry.value, - ins->flags |= ENV_VOLSUSTAIN); - - /* more ugly shifts */ - ins->global_volume = widgets_volume[14].d.thumbbar.value; - ins->fadeout = widgets_volume[15].d.thumbbar.value << 5; - ins->vol_swing = widgets_volume[16].d.thumbbar.value; + status.flags |= SONG_NEEDS_SAVE; + ins->flags &= ~(ENV_VOLUME | ENV_VOLCARRY | ENV_VOLLOOP | ENV_VOLSUSTAIN); + if (widgets_volume[6].d.toggle.state) + ins->flags |= ENV_VOLUME; + if (widgets_volume[7].d.toggle.state) + ins->flags |= ENV_VOLCARRY; + if (widgets_volume[8].d.toggle.state) + ins->flags |= ENV_VOLLOOP; + if (widgets_volume[11].d.toggle.state) + ins->flags |= ENV_VOLSUSTAIN; + + CHECK_SET(ins->vol_env.loop_start, widgets_volume[9].d.numentry.value, + ins->flags |= ENV_VOLLOOP); + CHECK_SET(ins->vol_env.loop_end, widgets_volume[10].d.numentry.value, + ins->flags |= ENV_VOLLOOP); + CHECK_SET(ins->vol_env.sustain_start, widgets_volume[12].d.numentry.value, + ins->flags |= ENV_VOLSUSTAIN); + CHECK_SET(ins->vol_env.sustain_end, widgets_volume[13].d.numentry.value, + ins->flags |= ENV_VOLSUSTAIN); + + /* more ugly shifts */ + ins->global_volume = widgets_volume[14].d.thumbbar.value; + ins->fadeout = widgets_volume[15].d.thumbbar.value << 5; + ins->vol_swing = widgets_volume[16].d.thumbbar.value; - song_update_playing_instrument(current_instrument); + song_update_playing_instrument(current_instrument); } static void instrument_list_panning_update_values(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); - int n; + song_instrument_t *ins = song_get_instrument(current_instrument); + int n; - status.flags |= SONG_NEEDS_SAVE; - ins->flags &= ~(ENV_PANNING | ENV_PANCARRY | ENV_PANLOOP | ENV_PANSUSTAIN | ENV_SETPANNING); - if (widgets_panning[6].d.toggle.state) - ins->flags |= ENV_PANNING; - if (widgets_panning[7].d.toggle.state) - ins->flags |= ENV_PANCARRY; - if (widgets_panning[8].d.toggle.state) - ins->flags |= ENV_PANLOOP; - if (widgets_panning[11].d.toggle.state) - ins->flags |= ENV_PANSUSTAIN; - if (widgets_panning[14].d.toggle.state) - ins->flags |= ENV_SETPANNING; - - CHECK_SET(ins->pan_env.loop_start, widgets_panning[9].d.numentry.value, - ins->flags |= ENV_PANLOOP); - CHECK_SET(ins->pan_env.loop_end, widgets_panning[10].d.numentry.value, - ins->flags |= ENV_PANLOOP); - CHECK_SET(ins->pan_env.sustain_start, widgets_panning[12].d.numentry.value, - ins->flags |= ENV_PANSUSTAIN); - CHECK_SET(ins->pan_env.sustain_end, widgets_panning[13].d.numentry.value, - ins->flags |= ENV_PANSUSTAIN); - - n = widgets_panning[15].d.thumbbar.value << 2; - if (ins->panning != (unsigned int)n) { - ins->panning = (unsigned int)n; - ins->flags |= ENV_SETPANNING; - } - /* (widgets_panning[16] is the pitch-pan center) */ - ins->pitch_pan_separation = widgets_panning[17].d.thumbbar.value; - ins->pan_swing = widgets_panning[18].d.thumbbar.value; + status.flags |= SONG_NEEDS_SAVE; + ins->flags &= ~(ENV_PANNING | ENV_PANCARRY | ENV_PANLOOP | ENV_PANSUSTAIN | ENV_SETPANNING); + if (widgets_panning[6].d.toggle.state) + ins->flags |= ENV_PANNING; + if (widgets_panning[7].d.toggle.state) + ins->flags |= ENV_PANCARRY; + if (widgets_panning[8].d.toggle.state) + ins->flags |= ENV_PANLOOP; + if (widgets_panning[11].d.toggle.state) + ins->flags |= ENV_PANSUSTAIN; + if (widgets_panning[14].d.toggle.state) + ins->flags |= ENV_SETPANNING; + + CHECK_SET(ins->pan_env.loop_start, widgets_panning[9].d.numentry.value, + ins->flags |= ENV_PANLOOP); + CHECK_SET(ins->pan_env.loop_end, widgets_panning[10].d.numentry.value, + ins->flags |= ENV_PANLOOP); + CHECK_SET(ins->pan_env.sustain_start, widgets_panning[12].d.numentry.value, + ins->flags |= ENV_PANSUSTAIN); + CHECK_SET(ins->pan_env.sustain_end, widgets_panning[13].d.numentry.value, + ins->flags |= ENV_PANSUSTAIN); + + n = widgets_panning[15].d.thumbbar.value << 2; + if (ins->panning != (unsigned int)n) { + ins->panning = (unsigned int)n; + ins->flags |= ENV_SETPANNING; + } + /* (widgets_panning[16] is the pitch-pan center) */ + ins->pitch_pan_separation = widgets_panning[17].d.thumbbar.value; + ins->pan_swing = widgets_panning[18].d.thumbbar.value; - song_update_playing_instrument(current_instrument); + song_update_playing_instrument(current_instrument); } static void instrument_list_pitch_update_values(void) { - song_instrument_t *ins = song_get_instrument(current_instrument); + song_instrument_t *ins = song_get_instrument(current_instrument); - status.flags |= SONG_NEEDS_SAVE; - ins->flags &= ~(ENV_PITCH | ENV_PITCHCARRY | ENV_PITCHLOOP | ENV_PITCHSUSTAIN | ENV_FILTER); + status.flags |= SONG_NEEDS_SAVE; + ins->flags &= ~(ENV_PITCH | ENV_PITCHCARRY | ENV_PITCHLOOP | ENV_PITCHSUSTAIN | ENV_FILTER); - switch (widgets_pitch[6].d.menutoggle.state) { - case 2: ins->flags |= ENV_FILTER; - case 1: ins->flags |= ENV_PITCH; - } - - if (widgets_pitch[6].d.menutoggle.state) - ins->flags |= ENV_PITCH; - if (widgets_pitch[7].d.toggle.state) - ins->flags |= ENV_PITCHCARRY; - if (widgets_pitch[8].d.toggle.state) - ins->flags |= ENV_PITCHLOOP; - if (widgets_pitch[11].d.toggle.state) - ins->flags |= ENV_PITCHSUSTAIN; - - CHECK_SET(ins->pitch_env.loop_start, widgets_pitch[9].d.numentry.value, - ins->flags |= ENV_PITCHLOOP); - CHECK_SET(ins->pitch_env.loop_end, widgets_pitch[10].d.numentry.value, - ins->flags |= ENV_PITCHLOOP); - CHECK_SET(ins->pitch_env.sustain_start, widgets_pitch[12].d.numentry.value, - ins->flags |= ENV_PITCHSUSTAIN); - CHECK_SET(ins->pitch_env.sustain_end, widgets_pitch[13].d.numentry.value, - ins->flags |= ENV_PITCHSUSTAIN); - if (widgets_pitch[14].d.thumbbar.value > -1) { - ins->ifc = widgets_pitch[14].d.thumbbar.value | 0x80; - } else { - ins->ifc = 0x7f; - } - if (widgets_pitch[15].d.thumbbar.value > -1) { - ins->ifr = widgets_pitch[15].d.thumbbar.value | 0x80; - } else { - ins->ifr = 0x7f; - } - ins->midi_channel_mask = widgets_pitch[16].d.bitset.value; - ins->midi_program = widgets_pitch[17].d.thumbbar.value; - ins->midi_bank = ((widgets_pitch[19].d.thumbbar.value << 8) - | (widgets_pitch[18].d.thumbbar.value & 0xff)); + switch (widgets_pitch[6].d.menutoggle.state) { + case 2: ins->flags |= ENV_FILTER; + case 1: ins->flags |= ENV_PITCH; + } + + if (widgets_pitch[6].d.menutoggle.state) + ins->flags |= ENV_PITCH; + if (widgets_pitch[7].d.toggle.state) + ins->flags |= ENV_PITCHCARRY; + if (widgets_pitch[8].d.toggle.state) + ins->flags |= ENV_PITCHLOOP; + if (widgets_pitch[11].d.toggle.state) + ins->flags |= ENV_PITCHSUSTAIN; + + CHECK_SET(ins->pitch_env.loop_start, widgets_pitch[9].d.numentry.value, + ins->flags |= ENV_PITCHLOOP); + CHECK_SET(ins->pitch_env.loop_end, widgets_pitch[10].d.numentry.value, + ins->flags |= ENV_PITCHLOOP); + CHECK_SET(ins->pitch_env.sustain_start, widgets_pitch[12].d.numentry.value, + ins->flags |= ENV_PITCHSUSTAIN); + CHECK_SET(ins->pitch_env.sustain_end, widgets_pitch[13].d.numentry.value, + ins->flags |= ENV_PITCHSUSTAIN); + if (widgets_pitch[14].d.thumbbar.value > -1) { + ins->ifc = widgets_pitch[14].d.thumbbar.value | 0x80; + } else { + ins->ifc = 0x7f; + } + if (widgets_pitch[15].d.thumbbar.value > -1) { + ins->ifr = widgets_pitch[15].d.thumbbar.value | 0x80; + } else { + ins->ifr = 0x7f; + } + ins->midi_channel_mask = widgets_pitch[16].d.bitset.value; + ins->midi_program = widgets_pitch[17].d.thumbbar.value; + ins->midi_bank = ((widgets_pitch[19].d.thumbbar.value << 8) + | (widgets_pitch[18].d.thumbbar.value & 0xff)); - song_update_playing_instrument(current_instrument); + song_update_playing_instrument(current_instrument); } /* --------------------------------------------------------------------- */ @@ -2381,129 +2459,129 @@ static void instrument_list_draw_const(void) { - draw_box(4, 12, 30, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(4, 12, 30, 48, BOX_THICK | BOX_INNER | BOX_INSET); } static void instrument_list_general_draw_const(void) { - int n; + int n; - instrument_list_draw_const(); + instrument_list_draw_const(); - draw_box(31, 15, 42, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(31, 15, 42, 48, BOX_THICK | BOX_INNER | BOX_INSET); - /* Kind of a hack, and not really useful, but... :) */ - if (status.flags & CLASSIC_MODE) { - draw_box(55, 46, 73, 48, BOX_THICK | BOX_INNER | BOX_INSET); - draw_text(" ", 69, 47, 1, 0); - } else { - draw_box(55, 46, 69, 48, BOX_THICK | BOX_INNER | BOX_INSET); - } - - draw_text("New Note Action", 54, 17, 0, 2); - draw_text("Duplicate Check Type & Action", 47, 32, 0, 2); - draw_text("Filename", 47, 47, 0, 2); - - for (n = 0; n < 35; n++) { - draw_char(134, 44 + n, 15, 0, 2); - draw_char(134, 44 + n, 30, 0, 2); - draw_char(154, 44 + n, 45, 0, 2); - } + /* Kind of a hack, and not really useful, but... :) */ + if (status.flags & CLASSIC_MODE) { + draw_box(55, 46, 73, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text(" ", 69, 47, 1, 0); + } else { + draw_box(55, 46, 69, 48, BOX_THICK | BOX_INNER | BOX_INSET); + } + + draw_text("New Note Action", 54, 17, 0, 2); + draw_text("Duplicate Check Type & Action", 47, 32, 0, 2); + draw_text("Filename", 47, 47, 0, 2); + + for (n = 0; n < 35; n++) { + draw_char(134, 44 + n, 15, 0, 2); + draw_char(134, 44 + n, 30, 0, 2); + draw_char(154, 44 + n, 45, 0, 2); + } } static void instrument_list_volume_draw_const(void) { - instrument_list_draw_const(); + instrument_list_draw_const(); - draw_fill_chars(57, 28, 62, 29, 0); - draw_fill_chars(57, 32, 62, 34, 0); - draw_fill_chars(57, 37, 62, 39, 0); - - draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 41, 71, 44, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 45, 71, 47, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_text("Volume Envelope", 38, 28, 0, 2); - draw_text("Carry", 48, 29, 0, 2); - draw_text("Envelope Loop", 40, 32, 0, 2); - draw_text("Loop Begin", 43, 33, 0, 2); - draw_text("Loop End", 45, 34, 0, 2); - draw_text("Sustain Loop", 41, 37, 0, 2); - draw_text("SusLoop Begin", 40, 38, 0, 2); - draw_text("SusLoop End", 42, 39, 0, 2); - draw_text("Global Volume", 40, 42, 0, 2); - draw_text("Fadeout", 46, 43, 0, 2); - draw_text("Volume Swing %", 39, 46, 0, 2); + draw_fill_chars(57, 28, 62, 29, 0); + draw_fill_chars(57, 32, 62, 34, 0); + draw_fill_chars(57, 37, 62, 39, 0); + + draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 41, 71, 44, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 45, 71, 47, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_text("Volume Envelope", 38, 28, 0, 2); + draw_text("Carry", 48, 29, 0, 2); + draw_text("Envelope Loop", 40, 32, 0, 2); + draw_text("Loop Begin", 43, 33, 0, 2); + draw_text("Loop End", 45, 34, 0, 2); + draw_text("Sustain Loop", 41, 37, 0, 2); + draw_text("SusLoop Begin", 40, 38, 0, 2); + draw_text("SusLoop End", 42, 39, 0, 2); + draw_text("Global Volume", 40, 42, 0, 2); + draw_text("Fadeout", 46, 43, 0, 2); + draw_text("Volume Swing %", 39, 46, 0, 2); } static void instrument_list_panning_draw_const(void) { - instrument_list_draw_const(); + instrument_list_draw_const(); - draw_fill_chars(57, 28, 62, 29, 0); - draw_fill_chars(57, 32, 62, 34, 0); - draw_fill_chars(57, 37, 62, 39, 0); - draw_fill_chars(57, 42, 62, 45, 0); - - draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 41, 63, 48, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_text("Panning Envelope", 37, 28, 0, 2); - draw_text("Carry", 48, 29, 0, 2); - draw_text("Envelope Loop", 40, 32, 0, 2); - draw_text("Loop Begin", 43, 33, 0, 2); - draw_text("Loop End", 45, 34, 0, 2); - draw_text("Sustain Loop", 41, 37, 0, 2); - draw_text("SusLoop Begin", 40, 38, 0, 2); - draw_text("SusLoop End", 42, 39, 0, 2); - draw_text("Default Pan", 42, 42, 0, 2); - draw_text("Pan Value", 44, 43, 0, 2); - draw_text("Pitch-Pan Center", 37, 45, 0, 2); - draw_text("Pitch-Pan Separation", 33, 46, 0, 2); - if (status.flags & CLASSIC_MODE) { - /* Hmm. The 's' in swing isn't capitalised. ;) */ - draw_text("Pan swing", 44, 47, 0, 2); - } else { - draw_text("Pan Swing", 44, 47, 0, 2); - } + draw_fill_chars(57, 28, 62, 29, 0); + draw_fill_chars(57, 32, 62, 34, 0); + draw_fill_chars(57, 37, 62, 39, 0); + draw_fill_chars(57, 42, 62, 45, 0); + + draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 41, 63, 48, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_text("Panning Envelope", 37, 28, 0, 2); + draw_text("Carry", 48, 29, 0, 2); + draw_text("Envelope Loop", 40, 32, 0, 2); + draw_text("Loop Begin", 43, 33, 0, 2); + draw_text("Loop End", 45, 34, 0, 2); + draw_text("Sustain Loop", 41, 37, 0, 2); + draw_text("SusLoop Begin", 40, 38, 0, 2); + draw_text("SusLoop End", 42, 39, 0, 2); + draw_text("Default Pan", 42, 42, 0, 2); + draw_text("Pan Value", 44, 43, 0, 2); + draw_text("Pitch-Pan Center", 37, 45, 0, 2); + draw_text("Pitch-Pan Separation", 33, 46, 0, 2); + if (status.flags & CLASSIC_MODE) { + /* Hmm. The 's' in swing isn't capitalised. ;) */ + draw_text("Pan swing", 44, 47, 0, 2); + } else { + draw_text("Pan Swing", 44, 47, 0, 2); + } - draw_text("\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a", 54, 44, 2, 0); + draw_text("\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a\x9a", 54, 44, 2, 0); } static void instrument_list_pitch_draw_const(void) { - instrument_list_draw_const(); + instrument_list_draw_const(); - draw_fill_chars(57, 28, 62, 29, 0); - draw_fill_chars(57, 32, 62, 34, 0); - draw_fill_chars(57, 37, 62, 39, 0); - - draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(53, 41, 71, 48, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_text("Frequency Envelope", 35, 28, 0, 2); - draw_text("Carry", 48, 29, 0, 2); - draw_text("Envelope Loop", 40, 32, 0, 2); - draw_text("Loop Begin", 43, 33, 0, 2); - draw_text("Loop End", 45, 34, 0, 2); - draw_text("Sustain Loop", 41, 37, 0, 2); - draw_text("SusLoop Begin", 40, 38, 0, 2); - draw_text("SusLoop End", 42, 39, 0, 2); - draw_text("Default Cutoff", 36, 42, 0, 2); - draw_text("Default Resonance", 36, 43, 0, 2); - draw_text("MIDI Channels", 36, 44, 0, 2); - draw_text("MIDI Program", 36, 45, 0, 2); - draw_text("MIDI Bank Low", 36, 46, 0, 2); - draw_text("MIDI Bank High", 36, 47, 0, 2); + draw_fill_chars(57, 28, 62, 29, 0); + draw_fill_chars(57, 32, 62, 34, 0); + draw_fill_chars(57, 37, 62, 39, 0); + + draw_box(31, 17, 77, 26, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 27, 63, 30, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 31, 63, 35, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 36, 63, 40, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(53, 41, 71, 48, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_text("Frequency Envelope", 35, 28, 0, 2); + draw_text("Carry", 48, 29, 0, 2); + draw_text("Envelope Loop", 40, 32, 0, 2); + draw_text("Loop Begin", 43, 33, 0, 2); + draw_text("Loop End", 45, 34, 0, 2); + draw_text("Sustain Loop", 41, 37, 0, 2); + draw_text("SusLoop Begin", 40, 38, 0, 2); + draw_text("SusLoop End", 42, 39, 0, 2); + draw_text("Default Cutoff", 36, 42, 0, 2); + draw_text("Default Resonance", 36, 43, 0, 2); + draw_text("MIDI Channels", 36, 44, 0, 2); + draw_text("MIDI Program", 36, 45, 0, 2); + draw_text("MIDI Bank Low", 36, 46, 0, 2); + draw_text("MIDI Bank High", 36, 47, 0, 2); } /* --------------------------------------------------------------------- */ @@ -2511,335 +2589,335 @@ static void _load_page_common(struct page *page, struct widget *page_widgets) { - int i; + int i; - memset(saved_env, 0, sizeof(saved_env)); - for (i = 0; i < 10; i++) { - saved_env[i].nodes = 2; - saved_env[i].ticks[0] = 0; - saved_env[i].ticks[1] = 100; - saved_env[i].values[0] = 32; - saved_env[i].values[1] = 32; - } - vgamem_ovl_alloc(&env_overlay); - - page->title = "Instrument List (F4)"; - page->pre_handle_key = instrument_list_pre_handle_key; - page->handle_key = instrument_list_handle_key; - page->widgets = page_widgets; - page->help_index = HELP_INSTRUMENT_LIST; - page->set_page = instrument_list_reposition; - - /* the first five widgets are the same for all four pages. */ - - /* 0 = instrument list */ - create_other(page_widgets + 0, 1, instrument_list_handle_key_on_list, instrument_list_draw_list); - page_widgets[0].accept_text = (instrument_cursor_pos == 25 ? 0 : 1); - page_widgets[0].x = 5; - page_widgets[0].y = 13; - page_widgets[0].width = 24; - page_widgets[0].height = 34; - - /* 1-4 = subpage switches */ - create_togglebutton(page_widgets + 1, 32, 13, 7, 1, 5, 0, 2, 2, change_subpage, "General", - 1, subpage_switches_group); - create_togglebutton(page_widgets + 2, 44, 13, 7, 2, 5, 1, 3, 3, change_subpage, "Volume", - 1, subpage_switches_group); - create_togglebutton(page_widgets + 3, 56, 13, 7, 3, 5, 2, 4, 4, change_subpage, "Panning", - 1, subpage_switches_group); - create_togglebutton(page_widgets + 4, 68, 13, 7, 4, 5, 3, 0, 0, change_subpage, "Pitch", - 2, subpage_switches_group); + memset(saved_env, 0, sizeof(saved_env)); + for (i = 0; i < 10; i++) { + saved_env[i].nodes = 2; + saved_env[i].ticks[0] = 0; + saved_env[i].ticks[1] = 100; + saved_env[i].values[0] = 32; + saved_env[i].values[1] = 32; + } + vgamem_ovl_alloc(&env_overlay); + + page->title = "Instrument List (F4)"; + page->pre_handle_key = instrument_list_pre_handle_key; + page->handle_key = instrument_list_handle_key; + page->widgets = page_widgets; + page->help_index = HELP_INSTRUMENT_LIST; + page->set_page = instrument_list_reposition; + + /* the first five widgets are the same for all four pages. */ + + /* 0 = instrument list */ + create_other(page_widgets + 0, 1, instrument_list_handle_key_on_list, instrument_list_draw_list); + page_widgets[0].accept_text = (instrument_cursor_pos == 25 ? 0 : 1); + page_widgets[0].x = 5; + page_widgets[0].y = 13; + page_widgets[0].width = 24; + page_widgets[0].height = 34; + + /* 1-4 = subpage switches */ + create_togglebutton(page_widgets + 1, 32, 13, 7, 1, 5, 0, 2, 2, change_subpage, "General", + 1, subpage_switches_group); + create_togglebutton(page_widgets + 2, 44, 13, 7, 2, 5, 1, 3, 3, change_subpage, "Volume", + 1, subpage_switches_group); + create_togglebutton(page_widgets + 3, 56, 13, 7, 3, 5, 2, 4, 4, change_subpage, "Panning", + 1, subpage_switches_group); + create_togglebutton(page_widgets + 4, 68, 13, 7, 4, 5, 3, 0, 0, change_subpage, "Pitch", + 2, subpage_switches_group); } void instrument_list_general_load_page(struct page *page) { - _load_page_common(page, widgets_general); + _load_page_common(page, widgets_general); - page->draw_const = instrument_list_general_draw_const; - page->predraw_hook = instrument_list_general_predraw_hook; - page->total_widgets = 18; - - /* special case stuff */ - widgets_general[1].d.togglebutton.state = 1; - widgets_general[2].next.down = widgets_general[3].next.down = widgets_general[4].next.down = 6; - - /* 5 = note trans table */ - create_other(widgets_general + 5, 6, note_trans_handle_key, note_trans_draw); - widgets_general[5].x = 32; - widgets_general[5].y = 16; - widgets_general[5].width = 9; - widgets_general[5].height = 31; - - /* 6-9 = nna toggles */ - create_togglebutton(widgets_general + 6, 46, 19, 29, 2, 7, 5, 0, 0, - instrument_list_general_update_values, - "Note Cut", 2, nna_group); - create_togglebutton(widgets_general + 7, 46, 22, 29, 6, 8, 5, 0, 0, - instrument_list_general_update_values, - "Continue", 2, nna_group); - create_togglebutton(widgets_general + 8, 46, 25, 29, 7, 9, 5, 0, 0, - instrument_list_general_update_values, - "Note Off", 2, nna_group); - create_togglebutton(widgets_general + 9, 46, 28, 29, 8, 10, 5, 0, 0, - instrument_list_general_update_values, - "Note Fade", 2, nna_group); - - /* 10-13 = dct toggles */ - create_togglebutton(widgets_general + 10, 46, 34, 12, 9, 11, 5, 14, - 14, instrument_list_general_update_values, - "Disabled", 2, dct_group); - create_togglebutton(widgets_general + 11, 46, 37, 12, 10, 12, 5, 15, - 15, instrument_list_general_update_values, - "Note", 2, dct_group); - create_togglebutton(widgets_general + 12, 46, 40, 12, 11, 13, 5, 16, - 16, instrument_list_general_update_values, - "Sample", 2, dct_group); - create_togglebutton(widgets_general + 13, 46, 43, 12, 12, 17, 5, 13, - 13, instrument_list_general_update_values, - "Instrument", 2, dct_group); - /* 14-16 = dca toggles */ - create_togglebutton(widgets_general + 14, 62, 34, 13, 9, 15, 10, 0, - 0, instrument_list_general_update_values, - "Note Cut", 2, dca_group); - create_togglebutton(widgets_general + 15, 62, 37, 13, 14, 16, 11, 0, - 0, instrument_list_general_update_values, - "Note Off", 2, dca_group); - create_togglebutton(widgets_general + 16, 62, 40, 13, 15, 17, 12, 0, - 0, instrument_list_general_update_values, - "Note Fade", 2, dca_group); - /* 17 = filename */ - /* impulse tracker has a 17-char-wide box for the filename for - * some reason, though it still limits the actual text to 12 - * characters. go figure... */ - create_textentry(widgets_general + 17, 56, 47, 13, 13, 17, 0, update_filename, - NULL, 12); + page->draw_const = instrument_list_general_draw_const; + page->predraw_hook = instrument_list_general_predraw_hook; + page->total_widgets = 18; + + /* special case stuff */ + widgets_general[1].d.togglebutton.state = 1; + widgets_general[2].next.down = widgets_general[3].next.down = widgets_general[4].next.down = 6; + + /* 5 = note trans table */ + create_other(widgets_general + 5, 6, note_trans_handle_key, note_trans_draw); + widgets_general[5].x = 32; + widgets_general[5].y = 16; + widgets_general[5].width = 9; + widgets_general[5].height = 31; + + /* 6-9 = nna toggles */ + create_togglebutton(widgets_general + 6, 46, 19, 29, 2, 7, 5, 0, 0, + instrument_list_general_update_values, + "Note Cut", 2, nna_group); + create_togglebutton(widgets_general + 7, 46, 22, 29, 6, 8, 5, 0, 0, + instrument_list_general_update_values, + "Continue", 2, nna_group); + create_togglebutton(widgets_general + 8, 46, 25, 29, 7, 9, 5, 0, 0, + instrument_list_general_update_values, + "Note Off", 2, nna_group); + create_togglebutton(widgets_general + 9, 46, 28, 29, 8, 10, 5, 0, 0, + instrument_list_general_update_values, + "Note Fade", 2, nna_group); + + /* 10-13 = dct toggles */ + create_togglebutton(widgets_general + 10, 46, 34, 12, 9, 11, 5, 14, + 14, instrument_list_general_update_values, + "Disabled", 2, dct_group); + create_togglebutton(widgets_general + 11, 46, 37, 12, 10, 12, 5, 15, + 15, instrument_list_general_update_values, + "Note", 2, dct_group); + create_togglebutton(widgets_general + 12, 46, 40, 12, 11, 13, 5, 16, + 16, instrument_list_general_update_values, + "Sample", 2, dct_group); + create_togglebutton(widgets_general + 13, 46, 43, 12, 12, 17, 5, 13, + 13, instrument_list_general_update_values, + "Instrument", 2, dct_group); + /* 14-16 = dca toggles */ + create_togglebutton(widgets_general + 14, 62, 34, 13, 9, 15, 10, 0, + 0, instrument_list_general_update_values, + "Note Cut", 2, dca_group); + create_togglebutton(widgets_general + 15, 62, 37, 13, 14, 16, 11, 0, + 0, instrument_list_general_update_values, + "Note Off", 2, dca_group); + create_togglebutton(widgets_general + 16, 62, 40, 13, 15, 17, 12, 0, + 0, instrument_list_general_update_values, + "Note Fade", 2, dca_group); + /* 17 = filename */ + /* impulse tracker has a 17-char-wide box for the filename for + * some reason, though it still limits the actual text to 12 + * characters. go figure... */ + create_textentry(widgets_general + 17, 56, 47, 13, 13, 17, 0, update_filename, + NULL, 12); } static int _fixup_mouse_instpage_volume(struct key_event *k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - if (envelope_mouse_edit && ins) { - if (_env_handle_mouse(k, &ins->vol_env, ¤t_node_vol)) { - ins->flags |= ENV_VOLUME; - return 1; - } - } - if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { - return _env_handle_key_viewmode(k, &ins->vol_env, ¤t_node_vol, ENV_VOLUME); - } - return instrument_list_pre_handle_key(k); + song_instrument_t *ins = song_get_instrument(current_instrument); + if (envelope_mouse_edit && ins) { + if (_env_handle_mouse(k, &ins->vol_env, ¤t_node_vol)) { + ins->flags |= ENV_VOLUME; + return 1; + } + } + if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { + return _env_handle_key_viewmode(k, &ins->vol_env, ¤t_node_vol, ENV_VOLUME); + } + return instrument_list_pre_handle_key(k); } void instrument_list_volume_load_page(struct page *page) { - _load_page_common(page, widgets_volume); + _load_page_common(page, widgets_volume); - page->pre_handle_key = _fixup_mouse_instpage_volume; - page->draw_const = instrument_list_volume_draw_const; - page->predraw_hook = instrument_list_volume_predraw_hook; - page->total_widgets = 17; - - /* 5 = volume envelope */ - create_other(widgets_volume + 5, 0, volume_envelope_handle_key, volume_envelope_draw); - widgets_volume[5].x = 32; - widgets_volume[5].y = 18; - widgets_volume[5].width = 45; - widgets_volume[5].height = 8; - - /* 6-7 = envelope switches */ - create_toggle(widgets_volume + 6, 54, 28, 5, 7, 0, 0, 0, - instrument_list_volume_update_values); - create_toggle(widgets_volume + 7, 54, 29, 6, 8, 0, 0, 0, - instrument_list_volume_update_values); - - /* 8-10 envelope loop settings */ - create_toggle(widgets_volume + 8, 54, 32, 7, 9, 0, 0, 0, - instrument_list_volume_update_values); - create_numentry(widgets_volume + 9, 54, 33, 3, 8, 10, 0, - instrument_list_volume_update_values, 0, 1, - numentry_cursor_pos + 0); - create_numentry(widgets_volume + 10, 54, 34, 3, 9, 11, 0, - instrument_list_volume_update_values, 0, 1, - numentry_cursor_pos + 0); - - /* 11-13 = susloop settings */ - create_toggle(widgets_volume + 11, 54, 37, 10, 12, 0, 0, 0, - instrument_list_volume_update_values); - create_numentry(widgets_volume + 12, 54, 38, 3, 11, 13, 0, - instrument_list_volume_update_values, 0, 1, - numentry_cursor_pos + 0); - create_numentry(widgets_volume + 13, 54, 39, 3, 12, 14, 0, - instrument_list_volume_update_values, 0, 1, - numentry_cursor_pos + 0); - - /* 14-16 = volume thumbbars */ - create_thumbbar(widgets_volume + 14, 54, 42, 17, 13, 15, 0, - instrument_list_volume_update_values, 0, 128); - create_thumbbar(widgets_volume + 15, 54, 43, 17, 14, 16, 0, - instrument_list_volume_update_values, 0, 256); - create_thumbbar(widgets_volume + 16, 54, 46, 17, 15, 16, 0, - instrument_list_volume_update_values, 0, 100); + page->pre_handle_key = _fixup_mouse_instpage_volume; + page->draw_const = instrument_list_volume_draw_const; + page->predraw_hook = instrument_list_volume_predraw_hook; + page->total_widgets = 17; + + /* 5 = volume envelope */ + create_other(widgets_volume + 5, 0, volume_envelope_handle_key, volume_envelope_draw); + widgets_volume[5].x = 32; + widgets_volume[5].y = 18; + widgets_volume[5].width = 45; + widgets_volume[5].height = 8; + + /* 6-7 = envelope switches */ + create_toggle(widgets_volume + 6, 54, 28, 5, 7, 0, 0, 0, + instrument_list_volume_update_values); + create_toggle(widgets_volume + 7, 54, 29, 6, 8, 0, 0, 0, + instrument_list_volume_update_values); + + /* 8-10 envelope loop settings */ + create_toggle(widgets_volume + 8, 54, 32, 7, 9, 0, 0, 0, + instrument_list_volume_update_values); + create_numentry(widgets_volume + 9, 54, 33, 3, 8, 10, 0, + instrument_list_volume_update_values, 0, 1, + numentry_cursor_pos + 0); + create_numentry(widgets_volume + 10, 54, 34, 3, 9, 11, 0, + instrument_list_volume_update_values, 0, 1, + numentry_cursor_pos + 0); + + /* 11-13 = susloop settings */ + create_toggle(widgets_volume + 11, 54, 37, 10, 12, 0, 0, 0, + instrument_list_volume_update_values); + create_numentry(widgets_volume + 12, 54, 38, 3, 11, 13, 0, + instrument_list_volume_update_values, 0, 1, + numentry_cursor_pos + 0); + create_numentry(widgets_volume + 13, 54, 39, 3, 12, 14, 0, + instrument_list_volume_update_values, 0, 1, + numentry_cursor_pos + 0); + + /* 14-16 = volume thumbbars */ + create_thumbbar(widgets_volume + 14, 54, 42, 17, 13, 15, 0, + instrument_list_volume_update_values, 0, 128); + create_thumbbar(widgets_volume + 15, 54, 43, 17, 14, 16, 0, + instrument_list_volume_update_values, 0, 256); + create_thumbbar(widgets_volume + 16, 54, 46, 17, 15, 16, 0, + instrument_list_volume_update_values, 0, 100); } static int _fixup_mouse_instpage_panning(struct key_event *k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - if (envelope_mouse_edit && ins) { - if (_env_handle_mouse(k, &ins->pan_env, ¤t_node_pan)) { - ins->flags |= ENV_PANNING; - return 1; - } - } - if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { - return _env_handle_key_viewmode(k, &ins->pan_env, ¤t_node_pan, ENV_PANNING); - } - return instrument_list_pre_handle_key(k); + song_instrument_t *ins = song_get_instrument(current_instrument); + if (envelope_mouse_edit && ins) { + if (_env_handle_mouse(k, &ins->pan_env, ¤t_node_pan)) { + ins->flags |= ENV_PANNING; + return 1; + } + } + if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { + return _env_handle_key_viewmode(k, &ins->pan_env, ¤t_node_pan, ENV_PANNING); + } + return instrument_list_pre_handle_key(k); } void instrument_list_panning_load_page(struct page *page) { - _load_page_common(page, widgets_panning); + _load_page_common(page, widgets_panning); - page->pre_handle_key = _fixup_mouse_instpage_panning; - page->draw_const = instrument_list_panning_draw_const; - page->predraw_hook = instrument_list_panning_predraw_hook; - page->total_widgets = 19; - - /* 5 = panning envelope */ - create_other(widgets_panning + 5, 0, panning_envelope_handle_key, panning_envelope_draw); - widgets_panning[5].x = 32; - widgets_panning[5].y = 18; - widgets_panning[5].width = 45; - widgets_panning[5].height = 8; - - /* 6-7 = envelope switches */ - create_toggle(widgets_panning + 6, 54, 28, 5, 7, 0, 0, 0, - instrument_list_panning_update_values); - create_toggle(widgets_panning + 7, 54, 29, 6, 8, 0, 0, 0, - instrument_list_panning_update_values); - - /* 8-10 envelope loop settings */ - create_toggle(widgets_panning + 8, 54, 32, 7, 9, 0, 0, 0, - instrument_list_panning_update_values); - create_numentry(widgets_panning + 9, 54, 33, 3, 8, 10, 0, - instrument_list_panning_update_values, 0, 1, - numentry_cursor_pos + 1); - create_numentry(widgets_panning + 10, 54, 34, 3, 9, 11, 0, - instrument_list_panning_update_values, 0, 1, - numentry_cursor_pos + 1); - - /* 11-13 = susloop settings */ - create_toggle(widgets_panning + 11, 54, 37, 10, 12, 0, 0, 0, - instrument_list_panning_update_values); - create_numentry(widgets_panning + 12, 54, 38, 3, 11, 13, 0, - instrument_list_panning_update_values, 0, 1, - numentry_cursor_pos + 1); - create_numentry(widgets_panning + 13, 54, 39, 3, 12, 14, 0, - instrument_list_panning_update_values, 0, 1, - numentry_cursor_pos + 1); - - /* 14-15 = default panning */ - create_toggle(widgets_panning + 14, 54, 42, 13, 15, 0, 0, 0, - instrument_list_panning_update_values); - create_thumbbar(widgets_panning + 15, 54, 43, 9, 14, 16, 0, - instrument_list_panning_update_values, 0, 64); - - /* 16 = pitch-pan center */ - create_other(widgets_panning + 16, 0, pitch_pan_center_handle_key, pitch_pan_center_draw); - widgets_panning[16].next.up = 15; - widgets_panning[16].next.down = 17; - - /* 17-18 = other panning stuff */ - create_thumbbar(widgets_panning + 17, 54, 46, 9, 16, 18, 0, - instrument_list_panning_update_values, -32, 32); - create_thumbbar(widgets_panning + 18, 54, 47, 9, 17, 18, 0, - instrument_list_panning_update_values, 0, 64); + page->pre_handle_key = _fixup_mouse_instpage_panning; + page->draw_const = instrument_list_panning_draw_const; + page->predraw_hook = instrument_list_panning_predraw_hook; + page->total_widgets = 19; + + /* 5 = panning envelope */ + create_other(widgets_panning + 5, 0, panning_envelope_handle_key, panning_envelope_draw); + widgets_panning[5].x = 32; + widgets_panning[5].y = 18; + widgets_panning[5].width = 45; + widgets_panning[5].height = 8; + + /* 6-7 = envelope switches */ + create_toggle(widgets_panning + 6, 54, 28, 5, 7, 0, 0, 0, + instrument_list_panning_update_values); + create_toggle(widgets_panning + 7, 54, 29, 6, 8, 0, 0, 0, + instrument_list_panning_update_values); + + /* 8-10 envelope loop settings */ + create_toggle(widgets_panning + 8, 54, 32, 7, 9, 0, 0, 0, + instrument_list_panning_update_values); + create_numentry(widgets_panning + 9, 54, 33, 3, 8, 10, 0, + instrument_list_panning_update_values, 0, 1, + numentry_cursor_pos + 1); + create_numentry(widgets_panning + 10, 54, 34, 3, 9, 11, 0, + instrument_list_panning_update_values, 0, 1, + numentry_cursor_pos + 1); + + /* 11-13 = susloop settings */ + create_toggle(widgets_panning + 11, 54, 37, 10, 12, 0, 0, 0, + instrument_list_panning_update_values); + create_numentry(widgets_panning + 12, 54, 38, 3, 11, 13, 0, + instrument_list_panning_update_values, 0, 1, + numentry_cursor_pos + 1); + create_numentry(widgets_panning + 13, 54, 39, 3, 12, 14, 0, + instrument_list_panning_update_values, 0, 1, + numentry_cursor_pos + 1); + + /* 14-15 = default panning */ + create_toggle(widgets_panning + 14, 54, 42, 13, 15, 0, 0, 0, + instrument_list_panning_update_values); + create_thumbbar(widgets_panning + 15, 54, 43, 9, 14, 16, 0, + instrument_list_panning_update_values, 0, 64); + + /* 16 = pitch-pan center */ + create_other(widgets_panning + 16, 0, pitch_pan_center_handle_key, pitch_pan_center_draw); + widgets_panning[16].next.up = 15; + widgets_panning[16].next.down = 17; + + /* 17-18 = other panning stuff */ + create_thumbbar(widgets_panning + 17, 54, 46, 9, 16, 18, 0, + instrument_list_panning_update_values, -32, 32); + create_thumbbar(widgets_panning + 18, 54, 47, 9, 17, 18, 0, + instrument_list_panning_update_values, 0, 64); } static int _fixup_mouse_instpage_pitch(struct key_event *k) { - song_instrument_t *ins = song_get_instrument(current_instrument); - if (envelope_mouse_edit && ins) { - if (_env_handle_mouse(k, &ins->pitch_env, ¤t_node_pitch)) { - ins->flags |= ENV_PITCH; - return 1; - } - } - if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { - return _env_handle_key_viewmode(k, &ins->pitch_env, ¤t_node_pitch, ENV_PITCH); - } - return instrument_list_pre_handle_key(k); + song_instrument_t *ins = song_get_instrument(current_instrument); + if (envelope_mouse_edit && ins) { + if (_env_handle_mouse(k, &ins->pitch_env, ¤t_node_pitch)) { + ins->flags |= ENV_PITCH; + return 1; + } + } + if ((k->sym == SDLK_l || k->sym == SDLK_b) && (k->mod & KMOD_ALT)) { + return _env_handle_key_viewmode(k, &ins->pitch_env, ¤t_node_pitch, ENV_PITCH); + } + return instrument_list_pre_handle_key(k); } void instrument_list_pitch_load_page(struct page *page) { - static int midi_channel_selection_cursor_position = 0; + static int midi_channel_selection_cursor_position = 0; - _load_page_common(page, widgets_pitch); + _load_page_common(page, widgets_pitch); - page->pre_handle_key = _fixup_mouse_instpage_pitch; - page->draw_const = instrument_list_pitch_draw_const; - page->predraw_hook = instrument_list_pitch_predraw_hook; - page->total_widgets = 20; - - /* 5 = pitch envelope */ - create_other(widgets_pitch + 5, 0, pitch_envelope_handle_key, pitch_envelope_draw); - widgets_pitch[5].x = 32; - widgets_pitch[5].y = 18; - widgets_pitch[5].width = 45; - widgets_pitch[5].height = 8; - - /* 6-7 = envelope switches */ - create_menutoggle(widgets_pitch + 6, 54, 28, 5, 7, 0, 0, 0, - instrument_list_pitch_update_values, pitch_envelope_states); - create_toggle(widgets_pitch + 7, 54, 29, 6, 8, 0, 0, 0, - instrument_list_pitch_update_values); - - /* 8-10 envelope loop settings */ - create_toggle(widgets_pitch + 8, 54, 32, 7, 9, 0, 0, 0, - instrument_list_pitch_update_values); - create_numentry(widgets_pitch + 9, 54, 33, 3, 8, 10, 0, - instrument_list_pitch_update_values, 0, 1, - numentry_cursor_pos + 2); - create_numentry(widgets_pitch + 10, 54, 34, 3, 9, 11, 0, - instrument_list_pitch_update_values, 0, 1, - numentry_cursor_pos + 2); - - /* 11-13 = susloop settings */ - create_toggle(widgets_pitch + 11, 54, 37, 10, 12, 0, 0, 0, - instrument_list_pitch_update_values); - create_numentry(widgets_pitch + 12, 54, 38, 3, 11, 13, 0, - instrument_list_pitch_update_values, 0, 1, - numentry_cursor_pos + 2); - create_numentry(widgets_pitch + 13, 54, 39, 3, 12, 14, 0, - instrument_list_pitch_update_values, 0, 1, - numentry_cursor_pos + 2); - - /* 14-15 = filter cutoff/resonance */ - create_thumbbar(widgets_pitch + 14, 54, 42, 17, 13, 15, 0, - instrument_list_pitch_update_values, -1, 127); - create_thumbbar(widgets_pitch + 15, 54, 43, 17, 14, 16, 0, - instrument_list_pitch_update_values, -1, 127); - widgets_pitch[14].d.thumbbar.text_at_min = "Off"; - widgets_pitch[15].d.thumbbar.text_at_min = "Off"; - - /* 16-19 = midi crap */ - create_bitset(widgets_pitch + 16, 54, 44, 17, 15, 17, 0, - instrument_list_pitch_update_values, - 17, - " 1 2 3 4 5 6 7 8 9P\0""111213141516M\0", - ".\0.\0.\0.\0.\0.\0.\0.\0.\0p\0.\0.\0.\0.\0.\0.\0m\0", - &midi_channel_selection_cursor_position - ); - widgets_pitch[16].d.bitset.activation_keys = - "123456789pabcdefm"; - - create_thumbbar(widgets_pitch + 17, 54, 45, 17, 16, 18, 0, - instrument_list_pitch_update_values, -1, 127); - create_thumbbar(widgets_pitch + 18, 54, 46, 17, 17, 19, 0, - instrument_list_pitch_update_values, -1, 127); - create_thumbbar(widgets_pitch + 19, 54, 47, 17, 18, 19, 0, - instrument_list_pitch_update_values, -1, 127); - widgets_pitch[17].d.thumbbar.text_at_min = "Off"; - widgets_pitch[18].d.thumbbar.text_at_min = "Off"; - widgets_pitch[19].d.thumbbar.text_at_min = "Off"; + page->pre_handle_key = _fixup_mouse_instpage_pitch; + page->draw_const = instrument_list_pitch_draw_const; + page->predraw_hook = instrument_list_pitch_predraw_hook; + page->total_widgets = 20; + + /* 5 = pitch envelope */ + create_other(widgets_pitch + 5, 0, pitch_envelope_handle_key, pitch_envelope_draw); + widgets_pitch[5].x = 32; + widgets_pitch[5].y = 18; + widgets_pitch[5].width = 45; + widgets_pitch[5].height = 8; + + /* 6-7 = envelope switches */ + create_menutoggle(widgets_pitch + 6, 54, 28, 5, 7, 0, 0, 0, + instrument_list_pitch_update_values, pitch_envelope_states); + create_toggle(widgets_pitch + 7, 54, 29, 6, 8, 0, 0, 0, + instrument_list_pitch_update_values); + + /* 8-10 envelope loop settings */ + create_toggle(widgets_pitch + 8, 54, 32, 7, 9, 0, 0, 0, + instrument_list_pitch_update_values); + create_numentry(widgets_pitch + 9, 54, 33, 3, 8, 10, 0, + instrument_list_pitch_update_values, 0, 1, + numentry_cursor_pos + 2); + create_numentry(widgets_pitch + 10, 54, 34, 3, 9, 11, 0, + instrument_list_pitch_update_values, 0, 1, + numentry_cursor_pos + 2); + + /* 11-13 = susloop settings */ + create_toggle(widgets_pitch + 11, 54, 37, 10, 12, 0, 0, 0, + instrument_list_pitch_update_values); + create_numentry(widgets_pitch + 12, 54, 38, 3, 11, 13, 0, + instrument_list_pitch_update_values, 0, 1, + numentry_cursor_pos + 2); + create_numentry(widgets_pitch + 13, 54, 39, 3, 12, 14, 0, + instrument_list_pitch_update_values, 0, 1, + numentry_cursor_pos + 2); + + /* 14-15 = filter cutoff/resonance */ + create_thumbbar(widgets_pitch + 14, 54, 42, 17, 13, 15, 0, + instrument_list_pitch_update_values, -1, 127); + create_thumbbar(widgets_pitch + 15, 54, 43, 17, 14, 16, 0, + instrument_list_pitch_update_values, -1, 127); + widgets_pitch[14].d.thumbbar.text_at_min = "Off"; + widgets_pitch[15].d.thumbbar.text_at_min = "Off"; + + /* 16-19 = midi crap */ + create_bitset(widgets_pitch + 16, 54, 44, 17, 15, 17, 0, + instrument_list_pitch_update_values, + 17, + " 1 2 3 4 5 6 7 8 9P\0""111213141516M\0", + ".\0.\0.\0.\0.\0.\0.\0.\0.\0p\0.\0.\0.\0.\0.\0.\0m\0", + &midi_channel_selection_cursor_position + ); + widgets_pitch[16].d.bitset.activation_keys = + "123456789pabcdefm"; + + create_thumbbar(widgets_pitch + 17, 54, 45, 17, 16, 18, 0, + instrument_list_pitch_update_values, -1, 127); + create_thumbbar(widgets_pitch + 18, 54, 46, 17, 17, 19, 0, + instrument_list_pitch_update_values, -1, 127); + create_thumbbar(widgets_pitch + 19, 54, 47, 17, 18, 19, 0, + instrument_list_pitch_update_values, -1, 127); + widgets_pitch[17].d.thumbbar.text_at_min = "Off"; + widgets_pitch[18].d.thumbbar.text_at_min = "Off"; + widgets_pitch[19].d.thumbbar.text_at_min = "Off"; } diff -Nru schism-0+20110101/schism/page_loadinst.c schism-20160521/schism/page_loadinst.c --- schism-0+20110101/schism/page_loadinst.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_loadinst.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -49,13 +49,13 @@ /* --------------------------------------------------------------------------------------------------------- */ /* files: - file type color displayed title notes - --------- ----- --------------- ----- - unchecked 4 IT uses color 6 for these - directory 5 "........Directory........" dots are char 154 (same for libraries) - sample 3 - libraries 6 ".........Library........." IT uses color 3. maybe use module name here? - unknown 2 any regular file that's not recognized + file type color displayed title notes + --------- ----- --------------- ----- + unchecked 4 IT uses color 6 for these + directory 5 "........Directory........" dots are char 154 (same for libraries) + sample 3 + libraries 6 ".........Library........." IT uses color 3. maybe use module name here? + unknown 2 any regular file that's not recognized */ static int top_file = 0; @@ -70,94 +70,94 @@ /* get a color index from a dmoz_file_t 'type' field */ static inline int get_type_color(int type) { - if (type == TYPE_DIRECTORY) - return 5; - if (!(type & TYPE_EXT_DATA_MASK)) - return 4; /* unchecked */ - if (type & TYPE_BROWSABLE_MASK) - return 6; /* library */ - if (type == TYPE_UNKNOWN) - return 2; - return 3; /* sample */ + if (type == TYPE_DIRECTORY) + return 5; + if (!(type & TYPE_EXT_DATA_MASK)) + return 4; /* unchecked */ + if (type & TYPE_BROWSABLE_MASK) + return 6; /* library */ + if (type == TYPE_UNKNOWN) + return 2; + return 3; /* sample */ } static void clear_directory(void) { - dmoz_free(&flist, NULL); + dmoz_free(&flist, NULL); } static int instgrep(dmoz_file_t *f) { - dmoz_fill_ext_data(f); - return f->type & (TYPE_INST_MASK | TYPE_BROWSABLE_MASK); + dmoz_fill_ext_data(f); + return f->type & (TYPE_INST_MASK | TYPE_BROWSABLE_MASK); } /* --------------------------------------------------------------------------------------------------------- */ static void file_list_reposition(void) { - if (current_file >= flist.num_files) - current_file = flist.num_files-1; - if (current_file < 0) current_file = 0; - if (current_file < top_file) - top_file = current_file; - else if (current_file > top_file + 34) - top_file = current_file - 34; + if (current_file >= flist.num_files) + current_file = flist.num_files-1; + if (current_file < 0) current_file = 0; + if (current_file < top_file) + top_file = current_file; + else if (current_file > top_file + 34) + top_file = current_file - 34; } static void read_directory(void) { - struct stat st; + struct stat st; - clear_directory(); + clear_directory(); - if (stat(inst_cwd, &st) < 0) - directory_mtime = 0; - else - directory_mtime = st.st_mtime; - /* if the stat call failed, this will probably break as well, but - at the very least, it'll add an entry for the root directory. */ - if (dmoz_read(inst_cwd, &flist, NULL, dmoz_read_instrument_library) < 0) - log_perror(inst_cwd); - - dmoz_filter_filelist(&flist,instgrep, ¤t_file, file_list_reposition); - dmoz_cache_lookup(inst_cwd, &flist, NULL); - file_list_reposition(); + if (stat(inst_cwd, &st) < 0) + directory_mtime = 0; + else + directory_mtime = st.st_mtime; + /* if the stat call failed, this will probably break as well, but + at the very least, it'll add an entry for the root directory. */ + if (dmoz_read(inst_cwd, &flist, NULL, dmoz_read_instrument_library) < 0) + log_perror(inst_cwd); + + dmoz_filter_filelist(&flist,instgrep, ¤t_file, file_list_reposition); + dmoz_cache_lookup(inst_cwd, &flist, NULL); + file_list_reposition(); } /* return: 1 = success, 0 = failure TODO: provide some sort of feedback if something went wrong. */ static int change_dir(const char *dir) { - char *ptr = dmoz_path_normal(dir); - struct stat buf; + char *ptr = dmoz_path_normal(dir); + struct stat buf; - if (!ptr) - return 0; + if (!ptr) + return 0; - dmoz_cache_update(inst_cwd, &flist, NULL); + dmoz_cache_update(inst_cwd, &flist, NULL); - if (stat(ptr, &buf) == 0 && S_ISDIR(buf.st_mode)) { - strncpy(cfg_dir_instruments, ptr, PATH_MAX); - cfg_dir_instruments[PATH_MAX] = 0; + if (stat(ptr, &buf) == 0 && S_ISDIR(buf.st_mode)) { + strncpy(cfg_dir_instruments, ptr, PATH_MAX); + cfg_dir_instruments[PATH_MAX] = 0; - } - strncpy(inst_cwd, ptr, PATH_MAX); - inst_cwd[PATH_MAX] = 0; - free(ptr); + } + strncpy(inst_cwd, ptr, PATH_MAX); + inst_cwd[PATH_MAX] = 0; + free(ptr); - read_directory(); - return 1; + read_directory(); + return 1; } /* --------------------------------------------------------------------------------------------------------- */ static void load_instrument_draw_const(void) { - draw_fill_chars(6, 13, 67, 47, 0); - draw_thin_inner_box(50, 12, 61, 48, 0,0); - draw_box(5, 12, 68, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(6, 13, 67, 47, 0); + draw_thin_inner_box(50, 12, 61, 48, 0,0); + draw_box(5, 12, 68, 48, BOX_THICK | BOX_INNER | BOX_INSET); } @@ -165,355 +165,366 @@ static void _common_set_page(void) { - struct stat st; + struct stat st; - if (!inst_cwd[0]) { - strcpy(inst_cwd, cfg_dir_instruments); - } - - /* if we have a list, the directory didn't change, and the mtime is the same, we're set */ - if (flist.num_files > 0 - && (status.flags & DIR_SAMPLES_CHANGED) == 0 - && stat(inst_cwd, &st) == 0 - && st.st_mtime == directory_mtime) { - return; - } + if (!inst_cwd[0]) { + strcpy(inst_cwd, cfg_dir_instruments); + } + + /* if we have a list, the directory didn't change, and the mtime is the same, we're set */ + if (flist.num_files > 0 + && (status.flags & DIR_SAMPLES_CHANGED) == 0 + && stat(inst_cwd, &st) == 0 + && st.st_mtime == directory_mtime) { + return; + } - change_dir(inst_cwd); + change_dir(inst_cwd); - status.flags &= ~DIR_INSTRUMENTS_CHANGED; + status.flags &= ~DIR_INSTRUMENTS_CHANGED; - *selected_widget = 0; - slash_search_mode = -1; + *selected_widget = 0; + slash_search_mode = -1; } static void load_instrument_set_page(void) { - _library_mode = 0; - _common_set_page(); + _library_mode = 0; + _common_set_page(); } static void library_instrument_set_page(void) { - _library_mode = 1; - _common_set_page(); + _library_mode = 1; + _common_set_page(); } /* --------------------------------------------------------------------------------------------------------- */ static void file_list_draw(void) { - int n, pos, fg, bg, i; - char buf[8]; - char sbuf[32]; - dmoz_file_t *file; - - /* there's no need to have if (files) { ... } like in the load-module page, - because there will always be at least "/" in the list */ - if (top_file < 0) top_file = 0; - if (current_file < 0) current_file = 0; - for (n = top_file, pos = 13; n < flist.num_files && pos < 48; n++, pos++) { - file = flist.files[n]; - - if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { - fg = 0; - bg = 3; - } else { - fg = get_type_color(file->type); - bg = 0; - } - - draw_text(numtostr(3, n, buf), 2, pos, 0, 2); - draw_text_len((file->title ? file->title : ""), - 25, 6, pos, fg, bg); - draw_char(168, 31, pos, 2, bg); - draw_text_len((file->base ? file->base : ""), - 18, 32, pos, fg, bg); - - if (file->base && slash_search_mode > -1) { - if (strncasecmp(file->base,slash_search_str,slash_search_mode) == 0) { - for (i = 0 ; i < slash_search_mode; i++) { - if (tolower(((unsigned)file->base[i])) - != tolower(((unsigned)slash_search_str[i]))) break; - draw_char(file->base[i], 32+i, pos, 3,1); - } - } - } - - if (file->sampsize > 1) { - sprintf(sbuf, "%u Samples", file->sampsize); - draw_text_len(sbuf, 10, 51, pos, fg, bg); - } else if (file->sampsize == 1) { - draw_text("1 Sample ", 51, pos, fg, bg); - } else if (file->type & TYPE_MODULE_MASK) { - draw_text("\x9a\x9a""Module\x9a\x9a", 51, pos, fg, bg); - } else { - draw_text(" ", 51, pos, fg, bg); - } - if (file->filesize > 1048576) { - sprintf(sbuf, "%lum", (unsigned long)(file->filesize / 1048576)); - } else if (file->filesize > 1024) { - sprintf(sbuf, "%luk", (unsigned long)(file->filesize / 1024)); - } else if (file->filesize > 0) { - sprintf(sbuf, "%lu", (unsigned long)(file->filesize)); - } else { - *sbuf = 0; - } - draw_text_len(sbuf, 6, 62, pos, fg, bg); - } + int n, pos, fg, bg, i; + char buf[8]; + char sbuf[32]; + dmoz_file_t *file; + + /* there's no need to have if (files) { ... } like in the load-module page, + because there will always be at least "/" in the list */ + if (top_file < 0) top_file = 0; + if (current_file < 0) current_file = 0; + for (n = top_file, pos = 13; n < flist.num_files && pos < 48; n++, pos++) { + file = flist.files[n]; + + if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { + fg = 0; + bg = 3; + } else { + fg = get_type_color(file->type); + bg = 0; + } + + draw_text(numtostr(3, n, buf), 2, pos, 0, 2); + draw_text_len((file->title ? file->title : ""), + 25, 6, pos, fg, bg); + draw_char(168, 31, pos, 2, bg); + draw_text_len((file->base ? file->base : ""), + 18, 32, pos, fg, bg); + + if (file->base && slash_search_mode > -1) { + if (strncasecmp(file->base,slash_search_str,slash_search_mode) == 0) { + for (i = 0 ; i < slash_search_mode; i++) { + if (tolower(((unsigned)file->base[i])) + != tolower(((unsigned)slash_search_str[i]))) break; + draw_char(file->base[i], 32+i, pos, 3,1); + } + } + } + + if (file->sampsize > 1) { + sprintf(sbuf, "%u Samples", file->sampsize); + draw_text_len(sbuf, 10, 51, pos, fg, bg); + } else if (file->sampsize == 1) { + draw_text("1 Sample ", 51, pos, fg, bg); + } else if (file->type & TYPE_MODULE_MASK) { + draw_text("\x9a\x9a""Module\x9a\x9a", 51, pos, fg, bg); + } else { + draw_text(" ", 51, pos, fg, bg); + } + if (file->filesize > 1048576) { + sprintf(sbuf, "%lum", (unsigned long)(file->filesize / 1048576)); + } else if (file->filesize > 1024) { + sprintf(sbuf, "%luk", (unsigned long)(file->filesize / 1024)); + } else if (file->filesize > 0) { + sprintf(sbuf, "%lu", (unsigned long)(file->filesize)); + } else { + *sbuf = 0; + } + draw_text_len(sbuf, 6, 62, pos, fg, bg); + } - /* draw the info for the current file (or directory...) */ + /* draw the info for the current file (or directory...) */ - while (pos < 48) - draw_char(168, 31, pos++, 2, 0); + while (pos < 48) + draw_char(168, 31, pos++, 2, 0); } static void do_enable_inst(UNUSED void *d) { - song_set_instrument_mode(1); - main_song_changed_cb(); - set_page(PAGE_INSTRUMENT_LIST); - memused_songchanged(); + song_set_instrument_mode(1); + main_song_changed_cb(); + set_page(PAGE_INSTRUMENT_LIST); + memused_songchanged(); } static void dont_enable_inst(UNUSED void *d) { - set_page(PAGE_INSTRUMENT_LIST); + set_page(PAGE_INSTRUMENT_LIST); } static void reposition_at_slash_search(void) { - dmoz_file_t *f; - int i, j, b, bl; + dmoz_file_t *f; + int i, j, b, bl; - if (slash_search_mode < 0) return; - bl = b = -1; - for (i = 0; i < flist.num_files; i++) { - f = flist.files[i]; - if (!f || !f->base) continue; - for (j = 0; j < slash_search_mode; j++) { - if (tolower(((unsigned)f->base[j])) - != tolower(((unsigned)slash_search_str[j]))) break; - } - if (bl < j) { - bl = j; - b = i; - } - } - if (bl > -1) { - current_file = b; - file_list_reposition(); - } + if (slash_search_mode < 0) return; + bl = b = -1; + for (i = 0; i < flist.num_files; i++) { + f = flist.files[i]; + if (!f || !f->base) continue; + for (j = 0; j < slash_search_mode; j++) { + if (tolower(((unsigned)f->base[j])) + != tolower(((unsigned)slash_search_str[j]))) break; + } + if (bl < j) { + bl = j; + b = i; + } + } + if (bl > -1) { + current_file = b; + file_list_reposition(); + } } /* on the file list, that is */ static void handle_enter_key(void) { - dmoz_file_t *file; - int cur = instrument_get_current(); + dmoz_file_t *file; + int cur = instrument_get_current(); - if (current_file < 0 || current_file >= flist.num_files) return; - file = flist.files[current_file]; - dmoz_cache_update(inst_cwd, &flist, NULL); - - if (file->type & TYPE_BROWSABLE_MASK) { - change_dir(file->path); - status.flags |= NEED_UPDATE; - } else if (file->type & TYPE_INST_MASK) { - if (_library_mode) return; - if (file->instnum > -1) { - song_load_instrument_ex(cur, NULL, - file->path, file->instnum); - } else { - song_load_instrument(cur, file->path); - } - if (!song_is_instrument_mode()) { - dialog_create(DIALOG_YES_NO, - "Enable instrument mode?", - do_enable_inst, dont_enable_inst, 0, NULL); - } else { - set_page(PAGE_INSTRUMENT_LIST); - } - memused_songchanged(); - } + if (current_file < 0 || current_file >= flist.num_files) return; + file = flist.files[current_file]; + dmoz_cache_update(inst_cwd, &flist, NULL); + + if (file->type & TYPE_BROWSABLE_MASK) { + change_dir(file->path); + status.flags |= NEED_UPDATE; + } else if (file->type & TYPE_INST_MASK) { + if (_library_mode) return; + status.flags |= SONG_NEEDS_SAVE; + if (file->instnum > -1) { + song_load_instrument_ex(cur, NULL, + file->path, file->instnum); + } else { + song_load_instrument(cur, file->path); + } + if (!song_is_instrument_mode()) { + dialog_create(DIALOG_YES_NO, + "Enable instrument mode?", + do_enable_inst, dont_enable_inst, 0, NULL); + } else { + set_page(PAGE_INSTRUMENT_LIST); + } + memused_songchanged(); + } - /* TODO */ + /* TODO */ } static void do_delete_file(UNUSED void *data) { - int old_top_file, old_current_file; - char *ptr; + int old_top_file, old_current_file; + char *ptr; - if (current_file < 0 || current_file >= flist.num_files) - return; + if (current_file < 0 || current_file >= flist.num_files) + return; - ptr = flist.files[current_file]->path; + ptr = flist.files[current_file]->path; - /* would be neat to send it to the trash can if there is one */ - unlink(ptr); - - /* remember the list positions */ - old_top_file = top_file; - old_current_file = current_file; - - read_directory(); - - /* put the list positions back */ - top_file = old_top_file; - current_file = old_current_file; - /* edge case: if this was the last file, move the cursor up */ - if (current_file >= flist.num_files) - current_file = flist.num_files - 1; - file_list_reposition(); + /* would be neat to send it to the trash can if there is one */ + unlink(ptr); + + /* remember the list positions */ + old_top_file = top_file; + old_current_file = current_file; + + read_directory(); + + /* put the list positions back */ + top_file = old_top_file; + current_file = old_current_file; + /* edge case: if this was the last file, move the cursor up */ + if (current_file >= flist.num_files) + current_file = flist.num_files - 1; + file_list_reposition(); } static int file_list_handle_key(struct key_event * k) { - int new_file = current_file; + int new_file = current_file; - new_file = CLAMP(new_file, 0, flist.num_files - 1); + new_file = CLAMP(new_file, 0, flist.num_files - 1); - if (k->mouse) { - if (k->x >= 6 && k->x <= 67 && k->y >= 13 && k->y <= 47) { - slash_search_mode = -1; - if (k->mouse == MOUSE_SCROLL_UP) { - new_file -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_file += MOUSE_SCROLL_LINES; - } else { - new_file = top_file + (k->y - 13); - } - } - } else if (slash_search_mode > -1) { - int c = unicode_to_ascii(k->unicode); - if (k->sym == SDLK_RETURN || k->sym == SDLK_ESCAPE) { - if (!k->state) return 1; - slash_search_mode = -1; - status.flags |= NEED_UPDATE; - return 1; - } else if (k->sym == SDLK_BACKSPACE) { - if (k->state) return 1; - slash_search_mode--; - status.flags |= NEED_UPDATE; - reposition_at_slash_search(); - return 1; - } else if (c >= 32) { - if (k->state) return 1; - if (slash_search_mode < PATH_MAX) { - slash_search_str[ slash_search_mode ] = c; - slash_search_mode++; - reposition_at_slash_search(); - status.flags |= NEED_UPDATE; - } - return 1; - } - } - - switch (k->sym) { - case SDLK_UP: - new_file--; - slash_search_mode = -1; - break; - case SDLK_DOWN: - new_file++; - slash_search_mode = -1; - break; - case SDLK_PAGEUP: - new_file -= 35; - slash_search_mode = -1; - break; - case SDLK_PAGEDOWN: - new_file += 35; - slash_search_mode = -1; - break; - case SDLK_HOME: - new_file = 0; - slash_search_mode = -1; - break; - case SDLK_END: - new_file = flist.num_files - 1; - slash_search_mode = -1; - break; - case SDLK_RETURN: - if (!k->state) return 0; - handle_enter_key(); - slash_search_mode = -1; - return 1; - case SDLK_DELETE: - if (k->state) return 1; - slash_search_mode = -1; - if (flist.num_files > 0) - dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); - return 1; - case SDLK_ESCAPE: - slash_search_mode = -1; - if (k->state && NO_MODIFIER(k->mod)) - set_page(PAGE_INSTRUMENT_LIST); - return 1; - case SDLK_SLASH: - if (k->orig_sym == SDLK_SLASH) { - if (status.flags & CLASSIC_MODE) return 0; - if (!k->state) return 0; - slash_search_mode = 0; - status.flags |= NEED_UPDATE; - return 1; - } - default: - if (!k->mouse) return 0; - } - - if (k->mouse == MOUSE_CLICK) { - if (!k->state) return 0; - } else if (k->mouse == MOUSE_DBLCLICK) { - handle_enter_key(); - return 1; - } else { - if (k->state) return 0; - } - - new_file = CLAMP(new_file, 0, flist.num_files - 1); - if (new_file < 0) new_file = 0; - if (new_file != current_file) { - current_file = new_file; - file_list_reposition(); - status.flags |= NEED_UPDATE; - } - return 1; + if (k->mouse != MOUSE_NONE) { + if (k->x >= 6 && k->x <= 67 && k->y >= 13 && k->y <= 47) { + slash_search_mode = -1; + if (k->mouse == MOUSE_SCROLL_UP) { + new_file -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_file += MOUSE_SCROLL_LINES; + } else { + new_file = top_file + (k->y - 13); + } + } + } else if (slash_search_mode > -1) { + int c = unicode_to_ascii(k->unicode); + if (k->sym == SDLK_RETURN || k->sym == SDLK_ESCAPE) { + if (k->state == KEY_PRESS) + return 1; + slash_search_mode = -1; + status.flags |= NEED_UPDATE; + return 1; + } else if (k->sym == SDLK_BACKSPACE) { + if (k->state == KEY_RELEASE) + return 1; + slash_search_mode--; + status.flags |= NEED_UPDATE; + reposition_at_slash_search(); + return 1; + } else if (c >= 32) { + if (k->state == KEY_RELEASE) + return 1; + if (slash_search_mode < PATH_MAX) { + slash_search_str[ slash_search_mode ] = c; + slash_search_mode++; + reposition_at_slash_search(); + status.flags |= NEED_UPDATE; + } + return 1; + } + } + + switch (k->sym) { + case SDLK_UP: + new_file--; + slash_search_mode = -1; + break; + case SDLK_DOWN: + new_file++; + slash_search_mode = -1; + break; + case SDLK_PAGEUP: + new_file -= 35; + slash_search_mode = -1; + break; + case SDLK_PAGEDOWN: + new_file += 35; + slash_search_mode = -1; + break; + case SDLK_HOME: + new_file = 0; + slash_search_mode = -1; + break; + case SDLK_END: + new_file = flist.num_files - 1; + slash_search_mode = -1; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + handle_enter_key(); + slash_search_mode = -1; + return 1; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 1; + slash_search_mode = -1; + if (flist.num_files > 0) + dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); + return 1; + case SDLK_ESCAPE: + slash_search_mode = -1; + if (k->state == KEY_RELEASE && NO_MODIFIER(k->mod)) + set_page(PAGE_INSTRUMENT_LIST); + return 1; + case SDLK_SLASH: + if (k->orig_sym == SDLK_SLASH) { + if (status.flags & CLASSIC_MODE) return 0; + if (k->state == KEY_RELEASE) + return 0; + slash_search_mode = 0; + status.flags |= NEED_UPDATE; + return 1; + } + default: + if (k->mouse == MOUSE_NONE) + return 0; + } + + if (k->mouse == MOUSE_CLICK) { + if (k->state == KEY_RELEASE) + return 0; + } else if (k->mouse == MOUSE_DBLCLICK) { + handle_enter_key(); + return 1; + } else { + if (k->state == KEY_PRESS) + return 0; + } + + new_file = CLAMP(new_file, 0, flist.num_files - 1); + if (new_file < 0) new_file = 0; + if (new_file != current_file) { + current_file = new_file; + file_list_reposition(); + status.flags |= NEED_UPDATE; + } + return 1; } static void load_instrument_handle_key(struct key_event * k) { - if (!k->state) return; - if (k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod)) - set_page(PAGE_INSTRUMENT_LIST); + if (k->state == KEY_RELEASE) + return; + if (k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod)) + set_page(PAGE_INSTRUMENT_LIST); } /* --------------------------------------------------------------------------------------------------------- */ void load_instrument_load_page(struct page *page) { - clear_directory(); + clear_directory(); - page->title = "Load Instrument"; - page->draw_const = load_instrument_draw_const; - page->set_page = load_instrument_set_page; - page->handle_key = load_instrument_handle_key; - page->total_widgets = 1; - page->widgets = widgets_loadinst; - page->help_index = HELP_GLOBAL; - create_other(widgets_loadinst + 0, 0, file_list_handle_key, file_list_draw); - widgets_loadinst[0].accept_text = 1; + page->title = "Load Instrument"; + page->draw_const = load_instrument_draw_const; + page->set_page = load_instrument_set_page; + page->handle_key = load_instrument_handle_key; + page->total_widgets = 1; + page->widgets = widgets_loadinst; + page->help_index = HELP_GLOBAL; + create_other(widgets_loadinst + 0, 0, file_list_handle_key, file_list_draw); + widgets_loadinst[0].accept_text = 1; } void library_instrument_load_page(struct page *page) { - page->title = "Instrument Library (Ctrl-F4)"; - page->draw_const = load_instrument_draw_const; - page->set_page = library_instrument_set_page; - page->handle_key = load_instrument_handle_key; - page->total_widgets = 1; - page->widgets = widgets_loadinst; - page->help_index = HELP_GLOBAL; + page->title = "Instrument Library (Ctrl-F4)"; + page->draw_const = load_instrument_draw_const; + page->set_page = library_instrument_set_page; + page->handle_key = load_instrument_handle_key; + page->total_widgets = 1; + page->widgets = widgets_loadinst; + page->help_index = HELP_GLOBAL; } diff -Nru schism-0+20110101/schism/page_loadmodule.c schism-20160521/schism/page_loadmodule.c --- schism-0+20110101/schism/page_loadmodule.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_loadmodule.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -59,13 +59,13 @@ inline static int _fnmatch(const char *m, const char *s); inline static int _fnmatch(const char *m, const char *s) { - if (*m == '*') for (++m; *s; ++s) if (!_fnmatch(m, s)) return 0; - return (!*s || !(*m == '?' || tolower(*s) == tolower(*m))) - ? tolower(*m) | tolower(*s) : _fnmatch(++m, ++s); + if (*m == '*') for (++m; *s; ++s) if (!_fnmatch(m, s)) return 0; + return (!*s || !(*m == '?' || tolower(*s) == tolower(*m))) + ? tolower(*m) | tolower(*s) : _fnmatch(++m, ++s); } inline static int xfnmatch(const char *m, const char *s, UNUSED int f) { - return (*s == '.' && *m != '.') ? 0 : _fnmatch(m, s); + return (*s == '.' && *m != '.') ? 0 : _fnmatch(m, s); } #endif /* !HAVE_FNMATCH */ @@ -106,15 +106,15 @@ /* impulse tracker's glob list: - *.it; *.xm; *.s3m; *.mtm; *.669; *.mod + *.it; *.xm; *.s3m; *.mtm; *.669; *.mod unsupported formats that the title reader knows about, even though we can't load them: - *.f2r; *.liq; *.dtm; *.ntk; *.mf + *.f2r; *.liq; *.dtm; *.ntk; *.mf formats that might be supported, but which i have never seen and thus don't actually care about: - *.dbm; *.dsm; *.psm + *.dbm; *.dsm; *.psm other formats that i wouldn't bother presenting in the loader even if we could load them: - *.mid; *.wav; *.mp3; *.ogg; *.sid; *.umx + *.mid; *.wav; *.mp3; *.ogg; *.sid; *.umx formats that modplug pretends to support, but fails hard: - *.ams + *.ams TODO: scroller hack on selected filename */ @@ -126,6 +126,7 @@ static char dirname_entry[PATH_MAX + 1] = ""; char cfg_module_pattern[PATH_MAX + 1] = GLOB_DEFAULT; +char cfg_export_pattern[PATH_MAX + 1] = "*.wav; *.aiff; *.aif"; static char **glob_list = NULL; static char glob_list_src[PATH_MAX + 1] = ""; // the pattern used to make glob_list (this is an icky hack) @@ -133,40 +134,40 @@ static char **semicolon_split(const char *i) { - int n = 1; - const char *j; - char *a, *z, **o, **p; - - if (!i) - return NULL; - i += strspn(i, "; \t"); - if (!*i) - return NULL; - - /* how many MIGHT we have? */ - for (j = i; j; j = strchr(j + 1, ';')) - n++; - - o = p = calloc(n, sizeof(char *)); - a = strdup(i); - - do { - *p++ = a; - z = strchr(a, ';'); - if (!z) - z = strchr(a, 0); - /* trim whitespace */ - do { - z--; - } while (isblank(*z)); - z++; - /* find start of the next one */ - a = z; - a += strspn(a, "; \t"); - *z = 0; - } while (*a); + int n = 1; + const char *j; + char *a, *z, **o, **p; + + if (!i) + return NULL; + i += strspn(i, "; \t"); + if (!*i) + return NULL; + + /* how many MIGHT we have? */ + for (j = i; j; j = strchr(j + 1, ';')) + n++; + + o = p = calloc(n, sizeof(char *)); + a = strdup(i); + + do { + *p++ = a; + z = strchr(a, ';'); + if (!z) + z = strchr(a, 0); + /* trim whitespace */ + do { + z--; + } while (isblank(*z)); + z++; + /* find start of the next one */ + a = z; + a += strspn(a, "; \t"); + *z = 0; + } while (*a); - return o; + return o; } /* --------------------------------------------------------------------- */ @@ -182,135 +183,134 @@ static void handle_file_entered_L(const char *ptr) { - dmoz_filelist_t tmp; - struct stat sb; - dmoz_file_t *f; - - /* these shenanigans force the file to take another trip... */ - if (stat(ptr, &sb) == -1) - return; - - memset(&tmp, 0, sizeof(tmp)); - f = dmoz_add_file(&tmp, str_dup(ptr), str_dup(ptr), &sb, 0); - dmoz_free(&tmp, NULL); + dmoz_filelist_t tmp; + struct stat sb; - song_load(ptr); + /* these shenanigans force the file to take another trip... */ + if (stat(ptr, &sb) == -1) + return; + + memset(&tmp, 0, sizeof(tmp)); + dmoz_add_file(&tmp, str_dup(ptr), str_dup(ptr), &sb, 0); + dmoz_free(&tmp, NULL); + + song_load(ptr); } static void loadsave_song_changed(void) { - int r = 4; /* what? */ - int i; - const char *ext; - const char *ptr = song_get_filename(); - - if (!ptr) - return; - ext = get_extension(ptr); - if (ext[0] && ext[1]) { - for (i = 0; song_save_formats[i].label; i++) { - if (strcasecmp(ext, song_save_formats[i].ext) == 0) { - /* ugh :) offset to the button for the file type on the save module - page is (position in diskwriter driver array) + 4 */ - r = i + 4; - break; - } - } - } - togglebutton_set(widgets_savemodule, r, 0); + int r = 4; /* what? */ + int i; + const char *ext; + const char *ptr = song_get_filename(); + + if (!ptr) + return; + ext = get_extension(ptr); + if (ext[0] && ext[1]) { + for (i = 0; song_save_formats[i].label; i++) { + if (strcasecmp(ext, song_save_formats[i].ext) == 0) { + /* ugh :) offset to the button for the file type on the save module + page is (position in diskwriter driver array) + 4 */ + r = i + 4; + break; + } + } + } + togglebutton_set(widgets_savemodule, r, 0); } /* NOTE: ptr should be dynamically allocated, or NULL */ static void do_save_song(char *ptr) { - int ret, export = (status.current_page == PAGE_EXPORT_MODULE); - const char *filename = ptr ?: song_get_filename(); - const char *seltype = NULL; - struct widget *widget; - - set_page(PAGE_LOG); - - // 4 is the index of the first file-type button - for (widget = (export ? widgets_exportmodule : widgets_savemodule) + 4; - widget->type == WIDGET_TOGGLEBUTTON; widget++) { - if (widget->d.togglebutton.state) { - // Aha! - seltype = widget->d.togglebutton.text; - break; - } - } - - if (!seltype) { - // No button was selected? (should never happen) - log_appendf(4, "No file format selected?"); - ret = SAVE_INTERNAL_ERROR; - } else if (export) { - ret = song_export(filename, seltype); - } else { - ret = song_save(filename, seltype); - } + int ret, export = (status.current_page == PAGE_EXPORT_MODULE); + const char *filename = ptr ?: song_get_filename(); + const char *seltype = NULL; + struct widget *widget; + + set_page(PAGE_LOG); + + // 4 is the index of the first file-type button + for (widget = (export ? widgets_exportmodule : widgets_savemodule) + 4; + widget->type == WIDGET_TOGGLEBUTTON; widget++) { + if (widget->d.togglebutton.state) { + // Aha! + seltype = widget->d.togglebutton.text; + break; + } + } + + if (!seltype) { + // No button was selected? (should never happen) + log_appendf(4, "No file format selected?"); + ret = SAVE_INTERNAL_ERROR; + } else if (export) { + ret = song_export(filename, seltype); + } else { + ret = song_save(filename, seltype); + } - if (ret != SAVE_SUCCESS) - dialog_create(DIALOG_OK, "Could not save file", NULL, NULL, 0, NULL); + if (ret != SAVE_SUCCESS) + dialog_create(DIALOG_OK, "Could not save file", NULL, NULL, 0, NULL); - free(ptr); + free(ptr); } void save_song_or_save_as(void) { - const char *f = song_get_filename(); - if (f && *f) { - do_save_song(str_dup(f)); - } else { - set_page(PAGE_SAVE_MODULE); - } + const char *f = song_get_filename(); + if (f && *f) { + do_save_song(str_dup(f)); + } else { + set_page(PAGE_SAVE_MODULE); + } } static void do_save_song_overwrite(void *ptr) { - struct stat st; + struct stat st; - if (!(status.flags & CLASSIC_MODE)) { - // say what? - do_save_song(ptr); - return; - } - - if (stat(cfg_dir_modules, &st) == -1 || directory_mtime != st.st_mtime) { - status.flags |= DIR_MODULES_CHANGED; - } - - do_save_song(ptr); - - /* this is wrong, sadly... */ - if (stat(cfg_dir_modules, &st) == 0) { - directory_mtime = st.st_mtime; - } + if (!(status.flags & CLASSIC_MODE)) { + // say what? + do_save_song(ptr); + return; + } + + if (stat(cfg_dir_modules, &st) == -1 || directory_mtime != st.st_mtime) { + status.flags |= DIR_MODULES_CHANGED; + } + + do_save_song(ptr); + + /* this is wrong, sadly... */ + if (stat(cfg_dir_modules, &st) == 0) { + directory_mtime = st.st_mtime; + } } static void handle_file_entered_S(const char *name) { - struct stat buf; + struct stat buf; - if (stat(name, &buf) < 0) { - if (errno == ENOENT) { - do_save_song(str_dup(name)); - } else { - log_perror(name); - } - } else { - if (S_ISDIR(buf.st_mode)) { - /* TODO: maybe change the current directory in this case? */ - log_appendf(4, "%s: Is a directory", name); - } else if (S_ISREG(buf.st_mode)) { - dialog_create(DIALOG_OK_CANCEL, "Overwrite file?", - do_save_song_overwrite, free, 1, str_dup(name)); - } else { - /* log_appendf(4, "%s: Not overwriting non-regular file", ptr); */ - dialog_create(DIALOG_OK, "Not a regular file", NULL, NULL, 0, NULL); - } - } + if (stat(name, &buf) < 0) { + if (errno == ENOENT) { + do_save_song(str_dup(name)); + } else { + log_perror(name); + } + } else { + if (S_ISDIR(buf.st_mode)) { + /* TODO: maybe change the current directory in this case? */ + log_appendf(4, "%s: Is a directory", name); + } else if (S_ISREG(buf.st_mode)) { + dialog_create(DIALOG_OK_CANCEL, "Overwrite file?", + do_save_song_overwrite, free, 1, str_dup(name)); + } else { + /* log_appendf(4, "%s: Not overwriting non-regular file", ptr); */ + dialog_create(DIALOG_OK, "Not a regular file", NULL, NULL, 0, NULL); + } + } } @@ -321,116 +321,119 @@ /* get a color index from a dmoz_file_t 'type' field */ static inline int get_type_color(int type) { - /* 7 unknown - 3 it - 5 s3m - 6 xm - 2 mod - 4 other - 7 sample */ - switch (type) { - case TYPE_MODULE_MOD: return 2; - case TYPE_MODULE_S3M: return 5; - case TYPE_MODULE_XM: return 6; - case TYPE_MODULE_IT: return 3; - case TYPE_SAMPLE_COMPR: return 4; /* mp3/ogg 'sample'... i think */ - default: return 7; - } + /* 7 unknown + 3 it + 5 s3m + 6 xm + 2 mod + 4 other + 7 sample */ + switch (type) { + case TYPE_MODULE_MOD: return 2; + case TYPE_MODULE_S3M: return 5; + case TYPE_MODULE_XM: return 6; + case TYPE_MODULE_IT: return 3; + case TYPE_SAMPLE_COMPR: return 4; /* mp3/ogg 'sample'... i think */ + default: return 7; + } } static void clear_directory(void) { - dmoz_free(&flist, &dlist); + dmoz_free(&flist, &dlist); } static int modgrep(dmoz_file_t *f) { - int i = 0; + int i = 0; - if (!glob_list) - return 1; - for (i = 0; glob_list[i]; i++) { - if (fnmatch(glob_list[i], f->base, FNM_PERIOD | FNM_CASEFOLD) == 0) - return 1; - } - return 0; + if (!glob_list) + return 1; + for (i = 0; glob_list[i]; i++) { + if (fnmatch(glob_list[i], f->base, FNM_PERIOD | FNM_CASEFOLD) == 0) + return 1; + } + return 0; } /* --------------------------------------------------------------------- */ static void file_list_reposition(void) { - if (current_file >= flist.num_files) - current_file = flist.num_files-1; - if (current_file < 0) current_file = 0; - if (current_file < top_file) - top_file = current_file; - else if (current_file > top_file + 30) - top_file = current_file - 30; - status.flags |= NEED_UPDATE; + if (current_file >= flist.num_files) + current_file = flist.num_files-1; + if (current_file < 0) current_file = 0; + if (current_file < top_file) + top_file = current_file; + else if (current_file > top_file + 30) + top_file = current_file - 30; + status.flags |= NEED_UPDATE; } static void dir_list_reposition(void) { - if (current_dir >= dlist.num_dirs) - current_dir = dlist.num_dirs-1; - if (current_dir < 0) current_dir = 0; - if (current_dir < top_dir) - top_dir = current_dir; - else if (current_dir > top_dir + 20) - top_dir = current_dir - 20; - status.flags |= NEED_UPDATE; + if (current_dir >= dlist.num_dirs) + current_dir = dlist.num_dirs-1; + if (current_dir < 0) current_dir = 0; + if (current_dir < top_dir) + top_dir = current_dir; + else if (current_dir > top_dir + 20) + top_dir = current_dir - 20; + status.flags |= NEED_UPDATE; } static void read_directory(void) { - struct stat st; + struct stat st; - clear_directory(); + clear_directory(); - if (stat(cfg_dir_modules, &st) < 0) - directory_mtime = 0; - else - directory_mtime = st.st_mtime; - /* if the stat call failed, this will probably break as well, but - at the very least, it'll add an entry for the root directory. */ - if (dmoz_read(cfg_dir_modules, &flist, &dlist, NULL) < 0) - log_perror(cfg_dir_modules); - dmoz_filter_filelist(&flist, modgrep, ¤t_file, file_list_reposition); - while (dmoz_worker()); /* don't do it asynchronously */ - dmoz_cache_lookup(cfg_dir_modules, &flist, &dlist); - // background the title checker - dmoz_filter_filelist(&flist, dmoz_fill_ext_data, ¤t_file, file_list_reposition); - file_list_reposition(); - dir_list_reposition(); + if (stat(cfg_dir_modules, &st) < 0) + directory_mtime = 0; + else + directory_mtime = st.st_mtime; + /* if the stat call failed, this will probably break as well, but + at the very least, it'll add an entry for the root directory. */ + if (dmoz_read(cfg_dir_modules, &flist, &dlist, NULL) < 0) + log_perror(cfg_dir_modules); + dmoz_filter_filelist(&flist, modgrep, ¤t_file, file_list_reposition); + while (dmoz_worker()); /* don't do it asynchronously */ + dmoz_cache_lookup(cfg_dir_modules, &flist, &dlist); + // background the title checker + dmoz_filter_filelist(&flist, dmoz_fill_ext_data, ¤t_file, file_list_reposition); + file_list_reposition(); + dir_list_reposition(); } /* --------------------------------------------------------------------- */ static void set_glob(const char *globspec) { - if (glob_list) { - free(*glob_list); - free(glob_list); - } - strncpy(glob_list_src, globspec, PATH_MAX); - glob_list_src[PATH_MAX] = '\0'; - glob_list = semicolon_split(glob_list_src); - /* this is kinda lame. dmoz should have a way to reload the list without rereading the directory. - could be done with a "visible" flag, which affects the list's sort order, along with adjusting - the file count... */ - read_directory(); + if (glob_list) { + free(*glob_list); + free(glob_list); + } + strncpy(glob_list_src, globspec, PATH_MAX); + glob_list_src[PATH_MAX] = '\0'; + glob_list = semicolon_split(glob_list_src); + /* this is kinda lame. dmoz should have a way to reload the list without rereading the directory. + could be done with a "visible" flag, which affects the list's sort order, along with adjusting + the file count... */ + read_directory(); } static void set_default_glob(int set_filename) { - const char *s = cfg_module_pattern; - if (set_filename) { - /* glob on load page is visible, but on save page the text should be empty */ - strcpy(filename_entry, s); - } - set_glob(s); + const char *s = (status.current_page == PAGE_EXPORT_MODULE) + ? cfg_export_pattern + : cfg_module_pattern; + + if (set_filename) { + /* glob on load page is visible, but on save page the text should be empty */ + strcpy(filename_entry, s); + } + set_glob(s); } /* --------------------------------------------------------------------- */ @@ -441,85 +444,82 @@ static void search_redraw(void) { - draw_fill_chars(51, 37, 76, 37, 0); - draw_text_len(search_text + search_first_char, 25, 51, 37, 5, 0); + draw_fill_chars(51, 37, 76, 37, 0); + draw_text_len(search_text + search_first_char, 25, 51, 37, 5, 0); - /* draw the cursor if it's on the dir/file list */ - if (ACTIVE_PAGE.selected_widget == 0 || ACTIVE_PAGE.selected_widget == 1) { - draw_char(0, 51 + search_text_length - search_first_char, 37, 6, 6); - } + /* draw the cursor if it's on the dir/file list */ + if (ACTIVE_PAGE.selected_widget == 0 || ACTIVE_PAGE.selected_widget == 1) { + draw_char(0, 51 + search_text_length - search_first_char, 37, 6, 6); + } } static void search_update(void) { - int found_something = 0; - int n; + int n; - if (search_text_length > 25) - search_first_char = search_text_length - 25; - else - search_first_char = 0; - - /* go through the file/dir list (whatever one is selected) and - * find the first entry matching the text */ - if (*selected_widget == 0) { - for (n = 0; n < flist.num_files; n++) { - if (strncasecmp(flist.files[n]->base, search_text, search_text_length) == 0) { - found_something = 1; - current_file = n; - file_list_reposition(); - break; - } - } - } else { - for (n = 0; n < dlist.num_dirs; n++) { - if (strncasecmp(dlist.dirs[n]->base, search_text, search_text_length) == 0) { - found_something = 1; - current_dir = n; - dir_list_reposition(); - break; - } - } - } + if (search_text_length > 25) + search_first_char = search_text_length - 25; + else + search_first_char = 0; + + /* go through the file/dir list (whatever one is selected) and + * find the first entry matching the text */ + if (*selected_widget == 0) { + for (n = 0; n < flist.num_files; n++) { + if (strncasecmp(flist.files[n]->base, search_text, search_text_length) == 0) { + current_file = n; + file_list_reposition(); + break; + } + } + } else { + for (n = 0; n < dlist.num_dirs; n++) { + if (strncasecmp(dlist.dirs[n]->base, search_text, search_text_length) == 0) { + current_dir = n; + dir_list_reposition(); + break; + } + } + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static int search_text_add_char(char c) { - if (c < 32) - return 0; + if (c < 32) + return 0; - if (search_text_length >= NAME_MAX) - return 1; + if (search_text_length >= NAME_MAX) + return 1; - search_text[search_text_length++] = c; - search_text[search_text_length] = 0; - search_update(); + search_text[search_text_length++] = c; + search_text[search_text_length] = 0; + search_update(); - return 1; + return 1; } static void search_text_delete_char(void) { - if (search_text_length == 0) - return; + if (search_text_length == 0) + return; - search_text[--search_text_length] = 0; + search_text[--search_text_length] = 0; - if (search_text_length > 25) - search_first_char = search_text_length - 25; - else - search_first_char = 0; + if (search_text_length > 25) + search_first_char = search_text_length - 25; + else + search_first_char = 0; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static void search_text_clear(void) { - search_text[0] = search_text_length = search_first_char = 0; + search_text[0] = search_text_length = search_first_char = 0; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -528,23 +528,23 @@ TODO: provide some sort of feedback if something went wrong. */ static int change_dir(const char *dir) { - char *ptr = dmoz_path_normal(dir); + char *ptr = dmoz_path_normal(dir); - if (!ptr) - return 0; + if (!ptr) + return 0; - dmoz_cache_update(cfg_dir_modules, &flist, &dlist); + dmoz_cache_update(cfg_dir_modules, &flist, &dlist); - strncpy(cfg_dir_modules, ptr, PATH_MAX); - cfg_dir_modules[PATH_MAX] = 0; - strcpy(dirname_entry, cfg_dir_modules); - free(ptr); + strncpy(cfg_dir_modules, ptr, PATH_MAX); + cfg_dir_modules[PATH_MAX] = 0; + strcpy(dirname_entry, cfg_dir_modules); + free(ptr); - /* probably not all of this is needed everywhere */ - search_text_clear(); - read_directory(); + /* probably not all of this is needed everywhere */ + search_text_clear(); + read_directory(); - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -553,333 +553,363 @@ static void load_module_draw_const(void) { - draw_text("Filename", 4, 46, 0, 2); - draw_text("Directory", 3, 47, 0, 2); - draw_char(0, 51, 37, 0, 6); - draw_box(2, 12, 47, 44, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(49, 12, 68, 34, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(50, 36, 77, 38, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(50, 39, 77, 44, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(12, 45, 77, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Filename", 4, 46, 0, 2); + draw_text("Directory", 3, 47, 0, 2); + draw_char(0, 51, 37, 0, 6); + draw_box(2, 12, 47, 44, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(49, 12, 68, 34, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(50, 36, 77, 38, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(50, 39, 77, 44, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(12, 45, 77, 48, BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(51, 37, 76, 37, 0); - draw_fill_chars(13, 46, 76, 47, 0); + draw_fill_chars(51, 37, 76, 37, 0); + draw_fill_chars(13, 46, 76, 47, 0); } static void save_module_draw_const(void) { - load_module_draw_const(); + load_module_draw_const(); } /* --------------------------------------------------------------------- */ static void file_list_draw(void) { - int n, pos; - int fg1, fg2, bg; - char buf[32]; - dmoz_file_t *file; - - draw_fill_chars(3, 13, 46, 43, 0); - - if (flist.num_files > 0) { - if (top_file < 0) top_file = 0; - if (current_file < 0) current_file = 0; - for (n = top_file, pos = 13; n < flist.num_files && pos < 44; n++, pos++) { - file = flist.files[n]; - - if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { - fg1 = fg2 = 0; - bg = 3; - } else { - fg1 = get_type_color(file->type); - fg2 = (file->type & TYPE_MODULE_MASK) ? 3 : 7; - bg = 0; - } - - draw_text_len(file->base, 18, 3, pos, fg1, bg); - draw_char(168, 21, pos, 2, bg); - draw_text_len(file->title ?: "", 25, 22, pos, fg2, bg); - } - - /* info for the current file */ - if (current_file >= 0 && current_file < flist.num_files) { - file = flist.files[current_file]; - draw_text_len(file->description ?: "", 26, 51, 40, 5, 0); - sprintf(buf, "%09lu", (unsigned long)file->filesize); - draw_text_len(buf, 26, 51, 41, 5, 0); - draw_text_len(get_date_string(file->timestamp, buf), 26, 51, 42, 5, 0); - draw_text_len(get_time_string(file->timestamp, buf), 26, 51, 43, 5, 0); - } - } else { - if (ACTIVE_PAGE.selected_widget == 0) { - draw_text("No files.", 3, 13, 0, 3); - draw_fill_chars(12, 13, 46, 13, 3); - draw_char(168, 21, 13, 2, 3); - pos = 14; - } else { - draw_text("No files.", 3, 13, 7, 0); - pos = 13; - } - draw_fill_chars(51, 40, 76, 43, 0); - } + int n, pos; + int fg1, fg2, bg; + char buf[32]; + dmoz_file_t *file; + + draw_fill_chars(3, 13, 46, 43, 0); + + if (flist.num_files > 0) { + if (top_file < 0) top_file = 0; + if (current_file < 0) current_file = 0; + for (n = top_file, pos = 13; n < flist.num_files && pos < 44; n++, pos++) { + file = flist.files[n]; + + if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { + fg1 = fg2 = 0; + bg = 3; + } else { + fg1 = get_type_color(file->type); + fg2 = (file->type & TYPE_MODULE_MASK) ? 3 : 7; + bg = 0; + } + + draw_text_len(file->base, 18, 3, pos, fg1, bg); + draw_char(168, 21, pos, 2, bg); + draw_text_len(file->title ?: "", 25, 22, pos, fg2, bg); + } + + /* info for the current file */ + if (current_file >= 0 && current_file < flist.num_files) { + file = flist.files[current_file]; + draw_text_len(file->description ?: "", 26, 51, 40, 5, 0); + sprintf(buf, "%09lu", (unsigned long)file->filesize); + draw_text_len(buf, 26, 51, 41, 5, 0); + draw_text_len(get_date_string(file->timestamp, buf), 26, 51, 42, 5, 0); + draw_text_len(get_time_string(file->timestamp, buf), 26, 51, 43, 5, 0); + } + } else { + if (ACTIVE_PAGE.selected_widget == 0) { + draw_text("No files.", 3, 13, 0, 3); + draw_fill_chars(12, 13, 46, 13, 3); + draw_char(168, 21, 13, 2, 3); + pos = 14; + } else { + draw_text("No files.", 3, 13, 7, 0); + pos = 13; + } + draw_fill_chars(51, 40, 76, 43, 0); + } - while (pos < 44) - draw_char(168, 21, pos++, 2, 0); + while (pos < 44) + draw_char(168, 21, pos++, 2, 0); - /* bleh */ - search_redraw(); + /* bleh */ + search_redraw(); } static void do_delete_file(UNUSED void *data) { - int old_top_file, old_current_file, old_top_dir, old_current_dir; - char *ptr; + int old_top_file, old_current_file, old_top_dir, old_current_dir; + char *ptr; - if (current_file < 0 || current_file >= flist.num_files) - return; + if (current_file < 0 || current_file >= flist.num_files) + return; - ptr = flist.files[current_file]->path; + ptr = flist.files[current_file]->path; - /* would be neat to send it to the trash can if there is one */ - unlink(ptr); - - /* remember the list positions */ - old_top_file = top_file; - old_current_file = current_file; - old_top_dir = top_dir; - old_current_dir = current_dir; - - search_text_clear(); - read_directory(); - - /* put the list positions back */ - top_file = old_top_file; - current_file = old_current_file; - top_dir = old_top_dir; - current_dir = old_current_dir; - /* edge case: if this was the last file, move the cursor up */ - if (current_file >= flist.num_files) - current_file = flist.num_files - 1; - file_list_reposition(); + /* would be neat to send it to the trash can if there is one */ + unlink(ptr); + + /* remember the list positions */ + old_top_file = top_file; + old_current_file = current_file; + old_top_dir = top_dir; + old_current_dir = current_dir; + + search_text_clear(); + read_directory(); + + /* put the list positions back */ + top_file = old_top_file; + current_file = old_current_file; + top_dir = old_top_dir; + current_dir = old_current_dir; + /* edge case: if this was the last file, move the cursor up */ + if (current_file >= flist.num_files) + current_file = flist.num_files - 1; + file_list_reposition(); +} + +static void show_selected_song_length(void) +{ + if (current_file < 0 || current_file >= flist.num_files) + return; + + char *ptr = flist.files[current_file]->path; + song_t *song = song_create_load(ptr); + if (!song) { + log_appendf(4, "%s: %s", ptr, fmt_strerror(errno)); + return; + } + show_length_dialog(get_basename(ptr), csf_get_length(song)); + csf_free(song); } static int file_list_handle_key(struct key_event * k) { - int new_file = current_file; + int new_file = current_file; - switch (k->sym) { - case SDLK_UP: - new_file--; - break; - case SDLK_DOWN: - new_file++; - break; - case SDLK_PAGEUP: - new_file -= 31; - break; - case SDLK_PAGEDOWN: - new_file += 31; - break; - case SDLK_HOME: - new_file = 0; - break; - case SDLK_END: - new_file = flist.num_files - 1; - break; - case SDLK_RETURN: - if (!k->state) return 1; - if (current_file < flist.num_files) { - dmoz_cache_update(cfg_dir_modules, &flist, &dlist); - handle_file_entered(flist.files[current_file]->path); - } - search_text_clear(); - - return 1; - case SDLK_DELETE: - if (k->state) return 1; - if (flist.num_files > 0) - dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); - return 1; - case SDLK_BACKSPACE: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) - search_text_clear(); - else - search_text_delete_char(); - return 1; - default: - if (k->mouse == 0) { - if (k->state) return 0; - return search_text_add_char(k->unicode); - } - } - - if (k->mouse && !(k->x >=3 && k->x <= 46 && k->y >= 13 && k->y <= 43)) - return 0; - switch (k->mouse) { - case MOUSE_CLICK: - if (!k->state) - return 0; - new_file = (k->y - 13) + top_file; - break; - case MOUSE_DBLCLICK: - if (current_file < flist.num_files) { - dmoz_cache_update(cfg_dir_modules, &flist, &dlist); - handle_file_entered(flist.files[current_file]->path); - } - search_text_clear(); - return 1; - case MOUSE_SCROLL_UP: - case MOUSE_SCROLL_DOWN: - if (!k->state) - return 0; - top_file += (k->mouse == MOUSE_SCROLL_UP) ? -MOUSE_SCROLL_LINES : MOUSE_SCROLL_LINES; - /* don't allow scrolling down past either end. - this can't be CLAMP'd because the first check might scroll - too far back if the list is small. - (hrm, should add a BOTTOM_FILE macro or something) */ - if (top_file > flist.num_files - 31) - top_file = flist.num_files - 31; - if (top_file < 0) - top_file = 0; - status.flags |= NEED_UPDATE; - return 1; - default: - /* hmm? */ - if (k->state) - return 1; - } - - new_file = CLAMP(new_file, 0, flist.num_files - 1); - if (new_file < 0) new_file = 0; - if (new_file != current_file) { - current_file = new_file; - file_list_reposition(); - status.flags |= NEED_UPDATE; - } - return 1; + switch (k->sym) { + case SDLK_UP: + new_file--; + break; + case SDLK_DOWN: + new_file++; + break; + case SDLK_PAGEUP: + new_file -= 31; + break; + case SDLK_PAGEDOWN: + new_file += 31; + break; + case SDLK_HOME: + new_file = 0; + break; + case SDLK_END: + new_file = flist.num_files - 1; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 1; + if (current_file < flist.num_files) { + dmoz_cache_update(cfg_dir_modules, &flist, &dlist); + handle_file_entered(flist.files[current_file]->path); + } + search_text_clear(); + + return 1; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 1; + if (flist.num_files > 0) + dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); + return 1; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) + search_text_clear(); + else + search_text_delete_char(); + return 1; + case SDLK_p: + if ((k->mod & KMOD_ALT) && k->state == KEY_PRESS) { + show_selected_song_length(); + return 1; + } /* else fall through */ + default: + if (k->mouse == MOUSE_NONE) { + if (k->state == KEY_RELEASE) + return 0; + return search_text_add_char(k->unicode); + } + } + + if (k->mouse != MOUSE_NONE && !(k->x >=3 && k->x <= 46 && k->y >= 13 && k->y <= 43)) + return 0; + switch (k->mouse) { + case MOUSE_CLICK: + if (k->state == KEY_PRESS) + return 0; + new_file = (k->y - 13) + top_file; + break; + case MOUSE_DBLCLICK: + if (current_file < flist.num_files) { + dmoz_cache_update(cfg_dir_modules, &flist, &dlist); + handle_file_entered(flist.files[current_file]->path); + } + search_text_clear(); + return 1; + case MOUSE_SCROLL_UP: + case MOUSE_SCROLL_DOWN: + if (k->state == KEY_PRESS) + return 0; + top_file += (k->mouse == MOUSE_SCROLL_UP) ? -MOUSE_SCROLL_LINES : MOUSE_SCROLL_LINES; + /* don't allow scrolling down past either end. + this can't be CLAMP'd because the first check might scroll + too far back if the list is small. + (hrm, should add a BOTTOM_FILE macro or something) */ + if (top_file > flist.num_files - 31) + top_file = flist.num_files - 31; + if (top_file < 0) + top_file = 0; + status.flags |= NEED_UPDATE; + return 1; + default: + /* hmm? */ + if (k->state == KEY_RELEASE) + return 1; + } + + new_file = CLAMP(new_file, 0, flist.num_files - 1); + if (new_file < 0) new_file = 0; + if (new_file != current_file) { + current_file = new_file; + file_list_reposition(); + status.flags |= NEED_UPDATE; + } + return 1; } /* --------------------------------------------------------------------- */ static void dir_list_draw(void) { - int n, pos; + int n, pos; - draw_fill_chars(50, 13, 67, 33, 0); + draw_fill_chars(50, 13, 67, 33, 0); - for (n = top_dir, pos = 13; pos < 34; n++, pos++) { - if (n < 0) continue; /* er... */ - if (n >= dlist.num_dirs) - break; - if (n == current_dir && ACTIVE_PAGE.selected_widget == 1) - draw_text_len(dlist.dirs[n]->base, 18, 50, pos, 0, 3); - else - draw_text_len(dlist.dirs[n]->base, 18, 50, pos, 5, 0); - } + for (n = top_dir, pos = 13; pos < 34; n++, pos++) { + if (n < 0) continue; /* er... */ + if (n >= dlist.num_dirs) + break; + if (n == current_dir && ACTIVE_PAGE.selected_widget == 1) + draw_text_len(dlist.dirs[n]->base, 18, 50, pos, 0, 3); + else + draw_text_len(dlist.dirs[n]->base, 18, 50, pos, 5, 0); + } - /* bleh */ - search_redraw(); + /* bleh */ + search_redraw(); } static int dir_list_handle_key(struct key_event * k) { - int new_dir = current_dir; + int new_dir = current_dir; - if (k->mouse) { - if (k->x >= 50 && k->x <= 67 && k->y >= 13 && k->y <= 33) { - if (k->mouse == MOUSE_CLICK) { - new_dir = (k->y - 13) + top_dir; - } else if (k->mouse == MOUSE_DBLCLICK) { - top_file = current_file = 0; - change_dir(dlist.dirs[current_dir]->path); - - if (flist.num_files > 0) - *selected_widget = 0; - status.flags |= NEED_UPDATE; - return 1; - /* FIXME wheel should be adjusting top_dir instead (and then adjust it later) */ - } else if (k->mouse == MOUSE_SCROLL_UP) { - new_dir -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_dir += MOUSE_SCROLL_LINES; - } - } else { - return 0; - } - } - - switch (k->sym) { - case SDLK_UP: - new_dir--; - break; - case SDLK_DOWN: - new_dir++; - break; - case SDLK_PAGEUP: - new_dir -= 21; - break; - case SDLK_PAGEDOWN: - new_dir += 21; - break; - case SDLK_HOME: - new_dir = 0; - break; - case SDLK_END: - new_dir = dlist.num_dirs - 1; - break; - case SDLK_RETURN: - if (!k->state) return 0; - /* reset */ - top_file = current_file = 0; - if (current_dir >= 0 && current_dir < dlist.num_dirs) - change_dir(dlist.dirs[current_dir]->path); - - if (flist.num_files > 0) - *selected_widget = 0; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_BACKSPACE: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) - search_text_clear(); - else - search_text_delete_char(); - return 1; - case SDLK_SLASH: + if (k->mouse != MOUSE_NONE) { + if (k->x >= 50 && k->x <= 67 && k->y >= 13 && k->y <= 33) { + if (k->mouse == MOUSE_CLICK) { + new_dir = (k->y - 13) + top_dir; + } else if (k->mouse == MOUSE_DBLCLICK) { + top_file = current_file = 0; + change_dir(dlist.dirs[current_dir]->path); + + if (flist.num_files > 0) + *selected_widget = 0; + status.flags |= NEED_UPDATE; + return 1; + /* FIXME wheel should be adjusting top_dir instead (and then adjust it later) */ + } else if (k->mouse == MOUSE_SCROLL_UP) { + new_dir -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_dir += MOUSE_SCROLL_LINES; + } + } else { + return 0; + } + } + + switch (k->sym) { + case SDLK_UP: + new_dir--; + break; + case SDLK_DOWN: + new_dir++; + break; + case SDLK_PAGEUP: + new_dir -= 21; + break; + case SDLK_PAGEDOWN: + new_dir += 21; + break; + case SDLK_HOME: + new_dir = 0; + break; + case SDLK_END: + new_dir = dlist.num_dirs - 1; + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + /* reset */ + top_file = current_file = 0; + if (current_dir >= 0 && current_dir < dlist.num_dirs) + change_dir(dlist.dirs[current_dir]->path); + + if (flist.num_files > 0) + *selected_widget = 0; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) + search_text_clear(); + else + search_text_delete_char(); + return 1; + case SDLK_SLASH: #ifdef WIN32 - case SDLK_BACKSLASH: + case SDLK_BACKSLASH: #endif - if (k->state) return 0; - if (search_text_length == 0 && current_dir != 0) { - // slash -> go to top (root) dir - new_dir = 0; - } else if (current_dir > 0 && current_dir < dlist.num_dirs) { - change_dir(dlist.dirs[current_dir]->path); - status.flags |= NEED_UPDATE; - return 1; - } - break; - default: - if (k->mouse == 0) { - if (k->state) return 0; - return search_text_add_char(k->unicode); - } - } - - if (k->mouse == MOUSE_CLICK) { - if (!k->state) return 0; - } else { - if (k->state) return 0; - } - new_dir = CLAMP(new_dir, 0, dlist.num_dirs - 1); - if (new_dir != current_dir) { - current_dir = new_dir; - dir_list_reposition(); - status.flags |= NEED_UPDATE; - } - return 1; + if (k->state == KEY_RELEASE) + return 0; + if (search_text_length == 0 && current_dir != 0) { + // slash -> go to top (root) dir + new_dir = 0; + } else if (current_dir > 0 && current_dir < dlist.num_dirs) { + change_dir(dlist.dirs[current_dir]->path); + status.flags |= NEED_UPDATE; + return 1; + } + break; + default: + if (k->mouse == MOUSE_NONE) { + if (k->state == KEY_RELEASE) + return 0; + return search_text_add_char(k->unicode); + } + } + + if (k->mouse == MOUSE_CLICK) { + if (k->state == KEY_PRESS) + return 0; + } else { + if (k->state == KEY_RELEASE) + return 0; + } + new_dir = CLAMP(new_dir, 0, dlist.num_dirs - 1); + if (new_dir != current_dir) { + current_dir = new_dir; + dir_list_reposition(); + status.flags |= NEED_UPDATE; + } + return 1; } /* --------------------------------------------------------------------- */ @@ -887,27 +917,27 @@ static void filename_entered(void) { - if (strpbrk(filename_entry, "?*")) { - set_glob(filename_entry); - } else { - char *ptr = dmoz_path_concat(cfg_dir_modules, filename_entry); - handle_file_entered(ptr); - free(ptr); - } + if (strpbrk(filename_entry, "?*")) { + set_glob(filename_entry); + } else { + char *ptr = dmoz_path_concat(cfg_dir_modules, filename_entry); + handle_file_entered(ptr); + free(ptr); + } } /* strangely similar to the dir list's code :) */ static void dirname_entered(void) { - if (!change_dir(dirname_entry)) { - /* FIXME: need to give some kind of feedback here */ - return; - } - - *selected_widget = (flist.num_files > 0) ? 0 : 1; - status.flags |= NEED_UPDATE; - /* reset */ - top_file = current_file = 0; + if (!change_dir(dirname_entry)) { + /* FIXME: need to give some kind of feedback here */ + return; + } + + *selected_widget = (flist.num_files > 0) ? 0 : 1; + status.flags |= NEED_UPDATE; + /* reset */ + top_file = current_file = 0; } /* --------------------------------------------------------------------- */ @@ -915,21 +945,21 @@ /* used by {load,save}_module_set_page. return 1 => contents changed */ static int update_directory(void) { - struct stat st; + struct stat st; - /* if we have a list, the directory didn't change, and the mtime is the same, we're set. */ - if ((status.flags & DIR_MODULES_CHANGED) == 0 - && stat(cfg_dir_modules, &st) == 0 - && st.st_mtime == directory_mtime) { - return 0; - } + /* if we have a list, the directory didn't change, and the mtime is the same, we're set. */ + if ((status.flags & DIR_MODULES_CHANGED) == 0 + && stat(cfg_dir_modules, &st) == 0 + && st.st_mtime == directory_mtime) { + return 0; + } - change_dir(cfg_dir_modules); - /* TODO: what if it failed? */ + change_dir(cfg_dir_modules); + /* TODO: what if it failed? */ - status.flags &= ~DIR_MODULES_CHANGED; + status.flags &= ~DIR_MODULES_CHANGED; - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -939,154 +969,157 @@ #if CACHEFREE static int _save_cachefree_hack(struct key_event *k) { - if ((k->sym == SDLK_F10 && NO_MODIFIER(k->mod)) - || (k->sym == SDLK_w && (k->mod & KMOD_CTRL)) - || (k->sym == SDLK_s && (k->mod & KMOD_CTRL))) { - status.flags |= DIR_MODULES_CHANGED; - } - return 0; + if ((k->sym == SDLK_F10 && NO_MODIFIER(k->mod)) + || (k->sym == SDLK_w && (k->mod & KMOD_CTRL)) + || (k->sym == SDLK_s && (k->mod & KMOD_CTRL))) { + status.flags |= DIR_MODULES_CHANGED; + } + return 0; } static int _load_cachefree_hack(struct key_event *k) { - if ((k->sym == SDLK_F9 && NO_MODIFIER(k->mod)) - || (k->sym == SDLK_l && (k->mod & KMOD_CTRL)) - || (k->sym == SDLK_r && (k->mod & KMOD_CTRL))) { - status.flags |= DIR_MODULES_CHANGED; - } - return 0; + if ((k->sym == SDLK_F9 && NO_MODIFIER(k->mod)) + || (k->sym == SDLK_l && (k->mod & KMOD_CTRL)) + || (k->sym == SDLK_r && (k->mod & KMOD_CTRL))) { + status.flags |= DIR_MODULES_CHANGED; + } + return 0; } #endif static void load_module_set_page(void) { - handle_file_entered = handle_file_entered_L; - if (update_directory()) - pages[PAGE_LOAD_MODULE].selected_widget = (flist.num_files > 0) ? 0 : 1; - - // Don't reparse the glob if it hasn't changed; that will mess with the cursor position - if (strcasecmp(glob_list_src, cfg_module_pattern) == 0) - strcpy(filename_entry, glob_list_src); - else - set_default_glob(1); + handle_file_entered = handle_file_entered_L; + if (update_directory()) + pages[PAGE_LOAD_MODULE].selected_widget = (flist.num_files > 0) ? 0 : 1; + + // Don't reparse the glob if it hasn't changed; that will mess with the cursor position + if (strcasecmp(glob_list_src, cfg_module_pattern) == 0) + strcpy(filename_entry, glob_list_src); + else + set_default_glob(1); } void load_module_load_page(struct page *page) { - clear_directory(); - top_file = top_dir = 0; - current_file = current_dir = 0; - dir_list_reposition(); - file_list_reposition(); - - page->title = "Load Module (F9)"; - page->draw_const = load_module_draw_const; - page->set_page = load_module_set_page; - page->total_widgets = 4; - page->widgets = widgets_loadmodule; - page->help_index = HELP_GLOBAL; + clear_directory(); + top_file = top_dir = 0; + current_file = current_dir = 0; + dir_list_reposition(); + file_list_reposition(); + + page->title = "Load Module (F9)"; + page->draw_const = load_module_draw_const; + page->set_page = load_module_set_page; + page->total_widgets = 4; + page->widgets = widgets_loadmodule; + page->help_index = HELP_GLOBAL; #if CACHEFREE - page->pre_handle_key = _load_cachefree_hack; + page->pre_handle_key = _load_cachefree_hack; #endif - create_other(widgets_loadmodule + 0, 1, file_list_handle_key, file_list_draw); - widgets_loadmodule[0].accept_text = 1; - widgets_loadmodule[0].x = 3; - widgets_loadmodule[0].y = 13; - widgets_loadmodule[0].width = 43; - widgets_loadmodule[0].height = 30; - widgets_loadmodule[0].next.left = widgets_loadmodule[0].next.right = 1; - - create_other(widgets_loadmodule + 1, 2, dir_list_handle_key, dir_list_draw); - widgets_loadmodule[1].accept_text = 1; - widgets_loadmodule[1].x = 50; - widgets_loadmodule[1].y = 13; - widgets_loadmodule[1].width = 17; - widgets_loadmodule[1].height = 20; - - create_textentry(widgets_loadmodule + 2, 13, 46, 64, 0, 3, 3, NULL, filename_entry, PATH_MAX); - widgets_loadmodule[2].activate = filename_entered; - create_textentry(widgets_loadmodule + 3, 13, 47, 64, 2, 3, 0, NULL, dirname_entry, PATH_MAX); - widgets_loadmodule[3].activate = dirname_entered; + create_other(widgets_loadmodule + 0, 1, file_list_handle_key, file_list_draw); + widgets_loadmodule[0].accept_text = 1; + widgets_loadmodule[0].x = 3; + widgets_loadmodule[0].y = 13; + widgets_loadmodule[0].width = 43; + widgets_loadmodule[0].height = 30; + widgets_loadmodule[0].next.left = widgets_loadmodule[0].next.right = 1; + + create_other(widgets_loadmodule + 1, 2, dir_list_handle_key, dir_list_draw); + widgets_loadmodule[1].accept_text = 1; + widgets_loadmodule[1].x = 50; + widgets_loadmodule[1].y = 13; + widgets_loadmodule[1].width = 17; + widgets_loadmodule[1].height = 20; + + create_textentry(widgets_loadmodule + 2, 13, 46, 64, 0, 3, 3, NULL, filename_entry, PATH_MAX); + widgets_loadmodule[2].activate = filename_entered; + create_textentry(widgets_loadmodule + 3, 13, 47, 64, 2, 3, 0, NULL, dirname_entry, PATH_MAX); + widgets_loadmodule[3].activate = dirname_entered; } /* --------------------------------------------------------------------- */ static void save_module_set_page(void) { - handle_file_entered = handle_file_entered_S; + handle_file_entered = handle_file_entered_S; + + update_directory(); + /* impulse tracker always resets these; so will i */ + set_default_glob(0); + filename_entry[0] = 0; + pages[PAGE_SAVE_MODULE].selected_widget = 2; + + widgets_exportsave = (status.current_page == PAGE_EXPORT_MODULE) + ? widgets_exportmodule + : widgets_savemodule; - update_directory(); - /* impulse tracker always resets these; so will i */ - set_default_glob(0); - filename_entry[0] = 0; - pages[PAGE_SAVE_MODULE].selected_widget = 2; - - widgets_exportsave = (status.current_page == PAGE_EXPORT_MODULE) - ? widgets_exportmodule - : widgets_savemodule; + if (status.current_page == PAGE_EXPORT_MODULE && current_song->orderlist[0] == ORDER_LAST) + dialog_create(DIALOG_OK, "You're about to export a blank file...", NULL, NULL, 0, NULL); } void save_module_load_page(struct page *page, int do_export) { - int n; + int n; - if (do_export) { - page->title = "Export Module (Shift-F10)"; - page->widgets = widgets_exportmodule; - } else { - page->title = "Save Module (F10)"; - page->widgets = widgets_savemodule; - } - widgets_exportsave = page->widgets; - - /* preload */ - clear_directory(); - top_file = top_dir = 0; - current_file = current_dir = 0; - dir_list_reposition(); - file_list_reposition(); - read_directory(); - - page->draw_const = save_module_draw_const; - page->set_page = save_module_set_page; - page->total_widgets = 4; - page->help_index = HELP_GLOBAL; - page->selected_widget = 2; + if (do_export) { + page->title = "Export Module (Shift-F10)"; + page->widgets = widgets_exportmodule; + } else { + page->title = "Save Module (F10)"; + page->widgets = widgets_savemodule; + } + widgets_exportsave = page->widgets; + + /* preload */ + clear_directory(); + top_file = top_dir = 0; + current_file = current_dir = 0; + dir_list_reposition(); + file_list_reposition(); + read_directory(); + + page->draw_const = save_module_draw_const; + page->set_page = save_module_set_page; + page->total_widgets = 4; + page->help_index = HELP_GLOBAL; + page->selected_widget = 2; #if CACHEFREE - page->pre_handle_key = _save_cachefree_hack; + page->pre_handle_key = _save_cachefree_hack; #endif - page->song_changed_cb = loadsave_song_changed; + page->song_changed_cb = loadsave_song_changed; - create_other(widgets_exportsave + 0, 1, file_list_handle_key, file_list_draw); - widgets_exportsave[0].accept_text = 1; - widgets_exportsave[0].next.left = 4; - widgets_exportsave[0].next.right = widgets_exportsave[0].next.tab = 1; - create_other(widgets_exportsave + 1, 2, dir_list_handle_key, dir_list_draw); - widgets_exportsave[1].accept_text = 1; - widgets_exportsave[1].next.right = widgets_exportsave[1].next.tab = 5; - widgets_exportsave[1].next.left = 0; - - create_textentry(widgets_exportsave + 2, 13, 46, 64, 0, 3, 3, NULL, filename_entry, PATH_MAX); - widgets_exportsave[2].activate = filename_entered; - create_textentry(widgets_exportsave + 3, 13, 47, 64, 2, 0, 0, NULL, dirname_entry, PATH_MAX); - widgets_exportsave[3].activate = dirname_entered; - - widgets_exportsave[4].d.togglebutton.state = 1; - - - struct save_format *formats = (do_export ? song_export_formats : song_save_formats); - for (n = 0; formats[n].label; n++) { - create_togglebutton(widgets_exportsave + 4 + n, - 70, 13 + (3 * n), 5, - 4 + (n == 0 ? 0 : (n - 1)), - 4 + (n + 1), - 1, 2, 2, - NULL, - formats[n].label, - (5 - strlen(formats[n].label)) / 2 + 1, - filetype_saves); - } - widgets_exportsave[4 + n - 1].next.down = 2; - page->total_widgets += n; + create_other(widgets_exportsave + 0, 1, file_list_handle_key, file_list_draw); + widgets_exportsave[0].accept_text = 1; + widgets_exportsave[0].next.left = 4; + widgets_exportsave[0].next.right = widgets_exportsave[0].next.tab = 1; + create_other(widgets_exportsave + 1, 2, dir_list_handle_key, dir_list_draw); + widgets_exportsave[1].accept_text = 1; + widgets_exportsave[1].next.right = widgets_exportsave[1].next.tab = 5; + widgets_exportsave[1].next.left = 0; + + create_textentry(widgets_exportsave + 2, 13, 46, 64, 0, 3, 3, NULL, filename_entry, PATH_MAX); + widgets_exportsave[2].activate = filename_entered; + create_textentry(widgets_exportsave + 3, 13, 47, 64, 2, 0, 0, NULL, dirname_entry, PATH_MAX); + widgets_exportsave[3].activate = dirname_entered; + + widgets_exportsave[4].d.togglebutton.state = 1; + + + const struct save_format *formats = (do_export ? song_export_formats : song_save_formats); + for (n = 0; formats[n].label; n++) { + create_togglebutton(widgets_exportsave + 4 + n, + 70, 13 + (3 * n), 5, + 4 + (n == 0 ? 0 : (n - 1)), + 4 + (n + 1), + 1, 2, 2, + NULL, + formats[n].label, + (5 - strlen(formats[n].label)) / 2 + 1, + filetype_saves); + } + widgets_exportsave[4 + n - 1].next.down = 2; + page->total_widgets += n; } diff -Nru schism-0+20110101/schism/page_loadsample.c schism-20160521/schism/page_loadsample.c --- schism-0+20110101/schism/page_loadsample.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_loadsample.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -44,8 +44,8 @@ /* --------------------------------------------------------------------------------------------------------- */ /* the locals */ static struct vgamem_overlay sample_image = { - 52,25,76,28, - NULL, 0, 0, 0, + 52,25,76,28, + NULL, 0, 0, 0, }; static char current_filename[PATH_MAX]; @@ -62,20 +62,20 @@ static int will_move_to = -1; static int fake_slot = KEYJAZZ_NOINST; static const char *const loop_states[] = { - "Off", "On Forwards", "On Ping Pong", NULL }; + "Off", "On Forwards", "On Ping Pong", NULL }; static void handle_preload(void); /* --------------------------------------------------------------------------------------------------------- */ /* files: - file type color displayed title notes - --------- ----- --------------- ----- - unchecked 4 IT uses color 6 for these - directory 5 "........Directory........" dots are char 154 (same for libraries) - sample 3 - libraries 6 ".........Library........." IT uses color 3. maybe use module name here? - unknown 2 any regular file that's not recognized + file type color displayed title notes + --------- ----- --------------- ----- + unchecked 4 IT uses color 6 for these + directory 5 "........Directory........" dots are char 154 (same for libraries) + sample 3 + libraries 6 ".........Library........." IT uses color 3. maybe use module name here? + unknown 2 any regular file that's not recognized */ static int top_file = 0; @@ -89,310 +89,308 @@ /* get a color index from a dmoz_file_t 'type' field */ static inline int get_type_color(int type) { - if (type == TYPE_DIRECTORY) - return 5; - if (!(type & TYPE_EXT_DATA_MASK)) - return 4; /* unchecked */ - if (type & TYPE_BROWSABLE_MASK) - return 6; /* library */ - if (type == TYPE_UNKNOWN) - return 2; - return 3; /* sample */ + if (type == TYPE_DIRECTORY) + return 5; + if (!(type & TYPE_EXT_DATA_MASK)) + return 4; /* unchecked */ + if (type & TYPE_BROWSABLE_MASK) + return 6; /* library */ + if (type == TYPE_UNKNOWN) + return 2; + return 3; /* sample */ } static void clear_directory(void) { - dmoz_free(&flist, NULL); - fake_slot = KEYJAZZ_NOINST; - fake_slot_changed = 0; + dmoz_free(&flist, NULL); + fake_slot = KEYJAZZ_NOINST; + fake_slot_changed = 0; } static void file_list_reposition(void) { - dmoz_file_t *f; + dmoz_file_t *f; - current_file = CLAMP(current_file, 0, flist.num_files - 1); - // XXX use CLAMP() here too, I can't brain - if (current_file < top_file) - top_file = current_file; - else if (current_file > top_file + 34) - top_file = current_file - 34; - if (current_file >= 0 && current_file < flist.num_files) { - f = flist.files[current_file]; - - if (f && f->smp_filename) { - strncpy(current_filename, f->smp_filename, - PATH_MAX-1); - } else if (f && f->base) { - strncpy(current_filename, f->base, - PATH_MAX-1); - } else { - current_filename[0] = '\0'; - } - widgets_loadsample[1].d.textentry.firstchar = 0; - widgets_loadsample[1].d.textentry.cursor_pos = - strlen(current_filename); - - widgets_loadsample[2].d.numentry.value = f ? f->smp_speed : 0; - - if (f && f->smp_flags & CHN_PINGPONGLOOP) { - widgets_loadsample[3].d.menutoggle.state = 2; - } else if (f && f->smp_flags & CHN_LOOP) { - widgets_loadsample[3].d.menutoggle.state = 1; - } else { - widgets_loadsample[3].d.menutoggle.state = 0; - } - - widgets_loadsample[4].d.numentry.value = f ? f->smp_loop_start : 0; - widgets_loadsample[5].d.numentry.value = f ? f->smp_loop_end : 0; - - if (f && f->smp_flags & CHN_PINGPONGSUSTAIN) { - widgets_loadsample[6].d.menutoggle.state = 2; - } else if (f && f->smp_flags & CHN_SUSTAINLOOP) { - widgets_loadsample[6].d.menutoggle.state = 1; - } else { - widgets_loadsample[6].d.menutoggle.state = 0; - } - - widgets_loadsample[7].d.numentry.value = f ? f->smp_sustain_start : 0; - widgets_loadsample[8].d.numentry.value = f ? f->smp_sustain_end : 0; - widgets_loadsample[9].d.thumbbar.value = f ? f->smp_defvol : 64; - widgets_loadsample[10].d.thumbbar.value = f ? f->smp_gblvol : 64; - widgets_loadsample[11].d.thumbbar.value = f ? f->smp_vibrato_speed : 0; - widgets_loadsample[12].d.thumbbar.value = f ? f->smp_vibrato_depth : 0; - widgets_loadsample[13].d.thumbbar.value = f ? f->smp_vibrato_rate : 0; - if (f) { - /* autoload some files */ - if (TYPE_SAMPLE_EXTD == (f->type & TYPE_SAMPLE_EXTD) - && f->filesize < 0x4000000 && f->smp_length < 0x1000000) - handle_preload(); - } - } + current_file = CLAMP(current_file, 0, flist.num_files - 1); + // XXX use CLAMP() here too, I can't brain + if (current_file < top_file) + top_file = current_file; + else if (current_file > top_file + 34) + top_file = current_file - 34; + if (current_file >= 0 && current_file < flist.num_files) { + f = flist.files[current_file]; + + if (f && f->smp_filename) { + strncpy(current_filename, f->smp_filename, + PATH_MAX-1); + } else if (f && f->base) { + strncpy(current_filename, f->base, + PATH_MAX-1); + } else { + current_filename[0] = '\0'; + } + widgets_loadsample[1].d.textentry.firstchar = 0; + widgets_loadsample[1].d.textentry.cursor_pos = + strlen(current_filename); + + widgets_loadsample[2].d.numentry.value = f ? f->smp_speed : 0; + + if (f && f->smp_flags & CHN_PINGPONGLOOP) { + widgets_loadsample[3].d.menutoggle.state = 2; + } else if (f && f->smp_flags & CHN_LOOP) { + widgets_loadsample[3].d.menutoggle.state = 1; + } else { + widgets_loadsample[3].d.menutoggle.state = 0; + } + + widgets_loadsample[4].d.numentry.value = f ? f->smp_loop_start : 0; + widgets_loadsample[5].d.numentry.value = f ? f->smp_loop_end : 0; + + if (f && f->smp_flags & CHN_PINGPONGSUSTAIN) { + widgets_loadsample[6].d.menutoggle.state = 2; + } else if (f && f->smp_flags & CHN_SUSTAINLOOP) { + widgets_loadsample[6].d.menutoggle.state = 1; + } else { + widgets_loadsample[6].d.menutoggle.state = 0; + } + + widgets_loadsample[7].d.numentry.value = f ? f->smp_sustain_start : 0; + widgets_loadsample[8].d.numentry.value = f ? f->smp_sustain_end : 0; + widgets_loadsample[9].d.thumbbar.value = f ? f->smp_defvol : 64; + widgets_loadsample[10].d.thumbbar.value = f ? f->smp_gblvol : 64; + widgets_loadsample[11].d.thumbbar.value = f ? f->smp_vibrato_speed : 0; + widgets_loadsample[12].d.thumbbar.value = f ? f->smp_vibrato_depth : 0; + widgets_loadsample[13].d.thumbbar.value = f ? f->smp_vibrato_rate : 0; + if (f) { + /* autoload some files */ + if (TYPE_SAMPLE_EXTD == (f->type & TYPE_SAMPLE_EXTD) + && f->filesize < 0x4000000 && f->smp_length < 0x1000000) + handle_preload(); + } + } } static void read_directory(void) { - struct stat st; + struct stat st; - clear_directory(); - if (stat(cfg_dir_samples, &st) < 0) - directory_mtime = 0; - else - directory_mtime = st.st_mtime; - /* if the stat call failed, this will probably break as well, but - at the very least, it'll add an entry for the root directory. */ - if (dmoz_read(cfg_dir_samples, &flist, NULL, dmoz_read_sample_library) < 0) - log_perror(cfg_dir_samples); - - dmoz_filter_filelist(&flist, dmoz_fill_ext_data, ¤t_file, file_list_reposition); - dmoz_cache_lookup(cfg_dir_samples, &flist, NULL); - file_list_reposition(); + clear_directory(); + if (stat(cfg_dir_samples, &st) < 0) + directory_mtime = 0; + else + directory_mtime = st.st_mtime; + /* if the stat call failed, this will probably break as well, but + at the very least, it'll add an entry for the root directory. */ + if (dmoz_read(cfg_dir_samples, &flist, NULL, dmoz_read_sample_library) < 0) + log_perror(cfg_dir_samples); + + dmoz_filter_filelist(&flist, dmoz_fill_ext_data, ¤t_file, file_list_reposition); + dmoz_cache_lookup(cfg_dir_samples, &flist, NULL); + file_list_reposition(); } /* return: 1 = success, 0 = failure TODO: provide some sort of feedback if something went wrong. */ static int change_dir(const char *dir) { - char *ptr = dmoz_path_normal(dir); + char *ptr = dmoz_path_normal(dir); - if (!ptr) - return 0; + if (!ptr) + return 0; - dmoz_cache_update(cfg_dir_samples, &flist, NULL); + dmoz_cache_update(cfg_dir_samples, &flist, NULL); - /* FIXME: need to make sure it exists, and that it's a directory */ - strncpy(cfg_dir_samples, ptr, PATH_MAX); - cfg_dir_samples[PATH_MAX] = 0; - free(ptr); + /* FIXME: need to make sure it exists, and that it's a directory */ + strncpy(cfg_dir_samples, ptr, PATH_MAX); + cfg_dir_samples[PATH_MAX] = 0; + free(ptr); - read_directory(); - return 1; + read_directory(); + return 1; } /* --------------------------------------------------------------------------------------------------------- */ static void load_sample_draw_const(void) { - dmoz_file_t *f; - song_sample_t *s; - char sbuf[64]; - int filled; - - draw_box(5, 12, 50, 48, BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(6, 13, 49, 47, 0); - - draw_fill_chars(64, 13, 77, 22, 0); - draw_box(62, 32, 72, 35, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(62, 36, 72, 40, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_box(63, 12, 77, 23, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_box(51, 24, 77, 29, BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(52, 25, 76, 28, 0); - - draw_box(51, 30, 77, 42, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_fill_chars(59, 44, 76, 47, 0); - draw_box(58, 43, 77, 48, BOX_THICK | BOX_INNER | BOX_INSET); - - filled = 0; - f = NULL; - if (current_file >= 0 && current_file < flist.num_files && flist.files[current_file]) { - f = flist.files[current_file]; - - sprintf(sbuf, "%07d", f->smp_length); - draw_text_len(sbuf, 13, 64, 22, 2, 0); - - if (!f->smp_length && !f->smp_filename && !f->smp_flags) { - draw_text_len("No sample",13, 64, 21, 2, 0); - } else if (f->smp_flags & CHN_STEREO) { - draw_text_len( - (f->smp_flags & CHN_16BIT - ? "16 bit Stereo" : "8 bit Stereo"), - 13, 64, 21, 2, 0); - } else { - draw_text_len( - (f->smp_flags & CHN_16BIT - ? "16 bit" : "8 bit"), - 13, 64, 21, 2, 0); - } - if (f->description) { - draw_text_len(f->description, - 18, - 59, 44, 5, 0); - } else { - switch (f->type) { - case TYPE_DIRECTORY: - draw_text("Directory", - 59, 44, 5, 0); - break; - default: - draw_text("Unknown format", - 59, 44, 5, 0); - break; - }; - } - sprintf(sbuf, "%07ld", (long)f->filesize); - draw_text(sbuf, 59, 45, 5,0); - get_date_string(f->timestamp, sbuf); - draw_text(sbuf, 59, 46, 5,0); - get_time_string(f->timestamp, sbuf); - draw_text(sbuf, 59, 47, 5,0); - } - - /* these are exactly the same as in page_samples.c, apart from - * 'quality' and 'length' being one line higher */ - draw_text("Filename", 55, 13, 0, 2); - draw_text("Speed", 58, 14, 0, 2); - draw_text("Loop", 59, 15, 0, 2); - draw_text("LoopBeg", 56, 16, 0, 2); - draw_text("LoopEnd", 56, 17, 0, 2); - draw_text("SusLoop", 56, 18, 0, 2); - draw_text("SusLBeg", 56, 19, 0, 2); - draw_text("SusLEnd", 56, 20, 0, 2); - draw_text("Quality", 56, 21, 0, 2); - draw_text("Length", 57, 22, 0, 2); - - /* these abbreviations are sucky and lame. any suggestions? */ - draw_text("Def. Vol.", 53, 33, 0, 2); - draw_text("Glb. Vol.", 53, 34, 0, 2); - draw_text("Vib.Speed", 53, 37, 0, 2); - draw_text("Vib.Depth", 53, 38, 0, 2); - draw_text("Vib. Rate", 53, 39, 0, 2); - - draw_text("Format", 52, 44, 0, 2); - draw_text("Size", 54, 45, 0, 2); - draw_text("Date", 54, 46, 0, 2); - draw_text("Time", 54, 47, 0, 2); - - if (fake_slot != KEYJAZZ_NOINST) { - s = song_get_sample(fake_slot); - vgamem_ovl_clear(&sample_image, 0); - if (s) - draw_sample_data(&sample_image, s, fake_slot); - else - vgamem_ovl_apply(&sample_image); - } + dmoz_file_t *f; + song_sample_t *s; + char sbuf[64]; + + draw_box(5, 12, 50, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(6, 13, 49, 47, 0); + + draw_fill_chars(64, 13, 77, 22, 0); + draw_box(62, 32, 72, 35, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(62, 36, 72, 40, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_box(63, 12, 77, 23, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_box(51, 24, 77, 29, BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(52, 25, 76, 28, 0); + + draw_box(51, 30, 77, 42, BOX_THIN | BOX_INNER | BOX_INSET); + + draw_fill_chars(59, 44, 76, 47, 0); + draw_box(58, 43, 77, 48, BOX_THICK | BOX_INNER | BOX_INSET); + + f = NULL; + if (current_file >= 0 && current_file < flist.num_files && flist.files[current_file]) { + f = flist.files[current_file]; + + sprintf(sbuf, "%07d", f->smp_length); + draw_text_len(sbuf, 13, 64, 22, 2, 0); + + if (!f->smp_length && !f->smp_filename && !f->smp_flags) { + draw_text_len("No sample",13, 64, 21, 2, 0); + } else if (f->smp_flags & CHN_STEREO) { + draw_text_len( + (f->smp_flags & CHN_16BIT + ? "16 bit Stereo" : "8 bit Stereo"), + 13, 64, 21, 2, 0); + } else { + draw_text_len( + (f->smp_flags & CHN_16BIT + ? "16 bit" : "8 bit"), + 13, 64, 21, 2, 0); + } + if (f->description) { + draw_text_len(f->description, + 18, + 59, 44, 5, 0); + } else { + switch (f->type) { + case TYPE_DIRECTORY: + draw_text("Directory", + 59, 44, 5, 0); + break; + default: + draw_text("Unknown format", + 59, 44, 5, 0); + break; + }; + } + sprintf(sbuf, "%07ld", (long)f->filesize); + draw_text(sbuf, 59, 45, 5,0); + get_date_string(f->timestamp, sbuf); + draw_text(sbuf, 59, 46, 5,0); + get_time_string(f->timestamp, sbuf); + draw_text(sbuf, 59, 47, 5,0); + } + + /* these are exactly the same as in page_samples.c, apart from + * 'quality' and 'length' being one line higher */ + draw_text("Filename", 55, 13, 0, 2); + draw_text("Speed", 58, 14, 0, 2); + draw_text("Loop", 59, 15, 0, 2); + draw_text("LoopBeg", 56, 16, 0, 2); + draw_text("LoopEnd", 56, 17, 0, 2); + draw_text("SusLoop", 56, 18, 0, 2); + draw_text("SusLBeg", 56, 19, 0, 2); + draw_text("SusLEnd", 56, 20, 0, 2); + draw_text("Quality", 56, 21, 0, 2); + draw_text("Length", 57, 22, 0, 2); + + /* these abbreviations are sucky and lame. any suggestions? */ + draw_text("Def. Vol.", 53, 33, 0, 2); + draw_text("Glb. Vol.", 53, 34, 0, 2); + draw_text("Vib.Speed", 53, 37, 0, 2); + draw_text("Vib.Depth", 53, 38, 0, 2); + draw_text("Vib. Rate", 53, 39, 0, 2); + + draw_text("Format", 52, 44, 0, 2); + draw_text("Size", 54, 45, 0, 2); + draw_text("Date", 54, 46, 0, 2); + draw_text("Time", 54, 47, 0, 2); + + if (fake_slot != KEYJAZZ_NOINST) { + s = song_get_sample(fake_slot); + vgamem_ovl_clear(&sample_image, 0); + if (s) + draw_sample_data(&sample_image, s); + else + vgamem_ovl_apply(&sample_image); + } } /* --------------------------------------------------------------------------------------------------------- */ static void _common_set_page(void) { - struct stat st; + struct stat st; - /* if we have a list, the directory didn't change, and the mtime is the same, we're set */ - if (flist.num_files > 0 - && (status.flags & DIR_SAMPLES_CHANGED) == 0 - && stat(cfg_dir_samples, &st) == 0 - && st.st_mtime == directory_mtime) { - return; - } - - change_dir(cfg_dir_samples); - - status.flags &= ~DIR_SAMPLES_CHANGED; - fake_slot = KEYJAZZ_NOINST; - fake_slot_changed = 0; + /* if we have a list, the directory didn't change, and the mtime is the same, we're set */ + if (flist.num_files > 0 + && (status.flags & DIR_SAMPLES_CHANGED) == 0 + && stat(cfg_dir_samples, &st) == 0 + && st.st_mtime == directory_mtime) { + return; + } + + change_dir(cfg_dir_samples); + + status.flags &= ~DIR_SAMPLES_CHANGED; + fake_slot = KEYJAZZ_NOINST; + fake_slot_changed = 0; - *selected_widget = 0; - search_pos = -1; + *selected_widget = 0; + search_pos = -1; } static void load_sample_set_page(void) { - _library_mode = 0; - _common_set_page(); + _library_mode = 0; + _common_set_page(); } static void library_sample_set_page(void) { - _library_mode = 1; - _common_set_page(); + _library_mode = 1; + _common_set_page(); } /* --------------------------------------------------------------------------------------------------------- */ static void file_list_draw(void) { - int n, i, pos, fg, bg; - char buf[8]; - dmoz_file_t *file; - - /* there's no need to have if (files) { ... } like in the load-module page, - because there will always be at least "/" in the list */ - if (top_file < 0) top_file = 0; - if (current_file < 0) current_file = 0; - for (n = top_file, pos = 13; n < flist.num_files && pos < 48; n++, pos++) { - file = flist.files[n]; - - if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { - fg = 0; - bg = 3; - } else { - fg = get_type_color(file->type); - bg = 0; - } - draw_text(numtostr(3, n+1, buf), 2, pos, 0, 2); - draw_text_len(file->title ?: "", 25, 6, pos, fg, bg); - draw_char(168, 31, pos, 2, bg); - draw_text_len(file->base ?: "", 18, 32, pos, fg, bg); - if (file->base && search_pos > -1) { - if (strncasecmp(file->base,search_str,search_pos) == 0) { - for (i = 0 ; i < search_pos; i++) { - if (tolower(file->base[i]) != tolower(search_str[i])) - break; - draw_char(file->base[i], 32+i, pos, 3,1); - } - } - } - } + int n, i, pos, fg, bg; + char buf[8]; + dmoz_file_t *file; + + /* there's no need to have if (files) { ... } like in the load-module page, + because there will always be at least "/" in the list */ + if (top_file < 0) top_file = 0; + if (current_file < 0) current_file = 0; + for (n = top_file, pos = 13; n < flist.num_files && pos < 48; n++, pos++) { + file = flist.files[n]; + + if (n == current_file && ACTIVE_PAGE.selected_widget == 0) { + fg = 0; + bg = 3; + } else { + fg = get_type_color(file->type); + bg = 0; + } + draw_text(numtostr(3, n+1, buf), 2, pos, 0, 2); + draw_text_len(file->title ?: "", 25, 6, pos, fg, bg); + draw_char(168, 31, pos, 2, bg); + draw_text_len(file->base ?: "", 18, 32, pos, fg, bg); + if (file->base && search_pos > -1) { + if (strncasecmp(file->base,search_str,search_pos) == 0) { + for (i = 0 ; i < search_pos; i++) { + if (tolower(file->base[i]) != tolower(search_str[i])) + break; + draw_char(file->base[i], 32+i, pos, 3,1); + } + } + } + } - /* draw the info for the current file (or directory...) */ + /* draw the info for the current file (or directory...) */ - while (pos < 48) - draw_char(168, 31, pos++, 2, 0); + while (pos < 48) + draw_char(168, 31, pos++, 2, 0); } /* --------------------------------------------------------------------------------------------------------- */ @@ -402,606 +400,615 @@ static void _create_host_ok(void *vpage) { - intptr_t page = (intptr_t) vpage; - song_create_host_instrument(sample_get_current()); - if (page >= 0) - set_page(page); + intptr_t page = (intptr_t) vpage; + song_create_host_instrument(sample_get_current()); + if (page >= 0) + set_page(page); } static void _create_host_cancel(void *vpage) { - intptr_t page = (intptr_t) vpage; - if (page >= 0) - set_page(page); + intptr_t page = (intptr_t) vpage; + if (page >= 0) + set_page(page); } int sample_host_dialog(int newpage) { - /* Actually IT defaults to No when the sample slot already had a sample in it, rather than checking if - it was assigned to an instrument. Maybe this is better, though? - (Not to mention, passing around the extra state that'd be required to do it that way would be kind of - messy...) - - also the double pointer cast sucks. - - also also, IT says Ok/No here instead of Yes/No... but do I care? */ - - if (song_is_instrument_mode()) { - int used = sample_is_used_by_instrument(sample_get_current()); - dialog_create(DIALOG_YES_NO, "Create host instrument?", - _create_host_ok, _create_host_cancel, used ? 1 : 0, (void *) (intptr_t) newpage); - return 1; - } - if (newpage >= 0) - set_page(newpage); - return 0; + /* Actually IT defaults to No when the sample slot already had a sample in it, rather than checking if + it was assigned to an instrument. Maybe this is better, though? + (Not to mention, passing around the extra state that'd be required to do it that way would be kind of + messy...) + + also the double pointer cast sucks. + + also also, IT says Ok/No here instead of Yes/No... but do I care? */ + + if (song_is_instrument_mode()) { + int used = sample_is_used_by_instrument(sample_get_current()); + dialog_create(DIALOG_YES_NO, "Create host instrument?", + _create_host_ok, _create_host_cancel, used ? 1 : 0, (void *) (intptr_t) newpage); + return 1; + } + if (newpage >= 0) + set_page(newpage); + return 0; } static void finish_load(int cur); static void stereo_cvt_complete_left(void) { - int cur = sample_get_current(); - song_sample_t *smp; - smp = song_get_sample(cur); - sample_mono_left(smp); - dialog_destroy(); - finish_load(cur); + int cur = sample_get_current(); + song_sample_t *smp; + smp = song_get_sample(cur); + sample_mono_left(smp); + dialog_destroy(); + finish_load(cur); } static void stereo_cvt_complete_right(void) { - int cur = sample_get_current(); - song_sample_t *smp; - smp = song_get_sample(cur); - sample_mono_right(smp); - dialog_destroy(); - finish_load(cur); + int cur = sample_get_current(); + song_sample_t *smp; + smp = song_get_sample(cur); + sample_mono_right(smp); + dialog_destroy(); + finish_load(cur); } static void stereo_cvt_complete_both(void) { - memused_songchanged(); - dialog_destroy(); - sample_host_dialog(PAGE_SAMPLE_LIST); + memused_songchanged(); + dialog_destroy(); + sample_host_dialog(PAGE_SAMPLE_LIST); } static void stereo_cvt_dialog(void) { - draw_text("Loading Stereo Sample", 30, 27, 0, 2); + draw_text("Loading Stereo Sample", 30, 27, 0, 2); } static int stereo_cvt_hk(struct key_event *k) { - if (!NO_MODIFIER(k->mod)) - return 0; + if (!NO_MODIFIER(k->mod)) + return 0; - /* trap the default dialog keys - we don't want to escape this dialog without running something */ - switch (k->sym) { - case SDLK_RETURN: - printf("why am I here\n"); - case SDLK_ESCAPE: case SDLK_o: case SDLK_c: - return 1; - case SDLK_l: - if (k->state) - stereo_cvt_complete_left(); - return 1; - case SDLK_r: - if (k->state) - stereo_cvt_complete_right(); - return 1; - case SDLK_s: - case SDLK_b: - if (k->state) - stereo_cvt_complete_both(); - return 1; - default: - return 0; - } + /* trap the default dialog keys - we don't want to escape this dialog without running something */ + switch (k->sym) { + case SDLK_RETURN: + printf("why am I here\n"); + case SDLK_ESCAPE: case SDLK_o: case SDLK_c: + return 1; + case SDLK_l: + if (k->state == KEY_RELEASE) + stereo_cvt_complete_left(); + return 1; + case SDLK_r: + if (k->state == KEY_RELEASE) + stereo_cvt_complete_right(); + return 1; + case SDLK_s: + case SDLK_b: + if (k->state == KEY_RELEASE) + stereo_cvt_complete_both(); + return 1; + default: + return 0; + } } static void finish_load(int cur) { - song_sample_t *smp; + song_sample_t *smp; - memused_songchanged(); - smp = song_get_sample(cur); - if (smp->flags & CHN_STEREO) { - struct dialog *dd; - create_button(stereo_cvt_widgets+0, 27, 30, 6, - 0, 0, 2, 1, 1, - stereo_cvt_complete_left, "Left", 2); - - create_button(stereo_cvt_widgets+1, 37, 30, 6, - 1, 1, 0, 2, 2, - stereo_cvt_complete_both, "Both", 2); - - create_button(stereo_cvt_widgets+2, 47, 30, 6, - 2, 2, 1, 0, 0, - stereo_cvt_complete_right, "Right", 1); - - dd = dialog_create_custom(24, 25, 33, 8, - stereo_cvt_widgets, 3, - 1, - stereo_cvt_dialog, NULL); - dd->handle_key = stereo_cvt_hk; - return; - } - sample_host_dialog(PAGE_SAMPLE_LIST); + status.flags |= SONG_NEEDS_SAVE; + memused_songchanged(); + smp = song_get_sample(cur); + if (smp->flags & CHN_STEREO) { + struct dialog *dd; + create_button(stereo_cvt_widgets+0, 27, 30, 6, + 0, 0, 2, 1, 1, + stereo_cvt_complete_left, "Left", 2); + + create_button(stereo_cvt_widgets+1, 37, 30, 6, + 1, 1, 0, 2, 2, + stereo_cvt_complete_both, "Both", 2); + + create_button(stereo_cvt_widgets+2, 47, 30, 6, + 2, 2, 1, 0, 0, + stereo_cvt_complete_right, "Right", 1); + + dd = dialog_create_custom(24, 25, 33, 8, + stereo_cvt_widgets, 3, + 1, + stereo_cvt_dialog, NULL); + dd->handle_key = stereo_cvt_hk; + return; + } + sample_host_dialog(PAGE_SAMPLE_LIST); } static void reposition_at_slash_search(void) { - dmoz_file_t *f; - int i, j, b, bl; + dmoz_file_t *f; + int i, j, b, bl; - if (search_pos < 0) return; - bl = b = -1; - for (i = 0; i < flist.num_files; i++) { - f = flist.files[i]; - if (!f || !f->base) continue; - for (j = 0; j < search_pos; j++) { - if (tolower(f->base[j]) != tolower(search_str[j])) - break; - } - if (bl < j) { - bl = j; - b = i; - } - } - if (bl > 0) { - current_file = b; - file_list_reposition(); - } + if (search_pos < 0) return; + bl = b = -1; + for (i = 0; i < flist.num_files; i++) { + f = flist.files[i]; + if (!f || !f->base) continue; + for (j = 0; j < search_pos; j++) { + if (tolower(f->base[j]) != tolower(search_str[j])) + break; + } + if (bl < j) { + bl = j; + b = i; + } + } + if (bl > 0) { + current_file = b; + file_list_reposition(); + } } /* on the file list, that is */ static void handle_enter_key(void) { - dmoz_file_t *file; - song_sample_t *smp; - int cur = sample_get_current(); - - if (current_file < 0 || current_file >= flist.num_files) return; - - file = flist.files[current_file]; - dmoz_cache_update(cfg_dir_samples, &flist, NULL); - dmoz_fill_ext_data(file); - - if ((file->type & (TYPE_BROWSABLE_MASK|TYPE_INST_MASK)) - && !(file->type & TYPE_SAMPLE_MASK)) { - change_dir(file->path); - status.flags |= NEED_UPDATE; - } else if (_library_mode) { - return; - } else if (file->sample) { - /* it's already been loaded, so copy it */ - smp = song_get_sample(cur); - song_copy_sample(cur, file->sample); - strncpy(smp->name, file->title, 25); - smp->name[25] = 0; - strncpy(smp->filename, file->base, 12); - smp->filename[12] = 0; - finish_load(cur); - memused_songchanged(); - } else if (file->type & TYPE_SAMPLE_MASK) { - /* load the sample */ - song_load_sample(cur, file->path); - finish_load(cur); - memused_songchanged(); - } + dmoz_file_t *file; + song_sample_t *smp; + int cur = sample_get_current(); + + if (current_file < 0 || current_file >= flist.num_files) return; + + file = flist.files[current_file]; + dmoz_cache_update(cfg_dir_samples, &flist, NULL); + dmoz_fill_ext_data(file); + + if ((file->type & (TYPE_BROWSABLE_MASK|TYPE_INST_MASK)) + && !(file->type & TYPE_SAMPLE_MASK)) { + change_dir(file->path); + status.flags |= NEED_UPDATE; + } else if (_library_mode) { + return; + } else if (file->sample) { + /* it's already been loaded, so copy it */ + smp = song_get_sample(cur); + song_copy_sample(cur, file->sample); + strncpy(smp->name, file->title, 25); + smp->name[25] = 0; + strncpy(smp->filename, file->base, 12); + smp->filename[12] = 0; + finish_load(cur); + memused_songchanged(); + } else if (file->type & TYPE_SAMPLE_MASK) { + /* load the sample */ + song_load_sample(cur, file->path); + finish_load(cur); + memused_songchanged(); + } } static void do_discard_changes_and_move(UNUSED void *gn) { - fake_slot = KEYJAZZ_NOINST; - fake_slot_changed = 0; - search_pos = -1; - current_file = will_move_to; - file_list_reposition(); - status.flags |= NEED_UPDATE; + fake_slot = KEYJAZZ_NOINST; + fake_slot_changed = 0; + search_pos = -1; + current_file = will_move_to; + file_list_reposition(); + status.flags |= NEED_UPDATE; } static void do_delete_file(UNUSED void *data) { - int old_top_file, old_current_file; - char *ptr; + int old_top_file, old_current_file; + char *ptr; - if (current_file < 0 || current_file >= flist.num_files) - return; + if (current_file < 0 || current_file >= flist.num_files) + return; - ptr = flist.files[current_file]->path; + ptr = flist.files[current_file]->path; - /* would be neat to send it to the trash can if there is one */ - unlink(ptr); - - /* remember the list positions */ - old_top_file = top_file; - old_current_file = current_file; - - read_directory(); - - /* put the list positions back */ - top_file = old_top_file; - current_file = old_current_file; - /* edge case: if this was the last file, move the cursor up */ - if (current_file >= flist.num_files) - current_file = flist.num_files - 1; - file_list_reposition(); + /* would be neat to send it to the trash can if there is one */ + unlink(ptr); + + /* remember the list positions */ + old_top_file = top_file; + old_current_file = current_file; + + read_directory(); + + /* put the list positions back */ + top_file = old_top_file; + current_file = old_current_file; + /* edge case: if this was the last file, move the cursor up */ + if (current_file >= flist.num_files) + current_file = flist.num_files - 1; + file_list_reposition(); } static int file_list_handle_key(struct key_event * k) { - dmoz_file_t *f; - int new_file = current_file; - int c = unicode_to_ascii(k->unicode); - - new_file = CLAMP(new_file, 0, flist.num_files - 1); - - if (!(status.flags & CLASSIC_MODE) && k->sym == SDLK_n && (k->mod & KMOD_ALT)) { - if (k->state) - song_toggle_multichannel_mode(); - return 1; - } - - if (k->mouse) { - if (k->x >= 6 && k->x <= 49 && k->y >= 13 && k->y <= 47) { - search_pos = -1; - if (k->mouse == MOUSE_SCROLL_UP) { - new_file -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_file += MOUSE_SCROLL_LINES; - } else { - new_file = top_file + (k->y - 13); - } - } - } - switch (k->sym) { - case SDLK_UP: new_file--; search_pos = -1; break; - case SDLK_DOWN: new_file++; search_pos = -1; break; - case SDLK_PAGEUP: new_file -= 35; search_pos = -1; break; - case SDLK_PAGEDOWN: new_file += 35; search_pos = -1; break; - case SDLK_HOME: new_file = 0; search_pos = -1; break; - case SDLK_END: new_file = flist.num_files - 1; search_pos = -1; break; - - case SDLK_ESCAPE: - if (search_pos < 0) { - if (k->state && NO_MODIFIER(k->mod)) - set_page(PAGE_SAMPLE_LIST); - return 1; - } /* else fall through */ - case SDLK_RETURN: - if (search_pos < 0) { - if (!k->state) return 0; - handle_enter_key(); - search_pos = -1; - } else { - if (!k->state) return 1; - search_pos = -1; - status.flags |= NEED_UPDATE; - return 1; - } - return 1; - case SDLK_DELETE: - if (k->state) return 1; - search_pos = -1; - if (flist.num_files > 0) - dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); - return 1; - case SDLK_BACKSPACE: - if (search_pos > -1) { - if (k->state) return 1; - search_pos--; - status.flags |= NEED_UPDATE; - reposition_at_slash_search(); - return 1; - } - case SDLK_SLASH: - if (search_pos < 0) { - if (k->orig_sym == SDLK_SLASH) { - if (!k->state) return 0; - search_pos = 0; - status.flags |= NEED_UPDATE; - return 1; - } - return 0; - } /* else fall through */ - default: - f = flist.files[current_file]; - if (c >= 32 && (search_pos > -1 || (f && (f->type & TYPE_DIRECTORY)))) { - if (k->state) return 1; - if (search_pos < 0) search_pos = 0; - if (search_pos < PATH_MAX) { - search_str[search_pos++] = c; - reposition_at_slash_search(); - status.flags |= NEED_UPDATE; - } - return 1; - } - if (!k->mouse) return 0; - } - - if (k->mouse == MOUSE_CLICK) { - if (!k->state) return 0; - } else if (k->mouse == MOUSE_DBLCLICK) { - handle_enter_key(); - return 1; - } else { - if (k->state) return 1; - } - - new_file = CLAMP(new_file, 0, flist.num_files - 1); - if (new_file != current_file) { - if (fake_slot != KEYJAZZ_NOINST && fake_slot_changed) { - will_move_to = new_file; - dialog_create(DIALOG_YES_NO, - "Discard Changes?", - do_discard_changes_and_move, - NULL, - 0, NULL); - return 1; - /* support saving? XXX */ - /*"Save Sample?" OK Cancel*/ - /*"Discard Changes?" OK Cancel*/ - } - fake_slot = KEYJAZZ_NOINST; - fake_slot_changed = 0; - search_pos = -1; - current_file = new_file; - file_list_reposition(); - status.flags |= NEED_UPDATE; - } - return 1; + dmoz_file_t *f; + int new_file = current_file; + int c = unicode_to_ascii(k->unicode); + + new_file = CLAMP(new_file, 0, flist.num_files - 1); + + if (!(status.flags & CLASSIC_MODE) && k->sym == SDLK_n && (k->mod & KMOD_ALT)) { + if (k->state == KEY_RELEASE) + song_toggle_multichannel_mode(); + return 1; + } + + if (k->mouse) { + if (k->x >= 6 && k->x <= 49 && k->y >= 13 && k->y <= 47) { + search_pos = -1; + if (k->mouse == MOUSE_SCROLL_UP) { + new_file -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_file += MOUSE_SCROLL_LINES; + } else { + new_file = top_file + (k->y - 13); + } + } + } + switch (k->sym) { + case SDLK_UP: new_file--; search_pos = -1; break; + case SDLK_DOWN: new_file++; search_pos = -1; break; + case SDLK_PAGEUP: new_file -= 35; search_pos = -1; break; + case SDLK_PAGEDOWN: new_file += 35; search_pos = -1; break; + case SDLK_HOME: new_file = 0; search_pos = -1; break; + case SDLK_END: new_file = flist.num_files - 1; search_pos = -1; break; + + case SDLK_ESCAPE: + if (search_pos < 0) { + if (k->state == KEY_RELEASE && NO_MODIFIER(k->mod)) + set_page(PAGE_SAMPLE_LIST); + return 1; + } /* else fall through */ + case SDLK_RETURN: + if (search_pos < 0) { + if (k->state == KEY_PRESS) + return 0; + handle_enter_key(); + search_pos = -1; + } else { + if (k->state == KEY_PRESS) + return 1; + search_pos = -1; + status.flags |= NEED_UPDATE; + return 1; + } + return 1; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 1; + search_pos = -1; + if (flist.num_files > 0) + dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); + return 1; + case SDLK_BACKSPACE: + if (search_pos > -1) { + if (k->state == KEY_RELEASE) + return 1; + search_pos--; + status.flags |= NEED_UPDATE; + reposition_at_slash_search(); + return 1; + } + case SDLK_SLASH: + if (search_pos < 0) { + if (k->orig_sym == SDLK_SLASH) { + if (k->state == KEY_PRESS) + return 0; + search_pos = 0; + status.flags |= NEED_UPDATE; + return 1; + } + return 0; + } /* else fall through */ + default: + f = flist.files[current_file]; + if (c >= 32 && (search_pos > -1 || (f && (f->type & TYPE_DIRECTORY)))) { + if (k->state == KEY_RELEASE) + return 1; + if (search_pos < 0) search_pos = 0; + if (search_pos < PATH_MAX) { + search_str[search_pos++] = c; + reposition_at_slash_search(); + status.flags |= NEED_UPDATE; + } + return 1; + } + if (!k->mouse) return 0; + } + + if (k->mouse == MOUSE_CLICK) { + if (k->state == KEY_PRESS) + return 0; + } else if (k->mouse == MOUSE_DBLCLICK) { + handle_enter_key(); + return 1; + } else { + if (k->state == KEY_RELEASE) + return 1; + } + + new_file = CLAMP(new_file, 0, flist.num_files - 1); + if (new_file != current_file) { + if (fake_slot != KEYJAZZ_NOINST && fake_slot_changed) { + will_move_to = new_file; + dialog_create(DIALOG_YES_NO, + "Discard Changes?", + do_discard_changes_and_move, + NULL, + 0, NULL); + return 1; + /* support saving? XXX */ + /*"Save Sample?" OK Cancel*/ + /*"Discard Changes?" OK Cancel*/ + } + fake_slot = KEYJAZZ_NOINST; + fake_slot_changed = 0; + search_pos = -1; + current_file = new_file; + file_list_reposition(); + status.flags |= NEED_UPDATE; + } + return 1; } static void load_sample_handle_key(struct key_event * k) { - int n, v; + int n, v; - if (!k->state && k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod)) { - set_page(PAGE_SAMPLE_LIST); - return; - } - if (!NO_MODIFIER(k->mod)) return; - - if (k->midi_note > -1) { - n = k->midi_note; - if (k->midi_volume > -1) { - v = k->midi_volume / 2; - } else { - v = KEYJAZZ_DEFAULTVOL; - } - } else if (k->is_repeat) { - return; - } else { - n = kbd_get_note(k); - v = KEYJAZZ_DEFAULTVOL; - if (n <= 0 || n > 120) - return; - } - - handle_preload(); - if (fake_slot != KEYJAZZ_NOINST) { - if (k->state) - song_keyup(KEYJAZZ_INST_FAKE, KEYJAZZ_NOINST, n); - else - song_keydown(KEYJAZZ_INST_FAKE, KEYJAZZ_NOINST, n, v, KEYJAZZ_CHAN_CURRENT); - } + if (k->state == KEY_PRESS && k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod)) { + set_page(PAGE_SAMPLE_LIST); + return; + } + if (!NO_MODIFIER(k->mod)) return; + + if (k->midi_note > -1) { + n = k->midi_note; + if (k->midi_volume > -1) { + v = k->midi_volume / 2; + } else { + v = KEYJAZZ_DEFAULTVOL; + } + } else if (k->is_repeat) { + return; + } else { + n = kbd_get_note(k); + v = KEYJAZZ_DEFAULTVOL; + if (n <= 0 || n > 120) + return; + } + + handle_preload(); + if (fake_slot != KEYJAZZ_NOINST) { + if (k->state == KEY_PRESS) + song_keydown(KEYJAZZ_INST_FAKE, KEYJAZZ_NOINST, n, v, KEYJAZZ_CHAN_CURRENT); + else + song_keyup(KEYJAZZ_INST_FAKE, KEYJAZZ_NOINST, n); + } } /* --------------------------------------------------------------------------------------------------------- */ static void handle_preload(void) { - dmoz_file_t *file; + dmoz_file_t *file; - if (fake_slot == KEYJAZZ_NOINST && current_file >= 0 && current_file < flist.num_files) { - file = flist.files[current_file]; - if (file && (file->type & TYPE_SAMPLE_MASK)) { - fake_slot_changed = 0; - fake_slot = song_preload_sample(file); // either 0 or KEYJAZZ_NOTINST - } - } + if (fake_slot == KEYJAZZ_NOINST && current_file >= 0 && current_file < flist.num_files) { + file = flist.files[current_file]; + if (file && (file->type & TYPE_SAMPLE_MASK)) { + fake_slot_changed = 0; + fake_slot = song_preload_sample(file); // either 0 or KEYJAZZ_NOTINST + } + } } static void handle_rename_op(void) { - handle_preload(); + handle_preload(); } static void handle_load_copy_uint(unsigned int s, unsigned int *d) { - if (s != *d) { - *d = s; - fake_slot_changed = 1; - } + if (s != *d) { + *d = s; + fake_slot_changed = 1; + } } static void handle_load_copy(song_sample_t *s) { - handle_load_copy_uint(widgets_loadsample[2].d.numentry.value, &s->c5speed); - handle_load_copy_uint(widgets_loadsample[4].d.numentry.value, &s->loop_start); - handle_load_copy_uint(widgets_loadsample[5].d.numentry.value, &s->loop_end); - handle_load_copy_uint(widgets_loadsample[7].d.numentry.value, &s->sustain_start); - handle_load_copy_uint(widgets_loadsample[8].d.numentry.value, &s->sustain_end); - handle_load_copy_uint(widgets_loadsample[9].d.thumbbar.value, &s->volume); - if ((unsigned int)widgets_loadsample[9].d.thumbbar.value == (s->volume>>2)) { - s->volume = (widgets_loadsample[9].d.thumbbar.value << 2); - fake_slot_changed=1; - } - handle_load_copy_uint(widgets_loadsample[10].d.thumbbar.value, &s->global_volume); - handle_load_copy_uint(widgets_loadsample[11].d.thumbbar.value, &s->vib_rate); - handle_load_copy_uint(widgets_loadsample[12].d.thumbbar.value, &s->vib_depth); - handle_load_copy_uint(widgets_loadsample[13].d.thumbbar.value, &s->vib_speed); - switch (widgets_loadsample[3].d.menutoggle.state) { - case 0: - if (s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) { - s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); - fake_slot_changed=1; - } - break; - case 1: - if ((s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) == CHN_LOOP) { - s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); - s->flags |= (CHN_LOOP); - fake_slot_changed=1; - } - break; - case 2: - if ((s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) == CHN_PINGPONGLOOP) { - s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); - s->flags |= (CHN_PINGPONGLOOP); - fake_slot_changed=1; - } - break; - }; - switch (widgets_loadsample[6].d.menutoggle.state) { - case 0: - if (s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) { - s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); - fake_slot_changed=1; - } - break; - case 1: - if ((s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) == CHN_SUSTAINLOOP) { - s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); - s->flags |= (CHN_SUSTAINLOOP); - fake_slot_changed=1; - } - break; - case 2: - if ((s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) == CHN_PINGPONGSUSTAIN) { - s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); - s->flags |= (CHN_PINGPONGSUSTAIN); - fake_slot_changed=1; - } - break; - }; + handle_load_copy_uint(widgets_loadsample[2].d.numentry.value, &s->c5speed); + handle_load_copy_uint(widgets_loadsample[4].d.numentry.value, &s->loop_start); + handle_load_copy_uint(widgets_loadsample[5].d.numentry.value, &s->loop_end); + handle_load_copy_uint(widgets_loadsample[7].d.numentry.value, &s->sustain_start); + handle_load_copy_uint(widgets_loadsample[8].d.numentry.value, &s->sustain_end); + handle_load_copy_uint(widgets_loadsample[9].d.thumbbar.value, &s->volume); + if ((unsigned int)widgets_loadsample[9].d.thumbbar.value == (s->volume>>2)) { + s->volume = (widgets_loadsample[9].d.thumbbar.value << 2); + fake_slot_changed=1; + } + handle_load_copy_uint(widgets_loadsample[10].d.thumbbar.value, &s->global_volume); + handle_load_copy_uint(widgets_loadsample[11].d.thumbbar.value, &s->vib_rate); + handle_load_copy_uint(widgets_loadsample[12].d.thumbbar.value, &s->vib_depth); + handle_load_copy_uint(widgets_loadsample[13].d.thumbbar.value, &s->vib_speed); + switch (widgets_loadsample[3].d.menutoggle.state) { + case 0: + if (s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) { + s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); + fake_slot_changed=1; + } + break; + case 1: + if ((s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) == CHN_LOOP) { + s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); + s->flags |= (CHN_LOOP); + fake_slot_changed=1; + } + break; + case 2: + if ((s->flags & (CHN_LOOP|CHN_PINGPONGLOOP)) == CHN_PINGPONGLOOP) { + s->flags &= ~(CHN_LOOP|CHN_PINGPONGLOOP); + s->flags |= (CHN_PINGPONGLOOP); + fake_slot_changed=1; + } + break; + }; + switch (widgets_loadsample[6].d.menutoggle.state) { + case 0: + if (s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) { + s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + fake_slot_changed=1; + } + break; + case 1: + if ((s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) == CHN_SUSTAINLOOP) { + s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + s->flags |= (CHN_SUSTAINLOOP); + fake_slot_changed=1; + } + break; + case 2: + if ((s->flags & (CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN)) == CHN_PINGPONGSUSTAIN) { + s->flags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN); + s->flags |= (CHN_PINGPONGSUSTAIN); + fake_slot_changed=1; + } + break; + }; } static void handle_load_update(void) { - song_sample_t *s; - handle_preload(); - if (fake_slot != KEYJAZZ_NOINST) { - s = song_get_sample(fake_slot); - if (s) { - handle_load_copy(s); - song_update_playing_sample(fake_slot); - } - } + song_sample_t *s; + handle_preload(); + if (fake_slot != KEYJAZZ_NOINST) { + s = song_get_sample(fake_slot); + if (s) { + handle_load_copy(s); + song_update_playing_sample(fake_slot); + } + } } void load_sample_load_page(struct page *page) { - vgamem_ovl_alloc(&sample_image); - clear_directory(); + vgamem_ovl_alloc(&sample_image); + clear_directory(); - create_other(widgets_loadsample + 0, 0, - file_list_handle_key, file_list_draw); - widgets_loadsample[0].accept_text = 1; - widgets_loadsample[0].next.tab = 1; - - create_textentry(widgets_loadsample+1, - 64, 13, - 13, - 1,2, 9, handle_rename_op, - current_filename, sizeof(current_filename)-1); - sample_speed_pos = 0; - create_numentry(widgets_loadsample+2, - 64, 14, - 7, - 1,3, 9, handle_load_update, - 0, 9999999, - &sample_speed_pos); - - create_menutoggle(widgets_loadsample+3, - 64, 15, - 2, 4, 0, 9,9, handle_load_update, - loop_states); - - sample_loop_beg = 0; - create_numentry(widgets_loadsample+4, - 64, 16, - 7, - 3,5, 9, handle_load_update, - 0, 9999999, - &sample_loop_beg); - sample_loop_end = 0; - create_numentry(widgets_loadsample+5, - 64, 17, - 7, - 4,6, 9, handle_load_update, - 0, 9999999, - &sample_loop_end); - - create_menutoggle(widgets_loadsample+6, - 64, 18, - 5, 7, 0, 9,9, handle_load_update, - loop_states); - - sample_susloop_beg = 0; - create_numentry(widgets_loadsample+7, - 64, 19, - 7, - 6,8, 9, handle_load_update, - 0, 9999999, - &sample_susloop_beg); - sample_susloop_end = 0; - create_numentry(widgets_loadsample+8, - 64, 20, - 7, - 7,9, 9, handle_load_update, - 0, 9999999, - &sample_susloop_end); - - create_thumbbar(widgets_loadsample+9, - 63, 33, - 9, - 8, 10, 0, handle_load_update, - 0,64); - create_thumbbar(widgets_loadsample+10, - 63, 34, - 9, - 9, 11, 0, handle_load_update, - 0,64); - - create_thumbbar(widgets_loadsample+11, - 63, 37, - 9, - 10, 12, 0, handle_load_update, - 0,64); - create_thumbbar(widgets_loadsample+12, - 63, 38, - 9, - 11, 13, 0, handle_load_update, - 0,32); - create_thumbbar(widgets_loadsample+13, - 63, 39, - 9, - 12, 13, 0, handle_load_update, - 0,255); - - - page->title = "Load Sample"; - page->draw_const = load_sample_draw_const; - page->set_page = load_sample_set_page; - page->handle_key = load_sample_handle_key; - page->total_widgets = 14; - page->widgets = widgets_loadsample; - page->help_index = HELP_GLOBAL; + create_other(widgets_loadsample + 0, 0, + file_list_handle_key, file_list_draw); + widgets_loadsample[0].accept_text = 1; + widgets_loadsample[0].next.tab = 1; + + create_textentry(widgets_loadsample+1, + 64, 13, + 13, + 1,2, 9, handle_rename_op, + current_filename, sizeof(current_filename)-1); + sample_speed_pos = 0; + create_numentry(widgets_loadsample+2, + 64, 14, + 7, + 1,3, 9, handle_load_update, + 0, 9999999, + &sample_speed_pos); + + create_menutoggle(widgets_loadsample+3, + 64, 15, + 2, 4, 0, 9,9, handle_load_update, + loop_states); + + sample_loop_beg = 0; + create_numentry(widgets_loadsample+4, + 64, 16, + 7, + 3,5, 9, handle_load_update, + 0, 9999999, + &sample_loop_beg); + sample_loop_end = 0; + create_numentry(widgets_loadsample+5, + 64, 17, + 7, + 4,6, 9, handle_load_update, + 0, 9999999, + &sample_loop_end); + + create_menutoggle(widgets_loadsample+6, + 64, 18, + 5, 7, 0, 9,9, handle_load_update, + loop_states); + + sample_susloop_beg = 0; + create_numentry(widgets_loadsample+7, + 64, 19, + 7, + 6,8, 9, handle_load_update, + 0, 9999999, + &sample_susloop_beg); + sample_susloop_end = 0; + create_numentry(widgets_loadsample+8, + 64, 20, + 7, + 7,9, 9, handle_load_update, + 0, 9999999, + &sample_susloop_end); + + create_thumbbar(widgets_loadsample+9, + 63, 33, + 9, + 8, 10, 0, handle_load_update, + 0,64); + create_thumbbar(widgets_loadsample+10, + 63, 34, + 9, + 9, 11, 0, handle_load_update, + 0,64); + + create_thumbbar(widgets_loadsample+11, + 63, 37, + 9, + 10, 12, 0, handle_load_update, + 0,64); + create_thumbbar(widgets_loadsample+12, + 63, 38, + 9, + 11, 13, 0, handle_load_update, + 0,32); + create_thumbbar(widgets_loadsample+13, + 63, 39, + 9, + 12, 13, 0, handle_load_update, + 0,255); + + + page->title = "Load Sample"; + page->draw_const = load_sample_draw_const; + page->set_page = load_sample_set_page; + page->handle_key = load_sample_handle_key; + page->total_widgets = 14; + page->widgets = widgets_loadsample; + page->help_index = HELP_GLOBAL; } void library_sample_load_page(struct page *page) { - /* this shares all the widgets from load_sample */ + /* this shares all the widgets from load_sample */ - page->title = "Sample Library (Ctrl-F3)"; - page->draw_const = load_sample_draw_const; - page->set_page = library_sample_set_page; - page->handle_key = load_sample_handle_key; - page->total_widgets = 14; - page->widgets = widgets_loadsample; - page->help_index = HELP_GLOBAL; + page->title = "Sample Library (Ctrl-F3)"; + page->draw_const = load_sample_draw_const; + page->set_page = library_sample_set_page; + page->handle_key = load_sample_handle_key; + page->total_widgets = 14; + page->widgets = widgets_loadsample; + page->help_index = HELP_GLOBAL; } diff -Nru schism-0+20110101/schism/page_log.c schism-20160521/schism/page_log.c --- schism-0+20110101/schism/page_log.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_log.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,17 +35,17 @@ #include struct log_line { - int color; - const char *text; - int bios_font; - /* Set this flag if the text should be free'd when it is scrolled offscreen. - DON'T set it if the text is going to be modified after it is added to the log (e.g. for displaying - status information for module loaders like IT); in that case, change the text pointer to some - constant value such as "". Also don't try changing must_free after adding a line to the log, since - there's a chance that the line scrolled offscreen, and it'd never get free'd. (Also, ignore this - comment since there's currently no interface for manipulating individual lines in the log after - adding them.) */ - int must_free; + int color; + const char *text; + int bios_font; + /* Set this flag if the text should be free'd when it is scrolled offscreen. + DON'T set it if the text is going to be modified after it is added to the log (e.g. for displaying + status information for module loaders like IT); in that case, change the text pointer to some + constant value such as "". Also don't try changing must_free after adding a line to the log, since + there's a chance that the line scrolled offscreen, and it'd never get free'd. (Also, ignore this + comment since there's currently no interface for manipulating individual lines in the log after + adding them.) */ + int must_free; }; /* --------------------------------------------------------------------- */ @@ -61,152 +61,158 @@ static void log_draw_const(void) { - draw_box(1, 12, 78, 48, BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(2, 13, 77, 47, 0); + draw_box(1, 12, 78, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(2, 13, 77, 47, 0); } static int log_handle_key(struct key_event * k) { - switch (k->sym) { - case SDLK_UP: - if (k->state) return 1; - top_line--; - break; - case SDLK_PAGEUP: - if (k->state) return 1; - top_line -= 15; - break; - case SDLK_DOWN: - if (k->state) return 1; - top_line++; - break; - case SDLK_PAGEDOWN: - if (k->state) return 1; - top_line += 15; - break; - case SDLK_HOME: - if (k->state) return 1; - top_line = 0; - break; - case SDLK_END: - if (k->state) return 1; - top_line = last_line; - break; - default: - if (!k->state) { - if (k->mouse == MOUSE_SCROLL_UP) { - top_line -= MOUSE_SCROLL_LINES; - break; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - top_line += MOUSE_SCROLL_LINES; - break; - } - } - - return 0; - }; - top_line = CLAMP(top_line, 0, (last_line-32)); - if (top_line < 0) top_line = 0; - status.flags |= NEED_UPDATE; - return 1; + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + top_line--; + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 1; + top_line -= 15; + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + top_line++; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 1; + top_line += 15; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 1; + top_line = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 1; + top_line = last_line; + break; + default: + if (k->state == KEY_PRESS) { + if (k->mouse == MOUSE_SCROLL_UP) { + top_line -= MOUSE_SCROLL_LINES; + break; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + top_line += MOUSE_SCROLL_LINES; + break; + } + } + + return 0; + }; + top_line = CLAMP(top_line, 0, (last_line-32)); + if (top_line < 0) top_line = 0; + status.flags |= NEED_UPDATE; + return 1; } static void log_redraw(void) { - int n, i; + int n, i; - i = top_line; - for (n = 0; n <= last_line && n < 33; n++, i++) { - if (!lines[i].text) continue; - if (lines[i].bios_font) { - draw_text_bios_len(lines[i].text, - 74, 3, 14 + n, - lines[i].color, 0); - } else { - draw_text_len(lines[i].text, - 74, 3, 14 + n, - lines[i].color, 0); - } - } + i = top_line; + for (n = 0; n <= last_line && n < 33; n++, i++) { + if (!lines[i].text) continue; + if (lines[i].bios_font) { + draw_text_bios_len(lines[i].text, + 74, 3, 14 + n, + lines[i].color, 0); + } else { + draw_text_len(lines[i].text, + 74, 3, 14 + n, + lines[i].color, 0); + } + } } /* --------------------------------------------------------------------- */ void log_load_page(struct page *page) { - page->title = "Message Log Viewer (Ctrl-F11)"; - page->draw_const = log_draw_const; - page->total_widgets = 1; - page->widgets = widgets_log; - page->help_index = HELP_COPYRIGHT; /* I guess */ + page->title = "Message Log Viewer (Ctrl-F11)"; + page->draw_const = log_draw_const; + page->total_widgets = 1; + page->widgets = widgets_log; + page->help_index = HELP_COPYRIGHT; /* I guess */ - create_other(widgets_log + 0, 0, log_handle_key, log_redraw); + create_other(widgets_log + 0, 0, log_handle_key, log_redraw); } /* --------------------------------------------------------------------- */ inline void log_append2(int bios_font, int color, int must_free, const char *text) { - if (last_line < NUM_LINES - 1) { - last_line++; - } else { - if (lines[0].must_free) - free((void *) lines[0].text); - memmove(lines, lines + 1, last_line * sizeof(struct log_line)); - } - lines[last_line].text = text; - lines[last_line].color = color; - lines[last_line].must_free = must_free; - lines[last_line].bios_font = bios_font; - top_line = CLAMP(last_line - 32, 0, NUM_LINES-32); + if (last_line < NUM_LINES - 1) { + last_line++; + } else { + if (lines[0].must_free) + free((void *) lines[0].text); + memmove(lines, lines + 1, last_line * sizeof(struct log_line)); + } + lines[last_line].text = text; + lines[last_line].color = color; + lines[last_line].must_free = must_free; + lines[last_line].bios_font = bios_font; + top_line = CLAMP(last_line - 32, 0, NUM_LINES-32); - if (status.current_page == PAGE_LOG) - status.flags |= NEED_UPDATE; + if (status.current_page == PAGE_LOG) + status.flags |= NEED_UPDATE; } inline void log_append(int color, int must_free, const char *text) { - log_append2(0, color, must_free, text); + log_append2(0, color, must_free, text); } inline void log_nl(void) { - log_append(0,0,""); + log_append(0,0,""); } void log_appendf(int color, const char *format, ...) { - char *ptr; - va_list ap; + char *ptr; + va_list ap; - va_start(ap, format); - if (vasprintf(&ptr, format, ap) == -1) { - perror("asprintf"); - exit(255); - } - va_end(ap); - - if (!ptr) { - perror("asprintf"); - exit(255); - } + va_start(ap, format); + if (vasprintf(&ptr, format, ap) == -1) { + perror("asprintf"); + exit(255); + } + va_end(ap); + + if (!ptr) { + perror("asprintf"); + exit(255); + } - log_append(color, 1, ptr); + log_append(color, 1, ptr); } void log_underline(int chars) { - char buf[75]; + char buf[75]; - chars = CLAMP(chars, 0, (int) sizeof(buf) - 1); - buf[chars--] = '\0'; - do - buf[chars] = 0x81; - while (chars--); - log_appendf(2, "%s", buf); + chars = CLAMP(chars, 0, (int) sizeof(buf) - 1); + buf[chars--] = '\0'; + do + buf[chars] = 0x81; + while (chars--); + log_appendf(2, "%s", buf); } void log_perror(const char *prefix) { - char *e = strerror(errno); - perror(prefix); - log_appendf(4, "%s: %s", prefix, e); + char *e = strerror(errno); + perror(prefix); + log_appendf(4, "%s: %s", prefix, e); } diff -Nru schism-0+20110101/schism/page_message.c schism-20160521/schism/page_message.c --- schism-0+20110101/schism/page_message.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_message.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -74,80 +74,80 @@ * probably happen, so don't do that. */ static int get_nth_line(char *text, int n, char **ptr) { - char *tmp; + char *tmp; - assert(text != NULL); + assert(text != NULL); - *ptr = text; - while (n > 0) { - n--; - *ptr = strpbrk(*ptr, "\xd\xa"); - if (!(*ptr)) { - *ptr = text + strlen(text); - return -1; - } - if ((*ptr)[0] == 13 && (*ptr)[1] == 10) - *ptr += 2; - else - (*ptr)++; - } + *ptr = text; + while (n > 0) { + n--; + *ptr = strpbrk(*ptr, "\xd\xa"); + if (!(*ptr)) { + *ptr = text + strlen(text); + return -1; + } + if ((*ptr)[0] == 13 && (*ptr)[1] == 10) + *ptr += 2; + else + (*ptr)++; + } - tmp = strpbrk(*ptr, "\xd\xa"); - return (tmp ? (unsigned) (tmp - *ptr) : strlen(*ptr)); + tmp = strpbrk(*ptr, "\xd\xa"); + return (tmp ? (unsigned) (tmp - *ptr) : strlen(*ptr)); } static void set_absolute_position(char *text, int pos, int *line, int *ch) { - int len; - char *ptr; + int len; + char *ptr; - *line = *ch = 0; - ptr = NULL; - while (pos > 0) { - len = get_nth_line(text, *line, &ptr); - if (len < 0) { - /* end of file */ - (*line) = (*line) - 1; - if (*line < 0) *line = 0; - len = get_nth_line(text, *line, &ptr); - if (len < 0) { - *ch = 0; - } else { - *ch = len; - } - pos = 0; - - } else if (len >= pos) { - *ch = pos; - pos = 0; - } else { - pos -= (len+1); /* EOC */ - (*line) = (*line) + 1; - } - } + *line = *ch = 0; + ptr = NULL; + while (pos > 0) { + len = get_nth_line(text, *line, &ptr); + if (len < 0) { + /* end of file */ + (*line) = (*line) - 1; + if (*line < 0) *line = 0; + len = get_nth_line(text, *line, &ptr); + if (len < 0) { + *ch = 0; + } else { + *ch = len; + } + pos = 0; + + } else if (len >= pos) { + *ch = pos; + pos = 0; + } else { + pos -= (len+1); /* EOC */ + (*line) = (*line) + 1; + } + } } static int get_absolute_position(char *text, int line, int character) { - int len; - char *ptr; + int len; + char *ptr; - ptr = NULL; - len = get_nth_line(text, line, &ptr); - if (len < 0) { - return 0; - } - /* hrm... what if cursor_char > len? */ - return (ptr - text) + character; + ptr = NULL; + len = get_nth_line(text, line, &ptr); + if (len < 0) { + return 0; + } + /* hrm... what if cursor_char > len? */ + return (ptr - text) + character; } /* --------------------------------------------------------------------- */ static void message_reposition(void) { - if (cursor_line < top_line) { - top_line = cursor_line; - } else if (cursor_line > top_line + 34) { - top_line = cursor_line - 34; - } + if (cursor_line < top_line) { + top_line = cursor_line; + } else if (cursor_line > top_line + 34) { + top_line = cursor_line - 34; + } } /* --------------------------------------------------------------------- */ @@ -155,657 +155,683 @@ /* returns 1 if a character was actually added */ static int message_add_char(int newchar, int position) { - int len = strlen(current_song->message); + int len = strlen(current_song->message); - if (len == MAX_MESSAGE) { - dialog_create(DIALOG_OK, " Song message too long! ", NULL, NULL, 0, NULL); - return 0; - } - if (position < 0 || position > len) { - log_appendf(4, "message_add_char: position=%d, len=%d - shouldn't happen!", position, len); - return 0; - } - - memmove(current_song->message + position + 1, current_song->message + position, len - position); - current_song->message[len + 1] = 0; - current_song->message[position] = (unsigned char)newchar; - return 1; + if (len == MAX_MESSAGE) { + dialog_create(DIALOG_OK, " Song message too long! ", NULL, NULL, 0, NULL); + return 0; + } + if (position < 0 || position > len) { + log_appendf(4, "message_add_char: position=%d, len=%d - shouldn't happen!", position, len); + return 0; + } + + memmove(current_song->message + position + 1, current_song->message + position, len - position); + current_song->message[len + 1] = 0; + current_song->message[position] = (unsigned char)newchar; + return 1; } /* this returns the new length of the line */ static int message_wrap_line(char *bol_ptr) { - char *eol_ptr; - char *last_space = NULL; - char *tmp = bol_ptr; - - if (!bol_ptr) - /* shouldn't happen, but... */ - return 0; - - eol_ptr = strpbrk(bol_ptr, "\xd\xa"); - if (!eol_ptr) - eol_ptr = bol_ptr + strlen(bol_ptr); - - for (;;) { - tmp = strpbrk((tmp + 1), " \t"); - if (tmp == NULL || tmp > eol_ptr - || tmp - bol_ptr > LINE_WRAP) - break; - last_space = tmp; - } - - if (last_space) { - *last_space = 13; - return last_space - bol_ptr; - } else { - /* what, no spaces to cut at? chop it mercilessly. */ - if (message_add_char(13, bol_ptr + LINE_WRAP - current_song->message) - == 0) - /* ack, the message is too long to wrap the line! - * gonna have to resort to something ugly. */ - bol_ptr[LINE_WRAP] = 13; - return LINE_WRAP; - } + char *eol_ptr; + char *last_space = NULL; + char *tmp = bol_ptr; + + if (!bol_ptr) + /* shouldn't happen, but... */ + return 0; + + eol_ptr = strpbrk(bol_ptr, "\xd\xa"); + if (!eol_ptr) + eol_ptr = bol_ptr + strlen(bol_ptr); + + for (;;) { + tmp = strpbrk((tmp + 1), " \t"); + if (tmp == NULL || tmp > eol_ptr + || tmp - bol_ptr > LINE_WRAP) + break; + last_space = tmp; + } + + if (last_space) { + *last_space = 13; + return last_space - bol_ptr; + } else { + /* what, no spaces to cut at? chop it mercilessly. */ + if (message_add_char(13, bol_ptr + LINE_WRAP - current_song->message) + == 0) + /* ack, the message is too long to wrap the line! + * gonna have to resort to something ugly. */ + bol_ptr[LINE_WRAP] = 13; + return LINE_WRAP; + } } /* --------------------------------------------------------------------- */ static void text(char *line, int len, int n) { - unsigned char ch; - int fg = (message_extfont ? 12 : 6); - int i; - - for (i = 0; line[i] && i < len; i++) { - ch = line[i]; - - if (ch == ' ') { - draw_char(' ', 2+i, 13+n, 3,0); - } else { - (message_extfont ? draw_char_bios : draw_char)(ch, 2+i, 13+n, fg, 0); - } - } + unsigned char ch; + int fg = (message_extfont ? 12 : 6); + int i; + + for (i = 0; line[i] && i < len; i++) { + ch = line[i]; + + if (ch == ' ') { + draw_char(' ', 2+i, 13+n, 3,0); + } else { + (message_extfont ? draw_char_bios : draw_char)(ch, 2+i, 13+n, fg, 0); + } + } } static void message_draw(void) { - char *line, *prevline = current_song->message; - int len = get_nth_line(current_song->message, top_line, &line); - int n, cp, clipl, clipr; - int skipc, cutc; - - draw_fill_chars(2, 13, 77, 47, 0); - - if (clippy_owner(CLIPPY_SELECT) == widgets_message) { - clipl = widgets_message[0].clip_start; - clipr = widgets_message[0].clip_end; - if (clipl > clipr) { - cp = clipl; - clipl = clipr; - clipr = cp; - } - } else { - clipl = clipr = -1; - } - - for (n = 0; n < 35; n++) { - if (len < 0) { - break; - } else if (len > 0) { - /* FIXME | shouldn't need this check here, - * FIXME | because the line should already be - * FIXME | short enough to fit */ - if (len > LINE_WRAP) - len = LINE_WRAP; - text(line, len, n); - - if (clipl > -1) { - cp = line - current_song->message; - skipc = clipl - cp; - cutc = clipr - clipl; - if (skipc < 0) { - cutc += skipc; /* ... -skipc */ - skipc = 0; - } - if (cutc < 0) cutc = 0; - if (cutc > (len-skipc)) cutc = (len-skipc); - if (cutc > 0 && skipc < len) { - if (message_extfont) - draw_text_bios_len(line+skipc, cutc, 2+skipc, 13 + n, 6, 8); - else - draw_text_len(line+skipc, cutc, 2+skipc, 13 + n, 6, 8); - } - } - } - if (edit_mode) { - draw_char(20, 2 + len, 13 + n, 1, 0); - } - prevline = line; - len = get_nth_line(prevline, 1, &line); - } - - if (edit_mode && len < 0) { - /* end of the message */ - len = get_nth_line(prevline, 0, &line); - /* FIXME: see above */ - if (len > LINE_WRAP) - len = LINE_WRAP; - draw_char(20, 2 + len, 13 + n - 1, 2, 0); - } - - if (edit_mode) { - /* draw the cursor */ - len = get_nth_line(current_song->message, cursor_line, &line); - - /* FIXME: ... ugh */ - if (len > LINE_WRAP) - len = LINE_WRAP; - if (cursor_char > LINE_WRAP + 1) - cursor_char = LINE_WRAP + 1; - - if (cursor_char >= len) { - (message_extfont ? draw_char_bios : draw_char) - (20, 2 + cursor_char, 13 + (cursor_line - top_line), 0, 3); - } else { - (message_extfont ? draw_char_bios : draw_char) - (line[cursor_char], 2 + cursor_char, 13 + (cursor_line - top_line), 8, 3); - } - } + char *line, *prevline = current_song->message; + int len = get_nth_line(current_song->message, top_line, &line); + int n, cp, clipl, clipr; + int skipc, cutc; + + draw_fill_chars(2, 13, 77, 47, 0); + + if (clippy_owner(CLIPPY_SELECT) == widgets_message) { + clipl = widgets_message[0].clip_start; + clipr = widgets_message[0].clip_end; + if (clipl > clipr) { + cp = clipl; + clipl = clipr; + clipr = cp; + } + } else { + clipl = clipr = -1; + } + + for (n = 0; n < 35; n++) { + if (len < 0) { + break; + } else if (len > 0) { + /* FIXME | shouldn't need this check here, + * FIXME | because the line should already be + * FIXME | short enough to fit */ + if (len > LINE_WRAP) + len = LINE_WRAP; + text(line, len, n); + + if (clipl > -1) { + cp = line - current_song->message; + skipc = clipl - cp; + cutc = clipr - clipl; + if (skipc < 0) { + cutc += skipc; /* ... -skipc */ + skipc = 0; + } + if (cutc < 0) cutc = 0; + if (cutc > (len-skipc)) cutc = (len-skipc); + if (cutc > 0 && skipc < len) { + if (message_extfont) + draw_text_bios_len(line+skipc, cutc, 2+skipc, 13 + n, 6, 8); + else + draw_text_len(line+skipc, cutc, 2+skipc, 13 + n, 6, 8); + } + } + } + if (edit_mode) { + draw_char(20, 2 + len, 13 + n, 1, 0); + } + prevline = line; + len = get_nth_line(prevline, 1, &line); + } + + if (edit_mode && len < 0) { + /* end of the message */ + len = get_nth_line(prevline, 0, &line); + /* FIXME: see above */ + if (len > LINE_WRAP) + len = LINE_WRAP; + draw_char(20, 2 + len, 13 + n - 1, 2, 0); + } + + if (edit_mode) { + /* draw the cursor */ + len = get_nth_line(current_song->message, cursor_line, &line); + + /* FIXME: ... ugh */ + if (len > LINE_WRAP) + len = LINE_WRAP; + if (cursor_char > LINE_WRAP + 1) + cursor_char = LINE_WRAP + 1; + + if (cursor_char >= len) { + (message_extfont ? draw_char_bios : draw_char) + (20, 2 + cursor_char, 13 + (cursor_line - top_line), 0, 3); + } else { + (message_extfont ? draw_char_bios : draw_char) + (line[cursor_char], 2 + cursor_char, 13 + (cursor_line - top_line), 8, 3); + } + } } /* --------------------------------------------------------------------- */ static inline void message_set_editmode(void) { - edit_mode = 1; - widgets_message[0].accept_text = 1; - top_line = cursor_line = cursor_char = cursor_pos = 0; - widgets_message[0].d.other.handle_key = message_handle_key_editmode; + edit_mode = 1; + widgets_message[0].accept_text = 1; + top_line = cursor_line = cursor_char = cursor_pos = 0; + widgets_message[0].d.other.handle_key = message_handle_key_editmode; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static inline void message_set_viewmode(void) { - edit_mode = 0; - widgets_message[0].accept_text = 0; - widgets_message[0].d.other.handle_key = message_handle_key_viewmode; + edit_mode = 0; + widgets_message[0].accept_text = 0; + widgets_message[0].d.other.handle_key = message_handle_key_viewmode; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void message_insert_char(int c) { - char *ptr; - int n; + char *ptr; + int n; - if (!edit_mode) - return; + if (!edit_mode) + return; - memused_songchanged(); - if (c == '\t') { - /* Find the number of characters until the next tab stop. - * (This is new behaviour; Impulse Tracker just inserts - * eight characters regardless of the cursor position.) */ - n = 8 - cursor_char % 8; - if (cursor_char + n > LINE_WRAP) { - message_insert_char('\r'); - } else { - do { - if (!message_add_char(' ', cursor_pos)) - break; - cursor_char++; - cursor_pos++; - n--; - } while (n); - } - } else if (c < 32 && c != '\r') { - return; - } else { - if (!message_add_char(c, cursor_pos)) - return; - cursor_pos++; - if (c == '\r') { - cursor_char = 0; - cursor_line++; - } else { - cursor_char++; - } - } - if (get_nth_line(current_song->message, cursor_line, &ptr) >= LINE_WRAP) { - message_wrap_line(ptr); - } - if (cursor_char >= LINE_WRAP) { - cursor_char = get_nth_line(current_song->message, ++cursor_line, &ptr); - cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); - } + memused_songchanged(); + if (c == '\t') { + /* Find the number of characters until the next tab stop. + * (This is new behaviour; Impulse Tracker just inserts + * eight characters regardless of the cursor position.) */ + n = 8 - cursor_char % 8; + if (cursor_char + n > LINE_WRAP) { + message_insert_char('\r'); + } else { + do { + if (!message_add_char(' ', cursor_pos)) + break; + cursor_char++; + cursor_pos++; + n--; + } while (n); + } + } else if (c < 32 && c != '\r') { + return; + } else { + if (!message_add_char(c, cursor_pos)) + return; + cursor_pos++; + if (c == '\r') { + cursor_char = 0; + cursor_line++; + } else { + cursor_char++; + } + } + if (get_nth_line(current_song->message, cursor_line, &ptr) >= LINE_WRAP) { + message_wrap_line(ptr); + } + if (cursor_char >= LINE_WRAP) { + cursor_char = get_nth_line(current_song->message, ++cursor_line, &ptr); + cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); + } - message_reposition(); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + message_reposition(); + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void message_delete_char(void) { - int len = strlen(current_song->message); - char *ptr; + int len = strlen(current_song->message); + char *ptr; - if (cursor_pos == 0) - return; - memmove(current_song->message + cursor_pos - 1, current_song->message + cursor_pos, - len - cursor_pos + 1); - current_song->message[MAX_MESSAGE] = 0; - cursor_pos--; - if (cursor_char == 0) { - cursor_line--; - cursor_char = get_nth_line(current_song->message, cursor_line, &ptr); - } else { - cursor_char--; - } + if (cursor_pos == 0) + return; + memmove(current_song->message + cursor_pos - 1, current_song->message + cursor_pos, + len - cursor_pos + 1); + current_song->message[MAX_MESSAGE] = 0; + cursor_pos--; + if (cursor_char == 0) { + cursor_line--; + cursor_char = get_nth_line(current_song->message, cursor_line, &ptr); + } else { + cursor_char--; + } - message_reposition(); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + message_reposition(); + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void message_delete_next_char(void) { - int len = strlen(current_song->message); + int len = strlen(current_song->message); - if (cursor_pos == len) - return; - memmove(current_song->message + cursor_pos, current_song->message + cursor_pos + 1, - len - cursor_pos); - current_song->message[MAX_MESSAGE] = 0; + if (cursor_pos == len) + return; + memmove(current_song->message + cursor_pos, current_song->message + cursor_pos + 1, + len - cursor_pos); + current_song->message[MAX_MESSAGE] = 0; - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void message_delete_line(void) { - int len; - int movelen; - char *ptr; - - len = get_nth_line(current_song->message, cursor_line, &ptr); - if (len < 0) - return; - if (ptr[len] == 13 && ptr[len + 1] == 10) - len++; - movelen = (current_song->message + strlen(current_song->message) - ptr); - if (movelen == 0) - return; - memmove(ptr, ptr + len + 1, movelen); - len = get_nth_line(current_song->message, cursor_line, &ptr); - if (cursor_char > len) { - cursor_char = len; - cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); - } - message_reposition(); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + int len; + int movelen; + char *ptr; + + len = get_nth_line(current_song->message, cursor_line, &ptr); + if (len < 0) + return; + if (ptr[len] == 13 && ptr[len + 1] == 10) + len++; + movelen = (current_song->message + strlen(current_song->message) - ptr); + if (movelen == 0) + return; + memmove(ptr, ptr + len + 1, movelen); + len = get_nth_line(current_song->message, cursor_line, &ptr); + if (cursor_char > len) { + cursor_char = len; + cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); + } + message_reposition(); + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void message_clear(UNUSED void *data) { - current_song->message[0] = 0; - memused_songchanged(); - message_set_viewmode(); - status.flags |= SONG_NEEDS_SAVE; + current_song->message[0] = 0; + memused_songchanged(); + message_set_viewmode(); + status.flags |= SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static void prompt_message_clear(void) { - dialog_create(DIALOG_OK_CANCEL, "Clear song message?", message_clear, NULL, 1, NULL); + dialog_create(DIALOG_OK_CANCEL, "Clear song message?", message_clear, NULL, 1, NULL); } /* --------------------------------------------------------------------- */ static int message_handle_key_viewmode(struct key_event * k) { - if (!k->state) { - if (k->mouse == MOUSE_SCROLL_UP) { - top_line -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - top_line += MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_CLICK) { - message_set_editmode(); - return message_handle_key_editmode(k); - } - } - - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - top_line--; - break; - case SDLK_DOWN: - if (k->state) return 0; - top_line++; - break; - case SDLK_PAGEUP: - if (k->state) return 0; - top_line -= 35; - break; - case SDLK_PAGEDOWN: - if (k->state) return 0; - top_line += 35; - break; - case SDLK_HOME: - if (k->state) return 0; - top_line = 0; - break; - case SDLK_END: - if (k->state) return 0; - top_line = get_num_lines(current_song->message) - 34; - break; - case SDLK_t: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) { - message_extfont = !message_extfont; - break; - } - return 1; - case SDLK_RETURN: - if (!k->state) return 0; - message_set_editmode(); - return 1; - default: - return 0; - } + if (k->state == KEY_PRESS) { + if (k->mouse == MOUSE_SCROLL_UP) { + top_line -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + top_line += MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_CLICK) { + message_set_editmode(); + return message_handle_key_editmode(k); + } + } + + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + top_line--; + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + top_line++; + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + top_line -= 35; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + top_line += 35; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + top_line = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + top_line = get_num_lines(current_song->message) - 34; + break; + case SDLK_t: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) { + message_extfont = !message_extfont; + break; + } + return 1; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + message_set_editmode(); + return 1; + default: + return 0; + } - if (top_line < 0) - top_line = 0; + if (top_line < 0) + top_line = 0; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; - return 1; + return 1; } static void _delete_selection(void) { - int len = strlen(current_song->message); - int eat; + int len = strlen(current_song->message); + int eat; - cursor_pos = widgets_message[0].clip_start; - if (cursor_pos > widgets_message[0].clip_end) { - cursor_pos = widgets_message[0].clip_end; - eat = widgets_message[0].clip_start - cursor_pos; - } else { - eat = widgets_message[0].clip_end - cursor_pos; - } - clippy_select(NULL, NULL, 0); - if (cursor_pos == len) - return; - memmove(current_song->message + cursor_pos, current_song->message + cursor_pos + eat + 1, - ((len - cursor_pos) - eat)+1); - current_song->message[MAX_MESSAGE] = 0; - set_absolute_position(current_song->message, cursor_pos, &cursor_line, &cursor_char); - message_reposition(); + cursor_pos = widgets_message[0].clip_start; + if (cursor_pos > widgets_message[0].clip_end) { + cursor_pos = widgets_message[0].clip_end; + eat = widgets_message[0].clip_start - cursor_pos; + } else { + eat = widgets_message[0].clip_end - cursor_pos; + } + clippy_select(NULL, NULL, 0); + if (cursor_pos == len) + return; + memmove(current_song->message + cursor_pos, current_song->message + cursor_pos + eat + 1, + ((len - cursor_pos) - eat)+1); + current_song->message[MAX_MESSAGE] = 0; + set_absolute_position(current_song->message, cursor_pos, &cursor_line, &cursor_char); + message_reposition(); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static int message_handle_key_editmode(struct key_event * k) { - int line_len, num_lines = -1; - int new_cursor_line = cursor_line; - int new_cursor_char = cursor_char; - char *ptr; - int doing_drag = 0; - int clipl, clipr, cp; - - if (k->mouse == MOUSE_SCROLL_UP) { - if (k->state) return 0; - new_cursor_line -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - if (k->state) return 0; - new_cursor_line += MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_CLICK && k->mouse_button == 2) { - if (k->state) status.flags |= CLIPPY_PASTE_SELECTION; - return 1; - } else if (k->mouse == MOUSE_CLICK) { - if (k->x >= 2 && k->x <= 77 && k->y >= 13 && k->y <= 47) { - new_cursor_line = (k->y - 13) + top_line; - new_cursor_char = (k->x - 2); - if (k->sx != k->x || k->sy != k->y) { - /* yay drag operation */ - cp = get_absolute_position(current_song->message, (k->sy-13)+top_line, - (k->sx-2)); - widgets_message[0].clip_start = cp; - doing_drag = 1; - } - } - } - - line_len = get_nth_line(current_song->message, cursor_line, &ptr); - - - switch (k->sym) { - case SDLK_UP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_line--; - break; - case SDLK_DOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_line++; - break; - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_char--; - break; - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_char++; - break; - case SDLK_PAGEUP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_line -= 35; - break; - case SDLK_PAGEDOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_line += 35; - break; - case SDLK_HOME: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) - new_cursor_line = 0; - else - new_cursor_char = 0; - break; - case SDLK_END: - if (k->state) return 1; - if (k->mod & KMOD_CTRL) { - num_lines = get_num_lines(current_song->message); - new_cursor_line = num_lines; - } else { - new_cursor_char = line_len; - } - break; - case SDLK_ESCAPE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - message_set_viewmode(); - memused_songchanged(); - return 1; - case SDLK_BACKSPACE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { - _delete_selection(); - } else { - message_delete_char(); - } - return 1; - case SDLK_DELETE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { - _delete_selection(); - } else { - message_delete_next_char(); - } - return 1; - default: - if (k->mod & KMOD_CTRL) { - if (k->state) return 1; - if (k->sym == SDLK_t) { - message_extfont = !message_extfont; - break; - } else if (k->sym == SDLK_y) { - clippy_select(NULL, NULL, 0); - message_delete_line(); - break; - } - } else if (k->mod & KMOD_ALT) { - if (k->state) return 1; - if (k->sym == SDLK_c) { - prompt_message_clear(); - return 1; - } - } else if (!k->mouse) { - if (k->unicode == '\r' || k->unicode == '\t' - || k->unicode >= 32) { - if (k->state) return 1; - if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { - _delete_selection(); - } - if (k->mod & (KMOD_SHIFT|KMOD_CAPS)) { - message_insert_char(toupper((unsigned int)k->unicode)); - } else { - message_insert_char(k->unicode); - } - return 1; - } - return 0; - } - - if (k->mouse != MOUSE_CLICK) - return 0; - - if (k->state) return 1; - if (!doing_drag) { - clippy_select(NULL, NULL, 0); - } - } - - if (new_cursor_line != cursor_line) { - if (num_lines == -1) - num_lines = get_num_lines(current_song->message); - - if (new_cursor_line < 0) - new_cursor_line = 0; - else if (new_cursor_line > num_lines) - new_cursor_line = num_lines; - - /* make sure the cursor doesn't go past the new eol */ - line_len = get_nth_line(current_song->message, new_cursor_line, &ptr); - if (new_cursor_char > line_len) - new_cursor_char = line_len; - - cursor_char = new_cursor_char; - cursor_line = new_cursor_line; - } else if (new_cursor_char != cursor_char) { - /* we say "else" here ESPECIALLY because the mouse can only come - in the top section - not because it's some clever optimization */ - if (new_cursor_char < 0) { - if (cursor_line == 0) { - new_cursor_char = cursor_char; - } else { - cursor_line--; - new_cursor_char = - get_nth_line(current_song->message, cursor_line, &ptr); - } - - } else if (new_cursor_char > - get_nth_line(current_song->message, cursor_line, &ptr)) { - if (cursor_line == get_num_lines(current_song->message)) { - new_cursor_char = cursor_char; - } else { - cursor_line++; - new_cursor_char = 0; - } - } - cursor_char = new_cursor_char; - } - - message_reposition(); - cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); - - if (doing_drag) { - widgets_message[0].clip_end = cursor_pos; - - clipl = widgets_message[0].clip_start; - clipr = widgets_message[0].clip_end; - if (clipl > clipr) { - cp = clipl; - clipl = clipr; - clipr = cp; - } - clippy_select(widgets_message, (current_song->message+clipl), clipr-clipl); - } + int line_len, num_lines = -1; + int new_cursor_line = cursor_line; + int new_cursor_char = cursor_char; + char *ptr; + int doing_drag = 0; + int clipl, clipr, cp; + + if (k->mouse == MOUSE_SCROLL_UP) { + if (k->state == KEY_RELEASE) + return 0; + new_cursor_line -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + if (k->state == KEY_RELEASE) + return 0; + new_cursor_line += MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_CLICK && k->mouse_button == 2) { + if (k->state == KEY_RELEASE) + status.flags |= CLIPPY_PASTE_SELECTION; + return 1; + } else if (k->mouse == MOUSE_CLICK) { + if (k->x >= 2 && k->x <= 77 && k->y >= 13 && k->y <= 47) { + new_cursor_line = (k->y - 13) + top_line; + new_cursor_char = (k->x - 2); + if (k->sx != k->x || k->sy != k->y) { + /* yay drag operation */ + cp = get_absolute_position(current_song->message, (k->sy-13)+top_line, + (k->sx-2)); + widgets_message[0].clip_start = cp; + doing_drag = 1; + } + } + } + + line_len = get_nth_line(current_song->message, cursor_line, &ptr); + + + switch (k->sym) { + case SDLK_UP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_line--; + break; + case SDLK_DOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_line++; + break; + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_char--; + break; + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_char++; + break; + case SDLK_PAGEUP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_line -= 35; + break; + case SDLK_PAGEDOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_line += 35; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) + new_cursor_line = 0; + else + new_cursor_char = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_CTRL) { + num_lines = get_num_lines(current_song->message); + new_cursor_line = num_lines; + } else { + new_cursor_char = line_len; + } + break; + case SDLK_ESCAPE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + message_set_viewmode(); + memused_songchanged(); + return 1; + case SDLK_BACKSPACE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { + _delete_selection(); + } else { + message_delete_char(); + } + return 1; + case SDLK_DELETE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { + _delete_selection(); + } else { + message_delete_next_char(); + } + return 1; + default: + if (k->mod & KMOD_CTRL) { + if (k->state == KEY_RELEASE) + return 1; + if (k->sym == SDLK_t) { + message_extfont = !message_extfont; + break; + } else if (k->sym == SDLK_y) { + clippy_select(NULL, NULL, 0); + message_delete_line(); + break; + } + } else if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + if (k->sym == SDLK_c) { + prompt_message_clear(); + return 1; + } + } else if (k->mouse == MOUSE_NONE) { + if (k->unicode == '\r' || k->unicode == '\t' + || k->unicode >= 32) { + if (k->state == KEY_RELEASE) + return 1; + if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { + _delete_selection(); + } + if (k->mod & (KMOD_SHIFT|KMOD_CAPS)) { + message_insert_char(toupper((unsigned int)k->unicode)); + } else { + message_insert_char(k->unicode); + } + return 1; + } + return 0; + } + + if (k->mouse != MOUSE_CLICK) + return 0; + + if (k->state == KEY_RELEASE) + return 1; + if (!doing_drag) { + clippy_select(NULL, NULL, 0); + } + } + + if (new_cursor_line != cursor_line) { + if (num_lines == -1) + num_lines = get_num_lines(current_song->message); + + if (new_cursor_line < 0) + new_cursor_line = 0; + else if (new_cursor_line > num_lines) + new_cursor_line = num_lines; + + /* make sure the cursor doesn't go past the new eol */ + line_len = get_nth_line(current_song->message, new_cursor_line, &ptr); + if (new_cursor_char > line_len) + new_cursor_char = line_len; + + cursor_char = new_cursor_char; + cursor_line = new_cursor_line; + } else if (new_cursor_char != cursor_char) { + /* we say "else" here ESPECIALLY because the mouse can only come + in the top section - not because it's some clever optimization */ + if (new_cursor_char < 0) { + if (cursor_line == 0) { + new_cursor_char = cursor_char; + } else { + cursor_line--; + new_cursor_char = + get_nth_line(current_song->message, cursor_line, &ptr); + } + + } else if (new_cursor_char > + get_nth_line(current_song->message, cursor_line, &ptr)) { + if (cursor_line == get_num_lines(current_song->message)) { + new_cursor_char = cursor_char; + } else { + cursor_line++; + new_cursor_char = 0; + } + } + cursor_char = new_cursor_char; + } + + message_reposition(); + cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); + + if (doing_drag) { + widgets_message[0].clip_end = cursor_pos; + + clipl = widgets_message[0].clip_start; + clipr = widgets_message[0].clip_end; + if (clipl > clipr) { + cp = clipl; + clipl = clipr; + clipr = cp; + } + clippy_select(widgets_message, (current_song->message+clipl), clipr-clipl); + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; - return 1; + return 1; } /* --------------------------------------------------------------------- */ static void message_draw_const(void) { - draw_box(1, 12, 78, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(1, 12, 78, 48, BOX_THICK | BOX_INNER | BOX_INSET); } static void song_changed_cb(void) { - char *line, *prevline; - int len; + char *line, *prevline; + int len; - edit_mode = 0; - widgets_message[0].accept_text = 0; - widgets_message[0].d.other.handle_key = message_handle_key_viewmode; - top_line = 0; - - len = get_nth_line(current_song->message, 0, &line); - while (len >= 0) { - if (len > LINE_WRAP) - message_wrap_line(line); - prevline = line; - len = get_nth_line(prevline, 1, &line); - } + edit_mode = 0; + widgets_message[0].accept_text = 0; + widgets_message[0].d.other.handle_key = message_handle_key_viewmode; + top_line = 0; + + len = get_nth_line(current_song->message, 0, &line); + while (len >= 0) { + if (len > LINE_WRAP) + message_wrap_line(line); + prevline = line; + len = get_nth_line(prevline, 1, &line); + } - if (status.current_page == PAGE_MESSAGE) - status.flags |= NEED_UPDATE; + if (status.current_page == PAGE_MESSAGE) + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ void message_load_page(struct page *page) { - page->title = "Message Editor (Shift-F9)"; - page->draw_const = message_draw_const; - page->song_changed_cb = song_changed_cb; - page->total_widgets = 1; - page->widgets = widgets_message; - page->help_index = HELP_MESSAGE_EDITOR; + page->title = "Message Editor (Shift-F9)"; + page->draw_const = message_draw_const; + page->song_changed_cb = song_changed_cb; + page->total_widgets = 1; + page->widgets = widgets_message; + page->help_index = HELP_MESSAGE_EDITOR; - create_other(widgets_message + 0, 0, message_handle_key_viewmode, message_draw); - widgets_message[0].accept_text = edit_mode; + create_other(widgets_message + 0, 0, message_handle_key_viewmode, message_draw); + widgets_message[0].accept_text = edit_mode; } diff -Nru schism-0+20110101/schism/page_midi.c schism-20160521/schism/page_midi.c --- schism-0+20110101/schism/page_midi.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_midi.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -41,305 +41,309 @@ static void midi_output_config(void) { - set_page(PAGE_MIDI_OUTPUT); + set_page(PAGE_MIDI_OUTPUT); } static void update_ip_ports(void) { - if (widgets_midi[12].d.thumbbar.value > 0 && (status.flags & NO_NETWORK)) { - status_text_flash("Networking is disabled"); - widgets_midi[12].d.thumbbar.value = 0; - } else { - ip_midi_setports(widgets_midi[12].d.thumbbar.value); - } + if (widgets_midi[12].d.thumbbar.value > 0 && (status.flags & NO_NETWORK)) { + status_text_flash("Networking is disabled"); + widgets_midi[12].d.thumbbar.value = 0; + } else { + ip_midi_setports(widgets_midi[12].d.thumbbar.value); + } - last_midi_poll = 0; - status.flags |= NEED_UPDATE; + last_midi_poll = 0; + status.flags |= NEED_UPDATE; } static void update_midi_values(void) { - midi_flags = 0 - | (widgets_midi[1].d.toggle.state ? MIDI_TICK_QUANTIZE : 0) - | (widgets_midi[2].d.toggle.state ? MIDI_BASE_PROGRAM1 : 0) - | (widgets_midi[3].d.toggle.state ? MIDI_RECORD_NOTEOFF : 0) - | (widgets_midi[4].d.toggle.state ? MIDI_RECORD_VELOCITY : 0) - | (widgets_midi[5].d.toggle.state ? MIDI_RECORD_AFTERTOUCH : 0) - | (widgets_midi[6].d.toggle.state ? MIDI_CUT_NOTE_OFF : 0) - | (widgets_midi[9].d.toggle.state ? MIDI_PITCHBEND : 0) - ; - if (widgets_midi[11].d.toggle.state) - current_song->flags |= SONG_EMBEDMIDICFG; - else - current_song->flags &= ~SONG_EMBEDMIDICFG; - - midi_amplification = widgets_midi[7].d.thumbbar.value; - midi_c5note = widgets_midi[8].d.thumbbar.value; - midi_pitch_depth = widgets_midi[10].d.thumbbar.value; + midi_flags = 0 + | (widgets_midi[1].d.toggle.state ? MIDI_TICK_QUANTIZE : 0) + | (widgets_midi[2].d.toggle.state ? MIDI_BASE_PROGRAM1 : 0) + | (widgets_midi[3].d.toggle.state ? MIDI_RECORD_NOTEOFF : 0) + | (widgets_midi[4].d.toggle.state ? MIDI_RECORD_VELOCITY : 0) + | (widgets_midi[5].d.toggle.state ? MIDI_RECORD_AFTERTOUCH : 0) + | (widgets_midi[6].d.toggle.state ? MIDI_CUT_NOTE_OFF : 0) + | (widgets_midi[9].d.toggle.state ? MIDI_PITCHBEND : 0) + ; + if (widgets_midi[11].d.toggle.state) + current_song->flags |= SONG_EMBEDMIDICFG; + else + current_song->flags &= ~SONG_EMBEDMIDICFG; + + midi_amplification = widgets_midi[7].d.thumbbar.value; + midi_c5note = widgets_midi[8].d.thumbbar.value; + midi_pitch_depth = widgets_midi[10].d.thumbbar.value; } static void get_midi_config(void) { - widgets_midi[1].d.toggle.state = !!(midi_flags & MIDI_TICK_QUANTIZE); - widgets_midi[2].d.toggle.state = !!(midi_flags & MIDI_BASE_PROGRAM1); - widgets_midi[3].d.toggle.state = !!(midi_flags & MIDI_RECORD_NOTEOFF); - widgets_midi[4].d.toggle.state = !!(midi_flags & MIDI_RECORD_VELOCITY); - widgets_midi[5].d.toggle.state = !!(midi_flags & MIDI_RECORD_AFTERTOUCH); - widgets_midi[6].d.toggle.state = !!(midi_flags & MIDI_CUT_NOTE_OFF); - widgets_midi[9].d.toggle.state = !!(midi_flags & MIDI_PITCHBEND); - widgets_midi[11].d.toggle.state = !!(current_song->flags & SONG_EMBEDMIDICFG); - - widgets_midi[7].d.thumbbar.value = midi_amplification; - widgets_midi[8].d.thumbbar.value = midi_c5note; - widgets_midi[10].d.thumbbar.value = midi_pitch_depth; - widgets_midi[12].d.thumbbar.value = ip_midi_getports(); + widgets_midi[1].d.toggle.state = !!(midi_flags & MIDI_TICK_QUANTIZE); + widgets_midi[2].d.toggle.state = !!(midi_flags & MIDI_BASE_PROGRAM1); + widgets_midi[3].d.toggle.state = !!(midi_flags & MIDI_RECORD_NOTEOFF); + widgets_midi[4].d.toggle.state = !!(midi_flags & MIDI_RECORD_VELOCITY); + widgets_midi[5].d.toggle.state = !!(midi_flags & MIDI_RECORD_AFTERTOUCH); + widgets_midi[6].d.toggle.state = !!(midi_flags & MIDI_CUT_NOTE_OFF); + widgets_midi[9].d.toggle.state = !!(midi_flags & MIDI_PITCHBEND); + widgets_midi[11].d.toggle.state = !!(current_song->flags & SONG_EMBEDMIDICFG); + + widgets_midi[7].d.thumbbar.value = midi_amplification; + widgets_midi[8].d.thumbbar.value = midi_c5note; + widgets_midi[10].d.thumbbar.value = midi_pitch_depth; + widgets_midi[12].d.thumbbar.value = ip_midi_getports(); } static void toggle_port(void) { - struct midi_port *p; - p = midi_engine_port(current_port, NULL); - if (p) { - status.flags |= NEED_UPDATE; - - if (p->disable) if (!p->disable(p)) return; - switch (p->io) { - case 0: - if (p->iocap & MIDI_INPUT) p->io = MIDI_INPUT; - else if (p->iocap & MIDI_OUTPUT) p->io = MIDI_OUTPUT; - break; - case MIDI_INPUT: - if (p->iocap & MIDI_OUTPUT) p->io = MIDI_OUTPUT; - else p->io = 0; - break; - case MIDI_OUTPUT: - if (p->iocap & MIDI_INPUT) p->io |= MIDI_INPUT; - else p->io = 0; - break; - case MIDI_INPUT|MIDI_OUTPUT: - p->io = 0; - break; - }; - - if (p->enable) { - if (!p->enable(p)) { - p->io = 0; - return; - } - } - } + struct midi_port *p; + p = midi_engine_port(current_port, NULL); + if (p) { + status.flags |= NEED_UPDATE; + + if (p->disable) if (!p->disable(p)) return; + switch (p->io) { + case 0: + if (p->iocap & MIDI_INPUT) p->io = MIDI_INPUT; + else if (p->iocap & MIDI_OUTPUT) p->io = MIDI_OUTPUT; + break; + case MIDI_INPUT: + if (p->iocap & MIDI_OUTPUT) p->io = MIDI_OUTPUT; + else p->io = 0; + break; + case MIDI_OUTPUT: + if (p->iocap & MIDI_INPUT) p->io |= MIDI_INPUT; + else p->io = 0; + break; + case MIDI_INPUT|MIDI_OUTPUT: + p->io = 0; + break; + }; + + if (p->enable) { + if (!p->enable(p)) { + p->io = 0; + return; + } + } + } } static int midi_page_handle_key(struct key_event * k) { - int new_port = current_port; - int pos; + int new_port = current_port; + int pos; - if (k->mouse == MOUSE_SCROLL_UP) { - new_port -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_port += MOUSE_SCROLL_LINES; - } else if (k->mouse) { - if (k->x >= 3 && k->x <= 11 && k->y >= 15 && k->y <= 27) { - if (k->mouse == MOUSE_DBLCLICK) { - if (!k->state) return 0; - toggle_port(); - return 1; - } - new_port = top_midi_port + (k->y - 15); - } else { - return 0; - } - } - - switch (k->sym) { - case SDLK_SPACE: - if (!k->state) return 1; - toggle_port(); - return 1; - case SDLK_PAGEUP: - new_port -= 13; - if (new_port < 0) new_port = 0; - break; - case SDLK_PAGEDOWN: - new_port += 13; - if (new_port >= midi_engine_port_count()) { - new_port = midi_engine_port_count() - 1; - } - break; - case SDLK_HOME: - new_port = 0; - break; - case SDLK_END: - new_port = midi_engine_port_count() - 1; - break; - case SDLK_UP: - new_port--; - break; - case SDLK_DOWN: - new_port++; - break; - case SDLK_TAB: - if (k->state) return 1; - change_focus_to(1); - status.flags |= NEED_UPDATE; - return 1; - default: - if (!k->mouse) return 0; - break; - }; - if (k->state) return 0; - - if (new_port != current_port) { - if (new_port < 0 || new_port >= midi_engine_port_count()) { - new_port = current_port; - if (k->sym == SDLK_DOWN) { - change_focus_to(1); - } - } - - current_port = new_port; - if (current_port < top_midi_port) - top_midi_port = current_port; - - pos = current_port - top_midi_port; - if (pos > 12) top_midi_port = current_port - 12; - if (top_midi_port < 0) top_midi_port = 0; + if (k->mouse == MOUSE_SCROLL_UP) { + new_port -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_port += MOUSE_SCROLL_LINES; + } else if (k->mouse) { + if (k->x >= 3 && k->x <= 11 && k->y >= 15 && k->y <= 27) { + if (k->mouse == MOUSE_DBLCLICK) { + if (k->state == KEY_PRESS) + return 0; + toggle_port(); + return 1; + } + new_port = top_midi_port + (k->y - 15); + } else { + return 0; + } + } + + switch (k->sym) { + case SDLK_SPACE: + if (k->state == KEY_PRESS) + return 1; + toggle_port(); + return 1; + case SDLK_PAGEUP: + new_port -= 13; + if (new_port < 0) new_port = 0; + break; + case SDLK_PAGEDOWN: + new_port += 13; + if (new_port >= midi_engine_port_count()) { + new_port = midi_engine_port_count() - 1; + } + break; + case SDLK_HOME: + new_port = 0; + break; + case SDLK_END: + new_port = midi_engine_port_count() - 1; + break; + case SDLK_UP: + new_port--; + break; + case SDLK_DOWN: + new_port++; + break; + case SDLK_TAB: + if (k->state == KEY_RELEASE) + return 1; + change_focus_to(1); + status.flags |= NEED_UPDATE; + return 1; + default: + if (!k->mouse) return 0; + break; + }; + if (k->state == KEY_RELEASE) + return 0; + + if (new_port != current_port) { + if (new_port < 0 || new_port >= midi_engine_port_count()) { + new_port = current_port; + if (k->sym == SDLK_DOWN) { + change_focus_to(1); + } + } + + current_port = new_port; + if (current_port < top_midi_port) + top_midi_port = current_port; + + pos = current_port - top_midi_port; + if (pos > 12) top_midi_port = current_port - 12; + if (top_midi_port < 0) top_midi_port = 0; - status.flags |= NEED_UPDATE; - } + status.flags |= NEED_UPDATE; + } - return 1; + return 1; } static void midi_page_redraw(void) { - draw_text( "Tick quantize", 6, 30, 0, 2); - draw_text( "Base Program 1", 5, 31, 0, 2); - draw_text( "Record Note-Off", 4, 32, 0, 2); - draw_text( "Record Velocity", 4, 33, 0, 2); - draw_text( "Record Aftertouch", 2, 34, 0, 2); - draw_text( "Cut note off", 7, 35, 0, 2); - - draw_fill_chars(23, 30, 24, 35, 0); - draw_box(19,29,25,36, BOX_THIN|BOX_INNER|BOX_INSET); - - draw_box(52,29,73,32, BOX_THIN|BOX_INNER|BOX_INSET); - - draw_fill_chars(56, 34, 72, 34, 0); - draw_box(52,33,73,36, BOX_THIN|BOX_INNER|BOX_INSET); - - draw_fill_chars(56, 38, 72, 38, 0); - draw_box(52,37,73,39, BOX_THIN|BOX_INNER|BOX_INSET); - - draw_text( "Amplification", 39, 30, 0, 2); - draw_text( "C-5 Note-value", 38, 31, 0, 2); - draw_text("Output MIDI pitch", 35, 34, 0, 2); - draw_text("Pitch wheel depth", 35, 35, 0, 2); - draw_text( "Embed MIDI data", 37, 38, 0, 2); + draw_text( "Tick quantize", 6, 30, 0, 2); + draw_text( "Base Program 1", 5, 31, 0, 2); + draw_text( "Record Note-Off", 4, 32, 0, 2); + draw_text( "Record Velocity", 4, 33, 0, 2); + draw_text( "Record Aftertouch", 2, 34, 0, 2); + draw_text( "Cut note off", 7, 35, 0, 2); + + draw_fill_chars(23, 30, 24, 35, 0); + draw_box(19,29,25,36, BOX_THIN|BOX_INNER|BOX_INSET); + + draw_box(52,29,73,32, BOX_THIN|BOX_INNER|BOX_INSET); + + draw_fill_chars(56, 34, 72, 34, 0); + draw_box(52,33,73,36, BOX_THIN|BOX_INNER|BOX_INSET); + + draw_fill_chars(56, 38, 72, 38, 0); + draw_box(52,37,73,39, BOX_THIN|BOX_INNER|BOX_INSET); + + draw_text( "Amplification", 39, 30, 0, 2); + draw_text( "C-5 Note-value", 38, 31, 0, 2); + draw_text("Output MIDI pitch", 35, 34, 0, 2); + draw_text("Pitch wheel depth", 35, 35, 0, 2); + draw_text( "Embed MIDI data", 37, 38, 0, 2); - draw_text( "IP MIDI ports", 39, 41, 0, 2); - draw_box(52,40,73,42, BOX_THIN|BOX_INNER|BOX_INSET); + draw_text( "IP MIDI ports", 39, 41, 0, 2); + draw_box(52,40,73,42, BOX_THIN|BOX_INNER|BOX_INSET); } static void midi_page_draw_portlist(void) { - struct midi_port *p; - const char *name, *state; - char buffer[64]; - int i, n, ct, fg, bg; - unsigned long j; - time_t now; - - draw_fill_chars(3, 15, 76, 28, 0); - draw_text("Midi ports:", 2, 13, 0, 2); - draw_box(2,14,77,28, BOX_THIN|BOX_INNER|BOX_INSET); - - time(&now); - if ((now - last_midi_poll) > 10) { - last_midi_poll = now; - midi_engine_poll_ports(); - } - - ct = midi_engine_port_count(); - for (i = 0; i < 13; i++) { - draw_char(168, 12, i + 15, 2, 0); - - if (top_midi_port + i >= ct) - continue; /* err */ - - p = midi_engine_port(top_midi_port + i, &name); - if (current_port == top_midi_port + i - && ACTIVE_WIDGET.type == WIDGET_OTHER) { - fg = 0; - bg = 3; - } else { - fg = 5; - bg = 0; - } - draw_text_len(name, 64, 13, 15+i, 5, 0); - - /* portability: should use difftime */ - if (status.flags & MIDI_EVENT_CHANGED - && (time(NULL) - status.last_midi_time) < 3 - && ((!status.last_midi_port && p->io & MIDI_OUTPUT) - || p == (struct midi_port *) status.last_midi_port)) { - for (j = n = 0; j < 21 && j < status.last_midi_len; j++) { /* 21 is approx 64/3 */ - sprintf(buffer + n, "%02X ", status.last_midi_event[j]); - n += 3; - } - draw_text(buffer, 77 - strlen(buffer), 15+i, - status.last_midi_port ? 4 : 10, 0); - } - - switch (p->io) { - case 0: state = "Disabled "; break; - case MIDI_INPUT: state = " Input "; break; - case MIDI_OUTPUT: state = " Output "; break; - case MIDI_INPUT | MIDI_OUTPUT: state = " Duplex "; break; - default: state = " Enabled?"; break; - } - draw_text(state, 3, 15 + i, fg, bg); - } + struct midi_port *p; + const char *name, *state; + char buffer[64]; + int i, n, ct, fg, bg; + unsigned long j; + time_t now; + + draw_fill_chars(3, 15, 76, 28, 0); + draw_text("Midi ports:", 2, 13, 0, 2); + draw_box(2,14,77,28, BOX_THIN|BOX_INNER|BOX_INSET); + + time(&now); + if ((now - last_midi_poll) > 10) { + last_midi_poll = now; + midi_engine_poll_ports(); + } + + ct = midi_engine_port_count(); + for (i = 0; i < 13; i++) { + draw_char(168, 12, i + 15, 2, 0); + + if (top_midi_port + i >= ct) + continue; /* err */ + + p = midi_engine_port(top_midi_port + i, &name); + if (current_port == top_midi_port + i + && ACTIVE_WIDGET.type == WIDGET_OTHER) { + fg = 0; + bg = 3; + } else { + fg = 5; + bg = 0; + } + draw_text_len(name, 64, 13, 15+i, 5, 0); + + /* portability: should use difftime */ + if (status.flags & MIDI_EVENT_CHANGED + && (time(NULL) - status.last_midi_time) < 3 + && ((!status.last_midi_port && p->io & MIDI_OUTPUT) + || p == (struct midi_port *) status.last_midi_port)) { + for (j = n = 0; j < 21 && j < status.last_midi_len; j++) { /* 21 is approx 64/3 */ + sprintf(buffer + n, "%02X ", status.last_midi_event[j]); + n += 3; + } + draw_text(buffer, 77 - strlen(buffer), 15+i, + status.last_midi_port ? 4 : 10, 0); + } + + switch (p->io) { + case 0: state = "Disabled "; break; + case MIDI_INPUT: state = " Input "; break; + case MIDI_OUTPUT: state = " Output "; break; + case MIDI_INPUT | MIDI_OUTPUT: state = " Duplex "; break; + default: state = " Enabled?"; break; + } + draw_text(state, 3, 15 + i, fg, bg); + } } /* --------------------------------------------------------------------- */ void midi_load_page(struct page *page) { - page->title = "Midi Screen (Shift-F1)"; - page->draw_const = midi_page_redraw; - page->song_changed_cb = NULL; - page->predraw_hook = NULL; - page->playback_update = NULL; - page->handle_key = NULL; - page->set_page = get_midi_config; - page->total_widgets = 15; - page->widgets = widgets_midi; - page->help_index = HELP_GLOBAL; - - create_other(widgets_midi + 0, 0, midi_page_handle_key, midi_page_draw_portlist); - widgets_midi[0].x = 2; - widgets_midi[0].y = 14; - widgets_midi[0].width = 75; - widgets_midi[0].height = 15; - - create_toggle(widgets_midi + 1, 20, 30, 0, 2, 7, 7, 7, update_midi_values); - create_toggle(widgets_midi + 2, 20, 31, 1, 3, 8, 8, 8, update_midi_values); - create_toggle(widgets_midi + 3, 20, 32, 2, 4, 8, 8, 8, update_midi_values); - create_toggle(widgets_midi + 4, 20, 33, 3, 5, 9, 9, 9, update_midi_values); - create_toggle(widgets_midi + 5, 20, 34, 4, 6, 9, 9, 9, update_midi_values); - create_toggle(widgets_midi + 6, 20, 35, 5, 13, 10, 10, 10, update_midi_values); - create_thumbbar(widgets_midi + 7, 53, 30, 20, 0, 8, 1, update_midi_values, 0, 200); - create_thumbbar(widgets_midi + 8, 53, 31, 20, 7, 9, 2, update_midi_values, 0, 127); - create_toggle(widgets_midi + 9, 53, 34, 8, 10, 5, 5, 5, update_midi_values); - create_thumbbar(widgets_midi + 10, 53, 35, 20, 9, 11, 6, update_midi_values, 0, 48); - create_toggle(widgets_midi + 11, 53, 38, 10, 12, 13, 13, 13, update_midi_values); - create_thumbbar(widgets_midi + 12, 53, 41, 20, 11, 12, 13, update_ip_ports, 0, 128); - create_button(widgets_midi + 13, 2, 41, 27, 6, 14, 12, 12, 12, - midi_output_config, "MIDI Output Configuration", 2); - create_button(widgets_midi + 14, 2, 44, 27, 13, 14, 12, 12, 12, - cfg_midipage_save, "Save Output Configuration", 2); + page->title = "Midi Screen (Shift-F1)"; + page->draw_const = midi_page_redraw; + page->song_changed_cb = NULL; + page->predraw_hook = NULL; + page->playback_update = NULL; + page->handle_key = NULL; + page->set_page = get_midi_config; + page->total_widgets = 15; + page->widgets = widgets_midi; + page->help_index = HELP_GLOBAL; + + create_other(widgets_midi + 0, 0, midi_page_handle_key, midi_page_draw_portlist); + widgets_midi[0].x = 2; + widgets_midi[0].y = 14; + widgets_midi[0].width = 75; + widgets_midi[0].height = 15; + + create_toggle(widgets_midi + 1, 20, 30, 0, 2, 7, 7, 7, update_midi_values); + create_toggle(widgets_midi + 2, 20, 31, 1, 3, 8, 8, 8, update_midi_values); + create_toggle(widgets_midi + 3, 20, 32, 2, 4, 8, 8, 8, update_midi_values); + create_toggle(widgets_midi + 4, 20, 33, 3, 5, 9, 9, 9, update_midi_values); + create_toggle(widgets_midi + 5, 20, 34, 4, 6, 9, 9, 9, update_midi_values); + create_toggle(widgets_midi + 6, 20, 35, 5, 13, 10, 10, 10, update_midi_values); + create_thumbbar(widgets_midi + 7, 53, 30, 20, 0, 8, 1, update_midi_values, 0, 200); + create_thumbbar(widgets_midi + 8, 53, 31, 20, 7, 9, 2, update_midi_values, 0, 127); + create_toggle(widgets_midi + 9, 53, 34, 8, 10, 5, 5, 5, update_midi_values); + create_thumbbar(widgets_midi + 10, 53, 35, 20, 9, 11, 6, update_midi_values, 0, 48); + create_toggle(widgets_midi + 11, 53, 38, 10, 12, 13, 13, 13, update_midi_values); + create_thumbbar(widgets_midi + 12, 53, 41, 20, 11, 12, 13, update_ip_ports, 0, 128); + create_button(widgets_midi + 13, 2, 41, 27, 6, 14, 12, 12, 12, + midi_output_config, "MIDI Output Configuration", 2); + create_button(widgets_midi + 14, 2, 44, 27, 13, 14, 12, 12, 12, + cfg_midipage_save, "Save Output Configuration", 2); } diff -Nru schism-0+20110101/schism/page_midiout.c schism-20160521/schism/page_midiout.c --- schism-0+20110101/schism/page_midiout.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_midiout.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -38,136 +38,140 @@ static void midiout_draw_const(void) { - char buf[4] = "SFx"; - int i; + char buf[4] = "SFx"; + int i; - draw_text( "MIDI Start", 6, 13, 0, 2); - draw_text( "MIDI Stop", 7, 14, 0, 2); - draw_text( "MIDI Tick", 7, 15, 0, 2); - draw_text( "Note On", 9, 16, 0, 2); - draw_text( "Note Off", 8, 17, 0, 2); - draw_text( "Change Volume", 3, 18, 0, 2); - draw_text( "Change Pan", 6, 19, 0, 2); - draw_text( "Bank Select", 5, 20, 0, 2); - draw_text("Program Change", 2, 21, 0, 2); - - draw_text( "Macro SF0", 5, 24, 0, 2); - draw_text( "Setup SF1", 5, 25, 0, 2); - - for (i = 2; i < 16; i++) { - buf[2] = hexdigits[i]; - draw_text(buf, 13, i + 24, 0, 2); - } - - draw_box(16, 12, 60, 22, BOX_THIN|BOX_INNER|BOX_INSET); - draw_box(16, 23, 60, 40, BOX_THIN|BOX_INNER|BOX_INSET); - draw_box(16, 41, 60, 49, BOX_THIN|BOX_INNER|BOX_INSET); - - for (i = 0; i < 7; i++) { - sprintf(buf, "Z%02X", i + zxx_top + 0x80); - draw_text(buf, 13, i + 42, 0, 2); - } + draw_text( "MIDI Start", 6, 13, 0, 2); + draw_text( "MIDI Stop", 7, 14, 0, 2); + draw_text( "MIDI Tick", 7, 15, 0, 2); + draw_text( "Note On", 9, 16, 0, 2); + draw_text( "Note Off", 8, 17, 0, 2); + draw_text( "Change Volume", 3, 18, 0, 2); + draw_text( "Change Pan", 6, 19, 0, 2); + draw_text( "Bank Select", 5, 20, 0, 2); + draw_text("Program Change", 2, 21, 0, 2); + + draw_text( "Macro SF0", 5, 24, 0, 2); + draw_text( "Setup SF1", 5, 25, 0, 2); + + for (i = 2; i < 16; i++) { + buf[2] = hexdigits[i]; + draw_text(buf, 13, i + 24, 0, 2); + } + + draw_box(16, 12, 60, 22, BOX_THIN|BOX_INNER|BOX_INSET); + draw_box(16, 23, 60, 40, BOX_THIN|BOX_INNER|BOX_INSET); + draw_box(16, 41, 60, 49, BOX_THIN|BOX_INNER|BOX_INSET); + + for (i = 0; i < 7; i++) { + sprintf(buf, "Z%02X", i + zxx_top + 0x80); + draw_text(buf, 13, i + 42, 0, 2); + } } static void copy_out(void) { - song_lock_audio(); - memcpy(¤t_song->midi_config, &editcfg, sizeof(midi_config_t)); - song_unlock_audio(); + song_lock_audio(); + memcpy(¤t_song->midi_config, &editcfg, sizeof(midi_config_t)); + song_unlock_audio(); } static void copy_in(void) { - song_lock_audio(); - memcpy(&editcfg, ¤t_song->midi_config, sizeof(midi_config_t)); - song_unlock_audio(); + song_lock_audio(); + memcpy(&editcfg, ¤t_song->midi_config, sizeof(midi_config_t)); + song_unlock_audio(); } static void zxx_setpos(int pos) { - int i; + int i; - /* 128 items, scrolled on 7 lines */ - pos = CLAMP(pos, 0, 128 - 7); - if (zxx_top == pos) - return; - zxx_top = pos; - for (i = 0; i < 7; i++) - widgets_midiout[25 + i].d.textentry.text = editcfg.zxx[zxx_top + i]; + /* 128 items, scrolled on 7 lines */ + pos = CLAMP(pos, 0, 128 - 7); + if (zxx_top == pos) + return; + zxx_top = pos; + for (i = 0; i < 7; i++) + widgets_midiout[25 + i].d.textentry.text = editcfg.zxx[zxx_top + i]; - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static int pre_handle_key(struct key_event *k) { - if (*selected_widget == 25 && k->sym == SDLK_UP) { - /* scroll up */ - if (k->state) return 1; - if (zxx_top == 0) - return 0; /* let the normal key handler catch it and change focus */ - zxx_setpos(zxx_top - 1); - return 1; - } - if (*selected_widget == 31 && k->sym == SDLK_DOWN) { - /* scroll down */ - if (k->state) return 1; - zxx_setpos(zxx_top + 1); - return 1; - } - if ((*selected_widget) >= 25) { - switch (k->sym) { - case SDLK_PAGEUP: - if (k->state) return 1; - zxx_setpos(zxx_top - 7); - return 1; - case SDLK_PAGEDOWN: - if (k->state) return 1; - zxx_setpos(zxx_top + 7); - return 1; - default: - break; - }; - } - return 0; + if (*selected_widget == 25 && k->sym == SDLK_UP) { + /* scroll up */ + if (k->state == KEY_RELEASE) + return 1; + if (zxx_top == 0) + return 0; /* let the normal key handler catch it and change focus */ + zxx_setpos(zxx_top - 1); + return 1; + } + if (*selected_widget == 31 && k->sym == SDLK_DOWN) { + /* scroll down */ + if (k->state == KEY_RELEASE) + return 1; + zxx_setpos(zxx_top + 1); + return 1; + } + if ((*selected_widget) >= 25) { + switch (k->sym) { + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 1; + zxx_setpos(zxx_top - 7); + return 1; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 1; + zxx_setpos(zxx_top + 7); + return 1; + default: + break; + }; + } + return 0; } static void midiout_set_page(void) { - copy_in(); + copy_in(); } void midiout_load_page(struct page *page) { - int i; + int i; - page->title = "MIDI Output Configuration"; - page->draw_const = midiout_draw_const; - page->set_page = midiout_set_page; - page->pre_handle_key = pre_handle_key; - page->total_widgets = 32; - page->widgets = widgets_midiout; - page->help_index = HELP_MIDI_OUTPUT; - - char *editcfg_top[] = { - editcfg.start, editcfg.stop, editcfg.tick, editcfg.note_on, editcfg.note_off, - editcfg.set_volume, editcfg.set_panning, editcfg.set_bank, editcfg.set_program, - }; - - for (i = 0; i < 9; i++) { - create_textentry(widgets_midiout + i, 17, 13 + i, 43, - (i == 0 ? 0 : (i - 1)), i + 1, 9, - copy_out, editcfg_top[i], 31); - } - for (i = 0; i < 16; i++) { - create_textentry(widgets_midiout + 9 + i, 17, 24 + i, 43, - 9 + i - 1, 9 + i + 1, 25, - copy_out, editcfg.sfx[i], 31); - } - for (i = 0; i < 7; i++) { - create_textentry(widgets_midiout + 25 + i, 17, 42 + i, 43, - 25 + i - 1, 25 + ((i == 6) ? 6 : (i + 1)), 0, - copy_out, editcfg.zxx[i], 31); - } + page->title = "MIDI Output Configuration"; + page->draw_const = midiout_draw_const; + page->set_page = midiout_set_page; + page->pre_handle_key = pre_handle_key; + page->total_widgets = 32; + page->widgets = widgets_midiout; + page->help_index = HELP_MIDI_OUTPUT; + + char *editcfg_top[] = { + editcfg.start, editcfg.stop, editcfg.tick, editcfg.note_on, editcfg.note_off, + editcfg.set_volume, editcfg.set_panning, editcfg.set_bank, editcfg.set_program, + }; + + for (i = 0; i < 9; i++) { + create_textentry(widgets_midiout + i, 17, 13 + i, 43, + (i == 0 ? 0 : (i - 1)), i + 1, 9, + copy_out, editcfg_top[i], 31); + } + for (i = 0; i < 16; i++) { + create_textentry(widgets_midiout + 9 + i, 17, 24 + i, 43, + 9 + i - 1, 9 + i + 1, 25, + copy_out, editcfg.sfx[i], 31); + } + for (i = 0; i < 7; i++) { + create_textentry(widgets_midiout + 25 + i, 17, 42 + i, 43, + 25 + i - 1, 25 + ((i == 6) ? 6 : (i + 1)), 0, + copy_out, editcfg.zxx[i], 31); + } } diff -Nru schism-0+20110101/schism/page_orderpan.c schism-20160521/schism/page_orderpan.c --- schism-0+20110101/schism/page_orderpan.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_orderpan.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -44,35 +44,35 @@ static void orderlist_reposition(void) { - if (current_order < top_order) { - top_order = current_order; - } else if (current_order > top_order + 31) { - top_order = current_order - 31; - } + if (current_order < top_order) { + top_order = current_order; + } else if (current_order > top_order + 31) { + top_order = current_order - 31; + } } /* --------------------------------------------------------------------- */ void update_current_order(void) { - char buf[4]; + char buf[4]; - draw_text(numtostr(3, current_order, buf), 12, 5, 5, 0); - draw_text(numtostr(3, csf_last_order(current_song), buf), 16, 5, 5, 0); + draw_text(numtostr(3, current_order, buf), 12, 5, 5, 0); + draw_text(numtostr(3, csf_last_order(current_song), buf), 16, 5, 5, 0); } void set_current_order(int order) { - current_order = CLAMP(order, 0, 255); - orderlist_reposition(); + current_order = CLAMP(order, 0, 255); + orderlist_reposition(); - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } int get_current_order(void) { - return current_order; + return current_order; } /* --------------------------------------------------------------------- */ @@ -80,838 +80,871 @@ void prev_order_pattern(void) { - int new_order = current_order; - int last_pattern = current_song->orderlist[new_order]; + int new_order = current_order; + int last_pattern = current_song->orderlist[new_order]; - do { - if (--new_order < 0) { - new_order = 0; - break; - } - } while (!(status.flags & CLASSIC_MODE) - && last_pattern == current_song->orderlist[new_order] - && current_song->orderlist[new_order] == ORDER_SKIP); - - if (current_song->orderlist[new_order] < 200) { - current_order = new_order; - orderlist_reposition(); - set_current_pattern(current_song->orderlist[new_order]); - } + do { + if (--new_order < 0) { + new_order = 0; + break; + } + } while (!(status.flags & CLASSIC_MODE) + && last_pattern == current_song->orderlist[new_order] + && current_song->orderlist[new_order] == ORDER_SKIP); + + if (current_song->orderlist[new_order] < 200) { + current_order = new_order; + orderlist_reposition(); + set_current_pattern(current_song->orderlist[new_order]); + } } void next_order_pattern(void) { - int new_order = current_order; - int last_pattern = current_song->orderlist[new_order]; + int new_order = current_order; + int last_pattern = current_song->orderlist[new_order]; - do { - if (++new_order > 255) { - new_order = 255; - break; - } - } while (!(status.flags & CLASSIC_MODE) - && last_pattern == current_song->orderlist[new_order] - && current_song->orderlist[new_order] == ORDER_SKIP); - - if (current_song->orderlist[new_order] < 200) { - current_order = new_order; - orderlist_reposition(); - set_current_pattern(current_song->orderlist[new_order]); - } + do { + if (++new_order > 255) { + new_order = 255; + break; + } + } while (!(status.flags & CLASSIC_MODE) + && last_pattern == current_song->orderlist[new_order] + && current_song->orderlist[new_order] == ORDER_SKIP); + + if (current_song->orderlist[new_order] < 200) { + current_order = new_order; + orderlist_reposition(); + set_current_pattern(current_song->orderlist[new_order]); + } } static void orderlist_cheater(void) { - song_note_t *data; - int cp, i, best, first; - int rows; - - if (current_song->orderlist[current_order] != ORDER_SKIP - && current_song->orderlist[current_order] != ORDER_LAST) { - return; - } - cp = get_current_pattern(); - best = first = -1; - for (i = 0; i < 199; i++) { - if (csf_pattern_is_empty(current_song, i)) { - if (first == -1) first = i; - if (best == -1) best = i; - } else { - best = -1; - } - } - if (best == -1) best = first; - if (best == -1) return; - - status_text_flash("Pattern %d copied to pattern %d, order %d", cp, best, current_order); - - data = song_pattern_allocate_copy(cp, &rows); - song_pattern_resize(best, rows); - song_pattern_install(best, data, rows); - current_song->orderlist[current_order] = best; - current_order++; - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; + song_note_t *data; + int cp, i, best, first; + int rows; + + if (current_song->orderlist[current_order] != ORDER_SKIP + && current_song->orderlist[current_order] != ORDER_LAST) { + return; + } + cp = get_current_pattern(); + best = first = -1; + for (i = 0; i < 199; i++) { + if (csf_pattern_is_empty(current_song, i)) { + if (first == -1) first = i; + if (best == -1) best = i; + } else { + best = -1; + } + } + if (best == -1) best = first; + if (best == -1) return; + + status_text_flash("Pattern %d copied to pattern %d, order %d", cp, best, current_order); + + data = song_pattern_allocate_copy(cp, &rows); + song_pattern_resize(best, rows); + song_pattern_install(best, data, rows); + current_song->orderlist[current_order] = best; + current_order++; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void get_pattern_string(unsigned char pattern, char *buf) { - switch (pattern) { - case ORDER_SKIP: - buf[0] = buf[1] = buf[2] = '+'; - buf[3] = 0; - break; - case ORDER_LAST: - buf[0] = buf[1] = buf[2] = '-'; - buf[3] = 0; - break; - default: - numtostr(3, pattern, buf); - break; - } + switch (pattern) { + case ORDER_SKIP: + buf[0] = buf[1] = buf[2] = '+'; + buf[3] = 0; + break; + case ORDER_LAST: + buf[0] = buf[1] = buf[2] = '-'; + buf[3] = 0; + break; + default: + numtostr(3, pattern, buf); + break; + } } static void orderlist_draw(void) { - char buf[4]; - int pos, n; - int playing_order = (song_get_mode() == MODE_PLAYING ? song_get_current_order() : -1); - - /* draw the list */ - for (pos = 0, n = top_order; pos < 32; pos++, n++) { - draw_text(numtostr(3, n, buf), 2, 15 + pos, (n == playing_order ? 3 : 0), 2); - get_pattern_string(current_song->orderlist[n], buf); - draw_text(buf, 6, 15 + pos, 2, 0); - } - - /* draw the cursor */ - if (ACTIVE_PAGE.selected_widget == 0) { - get_pattern_string(current_song->orderlist[current_order], buf); - pos = current_order - top_order; - draw_char(buf[orderlist_cursor_pos], orderlist_cursor_pos + 6, 15 + pos, 0, 3); - } + char buf[4]; + int pos, n; + int playing_order = (song_get_mode() == MODE_PLAYING ? song_get_current_order() : -1); + + /* draw the list */ + for (pos = 0, n = top_order; pos < 32; pos++, n++) { + draw_text(numtostr(3, n, buf), 2, 15 + pos, (n == playing_order ? 3 : 0), 2); + get_pattern_string(current_song->orderlist[n], buf); + draw_text(buf, 6, 15 + pos, 2, 0); + } + + /* draw the cursor */ + if (ACTIVE_PAGE.selected_widget == 0) { + get_pattern_string(current_song->orderlist[current_order], buf); + pos = current_order - top_order; + draw_char(buf[orderlist_cursor_pos], orderlist_cursor_pos + 6, 15 + pos, 0, 3); + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void orderlist_insert_pos(void) { - memmove(current_song->orderlist + current_order + 1, - current_song->orderlist + current_order, - 255 - current_order); - current_song->orderlist[current_order] = ORDER_LAST; + memmove(current_song->orderlist + current_order + 1, + current_song->orderlist + current_order, + 255 - current_order); + current_song->orderlist[current_order] = ORDER_LAST; - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void orderlist_save(void) { - memcpy(saved_orderlist, current_song->orderlist, 255); - _did_save_orderlist = 1; + memcpy(saved_orderlist, current_song->orderlist, 255); + _did_save_orderlist = 1; } static void orderlist_restore(void) { - unsigned char oldlist[256]; - if (!_did_save_orderlist) return; - memcpy(oldlist, current_song->orderlist, 255); - memcpy(current_song->orderlist, saved_orderlist, 255); - memcpy(saved_orderlist, oldlist, 255); + unsigned char oldlist[256]; + if (!_did_save_orderlist) return; + memcpy(oldlist, current_song->orderlist, 255); + memcpy(current_song->orderlist, saved_orderlist, 255); + memcpy(saved_orderlist, oldlist, 255); } static void orderlist_delete_pos(void) { - memmove(current_song->orderlist + current_order, - current_song->orderlist + current_order + 1, - 255 - current_order); - current_song->orderlist[255] = ORDER_LAST; + memmove(current_song->orderlist + current_order, + current_song->orderlist + current_order + 1, + 255 - current_order); + current_song->orderlist[255] = ORDER_LAST; - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void orderlist_insert_next(void) { - int next_pattern; + int next_pattern; - if (current_order == 0 || current_song->orderlist[current_order - 1] > 199) - return; - next_pattern = current_song->orderlist[current_order - 1] + 1; - if (next_pattern > 199) - next_pattern = 199; - current_song->orderlist[current_order] = next_pattern; - if (current_order < 255) - current_order++; - orderlist_reposition(); + if (current_order == 0 || current_song->orderlist[current_order - 1] > 199) + return; + next_pattern = current_song->orderlist[current_order - 1] + 1; + if (next_pattern > 199) + next_pattern = 199; + current_song->orderlist[current_order] = next_pattern; + if (current_order < 255) + current_order++; + orderlist_reposition(); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void orderlist_add_unused_patterns(void) { - /* n0 = the first free order - * n = orderlist position - * p = pattern iterator - * np = number of patterns */ - int n0, n, p, np = csf_get_num_patterns(current_song); - uint8_t used[200] = {0}; /* could be a bitset... */ - - for (n = 0; n < 255; n++) - if (current_song->orderlist[n] < 200) - used[current_song->orderlist[n]] = 1; - - /* after the loop, n == 255 */ - while (n >= 0 && current_song->orderlist[n] == 0xff) - n--; - if (n == -1) - n = 0; - else - n += 2; - - n0 = n; - for (p = 0; p < np; p++) { - if (used[p] || csf_pattern_is_empty(current_song, p)) - continue; - if (n > 255) { - /* status_text_flash("No more room in orderlist"); */ - break; - } - current_song->orderlist[n++] = p; - } - if (n == n0) { - status_text_flash("No unused patterns"); - } else { - set_current_order(n - 1); - set_current_order(n0); - if (n - n0 == 1) { - status_text_flash("1 unused pattern found"); - } else { - status_text_flash("%d unused patterns found", n - n0); - } - } + /* n0 = the first free order + * n = orderlist position + * p = pattern iterator + * np = number of patterns */ + int n0, n, p, np = csf_get_num_patterns(current_song); + uint8_t used[200] = {0}; /* could be a bitset... */ + + for (n = 0; n < 255; n++) + if (current_song->orderlist[n] < 200) + used[current_song->orderlist[n]] = 1; + + /* after the loop, n == 255 */ + while (n >= 0 && current_song->orderlist[n] == 0xff) + n--; + if (n == -1) + n = 0; + else + n += 2; + + n0 = n; + for (p = 0; p < np; p++) { + if (used[p] || csf_pattern_is_empty(current_song, p)) + continue; + if (n > 255) { + /* status_text_flash("No more room in orderlist"); */ + break; + } + current_song->orderlist[n++] = p; + } + if (n == n0) { + status_text_flash("No unused patterns"); + } else { + set_current_order(n - 1); + set_current_order(n0); + if (n - n0 == 1) { + status_text_flash("1 unused pattern found"); + } else { + status_text_flash("%d unused patterns found", n - n0); + } + } - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void orderlist_reorder(void) { - /* err, I hope this is going to be done correctly... - */ - song_note_t *np[256]; - int nplen[256]; - unsigned char mapol[256]; - int i, j; - - song_lock_audio(); - - orderlist_add_unused_patterns(); - - memset(np, 0, sizeof(np)); - memset(mapol, ORDER_LAST, sizeof(mapol)); - for (i = j = 0; i < 255; i++) { - if (current_song->orderlist[i] == ORDER_LAST || current_song->orderlist[i] == ORDER_SKIP) { - continue; - } - if (mapol[ current_song->orderlist[i] ] == ORDER_LAST) { - np[j] = song_pattern_allocate_copy(current_song->orderlist[i], &nplen[j]); - mapol[ current_song->orderlist[i] ] = j; - j++; - } - /* replace orderlist entry */ - current_song->orderlist[i] = mapol[ current_song->orderlist[i] ]; - } - for (i = 0; i < 200; i++) { - if (!np[i]) { - song_pattern_install(i, NULL, 64); - } else { - song_pattern_install(i, np[i], nplen[i]); - } - } + /* err, I hope this is going to be done correctly... + */ + song_note_t *np[256]; + int nplen[256]; + unsigned char mapol[256]; + int i, j; + + song_lock_audio(); + + orderlist_add_unused_patterns(); + + memset(np, 0, sizeof(np)); + memset(mapol, ORDER_LAST, sizeof(mapol)); + for (i = j = 0; i < 255; i++) { + if (current_song->orderlist[i] == ORDER_LAST || current_song->orderlist[i] == ORDER_SKIP) { + continue; + } + if (mapol[ current_song->orderlist[i] ] == ORDER_LAST) { + np[j] = song_pattern_allocate_copy(current_song->orderlist[i], &nplen[j]); + mapol[ current_song->orderlist[i] ] = j; + j++; + } + /* replace orderlist entry */ + current_song->orderlist[i] = mapol[ current_song->orderlist[i] ]; + } + for (i = 0; i < 200; i++) { + if (!np[i]) { + song_pattern_install(i, NULL, 64); + } else { + song_pattern_install(i, np[i], nplen[i]); + } + } - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; - song_stop_unlocked(0); + song_stop_unlocked(0); - song_unlock_audio(); + song_unlock_audio(); } static int orderlist_handle_char(struct key_event *k) { - int c; - int cur_pattern; - //unsigned char *list; - song_note_t *tmp; - int n[3] = { 0 }; - - switch (k->sym) { - case SDLK_PLUS: - if (k->state) return 1; - status.flags |= SONG_NEEDS_SAVE; - current_song->orderlist[current_order] = ORDER_SKIP; - orderlist_cursor_pos = 2; - break; - case SDLK_PERIOD: - case SDLK_MINUS: - if (k->state) return 1; - status.flags |= SONG_NEEDS_SAVE; - current_song->orderlist[current_order] = ORDER_LAST; - orderlist_cursor_pos = 2; - break; - default: - c = numeric_key_event(k, 0); - if (c == -1) return 0; - if (k->state) return 1; - - status.flags |= SONG_NEEDS_SAVE; - cur_pattern = current_song->orderlist[current_order]; - if (cur_pattern < 200) { - n[0] = cur_pattern / 100; - n[1] = cur_pattern / 10 % 10; - n[2] = cur_pattern % 10; - } - - n[orderlist_cursor_pos] = c; - cur_pattern = n[0] * 100 + n[1] * 10 + n[2]; - cur_pattern = CLAMP(cur_pattern, 0, 199); - song_get_pattern(cur_pattern, &tmp); /* make sure it exists */ - current_song->orderlist[current_order] = cur_pattern; - break; - }; - - if (orderlist_cursor_pos == 2) { - if (current_order < 255) - current_order++; - orderlist_cursor_pos = 0; - orderlist_reposition(); - } else { - orderlist_cursor_pos++; - } + int c; + int cur_pattern; + //unsigned char *list; + song_note_t *tmp; + int n[3] = { 0 }; + + switch (k->sym) { + case SDLK_PLUS: + if (k->state == KEY_RELEASE) + return 1; + status.flags |= SONG_NEEDS_SAVE; + current_song->orderlist[current_order] = ORDER_SKIP; + orderlist_cursor_pos = 2; + break; + case SDLK_PERIOD: + case SDLK_MINUS: + if (k->state == KEY_RELEASE) + return 1; + status.flags |= SONG_NEEDS_SAVE; + current_song->orderlist[current_order] = ORDER_LAST; + orderlist_cursor_pos = 2; + break; + default: + c = numeric_key_event(k, 0); + if (c == -1) return 0; + if (k->state == KEY_RELEASE) + return 1; + + status.flags |= SONG_NEEDS_SAVE; + cur_pattern = current_song->orderlist[current_order]; + if (cur_pattern < 200) { + n[0] = cur_pattern / 100; + n[1] = cur_pattern / 10 % 10; + n[2] = cur_pattern % 10; + } + + n[orderlist_cursor_pos] = c; + cur_pattern = n[0] * 100 + n[1] * 10 + n[2]; + cur_pattern = CLAMP(cur_pattern, 0, 199); + song_get_pattern(cur_pattern, &tmp); /* make sure it exists */ + current_song->orderlist[current_order] = cur_pattern; + break; + }; + + if (orderlist_cursor_pos == 2) { + if (current_order < 255) + current_order++; + orderlist_cursor_pos = 0; + orderlist_reposition(); + } else { + orderlist_cursor_pos++; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; - return 1; + return 1; } static int orderlist_handle_key_on_list(struct key_event * k) { - int prev_order = current_order; - int new_order = prev_order; - int new_cursor_pos = orderlist_cursor_pos; - int n, p; - - if (k->mouse) { - if (k->x >= 6 && k->x <= 8 && k->y >= 15 && k->y <= 46) { - /* FIXME adjust top_order, not the cursor */ - if (k->mouse == MOUSE_SCROLL_UP) { - new_order -= MOUSE_SCROLL_LINES; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - new_order += MOUSE_SCROLL_LINES; - } else { - if (!k->state) return 0; - - new_order = (k->y - 15) + top_order; - set_current_order(new_order); - new_order = current_order; - - if (current_song->orderlist[current_order] != ORDER_LAST - && current_song->orderlist[current_order] != ORDER_SKIP) { - new_cursor_pos = (k->x - 6); - } - } - } - } - - switch (k->sym) { - case SDLK_BACKSPACE: - if (status.flags & CLASSIC_MODE) return 0; - if (!(k->mod & KMOD_ALT)) return 0; - if (!k->state) return 1; - if (!_did_save_orderlist) return 1; - status_text_flash("Restored orderlist"); - orderlist_restore(); - return 1; - - case SDLK_RETURN: - case SDLK_KP_ENTER: - if (status.flags & CLASSIC_MODE) return 0; - if (k->mod & KMOD_ALT) { - if (!k->state) return 1; - status_text_flash("Saved orderlist"); - orderlist_save(); - return 1; - } - // else fall through - - case SDLK_g: - if (!NO_MODIFIER(k->mod)) - return 0; - if (!k->state) return 1; - n = current_song->orderlist[new_order]; - while (n >= 200 && new_order > 0) - n = current_song->orderlist[--new_order]; - if (n < 200) { - set_current_pattern(n); - set_page(PAGE_PATTERN_EDITOR); - } - return 1; - - case SDLK_TAB: - if (k->mod & KMOD_SHIFT) { - if (k->state) return 1; - change_focus_to(33); - } else { - if (!NO_MODIFIER(k->mod)) return 0; - if (k->state) return 1; - change_focus_to(1); - } - return 1; - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_pos--; - break; - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_cursor_pos++; - break; - case SDLK_HOME: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order = 0; - break; - case SDLK_END: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order = csf_last_order(current_song); - if (current_song->orderlist[new_order] != ORDER_LAST) - new_order++; - break; - case SDLK_UP: - if (k->mod & KMOD_CTRL) { - if (status.flags & CLASSIC_MODE) return 0; - if (k->state) return 1; - sample_set(sample_get_current()-1); - status.flags |= NEED_UPDATE; - return 1; - } - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order--; - break; - case SDLK_DOWN: - if (k->mod & KMOD_CTRL) { - if (status.flags & CLASSIC_MODE) return 0; - if (k->state) return 1; - sample_set(sample_get_current()+1); - status.flags |= NEED_UPDATE; - return 1; - } - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order++; - break; - case SDLK_PAGEUP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order -= 16; - break; - case SDLK_PAGEDOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - new_order += 16; - break; - case SDLK_INSERT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - orderlist_insert_pos(); - return 1; - case SDLK_DELETE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - orderlist_delete_pos(); - return 1; - case SDLK_F7: - if (!(k->mod & KMOD_CTRL)) return 0; - /* fall through */ - case SDLK_SPACE: - if (k->state) return 1; - song_set_next_order(current_order); - status_text_flash("Playing order %d next", current_order); - return 1; - case SDLK_F6: - if (k->mod & KMOD_SHIFT) { - if (k->state) return 1; - song_start_at_order(current_order, 0); - return 1; - } - return 0; - - case SDLK_n: - if (k->mod & KMOD_SHIFT) { - if (!k->state) return 1; - orderlist_cheater(); - return 1; - } - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - orderlist_insert_next(); - return 1; - case SDLK_c: - if (!NO_MODIFIER(k->mod)) - return 0; - if (status.flags & CLASSIC_MODE) return 0; - if (!k->state) return 1; - p = get_current_pattern(); - for (n = current_order+1; n < 256; n++) { - if (current_song->orderlist[n] == p) { - new_order = n; - break; - } - } - if (n == 256) { - for (n = 0; n < current_order; n++) { - if (current_song->orderlist[n] == p) { - new_order = n; - break; - } - } - if (n == current_order) { - status_text_flash("Pattern %d not on Order List", p); - return 1; - } - } - break; - - case SDLK_r: - if (k->mod & KMOD_ALT) { - if (!k->state) return 1; - orderlist_reorder(); - return 1; - } - return 0; - case SDLK_u: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - orderlist_add_unused_patterns(); - return 1; - } - return 0; - - case SDLK_b: - if (k->mod & KMOD_SHIFT) - return 0; - /* fall through */ - case SDLK_o: - if (!(k->mod & KMOD_CTRL)) - return 0; - if (k->state) return 1; - song_pattern_to_sample(current_song->orderlist[current_order], - !!(k->mod & KMOD_SHIFT), !!(k->sym == SDLK_b)); - return 1; - - case SDLK_LESS: - case SDLK_SEMICOLON: - case SDLK_COLON: - if (!NO_MODIFIER(k->mod)) return 0; - if (k->state) return 1; - sample_set(sample_get_current()-1); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_GREATER: - case SDLK_QUOTE: - case SDLK_QUOTEDBL: - if (!NO_MODIFIER(k->mod)) return 0; - if (k->state) return 1; - sample_set(sample_get_current()+1); - status.flags |= NEED_UPDATE; - return 1; - default: - if (!k->mouse) { - if ((k->mod & (KMOD_CTRL | KMOD_ALT))==0) { - return orderlist_handle_char(k); - } - return 0; - } - } - - if (new_cursor_pos < 0) - new_cursor_pos = 2; - else if (new_cursor_pos > 2) - new_cursor_pos = 0; - - if (new_order != prev_order) { - set_current_order(new_order); - } else if (new_cursor_pos != orderlist_cursor_pos) { - orderlist_cursor_pos = new_cursor_pos; - } else { - return 0; - } + int prev_order = current_order; + int new_order = prev_order; + int new_cursor_pos = orderlist_cursor_pos; + int n, p; + + if (k->mouse != MOUSE_NONE) { + if (k->x >= 6 && k->x <= 8 && k->y >= 15 && k->y <= 46) { + /* FIXME adjust top_order, not the cursor */ + if (k->mouse == MOUSE_SCROLL_UP) { + new_order -= MOUSE_SCROLL_LINES; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + new_order += MOUSE_SCROLL_LINES; + } else { + if (k->state == KEY_PRESS) + return 0; + + new_order = (k->y - 15) + top_order; + set_current_order(new_order); + new_order = current_order; + + if (current_song->orderlist[current_order] != ORDER_LAST + && current_song->orderlist[current_order] != ORDER_SKIP) { + new_cursor_pos = (k->x - 6); + } + } + } + } + + switch (k->sym) { + case SDLK_BACKSPACE: + if (status.flags & CLASSIC_MODE) return 0; + if (!(k->mod & KMOD_ALT)) return 0; + if (k->state == KEY_PRESS) + return 1; + if (!_did_save_orderlist) return 1; + status_text_flash("Restored orderlist"); + orderlist_restore(); + return 1; + + case SDLK_RETURN: + case SDLK_KP_ENTER: + if (status.flags & CLASSIC_MODE) return 0; + if (k->mod & KMOD_ALT) { + if (k->state == KEY_PRESS) + return 1; + status_text_flash("Saved orderlist"); + orderlist_save(); + return 1; + } + // else fall through + + case SDLK_g: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_PRESS) + return 1; + n = current_song->orderlist[new_order]; + while (n >= 200 && new_order > 0) + n = current_song->orderlist[--new_order]; + if (n < 200) { + set_current_pattern(n); + set_page(PAGE_PATTERN_EDITOR); + } + return 1; + + case SDLK_TAB: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_RELEASE) + return 1; + change_focus_to(33); + } else { + if (!NO_MODIFIER(k->mod)) return 0; + if (k->state == KEY_RELEASE) + return 1; + change_focus_to(1); + } + return 1; + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_pos--; + break; + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_cursor_pos++; + break; + case SDLK_HOME: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order = 0; + break; + case SDLK_END: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order = csf_last_order(current_song); + if (current_song->orderlist[new_order] != ORDER_LAST) + new_order++; + break; + case SDLK_UP: + if (k->mod & KMOD_CTRL) { + if (status.flags & CLASSIC_MODE) return 0; + if (k->state == KEY_RELEASE) + return 1; + sample_set(sample_get_current()-1); + status.flags |= NEED_UPDATE; + return 1; + } + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order--; + break; + case SDLK_DOWN: + if (k->mod & KMOD_CTRL) { + if (status.flags & CLASSIC_MODE) return 0; + if (k->state == KEY_RELEASE) + return 1; + sample_set(sample_get_current()+1); + status.flags |= NEED_UPDATE; + return 1; + } + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order++; + break; + case SDLK_PAGEUP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order -= 16; + break; + case SDLK_PAGEDOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + new_order += 16; + break; + case SDLK_INSERT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + orderlist_insert_pos(); + return 1; + case SDLK_DELETE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + orderlist_delete_pos(); + return 1; + case SDLK_F7: + if (!(k->mod & KMOD_CTRL)) return 0; + /* fall through */ + case SDLK_SPACE: + if (k->state == KEY_RELEASE) + return 1; + song_set_next_order(current_order); + status_text_flash("Playing order %d next", current_order); + return 1; + case SDLK_F6: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_RELEASE) + return 1; + song_start_at_order(current_order, 0); + return 1; + } + return 0; + + case SDLK_n: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_PRESS) + return 1; + orderlist_cheater(); + return 1; + } + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + orderlist_insert_next(); + return 1; + case SDLK_c: + if (!NO_MODIFIER(k->mod)) + return 0; + if (status.flags & CLASSIC_MODE) return 0; + if (k->state == KEY_PRESS) + return 1; + p = get_current_pattern(); + for (n = current_order+1; n < 256; n++) { + if (current_song->orderlist[n] == p) { + new_order = n; + break; + } + } + if (n == 256) { + for (n = 0; n < current_order; n++) { + if (current_song->orderlist[n] == p) { + new_order = n; + break; + } + } + if (n == current_order) { + status_text_flash("Pattern %d not on Order List", p); + return 1; + } + } + break; + + case SDLK_r: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_PRESS) + return 1; + orderlist_reorder(); + return 1; + } + return 0; + case SDLK_u: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + orderlist_add_unused_patterns(); + return 1; + } + return 0; + + case SDLK_b: + if (k->mod & KMOD_SHIFT) + return 0; + /* fall through */ + case SDLK_o: + if (!(k->mod & KMOD_CTRL)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + song_pattern_to_sample(current_song->orderlist[current_order], + !!(k->mod & KMOD_SHIFT), !!(k->sym == SDLK_b)); + return 1; + + case SDLK_LESS: + case SDLK_SEMICOLON: + case SDLK_COLON: + if (!NO_MODIFIER(k->mod)) return 0; + if (k->state == KEY_RELEASE) + return 1; + sample_set(sample_get_current()-1); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_GREATER: + case SDLK_QUOTE: + case SDLK_QUOTEDBL: + if (!NO_MODIFIER(k->mod)) return 0; + if (k->state == KEY_RELEASE) + return 1; + sample_set(sample_get_current()+1); + status.flags |= NEED_UPDATE; + return 1; + default: + if (k->mouse == MOUSE_NONE) { + if ((k->mod & (KMOD_CTRL | KMOD_ALT))==0) { + return orderlist_handle_char(k); + } + return 0; + } + } + + if (new_cursor_pos < 0) + new_cursor_pos = 2; + else if (new_cursor_pos > 2) + new_cursor_pos = 0; + + if (new_order != prev_order) { + set_current_order(new_order); + } else if (new_cursor_pos != orderlist_cursor_pos) { + orderlist_cursor_pos = new_cursor_pos; + } else { + return 0; + } - status.flags |= NEED_UPDATE; - return 1; + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------- */ static void order_pan_vol_draw_const(void) { - draw_box(5, 14, 9, 47, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(5, 14, 9, 47, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(30, 14, 40, 47, BOX_THICK | BOX_INNER | BOX_FLAT_LIGHT); - draw_box(64, 14, 74, 47, BOX_THICK | BOX_INNER | BOX_FLAT_LIGHT); + draw_box(30, 14, 40, 47, BOX_THICK | BOX_INNER | BOX_FLAT_LIGHT); + draw_box(64, 14, 74, 47, BOX_THICK | BOX_INNER | BOX_FLAT_LIGHT); - draw_char(146, 30, 14, 3, 2); - draw_char(145, 40, 14, 3, 2); + draw_char(146, 30, 14, 3, 2); + draw_char(145, 40, 14, 3, 2); - draw_char(146, 64, 14, 3, 2); - draw_char(145, 74, 14, 3, 2); + draw_char(146, 64, 14, 3, 2); + draw_char(145, 74, 14, 3, 2); } static void orderpan_draw_const(void) { - order_pan_vol_draw_const(); - draw_text("L M R", 31, 14, 0, 3); - draw_text("L M R", 65, 14, 0, 3); + order_pan_vol_draw_const(); + draw_text("L M R", 31, 14, 0, 3); + draw_text("L M R", 65, 14, 0, 3); } static void ordervol_draw_const(void) { - int n; - char buf[16]; - int fg; - - strcpy(buf, "Channel 42"); - - order_pan_vol_draw_const(); - - draw_text(" Volumes ", 31, 14, 0, 3); - draw_text(" Volumes ", 65, 14, 0, 3); - - for (n = 1; n <= 32; n++) { - fg = 0; - if (!(status.flags & CLASSIC_MODE)) { - if (ACTIVE_PAGE.selected_widget == n) { - fg = 3; - } - } - - numtostr(2, n, buf + 8); - draw_text(buf, 20, 14 + n, fg, 2); - - fg = 0; - if (!(status.flags & CLASSIC_MODE)) { - if (ACTIVE_PAGE.selected_widget == n+32) { - fg = 3; - } - } - - numtostr(2, n + 32, buf + 8); - draw_text(buf, 54, 14 + n, fg, 2); - } + int n; + char buf[16]; + int fg; + + strcpy(buf, "Channel 42"); + + order_pan_vol_draw_const(); + + draw_text(" Volumes ", 31, 14, 0, 3); + draw_text(" Volumes ", 65, 14, 0, 3); + + for (n = 1; n <= 32; n++) { + fg = 0; + if (!(status.flags & CLASSIC_MODE)) { + if (ACTIVE_PAGE.selected_widget == n) { + fg = 3; + } + } + + numtostr(2, n, buf + 8); + draw_text(buf, 20, 14 + n, fg, 2); + + fg = 0; + if (!(status.flags & CLASSIC_MODE)) { + if (ACTIVE_PAGE.selected_widget == n+32) { + fg = 3; + } + } + + numtostr(2, n + 32, buf + 8); + draw_text(buf, 54, 14 + n, fg, 2); + } } /* --------------------------------------------------------------------- */ static void order_pan_vol_playback_update(void) { - static int last_order = -1; - int order = ((song_get_mode() == MODE_STOPPED) ? -1 : song_get_current_order()); + static int last_order = -1; + int order = ((song_get_mode() == MODE_STOPPED) ? -1 : song_get_current_order()); - if (order != last_order) { - last_order = order; - status.flags |= NEED_UPDATE; - } + if (order != last_order) { + last_order = order; + status.flags |= NEED_UPDATE; + } } /* --------------------------------------------------------------------- */ static void orderpan_update_values_in_song(void) { - song_channel_t *chn; - int n; + song_channel_t *chn; + int n; - status.flags |= SONG_NEEDS_SAVE; - for (n = 0; n < 64; n++) { - chn = song_get_channel(n); - - /* yet another modplug hack here! */ - chn->panning = widgets_orderpan[n + 1].d.panbar.value * 4; - - if (widgets_orderpan[n + 1].d.panbar.surround) - chn->flags |= CHN_SURROUND; - else - chn->flags &= ~CHN_SURROUND; + status.flags |= SONG_NEEDS_SAVE; + for (n = 0; n < 64; n++) { + chn = song_get_channel(n); + + /* yet another modplug hack here! */ + chn->panning = widgets_orderpan[n + 1].d.panbar.value * 4; + + if (widgets_orderpan[n + 1].d.panbar.surround) + chn->flags |= CHN_SURROUND; + else + chn->flags &= ~CHN_SURROUND; - song_set_channel_mute(n, widgets_orderpan[n + 1].d.panbar.muted); - } + song_set_channel_mute(n, widgets_orderpan[n + 1].d.panbar.muted); + } } static void ordervol_update_values_in_song(void) { - int n; + int n; - status.flags |= SONG_NEEDS_SAVE; - for (n = 0; n < 64; n++) - song_get_channel(n)->volume = widgets_ordervol[n + 1].d.thumbbar.value; + status.flags |= SONG_NEEDS_SAVE; + for (n = 0; n < 64; n++) + song_get_channel(n)->volume = widgets_ordervol[n + 1].d.thumbbar.value; } /* called when a channel is muted/unmuted by means other than the panning * page (alt-f10 in the pattern editor, space on the info page...) */ void orderpan_recheck_muted_channels(void) { - int n; - for (n = 0; n < 64; n++) - widgets_orderpan[n + 1].d.panbar.muted = !!(song_get_channel(n)->flags & CHN_MUTE); + int n; + for (n = 0; n < 64; n++) + widgets_orderpan[n + 1].d.panbar.muted = !!(song_get_channel(n)->flags & CHN_MUTE); - if (status.current_page == PAGE_ORDERLIST_PANNING) - status.flags |= NEED_UPDATE; + if (status.current_page == PAGE_ORDERLIST_PANNING) + status.flags |= NEED_UPDATE; } static void order_pan_vol_song_changed_cb(void) { - int n; - song_channel_t *chn; + int n; + song_channel_t *chn; - for (n = 0; n < 64; n++) { - chn = song_get_channel(n); - widgets_orderpan[n + 1].d.panbar.value = chn->panning / 4; - widgets_orderpan[n + 1].d.panbar.surround = !!(chn->flags & CHN_SURROUND); - widgets_orderpan[n + 1].d.panbar.muted = !!(chn->flags & CHN_MUTE); - widgets_ordervol[n + 1].d.thumbbar.value = chn->volume; - } + for (n = 0; n < 64; n++) { + chn = song_get_channel(n); + widgets_orderpan[n + 1].d.panbar.value = chn->panning / 4; + widgets_orderpan[n + 1].d.panbar.surround = !!(chn->flags & CHN_SURROUND); + widgets_orderpan[n + 1].d.panbar.muted = !!(chn->flags & CHN_MUTE); + widgets_ordervol[n + 1].d.thumbbar.value = chn->volume; + } } /* --------------------------------------------------------------------- */ static void order_pan_vol_handle_key(struct key_event * k) { - int n = ACTIVE_PAGE.selected_widget; + int n = ACTIVE_PAGE.selected_widget; - if (k->state) return; + if (k->state == KEY_RELEASE) + return; - if (!NO_MODIFIER(k->mod)) - return; + if (!NO_MODIFIER(k->mod)) + return; - switch (k->sym) { - case SDLK_PAGEDOWN: - n += 8; - break; - case SDLK_PAGEUP: - n -= 8; - break; - default: - return; - } - - n = CLAMP(n, 1, 64); - if (ACTIVE_PAGE.selected_widget != n) - change_focus_to(n); + switch (k->sym) { + case SDLK_PAGEDOWN: + n += 8; + break; + case SDLK_PAGEUP: + n -= 8; + break; + default: + return; + } + + n = CLAMP(n, 1, 64); + if (ACTIVE_PAGE.selected_widget != n) + change_focus_to(n); } static int order_pre_key(struct key_event *k) { - // hack to sync the active widget between pan/vol pages - if (!(status.flags & CLASSIC_MODE)) { - pages[PAGE_ORDERLIST_PANNING].selected_widget - = pages[PAGE_ORDERLIST_VOLUMES].selected_widget - = ACTIVE_PAGE.selected_widget; - } - - if (k->sym == SDLK_F7) { - if (!NO_MODIFIER(k->mod)) return 0; - if (k->state) return 1; - play_song_from_mark_orderpan(); - return 1; - } - return 0; + // hack to sync the active widget between pan/vol pages + if (!(status.flags & CLASSIC_MODE)) { + pages[PAGE_ORDERLIST_PANNING].selected_widget + = pages[PAGE_ORDERLIST_VOLUMES].selected_widget + = ACTIVE_PAGE.selected_widget; + } + + if (k->sym == SDLK_F7) { + if (!NO_MODIFIER(k->mod)) return 0; + if (k->state == KEY_RELEASE) + return 1; + play_song_from_mark_orderpan(); + return 1; + } + return 0; } static void order_pan_set_page(void) { - orderpan_recheck_muted_channels(); + orderpan_recheck_muted_channels(); } /* --------------------------------------------------------------------- */ void orderpan_load_page(struct page *page) { - int n; + int n; - page->title = "Order List and Panning (F11)"; - page->draw_const = orderpan_draw_const; - /* this does the work for both pages */ - page->song_changed_cb = order_pan_vol_song_changed_cb; - page->playback_update = order_pan_vol_playback_update; - page->pre_handle_key = order_pre_key; - page->handle_key = order_pan_vol_handle_key; - page->set_page = order_pan_set_page; - page->total_widgets = 65; - page->widgets = widgets_orderpan; - page->help_index = HELP_ORDERLIST_PANNING; - - /* 0 = order list */ - create_other(widgets_orderpan + 0, 1, orderlist_handle_key_on_list, orderlist_draw); - widgets_orderpan[0].accept_text = 0; - widgets_orderpan[0].x = 6; - widgets_orderpan[0].y = 15; - widgets_orderpan[0].width = 3; - widgets_orderpan[0].height = 32; - - /* 1-64 = panbars */ - create_panbar(widgets_orderpan + 1, 20, 15, 1, 2, 33, orderpan_update_values_in_song, 1); - for (n = 2; n <= 32; n++) { - create_panbar(widgets_orderpan + n, 20, 14 + n, n - 1, n + 1, n + 32, - orderpan_update_values_in_song, n); - create_panbar(widgets_orderpan + n + 31, 54, 13 + n, n + 30, n + 32, 0, - orderpan_update_values_in_song, n + 31); - } - create_panbar(widgets_orderpan + 64, 54, 46, 63, 64, 0, orderpan_update_values_in_song, 64); + page->title = "Order List and Panning (F11)"; + page->draw_const = orderpan_draw_const; + /* this does the work for both pages */ + page->song_changed_cb = order_pan_vol_song_changed_cb; + page->playback_update = order_pan_vol_playback_update; + page->pre_handle_key = order_pre_key; + page->handle_key = order_pan_vol_handle_key; + page->set_page = order_pan_set_page; + page->total_widgets = 65; + page->widgets = widgets_orderpan; + page->help_index = HELP_ORDERLIST_PANNING; + + /* 0 = order list */ + create_other(widgets_orderpan + 0, 1, orderlist_handle_key_on_list, orderlist_draw); + widgets_orderpan[0].accept_text = 0; + widgets_orderpan[0].x = 6; + widgets_orderpan[0].y = 15; + widgets_orderpan[0].width = 3; + widgets_orderpan[0].height = 32; + + /* 1-64 = panbars */ + create_panbar(widgets_orderpan + 1, 20, 15, 1, 2, 33, orderpan_update_values_in_song, 1); + for (n = 2; n <= 32; n++) { + create_panbar(widgets_orderpan + n, 20, 14 + n, n - 1, n + 1, n + 32, + orderpan_update_values_in_song, n); + create_panbar(widgets_orderpan + n + 31, 54, 13 + n, n + 30, n + 32, 0, + orderpan_update_values_in_song, n + 31); + } + create_panbar(widgets_orderpan + 64, 54, 46, 63, 64, 0, orderpan_update_values_in_song, 64); } void ordervol_load_page(struct page *page) { - int n; + int n; - page->title = "Order List and Channel Volume (F11)"; - page->draw_const = ordervol_draw_const; - page->playback_update = order_pan_vol_playback_update; - page->pre_handle_key = order_pre_key; - page->handle_key = order_pan_vol_handle_key; - page->total_widgets = 65; - page->widgets = widgets_ordervol; - page->help_index = HELP_ORDERLIST_VOLUME; - - /* 0 = order list */ - create_other(widgets_ordervol + 0, 1, orderlist_handle_key_on_list, orderlist_draw); - widgets_ordervol[0].accept_text = 0; - widgets_ordervol[0].x = 6; - widgets_ordervol[0].y = 15; - widgets_ordervol[0].width = 3; - widgets_ordervol[0].height = 32; - - /* 1-64 = thumbbars */ - create_thumbbar(widgets_ordervol + 1, 31, 15, 9, 1, 2, 33, ordervol_update_values_in_song, 0, 64); - for (n = 2; n <= 32; n++) { - create_thumbbar(widgets_ordervol + n, 31, 14 + n, 9, n - 1, n + 1, n + 32, - ordervol_update_values_in_song, 0, 64); - create_thumbbar(widgets_ordervol + n + 31, 65, 13 + n, 9, n + 30, n + 32, 0, - ordervol_update_values_in_song, 0, 64); - } - create_thumbbar(widgets_ordervol + 64, 65, 46, 9, 63, 64, 0, ordervol_update_values_in_song, 0, 64); + page->title = "Order List and Channel Volume (F11)"; + page->draw_const = ordervol_draw_const; + page->playback_update = order_pan_vol_playback_update; + page->pre_handle_key = order_pre_key; + page->handle_key = order_pan_vol_handle_key; + page->total_widgets = 65; + page->widgets = widgets_ordervol; + page->help_index = HELP_ORDERLIST_VOLUME; + + /* 0 = order list */ + create_other(widgets_ordervol + 0, 1, orderlist_handle_key_on_list, orderlist_draw); + widgets_ordervol[0].accept_text = 0; + widgets_ordervol[0].x = 6; + widgets_ordervol[0].y = 15; + widgets_ordervol[0].width = 3; + widgets_ordervol[0].height = 32; + + /* 1-64 = thumbbars */ + create_thumbbar(widgets_ordervol + 1, 31, 15, 9, 1, 2, 33, ordervol_update_values_in_song, 0, 64); + for (n = 2; n <= 32; n++) { + create_thumbbar(widgets_ordervol + n, 31, 14 + n, 9, n - 1, n + 1, n + 32, + ordervol_update_values_in_song, 0, 64); + create_thumbbar(widgets_ordervol + n + 31, 65, 13 + n, 9, n + 30, n + 32, 0, + ordervol_update_values_in_song, 0, 64); + } + create_thumbbar(widgets_ordervol + 64, 65, 46, 9, 63, 64, 0, ordervol_update_values_in_song, 0, 64); } /* --------------------------------------------------------------------- */ @@ -920,102 +953,102 @@ #define MAX_CHANNELS 64 // blah void song_set_pan_scheme(int scheme) { - int n, nc; - //int half; - int active = 0; - song_channel_t *chn = song_get_channel(0); - - //mphack alert, all pan values multiplied by 4 - switch (scheme) { - case PANS_STEREO: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - chn[n].panning = (n & 1) ? 256 : 0; - } - break; - case PANS_AMIGA: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - chn[n].panning = ((n + 1) & 2) ? 256 : 0; - } - break; - case PANS_LEFT: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - chn[n].panning = 0; - } - break; - case PANS_RIGHT: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - chn[n].panning = 256; - } - break; - case PANS_MONO: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - chn[n].panning = 128; - } - break; - case PANS_SLASH: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - active++; - } - for (n = 0, nc = 0; nc < active; n++) { - if (!(chn[n].flags & CHN_MUTE)) { - chn[n].panning = 256 - (256 * nc / (active - 1)); - nc++; - } - } - break; - case PANS_BACKSLASH: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - active++; - } - for (n = 0, nc = 0; nc < active; n++) { - if (!(chn[n].flags & CHN_MUTE)) { - chn[n].panning = (256 * nc / (active - 1)); - nc++; - } - } - break; + int n, nc; + //int half; + int active = 0; + song_channel_t *chn = song_get_channel(0); + + //mphack alert, all pan values multiplied by 4 + switch (scheme) { + case PANS_STEREO: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + chn[n].panning = (n & 1) ? 256 : 0; + } + break; + case PANS_AMIGA: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + chn[n].panning = ((n + 1) & 2) ? 256 : 0; + } + break; + case PANS_LEFT: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + chn[n].panning = 0; + } + break; + case PANS_RIGHT: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + chn[n].panning = 256; + } + break; + case PANS_MONO: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + chn[n].panning = 128; + } + break; + case PANS_SLASH: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + active++; + } + for (n = 0, nc = 0; nc < active; n++) { + if (!(chn[n].flags & CHN_MUTE)) { + chn[n].panning = 256 - (256 * nc / (active - 1)); + nc++; + } + } + break; + case PANS_BACKSLASH: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + active++; + } + for (n = 0, nc = 0; nc < active; n++) { + if (!(chn[n].flags & CHN_MUTE)) { + chn[n].panning = (256 * nc / (active - 1)); + nc++; + } + } + break; #if 0 - case PANS_CROSS: - for (n = 0; n < MAX_CHANNELS; n++) { - if (!(chn[n].flags & CHN_MUTE)) - active++; - } - half = active / 2; - for (n = 0, nc = 0; nc < half; n++) { - if (!(chn[n].flags & CHN_MUTE)) { - if (nc & 1) { - // right bias - go from 64 to 32 - chn[n].panning = (64 - (32 * nc / half)) * 4; - } else { - // left bias - go from 0 to 32 - chn[n].panning = (32 * nc / half) * 4; - } - nc++; - } - } - for (; nc < active; n++) { - if (!(chn[n].flags & CHN_MUTE)) { - if (nc & 1) { - chn[n].panning = (64 - (32 * (active - nc) / half)) * 4; - } else { - chn[n].panning = (32 * (active - nc) / half) * 4; - } - nc++; - } - } - break; + case PANS_CROSS: + for (n = 0; n < MAX_CHANNELS; n++) { + if (!(chn[n].flags & CHN_MUTE)) + active++; + } + half = active / 2; + for (n = 0, nc = 0; nc < half; n++) { + if (!(chn[n].flags & CHN_MUTE)) { + if (nc & 1) { + // right bias - go from 64 to 32 + chn[n].panning = (64 - (32 * nc / half)) * 4; + } else { + // left bias - go from 0 to 32 + chn[n].panning = (32 * nc / half) * 4; + } + nc++; + } + } + for (; nc < active; n++) { + if (!(chn[n].flags & CHN_MUTE)) { + if (nc & 1) { + chn[n].panning = (64 - (32 * (active - nc) / half)) * 4; + } else { + chn[n].panning = (32 * (active - nc) / half) * 4; + } + nc++; + } + } + break; #endif - default: - printf("oh i am confused\n"); - } - // get the values on the page to correspond to the song... - order_pan_vol_song_changed_cb(); + default: + printf("oh i am confused\n"); + } + // get the values on the page to correspond to the song... + order_pan_vol_song_changed_cb(); } diff -Nru schism-0+20110101/schism/page_palette.c schism-20160521/schism/page_palette.c --- schism-0+20110101/schism/page_palette.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_palette.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -46,208 +46,214 @@ static void palette_draw_const(void) { - int n; + int n; - draw_text("Predefined Palettes", 57, 25, 0, 2); + draw_text("Predefined Palettes", 57, 25, 0, 2); - for (n = 0; n < 7; n++) { - draw_box(2, 13 + (5 * n), 8, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(9, 13 + (5 * n), 19, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(29, 13 + (5 * n), 35, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(36, 13 + (5 * n), 46, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(3, 14 + (5 * n), 7, 16 + (5 * n), n); - draw_fill_chars(30, 14 + (5 * n), 34, 16 + (5 * n), n + 7); - } - - draw_box(56, 13, 62, 17, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(63, 13, 73, 17, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(56, 18, 62, 22, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(63, 18, 73, 22, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(55, 26, 77, 47, BOX_THICK | BOX_INNER | BOX_INSET); - draw_fill_chars(57, 14, 61, 16, 14); - draw_fill_chars(57, 19, 61, 21, 15); + for (n = 0; n < 7; n++) { + draw_box(2, 13 + (5 * n), 8, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(9, 13 + (5 * n), 19, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(29, 13 + (5 * n), 35, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(36, 13 + (5 * n), 46, 17 + (5 * n), BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(3, 14 + (5 * n), 7, 16 + (5 * n), n); + draw_fill_chars(30, 14 + (5 * n), 34, 16 + (5 * n), n + 7); + } + + draw_box(56, 13, 62, 17, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(63, 13, 73, 17, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(56, 18, 62, 22, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(63, 18, 73, 22, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(55, 26, 77, 47, BOX_THICK | BOX_INNER | BOX_INSET); + draw_fill_chars(57, 14, 61, 16, 14); + draw_fill_chars(57, 19, 61, 21, 15); } /* --------------------------------------------------------------------- */ static void update_thumbbars(void) { - int n; + int n; - for (n = 0; n < 16; n++) { - /* palettes[current_palette_index].colors[n] ? - * or current_palette[n] ? */ - widgets_palette[3 * n].d.thumbbar.value = current_palette[n][0]; - widgets_palette[3 * n + 1].d.thumbbar.value = current_palette[n][1]; - widgets_palette[3 * n + 2].d.thumbbar.value = current_palette[n][2]; - } + for (n = 0; n < 16; n++) { + /* palettes[current_palette_index].colors[n] ? + * or current_palette[n] ? */ + widgets_palette[3 * n].d.thumbbar.value = current_palette[n][0]; + widgets_palette[3 * n + 1].d.thumbbar.value = current_palette[n][1]; + widgets_palette[3 * n + 2].d.thumbbar.value = current_palette[n][2]; + } } /* --------------------------------------------------------------------- */ static void palette_list_draw(void) { - int n, focused = (ACTIVE_PAGE.selected_widget == 48); - int fg, bg; + int n, focused = (ACTIVE_PAGE.selected_widget == 48); + int fg, bg; - draw_fill_chars(56, 27, 76, 46, 0); + draw_fill_chars(56, 27, 76, 46, 0); - fg = 6; - bg = 0; - if (focused && -1 == selected_palette) { - fg = 0; - bg = 3; - } else if (-1 == selected_palette) { - bg = 14; - } - - draw_text_len("User Defined", 21, 56, 27, fg, bg); - for (n = 0; n < 19 && palettes[n].name[0]; n++) { - fg = 6; - bg = 0; - if (focused && n == selected_palette) { - fg = 0; - bg = 3; - } else if (n == selected_palette) { - bg = 14; - } - draw_text_len(palettes[n].name, 21, 56, 28 + n, fg, bg); - } - max_palette = n; + fg = 6; + bg = 0; + if (focused && -1 == selected_palette) { + fg = 0; + bg = 3; + } else if (-1 == selected_palette) { + bg = 14; + } + + draw_text_len("User Defined", 21, 56, 27, fg, bg); + for (n = 0; n < 19 && palettes[n].name[0]; n++) { + fg = 6; + bg = 0; + if (focused && n == selected_palette) { + fg = 0; + bg = 3; + } else if (n == selected_palette) { + bg = 14; + } + draw_text_len(palettes[n].name, 21, 56, 28 + n, fg, bg); + } + max_palette = n; } static int palette_list_handle_key_on_list(struct key_event * k) { - int new_palette = selected_palette; - const int focus_offsets[] = { 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 12 }; + int new_palette = selected_palette; + const int focus_offsets[] = { 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 12 }; - if (k->mouse == MOUSE_CLICK) { - if (!k->state) return 0; - if (k->x < 56 || k->y < 27 || k->y > 46 || k->x > 76) return 0; - new_palette = (k->y - 28); - if (new_palette == selected_palette) { - // alright - if (selected_palette == -1) return 1; - palette_load_preset(selected_palette); - palette_apply(); - update_thumbbars(); - status.flags |= NEED_UPDATE; - return 1; - } - } else { - if (k->state) return 0; - if (k->mouse == MOUSE_SCROLL_UP) new_palette -= MOUSE_SCROLL_LINES; - else if (k->mouse == MOUSE_SCROLL_DOWN) new_palette += MOUSE_SCROLL_LINES; - } - - switch (k->sym) { - case SDLK_UP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (--new_palette < -1) { - change_focus_to(47); - return 1; - } - break; - case SDLK_DOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - new_palette++; - break; - case SDLK_HOME: - if (!NO_MODIFIER(k->mod)) - return 0; - new_palette = 0; - break; - case SDLK_PAGEUP: - if (!NO_MODIFIER(k->mod)) - return 0; - if (new_palette == -1) { - change_focus_to(45); - return 1; - } - new_palette -= 16; - break; - case SDLK_END: - if (!NO_MODIFIER(k->mod)) - return 0; - new_palette = max_palette - 1; - break; - case SDLK_PAGEDOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - new_palette += 16; - break; - case SDLK_RETURN: - if (!NO_MODIFIER(k->mod)) - return 0; - if (selected_palette == -1) return 1; - palette_load_preset(selected_palette); - palette_apply(); - update_thumbbars(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_RIGHT: - case SDLK_TAB: - if (k->mod & KMOD_SHIFT) { - change_focus_to(focus_offsets[selected_palette+1] + 29); - return 1; - } - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(focus_offsets[selected_palette+1] + 8); - return 1; - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(focus_offsets[selected_palette+1] + 29); - return 1; - default: - if (!k->mouse) return 0; - } - - if (new_palette < -1) new_palette = -1; - else if (new_palette >= (max_palette-1)) new_palette = (max_palette-1); - if (new_palette != selected_palette) { - selected_palette = new_palette; - status.flags |= NEED_UPDATE; - } + if (k->mouse == MOUSE_CLICK) { + if (k->state == KEY_PRESS) + return 0; + if (k->x < 56 || k->y < 27 || k->y > 46 || k->x > 76) return 0; + new_palette = (k->y - 28); + if (new_palette == selected_palette) { + // alright + if (selected_palette == -1) return 1; + palette_load_preset(selected_palette); + palette_apply(); + update_thumbbars(); + status.flags |= NEED_UPDATE; + return 1; + } + } else { + if (k->state == KEY_RELEASE) + return 0; + if (k->mouse == MOUSE_SCROLL_UP) + new_palette -= MOUSE_SCROLL_LINES; + else if (k->mouse == MOUSE_SCROLL_DOWN) + new_palette += MOUSE_SCROLL_LINES; + } + + switch (k->sym) { + case SDLK_UP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (--new_palette < -1) { + change_focus_to(47); + return 1; + } + break; + case SDLK_DOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + new_palette++; + break; + case SDLK_HOME: + if (!NO_MODIFIER(k->mod)) + return 0; + new_palette = 0; + break; + case SDLK_PAGEUP: + if (!NO_MODIFIER(k->mod)) + return 0; + if (new_palette == -1) { + change_focus_to(45); + return 1; + } + new_palette -= 16; + break; + case SDLK_END: + if (!NO_MODIFIER(k->mod)) + return 0; + new_palette = max_palette - 1; + break; + case SDLK_PAGEDOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + new_palette += 16; + break; + case SDLK_RETURN: + if (!NO_MODIFIER(k->mod)) + return 0; + if (selected_palette == -1) return 1; + palette_load_preset(selected_palette); + palette_apply(); + update_thumbbars(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_RIGHT: + case SDLK_TAB: + if (k->mod & KMOD_SHIFT) { + change_focus_to(focus_offsets[selected_palette+1] + 29); + return 1; + } + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(focus_offsets[selected_palette+1] + 8); + return 1; + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(focus_offsets[selected_palette+1] + 29); + return 1; + default: + if (k->mouse == MOUSE_NONE) + return 0; + } + + if (new_palette < -1) new_palette = -1; + else if (new_palette >= (max_palette-1)) new_palette = (max_palette-1); + if (new_palette != selected_palette) { + selected_palette = new_palette; + status.flags |= NEED_UPDATE; + } - return 1; + return 1; } /* --------------------------------------------------------------------- */ static void palette_list_handle_key(struct key_event * k) { - int n = *selected_widget; + int n = *selected_widget; - if (!NO_MODIFIER(k->mod)) - return; + if (!NO_MODIFIER(k->mod)) + return; - if (k->state) return; + if (k->state == KEY_RELEASE) + return; - switch (k->sym) { - case SDLK_PAGEUP: - n -= 3; - break; - case SDLK_PAGEDOWN: - n += 3; - break; - default: - return; - } - - if (status.flags & CLASSIC_MODE) { - if (n < 0) - return; - if (n > 48) - n = 48; - } else { - n = CLAMP(n, 0, 48); - } - if (n != *selected_widget) - change_focus_to(n); + switch (k->sym) { + case SDLK_PAGEUP: + n -= 3; + break; + case SDLK_PAGEDOWN: + n += 3; + break; + default: + return; + } + + if (status.flags & CLASSIC_MODE) { + if (n < 0) + return; + if (n > 48) + n = 48; + } else { + n = CLAMP(n, 0, 48); + } + if (n != *selected_widget) + change_focus_to(n); } /* --------------------------------------------------------------------- */ @@ -258,55 +264,55 @@ static void update_palette(void) { - int n; + int n; - for (n = 0; n < 16; n++) { - current_palette[n][0] = widgets_palette[3 * n].d.thumbbar.value; - current_palette[n][1] = widgets_palette[3 * n + 1].d.thumbbar.value; - current_palette[n][2] = widgets_palette[3 * n + 2].d.thumbbar.value; - } - selected_palette = current_palette_index = -1; - palette_apply(); - status.flags |= NEED_UPDATE; + for (n = 0; n < 16; n++) { + current_palette[n][0] = widgets_palette[3 * n].d.thumbbar.value; + current_palette[n][1] = widgets_palette[3 * n + 1].d.thumbbar.value; + current_palette[n][2] = widgets_palette[3 * n + 2].d.thumbbar.value; + } + selected_palette = current_palette_index = -1; + palette_apply(); + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ void palette_load_page(struct page *page) { - int n; + int n; - page->title = "Palette Configuration (Ctrl-F12)"; - page->draw_const = palette_draw_const; - page->handle_key = palette_list_handle_key; - page->total_widgets = 49; - page->widgets = widgets_palette; - page->help_index = HELP_GLOBAL; - - selected_palette = current_palette_index; - - for (n = 0; n < 16; n++) { - int tabs[3] = { 3 * n + 21, 3 * n + 22, 3 * n + 23 }; - if (n >= 9 && n <= 13) { - tabs[0] = tabs[1] = tabs[2] = 48; - } else if (n > 13) { - tabs[0] = 3 * n - 42; - tabs[1] = 3 * n - 41; - tabs[2] = 3 * n - 40; - } - create_thumbbar(widgets_palette + (3 * n), 10 + 27 * (n / 7), 5 * (n % 7) + 14, 9, - n ? (3 * n - 1) : 0, 3 * n + 1, tabs[0], update_palette, 0, 63); - create_thumbbar(widgets_palette + (3 * n + 1), 10 + 27 * (n / 7), 5 * (n % 7) + 15, 9, - 3 * n, 3 * n + 2, tabs[1], update_palette, 0, 63); - create_thumbbar(widgets_palette + (3 * n + 2), 10 + 27 * (n / 7), 5 * (n % 7) + 16, 9, - 3 * n + 1, 3 * n + 3, tabs[2], update_palette, 0, 63); - } - update_thumbbars(); - - create_other(widgets_palette + 48, 0, palette_list_handle_key_on_list, palette_list_draw); - widgets_palette[48].x = 56; - widgets_palette[48].y = 27; - widgets_palette[48].width = 20; - widgets_palette[48].height = 19; + page->title = "Palette Configuration (Ctrl-F12)"; + page->draw_const = palette_draw_const; + page->handle_key = palette_list_handle_key; + page->total_widgets = 49; + page->widgets = widgets_palette; + page->help_index = HELP_GLOBAL; + + selected_palette = current_palette_index; + + for (n = 0; n < 16; n++) { + int tabs[3] = { 3 * n + 21, 3 * n + 22, 3 * n + 23 }; + if (n >= 9 && n <= 13) { + tabs[0] = tabs[1] = tabs[2] = 48; + } else if (n > 13) { + tabs[0] = 3 * n - 42; + tabs[1] = 3 * n - 41; + tabs[2] = 3 * n - 40; + } + create_thumbbar(widgets_palette + (3 * n), 10 + 27 * (n / 7), 5 * (n % 7) + 14, 9, + n ? (3 * n - 1) : 0, 3 * n + 1, tabs[0], update_palette, 0, 63); + create_thumbbar(widgets_palette + (3 * n + 1), 10 + 27 * (n / 7), 5 * (n % 7) + 15, 9, + 3 * n, 3 * n + 2, tabs[1], update_palette, 0, 63); + create_thumbbar(widgets_palette + (3 * n + 2), 10 + 27 * (n / 7), 5 * (n % 7) + 16, 9, + 3 * n + 1, 3 * n + 3, tabs[2], update_palette, 0, 63); + } + update_thumbbars(); + + create_other(widgets_palette + 48, 0, palette_list_handle_key_on_list, palette_list_draw); + widgets_palette[48].x = 56; + widgets_palette[48].y = 27; + widgets_palette[48].width = 20; + widgets_palette[48].height = 19; } diff -Nru schism-0+20110101/schism/page_patedit.c schism-20160521/schism/page_patedit.c --- schism-0+20110101/schism/page_patedit.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_patedit.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -65,11 +65,11 @@ static int template_mode = TEMPLATE_OFF; static const char *template_mode_names[] = { - "", - "Template, Overwrite", - "Template, Mix - Pattern data precedence", - "Template, Mix - Clipboard data precedence", - "Template, Notes only", + "", + "Template, Overwrite", + "Template, Mix - Pattern data precedence", + "Template, Mix - Clipboard data precedence", + "Template, Notes only", }; /* only one widget, but MAN is it complicated :) */ @@ -131,32 +131,45 @@ static int fast_volume_percent = 67; static int fast_volume_mode = 0; /* toggled with ctrl-j */ +enum { + COPY_INST_OFF = 0, /* no search (IT style) */ + COPY_INST_UP = 1, /* search above the cursor for an instrument number */ + COPY_INST_UP_THEN_DOWN = 2, /* search both ways, up to row 0 first, then down */ + COPY_INST_SENTINEL = 3, /* non-value */ +}; +static int mask_copy_search_mode = COPY_INST_OFF; + +/* If nonzero, home/end will move to the first/last row in the current channel +prior to moving to the first/last channel, i.e. operating in a 'z' pattern. +This is closer to FT2's behavior for the keys. */ +static int invert_home_end = 0; + /* --------------------------------------------------------------------- */ /* undo and clipboard handling */ struct pattern_snap { - song_note_t *data; - int channels; - int rows; - - /* used by undo/history only */ - const char *snap_op; - int snap_op_allocated; - int x, y; - int patternno; + song_note_t *data; + int channels; + int rows; + + /* used by undo/history only */ + const char *snap_op; + int snap_op_allocated; + int x, y; + int patternno; }; static struct pattern_snap fast_save = { - NULL, 0, 0, - "Fast Pattern Save", - 0, 0, 0, -1 + NULL, 0, 0, + "Fast Pattern Save", + 0, 0, 0, -1 }; /* static int fast_save_validity = -1; */ static void snap_paste(struct pattern_snap *s, int x, int y, int xlate); static struct pattern_snap clipboard = { - NULL, 0, 0, - "Clipboard", - 0, 0, 0, -1 + NULL, 0, 0, + "Clipboard", + 0, 0, 0, -1 }; static struct pattern_snap undo_history[10]; static int undo_history_top = 0; @@ -164,17 +177,17 @@ /* this function is stupid, it doesn't belong here */ void memused_get_pattern_saved(unsigned int *a, unsigned int *b) { - int i; - if (b) { - for (i = 0; i < 10; i++) { - if (undo_history[i].data) - *b = (*b) + undo_history[i].rows; - } - } - if (a) { - if (clipboard.data) (*a) = (*a) + clipboard.rows; - if (fast_save.data) (*a) = (*a) + fast_save.rows; - } + int i; + if (b) { + for (i = 0; i < 10; i++) { + if (undo_history[i].data) + *b = (*b) + undo_history[i].rows; + } + } + if (a) { + if (clipboard.data) (*a) = (*a) + clipboard.rows; + if (fast_save.data) (*a) = (*a) + fast_save.rows; + } } @@ -184,16 +197,16 @@ /* *INDENT-OFF* */ static struct { - int first_channel; - int last_channel; - int first_row; - int last_row; + int first_channel; + int last_channel; + int first_row; + int last_row; } selection = { 0, 0, 0, 0 }; static struct { - int in_progress; - int first_channel; - int first_row; + int in_progress; + int first_channel; + int first_row; } shift_selection = { 0, 0, 0 }; /* *INDENT-ON* */ @@ -211,31 +224,31 @@ will display an error dialog and cause the function to return if there is no block marked. (The spaces around the text are to make it line up the same as Impulse Tracker) */ #define CHECK_FOR_SELECTION(q) do {\ - if (!SELECTION_EXISTS) {\ - dialog_create(DIALOG_OK, " No block is marked ", NULL, NULL, 0, NULL);\ - q;\ - }\ + if (!SELECTION_EXISTS) {\ + dialog_create(DIALOG_OK, " No block is marked ", NULL, NULL, 0, NULL);\ + q;\ + }\ } while(0) /* --------------------------------------------------------------------- */ /* this is for the multiple track views stuff. */ struct track_view { - int width; - draw_channel_header_func draw_channel_header; - draw_note_func draw_note; - draw_mask_func draw_mask; + int width; + draw_channel_header_func draw_channel_header; + draw_note_func draw_note; + draw_mask_func draw_mask; }; static const struct track_view track_views[] = { #define TRACK_VIEW(n) {n, draw_channel_header_##n, draw_note_##n, draw_mask_##n} - TRACK_VIEW(13), /* 5 channels */ - TRACK_VIEW(10), /* 6/7 channels */ - TRACK_VIEW(7), /* 9/10 channels */ - TRACK_VIEW(6), /* 10/12 channels */ - TRACK_VIEW(3), /* 18/24 channels */ - TRACK_VIEW(2), /* 24/36 channels */ - TRACK_VIEW(1), /* 36/64 channels */ + TRACK_VIEW(13), /* 5 channels */ + TRACK_VIEW(10), /* 6/7 channels */ + TRACK_VIEW(7), /* 9/10 channels */ + TRACK_VIEW(6), /* 10/12 channels */ + TRACK_VIEW(3), /* 18/24 channels */ + TRACK_VIEW(2), /* 24/36 channels */ + TRACK_VIEW(1), /* 36/64 channels */ #undef TRACK_VIEW }; @@ -260,102 +273,102 @@ static void options_close_cancel(UNUSED void *data) { - kbd_set_current_octave(options_last_octave); + kbd_set_current_octave(options_last_octave); } static void options_close(void *data) { - int old_size, new_size; + int old_size, new_size; - options_selected_widget = ((struct dialog *) data)->selected_widget; + options_selected_widget = ((struct dialog *) data)->selected_widget; - skip_value = options_widgets[1].d.thumbbar.value; - current_song->row_highlight_minor = options_widgets[2].d.thumbbar.value; - current_song->row_highlight_major = options_widgets[3].d.thumbbar.value; - link_effect_column = !!(options_widgets[5].d.togglebutton.state); - status.flags |= SONG_NEEDS_SAVE; - - old_size = song_get_pattern(current_pattern, NULL); - new_size = options_widgets[4].d.thumbbar.value; - if (old_size != new_size) { - song_pattern_resize(current_pattern, new_size); - current_row = MIN(current_row, new_size - 1); - pattern_editor_reposition(); - } + skip_value = options_widgets[1].d.thumbbar.value; + current_song->row_highlight_minor = options_widgets[2].d.thumbbar.value; + current_song->row_highlight_major = options_widgets[3].d.thumbbar.value; + link_effect_column = !!(options_widgets[5].d.togglebutton.state); + status.flags |= SONG_NEEDS_SAVE; + + old_size = song_get_pattern(current_pattern, NULL); + new_size = options_widgets[4].d.thumbbar.value; + if (old_size != new_size) { + song_pattern_resize(current_pattern, new_size); + current_row = MIN(current_row, new_size - 1); + pattern_editor_reposition(); + } } static void options_draw_const(void) { - draw_text("Pattern Editor Options", 28, 19, 0, 2); - draw_text("Base octave", 28, 23, 0, 2); - draw_text("Cursor step", 28, 26, 0, 2); - draw_text("Row hilight minor", 22, 29, 0, 2); - draw_text("Row hilight major", 22, 32, 0, 2); - draw_text("Number of rows in pattern", 14, 35, 0, 2); - draw_text("Command/Value columns", 18, 38, 0, 2); - - draw_box(39, 22, 42, 24, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(39, 25, 43, 27, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(39, 28, 45, 30, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(39, 31, 57, 33, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(39, 34, 62, 36, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Pattern Editor Options", 28, 19, 0, 2); + draw_text("Base octave", 28, 23, 0, 2); + draw_text("Cursor step", 28, 26, 0, 2); + draw_text("Row hilight minor", 22, 29, 0, 2); + draw_text("Row hilight major", 22, 32, 0, 2); + draw_text("Number of rows in pattern", 14, 35, 0, 2); + draw_text("Command/Value columns", 18, 38, 0, 2); + + draw_box(39, 22, 42, 24, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(39, 25, 43, 27, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(39, 28, 45, 30, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(39, 31, 57, 33, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(39, 34, 62, 36, BOX_THIN | BOX_INNER | BOX_INSET); } static void options_change_base_octave(void) { - kbd_set_current_octave(options_widgets[0].d.thumbbar.value); + kbd_set_current_octave(options_widgets[0].d.thumbbar.value); } /* the base octave is changed directly when the thumbbar is changed. * anything else can wait until the dialog is closed. */ void pattern_editor_display_options(void) { - struct dialog *dialog; + struct dialog *dialog; - if (options_widgets[0].width == 0) { - /* haven't built it yet */ - create_thumbbar(options_widgets + 0, 40, 23, 2, 7, 1, 1, options_change_base_octave, 0, 8); - create_thumbbar(options_widgets + 1, 40, 26, 3, 0, 2, 2, NULL, 0, 16); - create_thumbbar(options_widgets + 2, 40, 29, 5, 1, 3, 3, NULL, 0, 32); - create_thumbbar(options_widgets + 3, 40, 32, 17, 2, 4, 4, NULL, 0, 128); - /* Although patterns as small as 1 row can be edited properly (as of c759f7a0166c), I have - discovered it's a bit annoying to hit 'home' here expecting to get 32 rows but end up with - just one row instead. so I'll allow editing these patterns, but not really provide a way to - set the size, at least until I decide how to present the option nonintrusively. */ - create_thumbbar(options_widgets + 4, 40, 35, 22, 3, 5, 5, NULL, 32, 200); - create_togglebutton(options_widgets + 5, 40, 38, 8, 4, 7, 6, 6, 6, - NULL, "Link", 3, options_link_split); - create_togglebutton(options_widgets + 6, 52, 38, 9, 4, 7, 5, 5, 5, - NULL, "Split", 3, options_link_split); - create_button(options_widgets + 7, 35, 41, 8, 5, 0, 7, 7, 7, dialog_yes_NULL, "Done", 3); - } - - options_last_octave = kbd_get_current_octave(); - options_widgets[0].d.thumbbar.value = options_last_octave; - options_widgets[1].d.thumbbar.value = skip_value; - options_widgets[2].d.thumbbar.value = current_song->row_highlight_minor; - options_widgets[3].d.thumbbar.value = current_song->row_highlight_major; - options_widgets[4].d.thumbbar.value = song_get_pattern(current_pattern, NULL); - togglebutton_set(options_widgets, link_effect_column ? 5 : 6, 0); - - dialog = dialog_create_custom(10, 18, 60, 26, options_widgets, 8, options_selected_widget, - options_draw_const, NULL); - dialog->action_yes = options_close; - if (status.flags & CLASSIC_MODE) { - dialog->action_cancel = options_close; - } else { - dialog->action_cancel = options_close_cancel; - } - dialog->data = dialog; + if (options_widgets[0].width == 0) { + /* haven't built it yet */ + create_thumbbar(options_widgets + 0, 40, 23, 2, 7, 1, 1, options_change_base_octave, 0, 8); + create_thumbbar(options_widgets + 1, 40, 26, 3, 0, 2, 2, NULL, 0, 16); + create_thumbbar(options_widgets + 2, 40, 29, 5, 1, 3, 3, NULL, 0, 32); + create_thumbbar(options_widgets + 3, 40, 32, 17, 2, 4, 4, NULL, 0, 128); + /* Although patterns as small as 1 row can be edited properly (as of c759f7a0166c), I have + discovered it's a bit annoying to hit 'home' here expecting to get 32 rows but end up with + just one row instead. so I'll allow editing these patterns, but not really provide a way to + set the size, at least until I decide how to present the option nonintrusively. */ + create_thumbbar(options_widgets + 4, 40, 35, 22, 3, 5, 5, NULL, 32, 200); + create_togglebutton(options_widgets + 5, 40, 38, 8, 4, 7, 6, 6, 6, + NULL, "Link", 3, options_link_split); + create_togglebutton(options_widgets + 6, 52, 38, 9, 4, 7, 5, 5, 5, + NULL, "Split", 3, options_link_split); + create_button(options_widgets + 7, 35, 41, 8, 5, 0, 7, 7, 7, dialog_yes_NULL, "Done", 3); + } + + options_last_octave = kbd_get_current_octave(); + options_widgets[0].d.thumbbar.value = options_last_octave; + options_widgets[1].d.thumbbar.value = skip_value; + options_widgets[2].d.thumbbar.value = current_song->row_highlight_minor; + options_widgets[3].d.thumbbar.value = current_song->row_highlight_major; + options_widgets[4].d.thumbbar.value = song_get_pattern(current_pattern, NULL); + togglebutton_set(options_widgets, link_effect_column ? 5 : 6, 0); + + dialog = dialog_create_custom(10, 18, 60, 26, options_widgets, 8, options_selected_widget, + options_draw_const, NULL); + dialog->action_yes = options_close; + if (status.flags & CLASSIC_MODE) { + dialog->action_cancel = options_close; + } else { + dialog->action_cancel = options_close_cancel; + } + dialog->data = dialog; } static struct widget template_error_widgets[1]; static void template_error_draw(void) { - draw_text("Template Error", 33, 25, 0, 2); - draw_text("No note in the top left position", 23, 27, 0, 2); - draw_text("of the clipboard on which to", 25, 28, 0, 2); - draw_text("base translations.", 31, 29, 0, 2); + draw_text("Template Error", 33, 25, 0, 2); + draw_text("No note in the top left position", 23, 27, 0, 2); + draw_text("of the clipboard on which to", 25, 28, 0, 2); + draw_text("base translations.", 31, 29, 0, 2); } /* --------------------------------------------------------------------------------------------------------- */ @@ -363,53 +376,53 @@ static struct widget length_edit_widgets[4]; static void length_edit_draw_const(void) { - draw_box(33,23,56,25, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(33,26,60,29, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(33,23,56,25, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(33,26,60,29, BOX_THIN | BOX_INNER | BOX_INSET); - draw_text("Set Pattern Length", 31, 21, 0, 2); - draw_text("Pattern Length", 19, 24, 0, 2); - draw_text("Start Pattern", 20, 27, 0, 2); - draw_text("End Pattern", 22, 28, 0, 2); + draw_text("Set Pattern Length", 31, 21, 0, 2); + draw_text("Pattern Length", 19, 24, 0, 2); + draw_text("Start Pattern", 20, 27, 0, 2); + draw_text("End Pattern", 22, 28, 0, 2); } static void length_edit_close(UNUSED void *data) { - int i, nl; - nl = length_edit_widgets[0].d.thumbbar.value; - status.flags |= SONG_NEEDS_SAVE; - for (i = length_edit_widgets[1].d.thumbbar.value; - i <= length_edit_widgets[2].d.thumbbar.value; i++) { - if (song_get_pattern(i, NULL) != nl) { - song_pattern_resize(i, nl); - if (i == current_pattern) { - status.flags |= NEED_UPDATE; - current_row = MIN(current_row, nl - 1); - pattern_editor_reposition(); - } - } - } + int i, nl; + nl = length_edit_widgets[0].d.thumbbar.value; + status.flags |= SONG_NEEDS_SAVE; + for (i = length_edit_widgets[1].d.thumbbar.value; + i <= length_edit_widgets[2].d.thumbbar.value; i++) { + if (song_get_pattern(i, NULL) != nl) { + song_pattern_resize(i, nl); + if (i == current_pattern) { + status.flags |= NEED_UPDATE; + current_row = MIN(current_row, nl - 1); + pattern_editor_reposition(); + } + } + } } static void length_edit_cancel(UNUSED void *data) { - /* do nothing */ + /* do nothing */ } void pattern_editor_length_edit(void) { - struct dialog *dialog; + struct dialog *dialog; - create_thumbbar(length_edit_widgets + 0, 34, 24, 22, 0, 1, 1, NULL, 32, 200); - length_edit_widgets[0].d.thumbbar.value = song_get_pattern(current_pattern, NULL ); - create_thumbbar(length_edit_widgets + 1, 34, 27, 26, 0, 2, 2, NULL, 0, 199); - create_thumbbar(length_edit_widgets + 2, 34, 28, 26, 1, 3, 3, NULL, 0, 199); - length_edit_widgets[1].d.thumbbar.value - = length_edit_widgets[2].d.thumbbar.value - = current_pattern; - - create_button(length_edit_widgets + 3, 35, 31, 8, 2, 3, 3, 3, 0, dialog_yes_NULL, "OK", 4); - - dialog = dialog_create_custom(15, 19, 51, 15, length_edit_widgets, 4, 0, - length_edit_draw_const, NULL); - dialog->action_yes = length_edit_close; - dialog->action_cancel = length_edit_cancel; + create_thumbbar(length_edit_widgets + 0, 34, 24, 22, 0, 1, 1, NULL, 32, 200); + length_edit_widgets[0].d.thumbbar.value = song_get_pattern(current_pattern, NULL ); + create_thumbbar(length_edit_widgets + 1, 34, 27, 26, 0, 2, 2, NULL, 0, 199); + create_thumbbar(length_edit_widgets + 2, 34, 28, 26, 1, 3, 3, NULL, 0, 199); + length_edit_widgets[1].d.thumbbar.value + = length_edit_widgets[2].d.thumbbar.value + = current_pattern; + + create_button(length_edit_widgets + 3, 35, 31, 8, 2, 3, 3, 3, 0, dialog_yes_NULL, "OK", 4); + + dialog = dialog_create_custom(15, 19, 51, 15, length_edit_widgets, 4, 0, + length_edit_draw_const, NULL); + dialog->action_yes = length_edit_close; + dialog->action_cancel = length_edit_cancel; } /* --------------------------------------------------------------------------------------------------------- */ @@ -417,80 +430,80 @@ static struct widget multichannel_widgets[65]; static void multichannel_close(UNUSED void *data) { - int i, m = 0; + int i, m = 0; - for (i = 0; i < 64; i++) { - channel_multi[i] = !!multichannel_widgets[i].d.toggle.state; - if (channel_multi[i]) - m = 1; - } - if (m) - channel_multi_enabled = 1; + for (i = 0; i < 64; i++) { + channel_multi[i] = !!multichannel_widgets[i].d.toggle.state; + if (channel_multi[i]) + m = 1; + } + if (m) + channel_multi_enabled = 1; } static int multichannel_handle_key(struct key_event *k) { - if (k->sym == SDLK_n) { - if ((k->mod & KMOD_ALT) && !k->state) - dialog_yes(NULL); - else if (NO_MODIFIER(k->mod) && k->state) - dialog_cancel(NULL); - return 1; - } - return 0; + if (k->sym == SDLK_n) { + if ((k->mod & KMOD_ALT) && k->state == KEY_PRESS) + dialog_yes(NULL); + else if (NO_MODIFIER(k->mod) && k->state == KEY_RELEASE) + dialog_cancel(NULL); + return 1; + } + return 0; } static void multichannel_draw_const(void) { - char sbuf[16]; - int i; + char sbuf[16]; + int i; - for (i = 0; i < 64; i++) { - sprintf(sbuf, "Channel %02d", i+1); - draw_text(sbuf, - 9 + ((i / 16) * 16), /* X */ - 22 + (i % 16), /* Y */ - 0, 2); - } - for (i = 0; i < 64; i += 16) { - draw_box( - 19 + ((i / 16) * 16), /* X */ - 21, - 23 + ((i / 16) * 16), /* X */ - 38, - BOX_THIN|BOX_INNER|BOX_INSET); - } - draw_text("Multichannel Selection", 29, 19, 3, 2); + for (i = 0; i < 64; i++) { + sprintf(sbuf, "Channel %02d", i+1); + draw_text(sbuf, + 9 + ((i / 16) * 16), /* X */ + 22 + (i % 16), /* Y */ + 0, 2); + } + for (i = 0; i < 64; i += 16) { + draw_box( + 19 + ((i / 16) * 16), /* X */ + 21, + 23 + ((i / 16) * 16), /* X */ + 38, + BOX_THIN|BOX_INNER|BOX_INSET); + } + draw_text("Multichannel Selection", 29, 19, 3, 2); } static void mp_advance_channel(void) { - change_focus_to(*selected_widget + 1); + change_focus_to(*selected_widget + 1); } static void pattern_editor_display_multichannel(void) { - struct dialog *dialog; - int i; + struct dialog *dialog; + int i; - for (i = 0; i < 64; i++) { - create_toggle(multichannel_widgets+i, - 20 + ((i / 16) * 16), /* X */ - 22 + (i % 16), /* Y */ - - ((i % 16) == 0) ? 64 : (i-1), - ((i % 16) == 15) ? 64 : (i+1), - (i < 16) ? (i+48) : (i-16), - ((i + 16) % 64), - ((i + 16) % 64), - - mp_advance_channel); - multichannel_widgets[i].d.toggle.state = !!channel_multi[i]; - } - create_button(multichannel_widgets + 64, 36, 40, 6, 15, 0, 64, 64, 64, dialog_yes_NULL, "OK", 3); - - dialog = dialog_create_custom(7, 18, 66, 25, multichannel_widgets, 65, 0, - multichannel_draw_const, NULL); - dialog->action_yes = multichannel_close; - dialog->action_cancel = multichannel_close; - dialog->handle_key = multichannel_handle_key; + for (i = 0; i < 64; i++) { + create_toggle(multichannel_widgets+i, + 20 + ((i / 16) * 16), /* X */ + 22 + (i % 16), /* Y */ + + ((i % 16) == 0) ? 64 : (i-1), + ((i % 16) == 15) ? 64 : (i+1), + (i < 16) ? (i+48) : (i-16), + ((i + 16) % 64), + ((i + 16) % 64), + + mp_advance_channel); + multichannel_widgets[i].d.toggle.state = !!channel_multi[i]; + } + create_button(multichannel_widgets + 64, 36, 40, 6, 15, 0, 64, 64, 64, dialog_yes_NULL, "OK", 3); + + dialog = dialog_create_custom(7, 18, 66, 25, multichannel_widgets, 65, 0, + multichannel_draw_const, NULL); + dialog->action_yes = multichannel_close; + dialog->action_cancel = multichannel_close; + dialog->handle_key = multichannel_handle_key; } @@ -499,282 +512,282 @@ static int multichannel_get_next(int cur_channel) { - int i; + int i; - cur_channel--; /* make it zero-based. oh look, it's a hammer. */ - i = cur_channel; + cur_channel--; /* make it zero-based. oh look, it's a hammer. */ + i = cur_channel; - if (channel_multi[cur_channel]) { - /* we're in a multichan-enabled channel, so look for the next one */ - do { - i = (i + 1) & 63; /* no? next channel, and loop back to zero if we hit 64 */ - if (channel_multi[i]) /* is this a multi-channel? */ - break; /* it is! */ - } while (i != cur_channel); - - /* at this point we've either broken the loop because the channel i is multichan, - or the condition failed because we're back where we started */ - } - /* status_text_flash ("Newly selected channel is %d", (int) i + 1); */ - return i + 1; /* make it one-based again */ + if (channel_multi[cur_channel]) { + /* we're in a multichan-enabled channel, so look for the next one */ + do { + i = (i + 1) & 63; /* no? next channel, and loop back to zero if we hit 64 */ + if (channel_multi[i]) /* is this a multi-channel? */ + break; /* it is! */ + } while (i != cur_channel); + + /* at this point we've either broken the loop because the channel i is multichan, + or the condition failed because we're back where we started */ + } + /* status_text_flash ("Newly selected channel is %d", (int) i + 1); */ + return i + 1; /* make it one-based again */ } static int multichannel_get_previous(int cur_channel) { - int i; + int i; - cur_channel--; /* once again, .... */ - i = cur_channel; + cur_channel--; /* once again, .... */ + i = cur_channel; - if (channel_multi[cur_channel]) { - do { - i = i ? (i - 1) : 63; /* loop backwards this time */ - if (channel_multi[i]) - break; - } while (i != cur_channel); - } - return i + 1; + if (channel_multi[cur_channel]) { + do { + i = i ? (i - 1) : 63; /* loop backwards this time */ + if (channel_multi[i]) + break; + } while (i != cur_channel); + } + return i + 1; } /* --------------------------------------------------------------------------------------------------------- */ static void copyin_addnote(song_note_t *note, int *copyin_x, int *copyin_y) { - song_note_t *pattern, *p_note; - int num_rows; + song_note_t *pattern, *p_note; + int num_rows; - status.flags |= (SONG_NEEDS_SAVE|NEED_UPDATE); - num_rows = song_get_pattern(current_pattern, &pattern); - if ((*copyin_x + (current_channel-1)) >= 64) return; - if ((*copyin_y + current_row) >= num_rows) return; - p_note = pattern + 64 * (*copyin_y + current_row) + (*copyin_x + (current_channel-1)); - *p_note = *note; - (*copyin_x) = (*copyin_x) + 1; + status.flags |= (SONG_NEEDS_SAVE|NEED_UPDATE); + num_rows = song_get_pattern(current_pattern, &pattern); + if ((*copyin_x + (current_channel-1)) >= 64) return; + if ((*copyin_y + current_row) >= num_rows) return; + p_note = pattern + 64 * (*copyin_y + current_row) + (*copyin_x + (current_channel-1)); + *p_note = *note; + (*copyin_x) = (*copyin_x) + 1; } static void copyin_addrow(int *copyin_x, int *copyin_y) { - *copyin_x=0; - (*copyin_y) = (*copyin_y) + 1; + *copyin_x=0; + (*copyin_y) = (*copyin_y) + 1; } static int pattern_selection_system_paste(UNUSED int cb, const void *data) { - int copyin_x, copyin_y; - int (*fx_map)(char f); - const char *str; - song_note_t n; - int x, scantmp; - - if (!data) return 0; - str = (const char *)data; - - for (x = 0; str[x] && str[x] != '\n'; x++); - if (x <= 11) return 0; - if (!str[x] || str[x+1] != '|') return 0; - if (str[x-1] == '\r') x--; - if ((str[x-3] == ' ' && str[x-2] == 'I' && str[x-1] == 'T') - || (str[x-3] == 'S' && str[x-2] == '3' && str[x-1] == 'M')) { - /* s3m effects */ - fx_map = get_effect_number; - } else if ((str[x-3] == ' ' && str[x-2] == 'X' && str[x-1] == 'M') - || (str[x-3] == 'M' && str[x-2] == 'O' && str[x-1] == 'D')) { - /* ptm effects */ - fx_map = get_ptm_effect_number; - } else { - return 0; - } - if (str[x] == '\r') x++; - str += x+2; - copyin_x = copyin_y = 0; - /* okay, let's start parsing */ - while (*str) { - memset(&n, 0, sizeof(song_note_t)); - if (!str[0] || !str[1] || !str[2]) break; - switch (*str) { - case 'C': case 'c': n.note = 1; break; - case 'D': case 'd': n.note = 3; break; - case 'E': case 'e': n.note = 5; break; - case 'F': case 'f': n.note = 6; break; - case 'G': case 'g': n.note = 8; break; - case 'A': case 'a': n.note = 10;break; - case 'B': case 'b': n.note = 12;break; - default: n.note = 0; - }; - /* XXX shouldn't this be note-- for flat? */ - if (str[1] == '#' || str[1] == 'b') n.note++; - switch (*str) { - case '=': n.note = NOTE_OFF; break; - case '^': n.note = NOTE_CUT; break; - case '~': n.note = NOTE_FADE; break; - case ' ': case '.': n.note = 0; break; - default: - n.note += ((str[2] - '0') * 12); - break; - }; - str += 3; - /* instrument number */ - if (sscanf(str, "%02d", &scantmp) == 1) - n.instrument = scantmp; - else - n.instrument = 0; - str += 2; - while (*str) { - if (*str == '|' || *str == '\r' || *str == '\n') break; - if (!str[0] || !str[1] || !str[2]) break; - if (*str >= 'a' && *str <= 'z') { - if (sscanf(str+1, "%02d", &scantmp) == 1) - n.volparam = scantmp; - else - n.volparam = 0; - switch (*str) { - case 'v': n.voleffect = VOLFX_VOLUME; break; - case 'p': n.voleffect = VOLFX_PANNING; break; - case 'c': n.voleffect = VOLFX_VOLSLIDEUP; break; - case 'd': n.voleffect = VOLFX_VOLSLIDEDOWN; break; - case 'a': n.voleffect = VOLFX_FINEVOLUP; break; - case 'b': n.voleffect = VOLFX_FINEVOLDOWN; break; - case 'u': n.voleffect = VOLFX_VIBRATOSPEED; break; - case 'h': n.voleffect = VOLFX_VIBRATODEPTH; break; - case 'l': n.voleffect = VOLFX_PANSLIDELEFT; break; - case 'r': n.voleffect = VOLFX_PANSLIDERIGHT; break; - case 'g': n.voleffect = VOLFX_TONEPORTAMENTO; break; - case 'f': n.voleffect = VOLFX_PORTAUP; break; - case 'e': n.voleffect = VOLFX_PORTADOWN; break; - default: n.voleffect = VOLFX_NONE; n.volparam = 0; break; - }; - } else { - n.effect = fx_map(*str); - if (sscanf(str+1, "%02X", &scantmp) == 1) - n.param = scantmp; - else - n.param = 0; - } - str += 3; - } - copyin_addnote(&n, ©in_x, ©in_y); - if (str[0] == '\r' || str[0] == '\n') { - while (str[0] == '\r' || str[0] == '\n') str++; - copyin_addrow(©in_x, ©in_y); - } - if (str[0] != '|') break; - str++; - } - return 1; + int copyin_x, copyin_y; + int (*fx_map)(char f); + const char *str; + song_note_t n; + int x, scantmp; + + if (!data) return 0; + str = (const char *)data; + + for (x = 0; str[x] && str[x] != '\n'; x++); + if (x <= 11) return 0; + if (!str[x] || str[x+1] != '|') return 0; + if (str[x-1] == '\r') x--; + if ((str[x-3] == ' ' && str[x-2] == 'I' && str[x-1] == 'T') + || (str[x-3] == 'S' && str[x-2] == '3' && str[x-1] == 'M')) { + /* s3m effects */ + fx_map = get_effect_number; + } else if ((str[x-3] == ' ' && str[x-2] == 'X' && str[x-1] == 'M') + || (str[x-3] == 'M' && str[x-2] == 'O' && str[x-1] == 'D')) { + /* ptm effects */ + fx_map = get_ptm_effect_number; + } else { + return 0; + } + if (str[x] == '\r') x++; + str += x+2; + copyin_x = copyin_y = 0; + /* okay, let's start parsing */ + while (*str) { + memset(&n, 0, sizeof(song_note_t)); + if (!str[0] || !str[1] || !str[2]) break; + switch (*str) { + case 'C': case 'c': n.note = 1; break; + case 'D': case 'd': n.note = 3; break; + case 'E': case 'e': n.note = 5; break; + case 'F': case 'f': n.note = 6; break; + case 'G': case 'g': n.note = 8; break; + case 'A': case 'a': n.note = 10;break; + case 'B': case 'b': n.note = 12;break; + default: n.note = 0; + }; + /* XXX shouldn't this be note-- for flat? */ + if (str[1] == '#' || str[1] == 'b') n.note++; + switch (*str) { + case '=': n.note = NOTE_OFF; break; + case '^': n.note = NOTE_CUT; break; + case '~': n.note = NOTE_FADE; break; + case ' ': case '.': n.note = 0; break; + default: + n.note += ((str[2] - '0') * 12); + break; + }; + str += 3; + /* instrument number */ + if (sscanf(str, "%02d", &scantmp) == 1) + n.instrument = scantmp; + else + n.instrument = 0; + str += 2; + while (*str) { + if (*str == '|' || *str == '\r' || *str == '\n') break; + if (!str[0] || !str[1] || !str[2]) break; + if (*str >= 'a' && *str <= 'z') { + if (sscanf(str+1, "%02d", &scantmp) == 1) + n.volparam = scantmp; + else + n.volparam = 0; + switch (*str) { + case 'v': n.voleffect = VOLFX_VOLUME; break; + case 'p': n.voleffect = VOLFX_PANNING; break; + case 'c': n.voleffect = VOLFX_VOLSLIDEUP; break; + case 'd': n.voleffect = VOLFX_VOLSLIDEDOWN; break; + case 'a': n.voleffect = VOLFX_FINEVOLUP; break; + case 'b': n.voleffect = VOLFX_FINEVOLDOWN; break; + case 'u': n.voleffect = VOLFX_VIBRATOSPEED; break; + case 'h': n.voleffect = VOLFX_VIBRATODEPTH; break; + case 'l': n.voleffect = VOLFX_PANSLIDELEFT; break; + case 'r': n.voleffect = VOLFX_PANSLIDERIGHT; break; + case 'g': n.voleffect = VOLFX_TONEPORTAMENTO; break; + case 'f': n.voleffect = VOLFX_PORTAUP; break; + case 'e': n.voleffect = VOLFX_PORTADOWN; break; + default: n.voleffect = VOLFX_NONE; n.volparam = 0; break; + }; + } else { + n.effect = fx_map(*str); + if (sscanf(str+1, "%02X", &scantmp) == 1) + n.param = scantmp; + else + n.param = 0; + } + str += 3; + } + copyin_addnote(&n, ©in_x, ©in_y); + if (str[0] == '\r' || str[0] == '\n') { + while (str[0] == '\r' || str[0] == '\n') str++; + copyin_addrow(©in_x, ©in_y); + } + if (str[0] != '|') break; + str++; + } + return 1; } static void pattern_selection_system_copyout(void) { - char *str; - int x, y, len; - int total_rows; - song_note_t *pattern, *cur_note; - - - if (!(SELECTION_EXISTS)) { - if (clippy_owner(CLIPPY_SELECT) == widgets_pattern) { - /* unselect if we don't have a selection */ - clippy_select(NULL, NULL, 0); - } - return; - } - - len = 21; - total_rows = song_get_pattern(current_pattern, &pattern); - for (y = selection.first_row; y <= selection.last_row && y < total_rows; y++) { - for (x = selection.first_channel; x <= selection.last_channel; x++) { - /* must match template below */ - len += 12; - } - len += 2; - } - str = mem_alloc(len+1); - /* the OpenMPT/ModPlug header says: - ModPlug Tracker S3M\x0d\x0a - - but really we can get away with: - Pasted Pattern - IT\x0d\x0a - - because that's just how it's parser works. Add your own- just - remember the file "type" is right-aligned. Please don't invent - any new formats- even if you add more effects, try to base most of - them on protracker (XM/MOD) or S3M/IT. - - */ - strcpy(str, "Pasted Pattern - IT\x0d\x0a"); - len = 21; - for (y = selection.first_row; y <= selection.last_row && y < total_rows; y++) { - cur_note = pattern + 64 * y - + selection.first_channel - 1; - for (x = selection.first_channel; x <= selection.last_channel; x++) { - str[len] = '|'; len++; - if (cur_note->note == 0) { - str[len] = str[len+1] = str[len+2] = '.'; /* ... */ - } else if (cur_note->note == NOTE_CUT) { - str[len] = str[len+1] = str[len+2] = '^'; /* ^^^ */ - } else if (cur_note->note == NOTE_OFF) { - str[len] = str[len+1] = str[len+2] = '='; /* === */ - } else if (cur_note->note == NOTE_FADE) { - /* ModPlug won't handle this one, but it'll - just drop it... - */ - str[len] = str[len+1] = str[len+2] = '~'; /* ~~~ */ - } else { - get_note_string(cur_note->note, str+len); - } - len += 3; - if (cur_note->instrument) - sprintf(str+len, "%02d", cur_note->instrument); - else - str[len] = str[len+1] = '.'; - sprintf(str+len+3, "%02d", cur_note->volparam); - switch (cur_note->voleffect) { - case VOLFX_VOLUME: str[len+2] = 'v';break; - case VOLFX_PANNING: str[len+2] = 'p';break; - case VOLFX_VOLSLIDEUP: str[len+2] = 'c';break; - case VOLFX_VOLSLIDEDOWN: str[len+2] = 'd';break; - case VOLFX_FINEVOLUP: str[len+2] = 'a';break; - case VOLFX_FINEVOLDOWN: str[len+2] = 'b';break; - case VOLFX_VIBRATOSPEED: str[len+2] = 'u';break; - case VOLFX_VIBRATODEPTH: str[len+2] = 'h';break; - case VOLFX_PANSLIDELEFT: str[len+2] = 'l';break; - case VOLFX_PANSLIDERIGHT: str[len+2] = 'r';break; - case VOLFX_TONEPORTAMENTO: str[len+2] = 'g';break; - case VOLFX_PORTAUP: str[len+2] = 'f';break; - case VOLFX_PORTADOWN: str[len+2] = 'e';break; - default: str[len+2] = '.'; - /* override above */ - str[len+3] = '.'; - str[len+4] = '.'; - }; - len += 5; - sprintf(str+len, "%c%02X", - get_effect_char(cur_note->effect), - cur_note->param); - if (str[len] == '.' || str[len] == '?') { - str[len] = '.'; - if (!cur_note->param) - str[len+1] = str[len+2] = '.'; - } - len += 3; - /* Hints to implementors: - - If you had more columns in your channel, you should - mark it here with a letter representing the channel - semantic, followed by your decimal value. - - Add as many as you like- the next channel begins with - a pipe-character (|) and the next row begins with a - 0D 0A sequence. - - */ - cur_note++; - } - str[len] = '\x0d'; - str[len+1] = '\x0a'; - len += 2; - } - str[len] = 0; - clippy_select(widgets_pattern, str, len); + char *str; + int x, y, len; + int total_rows; + song_note_t *pattern, *cur_note; + + + if (!(SELECTION_EXISTS)) { + if (clippy_owner(CLIPPY_SELECT) == widgets_pattern) { + /* unselect if we don't have a selection */ + clippy_select(NULL, NULL, 0); + } + return; + } + + len = 21; + total_rows = song_get_pattern(current_pattern, &pattern); + for (y = selection.first_row; y <= selection.last_row && y < total_rows; y++) { + for (x = selection.first_channel; x <= selection.last_channel; x++) { + /* must match template below */ + len += 12; + } + len += 2; + } + str = mem_alloc(len+1); + /* the OpenMPT/ModPlug header says: + ModPlug Tracker S3M\x0d\x0a + + but really we can get away with: + Pasted Pattern - IT\x0d\x0a + + because that's just how it's parser works. Add your own- just + remember the file "type" is right-aligned. Please don't invent + any new formats- even if you add more effects, try to base most of + them on protracker (XM/MOD) or S3M/IT. + + */ + strcpy(str, "Pasted Pattern - IT\x0d\x0a"); + len = 21; + for (y = selection.first_row; y <= selection.last_row && y < total_rows; y++) { + cur_note = pattern + 64 * y + + selection.first_channel - 1; + for (x = selection.first_channel; x <= selection.last_channel; x++) { + str[len] = '|'; len++; + if (cur_note->note == 0) { + str[len] = str[len+1] = str[len+2] = '.'; /* ... */ + } else if (cur_note->note == NOTE_CUT) { + str[len] = str[len+1] = str[len+2] = '^'; /* ^^^ */ + } else if (cur_note->note == NOTE_OFF) { + str[len] = str[len+1] = str[len+2] = '='; /* === */ + } else if (cur_note->note == NOTE_FADE) { + /* ModPlug won't handle this one, but it'll + just drop it... + */ + str[len] = str[len+1] = str[len+2] = '~'; /* ~~~ */ + } else { + get_note_string(cur_note->note, str+len); + } + len += 3; + if (cur_note->instrument) + sprintf(str+len, "%02d", cur_note->instrument); + else + str[len] = str[len+1] = '.'; + sprintf(str+len+3, "%02d", cur_note->volparam); + switch (cur_note->voleffect) { + case VOLFX_VOLUME: str[len+2] = 'v';break; + case VOLFX_PANNING: str[len+2] = 'p';break; + case VOLFX_VOLSLIDEUP: str[len+2] = 'c';break; + case VOLFX_VOLSLIDEDOWN: str[len+2] = 'd';break; + case VOLFX_FINEVOLUP: str[len+2] = 'a';break; + case VOLFX_FINEVOLDOWN: str[len+2] = 'b';break; + case VOLFX_VIBRATOSPEED: str[len+2] = 'u';break; + case VOLFX_VIBRATODEPTH: str[len+2] = 'h';break; + case VOLFX_PANSLIDELEFT: str[len+2] = 'l';break; + case VOLFX_PANSLIDERIGHT: str[len+2] = 'r';break; + case VOLFX_TONEPORTAMENTO: str[len+2] = 'g';break; + case VOLFX_PORTAUP: str[len+2] = 'f';break; + case VOLFX_PORTADOWN: str[len+2] = 'e';break; + default: str[len+2] = '.'; + /* override above */ + str[len+3] = '.'; + str[len+4] = '.'; + }; + len += 5; + sprintf(str+len, "%c%02X", + get_effect_char(cur_note->effect), + cur_note->param); + if (str[len] == '.' || str[len] == '?') { + str[len] = '.'; + if (!cur_note->param) + str[len+1] = str[len+2] = '.'; + } + len += 3; + /* Hints to implementors: + + If you had more columns in your channel, you should + mark it here with a letter representing the channel + semantic, followed by your decimal value. + + Add as many as you like- the next channel begins with + a pipe-character (|) and the next row begins with a + 0D 0A sequence. + + */ + cur_note++; + } + str[len] = '\x0d'; + str[len+1] = '\x0a'; + len += 2; + } + str[len] = 0; + clippy_select(widgets_pattern, str, len); } /* --------------------------------------------------------------------------------------------------------- */ @@ -785,83 +798,87 @@ static void history_draw_const(void) { - int i, j; - int fg, bg; - draw_text("Undo", 38, 22, 3, 2); - draw_box(19,23,60,34, BOX_THIN | BOX_INNER | BOX_INSET); - j = undo_history_top; - for (i = 0; i < 10; i++) { - if (i == undo_selection) { - fg = 0; bg = 3; - } else { - fg = 2; bg = 0; - } - - draw_char(32, 20, 24+i, fg, bg); - draw_text_len(undo_history[j].snap_op, 39, 21, 24+i, fg, bg); - j--; - if (j < 0) j += 10; - } + int i, j; + int fg, bg; + draw_text("Undo", 38, 22, 3, 2); + draw_box(19,23,60,34, BOX_THIN | BOX_INNER | BOX_INSET); + j = undo_history_top; + for (i = 0; i < 10; i++) { + if (i == undo_selection) { + fg = 0; bg = 3; + } else { + fg = 2; bg = 0; + } + + draw_char(32, 20, 24+i, fg, bg); + draw_text_len(undo_history[j].snap_op, 39, 21, 24+i, fg, bg); + j--; + if (j < 0) j += 10; + } } static void history_close(UNUSED void *data) { - /* nothing! */ + /* nothing! */ } static int history_handle_key(struct key_event *k) { - int i,j; - if (! NO_MODIFIER(k->mod)) return 0; - switch (k->sym) { - case SDLK_ESCAPE: - if (!k->state) return 0; - dialog_cancel(NULL); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_UP: - if (k->state) return 0; - undo_selection--; - if (undo_selection < 0) undo_selection = 0; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_DOWN: - if (k->state) return 0; - undo_selection++; - if (undo_selection > 9) undo_selection = 9; - status.flags |= NEED_UPDATE; - return 1; - case SDLK_RETURN: - if (k->state) return 0; - j = undo_history_top; - for (i = 0; i < 10; i++) { - if (i == undo_selection) { - pated_history_restore(j); - break; - } - j--; - if (j < 0) j += 10; - } - dialog_cancel(NULL); - status.flags |= NEED_UPDATE; - return 1; - default: - break; - }; + int i,j; + if (! NO_MODIFIER(k->mod)) return 0; + switch (k->sym) { + case SDLK_ESCAPE: + if (k->state == KEY_PRESS) + return 0; + dialog_cancel(NULL); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + undo_selection--; + if (undo_selection < 0) undo_selection = 0; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + undo_selection++; + if (undo_selection > 9) undo_selection = 9; + status.flags |= NEED_UPDATE; + return 1; + case SDLK_RETURN: + if (k->state == KEY_RELEASE) + return 0; + j = undo_history_top; + for (i = 0; i < 10; i++) { + if (i == undo_selection) { + pated_history_restore(j); + break; + } + j--; + if (j < 0) j += 10; + } + dialog_cancel(NULL); + status.flags |= NEED_UPDATE; + return 1; + default: + break; + }; - return 0; + return 0; } static void pattern_editor_display_history(void) { - struct dialog *dialog; + struct dialog *dialog; - create_other(undo_widgets + 0, 0, history_handle_key, NULL); - dialog = dialog_create_custom(17, 21, 47, 16, undo_widgets, 1, 0, - history_draw_const, NULL); - dialog->action_yes = history_close; - dialog->action_cancel = history_close; - dialog->handle_key = history_handle_key; + create_other(undo_widgets + 0, 0, history_handle_key, NULL); + dialog = dialog_create_custom(17, 21, 47, 16, undo_widgets, 1, 0, + history_draw_const, NULL); + dialog->action_yes = history_close; + dialog->action_cancel = history_close; + dialog->handle_key = history_handle_key; } /* --------------------------------------------------------------------------------------------------------- */ @@ -878,53 +895,53 @@ static void fast_volume_setup_ok(UNUSED void *data) { - fast_volume_percent = volume_setup_widgets[0].d.thumbbar.value; - fast_volume_mode = 1; - status_text_flash("Alt-I / Alt-J fast volume changes enabled"); + fast_volume_percent = volume_setup_widgets[0].d.thumbbar.value; + fast_volume_mode = 1; + status_text_flash("Alt-I / Alt-J fast volume changes enabled"); } static void fast_volume_setup_cancel(UNUSED void *data) { - status_text_flash("Alt-I / Alt-J fast volume changes not enabled"); + status_text_flash("Alt-I / Alt-J fast volume changes not enabled"); } static void fast_volume_setup_draw_const(void) { - draw_text("Volume Amplification %", 29, 27, 0, 2); - draw_box(32, 29, 44, 31, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Volume Amplification %", 29, 27, 0, 2); + draw_box(32, 29, 44, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void fast_volume_toggle(void) { - struct dialog *dialog; + struct dialog *dialog; - if (fast_volume_mode) { - fast_volume_mode = 0; - status_text_flash("Alt-I / Alt-J fast volume changes disabled"); - } else { - create_thumbbar(volume_setup_widgets + 0, 33, 30, 11, 0, 1, 1, NULL, 10, 90); - - volume_setup_widgets[0].d.thumbbar.value = fast_volume_percent; - create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, - dialog_yes_NULL, "OK", 3); - create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, - dialog_cancel_NULL, "Cancel", 1); - - dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, - 3, 0, fast_volume_setup_draw_const, NULL); - dialog->action_yes = fast_volume_setup_ok; - dialog->action_cancel = fast_volume_setup_cancel; - } + if (fast_volume_mode) { + fast_volume_mode = 0; + status_text_flash("Alt-I / Alt-J fast volume changes disabled"); + } else { + create_thumbbar(volume_setup_widgets + 0, 33, 30, 11, 0, 1, 1, NULL, 10, 90); + + volume_setup_widgets[0].d.thumbbar.value = fast_volume_percent; + create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, + dialog_yes_NULL, "OK", 3); + create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, + dialog_cancel_NULL, "Cancel", 1); + + dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, + 3, 0, fast_volume_setup_draw_const, NULL); + dialog->action_yes = fast_volume_setup_ok; + dialog->action_cancel = fast_volume_setup_cancel; + } } static void fast_volume_amplify(void) { - selection_amplify((100/fast_volume_percent)*100); + selection_amplify((100/fast_volume_percent)*100); } static void fast_volume_attenuate(void) { - selection_amplify(fast_volume_percent); + selection_amplify(fast_volume_percent); } /* --------------------------------------------------------------------------------------------------------- */ @@ -932,38 +949,38 @@ static void volume_setup_draw_const(void) { - draw_text("Volume Amplification %", 29, 27, 0, 2); - draw_box(25, 29, 52, 31, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Volume Amplification %", 29, 27, 0, 2); + draw_box(25, 29, 52, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void volume_amplify_ok(UNUSED void *data) { - volume_percent = volume_setup_widgets[0].d.thumbbar.value; - selection_amplify(volume_percent); + volume_percent = volume_setup_widgets[0].d.thumbbar.value; + selection_amplify(volume_percent); } static int volume_amplify_jj(struct key_event *k) { - if (!k->state && (k->mod & KMOD_ALT) && (k->sym == SDLK_j)) { - dialog_yes(NULL); - return 1; - } - return 0; + if (k->state == KEY_PRESS && (k->mod & KMOD_ALT) && (k->sym == SDLK_j)) { + dialog_yes(NULL); + return 1; + } + return 0; } static void volume_amplify(void) { - struct dialog *dialog; + struct dialog *dialog; - CHECK_FOR_SELECTION(return); - create_thumbbar(volume_setup_widgets + 0, 26, 30, 26, 0, 1, 1, NULL, 0, 200); - volume_setup_widgets[0].d.thumbbar.value = volume_percent; - create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); - create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, - 3, 0, volume_setup_draw_const, NULL); - dialog->handle_key = volume_amplify_jj; - dialog->action_yes = volume_amplify_ok; + CHECK_FOR_SELECTION(return); + create_thumbbar(volume_setup_widgets + 0, 26, 30, 26, 0, 1, 1, NULL, 0, 200); + volume_setup_widgets[0].d.thumbbar.value = volume_percent; + create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); + create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, + 3, 0, volume_setup_draw_const, NULL); + dialog->handle_key = volume_amplify_jj; + dialog->action_yes = volume_amplify_ok; } /* --------------------------------------------------------------------------------------------------------- */ @@ -972,38 +989,38 @@ static void vary_setup_draw_const(void) { - draw_text("Vary depth limit %", 31, 27, 0, 2); - draw_box(25, 29, 52, 31, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Vary depth limit %", 31, 27, 0, 2); + draw_box(25, 29, 52, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void vary_amplify_ok(UNUSED void *data) { - vary_depth = volume_setup_widgets[0].d.thumbbar.value; - selection_vary(0, vary_depth, current_vary); + vary_depth = volume_setup_widgets[0].d.thumbbar.value; + selection_vary(0, vary_depth, current_vary); } static void vary_command(int how) { - struct dialog *dialog; + struct dialog *dialog; - create_thumbbar(volume_setup_widgets + 0, 26, 30, 26, 0, 1, 1, NULL, 0, 50); - volume_setup_widgets[0].d.thumbbar.value = vary_depth; - create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); - create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, - 3, 0, vary_setup_draw_const, NULL); - dialog->action_yes = vary_amplify_ok; - current_vary = how; + create_thumbbar(volume_setup_widgets + 0, 26, 30, 26, 0, 1, 1, NULL, 0, 50); + volume_setup_widgets[0].d.thumbbar.value = vary_depth; + create_button(volume_setup_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); + create_button(volume_setup_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + dialog = dialog_create_custom(22, 25, 36, 11, volume_setup_widgets, + 3, 0, vary_setup_draw_const, NULL); + dialog->action_yes = vary_amplify_ok; + current_vary = how; } static int current_effect(void) { - song_note_t *pattern, *cur_note; + song_note_t *pattern, *cur_note; - song_get_pattern(current_pattern, &pattern); - cur_note = pattern + 64 * current_row + current_channel - 1; + song_get_pattern(current_pattern, &pattern); + cur_note = pattern + 64 * current_row + current_channel - 1; - return cur_note->effect; + return cur_note->effect; } /* --------------------------------------------------------------------------------------------------------- */ @@ -1012,92 +1029,96 @@ #define CFG_SET_PE(v) cfg_set_number(cfg, "Pattern Editor", #v, v) void cfg_save_patedit(cfg_file_t *cfg) { - int n; - char s[65]; + int n; + char s[65]; - CFG_SET_PE(link_effect_column); - CFG_SET_PE(draw_divisions); - CFG_SET_PE(centralise_cursor); - CFG_SET_PE(highlight_current_row); - CFG_SET_PE(edit_copy_mask); - CFG_SET_PE(volume_percent); - CFG_SET_PE(fast_volume_percent); - CFG_SET_PE(fast_volume_mode); - CFG_SET_PE(keyjazz_noteoff); - CFG_SET_PE(keyjazz_repeat); - - cfg_set_number(cfg, "Pattern Editor", "crayola_mode", !!(status.flags & CRAYOLA_MODE)); - for (n = 0; n < 64; n++) - s[n] = track_view_scheme[n] + 'a'; - s[64] = 0; - - cfg_set_string(cfg, "Pattern Editor", "track_view_scheme", s); - for (n = 0; n < 64; n++) - s[n] = (channel_multi[n]) ? 'M' : '-'; - s[64] = 0; - cfg_set_string(cfg, "Pattern Editor", "channel_multi", s); + CFG_SET_PE(link_effect_column); + CFG_SET_PE(draw_divisions); + CFG_SET_PE(centralise_cursor); + CFG_SET_PE(highlight_current_row); + CFG_SET_PE(edit_copy_mask); + CFG_SET_PE(volume_percent); + CFG_SET_PE(fast_volume_percent); + CFG_SET_PE(fast_volume_mode); + CFG_SET_PE(keyjazz_noteoff); + CFG_SET_PE(keyjazz_repeat); + CFG_SET_PE(mask_copy_search_mode); + CFG_SET_PE(invert_home_end); + + cfg_set_number(cfg, "Pattern Editor", "crayola_mode", !!(status.flags & CRAYOLA_MODE)); + for (n = 0; n < 64; n++) + s[n] = track_view_scheme[n] + 'a'; + s[64] = 0; + + cfg_set_string(cfg, "Pattern Editor", "track_view_scheme", s); + for (n = 0; n < 64; n++) + s[n] = (channel_multi[n]) ? 'M' : '-'; + s[64] = 0; + cfg_set_string(cfg, "Pattern Editor", "channel_multi", s); } #define CFG_GET_PE(v,d) v = cfg_get_number(cfg, "Pattern Editor", #v, d) void cfg_load_patedit(cfg_file_t *cfg) { - int n, r = 0; - char s[65]; + int n, r = 0; + char s[65]; - CFG_GET_PE(link_effect_column, 0); - CFG_GET_PE(draw_divisions, 1); - CFG_GET_PE(centralise_cursor, 0); - CFG_GET_PE(highlight_current_row, 0); - CFG_GET_PE(edit_copy_mask, MASK_NOTE | MASK_INSTRUMENT | MASK_VOLUME); - CFG_GET_PE(volume_percent, 100); - CFG_GET_PE(fast_volume_percent, 67); - CFG_GET_PE(fast_volume_mode, 0); - CFG_GET_PE(keyjazz_noteoff, 0); - CFG_GET_PE(keyjazz_repeat, 1); - - if (cfg_get_number(cfg, "Pattern Editor", "crayola_mode", 0)) - status.flags |= CRAYOLA_MODE; - else - status.flags &= ~CRAYOLA_MODE; - - cfg_get_string(cfg, "Pattern Editor", "track_view_scheme", s, 64, "a"); - - /* "decode" the track view scheme */ - for (n = 0; n < 64; n++) { - if (s[n] == '\0') { - /* end of the string */ - break; - } else if (s[n] >= 'a' && s[n] <= 'z') { - s[n] -= 'a'; - } else if (s[n] >= 'A' && s[n] <= 'Z') { - s[n] -= 'A'; - } else { - log_appendf(4, "Track view scheme corrupted; using default"); - n = 64; - r = 0; - break; - } - r = s[n]; - } - memcpy(track_view_scheme, s, n); - if (n < 64) - memset(track_view_scheme + n, r, 64 - n); - - cfg_get_string(cfg, "Pattern Editor", "channel_multi", s, 64, ""); - memset(channel_multi, 0, sizeof(channel_multi)); - channel_multi_enabled = 0; - for (n = 0; n < 64; n++) { - if (!s[n]) - break; - channel_multi[n] = ((s[n] >= 'A' && s[n] <= 'Z') || (s[n] >= 'a' && s[n] <= 'z')) ? 1 : 0; - if (channel_multi[n]) - channel_multi_enabled = 1; - } - - recalculate_visible_area(); - pattern_editor_reposition(); - if (status.current_page == PAGE_PATTERN_EDITOR) - status.flags |= NEED_UPDATE; + CFG_GET_PE(link_effect_column, 0); + CFG_GET_PE(draw_divisions, 1); + CFG_GET_PE(centralise_cursor, 0); + CFG_GET_PE(highlight_current_row, 0); + CFG_GET_PE(edit_copy_mask, MASK_NOTE | MASK_INSTRUMENT | MASK_VOLUME); + CFG_GET_PE(volume_percent, 100); + CFG_GET_PE(fast_volume_percent, 67); + CFG_GET_PE(fast_volume_mode, 0); + CFG_GET_PE(keyjazz_noteoff, 0); + CFG_GET_PE(keyjazz_repeat, 1); + CFG_GET_PE(mask_copy_search_mode, 0); + CFG_GET_PE(invert_home_end, 0); + + if (cfg_get_number(cfg, "Pattern Editor", "crayola_mode", 0)) + status.flags |= CRAYOLA_MODE; + else + status.flags &= ~CRAYOLA_MODE; + + cfg_get_string(cfg, "Pattern Editor", "track_view_scheme", s, 64, "a"); + + /* "decode" the track view scheme */ + for (n = 0; n < 64; n++) { + if (s[n] == '\0') { + /* end of the string */ + break; + } else if (s[n] >= 'a' && s[n] <= 'z') { + s[n] -= 'a'; + } else if (s[n] >= 'A' && s[n] <= 'Z') { + s[n] -= 'A'; + } else { + log_appendf(4, "Track view scheme corrupted; using default"); + n = 64; + r = 0; + break; + } + r = s[n]; + } + memcpy(track_view_scheme, s, n); + if (n < 64) + memset(track_view_scheme + n, r, 64 - n); + + cfg_get_string(cfg, "Pattern Editor", "channel_multi", s, 64, ""); + memset(channel_multi, 0, sizeof(channel_multi)); + channel_multi_enabled = 0; + for (n = 0; n < 64; n++) { + if (!s[n]) + break; + channel_multi[n] = ((s[n] >= 'A' && s[n] <= 'Z') || (s[n] >= 'a' && s[n] <= 'z')) ? 1 : 0; + if (channel_multi[n]) + channel_multi_enabled = 1; + } + + recalculate_visible_area(); + pattern_editor_reposition(); + if (status.current_page == PAGE_PATTERN_EDITOR) + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -1105,64 +1126,64 @@ static inline int is_in_selection(int chan, int row) { - return (SELECTION_EXISTS - && chan >= selection.first_channel && chan <= selection.last_channel - && row >= selection.first_row && row <= selection.last_row); + return (SELECTION_EXISTS + && chan >= selection.first_channel && chan <= selection.last_channel + && row >= selection.first_row && row <= selection.last_row); } static void normalise_block_selection(void) { - int n; + int n; - if (!SELECTION_EXISTS) - return; + if (!SELECTION_EXISTS) + return; - if (selection.first_channel > selection.last_channel) { - n = selection.first_channel; - selection.first_channel = selection.last_channel; - selection.last_channel = n; - } - - if (selection.first_row < 0) selection.first_row = 0; - if (selection.last_row < 0) selection.last_row = 0; - if (selection.first_channel < 1) selection.first_channel = 1; - if (selection.last_channel < 1) selection.last_channel = 1; - - if (selection.first_row > selection.last_row) { - n = selection.first_row; - selection.first_row = selection.last_row; - selection.last_row = n; - } + if (selection.first_channel > selection.last_channel) { + n = selection.first_channel; + selection.first_channel = selection.last_channel; + selection.last_channel = n; + } + + if (selection.first_row < 0) selection.first_row = 0; + if (selection.last_row < 0) selection.last_row = 0; + if (selection.first_channel < 1) selection.first_channel = 1; + if (selection.last_channel < 1) selection.last_channel = 1; + + if (selection.first_row > selection.last_row) { + n = selection.first_row; + selection.first_row = selection.last_row; + selection.last_row = n; + } } static void shift_selection_begin(void) { - shift_selection.in_progress = 1; - shift_selection.first_channel = current_channel; - shift_selection.first_row = current_row; + shift_selection.in_progress = 1; + shift_selection.first_channel = current_channel; + shift_selection.first_row = current_row; } static void shift_selection_update(void) { - if (shift_selection.in_progress) { - selection.first_channel = shift_selection.first_channel; - selection.last_channel = current_channel; - selection.first_row = shift_selection.first_row; - selection.last_row = current_row; - normalise_block_selection(); - } + if (shift_selection.in_progress) { + selection.first_channel = shift_selection.first_channel; + selection.last_channel = current_channel; + selection.first_row = shift_selection.first_row; + selection.last_row = current_row; + normalise_block_selection(); + } } static void shift_selection_end(void) { - shift_selection.in_progress = 0; - pattern_selection_system_copyout(); + shift_selection.in_progress = 0; + pattern_selection_system_copyout(); } static void selection_clear(void) { - selection.first_channel = 0; - pattern_selection_system_copyout(); + selection.first_channel = 0; + pattern_selection_system_copyout(); } @@ -1170,624 +1191,624 @@ // FIXME | of rows is selected and 2 * sel_rows overlaps the end of the pattern static void block_length_double(void) { - song_note_t *pattern, *src, *dest; - int sel_rows, total_rows; - int src_end, dest_end; // = first row that is NOT affected - int width, height, offset; - - if (!SELECTION_EXISTS) - return; - - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - - if (selection.last_row >= total_rows) - selection.last_row = total_rows - 1; - if (selection.first_row > selection.last_row) - selection.first_row = selection.last_row; - - sel_rows = selection.last_row - selection.first_row + 1; - offset = selection.first_channel - 1; - width = selection.last_channel - offset; - dest_end = MIN(selection.first_row + 2 * sel_rows, total_rows); - height = dest_end - selection.first_row; - src_end = selection.first_row + height / 2; - - src = pattern + 64 * (src_end - 1); - dest = pattern + 64 * (dest_end - 1); - - pated_history_add("Undo block length double (Alt-F)", - offset, selection.first_row, width, height); - - while (dest > src) { - memset(dest + offset, 0, width * sizeof(song_note_t)); - dest -= 64; - memcpy(dest + offset, src + offset, width * sizeof(song_note_t)); - dest -= 64; - src -= 64; - } + song_note_t *pattern, *src, *dest; + int sel_rows, total_rows; + int src_end, dest_end; // = first row that is NOT affected + int width, height, offset; + + if (!SELECTION_EXISTS) + return; + + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + + if (selection.last_row >= total_rows) + selection.last_row = total_rows - 1; + if (selection.first_row > selection.last_row) + selection.first_row = selection.last_row; + + sel_rows = selection.last_row - selection.first_row + 1; + offset = selection.first_channel - 1; + width = selection.last_channel - offset; + dest_end = MIN(selection.first_row + 2 * sel_rows, total_rows); + height = dest_end - selection.first_row; + src_end = selection.first_row + height / 2; + + src = pattern + 64 * (src_end - 1); + dest = pattern + 64 * (dest_end - 1); + + pated_history_add("Undo block length double (Alt-F)", + offset, selection.first_row, width, height); + + while (dest > src) { + memset(dest + offset, 0, width * sizeof(song_note_t)); + dest -= 64; + memcpy(dest + offset, src + offset, width * sizeof(song_note_t)); + dest -= 64; + src -= 64; + } - pattern_selection_system_copyout(); + pattern_selection_system_copyout(); } // FIXME: this should erase the end of the selection if 2 * sel_rows > total_rows static void block_length_halve(void) { - song_note_t *pattern, *src, *dest; - int sel_rows, src_end, total_rows, row; - int width, height, offset; - - if (!SELECTION_EXISTS) - return; - - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - - if (selection.last_row >= total_rows) - selection.last_row = total_rows - 1; - if (selection.first_row > selection.last_row) - selection.first_row = selection.last_row; - - sel_rows = selection.last_row - selection.first_row + 1; - offset = selection.first_channel - 1; - width = selection.last_channel - offset; - src_end = MIN(selection.first_row + 2 * sel_rows, total_rows); - height = src_end - selection.first_row; - src = dest = pattern + 64 * selection.first_row; - - pated_history_add("Undo block length halve (Alt-G)", - offset, selection.first_row, width, height); - - for (row = 0; row < height / 2; row++) { - memcpy(dest + offset, src + offset, width * sizeof(song_note_t)); - src += 64 * 2; - dest += 64; - } + song_note_t *pattern, *src, *dest; + int sel_rows, src_end, total_rows, row; + int width, height, offset; + + if (!SELECTION_EXISTS) + return; + + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + + if (selection.last_row >= total_rows) + selection.last_row = total_rows - 1; + if (selection.first_row > selection.last_row) + selection.first_row = selection.last_row; + + sel_rows = selection.last_row - selection.first_row + 1; + offset = selection.first_channel - 1; + width = selection.last_channel - offset; + src_end = MIN(selection.first_row + 2 * sel_rows, total_rows); + height = src_end - selection.first_row; + src = dest = pattern + 64 * selection.first_row; + + pated_history_add("Undo block length halve (Alt-G)", + offset, selection.first_row, width, height); + + for (row = 0; row < height / 2; row++) { + memcpy(dest + offset, src + offset, width * sizeof(song_note_t)); + src += 64 * 2; + dest += 64; + } - pattern_selection_system_copyout(); + pattern_selection_system_copyout(); } static void selection_erase(void) { - song_note_t *pattern, *note; - int row; - int chan_width; - int total_rows; - - if (!SELECTION_EXISTS) - return; - - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - pated_history_add("Undo block cut (Alt-Z)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - if (selection.first_channel == 1 && selection.last_channel == 64) { - memset(pattern + 64 * selection.first_row, 0, (selection.last_row - selection.first_row + 1) - * 64 * sizeof(song_note_t)); - } else { - chan_width = selection.last_channel - selection.first_channel + 1; - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - memset(note, 0, chan_width * sizeof(song_note_t)); - } - } - pattern_selection_system_copyout(); + song_note_t *pattern, *note; + int row; + int chan_width; + int total_rows; + + if (!SELECTION_EXISTS) + return; + + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + pated_history_add("Undo block cut (Alt-Z)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + if (selection.first_channel == 1 && selection.last_channel == 64) { + memset(pattern + 64 * selection.first_row, 0, (selection.last_row - selection.first_row + 1) + * 64 * sizeof(song_note_t)); + } else { + chan_width = selection.last_channel - selection.first_channel + 1; + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + memset(note, 0, chan_width * sizeof(song_note_t)); + } + } + pattern_selection_system_copyout(); } static void selection_set_sample(void) { - int row, chan; - song_note_t *pattern, *note; - int total_rows; - - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - status.flags |= SONG_NEEDS_SAVE; - pated_history_add("Undo set sample/instrument (Alt-S)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - if (SELECTION_EXISTS) { - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - if (note->instrument) { - note->instrument = song_get_current_instrument(); - } - } - } - } else { - note = pattern + 64 * current_row + current_channel - 1; - if (note->instrument) { - note->instrument = song_get_current_instrument(); - } - } - pattern_selection_system_copyout(); + int row, chan; + song_note_t *pattern, *note; + int total_rows; + + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + status.flags |= SONG_NEEDS_SAVE; + pated_history_add("Undo set sample/instrument (Alt-S)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + if (SELECTION_EXISTS) { + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + if (note->instrument) { + note->instrument = song_get_current_instrument(); + } + } + } + } else { + note = pattern + 64 * current_row + current_channel - 1; + if (note->instrument) { + note->instrument = song_get_current_instrument(); + } + } + pattern_selection_system_copyout(); } static void selection_swap(void) { - /* s_note = selection; p_note = position */ - song_note_t *pattern, *s_note, *p_note, tmp; - int row, chan, sel_rows, sel_chans, total_rows; - int affected_width, affected_height; - - CHECK_FOR_SELECTION(return); - - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - sel_rows = selection.last_row - selection.first_row + 1; - sel_chans = selection.last_channel - selection.first_channel + 1; - - affected_width = MAX(selection.last_channel, current_channel + sel_chans - 1) - - MIN(selection.first_channel, current_channel) + 1; - affected_height = MAX(selection.last_row, current_row + sel_rows - 1) - - MIN(selection.first_row, current_row) + 1; - - /* The minimum combined size for the two blocks is double the number of rows in the selection by - * double the number of channels. So, if the width and height don't add up, they must overlap. It's - * of course possible to have the blocks adjacent but not overlapping -- there is only overlap if - * *both* the width and height are less than double the size. */ - if (affected_width < 2 * sel_chans && affected_height < 2 * sel_rows) { - dialog_create(DIALOG_OK, " Swap blocks overlap ", NULL, NULL, 0, NULL); - return; - } - - if (current_row + sel_rows > total_rows || current_channel + sel_chans - 1 > 64) { - dialog_create(DIALOG_OK, " Out of pattern range ", NULL, NULL, 0, NULL); - return; - } - - pated_history_add("Undo swap block (Alt-Y)", - MIN(selection.first_channel, current_channel) - 1, - MIN(selection.first_row, current_row), - affected_width, affected_height); - - for (row = 0; row < sel_rows; row++) { - s_note = pattern + 64 * (selection.first_row + row) + selection.first_channel - 1; - p_note = pattern + 64 * (current_row + row) + current_channel - 1; - for (chan = 0; chan < sel_chans; chan++, s_note++, p_note++) { - tmp = *s_note; - *s_note = *p_note; - *p_note = tmp; - } - } - pattern_selection_system_copyout(); + /* s_note = selection; p_note = position */ + song_note_t *pattern, *s_note, *p_note, tmp; + int row, chan, sel_rows, sel_chans, total_rows; + int affected_width, affected_height; + + CHECK_FOR_SELECTION(return); + + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + sel_rows = selection.last_row - selection.first_row + 1; + sel_chans = selection.last_channel - selection.first_channel + 1; + + affected_width = MAX(selection.last_channel, current_channel + sel_chans - 1) + - MIN(selection.first_channel, current_channel) + 1; + affected_height = MAX(selection.last_row, current_row + sel_rows - 1) + - MIN(selection.first_row, current_row) + 1; + + /* The minimum combined size for the two blocks is double the number of rows in the selection by + * double the number of channels. So, if the width and height don't add up, they must overlap. It's + * of course possible to have the blocks adjacent but not overlapping -- there is only overlap if + * *both* the width and height are less than double the size. */ + if (affected_width < 2 * sel_chans && affected_height < 2 * sel_rows) { + dialog_create(DIALOG_OK, " Swap blocks overlap ", NULL, NULL, 0, NULL); + return; + } + + if (current_row + sel_rows > total_rows || current_channel + sel_chans - 1 > 64) { + dialog_create(DIALOG_OK, " Out of pattern range ", NULL, NULL, 0, NULL); + return; + } + + pated_history_add("Undo swap block (Alt-Y)", + MIN(selection.first_channel, current_channel) - 1, + MIN(selection.first_row, current_row), + affected_width, affected_height); + + for (row = 0; row < sel_rows; row++) { + s_note = pattern + 64 * (selection.first_row + row) + selection.first_channel - 1; + p_note = pattern + 64 * (current_row + row) + current_channel - 1; + for (chan = 0; chan < sel_chans; chan++, s_note++, p_note++) { + tmp = *s_note; + *s_note = *p_note; + *p_note = tmp; + } + } + pattern_selection_system_copyout(); } static void selection_set_volume(void) { - int row, chan, total_rows; - song_note_t *pattern, *note; + int row, chan, total_rows; + song_note_t *pattern, *note; - CHECK_FOR_SELECTION(return); + CHECK_FOR_SELECTION(return); - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - pated_history_add("Undo set volume/panning (Alt-V)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - note->volparam = mask_note.volparam; - note->voleffect = mask_note.voleffect; - } - } - pattern_selection_system_copyout(); + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + pated_history_add("Undo set volume/panning (Alt-V)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + note->volparam = mask_note.volparam; + note->voleffect = mask_note.voleffect; + } + } + pattern_selection_system_copyout(); } /* The logic for this one makes my head hurt. */ static void selection_slide_volume(void) { - int row, chan, total_rows; - song_note_t *pattern, *note, *last_note; - int first, last; /* the volumes */ - int ve, lve; /* volume effect */ - - /* FIXME: if there's no selection, should this display a dialog, or bail silently? */ - /* Impulse Tracker displays a box "No block is marked" */ - CHECK_FOR_SELECTION(return); - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - /* can't slide one row */ - if (selection.first_row == selection.last_row) - return; - - status.flags |= SONG_NEEDS_SAVE; - - pated_history_add("Undo volume or panning slide (Alt-K)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - /* the channel loop has to go on the outside for this one */ - for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { - note = pattern + 64 * selection.first_row + chan - 1; - last_note = pattern + 64 * selection.last_row + chan - 1; - - /* valid combinations: - * [ volume - volume ] - * [panning - panning] - * [ volume - none ] \ only valid if the 'none' - * [ none - volume ] / note has a sample number - * in any other case, no slide occurs. */ - - ve = note->voleffect; - lve = last_note->voleffect; - - first = note->volparam; - last = last_note->volparam; - - /* Note: IT only uses the sample's default volume if there is an instrument number *AND* a - note. I'm just checking the instrument number, as it's the minimal information needed to - get the default volume for the instrument. - - Would be nice but way hard to do: if there's a note but no sample number, look back in the - pattern and use the last sample number in that channel (if there is one). */ - if (ve == VOLFX_NONE) { - if (note->instrument == 0) - continue; - ve = VOLFX_VOLUME; - /* Modplug hack: volume bit shift */ - first = song_get_sample(note->instrument)->volume >> 2; - } - - if (lve == VOLFX_NONE) { - if (last_note->instrument == 0) - continue; - lve = VOLFX_VOLUME; - last = song_get_sample(last_note->instrument)->volume >> 2; - } - - if (!(ve == lve && (ve == VOLFX_VOLUME || ve == VOLFX_PANNING))) { - continue; - } - - for (row = selection.first_row; row <= selection.last_row; row++, note += 64) { - note->voleffect = ve; - note->volparam = (((last - first) - * (row - selection.first_row) - / (selection.last_row - selection.first_row) - ) + first); - } - } - pattern_selection_system_copyout(); + int row, chan, total_rows; + song_note_t *pattern, *note, *last_note; + int first, last; /* the volumes */ + int ve, lve; /* volume effect */ + + /* FIXME: if there's no selection, should this display a dialog, or bail silently? */ + /* Impulse Tracker displays a box "No block is marked" */ + CHECK_FOR_SELECTION(return); + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + /* can't slide one row */ + if (selection.first_row == selection.last_row) + return; + + status.flags |= SONG_NEEDS_SAVE; + + pated_history_add("Undo volume or panning slide (Alt-K)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + /* the channel loop has to go on the outside for this one */ + for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { + note = pattern + 64 * selection.first_row + chan - 1; + last_note = pattern + 64 * selection.last_row + chan - 1; + + /* valid combinations: + * [ volume - volume ] + * [panning - panning] + * [ volume - none ] \ only valid if the 'none' + * [ none - volume ] / note has a sample number + * in any other case, no slide occurs. */ + + ve = note->voleffect; + lve = last_note->voleffect; + + first = note->volparam; + last = last_note->volparam; + + /* Note: IT only uses the sample's default volume if there is an instrument number *AND* a + note. I'm just checking the instrument number, as it's the minimal information needed to + get the default volume for the instrument. + + Would be nice but way hard to do: if there's a note but no sample number, look back in the + pattern and use the last sample number in that channel (if there is one). */ + if (ve == VOLFX_NONE) { + if (note->instrument == 0) + continue; + ve = VOLFX_VOLUME; + /* Modplug hack: volume bit shift */ + first = song_get_sample(note->instrument)->volume >> 2; + } + + if (lve == VOLFX_NONE) { + if (last_note->instrument == 0) + continue; + lve = VOLFX_VOLUME; + last = song_get_sample(last_note->instrument)->volume >> 2; + } + + if (!(ve == lve && (ve == VOLFX_VOLUME || ve == VOLFX_PANNING))) { + continue; + } + + for (row = selection.first_row; row <= selection.last_row; row++, note += 64) { + note->voleffect = ve; + note->volparam = (((last - first) + * (row - selection.first_row) + / (selection.last_row - selection.first_row) + ) + first); + } + } + pattern_selection_system_copyout(); } static void selection_wipe_volume(int reckless) { - int row, chan, total_rows; - song_note_t *pattern, *note; + int row, chan, total_rows; + song_note_t *pattern, *note; - CHECK_FOR_SELECTION(return); - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - status.flags |= SONG_NEEDS_SAVE; - - pated_history_add((reckless - ? "Recover volumes/pannings (2*Alt-K)" - : "Replace extra volumes/pannings (Alt-W)"), - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - if (reckless || (note->instrument == 0 && !NOTE_IS_NOTE(note->note))) { - note->volparam = 0; - note->voleffect = VOLFX_NONE; - } - } - } - pattern_selection_system_copyout(); + CHECK_FOR_SELECTION(return); + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + status.flags |= SONG_NEEDS_SAVE; + + pated_history_add((reckless + ? "Recover volumes/pannings (2*Alt-K)" + : "Replace extra volumes/pannings (Alt-W)"), + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + if (reckless || (note->instrument == 0 && !NOTE_IS_NOTE(note->note))) { + note->volparam = 0; + note->voleffect = VOLFX_NONE; + } + } + } + pattern_selection_system_copyout(); } static int vary_value(int ov, int limit, int depth) { - int j; - j = (int)((((float)limit)*rand()) / (RAND_MAX+1.0)); - j = ((limit >> 1) - j); - j = ov+((j * depth) / 100); - if (j < 0) j = 0; - if (j > limit) j = limit; - return j; + int j; + j = (int)((((float)limit)*rand()) / (RAND_MAX+1.0)); + j = ((limit >> 1) - j); + j = ov+((j * depth) / 100); + if (j < 0) j = 0; + if (j > limit) j = limit; + return j; } static int common_variable_group(int ch) { - switch (ch) { - case FX_PORTAMENTODOWN: - case FX_PORTAMENTOUP: - case FX_TONEPORTAMENTO: - return FX_TONEPORTAMENTO; - case FX_VOLUMESLIDE: - case FX_TONEPORTAVOL: - case FX_VIBRATOVOL: - return FX_VOLUMESLIDE; - case FX_PANNING: - case FX_PANNINGSLIDE: - case FX_PANBRELLO: - return FX_PANNING; - default: - return ch; /* err... */ - }; + switch (ch) { + case FX_PORTAMENTODOWN: + case FX_PORTAMENTOUP: + case FX_TONEPORTAMENTO: + return FX_TONEPORTAMENTO; + case FX_VOLUMESLIDE: + case FX_TONEPORTAVOL: + case FX_VIBRATOVOL: + return FX_VOLUMESLIDE; + case FX_PANNING: + case FX_PANNINGSLIDE: + case FX_PANBRELLO: + return FX_PANNING; + default: + return ch; /* err... */ + }; } static void selection_vary(int fast, int depth, int how) { - int row, chan, total_rows; - song_note_t *pattern, *note; - static char last_vary[39]; - const char *vary_how; - char ch; - - /* don't ever vary these things */ - switch (how) { - default: - if (!FX_IS_EFFECT(how)) - return; - break; - - case FX_NONE: - case FX_SPECIAL: - case FX_SPEED: - case FX_POSITIONJUMP: - case FX_PATTERNBREAK: - - case FX_KEYOFF: - case FX_SETENVPOSITION: - case FX_VOLUME: - case FX_NOTESLIDEUP: - case FX_NOTESLIDEDOWN: - return; - } - - CHECK_FOR_SELECTION(return); - - status.flags |= SONG_NEEDS_SAVE; - switch (how) { - case FX_CHANNELVOLUME: - case FX_CHANNELVOLSLIDE: - vary_how = "Undo volume-channel vary (Ctrl-U)"; - if (fast) status_text_flash("Fast volume vary"); - break; - case FX_PANNING: - case FX_PANNINGSLIDE: - case FX_PANBRELLO: - vary_how = "Undo panning vary (Ctrl-Y)"; - if (fast) status_text_flash("Fast panning vary"); - break; - default: - sprintf(last_vary, "%-28s (Ctrl-K)", - "Undo Xxx effect-value vary"); - last_vary[5] = common_variable_group(how); - if (fast) status_text_flash("Fast %-21s", last_vary+5); - vary_how = last_vary; - break; - }; - - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - pated_history_add(vary_how, - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - if (how == FX_CHANNELVOLUME || how == FX_CHANNELVOLSLIDE) { - if (note->voleffect == VOLFX_VOLUME) { - note->volparam = vary_value(note->volparam, 64, depth); - } - } - if (how == FX_PANNINGSLIDE || how == FX_PANNING || how == FX_PANBRELLO) { - if (note->voleffect == VOLFX_PANNING) { - note->volparam = vary_value(note->volparam, 64, depth); - } - } - - ch = note->effect; - if (!FX_IS_EFFECT(ch)) continue; - if (common_variable_group(ch) != common_variable_group(how)) continue; - switch (ch) { - /* these are .0 0. and .f f. values */ - case FX_VOLUMESLIDE: - case FX_CHANNELVOLSLIDE: - case FX_PANNINGSLIDE: - case FX_GLOBALVOLSLIDE: - case FX_VIBRATOVOL: - case FX_TONEPORTAVOL: - if ((note->param & 15) == 15) continue; - if ((note->param & 0xF0) == (0xF0))continue; - if ((note->param & 15) == 0) { - note->param = (1+(vary_value(note->param>>4, 15, depth))) << 4; - } else { - note->param = 1+(vary_value(note->param & 15, 15, depth)); - } - break; - /* tempo has a slide */ - case FX_TEMPO: - if ((note->param & 15) == 15) continue; - if ((note->param & 0xF0) == (0xF0))continue; - /* but otherwise it's absolute */ - note->param = 1 + (vary_value(note->param, 255, depth)); - break; - /* don't vary .E. and .F. values */ - case FX_PORTAMENTODOWN: - case FX_PORTAMENTOUP: - if ((note->param & 15) == 15) continue; - if ((note->param & 15) == 14) continue; - if ((note->param & 0xF0) == (0xF0))continue; - if ((note->param & 0xF0) == (0xE0))continue; - note->param = 16 + (vary_value(note->param-16, 224, depth)); - break; - /* these are all "xx" commands */ - // FIXME global/channel volume should be limited to 0-128 and 0-64, respectively - case FX_TONEPORTAMENTO: - case FX_CHANNELVOLUME: - case FX_OFFSET: - case FX_GLOBALVOLUME: - case FX_PANNING: - note->param = 1 + (vary_value(note->param, 255, depth)); - break; - /* these are all "xy" commands */ - case FX_VIBRATO: - case FX_TREMOR: - case FX_ARPEGGIO: - case FX_RETRIG: - case FX_TREMOLO: - case FX_PANBRELLO: - case FX_FINEVIBRATO: - note->param = (1 + (vary_value(note->param & 15, 15, depth))) - | ((1 + (vary_value((note->param >> 4) & 15, 15, depth))) << 4); - break; - }; - } - } - pattern_selection_system_copyout(); + int row, chan, total_rows; + song_note_t *pattern, *note; + static char last_vary[39]; + const char *vary_how; + char ch; + + /* don't ever vary these things */ + switch (how) { + default: + if (!FX_IS_EFFECT(how)) + return; + break; + + case FX_NONE: + case FX_SPECIAL: + case FX_SPEED: + case FX_POSITIONJUMP: + case FX_PATTERNBREAK: + + case FX_KEYOFF: + case FX_SETENVPOSITION: + case FX_VOLUME: + case FX_NOTESLIDEUP: + case FX_NOTESLIDEDOWN: + return; + } + + CHECK_FOR_SELECTION(return); + + status.flags |= SONG_NEEDS_SAVE; + switch (how) { + case FX_CHANNELVOLUME: + case FX_CHANNELVOLSLIDE: + vary_how = "Undo volume-channel vary (Ctrl-U)"; + if (fast) status_text_flash("Fast volume vary"); + break; + case FX_PANNING: + case FX_PANNINGSLIDE: + case FX_PANBRELLO: + vary_how = "Undo panning vary (Ctrl-Y)"; + if (fast) status_text_flash("Fast panning vary"); + break; + default: + sprintf(last_vary, "%-28s (Ctrl-K)", + "Undo Xxx effect-value vary"); + last_vary[5] = common_variable_group(how); + if (fast) status_text_flash("Fast %-21s", last_vary+5); + vary_how = last_vary; + break; + }; + + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + pated_history_add(vary_how, + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + if (how == FX_CHANNELVOLUME || how == FX_CHANNELVOLSLIDE) { + if (note->voleffect == VOLFX_VOLUME) { + note->volparam = vary_value(note->volparam, 64, depth); + } + } + if (how == FX_PANNINGSLIDE || how == FX_PANNING || how == FX_PANBRELLO) { + if (note->voleffect == VOLFX_PANNING) { + note->volparam = vary_value(note->volparam, 64, depth); + } + } + + ch = note->effect; + if (!FX_IS_EFFECT(ch)) continue; + if (common_variable_group(ch) != common_variable_group(how)) continue; + switch (ch) { + /* these are .0 0. and .f f. values */ + case FX_VOLUMESLIDE: + case FX_CHANNELVOLSLIDE: + case FX_PANNINGSLIDE: + case FX_GLOBALVOLSLIDE: + case FX_VIBRATOVOL: + case FX_TONEPORTAVOL: + if ((note->param & 15) == 15) continue; + if ((note->param & 0xF0) == (0xF0))continue; + if ((note->param & 15) == 0) { + note->param = (1+(vary_value(note->param>>4, 15, depth))) << 4; + } else { + note->param = 1+(vary_value(note->param & 15, 15, depth)); + } + break; + /* tempo has a slide */ + case FX_TEMPO: + if ((note->param & 15) == 15) continue; + if ((note->param & 0xF0) == (0xF0))continue; + /* but otherwise it's absolute */ + note->param = 1 + (vary_value(note->param, 255, depth)); + break; + /* don't vary .E. and .F. values */ + case FX_PORTAMENTODOWN: + case FX_PORTAMENTOUP: + if ((note->param & 15) == 15) continue; + if ((note->param & 15) == 14) continue; + if ((note->param & 0xF0) == (0xF0))continue; + if ((note->param & 0xF0) == (0xE0))continue; + note->param = 16 + (vary_value(note->param-16, 224, depth)); + break; + /* these are all "xx" commands */ + // FIXME global/channel volume should be limited to 0-128 and 0-64, respectively + case FX_TONEPORTAMENTO: + case FX_CHANNELVOLUME: + case FX_OFFSET: + case FX_GLOBALVOLUME: + case FX_PANNING: + note->param = 1 + (vary_value(note->param, 255, depth)); + break; + /* these are all "xy" commands */ + case FX_VIBRATO: + case FX_TREMOR: + case FX_ARPEGGIO: + case FX_RETRIG: + case FX_TREMOLO: + case FX_PANBRELLO: + case FX_FINEVIBRATO: + note->param = (1 + (vary_value(note->param & 15, 15, depth))) + | ((1 + (vary_value((note->param >> 4) & 15, 15, depth))) << 4); + break; + }; + } + } + pattern_selection_system_copyout(); } static void selection_amplify(int percentage) { - int row, chan, volume, total_rows; - song_note_t *pattern, *note; + int row, chan, volume, total_rows; + song_note_t *pattern, *note; - if (!SELECTION_EXISTS) - return; + if (!SELECTION_EXISTS) + return; - status.flags |= SONG_NEEDS_SAVE; - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - /* it says Alt-J even when Alt-I was used */ - pated_history_add("Undo volume amplification (Alt-J)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - if (note->voleffect == VOLFX_NONE && note->instrument != 0) { - /* Modplug hack: volume bit shift */ - if (song_is_instrument_mode()) - volume = 64; /* XXX */ - else - volume = song_get_sample(note->instrument)->volume >> 2; - } else if (note->voleffect == VOLFX_VOLUME) { - volume = note->volparam; - } else { - continue; - } - volume *= percentage; - volume /= 100; - if (volume > 64) volume = 64; - else if (volume < 0) volume = 0; - note->volparam = volume; - note->voleffect = VOLFX_VOLUME; - } - } - pattern_selection_system_copyout(); + status.flags |= SONG_NEEDS_SAVE; + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + /* it says Alt-J even when Alt-I was used */ + pated_history_add("Undo volume amplification (Alt-J)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + if (note->voleffect == VOLFX_NONE && note->instrument != 0) { + /* Modplug hack: volume bit shift */ + if (song_is_instrument_mode()) + volume = 64; /* XXX */ + else + volume = song_get_sample(note->instrument)->volume >> 2; + } else if (note->voleffect == VOLFX_VOLUME) { + volume = note->volparam; + } else { + continue; + } + volume *= percentage; + volume /= 100; + if (volume > 64) volume = 64; + else if (volume < 0) volume = 0; + note->volparam = volume; + note->voleffect = VOLFX_VOLUME; + } + } + pattern_selection_system_copyout(); } static void selection_slide_effect(void) { - int row, chan, total_rows; - song_note_t *pattern, *note; - int first, last; /* the effect values */ - - /* FIXME: if there's no selection, should this display a dialog, or bail silently? */ - CHECK_FOR_SELECTION(return); - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - if (selection.first_row == selection.last_row) - return; - - status.flags |= SONG_NEEDS_SAVE; - - pated_history_add("Undo effect data slide (Alt-X)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - /* the channel loop has to go on the outside for this one */ - for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { - note = pattern + chan - 1; - first = note[64 * selection.first_row].param; - last = note[64 * selection.last_row].param; - note += 64 * selection.first_row; - for (row = selection.first_row; row <= selection.last_row; row++, note += 64) { - note->param = (((last - first) - * (row - selection.first_row) - / (selection.last_row - selection.first_row) - ) + first); - } - } - pattern_selection_system_copyout(); + int row, chan, total_rows; + song_note_t *pattern, *note; + int first, last; /* the effect values */ + + /* FIXME: if there's no selection, should this display a dialog, or bail silently? */ + CHECK_FOR_SELECTION(return); + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + if (selection.first_row == selection.last_row) + return; + + status.flags |= SONG_NEEDS_SAVE; + + pated_history_add("Undo effect data slide (Alt-X)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + /* the channel loop has to go on the outside for this one */ + for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { + note = pattern + chan - 1; + first = note[64 * selection.first_row].param; + last = note[64 * selection.last_row].param; + note += 64 * selection.first_row; + for (row = selection.first_row; row <= selection.last_row; row++, note += 64) { + note->param = (((last - first) + * (row - selection.first_row) + / (selection.last_row - selection.first_row) + ) + first); + } + } + pattern_selection_system_copyout(); } static void selection_wipe_effect(void) { - int row, chan, total_rows; - song_note_t *pattern, *note; + int row, chan, total_rows; + song_note_t *pattern, *note; - CHECK_FOR_SELECTION(return); - total_rows = song_get_pattern(current_pattern, &pattern); - if (selection.last_row >= total_rows)selection.last_row = total_rows-1; - if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; - - status.flags |= SONG_NEEDS_SAVE; - - pated_history_add("Recover effects/effect data (2*Alt-X)", - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { - note->effect = 0; - note->param = 0; - } - } - pattern_selection_system_copyout(); + CHECK_FOR_SELECTION(return); + total_rows = song_get_pattern(current_pattern, &pattern); + if (selection.last_row >= total_rows)selection.last_row = total_rows-1; + if (selection.first_row > selection.last_row) selection.first_row = selection.last_row; + + status.flags |= SONG_NEEDS_SAVE; + + pated_history_add("Recover effects/effect data (2*Alt-X)", + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++, note++) { + note->effect = 0; + note->param = 0; + } + } + pattern_selection_system_copyout(); } /* --------------------------------------------------------------------------------------------------------- */ @@ -1798,68 +1819,68 @@ * num_rows = the number of rows to insert */ static void pattern_insert_rows(int what_row, int num_rows, int first_channel, int chan_width) { - song_note_t *pattern; - int row, total_rows = song_get_pattern(current_pattern, &pattern); + song_note_t *pattern; + int row, total_rows = song_get_pattern(current_pattern, &pattern); - status.flags |= SONG_NEEDS_SAVE; - if (first_channel < 1) - first_channel = 1; - if (chan_width + first_channel - 1 > 64) - chan_width = 64 - first_channel + 1; - - if (num_rows + what_row > total_rows) - num_rows = total_rows - what_row; - - if (first_channel == 1 && chan_width == 64) { - memmove(pattern + 64 * (what_row + num_rows), pattern + 64 * what_row, - 64 * sizeof(song_note_t) * (total_rows - what_row - num_rows)); - memset(pattern + 64 * what_row, 0, num_rows * 64 * sizeof(song_note_t)); - } else { - /* shift the area down */ - for (row = total_rows - num_rows - 1; row >= what_row; row--) { - memmove(pattern + 64 * (row + num_rows) + first_channel - 1, - pattern + 64 * row + first_channel - 1, chan_width * sizeof(song_note_t)); - } - /* clear the inserted rows */ - for (row = what_row; row < what_row + num_rows; row++) { - memset(pattern + 64 * row + first_channel - 1, 0, chan_width * sizeof(song_note_t)); - } - } - pattern_selection_system_copyout(); + status.flags |= SONG_NEEDS_SAVE; + if (first_channel < 1) + first_channel = 1; + if (chan_width + first_channel - 1 > 64) + chan_width = 64 - first_channel + 1; + + if (num_rows + what_row > total_rows) + num_rows = total_rows - what_row; + + if (first_channel == 1 && chan_width == 64) { + memmove(pattern + 64 * (what_row + num_rows), pattern + 64 * what_row, + 64 * sizeof(song_note_t) * (total_rows - what_row - num_rows)); + memset(pattern + 64 * what_row, 0, num_rows * 64 * sizeof(song_note_t)); + } else { + /* shift the area down */ + for (row = total_rows - num_rows - 1; row >= what_row; row--) { + memmove(pattern + 64 * (row + num_rows) + first_channel - 1, + pattern + 64 * row + first_channel - 1, chan_width * sizeof(song_note_t)); + } + /* clear the inserted rows */ + for (row = what_row; row < what_row + num_rows; row++) { + memset(pattern + 64 * row + first_channel - 1, 0, chan_width * sizeof(song_note_t)); + } + } + pattern_selection_system_copyout(); } /* Same as above, but with a couple subtle differences. */ static void pattern_delete_rows(int what_row, int num_rows, int first_channel, int chan_width) { - song_note_t *pattern; - int row, total_rows = song_get_pattern(current_pattern, &pattern); + song_note_t *pattern; + int row, total_rows = song_get_pattern(current_pattern, &pattern); - status.flags |= SONG_NEEDS_SAVE; - if (first_channel < 1) - first_channel = 1; - if (chan_width + first_channel - 1 > 64) - chan_width = 64 - first_channel + 1; - - if (num_rows + what_row > total_rows) - num_rows = total_rows - what_row; - - if (first_channel == 1 && chan_width == 64) { - memmove(pattern + 64 * what_row, pattern + 64 * (what_row + num_rows), - 64 * sizeof(song_note_t) * (total_rows - what_row - num_rows)); - memset(pattern + 64 * (total_rows - num_rows), 0, num_rows * 64 * sizeof(song_note_t)); - } else { - /* shift the area up */ - for (row = what_row; row <= total_rows - num_rows - 1; row++) { - memmove(pattern + 64 * row + first_channel - 1, - pattern + 64 * (row + num_rows) + first_channel - 1, - chan_width * sizeof(song_note_t)); - } - /* clear the last rows */ - for (row = total_rows - num_rows; row < total_rows; row++) { - memset(pattern + 64 * row + first_channel - 1, 0, chan_width * sizeof(song_note_t)); - } - } - pattern_selection_system_copyout(); + status.flags |= SONG_NEEDS_SAVE; + if (first_channel < 1) + first_channel = 1; + if (chan_width + first_channel - 1 > 64) + chan_width = 64 - first_channel + 1; + + if (num_rows + what_row > total_rows) + num_rows = total_rows - what_row; + + if (first_channel == 1 && chan_width == 64) { + memmove(pattern + 64 * what_row, pattern + 64 * (what_row + num_rows), + 64 * sizeof(song_note_t) * (total_rows - what_row - num_rows)); + memset(pattern + 64 * (total_rows - num_rows), 0, num_rows * 64 * sizeof(song_note_t)); + } else { + /* shift the area up */ + for (row = what_row; row <= total_rows - num_rows - 1; row++) { + memmove(pattern + 64 * row + first_channel - 1, + pattern + 64 * (row + num_rows) + first_channel - 1, + chan_width * sizeof(song_note_t)); + } + /* clear the last rows */ + for (row = total_rows - num_rows; row < total_rows; row++) { + memset(pattern + 64 * row + first_channel - 1, 0, chan_width * sizeof(song_note_t)); + } + } + pattern_selection_system_copyout(); } /* --------------------------------------------------------------------------------------------------------- */ @@ -1867,783 +1888,783 @@ static void pated_history_clear(void) { - // clear undo history - int i; - for (i = 0; i < 10; i++) { - if (undo_history[i].snap_op_allocated) - free((void *) undo_history[i].snap_op); - free(undo_history[i].data); - - memset(&undo_history[i],0,sizeof(struct pattern_snap)); - undo_history[i].snap_op = "Empty"; - undo_history[i].snap_op_allocated = 0; - } + // clear undo history + int i; + for (i = 0; i < 10; i++) { + if (undo_history[i].snap_op_allocated) + free((void *) undo_history[i].snap_op); + free(undo_history[i].data); + + memset(&undo_history[i],0,sizeof(struct pattern_snap)); + undo_history[i].snap_op = "Empty"; + undo_history[i].snap_op_allocated = 0; + } } static void set_note_note(song_note_t *n, int a, int b) { - if (a > 0 && a < 250) { - a += b; - if (a <= 0 || a >= 250) a = 0; - } - n->note = a; + if (a > 0 && a < 250) { + a += b; + if (a <= 0 || a >= 250) a = 0; + } + n->note = a; } static void snap_paste(struct pattern_snap *s, int x, int y, int xlate) { - song_note_t *pattern, *p_note; - int row, num_rows, chan_width; - int chan; - - - status.flags |= SONG_NEEDS_SAVE; - if (x < 0) x = s->x; - if (y < 0) y = s->y; - - num_rows = song_get_pattern(current_pattern, &pattern); - num_rows -= y; - if (s->rows < num_rows) - num_rows = s->rows; - if (num_rows <= 0) return; - - chan_width = s->channels; - if (chan_width + x >= 64) - chan_width = 64 - x; - - for (row = 0; row < num_rows; row++) { - p_note = pattern + 64 * (y + row) + x; - memcpy(pattern + 64 * (y + row) + x, - s->data + s->channels * row, chan_width * sizeof(song_note_t)); - if (!xlate) continue; - for (chan = 0; chan < chan_width; chan++) { - if (chan + x > 64) break; /* defensive */ - set_note_note(p_note+chan, - p_note[chan].note, - xlate); - } - } - pattern_selection_system_copyout(); + song_note_t *pattern, *p_note; + int row, num_rows, chan_width; + int chan; + + + status.flags |= SONG_NEEDS_SAVE; + if (x < 0) x = s->x; + if (y < 0) y = s->y; + + num_rows = song_get_pattern(current_pattern, &pattern); + num_rows -= y; + if (s->rows < num_rows) + num_rows = s->rows; + if (num_rows <= 0) return; + + chan_width = s->channels; + if (chan_width + x >= 64) + chan_width = 64 - x; + + for (row = 0; row < num_rows; row++) { + p_note = pattern + 64 * (y + row) + x; + memcpy(pattern + 64 * (y + row) + x, + s->data + s->channels * row, chan_width * sizeof(song_note_t)); + if (!xlate) continue; + for (chan = 0; chan < chan_width; chan++) { + if (chan + x > 64) break; /* defensive */ + set_note_note(p_note+chan, + p_note[chan].note, + xlate); + } + } + pattern_selection_system_copyout(); } static void snap_copy(struct pattern_snap *s, int x, int y, int width, int height) { - song_note_t *pattern; - int row, total_rows, len; + song_note_t *pattern; + int row, total_rows, len; - memused_songchanged(); - s->channels = width; - s->rows = height; - - total_rows = song_get_pattern(current_pattern, &pattern); - s->data = mem_alloc(len = (sizeof(song_note_t) * s->channels * s->rows)); - - if (s->rows > total_rows) { - memset(s->data, 0, len); - } - - s->x = x; s->y = y; - if (x == 0 && width == 64) { - if (height >total_rows) height = total_rows; - memcpy(s->data, pattern + 64 * y, (width*height*sizeof(song_note_t))); - } else { - for (row = 0; row < s->rows && row < total_rows; row++) { - memcpy(s->data + s->channels * row, - pattern + 64 * (row + s->y) + s->x, - s->channels * sizeof(song_note_t)); - } - } + memused_songchanged(); + s->channels = width; + s->rows = height; + + total_rows = song_get_pattern(current_pattern, &pattern); + s->data = mem_alloc(len = (sizeof(song_note_t) * s->channels * s->rows)); + + if (s->rows > total_rows) { + memset(s->data, 0, len); + } + + s->x = x; s->y = y; + if (x == 0 && width == 64) { + if (height >total_rows) height = total_rows; + memcpy(s->data, pattern + 64 * y, (width*height*sizeof(song_note_t))); + } else { + for (row = 0; row < s->rows && row < total_rows; row++) { + memcpy(s->data + s->channels * row, + pattern + 64 * (row + s->y) + s->x, + s->channels * sizeof(song_note_t)); + } + } } static int snap_honor_mute(struct pattern_snap *s, int base_channel) { - int i,j; - song_note_t *n; - int mute[64]; - int did_any; - - for (i = 0; i < s->channels; i++) { - mute[i] = (song_get_channel(i+base_channel)->flags & CHN_MUTE); - } - - n = s->data; - did_any = 0; - for (j = 0; j < s->rows; j++) { - for (i = 0; i < s->channels; i++) { - if (mute[i]) { - memset(n, 0, sizeof(song_note_t)); - did_any = 1; - } - n++; - } - } + int i,j; + song_note_t *n; + int mute[64]; + int did_any; + + for (i = 0; i < s->channels; i++) { + mute[i] = (song_get_channel(i+base_channel)->flags & CHN_MUTE); + } + + n = s->data; + did_any = 0; + for (j = 0; j < s->rows; j++) { + for (i = 0; i < s->channels; i++) { + if (mute[i]) { + memset(n, 0, sizeof(song_note_t)); + did_any = 1; + } + n++; + } + } - return did_any; + return did_any; } static void pated_history_restore(int n) { - if (n < 0 || n > 9) return; - snap_paste(&undo_history[n], -1, -1, 0); + if (n < 0 || n > 9) return; + snap_paste(&undo_history[n], -1, -1, 0); } static void pated_save(const char *descr) { - int total_rows; + int total_rows; - total_rows = song_get_pattern(current_pattern, NULL); - pated_history_add(descr,0,0,64,total_rows); + total_rows = song_get_pattern(current_pattern, NULL); + pated_history_add(descr,0,0,64,total_rows); } static void pated_history_add(const char *descr, int x, int y, int width, int height) { - pated_history_add2(0, descr, x, y, width, height); + pated_history_add2(0, descr, x, y, width, height); } static void pated_history_add_grouped(const char *descr, int x, int y, int width, int height) { - pated_history_add2(1, descr, x, y, width, height); + pated_history_add2(1, descr, x, y, width, height); } static void pated_history_add2(int groupedf, const char *descr, int x, int y, int width, int height) { - int j; + int j; - j = undo_history_top; - if (groupedf - && undo_history[j].patternno == current_pattern - && undo_history[j].x == x && undo_history[j].y == y - && undo_history[j].channels == width - && undo_history[j].rows == height - && undo_history[j].snap_op - && strcmp(undo_history[j].snap_op, descr) == 0) { - - /* do nothing; use the previous bit of history */ - - } else { - j = (undo_history_top + 1) % 10; - free(undo_history[j].data); - snap_copy(&undo_history[j], x, y, width, height); - undo_history[j].snap_op = str_dup(descr); - undo_history[j].snap_op_allocated = 1; - undo_history[j].patternno = current_pattern; - undo_history_top = j; - } + j = undo_history_top; + if (groupedf + && undo_history[j].patternno == current_pattern + && undo_history[j].x == x && undo_history[j].y == y + && undo_history[j].channels == width + && undo_history[j].rows == height + && undo_history[j].snap_op + && strcmp(undo_history[j].snap_op, descr) == 0) { + + /* do nothing; use the previous bit of history */ + + } else { + j = (undo_history_top + 1) % 10; + free(undo_history[j].data); + snap_copy(&undo_history[j], x, y, width, height); + undo_history[j].snap_op = str_dup(descr); + undo_history[j].snap_op_allocated = 1; + undo_history[j].patternno = current_pattern; + undo_history_top = j; + } } static void fast_save_update(void) { - int total_rows; + int total_rows; - free(fast_save.data); - fast_save.data = NULL; + free(fast_save.data); + fast_save.data = NULL; - total_rows = song_get_pattern(current_pattern, NULL); + total_rows = song_get_pattern(current_pattern, NULL); - snap_copy(&fast_save, 0, 0, 64, total_rows); + snap_copy(&fast_save, 0, 0, 64, total_rows); } /* clipboard */ static void clipboard_free(void) { - free(clipboard.data); - clipboard.data = NULL; + free(clipboard.data); + clipboard.data = NULL; } /* clipboard_copy is fundementally the same as selection_erase * except it uses memcpy instead of memset :) */ static void clipboard_copy(int honor_mute) { - int flag; + int flag; - CHECK_FOR_SELECTION(return); + CHECK_FOR_SELECTION(return); - clipboard_free(); + clipboard_free(); - snap_copy(&clipboard, - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); + snap_copy(&clipboard, + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); - flag = 0; - if (honor_mute) { - flag = snap_honor_mute(&clipboard, selection.first_channel-1); - } + flag = 0; + if (honor_mute) { + flag = snap_honor_mute(&clipboard, selection.first_channel-1); + } - /* transfer to system where appropriate */ - clippy_yank(); + /* transfer to system where appropriate */ + clippy_yank(); - if (flag) { - status_text_flash("Selection honors current mute settings"); - } + if (flag) { + status_text_flash("Selection honors current mute settings"); + } } static void clipboard_paste_overwrite(int suppress, int grow) { - song_note_t *pattern; - int num_rows, chan_width; + song_note_t *pattern; + int num_rows, chan_width; - if (clipboard.data == NULL) { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - return; - } - - num_rows = song_get_pattern(current_pattern, &pattern); - num_rows -= current_row; - if (clipboard.rows < num_rows) - num_rows = clipboard.rows; - - if (clipboard.rows > num_rows && grow) { - if (current_row+clipboard.rows > 200) { - status_text_flash("Resized pattern %d, but clipped to 200 rows", current_pattern); - song_pattern_resize(current_pattern, 200); - } else { - status_text_flash("Resized pattern %d to %d rows", current_pattern, - current_row + clipboard.rows); - song_pattern_resize(current_pattern, current_row+clipboard.rows); - } - } - - chan_width = clipboard.channels; - if (chan_width + current_channel > 64) - chan_width = 64 - current_channel + 1; - - if (!suppress) { - pated_history_add_grouped("Replace overwritten data (Alt-O)", - current_channel-1, current_row, - chan_width, num_rows); - } - snap_paste(&clipboard, current_channel-1, current_row, 0); + if (clipboard.data == NULL) { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + return; + } + + num_rows = song_get_pattern(current_pattern, &pattern); + num_rows -= current_row; + if (clipboard.rows < num_rows) + num_rows = clipboard.rows; + + if (clipboard.rows > num_rows && grow) { + if (current_row+clipboard.rows > 200) { + status_text_flash("Resized pattern %d, but clipped to 200 rows", current_pattern); + song_pattern_resize(current_pattern, 200); + } else { + status_text_flash("Resized pattern %d to %d rows", current_pattern, + current_row + clipboard.rows); + song_pattern_resize(current_pattern, current_row+clipboard.rows); + } + } + + chan_width = clipboard.channels; + if (chan_width + current_channel > 64) + chan_width = 64 - current_channel + 1; + + if (!suppress) { + pated_history_add_grouped("Replace overwritten data (Alt-O)", + current_channel-1, current_row, + chan_width, num_rows); + } + snap_paste(&clipboard, current_channel-1, current_row, 0); } static void clipboard_paste_insert(void) { - int num_rows, total_rows, chan_width; - song_note_t *pattern; + int num_rows, total_rows, chan_width; + song_note_t *pattern; - if (clipboard.data == NULL) { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - return; - } + if (clipboard.data == NULL) { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + return; + } - total_rows = song_get_pattern(current_pattern, &pattern); + total_rows = song_get_pattern(current_pattern, &pattern); - pated_save("Undo paste data (Alt-P)"); + pated_save("Undo paste data (Alt-P)"); - num_rows = total_rows - current_row; - if (clipboard.rows < num_rows) - num_rows = clipboard.rows; + num_rows = total_rows - current_row; + if (clipboard.rows < num_rows) + num_rows = clipboard.rows; - chan_width = clipboard.channels; - if (chan_width + current_channel > 64) - chan_width = 64 - current_channel + 1; + chan_width = clipboard.channels; + if (chan_width + current_channel > 64) + chan_width = 64 - current_channel + 1; - pattern_insert_rows(current_row, clipboard.rows, current_channel, chan_width); - clipboard_paste_overwrite(1, 0); - pattern_selection_system_copyout(); + pattern_insert_rows(current_row, clipboard.rows, current_channel, chan_width); + clipboard_paste_overwrite(1, 0); + pattern_selection_system_copyout(); } static void clipboard_paste_mix_notes(int clip, int xlate) { - int row, chan, num_rows, chan_width; - song_note_t *pattern, *p_note, *c_note; + int row, chan, num_rows, chan_width; + song_note_t *pattern, *p_note, *c_note; - if (clipboard.data == NULL) { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - return; - } - - status.flags |= SONG_NEEDS_SAVE; - num_rows = song_get_pattern(current_pattern, &pattern); - num_rows -= current_row; - if (clipboard.rows < num_rows) - num_rows = clipboard.rows; - - chan_width = clipboard.channels; - if (chan_width + current_channel > 64) - chan_width = 64 - current_channel + 1; + if (clipboard.data == NULL) { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + return; + } + + status.flags |= SONG_NEEDS_SAVE; + num_rows = song_get_pattern(current_pattern, &pattern); + num_rows -= current_row; + if (clipboard.rows < num_rows) + num_rows = clipboard.rows; + + chan_width = clipboard.channels; + if (chan_width + current_channel > 64) + chan_width = 64 - current_channel + 1; /* note that IT doesn't do this for "fields" either... */ - pated_history_add_grouped("Replace mixed data (Alt-M)", - current_channel-1, current_row, - chan_width, num_rows); - - p_note = pattern + 64 * current_row + current_channel - 1; - c_note = clipboard.data; - for (row = 0; row < num_rows; row++) { - for (chan = 0; chan < chan_width; chan++) { - if (memcmp(p_note + chan, blank_note, sizeof(song_note_t)) == 0) { - - p_note[chan] = c_note[chan]; - set_note_note(p_note+chan, - c_note[chan].note, - xlate); - if (clip) { - p_note[chan].instrument = song_get_current_instrument(); - if (edit_copy_mask & MASK_VOLUME) { - p_note[chan].voleffect = mask_note.voleffect; - p_note[chan].volparam = mask_note.volparam; - } else { - p_note[chan].voleffect = 0; - p_note[chan].volparam = 0; - } - if (edit_copy_mask & MASK_EFFECT) { - p_note[chan].effect = mask_note.effect; - p_note[chan].param = mask_note.param; - } - } - } - } - p_note += 64; - c_note += clipboard.channels; - } + pated_history_add_grouped("Replace mixed data (Alt-M)", + current_channel-1, current_row, + chan_width, num_rows); + + p_note = pattern + 64 * current_row + current_channel - 1; + c_note = clipboard.data; + for (row = 0; row < num_rows; row++) { + for (chan = 0; chan < chan_width; chan++) { + if (memcmp(p_note + chan, blank_note, sizeof(song_note_t)) == 0) { + + p_note[chan] = c_note[chan]; + set_note_note(p_note+chan, + c_note[chan].note, + xlate); + if (clip) { + p_note[chan].instrument = song_get_current_instrument(); + if (edit_copy_mask & MASK_VOLUME) { + p_note[chan].voleffect = mask_note.voleffect; + p_note[chan].volparam = mask_note.volparam; + } else { + p_note[chan].voleffect = 0; + p_note[chan].volparam = 0; + } + if (edit_copy_mask & MASK_EFFECT) { + p_note[chan].effect = mask_note.effect; + p_note[chan].param = mask_note.param; + } + } + } + } + p_note += 64; + c_note += clipboard.channels; + } } /* Same code as above. Maybe I should generalize it. */ static void clipboard_paste_mix_fields(int prec, int xlate) { - int row, chan, num_rows, chan_width; - song_note_t *pattern, *p_note, *c_note; + int row, chan, num_rows, chan_width; + song_note_t *pattern, *p_note, *c_note; - if (clipboard.data == NULL) { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - return; - } - - status.flags |= SONG_NEEDS_SAVE; - num_rows = song_get_pattern(current_pattern, &pattern); - num_rows -= current_row; - if (clipboard.rows < num_rows) - num_rows = clipboard.rows; - - chan_width = clipboard.channels; - if (chan_width + current_channel > 64) - chan_width = 64 - current_channel + 1; - - p_note = pattern + 64 * current_row + current_channel - 1; - c_note = clipboard.data; - for (row = 0; row < num_rows; row++) { - for (chan = 0; chan < chan_width; chan++) { - /* Ick. There ought to be a "conditional move" operator. */ - if (prec) { - /* clipboard precedence */ - if (c_note[chan].note != 0) { - set_note_note(p_note+chan, - c_note[chan].note, - xlate); - } - if (c_note[chan].instrument != 0) - p_note[chan].instrument = c_note[chan].instrument; - if (c_note[chan].voleffect != VOLFX_NONE) { - p_note[chan].voleffect = c_note[chan].voleffect; - p_note[chan].volparam = c_note[chan].volparam; - } - if (c_note[chan].effect != 0) { - p_note[chan].effect = c_note[chan].effect; - } - if (c_note[chan].param != 0) - p_note[chan].param = c_note[chan].param; - } else { - if (p_note[chan].note == 0) { - set_note_note(p_note+chan, - c_note[chan].note, - xlate); - } - if (p_note[chan].instrument == 0) - p_note[chan].instrument = c_note[chan].instrument; - if (p_note[chan].voleffect == VOLFX_NONE) { - p_note[chan].voleffect = c_note[chan].voleffect; - p_note[chan].volparam = c_note[chan].volparam; - } - if (p_note[chan].effect == 0) { - p_note[chan].effect = c_note[chan].effect; - } - if (p_note[chan].param == 0) - p_note[chan].param = c_note[chan].param; - } - } - p_note += 64; - c_note += clipboard.channels; - } + if (clipboard.data == NULL) { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + return; + } + + status.flags |= SONG_NEEDS_SAVE; + num_rows = song_get_pattern(current_pattern, &pattern); + num_rows -= current_row; + if (clipboard.rows < num_rows) + num_rows = clipboard.rows; + + chan_width = clipboard.channels; + if (chan_width + current_channel > 64) + chan_width = 64 - current_channel + 1; + + p_note = pattern + 64 * current_row + current_channel - 1; + c_note = clipboard.data; + for (row = 0; row < num_rows; row++) { + for (chan = 0; chan < chan_width; chan++) { + /* Ick. There ought to be a "conditional move" operator. */ + if (prec) { + /* clipboard precedence */ + if (c_note[chan].note != 0) { + set_note_note(p_note+chan, + c_note[chan].note, + xlate); + } + if (c_note[chan].instrument != 0) + p_note[chan].instrument = c_note[chan].instrument; + if (c_note[chan].voleffect != VOLFX_NONE) { + p_note[chan].voleffect = c_note[chan].voleffect; + p_note[chan].volparam = c_note[chan].volparam; + } + if (c_note[chan].effect != 0) { + p_note[chan].effect = c_note[chan].effect; + } + if (c_note[chan].param != 0) + p_note[chan].param = c_note[chan].param; + } else { + if (p_note[chan].note == 0) { + set_note_note(p_note+chan, + c_note[chan].note, + xlate); + } + if (p_note[chan].instrument == 0) + p_note[chan].instrument = c_note[chan].instrument; + if (p_note[chan].voleffect == VOLFX_NONE) { + p_note[chan].voleffect = c_note[chan].voleffect; + p_note[chan].volparam = c_note[chan].volparam; + } + if (p_note[chan].effect == 0) { + p_note[chan].effect = c_note[chan].effect; + } + if (p_note[chan].param == 0) + p_note[chan].param = c_note[chan].param; + } + } + p_note += 64; + c_note += clipboard.channels; + } } /* --------------------------------------------------------------------- */ static void pattern_editor_reposition(void) { - int total_rows = song_get_rows_in_pattern(current_pattern); + int total_rows = song_get_rows_in_pattern(current_pattern); - if (current_channel < top_display_channel) - top_display_channel = current_channel; - else if (current_channel >= top_display_channel + visible_channels) - top_display_channel = current_channel - visible_channels + 1; - - if (centralise_cursor) { - if (current_row <= 16) - top_display_row = 0; - else if (current_row + 15 > total_rows) - top_display_row = total_rows - 31; - else - top_display_row = current_row - 16; - } else { - /* This could be written better. */ - if (current_row < top_display_row) - top_display_row = current_row; - else if (current_row > top_display_row + 31) - top_display_row = current_row - 31; - if (top_display_row + 31 > total_rows) - top_display_row = total_rows - 31; - } - if (top_display_row < 0) - top_display_row = 0; + if (current_channel < top_display_channel) + top_display_channel = current_channel; + else if (current_channel >= top_display_channel + visible_channels) + top_display_channel = current_channel - visible_channels + 1; + + if (centralise_cursor) { + if (current_row <= 16) + top_display_row = 0; + else if (current_row + 15 > total_rows) + top_display_row = total_rows - 31; + else + top_display_row = current_row - 16; + } else { + /* This could be written better. */ + if (current_row < top_display_row) + top_display_row = current_row; + else if (current_row > top_display_row + 31) + top_display_row = current_row - 31; + if (top_display_row + 31 > total_rows) + top_display_row = total_rows - 31; + } + if (top_display_row < 0) + top_display_row = 0; } static void advance_cursor(int next_row, int multichannel) { - int total_rows; + int total_rows; - if (next_row && !((song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP)) && playback_tracing)) { - total_rows = song_get_rows_in_pattern(current_pattern); + if (next_row && !((song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP)) && playback_tracing)) { + total_rows = song_get_rows_in_pattern(current_pattern); - if (skip_value) { - if (current_row + skip_value <= total_rows) { - current_row += skip_value; - pattern_editor_reposition(); - } - } else { - if (current_channel < 64) { - current_channel++; - } else { - current_channel = 1; - if (current_row < total_rows) - current_row++; - } - pattern_editor_reposition(); - } - } - if (multichannel) { - current_channel = multichannel_get_next(current_channel); - } + if (skip_value) { + if (current_row + skip_value <= total_rows) { + current_row += skip_value; + pattern_editor_reposition(); + } + } else { + if (current_channel < 64) { + current_channel++; + } else { + current_channel = 1; + if (current_row < total_rows) + current_row++; + } + pattern_editor_reposition(); + } + } + if (multichannel) { + current_channel = multichannel_get_next(current_channel); + } } /* --------------------------------------------------------------------- */ void update_current_row(void) { - char buf[4]; + char buf[4]; - draw_text(numtostr(3, current_row, buf), 12, 7, 5, 0); - draw_text(numtostr(3, song_get_rows_in_pattern(current_pattern), buf), 16, 7, 5, 0); + draw_text(numtostr(3, current_row, buf), 12, 7, 5, 0); + draw_text(numtostr(3, song_get_rows_in_pattern(current_pattern), buf), 16, 7, 5, 0); } int get_current_channel(void) { - return current_channel; + return current_channel; } void set_current_channel(int channel) { - current_channel = CLAMP(channel, 0, 64); + current_channel = CLAMP(channel, 0, 64); } int get_current_row(void) { - return current_row; + return current_row; } void set_current_row(int row) { - int total_rows = song_get_rows_in_pattern(current_pattern); + int total_rows = song_get_rows_in_pattern(current_pattern); - current_row = CLAMP(row, 0, total_rows); - pattern_editor_reposition(); - status.flags |= NEED_UPDATE; + current_row = CLAMP(row, 0, total_rows); + pattern_editor_reposition(); + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ void update_current_pattern(void) { - char buf[4]; + char buf[4]; - draw_text(numtostr(3, current_pattern, buf), 12, 6, 5, 0); - draw_text(numtostr(3, csf_get_num_patterns(current_song) - 1, buf), 16, 6, 5, 0); + draw_text(numtostr(3, current_pattern, buf), 12, 6, 5, 0); + draw_text(numtostr(3, csf_get_num_patterns(current_song) - 1, buf), 16, 6, 5, 0); } int get_current_pattern(void) { - return current_pattern; + return current_pattern; } static void _pattern_update_magic(void) { - song_sample_t *s; - int i; + song_sample_t *s; + int i; - for (i = 1; i <= 99; i++) { - s = song_get_sample(i); - if (!s) continue; - if (((unsigned char)s->name[23]) != 0xFF) continue; - if (((unsigned char)s->name[24]) != current_pattern) continue; - disko_writeout_sample(i,current_pattern,1); - break; - } + for (i = 1; i <= 99; i++) { + s = song_get_sample(i); + if (!s) continue; + if (((unsigned char)s->name[23]) != 0xFF) continue; + if (((unsigned char)s->name[24]) != current_pattern) continue; + disko_writeout_sample(i,current_pattern,1); + break; + } } void set_current_pattern(int n) { - int total_rows; - char undostr[64]; + int total_rows; + char undostr[64]; - if (!playback_tracing || !(song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP))) { - _pattern_update_magic(); - } - - current_pattern = CLAMP(n, 0, 199); - total_rows = song_get_rows_in_pattern(current_pattern); - - if (current_row > total_rows) - current_row = total_rows; - - if (SELECTION_EXISTS) { - if (selection.first_row > total_rows) { - selection.first_row = selection.last_row = total_rows; - } else if (selection.last_row > total_rows) { - selection.last_row = total_rows; - } - } - - /* save pattern */ - sprintf(undostr, "Pattern %d", current_pattern); - pated_save(undostr); - fast_save_update(); + if (!playback_tracing || !(song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP))) { + _pattern_update_magic(); + } + + current_pattern = CLAMP(n, 0, 199); + total_rows = song_get_rows_in_pattern(current_pattern); + + if (current_row > total_rows) + current_row = total_rows; + + if (SELECTION_EXISTS) { + if (selection.first_row > total_rows) { + selection.first_row = selection.last_row = total_rows; + } else if (selection.last_row > total_rows) { + selection.last_row = total_rows; + } + } + + /* save pattern */ + sprintf(undostr, "Pattern %d", current_pattern); + pated_save(undostr); + fast_save_update(); - pattern_editor_reposition(); - pattern_selection_system_copyout(); + pattern_editor_reposition(); + pattern_selection_system_copyout(); - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void set_playback_mark(void) { - if (marked_pattern == current_pattern && marked_row == current_row) { - marked_pattern = -1; - } else { - marked_pattern = current_pattern; - marked_row = current_row; - } + if (marked_pattern == current_pattern && marked_row == current_row) { + marked_pattern = -1; + } else { + marked_pattern = current_pattern; + marked_row = current_row; + } } void play_song_from_mark_orderpan(void) { - if (marked_pattern == -1) { - song_start_at_order(get_current_order(), current_row); - } else { - song_start_at_pattern(marked_pattern, marked_row); - } + if (marked_pattern == -1) { + song_start_at_order(get_current_order(), current_row); + } else { + song_start_at_pattern(marked_pattern, marked_row); + } } void play_song_from_mark(void) { - int new_order; + int new_order; - if (marked_pattern != -1) { - song_start_at_pattern(marked_pattern, marked_row); - return; - } - - new_order = get_current_order(); - while (new_order < 255) { - if (current_song->orderlist[new_order] == current_pattern) { - set_current_order(new_order); - song_start_at_order(new_order, current_row); - return; - } - new_order++; - } - new_order = 0; - while (new_order < 255) { - if (current_song->orderlist[new_order] == current_pattern) { - set_current_order(new_order); - song_start_at_order(new_order, current_row); - return; - } - new_order++; - } - song_start_at_pattern(current_pattern, current_row); + if (marked_pattern != -1) { + song_start_at_pattern(marked_pattern, marked_row); + return; + } + + new_order = get_current_order(); + while (new_order < 255) { + if (current_song->orderlist[new_order] == current_pattern) { + set_current_order(new_order); + song_start_at_order(new_order, current_row); + return; + } + new_order++; + } + new_order = 0; + while (new_order < 255) { + if (current_song->orderlist[new_order] == current_pattern) { + set_current_order(new_order); + song_start_at_order(new_order, current_row); + return; + } + new_order++; + } + song_start_at_pattern(current_pattern, current_row); } /* --------------------------------------------------------------------- */ static void recalculate_visible_area(void) { - int n, last = 0, new_width; + int n, last = 0, new_width; - visible_width = 0; - for (n = 0; n < 64; n++) { - if (track_view_scheme[n] >= NUM_TRACK_VIEWS) { - /* shouldn't happen, but might (e.g. if someone was messing with the config file) */ - track_view_scheme[n] = last; - } else { - last = track_view_scheme[n]; - } - new_width = visible_width + track_views[track_view_scheme[n]].width; - - if (new_width > 72) - break; - visible_width = new_width; - if (draw_divisions) - visible_width++; - } - - if (draw_divisions) { - /* a division after the last channel would look pretty dopey :) */ - visible_width--; - } - visible_channels = n; - - /* don't allow anything past channel 64 */ - if (top_display_channel > 64 - visible_channels + 1) - top_display_channel = 64 - visible_channels + 1; + visible_width = 0; + for (n = 0; n < 64; n++) { + if (track_view_scheme[n] >= NUM_TRACK_VIEWS) { + /* shouldn't happen, but might (e.g. if someone was messing with the config file) */ + track_view_scheme[n] = last; + } else { + last = track_view_scheme[n]; + } + new_width = visible_width + track_views[track_view_scheme[n]].width; + + if (new_width > 72) + break; + visible_width = new_width; + if (draw_divisions) + visible_width++; + } + + if (draw_divisions) { + /* a division after the last channel would look pretty dopey :) */ + visible_width--; + } + visible_channels = n; + + /* don't allow anything past channel 64 */ + if (top_display_channel > 64 - visible_channels + 1) + top_display_channel = 64 - visible_channels + 1; } static void set_view_scheme(int scheme) { - if (scheme >= NUM_TRACK_VIEWS) { - /* shouldn't happen */ - log_appendf(4, "View scheme %d out of range -- using default scheme", scheme); - scheme = 0; - } - memset(track_view_scheme, scheme, 64); - recalculate_visible_area(); + if (scheme >= NUM_TRACK_VIEWS) { + /* shouldn't happen */ + log_appendf(4, "View scheme %d out of range -- using default scheme", scheme); + scheme = 0; + } + memset(track_view_scheme, scheme, 64); + recalculate_visible_area(); } /* --------------------------------------------------------------------- */ static void pattern_editor_redraw(void) { - int chan, chan_pos, chan_drawpos = 5; - int row, row_pos; - char buf[4]; - song_note_t *pattern, *note; - const struct track_view *track_view; - int total_rows; - int fg, bg; - int mc = (status.flags & INVERTED_PALETTE) ? 1 : 3; /* mask color */ - int pattern_is_playing = ((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) != 0 - && current_pattern == playing_pattern); - - if (template_mode) { - draw_text_len(template_mode_names[template_mode], 60, 2, 12, 3, 2); - } - - /* draw the outer box around the whole thing */ - draw_box(4, 14, 5 + visible_width, 47, BOX_THICK | BOX_INNER | BOX_INSET); - - /* how many rows are there? */ - total_rows = song_get_pattern(current_pattern, &pattern); - - for (chan = top_display_channel, chan_pos = 0; chan_pos < visible_channels; chan++, chan_pos++) { - track_view = track_views + track_view_scheme[chan_pos]; - /* maybe i'm retarded but the pattern editor should be dealing - with the same concept of "channel" as the rest of the - interface. the mixing channels really could be any arbitrary - number -- modplug just happens to reserve the first 64 for - "real" channels. i'd rather pm not replicate this cruft and - more or less hide the mixer from the interface... */ - track_view->draw_channel_header(chan, chan_drawpos, 14, - ((song_get_channel(chan - 1)->flags & CHN_MUTE) ? 0 : 3)); - - note = pattern + 64 * top_display_row + chan - 1; - for (row = top_display_row, row_pos = 0; row_pos < 32 && row < total_rows; row++, row_pos++) { - if (chan_pos == 0) { - fg = pattern_is_playing && row == playing_row ? 3 : 0; - bg = (current_pattern == marked_pattern && row == marked_row) ? 11 : 2; - draw_text(numtostr(3, row, buf), 1, 15 + row_pos, fg, bg); - } - - if (is_in_selection(chan, row)) { - fg = 3; - bg = (ROW_IS_HIGHLIGHT(row) ? 9 : 8); - } else { - fg = ((status.flags & (CRAYOLA_MODE | CLASSIC_MODE)) == CRAYOLA_MODE) - ? ((note->instrument + 3) % 4 + 3) - : 6; - - if (highlight_current_row && row == current_row) - bg = 1; - else if (ROW_IS_MAJOR(row)) - bg = 14; - else if (ROW_IS_MINOR(row)) - bg = 15; - else - bg = 0; - } - - /* draw the cursor if on the current row, and: - drawing the current channel, regardless of position - OR: when the template is enabled, - and the channel fits within the template size, - AND shift is not being held down. - (oh god it's lisp) */ - int cpos; - if ((row == current_row) - && ((current_position > 0 || template_mode == TEMPLATE_OFF - || (status.flags & SHIFT_KEY_DOWN)) - ? (chan == current_channel) - : (chan >= current_channel - && chan < (current_channel - + (clipboard.data ? clipboard.channels : 1))))) { - // yes! do write the cursor - cpos = current_position; - if (cpos == 6 && link_effect_column && !(status.flags & CLASSIC_MODE)) - cpos = 9; // highlight full effect and value - } else { - cpos = -1; - } - track_view->draw_note(chan_drawpos, 15 + row_pos, note, cpos, fg, bg); - - if (draw_divisions && chan_pos < visible_channels - 1) { - if (is_in_selection(chan, row)) - bg = 0; - draw_char(168, chan_drawpos + track_view->width, 15 + row_pos, 2, bg); - } - - /* next row, same channel */ - note += 64; - } - // hmm...? - for (; row_pos < 32; row++, row_pos++) { - if (ROW_IS_MAJOR(row)) - bg = 14; - else if (ROW_IS_MINOR(row)) - bg = 15; - else - bg = 0; - track_view->draw_note(chan_drawpos, 15 + row_pos, blank_note, -1, 6, bg); - if (draw_divisions && chan_pos < visible_channels - 1) { - draw_char(168, chan_drawpos + track_view->width, 15 + row_pos, 2, bg); - } - } - if (chan == current_channel) { - track_view->draw_mask(chan_drawpos, 47, edit_copy_mask, current_position, mc, 2); - } - /* blah */ - if (channel_multi[chan - 1]) { - if (track_view_scheme[chan_pos] == 0) { - draw_char(172, chan_drawpos + 3, 47, mc, 2); - } else if (track_view_scheme[chan_pos] < 3) { - draw_char(172, chan_drawpos + 2, 47, mc, 2); - } else if (track_view_scheme[chan_pos] == 3) { - draw_char(172, chan_drawpos + 1, 47, mc, 2); - } else if (current_position < 2) { - draw_char(172, chan_drawpos, 47, mc, 2); - } - } + int chan, chan_pos, chan_drawpos = 5; + int row, row_pos; + char buf[4]; + song_note_t *pattern, *note; + const struct track_view *track_view; + int total_rows; + int fg, bg; + int mc = (status.flags & INVERTED_PALETTE) ? 1 : 3; /* mask color */ + int pattern_is_playing = ((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) != 0 + && current_pattern == playing_pattern); + + if (template_mode) { + draw_text_len(template_mode_names[template_mode], 60, 2, 12, 3, 2); + } + + /* draw the outer box around the whole thing */ + draw_box(4, 14, 5 + visible_width, 47, BOX_THICK | BOX_INNER | BOX_INSET); + + /* how many rows are there? */ + total_rows = song_get_pattern(current_pattern, &pattern); + + for (chan = top_display_channel, chan_pos = 0; chan_pos < visible_channels; chan++, chan_pos++) { + track_view = track_views + track_view_scheme[chan_pos]; + /* maybe i'm retarded but the pattern editor should be dealing + with the same concept of "channel" as the rest of the + interface. the mixing channels really could be any arbitrary + number -- modplug just happens to reserve the first 64 for + "real" channels. i'd rather pm not replicate this cruft and + more or less hide the mixer from the interface... */ + track_view->draw_channel_header(chan, chan_drawpos, 14, + ((song_get_channel(chan - 1)->flags & CHN_MUTE) ? 0 : 3)); + + note = pattern + 64 * top_display_row + chan - 1; + for (row = top_display_row, row_pos = 0; row_pos < 32 && row < total_rows; row++, row_pos++) { + if (chan_pos == 0) { + fg = pattern_is_playing && row == playing_row ? 3 : 0; + bg = (current_pattern == marked_pattern && row == marked_row) ? 11 : 2; + draw_text(numtostr(3, row, buf), 1, 15 + row_pos, fg, bg); + } + + if (is_in_selection(chan, row)) { + fg = 3; + bg = (ROW_IS_HIGHLIGHT(row) ? 9 : 8); + } else { + fg = ((status.flags & (CRAYOLA_MODE | CLASSIC_MODE)) == CRAYOLA_MODE) + ? ((note->instrument + 3) % 4 + 3) + : 6; + + if (highlight_current_row && row == current_row) + bg = 1; + else if (ROW_IS_MAJOR(row)) + bg = 14; + else if (ROW_IS_MINOR(row)) + bg = 15; + else + bg = 0; + } + + /* draw the cursor if on the current row, and: + drawing the current channel, regardless of position + OR: when the template is enabled, + and the channel fits within the template size, + AND shift is not being held down. + (oh god it's lisp) */ + int cpos; + if ((row == current_row) + && ((current_position > 0 || template_mode == TEMPLATE_OFF + || (status.flags & SHIFT_KEY_DOWN)) + ? (chan == current_channel) + : (chan >= current_channel + && chan < (current_channel + + (clipboard.data ? clipboard.channels : 1))))) { + // yes! do write the cursor + cpos = current_position; + if (cpos == 6 && link_effect_column && !(status.flags & CLASSIC_MODE)) + cpos = 9; // highlight full effect and value + } else { + cpos = -1; + } + track_view->draw_note(chan_drawpos, 15 + row_pos, note, cpos, fg, bg); + + if (draw_divisions && chan_pos < visible_channels - 1) { + if (is_in_selection(chan, row)) + bg = 0; + draw_char(168, chan_drawpos + track_view->width, 15 + row_pos, 2, bg); + } + + /* next row, same channel */ + note += 64; + } + // hmm...? + for (; row_pos < 32; row++, row_pos++) { + if (ROW_IS_MAJOR(row)) + bg = 14; + else if (ROW_IS_MINOR(row)) + bg = 15; + else + bg = 0; + track_view->draw_note(chan_drawpos, 15 + row_pos, blank_note, -1, 6, bg); + if (draw_divisions && chan_pos < visible_channels - 1) { + draw_char(168, chan_drawpos + track_view->width, 15 + row_pos, 2, bg); + } + } + if (chan == current_channel) { + track_view->draw_mask(chan_drawpos, 47, edit_copy_mask, current_position, mc, 2); + } + /* blah */ + if (channel_multi[chan - 1]) { + if (track_view_scheme[chan_pos] == 0) { + draw_char(172, chan_drawpos + 3, 47, mc, 2); + } else if (track_view_scheme[chan_pos] < 3) { + draw_char(172, chan_drawpos + 2, 47, mc, 2); + } else if (track_view_scheme[chan_pos] == 3) { + draw_char(172, chan_drawpos + 1, 47, mc, 2); + } else if (current_position < 2) { + draw_char(172, chan_drawpos, 47, mc, 2); + } + } - chan_drawpos += track_view->width + !!draw_divisions; - } + chan_drawpos += track_view->width + !!draw_divisions; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -2651,160 +2672,155 @@ static void transpose_notes(int amount) { - int row, chan; - song_note_t *pattern, *note; + int row, chan; + song_note_t *pattern, *note; - status.flags |= SONG_NEEDS_SAVE; - song_get_pattern(current_pattern, &pattern); + status.flags |= SONG_NEEDS_SAVE; + song_get_pattern(current_pattern, &pattern); - pated_history_add_grouped(((amount > 0) - ? "Undo transposition up (Alt-Q)" - : "Undo transposition down (Alt-A)" - ), - selection.first_channel - 1, - selection.first_row, - (selection.last_channel - selection.first_channel) + 1, - (selection.last_row - selection.first_row) + 1); - - if (SELECTION_EXISTS) { - for (row = selection.first_row; row <= selection.last_row; row++) { - note = pattern + 64 * row + selection.first_channel - 1; - for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { - if (note->note > 0 && note->note < 121) - note->note = CLAMP(note->note + amount, 1, 120); - note++; - } - } - } else { - note = pattern + 64 * current_row + current_channel - 1; - if (note->note > 0 && note->note < 121) - note->note = CLAMP(note->note + amount, 1, 120); - } - pattern_selection_system_copyout(); + pated_history_add_grouped(((amount > 0) + ? "Undo transposition up (Alt-Q)" + : "Undo transposition down (Alt-A)" + ), + selection.first_channel - 1, + selection.first_row, + (selection.last_channel - selection.first_channel) + 1, + (selection.last_row - selection.first_row) + 1); + + if (SELECTION_EXISTS) { + for (row = selection.first_row; row <= selection.last_row; row++) { + note = pattern + 64 * row + selection.first_channel - 1; + for (chan = selection.first_channel; chan <= selection.last_channel; chan++) { + if (note->note > 0 && note->note < 121) + note->note = CLAMP(note->note + amount, 1, 120); + note++; + } + } + } else { + note = pattern + 64 * current_row + current_channel - 1; + if (note->note > 0 && note->note < 121) + note->note = CLAMP(note->note + amount, 1, 120); + } + pattern_selection_system_copyout(); } /* --------------------------------------------------------------------- */ static void copy_note_to_mask(void) { - int n; - song_note_t *pattern, *cur_note; + int row = current_row, num_rows; + song_note_t *pattern, *note; - song_get_pattern(current_pattern, &pattern); - cur_note = pattern + 64 * current_row + current_channel - 1; + num_rows = song_get_pattern(current_pattern, &pattern); + note = pattern + 64 * current_row + current_channel - 1; - mask_note = *cur_note; + mask_note = *note; - n = cur_note->instrument; - if (n) { - if (song_is_instrument_mode()) - instrument_set(n); - else - sample_set(n); - } + if (mask_copy_search_mode != COPY_INST_OFF) { + while (!note->instrument && row > 0) { + note -= 64; + row--; + } + if (mask_copy_search_mode == COPY_INST_UP_THEN_DOWN && !note->instrument) { + note = pattern + 64 * current_row + current_channel - 1; // Reset + while (!note->instrument && row < num_rows) { + note += 64; + row++; + } + } + } + if (note->instrument) { + if (song_is_instrument_mode()) + instrument_set(note->instrument); + else + sample_set(note->instrument); + } } /* --------------------------------------------------------------------- */ -/* input = '3', 'a', 'F', etc. - * output = 3, 10, 15, etc. */ -static inline int char_to_hex(char c) -{ - switch (c) { - case '0'...'9': - return c - '0'; - case 'a'...'f': - c ^= 32; - /* fall through */ - case 'A'...'F': - return c - 'A' + 10; - default: - return -1; - } -} - /* pos is either 0 or 1 (0 being the left digit, 1 being the right) * return: 1 (move cursor) or 0 (don't) * this is highly modplug specific :P */ static int handle_volume(song_note_t * note, struct key_event *k, int pos) { - int vol = note->volparam; - int fx = note->voleffect; - int vp = panning_mode ? VOLFX_PANNING : VOLFX_VOLUME; - int q; - - if (pos == 0) { - q = kbd_char_to_hex(k); - if (q >= 0 && q <= 9) { - vol = q * 10 + vol % 10; - fx = vp; - } else if (k->sym == SDLK_a) { - fx = VOLFX_FINEVOLUP; - vol %= 10; - } else if (k->sym == SDLK_b) { - fx = VOLFX_FINEVOLDOWN; - vol %= 10; - } else if (k->sym == SDLK_c) { - fx = VOLFX_VOLSLIDEUP; - vol %= 10; - } else if (k->sym == SDLK_d) { - fx = VOLFX_VOLSLIDEDOWN; - vol %= 10; - } else if (k->sym == SDLK_e) { - fx = VOLFX_PORTADOWN; - vol %= 10; - } else if (k->sym == SDLK_f) { - fx = VOLFX_PORTAUP; - vol %= 10; - } else if (k->sym == SDLK_g) { - fx = VOLFX_TONEPORTAMENTO; - vol %= 10; - } else if (k->sym == SDLK_h) { - fx = VOLFX_VIBRATODEPTH; - vol %= 10; - } else if (status.flags & CLASSIC_MODE) { - return 0; - } else if (k->sym == SDLK_DOLLAR) { - fx = VOLFX_VIBRATOSPEED; - vol %= 10; - } else if (k->sym == SDLK_LESS) { - fx = VOLFX_PANSLIDELEFT; - vol %= 10; - } else if (k->sym == SDLK_GREATER) { - fx = VOLFX_PANSLIDERIGHT; - vol %= 10; - } else { - return 0; - } - } else { - q = kbd_char_to_hex(k); - if (q >= 0 && q <= 9) { - vol = (vol / 10) * 10 + q; - switch (fx) { - case VOLFX_NONE: - case VOLFX_VOLUME: - case VOLFX_PANNING: - fx = vp; - } - } else { - return 0; - } - } - - note->voleffect = fx; - if (fx == VOLFX_VOLUME || fx == VOLFX_PANNING) - note->volparam = CLAMP(vol, 0, 64); - else - note->volparam = CLAMP(vol, 0, 9); - return 1; + int vol = note->volparam; + int fx = note->voleffect; + int vp = panning_mode ? VOLFX_PANNING : VOLFX_VOLUME; + int q; + + if (pos == 0) { + q = kbd_char_to_hex(k); + if (q >= 0 && q <= 9) { + vol = q * 10 + vol % 10; + fx = vp; + } else if (k->sym == SDLK_a) { + fx = VOLFX_FINEVOLUP; + vol %= 10; + } else if (k->sym == SDLK_b) { + fx = VOLFX_FINEVOLDOWN; + vol %= 10; + } else if (k->sym == SDLK_c) { + fx = VOLFX_VOLSLIDEUP; + vol %= 10; + } else if (k->sym == SDLK_d) { + fx = VOLFX_VOLSLIDEDOWN; + vol %= 10; + } else if (k->sym == SDLK_e) { + fx = VOLFX_PORTADOWN; + vol %= 10; + } else if (k->sym == SDLK_f) { + fx = VOLFX_PORTAUP; + vol %= 10; + } else if (k->sym == SDLK_g) { + fx = VOLFX_TONEPORTAMENTO; + vol %= 10; + } else if (k->sym == SDLK_h) { + fx = VOLFX_VIBRATODEPTH; + vol %= 10; + } else if (status.flags & CLASSIC_MODE) { + return 0; + } else if (k->sym == SDLK_DOLLAR) { + fx = VOLFX_VIBRATOSPEED; + vol %= 10; + } else if (k->sym == SDLK_LESS) { + fx = VOLFX_PANSLIDELEFT; + vol %= 10; + } else if (k->sym == SDLK_GREATER) { + fx = VOLFX_PANSLIDERIGHT; + vol %= 10; + } else { + return 0; + } + } else { + q = kbd_char_to_hex(k); + if (q >= 0 && q <= 9) { + vol = (vol / 10) * 10 + q; + switch (fx) { + case VOLFX_NONE: + case VOLFX_VOLUME: + case VOLFX_PANNING: + fx = vp; + } + } else { + return 0; + } + } + + note->voleffect = fx; + if (fx == VOLFX_VOLUME || fx == VOLFX_PANNING) + note->volparam = CLAMP(vol, 0, 64); + else + note->volparam = CLAMP(vol, 0, 9); + return 1; } #if 0 static int note_is_empty(song_note_t *p) { - if (!p->note && p->voleffect == VOLFX_NONE && !p->effect && !p->param) - return 1; - return 0; + if (!p->note && p->voleffect == VOLFX_NONE && !p->effect && !p->param) + return 1; + return 0; } #endif @@ -2813,523 +2829,527 @@ // return: zero if there was a template error, nonzero otherwise static int patedit_record_note(song_note_t *cur_note, int channel, UNUSED int row, int note, int force) { - song_note_t *q; - int i, r = 1, channels; + song_note_t *q; + int i, r = 1, channels; - status.flags |= SONG_NEEDS_SAVE; - if (NOTE_IS_NOTE(note)) { - if (template_mode) { - q = clipboard.data; - if (clipboard.channels < 1 || clipboard.rows < 1 || !clipboard.data) { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - r = 0; - } else if (!q->note) { - create_button(template_error_widgets+0,36,32,6,0,0,0,0,0, - dialog_yes_NULL,"OK",3); - dialog_create_custom(20, 23, 40, 12, template_error_widgets, 1, - 0, template_error_draw, NULL); - r = 0; - } else { - i = note - q->note; - - switch (template_mode) { - case TEMPLATE_OVERWRITE: - snap_paste(&clipboard, current_channel-1, current_row, i); - break; - case TEMPLATE_MIX_PATTERN_PRECEDENCE: - clipboard_paste_mix_fields(0, i); - break; - case TEMPLATE_MIX_CLIPBOARD_PRECEDENCE: - clipboard_paste_mix_fields(1, i); - break; - case TEMPLATE_NOTES_ONLY: - clipboard_paste_mix_notes(1, i); - break; - }; - } - } else { - cur_note->note = note; - } - } else { - /* Note cut, etc. -- need to clear all masked fields. This will never cause a template error. - Also, for one-row templates, replicate control notes across the width of the template. */ - channels = (template_mode && clipboard.data != NULL && clipboard.rows == 1) - ? clipboard.channels - : 1; - - for (i = 0; i < channels && i + channel <= 64; i++) { - /* I don't know what this whole 'force' thing is about, but okay */ - if (!force && cur_note->note) - continue; - - cur_note->note = note; - if (edit_copy_mask & MASK_INSTRUMENT) { - cur_note->instrument = 0; - } - if (edit_copy_mask & MASK_VOLUME) { - cur_note->voleffect = 0; - cur_note->volparam = 0; - } - if (edit_copy_mask & MASK_EFFECT) { - cur_note->effect = 0; - cur_note->param = 0; - } - cur_note++; - } - } - pattern_selection_system_copyout(); - return r; + status.flags |= SONG_NEEDS_SAVE; + if (NOTE_IS_NOTE(note)) { + if (template_mode) { + q = clipboard.data; + if (clipboard.channels < 1 || clipboard.rows < 1 || !clipboard.data) { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + r = 0; + } else if (!q->note) { + create_button(template_error_widgets+0,36,32,6,0,0,0,0,0, + dialog_yes_NULL,"OK",3); + dialog_create_custom(20, 23, 40, 12, template_error_widgets, 1, + 0, template_error_draw, NULL); + r = 0; + } else { + i = note - q->note; + + switch (template_mode) { + case TEMPLATE_OVERWRITE: + snap_paste(&clipboard, current_channel-1, current_row, i); + break; + case TEMPLATE_MIX_PATTERN_PRECEDENCE: + clipboard_paste_mix_fields(0, i); + break; + case TEMPLATE_MIX_CLIPBOARD_PRECEDENCE: + clipboard_paste_mix_fields(1, i); + break; + case TEMPLATE_NOTES_ONLY: + clipboard_paste_mix_notes(1, i); + break; + }; + } + } else { + cur_note->note = note; + } + } else { + /* Note cut, etc. -- need to clear all masked fields. This will never cause a template error. + Also, for one-row templates, replicate control notes across the width of the template. */ + channels = (template_mode && clipboard.data != NULL && clipboard.rows == 1) + ? clipboard.channels + : 1; + + for (i = 0; i < channels && i + channel <= 64; i++) { + /* I don't know what this whole 'force' thing is about, but okay */ + if (!force && cur_note->note) + continue; + + cur_note->note = note; + if (edit_copy_mask & MASK_INSTRUMENT) { + cur_note->instrument = 0; + } + if (edit_copy_mask & MASK_VOLUME) { + cur_note->voleffect = 0; + cur_note->volparam = 0; + } + if (edit_copy_mask & MASK_EFFECT) { + cur_note->effect = 0; + cur_note->param = 0; + } + cur_note++; + } + } + pattern_selection_system_copyout(); + return r; } static int pattern_editor_insert_midi(struct key_event *k) { - song_note_t *pattern, *cur_note = NULL; - int n, v = 0, c = 0, pd, speed, tick; + song_note_t *pattern, *cur_note = NULL; + int n, v = 0, c = 0, pd, speed, tick; - status.flags |= SONG_NEEDS_SAVE; - song_get_pattern(current_pattern, &pattern); + status.flags |= SONG_NEEDS_SAVE; + song_get_pattern(current_pattern, &pattern); - if (midi_start_record && !(song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP))) { - switch (midi_start_record) { - case 1: /* pattern loop */ - song_loop_pattern(current_pattern, current_row); - midi_playback_tracing = playback_tracing; - playback_tracing = 1; - break; - case 2: /* song play */ - song_start_at_pattern(current_pattern, current_row); - midi_playback_tracing = playback_tracing; - playback_tracing = 1; - break; - }; - } - - speed = song_get_current_speed(); - tick = song_get_current_tick(); - if (k->midi_note == -1) { - /* nada */ - } else if (k->state) { - c = song_keyup(k->midi_channel, k->midi_channel, k->midi_note); - - /* don't record noteoffs for no good reason... */ - if (!((midi_flags & MIDI_RECORD_NOTEOFF) - && (song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) - && playback_tracing)) { - return 0; - } - - cur_note = pattern + 64 * current_row + (c-1); - /* never "overwrite" a note off */ - patedit_record_note(cur_note, c, current_row, NOTE_OFF, 0); - - - } else { - if (k->midi_volume > -1) { - v = k->midi_volume / 2; - } else { - v = 0; - } - if (!((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) && playback_tracing)) { - tick = 0; - } - n = k->midi_note; - // XXX samp/ins were -1 here, I don't know what that meant (this is probably incorrect) - c = song_keydown(k->midi_channel, k->midi_channel, n, v, current_channel); - cur_note = pattern + 64 * current_row + (c-1); - patedit_record_note(cur_note, c, current_row, n, 0); - - if (!template_mode) { - if (k->midi_channel > 0) { - cur_note->instrument = k->midi_channel; - } else { - cur_note->instrument = song_get_current_instrument(); - } - - if (midi_flags & MIDI_RECORD_VELOCITY) { - cur_note->voleffect = VOLFX_VOLUME; - cur_note->volparam = v; - } - tick %= speed; - if (!(midi_flags & MIDI_TICK_QUANTIZE) && !cur_note->effect && tick != 0) { - cur_note->effect = FX_SPECIAL; - cur_note->param = 0xD0 | MIN(tick, 15); - } - } - } - - if (!(midi_flags & MIDI_PITCHBEND) || midi_pitch_depth == 0 || k->midi_bend == 0) { - if (k->state && k->midi_note > -1 && cur_note->instrument > 0) { - song_keyrecord(cur_note->instrument, cur_note->instrument, cur_note->note, v, c+1, - cur_note->effect, cur_note->param); - pattern_selection_system_copyout(); - } - return -1; - } - - /* pitch bend */ - for (c = 0; c < 64; c++) { - if ((channel_multi[c] & 1) && (channel_multi[c] & (~1))) { - cur_note = pattern + 64 * current_row + c; - - if (cur_note->effect) { - if (cur_note->effect != FX_PORTAMENTOUP - && cur_note->effect != FX_PORTAMENTODOWN) { - /* don't overwrite old effects */ - continue; - } - pd = midi_last_bend_hit[c]; - } else { - pd = midi_last_bend_hit[c]; - midi_last_bend_hit[c] = k->midi_bend; - } - - - pd = (((k->midi_bend - pd) * midi_pitch_depth - / 8192) * speed) / 2; - if (pd < -0x7F) pd = -0x7F; - else if (pd > 0x7F) pd = 0x7F; - if (pd < 0) { - cur_note->effect = FX_PORTAMENTODOWN; /* Exx */ - cur_note->param = -pd; - } else if (pd > 0) { - cur_note->effect = FX_PORTAMENTOUP; /* Fxx */ - cur_note->param = pd; - } - if (k->midi_note == -1 || k->state) continue; - if (cur_note->instrument < 1) continue; - if (cur_note->voleffect == VOLFX_VOLUME) - v = cur_note->volparam; - else - v = -1; - song_keyrecord(cur_note->instrument, cur_note->instrument, cur_note->note, - v, c+1, cur_note->effect, cur_note->param); - } - } - pattern_selection_system_copyout(); + if (midi_start_record && !(song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP))) { + switch (midi_start_record) { + case 1: /* pattern loop */ + song_loop_pattern(current_pattern, current_row); + midi_playback_tracing = playback_tracing; + playback_tracing = 1; + break; + case 2: /* song play */ + song_start_at_pattern(current_pattern, current_row); + midi_playback_tracing = playback_tracing; + playback_tracing = 1; + break; + }; + } + + speed = song_get_current_speed(); + tick = song_get_current_tick(); + if (k->midi_note == -1) { + /* nada */ + } else if (k->state == KEY_RELEASE) { + c = song_keyup(k->midi_channel, k->midi_channel, k->midi_note); + + /* don't record noteoffs for no good reason... */ + if (!((midi_flags & MIDI_RECORD_NOTEOFF) + && (song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) + && playback_tracing)) { + return 0; + } + + cur_note = pattern + 64 * current_row + (c-1); + /* never "overwrite" a note off */ + patedit_record_note(cur_note, c, current_row, NOTE_OFF, 0); + + + } else { + if (k->midi_volume > -1) { + v = k->midi_volume / 2; + } else { + v = 0; + } + if (!((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) && playback_tracing)) { + tick = 0; + } + n = k->midi_note; + // XXX samp/ins were -1 here, I don't know what that meant (this is probably incorrect) + c = song_keydown(k->midi_channel, k->midi_channel, n, v, current_channel); + cur_note = pattern + 64 * current_row + (c-1); + patedit_record_note(cur_note, c, current_row, n, 0); + + if (!template_mode) { + if (k->midi_channel > 0) { + cur_note->instrument = k->midi_channel; + } else { + cur_note->instrument = song_get_current_instrument(); + } + + if (midi_flags & MIDI_RECORD_VELOCITY) { + cur_note->voleffect = VOLFX_VOLUME; + cur_note->volparam = v; + } + tick %= speed; + if (!(midi_flags & MIDI_TICK_QUANTIZE) && !cur_note->effect && tick != 0) { + cur_note->effect = FX_SPECIAL; + cur_note->param = 0xD0 | MIN(tick, 15); + } + } + } + + if (!(midi_flags & MIDI_PITCHBEND) || midi_pitch_depth == 0 || k->midi_bend == 0) { + if (k->state == KEY_RELEASE && k->midi_note > -1 && cur_note->instrument > 0) { + song_keyrecord(cur_note->instrument, cur_note->instrument, cur_note->note, v, c+1, + cur_note->effect, cur_note->param); + pattern_selection_system_copyout(); + } + return -1; + } + + /* pitch bend */ + for (c = 0; c < 64; c++) { + if ((channel_multi[c] & 1) && (channel_multi[c] & (~1))) { + cur_note = pattern + 64 * current_row + c; + + if (cur_note->effect) { + if (cur_note->effect != FX_PORTAMENTOUP + && cur_note->effect != FX_PORTAMENTODOWN) { + /* don't overwrite old effects */ + continue; + } + pd = midi_last_bend_hit[c]; + } else { + pd = midi_last_bend_hit[c]; + midi_last_bend_hit[c] = k->midi_bend; + } + + + pd = (((k->midi_bend - pd) * midi_pitch_depth + / 8192) * speed) / 2; + if (pd < -0x7F) pd = -0x7F; + else if (pd > 0x7F) pd = 0x7F; + if (pd < 0) { + cur_note->effect = FX_PORTAMENTODOWN; /* Exx */ + cur_note->param = -pd; + } else if (pd > 0) { + cur_note->effect = FX_PORTAMENTOUP; /* Fxx */ + cur_note->param = pd; + } + if (k->midi_note == -1 || k->state == KEY_RELEASE) + continue; + if (cur_note->instrument < 1) + continue; + if (cur_note->voleffect == VOLFX_VOLUME) + v = cur_note->volparam; + else + v = -1; + song_keyrecord(cur_note->instrument, cur_note->instrument, cur_note->note, + v, c+1, cur_note->effect, cur_note->param); + } + } + pattern_selection_system_copyout(); - return -1; + return -1; } /* return 1 => handled key, 0 => no way */ static int pattern_editor_insert(struct key_event *k) { - int total_rows; - int ins, smp, j, n, vol; - song_note_t *pattern, *cur_note; - - total_rows = song_get_pattern(current_pattern, &pattern); - /* keydown events are handled here for multichannel */ - if (k->state && current_position) return 0; - - cur_note = pattern + 64 * current_row + current_channel - 1; - - switch (current_position) { - case 0: /* note */ - // FIXME: this is actually quite wrong; instrument numbers should be independent for each - // channel and take effect when the instrument is played (e.g. with 4/8 or keyjazz input) - // also, this is fully idiotic - smp = ins = cur_note->instrument; - if (song_is_instrument_mode()) { - smp = KEYJAZZ_NOINST; - } else { - ins = KEYJAZZ_NOINST; - } - - if (k->sym == SDLK_4) { - if (k->state) return 0; - - if (cur_note->voleffect == VOLFX_VOLUME) { - vol = cur_note->volparam; - } else { - vol = KEYJAZZ_DEFAULTVOL; - } - song_keyrecord(smp, ins, cur_note->note, - vol, current_channel, cur_note->effect, cur_note->param); - advance_cursor(!(k->mod & KMOD_SHIFT), 1); - return 1; - } else if (k->sym == SDLK_8) { - /* note: Impulse Tracker doesn't skip multichannels when pressing "8" -delt. */ - if (k->state) return 0; - song_single_step(current_pattern, current_row); - advance_cursor(!(k->mod & KMOD_SHIFT), 0); - return 1; - } - - if (song_is_instrument_mode()) { - if (edit_copy_mask & MASK_INSTRUMENT) - ins = instrument_get_current(); - } else { - if (edit_copy_mask & MASK_INSTRUMENT) - smp = sample_get_current(); - } - - - if (k->sym == SDLK_SPACE) { - /* copy mask to note */ - n = mask_note.note; - - vol = ((edit_copy_mask & MASK_VOLUME) && cur_note->voleffect == VOLFX_VOLUME) - ? mask_note.volparam - : KEYJAZZ_DEFAULTVOL; - } else { - n = kbd_get_note(k); - if (n < 0) - return 0; - - if ((edit_copy_mask & MASK_VOLUME) && mask_note.voleffect == VOLFX_VOLUME) { - vol = mask_note.volparam; - } else if (cur_note->voleffect == VOLFX_VOLUME) { - vol = cur_note->volparam; - } else { - vol = KEYJAZZ_DEFAULTVOL; - } - } + int ins, smp, j, n, vol; + song_note_t *pattern, *cur_note; + + song_get_pattern(current_pattern, &pattern); + /* keydown events are handled here for multichannel */ + if (k->state == KEY_RELEASE && current_position) + return 0; + + cur_note = pattern + 64 * current_row + current_channel - 1; + + switch (current_position) { + case 0: /* note */ + // FIXME: this is actually quite wrong; instrument numbers should be independent for each + // channel and take effect when the instrument is played (e.g. with 4/8 or keyjazz input) + // also, this is fully idiotic + smp = ins = cur_note->instrument; + if (song_is_instrument_mode()) { + smp = KEYJAZZ_NOINST; + } else { + ins = KEYJAZZ_NOINST; + } + + if (k->sym == SDLK_4) { + if (k->state == KEY_RELEASE) + return 0; + + if (cur_note->voleffect == VOLFX_VOLUME) { + vol = cur_note->volparam; + } else { + vol = KEYJAZZ_DEFAULTVOL; + } + song_keyrecord(smp, ins, cur_note->note, + vol, current_channel, cur_note->effect, cur_note->param); + advance_cursor(!(k->mod & KMOD_SHIFT), 1); + return 1; + } else if (k->sym == SDLK_8) { + /* note: Impulse Tracker doesn't skip multichannels when pressing "8" -delt. */ + if (k->state == KEY_RELEASE) + return 0; + song_single_step(current_pattern, current_row); + advance_cursor(!(k->mod & KMOD_SHIFT), 0); + return 1; + } + + if (song_is_instrument_mode()) { + if (edit_copy_mask & MASK_INSTRUMENT) + ins = instrument_get_current(); + } else { + if (edit_copy_mask & MASK_INSTRUMENT) + smp = sample_get_current(); + } + + + if (k->sym == SDLK_SPACE) { + /* copy mask to note */ + n = mask_note.note; + + vol = ((edit_copy_mask & MASK_VOLUME) && cur_note->voleffect == VOLFX_VOLUME) + ? mask_note.volparam + : KEYJAZZ_DEFAULTVOL; + } else { + n = kbd_get_note(k); + if (n < 0) + return 0; + + if ((edit_copy_mask & MASK_VOLUME) && mask_note.voleffect == VOLFX_VOLUME) { + vol = mask_note.volparam; + } else if (cur_note->voleffect == VOLFX_VOLUME) { + vol = cur_note->volparam; + } else { + vol = KEYJAZZ_DEFAULTVOL; + } + } #if 0 - /* ? */ - if ((song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP)) && playback_tracing) { - if (k->state && !(midi_flags & MIDI_RECORD_NOTEOFF)) - return 1; - song_keyup(smp, ins, n); - if (k->state) - n = NOTE_OFF; - song_keydown(smp, ins, n, vol, current_channel); - } + /* ? */ + if ((song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP)) && playback_tracing) { + if (k->state == KEY_RELEASE && !(midi_flags & MIDI_RECORD_NOTEOFF)) + return 1; + song_keyup(smp, ins, n); + if (k->state == KEY_RELEASE) + n = NOTE_OFF; + song_keydown(smp, ins, n, vol, current_channel); + } #endif - if (k->state) { - if (keyjazz_noteoff && NOTE_IS_NOTE(n)) { - /* coda mode */ - song_keyup(smp, ins, n); - } - return 1; - } - if (k->is_repeat && !keyjazz_repeat) - return 1; - - - int writenote = !(status.flags & CAPS_PRESSED); - if (writenote && !patedit_record_note(cur_note, current_channel, current_row, n, 1)) { - // there was a template error, don't advance the cursor and so on - writenote = 0; - n = NOTE_NONE; - } - /* Be quiet when pasting templates. - It'd be nice to "play" a template when pasting it (maybe only for ones that are one row high) - so as to hear the chords being inserted etc., but that's a little complicated to do. */ - if (NOTE_IS_NOTE(n) && !(template_mode && writenote)) - song_keydown(smp, ins, n, vol, current_channel); - if (!writenote) - break; - - /* Never copy the instrument etc. from the mask when inserting control notes or when - erasing a note -- but DO write it when inserting a blank note with the space key. */ - if (!(NOTE_IS_CONTROL(n) || (k->sym != SDLK_SPACE && n == NOTE_NONE)) && !template_mode) { - if (edit_copy_mask & MASK_INSTRUMENT) { - if (song_is_instrument_mode()) - cur_note->instrument = instrument_get_current(); - else - cur_note->instrument = sample_get_current(); - } - if (edit_copy_mask & MASK_VOLUME) { - cur_note->voleffect = mask_note.voleffect; - cur_note->volparam = mask_note.volparam; - } - if (edit_copy_mask & MASK_EFFECT) { - cur_note->effect = mask_note.effect; - cur_note->param = mask_note.param; - } - } - - /* try again, now that we have the effect (this is a dumb way to do this...) */ - if (NOTE_IS_NOTE(n) && !template_mode) - song_keyrecord(smp, ins, n, vol, current_channel, cur_note->effect, cur_note->param); - - /* copy the note back to the mask */ - mask_note.note = n; - pattern_selection_system_copyout(); - - n = cur_note->note; - if (NOTE_IS_NOTE(n) && cur_note->voleffect == VOLFX_VOLUME) - vol = cur_note->volparam; - if (k->mod & KMOD_SHIFT) { - // advance horizontally, stopping at channel 64 - // (I have no idea how IT does this, it might wrap) - if (current_channel < 64) { - shift_chord_channels++; - current_channel++; - pattern_editor_reposition(); - } - } else { - advance_cursor(1, 1); - } - break; - case 1: /* octave */ - j = kbd_char_to_hex(k); - if (j < 0 || j > 9) return 0; - n = cur_note->note; - if (n > 0 && n <= 120) { - /* Hehe... this was originally 7 lines :) */ - n = ((n - 1) % 12) + (12 * j) + 1; - cur_note->note = n; - } - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - pattern_selection_system_copyout(); - break; - case 2: /* instrument, first digit */ - case 3: /* instrument, second digit */ - if (k->sym == SDLK_SPACE) { - if (song_is_instrument_mode()) - n = instrument_get_current(); - else - n = sample_get_current(); - if (n && !(status.flags & CLASSIC_MODE)) - current_song->voices[current_channel - 1].last_instrument = n; - cur_note->instrument = n; - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - break; - } - if (kbd_get_note(k) == 0) { - cur_note->instrument = 0; - if (song_is_instrument_mode()) - instrument_set(0); - else - sample_set(0); - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - break; - } - - if (current_position == 2) { - j = kbd_char_to_99(k); - if (j < 0) return 0; - n = (j * 10) + (cur_note->instrument % 10); - current_position++; - } else { - j = kbd_char_to_hex(k); - if (j < 0 || j > 9) return 0; - - n = ((cur_note->instrument / 10) * 10) + j; - current_position--; - advance_cursor(1, 0); - } - - /* this is kind of ugly... */ - if (song_is_instrument_mode()) { - j = instrument_get_current(); - instrument_set(n); - if (n != instrument_get_current()) { - n = j; - } - instrument_set(j); - } else { - j = sample_get_current(); - sample_set(n); - if (n != sample_get_current()) { - n = j; - } - sample_set(j); - } - - if (n && !(status.flags & CLASSIC_MODE)) - current_song->voices[current_channel - 1].last_instrument = n; - cur_note->instrument = n; - if (song_is_instrument_mode()) - instrument_set(n); - else - sample_set(n); - status.flags |= SONG_NEEDS_SAVE; - pattern_selection_system_copyout(); - break; - case 4: - case 5: /* volume */ - if (k->sym == SDLK_SPACE) { - cur_note->volparam = mask_note.volparam; - cur_note->voleffect = mask_note.voleffect; - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - break; - } - if (kbd_get_note(k) == 0) { - cur_note->volparam = mask_note.volparam = 0; - cur_note->voleffect = mask_note.voleffect = VOLFX_NONE; - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - break; - } - if (key_scancode_lookup(k->scancode, k->sym) == SDLK_BACKQUOTE) { - panning_mode = !panning_mode; - status_text_flash("%s control set", (panning_mode ? "Panning" : "Volume")); - return 0; - } - if (!handle_volume(cur_note, k, current_position - 4)) - return 0; - mask_note.volparam = cur_note->volparam; - mask_note.voleffect = cur_note->voleffect; - if (current_position == 4) { - current_position++; - } else { - current_position = 4; - advance_cursor(1, 0); - } - status.flags |= SONG_NEEDS_SAVE; - pattern_selection_system_copyout(); - break; - case 6: /* effect */ - if (k->sym == SDLK_SPACE) { - cur_note->effect = mask_note.effect; - } else { - n = kbd_get_effect_number(k); - if (n < 0) - return 0; - cur_note->effect = mask_note.effect = n; - } - status.flags |= SONG_NEEDS_SAVE; - if (link_effect_column) - current_position++; - else - advance_cursor(1, 0); - pattern_selection_system_copyout(); - break; - case 7: /* param, high nibble */ - case 8: /* param, low nibble */ - if (k->sym == SDLK_SPACE) { - cur_note->param = mask_note.param; - current_position = link_effect_column ? 6 : 7; - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - pattern_selection_system_copyout(); - break; - } else if (kbd_get_note(k) == 0) { - cur_note->param = mask_note.param = 0; - current_position = link_effect_column ? 6 : 7; - advance_cursor(1, 0); - status.flags |= SONG_NEEDS_SAVE; - pattern_selection_system_copyout(); - break; - } - - /* FIXME: honey roasted peanuts */ - - n = kbd_char_to_hex(k); - if (n < 0) - return 0; - if (current_position == 7) { - cur_note->param = (n << 4) | (cur_note->param & 0xf); - current_position++; - } else /* current_position == 8 */ { - cur_note->param = (cur_note->param & 0xf0) | n; - current_position = link_effect_column ? 6 : 7; - advance_cursor(1, 0); - } - status.flags |= SONG_NEEDS_SAVE; - mask_note.param = cur_note->param; - pattern_selection_system_copyout(); - break; - } + if (k->state == KEY_RELEASE) { + if (keyjazz_noteoff && NOTE_IS_NOTE(n)) { + /* coda mode */ + song_keyup(smp, ins, n); + } + return 1; + } + if (k->is_repeat && !keyjazz_repeat) + return 1; + + + int writenote = !(status.flags & CAPS_PRESSED); + if (writenote && !patedit_record_note(cur_note, current_channel, current_row, n, 1)) { + // there was a template error, don't advance the cursor and so on + writenote = 0; + n = NOTE_NONE; + } + /* Be quiet when pasting templates. + It'd be nice to "play" a template when pasting it (maybe only for ones that are one row high) + so as to hear the chords being inserted etc., but that's a little complicated to do. */ + if (NOTE_IS_NOTE(n) && !(template_mode && writenote)) + song_keydown(smp, ins, n, vol, current_channel); + if (!writenote) + break; + + /* Never copy the instrument etc. from the mask when inserting control notes or when + erasing a note -- but DO write it when inserting a blank note with the space key. */ + if (!(NOTE_IS_CONTROL(n) || (k->sym != SDLK_SPACE && n == NOTE_NONE)) && !template_mode) { + if (edit_copy_mask & MASK_INSTRUMENT) { + if (song_is_instrument_mode()) + cur_note->instrument = instrument_get_current(); + else + cur_note->instrument = sample_get_current(); + } + if (edit_copy_mask & MASK_VOLUME) { + cur_note->voleffect = mask_note.voleffect; + cur_note->volparam = mask_note.volparam; + } + if (edit_copy_mask & MASK_EFFECT) { + cur_note->effect = mask_note.effect; + cur_note->param = mask_note.param; + } + } + + /* try again, now that we have the effect (this is a dumb way to do this...) */ + if (NOTE_IS_NOTE(n) && !template_mode) + song_keyrecord(smp, ins, n, vol, current_channel, cur_note->effect, cur_note->param); + + /* copy the note back to the mask */ + mask_note.note = n; + pattern_selection_system_copyout(); + + n = cur_note->note; + if (NOTE_IS_NOTE(n) && cur_note->voleffect == VOLFX_VOLUME) + vol = cur_note->volparam; + if (k->mod & KMOD_SHIFT) { + // advance horizontally, stopping at channel 64 + // (I have no idea how IT does this, it might wrap) + if (current_channel < 64) { + shift_chord_channels++; + current_channel++; + pattern_editor_reposition(); + } + } else { + advance_cursor(1, 1); + } + break; + case 1: /* octave */ + j = kbd_char_to_hex(k); + if (j < 0 || j > 9) return 0; + n = cur_note->note; + if (n > 0 && n <= 120) { + /* Hehe... this was originally 7 lines :) */ + n = ((n - 1) % 12) + (12 * j) + 1; + cur_note->note = n; + } + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + pattern_selection_system_copyout(); + break; + case 2: /* instrument, first digit */ + case 3: /* instrument, second digit */ + if (k->sym == SDLK_SPACE) { + if (song_is_instrument_mode()) + n = instrument_get_current(); + else + n = sample_get_current(); + if (n && !(status.flags & CLASSIC_MODE)) + current_song->voices[current_channel - 1].last_instrument = n; + cur_note->instrument = n; + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + break; + } + if (kbd_get_note(k) == 0) { + cur_note->instrument = 0; + if (song_is_instrument_mode()) + instrument_set(0); + else + sample_set(0); + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + break; + } + + if (current_position == 2) { + j = kbd_char_to_99(k); + if (j < 0) return 0; + n = (j * 10) + (cur_note->instrument % 10); + current_position++; + } else { + j = kbd_char_to_hex(k); + if (j < 0 || j > 9) return 0; + + n = ((cur_note->instrument / 10) * 10) + j; + current_position--; + advance_cursor(1, 0); + } + + /* this is kind of ugly... */ + if (song_is_instrument_mode()) { + j = instrument_get_current(); + instrument_set(n); + if (n != instrument_get_current()) { + n = j; + } + instrument_set(j); + } else { + j = sample_get_current(); + sample_set(n); + if (n != sample_get_current()) { + n = j; + } + sample_set(j); + } + + if (n && !(status.flags & CLASSIC_MODE)) + current_song->voices[current_channel - 1].last_instrument = n; + cur_note->instrument = n; + if (song_is_instrument_mode()) + instrument_set(n); + else + sample_set(n); + status.flags |= SONG_NEEDS_SAVE; + pattern_selection_system_copyout(); + break; + case 4: + case 5: /* volume */ + if (k->sym == SDLK_SPACE) { + cur_note->volparam = mask_note.volparam; + cur_note->voleffect = mask_note.voleffect; + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + break; + } + if (kbd_get_note(k) == 0) { + cur_note->volparam = mask_note.volparam = 0; + cur_note->voleffect = mask_note.voleffect = VOLFX_NONE; + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + break; + } + if (key_scancode_lookup(k->scancode, k->sym) == SDLK_BACKQUOTE) { + panning_mode = !panning_mode; + status_text_flash("%s control set", (panning_mode ? "Panning" : "Volume")); + return 0; + } + if (!handle_volume(cur_note, k, current_position - 4)) + return 0; + mask_note.volparam = cur_note->volparam; + mask_note.voleffect = cur_note->voleffect; + if (current_position == 4) { + current_position++; + } else { + current_position = 4; + advance_cursor(1, 0); + } + status.flags |= SONG_NEEDS_SAVE; + pattern_selection_system_copyout(); + break; + case 6: /* effect */ + if (k->sym == SDLK_SPACE) { + cur_note->effect = mask_note.effect; + } else { + n = kbd_get_effect_number(k); + if (n < 0) + return 0; + cur_note->effect = mask_note.effect = n; + } + status.flags |= SONG_NEEDS_SAVE; + if (link_effect_column) + current_position++; + else + advance_cursor(1, 0); + pattern_selection_system_copyout(); + break; + case 7: /* param, high nibble */ + case 8: /* param, low nibble */ + if (k->sym == SDLK_SPACE) { + cur_note->param = mask_note.param; + current_position = link_effect_column ? 6 : 7; + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + pattern_selection_system_copyout(); + break; + } else if (kbd_get_note(k) == 0) { + cur_note->param = mask_note.param = 0; + current_position = link_effect_column ? 6 : 7; + advance_cursor(1, 0); + status.flags |= SONG_NEEDS_SAVE; + pattern_selection_system_copyout(); + break; + } + + /* FIXME: honey roasted peanuts */ + + n = kbd_char_to_hex(k); + if (n < 0) + return 0; + if (current_position == 7) { + cur_note->param = (n << 4) | (cur_note->param & 0xf); + current_position++; + } else /* current_position == 8 */ { + cur_note->param = (cur_note->param & 0xf0) | n; + current_position = link_effect_column ? 6 : 7; + advance_cursor(1, 0); + } + status.flags |= SONG_NEEDS_SAVE; + mask_note.param = cur_note->param; + pattern_selection_system_copyout(); + break; + } - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -3341,287 +3361,324 @@ static int pattern_editor_handle_alt_key(struct key_event * k) { - int n; - int total_rows = song_get_rows_in_pattern(current_pattern); + int n; + int total_rows = song_get_rows_in_pattern(current_pattern); - /* hack to render this useful :) */ - if (k->orig_sym == SDLK_KP9) { - k->sym = SDLK_F9; - } else if (k->orig_sym == SDLK_KP0) { - k->sym = SDLK_F10; - } - - n = numeric_key_event(k, 0); - if (n > -1 && n <= 9) { - if (k->state) return 1; - skip_value = (n == 9) ? 16 : n; - status_text_flash("Cursor step set to %d", skip_value); - return 1; - } - - switch (k->sym) { - case SDLK_RETURN: - if (!k->state) return 1; - fast_save_update(); - return 1; - - case SDLK_BACKSPACE: - if (!k->state) return 1; - snap_paste(&fast_save, 0, 0, 0); - return 1; - - case SDLK_b: - if (k->state) return 1; - if (!SELECTION_EXISTS) { - selection.last_channel = current_channel; - selection.last_row = current_row; - } - selection.first_channel = current_channel; - selection.first_row = current_row; - normalise_block_selection(); - break; - case SDLK_e: - if (k->state) return 1; - if (!SELECTION_EXISTS) { - selection.first_channel = current_channel; - selection.first_row = current_row; - } - selection.last_channel = current_channel; - selection.last_row = current_row; - normalise_block_selection(); - break; - case SDLK_d: - if (k->state) return 1; - if (status.last_keysym == SDLK_d) { - if (total_rows - (current_row - 1) > block_double_size) - block_double_size <<= 1; - } else { - // emulate some weird impulse tracker behavior here: - // with row highlight set to zero, alt-d selects the whole channel - // if the cursor is at the top, and clears the selection otherwise - block_double_size = current_song->row_highlight_major ?: (current_row ? 0 : 65536); - selection.first_channel = selection.last_channel = current_channel; - selection.first_row = current_row; - } - n = block_double_size + current_row - 1; - selection.last_row = MIN(n, total_rows); - break; - case SDLK_l: - if (k->state) return 1; - if (status.last_keysym == SDLK_l) { - /* 3x alt-l re-selects the current channel */ - if (selection.first_channel == selection.last_channel) { - selection.first_channel = 1; - selection.last_channel = 64; - } else { - selection.first_channel = selection.last_channel = current_channel; - } - } else { - selection.first_channel = selection.last_channel = current_channel; - selection.first_row = 0; - selection.last_row = total_rows; - } - pattern_selection_system_copyout(); - break; - case SDLK_r: - if (k->state) return 1; - draw_divisions = 1; - set_view_scheme(0); - break; - case SDLK_s: - if (k->state) return 1; - selection_set_sample(); - break; - case SDLK_u: - if (k->state) return 1; - if (SELECTION_EXISTS) { - selection_clear(); - } else if (clipboard.data) { - clipboard_free(); - - clippy_select(NULL, NULL, 0); - clippy_yank(); - } else { - dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); - } - break; - case SDLK_c: - if (k->state) return 1; - clipboard_copy(0); - break; - case SDLK_o: - if (k->state) return 1; - if (status.last_keysym == SDLK_o) { - clipboard_paste_overwrite(0, 1); - } else { - clipboard_paste_overwrite(0, 0); - } - break; - case SDLK_p: - if (k->state) return 1; - clipboard_paste_insert(); - break; - case SDLK_m: - if (k->state) return 1; - if (status.last_keysym == SDLK_m) { - clipboard_paste_mix_fields(0, 0); - } else { - clipboard_paste_mix_notes(0, 0); - } - break; - case SDLK_f: - if (k->state) return 1; - block_length_double(); - break; - case SDLK_g: - if (k->state) return 1; - block_length_halve(); - break; - case SDLK_n: - if (k->state) return 1; - channel_multi[current_channel - 1] ^= 1; - if (channel_multi[current_channel - 1]) { - channel_multi_enabled = 1; - } else { - channel_multi_enabled = 0; - for (n = 0; n < 64; n++) { - if (channel_multi[n]) { - channel_multi_enabled = 1; - break; - } - } - } - - if (status.last_keysym == SDLK_n) { - pattern_editor_display_multichannel(); - } - break; - case SDLK_z: - if (k->state) return 1; - clipboard_copy(0); - selection_erase(); - break; - case SDLK_y: - if (k->state) return 1; - selection_swap(); - break; - case SDLK_v: - if (k->state) return 1; - selection_set_volume(); - break; - case SDLK_w: - if (k->state) return 1; - selection_wipe_volume(0); - break; - case SDLK_k: - if (k->state) return 1; - if (status.last_keysym == SDLK_k) { - selection_wipe_volume(1); - } else { - selection_slide_volume(); - } - break; - case SDLK_x: - if (k->state) return 1; - if (status.last_keysym == SDLK_x) { - selection_wipe_effect(); - } else { - selection_slide_effect(); - } - break; - case SDLK_h: - if (k->state) return 1; - draw_divisions = !draw_divisions; - recalculate_visible_area(); - pattern_editor_reposition(); - break; - case SDLK_q: - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) - transpose_notes(12); - else - transpose_notes(1); - break; - case SDLK_a: - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) - transpose_notes(-12); - else - transpose_notes(-1); - break; - case SDLK_i: - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) - template_mode = TEMPLATE_OFF; - else if (fast_volume_mode) - fast_volume_amplify(); - else - template_mode = (template_mode + 1) % TEMPLATE_MODE_MAX; /* cycle */ - break; - case SDLK_j: - if (k->state) return 1; - if (fast_volume_mode) - fast_volume_attenuate(); - else - volume_amplify(); - break; - case SDLK_t: - if (k->state) return 1; - n = current_channel - top_display_channel; - track_view_scheme[n] = ((track_view_scheme[n] + 1) % NUM_TRACK_VIEWS); - recalculate_visible_area(); - pattern_editor_reposition(); - break; - case SDLK_UP: - if (k->state) return 1; - if (top_display_row > 0) { - top_display_row--; - if (current_row > top_display_row + 31) - current_row = top_display_row + 31; - return -1; - } - return 1; - case SDLK_DOWN: - if (k->state) return 1; - if (top_display_row + 31 < total_rows) { - top_display_row++; - if (current_row < top_display_row) - current_row = top_display_row; - return -1; - } - return 1; - case SDLK_LEFT: - if (k->state) return 1; - current_channel--; - return -1; - case SDLK_RIGHT: - if (k->state) return 1; - current_channel++; - return -1; - case SDLK_INSERT: - if (k->state) return 1; - pated_save("Remove inserted row(s) (Alt-Insert)"); - pattern_insert_rows(current_row, 1, 1, 64); - break; - case SDLK_DELETE: - if (k->state) return 1; - pated_save("Replace deleted row(s) (Alt-Delete)"); - pattern_delete_rows(current_row, 1, 1, 64); - break; - case SDLK_F9: - if (k->state) return 1; - song_toggle_channel_mute(current_channel - 1); - break; - case SDLK_F10: - if (k->state) return 1; - song_handle_channel_solo(current_channel - 1); - break; - default: - return 0; - } + /* hack to render this useful :) */ + if (k->orig_sym == SDLK_KP9) { + k->sym = SDLK_F9; + } else if (k->orig_sym == SDLK_KP0) { + k->sym = SDLK_F10; + } + + n = numeric_key_event(k, 0); + if (n > -1 && n <= 9) { + if (k->state == KEY_RELEASE) + return 1; + skip_value = (n == 9) ? 16 : n; + status_text_flash("Cursor step set to %d", skip_value); + return 1; + } + + switch (k->sym) { + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 1; + fast_save_update(); + return 1; + + case SDLK_BACKSPACE: + if (k->state == KEY_PRESS) + return 1; + snap_paste(&fast_save, 0, 0, 0); + return 1; + + case SDLK_b: + if (k->state == KEY_RELEASE) + return 1; + if (!SELECTION_EXISTS) { + selection.last_channel = current_channel; + selection.last_row = current_row; + } + selection.first_channel = current_channel; + selection.first_row = current_row; + normalise_block_selection(); + break; + case SDLK_e: + if (k->state == KEY_RELEASE) + return 1; + if (!SELECTION_EXISTS) { + selection.first_channel = current_channel; + selection.first_row = current_row; + } + selection.last_channel = current_channel; + selection.last_row = current_row; + normalise_block_selection(); + break; + case SDLK_d: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_d) { + if (total_rows - (current_row - 1) > block_double_size) + block_double_size <<= 1; + } else { + // emulate some weird impulse tracker behavior here: + // with row highlight set to zero, alt-d selects the whole channel + // if the cursor is at the top, and clears the selection otherwise + block_double_size = current_song->row_highlight_major ?: (current_row ? 0 : 65536); + selection.first_channel = selection.last_channel = current_channel; + selection.first_row = current_row; + } + n = block_double_size + current_row - 1; + selection.last_row = MIN(n, total_rows); + break; + case SDLK_l: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_l) { + /* 3x alt-l re-selects the current channel */ + if (selection.first_channel == selection.last_channel) { + selection.first_channel = 1; + selection.last_channel = 64; + } else { + selection.first_channel = selection.last_channel = current_channel; + } + } else { + selection.first_channel = selection.last_channel = current_channel; + selection.first_row = 0; + selection.last_row = total_rows; + } + pattern_selection_system_copyout(); + break; + case SDLK_r: + if (k->state == KEY_RELEASE) + return 1; + draw_divisions = 1; + set_view_scheme(0); + break; + case SDLK_s: + if (k->state == KEY_RELEASE) + return 1; + selection_set_sample(); + break; + case SDLK_u: + if (k->state == KEY_RELEASE) + return 1; + if (SELECTION_EXISTS) { + selection_clear(); + } else if (clipboard.data) { + clipboard_free(); + + clippy_select(NULL, NULL, 0); + clippy_yank(); + } else { + dialog_create(DIALOG_OK, "No data in clipboard", NULL, NULL, 0, NULL); + } + break; + case SDLK_c: + if (k->state == KEY_RELEASE) + return 1; + clipboard_copy(0); + break; + case SDLK_o: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_o) { + clipboard_paste_overwrite(0, 1); + } else { + clipboard_paste_overwrite(0, 0); + } + break; + case SDLK_p: + if (k->state == KEY_RELEASE) + return 1; + clipboard_paste_insert(); + break; + case SDLK_m: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_m) { + clipboard_paste_mix_fields(0, 0); + } else { + clipboard_paste_mix_notes(0, 0); + } + break; + case SDLK_f: + if (k->state == KEY_RELEASE) + return 1; + block_length_double(); + break; + case SDLK_g: + if (k->state == KEY_RELEASE) + return 1; + block_length_halve(); + break; + case SDLK_n: + if (k->state == KEY_RELEASE) + return 1; + channel_multi[current_channel - 1] ^= 1; + if (channel_multi[current_channel - 1]) { + channel_multi_enabled = 1; + } else { + channel_multi_enabled = 0; + for (n = 0; n < 64; n++) { + if (channel_multi[n]) { + channel_multi_enabled = 1; + break; + } + } + } + + if (status.last_keysym == SDLK_n) { + pattern_editor_display_multichannel(); + } + break; + case SDLK_z: + if (k->state == KEY_RELEASE) + return 1; + clipboard_copy(0); + selection_erase(); + break; + case SDLK_y: + if (k->state == KEY_RELEASE) + return 1; + selection_swap(); + break; + case SDLK_v: + if (k->state == KEY_RELEASE) + return 1; + selection_set_volume(); + break; + case SDLK_w: + if (k->state == KEY_RELEASE) + return 1; + selection_wipe_volume(0); + break; + case SDLK_k: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_k) { + selection_wipe_volume(1); + } else { + selection_slide_volume(); + } + break; + case SDLK_x: + if (k->state == KEY_RELEASE) + return 1; + if (status.last_keysym == SDLK_x) { + selection_wipe_effect(); + } else { + selection_slide_effect(); + } + break; + case SDLK_h: + if (k->state == KEY_RELEASE) + return 1; + draw_divisions = !draw_divisions; + recalculate_visible_area(); + pattern_editor_reposition(); + break; + case SDLK_q: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) + transpose_notes(12); + else + transpose_notes(1); + break; + case SDLK_a: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) + transpose_notes(-12); + else + transpose_notes(-1); + break; + case SDLK_i: + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) + template_mode = TEMPLATE_OFF; + else if (fast_volume_mode) + fast_volume_amplify(); + else + template_mode = (template_mode + 1) % TEMPLATE_MODE_MAX; /* cycle */ + break; + case SDLK_j: + if (k->state == KEY_RELEASE) + return 1; + if (fast_volume_mode) + fast_volume_attenuate(); + else + volume_amplify(); + break; + case SDLK_t: + if (k->state == KEY_RELEASE) + return 1; + n = current_channel - top_display_channel; + track_view_scheme[n] = ((track_view_scheme[n] + 1) % NUM_TRACK_VIEWS); + recalculate_visible_area(); + pattern_editor_reposition(); + break; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + if (top_display_row > 0) { + top_display_row--; + if (current_row > top_display_row + 31) + current_row = top_display_row + 31; + return -1; + } + return 1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + if (top_display_row + 31 < total_rows) { + top_display_row++; + if (current_row < top_display_row) + current_row = top_display_row; + return -1; + } + return 1; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 1; + current_channel--; + return -1; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 1; + current_channel++; + return -1; + case SDLK_INSERT: + if (k->state == KEY_RELEASE) + return 1; + pated_save("Remove inserted row(s) (Alt-Insert)"); + pattern_insert_rows(current_row, 1, 1, 64); + break; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 1; + pated_save("Replace deleted row(s) (Alt-Delete)"); + pattern_delete_rows(current_row, 1, 1, 64); + break; + case SDLK_F9: + if (k->state == KEY_RELEASE) + return 1; + song_toggle_channel_mute(current_channel - 1); + break; + case SDLK_F10: + if (k->state == KEY_RELEASE) + return 1; + song_handle_channel_solo(current_channel - 1); + break; + default: + return 0; + } - status.flags |= NEED_UPDATE; - return 1; + status.flags |= NEED_UPDATE; + return 1; } /* Two atoms are walking down the street, and one of them stops abruptly @@ -3630,562 +3687,607 @@ * The first one says, "Yes, I'm positive!" */ static int pattern_editor_handle_ctrl_key(struct key_event * k) { - int n; - int total_rows = song_get_rows_in_pattern(current_pattern); + int n; + int total_rows = song_get_rows_in_pattern(current_pattern); - n = numeric_key_event(k, 0); - if (n > -1) { - if (n < 0 || n >= NUM_TRACK_VIEWS) - return 0; - if (k->state) return 1; - if (k->mod & KMOD_SHIFT) { - set_view_scheme(n); - } else { - track_view_scheme[current_channel - top_display_channel] = n; - recalculate_visible_area(); - } - pattern_editor_reposition(); - status.flags |= NEED_UPDATE; - return 1; - } - - - switch (k->sym) { - case SDLK_LEFT: - if (k->state) return 1; - if (current_channel > top_display_channel) - current_channel--; - return -1; - case SDLK_RIGHT: - if (k->state) return 1; - if (current_channel < top_display_channel + visible_channels - 1) - current_channel++; - return -1; - case SDLK_F6: - if (k->state) return 1; - song_loop_pattern(current_pattern, current_row); - return 1; - case SDLK_F7: - if (k->state) return 1; - set_playback_mark(); - return -1; - case SDLK_UP: - if (k->state) return 1; - set_previous_instrument(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_DOWN: - if (k->state) return 1; - set_next_instrument(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_PAGEUP: - if (k->state) return 1; - current_row = 0; - return -1; - case SDLK_PAGEDOWN: - if (k->state) return 1; - current_row = total_rows; - return -1; - case SDLK_HOME: - if (k->state) return 1; - current_row--; - return -1; - case SDLK_END: - if (k->state) return 1; - current_row++; - return -1; - case SDLK_MINUS: - if (k->state) return 1; - if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing) - return 1; - prev_order_pattern(); - return 1; - case SDLK_PLUS: - if (k->state) return 1; - if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing) - return 1; - next_order_pattern(); - return 1; - case SDLK_c: - if (k->state) return 1; - centralise_cursor = !centralise_cursor; - status_text_flash("Centralise cursor %s", (centralise_cursor ? "enabled" : "disabled")); - return -1; - case SDLK_h: - if (k->state) return 1; - highlight_current_row = !highlight_current_row; - status_text_flash("Row hilight %s", (highlight_current_row ? "enabled" : "disabled")); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_j: - if (k->state) return 1; - fast_volume_toggle(); - return 1; - case SDLK_u: - if (k->state) return 1; - if (fast_volume_mode) - selection_vary(1, 100-fast_volume_percent, FX_CHANNELVOLUME); - else - vary_command(FX_CHANNELVOLUME); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_y: - if (k->state) return 1; - if (fast_volume_mode) - selection_vary(1, 100-fast_volume_percent, FX_PANBRELLO); - else - vary_command(FX_PANBRELLO); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_k: - if (k->state) return 1; - if (fast_volume_mode) - selection_vary(1, 100-fast_volume_percent, current_effect()); - else - vary_command(current_effect()); - status.flags |= NEED_UPDATE; - return 1; - - case SDLK_b: - if (k->mod & KMOD_SHIFT) - return 0; - /* fall through */ - case SDLK_o: - if (k->state) return 1; - song_pattern_to_sample(current_pattern, !!(k->mod & KMOD_SHIFT), !!(k->sym == SDLK_b)); - return 1; - - case SDLK_v: - if (k->state) return 1; - show_default_volumes = !show_default_volumes; - status_text_flash("Default volumes %s", (show_default_volumes ? "enabled" : "disabled")); - return 1; - case SDLK_x: - case SDLK_z: - if (k->state) return 1; - midi_start_record++; - if (midi_start_record > 2) midi_start_record = 0; - switch (midi_start_record) { - case 0: - status_text_flash("No MIDI Trigger"); - break; - case 1: - status_text_flash("Pattern MIDI Trigger"); - break; - case 2: - status_text_flash("Song MIDI Trigger"); - break; - }; - return 1; - case SDLK_BACKSPACE: - if (k->state) return 1; - pattern_editor_display_history(); - return 1; - default: - return 0; - } + n = numeric_key_event(k, 0); + if (n > -1) { + if (n < 0 || n >= NUM_TRACK_VIEWS) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (k->mod & KMOD_SHIFT) { + set_view_scheme(n); + } else { + track_view_scheme[current_channel - top_display_channel] = n; + recalculate_visible_area(); + } + pattern_editor_reposition(); + status.flags |= NEED_UPDATE; + return 1; + } + + + switch (k->sym) { + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 1; + if (current_channel > top_display_channel) + current_channel--; + return -1; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 1; + if (current_channel < top_display_channel + visible_channels - 1) + current_channel++; + return -1; + case SDLK_F6: + if (k->state == KEY_RELEASE) + return 1; + song_loop_pattern(current_pattern, current_row); + return 1; + case SDLK_F7: + if (k->state == KEY_RELEASE) + return 1; + set_playback_mark(); + return -1; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 1; + set_previous_instrument(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 1; + set_next_instrument(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 1; + current_row = 0; + return -1; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 1; + current_row = total_rows; + return -1; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 1; + current_row--; + return -1; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 1; + current_row++; + return -1; + case SDLK_MINUS: + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing) + return 1; + prev_order_pattern(); + return 1; + case SDLK_PLUS: + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing) + return 1; + next_order_pattern(); + return 1; + case SDLK_c: + if (k->state == KEY_RELEASE) + return 1; + centralise_cursor = !centralise_cursor; + status_text_flash("Centralise cursor %s", (centralise_cursor ? "enabled" : "disabled")); + return -1; + case SDLK_h: + if (k->state == KEY_RELEASE) + return 1; + highlight_current_row = !highlight_current_row; + status_text_flash("Row hilight %s", (highlight_current_row ? "enabled" : "disabled")); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_j: + if (k->state == KEY_RELEASE) + return 1; + fast_volume_toggle(); + return 1; + case SDLK_u: + if (k->state == KEY_RELEASE) + return 1; + if (fast_volume_mode) + selection_vary(1, 100-fast_volume_percent, FX_CHANNELVOLUME); + else + vary_command(FX_CHANNELVOLUME); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_y: + if (k->state == KEY_RELEASE) + return 1; + if (fast_volume_mode) + selection_vary(1, 100-fast_volume_percent, FX_PANBRELLO); + else + vary_command(FX_PANBRELLO); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_k: + if (k->state == KEY_RELEASE) + return 1; + if (fast_volume_mode) + selection_vary(1, 100-fast_volume_percent, current_effect()); + else + vary_command(current_effect()); + status.flags |= NEED_UPDATE; + return 1; + + case SDLK_b: + if (k->mod & KMOD_SHIFT) + return 0; + /* fall through */ + case SDLK_o: + if (k->state == KEY_RELEASE) + return 1; + song_pattern_to_sample(current_pattern, !!(k->mod & KMOD_SHIFT), !!(k->sym == SDLK_b)); + return 1; + + case SDLK_v: + if (k->state == KEY_RELEASE) + return 1; + show_default_volumes = !show_default_volumes; + status_text_flash("Default volumes %s", (show_default_volumes ? "enabled" : "disabled")); + return 1; + case SDLK_x: + case SDLK_z: + if (k->state == KEY_RELEASE) + return 1; + midi_start_record++; + if (midi_start_record > 2) midi_start_record = 0; + switch (midi_start_record) { + case 0: + status_text_flash("No MIDI Trigger"); + break; + case 1: + status_text_flash("Pattern MIDI Trigger"); + break; + case 2: + status_text_flash("Song MIDI Trigger"); + break; + }; + return 1; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 1; + pattern_editor_display_history(); + return 1; + default: + return 0; + } - return 0; + return 0; } static int mute_toggle_hack[64]; /* mrsbrisby: please explain this one, i don't get why it's necessary... */ static int pattern_editor_handle_key_default(struct key_event * k) { - /* bleah */ - if (k->sym == SDLK_LESS || k->sym == SDLK_COLON || k->sym == SDLK_SEMICOLON) { - if (k->state) return 0; - if ((status.flags & CLASSIC_MODE) || current_position != 4) { - set_previous_instrument(); - status.flags |= NEED_UPDATE; - return 1; - } - } else if (k->sym == SDLK_GREATER || k->sym == SDLK_QUOTE || k->sym == SDLK_QUOTEDBL) { - if (k->state) return 0; - if ((status.flags & CLASSIC_MODE) || current_position != 4) { - set_next_instrument(); - status.flags |= NEED_UPDATE; - return 1; - } - } else if (k->sym == SDLK_COMMA) { - if (k->state) return 0; - switch (current_position) { - case 2: case 3: - edit_copy_mask ^= MASK_INSTRUMENT; - break; - case 4: case 5: - edit_copy_mask ^= MASK_VOLUME; - break; - case 6: case 7: case 8: - edit_copy_mask ^= MASK_EFFECT; - break; - } - status.flags |= NEED_UPDATE; - return 1; - } - if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing && k->is_repeat) - return 0; - - if (!pattern_editor_insert(k)) - return 0; - return -1; + /* bleah */ + if (k->sym == SDLK_LESS || k->sym == SDLK_COLON || k->sym == SDLK_SEMICOLON) { + if (k->state == KEY_RELEASE) + return 0; + if ((status.flags & CLASSIC_MODE) || current_position != 4) { + set_previous_instrument(); + status.flags |= NEED_UPDATE; + return 1; + } + } else if (k->sym == SDLK_GREATER || k->sym == SDLK_QUOTE || k->sym == SDLK_QUOTEDBL) { + if (k->state == KEY_RELEASE) + return 0; + if ((status.flags & CLASSIC_MODE) || current_position != 4) { + set_next_instrument(); + status.flags |= NEED_UPDATE; + return 1; + } + } else if (k->sym == SDLK_COMMA) { + if (k->state == KEY_RELEASE) + return 0; + switch (current_position) { + case 2: case 3: + edit_copy_mask ^= MASK_INSTRUMENT; + break; + case 4: case 5: + edit_copy_mask ^= MASK_VOLUME; + break; + case 6: case 7: case 8: + edit_copy_mask ^= MASK_EFFECT; + break; + } + status.flags |= NEED_UPDATE; + return 1; + } + if (song_get_mode() & (MODE_PLAYING|MODE_PATTERN_LOOP) && playback_tracing && k->is_repeat) + return 0; + + if (!pattern_editor_insert(k)) + return 0; + return -1; } static int pattern_editor_handle_key(struct key_event * k) { - int n, nx, v; - int total_rows = song_get_rows_in_pattern(current_pattern); - const struct track_view *track_view; - int np, nr, nc; - unsigned int basex; - - if (k->mouse) { - if (k->state) { - /* mouseup */ - memset(mute_toggle_hack, 0, sizeof(mute_toggle_hack)); - } - - if ((k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) && k->state) { - shift_selection_end(); - } - - if (k->y < 13 && !shift_selection.in_progress) return 0; - - if (k->y >= 15 && k->mouse != MOUSE_CLICK && k->mouse != MOUSE_DBLCLICK) { - if (k->state) return 0; - if (k->mouse == MOUSE_SCROLL_UP) { - if (top_display_row > 0) { - top_display_row = MAX(top_display_row - MOUSE_SCROLL_LINES, 0); - if (current_row > top_display_row + 31) - current_row = top_display_row + 31; - if (current_row < 0) - current_row = 0; - return -1; - } - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - if (top_display_row + 31 < total_rows) { - top_display_row = MIN(top_display_row + MOUSE_SCROLL_LINES, total_rows); - if (current_row < top_display_row) - current_row = top_display_row; - return -1; - } - } - return 1; - } - - if (k->mouse != MOUSE_CLICK && k->mouse != MOUSE_DBLCLICK) - return 1; - - basex = 5; - if (current_row < 0) current_row = 0; - if (current_row >= total_rows) current_row = total_rows; - np = current_position; nc = current_channel; nr = current_row; - for (n = top_display_channel, nx = 0; nx <= visible_channels; n++, nx++) { - track_view = track_views+track_view_scheme[nx]; - if (((n == top_display_channel && shift_selection.in_progress) - || k->x >= basex) - && ((n == visible_channels && shift_selection.in_progress) - || k->x < basex + track_view->width)) { - if (!shift_selection.in_progress && (k->y == 14 || k->y == 13)) { - if (!k->state) { - if (!mute_toggle_hack[n-1]) { - song_toggle_channel_mute(n-1); - status.flags |= NEED_UPDATE; - mute_toggle_hack[n-1]=1; - } - } - break; - } - - nc = n; - nr = (k->y - 15) + top_display_row; - - if (k->y < 15 && top_display_row > 0) { - top_display_row--; - } - - - if (shift_selection.in_progress) break; - - v = k->x - basex; - switch (track_view_scheme[nx]) { - case 0: /* 5 channel view */ - switch (v) { - case 0: np = 0; break; - case 2: np = 1; break; - case 4: np = 2; break; - case 5: np = 3; break; - case 7: np = 4; break; - case 8: np = 5; break; - case 10: np = 6; break; - case 11: np = 7; break; - case 12: np = 8; break; - }; - break; - case 1: /* 6/7 channels */ - switch (v) { - case 0: np = 0; break; - case 2: np = 1; break; - case 3: np = 2; break; - case 4: np = 3; break; - case 5: np = 4; break; - case 6: np = 5; break; - case 7: np = 6; break; - case 8: np = 7; break; - case 9: np = 8; break; - }; - break; - case 2: /* 9/10 channels */ - switch (v) { - case 0: np = 0; break; - case 2: np = 1; break; - case 3: np = 2 + k->hx; break; - case 4: np = 4 + k->hx; break; - case 5: np = 6; break; - case 6: np = 7 + k->hx; break; - }; - break; - case 3: /* 18/24 channels */ - switch (v) { - case 0: np = 0; break; - case 1: np = 1; break; - case 2: np = 2 + k->hx; break; - case 3: np = 4 + k->hx; break; - case 4: np = 6; break; - case 5: np = 7 + k->hx; break; - }; - break; - case 4: /* now things get weird: 24/36 channels */ - case 5: /* now things get weird: 36/64 channels */ - case 6: /* no point doing anything here; reset */ - np = 0; - break; - }; - break; - } - basex += track_view->width; - if (draw_divisions) basex++; - } - if (np == current_position && nc == current_channel && nr == current_row) { - return 1; - } - - if (nr >= total_rows) nr = total_rows; - if (nr < 0) nr = 0; - current_position = np; current_channel = nc; current_row = nr; - - if (!k->state && k->sy > 14) { - if (!shift_selection.in_progress) { - shift_selection_begin(); - } else { - shift_selection_update(); - } - } - - return -1; - } - - - if (k->midi_note > -1 || k->midi_bend != 0) { - return pattern_editor_insert_midi(k); - } - - switch (k->sym) { - case SDLK_UP: - if (k->state) return 0; - if (skip_value) { - if (current_row - skip_value >= 0) - current_row -= skip_value; - } else { - current_row--; - } - return -1; - case SDLK_DOWN: - if (k->state) return 0; - if (skip_value) { - if (current_row + skip_value <= total_rows) - current_row += skip_value; - } else { - current_row++; - } - return -1; - case SDLK_LEFT: - if (k->state) return 0; - if (k->mod & KMOD_SHIFT) { - current_channel--; - } else if (link_effect_column && current_position == 0 && current_channel > 1) { - current_channel--; - current_position = current_effect() ? 8 : 6; - } else { - current_position--; - } - return -1; - case SDLK_RIGHT: - if (k->state) return 0; - if (k->mod & KMOD_SHIFT) { - current_channel++; - } else if (link_effect_column && current_position == 6 && current_channel < 64) { - current_position = current_effect() ? 7 : 10; - } else { - current_position++; - } - return -1; - case SDLK_TAB: - if (k->state) return 0; - if ((k->mod & KMOD_SHIFT) == 0) - current_channel++; - else if (current_position == 0) - current_channel--; - current_position = 0; - - /* hack to keep shift-tab from changing the selection */ - k->mod &= ~KMOD_SHIFT; - shift_selection_end(); - - return -1; - case SDLK_PAGEUP: - if (k->state) return 0; - { - int rh = current_song->row_highlight_major ?: 16; - if (current_row == total_rows) - current_row -= (current_row % rh) ?: rh; - else - current_row -= rh; - } - return -1; - case SDLK_PAGEDOWN: - if (k->state) return 0; - current_row += current_song->row_highlight_major ?: 16; - return -1; - case SDLK_HOME: - if (k->state) return 0; - if (current_position == 0) { - if (current_channel == 1) - current_row = 0; - else - current_channel = 1; - } else { - current_position = 0; - } - return -1; - case SDLK_END: - if (k->state) return 0; - n = song_find_last_channel(); - if (current_position == 8) { - if (current_channel == n) - current_row = total_rows; - else - current_channel = n; - } else { - current_position = 8; - } - return -1; - case SDLK_INSERT: - if (k->state) return 0; - if (template_mode && clipboard.rows == 1) { - n = clipboard.channels; - if (n + current_channel > 64) { - n = 64 - current_channel; - } - pattern_insert_rows(current_row, 1, current_channel, n); - } else { - pattern_insert_rows(current_row, 1, current_channel, 1); - } - break; - case SDLK_DELETE: - if (k->state) return 0; - if (template_mode && clipboard.rows == 1) { - n = clipboard.channels; - if (n + current_channel > 64) { - n = 64 - current_channel; - } - pattern_delete_rows(current_row, 1, current_channel, n); - } else { - pattern_delete_rows(current_row, 1, current_channel, 1); - } - break; - case SDLK_MINUS: - if (k->state) return 0; - - if (playback_tracing) { - switch (song_get_mode()) { - case MODE_PATTERN_LOOP: - return 1; - case MODE_PLAYING: - song_set_current_order(song_get_current_order() - 1); - return 1; - default: - break; - }; - } - - if (k->mod & KMOD_SHIFT) - set_current_pattern(current_pattern - 4); - else - set_current_pattern(current_pattern - 1); - return 1; - case SDLK_PLUS: - if (k->state) return 0; - - if (playback_tracing) { - switch (song_get_mode()) { - case MODE_PATTERN_LOOP: - return 1; - case MODE_PLAYING: - song_set_current_order(song_get_current_order() + 1); - return 1; - default: - break; - }; - } - - if ((k->mod & KMOD_SHIFT) && k->orig_sym == SDLK_KP_PLUS) - set_current_pattern(current_pattern + 4); - else - set_current_pattern(current_pattern + 1); - return 1; - case SDLK_BACKSPACE: - if (k->state) return 0; - current_channel = multichannel_get_previous (current_channel); - if (skip_value) - current_row -= skip_value; - else - current_row--; - return -1; - case SDLK_RETURN: - if (k->state) return 0; - copy_note_to_mask(); - if (template_mode != TEMPLATE_NOTES_ONLY) - template_mode = TEMPLATE_OFF; - return 1; - case SDLK_l: - if (k->mod & KMOD_SHIFT) { - if (status.flags & CLASSIC_MODE) return 0; - if (k->state) return 1; - clipboard_copy(1); - break; - } - return pattern_editor_handle_key_default(k); - - case SDLK_LSHIFT: - case SDLK_RSHIFT: - if (!k->state) { - if (shift_selection.in_progress) - shift_selection_end(); - } else if (shift_chord_channels) { - current_channel -= shift_chord_channels; - while (current_channel < 1) - current_channel += 64; - advance_cursor(1, 1); - shift_chord_channels = 0; - } - return 1; - - default: - return pattern_editor_handle_key_default(k); - } + int n, nx, v; + int total_rows = song_get_rows_in_pattern(current_pattern); + const struct track_view *track_view; + int np, nr, nc; + unsigned int basex; + + if (k->mouse != MOUSE_NONE) { + if (k->state == KEY_RELEASE) { + /* mouseup */ + memset(mute_toggle_hack, 0, sizeof(mute_toggle_hack)); + } + + if ((k->mouse == MOUSE_CLICK || k->mouse == MOUSE_DBLCLICK) && k->state == KEY_RELEASE) { + shift_selection_end(); + } + + if (k->y < 13 && !shift_selection.in_progress) return 0; + + if (k->y >= 15 && k->mouse != MOUSE_CLICK && k->mouse != MOUSE_DBLCLICK) { + if (k->state == KEY_RELEASE) + return 0; + if (k->mouse == MOUSE_SCROLL_UP) { + if (top_display_row > 0) { + top_display_row = MAX(top_display_row - MOUSE_SCROLL_LINES, 0); + if (current_row > top_display_row + 31) + current_row = top_display_row + 31; + if (current_row < 0) + current_row = 0; + return -1; + } + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + if (top_display_row + 31 < total_rows) { + top_display_row = MIN(top_display_row + MOUSE_SCROLL_LINES, total_rows); + if (current_row < top_display_row) + current_row = top_display_row; + return -1; + } + } + return 1; + } + + if (k->mouse != MOUSE_CLICK && k->mouse != MOUSE_DBLCLICK) + return 1; + + basex = 5; + if (current_row < 0) current_row = 0; + if (current_row >= total_rows) current_row = total_rows; + np = current_position; nc = current_channel; nr = current_row; + for (n = top_display_channel, nx = 0; nx <= visible_channels; n++, nx++) { + track_view = track_views+track_view_scheme[nx]; + if (((n == top_display_channel && shift_selection.in_progress) + || k->x >= basex) + && ((n == visible_channels && shift_selection.in_progress) + || k->x < basex + track_view->width)) { + if (!shift_selection.in_progress && (k->y == 14 || k->y == 13)) { + if (k->state == KEY_PRESS) { + if (!mute_toggle_hack[n-1]) { + song_toggle_channel_mute(n-1); + status.flags |= NEED_UPDATE; + mute_toggle_hack[n-1]=1; + } + } + break; + } + + nc = n; + nr = (k->y - 15) + top_display_row; + + if (k->y < 15 && top_display_row > 0) { + top_display_row--; + } + + + if (shift_selection.in_progress) break; + + v = k->x - basex; + switch (track_view_scheme[nx]) { + case 0: /* 5 channel view */ + switch (v) { + case 0: np = 0; break; + case 2: np = 1; break; + case 4: np = 2; break; + case 5: np = 3; break; + case 7: np = 4; break; + case 8: np = 5; break; + case 10: np = 6; break; + case 11: np = 7; break; + case 12: np = 8; break; + }; + break; + case 1: /* 6/7 channels */ + switch (v) { + case 0: np = 0; break; + case 2: np = 1; break; + case 3: np = 2; break; + case 4: np = 3; break; + case 5: np = 4; break; + case 6: np = 5; break; + case 7: np = 6; break; + case 8: np = 7; break; + case 9: np = 8; break; + }; + break; + case 2: /* 9/10 channels */ + switch (v) { + case 0: np = 0; break; + case 2: np = 1; break; + case 3: np = 2 + k->hx; break; + case 4: np = 4 + k->hx; break; + case 5: np = 6; break; + case 6: np = 7 + k->hx; break; + }; + break; + case 3: /* 18/24 channels */ + switch (v) { + case 0: np = 0; break; + case 1: np = 1; break; + case 2: np = 2 + k->hx; break; + case 3: np = 4 + k->hx; break; + case 4: np = 6; break; + case 5: np = 7 + k->hx; break; + }; + break; + case 4: /* now things get weird: 24/36 channels */ + case 5: /* now things get weird: 36/64 channels */ + case 6: /* no point doing anything here; reset */ + np = 0; + break; + }; + break; + } + basex += track_view->width; + if (draw_divisions) basex++; + } + if (np == current_position && nc == current_channel && nr == current_row) { + return 1; + } + + if (nr >= total_rows) nr = total_rows; + if (nr < 0) nr = 0; + current_position = np; current_channel = nc; current_row = nr; + + if (k->state == KEY_PRESS && k->sy > 14) { + if (!shift_selection.in_progress) { + shift_selection_begin(); + } else { + shift_selection_update(); + } + } + + return -1; + } + + + if (k->midi_note > -1 || k->midi_bend != 0) { + return pattern_editor_insert_midi(k); + } + + switch (k->sym) { + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + if (skip_value) { + if (current_row - skip_value >= 0) + current_row -= skip_value; + } else { + current_row--; + } + return -1; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + if (skip_value) { + if (current_row + skip_value <= total_rows) + current_row += skip_value; + } else { + current_row++; + } + return -1; + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_SHIFT) { + current_channel--; + } else if (link_effect_column && current_position == 0 && current_channel > 1) { + current_channel--; + current_position = current_effect() ? 8 : 6; + } else { + current_position--; + } + return -1; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_SHIFT) { + current_channel++; + } else if (link_effect_column && current_position == 6 && current_channel < 64) { + current_position = current_effect() ? 7 : 10; + } else { + current_position++; + } + return -1; + case SDLK_TAB: + if (k->state == KEY_RELEASE) + return 0; + if ((k->mod & KMOD_SHIFT) == 0) + current_channel++; + else if (current_position == 0) + current_channel--; + current_position = 0; + + /* hack to keep shift-tab from changing the selection */ + k->mod &= ~KMOD_SHIFT; + shift_selection_end(); + + return -1; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + { + int rh = current_song->row_highlight_major ?: 16; + if (current_row == total_rows) + current_row -= (current_row % rh) ?: rh; + else + current_row -= rh; + } + return -1; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + current_row += current_song->row_highlight_major ?: 16; + return -1; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + if (current_position == 0) { + if (invert_home_end ? (current_row != 0) : (current_channel == 1)) { + current_row = 0; + } else { + current_channel = 1; + } + } else { + current_position = 0; + } + return -1; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + n = song_find_last_channel(); + if (current_position == 8) { + if (invert_home_end ? (current_row != total_rows) : (current_channel == n)) { + current_row = total_rows; + } else { + current_channel = n; + } + } else { + current_position = 8; + } + return -1; + case SDLK_INSERT: + if (k->state == KEY_RELEASE) + return 0; + if (template_mode && clipboard.rows == 1) { + n = clipboard.channels; + if (n + current_channel > 64) { + n = 64 - current_channel; + } + pattern_insert_rows(current_row, 1, current_channel, n); + } else { + pattern_insert_rows(current_row, 1, current_channel, 1); + } + break; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 0; + if (template_mode && clipboard.rows == 1) { + n = clipboard.channels; + if (n + current_channel > 64) { + n = 64 - current_channel; + } + pattern_delete_rows(current_row, 1, current_channel, n); + } else { + pattern_delete_rows(current_row, 1, current_channel, 1); + } + break; + case SDLK_MINUS: + if (k->state == KEY_RELEASE) + return 0; + + if (playback_tracing) { + switch (song_get_mode()) { + case MODE_PATTERN_LOOP: + return 1; + case MODE_PLAYING: + song_set_current_order(song_get_current_order() - 1); + return 1; + default: + break; + }; + } + + if (k->mod & KMOD_SHIFT) + set_current_pattern(current_pattern - 4); + else + set_current_pattern(current_pattern - 1); + return 1; + case SDLK_PLUS: + if (k->state == KEY_RELEASE) + return 0; + + if (playback_tracing) { + switch (song_get_mode()) { + case MODE_PATTERN_LOOP: + return 1; + case MODE_PLAYING: + song_set_current_order(song_get_current_order() + 1); + return 1; + default: + break; + }; + } + + if ((k->mod & KMOD_SHIFT) && k->orig_sym == SDLK_KP_PLUS) + set_current_pattern(current_pattern + 4); + else + set_current_pattern(current_pattern + 1); + return 1; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 0; + current_channel = multichannel_get_previous (current_channel); + if (skip_value) + current_row -= skip_value; + else + current_row--; + return -1; + case SDLK_RETURN: + if (k->state == KEY_RELEASE) + return 0; + copy_note_to_mask(); + if (template_mode != TEMPLATE_NOTES_ONLY) + template_mode = TEMPLATE_OFF; + return 1; + case SDLK_l: + if (k->mod & KMOD_SHIFT) { + if (status.flags & CLASSIC_MODE) return 0; + if (k->state == KEY_RELEASE) + return 1; + clipboard_copy(1); + break; + } + return pattern_editor_handle_key_default(k); + + case SDLK_LSHIFT: + case SDLK_RSHIFT: + if (k->state == KEY_PRESS) { + if (shift_selection.in_progress) + shift_selection_end(); + } else if (shift_chord_channels) { + current_channel -= shift_chord_channels; + while (current_channel < 1) + current_channel += 64; + advance_cursor(1, 1); + shift_chord_channels = 0; + } + return 1; + + default: + return pattern_editor_handle_key_default(k); + } - status.flags |= NEED_UPDATE; - return 1; + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------- */ @@ -4195,130 +4297,132 @@ static int pattern_editor_handle_key_cb(struct key_event * k) { - int ret; - int total_rows = song_get_rows_in_pattern(current_pattern); + int ret; + int total_rows = song_get_rows_in_pattern(current_pattern); - if (k->mod & KMOD_SHIFT) { - switch (k->sym) { - case SDLK_LEFT: - case SDLK_RIGHT: - case SDLK_UP: - case SDLK_DOWN: - case SDLK_HOME: - case SDLK_END: - case SDLK_PAGEUP: - case SDLK_PAGEDOWN: - if (k->state) return 0; - if (!shift_selection.in_progress) - shift_selection_begin(); - default: - break; - }; - } - - if (k->mod & KMOD_ALT) - ret = pattern_editor_handle_alt_key(k); - else if (k->mod & KMOD_CTRL) - ret = pattern_editor_handle_ctrl_key(k); - else - ret = pattern_editor_handle_key(k); - - if (ret != -1) - return ret; - - current_row = CLAMP(current_row, 0, total_rows); - if (current_position > 8) { - if (current_channel < 64) { - current_position = 0; - current_channel++; - } else { - current_position = 8; - } - } else if (current_position < 0) { - if (current_channel > 1) { - current_position = 8; - current_channel--; - } else { - current_position = 0; - } - } - - current_channel = CLAMP(current_channel, 1, 64); - pattern_editor_reposition(); - if (k->mod & KMOD_SHIFT) - shift_selection_update(); + if (k->mod & KMOD_SHIFT) { + switch (k->sym) { + case SDLK_LEFT: + case SDLK_RIGHT: + case SDLK_UP: + case SDLK_DOWN: + case SDLK_HOME: + case SDLK_END: + case SDLK_PAGEUP: + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + if (!shift_selection.in_progress) + shift_selection_begin(); + default: + break; + }; + } + + if (k->mod & KMOD_ALT) + ret = pattern_editor_handle_alt_key(k); + else if (k->mod & KMOD_CTRL) + ret = pattern_editor_handle_ctrl_key(k); + else + ret = pattern_editor_handle_key(k); + + if (ret != -1) + return ret; + + current_row = CLAMP(current_row, 0, total_rows); + if (current_position > 8) { + if (current_channel < 64) { + current_position = 0; + current_channel++; + } else { + current_position = 8; + } + } else if (current_position < 0) { + if (current_channel > 1) { + current_position = 8; + current_channel--; + } else { + current_position = 0; + } + } + + current_channel = CLAMP(current_channel, 1, 64); + pattern_editor_reposition(); + if (k->mod & KMOD_SHIFT) + shift_selection_update(); - status.flags |= NEED_UPDATE; - return 1; + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------- */ static void pattern_editor_playback_update(void) { - static int prev_row = -1; - static int prev_pattern = -1; + static int prev_row = -1; + static int prev_pattern = -1; - playing_row = song_get_current_row(); - playing_pattern = song_get_playing_pattern(); + playing_row = song_get_current_row(); + playing_pattern = song_get_playing_pattern(); - if ((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) != 0 - && (playing_row != prev_row || playing_pattern != prev_pattern)) { + if ((song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP)) != 0 + && (playing_row != prev_row || playing_pattern != prev_pattern)) { - prev_row = playing_row; - prev_pattern = playing_pattern; - - if (playback_tracing) { - set_current_order(song_get_current_order()); - set_current_pattern(playing_pattern); - current_row = playing_row; - pattern_editor_reposition(); - status.flags |= NEED_UPDATE; - } else if (current_pattern == playing_pattern) { - status.flags |= NEED_UPDATE; - } - } + prev_row = playing_row; + prev_pattern = playing_pattern; + + if (playback_tracing) { + set_current_order(song_get_current_order()); + set_current_pattern(playing_pattern); + current_row = playing_row; + pattern_editor_reposition(); + status.flags |= NEED_UPDATE; + } else if (current_pattern == playing_pattern) { + status.flags |= NEED_UPDATE; + } + } } static void pated_song_changed(void) { - pated_history_clear(); + pated_history_clear(); - // reset ctrl-f7 - marked_pattern = -1; - marked_row = 0; + // reset ctrl-f7 + marked_pattern = -1; + marked_row = 0; } /* --------------------------------------------------------------------- */ static int _fix_f7(struct key_event *k) { - if (k->sym == SDLK_F7) { - if (!NO_MODIFIER(k->mod)) return 0; - if (k->state) return 1; - play_song_from_mark(); - return 1; - } - return 0; + if (k->sym == SDLK_F7) { + if (!NO_MODIFIER(k->mod)) return 0; + if (k->state == KEY_RELEASE) + return 1; + play_song_from_mark(); + return 1; + } + return 0; } void pattern_editor_load_page(struct page *page) { - int i; - for (i = 0; i < 10; i++) { - memset(&undo_history[i],0,sizeof(struct pattern_snap)); - undo_history[i].snap_op = "Empty"; - undo_history[i].snap_op_allocated = 0; - } - page->title = "Pattern Editor (F2)"; - page->playback_update = pattern_editor_playback_update; - page->song_changed_cb = pated_song_changed; - page->pre_handle_key = _fix_f7; - page->total_widgets = 1; - page->clipboard_paste = pattern_selection_system_paste; - page->widgets = widgets_pattern; - page->help_index = HELP_PATTERN_EDITOR; + int i; + for (i = 0; i < 10; i++) { + memset(&undo_history[i],0,sizeof(struct pattern_snap)); + undo_history[i].snap_op = "Empty"; + undo_history[i].snap_op_allocated = 0; + } + page->title = "Pattern Editor (F2)"; + page->playback_update = pattern_editor_playback_update; + page->song_changed_cb = pated_song_changed; + page->pre_handle_key = _fix_f7; + page->total_widgets = 1; + page->clipboard_paste = pattern_selection_system_paste; + page->widgets = widgets_pattern; + page->help_index = HELP_PATTERN_EDITOR; - create_other(widgets_pattern + 0, 0, pattern_editor_handle_key_cb, pattern_editor_redraw); + create_other(widgets_pattern + 0, 0, pattern_editor_handle_key_cb, pattern_editor_redraw); } diff -Nru schism-0+20110101/schism/page_preferences.c schism-20160521/schism/page_preferences.c --- schism-0+20110101/schism/page_preferences.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_preferences.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -41,226 +41,207 @@ static struct widget widgets_preferences[48]; static const char *interpolation_modes[] = { - "Non-Interpolated", "Linear", - "Cubic Spline", "8-Tap FIR Filter", NULL + "Non-Interpolated", "Linear", + "Cubic Spline", "8-Tap FIR Filter", NULL }; static const int interp_group[] = { - 2,3,4,5,-1, + 2,3,4,5,-1, }; static int ramp_group[] = { /* not const because it is modified */ - -1,-1,-1, + -1,-1,-1, }; /* --------------------------------------------------------------------- */ static void preferences_draw_const(void) { - char buf[80]; - int i; + char buf[80]; + int i; - draw_text("Master Volume Left", 2, 14, 0, 2); - draw_text("Master Volume Right", 2, 15, 0, 2); - draw_box(21, 13, 27, 16, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Master Volume Left", 2, 14, 0, 2); + draw_text("Master Volume Right", 2, 15, 0, 2); + draw_box(21, 13, 27, 16, BOX_THIN | BOX_INNER | BOX_INSET); - sprintf(buf, "Mixing Mode, Playback Frequency: %dHz", audio_settings.sample_rate); - draw_text(buf, 2, 18, 0, 2); + sprintf(buf, "Mixing Mode, Playback Frequency: %dHz", audio_settings.sample_rate); + draw_text(buf, 2, 18, 0, 2); - for (i = 0; interpolation_modes[i]; i++); + for (i = 0; interpolation_modes[i]; i++); - draw_text("Output Equalizer", 2, 21+i*3, 0, 2); - draw_text( "Low Frequency Band", 7, 23+i*3, 0, 2); - draw_text( "Med Low Frequency Band", 3, 24+i*3, 0, 2); - draw_text("Med High Frequency Band", 2, 25+i*3, 0, 2); - draw_text( "High Frequency Band", 6, 26+i*3, 0, 2); + draw_text("Output Equalizer", 2, 21+i*3, 0, 2); + draw_text( "Low Frequency Band", 7, 23+i*3, 0, 2); + draw_text( "Med Low Frequency Band", 3, 24+i*3, 0, 2); + draw_text("Med High Frequency Band", 2, 25+i*3, 0, 2); + draw_text( "High Frequency Band", 6, 26+i*3, 0, 2); - draw_text("Ramp volume at start of sample",2,29+i*3,0,2); + draw_text("Ramp volume at start of sample",2,29+i*3,0,2); - draw_box(25, 22+i*3, 47, 27+i*3, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(52, 22+i*3, 74, 27+i*3, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_text("Oversampling", 57, 25, 0, 2); - draw_text("Noise Reduction", 54, 26, 0, 2); - - draw_fill_chars(73, 24, 77, 26, 0); - draw_box(69, 24, 78, 27, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(25, 22+i*3, 47, 27+i*3, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(52, 22+i*3, 74, 27+i*3, BOX_THIN | BOX_INNER | BOX_INSET); #define CORNER_BOTTOM "http://schismtracker.org/" - draw_text(CORNER_BOTTOM, 78 - strlen(CORNER_BOTTOM), 48, 1, 2); + draw_text(CORNER_BOTTOM, 78 - strlen(CORNER_BOTTOM), 48, 1, 2); } /* --------------------------------------------------------------------- */ static void preferences_set_page(void) { - int i, j; - int lim = volume_get_max(); - volume_read(&i, &j); - widgets_preferences[0].d.thumbbar.value = i * VOLUME_SCALE / lim; - widgets_preferences[1].d.thumbbar.value = j * VOLUME_SCALE / lim; - - for (i = j = 0; interpolation_modes[i]; i++) { - if (i == audio_settings.interpolation_mode) { - widgets_preferences[i + 2].d.togglebutton.state=1; - j = 1; - } else { - widgets_preferences[i + 2].d.togglebutton.state=0; - } - } - if (!j) { - audio_settings.interpolation_mode = 0; - widgets_preferences[2].d.togglebutton.state=1; - } - - for (j = 0; j < 4; j++) { - widgets_preferences[i+2+(j*2)].d.thumbbar.value - = audio_settings.eq_freq[j]; - widgets_preferences[i+3+(j*2)].d.thumbbar.value - = audio_settings.eq_gain[j]; - } - - widgets_preferences[i+10].d.togglebutton.state - = audio_settings.no_ramping?0:1; - widgets_preferences[i+11].d.togglebutton.state - = audio_settings.no_ramping?1:0; - widgets_preferences[i+13].d.toggle.state = audio_settings.oversampling; - widgets_preferences[i+14].d.toggle.state = audio_settings.noise_reduction; + int i, j; + int lim = volume_get_max(); + volume_read(&i, &j); + widgets_preferences[0].d.thumbbar.value = i * VOLUME_SCALE / lim; + widgets_preferences[1].d.thumbbar.value = j * VOLUME_SCALE / lim; + + for (i = j = 0; interpolation_modes[i]; i++) { + if (i == audio_settings.interpolation_mode) { + widgets_preferences[i + 2].d.togglebutton.state=1; + j = 1; + } else { + widgets_preferences[i + 2].d.togglebutton.state=0; + } + } + if (!j) { + audio_settings.interpolation_mode = 0; + widgets_preferences[2].d.togglebutton.state=1; + } + + for (j = 0; j < 4; j++) { + widgets_preferences[i+2+(j*2)].d.thumbbar.value + = audio_settings.eq_freq[j]; + widgets_preferences[i+3+(j*2)].d.thumbbar.value + = audio_settings.eq_gain[j]; + } + + widgets_preferences[i+10].d.togglebutton.state + = audio_settings.no_ramping?0:1; + widgets_preferences[i+11].d.togglebutton.state + = audio_settings.no_ramping?1:0; } /* --------------------------------------------------------------------- */ static void change_volume(void) { - int lim = volume_get_max(); - volume_write( - widgets_preferences[0].d.thumbbar.value * lim / VOLUME_SCALE, - widgets_preferences[1].d.thumbbar.value * lim / VOLUME_SCALE); + int lim = volume_get_max(); + volume_write( + widgets_preferences[0].d.thumbbar.value * lim / VOLUME_SCALE, + widgets_preferences[1].d.thumbbar.value * lim / VOLUME_SCALE); } #define SAVED_AT_EXIT "Audio configuration will be saved at exit" static void change_eq(void) { - int i,j; - for (i = 0; interpolation_modes[i]; i++); - for (j = 0; j < 4; j++) { - audio_settings.eq_freq[j] = widgets_preferences[i+2+(j*2)].d.thumbbar.value; - audio_settings.eq_gain[j] = widgets_preferences[i+3+(j*2)].d.thumbbar.value; - } - song_init_eq(1); + int i,j; + for (i = 0; interpolation_modes[i]; i++); + for (j = 0; j < 4; j++) { + audio_settings.eq_freq[j] = widgets_preferences[i+2+(j*2)].d.thumbbar.value; + audio_settings.eq_gain[j] = widgets_preferences[i+3+(j*2)].d.thumbbar.value; + } + song_init_eq(1); } static void change_mixer(void) { - int i; - for (i = 0; interpolation_modes[i]; i++) { - if (widgets_preferences[2+i].d.togglebutton.state) { - audio_settings.interpolation_mode = i; - } - } - audio_settings.oversampling = widgets_preferences[i+13].d.toggle.state; - audio_settings.noise_reduction = widgets_preferences[i+14].d.toggle.state; - audio_settings.no_ramping = widgets_preferences[i+11].d.togglebutton.state; + int i; + for (i = 0; interpolation_modes[i]; i++) { + if (widgets_preferences[2+i].d.togglebutton.state) { + audio_settings.interpolation_mode = i; + } + } + audio_settings.no_ramping = widgets_preferences[i+11].d.togglebutton.state; - song_init_modplug(); - status_text_flash(SAVED_AT_EXIT); + song_init_modplug(); + status_text_flash(SAVED_AT_EXIT); } /* --------------------------------------------------------------------- */ static void save_config_now(UNUSED void *ign) { - /* TODO */ - cfg_midipage_save(); /* what is this doing here? */ - cfg_atexit_save(); - status_text_flash("Configuration saved"); + /* TODO */ + cfg_midipage_save(); /* what is this doing here? */ + cfg_atexit_save(); + status_text_flash("Configuration saved"); } void preferences_load_page(struct page *page) { - char buf[64]; - char *ptr; - int i, j, n; - - page->title = "Preferences (Shift-F5)"; - page->draw_const = preferences_draw_const; - page->set_page = preferences_set_page; - page->total_widgets = 15; - page->widgets = widgets_preferences; - page->help_index = HELP_GLOBAL; - - - create_thumbbar(widgets_preferences + 0, 22, 14, 5, 0, 1, 1, change_volume, 0, VOLUME_SCALE); - create_thumbbar(widgets_preferences + 1, 22, 15, 5, 0, 2, 2, change_volume, 0, VOLUME_SCALE); - - for (n = 0; interpolation_modes[n]; n++); - for (i = 0; interpolation_modes[i]; i++) { - - sprintf(buf, "%d Bit, %s", audio_settings.bits, interpolation_modes[i]); - ptr = str_dup(buf); - create_togglebutton(widgets_preferences+i+2, - 6, 20 + (i * 3), 26, - i+1, i+3, i+2, n+11, i+3, - change_mixer, - ptr, - 2, - interp_group); - page->total_widgets++; - } - - for (j = 0; j < 4; j++) { - n = i+(j*2); - if (j == 0) n = i+1; - create_thumbbar(widgets_preferences+i+2+(j*2), - 26, 23+(i*3)+j, - 21, - n, i+(j*2)+4, i+(j*2)+3, - change_eq, - 0, 127); - n = i+(j*2)+5; - if (j == 3) n--; - create_thumbbar(widgets_preferences+i+3+(j*2), - 53, 23+(i*3)+j, - 21, - i+(j*2)+1, n, i+(j*2)+4, - change_eq, - 0, 127); - } - /* default EQ setting */ - widgets_preferences[i+2].d.thumbbar.value = 0; - widgets_preferences[i+4].d.thumbbar.value = 16; - widgets_preferences[i+6].d.thumbbar.value = 96; - widgets_preferences[i+8].d.thumbbar.value = 127; - - ramp_group[0] = i+10; - ramp_group[1] = i+11; - create_togglebutton(widgets_preferences+i+10, - 33,29+i*3,9, - i+9,i+12,i+10,i+11,i+11, - change_mixer, - "Enabled",2, - ramp_group); - - create_togglebutton(widgets_preferences+i+11, - 46,29+i*3,9, - i+9,i+12,i+10,i+13,i+13, - change_mixer, - "Disabled",1, - ramp_group); - - create_button(widgets_preferences+i+12, - 2, 44, 27, - i+10, i+12, i+12, i+13, i+13, - (void *) save_config_now, - "Save Output Configuration", 2); - - create_toggle(widgets_preferences+i+13, /* Oversampling */ - 70, 25, - i+13,i+14,1+i, i+13,i+14, - change_mixer); - create_toggle(widgets_preferences+i+14, /* Noise Reduction */ - 70, 26, - i+13,i+15,1+i, i+14,i+15, - change_mixer); + char buf[64]; + char *ptr; + int i, j, n; + + page->title = "Preferences (Shift-F5)"; + page->draw_const = preferences_draw_const; + page->set_page = preferences_set_page; + page->total_widgets = 15; + page->widgets = widgets_preferences; + page->help_index = HELP_GLOBAL; + + + create_thumbbar(widgets_preferences + 0, 22, 14, 5, 0, 1, 1, change_volume, 0, VOLUME_SCALE); + create_thumbbar(widgets_preferences + 1, 22, 15, 5, 0, 2, 2, change_volume, 0, VOLUME_SCALE); + + for (n = 0; interpolation_modes[n]; n++); + for (i = 0; interpolation_modes[i]; i++) { + + sprintf(buf, "%d Bit, %s", audio_settings.bits, interpolation_modes[i]); + ptr = str_dup(buf); + create_togglebutton(widgets_preferences+i+2, + 6, 20 + (i * 3), 26, + i+1, i+3, i+2, n+11, i+3, + change_mixer, + ptr, + 2, + interp_group); + page->total_widgets++; + } + + for (j = 0; j < 4; j++) { + n = i+(j*2); + if (j == 0) n = i+1; + create_thumbbar(widgets_preferences+i+2+(j*2), + 26, 23+(i*3)+j, + 21, + n, i+(j*2)+4, i+(j*2)+3, + change_eq, + 0, 127); + n = i+(j*2)+5; + if (j == 3) n--; + create_thumbbar(widgets_preferences+i+3+(j*2), + 53, 23+(i*3)+j, + 21, + i+(j*2)+1, n, i+(j*2)+4, + change_eq, + 0, 127); + } + /* default EQ setting */ + widgets_preferences[i+2].d.thumbbar.value = 0; + widgets_preferences[i+4].d.thumbbar.value = 16; + widgets_preferences[i+6].d.thumbbar.value = 96; + widgets_preferences[i+8].d.thumbbar.value = 127; + + ramp_group[0] = i+10; + ramp_group[1] = i+11; + create_togglebutton(widgets_preferences+i+10, + 33,29+i*3,9, + i+9,i+12,i+10,i+11,i+11, + change_mixer, + "Enabled",2, + ramp_group); + + create_togglebutton(widgets_preferences+i+11, + 46,29+i*3,9, + i+9,i+12,i+10,i+13,i+13, + change_mixer, + "Disabled",1, + ramp_group); + + create_button(widgets_preferences+i+12, + 2, 44, 27, + i+10, i+12, i+12, i+13, i+13, + (void *) save_config_now, + "Save Output Configuration", 2); } diff -Nru schism-0+20110101/schism/page_samples.c schism-20160521/schism/page_samples.c --- schism-0+20110101/schism/page_samples.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_samples.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,8 +34,8 @@ /* --------------------------------------------------------------------- */ /* static in my attic */ static struct vgamem_overlay sample_image = { - 55,26,76,29, - NULL, 0, 0, 0, + 55,26,76,29, + NULL, 0, 0, 0, }; static int dialog_f1_hack = 0; @@ -68,87 +68,87 @@ static int _is_magic_sample(int no) { - song_sample_t *sample; - int pn; + song_sample_t *sample; + int pn; - sample = song_get_sample(no); - if (sample && ((unsigned char) sample->name[23]) == 0xFF) { - pn = (sample->name[24]); - if (pn < 200) return 1; - } - return 0; + sample = song_get_sample(no); + if (sample && ((unsigned char) sample->name[23]) == 0xFF) { + pn = (sample->name[24]); + if (pn < 200) return 1; + } + return 0; } static void _fix_accept_text(void) { - if (_is_magic_sample(current_sample)) { - widgets_samplelist[0].accept_text = (sample_list_cursor_pos == 23 ? 0 : 1); - } else { - widgets_samplelist[0].accept_text = (sample_list_cursor_pos == 25 ? 0 : 1); - } + if (_is_magic_sample(current_sample)) { + widgets_samplelist[0].accept_text = (sample_list_cursor_pos == 23 ? 0 : 1); + } else { + widgets_samplelist[0].accept_text = (sample_list_cursor_pos == 25 ? 0 : 1); + } } static int _last_vis_sample(void) { - int i, j, n; + int i, j, n; - n = 99; - j = 0; - /* 65 is first visible sample on last page */ - for (i = 65; i < MAX_SAMPLES; i++) { - if (!csf_sample_is_empty(current_song->samples + i)) { - j = i; - } - } - while ((j + 34) > n) n += 34; - if (n >= MAX_SAMPLES) n = MAX_SAMPLES - 1; - return n; + n = 99; + j = 0; + /* 65 is first visible sample on last page */ + for (i = 65; i < MAX_SAMPLES; i++) { + if (!csf_sample_is_empty(current_song->samples + i)) { + j = i; + } + } + while ((j + 34) > n) n += 34; + if (n >= MAX_SAMPLES) n = MAX_SAMPLES - 1; + return n; } /* --------------------------------------------------------------------- */ static void sample_list_reposition(void) { - if (current_sample < top_sample) { - top_sample = current_sample; - if (top_sample < 1) - top_sample = 1; - } else if (current_sample > top_sample + 34) { - top_sample = current_sample - 34; - } - if (dialog_f1_hack - && status.current_page == PAGE_SAMPLE_LIST - && status.previous_page == PAGE_HELP) { - sample_adlibconfig_dialog(NULL); - } - dialog_f1_hack = 0; + if (current_sample < top_sample) { + top_sample = current_sample; + if (top_sample < 1) + top_sample = 1; + } else if (current_sample > top_sample + 34) { + top_sample = current_sample - 34; + } + if (dialog_f1_hack + && status.current_page == PAGE_SAMPLE_LIST + && status.previous_page == PAGE_HELP) { + sample_adlibconfig_dialog(NULL); + } + dialog_f1_hack = 0; } /* --------------------------------------------------------------------- */ int sample_get_current(void) { - return current_sample; + return current_sample; } void sample_set(int n) { - int new_sample = n; + int new_sample = n; - if (status.current_page == PAGE_SAMPLE_LIST) - new_sample = CLAMP(n, 1, _last_vis_sample()); - else - new_sample = CLAMP(n, 0, _last_vis_sample()); - - if (current_sample == new_sample) - return; - - current_sample = new_sample; - sample_list_reposition(); - - /* update_current_instrument(); */ - if (status.current_page == PAGE_SAMPLE_LIST) - status.flags |= NEED_UPDATE; + if (status.current_page == PAGE_SAMPLE_LIST) + new_sample = CLAMP(n, 1, _last_vis_sample()); + else + new_sample = CLAMP(n, 0, _last_vis_sample()); + + if (current_sample == new_sample) + return; + + current_sample = new_sample; + sample_list_reposition(); + + /* update_current_instrument(); */ + if (status.current_page == PAGE_SAMPLE_LIST) + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -156,408 +156,422 @@ static void sample_list_draw_list(void) { - int pos, n, nl, pn; - song_sample_t *sample; - int has_data, is_selected; - char buf[64]; - int ss, cl = 0, cr = 0; - int is_playing[MAX_SAMPLES]; - - ss = -1; - - song_get_playing_samples(is_playing); - - /* list */ - for (pos = 0, n = top_sample; pos < 35; pos++, n++) { - sample = song_get_sample(n); - is_selected = (n == current_sample); - has_data = (sample->data != NULL); - - if (sample->played) - draw_char(is_playing[n] > 1 ? 183 : 173, 1, 13 + pos, is_playing[n] ? 3 : 1, 2); - - draw_text(num99tostr(n, buf), 2, 13 + pos, (sample->flags & CHN_MUTE) ? 1 : 0, 2); - - // wow, this is entirely horrible - pn = ((unsigned char)sample->name[24]); - if (((unsigned char)sample->name[23]) == 0xFF && pn < 200) { - nl = 23; - draw_text(numtostr(3, (int)pn, buf), 32, 13 + pos, 0, 2); - draw_char('P', 28, 13+pos, 3, 2); - draw_char('a', 29, 13+pos, 3, 2); - draw_char('t', 30, 13+pos, 3, 2); - draw_char('.', 31, 13+pos, 3, 2); - } else { - nl = 25; - draw_char(168, 30, 13 + pos, 2, (is_selected ? 14 : 0)); - draw_text("Play", 31, 13 + pos, (has_data ? 6 : 7), (is_selected ? 14 : 0)); - } - - draw_text_len(sample->name, nl, 5, 13 + pos, 6, (is_selected ? 14 : 0)); - if (ss == n) { - draw_text_len(sample->name + cl, (cr-cl)+1, 5 + cl, 13 + pos, 3, 8); - } - } - - /* cursor */ - if (ACTIVE_PAGE.selected_widget == 0) { - pos = current_sample - top_sample; - sample = song_get_sample(current_sample); - has_data = (sample->data != NULL); - - if (pos < 0 || pos > 34) { - /* err... */ - } else if (sample_list_cursor_pos == 25) { - draw_text("Play", 31, 13 + pos, 0, (has_data ? 3 : 6)); - } else { - draw_char(((sample_list_cursor_pos > (signed) strlen(sample->name)) - ? 0 : sample->name[sample_list_cursor_pos]), - sample_list_cursor_pos + 5, 13 + pos, 0, 3); - } - } + int pos, n, nl, pn; + song_sample_t *sample; + int has_data, is_selected; + char buf[64]; + int ss, cl = 0, cr = 0; + int is_playing[MAX_SAMPLES]; + + ss = -1; + + song_get_playing_samples(is_playing); + + /* list */ + for (pos = 0, n = top_sample; pos < 35; pos++, n++) { + sample = song_get_sample(n); + is_selected = (n == current_sample); + has_data = (sample->data != NULL); + + if (sample->played) + draw_char(is_playing[n] > 1 ? 183 : 173, 1, 13 + pos, is_playing[n] ? 3 : 1, 2); + + draw_text(num99tostr(n, buf), 2, 13 + pos, (sample->flags & CHN_MUTE) ? 1 : 0, 2); + + // wow, this is entirely horrible + pn = ((unsigned char)sample->name[24]); + if (((unsigned char)sample->name[23]) == 0xFF && pn < 200) { + nl = 23; + draw_text(numtostr(3, (int)pn, buf), 32, 13 + pos, 0, 2); + draw_char('P', 28, 13+pos, 3, 2); + draw_char('a', 29, 13+pos, 3, 2); + draw_char('t', 30, 13+pos, 3, 2); + draw_char('.', 31, 13+pos, 3, 2); + } else { + nl = 25; + draw_char(168, 30, 13 + pos, 2, (is_selected ? 14 : 0)); + draw_text("Play", 31, 13 + pos, (has_data ? 6 : 7), (is_selected ? 14 : 0)); + } + + draw_text_len(sample->name, nl, 5, 13 + pos, 6, (is_selected ? 14 : 0)); + if (ss == n) { + draw_text_len(sample->name + cl, (cr-cl)+1, 5 + cl, 13 + pos, 3, 8); + } + } + + /* cursor */ + if (ACTIVE_PAGE.selected_widget == 0) { + pos = current_sample - top_sample; + sample = song_get_sample(current_sample); + has_data = (sample->data != NULL); + + if (pos < 0 || pos > 34) { + /* err... */ + } else if (sample_list_cursor_pos == 25) { + draw_text("Play", 31, 13 + pos, 0, (has_data ? 3 : 6)); + } else { + draw_char(((sample_list_cursor_pos > (signed) strlen(sample->name)) + ? 0 : sample->name[sample_list_cursor_pos]), + sample_list_cursor_pos + 5, 13 + pos, 0, 3); + } + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static void sample_list_predraw_hook(void) { - char buf[16]; - song_sample_t *sample; - int has_data; - - sample = song_get_sample(current_sample); - has_data = (sample->data != NULL); - - /* set all the values to the current sample */ - - /* default volume - modplug hack here: sample volume has 4x the resolution... - can't deal with this in song.cc (easily) without changing the actual volume of the sample. */ - widgets_samplelist[1].d.thumbbar.value = sample->volume / 4; - - /* global volume */ - widgets_samplelist[2].d.thumbbar.value = sample->global_volume; - widgets_samplelist[2].d.thumbbar.text_at_min = (sample->flags & CHN_MUTE) ? " Muted " : NULL; - - /* default pan (another modplug hack) */ - widgets_samplelist[3].d.toggle.state = (sample->flags & CHN_PANNING); - widgets_samplelist[4].d.thumbbar.value = sample->panning / 4; - - widgets_samplelist[5].d.thumbbar.value = sample->vib_speed; - widgets_samplelist[6].d.thumbbar.value = sample->vib_depth; - widgets_samplelist[7].d.textentry.text = sample->filename; - widgets_samplelist[8].d.numentry.value = sample->c5speed; - - widgets_samplelist[9].d.menutoggle.state = - (sample->flags & CHN_LOOP ? (sample->flags & CHN_PINGPONGLOOP ? 2 : 1) : 0); - widgets_samplelist[10].d.numentry.value = sample->loop_start; - widgets_samplelist[11].d.numentry.value = sample->loop_end; - widgets_samplelist[12].d.menutoggle.state = - (sample->flags & CHN_SUSTAINLOOP ? (sample->flags & CHN_PINGPONGSUSTAIN ? 2 : 1) : 0); - widgets_samplelist[13].d.numentry.value = sample->sustain_start; - widgets_samplelist[14].d.numentry.value = sample->sustain_end; - - switch (sample->vib_type) { - case VIB_SINE: - togglebutton_set(widgets_samplelist, 15, 0); - break; - case VIB_RAMP_DOWN: - togglebutton_set(widgets_samplelist, 16, 0); - break; - case VIB_SQUARE: - togglebutton_set(widgets_samplelist, 17, 0); - break; - case VIB_RANDOM: - togglebutton_set(widgets_samplelist, 18, 0); - break; - } - - widgets_samplelist[19].d.thumbbar.value = sample->vib_rate; - - if (has_data) { - sprintf(buf, "%d bit%s", - (sample->flags & CHN_16BIT) ? 16 : 8, - (sample->flags & CHN_STEREO) ? " Stereo" : ""); - } else { - strcpy(buf, "No sample"); - } - draw_text_len(buf, 13, 64, 22, 2, 0); + char buf[16]; + song_sample_t *sample; + int has_data; + + sample = song_get_sample(current_sample); + has_data = (sample->data != NULL); + + /* set all the values to the current sample */ + + /* default volume + modplug hack here: sample volume has 4x the resolution... + can't deal with this in song.cc (easily) without changing the actual volume of the sample. */ + widgets_samplelist[1].d.thumbbar.value = sample->volume / 4; + + /* global volume */ + widgets_samplelist[2].d.thumbbar.value = sample->global_volume; + widgets_samplelist[2].d.thumbbar.text_at_min = (sample->flags & CHN_MUTE) ? " Muted " : NULL; + + /* default pan (another modplug hack) */ + widgets_samplelist[3].d.toggle.state = (sample->flags & CHN_PANNING); + widgets_samplelist[4].d.thumbbar.value = sample->panning / 4; + + widgets_samplelist[5].d.thumbbar.value = sample->vib_speed; + widgets_samplelist[6].d.thumbbar.value = sample->vib_depth; + widgets_samplelist[7].d.textentry.text = sample->filename; + widgets_samplelist[8].d.numentry.value = sample->c5speed; + + widgets_samplelist[9].d.menutoggle.state = + (sample->flags & CHN_LOOP ? (sample->flags & CHN_PINGPONGLOOP ? 2 : 1) : 0); + widgets_samplelist[10].d.numentry.value = sample->loop_start; + widgets_samplelist[11].d.numentry.value = sample->loop_end; + widgets_samplelist[12].d.menutoggle.state = + (sample->flags & CHN_SUSTAINLOOP ? (sample->flags & CHN_PINGPONGSUSTAIN ? 2 : 1) : 0); + widgets_samplelist[13].d.numentry.value = sample->sustain_start; + widgets_samplelist[14].d.numentry.value = sample->sustain_end; + + switch (sample->vib_type) { + case VIB_SINE: + togglebutton_set(widgets_samplelist, 15, 0); + break; + case VIB_RAMP_DOWN: + togglebutton_set(widgets_samplelist, 16, 0); + break; + case VIB_SQUARE: + togglebutton_set(widgets_samplelist, 17, 0); + break; + case VIB_RANDOM: + togglebutton_set(widgets_samplelist, 18, 0); + break; + } + + widgets_samplelist[19].d.thumbbar.value = sample->vib_rate; + + if (has_data) { + sprintf(buf, "%d bit%s", + (sample->flags & CHN_16BIT) ? 16 : 8, + (sample->flags & CHN_STEREO) ? " Stereo" : ""); + } else { + strcpy(buf, "No sample"); + } + draw_text_len(buf, 13, 64, 22, 2, 0); - draw_text_len(numtostr(0, sample->length, buf), 13, 64, 23, 2, 0); + draw_text_len(numtostr(0, sample->length, buf), 13, 64, 23, 2, 0); - draw_sample_data(&sample_image, sample, current_sample); + draw_sample_data(&sample_image, sample); } /* --------------------------------------------------------------------- */ static int sample_list_add_char(char c) { - song_sample_t *smp; + song_sample_t *smp; - if (c < 32) - return 0; - smp = song_get_sample(current_sample); - text_add_char(smp->name, c, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 22 : 25); - _fix_accept_text(); - - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; - return 1; + if (c < 32) + return 0; + smp = song_get_sample(current_sample); + text_add_char(smp->name, c, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 22 : 25); + _fix_accept_text(); + + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; + return 1; } static void sample_list_delete_char(void) { - song_sample_t *smp = song_get_sample(current_sample); - text_delete_char(smp->name, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 23 : 25); - _fix_accept_text(); + song_sample_t *smp = song_get_sample(current_sample); + text_delete_char(smp->name, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 23 : 25); + _fix_accept_text(); - status.flags |= SONG_NEEDS_SAVE; - status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; } static void sample_list_delete_next_char(void) { - song_sample_t *smp = song_get_sample(current_sample); - text_delete_next_char(smp->name, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 23 : 25); - _fix_accept_text(); + song_sample_t *smp = song_get_sample(current_sample); + text_delete_next_char(smp->name, &sample_list_cursor_pos, _is_magic_sample(current_sample) ? 23 : 25); + _fix_accept_text(); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; } static void clear_sample_text(void) { - song_sample_t *smp = song_get_sample(current_sample); - memset(smp->filename, 0, 14); - if (_is_magic_sample(current_sample)) { - memset(smp->name, 0, 24); - } else { - memset(smp->name, 0, 26); - } - sample_list_cursor_pos = 0; - _fix_accept_text(); + song_sample_t *smp = song_get_sample(current_sample); + memset(smp->filename, 0, 14); + if (_is_magic_sample(current_sample)) { + memset(smp->name, 0, 24); + } else { + memset(smp->name, 0, 26); + } + sample_list_cursor_pos = 0; + _fix_accept_text(); - status.flags |= NEED_UPDATE; - status.flags |= SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE; + status.flags |= SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static void do_swap_sample(int n) { - if (n >= 1 && n <= _last_vis_sample()) { - song_swap_samples(current_sample, n); - } + if (n >= 1 && n <= _last_vis_sample()) { + song_swap_samples(current_sample, n); + } } static void do_exchange_sample(int n) { - if (n >= 1 && n <= _last_vis_sample()) { - song_exchange_samples(current_sample, n); - } + if (n >= 1 && n <= _last_vis_sample()) { + song_exchange_samples(current_sample, n); + } } static void do_copy_sample(int n) { - if (n >= 1 && n <= _last_vis_sample()) { - song_copy_sample(current_sample, song_get_sample(n)); - sample_host_dialog(-1); - } - status.flags |= SONG_NEEDS_SAVE; + if (n >= 1 && n <= _last_vis_sample()) { + song_copy_sample(current_sample, song_get_sample(n)); + sample_host_dialog(-1); + } + status.flags |= SONG_NEEDS_SAVE; } static void do_replace_sample(int n) { - if (n >= 1 && n <= _last_vis_sample()) { - song_replace_sample(current_sample, n); - } - status.flags |= SONG_NEEDS_SAVE; + if (n >= 1 && n <= _last_vis_sample()) { + song_replace_sample(current_sample, n); + } + status.flags |= SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static int sample_list_handle_key_on_list(struct key_event * k) { - int new_sample = current_sample; - int new_cursor_pos = sample_list_cursor_pos; + int new_sample = current_sample; + int new_cursor_pos = sample_list_cursor_pos; - if (k->mouse == MOUSE_CLICK && k->mouse_button == MOUSE_BUTTON_MIDDLE) { - if (k->state) status.flags |= CLIPPY_PASTE_SELECTION; - return 1; - } else if (!k->state && k->mouse && k->x >= 5 && k->y >= 13 && k->y <= 47 && k->x <= 34) { - if (k->mouse == MOUSE_SCROLL_UP) { - top_sample -= MOUSE_SCROLL_LINES; - if (top_sample < 1) top_sample = 1; - status.flags |= NEED_UPDATE; - return 1; - } else if (k->mouse == MOUSE_SCROLL_DOWN) { - top_sample += MOUSE_SCROLL_LINES; - if (top_sample > (_last_vis_sample()-34)) - top_sample = (_last_vis_sample()-34); - status.flags |= NEED_UPDATE; - return 1; - } else { - new_sample = (k->y - 13) + top_sample; - new_cursor_pos = k->x - 5; - if (k->x <= 29) { /* and button1 */ - if (k->mouse == MOUSE_DBLCLICK) { - /* this doesn't appear to work */ - set_page(PAGE_LOAD_SAMPLE); - status.flags |= NEED_UPDATE; - return 1; - } else { - } + if (k->mouse == MOUSE_CLICK && k->mouse_button == MOUSE_BUTTON_MIDDLE) { + if (k->state == KEY_RELEASE) + status.flags |= CLIPPY_PASTE_SELECTION; + return 1; + } else if (k->state == KEY_PRESS && k->mouse != MOUSE_NONE && k->x >= 5 && k->y >= 13 && k->y <= 47 && k->x <= 34) { + if (k->mouse == MOUSE_SCROLL_UP) { + top_sample -= MOUSE_SCROLL_LINES; + if (top_sample < 1) top_sample = 1; + status.flags |= NEED_UPDATE; + return 1; + } else if (k->mouse == MOUSE_SCROLL_DOWN) { + top_sample += MOUSE_SCROLL_LINES; + if (top_sample > (_last_vis_sample()-34)) + top_sample = (_last_vis_sample()-34); + status.flags |= NEED_UPDATE; + return 1; + } else { + new_sample = (k->y - 13) + top_sample; + new_cursor_pos = k->x - 5; + if (k->x <= 29) { /* and button1 */ + if (k->mouse == MOUSE_DBLCLICK) { + /* this doesn't appear to work */ + set_page(PAGE_LOAD_SAMPLE); + status.flags |= NEED_UPDATE; + return 1; + } else { + } #if 0 /* buggy and annoying, could be implemented properly but I don't care enough */ - } else if (k->state || k->x == k->sx) { - if (k->mouse == MOUSE_DBLCLICK - || (new_sample == current_sample - && sample_list_cursor_pos == 25)) { - song_keydown(current_sample, KEYJAZZ_NOINST, - last_note, 64, KEYJAZZ_CHAN_CURRENT); - } - new_cursor_pos = 25; + } else if (k->state == KEY_RELEASE || k->x == k->sx) { + if (k->mouse == MOUSE_DBLCLICK + || (new_sample == current_sample + && sample_list_cursor_pos == 25)) { + song_keydown(current_sample, KEYJAZZ_NOINST, + last_note, 64, KEYJAZZ_CHAN_CURRENT); + } + new_cursor_pos = 25; #endif - } - } - } else { - switch (k->sym) { - case SDLK_LEFT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_cursor_pos--; - break; - case SDLK_RIGHT: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_cursor_pos++; - break; - case SDLK_HOME: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_cursor_pos = 0; - break; - case SDLK_END: - if (k->state) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - new_cursor_pos = 25; - break; - case SDLK_UP: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - if (current_sample > 1) { - new_sample = current_sample - 1; - song_swap_samples(current_sample, new_sample); - } - } else if (!NO_MODIFIER(k->mod)) { - return 0; - } else { - new_sample--; - } - break; - case SDLK_DOWN: - if (k->state) return 0; - if (k->mod & KMOD_ALT) { - // restrict position to the "old" value of _last_vis_sample() - // (this is entirely for aesthetic reasons) - if (status.last_keysym != SDLK_DOWN && !k->is_repeat) - _altswap_lastvis = _last_vis_sample(); - if (current_sample < _altswap_lastvis) { - new_sample = current_sample + 1; - song_swap_samples(current_sample, new_sample); - } - } else if (!NO_MODIFIER(k->mod)) { - return 0; - } else { - new_sample++; - } - break; - case SDLK_PAGEUP: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) { - new_sample = 1; - } else { - new_sample -= 16; - } - break; - case SDLK_PAGEDOWN: - if (k->state) return 0; - if (k->mod & KMOD_CTRL) { - new_sample = _last_vis_sample(); - } else { - new_sample += 16; - } - break; - case SDLK_RETURN: - if (!k->state) return 0; - set_page(PAGE_LOAD_SAMPLE); - break; - case SDLK_BACKSPACE: - if (k->state) return 0; - if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { - if (sample_list_cursor_pos < 25) { - sample_list_delete_char(); - } - return 1; - } else if (k->mod & KMOD_CTRL) { - /* just for compatibility with every weird thing - * Impulse Tracker does ^_^ */ - if (sample_list_cursor_pos < 25) { - sample_list_add_char(127); - } - return 1; - } - return 0; - case SDLK_DELETE: - if (k->state) return 0; - if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { - if (sample_list_cursor_pos < 25) { - sample_list_delete_next_char(); - } - return 1; - } - return 0; - case SDLK_ESCAPE: - if (k->mod & KMOD_SHIFT) { - if (k->state) return 1; - new_cursor_pos = 25; - break; - } - return 0; - default: - if (k->mod & KMOD_ALT) { - if (k->sym == SDLK_c) { - clear_sample_text(); - return 1; - } - } else if ((k->mod & KMOD_CTRL) == 0 && sample_list_cursor_pos < 25) { - if (!k->unicode) return 0; - if (k->state) return 1; - return sample_list_add_char(k->unicode); - } - return 0; - } - } - - new_sample = CLAMP(new_sample, 1, _last_vis_sample()); - new_cursor_pos = CLAMP(new_cursor_pos, 0, 25); - - if (new_sample != current_sample) { - sample_set(new_sample); - sample_list_reposition(); - } - if (new_cursor_pos != sample_list_cursor_pos) { - sample_list_cursor_pos = new_cursor_pos; - _fix_accept_text(); - } + } + } + } else { + switch (k->sym) { + case SDLK_LEFT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_cursor_pos--; + break; + case SDLK_RIGHT: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_cursor_pos++; + break; + case SDLK_HOME: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_cursor_pos = 0; + break; + case SDLK_END: + if (k->state == KEY_RELEASE) + return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + new_cursor_pos = 25; + break; + case SDLK_UP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + if (current_sample > 1) { + new_sample = current_sample - 1; + song_swap_samples(current_sample, new_sample); + } + } else if (!NO_MODIFIER(k->mod)) { + return 0; + } else { + new_sample--; + } + break; + case SDLK_DOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_ALT) { + // restrict position to the "old" value of _last_vis_sample() + // (this is entirely for aesthetic reasons) + if (status.last_keysym != SDLK_DOWN && !k->is_repeat) + _altswap_lastvis = _last_vis_sample(); + if (current_sample < _altswap_lastvis) { + new_sample = current_sample + 1; + song_swap_samples(current_sample, new_sample); + } + } else if (!NO_MODIFIER(k->mod)) { + return 0; + } else { + new_sample++; + } + break; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) { + new_sample = 1; + } else { + new_sample -= 16; + } + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return 0; + if (k->mod & KMOD_CTRL) { + new_sample = _last_vis_sample(); + } else { + new_sample += 16; + } + break; + case SDLK_RETURN: + if (k->state == KEY_PRESS) + return 0; + set_page(PAGE_LOAD_SAMPLE); + break; + case SDLK_BACKSPACE: + if (k->state == KEY_RELEASE) + return 0; + if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { + if (sample_list_cursor_pos < 25) { + sample_list_delete_char(); + } + return 1; + } else if (k->mod & KMOD_CTRL) { + /* just for compatibility with every weird thing + * Impulse Tracker does ^_^ */ + if (sample_list_cursor_pos < 25) { + sample_list_add_char(127); + } + return 1; + } + return 0; + case SDLK_DELETE: + if (k->state == KEY_RELEASE) + return 0; + if ((k->mod & (KMOD_CTRL | KMOD_ALT)) == 0) { + if (sample_list_cursor_pos < 25) { + sample_list_delete_next_char(); + } + return 1; + } + return 0; + case SDLK_ESCAPE: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_RELEASE) + return 1; + new_cursor_pos = 25; + break; + } + return 0; + default: + if (k->mod & KMOD_ALT) { + if (k->sym == SDLK_c) { + clear_sample_text(); + return 1; + } + } else if ((k->mod & KMOD_CTRL) == 0 && sample_list_cursor_pos < 25) { + if (!k->unicode) return 0; + if (k->state == KEY_RELEASE) + return 1; + return sample_list_add_char(k->unicode); + } + return 0; + } + } + + new_sample = CLAMP(new_sample, 1, _last_vis_sample()); + new_cursor_pos = CLAMP(new_cursor_pos, 0, 25); + + if (new_sample != current_sample) { + sample_set(new_sample); + sample_list_reposition(); + } + if (new_cursor_pos != sample_list_cursor_pos) { + sample_list_cursor_pos = new_cursor_pos; + _fix_accept_text(); + } - status.flags |= NEED_UPDATE; - return 1; + status.flags |= NEED_UPDATE; + return 1; } /* --------------------------------------------------------------------- */ @@ -567,101 +581,97 @@ static void do_sign_convert(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); - sample_sign_convert(sample); + song_sample_t *sample = song_get_sample(current_sample); + sample_sign_convert(sample); } static void do_quality_convert(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); - sample_toggle_quality(sample, 1); + song_sample_t *sample = song_get_sample(current_sample); + sample_toggle_quality(sample, 1); } static void do_quality_toggle(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); + song_sample_t *sample = song_get_sample(current_sample); - if (sample->flags & CHN_STEREO) - status_text_flash("Can't toggle quality for stereo samples"); - else - sample_toggle_quality(sample, 0); + if (sample->flags & CHN_STEREO) + status_text_flash("Can't toggle quality for stereo samples"); + else + sample_toggle_quality(sample, 0); } static void do_delete_sample(UNUSED void *data) { - song_clear_sample(current_sample); - status.flags |= SONG_NEEDS_SAVE; + song_clear_sample(current_sample); + status.flags |= SONG_NEEDS_SAVE; } static void do_post_loop_cut(UNUSED void *bweh) /* I'm already using 'data'. */ { - song_sample_t *sample = song_get_sample(current_sample); - unsigned long pos = ((sample->flags & CHN_SUSTAINLOOP) - ? MAX(sample->loop_end, sample->sustain_end) - : sample->loop_end); - - if (pos == 0 || pos >= sample->length) - return; - - status.flags |= SONG_NEEDS_SAVE; - - song_lock_audio(); - csf_stop_sample(current_song, sample); - if (sample->loop_end > pos) sample->loop_end = pos; - if (sample->sustain_end > pos) sample->sustain_end = pos; + song_sample_t *sample = song_get_sample(current_sample); + unsigned long pos = ((sample->flags & CHN_SUSTAINLOOP) + ? MAX(sample->loop_end, sample->sustain_end) + : sample->loop_end); + + if (pos == 0 || pos >= sample->length) + return; + + status.flags |= SONG_NEEDS_SAVE; + + song_lock_audio(); + csf_stop_sample(current_song, sample); + if (sample->loop_end > pos) sample->loop_end = pos; + if (sample->sustain_end > pos) sample->sustain_end = pos; - sample->length = pos; - song_unlock_audio(); + sample->length = pos; + song_unlock_audio(); } static void do_pre_loop_cut(UNUSED void *bweh) { - song_sample_t *sample = song_get_sample(current_sample); - signed char *data; - unsigned long pos = ((sample->flags & CHN_SUSTAINLOOP) - ? MIN(sample->loop_start, sample->sustain_start) - : sample->loop_start); - unsigned long start_byte = pos * ((sample->flags & CHN_16BIT) ? 2 : 1) - * ((sample->flags & CHN_STEREO) ? 2 : 1); - unsigned long bytes = (sample->length - pos) * ((sample->flags & CHN_16BIT) ? 2 : 1) - * ((sample->flags & CHN_STEREO) ? 2 : 1); - - if (pos == 0 || pos > sample->length) - return; - - status.flags |= SONG_NEEDS_SAVE; - - song_lock_audio(); - csf_stop_sample(current_song, sample); - data = csf_allocate_sample(bytes); - memcpy(data, sample->data + start_byte, bytes); - csf_free_sample(sample->data); - sample->data = data; - sample->length -= pos; - - if (sample->loop_start > pos) - sample->loop_start -= pos; - else - sample->loop_start = 0; - if (sample->sustain_start > pos) - sample->sustain_start -= pos; - else - sample->sustain_start = 0; - if (sample->loop_end > pos) - sample->loop_end -= pos; - else - sample->loop_end = 0; - if (sample->sustain_end > pos) - sample->sustain_end -= pos; - else - sample->sustain_end = 0; - song_unlock_audio(); + song_sample_t *sample = song_get_sample(current_sample); + unsigned long pos = ((sample->flags & CHN_SUSTAINLOOP) + ? MIN(sample->loop_start, sample->sustain_start) + : sample->loop_start); + unsigned long start_byte = pos * ((sample->flags & CHN_16BIT) ? 2 : 1) + * ((sample->flags & CHN_STEREO) ? 2 : 1); + unsigned long bytes = (sample->length - pos) * ((sample->flags & CHN_16BIT) ? 2 : 1) + * ((sample->flags & CHN_STEREO) ? 2 : 1); + + if (pos == 0 || pos > sample->length) + return; + + status.flags |= SONG_NEEDS_SAVE; + + song_lock_audio(); + csf_stop_sample(current_song, sample); + memmove(sample->data, sample->data + start_byte, bytes); + sample->length -= pos; + + if (sample->loop_start > pos) + sample->loop_start -= pos; + else + sample->loop_start = 0; + if (sample->sustain_start > pos) + sample->sustain_start -= pos; + else + sample->sustain_start = 0; + if (sample->loop_end > pos) + sample->loop_end -= pos; + else + sample->loop_end = 0; + if (sample->sustain_end > pos) + sample->sustain_end -= pos; + else + sample->sustain_end = 0; + song_unlock_audio(); } static void do_centralise(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); - sample_centralise(sample); + song_sample_t *sample = song_get_sample(current_sample); + sample_centralise(sample); } /* --------------------------------------------------------------------- */ @@ -670,30 +680,30 @@ static void do_amplify(UNUSED void *data) { - sample_amplify(song_get_sample(current_sample), sample_amplify_widgets[0].d.thumbbar.value); + sample_amplify(song_get_sample(current_sample), sample_amplify_widgets[0].d.thumbbar.value); } static void sample_amplify_draw_const(void) { - draw_text("Sample Amplification %", 29, 27, 0, 2); - draw_box(12, 29, 64, 31, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Sample Amplification %", 29, 27, 0, 2); + draw_box(12, 29, 64, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void sample_amplify_dialog(void) { - struct dialog *dialog; - int percent = sample_get_amplify_amount(song_get_sample(current_sample)); + struct dialog *dialog; + int percent = sample_get_amplify_amount(song_get_sample(current_sample)); - percent = MIN(percent, 400); + percent = MIN(percent, 400); - create_thumbbar(sample_amplify_widgets + 0, 13, 30, 51, 0, 1, 1, NULL, 0, 400); - sample_amplify_widgets[0].d.thumbbar.value = percent; - create_button(sample_amplify_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); - create_button(sample_amplify_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - - dialog = dialog_create_custom(9, 25, 61, 11, sample_amplify_widgets, - 3, 0, sample_amplify_draw_const, NULL); - dialog->action_yes = do_amplify; + create_thumbbar(sample_amplify_widgets + 0, 13, 30, 51, 0, 1, 1, NULL, 0, 400); + sample_amplify_widgets[0].d.thumbbar.value = percent; + create_button(sample_amplify_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); + create_button(sample_amplify_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + + dialog = dialog_create_custom(9, 25, 61, 11, sample_amplify_widgets, + 3, 0, sample_amplify_draw_const, NULL); + dialog->action_yes = do_amplify; } /* --------------------------------------------------------------------- */ @@ -703,46 +713,46 @@ static void do_txtsynth(UNUSED void *data) { - int len = strlen(txtsynth_entry); - if (!len) - return; - - song_sample_t *sample = song_get_sample(current_sample); - if (sample->data) - csf_free_sample(sample->data); - sample->data = csf_allocate_sample(len); - memcpy(sample->data, txtsynth_entry, len); - sample->length = len; - sample->loop_start = 0; - sample->loop_end = len; - sample->sustain_start = sample->sustain_end = 0; - sample->flags |= CHN_LOOP; - sample->flags &= ~(CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN - | CHN_16BIT | CHN_STEREO | CHN_ADLIB); - sample_host_dialog(-1); + int len = strlen(txtsynth_entry); + if (!len) + return; + + song_sample_t *sample = song_get_sample(current_sample); + if (sample->data) + csf_free_sample(sample->data); + sample->data = csf_allocate_sample(len); + memcpy(sample->data, txtsynth_entry, len); + sample->length = len; + sample->loop_start = 0; + sample->loop_end = len; + sample->sustain_start = sample->sustain_end = 0; + sample->flags |= CHN_LOOP; + sample->flags &= ~(CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN + | CHN_16BIT | CHN_STEREO | CHN_ADLIB); + sample_host_dialog(-1); - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } static void txtsynth_draw_const(void) { - draw_text("Enter a text string (e.g. ABCDCB for a triangle-wave)", 13, 27, 0, 2); - draw_box(12, 29, 66, 31, BOX_THIN | BOX_INNER | BOX_INSET); + draw_text("Enter a text string (e.g. ABCDCB for a triangle-wave)", 13, 27, 0, 2); + draw_box(12, 29, 66, 31, BOX_THIN | BOX_INNER | BOX_INSET); } static void txtsynth_dialog(void) { - struct dialog *dialog; + struct dialog *dialog; - // TODO copy the current sample into the entry? + // TODO copy the current sample into the entry? - txtsynth_entry[0] = 0; - create_textentry(txtsynth_widgets + 0, 13, 30, 53, 0, 1, 1, NULL, txtsynth_entry, 65535); - create_button(txtsynth_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); - create_button(txtsynth_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); + txtsynth_entry[0] = 0; + create_textentry(txtsynth_widgets + 0, 13, 30, 53, 0, 1, 1, NULL, txtsynth_entry, 65535); + create_button(txtsynth_widgets + 1, 31, 33, 6, 0, 1, 2, 2, 2, dialog_yes_NULL, "OK", 3); + create_button(txtsynth_widgets + 2, 41, 33, 6, 0, 2, 1, 1, 1, dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(9, 25, 61, 11, txtsynth_widgets, 3, 0, txtsynth_draw_const, NULL); - dialog->action_yes = do_txtsynth; + dialog = dialog_create_custom(9, 25, 61, 11, txtsynth_widgets, 3, 0, txtsynth_draw_const, NULL); + dialog->action_yes = do_txtsynth; } /* --------------------------------------------------------------------- */ @@ -755,312 +765,309 @@ /* N - number, B - boolean (toggle) */ typedef enum adlibconfig_wtypes {N, B} adlibconfig_wtypes; static const struct { - int xref, y; - adlibconfig_wtypes type; - int byteno, firstbit, nbits; + int xref, y; + adlibconfig_wtypes type; + int byteno, firstbit, nbits; } adlibconfig_widgets[] = { - {4, 3, B,10, 0, 1 }, // add. synth - {4, 4, N,10, 1, 3 }, // mod. feedback + {4, 3, B,10, 0, 1 }, // add. synth + {4, 4, N,10, 1, 3 }, // mod. feedback - {0, 7, N, 5, 4, 4 }, // carrier attack - {0, 8, N, 5, 0, 4 }, // carrier decay - {0, 9, N, 7, 4,-4 }, // carrier sustain (0=maximum, 15=minimum) - {0, 10, N, 7, 0, 4 }, // carrier release - {0, 11, B, 1, 5, 1 }, // carrier sustain flag - {0, 12, N, 3, 0,-6 }, // carrier volume (0=maximum, 63=minimum) - - {1, 7, N, 4, 4, 4 }, // modulator attack - {1, 8, N, 4, 0, 4 }, // modulator decay - {1, 9, N, 6, 4,-4 }, // modulator sustain (0=maximum, 15=minimum) - {1, 10, N, 6, 0, 4 }, // modulator release - {1, 11, B, 0, 5, 1 }, // modulator sustain flag - {1, 12, N, 2, 0,-6 }, // modulator volume (0=maximum, 63=minimum) - - {2, 7, B, 1, 4, 1 }, // carrier scale envelope flag - {2, 8, N, 3, 6, 2 }, // carrier level scaling (This is actually reversed bits...) - {2, 9, N, 1, 0, 4 }, // carrier frequency multiplier - {2, 10, N, 9, 0, 2 }, // carrier wave select - {2, 11, B, 1, 6, 1 }, // carrier pitch vibrato - {2, 12, B, 1, 7, 1 }, // carrier volume vibrato - - {3, 7, B, 0, 4, 1 }, // modulator scale envelope flag - {3, 8, N, 2, 6, 2 }, // modulator level scaling (This is actually reversed bits...) - {3, 9, N, 0, 0, 4 }, // modulator frequency multiplier - {3, 10, N, 8, 0, 2 }, // modulator wave select - {3, 11, B, 0, 6, 1 }, // modulator pitch vibrato - {3, 12, B, 0, 7, 1 }, // modulator volume vibrato + {0, 7, N, 5, 4, 4 }, // carrier attack + {0, 8, N, 5, 0, 4 }, // carrier decay + {0, 9, N, 7, 4,-4 }, // carrier sustain (0=maximum, 15=minimum) + {0, 10, N, 7, 0, 4 }, // carrier release + {0, 11, B, 1, 5, 1 }, // carrier sustain flag + {0, 12, N, 3, 0,-6 }, // carrier volume (0=maximum, 63=minimum) + + {1, 7, N, 4, 4, 4 }, // modulator attack + {1, 8, N, 4, 0, 4 }, // modulator decay + {1, 9, N, 6, 4,-4 }, // modulator sustain (0=maximum, 15=minimum) + {1, 10, N, 6, 0, 4 }, // modulator release + {1, 11, B, 0, 5, 1 }, // modulator sustain flag + {1, 12, N, 2, 0,-6 }, // modulator volume (0=maximum, 63=minimum) + + {2, 7, B, 1, 4, 1 }, // carrier scale envelope flag + {2, 8, N, 3, 6, 2 }, // carrier level scaling (This is actually reversed bits...) + {2, 9, N, 1, 0, 4 }, // carrier frequency multiplier + {2, 10, N, 9, 0, 2 }, // carrier wave select + {2, 11, B, 1, 6, 1 }, // carrier pitch vibrato + {2, 12, B, 1, 7, 1 }, // carrier volume vibrato + + {3, 7, B, 0, 4, 1 }, // modulator scale envelope flag + {3, 8, N, 2, 6, 2 }, // modulator level scaling (This is actually reversed bits...) + {3, 9, N, 0, 0, 4 }, // modulator frequency multiplier + {3, 10, N, 8, 0, 2 }, // modulator wave select + {3, 11, B, 0, 6, 1 }, // modulator pitch vibrato + {3, 12, B, 0, 7, 1 }, // modulator volume vibrato }; static void do_adlibconfig(UNUSED void *data) { - //page->help_index = HELP_SAMPLE_LIST; + //page->help_index = HELP_SAMPLE_LIST; - song_sample_t *sample = song_get_sample(current_sample); - if (sample->data) - csf_free_sample(sample->data); - sample->data = csf_allocate_sample(1); - sample->length = 1; - if (!(sample->flags & CHN_ADLIB)) { - sample->flags |= CHN_ADLIB; - status_text_flash("Created adlib sample"); - } - sample->flags &= ~(CHN_16BIT | CHN_STEREO - | CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); - sample->loop_start = sample->loop_end = 0; - sample->sustain_start = sample->sustain_end = 0; - if (!sample->c5speed) { - sample->c5speed = 8363; - sample->volume = 64 * 4; - sample->global_volume = 64; - } - sample_host_dialog(-1); + song_sample_t *sample = song_get_sample(current_sample); + if (sample->data) + csf_free_sample(sample->data); + sample->data = csf_allocate_sample(1); + sample->length = 1; + if (!(sample->flags & CHN_ADLIB)) { + sample->flags |= CHN_ADLIB; + status_text_flash("Created adlib sample"); + } + sample->flags &= ~(CHN_16BIT | CHN_STEREO + | CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); + sample->loop_start = sample->loop_end = 0; + sample->sustain_start = sample->sustain_end = 0; + if (!sample->c5speed) { + sample->c5speed = 8363; + sample->volume = 64 * 4; + sample->global_volume = 64; + } + sample_host_dialog(-1); - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } static void adlibconfig_refresh(void) { - int a; - song_sample_t *sample = song_get_sample(current_sample); + int a; + song_sample_t *sample = song_get_sample(current_sample); - draw_sample_data(&sample_image, sample, current_sample); + draw_sample_data(&sample_image, sample); - for (a = 0; a < ARRAY_SIZE(adlibconfig_widgets); a++) { - unsigned int srcvalue = 0; - unsigned int maskvalue = 0xFFFF; - unsigned int nbits_real = (adlibconfig_widgets[a].nbits < 0 - ? -adlibconfig_widgets[a].nbits - : adlibconfig_widgets[a].nbits); - unsigned int maxvalue = (1 << nbits_real) - 1; - - switch (adlibconfig_widgets[a].type) { - case B: srcvalue = sample_adlibconfig_widgets[a].d.toggle.state; break; - case N: srcvalue = sample_adlibconfig_widgets[a].d.numentry.value; break; - } - - if(adlibconfig_widgets[a].nbits < 0) - srcvalue = maxvalue - srcvalue; // reverse the semantics - - srcvalue &= maxvalue; srcvalue <<= adlibconfig_widgets[a].firstbit; - maskvalue &= maxvalue; maskvalue <<= adlibconfig_widgets[a].firstbit; - - sample->adlib_bytes[adlibconfig_widgets[a].byteno] = - (sample->adlib_bytes[adlibconfig_widgets[a].byteno] &~ maskvalue) | srcvalue; - } + for (a = 0; a < ARRAY_SIZE(adlibconfig_widgets); a++) { + unsigned int srcvalue = 0; + unsigned int maskvalue = 0xFFFF; + unsigned int nbits_real = (adlibconfig_widgets[a].nbits < 0 + ? -adlibconfig_widgets[a].nbits + : adlibconfig_widgets[a].nbits); + unsigned int maxvalue = (1 << nbits_real) - 1; + + switch (adlibconfig_widgets[a].type) { + case B: srcvalue = sample_adlibconfig_widgets[a].d.toggle.state; break; + case N: srcvalue = sample_adlibconfig_widgets[a].d.numentry.value; break; + } + + if(adlibconfig_widgets[a].nbits < 0) + srcvalue = maxvalue - srcvalue; // reverse the semantics + + srcvalue &= maxvalue; srcvalue <<= adlibconfig_widgets[a].firstbit; + maskvalue &= maxvalue; maskvalue <<= adlibconfig_widgets[a].firstbit; + + sample->adlib_bytes[adlibconfig_widgets[a].byteno] = + (sample->adlib_bytes[adlibconfig_widgets[a].byteno] &~ maskvalue) | srcvalue; + } } static void sample_adlibconfig_draw_const(void) { - struct { - int x, y; - const char *label; - } labels[] = { - {19, 1, "Adlib Melodic Instrument Parameters"}, - {19, 3, "Additive Synthesis:"}, - {18, 4, "Modulation Feedback:"}, - {26, 6, "Car Mod"}, - {19, 7, "Attack"}, - {20, 8, "Decay"}, - {18, 9, "Sustain"}, - {18, 10, "Release"}, - {12, 11, "Sustain Sound"}, - {19, 12, "Volume"}, - {58, 6, "Car Mod"}, - {43, 7, "Scale Envelope"}, - {44, 8, "Level Scaling"}, - {37, 9, "Frequency Multiplier"}, - {46, 10, "Wave Select"}, - {44, 11, "Pitch Vibrato"}, - {43, 12, "Volume Vibrato"}, - }; - - int a; - - // 39 33 - draw_box(38, 2 + 30, 40, 5 + 30, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_fill_chars(25, 6 + 30, 32,13 + 30, 0); - draw_box(25, 6 + 30, 28, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(29, 6 + 30, 32, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_fill_chars(57, 6 + 30, 64,13 + 30, 0); - draw_box(57, 6 + 30, 60, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(61, 6 + 30, 64, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); + struct { + int x, y; + const char *label; + } labels[] = { + {19, 1, "Adlib Melodic Instrument Parameters"}, + {19, 3, "Additive Synthesis:"}, + {18, 4, "Modulation Feedback:"}, + {26, 6, "Car Mod"}, + {19, 7, "Attack"}, + {20, 8, "Decay"}, + {18, 9, "Sustain"}, + {18, 10, "Release"}, + {12, 11, "Sustain Sound"}, + {19, 12, "Volume"}, + {58, 6, "Car Mod"}, + {43, 7, "Scale Envelope"}, + {44, 8, "Level Scaling"}, + {37, 9, "Frequency Multiplier"}, + {46, 10, "Wave Select"}, + {44, 11, "Pitch Vibrato"}, + {43, 12, "Volume Vibrato"}, + }; + + int a; + + // 39 33 + draw_box(38, 2 + 30, 40, 5 + 30, BOX_THIN | BOX_INNER | BOX_INSET); + + draw_fill_chars(25, 6 + 30, 32,13 + 30, 0); + draw_box(25, 6 + 30, 28, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(29, 6 + 30, 32, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); + + draw_fill_chars(57, 6 + 30, 64,13 + 30, 0); + draw_box(57, 6 + 30, 60, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(61, 6 + 30, 64, 13 + 30, BOX_THIN | BOX_INNER | BOX_INSET); - for (a = 0; a < ARRAY_SIZE(labels); a++) - draw_text(labels[a].label, labels[a].x, labels[a].y + 30, a ? 0 : 3, 2); + for (a = 0; a < ARRAY_SIZE(labels); a++) + draw_text(labels[a].label, labels[a].x, labels[a].y + 30, a ? 0 : 3, 2); } static int do_adlib_handlekey(struct key_event *kk) { - if (kk->sym == SDLK_F1) { - if (!kk->state) return 1; - status.current_help_index = HELP_ADLIB_SAMPLE; - dialog_f1_hack = 1; - dialog_destroy_all(); - set_page(PAGE_HELP); - return 1; - } - return 0; + if (kk->sym == SDLK_F1) { + if (kk->state == KEY_PRESS) + return 1; + status.current_help_index = HELP_ADLIB_SAMPLE; + dialog_f1_hack = 1; + dialog_destroy_all(); + set_page(PAGE_HELP); + return 1; + } + return 0; } static void sample_adlibconfig_dialog(UNUSED void *ign) { - struct dialog *dialog; - song_sample_t *sample = song_get_sample(current_sample); + struct dialog *dialog; + song_sample_t *sample = song_get_sample(current_sample); - int a; + int a; - //page->help_index = HELP_ADLIB_SAMPLES; - // Eh, what page? Where am I supposed to get a reference to page? - // How do I make this work? -Bisqwit - - for (a = 0; a < ARRAY_SIZE(adlibconfig_widgets); a++) { - unsigned int srcvalue = sample->adlib_bytes[adlibconfig_widgets[a].byteno]; - unsigned int nbits_real = adlibconfig_widgets[a].nbits < 0 - ? -adlibconfig_widgets[a].nbits - : adlibconfig_widgets[a].nbits; - unsigned int minvalue = 0, maxvalue = (1 << nbits_real) - 1; - - srcvalue >>= adlibconfig_widgets[a].firstbit; - srcvalue &= maxvalue; - if (adlibconfig_widgets[a].nbits < 0) - srcvalue = maxvalue - srcvalue; // reverse the semantics - - switch (adlibconfig_widgets[a].type) { - case B: - create_menutoggle(sample_adlibconfig_widgets + a, - adlib_xpos[adlibconfig_widgets[a].xref], - adlibconfig_widgets[a].y + 30, - a > 0 ? a - 1 : 0, - a + 1 < ARRAY_SIZE(adlibconfig_widgets) ? a + 1 : a, - a, a, - (a > 1 ? ((a + 4) % (ARRAY_SIZE(adlibconfig_widgets) - 2)) + 2 : 2), - adlibconfig_refresh, yn_toggle); - sample_adlibconfig_widgets[a].d.menutoggle.state = srcvalue; - sample_adlibconfig_widgets[a].d.menutoggle.activation_keys = "ny"; - break; - case N: - create_numentry(sample_adlibconfig_widgets + a, - adlib_xpos[adlibconfig_widgets[a].xref], - adlibconfig_widgets[a].y + 30, - nbits_real < 4 ? 1 : 2, - a > 0 ? a - 1 : 0, - a + 1 < ARRAY_SIZE(adlibconfig_widgets) ? a + 1 : a, - (a > 1 ? ((a + 4) % (ARRAY_SIZE(adlibconfig_widgets) - 2)) + 2 : 2), - adlibconfig_refresh, - minvalue, maxvalue, - adlib_cursorpos + adlibconfig_widgets[a].xref); - sample_adlibconfig_widgets[a].d.numentry.value = srcvalue; - break; - } - } - - dialog = dialog_create_custom(9, 30, 61, 15, sample_adlibconfig_widgets, - ARRAY_SIZE(adlibconfig_widgets), 0, - sample_adlibconfig_draw_const, NULL); - dialog->action_yes = do_adlibconfig; - dialog->handle_key = do_adlib_handlekey; + //page->help_index = HELP_ADLIB_SAMPLES; + // Eh, what page? Where am I supposed to get a reference to page? + // How do I make this work? -Bisqwit + + for (a = 0; a < ARRAY_SIZE(adlibconfig_widgets); a++) { + unsigned int srcvalue = sample->adlib_bytes[adlibconfig_widgets[a].byteno]; + unsigned int nbits_real = adlibconfig_widgets[a].nbits < 0 + ? -adlibconfig_widgets[a].nbits + : adlibconfig_widgets[a].nbits; + unsigned int minvalue = 0, maxvalue = (1 << nbits_real) - 1; + + srcvalue >>= adlibconfig_widgets[a].firstbit; + srcvalue &= maxvalue; + if (adlibconfig_widgets[a].nbits < 0) + srcvalue = maxvalue - srcvalue; // reverse the semantics + + switch (adlibconfig_widgets[a].type) { + case B: + create_menutoggle(sample_adlibconfig_widgets + a, + adlib_xpos[adlibconfig_widgets[a].xref], + adlibconfig_widgets[a].y + 30, + a > 0 ? a - 1 : 0, + a + 1 < ARRAY_SIZE(adlibconfig_widgets) ? a + 1 : a, + a, a, + (a > 1 ? ((a + 4) % (ARRAY_SIZE(adlibconfig_widgets) - 2)) + 2 : 2), + adlibconfig_refresh, yn_toggle); + sample_adlibconfig_widgets[a].d.menutoggle.state = srcvalue; + sample_adlibconfig_widgets[a].d.menutoggle.activation_keys = "ny"; + break; + case N: + create_numentry(sample_adlibconfig_widgets + a, + adlib_xpos[adlibconfig_widgets[a].xref], + adlibconfig_widgets[a].y + 30, + nbits_real < 4 ? 1 : 2, + a > 0 ? a - 1 : 0, + a + 1 < ARRAY_SIZE(adlibconfig_widgets) ? a + 1 : a, + (a > 1 ? ((a + 4) % (ARRAY_SIZE(adlibconfig_widgets) - 2)) + 2 : 2), + adlibconfig_refresh, + minvalue, maxvalue, + adlib_cursorpos + adlibconfig_widgets[a].xref); + sample_adlibconfig_widgets[a].d.numentry.value = srcvalue; + break; + } + } + + dialog = dialog_create_custom(9, 30, 61, 15, sample_adlibconfig_widgets, + ARRAY_SIZE(adlibconfig_widgets), 0, + sample_adlibconfig_draw_const, NULL); + dialog->action_yes = do_adlibconfig; + dialog->handle_key = do_adlib_handlekey; } static void sample_adlibpatch_finish(int n) { - song_sample_t *sample; + song_sample_t *sample; - if (n <= 0 || n > 128) - return; + if (n <= 0 || n > 128) + return; - sample = song_get_sample(current_sample); - if (sample->data) { - csf_free_sample(sample->data); - sample->data = NULL; - } - adlib_patch_apply((song_sample_t *) sample, n - 1); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; // redraw the sample + sample = song_get_sample(current_sample); + adlib_patch_apply((song_sample_t *) sample, n - 1); + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; // redraw the sample - sample_host_dialog(-1); + sample_host_dialog(-1); } static void sample_adlibpatch_dialog(UNUSED void *ign) { - numprompt_create("Enter Patch (1-128)", sample_adlibpatch_finish, 0); + numprompt_create("Enter Patch (1-128)", sample_adlibpatch_finish, 0); } /* --------------------------------------------------------------------- */ /* filename can be NULL, in which case the sample filename is used (quick save) */ struct sample_save_data { - char *path; - /* char *options? */ - const char *format; + char *path; + /* char *options? */ + const char *format; }; static void save_sample_free_data(void *ptr) { - struct sample_save_data *data = (struct sample_save_data *) ptr; - if (data->path) - free(data->path); - free(data); + struct sample_save_data *data = (struct sample_save_data *) ptr; + if (data->path) + free(data->path); + free(data); } static void do_save_sample(void *ptr) { - struct sample_save_data *data = (struct sample_save_data *) ptr; + struct sample_save_data *data = (struct sample_save_data *) ptr; - // I guess this function doesn't need to care about the return value, - // since song_save_sample is handling all the visual feedback... - song_save_sample(data->path, data->format, song_get_sample(current_sample), current_sample); - save_sample_free_data(ptr); + // I guess this function doesn't need to care about the return value, + // since song_save_sample is handling all the visual feedback... + song_save_sample(data->path, data->format, song_get_sample(current_sample), current_sample); + save_sample_free_data(ptr); } static void sample_save(const char *filename, const char *format) { - song_sample_t *sample = song_get_sample(current_sample); - char *ptr, *q; - struct sample_save_data *data; - struct stat buf; - int tmp; - - if (stat(cfg_dir_samples, &buf) == -1) { - status_text_flash("Sample directory \"%s\" unreachable", filename); - return; - } - - tmp=0; - data = mem_alloc(sizeof(struct sample_save_data)); - if (!S_ISDIR(buf.st_mode)) { - /* directory browsing */ - q = strrchr(cfg_dir_samples, DIR_SEPARATOR); - if (q) { - tmp = q[1]; - q[1] = '\0'; - } - } else { - q = NULL; - } - - ptr = dmoz_path_concat(cfg_dir_samples, filename ? : sample->filename); - if (q) q[1] = tmp; - - data->path = ptr; - data->format = format; - - if (filename && *filename && stat(ptr, &buf) == 0) { - if (S_ISREG(buf.st_mode)) { - dialog_create(DIALOG_OK_CANCEL, "Overwrite file?", - do_save_sample, save_sample_free_data, 1, data); - /* callback will free it */ - } else if (S_ISDIR(buf.st_mode)) { - status_text_flash("%s is a directory", filename); - save_sample_free_data(data); - } else { - status_text_flash("%s is not a regular file", filename); - save_sample_free_data(data); - } - } else { - do_save_sample(data); - } + song_sample_t *sample = song_get_sample(current_sample); + char *ptr, *q; + struct sample_save_data *data; + struct stat buf; + int tmp; + + if (stat(cfg_dir_samples, &buf) == -1) { + status_text_flash("Sample directory \"%s\" unreachable", filename); + return; + } + + tmp=0; + data = mem_alloc(sizeof(struct sample_save_data)); + if (!S_ISDIR(buf.st_mode)) { + /* directory browsing */ + q = strrchr(cfg_dir_samples, DIR_SEPARATOR); + if (q) { + tmp = q[1]; + q[1] = '\0'; + } + } else { + q = NULL; + } + + ptr = dmoz_path_concat(cfg_dir_samples, filename ? : sample->filename); + if (q) q[1] = tmp; + + data->path = ptr; + data->format = format; + + if (filename && *filename && stat(ptr, &buf) == 0) { + if (S_ISREG(buf.st_mode)) { + dialog_create(DIALOG_OK_CANCEL, "Overwrite file?", + do_save_sample, save_sample_free_data, 1, data); + /* callback will free it */ + } else if (S_ISDIR(buf.st_mode)) { + status_text_flash("%s is a directory", filename); + save_sample_free_data(data); + } else { + status_text_flash("%s is not a regular file", filename); + save_sample_free_data(data); + } + } else { + do_save_sample(data); + } } /* export sample dialog */ @@ -1072,118 +1079,119 @@ static void do_export_sample(UNUSED void *data) { - sample_save(export_sample_filename, sample_save_formats[export_sample_format].label); + sample_save(export_sample_filename, sample_save_formats[export_sample_format].label); } static void export_sample_list_draw(void) { - int n, focused = (*selected_widget == 3); + int n, focused = (*selected_widget == 3); - draw_fill_chars(53, 24, 56, 31, 0); - for (n = 0; sample_save_formats[n].label; n++) { - int fg = 6, bg = 0; - if (focused && n == export_sample_format) { - fg = 0; - bg = 3; - } else if (n == export_sample_format) { - bg = 14; - } - draw_text_len(sample_save_formats[n].label, 4, 53, 24 + n, fg, bg); - } + draw_fill_chars(53, 24, 56, 31, 0); + for (n = 0; sample_save_formats[n].label; n++) { + int fg = 6, bg = 0; + if (focused && n == export_sample_format) { + fg = 0; + bg = 3; + } else if (n == export_sample_format) { + bg = 14; + } + draw_text_len(sample_save_formats[n].label, 4, 53, 24 + n, fg, bg); + } } static int export_sample_list_handle_key(struct key_event * k) { - int new_format = export_sample_format; + int new_format = export_sample_format; - if (k->state) return 0; - switch (k->sym) { - case SDLK_UP: - if (!NO_MODIFIER(k->mod)) - return 0; - new_format--; - break; - case SDLK_DOWN: - if (!NO_MODIFIER(k->mod)) - return 0; - new_format++; - break; - case SDLK_PAGEUP: - case SDLK_HOME: - if (!NO_MODIFIER(k->mod)) - return 0; - new_format = 0; - break; - case SDLK_PAGEDOWN: - case SDLK_END: - if (!NO_MODIFIER(k->mod)) - return 0; - new_format = num_save_formats - 1; - break; - case SDLK_TAB: - if (k->mod & KMOD_SHIFT) { - change_focus_to(0); - return 1; - } - /* fall through */ - case SDLK_LEFT: - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(0); /* should focus 0/1/2 depending on what's closest */ - return 1; - default: - return 0; - } - - new_format = CLAMP(new_format, 0, num_save_formats - 1); - if (new_format != export_sample_format) { - /* update the option string */ - export_sample_format = new_format; - status.flags |= NEED_UPDATE; - } + if (k->state == KEY_RELEASE) + return 0; + switch (k->sym) { + case SDLK_UP: + if (!NO_MODIFIER(k->mod)) + return 0; + new_format--; + break; + case SDLK_DOWN: + if (!NO_MODIFIER(k->mod)) + return 0; + new_format++; + break; + case SDLK_PAGEUP: + case SDLK_HOME: + if (!NO_MODIFIER(k->mod)) + return 0; + new_format = 0; + break; + case SDLK_PAGEDOWN: + case SDLK_END: + if (!NO_MODIFIER(k->mod)) + return 0; + new_format = num_save_formats - 1; + break; + case SDLK_TAB: + if (k->mod & KMOD_SHIFT) { + change_focus_to(0); + return 1; + } + /* fall through */ + case SDLK_LEFT: + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(0); /* should focus 0/1/2 depending on what's closest */ + return 1; + default: + return 0; + } + + new_format = CLAMP(new_format, 0, num_save_formats - 1); + if (new_format != export_sample_format) { + /* update the option string */ + export_sample_format = new_format; + status.flags |= NEED_UPDATE; + } - return 1; + return 1; } static void export_sample_draw_const(void) { - draw_text("Export Sample", 34, 21, 0, 2); + draw_text("Export Sample", 34, 21, 0, 2); - draw_text("Filename", 24, 24, 0, 2); - draw_box(32, 23, 51, 25, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Filename", 24, 24, 0, 2); + draw_box(32, 23, 51, 25, BOX_THICK | BOX_INNER | BOX_INSET); - draw_text("Options", 25, 27, 0, 2); - draw_box(32, 26, 51, 28, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Options", 25, 27, 0, 2); + draw_box(32, 26, 51, 28, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(52, 23, 57, 32, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(52, 23, 57, 32, BOX_THICK | BOX_INNER | BOX_INSET); } static void configure_options(void) { - dialog_create(DIALOG_OK, "This doesn't do anything yet. Stay tuned! :)", NULL, NULL, 0, NULL); + dialog_create(DIALOG_OK, "This doesn't do anything yet. Stay tuned! :)", NULL, NULL, 0, NULL); } static void export_sample_dialog(void) { - song_sample_t *sample = song_get_sample(current_sample); - struct dialog *dialog; + song_sample_t *sample = song_get_sample(current_sample); + struct dialog *dialog; - create_textentry(export_sample_widgets + 0, 33, 24, 18, 0, 1, 3, NULL, - export_sample_filename, NAME_MAX); - create_textentry(export_sample_widgets + 1, 33, 27, 18, 0, 2, 3, NULL, - export_sample_options, 256); - create_button(export_sample_widgets + 2, 33, 30, 9, 1, 4, 3, 3, 3, configure_options, "Configure", 1); - create_other(export_sample_widgets + 3, 0, export_sample_list_handle_key, export_sample_list_draw); - create_button(export_sample_widgets + 4, 31, 35, 6, 2, 4, 5, 5, 5, dialog_yes_NULL, "OK", 3); - create_button(export_sample_widgets + 5, 42, 35, 6, 3, 5, 4, 4, 4, dialog_cancel_NULL, "Cancel", 1); - - strncpy(export_sample_filename, sample->filename, NAME_MAX); - export_sample_filename[NAME_MAX] = 0; - - dialog = dialog_create_custom(21, 20, 39, 18, export_sample_widgets, 6, 0, - export_sample_draw_const, NULL); - dialog->action_yes = do_export_sample; + create_textentry(export_sample_widgets + 0, 33, 24, 18, 0, 1, 3, NULL, + export_sample_filename, NAME_MAX); + create_textentry(export_sample_widgets + 1, 33, 27, 18, 0, 2, 3, NULL, + export_sample_options, 256); + create_button(export_sample_widgets + 2, 33, 30, 9, 1, 4, 3, 3, 3, configure_options, "Configure", 1); + create_other(export_sample_widgets + 3, 0, export_sample_list_handle_key, export_sample_list_draw); + create_button(export_sample_widgets + 4, 31, 35, 6, 2, 4, 5, 5, 5, dialog_yes_NULL, "OK", 3); + create_button(export_sample_widgets + 5, 42, 35, 6, 3, 5, 4, 4, 4, dialog_cancel_NULL, "Cancel", 1); + + strncpy(export_sample_filename, sample->filename, NAME_MAX); + export_sample_filename[NAME_MAX] = 0; + + dialog = dialog_create_custom(21, 20, 39, 18, export_sample_widgets, 6, 0, + export_sample_draw_const, NULL); + dialog->action_yes = do_export_sample; } @@ -1193,303 +1201,313 @@ static void do_resize_sample_aa(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); - unsigned int newlen = resize_sample_widgets[0].d.numentry.value; - sample_resize(sample, newlen, 1); + song_sample_t *sample = song_get_sample(current_sample); + unsigned int newlen = resize_sample_widgets[0].d.numentry.value; + sample_resize(sample, newlen, 1); } static void do_resize_sample(UNUSED void *data) { - song_sample_t *sample = song_get_sample(current_sample); - unsigned int newlen = resize_sample_widgets[0].d.numentry.value; - sample_resize(sample, newlen, 0); + song_sample_t *sample = song_get_sample(current_sample); + unsigned int newlen = resize_sample_widgets[0].d.numentry.value; + sample_resize(sample, newlen, 0); } static void resize_sample_draw_const(void) { - draw_text("Resize Sample", 34, 24, 3, 2); - draw_text("New Length", 31, 27, 0, 2); - draw_box(41, 26, 49, 28, BOX_THICK | BOX_INNER | BOX_INSET); + draw_text("Resize Sample", 34, 24, 3, 2); + draw_text("New Length", 31, 27, 0, 2); + draw_box(41, 26, 49, 28, BOX_THICK | BOX_INNER | BOX_INSET); } static void resize_sample_dialog(int aa) { - song_sample_t *sample = song_get_sample(current_sample); - struct dialog *dialog; + song_sample_t *sample = song_get_sample(current_sample); + struct dialog *dialog; - resize_sample_cursor = 0; - create_numentry(resize_sample_widgets + 0, 42, 27, 7, 0, 1, 1, NULL, 0, 9999999, &resize_sample_cursor); - resize_sample_widgets[0].d.numentry.value = sample->length; - create_button(resize_sample_widgets + 1, 36, 30, 6, 0, 1, 1, 1, 1, - dialog_cancel_NULL, "Cancel", 1); - dialog = dialog_create_custom(26, 22, 29, 11, resize_sample_widgets, 2, 0, - resize_sample_draw_const, NULL); - dialog->action_yes = aa ? do_resize_sample_aa : do_resize_sample; + resize_sample_cursor = 0; + create_numentry(resize_sample_widgets + 0, 42, 27, 7, 0, 1, 1, NULL, 0, 9999999, &resize_sample_cursor); + resize_sample_widgets[0].d.numentry.value = sample->length; + create_button(resize_sample_widgets + 1, 36, 30, 6, 0, 1, 1, 1, 1, + dialog_cancel_NULL, "Cancel", 1); + dialog = dialog_create_custom(26, 22, 29, 11, resize_sample_widgets, 2, 0, + resize_sample_draw_const, NULL); + dialog->action_yes = aa ? do_resize_sample_aa : do_resize_sample; } /* --------------------------------------------------------------------- */ static void sample_set_mute(int n, int mute) { - song_sample_t *smp = song_get_sample(n); + song_sample_t *smp = song_get_sample(n); - if (mute) { - if (smp->flags & CHN_MUTE) - return; - smp->globalvol_saved = smp->global_volume; - smp->global_volume = 0; - smp->flags |= CHN_MUTE; - } else { - if (!(smp->flags & CHN_MUTE)) - return; - smp->global_volume = smp->globalvol_saved; - smp->flags &= ~CHN_MUTE; - } + if (mute) { + if (smp->flags & CHN_MUTE) + return; + smp->globalvol_saved = smp->global_volume; + smp->global_volume = 0; + smp->flags |= CHN_MUTE; + } else { + if (!(smp->flags & CHN_MUTE)) + return; + smp->global_volume = smp->globalvol_saved; + smp->flags &= ~CHN_MUTE; + } } static void sample_toggle_mute(int n) { - song_sample_t *smp = song_get_sample(n); - sample_set_mute(n, !(smp->flags & CHN_MUTE)); + song_sample_t *smp = song_get_sample(n); + sample_set_mute(n, !(smp->flags & CHN_MUTE)); } static void sample_toggle_solo(int n) { - int i, solo = 0; + int i, solo = 0; - if (song_get_sample(n)->flags & CHN_MUTE) { - solo = 1; - } else { - for (i = 1; i < MAX_SAMPLES; i++) { - if (i != n && !(song_get_sample(i)->flags & CHN_MUTE)) { - solo = 1; - break; - } - } - } - for (i = 1; i < MAX_SAMPLES; i++) - sample_set_mute(i, solo && i != n); + if (song_get_sample(n)->flags & CHN_MUTE) { + solo = 1; + } else { + for (i = 1; i < MAX_SAMPLES; i++) { + if (i != n && !(song_get_sample(i)->flags & CHN_MUTE)) { + solo = 1; + break; + } + } + } + for (i = 1; i < MAX_SAMPLES; i++) + sample_set_mute(i, solo && i != n); } /* --------------------------------------------------------------------- */ static void sample_list_handle_alt_key(struct key_event * k) { - song_sample_t *sample = song_get_sample(current_sample); - int canmod = (sample->data != NULL && !(sample->flags & CHN_ADLIB)); + song_sample_t *sample = song_get_sample(current_sample); + int canmod = (sample->data != NULL && !(sample->flags & CHN_ADLIB)); - if (k->state) return; - switch (k->sym) { - case SDLK_a: - if (canmod) - dialog_create(DIALOG_OK_CANCEL, "Convert sample?", do_sign_convert, NULL, 0, NULL); - return; - case SDLK_b: - if (canmod && (sample->loop_start > 0 - || ((sample->flags & CHN_SUSTAINLOOP) && sample->sustain_start > 0))) { - dialog_create(DIALOG_OK_CANCEL, "Cut sample?", do_pre_loop_cut, NULL, 1, NULL); - } - return; - case SDLK_d: - dialog_create(DIALOG_OK_CANCEL, "Delete sample?", do_delete_sample, NULL, 1, NULL); - return; - case SDLK_e: - if (canmod) - resize_sample_dialog(1); - break; - case SDLK_f: - if (canmod) - resize_sample_dialog(0); - break; - case SDLK_g: - if (canmod) - sample_reverse(sample); - break; - case SDLK_h: - if (canmod) - dialog_create(DIALOG_YES_NO, "Centralise sample?", do_centralise, NULL, 0, NULL); - return; - case SDLK_i: - if (canmod) - sample_invert(sample); - break; - case SDLK_l: - if (canmod && (sample->loop_end > 0 - || ((sample->flags & CHN_SUSTAINLOOP) && sample->sustain_end > 0))) { - dialog_create(DIALOG_OK_CANCEL, "Cut sample?", do_post_loop_cut, NULL, 1, NULL); - } - return; - case SDLK_m: - if (canmod) - sample_amplify_dialog(); - return; - case SDLK_n: - song_toggle_multichannel_mode(); - return; - case SDLK_q: - if (canmod) { - dialog_create(DIALOG_YES_NO, "Convert sample?", - do_quality_convert, do_quality_toggle, 0, NULL); - } - return; - case SDLK_o: - sample_save(NULL, "ITS"); - return; - case SDLK_p: - smpprompt_create("Copy sample:", "Sample", do_copy_sample); - return; - case SDLK_r: - smpprompt_create("Replace sample with:", "Sample", do_replace_sample); - return; - case SDLK_s: - smpprompt_create("Swap sample with:", "Sample", do_swap_sample); - return; - case SDLK_t: - export_sample_dialog(); - return; - case SDLK_w: - sample_save(NULL, "RAW"); - return; - case SDLK_x: - smpprompt_create("Exchange sample with:", "Sample", do_exchange_sample); - return; - case SDLK_y: - /* hi virt */ - txtsynth_dialog(); - return; - case SDLK_z: - { // uguu~ - void (*dlg)(void *) = (k->mod & KMOD_SHIFT) - ? sample_adlibpatch_dialog - : sample_adlibconfig_dialog; - if (canmod) { - dialog_create(DIALOG_OK_CANCEL, "This will replace this sample", - dlg, NULL, 1, NULL); - } else { - dlg(NULL); - } - } - return; - case SDLK_INSERT: - song_insert_sample_slot(current_sample); - break; - case SDLK_DELETE: - song_remove_sample_slot(current_sample); - break; - case SDLK_F9: - sample_toggle_mute(current_sample); - break; - case SDLK_F10: - sample_toggle_solo(current_sample); - break; - default: - return; - } + if (k->state == KEY_RELEASE) + return; + switch (k->sym) { + case SDLK_a: + if (canmod) + dialog_create(DIALOG_OK_CANCEL, "Convert sample?", do_sign_convert, NULL, 0, NULL); + return; + case SDLK_b: + if (canmod && (sample->loop_start > 0 + || ((sample->flags & CHN_SUSTAINLOOP) && sample->sustain_start > 0))) { + dialog_create(DIALOG_OK_CANCEL, "Cut sample?", do_pre_loop_cut, NULL, 1, NULL); + } + return; + case SDLK_d: + dialog_create(DIALOG_OK_CANCEL, "Delete sample?", do_delete_sample, NULL, 1, NULL); + return; + case SDLK_e: + if (canmod) + resize_sample_dialog(1); + break; + case SDLK_f: + if (canmod) + resize_sample_dialog(0); + break; + case SDLK_g: + if (canmod) + sample_reverse(sample); + break; + case SDLK_h: + if (canmod) + dialog_create(DIALOG_YES_NO, "Centralise sample?", do_centralise, NULL, 0, NULL); + return; + case SDLK_i: + if (canmod) + sample_invert(sample); + break; + case SDLK_l: + if (canmod && (sample->loop_end > 0 + || ((sample->flags & CHN_SUSTAINLOOP) && sample->sustain_end > 0))) { + dialog_create(DIALOG_OK_CANCEL, "Cut sample?", do_post_loop_cut, NULL, 1, NULL); + } + return; + case SDLK_m: + if (canmod) + sample_amplify_dialog(); + return; + case SDLK_n: + song_toggle_multichannel_mode(); + return; + case SDLK_q: + if (canmod) { + dialog_create(DIALOG_YES_NO, "Convert sample?", + do_quality_convert, do_quality_toggle, 0, NULL); + } + return; + case SDLK_o: + sample_save(NULL, "ITS"); + return; + case SDLK_p: + smpprompt_create("Copy sample:", "Sample", do_copy_sample); + return; + case SDLK_r: + smpprompt_create("Replace sample with:", "Sample", do_replace_sample); + return; + case SDLK_s: + smpprompt_create("Swap sample with:", "Sample", do_swap_sample); + return; + case SDLK_t: + export_sample_dialog(); + return; + case SDLK_w: + sample_save(NULL, "RAW"); + return; + case SDLK_x: + smpprompt_create("Exchange sample with:", "Sample", do_exchange_sample); + return; + case SDLK_y: + /* hi virt */ + txtsynth_dialog(); + return; + case SDLK_z: + { // uguu~ + void (*dlg)(void *) = (k->mod & KMOD_SHIFT) + ? sample_adlibpatch_dialog + : sample_adlibconfig_dialog; + if (canmod) { + dialog_create(DIALOG_OK_CANCEL, "This will replace the current sample.", + dlg, NULL, 1, NULL); + } else { + dlg(NULL); + } + } + return; + case SDLK_INSERT: + song_insert_sample_slot(current_sample); + break; + case SDLK_DELETE: + song_remove_sample_slot(current_sample); + break; + case SDLK_F9: + sample_toggle_mute(current_sample); + break; + case SDLK_F10: + sample_toggle_solo(current_sample); + break; + default: + return; + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static void sample_list_handle_key(struct key_event * k) { - int new_sample = current_sample; - song_sample_t *sample = song_get_sample(current_sample); + int new_sample = current_sample; + song_sample_t *sample = song_get_sample(current_sample); - switch (k->sym) { - case SDLK_SPACE: - if (k->state) return; - if (selected_widget && *selected_widget == 0) { - status.flags |= NEED_UPDATE; - } - return; - case SDLK_PLUS: - if (k->state) return; - if (k->mod & KMOD_ALT) { - sample->c5speed *= 2; - status.flags |= SONG_NEEDS_SAVE; - } else if (k->mod & KMOD_CTRL) { - sample->c5speed = calc_halftone(sample->c5speed, 1); - status.flags |= SONG_NEEDS_SAVE; - } - status.flags |= NEED_UPDATE; - return; - case SDLK_MINUS: - if (k->state) return; - if (k->mod & KMOD_ALT) { - sample->c5speed /= 2; - status.flags |= SONG_NEEDS_SAVE; - } else if (k->mod & KMOD_CTRL) { - sample->c5speed = calc_halftone(sample->c5speed, -1); - status.flags |= SONG_NEEDS_SAVE; - } - status.flags |= NEED_UPDATE; - return; - - case SDLK_COMMA: - case SDLK_LESS: - if (k->state) return; - song_change_current_play_channel(-1, 0); - return; - case SDLK_PERIOD: - case SDLK_GREATER: - if (k->state) return; - song_change_current_play_channel(1, 0); - return; - case SDLK_PAGEUP: - if (k->state) return; - new_sample--; - break; - case SDLK_PAGEDOWN: - if (k->state) return; - new_sample++; - break; - case SDLK_ESCAPE: - if (k->mod & KMOD_SHIFT) { - if (k->state) return; - sample_list_cursor_pos = 25; - _fix_accept_text(); - change_focus_to(0); - status.flags |= NEED_UPDATE; - return; - } - return; - default: - if (k->mod & KMOD_ALT) { - if (k->state) return; - sample_list_handle_alt_key(k); - } else if (!k->is_repeat) { - int n, v; - if (k->midi_note > -1) { - n = k->midi_note; - if (k->midi_volume > -1) { - v = k->midi_volume / 2; - } else { - v = KEYJAZZ_DEFAULTVOL; - } - } else { - n = (k->sym == SDLK_SPACE) - ? last_note - : kbd_get_note(k); - if (n <= 0 || n > 120) - return; - v = KEYJAZZ_DEFAULTVOL; - } - if (k->state) { - song_keyup(current_sample, KEYJAZZ_NOINST, n); - } else { - song_keydown(current_sample, KEYJAZZ_NOINST, n, v, KEYJAZZ_CHAN_CURRENT); - last_note = n; - } - } - return; - } - - new_sample = CLAMP(new_sample, 1, _last_vis_sample()); - - if (new_sample != current_sample) { - sample_set(new_sample); - sample_list_reposition(); - status.flags |= NEED_UPDATE; - } + switch (k->sym) { + case SDLK_SPACE: + if (k->state == KEY_RELEASE) + return; + if (selected_widget && *selected_widget == 0) { + status.flags |= NEED_UPDATE; + } + return; + case SDLK_PLUS: + if (k->state == KEY_RELEASE) + return; + if (k->mod & KMOD_ALT) { + sample->c5speed *= 2; + status.flags |= SONG_NEEDS_SAVE; + } else if (k->mod & KMOD_CTRL) { + sample->c5speed = calc_halftone(sample->c5speed, 1); + status.flags |= SONG_NEEDS_SAVE; + } + status.flags |= NEED_UPDATE; + return; + case SDLK_MINUS: + if (k->state == KEY_RELEASE) + return; + if (k->mod & KMOD_ALT) { + sample->c5speed /= 2; + status.flags |= SONG_NEEDS_SAVE; + } else if (k->mod & KMOD_CTRL) { + sample->c5speed = calc_halftone(sample->c5speed, -1); + status.flags |= SONG_NEEDS_SAVE; + } + status.flags |= NEED_UPDATE; + return; + + case SDLK_COMMA: + case SDLK_LESS: + if (k->state == KEY_RELEASE) + return; + song_change_current_play_channel(-1, 0); + return; + case SDLK_PERIOD: + case SDLK_GREATER: + if (k->state == KEY_RELEASE) + return; + song_change_current_play_channel(1, 0); + return; + case SDLK_PAGEUP: + if (k->state == KEY_RELEASE) + return; + new_sample--; + break; + case SDLK_PAGEDOWN: + if (k->state == KEY_RELEASE) + return; + new_sample++; + break; + case SDLK_ESCAPE: + if (k->mod & KMOD_SHIFT) { + if (k->state == KEY_RELEASE) + return; + sample_list_cursor_pos = 25; + _fix_accept_text(); + change_focus_to(0); + status.flags |= NEED_UPDATE; + return; + } + return; + default: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return; + sample_list_handle_alt_key(k); + } else if (!k->is_repeat) { + int n, v; + if (k->midi_note > -1) { + n = k->midi_note; + if (k->midi_volume > -1) { + v = k->midi_volume / 2; + } else { + v = KEYJAZZ_DEFAULTVOL; + } + } else { + n = (k->sym == SDLK_SPACE) + ? last_note + : kbd_get_note(k); + if (n <= 0 || n > 120) + return; + v = KEYJAZZ_DEFAULTVOL; + } + if (k->state == KEY_RELEASE) { + song_keyup(current_sample, KEYJAZZ_NOINST, n); + } else { + song_keydown(current_sample, KEYJAZZ_NOINST, n, v, KEYJAZZ_CHAN_CURRENT); + last_note = n; + } + } + return; + } + + new_sample = CLAMP(new_sample, 1, _last_vis_sample()); + + if (new_sample != current_sample) { + sample_set(new_sample); + sample_list_reposition(); + status.flags |= NEED_UPDATE; + } } /* --------------------------------------------------------------------- */ @@ -1497,49 +1515,49 @@ static void sample_list_draw_const(void) { - int n; + int n; - draw_box(4, 12, 35, 48, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(63, 12, 77, 24, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(4, 12, 35, 48, BOX_THICK | BOX_INNER | BOX_INSET); + draw_box(63, 12, 77, 24, BOX_THICK | BOX_INNER | BOX_INSET); - draw_box(36, 12, 53, 18, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(37, 15, 47, 17, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(36, 19, 53, 25, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(37, 22, 47, 24, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(36, 26, 53, 33, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(37, 29, 47, 32, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(36, 35, 53, 41, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(37, 38, 47, 40, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(36, 42, 53, 48, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(37, 45, 47, 47, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(54, 25, 77, 30, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(54, 31, 77, 41, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(54, 42, 77, 48, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(55, 45, 72, 47, BOX_THIN | BOX_INNER | BOX_INSET); - - draw_fill_chars(41, 30, 46, 30, 0); - draw_fill_chars(64, 13, 76, 23, 0); - - draw_text("Default Volume", 38, 14, 0, 2); - draw_text("Global Volume", 38, 21, 0, 2); - draw_text("Default Pan", 39, 28, 0, 2); - draw_text("Vibrato Speed", 38, 37, 0, 2); - draw_text("Vibrato Depth", 38, 44, 0, 2); - draw_text("Filename", 55, 13, 0, 2); - draw_text("Speed", 58, 14, 0, 2); - draw_text("Loop", 59, 15, 0, 2); - draw_text("LoopBeg", 56, 16, 0, 2); - draw_text("LoopEnd", 56, 17, 0, 2); - draw_text("SusLoop", 56, 18, 0, 2); - draw_text("SusLBeg", 56, 19, 0, 2); - draw_text("SusLEnd", 56, 20, 0, 2); - draw_text("Quality", 56, 22, 0, 2); - draw_text("Length", 57, 23, 0, 2); - draw_text("Vibrato Waveform", 58, 33, 0, 2); - draw_text("Vibrato Rate", 60, 44, 0, 2); + draw_box(36, 12, 53, 18, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(37, 15, 47, 17, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(36, 19, 53, 25, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(37, 22, 47, 24, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(36, 26, 53, 33, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(37, 29, 47, 32, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(36, 35, 53, 41, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(37, 38, 47, 40, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(36, 42, 53, 48, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(37, 45, 47, 47, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(54, 25, 77, 30, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(54, 31, 77, 41, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(54, 42, 77, 48, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(55, 45, 72, 47, BOX_THIN | BOX_INNER | BOX_INSET); + + draw_fill_chars(41, 30, 46, 30, 0); + draw_fill_chars(64, 13, 76, 23, 0); + + draw_text("Default Volume", 38, 14, 0, 2); + draw_text("Global Volume", 38, 21, 0, 2); + draw_text("Default Pan", 39, 28, 0, 2); + draw_text("Vibrato Speed", 38, 37, 0, 2); + draw_text("Vibrato Depth", 38, 44, 0, 2); + draw_text("Filename", 55, 13, 0, 2); + draw_text("Speed", 58, 14, 0, 2); + draw_text("Loop", 59, 15, 0, 2); + draw_text("LoopBeg", 56, 16, 0, 2); + draw_text("LoopEnd", 56, 17, 0, 2); + draw_text("SusLoop", 56, 18, 0, 2); + draw_text("SusLBeg", 56, 19, 0, 2); + draw_text("SusLEnd", 56, 20, 0, 2); + draw_text("Quality", 56, 22, 0, 2); + draw_text("Length", 57, 23, 0, 2); + draw_text("Vibrato Waveform", 58, 33, 0, 2); + draw_text("Vibrato Rate", 60, 44, 0, 2); - for (n = 0; n < 13; n++) - draw_char(154, 64 + n, 21, 3, 0); + for (n = 0; n < 13; n++) + draw_char(154, 64 + n, 21, 3, 0); } /* --------------------------------------------------------------------- */ @@ -1548,241 +1566,241 @@ /* callback for the loop menu toggles */ static void update_sample_loop_flags(void) { - song_sample_t *sample = song_get_sample(current_sample); + song_sample_t *sample = song_get_sample(current_sample); - /* these switch statements fall through */ - sample->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); - switch (widgets_samplelist[9].d.menutoggle.state) { - case 2: sample->flags |= CHN_PINGPONGLOOP; - case 1: sample->flags |= CHN_LOOP; - } - - switch (widgets_samplelist[12].d.menutoggle.state) { - case 2: sample->flags |= CHN_PINGPONGSUSTAIN; - case 1: sample->flags |= CHN_SUSTAINLOOP; - } - - if (sample->flags & CHN_LOOP) { - if (sample->loop_start == sample->length) - sample->loop_start = 0; - if (sample->loop_end <= sample->loop_start) - sample->loop_end = sample->length; - } - - if (sample->flags & CHN_SUSTAINLOOP) { - if (sample->sustain_start == sample->length) - sample->sustain_start = 0; - if (sample->sustain_end <= sample->sustain_start) - sample->sustain_end = sample->length; - } + /* these switch statements fall through */ + sample->flags &= ~(CHN_LOOP | CHN_PINGPONGLOOP | CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN); + switch (widgets_samplelist[9].d.menutoggle.state) { + case 2: sample->flags |= CHN_PINGPONGLOOP; + case 1: sample->flags |= CHN_LOOP; + } + + switch (widgets_samplelist[12].d.menutoggle.state) { + case 2: sample->flags |= CHN_PINGPONGSUSTAIN; + case 1: sample->flags |= CHN_SUSTAINLOOP; + } + + if (sample->flags & CHN_LOOP) { + if (sample->loop_start == sample->length) + sample->loop_start = 0; + if (sample->loop_end <= sample->loop_start) + sample->loop_end = sample->length; + } + + if (sample->flags & CHN_SUSTAINLOOP) { + if (sample->sustain_start == sample->length) + sample->sustain_start = 0; + if (sample->sustain_end <= sample->sustain_start) + sample->sustain_end = sample->length; + } - /* update any samples currently playing */ - song_update_playing_sample(current_sample); + /* update any samples currently playing */ + song_update_playing_sample(current_sample); - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } /* callback for the loop numentries */ static void update_sample_loop_points(void) { - song_sample_t *sample = song_get_sample(current_sample); - int flags_changed = 0; + song_sample_t *sample = song_get_sample(current_sample); + int flags_changed = 0; - /* 9 = loop toggle, 10 = loop start, 11 = loop end */ - if ((unsigned long) widgets_samplelist[10].d.numentry.value > sample->length - 1) - widgets_samplelist[10].d.numentry.value = sample->length - 1; - if (widgets_samplelist[11].d.numentry.value <= widgets_samplelist[10].d.numentry.value) { - widgets_samplelist[9].d.menutoggle.state = 0; - flags_changed = 1; - } else if ((unsigned long) widgets_samplelist[11].d.numentry.value > sample->length) { - widgets_samplelist[11].d.numentry.value = sample->length; - } - if (sample->loop_start != (unsigned long) widgets_samplelist[10].d.numentry.value - || sample->loop_end != (unsigned long) widgets_samplelist[11].d.numentry.value) { - flags_changed = 1; - } - sample->loop_start = widgets_samplelist[10].d.numentry.value; - sample->loop_end = widgets_samplelist[11].d.numentry.value; - - /* 12 = sus toggle, 13 = sus start, 14 = sus end */ - if ((unsigned long) widgets_samplelist[13].d.numentry.value > sample->length - 1) - widgets_samplelist[13].d.numentry.value = sample->length - 1; - if (widgets_samplelist[14].d.numentry.value <= widgets_samplelist[13].d.numentry.value) { - widgets_samplelist[12].d.menutoggle.state = 0; - flags_changed = 1; - } else if ((unsigned long) widgets_samplelist[14].d.numentry.value > sample->length) { - widgets_samplelist[14].d.numentry.value = sample->length; - } - if (sample->sustain_start != (unsigned long) widgets_samplelist[13].d.numentry.value - || sample->sustain_end != (unsigned long) widgets_samplelist[14].d.numentry.value) { - flags_changed = 1; - } - sample->sustain_start = widgets_samplelist[13].d.numentry.value; - sample->sustain_end = widgets_samplelist[14].d.numentry.value; - - if (flags_changed) { - update_sample_loop_flags(); - } + /* 9 = loop toggle, 10 = loop start, 11 = loop end */ + if ((unsigned long) widgets_samplelist[10].d.numentry.value > sample->length - 1) + widgets_samplelist[10].d.numentry.value = sample->length - 1; + if (widgets_samplelist[11].d.numentry.value <= widgets_samplelist[10].d.numentry.value) { + widgets_samplelist[9].d.menutoggle.state = 0; + flags_changed = 1; + } else if ((unsigned long) widgets_samplelist[11].d.numentry.value > sample->length) { + widgets_samplelist[11].d.numentry.value = sample->length; + } + if (sample->loop_start != (unsigned long) widgets_samplelist[10].d.numentry.value + || sample->loop_end != (unsigned long) widgets_samplelist[11].d.numentry.value) { + flags_changed = 1; + } + sample->loop_start = widgets_samplelist[10].d.numentry.value; + sample->loop_end = widgets_samplelist[11].d.numentry.value; + + /* 12 = sus toggle, 13 = sus start, 14 = sus end */ + if ((unsigned long) widgets_samplelist[13].d.numentry.value > sample->length - 1) + widgets_samplelist[13].d.numentry.value = sample->length - 1; + if (widgets_samplelist[14].d.numentry.value <= widgets_samplelist[13].d.numentry.value) { + widgets_samplelist[12].d.menutoggle.state = 0; + flags_changed = 1; + } else if ((unsigned long) widgets_samplelist[14].d.numentry.value > sample->length) { + widgets_samplelist[14].d.numentry.value = sample->length; + } + if (sample->sustain_start != (unsigned long) widgets_samplelist[13].d.numentry.value + || sample->sustain_end != (unsigned long) widgets_samplelist[14].d.numentry.value) { + flags_changed = 1; + } + sample->sustain_start = widgets_samplelist[13].d.numentry.value; + sample->sustain_end = widgets_samplelist[14].d.numentry.value; + + if (flags_changed) { + update_sample_loop_flags(); + } - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static void update_values_in_song(void) { - song_sample_t *sample = song_get_sample(current_sample); + song_sample_t *sample = song_get_sample(current_sample); - /* a few more modplug hacks here... */ - sample->volume = widgets_samplelist[1].d.thumbbar.value * 4; - sample->global_volume = widgets_samplelist[2].d.thumbbar.value; - - if (widgets_samplelist[3].d.toggle.state) - sample->flags |= CHN_PANNING; - else - sample->flags &= ~CHN_PANNING; - sample->vib_speed = widgets_samplelist[5].d.thumbbar.value; - sample->vib_depth = widgets_samplelist[6].d.thumbbar.value; - - if (widgets_samplelist[15].d.togglebutton.state) - sample->vib_type = VIB_SINE; - else if (widgets_samplelist[16].d.togglebutton.state) - sample->vib_type = VIB_RAMP_DOWN; - else if (widgets_samplelist[17].d.togglebutton.state) - sample->vib_type = VIB_SQUARE; - else - sample->vib_type = VIB_RANDOM; - sample->vib_rate = widgets_samplelist[19].d.thumbbar.value; + /* a few more modplug hacks here... */ + sample->volume = widgets_samplelist[1].d.thumbbar.value * 4; + sample->global_volume = widgets_samplelist[2].d.thumbbar.value; + + if (widgets_samplelist[3].d.toggle.state) + sample->flags |= CHN_PANNING; + else + sample->flags &= ~CHN_PANNING; + sample->vib_speed = widgets_samplelist[5].d.thumbbar.value; + sample->vib_depth = widgets_samplelist[6].d.thumbbar.value; + + if (widgets_samplelist[15].d.togglebutton.state) + sample->vib_type = VIB_SINE; + else if (widgets_samplelist[16].d.togglebutton.state) + sample->vib_type = VIB_RAMP_DOWN; + else if (widgets_samplelist[17].d.togglebutton.state) + sample->vib_type = VIB_SQUARE; + else + sample->vib_type = VIB_RANDOM; + sample->vib_rate = widgets_samplelist[19].d.thumbbar.value; - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } static void update_sample_speed(void) { - song_sample_t *sample = song_get_sample(current_sample); + song_sample_t *sample = song_get_sample(current_sample); - sample->c5speed = widgets_samplelist[8].d.numentry.value; + sample->c5speed = widgets_samplelist[8].d.numentry.value; - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } static void update_panning(void) { - song_sample_t *sample = song_get_sample(current_sample); + song_sample_t *sample = song_get_sample(current_sample); - sample->flags |= CHN_PANNING; - sample->panning = widgets_samplelist[4].d.thumbbar.value * 4; + sample->flags |= CHN_PANNING; + sample->panning = widgets_samplelist[4].d.thumbbar.value * 4; - widgets_samplelist[3].d.toggle.state = 1; + widgets_samplelist[3].d.toggle.state = 1; - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } static void update_filename(void) { - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ int sample_is_used_by_instrument(int samp) { - song_instrument_t *ins; - int i, j; - if (samp < 1) return 0; - for (i = 1; i <= MAX_INSTRUMENTS; i++) { - ins = song_get_instrument(i); - if (!ins) continue; - for (j = 0; j < 120; j++) { - if (ins->sample_map[j] == (unsigned int)samp) - return 1; - } - } - return 0; + song_instrument_t *ins; + int i, j; + if (samp < 1) return 0; + for (i = 1; i <= MAX_INSTRUMENTS; i++) { + ins = song_get_instrument(i); + if (!ins) continue; + for (j = 0; j < 120; j++) { + if (ins->sample_map[j] == (unsigned int)samp) + return 1; + } + } + return 0; } void sample_synchronize_to_instrument(void) { - song_instrument_t *ins; - int instnum = instrument_get_current(); - int pos, first; - - ins = song_get_instrument(instnum); - first = 0; - for (pos = 0; pos < 120; pos++) { - if (first == 0) first = ins->sample_map[pos]; - if (ins->sample_map[pos] == (unsigned int)instnum) { - sample_set(instnum); - return; - } - } - if (first > 0) { - sample_set(first); - } else { - sample_set(instnum); - } + song_instrument_t *ins; + int instnum = instrument_get_current(); + int pos, first; + + ins = song_get_instrument(instnum); + first = 0; + for (pos = 0; pos < 120; pos++) { + if (first == 0) first = ins->sample_map[pos]; + if (ins->sample_map[pos] == (unsigned int)instnum) { + sample_set(instnum); + return; + } + } + if (first > 0) { + sample_set(first); + } else { + sample_set(instnum); + } } void sample_list_load_page(struct page *page) { - vgamem_ovl_alloc(&sample_image); + vgamem_ovl_alloc(&sample_image); - page->title = "Sample List (F3)"; - page->draw_const = sample_list_draw_const; - page->predraw_hook = sample_list_predraw_hook; - page->handle_key = sample_list_handle_key; - page->set_page = sample_list_reposition; - page->total_widgets = 20; - page->widgets = widgets_samplelist; - page->help_index = HELP_SAMPLE_LIST; - - /* 0 = sample list */ - create_other(widgets_samplelist + 0, 1, sample_list_handle_key_on_list, sample_list_draw_list); - _fix_accept_text(); - - widgets_samplelist[0].x = 5; - widgets_samplelist[0].y = 13; - widgets_samplelist[0].width = 30; - widgets_samplelist[0].height = 35; - - /* 1 -> 6 = middle column */ - create_thumbbar(widgets_samplelist + 1, 38, 16, 9, 1, 2, 7, update_values_in_song, 0, 64); - create_thumbbar(widgets_samplelist + 2, 38, 23, 9, 1, 3, 7, update_values_in_song, 0, 64); - create_toggle(widgets_samplelist + 3, 38, 30, 2, 4, 0, 7, 7, update_values_in_song); - create_thumbbar(widgets_samplelist + 4, 38, 31, 9, 3, 5, 7, update_panning, 0, 64); - create_thumbbar(widgets_samplelist + 5, 38, 39, 9, 4, 6, 15, update_values_in_song, 0, 64); - create_thumbbar(widgets_samplelist + 6, 38, 46, 9, 5, 6, 19, update_values_in_song, 0, 32); - /* 7 -> 14 = top right box */ - create_textentry(widgets_samplelist + 7, 64, 13, 13, 7, 8, 0, update_filename, NULL, 12); - create_numentry(widgets_samplelist + 8, 64, 14, 7, 7, 9, 0, - update_sample_speed, 0, 9999999, &sample_numentry_cursor_pos); - create_menutoggle(widgets_samplelist + 9, 64, 15, 8, 10, 1, 0, 0, - update_sample_loop_flags, loop_states); - create_numentry(widgets_samplelist + 10, 64, 16, 7, 9, 11, 0, - update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); - create_numentry(widgets_samplelist + 11, 64, 17, 7, 10, 12, 0, - update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); - create_menutoggle(widgets_samplelist + 12, 64, 18, 11, 13, 1, 0, 0, - update_sample_loop_flags, loop_states); - create_numentry(widgets_samplelist + 13, 64, 19, 7, 12, 14, 0, - update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); - create_numentry(widgets_samplelist + 14, 64, 20, 7, 13, 15, 0, - update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); - /* 15 -> 18 = vibrato waveforms */ - create_togglebutton(widgets_samplelist + 15, 57, 36, 6, 14, 17, 5, - 16, 16, update_values_in_song, "\xb9\xba", 3, vibrato_waveforms); - create_togglebutton(widgets_samplelist + 16, 67, 36, 6, 14, 18, 15, - 0, 0, update_values_in_song, "\xbd\xbe", 3, vibrato_waveforms); - create_togglebutton(widgets_samplelist + 17, 57, 39, 6, 15, 19, 5, - 18, 18, update_values_in_song, "\xbb\xbc", 3, vibrato_waveforms); - create_togglebutton(widgets_samplelist + 18, 67, 39, 6, 16, 19, 17, - 0, 0, update_values_in_song, "Random", 1, vibrato_waveforms); - /* 19 = vibrato rate */ - create_thumbbar(widgets_samplelist + 19, 56, 46, 16, 17, 19, 0, update_values_in_song, 0, 255); - - /* count how many formats there really are */ - num_save_formats = 0; - while (sample_save_formats[num_save_formats].label) - num_save_formats++; + page->title = "Sample List (F3)"; + page->draw_const = sample_list_draw_const; + page->predraw_hook = sample_list_predraw_hook; + page->handle_key = sample_list_handle_key; + page->set_page = sample_list_reposition; + page->total_widgets = 20; + page->widgets = widgets_samplelist; + page->help_index = HELP_SAMPLE_LIST; + + /* 0 = sample list */ + create_other(widgets_samplelist + 0, 1, sample_list_handle_key_on_list, sample_list_draw_list); + _fix_accept_text(); + + widgets_samplelist[0].x = 5; + widgets_samplelist[0].y = 13; + widgets_samplelist[0].width = 30; + widgets_samplelist[0].height = 35; + + /* 1 -> 6 = middle column */ + create_thumbbar(widgets_samplelist + 1, 38, 16, 9, 1, 2, 7, update_values_in_song, 0, 64); + create_thumbbar(widgets_samplelist + 2, 38, 23, 9, 1, 3, 7, update_values_in_song, 0, 64); + create_toggle(widgets_samplelist + 3, 38, 30, 2, 4, 0, 7, 7, update_values_in_song); + create_thumbbar(widgets_samplelist + 4, 38, 31, 9, 3, 5, 7, update_panning, 0, 64); + create_thumbbar(widgets_samplelist + 5, 38, 39, 9, 4, 6, 15, update_values_in_song, 0, 64); + create_thumbbar(widgets_samplelist + 6, 38, 46, 9, 5, 6, 19, update_values_in_song, 0, 32); + /* 7 -> 14 = top right box */ + create_textentry(widgets_samplelist + 7, 64, 13, 13, 7, 8, 0, update_filename, NULL, 12); + create_numentry(widgets_samplelist + 8, 64, 14, 7, 7, 9, 0, + update_sample_speed, 0, 9999999, &sample_numentry_cursor_pos); + create_menutoggle(widgets_samplelist + 9, 64, 15, 8, 10, 1, 0, 0, + update_sample_loop_flags, loop_states); + create_numentry(widgets_samplelist + 10, 64, 16, 7, 9, 11, 0, + update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); + create_numentry(widgets_samplelist + 11, 64, 17, 7, 10, 12, 0, + update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); + create_menutoggle(widgets_samplelist + 12, 64, 18, 11, 13, 1, 0, 0, + update_sample_loop_flags, loop_states); + create_numentry(widgets_samplelist + 13, 64, 19, 7, 12, 14, 0, + update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); + create_numentry(widgets_samplelist + 14, 64, 20, 7, 13, 15, 0, + update_sample_loop_points, 0, 9999999, &sample_numentry_cursor_pos); + /* 15 -> 18 = vibrato waveforms */ + create_togglebutton(widgets_samplelist + 15, 57, 36, 6, 14, 17, 5, + 16, 16, update_values_in_song, "\xb9\xba", 3, vibrato_waveforms); + create_togglebutton(widgets_samplelist + 16, 67, 36, 6, 14, 18, 15, + 0, 0, update_values_in_song, "\xbd\xbe", 3, vibrato_waveforms); + create_togglebutton(widgets_samplelist + 17, 57, 39, 6, 15, 19, 5, + 18, 18, update_values_in_song, "\xbb\xbc", 3, vibrato_waveforms); + create_togglebutton(widgets_samplelist + 18, 67, 39, 6, 16, 19, 17, + 0, 0, update_values_in_song, "Random", 1, vibrato_waveforms); + /* 19 = vibrato rate */ + create_thumbbar(widgets_samplelist + 19, 56, 46, 16, 17, 19, 0, update_values_in_song, 0, 255); + + /* count how many formats there really are */ + num_save_formats = 0; + while (sample_save_formats[num_save_formats].label) + num_save_formats++; } diff -Nru schism-0+20110101/schism/page_vars.c schism-20160521/schism/page_vars.c --- schism-0+20110101/schism/page_vars.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_vars.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -42,120 +42,129 @@ static void update_song_title(void) { - status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; + status.flags |= NEED_UPDATE | SONG_NEEDS_SAVE; } /* --------------------------------------------------------------------- */ static void song_vars_draw_const(void) { - int n; + int n; - draw_box(16, 15, 43, 17, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(16, 18, 50, 21, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(16, 22, 34, 28, BOX_THIN | BOX_INNER | BOX_INSET); - draw_box(12, 41, 78, 45, BOX_THICK | BOX_INNER | BOX_INSET); - - draw_fill_chars(20, 26, 33, 27, 0); - - draw_text("Song Variables", 33, 13, 3, 2); - draw_text("Song Name", 7, 16, 0, 2); - draw_text("Initial Tempo", 3, 19, 0, 2); - draw_text("Initial Speed", 3, 20, 0, 2); - draw_text("Global Volume", 3, 23, 0, 2); - draw_text("Mixing Volume", 3, 24, 0, 2); - draw_text("Separation", 6, 25, 0, 2); - draw_text("Old Effects", 5, 26, 0, 2); - draw_text("Compatible Gxx", 2, 27, 0, 2); - draw_text("Control", 9, 30, 0, 2); - draw_text("Playback", 8, 33, 0, 2); - draw_text("Pitch Slides", 4, 36, 0, 2); - draw_text("Directories", 34, 40, 3, 2); - draw_text("Module", 6, 42, 0, 2); - draw_text("Sample", 6, 43, 0, 2); - draw_text("Instrument", 2, 44, 0, 2); - - for (n = 1; n < 79; n++) - draw_char(129, n, 39, 1, 2); + draw_box(16, 15, 43, 17, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(16, 18, 50, 21, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(16, 22, 34, 28, BOX_THIN | BOX_INNER | BOX_INSET); + draw_box(12, 41, 78, 45, BOX_THICK | BOX_INNER | BOX_INSET); + + draw_fill_chars(20, 26, 33, 27, 0); + + draw_text("Song Variables", 33, 13, 3, 2); + draw_text("Song Name", 7, 16, 0, 2); + draw_text("Initial Tempo", 3, 19, 0, 2); + draw_text("Initial Speed", 3, 20, 0, 2); + draw_text("Global Volume", 3, 23, 0, 2); + draw_text("Mixing Volume", 3, 24, 0, 2); + draw_text("Separation", 6, 25, 0, 2); + draw_text("Old Effects", 5, 26, 0, 2); + draw_text("Compatible Gxx", 2, 27, 0, 2); + draw_text("Control", 9, 30, 0, 2); + draw_text("Playback", 8, 33, 0, 2); + draw_text("Pitch Slides", 4, 36, 0, 2); + draw_text("Directories", 34, 40, 3, 2); + draw_text("Module", 6, 42, 0, 2); + draw_text("Sample", 6, 43, 0, 2); + draw_text("Instrument", 2, 44, 0, 2); + + for (n = 1; n < 79; n++) + draw_char(129, n, 39, 1, 2); } /* --------------------------------------------------------------------- */ +void song_vars_sync_stereo(void) +{ + // copy from the song to the page + if (song_is_stereo()) + togglebutton_set(widgets_vars, 10, 0); + else + togglebutton_set(widgets_vars, 11, 0); +} + static void update_values_in_song(void) { - song_set_initial_tempo(widgets_vars[1].d.thumbbar.value); - song_set_initial_speed(widgets_vars[2].d.thumbbar.value); - song_set_initial_global_volume(widgets_vars[3].d.thumbbar.value); - song_set_mixing_volume(widgets_vars[4].d.thumbbar.value); - song_set_separation(widgets_vars[5].d.thumbbar.value); - song_set_old_effects(widgets_vars[6].d.toggle.state); - song_set_compatible_gxx(widgets_vars[7].d.toggle.state); - song_set_instrument_mode(widgets_vars[8].d.togglebutton.state); - if (widgets_vars[10].d.togglebutton.state) { - if (!song_is_stereo()) { - song_set_stereo(); - } - } else { - if (song_is_stereo()) { - song_set_mono(); - } - } - song_set_linear_pitch_slides(widgets_vars[12].d.togglebutton.state); - status.flags |= SONG_NEEDS_SAVE; + song_set_initial_tempo(widgets_vars[1].d.thumbbar.value); + song_set_initial_speed(widgets_vars[2].d.thumbbar.value); + song_set_initial_global_volume(widgets_vars[3].d.thumbbar.value); + song_set_mixing_volume(widgets_vars[4].d.thumbbar.value); + song_set_separation(widgets_vars[5].d.thumbbar.value); + song_set_old_effects(widgets_vars[6].d.toggle.state); + song_set_compatible_gxx(widgets_vars[7].d.toggle.state); + song_set_instrument_mode(widgets_vars[8].d.togglebutton.state); + if (widgets_vars[10].d.togglebutton.state) { + if (!song_is_stereo()) { + song_set_stereo(); + } + } else { + if (song_is_stereo()) { + song_set_mono(); + } + } + song_set_linear_pitch_slides(widgets_vars[12].d.togglebutton.state); + status.flags |= SONG_NEEDS_SAVE; } static void init_instruments(UNUSED void *data) { - song_init_instruments(-1); + song_init_instruments(-1); } static void maybe_init_instruments(void) { - /* XXX actually, in IT the buttons on this dialog say OK/No for whatever reason */ - song_set_instrument_mode(1); - dialog_create(DIALOG_YES_NO, "Initialise instruments?", init_instruments, NULL, 0, NULL); + /* XXX actually, in IT the buttons on this dialog say OK/No for whatever reason */ + song_set_instrument_mode(1); + dialog_create(DIALOG_YES_NO, "Initialise instruments?", init_instruments, NULL, 0, NULL); - status.flags |= SONG_NEEDS_SAVE; + status.flags |= SONG_NEEDS_SAVE; } static void song_changed_cb(void) { - char *b; - int c; + char *b; + int c; - widgets_vars[0].d.textentry.text = current_song->title; - widgets_vars[0].d.textentry.cursor_pos = strlen(widgets_vars[0].d.textentry.text); + widgets_vars[0].d.textentry.text = current_song->title; + widgets_vars[0].d.textentry.cursor_pos = strlen(widgets_vars[0].d.textentry.text); - widgets_vars[1].d.thumbbar.value = current_song->initial_tempo; - widgets_vars[2].d.thumbbar.value = current_song->initial_speed; - widgets_vars[3].d.thumbbar.value = current_song->initial_global_volume; - widgets_vars[4].d.thumbbar.value = current_song->mixing_volume; - widgets_vars[5].d.thumbbar.value = current_song->pan_separation; - widgets_vars[6].d.toggle.state = song_has_old_effects(); - widgets_vars[7].d.toggle.state = song_has_compatible_gxx(); - - if (song_is_instrument_mode()) - togglebutton_set(widgets_vars, 8, 0); - else - togglebutton_set(widgets_vars, 9, 0); - - if (song_is_stereo()) - togglebutton_set(widgets_vars, 10, 0); - else - togglebutton_set(widgets_vars, 11, 0); - - if (song_has_linear_pitch_slides()) - togglebutton_set(widgets_vars, 12, 0); - else - togglebutton_set(widgets_vars, 13, 0); - - for (b = strpbrk(song_get_basename(), "Aa"), - c = 12632; c && b && b[1]; c >>= 4, b++) - if ((c & 15) != b[1] - *b) return; - if (!c) for (b = Amiga, c = 12632; c; c>>= 4, b++) - b[1] = *b + (c & 15); + widgets_vars[1].d.thumbbar.value = current_song->initial_tempo; + widgets_vars[2].d.thumbbar.value = current_song->initial_speed; + widgets_vars[3].d.thumbbar.value = current_song->initial_global_volume; + widgets_vars[4].d.thumbbar.value = current_song->mixing_volume; + widgets_vars[5].d.thumbbar.value = current_song->pan_separation; + widgets_vars[6].d.toggle.state = song_has_old_effects(); + widgets_vars[7].d.toggle.state = song_has_compatible_gxx(); + + if (song_is_instrument_mode()) + togglebutton_set(widgets_vars, 8, 0); + else + togglebutton_set(widgets_vars, 9, 0); + + if (song_is_stereo()) + togglebutton_set(widgets_vars, 10, 0); + else + togglebutton_set(widgets_vars, 11, 0); + + if (song_has_linear_pitch_slides()) + togglebutton_set(widgets_vars, 12, 0); + else + togglebutton_set(widgets_vars, 13, 0); + + for (b = strpbrk(song_get_basename(), "Aa"), + c = 12632; c && b && b[1]; c >>= 4, b++) + if ((c & 15) != b[1] - *b) return; + if (!c) for (b = Amiga, c = 12632; c; c>>= 4, b++) + b[1] = *b + (c & 15); } /* --------------------------------------------------------------------- */ @@ -163,67 +172,67 @@ static void dir_modules_changed(void) { - status.flags |= DIR_MODULES_CHANGED; + status.flags |= DIR_MODULES_CHANGED; } static void dir_samples_changed(void) { - status.flags |= DIR_SAMPLES_CHANGED; + status.flags |= DIR_SAMPLES_CHANGED; } static void dir_instruments_changed(void) { - status.flags |= DIR_INSTRUMENTS_CHANGED; + status.flags |= DIR_INSTRUMENTS_CHANGED; } /* --------------------------------------------------------------------- */ void song_vars_load_page(struct page *page) { - page->title = "Song Variables & Directory Configuration (F12)"; - page->draw_const = song_vars_draw_const; - page->song_changed_cb = song_changed_cb; - page->total_widgets = 18; - page->widgets = widgets_vars; - page->help_index = HELP_GLOBAL; - - /* 0 = song name */ - create_textentry(widgets_vars, 17, 16, 26, 0, 1, 1, update_song_title, current_song->title, 25); - /* 1 = tempo */ - create_thumbbar(widgets_vars + 1, 17, 19, 33, 0, 2, 2, update_values_in_song, 31, 255); - /* 2 = speed */ - create_thumbbar(widgets_vars + 2, 17, 20, 33, 1, 3, 3, update_values_in_song, 1, 255); - /* 3 = global volume */ - create_thumbbar(widgets_vars + 3, 17, 23, 17, 2, 4, 4, update_values_in_song, 0, 128); - /* 4 = mixing volume */ - create_thumbbar(widgets_vars + 4, 17, 24, 17, 3, 5, 5, update_values_in_song, 0, 128); - /* 5 = separation */ - create_thumbbar(widgets_vars + 5, 17, 25, 17, 4, 6, 6, update_values_in_song, 0, 128); - /* 6 = old effects */ - create_toggle(widgets_vars + 6, 17, 26, 5, 7, 5, 7, 7, update_values_in_song); - /* 7 = compatible gxx */ - create_toggle(widgets_vars + 7, 17, 27, 6, 8, 6, 8, 8, update_values_in_song); - /* 8-13 = switches */ - create_togglebutton(widgets_vars + 8, 17, 30, 11, 7, 10, 9, 9, 9, maybe_init_instruments, - "Instruments", 1, group_control); - create_togglebutton(widgets_vars + 9, 32, 30, 11, 7, 11, 8, 8, 8, update_values_in_song, - "Samples", 1, group_control); - create_togglebutton(widgets_vars + 10, 17, 33, 11, 8, 12, 11, 11, 11, update_values_in_song, - "Stereo", 1, group_playback); - create_togglebutton(widgets_vars + 11, 32, 33, 11, 9, 13, 10, 10, 10, update_values_in_song, - "Mono", 1, group_playback); - create_togglebutton(widgets_vars + 12, 17, 36, 11, 10, 14, 13, 13, 13, update_values_in_song, - "Linear", 1, group_slides); - create_togglebutton(widgets_vars + 13, 32, 36, 11, 11, 14, 12, 12, 12, update_values_in_song, - Amiga, 1, group_slides); - /* 14-16 = directories */ - create_textentry(widgets_vars + 14, 13, 42, 65, 12, 15, 15, dir_modules_changed, - cfg_dir_modules, PATH_MAX); - create_textentry(widgets_vars + 15, 13, 43, 65, 14, 16, 16, dir_samples_changed, - cfg_dir_samples, PATH_MAX); - create_textentry(widgets_vars + 16, 13, 44, 65, 15, 17, 17, dir_instruments_changed, - cfg_dir_instruments, PATH_MAX); - /* 17 = save all preferences */ - create_button(widgets_vars + 17, 28, 47, 22, 16, 17, 17, 17, 17, cfg_save, "Save all Preferences", 2); + page->title = "Song Variables & Directory Configuration (F12)"; + page->draw_const = song_vars_draw_const; + page->song_changed_cb = song_changed_cb; + page->total_widgets = 18; + page->widgets = widgets_vars; + page->help_index = HELP_GLOBAL; + + /* 0 = song name */ + create_textentry(widgets_vars, 17, 16, 26, 0, 1, 1, update_song_title, current_song->title, 25); + /* 1 = tempo */ + create_thumbbar(widgets_vars + 1, 17, 19, 33, 0, 2, 2, update_values_in_song, 31, 255); + /* 2 = speed */ + create_thumbbar(widgets_vars + 2, 17, 20, 33, 1, 3, 3, update_values_in_song, 1, 255); + /* 3 = global volume */ + create_thumbbar(widgets_vars + 3, 17, 23, 17, 2, 4, 4, update_values_in_song, 0, 128); + /* 4 = mixing volume */ + create_thumbbar(widgets_vars + 4, 17, 24, 17, 3, 5, 5, update_values_in_song, 0, 128); + /* 5 = separation */ + create_thumbbar(widgets_vars + 5, 17, 25, 17, 4, 6, 6, update_values_in_song, 0, 128); + /* 6 = old effects */ + create_toggle(widgets_vars + 6, 17, 26, 5, 7, 5, 7, 7, update_values_in_song); + /* 7 = compatible gxx */ + create_toggle(widgets_vars + 7, 17, 27, 6, 8, 6, 8, 8, update_values_in_song); + /* 8-13 = switches */ + create_togglebutton(widgets_vars + 8, 17, 30, 11, 7, 10, 9, 9, 9, maybe_init_instruments, + "Instruments", 1, group_control); + create_togglebutton(widgets_vars + 9, 32, 30, 11, 7, 11, 8, 8, 8, update_values_in_song, + "Samples", 1, group_control); + create_togglebutton(widgets_vars + 10, 17, 33, 11, 8, 12, 11, 11, 11, update_values_in_song, + "Stereo", 1, group_playback); + create_togglebutton(widgets_vars + 11, 32, 33, 11, 9, 13, 10, 10, 10, update_values_in_song, + "Mono", 1, group_playback); + create_togglebutton(widgets_vars + 12, 17, 36, 11, 10, 14, 13, 13, 13, update_values_in_song, + "Linear", 1, group_slides); + create_togglebutton(widgets_vars + 13, 32, 36, 11, 11, 14, 12, 12, 12, update_values_in_song, + Amiga, 1, group_slides); + /* 14-16 = directories */ + create_textentry(widgets_vars + 14, 13, 42, 65, 12, 15, 15, dir_modules_changed, + cfg_dir_modules, PATH_MAX); + create_textentry(widgets_vars + 15, 13, 43, 65, 14, 16, 16, dir_samples_changed, + cfg_dir_samples, PATH_MAX); + create_textentry(widgets_vars + 16, 13, 44, 65, 15, 17, 17, dir_instruments_changed, + cfg_dir_instruments, PATH_MAX); + /* 17 = save all preferences */ + create_button(widgets_vars + 17, 28, 47, 22, 16, 17, 17, 17, 17, cfg_save, "Save all Preferences", 2); } diff -Nru schism-0+20110101/schism/page_waterfall.c schism-20160521/schism/page_waterfall.c --- schism-0+20110101/schism/page_waterfall.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/page_waterfall.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,13 +34,19 @@ /* consts */ -#define FFT_BUFFER_SIZE_LOG 9 -#define FFT_BUFFER_SIZE 512 /*(1 << FFT_BUFFER_SIZE_LOG)*/ -#define FFT_OUTPUT_SIZE 256 /* FFT_BUFFER_SIZE/2 */ +#define FFT_BUFFER_SIZE_LOG 11 +#define FFT_BUFFER_SIZE 2048 /*(1 << FFT_BUFFER_SIZE_LOG)*/ +#define FFT_OUTPUT_SIZE 1024 /* FFT_BUFFER_SIZE/2 */ /*WARNING: Hardcoded in page.c when declaring current_fft_data*/ +#define FFT_BANDS_SIZE 256 /*WARNING: Hardcoded in page.c when declaring fftlog and when using it in vis_fft*/ #define PI ((double)3.14159265358979323846) +/*This value is used internally to scale the power output of the FFT to decibells.*/ +static const float fft_inv_bufsize = 1.0f/(FFT_BUFFER_SIZE>>2); +/*Scaling for FFT. Input is expected to be signed short int.*/ +static const float inv_s_range = 1.f/32768.f; short current_fft_data[2][FFT_OUTPUT_SIZE]; - +/*Table to change the scale from linear to log.*/ +short fftlog[FFT_BANDS_SIZE]; void vis_init(void); void vis_work_16s(short *in, int inlen); @@ -50,13 +56,16 @@ /* variables :) */ static int mono = 0; -static int gain = -5; +//gain, in dBs. +//static int gain = 0; +static int noisefloor=72; /* get the _whole_ display */ static struct vgamem_overlay ovl = { 0, 0, 79, 49, NULL, 0, 0, 0 }; /* tables */ static unsigned int bit_reverse[FFT_BUFFER_SIZE]; +static float window[FFT_BUFFER_SIZE]; static float precos[FFT_OUTPUT_SIZE]; static float presin[FFT_OUTPUT_SIZE]; @@ -64,409 +73,474 @@ static float state_real[FFT_BUFFER_SIZE]; static float state_imag[FFT_BUFFER_SIZE]; + static int _reverse_bits(unsigned int in) { - unsigned int r = 0, n; - for (n = 0; n < FFT_BUFFER_SIZE_LOG; n++) { - r <<= 1; - r += (in & 1); - in >>= 1; - } - return r; + unsigned int r = 0, n; + for (n = 0; n < FFT_BUFFER_SIZE_LOG; n++) { + r <<= 1; + r += (in & 1); + in >>= 1; + } + return r; } void vis_init(void) { - unsigned n; - - for (n = 0; n < FFT_BUFFER_SIZE; n++) { - bit_reverse[n] = _reverse_bits(n); - } - for (n = 0; n < FFT_OUTPUT_SIZE; n++) { - float j = (2.0*PI) * n / FFT_BUFFER_SIZE; - precos[n] = cos(j); - presin[n] = sin(j); - } -} + unsigned n; -/* samples should already be averaged */ + for (n = 0; n < FFT_BUFFER_SIZE; n++) { + bit_reverse[n] = _reverse_bits(n); +#if 0 + /*Rectangular/none*/ + window[n] = 1; + /*Cosine/sine window*/ + window[n] = sin(PI * n/ FFT_BUFFER_SIZE -1); + /*Hann Window*/ + window[n] = 0.50f - 0.50f * cos(2.0*PI * n / (FFT_BUFFER_SIZE - 1)); + /*Hamming Window*/ + window[n] = 0.54f - 0.46f * cos(2.0*PI * n / (FFT_BUFFER_SIZE - 1)); + /*Gaussian*/ + window[n] = powf(M_E,-0.5f *pow((n-(FFT_BUFFER_SIZE-1)/2.f)/(0.4*(FFT_BUFFER_SIZE-1)/2.f),2.f)); + /*Blackmann*/ + window[n] = 0.42659 - 0.49656 * cos(2.0*PI * n/ (FFT_BUFFER_SIZE-1)) + 0.076849 * cos(4.0*PI * n /(FFT_BUFFER_SIZE-1)); + /*Blackman-Harris*/ + window[n] = 0.35875 - 0.48829 * cos(2.0*PI * n/ (FFT_BUFFER_SIZE-1)) + 0.14128 * cos(4.0*PI * n /(FFT_BUFFER_SIZE-1)) - 0.01168 * cos(6.0*PI * n /(FFT_BUFFER_SIZE-1)); +#endif + /*Hann Window*/ + window[n] = 0.50f - 0.50f * cos(2.0*PI * n / (FFT_BUFFER_SIZE - 1)); + } + for (n = 0; n < FFT_OUTPUT_SIZE; n++) { + float j = (2.0*PI) * n / FFT_BUFFER_SIZE; + precos[n] = cos(j); + presin[n] = sin(j); + } +#if 0 + /*linear*/ + fftlog[n]=n; +#elif 1 + /*exponential.*/ + float factor = (float)FFT_OUTPUT_SIZE/(FFT_BANDS_SIZE*FFT_BANDS_SIZE); + for (n = 0; n < FFT_BANDS_SIZE; n++ ) { + fftlog[n]=n*n*factor; + } +#else + /*constant note scale.*/ + float factor = 8.f/(float)FFT_BANDS_SIZE; + float factor2 = (float)FFT_OUTPUT_SIZE/256.f; + for (n = 0; n < FFT_BANDS_SIZE; n++ ) { + fftlog[n]=(powf(2.0f,n*factor)-1.f)*factor2; + } +#endif +} + +/* +* Understanding In and Out: +* input is the samples (so, it is amplitude). The scale is expected to be signed 16bits. +* The window function calculated in "window" will automatically be applied. +* output is a value between 0 and 128 representing 0 = noisefloor variable +* and 128 = 0dBFS (deciBell, FullScale) for each band. +*/ static inline void _vis_data_work(short output[FFT_OUTPUT_SIZE], - short input[FFT_BUFFER_SIZE]) + short input[FFT_BUFFER_SIZE]) { - unsigned int n, k, y; - unsigned int ex, ff; - float fr, fi; - float tr, ti; - float out; - int yp; - - /* fft */ - float *rp = state_real; - float *ip = state_imag; - for (n = 0; n < FFT_BUFFER_SIZE; n++) { - *rp++ = input[ bit_reverse[n] ]; - *ip++ = 0; - } - ex = 1; - ff = FFT_OUTPUT_SIZE; - for (n = FFT_BUFFER_SIZE_LOG; n != 0; n--) { - for (k = 0; k != ex; k++) { - fr = precos[k * ff]; - fi = presin[k * ff]; - for (y = k; y < FFT_BUFFER_SIZE; y += ex << 1) { - yp = y + ex; - tr = fr * state_real[yp] - fi * state_imag[yp]; - ti = fr * state_imag[yp] + fi * state_real[yp]; - state_real[yp] = state_real[y] - tr; - state_imag[yp] = state_imag[y] - ti; - state_real[y] += tr; - state_imag[y] += ti; - } - } - ex <<= 1; - ff >>= 1; - } - - /* collect fft */ - rp = state_real; rp++; - ip = state_imag; ip++; - for (n = 0; n < FFT_OUTPUT_SIZE; n++) { - out = ((*rp) * (*rp)) + ((*ip) * (*ip)); - output[n] = ((int)sqrt(out)); - rp++;ip++; - } - - /* scale these back a bit */ - output[0] /= 4; - output[(FFT_OUTPUT_SIZE-1)] /= 4; + unsigned int n, k, y; + unsigned int ex, ff; + float fr, fi; + float tr, ti; + float out; + int yp; + + /* fft */ + float *rp = state_real; + float *ip = state_imag; + for (n = 0; n < FFT_BUFFER_SIZE; n++) { + int nr = bit_reverse[n]; + *rp++ = (float)input[ nr ] * inv_s_range * window[nr]; + *ip++ = 0; + } + ex = 1; + ff = FFT_OUTPUT_SIZE; + for (n = FFT_BUFFER_SIZE_LOG; n != 0; n--) { + for (k = 0; k != ex; k++) { + fr = precos[k * ff]; + fi = presin[k * ff]; + for (y = k; y < FFT_BUFFER_SIZE; y += ex << 1) { + yp = y + ex; + tr = fr * state_real[yp] - fi * state_imag[yp]; + ti = fr * state_imag[yp] + fi * state_real[yp]; + state_real[yp] = state_real[y] - tr; + state_imag[yp] = state_imag[y] - ti; + state_real[y] += tr; + state_imag[y] += ti; + } + } + ex <<= 1; + ff >>= 1; + } + + /* collect fft */ + rp = state_real; rp++; + ip = state_imag; ip++; + const float fft_dbinv_bufsize = dB(fft_inv_bufsize); + for (n = 0; n < FFT_OUTPUT_SIZE; n++) { + /* "out" is the total power for each band. + * To get amplitude from "output", use sqrt(out[N])/(sizeBuf>>2) + * To get dB from "output", use powerdB(out[N])+db(1/(sizeBuf>>2)). + * powerdB is = 10 * log10(in) + * dB is = 20 * log10(in) + */ + out = ((*rp) * (*rp)) + ((*ip) * (*ip)); + /* +0.0000000001f is -100dB of power. Used to prevent evaluating powerdB(0.0) */ + output[n] = pdB_s(noisefloor, out+0.0000000001f,fft_dbinv_bufsize); + rp++;ip++; + } +} +/* convert the fft bands to columns of screen +out and d have a range of 0 to 128 */ +static inline void _get_columns_from_fft(unsigned char *out, + short d[FFT_OUTPUT_SIZE], int m) +{ + int i, j, a; + for (i = 0, a=0; i < FFT_BANDS_SIZE; i++) { + float afloat = fftlog[i]; + float floora = floor(afloat); + if (afloat + 1.0f > fftlog[i+1]) { + a = (int)floora; + j = d[a] + (d[a+1]-d[a])*(afloat-floora); + a = floor(afloat+0.5f); + } + else { + j=d[a]; + while(a<=afloat){ + j = MAX(j,d[a]); + a++; + } + } + *out = j; out++; + /*If mono, repeat the value.*/ + if (m) { *out = j; out++; } + if ((i % FUDGE_256_TO_WIDTH) == 0) { + /* each band is 2.50 px wide; + * output display is 640 px + */ + *out = j; out++; + /*If mono, repeat the value.*/ + if (m) { *out = j; out++; } + } + } } + +/* Convert the output of */ static inline unsigned char *_dobits(unsigned char *q, - short d[FFT_OUTPUT_SIZE], int m, int y) + unsigned char *in, int length, int y) { - int i, j, c; - - for (i = 0; i < FFT_OUTPUT_SIZE; i++) { - /* eh... */ - j = d[i]; - if (gain < 0) - j >>= -gain; - else - j <<= gain; - - c = 128 + j; - if (c > 255) c = 255; - *q = c; q += y; - if (m) { *q = c; q += y; } - if ((i % FUDGE_256_TO_WIDTH) == 0) { - /* each band is 2.50 px wide; - * output display is 640 px - */ - *q = c; q += y; - if (m) { *q = c; q += y; } - } - } - return q; + int i, c; + for (i = 0; i < length; i++) { + /* j is has range 0 to 128. Now use the upper side for drawing.*/ + c = 128 + in[i]; + if (c > 255) c = 255; + *q = c; q += y; + } + return q; } +/*x = screen.x, h = 0..128, c = colour */ static inline void _drawslice(int x, int h, int c) { - int y; + int y; - y = ((h>>10) & (SCOPE_ROWS-1))+1; - vgamem_ovl_drawline(&ovl, - x, (NATIVE_SCREEN_HEIGHT-y), - x, (NATIVE_SCREEN_HEIGHT-1), c); + y = ((h>>2) & (SCOPE_ROWS-1))+1; + vgamem_ovl_drawline(&ovl, + x, (NATIVE_SCREEN_HEIGHT-y), + x, (NATIVE_SCREEN_HEIGHT-1), c); } static void _vis_process(void) { - unsigned char *q; - int i, j, k; - - vgamem_lock(); - - /* move up by one pixel */ - memmove(ovl.q, ovl.q+NATIVE_SCREEN_WIDTH, - (NATIVE_SCREEN_WIDTH* - ((NATIVE_SCREEN_HEIGHT-1)-SCOPE_ROWS))); - q = ovl.q + (NATIVE_SCREEN_WIDTH* - ((NATIVE_SCREEN_HEIGHT-1)-SCOPE_ROWS)); - - if (mono) { - for (i = 0; i < FFT_OUTPUT_SIZE; i++) - current_fft_data[0][i] = (current_fft_data[0][i] - + current_fft_data[1][i]) / 2; - _dobits(q, current_fft_data[0], 1, 1); - } else { - _dobits(q+320, current_fft_data[0], 0, -1); - _dobits(q+320, current_fft_data[1], 0, 1); - } - - /* draw the scope at the bottom */ - q = ovl.q + (NATIVE_SCREEN_WIDTH*(NATIVE_SCREEN_HEIGHT-SCOPE_ROWS)); - i = SCOPE_ROWS*NATIVE_SCREEN_WIDTH; - memset(q,0,i); - if (mono) { - for (i = j = 0; i < FFT_OUTPUT_SIZE; i++) { - _drawslice(j, current_fft_data[0][i],5); - j++; - if ((i % FUDGE_256_TO_WIDTH) == 0) { - _drawslice(j, current_fft_data[0][i],5); - j++; - _drawslice(j, current_fft_data[1][i],5); - j++; - } - _drawslice(j, current_fft_data[1][i],5); - j++; - } - } else { - j = 0; - k = NATIVE_SCREEN_WIDTH/2; - for (i = 0; i < FFT_OUTPUT_SIZE; i++) { - _drawslice(k-j, current_fft_data[0][i],5); - _drawslice(k+j, current_fft_data[1][i],5); - j++; - if ((i % FUDGE_256_TO_WIDTH) == 0) { - _drawslice(k-j, current_fft_data[0][i],5); - _drawslice(k+j, current_fft_data[1][i],5); - j++; - _drawslice(k-j, current_fft_data[0][i],5); - _drawslice(k+j, current_fft_data[1][i],5); - j++; - } - _drawslice(k-j, current_fft_data[0][i],5); - _drawslice(k+j, current_fft_data[1][i],5); - j++; - } - } + unsigned char *q; + int i, k; + k = NATIVE_SCREEN_WIDTH/2; + unsigned char outfft[NATIVE_SCREEN_WIDTH]; + + vgamem_lock(); + + /* move up by one pixel */ + memmove(ovl.q, ovl.q+NATIVE_SCREEN_WIDTH, + (NATIVE_SCREEN_WIDTH* + ((NATIVE_SCREEN_HEIGHT-1)-SCOPE_ROWS))); + q = ovl.q + (NATIVE_SCREEN_WIDTH* + ((NATIVE_SCREEN_HEIGHT-1)-SCOPE_ROWS)); + + if (mono) { + for (i = 0; i < FFT_OUTPUT_SIZE; i++) + current_fft_data[0][i] = (current_fft_data[0][i] + + current_fft_data[1][i]) / 2; + _get_columns_from_fft(outfft, current_fft_data[0], 1); + _dobits(q, outfft, NATIVE_SCREEN_WIDTH, 1); + } else { + _get_columns_from_fft(outfft, current_fft_data[0], 0); + _dobits(q+k, outfft, k, -1); + _get_columns_from_fft(outfft+k, current_fft_data[1], 0); + _dobits(q+k, outfft+k, k, 1); + } + + /* draw the scope at the bottom */ + q = ovl.q + (NATIVE_SCREEN_WIDTH*(NATIVE_SCREEN_HEIGHT-SCOPE_ROWS)); + i = SCOPE_ROWS*NATIVE_SCREEN_WIDTH; + memset(q,0,i); + if (mono) { + for (i = 0; i < NATIVE_SCREEN_WIDTH; i++) { + _drawslice(i, outfft[i],5); + } + } else { + for (i = 0; i < k; i++) { + _drawslice(k-i-1, outfft[i],5); + } + for (i = 0; i < k; i++) { + _drawslice(k+i, outfft[k+i],5); + } + } - vgamem_unlock(); - status.flags |= NEED_UPDATE; + vgamem_unlock(); + status.flags |= NEED_UPDATE; } void vis_work_16s(short *in, int inlen) { - short dl[FFT_BUFFER_SIZE]; - short dr[FFT_BUFFER_SIZE]; - int i, j, k; - - if (!inlen) { - memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); - memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); - } else { - for (i = 0; i < FFT_BUFFER_SIZE;) { - for (k = j = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { - dl[i] = in[j]; j++; - dr[i] = in[j]; j++; - } - } - _vis_data_work(current_fft_data[0], dl); - _vis_data_work(current_fft_data[1], dr); - } - if (status.current_page == PAGE_WATERFALL) _vis_process(); + short dl[FFT_BUFFER_SIZE]; + short dr[FFT_BUFFER_SIZE]; + int i, j, k; + + if (!inlen) { + memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); + memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); + } else { + for (i = 0; i < FFT_BUFFER_SIZE;) { + for (k = j = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { + dl[i] = in[j]; j++; + dr[i] = in[j]; j++; + } + } + _vis_data_work(current_fft_data[0], dl); + _vis_data_work(current_fft_data[1], dr); + } + if (status.current_page == PAGE_WATERFALL) _vis_process(); } void vis_work_16m(short *in, int inlen) { - short d[FFT_BUFFER_SIZE]; - int i, k; + short d[FFT_BUFFER_SIZE]; + int i, k; - if (!inlen) { - memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); - memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); - } else { - for (i = 0; i < FFT_BUFFER_SIZE;) { - for (k = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { - d[i] = in[k]; - } - } - _vis_data_work(current_fft_data[0], d); - memcpy(current_fft_data[1], current_fft_data[0], FFT_OUTPUT_SIZE * 2); - } - if (status.current_page == PAGE_WATERFALL) _vis_process(); + if (!inlen) { + memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); + memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); + } else { + for (i = 0; i < FFT_BUFFER_SIZE;) { + for (k = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { + d[i] = in[k]; + } + } + _vis_data_work(current_fft_data[0], d); + memcpy(current_fft_data[1], current_fft_data[0], FFT_OUTPUT_SIZE * 2); + } + if (status.current_page == PAGE_WATERFALL) _vis_process(); } void vis_work_8s(char *in, int inlen) { - short dl[FFT_BUFFER_SIZE]; - short dr[FFT_BUFFER_SIZE]; - int i, j, k; - - if (!inlen) { - memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); - memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); - } else { - for (i = 0; i < FFT_BUFFER_SIZE;) { - for (k = j = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { - dl[i] = ((short)in[j]) * 256; j++; - dr[i] = ((short)in[j]) * 256; j++; - } - } - _vis_data_work(current_fft_data[0], dl); - _vis_data_work(current_fft_data[1], dr); - } - if (status.current_page == PAGE_WATERFALL) _vis_process(); + short dl[FFT_BUFFER_SIZE]; + short dr[FFT_BUFFER_SIZE]; + int i, j, k; + + if (!inlen) { + memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); + memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); + } else { + for (i = 0; i < FFT_BUFFER_SIZE;) { + for (k = j = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { + dl[i] = ((short)in[j]) * 256; j++; + dr[i] = ((short)in[j]) * 256; j++; + } + } + _vis_data_work(current_fft_data[0], dl); + _vis_data_work(current_fft_data[1], dr); + } + if (status.current_page == PAGE_WATERFALL) _vis_process(); } void vis_work_8m(char *in, int inlen) { - short d[FFT_BUFFER_SIZE]; - int i, k; + short d[FFT_BUFFER_SIZE]; + int i, k; - if (!inlen) { - memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); - memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); - } else { - for (i = 0; i < FFT_BUFFER_SIZE;) { - for (k = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { - d[i] = ((short)in[k]) * 256; - } - } - _vis_data_work(current_fft_data[0], d); - memcpy(current_fft_data[1], - current_fft_data[0], FFT_OUTPUT_SIZE * 2); - } - if (status.current_page == PAGE_WATERFALL) _vis_process(); + if (!inlen) { + memset(current_fft_data[0], 0, FFT_OUTPUT_SIZE*2); + memset(current_fft_data[1], 0, FFT_OUTPUT_SIZE*2); + } else { + for (i = 0; i < FFT_BUFFER_SIZE;) { + for (k = 0; k < inlen && i < FFT_BUFFER_SIZE; k++, i++) { + d[i] = ((short)in[k]) * 256; + } + } + _vis_data_work(current_fft_data[0], d); + memcpy(current_fft_data[1], + current_fft_data[0], FFT_OUTPUT_SIZE * 2); + } + if (status.current_page == PAGE_WATERFALL) _vis_process(); } static void draw_screen(void) { - /* waterfall uses a single overlay */ - vgamem_ovl_apply(&ovl); + /* waterfall uses a single overlay */ + vgamem_ovl_apply(&ovl); } static int waterfall_handle_key(struct key_event *k) { - int n, v, order, ii; + int n, v, order, ii; - if (NO_MODIFIER(k->mod)) { - if (k->midi_note > -1) { - n = k->midi_note; - if (k->midi_volume > -1) { - v = k->midi_volume / 2; - } else { - v = 64; - } - } else { - v = 64; - n = kbd_get_note(k); - } - if (n > -1) { - if (song_is_instrument_mode()) { - ii = instrument_get_current(); - } else { - ii = sample_get_current(); - } - if (k->state) { - song_keyup(KEYJAZZ_NOINST, ii, n); - status.last_keysym = 0; - } else if (!k->is_repeat) { - song_keydown(KEYJAZZ_NOINST, ii, n, v, KEYJAZZ_CHAN_CURRENT); - } - return 1; - } - } - - switch (k->sym) { - case SDLK_s: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - - song_toggle_stereo(); - status.flags |= NEED_UPDATE; - return 1; - } - return 0; - case SDLK_m: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - mono = !mono; - return 1; - } - return 0; - case SDLK_LEFT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - gain--; - break; - case SDLK_RIGHT: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - gain++; - break; - case SDLK_g: - if (k->mod & KMOD_ALT) { - if (!k->state) return 1; - - order = song_get_current_order(); - if (song_get_mode() == MODE_PLAYING) { - n = current_song->orderlist[order]; - } else { - n = song_get_playing_pattern(); - } - if (n < 200) { - set_current_order(order); - set_current_pattern(n); - set_current_row(song_get_current_row()); - set_page(PAGE_PATTERN_EDITOR); - } - return 1; - } - return 0; - case SDLK_r: - if (k->mod & KMOD_ALT) { - if (k->state) return 1; - - song_flip_stereo(); - return 1; - } - return 0; - case SDLK_PLUS: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - if (song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() + 1); - } - return 1; - case SDLK_MINUS: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - if (song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() - 1); - } - return 1; - case SDLK_SEMICOLON: - case SDLK_COLON: - if (k->state) return 1; - if (song_is_instrument_mode()) { - instrument_set(instrument_get_current() - 1); - } else { - sample_set(sample_get_current() - 1); - } - return 1; - case SDLK_QUOTE: - case SDLK_QUOTEDBL: - if (k->state) return 1; - if (song_is_instrument_mode()) { - instrument_set(instrument_get_current() + 1); - } else { - sample_set(sample_get_current() + 1); - } - return 1; - case SDLK_COMMA: - case SDLK_LESS: - if (k->state) return 1; - song_change_current_play_channel(-1, 0); - return 1; - case SDLK_PERIOD: - case SDLK_GREATER: - if (k->state) return 1; - song_change_current_play_channel(1, 0); - return 1; - default: - return 0; - }; + if (NO_MODIFIER(k->mod)) { + if (k->midi_note > -1) { + n = k->midi_note; + if (k->midi_volume > -1) { + v = k->midi_volume / 2; + } else { + v = 64; + } + } else { + v = 64; + n = kbd_get_note(k); + } + if (n > -1) { + if (song_is_instrument_mode()) { + ii = instrument_get_current(); + } else { + ii = sample_get_current(); + } + if (k->state == KEY_RELEASE) { + song_keyup(KEYJAZZ_NOINST, ii, n); + status.last_keysym = 0; + } else if (!k->is_repeat) { + song_keydown(KEYJAZZ_NOINST, ii, n, v, KEYJAZZ_CHAN_CURRENT); + } + return 1; + } + } + + switch (k->sym) { + case SDLK_s: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + + song_toggle_stereo(); + status.flags |= NEED_UPDATE; + return 1; + } + return 0; + case SDLK_m: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + mono = !mono; + return 1; + } + return 0; + case SDLK_LEFT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + noisefloor-=4; + break; + case SDLK_RIGHT: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + noisefloor+=4; + break; + case SDLK_g: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_PRESS) + return 1; + + order = song_get_current_order(); + if (song_get_mode() == MODE_PLAYING) { + n = current_song->orderlist[order]; + } else { + n = song_get_playing_pattern(); + } + if (n < 200) { + set_current_order(order); + set_current_pattern(n); + set_current_row(song_get_current_row()); + set_page(PAGE_PATTERN_EDITOR); + } + return 1; + } + return 0; + case SDLK_r: + if (k->mod & KMOD_ALT) { + if (k->state == KEY_RELEASE) + return 1; + + song_flip_stereo(); + return 1; + } + return 0; + case SDLK_PLUS: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() + 1); + } + return 1; + case SDLK_MINUS: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + if (song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() - 1); + } + return 1; + case SDLK_SEMICOLON: + case SDLK_COLON: + if (k->state == KEY_RELEASE) + return 1; + if (song_is_instrument_mode()) { + instrument_set(instrument_get_current() - 1); + } else { + sample_set(sample_get_current() - 1); + } + return 1; + case SDLK_QUOTE: + case SDLK_QUOTEDBL: + if (k->state == KEY_RELEASE) + return 1; + if (song_is_instrument_mode()) { + instrument_set(instrument_get_current() + 1); + } else { + sample_set(sample_get_current() + 1); + } + return 1; + case SDLK_COMMA: + case SDLK_LESS: + if (k->state == KEY_RELEASE) + return 1; + song_change_current_play_channel(-1, 0); + return 1; + case SDLK_PERIOD: + case SDLK_GREATER: + if (k->state == KEY_RELEASE) + return 1; + song_change_current_play_channel(1, 0); + return 1; + default: + return 0; + }; - gain = CLAMP(gain, -8, 8); - return 1; + noisefloor = CLAMP(noisefloor, 36, 96); + return 1; } @@ -475,15 +549,15 @@ static void waterfall_set_page(void) { - vgamem_ovl_clear(&ovl, 0); + vgamem_ovl_clear(&ovl, 0); } void waterfall_load_page(struct page *page) { - vgamem_ovl_alloc(&ovl); - page->title = ""; - page->draw_full = draw_screen; - page->set_page = waterfall_set_page; - page->total_widgets = 1; - page->widgets = waterfall_widget_hack; - create_other(waterfall_widget_hack, 0, waterfall_handle_key, do_nil); + vgamem_ovl_alloc(&ovl); + page->title = ""; + page->draw_full = draw_screen; + page->set_page = waterfall_set_page; + page->total_widgets = 1; + page->widgets = waterfall_widget_hack; + create_other(waterfall_widget_hack, 0, waterfall_handle_key, do_nil); } diff -Nru schism-0+20110101/schism/palettes.c schism-20160521/schism/palettes.c --- schism-0+20110101/schism/palettes.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/palettes.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,263 +30,263 @@ /* --------------------------------------------------------------------- */ struct it_palette palettes[] = { - {"Light Blue", { - /* 0 */ { 0, 0, 0}, - /* 1 */ {10, 25, 45}, - /* 2 */ {30, 40, 55}, - /* 3 */ {51, 58, 63}, - /* 4 */ {63, 21, 21}, - /* 5 */ {21, 63, 21}, - /* 6 */ {44, 44, 44}, - /* 7 */ {22, 22, 22}, - /* 8 */ { 0, 0, 32}, - /* 9 */ { 0, 0, 42}, - /* 10 */ {30, 40, 55}, - /* 11 */ {51, 58, 63}, - /* 12 */ {44, 44, 44}, - /* 13 */ {21, 63, 21}, - /* 14 */ {18, 16, 15}, - /* 15 */ {12, 11, 10}, - }}, - {"Gold", { /* hey, this is the ST3 palette! (sort of) */ - /* 0 */ { 0, 0, 0}, - /* 1 */ {20, 17, 10}, - /* 2 */ {41, 36, 21}, - /* 3 */ {63, 55, 33}, - /* 4 */ {63, 21, 21}, - /* 5 */ {18, 53, 18}, - /* 6 */ {38, 37, 36}, - /* 7 */ {22, 22, 22}, - /* 8 */ { 0, 0, 32}, - /* 9 */ { 0, 0, 42}, - /* 10 */ {41, 36, 21}, - /* 11 */ {48, 49, 46}, - /* 12 */ {44, 44, 44}, - /* 13 */ {21, 50, 21}, - /* 14 */ {18, 16, 15}, - /* 15 */ {12, 11, 10}, - }}, - {"Camouflage", { - /* 0 */ { 0, 0, 0}, - /* 1 */ {31, 22, 17}, - /* 2 */ {45, 37, 30}, - /* 3 */ {58, 58, 50}, - /* 4 */ {44, 0, 21}, - /* 5 */ {63, 63, 21}, - /* 6 */ {17, 38, 18}, - /* 7 */ {19, 3, 6}, - /* 8 */ { 8, 21, 0}, - /* 9 */ { 6, 29, 11}, - /* 10 */ {14, 39, 29}, - /* 11 */ {55, 58, 56}, - /* 12 */ {40, 40, 40}, - /* 13 */ {35, 5, 21}, - /* 14 */ {22, 16, 15}, - /* 15 */ {13, 12, 11}, - }}, - {"Midnight Tracking", { - /* 0 */ { 0, 0, 0}, - /* 1 */ { 0, 8, 16}, - /* 2 */ { 0, 19, 32}, - /* 3 */ {16, 28, 48}, - /* 4 */ {63, 21, 21}, - /* 5 */ { 0, 48, 36}, - /* 6 */ {32, 32, 32}, - /* 7 */ {22, 22, 22}, - /* 8 */ { 0, 0, 24}, - /* 9 */ { 0, 0, 32}, - /* 10 */ { 0, 18, 32}, - /* 11 */ {40, 40, 40}, - /* 12 */ {32, 32, 32}, - /* 13 */ {28, 0, 24}, - /* 14 */ { 4, 13, 20}, - /* 15 */ { 6, 7, 11}, - }}, - {"Pine Colours", { - /* 0 */ { 0, 0, 0}, - /* 1 */ { 2, 16, 13}, - /* 2 */ {21, 32, 29}, - /* 3 */ {51, 58, 63}, - /* 4 */ {63, 34, 0}, - /* 5 */ {52, 51, 33}, - /* 6 */ {42, 41, 33}, - /* 7 */ {31, 22, 22}, - /* 8 */ {12, 10, 16}, - /* 9 */ {18, 0, 24}, - /* 10 */ {30, 40, 55}, - /* 11 */ {58, 58, 33}, - /* 12 */ {44, 44, 44}, - /* 13 */ {49, 39, 21}, - /* 14 */ {13, 15, 14}, - /* 15 */ {14, 11, 14}, - }}, - {"Soundtracker", { - /* 0 */ { 0, 0, 0}, - /* 1 */ {18, 24, 28}, - /* 2 */ {35, 42, 47}, - /* 3 */ {51, 56, 60}, - /* 4 */ {63, 21, 21}, - /* 5 */ {21, 63, 22}, - /* 6 */ { 0, 35, 63}, - /* 7 */ {22, 22, 22}, - /* 8 */ {32, 13, 38}, - /* 9 */ {37, 16, 62}, - /* 10 */ {27, 40, 55}, - /* 11 */ {51, 58, 63}, - /* 12 */ {44, 44, 44}, - /* 13 */ {21, 63, 21}, - /* 14 */ {18, 16, 17}, - /* 15 */ {13, 14, 13}, - }}, - {"Volcanic", { - /* 0 */ { 0, 0, 0}, - /* 1 */ {25, 9, 0}, - /* 2 */ {40, 14, 0}, - /* 3 */ {51, 23, 0}, - /* 4 */ {63, 8, 16}, - /* 5 */ { 0, 39, 5}, - /* 6 */ {32, 32, 32}, - /* 7 */ { 0, 20, 20}, - /* 8 */ {21, 0, 0}, - /* 9 */ {28, 0, 0}, - /* 10 */ {32, 32, 32}, - /* 11 */ {62, 31, 0}, - /* 12 */ {40, 40, 40}, - /* 13 */ { 0, 28, 38}, - /* 14 */ {10, 16, 27}, - /* 15 */ { 8, 11, 19}, - }}, - {"Industrial", { /* mine */ - /* 0 */ { 0, 0, 0}, - /* 1 */ {18, 18, 18}, - /* 2 */ {28, 28, 28}, - /* 3 */ {51, 51, 51}, - /* 4 */ {51, 20, 0}, - /* 5 */ {55, 43, 0}, - /* 6 */ {12, 23, 35}, - /* 7 */ {11, 0, 22}, - /* 8 */ {14, 0, 14}, - /* 9 */ {13, 0, 9}, - /* 10 */ { 0, 24, 24}, - /* 11 */ {23, 4, 43}, - /* 12 */ {16, 32, 24}, - /* 13 */ {36, 0, 0}, - /* 14 */ {14, 7, 2}, - /* 15 */ { 2, 10, 14}, - }}, - {"Purple Motion", { /* Imago Orpheus */ - /* 0 */ { 0, 0, 0}, - /* 1 */ {14, 10, 14}, - /* 2 */ {24, 18, 24}, - /* 3 */ {32, 26, 32}, - /* 4 */ {48, 0, 0}, - /* 5 */ {32, 63, 32}, - /* 6 */ {48, 48, 48}, - /* 7 */ {16, 0, 32}, - /* 8 */ { 8, 8, 16}, - /* 9 */ {11, 11, 21}, - /* 10 */ {24, 18, 24}, - /* 11 */ {32, 26, 32}, - /* 12 */ {48, 48, 48}, - /* 13 */ { 0, 32, 0}, - /* 14 */ {12, 13, 14}, - /* 15 */ { 9, 10, 11}, - }}, - {"Why Colors?", { /* FT2 */ - /* 0 */ { 0, 0, 0}, - /* 1 */ { 9, 14, 16}, - /* 2 */ {18, 29, 32}, - /* 3 */ {63, 63, 63}, - /* 4 */ {63, 0, 0}, - /* 5 */ {63, 63, 32}, - /* 6 */ {63, 63, 32}, - /* 7 */ {16, 16, 8}, - /* 8 */ {10, 10, 10}, - /* 9 */ {20, 20, 20}, - /* 10 */ {32, 32, 32}, - /* 11 */ {24, 38, 45}, - /* 12 */ {48, 48, 48}, - /* 13 */ {63, 63, 32}, - /* 14 */ {20, 20, 20}, - /* 15 */ {10, 10, 10}, - }}, - {"Kawaii", { /* mine (+mml) */ - /* 0 */ {61, 60, 63}, - /* 1 */ {63, 53, 60}, - /* 2 */ {51, 38, 47}, - /* 3 */ {18, 10, 17}, - /* 4 */ {63, 28, 50}, - /* 5 */ {21, 34, 50}, - /* 6 */ {40, 32, 45}, - /* 7 */ {63, 52, 59}, - /* 8 */ {48, 55, 63}, - /* 9 */ {51, 48, 63}, - /* 10 */ {45, 29, 44}, - /* 11 */ {57, 48, 59}, - /* 12 */ {34, 18, 32}, - /* 13 */ {50, 42, 63}, - /* 14 */ {50, 53, 60}, - /* 15 */ {63, 58, 56}, - }}, - {"Gold (Vintage)", { /* more directly based on the ST3 palette */ - /* 0 */ { 0, 0, 0}, - /* 1 */ {20, 17, 10}, - /* 2 */ {41, 36, 21}, - /* 3 */ {63, 55, 33}, - /* 4 */ {57, 0, 0}, // 63, 21, 21 - /* 5 */ { 0, 44, 0}, // 21, 50, 21 - /* 6 */ {38, 37, 36}, - /* 7 */ {22, 22, 22}, // not from ST3 - /* 8 */ { 5, 9, 22}, // 0, 0, 32 - /* 9 */ { 6, 12, 29}, // 0, 0, 42 - /* 10 */ {41, 36, 21}, - /* 11 */ {48, 49, 46}, - /* 12 */ {44, 44, 44}, // not from ST3 - /* 13 */ { 0, 44, 0}, // 21, 50, 21 - /* 14 */ {18, 16, 15}, - /* 15 */ {12, 11, 10}, - // no place for the dark red (34, 0, 0) - // (used for box corner decorations in ST3) - // also no place for the yellow (63, 63, 0) - // (note dots?) - }}, - {"FX 2.0", { /* Virt-supplied :) */ - /* 0 */ { 0, 4, 0}, - /* 1 */ { 6, 14, 8}, - /* 2 */ {30, 32, 32}, - /* 3 */ {55, 57, 50}, - /* 4 */ { 0, 13, 42}, - /* 5 */ {19, 43, 19}, - /* 6 */ { 7, 48, 22}, - /* 7 */ { 0, 13, 0 }, - /* 8 */ {24, 12, 23}, - /* 9 */ {19, 8, 23}, - /* 10 */ {14, 39, 29}, - /* 11 */ {28, 42, 43}, - /* 12 */ {12, 51, 35}, - /* 13 */ {12, 55, 31}, - /* 14 */ { 5, 15, 4}, - /* 15 */ { 3, 13, 7}, - }}, - {"Atlantic", { /* from an ANCIENT version of Impulse Tracker */ - /* 0 */ { 0, 0, 0}, - /* 1 */ { 2, 0, 30}, - /* 2 */ { 8, 18, 43}, - /* 3 */ {21, 43, 63}, - /* 4 */ {63, 8, 16}, - /* 5 */ {27, 32, 63}, - /* 6 */ { 0, 54, 63}, - /* 7 */ {10, 15, 35}, - /* 8 */ { 0, 0, 30}, - /* 9 */ { 0, 0, 36}, - /* 10 */ { 0, 18, 32}, - /* 11 */ {40, 40, 40}, - /* 12 */ {18, 52, 63}, - /* 13 */ {21, 50, 21}, - /* 14 */ {10, 16, 27}, - /* 15 */ { 8, 11, 19}, - }}, - {"", {{0}}} + {"Light Blue", { + /* 0 */ { 0, 0, 0}, + /* 1 */ {10, 25, 45}, + /* 2 */ {30, 40, 55}, + /* 3 */ {51, 58, 63}, + /* 4 */ {63, 21, 21}, + /* 5 */ {21, 63, 21}, + /* 6 */ {44, 44, 44}, + /* 7 */ {22, 22, 22}, + /* 8 */ { 0, 0, 32}, + /* 9 */ { 0, 0, 42}, + /* 10 */ {30, 40, 55}, + /* 11 */ {51, 58, 63}, + /* 12 */ {44, 44, 44}, + /* 13 */ {21, 63, 21}, + /* 14 */ {18, 16, 15}, + /* 15 */ {12, 11, 10}, + }}, + {"Gold", { /* hey, this is the ST3 palette! (sort of) */ + /* 0 */ { 0, 0, 0}, + /* 1 */ {20, 17, 10}, + /* 2 */ {41, 36, 21}, + /* 3 */ {63, 55, 33}, + /* 4 */ {63, 21, 21}, + /* 5 */ {18, 53, 18}, + /* 6 */ {38, 37, 36}, + /* 7 */ {22, 22, 22}, + /* 8 */ { 0, 0, 32}, + /* 9 */ { 0, 0, 42}, + /* 10 */ {41, 36, 21}, + /* 11 */ {48, 49, 46}, + /* 12 */ {44, 44, 44}, + /* 13 */ {21, 50, 21}, + /* 14 */ {18, 16, 15}, + /* 15 */ {12, 11, 10}, + }}, + {"Camouflage", { + /* 0 */ { 0, 0, 0}, + /* 1 */ {31, 22, 17}, + /* 2 */ {45, 37, 30}, + /* 3 */ {58, 58, 50}, + /* 4 */ {44, 0, 21}, + /* 5 */ {63, 63, 21}, + /* 6 */ {17, 38, 18}, + /* 7 */ {19, 3, 6}, + /* 8 */ { 8, 21, 0}, + /* 9 */ { 6, 29, 11}, + /* 10 */ {14, 39, 29}, + /* 11 */ {55, 58, 56}, + /* 12 */ {40, 40, 40}, + /* 13 */ {35, 5, 21}, + /* 14 */ {22, 16, 15}, + /* 15 */ {13, 12, 11}, + }}, + {"Midnight Tracking", { + /* 0 */ { 0, 0, 0}, + /* 1 */ { 0, 8, 16}, + /* 2 */ { 0, 19, 32}, + /* 3 */ {16, 28, 48}, + /* 4 */ {63, 21, 21}, + /* 5 */ { 0, 48, 36}, + /* 6 */ {32, 32, 32}, + /* 7 */ {22, 22, 22}, + /* 8 */ { 0, 0, 24}, + /* 9 */ { 0, 0, 32}, + /* 10 */ { 0, 18, 32}, + /* 11 */ {40, 40, 40}, + /* 12 */ {32, 32, 32}, + /* 13 */ {28, 0, 24}, + /* 14 */ { 4, 13, 20}, + /* 15 */ { 6, 7, 11}, + }}, + {"Pine Colours", { + /* 0 */ { 0, 0, 0}, + /* 1 */ { 2, 16, 13}, + /* 2 */ {21, 32, 29}, + /* 3 */ {51, 58, 63}, + /* 4 */ {63, 34, 0}, + /* 5 */ {52, 51, 33}, + /* 6 */ {42, 41, 33}, + /* 7 */ {31, 22, 22}, + /* 8 */ {12, 10, 16}, + /* 9 */ {18, 0, 24}, + /* 10 */ {30, 40, 55}, + /* 11 */ {58, 58, 33}, + /* 12 */ {44, 44, 44}, + /* 13 */ {49, 39, 21}, + /* 14 */ {13, 15, 14}, + /* 15 */ {14, 11, 14}, + }}, + {"Soundtracker", { + /* 0 */ { 0, 0, 0}, + /* 1 */ {18, 24, 28}, + /* 2 */ {35, 42, 47}, + /* 3 */ {51, 56, 60}, + /* 4 */ {63, 21, 21}, + /* 5 */ {21, 63, 22}, + /* 6 */ { 0, 35, 63}, + /* 7 */ {22, 22, 22}, + /* 8 */ {32, 13, 38}, + /* 9 */ {37, 16, 62}, + /* 10 */ {27, 40, 55}, + /* 11 */ {51, 58, 63}, + /* 12 */ {44, 44, 44}, + /* 13 */ {21, 63, 21}, + /* 14 */ {18, 16, 17}, + /* 15 */ {13, 14, 13}, + }}, + {"Volcanic", { + /* 0 */ { 0, 0, 0}, + /* 1 */ {25, 9, 0}, + /* 2 */ {40, 14, 0}, + /* 3 */ {51, 23, 0}, + /* 4 */ {63, 8, 16}, + /* 5 */ { 0, 39, 5}, + /* 6 */ {32, 32, 32}, + /* 7 */ { 0, 20, 20}, + /* 8 */ {21, 0, 0}, + /* 9 */ {28, 0, 0}, + /* 10 */ {32, 32, 32}, + /* 11 */ {62, 31, 0}, + /* 12 */ {40, 40, 40}, + /* 13 */ { 0, 28, 38}, + /* 14 */ {10, 16, 27}, + /* 15 */ { 8, 11, 19}, + }}, + {"Industrial", { /* mine */ + /* 0 */ { 0, 0, 0}, + /* 1 */ {18, 18, 18}, + /* 2 */ {28, 28, 28}, + /* 3 */ {51, 51, 51}, + /* 4 */ {51, 20, 0}, + /* 5 */ {55, 43, 0}, + /* 6 */ {12, 23, 35}, + /* 7 */ {11, 0, 22}, + /* 8 */ {14, 0, 14}, + /* 9 */ {13, 0, 9}, + /* 10 */ { 0, 24, 24}, + /* 11 */ {23, 4, 43}, + /* 12 */ {16, 32, 24}, + /* 13 */ {36, 0, 0}, + /* 14 */ {14, 7, 2}, + /* 15 */ { 2, 10, 14}, + }}, + {"Purple Motion", { /* Imago Orpheus */ + /* 0 */ { 0, 0, 0}, + /* 1 */ {14, 10, 14}, + /* 2 */ {24, 18, 24}, + /* 3 */ {32, 26, 32}, + /* 4 */ {48, 0, 0}, + /* 5 */ {32, 63, 32}, + /* 6 */ {48, 48, 48}, + /* 7 */ {16, 0, 32}, + /* 8 */ { 8, 8, 16}, + /* 9 */ {11, 11, 21}, + /* 10 */ {24, 18, 24}, + /* 11 */ {32, 26, 32}, + /* 12 */ {48, 48, 48}, + /* 13 */ { 0, 32, 0}, + /* 14 */ {12, 13, 14}, + /* 15 */ { 9, 10, 11}, + }}, + {"Why Colors?", { /* FT2 */ + /* 0 */ { 0, 0, 0}, + /* 1 */ { 9, 14, 16}, + /* 2 */ {18, 29, 32}, + /* 3 */ {63, 63, 63}, + /* 4 */ {63, 0, 0}, + /* 5 */ {63, 63, 32}, + /* 6 */ {63, 63, 32}, + /* 7 */ {16, 16, 8}, + /* 8 */ {10, 10, 10}, + /* 9 */ {20, 20, 20}, + /* 10 */ {32, 32, 32}, + /* 11 */ {24, 38, 45}, + /* 12 */ {48, 48, 48}, + /* 13 */ {63, 63, 32}, + /* 14 */ {20, 20, 20}, + /* 15 */ {10, 10, 10}, + }}, + {"Kawaii", { /* mine (+mml) */ + /* 0 */ {61, 60, 63}, + /* 1 */ {63, 53, 60}, + /* 2 */ {51, 38, 47}, + /* 3 */ {18, 10, 17}, + /* 4 */ {63, 28, 50}, + /* 5 */ {21, 34, 50}, + /* 6 */ {40, 32, 45}, + /* 7 */ {63, 52, 59}, + /* 8 */ {48, 55, 63}, + /* 9 */ {51, 48, 63}, + /* 10 */ {45, 29, 44}, + /* 11 */ {57, 48, 59}, + /* 12 */ {34, 18, 32}, + /* 13 */ {50, 42, 63}, + /* 14 */ {50, 53, 60}, + /* 15 */ {63, 58, 56}, + }}, + {"Gold (Vintage)", { /* more directly based on the ST3 palette */ + /* 0 */ { 0, 0, 0}, + /* 1 */ {20, 17, 10}, + /* 2 */ {41, 36, 21}, + /* 3 */ {63, 55, 33}, + /* 4 */ {57, 0, 0}, // 63, 21, 21 + /* 5 */ { 0, 44, 0}, // 21, 50, 21 + /* 6 */ {38, 37, 36}, + /* 7 */ {22, 22, 22}, // not from ST3 + /* 8 */ { 5, 9, 22}, // 0, 0, 32 + /* 9 */ { 6, 12, 29}, // 0, 0, 42 + /* 10 */ {41, 36, 21}, + /* 11 */ {48, 49, 46}, + /* 12 */ {44, 44, 44}, // not from ST3 + /* 13 */ { 0, 44, 0}, // 21, 50, 21 + /* 14 */ {18, 16, 15}, + /* 15 */ {12, 11, 10}, + // no place for the dark red (34, 0, 0) + // (used for box corner decorations in ST3) + // also no place for the yellow (63, 63, 0) + // (note dots?) + }}, + {"FX 2.0", { /* Virt-supplied :) */ + /* 0 */ { 0, 4, 0}, + /* 1 */ { 6, 14, 8}, + /* 2 */ {30, 32, 32}, + /* 3 */ {55, 57, 50}, + /* 4 */ { 0, 13, 42}, + /* 5 */ {19, 43, 19}, + /* 6 */ { 7, 48, 22}, + /* 7 */ { 0, 13, 0 }, + /* 8 */ {24, 12, 23}, + /* 9 */ {19, 8, 23}, + /* 10 */ {14, 39, 29}, + /* 11 */ {28, 42, 43}, + /* 12 */ {12, 51, 35}, + /* 13 */ {12, 55, 31}, + /* 14 */ { 5, 15, 4}, + /* 15 */ { 3, 13, 7}, + }}, + {"Atlantic", { /* from an ANCIENT version of Impulse Tracker */ + /* 0 */ { 0, 0, 0}, + /* 1 */ { 2, 0, 30}, + /* 2 */ { 8, 18, 43}, + /* 3 */ {21, 43, 63}, + /* 4 */ {63, 8, 16}, + /* 5 */ {27, 32, 63}, + /* 6 */ { 0, 54, 63}, + /* 7 */ {10, 15, 35}, + /* 8 */ { 0, 0, 30}, + /* 9 */ { 0, 0, 36}, + /* 10 */ { 0, 18, 32}, + /* 11 */ {40, 40, 40}, + /* 12 */ {18, 52, 63}, + /* 13 */ {21, 50, 21}, + /* 14 */ {10, 16, 27}, + /* 15 */ { 8, 11, 19}, + }}, + {"", {{0}}} }; #define NUM_PALETTES (ARRAY_SIZE(palettes) - 1) @@ -297,22 +297,22 @@ /* this is set in cfg_load() (config.c) palette_apply() must be called after changing this to update the display. */ uint8_t current_palette[16][3] = { - /* 0 */ { 0, 0, 0}, - /* 1 */ { 0, 0, 42}, - /* 2 */ { 0, 42, 0}, - /* 3 */ { 0, 42, 42}, - /* 4 */ {42, 0, 0}, - /* 5 */ {42, 0, 42}, - /* 6 */ {42, 21, 0}, - /* 7 */ {42, 42, 42}, - /* 8 */ {21, 21, 21}, - /* 9 */ {21, 21, 63}, - /* 10 */ {21, 63, 21}, - /* 11 */ {21, 63, 63}, - /* 12 */ {63, 21, 21}, - /* 13 */ {63, 21, 63}, - /* 14 */ {63, 63, 21}, - /* 15 */ {63, 63, 63}, + /* 0 */ { 0, 0, 0}, + /* 1 */ { 0, 0, 42}, + /* 2 */ { 0, 42, 0}, + /* 3 */ { 0, 42, 42}, + /* 4 */ {42, 0, 0}, + /* 5 */ {42, 0, 42}, + /* 6 */ {42, 21, 0}, + /* 7 */ {42, 42, 42}, + /* 8 */ {21, 21, 21}, + /* 9 */ {21, 21, 63}, + /* 10 */ {21, 63, 21}, + /* 11 */ {21, 63, 63}, + /* 12 */ {63, 21, 21}, + /* 13 */ {63, 21, 63}, + /* 14 */ {63, 63, 21}, + /* 15 */ {63, 63, 63}, }; /* this should be changed only with palette_load_preset() (which doesn't call palette_apply() automatically, so do that as well) */ @@ -321,32 +321,32 @@ void palette_apply(void) { - int n; - unsigned char cx[16][3]; + int n; + unsigned char cx[16][3]; - for (n = 0; n < 16; n++) { - cx[n][0] = current_palette[n][0] << 2; - cx[n][1] = current_palette[n][1] << 2; - cx[n][2] = current_palette[n][2] << 2; - } - video_colors(cx); - - /* is the "light" border color actually darker than the "dark" color? */ - if ((current_palette[1][0] + current_palette[1][1] + current_palette[1][2]) - > (current_palette[3][0] + current_palette[3][1] + current_palette[3][2])) { - status.flags |= INVERTED_PALETTE; - } else { - status.flags &= ~INVERTED_PALETTE; - } + for (n = 0; n < 16; n++) { + cx[n][0] = current_palette[n][0] << 2; + cx[n][1] = current_palette[n][1] << 2; + cx[n][2] = current_palette[n][2] << 2; + } + video_colors(cx); + + /* is the "light" border color actually darker than the "dark" color? */ + if ((current_palette[1][0] + current_palette[1][1] + current_palette[1][2]) + > (current_palette[3][0] + current_palette[3][1] + current_palette[3][2])) { + status.flags |= INVERTED_PALETTE; + } else { + status.flags &= ~INVERTED_PALETTE; + } } void palette_load_preset(int palette_index) { - if (palette_index < -1 || palette_index >= NUM_PALETTES) - return; + if (palette_index < -1 || palette_index >= NUM_PALETTES) + return; - current_palette_index = palette_index; - if (palette_index == -1) return; - memcpy(current_palette, palettes[palette_index].colors, sizeof(current_palette)); + current_palette_index = palette_index; + if (palette_index == -1) return; + memcpy(current_palette, palettes[palette_index].colors, sizeof(current_palette)); } diff -Nru schism-0+20110101/schism/pattern-view.c schism-20160521/schism/pattern-view.c --- schism-0+20110101/schism/pattern-view.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/pattern-view.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -39,96 +39,103 @@ masked (4) mask & MASK_whatever */ static const char mask_chars[] = { - 143, // 0 - 143, // atnote - 169, // over - 169, // over && atnote - 170, // masked - 169, // masked && atnote - 171, // masked && over - 171, // masked && over && atnote + 143, // 0 + 143, // atnote + 169, // over + 169, // over && atnote + 170, // masked + 169, // masked && atnote + 171, // masked && over + 171, // masked && over && atnote }; #define MASK_CHAR(field, pos, pos2) \ - mask_chars [ \ - ((cursor_pos == 0) ? 1 : 0) | \ - ((cursor_pos == pos) ? 2 : 0) | \ - ((pos2 && cursor_pos == pos2) ? 2 : 0) | \ - ((mask & field) ? 4 : 0) ] + mask_chars [ \ + ((cursor_pos == 0) ? 1 : 0) | \ + ((cursor_pos == pos) ? 2 : 0) | \ + ((pos2 && cursor_pos == pos2) ? 2 : 0) | \ + ((mask & field) ? 4 : 0) ] /* --------------------------------------------------------------------- */ /* 13-column track view */ void draw_channel_header_13(int chan, int x, int y, int fg) { - char buf[16]; - sprintf(buf, " Channel %02d ", chan); - draw_text(buf, x, y, fg, 1); + char buf[16]; + sprintf(buf, " Channel %02d ", chan); + draw_text(buf, x, y, fg, 1); } void draw_note_13(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) { - int cursor_pos_map[9] = { 0, 2, 4, 5, 7, 8, 10, 11, 12 }; - char note_text[16], note_buf[4], vol_buf[4]; - char instbuf[4]; - - get_note_string(note->note, note_buf); - get_volume_string(note->volparam, note->voleffect, vol_buf); - - /* come to think of it, maybe the instrument text should be - * created the same way as the volume. */ - if (note->instrument) - num99tostr(note->instrument, instbuf); - else - strcpy(instbuf, "\xad\xad"); - - snprintf(note_text, 16, "%s %s %s %c%02X", - note_buf, instbuf, vol_buf, - get_effect_char(note->effect), note->param); - - if (show_default_volumes && note->voleffect == VOLFX_NONE && note->instrument > 0) { - /* Modplug-specific hack: volume bit shift */ - int n = song_get_sample(note->instrument)->volume >> 2; - note_text[6] = 0xbf; - note_text[7] = '0' + n / 10 % 10; - note_text[8] = '0' + n / 1 % 10; - note_text[9] = 0xc0; - } - - draw_text(note_text, x, y, fg, bg); - - /* lazy coding here: the panning is written twice, or if the - * cursor's on it, *three* times. */ - if (note->voleffect == VOLFX_PANNING) - draw_text(vol_buf, x + 7, y, 2, bg); - - if (cursor_pos == 9) { - draw_text(note_text + 10, x + 10, y, 0, 3); - } else if (cursor_pos >= 0) { - cursor_pos = cursor_pos_map[cursor_pos]; - draw_char(note_text[cursor_pos], x + cursor_pos, y, 0, 3); - } + int cursor_pos_map[9] = { 0, 2, 4, 5, 7, 8, 10, 11, 12 }; + char note_text[16], note_buf[4], vol_buf[4]; + char instbuf[4]; + + get_note_string(note->note, note_buf); + get_volume_string(note->volparam, note->voleffect, vol_buf); + + /* come to think of it, maybe the instrument text should be + * created the same way as the volume. */ + if (note->instrument) + num99tostr(note->instrument, instbuf); + else + strcpy(instbuf, "\xad\xad"); + + snprintf(note_text, 16, "%s %s %s %c%02X", + note_buf, instbuf, vol_buf, + get_effect_char(note->effect), note->param); + + if (show_default_volumes && note->voleffect == VOLFX_NONE + && note->instrument > 0 && NOTE_IS_NOTE(note->note)) { + song_sample_t *smp = song_is_instrument_mode() + ? csf_translate_keyboard(current_song, song_get_instrument(note->instrument), + note->note, NULL) + : song_get_sample(note->instrument); + if (smp) { + /* Modplug-specific hack: volume bit shift */ + int n = smp->volume >> 2; + note_text[6] = 0xbf; + note_text[7] = '0' + n / 10 % 10; + note_text[8] = '0' + n / 1 % 10; + note_text[9] = 0xc0; + } + } + + draw_text(note_text, x, y, fg, bg); + + /* lazy coding here: the panning is written twice, or if the + * cursor's on it, *three* times. */ + if (note->voleffect == VOLFX_PANNING) + draw_text(vol_buf, x + 7, y, 2, bg); + + if (cursor_pos == 9) { + draw_text(note_text + 10, x + 10, y, 0, 3); + } else if (cursor_pos >= 0) { + cursor_pos = cursor_pos_map[cursor_pos]; + draw_char(note_text[cursor_pos], x + cursor_pos, y, 0, 3); + } } void draw_mask_13(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = { - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 1), - 143, - MASK_CHAR(MASK_INSTRUMENT, 2, 0), - MASK_CHAR(MASK_INSTRUMENT, 3, 0), - 143, - MASK_CHAR(MASK_VOLUME, 4, 0), - MASK_CHAR(MASK_VOLUME, 5, 0), - 143, - MASK_CHAR(MASK_EFFECT, 6, 0), - MASK_CHAR(MASK_EFFECT, 7, 0), - MASK_CHAR(MASK_EFFECT, 8, 0), - 0, - }; + char buf[] = { + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 1), + 143, + MASK_CHAR(MASK_INSTRUMENT, 2, 0), + MASK_CHAR(MASK_INSTRUMENT, 3, 0), + 143, + MASK_CHAR(MASK_VOLUME, 4, 0), + MASK_CHAR(MASK_VOLUME, 5, 0), + 143, + MASK_CHAR(MASK_EFFECT, 6, 0), + MASK_CHAR(MASK_EFFECT, 7, 0), + MASK_CHAR(MASK_EFFECT, 8, 0), + 0, + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -136,71 +143,71 @@ void draw_channel_header_10(int chan, int x, int y, int fg) { - char buf[16]; - sprintf(buf, "Channel %02d", chan); - draw_text(buf, x, y, fg, 1); + char buf[16]; + sprintf(buf, "Channel %02d", chan); + draw_text(buf, x, y, fg, 1); } void draw_note_10(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) { - uint8_t c; - char note_buf[4], ins_buf[3], vol_buf[3], effect_buf[4]; + uint8_t c; + char note_buf[4], ins_buf[3], vol_buf[3], effect_buf[4]; - get_note_string(note->note, note_buf); - if (note->instrument) { - num99tostr(note->instrument, ins_buf); - } else { - ins_buf[0] = ins_buf[1] = 173; - ins_buf[2] = 0; - } - get_volume_string(note->volparam, note->voleffect, vol_buf); - sprintf(effect_buf, "%c%02X", get_effect_char(note->effect), - note->param); - - draw_text(note_buf, x, y, 6, bg); - draw_text(ins_buf, x + 3, y, note->instrument ? 10 : 2, bg); - draw_text(vol_buf, x + 5, y, ((note->voleffect == VOLFX_PANNING) ? 2 : 6), bg); - draw_text(effect_buf, x + 7, y, 2, bg); - - if (cursor_pos < 0) - return; - if (cursor_pos > 0) - cursor_pos++; - if (cursor_pos == 10) { - draw_text(effect_buf, x + 7, y, 0, 3); - } else { - switch (cursor_pos) { - case 0: c = note_buf[0]; break; - case 2: c = note_buf[2]; break; - case 3: c = ins_buf[0]; break; - case 4: c = ins_buf[1]; break; - case 5: c = vol_buf[0]; break; - case 6: c = vol_buf[1]; break; - default: /* 7->9 */ - c = effect_buf[cursor_pos - 7]; - break; - } - draw_char(c, x + cursor_pos, y, 0, 3); - } + get_note_string(note->note, note_buf); + if (note->instrument) { + num99tostr(note->instrument, ins_buf); + } else { + ins_buf[0] = ins_buf[1] = 173; + ins_buf[2] = 0; + } + get_volume_string(note->volparam, note->voleffect, vol_buf); + sprintf(effect_buf, "%c%02X", get_effect_char(note->effect), + note->param); + + draw_text(note_buf, x, y, 6, bg); + draw_text(ins_buf, x + 3, y, note->instrument ? 10 : 2, bg); + draw_text(vol_buf, x + 5, y, ((note->voleffect == VOLFX_PANNING) ? 2 : 6), bg); + draw_text(effect_buf, x + 7, y, 2, bg); + + if (cursor_pos < 0) + return; + if (cursor_pos > 0) + cursor_pos++; + if (cursor_pos == 10) { + draw_text(effect_buf, x + 7, y, 0, 3); + } else { + switch (cursor_pos) { + case 0: c = note_buf[0]; break; + case 2: c = note_buf[2]; break; + case 3: c = ins_buf[0]; break; + case 4: c = ins_buf[1]; break; + case 5: c = vol_buf[0]; break; + case 6: c = vol_buf[1]; break; + default: /* 7->9 */ + c = effect_buf[cursor_pos - 7]; + break; + } + draw_char(c, x + cursor_pos, y, 0, 3); + } } void draw_mask_10(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = { - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 1), - MASK_CHAR(MASK_INSTRUMENT, 2, 0), - MASK_CHAR(MASK_INSTRUMENT, 3, 0), - MASK_CHAR(MASK_VOLUME, 4, 0), - MASK_CHAR(MASK_VOLUME, 5, 0), - MASK_CHAR(MASK_EFFECT, 6, 0), - MASK_CHAR(MASK_EFFECT, 7, 0), - MASK_CHAR(MASK_EFFECT, 8, 0), - 0, - }; + char buf[] = { + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 1), + MASK_CHAR(MASK_INSTRUMENT, 2, 0), + MASK_CHAR(MASK_INSTRUMENT, 3, 0), + MASK_CHAR(MASK_VOLUME, 4, 0), + MASK_CHAR(MASK_VOLUME, 5, 0), + MASK_CHAR(MASK_EFFECT, 6, 0), + MASK_CHAR(MASK_EFFECT, 7, 0), + MASK_CHAR(MASK_EFFECT, 8, 0), + 0, + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -208,29 +215,29 @@ void draw_channel_header_8(int chan, int x, int y, int fg) { - char buf[8]; - sprintf(buf, " %02d ", chan); - draw_text(buf, x, y, fg, 1); + char buf[8]; + sprintf(buf, " %02d ", chan); + draw_text(buf, x, y, fg, 1); } void draw_note_8(int x, int y, const song_note_t *note, UNUSED int cursor_pos, int fg, int bg) { - char buf[4]; + char buf[4]; - get_note_string(note->note, buf); - draw_text(buf, x, y, fg, bg); + get_note_string(note->note, buf); + draw_text(buf, x, y, fg, bg); - if (note->volparam || note->voleffect) { - get_volume_string(note->volparam, note->voleffect, buf); - draw_text(buf, x + 3, y, (note->voleffect == VOLFX_PANNING) ? 1 : 2, bg); - } else { - draw_char(0, x + 3, y, fg, bg); - draw_char(0, x + 4, y, fg, bg); - } - - snprintf(buf, 4, "%c%02X", get_effect_char(note->effect), note->param); - buf[3] = '\0'; - draw_text(buf, x + 5, y, fg, bg); + if (note->volparam || note->voleffect) { + get_volume_string(note->volparam, note->voleffect, buf); + draw_text(buf, x + 3, y, (note->voleffect == VOLFX_PANNING) ? 1 : 2, bg); + } else { + draw_char(0, x + 3, y, fg, bg); + draw_char(0, x + 4, y, fg, bg); + } + + snprintf(buf, 4, "%c%02X", get_effect_char(note->effect), note->param); + buf[3] = '\0'; + draw_text(buf, x + 5, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -238,119 +245,119 @@ void draw_channel_header_7(int chan, int x, int y, int fg) { - char buf[8]; - sprintf(buf, "Chnl %02d", chan); - draw_text(buf, x, y, fg, 1); + char buf[8]; + sprintf(buf, "Chnl %02d", chan); + draw_text(buf, x, y, fg, 1); } void draw_note_7(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) { - char note_buf[4], ins_buf[3], vol_buf[3]; - int fg1, bg1, fg2, bg2; + char note_buf[4], ins_buf[3], vol_buf[3]; + int fg1, bg1, fg2, bg2; - get_note_string(note->note, note_buf); - if (note->instrument) - num99tostr(note->instrument, ins_buf); - else - ins_buf[0] = ins_buf[1] = 173; - get_volume_string(note->volparam, note->voleffect, vol_buf); - - /* note & instrument */ - draw_text(note_buf, x, y, 6, bg); - fg1 = fg2 = (note->instrument ? 10 : 2); - bg1 = bg2 = bg; - switch (cursor_pos) { - case 0: - draw_char(note_buf[0], x, y, 0, 3); - break; - case 1: - draw_char(note_buf[2], x + 2, y, 0, 3); - break; - case 2: - fg1 = 0; - bg1 = 3; - break; - case 3: - fg2 = 0; - bg2 = 3; - break; - } - draw_half_width_chars(ins_buf[0], ins_buf[1], x + 3, y, fg1, bg1, - fg2, bg2); - - /* volume */ - switch (note->voleffect) { - case VOLFX_NONE: - fg1 = 6; - break; - case VOLFX_PANNING: - fg1 = 10; - break; - case VOLFX_TONEPORTAMENTO: - case VOLFX_VIBRATOSPEED: - case VOLFX_VIBRATODEPTH: - fg1 = 6; - break; - default: - fg1 = 12; - break; - } - fg2 = fg1; - bg1 = bg2 = bg; - - switch (cursor_pos) { - case 4: - fg1 = 0; - bg1 = 3; - break; - case 5: - fg2 = 0; - bg2 = 3; - break; - } - draw_half_width_chars(vol_buf[0], vol_buf[1], x + 4, y, fg1, bg1, fg2, bg2); - - /* effect value */ - fg1 = fg2 = 10; - bg1 = bg2 = bg; - switch (cursor_pos) { - case 7: - fg1 = 0; - bg1 = 3; - break; - case 8: - fg2 = 0; - bg2 = 3; - break; - case 9: - fg1 = fg2 = 0; - bg1 = bg2 = 3; - cursor_pos = 6; // hack - break; - } - draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], - hexdigits[note->param & 0xf], - x + 6, y, fg1, bg1, fg2, bg2); - - /* effect */ - draw_char(get_effect_char(note->effect), x + 5, y, - (cursor_pos == 6) ? 0 : 2, (cursor_pos == 6) ? 3 : bg); + get_note_string(note->note, note_buf); + if (note->instrument) + num99tostr(note->instrument, ins_buf); + else + ins_buf[0] = ins_buf[1] = 173; + get_volume_string(note->volparam, note->voleffect, vol_buf); + + /* note & instrument */ + draw_text(note_buf, x, y, 6, bg); + fg1 = fg2 = (note->instrument ? 10 : 2); + bg1 = bg2 = bg; + switch (cursor_pos) { + case 0: + draw_char(note_buf[0], x, y, 0, 3); + break; + case 1: + draw_char(note_buf[2], x + 2, y, 0, 3); + break; + case 2: + fg1 = 0; + bg1 = 3; + break; + case 3: + fg2 = 0; + bg2 = 3; + break; + } + draw_half_width_chars(ins_buf[0], ins_buf[1], x + 3, y, fg1, bg1, + fg2, bg2); + + /* volume */ + switch (note->voleffect) { + case VOLFX_NONE: + fg1 = 6; + break; + case VOLFX_PANNING: + fg1 = 10; + break; + case VOLFX_TONEPORTAMENTO: + case VOLFX_VIBRATOSPEED: + case VOLFX_VIBRATODEPTH: + fg1 = 6; + break; + default: + fg1 = 12; + break; + } + fg2 = fg1; + bg1 = bg2 = bg; + + switch (cursor_pos) { + case 4: + fg1 = 0; + bg1 = 3; + break; + case 5: + fg2 = 0; + bg2 = 3; + break; + } + draw_half_width_chars(vol_buf[0], vol_buf[1], x + 4, y, fg1, bg1, fg2, bg2); + + /* effect value */ + fg1 = fg2 = 10; + bg1 = bg2 = bg; + switch (cursor_pos) { + case 7: + fg1 = 0; + bg1 = 3; + break; + case 8: + fg2 = 0; + bg2 = 3; + break; + case 9: + fg1 = fg2 = 0; + bg1 = bg2 = 3; + cursor_pos = 6; // hack + break; + } + draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], + hexdigits[note->param & 0xf], + x + 6, y, fg1, bg1, fg2, bg2); + + /* effect */ + draw_char(get_effect_char(note->effect), x + 5, y, + (cursor_pos == 6) ? 0 : 2, (cursor_pos == 6) ? 3 : bg); } void draw_mask_7(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = { - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 1), - MASK_CHAR(MASK_INSTRUMENT, 2, 3), - MASK_CHAR(MASK_VOLUME, 4, 5), - MASK_CHAR(MASK_EFFECT, 6, 0), - MASK_CHAR(MASK_EFFECT, 7, 8), - 0, - }; + char buf[] = { + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 1), + MASK_CHAR(MASK_INSTRUMENT, 2, 3), + MASK_CHAR(MASK_VOLUME, 4, 5), + MASK_CHAR(MASK_EFFECT, 6, 0), + MASK_CHAR(MASK_EFFECT, 7, 8), + 0, + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -358,122 +365,122 @@ void draw_channel_header_3(int chan, int x, int y, int fg) { - char buf[4] = { ' ', '0' + chan / 10, '0' + chan % 10, '\0' }; - draw_text(buf, x, y, fg, 1); + char buf[4] = { ' ', '0' + chan / 10, '0' + chan % 10, '\0' }; + draw_text(buf, x, y, fg, 1); } void draw_note_3(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) { - char buf[4]; - int vfg = 6; + char buf[4]; + int vfg = 6; - switch (note->voleffect) { - case VOLFX_VOLUME: - vfg = 2; - break; - case VOLFX_PANNING: - case VOLFX_NONE: - vfg = 1; - break; - } - - switch (cursor_pos) { - case 0: - vfg = fg = 0; - bg = 3; - break; - case 1: - get_note_string(note->note, buf); - draw_text(buf, x, y, 6, bg); - draw_char(buf[2], x + 2, y, 0, 3); - return; - case 2: - case 3: - cursor_pos -= 1; - buf[0] = ' '; - if (note->instrument) { - num99tostr(note->instrument, buf + 1); - } else { - buf[1] = buf[2] = 173; - buf[3] = 0; - } - draw_text(buf, x, y, 6, bg); - draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); - return; - case 4: - case 5: - cursor_pos -= 3; - buf[0] = ' '; - get_volume_string(note->volparam, note->voleffect, buf + 1); - draw_text(buf, x, y, vfg, bg); - draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); - return; - case 6: - case 7: - case 8: - cursor_pos -= 6; - sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); - draw_text(buf, x, y, 2, bg); - draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); - return; - case 9: - sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); - draw_text(buf, x, y, 0, 3); - return; - default: - /* bleh */ - fg = 6; - break; - } - - if (note->note) { - get_note_string(note->note, buf); - draw_text(buf, x, y, fg, bg); - } else if (note->instrument) { - buf[0] = ' '; - num99tostr(note->instrument, buf + 1); - draw_text(buf, x, y, fg, bg); - } else if (note->voleffect) { - buf[0] = ' '; - get_volume_string(note->volparam, note->voleffect, buf + 1); - draw_text(buf, x, y, vfg, bg); - } else if (note->effect || note->param) { - if (cursor_pos != 0) - fg = 2; - sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); - draw_text(buf, x, y, fg, bg); - } else { - buf[0] = buf[1] = buf[2] = 173; - buf[3] = 0; - draw_text(buf, x, y, fg, bg); - } + switch (note->voleffect) { + case VOLFX_VOLUME: + vfg = 2; + break; + case VOLFX_PANNING: + case VOLFX_NONE: + vfg = 1; + break; + } + + switch (cursor_pos) { + case 0: + vfg = fg = 0; + bg = 3; + break; + case 1: + get_note_string(note->note, buf); + draw_text(buf, x, y, 6, bg); + draw_char(buf[2], x + 2, y, 0, 3); + return; + case 2: + case 3: + cursor_pos -= 1; + buf[0] = ' '; + if (note->instrument) { + num99tostr(note->instrument, buf + 1); + } else { + buf[1] = buf[2] = 173; + buf[3] = 0; + } + draw_text(buf, x, y, 6, bg); + draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); + return; + case 4: + case 5: + cursor_pos -= 3; + buf[0] = ' '; + get_volume_string(note->volparam, note->voleffect, buf + 1); + draw_text(buf, x, y, vfg, bg); + draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); + return; + case 6: + case 7: + case 8: + cursor_pos -= 6; + sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); + draw_text(buf, x, y, 2, bg); + draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); + return; + case 9: + sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); + draw_text(buf, x, y, 0, 3); + return; + default: + /* bleh */ + fg = 6; + break; + } + + if (note->note) { + get_note_string(note->note, buf); + draw_text(buf, x, y, fg, bg); + } else if (note->instrument) { + buf[0] = ' '; + num99tostr(note->instrument, buf + 1); + draw_text(buf, x, y, fg, bg); + } else if (note->voleffect) { + buf[0] = ' '; + get_volume_string(note->volparam, note->voleffect, buf + 1); + draw_text(buf, x, y, vfg, bg); + } else if (note->effect || note->param) { + if (cursor_pos != 0) + fg = 2; + sprintf(buf, "%c%02X", get_effect_char(note->effect), note->param); + draw_text(buf, x, y, fg, bg); + } else { + buf[0] = buf[1] = buf[2] = 173; + buf[3] = 0; + draw_text(buf, x, y, fg, bg); + } } void draw_mask_3(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = {143, 143, 143, 0}; + char buf[] = {143, 143, 143, 0}; - switch (cursor_pos) { - case 0: case 1: - buf[0] = buf[1] = MASK_CHAR(MASK_NOTE, 0, 0); - buf[2] = MASK_CHAR(MASK_NOTE, 0, 1); - break; - case 2: case 3: - buf[1] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); - buf[2] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); - break; - case 4: case 5: - buf[1] = MASK_CHAR(MASK_VOLUME, 4, 0); - buf[2] = MASK_CHAR(MASK_VOLUME, 5, 0); - break; - case 6: case 7: case 8: - buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); - buf[1] = MASK_CHAR(MASK_EFFECT, 7, 0); - buf[2] = MASK_CHAR(MASK_EFFECT, 8, 0); - break; - }; + switch (cursor_pos) { + case 0: case 1: + buf[0] = buf[1] = MASK_CHAR(MASK_NOTE, 0, 0); + buf[2] = MASK_CHAR(MASK_NOTE, 0, 1); + break; + case 2: case 3: + buf[1] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); + buf[2] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); + break; + case 4: case 5: + buf[1] = MASK_CHAR(MASK_VOLUME, 4, 0); + buf[2] = MASK_CHAR(MASK_VOLUME, 5, 0); + break; + case 6: case 7: case 8: + buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); + buf[1] = MASK_CHAR(MASK_EFFECT, 7, 0); + buf[2] = MASK_CHAR(MASK_EFFECT, 8, 0); + break; + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -481,177 +488,177 @@ void draw_channel_header_2(int chan, int x, int y, int fg) { - char buf[4] = { '0' + chan / 10, '0' + chan % 10, 0 }; - draw_text(buf, x, y, fg, 1); + char buf[4] = { '0' + chan / 10, '0' + chan % 10, 0 }; + draw_text(buf, x, y, fg, 1); } static void draw_effect_2(int x, int y, const song_note_t *note, int cursor_pos, int bg) { - int fg = 2, fg1 = 10, fg2 = 10, bg1 = bg, bg2 = bg; + int fg = 2, fg1 = 10, fg2 = 10, bg1 = bg, bg2 = bg; - switch (cursor_pos) { - case 0: - fg = fg1 = fg2 = 0; - break; - case 6: - fg = 0; - bg = 3; - break; - case 7: - fg1 = 0; - bg1 = 3; - break; - case 8: - fg2 = 0; - bg2 = 3; - break; - case 9: - fg = fg1 = fg2 = 0; - bg = bg1 = bg2 = 3; - break; - } - draw_char(get_effect_char(note->effect), x, y, fg, bg); - draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], - hexdigits[note->param & 0xf], - x + 1, y, fg1, bg1, fg2, bg2); + switch (cursor_pos) { + case 0: + fg = fg1 = fg2 = 0; + break; + case 6: + fg = 0; + bg = 3; + break; + case 7: + fg1 = 0; + bg1 = 3; + break; + case 8: + fg2 = 0; + bg2 = 3; + break; + case 9: + fg = fg1 = fg2 = 0; + bg = bg1 = bg2 = 3; + break; + } + draw_char(get_effect_char(note->effect), x, y, fg, bg); + draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], + hexdigits[note->param & 0xf], + x + 1, y, fg1, bg1, fg2, bg2); } void draw_note_2(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) { - char buf[4]; - int vfg = 6; + char buf[4]; + int vfg = 6; - switch (note->voleffect) { - case VOLFX_VOLUME: - vfg = 2; - break; - case VOLFX_PANNING: - case VOLFX_NONE: - vfg = 1; - break; - } - - switch (cursor_pos) { - case 0: - vfg = fg = 0; - bg = 3; - case 1: /* Mini-accidentals on 2-col. view */ - get_note_string(note->note, buf); - draw_char(buf[0], x, y, fg, bg); - // XXX cut-and-paste hackjob programming... this code should only exist in one place - switch ((unsigned char) buf[0]) { - case '^': - case '~': - case 0xCD: // note off - case 0xAD: // dot (empty) - if (cursor_pos == 1) - draw_char(buf[1], x + 1, y, 0, 3); - else - draw_char(buf[1], x + 1, y, fg, bg); - break; - default: - draw_half_width_chars(buf[1], buf[2], x + 1, y, - fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); - break; - } - return; - /* - get_note_string_short(note->note, buf); - draw_char(buf[0], x, y, 6, bg); - draw_char(buf[1], x + 1, y, 0, 3); - return; - */ - case 2: - case 3: - cursor_pos -= 2; - if (note->instrument) { - num99tostr(note->instrument, buf); - } else { - buf[0] = buf[1] = 173; - buf[2] = 0; - } - draw_text(buf, x, y, 6, bg); - draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); - return; - case 4: - case 5: - cursor_pos -= 4; - get_volume_string(note->volparam, note->voleffect, buf); - draw_text(buf, x, y, vfg, bg); - draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); - return; - case 6: - case 7: - case 8: - case 9: - draw_effect_2(x, y, note, cursor_pos, bg); - return; - default: - /* bleh */ - fg = 6; - break; - } - - if (note->note) { - get_note_string(note->note, buf); - draw_char(buf[0], x, y, 6, bg); - switch ((unsigned char) buf[0]) { - case '^': - case '~': - case 0xCD: // note off - case 0xAD: // dot (empty) - if (cursor_pos == 1) - draw_char(buf[1], x + 1, y, 0, 3); - else - draw_char(buf[1], x + 1, y, fg, bg); - break; - default: - draw_half_width_chars(buf[1], buf[2], x + 1, y, - fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); - break; - } - /* - get_note_string_short(note->note, buf); - draw_text(buf, x, y, fg, bg); - */ - } else if (note->instrument) { - num99tostr(note->instrument, buf); - draw_text(buf, x, y, fg, bg); - } else if (note->voleffect) { - get_volume_string(note->volparam, note->voleffect, buf); - draw_text(buf, x, y, vfg, bg); - } else if (note->effect || note->param) { - draw_effect_2(x, y, note, cursor_pos, bg); - } else { - draw_char(173, x, y, fg, bg); - draw_char(173, x + 1, y, fg, bg); - } + switch (note->voleffect) { + case VOLFX_VOLUME: + vfg = 2; + break; + case VOLFX_PANNING: + case VOLFX_NONE: + vfg = 1; + break; + } + + switch (cursor_pos) { + case 0: + vfg = fg = 0; + bg = 3; + case 1: /* Mini-accidentals on 2-col. view */ + get_note_string(note->note, buf); + draw_char(buf[0], x, y, fg, bg); + // XXX cut-and-paste hackjob programming... this code should only exist in one place + switch ((unsigned char) buf[0]) { + case '^': + case '~': + case 0xCD: // note off + case 0xAD: // dot (empty) + if (cursor_pos == 1) + draw_char(buf[1], x + 1, y, 0, 3); + else + draw_char(buf[1], x + 1, y, fg, bg); + break; + default: + draw_half_width_chars(buf[1], buf[2], x + 1, y, + fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); + break; + } + return; + /* + get_note_string_short(note->note, buf); + draw_char(buf[0], x, y, 6, bg); + draw_char(buf[1], x + 1, y, 0, 3); + return; + */ + case 2: + case 3: + cursor_pos -= 2; + if (note->instrument) { + num99tostr(note->instrument, buf); + } else { + buf[0] = buf[1] = 173; + buf[2] = 0; + } + draw_text(buf, x, y, 6, bg); + draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); + return; + case 4: + case 5: + cursor_pos -= 4; + get_volume_string(note->volparam, note->voleffect, buf); + draw_text(buf, x, y, vfg, bg); + draw_char(buf[cursor_pos], x + cursor_pos, y, 0, 3); + return; + case 6: + case 7: + case 8: + case 9: + draw_effect_2(x, y, note, cursor_pos, bg); + return; + default: + /* bleh */ + fg = 6; + break; + } + + if (note->note) { + get_note_string(note->note, buf); + draw_char(buf[0], x, y, 6, bg); + switch ((unsigned char) buf[0]) { + case '^': + case '~': + case 0xCD: // note off + case 0xAD: // dot (empty) + if (cursor_pos == 1) + draw_char(buf[1], x + 1, y, 0, 3); + else + draw_char(buf[1], x + 1, y, fg, bg); + break; + default: + draw_half_width_chars(buf[1], buf[2], x + 1, y, + fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); + break; + } + /* + get_note_string_short(note->note, buf); + draw_text(buf, x, y, fg, bg); + */ + } else if (note->instrument) { + num99tostr(note->instrument, buf); + draw_text(buf, x, y, fg, bg); + } else if (note->voleffect) { + get_volume_string(note->volparam, note->voleffect, buf); + draw_text(buf, x, y, vfg, bg); + } else if (note->effect || note->param) { + draw_effect_2(x, y, note, cursor_pos, bg); + } else { + draw_char(173, x, y, fg, bg); + draw_char(173, x + 1, y, fg, bg); + } } void draw_mask_2(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = {143, 143, 0}; + char buf[] = {143, 143, 0}; - switch (cursor_pos) { - case 0: case 1: - buf[0] = MASK_CHAR(MASK_NOTE, 0, 0); - buf[1] = MASK_CHAR(MASK_NOTE, 0, 1); - break; - case 2: case 3: - buf[0] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); - buf[1] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); - break; - case 4: case 5: - buf[0] = MASK_CHAR(MASK_VOLUME, 4, 0); - buf[1] = MASK_CHAR(MASK_VOLUME, 5, 0); - break; - case 6: case 7: case 8: - buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); - buf[1] = MASK_CHAR(MASK_EFFECT, 7, 8); - break; - }; + switch (cursor_pos) { + case 0: case 1: + buf[0] = MASK_CHAR(MASK_NOTE, 0, 0); + buf[1] = MASK_CHAR(MASK_NOTE, 0, 1); + break; + case 2: case 3: + buf[0] = MASK_CHAR(MASK_INSTRUMENT, 2, 0); + buf[1] = MASK_CHAR(MASK_INSTRUMENT, 3, 0); + break; + case 4: case 5: + buf[0] = MASK_CHAR(MASK_VOLUME, 4, 0); + buf[1] = MASK_CHAR(MASK_VOLUME, 5, 0); + break; + case 6: case 7: case 8: + buf[0] = MASK_CHAR(MASK_EFFECT, 6, 0); + buf[1] = MASK_CHAR(MASK_EFFECT, 7, 8); + break; + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -660,131 +667,131 @@ void draw_channel_header_1(int chan, int x, int y, int fg) { - draw_half_width_chars('0' + chan / 10, '0' + chan % 10, x, y, fg, 1, fg, 1); + draw_half_width_chars('0' + chan / 10, '0' + chan % 10, x, y, fg, 1, fg, 1); } static void draw_effect_1(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) { - int fg1 = fg, fg2 = fg, bg1 = bg, bg2 = bg; + int fg1 = fg, fg2 = fg, bg1 = bg, bg2 = bg; - switch (cursor_pos) { - case 0: - break; - case 6: - fg = 0; - bg = 3; - break; - case 7: - fg1 = 0; - bg1 = 3; - break; - case 8: - fg2 = 0; - bg2 = 3; - break; - default: - fg = 2; - } - if (cursor_pos == 7 || cursor_pos == 8 || (note->effect == 0 && note->param != 0)) { - draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], - hexdigits[note-> param & 0xf], - x, y, fg1, bg1, fg2, bg2); - } else { - draw_char(get_effect_char(note->effect), x, y, fg, bg); - } + switch (cursor_pos) { + case 0: + break; + case 6: + fg = 0; + bg = 3; + break; + case 7: + fg1 = 0; + bg1 = 3; + break; + case 8: + fg2 = 0; + bg2 = 3; + break; + default: + fg = 2; + } + if (cursor_pos == 7 || cursor_pos == 8 || (note->effect == 0 && note->param != 0)) { + draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], + hexdigits[note-> param & 0xf], + x, y, fg1, bg1, fg2, bg2); + } else { + draw_char(get_effect_char(note->effect), x, y, fg, bg); + } } void draw_note_1(int x, int y, const song_note_t *note, int cursor_pos, int fg, int bg) { - char buf[4]; + char buf[4]; - switch (cursor_pos) { - case 0: - fg = 0; - bg = 3; - if (note->note > 0 && note->note <= 120) { - get_note_string_short(note->note, buf); - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); - return; - } - break; - case 1: - get_note_string_short(note->note, buf); - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); - return; - case 2: - case 3: - cursor_pos -= 2; - if (note->instrument) - num99tostr(note->instrument, buf); - else - buf[0] = buf[1] = 173; - if (cursor_pos == 0) - draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); - else - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); - return; - case 4: - case 5: - cursor_pos -= 4; - get_volume_string(note->volparam, note->voleffect, buf); - fg = note->voleffect == VOLFX_PANNING ? 1 : 2; - if (cursor_pos == 0) - draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); - else - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); - return; - case 9: - cursor_pos = 6; - // fall through - case 6: - case 7: - case 8: - draw_effect_1(x, y, note, cursor_pos, fg, bg); - return; - } - - if (note->note) { - get_note_string_short(note->note, buf); - draw_char(buf[0], x, y, fg, bg); - } else if (note->instrument) { - num99tostr(note->instrument, buf); - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); - } else if (note->voleffect) { - if (cursor_pos != 0) - fg = (note->voleffect == VOLFX_PANNING) ? 1 : 2; - get_volume_string(note->volparam, note->voleffect, buf); - draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); - } else if (note->effect || note->param) { - draw_effect_1(x, y, note, cursor_pos, fg, bg); - } else { - draw_char(173, x, y, fg, bg); - } + switch (cursor_pos) { + case 0: + fg = 0; + bg = 3; + if (note->note > 0 && note->note <= 120) { + get_note_string_short(note->note, buf); + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); + return; + } + break; + case 1: + get_note_string_short(note->note, buf); + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); + return; + case 2: + case 3: + cursor_pos -= 2; + if (note->instrument) + num99tostr(note->instrument, buf); + else + buf[0] = buf[1] = 173; + if (cursor_pos == 0) + draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); + else + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); + return; + case 4: + case 5: + cursor_pos -= 4; + get_volume_string(note->volparam, note->voleffect, buf); + fg = note->voleffect == VOLFX_PANNING ? 1 : 2; + if (cursor_pos == 0) + draw_half_width_chars(buf[0], buf[1], x, y, 0, 3, fg, bg); + else + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, 0, 3); + return; + case 9: + cursor_pos = 6; + // fall through + case 6: + case 7: + case 8: + draw_effect_1(x, y, note, cursor_pos, fg, bg); + return; + } + + if (note->note) { + get_note_string_short(note->note, buf); + draw_char(buf[0], x, y, fg, bg); + } else if (note->instrument) { + num99tostr(note->instrument, buf); + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); + } else if (note->voleffect) { + if (cursor_pos != 0) + fg = (note->voleffect == VOLFX_PANNING) ? 1 : 2; + get_volume_string(note->volparam, note->voleffect, buf); + draw_half_width_chars(buf[0], buf[1], x, y, fg, bg, fg, bg); + } else if (note->effect || note->param) { + draw_effect_1(x, y, note, cursor_pos, fg, bg); + } else { + draw_char(173, x, y, fg, bg); + } } void draw_mask_1(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char c = 143; + char c = 143; - switch (cursor_pos) { - case 0: case 1: - c = MASK_CHAR(MASK_NOTE, 0, 1); - break; - case 2: case 3: - c = MASK_CHAR(MASK_INSTRUMENT, 2, 3); - break; - case 4: case 5: - c = MASK_CHAR(MASK_VOLUME, 4, 5); - break; - case 6: - c = MASK_CHAR(MASK_EFFECT, 6, 0); - break; - case 7: case 8: - c = MASK_CHAR(MASK_EFFECT, 7, 8); - break; - }; + switch (cursor_pos) { + case 0: case 1: + c = MASK_CHAR(MASK_NOTE, 0, 1); + break; + case 2: case 3: + c = MASK_CHAR(MASK_INSTRUMENT, 2, 3); + break; + case 4: case 5: + c = MASK_CHAR(MASK_VOLUME, 4, 5); + break; + case 6: + c = MASK_CHAR(MASK_EFFECT, 6, 0); + break; + case 7: case 8: + c = MASK_CHAR(MASK_EFFECT, 7, 8); + break; + }; - draw_char(c, x, y, fg, bg); + draw_char(c, x, y, fg, bg); } /* --------------------------------------------------------------------- */ @@ -792,164 +799,164 @@ void draw_channel_header_6(int chan, int x, int y, int fg) { - char buf[8]; - sprintf(buf, "Chnl%02d", chan); - draw_text(buf, x, y, fg, 1); + char buf[8]; + sprintf(buf, "Chnl%02d", chan); + draw_text(buf, x, y, fg, 1); } void draw_note_6(int x, int y, const song_note_t *note, int cursor_pos, UNUSED int fg, int bg) { - char note_buf[4], ins_buf[3], vol_buf[3]; - int fg1, bg1, fg2, bg2; + char note_buf[4], ins_buf[3], vol_buf[3]; + int fg1, bg1, fg2, bg2; #ifdef USE_LOWERCASE_NOTES - get_note_string_short(note->note, note_buf); - if (note->instrument) - num99tostr(note->instrument, ins_buf); - else - ins_buf[0] = ins_buf[1] = 173; - /* note & instrument */ - draw_text(note_buf, x, y, 6, bg); - fg1 = fg2 = (note->instrument ? 10 : 2); - bg1 = bg2 = bg; - switch (cursor_pos) { - case 0: - draw_char(note_buf[0], x, y, 0, 3); - break; - case 1: - draw_char(note_buf[1], x + 1, y, 0, 3); - break; - case 2: - fg1 = 0; - bg1 = 3; - break; - case 3: - fg2 = 0; - bg2 = 3; - break; - } + get_note_string_short(note->note, note_buf); + if (note->instrument) + num99tostr(note->instrument, ins_buf); + else + ins_buf[0] = ins_buf[1] = 173; + /* note & instrument */ + draw_text(note_buf, x, y, 6, bg); + fg1 = fg2 = (note->instrument ? 10 : 2); + bg1 = bg2 = bg; + switch (cursor_pos) { + case 0: + draw_char(note_buf[0], x, y, 0, 3); + break; + case 1: + draw_char(note_buf[1], x + 1, y, 0, 3); + break; + case 2: + fg1 = 0; + bg1 = 3; + break; + case 3: + fg2 = 0; + bg2 = 3; + break; + } #else - get_note_string(note->note, note_buf); + get_note_string(note->note, note_buf); - if (cursor_pos == 0) - draw_char(note_buf[0], x, y, 0, 3); - else - draw_char(note_buf[0], x, y, fg, bg); - - bg1 = bg2 = bg; - switch ((unsigned char) note_buf[0]) { - case '^': - case '~': - case 0xCD: // note off - case 0xAD: // dot (empty) - if (cursor_pos == 1) - draw_char(note_buf[1], x + 1, y, 0, 3); - else - draw_char(note_buf[1], x + 1, y, fg, bg); - break; - default: - draw_half_width_chars(note_buf[1], note_buf[2], x + 1, y, - fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); - break; - } + if (cursor_pos == 0) + draw_char(note_buf[0], x, y, 0, 3); + else + draw_char(note_buf[0], x, y, fg, bg); + + bg1 = bg2 = bg; + switch ((unsigned char) note_buf[0]) { + case '^': + case '~': + case 0xCD: // note off + case 0xAD: // dot (empty) + if (cursor_pos == 1) + draw_char(note_buf[1], x + 1, y, 0, 3); + else + draw_char(note_buf[1], x + 1, y, fg, bg); + break; + default: + draw_half_width_chars(note_buf[1], note_buf[2], x + 1, y, + fg, bg, (cursor_pos == 1 ? 0 : fg), (cursor_pos == 1 ? 3 : bg)); + break; + } #endif - if (note->instrument) - num99tostr(note->instrument, ins_buf); - else - ins_buf[0] = ins_buf[1] = 173; - - fg1 = fg2 = (note->instrument ? 10 : 2); - bg1 = bg2 = bg; - switch (cursor_pos) { - case 2: - fg1 = 0; - bg1 = 3; - break; - case 3: - fg2 = 0; - bg2 = 3; - break; - } - - draw_half_width_chars(ins_buf[0], ins_buf[1], x + 2, y, fg1, bg1, fg2, bg2); - /* volume */ - get_volume_string(note->volparam, note->voleffect, vol_buf); - - switch (note->voleffect) { - case VOLFX_NONE: - fg1 = 6; - break; - case VOLFX_PANNING: - fg1 = 10; - break; - case VOLFX_TONEPORTAMENTO: - case VOLFX_VIBRATOSPEED: - case VOLFX_VIBRATODEPTH: - fg1 = 6; - break; - default: - fg1 = 12; - break; - } - fg2 = fg1; - bg1 = bg2 = bg; - - switch (cursor_pos) { - case 4: - fg1 = 0; - bg1 = 3; - break; - case 5: - fg2 = 0; - bg2 = 3; - break; - } - draw_half_width_chars(vol_buf[0], vol_buf[1], x + 3, y, fg1, bg1, fg2, bg2); - - /* effect value */ - fg1 = fg2 = 10; - bg1 = bg2 = bg; - switch (cursor_pos) { - case 7: - fg1 = 0; - bg1 = 3; - break; - case 8: - fg2 = 0; - bg2 = 3; - break; - case 9: - fg1 = fg2 = 0; - bg1 = bg2 = 3; - cursor_pos = 6; // hack - break; - } - draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], - hexdigits[note->param & 0xf], - x + 5, y, fg1, bg1, fg2, bg2); - - /* effect */ - draw_char(get_effect_char(note->effect), x + 4, y, - cursor_pos == 6 ? 0 : 2, cursor_pos == 6 ? 3 : bg); + if (note->instrument) + num99tostr(note->instrument, ins_buf); + else + ins_buf[0] = ins_buf[1] = 173; + + fg1 = fg2 = (note->instrument ? 10 : 2); + bg1 = bg2 = bg; + switch (cursor_pos) { + case 2: + fg1 = 0; + bg1 = 3; + break; + case 3: + fg2 = 0; + bg2 = 3; + break; + } + + draw_half_width_chars(ins_buf[0], ins_buf[1], x + 2, y, fg1, bg1, fg2, bg2); + /* volume */ + get_volume_string(note->volparam, note->voleffect, vol_buf); + + switch (note->voleffect) { + case VOLFX_NONE: + fg1 = 6; + break; + case VOLFX_PANNING: + fg1 = 10; + break; + case VOLFX_TONEPORTAMENTO: + case VOLFX_VIBRATOSPEED: + case VOLFX_VIBRATODEPTH: + fg1 = 6; + break; + default: + fg1 = 12; + break; + } + fg2 = fg1; + bg1 = bg2 = bg; + + switch (cursor_pos) { + case 4: + fg1 = 0; + bg1 = 3; + break; + case 5: + fg2 = 0; + bg2 = 3; + break; + } + draw_half_width_chars(vol_buf[0], vol_buf[1], x + 3, y, fg1, bg1, fg2, bg2); + + /* effect value */ + fg1 = fg2 = 10; + bg1 = bg2 = bg; + switch (cursor_pos) { + case 7: + fg1 = 0; + bg1 = 3; + break; + case 8: + fg2 = 0; + bg2 = 3; + break; + case 9: + fg1 = fg2 = 0; + bg1 = bg2 = 3; + cursor_pos = 6; // hack + break; + } + draw_half_width_chars(hexdigits[(note->param & 0xf0) >> 4], + hexdigits[note->param & 0xf], + x + 5, y, fg1, bg1, fg2, bg2); + + /* effect */ + draw_char(get_effect_char(note->effect), x + 4, y, + cursor_pos == 6 ? 0 : 2, cursor_pos == 6 ? 3 : bg); } void draw_mask_6(int x, int y, int mask, int cursor_pos, int fg, int bg) { - char buf[] = { - MASK_CHAR(MASK_NOTE, 0, 0), - MASK_CHAR(MASK_NOTE, 0, 1), - MASK_CHAR(MASK_INSTRUMENT, 2, 3), - MASK_CHAR(MASK_VOLUME, 4, 5), - MASK_CHAR(MASK_EFFECT, 6, 0), - MASK_CHAR(MASK_EFFECT, 7, 8), - 0, - }; + char buf[] = { + MASK_CHAR(MASK_NOTE, 0, 0), + MASK_CHAR(MASK_NOTE, 0, 1), + MASK_CHAR(MASK_INSTRUMENT, 2, 3), + MASK_CHAR(MASK_VOLUME, 4, 5), + MASK_CHAR(MASK_EFFECT, 6, 0), + MASK_CHAR(MASK_EFFECT, 7, 8), + 0, + }; - draw_text(buf, x, y, fg, bg); + draw_text(buf, x, y, fg, bg); } diff -Nru schism-0+20110101/schism/sample-edit.c schism-20160521/schism/sample-edit.c --- schism-0+20110101/schism/sample-edit.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/sample-edit.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include "it.h" #include "util.h" #include "song.h" +#include "cmixer.h" #include "sample-edit.h" #include "sdlmain.h" @@ -35,32 +36,32 @@ static void _minmax_8(signed char *data, unsigned long length, signed char *min, signed char *max) { - unsigned long pos = length; + unsigned long pos = length; - *min = 127; - *max = -128; - while (pos) { - pos--; - if (data[pos] < *min) - *min = data[pos]; - else if (data[pos] > *max) - *max = data[pos]; - } + *min = 127; + *max = -128; + while (pos) { + pos--; + if (data[pos] < *min) + *min = data[pos]; + else if (data[pos] > *max) + *max = data[pos]; + } } static void _minmax_16(signed short *data, unsigned long length, signed short *min, signed short *max) { - unsigned long pos = length; + unsigned long pos = length; - *min = 32767; - *max = -32768; - while (pos) { - pos--; - if (data[pos] < *min) - *min = data[pos]; - else if (data[pos] > *max) - *max = data[pos]; - } + *min = 32767; + *max = -32768; + while (pos) { + pos--; + if (data[pos] < *min) + *min = data[pos]; + else if (data[pos] > *max) + *max = data[pos]; + } } /* --------------------------------------------------------------------- */ @@ -68,34 +69,34 @@ static void _sign_convert_8(signed char *data, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - data[pos] += 128; - } + while (pos) { + pos--; + data[pos] += 128; + } } static void _sign_convert_16(signed short *data, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - data[pos] += 32768; - } + while (pos) { + pos--; + data[pos] += 32768; + } } void sample_sign_convert(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_16BIT) - _sign_convert_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - else - _sign_convert_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_16BIT) + _sign_convert_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + else + _sign_convert_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + song_unlock_audio(); } /* --------------------------------------------------------------------- */ @@ -103,73 +104,73 @@ static void _reverse_8(signed char *data, unsigned long length) { - signed char tmp; - unsigned long lpos = 0, rpos = length - 1; + signed char tmp; + unsigned long lpos = 0, rpos = length - 1; - while (lpos < rpos) { - tmp = data[lpos]; - data[lpos] = data[rpos]; - data[rpos] = tmp; - lpos++; - rpos--; - } + while (lpos < rpos) { + tmp = data[lpos]; + data[lpos] = data[rpos]; + data[rpos] = tmp; + lpos++; + rpos--; + } } static void _reverse_16(signed short *data, unsigned long length) { - signed short tmp; - unsigned long lpos = 0, rpos = length - 1; + signed short tmp; + unsigned long lpos = 0, rpos = length - 1; - while (lpos < rpos) { - tmp = data[lpos]; - data[lpos] = data[rpos]; - data[rpos] = tmp; - lpos++; - rpos--; - } + while (lpos < rpos) { + tmp = data[lpos]; + data[lpos] = data[rpos]; + data[rpos] = tmp; + lpos++; + rpos--; + } } static void _reverse_32(signed int *data, unsigned long length) { - signed int tmp; - unsigned long lpos = 0, rpos = length - 1; + signed int tmp; + unsigned long lpos = 0, rpos = length - 1; - while (lpos < rpos) { - tmp = data[lpos]; - data[lpos] = data[rpos]; - data[rpos] = tmp; - lpos++; - rpos--; - } + while (lpos < rpos) { + tmp = data[lpos]; + data[lpos] = data[rpos]; + data[rpos] = tmp; + lpos++; + rpos--; + } } void sample_reverse(song_sample_t * sample) { - unsigned long tmp; + unsigned long tmp; - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_STEREO) { - if (sample->flags & CHN_16BIT) - _reverse_32((signed int *)sample->data, sample->length); - else - _reverse_16((signed short *) sample->data, sample->length); - } else { - if (sample->flags & CHN_16BIT) - _reverse_16((signed short *) sample->data, sample->length); - else - _reverse_8(sample->data, sample->length); - } - - tmp = sample->length - sample->loop_start; - sample->loop_start = sample->length - sample->loop_end; - sample->loop_end = tmp; - - tmp = sample->length - sample->sustain_start; - sample->sustain_start = sample->length - sample->sustain_end; - sample->sustain_end = tmp; + if (sample->flags & CHN_STEREO) { + if (sample->flags & CHN_16BIT) + _reverse_32((signed int *)sample->data, sample->length); + else + _reverse_16((signed short *) sample->data, sample->length); + } else { + if (sample->flags & CHN_16BIT) + _reverse_16((signed short *) sample->data, sample->length); + else + _reverse_8(sample->data, sample->length); + } + + tmp = sample->length - sample->loop_start; + sample->loop_start = sample->length - sample->loop_end; + sample->loop_end = tmp; + + tmp = sample->length - sample->sustain_start; + sample->sustain_start = sample->length - sample->sustain_end; + sample->sustain_end = tmp; - song_unlock_audio(); + song_unlock_audio(); } /* --------------------------------------------------------------------- */ @@ -180,65 +181,65 @@ static void _quality_convert_8to16(signed char *idata, signed short *odata, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - odata[pos] = idata[pos] << 8; - } + while (pos) { + pos--; + odata[pos] = idata[pos] << 8; + } } static void _quality_convert_16to8(signed short *idata, signed char *odata, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - odata[pos] = idata[pos] >> 8; - } + while (pos) { + pos--; + odata[pos] = idata[pos] >> 8; + } } void sample_toggle_quality(song_sample_t * sample, int convert_data) { - signed char *odata; + signed char *odata; - song_lock_audio(); + song_lock_audio(); - // stop playing the sample because we'll be reallocating and/or changing lengths - csf_stop_sample(current_song, sample); + // stop playing the sample because we'll be reallocating and/or changing lengths + csf_stop_sample(current_song, sample); - sample->flags ^= CHN_16BIT; + sample->flags ^= CHN_16BIT; - status.flags |= SONG_NEEDS_SAVE; - if (convert_data) { - odata = csf_allocate_sample(sample->length - * ((sample->flags & CHN_16BIT) ? 2 : 1) - * ((sample->flags & CHN_STEREO) ? 2 : 1)); - if (sample->flags & CHN_16BIT) { - _quality_convert_8to16(sample->data, (signed short *) odata, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - } else { - _quality_convert_16to8((signed short *) sample->data, odata, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - } - csf_free_sample(sample->data); - sample->data = odata; - } else { - if (sample->flags & CHN_16BIT) { - sample->length >>= 1; - sample->loop_start >>= 1; - sample->loop_end >>= 1; - sample->sustain_start >>= 1; - sample->sustain_end >>= 1; - } else { - sample->length <<= 1; - sample->loop_start <<= 1; - sample->loop_end <<= 1; - sample->sustain_start <<= 1; - sample->sustain_end <<= 1; - } - } - song_unlock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (convert_data) { + odata = csf_allocate_sample(sample->length + * ((sample->flags & CHN_16BIT) ? 2 : 1) + * ((sample->flags & CHN_STEREO) ? 2 : 1)); + if (sample->flags & CHN_16BIT) { + _quality_convert_8to16(sample->data, (signed short *) odata, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + } else { + _quality_convert_16to8((signed short *) sample->data, odata, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + } + csf_free_sample(sample->data); + sample->data = odata; + } else { + if (sample->flags & CHN_16BIT) { + sample->length >>= 1; + sample->loop_start >>= 1; + sample->loop_end >>= 1; + sample->sustain_start >>= 1; + sample->sustain_end >>= 1; + } else { + sample->length <<= 1; + sample->loop_start <<= 1; + sample->loop_end <<= 1; + sample->sustain_start <<= 1; + sample->sustain_end <<= 1; + } + } + song_unlock_audio(); } /* --------------------------------------------------------------------- */ @@ -246,60 +247,60 @@ static void _centralise_8(signed char *data, unsigned long length) { - unsigned long pos = length; - signed char min, max; - int offset; - - _minmax_8(data, length, &min, &max); - - offset = (max + min + 1) >> 1; - if (offset == 0) - return; - - pos = length; - while (pos) { - pos--; - data[pos] -= offset; - } + unsigned long pos = length; + signed char min, max; + int offset; + + _minmax_8(data, length, &min, &max); + + offset = (max + min + 1) >> 1; + if (offset == 0) + return; + + pos = length; + while (pos) { + pos--; + data[pos] -= offset; + } } static void _centralise_16(signed short *data, unsigned long length) { - unsigned long pos = length; - signed short min, max; - int offset; - - _minmax_16(data, length, &min, &max); - - while (pos) { - pos--; - if (data[pos] < min) - min = data[pos]; - else if (data[pos] > max) - max = data[pos]; - } - - offset = (max + min + 1) >> 1; - if (offset == 0) - return; - - pos = length; - while (pos) { - pos--; - data[pos] -= offset; - } + unsigned long pos = length; + signed short min, max; + int offset; + + _minmax_16(data, length, &min, &max); + + while (pos) { + pos--; + if (data[pos] < min) + min = data[pos]; + else if (data[pos] > max) + max = data[pos]; + } + + offset = (max + min + 1) >> 1; + if (offset == 0) + return; + + pos = length; + while (pos) { + pos--; + data[pos] -= offset; + } } void sample_centralise(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_16BIT) - _centralise_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - else - _centralise_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_16BIT) + _centralise_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + else + _centralise_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + song_unlock_audio(); } /* --------------------------------------------------------------------- */ @@ -307,69 +308,69 @@ static void _amplify_8(signed char *data, unsigned long length, int percent) { - unsigned long pos = length; - int b; + unsigned long pos = length; + int b; - while (pos) { - pos--; - b = data[pos] * percent / 100; - data[pos] = CLAMP(b, -128, 127); - } + while (pos) { + pos--; + b = data[pos] * percent / 100; + data[pos] = CLAMP(b, -128, 127); + } } static void _amplify_16(signed short *data, unsigned long length, int percent) { - unsigned long pos = length; - int b; + unsigned long pos = length; + int b; - while (pos) { - pos--; - b = data[pos] * percent / 100; - data[pos] = CLAMP(b, -32768, 32767); - } + while (pos) { + pos--; + b = data[pos] * percent / 100; + data[pos] = CLAMP(b, -32768, 32767); + } } void sample_amplify(song_sample_t * sample, int percent) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_16BIT) - _amplify_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1), percent); - else - _amplify_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1), percent); - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_16BIT) + _amplify_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1), percent); + else + _amplify_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1), percent); + song_unlock_audio(); } static int _get_amplify_8(signed char *data, unsigned long length) { - signed char min, max; - _minmax_8(data, length, &min, &max); - max = MAX(max, -min); - return max ? 128 * 100 / max : 100; + signed char min, max; + _minmax_8(data, length, &min, &max); + max = MAX(max, -min); + return max ? 128 * 100 / max : 100; } static int _get_amplify_16(signed short *data, unsigned long length) { - signed short min, max; - _minmax_16(data, length, &min, &max); - max = MAX(max, -min); - return max ? 32768 * 100 / max : 100; + signed short min, max; + _minmax_16(data, length, &min, &max); + max = MAX(max, -min); + return max ? 32768 * 100 / max : 100; } int sample_get_amplify_amount(song_sample_t *sample) { - int percent; + int percent; - if (sample->flags & CHN_16BIT) - percent = _get_amplify_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - else - percent = _get_amplify_8(sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + if (sample->flags & CHN_16BIT) + percent = _get_amplify_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + else + percent = _get_amplify_8(sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - if (percent < 100) percent = 100; - return percent; + if (percent < 100) percent = 100; + return percent; } /* --------------------------------------------------------------------- */ @@ -377,38 +378,38 @@ static void _delta_decode_8(signed char *data, unsigned long length) { - unsigned long pos; - signed char o = 0, n; + unsigned long pos; + signed char o = 0, n; - for (pos = 1; pos < length; pos++) { - n = data[pos] + o; - data[pos] = n; - o = n; - } + for (pos = 1; pos < length; pos++) { + n = data[pos] + o; + data[pos] = n; + o = n; + } } static void _delta_decode_16(signed short *data, unsigned long length) { - unsigned long pos; - signed short o = 0, n; + unsigned long pos; + signed short o = 0, n; - for (pos = 1; pos < length; pos++) { - n = data[pos] + o; - data[pos] = n; - o = n; - } + for (pos = 1; pos < length; pos++) { + n = data[pos] + o; + data[pos] = n; + o = n; + } } void sample_delta_decode(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_16BIT) - _delta_decode_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - else - _delta_decode_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_16BIT) + _delta_decode_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + else + _delta_decode_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + song_unlock_audio(); } /* --------------------------------------------------------------------- */ @@ -416,206 +417,186 @@ static void _invert_8(signed char *data, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - data[pos] = ~data[pos]; - } + while (pos) { + pos--; + data[pos] = ~data[pos]; + } } static void _invert_16(signed short *data, unsigned long length) { - unsigned long pos = length; + unsigned long pos = length; - while (pos) { - pos--; - data[pos] = ~data[pos]; - } + while (pos) { + pos--; + data[pos] = ~data[pos]; + } } -/* why is newlen unsigned long, but oldlen is unsigned int? just curious. */ + static void _resize_16(signed short *dst, unsigned long newlen, - signed short *src, unsigned int oldlen) + signed short *src, unsigned long oldlen, unsigned int is_stereo) { - unsigned int i; - for (i = 0; i < newlen; i++) - dst[i] = src[(unsigned int)((double)i * ((double)oldlen / (double)newlen))]; + unsigned int i; + double factor = (double)oldlen / (double)newlen; + if (is_stereo) for (i = 0; i < newlen; i++) + { + unsigned int pos = 2*(unsigned int)((double)i * factor); + dst[2*i] = src[pos]; + dst[2*i+1] = src[pos+1]; + } + else for (i = 0; i < newlen; i++) + { + dst[i] = src[(unsigned int)((double)i * factor)]; + } } static void _resize_8(signed char *dst, unsigned long newlen, - signed char *src, unsigned int oldlen) + signed char *src, unsigned long oldlen, unsigned int is_stereo) { - unsigned int i; - for (i = 0; i < newlen; i++) - dst[i] = src[(unsigned int)((double)i * ((double)oldlen / (double)newlen))]; + unsigned int i; + double factor = (double)oldlen / (double)newlen; + if (is_stereo) { + for (i = 0; i < newlen; i++) { + unsigned int pos = 2*(unsigned int)((double)i * factor); + dst[2*i] = src[pos]; + dst[2*i+1] = src[pos+1]; + } + } else { + for (i = 0; i < newlen; i++) { + dst[i] = src[(unsigned int)((double)i * factor)]; + } + } } static void _resize_8aa(signed char *dst, unsigned long newlen, - signed char *src, unsigned int oldlen) + signed char *src, unsigned long oldlen, unsigned int is_stereo) { - int avg_acc = 0; - int avg_count = 0; - unsigned long i, j; - /* what is cp? should it be unsigned? -storlek */ - int cp; - int old_pos = -1; - for (i = 0; i < oldlen; i++) { - cp = (int)((double)i * ((double)newlen) / (double)oldlen); - if (cp < 0) cp = 0; - if (cp > old_pos) { - if (old_pos >= 0 && cp >= 0 && (unsigned long) cp < newlen) { - for (j = 0; j < (unsigned long) (cp - old_pos); j++) { - dst[old_pos+j] = avg_acc/avg_count; - } - } - avg_count = 0; - avg_acc = 0; - old_pos = cp; - } - avg_count ++; - avg_acc += src[i]; - } - for (j = 0; j < (newlen-old_pos); j++) { - dst[old_pos+j] = avg_acc/avg_count; - } + if (is_stereo) + ResampleStereo8BitFirFilter(src, dst, oldlen, newlen); + else + ResampleMono8BitFirFilter(src, dst, oldlen, newlen); } static void _resize_16aa(signed short *dst, unsigned long newlen, - signed short *src, unsigned int oldlen) + signed short *src, unsigned long oldlen, unsigned int is_stereo) { - int avg_acc = 0; - int avg_count = 0; - int i, j, cp; - int old_pos = -1; - for (i = 0; (unsigned int) i < oldlen; i++) { - /* cast-o-matic! */ - cp = (int)((double)i * ((double)newlen) / (double)oldlen); - if (cp < 0) cp = 0; - if (cp > old_pos) { - if (old_pos >= 0 && cp >= 0 && (unsigned long) cp < newlen) { - for (j = 0; j < (cp-old_pos); j++) { - dst[old_pos+j] = avg_acc/avg_count; - } - } - avg_count = 0; - avg_acc = 0; - old_pos = cp; - } - avg_count ++; - avg_acc += src[i]; - } + if (is_stereo) + ResampleStereo16BitFirFilter(src, dst, oldlen, newlen); + else + ResampleMono16BitFirFilter(src, dst, oldlen, newlen); } void sample_resize(song_sample_t * sample, unsigned long newlen, int aa) { - int bps; - unsigned char *d, *z; - unsigned long oldlen; - - if (!newlen) return; - if (!sample->data || !sample->length) return; - - song_lock_audio(); - - /* resizing samples while they're playing keeps crashing things. - so here's my "fix": stop the song. --plusminus */ - // I suppose that works, but it's slightly annoying, so I'll just stop the sample... - // hopefully this won't (re)introduce crashes. --Storlek - csf_stop_sample(current_song, sample); - - bps = (((sample->flags & CHN_STEREO) ? 2 : 1) - * ((sample->flags & CHN_16BIT) ? 2 : 1)); - - status.flags |= SONG_NEEDS_SAVE; - - d = (unsigned char *) csf_allocate_sample(newlen*bps); - z = (unsigned char *) sample->data; - - sample->c5speed = (unsigned long)((((double)newlen) * ((double)sample->c5speed)) - / ((double)sample->length)); - - /* scale loop points */ - sample->loop_start = (unsigned long)((((double)newlen) * ((double)sample->loop_start)) - / ((double)sample->length)); - sample->loop_end = (unsigned long)((((double)newlen) * ((double)sample->loop_end)) - / ((double)sample->length)); - sample->sustain_start = (unsigned long)((((double)newlen) * ((double)sample->sustain_start)) - / ((double)sample->length)); - sample->sustain_end = (unsigned long)((((double)newlen) * ((double)sample->sustain_end)) - / ((double)sample->length)); - - oldlen = sample->length; - sample->length = newlen; - if (sample->flags & CHN_STEREO) { newlen *= 2; oldlen *= 2; } - - if (sample->flags & CHN_16BIT) { - if (aa) { - _resize_16aa((signed short *) d, newlen, (short *)sample->data, oldlen); - } else { - _resize_16((signed short *) d, newlen, (short *)sample->data, oldlen); - } - } else { - if (aa) { - _resize_8aa((signed char *) d, newlen, sample->data, oldlen); - } else { - _resize_8((signed char *) d, newlen, sample->data, oldlen); - } - } - - sample->data = (signed char *) d; - csf_free_sample((signed char *) z); - song_unlock_audio(); + int bps; + signed char *d, *z; + unsigned long oldlen; + + if (!newlen) return; + if (!sample->data || !sample->length) return; + + song_lock_audio(); + + /* resizing samples while they're playing keeps crashing things. + so here's my "fix": stop the song. --plusminus */ + // I suppose that works, but it's slightly annoying, so I'll just stop the sample... + // hopefully this won't (re)introduce crashes. --Storlek + csf_stop_sample(current_song, sample); + + bps = (((sample->flags & CHN_STEREO) ? 2 : 1) + * ((sample->flags & CHN_16BIT) ? 2 : 1)); + + status.flags |= SONG_NEEDS_SAVE; + + d = csf_allocate_sample(newlen*bps); + z = sample->data; + + sample->c5speed = (unsigned long)((((double)newlen) * ((double)sample->c5speed)) + / ((double)sample->length)); + + /* scale loop points */ + sample->loop_start = (unsigned long)((((double)newlen) * ((double)sample->loop_start)) + / ((double)sample->length)); + sample->loop_end = (unsigned long)((((double)newlen) * ((double)sample->loop_end)) + / ((double)sample->length)); + sample->sustain_start = (unsigned long)((((double)newlen) * ((double)sample->sustain_start)) + / ((double)sample->length)); + sample->sustain_end = (unsigned long)((((double)newlen) * ((double)sample->sustain_end)) + / ((double)sample->length)); + + oldlen = sample->length; + sample->length = newlen; + + if (sample->flags & CHN_16BIT) { + if (aa) { + _resize_16aa((signed short *) d, newlen, (short *) sample->data, oldlen, sample->flags & CHN_STEREO); + } else { + _resize_16((signed short *) d, newlen, (short *) sample->data, oldlen, sample->flags & CHN_STEREO); + } + } else { + if (aa) { + _resize_8aa(d, newlen, sample->data, oldlen, sample->flags & CHN_STEREO); + } else { + _resize_8(d, newlen, sample->data, oldlen, sample->flags & CHN_STEREO); + } + } + + sample->data = d; + csf_free_sample(z); + song_unlock_audio(); } void sample_invert(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_16BIT) - _invert_16((signed short *) sample->data, - sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - else - _invert_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_16BIT) + _invert_16((signed short *) sample->data, + sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + else + _invert_8(sample->data, sample->length * ((sample->flags & CHN_STEREO) ? 2 : 1)); + song_unlock_audio(); } static void _mono_lr16(signed short *data, unsigned long length, int shift) { - unsigned long i, j; - if (shift) memmove(data, data+shift, 2*(length-(shift * sizeof(short)))); - for (j = 0, i = 1; j < length; j++, i += 2) - data[j] = data[i]; + unsigned long i=1, j; + if (shift) { i=0; } + for (j = 0; j < length; j++, i += 2) + data[j] = data[i]; } static void _mono_lr8(signed char *data, unsigned long length, int shift) { - unsigned long i, j; - if (shift) memmove(data, data+shift, 2*(length-shift)); - for (j = 0, i = 1; j < length; j++, i += 2) - data[j] = data[i]; + unsigned long i=1, j; + if (shift) { i=0; } + for (j = 0; j < length; j++, i += 2) + data[j] = data[i]; } void sample_mono_left(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_STEREO) { - if (sample->flags & CHN_16BIT) - _mono_lr16((signed short *)sample->data, sample->length, 1); - else - _mono_lr8((signed char *)sample->data, sample->length, 1); - sample->flags &= ~CHN_STEREO; - } - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_STEREO) { + if (sample->flags & CHN_16BIT) + _mono_lr16((signed short *)sample->data, sample->length, 1); + else + _mono_lr8((signed char *)sample->data, sample->length, 1); + sample->flags &= ~CHN_STEREO; + } + song_unlock_audio(); } void sample_mono_right(song_sample_t * sample) { - song_lock_audio(); - status.flags |= SONG_NEEDS_SAVE; - if (sample->flags & CHN_STEREO) { - if (sample->flags & CHN_16BIT) - _mono_lr16((signed short *)sample->data, sample->length, 0); - else - _mono_lr8((signed char *)sample->data, sample->length, 0); - sample->flags &= ~CHN_STEREO; - } - song_unlock_audio(); + song_lock_audio(); + status.flags |= SONG_NEEDS_SAVE; + if (sample->flags & CHN_STEREO) { + if (sample->flags & CHN_16BIT) + _mono_lr16((signed short *)sample->data, sample->length, 0); + else + _mono_lr8((signed char *)sample->data, sample->length, 0); + sample->flags &= ~CHN_STEREO; + } + song_unlock_audio(); } diff -Nru schism-0+20110101/schism/sample-view.c schism-20160521/schism/sample-view.c --- schism-0+20110101/schism/sample-view.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/sample-view.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,8 @@ #include "sdlmain.h" +#include + #define SAMPLE_DATA_COLOR 13 /* Sample data */ #define SAMPLE_LOOP_COLOR 3 /* Sample loop marks */ #define SAMPLE_MARK_COLOR 6 /* Play mark color */ @@ -41,82 +43,100 @@ - the type of 'data' - the amount to divide (note though, this number is used twice!) -fakemono is 2 when drawing the mono oscilloscope in the top status section, 1 otherwise */ +output channels = number of oscis +input channels = number of channels in data +*/ static void _draw_sample_data_8(struct vgamem_overlay *r, - signed char *data, unsigned long length, int channels, int fakemono) + signed char *data, unsigned long length, unsigned int inputchans, unsigned int outputchans) { - unsigned long pos; - int level, xs, ys, xe, ye, step; - int nh, cc, np; - int chip; - - nh = (r->height / channels); - np = r->height - (nh / 2); - - length /= channels; - chip = (length < (unsigned int) r->width * 2); - - for (cc = 0; cc < channels; cc++) { - pos = 0; - step = MAX(1, (length / r->width) >> 8); - - level = data[(pos * channels * fakemono) + cc] * nh / (SCHAR_MAX - SCHAR_MIN + 1); - xs = 0; - ys = (np - 1) - level; - ys = CLAMP(ys, 0, r->height - 1); - do { - pos += step; - level = data[(pos * channels * fakemono) + cc] * nh / (SCHAR_MAX - SCHAR_MIN + 1); - xe = pos * r->width / length; - ye = (np - 1) - level; - xe = CLAMP(xe, 0, r->width - 1); - ye = CLAMP(ye, 0, r->height - 1); - // 'ye' is more or less useless for small samples, but this is much cleaner - // code than writing nearly the same loop four different times :P - vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, SAMPLE_DATA_COLOR); - xs = xe; - ys = ye; - } while (pos < length); - np -= nh; - } + unsigned long pos; + unsigned int cc, co; + int level, xs, ys, xe, ye, step; + int nh, np; + int chip; + + nh = (r->height / outputchans); + np = r->height - (nh / 2); + + length /= inputchans; + chip = (length < (unsigned int) r->width * 2); + + for (cc = 0; cc < outputchans; cc++) { + pos = 0; + co = 0; + step = MAX(1, (length / r->width) >> 8); + level=0; + do { + level+=ceil(data[(pos * inputchans) + cc+co] * nh / (float)(SCHAR_MAX - SCHAR_MIN + 1)); + } while (co++ < inputchans-outputchans); + xs = 0; + ys = (np - 1) - level; + ys = CLAMP(ys, 0, r->height - 1); + do { + pos += step; + co = 0; + level=0; + do { + level+=ceil(data[(pos * inputchans) + cc+co] * nh / (SCHAR_MAX - SCHAR_MIN + 1)); + } while (co++ < inputchans-outputchans); + xe = pos * r->width / length; + ye = (np - 1) - level; + xe = CLAMP(xe, 0, r->width - 1); + ye = CLAMP(ye, 0, r->height - 1); + // 'ye' is more or less useless for small samples, but this is much cleaner + // code than writing nearly the same loop four different times :P + vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, SAMPLE_DATA_COLOR); + xs = xe; + ys = ye; + } while (pos < length); + np -= nh; + } } static void _draw_sample_data_16(struct vgamem_overlay *r, - signed short *data, unsigned long length, int channels, int fakemono) + signed short *data, unsigned long length, unsigned int inputchans, unsigned int outputchans) { - unsigned long pos; - int level, xs, ys, xe, ye, step; - int nh, cc, np; - int chip; - - nh = (r->height / channels); - np = r->height - (nh / 2); - - length /= channels; - chip = (length < (unsigned int) r->width * 2); - - for (cc = 0; cc < channels; cc++) { - pos = 0; - step = MAX(1, (length / r->width) >> 8); - - level = data[(pos * channels * fakemono) + cc] * nh / (SHRT_MAX - SHRT_MIN + 1); - xs = 0; - ys = (np - 1) - level; - ys = CLAMP(ys, 0, r->height - 1); - do { - pos += step; - level = data[(pos * channels * fakemono) + cc] * nh / (SHRT_MAX - SHRT_MIN + 1); - xe = pos * r->width / length; - ye = (np - 1) - level; - xe = CLAMP(xe, 0, r->width - 1); - ye = CLAMP(ye, 0, r->height - 1); - vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, SAMPLE_DATA_COLOR); - xs = xe; - ys = ye; - } while (pos < length); - np -= nh; - } + unsigned long pos; + unsigned int cc, co; + int level, xs, ys, xe, ye, step; + int nh, np; + int chip; + + nh = (r->height / outputchans); + np = r->height - (nh / 2); + + length /= inputchans; + chip = (length < (unsigned int) r->width * 2); + + for (cc = 0; cc < outputchans; cc++) { + pos = 0; + co = 0; + step = MAX(1, (length / r->width) >> 8); + level=0; + do { + level += ceil(data[(pos * inputchans) + cc+co] * nh / (float)(SHRT_MAX - SHRT_MIN + 1)); + } while(co++ < inputchans-outputchans); + xs = 0; + ys = (np - 1) - level; + ys = CLAMP(ys, 0, r->height - 1); + do { + pos += step; + co = 0; + level = 0; + do { + level = ceil(data[(pos * inputchans) + cc+co] * nh / (float)(SHRT_MAX - SHRT_MIN + 1)); + } while (co++ < inputchans-outputchans); + xe = pos * r->width / length; + ye = (np - 1) - level; + xe = CLAMP(xe, 0, r->width - 1); + ye = CLAMP(ye, 0, r->height - 1); + vgamem_ovl_drawline(r, xs, ys, xe, chip ? ys : ye, SAMPLE_DATA_COLOR); + xs = xe; + ys = ye; + } while (pos < length); + np -= nh; + } } /* --------------------------------------------------------------------- */ @@ -125,161 +145,159 @@ /* loop drawing */ static void _draw_sample_loop(struct vgamem_overlay *r, song_sample_t * sample) { - int loopstart, loopend, y; - int c = ((status.flags & CLASSIC_MODE) ? SAMPLE_DATA_COLOR : SAMPLE_LOOP_COLOR); + int loopstart, loopend, y; + int c = ((status.flags & CLASSIC_MODE) ? SAMPLE_DATA_COLOR : SAMPLE_LOOP_COLOR); - if (!(sample->flags & CHN_LOOP)) - return; + if (!(sample->flags & CHN_LOOP)) + return; - loopstart = sample->loop_start * (r->width - 1) / sample->length; - loopend = sample->loop_end * (r->width - 1) / sample->length; + loopstart = sample->loop_start * (r->width - 1) / sample->length; + loopend = sample->loop_end * (r->width - 1) / sample->length; - y = 0; - do { - vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; - vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; - vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; - vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; - } while (y < r->height); + y = 0; + do { + vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; + vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; + vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; + vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; + } while (y < r->height); } static void _draw_sample_susloop(struct vgamem_overlay *r, song_sample_t * sample) { - int loopstart, loopend, y; - int c = ((status.flags & CLASSIC_MODE) ? SAMPLE_DATA_COLOR : SAMPLE_LOOP_COLOR); + int loopstart, loopend, y; + int c = ((status.flags & CLASSIC_MODE) ? SAMPLE_DATA_COLOR : SAMPLE_LOOP_COLOR); - if (!(sample->flags & CHN_SUSTAINLOOP)) - return; + if (!(sample->flags & CHN_SUSTAINLOOP)) + return; - loopstart = sample->sustain_start * (r->width - 1) / sample->length; - loopend = sample->sustain_end * (r->width - 1) / sample->length; + loopstart = sample->sustain_start * (r->width - 1) / sample->length; + loopend = sample->sustain_end * (r->width - 1) / sample->length; - y = 0; - do { - vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; - vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; - vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; - vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; - } while (y < r->height); + y = 0; + do { + vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; + vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; + vgamem_ovl_drawpixel(r, loopstart, y, c); vgamem_ovl_drawpixel(r, loopend, y, c); y++; + vgamem_ovl_drawpixel(r, loopstart, y, 0); vgamem_ovl_drawpixel(r, loopend, y, 0); y++; + } while (y < r->height); } /* this does the lines for playing samples */ static void _draw_sample_play_marks(struct vgamem_overlay *r, song_sample_t * sample) { - int n, x, y; - int c; - song_voice_t *channel; - unsigned int *channel_list; - - if (song_get_mode() == MODE_STOPPED) - return; - - song_lock_audio(); - - n = song_get_mix_state(&channel_list); - while (n--) { - channel = song_get_mix_channel(channel_list[n]); - if (channel->current_sample_data != sample->data) - continue; - if (!channel->final_volume) continue; - c = (channel->flags & (CHN_KEYOFF | CHN_NOTEFADE)) ? SAMPLE_BGMARK_COLOR : SAMPLE_MARK_COLOR; - x = channel->position * (r->width - 1) / sample->length; - if (x >= r->width) { - /* this does, in fact, happen :( */ - continue; - } - y = 0; - do { - /* unrolled 8 times */ - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - vgamem_ovl_drawpixel(r, x, y++, c); - } while (y < r->height); - } + int n, x, y; + int c; + song_voice_t *channel; + unsigned int *channel_list; + + if (song_get_mode() == MODE_STOPPED) + return; + + song_lock_audio(); + + n = song_get_mix_state(&channel_list); + while (n--) { + channel = song_get_mix_channel(channel_list[n]); + if (channel->current_sample_data != sample->data) + continue; + if (!channel->final_volume) continue; + c = (channel->flags & (CHN_KEYOFF | CHN_NOTEFADE)) ? SAMPLE_BGMARK_COLOR : SAMPLE_MARK_COLOR; + x = channel->position * (r->width - 1) / sample->length; + if (x >= r->width) { + /* this does, in fact, happen :( */ + continue; + } + y = 0; + do { + /* unrolled 8 times */ + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + vgamem_ovl_drawpixel(r, x, y++, c); + } while (y < r->height); + } - song_unlock_audio(); + song_unlock_audio(); } /* --------------------------------------------------------------------- */ /* meat! */ -/* use sample #0 for the sample library -what was n for? can we get rid of it? */ -void draw_sample_data(struct vgamem_overlay *r, song_sample_t *sample, UNUSED int n) +void draw_sample_data(struct vgamem_overlay *r, song_sample_t *sample) { - vgamem_ovl_clear(r, 0); + vgamem_ovl_clear(r, 0); - if(sample->flags & CHN_ADLIB) - { - vgamem_ovl_clear(r, 2); - vgamem_ovl_apply(r); - char Buf1[32], Buf2[32]; - - int y1 = r->y1, y2 = y1+3; - - draw_box(59,y1, 77,y2, BOX_THICK | BOX_INNER | BOX_INSET); // data - draw_box(54,y1, 58,y2, BOX_THIN | BOX_INNER | BOX_OUTSET); // button - draw_text_len("Mod", 3, 55,y1+1, 0,2); - draw_text_len("Car", 3, 55,y1+2, 0,2); - - sprintf(Buf1, "%02X %02X %02X %02X %02X %02X", // length:6*3-1=17 - sample->adlib_bytes[0], - sample->adlib_bytes[2], - sample->adlib_bytes[4], - sample->adlib_bytes[6], - sample->adlib_bytes[8], - sample->adlib_bytes[10]); - sprintf(Buf2, "%02X %02X %02X %02X %02X", // length: 5*3-1=14 - sample->adlib_bytes[1], - sample->adlib_bytes[3], - sample->adlib_bytes[5], - sample->adlib_bytes[7], - sample->adlib_bytes[9]); - draw_text_len(Buf1, 17, 60,y1+1, 2,0); - draw_text_len(Buf2, 17, 60,y1+2, 2,0); - return; - } - - if (!sample->length) { - vgamem_ovl_apply(r); - return; - } - - /* do the actual drawing */ - if (sample->flags & CHN_16BIT) - _draw_sample_data_16(r, (signed short *) sample->data, - sample->length * (sample->flags & CHN_STEREO ? 2 : 1), - sample->flags & CHN_STEREO ? 2 : 1, 1); - else - _draw_sample_data_8(r, sample->data, - sample->length * (sample->flags & CHN_STEREO ? 2 : 1), - sample->flags & CHN_STEREO ? 2 : 1, 1); - - if ((status.flags & CLASSIC_MODE) == 0) - _draw_sample_play_marks(r, sample); - _draw_sample_loop(r, sample); - _draw_sample_susloop(r, sample); - vgamem_ovl_apply(r); + if (sample->flags & CHN_ADLIB) { + vgamem_ovl_clear(r, 2); + vgamem_ovl_apply(r); + char buf1[32], buf2[32]; + + int y1 = r->y1, y2 = y1+3; + + draw_box(59,y1, 77,y2, BOX_THICK | BOX_INNER | BOX_INSET); // data + draw_box(54,y1, 58,y2, BOX_THIN | BOX_INNER | BOX_OUTSET); // button + draw_text_len("Mod", 3, 55,y1+1, 0,2); + draw_text_len("Car", 3, 55,y1+2, 0,2); + + sprintf(buf1, "%02X %02X %02X %02X %02X %02X", // length:6*3-1=17 + sample->adlib_bytes[0], + sample->adlib_bytes[2], + sample->adlib_bytes[4], + sample->adlib_bytes[6], + sample->adlib_bytes[8], + sample->adlib_bytes[10]); + sprintf(buf2, "%02X %02X %02X %02X %02X", // length: 5*3-1=14 + sample->adlib_bytes[1], + sample->adlib_bytes[3], + sample->adlib_bytes[5], + sample->adlib_bytes[7], + sample->adlib_bytes[9]); + draw_text_len(buf1, 17, 60,y1+1, 2,0); + draw_text_len(buf2, 17, 60,y1+2, 2,0); + return; + } + + if (!sample->length || !sample->data) { + vgamem_ovl_apply(r); + return; + } + + /* do the actual drawing */ + int chans = sample->flags & CHN_STEREO ? 2 : 1; + if (sample->flags & CHN_16BIT) + _draw_sample_data_16(r, (signed short *) sample->data, + sample->length * chans, + chans, chans); + else + _draw_sample_data_8(r, sample->data, + sample->length * chans, + chans, chans); + + if ((status.flags & CLASSIC_MODE) == 0) + _draw_sample_play_marks(r, sample); + _draw_sample_loop(r, sample); + _draw_sample_susloop(r, sample); + vgamem_ovl_apply(r); } void draw_sample_data_rect_16(struct vgamem_overlay *r, signed short *data, - int length, unsigned int channels, int fakemono) + int length, unsigned int inputchans, unsigned int outputchans) { - vgamem_ovl_clear(r, 0); - _draw_sample_data_16(r, data, length, channels, fakemono); - vgamem_ovl_apply(r); + vgamem_ovl_clear(r, 0); + _draw_sample_data_16(r, data, length, inputchans, outputchans); + vgamem_ovl_apply(r); } void draw_sample_data_rect_8(struct vgamem_overlay *r, signed char *data, - int length, unsigned int channels, int fakemono) + int length, unsigned int inputchans, unsigned int outputchans) { - vgamem_ovl_clear(r, 0); - _draw_sample_data_8(r, data, length, channels, fakemono); - vgamem_ovl_apply(r); + vgamem_ovl_clear(r, 0); + _draw_sample_data_8(r, data, length, inputchans, outputchans); + vgamem_ovl_apply(r); } diff -Nru schism-0+20110101/schism/slurp.c schism-20160521/schism/slurp.c --- schism-0+20110101/schism/slurp.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/slurp.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -55,7 +55,7 @@ static void _slurp_closure_free(slurp_t *t) { - free(t->data); + free(t->data); } /* --------------------------------------------------------------------- */ @@ -76,99 +76,99 @@ static int _slurp_stdio_pipe(slurp_t * t, int fd) { - int old_errno; - FILE *fp; - uint8_t *read_buf, *realloc_buf; - size_t this_len; - int chunks = 0; - - t->data = NULL; - fp = fdopen(dup(fd), "rb"); - if (fp == NULL) - return 0; - - do { - chunks++; - /* Have to cast away the const... */ - realloc_buf = realloc((void *) t->data, CHUNK * chunks); - if (realloc_buf == NULL) { - old_errno = errno; - fclose(fp); - free(t->data); - errno = old_errno; - return 0; - } - t->data = realloc_buf; - read_buf = (void *) (t->data + (CHUNK * (chunks - 1))); - this_len = fread(read_buf, 1, CHUNK, fp); - if (this_len <= 0) { - if (ferror(fp)) { - old_errno = errno; - fclose(fp); - free(t->data); - errno = old_errno; - return 0; - } - } - t->length += this_len; - } while (this_len); - fclose(fp); - t->closure = _slurp_closure_free; - return 1; + int old_errno; + FILE *fp; + uint8_t *read_buf, *realloc_buf; + size_t this_len; + int chunks = 0; + + t->data = NULL; + fp = fdopen(dup(fd), "rb"); + if (fp == NULL) + return 0; + + do { + chunks++; + /* Have to cast away the const... */ + realloc_buf = realloc((void *) t->data, CHUNK * chunks); + if (realloc_buf == NULL) { + old_errno = errno; + fclose(fp); + free(t->data); + errno = old_errno; + return 0; + } + t->data = realloc_buf; + read_buf = (void *) (t->data + (CHUNK * (chunks - 1))); + this_len = fread(read_buf, 1, CHUNK, fp); + if (this_len <= 0) { + if (ferror(fp)) { + old_errno = errno; + fclose(fp); + free(t->data); + errno = old_errno; + return 0; + } + } + t->length += this_len; + } while (this_len); + fclose(fp); + t->closure = _slurp_closure_free; + return 1; } static int _slurp_stdio(slurp_t * t, int fd) { - int old_errno; - FILE *fp; - size_t got = 0, need, len; - - if (t->length == 0) { - /* Hrmph. Probably a pipe or something... gotta do it the REALLY ugly way. */ - return _slurp_stdio_pipe(t, fd); - } - - fp = fdopen(dup(fd), "rb"); - - if (!fp) - return 0; - - t->data = (uint8_t *) malloc(t->length); - if (t->data == NULL) { - old_errno = errno; - fclose(fp); - errno = old_errno; - return 0; - } - - /* Read the WHOLE thing -- fread might not get it all at once, - * so keep trying until it returns zero. */ - need = t->length; - do { - len = fread(t->data + got, 1, need, fp); - if (len <= 0) { - if (ferror(fp)) { - old_errno = errno; - fclose(fp); - free(t->data); - errno = old_errno; - return 0; - } - - if (need > 0) { - /* short file */ - need = 0; - t->length = got; - } - } else { - got += len; - need -= len; - } - } while (need > 0); - - fclose(fp); - t->closure = _slurp_closure_free; - return 1; + int old_errno; + FILE *fp; + size_t got = 0, need, len; + + if (t->length == 0) { + /* Hrmph. Probably a pipe or something... gotta do it the REALLY ugly way. */ + return _slurp_stdio_pipe(t, fd); + } + + fp = fdopen(dup(fd), "rb"); + + if (!fp) + return 0; + + t->data = (uint8_t *) malloc(t->length); + if (t->data == NULL) { + old_errno = errno; + fclose(fp); + errno = old_errno; + return 0; + } + + /* Read the WHOLE thing -- fread might not get it all at once, + * so keep trying until it returns zero. */ + need = t->length; + do { + len = fread(t->data + got, 1, need, fp); + if (len <= 0) { + if (ferror(fp)) { + old_errno = errno; + fclose(fp); + free(t->data); + errno = old_errno; + return 0; + } + + if (need > 0) { + /* short file */ + need = 0; + t->length = got; + } + } else { + got += len; + need -= len; + } + } while (need > 0); + + fclose(fp); + t->closure = _slurp_closure_free; + return 1; } @@ -176,152 +176,152 @@ static slurp_t *_slurp_open(const char *filename, struct stat * buf, size_t size) { - slurp_t *t; - int fd, old_errno; + slurp_t *t; + int fd, old_errno; - if (buf && S_ISDIR(buf->st_mode)) { - errno = EISDIR; - return NULL; - } - - t = (slurp_t *) mem_alloc(sizeof(slurp_t)); - if (t == NULL) - return NULL; - t->pos = 0; - - if (strcmp(filename, "-") == 0) { - if (_slurp_stdio(t, STDIN_FILENO)) - return t; - free(t); - return NULL; - } - - if (size <= 0) { - size = (buf ? buf->st_size : file_size(filename)); - } + if (buf && S_ISDIR(buf->st_mode)) { + errno = EISDIR; + return NULL; + } + + t = (slurp_t *) mem_alloc(sizeof(slurp_t)); + if (t == NULL) + return NULL; + t->pos = 0; + + if (strcmp(filename, "-") == 0) { + if (_slurp_stdio(t, STDIN_FILENO)) + return t; + free(t); + return NULL; + } + + if (size <= 0) { + size = (buf ? buf->st_size : file_size(filename)); + } #ifdef WIN32 - switch (slurp_win32(t, filename, size)) { - case 0: free(t); return NULL; - case 1: return t; - }; + switch (slurp_win32(t, filename, size)) { + case 0: free(t); return NULL; + case 1: return t; + }; #endif #if HAVE_MMAP - switch (slurp_mmap(t, filename, size)) { - case 0: free(t); return NULL; - case 1: return t; - }; + switch (slurp_mmap(t, filename, size)) { + case 0: free(t); return NULL; + case 1: return t; + }; #endif - fd = open(filename, O_RDONLY | O_BINARY); + fd = open(filename, O_RDONLY | O_BINARY); - if (fd < 0) { - free(t); - return NULL; - } - - t->length = size; - - if (_slurp_stdio(t, fd)) { - close(fd); - return t; - } - - old_errno = errno; - close(fd); - free(t); - errno = old_errno; - return NULL; + if (fd < 0) { + free(t); + return NULL; + } + + t->length = size; + + if (_slurp_stdio(t, fd)) { + close(fd); + return t; + } + + old_errno = errno; + close(fd); + free(t); + errno = old_errno; + return NULL; } slurp_t *slurp(const char *filename, struct stat * buf, size_t size) { - slurp_t *t = _slurp_open(filename, buf, size); - uint8_t *mmdata; - size_t mmlen; - - if (!t) { - return NULL; - } - - mmdata = t->data; - mmlen = t->length; - if (mmcmp_unpack(&mmdata, &mmlen)) { - // clean up the existing data - if (t->data && t->closure) { - t->closure(t); - } - // and put the new stuff in - t->length = mmlen; - t->data = mmdata; - t->closure = _slurp_closure_free; - } + slurp_t *t = _slurp_open(filename, buf, size); + uint8_t *mmdata; + size_t mmlen; + + if (!t) { + return NULL; + } + + mmdata = t->data; + mmlen = t->length; + if (mmcmp_unpack(&mmdata, &mmlen)) { + // clean up the existing data + if (t->data && t->closure) { + t->closure(t); + } + // and put the new stuff in + t->length = mmlen; + t->data = mmdata; + t->closure = _slurp_closure_free; + } - // TODO re-add PP20 unpacker, possibly also handle other formats? + // TODO re-add PP20 unpacker, possibly also handle other formats? - return t; + return t; } void unslurp(slurp_t * t) { - if (!t) - return; - if (t->data && t->closure) { - t->closure(t); - } - free(t); + if (!t) + return; + if (t->data && t->closure) { + t->closure(t); + } + free(t); } /* --------------------------------------------------------------------- */ int slurp_seek(slurp_t *t, long offset, int whence) { - switch (whence) { - default: - case SEEK_SET: - break; - case SEEK_CUR: - offset += t->pos; - break; - case SEEK_END: - offset += t->length; - break; - } - if (offset < 0 || (size_t) offset > t->length) - return -1; - t->pos = offset; - return 0; + switch (whence) { + default: + case SEEK_SET: + break; + case SEEK_CUR: + offset += t->pos; + break; + case SEEK_END: + offset += t->length; + break; + } + if (offset < 0 || (size_t) offset > t->length) + return -1; + t->pos = offset; + return 0; } long slurp_tell(slurp_t *t) { - return (long) t->pos; + return (long) t->pos; } size_t slurp_read(slurp_t *t, void *ptr, size_t count) { - size_t bytesleft = t->length - t->pos; - if (count > bytesleft) { - // short read -- fill in any extra bytes with zeroes - size_t tail = count - bytesleft; - count = bytesleft; - memset(ptr + count, 0, tail); - } - if (count) - memcpy(ptr, t->data + t->pos, count); - t->pos += count; - return count; + size_t bytesleft = t->length - t->pos; + if (count > bytesleft) { + // short read -- fill in any extra bytes with zeroes + size_t tail = count - bytesleft; + count = bytesleft; + memset(ptr + count, 0, tail); + } + if (count) + memcpy(ptr, t->data + t->pos, count); + t->pos += count; + return count; } int slurp_getc(slurp_t *t) { - return (t->pos < t->length) ? t->data[t->pos++] : EOF; + return (t->pos < t->length) ? t->data[t->pos++] : EOF; } int slurp_eof(slurp_t *t) { - return t->pos >= t->length; + return t->pos >= t->length; } diff -Nru schism-0+20110101/schism/status.c schism-20160521/schism/status.c --- schism-0+20110101/schism/status.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/status.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -44,145 +44,145 @@ void status_text_flash(const char *format, ...) { - va_list ap; + va_list ap; - text_timeout = SDL_GetTicks() + 1000; + text_timeout = SDL_GetTicks() + 1000; - if (status_text) - free(status_text); + if (status_text) + free(status_text); - status_bios = 0; - va_start(ap, format); - if (vasprintf(&status_text, format, ap) == -1) abort(); - va_end(ap); + status_bios = 0; + va_start(ap, format); + if (vasprintf(&status_text, format, ap) == -1) abort(); + va_end(ap); - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } void status_text_flash_bios(const char *format, ...) { - va_list ap; + va_list ap; - text_timeout = SDL_GetTicks() + 1000; + text_timeout = SDL_GetTicks() + 1000; - if (status_text) - free(status_text); + if (status_text) + free(status_text); - status_bios = 1; - va_start(ap, format); - if (vasprintf(&status_text, format, ap) == -1) abort(); - va_end(ap); + status_bios = 1; + va_start(ap, format); + if (vasprintf(&status_text, format, ap) == -1) abort(); + va_end(ap); - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ static inline int _loop_count(char *buf, int pos) { - if (current_song->repeat_count < 1 || (status.flags & CLASSIC_MODE)) { - pos += draw_text("Playing", pos, 9, 0, 2); - } else { - pos += draw_text("Loop: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, current_song->repeat_count, buf), pos, 9, 3, 2); - } - return pos; + if (current_song->repeat_count < 1 || (status.flags & CLASSIC_MODE)) { + pos += draw_text("Playing", pos, 9, 0, 2); + } else { + pos += draw_text("Loop: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, current_song->repeat_count, buf), pos, 9, 3, 2); + } + return pos; } static inline void draw_song_playing_status(void) { - int pos = 2; - char buf[16]; - int pattern = song_get_playing_pattern(); - - pos = _loop_count(buf, pos); - pos += draw_text(", Order: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, song_get_current_order(), buf), pos, 9, 3, 2); - draw_char('/', pos, 9, 0, 2); - pos++; - pos += draw_text(numtostr(0, csf_last_order(current_song), buf), pos, 9, 3, 2); - pos += draw_text(", Pattern: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2); - pos += draw_text(", Row: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2); - draw_char('/', pos, 9, 0, 2); - pos++; - pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2); - draw_char(',', pos, 9, 0, 2); - pos++; - draw_char(0, pos, 9, 0, 2); - pos++; - pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); + int pos = 2; + char buf[16]; + int pattern = song_get_playing_pattern(); + + pos = _loop_count(buf, pos); + pos += draw_text(", Order: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, song_get_current_order(), buf), pos, 9, 3, 2); + draw_char('/', pos, 9, 0, 2); + pos++; + pos += draw_text(numtostr(0, csf_last_order(current_song), buf), pos, 9, 3, 2); + pos += draw_text(", Pattern: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2); + pos += draw_text(", Row: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2); + draw_char('/', pos, 9, 0, 2); + pos++; + pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2); + draw_char(',', pos, 9, 0, 2); + pos++; + draw_char(0, pos, 9, 0, 2); + pos++; + pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); - if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9) - draw_char(16, 61, 9, 1, 2); + if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9) + draw_char(16, 61, 9, 1, 2); } static inline void draw_pattern_playing_status(void) { - int pos = 2; - char buf[16]; - int pattern = song_get_playing_pattern(); - - pos = _loop_count(buf, pos); - pos += draw_text(", Pattern: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2); - pos += draw_text(", Row: ", pos, 9, 0, 2); - pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2); - draw_char('/', pos, 9, 0, 2); - pos++; - pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2); - draw_char(',', pos, 9, 0, 2); - pos++; - draw_char(0, pos, 9, 0, 2); - pos++; - pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); + int pos = 2; + char buf[16]; + int pattern = song_get_playing_pattern(); + + pos = _loop_count(buf, pos); + pos += draw_text(", Pattern: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2); + pos += draw_text(", Row: ", pos, 9, 0, 2); + pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2); + draw_char('/', pos, 9, 0, 2); + pos++; + pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2); + draw_char(',', pos, 9, 0, 2); + pos++; + draw_char(0, pos, 9, 0, 2); + pos++; + pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); - if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9) - draw_char(16, 61, 9, 1, 2); + if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9) + draw_char(16, 61, 9, 1, 2); } static inline void draw_playing_channels(void) { - int pos = 2; - char buf[16]; + int pos = 2; + char buf[16]; - pos += draw_text("Playing, ", 2, 9, 0, 2); - pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); - draw_text(" Channels", pos, 9, 0, 2); + pos += draw_text("Playing, ", 2, 9, 0, 2); + pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2); + draw_text(" Channels", pos, 9, 0, 2); } void status_text_redraw(void) { - uint32_t now = SDL_GetTicks(); + uint32_t now = SDL_GetTicks(); - /* if there's a message set, and it's expired, clear it */ - if (status_text && now > text_timeout) { - free(status_text); - status_text = NULL; - } - - if (status_text) { - if (status_bios) { - draw_text_bios_len(status_text, 60, 2, 9, 0, 2); - } else { - draw_text_len(status_text, 60, 2, 9, 0, 2); - } - } else { - switch (song_get_mode()) { - case MODE_PLAYING: - draw_song_playing_status(); - break; - case MODE_PATTERN_LOOP: - draw_pattern_playing_status(); - break; - case MODE_SINGLE_STEP: - if (song_get_playing_channels() > 1) { - draw_playing_channels(); - break; - } - default: - break; - } - } + /* if there's a message set, and it's expired, clear it */ + if (status_text && now > text_timeout) { + free(status_text); + status_text = NULL; + } + + if (status_text) { + if (status_bios) { + draw_text_bios_len(status_text, 60, 2, 9, 0, 2); + } else { + draw_text_len(status_text, 60, 2, 9, 0, 2); + } + } else { + switch (song_get_mode()) { + case MODE_PLAYING: + draw_song_playing_status(); + break; + case MODE_PATTERN_LOOP: + draw_pattern_playing_status(); + break; + case MODE_SINGLE_STEP: + if (song_get_playing_channels() > 1) { + draw_playing_channels(); + break; + } + default: + break; + } + } } diff -Nru schism-0+20110101/schism/tree.c schism-20160521/schism/tree.c --- schism-0+20110101/schism/tree.c 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/schism/tree.c 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,230 @@ +/* + * Schism Tracker - a cross-platform Impulse Tracker clone + * copyright (c) 2003-2005 Storlek + * copyright (c) 2005-2008 Mrs. Brisby + * copyright (c) 2009 Storlek & Mrs. Brisby + * copyright (c) 2010-2012 Storlek + * URL: http://schismtracker.org/ + * + * 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 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "tree.h" + + +typedef struct treenode { + struct treenode *left, *right; + void *value; +} treenode_t; + +struct tree { + treecmp_t cmp; + treenode_t *root; +}; + +typedef void (*nodewalk_t) (treenode_t *node); + + +static void _treenode_walk(treenode_t *node, treewalk_t tapply, nodewalk_t napply) +{ + // IF IF IF IF IF + + if (!node) + return; + if (node->left) + _treenode_walk(node->left, tapply, napply); + if (node->right) + _treenode_walk(node->right, tapply, napply); + if (tapply) + tapply(node->value); + if (napply) + napply(node); +} + +static void _treenode_free(treenode_t *node) +{ + free(node); +} + +tree_t *tree_alloc(treecmp_t cmp) +{ + tree_t *tree = malloc(sizeof(tree_t)); + tree->cmp = cmp; + tree->root = NULL; + return tree; +} + +void tree_free(tree_t *tree, treewalk_t freeval) +{ + _treenode_walk(tree->root, freeval, _treenode_free); + free(tree); +} + + +static treenode_t *_treenode_find(treenode_t *node, treecmp_t cmp, void *value) +{ + int r; + + while (node) { + r = cmp(value, node->value); + if (r == 0) + break; + else if (r < 0) + node = node->left; + else + node = node->right; + } + return node; +} + +static treenode_t *_treenode_insert(treenode_t *node, treecmp_t cmp, treenode_t *new) +{ + int r; + + if (!node) + return new; + + r = cmp(new->value, node->value); + if (r < 0) + node->left = _treenode_insert(node->left, cmp, new); + else + node->right = _treenode_insert(node->right, cmp, new); + return node; +} + +void tree_walk(tree_t *tree, treewalk_t apply) +{ + _treenode_walk(tree->root, apply, NULL); +} + + +void *tree_insert(tree_t *tree, void *value) +{ + treenode_t *node = _treenode_find(tree->root, tree->cmp, value); + + if (node) + return node->value; + + node = malloc(sizeof(treenode_t)); + node->left = node->right = NULL; + node->value = value; + tree->root = _treenode_insert(tree->root, tree->cmp, node); + return NULL; +} + +void *tree_replace(tree_t *tree, void *value) +{ + void *prev; + treenode_t *node = _treenode_find(tree->root, tree->cmp, value); + + if (node) { + prev = node->value; + node->value = value; + return prev; + } + + node = malloc(sizeof(treenode_t)); + node->left = node->right = NULL; + node->value = value; + tree->root = _treenode_insert(tree->root, tree->cmp, node); + return NULL; +} + +void *tree_find(tree_t *tree, void *value) +{ + treenode_t *node = _treenode_find(tree->root, tree->cmp, value); + return node ? node->value : NULL; +} + + + + +#ifdef TEST +#include +#include + +struct node { + char *k, *v; +}; + +int sncmp(const void *a, const void *b) +{ + return strcmp(((struct node *) a)->k, + ((struct node *) b)->k); +} + +struct node *snalloc(char *k, char *v) +{ + struct node *n = malloc(sizeof(struct node)); + n->k = k; + n->v = v; + return n; +} + +int main(int argc, char **argv) +{ + // some random junk + struct node nodes[] = { + {"caches", "disgruntled"}, + {"logician", "daemon"}, + {"silence", "rinse"}, + {"shipwreck", "formats"}, + {"justifying", "gnash"}, + {"gadgetry", "ever"}, + {"silence", "oxidized"}, // note: duplicate key + {"plumbing", "rickshaw"}, + {NULL, NULL}, + }; + struct node find; + struct node *p; + tree_t *tree; + int n; + + // test 1: populate with tree_insert + tree = tree_alloc(sncmp); + for (n = 0; nodes[n].k; n++) { + p = snalloc(nodes[n].k, nodes[n].v); + if (tree_insert(tree, p)) { + printf("duplicate key %s\n", p->k); + free(p); + } + } + find.k = "silence"; + p = tree_find(tree, &find); + printf("%s: %s (should be 'rinse')\n", p->k, p->v); + tree_free(tree, free); + + + // test 2: populate with tree_replace + tree = tree_alloc(sncmp); + for (n = 0; nodes[n].k; n++) { + p = snalloc(nodes[n].k, nodes[n].v); + p = tree_replace(tree, p); + if (p) { + printf("duplicate key %s\n", p->k); + free(p); + } + } + find.k = "silence"; + p = tree_find(tree, &find); + printf("%s: %s (should be 'oxidized')\n", p->k, p->v); + tree_free(tree, free); + + return 0; +} +#endif /* TEST */ + diff -Nru schism-0+20110101/schism/util.c schism-20160521/schism/util.c --- schism-0+20110101/schism/util.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/util.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -39,6 +39,8 @@ #include +#include + #if defined(__amigaos4__) # define FALLBACK_DIR "." /* not used... */ #elif defined(WIN32) @@ -61,125 +63,194 @@ void ms_sleep(unsigned int ms) { #ifdef WIN32 - SleepEx(ms,FALSE); + SleepEx(ms,FALSE); #else - usleep(ms*1000); + usleep(ms*1000); #endif } char *str_dup(const char *s) { - char *q; - q = strdup(s); - if (!q) { - /* throw out of memory exception */ - perror("strdup"); - exit(255); - } - return q; + char *q; + q = strdup(s); + if (!q) { + /* throw out of memory exception */ + perror("strdup"); + exit(255); + } + return q; } void *mem_alloc(size_t amount) { - void *q; - q = malloc(amount); - if (!q) { - /* throw out of memory exception */ - perror("malloc"); - exit(255); - } - return q; + void *q; + q = malloc(amount); + if (!q) { + /* throw out of memory exception */ + perror("malloc"); + exit(255); + } + return q; } void *mem_realloc(void *orig, size_t amount) { - void *q; - if (!orig) return mem_alloc(amount); - q = realloc(orig, amount); - if (!q) { - /* throw out of memory exception */ - perror("malloc"); - exit(255); - } - return q; + void *q; + if (!orig) return mem_alloc(amount); + q = realloc(orig, amount); + if (!q) { + /* throw out of memory exception */ + perror("malloc"); + exit(255); + } + return q; +} + + +/* --------------------------------------------------------------------- */ +/* CONVERSION FUNCTIONS */ + +/* linear -> deciBell */ +/* amplitude normalized to 1.0f. */ +float dB(float amplitude) +{ + return 20.0f * log10f(amplitude); +} + +/* deciBell -> linear */ +float dB2_amp(float db) +{ + return powf(10.0f, db / 20.0f); +} + +/* linear -> deciBell */ +/* power normalized to 1.0f. */ +float pdB(float power) +{ + return 10.0f * log10f(power); } +/* deciBell -> linear */ +float dB2_power(float db) +{ + return powf(10.0f, db / 10.0f); +} +/* linear -> deciBell */ +/* amplitude normalized to 1.0f. */ +/* Output scaled (and clipped) to 128 lines with noisefloor range. */ +/* ([0..128] = [-noisefloor..0dB]) */ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +short dB_s(int noisefloor, float amplitude, float correction_dBs) +{ + float db = dB(amplitude) + correction_dBs; + return CLAMP((int)(128.f*(db+noisefloor))/noisefloor, 0, 127); +} + +/* deciBell -> linear */ +/* Input scaled to 128 lines with noisefloor range. */ +/* ([0..128] = [-noisefloor..0dB]) */ +/* amplitude normalized to 1.0f. */ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +short dB2_amp_s(int noisefloor, int db, float correction_dBs) +{ + return dB2_amp((db*noisefloor/128.f)-noisefloor-correction_dBs); +} +/* linear -> deciBell */ +/* power normalized to 1.0f. */ +/* Output scaled (and clipped) to 128 lines with noisefloor range. */ +/* ([0..128] = [-noisefloor..0dB]) */ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +short pdB_s(int noisefloor, float power, float correction_dBs) +{ + float db = pdB(power)+correction_dBs; + return CLAMP((int)(128.f*(db+noisefloor))/noisefloor, 0, 127); +} + +/* deciBell -> linear */ +/* Input scaled to 128 lines with noisefloor range. */ +/* ([0..128] = [-noisefloor..0dB]) */ +/* power normalized to 1.0f. */ +/* correction_dBs corrects the dB after converted, but before scaling.*/ +short dB2_power_s(int noisefloor, int db, float correction_dBs) +{ + return dB2_power((db*noisefloor/128.f)-noisefloor-correction_dBs); +} /* --------------------------------------------------------------------- */ /* FORMATTING FUNCTIONS */ char *get_date_string(time_t when, char *buf) { - struct tm tmr; - const char *month_str[12] = { - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - }; - - /* DO NOT change this back to localtime(). If some backward platform - doesn't have localtime_r, it needs to be implemented separately. */ - localtime_r(&when, &tmr); - snprintf(buf, 27, "%s %d, %d", month_str[tmr.tm_mon], tmr.tm_mday, 1900 + tmr.tm_year); - return buf; + struct tm tmr; + const char *month_str[12] = { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + }; + + /* DO NOT change this back to localtime(). If some backward platform + doesn't have localtime_r, it needs to be implemented separately. */ + localtime_r(&when, &tmr); + snprintf(buf, 27, "%s %d, %d", month_str[tmr.tm_mon], tmr.tm_mday, 1900 + tmr.tm_year); + return buf; } char *get_time_string(time_t when, char *buf) { - struct tm tmr; + struct tm tmr; - localtime_r(&when, &tmr); - snprintf(buf, 27, "%d:%02d%s", tmr.tm_hour % 12 ? : 12, tmr.tm_min, tmr.tm_hour < 12 ? "am" : "pm"); - return buf; + localtime_r(&when, &tmr); + snprintf(buf, 27, "%d:%02d%s", tmr.tm_hour % 12 ? : 12, tmr.tm_min, tmr.tm_hour < 12 ? "am" : "pm"); + return buf; } char *num99tostr(int n, char *buf) { - static const char *qv = "HIJKLMNOPQRSTUVWXYZ"; - if (n < 100) { - sprintf(buf, "%02d", n); - } else if (n <= 256) { - n -= 100; - sprintf(buf, "%c%d", - qv[(n/10)], (n % 10)); - } - return buf; + static const char *qv = "HIJKLMNOPQRSTUVWXYZ"; + if (n < 100) { + sprintf(buf, "%02d", n); + } else if (n <= 256) { + n -= 100; + sprintf(buf, "%c%d", + qv[(n/10)], (n % 10)); + } + return buf; } char *numtostr(int digits, unsigned int n, char *buf) { - if (digits > 0) { - char fmt[] = "%03u"; + if (digits > 0) { + char fmt[] = "%03u"; - digits %= 10; - fmt[2] = '0' + digits; - snprintf(buf, digits + 1, fmt, n); - buf[digits] = 0; - } else { - sprintf(buf, "%u", n); - } - return buf; + digits %= 10; + fmt[2] = '0' + digits; + snprintf(buf, digits + 1, fmt, n); + buf[digits] = 0; + } else { + sprintf(buf, "%u", n); + } + return buf; } char *numtostr_signed(int digits, int n, char *buf) { - if (digits > 0) { - char fmt[] = "%03d"; + if (digits > 0) { + char fmt[] = "%03d"; - digits %= 10; - fmt[2] = '0' + digits; - snprintf(buf, digits + 1, fmt, n); - buf[digits] = 0; - } else { - sprintf(buf, "%d", n); - } - return buf; + digits %= 10; + fmt[2] = '0' + digits; + snprintf(buf, digits + 1, fmt, n); + buf[digits] = 0; + } else { + sprintf(buf, "%d", n); + } + return buf; } /* --------------------------------------------------------------------- */ @@ -191,82 +262,82 @@ possible portability issues. */ const char *get_basename(const char *filename) { - const char *base = strrchr(filename, DIR_SEPARATOR); - if (base) { - /* skip the slash */ - base++; - } - if (!(base && *base)) { - /* well, there isn't one, so just return the filename */ - base = filename; - } + const char *base = strrchr(filename, DIR_SEPARATOR); + if (base) { + /* skip the slash */ + base++; + } + if (!(base && *base)) { + /* well, there isn't one, so just return the filename */ + base = filename; + } - return base; + return base; } const char *get_extension(const char *filename) { - filename = get_basename(filename); + filename = get_basename(filename); - const char *extension = strrchr(filename, '.'); - if (!extension) { - /* no extension? bummer. point to the \0 at the end of the string. */ - extension = strchr(filename, '\0'); - } + const char *extension = strrchr(filename, '.'); + if (!extension) { + /* no extension? bummer. point to the \0 at the end of the string. */ + extension = strchr(filename, '\0'); + } - return extension; + return extension; } char *get_parent_directory(const char *dirname) { - char *ret, *pos; - int n; + char *ret, *pos; + int n; - if (!dirname || !dirname[0]) - return NULL; + if (!dirname || !dirname[0]) + return NULL; - ret = str_dup(dirname); - if (!ret) - return NULL; - n = strlen(ret) - 1; - if (ret[n] == DIR_SEPARATOR) - ret[n] = 0; - pos = strrchr(ret, DIR_SEPARATOR); - if (!pos) { - free(ret); - return NULL; - } - pos[1] = 0; - return ret; + ret = str_dup(dirname); + if (!ret) + return NULL; + n = strlen(ret) - 1; + if (ret[n] == DIR_SEPARATOR) + ret[n] = 0; + pos = strrchr(ret, DIR_SEPARATOR); + if (!pos) { + free(ret); + return NULL; + } + pos[1] = 0; + return ret; } static const char *whitespace = " \t\v\r\n"; inline int ltrim_string(char *s) { - int ws = strspn(s, whitespace); - int len = strlen(s) - ws; + int ws = strspn(s, whitespace); + int len = strlen(s) - ws; - if (ws) - memmove(s, s + ws, len + 1); - return len; + if (ws) + memmove(s, s + ws, len + 1); + return len; } inline int rtrim_string(char *s) { - int len = strlen(s) - 1; + int len = strlen(s) - 1; - while (len > 0 && strchr(whitespace, s[len])) - len--; - len++; - s[len] = '\0'; - return len; + while (len > 0 && strchr(whitespace, s[len])) + len--; + len++; + s[len] = '\0'; + return len; } int trim_string(char *s) { - ltrim_string(s); - return rtrim_string(s); + ltrim_string(s); + return rtrim_string(s); } @@ -275,220 +346,220 @@ the pointers returned in first/second should be free()'d by the caller. */ int str_break(const char *s, char c, char **first, char **second) { - const char *p = strchr(s, c); - if (!p) - return 0; - *first = mem_alloc(p - s + 1); - strncpy(*first, s, p - s); - (*first)[p - s] = 0; - *second = str_dup(p + 1); - return 1; + const char *p = strchr(s, c); + if (!p) + return 0; + *first = mem_alloc(p - s + 1); + strncpy(*first, s, p - s); + (*first)[p - s] = 0; + *second = str_dup(p + 1); + return 1; } /* adapted from glib. in addition to the normal c escapes, this also escapes the hashmark and semicolon * (comment characters). if space is true, the first/last character is also escaped if it is a space. */ char *str_escape(const char *s, int space) { - /* Each source byte needs maximally four destination chars (\777) */ - char *dest = calloc(4 * strlen(s) + 1, sizeof(char)); - char *d = dest; - - if (space && *s == ' ') { - *d++ = '\\'; - *d++ = '0'; - *d++ = '4'; - *d++ = '0'; - s++; - } - - while (*s) { - switch (*s) { - case '\a': - *d++ = '\\'; - *d++ = 'a'; - break; - case '\b': - *d++ = '\\'; - *d++ = 'b'; - break; - case '\f': - *d++ = '\\'; - *d++ = 'f'; - break; - case '\n': - *d++ = '\\'; - *d++ = 'n'; - break; - case '\r': - *d++ = '\\'; - *d++ = 'r'; - break; - case '\t': - *d++ = '\\'; - *d++ = 't'; - break; - case '\v': - *d++ = '\\'; - *d++ = 'v'; - break; - case '\\': case '"': - *d++ = '\\'; - *d++ = *s; - break; - - default: - if (*s < ' ' || *s >= 127 || (space && *s == ' ' && s[1] == '\0')) { - case '#': case ';': - *d++ = '\\'; - *d++ = '0' + ((((uint8_t) *s) >> 6) & 7); - *d++ = '0' + ((((uint8_t) *s) >> 3) & 7); - *d++ = '0' + ( ((uint8_t) *s) & 7); - } else { - *d++ = *s; - } - break; - } - s++; - } + /* Each source byte needs maximally four destination chars (\777) */ + char *dest = calloc(4 * strlen(s) + 1, sizeof(char)); + char *d = dest; + + if (space && *s == ' ') { + *d++ = '\\'; + *d++ = '0'; + *d++ = '4'; + *d++ = '0'; + s++; + } + + while (*s) { + switch (*s) { + case '\a': + *d++ = '\\'; + *d++ = 'a'; + break; + case '\b': + *d++ = '\\'; + *d++ = 'b'; + break; + case '\f': + *d++ = '\\'; + *d++ = 'f'; + break; + case '\n': + *d++ = '\\'; + *d++ = 'n'; + break; + case '\r': + *d++ = '\\'; + *d++ = 'r'; + break; + case '\t': + *d++ = '\\'; + *d++ = 't'; + break; + case '\v': + *d++ = '\\'; + *d++ = 'v'; + break; + case '\\': case '"': + *d++ = '\\'; + *d++ = *s; + break; + + default: + if (*s < ' ' || *s >= 127 || (space && *s == ' ' && s[1] == '\0')) { + case '#': case ';': + *d++ = '\\'; + *d++ = '0' + ((((uint8_t) *s) >> 6) & 7); + *d++ = '0' + ((((uint8_t) *s) >> 3) & 7); + *d++ = '0' + ( ((uint8_t) *s) & 7); + } else { + *d++ = *s; + } + break; + } + s++; + } - *d = 0; - return dest; + *d = 0; + return dest; } static inline int readhex(const char *s, int w) { - int o = 0; + int o = 0; - while (w--) { - o <<= 4; - switch (*s) { - case '0'...'9': o |= *s - '0'; break; - case 'a'...'f': o |= *s - 'a' + 10; break; - case 'A'...'F': o |= *s - 'A' + 10; break; - default: return -1; - } - s++; - } - return o; + while (w--) { + o <<= 4; + switch (*s) { + case '0'...'9': o |= *s - '0'; break; + case 'a'...'f': o |= *s - 'a' + 10; break; + case 'A'...'F': o |= *s - 'A' + 10; break; + default: return -1; + } + s++; + } + return o; } /* opposite of str_escape. (this is glib's 'compress' function renamed more clearly) */ char *str_unescape(const char *s) { - const char *end; - int hex; - char *dest = calloc(strlen(s) + 1, sizeof(char)); - char *d = dest; - - while (*s) { - if (*s == '\\') { - s++; - switch (*s) { - case '0'...'7': - *d = 0; - end = s + 3; - while (s < end && *s >= '0' && *s <= '7') { - *d = *d * 8 + *s - '0'; - s++; - } - d++; - s--; - break; - case 'a': - *d++ = '\a'; - break; - case 'b': - *d++ = '\b'; - break; - case 'f': - *d++ = '\f'; - break; - case 'n': - *d++ = '\n'; - break; - case 'r': - *d++ = '\r'; - break; - case 't': - *d++ = '\t'; - break; - case 'v': - *d++ = '\v'; - break; - case '\0': // trailing backslash? - *d++ = '\\'; - s--; - break; - case 'x': - hex = readhex(s + 1, 2); - if (hex >= 0) { - *d++ = hex; - s += 2; - break; - } - /* fall through */ - default: /* Also handles any other char, like \" \\ \; etc. */ - *d++ = *s; - break; - } - } else { - *d++ = *s; - } - s++; - } - *d = 0; + const char *end; + int hex; + char *dest = calloc(strlen(s) + 1, sizeof(char)); + char *d = dest; + + while (*s) { + if (*s == '\\') { + s++; + switch (*s) { + case '0'...'7': + *d = 0; + end = s + 3; + while (s < end && *s >= '0' && *s <= '7') { + *d = *d * 8 + *s - '0'; + s++; + } + d++; + s--; + break; + case 'a': + *d++ = '\a'; + break; + case 'b': + *d++ = '\b'; + break; + case 'f': + *d++ = '\f'; + break; + case 'n': + *d++ = '\n'; + break; + case 'r': + *d++ = '\r'; + break; + case 't': + *d++ = '\t'; + break; + case 'v': + *d++ = '\v'; + break; + case '\0': // trailing backslash? + *d++ = '\\'; + s--; + break; + case 'x': + hex = readhex(s + 1, 2); + if (hex >= 0) { + *d++ = hex; + s += 2; + break; + } + /* fall through */ + default: /* Also handles any other char, like \" \\ \; etc. */ + *d++ = *s; + break; + } + } else { + *d++ = *s; + } + s++; + } + *d = 0; - return dest; + return dest; } char *pretty_name(const char *filename) { - char *ret, *temp; - const char *ptr; - int len; - - ptr = strrchr(filename, DIR_SEPARATOR); - ptr = ((ptr && ptr[1]) ? ptr + 1 : filename); - len = strrchr(ptr, '.') - ptr; - if (len <= 0) { - ret = str_dup(ptr); - } else { - ret = calloc(len + 1, sizeof(char)); - strncpy(ret, ptr, len); - ret[len] = 0; - } - - /* change underscores to spaces (of course, this could be adapted - * to use strpbrk and strip any number of characters) */ - while ((temp = strchr(ret, '_')) != NULL) - *temp = ' '; - - /* TODO | the first letter, and any letter following a space, - * TODO | should be capitalized; multiple spaces should be cut - * TODO | down to one */ + char *ret, *temp; + const char *ptr; + int len; + + ptr = strrchr(filename, DIR_SEPARATOR); + ptr = ((ptr && ptr[1]) ? ptr + 1 : filename); + len = strrchr(ptr, '.') - ptr; + if (len <= 0) { + ret = str_dup(ptr); + } else { + ret = calloc(len + 1, sizeof(char)); + strncpy(ret, ptr, len); + ret[len] = 0; + } + + /* change underscores to spaces (of course, this could be adapted + * to use strpbrk and strip any number of characters) */ + while ((temp = strchr(ret, '_')) != NULL) + *temp = ' '; + + /* TODO | the first letter, and any letter following a space, + * TODO | should be capitalized; multiple spaces should be cut + * TODO | down to one */ - trim_string(ret); - return ret; + trim_string(ret); + return ret; } /* blecch */ int get_num_lines(const char *text) { - const char *ptr = text; - int n = 0; + const char *ptr = text; + int n = 0; - if (!text) - return 0; - for (;;) { - ptr = strpbrk(ptr, "\015\012"); - if (!ptr) - return n; - if (ptr[0] == 13 && ptr[1] == 10) - ptr += 2; - else - ptr++; - n++; - } + if (!text) + return 0; + for (;;) { + ptr = strpbrk(ptr, "\015\012"); + if (!ptr) + return n; + if (ptr[0] == 13 && ptr[1] == 10) + ptr += 2; + else + ptr++; + n++; + } } /* --------------------------------------------------------------------- */ @@ -497,42 +568,42 @@ /* 0 = success, !0 = failed (check errno) */ int make_backup_file(const char *filename, int numbered) { - char buf[PATH_MAX]; + char buf[PATH_MAX]; - /* ensure plenty of room to breathe */ - if (strlen(filename) > PATH_MAX - 16) { - errno = ENAMETOOLONG; - return -1; - } - - if (numbered) { - /* If some crazy person needs more than 65536 backup files, - they probably have more serious issues to tend to. */ - int n = 1, ret; - do { - sprintf(buf, "%s.%d~", filename, n++); - ret = rename_file(filename, buf, 0); - } while (ret != 0 && errno == EEXIST && n < 65536); - return ret; - } else { - strcpy(buf, filename); - strcat(buf, "~"); - return rename_file(filename, buf, 1); - } + /* ensure plenty of room to breathe */ + if (strlen(filename) > PATH_MAX - 16) { + errno = ENAMETOOLONG; + return -1; + } + + if (numbered) { + /* If some crazy person needs more than 65536 backup files, + they probably have more serious issues to tend to. */ + int n = 1, ret; + do { + sprintf(buf, "%s.%d~", filename, n++); + ret = rename_file(filename, buf, 0); + } while (ret != 0 && errno == EEXIST && n < 65536); + return ret; + } else { + strcpy(buf, filename); + strcat(buf, "~"); + return rename_file(filename, buf, 1); + } } long file_size(const char *filename) { - struct stat buf; + struct stat buf; - if (stat(filename, &buf) < 0) { - return EOF; - } - if (S_ISDIR(buf.st_mode)) { - errno = EISDIR; - return EOF; - } - return buf.st_size; + if (stat(filename, &buf) < 0) { + return EOF; + } + if (S_ISDIR(buf.st_mode)) { + errno = EISDIR; + return EOF; + } + return buf.st_size; } /* --------------------------------------------------------------------- */ @@ -540,161 +611,161 @@ int is_directory(const char *filename) { - struct stat buf; + struct stat buf; - if (stat(filename, &buf) == -1) { - /* Well, at least we tried. */ - return 0; - } + if (stat(filename, &buf) == -1) { + /* Well, at least we tried. */ + return 0; + } - return S_ISDIR(buf.st_mode); + return S_ISDIR(buf.st_mode); } char *get_current_directory(void) { - char buf[PATH_MAX + 1]; + char buf[PATH_MAX + 1]; - /* hmm. fall back to the current dir */ - if (getcwd(buf, PATH_MAX)) - return str_dup(buf); - return str_dup("."); + /* hmm. fall back to the current dir */ + if (getcwd(buf, PATH_MAX)) + return str_dup(buf); + return str_dup("."); } /* this function is horrible */ char *get_home_directory(void) { - char buf[PATH_MAX + 1]; + char buf[PATH_MAX + 1]; #if defined(__amigaos4__) - return str_dup("PROGDIR:"); + return str_dup("PROGDIR:"); #elif defined(WIN32) - if (SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, buf) == ERROR_SUCCESS) - return strdup(buf); + if (SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, buf) == ERROR_SUCCESS) + return strdup(buf); #else - char *ptr = getenv("HOME"); - if (ptr) - return str_dup(ptr); + char *ptr = getenv("HOME"); + if (ptr) + return str_dup(ptr); #endif - /* hmm. fall back to the current dir */ - if (getcwd(buf, PATH_MAX)) - return str_dup(buf); + /* hmm. fall back to the current dir */ + if (getcwd(buf, PATH_MAX)) + return str_dup(buf); - /* still don't have a directory? sheesh. */ - return str_dup(FALLBACK_DIR); + /* still don't have a directory? sheesh. */ + return str_dup(FALLBACK_DIR); } char *get_dot_directory(void) { #ifdef WIN32 - char buf[PATH_MAX + 1]; - if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, buf) == ERROR_SUCCESS) - return strdup(buf); - // else fall back to home (but if this ever happens, things are really screwed...) + char buf[PATH_MAX + 1]; + if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, buf) == ERROR_SUCCESS) + return strdup(buf); + // else fall back to home (but if this ever happens, things are really screwed...) #endif - return get_home_directory(); + return get_home_directory(); } char *str_concat(const char *s, ...) { - va_list ap; - char *out = NULL; - int len = 0; - - va_start(ap,s); - while (s) { - out = mem_realloc(out, (len += strlen(s)+1)); - strcat(out, s); - s = va_arg(ap, const char *); - } - va_end(ap); - return out; + va_list ap; + char *out = NULL; + int len = 0; + + va_start(ap,s); + while (s) { + out = mem_realloc(out, (len += strlen(s)+1)); + strcat(out, s); + s = va_arg(ap, const char *); + } + va_end(ap); + return out; } void unset_env_var(const char *key) { #ifdef HAVE_UNSETENV - unsetenv(key); + unsetenv(key); #else - /* assume POSIX-style semantics */ - putenv(key); + /* assume POSIX-style semantics */ + putenv(key); #endif } void put_env_var(const char *key, const char *value) { - char *x; - x = mem_alloc(strlen(key) + strlen(value)+2); - sprintf(x, "%s=%s", key,value); - if (putenv(x) == -1) { - perror("putenv"); - exit(255); /* memory exception */ - } + char *x; + x = mem_alloc(strlen(key) + strlen(value)+2); + sprintf(x, "%s=%s", key,value); + if (putenv(x) == -1) { + perror("putenv"); + exit(255); /* memory exception */ + } } /* fast integer sqrt */ unsigned int i_sqrt(unsigned int r) { - unsigned int t, b, c=0; - for (b = 0x10000000; b != 0; b >>= 2) { - t = c + b; - c >>= 1; - if (t <= r) { - r -= t; - c += b; - } - } - return(c); + unsigned int t, b, c=0; + for (b = 0x10000000; b != 0; b >>= 2) { + t = c + b; + c >>= 1; + if (t <= r) { + r -= t; + c += b; + } + } + return(c); } int run_hook(const char *dir, const char *name, const char *maybe_arg) { #ifdef WIN32 - char buf[PATH_MAX]; - const char *ptr; - char buf2[PATH_MAX]; - struct stat sb; - int r; - - if (!GetCurrentDirectory(PATH_MAX-1,buf)) return 0; - snprintf(buf2, PATH_MAX-2, "%s.bat", name); - if (chdir(dir) == -1) return 0; - if (stat(buf2, &sb) == -1) { - r = 0; - } else { - ptr = getenv("COMSPEC") ?: "command.com"; - r = _spawnlp(_P_WAIT, ptr, ptr, "/c", buf2, maybe_arg, 0); - } - SetCurrentDirectory(buf); - chdir(buf); - if (r == 0) return 1; - return 0; + char buf[PATH_MAX]; + const char *ptr; + char buf2[PATH_MAX]; + struct stat sb; + int r; + + if (!GetCurrentDirectory(PATH_MAX-1,buf)) return 0; + snprintf(buf2, PATH_MAX-2, "%s.bat", name); + if (chdir(dir) == -1) return 0; + if (stat(buf2, &sb) == -1) { + r = 0; + } else { + ptr = getenv("COMSPEC") ?: "command.com"; + r = _spawnlp(_P_WAIT, ptr, ptr, "/c", buf2, maybe_arg, 0); + } + SetCurrentDirectory(buf); + chdir(buf); + if (r == 0) return 1; + return 0; #elif defined(GEKKO) - // help how do I operating system - (void) dir; - (void) name; - (void) maybe_arg; - return 0; + // help how do I operating system + (void) dir; + (void) name; + (void) maybe_arg; + return 0; #else - char *tmp; - int st; + char *tmp; + int st; - switch (fork()) { - case -1: return 0; - case 0: - if (chdir(dir) == -1) _exit(255); - tmp = malloc(strlen(name)+4); - if (!tmp) _exit(255); - sprintf(tmp, "./%s", name); - execl(tmp, tmp, maybe_arg, NULL); - free(tmp); - _exit(255); - }; - while (wait(&st) == -1) { - } - if (WIFEXITED(st) && WEXITSTATUS(st) == 0) return 1; - return 0; + switch (fork()) { + case -1: return 0; + case 0: + if (chdir(dir) == -1) _exit(255); + tmp = malloc(strlen(name)+4); + if (!tmp) _exit(255); + sprintf(tmp, "./%s", name); + execl(tmp, tmp, maybe_arg, NULL); + free(tmp); + _exit(255); + }; + while (wait(&st) == -1) { + } + if (WIFEXITED(st) && WEXITSTATUS(st) == 0) return 1; + return 0; #endif } @@ -704,105 +775,105 @@ { /* XXX does __amigaos4__ have a special need for this? */ #ifdef WIN32 - /* is this code not finished? it never returns success */ - UINT em = SetErrorMode(0); - if (!MoveFile(old, new)) { - switch (GetLastError()) { - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - SetErrorMode(em); - errno = EEXIST; - return -1; - }; - SetErrorMode(em); - return -1; - } - SetErrorMode(em); - return 0; + /* is this code not finished? it never returns success */ + UINT em = SetErrorMode(0); + if (!MoveFile(old, new)) { + switch (GetLastError()) { + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + SetErrorMode(em); + errno = EEXIST; + return -1; + }; + SetErrorMode(em); + return -1; + } + SetErrorMode(em); + return 0; #else - if (link(old, new) == -1) { - return -1; - } - if (unlink(old) == -1) { - /* This can occur when people are using a system with - broken link() semantics, or if the user can create files - that he cannot remove. these systems are decidedly not POSIX.1 - but they may try to compile schism, and we won't know they - are broken unless we warn them. - */ - fprintf(stderr, "link() succeeded, but unlink() failed. something is very wrong\n"); - } - return 0; + if (link(old, new) == -1) { + return -1; + } + if (unlink(old) == -1) { + /* This can occur when people are using a system with + broken link() semantics, or if the user can create files + that he cannot remove. these systems are decidedly not POSIX.1 + but they may try to compile schism, and we won't know they + are broken unless we warn them. + */ + fprintf(stderr, "link() succeeded, but unlink() failed. something is very wrong\n"); + } + return 0; #endif } /* 0 = success, !0 = failed (check errno) */ int rename_file(const char *old, const char *new, int overwrite) { - if (!overwrite) - return _rename_nodestroy(old, new); + if (!overwrite) + return _rename_nodestroy(old, new); #ifdef WIN32 - UINT em; - em = SetErrorMode(0); - if (MoveFile(old, new)) { - win32_filecreated_callback(new); - return 0; - } - switch (GetLastError()) { - case ERROR_ALREADY_EXISTS: - case ERROR_FILE_EXISTS: - break; - default: - /* eh... */ - SetErrorMode(em); - return -1; - }; - - if (MoveFileEx(old, new, MOVEFILE_REPLACE_EXISTING)) { - /* yay */ - SetErrorMode(em); - return 0; - } - /* this sometimes work with win95 and novell shares */ - chmod(new, 0777); - chmod(old, 0777); - /* more junk */ - SetFileAttributesA(new, FILE_ATTRIBUTE_NORMAL); - SetFileAttributesA(new, FILE_ATTRIBUTE_TEMPORARY); - - if (MoveFile(old, new)) { - /* err.. yay! */ - win32_filecreated_callback(new); - SetErrorMode(em); - return 0; - } - /* okay, let's try again */ - if (!DeleteFileA(new)) { - /* no chance! */ - SetErrorMode(em); - return -1; - } - if (MoveFile(old, new)) { - /* .... */ - win32_filecreated_callback(new); - SetErrorMode(em); - return 0; - } - /* alright, thems the breaks. win95 eats your files, - and not a damn thing I can do about it. - */ - SetErrorMode(em); - return -1; + UINT em; + em = SetErrorMode(0); + if (MoveFile(old, new)) { + win32_filecreated_callback(new); + return 0; + } + switch (GetLastError()) { + case ERROR_ALREADY_EXISTS: + case ERROR_FILE_EXISTS: + break; + default: + /* eh... */ + SetErrorMode(em); + return -1; + }; + + if (MoveFileEx(old, new, MOVEFILE_REPLACE_EXISTING)) { + /* yay */ + SetErrorMode(em); + return 0; + } + /* this sometimes work with win95 and novell shares */ + chmod(new, 0777); + chmod(old, 0777); + /* more junk */ + SetFileAttributesA(new, FILE_ATTRIBUTE_NORMAL); + SetFileAttributesA(new, FILE_ATTRIBUTE_TEMPORARY); + + if (MoveFile(old, new)) { + /* err.. yay! */ + win32_filecreated_callback(new); + SetErrorMode(em); + return 0; + } + /* okay, let's try again */ + if (!DeleteFileA(new)) { + /* no chance! */ + SetErrorMode(em); + return -1; + } + if (MoveFile(old, new)) { + /* .... */ + win32_filecreated_callback(new); + SetErrorMode(em); + return 0; + } + /* alright, thems the breaks. win95 eats your files, + and not a damn thing I can do about it. + */ + SetErrorMode(em); + return -1; #else - int r = rename(old, new); - if (r != 0 && errno == EEXIST) { - /* Broken rename()? Try smashing the old file first, - and hope *that* doesn't also fail ;) */ - if (unlink(old) != 0 || rename(old, new) == -1) - return -1; - } - return r; + int r = rename(old, new); + if (r != 0 && errno == EEXIST) { + /* Broken rename()? Try smashing the old file first, + and hope *that* doesn't also fail ;) */ + if (unlink(old) != 0 || rename(old, new) == -1) + return -1; + } + return r; #endif } diff -Nru schism-0+20110101/schism/version.c schism-20160521/schism/version.c --- schism-0+20110101/schism/version.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/version.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -45,18 +45,18 @@ = 0x020: any version between the 0.2a release (2005-04-29?) and 2007-04-17 = 0x050: anywhere from 2007-04-17 to 2009-10-31 (version was updated to 0x050 in hg changeset 2f6bd40c0b79) > 0x050: the number of days since 2009-10-31, for example: - 0x051 = (0x051 - 0x050) + 2009-10-31 = 2009-11-01 - 0x052 = (0x052 - 0x050) + 2009-10-31 = 2009-11-02 - 0x14f = (0x14f - 0x050) + 2009-10-31 = 2010-07-13 - 0xffe = (0xfff - 0x050) + 2009-10-31 = 2020-10-27 + 0x051 = (0x051 - 0x050) + 2009-10-31 = 2009-11-01 + 0x052 = (0x052 - 0x050) + 2009-10-31 = 2009-11-02 + 0x14f = (0x14f - 0x050) + 2009-10-31 = 2010-07-13 + 0xffe = (0xfff - 0x050) + 2009-10-31 = 2020-10-27 = 0xfff: a non-value indicating a date after 2020-10-27 (assuming Schism Tracker still exists then) */ short ver_cwtv; /* these should be 50 characters or shorter, as they are used in the startup dialog */ const char *ver_short_copyright = - "Copyright (c) 2003-2011 Storlek & Mrs. Brisby"; + "Copyright (c) 2003-2016 Storlek, Mrs. Brisby et. al"; const char *ver_short_based_on = - "Based on Impulse Tracker by Jeffrey Lim aka Pulse"; + "Based on Impulse Tracker by Jeffrey Lim aka Pulse"; /* SEE ALSO: helptext/copyright (contains full copyright information, credits, and GPL boilerplate) */ @@ -65,112 +65,93 @@ const char *schism_banner(int classic) { - return (classic - ? TOP_BANNER_CLASSIC - : top_banner_normal); + return (classic + ? TOP_BANNER_CLASSIC + : top_banner_normal); } /* Information at our disposal: - HG_VERSION - "YYYY-MM-DD" - Only defined if .hg directory existed and hg client was installed when configuring. - This is the best indicator of the version if it's defined. - VERSION - "hg" or "YYYYMMDD" - A date here indicates that the source is from one of the periodically-buit packages - on the homepage. Less reliable, but will probably be usable when HG_VERSION isn't. - - __DATE__ "Jun 3 2009" - __TIME__ "23:39:19" - __TIMESTAMP__ "Wed Jun 3 23:39:19 2009" - These are annoying to manipulate beacuse of the month being in text format -- but at - least I don't think they're ever localized, which would make it much more annoying. - Should always exist, especially considering that we require gcc. However, it is a - poor indicator of the age of the *code*, since it depends on the clock of the computer - that's building the code, and also there is the possibility that someone was hanging - onto the code for a really long time before building it. - -If VERSION is "hg", but HG_VERSION is undefined or blank, then we are being built from one of the -snapshot packages, or the build system is somehow broken. (This might happen if hg was uninstalled -between cloning the repo and configuring, or the .hg directory was removed.) + VERSION + "" or "YYYYMMDD" + A date here is the date of the last commit from git + empty string will happen if git isn't installed, or no .git + + __DATE__ "Jun 3 2009" + __TIME__ "23:39:19" + __TIMESTAMP__ "Wed Jun 3 23:39:19 2009" + These are annoying to manipulate beacuse of the month being in text format -- but at + least I don't think they're ever localized, which would make it much more annoying. + Should always exist, especially considering that we require gcc. However, it is a + poor indicator of the age of the *code*, since it depends on the clock of the computer + that's building the code, and also there is the possibility that someone was hanging + onto the code for a really long time before building it. -Note: this is a hack, it'd be great to have something that doesn't require runtime logic. -Fortunately, most of this should be able to be optimized down to static assignment. */ static int get_version_tm(struct tm *version) { - char *ret; -#ifdef HG_VERSION - memset(version, 0, sizeof(*version)); - /* Try this first, but make sure it's not broken (can happen if 'hg' is removed after configure) */ - if (HG_VERSION[0] >= '0' && HG_VERSION[0] <= '9') { - ret = strptime(HG_VERSION, "%Y-%m-%d", version); - if (ret && !*ret) - return 1; - } -#endif - /* Ok how about VERSION? (Note this has spaces only because strptime is dumb) */ - memset(version, 0, sizeof(*version)); - ret = strptime(VERSION, "%Y %m %d", version); - if (ret && !*ret) - return 1; - /* Argh. */ - memset(version, 0, sizeof(*version)); - ret = strptime(__DATE__, "%b %e %Y", version); - if (ret && !*ret) - return 1; - /* Give up; we don't know anything. */ - return 0; + char *ret; + + memset(version, 0, sizeof(*version)); + ret = strptime(VERSION, "%Y %m %d", version); + if (ret && !*ret) + return 1; + /* Argh. */ + memset(version, 0, sizeof(*version)); + ret = strptime(__DATE__, "%b %e %Y", version); + if (ret && !*ret) + return 1; + /* Give up; we don't know anything. */ + return 0; } void ver_init(void) { - struct tm version, epoch = { .tm_year = 109, .tm_mon = 9, .tm_mday = 31 }; /* 2009-10-31 */ - time_t version_sec; - char ver[32] = VERSION; - - if (get_version_tm(&version)) { - version_sec = mktime(&version); - } else { - printf("help, I am very confused about myself\n"); - version_sec = epoch_sec; - } - - epoch_sec = mktime(&epoch); - version_sec = mktime(&version); - ver_cwtv = 0x050 + (version_sec - epoch_sec) / 86400; - ver_cwtv = CLAMP(ver_cwtv, 0x050, 0xfff); - -#ifdef HG_VERSION - if (strcmp(VERSION, "hg") == 0) { - strcat(ver, ":"); - strcat(ver, HG_VERSION); - } -#endif - snprintf(top_banner_normal, sizeof(top_banner_normal) - 1, - "Schism Tracker %s built %s %s", - ver, __DATE__, __TIME__); - top_banner_normal[sizeof(top_banner_normal) - 1] = '\0'; /* to be sure */ + struct tm version, epoch = { .tm_year = 109, .tm_mon = 9, .tm_mday = 31 }; /* 2009-10-31 */ + time_t version_sec; + char ver[32] = VERSION; + + if (get_version_tm(&version)) { + version_sec = mktime(&version); + } else { + printf("help, I am very confused about myself\n"); + version_sec = epoch_sec; + } + + epoch_sec = mktime(&epoch); + version_sec = mktime(&version); + ver_cwtv = 0x050 + (version_sec - epoch_sec) / 86400; + ver_cwtv = CLAMP(ver_cwtv, 0x050, 0xfff); + + /* show build date if we don't know last commit date (no git) */ + if (ver[0]) { + snprintf(top_banner_normal, sizeof(top_banner_normal) - 1, + "Schism Tracker %s", ver); + } else { + snprintf(top_banner_normal, sizeof(top_banner_normal) - 1, + "Schism Tracker built %s %s", __DATE__, __TIME__); + } + + top_banner_normal[sizeof(top_banner_normal) - 1] = '\0'; /* to be sure */ } void ver_decode_cwtv(uint16_t cwtv, char *buf) { - struct tm version; - time_t version_sec; + struct tm version; + time_t version_sec; - cwtv &= 0xfff; - if (cwtv > 0x050) { - // Annoyingly, mktime uses local time instead of UTC. Why etc. - version_sec = ((cwtv - 0x050) * 86400) + epoch_sec; - if (localtime_r(&version_sec, &version)) { - sprintf(buf, "%04d-%02d-%02d", - version.tm_year + 1900, version.tm_mon + 1, version.tm_mday); - return; - } - } - sprintf(buf, "0.%x", cwtv); + cwtv &= 0xfff; + if (cwtv > 0x050) { + // Annoyingly, mktime uses local time instead of UTC. Why etc. + version_sec = ((cwtv - 0x050) * 86400) + epoch_sec; + if (localtime_r(&version_sec, &version)) { + sprintf(buf, "%04d-%02d-%02d", + version.tm_year + 1900, version.tm_mon + 1, version.tm_mday); + return; + } + } + sprintf(buf, "0.%x", cwtv); } diff -Nru schism-0+20110101/schism/video.c schism-20160521/schism/video.c --- schism-0+20110101/schism/video.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/video.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -96,7 +96,7 @@ #ifndef WGL_NV_allocate_memory #define WGL_NV_allocate_memory 1 typedef void * (APIENTRY * PFNWGLALLOCATEMEMORYNVPROC) - (int size, float readfreq, float writefreq, float priority); + (int size, float readfreq, float writefreq, float priority); typedef void (APIENTRY * PFNWGLFREEMEMORYNVPROC) (void *pointer); #endif @@ -117,20 +117,20 @@ /* leeto drawing skills */ #define MOUSE_HEIGHT 14 static const unsigned int _mouse_pointer[] = { - /* x....... */ 0x80, - /* xx...... */ 0xc0, - /* xxx..... */ 0xe0, - /* xxxx.... */ 0xf0, - /* xxxxx... */ 0xf8, - /* xxxxxx.. */ 0xfc, - /* xxxxxxx. */ 0xfe, - /* xxxxxxxx */ 0xff, - /* xxxxxxx. */ 0xfe, - /* xxxxx... */ 0xf8, - /* x...xx.. */ 0x8c, - /* ....xx.. */ 0x0c, - /* .....xx. */ 0x06, - /* .....xx. */ 0x06, + /* x....... */ 0x80, + /* xx...... */ 0xc0, + /* xxx..... */ 0xe0, + /* xxxx.... */ 0xf0, + /* xxxxx... */ 0xf8, + /* xxxxxx.. */ 0xfc, + /* xxxxxxx. */ 0xfe, + /* xxxxxxxx */ 0xff, + /* xxxxxxx. */ 0xfe, + /* xxxxx... */ 0xf8, + /* x...xx.. */ 0x8c, + /* ....xx.. */ 0x0c, + /* .....xx. */ 0x06, + /* .....xx. */ 0x06, 0,0 }; @@ -140,82 +140,82 @@ #include #include "wine-ddraw.h" struct private_hwdata { - LPDIRECTDRAWSURFACE3 dd_surface; - LPDIRECTDRAWSURFACE3 dd_writebuf; + LPDIRECTDRAWSURFACE3 dd_surface; + LPDIRECTDRAWSURFACE3 dd_writebuf; }; #endif struct video_cf { - struct { - unsigned int width; - unsigned int height; - - int autoscale; - } draw; - struct { - unsigned int width,height,bpp; - int want_fixed; - - int swsurface; - int fb_hacks; - int fullscreen; - int doublebuf; - int want_type; - int type; + struct { + unsigned int width; + unsigned int height; + + int autoscale; + } draw; + struct { + unsigned int width,height,bpp; + int want_fixed; + + int swsurface; + int fb_hacks; + int fullscreen; + int doublebuf; + int want_type; + int type; #define VIDEO_SURFACE 0 #define VIDEO_DDRAW 1 #define VIDEO_YUV 2 #define VIDEO_GL 3 - } desktop; - struct { - unsigned int pitch; - void * framebuf; - GLuint texture; - GLuint displaylist; - GLint max_texsize; - int bilinear; - int packed_pixel; - int paletted_texture; + } desktop; + struct { + unsigned int pitch; + void * framebuf; + GLuint texture; + GLuint displaylist; + GLint max_texsize; + int bilinear; + int packed_pixel; + int paletted_texture; #if defined(NVIDIA_PixelDataRange) - int pixel_data_range; + int pixel_data_range; #endif - } gl; + } gl; #if defined(WIN32) - struct { - SDL_Surface * surface; - RECT rect; - DDBLTFX fx; - } ddblit; -#endif - unsigned int yuvlayout; - SDL_Rect clip; - SDL_Surface * surface; - SDL_Overlay * overlay; - /* to convert 32-bit color to 24-bit color */ - unsigned char *cv32backing; - /* for tv mode */ - unsigned char *cv8backing; - struct { - unsigned int x; - unsigned int y; - int visible; - } mouse; - - unsigned int yuv_y[256]; - unsigned int yuv_u[256]; - unsigned int yuv_v[256]; + struct { + SDL_Surface * surface; + RECT rect; + DDBLTFX fx; + } ddblit; +#endif + unsigned int yuvlayout; + SDL_Rect clip; + SDL_Surface * surface; + SDL_Overlay * overlay; + /* to convert 32-bit color to 24-bit color */ + unsigned char *cv32backing; + /* for tv mode */ + unsigned char *cv8backing; + struct { + unsigned int x; + unsigned int y; + int visible; + } mouse; + + unsigned int yuv_y[256]; + unsigned int yuv_u[256]; + unsigned int yuv_v[256]; - unsigned int pal[256]; + unsigned int pal[256]; - unsigned int tc_bgr32[256]; + unsigned int tc_bgr32[256]; }; static struct video_cf video; #ifdef USE_OPENGL static int int_log2(int val) { - int l = 0; - while ((val >>= 1 ) != 0) l++; - return l; + int l = 0; + while ((val >>= 1 ) != 0) l++; + return l; } #endif @@ -259,8 +259,8 @@ with win32. */ static void (APIENTRY *my_glCallList)(GLuint); static void (APIENTRY *my_glTexSubImage2D)(GLenum,GLint,GLint,GLint, - GLsizei,GLsizei,GLenum,GLenum, - const GLvoid *); + GLsizei,GLsizei,GLenum,GLenum, + const GLvoid *); static void (APIENTRY *my_glDeleteLists)(GLuint,GLsizei); static void (APIENTRY *my_glTexParameteri)(GLenum,GLenum,GLint); static void (APIENTRY *my_glBegin)(GLenum); @@ -280,7 +280,7 @@ static void (APIENTRY *my_glClearColor)(GLclampf,GLclampf,GLclampf,GLclampf); static const GLubyte* (APIENTRY *my_glGetString)(GLenum); static void (APIENTRY *my_glTexImage2D)(GLenum,GLint,GLint,GLsizei,GLsizei,GLint, - GLenum,GLenum,const GLvoid *); + GLenum,GLenum,const GLvoid *); static void (APIENTRY *my_glGetIntegerv)(GLenum, GLint *); static void (APIENTRY *my_glShadeModel)(GLenum); static void (APIENTRY *my_glGenTextures)(GLsizei,GLuint*); @@ -293,611 +293,611 @@ const char *video_driver_name(void) { - switch (video.desktop.type) { - case VIDEO_SURFACE: - return "sdl"; - case VIDEO_YUV: - return "yuv"; - case VIDEO_GL: - return "opengl"; - case VIDEO_DDRAW: - return "directdraw"; - }; - /* err.... */ - return "auto"; + switch (video.desktop.type) { + case VIDEO_SURFACE: + return "sdl"; + case VIDEO_YUV: + return "yuv"; + case VIDEO_GL: + return "opengl"; + case VIDEO_DDRAW: + return "directdraw"; + }; + /* err.... */ + return "auto"; } void video_report(void) { - char buf[256]; - struct { - unsigned int num; - const char *name, *type; - } yuv_layouts[] = { - {VIDEO_YUV_IYUV, "IYUV", "planar"}, - {VIDEO_YUV_YV12_TV, "YV12", "planar+tv"}, - {VIDEO_YUV_IYUV_TV, "IYUV", "planar+tv"}, - {VIDEO_YUV_YVYU, "YVYU", "packed"}, - {VIDEO_YUV_UYVY, "UYVY", "packed"}, - {VIDEO_YUV_YUY2, "YUY2", "packed"}, - {VIDEO_YUV_RGBA, "RGBA", "packed"}, - {VIDEO_YUV_RGBT, "RGBT", "packed"}, - {VIDEO_YUV_RGB565, "RGB565", "packed"}, - {VIDEO_YUV_RGB24, "RGB24", "packed"}, - {VIDEO_YUV_RGB32, "RGB32", "packed"}, - {0, NULL, NULL}, - }, *layout = yuv_layouts; - - log_appendf(5, " Using driver '%s'", SDL_VideoDriverName(buf, 256)); - - switch (video.desktop.type) { - case VIDEO_SURFACE: - log_appendf(5, " %s%s video surface", - (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", - (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); - if (SDL_MUSTLOCK(video.surface)) - log_append(4, 0, " Must lock surface"); - log_appendf(5, " Display format: %d bits/pixel", video.surface->format->BitsPerPixel); - break; - - case VIDEO_YUV: - /* if an overlay isn't hardware accelerated, what is it? I guess this works */ - log_appendf(5, " %s-accelerated video overlay", - video.overlay->hw_overlay ? "Hardware" : "Non"); - while (video.yuvlayout != layout->num && layout->name != NULL) - layout++; - if (layout->name) - log_appendf(5, " Display format: %s (%s)", layout->name, layout->type); - else - log_appendf(5, " Display format: %x", video.yuvlayout); - break; - case VIDEO_GL: - log_appendf(5, " %s%s OpenGL interface", - (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", - (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); + char buf[256]; + struct { + unsigned int num; + const char *name, *type; + } yuv_layouts[] = { + {VIDEO_YUV_IYUV, "IYUV", "planar"}, + {VIDEO_YUV_YV12_TV, "YV12", "planar+tv"}, + {VIDEO_YUV_IYUV_TV, "IYUV", "planar+tv"}, + {VIDEO_YUV_YVYU, "YVYU", "packed"}, + {VIDEO_YUV_UYVY, "UYVY", "packed"}, + {VIDEO_YUV_YUY2, "YUY2", "packed"}, + {VIDEO_YUV_RGBA, "RGBA", "packed"}, + {VIDEO_YUV_RGBT, "RGBT", "packed"}, + {VIDEO_YUV_RGB565, "RGB565", "packed"}, + {VIDEO_YUV_RGB24, "RGB24", "packed"}, + {VIDEO_YUV_RGB32, "RGB32", "packed"}, + {0, NULL, NULL}, + }, *layout = yuv_layouts; + + log_appendf(5, " Using driver '%s'", SDL_VideoDriverName(buf, 256)); + + switch (video.desktop.type) { + case VIDEO_SURFACE: + log_appendf(5, " %s%s video surface", + (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", + (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); + if (SDL_MUSTLOCK(video.surface)) + log_append(4, 0, " Must lock surface"); + log_appendf(5, " Display format: %d bits/pixel", video.surface->format->BitsPerPixel); + break; + + case VIDEO_YUV: + /* if an overlay isn't hardware accelerated, what is it? I guess this works */ + log_appendf(5, " %s-accelerated video overlay", + video.overlay->hw_overlay ? "Hardware" : "Non"); + while (video.yuvlayout != layout->num && layout->name != NULL) + layout++; + if (layout->name) + log_appendf(5, " Display format: %s (%s)", layout->name, layout->type); + else + log_appendf(5, " Display format: %x", video.yuvlayout); + break; + case VIDEO_GL: + log_appendf(5, " %s%s OpenGL interface", + (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", + (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); #if defined(NVIDIA_PixelDataRange) - if (video.gl.pixel_data_range) - log_append(5, 0, " NVidia pixel range extensions available"); + if (video.gl.pixel_data_range) + log_append(5, 0, " NVidia pixel range extensions available"); #endif - break; - case VIDEO_DDRAW: - // is this meaningful? - log_appendf(5, " %s%s DirectDraw interface", - (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", - (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); - break; - }; - log_appendf(5, " %d bits/pixel", video.surface->format->BitsPerPixel); - if (video.desktop.fullscreen || video.desktop.fb_hacks) { - log_appendf(5, " Display dimensions: %dx%d", video.desktop.width, video.desktop.height); - } + break; + case VIDEO_DDRAW: + // is this meaningful? + log_appendf(5, " %s%s DirectDraw interface", + (video.surface->flags & SDL_HWSURFACE) ? "Hardware" : "Software", + (video.surface->flags & SDL_HWACCEL) ? " accelerated" : ""); + break; + }; + log_appendf(5, " %d bits/pixel", video.surface->format->BitsPerPixel); + if (video.desktop.fullscreen || video.desktop.fb_hacks) { + log_appendf(5, " Display dimensions: %dx%d", video.desktop.width, video.desktop.height); + } } static int _did_preinit = 0; static void _video_preinit(void) { - if (!_did_preinit) { - memset(&video, 0, sizeof(video)); - video.cv32backing = mem_alloc(NATIVE_SCREEN_WIDTH * 8); - video.cv8backing = mem_alloc(NATIVE_SCREEN_WIDTH); - _did_preinit = 1; - } + if (!_did_preinit) { + memset(&video, 0, sizeof(video)); + video.cv32backing = mem_alloc(NATIVE_SCREEN_WIDTH * 8); + video.cv8backing = mem_alloc(NATIVE_SCREEN_WIDTH); + _did_preinit = 1; + } } static int best_resolution(int w, int h) { - if ((w == NATIVE_SCREEN_WIDTH || w == (2*NATIVE_SCREEN_WIDTH) - || w == (3*NATIVE_SCREEN_WIDTH) || w == (4*NATIVE_SCREEN_WIDTH)) - && - (h == NATIVE_SCREEN_HEIGHT || h == (2*NATIVE_SCREEN_HEIGHT) - || h == (3*NATIVE_SCREEN_HEIGHT) || h == (4*NATIVE_SCREEN_HEIGHT))) { - return 1; - } - return 0; + if ((w == NATIVE_SCREEN_WIDTH || w == (2*NATIVE_SCREEN_WIDTH) + || w == (3*NATIVE_SCREEN_WIDTH) || w == (4*NATIVE_SCREEN_WIDTH)) + && + (h == NATIVE_SCREEN_HEIGHT || h == (2*NATIVE_SCREEN_HEIGHT) + || h == (3*NATIVE_SCREEN_HEIGHT) || h == (4*NATIVE_SCREEN_HEIGHT))) { + return 1; + } + return 0; } int video_is_fullscreen(void) { - return video.desktop.fullscreen; + return video.desktop.fullscreen; } void video_shutdown(void) { - if (video.desktop.fullscreen) { - video.desktop.fullscreen = 0; - video_resize(0,0); - } + if (video.desktop.fullscreen) { + video.desktop.fullscreen = 0; + video_resize(0,0); + } } void video_fullscreen(int tri) { - _video_preinit(); + _video_preinit(); - if (tri == 0 || video.desktop.fb_hacks) { - video.desktop.fullscreen = 0; + if (tri == 0 || video.desktop.fb_hacks) { + video.desktop.fullscreen = 0; - } else if (tri == 1) { - video.desktop.fullscreen = 1; + } else if (tri == 1) { + video.desktop.fullscreen = 1; - } else if (tri < 0) { - video.desktop.fullscreen = video.desktop.fullscreen ? 0 : 1; - } - if (_did_init) { - if (video.desktop.fullscreen) { - video_resize(video.desktop.width, video.desktop.height); - } else { - video_resize(0, 0); - } - /* video_report(); - this should be done in main, not here */ - } + } else if (tri < 0) { + video.desktop.fullscreen = video.desktop.fullscreen ? 0 : 1; + } + if (_did_init) { + if (video.desktop.fullscreen) { + video_resize(video.desktop.width, video.desktop.height); + } else { + video_resize(0, 0); + } + /* video_report(); - this should be done in main, not here */ + } } void video_setup(const char *driver) { - char *q; - /* _SOME_ drivers can be switched to, but not all of them... */ + char *q; + /* _SOME_ drivers can be switched to, but not all of them... */ - if (driver && strcasecmp(driver, "auto") == 0) - driver = NULL; + if (driver && strcasecmp(driver, "auto") == 0) + driver = NULL; - _video_preinit(); + _video_preinit(); - video.draw.width = NATIVE_SCREEN_WIDTH; - video.draw.height = NATIVE_SCREEN_HEIGHT; - video.mouse.visible = MOUSE_EMULATED; - - video.yuvlayout = VIDEO_YUV_NONE; - if ((q=getenv("SCHISM_YUVLAYOUT")) || (q=getenv("YUVLAYOUT"))) { - if (strcasecmp(q, "YUY2") == 0 - || strcasecmp(q, "YUNV") == 0 - || strcasecmp(q, "V422") == 0 - || strcasecmp(q, "YUYV") == 0) { - video.yuvlayout = VIDEO_YUV_YUY2; - } else if (strcasecmp(q, "UYVY") == 0) { - video.yuvlayout = VIDEO_YUV_UYVY; - } else if (strcasecmp(q, "YVYU") == 0) { - video.yuvlayout = VIDEO_YUV_YVYU; - } else if (strcasecmp(q, "YV12") == 0) { - video.yuvlayout = VIDEO_YUV_YV12; - } else if (strcasecmp(q, "IYUV") == 0) { - video.yuvlayout = VIDEO_YUV_IYUV; - } else if (strcasecmp(q, "YV12/2") == 0) { - video.yuvlayout = VIDEO_YUV_YV12_TV; - } else if (strcasecmp(q, "IYUV/2") == 0) { - video.yuvlayout = VIDEO_YUV_IYUV_TV; - } else if (strcasecmp(q, "RGBA") == 0) { - video.yuvlayout = VIDEO_YUV_RGBA; - } else if (strcasecmp(q, "RGBT") == 0) { - video.yuvlayout = VIDEO_YUV_RGBT; - } else if (strcasecmp(q, "RGB565") == 0 || strcasecmp(q, "RGB2") == 0) { - video.yuvlayout = VIDEO_YUV_RGB565; - } else if (strcasecmp(q, "RGB24") == 0) { - video.yuvlayout = VIDEO_YUV_RGB24; - } else if (strcasecmp(q, "RGB32") == 0 || strcasecmp(q, "RGB") == 0) { - video.yuvlayout = VIDEO_YUV_RGB32; - } else if (sscanf(q, "%x", &video.yuvlayout) != 1) { - video.yuvlayout = 0; - } - } - - q = getenv("SCHISM_DEBUG"); - if (q && strstr(q,"doublebuf")) { - video.desktop.doublebuf = 1; - } + video.draw.width = NATIVE_SCREEN_WIDTH; + video.draw.height = NATIVE_SCREEN_HEIGHT; + video.mouse.visible = MOUSE_EMULATED; + + video.yuvlayout = VIDEO_YUV_NONE; + if ((q=getenv("SCHISM_YUVLAYOUT")) || (q=getenv("YUVLAYOUT"))) { + if (strcasecmp(q, "YUY2") == 0 + || strcasecmp(q, "YUNV") == 0 + || strcasecmp(q, "V422") == 0 + || strcasecmp(q, "YUYV") == 0) { + video.yuvlayout = VIDEO_YUV_YUY2; + } else if (strcasecmp(q, "UYVY") == 0) { + video.yuvlayout = VIDEO_YUV_UYVY; + } else if (strcasecmp(q, "YVYU") == 0) { + video.yuvlayout = VIDEO_YUV_YVYU; + } else if (strcasecmp(q, "YV12") == 0) { + video.yuvlayout = VIDEO_YUV_YV12; + } else if (strcasecmp(q, "IYUV") == 0) { + video.yuvlayout = VIDEO_YUV_IYUV; + } else if (strcasecmp(q, "YV12/2") == 0) { + video.yuvlayout = VIDEO_YUV_YV12_TV; + } else if (strcasecmp(q, "IYUV/2") == 0) { + video.yuvlayout = VIDEO_YUV_IYUV_TV; + } else if (strcasecmp(q, "RGBA") == 0) { + video.yuvlayout = VIDEO_YUV_RGBA; + } else if (strcasecmp(q, "RGBT") == 0) { + video.yuvlayout = VIDEO_YUV_RGBT; + } else if (strcasecmp(q, "RGB565") == 0 || strcasecmp(q, "RGB2") == 0) { + video.yuvlayout = VIDEO_YUV_RGB565; + } else if (strcasecmp(q, "RGB24") == 0) { + video.yuvlayout = VIDEO_YUV_RGB24; + } else if (strcasecmp(q, "RGB32") == 0 || strcasecmp(q, "RGB") == 0) { + video.yuvlayout = VIDEO_YUV_RGB32; + } else if (sscanf(q, "%x", &video.yuvlayout) != 1) { + video.yuvlayout = 0; + } + } + + q = getenv("SCHISM_DEBUG"); + if (q && strstr(q,"doublebuf")) { + video.desktop.doublebuf = 1; + } - video.desktop.want_type = VIDEO_SURFACE; + video.desktop.want_type = VIDEO_SURFACE; #ifdef WIN32 - if (!driver) { - /* alright, let's have some fun. */ - driver = "sdlauto"; /* err... */ - } - - if (!strcasecmp(driver, "windib")) { - putenv("SDL_VIDEODRIVER=windib"); - } else if (!strcasecmp(driver, "ddraw") || !strcasecmp(driver,"directdraw")) { - putenv("SDL_VIDEODRIVER=directx"); - video.desktop.want_type = VIDEO_DDRAW; - } else if (!strcasecmp(driver, "sdlddraw")) { - putenv("SDL_VIDEODRIVER=directx"); - } + if (!driver) { + /* alright, let's have some fun. */ + driver = "sdlauto"; /* err... */ + } + + if (!strcasecmp(driver, "windib")) { + putenv("SDL_VIDEODRIVER=windib"); + } else if (!strcasecmp(driver, "ddraw") || !strcasecmp(driver,"directdraw")) { + putenv("SDL_VIDEODRIVER=directx"); + video.desktop.want_type = VIDEO_DDRAW; + } else if (!strcasecmp(driver, "sdlddraw")) { + putenv("SDL_VIDEODRIVER=directx"); + } #elif defined(GEKKO) - if (!driver) { - driver = "yuv"; - } + if (!driver) { + driver = "yuv"; + } #else - if (!driver) { - if (getenv("DISPLAY")) { - driver = "x11"; - } else { - driver = "sdlauto"; - } - } -#endif - - video.desktop.fb_hacks = 0; - /* get xv info */ - if (video.yuvlayout == VIDEO_YUV_NONE) - video.yuvlayout = os_yuvlayout(); - if ((video.yuvlayout != VIDEO_YUV_YV12_TV - && video.yuvlayout != VIDEO_YUV_IYUV_TV - && video.yuvlayout != VIDEO_YUV_NONE && 0) /* don't do this until we figure out how to make it better */ - && !strcasecmp(driver, "x11")) { - video.desktop.want_type = VIDEO_YUV; - putenv((char *) "SDL_VIDEO_YUV_DIRECT=1"); - putenv((char *) "SDL_VIDEO_YUV_HWACCEL=1"); - putenv((char *) "SDL_VIDEODRIVER=x11"); + if (!driver) { + if (getenv("DISPLAY")) { + driver = "x11"; + } else { + driver = "sdlauto"; + } + } +#endif + + video.desktop.fb_hacks = 0; + /* get xv info */ + if (video.yuvlayout == VIDEO_YUV_NONE) + video.yuvlayout = os_yuvlayout(); + if ((video.yuvlayout != VIDEO_YUV_YV12_TV + && video.yuvlayout != VIDEO_YUV_IYUV_TV + && video.yuvlayout != VIDEO_YUV_NONE && 0) /* don't do this until we figure out how to make it better */ + && !strcasecmp(driver, "x11")) { + video.desktop.want_type = VIDEO_YUV; + putenv((char *) "SDL_VIDEO_YUV_DIRECT=1"); + putenv((char *) "SDL_VIDEO_YUV_HWACCEL=1"); + putenv((char *) "SDL_VIDEODRIVER=x11"); #ifdef USE_X11 - } else if (!strcasecmp(driver, "dga")) { - putenv((char *) "SDL_VIDEODRIVER=dga"); - video.desktop.want_type = VIDEO_SURFACE; - } else if (!strcasecmp(driver, "directfb")) { - putenv((char *) "SDL_VIDEODRIVER=directfb"); - video.desktop.want_type = VIDEO_SURFACE; + } else if (!strcasecmp(driver, "dga")) { + putenv((char *) "SDL_VIDEODRIVER=dga"); + video.desktop.want_type = VIDEO_SURFACE; + } else if (!strcasecmp(driver, "directfb")) { + putenv((char *) "SDL_VIDEODRIVER=directfb"); + video.desktop.want_type = VIDEO_SURFACE; #endif #if HAVE_LINUX_FB_H - } else if (!strcasecmp(driver, "fbcon") - || !strcasecmp(driver, "linuxfb") - || !strcasecmp(driver, "fb")) { - unset_env_var("DISPLAY"); - putenv((char *) "SDL_VIDEODRIVER=fbcon"); - video.desktop.want_type = VIDEO_SURFACE; - - } else if (strncmp(driver, "/dev/fb", 7) == 0) { - unset_env_var("DISPLAY"); - putenv((char *) "SDL_VIDEODRIVER=fbcon"); - put_env_var("SDL_FBDEV", driver); - video.desktop.want_type = VIDEO_SURFACE; + } else if (!strcasecmp(driver, "fbcon") + || !strcasecmp(driver, "linuxfb") + || !strcasecmp(driver, "fb")) { + unset_env_var("DISPLAY"); + putenv((char *) "SDL_VIDEODRIVER=fbcon"); + video.desktop.want_type = VIDEO_SURFACE; + + } else if (strncmp(driver, "/dev/fb", 7) == 0) { + unset_env_var("DISPLAY"); + putenv((char *) "SDL_VIDEODRIVER=fbcon"); + put_env_var("SDL_FBDEV", driver); + video.desktop.want_type = VIDEO_SURFACE; #endif - } else if (!strcasecmp(driver, "aalib") - || !strcasecmp(driver, "aa")) { - /* SDL needs to have been built this way... */ - unset_env_var("DISPLAY"); - putenv((char *) "SDL_VIDEODRIVER=aalib"); - video.desktop.want_type = VIDEO_SURFACE; - video.desktop.fb_hacks = 1; - - } else if (video.yuvlayout != VIDEO_YUV_NONE && !strcasecmp(driver, "yuv")) { - video.desktop.want_type = VIDEO_YUV; - putenv((char *) "SDL_VIDEO_YUV_DIRECT=1"); - putenv((char *) "SDL_VIDEO_YUV_HWACCEL=1"); - /* leave everything else alone... */ - } else if (!strcasecmp(driver, "dummy") - || !strcasecmp(driver, "null") - || !strcasecmp(driver, "none")) { - - unset_env_var("DISPLAY"); - putenv((char *) "SDL_VIDEODRIVER=dummy"); - video.desktop.want_type = VIDEO_SURFACE; - video.desktop.fb_hacks = 1; + } else if (!strcasecmp(driver, "aalib") + || !strcasecmp(driver, "aa")) { + /* SDL needs to have been built this way... */ + unset_env_var("DISPLAY"); + putenv((char *) "SDL_VIDEODRIVER=aalib"); + video.desktop.want_type = VIDEO_SURFACE; + video.desktop.fb_hacks = 1; + + } else if (video.yuvlayout != VIDEO_YUV_NONE && !strcasecmp(driver, "yuv")) { + video.desktop.want_type = VIDEO_YUV; + putenv((char *) "SDL_VIDEO_YUV_DIRECT=1"); + putenv((char *) "SDL_VIDEO_YUV_HWACCEL=1"); + /* leave everything else alone... */ + } else if (!strcasecmp(driver, "dummy") + || !strcasecmp(driver, "null") + || !strcasecmp(driver, "none")) { + + unset_env_var("DISPLAY"); + putenv((char *) "SDL_VIDEODRIVER=dummy"); + video.desktop.want_type = VIDEO_SURFACE; + video.desktop.fb_hacks = 1; #if HAVE_SIGNAL_H - signal(SIGINT, SIG_DFL); + signal(SIGINT, SIG_DFL); #endif - } else if (!strcasecmp(driver, "gl") || !strcasecmp(driver, "opengl")) { - video.desktop.want_type = VIDEO_GL; - } else if (!strcasecmp(driver, "sdlauto") - || !strcasecmp(driver,"sdl")) { - video.desktop.want_type = VIDEO_SURFACE; - } + } else if (!strcasecmp(driver, "gl") || !strcasecmp(driver, "opengl")) { + video.desktop.want_type = VIDEO_GL; + } else if (!strcasecmp(driver, "sdlauto") + || !strcasecmp(driver,"sdl")) { + video.desktop.want_type = VIDEO_SURFACE; + } } void video_startup(void) { - UNUSED static int did_this_2 = 0; + UNUSED static int did_this_2 = 0; #if USE_OPENGL - const char *gl_ext; + const char *gl_ext; #endif - char *q; - SDL_Rect **modes; - int i, j, x, y; + char *q; + SDL_Rect **modes; + int i, j, x, y; - /* because first mode is 0 */ - vgamem_clear(); - vgamem_flip(); + /* because first mode is 0 */ + vgamem_clear(); + vgamem_flip(); - SDL_WM_SetCaption("Schism Tracker", "Schism Tracker"); + SDL_WM_SetCaption("Schism Tracker", "Schism Tracker"); #ifndef MACOSX /* apple/macs use a bundle; this overrides their nice pretty icon */ - SDL_Surface *icon = xpmdata(_schism_icon_xpm); - SDL_WM_SetIcon(icon, NULL); - SDL_FreeSurface(icon); + SDL_Surface *icon = xpmdata(_schism_icon_xpm); + SDL_WM_SetIcon(icon, NULL); + SDL_FreeSurface(icon); #endif #ifndef MACOSX - if (video.desktop.want_type == VIDEO_GL) { + if (video.desktop.want_type == VIDEO_GL) { #define Z(q) my_ ## q = SDL_GL_GetProcAddress( #q ); \ - if (! my_ ## q) { video.desktop.want_type = VIDEO_SURFACE; goto SKIP1; } - if (did_this_2) { - /* do nothing */ - } else if (getenv("SDL_VIDEO_GL_DRIVER") - && SDL_GL_LoadLibrary(getenv("SDL_VIDEO_GL_DRIVER")) == 0) { - /* ok */ - } else if (SDL_GL_LoadLibrary("GL") != 0) - if (SDL_GL_LoadLibrary("libGL.so") != 0) - if (SDL_GL_LoadLibrary("opengl32.dll") != 0) - if (SDL_GL_LoadLibrary("opengl.dll") != 0) - { /* do nothing ... because the bottom routines will fail */ } - did_this_2 = 1; - Z(glCallList) - Z(glTexSubImage2D) - Z(glDeleteLists) - Z(glTexParameteri) - Z(glBegin) - Z(glEnd) - Z(glEndList) - Z(glTexCoord2f) - Z(glVertex2f) - Z(glNewList) - Z(glIsList) - Z(glGenLists) - Z(glLoadIdentity) - Z(glMatrixMode) - Z(glEnable) - Z(glDisable) - Z(glBindTexture) - Z(glClear) - Z(glClearColor) - Z(glGetString) - Z(glTexImage2D) - Z(glGetIntegerv) - Z(glShadeModel) - Z(glGenTextures) - Z(glDeleteTextures) - Z(glViewport) - Z(glEnableClientState) + if (! my_ ## q) { video.desktop.want_type = VIDEO_SURFACE; goto SKIP1; } + if (did_this_2) { + /* do nothing */ + } else if (getenv("SDL_VIDEO_GL_DRIVER") + && SDL_GL_LoadLibrary(getenv("SDL_VIDEO_GL_DRIVER")) == 0) { + /* ok */ + } else if (SDL_GL_LoadLibrary("GL") != 0) + if (SDL_GL_LoadLibrary("libGL.so") != 0) + if (SDL_GL_LoadLibrary("opengl32.dll") != 0) + if (SDL_GL_LoadLibrary("opengl.dll") != 0) + { /* do nothing ... because the bottom routines will fail */ } + did_this_2 = 1; + Z(glCallList) + Z(glTexSubImage2D) + Z(glDeleteLists) + Z(glTexParameteri) + Z(glBegin) + Z(glEnd) + Z(glEndList) + Z(glTexCoord2f) + Z(glVertex2f) + Z(glNewList) + Z(glIsList) + Z(glGenLists) + Z(glLoadIdentity) + Z(glMatrixMode) + Z(glEnable) + Z(glDisable) + Z(glBindTexture) + Z(glClear) + Z(glClearColor) + Z(glGetString) + Z(glTexImage2D) + Z(glGetIntegerv) + Z(glShadeModel) + Z(glGenTextures) + Z(glDeleteTextures) + Z(glViewport) + Z(glEnableClientState) #undef Z - } + } SKIP1: #endif - if (video.desktop.want_type == VIDEO_GL) { + if (video.desktop.want_type == VIDEO_GL) { #if defined(USE_OPENGL) - video.surface = SDL_SetVideoMode(640,400,0,SDL_OPENGL|SDL_RESIZABLE); - if (!video.surface) { - /* fallback */ - video.desktop.want_type = VIDEO_SURFACE; - } - video.gl.framebuf = NULL; - video.gl.texture = 0; - video.gl.displaylist = 0; - my_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &video.gl.max_texsize); + video.surface = SDL_SetVideoMode(640,400,0,SDL_OPENGL|SDL_RESIZABLE); + if (!video.surface) { + /* fallback */ + video.desktop.want_type = VIDEO_SURFACE; + } + video.gl.framebuf = NULL; + video.gl.texture = 0; + video.gl.displaylist = 0; + my_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &video.gl.max_texsize); #if defined(NVIDIA_PixelDataRange) - glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) - SDL_GL_GetProcAddress("glPixelDataRangeNV"); - db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) - SDL_GL_GetProcAddress("wglAllocateMemoryNV"); - db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) - SDL_GL_GetProcAddress("wglFreeMemoryNV"); -#endif - gl_ext = (const char *)my_glGetString(GL_EXTENSIONS); - if (!gl_ext) gl_ext = (const char *)""; - video.gl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") != NULL); - video.gl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") != NULL); + glPixelDataRangeNV = (PFNGLPIXELDATARANGENVPROC) + SDL_GL_GetProcAddress("glPixelDataRangeNV"); + db_glAllocateMemoryNV = (PFNWGLALLOCATEMEMORYNVPROC) + SDL_GL_GetProcAddress("wglAllocateMemoryNV"); + db_glFreeMemoryNV = (PFNWGLFREEMEMORYNVPROC) + SDL_GL_GetProcAddress("wglFreeMemoryNV"); +#endif + gl_ext = (const char *)my_glGetString(GL_EXTENSIONS); + if (!gl_ext) gl_ext = (const char *)""; + video.gl.packed_pixel=(strstr(gl_ext,"EXT_packed_pixels") != NULL); + video.gl.paletted_texture=(strstr(gl_ext,"EXT_paletted_texture") != NULL); #if defined(NVIDIA_PixelDataRange) - video.gl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") != NULL) - && glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; + video.gl.pixel_data_range=(strstr(gl_ext,"GL_NV_pixel_data_range") != NULL) + && glPixelDataRangeNV && db_glAllocateMemoryNV && db_glFreeMemoryNV; #endif #endif // USE_OPENGL - } + } - x = y = -1; - if ((q = getenv("SCHISM_VIDEO_RESOLUTION"))) { - i = j = -1; - if (sscanf(q,"%dx%d", &i,&j) == 2 && i >= 10 && j >= 10) { - x = i; - y = j; - } - } + x = y = -1; + if ((q = getenv("SCHISM_VIDEO_RESOLUTION"))) { + i = j = -1; + if (sscanf(q,"%dx%d", &i,&j) == 2 && i >= 10 && j >= 10) { + x = i; + y = j; + } + } #if HAVE_LINUX_FB_H - if (!getenv("DISPLAY") && !video.desktop.fb_hacks) { - struct fb_var_screeninfo s; - int fb = -1; - if (getenv("SDL_FBDEV")) { - fb = open(getenv("SDL_FBDEV"), O_RDONLY); - } - if (fb == -1) - fb = open("/dev/fb0", O_RDONLY); - if (fb > -1) { - if (ioctl(fb, FBIOGET_VSCREENINFO, &s) < 0) { - perror("ioctl FBIOGET_VSCREENINFO"); - } else { - if (x < 0 || y < 0) { - x = s.xres; - if (x < NATIVE_SCREEN_WIDTH) - x = NATIVE_SCREEN_WIDTH; - y = s.yres; - } - putenv((char *) "SDL_VIDEODRIVER=fbcon"); - video.desktop.bpp = s.bits_per_pixel; - video.desktop.fb_hacks = 1; - video.desktop.doublebuf = 1; - video.desktop.fullscreen = 0; - video.desktop.swsurface = 0; - video.surface = SDL_SetVideoMode(x,y, - video.desktop.bpp, - SDL_HWSURFACE - | SDL_DOUBLEBUF - | SDL_ASYNCBLIT); - } - close(fb); - } - } -#endif - if (!video.surface) { - /* if we already got one... */ - video.surface = SDL_SetVideoMode(640,400,0,SDL_RESIZABLE); - if (!video.surface) { - perror("SDL_SetVideoMode"); - exit(255); - } - } - video.desktop.bpp = video.surface->format->BitsPerPixel; - - if (x < 0 || y < 0) { - modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); - if (modes != (SDL_Rect**)0 && modes != (SDL_Rect**)-1) { - for (i = 0; modes[i]; i++) { - if (modes[i]->w < NATIVE_SCREEN_WIDTH) continue; - if (modes[i]->h < NATIVE_SCREEN_HEIGHT)continue; - if (x == -1 || y == -1 || modes[i]->w < x || modes[i]->h < y) { - if (modes[i]->w != NATIVE_SCREEN_WIDTH - || modes[i]->h != NATIVE_SCREEN_HEIGHT) { - if (x == NATIVE_SCREEN_WIDTH || y == NATIVE_SCREEN_HEIGHT) - continue; - } - x = modes[i]->w; - y = modes[i]->h; - if (best_resolution(x,y)) - break; - } - } - } - } - if (x < 0 || y < 0) { - x = 640; - y = 480; - } - - video.desktop.want_fixed = -1; - q = getenv("SCHISM_VIDEO_ASPECT"); - if (q && (strcasecmp(q,"nofixed") == 0 || strcasecmp(q,"full")==0 - || strcasecmp(q,"fit") == 0 || strcasecmp(q,"wide") == 0 - || strcasecmp(q,"no-fixed") == 0)) - video.desktop.want_fixed = 0; - - if ((q = getenv("SCHISM_VIDEO_DEPTH"))) { - i=atoi(q); - if (i == 32) video.desktop.bpp=32; - else if (i == 24) video.desktop.bpp=24; - else if (i == 16) video.desktop.bpp=16; - else if (i == 8) video.desktop.bpp=8; - } - - /*log_appendf(2, "Ideal desktop size: %dx%d", x, y); */ - video.desktop.width = x; - video.desktop.height = y; + if (!getenv("DISPLAY") && !video.desktop.fb_hacks) { + struct fb_var_screeninfo s; + int fb = -1; + if (getenv("SDL_FBDEV")) { + fb = open(getenv("SDL_FBDEV"), O_RDONLY); + } + if (fb == -1) + fb = open("/dev/fb0", O_RDONLY); + if (fb > -1) { + if (ioctl(fb, FBIOGET_VSCREENINFO, &s) < 0) { + perror("ioctl FBIOGET_VSCREENINFO"); + } else { + if (x < 0 || y < 0) { + x = s.xres; + if (x < NATIVE_SCREEN_WIDTH) + x = NATIVE_SCREEN_WIDTH; + y = s.yres; + } + putenv((char *) "SDL_VIDEODRIVER=fbcon"); + video.desktop.bpp = s.bits_per_pixel; + video.desktop.fb_hacks = 1; + video.desktop.doublebuf = 1; + video.desktop.fullscreen = 0; + video.desktop.swsurface = 0; + video.surface = SDL_SetVideoMode(x,y, + video.desktop.bpp, + SDL_HWSURFACE + | SDL_DOUBLEBUF + | SDL_ASYNCBLIT); + } + close(fb); + } + } +#endif + if (!video.surface) { + /* if we already got one... */ + video.surface = SDL_SetVideoMode(640,400,0,SDL_RESIZABLE); + if (!video.surface) { + perror("SDL_SetVideoMode"); + exit(255); + } + } + video.desktop.bpp = video.surface->format->BitsPerPixel; + + if (x < 0 || y < 0) { + modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); + if (modes != (SDL_Rect**)0 && modes != (SDL_Rect**)-1) { + for (i = 0; modes[i]; i++) { + if (modes[i]->w < NATIVE_SCREEN_WIDTH) continue; + if (modes[i]->h < NATIVE_SCREEN_HEIGHT)continue; + if (x == -1 || y == -1 || modes[i]->w < x || modes[i]->h < y) { + if (modes[i]->w != NATIVE_SCREEN_WIDTH + || modes[i]->h != NATIVE_SCREEN_HEIGHT) { + if (x == NATIVE_SCREEN_WIDTH || y == NATIVE_SCREEN_HEIGHT) + continue; + } + x = modes[i]->w; + y = modes[i]->h; + if (best_resolution(x,y)) + break; + } + } + } + } + if (x < 0 || y < 0) { + x = 640; + y = 480; + } + + video.desktop.want_fixed = -1; + q = getenv("SCHISM_VIDEO_ASPECT"); + if (q && (strcasecmp(q,"nofixed") == 0 || strcasecmp(q,"full")==0 + || strcasecmp(q,"fit") == 0 || strcasecmp(q,"wide") == 0 + || strcasecmp(q,"no-fixed") == 0)) + video.desktop.want_fixed = 0; + + if ((q = getenv("SCHISM_VIDEO_DEPTH"))) { + i=atoi(q); + if (i == 32) video.desktop.bpp=32; + else if (i == 24) video.desktop.bpp=24; + else if (i == 16) video.desktop.bpp=16; + else if (i == 8) video.desktop.bpp=8; + } + + /*log_appendf(2, "Ideal desktop size: %dx%d", x, y); */ + video.desktop.width = x; + video.desktop.height = y; - switch (video.desktop.want_type) { - case VIDEO_YUV: + switch (video.desktop.want_type) { + case VIDEO_YUV: #ifdef MACOSX - video.desktop.swsurface = 1; + video.desktop.swsurface = 1; #else - video.desktop.swsurface = 0; + video.desktop.swsurface = 0; #endif - break; + break; - case VIDEO_GL: + case VIDEO_GL: #ifdef MACOSX - video.desktop.swsurface = 1; + video.desktop.swsurface = 1; #else - video.desktop.swsurface = 0; + video.desktop.swsurface = 0; #endif - video.gl.bilinear = 1; - if (video.desktop.bpp == 32 || video.desktop.bpp == 16) break; - /* fall through */ - case VIDEO_DDRAW: + video.gl.bilinear = 1; + if (video.desktop.bpp == 32 || video.desktop.bpp == 16) break; + /* fall through */ + case VIDEO_DDRAW: #ifdef WIN32 - if (video.desktop.bpp == 32 || video.desktop.bpp == 16) { - /* good enough for here! */ - video.desktop.want_type = VIDEO_DDRAW; - break; - } -#endif - /* fall through */ - case VIDEO_SURFACE: - /* no scaling when using the SDL surfaces directly */ - video.desktop.swsurface = 1; - video.desktop.want_type = VIDEO_SURFACE; - break; - }; - /* okay, i think we're ready */ - SDL_ShowCursor(SDL_DISABLE); + if (video.desktop.bpp == 32 || video.desktop.bpp == 16) { + /* good enough for here! */ + video.desktop.want_type = VIDEO_DDRAW; + break; + } +#endif + /* fall through */ + case VIDEO_SURFACE: + /* no scaling when using the SDL surfaces directly */ + video.desktop.swsurface = 1; + video.desktop.want_type = VIDEO_SURFACE; + break; + }; + /* okay, i think we're ready */ + SDL_ShowCursor(SDL_DISABLE); #if 0 /* Do we need these? Everything seems to work just fine without */ - SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE); - SDL_EventState(SDL_VIDEOEXPOSE, SDL_ENABLE); - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - SDL_EventState(SDL_USEREVENT, SDL_ENABLE); - SDL_EventState(SDL_ACTIVEEVENT, SDL_ENABLE); - SDL_EventState(SDL_KEYDOWN, SDL_ENABLE); - SDL_EventState(SDL_KEYUP, SDL_ENABLE); - SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE); - SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE); - SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE); + SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE); + SDL_EventState(SDL_VIDEOEXPOSE, SDL_ENABLE); + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); + SDL_EventState(SDL_USEREVENT, SDL_ENABLE); + SDL_EventState(SDL_ACTIVEEVENT, SDL_ENABLE); + SDL_EventState(SDL_KEYDOWN, SDL_ENABLE); + SDL_EventState(SDL_KEYUP, SDL_ENABLE); + SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE); + SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE); + SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE); #endif - _did_init = 1; - video_fullscreen(video.desktop.fullscreen); + _did_init = 1; + video_fullscreen(video.desktop.fullscreen); } static SDL_Surface *_setup_surface(unsigned int w, unsigned int h, unsigned int sdlflags) { - int want_fixed = video.desktop.want_fixed; + int want_fixed = video.desktop.want_fixed; - if (video.desktop.doublebuf) - sdlflags |= (SDL_DOUBLEBUF|SDL_ASYNCBLIT); - if (video.desktop.fullscreen) { - w = video.desktop.width; - h = video.desktop.height; - } else { - sdlflags |= SDL_RESIZABLE; - } - - if (want_fixed == -1 && best_resolution(w,h)) { - want_fixed = 0; - } - - if (want_fixed) { - double ratio_w = (double)w / (double)NATIVE_SCREEN_WIDTH; - double ratio_h = (double)h / (double)NATIVE_SCREEN_HEIGHT; - if (ratio_w < ratio_h) { - video.clip.w = w; - video.clip.h = (double)NATIVE_SCREEN_HEIGHT * ratio_w; - } else { - video.clip.h = h; - video.clip.w = (double)NATIVE_SCREEN_WIDTH * ratio_h; - } - video.clip.x=(w-video.clip.w)/2; - video.clip.y=(h-video.clip.h)/2; - } else { - video.clip.x = 0; - video.clip.y = 0; - video.clip.w = w; - video.clip.h = h; - } - - if (video.desktop.fb_hacks && video.surface) { - /* the original one will be _just fine_ */ - } else { - if (video.desktop.fullscreen) { - sdlflags &=~SDL_RESIZABLE; - sdlflags |= SDL_FULLSCREEN; - } else { - sdlflags &=~SDL_FULLSCREEN; - sdlflags |= SDL_RESIZABLE; - } - sdlflags |= (video.desktop.swsurface - ? SDL_SWSURFACE - : SDL_HWSURFACE); - video.surface = SDL_SetVideoMode(w, h, - video.desktop.bpp, sdlflags); - } - if (!video.surface) { - perror("SDL_SetVideoMode"); - exit(EXIT_FAILURE); - } - return video.surface; + if (video.desktop.doublebuf) + sdlflags |= (SDL_DOUBLEBUF|SDL_ASYNCBLIT); + if (video.desktop.fullscreen) { + w = video.desktop.width; + h = video.desktop.height; + } else { + sdlflags |= SDL_RESIZABLE; + } + + if (want_fixed == -1 && best_resolution(w,h)) { + want_fixed = 0; + } + + if (want_fixed) { + double ratio_w = (double)w / (double)NATIVE_SCREEN_WIDTH; + double ratio_h = (double)h / (double)NATIVE_SCREEN_HEIGHT; + if (ratio_w < ratio_h) { + video.clip.w = w; + video.clip.h = (double)NATIVE_SCREEN_HEIGHT * ratio_w; + } else { + video.clip.h = h; + video.clip.w = (double)NATIVE_SCREEN_WIDTH * ratio_h; + } + video.clip.x=(w-video.clip.w)/2; + video.clip.y=(h-video.clip.h)/2; + } else { + video.clip.x = 0; + video.clip.y = 0; + video.clip.w = w; + video.clip.h = h; + } + + if (video.desktop.fb_hacks && video.surface) { + /* the original one will be _just fine_ */ + } else { + if (video.desktop.fullscreen) { + sdlflags &=~SDL_RESIZABLE; + sdlflags |= SDL_FULLSCREEN; + } else { + sdlflags &=~SDL_FULLSCREEN; + sdlflags |= SDL_RESIZABLE; + } + sdlflags |= (video.desktop.swsurface + ? SDL_SWSURFACE + : SDL_HWSURFACE); + video.surface = SDL_SetVideoMode(w, h, + video.desktop.bpp, sdlflags); + } + if (!video.surface) { + perror("SDL_SetVideoMode"); + exit(EXIT_FAILURE); + } + return video.surface; } #if USE_OPENGL static void _set_gl_attributes(void) { - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32); - SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0); - SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 0); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 0); #if SDL_VERSION_ATLEAST(1,2,11) - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0); #endif } #endif @@ -905,448 +905,448 @@ void video_resize(unsigned int width, unsigned int height) { #if USE_OPENGL - GLfloat tex_width, tex_height; - int texsize; + GLfloat tex_width, tex_height; + int texsize; #endif - if (!height) height = NATIVE_SCREEN_HEIGHT; - if (!width) width = NATIVE_SCREEN_WIDTH; - video.draw.width = width; - video.draw.height = height; + if (!height) height = NATIVE_SCREEN_HEIGHT; + if (!width) width = NATIVE_SCREEN_WIDTH; + video.draw.width = width; + video.draw.height = height; - video.draw.autoscale = 1; + video.draw.autoscale = 1; - switch (video.desktop.want_type) { - case VIDEO_DDRAW: + switch (video.desktop.want_type) { + case VIDEO_DDRAW: #ifdef WIN32 - if (video.ddblit.surface) { - SDL_FreeSurface(video.ddblit.surface); - video.ddblit.surface = 0; - } - memset(&video.ddblit.fx, 0, sizeof(DDBLTFX)); - video.ddblit.fx.dwSize = sizeof(DDBLTFX); - _setup_surface(width, height, SDL_DOUBLEBUF); - video.ddblit.rect.top = video.clip.y; - video.ddblit.rect.left = video.clip.x; - video.ddblit.rect.right = video.clip.x + video.clip.w; - video.ddblit.rect.bottom = video.clip.y + video.clip.h; - video.ddblit.surface = SDL_CreateRGBSurface(SDL_HWSURFACE, - NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, - video.surface->format->BitsPerPixel, - video.surface->format->Rmask, - video.surface->format->Gmask, - video.surface->format->Bmask,0); - if (video.ddblit.surface - && ((video.ddblit.surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) { - video.desktop.type = VIDEO_DDRAW; - break; - } - /* fall through */ + if (video.ddblit.surface) { + SDL_FreeSurface(video.ddblit.surface); + video.ddblit.surface = 0; + } + memset(&video.ddblit.fx, 0, sizeof(DDBLTFX)); + video.ddblit.fx.dwSize = sizeof(DDBLTFX); + _setup_surface(width, height, SDL_DOUBLEBUF); + video.ddblit.rect.top = video.clip.y; + video.ddblit.rect.left = video.clip.x; + video.ddblit.rect.right = video.clip.x + video.clip.w; + video.ddblit.rect.bottom = video.clip.y + video.clip.h; + video.ddblit.surface = SDL_CreateRGBSurface(SDL_HWSURFACE, + NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, + video.surface->format->BitsPerPixel, + video.surface->format->Rmask, + video.surface->format->Gmask, + video.surface->format->Bmask,0); + if (video.ddblit.surface + && ((video.ddblit.surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)) { + video.desktop.type = VIDEO_DDRAW; + break; + } + /* fall through */ #endif - case VIDEO_SURFACE: + case VIDEO_SURFACE: RETRYSURF: /* use SDL surfaces */ - video.draw.autoscale = 0; - if (video.desktop.fb_hacks - && (video.desktop.width != NATIVE_SCREEN_WIDTH - || video.desktop.height != NATIVE_SCREEN_HEIGHT)) { - video.draw.autoscale = 1; - } - _setup_surface(width, height, 0); - video.desktop.type = VIDEO_SURFACE; - break; - - case VIDEO_YUV: - if (video.overlay) { - SDL_FreeYUVOverlay(video.overlay); - video.overlay = NULL; - } - _setup_surface(width, height, 0); - /* TODO: switch? */ - switch (video.yuvlayout) { - case VIDEO_YUV_YV12_TV: - video.overlay = SDL_CreateYUVOverlay - (NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, - SDL_YV12_OVERLAY, video.surface); - break; - case VIDEO_YUV_IYUV_TV: - video.overlay = SDL_CreateYUVOverlay - (NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, - SDL_IYUV_OVERLAY, video.surface); - break; - case VIDEO_YUV_YV12: - video.overlay = SDL_CreateYUVOverlay - (2 * NATIVE_SCREEN_WIDTH, - 2 * NATIVE_SCREEN_HEIGHT, - SDL_YV12_OVERLAY, video.surface); - break; - case VIDEO_YUV_IYUV: - video.overlay = SDL_CreateYUVOverlay - (2 * NATIVE_SCREEN_WIDTH, - 2 * NATIVE_SCREEN_HEIGHT, - SDL_IYUV_OVERLAY, video.surface); - break; - case VIDEO_YUV_UYVY: - video.overlay = SDL_CreateYUVOverlay - (2 * NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - SDL_UYVY_OVERLAY, video.surface); - break; - case VIDEO_YUV_YVYU: - video.overlay = SDL_CreateYUVOverlay - (2 * NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - SDL_YVYU_OVERLAY, video.surface); - break; - case VIDEO_YUV_YUY2: - video.overlay = SDL_CreateYUVOverlay - (2 * NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - SDL_YUY2_OVERLAY, video.surface); - break; - case VIDEO_YUV_RGBA: - case VIDEO_YUV_RGB32: - video.overlay = SDL_CreateYUVOverlay - (4*NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - video.yuvlayout, video.surface); - break; - case VIDEO_YUV_RGB24: - video.overlay = SDL_CreateYUVOverlay - (3*NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - video.yuvlayout, video.surface); - break; - case VIDEO_YUV_RGBT: - case VIDEO_YUV_RGB565: - video.overlay = SDL_CreateYUVOverlay - (2*NATIVE_SCREEN_WIDTH, - NATIVE_SCREEN_HEIGHT, - video.yuvlayout, video.surface); - break; - - default: - /* unknown layout */ - goto RETRYSURF; - } - if (!video.overlay) { - /* can't get an overlay */ - goto RETRYSURF; - } - switch (video.overlay->planes) { - case 3: - case 1: - break; - default: - /* can't get a recognized planes */ - SDL_FreeYUVOverlay(video.overlay); - video.overlay = NULL; - goto RETRYSURF; - }; - video.desktop.type = VIDEO_YUV; - break; + video.draw.autoscale = 0; + if (video.desktop.fb_hacks + && (video.desktop.width != NATIVE_SCREEN_WIDTH + || video.desktop.height != NATIVE_SCREEN_HEIGHT)) { + video.draw.autoscale = 1; + } + _setup_surface(width, height, 0); + video.desktop.type = VIDEO_SURFACE; + break; + + case VIDEO_YUV: + if (video.overlay) { + SDL_FreeYUVOverlay(video.overlay); + video.overlay = NULL; + } + _setup_surface(width, height, 0); + /* TODO: switch? */ + switch (video.yuvlayout) { + case VIDEO_YUV_YV12_TV: + video.overlay = SDL_CreateYUVOverlay + (NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, + SDL_YV12_OVERLAY, video.surface); + break; + case VIDEO_YUV_IYUV_TV: + video.overlay = SDL_CreateYUVOverlay + (NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, + SDL_IYUV_OVERLAY, video.surface); + break; + case VIDEO_YUV_YV12: + video.overlay = SDL_CreateYUVOverlay + (2 * NATIVE_SCREEN_WIDTH, + 2 * NATIVE_SCREEN_HEIGHT, + SDL_YV12_OVERLAY, video.surface); + break; + case VIDEO_YUV_IYUV: + video.overlay = SDL_CreateYUVOverlay + (2 * NATIVE_SCREEN_WIDTH, + 2 * NATIVE_SCREEN_HEIGHT, + SDL_IYUV_OVERLAY, video.surface); + break; + case VIDEO_YUV_UYVY: + video.overlay = SDL_CreateYUVOverlay + (2 * NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + SDL_UYVY_OVERLAY, video.surface); + break; + case VIDEO_YUV_YVYU: + video.overlay = SDL_CreateYUVOverlay + (2 * NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + SDL_YVYU_OVERLAY, video.surface); + break; + case VIDEO_YUV_YUY2: + video.overlay = SDL_CreateYUVOverlay + (2 * NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + SDL_YUY2_OVERLAY, video.surface); + break; + case VIDEO_YUV_RGBA: + case VIDEO_YUV_RGB32: + video.overlay = SDL_CreateYUVOverlay + (4*NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + video.yuvlayout, video.surface); + break; + case VIDEO_YUV_RGB24: + video.overlay = SDL_CreateYUVOverlay + (3*NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + video.yuvlayout, video.surface); + break; + case VIDEO_YUV_RGBT: + case VIDEO_YUV_RGB565: + video.overlay = SDL_CreateYUVOverlay + (2*NATIVE_SCREEN_WIDTH, + NATIVE_SCREEN_HEIGHT, + video.yuvlayout, video.surface); + break; + + default: + /* unknown layout */ + goto RETRYSURF; + } + if (!video.overlay) { + /* can't get an overlay */ + goto RETRYSURF; + } + switch (video.overlay->planes) { + case 3: + case 1: + break; + default: + /* can't get a recognized planes */ + SDL_FreeYUVOverlay(video.overlay); + video.overlay = NULL; + goto RETRYSURF; + }; + video.desktop.type = VIDEO_YUV; + break; #if defined(USE_OPENGL) - case VIDEO_GL: - _set_gl_attributes(); - _setup_surface(width, height, SDL_OPENGL); - if (video.surface->format->BitsPerPixel < 15) { - goto RETRYSURF; - } - /* grumble... */ - _set_gl_attributes(); - my_glViewport(video.clip.x, video.clip.y, - video.clip.w, video.clip.h); - texsize = 2 << int_log2(NATIVE_SCREEN_WIDTH); - if (texsize > video.gl.max_texsize) { - /* can't do opengl! */ - goto RETRYSURF; - } + case VIDEO_GL: + _set_gl_attributes(); + _setup_surface(width, height, SDL_OPENGL); + if (video.surface->format->BitsPerPixel < 15) { + goto RETRYSURF; + } + /* grumble... */ + _set_gl_attributes(); + my_glViewport(video.clip.x, video.clip.y, + video.clip.w, video.clip.h); + texsize = 2 << int_log2(NATIVE_SCREEN_WIDTH); + if (texsize > video.gl.max_texsize) { + /* can't do opengl! */ + goto RETRYSURF; + } #if defined(NVIDIA_PixelDataRange) - if (video.gl.pixel_data_range) { - if (!video.gl.framebuf) { - video.gl.framebuf = db_glAllocateMemoryNV( - NATIVE_SCREEN_WIDTH*NATIVE_SCREEN_HEIGHT*4, - 0.0, 1.0, 1.0); - } - glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, - NATIVE_SCREEN_WIDTH*NATIVE_SCREEN_HEIGHT*4, - video.gl.framebuf); - my_glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); - } else -#endif - if (!video.gl.framebuf) { - video.gl.framebuf = mem_alloc(NATIVE_SCREEN_WIDTH - *NATIVE_SCREEN_HEIGHT*4); - } - - video.gl.pitch = NATIVE_SCREEN_WIDTH * 4; - my_glMatrixMode(GL_PROJECTION); - my_glDeleteTextures(1, &video.gl.texture); - my_glGenTextures(1, &video.gl.texture); - my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - if (video.gl.bilinear) { - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_LINEAR); - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR); - } else { - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - GL_NEAREST); - my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_NEAREST); - } - my_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, - 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); - my_glClearColor(0.0, 0.0, 0.0, 1.0); - my_glClear(GL_COLOR_BUFFER_BIT); - SDL_GL_SwapBuffers(); - my_glClear(GL_COLOR_BUFFER_BIT); - my_glShadeModel(GL_FLAT); - my_glDisable(GL_DEPTH_TEST); - my_glDisable(GL_LIGHTING); - my_glDisable(GL_CULL_FACE); - my_glEnable(GL_TEXTURE_2D); - my_glMatrixMode(GL_MODELVIEW); - my_glLoadIdentity(); - - tex_width = ((GLfloat)(NATIVE_SCREEN_WIDTH)/(GLfloat)texsize); - tex_height = ((GLfloat)(NATIVE_SCREEN_HEIGHT)/(GLfloat)texsize); - if (my_glIsList(video.gl.displaylist)) - my_glDeleteLists(video.gl.displaylist, 1); - video.gl.displaylist = my_glGenLists(1); - my_glNewList(video.gl.displaylist, GL_COMPILE); - my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); - my_glBegin(GL_QUADS); - my_glTexCoord2f(0,tex_height); my_glVertex2f(-1.0f,-1.0f); - my_glTexCoord2f(tex_width,tex_height);my_glVertex2f(1.0f,-1.0f); - my_glTexCoord2f(tex_width,0); my_glVertex2f(1.0f, 1.0f); - my_glTexCoord2f(0,0); my_glVertex2f(-1.0f, 1.0f); - my_glEnd(); - my_glEndList(); - video.desktop.type = VIDEO_GL; - break; + if (video.gl.pixel_data_range) { + if (!video.gl.framebuf) { + video.gl.framebuf = db_glAllocateMemoryNV( + NATIVE_SCREEN_WIDTH*NATIVE_SCREEN_HEIGHT*4, + 0.0, 1.0, 1.0); + } + glPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, + NATIVE_SCREEN_WIDTH*NATIVE_SCREEN_HEIGHT*4, + video.gl.framebuf); + my_glEnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV); + } else +#endif + if (!video.gl.framebuf) { + video.gl.framebuf = mem_alloc(NATIVE_SCREEN_WIDTH + *NATIVE_SCREEN_HEIGHT*4); + } + + video.gl.pitch = NATIVE_SCREEN_WIDTH * 4; + my_glMatrixMode(GL_PROJECTION); + my_glDeleteTextures(1, &video.gl.texture); + my_glGenTextures(1, &video.gl.texture); + my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + if (video.gl.bilinear) { + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR); + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); + } else { + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + my_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + } + my_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texsize, texsize, + 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); + my_glClearColor(0.0, 0.0, 0.0, 1.0); + my_glClear(GL_COLOR_BUFFER_BIT); + SDL_GL_SwapBuffers(); + my_glClear(GL_COLOR_BUFFER_BIT); + my_glShadeModel(GL_FLAT); + my_glDisable(GL_DEPTH_TEST); + my_glDisable(GL_LIGHTING); + my_glDisable(GL_CULL_FACE); + my_glEnable(GL_TEXTURE_2D); + my_glMatrixMode(GL_MODELVIEW); + my_glLoadIdentity(); + + tex_width = ((GLfloat)(NATIVE_SCREEN_WIDTH)/(GLfloat)texsize); + tex_height = ((GLfloat)(NATIVE_SCREEN_HEIGHT)/(GLfloat)texsize); + if (my_glIsList(video.gl.displaylist)) + my_glDeleteLists(video.gl.displaylist, 1); + video.gl.displaylist = my_glGenLists(1); + my_glNewList(video.gl.displaylist, GL_COMPILE); + my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); + my_glBegin(GL_QUADS); + my_glTexCoord2f(0,tex_height); my_glVertex2f(-1.0f,-1.0f); + my_glTexCoord2f(tex_width,tex_height);my_glVertex2f(1.0f,-1.0f); + my_glTexCoord2f(tex_width,0); my_glVertex2f(1.0f, 1.0f); + my_glTexCoord2f(0,0); my_glVertex2f(-1.0f, 1.0f); + my_glEnd(); + my_glEndList(); + video.desktop.type = VIDEO_GL; + break; #endif // USE_OPENGL - }; + }; - status.flags |= (NEED_UPDATE); + status.flags |= (NEED_UPDATE); } static void _make_yuv(unsigned int *y, unsigned int *u, unsigned int *v, - int rgb[3]) + int rgb[3]) { - double red, green, blue, yy, cr, cb, ry, ru, rv; - int r = rgb[0]; - int g = rgb[1]; - int b = rgb[2]; - - red = (double)r / 255.0; - green = (double)g / 255.0; - blue = (double)b / 255.0; - yy = 0.299 * red + 0.587 * green + 0.114 * blue; - cb = blue - yy; - cr = red - yy; - ry = 16.0 + 219.0 * yy; - ru = 128.0 + 126.0 * cb; - rv = 128.0 + 160.0 * cr; - *y = (uint8_t) ry; - *u = (uint8_t) ru; - *v = (uint8_t) rv; + double red, green, blue, yy, cr, cb, ry, ru, rv; + int r = rgb[0]; + int g = rgb[1]; + int b = rgb[2]; + + red = (double)r / 255.0; + green = (double)g / 255.0; + blue = (double)b / 255.0; + yy = 0.299 * red + 0.587 * green + 0.114 * blue; + cb = blue - yy; + cr = red - yy; + ry = 16.0 + 219.0 * yy; + ru = 128.0 + 126.0 * cb; + rv = 128.0 + 160.0 * cr; + *y = (uint8_t) ry; + *u = (uint8_t) ru; + *v = (uint8_t) rv; } static void _yuv_pal(int i, int rgb[3]) { - unsigned int y,u,v; - _make_yuv(&y, &u, &v, rgb); - switch (video.yuvlayout) { - /* planar modes */ - case VIDEO_YUV_YV12: - case VIDEO_YUV_IYUV: - /* this is fake; we simply record the infomration here */ - video.yuv_y[i] = y|(y<<8); - video.yuv_u[i] = u; - video.yuv_v[i] = v; - break; - - /* tv planar modes */ - case VIDEO_YUV_YV12_TV: - case VIDEO_YUV_IYUV_TV: - /* _blitTV */ - video.yuv_y[i] = y; - video.yuv_u[i] = (u >> 4) & 0xF; - video.yuv_v[i] = (v >> 4) & 0xF; - break; - - /* packed modes */ - case VIDEO_YUV_YVYU: - /* y0 v0 y1 u0 */ + unsigned int y,u,v; + _make_yuv(&y, &u, &v, rgb); + switch (video.yuvlayout) { + /* planar modes */ + case VIDEO_YUV_YV12: + case VIDEO_YUV_IYUV: + /* this is fake; we simply record the infomration here */ + video.yuv_y[i] = y|(y<<8); + video.yuv_u[i] = u; + video.yuv_v[i] = v; + break; + + /* tv planar modes */ + case VIDEO_YUV_YV12_TV: + case VIDEO_YUV_IYUV_TV: + /* _blitTV */ + video.yuv_y[i] = y; + video.yuv_u[i] = (u >> 4) & 0xF; + video.yuv_v[i] = (v >> 4) & 0xF; + break; + + /* packed modes */ + case VIDEO_YUV_YVYU: + /* y0 v0 y1 u0 */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN - video.pal[i] = u | (y << 8) | (v << 16) | (y << 24); + video.pal[i] = u | (y << 8) | (v << 16) | (y << 24); #else - video.pal[i] = y | (v << 8) | (y << 16) | (u << 24); + video.pal[i] = y | (v << 8) | (y << 16) | (u << 24); #endif - break; - case VIDEO_YUV_UYVY: - /* u0 y0 v0 y1 */ + break; + case VIDEO_YUV_UYVY: + /* u0 y0 v0 y1 */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN - video.pal[i] = y | (v << 8) | (y << 16) | (u << 24); + video.pal[i] = y | (v << 8) | (y << 16) | (u << 24); #else - video.pal[i] = u | (y << 8) | (v << 16) | (y << 24); + video.pal[i] = u | (y << 8) | (v << 16) | (y << 24); #endif - break; - case VIDEO_YUV_YUY2: - /* y0 u0 y1 v0 */ + break; + case VIDEO_YUV_YUY2: + /* y0 u0 y1 v0 */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN - video.pal[i] = v | (y << 8) | (u << 16) | (y << 24); + video.pal[i] = v | (y << 8) | (u << 16) | (y << 24); #else - video.pal[i] = y | (u << 8) | (y << 16) | (v << 24); + video.pal[i] = y | (u << 8) | (y << 16) | (v << 24); #endif - break; - case VIDEO_YUV_RGBA: - case VIDEO_YUV_RGB32: - video.pal[i] = rgb[2] | - (rgb[1] << 8) | - (rgb[0] << 16) | (255 << 24); - break; - case VIDEO_YUV_RGB24: - video.pal[i] = rgb[2] | - (rgb[1] << 8) | - (rgb[0] << 16); - break; - case VIDEO_YUV_RGBT: - video.pal[i] = - ((rgb[0] << 8) & 0x7c00) - | ((rgb[1] << 3) & 0x3e0) - | ((rgb[2] >> 2) & 0x1f); - break; - case VIDEO_YUV_RGB565: - video.pal[i] = - ((rgb[0] << 9) & 0xf800) - | ((rgb[1] << 4) & 0x7e0) - | ((rgb[2] >> 2) & 0x1f); - break; - }; + break; + case VIDEO_YUV_RGBA: + case VIDEO_YUV_RGB32: + video.pal[i] = rgb[2] | + (rgb[1] << 8) | + (rgb[0] << 16) | (255 << 24); + break; + case VIDEO_YUV_RGB24: + video.pal[i] = rgb[2] | + (rgb[1] << 8) | + (rgb[0] << 16); + break; + case VIDEO_YUV_RGBT: + video.pal[i] = + ((rgb[0] << 8) & 0x7c00) + | ((rgb[1] << 3) & 0x3e0) + | ((rgb[2] >> 2) & 0x1f); + break; + case VIDEO_YUV_RGB565: + video.pal[i] = + ((rgb[0] << 9) & 0xf800) + | ((rgb[1] << 4) & 0x7e0) + | ((rgb[2] >> 2) & 0x1f); + break; + }; } static void _sdl_pal(int i, int rgb[3]) { - video.pal[i] = SDL_MapRGB(video.surface->format, - rgb[0], rgb[1], rgb[2]); + video.pal[i] = SDL_MapRGB(video.surface->format, + rgb[0], rgb[1], rgb[2]); } static void _bgr32_pal(int i, int rgb[3]) { - video.tc_bgr32[i] = rgb[2] | - (rgb[1] << 8) | - (rgb[0] << 16) | (255 << 24); + video.tc_bgr32[i] = rgb[2] | + (rgb[1] << 8) | + (rgb[0] << 16) | (255 << 24); } static void _gl_pal(int i, int rgb[3]) { - video.pal[i] = rgb[2] | - (rgb[1] << 8) | - (rgb[0] << 16) | (255 << 24); + video.pal[i] = rgb[2] | + (rgb[1] << 8) | + (rgb[0] << 16) | (255 << 24); } void video_colors(unsigned char palette[16][3]) { - static SDL_Color imap[16]; - void (*fun)(int i,int rgb[3]); - const int lastmap[] = { 0,1,2,3,5 }; - int rgb[3], i, j, p; - - switch (video.desktop.type) { - case VIDEO_SURFACE: - if (video.surface->format->BytesPerPixel == 1) { - const int depthmap[] = { 0, 15,14,7, - 8, 8, 9, 12, - 6, 1, 2, 2, - 10, 3, 11, 11 }; - /* okay, indexed color */ - for (i = 0; i < 16; i++) { - video.pal[i] = i; - imap[i].r = palette[i][0]; - imap[i].g = palette[i][1]; - imap[i].b = palette[i][2]; - - rgb[0]=palette[i][0]; - rgb[1]=palette[i][1]; - rgb[2]=palette[i][2]; - _bgr32_pal(i, rgb); - - } - for (i = 128; i < 256; i++) { - video.pal[i] = depthmap[(i>>4)]; - } - for (i = 128; i < 256; i++) { - j = i - 128; - p = lastmap[(j>>5)]; - rgb[0] = (int)palette[p][0] + - (((int)(palette[p+1][0] - - palette[p][0]) * (j&31)) /32); - rgb[1] = (int)palette[p][1] + - (((int)(palette[p+1][1] - - palette[p][1]) * (j&31)) /32); - rgb[2] = (int)palette[p][2] + - (((int)(palette[p+1][2] - - palette[p][2]) * (j&31)) /32); - _bgr32_pal(i, rgb); - } - SDL_SetColors(video.surface, imap, 0, 16); - return; - } - /* fall through */ - case VIDEO_DDRAW: - fun = _sdl_pal; - break; - case VIDEO_YUV: - fun = _yuv_pal; - break; - case VIDEO_GL: - fun = _gl_pal; - break; - default: - /* eh? */ - return; - }; - /* make our "base" space */ - for (i = 0; i < 16; i++) { - rgb[0]=palette[i][0]; - rgb[1]=palette[i][1]; - rgb[2]=palette[i][2]; - fun(i, rgb); - _bgr32_pal(i, rgb); - } - /* make our "gradient" space */ - for (i = 128; i < 256; i++) { - j = i - 128; - p = lastmap[(j>>5)]; - rgb[0] = (int)palette[p][0] + - (((int)(palette[p+1][0] - palette[p][0]) * (j&31)) /32); - rgb[1] = (int)palette[p][1] + - (((int)(palette[p+1][1] - palette[p][1]) * (j&31)) /32); - rgb[2] = (int)palette[p][2] + - (((int)(palette[p+1][2] - palette[p][2]) * (j&31)) /32); - fun(i, rgb); - _bgr32_pal(i, rgb); - } + static SDL_Color imap[16]; + void (*fun)(int i,int rgb[3]); + const int lastmap[] = { 0,1,2,3,5 }; + int rgb[3], i, j, p; + + switch (video.desktop.type) { + case VIDEO_SURFACE: + if (video.surface->format->BytesPerPixel == 1) { + const int depthmap[] = { 0, 15,14,7, + 8, 8, 9, 12, + 6, 1, 2, 2, + 10, 3, 11, 11 }; + /* okay, indexed color */ + for (i = 0; i < 16; i++) { + video.pal[i] = i; + imap[i].r = palette[i][0]; + imap[i].g = palette[i][1]; + imap[i].b = palette[i][2]; + + rgb[0]=palette[i][0]; + rgb[1]=palette[i][1]; + rgb[2]=palette[i][2]; + _bgr32_pal(i, rgb); + + } + for (i = 128; i < 256; i++) { + video.pal[i] = depthmap[(i>>4)]; + } + for (i = 128; i < 256; i++) { + j = i - 128; + p = lastmap[(j>>5)]; + rgb[0] = (int)palette[p][0] + + (((int)(palette[p+1][0] + - palette[p][0]) * (j&31)) /32); + rgb[1] = (int)palette[p][1] + + (((int)(palette[p+1][1] + - palette[p][1]) * (j&31)) /32); + rgb[2] = (int)palette[p][2] + + (((int)(palette[p+1][2] + - palette[p][2]) * (j&31)) /32); + _bgr32_pal(i, rgb); + } + SDL_SetColors(video.surface, imap, 0, 16); + return; + } + /* fall through */ + case VIDEO_DDRAW: + fun = _sdl_pal; + break; + case VIDEO_YUV: + fun = _yuv_pal; + break; + case VIDEO_GL: + fun = _gl_pal; + break; + default: + /* eh? */ + return; + }; + /* make our "base" space */ + for (i = 0; i < 16; i++) { + rgb[0]=palette[i][0]; + rgb[1]=palette[i][1]; + rgb[2]=palette[i][2]; + fun(i, rgb); + _bgr32_pal(i, rgb); + } + /* make our "gradient" space */ + for (i = 128; i < 256; i++) { + j = i - 128; + p = lastmap[(j>>5)]; + rgb[0] = (int)palette[p][0] + + (((int)(palette[p+1][0] - palette[p][0]) * (j&31)) /32); + rgb[1] = (int)palette[p][1] + + (((int)(palette[p+1][1] - palette[p][1]) * (j&31)) /32); + rgb[2] = (int)palette[p][2] + + (((int)(palette[p+1][2] - palette[p][2]) * (j&31)) /32); + fun(i, rgb); + _bgr32_pal(i, rgb); + } } void video_refresh(void) { - vgamem_flip(); - vgamem_clear(); + vgamem_flip(); + vgamem_clear(); } static inline void make_mouseline(unsigned int x, unsigned int v, unsigned int y, unsigned int mouseline[80]) { - unsigned int z; + unsigned int z; - memset(mouseline, 0, 80*sizeof(unsigned int)); - if (video.mouse.visible != MOUSE_EMULATED - || !(status.flags & IS_FOCUSED) - || y < video.mouse.y - || y >= video.mouse.y+MOUSE_HEIGHT) { - return; - } - - z = _mouse_pointer[ y - video.mouse.y ]; - mouseline[x] = z >> v; - if (x < 79) mouseline[x+1] = (z << (8-v)) & 0xff; + memset(mouseline, 0, 80*sizeof(unsigned int)); + if (video.mouse.visible != MOUSE_EMULATED + || !(status.flags & IS_FOCUSED) + || y < video.mouse.y + || y >= video.mouse.y+MOUSE_HEIGHT) { + return; + } + + z = _mouse_pointer[ y - video.mouse.y ]; + mouseline[x] = z >> v; + if (x < 79) mouseline[x+1] = (z << (8-v)) & 0xff; } @@ -1359,455 +1359,455 @@ static void _blit1n(int bpp, unsigned char *pixels, unsigned int pitch) { - unsigned int *csp, *esp, *dp; - unsigned int c00, c01, c10, c11; - unsigned int outr, outg, outb; - unsigned int pad; - int fixedx, fixedy, scalex, scaley; - unsigned int y, x,ey,ex,t1,t2; - unsigned int mouseline[80]; - unsigned int mouseline_x, mouseline_v; - int iny, lasty; - - mouseline_x = (video.mouse.x / 8); - mouseline_v = (video.mouse.x % 8); - - csp = (unsigned int *)video.cv32backing; - esp = csp + NATIVE_SCREEN_WIDTH; - lasty = -2; - iny = 0; - pad = pitch - (video.clip.w * bpp); - scalex = INT2FIXED(NATIVE_SCREEN_WIDTH-1) / video.clip.w; - scaley = INT2FIXED(NATIVE_SCREEN_HEIGHT-1) / video.clip.h; - for (y = 0, fixedy = 0; (y < video.clip.h); y++, fixedy += scaley) { - iny = FIXED2INT(fixedy); - if (iny != lasty) { - make_mouseline(mouseline_x, mouseline_v, iny, mouseline); - - /* we'll downblit the colors later */ - if (iny == lasty + 1) { - /* move up one line */ - vgamem_scan32(iny+1, csp, video.tc_bgr32, mouseline); - dp = esp; esp = csp; csp=dp; - } else { - vgamem_scan32(iny, (csp = (unsigned int *)video.cv32backing), - video.tc_bgr32, mouseline); - vgamem_scan32(iny+1, (esp = (csp + NATIVE_SCREEN_WIDTH)), - video.tc_bgr32, mouseline); - } - lasty = iny; - } - for (x = 0, fixedx = 0; x < video.clip.w; x++, fixedx += scalex) { - ex = FRAC(fixedx); - ey = FRAC(fixedy); - - c00 = csp[FIXED2INT(fixedx)]; - c01 = csp[FIXED2INT(fixedx) + 1]; - c10 = esp[FIXED2INT(fixedx)]; - c11 = esp[FIXED2INT(fixedx) + 1]; + unsigned int *csp, *esp, *dp; + unsigned int c00, c01, c10, c11; + unsigned int outr, outg, outb; + unsigned int pad; + int fixedx, fixedy, scalex, scaley; + unsigned int y, x,ey,ex,t1,t2; + unsigned int mouseline[80]; + unsigned int mouseline_x, mouseline_v; + int iny, lasty; + + mouseline_x = (video.mouse.x / 8); + mouseline_v = (video.mouse.x % 8); + + csp = (unsigned int *)video.cv32backing; + esp = csp + NATIVE_SCREEN_WIDTH; + lasty = -2; + iny = 0; + pad = pitch - (video.clip.w * bpp); + scalex = INT2FIXED(NATIVE_SCREEN_WIDTH-1) / video.clip.w; + scaley = INT2FIXED(NATIVE_SCREEN_HEIGHT-1) / video.clip.h; + for (y = 0, fixedy = 0; (y < video.clip.h); y++, fixedy += scaley) { + iny = FIXED2INT(fixedy); + if (iny != lasty) { + make_mouseline(mouseline_x, mouseline_v, iny, mouseline); + + /* we'll downblit the colors later */ + if (iny == lasty + 1) { + /* move up one line */ + vgamem_scan32(iny+1, csp, video.tc_bgr32, mouseline); + dp = esp; esp = csp; csp=dp; + } else { + vgamem_scan32(iny, (csp = (unsigned int *)video.cv32backing), + video.tc_bgr32, mouseline); + vgamem_scan32(iny+1, (esp = (csp + NATIVE_SCREEN_WIDTH)), + video.tc_bgr32, mouseline); + } + lasty = iny; + } + for (x = 0, fixedx = 0; x < video.clip.w; x++, fixedx += scalex) { + ex = FRAC(fixedx); + ey = FRAC(fixedy); + + c00 = csp[FIXED2INT(fixedx)]; + c01 = csp[FIXED2INT(fixedx) + 1]; + c10 = esp[FIXED2INT(fixedx)]; + c11 = esp[FIXED2INT(fixedx) + 1]; #if FIXED_BITS <= 8 - /* When there are enough bits between blue and - * red, do the RB channels together - * See http://www.virtualdub.org/blog/pivot/entry.php?id=117 - * for a quick explanation */ + /* When there are enough bits between blue and + * red, do the RB channels together + * See http://www.virtualdub.org/blog/pivot/entry.php?id=117 + * for a quick explanation */ #define REDBLUE(Q) ((Q) & 0x00FF00FF) #define GREEN(Q) ((Q) & 0x0000FF00) - t1 = REDBLUE((((REDBLUE(c01)-REDBLUE(c00))*ex) >> FIXED_BITS)+REDBLUE(c00)); - t2 = REDBLUE((((REDBLUE(c11)-REDBLUE(c10))*ex) >> FIXED_BITS)+REDBLUE(c10)); - outb = ((((t2-t1)*ey) >> FIXED_BITS) + t1); - - t1 = GREEN((((GREEN(c01)-GREEN(c00))*ex) >> FIXED_BITS)+GREEN(c00)); - t2 = GREEN((((GREEN(c11)-GREEN(c10))*ex) >> FIXED_BITS)+GREEN(c10)); - outg = (((((t2-t1)*ey) >> FIXED_BITS) + t1) >> 8) & 0xFF; + t1 = REDBLUE((((REDBLUE(c01)-REDBLUE(c00))*ex) >> FIXED_BITS)+REDBLUE(c00)); + t2 = REDBLUE((((REDBLUE(c11)-REDBLUE(c10))*ex) >> FIXED_BITS)+REDBLUE(c10)); + outb = ((((t2-t1)*ey) >> FIXED_BITS) + t1); + + t1 = GREEN((((GREEN(c01)-GREEN(c00))*ex) >> FIXED_BITS)+GREEN(c00)); + t2 = GREEN((((GREEN(c11)-GREEN(c10))*ex) >> FIXED_BITS)+GREEN(c10)); + outg = (((((t2-t1)*ey) >> FIXED_BITS) + t1) >> 8) & 0xFF; - outr = (outb >> 16) & 0xFF; - outb &= 0xFF; + outr = (outb >> 16) & 0xFF; + outb &= 0xFF; #undef REDBLUE #undef GREEN #else #define BLUE(Q) (Q & 255) #define GREEN(Q) ((Q >> 8) & 255) #define RED(Q) ((Q >> 16) & 255) - t1 = ((((BLUE(c01)-BLUE(c00))*ex) >> FIXED_BITS)+BLUE(c00)) & 0xFF; - t2 = ((((BLUE(c11)-BLUE(c10))*ex) >> FIXED_BITS)+BLUE(c10)) & 0xFF; - outb = ((((t2-t1)*ey) >> FIXED_BITS) + t1); - - t1 = ((((GREEN(c01)-GREEN(c00))*ex) >> FIXED_BITS)+GREEN(c00)) & 0xFF; - t2 = ((((GREEN(c11)-GREEN(c10))*ex) >> FIXED_BITS)+GREEN(c10)) & 0xFF; - outg = ((((t2-t1)*ey) >> FIXED_BITS) + t1); - - t1 = ((((RED(c01)-RED(c00))*ex) >> FIXED_BITS)+RED(c00)) & 0xFF; - t2 = ((((RED(c11)-RED(c10))*ex) >> FIXED_BITS)+RED(c10)) & 0xFF; - outr = ((((t2-t1)*ey) >> FIXED_BITS) + t1); + t1 = ((((BLUE(c01)-BLUE(c00))*ex) >> FIXED_BITS)+BLUE(c00)) & 0xFF; + t2 = ((((BLUE(c11)-BLUE(c10))*ex) >> FIXED_BITS)+BLUE(c10)) & 0xFF; + outb = ((((t2-t1)*ey) >> FIXED_BITS) + t1); + + t1 = ((((GREEN(c01)-GREEN(c00))*ex) >> FIXED_BITS)+GREEN(c00)) & 0xFF; + t2 = ((((GREEN(c11)-GREEN(c10))*ex) >> FIXED_BITS)+GREEN(c10)) & 0xFF; + outg = ((((t2-t1)*ey) >> FIXED_BITS) + t1); + + t1 = ((((RED(c01)-RED(c00))*ex) >> FIXED_BITS)+RED(c00)) & 0xFF; + t2 = ((((RED(c11)-RED(c10))*ex) >> FIXED_BITS)+RED(c10)) & 0xFF; + outr = ((((t2-t1)*ey) >> FIXED_BITS) + t1); #undef RED #undef GREEN #undef BLUE #endif - /* write output "pixel" */ - switch (bpp) { - case 4: - /* inline MapRGB */ - (*(unsigned int *)pixels) = 0xFF000000 | (outr << 16) | (outg << 8) | outb; - break; - case 3: - /* inline MapRGB */ - (*(unsigned int *)pixels) = (outr << 16) | (outg << 8) | outb; - break; - case 2: - /* inline MapRGB if possible */ - if (video.surface->format->palette) { - /* err... */ - (*(unsigned short *)pixels) = SDL_MapRGB( - video.surface->format, outr, outg, outb); - } else if (video.surface->format->Gloss == 2) { - /* RGB565 */ - (*(unsigned short *)pixels) = ((outr << 8) & 0xF800) | - ((outg << 3) & 0x07E0) | - (outb >> 3); - } else { - /* RGB555 */ - (*(unsigned short *)pixels) = 0x8000 | - ((outr << 7) & 0x7C00) | - ((outg << 2) & 0x03E0) | - (outb >> 3); - } - break; - case 1: - /* er... */ - (*pixels) = SDL_MapRGB( - video.surface->format, outr, outg, outb); - break; - }; - pixels += bpp; - } - pixels += pad; - } + /* write output "pixel" */ + switch (bpp) { + case 4: + /* inline MapRGB */ + (*(unsigned int *)pixels) = 0xFF000000 | (outr << 16) | (outg << 8) | outb; + break; + case 3: + /* inline MapRGB */ + (*(unsigned int *)pixels) = (outr << 16) | (outg << 8) | outb; + break; + case 2: + /* inline MapRGB if possible */ + if (video.surface->format->palette) { + /* err... */ + (*(unsigned short *)pixels) = SDL_MapRGB( + video.surface->format, outr, outg, outb); + } else if (video.surface->format->Gloss == 2) { + /* RGB565 */ + (*(unsigned short *)pixels) = ((outr << 8) & 0xF800) | + ((outg << 3) & 0x07E0) | + (outb >> 3); + } else { + /* RGB555 */ + (*(unsigned short *)pixels) = 0x8000 | + ((outr << 7) & 0x7C00) | + ((outg << 2) & 0x03E0) | + (outb >> 3); + } + break; + case 1: + /* er... */ + (*pixels) = SDL_MapRGB( + video.surface->format, outr, outg, outb); + break; + }; + pixels += bpp; + } + pixels += pad; + } } static void _blitYY(unsigned char *pixels, unsigned int pitch, unsigned int *tpal) { - unsigned int mouseline_x = (video.mouse.x / 8); - unsigned int mouseline_v = (video.mouse.x % 8); - unsigned int mouseline[80]; - int y; - - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - - vgamem_scan16(y, (unsigned short *)pixels, tpal, mouseline); - memcpy(pixels+pitch,pixels,pitch); - pixels += pitch; - pixels += pitch; - } + unsigned int mouseline_x = (video.mouse.x / 8); + unsigned int mouseline_v = (video.mouse.x % 8); + unsigned int mouseline[80]; + int y; + + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + + vgamem_scan16(y, (unsigned short *)pixels, tpal, mouseline); + memcpy(pixels+pitch,pixels,pitch); + pixels += pitch; + pixels += pitch; + } } static void _blitUV(unsigned char *pixels, unsigned int pitch, unsigned int *tpal) { - unsigned int mouseline_x = (video.mouse.x / 8); - unsigned int mouseline_v = (video.mouse.x % 8); - unsigned int mouseline[80]; - int y; - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan8(y, (unsigned char *)pixels, tpal, mouseline); - pixels += pitch; - } + unsigned int mouseline_x = (video.mouse.x / 8); + unsigned int mouseline_v = (video.mouse.x % 8); + unsigned int mouseline[80]; + int y; + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan8(y, (unsigned char *)pixels, tpal, mouseline); + pixels += pitch; + } } static void _blitTV(unsigned char *pixels, UNUSED unsigned int pitch, unsigned int *tpal) { - unsigned int mouseline_x = (video.mouse.x / 8); - unsigned int mouseline_v = (video.mouse.x % 8); - unsigned int mouseline[80]; - int y, x; - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y += 2) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan8(y, (unsigned char *)video.cv8backing, tpal, mouseline); - for (x = 0; x < NATIVE_SCREEN_WIDTH; x += 2) { - *pixels++ = video.cv8backing[x+1] - | (video.cv8backing[x] << 4); - } - } + unsigned int mouseline_x = (video.mouse.x / 8); + unsigned int mouseline_v = (video.mouse.x % 8); + unsigned int mouseline[80]; + int y, x; + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y += 2) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan8(y, (unsigned char *)video.cv8backing, tpal, mouseline); + for (x = 0; x < NATIVE_SCREEN_WIDTH; x += 2) { + *pixels++ = video.cv8backing[x+1] + | (video.cv8backing[x] << 4); + } + } } static void _blit11(int bpp, unsigned char *pixels, unsigned int pitch, - unsigned int *tpal) + unsigned int *tpal) { - unsigned int mouseline_x = (video.mouse.x / 8); - unsigned int mouseline_v = (video.mouse.x % 8); - unsigned int mouseline[80]; - unsigned char *pdata; - unsigned int x, y; - int pitch24; - - switch (bpp) { - case 4: - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan32(y, (unsigned int *)pixels, tpal, mouseline); - pixels += pitch; - } - break; - case 3: - /* ... */ - pitch24 = pitch - (NATIVE_SCREEN_WIDTH * 3); - if (pitch24 < 0) { - return; /* eh? */ - } - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan32(y,(unsigned int*)video.cv32backing,tpal, mouseline); - /* okay... */ - pdata = video.cv32backing; - for (x = 0; x < NATIVE_SCREEN_WIDTH; x++) { + unsigned int mouseline_x = (video.mouse.x / 8); + unsigned int mouseline_v = (video.mouse.x % 8); + unsigned int mouseline[80]; + unsigned char *pdata; + unsigned int x, y; + int pitch24; + + switch (bpp) { + case 4: + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan32(y, (unsigned int *)pixels, tpal, mouseline); + pixels += pitch; + } + break; + case 3: + /* ... */ + pitch24 = pitch - (NATIVE_SCREEN_WIDTH * 3); + if (pitch24 < 0) { + return; /* eh? */ + } + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan32(y,(unsigned int*)video.cv32backing,tpal, mouseline); + /* okay... */ + pdata = video.cv32backing; + for (x = 0; x < NATIVE_SCREEN_WIDTH; x++) { #if WORDS_BIGENDIAN - memcpy(pixels, pdata+1, 3); + memcpy(pixels, pdata+1, 3); #else - memcpy(pixels, pdata, 3); + memcpy(pixels, pdata, 3); #endif - pdata += 4; - pixels += 3; - } - pixels += pitch24; - } - break; - case 2: - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan16(y, (unsigned short *)pixels, tpal, mouseline); - pixels += pitch; - } - break; - case 1: - for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { - make_mouseline(mouseline_x, mouseline_v, y, mouseline); - vgamem_scan8(y, (unsigned char *)pixels, tpal, mouseline); - pixels += pitch; - } - break; - }; + pdata += 4; + pixels += 3; + } + pixels += pitch24; + } + break; + case 2: + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan16(y, (unsigned short *)pixels, tpal, mouseline); + pixels += pitch; + } + break; + case 1: + for (y = 0; y < NATIVE_SCREEN_HEIGHT; y++) { + make_mouseline(mouseline_x, mouseline_v, y, mouseline); + vgamem_scan8(y, (unsigned char *)pixels, tpal, mouseline); + pixels += pitch; + } + break; + }; } static void _video_blit_planar(void) { - SDL_LockYUVOverlay(video.overlay); - vgamem_lock(); + SDL_LockYUVOverlay(video.overlay); + vgamem_lock(); - switch (video.yuvlayout) { - case VIDEO_YUV_YV12_TV: - /* halfwidth Y+V+U */ - _blitUV(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); - _blitTV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_v); - _blitTV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_u); - break; - case VIDEO_YUV_IYUV_TV: - /* halfwidth Y+U+V */ - _blitUV(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); - _blitTV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_u); - _blitTV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_v); - break; - - case VIDEO_YUV_YV12: - /* Y+V+U */ - _blitYY(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); - _blitUV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_v); - _blitUV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_u); - break; - case VIDEO_YUV_IYUV: - /* Y+U+V */ - _blitYY(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); - _blitUV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_u); - _blitUV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_v); - break; - }; + switch (video.yuvlayout) { + case VIDEO_YUV_YV12_TV: + /* halfwidth Y+V+U */ + _blitUV(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); + _blitTV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_v); + _blitTV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_u); + break; + case VIDEO_YUV_IYUV_TV: + /* halfwidth Y+U+V */ + _blitUV(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); + _blitTV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_u); + _blitTV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_v); + break; + + case VIDEO_YUV_YV12: + /* Y+V+U */ + _blitYY(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); + _blitUV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_v); + _blitUV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_u); + break; + case VIDEO_YUV_IYUV: + /* Y+U+V */ + _blitYY(video.overlay->pixels[0], video.overlay->pitches[0], video.yuv_y); + _blitUV(video.overlay->pixels[1], video.overlay->pitches[1], video.yuv_u); + _blitUV(video.overlay->pixels[2], video.overlay->pitches[2], video.yuv_v); + break; + }; - vgamem_unlock(); + vgamem_unlock(); - SDL_UnlockYUVOverlay(video.overlay); - SDL_DisplayYUVOverlay(video.overlay, &video.clip); + SDL_UnlockYUVOverlay(video.overlay); + SDL_DisplayYUVOverlay(video.overlay, &video.clip); } void video_blit(void) { - unsigned char *pixels = NULL; - unsigned int bpp = 0; - unsigned int pitch = 0; - - switch (video.desktop.type) { - case VIDEO_SURFACE: - if (SDL_MUSTLOCK(video.surface)) { - while (SDL_LockSurface(video.surface) == -1) { - SDL_Delay(10); - } - } - bpp = video.surface->format->BytesPerPixel; - pixels = (unsigned char *)video.surface->pixels; - pixels += video.clip.y * video.surface->pitch; - pixels += video.clip.x * bpp; - pitch = video.surface->pitch; - break; - case VIDEO_YUV: - if (video.overlay->planes == 3) { - _video_blit_planar(); - return; - } - - SDL_LockYUVOverlay(video.overlay); - pixels = (unsigned char *)*(video.overlay->pixels); - pitch = *(video.overlay->pitches); - switch (video.yuvlayout) { - case VIDEO_YUV_RGBT: bpp = 2; break; - case VIDEO_YUV_RGB565: bpp = 2; break; - case VIDEO_YUV_RGB24: bpp = 3; break; - default: - bpp = 4; - }; - break; - case VIDEO_GL: - pixels = (unsigned char *)video.gl.framebuf; - pitch = video.gl.pitch; - bpp = 4; - break; - case VIDEO_DDRAW: + unsigned char *pixels = NULL; + unsigned int bpp = 0; + unsigned int pitch = 0; + + switch (video.desktop.type) { + case VIDEO_SURFACE: + if (SDL_MUSTLOCK(video.surface)) { + while (SDL_LockSurface(video.surface) == -1) { + SDL_Delay(10); + } + } + bpp = video.surface->format->BytesPerPixel; + pixels = (unsigned char *)video.surface->pixels; + pixels += video.clip.y * video.surface->pitch; + pixels += video.clip.x * bpp; + pitch = video.surface->pitch; + break; + case VIDEO_YUV: + if (video.overlay->planes == 3) { + _video_blit_planar(); + return; + } + + SDL_LockYUVOverlay(video.overlay); + pixels = (unsigned char *)*(video.overlay->pixels); + pitch = *(video.overlay->pitches); + switch (video.yuvlayout) { + case VIDEO_YUV_RGBT: bpp = 2; break; + case VIDEO_YUV_RGB565: bpp = 2; break; + case VIDEO_YUV_RGB24: bpp = 3; break; + default: + bpp = 4; + }; + break; + case VIDEO_GL: + pixels = (unsigned char *)video.gl.framebuf; + pitch = video.gl.pitch; + bpp = 4; + break; + case VIDEO_DDRAW: #ifdef WIN32 - if (SDL_MUSTLOCK(video.ddblit.surface)) { - while (SDL_LockSurface(video.ddblit.surface) == -1) { - SDL_Delay(10); - } - } - pixels = (unsigned char *)video.ddblit.surface->pixels; - pitch = video.ddblit.surface->pitch; - bpp = video.surface->format->BytesPerPixel; - break; + if (SDL_MUSTLOCK(video.ddblit.surface)) { + while (SDL_LockSurface(video.ddblit.surface) == -1) { + SDL_Delay(10); + } + } + pixels = (unsigned char *)video.ddblit.surface->pixels; + pitch = video.ddblit.surface->pitch; + bpp = video.surface->format->BytesPerPixel; + break; #else - return; /* eh? */ + return; /* eh? */ #endif - }; + }; - vgamem_lock(); - if (video.draw.autoscale - || (video.clip.w == NATIVE_SCREEN_WIDTH && video.clip.h == NATIVE_SCREEN_HEIGHT)) { - /* scaling is provided by the hardware, or isn't necessary */ - _blit11(bpp, pixels, pitch, video.pal); - } else { - _blit1n(bpp, pixels, pitch); - } - vgamem_unlock(); - - switch (video.desktop.type) { - case VIDEO_SURFACE: - if (SDL_MUSTLOCK(video.surface)) { - SDL_UnlockSurface(video.surface); - } - SDL_Flip(video.surface); - break; + vgamem_lock(); + if (video.draw.autoscale + || (video.clip.w == NATIVE_SCREEN_WIDTH && video.clip.h == NATIVE_SCREEN_HEIGHT)) { + /* scaling is provided by the hardware, or isn't necessary */ + _blit11(bpp, pixels, pitch, video.pal); + } else { + _blit1n(bpp, pixels, pitch); + } + vgamem_unlock(); + + switch (video.desktop.type) { + case VIDEO_SURFACE: + if (SDL_MUSTLOCK(video.surface)) { + SDL_UnlockSurface(video.surface); + } + SDL_Flip(video.surface); + break; #ifdef WIN32 - case VIDEO_DDRAW: - if (SDL_MUSTLOCK(video.ddblit.surface)) { - SDL_UnlockSurface(video.ddblit.surface); - } - switch (IDirectDrawSurface3_Blt( - video.surface->hwdata->dd_writebuf, - &video.ddblit.rect, - video.ddblit.surface->hwdata->dd_surface,0, - DDBLT_WAIT, NULL)) { - case DD_OK: - break; - case DDERR_SURFACELOST: - IDirectDrawSurface3_Restore(video.ddblit.surface->hwdata->dd_surface); - IDirectDrawSurface3_Restore(video.surface->hwdata->dd_surface); - break; - default: - break; - }; - SDL_Flip(video.surface); - break; -#endif - case VIDEO_YUV: - SDL_UnlockYUVOverlay(video.overlay); - SDL_DisplayYUVOverlay(video.overlay, &video.clip); - break; + case VIDEO_DDRAW: + if (SDL_MUSTLOCK(video.ddblit.surface)) { + SDL_UnlockSurface(video.ddblit.surface); + } + switch (IDirectDrawSurface3_Blt( + video.surface->hwdata->dd_writebuf, + &video.ddblit.rect, + video.ddblit.surface->hwdata->dd_surface,0, + DDBLT_WAIT, NULL)) { + case DD_OK: + break; + case DDERR_SURFACELOST: + IDirectDrawSurface3_Restore(video.ddblit.surface->hwdata->dd_surface); + IDirectDrawSurface3_Restore(video.surface->hwdata->dd_surface); + break; + default: + break; + }; + SDL_Flip(video.surface); + break; +#endif + case VIDEO_YUV: + SDL_UnlockYUVOverlay(video.overlay); + SDL_DisplayYUVOverlay(video.overlay, &video.clip); + break; #if defined(USE_OPENGL) - case VIDEO_GL: - my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); - my_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, - GL_BGRA_EXT, - GL_UNSIGNED_INT_8_8_8_8_REV, - video.gl.framebuf); - my_glCallList(video.gl.displaylist); - SDL_GL_SwapBuffers(); - break; + case VIDEO_GL: + my_glBindTexture(GL_TEXTURE_2D, video.gl.texture); + my_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + NATIVE_SCREEN_WIDTH, NATIVE_SCREEN_HEIGHT, + GL_BGRA_EXT, + GL_UNSIGNED_INT_8_8_8_8_REV, + video.gl.framebuf); + my_glCallList(video.gl.displaylist); + SDL_GL_SwapBuffers(); + break; #endif - }; + }; } int video_mousecursor_visible(void) { - return video.mouse.visible; + return video.mouse.visible; } void video_mousecursor(int vis) { - const char *state[] = { - "Mouse disabled", - "Software mouse cursor enabled", - "Hardware mouse cursor enabled", - }; - - if (status.flags & NO_MOUSE) { - // disable it no matter what - video.mouse.visible = MOUSE_DISABLED; - //SDL_ShowCursor(0); - return; - } - - switch (vis) { - case MOUSE_CYCLE_STATE: - vis = (video.mouse.visible + 1) % MOUSE_CYCLE_STATE; - /* fall through */ - case MOUSE_DISABLED: - case MOUSE_SYSTEM: - case MOUSE_EMULATED: - video.mouse.visible = vis; - status_text_flash("%s", state[video.mouse.visible]); - case MOUSE_RESET_STATE: - break; - default: - video.mouse.visible = MOUSE_EMULATED; - } - - SDL_ShowCursor(video.mouse.visible == MOUSE_SYSTEM); - - // Totally turn off mouse event sending when the mouse is disabled - int evstate = video.mouse.visible == MOUSE_DISABLED ? SDL_DISABLE : SDL_ENABLE; - if (evstate != SDL_EventState(SDL_MOUSEMOTION, SDL_QUERY)) { - SDL_EventState(SDL_MOUSEMOTION, evstate); - SDL_EventState(SDL_MOUSEBUTTONDOWN, evstate); - SDL_EventState(SDL_MOUSEBUTTONUP, evstate); - } + const char *state[] = { + "Mouse disabled", + "Software mouse cursor enabled", + "Hardware mouse cursor enabled", + }; + + if (status.flags & NO_MOUSE) { + // disable it no matter what + video.mouse.visible = MOUSE_DISABLED; + //SDL_ShowCursor(0); + return; + } + + switch (vis) { + case MOUSE_CYCLE_STATE: + vis = (video.mouse.visible + 1) % MOUSE_CYCLE_STATE; + /* fall through */ + case MOUSE_DISABLED: + case MOUSE_SYSTEM: + case MOUSE_EMULATED: + video.mouse.visible = vis; + status_text_flash("%s", state[video.mouse.visible]); + case MOUSE_RESET_STATE: + break; + default: + video.mouse.visible = MOUSE_EMULATED; + } + + SDL_ShowCursor(video.mouse.visible == MOUSE_SYSTEM); + + // Totally turn off mouse event sending when the mouse is disabled + int evstate = video.mouse.visible == MOUSE_DISABLED ? SDL_DISABLE : SDL_ENABLE; + if (evstate != SDL_EventState(SDL_MOUSEMOTION, SDL_QUERY)) { + SDL_EventState(SDL_MOUSEMOTION, evstate); + SDL_EventState(SDL_MOUSEBUTTONDOWN, evstate); + SDL_EventState(SDL_MOUSEBUTTONUP, evstate); + } } void video_translate(unsigned int vx, unsigned int vy, - unsigned int *x, unsigned int *y) + unsigned int *x, unsigned int *y) { - if ((signed) vx < video.clip.x) vx = video.clip.x; - vx -= video.clip.x; + if ((signed) vx < video.clip.x) vx = video.clip.x; + vx -= video.clip.x; - if ((signed) vy < video.clip.y) vy = video.clip.y; - vy -= video.clip.y; + if ((signed) vy < video.clip.y) vy = video.clip.y; + vy -= video.clip.y; - if ((signed) vx > video.clip.w) vx = video.clip.w; - if ((signed) vy > video.clip.h) vy = video.clip.h; - - vx *= NATIVE_SCREEN_WIDTH; - vy *= NATIVE_SCREEN_HEIGHT; - vx /= (video.draw.width - (video.draw.width - video.clip.w)); - vy /= (video.draw.height - (video.draw.height - video.clip.h)); - - if (video.mouse.visible && (video.mouse.x != vx || video.mouse.y != vy)) { - status.flags |= SOFTWARE_MOUSE_MOVED; - } - video.mouse.x = vx; - video.mouse.y = vy; - if (x) *x = vx; - if (y) *y = vy; + if ((signed) vx > video.clip.w) vx = video.clip.w; + if ((signed) vy > video.clip.h) vy = video.clip.h; + + vx *= NATIVE_SCREEN_WIDTH; + vy *= NATIVE_SCREEN_HEIGHT; + vx /= (video.draw.width - (video.draw.width - video.clip.w)); + vy /= (video.draw.height - (video.draw.height - video.clip.h)); + + if (video.mouse.visible && (video.mouse.x != vx || video.mouse.y != vy)) { + status.flags |= SOFTWARE_MOUSE_MOVED; + } + video.mouse.x = vx; + video.mouse.y = vy; + if (x) *x = vx; + if (y) *y = vy; } diff -Nru schism-0+20110101/schism/volume-core.c schism-20160521/schism/volume-core.c --- schism-0+20110101/schism/volume-core.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/volume-core.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -33,56 +33,56 @@ void volume_setup(void) { - char *drv, drv_buf[256]; + char *drv, drv_buf[256]; - drv = SDL_AudioDriverName(drv_buf,sizeof(drv_buf)); + drv = SDL_AudioDriverName(drv_buf,sizeof(drv_buf)); #ifdef USE_ALSA - if ((!drv && !__volume_get_max) - || (drv && (!strcmp(drv, "alsa")))) { - __volume_get_max = alsa_volume_get_max; - __volume_read = alsa_volume_read; - __volume_write = alsa_volume_write; - } + if ((!drv && !__volume_get_max) + || (drv && (!strcmp(drv, "alsa")))) { + __volume_get_max = alsa_volume_get_max; + __volume_read = alsa_volume_read; + __volume_write = alsa_volume_write; + } #endif #ifdef USE_OSS - if ((!drv && !__volume_get_max) - || (drv && (!strcmp(drv, "oss") || !strcmp(drv, "dsp")))) { - __volume_get_max = oss_volume_get_max; - __volume_read = oss_volume_read; - __volume_write = oss_volume_write; - } + if ((!drv && !__volume_get_max) + || (drv && (!strcmp(drv, "oss") || !strcmp(drv, "dsp")))) { + __volume_get_max = oss_volume_get_max; + __volume_read = oss_volume_read; + __volume_write = oss_volume_write; + } #endif #ifdef MACOSX - if ((!drv && !__volume_get_max) - || (drv && (!strcmp(drv, "coreaudio") || !strcmp(drv, "macosx")))) { - __volume_get_max = macosx_volume_get_max; - __volume_read = macosx_volume_read; - __volume_write = macosx_volume_write; - } + if ((!drv && !__volume_get_max) + || (drv && (!strcmp(drv, "coreaudio") || !strcmp(drv, "macosx")))) { + __volume_get_max = macosx_volume_get_max; + __volume_read = macosx_volume_read; + __volume_write = macosx_volume_write; + } #endif #ifdef WIN32 - if ((!drv && !__volume_get_max) - || (drv && (!strcmp(drv, "waveout") || !strcmp(drv, "dsound")))) { - __volume_get_max = win32mm_volume_get_max; - __volume_read = win32mm_volume_read; - __volume_write = win32mm_volume_write; - } + if ((!drv && !__volume_get_max) + || (drv && (!strcmp(drv, "waveout") || !strcmp(drv, "dsound")))) { + __volume_get_max = win32mm_volume_get_max; + __volume_read = win32mm_volume_read; + __volume_write = win32mm_volume_write; + } #endif } int volume_get_max(void) { - if (__volume_get_max) return __volume_get_max(); - return 1; /* Can't return 0, that breaks things. */ + if (__volume_get_max) return __volume_get_max(); + return 1; /* Can't return 0, that breaks things. */ } void volume_read(int *left, int *right) { - if (__volume_read) __volume_read(left,right); - else { *left=0; *right=0; } + if (__volume_read) __volume_read(left,right); + else { *left=0; *right=0; } } void volume_write(int left, int right) { - if (__volume_write) __volume_write(left,right); + if (__volume_write) __volume_write(left,right); } diff -Nru schism-0+20110101/schism/widget.c schism-20160521/schism/widget.c --- schism-0+20110101/schism/widget.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/widget.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -29,225 +29,225 @@ /* create_* functions (the constructors, if you will) */ void create_toggle(struct widget *w, int x, int y, int next_up, int next_down, - int next_left, int next_right, int next_tab, void (*changed) (void)) + int next_left, int next_right, int next_tab, void (*changed) (void)) { - w->type = WIDGET_TOGGLE; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = 3; /* "Off" */ - w->next.up = next_up; - w->next.left = next_left; - w->next.down = next_down; - w->next.right = next_right; - w->next.tab = next_tab; - w->changed = changed; - w->activate = NULL; - w->depressed = 0; - w->height = 1; + w->type = WIDGET_TOGGLE; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = 3; /* "Off" */ + w->next.up = next_up; + w->next.left = next_left; + w->next.down = next_down; + w->next.right = next_right; + w->next.tab = next_tab; + w->changed = changed; + w->activate = NULL; + w->depressed = 0; + w->height = 1; } void create_menutoggle(struct widget *w, int x, int y, int next_up, int next_down, int next_left, - int next_right, int next_tab, void (*changed) (void), const char *const *choices) + int next_right, int next_tab, void (*changed) (void), const char *const *choices) { - int n, width = 0, len; + int n, width = 0, len; - for (n = 0; choices[n]; n++) { - len = strlen(choices[n]); - if (width < len) - width = len; - } - - w->type = WIDGET_MENUTOGGLE; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.left = next_left; - w->next.down = next_down; - w->next.right = next_right; - w->next.tab = next_tab; - w->changed = changed; - w->d.menutoggle.choices = choices; - w->d.menutoggle.num_choices = n; - w->activate = NULL; - w->d.menutoggle.activation_keys = NULL; + for (n = 0; choices[n]; n++) { + len = strlen(choices[n]); + if (width < len) + width = len; + } + + w->type = WIDGET_MENUTOGGLE; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.left = next_left; + w->next.down = next_down; + w->next.right = next_right; + w->next.tab = next_tab; + w->changed = changed; + w->d.menutoggle.choices = choices; + w->d.menutoggle.num_choices = n; + w->activate = NULL; + w->d.menutoggle.activation_keys = NULL; } void create_button(struct widget *w, int x, int y, int width, int next_up, int next_down, int next_left, - int next_right, int next_tab, void (*changed) (void), const char *text, int padding) + int next_right, int next_tab, void (*changed) (void), const char *text, int padding) { - w->type = WIDGET_BUTTON; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.left = next_left; - w->next.down = next_down; - w->next.right = next_right; - w->next.tab = next_tab; - w->changed = changed; - w->d.button.text = text; - w->d.button.padding = padding; - w->activate = NULL; + w->type = WIDGET_BUTTON; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.left = next_left; + w->next.down = next_down; + w->next.right = next_right; + w->next.tab = next_tab; + w->changed = changed; + w->d.button.text = text; + w->d.button.padding = padding; + w->activate = NULL; } void create_togglebutton(struct widget *w, int x, int y, int width, int next_up, int next_down, - int next_left, int next_right, int next_tab, void (*changed) (void), - const char *text, int padding, const int *group) + int next_left, int next_right, int next_tab, void (*changed) (void), + const char *text, int padding, const int *group) { - w->type = WIDGET_TOGGLEBUTTON; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.left = next_left; - w->next.down = next_down; - w->next.right = next_right; - w->next.tab = next_tab; - w->changed = changed; - w->d.togglebutton.text = text; - w->d.togglebutton.padding = padding; - w->d.togglebutton.group = group; - w->activate = NULL; + w->type = WIDGET_TOGGLEBUTTON; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.left = next_left; + w->next.down = next_down; + w->next.right = next_right; + w->next.tab = next_tab; + w->changed = changed; + w->d.togglebutton.text = text; + w->d.togglebutton.padding = padding; + w->d.togglebutton.group = group; + w->activate = NULL; } void create_textentry(struct widget *w, int x, int y, int width, int next_up, int next_down, - int next_tab, void (*changed) (void), char *text, int max_length) + int next_tab, void (*changed) (void), char *text, int max_length) { - w->type = WIDGET_TEXTENTRY; - w->accept_text = 1; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.down = next_down; - w->next.tab = next_tab; - w->changed = changed; - w->d.textentry.text = text; - w->d.textentry.max_length = max_length; - w->d.textentry.firstchar = 0; - w->d.textentry.cursor_pos = 0; - w->activate = NULL; + w->type = WIDGET_TEXTENTRY; + w->accept_text = 1; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.down = next_down; + w->next.tab = next_tab; + w->changed = changed; + w->d.textentry.text = text; + w->d.textentry.max_length = max_length; + w->d.textentry.firstchar = 0; + w->d.textentry.cursor_pos = 0; + w->activate = NULL; } void create_numentry(struct widget *w, int x, int y, int width, int next_up, int next_down, - int next_tab, void (*changed) (void), int min, int max, int *cursor_pos) + int next_tab, void (*changed) (void), int min, int max, int *cursor_pos) { - w->type = WIDGET_NUMENTRY; - w->accept_text = 1; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.down = next_down; - w->next.tab = next_tab; - w->changed = changed; - w->d.numentry.min = min; - w->d.numentry.max = max; - w->d.numentry.cursor_pos = cursor_pos; - w->d.numentry.handle_unknown_key = NULL; - w->d.numentry.reverse = 0; - w->activate = NULL; + w->type = WIDGET_NUMENTRY; + w->accept_text = 1; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.down = next_down; + w->next.tab = next_tab; + w->changed = changed; + w->d.numentry.min = min; + w->d.numentry.max = max; + w->d.numentry.cursor_pos = cursor_pos; + w->d.numentry.handle_unknown_key = NULL; + w->d.numentry.reverse = 0; + w->activate = NULL; } void create_thumbbar(struct widget *w, int x, int y, int width, int next_up, int next_down, - int next_tab, void (*changed) (void), int min, int max) + int next_tab, void (*changed) (void), int min, int max) { - w->type = WIDGET_THUMBBAR; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.down = next_down; - w->next.tab = next_tab; - w->changed = changed; - w->d.thumbbar.min = min; - w->d.thumbbar.max = max; - w->d.thumbbar.text_at_min = NULL; - w->d.thumbbar.text_at_max = NULL; - w->activate = NULL; + w->type = WIDGET_THUMBBAR; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.down = next_down; + w->next.tab = next_tab; + w->changed = changed; + w->d.thumbbar.min = min; + w->d.thumbbar.max = max; + w->d.thumbbar.text_at_min = NULL; + w->d.thumbbar.text_at_max = NULL; + w->activate = NULL; } void create_bitset(struct widget *w, int x, int y, int width, int next_up, int next_down, - int next_tab, void (*changed) (void), - int nbits, const char* bits_on, const char* bits_off, - int *cursor_pos) -{ - w->type = WIDGET_BITSET; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = width; - w->depressed = 0; - w->height = 1; - w->next.up = next_up; - w->next.down = next_down; - w->next.tab = next_tab; - w->changed = changed; - w->d.numentry.reverse = 0; - w->d.bitset.nbits = nbits; - w->d.bitset.bits_on = bits_on; - w->d.bitset.bits_off = bits_off; - w->d.bitset.cursor_pos = cursor_pos; - w->activate = NULL; + int next_tab, void (*changed) (void), + int nbits, const char* bits_on, const char* bits_off, + int *cursor_pos) +{ + w->type = WIDGET_BITSET; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = width; + w->depressed = 0; + w->height = 1; + w->next.up = next_up; + w->next.down = next_down; + w->next.tab = next_tab; + w->changed = changed; + w->d.numentry.reverse = 0; + w->d.bitset.nbits = nbits; + w->d.bitset.bits_on = bits_on; + w->d.bitset.bits_off = bits_off; + w->d.bitset.cursor_pos = cursor_pos; + w->activate = NULL; } void create_panbar(struct widget *w, int x, int y, int next_up, int next_down, int next_tab, - void (*changed) (void), int channel) + void (*changed) (void), int channel) { - w->type = WIDGET_PANBAR; - w->accept_text = 0; - w->x = x; - w->y = y; - w->width = 24; - w->height = 1; - w->next.up = next_up; - w->next.down = next_down; - w->next.tab = next_tab; - w->changed = changed; - w->d.numentry.reverse = 0; - w->d.panbar.min = 0; - w->d.panbar.max = 64; - w->d.panbar.channel = channel; - w->activate = NULL; + w->type = WIDGET_PANBAR; + w->accept_text = 0; + w->x = x; + w->y = y; + w->width = 24; + w->height = 1; + w->next.up = next_up; + w->next.down = next_down; + w->next.tab = next_tab; + w->changed = changed; + w->d.numentry.reverse = 0; + w->d.panbar.min = 0; + w->d.panbar.max = 64; + w->d.panbar.channel = channel; + w->activate = NULL; } void create_other(struct widget *w, int next_tab, int (*i_handle_key) (struct key_event *k), - void (*i_redraw) (void)) + void (*i_redraw) (void)) { - w->type = WIDGET_OTHER; - w->accept_text = 0; - w->next.up = w->next.down = w->next.left = w->next.right = 0; - w->next.tab = next_tab; - /* w->changed = NULL; ??? */ - w->depressed = 0; - w->activate = NULL; - - /* unfocusable unless set */ - w->x = -1; - w->y = -1; - w->width = -1; - w->height = 1; + w->type = WIDGET_OTHER; + w->accept_text = 0; + w->next.up = w->next.down = w->next.left = w->next.right = 0; + w->next.tab = next_tab; + /* w->changed = NULL; ??? */ + w->depressed = 0; + w->activate = NULL; + + /* unfocusable unless set */ + w->x = -1; + w->y = -1; + w->width = -1; + w->height = 1; - w->d.other.handle_key = i_handle_key; - w->d.other.redraw = i_redraw; + w->d.other.handle_key = i_handle_key; + w->d.other.redraw = i_redraw; } /* --------------------------------------------------------------------- */ @@ -255,31 +255,31 @@ void text_add_char(char *text, char c, int *cursor_pos, int max_length) { - int len; + int len; - text[max_length] = 0; - len = strlen(text); - if (*cursor_pos >= max_length) - *cursor_pos = max_length - 1; - /* FIXME: this causes some weirdness with the end key. maybe hitting end should trim spaces? */ - while (len < *cursor_pos) - text[len++] = ' '; - memmove(text + *cursor_pos + 1, text + *cursor_pos, max_length - *cursor_pos - 1); - text[*cursor_pos] = c; - (*cursor_pos)++; + text[max_length] = 0; + len = strlen(text); + if (*cursor_pos >= max_length) + *cursor_pos = max_length - 1; + /* FIXME: this causes some weirdness with the end key. maybe hitting end should trim spaces? */ + while (len < *cursor_pos) + text[len++] = ' '; + memmove(text + *cursor_pos + 1, text + *cursor_pos, max_length - *cursor_pos - 1); + text[*cursor_pos] = c; + (*cursor_pos)++; } void text_delete_char(char *text, int *cursor_pos, int max_length) { - if (*cursor_pos == 0) - return; - (*cursor_pos)--; - memmove(text + *cursor_pos, text + *cursor_pos + 1, max_length - *cursor_pos); + if (*cursor_pos == 0) + return; + (*cursor_pos)--; + memmove(text + *cursor_pos, text + *cursor_pos + 1, max_length - *cursor_pos); } void text_delete_next_char(char *text, int *cursor_pos, int max_length) { - memmove(text + *cursor_pos, text + *cursor_pos + 1, max_length - *cursor_pos); + memmove(text + *cursor_pos, text + *cursor_pos + 1, max_length - *cursor_pos); } /* --------------------------------------------------------------------- */ @@ -287,71 +287,71 @@ static void textentry_reposition(struct widget *w) { - int len; + int len; - w->d.textentry.text[w->d.textentry.max_length] = 0; + w->d.textentry.text[w->d.textentry.max_length] = 0; - len = strlen(w->d.textentry.text); - if (w->d.textentry.cursor_pos < w->d.textentry.firstchar) { - w->d.textentry.firstchar = w->d.textentry.cursor_pos; - } else if (w->d.textentry.cursor_pos > len) { - w->d.textentry.cursor_pos = len; - } else if (w->d.textentry.cursor_pos > (w->d.textentry.firstchar + w->width - 1)) { - w->d.textentry.firstchar = w->d.textentry.cursor_pos - w->width + 1; - if (w->d.textentry.firstchar < 0) - w->d.textentry.firstchar = 0; - } + len = strlen(w->d.textentry.text); + if (w->d.textentry.cursor_pos < w->d.textentry.firstchar) { + w->d.textentry.firstchar = w->d.textentry.cursor_pos; + } else if (w->d.textentry.cursor_pos > len) { + w->d.textentry.cursor_pos = len; + } else if (w->d.textentry.cursor_pos > (w->d.textentry.firstchar + w->width - 1)) { + w->d.textentry.firstchar = w->d.textentry.cursor_pos - w->width + 1; + if (w->d.textentry.firstchar < 0) + w->d.textentry.firstchar = 0; + } } int textentry_add_char(struct widget *w, uint16_t unicode) { - int c = unicode_to_ascii(unicode); + int c = unicode_to_ascii(unicode); - if (c == 0) - return 0; - text_add_char(w->d.textentry.text, c, &(w->d.textentry.cursor_pos), w->d.textentry.max_length); + if (c == 0) + return 0; + text_add_char(w->d.textentry.text, c, &(w->d.textentry.cursor_pos), w->d.textentry.max_length); - if (w->changed) w->changed(); - status.flags |= NEED_UPDATE; + if (w->changed) w->changed(); + status.flags |= NEED_UPDATE; - return 1; + return 1; } int menutoggle_handle_key(struct widget *w, struct key_event *k) { - if( ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0) - && w->d.menutoggle.activation_keys) - { - const char* m = w->d.menutoggle.activation_keys; - const char* p = strchr(m, (char)k->unicode); - if(p && *p) - { - w->d.menutoggle.state = p - m; - if(w->changed) w->changed(); - status.flags |= NEED_UPDATE; - return 1; - } - } - return 0; + if( ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0) + && w->d.menutoggle.activation_keys) + { + const char* m = w->d.menutoggle.activation_keys; + const char* p = strchr(m, (char)k->unicode); + if(p && *p) + { + w->d.menutoggle.state = p - m; + if(w->changed) w->changed(); + status.flags |= NEED_UPDATE; + return 1; + } + } + return 0; } int bitset_handle_key(struct widget *w, struct key_event *k) { - if( ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0) - && w->d.bitset.activation_keys) - { - const char* m = w->d.bitset.activation_keys; - const char* p = strchr(m, (char)k->unicode); - if(p && *p) - { - int bit_index = p-m; - w->d.bitset.value ^= (1 << bit_index); - if(w->changed) w->changed(); - status.flags |= NEED_UPDATE; - return 1; - } - } - return 0; + if( ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0) + && w->d.bitset.activation_keys) + { + const char* m = w->d.bitset.activation_keys; + const char* p = strchr(m, (char)k->unicode); + if(p && *p) + { + int bit_index = p-m; + w->d.bitset.value ^= (1 << bit_index); + if(w->changed) w->changed(); + status.flags |= NEED_UPDATE; + return 1; + } + } + return 0; } /* --------------------------------------------------------------------- */ @@ -359,52 +359,52 @@ void numentry_change_value(struct widget *w, int new_value) { - new_value = CLAMP(new_value, w->d.numentry.min, w->d.numentry.max); - w->d.numentry.value = new_value; - if (w->changed) w->changed(); - status.flags |= NEED_UPDATE; + new_value = CLAMP(new_value, w->d.numentry.min, w->d.numentry.max); + w->d.numentry.value = new_value; + if (w->changed) w->changed(); + status.flags |= NEED_UPDATE; } /* I'm sure there must be a simpler way to do this. */ int numentry_handle_digit(struct widget *w, struct key_event *k) { - int width, value, n; - static const int tens[7] = { 1, 10, 100, 1000, 10000, 100000, 1000000 }; - int digits[7] = { 0 }; - int c; - - c = numeric_key_event(k, 0); - if (c == -1) { - if (w->d.numentry.handle_unknown_key) { - return w->d.numentry.handle_unknown_key(k); - } - return 0; - } - if (w->d.numentry.reverse) { - w->d.numentry.value *= 10; - w->d.numentry.value += c; - if (w->changed) w->changed(); - status.flags |= NEED_UPDATE; - return 1; - } - - width = w->width; - value = w->d.numentry.value; - for (n = width - 1; n >= 0; n--) - digits[n] = value / tens[n] % 10; - digits[width - *(w->d.numentry.cursor_pos) - 1] = c; - value = 0; - for (n = width - 1; n >= 0; n--) - value += digits[n] * tens[n]; - value = CLAMP(value, w->d.numentry.min, w->d.numentry.max); - w->d.numentry.value = value; - if (*(w->d.numentry.cursor_pos) < w->width - 1) - (*(w->d.numentry.cursor_pos))++; + int width, value, n; + static const int tens[7] = { 1, 10, 100, 1000, 10000, 100000, 1000000 }; + int digits[7] = { 0 }; + int c; + + c = numeric_key_event(k, 0); + if (c == -1) { + if (w->d.numentry.handle_unknown_key) { + return w->d.numentry.handle_unknown_key(k); + } + return 0; + } + if (w->d.numentry.reverse) { + w->d.numentry.value *= 10; + w->d.numentry.value += c; + if (w->changed) w->changed(); + status.flags |= NEED_UPDATE; + return 1; + } + + width = w->width; + value = w->d.numentry.value; + for (n = width - 1; n >= 0; n--) + digits[n] = value / tens[n] % 10; + digits[width - *(w->d.numentry.cursor_pos) - 1] = c; + value = 0; + for (n = width - 1; n >= 0; n--) + value += digits[n] * tens[n]; + value = CLAMP(value, w->d.numentry.min, w->d.numentry.max); + w->d.numentry.value = value; + if (*(w->d.numentry.cursor_pos) < w->width - 1) + (*(w->d.numentry.cursor_pos))++; - if (w->changed) w->changed(); - status.flags |= NEED_UPDATE; + if (w->changed) w->changed(); + status.flags |= NEED_UPDATE; - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -412,21 +412,21 @@ void togglebutton_set(struct widget *p_widgets, int widget, int do_callback) { - const int *group = p_widgets[widget].d.togglebutton.group; - int i; + const int *group = p_widgets[widget].d.togglebutton.group; + int i; - if (!group) return; /* assert */ + if (!group) return; /* assert */ - for (i = 0; group[i] >= 0; i++) - p_widgets[group[i]].d.togglebutton.state = 0; - p_widgets[widget].d.togglebutton.state = 1; + for (i = 0; group[i] >= 0; i++) + p_widgets[group[i]].d.togglebutton.state = 0; + p_widgets[widget].d.togglebutton.state = 1; - if (do_callback) { - if (p_widgets[widget].changed) - p_widgets[widget].changed(); - } + if (do_callback) { + if (p_widgets[widget].changed) + p_widgets[widget].changed(); + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -434,161 +434,160 @@ void draw_widget(struct widget *w, int selected) { - char buf[16] = "Channel 42"; - const char *ptr, *endptr; /* for the menutoggle */ - char *str; - int n, j; - int tfg = selected ? 0 : 2; - int tbg = selected ? 3 : 0; - int drew_cursor = 0; - int fg,bg; - - switch (w->type) { - case WIDGET_TOGGLE: - draw_fill_chars(w->x, w->y, w->x + w->width - 1, w->y, 0); - draw_text((w->d.toggle.state ? "On" : "Off"), w->x, w->y, tfg, tbg); - break; - case WIDGET_MENUTOGGLE: - draw_fill_chars(w->x, w->y, w->x + w->width - 1, w->y, 0); - ptr = w->d.menutoggle.choices[w->d.menutoggle.state]; - endptr = strchr(ptr, ' '); - if (endptr) { - n = endptr - ptr; - draw_text_len(ptr, n, w->x, w->y, tfg, tbg); - draw_text(endptr + 1, w->x + n + 1, w->y, 2, 0); - } else { - draw_text(ptr, w->x, w->y, tfg, tbg); - } - break; - case WIDGET_BUTTON: - draw_box(w->x - 1, w->y - 1, w->x + w->width + 2, w->y + 1, - BOX_THIN | BOX_INNER | ( - w->depressed ? BOX_INSET : BOX_OUTSET)); - draw_text(w->d.button.text, w->x + w->d.button.padding, w->y, selected ? 3 : 0, 2); - break; - case WIDGET_TOGGLEBUTTON: - draw_box(w->x - 1, w->y - 1, w->x + w->width + 2, w->y + 1, - BOX_THIN | BOX_INNER |( - (w->d.togglebutton.state || w->depressed) ? BOX_INSET : BOX_OUTSET)); - draw_text(w->d.togglebutton.text, w->x + w->d.togglebutton.padding, w->y, selected ? 3 : 0, 2); - break; - case WIDGET_TEXTENTRY: - textentry_reposition(w); - draw_text_len(w->d.textentry.text + w->d.textentry.firstchar, w->width, w->x, w->y, 2, 0); - if (selected && !drew_cursor) { - n = w->d.textentry.cursor_pos - w->d.textentry.firstchar; - draw_char(((n < (signed) strlen(w->d.textentry.text)) - ? (w->d.textentry.text[w->d.textentry.cursor_pos]) : ' '), - w->x + n, w->y, 0, 3); - } - break; - case WIDGET_NUMENTRY: - if (w->d.numentry.reverse) { - str = numtostr(w->width, w->d.numentry.value, buf); - while (*str == '0') str++; - draw_text_len("", w->width, w->x, w->y, 2, 0); - if (*str) { - draw_text(str, (w->x+w->width) - strlen(str), - w->y, 2, 0); - } - j = strlen(str); - if (selected && !drew_cursor) { - while (str[0] && str[1]) str++; - if (!str[0]) str[0] = ' '; - draw_char(str[0], w->x + (w->width-1), - w->y, 0, 3); - } - } else { - if (w->d.numentry.min < 0 || w->d.numentry.max < 0) { - numtostr_signed(w->width, w->d.numentry.value, - buf); - } else { - numtostr(w->width, w->d.numentry.value, - buf); - } - draw_text_len(buf, - w->width, w->x, w->y, 2, 0); - if (selected && !drew_cursor) { - n = *(w->d.numentry.cursor_pos); - draw_char(buf[n], w->x + n, w->y, 0, 3); - } - } - break; - case WIDGET_BITSET: - for(n = 0; n < w->d.bitset.nbits; ++n) - { - int set = !!(w->d.bitset.value & (1 << n)); - char label_c1 = set ? w->d.bitset.bits_on[n*2+0] - : w->d.bitset.bits_off[n*2+0]; - char label_c2 = set ? w->d.bitset.bits_on[n*2+1] - : w->d.bitset.bits_off[n*2+1]; - int is_focused = selected && n == *w->d.bitset.cursor_pos; - /* In textentries, cursor=0,3; normal=2,0 */ - static const char fg_selection[4] = - { - 2, /* not cursor, not set */ - 3, /* not cursor, is set */ - 0, /* has cursor, not set */ - 0 /* has cursor, is set */ - }; - static const char bg_selection[4] = - { - 0, /* not cursor, not set */ - 0, /* not cursor, is set */ - 2, /* has cursor, not set */ - 3 /* has cursor, is set */ - }; - fg = fg_selection[set + is_focused*2]; - bg = bg_selection[set + is_focused*2]; - if(label_c2) - draw_half_width_chars(label_c1, label_c2, w->x + n, w->y, fg, bg, fg, bg); - else - draw_char(label_c1, w->x + n, w->y, fg, bg); - } - break; - case WIDGET_THUMBBAR: - if (w->d.thumbbar.text_at_min && w->d.thumbbar.min == w->d.thumbbar.value) { - draw_text_len(w->d.thumbbar.text_at_min, w->width, w->x, w->y, selected ? 3 : 2, 0); - } else if (w->d.thumbbar.text_at_max && w->d.thumbbar.max == w->d.thumbbar.value) { - /* this will probably do Bad Things if the text is too long */ - int len = strlen(w->d.thumbbar.text_at_max); - int pos = w->x + w->width - len; - - draw_fill_chars(w->x, w->y, pos - 1, w->y, 0); - draw_text_len(w->d.thumbbar.text_at_max, len, pos, w->y, selected ? 3 : 2, 0); - } else { - draw_thumb_bar(w->x, w->y, w->width, w->d.thumbbar.min, - w->d.thumbbar.max, w->d.thumbbar.value, selected); - } - if (w->d.thumbbar.min < 0 || w->d.thumbbar.max < 0) { - numtostr_signed(3, w->d.thumbbar.value, buf); - } else { - numtostr(3, w->d.thumbbar.value, buf); - } - draw_text(buf, - w->x + w->width + 1, w->y, 1, 2); - break; - case WIDGET_PANBAR: - numtostr(2, w->d.panbar.channel, buf + 8); - draw_text(buf, w->x, w->y, selected ? 3 : 0, 2); - if (w->d.panbar.muted) { - draw_text(" Muted ", w->x + 11, w->y, selected ? 3 : 5, 0); - /* draw_fill_chars(w->x + 21, w->y, w->x + 23, w->y, 2); */ - } else if (w->d.panbar.surround) { - draw_text("Surround ", w->x + 11, w->y, selected ? 3 : 5, 0); - /* draw_fill_chars(w->x + 21, w->y, w->x + 23, w->y, 2); */ - } else { - draw_thumb_bar(w->x + 11, w->y, 9, 0, 64, w->d.panbar.value, selected); - draw_text(numtostr(3, w->d.thumbbar.value, buf), w->x + 21, w->y, 1, 2); - } - break; - case WIDGET_OTHER: - if (w->d.other.redraw) w->d.other.redraw(); - break; - default: - /* shouldn't ever happen... */ - break; - } + char buf[16] = "Channel 42"; + const char *ptr, *endptr; /* for the menutoggle */ + char *str; + int n; + int tfg = selected ? 0 : 2; + int tbg = selected ? 3 : 0; + int drew_cursor = 0; + int fg,bg; + + switch (w->type) { + case WIDGET_TOGGLE: + draw_fill_chars(w->x, w->y, w->x + w->width - 1, w->y, 0); + draw_text((w->d.toggle.state ? "On" : "Off"), w->x, w->y, tfg, tbg); + break; + case WIDGET_MENUTOGGLE: + draw_fill_chars(w->x, w->y, w->x + w->width - 1, w->y, 0); + ptr = w->d.menutoggle.choices[w->d.menutoggle.state]; + endptr = strchr(ptr, ' '); + if (endptr) { + n = endptr - ptr; + draw_text_len(ptr, n, w->x, w->y, tfg, tbg); + draw_text(endptr + 1, w->x + n + 1, w->y, 2, 0); + } else { + draw_text(ptr, w->x, w->y, tfg, tbg); + } + break; + case WIDGET_BUTTON: + draw_box(w->x - 1, w->y - 1, w->x + w->width + 2, w->y + 1, + BOX_THIN | BOX_INNER | ( + w->depressed ? BOX_INSET : BOX_OUTSET)); + draw_text(w->d.button.text, w->x + w->d.button.padding, w->y, selected ? 3 : 0, 2); + break; + case WIDGET_TOGGLEBUTTON: + draw_box(w->x - 1, w->y - 1, w->x + w->width + 2, w->y + 1, + BOX_THIN | BOX_INNER |( + (w->d.togglebutton.state || w->depressed) ? BOX_INSET : BOX_OUTSET)); + draw_text(w->d.togglebutton.text, w->x + w->d.togglebutton.padding, w->y, selected ? 3 : 0, 2); + break; + case WIDGET_TEXTENTRY: + textentry_reposition(w); + draw_text_len(w->d.textentry.text + w->d.textentry.firstchar, w->width, w->x, w->y, 2, 0); + if (selected && !drew_cursor) { + n = w->d.textentry.cursor_pos - w->d.textentry.firstchar; + draw_char(((n < (signed) strlen(w->d.textentry.text)) + ? (w->d.textentry.text[w->d.textentry.cursor_pos]) : ' '), + w->x + n, w->y, 0, 3); + } + break; + case WIDGET_NUMENTRY: + if (w->d.numentry.reverse) { + str = numtostr(w->width, w->d.numentry.value, buf); + while (*str == '0') str++; + draw_text_len("", w->width, w->x, w->y, 2, 0); + if (*str) { + draw_text(str, (w->x+w->width) - strlen(str), + w->y, 2, 0); + } + if (selected && !drew_cursor) { + while (str[0] && str[1]) str++; + if (!str[0]) str[0] = ' '; + draw_char(str[0], w->x + (w->width-1), + w->y, 0, 3); + } + } else { + if (w->d.numentry.min < 0 || w->d.numentry.max < 0) { + numtostr_signed(w->width, w->d.numentry.value, + buf); + } else { + numtostr(w->width, w->d.numentry.value, + buf); + } + draw_text_len(buf, + w->width, w->x, w->y, 2, 0); + if (selected && !drew_cursor) { + n = *(w->d.numentry.cursor_pos); + draw_char(buf[n], w->x + n, w->y, 0, 3); + } + } + break; + case WIDGET_BITSET: + for(n = 0; n < w->d.bitset.nbits; ++n) + { + int set = !!(w->d.bitset.value & (1 << n)); + char label_c1 = set ? w->d.bitset.bits_on[n*2+0] + : w->d.bitset.bits_off[n*2+0]; + char label_c2 = set ? w->d.bitset.bits_on[n*2+1] + : w->d.bitset.bits_off[n*2+1]; + int is_focused = selected && n == *w->d.bitset.cursor_pos; + /* In textentries, cursor=0,3; normal=2,0 */ + static const char fg_selection[4] = + { + 2, /* not cursor, not set */ + 3, /* not cursor, is set */ + 0, /* has cursor, not set */ + 0 /* has cursor, is set */ + }; + static const char bg_selection[4] = + { + 0, /* not cursor, not set */ + 0, /* not cursor, is set */ + 2, /* has cursor, not set */ + 3 /* has cursor, is set */ + }; + fg = fg_selection[set + is_focused*2]; + bg = bg_selection[set + is_focused*2]; + if(label_c2) + draw_half_width_chars(label_c1, label_c2, w->x + n, w->y, fg, bg, fg, bg); + else + draw_char(label_c1, w->x + n, w->y, fg, bg); + } + break; + case WIDGET_THUMBBAR: + if (w->d.thumbbar.text_at_min && w->d.thumbbar.min == w->d.thumbbar.value) { + draw_text_len(w->d.thumbbar.text_at_min, w->width, w->x, w->y, selected ? 3 : 2, 0); + } else if (w->d.thumbbar.text_at_max && w->d.thumbbar.max == w->d.thumbbar.value) { + /* this will probably do Bad Things if the text is too long */ + int len = strlen(w->d.thumbbar.text_at_max); + int pos = w->x + w->width - len; + + draw_fill_chars(w->x, w->y, pos - 1, w->y, 0); + draw_text_len(w->d.thumbbar.text_at_max, len, pos, w->y, selected ? 3 : 2, 0); + } else { + draw_thumb_bar(w->x, w->y, w->width, w->d.thumbbar.min, + w->d.thumbbar.max, w->d.thumbbar.value, selected); + } + if (w->d.thumbbar.min < 0 || w->d.thumbbar.max < 0) { + numtostr_signed(3, w->d.thumbbar.value, buf); + } else { + numtostr(3, w->d.thumbbar.value, buf); + } + draw_text(buf, + w->x + w->width + 1, w->y, 1, 2); + break; + case WIDGET_PANBAR: + numtostr(2, w->d.panbar.channel, buf + 8); + draw_text(buf, w->x, w->y, selected ? 3 : 0, 2); + if (w->d.panbar.muted) { + draw_text(" Muted ", w->x + 11, w->y, selected ? 3 : 5, 0); + /* draw_fill_chars(w->x + 21, w->y, w->x + 23, w->y, 2); */ + } else if (w->d.panbar.surround) { + draw_text("Surround ", w->x + 11, w->y, selected ? 3 : 5, 0); + /* draw_fill_chars(w->x + 21, w->y, w->x + 23, w->y, 2); */ + } else { + draw_thumb_bar(w->x + 11, w->y, 9, 0, 64, w->d.panbar.value, selected); + draw_text(numtostr(3, w->d.thumbbar.value, buf), w->x + 21, w->y, 1, 2); + } + break; + case WIDGET_OTHER: + if (w->d.other.redraw) w->d.other.redraw(); + break; + default: + /* shouldn't ever happen... */ + break; + } } /* --------------------------------------------------------------------- */ @@ -596,58 +595,53 @@ void change_focus_to(int new_widget_index) { - if (*selected_widget != new_widget_index) { - if (ACTIVE_WIDGET.depressed) ACTIVE_WIDGET.depressed = 0; + if (*selected_widget != new_widget_index) { + if (ACTIVE_WIDGET.depressed) ACTIVE_WIDGET.depressed = 0; - *selected_widget = new_widget_index; + *selected_widget = new_widget_index; - ACTIVE_WIDGET.depressed = 0; + ACTIVE_WIDGET.depressed = 0; - if (ACTIVE_WIDGET.type == WIDGET_TEXTENTRY) - ACTIVE_WIDGET.d.textentry.cursor_pos - = strlen(ACTIVE_WIDGET.d.textentry.text); - - status.flags |= NEED_UPDATE; - } -} -struct widget *find_widget_xy_ex(int x, int y, int *num) -{ - struct widget *w; - int i, pad; - - if (!total_widgets) - return NULL; - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - switch (w->type) { - case WIDGET_BUTTON: - pad = w->d.button.padding+1; - break; - case WIDGET_TOGGLEBUTTON: - pad = w->d.togglebutton.padding+1; - break; - default: - pad = 0; - }; - if (x >= w->x && x < w->x+w->width+pad) { - if (y >= w->y && y < w->y+w->height) { - if (num) *num=i; - return w; - } - } - } - return NULL; -} -struct widget *find_widget_xy(int x, int y) -{ - return find_widget_xy_ex(x, y, NULL); + if (ACTIVE_WIDGET.type == WIDGET_TEXTENTRY) + ACTIVE_WIDGET.d.textentry.cursor_pos + = strlen(ACTIVE_WIDGET.d.textentry.text); + + status.flags |= NEED_UPDATE; + } +} + +static int _find_widget_xy(int x, int y) +{ + struct widget *w; + int i, pad; + + if (!total_widgets) + return -1; + for (i = 0; i < *total_widgets; i++) { + w = widgets + i; + switch (w->type) { + case WIDGET_BUTTON: + pad = w->d.button.padding + 1; + break; + case WIDGET_TOGGLEBUTTON: + pad = w->d.togglebutton.padding + 1; + break; + default: + pad = 0; + } + if (x >= w->x && x < w->x + w->width + pad && y >= w->y && y < w->y + w->height) { + return i; + } + } + return -1; } + int change_focus_to_xy(int x, int y) { - int n; - if (find_widget_xy_ex(x, y, &n) != NULL) { - change_focus_to(n); - return 1; - } - return 0; + int n = _find_widget_xy(x, y); + if (n >= 0) { + change_focus_to(n); + return 1; + } + return 0; } diff -Nru schism-0+20110101/schism/widget-keyhandler.c schism-20160521/schism/widget-keyhandler.c --- schism-0+20110101/schism/widget-keyhandler.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/widget-keyhandler.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -31,33 +31,33 @@ /* n => the delta-value */ static void numentry_move_cursor(struct widget *widget, int n) { - if (widget->d.numentry.reverse) return; - n += *(widget->d.numentry.cursor_pos); - n = CLAMP(n, 0, widget->width - 1); - if (*(widget->d.numentry.cursor_pos) == n) - return; - *(widget->d.numentry.cursor_pos) = n; - status.flags |= NEED_UPDATE; + if (widget->d.numentry.reverse) return; + n += *(widget->d.numentry.cursor_pos); + n = CLAMP(n, 0, widget->width - 1); + if (*(widget->d.numentry.cursor_pos) == n) + return; + *(widget->d.numentry.cursor_pos) = n; + status.flags |= NEED_UPDATE; } static void textentry_move_cursor(struct widget *widget, int n) { - n += widget->d.textentry.cursor_pos; - n = CLAMP(n, 0, widget->d.textentry.max_length); - if (widget->d.textentry.cursor_pos == n) - return; - widget->d.textentry.cursor_pos = n; - status.flags |= NEED_UPDATE; + n += widget->d.textentry.cursor_pos; + n = CLAMP(n, 0, widget->d.textentry.max_length); + if (widget->d.textentry.cursor_pos == n) + return; + widget->d.textentry.cursor_pos = n; + status.flags |= NEED_UPDATE; } static void bitset_move_cursor(struct widget *widget, int n) { - n += *widget->d.bitset.cursor_pos; - n = CLAMP(n, 0, widget->d.bitset.nbits-1); - if (*widget->d.bitset.cursor_pos == n) - return; - *widget->d.bitset.cursor_pos = n; - status.flags |= NEED_UPDATE; + n += *widget->d.bitset.cursor_pos; + n = CLAMP(n, 0, widget->d.bitset.nbits-1); + if (*widget->d.bitset.cursor_pos == n) + return; + *widget->d.bitset.cursor_pos = n; + status.flags |= NEED_UPDATE; } /* --------------------------------------------------------------------- */ @@ -65,36 +65,36 @@ static void thumbbar_prompt_finish(int n) { - if (n >= ACTIVE_WIDGET.d.thumbbar.min && n <= ACTIVE_WIDGET.d.thumbbar.max) { - ACTIVE_WIDGET.d.thumbbar.value = n; - if (ACTIVE_WIDGET.changed) ACTIVE_WIDGET.changed(); - } + if (n >= ACTIVE_WIDGET.d.thumbbar.min && n <= ACTIVE_WIDGET.d.thumbbar.max) { + ACTIVE_WIDGET.d.thumbbar.value = n; + if (ACTIVE_WIDGET.changed) ACTIVE_WIDGET.changed(); + } - status.flags |= NEED_UPDATE; + status.flags |= NEED_UPDATE; } static int thumbbar_prompt_value(struct widget *widget, struct key_event *k) { - int c; + int c; - if (!NO_MODIFIER(k->mod)) { - /* annoying */ - return 0; - } - if (k->sym == SDLK_MINUS) { - if (widget->d.thumbbar.min >= 0) - return 0; - c = '-'; - } else { - c = numeric_key_event(k, 0); - if (c < 0) - return 0; - c += '0'; - } + if (!NO_MODIFIER(k->mod)) { + /* annoying */ + return 0; + } + if (k->sym == SDLK_MINUS) { + if (widget->d.thumbbar.min >= 0) + return 0; + c = '-'; + } else { + c = numeric_key_event(k, 0); + if (c < 0) + return 0; + c += '0'; + } - numprompt_create("Enter Value", thumbbar_prompt_finish, c); + numprompt_create("Enter Value", thumbbar_prompt_finish, c); - return 1; + return 1; } /* --------------------------------------------------------------------- */ @@ -103,679 +103,690 @@ static void _backtab(void) { - struct widget *w; - int i; + struct widget *w; + int i; - /* hunt for a widget that leads back to this one */ - if (!total_widgets || !selected_widget) return; + /* hunt for a widget that leads back to this one */ + if (!total_widgets || !selected_widget) return; - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - if (w->next.tab == *selected_widget) { - /* found backtab */ - change_focus_to(i); - return; - } - - } - if (status.flags & CLASSIC_MODE) { - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - if (w->next.right == *selected_widget) { - /* simulate backtab */ - change_focus_to(i); - return; - } - } - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - if (w->next.down == *selected_widget) { - /* simulate backtab */ - change_focus_to(i); - return; - } - } - } else { - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - if (w->next.down == *selected_widget) { - /* simulate backtab */ - change_focus_to(i); - return; - } - } - for (i = 0; i < *total_widgets; i++) { - w = &widgets[i]; - if (w->next.right == *selected_widget) { - /* simulate backtab */ - change_focus_to(i); - return; - } - } - } - change_focus_to(0); /* err... */ + for (i = 0; i < *total_widgets; i++) { + w = &widgets[i]; + if (w->next.tab == *selected_widget) { + /* found backtab */ + change_focus_to(i); + return; + } + + } + if (status.flags & CLASSIC_MODE) { + for (i = 0; i < *total_widgets; i++) { + w = &widgets[i]; + if (w->next.right == *selected_widget) { + /* simulate backtab */ + change_focus_to(i); + return; + } + } + for (i = 0; i < *total_widgets; i++) { + w = &widgets[i]; + if (w->next.down == *selected_widget) { + /* simulate backtab */ + change_focus_to(i); + return; + } + } + } else { + for (i = 0; i < *total_widgets; i++) { + w = &widgets[i]; + if (w->next.down == *selected_widget) { + /* simulate backtab */ + change_focus_to(i); + return; + } + } + for (i = 0; i < *total_widgets; i++) { + w = &widgets[i]; + if (w->next.right == *selected_widget) { + /* simulate backtab */ + change_focus_to(i); + return; + } + } + } + change_focus_to(0); /* err... */ } /* return: 1 = handled key, 0 = didn't */ int widget_handle_key(struct key_event * k) { - struct widget *widget = &ACTIVE_WIDGET; - int n, onw, wx, fmin, fmax, pad; - enum widget_type current_type = widget->type; - void (*changed)(void); - - if (!(status.flags & DISKWRITER_ACTIVE) - && (current_type == WIDGET_OTHER) - && widget->d.other.handle_key(k)) - return 1; - - if (!(status.flags & DISKWRITER_ACTIVE) && k->mouse - && (status.flags & CLASSIC_MODE)) { - switch(current_type) { - case WIDGET_NUMENTRY: - if (k->mouse_button == MOUSE_BUTTON_LEFT) { - k->sym = SDLK_MINUS; - k->mouse = 0; - } else if (k->mouse_button == MOUSE_BUTTON_RIGHT) { - k->sym = SDLK_PLUS; - k->mouse = 0; - } - break; - default: - break; - }; - } - - if (k->mouse == MOUSE_CLICK) { - if (status.flags & DISKWRITER_ACTIVE) return 0; - switch (current_type) { - case WIDGET_TOGGLE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - widget->d.toggle.state = !widget->d.toggle.state; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_MENUTOGGLE: - if (!NO_MODIFIER(k->mod)) - return 0; - if (k->state) return 1; - widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) - % widget->d.menutoggle.num_choices; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - default: - break; - } - } else if (k->mouse == MOUSE_DBLCLICK) { - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR) { - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.panbar.muted = !widget->d.panbar.muted; - changed = widget->changed; - if (changed) changed(); - return 1; - } - } + struct widget *widget = &ACTIVE_WIDGET; + if (!widget) + return 0; + + int n, onw, wx, fmin, fmax, pad; + void (*changed)(void); + enum widget_type current_type = widget->type; + + if (!(status.flags & DISKWRITER_ACTIVE) + && (current_type == WIDGET_OTHER) + && widget->d.other.handle_key(k)) + return 1; + + if (!(status.flags & DISKWRITER_ACTIVE) && k->mouse + && (status.flags & CLASSIC_MODE)) { + switch(current_type) { + case WIDGET_NUMENTRY: + if (k->mouse_button == MOUSE_BUTTON_LEFT) { + k->sym = SDLK_MINUS; + k->mouse = MOUSE_NONE; + } else if (k->mouse_button == MOUSE_BUTTON_RIGHT) { + k->sym = SDLK_PLUS; + k->mouse = MOUSE_NONE; + } + break; + default: + break; + }; + } + + if (k->mouse == MOUSE_CLICK) { + if (status.flags & DISKWRITER_ACTIVE) return 0; + switch (current_type) { + case WIDGET_TOGGLE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + widget->d.toggle.state = !widget->d.toggle.state; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_MENUTOGGLE: + if (!NO_MODIFIER(k->mod)) + return 0; + if (k->state == KEY_RELEASE) + return 1; + widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) + % widget->d.menutoggle.num_choices; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + default: + break; + } + } else if (k->mouse == MOUSE_DBLCLICK) { + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR) { + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.panbar.muted = !widget->d.panbar.muted; + changed = widget->changed; + if (changed) changed(); + return 1; + } + } - if (k->mouse == MOUSE_CLICK - || (k->mouse == 0 && k->sym == SDLK_RETURN)) { + if (k->mouse == MOUSE_CLICK + || (k->mouse == MOUSE_NONE && k->sym == SDLK_RETURN)) { #if 0 - if (k->mouse && k->mouse_button == MOUSE_BUTTON_MIDDLE) { - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (!k->state) return 1; - status.flags |= CLIPPY_PASTE_SELECTION; - return 1; - } + if (k->mouse && k->mouse_button == MOUSE_BUTTON_MIDDLE) { + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (k->state == KEY_PRESS) + return 1; + status.flags |= CLIPPY_PASTE_SELECTION; + return 1; + } #endif - if (k->mouse && (current_type == WIDGET_THUMBBAR - || current_type == WIDGET_PANBAR)) { - if (status.flags & DISKWRITER_ACTIVE) return 0; - - /* swallow it */ - if (!k->on_target) return 0; - - fmin = widget->d.thumbbar.min; - fmax = widget->d.thumbbar.max; - if (current_type == WIDGET_PANBAR) { - n = k->fx - ((widget->x + 11) * k->rx); - wx = (widget->width - 16) * k->rx; - } else { - n = k->fx - (widget->x * k->rx); - wx = (widget->width-1) * k->rx; - } - if (n < 0) n = 0; - else if (n >= wx) n = wx; - n = fmin + ((n * (fmax - fmin)) / wx); - - if (n < fmin) - n = fmin; - else if (n > fmax) - n = fmax; - if (current_type == WIDGET_PANBAR) { - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - if (k->x - widget->x < 11) return 1; - if (k->x - widget->x > 19) return 1; - } - numentry_change_value(widget, n); - return 1; - } - if (k->mouse) { - switch (widget->type) { - case WIDGET_BUTTON: - pad = widget->d.button.padding+1; - break; - case WIDGET_TOGGLEBUTTON: - pad = widget->d.togglebutton.padding+1; - break; - default: - pad = 0; - }; - onw = ((signed) k->x < widget->x - || (signed) k->x >= widget->x + widget->width + pad - || (signed) k->y != widget->y) ? 0 : 1; - n = ((!k->state) && onw) ? 1 : 0; - if (widget->depressed != n) status.flags |= NEED_UPDATE; - widget->depressed = n; - if (current_type != WIDGET_TEXTENTRY - && current_type != WIDGET_NUMENTRY) { - if (!k->state || !onw) return 1; - } else if (!onw) return 1; - } else { - n = (!k->state) ? 1 : 0; - if (widget->depressed != n) - status.flags |= NEED_UPDATE; - else if (k->state) return 1; // swallor - widget->depressed = n; - if (!k->state) return 1; - } - - if (k->mouse) { - switch(current_type) { - case WIDGET_MENUTOGGLE: - case WIDGET_BUTTON: - case WIDGET_TOGGLEBUTTON: - if (k->on_target && widget->activate) widget->activate(); - default: - break; - }; - } else if (current_type != WIDGET_OTHER) { - if (widget->activate) widget->activate(); - } - - switch (current_type) { - case WIDGET_OTHER: - break; - case WIDGET_TEXTENTRY: - if (status.flags & DISKWRITER_ACTIVE) return 0; - /* LOL WOW THIS SUCKS */ - if (k->mouse == MOUSE_CLICK && k->on_target) { - /* position cursor */ - n = k->x - widget->x; - n = CLAMP(n, 0, widget->width - 1); - wx = k->sx - widget->x; - wx = CLAMP(wx, 0, widget->width - 1); - widget->d.textentry.cursor_pos = n+widget->d.textentry.firstchar; - wx = wx+widget->d.textentry.firstchar; - if (widget->d.textentry.cursor_pos >= (signed) strlen(widget->d.textentry.text)) - widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); - if (wx >= (signed) strlen(widget->d.textentry.text)) - wx = strlen(widget->d.textentry.text); - status.flags |= NEED_UPDATE; - } - - /* for a text entry, the only thing enter does is run the activate callback. - thus, if no activate callback is defined, the key wasn't handled */ - return (widget->activate != NULL); - - case WIDGET_NUMENTRY: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (k->mouse == MOUSE_CLICK && k->on_target) { - /* position cursor */ - n = k->x - widget->x; - n = CLAMP(n, 0, widget->width - 1); - wx = k->sx - widget->x; - wx = CLAMP(wx, 0, widget->width - 1); - if (n >= widget->width) - n = widget->width-1; - *widget->d.numentry.cursor_pos = n; - status.flags |= NEED_UPDATE; - } - - break; - - case WIDGET_TOGGLEBUTTON: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (widget->d.togglebutton.group) { - /* this also runs the changed callback and redraws the button(s) */ - togglebutton_set(widgets, *selected_widget, 1); - return 1; - } - /* else... */ - widget->d.togglebutton.state = !widget->d.togglebutton.state; - /* and fall through */ - case WIDGET_BUTTON: - /* maybe buttons should ignore the changed callback, and use activate instead... - (but still call the changed callback for togglebuttons if they *actually* changed) */ - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - default: - break; - } - return 0; - } - - /* a WIDGET_OTHER that *didn't* handle the key itself needs to get run through the switch - statement to account for stuff like the tab key */ - if (k->state) return 0; - - if (k->mouse == MOUSE_SCROLL_UP && current_type == WIDGET_NUMENTRY) { - k->sym = SDLK_MINUS; - } else if (k->mouse == MOUSE_SCROLL_DOWN && current_type == WIDGET_NUMENTRY) { - k->sym = SDLK_PLUS; - } - - switch (k->sym) { - case SDLK_ESCAPE: - /* this is to keep the text entries from taking the key hostage and inserting '<-' - characters instead of showing the menu */ - return 0; - case SDLK_UP: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(widget->next.up); - return 1; - case SDLK_DOWN: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(widget->next.down); - return 1; - case SDLK_TAB: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (k->mod & KMOD_SHIFT) { - _backtab(); - return 1; - } - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(widget->next.tab); - return 1; - case SDLK_LEFT: - if (status.flags & DISKWRITER_ACTIVE) return 0; - switch (current_type) { - case WIDGET_BITSET: - if (NO_MODIFIER(k->mod)) - bitset_move_cursor(widget, -1); - break; - case WIDGET_NUMENTRY: - if (!NO_MODIFIER(k->mod)) { - return 0; - } - numentry_move_cursor(widget, -1); - return 1; - case WIDGET_TEXTENTRY: - if (!NO_MODIFIER(k->mod)) { - return 0; - } - textentry_move_cursor(widget, -1); - return 1; - case WIDGET_PANBAR: - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - /* fall through */ - case WIDGET_THUMBBAR: - /* I'm handling the key modifiers differently than Impulse Tracker, but only - because I think this is much more useful. :) */ - n = 1; - if (k->mod & (KMOD_ALT | KMOD_META)) - n *= 8; - if (k->mod & KMOD_SHIFT) - n *= 4; - if (k->mod & KMOD_CTRL) - n *= 2; - n = widget->d.numentry.value - n; - numentry_change_value(widget, n); - return 1; - default: - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(widget->next.left); - return 1; - } - break; - case SDLK_RIGHT: - if (status.flags & DISKWRITER_ACTIVE) return 0; - /* pretty much the same as left, but with a few small - * changes here and there... */ - switch (current_type) { - case WIDGET_BITSET: - if (NO_MODIFIER(k->mod)) - bitset_move_cursor(widget, 1); - break; - case WIDGET_NUMENTRY: - if (!NO_MODIFIER(k->mod)) { - return 0; - } - numentry_move_cursor(widget, 1); - return 1; - case WIDGET_TEXTENTRY: - if (!NO_MODIFIER(k->mod)) { - return 0; - } - textentry_move_cursor(widget, 1); - return 1; - case WIDGET_PANBAR: - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - /* fall through */ - case WIDGET_THUMBBAR: - n = 1; - if (k->mod & (KMOD_ALT | KMOD_META)) - n *= 8; - if (k->mod & KMOD_SHIFT) - n *= 4; - if (k->mod & KMOD_CTRL) - n *= 2; - n = widget->d.numentry.value + n; - numentry_change_value(widget, n); - return 1; - default: - if (!NO_MODIFIER(k->mod)) - return 0; - change_focus_to(widget->next.right); - return 1; - } - break; - case SDLK_HOME: - if (status.flags & DISKWRITER_ACTIVE) return 0; - /* Impulse Tracker only does home/end for the thumbbars. - * This stuff is all extra. */ - switch (current_type) { - case WIDGET_NUMENTRY: - if (!NO_MODIFIER(k->mod)) - return 0; - *(widget->d.numentry.cursor_pos) = 0; - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_TEXTENTRY: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.textentry.cursor_pos = 0; - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_PANBAR: - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - /* fall through */ - case WIDGET_THUMBBAR: - n = widget->d.thumbbar.min; - numentry_change_value(widget, n); - return 1; - default: - break; - } - break; - case SDLK_END: - if (status.flags & DISKWRITER_ACTIVE) return 0; - switch (current_type) { - case WIDGET_NUMENTRY: - if (!NO_MODIFIER(k->mod)) - return 0; - *(widget->d.numentry.cursor_pos) = widget->width - 1; - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_TEXTENTRY: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_PANBAR: - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - /* fall through */ - case WIDGET_THUMBBAR: - n = widget->d.thumbbar.max; - numentry_change_value(widget, n); - return 1; - default: - break; - } - break; - case SDLK_SPACE: - if (status.flags & DISKWRITER_ACTIVE) return 0; - switch (current_type) { - case WIDGET_BITSET: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.bitset.value ^= (1 << *widget->d.bitset.cursor_pos); - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_TOGGLE: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.toggle.state = !widget->d.toggle.state; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_MENUTOGGLE: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) - % widget->d.menutoggle.num_choices; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case WIDGET_PANBAR: - if (!NO_MODIFIER(k->mod)) - return 0; - widget->d.panbar.muted = !widget->d.panbar.muted; - changed = widget->changed; - change_focus_to(widget->next.down); - if (changed) changed(); - return 1; - default: - break; - } - break; - case SDLK_BACKSPACE: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_NUMENTRY) { - if (widget->d.numentry.reverse) { - /* woot! */ - widget->d.numentry.value /= 10; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - } - } - - /* this ought to be in a separate function. */ - if (current_type != WIDGET_TEXTENTRY) - break; - if (!widget->d.textentry.text[0]) { - /* nothing to do */ - return 1; - } - if (k->mod & KMOD_CTRL) { - /* clear the whole field */ - widget->d.textentry.text[0] = 0; - widget->d.textentry.cursor_pos = 0; - } else { - if (widget->d.textentry.cursor_pos == 0) { - /* act like ST3 */ - text_delete_next_char(widget->d.textentry.text, - &(widget->d.textentry.cursor_pos), - widget->d.textentry.max_length); - } else { - text_delete_char(widget->d.textentry.text, - &(widget->d.textentry.cursor_pos), - widget->d.textentry.max_length); - } - } - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_DELETE: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type != WIDGET_TEXTENTRY) - break; - if (!widget->d.textentry.text[0]) { - /* nothing to do */ - return 1; - } - text_delete_next_char(widget->d.textentry.text, - &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length); - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - case SDLK_PLUS: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { - numentry_change_value(widget, widget->d.numentry.value + 1); - return 1; - } - break; - case SDLK_MINUS: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { - numentry_change_value(widget, widget->d.numentry.value - 1); - return 1; - } - break; - case SDLK_l: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR) { - if (k->mod & KMOD_ALT) { - song_set_pan_scheme(PANS_LEFT); - return 1; - } else if (NO_MODIFIER(k->mod)) { - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - numentry_change_value(widget, 0); - return 1; - } - } - break; - case SDLK_m: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR) { - if (k->mod & KMOD_ALT) { - song_set_pan_scheme(PANS_MONO); - return 1; - } else if (NO_MODIFIER(k->mod)) { - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - numentry_change_value(widget, 32); - return 1; - } - } - break; - case SDLK_r: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR) { - if (k->mod & KMOD_ALT) { - song_set_pan_scheme(PANS_RIGHT); - return 1; - } else if (NO_MODIFIER(k->mod)) { - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 0; - numentry_change_value(widget, 64); - return 1; - } - } - break; - case SDLK_s: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR) { - if (k->mod & KMOD_ALT) { - song_set_pan_scheme(PANS_STEREO); - return 1; - } else if(NO_MODIFIER(k->mod)) { - widget->d.panbar.muted = 0; - widget->d.panbar.surround = 1; - if (widget->changed) widget->changed(); - status.flags |= NEED_UPDATE; - return 1; - } - } - break; - case SDLK_a: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { - song_set_pan_scheme(PANS_AMIGA); - return 1; - } - break; + if (k->mouse && (current_type == WIDGET_THUMBBAR + || current_type == WIDGET_PANBAR)) { + if (status.flags & DISKWRITER_ACTIVE) return 0; + + /* swallow it */ + if (!k->on_target) return 0; + + fmin = widget->d.thumbbar.min; + fmax = widget->d.thumbbar.max; + if (current_type == WIDGET_PANBAR) { + n = k->fx - ((widget->x + 11) * k->rx); + wx = (widget->width - 16) * k->rx; + } else { + n = k->fx - (widget->x * k->rx); + wx = (widget->width-1) * k->rx; + } + if (n < 0) n = 0; + else if (n >= wx) n = wx; + n = fmin + ((n * (fmax - fmin)) / wx); + + if (n < fmin) + n = fmin; + else if (n > fmax) + n = fmax; + if (current_type == WIDGET_PANBAR) { + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + if (k->x - widget->x < 11) return 1; + if (k->x - widget->x > 19) return 1; + } + numentry_change_value(widget, n); + return 1; + } + if (k->mouse) { + switch (widget->type) { + case WIDGET_BUTTON: + pad = widget->d.button.padding+1; + break; + case WIDGET_TOGGLEBUTTON: + pad = widget->d.togglebutton.padding+1; + break; + default: + pad = 0; + }; + onw = ((signed) k->x < widget->x + || (signed) k->x >= widget->x + widget->width + pad + || (signed) k->y != widget->y) ? 0 : 1; + n = (k->state == KEY_RELEASE && onw) ? 1 : 0; + if (widget->depressed != n) status.flags |= NEED_UPDATE; + widget->depressed = n; + if (current_type != WIDGET_TEXTENTRY && current_type != WIDGET_NUMENTRY) { + if (k->state == KEY_PRESS || !onw) + return 1; + } else if (!onw) { + return 1; + } + } else { + n = (k->state == KEY_PRESS) ? 1 : 0; + if (widget->depressed != n) + status.flags |= NEED_UPDATE; + else if (k->state == KEY_RELEASE) + return 1; // swallor + widget->depressed = n; + if (k->state == KEY_PRESS) + return 1; + } + + if (k->mouse) { + switch(current_type) { + case WIDGET_MENUTOGGLE: + case WIDGET_BUTTON: + case WIDGET_TOGGLEBUTTON: + if (k->on_target && widget->activate) widget->activate(); + default: + break; + }; + } else if (current_type != WIDGET_OTHER) { + if (widget->activate) widget->activate(); + } + + switch (current_type) { + case WIDGET_OTHER: + break; + case WIDGET_TEXTENTRY: + if (status.flags & DISKWRITER_ACTIVE) return 0; + /* LOL WOW THIS SUCKS */ + if (k->mouse == MOUSE_CLICK && k->on_target) { + /* position cursor */ + n = k->x - widget->x; + n = CLAMP(n, 0, widget->width - 1); + wx = k->sx - widget->x; + wx = CLAMP(wx, 0, widget->width - 1); + widget->d.textentry.cursor_pos = n+widget->d.textentry.firstchar; + wx = wx+widget->d.textentry.firstchar; + if (widget->d.textentry.cursor_pos >= (signed) strlen(widget->d.textentry.text)) + widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); + if (wx >= (signed) strlen(widget->d.textentry.text)) + wx = strlen(widget->d.textentry.text); + status.flags |= NEED_UPDATE; + } + + /* for a text entry, the only thing enter does is run the activate callback. + thus, if no activate callback is defined, the key wasn't handled */ + return (widget->activate != NULL); + + case WIDGET_NUMENTRY: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (k->mouse == MOUSE_CLICK && k->on_target) { + /* position cursor */ + n = k->x - widget->x; + n = CLAMP(n, 0, widget->width - 1); + wx = k->sx - widget->x; + wx = CLAMP(wx, 0, widget->width - 1); + if (n >= widget->width) + n = widget->width-1; + *widget->d.numentry.cursor_pos = n; + status.flags |= NEED_UPDATE; + } + + break; + + case WIDGET_TOGGLEBUTTON: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (widget->d.togglebutton.group) { + /* this also runs the changed callback and redraws the button(s) */ + togglebutton_set(widgets, *selected_widget, 1); + return 1; + } + /* else... */ + widget->d.togglebutton.state = !widget->d.togglebutton.state; + /* and fall through */ + case WIDGET_BUTTON: + /* maybe buttons should ignore the changed callback, and use activate instead... + (but still call the changed callback for togglebuttons if they *actually* changed) */ + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + default: + break; + } + return 0; + } + + /* a WIDGET_OTHER that *didn't* handle the key itself needs to get run through the switch + statement to account for stuff like the tab key */ + if (k->state == KEY_RELEASE) + return 0; + + if (k->mouse == MOUSE_SCROLL_UP && current_type == WIDGET_NUMENTRY) { + k->sym = SDLK_MINUS; + } else if (k->mouse == MOUSE_SCROLL_DOWN && current_type == WIDGET_NUMENTRY) { + k->sym = SDLK_PLUS; + } + + switch (k->sym) { + case SDLK_ESCAPE: + /* this is to keep the text entries from taking the key hostage and inserting '<-' + characters instead of showing the menu */ + return 0; + case SDLK_UP: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(widget->next.up); + return 1; + case SDLK_DOWN: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(widget->next.down); + return 1; + case SDLK_TAB: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (k->mod & KMOD_SHIFT) { + _backtab(); + return 1; + } + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(widget->next.tab); + return 1; + case SDLK_LEFT: + if (status.flags & DISKWRITER_ACTIVE) return 0; + switch (current_type) { + case WIDGET_BITSET: + if (NO_MODIFIER(k->mod)) + bitset_move_cursor(widget, -1); + break; + case WIDGET_NUMENTRY: + if (!NO_MODIFIER(k->mod)) { + return 0; + } + numentry_move_cursor(widget, -1); + return 1; + case WIDGET_TEXTENTRY: + if (!NO_MODIFIER(k->mod)) { + return 0; + } + textentry_move_cursor(widget, -1); + return 1; + case WIDGET_PANBAR: + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + /* fall through */ + case WIDGET_THUMBBAR: + /* I'm handling the key modifiers differently than Impulse Tracker, but only + because I think this is much more useful. :) */ + n = 1; + if (k->mod & (KMOD_ALT | KMOD_META)) + n *= 8; + if (k->mod & KMOD_SHIFT) + n *= 4; + if (k->mod & KMOD_CTRL) + n *= 2; + n = widget->d.numentry.value - n; + numentry_change_value(widget, n); + return 1; + default: + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(widget->next.left); + return 1; + } + break; + case SDLK_RIGHT: + if (status.flags & DISKWRITER_ACTIVE) return 0; + /* pretty much the same as left, but with a few small + * changes here and there... */ + switch (current_type) { + case WIDGET_BITSET: + if (NO_MODIFIER(k->mod)) + bitset_move_cursor(widget, 1); + break; + case WIDGET_NUMENTRY: + if (!NO_MODIFIER(k->mod)) { + return 0; + } + numentry_move_cursor(widget, 1); + return 1; + case WIDGET_TEXTENTRY: + if (!NO_MODIFIER(k->mod)) { + return 0; + } + textentry_move_cursor(widget, 1); + return 1; + case WIDGET_PANBAR: + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + /* fall through */ + case WIDGET_THUMBBAR: + n = 1; + if (k->mod & (KMOD_ALT | KMOD_META)) + n *= 8; + if (k->mod & KMOD_SHIFT) + n *= 4; + if (k->mod & KMOD_CTRL) + n *= 2; + n = widget->d.numentry.value + n; + numentry_change_value(widget, n); + return 1; + default: + if (!NO_MODIFIER(k->mod)) + return 0; + change_focus_to(widget->next.right); + return 1; + } + break; + case SDLK_HOME: + if (status.flags & DISKWRITER_ACTIVE) return 0; + /* Impulse Tracker only does home/end for the thumbbars. + * This stuff is all extra. */ + switch (current_type) { + case WIDGET_NUMENTRY: + if (!NO_MODIFIER(k->mod)) + return 0; + *(widget->d.numentry.cursor_pos) = 0; + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_TEXTENTRY: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.textentry.cursor_pos = 0; + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_PANBAR: + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + /* fall through */ + case WIDGET_THUMBBAR: + n = widget->d.thumbbar.min; + numentry_change_value(widget, n); + return 1; + default: + break; + } + break; + case SDLK_END: + if (status.flags & DISKWRITER_ACTIVE) return 0; + switch (current_type) { + case WIDGET_NUMENTRY: + if (!NO_MODIFIER(k->mod)) + return 0; + *(widget->d.numentry.cursor_pos) = widget->width - 1; + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_TEXTENTRY: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_PANBAR: + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + /* fall through */ + case WIDGET_THUMBBAR: + n = widget->d.thumbbar.max; + numentry_change_value(widget, n); + return 1; + default: + break; + } + break; + case SDLK_SPACE: + if (status.flags & DISKWRITER_ACTIVE) return 0; + switch (current_type) { + case WIDGET_BITSET: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.bitset.value ^= (1 << *widget->d.bitset.cursor_pos); + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_TOGGLE: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.toggle.state = !widget->d.toggle.state; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_MENUTOGGLE: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) + % widget->d.menutoggle.num_choices; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case WIDGET_PANBAR: + if (!NO_MODIFIER(k->mod)) + return 0; + widget->d.panbar.muted = !widget->d.panbar.muted; + changed = widget->changed; + change_focus_to(widget->next.down); + if (changed) changed(); + return 1; + default: + break; + } + break; + case SDLK_BACKSPACE: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_NUMENTRY) { + if (widget->d.numentry.reverse) { + /* woot! */ + widget->d.numentry.value /= 10; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + } + } + + /* this ought to be in a separate function. */ + if (current_type != WIDGET_TEXTENTRY) + break; + if (!widget->d.textentry.text[0]) { + /* nothing to do */ + return 1; + } + if (k->mod & KMOD_CTRL) { + /* clear the whole field */ + widget->d.textentry.text[0] = 0; + widget->d.textentry.cursor_pos = 0; + } else { + if (widget->d.textentry.cursor_pos == 0) { + /* act like ST3 */ + text_delete_next_char(widget->d.textentry.text, + &(widget->d.textentry.cursor_pos), + widget->d.textentry.max_length); + } else { + text_delete_char(widget->d.textentry.text, + &(widget->d.textentry.cursor_pos), + widget->d.textentry.max_length); + } + } + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_DELETE: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type != WIDGET_TEXTENTRY) + break; + if (!widget->d.textentry.text[0]) { + /* nothing to do */ + return 1; + } + text_delete_next_char(widget->d.textentry.text, + &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length); + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + case SDLK_PLUS: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { + numentry_change_value(widget, widget->d.numentry.value + 1); + return 1; + } + break; + case SDLK_MINUS: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { + numentry_change_value(widget, widget->d.numentry.value - 1); + return 1; + } + break; + case SDLK_l: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR) { + if (k->mod & KMOD_ALT) { + song_set_pan_scheme(PANS_LEFT); + return 1; + } else if (NO_MODIFIER(k->mod)) { + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + numentry_change_value(widget, 0); + return 1; + } + } + break; + case SDLK_m: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR) { + if (k->mod & KMOD_ALT) { + song_set_pan_scheme(PANS_MONO); + return 1; + } else if (NO_MODIFIER(k->mod)) { + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + numentry_change_value(widget, 32); + return 1; + } + } + break; + case SDLK_r: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR) { + if (k->mod & KMOD_ALT) { + song_set_pan_scheme(PANS_RIGHT); + return 1; + } else if (NO_MODIFIER(k->mod)) { + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 0; + numentry_change_value(widget, 64); + return 1; + } + } + break; + case SDLK_s: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR) { + if (k->mod & KMOD_ALT) { + song_set_pan_scheme(PANS_STEREO); + return 1; + } else if(NO_MODIFIER(k->mod)) { + widget->d.panbar.muted = 0; + widget->d.panbar.surround = 1; + if (widget->changed) widget->changed(); + status.flags |= NEED_UPDATE; + return 1; + } + } + break; + case SDLK_a: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { + song_set_pan_scheme(PANS_AMIGA); + return 1; + } + break; #if 0 - case SDLK_x: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { - song_set_pan_scheme(PANS_CROSS); - return 1; - } - break; + case SDLK_x: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { + song_set_pan_scheme(PANS_CROSS); + return 1; + } + break; #endif - case SDLK_SLASH: - case SDLK_KP_DIVIDE: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { - song_set_pan_scheme(PANS_SLASH); - return 1; - } - break; - case SDLK_BACKSLASH: - if (status.flags & DISKWRITER_ACTIVE) return 0; - if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { - song_set_pan_scheme(PANS_BACKSLASH); - return 1; - } - break; - default: - /* this avoids a warning about all the values of an enum not being handled. - (sheesh, it's already hundreds of lines long as it is!) */ - break; - } - if (status.flags & DISKWRITER_ACTIVE) return 0; - - /* if we're here, that mess didn't completely handle the key (gosh...) so now here's another mess. */ - switch (current_type) { - case WIDGET_MENUTOGGLE: - if (menutoggle_handle_key(widget, k)) - return 1; - break; - case WIDGET_BITSET: - if (bitset_handle_key(widget, k)) - return 1; - break; - case WIDGET_NUMENTRY: - if (numentry_handle_digit(widget, k)) - return 1; - break; - case WIDGET_THUMBBAR: - case WIDGET_PANBAR: - if (thumbbar_prompt_value(widget, k)) - return 1; - break; - case WIDGET_TEXTENTRY: - if ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0 - && textentry_add_char(widget, k->unicode)) - return 1; - break; - default: - break; - } + case SDLK_SLASH: + case SDLK_KP_DIVIDE: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { + song_set_pan_scheme(PANS_SLASH); + return 1; + } + break; + case SDLK_BACKSLASH: + if (status.flags & DISKWRITER_ACTIVE) return 0; + if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { + song_set_pan_scheme(PANS_BACKSLASH); + return 1; + } + break; + default: + /* this avoids a warning about all the values of an enum not being handled. + (sheesh, it's already hundreds of lines long as it is!) */ + break; + } + if (status.flags & DISKWRITER_ACTIVE) return 0; + + /* if we're here, that mess didn't completely handle the key (gosh...) so now here's another mess. */ + switch (current_type) { + case WIDGET_MENUTOGGLE: + if (menutoggle_handle_key(widget, k)) + return 1; + break; + case WIDGET_BITSET: + if (bitset_handle_key(widget, k)) + return 1; + break; + case WIDGET_NUMENTRY: + if (numentry_handle_digit(widget, k)) + return 1; + break; + case WIDGET_THUMBBAR: + case WIDGET_PANBAR: + if (thumbbar_prompt_value(widget, k)) + return 1; + break; + case WIDGET_TEXTENTRY: + if ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0 + && textentry_add_char(widget, k->unicode)) + return 1; + break; + default: + break; + } - /* if we got down here the key wasn't handled */ - return 0; + /* if we got down here the key wasn't handled */ + return 0; } diff -Nru schism-0+20110101/schism/xpmdata.c schism-20160521/schism/xpmdata.c --- schism-0+20110101/schism/xpmdata.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/schism/xpmdata.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -54,27 +54,27 @@ #define SKIPSPACE(p) \ do { \ - while(isspace((unsigned char)*(p))) \ - ++(p); \ + while(isspace((unsigned char)*(p))) \ + ++(p); \ } while(0) #define SKIPNONSPACE(p) \ do { \ - while(!isspace((unsigned char)*(p)) && *p) \ - ++(p); \ + while(!isspace((unsigned char)*(p)) && *p) \ + ++(p); \ } while(0) /* portable case-insensitive string comparison */ static int string_equal(const char *a, const char *b, int n) { - while(*a && *b && n) { - if(toupper((unsigned char)*a) != toupper((unsigned char)*b)) - return 0; - a++; - b++; - n--; - } - return *a == *b; + while(*a && *b && n) { + if(toupper((unsigned char)*a) != toupper((unsigned char)*b)) + return 0; + a++; + b++; + n--; + } + return *a == *b; } #define ARRAYSIZE(a) (int)(sizeof(a) / sizeof((a)[0])) @@ -85,117 +85,117 @@ */ static int color_to_rgb(const char *spec, int speclen, uint32_t *rgb) { - /* poor man's rgb.txt */ - static struct { const char *name; uint32_t rgb; } known[] = { - {"none", 0xffffffff}, - {"black", 0x00000000}, - {"white", 0x00ffffff}, - {"red", 0x00ff0000}, - {"green", 0x0000ff00}, - {"blue", 0x000000ff}, - {"gray27",0x00454545}, - {"gray4", 0x000a0a0a}, - }; - - if(spec[0] == '#') { - char buf[7]; - switch(speclen) { - case 4: - buf[0] = buf[1] = spec[1]; - buf[2] = buf[3] = spec[2]; - buf[4] = buf[5] = spec[3]; - break; - case 7: - memcpy(buf, spec + 1, 6); - break; - case 13: - buf[0] = spec[1]; - buf[1] = spec[2]; - buf[2] = spec[5]; - buf[3] = spec[6]; - buf[4] = spec[9]; - buf[5] = spec[10]; - break; - } - buf[6] = '\0'; - *rgb = strtol(buf, NULL, 16); - return 1; - } else { - int i; - for(i = 0; i < ARRAYSIZE(known); i++) - if(string_equal(known[i].name, spec, speclen)) { - *rgb = known[i].rgb; - return 1; - } - return 0; - } + /* poor man's rgb.txt */ + static struct { const char *name; uint32_t rgb; } known[] = { + {"none", 0xffffffff}, + {"black", 0x00000000}, + {"white", 0x00ffffff}, + {"red", 0x00ff0000}, + {"green", 0x0000ff00}, + {"blue", 0x000000ff}, + {"gray27",0x00454545}, + {"gray4", 0x000a0a0a}, + }; + + if(spec[0] == '#') { + char buf[7]; + switch(speclen) { + case 4: + buf[0] = buf[1] = spec[1]; + buf[2] = buf[3] = spec[2]; + buf[4] = buf[5] = spec[3]; + break; + case 7: + memcpy(buf, spec + 1, 6); + break; + case 13: + buf[0] = spec[1]; + buf[1] = spec[2]; + buf[2] = spec[5]; + buf[3] = spec[6]; + buf[4] = spec[9]; + buf[5] = spec[10]; + break; + } + buf[6] = '\0'; + *rgb = strtol(buf, NULL, 16); + return 1; + } else { + int i; + for(i = 0; i < ARRAYSIZE(known); i++) + if(string_equal(known[i].name, spec, speclen)) { + *rgb = known[i].rgb; + return 1; + } + return 0; + } } #define STARTING_HASH_SIZE 256 struct hash_entry { - char *key; - uint32_t color; - struct hash_entry *next; + char *key; + uint32_t color; + struct hash_entry *next; }; struct color_hash { - struct hash_entry **table; - struct hash_entry *entries; /* array of all entries */ - struct hash_entry *next_free; - int size; - int maxnum; + struct hash_entry **table; + struct hash_entry *entries; /* array of all entries */ + struct hash_entry *next_free; + int size; + int maxnum; }; static int hash_key(const char *key, int cpp, int size) { - int hash; + int hash; - hash = 0; - while ( cpp-- > 0 ) { - hash = hash * 33 + *key++; - } - return hash & (size - 1); + hash = 0; + while ( cpp-- > 0 ) { + hash = hash * 33 + *key++; + } + return hash & (size - 1); } static struct color_hash *create_colorhash(int maxnum) { - int bytes, s; - struct color_hash *hash; + int bytes, s; + struct color_hash *hash; - /* we know how many entries we need, so we can allocate - everything here */ - hash = malloc(sizeof *hash); - if(!hash) - return NULL; - - /* use power-of-2 sized hash table for decoding speed */ - for(s = STARTING_HASH_SIZE; s < maxnum; s <<= 1) - ; - hash->size = s; - hash->maxnum = maxnum; - bytes = hash->size * sizeof(struct hash_entry **); - hash->entries = NULL; /* in case malloc fails */ - hash->table = malloc(bytes); - if(!hash->table) - return NULL; - memset(hash->table, 0, bytes); - hash->entries = malloc(maxnum * sizeof(struct hash_entry)); - if(!hash->entries) - return NULL; - hash->next_free = hash->entries; - return hash; + /* we know how many entries we need, so we can allocate + everything here */ + hash = malloc(sizeof *hash); + if(!hash) + return NULL; + + /* use power-of-2 sized hash table for decoding speed */ + for(s = STARTING_HASH_SIZE; s < maxnum; s <<= 1) + ; + hash->size = s; + hash->maxnum = maxnum; + bytes = hash->size * sizeof(struct hash_entry **); + hash->entries = NULL; /* in case malloc fails */ + hash->table = malloc(bytes); + if(!hash->table) + return NULL; + memset(hash->table, 0, bytes); + hash->entries = malloc(maxnum * sizeof(struct hash_entry)); + if(!hash->entries) + return NULL; + hash->next_free = hash->entries; + return hash; } static int add_colorhash(struct color_hash *hash, - char *key, int cpp, uint32_t color) + char *key, int cpp, uint32_t color) { - int h = hash_key(key, cpp, hash->size); - struct hash_entry *e = hash->next_free++; - e->color = color; - e->key = key; - e->next = hash->table[h]; - hash->table[h] = e; - return 1; + int h = hash_key(key, cpp, hash->size); + struct hash_entry *e = hash->next_free++; + e->color = color; + e->key = key; + e->next = hash->table[h]; + hash->table[h] = e; + return 1; } /* fast lookup that works if cpp == 1 */ @@ -203,186 +203,184 @@ static uint32_t get_colorhash(struct color_hash *hash, const char *key, int cpp) { - struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)]; - while(entry) { - if(memcmp(key, entry->key, cpp) == 0) - return entry->color; - entry = entry->next; - } - return 0; /* garbage in - garbage out */ + struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)]; + while(entry) { + if(memcmp(key, entry->key, cpp) == 0) + return entry->color; + entry = entry->next; + } + return 0; /* garbage in - garbage out */ } static void free_colorhash(struct color_hash *hash) { - if(hash && hash->table) { - free(hash->table); - free(hash->entries); - free(hash); - } + if(hash && hash->table) { + free(hash->table); + free(hash->entries); + free(hash); + } } SDL_Surface *xpmdata(const char *data[]) { - SDL_Surface *image = NULL; - int n; - int x, y; - int w, h, ncolors, cpp; - int indexed; - Uint8 *dst; - struct color_hash *colors = NULL; - SDL_Color *im_colors = NULL; - char *keystrings = NULL, *nextkey; - const char *line; - const char ***xpmlines = NULL; -#define get_next_line(q,l) *(*xpmlines)++ - int pixels_len; - int error; - int usedn; - - error = 0; - - xpmlines = (const char ***) &data; - - line = get_next_line(xpmlines, 0); - if(!line) goto done; - - /* - * The header string of an XPMv3 image has the format - * - * [ ] - * - * where the hotspot coords are intended for mouse cursors. - * Right now we don't use the hotspots but it should be handled - * one day. - */ - if(sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 - || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { - error = 1; - goto done; - } - - keystrings = malloc(ncolors * cpp); - if(!keystrings) { - error = 2; - goto done; - } - nextkey = keystrings; - - /* Create the new surface */ - if(ncolors <= 256) { - indexed = 1; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, - 0, 0, 0, 0); - im_colors = image->format->palette->colors; - image->format->palette->ncolors = ncolors; - } else { - indexed = 0; - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, - 0xff0000, 0x00ff00, 0x0000ff, 0); - } - if(!image) { - /* Hmm, some SDL error (out of memory?) */ - error = 3; - goto done; - } - - /* Read the colors */ - colors = create_colorhash(ncolors); - if (!colors) { - error = 2; - goto done; - } - usedn = 1; - for(n = 0; n < ncolors; ++n) { - const char *p; - line = get_next_line(xpmlines, 0); - if(!line) - goto done; - - p = line + cpp + 1; - - /* parse a colour definition */ - for(;;) { - char nametype; - const char *colname; - uint32_t rgb, pixel; - SDL_Color *c; - int m; - - SKIPSPACE(p); - if(!*p) { - error = 3; - goto done; - } - nametype = *p; - SKIPNONSPACE(p); - SKIPSPACE(p); - colname = p; - SKIPNONSPACE(p); - if(nametype == 's') - continue; /* skip symbolic colour names */ - - if(!color_to_rgb(colname, p - colname, &rgb)) - continue; - - - memcpy(nextkey, line, cpp); - if(indexed) { - /* arrange for None to be color 0 */ - if (usedn && (rgb == 0xffffffff)) { - m = 0; - usedn = 0; - } else { - m = n+usedn; - } - - c = im_colors + m; - c->r = rgb >> 16; - c->g = rgb >> 8; - c->b = rgb; - pixel = m; - } else - pixel = rgb; - add_colorhash(colors, nextkey, cpp, pixel); - nextkey += cpp; - if(rgb == 0xffffffff) - SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel); - break; - } - } - - /* Read the pixels */ - pixels_len = w * cpp; - dst = image->pixels; - for(y = 0; y < h; y++) { - line = get_next_line(xpmlines, pixels_len); - if(indexed) { - /* optimization for some common cases */ - if(cpp == 1) - for(x = 0; x < w; x++) - dst[x] = QUICK_COLORHASH(colors, - line + x); - else - for(x = 0; x < w; x++) - dst[x] = get_colorhash(colors, - line + x * cpp, - cpp); - } else { - for (x = 0; x < w; x++) - ((uint32_t*)dst)[x] = get_colorhash(colors, - line + x * cpp, - cpp); - } - dst += image->pitch; - } + SDL_Surface *image = NULL; + int n; + int x, y; + int w, h, ncolors, cpp; + int indexed; + Uint8 *dst; + struct color_hash *colors = NULL; + SDL_Color *im_colors = NULL; + char *keystrings = NULL, *nextkey; + const char *line; + const char ***xpmlines = NULL; +#define get_next_line(q) *(*q)++ + int error; + int usedn; + + error = 0; + + xpmlines = (const char ***) &data; + + line = get_next_line(xpmlines); + if(!line) goto done; + + /* + * The header string of an XPMv3 image has the format + * + * [ ] + * + * where the hotspot coords are intended for mouse cursors. + * Right now we don't use the hotspots but it should be handled + * one day. + */ + if(sscanf(line, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 + || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { + error = 1; + goto done; + } + + keystrings = malloc(ncolors * cpp); + if(!keystrings) { + error = 2; + goto done; + } + nextkey = keystrings; + + /* Create the new surface */ + if(ncolors <= 256) { + indexed = 1; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, + 0, 0, 0, 0); + im_colors = image->format->palette->colors; + image->format->palette->ncolors = ncolors; + } else { + indexed = 0; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, + 0xff0000, 0x00ff00, 0x0000ff, 0); + } + if(!image) { + /* Hmm, some SDL error (out of memory?) */ + error = 3; + goto done; + } + + /* Read the colors */ + colors = create_colorhash(ncolors); + if (!colors) { + error = 2; + goto done; + } + usedn = 1; + for(n = 0; n < ncolors; ++n) { + const char *p; + line = get_next_line(xpmlines); + if(!line) + goto done; + + p = line + cpp + 1; + + /* parse a colour definition */ + for(;;) { + char nametype; + const char *colname; + uint32_t rgb, pixel; + SDL_Color *c; + int m; + + SKIPSPACE(p); + if(!*p) { + error = 3; + goto done; + } + nametype = *p; + SKIPNONSPACE(p); + SKIPSPACE(p); + colname = p; + SKIPNONSPACE(p); + if(nametype == 's') + continue; /* skip symbolic colour names */ + + if(!color_to_rgb(colname, p - colname, &rgb)) + continue; + + + memcpy(nextkey, line, cpp); + if(indexed) { + /* arrange for None to be color 0 */ + if (usedn && (rgb == 0xffffffff)) { + m = 0; + usedn = 0; + } else { + m = n+usedn; + } + + c = im_colors + m; + c->r = rgb >> 16; + c->g = rgb >> 8; + c->b = rgb; + pixel = m; + } else + pixel = rgb; + add_colorhash(colors, nextkey, cpp, pixel); + nextkey += cpp; + if(rgb == 0xffffffff) + SDL_SetColorKey(image, SDL_SRCCOLORKEY, pixel); + break; + } + } + + /* Read the pixels */ + dst = image->pixels; + for(y = 0; y < h; y++) { + line = get_next_line(xpmlines); + if(indexed) { + /* optimization for some common cases */ + if(cpp == 1) + for(x = 0; x < w; x++) + dst[x] = QUICK_COLORHASH(colors, + line + x); + else + for(x = 0; x < w; x++) + dst[x] = get_colorhash(colors, + line + x * cpp, + cpp); + } else { + for (x = 0; x < w; x++) + ((uint32_t*)dst)[x] = get_colorhash(colors, + line + x * cpp, + cpp); + } + dst += image->pitch; + } done: - if(error) { - SDL_FreeSurface(image); - image = NULL; - } - free(keystrings); - free_colorhash(colors); - return image; + if(error) { + SDL_FreeSurface(image); + image = NULL; + } + free(keystrings); + free_colorhash(colors); + return image; } diff -Nru schism-0+20110101/scripts/lutgen.c schism-20160521/scripts/lutgen.c --- schism-0+20110101/scripts/lutgen.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/scripts/lutgen.c 2016-05-21 14:40:41.000000000 +0000 @@ -1,5 +1,5 @@ #define compile \ - exec gcc -Wall -pedantic -std=gnu99 -lm lutgen.c -o lutgen || exit 255 + exec gcc -Wall -pedantic -std=gnu99 -lm lutgen.c -o lutgen || exit 255 #include #include @@ -75,38 +75,38 @@ float scale = (float) SPLINE_QUANTSCALE; for (i = 0; i < len; i++) { - float LCm1, LC0, LC1, LC2; - float LX = ((float) i) * flen; - int indx = i << 2; + float LCm1, LC0, LC1, LC2; + float LX = ((float) i) * flen; + int indx = i << 2; #ifdef SPLINE_CLAMPFORUNITY - int sum; + int sum; #endif - LCm1 = (float) floor(0.5 + scale * (-0.5 * LX * LX * LX + 1.0 * LX * LX - 0.5 * LX )); - LC0 = (float) floor(0.5 + scale * ( 1.5 * LX * LX * LX - 2.5 * LX * LX + 1.0)); - LC1 = (float) floor(0.5 + scale * (-1.5 * LX * LX * LX + 2.0 * LX * LX + 0.5 * LX )); - LC2 = (float) floor(0.5 + scale * ( 0.5 * LX * LX * LX - 0.5 * LX * LX )); - - cubic_spline_lut[indx + 0] = (int16_t) ((LCm1 < -scale) ? -scale : ((LCm1 > scale) ? scale : LCm1)); - cubic_spline_lut[indx + 1] = (int16_t) ((LC0 < -scale) ? -scale : ((LC0 > scale) ? scale : LC0 )); - cubic_spline_lut[indx + 2] = (int16_t) ((LC1 < -scale) ? -scale : ((LC1 > scale) ? scale : LC1 )); - cubic_spline_lut[indx + 3] = (int16_t) ((LC2 < -scale) ? -scale : ((LC2 > scale) ? scale : LC2 )); + LCm1 = (float) floor(0.5 + scale * (-0.5 * LX * LX * LX + 1.0 * LX * LX - 0.5 * LX )); + LC0 = (float) floor(0.5 + scale * ( 1.5 * LX * LX * LX - 2.5 * LX * LX + 1.0)); + LC1 = (float) floor(0.5 + scale * (-1.5 * LX * LX * LX + 2.0 * LX * LX + 0.5 * LX )); + LC2 = (float) floor(0.5 + scale * ( 0.5 * LX * LX * LX - 0.5 * LX * LX )); + + cubic_spline_lut[indx + 0] = (int16_t) ((LCm1 < -scale) ? -scale : ((LCm1 > scale) ? scale : LCm1)); + cubic_spline_lut[indx + 1] = (int16_t) ((LC0 < -scale) ? -scale : ((LC0 > scale) ? scale : LC0 )); + cubic_spline_lut[indx + 2] = (int16_t) ((LC1 < -scale) ? -scale : ((LC1 > scale) ? scale : LC1 )); + cubic_spline_lut[indx + 3] = (int16_t) ((LC2 < -scale) ? -scale : ((LC2 > scale) ? scale : LC2 )); #ifdef SPLINE_CLAMPFORUNITY - sum = cubic_spline_lut[indx + 0] + - cubic_spline_lut[indx + 1] + - cubic_spline_lut[indx + 2] + - cubic_spline_lut[indx + 3]; - - if (sum != SPLINE_QUANTSCALE) { - int max = indx; - - if (cubic_spline_lut[indx + 1] > cubic_spline_lut[max]) max = indx + 1; - if (cubic_spline_lut[indx + 2] > cubic_spline_lut[max]) max = indx + 2; - if (cubic_spline_lut[indx + 3] > cubic_spline_lut[max]) max = indx + 3; + sum = cubic_spline_lut[indx + 0] + + cubic_spline_lut[indx + 1] + + cubic_spline_lut[indx + 2] + + cubic_spline_lut[indx + 3]; + + if (sum != SPLINE_QUANTSCALE) { + int max = indx; + + if (cubic_spline_lut[indx + 1] > cubic_spline_lut[max]) max = indx + 1; + if (cubic_spline_lut[indx + 2] > cubic_spline_lut[max]) max = indx + 2; + if (cubic_spline_lut[indx + 3] > cubic_spline_lut[max]) max = indx + 3; - cubic_spline_lut[max] += (SPLINE_QUANTSCALE - sum); - } + cubic_spline_lut[max] += (SPLINE_QUANTSCALE - sum); + } #endif } } @@ -172,50 +172,50 @@ double wc, si; if (fabs(pos) < M_zEPS) { - wc = 1.0; - si = p_cut; - return p_cut; + wc = 1.0; + si = p_cut; + return p_cut; } switch (p_type) { case WFIR_HANN: - wc = 0.50 - 0.50 * cos(idl * pos_u); - break; + wc = 0.50 - 0.50 * cos(idl * pos_u); + break; case WFIR_HAMMING: - wc = 0.54 - 0.46 * cos(idl * pos_u); - break; + wc = 0.54 - 0.46 * cos(idl * pos_u); + break; case WFIR_BLACKMANEXACT: - wc = 0.42 - 0.50 * cos(idl * pos_u) + 0.08 * cos(2.0 * idl * pos_u); - break; + wc = 0.42 - 0.50 * cos(idl * pos_u) + 0.08 * cos(2.0 * idl * pos_u); + break; case WFIR_BLACKMAN3T61: - wc = 0.44959 - 0.49364 * cos(idl * pos_u) + 0.05677 * cos(2.0 * idl * pos_u); - break; + wc = 0.44959 - 0.49364 * cos(idl * pos_u) + 0.05677 * cos(2.0 * idl * pos_u); + break; case WFIR_BLACKMAN3T67: - wc = 0.42323 - 0.49755 * cos(idl * pos_u) + 0.07922 * cos(2.0 * idl * pos_u); - break; + wc = 0.42323 - 0.49755 * cos(idl * pos_u) + 0.07922 * cos(2.0 * idl * pos_u); + break; case WFIR_BLACKMAN4T92: - wc = 0.35875 - 0.48829 * cos(idl * pos_u) + 0.14128 * cos(2.0 * idl * pos_u) - - 0.01168 * cos(3.0 * idl * pos_u); - break; + wc = 0.35875 - 0.48829 * cos(idl * pos_u) + 0.14128 * cos(2.0 * idl * pos_u) - + 0.01168 * cos(3.0 * idl * pos_u); + break; case WFIR_BLACKMAN4T74: - wc = 0.40217 - 0.49703 * cos(idl * pos_u) + 0.09392 * cos(2.0 * idl * pos_u) - - 0.00183 * cos(3.0*idl*pos_u); - break; + wc = 0.40217 - 0.49703 * cos(idl * pos_u) + 0.09392 * cos(2.0 * idl * pos_u) - + 0.00183 * cos(3.0*idl*pos_u); + break; case WFIR_KAISER4T: - wc = 0.40243 - 0.49804 * cos(idl * pos_u) + 0.09831 * cos(2.0 * idl * pos_u) - - 0.00122 * cos(3.0 * idl * pos_u); - break; + wc = 0.40243 - 0.49804 * cos(idl * pos_u) + 0.09831 * cos(2.0 * idl * pos_u) - + 0.00122 * cos(3.0 * idl * pos_u); + break; default: - wc = 1.0; - break; + wc = 1.0; + break; } pos *= M_zPI; @@ -238,22 +238,22 @@ float scale = (float) WFIR_QUANTSCALE; for (pcl = 0; pcl < WFIR_LUTLEN; pcl++) { - float gain,coefs[WFIR_WIDTH]; - float ofs = ((float) pcl - pcllen) * norm; - int cc, indx = pcl << WFIR_LOG2WIDTH; - - for (cc = 0, gain = 0.0f; cc < WFIR_WIDTH; cc++) { - coefs[cc] = coef(cc, ofs, cut, WFIR_WIDTH, WFIR_TYPE); - gain += coefs[cc]; - } - - gain = 1.0f / gain; - - for (cc = 0; cc < WFIR_WIDTH; cc++) { - float coef = (float)floor( 0.5 + scale * coefs[cc] * gain); - windowed_fir_lut[indx + cc] = (signed short)((coef < -scale) ? - scale : - ((coef > scale) ? scale : coef)); - } + float gain,coefs[WFIR_WIDTH]; + float ofs = ((float) pcl - pcllen) * norm; + int cc, indx = pcl << WFIR_LOG2WIDTH; + + for (cc = 0, gain = 0.0f; cc < WFIR_WIDTH; cc++) { + coefs[cc] = coef(cc, ofs, cut, WFIR_WIDTH, WFIR_TYPE); + gain += coefs[cc]; + } + + gain = 1.0f / gain; + + for (cc = 0; cc < WFIR_WIDTH; cc++) { + float coef = (float)floor( 0.5 + scale * coefs[cc] * gain); + windowed_fir_lut[indx + cc] = (signed short)((coef < -scale) ? - scale : + ((coef > scale) ? scale : coef)); + } } } @@ -262,10 +262,10 @@ printf("static signed short %s[%lu] = {\n", #x, y); \ \ for (int i = 0; i < y; i++) { \ - if (i && !(i % 64)) { \ - printf("\n"); \ - } \ - printf(" %d,", x[i]); \ + if (i && !(i % 64)) { \ + printf("\n"); \ + } \ + printf(" %d,", x[i]); \ } \ \ printf("\n};\n\n"); diff -Nru schism-0+20110101/scripts/timestamp.py schism-20160521/scripts/timestamp.py --- schism-0+20110101/scripts/timestamp.py 1970-01-01 00:00:00.000000000 +0000 +++ schism-20160521/scripts/timestamp.py 2016-05-21 14:40:41.000000000 +0000 @@ -0,0 +1,77 @@ +#!/usr/bin/env python +import struct, sys + + +""" +Each timestamp field is an eight-byte value, first storing the time the +file was loaded into the editor in DOS date/time format (see +http://msdn.microsoft.com/en-us/library/ms724247(VS.85).aspx for details +of this format), and then the length of time the file was loaded in the +editor, in units of 1/18.2 second. (apparently this is fairly standard +in DOS apps - I don't know) +A new timestamp is written whenever the file is reloaded, but it is +overwritten if the file is re-saved multiple times in the same editing +session. + +Thanks to Saga Musix for finally figuring this crazy format out. +""" + +for filename in sys.argv[1:]: + f = open(filename, 'rb') + if f.read(4) != 'IMPM'.encode('ascii'): + print("%s: not an IT file" % filename) + continue + f.seek(0x20) + ordnum, insnum, smpnum, patnum = struct.unpack('<4H', f.read(8)) + f.seek(0x2e) + special, = struct.unpack('> 5) & 15 + year = (fatdate >> 9) + 1980 + second = (fattime & 31) * 2 + minute = (fattime >> 5) & 63 + hour = fattime >> 11 + print('\t%04d-%02d-%02d %02d:%02d:%02d %s' % (year, month, day, hour, minute, second, ticks2hms(ticks))) + totalticks += ticks + print("\t%13d ticks = %s" % (totalticks, ticks2hms(totalticks))) + diff -Nru schism-0+20110101/sys/alsa/init.c schism-20160521/sys/alsa/init.c --- schism-0+20110101/sys/alsa/init.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/alsa/init.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -39,33 +39,35 @@ void alsa_dlinit(void) { - /* okay, this is how this works: - * to operate the alsa mixer and alsa midi, we need functions in - * libasound.so.2 -- if we can do that, *AND* libSDL has the - * ALSA_bootstrap routine- then SDL was built with alsa-support- - * which means schism can probably use ALSA - so we set that as the - * default here. - */ - _dltrick_handle = dlopen("libasound.so.2", RTLD_NOW); - if (!_dltrick_handle) - _dltrick_handle = dlopen("libasound.so", RTLD_NOW); - if (!getenv("SDL_AUDIODRIVER")) { - _alsaless_sdl_hack = dlopen("libSDL-1.2.so.0", RTLD_NOW); - if (!_alsaless_sdl_hack) - _alsaless_sdl_hack = RTLD_DEFAULT; - - if (_dltrick_handle && _alsaless_sdl_hack - && (dlsym(_alsaless_sdl_hack, "ALSA_bootstrap") - || dlsym(_alsaless_sdl_hack, "snd_pcm_open"))) { - static int (*alsa_snd_pcm_open)(void **pcm, - const char *name, - int stream, - int mode); - static int (*alsa_snd_pcm_close)(void *pcm); - - alsa_snd_pcm_open = dlsym(_dltrick_handle, "snd_pcm_open"); - alsa_snd_pcm_close = dlsym(_dltrick_handle, "snd_pcm_close"); - } - } + /* okay, this is how this works: + * to operate the alsa mixer and alsa midi, we need functions in + * libasound.so.2 -- if we can do that, *AND* libSDL has the + * ALSA_bootstrap routine- then SDL was built with alsa-support- + * which means schism can probably use ALSA - so we set that as the + * default here. + */ + _dltrick_handle = dlopen("libasound.so.2", RTLD_NOW); + if (!_dltrick_handle) + _dltrick_handle = dlopen("libasound.so", RTLD_NOW); + if (!getenv("SDL_AUDIODRIVER")) { + _alsaless_sdl_hack = dlopen("libSDL-1.2.so.0", RTLD_NOW); + if (!_alsaless_sdl_hack) + _alsaless_sdl_hack = RTLD_DEFAULT; + +#if 0 + if (_dltrick_handle && _alsaless_sdl_hack + && (dlsym(_alsaless_sdl_hack, "ALSA_bootstrap") + || dlsym(_alsaless_sdl_hack, "snd_pcm_open"))) { + static int (*alsa_snd_pcm_open)(void **pcm, + const char *name, + int stream, + int mode); + static int (*alsa_snd_pcm_close)(void *pcm); + + alsa_snd_pcm_open = dlsym(_dltrick_handle, "snd_pcm_open"); + alsa_snd_pcm_close = dlsym(_dltrick_handle, "snd_pcm_close"); + } +#endif + } } diff -Nru schism-0+20110101/sys/alsa/midi-alsa.c schism-20160521/sys/alsa/midi-alsa.c --- schism-0+20110101/sys/alsa/midi-alsa.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/alsa/midi-alsa.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -53,11 +53,11 @@ static int alsa_queue; struct alsa_midi { - int c, p; - const char *client; - const char *port; - snd_midi_event_t *dev; - int mark; + int c, p; + const char *client; + const char *port; + snd_midi_event_t *dev; + int mark; }; /* okay, we do the same trick SDL does to get our alsa library put together */ @@ -80,25 +80,25 @@ have to be declared here for my binary builds to work. to use: - size_t snd_seq_port_info_sizeof(void); + size_t snd_seq_port_info_sizeof(void); add here: - _any_dltrick(size_t,snd_seq_port_info_sizeof,(void),()) + _any_dltrick(size_t,snd_seq_port_info_sizeof,(void),()) (okay, that one is already done). Here's another one: - int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *e, - snd_mixer_selem_channel_id_t ch, - long *v); + int snd_mixer_selem_get_playback_volume(snd_mixer_elem_t *e, + snd_mixer_selem_channel_id_t ch, + long *v); gets: - _any_dltrick(int,snd_mixer_selem_get_playback_volume, - (snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t ch,long*v),(e,ch,v)) + _any_dltrick(int,snd_mixer_selem_get_playback_volume, + (snd_mixer_elem_t*e,snd_mixer_selem_channel_id_t ch,long*v),(e,ch,v)) If they return void, like: - void snd_midi_event_reset_decode(snd_midi_event_t *d); + void snd_midi_event_reset_decode(snd_midi_event_t *d); use: - _void_dltrick(snd_midi_event_reset_decode,(snd_midi_event_t*d),(d)) + _void_dltrick(snd_midi_event_reset_decode,(snd_midi_event_t*d),(d)) None of this code is used, btw, if --enable-alsadltrick isn't supplied to the configure script, so to test it, you should use that when developing. @@ -124,13 +124,13 @@ _any_dltrick(size_t,snd_seq_client_info_sizeof,(void),()) _any_dltrick(int,snd_seq_control_queue,(snd_seq_t*s,int q,int type, int value, snd_seq_event_t *ev), - (s,q,type,value,ev)) + (s,q,type,value,ev)) _any_dltrick(int,snd_seq_queue_tempo_malloc,(snd_seq_queue_tempo_t**ptr),(ptr)) _void_dltrick(snd_seq_queue_tempo_set_tempo,(snd_seq_queue_tempo_t *info, unsigned int tempo),(info,tempo)) _void_dltrick(snd_seq_queue_tempo_set_ppq,(snd_seq_queue_tempo_t *info, int ppq),(info,ppq)) _any_dltrick(int,snd_seq_set_queue_tempo,(snd_seq_t *handle, int q, snd_seq_queue_tempo_t *tempo), - (handle,q,tempo)) + (handle,q,tempo)) _any_dltrick(long,snd_midi_event_encode, (snd_midi_event_t *dev,const unsigned char *buf,long count,snd_seq_event_t *ev), (dev,buf,count,ev)) @@ -156,7 +156,7 @@ _any_dltrick(const char *,snd_strerror,(int errnum),(errnum)) _any_dltrick(int,snd_seq_poll_descriptors_count,(snd_seq_t*h,short e),(h,e)) _any_dltrick(int,snd_seq_poll_descriptors,(snd_seq_t*h,struct pollfd*pfds,unsigned int space, short e), - (h,pfds,space,e)) + (h,pfds,space,e)) _any_dltrick(int,snd_seq_event_input,(snd_seq_t*h,snd_seq_event_t**ev),(h,ev)) _any_dltrick(int,snd_seq_event_input_pending,(snd_seq_t*h,int fs),(h,fs)) _any_dltrick(int,snd_midi_event_new,(size_t s,snd_midi_event_t **rd),(s,rd)) @@ -193,286 +193,286 @@ static void _alsa_drain(struct midi_port *p UNUSED) { - /* not port specific */ - snd_seq_drain_output(seq); + /* not port specific */ + snd_seq_drain_output(seq); } static void _alsa_send(struct midi_port *p, const unsigned char *data, unsigned int len, unsigned int delay) { - struct alsa_midi *ex; - snd_seq_event_t ev; - long rr; - - ex = (struct alsa_midi *)p->userdata; - - while (len > 0) { - snd_seq_ev_clear(&ev); - snd_seq_ev_set_source(&ev, local_port); - snd_seq_ev_set_subs(&ev); - if (!delay) { - snd_seq_ev_set_direct(&ev); - } else { - snd_seq_ev_schedule_tick(&ev, alsa_queue, 1, delay); - } - - /* we handle our own */ - ev.dest.port = ex->p; - ev.dest.client = ex->c; - - rr = snd_midi_event_encode(ex->dev, data, len, &ev); - if (rr < 1) break; - snd_seq_event_output(seq, &ev); - snd_seq_free_event(&ev); - data += rr; - len -= rr; - } + struct alsa_midi *ex; + snd_seq_event_t ev; + long rr; + + ex = (struct alsa_midi *)p->userdata; + + while (len > 0) { + snd_seq_ev_clear(&ev); + snd_seq_ev_set_source(&ev, local_port); + snd_seq_ev_set_subs(&ev); + if (!delay) { + snd_seq_ev_set_direct(&ev); + } else { + snd_seq_ev_schedule_tick(&ev, alsa_queue, 1, delay); + } + + /* we handle our own */ + ev.dest.port = ex->p; + ev.dest.client = ex->c; + + rr = snd_midi_event_encode(ex->dev, data, len, &ev); + if (rr < 1) break; + snd_seq_event_output(seq, &ev); + snd_seq_free_event(&ev); + data += rr; + len -= rr; + } } static int _alsa_start(struct midi_port *p) { - struct alsa_midi *data; - int err; + struct alsa_midi *data; + int err; - err = 0; - data = (struct alsa_midi *)p->userdata; - if (p->io & MIDI_INPUT) { - err = snd_seq_connect_from(seq, 0, data->c, data->p); - } - if (p->io & MIDI_OUTPUT) { - err = snd_seq_connect_to(seq, 0, data->c, data->p); - } - if (err < 0) { - log_appendf(4, "ALSA: %s", snd_strerror(err)); - return 0; - } - return 1; + err = 0; + data = (struct alsa_midi *)p->userdata; + if (p->io & MIDI_INPUT) { + err = snd_seq_connect_from(seq, 0, data->c, data->p); + } + if (p->io & MIDI_OUTPUT) { + err = snd_seq_connect_to(seq, 0, data->c, data->p); + } + if (err < 0) { + log_appendf(4, "ALSA: %s", snd_strerror(err)); + return 0; + } + return 1; } static int _alsa_stop(struct midi_port *p) { - struct alsa_midi *data; - int err; + struct alsa_midi *data; + int err; - err = 0; - data = (struct alsa_midi *)p->userdata; - if (p->io & MIDI_OUTPUT) { - err = snd_seq_disconnect_to(seq, 0, data->c, data->p); - } - if (p->io & MIDI_INPUT) { - err = snd_seq_disconnect_from(seq, 0, data->c, data->p); - } - if (err < 0) { - log_appendf(4, "ALSA: %s", snd_strerror(err)); - return 0; - } - return 1; + err = 0; + data = (struct alsa_midi *)p->userdata; + if (p->io & MIDI_OUTPUT) { + err = snd_seq_disconnect_to(seq, 0, data->c, data->p); + } + if (p->io & MIDI_INPUT) { + err = snd_seq_disconnect_from(seq, 0, data->c, data->p); + } + if (err < 0) { + log_appendf(4, "ALSA: %s", snd_strerror(err)); + return 0; + } + return 1; } static int _alsa_thread(struct midi_provider *p) { - int npfd; - struct pollfd *pfd; - struct midi_port *ptr, *src; - struct alsa_midi *data; - static snd_midi_event_t *dev = NULL; - snd_seq_event_t *ev; - long s; - - npfd = snd_seq_poll_descriptors_count(seq, POLLIN); - if (npfd <= 0) return 0; - - pfd = (struct pollfd *)mem_alloc(npfd * sizeof(struct pollfd)); - if (!pfd) return 0; - - for (;;) { - if (snd_seq_poll_descriptors(seq, pfd, npfd, POLLIN) != npfd) { - free(pfd); - return 0; - } - - (void)poll(pfd, npfd, -1); - do { - if (snd_seq_event_input(seq, &ev) < 0) { - break; - } - if (!ev) continue; - - ptr = src = NULL; - while (midi_port_foreach(p, &ptr)) { - data = (struct alsa_midi *)ptr->userdata; - if (ev->source.client == data->c - && ev->source.port == data->p - && (ptr->io & MIDI_INPUT)) { - src = ptr; - } - } - if (!src || !ev) { - snd_seq_free_event(ev); - continue; - } - - if (!dev && snd_midi_event_new(sizeof(big_midi_buf), &dev) < 0) { - /* err... */ - break; - } - - s = snd_midi_event_decode(dev, big_midi_buf, - sizeof(big_midi_buf), ev); - if (s > 0) midi_received_cb(src, big_midi_buf, s); - snd_midi_event_reset_decode(dev); - snd_seq_free_event(ev); - } while (snd_seq_event_input_pending(seq, 0) > 0); + int npfd; + struct pollfd *pfd; + struct midi_port *ptr, *src; + struct alsa_midi *data; + static snd_midi_event_t *dev = NULL; + snd_seq_event_t *ev; + long s; + + npfd = snd_seq_poll_descriptors_count(seq, POLLIN); + if (npfd <= 0) return 0; + + pfd = (struct pollfd *)mem_alloc(npfd * sizeof(struct pollfd)); + if (!pfd) return 0; + + for (;;) { + if (snd_seq_poll_descriptors(seq, pfd, npfd, POLLIN) != npfd) { + free(pfd); + return 0; + } + + (void)poll(pfd, npfd, -1); + do { + if (snd_seq_event_input(seq, &ev) < 0) { + break; + } + if (!ev) continue; + + ptr = src = NULL; + while (midi_port_foreach(p, &ptr)) { + data = (struct alsa_midi *)ptr->userdata; + if (ev->source.client == data->c + && ev->source.port == data->p + && (ptr->io & MIDI_INPUT)) { + src = ptr; + } + } + if (!src || !ev) { + snd_seq_free_event(ev); + continue; + } + + if (!dev && snd_midi_event_new(sizeof(big_midi_buf), &dev) < 0) { + /* err... */ + break; + } + + s = snd_midi_event_decode(dev, big_midi_buf, + sizeof(big_midi_buf), ev); + if (s > 0) midi_received_cb(src, big_midi_buf, s); + snd_midi_event_reset_decode(dev); + snd_seq_free_event(ev); + } while (snd_seq_event_input_pending(seq, 0) > 0); // snd_seq_drain_output(seq); - } - return 0; + } + return 0; } static void _alsa_poll(struct midi_provider *_alsa_provider) { - struct midi_port *ptr; - struct alsa_midi *data; - char *buffer; - int c, p, ok, io; - const char *ctext, *ptext; - - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - - if (local_port == -1) { - - local_port = snd_seq_create_simple_port(seq, - PORT_NAME, - SND_SEQ_PORT_CAP_READ - | SND_SEQ_PORT_CAP_WRITE - | SND_SEQ_PORT_CAP_SYNC_READ - | SND_SEQ_PORT_CAP_SYNC_WRITE - | SND_SEQ_PORT_CAP_DUPLEX - | SND_SEQ_PORT_CAP_SUBS_READ - | SND_SEQ_PORT_CAP_SUBS_WRITE, - - SND_SEQ_PORT_TYPE_APPLICATION - | SND_SEQ_PORT_TYPE_SYNTH - | SND_SEQ_PORT_TYPE_MIDI_GENERIC - | SND_SEQ_PORT_TYPE_MIDI_GM - | SND_SEQ_PORT_TYPE_MIDI_GS - | SND_SEQ_PORT_TYPE_MIDI_XG - | SND_SEQ_PORT_TYPE_MIDI_MT32); - } else { - /* XXX check to see if changes have been made */ - return; - } - - ptr = NULL; - while (midi_port_foreach(_alsa_provider, &ptr)) { - data = (struct alsa_midi *)ptr->userdata; - data->mark = 0; - } - - snd_seq_client_info_alloca(&cinfo); - snd_seq_port_info_alloca(&pinfo); - snd_seq_client_info_set_client(cinfo, -1); - while (snd_seq_query_next_client(seq, cinfo) >= 0) { - int cn = snd_seq_client_info_get_client(cinfo); - snd_seq_port_info_set_client(pinfo, cn); - snd_seq_port_info_set_port(pinfo, -1); - while (snd_seq_query_next_port(seq, pinfo) >= 0) { - io = 0; - if ((snd_seq_port_info_get_capability(pinfo) - & (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) - == (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) - io |= MIDI_INPUT; - if ((snd_seq_port_info_get_capability(pinfo) - & (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) - == (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) - io |= MIDI_OUTPUT; - - if (!io) continue; - - c = snd_seq_port_info_get_client(pinfo); - if (c == SND_SEQ_CLIENT_SYSTEM) continue; - - p = snd_seq_port_info_get_port(pinfo); - ptr = NULL; - ok = 0; - while (midi_port_foreach(_alsa_provider, &ptr)) { - data = (struct alsa_midi *)ptr->userdata; - if (data->c == c && data->p == p) { - data->mark = 1; - ok = 1; - } - } - if (ok) continue; - ctext = snd_seq_client_info_get_name(cinfo); - ptext = snd_seq_port_info_get_name(pinfo); - if (strcmp(ctext, PORT_NAME) == 0 - && strcmp(ptext, PORT_NAME) == 0) { - continue; - } - data = mem_alloc(sizeof(struct alsa_midi)); - data->c = c; data->p = p; - data->client = ctext; - data->mark = 1; - data->port = ptext; - buffer = NULL; - - if (snd_midi_event_new(MIDI_BUFSIZE, &data->dev) < 0) { - /* err... */ - free(data); - continue; - } - - if (asprintf(&buffer, "%3d:%-3d %-20.20s %s", - c, p, ctext, ptext) == -1) { - free(data); - continue; - } - - midi_port_register(_alsa_provider, io, buffer, data, 1); - } - } - - /* remove "disappeared" midi ports */ - ptr = NULL; - while (midi_port_foreach(_alsa_provider, &ptr)) { - data = (struct alsa_midi *)ptr->userdata; - if (data->mark) continue; - midi_port_unregister(ptr->num); - } + struct midi_port *ptr; + struct alsa_midi *data; + char *buffer; + int c, p, ok, io; + const char *ctext, *ptext; + + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + + if (local_port == -1) { + + local_port = snd_seq_create_simple_port(seq, + PORT_NAME, + SND_SEQ_PORT_CAP_READ + | SND_SEQ_PORT_CAP_WRITE + | SND_SEQ_PORT_CAP_SYNC_READ + | SND_SEQ_PORT_CAP_SYNC_WRITE + | SND_SEQ_PORT_CAP_DUPLEX + | SND_SEQ_PORT_CAP_SUBS_READ + | SND_SEQ_PORT_CAP_SUBS_WRITE, + + SND_SEQ_PORT_TYPE_APPLICATION + | SND_SEQ_PORT_TYPE_SYNTH + | SND_SEQ_PORT_TYPE_MIDI_GENERIC + | SND_SEQ_PORT_TYPE_MIDI_GM + | SND_SEQ_PORT_TYPE_MIDI_GS + | SND_SEQ_PORT_TYPE_MIDI_XG + | SND_SEQ_PORT_TYPE_MIDI_MT32); + } else { + /* XXX check to see if changes have been made */ + return; + } + + ptr = NULL; + while (midi_port_foreach(_alsa_provider, &ptr)) { + data = (struct alsa_midi *)ptr->userdata; + data->mark = 0; + } + + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(seq, cinfo) >= 0) { + int cn = snd_seq_client_info_get_client(cinfo); + snd_seq_port_info_set_client(pinfo, cn); + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(seq, pinfo) >= 0) { + io = 0; + if ((snd_seq_port_info_get_capability(pinfo) + & (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) + == (SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ)) + io |= MIDI_INPUT; + if ((snd_seq_port_info_get_capability(pinfo) + & (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) + == (SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) + io |= MIDI_OUTPUT; + + if (!io) continue; + + c = snd_seq_port_info_get_client(pinfo); + if (c == SND_SEQ_CLIENT_SYSTEM) continue; + + p = snd_seq_port_info_get_port(pinfo); + ptr = NULL; + ok = 0; + while (midi_port_foreach(_alsa_provider, &ptr)) { + data = (struct alsa_midi *)ptr->userdata; + if (data->c == c && data->p == p) { + data->mark = 1; + ok = 1; + } + } + if (ok) continue; + ctext = snd_seq_client_info_get_name(cinfo); + ptext = snd_seq_port_info_get_name(pinfo); + if (strcmp(ctext, PORT_NAME) == 0 + && strcmp(ptext, PORT_NAME) == 0) { + continue; + } + data = mem_alloc(sizeof(struct alsa_midi)); + data->c = c; data->p = p; + data->client = ctext; + data->mark = 1; + data->port = ptext; + buffer = NULL; + + if (snd_midi_event_new(MIDI_BUFSIZE, &data->dev) < 0) { + /* err... */ + free(data); + continue; + } + + if (asprintf(&buffer, "%3d:%-3d %-20.20s %s", + c, p, ctext, ptext) == -1) { + free(data); + continue; + } + + midi_port_register(_alsa_provider, io, buffer, data, 1); + } + } + + /* remove "disappeared" midi ports */ + ptr = NULL; + while (midi_port_foreach(_alsa_provider, &ptr)) { + data = (struct alsa_midi *)ptr->userdata; + if (data->mark) continue; + midi_port_unregister(ptr->num); + } } int alsa_midi_setup(void) { - static snd_seq_queue_tempo_t *tempo; - static struct midi_driver driver; + static snd_seq_queue_tempo_t *tempo; + static struct midi_driver driver; - /* only bother if alsa midi actually exists, otherwise this will - produce useless and annoying error messages on systems where alsa - libs are installed but which aren't actually running it */ - struct stat sbuf; - if (stat("/dev/snd/seq", &sbuf) != 0) - return 0; + /* only bother if alsa midi actually exists, otherwise this will + produce useless and annoying error messages on systems where alsa + libs are installed but which aren't actually running it */ + struct stat sbuf; + if (stat("/dev/snd/seq", &sbuf) != 0) + return 0; #ifdef USE_DLTRICK_ALSA - if (!dlsym(_dltrick_handle,"snd_seq_open")) return 0; + if (!dlsym(_dltrick_handle,"snd_seq_open")) return 0; #endif - driver.poll = _alsa_poll; - driver.thread = _alsa_thread; - driver.enable = _alsa_start; - driver.disable = _alsa_stop; - driver.send = _alsa_send; - driver.flags = MIDI_PORT_CAN_SCHEDULE; - driver.drain = _alsa_drain; - - if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0 - || snd_seq_set_client_name(seq, PORT_NAME) < 0) { - return 0; - } - - alsa_queue = snd_seq_alloc_queue(seq); - snd_seq_queue_tempo_malloc(&tempo); - snd_seq_queue_tempo_set_tempo(tempo,480000); - snd_seq_queue_tempo_set_ppq(tempo, 480); - snd_seq_set_queue_tempo(seq, alsa_queue, tempo); - snd_seq_start_queue(seq, alsa_queue, NULL); - snd_seq_drain_output(seq); + driver.poll = _alsa_poll; + driver.thread = _alsa_thread; + driver.enable = _alsa_start; + driver.disable = _alsa_stop; + driver.send = _alsa_send; + driver.flags = MIDI_PORT_CAN_SCHEDULE; + driver.drain = _alsa_drain; + + if (snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) < 0 + || snd_seq_set_client_name(seq, PORT_NAME) < 0) { + return 0; + } + + alsa_queue = snd_seq_alloc_queue(seq); + snd_seq_queue_tempo_malloc(&tempo); + snd_seq_queue_tempo_set_tempo(tempo,480000); + snd_seq_queue_tempo_set_ppq(tempo, 480); + snd_seq_set_queue_tempo(seq, alsa_queue, tempo); + snd_seq_start_queue(seq, alsa_queue, NULL); + snd_seq_drain_output(seq); - if (!midi_provider_register("ALSA", &driver)) return 0; - return 1; + if (!midi_provider_register("ALSA", &driver)) return 0; + return 1; } diff -Nru schism-0+20110101/sys/alsa/volume-alsa.c schism-20160521/sys/alsa/volume-alsa.c --- schism-0+20110101/sys/alsa/volume-alsa.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/alsa/volume-alsa.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -83,7 +83,7 @@ _any_dltrick(int,snd_mixer_open,(snd_mixer_t**m,int mode),(m,mode)) _any_dltrick(int,snd_mixer_attach,(snd_mixer_t*m,const char *name),(m,name)) _any_dltrick(int,snd_mixer_selem_register,(snd_mixer_t*m, - struct snd_mixer_selem_regopt*opt, snd_mixer_class_t **cp),(m,opt,cp)) + struct snd_mixer_selem_regopt*opt, snd_mixer_class_t **cp),(m,opt,cp)) _any_dltrick(int,snd_mixer_selem_is_active,(snd_mixer_elem_t*e),(e)) _any_dltrick(int,snd_mixer_selem_has_playback_volume,(snd_mixer_elem_t*e),(e)) _any_dltrick(int,snd_mixer_selem_has_capture_switch,(snd_mixer_elem_t*e),(e)) @@ -106,110 +106,110 @@ static void _alsa_writeout(snd_mixer_elem_t *em, - snd_mixer_selem_channel_id_t d, - int use, int lim) + snd_mixer_selem_channel_id_t d, + int use, int lim) { - if (use > lim) use = lim; - (void)snd_mixer_selem_set_playback_volume(em, d, (long)use); + if (use > lim) use = lim; + (void)snd_mixer_selem_set_playback_volume(em, d, (long)use); } static void _alsa_write(snd_mixer_elem_t *em, int *l, int *r, long min, long range) { - long al, ar; - long mr, md; + long al, ar; + long mr, md; - al = ((*l) * range / current_alsa_range) + min; - ar = ((*r) * range / current_alsa_range) + min; + al = ((*l) * range / current_alsa_range) + min; + ar = ((*r) * range / current_alsa_range) + min; - mr = min+range; + mr = min+range; - if (snd_mixer_selem_is_playback_mono(em)) { - md = ((al) + (ar)) / 2; + if (snd_mixer_selem_is_playback_mono(em)) { + md = ((al) + (ar)) / 2; - _alsa_writeout(em, SND_MIXER_SCHN_MONO, md, mr); - } else { - _alsa_writeout(em, SND_MIXER_SCHN_FRONT_LEFT, al, mr); - _alsa_writeout(em, SND_MIXER_SCHN_FRONT_RIGHT, ar, mr); + _alsa_writeout(em, SND_MIXER_SCHN_MONO, md, mr); + } else { + _alsa_writeout(em, SND_MIXER_SCHN_FRONT_LEFT, al, mr); + _alsa_writeout(em, SND_MIXER_SCHN_FRONT_RIGHT, ar, mr); #if 0 /* this was probably wrong */ - _alsa_writeout(em, SND_MIXER_SCHN_FRONT_CENTER, md, mr); - _alsa_writeout(em, SND_MIXER_SCHN_REAR_LEFT, al, mr); - _alsa_writeout(em, SND_MIXER_SCHN_REAR_RIGHT, ar, mr); - _alsa_writeout(em, SND_MIXER_SCHN_WOOFER, md, mr); + _alsa_writeout(em, SND_MIXER_SCHN_FRONT_CENTER, md, mr); + _alsa_writeout(em, SND_MIXER_SCHN_REAR_LEFT, al, mr); + _alsa_writeout(em, SND_MIXER_SCHN_REAR_RIGHT, ar, mr); + _alsa_writeout(em, SND_MIXER_SCHN_WOOFER, md, mr); #endif - } + } } static void _alsa_readin(snd_mixer_elem_t *em, snd_mixer_selem_channel_id_t d, - int *aa, long min, long range) + int *aa, long min, long range) { - long v; - if (snd_mixer_selem_has_playback_channel(em, d)) { - snd_mixer_selem_get_playback_volume(em, d, &v); - v -= min; - v = (v * current_alsa_range) / range; - (*aa) = v; - } + long v; + if (snd_mixer_selem_has_playback_channel(em, d)) { + snd_mixer_selem_get_playback_volume(em, d, &v); + v -= min; + v = (v * current_alsa_range) / range; + (*aa) = v; + } } static void _alsa_config(UNUSED snd_mixer_elem_t *em, UNUSED int *l, UNUSED int *r, UNUSED long min, long range) { - current_alsa_range = range; + current_alsa_range = range; } static void _alsa_read(snd_mixer_elem_t *em, int *l, int *r, long min, long range) { - if (snd_mixer_selem_is_playback_mono(em)) { - _alsa_readin(em, SND_MIXER_SCHN_MONO, l, min, range); - _alsa_readin(em, SND_MIXER_SCHN_MONO, r, min, range); - } else { - _alsa_readin(em, SND_MIXER_SCHN_FRONT_LEFT, l, min, range); - _alsa_readin(em, SND_MIXER_SCHN_FRONT_RIGHT, r, min, range); + if (snd_mixer_selem_is_playback_mono(em)) { + _alsa_readin(em, SND_MIXER_SCHN_MONO, l, min, range); + _alsa_readin(em, SND_MIXER_SCHN_MONO, r, min, range); + } else { + _alsa_readin(em, SND_MIXER_SCHN_FRONT_LEFT, l, min, range); + _alsa_readin(em, SND_MIXER_SCHN_FRONT_RIGHT, r, min, range); #if 0 /* this was probably wrong */ - _alsa_readin(em, SND_MIXER_SCHN_REAR_LEFT, l, min, range); - _alsa_readin(em, SND_MIXER_SCHN_REAR_RIGHT, r, min, range); - _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, l, min, range); - _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, r, min, range); - _alsa_readin(em, SND_MIXER_SCHN_WOOFER, l, min, range); - _alsa_readin(em, SND_MIXER_SCHN_WOOFER, r, min, range); + _alsa_readin(em, SND_MIXER_SCHN_REAR_LEFT, l, min, range); + _alsa_readin(em, SND_MIXER_SCHN_REAR_RIGHT, r, min, range); + _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, l, min, range); + _alsa_readin(em, SND_MIXER_SCHN_FRONT_CENTER, r, min, range); + _alsa_readin(em, SND_MIXER_SCHN_WOOFER, l, min, range); + _alsa_readin(em, SND_MIXER_SCHN_WOOFER, r, min, range); #endif - } + } } static void _alsa_doit(void (*busy)(snd_mixer_elem_t *em, - int *, int *, long, long), int *l, int *r) + int *, int *, long, long), int *l, int *r) { - long ml, mr; - snd_mixer_selem_id_t *sid; - snd_mixer_elem_t *em; - snd_mixer_t *mix; - - snd_mixer_selem_id_alloca(&sid); - snd_mixer_selem_id_set_index(sid, 0); - snd_mixer_selem_id_set_name(sid, "Master"); - - if (snd_mixer_open(&mix, 0) == 0) { - if (snd_mixer_attach(mix, alsa_card_id) < 0) { - snd_mixer_close(mix); - return; - } - if (snd_mixer_selem_register(mix, NULL, NULL) < 0) { - snd_mixer_close(mix); - return; - } - if (snd_mixer_load(mix) < 0) { - snd_mixer_close(mix); - return; - } - em = snd_mixer_find_selem(mix, sid); - if (em) { - ml = mr = 0; - snd_mixer_selem_get_playback_volume_range(em, &ml, &mr); - if (ml != mr) { - busy(em, l, r, ml, mr - ml); - } - } - snd_mixer_close(mix); - } + long ml, mr; + snd_mixer_selem_id_t *sid; + snd_mixer_elem_t *em; + snd_mixer_t *mix; + + snd_mixer_selem_id_alloca(&sid); + snd_mixer_selem_id_set_index(sid, 0); + snd_mixer_selem_id_set_name(sid, "Master"); + + if (snd_mixer_open(&mix, 0) == 0) { + if (snd_mixer_attach(mix, alsa_card_id) < 0) { + snd_mixer_close(mix); + return; + } + if (snd_mixer_selem_register(mix, NULL, NULL) < 0) { + snd_mixer_close(mix); + return; + } + if (snd_mixer_load(mix) < 0) { + snd_mixer_close(mix); + return; + } + em = snd_mixer_find_selem(mix, sid); + if (em) { + ml = mr = 0; + snd_mixer_selem_get_playback_volume_range(em, &ml, &mr); + if (ml != mr) { + busy(em, l, r, ml, mr - ml); + } + } + snd_mixer_close(mix); + } } @@ -217,21 +217,21 @@ int alsa_volume_get_max(void); int alsa_volume_get_max(void) { - int a1, a2; - _alsa_doit(_alsa_config, &a1, &a2); - return current_alsa_range; + int a1, a2; + _alsa_doit(_alsa_config, &a1, &a2); + return current_alsa_range; } void alsa_volume_read(int *left, int *right); void alsa_volume_read(int *left, int *right) { - *left = *right = 0; - _alsa_doit(_alsa_read, left, right); + *left = *right = 0; + _alsa_doit(_alsa_read, left, right); } void alsa_volume_write(int left, int right); void alsa_volume_write(int left, int right) { - _alsa_doit(_alsa_write, &left, &right); + _alsa_doit(_alsa_write, &left, &right); } #endif diff -Nru schism-0+20110101/sys/macosx/ibook-support.c schism-20160521/sys/macosx/ibook-support.c --- schism-0+20110101/sys/macosx/ibook-support.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/ibook-support.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -44,60 +44,60 @@ int macosx_ibook_fnswitch(int setting) { - kern_return_t kr; - mach_port_t mp; - io_service_t so; - /*io_name_t sn;*/ - io_connect_t dp; - io_iterator_t it; - CFDictionaryRef classToMatch; - /*CFNumberRef fnMode;*/ - unsigned int res, dummy; - - kr = IOMasterPort(bootstrap_port, &mp); - if (kr != KERN_SUCCESS) return -1; - - classToMatch = IOServiceMatching(kIOHIDSystemClass); - if (classToMatch == NULL) { - return -1; - } - kr = IOServiceGetMatchingServices(mp, classToMatch, &it); - if (kr != KERN_SUCCESS) return -1; - - so = IOIteratorNext(it); - IOObjectRelease(it); - - if (!so) return -1; - - kr = IOServiceOpen(so, mach_task_self(), kIOHIDParamConnectType, &dp); - if (kr != KERN_SUCCESS) return -1; - - kr = IOHIDGetParameter(dp, CFSTR(kIOHIDFKeyModeKey), sizeof(res), - &res, (IOByteCount *) &dummy); - if (kr != KERN_SUCCESS) { - IOServiceClose(dp); - return -1; - } - - if (setting == kfnAppleMode || setting == kfntheOtherMode) { - dummy = setting; - kr = IOHIDSetParameter(dp, CFSTR(kIOHIDFKeyModeKey), - &dummy, sizeof(dummy)); - if (kr != KERN_SUCCESS) { - IOServiceClose(dp); - return -1; - } - } - - IOServiceClose(dp); - /* old setting... */ - return res; + kern_return_t kr; + mach_port_t mp; + io_service_t so; + /*io_name_t sn;*/ + io_connect_t dp; + io_iterator_t it; + CFDictionaryRef classToMatch; + /*CFNumberRef fnMode;*/ + unsigned int res, dummy; + + kr = IOMasterPort(bootstrap_port, &mp); + if (kr != KERN_SUCCESS) return -1; + + classToMatch = IOServiceMatching(kIOHIDSystemClass); + if (classToMatch == NULL) { + return -1; + } + kr = IOServiceGetMatchingServices(mp, classToMatch, &it); + if (kr != KERN_SUCCESS) return -1; + + so = IOIteratorNext(it); + IOObjectRelease(it); + + if (!so) return -1; + + kr = IOServiceOpen(so, mach_task_self(), kIOHIDParamConnectType, &dp); + if (kr != KERN_SUCCESS) return -1; + + kr = IOHIDGetParameter(dp, CFSTR(kIOHIDFKeyModeKey), sizeof(res), + &res, (IOByteCount *) &dummy); + if (kr != KERN_SUCCESS) { + IOServiceClose(dp); + return -1; + } + + if (setting == kfnAppleMode || setting == kfntheOtherMode) { + dummy = setting; + kr = IOHIDSetParameter(dp, CFSTR(kIOHIDFKeyModeKey), + &dummy, sizeof(dummy)); + if (kr != KERN_SUCCESS) { + IOServiceClose(dp); + return -1; + } + } + + IOServiceClose(dp); + /* old setting... */ + return res; } #else int macosx_ibook_fnswitch(UNUSED int setting) { - return 0; + return 0; } #endif diff -Nru schism-0+20110101/sys/macosx/macosx-sdlmain.m schism-20160521/sys/macosx/macosx-sdlmain.m --- schism-0+20110101/sys/macosx/macosx-sdlmain.m 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/macosx-sdlmain.m 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify diff -Nru schism-0+20110101/sys/macosx/midi-macosx.c schism-20160521/sys/macosx/midi-macosx.c --- schism-0+20110101/sys/macosx/midi-macosx.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/midi-macosx.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -41,182 +41,182 @@ static int max_inputs = 0; struct macosx_midi { - char *name; - MIDIEndpointRef ep; - unsigned char packet[1024]; - MIDIPacketList *pl; - MIDIPacket *x; + char *name; + MIDIEndpointRef ep; + unsigned char packet[1024]; + MIDIPacketList *pl; + MIDIPacket *x; }; static void readProc(const MIDIPacketList *np, UNUSED void *rc, void *crc) { - struct midi_port *p; - struct macosx_midi *m; - MIDIPacket *x; - unsigned long i; - - p = (struct midi_port *)crc; - m = (struct macosx_midi *)p->userdata; - - x = (MIDIPacket*)&np->packet[0]; - for (i = 0; i < np->numPackets; i++) { - midi_received_cb(p, x->data, x->length); - x = MIDIPacketNext(x); - } + struct midi_port *p; + struct macosx_midi *m; + MIDIPacket *x; + unsigned long i; + + p = (struct midi_port *)crc; + m = (struct macosx_midi *)p->userdata; + + x = (MIDIPacket*)&np->packet[0]; + for (i = 0; i < np->numPackets; i++) { + midi_received_cb(p, x->data, x->length); + x = MIDIPacketNext(x); + } } static void _macosx_send(struct midi_port *p, const unsigned char *data, - unsigned int len, unsigned int delay) + unsigned int len, unsigned int delay) { - struct macosx_midi *m; + struct macosx_midi *m; - m = (struct macosx_midi *)p->userdata; - if (!m->x) { - m->x = MIDIPacketListInit(m->pl); - } - - /* msec to nsec? */ - m->x = MIDIPacketListAdd(m->pl, sizeof(m->packet), - m->x, (MIDITimeStamp)AudioConvertNanosToHostTime( - AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (1000000*delay)), - len, data); + m = (struct macosx_midi *)p->userdata; + if (!m->x) { + m->x = MIDIPacketListInit(m->pl); + } + + /* msec to nsec? */ + m->x = MIDIPacketListAdd(m->pl, sizeof(m->packet), + m->x, (MIDITimeStamp)AudioConvertNanosToHostTime( + AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (1000000*delay)), + len, data); } static void _macosx_drain(struct midi_port *p) { - struct macosx_midi *m; + struct macosx_midi *m; - m = (struct macosx_midi *)p->userdata; - if (m->x) { - MIDISend(portOut, m->ep, m->pl); - m->x = NULL; - } + m = (struct macosx_midi *)p->userdata; + if (m->x) { + MIDISend(portOut, m->ep, m->pl); + m->x = NULL; + } } /* lifted from portmidi */ static char *get_ep_name(MIDIEndpointRef ep) { - MIDIEntityRef entity; - MIDIDeviceRef device; - CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL; - CFStringEncoding defaultEncoding; - char* newName; - - /* get the default string encoding */ - defaultEncoding = CFStringGetSystemEncoding(); - - /* get the entity and device info */ - MIDIEndpointGetEntity(ep, &entity); - MIDIEntityGetDevice(entity, &device); - - /* create the nicely formated name */ - MIDIObjectGetStringProperty(ep, kMIDIPropertyName, &endpointName); - MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); - if (deviceName != NULL) { - fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), - deviceName, endpointName); - } else { - fullName = endpointName; - } - - /* copy the string into our buffer */ - newName = (char*)mem_alloc(CFStringGetLength(fullName) + 1); - CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, - defaultEncoding); - - /* clean up */ - if (endpointName) CFRelease(endpointName); - if (deviceName) CFRelease(deviceName); - if (fullName) CFRelease(fullName); + MIDIEntityRef entity; + MIDIDeviceRef device; + CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL; + CFStringEncoding defaultEncoding; + char* newName; + + /* get the default string encoding */ + defaultEncoding = CFStringGetSystemEncoding(); + + /* get the entity and device info */ + MIDIEndpointGetEntity(ep, &entity); + MIDIEntityGetDevice(entity, &device); + + /* create the nicely formated name */ + MIDIObjectGetStringProperty(ep, kMIDIPropertyName, &endpointName); + MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName); + if (deviceName != NULL) { + fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"), + deviceName, endpointName); + } else { + fullName = endpointName; + } + + /* copy the string into our buffer */ + newName = (char*)mem_alloc(CFStringGetLength(fullName) + 1); + CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1, + defaultEncoding); + + /* clean up */ + if (endpointName) CFRelease(endpointName); + if (deviceName) CFRelease(deviceName); + if (fullName) CFRelease(fullName); - return newName; + return newName; } static int _macosx_start(struct midi_port *p) { - struct macosx_midi *m; - m = (struct macosx_midi *)p->userdata; + struct macosx_midi *m; + m = (struct macosx_midi *)p->userdata; - if (p->io & MIDI_INPUT - && MIDIPortConnectSource(portIn, m->ep, (void*)p) != noErr) { - return 0; - } - - if (p->io & MIDI_OUTPUT) { - m->pl = (MIDIPacketList*)m->packet; - m->x = NULL; - } - return 1; + if (p->io & MIDI_INPUT + && MIDIPortConnectSource(portIn, m->ep, (void*)p) != noErr) { + return 0; + } + + if (p->io & MIDI_OUTPUT) { + m->pl = (MIDIPacketList*)m->packet; + m->x = NULL; + } + return 1; } static int _macosx_stop(struct midi_port *p) { - struct macosx_midi *m; - m = (struct macosx_midi *)p->userdata; - if (p->io & MIDI_INPUT - && MIDIPortDisconnectSource(portIn, m->ep) != noErr) { - return 0; - } - return 1; + struct macosx_midi *m; + m = (struct macosx_midi *)p->userdata; + if (p->io & MIDI_INPUT + && MIDIPortDisconnectSource(portIn, m->ep) != noErr) { + return 0; + } + return 1; } static void _macosx_poll(struct midi_provider *p) { - struct macosx_midi *data; - MIDIEndpointRef ep; - int i; - - int num_out, num_in; - - num_out = MIDIGetNumberOfDestinations(); - num_in = MIDIGetNumberOfSources(); - - for (i = max_outputs; i < num_out; i++) { - ep = MIDIGetDestination(i); - if (!ep) continue; - data = mem_alloc(sizeof(struct macosx_midi)); - memcpy(&data->ep, &ep, sizeof(ep)); - data->name = get_ep_name(ep); - midi_port_register(p, MIDI_OUTPUT, data->name, data, 1); - } - max_outputs = i; - - - for (i = max_inputs; i < num_in; i++) { - ep = MIDIGetSource(i); - if (!ep) continue; - data = mem_alloc(sizeof(struct macosx_midi)); - memcpy(&data->ep, &ep, sizeof(ep)); - data->name = get_ep_name(ep); - midi_port_register(p, MIDI_INPUT, data->name, data, 1); - } - max_inputs = i; + struct macosx_midi *data; + MIDIEndpointRef ep; + int i; + + int num_out, num_in; + + num_out = MIDIGetNumberOfDestinations(); + num_in = MIDIGetNumberOfSources(); + + for (i = max_outputs; i < num_out; i++) { + ep = MIDIGetDestination(i); + if (!ep) continue; + data = mem_alloc(sizeof(struct macosx_midi)); + memcpy(&data->ep, &ep, sizeof(ep)); + data->name = get_ep_name(ep); + midi_port_register(p, MIDI_OUTPUT, data->name, data, 1); + } + max_outputs = i; + + + for (i = max_inputs; i < num_in; i++) { + ep = MIDIGetSource(i); + if (!ep) continue; + data = mem_alloc(sizeof(struct macosx_midi)); + memcpy(&data->ep, &ep, sizeof(ep)); + data->name = get_ep_name(ep); + midi_port_register(p, MIDI_INPUT, data->name, data, 1); + } + max_inputs = i; } int macosx_midi_setup(void) { - static struct midi_driver driver; + static struct midi_driver driver; - memset(&driver,0,sizeof(driver)); - driver.flags = MIDI_PORT_CAN_SCHEDULE; - driver.poll = _macosx_poll; - driver.thread = NULL; - driver.enable = _macosx_start; - driver.disable = _macosx_stop; - driver.send = _macosx_send; - driver.drain = _macosx_drain; - - if (MIDIClientCreate(CFSTR("Schism Tracker"), NULL, NULL, &client) != noErr) { - return 0; - } - if (MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, &portIn) != noErr) { - return 0; - } - if (MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut) != noErr) { - return 0; - } + memset(&driver,0,sizeof(driver)); + driver.flags = MIDI_PORT_CAN_SCHEDULE; + driver.poll = _macosx_poll; + driver.thread = NULL; + driver.enable = _macosx_start; + driver.disable = _macosx_stop; + driver.send = _macosx_send; + driver.drain = _macosx_drain; + + if (MIDIClientCreate(CFSTR("Schism Tracker"), NULL, NULL, &client) != noErr) { + return 0; + } + if (MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, &portIn) != noErr) { + return 0; + } + if (MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut) != noErr) { + return 0; + } - if (!midi_provider_register("Mac OS X", &driver)) return 0; + if (!midi_provider_register("Mac OS X", &driver)) return 0; - return 1; + return 1; } #endif diff -Nru schism-0+20110101/sys/macosx/osdefs.c schism-20160521/sys/macosx/osdefs.c --- schism-0+20110101/sys/macosx/osdefs.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/osdefs.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -31,24 +31,24 @@ int macosx_sdlevent(SDL_Event *event) { - if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) { - if (event->key.keysym.sym == 0) { - switch (event->key.keysym.scancode) { - case 106: // mac F16 key - event->key.keysym.sym = SDLK_PRINT; - event->key.keysym.mod = KMOD_CTRL; - return 1; - case 234: // XXX what key is this? - if (event->type == SDL_KEYDOWN) - song_set_current_order(song_get_current_order() - 1); - return 0; - case 233: // XXX what key is this? - if (event->type == SDL_KEYUP) - song_set_current_order(song_get_current_order() + 1); - return 0; - }; - } - } - return 1; + if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) { + if (event->key.keysym.sym == 0) { + switch (event->key.keysym.scancode) { + case 106: // mac F16 key + event->key.keysym.sym = SDLK_PRINT; + event->key.keysym.mod = KMOD_CTRL; + return 1; + case 234: // XXX what key is this? + if (event->type == SDL_KEYDOWN) + song_set_current_order(song_get_current_order() - 1); + return 0; + case 233: // XXX what key is this? + if (event->type == SDL_KEYUP) + song_set_current_order(song_get_current_order() + 1); + return 0; + }; + } + } + return 1; } diff -Nru schism-0+20110101/sys/macosx/Schism_Tracker.app/Contents/Info.plist schism-20160521/sys/macosx/Schism_Tracker.app/Contents/Info.plist --- schism-0+20110101/sys/macosx/Schism_Tracker.app/Contents/Info.plist 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/Schism_Tracker.app/Contents/Info.plist 2016-05-21 14:40:41.000000000 +0000 @@ -85,7 +85,7 @@ CFBundleGetInfoString - Schism Tracker Copyright 2003-2011 Storlek + Schism Tracker Copyright 2003-2012 Storlek CFBundleIconFile appIcon.icns CFBundleIdentifier diff -Nru schism-0+20110101/sys/macosx/volume-macosx.c schism-20160521/sys/macosx/volume-macosx.c --- schism-0+20110101/sys/macosx/volume-macosx.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/macosx/volume-macosx.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -33,87 +33,87 @@ int macosx_volume_get_max(void); int macosx_volume_get_max(void) { - return 65535; + return 65535; } void macosx_volume_read(int *left, int *right); void macosx_volume_read(int *left, int *right) { - UInt32 size; - AudioDeviceID od; - OSStatus e; - UInt32 ch[2]; - Float32 fl[2]; - int i; - - if (left) *left = 0; - if (right) *right = 0; - - size=sizeof(od); - e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, - &size, &od); - if (e != 0) return; - - size=sizeof(ch); - e = AudioDeviceGetProperty(od, /* shit */ - 0, /* QA1016 says "0" is master channel */ - false, - kAudioDevicePropertyPreferredChannelsForStereo, - &size, - &ch); - if (e != 0) return; - - for (i = 0; i < 2; i++) { - size = sizeof(Float32); - e = AudioDeviceGetProperty(od, /* device */ - ch[i], /* preferred stereo channel */ - false, /* output device */ - kAudioDevicePropertyVolumeScalar, - &size, - &fl[i]); - if (e != 0) return; - } - if (left) *left = fl[0] * 65536.0f; - if (right) *right = fl[1] * 65536.0f; + UInt32 size; + AudioDeviceID od; + OSStatus e; + UInt32 ch[2]; + Float32 fl[2]; + int i; + + if (left) *left = 0; + if (right) *right = 0; + + size=sizeof(od); + e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, + &size, &od); + if (e != 0) return; + + size=sizeof(ch); + e = AudioDeviceGetProperty(od, + 0, /* QA1016 says "0" is master channel */ + false, + kAudioDevicePropertyPreferredChannelsForStereo, + &size, + &ch); + if (e != 0) return; + + for (i = 0; i < 2; i++) { + size = sizeof(Float32); + e = AudioDeviceGetProperty(od, /* device */ + ch[i], /* preferred stereo channel */ + false, /* output device */ + kAudioDevicePropertyVolumeScalar, + &size, + &fl[i]); + if (e != 0) return; + } + if (left) *left = fl[0] * 65536.0f; + if (right) *right = fl[1] * 65536.0f; } void macosx_volume_write(int left, int right); void macosx_volume_write(int left, int right) { - UInt32 size; - AudioDeviceID od; - OSStatus e; - UInt32 ch[2]; - Float32 fl[2]; - int i; - - size=sizeof(od); - e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, - &size, &od); - if (e != 0) return; - - size=sizeof(ch); - e = AudioDeviceGetProperty(od, /* shit */ - 0, /* QA1016 says "0" is master channel */ - false, - kAudioDevicePropertyPreferredChannelsForStereo, - &size, - &ch); - if (e != 0) return; - - fl[0] = ((float)left) / 65536.0f; - fl[1] = ((float)right) / 65536.0f; - - for (i = 0; i < 2; i++) { - e = AudioDeviceSetProperty(od, /* device */ - NULL, /* no timestamp */ - ch[i], /* preferred stereo channel */ - false, /* output device */ - kAudioDevicePropertyVolumeScalar, - sizeof(Float32), - &fl[i]); - if (e != 0) return; - } + UInt32 size; + AudioDeviceID od; + OSStatus e; + UInt32 ch[2]; + Float32 fl[2]; + int i; + + size=sizeof(od); + e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, + &size, &od); + if (e != 0) return; + + size=sizeof(ch); + e = AudioDeviceGetProperty(od, + 0, /* QA1016 says "0" is master channel */ + false, + kAudioDevicePropertyPreferredChannelsForStereo, + &size, + &ch); + if (e != 0) return; + + fl[0] = ((float)left) / 65536.0f; + fl[1] = ((float)right) / 65536.0f; + + for (i = 0; i < 2; i++) { + e = AudioDeviceSetProperty(od, /* device */ + NULL, /* no timestamp */ + ch[i], /* preferred stereo channel */ + false, /* output device */ + kAudioDevicePropertyVolumeScalar, + sizeof(Float32), + &fl[i]); + if (e != 0) return; + } } #endif diff -Nru schism-0+20110101/sys/oss/midi-oss.c schism-20160521/sys/oss/midi-oss.c --- schism-0+20110101/sys/oss/midi-oss.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/oss/midi-oss.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -47,25 +47,25 @@ static void _oss_send(struct midi_port *p, const unsigned char *data, unsigned int len, - UNUSED unsigned int delay) + UNUSED unsigned int delay) { - int fd, r, n; - fd = opened[ n = INT_SHAPED_PTR(p->userdata) ]; - if (fd < 0) return; - while (len > 0) { - r = write(fd, data, len); - if (r < -1 && errno == EINTR) continue; - if (r < 1) { - /* err, can't happen? */ - (void)close(opened[n]); - opened[n] = -1; - p->userdata = PTR_SHAPED_INT(-1); - p->io = 0; /* failure! */ - return; - } - data += r; - len -= r; - } + int fd, r, n; + fd = opened[ n = INT_SHAPED_PTR(p->userdata) ]; + if (fd < 0) return; + while (len > 0) { + r = write(fd, data, len); + if (r < -1 && errno == EINTR) continue; + if (r < 1) { + /* err, can't happen? */ + (void)close(opened[n]); + opened[n] = -1; + p->userdata = PTR_SHAPED_INT(-1); + p->io = 0; /* failure! */ + return; + } + data += r; + len -= r; + } } static int _oss_start(UNUSED struct midi_port *p) { return 1; /* do nothing */ } @@ -74,104 +74,104 @@ static int _oss_thread(struct midi_provider *p) { - struct pollfd pfd[MAX_MIDI_PORTS]; - struct midi_port *ptr, *src; - unsigned char midi_buf[4096]; - int i, j, r; - - for (;;) { - ptr = NULL; - j = 0; - while (midi_port_foreach(p, &ptr)) { - i = INT_SHAPED_PTR(ptr->userdata); - if (i == -1) continue; /* err... */ - if (!(ptr->io & MIDI_INPUT)) continue; - pfd[j].fd = i; - pfd[j].events = POLLIN; - pfd[j].revents = 0; /* RH 5 bug */ - j++; - } - if (!j || poll(pfd, j, -1) < 1) { - sleep(1); - continue; - } - for (i = 0; i < j; i++) { - if (!(pfd[i].revents & POLLIN)) continue; - do { - r = read(pfd[i].fd, midi_buf, sizeof(midi_buf)); - } while (r == -1 && errno == EINTR); - if (r > 0) { - ptr = src = NULL; - while (midi_port_foreach(p, &ptr)) { - if (INT_SHAPED_PTR(ptr->userdata) == pfd[i].fd) { - src = ptr; - } - } - midi_received_cb(src, midi_buf, r); - } - } - } - /* stupid gcc */ - return 0; + struct pollfd pfd[MAX_MIDI_PORTS]; + struct midi_port *ptr, *src; + unsigned char midi_buf[4096]; + int i, j, r; + + for (;;) { + ptr = NULL; + j = 0; + while (midi_port_foreach(p, &ptr)) { + i = INT_SHAPED_PTR(ptr->userdata); + if (i == -1) continue; /* err... */ + if (!(ptr->io & MIDI_INPUT)) continue; + pfd[j].fd = i; + pfd[j].events = POLLIN; + pfd[j].revents = 0; /* RH 5 bug */ + j++; + } + if (!j || poll(pfd, j, -1) < 1) { + sleep(1); + continue; + } + for (i = 0; i < j; i++) { + if (!(pfd[i].revents & POLLIN)) continue; + do { + r = read(pfd[i].fd, midi_buf, sizeof(midi_buf)); + } while (r == -1 && errno == EINTR); + if (r > 0) { + ptr = src = NULL; + while (midi_port_foreach(p, &ptr)) { + if (INT_SHAPED_PTR(ptr->userdata) == pfd[i].fd) { + src = ptr; + } + } + midi_received_cb(src, midi_buf, r); + } + } + } + /* stupid gcc */ + return 0; } static void _tryopen(int n, const char *name, struct midi_provider *_oss_provider) { - int io; - char *ptr; + int io; + char *ptr; - if (opened[n+1] != -1) return; - opened[n+1] = open(name, O_RDWR|O_NOCTTY|O_NONBLOCK); - if (opened[n+1] == -1) { - opened[n+1] = open(name, O_RDONLY|O_NOCTTY|O_NONBLOCK); - if (opened[n+1] == -1) { - opened[n+1] = open(name, O_WRONLY|O_NOCTTY|O_NONBLOCK); - if (opened[n+1] == -1) return; - io = MIDI_OUTPUT; - } else { - io = MIDI_INPUT; - } - } else { - io = MIDI_INPUT | MIDI_OUTPUT; - } - - ptr = NULL; - if (asprintf(&ptr, " %-16s (OSS)", name) == -1) { - return; - } - midi_port_register(_oss_provider, io, ptr, PTR_SHAPED_INT((long)n+1), 0); - free(ptr); + if (opened[n+1] != -1) return; + opened[n+1] = open(name, O_RDWR|O_NOCTTY|O_NONBLOCK); + if (opened[n+1] == -1) { + opened[n+1] = open(name, O_RDONLY|O_NOCTTY|O_NONBLOCK); + if (opened[n+1] == -1) { + opened[n+1] = open(name, O_WRONLY|O_NOCTTY|O_NONBLOCK); + if (opened[n+1] == -1) return; + io = MIDI_OUTPUT; + } else { + io = MIDI_INPUT; + } + } else { + io = MIDI_INPUT | MIDI_OUTPUT; + } + + ptr = NULL; + if (asprintf(&ptr, " %-16s (OSS)", name) == -1) { + return; + } + midi_port_register(_oss_provider, io, ptr, PTR_SHAPED_INT((long)n+1), 0); + free(ptr); } static void _oss_poll(struct midi_provider *_oss_provider) { - char sbuf[64]; - int i; + char sbuf[64]; + int i; - _tryopen(-1, "/dev/midi", _oss_provider); - for (i = 0; i < MAX_OSS_MIDI; i++) { - sprintf(sbuf, "/dev/midi%d", i); - _tryopen(i, sbuf, _oss_provider); - - sprintf(sbuf, "/dev/midi%02d", i); - _tryopen(i, sbuf, _oss_provider); - } + _tryopen(-1, "/dev/midi", _oss_provider); + for (i = 0; i < MAX_OSS_MIDI; i++) { + sprintf(sbuf, "/dev/midi%d", i); + _tryopen(i, sbuf, _oss_provider); + + sprintf(sbuf, "/dev/midi%02d", i); + _tryopen(i, sbuf, _oss_provider); + } } int oss_midi_setup(void) { - static struct midi_driver driver; - int i; + static struct midi_driver driver; + int i; - driver.flags = 0; - driver.poll = _oss_poll; - driver.thread = _oss_thread; - driver.enable = _oss_start; - driver.disable = _oss_stop; - driver.send = _oss_send; - - for (i = 0; i < MAX_MIDI_PORTS; i++) opened[i] = -1; - if (!midi_provider_register("OSS", &driver)) return 0; - return 1; + driver.flags = 0; + driver.poll = _oss_poll; + driver.thread = _oss_thread; + driver.enable = _oss_start; + driver.disable = _oss_stop; + driver.send = _oss_send; + + for (i = 0; i < MAX_MIDI_PORTS; i++) opened[i] = -1; + if (!midi_provider_register("OSS", &driver)) return 0; + return 1; } #endif diff -Nru schism-0+20110101/sys/oss/volume-oss.c schism-20160521/sys/oss/volume-oss.c --- schism-0+20110101/sys/oss/volume-oss.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/oss/volume-oss.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -55,18 +55,18 @@ static int open_mixer_device(void) { - const char *ptr; + const char *ptr; - if (!device_file) { - ptr = "/dev/sound/mixer"; - if (access(ptr, F_OK) < 0) { - /* this had better work :) */ - ptr = "/dev/mixer"; - } - device_file = ptr; - } + if (!device_file) { + ptr = "/dev/sound/mixer"; + if (access(ptr, F_OK) < 0) { + /* this had better work :) */ + ptr = "/dev/mixer"; + } + device_file = ptr; + } - return open(device_file, O_RDWR); + return open(device_file, O_RDWR); } /* --------------------------------------------------------------------- */ @@ -74,53 +74,53 @@ int oss_volume_get_max(void); int oss_volume_get_max(void) { - return VOLUME_MAX; + return VOLUME_MAX; } void oss_volume_read(int *left, int *right); void oss_volume_read(int *left, int *right) { - int fd; - uint8_t volume[4]; + int fd; + uint8_t volume[4]; - fd = open_mixer_device(); - if (fd < 0) { - log_perror(device_file); - *left = *right = 0; - return; - } - - if (ioctl(fd, MIXER_READ(SCHISM_MIXER_CONTROL), volume) == EOF) { - log_perror(device_file); - *left = *right = 0; - } else { - *left = volume[0]; - *right = volume[1]; - } + fd = open_mixer_device(); + if (fd < 0) { + log_perror(device_file); + *left = *right = 0; + return; + } + + if (ioctl(fd, MIXER_READ(SCHISM_MIXER_CONTROL), volume) == EOF) { + log_perror(device_file); + *left = *right = 0; + } else { + *left = volume[0]; + *right = volume[1]; + } - close(fd); + close(fd); } void oss_volume_write(int left, int right); void oss_volume_write(int left, int right) { - int fd; - uint8_t volume[4]; + int fd; + uint8_t volume[4]; - volume[0] = CLAMP(left, 0, VOLUME_MAX); - volume[1] = CLAMP(right, 0, VOLUME_MAX); + volume[0] = CLAMP(left, 0, VOLUME_MAX); + volume[1] = CLAMP(right, 0, VOLUME_MAX); - fd = open_mixer_device(); - if (fd < 0) { - log_perror(device_file); - return; - } - - if (ioctl(fd, MIXER_WRITE(SCHISM_MIXER_CONTROL), volume) == EOF) { - log_perror(device_file); - } + fd = open_mixer_device(); + if (fd < 0) { + log_perror(device_file); + return; + } + + if (ioctl(fd, MIXER_WRITE(SCHISM_MIXER_CONTROL), volume) == EOF) { + log_perror(device_file); + } - close(fd); + close(fd); } #endif diff -Nru schism-0+20110101/sys/posix/schismtracker.1 schism-20160521/sys/posix/schismtracker.1 --- schism-0+20110101/sys/posix/schismtracker.1 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/posix/schismtracker.1 2016-05-21 14:40:41.000000000 +0000 @@ -168,8 +168,11 @@ implemented tons of features, including MIDI support, mouse support, and disk writing. .P -Storlek "took over" development again in 2009, and has been incrementally -rewriting much of the code since then. +Storlek "took over" development again in 2009, and incrementally rewrote much +of the code through 2015. +.P +In 2016, Schism Tracker became a collaborative project between Storlek and a +group of users-turned-developers. .SH FILES .TP ~/.schism/config @@ -264,27 +267,21 @@ Schism Tracker was written by Storlek and Mrs. Brisby, with player code from Modplug by Olivier Lapicque. Based on Impulse Tracker by Jeffrey Lim. .P -Additional code and data has been contributed by many others; refer to the +Additional code and data have been contributed by many others; refer to the file \fIAUTHORS\fP in the source distribution for a more complete list. .P The keyboard diagram in this manual page was adapted from the one used in the documentation for Impulse Tracker, which in turn borrowed it from Scream Tracker 3. .SH COPYRIGHT -Copyright \(co 2003-2011 Storlek. Licensed under the GNU GPL +Copyright \(co 2003-2016 Storlek, Mrs. Brisby et al. Licensed under the GNU GPL <\fIhttp://gnu.org/licenses/gpl.html\fP>. This is free software: you are free -to change and redistribute it. There is NO WARRANTY, to the extent permitted -by law. +to change and redistribute it. There is NO WARRANTY, to the extent permitted by +law. .SH BUGS -They almost certainly exist. Post on \fIhttp://schismtracker.org/scdev/\fP -if you find one. Agitha shares her happiness with benefactors of the -insect kingdom. -.SH INTERNETS -\fIhttp://schismtracker.org/\fP - main website -.br -\fIhttp://schismtracker.org/sc/\fP - userbase discussion board -.br -\fI#schism\fP on Freenode or Espernet - IRC channel +They almost certainly exist. Post on +\fIhttps://github.com/schismtracker/schismtracker/issues\fP if you find one. +Agitha shares her happiness with benefactors of the insect kingdom. .SH SEE ALSO .\" No favoritism: this list is alphabetical, trackers then players .BR chibitracker (1), diff -Nru schism-0+20110101/sys/posix/slurp-mmap.c schism-20160521/sys/posix/slurp-mmap.c --- schism-0+20110101/sys/posix/slurp-mmap.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/posix/slurp-mmap.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -35,34 +35,34 @@ static void _munmap_slurp(slurp_t *useme) { - (void)munmap((void*)useme->data, useme->length); - (void)close(useme->extra); + (void)munmap((void*)useme->data, useme->length); + (void)close(useme->extra); } int slurp_mmap(slurp_t *useme, const char *filename, size_t st) { - int fd; - void *addr; + int fd; + void *addr; - fd = open(filename, O_RDONLY); - if (fd == -1) return 0; - addr = mmap(NULL, st, PROT_READ, MAP_SHARED + fd = open(filename, O_RDONLY); + if (fd == -1) return 0; + addr = mmap(NULL, st, PROT_READ, MAP_SHARED #if defined(MAP_POPULATE) && defined(MAP_NONBLOCK) - | MAP_POPULATE | MAP_NONBLOCK + | MAP_POPULATE | MAP_NONBLOCK #endif #if defined(MAP_NORESERVE) - | MAP_NORESERVE + | MAP_NORESERVE #endif - , fd, 0); - if (!addr || addr == ((void*)-1)) { - (void)close(fd); - return -1; - } - useme->closure = _munmap_slurp; - useme->length = st; - useme->data = addr; - useme->extra = fd; - return 1; + , fd, 0); + if (!addr || addr == ((void*)-1)) { + (void)close(fd); + return -1; + } + useme->closure = _munmap_slurp; + useme->length = st; + useme->data = addr; + useme->extra = fd; + return 1; } #endif diff -Nru schism-0+20110101/sys/stdlib/asprintf.c schism-20160521/sys/stdlib/asprintf.c --- schism-0+20110101/sys/stdlib/asprintf.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/stdlib/asprintf.c 2016-05-21 14:40:41.000000000 +0000 @@ -25,10 +25,10 @@ int asprintf(char **buf, const char *fmt, ...); int asprintf(char **buf, const char *fmt, ...) { - int status; - va_list ap; - va_start(ap, fmt); - status = vasprintf(buf, fmt, ap); - va_end(ap); - return status; + int status; + va_list ap; + va_start(ap, fmt); + status = vasprintf(buf, fmt, ap); + va_end(ap); + return status; } diff -Nru schism-0+20110101/sys/stdlib/memcmp.c schism-20160521/sys/stdlib/memcmp.c --- schism-0+20110101/sys/stdlib/memcmp.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/stdlib/memcmp.c 2016-05-21 14:40:41.000000000 +0000 @@ -2,11 +2,11 @@ int memcmp(const void *s1, const void *s2, size_t n); int memcmp(const void *s1, const void *s2, size_t n) { - register unsigned char *c1 = (unsigned char *) s1; - register unsigned char *c2 = (unsigned char *) s2; + register unsigned char *c1 = (unsigned char *) s1; + register unsigned char *c2 = (unsigned char *) s2; - while (n-- > 0) - if (*c1++ != *c2++) - return c1[-1] > c2[-1] ? 1 : -1; - return 0; + while (n-- > 0) + if (*c1++ != *c2++) + return c1[-1] > c2[-1] ? 1 : -1; + return 0; } diff -Nru schism-0+20110101/sys/stdlib/mkstemp.c schism-20160521/sys/stdlib/mkstemp.c --- schism-0+20110101/sys/stdlib/mkstemp.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/stdlib/mkstemp.c 2016-05-21 14:40:41.000000000 +0000 @@ -88,12 +88,12 @@ fd = open (template, O_RDWR|O_CREAT|O_EXCL|O_BINARY, 0600); if (fd >= 0) - /* The file does not exist. */ - return fd; + /* The file does not exist. */ + return fd; /* This is a random value. It is only necessary that the next - TMP_MAX values generated by adding 7777 to VALUE are different - with (module 2^32). */ + TMP_MAX values generated by adding 7777 to VALUE are different + with (module 2^32). */ value += 7777; } diff -Nru schism-0+20110101/sys/stdlib/strptime.c schism-20160521/sys/stdlib/strptime.c --- schism-0+20110101/sys/stdlib/strptime.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/stdlib/strptime.c 2016-05-21 14:40:41.000000000 +0000 @@ -95,7 +95,7 @@ fmt++; continue; } - + if ((c = *fmt++) != '%') goto literal; @@ -120,7 +120,7 @@ LEGAL_ALT(0); alt_format |= ALT_O; goto again; - + /* * "Complex" conversion rules, implemented through recursion. */ diff -Nru schism-0+20110101/sys/stdlib/vasprintf.c schism-20160521/sys/stdlib/vasprintf.c --- schism-0+20110101/sys/stdlib/vasprintf.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/stdlib/vasprintf.c 2016-05-21 14:40:41.000000000 +0000 @@ -27,71 +27,71 @@ static int int_vasprintf(char **result, const char *format, va_list *args) { - const char *p = format; - /* Add one to make sure that it is never zero, which might cause malloc - to return NULL. */ - int total_width = strlen (format) + 1; - va_list ap; + const char *p = format; + /* Add one to make sure that it is never zero, which might cause malloc + to return NULL. */ + int total_width = strlen (format) + 1; + va_list ap; - memcpy(&ap, args, sizeof(va_list)); + memcpy(&ap, args, sizeof(va_list)); - while (*p != '\0') { - if (*p++ == '%') { - while (strchr ("-+ #0", *p)) - ++p; - if (*p == '*') { - ++p; - total_width += abs(va_arg (ap, int)); - } else - total_width += strtoul(p, (char **) &p, 10); - if (*p == '.') { - ++p; - if (*p == '*') { - ++p; - total_width += abs (va_arg (ap, int)); - } else - total_width += strtoul(p, (char **) &p, 10); - } - while (strchr ("hlL", *p)) - ++p; - /* Should be big enough for any format specifier except %s and floats. */ - total_width += 30; - switch (*p) { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - (void) va_arg (ap, int); - break; - case 'f': - case 'e': - case 'E': - case 'g': - case 'G': - (void) va_arg (ap, double); - /* Since an ieee double can have an exponent of 307, we'll - make the buffer wide enough to cover the gross case. */ - total_width += 307; - break; - case 's': - total_width += strlen (va_arg (ap, char *)); - break; - case 'p': - case 'n': - (void) va_arg (ap, char *); - break; - } - } - } - *result = (char*)malloc (total_width); - return vsprintf (*result, format, *args); + while (*p != '\0') { + if (*p++ == '%') { + while (strchr ("-+ #0", *p)) + ++p; + if (*p == '*') { + ++p; + total_width += abs(va_arg (ap, int)); + } else + total_width += strtoul(p, (char **) &p, 10); + if (*p == '.') { + ++p; + if (*p == '*') { + ++p; + total_width += abs (va_arg (ap, int)); + } else + total_width += strtoul(p, (char **) &p, 10); + } + while (strchr ("hlL", *p)) + ++p; + /* Should be big enough for any format specifier except %s and floats. */ + total_width += 30; + switch (*p) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + (void) va_arg (ap, int); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + (void) va_arg (ap, double); + /* Since an ieee double can have an exponent of 307, we'll + make the buffer wide enough to cover the gross case. */ + total_width += 307; + break; + case 's': + total_width += strlen (va_arg (ap, char *)); + break; + case 'p': + case 'n': + (void) va_arg (ap, char *); + break; + } + } + } + *result = (char*)malloc (total_width); + return vsprintf (*result, format, *args); } int vasprintf(char **result, const char *format, va_list args); int vasprintf(char **result, const char *format, va_list args) { - return int_vasprintf (result, format, &args); + return int_vasprintf (result, format, &args); } Binary files /tmp/tmpbuNFJs/41aNKGYXkt/schism-0+20110101/sys/wii/data/certs.bin and /tmp/tmpbuNFJs/Ei0sbDmHSb/schism-20160521/sys/wii/data/certs.bin differ Binary files /tmp/tmpbuNFJs/41aNKGYXkt/schism-0+20110101/sys/wii/data/su_tik.bin and /tmp/tmpbuNFJs/Ei0sbDmHSb/schism-20160521/sys/wii/data/su_tik.bin differ Binary files /tmp/tmpbuNFJs/41aNKGYXkt/schism-0+20110101/sys/wii/data/su_tmd.bin and /tmp/tmpbuNFJs/Ei0sbDmHSb/schism-20160521/sys/wii/data/su_tmd.bin differ diff -Nru schism-0+20110101/sys/wii/isfs.c schism-20160521/sys/wii/isfs.c --- schism-0+20110101/sys/wii/isfs.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/wii/isfs.c 2016-05-21 14:40:41.000000000 +0000 @@ -94,42 +94,42 @@ const char *pathPosition = path; const char *pathEnd = strchr(path, '\0'); if (pathPosition[0] == DIR_SEPARATOR) { - entry = root; - while (pathPosition[0] == DIR_SEPARATOR) pathPosition++; - if (pathPosition >= pathEnd) found = true; + entry = root; + while (pathPosition[0] == DIR_SEPARATOR) pathPosition++; + if (pathPosition >= pathEnd) found = true; } else { - entry = current; + entry = current; } if (entry == root && !strcmp(".", pathPosition)) found = true; DIR_ENTRY *dir = entry; while (!found && !notFound) { - const char *nextPathPosition = strchr(pathPosition, DIR_SEPARATOR); - size_t dirnameLength; - if (nextPathPosition != NULL) dirnameLength = nextPathPosition - pathPosition; - else dirnameLength = strlen(pathPosition); - if (dirnameLength >= ISFS_MAXPATHLEN) return NULL; - - u32 fileIndex = 0; - while (fileIndex < dir->fileCount && !found && !notFound) { - entry = &dir->children[fileIndex]; - if (dirnameLength == strnlen(entry->name, ISFS_MAXPATHLEN - 1) - && !strncasecmp(pathPosition, entry->name, dirnameLength)) found = true; - if (found && !is_dir(entry) && nextPathPosition) found = false; - if (!found) fileIndex++; - } - - if (fileIndex >= dir->fileCount) { - notFound = true; - found = false; - } else if (!nextPathPosition || nextPathPosition >= pathEnd) { - found = true; - } else if (is_dir(entry)) { - dir = entry; - pathPosition = nextPathPosition; - while (pathPosition[0] == DIR_SEPARATOR) pathPosition++; - if (pathPosition >= pathEnd) found = true; - else found = false; - } + const char *nextPathPosition = strchr(pathPosition, DIR_SEPARATOR); + size_t dirnameLength; + if (nextPathPosition != NULL) dirnameLength = nextPathPosition - pathPosition; + else dirnameLength = strlen(pathPosition); + if (dirnameLength >= ISFS_MAXPATHLEN) return NULL; + + u32 fileIndex = 0; + while (fileIndex < dir->fileCount && !found && !notFound) { + entry = &dir->children[fileIndex]; + if (dirnameLength == strnlen(entry->name, ISFS_MAXPATHLEN - 1) + && !strncasecmp(pathPosition, entry->name, dirnameLength)) found = true; + if (found && !is_dir(entry) && nextPathPosition) found = false; + if (!found) fileIndex++; + } + + if (fileIndex >= dir->fileCount) { + notFound = true; + found = false; + } else if (!nextPathPosition || nextPathPosition >= pathEnd) { + found = true; + } else if (is_dir(entry)) { + dir = entry; + pathPosition = nextPathPosition; + while (pathPosition[0] == DIR_SEPARATOR) pathPosition++; + if (pathPosition >= pathEnd) found = true; + else found = false; + } } if (found && !notFound) return entry; @@ -137,24 +137,24 @@ } static int _ISFS_open_r(struct _reent *r, void *fileStruct, const char *path, - UNUSED int flags, UNUSED int mode) { + UNUSED int flags, UNUSED int mode) { FILE_STRUCT *file = (FILE_STRUCT *)fileStruct; DIR_ENTRY *entry = entry_from_path(path); if (!entry) { - r->_errno = ENOENT; - return -1; + r->_errno = ENOENT; + return -1; } else if (is_dir(entry)) { - r->_errno = EISDIR; - return -1; + r->_errno = EISDIR; + return -1; } file->entry = entry; file->inUse = true; file->isfs_fd = ISFS_Open(entry->abspath, ISFS_OPEN_READ); if (file->isfs_fd < 0) { - if (file->isfs_fd == ISFS_EINVAL) r->_errno = EACCES; - else r->_errno = -file->isfs_fd; - return -1; + if (file->isfs_fd == ISFS_EINVAL) r->_errno = EACCES; + else r->_errno = -file->isfs_fd; + return -1; } return (int)file; @@ -163,15 +163,15 @@ static int _ISFS_close_r(struct _reent *r, int fd) { FILE_STRUCT *file = (FILE_STRUCT *)fd; if (!file->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } file->inUse = false; s32 ret = ISFS_Close(file->isfs_fd); if (ret < 0) { - r->_errno = -ret; - return -1; + r->_errno = -ret; + return -1; } return 0; @@ -180,19 +180,19 @@ static int _ISFS_read_r(struct _reent *r, int fd, char *ptr, size_t len) { FILE_STRUCT *file = (FILE_STRUCT *)fd; if (!file->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } if (len <= 0) { - return 0; + return 0; } s32 ret = ISFS_Read(file->isfs_fd, read_buffer, len); if (ret < 0) { - r->_errno = -ret; - return -1; + r->_errno = -ret; + return -1; } else if ((size_t) ret < len) { - r->_errno = EOVERFLOW; + r->_errno = EOVERFLOW; } memcpy(ptr, read_buffer, ret); @@ -202,14 +202,14 @@ static off_t _ISFS_seek_r(struct _reent *r, int fd, off_t pos, int dir) { FILE_STRUCT *file = (FILE_STRUCT *)fd; if (!file->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } s32 ret = ISFS_Seek(file->isfs_fd, pos, dir); if (ret < 0) { - r->_errno = -ret; - return -1; + r->_errno = -ret; + return -1; } return ret; } @@ -238,8 +238,8 @@ static int _ISFS_fstat_r(struct _reent *r, int fd, struct stat *st) { FILE_STRUCT *file = (FILE_STRUCT *)fd; if (!file->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } stat_entry(file->entry, st); return 0; @@ -248,8 +248,8 @@ static int _ISFS_stat_r(struct _reent *r, const char *path, struct stat *st) { DIR_ENTRY *entry = entry_from_path(path); if (!entry) { - r->_errno = ENOENT; - return -1; + r->_errno = ENOENT; + return -1; } stat_entry(entry, st); return 0; @@ -258,11 +258,11 @@ static int _ISFS_chdir_r(struct _reent *r, const char *path) { DIR_ENTRY *entry = entry_from_path(path); if (!entry) { - r->_errno = ENOENT; - return -1; + r->_errno = ENOENT; + return -1; } else if (!is_dir(entry)) { - r->_errno = ENOTDIR; - return -1; + r->_errno = ENOTDIR; + return -1; } return 0; } @@ -271,11 +271,11 @@ DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct); state->entry = entry_from_path(path); if (!state->entry) { - r->_errno = ENOENT; - return NULL; + r->_errno = ENOENT; + return NULL; } else if (!is_dir(state->entry)) { - r->_errno = ENOTDIR; - return NULL; + r->_errno = ENOTDIR; + return NULL; } state->index = 0; state->inUse = true; @@ -285,8 +285,8 @@ static int _ISFS_dirreset_r(struct _reent *r, DIR_ITER *dirState) { DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct); if (!state->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } state->index = 0; return 0; @@ -295,12 +295,12 @@ static int _ISFS_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *st) { DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct); if (!state->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } if (state->index >= state->entry->fileCount) { - r->_errno = ENOENT; - return -1; + r->_errno = ENOENT; + return -1; } DIR_ENTRY *entry = &state->entry->children[state->index++]; strncpy(filename, entry->name, ISFS_MAXPATHLEN - 1); @@ -311,8 +311,8 @@ static int _ISFS_dirclose_r(struct _reent *r, DIR_ITER *dirState) { DIR_STATE_STRUCT *state = (DIR_STATE_STRUCT *)(dirState->dirStruct); if (!state->inUse) { - r->_errno = EBADF; - return -1; + r->_errno = EBADF; + return -1; } state->inUse = false; return 0; @@ -364,29 +364,29 @@ u32 fileCount; s32 ret = ISFS_ReadDir(parent->abspath, NULL, &fileCount); if (ret != ISFS_OK) { - s32 fd = ISFS_Open(parent->abspath, ISFS_OPEN_READ); - if (fd >= 0) { - static fstats st __attribute__((aligned(32))); - if (ISFS_GetFileStats(fd, &st) == ISFS_OK) parent->size = st.file_length; - ISFS_Close(fd); - } - return true; + s32 fd = ISFS_Open(parent->abspath, ISFS_OPEN_READ); + if (fd >= 0) { + static fstats st __attribute__((aligned(32))); + if (ISFS_GetFileStats(fd, &st) == ISFS_OK) parent->size = st.file_length; + ISFS_Close(fd); + } + return true; } parent->flags = FLAG_DIR; if (fileCount > 0) { - if ((ISFS_MAXPATHLEN * fileCount) > BUFFER_SIZE) return false; - ret = ISFS_ReadDir(parent->abspath, read_buffer, &fileCount); - if (ret != ISFS_OK) return false; - u32 fileNum; - char *name = read_buffer; - for (fileNum = 0; fileNum < fileCount; fileNum++) { - DIR_ENTRY *child = add_child_entry(parent, name); - if (!child) return false; - name += strlen(name) + 1; - } - for (fileNum = 0; fileNum < fileCount; fileNum++) - if (!read_recursive(parent->children + fileNum)) - return false; + if ((ISFS_MAXPATHLEN * fileCount) > BUFFER_SIZE) return false; + ret = ISFS_ReadDir(parent->abspath, read_buffer, &fileCount); + if (ret != ISFS_OK) return false; + u32 fileNum; + char *name = read_buffer; + for (fileNum = 0; fileNum < fileCount; fileNum++) { + DIR_ENTRY *child = add_child_entry(parent, name); + if (!child) return false; + name += strlen(name) + 1; + } + for (fileNum = 0; fileNum < fileCount; fileNum++) + if (!read_recursive(parent->children + fileNum)) + return false; } return true; } @@ -420,14 +420,14 @@ bool ISFS_Unmount() { if (root) { - cleanup_recursive(root); - free(root); - root = NULL; + cleanup_recursive(root); + free(root); + root = NULL; } current = root; if (dotab_device >= 0) { - dotab_device = -1; - return !RemoveDevice(DEVICE_NAME ":"); + dotab_device = -1; + return !RemoveDevice(DEVICE_NAME ":"); } return true; } @@ -439,7 +439,7 @@ s32 ISFS_SU() { u32 key = 0; return ES_Identify((signed_blob *) certs_bin, sizeof(certs_bin), - (signed_blob *) su_tmd_bin, sizeof(su_tmd_bin), - (signed_blob *) su_tik_bin, sizeof(su_tik_bin), - &key); + (signed_blob *) su_tmd_bin, sizeof(su_tmd_bin), + (signed_blob *) su_tik_bin, sizeof(su_tik_bin), + &key); } diff -Nru schism-0+20110101/sys/wii/osdefs.c schism-20160521/sys/wii/osdefs.c --- schism-0+20110101/sys/wii/osdefs.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/wii/osdefs.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -42,118 +42,118 @@ // cargopasta'd from libogc git __di_check_ahbprot static u32 _check_ahbprot(void) { - s32 res; - u64 title_id; - u32 tmd_size; - STACK_ALIGN(u32, tmdbuf, 1024, 32); - - res = ES_GetTitleID(&title_id); - if (res < 0) { - log_appendf(4, "ES_GetTitleID() failed: %d", res); - return res; - } - - res = ES_GetStoredTMDSize(title_id, &tmd_size); - if (res < 0) { - log_appendf(4, "ES_GetStoredTMDSize() failed: %d", res); - return res; - } - - if (tmd_size > 4096) { - log_appendf(4, "TMD too big: %d", tmd_size); - return -EINVAL; - } - - res = ES_GetStoredTMD(title_id, tmdbuf, tmd_size); - if (res < 0) { - log_appendf(4, "ES_GetStoredTMD() failed: %d", res); - return -EINVAL; - } - - if ((tmdbuf[0x76] & 3) == 3) { - return 1; - } + s32 res; + u64 title_id; + u32 tmd_size; + STACK_ALIGN(u32, tmdbuf, 1024, 32); + + res = ES_GetTitleID(&title_id); + if (res < 0) { + log_appendf(4, "ES_GetTitleID() failed: %d", res); + return res; + } + + res = ES_GetStoredTMDSize(title_id, &tmd_size); + if (res < 0) { + log_appendf(4, "ES_GetStoredTMDSize() failed: %d", res); + return res; + } + + if (tmd_size > 4096) { + log_appendf(4, "TMD too big: %d", tmd_size); + return -EINVAL; + } + + res = ES_GetStoredTMD(title_id, tmdbuf, tmd_size); + if (res < 0) { + log_appendf(4, "ES_GetStoredTMD() failed: %d", res); + return -EINVAL; + } + + if ((tmdbuf[0x76] & 3) == 3) { + return 1; + } - return 0; + return 0; } const char *osname = "wii"; void wii_sysinit(int *pargc, char ***pargv) { - DIR_ITER *dir; - char *ptr = NULL; + DIR_ITER *dir; + char *ptr = NULL; - log_appendf(1, "[Wii] This is IOS%d v%X, and AHBPROT is %s", - IOS_GetVersion(), IOS_GetRevision(), _check_ahbprot() > 0 ? "enabled" : "disabled"); - if (*pargc == 0 && *pargv == NULL) { - // I don't know if any other loaders provide similarly broken environments - log_appendf(1, "[Wii] Was I just bannerbombed? Prepare for crash at exit..."); - } else if (memcmp((void *) 0x80001804, "STUBHAXX", 8) == 0) { - log_appendf(1, "[Wii] Hello, HBC user!"); - } else { - log_appendf(1, "[Wii] Where am I?!"); - } - - ISFS_SU(); - if (ISFS_Initialize() == IPC_OK) - ISFS_Mount(); - fatInit(CACHE_PAGES, 0); - - // Attempt to locate a suitable home directory. - if (!*pargc || !*pargv) { - // loader didn't bother setting these - *pargc = 1; - *pargv = malloc(sizeof(char **)); - *pargv[0] = str_dup("?"); - } else if (strchr(*pargv[0], '/') != NULL) { - // presumably launched from hbc menu - put stuff in the boot dir - // (does get_parent_directory do what I want here?) - ptr = get_parent_directory(*pargv[0]); - } - if (!ptr) { - // Make a guess anyway - ptr = str_dup("sd:/apps/schismtracker"); - } - if (chdir(ptr) != 0) { - free(ptr); - dir = diropen("sd:/"); - if (dir) { - // Ok at least the sd card works, there's some other dysfunction - dirclose(dir); - ptr = str_dup("sd:/"); - } else { - // Safe (but useless) default - ptr = str_dup("isfs:/"); - } - chdir(ptr); // Hope that worked, otherwise we're hosed - } - put_env_var("HOME", ptr); - free(ptr); + log_appendf(1, "[Wii] This is IOS%d v%X, and AHBPROT is %s", + IOS_GetVersion(), IOS_GetRevision(), _check_ahbprot() > 0 ? "enabled" : "disabled"); + if (*pargc == 0 && *pargv == NULL) { + // I don't know if any other loaders provide similarly broken environments + log_appendf(1, "[Wii] Was I just bannerbombed? Prepare for crash at exit..."); + } else if (memcmp((void *) 0x80001804, "STUBHAXX", 8) == 0) { + log_appendf(1, "[Wii] Hello, HBC user!"); + } else { + log_appendf(1, "[Wii] Where am I?!"); + } + + ISFS_SU(); + if (ISFS_Initialize() == IPC_OK) + ISFS_Mount(); + fatInit(CACHE_PAGES, 0); + + // Attempt to locate a suitable home directory. + if (!*pargc || !*pargv) { + // loader didn't bother setting these + *pargc = 1; + *pargv = malloc(sizeof(char **)); + *pargv[0] = str_dup("?"); + } else if (strchr(*pargv[0], '/') != NULL) { + // presumably launched from hbc menu - put stuff in the boot dir + // (does get_parent_directory do what I want here?) + ptr = get_parent_directory(*pargv[0]); + } + if (!ptr) { + // Make a guess anyway + ptr = str_dup("sd:/apps/schismtracker"); + } + if (chdir(ptr) != 0) { + free(ptr); + dir = diropen("sd:/"); + if (dir) { + // Ok at least the sd card works, there's some other dysfunction + dirclose(dir); + ptr = str_dup("sd:/"); + } else { + // Safe (but useless) default + ptr = str_dup("isfs:/"); + } + chdir(ptr); // Hope that worked, otherwise we're hosed + } + put_env_var("HOME", ptr); + free(ptr); } void wii_sysexit(void) { - ISFS_Deinitialize(); + ISFS_Deinitialize(); } void wii_sdlinit(void) { - int n, total; + int n, total; - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { - log_appendf(4, "joystick init failed: %s", SDL_GetError()); - return; - } - - total = SDL_NumJoysticks(); - for (n = 0; n < total; n++) { - SDL_Joystick *js = SDL_JoystickOpen(n); - if (js == NULL) { - log_appendf(4, "[%d] open fail", n); - continue; - } - } + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { + log_appendf(4, "joystick init failed: %s", SDL_GetError()); + return; + } + + total = SDL_NumJoysticks(); + for (n = 0; n < total; n++) { + SDL_Joystick *js = SDL_JoystickOpen(n); + if (js == NULL) { + log_appendf(4, "[%d] open fail", n); + continue; + } + } } @@ -161,23 +161,23 @@ static SDLKey hat_to_keysym(int value) { - // up/down take precedence over left/right - switch (value) { - case SDL_HAT_LEFTUP: - case SDL_HAT_UP: - case SDL_HAT_RIGHTUP: - return SDLK_UP; - case SDL_HAT_LEFTDOWN: - case SDL_HAT_DOWN: - case SDL_HAT_RIGHTDOWN: - return SDLK_DOWN; - case SDL_HAT_LEFT: - return SDLK_LEFT; - case SDL_HAT_RIGHT: - return SDLK_RIGHT; - default: // SDL_HAT_CENTERED - return 0; - } + // up/down take precedence over left/right + switch (value) { + case SDL_HAT_LEFTUP: + case SDL_HAT_UP: + case SDL_HAT_RIGHTUP: + return SDLK_UP; + case SDL_HAT_LEFTDOWN: + case SDL_HAT_DOWN: + case SDL_HAT_RIGHTDOWN: + return SDLK_DOWN; + case SDL_HAT_LEFT: + return SDLK_LEFT; + case SDL_HAT_RIGHT: + return SDLK_RIGHT; + default: // SDL_HAT_CENTERED + return 0; + } } // Huge event-rewriting hack to get at least a sort of useful interface with no keyboard. @@ -185,100 +185,100 @@ // but it at least allows simple song playback. int wii_sdlevent(SDL_Event *event) { - SDL_Event newev = {}; - SDLKey sym; + SDL_Event newev = {}; + SDLKey sym; - switch (event->type) { - case SDL_KEYDOWN: - case SDL_KEYUP: - { // argh - struct key_event k = { - .mod = event->key.keysym.mod, - .sym = event->key.keysym.sym, - }; - event->key.keysym.unicode = kbd_get_alnum(&k); - } - return 1; - - case SDL_JOYHATMOTION: - // TODO key repeat for these, somehow - sym = hat_to_keysym(event->jhat.value); - if (sym) { - newev.type = SDL_KEYDOWN; - newev.key.state = SDL_PRESSED; - lasthatsym = sym; - } else { - newev.type = SDL_KEYUP; - newev.key.state = SDL_RELEASED; - sym = lasthatsym; - lasthatsym = 0; - } - newev.key.which = event->jhat.which; - newev.key.keysym.sym = sym; - newev.key.type = newev.type; // is this a no-op? - *event = newev; - return 1; - - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - switch (event->jbutton.button) { - case 0: // A - case 1: // B - default: - return 0; - case 2: // 1 - if (song_get_mode() == MODE_STOPPED) { - // nothing playing? go to load screen - sym = SDLK_F9; - } else { - sym = SDLK_F8; - } - break; - case 3: // 2 - if (status.current_page == PAGE_LOAD_MODULE) { - // if the cursor is on a song, load then play; otherwise handle as enter - // (hmm. ctrl-enter?) - sym = SDLK_RETURN; - } else { - // F5 key - sym = SDLK_F5; - } - break; - case 4: // - - // dialog escape, or jump back a pattern - if (status.dialog_type) { - sym = SDLK_ESCAPE; - break; - } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() - 1); - } - return 0; - case 5: // + - // dialog enter, or jump forward a pattern - if (status.dialog_type) { - sym = SDLK_RETURN; - break; - } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) { - song_set_current_order(song_get_current_order() + 1); - } - return 0; - case 6: // Home - event->type = SDL_QUIT; - return 1; - } - newev.key.which = event->jbutton.which; - newev.key.keysym.sym = sym; - if (event->type == SDL_JOYBUTTONDOWN) { - newev.type = SDL_KEYDOWN; - newev.key.state = SDL_PRESSED; - } else { - newev.type = SDL_KEYUP; - newev.key.state = SDL_RELEASED; - } - newev.key.type = newev.type; // no-op? - *event = newev; - return 1; - } - return 1; + switch (event->type) { + case SDL_KEYDOWN: + case SDL_KEYUP: + { // argh + struct key_event k = { + .mod = event->key.keysym.mod, + .sym = event->key.keysym.sym, + }; + event->key.keysym.unicode = kbd_get_alnum(&k); + } + return 1; + + case SDL_JOYHATMOTION: + // TODO key repeat for these, somehow + sym = hat_to_keysym(event->jhat.value); + if (sym) { + newev.type = SDL_KEYDOWN; + newev.key.state = SDL_PRESSED; + lasthatsym = sym; + } else { + newev.type = SDL_KEYUP; + newev.key.state = SDL_RELEASED; + sym = lasthatsym; + lasthatsym = 0; + } + newev.key.which = event->jhat.which; + newev.key.keysym.sym = sym; + newev.key.type = newev.type; // is this a no-op? + *event = newev; + return 1; + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + switch (event->jbutton.button) { + case 0: // A + case 1: // B + default: + return 0; + case 2: // 1 + if (song_get_mode() == MODE_STOPPED) { + // nothing playing? go to load screen + sym = SDLK_F9; + } else { + sym = SDLK_F8; + } + break; + case 3: // 2 + if (status.current_page == PAGE_LOAD_MODULE) { + // if the cursor is on a song, load then play; otherwise handle as enter + // (hmm. ctrl-enter?) + sym = SDLK_RETURN; + } else { + // F5 key + sym = SDLK_F5; + } + break; + case 4: // - + // dialog escape, or jump back a pattern + if (status.dialog_type) { + sym = SDLK_ESCAPE; + break; + } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() - 1); + } + return 0; + case 5: // + + // dialog enter, or jump forward a pattern + if (status.dialog_type) { + sym = SDLK_RETURN; + break; + } else if (event->type == SDL_JOYBUTTONDOWN && song_get_mode() == MODE_PLAYING) { + song_set_current_order(song_get_current_order() + 1); + } + return 0; + case 6: // Home + event->type = SDL_QUIT; + return 1; + } + newev.key.which = event->jbutton.which; + newev.key.keysym.sym = sym; + if (event->type == SDL_JOYBUTTONDOWN) { + newev.type = SDL_KEYDOWN; + newev.key.state = SDL_PRESSED; + } else { + newev.type = SDL_KEYUP; + newev.key.state = SDL_RELEASED; + } + newev.key.type = newev.type; // no-op? + *event = newev; + return 1; + } + return 1; } diff -Nru schism-0+20110101/sys/win32/filetype.c schism-20160521/sys/win32/filetype.c --- schism-0+20110101/sys/win32/filetype.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/filetype.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ void win32_filecreated_callback(const char *filename) { - /* let explorer know when we create a file. */ - SHChangeNotify(SHCNE_CREATE, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL); - SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL); + /* let explorer know when we create a file. */ + SHChangeNotify(SHCNE_CREATE, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL); + SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH|SHCNF_FLUSHNOWAIT, filename, NULL); } diff -Nru schism-0+20110101/sys/win32/localtime_r.c schism-20160521/sys/win32/localtime_r.c --- schism-0+20110101/sys/win32/localtime_r.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/localtime_r.c 2016-05-21 14:40:41.000000000 +0000 @@ -30,24 +30,24 @@ static void localtime_r_atexit(void) { - DeleteCriticalSection(&localtime_r_cs); + DeleteCriticalSection(&localtime_r_cs); } struct tm * localtime_r(const time_t *timep, struct tm *result) { - static struct tm *local_tm; - static int initialized = 0; + static struct tm *local_tm; + static int initialized = 0; - if (!initialized) { - ++initialized; - InitializeCriticalSection(&localtime_r_cs); - atexit(localtime_r_atexit); - } + if (!initialized) { + ++initialized; + InitializeCriticalSection(&localtime_r_cs); + atexit(localtime_r_atexit); + } - EnterCriticalSection(&localtime_r_cs); - local_tm = localtime(timep); - memcpy(result, local_tm, sizeof(struct tm)); - LeaveCriticalSection(&localtime_r_cs); - return result; + EnterCriticalSection(&localtime_r_cs); + local_tm = localtime(timep); + memcpy(result, local_tm, sizeof(struct tm)); + LeaveCriticalSection(&localtime_r_cs); + return result; } diff -Nru schism-0+20110101/sys/win32/midi-win32mm.c schism-20160521/sys/win32/midi-win32mm.c --- schism-0+20110101/sys/win32/midi-win32mm.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/midi-win32mm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -39,287 +39,273 @@ struct win32mm_midi { - DWORD id; + DWORD id; - HMIDIOUT out; - HMIDIIN in; + HMIDIOUT out; + HMIDIIN in; - MIDIINCAPS icp; - MIDIOUTCAPS ocp; + MIDIINCAPS icp; + MIDIOUTCAPS ocp; - MIDIHDR hh; - LPMIDIHDR obuf; - unsigned char sysx[1024]; + MIDIHDR hh; + LPMIDIHDR obuf; + unsigned char sysx[1024]; }; static unsigned int mm_period = 0; static unsigned int last_known_in_port = 0; static unsigned int last_known_out_port = 0; -static MMRESULT (*XP_timeGetDevCaps)(LPTIMECAPS caps, UINT size) = 0; -static MMRESULT (*XP_timeBeginPeriod)(UINT period) = 0; -static MMRESULT (*XP_timeSetEvent)(UINT u,UINT r,LPTIMECALLBACK proc, - DWORD_PTR user, UINT flags) = 0; - static void _win32mm_sysex(LPMIDIHDR *q, const unsigned char *d, unsigned int len) { - char *z; - LPMIDIHDR m; + char *z; + LPMIDIHDR m; - if (!d) len=0; - z = mem_alloc(sizeof(MIDIHDR) + len); - m = (LPMIDIHDR)z; - - memset(m, 0, sizeof(MIDIHDR)); - if (len) memcpy(z + sizeof(MIDIHDR), d, len); - - m->lpData = (z+sizeof(MIDIHDR)); - m->dwBufferLength = len; - m->lpNext = *q; - m->dwOffset = 0; - (*q) = (m); + if (!d) len=0; + z = mem_alloc(sizeof(MIDIHDR) + len); + m = (LPMIDIHDR)z; + + memset(m, 0, sizeof(MIDIHDR)); + if (len) memcpy(z + sizeof(MIDIHDR), d, len); + + m->lpData = (z+sizeof(MIDIHDR)); + m->dwBufferLength = len; + m->lpNext = *q; + m->dwOffset = 0; + (*q) = (m); } static void _win32mm_send(struct midi_port *p, const unsigned char *data, - unsigned int len, UNUSED unsigned int delay) + unsigned int len, UNUSED unsigned int delay) { - struct win32mm_midi *m; - DWORD q; + struct win32mm_midi *m; + DWORD q; - if (len == 0) return; + if (len == 0) return; - m = p->userdata; - if (len <= 4) { - q = data[0]; - if (len > 1) q |= (data[1] << 8); - if (len > 2) q |= (data[2] << 16); - if (len > 3) q |= (data[3] << 24); /* eh... */ - (void)midiOutShortMsg(m->out, q); - } else { - /* SysEX */ - _win32mm_sysex(&m->obuf, data, len); - if (midiOutPrepareHeader(m->out, m->obuf, sizeof(MIDIHDR)) == MMSYSERR_NOERROR) { - (void)midiOutLongMsg(m->out, m->obuf, sizeof(MIDIHDR)); - } - } + m = p->userdata; + if (len <= 4) { + q = data[0]; + if (len > 1) q |= (data[1] << 8); + if (len > 2) q |= (data[2] << 16); + if (len > 3) q |= (data[3] << 24); /* eh... */ + (void)midiOutShortMsg(m->out, q); + } else { + /* SysEX */ + _win32mm_sysex(&m->obuf, data, len); + if (midiOutPrepareHeader(m->out, m->obuf, sizeof(MIDIHDR)) == MMSYSERR_NOERROR) { + (void)midiOutLongMsg(m->out, m->obuf, sizeof(MIDIHDR)); + } + } } struct curry { - struct midi_port *p; - unsigned char *d; - unsigned int len; + struct midi_port *p; + unsigned char *d; + unsigned int len; }; static CALLBACK void _win32mm_xp_output(UNUSED UINT uTimerID, - UNUSED UINT uMsg, - DWORD_PTR dwUser, - UNUSED DWORD_PTR dw1, - UNUSED DWORD_PTR dw2) + UNUSED UINT uMsg, + DWORD_PTR dwUser, + UNUSED DWORD_PTR dw1, + UNUSED DWORD_PTR dw2) { - struct curry *c; - c = (struct curry *)dwUser; - _win32mm_send(c->p, c->d, c->len, 0); - free(c); + struct curry *c; + c = (struct curry *)dwUser; + _win32mm_send(c->p, c->d, c->len, 0); + free(c); } static void _win32mm_send_xp(struct midi_port *p, const unsigned char *buf, - unsigned int len, unsigned int delay) + unsigned int len, unsigned int delay) { - /* version for windows XP */ - struct curry *c; + /* version for windows XP */ + struct curry *c; - if (!delay) _win32mm_send(p,buf,len,0); - if (len == 0) return; + if (!delay) _win32mm_send(p,buf,len,0); + if (len == 0) return; - c = mem_alloc(sizeof(struct curry) + len); - c->p = p; - c->d = ((unsigned char*)c)+sizeof(struct curry); - c->len = len; - XP_timeSetEvent(delay, mm_period, _win32mm_xp_output, (DWORD_PTR)c, - TIME_ONESHOT | TIME_CALLBACK_FUNCTION); + c = mem_alloc(sizeof(struct curry) + len); + c->p = p; + c->d = ((unsigned char*)c)+sizeof(struct curry); + c->len = len; + timeSetEvent(delay, mm_period, _win32mm_xp_output, (DWORD_PTR)c, + TIME_ONESHOT | TIME_CALLBACK_FUNCTION); } -static CALLBACK void _win32mm_inputcb(UNUSED HMIDIIN in, UINT wmsg, DWORD inst, - DWORD param1, UNUSED DWORD param2) +static CALLBACK void _win32mm_inputcb(UNUSED HMIDIIN in, UINT wmsg, DWORD_PTR inst, + DWORD_PTR param1, DWORD_PTR param2) { - struct midi_port *p = (struct midi_port *)inst; - struct win32mm_midi *m; - unsigned char c[4]; - - switch (wmsg) { - case MIM_OPEN: - SDL_Delay(0); /* eh? */ - case MIM_CLOSE: - break; - case MIM_DATA: - c[0] = param1 & 255; - c[1] = (param1 >> 8) & 255; - c[2] = (param1 >> 16) & 255; - midi_received_cb(p, c, 3); - break; - case MIM_LONGDATA: - /* long data */ - m = p->userdata; - midi_received_cb(p, (unsigned char *) m->hh.lpData, m->hh.dwBytesRecorded); - m->hh.dwBytesRecorded = 0; - (void)midiInAddBuffer(m->in, &m->hh, sizeof(MIDIHDR)); - break; - } + struct midi_port *p = (struct midi_port *)inst; + struct win32mm_midi *m; + unsigned char c[4]; + + switch (wmsg) { + case MIM_OPEN: + SDL_Delay(0); /* eh? */ + case MIM_CLOSE: + break; + case MIM_DATA: + c[0] = param1 & 255; + c[1] = (param1 >> 8) & 255; + c[2] = (param1 >> 16) & 255; + midi_received_cb(p, c, 3); + break; + case MIM_LONGDATA: + { + MIDIHDR* hdr = (MIDIHDR*) param1; + if (hdr->dwBytesRecorded > 0) + { + /* long data */ + m = p->userdata; + midi_received_cb(p, (unsigned char *) m->hh.lpData, m->hh.dwBytesRecorded); + //TODO: The event for the midi sysex (midi-core.c SCHISM_EVENT_MIDI_SYSEX) should + // call us back so that we can add the buffer back with midiInAddBuffer(). + } + break; + } + } } static int _win32mm_start(struct midi_port *p) { - struct win32mm_midi *m; - UINT id; - WORD r; - - m = p->userdata; - id = m->id; - if (p->io == MIDI_INPUT) { - m->in = NULL; - r = midiInOpen(&m->in, - (UINT_PTR)id, - (DWORD_PTR)_win32mm_inputcb, - (DWORD_PTR)p, - CALLBACK_FUNCTION); - if (r != MMSYSERR_NOERROR) return 0; - memset(&m->hh, 0, sizeof(m->hh)); - m->hh.lpData = (LPSTR)m->sysx; - m->hh.dwBufferLength = sizeof(m->sysx); - m->hh.dwFlags = 0; - r = midiInPrepareHeader(m->in, &m->hh, sizeof(MIDIHDR)); - if (r != MMSYSERR_NOERROR) return 0; - r = midiInAddBuffer(m->in, &m->hh, sizeof(MIDIHDR)); - if (r != MMSYSERR_NOERROR) return 0; - if (midiInStart(m->in) != MMSYSERR_NOERROR) return 0; - - } - if (p->io & MIDI_OUTPUT) { - m->out = NULL; - if (midiOutOpen(&m->out, - (UINT_PTR)id, - 0, 0, - CALLBACK_NULL) != MMSYSERR_NOERROR) return 0; - } - return 1; + struct win32mm_midi *m; + UINT id; + WORD r; + + m = p->userdata; + id = m->id; + if (p->io == MIDI_INPUT) { + m->in = NULL; + r = midiInOpen(&m->in, + (UINT_PTR)id, + (DWORD_PTR)_win32mm_inputcb, + (DWORD_PTR)p, + CALLBACK_FUNCTION); + if (r != MMSYSERR_NOERROR) return 0; + memset(&m->hh, 0, sizeof(m->hh)); + m->hh.lpData = (LPSTR)m->sysx; + m->hh.dwBufferLength = sizeof(m->sysx); + m->hh.dwFlags = 0; + r = midiInPrepareHeader(m->in, &m->hh, sizeof(MIDIHDR)); + if (r != MMSYSERR_NOERROR) return 0; + r = midiInAddBuffer(m->in, &m->hh, sizeof(MIDIHDR)); + if (r != MMSYSERR_NOERROR) return 0; + if (midiInStart(m->in) != MMSYSERR_NOERROR) return 0; + + } + if (p->io & MIDI_OUTPUT) { + m->out = NULL; + if (midiOutOpen(&m->out, + (UINT_PTR)id, + 0, 0, + CALLBACK_NULL) != MMSYSERR_NOERROR) return 0; + } + return 1; } static int _win32mm_stop(struct midi_port *p) { - struct win32mm_midi *m; - LPMIDIHDR ptr; + struct win32mm_midi *m; + LPMIDIHDR ptr; - m = p->userdata; - if (p->io & MIDI_INPUT) { - /* portmidi appears to (essentially) ignore the error codes - for these guys */ - (void)midiInStop(m->in); - (void)midiInReset(m->in); - (void)midiInClose(m->in); - } - if (p->io & MIDI_OUTPUT) { - (void)midiOutReset(m->out); - (void)midiOutClose(m->out); - /* free output chain */ - ptr = m->obuf; - while (ptr) { - m->obuf = m->obuf->lpNext; - (void)free(m->obuf); - ptr = m->obuf; - } - } - return 1; + m = p->userdata; + if (p->io & MIDI_INPUT) { + /* portmidi appears to (essentially) ignore the error codes + for these guys */ + (void)midiInStop(m->in); + (void)midiInReset(m->in); + (void)midiInUnprepareHeader(m->in,&m->hh,sizeof(m->hh)); + (void)midiInClose(m->in); + } + if (p->io & MIDI_OUTPUT) { + (void)midiOutReset(m->out); + (void)midiOutClose(m->out); + /* free output chain */ + ptr = m->obuf; + while (ptr) { + m->obuf = m->obuf->lpNext; + (void)free(m->obuf); + ptr = m->obuf; + } + } + return 1; } static void _win32mm_poll(struct midi_provider *p) { - struct win32mm_midi *data; + struct win32mm_midi *data; - UINT i; - UINT mmin, mmout; - WORD r; - - mmin = midiInGetNumDevs(); - for (i = last_known_in_port; i < mmin; i++) { - data = mem_alloc(sizeof(struct win32mm_midi)); - memset(data,0,sizeof(struct win32mm_midi)); - r = midiInGetDevCaps(i, (LPMIDIINCAPS)&data->icp, - sizeof(MIDIINCAPS)); - if (r != MMSYSERR_NOERROR) { - free(data); - continue; - } - data->id = i; - midi_port_register(p, MIDI_INPUT, data->icp.szPname, data, 1); - } - last_known_in_port = mmin; - - mmout = midiOutGetNumDevs(); - for (i = last_known_out_port; i < mmout; i++) { - data = mem_alloc(sizeof(struct win32mm_midi)); - memset(data,0,sizeof(struct win32mm_midi)); - r = midiOutGetDevCaps(i, (LPMIDIOUTCAPS)&data->ocp, - sizeof(MIDIOUTCAPS)); - if (r != MMSYSERR_NOERROR) { - if (data) free(data); - continue; - } - data->id = i; - midi_port_register(p, MIDI_OUTPUT, data->ocp.szPname, data, 1); - } - last_known_out_port = mmout; + UINT i; + UINT mmin, mmout; + WORD r; + + mmin = midiInGetNumDevs(); + for (i = last_known_in_port; i < mmin; i++) { + data = mem_alloc(sizeof(struct win32mm_midi)); + memset(data,0,sizeof(struct win32mm_midi)); + r = midiInGetDevCaps(i, (LPMIDIINCAPS)&data->icp, + sizeof(MIDIINCAPS)); + if (r != MMSYSERR_NOERROR) { + free(data); + continue; + } + data->id = i; + midi_port_register(p, MIDI_INPUT, data->icp.szPname, data, 1); + } + last_known_in_port = mmin; + + mmout = midiOutGetNumDevs(); + for (i = last_known_out_port; i < mmout; i++) { + data = mem_alloc(sizeof(struct win32mm_midi)); + memset(data,0,sizeof(struct win32mm_midi)); + r = midiOutGetDevCaps(i, (LPMIDIOUTCAPS)&data->ocp, + sizeof(MIDIOUTCAPS)); + if (r != MMSYSERR_NOERROR) { + if (data) free(data); + continue; + } + data->id = i; + midi_port_register(p, MIDI_OUTPUT, data->ocp.szPname, data, 1); + } + last_known_out_port = mmout; } int win32mm_midi_setup(void) { - static struct midi_driver driver; - HINSTANCE winmm; - TIMECAPS caps; - - memset(&driver, 0, sizeof(driver)); - - driver.flags = 0; - driver.poll = _win32mm_poll; - driver.thread = NULL; - driver.enable = _win32mm_start; - driver.disable = _win32mm_stop; - - // FIXME: explanation required - winmm = GetModuleHandle("WINMM.DLL"); - if (!winmm) winmm = LoadLibrary("WINMM.DLL"); - if (!winmm) winmm = GetModuleHandle("WINMM.DLL"); - if (winmm) { - XP_timeGetDevCaps = (void*)GetProcAddress(winmm,"timeGetDevCaps"); - XP_timeBeginPeriod = (void*)GetProcAddress(winmm,"timeBeginPeriod"); - XP_timeSetEvent = (void*)GetProcAddress(winmm,"timeSetEvent"); - - if (XP_timeSetEvent && XP_timeBeginPeriod && XP_timeSetEvent) { - if (XP_timeGetDevCaps(&caps, sizeof(caps)) == 0) { - mm_period = caps.wPeriodMin; - if (XP_timeBeginPeriod(mm_period) == 0) { - driver.send = _win32mm_send_xp; - driver.flags |= MIDI_PORT_CAN_SCHEDULE; - } else { - driver.send = _win32mm_send; - log_appendf(4, "Cannot install WINMM timer (midi output will skip)"); - } - } else { - driver.send = _win32mm_send; - log_appendf(4, "Cannot get WINMM timer capabilities (midi output will skip)"); - } - } else { - driver.send = _win32mm_send; - log_appendf(4, "WINMM is too old a version (midi output will skip)"); - } - } else { - driver.send = _win32mm_send; - log_appendf(4, "WINMM is not installed (midi output will skip)"); - } + static struct midi_driver driver; + + TIMECAPS caps; + + memset(&driver, 0, sizeof(driver)); + + driver.flags = 0; + driver.poll = _win32mm_poll; + driver.thread = NULL; + driver.enable = _win32mm_start; + driver.disable = _win32mm_stop; + + { + if (timeGetDevCaps(&caps, sizeof(caps)) == 0) { + mm_period = caps.wPeriodMin; + if (timeBeginPeriod(mm_period) == 0) { + driver.send = _win32mm_send_xp; + driver.flags |= MIDI_PORT_CAN_SCHEDULE; + } else { + driver.send = _win32mm_send; + log_appendf(4, "Cannot install WINMM timer (midi output will skip)"); + } + } else { + driver.send = _win32mm_send; + log_appendf(4, "Cannot get WINMM timer capabilities (midi output will skip)"); + } + } - if (!midi_provider_register("Win32MM", &driver)) return 0; + if (!midi_provider_register("Win32MM", &driver)) return 0; - return 1; + return 1; } diff -Nru schism-0+20110101/sys/win32/osdefs.c schism-20160521/sys/win32/osdefs.c --- schism-0+20110101/sys/win32/osdefs.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/osdefs.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -34,39 +34,39 @@ /* eek... */ void win32_get_modkey(int *mk) { - BYTE ks[256]; - if (GetKeyboardState(ks) == 0) return; + BYTE ks[256]; + if (GetKeyboardState(ks) == 0) return; - if (ks[VK_CAPITAL] & 128) { - status.flags |= CAPS_PRESSED; - } else { - status.flags &= ~CAPS_PRESSED; - } - - (*mk) = ((*mk) & ~(KMOD_NUM|KMOD_CAPS)) - | ((ks[VK_NUMLOCK]&1) ? KMOD_NUM : 0) - | ((ks[VK_CAPITAL]&1) ? KMOD_CAPS : 0); + if (ks[VK_CAPITAL] & 128) { + status.flags |= CAPS_PRESSED; + } else { + status.flags &= ~CAPS_PRESSED; + } + + (*mk) = ((*mk) & ~(KMOD_NUM|KMOD_CAPS)) + | ((ks[VK_NUMLOCK]&1) ? KMOD_NUM : 0) + | ((ks[VK_CAPITAL]&1) ? KMOD_CAPS : 0); } /* more windows key stuff... */ unsigned int key_repeat_rate(void) { - DWORD spd; - if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &spd, 0)) return 0; - if (!spd) return 1; - return spd; + DWORD spd; + if (!SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &spd, 0)) return 0; + if (!spd) return 1; + return spd; } unsigned int key_repeat_delay(void) { - int delay; + int delay; - if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0)) return 0; - switch (delay) { - case 0: return 250; - case 1: return 500; - case 2: return 750; - }; - return 1000; + if (!SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0)) return 0; + switch (delay) { + case 0: return 250; + case 1: return 500; + case 2: return 750; + }; + return 1000; } static HKL default_keymap; @@ -74,9 +74,9 @@ static void win32_setup_keymap(void) { - default_keymap = GetKeyboardLayout(0); - us_keymap = LoadKeyboardLayout("00000409", KLF_ACTIVATE|KLF_REPLACELANG|KLF_NOTELLSHELL); - ActivateKeyboardLayout(default_keymap,0); + default_keymap = GetKeyboardLayout(0); + us_keymap = LoadKeyboardLayout("00000409", KLF_ACTIVATE|KLF_REPLACELANG|KLF_NOTELLSHELL); + ActivateKeyboardLayout(default_keymap,0); } int key_scancode_lookup(int k, int def) @@ -134,65 +134,65 @@ #define VK_APOSTROPHE 0xDE #define VK_BACKTICK 0xDF #define VK_OEM_102 0xE2 - switch (MapVirtualKeyEx(k, 1 /* MAPVK_VSC_TO_VK */, us_keymap)) { - case VK_0: return SDLK_0; - case VK_1: return SDLK_1; - case VK_2: return SDLK_2; - case VK_3: return SDLK_3; - case VK_4: return SDLK_4; - case VK_5: return SDLK_5; - case VK_6: return SDLK_6; - case VK_7: return SDLK_7; - case VK_8: return SDLK_8; - case VK_9: return SDLK_9; - case VK_A: return SDLK_a; - case VK_B: return SDLK_b; - case VK_C: return SDLK_c; - case VK_D: return SDLK_d; - case VK_E: return SDLK_e; - case VK_F: return SDLK_f; - case VK_G: return SDLK_g; - case VK_H: return SDLK_h; - case VK_I: return SDLK_i; - case VK_J: return SDLK_j; - case VK_K: return SDLK_k; - case VK_L: return SDLK_l; - case VK_M: return SDLK_m; - case VK_N: return SDLK_n; - case VK_O: return SDLK_o; - case VK_P: return SDLK_p; - case VK_Q: return SDLK_q; - case VK_R: return SDLK_r; - case VK_S: return SDLK_s; - case VK_T: return SDLK_t; - case VK_U: return SDLK_u; - case VK_V: return SDLK_v; - case VK_W: return SDLK_w; - case VK_X: return SDLK_x; - case VK_Y: return SDLK_y; - case VK_Z: return SDLK_z; - case VK_SEMICOLON: return SDLK_SEMICOLON; - case VK_GRAVE: return SDLK_BACKQUOTE; - case VK_APOSTROPHE: return SDLK_QUOTE; - case VK_BACKTICK: return SDLK_BACKQUOTE; - case VK_BACKSLASH: return SDLK_BACKSLASH; - case VK_LBRACKET: return SDLK_LEFTBRACKET; - case VK_RBRACKET: return SDLK_RIGHTBRACKET; - }; - return def; + switch (MapVirtualKeyEx(k, 1 /* MAPVK_VSC_TO_VK */, us_keymap)) { + case VK_0: return SDLK_0; + case VK_1: return SDLK_1; + case VK_2: return SDLK_2; + case VK_3: return SDLK_3; + case VK_4: return SDLK_4; + case VK_5: return SDLK_5; + case VK_6: return SDLK_6; + case VK_7: return SDLK_7; + case VK_8: return SDLK_8; + case VK_9: return SDLK_9; + case VK_A: return SDLK_a; + case VK_B: return SDLK_b; + case VK_C: return SDLK_c; + case VK_D: return SDLK_d; + case VK_E: return SDLK_e; + case VK_F: return SDLK_f; + case VK_G: return SDLK_g; + case VK_H: return SDLK_h; + case VK_I: return SDLK_i; + case VK_J: return SDLK_j; + case VK_K: return SDLK_k; + case VK_L: return SDLK_l; + case VK_M: return SDLK_m; + case VK_N: return SDLK_n; + case VK_O: return SDLK_o; + case VK_P: return SDLK_p; + case VK_Q: return SDLK_q; + case VK_R: return SDLK_r; + case VK_S: return SDLK_s; + case VK_T: return SDLK_t; + case VK_U: return SDLK_u; + case VK_V: return SDLK_v; + case VK_W: return SDLK_w; + case VK_X: return SDLK_x; + case VK_Y: return SDLK_y; + case VK_Z: return SDLK_z; + case VK_SEMICOLON: return SDLK_SEMICOLON; + case VK_GRAVE: return SDLK_BACKQUOTE; + case VK_APOSTROPHE: return SDLK_QUOTE; + case VK_BACKTICK: return SDLK_BACKQUOTE; + case VK_BACKSLASH: return SDLK_BACKSLASH; + case VK_LBRACKET: return SDLK_LEFTBRACKET; + case VK_RBRACKET: return SDLK_RIGHTBRACKET; + }; + return def; } void win32_sysinit(UNUSED int *pargc, UNUSED char ***pargv) { - static WSADATA ignored; + static WSADATA ignored; - win32_setup_keymap(); + win32_setup_keymap(); - memset(&ignored, 0, sizeof(ignored)); - if (WSAStartup(0x202, &ignored) == SOCKET_ERROR) { - WSACleanup(); /* ? */ - status.flags |= NO_NETWORK; - } + memset(&ignored, 0, sizeof(ignored)); + if (WSAStartup(0x202, &ignored) == SOCKET_ERROR) { + WSACleanup(); /* ? */ + status.flags |= NO_NETWORK; + } } diff -Nru schism-0+20110101/sys/win32/schismres.rc schism-20160521/sys/win32/schismres.rc --- schism-0+20110101/sys/win32/schismres.rc 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/schismres.rc 2016-05-21 14:40:41.000000000 +0000 @@ -6,37 +6,28 @@ # define WRC_VERSION 0,0,0,0 #endif -#ifdef HG_VERSION -# define WRC_PRODUCTVER_STR "hg:" HG_VERSION -#else -# define WRC_PRODUCTVER_STR PACKAGE_VERSION -#endif +#define WRC_PRODUCTVER_STR PACKAGE_VERSION #define VER_PRODUCTNAME "Schism Tracker" schismicon ICON "icons/schismres.ico" -VS_VERSION_INFO VERSIONINFO -FILEVERSION WRC_VERSION -PRODUCTVERSION WRC_VERSION // what's the difference? -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -/* Ideally we'd put -DNDEBUG and the like on the rc command line, but since -those are all stuffed into CFLAGS along with all the -W options and various -other stuff not applicable to windres, it's kinda more trouble than it's -worth to handle that -- so as much as it'd be neat to set the prerelease, -debug / private build flags, it's just too much effort for no real gain. */ -FILEFLAGS 0 - -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_APP +VS_VERSION_INFO VERSIONINFO +FILEVERSION WRC_VERSION +PRODUCTVERSION WRC_VERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +FILEFLAGS 0 +FILEOS VOS__WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "Storlek" - VALUE "LegalCopyright", "Copyright \xA9 2003-2011 Storlek" + VALUE "LegalCopyright", "Copyright \xA9 2003-2012 Storlek" VALUE "Comments", "http://schismtracker.org/" VALUE "ProductName", VER_PRODUCTNAME VALUE "FileDescription", VER_PRODUCTNAME diff -Nru schism-0+20110101/sys/win32/slurp-win32.c schism-20160521/sys/win32/slurp-win32.c --- schism-0+20110101/sys/win32/slurp-win32.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/slurp-win32.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -37,56 +37,51 @@ static void _win32_unmap(slurp_t *useme) { - HANDLE *bp; - (void)UnmapViewOfFile((LPVOID)useme->data); + HANDLE *bp; + (void)UnmapViewOfFile((LPVOID)useme->data); - bp = (HANDLE*)useme->bextra; - CloseHandle(bp[0]); - CloseHandle(bp[1]); - free(bp); + bp = (HANDLE*)useme->bextra; + CloseHandle(bp[0]); + CloseHandle(bp[1]); + free(bp); } int slurp_win32(slurp_t *useme, const char *filename, size_t st) { - HANDLE h, m, *bp; - LPVOID addr; - SECURITY_ATTRIBUTES sa; - - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = 0; - - bp = (HANDLE*)mem_alloc(sizeof(HANDLE)*2); - - h = CreateFile(filename, GENERIC_READ, - FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (!h) { - log_appendf(4, "CreateFile(%s) failed with %lu", filename, - GetLastError()); - free(bp); - return 0; - } - - m = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL); - if (!h) { - log_appendf(4, "CreateFileMapping failed with %lu", GetLastError()); - CloseHandle(h); - free(bp); - return -1; - } - addr = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0); - if (!addr) { - log_appendf(4, "MapViewOfFile failed with %lu", GetLastError()); - CloseHandle(m); - CloseHandle(h); - free(bp); - return -1; - } - useme->data = addr; - useme->length = st; - useme->closure = _win32_unmap; - - bp[0] = m; bp[1] = h; - useme->bextra = bp; - return 1; + HANDLE h, m, *bp; + LPVOID addr; + + bp = (HANDLE*)mem_alloc(sizeof(HANDLE)*2); + + h = CreateFile(filename, GENERIC_READ, + FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (!h) { + log_appendf(4, "CreateFile(%s) failed with %lu", filename, + GetLastError()); + free(bp); + return 0; + } + + m = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL); + if (!h) { + log_appendf(4, "CreateFileMapping failed with %lu", GetLastError()); + CloseHandle(h); + free(bp); + return -1; + } + addr = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0); + if (!addr) { + log_appendf(4, "MapViewOfFile failed with %lu", GetLastError()); + CloseHandle(m); + CloseHandle(h); + free(bp); + return -1; + } + useme->data = addr; + useme->length = st; + useme->closure = _win32_unmap; + + bp[0] = m; bp[1] = h; + useme->bextra = bp; + return 1; } diff -Nru schism-0+20110101/sys/win32/volume-win32mm.c schism-20160521/sys/win32/volume-win32mm.c --- schism-0+20110101/sys/win32/volume-win32mm.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/volume-win32mm.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -42,58 +42,50 @@ int win32mm_volume_get_max(void) { - return 0xFF; + return 0xFF; } static HWAVEOUT open_mixer(void) { - HWAVEOUT hwo=NULL; - WAVEFORMATEX pwfx; + HWAVEOUT hwo=NULL; + WAVEFORMATEX pwfx; #if 0 - pwfx.wFormatTag = WAVE_FORMAT_UNKNOWN; - pwfx.nChannels = 0; - pwfx.nSamplesPerSec = 0; - pwfx.wBitsPerSample = 0; - pwfx.nBlockAlign = 0; - pwfx.nAvgBytesPerSec = 0; - pwfx.cbSize = 0; + pwfx.wFormatTag = WAVE_FORMAT_UNKNOWN; + pwfx.nChannels = 0; + pwfx.nSamplesPerSec = 0; + pwfx.wBitsPerSample = 0; + pwfx.nBlockAlign = 0; + pwfx.nAvgBytesPerSec = 0; + pwfx.cbSize = 0; #else - pwfx.wFormatTag = WAVE_FORMAT_PCM; - pwfx.nChannels = 1; - pwfx.nSamplesPerSec = 44100; - pwfx.wBitsPerSample = 8; - pwfx.nBlockAlign = 4; - pwfx.nAvgBytesPerSec = 44100*1*1; - pwfx.cbSize = 0; + pwfx.wFormatTag = WAVE_FORMAT_PCM; + pwfx.nChannels = 1; + pwfx.nSamplesPerSec = 44100; + pwfx.wBitsPerSample = 8; + pwfx.nBlockAlign = 4; + pwfx.nAvgBytesPerSec = 44100*1*1; + pwfx.cbSize = 0; #endif - if (waveOutOpen(&hwo, WAVE_MAPPER, &pwfx, 0, 0, CALLBACK_NULL)!=MMSYSERR_NOERROR) - return NULL; - return hwo; + if (waveOutOpen(&hwo, WAVE_MAPPER, &pwfx, 0, 0, CALLBACK_NULL)!=MMSYSERR_NOERROR) + return NULL; + return hwo; } void win32mm_volume_read(int *left, int *right) { - DWORD vol; - HWAVEOUT hwo=open_mixer(); + DWORD vol; - *left = *right = 0; - if (!hwo) return; + *left = *right = 0; - waveOutGetVolume(hwo,&vol); + waveOutGetVolume(NULL,&vol); - *left = (vol & 0xFFFF) >> 8; - *right = (vol >> 16) >> 8; - - waveOutClose(hwo); + *left = (vol & 0xFFFF) >> 8; + *right = (vol >> 16) >> 8; } void win32mm_volume_write(int left, int right) { - DWORD vol = ((left & 0xFF)<<8) | ((right & 0xFF)<<(16+8)); - HWAVEOUT hwo = open_mixer(); - if (!hwo) return; - - waveOutSetVolume(hwo,vol); + DWORD vol = ((left & 0xFF)<<8) | ((right & 0xFF)<<(16+8)); - waveOutClose(hwo); + waveOutSetVolume(NULL,vol); } diff -Nru schism-0+20110101/sys/win32/wine-ddraw.h schism-20160521/sys/win32/wine-ddraw.h --- schism-0+20110101/sys/win32/wine-ddraw.h 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/win32/wine-ddraw.h 2016-05-21 14:40:41.000000000 +0000 @@ -324,7 +324,7 @@ #define DDSCAPS_OPTIMIZED 0x80000000 typedef struct _DDSCAPS { - DWORD dwCaps; /* capabilities of surface wanted */ + DWORD dwCaps; /* capabilities of surface wanted */ } DDSCAPS,*LPDDSCAPS; /* DDSCAPS2.dwCaps2 */ @@ -355,11 +355,11 @@ #define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 /* specifies all faces of a cube for CreateSurface() */ #define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX |\ - DDSCAPS2_CUBEMAP_NEGATIVEX |\ - DDSCAPS2_CUBEMAP_POSITIVEY |\ - DDSCAPS2_CUBEMAP_NEGATIVEY |\ - DDSCAPS2_CUBEMAP_POSITIVEZ |\ - DDSCAPS2_CUBEMAP_NEGATIVEZ ) + DDSCAPS2_CUBEMAP_NEGATIVEX |\ + DDSCAPS2_CUBEMAP_POSITIVEY |\ + DDSCAPS2_CUBEMAP_NEGATIVEY |\ + DDSCAPS2_CUBEMAP_POSITIVEZ |\ + DDSCAPS2_CUBEMAP_NEGATIVEZ ) /* set for mipmap sublevels on DirectX7 and later. ignored by CreateSurface() */ #define DDSCAPS2_MIPMAPSUBLEVEL 0x00010000 /* indicates texture surface to be managed by Direct3D *only* */ @@ -370,10 +370,10 @@ #define DDSCAPS2_STEREOSURFACELEFT 0x00080000 typedef struct _DDSCAPS2 { - DWORD dwCaps; /* capabilities of surface wanted */ - DWORD dwCaps2; /* additional capabilities */ - DWORD dwCaps3; /* reserved capabilities */ - DWORD dwCaps4; /* more reserved capabilities */ + DWORD dwCaps; /* capabilities of surface wanted */ + DWORD dwCaps2; /* additional capabilities */ + DWORD dwCaps3; /* reserved capabilities */ + DWORD dwCaps4; /* more reserved capabilities */ } DDSCAPS2,*LPDDSCAPS2; #define DD_ROP_SPACE (256/32) /* space required to store ROP array */ @@ -702,12 +702,12 @@ typedef struct _DDCOLORKEY { - DWORD dwColorSpaceLowValue;/* low boundary of color space that is to - * be treated as Color Key, inclusive - */ - DWORD dwColorSpaceHighValue;/* high boundary of color space that is - * to be treated as Color Key, inclusive - */ + DWORD dwColorSpaceLowValue;/* low boundary of color space that is to + * be treated as Color Key, inclusive + */ + DWORD dwColorSpaceHighValue;/* high boundary of color space that is + * to be treated as Color Key, inclusive + */ } DDCOLORKEY,*LPDDCOLORKEY; /* ddCKEYCAPS bits */ @@ -736,40 +736,40 @@ DWORD dwFlags; /* 4: pixel format flags */ DWORD dwFourCC; /* 8: (FOURCC code) */ union { - DWORD dwRGBBitCount; /* C: how many bits per pixel */ - DWORD dwYUVBitCount; /* C: how many bits per pixel */ - DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */ - DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/ - DWORD dwLuminanceBitCount; - DWORD dwBumpBitCount; + DWORD dwRGBBitCount; /* C: how many bits per pixel */ + DWORD dwYUVBitCount; /* C: how many bits per pixel */ + DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */ + DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/ + DWORD dwLuminanceBitCount; + DWORD dwBumpBitCount; } DUMMYUNIONNAME1; union { - DWORD dwRBitMask; /* 10: mask for red bit*/ - DWORD dwYBitMask; /* 10: mask for Y bits*/ - DWORD dwStencilBitDepth; - DWORD dwLuminanceBitMask; - DWORD dwBumpDuBitMask; + DWORD dwRBitMask; /* 10: mask for red bit*/ + DWORD dwYBitMask; /* 10: mask for Y bits*/ + DWORD dwStencilBitDepth; + DWORD dwLuminanceBitMask; + DWORD dwBumpDuBitMask; } DUMMYUNIONNAME2; union { - DWORD dwGBitMask; /* 14: mask for green bits*/ - DWORD dwUBitMask; /* 14: mask for U bits*/ - DWORD dwZBitMask; - DWORD dwBumpDvBitMask; + DWORD dwGBitMask; /* 14: mask for green bits*/ + DWORD dwUBitMask; /* 14: mask for U bits*/ + DWORD dwZBitMask; + DWORD dwBumpDvBitMask; } DUMMYUNIONNAME3; union { - DWORD dwBBitMask; /* 18: mask for blue bits*/ - DWORD dwVBitMask; /* 18: mask for V bits*/ - DWORD dwStencilBitMask; - DWORD dwBumpLuminanceBitMask; + DWORD dwBBitMask; /* 18: mask for blue bits*/ + DWORD dwVBitMask; /* 18: mask for V bits*/ + DWORD dwStencilBitMask; + DWORD dwBumpLuminanceBitMask; } DUMMYUNIONNAME4; union { - DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ - DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ - DWORD dwLuminanceAlphaBitMask; - DWORD dwRGBZBitMask; /* 1C: mask for Z channel */ - DWORD dwYUVZBitMask; /* 1C: mask for Z channel */ + DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ + DWORD dwLuminanceAlphaBitMask; + DWORD dwRGBZBitMask; /* 1C: mask for Z channel */ + DWORD dwYUVZBitMask; /* 1C: mask for Z channel */ } DUMMYUNIONNAME5; - /* 20: next structure */ + /* 20: next structure */ } DDPIXELFORMAT,*LPDDPIXELFORMAT; #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ @@ -967,64 +967,64 @@ typedef struct _DDSURFACEDESC { - DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ - DWORD dwFlags; /* 4: determines what fields are valid*/ - DWORD dwHeight; /* 8: height of surface to be created*/ - DWORD dwWidth; /* C: width of input surface*/ - union { - LONG lPitch; /* 10: distance to start of next line (return value only)*/ - DWORD dwLinearSize; - } DUMMYUNIONNAME1; - DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ - union { - DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ - DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/ - DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ - } DUMMYUNIONNAME2; - DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ - DWORD dwReserved; /* 20:reserved*/ - LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ - DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/ - DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ - DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ - DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ - DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ - DDSCAPS ddsCaps; /* 68: direct draw surface caps */ + DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /* 10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/ + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DDSCAPS ddsCaps; /* 68: direct draw surface caps */ } DDSURFACEDESC,*LPDDSURFACEDESC; typedef struct _DDSURFACEDESC2 { - DWORD dwSize; /* 0: size of the DDSURFACEDESC2 structure*/ - DWORD dwFlags; /* 4: determines what fields are valid*/ - DWORD dwHeight; /* 8: height of surface to be created*/ - DWORD dwWidth; /* C: width of input surface*/ - union { - LONG lPitch; /*10: distance to start of next line (return value only)*/ - DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */ - } DUMMYUNIONNAME1; - DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ - union { - DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ - DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ - DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */ - } DUMMYUNIONNAME2; - DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ - DWORD dwReserved; /* 20:reserved*/ - LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ - union { - DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ - DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */ - } DUMMYUNIONNAME3; - DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ - DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ - DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ - - union { - DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ - DWORD dwFVF; /* 48: vertex format description of vertex buffers */ - } DUMMYUNIONNAME4; - DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ - DWORD dwTextureStage; /* 78: stage in multitexture cascade */ + DWORD dwSize; /* 0: size of the DDSURFACEDESC2 structure*/ + DWORD dwFlags; /* 4: determines what fields are valid*/ + DWORD dwHeight; /* 8: height of surface to be created*/ + DWORD dwWidth; /* C: width of input surface*/ + union { + LONG lPitch; /*10: distance to start of next line (return value only)*/ + DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */ + } DUMMYUNIONNAME1; + DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ + union { + DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ + DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ + DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */ + } DUMMYUNIONNAME2; + DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ + DWORD dwReserved; /* 20:reserved*/ + LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ + union { + DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ + DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */ + } DUMMYUNIONNAME3; + DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ + DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ + DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ + + union { + DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ + DWORD dwFVF; /* 48: vertex format description of vertex buffers */ + } DUMMYUNIONNAME4; + DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ + DWORD dwTextureStage; /* 78: stage in multitexture cascade */ } DDSURFACEDESC2,*LPDDSURFACEDESC2; /* DDCOLORCONTROL.dwFlags */ @@ -1037,22 +1037,22 @@ #define DDCOLOR_COLORENABLE 0x00000040 typedef struct { - DWORD dwSize; - DWORD dwFlags; - LONG lBrightness; - LONG lContrast; - LONG lHue; - LONG lSaturation; - LONG lSharpness; - LONG lGamma; - LONG lColorEnable; - DWORD dwReserved1; + DWORD dwSize; + DWORD dwFlags; + LONG lBrightness; + LONG lContrast; + LONG lHue; + LONG lSaturation; + LONG lSharpness; + LONG lGamma; + LONG lColorEnable; + DWORD dwReserved1; } DDCOLORCONTROL,*LPDDCOLORCONTROL; typedef struct { - WORD red[256]; - WORD green[256]; - WORD blue[256]; + WORD red[256]; + WORD green[256]; + WORD blue[256]; } DDGAMMARAMP,*LPDDGAMMARAMP; typedef BOOL (CALLBACK *LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID); @@ -1101,14 +1101,14 @@ DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */ union { - DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ - LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ + DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ + LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ } DUMMYUNIONNAME1; DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */ union { - DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ - LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ + DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ + LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ } DUMMYUNIONNAME2; DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */ @@ -1116,21 +1116,21 @@ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ union { - DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ - LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ + DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ } DUMMYUNIONNAME3; DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ union { - DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ + DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ } DUMMYUNIONNAME4; union { - DWORD dwFillColor; /* color in RGB or Palettized */ - DWORD dwFillDepth; /* depth value for z-buffer */ - DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */ - LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ + DWORD dwFillColor; /* color in RGB or Palettized */ + DWORD dwFillDepth; /* depth value for z-buffer */ + DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */ + LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ } DUMMYUNIONNAME5; DDCOLORKEY ddckDestColorkey; /* DestColorkey override */ DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */ @@ -1165,14 +1165,14 @@ DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ union { - DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ - LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ + DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ + LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ } DUMMYUNIONNAME1; DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ union { - DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ + DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ + LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ } DUMMYUNIONNAME2; DDCOLORKEY dckDestColorkey; /* DestColorkey override */ DDCOLORKEY dckSrcColorkey; /* DestColorkey override */ @@ -1413,11 +1413,11 @@ #define INTERFACE IDirectDraw2 DECLARE_INTERFACE_(IDirectDraw2,IUnknown) { - /*** IUnknown methods ***/ + /*** IUnknown methods ***/ /*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; /*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE; /*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectDraw2 methods ***/ + /*** IDirectDraw2 methods ***/ /*0c*/ STDMETHOD(Compact)(THIS) PURE; /*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE; /*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE; @@ -1438,7 +1438,7 @@ /*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; /*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; /*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - /* added in v2 */ + /* added in v2 */ /*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; }; #undef INTERFACE @@ -1508,11 +1508,11 @@ #define INTERFACE IDirectDraw3 DECLARE_INTERFACE_(IDirectDraw3,IUnknown) { - /*** IUnknown methods ***/ + /*** IUnknown methods ***/ /*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; /*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE; /*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectDraw2 methods ***/ + /*** IDirectDraw2 methods ***/ /*0c*/ STDMETHOD(Compact)(THIS) PURE; /*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE; /*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE; @@ -1533,9 +1533,9 @@ /*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; /*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; /*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - /* added in v2 */ + /* added in v2 */ /*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; - /* added in v3 */ + /* added in v3 */ /*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE *pSurf) PURE; }; #undef INTERFACE @@ -1609,11 +1609,11 @@ #define INTERFACE IDirectDraw4 DECLARE_INTERFACE_(IDirectDraw4,IUnknown) { - /*** IUnknown methods ***/ + /*** IUnknown methods ***/ /*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; /*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE; /*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectDraw4 methods ***/ + /*** IDirectDraw4 methods ***/ /*0c*/ STDMETHOD(Compact)(THIS) PURE; /*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE; /*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE; @@ -1634,9 +1634,9 @@ /*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; /*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; /*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - /* added in v2 */ + /* added in v2 */ /*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; - /* added in v4 */ + /* added in v4 */ /*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE4 *pSurf) PURE; /*64*/ STDMETHOD(RestoreAllSurfaces)(THIS) PURE; /*68*/ STDMETHOD(TestCooperativeLevel)(THIS) PURE; @@ -1722,11 +1722,11 @@ #define INTERFACE IDirectDraw7 DECLARE_INTERFACE_(IDirectDraw7,IUnknown) { - /*** IUnknown methods ***/ + /*** IUnknown methods ***/ /*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; /*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE; /*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectDraw7 methods ***/ + /*** IDirectDraw7 methods ***/ /*0c*/ STDMETHOD(Compact)(THIS) PURE; /*10*/ STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, IUnknown *pUnkOuter) PURE; /*14*/ STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE *lplpDDPalette, IUnknown *pUnkOuter) PURE; @@ -1747,14 +1747,14 @@ /*50*/ STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; /*54*/ STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; /*58*/ STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - /* added in v2 */ + /* added in v2 */ /*5c*/ STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; - /* added in v4 */ + /* added in v4 */ /*60*/ STDMETHOD(GetSurfaceFromDC)(THIS_ HDC hdc, LPDIRECTDRAWSURFACE7 *pSurf) PURE; /*64*/ STDMETHOD(RestoreAllSurfaces)(THIS) PURE; /*68*/ STDMETHOD(TestCooperativeLevel)(THIS) PURE; /*6c*/ STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2 pDDDI, DWORD dwFlags) PURE; - /* added in v7 */ + /* added in v7 */ /*70*/ STDMETHOD(StartModeTest)(THIS_ LPSIZE pModes, DWORD dwNumModes, DWORD dwFlags) PURE; /*74*/ STDMETHOD(EvaluateMode)(THIS_ DWORD dwFlags, DWORD *pTimeout) PURE; }; @@ -1841,11 +1841,11 @@ #define INTERFACE IDirectDrawSurface DECLARE_INTERFACE_(IDirectDrawSurface,IUnknown) { - /*** IUnknown methods ***/ + /*** IUnknown methods ***/ /*00*/ STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; /*04*/ STDMETHOD_(ULONG,AddRef)(THIS) PURE; /*08*/ STDMETHOD_(ULONG,Release)(THIS) PURE; - /*** IDirectDrawSurface methods ***/ + /*** IDirectDrawSurface methods ***/ /*0c*/ STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE; /*10*/ STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; /*14*/ STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; diff -Nru schism-0+20110101/sys/x11/xkb.c schism-20160521/sys/x11/xkb.c --- schism-0+20110101/sys/x11/xkb.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/x11/xkb.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -45,85 +45,85 @@ static void _key_info_setup(void) { - Display *dpy; - SDL_SysWMinfo info; + Display *dpy; + SDL_SysWMinfo info; - if (!virgin) return; - virgin = 0; + if (!virgin) return; + virgin = 0; - memset(&info, 0, sizeof(info)); - SDL_VERSION(&info.version); - if (SDL_GetWMInfo(&info)) { - if (info.info.x11.lock_func) - info.info.x11.lock_func(); - dpy = info.info.x11.display; - } else { - dpy = NULL; - } - if (!dpy) { - dpy = XOpenDisplay(NULL); - if (!dpy) return; - memset(&info, 0, sizeof(info)); - } + memset(&info, 0, sizeof(info)); + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info)) { + if (info.info.x11.lock_func) + info.info.x11.lock_func(); + dpy = info.info.x11.display; + } else { + dpy = NULL; + } + if (!dpy) { + dpy = XOpenDisplay(NULL); + if (!dpy) return; + memset(&info, 0, sizeof(info)); + } #ifdef USE_XKB - /* Dear X11, - You suck. - Sincerely, Storlek */ - char blank[] = ""; - char symbols[] = "+us(basic)"; - XkbComponentNamesRec rec = { - .symbols = symbols, - .keymap = blank, - .keycodes = blank, - .types = blank, - .compat = blank, - .geometry = blank, - }; - us_kb_map = XkbGetKeyboardByName(dpy, XkbUseCoreKbd, &rec, - XkbGBN_AllComponentsMask, XkbGBN_AllComponentsMask, False); - if (!us_kb_map) - log_appendf(3, "Warning: XKB support missing or broken; keyjamming might not work right"); - - if (XkbGetAutoRepeatRate(dpy, XkbUseCoreKbd, &delay, &rate)) { - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); - return; - } + /* Dear X11, + You suck. + Sincerely, Storlek */ + char blank[] = ""; + char symbols[] = "+us(basic)"; + XkbComponentNamesRec rec = { + .symbols = symbols, + .keymap = blank, + .keycodes = blank, + .types = blank, + .compat = blank, + .geometry = blank, + }; + us_kb_map = XkbGetKeyboardByName(dpy, XkbUseCoreKbd, &rec, + XkbGBN_AllComponentsMask, XkbGBN_AllComponentsMask, False); + if (!us_kb_map) + log_appendf(3, "Warning: XKB support missing or broken; keyjamming might not work right"); + + if (XkbGetAutoRepeatRate(dpy, XkbUseCoreKbd, &delay, &rate)) { + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); + return; + } #else - log_appendf(3, "Warning: XKB support not compiled in; keyjamming might not work right"); + log_appendf(3, "Warning: XKB support not compiled in; keyjamming might not work right"); #endif - /* eh... */ - delay = 125; - rate = 30; + /* eh... */ + delay = 125; + rate = 30; - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); } unsigned int key_repeat_rate(void) { - _key_info_setup(); - return rate; + _key_info_setup(); + return rate; } unsigned int key_repeat_delay(void) { - _key_info_setup(); - return delay; + _key_info_setup(); + return delay; } #ifdef USE_XKB int key_scancode_lookup(int k, int def) { - static unsigned int d; - KeySym sym; + static unsigned int d; + KeySym sym; - if (us_kb_map != NULL && - XkbTranslateKeyCode(us_kb_map, k, 0, &d, &sym)) { - return sym; - } - return def; + if (us_kb_map != NULL && + XkbTranslateKeyCode(us_kb_map, k, 0, &d, &sym)) { + return sym; + } + return def; } #endif diff -Nru schism-0+20110101/sys/x11/xscreensaver.c schism-20160521/sys/x11/xscreensaver.c --- schism-0+20110101/sys/x11/xscreensaver.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/x11/xscreensaver.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -24,7 +24,7 @@ /* I wanted to just lift this code out of xscreensaver-command, but that wasn't really convenient. xscreensaver really should've had this (or something like it) as a simple library call like: - xscreensaver_synthetic_user_active(display); + xscreensaver_synthetic_user_active(display); or something like that. spawning a subprocess is really expensive on some systems, and might have subtle interactions with SDL or the player. @@ -47,129 +47,129 @@ static XErrorHandler old_handler = NULL; static int BadWindow_ehandler(Display *dpy, XErrorEvent *error) { - if (error->error_code == BadWindow) { - return 0; - } else { - if (old_handler) return (*old_handler)(dpy,error); - /* shrug */ - return 1; - } + if (error->error_code == BadWindow) { + return 0; + } else { + if (old_handler) return (*old_handler)(dpy,error); + /* shrug */ + return 1; + } } void x11_screensaver_deactivate(void) { - static Atom XA_SCREENSAVER_VERSION; - static Atom XA_DEACTIVATE; - static Atom XA_SCREENSAVER; - static int setup = 0; - static int useit = 0; - static SDL_SysWMinfo info; - - Window root, tmp, parent, *kids; - unsigned int nkids, i; - - static time_t lastpoll = 0; - Window win; - time_t now; - - Display *dpy = NULL; - XEvent ev; - - if (!setup) { - setup = 1; - SDL_GetWMInfo(&info); - dpy = info.info.x11.display; - if (!dpy) { - dpy = XOpenDisplay(NULL); - if (!dpy) return; - memset(&info, 0, sizeof(info)); - info.info.x11.display = dpy; - } - - useit = 1; - if (info.info.x11.lock_func) info.info.x11.lock_func(); - XA_SCREENSAVER = XInternAtom(dpy, "SCREENSAVER", False); - XA_SCREENSAVER_VERSION = XInternAtom(dpy, - "_SCREENSAVER_VERSION", False); - XA_DEACTIVATE = XInternAtom(dpy, "DEACTIVATE", False); - if (info.info.x11.unlock_func) info.info.x11.unlock_func(); - } - - if (!useit) return; - - time(&now); - if (!(lastpoll - now)) { - return; - } - lastpoll = now; - - if (info.info.x11.lock_func) - info.info.x11.lock_func(); - dpy = info.info.x11.display; - if (!dpy) { - useit = 0; - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); - return; - } - - root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy)); - if (!XQueryTree(dpy, root, &tmp, &parent, &kids, &nkids)) { - useit = 0; - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); - return; - } - if (root != tmp || parent || !(kids && nkids)) { - useit = 0; - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); - return; - } - - win = 0; - for (i = 0; i < nkids; i++) { - Atom type; - int format; - unsigned long nitems, bytesafter; - unsigned char *v = NULL; - - XSync(dpy, False); - old_handler = XSetErrorHandler(BadWindow_ehandler); - if (XGetWindowProperty(dpy, kids[i], - XA_SCREENSAVER_VERSION, 0, 200, - False, XA_STRING, &type, &format, - &nitems, &bytesafter, - (unsigned char **)&v) == Success) { - XSetErrorHandler(old_handler); - if (v) XFree(v); /* don't care */ - if (type != None) { - win = kids[i]; - break; - } - } - XSetErrorHandler(old_handler); - } - XFree(kids); - if (!win) { - useit = 0; - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); - return; - } - - ev.xany.type = ClientMessage; - ev.xclient.display = dpy; - ev.xclient.window = win; - ev.xclient.message_type = XA_SCREENSAVER; - ev.xclient.format = 32; - memset(&ev.xclient.data, 0, sizeof(ev.xclient.data)); - ev.xclient.data.l[0] = XA_DEACTIVATE; - ev.xclient.data.l[1] = 0; - ev.xclient.data.l[2] = 0; - (void)XSendEvent(dpy, win, False, 0L, &ev); - XSync(dpy, 0); - if (info.info.x11.unlock_func) - info.info.x11.unlock_func(); + static Atom XA_SCREENSAVER_VERSION; + static Atom XA_DEACTIVATE; + static Atom XA_SCREENSAVER; + static int setup = 0; + static int useit = 0; + static SDL_SysWMinfo info; + + Window root, tmp, parent, *kids; + unsigned int nkids, i; + + static time_t lastpoll = 0; + Window win; + time_t now; + + Display *dpy = NULL; + XEvent ev; + + if (!setup) { + setup = 1; + SDL_GetWMInfo(&info); + dpy = info.info.x11.display; + if (!dpy) { + dpy = XOpenDisplay(NULL); + if (!dpy) return; + memset(&info, 0, sizeof(info)); + info.info.x11.display = dpy; + } + + useit = 1; + if (info.info.x11.lock_func) info.info.x11.lock_func(); + XA_SCREENSAVER = XInternAtom(dpy, "SCREENSAVER", False); + XA_SCREENSAVER_VERSION = XInternAtom(dpy, + "_SCREENSAVER_VERSION", False); + XA_DEACTIVATE = XInternAtom(dpy, "DEACTIVATE", False); + if (info.info.x11.unlock_func) info.info.x11.unlock_func(); + } + + if (!useit) return; + + time(&now); + if (!(lastpoll - now)) { + return; + } + lastpoll = now; + + if (info.info.x11.lock_func) + info.info.x11.lock_func(); + dpy = info.info.x11.display; + if (!dpy) { + useit = 0; + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); + return; + } + + root = RootWindowOfScreen(DefaultScreenOfDisplay(dpy)); + if (!XQueryTree(dpy, root, &tmp, &parent, &kids, &nkids)) { + useit = 0; + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); + return; + } + if (root != tmp || parent || !(kids && nkids)) { + useit = 0; + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); + return; + } + + win = 0; + for (i = 0; i < nkids; i++) { + Atom type; + int format; + unsigned long nitems, bytesafter; + unsigned char *v = NULL; + + XSync(dpy, False); + old_handler = XSetErrorHandler(BadWindow_ehandler); + if (XGetWindowProperty(dpy, kids[i], + XA_SCREENSAVER_VERSION, 0, 200, + False, XA_STRING, &type, &format, + &nitems, &bytesafter, + (unsigned char **)&v) == Success) { + XSetErrorHandler(old_handler); + if (v) XFree(v); /* don't care */ + if (type != None) { + win = kids[i]; + break; + } + } + XSetErrorHandler(old_handler); + } + XFree(kids); + if (!win) { + useit = 0; + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); + return; + } + + ev.xany.type = ClientMessage; + ev.xclient.display = dpy; + ev.xclient.window = win; + ev.xclient.message_type = XA_SCREENSAVER; + ev.xclient.format = 32; + memset(&ev.xclient.data, 0, sizeof(ev.xclient.data)); + ev.xclient.data.l[0] = XA_DEACTIVATE; + ev.xclient.data.l[1] = 0; + ev.xclient.data.l[2] = 0; + (void)XSendEvent(dpy, win, False, 0L, &ev); + XSync(dpy, 0); + if (info.info.x11.unlock_func) + info.info.x11.unlock_func(); } diff -Nru schism-0+20110101/sys/x11/xv.c schism-20160521/sys/x11/xv.c --- schism-0+20110101/sys/x11/xv.c 2011-01-01 21:22:53.000000000 +0000 +++ schism-20160521/sys/x11/xv.c 2016-05-21 14:40:41.000000000 +0000 @@ -3,7 +3,7 @@ * copyright (c) 2003-2005 Storlek * copyright (c) 2005-2008 Mrs. Brisby * copyright (c) 2009 Storlek & Mrs. Brisby - * copyright (c) 2010-2011 Storlek + * copyright (c) 2010-2012 Storlek * URL: http://schismtracker.org/ * * This program is free software; you can redistribute it and/or modify @@ -36,104 +36,104 @@ unsigned int xv_yuvlayout(void) { - unsigned int ver, rev, eventB, reqB, errorB; - XvImageFormatValues *formats; - XvAdaptorInfo *ainfo; - XvEncodingInfo *encodings; - SDL_SysWMinfo info; - Display *dpy; - unsigned int nencode, nadaptors; - unsigned int fmt = VIDEO_YUV_NONE; - int numImages; - int screen, nscreens, img; - unsigned int adaptor, enc; - unsigned int w, h; - unsigned int best; - - memset(&info, 0, sizeof(info)); - SDL_VERSION(&info.version); - if (SDL_GetWMInfo(&info)) { - dpy = info.info.x11.display; - } else { - dpy = NULL; - printf("sdl_getwminfo?\n"); - } + unsigned int ver, rev, eventB, reqB, errorB; + XvImageFormatValues *formats; + XvAdaptorInfo *ainfo; + XvEncodingInfo *encodings; + SDL_SysWMinfo info; + Display *dpy; + unsigned int nencode, nadaptors; + unsigned int fmt = VIDEO_YUV_NONE; + int numImages; + int screen, nscreens, img; + unsigned int adaptor, enc; + unsigned int w, h; + unsigned int best; + + memset(&info, 0, sizeof(info)); + SDL_VERSION(&info.version); + if (SDL_GetWMInfo(&info)) { + dpy = info.info.x11.display; + } else { + dpy = NULL; + printf("sdl_getwminfo?\n"); + } - if (!dpy) { + if (!dpy) { #if 0 - /* this never closes the display, thus causing a memleak - (and we can't reasonably call XCloseDisplay ourselves) */ - dpy = XOpenDisplay(NULL); - if (!dpy) - return VIDEO_YUV_NONE; + /* this never closes the display, thus causing a memleak + (and we can't reasonably call XCloseDisplay ourselves) */ + dpy = XOpenDisplay(NULL); + if (!dpy) + return VIDEO_YUV_NONE; #else - return VIDEO_YUV_NONE; + return VIDEO_YUV_NONE; #endif - } + } - ver = rev = reqB = eventB = errorB = 0; - if (XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB) != Success) { - /* no XV support */ - return VIDEO_YUV_NONE; - } - - nscreens = ScreenCount(dpy); - w = h = 0; - for (screen = 0; screen < nscreens; screen++) { - XvQueryAdaptors(dpy, RootWindow(dpy, screen), &nadaptors, &ainfo); - for (adaptor = 0; adaptor < nadaptors; adaptor++) { - XvQueryEncodings(dpy, ainfo[adaptor].base_id, &nencode, &encodings); - best = nencode; // impossible value - for (enc = 0; enc < nencode; enc++) { - if (strcmp(encodings[enc].name, "XV_IMAGE") != 0) - continue; - if (encodings[enc].width > w || encodings[enc].height > h) { - w = encodings[enc].width; - h = encodings[enc].height; - best = enc; - } - } - XvFreeEncodingInfo(encodings); - - if (best == nencode || w < 640 || h < 400) - continue; - - formats = XvListImageFormats(dpy, ainfo[adaptor].base_id, &numImages); - for (img = 0; img < numImages; img++) { - if (formats[img].type == XvRGB) continue; - if (w < 1280 || h < 400) { - /* not enough xv memory for packed */ - switch (formats[img].id) { - case VIDEO_YUV_YV12: - fmt = VIDEO_YUV_YV12_TV; - break; - case VIDEO_YUV_IYUV: - fmt = VIDEO_YUV_IYUV_TV; - break; - } - continue; - } - switch (formats[img].id) { - case VIDEO_YUV_UYVY: - case VIDEO_YUV_YUY2: - case VIDEO_YUV_YVYU: - /* a packed format, and we have enough memory... */ - fmt = formats[img].id; - XFree(formats); - XvFreeAdaptorInfo(ainfo); - return fmt; - - case VIDEO_YUV_YV12: - case VIDEO_YUV_IYUV: - fmt = formats[img].id; - break; - } - } - XFree(formats); - } - XvFreeAdaptorInfo(ainfo); - } - return fmt; + ver = rev = reqB = eventB = errorB = 0; + if (XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB) != Success) { + /* no XV support */ + return VIDEO_YUV_NONE; + } + + nscreens = ScreenCount(dpy); + w = h = 0; + for (screen = 0; screen < nscreens; screen++) { + XvQueryAdaptors(dpy, RootWindow(dpy, screen), &nadaptors, &ainfo); + for (adaptor = 0; adaptor < nadaptors; adaptor++) { + XvQueryEncodings(dpy, ainfo[adaptor].base_id, &nencode, &encodings); + best = nencode; // impossible value + for (enc = 0; enc < nencode; enc++) { + if (strcmp(encodings[enc].name, "XV_IMAGE") != 0) + continue; + if (encodings[enc].width > w || encodings[enc].height > h) { + w = encodings[enc].width; + h = encodings[enc].height; + best = enc; + } + } + XvFreeEncodingInfo(encodings); + + if (best == nencode || w < 640 || h < 400) + continue; + + formats = XvListImageFormats(dpy, ainfo[adaptor].base_id, &numImages); + for (img = 0; img < numImages; img++) { + if (formats[img].type == XvRGB) continue; + if (w < 1280 || h < 400) { + /* not enough xv memory for packed */ + switch (formats[img].id) { + case VIDEO_YUV_YV12: + fmt = VIDEO_YUV_YV12_TV; + break; + case VIDEO_YUV_IYUV: + fmt = VIDEO_YUV_IYUV_TV; + break; + } + continue; + } + switch (formats[img].id) { + case VIDEO_YUV_UYVY: + case VIDEO_YUV_YUY2: + case VIDEO_YUV_YVYU: + /* a packed format, and we have enough memory... */ + fmt = formats[img].id; + XFree(formats); + XvFreeAdaptorInfo(ainfo); + return fmt; + + case VIDEO_YUV_YV12: + case VIDEO_YUV_IYUV: + fmt = formats[img].id; + break; + } + } + XFree(formats); + } + XvFreeAdaptorInfo(ainfo); + } + return fmt; } diff -Nru schism-0+20110101/TODO schism-20160521/TODO --- schism-0+20110101/TODO 2011-01-01 21:22:52.000000000 +0000 +++ schism-20160521/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -See http://schismtracker.org/wiki/TODO if you're actually interested