mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +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
|
/release_gcc
|
||||||
/dumb/vc6/dumb_static/release
|
/dumb/vc6/dumb_static/release
|
||||||
/dumb/vc6/dumb_static/debug
|
/dumb/vc6/dumb_static/debug
|
||||||
|
/dumb/vc6/dumb_static/x64
|
||||||
/DOOMSTATS.TXT
|
/DOOMSTATS.TXT
|
||||||
/src/gitinfo.h
|
/src/gitinfo.h
|
||||||
/src/sc_man_scanner.h
|
/src/sc_man_scanner.h
|
||||||
|
@ -25,4 +26,14 @@
|
||||||
/tools/*/*.exe
|
/tools/*/*.exe
|
||||||
/tools/lemon/build
|
/tools/lemon/build
|
||||||
/tools/re2c/build
|
/tools/re2c/build
|
||||||
|
/tools/updaterevision/x64/
|
||||||
|
/tools/zipdir/x64
|
||||||
/wadsrc/*.pk3
|
/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 )
|
cmake_minimum_required( VERSION 2.4 )
|
||||||
project(ZDoom)
|
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
|
# 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
|
# 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)
|
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 )
|
set( NO_GENERATOR_EXPRESSIONS ON )
|
||||||
endif(${CMAKE_MAJOR_VERSION} GREATER 2 OR ${CMAKE_MINOR_VERSION} GREATER 7)
|
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)
|
# Simplify pk3 building, add_pk3(filename srcdirectory)
|
||||||
function( add_pk3 PK3_NAME PK3_DIR )
|
function( add_pk3 PK3_NAME PK3_DIR )
|
||||||
get_target_property(ZIPDIR_EXE zipdir LOCATION)
|
get_target_property(ZIPDIR_EXE zipdir LOCATION)
|
||||||
|
@ -19,21 +34,34 @@ function( add_pk3 PK3_NAME PK3_DIR )
|
||||||
set( PK3_TARGET "pk3" )
|
set( PK3_TARGET "pk3" )
|
||||||
endif( ${PK3_TARGET} STREQUAL "zdoom_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}
|
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
||||||
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
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>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} $<TARGET_FILE_DIR:zdoom>/${PK3_NAME}
|
||||||
DEPENDS zipdir ${PK3_DIR} )
|
DEPENDS zipdir )
|
||||||
else( NO_GENERATOR_EXPRESSIONS )
|
else( NOT NO_GENERATOR_EXPRESSIONS AND NOT ZDOOM_OUTPUT_OLDSTYLE )
|
||||||
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/${PK3_NAME}
|
||||||
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
COMMAND ${ZIPDIR_EXE} -udf ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} ${PK3_DIR}
|
||||||
DEPENDS zipdir ${PK3_DIR} )
|
DEPENDS zipdir )
|
||||||
endif( NO_GENERATOR_EXPRESSIONS )
|
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
|
add_custom_target( ${PK3_TARGET} ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch ${ZIPDIR_EXE}
|
||||||
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
|
DEPENDS ${ZDOOM_OUTPUT_DIR}/${PK3_NAME} )
|
||||||
endfunction( add_pk3 )
|
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 )
|
IF( NOT CMAKE_BUILD_TYPE )
|
||||||
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
|
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
|
||||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
"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_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." )
|
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" )
|
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." )
|
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( BZip2 )
|
||||||
find_package( JPEG )
|
find_package( JPEG )
|
||||||
find_package( ZLIB )
|
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 )
|
if( MSVC )
|
||||||
# Eliminate unreferenced functions and data
|
# Eliminate unreferenced functions and data
|
||||||
# Perform identical COMDAT folding
|
# 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
|
# String pooling
|
||||||
# Function-level linking
|
# Function-level linking
|
||||||
# Disable run-time type information
|
# Disable run-time type information
|
||||||
set( ALL_C_FLAGS "/GF /Gy /GR-" )
|
set( ALL_C_FLAGS "/GF /Gy /GR-" )
|
||||||
|
|
||||||
# Avoid CRT DLL dependancies in release builds
|
if( CMAKE_SIZEOF_VOID_P MATCHES "4")
|
||||||
set( REL_C_FLAGS "/MT" )
|
# 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
|
# 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+
|
# Disable warnings for unsecure CRT functions from VC8+
|
||||||
if( MSVC_VERSION GREATER 1399 )
|
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_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )
|
||||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_MINSIZEREL ${CMAKE_CXX_FLAGS_MINSIZEREL} )
|
||||||
string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} )
|
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_RELEASE ${CMAKE_C_FLAGS_RELEASE} )
|
||||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
string(REPLACE "/MD " " " CMAKE_C_FLAGS_MINSIZEREL ${CMAKE_C_FLAGS_MINSIZEREL} )
|
||||||
string(REPLACE "/MD " " " CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
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} )
|
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 )
|
endif( MSVC )
|
||||||
|
|
||||||
set( CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${REL_LINKER_FLAGS}" )
|
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_ZLIB "Use internal zlib")
|
||||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||||
|
option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
||||||
|
|
||||||
if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB )
|
||||||
message( STATUS "Using system zlib" )
|
message( STATUS "Using system zlib" )
|
||||||
|
@ -137,11 +206,19 @@ else( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
||||||
set( BZIP2_LIBRARY bz2 )
|
set( BZIP2_LIBRARY bz2 )
|
||||||
endif( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 )
|
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" )
|
set( LZMA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lzma/C" )
|
||||||
|
|
||||||
add_subdirectory( lzma )
|
add_subdirectory( lzma )
|
||||||
add_subdirectory( tools )
|
add_subdirectory( tools )
|
||||||
add_subdirectory( game-music-emu )
|
|
||||||
add_subdirectory( dumb )
|
add_subdirectory( dumb )
|
||||||
add_subdirectory( gdtoa )
|
add_subdirectory( gdtoa )
|
||||||
add_subdirectory( wadsrc )
|
add_subdirectory( wadsrc )
|
||||||
|
@ -150,3 +227,7 @@ add_subdirectory( src )
|
||||||
if( NOT WIN32 AND NOT APPLE )
|
if( NOT WIN32 AND NOT APPLE )
|
||||||
add_subdirectory( output_sdl )
|
add_subdirectory( output_sdl )
|
||||||
endif( NOT WIN32 AND NOT APPLE )
|
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 )
|
cmake_minimum_required( VERSION 2.4 )
|
||||||
|
|
||||||
|
make_release_only()
|
||||||
|
|
||||||
if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
|
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" )
|
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" )
|
endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
cmake_minimum_required( VERSION 2.4 )
|
cmake_minimum_required( VERSION 2.4 )
|
||||||
|
|
||||||
|
make_release_only()
|
||||||
|
|
||||||
include( CheckFunctionExists )
|
include( CheckFunctionExists )
|
||||||
|
|
||||||
# DUMB is much slower in a Debug build than a Release build, so we force a Release
|
# 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;
|
return (int)note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Period table for Protracker octaves 0-5:
|
// Period table for Protracker octaves 0-5:
|
||||||
static const unsigned short ProTrackerPeriodTable[6*12] =
|
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,
|
1736,1640,1548,1460,1378,1302,1228,1160,1094,1032,974,920,
|
||||||
1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914
|
1724,1628,1536,1450,1368,1292,1220,1150,1086,1026,968,914
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer)
|
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;
|
int dumb_it_max_to_mix = 64;
|
||||||
|
|
||||||
|
#if 0
|
||||||
static const int aiMODVol[] =
|
static const int aiMODVol[] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
|
@ -4425,6 +4428,7 @@ static const int aiPTMVolScaled[] =
|
||||||
836, 847, 859, 870, 881, 897, 908, 916,
|
836, 847, 859, 870, 881, 897, 908, 916,
|
||||||
927, 939, 950, 962, 969, 983, 1005, 1024
|
927, 939, 950, 962, 969, 983, 1005, 1024
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, double volume)
|
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;
|
int flags;
|
||||||
|
|
||||||
memcpy( sample->filename, data, 13 );
|
memcpy( sample->filename, data, 13 );
|
||||||
sample->filename[ 14 ] = 0;
|
sample->filename[ 13 ] = 0;
|
||||||
|
|
||||||
flags = data[ 13 ] | ( data[ 14 ] << 8 );
|
flags = data[ 13 ] | ( data[ 14 ] << 8 );
|
||||||
sample->default_volume = data[ 15 ];
|
sample->default_volume = data[ 15 ];
|
||||||
sample->length = data[ 16 ] | ( data[ 17 ] << 8 ) | ( data[ 18 ] << 16 ) | ( data[ 19 ] << 24 );
|
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 */
|
/* And finally, the sample data */
|
||||||
k = get_chunk_count(mod, DUMB_ID('S','B','O','D'));
|
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) {
|
if (sigdata->sample[i].flags & IT_SAMPLE_EXISTS) {
|
||||||
chunk = get_chunk_by_type(mod, DUMB_ID('S','B','O','D'), j);
|
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)) {
|
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);
|
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];
|
k = (chunk->data[j * 2] << 8) | chunk->data[j * 2 + 1];
|
||||||
l = (j == 1 || j == 2) ? 48 : 16;
|
l = (j == 1 || j == 2) ? 48 : 16;
|
||||||
if (k == 0) {
|
if (k == 0) {
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
cmake_minimum_required( VERSION 2.4 )
|
# CMake project definition file.
|
||||||
include( CheckCXXCompilerFlag )
|
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.
|
# I don't plan on debugging this, so make it a release build.
|
||||||
if( NOT CMAKE_BUILD_TYPE MATCHES "Release" )
|
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( HAVE_NO_ARRAY_BOUNDS )
|
||||||
endif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
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
|
# Default emulators to build (all of them! ;)
|
||||||
gme/Data_Reader.cpp
|
if (NOT DEFINED USE_GME_AY)
|
||||||
gme/Dual_Resampler.cpp
|
SET(USE_GME_AY 1 CACHE BOOL "Enable support for Spectrum ZX music emulation")
|
||||||
gme/Effects_Buffer.cpp
|
endif()
|
||||||
gme/Fir_Resampler.cpp
|
|
||||||
gme/gme.cpp
|
if (NOT DEFINED USE_GME_GBS)
|
||||||
gme/Gme_File.cpp
|
SET(USE_GME_GBS 1 CACHE BOOL "Enable support for Game Boy music emulation")
|
||||||
gme/M3u_Playlist.cpp
|
endif()
|
||||||
gme/Multi_Buffer.cpp
|
|
||||||
gme/Music_Emu.cpp
|
if (NOT DEFINED USE_GME_GYM)
|
||||||
|
SET(USE_GME_GYM 1 CACHE BOOL "Enable Sega MegaDrive/Genesis music emulation")
|
||||||
gme/Ay_Apu.cpp
|
endif()
|
||||||
gme/Ay_Cpu.cpp
|
|
||||||
gme/Ay_Emu.cpp
|
if (NOT DEFINED USE_GME_HES)
|
||||||
gme/Gb_Apu.cpp
|
SET(USE_GME_HES 1 CACHE BOOL "Enable PC Engine/TurboGrafx-16 music emulation")
|
||||||
gme/Gb_Cpu.cpp
|
endif()
|
||||||
gme/Gb_Oscs.cpp
|
|
||||||
gme/Gbs_Emu.cpp
|
if (NOT DEFINED USE_GME_KSS)
|
||||||
gme/Gym_Emu.cpp
|
SET(USE_GME_KSS 1 CACHE BOOL "Enable MSX or other Z80 systems music emulation")
|
||||||
gme/Hes_Apu.cpp
|
endif()
|
||||||
gme/Hes_Cpu.cpp
|
|
||||||
gme/Hes_Emu.cpp
|
if (NOT DEFINED USE_GME_NSF)
|
||||||
gme/Kss_Cpu.cpp
|
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation")
|
||||||
gme/Kss_Emu.cpp
|
endif()
|
||||||
gme/Kss_Scc_Apu.cpp
|
|
||||||
gme/Nes_Apu.cpp
|
if (NOT DEFINED USE_GME_NSFE)
|
||||||
gme/Nes_Cpu.cpp
|
SET(USE_GME_NSFE 1 CACHE BOOL "Enable NES NSFE and NSF music emulation")
|
||||||
gme/Nes_Fme7_Apu.cpp
|
endif()
|
||||||
gme/Nes_Namco_Apu.cpp
|
|
||||||
gme/Nes_Oscs.cpp
|
if (NOT DEFINED USE_GME_SAP)
|
||||||
gme/Nes_Vrc6_Apu.cpp
|
SET(USE_GME_SAP 1 CACHE BOOL "Enable Atari SAP music emulation")
|
||||||
gme/Nsf_Emu.cpp
|
endif()
|
||||||
gme/Nsfe_Emu.cpp
|
|
||||||
gme/Sap_Apu.cpp
|
if (NOT DEFINED USE_GME_SPC)
|
||||||
gme/Sap_Cpu.cpp
|
SET(USE_GME_SPC 1 CACHE BOOL "Enable SNES SPC music emulation")
|
||||||
gme/Sap_Emu.cpp
|
endif()
|
||||||
gme/Sms_Apu.cpp
|
|
||||||
gme/Snes_Spc.cpp
|
if (NOT DEFINED USE_GME_VGM)
|
||||||
gme/Spc_Cpu.cpp
|
SET(USE_GME_VGM 1 CACHE BOOL "Enable Sega VGM/VGZ music emulation")
|
||||||
gme/Spc_Dsp.cpp
|
endif()
|
||||||
gme/Spc_Emu.cpp
|
|
||||||
gme/Vgm_Emu.cpp
|
if (USE_GME_NSFE AND NOT USE_GME_NSF)
|
||||||
gme/Vgm_Emu_Impl.cpp
|
MESSAGE(" -- NSFE support requires NSF, enabling NSF support. --")
|
||||||
gme/Ym2413_Emu.cpp
|
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
||||||
gme/Ym2612_Emu.cpp )
|
endif()
|
||||||
target_link_libraries( gme )
|
|
||||||
|
# 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 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
|
Game_Music_Emu 0.5.2
|
||||||
--------------------
|
--------------------
|
||||||
- *TONS* of changes and improvements. You should re-read the new header
|
- *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
|
This might be slightly out-of-date at times, but will be a big help in
|
||||||
understanding the library implementation.
|
understanding the library implementation.
|
||||||
|
|
|
@ -80,6 +80,69 @@
|
||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</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
|
<Configuration
|
||||||
Name="Release|Win32"
|
Name="Release|Win32"
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
@ -146,6 +209,73 @@
|
||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</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
|
<Configuration
|
||||||
Name="Release DLL|Win32"
|
Name="Release DLL|Win32"
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
@ -221,136 +351,6 @@
|
||||||
Name="VCPostBuildEventTool"
|
Name="VCPostBuildEventTool"
|
||||||
/>
|
/>
|
||||||
</Configuration>
|
</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
|
<Configuration
|
||||||
Name="Release DLL|x64"
|
Name="Release DLL|x64"
|
||||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
@ -601,6 +601,10 @@
|
||||||
RelativePath=".\gme\Spc_Emu.cpp"
|
RelativePath=".\gme\Spc_Emu.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gme\Spc_Filter.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gme\Vgm_Emu.cpp"
|
RelativePath=".\gme\Vgm_Emu.cpp"
|
||||||
>
|
>
|
||||||
|
@ -703,6 +707,10 @@
|
||||||
RelativePath=".\gme\Gme_File.h"
|
RelativePath=".\gme\Gme_File.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gme\gme_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gme\Gym_Emu.h"
|
RelativePath=".\gme\Gym_Emu.h"
|
||||||
>
|
>
|
||||||
|
@ -823,6 +831,10 @@
|
||||||
RelativePath=".\gme\Spc_Emu.h"
|
RelativePath=".\gme\Spc_Emu.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\gme\Spc_Filter.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\gme\Vgm_Emu.h"
|
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>
|
Author : Shay Green <gblargg@gmail.com>
|
||||||
Website: http://www.slack.net/~ant/libs/
|
Website: http://www.slack.net/~ant/libs/
|
||||||
Forum : http://groups.google.com/group/blargg-sound-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)
|
License: GNU Lesser General Public License (LGPL)
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
--------
|
--------
|
||||||
* Overview
|
* Overview
|
||||||
* C and C++ interfaces
|
|
||||||
* Function reference
|
|
||||||
* Error handling
|
* Error handling
|
||||||
* Emulator types
|
* Emulator types
|
||||||
* M3U playlist support
|
* M3U playlist support
|
||||||
|
@ -21,7 +20,6 @@ Contents
|
||||||
* Modular construction
|
* Modular construction
|
||||||
* Obscure features
|
* Obscure features
|
||||||
* Solving problems
|
* Solving problems
|
||||||
* Deprecated features
|
|
||||||
* Thanks
|
* Thanks
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,56 +60,15 @@ deleted with gme_set_user_cleanup()
|
||||||
Refer to gme.h for a comprehensive summary of features.
|
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
|
Error handling
|
||||||
--------------
|
--------------
|
||||||
Functions which can fail have a return type of gme_err_t (blargg_err_t
|
Functions which can fail have a return type of gme_err_t, which is a
|
||||||
in the C++ interfaces), which is a pointer to an error string (const
|
pointer to an error string (const char*). If a function is successful it
|
||||||
char*). If a function is successful it returns NULL. Errors that you can
|
returns NULL. Errors that you can easily avoid are checked with debug
|
||||||
easily avoid are checked with debug assertions; gme_err_t return values
|
assertions; gme_err_t return values are only used for genuine run-time
|
||||||
are only used for genuine run-time errors that can't be easily predicted
|
errors that can't be easily predicted in advance (out of memory, I/O
|
||||||
in advance (out of memory, I/O errors, incompatible file data). Your
|
errors, incompatible file data). Your code should check all error
|
||||||
code should check all error values.
|
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.
|
|
||||||
|
|
||||||
When loading a music file in the wrong emulator or trying to load a
|
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
|
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
|
executable size, edit GME_TYPE_LIST in blargg_config.h. For example, to
|
||||||
support just NSF and GBS, use this:
|
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
|
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 );
|
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
|
Sound parameters
|
||||||
----------------
|
----------------
|
||||||
|
@ -437,21 +362,6 @@ separate threads.
|
||||||
* If all else fails, see if the demos work.
|
* 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
|
Thanks
|
||||||
------
|
------
|
||||||
Big thanks to Chris Moeller (kode54) for help with library testing and
|
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,
|
start. Also thanks to Richard Bannister, Mahendra Tallur, Shazz,
|
||||||
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
|
nenolod, theHobbit, Johan Samuelsson, and nes6502 for testing, using,
|
||||||
and giving feedback for the library in their respective game music
|
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"
|
#include "Ay_Apu.h"
|
||||||
|
|
||||||
|
@ -123,8 +123,8 @@ void Ay_Apu::write_data_( int addr, int data )
|
||||||
|
|
||||||
if ( (unsigned) addr >= 14 )
|
if ( (unsigned) addr >= 14 )
|
||||||
{
|
{
|
||||||
#ifdef dprintf
|
#ifdef debug_printf
|
||||||
dprintf( "Wrote to I/O port %02X\n", (int) addr );
|
debug_printf( "Wrote to I/O port %02X\n", (int) addr );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time )
|
||||||
end_time = final_end_time;
|
end_time = final_end_time;
|
||||||
|
|
||||||
//if ( !(regs [12] | regs [11]) )
|
//if ( !(regs [12] | regs [11]) )
|
||||||
// dprintf( "Used envelope period 0\n" );
|
// debug_printf( "Used envelope period 0\n" );
|
||||||
}
|
}
|
||||||
else if ( !volume )
|
else if ( !volume )
|
||||||
{
|
{
|
||||||
|
@ -250,7 +250,7 @@ void Ay_Apu::run_until( blip_time_t final_end_time )
|
||||||
ntime = start_time + old_noise_delay;
|
ntime = start_time + old_noise_delay;
|
||||||
noise_lfsr = old_noise_lfsr;
|
noise_lfsr = old_noise_lfsr;
|
||||||
//if ( (regs [6] & 0x1F) == 0 )
|
//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):
|
// The following efficiently handles several cases (least demanding first):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// AY-3-8910 sound chip emulator
|
// AY-3-8910 sound chip emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef AY_APU_H
|
#ifndef AY_APU_H
|
||||||
#define AY_APU_H
|
#define AY_APU_H
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ private:
|
||||||
Blip_Buffer* output;
|
Blip_Buffer* output;
|
||||||
} oscs [osc_count];
|
} oscs [osc_count];
|
||||||
blip_time_t last_time;
|
blip_time_t last_time;
|
||||||
byte latch;
|
|
||||||
byte regs [reg_count];
|
byte regs [reg_count];
|
||||||
|
|
||||||
struct {
|
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
|
Last validated with zexall 2006.11.21 5:26 PM
|
||||||
|
@ -469,7 +469,7 @@ possibly_out_of_time:
|
||||||
add_hl_data: {
|
add_hl_data: {
|
||||||
blargg_ulong sum = rp.hl + data;
|
blargg_ulong sum = rp.hl + data;
|
||||||
data ^= rp.hl;
|
data ^= rp.hl;
|
||||||
rp.hl = sum;
|
rp.hl = (uint16_t)sum;
|
||||||
flags = (flags & (S80 | Z40 | V04)) |
|
flags = (flags & (S80 | Z40 | V04)) |
|
||||||
(sum >> 16) |
|
(sum >> 16) |
|
||||||
(sum >> 8 & (F20 | F08)) |
|
(sum >> 8 & (F20 | F08)) |
|
||||||
|
@ -719,7 +719,7 @@ possibly_out_of_time:
|
||||||
flags = (flags & (S80 | Z40 | P04)) |
|
flags = (flags & (S80 | Z40 | P04)) |
|
||||||
(temp & (F20 | F08)) |
|
(temp & (F20 | F08)) |
|
||||||
(temp >> 8);
|
(temp >> 8);
|
||||||
rg.a = temp;
|
rg.a = (uint8_t)temp;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -807,6 +807,7 @@ possibly_out_of_time:
|
||||||
case 0xCB:
|
case 0xCB:
|
||||||
unsigned data2;
|
unsigned data2;
|
||||||
data2 = INSTR( 1 );
|
data2 = INSTR( 1 );
|
||||||
|
(void) data2; // TODO is this the same as data in all cases?
|
||||||
pc++;
|
pc++;
|
||||||
switch ( data )
|
switch ( data )
|
||||||
{
|
{
|
||||||
|
@ -1055,7 +1056,7 @@ possibly_out_of_time:
|
||||||
(temp >> 8 & H10) |
|
(temp >> 8 & H10) |
|
||||||
(sum >> 8 & (S80 | F20 | F08)) |
|
(sum >> 8 & (S80 | F20 | F08)) |
|
||||||
((temp - -0x8000) >> 14 & V04);
|
((temp - -0x8000) >> 14 & V04);
|
||||||
rp.hl = sum;
|
rp.hl = (uint16_t)sum;
|
||||||
if ( (uint16_t) sum )
|
if ( (uint16_t) sum )
|
||||||
goto loop;
|
goto loop;
|
||||||
flags |= Z40;
|
flags |= Z40;
|
||||||
|
@ -1252,7 +1253,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x4F: // LD R,A
|
case 0x4F: // LD R,A
|
||||||
SET_R( rg.a );
|
SET_R( rg.a );
|
||||||
dprintf( "LD R,A not supported\n" );
|
debug_printf( "LD R,A not supported\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
|
@ -1262,7 +1263,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x5F: // LD A,R
|
case 0x5F: // LD A,R
|
||||||
rg.a = GET_R();
|
rg.a = GET_R();
|
||||||
dprintf( "LD A,R not supported\n" );
|
debug_printf( "LD A,R not supported\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
ld_ai_common:
|
ld_ai_common:
|
||||||
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
||||||
|
@ -1285,7 +1286,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Opcode $ED $%02X not supported\n", data );
|
debug_printf( "Opcode $ED $%02X not supported\n", data );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1545,7 +1546,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1634,7 +1635,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Unnecessary DD/FD prefix encountered\n" );
|
debug_printf( "Unnecessary DD/FD prefix encountered\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
pc--;
|
pc--;
|
||||||
goto loop;
|
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 );
|
assert( false );
|
||||||
|
|
||||||
halt:
|
halt:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Z80 CPU emulator
|
// Z80 CPU emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef AY_CPU_H
|
#ifndef AY_CPU_H
|
||||||
#define 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"
|
#include "Ay_Emu.h"
|
||||||
|
|
||||||
|
@ -209,9 +209,9 @@ blargg_err_t Ay_Emu::start_track_( int track )
|
||||||
set_warning( "Missing file data" );
|
set_warning( "Missing file data" );
|
||||||
len = unsigned(file.end - in);
|
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
|
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 );
|
memcpy( mem.ram + addr, in, len );
|
||||||
|
|
||||||
if ( file.end - blocks < 8 )
|
if ( file.end - blocks < 8 )
|
||||||
|
@ -242,7 +242,7 @@ blargg_err_t Ay_Emu::start_track_( int track )
|
||||||
};
|
};
|
||||||
memcpy( mem.ram, passive, sizeof passive );
|
memcpy( mem.ram, passive, sizeof passive );
|
||||||
unsigned play_addr = get_be16( more_data + 4 );
|
unsigned play_addr = get_be16( more_data + 4 );
|
||||||
//dprintf( "Play: $%04X\n", play_addr );
|
//debug_printf( "Play: $%04X\n", play_addr );
|
||||||
if ( play_addr )
|
if ( play_addr )
|
||||||
{
|
{
|
||||||
memcpy( mem.ram, active, sizeof active );
|
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;
|
return;
|
||||||
|
|
||||||
enable_cpc:
|
enable_cpc:
|
||||||
|
@ -356,7 +356,7 @@ int ay_cpu_in( Ay_Cpu*, unsigned addr )
|
||||||
if ( (addr & 0xFF) == 0xFE )
|
if ( (addr & 0xFF) == 0xFE )
|
||||||
return 0xFF; // other values break some beeper tunes
|
return 0xFF; // other values break some beeper tunes
|
||||||
|
|
||||||
dprintf( "Unmapped IN : $%04X\n", addr );
|
debug_printf( "Unmapped IN : $%04X\n", addr );
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Sinclair Spectrum AY music file emulator
|
// Sinclair Spectrum AY music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef AY_EMU_H
|
#ifndef AY_EMU_H
|
||||||
#define AY_EMU_H
|
#define AY_EMU_H
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ protected:
|
||||||
private:
|
private:
|
||||||
file_t file;
|
file_t file;
|
||||||
|
|
||||||
unsigned play_addr;
|
|
||||||
cpu_time_t play_period;
|
cpu_time_t play_period;
|
||||||
cpu_time_t next_play;
|
cpu_time_t next_play;
|
||||||
Blip_Buffer* beeper_output;
|
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;
|
double const to_angle = PI / 2 / maxh / oversample;
|
||||||
for ( int i = 0; i < count; i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
double angle_maxh = angle * maxh;
|
||||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
double angle_maxh_mid = angle_maxh * cutoff;
|
||||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
|
||||||
double cos_angle = cos( angle );
|
|
||||||
|
|
||||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
double y = maxh;
|
||||||
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;
|
|
||||||
|
|
||||||
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"
|
#include "Classic_Emu.h"
|
||||||
|
|
||||||
|
@ -176,9 +176,9 @@ void Rom_Data_::set_addr_( long addr, int unit )
|
||||||
|
|
||||||
if ( 0 )
|
if ( 0 )
|
||||||
{
|
{
|
||||||
dprintf( "addr: %X\n", addr );
|
debug_printf( "addr: %X\n", addr );
|
||||||
dprintf( "file_size: %d\n", file_size_ );
|
debug_printf( "file_size: %d\n", file_size_ );
|
||||||
dprintf( "rounded: %d\n", rounded );
|
debug_printf( "rounded: %d\n", rounded );
|
||||||
dprintf( "mask: $%X\n", mask );
|
debug_printf( "mask: $%X\n", mask );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Common aspects of emulators which use Blip_Buffer for sound output
|
// 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
|
#ifndef CLASSIC_EMU_H
|
||||||
#define CLASSIC_EMU_H
|
#define CLASSIC_EMU_H
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
// File_Extractor 0.4.0. http://www.slack.net/~ant/
|
// File_Extractor 0.4.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#define IN_GME 1
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "Data_Reader.h"
|
#include "Data_Reader.h"
|
||||||
|
|
||||||
#include "blargg_endian.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
|
/* 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
|
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
|
General Public License as published by the Free Software Foundation; either
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#define DATA_READER_H
|
#define DATA_READER_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
#include "gme.h"
|
|
||||||
|
|
||||||
// Supports reading and finding out how many bytes are remaining
|
// Supports reading and finding out how many bytes are remaining
|
||||||
class Data_Reader {
|
class Data_Reader {
|
||||||
|
@ -117,7 +116,7 @@ private:
|
||||||
// Invokes callback function to read data. Size of data must be specified in advance.
|
// Invokes callback function to read data. Size of data must be specified in advance.
|
||||||
class Callback_Reader : public Data_Reader {
|
class Callback_Reader : public Data_Reader {
|
||||||
public:
|
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 );
|
Callback_Reader( callback_t, long size, void* data = 0 );
|
||||||
public:
|
public:
|
||||||
long read_avail( void*, long );
|
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"
|
#include "Dual_Resampler.h"
|
||||||
|
|
||||||
|
@ -20,7 +20,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
unsigned const resampler_extra = 256;
|
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() { }
|
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 );
|
assert( blip_buf.samples_avail() == pair_count );
|
||||||
|
|
||||||
resampler.write( new_count );
|
resampler.write( new_count );
|
||||||
|
|
||||||
long count = resampler.read( sample_buf.begin(), sample_buf_size );
|
long count = resampler.read( sample_buf.begin(), sample_buf_size );
|
||||||
assert( count == (long) sample_buf_size );
|
assert( count == (long) sample_buf_size );
|
||||||
|
|
||||||
mix_samples( blip_buf, out );
|
mix_samples( blip_buf, out );
|
||||||
blip_buf.remove_samples( pair_count );
|
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);
|
r = 0x7FFF - (r >> 24);
|
||||||
|
|
||||||
in += 2;
|
in += 2;
|
||||||
out [0] = l;
|
out [0] = (dsample_t)l;
|
||||||
out [1] = r;
|
out [1] = (dsample_t)r;
|
||||||
out += 2;
|
out += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Combination of Fir_Resampler and Blip_Buffer mixing. Used by Sega FM emulators.
|
// 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
|
#ifndef DUAL_RESAMPLER_H
|
||||||
#define 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"
|
#include "Effects_Buffer.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Multi-channel effects buffer with panning, echo and reverb
|
// 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
|
#ifndef EFFECTS_BUFFER_H
|
||||||
#define 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"
|
#include "Fir_Resampler.h"
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ int Fir_Resampler_::input_needed( blargg_long output_count ) const
|
||||||
output_count -= 2;
|
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 )
|
if ( input_extra < 0 )
|
||||||
input_extra = 0;
|
input_extra = 0;
|
||||||
return input_extra;
|
return input_extra;
|
||||||
|
@ -187,7 +187,7 @@ int Fir_Resampler_::avail_( blargg_long input_count ) const
|
||||||
int Fir_Resampler_::skip_input( long count )
|
int Fir_Resampler_::skip_input( long count )
|
||||||
{
|
{
|
||||||
int remain = int(write_pos - buf.begin());
|
int remain = int(write_pos - buf.begin());
|
||||||
int max_count = remain - width_ * stereo;
|
int max_count = int(remain - width_ * stereo);
|
||||||
if ( count > max_count )
|
if ( count > max_count )
|
||||||
count = max_count;
|
count = max_count;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Finite impulse response (FIR) resampler with adjustable FIR size
|
// 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
|
#ifndef FIR_RESAMPLER_H
|
||||||
#define FIR_RESAMPLER_H
|
#define FIR_RESAMPLER_H
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
int input_needed( blargg_long count ) const;
|
int input_needed( blargg_long count ) const;
|
||||||
|
|
||||||
// Number of output samples available
|
// 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:
|
public:
|
||||||
~Fir_Resampler_();
|
~Fir_Resampler_();
|
||||||
|
|
|
@ -271,7 +271,7 @@ void Gb_Apu::write_register( blip_time_t time, unsigned addr, int data )
|
||||||
}
|
}
|
||||||
else
|
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"
|
#include "Gb_Cpu.h"
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ unsigned const c_flag = 0x10;
|
||||||
// -- produced by the BOOST_STATIC_ASSERT line below
|
// -- produced by the BOOST_STATIC_ASSERT line below
|
||||||
#pragma warning(disable:4101)
|
#pragma warning(disable:4101)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool Gb_Cpu::run( blargg_long cycle_count )
|
bool Gb_Cpu::run( blargg_long cycle_count )
|
||||||
{
|
{
|
||||||
state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
|
state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr;
|
||||||
|
@ -716,7 +717,7 @@ loop:
|
||||||
temp += prev;
|
temp += prev;
|
||||||
flags &= z_flag;
|
flags &= z_flag;
|
||||||
add_16_hl:
|
add_16_hl:
|
||||||
rp.hl = temp;
|
rp.hl = (uint16_t)temp;
|
||||||
add_16_comm:
|
add_16_comm:
|
||||||
flags |= (temp >> 12) & c_flag;
|
flags |= (temp >> 12) & c_flag;
|
||||||
flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
|
flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Nintendo Game Boy CPU emulator
|
// Nintendo Game Boy CPU emulator
|
||||||
// Treats every instruction as taking 4 cycles
|
// Treats every instruction as taking 4 cycles
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef GB_CPU_H
|
#ifndef GB_CPU_H
|
||||||
#define 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"
|
#include "Gbs_Emu.h"
|
||||||
|
|
||||||
|
@ -18,8 +18,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#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::handheld_eq =
|
||||||
Gbs_Emu::equalizer_t const Gbs_Emu::headphones_eq = { 0.0, 300, 0, 0, 0, 0, 0, 0, 0, 0 };
|
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()
|
Gbs_Emu::Gbs_Emu()
|
||||||
{
|
{
|
||||||
|
@ -39,8 +41,7 @@ Gbs_Emu::Gbs_Emu()
|
||||||
set_max_initial_silence( 21 );
|
set_max_initial_silence( 21 );
|
||||||
set_gain( 1.2 );
|
set_gain( 1.2 );
|
||||||
|
|
||||||
static equalizer_t const eq = { -1.0, 120, 0, 0, 0, 0, 0, 0, 0, 0 };
|
set_equalizer( make_equalizer( -1.0, 120 ) );
|
||||||
set_equalizer( eq );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Gbs_Emu::~Gbs_Emu() { }
|
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
|
// TODO: what is the correct behavior? Current Game & Watch Gallery
|
||||||
// rip requires that this have no effect or set to bank 1.
|
// 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;
|
return;
|
||||||
//n = 1;
|
//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++ )
|
for ( int i = 0; i < (int) sizeof sound_data; i++ )
|
||||||
apu.write_register( 0, i + apu.start_addr, 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 );
|
unsigned load_addr = get_le16( header_.load_addr );
|
||||||
cpu::rst_base = load_addr;
|
|
||||||
rom.set_addr( 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( ram_addr, 0x10000 - ram_addr, ram );
|
||||||
cpu::map_code( 0, bank_size, rom.at_addr( 0 ) );
|
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 )
|
else if ( cpu::r.pc > 0xFFFF )
|
||||||
{
|
{
|
||||||
dprintf( "PC wrapped around\n" );
|
debug_printf( "PC wrapped around\n" );
|
||||||
cpu::r.pc &= 0xFFFF;
|
cpu::r.pc &= 0xFFFF;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_warning( "Emulation error (illegal/unsupported instruction)" );
|
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 );
|
(int) *cpu::get_code( cpu::r.pc ), (int) cpu::r.pc );
|
||||||
cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
|
cpu::r.pc = (cpu::r.pc + 1) & 0xFFFF;
|
||||||
cpu_time += 6;
|
cpu_time += 6;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Nintendo Game Boy GBS music file emulator
|
// Nintendo Game Boy GBS music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef GBS_EMU_H
|
#ifndef GBS_EMU_H
|
||||||
#define 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"
|
#include "Gme_File.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Common interface to game music file loading and information
|
// 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
|
#ifndef GME_FILE_H
|
||||||
#define 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"
|
#include "Gym_Emu.h"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// Sega Genesis/Mega Drive GYM music file emulator
|
// Sega Genesis/Mega Drive GYM music file emulator
|
||||||
// Includes with PCM timing recovery to improve sample quality.
|
// 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
|
#ifndef GYM_EMU_H
|
||||||
#define 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"
|
#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;
|
unsigned noise_lfsr = this->noise_lfsr;
|
||||||
do
|
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"
|
// Implemented using "Galios configuration"
|
||||||
// TODO: find correct LFSR algorithm
|
// 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));
|
//noise_lfsr = (noise_lfsr >> 1) ^ (0x6000 & -(noise_lfsr & 1));
|
||||||
int delta = new_dac - dac;
|
int delta = new_dac - dac;
|
||||||
if ( delta )
|
if ( delta )
|
||||||
|
@ -158,7 +158,7 @@ void Hes_Osc::run_until( synth_t& synth_, blip_time_t end_time )
|
||||||
//period = 0x1000 * 2;
|
//period = 0x1000 * 2;
|
||||||
period = 1;
|
period = 1;
|
||||||
//if ( !(volume_0 | volume_1) )
|
//if ( !(volume_0 | volume_1) )
|
||||||
// dprintf( "Used period 0\n" );
|
// debug_printf( "Used period 0\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// maintain phase when silent
|
// maintain phase when silent
|
||||||
|
@ -295,7 +295,7 @@ void Hes_Apu::write_data( blip_time_t time, int addr, int data )
|
||||||
|
|
||||||
case 0x809:
|
case 0x809:
|
||||||
if ( !(data & 0x80) && (data & 0x03) != 0 )
|
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
|
// 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
|
#ifndef HES_APU_H
|
||||||
#define 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"
|
#include "Hes_Cpu.h"
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ loop:
|
||||||
/*
|
/*
|
||||||
static long count;
|
static long count;
|
||||||
if ( count == 1844 ) Debugger();
|
if ( count == 1844 ) Debugger();
|
||||||
if ( s.base != correct ) dprintf( "%ld\n", count );
|
if ( s.base != correct ) debug_printf( "%ld\n", count );
|
||||||
count++;
|
count++;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -741,7 +741,7 @@ possibly_out_of_time:
|
||||||
ARITH_ADDR_MODES( 0x65 ) // ADC
|
ARITH_ADDR_MODES( 0x65 ) // ADC
|
||||||
adc_imm: {
|
adc_imm: {
|
||||||
if ( status & st_d )
|
if ( status & st_d )
|
||||||
dprintf( "Decimal mode not supported\n" );
|
debug_printf( "Decimal mode not supported\n" );
|
||||||
fint16 carry = c >> 8 & 1;
|
fint16 carry = c >> 8 & 1;
|
||||||
fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
|
fint16 ov = (a ^ 0x80) + carry + (BOOST::int8_t) data; // sign-extend
|
||||||
status &= ~st_v;
|
status &= ~st_v;
|
||||||
|
@ -1085,7 +1085,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
delayed_cli:
|
delayed_cli:
|
||||||
dprintf( "Delayed CLI not supported\n" ); // TODO: implement
|
debug_printf( "Delayed CLI not supported\n" ); // TODO: implement
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1100,7 @@ possibly_out_of_time:
|
||||||
s_time += delta;
|
s_time += delta;
|
||||||
if ( s_time < 0 )
|
if ( s_time < 0 )
|
||||||
goto loop;
|
goto loop;
|
||||||
dprintf( "Delayed SEI not supported\n" ); // TODO: implement
|
debug_printf( "Delayed SEI not supported\n" ); // TODO: implement
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,7 +1145,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
case 0x54: // CSL
|
case 0x54: // CSL
|
||||||
dprintf( "CSL not supported\n" );
|
debug_printf( "CSL not supported\n" );
|
||||||
illegal_encountered = true;
|
illegal_encountered = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
|
@ -1154,7 +1154,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0xF4: { // SET
|
case 0xF4: { // SET
|
||||||
//fuint16 operand = GET_MSB();
|
//fuint16 operand = GET_MSB();
|
||||||
dprintf( "SET not handled\n" );
|
debug_printf( "SET not handled\n" );
|
||||||
//switch ( data )
|
//switch ( data )
|
||||||
//{
|
//{
|
||||||
//}
|
//}
|
||||||
|
@ -1233,7 +1233,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert( (unsigned) opcode <= 0xFF );
|
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;
|
illegal_encountered = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// PC Engine CPU emulator for use with HES music files
|
// 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
|
#ifndef HES_CPU_H
|
||||||
#define 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"
|
#include "Hes_Emu.h"
|
||||||
|
|
||||||
|
@ -273,12 +273,12 @@ void Hes_Emu::cpu_write_vdp( int addr, int data )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dprintf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
|
debug_printf( "VDP not supported: $%02X <- $%02X\n", vdp.latch, data );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
|
||||||
run_until( time );
|
run_until( time );
|
||||||
irq.disables = data;
|
irq.disables = data;
|
||||||
if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
|
if ( (data & 0xF8) && (data & 0xF8) != 0xF8 ) // flag questionable values
|
||||||
dprintf( "Int mask: $%02X\n", data );
|
debug_printf( "Int mask: $%02X\n", data );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1403:
|
case 0x1403:
|
||||||
|
@ -344,7 +344,7 @@ void Hes_Emu::cpu_write_( hes_addr_t addr, int data )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "unmapped write $%04X <- $%02X\n", addr, data );
|
debug_printf( "unmapped write $%04X <- $%02X\n", addr, data );
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -368,14 +368,14 @@ int Hes_Emu::cpu_read_( hes_addr_t addr )
|
||||||
|
|
||||||
case 0x0002:
|
case 0x0002:
|
||||||
case 0x0003:
|
case 0x0003:
|
||||||
dprintf( "VDP read not supported: %d\n", addr );
|
debug_printf( "VDP read not supported: %d\n", addr );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case 0x0C01:
|
case 0x0C01:
|
||||||
//return timer.enabled; // TODO: remove?
|
//return timer.enabled; // TODO: remove?
|
||||||
case 0x0C00:
|
case 0x0C00:
|
||||||
run_until( time );
|
run_until( time );
|
||||||
dprintf( "Timer count read\n" );
|
debug_printf( "Timer count read\n" );
|
||||||
return (unsigned) (timer.count - 1) / timer_base;
|
return (unsigned) (timer.count - 1) / timer_base;
|
||||||
|
|
||||||
case 0x1402:
|
case 0x1402:
|
||||||
|
@ -396,7 +396,7 @@ int Hes_Emu::cpu_read_( hes_addr_t addr )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "unmapped read $%04X\n", addr );
|
debug_printf( "unmapped read $%04X\n", addr );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// TurboGrafx-16/PC Engine HES music file emulator
|
// TurboGrafx-16/PC Engine HES music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef HES_EMU_H
|
#ifndef HES_EMU_H
|
||||||
#define 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
|
Last validated with zexall 2006.11.14 2:19 PM
|
||||||
|
@ -503,7 +503,7 @@ possibly_out_of_time:
|
||||||
add_hl_data: {
|
add_hl_data: {
|
||||||
blargg_ulong sum = rp.hl + data;
|
blargg_ulong sum = rp.hl + data;
|
||||||
data ^= rp.hl;
|
data ^= rp.hl;
|
||||||
rp.hl = sum;
|
rp.hl = (uint16_t)sum;
|
||||||
flags = (flags & (S80 | Z40 | V04)) |
|
flags = (flags & (S80 | Z40 | V04)) |
|
||||||
(sum >> 16) |
|
(sum >> 16) |
|
||||||
(sum >> 8 & (F20 | F08)) |
|
(sum >> 8 & (F20 | F08)) |
|
||||||
|
@ -753,7 +753,7 @@ possibly_out_of_time:
|
||||||
flags = (flags & (S80 | Z40 | P04)) |
|
flags = (flags & (S80 | Z40 | P04)) |
|
||||||
(temp & (F20 | F08)) |
|
(temp & (F20 | F08)) |
|
||||||
(temp >> 8);
|
(temp >> 8);
|
||||||
rg.a = temp;
|
rg.a = (uint8_t)temp;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,6 +841,7 @@ possibly_out_of_time:
|
||||||
case 0xCB:
|
case 0xCB:
|
||||||
unsigned data2;
|
unsigned data2;
|
||||||
data2 = instr [1];
|
data2 = instr [1];
|
||||||
|
(void) data2; // TODO is this the same as data in all cases?
|
||||||
pc++;
|
pc++;
|
||||||
switch ( data )
|
switch ( data )
|
||||||
{
|
{
|
||||||
|
@ -1092,7 +1093,7 @@ possibly_out_of_time:
|
||||||
(temp >> 8 & H10) |
|
(temp >> 8 & H10) |
|
||||||
(sum >> 8 & (S80 | F20 | F08)) |
|
(sum >> 8 & (S80 | F20 | F08)) |
|
||||||
((temp - -0x8000) >> 14 & V04);
|
((temp - -0x8000) >> 14 & V04);
|
||||||
rp.hl = sum;
|
rp.hl = (uint16_t)sum;
|
||||||
if ( (uint16_t) sum )
|
if ( (uint16_t) sum )
|
||||||
goto loop;
|
goto loop;
|
||||||
flags |= Z40;
|
flags |= Z40;
|
||||||
|
@ -1289,7 +1290,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x4F: // LD R,A
|
case 0x4F: // LD R,A
|
||||||
SET_R( rg.a );
|
SET_R( rg.a );
|
||||||
dprintf( "LD R,A not supported\n" );
|
debug_printf( "LD R,A not supported\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
|
@ -1299,7 +1300,7 @@ possibly_out_of_time:
|
||||||
|
|
||||||
case 0x5F: // LD A,R
|
case 0x5F: // LD A,R
|
||||||
rg.a = GET_R();
|
rg.a = GET_R();
|
||||||
dprintf( "LD A,R not supported\n" );
|
debug_printf( "LD A,R not supported\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
ld_ai_common:
|
ld_ai_common:
|
||||||
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
flags = (flags & C01) | SZ28( rg.a ) | (r.iff2 << 2 & V04);
|
||||||
|
@ -1322,7 +1323,7 @@ possibly_out_of_time:
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Opcode $ED $%02X not supported\n", data );
|
debug_printf( "Opcode $ED $%02X not supported\n", data );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1583,7 +1584,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
debug_printf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
|
||||||
warning = true;
|
warning = true;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1672,7 +1673,7 @@ possibly_out_of_time:
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf( "Unnecessary DD/FD prefix encountered\n" );
|
debug_printf( "Unnecessary DD/FD prefix encountered\n" );
|
||||||
warning = true;
|
warning = true;
|
||||||
pc--;
|
pc--;
|
||||||
goto loop;
|
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 );
|
assert( false );
|
||||||
|
|
||||||
hit_idle_addr:
|
hit_idle_addr:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Z80 CPU emulator
|
// Z80 CPU emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef KSS_CPU_H
|
#ifndef KSS_CPU_H
|
||||||
#define 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"
|
#include "Kss_Emu.h"
|
||||||
|
|
||||||
|
@ -230,9 +230,9 @@ blargg_err_t Kss_Emu::start_track_( int track )
|
||||||
bank_count = max_banks;
|
bank_count = max_banks;
|
||||||
set_warning( "Bank data missing" );
|
set_warning( "Bank data missing" );
|
||||||
}
|
}
|
||||||
//dprintf( "load_size : $%X\n", load_size );
|
//debug_printf( "load_size : $%X\n", load_size );
|
||||||
//dprintf( "bank_size : $%X\n", bank_size );
|
//debug_printf( "bank_size : $%X\n", bank_size );
|
||||||
//dprintf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
|
//debug_printf( "bank_count: %d (%d claimed)\n", bank_count, header_.bank_mode & 0x7F );
|
||||||
|
|
||||||
ram [idle_addr] = 0xFF;
|
ram [idle_addr] = 0xFF;
|
||||||
cpu::reset( unmapped_write, unmapped_read );
|
cpu::reset( unmapped_write, unmapped_read );
|
||||||
|
@ -301,7 +301,7 @@ void Kss_Emu::cpu_write( unsigned addr, int data )
|
||||||
return;
|
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 )
|
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
|
#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 )
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// MSX computer KSS music file emulator
|
// MSX computer KSS music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef KSS_EMU_H
|
#ifndef KSS_EMU_H
|
||||||
#define KSS_EMU_H
|
#define KSS_EMU_H
|
||||||
|
|
||||||
|
@ -68,7 +68,6 @@ private:
|
||||||
void update_gain();
|
void update_gain();
|
||||||
|
|
||||||
unsigned scc_enabled; // 0 or 0xC000
|
unsigned scc_enabled; // 0 or 0xC000
|
||||||
byte const* bank_data;
|
|
||||||
int bank_count;
|
int bank_count;
|
||||||
void set_bank( int logical, int physical );
|
void set_bank( int logical, int physical );
|
||||||
blargg_long bank_size() const { return (16 * 1024L) >> (header_.bank_mode >> 7 & 1); }
|
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"
|
#include "Kss_Scc_Apu.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Konami SCC sound chip emulator
|
// Konami SCC sound chip emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef KSS_SCC_APU_H
|
#ifndef KSS_SCC_APU_H
|
||||||
#define KSS_SCC_APU_H
|
#define KSS_SCC_APU_H
|
||||||
|
|
||||||
|
|
|
@ -1,6 +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 IN_GME 1
|
|
||||||
|
|
||||||
#include "M3u_Playlist.h"
|
#include "M3u_Playlist.h"
|
||||||
#include "Music_Emu.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 ) ); }
|
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 );
|
Mem_File_Reader in( data, size );
|
||||||
return me->load_m3u( in );
|
return me->load_m3u( in );
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// M3U playlist file parser, with support for subtrack information
|
// 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
|
#ifndef M3U_PLAYLIST_H
|
||||||
#define M3U_PLAYLIST_H
|
#define M3U_PLAYLIST_H
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public:
|
||||||
int repeat; // count
|
int repeat; // count
|
||||||
};
|
};
|
||||||
entry_t const& operator [] ( int i ) const { return entries [i]; }
|
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();
|
void clear();
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
|
||||||
if ( count )
|
if ( count )
|
||||||
{
|
{
|
||||||
int bufs_used = stereo_added | was_stereo;
|
int bufs_used = stereo_added | was_stereo;
|
||||||
//dprintf( "%X\n", bufs_used );
|
//debug_printf( "%X\n", bufs_used );
|
||||||
if ( bufs_used <= 1 )
|
if ( bufs_used <= 1 )
|
||||||
{
|
{
|
||||||
mix_mono( out, count );
|
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( left, bass );
|
||||||
BLIP_READER_NEXT( right, bass );
|
BLIP_READER_NEXT( right, bass );
|
||||||
|
|
||||||
out [0] = l;
|
out [0] = (blip_sample_t)l;
|
||||||
out [1] = r;
|
out [1] = (blip_sample_t)r;
|
||||||
out += 2;
|
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( left, bass );
|
||||||
BLIP_READER_NEXT( right, bass );
|
BLIP_READER_NEXT( right, bass );
|
||||||
|
|
||||||
out [0] = l;
|
out [0] = (blip_sample_t)l;
|
||||||
out [1] = r;
|
out [1] = (blip_sample_t)r;
|
||||||
out += 2;
|
out += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +223,8 @@ void Stereo_Buffer::mix_mono( blip_sample_t* out_, blargg_long count )
|
||||||
s = 0x7FFF - (s >> 24);
|
s = 0x7FFF - (s >> 24);
|
||||||
|
|
||||||
BLIP_READER_NEXT( center, bass );
|
BLIP_READER_NEXT( center, bass );
|
||||||
out [0] = s;
|
out [0] = (blip_sample_t)s;
|
||||||
out [1] = s;
|
out [1] = (blip_sample_t)s;
|
||||||
out += 2;
|
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"
|
#include "Music_Emu.h"
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ int const silence_threshold = 0x10;
|
||||||
long const fade_block_size = 512;
|
long const fade_block_size = 512;
|
||||||
int const fade_shift = 8; // fade ends with gain at 1.0 / (1 << fade_shift)
|
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()
|
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;
|
Music_Emu::sample_t* p = begin + size;
|
||||||
while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
|
while ( (unsigned) (*--p + silence_threshold / 2) <= (unsigned) silence_threshold ) { }
|
||||||
*begin = first;
|
*begin = first;
|
||||||
return size - long(p - begin);
|
return size - (p - begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill internal buffer and check it for silence
|
// 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 );
|
assert( emu_time >= out_time );
|
||||||
|
|
||||||
// prints nifty graph of how far ahead we are when searching for silence
|
// 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;
|
long pos = 0;
|
||||||
if ( silence_count )
|
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_::pre_load() { Gme_File::pre_load(); } // skip Music_Emu
|
||||||
void Gme_Info_::post_load_() { Gme_File::post_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_::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_::mute_voices_( int ) { check( false ); }
|
||||||
void Gme_Info_::set_tempo_( double ) { }
|
void Gme_Info_::set_tempo_( double ) { }
|
||||||
blargg_err_t Gme_Info_::start_track_( int ) { return "Use full emulator for playback"; }
|
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
|
// Common interface to game music file emulators
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef MUSIC_EMU_H
|
#ifndef MUSIC_EMU_H
|
||||||
#define 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().
|
// on others this has no effect. Should be called only once *before* set_sample_rate().
|
||||||
virtual void set_buffer( Multi_Buffer* ) { }
|
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)
|
// Sound equalization (treble/bass)
|
||||||
|
|
||||||
// Frequency equalizer parameters (see gme.txt)
|
// Frequency equalizer parameters (see gme.txt)
|
||||||
|
@ -93,6 +97,14 @@ public:
|
||||||
|
|
||||||
// Set frequency equalizer parameters
|
// Set frequency equalizer parameters
|
||||||
void set_equalizer( equalizer_t const& );
|
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
|
// Equalizer settings for TV speaker
|
||||||
static equalizer_t const tv_eq;
|
static equalizer_t const tv_eq;
|
||||||
|
@ -111,7 +123,8 @@ protected:
|
||||||
void remute_voices();
|
void remute_voices();
|
||||||
|
|
||||||
virtual blargg_err_t set_sample_rate_( long sample_rate ) = 0;
|
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 mute_voices_( int mask ) = 0;
|
||||||
virtual void set_tempo_( double ) = 0;
|
virtual void set_tempo_( double ) = 0;
|
||||||
virtual blargg_err_t start_track_( int ) = 0; // tempo is set before this
|
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 );
|
void emu_play( long count, sample_t* out );
|
||||||
|
|
||||||
Multi_Buffer* effects_buffer;
|
Multi_Buffer* effects_buffer;
|
||||||
friend GMEDLL Music_Emu* GMEAPI gme_new_emu( gme_type_t, int );
|
friend Music_Emu* gme_new_emu( gme_type_t, int );
|
||||||
friend GMEDLL void GMEAPI gme_set_stereo_depth( Music_Emu*, double );
|
friend void gme_set_stereo_depth( Music_Emu*, double );
|
||||||
};
|
};
|
||||||
|
|
||||||
// base class for info-only derivations
|
// 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 blargg_err_t set_sample_rate_( long sample_rate );
|
||||||
virtual void set_equalizer_( equalizer_t const& );
|
virtual void set_equalizer_( equalizer_t const& );
|
||||||
|
virtual void enable_accuracy_( bool );
|
||||||
virtual void mute_voices_( int mask );
|
virtual void mute_voices_( int mask );
|
||||||
virtual void set_tempo_( double );
|
virtual void set_tempo_( double );
|
||||||
virtual blargg_err_t start_track_( int );
|
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 bool Music_Emu::track_ended() const { return track_ended_; }
|
||||||
inline const Music_Emu::equalizer_t& Music_Emu::equalizer() const { return equalizer_; }
|
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::set_tempo_( double t ) { tempo_ = t; }
|
||||||
inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); }
|
inline void Music_Emu::remute_voices() { mute_voices( mute_mask_ ); }
|
||||||
inline void Music_Emu::ignore_silence( bool b ) { ignore_silence_ = b; }
|
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();
|
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;
|
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"
|
#include "Nes_Cpu.h"
|
||||||
|
|
||||||
|
@ -921,7 +921,7 @@ imm##op:
|
||||||
goto loop;
|
goto loop;
|
||||||
status &= ~st_i;
|
status &= ~st_i;
|
||||||
handle_cli: {
|
handle_cli: {
|
||||||
//dprintf( "CLI at %d\n", TIME );
|
//debug_printf( "CLI at %d\n", TIME );
|
||||||
this->r.status = status; // update externally-visible I flag
|
this->r.status = status; // update externally-visible I flag
|
||||||
blargg_long delta = s.base - irq_time_;
|
blargg_long delta = s.base - irq_time_;
|
||||||
if ( delta <= 0 )
|
if ( delta <= 0 )
|
||||||
|
@ -944,7 +944,7 @@ imm##op:
|
||||||
|
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
delayed_cli:
|
delayed_cli:
|
||||||
dprintf( "Delayed CLI not emulated\n" );
|
debug_printf( "Delayed CLI not emulated\n" );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +960,7 @@ imm##op:
|
||||||
if ( s_time < 0 )
|
if ( s_time < 0 )
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
dprintf( "Delayed SEI not emulated\n" );
|
debug_printf( "Delayed SEI not emulated\n" );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// NES 6502 CPU emulator
|
// NES 6502 CPU emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef NES_CPU_H
|
#ifndef NES_CPU_H
|
||||||
#define 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"
|
#include "Nes_Fme7_Apu.h"
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void Nes_Fme7_Apu::run_until( blip_time_t end_time )
|
||||||
// check for unsupported mode
|
// check for unsupported mode
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if ( (mode & 011) <= 001 && vol_mode & 0x1F )
|
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 );
|
mode, vol_mode & 0x1F );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Sunsoft FME-7 sound emulator
|
// Sunsoft FME-7 sound emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef NES_FME7_APU_H
|
#ifndef NES_FME7_APU_H
|
||||||
#define 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 )
|
if ( (unsigned) latch >= reg_count )
|
||||||
{
|
{
|
||||||
#ifdef dprintf
|
#ifdef debug_printf
|
||||||
dprintf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
|
debug_printf( "FME7 write to %02X (past end of sound registers)\n", (int) latch );
|
||||||
#endif
|
#endif
|
||||||
return;
|
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"
|
#include "Nsf_Emu.h"
|
||||||
|
|
||||||
|
@ -31,8 +31,10 @@ int const fme7_flag = 0x20;
|
||||||
|
|
||||||
long const clock_divisor = 12;
|
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::nes_eq =
|
||||||
Nsf_Emu::equalizer_t const Nsf_Emu::famicom_eq = { -15.0, 80, 0, 0, 0, 0, 0, 0, 0, 0 };
|
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 )
|
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?
|
// memory mapper?
|
||||||
if ( addr == 0xFFF8 ) return;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Nintendo NES/Famicom NSF music file emulator
|
// Nintendo NES/Famicom NSF music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef NSF_EMU_H
|
#ifndef NSF_EMU_H
|
||||||
#define 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
|
#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 size = get_le32( block_header [0] );
|
||||||
blargg_long tag = get_le32( block_header [1] );
|
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 )
|
switch ( tag )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Nintendo NES/Famicom NSFE music file emulator
|
// Nintendo NES/Famicom NSFE music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef NSFE_EMU_H
|
#ifndef NSFE_EMU_H
|
||||||
#define 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"
|
#include "Sap_Apu.h"
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ Sap_Apu_Impl::Sap_Apu_Impl()
|
||||||
blargg_ulong rev = n & 1;
|
blargg_ulong rev = n & 1;
|
||||||
for ( int i = 1; i < poly5_len; i++ )
|
for ( int i = 1; i < poly5_len; i++ )
|
||||||
rev |= (n >> i & 1) << (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;
|
period = (period - 6) * divider;
|
||||||
|
|
||||||
if ( (osc [-1].regs [1] & 0x1F) > 0x10 )
|
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;
|
osc->period = period;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Atari POKEY sound chip emulator
|
// Atari POKEY sound chip emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef SAP_APU_H
|
#ifndef SAP_APU_H
|
||||||
#define 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"
|
#include "Sap_Cpu.h"
|
||||||
|
|
||||||
|
@ -889,7 +889,7 @@ imm##op:
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
delayed_cli:
|
delayed_cli:
|
||||||
dprintf( "Delayed CLI not emulated\n" );
|
debug_printf( "Delayed CLI not emulated\n" );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,7 +904,7 @@ imm##op:
|
||||||
s_time += delta;
|
s_time += delta;
|
||||||
if ( s_time < 0 )
|
if ( s_time < 0 )
|
||||||
goto loop;
|
goto loop;
|
||||||
dprintf( "Delayed SEI not emulated\n" );
|
debug_printf( "Delayed SEI not emulated\n" );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,7 +945,7 @@ handle_brk:
|
||||||
goto idle_done;
|
goto idle_done;
|
||||||
pc++;
|
pc++;
|
||||||
result_ = 4;
|
result_ = 4;
|
||||||
dprintf( "BRK executed\n" );
|
debug_printf( "BRK executed\n" );
|
||||||
|
|
||||||
interrupt:
|
interrupt:
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Atari 6502 CPU emulator
|
// Atari 6502 CPU emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef SAP_CPU_H
|
#ifndef SAP_CPU_H
|
||||||
#define 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"
|
#include "Sap_Emu.h"
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ blargg_err_t Sap_Emu::start_track_( int track )
|
||||||
{
|
{
|
||||||
unsigned start = get_le16( in );
|
unsigned start = get_le16( in );
|
||||||
unsigned end = get_le16( in + 2 );
|
unsigned end = get_le16( in + 2 );
|
||||||
//dprintf( "Block $%04X-$%04X\n", start, end );
|
//debug_printf( "Block $%04X-$%04X\n", start, end );
|
||||||
in += 4;
|
in += 4;
|
||||||
if ( end < start )
|
if ( end < start )
|
||||||
{
|
{
|
||||||
|
@ -390,7 +390,7 @@ void Sap_Emu::cpu_write_( sap_addr_t addr, int data )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (addr & ~0x0010) != 0xD20F || data != 0x03 )
|
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()
|
inline void Sap_Emu::call_play()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Atari XL/XE SAP music file emulator
|
// Atari XL/XE SAP music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef SAP_EMU_H
|
#ifndef SAP_EMU_H
|
||||||
#define SAP_EMU_H
|
#define SAP_EMU_H
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SPC emulation support: init, sample buffering, reset, SPC loading
|
// 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"
|
#include "Snes_Spc.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// SNES SPC-700 APU emulator
|
// SNES SPC-700 APU emulator
|
||||||
|
|
||||||
// snes_spc 0.9.0
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef SNES_SPC_H
|
#ifndef SNES_SPC_H
|
||||||
#define SNES_SPC_H
|
#define SNES_SPC_H
|
||||||
|
|
||||||
|
@ -66,10 +66,7 @@ public:
|
||||||
// Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc.
|
// Sets tempo, where tempo_unit = normal, tempo_unit / 2 = half speed, etc.
|
||||||
enum { tempo_unit = 0x100 };
|
enum { tempo_unit = 0x100 };
|
||||||
void set_tempo( int );
|
void set_tempo( int );
|
||||||
|
|
||||||
enum { gain_unit = Spc_Dsp::gain_unit };
|
|
||||||
void set_gain( int gain );
|
|
||||||
|
|
||||||
// SPC music files
|
// SPC music files
|
||||||
|
|
||||||
// Loads SPC data into emulator
|
// Loads SPC data into emulator
|
||||||
|
@ -107,6 +104,22 @@ public:
|
||||||
bool check_kon();
|
bool check_kon();
|
||||||
#endif
|
#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:
|
public:
|
||||||
BLARGG_DISABLE_NOTHROW
|
BLARGG_DISABLE_NOTHROW
|
||||||
|
|
||||||
|
@ -146,15 +159,7 @@ private:
|
||||||
|
|
||||||
uint8_t smp_regs [2] [reg_count];
|
uint8_t smp_regs [2] [reg_count];
|
||||||
|
|
||||||
struct
|
regs_t cpu_regs;
|
||||||
{
|
|
||||||
int pc;
|
|
||||||
int a;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int psw;
|
|
||||||
int sp;
|
|
||||||
} cpu_regs;
|
|
||||||
|
|
||||||
rel_time_t dsp_time;
|
rel_time_t dsp_time;
|
||||||
time_t spc_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;
|
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::mute_voices( int mask ) { dsp.mute_voices( mask ); }
|
||||||
|
|
||||||
inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
|
inline void Snes_Spc::disable_surround( bool disable ) { dsp.disable_surround( disable ); }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Core SPC emulation: CPU, timers, SMP registers, memory
|
// 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"
|
#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 )
|
if ( REGS [r_dspaddr] <= 0x7F )
|
||||||
dsp.write( REGS [r_dspaddr], data );
|
dsp.write( REGS [r_dspaddr], data );
|
||||||
else if ( !SPC_MORE_ACCURACY )
|
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
|
#endif
|
||||||
|
|
||||||
// divided into multiple functions to keep rarely-used functionality separate
|
// Read/write handlers are divided into multiple functions to keep rarely-used
|
||||||
// so often-used functionality can be optimized better by compiler
|
// 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
|
// If write isn't preceded by read, data has this added to it
|
||||||
int const no_read_before_write = 0x2000;
|
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 ) &&
|
t->next_time == time + TIMER_MUL( t, 1 ) &&
|
||||||
((period - 1) | ~0x0F) & period )
|
((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,
|
// If the period is 3, 5, or 9, there's a probability this behavior won't occur,
|
||||||
// based on the previous period
|
// 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_t1out:
|
||||||
case r_t2out:
|
case r_t2out:
|
||||||
if ( !SPC_MORE_ACCURACY )
|
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 )
|
if ( data < no_read_before_write / 2 )
|
||||||
run_timer( &m.timers [addr - r_t0out], time - 1 )->counter = 0;
|
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:
|
case r_test:
|
||||||
if ( (uint8_t) data != 0x0A )
|
if ( (uint8_t) data != 0x0A )
|
||||||
dprintf( "SPC wrote to test register\n" );
|
debug_printf( "SPC wrote to test register\n" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case r_control:
|
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
|
/* 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
|
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
|
#if SPC_MORE_ACCURACY
|
||||||
#define SUSPICIOUS_OPCODE( name ) ((void) 0)
|
#define SUSPICIOUS_OPCODE( name ) ((void) 0)
|
||||||
#else
|
#else
|
||||||
#define SUSPICIOUS_OPCODE( name ) dprintf( "SPC: suspicious opcode: " name "\n" )
|
#define SUSPICIOUS_OPCODE( name ) debug_printf( "SPC: suspicious opcode: " name "\n" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CPU_READ( time, offset, addr )\
|
#define CPU_READ( time, offset, addr )\
|
||||||
|
@ -242,7 +242,7 @@ loop:
|
||||||
BRANCH( (uint8_t) nz )
|
BRANCH( (uint8_t) nz )
|
||||||
|
|
||||||
case 0x3F:{// CALL
|
case 0x3F:{// CALL
|
||||||
int old_addr = int(GET_PC() + 2);
|
int old_addr = GET_PC() + 2;
|
||||||
SET_PC( READ_PC16( pc ) );
|
SET_PC( READ_PC16( pc ) );
|
||||||
PUSH16( old_addr );
|
PUSH16( old_addr );
|
||||||
goto loop;
|
goto loop;
|
||||||
|
@ -1184,7 +1184,7 @@ loop:
|
||||||
{
|
{
|
||||||
addr &= 0xFFFF;
|
addr &= 0xFFFF;
|
||||||
SET_PC( addr );
|
SET_PC( addr );
|
||||||
dprintf( "SPC: PC wrapped around\n" );
|
debug_printf( "SPC: PC wrapped around\n" );
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1205,7 +1205,7 @@ stop:
|
||||||
|
|
||||||
// Uncache registers
|
// Uncache registers
|
||||||
if ( GET_PC() >= 0x10000 )
|
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.pc = (uint16_t) GET_PC();
|
||||||
m.cpu_regs.sp = ( uint8_t) GET_SP();
|
m.cpu_regs.sp = ( uint8_t) GET_SP();
|
||||||
m.cpu_regs.a = ( uint8_t) a;
|
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"
|
#include "Spc_Dsp.h"
|
||||||
|
|
||||||
|
@ -606,8 +606,8 @@ skip_brr:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sound out
|
// Sound out
|
||||||
int l = (((main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 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) * m.gain) >> 8;
|
int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14;
|
||||||
|
|
||||||
CLAMP16( l );
|
CLAMP16( l );
|
||||||
CLAMP16( r );
|
CLAMP16( r );
|
||||||
|
@ -641,7 +641,6 @@ void Spc_Dsp::mute_voices( int mask )
|
||||||
void Spc_Dsp::init( void* ram_64k )
|
void Spc_Dsp::init( void* ram_64k )
|
||||||
{
|
{
|
||||||
m.ram = (uint8_t*) ram_64k;
|
m.ram = (uint8_t*) ram_64k;
|
||||||
set_gain( gain_unit );
|
|
||||||
mute_voices( 0 );
|
mute_voices( 0 );
|
||||||
disable_surround( false );
|
disable_surround( false );
|
||||||
set_output( 0, 0 );
|
set_output( 0, 0 );
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// Fast SNES SPC-700 DSP emulator (about 3x speed of accurate one)
|
// 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
|
#ifndef SPC_DSP_H
|
||||||
#define SPC_DSP_H
|
#define SPC_DSP_H
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
class Spc_Dsp {
|
struct Spc_Dsp {
|
||||||
public:
|
public:
|
||||||
typedef BOOST::uint8_t uint8_t;
|
typedef BOOST::uint8_t uint8_t;
|
||||||
|
|
||||||
|
@ -51,10 +51,7 @@ public:
|
||||||
|
|
||||||
// If true, prevents channels and global volumes from being phase-negated
|
// If true, prevents channels and global volumes from being phase-negated
|
||||||
void disable_surround( bool disable = true );
|
void disable_surround( bool disable = true );
|
||||||
|
|
||||||
enum { gain_unit = 0x100 };
|
|
||||||
void set_gain( int gain );
|
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
|
||||||
// Resets DSP and uses supplied values to initialize registers
|
// Resets DSP and uses supplied values to initialize registers
|
||||||
|
@ -140,7 +137,6 @@ private:
|
||||||
// non-emulation state
|
// non-emulation state
|
||||||
uint8_t* ram; // 64K shared RAM between DSP and SMP
|
uint8_t* ram; // 64K shared RAM between DSP and SMP
|
||||||
int mute_mask;
|
int mute_mask;
|
||||||
int gain;
|
|
||||||
int surround_threshold;
|
int surround_threshold;
|
||||||
sample_t* out;
|
sample_t* out;
|
||||||
sample_t* out_end;
|
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 )
|
inline void Spc_Dsp::disable_surround( bool disable )
|
||||||
{
|
{
|
||||||
m.surround_threshold = disable ? 0 : -0x4000;
|
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"
|
#include "Spc_Emu.h"
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
|
// TODO: support Spc_Filter's bass
|
||||||
|
|
||||||
Spc_Emu::Spc_Emu()
|
Spc_Emu::Spc_Emu()
|
||||||
{
|
{
|
||||||
set_type( gme_spc_type );
|
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;
|
byte const* in = begin + 8;
|
||||||
if ( end - in > info_size )
|
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;
|
end = in + info_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +116,7 @@ static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
|
||||||
default:
|
default:
|
||||||
if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
|
if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
|
||||||
(id > 0x14 && id < 0x30) || id > 0x36 )
|
(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;
|
break;
|
||||||
}
|
}
|
||||||
if ( field )
|
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
|
// ...but some files have no padding
|
||||||
in = unaligned;
|
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;
|
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 };
|
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_;
|
gme_type_t const gme_spc_type = &gme_spc_type_;
|
||||||
|
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
|
|
||||||
blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
|
blargg_err_t Spc_Emu::set_sample_rate_( long sample_rate )
|
||||||
{
|
{
|
||||||
RETURN_ERR( apu.init() );
|
RETURN_ERR( apu.init() );
|
||||||
apu.set_gain( (int) (gain() * Snes_Spc::gain_unit) );
|
enable_accuracy( false );
|
||||||
if ( sample_rate != native_sample_rate )
|
if ( sample_rate != native_sample_rate )
|
||||||
{
|
{
|
||||||
RETURN_ERR( resampler.buffer_size( native_sample_rate / 20 * 2 ) );
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spc_Emu::enable_accuracy_( bool b )
|
||||||
|
{
|
||||||
|
Music_Emu::enable_accuracy_( b );
|
||||||
|
filter.enable( b );
|
||||||
|
}
|
||||||
|
|
||||||
void Spc_Emu::mute_voices_( int m )
|
void Spc_Emu::mute_voices_( int m )
|
||||||
{
|
{
|
||||||
Music_Emu::mute_voices_( m );
|
Music_Emu::mute_voices_( m );
|
||||||
|
@ -277,17 +286,29 @@ blargg_err_t Spc_Emu::load_mem_( byte const* in, long size )
|
||||||
|
|
||||||
// Emulation
|
// 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 )
|
blargg_err_t Spc_Emu::start_track_( int track )
|
||||||
{
|
{
|
||||||
RETURN_ERR( Music_Emu::start_track_( track ) );
|
RETURN_ERR( Music_Emu::start_track_( track ) );
|
||||||
resampler.clear();
|
resampler.clear();
|
||||||
|
filter.clear();
|
||||||
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
RETURN_ERR( apu.load_spc( file_data, file_size ) );
|
||||||
|
filter.set_gain( (int) (gain() * SPC_Filter::gain_unit) );
|
||||||
apu.clear_echo();
|
apu.clear_echo();
|
||||||
return 0;
|
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 )
|
blargg_err_t Spc_Emu::skip_( long count )
|
||||||
{
|
{
|
||||||
if ( sample_rate() != native_sample_rate )
|
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?
|
// TODO: shouldn't skip be adjusted for the 64 samples read afterwards?
|
||||||
|
|
||||||
if ( count > 0 )
|
if ( count > 0 )
|
||||||
|
{
|
||||||
RETURN_ERR( apu.skip( count ) );
|
RETURN_ERR( apu.skip( count ) );
|
||||||
|
filter.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// eliminate pop due to resampler
|
// eliminate pop due to resampler
|
||||||
const int resampler_latency = 64;
|
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 )
|
blargg_err_t Spc_Emu::play_( long count, sample_t* out )
|
||||||
{
|
{
|
||||||
if ( sample_rate() == native_sample_rate )
|
if ( sample_rate() == native_sample_rate )
|
||||||
return apu.play( count, out );
|
return play_and_filter( count, out );
|
||||||
|
|
||||||
long remain = count;
|
long remain = count;
|
||||||
while ( remain > 0 )
|
while ( remain > 0 )
|
||||||
|
@ -319,7 +343,7 @@ blargg_err_t Spc_Emu::play_( long count, sample_t* out )
|
||||||
if ( remain > 0 )
|
if ( remain > 0 )
|
||||||
{
|
{
|
||||||
long n = resampler.max_write();
|
long n = resampler.max_write();
|
||||||
RETURN_ERR( apu.play( n, resampler.buffer() ) );
|
RETURN_ERR( play_and_filter( n, resampler.buffer() ) );
|
||||||
resampler.write( n );
|
resampler.write( n );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
// Super Nintendo SPC music file emulator
|
// Super Nintendo SPC music file emulator
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef SPC_EMU_H
|
#ifndef SPC_EMU_H
|
||||||
#define SPC_EMU_H
|
#define SPC_EMU_H
|
||||||
|
|
||||||
#include "Fir_Resampler.h"
|
#include "Fir_Resampler.h"
|
||||||
#include "Music_Emu.h"
|
#include "Music_Emu.h"
|
||||||
#include "Snes_Spc.h"
|
#include "Snes_Spc.h"
|
||||||
|
#include "Spc_Filter.h"
|
||||||
|
|
||||||
class Spc_Emu : public Music_Emu {
|
class Spc_Emu : public Music_Emu {
|
||||||
public:
|
public:
|
||||||
|
@ -65,11 +66,15 @@ protected:
|
||||||
blargg_err_t skip_( long );
|
blargg_err_t skip_( long );
|
||||||
void mute_voices_( int );
|
void mute_voices_( int );
|
||||||
void set_tempo_( double );
|
void set_tempo_( double );
|
||||||
|
void enable_accuracy_( bool );
|
||||||
private:
|
private:
|
||||||
byte const* file_data;
|
byte const* file_data;
|
||||||
long file_size;
|
long file_size;
|
||||||
Fir_Resampler<24> resampler;
|
Fir_Resampler<24> resampler;
|
||||||
|
SPC_Filter filter;
|
||||||
Snes_Spc apu;
|
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 ); }
|
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"
|
#include "Vgm_Emu.h"
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ Vgm_Emu::Vgm_Emu()
|
||||||
|
|
||||||
set_silence_lookahead( 1 ); // tracks should already be trimmed
|
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( make_equalizer( -14.0, 80 ) );
|
||||||
set_equalizer( eq );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vgm_Emu::~Vgm_Emu() { }
|
Vgm_Emu::~Vgm_Emu() { }
|
||||||
|
@ -218,8 +217,8 @@ void Vgm_Emu::set_tempo_( double t )
|
||||||
{
|
{
|
||||||
vgm_rate = (long) (44100 * t + 0.5);
|
vgm_rate = (long) (44100 * t + 0.5);
|
||||||
blip_time_factor = (long) floor( double (1L << blip_time_bits) / vgm_rate * psg_rate + 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 );
|
//debug_printf( "blip_time_factor: %ld\n", blip_time_factor );
|
||||||
//dprintf( "vgm_rate: %ld\n", vgm_rate );
|
//debug_printf( "vgm_rate: %ld\n", vgm_rate );
|
||||||
// TODO: remove? calculates vgm_rate more accurately (above differs at most by one Hz only)
|
// 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 );
|
//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 );
|
//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
|
// 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
|
#ifndef VGM_EMU_H
|
||||||
#define 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"
|
#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;
|
int pairs = min_pairs;
|
||||||
while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
|
while ( (pairs = to_fm_time( vgm_time )) < min_pairs )
|
||||||
vgm_time++;
|
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() )
|
if ( ym2612.enabled() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Low-level parts of Vgm_Emu
|
// Low-level parts of Vgm_Emu
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef VGM_EMU_IMPL_H
|
#ifndef VGM_EMU_IMPL_H
|
||||||
#define 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
|
// 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"
|
#include "Ym2413_Emu.h"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// YM2413 FM sound chip emulator interface
|
// YM2413 FM sound chip emulator interface
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef YM2413_EMU_H
|
#ifndef YM2413_EMU_H
|
||||||
#define 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
|
// Based on Gens 2.10 ym2612.c
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.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
|
/* 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
|
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
|
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 MUL; // parametre "multiple de frequence"
|
||||||
int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
|
int TL; // Total Level = volume lorsque l'enveloppe est au plus haut
|
||||||
int TLL; // Total Level ajusted
|
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_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 !
|
// sur les differents parametres de l'enveloppe comme l'attaque, le decay ... comme dans la realite !
|
||||||
int SEG; // Type enveloppe SSG
|
int SEG; // Type enveloppe SSG
|
||||||
int env_xor;
|
int env_xor;
|
||||||
|
@ -58,24 +58,24 @@ struct slot_t
|
||||||
const int *RR; // Release Rate (table pointeur) = Taux pour le rel'chement (RR[KSR])
|
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 Fcnt; // Frequency Count = compteur-frequence pour determiner l'amplitude actuelle (SIN[Finc >> 16])
|
||||||
int Finc; // frequency step = pas d'incrementation du compteur-frequence
|
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
|
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 ...
|
// 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
|
// en fonction de la valeur de cette variable, on va appeler une fonction permettant
|
||||||
// de mettre à jour l'enveloppe courante.
|
// 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 Ecnt; // Envelope counter = le compteur-enveloppe permet de savoir o・l'on se trouve dans l'enveloppe
|
||||||
int Einc; // Envelope step courant
|
int Einc; // Envelope step courant
|
||||||
int Ecmp; // Envelope counter limite pour la prochaine phase
|
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
|
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
|
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
|
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
|
int EincR; // Envelope step for Release = pas d'incrementation du compteur durant la phase de rel'chement
|
||||||
// cette valeur est egal à RR[KSR]
|
// cette valeur est egal ・RR[KSR]
|
||||||
int *OUTp; // pointeur of SLOT output = pointeur permettant de connecter la sortie de ce slot à l'entree
|
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
|
// d'un autre ou carrement ・la sortie de la voie
|
||||||
int INd; // input data of the slot = donnees en entree du slot
|
int INd; // input data of the slot = donnees en entree du slot
|
||||||
int ChgEnM; // Change envelop mask.
|
int ChgEnM; // Change envelop mask.
|
||||||
int AMS; // AMS depth level of this SLOT = degre de modulation de l'amplitude par le LFO
|
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 TimerBase; // TimerBase calculation
|
||||||
int Status; // YM2612 Status (timer overflow)
|
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 TimerAL;
|
||||||
int TimerAcnt; // timerA counter = valeur courante du Timer A
|
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 TimerBL;
|
||||||
int TimerBcnt; // timerB counter = valeur courante du Timer B
|
int TimerBcnt; // timerB counter = valeur courante du Timer B
|
||||||
int Mode; // Mode actuel des voie 3 et 6 (normal / special)
|
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 )
|
if ( YM2612.Mode & 3 )
|
||||||
run_timer( pair_count );
|
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++ )
|
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
|
int ksr = ch.KC [i2] >> sl.KSR_S; // keycode attenuation
|
||||||
sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
|
sl.Finc = (finc + sl.DT [ch.KC [i2]]) * sl.MUL;
|
||||||
if (sl.KSR != ksr) // si le KSR a change alors
|
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.KSR = ksr;
|
||||||
|
|
||||||
sl.EincA = sl.AR [ksr];
|
sl.EincA = sl.AR [ksr];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// YM2612 FM sound chip emulator interface
|
// YM2612 FM sound chip emulator interface
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
// Game_Music_Emu 0.6.0
|
||||||
#ifndef YM2612_EMU_H
|
#ifndef YM2612_EMU_H
|
||||||
#define YM2612_EMU_H
|
#define YM2612_EMU_H
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
#ifndef BLARGG_COMMON_H
|
#ifndef BLARGG_COMMON_H
|
||||||
#define 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)
|
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||||
#ifndef STATIC_CAST
|
#ifndef STATIC_CAST
|
||||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||||
|
@ -54,10 +61,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef BLARGG_DISABLE_NOTHROW
|
#ifndef BLARGG_DISABLE_NOTHROW
|
||||||
#if __cplusplus < 199711
|
// throw spec mandatory in ISO C++ if operator new can return NULL
|
||||||
#define BLARGG_THROWS( spec )
|
#if __cplusplus >= 199711 || __GNUC__ >= 3
|
||||||
#else
|
|
||||||
#define BLARGG_THROWS( spec ) throw spec
|
#define BLARGG_THROWS( spec ) throw spec
|
||||||
|
#else
|
||||||
|
#define BLARGG_THROWS( spec )
|
||||||
#endif
|
#endif
|
||||||
#define BLARGG_DISABLE_NOTHROW \
|
#define BLARGG_DISABLE_NOTHROW \
|
||||||
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
void* operator new ( size_t s ) BLARGG_THROWS(()) { return malloc( s ); }\
|
||||||
|
@ -68,6 +76,7 @@ public:
|
||||||
#define BLARGG_NEW new (std::nothrow)
|
#define BLARGG_NEW new (std::nothrow)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant)
|
||||||
#define BLARGG_4CHAR( a, b, c, d ) \
|
#define BLARGG_4CHAR( a, b, c, d ) \
|
||||||
((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
|
((a&0xFF)*0x1000000L + (b&0xFF)*0x10000L + (c&0xFF)*0x100L + (d&0xFF))
|
||||||
|
|
||||||
|
@ -110,18 +119,17 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
// blargg_long/blargg_ulong = at least 32 bits, int if it's big enough
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#if INT_MAX >= 0x7FFFFFFF
|
#if INT_MAX < 0x7FFFFFFF || LONG_MAX == 0x7FFFFFFF
|
||||||
typedef int blargg_long;
|
|
||||||
#else
|
|
||||||
typedef long blargg_long;
|
typedef long blargg_long;
|
||||||
|
#else
|
||||||
|
typedef int blargg_long;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if UINT_MAX >= 0xFFFFFFFF
|
#if UINT_MAX < 0xFFFFFFFF || ULONG_MAX == 0xFFFFFFFF
|
||||||
typedef unsigned blargg_ulong;
|
|
||||||
#else
|
|
||||||
typedef unsigned long blargg_ulong;
|
typedef unsigned long blargg_ulong;
|
||||||
|
#else
|
||||||
|
typedef unsigned blargg_ulong;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BOOST::int8_t etc.
|
// BOOST::int8_t etc.
|
||||||
|
@ -171,5 +179,18 @@ public:
|
||||||
};
|
};
|
||||||
#endif
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,9 +6,22 @@
|
||||||
// Uncomment to use zlib for transparent decompression of gzipped files
|
// Uncomment to use zlib for transparent decompression of gzipped files
|
||||||
//#define HAVE_ZLIB_H
|
//#define HAVE_ZLIB_H
|
||||||
|
|
||||||
// Uncomment to support only the listed game music types. See gme_type_list.cpp
|
// Uncomment and edit list to support only the listed game music types,
|
||||||
// for a list of all types.
|
// so that the others don't get linked in at all.
|
||||||
//#define GME_TYPE_LIST gme_nsf_type, gme_gbs_type
|
/*
|
||||||
|
#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
|
// Uncomment to enable platform-specific optimizations
|
||||||
//#define BLARGG_NONPORTABLE 1
|
//#define BLARGG_NONPORTABLE 1
|
||||||
|
@ -27,5 +40,4 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// CPU Byte Order Utilities
|
// CPU Byte Order Utilities
|
||||||
|
|
||||||
// Game_Music_Emu 0.5.2
|
|
||||||
#ifndef BLARGG_ENDIAN
|
#ifndef BLARGG_ENDIAN
|
||||||
#define BLARGG_ENDIAN
|
#define BLARGG_ENDIAN
|
||||||
|
|
||||||
#include "blargg_common.h"
|
#include "blargg_common.h"
|
||||||
|
|
||||||
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
// BLARGG_CPU_CISC: Defined if CPU has very few general-purpose registers (< 16)
|
||||||
#if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \
|
#if defined (__i386__) || defined (__x86_64__) || defined (_M_IX86) || defined (_M_X64)
|
||||||
defined (__x86_64__) || defined (__ia64__) || defined (__i386__)
|
|
||||||
#define BLARGG_CPU_X86 1
|
#define BLARGG_CPU_X86 1
|
||||||
#define BLARGG_CPU_CISC 1
|
#define BLARGG_CPU_CISC 1
|
||||||
#endif
|
#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_POWERPC 1
|
||||||
|
#define BLARGG_CPU_RISC 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||||
|
@ -36,10 +36,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (MSB_FIRST) || defined (__BIG_ENDIAN__) || defined (WORDS_BIGENDIAN) || \
|
#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)
|
(defined (BIG_ENDIAN) && BIG_ENDIAN+0 != 4321)
|
||||||
#define BLARGG_BIG_ENDIAN 1
|
#define BLARGG_BIG_ENDIAN 1
|
||||||
#else
|
#elif !defined (__mips__)
|
||||||
// No endian specified; assume little-endian, since it's most common
|
// No endian specified; assume little-endian, since it's most common
|
||||||
#define BLARGG_LITTLE_ENDIAN 1
|
#define BLARGG_LITTLE_ENDIAN 1
|
||||||
#endif
|
#endif
|
||||||
|
@ -64,45 +64,60 @@ inline void blargg_verify_byte_order()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned get_le16( void const* p ) {
|
inline unsigned get_le16( void const* p )
|
||||||
return ((unsigned char const*) p) [1] * 0x100u +
|
{
|
||||||
((unsigned char const*) p) [0];
|
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 +
|
inline unsigned get_be16( void const* p )
|
||||||
((unsigned char const*) p) [1];
|
{
|
||||||
|
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 +
|
inline blargg_ulong get_le32( void const* p )
|
||||||
((unsigned char const*) p) [2] * 0x00010000u +
|
{
|
||||||
((unsigned char const*) p) [1] * 0x00000100u +
|
return (blargg_ulong) ((unsigned char const*) p) [3] << 24 |
|
||||||
((unsigned char const*) p) [0];
|
(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 +
|
inline blargg_ulong get_be32( void const* p )
|
||||||
((unsigned char const*) p) [1] * 0x00010000u +
|
{
|
||||||
((unsigned char const*) p) [2] * 0x00000100u +
|
return (blargg_ulong) ((unsigned char const*) p) [0] << 24 |
|
||||||
((unsigned char const*) p) [3];
|
(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) [1] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [0] = (unsigned char) n;
|
((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) [0] = (unsigned char) (n >> 8);
|
||||||
((unsigned char*) p) [1] = (unsigned char) n;
|
((unsigned char*) p) [1] = (unsigned char) n;
|
||||||
}
|
}
|
||||||
inline void set_le32( void* p, blargg_ulong n ) {
|
|
||||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
inline void set_le32( void* p, blargg_ulong n )
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
{
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [0] = (unsigned char) 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);
|
inline void set_be32( void* p, blargg_ulong n )
|
||||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
{
|
||||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
|
||||||
((unsigned char*) p) [3] = (unsigned char) 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
|
#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 GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||||
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
#define SET_BE16( addr, data ) (void) (*(BOOST::uint16_t*) (addr) = (data))
|
||||||
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
#define SET_BE32( addr, data ) (void) (*(BOOST::uint32_t*) (addr) = (data))
|
||||||
#endif
|
|
||||||
|
#if BLARGG_CPU_POWERPC
|
||||||
#if BLARGG_CPU_POWERPC && defined (__MWERKS__)
|
// PowerPC has special byte-reversed instructions
|
||||||
// PowerPC has special byte-reversed instructions
|
#if defined (__MWERKS__)
|
||||||
// to do: assumes that PowerPC is running in big-endian mode
|
#define GET_LE16( addr ) (__lhbrx( addr, 0 ))
|
||||||
// to do: implement for other compilers which don't support these macros
|
#define GET_LE32( addr ) (__lwbrx( addr, 0 ))
|
||||||
#define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
|
#define SET_LE16( addr, in ) (__sthbrx( in, addr, 0 ))
|
||||||
#define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
|
#define SET_LE32( addr, in ) (__stwbrx( in, addr, 0 ))
|
||||||
#define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
|
#elif defined (__GNUC__)
|
||||||
#define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_LE16
|
#ifndef GET_LE16
|
||||||
#define GET_LE16( addr ) get_le16( addr )
|
#define GET_LE16( addr ) get_le16( addr )
|
||||||
#define GET_LE32( addr ) get_le32( addr )
|
|
||||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
#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 )
|
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GET_BE16
|
#ifndef GET_BE16
|
||||||
#define GET_BE16( addr ) get_be16( addr )
|
#define GET_BE16( addr ) get_be16( addr )
|
||||||
#define GET_BE32( addr ) get_be32( addr )
|
|
||||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
#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 )
|
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||||
#endif
|
#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
|
#ifndef BLARGG_SOURCE_H
|
||||||
#define 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
|
// Like printf() except output goes to debug log file. Might be defined to do
|
||||||
// nothing (not even evaluate its arguments).
|
// nothing (not even evaluate its arguments).
|
||||||
// void dprintf( const char* format, ... );
|
// void debug_printf( const char* format, ... );
|
||||||
inline void blargg_dprintf_( const char*, ... ) { }
|
static inline void blargg_dprintf_( const char*, ... ) { }
|
||||||
#undef dprintf
|
#undef debug_printf
|
||||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
#define debug_printf (1) ? (void) 0 : blargg_dprintf_
|
||||||
|
|
||||||
// If enabled, evaluate expr and if false, make debug log entry with source file
|
// 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
|
// 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 min
|
||||||
#undef max
|
#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
|
// using const references generates crappy code, and I am currenly only using these
|
||||||
// for built-in types, so they take arguments by value
|
// for built-in types, so they take arguments by value
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
inline int min( int x, int y )
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T min( T x, T y )
|
inline T min( T x, T y )
|
||||||
{
|
{
|
||||||
|
@ -60,17 +80,29 @@ inline T max( T x, T y )
|
||||||
return y;
|
return y;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// TODO: good idea? bad idea?
|
// TODO: good idea? bad idea?
|
||||||
#undef byte
|
#undef byte
|
||||||
#define byte byte_
|
#define byte byte_
|
||||||
typedef unsigned char 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
|
// deprecated
|
||||||
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
#define BLARGG_CHECK_ALLOC CHECK_ALLOC
|
||||||
#define BLARGG_RETURN_ERR RETURN_ERR
|
#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
|
#ifdef BLARGG_SOURCE_BEGIN
|
||||||
#include BLARGG_SOURCE_BEGIN
|
#include BLARGG_SOURCE_BEGIN
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,9 +10,9 @@ int Gbs_Emu::cpu_read( gb_addr_t addr )
|
||||||
result = apu.read_register( clock(), addr );
|
result = apu.read_register( clock(), addr );
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
|
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 )
|
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
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
||||||
ram [offset] = 0xFF;
|
ram [offset] = 0xFF;
|
||||||
|
|
||||||
//if ( addr == 0xFFFF )
|
//if ( addr == 0xFFFF )
|
||||||
// dprintf( "Wrote interrupt mask\n" );
|
// debug_printf( "Wrote interrupt mask\n" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
|
else if ( (addr ^ 0x2000) <= 0x2000 - 1 )
|
||||||
|
@ -48,7 +48,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
else if ( unsigned (addr - 0x8000) < 0x2000 || unsigned (addr - 0xE000) < 0x1F00 )
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ void Gbs_Emu::cpu_write( gb_addr_t addr, int data )
|
||||||
#define CPU_READ_FAST_( emu, addr, time, out ) \
|
#define CPU_READ_FAST_( emu, addr, time, out ) \
|
||||||
{\
|
{\
|
||||||
out = READ_PROG( addr );\
|
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 );\
|
out = emu->apu.read_register( emu->cpu_time - time * clocks_per_instr, addr );\
|
||||||
else\
|
else\
|
||||||
check( out == emu->cpu_read( addr ) );\
|
check( out == emu->cpu_read( addr ) );\
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
// Game_Music_Emu 0.5.2. http://www.slack.net/~ant/
|
// Game_Music_Emu 0.6.0. http://www.slack.net/~ant/
|
||||||
|
|
||||||
#define IN_GME 1
|
|
||||||
|
|
||||||
#include "Music_Emu.h"
|
#include "Music_Emu.h"
|
||||||
|
|
||||||
|
#include "gme_types.h"
|
||||||
#if !GME_DISABLE_STEREO_DEPTH
|
#if !GME_DISABLE_STEREO_DEPTH
|
||||||
#include "Effects_Buffer.h"
|
#include "Effects_Buffer.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,32 +23,51 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
#include "blargg_source.h"
|
#include "blargg_source.h"
|
||||||
|
|
||||||
#ifndef GME_TYPE_LIST
|
BLARGG_EXPORT gme_type_t const* 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()
|
|
||||||
{
|
{
|
||||||
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_;
|
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 ) )
|
switch ( get_be32( header ) )
|
||||||
{
|
{
|
||||||
|
@ -78,7 +96,7 @@ static void to_uppercase( const char* in, int len, char* out )
|
||||||
*out = 0; // extension too long
|
*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_, '.' );
|
char const* end = strrchr( extension_, '.' );
|
||||||
if ( end )
|
if ( end )
|
||||||
|
@ -93,7 +111,7 @@ gme_type_t GMEAPI gme_identify_extension( const char* extension_ )
|
||||||
return 0;
|
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 );
|
*type_out = gme_identify_extension( path );
|
||||||
// TODO: don't examine header if file has extension?
|
// 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;
|
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 );
|
require( (data || !size) && out );
|
||||||
*out = 0;
|
*out = 0;
|
||||||
|
@ -132,7 +150,7 @@ gme_err_t GMEAPI gme_open_data( void const* data, long size, Music_Emu** out, in
|
||||||
return err;
|
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 );
|
require( path && out );
|
||||||
*out = 0;
|
*out = 0;
|
||||||
|
@ -169,7 +187,7 @@ GMEEXPORT gme_err_t GMEAPI gme_open_file( const char* path, Music_Emu** out, int
|
||||||
return err;
|
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 )
|
if ( type )
|
||||||
{
|
{
|
||||||
|
@ -202,27 +220,27 @@ Music_Emu* GMEAPI gme_new_emu( gme_type_t type, int rate )
|
||||||
return 0;
|
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 );
|
Mem_File_Reader in( data, size );
|
||||||
return me->load( in );
|
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 );
|
Callback_Reader in( func, size, data );
|
||||||
return me->load( in );
|
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
|
struct gme_info_t_ : gme_info_t
|
||||||
{
|
{
|
||||||
|
@ -231,7 +249,7 @@ struct gme_info_t_ : gme_info_t
|
||||||
BLARGG_DISABLE_NOTHROW
|
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;
|
*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;
|
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);
|
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 !GME_DISABLE_STEREO_DEPTH
|
||||||
if ( me->effects_buffer )
|
if ( me->effects_buffer )
|
||||||
|
@ -310,24 +328,26 @@ void GMEAPI gme_set_stereo_depth( Music_Emu* me, double depth )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void* GMEAPI gme_user_data ( Music_Emu const* me ) { return me->user_data(); }
|
BLARGG_EXPORT void* 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 ); }
|
BLARGG_EXPORT void 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_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 ); }
|
BLARGG_EXPORT gme_err_t 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 ); }
|
BLARGG_EXPORT gme_err_t 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 ); }
|
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
||||||
void GMEAPI 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(); }
|
||||||
int GMEAPI gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
||||||
int GMEAPI 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 ); }
|
||||||
gme_err_t GMEAPI 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(); }
|
||||||
int GMEAPI 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 ); }
|
||||||
void GMEAPI 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 ); }
|
||||||
void GMEAPI 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 ); }
|
||||||
void GMEAPI 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 ); }
|
||||||
void GMEAPI 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();
|
Music_Emu::equalizer_t e = me->equalizer();
|
||||||
e.treble = eq->treble;
|
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 );
|
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.treble = me->equalizer().treble;
|
||||||
e.bass = me->equalizer().bass;
|
e.bass = me->equalizer().bass;
|
||||||
*out = e;
|
*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() );
|
assert( (unsigned) i < (unsigned) me->voice_count() );
|
||||||
return me->voice_names() [i];
|
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 emulator library C interface (also usable from C++) */
|
||||||
|
|
||||||
/* Game_Music_Emu 0.5.2 */
|
/* Game_Music_Emu 0.6.0 */
|
||||||
#ifndef GME_H
|
#ifndef GME_H
|
||||||
#define 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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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) */
|
/* Error string returned by library functions, or NULL if no error (success) */
|
||||||
typedef const char* gme_err_t;
|
typedef const char* gme_err_t;
|
||||||
|
|
||||||
|
@ -38,38 +20,35 @@ typedef struct Music_Emu Music_Emu;
|
||||||
/******** Basic operations ********/
|
/******** Basic operations ********/
|
||||||
|
|
||||||
/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
|
/* 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 */
|
/* 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 */
|
/* 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. */
|
/* 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 [] );
|
gme_err_t gme_play( Music_Emu*, int count, short out [] );
|
||||||
|
|
||||||
/* Skip n samples */
|
|
||||||
GMEDLL gme_err_t GMEAPI gme_skip( Music_Emu*, long n );
|
|
||||||
|
|
||||||
/* Finish using emulator and free memory */
|
/* Finish using emulator and free memory */
|
||||||
GMEDLL void GMEAPI gme_delete( Music_Emu* );
|
void gme_delete( Music_Emu* );
|
||||||
|
|
||||||
|
|
||||||
/******** Track position/length ********/
|
/******** Track position/length ********/
|
||||||
|
|
||||||
/* Set time to start fading track out. Once fade ends track_ended() returns true.
|
/* Set time to start fading track out. Once fade ends track_ended() returns true.
|
||||||
Fade time can be changed while track is playing. */
|
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 */
|
/* 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 */
|
/* 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. */
|
/* 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 ********/
|
/******** Informational ********/
|
||||||
|
@ -80,22 +59,22 @@ enum { gme_info_only = -1 };
|
||||||
|
|
||||||
/* Most recent warning string, or NULL if none. Clears current warning after returning.
|
/* 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. */
|
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) */
|
/* 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
|
/* Clear any loaded m3u playlist and any internal playlist that the music format
|
||||||
supports (NSFE for example). */
|
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.).
|
/* Gets information for a particular track (length, name, author, etc.).
|
||||||
Must be freed after use. */
|
Must be freed after use. */
|
||||||
typedef struct gme_info_t gme_info_t;
|
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 */
|
/* Frees track information */
|
||||||
GMEDLL void GMEAPI gme_free_info( gme_info_t* );
|
void gme_free_info( gme_info_t* );
|
||||||
|
|
||||||
struct 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
|
/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
|
||||||
GYM, SPC, and Sega Genesis VGM music */
|
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
|
/* Disable automatic end-of-track detection and skipping of silence at beginning
|
||||||
if ignore is true */
|
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.
|
/* 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. */
|
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 */
|
/* 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 */
|
/* 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 */
|
/* 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
|
/* 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. */
|
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) */
|
/* Frequency equalizer parameters (see gme.txt) */
|
||||||
|
/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */
|
||||||
typedef struct gme_equalizer_t
|
typedef struct gme_equalizer_t
|
||||||
{
|
{
|
||||||
double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
|
double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
|
||||||
|
@ -160,11 +140,13 @@ typedef struct gme_equalizer_t
|
||||||
} gme_equalizer_t;
|
} gme_equalizer_t;
|
||||||
|
|
||||||
/* Get current frequency equalizater parameters */
|
/* 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 */
|
/* 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 ********/
|
/******** Game music types ********/
|
||||||
|
@ -187,17 +169,17 @@ extern const gme_type_t
|
||||||
gme_vgz_type;
|
gme_vgz_type;
|
||||||
|
|
||||||
/* Type of this emulator */
|
/* 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
|
/* 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. */
|
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 */
|
/* 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 */
|
/* 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 ********/
|
/******** Advanced file loading ********/
|
||||||
|
@ -206,50 +188,50 @@ GMEDLL int GMEAPI gme_type_multitrack( gme_type_t );
|
||||||
extern const char* const gme_wrong_file_type;
|
extern const char* const gme_wrong_file_type;
|
||||||
|
|
||||||
/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data. */
|
/* 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
|
/* 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
|
string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
|
||||||
file header is not recognized. */
|
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. */
|
/* 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).
|
/* 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. */
|
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
|
/* 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. */
|
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 */
|
/* 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. */
|
/* 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
|
/* 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. */
|
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 );
|
typedef gme_err_t (*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 );
|
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) */
|
/* 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 ********/
|
/******** User data ********/
|
||||||
|
|
||||||
/* Set/get pointer to data you want to associate with this emulator.
|
/* Set/get pointer to data you want to associate with this emulator.
|
||||||
You can use this for whatever you want. */
|
You can use this for whatever you want. */
|
||||||
GMEDLL void GMEAPI gme_set_user_data( Music_Emu*, void* new_user_data );
|
void gme_set_user_data( Music_Emu*, void* new_user_data );
|
||||||
GMEDLL void* GMEAPI gme_user_data( Music_Emu const* );
|
void* gme_user_data( Music_Emu const* );
|
||||||
|
|
||||||
/* Register cleanup function to be called when deleting emulator, or NULL to
|
/* Register cleanup function to be called when deleting emulator, or NULL to
|
||||||
clear it. Passes user_data to cleanup function. */
|
clear it. Passes user_data to cleanup function. */
|
||||||
typedef void (GMEAPI *gme_user_cleanup_t)( void* user_data );
|
typedef void (*gme_user_cleanup_t)( void* user_data );
|
||||||
GMEDLL void GMEAPI gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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