mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 08:41:59 +00:00
Merge remote-tracking branch 'origin/master' into openal
Conflicts: src/CMakeLists.txt
This commit is contained in:
commit
7ff7c151a8
433 changed files with 11726 additions and 6060 deletions
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -14,6 +14,7 @@
|
|||
/release_gcc
|
||||
/dumb/vc6/dumb_static/release
|
||||
/dumb/vc6/dumb_static/debug
|
||||
/dumb/vc6/dumb_static/x64
|
||||
/DOOMSTATS.TXT
|
||||
/src/gitinfo.h
|
||||
/src/sc_man_scanner.h
|
||||
|
@ -25,4 +26,14 @@
|
|||
/tools/*/*.exe
|
||||
/tools/lemon/build
|
||||
/tools/re2c/build
|
||||
/tools/updaterevision/x64/
|
||||
/tools/zipdir/x64
|
||||
/wadsrc/*.pk3
|
||||
/build_vc2013
|
||||
/bzip2/x64/
|
||||
/disasm.txt
|
||||
/game-music-emu/x64/
|
||||
/gdtoa/x64/
|
||||
/jpeg-6b/x64/
|
||||
/lzma/x64/
|
||||
/zlib/x64/
|
||||
|
|
103
CMakeLists.txt
103
CMakeLists.txt
|
@ -1,6 +1,10 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
project(ZDoom)
|
||||
|
||||
list( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} )
|
||||
include( CreateLaunchers )
|
||||
include( FindPackageHandleStandardArgs )
|
||||
|
||||
# Generator expression are available some time in CMake 2.8. Due to
|
||||
# cmake_minimum_required, we can assume a minor version of > 7 implies major >= 2
|
||||
if(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
|
||||
|
@ -9,6 +13,17 @@ else(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
|
|||
set( NO_GENERATOR_EXPRESSIONS ON )
|
||||
endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
|
||||
|
||||
# Support cross compiling
|
||||
option( FORCE_CROSSCOMPILE "Turn on cross compiling." NO )
|
||||
if( FORCE_CROSSCOMPILE )
|
||||
set( CMAKE_CROSSCOMPILING TRUE )
|
||||
endif( FORCE_CROSSCOMPILE )
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(IMPORT_EXECUTABLES "IMPORTFILE-NOTFOUND" CACHE FILEPATH "Export file from native build.")
|
||||
include(${IMPORT_EXECUTABLES})
|
||||
endif(CMAKE_CROSSCOMPILING)
|
||||
|
||||
# Simplify pk3 building, add_pk3(filename srcdirectory)
|
||||
function( add_pk3 PK3_NAME PK3_DIR )
|
||||
get_target_property(ZIPDIR_EXE zipdir LOCATION)
|
||||
|
@ -19,21 +34,34 @@ function( add_pk3 PK3_NAME PK3_DIR )
|
|||
set( PK3_TARGET "pk3" )
|
||||
endif( ${PK3_TARGET} STREQUAL "zdoom_pk3" )
|
||||
|
||||
if( NO_GENERATOR_EXPRESSIONS )
|
||||
if( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
||||
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>
|
||||
DEPENDS zipdir ${PK3_DIR} )
|
||||
else( NO_GENERATOR_EXPRESSIONS )
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>/${PK3_NAME}
|
||||
DEPENDS zipdir )
|
||||
else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
||||
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
||||
DEPENDS zipdir ${PK3_DIR} )
|
||||
endif( NO_GENERATOR_EXPRESSIONS )
|
||||
DEPENDS zipdir )
|
||||
endif( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||
|
||||
# Touch the zipdir executable here so that the pk3s are forced to rebuild
|
||||
# each time since their dependecy has "changed."
|
||||
add_custom_target( ${PK3_TARGET} ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${ZIPDIR_EXE}
|
||||
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
|
||||
endfunction( add_pk3 )
|
||||
|
||||
# Macro for building libraries without debugging information
|
||||
macro( make_release_only )
|
||||
set( CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_RELEASE} )
|
||||
set( CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELEASE} )
|
||||
string( REPLACE "/MT " "/MTd " CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_RELEASE} )
|
||||
set( CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
set( CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
string( REPLACE "/MT " "/MTd " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
endmacro( make_release_only )
|
||||
|
||||
IF( NOT CMAKE_BUILD_TYPE )
|
||||
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
|
||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||
|
@ -42,6 +70,13 @@ ENDIF( NOT CMAKE_BUILD_TYPE )
|
|||
|
||||
set( ZDOOM_OUTPUT_DIR ${CMAKE_BINARY_DIR} CACHE PATH "Directory where zdoom.pk3 and the executable will be created." )
|
||||
set( ZDOOM_EXE_NAME "zdoom" CACHE FILEPATH "Name of the executable to create." )
|
||||
if( MSVC )
|
||||
# Allow the user to use ZDOOM_OUTPUT_DIR as a single release point.
|
||||
# Use zdoom, zdoomd, zdoom64, and zdoomd64 for the binary names
|
||||
option( ZDOOM_OUTPUT_OLDSTYLE "Don't use Release/Debug directories." OFF )
|
||||
else( MSVC )
|
||||
set( ZDOOM_OUTPUT_OLDSTYLE OFF )
|
||||
endif( MSVC )
|
||||
|
||||
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||
set( PROFILE 0 CACHE BOOL "Enable profiling with gprof for Debug and RelWithDebInfo build types." )
|
||||
|
@ -55,22 +90,48 @@ option( NO_OPENAL "Disable OpenAL sound support" OFF )
|
|||
find_package( BZip2 )
|
||||
find_package( JPEG )
|
||||
find_package( ZLIB )
|
||||
# GME
|
||||
find_path( GME_INCLUDE_DIR gme.h )
|
||||
find_library( GME_LIBRARIES gme )
|
||||
mark_as_advanced( GME_INCLUDE_DIR GME_LIBRARIES )
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( GME
|
||||
REQUIRED_VARS GME_LIBRARIES GME_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if( MSVC )
|
||||
# Eliminate unreferenced functions and data
|
||||
# Perform identical COMDAT folding
|
||||
set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt" )
|
||||
set( REL_LINKER_FLAGS "/opt:ref /opt:icf /nodefaultlib:msvcrt /TSAWARE" )
|
||||
|
||||
# String pooling
|
||||
# Function-level linking
|
||||
# Disable run-time type information
|
||||
set( ALL_C_FLAGS "/GF /Gy /GR-" )
|
||||
|
||||
# Avoid CRT DLL dependancies in release builds
|
||||
set( REL_C_FLAGS "/MT" )
|
||||
if( CMAKE_SIZEOF_VOID_P MATCHES "4")
|
||||
# SSE2 option (mostly to switch it off in VC2012 and later where it's the default
|
||||
option (ZDOOM_USE_SSE2 "Use SSE2 instruction set")
|
||||
if (ZDOOM_USE_SSE2)
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:SSE2")
|
||||
else (ZDOOM_USE_SSE2)
|
||||
if (MSVC_VERSION GREATER 1699)
|
||||
# On Visual C++ 2012 and later SSE2 is the default, so we need to switch it off explicitly
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /arch:IA32")
|
||||
endif (MSVC_VERSION GREATER 1699)
|
||||
endif (ZDOOM_USE_SSE2)
|
||||
endif( CMAKE_SIZEOF_VOID_P MATCHES "4")
|
||||
|
||||
# Avoid CRT DLL dependancies in release builds, optionally generate assembly output for checking crash locations.
|
||||
option( ZDOOM_GENERATE_ASM "Generate assembly output." OFF )
|
||||
if( ZDOOM_GENERATE_ASM )
|
||||
set( REL_C_FLAGS "/MT /Oy /Oi /FAcs" )
|
||||
else( ZDOOM_GENERATE_ASM )
|
||||
set( REL_C_FLAGS "/MT /Oy /Oi" )
|
||||
endif( ZDOOM_GENERATE_ASM )
|
||||
|
||||
|
||||
# Debug allocations in debug builds
|
||||
set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC" )
|
||||
set( DEB_C_FLAGS "/D _CRTDBG_MAP_ALLOC /MTd" )
|
||||
|
||||
# Disable warnings for unsecure CRT functions from VC8+
|
||||
if( MSVC_VERSION GREATER 1399 )
|
||||
|
@ -81,10 +142,17 @@ if( MSVC )
|
|||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
||||
string(REPLACE "/MDd " " " CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} )
|
||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE} )
|
||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
||||
string(REPLACE "/MDd " " " CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG} )
|
||||
string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
|
||||
else( MSVC )
|
||||
set( REL_LINKER_FLAGS "" )
|
||||
set( ALL_C_FLAGS "" )
|
||||
set( REL_C_FLAGS "" )
|
||||
set( DEB_C_FLAGS "" )
|
||||
endif( MSVC )
|
||||
|
||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
||||
|
@ -106,6 +174,7 @@ set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
|||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||
option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
||||
|
||||
if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||
message( STATUS "Using system zlib" )
|
||||
|
@ -137,11 +206,19 @@ else( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
|||
set( BZIP2_LIBRARY bz2 )
|
||||
endif( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||
|
||||
if( GME_FOUND AND NOT FORCE_INTERNAL_GME )
|
||||
message( STATUS "Using system gme library ${GME_INCLUDE_DIR}" )
|
||||
else( GME_FOUND AND NOT FORCE_INTERNAL_GME )
|
||||
message( STATUS "Using internal gme library" )
|
||||
add_subdirectory( game-music-emu )
|
||||
set( GME_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/game-music-emu" )
|
||||
set( GME_LIBRARIES gme )
|
||||
endif( GME_FOUND AND NOT FORCE_INTERNAL_GME )
|
||||
|
||||
set( LZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lzma/C" )
|
||||
|
||||
add_subdirectory( lzma )
|
||||
add_subdirectory( tools )
|
||||
add_subdirectory( game-music-emu )
|
||||
add_subdirectory( dumb )
|
||||
add_subdirectory( gdtoa )
|
||||
add_subdirectory( wadsrc )
|
||||
|
@ -150,3 +227,7 @@ add_subdirectory( src )
|
|||
if( NOT WIN32 AND NOT APPLE )
|
||||
add_subdirectory( output_sdl )
|
||||
endif( NOT WIN32 AND NOT APPLE )
|
||||
|
||||
if( NOT CMAKE_CROSSCOMPILING )
|
||||
export(TARGETS ${CROSS_EXPORTS} FILE "${CMAKE_BINARY_DIR}/ImportExecutables.cmake" )
|
||||
endif( NOT CMAKE_CROSSCOMPILING )
|
||||
|
|
48
CleanDirectoryList.cmake
Normal file
48
CleanDirectoryList.cmake
Normal file
|
@ -0,0 +1,48 @@
|
|||
# - Removes duplicate entries and non-directories from a provided list
|
||||
#
|
||||
# clean_directory_list(<listvar> [<additional list items>...])
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__clean_directory_list)
|
||||
return()
|
||||
endif()
|
||||
set(__clean_directory_list YES)
|
||||
|
||||
function(clean_directory_list _var)
|
||||
# combine variable's current value with additional list items
|
||||
set(_in ${${_var}} ${ARGN})
|
||||
|
||||
if(_in)
|
||||
# Initial list cleaning
|
||||
list(REMOVE_DUPLICATES _in)
|
||||
|
||||
# Grab the absolute path of each actual directory
|
||||
set(_out)
|
||||
foreach(_dir ${_in})
|
||||
if(IS_DIRECTORY "${_dir}")
|
||||
get_filename_component(_dir "${_dir}" ABSOLUTE)
|
||||
file(TO_CMAKE_PATH "${_dir}" _dir)
|
||||
list(APPEND _out "${_dir}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_out)
|
||||
# Clean up the output list now
|
||||
list(REMOVE_DUPLICATES _out)
|
||||
endif()
|
||||
|
||||
# return _out
|
||||
set(${_var} "${_out}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
336
CreateLaunchers.cmake
Normal file
336
CreateLaunchers.cmake
Normal file
|
@ -0,0 +1,336 @@
|
|||
# - Create launchers to set working directory, env. vars, etc.
|
||||
#
|
||||
# include(CreateLaunchers) - to make these available
|
||||
# guess_runtime_library_dirs(<outputvarname> [<extralibrary> ...])
|
||||
# create_default_target_launcher(<targetname>
|
||||
# [ARGS <args...>]
|
||||
# [FORWARD_ARGS]
|
||||
# [RUNTIME_LIBRARY_DIRS <dir...>]
|
||||
# [WORKING_DIRECTORY <dir>]
|
||||
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
|
||||
#
|
||||
# create_target_launcher(<targetname>
|
||||
# [ARGS <args...>]
|
||||
# [FORWARD_ARGS]
|
||||
# [RUNTIME_LIBRARY_DIRS <dir...>]
|
||||
# [WORKING_DIRECTORY <dir>]
|
||||
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
|
||||
#
|
||||
# create_generic_launcher(<launchername>
|
||||
# [RUNTIME_LIBRARY_DIRS <dir...>]
|
||||
# [WORKING_DIRECTORY <dir>]
|
||||
# [ENVIRONMENT <VAR=value> [<VAR=value>...]])
|
||||
# - sets GENERIC_LAUNCHER_COMMAND and GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION
|
||||
#
|
||||
# Requires these CMake modules:
|
||||
# ListFilter
|
||||
# ProgramFilesGlob
|
||||
# CleanDirectoryList
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__create_launchers)
|
||||
return()
|
||||
endif()
|
||||
set(__create_launchers YES)
|
||||
|
||||
include(CleanDirectoryList)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_launchermoddir
|
||||
${CMAKE_CURRENT_LIST_FILE}
|
||||
PATH)
|
||||
set(_launchermoddir "${_launchermoddir}/launcher-templates")
|
||||
|
||||
macro(_launcher_system_settings)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITS 64)
|
||||
else()
|
||||
set(BITS 32)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Find user and system name
|
||||
set(SYSTEM_NAME $ENV{USERDOMAIN})
|
||||
set(USER_NAME $ENV{USERNAME})
|
||||
set(VCPROJ_TYPE vcproj)
|
||||
set(USERFILE_EXTENSION ${SYSTEM_NAME}.${USER_NAME}.user)
|
||||
set(LAUNCHER_LINESEP "
")
|
||||
if(MSVC90)
|
||||
set(USERFILE_VC_VERSION 9.00)
|
||||
elseif(MSVC80)
|
||||
set(USERFILE_VC_VERSION 8.00)
|
||||
elseif(MSVC71)
|
||||
set(USERFILE_VC_VERSION 7.10)
|
||||
elseif(MSVC10 OR (MSVC AND MSVC_VERSION GREATER 1600)) # 2010 or newer
|
||||
set(LAUNCHER_LINESEP "\n")
|
||||
set(USERFILE_VC_VERSION 10.00)
|
||||
set(USERFILE_EXTENSION user)
|
||||
set(VCPROJ_TYPE vcxproj)
|
||||
endif()
|
||||
if(BITS EQUAL 64)
|
||||
set(USERFILE_PLATFORM x64)
|
||||
else()
|
||||
set(USERFILE_PLATFORM Win${BITS})
|
||||
endif()
|
||||
set(_pathdelim ";")
|
||||
set(_suffix "cmd")
|
||||
else()
|
||||
set(_pathdelim ":")
|
||||
set(USERFILE_PLATFORM ${CMAKE_SYSTEM_NAME}${BITS})
|
||||
set(_suffix "sh")
|
||||
find_package(GDB QUIET)
|
||||
if(GDB_FOUND)
|
||||
set(LAUNCHERS_GOT_GDB YES)
|
||||
if(GDB_HAS_RETURN_CHILD_RESULT)
|
||||
set(LAUNCHERS_GDB_ARG --return-child-result)
|
||||
endif()
|
||||
else()
|
||||
set(LAUNCHERS_GOT_GDB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT USERFILE_REMOTE_MACHINE)
|
||||
site_name(USERFILE_REMOTE_MACHINE)
|
||||
mark_as_advanced(USERFILE_REMOTE_MACHINE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(_launcher_process_args)
|
||||
set(_nowhere)
|
||||
set(_curdest _nowhere)
|
||||
set(_val_args
|
||||
ARGS
|
||||
RUNTIME_LIBRARY_DIRS
|
||||
WORKING_DIRECTORY
|
||||
ENVIRONMENT)
|
||||
set(_bool_args FORWARD_ARGS)
|
||||
foreach(_arg ${_val_args} ${_bool_args})
|
||||
set(${_arg})
|
||||
endforeach()
|
||||
foreach(_element ${ARGN})
|
||||
list(FIND _val_args "${_element}" _val_arg_find)
|
||||
list(FIND _bool_args "${_element}" _bool_arg_find)
|
||||
if("${_val_arg_find}" GREATER "-1")
|
||||
set(_curdest "${_element}")
|
||||
elseif("${_bool_arg_find}" GREATER "-1")
|
||||
set("${_element}" ON)
|
||||
set(_curdest _nowhere)
|
||||
else()
|
||||
list(APPEND ${_curdest} "${_element}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(_nowhere)
|
||||
message(FATAL_ERROR
|
||||
"Syntax error in use of a function in CreateLaunchers!")
|
||||
endif()
|
||||
|
||||
# Turn into a list of native paths
|
||||
set(_runtime_lib_dirs)
|
||||
foreach(_dlldir ${RUNTIME_LIBRARY_DIRS})
|
||||
file(TO_NATIVE_PATH "${_dlldir}" _path)
|
||||
set(_runtime_lib_dirs "${_runtime_lib_dirs}${_path}${_pathdelim}")
|
||||
endforeach()
|
||||
|
||||
if(NOT WORKING_DIRECTORY)
|
||||
set(WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
if(FORWARD_ARGS)
|
||||
if(WIN32)
|
||||
set(FWD_ARGS %*)
|
||||
else()
|
||||
set(FWD_ARGS $*)
|
||||
endif()
|
||||
else()
|
||||
set(FWD_ARGS)
|
||||
endif()
|
||||
|
||||
set(USERFILE_WORKING_DIRECTORY "${WORKING_DIRECTORY}")
|
||||
set(USERFILE_COMMAND_ARGUMENTS "${ARGS}")
|
||||
set(LAUNCHERSCRIPT_COMMAND_ARGUMENTS "${ARGS} ${FWD_ARGS}")
|
||||
|
||||
if(WIN32)
|
||||
set(RUNTIME_LIBRARIES_ENVIRONMENT "PATH=${_runtime_lib_dirs};%PATH%")
|
||||
file(READ
|
||||
"${_launchermoddir}/launcher.env.cmd.in"
|
||||
_cmdenv)
|
||||
else()
|
||||
if(APPLE)
|
||||
set(RUNTIME_LIBRARIES_ENVIRONMENT
|
||||
"DYLD_LIBRARY_PATH=${_runtime_lib_dirs}:$DYLD_LIBRARY_PATH")
|
||||
else()
|
||||
set(RUNTIME_LIBRARIES_ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${_runtime_lib_dirs}:$LD_LIBRARY_PATH")
|
||||
endif()
|
||||
file(READ
|
||||
"${_launchermoddir}/launcher.env.sh.in"
|
||||
_cmdenv)
|
||||
endif()
|
||||
set(USERFILE_ENVIRONMENT "${RUNTIME_LIBRARIES_ENVIRONMENT}")
|
||||
|
||||
set(USERFILE_ENV_COMMANDS)
|
||||
foreach(_arg "${RUNTIME_LIBRARIES_ENVIRONMENT}" ${ENVIRONMENT})
|
||||
string(CONFIGURE
|
||||
"@USERFILE_ENVIRONMENT@@LAUNCHER_LINESEP@@_arg@"
|
||||
USERFILE_ENVIRONMENT
|
||||
@ONLY)
|
||||
string(CONFIGURE
|
||||
"@USERFILE_ENV_COMMANDS@${_cmdenv}"
|
||||
USERFILE_ENV_COMMANDS
|
||||
@ONLY)
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(_launcher_produce_vcproj_user)
|
||||
if(MSVC)
|
||||
file(READ
|
||||
"${_launchermoddir}/perconfig.${VCPROJ_TYPE}.user.in"
|
||||
_perconfig)
|
||||
set(USERFILE_CONFIGSECTIONS)
|
||||
foreach(USERFILE_CONFIGNAME ${CMAKE_CONFIGURATION_TYPES})
|
||||
get_target_property(USERFILE_${USERFILE_CONFIGNAME}_COMMAND
|
||||
${_targetname}
|
||||
LOCATION_${USERFILE_CONFIGNAME})
|
||||
file(TO_NATIVE_PATH
|
||||
"${USERFILE_${USERFILE_CONFIGNAME}_COMMAND}"
|
||||
USERFILE_${USERFILE_CONFIGNAME}_COMMAND)
|
||||
string(CONFIGURE "${_perconfig}" _temp @ONLY ESCAPE_QUOTES)
|
||||
string(CONFIGURE
|
||||
"${USERFILE_CONFIGSECTIONS}${_temp}"
|
||||
USERFILE_CONFIGSECTIONS
|
||||
ESCAPE_QUOTES)
|
||||
endforeach()
|
||||
|
||||
|
||||
configure_file("${_launchermoddir}/${VCPROJ_TYPE}.user.in"
|
||||
${VCPROJNAME}.${VCPROJ_TYPE}.${USERFILE_EXTENSION}
|
||||
@ONLY)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(_launcher_configure_executable _src _tmp _target)
|
||||
# get_filename_component(_targetname "${_target}" NAME)
|
||||
get_filename_component(_targetpath "${_target}" PATH)
|
||||
configure_file("${_src}"
|
||||
"${_tmp}"
|
||||
@ONLY)
|
||||
file(COPY "${_tmp}"
|
||||
DESTINATION "${_targetpath}"
|
||||
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
|
||||
endmacro()
|
||||
|
||||
macro(_launcher_create_target_launcher)
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
# Multi-config generator - multiple launchers
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
get_target_property(USERFILE_${_config}_COMMAND
|
||||
${_targetname}
|
||||
LOCATION_${_config})
|
||||
file(TO_NATIVE_PATH
|
||||
"${USERFILE_${_config}_COMMAND}"
|
||||
USERFILE_COMMAND)
|
||||
set(_fn "launch-${_targetname}-${_config}.${_suffix}")
|
||||
_launcher_configure_executable("${_launchermoddir}/targetlauncher.${_suffix}.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_fn}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${_fn}")
|
||||
endforeach()
|
||||
else()
|
||||
# Single-config generator - single launcher
|
||||
get_target_property(USERFILE_COMMAND
|
||||
${_targetname}
|
||||
LOCATION)
|
||||
file(TO_NATIVE_PATH
|
||||
"${USERFILE_COMMAND}"
|
||||
USERFILE_COMMAND)
|
||||
_launcher_configure_executable("${_launchermoddir}/targetlauncher.${_suffix}.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/launch-${_targetname}.${_suffix}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-${_targetname}.${_suffix}"
|
||||
@ONLY)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
function(create_default_target_launcher _targetname)
|
||||
_launcher_system_settings()
|
||||
_launcher_process_args(${ARGN})
|
||||
|
||||
set(VCPROJNAME "${CMAKE_BINARY_DIR}/ALL_BUILD")
|
||||
_launcher_produce_vcproj_user()
|
||||
|
||||
_launcher_create_target_launcher()
|
||||
endfunction()
|
||||
|
||||
function(create_target_launcher _targetname)
|
||||
_launcher_system_settings()
|
||||
_launcher_process_args(${ARGN})
|
||||
|
||||
set(VCPROJNAME "${CMAKE_CURRENT_BINARY_DIR}/${_targetname}")
|
||||
_launcher_produce_vcproj_user()
|
||||
|
||||
_launcher_create_target_launcher()
|
||||
endfunction()
|
||||
|
||||
function(create_generic_launcher _launchername)
|
||||
_launcher_system_settings()
|
||||
_launcher_process_args(${ARGN})
|
||||
|
||||
if(NOT IS_ABSOLUTE _launchername)
|
||||
set(_launchername
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${_launchername}.${_suffix}")
|
||||
else()
|
||||
set(_launchername "${_launchername}.${_suffix}")
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(GENERIC_LAUNCHER_COMMAND "${_launchername}" PARENT_SCOPE)
|
||||
set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION)
|
||||
else()
|
||||
set(GENERIC_LAUNCHER_COMMAND sh "${_launchername}" PARENT_SCOPE)
|
||||
set(GENERIC_LAUNCHER_FAIL_REGULAR_EXPRESSION
|
||||
"Program terminated with signal")
|
||||
endif()
|
||||
|
||||
_launcher_configure_executable("${_launchermoddir}/genericlauncher.${_suffix}.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/genericlauncher.${_suffix}.in"
|
||||
"${_launchername}")
|
||||
endfunction()
|
||||
|
||||
function(guess_runtime_library_dirs _var)
|
||||
# Start off with the link directories of the calling listfile's directory
|
||||
get_directory_property(_libdirs LINK_DIRECTORIES)
|
||||
|
||||
# Add additional libraries passed to the function
|
||||
foreach(_lib ${ARGN})
|
||||
get_filename_component(_libdir "${_lib}" PATH)
|
||||
list(APPEND _libdirs "${_libdir}")
|
||||
endforeach()
|
||||
|
||||
# Now, build a list of potential dll directories
|
||||
set(_dlldirs)
|
||||
foreach(_libdir ${_libdirs})
|
||||
# Add the libdir itself
|
||||
list(APPEND _dlldirs "${_libdir}")
|
||||
|
||||
# Look also in libdir/../bin since the dll might not be with the lib
|
||||
get_filename_component(_libdir "${_libdir}/../bin" ABSOLUTE)
|
||||
list(APPEND _dlldirs "${_libdir}")
|
||||
endforeach()
|
||||
|
||||
# Only keep the valid, unique directories
|
||||
clean_directory_list(_dlldirs)
|
||||
|
||||
# Return _dlldirs
|
||||
set(${_var} "${_dlldirs}" PARENT_SCOPE)
|
||||
endfunction()
|
|
@ -1,5 +1,7 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
|
||||
make_release_only()
|
||||
|
||||
if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -fomit-frame-pointer" )
|
||||
endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
|
||||
make_release_only()
|
||||
|
||||
include( CheckFunctionExists )
|
||||
|
||||
# DUMB is much slower in a Debug build than a Release build, so we force a Release
|
||||
|
|
|
@ -3950,6 +3950,7 @@ static int delta_to_note(float delta, int base)
|
|||
return (int)note;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Period table for Protracker octaves 0-5:
|
||||
static const unsigned short ProTrackerPeriodTable[6*12] =
|
||||
{
|
||||
|
@ -3981,6 +3982,7 @@ static const unsigned short ProTrackerTunedPeriods[16*12] =
|
|||
1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
|
||||
1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914
|
||||
};
|
||||
#endif
|
||||
|
||||
static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer)
|
||||
{
|
||||
|
@ -4400,6 +4402,7 @@ static int process_tick(DUMB_IT_SIGRENDERER *sigrenderer)
|
|||
|
||||
int dumb_it_max_to_mix = 64;
|
||||
|
||||
#if 0
|
||||
static const int aiMODVol[] =
|
||||
{
|
||||
0,
|
||||
|
@ -4425,6 +4428,7 @@ static const int aiPTMVolScaled[] =
|
|||
836, 847, 859, 870, 881, 897, 908, 916,
|
||||
927, 939, 950, 962, 969, 983, 1005, 1024
|
||||
};
|
||||
#endif
|
||||
|
||||
static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, double volume)
|
||||
{
|
||||
|
|
|
@ -31,8 +31,8 @@ static int it_riff_dsmf_process_sample( IT_SAMPLE * sample, const unsigned char
|
|||
int flags;
|
||||
|
||||
memcpy( sample->filename, data, 13 );
|
||||
sample->filename[ 14 ] = 0;
|
||||
|
||||
sample->filename[ 13 ] = 0;
|
||||
|
||||
flags = data[ 13 ] | ( data[ 14 ] << 8 );
|
||||
sample->default_volume = data[ 15 ];
|
||||
sample->length = data[ 16 ] | ( data[ 17 ] << 8 ) | ( data[ 18 ] << 16 ) | ( data[ 19 ] << 24 );
|
||||
|
|
|
@ -486,7 +486,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f)
|
|||
|
||||
/* And finally, the sample data */
|
||||
k = get_chunk_count(mod, DUMB_ID('S','B','O','D'));
|
||||
for (i = 0, j = 0; i < (unsigned)sigdata->n_samples, j < k; i++) {
|
||||
for (i = 0, j = 0; i < (unsigned)sigdata->n_samples && j < k; i++) {
|
||||
if (sigdata->sample[i].flags & IT_SAMPLE_EXISTS) {
|
||||
chunk = get_chunk_by_type(mod, DUMB_ID('S','B','O','D'), j);
|
||||
if (it_okt_read_sample_data(&sigdata->sample[i], (const char *)chunk->data, chunk->size)) {
|
||||
|
@ -503,7 +503,7 @@ static DUMB_IT_SIGDATA *it_okt_load_sigdata(DUMBFILE *f)
|
|||
|
||||
chunk = get_chunk_by_type(mod, DUMB_ID('C','M','O','D'), 0);
|
||||
|
||||
for (i = 0, j = 0; i < n_channels, j < 4; j++) {
|
||||
for (i = 0, j = 0; i < n_channels && j < 4; j++) {
|
||||
k = (chunk->data[j * 2] << 8) | chunk->data[j * 2 + 1];
|
||||
l = (j == 1 || j == 2) ? 48 : 16;
|
||||
if (k == 0) {
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
cmake_minimum_required( VERSION 2.4 )
|
||||
include( CheckCXXCompilerFlag )
|
||||
# CMake project definition file.
|
||||
project(libgme)
|
||||
|
||||
include (CheckCXXCompilerFlag)
|
||||
|
||||
# When version is changed, also change the one in gme/gme.h to match
|
||||
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
|
||||
|
||||
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
|
||||
# Of course, 2.4 might work, in which case you're welcome to drop
|
||||
# down the requirement, but I can't test that.
|
||||
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
||||
|
||||
make_release_only()
|
||||
|
||||
# I don't plan on debugging this, so make it a release build.
|
||||
if( NOT CMAKE_BUILD_TYPE MATCHES "Release" )
|
||||
|
@ -17,51 +29,80 @@ if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STRE
|
|||
endif( HAVE_NO_ARRAY_BOUNDS )
|
||||
endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||
|
||||
add_library( gme
|
||||
gme/Blip_Buffer.cpp
|
||||
gme/Classic_Emu.cpp
|
||||
gme/Data_Reader.cpp
|
||||
gme/Dual_Resampler.cpp
|
||||
gme/Effects_Buffer.cpp
|
||||
gme/Fir_Resampler.cpp
|
||||
gme/gme.cpp
|
||||
gme/Gme_File.cpp
|
||||
gme/M3u_Playlist.cpp
|
||||
gme/Multi_Buffer.cpp
|
||||
gme/Music_Emu.cpp
|
||||
|
||||
gme/Ay_Apu.cpp
|
||||
gme/Ay_Cpu.cpp
|
||||
gme/Ay_Emu.cpp
|
||||
gme/Gb_Apu.cpp
|
||||
gme/Gb_Cpu.cpp
|
||||
gme/Gb_Oscs.cpp
|
||||
gme/Gbs_Emu.cpp
|
||||
gme/Gym_Emu.cpp
|
||||
gme/Hes_Apu.cpp
|
||||
gme/Hes_Cpu.cpp
|
||||
gme/Hes_Emu.cpp
|
||||
gme/Kss_Cpu.cpp
|
||||
gme/Kss_Emu.cpp
|
||||
gme/Kss_Scc_Apu.cpp
|
||||
gme/Nes_Apu.cpp
|
||||
gme/Nes_Cpu.cpp
|
||||
gme/Nes_Fme7_Apu.cpp
|
||||
gme/Nes_Namco_Apu.cpp
|
||||
gme/Nes_Oscs.cpp
|
||||
gme/Nes_Vrc6_Apu.cpp
|
||||
gme/Nsf_Emu.cpp
|
||||
gme/Nsfe_Emu.cpp
|
||||
gme/Sap_Apu.cpp
|
||||
gme/Sap_Cpu.cpp
|
||||
gme/Sap_Emu.cpp
|
||||
gme/Sms_Apu.cpp
|
||||
gme/Snes_Spc.cpp
|
||||
gme/Spc_Cpu.cpp
|
||||
gme/Spc_Dsp.cpp
|
||||
gme/Spc_Emu.cpp
|
||||
gme/Vgm_Emu.cpp
|
||||
gme/Vgm_Emu_Impl.cpp
|
||||
gme/Ym2413_Emu.cpp
|
||||
gme/Ym2612_Emu.cpp )
|
||||
target_link_libraries( gme )
|
||||
|
||||
|
||||
# Default emulators to build (all of them! ;)
|
||||
if (NOT DEFINED USE_GME_AY)
|
||||
SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_GBS)
|
||||
SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_GYM)
|
||||
SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_HES)
|
||||
SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_KSS)
|
||||
SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_NSF)
|
||||
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_NSFE)
|
||||
SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_SAP)
|
||||
SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_SPC)
|
||||
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED USE_GME_VGM)
|
||||
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
|
||||
endif()
|
||||
|
||||
if (USE_GME_NSFE AND NOT USE_GME_NSF)
|
||||
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
|
||||
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
||||
endif()
|
||||
|
||||
# Check for GCC "visibility" support.
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
|
||||
set (ENABLE_VISIBILITY OFF)
|
||||
if (__LIBGME_TEST_VISIBILITY)
|
||||
# get the gcc version
|
||||
exec_program(${CMAKE_CXX_COMPILER} ARGS --version OUTPUT_VARIABLE _gcc_version_info)
|
||||
string (REGEX MATCH "[3-9]\\.[0-9]\\.[0-9]" _gcc_version "${_gcc_version_info}")
|
||||
|
||||
# gcc <4.1 had poor support for symbol visibility
|
||||
if ((${_gcc_version} VERSION_GREATER "4.1") OR (${_gcc_version} VERSION_EQUAL "4.1"))
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
set (ENABLE_VISIBILITY ON)
|
||||
add_definitions (-DLIBGME_VISIBILITY)
|
||||
|
||||
# GCC >= 4.2 also correctly supports making inline members have hidden
|
||||
# visibility by default.
|
||||
if ((${_gcc_version} VERSION_GREATER "4.2") OR (${_gcc_version} VERSION_EQUAL "4.2"))
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
|
||||
endif()
|
||||
endif()
|
||||
endif() # test visibility
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
# Cache this result
|
||||
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
|
||||
|
||||
# Shared library defined here
|
||||
add_subdirectory(gme)
|
||||
|
|
|
@ -1,6 +1,50 @@
|
|||
Game_Music_Emu Change Log
|
||||
-------------------------
|
||||
|
||||
Game_Music_Emu 0.6.0
|
||||
--------------------
|
||||
|
||||
- Note: A 0.5.6 release was referenced but never tagged or packaged.
|
||||
|
||||
- SPC improvements:
|
||||
- Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
|
||||
- Fixed Spc_Emu::gain().
|
||||
- Fixed support for files <0x10200 bytes.
|
||||
|
||||
- Other bugfixes:
|
||||
- Fixed a couple of GBS bugs, one involving access of memory after
|
||||
realloc.
|
||||
- Blip_Buffer works on systems where 'double' is a single-precision
|
||||
floating-point type.
|
||||
- Fix uninitialized buffer size in dual_resampler.
|
||||
- Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
|
||||
|
||||
- API changes/additions:
|
||||
- Removed documentation of C++ interface, as the C interface in gme.h is
|
||||
the only supported one.
|
||||
- Added gme_enable_accuracy() for enabling more accurate sound emulation
|
||||
options (currently affects SPC only).
|
||||
|
||||
- Build system improvements:
|
||||
- Add pkg_config support.
|
||||
- Fix build on case-insensitive systems.
|
||||
- Allow for install on Cygwin.
|
||||
- Fix install on multilib systems, such as many 64-bit distros (CMake must
|
||||
be able to figure out your system's libsuffix, if any).
|
||||
- C++ implementation symbols are not leaked into the resultant library
|
||||
file (requires symbol visibility support).
|
||||
|
||||
- Sample player improvements:
|
||||
- Can toggle fast/accurate emulation (with the 'A' key).
|
||||
|
||||
Game_Music_Emu 0.5.5
|
||||
--------------------
|
||||
- CMake build support has been added. You can build Game_Music_Emu as
|
||||
a shared library and install it so that you do not have to include your
|
||||
own copy if you know libgme will be present on your target system.
|
||||
Requires CMake 2.6 or higher.
|
||||
|
||||
|
||||
Game_Music_Emu 0.5.2
|
||||
--------------------
|
||||
- *TONS* of changes and improvements. You should re-read the new header
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Game_Music_Emu 0.5.2 Design
|
||||
Game_Music_Emu 0.6.0 Design
|
||||
---------------------------
|
||||
This might be slightly out-of-date at times, but will be a big help in
|
||||
understanding the library implementation.
|
||||
|
|
|
@ -80,6 +80,69 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
|
@ -146,6 +209,73 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release DLL|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
|
@ -221,136 +351,6 @@
|
|||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
ExceptionHandling="0"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release DLL|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
|
@ -601,6 +601,10 @@
|
|||
RelativePath=".\gme\Spc_Emu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\Spc_Filter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\Vgm_Emu.cpp"
|
||||
>
|
||||
|
@ -703,6 +707,10 @@
|
|||
RelativePath=".\gme\Gme_File.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\gme_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\Gym_Emu.h"
|
||||
>
|
||||
|
@ -823,6 +831,10 @@
|
|||
RelativePath=".\gme\Spc_Emu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\Spc_Filter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\gme\Vgm_Emu.h"
|
||||
>
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
Game_Music_Emu 0.5.2
|
||||
Game_Music_Emu 0.6.0
|
||||
--------------------
|
||||
Author : Shay Green <gblargg@gmail.com>
|
||||
Website: http://www.slack.net/~ant/libs/
|
||||
Forum : http://groups.google.com/group/blargg-sound-libs
|
||||
Source : https://code.google.com/p/game-music-emu/
|
||||
License: GNU Lesser General Public License (LGPL)
|
||||
|
||||
Contents
|
||||
--------
|
||||
* Overview
|
||||
* C and C++ interfaces
|
||||
* Function reference
|
||||
* Error handling
|
||||
* Emulator types
|
||||
* M3U playlist support
|
||||
|
@ -21,7 +20,6 @@ Contents
|
|||
* Modular construction
|
||||
* Obscure features
|
||||
* Solving problems
|
||||
* Deprecated features
|
||||
* Thanks
|
||||
|
||||
|
||||
|
@ -62,56 +60,15 @@ deleted with gme_set_user_cleanup()
|
|||
Refer to gme.h for a comprehensive summary of features.
|
||||
|
||||
|
||||
C and C++ interfaces
|
||||
--------------------
|
||||
While the library is written in C++, an extensive C interface is
|
||||
provided in gme.h. This C interface will be referred to throughout this
|
||||
documentation unless a feature is only available in the full C++
|
||||
interface. All C interface functions and other names have the gme_
|
||||
prefix, so you can recognize a C++-only feature by the lack of gme_ in
|
||||
the names used (contact me if you'd like a feature added to the C
|
||||
interface). If you're building a shared library, I highly recommend
|
||||
sticking to the C interface only, because it will be more stable between
|
||||
releases of the library than the C++ interface. Finally, the C and C++
|
||||
interfaces can be freely mixed without problems. Compare demo/basics.c
|
||||
with demo/cpp_basics.cpp to see how the C and C++ interfaces translate
|
||||
between each other.
|
||||
|
||||
|
||||
Function reference
|
||||
------------------
|
||||
Read the following header files for a complete reference to functions
|
||||
and features. The second group of header files can only be used in C++.
|
||||
|
||||
blargg_config.h Library configuration
|
||||
gme.h C interface (also usable from C++)
|
||||
|
||||
Gme_File.h File loading and track information
|
||||
Music_Emu.h Track playback and adjustments
|
||||
Data_Reader.h Custom data readers
|
||||
Effects_Buffer.h Sound buffer with adjustable stereo echo and panning
|
||||
M3u_Playlist.h M3U playlist support
|
||||
Gbs_Emu.h GBS equalizer settings
|
||||
Nsf_Emu.h NSF equalizer settings
|
||||
Spc_Emu.h SPC surround disable
|
||||
Vgm_Emu.h VGM oversampling disable and custom buffer query
|
||||
|
||||
|
||||
Error handling
|
||||
--------------
|
||||
Functions which can fail have a return type of gme_err_t (blargg_err_t
|
||||
in the C++ interfaces), which is a pointer to an error string (const
|
||||
char*). If a function is successful it returns NULL. Errors that you can
|
||||
easily avoid are checked with debug assertions; gme_err_t return values
|
||||
are only used for genuine run-time errors that can't be easily predicted
|
||||
in advance (out of memory, I/O errors, incompatible file data). Your
|
||||
code should check all error values.
|
||||
|
||||
To improve usability for C programmers, C++ programmers unfamiliar with
|
||||
exceptions, and compatibility with older C++ compilers, the library does
|
||||
*not* throw any C++ exceptions and uses malloc() instead of the standard
|
||||
operator new. This means that you *must* check for NULL when creating a
|
||||
library object with the new operator.
|
||||
Functions which can fail have a return type of gme_err_t, which is a
|
||||
pointer to an error string (const char*). If a function is successful it
|
||||
returns NULL. Errors that you can easily avoid are checked with debug
|
||||
assertions; gme_err_t return values are only used for genuine run-time
|
||||
errors that can't be easily predicted in advance (out of memory, I/O
|
||||
errors, incompatible file data). Your code should check all error
|
||||
values.
|
||||
|
||||
When loading a music file in the wrong emulator or trying to load a
|
||||
non-music file, gme_wrong_file_type is returned. You can check for this
|
||||
|
@ -154,7 +111,9 @@ If you want to remove support for some music types to reduce your
|
|||
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
|
||||
support just NSF and GBS, use this:
|
||||
|
||||
#define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
|
||||
#define GME_TYPE_LIST \
|
||||
gme_nsf_type,\
|
||||
gme_gbs_type
|
||||
|
||||
|
||||
M3U playlist support
|
||||
|
@ -271,40 +230,6 @@ create an emulator, you can use the following methods of loading:
|
|||
|
||||
error = gme_load_custom( emu, my_read, file_size, my_data );
|
||||
|
||||
* If you must load the file data into memory yourself, you can have the
|
||||
library use your data directly *without* making a copy. If you do this,
|
||||
you must not free the data until you're done playing the file.
|
||||
|
||||
error = emu->load_mem( pointer, size );
|
||||
|
||||
* If you've already read the first bytes of a file (perhaps to determine
|
||||
the file type) and want to avoid seeking back to the beginning for
|
||||
performance reasons, use Remaining_Reader:
|
||||
|
||||
Std_File_Reader in;
|
||||
error = in.open( file_path );
|
||||
|
||||
char header [4];
|
||||
error = in.read( &header, sizeof header );
|
||||
...
|
||||
|
||||
Remaining_Reader rem( &header, sizeof header, &in );
|
||||
error = emu->load( rem );
|
||||
|
||||
If you merely need access to a file's header after loading, use the
|
||||
emulator-specific header() functions, after casting the Music_Emu
|
||||
pointer to the specific emulator's type. This example examines the
|
||||
chip_flags field of the header if it's an NSF file:
|
||||
|
||||
if ( music_emu->type() == gme_nsf_type )
|
||||
{
|
||||
Nsf_Emu* nsf_emu = (Nsf_Emu*) music_emu;
|
||||
if ( nsf_emu->header().chip_flags & 0x01 )
|
||||
...
|
||||
}
|
||||
|
||||
Contact me if you want more information about loading files.
|
||||
|
||||
|
||||
Sound parameters
|
||||
----------------
|
||||
|
@ -437,21 +362,6 @@ separate threads.
|
|||
* If all else fails, see if the demos work.
|
||||
|
||||
|
||||
Deprecated features
|
||||
-------------------
|
||||
The following functions and other features have been deprecated and will
|
||||
be removed in a future release of the library. Alternatives to the
|
||||
deprecated features are listed to the right.
|
||||
|
||||
Music_Emu::error_count() warning()
|
||||
load( header, reader ) see "Loading file data" above
|
||||
Spc_Emu::trailer() track_info()
|
||||
Spc_Emu::trailer_size()
|
||||
Gym_Emu::track_length() track_info()
|
||||
Vgm_Emu::gd3_data() track_info()
|
||||
Nsfe_Emu::disable_playlist() clear_playlist()
|
||||
|
||||
|
||||
Thanks
|
||||
------
|
||||
Big thanks to Chris Moeller (kode54) for help with library testing and
|
||||
|
@ -461,4 +371,6 @@ Brad Martin's excellent OpenSPC SNES DSP emulator worked well from the
|
|||
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
|
||||
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
|
||||
and giving feedback for the library in their respective game music
|
||||
players.
|
||||
players. More recently, Lucas Paul and Michael Pyne have helped nudge the
|
||||
library into a public repository and get its interface more stable for use
|
||||
in shared libraries.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ay_Apu.h"
|
||||
|
||||
|
@ -123,8 +123,8 @@ void Ay_Apu::write_data_( int addr, int data )
|
|||
|
||||
if ( (unsigned) addr >= 14 )
|
||||
{
|
||||
#ifdef dprintf
|
||||
dprintf( "Wrote to I/O port %02X\n", (int) addr );
|
||||
#ifdef debug_printf
|
||||
debug_printf( "Wrote to I/O port %02X\n", (int) addr );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time )
|
|||
end_time = final_end_time;
|
||||
|
||||
//if ( !(regs [12] | regs [11]) )
|
||||
// dprintf( "Used envelope period 0\n" );
|
||||
// debug_printf( "Used envelope period 0\n" );
|
||||
}
|
||||
else if ( !volume )
|
||||
{
|
||||
|
@ -250,7 +250,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time )
|
|||
ntime = start_time + old_noise_delay;
|
||||
noise_lfsr = old_noise_lfsr;
|
||||
//if ( (regs [6] & 0x1F) == 0 )
|
||||
// dprintf( "Used noise period 0\n" );
|
||||
// debug_printf( "Used noise period 0\n" );
|
||||
}
|
||||
|
||||
// The following efficiently handles several cases (least demanding first):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// AY-3-8910 sound chip emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef AY_APU_H
|
||||
#define AY_APU_H
|
||||
|
||||
|
@ -50,7 +50,6 @@ private:
|
|||
Blip_Buffer* output;
|
||||
} oscs [osc_count];
|
||||
blip_time_t last_time;
|
||||
byte latch;
|
||||
byte regs [reg_count];
|
||||
|
||||
struct {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
/*
|
||||
Last validated with zexall 2006.11.21 5:26 PM
|
||||
|
@ -469,7 +469,7 @@ possibly_out_of_time:
|
|||
add_hl_data: {
|
||||
blargg_ulong sum = rp.hl + data;
|
||||
data ^= rp.hl;
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
flags = (flags & (S80 | Z40 | V04)) |
|
||||
(sum >> 16) |
|
||||
(sum >> 8 & (F20 | F08)) |
|
||||
|
@ -719,7 +719,7 @@ possibly_out_of_time:
|
|||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & (F20 | F08)) |
|
||||
(temp >> 8);
|
||||
rg.a = temp;
|
||||
rg.a = (uint8_t)temp;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -807,6 +807,7 @@ possibly_out_of_time:
|
|||
case 0xCB:
|
||||
unsigned data2;
|
||||
data2 = INSTR( 1 );
|
||||
(void) data2; // TODO is this the same as data in all cases?
|
||||
pc++;
|
||||
switch ( data )
|
||||
{
|
||||
|
@ -1055,7 +1056,7 @@ possibly_out_of_time:
|
|||
(temp >> 8 & H10) |
|
||||
(sum >> 8 & (S80 | F20 | F08)) |
|
||||
((temp - -0x8000) >> 14 & V04);
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
if ( (uint16_t) sum )
|
||||
goto loop;
|
||||
flags |= Z40;
|
||||
|
@ -1252,7 +1253,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0x4F: // LD R,A
|
||||
SET_R( rg.a );
|
||||
dprintf( "LD R,A not supported\n" );
|
||||
debug_printf( "LD R,A not supported\n" );
|
||||
warning = true;
|
||||
goto loop;
|
||||
|
||||
|
@ -1262,7 +1263,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0x5F: // LD A,R
|
||||
rg.a = GET_R();
|
||||
dprintf( "LD A,R not supported\n" );
|
||||
debug_printf( "LD A,R not supported\n" );
|
||||
warning = true;
|
||||
ld_ai_common:
|
||||
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
||||
|
@ -1285,7 +1286,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
default:
|
||||
dprintf( "Opcode $ED $%02X not supported\n", data );
|
||||
debug_printf( "Opcode $ED $%02X not supported\n", data );
|
||||
warning = true;
|
||||
goto loop;
|
||||
}
|
||||
|
@ -1545,7 +1546,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
default:
|
||||
dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||
debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||
warning = true;
|
||||
goto loop;
|
||||
}
|
||||
|
@ -1634,7 +1635,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
default:
|
||||
dprintf( "Unnecessary DD/FD prefix encountered\n" );
|
||||
debug_printf( "Unnecessary DD/FD prefix encountered\n" );
|
||||
warning = true;
|
||||
pc--;
|
||||
goto loop;
|
||||
|
@ -1643,7 +1644,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
}
|
||||
dprintf( "Unhandled main opcode: $%02X\n", opcode );
|
||||
debug_printf( "Unhandled main opcode: $%02X\n", opcode );
|
||||
assert( false );
|
||||
|
||||
halt:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Z80 CPU emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef AY_CPU_H
|
||||
#define AY_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ay_Emu.h"
|
||||
|
||||
|
@ -209,9 +209,9 @@ blargg_err_t Ay_Emu::start_track_( int track )
|
|||
set_warning( "Missing file data" );
|
||||
len = unsigned(file.end - in);
|
||||
}
|
||||
//dprintf( "addr: $%04X, len: $%04X\n", addr, len );
|
||||
//debug_printf( "addr: $%04X, len: $%04X\n", addr, len );
|
||||
if ( addr < ram_start && addr >= 0x400 ) // several tracks use low data
|
||||
dprintf( "Block addr in ROM\n" );
|
||||
debug_printf( "Block addr in ROM\n" );
|
||||
memcpy( mem.ram + addr, in, len );
|
||||
|
||||
if ( file.end - blocks < 8 )
|
||||
|
@ -242,7 +242,7 @@ blargg_err_t Ay_Emu::start_track_( int track )
|
|||
};
|
||||
memcpy( mem.ram, passive, sizeof passive );
|
||||
unsigned play_addr = get_be16( more_data + 4 );
|
||||
//dprintf( "Play: $%04X\n", play_addr );
|
||||
//debug_printf( "Play: $%04X\n", play_addr );
|
||||
if ( play_addr )
|
||||
{
|
||||
memcpy( mem.ram, active, sizeof active );
|
||||
|
@ -315,7 +315,7 @@ void Ay_Emu::cpu_out_misc( cpu_time_t time, unsigned addr, int data )
|
|||
}
|
||||
}
|
||||
|
||||
dprintf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
|
||||
debug_printf( "Unmapped OUT: $%04X <- $%02X\n", addr, data );
|
||||
return;
|
||||
|
||||
enable_cpc:
|
||||
|
@ -356,7 +356,7 @@ int ay_cpu_in( Ay_Cpu*, unsigned addr )
|
|||
if ( (addr & 0xFF) == 0xFE )
|
||||
return 0xFF; // other values break some beeper tunes
|
||||
|
||||
dprintf( "Unmapped IN : $%04X\n", addr );
|
||||
debug_printf( "Unmapped IN : $%04X\n", addr );
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Sinclair Spectrum AY music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef AY_EMU_H
|
||||
#define AY_EMU_H
|
||||
|
||||
|
@ -46,7 +46,6 @@ protected:
|
|||
private:
|
||||
file_t file;
|
||||
|
||||
unsigned play_addr;
|
||||
cpu_time_t play_period;
|
||||
cpu_time_t next_play;
|
||||
Blip_Buffer* beeper_output;
|
||||
|
|
|
@ -233,18 +233,32 @@ static void gen_sinc( float* out, int count, double oversample, double treble, d
|
|||
double const to_angle = PI / 2 / maxh / oversample;
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
||||
double cos_angle = cos( angle );
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double angle_maxh = angle * maxh;
|
||||
double angle_maxh_mid = angle_maxh * cutoff;
|
||||
|
||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
||||
double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
|
||||
double b = 2.0 - cos_angle - cos_angle;
|
||||
double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
|
||||
double y = maxh;
|
||||
|
||||
out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
|
||||
// 0 to Fs/2*cutoff, flat
|
||||
if ( angle_maxh_mid ) // unstable at t=0
|
||||
y *= sin( angle_maxh_mid ) / angle_maxh_mid;
|
||||
|
||||
// Fs/2*cutoff to Fs/2, logarithmic rolloff
|
||||
double cosa = cos( angle );
|
||||
double den = 1 + rolloff * (rolloff - cosa - cosa);
|
||||
|
||||
// Becomes unstable when rolloff is near 1.0 and t is near 0,
|
||||
// which is the only time den becomes small
|
||||
if ( den > 1e-13 )
|
||||
{
|
||||
double num =
|
||||
(cos( angle_maxh - angle ) * rolloff - cos( angle_maxh )) * pow_a_n -
|
||||
cos( angle_maxh_mid - angle ) * rolloff + cos( angle_maxh_mid );
|
||||
|
||||
y = y * cutoff + num / den;
|
||||
}
|
||||
|
||||
out [i] = (float) y;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
153
game-music-emu/gme/CMakeLists.txt
Normal file
153
game-music-emu/gme/CMakeLists.txt
Normal file
|
@ -0,0 +1,153 @@
|
|||
# List of source files required by libgme and any emulators
|
||||
# This is not 100% accurate (Fir_Resampler for instance) but
|
||||
# you'll be OK.
|
||||
set(libgme_SRCS Blip_Buffer.cpp
|
||||
Classic_Emu.cpp
|
||||
Data_Reader.cpp
|
||||
Dual_Resampler.cpp
|
||||
Effects_Buffer.cpp
|
||||
Fir_Resampler.cpp
|
||||
gme.cpp
|
||||
Gme_File.cpp
|
||||
M3u_Playlist.cpp
|
||||
Multi_Buffer.cpp
|
||||
Music_Emu.cpp
|
||||
)
|
||||
|
||||
# Ay_Apu is very popular around here
|
||||
if (USE_GME_AY OR USE_GME_KSS)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Ay_Apu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# so is Ym2612_Emu
|
||||
if (USE_GME_VGM OR USE_GME_GYM)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Ym2612_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# But none are as popular as Sms_Apu
|
||||
if (USE_GME_VGM OR USE_GME_GYM OR USE_GME_KSS)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Sms_Apu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_AY)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
# Ay_Apu.cpp included earlier
|
||||
Ay_Cpu.cpp
|
||||
Ay_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_GBS)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Gb_Apu.cpp
|
||||
Gb_Cpu.cpp
|
||||
Gb_Oscs.cpp
|
||||
Gbs_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_GYM)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
# Sms_Apu.cpp included earlier
|
||||
# Ym2612_Emu.cpp included earlier
|
||||
Gym_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_HES)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Hes_Apu.cpp
|
||||
Hes_Cpu.cpp
|
||||
Hes_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_KSS)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
# Ay_Apu.cpp included earlier
|
||||
# Sms_Apu.cpp included earlier
|
||||
Kss_Cpu.cpp
|
||||
Kss_Emu.cpp
|
||||
Kss_Scc_Apu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_NSF OR USE_GME_NSFE)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Nes_Apu.cpp
|
||||
Nes_Cpu.cpp
|
||||
Nes_Fme7_Apu.cpp
|
||||
Nes_Namco_Apu.cpp
|
||||
Nes_Oscs.cpp
|
||||
Nes_Vrc6_Apu.cpp
|
||||
Nsf_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_NSFE)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Nsfe_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_SAP)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Sap_Apu.cpp
|
||||
Sap_Cpu.cpp
|
||||
Sap_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_SPC)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
Snes_Spc.cpp
|
||||
Spc_Cpu.cpp
|
||||
Spc_Dsp.cpp
|
||||
Spc_Emu.cpp
|
||||
Spc_Filter.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (USE_GME_VGM)
|
||||
set(libgme_SRCS ${libgme_SRCS}
|
||||
# Sms_Apu.cpp included earlier
|
||||
# Ym2612_Emu.cpp included earlier
|
||||
Vgm_Emu.cpp
|
||||
Vgm_Emu_Impl.cpp
|
||||
Ym2413_Emu.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# These headers are part of the generic gme interface.
|
||||
set (EXPORTED_HEADERS gme.h)
|
||||
|
||||
# Run during cmake phase, so this is available during make
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gme_types.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/gme_types.h)
|
||||
|
||||
# On some platforms we may need to change headers or whatnot based on whether
|
||||
# we're building the library or merely using the library. The following is
|
||||
# only defined when building the library to allow us to tell which is which.
|
||||
#add_definitions(-DBLARGG_BUILD_DLL)
|
||||
|
||||
# For the gme_types.h
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Add library to be compiled.
|
||||
add_library(gme ${libgme_SRCS})
|
||||
|
||||
# The version is the release. The "soversion" is the API version. As long
|
||||
# as only build fixes are performed (i.e. no backwards-incompatible changes
|
||||
# to the API), the SOVERSION should be the same even when bumping up VERSION.
|
||||
# The way gme.h is designed, SOVERSION should very rarely be bumped, if ever.
|
||||
# Hopefully the API can stay compatible with old versions.
|
||||
#set_target_properties(gme
|
||||
# PROPERTIES VERSION ${GME_VERSION}
|
||||
# SOVERSION 0)
|
||||
target_link_libraries(gme)
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Classic_Emu.h"
|
||||
|
||||
|
@ -176,9 +176,9 @@ void Rom_Data_::set_addr_( long addr, int unit )
|
|||
|
||||
if ( 0 )
|
||||
{
|
||||
dprintf( "addr: %X\n", addr );
|
||||
dprintf( "file_size: %d\n", file_size_ );
|
||||
dprintf( "rounded: %d\n", rounded );
|
||||
dprintf( "mask: $%X\n", mask );
|
||||
debug_printf( "addr: %X\n", addr );
|
||||
debug_printf( "file_size: %d\n", file_size_ );
|
||||
debug_printf( "rounded: %d\n", rounded );
|
||||
debug_printf( "mask: $%X\n", mask );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Common aspects of emulators which use Blip_Buffer for sound output
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef CLASSIC_EMU_H
|
||||
#define CLASSIC_EMU_H
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// File_Extractor 0.4.0. http://www.slack.net/~ant/
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define IN_GME 1
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Data_Reader.h"
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Copyright (C) 2005-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#define DATA_READER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "gme.h"
|
||||
|
||||
// Supports reading and finding out how many bytes are remaining
|
||||
class Data_Reader {
|
||||
|
@ -117,7 +116,7 @@ private:
|
|||
// Invokes callback function to read data. Size of data must be specified in advance.
|
||||
class Callback_Reader : public Data_Reader {
|
||||
public:
|
||||
typedef const char* (GMEAPI *callback_t)( void* data, void* out, int count );
|
||||
typedef const char* (*callback_t)( void* data, void* out, int count );
|
||||
Callback_Reader( callback_t, long size, void* data = 0 );
|
||||
public:
|
||||
long read_avail( void*, long );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Dual_Resampler.h"
|
||||
|
||||
|
@ -20,7 +20,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
unsigned const resampler_extra = 256;
|
||||
|
||||
Dual_Resampler::Dual_Resampler() { }
|
||||
Dual_Resampler::Dual_Resampler() :
|
||||
sample_buf_size(0),
|
||||
oversamples_per_frame(-1),
|
||||
buf_pos(-1),
|
||||
resampler_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
Dual_Resampler::~Dual_Resampler() { }
|
||||
|
||||
|
@ -62,10 +68,10 @@ void Dual_Resampler::play_frame_( Blip_Buffer& blip_buf, dsample_t* out )
|
|||
assert( blip_buf.samples_avail() == pair_count );
|
||||
|
||||
resampler.write( new_count );
|
||||
|
||||
|
||||
long count = resampler.read( sample_buf.begin(), sample_buf_size );
|
||||
assert( count == (long) sample_buf_size );
|
||||
|
||||
|
||||
mix_samples( blip_buf, out );
|
||||
blip_buf.remove_samples( pair_count );
|
||||
}
|
||||
|
@ -121,8 +127,8 @@ void Dual_Resampler::mix_samples( Blip_Buffer& blip_buf, dsample_t* out )
|
|||
r = 0x7FFF - (r >> 24);
|
||||
|
||||
in += 2;
|
||||
out [0] = l;
|
||||
out [1] = r;
|
||||
out [0] = (dsample_t)l;
|
||||
out [1] = (dsample_t)r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators.
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef DUAL_RESAMPLER_H
|
||||
#define DUAL_RESAMPLER_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Effects_Buffer.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Multi-channel effects buffer with panning, echo and reverb
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef EFFECTS_BUFFER_H
|
||||
#define EFFECTS_BUFFER_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Fir_Resampler.h"
|
||||
|
||||
|
@ -156,7 +156,7 @@ int Fir_Resampler_::input_needed( blargg_long output_count ) const
|
|||
output_count -= 2;
|
||||
}
|
||||
|
||||
long input_extra = long(input_count - (write_pos - &buf [(width_ - 1) * stereo]));
|
||||
long input_extra = input_count - (write_pos - &buf [(width_ - 1) * stereo]);
|
||||
if ( input_extra < 0 )
|
||||
input_extra = 0;
|
||||
return input_extra;
|
||||
|
@ -187,7 +187,7 @@ int Fir_Resampler_::avail_( blargg_long input_count ) const
|
|||
int Fir_Resampler_::skip_input( long count )
|
||||
{
|
||||
int remain = int(write_pos - buf.begin());
|
||||
int max_count = remain - width_ * stereo;
|
||||
int max_count = int(remain - width_ * stereo);
|
||||
if ( count > max_count )
|
||||
count = max_count;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Finite impulse response (FIR) resampler with adjustable FIR size
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef FIR_RESAMPLER_H
|
||||
#define FIR_RESAMPLER_H
|
||||
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
int input_needed( blargg_long count ) const;
|
||||
|
||||
// Number of output samples available
|
||||
int avail() const { return avail_( blargg_long(write_pos - &buf [width_ * stereo]) ); }
|
||||
int avail() const { return avail_( blargg_long(write_pos - &buf [width_ * stereo] )); }
|
||||
|
||||
public:
|
||||
~Fir_Resampler_();
|
||||
|
|
|
@ -271,7 +271,7 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
|
|||
}
|
||||
else
|
||||
{
|
||||
//dprintf( "APU powered on\n" );
|
||||
//debug_printf( "APU powered on\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Cpu.h"
|
||||
|
||||
|
@ -94,6 +94,7 @@ unsigned const c_flag = 0x10;
|
|||
// -- produced by the BOOST_STATIC_ASSERT line below
|
||||
#pragma warning(disable:4101)
|
||||
#endif
|
||||
|
||||
bool Gb_Cpu::run( blargg_long cycle_count )
|
||||
{
|
||||
state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
|
||||
|
@ -716,7 +717,7 @@ loop:
|
|||
temp += prev;
|
||||
flags &= z_flag;
|
||||
add_16_hl:
|
||||
rp.hl = temp;
|
||||
rp.hl = (uint16_t)temp;
|
||||
add_16_comm:
|
||||
flags |= (temp >> 12) & c_flag;
|
||||
flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Nintendo Game Boy CPU emulator
|
||||
// Treats every instruction as taking 4 cycles
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef GB_CPU_H
|
||||
#define GB_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gbs_Emu.h"
|
||||
|
||||
|
@ -18,8 +18,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
#include "blargg_source.h"
|
||||
|
||||
Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq = { -47.0, 2000, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Gbs_Emu::equalizer_t const Gbs_Emu::handheld_eq =
|
||||
Music_Emu::make_equalizer( -47.0, 2000 );
|
||||
Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq =
|
||||
Music_Emu::make_equalizer( 0.0, 300 );
|
||||
|
||||
Gbs_Emu::Gbs_Emu()
|
||||
{
|
||||
|
@ -39,8 +41,7 @@ Gbs_Emu::Gbs_Emu()
|
|||
set_max_initial_silence( 21 );
|
||||
set_gain( 1.2 );
|
||||
|
||||
static equalizer_t const eq = { -1.0, 120, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
set_equalizer( eq );
|
||||
set_equalizer( make_equalizer( -1.0, 120 ) );
|
||||
}
|
||||
|
||||
Gbs_Emu::~Gbs_Emu() { }
|
||||
|
@ -151,7 +152,7 @@ void Gbs_Emu::set_bank( int n )
|
|||
{
|
||||
// TODO: what is the correct behavior? Current Game & Watch Gallery
|
||||
// rip requires that this have no effect or set to bank 1.
|
||||
//dprintf( "Selected ROM bank 0\n" );
|
||||
//debug_printf( "Selected ROM bank 0\n" );
|
||||
return;
|
||||
//n = 1;
|
||||
}
|
||||
|
@ -212,11 +213,11 @@ blargg_err_t Gbs_Emu::start_track_( int track )
|
|||
for ( int i = 0; i < (int) sizeof sound_data; i++ )
|
||||
apu.write_register( 0, i + apu.start_addr, sound_data [i] );
|
||||
|
||||
cpu::reset( rom.unmapped() );
|
||||
|
||||
unsigned load_addr = get_le16( header_.load_addr );
|
||||
cpu::rst_base = load_addr;
|
||||
rom.set_addr( load_addr );
|
||||
cpu::rst_base = load_addr;
|
||||
|
||||
cpu::reset( rom.unmapped() );
|
||||
|
||||
cpu::map_code( ram_addr, 0x10000 - ram_addr, ram );
|
||||
cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
|
||||
|
@ -265,13 +266,13 @@ blargg_err_t Gbs_Emu::run_clocks( blip_time_t& duration, int )
|
|||
}
|
||||
else if ( cpu::r.pc > 0xFFFF )
|
||||
{
|
||||
dprintf( "PC wrapped around\n" );
|
||||
debug_printf( "PC wrapped around\n" );
|
||||
cpu::r.pc &= 0xFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_warning( "Emulation error (illegal/unsupported instruction)" );
|
||||
dprintf( "Bad opcode $%.2x at $%.4x\n",
|
||||
debug_printf( "Bad opcode $%.2x at $%.4x\n",
|
||||
(int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
|
||||
cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
|
||||
cpu_time += 6;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Nintendo Game Boy GBS music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef GBS_EMU_H
|
||||
#define GBS_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gme_File.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Common interface to game music file loading and information
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef GME_FILE_H
|
||||
#define GME_FILE_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gym_Emu.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Sega Genesis/Mega Drive GYM music file emulator
|
||||
// Includes with PCM timing recovery to improve sample quality.
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef GYM_EMU_H
|
||||
#define GYM_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Hes_Apu.h"
|
||||
|
||||
|
@ -106,10 +106,10 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
|
|||
unsigned noise_lfsr = this->noise_lfsr;
|
||||
do
|
||||
{
|
||||
int new_dac = 0x1F & (unsigned)-(signed)(noise_lfsr >> 1 & 1);
|
||||
int new_dac = 0x1F & (unsigned)-(int)(noise_lfsr >> 1 & 1);
|
||||
// Implemented using "Galios configuration"
|
||||
// TODO: find correct LFSR algorithm
|
||||
noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & (unsigned)-(signed)(noise_lfsr & 1));
|
||||
noise_lfsr = (noise_lfsr >> 1) ^ (0xE008 & (unsigned)-(int)(noise_lfsr & 1));
|
||||
//noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
|
||||
int delta = new_dac - dac;
|
||||
if ( delta )
|
||||
|
@ -158,7 +158,7 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
|
|||
//period = 0x1000 * 2;
|
||||
period = 1;
|
||||
//if ( !(volume_0 | volume_1) )
|
||||
// dprintf( "Used period 0\n" );
|
||||
// debug_printf( "Used period 0\n" );
|
||||
}
|
||||
|
||||
// maintain phase when silent
|
||||
|
@ -295,7 +295,7 @@ void Hes_Apu::write_data( blip_time_t time, int addr, int data )
|
|||
|
||||
case 0x809:
|
||||
if ( !(data & 0x80) && (data & 0x03) != 0 )
|
||||
dprintf( "HES LFO not supported\n" );
|
||||
debug_printf( "HES LFO not supported\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Turbo Grafx 16 (PC Engine) PSG sound chip emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef HES_APU_H
|
||||
#define HES_APU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Hes_Cpu.h"
|
||||
|
||||
|
@ -148,7 +148,7 @@ loop:
|
|||
/*
|
||||
static long count;
|
||||
if ( count == 1844 ) Debugger();
|
||||
if ( s.base != correct ) dprintf( "%ld\n", count );
|
||||
if ( s.base != correct ) debug_printf( "%ld\n", count );
|
||||
count++;
|
||||
*/
|
||||
}
|
||||
|
@ -741,7 +741,7 @@ possibly_out_of_time:
|
|||
ARITH_ADDR_MODES( 0x65 ) // ADC
|
||||
adc_imm: {
|
||||
if ( status & st_d )
|
||||
dprintf( "Decimal mode not supported\n" );
|
||||
debug_printf( "Decimal mode not supported\n" );
|
||||
fint16 carry = c >> 8 & 1;
|
||||
fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
|
||||
status &= ~st_v;
|
||||
|
@ -1085,7 +1085,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
}
|
||||
delayed_cli:
|
||||
dprintf( "Delayed CLI not supported\n" ); // TODO: implement
|
||||
debug_printf( "Delayed CLI not supported\n" ); // TODO: implement
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -1100,7 +1100,7 @@ possibly_out_of_time:
|
|||
s_time += delta;
|
||||
if ( s_time < 0 )
|
||||
goto loop;
|
||||
dprintf( "Delayed SEI not supported\n" ); // TODO: implement
|
||||
debug_printf( "Delayed SEI not supported\n" ); // TODO: implement
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1145,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
case 0x54: // CSL
|
||||
dprintf( "CSL not supported\n" );
|
||||
debug_printf( "CSL not supported\n" );
|
||||
illegal_encountered = true;
|
||||
goto loop;
|
||||
|
||||
|
@ -1154,7 +1154,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0xF4: { // SET
|
||||
//fuint16 operand = GET_MSB();
|
||||
dprintf( "SET not handled\n" );
|
||||
debug_printf( "SET not handled\n" );
|
||||
//switch ( data )
|
||||
//{
|
||||
//}
|
||||
|
@ -1233,7 +1233,7 @@ possibly_out_of_time:
|
|||
|
||||
default:
|
||||
assert( (unsigned) opcode <= 0xFF );
|
||||
dprintf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
|
||||
debug_printf( "Illegal opcode $%02X at $%04X\n", (int) opcode, (int) pc - 1 );
|
||||
illegal_encountered = true;
|
||||
goto loop;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// PC Engine CPU emulator for use with HES music files
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef HES_CPU_H
|
||||
#define HES_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Hes_Emu.h"
|
||||
|
||||
|
@ -273,12 +273,12 @@ void Hes_Emu::cpu_write_vdp( int addr, int data )
|
|||
}
|
||||
else
|
||||
{
|
||||
dprintf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
|
||||
debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
dprintf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
|
||||
debug_printf( "VDP MSB not supported: $%02X <- $%02X\n", vdp.latch, data );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
|
|||
run_until( time );
|
||||
irq.disables = data;
|
||||
if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
|
||||
dprintf( "Int mask: $%02X\n", data );
|
||||
debug_printf( "Int mask: $%02X\n", data );
|
||||
break;
|
||||
|
||||
case 0x1403:
|
||||
|
@ -344,7 +344,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
|
|||
return;
|
||||
|
||||
default:
|
||||
dprintf( "unmapped write $%04X <- $%02X\n", addr, data );
|
||||
debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
@ -368,14 +368,14 @@ int Hes_Emu::cpu_read_( hes_addr_t addr )
|
|||
|
||||
case 0x0002:
|
||||
case 0x0003:
|
||||
dprintf( "VDP read not supported: %d\n", addr );
|
||||
debug_printf( "VDP read not supported: %d\n", addr );
|
||||
return 0;
|
||||
|
||||
case 0x0C01:
|
||||
//return timer.enabled; // TODO: remove?
|
||||
case 0x0C00:
|
||||
run_until( time );
|
||||
dprintf( "Timer count read\n" );
|
||||
debug_printf( "Timer count read\n" );
|
||||
return (unsigned) (timer.count - 1) / timer_base;
|
||||
|
||||
case 0x1402:
|
||||
|
@ -396,7 +396,7 @@ int Hes_Emu::cpu_read_( hes_addr_t addr )
|
|||
break;
|
||||
|
||||
default:
|
||||
dprintf( "unmapped read $%04X\n", addr );
|
||||
debug_printf( "unmapped read $%04X\n", addr );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// TurboGrafx-16/PC Engine HES music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef HES_EMU_H
|
||||
#define HES_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
/*
|
||||
Last validated with zexall 2006.11.14 2:19 PM
|
||||
|
@ -503,7 +503,7 @@ possibly_out_of_time:
|
|||
add_hl_data: {
|
||||
blargg_ulong sum = rp.hl + data;
|
||||
data ^= rp.hl;
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
flags = (flags & (S80 | Z40 | V04)) |
|
||||
(sum >> 16) |
|
||||
(sum >> 8 & (F20 | F08)) |
|
||||
|
@ -753,7 +753,7 @@ possibly_out_of_time:
|
|||
flags = (flags & (S80 | Z40 | P04)) |
|
||||
(temp & (F20 | F08)) |
|
||||
(temp >> 8);
|
||||
rg.a = temp;
|
||||
rg.a = (uint8_t)temp;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -841,6 +841,7 @@ possibly_out_of_time:
|
|||
case 0xCB:
|
||||
unsigned data2;
|
||||
data2 = instr [1];
|
||||
(void) data2; // TODO is this the same as data in all cases?
|
||||
pc++;
|
||||
switch ( data )
|
||||
{
|
||||
|
@ -1092,7 +1093,7 @@ possibly_out_of_time:
|
|||
(temp >> 8 & H10) |
|
||||
(sum >> 8 & (S80 | F20 | F08)) |
|
||||
((temp - -0x8000) >> 14 & V04);
|
||||
rp.hl = sum;
|
||||
rp.hl = (uint16_t)sum;
|
||||
if ( (uint16_t) sum )
|
||||
goto loop;
|
||||
flags |= Z40;
|
||||
|
@ -1289,7 +1290,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0x4F: // LD R,A
|
||||
SET_R( rg.a );
|
||||
dprintf( "LD R,A not supported\n" );
|
||||
debug_printf( "LD R,A not supported\n" );
|
||||
warning = true;
|
||||
goto loop;
|
||||
|
||||
|
@ -1299,7 +1300,7 @@ possibly_out_of_time:
|
|||
|
||||
case 0x5F: // LD A,R
|
||||
rg.a = GET_R();
|
||||
dprintf( "LD A,R not supported\n" );
|
||||
debug_printf( "LD A,R not supported\n" );
|
||||
warning = true;
|
||||
ld_ai_common:
|
||||
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
||||
|
@ -1322,7 +1323,7 @@ possibly_out_of_time:
|
|||
goto loop;
|
||||
|
||||
default:
|
||||
dprintf( "Opcode $ED $%02X not supported\n", data );
|
||||
debug_printf( "Opcode $ED $%02X not supported\n", data );
|
||||
warning = true;
|
||||
goto loop;
|
||||
}
|
||||
|
@ -1583,7 +1584,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
default:
|
||||
dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||
debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||
warning = true;
|
||||
goto loop;
|
||||
}
|
||||
|
@ -1672,7 +1673,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
default:
|
||||
dprintf( "Unnecessary DD/FD prefix encountered\n" );
|
||||
debug_printf( "Unnecessary DD/FD prefix encountered\n" );
|
||||
warning = true;
|
||||
pc--;
|
||||
goto loop;
|
||||
|
@ -1681,7 +1682,7 @@ possibly_out_of_time:
|
|||
}
|
||||
|
||||
}
|
||||
dprintf( "Unhandled main opcode: $%02X\n", opcode );
|
||||
debug_printf( "Unhandled main opcode: $%02X\n", opcode );
|
||||
assert( false );
|
||||
|
||||
hit_idle_addr:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Z80 CPU emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef KSS_CPU_H
|
||||
#define KSS_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Kss_Emu.h"
|
||||
|
||||
|
@ -230,9 +230,9 @@ blargg_err_t Kss_Emu::start_track_( int track )
|
|||
bank_count = max_banks;
|
||||
set_warning( "Bank data missing" );
|
||||
}
|
||||
//dprintf( "load_size : $%X\n", load_size );
|
||||
//dprintf( "bank_size : $%X\n", bank_size );
|
||||
//dprintf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
|
||||
//debug_printf( "load_size : $%X\n", load_size );
|
||||
//debug_printf( "bank_size : $%X\n", bank_size );
|
||||
//debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
|
||||
|
||||
ram [idle_addr] = 0xFF;
|
||||
cpu::reset( unmapped_write, unmapped_read );
|
||||
|
@ -301,7 +301,7 @@ void Kss_Emu::cpu_write( unsigned addr, int data )
|
|||
return;
|
||||
}
|
||||
|
||||
dprintf( "LD ($%04X),$%02X\n", addr, data );
|
||||
debug_printf( "LD ($%04X),$%02X\n", addr, data );
|
||||
}
|
||||
|
||||
void kss_cpu_write( Kss_Cpu* cpu, unsigned addr, int data )
|
||||
|
@ -358,7 +358,7 @@ void kss_cpu_out( Kss_Cpu* cpu, cpu_time_t time, unsigned addr, int data )
|
|||
#endif
|
||||
}
|
||||
|
||||
dprintf( "OUT $%04X,$%02X\n", addr, data );
|
||||
debug_printf( "OUT $%04X,$%02X\n", addr, data );
|
||||
}
|
||||
|
||||
int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
|
||||
|
@ -368,7 +368,7 @@ int kss_cpu_in( Kss_Cpu*, cpu_time_t, unsigned addr )
|
|||
//{
|
||||
//}
|
||||
|
||||
dprintf( "IN $%04X\n", addr );
|
||||
debug_printf( "IN $%04X\n", addr );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// MSX computer KSS music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef KSS_EMU_H
|
||||
#define KSS_EMU_H
|
||||
|
||||
|
@ -68,7 +68,6 @@ private:
|
|||
void update_gain();
|
||||
|
||||
unsigned scc_enabled; // 0 or 0xC000
|
||||
byte const* bank_data;
|
||||
int bank_count;
|
||||
void set_bank( int logical, int physical );
|
||||
blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Kss_Scc_Apu.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Konami SCC sound chip emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef KSS_SCC_APU_H
|
||||
#define KSS_SCC_APU_H
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
|
||||
#define IN_GME 1
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "M3u_Playlist.h"
|
||||
#include "Music_Emu.h"
|
||||
|
@ -54,9 +52,9 @@ blargg_err_t Gme_File::load_m3u( const char* path ) { return load_m3u_( playlist
|
|||
|
||||
blargg_err_t Gme_File::load_m3u( Data_Reader& in ) { return load_m3u_( playlist.load( in ) ); }
|
||||
|
||||
gme_err_t GMEAPI gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
|
||||
BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu* me, const char* path ) { return me->load_m3u( path ); }
|
||||
|
||||
gme_err_t GMEAPI gme_load_m3u_data( Music_Emu* me, const void* data, long size )
|
||||
BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu* me, const void* data, long size )
|
||||
{
|
||||
Mem_File_Reader in( data, size );
|
||||
return me->load_m3u( in );
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// M3U playlist file parser, with support for subtrack information
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef M3U_PLAYLIST_H
|
||||
#define M3U_PLAYLIST_H
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
|||
int repeat; // count
|
||||
};
|
||||
entry_t const& operator [] ( int i ) const { return entries [i]; }
|
||||
int size() const { return (int)entries.size(); }
|
||||
int size() const { return int(entries.size()); }
|
||||
|
||||
void clear();
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
|
|||
if ( count )
|
||||
{
|
||||
int bufs_used = stereo_added | was_stereo;
|
||||
//dprintf( "%X\n", bufs_used );
|
||||
//debug_printf( "%X\n", bufs_used );
|
||||
if ( bufs_used <= 1 )
|
||||
{
|
||||
mix_mono( out, count );
|
||||
|
@ -171,8 +171,8 @@ void Stereo_Buffer::mix_stereo( blip_sample_t* out_, blargg_long count )
|
|||
BLIP_READER_NEXT( left, bass );
|
||||
BLIP_READER_NEXT( right, bass );
|
||||
|
||||
out [0] = l;
|
||||
out [1] = r;
|
||||
out [0] = (blip_sample_t)l;
|
||||
out [1] = (blip_sample_t)r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
|
@ -201,8 +201,8 @@ void Stereo_Buffer::mix_stereo_no_center( blip_sample_t* out_, blargg_long count
|
|||
BLIP_READER_NEXT( left, bass );
|
||||
BLIP_READER_NEXT( right, bass );
|
||||
|
||||
out [0] = l;
|
||||
out [1] = r;
|
||||
out [0] = (blip_sample_t)l;
|
||||
out [1] = (blip_sample_t)r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
|
@ -223,8 +223,8 @@ void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
|
|||
s = 0x7FFF - (s >> 24);
|
||||
|
||||
BLIP_READER_NEXT( center, bass );
|
||||
out [0] = s;
|
||||
out [1] = s;
|
||||
out [0] = (blip_sample_t)s;
|
||||
out [1] = (blip_sample_t)s;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Music_Emu.h"
|
||||
|
||||
|
@ -24,7 +24,8 @@ int const silence_threshold = 0x10;
|
|||
long const fade_block_size = 512;
|
||||
int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
|
||||
|
||||
Music_Emu::equalizer_t const Music_Emu::tv_eq = { -8.0, 180, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Music_Emu::equalizer_t const Music_Emu::tv_eq =
|
||||
Music_Emu::make_equalizer( -8.0, 180 );
|
||||
|
||||
void Music_Emu::clear_track_vars()
|
||||
{
|
||||
|
@ -305,7 +306,7 @@ static long count_silence( Music_Emu::sample_t* begin, long size )
|
|||
Music_Emu::sample_t* p = begin + size;
|
||||
while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
|
||||
*begin = first;
|
||||
return size - long(p - begin);
|
||||
return size - (p - begin);
|
||||
}
|
||||
|
||||
// fill internal buffer and check it for silence
|
||||
|
@ -340,7 +341,7 @@ blargg_err_t Music_Emu::play( long out_count, sample_t* out )
|
|||
assert( emu_time >= out_time );
|
||||
|
||||
// prints nifty graph of how far ahead we are when searching for silence
|
||||
//dprintf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
|
||||
//debug_printf( "%*s \n", int ((emu_time - out_time) * 7 / sample_rate()), "*" );
|
||||
|
||||
long pos = 0;
|
||||
if ( silence_count )
|
||||
|
@ -404,6 +405,7 @@ blargg_err_t Gme_Info_::set_sample_rate_( long ) { return 0; }
|
|||
void Gme_Info_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
|
||||
void Gme_Info_::post_load_() { Gme_File::post_load_(); } // skip Music_Emu
|
||||
void Gme_Info_::set_equalizer_( equalizer_t const& ){ check( false ); }
|
||||
void Gme_Info_::enable_accuracy_( bool ) { check( false ); }
|
||||
void Gme_Info_::mute_voices_( int ) { check( false ); }
|
||||
void Gme_Info_::set_tempo_( double ) { }
|
||||
blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Common interface to game music file emulators
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef MUSIC_EMU_H
|
||||
#define MUSIC_EMU_H
|
||||
|
||||
|
@ -82,6 +82,10 @@ public:
|
|||
// on others this has no effect. Should be called only once *before* set_sample_rate().
|
||||
virtual void set_buffer( Multi_Buffer* ) { }
|
||||
|
||||
// Enables/disables accurate emulation options, if any are supported. Might change
|
||||
// equalizer settings.
|
||||
void enable_accuracy( bool enable = true );
|
||||
|
||||
// Sound equalization (treble/bass)
|
||||
|
||||
// Frequency equalizer parameters (see gme.txt)
|
||||
|
@ -93,6 +97,14 @@ public:
|
|||
|
||||
// Set frequency equalizer parameters
|
||||
void set_equalizer( equalizer_t const& );
|
||||
|
||||
// Construct equalizer of given treble/bass settings
|
||||
static const equalizer_t make_equalizer( double treble, double bass )
|
||||
{
|
||||
const Music_Emu::equalizer_t e = { treble, bass,
|
||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
return e;
|
||||
}
|
||||
|
||||
// Equalizer settings for TV speaker
|
||||
static equalizer_t const tv_eq;
|
||||
|
@ -111,7 +123,8 @@ protected:
|
|||
void remute_voices();
|
||||
|
||||
virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0;
|
||||
virtual void set_equalizer_( equalizer_t const& ) { };
|
||||
virtual void set_equalizer_( equalizer_t const& ) { }
|
||||
virtual void enable_accuracy_( bool /* enable */ ) { }
|
||||
virtual void mute_voices_( int mask ) = 0;
|
||||
virtual void set_tempo_( double ) = 0;
|
||||
virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this
|
||||
|
@ -160,8 +173,8 @@ private:
|
|||
void emu_play( long count, sample_t* out );
|
||||
|
||||
Multi_Buffer* effects_buffer;
|
||||
friend GMEDLL Music_Emu* GMEAPI gme_new_emu( gme_type_t, int );
|
||||
friend GMEDLL void GMEAPI gme_set_stereo_depth( Music_Emu*, double );
|
||||
friend Music_Emu* gme_new_emu( gme_type_t, int );
|
||||
friend void gme_set_stereo_depth( Music_Emu*, double );
|
||||
};
|
||||
|
||||
// base class for info-only derivations
|
||||
|
@ -169,6 +182,7 @@ struct Gme_Info_ : Music_Emu
|
|||
{
|
||||
virtual blargg_err_t set_sample_rate_( long sample_rate );
|
||||
virtual void set_equalizer_( equalizer_t const& );
|
||||
virtual void enable_accuracy_( bool );
|
||||
virtual void mute_voices_( int mask );
|
||||
virtual void set_tempo_( double );
|
||||
virtual blargg_err_t start_track_( int );
|
||||
|
@ -189,6 +203,7 @@ inline int Music_Emu::current_track() const { return current_track_; }
|
|||
inline bool Music_Emu::track_ended() const { return track_ended_; }
|
||||
inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; }
|
||||
|
||||
inline void Music_Emu::enable_accuracy( bool b ) { enable_accuracy_( b ); }
|
||||
inline void Music_Emu::set_tempo_( double t ) { tempo_ = t; }
|
||||
inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); }
|
||||
inline void Music_Emu::ignore_silence( bool b ) { ignore_silence_ = b; }
|
||||
|
|
|
@ -385,7 +385,7 @@ int Nes_Apu::read_status( nes_time_t time )
|
|||
irq_changed();
|
||||
}
|
||||
|
||||
//dprintf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
|
||||
//debug_printf( "%6d/%d Read $4015->$%02X\n", frame_delay, frame, result );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nes_Cpu.h"
|
||||
|
||||
|
@ -921,7 +921,7 @@ imm##op:
|
|||
goto loop;
|
||||
status &= ~st_i;
|
||||
handle_cli: {
|
||||
//dprintf( "CLI at %d\n", TIME );
|
||||
//debug_printf( "CLI at %d\n", TIME );
|
||||
this->r.status = status; // update externally-visible I flag
|
||||
blargg_long delta = s.base - irq_time_;
|
||||
if ( delta <= 0 )
|
||||
|
@ -944,7 +944,7 @@ imm##op:
|
|||
|
||||
// TODO: implement
|
||||
delayed_cli:
|
||||
dprintf( "Delayed CLI not emulated\n" );
|
||||
debug_printf( "Delayed CLI not emulated\n" );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -960,7 +960,7 @@ imm##op:
|
|||
if ( s_time < 0 )
|
||||
goto loop;
|
||||
|
||||
dprintf( "Delayed SEI not emulated\n" );
|
||||
debug_printf( "Delayed SEI not emulated\n" );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// NES 6502 CPU emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef NES_CPU_H
|
||||
#define NES_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nes_Fme7_Apu.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@ void Nes_Fme7_Apu::run_until( blip_time_t end_time )
|
|||
// check for unsupported mode
|
||||
#ifndef NDEBUG
|
||||
if ( (mode & 011) <= 001 && vol_mode & 0x1F )
|
||||
dprintf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
|
||||
debug_printf( "FME7 used unimplemented sound mode: %02X, vol_mode: %02X\n",
|
||||
mode, vol_mode & 0x1F );
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Sunsoft FME-7 sound emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef NES_FME7_APU_H
|
||||
#define NES_FME7_APU_H
|
||||
|
||||
|
@ -97,8 +97,8 @@ inline void Nes_Fme7_Apu::write_data( blip_time_t time, int data )
|
|||
{
|
||||
if ( (unsigned) latch >= reg_count )
|
||||
{
|
||||
#ifdef dprintf
|
||||
dprintf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
|
||||
#ifdef debug_printf
|
||||
debug_printf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Nsf_Emu.h"
|
||||
|
||||
|
@ -31,8 +31,10 @@ int const fme7_flag = 0x20;
|
|||
|
||||
long const clock_divisor = 12;
|
||||
|
||||
Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq = { -1.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
Nsf_Emu::equalizer_t const Nsf_Emu::nes_eq =
|
||||
Music_Emu::make_equalizer( -1.0, 80 );
|
||||
Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq =
|
||||
Music_Emu::make_equalizer( -15.0, 80 );
|
||||
|
||||
int Nsf_Emu::pcm_read( void* emu, nes_addr_t addr )
|
||||
{
|
||||
|
@ -442,7 +444,7 @@ void Nsf_Emu::cpu_write_misc( nes_addr_t addr, int data )
|
|||
// memory mapper?
|
||||
if ( addr == 0xFFF8 ) return;
|
||||
|
||||
dprintf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
|
||||
debug_printf( "write_unmapped( 0x%04X, 0x%02X )\n", (unsigned) addr, (unsigned) data );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Nintendo NES/Famicom NSF music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef NSF_EMU_H
|
||||
#define NSF_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
|
@ -137,7 +137,7 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
|
|||
blargg_long size = get_le32( block_header [0] );
|
||||
blargg_long tag = get_le32( block_header [1] );
|
||||
|
||||
//dprintf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
|
||||
//debug_printf( "tag: %c%c%c%c\n", char(tag), char(tag>>8), char(tag>>16), char(tag>>24) );
|
||||
|
||||
switch ( tag )
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Nintendo NES/Famicom NSFE music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef NSFE_EMU_H
|
||||
#define NSFE_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Sap_Apu.h"
|
||||
|
||||
|
@ -66,7 +66,7 @@ Sap_Apu_Impl::Sap_Apu_Impl()
|
|||
blargg_ulong rev = n & 1;
|
||||
for ( int i = 1; i < poly5_len; i++ )
|
||||
rev |= (n >> i & 1) << (poly5_len - i);
|
||||
dprintf( "poly5: 0x%08lX\n", rev );
|
||||
debug_printf( "poly5: 0x%08lX\n", rev );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ inline void Sap_Apu::calc_periods()
|
|||
period = (period - 6) * divider;
|
||||
|
||||
if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
|
||||
dprintf( "Use of slave channel in 16-bit mode not supported\n" );
|
||||
debug_printf( "Use of slave channel in 16-bit mode not supported\n" );
|
||||
}
|
||||
}
|
||||
osc->period = period;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Atari POKEY sound chip emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SAP_APU_H
|
||||
#define SAP_APU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Sap_Cpu.h"
|
||||
|
||||
|
@ -889,7 +889,7 @@ imm##op:
|
|||
goto loop;
|
||||
}
|
||||
delayed_cli:
|
||||
dprintf( "Delayed CLI not emulated\n" );
|
||||
debug_printf( "Delayed CLI not emulated\n" );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -904,7 +904,7 @@ imm##op:
|
|||
s_time += delta;
|
||||
if ( s_time < 0 )
|
||||
goto loop;
|
||||
dprintf( "Delayed SEI not emulated\n" );
|
||||
debug_printf( "Delayed SEI not emulated\n" );
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -945,7 +945,7 @@ handle_brk:
|
|||
goto idle_done;
|
||||
pc++;
|
||||
result_ = 4;
|
||||
dprintf( "BRK executed\n" );
|
||||
debug_printf( "BRK executed\n" );
|
||||
|
||||
interrupt:
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Atari 6502 CPU emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SAP_CPU_H
|
||||
#define SAP_CPU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Sap_Emu.h"
|
||||
|
||||
|
@ -336,7 +336,7 @@ blargg_err_t Sap_Emu::start_track_( int track )
|
|||
{
|
||||
unsigned start = get_le16( in );
|
||||
unsigned end = get_le16( in + 2 );
|
||||
//dprintf( "Block $%04X-$%04X\n", start, end );
|
||||
//debug_printf( "Block $%04X-$%04X\n", start, end );
|
||||
in += 4;
|
||||
if ( end < start )
|
||||
{
|
||||
|
@ -390,7 +390,7 @@ void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
|
|||
}
|
||||
|
||||
if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
|
||||
dprintf( "Unmapped write $%04X <- $%02X\n", addr, data );
|
||||
debug_printf( "Unmapped write $%04X <- $%02X\n", addr, data );
|
||||
}
|
||||
|
||||
inline void Sap_Emu::call_play()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Atari XL/XE SAP music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SAP_EMU_H
|
||||
#define SAP_EMU_H
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPC emulation support: init, sample buffering, reset, SPC loading
|
||||
|
||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Snes_Spc.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SNES SPC-700 APU emulator
|
||||
|
||||
// snes_spc 0.9.0
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SNES_SPC_H
|
||||
#define SNES_SPC_H
|
||||
|
||||
|
@ -66,10 +66,7 @@ public:
|
|||
// Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc.
|
||||
enum { tempo_unit = 0x100 };
|
||||
void set_tempo( int );
|
||||
|
||||
enum { gain_unit = Spc_Dsp::gain_unit };
|
||||
void set_gain( int gain );
|
||||
|
||||
|
||||
// SPC music files
|
||||
|
||||
// Loads SPC data into emulator
|
||||
|
@ -107,6 +104,22 @@ public:
|
|||
bool check_kon();
|
||||
#endif
|
||||
|
||||
public:
|
||||
// TODO: document
|
||||
struct regs_t
|
||||
{
|
||||
int pc;
|
||||
int a;
|
||||
int x;
|
||||
int y;
|
||||
int psw;
|
||||
int sp;
|
||||
};
|
||||
regs_t& smp_regs() { return m.cpu_regs; }
|
||||
|
||||
uint8_t* smp_ram() { return m.ram.ram; }
|
||||
|
||||
void run_until( time_t t ) { run_until_( t ); }
|
||||
public:
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
|
||||
|
@ -146,15 +159,7 @@ private:
|
|||
|
||||
uint8_t smp_regs [2] [reg_count];
|
||||
|
||||
struct
|
||||
{
|
||||
int pc;
|
||||
int a;
|
||||
int x;
|
||||
int y;
|
||||
int psw;
|
||||
int sp;
|
||||
} cpu_regs;
|
||||
regs_t cpu_regs;
|
||||
|
||||
rel_time_t dsp_time;
|
||||
time_t spc_time;
|
||||
|
@ -271,8 +276,6 @@ inline void Snes_Spc::write_port( time_t t, int port, int data )
|
|||
run_until_( t ) [0x10 + port] = data;
|
||||
}
|
||||
|
||||
inline void Snes_Spc::set_gain( int gain ) { dsp.set_gain( gain ); }
|
||||
|
||||
inline void Snes_Spc::mute_voices( int mask ) { dsp.mute_voices( mask ); }
|
||||
|
||||
inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Core SPC emulation: CPU, timers, SMP registers, memory
|
||||
|
||||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Snes_Spc.h"
|
||||
|
||||
|
@ -176,7 +176,7 @@ inline void Snes_Spc::dsp_write( int data, rel_time_t time )
|
|||
if ( REGS [r_dspaddr] <= 0x7F )
|
||||
dsp.write( REGS [r_dspaddr], data );
|
||||
else if ( !SPC_MORE_ACCURACY )
|
||||
dprintf( "SPC wrote to DSP register > $7F\n" );
|
||||
debug_printf( "SPC wrote to DSP register > $7F\n" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -277,8 +277,9 @@ static unsigned char const glitch_probs [3] [256] =
|
|||
};
|
||||
#endif
|
||||
|
||||
// divided into multiple functions to keep rarely-used functionality separate
|
||||
// so often-used functionality can be optimized better by compiler
|
||||
// Read/write handlers are divided into multiple functions to keep rarely-used
|
||||
// functionality separate so often-used functionality can be optimized better
|
||||
// by compiler.
|
||||
|
||||
// If write isn't preceded by read, data has this added to it
|
||||
int const no_read_before_write = 0x2000;
|
||||
|
@ -302,7 +303,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
|
|||
t->next_time == time + TIMER_MUL( t, 1 ) &&
|
||||
((period - 1) | ~0x0F) & period )
|
||||
{
|
||||
//dprintf( "SPC pathological timer target write\n" );
|
||||
//debug_printf( "SPC pathological timer target write\n" );
|
||||
|
||||
// If the period is 3, 5, or 9, there's a probability this behavior won't occur,
|
||||
// based on the previous period
|
||||
|
@ -331,7 +332,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
|
|||
case r_t1out:
|
||||
case r_t2out:
|
||||
if ( !SPC_MORE_ACCURACY )
|
||||
dprintf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
|
||||
debug_printf( "SPC wrote to counter %d\n", (int) addr - r_t0out );
|
||||
|
||||
if ( data < no_read_before_write / 2 )
|
||||
run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
|
||||
|
@ -345,7 +346,7 @@ void Snes_Spc::cpu_write_smp_reg_( int data, rel_time_t time, int addr )
|
|||
|
||||
case r_test:
|
||||
if ( (uint8_t) data != 0x0A )
|
||||
dprintf( "SPC wrote to test register\n" );
|
||||
debug_printf( "SPC wrote to test register\n" );
|
||||
break;
|
||||
|
||||
case r_control:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
/* Copyright (C) 2004-2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
|
@ -16,7 +16,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
#if SPC_MORE_ACCURACY
|
||||
#define SUSPICIOUS_OPCODE( name ) ((void) 0)
|
||||
#else
|
||||
#define SUSPICIOUS_OPCODE( name ) dprintf( "SPC: suspicious opcode: " name "\n" )
|
||||
#define SUSPICIOUS_OPCODE( name ) debug_printf( "SPC: suspicious opcode: " name "\n" )
|
||||
#endif
|
||||
|
||||
#define CPU_READ( time, offset, addr )\
|
||||
|
@ -242,7 +242,7 @@ loop:
|
|||
BRANCH( (uint8_t) nz )
|
||||
|
||||
case 0x3F:{// CALL
|
||||
int old_addr = int(GET_PC() + 2);
|
||||
int old_addr = GET_PC() + 2;
|
||||
SET_PC( READ_PC16( pc ) );
|
||||
PUSH16( old_addr );
|
||||
goto loop;
|
||||
|
@ -1184,7 +1184,7 @@ loop:
|
|||
{
|
||||
addr &= 0xFFFF;
|
||||
SET_PC( addr );
|
||||
dprintf( "SPC: PC wrapped around\n" );
|
||||
debug_printf( "SPC: PC wrapped around\n" );
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
|
@ -1205,7 +1205,7 @@ stop:
|
|||
|
||||
// Uncache registers
|
||||
if ( GET_PC() >= 0x10000 )
|
||||
dprintf( "SPC: PC wrapped around\n" );
|
||||
debug_printf( "SPC: PC wrapped around\n" );
|
||||
m.cpu_regs.pc = (uint16_t) GET_PC();
|
||||
m.cpu_regs.sp = ( uint8_t) GET_SP();
|
||||
m.cpu_regs.a = ( uint8_t) a;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// snes_spc 0.9.0. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Spc_Dsp.h"
|
||||
|
||||
|
@ -606,8 +606,8 @@ skip_brr:
|
|||
}
|
||||
|
||||
// Sound out
|
||||
int l = (((main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14) * m.gain) >> 8;
|
||||
int r = (((main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14) * m.gain) >> 8;
|
||||
int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14;
|
||||
int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14;
|
||||
|
||||
CLAMP16( l );
|
||||
CLAMP16( r );
|
||||
|
@ -641,7 +641,6 @@ void Spc_Dsp::mute_voices( int mask )
|
|||
void Spc_Dsp::init( void* ram_64k )
|
||||
{
|
||||
m.ram = (uint8_t*) ram_64k;
|
||||
set_gain( gain_unit );
|
||||
mute_voices( 0 );
|
||||
disable_surround( false );
|
||||
set_output( 0, 0 );
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// Fast SNES SPC-700 DSP emulator (about 3x speed of accurate one)
|
||||
|
||||
// snes_spc 0.9.0
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SPC_DSP_H
|
||||
#define SPC_DSP_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
class Spc_Dsp {
|
||||
struct Spc_Dsp {
|
||||
public:
|
||||
typedef BOOST::uint8_t uint8_t;
|
||||
|
||||
|
@ -51,10 +51,7 @@ public:
|
|||
|
||||
// If true, prevents channels and global volumes from being phase-negated
|
||||
void disable_surround( bool disable = true );
|
||||
|
||||
enum { gain_unit = 0x100 };
|
||||
void set_gain( int gain );
|
||||
|
||||
|
||||
// State
|
||||
|
||||
// Resets DSP and uses supplied values to initialize registers
|
||||
|
@ -140,7 +137,6 @@ private:
|
|||
// non-emulation state
|
||||
uint8_t* ram; // 64K shared RAM between DSP and SMP
|
||||
int mute_mask;
|
||||
int gain;
|
||||
int surround_threshold;
|
||||
sample_t* out;
|
||||
sample_t* out_end;
|
||||
|
@ -204,8 +200,6 @@ inline void Spc_Dsp::write( int addr, int data )
|
|||
}
|
||||
}
|
||||
|
||||
inline void Spc_Dsp::set_gain( int gain ) { m.gain = gain; }
|
||||
|
||||
inline void Spc_Dsp::disable_surround( bool disable )
|
||||
{
|
||||
m.surround_threshold = disable ? 0 : -0x4000;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Spc_Emu.h"
|
||||
|
||||
|
@ -19,6 +19,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
#include "blargg_source.h"
|
||||
|
||||
// TODO: support Spc_Filter's bass
|
||||
|
||||
Spc_Emu::Spc_Emu()
|
||||
{
|
||||
set_type( gme_spc_type );
|
||||
|
@ -54,7 +56,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
|
|||
byte const* in = begin + 8;
|
||||
if ( end - in > info_size )
|
||||
{
|
||||
dprintf( "Extra data after SPC xid6 info\n" );
|
||||
debug_printf( "Extra data after SPC xid6 info\n" );
|
||||
end = in + info_size;
|
||||
}
|
||||
|
||||
|
@ -114,7 +116,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
|
|||
default:
|
||||
if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
|
||||
(id > 0x14 && id < 0x30) || id > 0x36 )
|
||||
dprintf( "Unknown SPC xid6 block: %X\n", (int) id );
|
||||
debug_printf( "Unknown SPC xid6 block: %X\n", (int) id );
|
||||
break;
|
||||
}
|
||||
if ( field )
|
||||
|
@ -134,7 +136,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
|
|||
{
|
||||
// ...but some files have no padding
|
||||
in = unaligned;
|
||||
dprintf( "SPC info tag wasn't properly padded to align\n" );
|
||||
debug_printf( "SPC info tag wasn't properly padded to align\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -244,12 +246,13 @@ static Music_Emu* new_spc_file() { return BLARGG_NEW Spc_File; }
|
|||
static gme_type_t_ const gme_spc_type_ = { "Super Nintendo", 1, &new_spc_emu, &new_spc_file, "SPC", 0 };
|
||||
gme_type_t const gme_spc_type = &gme_spc_type_;
|
||||
|
||||
|
||||
// Setup
|
||||
|
||||
blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
|
||||
{
|
||||
RETURN_ERR( apu.init() );
|
||||
apu.set_gain( (int) (gain() * Snes_Spc::gain_unit) );
|
||||
enable_accuracy( false );
|
||||
if ( sample_rate != native_sample_rate )
|
||||
{
|
||||
RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
|
||||
|
@ -258,6 +261,12 @@ blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Spc_Emu::enable_accuracy_( bool b )
|
||||
{
|
||||
Music_Emu::enable_accuracy_( b );
|
||||
filter.enable( b );
|
||||
}
|
||||
|
||||
void Spc_Emu::mute_voices_( int m )
|
||||
{
|
||||
Music_Emu::mute_voices_( m );
|
||||
|
@ -277,17 +286,29 @@ blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
|
|||
|
||||
// Emulation
|
||||
|
||||
void Spc_Emu::set_tempo_( double t ) { apu.set_tempo( (int) (t * Snes_Spc::tempo_unit) ); }
|
||||
void Spc_Emu::set_tempo_( double t )
|
||||
{
|
||||
apu.set_tempo( (int) (t * apu.tempo_unit) );
|
||||
}
|
||||
|
||||
blargg_err_t Spc_Emu::start_track_( int track )
|
||||
{
|
||||
RETURN_ERR( Music_Emu::start_track_( track ) );
|
||||
resampler.clear();
|
||||
filter.clear();
|
||||
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
||||
filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
|
||||
apu.clear_echo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
blargg_err_t Spc_Emu::play_and_filter( long count, sample_t out [] )
|
||||
{
|
||||
RETURN_ERR( apu.play( count, out ) );
|
||||
filter.run( out, count );
|
||||
return 0;
|
||||
}
|
||||
|
||||
blargg_err_t Spc_Emu::skip_( long count )
|
||||
{
|
||||
if ( sample_rate() != native_sample_rate )
|
||||
|
@ -299,7 +320,10 @@ blargg_err_t Spc_Emu::skip_( long count )
|
|||
// TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
|
||||
|
||||
if ( count > 0 )
|
||||
{
|
||||
RETURN_ERR( apu.skip( count ) );
|
||||
filter.clear();
|
||||
}
|
||||
|
||||
// eliminate pop due to resampler
|
||||
const int resampler_latency = 64;
|
||||
|
@ -310,7 +334,7 @@ blargg_err_t Spc_Emu::skip_( long count )
|
|||
blargg_err_t Spc_Emu::play_( long count, sample_t* out )
|
||||
{
|
||||
if ( sample_rate() == native_sample_rate )
|
||||
return apu.play( count, out );
|
||||
return play_and_filter( count, out );
|
||||
|
||||
long remain = count;
|
||||
while ( remain > 0 )
|
||||
|
@ -319,7 +343,7 @@ blargg_err_t Spc_Emu::play_( long count, sample_t* out )
|
|||
if ( remain > 0 )
|
||||
{
|
||||
long n = resampler.max_write();
|
||||
RETURN_ERR( apu.play( n, resampler.buffer() ) );
|
||||
RETURN_ERR( play_and_filter( n, resampler.buffer() ) );
|
||||
resampler.write( n );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// Super Nintendo SPC music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SPC_EMU_H
|
||||
#define SPC_EMU_H
|
||||
|
||||
#include "Fir_Resampler.h"
|
||||
#include "Music_Emu.h"
|
||||
#include "Snes_Spc.h"
|
||||
#include "Spc_Filter.h"
|
||||
|
||||
class Spc_Emu : public Music_Emu {
|
||||
public:
|
||||
|
@ -65,11 +66,15 @@ protected:
|
|||
blargg_err_t skip_( long );
|
||||
void mute_voices_( int );
|
||||
void set_tempo_( double );
|
||||
void enable_accuracy_( bool );
|
||||
private:
|
||||
byte const* file_data;
|
||||
long file_size;
|
||||
Fir_Resampler<24> resampler;
|
||||
SPC_Filter filter;
|
||||
Snes_Spc apu;
|
||||
|
||||
blargg_err_t play_and_filter( long count, sample_t out [] );
|
||||
};
|
||||
|
||||
inline void Spc_Emu::disable_surround( bool b ) { apu.disable_surround( b ); }
|
||||
|
|
83
game-music-emu/gme/Spc_Filter.cpp
Normal file
83
game-music-emu/gme/Spc_Filter.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Spc_Filter.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version. This
|
||||
module is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
details. You should have received a copy of the GNU Lesser General Public
|
||||
License along with this module; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
void SPC_Filter::clear() { memset( ch, 0, sizeof ch ); }
|
||||
|
||||
SPC_Filter::SPC_Filter()
|
||||
{
|
||||
enabled = true;
|
||||
gain = gain_unit;
|
||||
bass = bass_norm;
|
||||
clear();
|
||||
}
|
||||
|
||||
void SPC_Filter::run( short* io, int count )
|
||||
{
|
||||
require( (count & 1) == 0 ); // must be even
|
||||
|
||||
int const gain = this->gain;
|
||||
if ( enabled )
|
||||
{
|
||||
int const bass = this->bass;
|
||||
chan_t* c = &ch [2];
|
||||
do
|
||||
{
|
||||
// cache in registers
|
||||
int sum = (--c)->sum;
|
||||
int pp1 = c->pp1;
|
||||
int p1 = c->p1;
|
||||
|
||||
for ( int i = 0; i < count; i += 2 )
|
||||
{
|
||||
// Low-pass filter (two point FIR with coeffs 0.25, 0.75)
|
||||
int f = io [i] + p1;
|
||||
p1 = io [i] * 3;
|
||||
|
||||
// High-pass filter ("leaky integrator")
|
||||
int delta = f - pp1;
|
||||
pp1 = f;
|
||||
int s = sum >> (gain_bits + 2);
|
||||
sum += (delta * gain) - (sum >> bass);
|
||||
|
||||
// Clamp to 16 bits
|
||||
if ( (short) s != s )
|
||||
s = (s >> 31) ^ 0x7FFF;
|
||||
|
||||
io [i] = (short) s;
|
||||
}
|
||||
|
||||
c->p1 = p1;
|
||||
c->pp1 = pp1;
|
||||
c->sum = sum;
|
||||
++io;
|
||||
}
|
||||
while ( c != ch );
|
||||
}
|
||||
else if ( gain != gain_unit )
|
||||
{
|
||||
short* const end = io + count;
|
||||
while ( io < end )
|
||||
{
|
||||
int s = (*io * gain) >> gain_bits;
|
||||
if ( (short) s != s )
|
||||
s = (s >> 31) ^ 0x7FFF;
|
||||
*io++ = (short) s;
|
||||
}
|
||||
}
|
||||
}
|
53
game-music-emu/gme/Spc_Filter.h
Normal file
53
game-music-emu/gme/Spc_Filter.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Simple low-pass and high-pass filter to better match sound output of a SNES
|
||||
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef SPC_FILTER_H
|
||||
#define SPC_FILTER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
struct SPC_Filter {
|
||||
public:
|
||||
|
||||
// Filters count samples of stereo sound in place. Count must be a multiple of 2.
|
||||
typedef short sample_t;
|
||||
void run( sample_t* io, int count );
|
||||
|
||||
// Optional features
|
||||
|
||||
// Clears filter to silence
|
||||
void clear();
|
||||
|
||||
// Sets gain (volume), where gain_unit is normal. Gains greater than gain_unit
|
||||
// are fine, since output is clamped to 16-bit sample range.
|
||||
enum { gain_unit = 0x100 };
|
||||
void set_gain( int gain );
|
||||
|
||||
// Enables/disables filtering (when disabled, gain is still applied)
|
||||
void enable( bool b );
|
||||
|
||||
// Sets amount of bass (logarithmic scale)
|
||||
enum { bass_none = 0 };
|
||||
enum { bass_norm = 8 }; // normal amount
|
||||
enum { bass_max = 31 };
|
||||
void set_bass( int bass );
|
||||
|
||||
public:
|
||||
SPC_Filter();
|
||||
BLARGG_DISABLE_NOTHROW
|
||||
private:
|
||||
enum { gain_bits = 8 };
|
||||
int gain;
|
||||
int bass;
|
||||
bool enabled;
|
||||
struct chan_t { int p1, pp1, sum; };
|
||||
chan_t ch [2];
|
||||
};
|
||||
|
||||
inline void SPC_Filter::enable( bool b ) { enabled = b; }
|
||||
|
||||
inline void SPC_Filter::set_gain( int g ) { gain = g; }
|
||||
|
||||
inline void SPC_Filter::set_bass( int b ) { bass = b; }
|
||||
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Vgm_Emu.h"
|
||||
|
||||
|
@ -36,8 +36,7 @@ Vgm_Emu::Vgm_Emu()
|
|||
|
||||
set_silence_lookahead( 1 ); // tracks should already be trimmed
|
||||
|
||||
static equalizer_t const eq = { -14.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
set_equalizer( eq );
|
||||
set_equalizer( make_equalizer( -14.0, 80 ) );
|
||||
}
|
||||
|
||||
Vgm_Emu::~Vgm_Emu() { }
|
||||
|
@ -218,8 +217,8 @@ void Vgm_Emu::set_tempo_( double t )
|
|||
{
|
||||
vgm_rate = (long) (44100 * t + 0.5);
|
||||
blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 0.5 );
|
||||
//dprintf( "blip_time_factor: %ld\n", blip_time_factor );
|
||||
//dprintf( "vgm_rate: %ld\n", vgm_rate );
|
||||
//debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
|
||||
//debug_printf( "vgm_rate: %ld\n", vgm_rate );
|
||||
// TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
|
||||
//blip_time_factor = (long) floor( double (1L << blip_time_bits) * psg_rate / 44100 / t + 0.5 );
|
||||
//vgm_rate = (long) floor( double (1L << blip_time_bits) * psg_rate / blip_time_factor + 0.5 );
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Sega Master System/Mark III, Sega Genesis/Mega Drive, BBC Micro VGM music file emulator
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef VGM_EMU_H
|
||||
#define VGM_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Vgm_Emu.h"
|
||||
|
||||
|
@ -244,7 +244,7 @@ int Vgm_Emu_Impl::play_frame( blip_time_t blip_time, int sample_count, sample_t*
|
|||
int pairs = min_pairs;
|
||||
while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
|
||||
vgm_time++;
|
||||
//dprintf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
|
||||
//debug_printf( "pairs: %d, min_pairs: %d\n", pairs, min_pairs );
|
||||
|
||||
if ( ym2612.enabled() )
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Low-level parts of Vgm_Emu
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef VGM_EMU_IMPL_H
|
||||
#define VGM_EMU_IMPL_H
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
// Use in place of Ym2413_Emu.cpp and ym2413.c to disable support for this chip
|
||||
|
||||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2413_Emu.h"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// YM2413 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef YM2413_EMU_H
|
||||
#define YM2413_EMU_H
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
// Based on Gens 2.10 ym2612.c
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2002 Stéphane Dallongeville (gens AT consolemul.com) */
|
||||
/* Copyright (C) 2002 Stephane Dallongeville (gens AT consolemul.com) */
|
||||
/* Copyright (C) 2004-2006 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
General Public License as published by the Free Software Foundation; either
|
||||
|
@ -44,9 +44,9 @@ struct slot_t
|
|||
int MUL; // parametre "multiple de frequence"
|
||||
int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
|
||||
int TLL; // Total Level ajusted
|
||||
int SLL; // Sustin Level (ajusted) = volume où l'enveloppe termine sa premiere phase de regression
|
||||
int SLL; // Sustin Level (ajusted) = volume o・l'enveloppe termine sa premiere phase de regression
|
||||
int KSR_S; // Key Scale Rate Shift = facteur de prise en compte du KSL dans la variations de l'enveloppe
|
||||
int KSR; // Key Scale Rate = cette valeur est calculee par rapport à la frequence actuelle, elle va influer
|
||||
int KSR; // Key Scale Rate = cette valeur est calculee par rapport ・la frequence actuelle, elle va influer
|
||||
// sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
|
||||
int SEG; // Type enveloppe SSG
|
||||
int env_xor;
|
||||
|
@ -58,24 +58,24 @@ struct slot_t
|
|||
const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
|
||||
int Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
|
||||
int Finc; // frequency step = pas d'incrementation du compteur-frequence
|
||||
// plus le pas est grand, plus la frequence est aïgu (ou haute)
|
||||
// plus le pas est grand, plus la frequence est a・u (ou haute)
|
||||
int Ecurp; // Envelope current phase = cette variable permet de savoir dans quelle phase
|
||||
// de l'enveloppe on se trouve, par exemple phase d'attaque ou phase de maintenue ...
|
||||
// en fonction de la valeur de cette variable, on va appeler une fonction permettant
|
||||
// de mettre à jour l'enveloppe courante.
|
||||
int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir où l'on se trouve dans l'enveloppe
|
||||
// de mettre ・jour l'enveloppe courante.
|
||||
int Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir o・l'on se trouve dans l'enveloppe
|
||||
int Einc; // Envelope step courant
|
||||
int Ecmp; // Envelope counter limite pour la prochaine phase
|
||||
int EincA; // Envelope step for Attack = pas d'incrementation du compteur durant la phase d'attaque
|
||||
// cette valeur est egal à AR[KSR]
|
||||
// cette valeur est egal ・AR[KSR]
|
||||
int EincD; // Envelope step for Decay = pas d'incrementation du compteur durant la phase de regression
|
||||
// cette valeur est egal à DR[KSR]
|
||||
// cette valeur est egal ・DR[KSR]
|
||||
int EincS; // Envelope step for Sustain = pas d'incrementation du compteur durant la phase de maintenue
|
||||
// cette valeur est egal à SR[KSR]
|
||||
// cette valeur est egal ・SR[KSR]
|
||||
int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
|
||||
// cette valeur est egal à RR[KSR]
|
||||
int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
|
||||
// d'un autre ou carrement à la sortie de la voie
|
||||
// cette valeur est egal ・RR[KSR]
|
||||
int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot ・l'entree
|
||||
// d'un autre ou carrement ・la sortie de la voie
|
||||
int INd; // input data of the slot = donnees en entree du slot
|
||||
int ChgEnM; // Change envelop mask.
|
||||
int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
|
||||
|
@ -102,10 +102,10 @@ struct state_t
|
|||
{
|
||||
int TimerBase; // TimerBase calculation
|
||||
int Status; // YM2612 Status (timer overflow)
|
||||
int TimerA; // timerA limit = valeur jusqu'à laquelle le timer A doit compter
|
||||
int TimerA; // timerA limit = valeur jusqu'・laquelle le timer A doit compter
|
||||
int TimerAL;
|
||||
int TimerAcnt; // timerA counter = valeur courante du Timer A
|
||||
int TimerB; // timerB limit = valeur jusqu'à laquelle le timer B doit compter
|
||||
int TimerB; // timerB limit = valeur jusqu'・laquelle le timer B doit compter
|
||||
int TimerBL;
|
||||
int TimerBcnt; // timerB counter = valeur courante du Timer B
|
||||
int Mode; // Mode actuel des voie 3 et 6 (normal / special)
|
||||
|
@ -1255,7 +1255,7 @@ void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
|
|||
if ( YM2612.Mode & 3 )
|
||||
run_timer( pair_count );
|
||||
|
||||
// Mise à jour des pas des compteurs-frequences s'ils ont ete modifies
|
||||
// Mise ・jour des pas des compteurs-frequences s'ils ont ete modifies
|
||||
|
||||
for ( int chi = 0; chi < channel_count; chi++ )
|
||||
{
|
||||
|
@ -1277,7 +1277,7 @@ void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t* out )
|
|||
int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
|
||||
sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
|
||||
if (sl.KSR != ksr) // si le KSR a change alors
|
||||
{ // les differents taux pour l'enveloppe sont mis à jour
|
||||
{ // les differents taux pour l'enveloppe sont mis ・jour
|
||||
sl.KSR = ksr;
|
||||
|
||||
sl.EincA = sl.AR [ksr];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// YM2612 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
// Game_Music_Emu 0.6.0
|
||||
#ifndef YM2612_EMU_H
|
||||
#define YM2612_EMU_H
|
||||
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
// BLARGG_RESTRICT: equivalent to restrict, where supported
|
||||
#if __GNUC__ >= 3 || _MSC_VER >= 1100
|
||||
#define BLARGG_RESTRICT __restrict
|
||||
#else
|
||||
#define BLARGG_RESTRICT
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
|
@ -54,10 +61,11 @@ public:
|
|||
};
|
||||
|
||||
#ifndef BLARGG_DISABLE_NOTHROW
|
||||
#if __cplusplus < 199711
|
||||
#define BLARGG_THROWS( spec )
|
||||
#else
|
||||
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||
#define BLARGG_THROWS( spec ) throw spec
|
||||
#else
|
||||
#define BLARGG_THROWS( spec )
|
||||
#endif
|
||||
#define BLARGG_DISABLE_NOTHROW \
|
||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||
|
@ -68,6 +76,7 @@ public:
|
|||
#define BLARGG_NEW new (std::nothrow)
|
||||
#endif
|
||||
|
||||
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||
((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
|
||||
|
||||
|
@ -110,18 +119,17 @@ public:
|
|||
#endif
|
||||
|
||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||
#include <limits.h>
|
||||
|
||||
#if INT_MAX >= 0x7FFFFFFF
|
||||
typedef int blargg_long;
|
||||
#else
|
||||
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||
typedef long blargg_long;
|
||||
#else
|
||||
typedef int blargg_long;
|
||||
#endif
|
||||
|
||||
#if UINT_MAX >= 0xFFFFFFFF
|
||||
typedef unsigned blargg_ulong;
|
||||
#else
|
||||
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||
typedef unsigned long blargg_ulong;
|
||||
#else
|
||||
typedef unsigned blargg_ulong;
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
@ -171,5 +179,18 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define BLARGG_DEPRECATED __attribute__ ((deprecated))
|
||||
#else
|
||||
#define BLARGG_DEPRECATED
|
||||
#endif
|
||||
|
||||
// Use in place of "= 0;" for a pure virtual, since these cause calls to std C++ lib.
|
||||
// During development, BLARGG_PURE( x ) expands to = 0;
|
||||
// virtual int func() BLARGG_PURE( { return 0; } )
|
||||
#ifndef BLARGG_PURE
|
||||
#define BLARGG_PURE( def ) def
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -6,9 +6,22 @@
|
|||
// Uncomment to use zlib for transparent decompression of gzipped files
|
||||
//#define HAVE_ZLIB_H
|
||||
|
||||
// Uncomment to support only the listed game music types. See gme_type_list.cpp
|
||||
// for a list of all types.
|
||||
//#define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
|
||||
// Uncomment and edit list to support only the listed game music types,
|
||||
// so that the others don't get linked in at all.
|
||||
/*
|
||||
#define GME_TYPE_LIST \
|
||||
gme_ay_type,\
|
||||
gme_gbs_type,\
|
||||
gme_gym_type,\
|
||||
gme_hes_type,\
|
||||
gme_kss_type,\
|
||||
gme_nsf_type,\
|
||||
gme_nsfe_type,\
|
||||
gme_sap_type,\
|
||||
gme_spc_type,\
|
||||
gme_vgm_type,\
|
||||
gme_vgz_type
|
||||
*/
|
||||
|
||||
// Uncomment to enable platform-specific optimizations
|
||||
//#define BLARGG_NONPORTABLE 1
|
||||
|
@ -27,5 +40,4 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
// CPU Byte Order Utilities
|
||||
|
||||
// Game_Music_Emu 0.5.2
|
||||
#ifndef BLARGG_ENDIAN
|
||||
#define BLARGG_ENDIAN
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
||||
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
|
||||
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
|
||||
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
|
||||
#define BLARGG_CPU_X86 1
|
||||
#define BLARGG_CPU_CISC 1
|
||||
#endif
|
||||
|
||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__POWERPC__) || defined (__powerc)
|
||||
#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) || \
|
||||
defined (__POWERPC__) || defined (__powerc)
|
||||
#define BLARGG_CPU_POWERPC 1
|
||||
#define BLARGG_CPU_RISC 1
|
||||
#endif
|
||||
|
||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||
|
@ -36,10 +36,10 @@
|
|||
#endif
|
||||
|
||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
||||
defined (__mips__) || defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
||||
defined (__sparc__) || BLARGG_CPU_POWERPC || \
|
||||
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#else
|
||||
#elif !defined (__mips__)
|
||||
// No endian specified; assume little-endian, since it's most common
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
@ -64,45 +64,60 @@ inline void blargg_verify_byte_order()
|
|||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le16( void const* p ) {
|
||||
return ((unsigned char const*) p) [1] * 0x100u +
|
||||
((unsigned char const*) p) [0];
|
||||
inline unsigned get_le16( void const* p )
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [1] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [0];
|
||||
}
|
||||
inline unsigned get_be16( void const* p ) {
|
||||
return ((unsigned char const*) p) [0] * 0x100u +
|
||||
((unsigned char const*) p) [1];
|
||||
|
||||
inline unsigned get_be16( void const* p )
|
||||
{
|
||||
return (unsigned) ((unsigned char const*) p) [0] << 8 |
|
||||
(unsigned) ((unsigned char const*) p) [1];
|
||||
}
|
||||
inline blargg_ulong get_le32( void const* p ) {
|
||||
return ((unsigned char const*) p) [3] * 0x01000000u +
|
||||
((unsigned char const*) p) [2] * 0x00010000u +
|
||||
((unsigned char const*) p) [1] * 0x00000100u +
|
||||
((unsigned char const*) p) [0];
|
||||
|
||||
inline blargg_ulong get_le32( void const* p )
|
||||
{
|
||||
return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [2] << 16 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [1] << 8 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [0];
|
||||
}
|
||||
inline blargg_ulong get_be32( void const* p ) {
|
||||
return ((unsigned char const*) p) [0] * 0x01000000u +
|
||||
((unsigned char const*) p) [1] * 0x00010000u +
|
||||
((unsigned char const*) p) [2] * 0x00000100u +
|
||||
((unsigned char const*) p) [3];
|
||||
|
||||
inline blargg_ulong get_be32( void const* p )
|
||||
{
|
||||
return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [1] << 16 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [2] << 8 |
|
||||
(blargg_ulong) ((unsigned char const*) p) [3];
|
||||
}
|
||||
inline void set_le16( void* p, unsigned n ) {
|
||||
|
||||
inline void set_le16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
}
|
||||
inline void set_be16( void* p, unsigned n ) {
|
||||
|
||||
inline void set_be16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) n;
|
||||
}
|
||||
inline void set_le32( void* p, blargg_ulong n ) {
|
||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
|
||||
inline void set_le32( void* p, blargg_ulong n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||
}
|
||||
inline void set_be32( void* p, blargg_ulong n ) {
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||
|
||||
inline void set_be32( void* p, blargg_ulong n )
|
||||
{
|
||||
((unsigned char*) p) [3] = (unsigned char) n;
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||
}
|
||||
|
||||
#if BLARGG_NONPORTABLE
|
||||
|
@ -117,30 +132,41 @@ inline void set_be32( void* p, blargg_ulong n ) {
|
|||
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||
#endif
|
||||
|
||||
#if BLARGG_CPU_POWERPC && defined (__MWERKS__)
|
||||
// PowerPC has special byte-reversed instructions
|
||||
// to do: assumes that PowerPC is running in big-endian mode
|
||||
// to do: implement for other compilers which don't support these macros
|
||||
#define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
|
||||
#define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
|
||||
#define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
|
||||
#define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
|
||||
|
||||
#if BLARGG_CPU_POWERPC
|
||||
// PowerPC has special byte-reversed instructions
|
||||
#if defined (__MWERKS__)
|
||||
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
||||
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
||||
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
||||
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
||||
#elif defined (__GNUC__)
|
||||
#define GET_LE16( addr ) ({unsigned short ppc_lhbrx_; __asm__ volatile( "lhbrx %0,0,%1" : "=r" (ppc_lhbrx_) : "r" (addr) : "memory" ); ppc_lhbrx_;})
|
||||
#define GET_LE32( addr ) ({unsigned short ppc_lwbrx_; __asm__ volatile( "lwbrx %0,0,%1" : "=r" (ppc_lwbrx_) : "r" (addr) : "memory" ); ppc_lwbrx_;})
|
||||
#define SET_LE16( addr, in ) ({__asm__ volatile( "sthbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||
#define SET_LE32( addr, in ) ({__asm__ volatile( "stwbrx %0,0,%1" : : "r" (in), "r" (addr) : "memory" );})
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE16
|
||||
#define GET_LE16( addr ) get_le16( addr )
|
||||
#define GET_LE32( addr ) get_le32( addr )
|
||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE32
|
||||
#define GET_LE32( addr ) get_le32( addr )
|
||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE16
|
||||
#define GET_BE16( addr ) get_be16( addr )
|
||||
#define GET_BE32( addr ) get_be32( addr )
|
||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE32
|
||||
#define GET_BE32( addr ) get_be32( addr )
|
||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
// Included at the beginning of library source files, after all other #include lines
|
||||
/* Included at the beginning of library source files, after all other #include lines.
|
||||
Sets up helpful macros and services used in my source code. They don't need
|
||||
module an annoying module prefix on their names since they are defined after
|
||||
all other #include lines. */
|
||||
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
|
@ -16,10 +20,10 @@
|
|||
|
||||
// Like printf() except output goes to debug log file. Might be defined to do
|
||||
// nothing (not even evaluate its arguments).
|
||||
// void dprintf( const char* format, ... );
|
||||
inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef dprintf
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
// void debug_printf( const char* format, ... );
|
||||
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#undef debug_printf
|
||||
#define debug_printf (1) ? (void) 0 : blargg_dprintf_
|
||||
|
||||
// If enabled, evaluate expr and if false, make debug log entry with source file
|
||||
// and line. Meant for finding situations that should be examined further, but that
|
||||
|
@ -42,9 +46,25 @@ inline void blargg_dprintf_( const char*, ... ) { }
|
|||
#undef min
|
||||
#undef max
|
||||
|
||||
#define DEF_MIN_MAX( type ) \
|
||||
static inline type min( type x, type y ) { if ( x < y ) return x; return y; }\
|
||||
static inline type max( type x, type y ) { if ( y < x ) return x; return y; }
|
||||
|
||||
DEF_MIN_MAX( int )
|
||||
DEF_MIN_MAX( unsigned )
|
||||
DEF_MIN_MAX( long )
|
||||
DEF_MIN_MAX( unsigned long )
|
||||
DEF_MIN_MAX( float )
|
||||
DEF_MIN_MAX( double )
|
||||
|
||||
#undef DEF_MIN_MAX
|
||||
|
||||
/*
|
||||
// using const references generates crappy code, and I am currenly only using these
|
||||
// for built-in types, so they take arguments by value
|
||||
|
||||
// TODO: remove
|
||||
inline int min( int x, int y )
|
||||
template<class T>
|
||||
inline T min( T x, T y )
|
||||
{
|
||||
|
@ -60,17 +80,29 @@ inline T max( T x, T y )
|
|||
return y;
|
||||
return x;
|
||||
}
|
||||
*/
|
||||
|
||||
// TODO: good idea? bad idea?
|
||||
#undef byte
|
||||
#define byte byte_
|
||||
typedef unsigned char byte;
|
||||
|
||||
// Setup compiler defines useful for exporting required public API symbols in gme.cpp
|
||||
#ifndef BLARGG_EXPORT
|
||||
#if defined (_WIN32) && defined(BLARGG_BUILD_DLL)
|
||||
#define BLARGG_EXPORT __declspec(dllexport)
|
||||
#elif defined (LIBGME_VISIBILITY)
|
||||
#define BLARGG_EXPORT __attribute__((visibility ("default")))
|
||||
#else
|
||||
#define BLARGG_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// deprecated
|
||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
||||
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf and check
|
||||
// BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of debug_printf and check
|
||||
#ifdef BLARGG_SOURCE_BEGIN
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
#endif
|
||||
|
|
|
@ -10,9 +10,9 @@ int Gbs_Emu::cpu_read( gb_addr_t addr )
|
|||
result = apu.read_register( clock(), addr );
|
||||
#ifndef NDEBUG
|
||||
else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
|
||||
dprintf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
|
||||
debug_printf( "Read from unmapped memory $%.4x\n", (unsigned) addr );
|
||||
else if ( unsigned (addr - 0xFF01) < 0xFF80 - 0xFF01 )
|
||||
dprintf( "Unhandled I/O read 0x%4X\n", (unsigned) addr );
|
||||
debug_printf( "Unhandled I/O read 0x%4X\n", (unsigned) addr );
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
|||
ram [offset] = 0xFF;
|
||||
|
||||
//if ( addr == 0xFFFF )
|
||||
// dprintf( "Wrote interrupt mask\n" );
|
||||
// debug_printf( "Wrote interrupt mask\n" );
|
||||
}
|
||||
}
|
||||
else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
|
||||
|
@ -48,7 +48,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
|||
#ifndef NDEBUG
|
||||
else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
|
||||
{
|
||||
dprintf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
|
||||
debug_printf( "Wrote to unmapped memory $%.4x\n", (unsigned) addr );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
|||
#define CPU_READ_FAST_( emu, addr, time, out ) \
|
||||
{\
|
||||
out = READ_PROG( addr );\
|
||||
if ( unsigned (addr - Gb_Apu::start_addr) <= Gb_Apu::register_count )\
|
||||
if ( unsigned (addr - Gb_Apu::start_addr) < Gb_Apu::register_count )\
|
||||
out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\
|
||||
else\
|
||||
check( out == emu->cpu_read( addr ) );\
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
||||
|
||||
#define IN_GME 1
|
||||
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Music_Emu.h"
|
||||
|
||||
#include "gme_types.h"
|
||||
#if !GME_DISABLE_STEREO_DEPTH
|
||||
#include "Effects_Buffer.h"
|
||||
#endif
|
||||
|
@ -24,32 +23,51 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
|||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#ifndef GME_TYPE_LIST
|
||||
|
||||
// Default list of all supported game music types (copy this to blargg_config.h
|
||||
// if you want to modify it)
|
||||
#define GME_TYPE_LIST \
|
||||
gme_ay_type,\
|
||||
gme_gbs_type,\
|
||||
gme_gym_type,\
|
||||
gme_hes_type,\
|
||||
gme_kss_type,\
|
||||
gme_nsf_type,\
|
||||
gme_nsfe_type,\
|
||||
gme_sap_type,\
|
||||
gme_spc_type,\
|
||||
gme_vgm_type,\
|
||||
gme_vgz_type
|
||||
|
||||
#endif
|
||||
|
||||
gme_type_t const* GMEAPI gme_type_list()
|
||||
BLARGG_EXPORT gme_type_t const* gme_type_list()
|
||||
{
|
||||
static gme_type_t const gme_type_list_ [] = { GME_TYPE_LIST, 0 };
|
||||
static gme_type_t const gme_type_list_ [] = {
|
||||
#ifdef GME_TYPE_LIST
|
||||
GME_TYPE_LIST,
|
||||
#else
|
||||
#ifdef USE_GME_AY
|
||||
gme_ay_type,
|
||||
#endif
|
||||
#ifdef USE_GME_GBS
|
||||
gme_gbs_type,
|
||||
#endif
|
||||
#ifdef USE_GME_GYM
|
||||
gme_gym_type,
|
||||
#endif
|
||||
#ifdef USE_GME_HES
|
||||
gme_hes_type,
|
||||
#endif
|
||||
#ifdef USE_GME_KSS
|
||||
gme_kss_type,
|
||||
#endif
|
||||
#ifdef USE_GME_NSF
|
||||
gme_nsf_type,
|
||||
#endif
|
||||
#ifdef USE_GME_NSFE
|
||||
gme_nsfe_type,
|
||||
#endif
|
||||
#ifdef USE_GME_SAP
|
||||
gme_sap_type,
|
||||
#endif
|
||||
#ifdef USE_GME_SPC
|
||||
gme_spc_type,
|
||||
#endif
|
||||
#ifdef USE_GME_VGM
|
||||
gme_vgm_type,
|
||||
gme_vgz_type,
|
||||
#endif
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
return gme_type_list_;
|
||||
}
|
||||
|
||||
const char* GMEAPI gme_identify_header( void const* header )
|
||||
BLARGG_EXPORT const char* gme_identify_header( void const* header )
|
||||
{
|
||||
switch ( get_be32( header ) )
|
||||
{
|
||||
|
@ -78,7 +96,7 @@ static void to_uppercase( const char* in, int len, char* out )
|
|||
*out = 0; // extension too long
|
||||
}
|
||||
|
||||
gme_type_t GMEAPI gme_identify_extension( const char* extension_ )
|
||||
BLARGG_EXPORT gme_type_t gme_identify_extension( const char* extension_ )
|
||||
{
|
||||
char const* end = strrchr( extension_, '.' );
|
||||
if ( end )
|
||||
|
@ -93,7 +111,7 @@ gme_type_t GMEAPI gme_identify_extension( const char* extension_ )
|
|||
return 0;
|
||||
}
|
||||
|
||||
gme_err_t GMEAPI gme_identify_file( const char* path, gme_type_t* type_out )
|
||||
BLARGG_EXPORT gme_err_t gme_identify_file( const char* path, gme_type_t* type_out )
|
||||
{
|
||||
*type_out = gme_identify_extension( path );
|
||||
// TODO: don't examine header if file has extension?
|
||||
|
@ -108,7 +126,7 @@ gme_err_t GMEAPI gme_identify_file( const char* path, gme_type_t* type_out )
|
|||
return 0;
|
||||
}
|
||||
|
||||
gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate )
|
||||
BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate )
|
||||
{
|
||||
require( (data || !size) && out );
|
||||
*out = 0;
|
||||
|
@ -132,7 +150,7 @@ gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, in
|
|||
return err;
|
||||
}
|
||||
|
||||
GMEEXPORT gme_err_t GMEAPI gme_open_file( const char* path, Music_Emu** out, int sample_rate )
|
||||
BLARGG_EXPORT gme_err_t gme_open_file( const char* path, Music_Emu** out, int sample_rate )
|
||||
{
|
||||
require( path && out );
|
||||
*out = 0;
|
||||
|
@ -169,7 +187,7 @@ GMEEXPORT gme_err_t GMEAPI gme_open_file( const char* path, Music_Emu** out, int
|
|||
return err;
|
||||
}
|
||||
|
||||
Music_Emu* GMEAPI gme_new_emu( gme_type_t type, int rate )
|
||||
BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t type, int rate )
|
||||
{
|
||||
if ( type )
|
||||
{
|
||||
|
@ -202,27 +220,27 @@ Music_Emu* GMEAPI gme_new_emu( gme_type_t type, int rate )
|
|||
return 0;
|
||||
}
|
||||
|
||||
gme_err_t GMEAPI gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
|
||||
BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu* me, const char* path ) { return me->load_file( path ); }
|
||||
|
||||
gme_err_t GMEAPI gme_load_data( Music_Emu* me, void const* data, long size )
|
||||
BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu* me, void const* data, long size )
|
||||
{
|
||||
Mem_File_Reader in( data, size );
|
||||
return me->load( in );
|
||||
}
|
||||
|
||||
gme_err_t GMEAPI gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
|
||||
BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu* me, gme_reader_t func, long size, void* data )
|
||||
{
|
||||
Callback_Reader in( func, size, data );
|
||||
return me->load( in );
|
||||
}
|
||||
|
||||
void GMEAPI gme_delete( Music_Emu* me ) { delete me; }
|
||||
BLARGG_EXPORT void gme_delete( Music_Emu* me ) { delete me; }
|
||||
|
||||
gme_type_t GMEAPI gme_type( Music_Emu const* me ) { return me->type(); }
|
||||
BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* me ) { return me->type(); }
|
||||
|
||||
const char* GMEAPI gme_warning( Music_Emu* me ) { return me->warning(); }
|
||||
BLARGG_EXPORT const char* gme_warning( Music_Emu* me ) { return me->warning(); }
|
||||
|
||||
int GMEAPI gme_track_count( Music_Emu const* me ) { return me->track_count(); }
|
||||
BLARGG_EXPORT int gme_track_count( Music_Emu const* me ) { return me->track_count(); }
|
||||
|
||||
struct gme_info_t_ : gme_info_t
|
||||
{
|
||||
|
@ -231,7 +249,7 @@ struct gme_info_t_ : gme_info_t
|
|||
BLARGG_DISABLE_NOTHROW
|
||||
};
|
||||
|
||||
gme_err_t GMEAPI gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
|
||||
BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const* me, gme_info_t** out, int track )
|
||||
{
|
||||
*out = NULL;
|
||||
|
||||
|
@ -297,12 +315,12 @@ gme_err_t GMEAPI gme_track_info( Music_Emu const* me, gme_info_t** out, int trac
|
|||
return 0;
|
||||
}
|
||||
|
||||
void GMEAPI gme_free_info( gme_info_t* info )
|
||||
BLARGG_EXPORT void gme_free_info( gme_info_t* info )
|
||||
{
|
||||
delete STATIC_CAST(gme_info_t_*,info);
|
||||
}
|
||||
|
||||
void GMEAPI gme_set_stereo_depth( Music_Emu* me, double depth )
|
||||
BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu* me, double depth )
|
||||
{
|
||||
#if !GME_DISABLE_STEREO_DEPTH
|
||||
if ( me->effects_buffer )
|
||||
|
@ -310,24 +328,26 @@ void GMEAPI gme_set_stereo_depth( Music_Emu* me, double depth )
|
|||
#endif
|
||||
}
|
||||
|
||||
void* GMEAPI gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
|
||||
void GMEAPI gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
|
||||
void GMEAPI gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
|
||||
BLARGG_EXPORT void* gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
|
||||
BLARGG_EXPORT void gme_set_user_data ( Music_Emu* me, void* new_user_data ) { me->set_user_data( new_user_data ); }
|
||||
BLARGG_EXPORT void gme_set_user_cleanup(Music_Emu* me, gme_user_cleanup_t func ) { me->set_user_cleanup( func ); }
|
||||
|
||||
gme_err_t GMEAPI gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
|
||||
gme_err_t GMEAPI gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); }
|
||||
gme_err_t GMEAPI gme_skip ( Music_Emu* me, long n ) { return me->skip( n ); }
|
||||
void GMEAPI gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
||||
int GMEAPI gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
||||
int GMEAPI gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
||||
gme_err_t GMEAPI gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
|
||||
int GMEAPI gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
|
||||
void GMEAPI gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
|
||||
void GMEAPI gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
|
||||
void GMEAPI gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
|
||||
void GMEAPI gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
|
||||
BLARGG_EXPORT gme_err_t gme_start_track ( Music_Emu* me, int index ) { return me->start_track( index ); }
|
||||
BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p ) { return me->play( n, p ); }
|
||||
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
||||
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
||||
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
||||
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
|
||||
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
|
||||
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
|
||||
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
|
||||
BLARGG_EXPORT void gme_mute_voice ( Music_Emu* me, int index, int mute ) { me->mute_voice( index, mute != 0 ); }
|
||||
BLARGG_EXPORT void gme_mute_voices ( Music_Emu* me, int mask ) { me->mute_voices( mask ); }
|
||||
BLARGG_EXPORT void gme_enable_accuracy( Music_Emu* me, int enabled ) { me->enable_accuracy( !!enabled ); }
|
||||
BLARGG_EXPORT void gme_clear_playlist ( Music_Emu* me ) { me->clear_playlist(); }
|
||||
BLARGG_EXPORT int gme_type_multitrack( gme_type_t t ) { return t->track_count != 1; }
|
||||
|
||||
void GMEAPI gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
|
||||
BLARGG_EXPORT void gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
|
||||
{
|
||||
Music_Emu::equalizer_t e = me->equalizer();
|
||||
e.treble = eq->treble;
|
||||
|
@ -335,16 +355,22 @@ void GMEAPI gme_set_equalizer ( Music_Emu* me, gme_equalizer_t const* eq )
|
|||
me->set_equalizer( e );
|
||||
}
|
||||
|
||||
void GMEAPI gme_equalizer( Music_Emu const* me, gme_equalizer_t* out )
|
||||
BLARGG_EXPORT void gme_equalizer( Music_Emu const* me, gme_equalizer_t* out )
|
||||
{
|
||||
gme_equalizer_t e = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
gme_equalizer_t e = gme_equalizer_t(); // Default-init all fields to 0.0f
|
||||
e.treble = me->equalizer().treble;
|
||||
e.bass = me->equalizer().bass;
|
||||
*out = e;
|
||||
}
|
||||
|
||||
const char* GMEAPI gme_voice_name( Music_Emu const* me, int i )
|
||||
BLARGG_EXPORT const char* gme_voice_name( Music_Emu const* me, int i )
|
||||
{
|
||||
assert( (unsigned) i < (unsigned) me->voice_count() );
|
||||
return me->voice_names() [i];
|
||||
}
|
||||
|
||||
BLARGG_EXPORT const char* gme_type_system( gme_type_t type )
|
||||
{
|
||||
assert( type );
|
||||
return type->system;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,15 @@
|
|||
/* Game music emulator library C interface (also usable from C++) */
|
||||
|
||||
/* Game_Music_Emu 0.5.2 */
|
||||
/* Game_Music_Emu 0.6.0 */
|
||||
#ifndef GME_H
|
||||
#define GME_H
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define GMEAPI __stdcall
|
||||
#else
|
||||
#define GMEAPI
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(GME_DLL)
|
||||
#define GMEEXPORT __declspec(dllexport)
|
||||
#define GMEIMPORT __declspec(dllimport)
|
||||
#if IN_GME
|
||||
#define GMEDLL GMEEXPORT
|
||||
#else
|
||||
#define GMEDLL GMEIMPORT
|
||||
#endif
|
||||
#else
|
||||
#define GMEEXPORT
|
||||
#define GMEIMPORT
|
||||
#define GMEDLL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
||||
|
||||
/* Error string returned by library functions, or NULL if no error (success) */
|
||||
typedef const char* gme_err_t;
|
||||
|
||||
|
@ -38,38 +20,35 @@ typedef struct Music_Emu Music_Emu;
|
|||
/******** Basic operations ********/
|
||||
|
||||
/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
|
||||
GMEDLL gme_err_t GMEAPI gme_open_file( const char path [], Music_Emu** out, int sample_rate );
|
||||
gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
|
||||
|
||||
/* Number of tracks available */
|
||||
GMEDLL int GMEAPI gme_track_count( Music_Emu const* );
|
||||
int gme_track_count( Music_Emu const* );
|
||||
|
||||
/* Start a track, where 0 is the first track */
|
||||
GMEDLL gme_err_t GMEAPI gme_start_track( Music_Emu*, int index );
|
||||
gme_err_t gme_start_track( Music_Emu*, int index );
|
||||
|
||||
/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
|
||||
GMEDLL gme_err_t GMEAPI gme_play( Music_Emu*, int count, short out [] );
|
||||
|
||||
/* Skip n samples */
|
||||
GMEDLL gme_err_t GMEAPI gme_skip( Music_Emu*, long n );
|
||||
gme_err_t gme_play( Music_Emu*, int count, short out [] );
|
||||
|
||||
/* Finish using emulator and free memory */
|
||||
GMEDLL void GMEAPI gme_delete( Music_Emu* );
|
||||
void gme_delete( Music_Emu* );
|
||||
|
||||
|
||||
/******** Track position/length ********/
|
||||
|
||||
/* Set time to start fading track out. Once fade ends track_ended() returns true.
|
||||
Fade time can be changed while track is playing. */
|
||||
GMEDLL void GMEAPI gme_set_fade( Music_Emu*, int start_msec );
|
||||
void gme_set_fade( Music_Emu*, int start_msec );
|
||||
|
||||
/* True if a track has reached its end */
|
||||
GMEDLL int GMEAPI gme_track_ended( Music_Emu const* );
|
||||
int gme_track_ended( Music_Emu const* );
|
||||
|
||||
/* Number of milliseconds (1000 = one second) played since beginning of track */
|
||||
GMEDLL int GMEAPI gme_tell( Music_Emu const* );
|
||||
int gme_tell( Music_Emu const* );
|
||||
|
||||
/* Seek to new time in track. Seeking backwards or far forward can take a while. */
|
||||
GMEDLL gme_err_t GMEAPI gme_seek( Music_Emu*, int msec );
|
||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||
|
||||
|
||||
/******** Informational ********/
|
||||
|
@ -80,22 +59,22 @@ enum { gme_info_only = -1 };
|
|||
|
||||
/* Most recent warning string, or NULL if none. Clears current warning after returning.
|
||||
Warning is also cleared when loading a file and starting a track. */
|
||||
GMEDLL const char* GMEAPI gme_warning( Music_Emu* );
|
||||
const char* gme_warning( Music_Emu* );
|
||||
|
||||
/* Load m3u playlist file (must be done after loading music) */
|
||||
GMEDLL gme_err_t GMEAPI gme_load_m3u( Music_Emu*, const char path [] );
|
||||
gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
|
||||
|
||||
/* Clear any loaded m3u playlist and any internal playlist that the music format
|
||||
supports (NSFE for example). */
|
||||
GMEDLL void GMEAPI gme_clear_playlist( Music_Emu* );
|
||||
void gme_clear_playlist( Music_Emu* );
|
||||
|
||||
/* Gets information for a particular track (length, name, author, etc.).
|
||||
Must be freed after use. */
|
||||
typedef struct gme_info_t gme_info_t;
|
||||
GMEDLL gme_err_t GMEAPI gme_track_info( Music_Emu const*, gme_info_t** out, int track );
|
||||
gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
|
||||
|
||||
/* Frees track information */
|
||||
GMEDLL void GMEAPI gme_free_info( gme_info_t* );
|
||||
void gme_free_info( gme_info_t* );
|
||||
|
||||
struct gme_info_t
|
||||
{
|
||||
|
@ -127,30 +106,31 @@ struct gme_info_t
|
|||
|
||||
/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
|
||||
GYM, SPC, and Sega Genesis VGM music */
|
||||
GMEDLL void GMEAPI gme_set_stereo_depth( Music_Emu*, double depth );
|
||||
void gme_set_stereo_depth( Music_Emu*, double depth );
|
||||
|
||||
/* Disable automatic end-of-track detection and skipping of silence at beginning
|
||||
if ignore is true */
|
||||
GMEDLL void GMEAPI gme_ignore_silence( Music_Emu*, int ignore );
|
||||
void gme_ignore_silence( Music_Emu*, int ignore );
|
||||
|
||||
/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
|
||||
Track length as returned by track_info() assumes a tempo of 1.0. */
|
||||
GMEDLL void GMEAPI gme_set_tempo( Music_Emu*, double tempo );
|
||||
void gme_set_tempo( Music_Emu*, double tempo );
|
||||
|
||||
/* Number of voices used by currently loaded file */
|
||||
GMEDLL int GMEAPI gme_voice_count( Music_Emu const* );
|
||||
int gme_voice_count( Music_Emu const* );
|
||||
|
||||
/* Name of voice i, from 0 to gme_voice_count() - 1 */
|
||||
GMEDLL const char* GMEAPI gme_voice_name( Music_Emu const*, int i );
|
||||
const char* gme_voice_name( Music_Emu const*, int i );
|
||||
|
||||
/* Mute/unmute voice i, where voice 0 is first voice */
|
||||
GMEDLL void GMEAPI gme_mute_voice( Music_Emu*, int index, int mute );
|
||||
void gme_mute_voice( Music_Emu*, int index, int mute );
|
||||
|
||||
/* Set muting state of all voices at once using a bit mask, where -1 mutes all
|
||||
voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
|
||||
GMEDLL void GMEAPI gme_mute_voices( Music_Emu*, int muting_mask );
|
||||
void gme_mute_voices( Music_Emu*, int muting_mask );
|
||||
|
||||
/* Frequency equalizer parameters (see gme.txt) */
|
||||
/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */
|
||||
typedef struct gme_equalizer_t
|
||||
{
|
||||
double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
|
||||
|
@ -160,11 +140,13 @@ typedef struct gme_equalizer_t
|
|||
} gme_equalizer_t;
|
||||
|
||||
/* Get current frequency equalizater parameters */
|
||||
GMEDLL void GMEAPI gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
|
||||
void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
|
||||
|
||||
/* Change frequency equalizer parameters */
|
||||
GMEDLL void GMEAPI gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
|
||||
void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
|
||||
|
||||
/* Enables/disables most accurate sound emulation options */
|
||||
void gme_enable_accuracy( Music_Emu*, int enabled );
|
||||
|
||||
|
||||
/******** Game music types ********/
|
||||
|
@ -187,17 +169,17 @@ extern const gme_type_t
|
|||
gme_vgz_type;
|
||||
|
||||
/* Type of this emulator */
|
||||
GMEDLL gme_type_t GMEAPI gme_type( Music_Emu const* );
|
||||
gme_type_t gme_type( Music_Emu const* );
|
||||
|
||||
/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
|
||||
to this library to support new music types without having to be updated. */
|
||||
GMEDLL gme_type_t const* GMEAPI gme_type_list();
|
||||
gme_type_t const* gme_type_list();
|
||||
|
||||
/* Name of game system for this music file type */
|
||||
GMEDLL const char* GMEAPI gme_type_system( gme_type_t );
|
||||
const char* gme_type_system( gme_type_t );
|
||||
|
||||
/* True if this music file type supports multiple tracks */
|
||||
GMEDLL int GMEAPI gme_type_multitrack( gme_type_t );
|
||||
int gme_type_multitrack( gme_type_t );
|
||||
|
||||
|
||||
/******** Advanced file loading ********/
|
||||
|
@ -206,50 +188,50 @@ GMEDLL int GMEAPI gme_type_multitrack( gme_type_t );
|
|||
extern const char* const gme_wrong_file_type;
|
||||
|
||||
/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */
|
||||
GMEDLL gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
|
||||
gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
|
||||
|
||||
/* Determine likely game music type based on first four bytes of file. Returns
|
||||
string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
|
||||
file header is not recognized. */
|
||||
GMEDLL const char* GMEAPI gme_identify_header( void const* header );
|
||||
const char* gme_identify_header( void const* header );
|
||||
|
||||
/* Get corresponding music type for file path or extension passed in. */
|
||||
GMEDLL gme_type_t GMEAPI gme_identify_extension( const char path_or_extension [] );
|
||||
gme_type_t gme_identify_extension( const char path_or_extension [] );
|
||||
|
||||
/* Determine file type based on file's extension or header (if extension isn't recognized).
|
||||
Sets *type_out to type, or 0 if unrecognized or error. */
|
||||
GMEDLL gme_err_t GMEAPI gme_identify_file( const char path [], gme_type_t* type_out );
|
||||
gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
|
||||
|
||||
/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
|
||||
track information, pass gme_info_only for sample_rate. */
|
||||
GMEDLL Music_Emu* GMEAPI gme_new_emu( gme_type_t, int sample_rate );
|
||||
Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
|
||||
|
||||
/* Load music file into emulator */
|
||||
GMEDLL gme_err_t GMEAPI gme_load_file( Music_Emu*, const char path [] );
|
||||
gme_err_t gme_load_file( Music_Emu*, const char path [] );
|
||||
|
||||
/* Load music file from memory into emulator. Makes a copy of data passed. */
|
||||
GMEDLL gme_err_t GMEAPI gme_load_data( Music_Emu*, void const* data, long size );
|
||||
gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
|
||||
|
||||
/* Load music file using custom data reader function that will be called to
|
||||
read file data. Most emulators load the entire file in one read call. */
|
||||
typedef gme_err_t (GMEAPI *gme_reader_t)( void* your_data, void* out, int count );
|
||||
GMEDLL gme_err_t GMEAPI gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
|
||||
typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count );
|
||||
gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
|
||||
|
||||
/* Load m3u playlist file from memory (must be done after loading music) */
|
||||
GMEDLL gme_err_t GMEAPI gme_load_m3u_data( Music_Emu*, void const* data, long size );
|
||||
gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
|
||||
|
||||
|
||||
/******** User data ********/
|
||||
|
||||
/* Set/get pointer to data you want to associate with this emulator.
|
||||
You can use this for whatever you want. */
|
||||
GMEDLL void GMEAPI gme_set_user_data( Music_Emu*, void* new_user_data );
|
||||
GMEDLL void* GMEAPI gme_user_data( Music_Emu const* );
|
||||
void gme_set_user_data( Music_Emu*, void* new_user_data );
|
||||
void* gme_user_data( Music_Emu const* );
|
||||
|
||||
/* Register cleanup function to be called when deleting emulator, or NULL to
|
||||
clear it. Passes user_data to cleanup function. */
|
||||
typedef void (GMEAPI *gme_user_cleanup_t)( void* user_data );
|
||||
GMEDLL void GMEAPI gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
||||
typedef void (*gme_user_cleanup_t)( void* user_data );
|
||||
void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
21
game-music-emu/gme/gme_types.h
Normal file
21
game-music-emu/gme/gme_types.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef GME_TYPES_H
|
||||
#define GME_TYPES_H
|
||||
|
||||
/*
|
||||
* This is a default gme_types.h for use when *not* using
|
||||
* CMake. If CMake is in use gme_types.h.in will be
|
||||
* processed instead.
|
||||
*/
|
||||
#define USE_GME_AY
|
||||
#define USE_GME_GBS
|
||||
#define USE_GME_GYM
|
||||
#define USE_GME_HES
|
||||
#define USE_GME_KSS
|
||||
#define USE_GME_NSF
|
||||
#define USE_GME_NSFE
|
||||
#define USE_GME_SAP
|
||||
#define USE_GME_SPC
|
||||
/* VGM and VGZ are a package deal */
|
||||
#define USE_GME_VGM
|
||||
|
||||
#endif /* GME_TYPES_H */
|
23
game-music-emu/gme/gme_types.h.in
Normal file
23
game-music-emu/gme/gme_types.h.in
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef GME_TYPES_H
|
||||
#define GME_TYPES_H
|
||||
|
||||
/* CMake will either define the following to 1, or #undef it,
|
||||
* depending on the options passed to CMake. This is used to
|
||||
* conditionally compile in the various emulator types.
|
||||
*
|
||||
* See gme_type_list() in gme.cpp
|
||||
*/
|
||||
|
||||
#cmakedefine USE_GME_AY
|
||||
#cmakedefine USE_GME_GBS
|
||||
#cmakedefine USE_GME_GYM
|
||||
#cmakedefine USE_GME_HES
|
||||
#cmakedefine USE_GME_KSS
|
||||
#cmakedefine USE_GME_NSF
|
||||
#cmakedefine USE_GME_NSFE
|
||||
#cmakedefine USE_GME_SAP
|
||||
#cmakedefine USE_GME_SPC
|
||||
/* VGM and VGZ are a package deal */
|
||||
#cmakedefine USE_GME_VGM
|
||||
|
||||
#endif /* GME_TYPES_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue