Merge branch 'master' into opengl-new-patch-features-support
This commit is contained in:
commit
8a2f8a441b
|
@ -3,7 +3,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
working_directory: /root/SRB2
|
working_directory: /root/SRB2
|
||||||
docker:
|
docker:
|
||||||
- image: debian:jessie
|
- image: debian:stretch
|
||||||
environment:
|
environment:
|
||||||
CC: ccache gcc -m32
|
CC: ccache gcc -m32
|
||||||
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
PKG_CONFIG_LIBDIR: /usr/lib/i386-linux-gnu/pkgconfig
|
||||||
|
@ -36,14 +36,20 @@ jobs:
|
||||||
- v1-SRB2-APT
|
- v1-SRB2-APT
|
||||||
- run:
|
- run:
|
||||||
name: Install SDK
|
name: Install SDK
|
||||||
command: apt-get -qq -y install git build-essential nasm libpng12-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx
|
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v1-SRB2-APT
|
key: v1-SRB2-APT
|
||||||
paths:
|
paths:
|
||||||
- /var/cache/apt/archives
|
- /var/cache/apt/archives
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Clean build
|
name: Compile without network support and BLUA
|
||||||
|
command: make -C src LINUX=1 ERRORMODE=1 -k NONET=1 NO_LUA=1
|
||||||
|
- run:
|
||||||
|
name: wipe build
|
||||||
|
command: make -C src LINUX=1 cleandep
|
||||||
|
- run:
|
||||||
|
name: rebuild depend
|
||||||
command: make -C src LINUX=1 clean
|
command: make -C src LINUX=1 clean
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
|
|
28
.travis.yml
28
.travis.yml
|
@ -15,6 +15,7 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-4.4
|
- gcc-4.4
|
||||||
compiler: gcc-4.4
|
compiler: gcc-4.4
|
||||||
|
env: GCC44=1
|
||||||
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
|
#gcc-4.4 (Ubuntu/Linaro 4.4.7-8ubuntu1) 4.4.7
|
||||||
- os: linux
|
- os: linux
|
||||||
addons:
|
addons:
|
||||||
|
@ -27,6 +28,7 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-4.6
|
- gcc-4.6
|
||||||
compiler: gcc-4.6
|
compiler: gcc-4.6
|
||||||
|
env: GCC46=1
|
||||||
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
|
#gcc-4.6 (Ubuntu/Linaro 4.6.4-6ubuntu2) 4.6.4
|
||||||
- os: linux
|
- os: linux
|
||||||
addons:
|
addons:
|
||||||
|
@ -39,9 +41,11 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-4.7
|
- gcc-4.7
|
||||||
compiler: gcc-4.7
|
compiler: gcc-4.7
|
||||||
|
env: GCC47=1
|
||||||
#gcc-4.7
|
#gcc-4.7
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
env: GCC48=1
|
||||||
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
|
#gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
|
||||||
- os: linux
|
- os: linux
|
||||||
addons:
|
addons:
|
||||||
|
@ -56,6 +60,7 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-4.8
|
- gcc-4.8
|
||||||
compiler: gcc-4.8
|
compiler: gcc-4.8
|
||||||
|
env: GCC48=1
|
||||||
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
|
#gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
|
||||||
- os: linux
|
- os: linux
|
||||||
addons:
|
addons:
|
||||||
|
@ -70,7 +75,7 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-7
|
- gcc-7
|
||||||
compiler: gcc-7
|
compiler: gcc-7
|
||||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough"
|
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough" GCC72=1
|
||||||
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
|
#gcc-7 (Ubuntu 7.2.0-1ubuntu1~14.04) 7.2.0 20170802
|
||||||
- os: linux
|
- os: linux
|
||||||
addons:
|
addons:
|
||||||
|
@ -85,7 +90,7 @@ matrix:
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
- gcc-8
|
- gcc-8
|
||||||
compiler: gcc-8
|
compiler: gcc-8
|
||||||
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow"
|
env: WFLAGS="-Wno-tautological-compare -Wno-error=implicit-fallthrough -Wno-implicit-fallthrough -Wno-error=format-overflow" GCC81=1
|
||||||
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
|
#gcc-8 (Ubuntu 7.2.0-1ubuntu1~14.04) 8.1.0
|
||||||
- os: linux
|
- os: linux
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
@ -216,9 +221,11 @@ matrix:
|
||||||
# - os: osx
|
# - os: osx
|
||||||
# osx_image: xcode7.2
|
# osx_image: xcode7.2
|
||||||
# #Apple LLVM version 7.0.2 (clang-700.1.81)
|
# #Apple LLVM version 7.0.2 (clang-700.1.81)
|
||||||
|
# - os: osx
|
||||||
|
# osx_image: xcode7.3
|
||||||
|
# #Apple LLVM version 7.3.0 (clang-703.0.31)
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode7.3
|
#Default: macOS 10.13 and Xcode 9.4.1
|
||||||
#Apple LLVM version 7.3.0 (clang-703.0.31)
|
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- compiler: clang-3.5
|
- compiler: clang-3.5
|
||||||
- compiler: clang-3.6
|
- compiler: clang-3.6
|
||||||
|
@ -242,6 +249,16 @@ addons:
|
||||||
- libgl1-mesa-dev
|
- libgl1-mesa-dev
|
||||||
- libgme-dev
|
- libgme-dev
|
||||||
- p7zip-full
|
- p7zip-full
|
||||||
|
homebrew:
|
||||||
|
taps:
|
||||||
|
- mazmazz/srb2
|
||||||
|
packages:
|
||||||
|
- sdl2_mixer
|
||||||
|
- game-music-emu
|
||||||
|
- p7zip
|
||||||
|
- cmake
|
||||||
|
update: true
|
||||||
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- wget --verbose --server-response -c http://rosenthalcastle.org/srb2/SRB2-v2115-assets-2.7z -O $HOME/srb2_cache/SRB2-v2115-assets-2.7z
|
- wget --verbose --server-response -c http://rosenthalcastle.org/srb2/SRB2-v2115-assets-2.7z -O $HOME/srb2_cache/SRB2-v2115-assets-2.7z
|
||||||
|
@ -253,9 +270,6 @@ before_script:
|
||||||
- cmake .. -DCMAKE_BUILD_TYPE=Release
|
- cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2 sdl2_mixer game-music-emu p7zip; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cmake||true; fi
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.6.dmg; hdiutil attach SDL2-2.0.6.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
|
||||||
- mkdir -p $HOME/srb2_cache
|
- mkdir -p $HOME/srb2_cache
|
||||||
|
|
|
@ -54,13 +54,19 @@ macro(copy_files_to_build_dir target dlllist_var)
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# 64-bit check
|
# bitness check
|
||||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
set(SRB2_SYSTEM_BITS 0)
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
message(STATUS "Target is 64-bit")
|
message(STATUS "Target is 64-bit")
|
||||||
set(SRB2_SYSTEM_BITS 64)
|
set(SRB2_SYSTEM_BITS 64)
|
||||||
else()
|
endif()
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
message(STATUS "Target is 32-bit")
|
||||||
set(SRB2_SYSTEM_BITS 32)
|
set(SRB2_SYSTEM_BITS 32)
|
||||||
endif()
|
endif()
|
||||||
|
if(${SRB2_SYSTEM_BITS} EQUAL 0)
|
||||||
|
message(STATUS "Target bitness is unknown")
|
||||||
|
endif()
|
||||||
|
|
||||||
# OS macros
|
# OS macros
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@ project(libgme)
|
||||||
include (CheckCXXCompilerFlag)
|
include (CheckCXXCompilerFlag)
|
||||||
|
|
||||||
# When version is changed, also change the one in gme/gme.h to match
|
# When version is changed, also change the one in gme/gme.h to match
|
||||||
set(GME_VERSION 0.6.0 CACHE INTERNAL "libgme Version")
|
set(GME_VERSION 0.6.2 CACHE INTERNAL "libgme Version")
|
||||||
|
|
||||||
# 2.6+ always assumes FATAL_ERROR, but 2.4 and below don't.
|
# 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
|
# Of course, 2.4 might work, in which case you're welcome to drop
|
||||||
|
@ -57,6 +57,8 @@ if (USE_GME_NSFE AND NOT USE_GME_NSF)
|
||||||
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
SET(USE_GME_NSF 1 CACHE BOOL "Enable NES NSF music emulation" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(BUILD_SHARED_LIBS "Build shared library (set to OFF for static library)" ON)
|
||||||
|
|
||||||
# Check for GCC "visibility" support.
|
# Check for GCC "visibility" support.
|
||||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
|
check_cxx_compiler_flag (-fvisibility=hidden __LIBGME_TEST_VISIBILITY)
|
||||||
|
@ -79,10 +81,10 @@ if (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif() # test visibility
|
endif() # test visibility
|
||||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
|
|
||||||
# Cache this result
|
# Cache this result
|
||||||
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
|
set( LIBGME_HAVE_GCC_VISIBILITY ${ENABLE_VISIBILITY} CACHE BOOL "GCC support for hidden visibility")
|
||||||
|
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|
||||||
# Shared library defined here
|
# Shared library defined here
|
||||||
add_subdirectory(gme)
|
add_subdirectory(gme)
|
||||||
|
|
|
@ -1,262 +1,5 @@
|
||||||
Game_Music_Emu Change Log
|
Game_Music_Emu Change Log
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Game_Music_Emu 0.6.0
|
Please see the git version history (e.g. git shortlog tags/0.6.0..tags/0.6.1)
|
||||||
--------------------
|
for the accurate change log.
|
||||||
|
|
||||||
- Note: A 0.5.6 release was referenced but never tagged or packaged.
|
|
||||||
|
|
||||||
- SPC improvements:
|
|
||||||
- Switched to newer snes_spc 0.9.0 for SPC emulation. Uses fast DSP.
|
|
||||||
- Fixed Spc_Emu::gain().
|
|
||||||
- Fixed support for files <0x10200 bytes.
|
|
||||||
|
|
||||||
- Other bugfixes:
|
|
||||||
- Fixed a couple of GBS bugs, one involving access of memory after
|
|
||||||
realloc.
|
|
||||||
- Blip_Buffer works on systems where 'double' is a single-precision
|
|
||||||
floating-point type.
|
|
||||||
- Fix uninitialized buffer size in dual_resampler.
|
|
||||||
- Compilation warnings squashed out as of clang 3.3-pre and gcc 4.7.2.
|
|
||||||
|
|
||||||
- API changes/additions:
|
|
||||||
- Removed documentation of C++ interface, as the C interface in gme.h is
|
|
||||||
the only supported one.
|
|
||||||
- Added gme_enable_accuracy() for enabling more accurate sound emulation
|
|
||||||
options (currently affects SPC only).
|
|
||||||
|
|
||||||
- Build system improvements:
|
|
||||||
- Add pkg_config support.
|
|
||||||
- Fix build on case-insensitive systems.
|
|
||||||
- Allow for install on Cygwin.
|
|
||||||
- Fix install on multilib systems, such as many 64-bit distros (CMake must
|
|
||||||
be able to figure out your system's libsuffix, if any).
|
|
||||||
- C++ implementation symbols are not leaked into the resultant library
|
|
||||||
file (requires symbol visibility support).
|
|
||||||
|
|
||||||
- Sample player improvements:
|
|
||||||
- Can toggle fast/accurate emulation (with the 'A' key).
|
|
||||||
|
|
||||||
Game_Music_Emu 0.5.5
|
|
||||||
--------------------
|
|
||||||
- CMake build support has been added. You can build Game_Music_Emu as
|
|
||||||
a shared library and install it so that you do not have to include your
|
|
||||||
own copy if you know libgme will be present on your target system.
|
|
||||||
Requires CMake 2.6 or higher.
|
|
||||||
|
|
||||||
|
|
||||||
Game_Music_Emu 0.5.2
|
|
||||||
--------------------
|
|
||||||
- *TONS* of changes and improvements. You should re-read the new header
|
|
||||||
files and documentation as the changes will allow you to simplify your
|
|
||||||
code a lot (it might even be simpler to just rewrite it). Existing code
|
|
||||||
should continue to work without changes in most cases (see Deprecated
|
|
||||||
features in gme.txt).
|
|
||||||
|
|
||||||
- New file formats: AY, HES, KSS, SAP, NSFE
|
|
||||||
|
|
||||||
- All-new comprehensive C interface (also usable from C++). Simplifies
|
|
||||||
many things, especially file loading, and brings everything together in
|
|
||||||
one header file (gme.h).
|
|
||||||
|
|
||||||
- Information tags and track names and times can be accessed for all
|
|
||||||
game music formats
|
|
||||||
|
|
||||||
- New features supported by all emulators: end of track fading,
|
|
||||||
automatic silence detection, adjustable song tempo, seek to new time in
|
|
||||||
track
|
|
||||||
|
|
||||||
- Updated mini player example to support track names and times, echo,
|
|
||||||
tempo, and channel muting, and added visual waveform display
|
|
||||||
|
|
||||||
- Improved configuration to use blargg_config.h, which you can modify
|
|
||||||
and keep when you update to a newer libary version. Includes flag for
|
|
||||||
library to automatically handle gzipped files using zlib (so you don't
|
|
||||||
need to use Gzip_File_Reader anymore).
|
|
||||||
|
|
||||||
- GBS: Fixed wave channel to not reset waveform when APU is powered off
|
|
||||||
(affected Garfield). Also improved invalid bank selection (affected Game
|
|
||||||
& Watch and others).
|
|
||||||
|
|
||||||
- VGM: Added support for alternate noise shifter register
|
|
||||||
configurations, used by other systems like the BBC Micro.
|
|
||||||
|
|
||||||
- SPC: Removed IPL ROM dump from emulator, as none of the SPC files I
|
|
||||||
scanned needed it, and an SPC file can include a copy if necessary. Also
|
|
||||||
re-enabled supposed clamping in gaussian interpolation between the third
|
|
||||||
and fourth lookups, though I don't know whether it matters
|
|
||||||
|
|
||||||
- Added Music_Emu::load_mem() to use music data already in memory
|
|
||||||
(without copying it)
|
|
||||||
|
|
||||||
- Added Music_Emu::warning(), which reports minor problems when loading
|
|
||||||
and playing a music file
|
|
||||||
|
|
||||||
- Added Music_Emu::set_gain() for uniform adjustment of gain. Can only
|
|
||||||
be set during initialization, so not useful as a general volume control.
|
|
||||||
|
|
||||||
- Added custom operator new to ensure that no exceptions are thrown in
|
|
||||||
the library (I'd use std::nothrow if it were part of pre-ISO (ARM) C++)
|
|
||||||
|
|
||||||
- Added BLIP_BUFFER_FAST flag to blargg_config.h to use a lower quality
|
|
||||||
bandlimited synthesis in "classic" emulators, which might help
|
|
||||||
performance on ancient processors (measure first!). Don't use this
|
|
||||||
unless absolutely necessary, as quality suffers.
|
|
||||||
|
|
||||||
- Improved performance a bit for x86 platforms
|
|
||||||
|
|
||||||
- Text files now in DOS newline format so they will open in Notepad
|
|
||||||
properly
|
|
||||||
|
|
||||||
- Removed requirement that file header structures not have any padding
|
|
||||||
added to the end
|
|
||||||
|
|
||||||
- Fixed common bug in all CPU emulators where negative program counter
|
|
||||||
could crash emulator (occurred during a negative branch from the
|
|
||||||
beginning of memory). Also fixed related bug in Z80 emulator for
|
|
||||||
IX/IY+displacement mode.
|
|
||||||
|
|
||||||
- Eliminated all warnings when compiling on gcc 4.0. The following
|
|
||||||
generates no diagnostics:
|
|
||||||
|
|
||||||
gcc -S gme/*.cpp -o /dev/null -ansi -fno-gnu-keywords
|
|
||||||
-fno-nonansi-builtins -pedantic -W -Wabi -Wall -Wcast-align
|
|
||||||
-Wcast-qual -Wchar-subscripts -Wdisabled-optimization -Werror
|
|
||||||
-Winline -Wlong-long -Wmultichar -Winvalid-offsetof
|
|
||||||
-Wnon-virtual-dtor -Woverloaded-virtual -Wparentheses
|
|
||||||
-Wpointer-arith -Wredundant-decls -Wreorder -Wsign-compare
|
|
||||||
-Wsign-promo -Wunknown-pragmas -Wwrite-strings
|
|
||||||
|
|
||||||
|
|
||||||
Game_Music_Emu 0.3.0
|
|
||||||
--------------------
|
|
||||||
- Added more demos, including music player using the SDL multimedia
|
|
||||||
library for sound, and improved documentation
|
|
||||||
|
|
||||||
- All: Improved interface to emulators to allow simpler setup and
|
|
||||||
loading. Instead of various init() functions, all now support
|
|
||||||
set_sample_rate( long rate ) and load( const char* file_path ).
|
|
||||||
|
|
||||||
- All: Removed error return from start_track() and play(), and added
|
|
||||||
error_count() to get the total number of emulation errors since the
|
|
||||||
track was last started. See demos for examples of new usage.
|
|
||||||
|
|
||||||
- All: Fixed mute_voices() muting to be preserved after loading files
|
|
||||||
and starting tracks, instead of being cleared as it was whenever a track
|
|
||||||
was started
|
|
||||||
|
|
||||||
- VGM: Rewrote Vgm_Emu to support Sega Genesis/Mega Drive FM sound at
|
|
||||||
any sample rate with optional FM oversampling, support for alternate
|
|
||||||
YM2612 sound cores, and support for optional YM2413
|
|
||||||
|
|
||||||
- VGM: Added tempo control, useful for slowing 60Hz NTSC Sega Genesis
|
|
||||||
music to 50Hz PAL
|
|
||||||
|
|
||||||
- VGM: Removed Vgm_Emu::track_data(), since I realized that this
|
|
||||||
information is already present in the VGM header (oops!)
|
|
||||||
|
|
||||||
- GYM: Changed Gym_Emu::track_length() operation (see Gym_Emu.h)
|
|
||||||
|
|
||||||
- NSF: Added support for Sunsoft FME-7 sound chip used by Gimmick
|
|
||||||
soundtrack
|
|
||||||
|
|
||||||
- NSF: Fixed Namco 106 problems with Final Lap and others
|
|
||||||
|
|
||||||
- Moved library sources to gme/ directory to reduce clutter, and merged
|
|
||||||
boost/ functionality into blargg_common.h
|
|
||||||
|
|
||||||
- Added Gzip_File_Reader for transparently using gzipped files
|
|
||||||
|
|
||||||
|
|
||||||
Game_Music_Emu 0.2.4
|
|
||||||
--------------------
|
|
||||||
- Created a discussion forum for problems and feedback:
|
|
||||||
http://groups-beta.google.com/group/blargg-sound-libs
|
|
||||||
|
|
||||||
- Changed error return value of Blip_Buffer::sample_rate() (also for
|
|
||||||
Stereo_Buffer, Effects_Buffer, etc.) to blargg_err_t (defined in
|
|
||||||
blargg_common.h), to make error reporting consistent with other
|
|
||||||
functions. This means the "no error" return value is the opposite of
|
|
||||||
what it was before, which will break current code which checks the error
|
|
||||||
return value:
|
|
||||||
|
|
||||||
// current code (broken)
|
|
||||||
if ( !buf.sample_rate( samples_per_sec ) )
|
|
||||||
out_of_memory();
|
|
||||||
|
|
||||||
// quick-and-dirty fix (just remove the ! operation)
|
|
||||||
if ( buf.sample_rate( samples_per_sec ) )
|
|
||||||
out_of_memory();
|
|
||||||
|
|
||||||
// proper fix
|
|
||||||
blargg_err_t error = buf.sample_rate( samples_per_sec );
|
|
||||||
if ( error )
|
|
||||||
report_error( error );
|
|
||||||
|
|
||||||
- Implemented workaround for MSVC++ 6 compiler limitations, allowing it
|
|
||||||
to work on that compiler again
|
|
||||||
|
|
||||||
- Added sample clamping to avoid wrap-around at high volumes, allowing
|
|
||||||
higher volume with little distortion
|
|
||||||
|
|
||||||
- Added to-do list and design notes
|
|
||||||
|
|
||||||
- Added Music_Emu::skip( long sample_count ) to skip ahead in current
|
|
||||||
track
|
|
||||||
|
|
||||||
- Added Gym_Emu::track_length() and Vgm_Emu::track_length() for
|
|
||||||
determining the length of non-looped GYM and VGM files
|
|
||||||
|
|
||||||
- Partially implemented DMC non-linearity when its value is directly set
|
|
||||||
using $4011, which reduces previously over-emphasized "popping" of
|
|
||||||
percussion on some games (TMNT II in particular)
|
|
||||||
|
|
||||||
- Fixed Fir_Resampler, used for SPC and GYM playback (was incorrectly
|
|
||||||
using abs() instead of fabs()...argh)
|
|
||||||
|
|
||||||
- Fixed SPC emulation bugs: eliminated clicks in Plok! soundtrack and
|
|
||||||
now stops sample slightly earlier than the end, as the SNES does. Fixed
|
|
||||||
a totally broken CPU addressing mode.
|
|
||||||
|
|
||||||
- Fixed Konami VRC6 saw wave (was very broken before). Now VRC6 music
|
|
||||||
sounds decent
|
|
||||||
|
|
||||||
- Fixed a minor GBS emulation bug
|
|
||||||
|
|
||||||
- Fixed GYM loop point bug when track was restarted before loop point
|
|
||||||
had been reached
|
|
||||||
|
|
||||||
- Made default GBS frequency equalization less muffled
|
|
||||||
|
|
||||||
- Added pseudo-surround effect removal for SPC files
|
|
||||||
|
|
||||||
- Added Music_Emu::voice_names() which returns names for each voice.
|
|
||||||
|
|
||||||
- Added BLARGG_SOURCE_BEGIN which allows custom compiler options to be
|
|
||||||
easily set for library sources
|
|
||||||
|
|
||||||
- Changed assignment of expansion sound chips in Nsf_Emu to be spread
|
|
||||||
more evenly when using Effects_Buffer
|
|
||||||
|
|
||||||
- Changed 'size_t' values in Blip_Buffer interface to 'long'
|
|
||||||
|
|
||||||
- Changed demo to generate a WAVE sound file rather than an AIFF file
|
|
||||||
|
|
||||||
|
|
||||||
Game_Music_Emu 0.2.0
|
|
||||||
--------------------
|
|
||||||
- Redid framework and rewrote/cleaned up emulators
|
|
||||||
|
|
||||||
- Changed licensing to GNU Lesser General Public License (LGPL)
|
|
||||||
|
|
||||||
- Added Sega Genesis GYM and Super Nintendo SPC emulators
|
|
||||||
|
|
||||||
- Added Namco-106 and Konami VRC6 sound chip support to NSF emulator
|
|
||||||
|
|
||||||
- Eliminated use of static mutable data in emulators, allowing
|
|
||||||
multi-instance safety
|
|
||||||
|
|
||||||
|
|
||||||
Game_Music_Emu 0.1.0
|
|
||||||
--------------------
|
|
||||||
- First release
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/* C example that opens a game music file and records 10 seconds to "out.wav" */
|
/* C example that opens a game music file and records 10 seconds to "out.wav" */
|
||||||
|
|
||||||
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
|
|
||||||
|
|
||||||
#include "gme/gme.h"
|
#include "gme/gme.h"
|
||||||
|
|
||||||
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
|
#include "Wave_Writer.h" /* wave_ functions for writing sound file */
|
||||||
|
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
|
||||||
|
|
||||||
void handle_error( const char* str );
|
void handle_error( const char* str );
|
||||||
|
|
||||||
int main()
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
const char *filename = "test.nsf"; /* Default file to open */
|
||||||
|
if ( argc >= 2 )
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
long sample_rate = 44100; /* number of samples per second */
|
long sample_rate = 44100; /* number of samples per second */
|
||||||
int track = 0; /* index of track to play (0 = first) */
|
/* index of track to play (0 = first) */
|
||||||
|
int track = argc >= 3 ? atoi(argv[2]) : 0;
|
||||||
|
|
||||||
/* Open music file in new emulator */
|
/* Open music file in new emulator */
|
||||||
Music_Emu* emu;
|
Music_Emu* emu;
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
// C++ example that opens a game music file and records 10 seconds to "out.wav"
|
// C++ example that opens a game music file and records 10 seconds to "out.wav"
|
||||||
|
|
||||||
static char filename [] = "test.nsf"; /* opens this file (can be any music type) */
|
|
||||||
|
|
||||||
#include "gme/Music_Emu.h"
|
#include "gme/Music_Emu.h"
|
||||||
|
|
||||||
#include "Wave_Writer.h"
|
#include "Wave_Writer.h"
|
||||||
|
@ -10,10 +8,15 @@ static char filename [] = "test.nsf"; /* opens this file (can be any music type)
|
||||||
|
|
||||||
void handle_error( const char* str );
|
void handle_error( const char* str );
|
||||||
|
|
||||||
int main()
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
const char *filename = "test.nsf"; /* Default file to open */
|
||||||
|
if ( argc >= 2 )
|
||||||
|
filename = argv[1];
|
||||||
|
|
||||||
long sample_rate = 44100; // number of samples per second
|
long sample_rate = 44100; // number of samples per second
|
||||||
int track = 0; // index of track to play (0 = first)
|
// index of track to play (0 = first)
|
||||||
|
int track = argc >= 3 ? atoi(argv[2]) : 0;
|
||||||
|
|
||||||
// Determine file type
|
// Determine file type
|
||||||
gme_type_t file_type;
|
gme_type_t file_type;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
Game_Music_Emu 0.6.0
|
Game_Music_Emu 0.6.2
|
||||||
--------------------
|
--------------------
|
||||||
Author : Shay Green <gblargg@gmail.com>
|
Author : Shay Green <gblargg@gmail.com>
|
||||||
Website: http://www.slack.net/~ant/libs/
|
Maintainer : Michael Pyne <mpyne@purinchu.net>
|
||||||
Forum : http://groups.google.com/group/blargg-sound-libs
|
Website : https://bitbucket.org/mpyne/game-music-emu/
|
||||||
Source : https://code.google.com/p/game-music-emu/
|
Source : https://bitbucket.org/mpyne/game-music-emu/
|
||||||
License: GNU Lesser General Public License (LGPL)
|
License : GNU Lesser General Public License (LGPL), see LICENSE.txt
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -143,7 +143,7 @@ add_definitions(-DBLARGG_BUILD_DLL)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
# Add library to be compiled.
|
# Add library to be compiled.
|
||||||
add_library(gme SHARED ${libgme_SRCS})
|
add_library(gme ${libgme_SRCS})
|
||||||
|
|
||||||
# The version is the release. The "soversion" is the API version. As long
|
# 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
|
# as only build fixes are performed (i.e. no backwards-incompatible changes
|
||||||
|
@ -159,4 +159,4 @@ install(TARGETS gme LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||||
ARCHIVE DESTINATION lib) # DLL platforms
|
ARCHIVE DESTINATION lib) # DLL platforms
|
||||||
|
|
||||||
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
|
install(FILES ${EXPORTED_HEADERS} DESTINATION include/gme)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib/pkgconfig)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgme.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig)
|
||||||
|
|
|
@ -22,8 +22,13 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
const char Data_Reader::eof_error [] = "Unexpected end of file";
|
const char Data_Reader::eof_error [] = "Unexpected end of file";
|
||||||
|
|
||||||
|
#define RETURN_VALIDITY_CHECK( cond ) \
|
||||||
|
do { if ( unlikely( !(cond) ) ) return "Corrupt file"; } while(0)
|
||||||
|
|
||||||
blargg_err_t Data_Reader::read( void* p, long s )
|
blargg_err_t Data_Reader::read( void* p, long s )
|
||||||
{
|
{
|
||||||
|
RETURN_VALIDITY_CHECK( s > 0 );
|
||||||
|
|
||||||
long result = read_avail( p, s );
|
long result = read_avail( p, s );
|
||||||
if ( result != s )
|
if ( result != s )
|
||||||
{
|
{
|
||||||
|
@ -38,6 +43,8 @@ blargg_err_t Data_Reader::read( void* p, long s )
|
||||||
|
|
||||||
blargg_err_t Data_Reader::skip( long count )
|
blargg_err_t Data_Reader::skip( long count )
|
||||||
{
|
{
|
||||||
|
RETURN_VALIDITY_CHECK( count >= 0 );
|
||||||
|
|
||||||
char buf [512];
|
char buf [512];
|
||||||
while ( count )
|
while ( count )
|
||||||
{
|
{
|
||||||
|
@ -54,7 +61,8 @@ long File_Reader::remain() const { return size() - tell(); }
|
||||||
|
|
||||||
blargg_err_t File_Reader::skip( long n )
|
blargg_err_t File_Reader::skip( long n )
|
||||||
{
|
{
|
||||||
assert( n >= 0 );
|
RETURN_VALIDITY_CHECK( n >= 0 );
|
||||||
|
|
||||||
if ( !n )
|
if ( !n )
|
||||||
return 0;
|
return 0;
|
||||||
return seek( tell() + n );
|
return seek( tell() + n );
|
||||||
|
@ -67,13 +75,14 @@ Subset_Reader::Subset_Reader( Data_Reader* dr, long size )
|
||||||
in = dr;
|
in = dr;
|
||||||
remain_ = dr->remain();
|
remain_ = dr->remain();
|
||||||
if ( remain_ > size )
|
if ( remain_ > size )
|
||||||
remain_ = size;
|
remain_ = max( 0l, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
long Subset_Reader::remain() const { return remain_; }
|
long Subset_Reader::remain() const { return remain_; }
|
||||||
|
|
||||||
long Subset_Reader::read_avail( void* p, long s )
|
long Subset_Reader::read_avail( void* p, long s )
|
||||||
{
|
{
|
||||||
|
s = max( 0l, s );
|
||||||
if ( s > remain_ )
|
if ( s > remain_ )
|
||||||
s = remain_;
|
s = remain_;
|
||||||
remain_ -= s;
|
remain_ -= s;
|
||||||
|
@ -85,7 +94,7 @@ long Subset_Reader::read_avail( void* p, long s )
|
||||||
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
|
Remaining_Reader::Remaining_Reader( void const* h, long size, Data_Reader* r )
|
||||||
{
|
{
|
||||||
header = (char const*) h;
|
header = (char const*) h;
|
||||||
header_end = header + size;
|
header_end = header + max( 0l, size );
|
||||||
in = r;
|
in = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +102,7 @@ long Remaining_Reader::remain() const { return header_end - header + in->remain(
|
||||||
|
|
||||||
long Remaining_Reader::read_first( void* out, long count )
|
long Remaining_Reader::read_first( void* out, long count )
|
||||||
{
|
{
|
||||||
|
count = max( 0l, count );
|
||||||
long first = header_end - header;
|
long first = header_end - header;
|
||||||
if ( first )
|
if ( first )
|
||||||
{
|
{
|
||||||
|
@ -107,8 +117,9 @@ long Remaining_Reader::read_first( void* out, long count )
|
||||||
|
|
||||||
long Remaining_Reader::read_avail( void* out, long count )
|
long Remaining_Reader::read_avail( void* out, long count )
|
||||||
{
|
{
|
||||||
|
count = max( 0l, count );
|
||||||
long first = read_first( out, count );
|
long first = read_first( out, count );
|
||||||
long second = count - first;
|
long second = max( 0l, count - first );
|
||||||
if ( second )
|
if ( second )
|
||||||
{
|
{
|
||||||
second = in->read_avail( (char*) out + first, second );
|
second = in->read_avail( (char*) out + first, second );
|
||||||
|
@ -120,8 +131,9 @@ long Remaining_Reader::read_avail( void* out, long count )
|
||||||
|
|
||||||
blargg_err_t Remaining_Reader::read( void* out, long count )
|
blargg_err_t Remaining_Reader::read( void* out, long count )
|
||||||
{
|
{
|
||||||
|
count = max( 0l, count );
|
||||||
long first = read_first( out, count );
|
long first = read_first( out, count );
|
||||||
long second = count - first;
|
long second = max( 0l, count - first );
|
||||||
if ( !second )
|
if ( !second )
|
||||||
return 0;
|
return 0;
|
||||||
return in->read( (char*) out + first, second );
|
return in->read( (char*) out + first, second );
|
||||||
|
@ -131,7 +143,7 @@ blargg_err_t Remaining_Reader::read( void* out, long count )
|
||||||
|
|
||||||
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
|
Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
|
||||||
begin( (const char*) p ),
|
begin( (const char*) p ),
|
||||||
size_( s )
|
size_( max( 0l, s ) )
|
||||||
{
|
{
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +153,7 @@ long Mem_File_Reader::size() const { return size_; }
|
||||||
long Mem_File_Reader::read_avail( void* p, long s )
|
long Mem_File_Reader::read_avail( void* p, long s )
|
||||||
{
|
{
|
||||||
long r = remain();
|
long r = remain();
|
||||||
|
s = max( 0l, s );
|
||||||
if ( s > r )
|
if ( s > r )
|
||||||
s = r;
|
s = r;
|
||||||
memcpy( p, begin + pos, s );
|
memcpy( p, begin + pos, s );
|
||||||
|
@ -152,6 +165,7 @@ long Mem_File_Reader::tell() const { return pos; }
|
||||||
|
|
||||||
blargg_err_t Mem_File_Reader::seek( long n )
|
blargg_err_t Mem_File_Reader::seek( long n )
|
||||||
{
|
{
|
||||||
|
RETURN_VALIDITY_CHECK( n >= 0 );
|
||||||
if ( n > size_ )
|
if ( n > size_ )
|
||||||
return eof_error;
|
return eof_error;
|
||||||
pos = n;
|
pos = n;
|
||||||
|
@ -164,7 +178,7 @@ Callback_Reader::Callback_Reader( callback_t c, long size, void* d ) :
|
||||||
callback( c ),
|
callback( c ),
|
||||||
data( d )
|
data( d )
|
||||||
{
|
{
|
||||||
remain_ = size;
|
remain_ = max( 0l, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
long Callback_Reader::remain() const { return remain_; }
|
long Callback_Reader::remain() const { return remain_; }
|
||||||
|
@ -173,13 +187,14 @@ long Callback_Reader::read_avail( void* out, long count )
|
||||||
{
|
{
|
||||||
if ( count > remain_ )
|
if ( count > remain_ )
|
||||||
count = remain_;
|
count = remain_;
|
||||||
if ( Callback_Reader::read( out, count ) )
|
if ( count < 0 || Callback_Reader::read( out, count ) )
|
||||||
count = -1;
|
count = -1;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Callback_Reader::read( void* out, long count )
|
blargg_err_t Callback_Reader::read( void* out, long count )
|
||||||
{
|
{
|
||||||
|
RETURN_VALIDITY_CHECK( count >= 0 );
|
||||||
if ( count > remain_ )
|
if ( count > remain_ )
|
||||||
return eof_error;
|
return eof_error;
|
||||||
return callback( data, out, count );
|
return callback( data, out, count );
|
||||||
|
@ -210,11 +225,12 @@ long Std_File_Reader::size() const
|
||||||
|
|
||||||
long Std_File_Reader::read_avail( void* p, long s )
|
long Std_File_Reader::read_avail( void* p, long s )
|
||||||
{
|
{
|
||||||
return fread( p, 1, s, (FILE*) file_ );
|
return fread( p, 1, max( 0l, s ), (FILE*) file_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Std_File_Reader::read( void* p, long s )
|
blargg_err_t Std_File_Reader::read( void* p, long s )
|
||||||
{
|
{
|
||||||
|
RETURN_VALIDITY_CHECK( s > 0 );
|
||||||
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
|
if ( s == (long) fread( p, 1, s, (FILE*) file_ ) )
|
||||||
return 0;
|
return 0;
|
||||||
if ( feof( (FILE*) file_ ) )
|
if ( feof( (FILE*) file_ ) )
|
||||||
|
|
|
@ -129,6 +129,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB_H
|
#ifdef HAVE_ZLIB_H
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
// Gzip compressed file reader
|
// Gzip compressed file reader
|
||||||
class Gzip_File_Reader : public File_Reader {
|
class Gzip_File_Reader : public File_Reader {
|
||||||
public:
|
public:
|
||||||
|
@ -143,7 +145,7 @@ public:
|
||||||
long tell() const;
|
long tell() const;
|
||||||
blargg_err_t seek( long );
|
blargg_err_t seek( long );
|
||||||
private:
|
private:
|
||||||
void* file_;
|
gzFile file_;
|
||||||
long size_;
|
long size_;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -178,6 +178,11 @@ blargg_long Music_Emu::msec_to_samples( blargg_long msec ) const
|
||||||
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
|
return (sec * sample_rate() + msec * sample_rate() / 1000) * stereo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long Music_Emu::tell_samples() const
|
||||||
|
{
|
||||||
|
return out_time;
|
||||||
|
}
|
||||||
|
|
||||||
long Music_Emu::tell() const
|
long Music_Emu::tell() const
|
||||||
{
|
{
|
||||||
blargg_long rate = sample_rate() * stereo;
|
blargg_long rate = sample_rate() * stereo;
|
||||||
|
@ -185,14 +190,18 @@ long Music_Emu::tell() const
|
||||||
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
|
return sec * 1000 + (out_time - sec * rate) * 1000 / rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
blargg_err_t Music_Emu::seek( long msec )
|
blargg_err_t Music_Emu::seek_samples( long time )
|
||||||
{
|
{
|
||||||
blargg_long time = msec_to_samples( msec );
|
|
||||||
if ( time < out_time )
|
if ( time < out_time )
|
||||||
RETURN_ERR( start_track( current_track_ ) );
|
RETURN_ERR( start_track( current_track_ ) );
|
||||||
return skip( time - out_time );
|
return skip( time - out_time );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blargg_err_t Music_Emu::seek( long msec )
|
||||||
|
{
|
||||||
|
return seek_samples( msec_to_samples( msec ) );
|
||||||
|
}
|
||||||
|
|
||||||
blargg_err_t Music_Emu::skip( long count )
|
blargg_err_t Music_Emu::skip( long count )
|
||||||
{
|
{
|
||||||
require( current_track() >= 0 ); // start_track() must have been called already
|
require( current_track() >= 0 ); // start_track() must have been called already
|
||||||
|
|
|
@ -41,9 +41,15 @@ public:
|
||||||
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
|
// Number of milliseconds (1000 msec = 1 second) played since beginning of track
|
||||||
long tell() const;
|
long tell() const;
|
||||||
|
|
||||||
|
// Number of samples generated since beginning of track
|
||||||
|
long tell_samples() 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.
|
||||||
blargg_err_t seek( long msec );
|
blargg_err_t seek( long msec );
|
||||||
|
|
||||||
|
// Equivalent to restarting track then skipping n samples
|
||||||
|
blargg_err_t seek_samples( long n );
|
||||||
|
|
||||||
// Skip n samples
|
// Skip n samples
|
||||||
blargg_err_t skip( long n );
|
blargg_err_t skip( long n );
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,9 @@ blargg_err_t Nsfe_Info::load( Data_Reader& in, Nsf_Emu* nsf_emu )
|
||||||
RETURN_ERR( in.read( block_header, sizeof block_header ) );
|
RETURN_ERR( in.read( block_header, sizeof block_header ) );
|
||||||
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] );
|
||||||
|
|
||||||
|
if ( size <= 0 )
|
||||||
|
return "Corrupt file";
|
||||||
|
|
||||||
//debug_printf( "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) );
|
||||||
|
|
||||||
|
|
|
@ -433,9 +433,7 @@ void Snes_Spc::cpu_write( int data, int addr, rel_time_t time )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Registers other than $F2 and $F4-$F7
|
// Registers other than $F2 and $F4-$F7
|
||||||
//if ( reg != 2 && reg != 4 && reg != 5 && reg != 6 && reg != 7 )
|
if ( reg != 2 && (reg < 4 || reg > 7) ) // 36%
|
||||||
// TODO: this is a bit on the fragile side
|
|
||||||
if ( ((~0x2F00 << (bits_in_int - 16)) << reg) < 0 ) // 36%
|
|
||||||
cpu_write_smp_reg( data, time, reg );
|
cpu_write_smp_reg( data, time, reg );
|
||||||
}
|
}
|
||||||
// High mem/address wrap-around
|
// High mem/address wrap-around
|
||||||
|
|
|
@ -76,8 +76,8 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
// TODO: remove non-wrapping versions?
|
// TODO: remove non-wrapping versions?
|
||||||
#define SPC_NO_SP_WRAPAROUND 0
|
#define SPC_NO_SP_WRAPAROUND 0
|
||||||
|
|
||||||
#define SET_SP( v ) (sp = ram + 0x101 + (v))
|
#define SET_SP( v ) (sp = ram + 0x101 + ((uint8_t) v))
|
||||||
#define GET_SP() (sp - 0x101 - ram)
|
#define GET_SP() (uint8_t (sp - 0x101 - ram))
|
||||||
|
|
||||||
#if SPC_NO_SP_WRAPAROUND
|
#if SPC_NO_SP_WRAPAROUND
|
||||||
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
|
#define PUSH16( v ) (sp -= 2, SET_LE16( sp, v ))
|
||||||
|
@ -485,7 +485,7 @@ loop:
|
||||||
|
|
||||||
case 0xAF: // MOV (X)+,A
|
case 0xAF: // MOV (X)+,A
|
||||||
WRITE_DP( 0, x, a + no_read_before_write );
|
WRITE_DP( 0, x, a + no_read_before_write );
|
||||||
x++;
|
x = (uint8_t) (x + 1);
|
||||||
goto loop;
|
goto loop;
|
||||||
|
|
||||||
// 5. 8-BIT LOGIC OPERATION COMMANDS
|
// 5. 8-BIT LOGIC OPERATION COMMANDS
|
||||||
|
@ -808,7 +808,7 @@ loop:
|
||||||
unsigned temp = y * a;
|
unsigned temp = y * a;
|
||||||
a = (uint8_t) temp;
|
a = (uint8_t) temp;
|
||||||
nz = ((temp >> 1) | temp) & 0x7F;
|
nz = ((temp >> 1) | temp) & 0x7F;
|
||||||
y = temp >> 8;
|
y = (uint8_t) (temp >> 8);
|
||||||
nz |= y;
|
nz |= y;
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -838,6 +838,7 @@ loop:
|
||||||
|
|
||||||
nz = (uint8_t) a;
|
nz = (uint8_t) a;
|
||||||
a = (uint8_t) a;
|
a = (uint8_t) a;
|
||||||
|
y = (uint8_t) y;
|
||||||
|
|
||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1005,7 @@ loop:
|
||||||
case 0x7F: // RET1
|
case 0x7F: // RET1
|
||||||
temp = *sp;
|
temp = *sp;
|
||||||
SET_PC( GET_LE16( sp + 1 ) );
|
SET_PC( GET_LE16( sp + 1 ) );
|
||||||
sp += 3;
|
SET_SP( GET_SP() + 3 );
|
||||||
goto set_psw;
|
goto set_psw;
|
||||||
case 0x8E: // POP PSW
|
case 0x8E: // POP PSW
|
||||||
POP( temp );
|
POP( temp );
|
||||||
|
|
|
@ -18,6 +18,19 @@ all other #include lines. */
|
||||||
#undef require
|
#undef require
|
||||||
#define require( expr ) assert( expr )
|
#define require( expr ) assert( expr )
|
||||||
|
|
||||||
|
// Use to provide hints to compiler for optimized code layout in situations where we
|
||||||
|
// can almost always expect a conditional to go one way or the other. Should only be
|
||||||
|
// used in situations where an unexpected branch is truly exceptional though!
|
||||||
|
#undef likely
|
||||||
|
#undef unlikely
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define likely( x ) __builtin_expect(x, 1)
|
||||||
|
#define unlikely( x ) __builtin_expect(x, 0)
|
||||||
|
#else
|
||||||
|
#define likely( x ) (x)
|
||||||
|
#define unlikely( x ) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
// 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 debug_printf( const char* format, ... );
|
// void debug_printf( const char* format, ... );
|
||||||
|
|
|
@ -337,7 +337,9 @@ BLARGG_EXPORT gme_err_t gme_play ( Music_Emu* me, int n, short* p )
|
||||||
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
BLARGG_EXPORT void gme_set_fade ( Music_Emu* me, int start_msec ) { me->set_fade( start_msec ); }
|
||||||
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
BLARGG_EXPORT int gme_track_ended ( Music_Emu const* me ) { return me->track_ended(); }
|
||||||
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
BLARGG_EXPORT int gme_tell ( Music_Emu const* me ) { return me->tell(); }
|
||||||
|
BLARGG_EXPORT int gme_tell_samples ( Music_Emu const* me ) { return me->tell_samples(); }
|
||||||
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
|
BLARGG_EXPORT gme_err_t gme_seek ( Music_Emu* me, int msec ) { return me->seek( msec ); }
|
||||||
|
BLARGG_EXPORT gme_err_t gme_seek_samples ( Music_Emu* me, int n ) { return me->seek_samples( n ); }
|
||||||
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
|
BLARGG_EXPORT int gme_voice_count ( Music_Emu const* me ) { return me->voice_count(); }
|
||||||
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
|
BLARGG_EXPORT void gme_ignore_silence ( Music_Emu* me, int disable ) { me->ignore_silence( disable != 0 ); }
|
||||||
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
|
BLARGG_EXPORT void gme_set_tempo ( Music_Emu* me, double t ) { me->set_tempo( t ); }
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Game music emulator library C interface (also usable from C++) */
|
/* Game music emulator library C interface (also usable from C++) */
|
||||||
|
|
||||||
/* Game_Music_Emu 0.6.0 */
|
/* Game_Music_Emu 0.6.1 */
|
||||||
#ifndef GME_H
|
#ifndef GME_H
|
||||||
#define GME_H
|
#define GME_H
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
#define GME_VERSION 0x000601 /* 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;
|
||||||
|
@ -47,9 +47,15 @@ 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 */
|
||||||
int gme_tell( Music_Emu const* );
|
int gme_tell( Music_Emu const* );
|
||||||
|
|
||||||
|
/* Number of samples generated since beginning of track */
|
||||||
|
int gme_tell_samples( 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. */
|
||||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||||
|
|
||||||
|
/* Equivalent to restarting track then skipping n samples */
|
||||||
|
gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||||
|
|
||||||
|
|
||||||
/******** Informational ********/
|
/******** Informational ********/
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# later are used by pkg-config.
|
# later are used by pkg-config.
|
||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
lib_suffix=
|
lib_suffix=@LIB_SUFFIX@
|
||||||
libdir=${exec_prefix}/lib${lib_suffix}
|
libdir=${exec_prefix}/lib${lib_suffix}
|
||||||
includedir=${prefix}/include
|
includedir=${prefix}/include
|
||||||
|
|
||||||
|
@ -13,3 +13,4 @@ URL: http://code.google.com/p/game-music-emu/
|
||||||
Version: @GME_VERSION@
|
Version: @GME_VERSION@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
Libs: -L${libdir} -lgme
|
Libs: -L${libdir} -lgme
|
||||||
|
Libs.private: -lstdc++
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Game music emulator library C interface (also usable from C++) */
|
/* Game music emulator library C interface (also usable from C++) */
|
||||||
|
|
||||||
/* Game_Music_Emu 0.6.0 */
|
/* Game_Music_Emu 0.6.1 */
|
||||||
#ifndef GME_H
|
#ifndef GME_H
|
||||||
#define GME_H
|
#define GME_H
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GME_VERSION 0x000600 /* 1 byte major, 1 byte minor, 1 byte patch-level */
|
#define GME_VERSION 0x000601 /* 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;
|
||||||
|
@ -47,9 +47,15 @@ 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 */
|
||||||
int gme_tell( Music_Emu const* );
|
int gme_tell( Music_Emu const* );
|
||||||
|
|
||||||
|
/* Number of samples generated since beginning of track */
|
||||||
|
int gme_tell_samples( 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. */
|
||||||
gme_err_t gme_seek( Music_Emu*, int msec );
|
gme_err_t gme_seek( Music_Emu*, int msec );
|
||||||
|
|
||||||
|
/* Equivalent to restarting track then skipping n samples */
|
||||||
|
gme_err_t gme_seek_samples( Music_Emu*, int n );
|
||||||
|
|
||||||
|
|
||||||
/******** Informational ********/
|
/******** Informational ********/
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Game_Music_Emu 0.6.0: Game Music Emulators
|
Game_Music_Emu 0.6.2: Game Music Emulators
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
Game_Music_Emu is a collection of video game music file emulators that
|
Game_Music_Emu is a collection of video game music file emulators that
|
||||||
support the following formats and systems:
|
support the following formats and systems:
|
||||||
|
@ -34,30 +34,45 @@ several architectures, Mac OS, MorphOS, Xbox, PlayStation Portable,
|
||||||
GP2X, and Nintendo DS.
|
GP2X, and Nintendo DS.
|
||||||
|
|
||||||
Author : Shay Green <gblargg@gmail.com>
|
Author : Shay Green <gblargg@gmail.com>
|
||||||
Website: http://www.slack.net/~ant/
|
Website: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
|
||||||
Forum : http://groups.google.com/group/blargg-sound-libs
|
|
||||||
License: GNU Lesser General Public License (LGPL)
|
License: GNU Lesser General Public License (LGPL)
|
||||||
|
|
||||||
|
Current Maintainer: Michael Pyne <mpyne@purinchu.net>
|
||||||
|
|
||||||
Getting Started
|
Getting Started
|
||||||
---------------
|
---------------
|
||||||
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
|
Build a program consisting of demo/basics.c, demo/Wave_Writer.cpp, and
|
||||||
all source files in gme/. If you have CMake 2.6 or later, execute
|
all source files in gme/.
|
||||||
|
|
||||||
run cmake
|
Or, if you have CMake 2.6 or later, execute at a command prompt (from the
|
||||||
cd demo
|
extracted source directory):
|
||||||
run make
|
|
||||||
|
|
||||||
Be sure "test.nsf" is in the same directory as the program. Running it
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ../ # <-- Pass any needed CMake flags here
|
||||||
|
make # To build the library
|
||||||
|
cd demo
|
||||||
|
make # To build the demo itself
|
||||||
|
|
||||||
|
Be sure "test.nsf" is in the same directory as the demo program. Running it
|
||||||
should generate the recording "out.wav".
|
should generate the recording "out.wav".
|
||||||
|
|
||||||
|
You can use "make install" to install the library. To choose where to install
|
||||||
|
the library to, use the CMake argument "-DCMAKE_INSTALL_PREFIX=/usr/local"
|
||||||
|
(and replace /usr/local with the base path you wish to use). Alternately, you
|
||||||
|
can specify the base path to install to when you run "make install" by passing
|
||||||
|
'DESTDIR=/usr/local' on the make install command line (again, replace
|
||||||
|
/usr/local as appropriate).
|
||||||
|
|
||||||
|
To build a static library instead of shared (the default), pass
|
||||||
|
-DBUILD_SHARED_LIBS=OFF to the cmake command when running cmake.
|
||||||
|
|
||||||
A slightly more extensive demo application is available in the player/
|
A slightly more extensive demo application is available in the player/
|
||||||
directory. It requires SDL to build.
|
directory. It requires SDL to build.
|
||||||
|
|
||||||
Read gme.txt for more information. Post to the discussion forum for
|
Read gme.txt for more information. Post to the discussion forum for
|
||||||
assistance.
|
assistance.
|
||||||
|
|
||||||
|
|
||||||
Files
|
Files
|
||||||
-----
|
-----
|
||||||
gme.txt General notes about the library
|
gme.txt General notes about the library
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -377,6 +377,12 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
|
||||||
set(SRB2_HAVE_PNG ON)
|
set(SRB2_HAVE_PNG ON)
|
||||||
add_definitions(-DHAVE_PNG)
|
add_definitions(-DHAVE_PNG)
|
||||||
add_definitions(-D_LARGEFILE64_SOURCE)
|
add_definitions(-D_LARGEFILE64_SOURCE)
|
||||||
|
set(SRB2_PNG_SOURCES apng.c)
|
||||||
|
set(SRB2_PNG_HEADERS apng.h)
|
||||||
|
prepend_sources(SRB2_PNG_SOURCES)
|
||||||
|
prepend_sources(SRB2_PNG_HEADERS)
|
||||||
|
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}
|
||||||
|
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
|
||||||
else()
|
else()
|
||||||
message(WARNING "You have specified that PNG is available but it was not found. SRB2 may not compile correctly.")
|
message(WARNING "You have specified that PNG is available but it was not found. SRB2 may not compile correctly.")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -281,6 +281,8 @@ endif
|
||||||
|
|
||||||
LIBS+=$(PNG_LDFLAGS)
|
LIBS+=$(PNG_LDFLAGS)
|
||||||
CFLAGS+=$(PNG_CFLAGS)
|
CFLAGS+=$(PNG_CFLAGS)
|
||||||
|
|
||||||
|
OBJS+=$(OBJDIR)/apng.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef HAVE_LIBGME
|
ifdef HAVE_LIBGME
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
# and other things
|
# and other things
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifdef GCC81
|
||||||
|
GCC80=1
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef GCC80
|
ifdef GCC80
|
||||||
GCC72=1
|
GCC72=1
|
||||||
endif
|
endif
|
||||||
|
@ -112,6 +116,7 @@ WFLAGS+=-Wfloat-equal
|
||||||
#WFLAGS+=-Wtraditional
|
#WFLAGS+=-Wtraditional
|
||||||
ifdef VCHELP
|
ifdef VCHELP
|
||||||
WFLAGS+=-Wdeclaration-after-statement
|
WFLAGS+=-Wdeclaration-after-statement
|
||||||
|
WFLAGS+=-Wno-error=declaration-after-statement
|
||||||
endif
|
endif
|
||||||
WFLAGS+=-Wundef
|
WFLAGS+=-Wundef
|
||||||
ifndef GCC295
|
ifndef GCC295
|
||||||
|
@ -181,12 +186,6 @@ ifdef GCC46
|
||||||
WFLAGS+=-Wno-suggest-attribute=noreturn
|
WFLAGS+=-Wno-suggest-attribute=noreturn
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef MINGW
|
|
||||||
ifdef GCC45
|
|
||||||
WFLAGS+=-Wunsuffixed-float-constants
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifdef NOLDWARNING
|
ifdef NOLDWARNING
|
||||||
LDFLAGS+=-Wl,--as-needed
|
LDFLAGS+=-Wl,--as-needed
|
||||||
endif
|
endif
|
||||||
|
@ -200,6 +199,9 @@ WFLAGS+=$(OLDWFLAGS)
|
||||||
ifdef GCC43
|
ifdef GCC43
|
||||||
#WFLAGS+=-Wno-error=clobbered
|
#WFLAGS+=-Wno-error=clobbered
|
||||||
endif
|
endif
|
||||||
|
ifdef GCC44
|
||||||
|
WFLAGS+=-Wno-error=array-bounds
|
||||||
|
endif
|
||||||
ifdef GCC46
|
ifdef GCC46
|
||||||
WFLAGS+=-Wno-error=suggest-attribute=noreturn
|
WFLAGS+=-Wno-error=suggest-attribute=noreturn
|
||||||
endif
|
endif
|
||||||
|
@ -220,6 +222,7 @@ ifdef GCC80
|
||||||
WFLAGS+=-Wno-format-overflow
|
WFLAGS+=-Wno-format-overflow
|
||||||
WFLAGS+=-Wno-stringop-truncation
|
WFLAGS+=-Wno-stringop-truncation
|
||||||
WFLAGS+=-Wno-stringop-overflow
|
WFLAGS+=-Wno-stringop-overflow
|
||||||
|
WFLAGS+=-Wno-error=multistatement-macros
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,37 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
(void)looppoint;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
(void)position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC PLAYBACK
|
// MUSIC PLAYBACK
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -140,3 +171,44 @@ void I_SetMusicVolume(INT32 volume)
|
||||||
{
|
{
|
||||||
(void)volume;
|
(void)volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)source_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
289
src/apng.c
Normal file
289
src/apng.c
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019, James R.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "apng.h"
|
||||||
|
|
||||||
|
#define APNG_INFO_acTL 0x20000U
|
||||||
|
|
||||||
|
#define APNG_WROTE_acTL 0x10000U
|
||||||
|
|
||||||
|
struct apng_info_def
|
||||||
|
{
|
||||||
|
png_uint_32 mode;
|
||||||
|
png_uint_32 valid;
|
||||||
|
|
||||||
|
png_uint_32 num_frames;
|
||||||
|
png_uint_32 num_plays;
|
||||||
|
|
||||||
|
long start_acTL;/* acTL is written here */
|
||||||
|
|
||||||
|
png_flush_ptr output_flush_fn;
|
||||||
|
apng_seek_ptr output_seek_fn;
|
||||||
|
apng_tell_ptr output_tell_fn;
|
||||||
|
|
||||||
|
apng_set_acTL_ptr set_acTL_fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PROTOS (FUCK COMPILER) */
|
||||||
|
void apng_seek (png_structp, apng_const_infop, size_t);
|
||||||
|
size_t apng_tell (png_structp, apng_const_infop);
|
||||||
|
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||||
|
void apng_flush (png_structp, apng_infop);
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
void apng_default_flush (png_structp);
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
void apng_default_seek (png_structp, size_t);
|
||||||
|
size_t apng_default_tell (png_structp);
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
void apng_write_IEND (png_structp);
|
||||||
|
void apng_write_acTL (png_structp, png_uint_32, png_uint_32);
|
||||||
|
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||||
|
png_uint_32 apng_set_acTL_dummy (png_structp, png_infop,
|
||||||
|
png_uint_32, png_uint_32);
|
||||||
|
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||||
|
|
||||||
|
apng_infop
|
||||||
|
apng_create_info_struct (png_structp pngp)
|
||||||
|
{
|
||||||
|
apng_infop ainfop;
|
||||||
|
(void)pngp;
|
||||||
|
if (( ainfop = calloc(sizeof (apng_info),1) ))
|
||||||
|
{
|
||||||
|
apng_set_write_fn(pngp, ainfop, 0, 0, 0, 0, 0);
|
||||||
|
apng_set_set_acTL_fn(pngp, ainfop, 0);
|
||||||
|
}
|
||||||
|
return ainfop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_destroy_info_struct (png_structp pngp, apng_infopp ainfopp)
|
||||||
|
{
|
||||||
|
(void)pngp;
|
||||||
|
if (!( pngp && ainfopp ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
free((*ainfopp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_seek (png_structp pngp, apng_const_infop ainfop, size_t l)
|
||||||
|
{
|
||||||
|
(*(ainfop->output_seek_fn))(pngp, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
apng_tell (png_structp pngp, apng_const_infop ainfop)
|
||||||
|
{
|
||||||
|
return (*(ainfop->output_tell_fn))(pngp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||||
|
void
|
||||||
|
apng_flush (png_structp pngp, apng_infop ainfop)
|
||||||
|
{
|
||||||
|
if (ainfop->output_flush_fn)
|
||||||
|
(*(ainfop->output_flush_fn))(pngp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
void
|
||||||
|
apng_default_flush (png_structp pngp)
|
||||||
|
{
|
||||||
|
if (!( pngp ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
fflush((png_FILE_p)png_get_io_ptr);
|
||||||
|
}
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
void
|
||||||
|
apng_default_seek (png_structp pngp, size_t l)
|
||||||
|
{
|
||||||
|
if (!( pngp ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fseek((png_FILE_p)png_get_io_ptr(pngp), (long)l, SEEK_SET) == -1)
|
||||||
|
png_error(pngp, "Seek Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
apng_default_tell (png_structp pngp)
|
||||||
|
{
|
||||||
|
long l;
|
||||||
|
|
||||||
|
if (!( pngp ))
|
||||||
|
{
|
||||||
|
png_error(pngp, "Call to apng_default_tell with NULL pngp failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (( l = ftell((png_FILE_p)png_get_io_ptr(pngp)) ) == -1)
|
||||||
|
png_error(pngp, "Tell Error");
|
||||||
|
|
||||||
|
return (size_t)l;
|
||||||
|
}
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_set_write_fn (png_structp pngp, apng_infop ainfop, png_voidp iop,
|
||||||
|
png_rw_ptr write_f, png_flush_ptr flush_f,
|
||||||
|
apng_seek_ptr seek_f, apng_tell_ptr tell_f)
|
||||||
|
{
|
||||||
|
if (!( pngp && ainfop ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
png_set_write_fn(pngp, iop, write_f, flush_f);
|
||||||
|
|
||||||
|
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
if (!flush_f)
|
||||||
|
ainfop->output_flush_fn = &apng_default_flush;
|
||||||
|
else
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
ainfop->output_flush_fn = flush_f;
|
||||||
|
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
if (!seek_f)
|
||||||
|
ainfop->output_seek_fn = &apng_default_seek;
|
||||||
|
else
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
ainfop->output_seek_fn = seek_f;
|
||||||
|
#ifdef PNG_STDIO_SUPPORTED
|
||||||
|
if (!seek_f)
|
||||||
|
ainfop->output_tell_fn = apng_default_tell;
|
||||||
|
else
|
||||||
|
#endif/* PNG_STDIO_SUPPORTED */
|
||||||
|
ainfop->output_tell_fn = tell_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_write_IEND (png_structp pngp)
|
||||||
|
{
|
||||||
|
png_byte chunkc[] = "IEND";
|
||||||
|
png_write_chunk(pngp, chunkc, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_write_acTL (png_structp pngp, png_uint_32 frames, png_uint_32 plays)
|
||||||
|
{
|
||||||
|
png_byte chunkc[] = "acTL";
|
||||||
|
png_byte buf[8];
|
||||||
|
png_save_uint_32(buf, frames);
|
||||||
|
png_save_uint_32(buf + 4, plays);
|
||||||
|
png_write_chunk(pngp, chunkc, buf, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
png_uint_32
|
||||||
|
apng_set_acTL (png_structp pngp, png_infop infop, apng_infop ainfop,
|
||||||
|
png_uint_32 frames, png_uint_32 plays)
|
||||||
|
{
|
||||||
|
(void)pngp;
|
||||||
|
(void)infop;
|
||||||
|
if (!( pngp && infop && ainfop ))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ainfop->num_frames = frames;
|
||||||
|
ainfop->num_plays = plays;
|
||||||
|
|
||||||
|
ainfop->valid |= APNG_INFO_acTL;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_write_info_before_PLTE (png_structp pngp, png_infop infop,
|
||||||
|
apng_infop ainfop)
|
||||||
|
{
|
||||||
|
if (!( pngp && infop && ainfop ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
png_write_info_before_PLTE(pngp, infop);
|
||||||
|
|
||||||
|
if (( ainfop->valid & APNG_INFO_acTL )&&!( ainfop->mode & APNG_WROTE_acTL ))
|
||||||
|
{
|
||||||
|
ainfop->start_acTL = apng_tell(pngp, ainfop);
|
||||||
|
|
||||||
|
apng_write_acTL(pngp, 0, 0);
|
||||||
|
/* modified for runtime dynamic linking */
|
||||||
|
(*(ainfop->set_acTL_fn))(pngp, infop, PNG_UINT_31_MAX, 0);
|
||||||
|
|
||||||
|
ainfop->mode |= APNG_WROTE_acTL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_write_info (png_structp pngp, png_infop infop,
|
||||||
|
apng_infop ainfop)
|
||||||
|
{
|
||||||
|
apng_write_info_before_PLTE(pngp, infop, ainfop);
|
||||||
|
png_write_info(pngp, infop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
apng_write_end (png_structp pngp, png_infop infop, apng_infop ainfop)
|
||||||
|
{
|
||||||
|
(void)infop;
|
||||||
|
apng_write_IEND(pngp);
|
||||||
|
apng_seek(pngp, ainfop, ainfop->start_acTL);
|
||||||
|
apng_write_acTL(pngp, ainfop->num_frames, ainfop->num_plays);
|
||||||
|
|
||||||
|
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
||||||
|
#ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
|
||||||
|
apng_flush(pngp, infop);
|
||||||
|
#endif/* PNG_WRITE_FLUSH_SUPPORTED */
|
||||||
|
#endif/* PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||||
|
png_uint_32
|
||||||
|
apng_set_acTL_dummy (png_structp pngp, png_infop infop,
|
||||||
|
png_uint_32 frames, png_uint_32 plays)
|
||||||
|
{
|
||||||
|
(void)pngp;
|
||||||
|
(void)infop;
|
||||||
|
(void)frames;
|
||||||
|
(void)plays;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||||
|
|
||||||
|
/* Dynamic runtime linking capable! (Hopefully.) */
|
||||||
|
void
|
||||||
|
apng_set_set_acTL_fn (png_structp pngp, apng_infop ainfop,
|
||||||
|
apng_set_acTL_ptr set_acTL_f)
|
||||||
|
{
|
||||||
|
(void)pngp;
|
||||||
|
if (!ainfop->set_acTL_fn)
|
||||||
|
#ifndef PNG_WRITE_APNG_SUPPORTED
|
||||||
|
ainfop->set_acTL_fn = &apng_set_acTL_dummy;
|
||||||
|
#else
|
||||||
|
ainfop->set_acTL_fn = &png_set_acTL;
|
||||||
|
#endif/* PNG_WRITE_APNG_SUPPORTED */
|
||||||
|
else
|
||||||
|
ainfop->set_acTL_fn = set_acTL_f;
|
||||||
|
}
|
82
src/apng.h
Normal file
82
src/apng.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019, James R.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APNG_H
|
||||||
|
#define APNG_H
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
#ifndef _WII
|
||||||
|
#ifndef _LARGEFILE64_SOURCE
|
||||||
|
#define _LARGEFILE64_SOURCE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _LFS64_LARGEFILE
|
||||||
|
#define _LFS64_LARGEFILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _FILE_OFFSET_BITS
|
||||||
|
#define _FILE_OFFSET_BITS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
typedef struct apng_info_def apng_info;
|
||||||
|
typedef apng_info * apng_infop;
|
||||||
|
typedef const apng_info * apng_const_infop;
|
||||||
|
typedef apng_info * * apng_infopp;
|
||||||
|
|
||||||
|
typedef void (*apng_seek_ptr)(png_structp, size_t);
|
||||||
|
typedef size_t (*apng_tell_ptr)(png_structp);
|
||||||
|
|
||||||
|
typedef png_uint_32 (*apng_set_acTL_ptr)(png_structp, png_infop,
|
||||||
|
png_uint_32, png_uint_32);
|
||||||
|
|
||||||
|
apng_infop apng_create_info_struct (png_structp png_ptr);
|
||||||
|
|
||||||
|
void apng_destroy_info_struct (png_structp png_ptr,
|
||||||
|
apng_infopp info_ptr_ptr);
|
||||||
|
|
||||||
|
/* Call the following functions in place of the libpng counterparts. */
|
||||||
|
|
||||||
|
png_uint_32 apng_set_acTL (png_structp png_ptr, png_infop info_ptr,
|
||||||
|
apng_infop ainfo_ptr,
|
||||||
|
png_uint_32 num_frames, png_uint_32 num_plays);
|
||||||
|
|
||||||
|
void apng_write_info_before_PLTE (png_structp png_ptr, png_infop info_ptr,
|
||||||
|
apng_infop ainfo_ptr);
|
||||||
|
void apng_write_info (png_structp png_ptr, png_infop info_ptr,
|
||||||
|
apng_infop ainfo_ptr);
|
||||||
|
|
||||||
|
void apng_write_end (png_structp png_ptr, png_infop info_ptr,
|
||||||
|
apng_infop ainfo_ptr);
|
||||||
|
|
||||||
|
void apng_set_write_fn (png_structp png_ptr, apng_infop ainfo_ptr,
|
||||||
|
png_voidp io_ptr,
|
||||||
|
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn,
|
||||||
|
apng_seek_ptr output_seek_fn, apng_tell_ptr output_tell_fn);
|
||||||
|
|
||||||
|
void apng_set_set_acTL_fn (png_structp png_ptr, apng_infop ainfo_ptr,
|
||||||
|
apng_set_acTL_ptr set_acTL_fn);
|
||||||
|
|
||||||
|
#endif/* APNG_H */
|
|
@ -93,6 +93,7 @@ static size_t input_len; // length of current line, used to bound cursor and suc
|
||||||
// protos.
|
// protos.
|
||||||
static void CON_InputInit(void);
|
static void CON_InputInit(void);
|
||||||
static void CON_RecalcSize(void);
|
static void CON_RecalcSize(void);
|
||||||
|
static void CON_ChangeHeight(void);
|
||||||
|
|
||||||
static void CONS_hudlines_Change(void);
|
static void CONS_hudlines_Change(void);
|
||||||
static void CONS_backcolor_Change(void);
|
static void CONS_backcolor_Change(void);
|
||||||
|
@ -499,6 +500,12 @@ static void CON_RecalcSize(void)
|
||||||
con_destlines = vid.height;
|
con_destlines = vid.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (con_destlines > 0) // Resize console if already open
|
||||||
|
{
|
||||||
|
CON_ChangeHeight();
|
||||||
|
con_curlines = con_destlines;
|
||||||
|
}
|
||||||
|
|
||||||
// check for change of video width
|
// check for change of video width
|
||||||
if (conw == con_width)
|
if (conw == con_width)
|
||||||
return; // didn't change
|
return; // didn't change
|
||||||
|
@ -548,6 +555,20 @@ static void CON_RecalcSize(void)
|
||||||
Z_Free(tmp_buffer);
|
Z_Free(tmp_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CON_ChangeHeight(void)
|
||||||
|
{
|
||||||
|
INT32 minheight = 20 * con_scalefactor; // 20 = 8+8+4
|
||||||
|
|
||||||
|
// toggle console in
|
||||||
|
con_destlines = (cons_height.value*vid.height)/100;
|
||||||
|
if (con_destlines < minheight)
|
||||||
|
con_destlines = minheight;
|
||||||
|
else if (con_destlines > vid.height)
|
||||||
|
con_destlines = vid.height;
|
||||||
|
|
||||||
|
con_destlines &= ~0x3; // multiple of text row height
|
||||||
|
}
|
||||||
|
|
||||||
// Handles Console moves in/out of screen (per frame)
|
// Handles Console moves in/out of screen (per frame)
|
||||||
//
|
//
|
||||||
static void CON_MoveConsole(void)
|
static void CON_MoveConsole(void)
|
||||||
|
@ -636,16 +657,7 @@ void CON_Ticker(void)
|
||||||
CON_ClearHUD();
|
CON_ClearHUD();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
CON_ChangeHeight();
|
||||||
// toggle console in
|
|
||||||
con_destlines = (cons_height.value*vid.height)/100;
|
|
||||||
if (con_destlines < minheight)
|
|
||||||
con_destlines = minheight;
|
|
||||||
else if (con_destlines > vid.height)
|
|
||||||
con_destlines = vid.height;
|
|
||||||
|
|
||||||
con_destlines &= ~0x3; // multiple of text row height
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// console movement
|
// console movement
|
||||||
|
@ -1158,6 +1170,7 @@ static void CON_Print(char *msg)
|
||||||
{
|
{
|
||||||
size_t l;
|
size_t l;
|
||||||
INT32 controlchars = 0; // for color changing
|
INT32 controlchars = 0; // for color changing
|
||||||
|
char color = '\x80'; // keep color across lines
|
||||||
|
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -1183,7 +1196,7 @@ static void CON_Print(char *msg)
|
||||||
{
|
{
|
||||||
if (*msg & 0x80)
|
if (*msg & 0x80)
|
||||||
{
|
{
|
||||||
con_line[con_cx++] = *(msg++);
|
color = con_line[con_cx++] = *(msg++);
|
||||||
controlchars++;
|
controlchars++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1191,12 +1204,14 @@ static void CON_Print(char *msg)
|
||||||
{
|
{
|
||||||
con_cy--;
|
con_cy--;
|
||||||
CON_Linefeed();
|
CON_Linefeed();
|
||||||
|
color = '\x80';
|
||||||
controlchars = 0;
|
controlchars = 0;
|
||||||
}
|
}
|
||||||
else if (*msg == '\n') // linefeed
|
else if (*msg == '\n') // linefeed
|
||||||
{
|
{
|
||||||
CON_Linefeed();
|
CON_Linefeed();
|
||||||
controlchars = 0;
|
con_line[con_cx++] = color;
|
||||||
|
controlchars = 1;
|
||||||
}
|
}
|
||||||
else if (*msg == ' ') // space
|
else if (*msg == ' ') // space
|
||||||
{
|
{
|
||||||
|
@ -1204,7 +1219,8 @@ static void CON_Print(char *msg)
|
||||||
if (con_cx - controlchars >= con_width-11)
|
if (con_cx - controlchars >= con_width-11)
|
||||||
{
|
{
|
||||||
CON_Linefeed();
|
CON_Linefeed();
|
||||||
controlchars = 0;
|
con_line[con_cx++] = color;
|
||||||
|
controlchars = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*msg == '\t')
|
else if (*msg == '\t')
|
||||||
|
@ -1219,7 +1235,8 @@ static void CON_Print(char *msg)
|
||||||
if (con_cx - controlchars >= con_width-11)
|
if (con_cx - controlchars >= con_width-11)
|
||||||
{
|
{
|
||||||
CON_Linefeed();
|
CON_Linefeed();
|
||||||
controlchars = 0;
|
con_line[con_cx++] = color;
|
||||||
|
controlchars = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg++;
|
msg++;
|
||||||
|
@ -1236,7 +1253,8 @@ static void CON_Print(char *msg)
|
||||||
if ((con_cx - controlchars) + l > con_width-11)
|
if ((con_cx - controlchars) + l > con_width-11)
|
||||||
{
|
{
|
||||||
CON_Linefeed();
|
CON_Linefeed();
|
||||||
controlchars = 0;
|
con_line[con_cx++] = color;
|
||||||
|
controlchars = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a word at a time
|
// a word at a time
|
||||||
|
@ -1586,8 +1604,7 @@ static void CON_DrawConsole(void)
|
||||||
i = con_cy - con_scrollup;
|
i = con_cy - con_scrollup;
|
||||||
|
|
||||||
// skip the last empty line due to the cursor being at the start of a new line
|
// skip the last empty line due to the cursor being at the start of a new line
|
||||||
if (!con_scrollup && !con_cx)
|
i--;
|
||||||
i--;
|
|
||||||
|
|
||||||
i -= (con_curlines - minheight) / charheight;
|
i -= (con_curlines - minheight) / charheight;
|
||||||
|
|
||||||
|
|
|
@ -2429,6 +2429,8 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting
|
||||||
|
#else
|
||||||
|
(void)reason;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Reset player data
|
// Reset player data
|
||||||
|
|
|
@ -742,7 +742,6 @@ void D_StartTitle(void)
|
||||||
paused = false;
|
paused = false;
|
||||||
advancedemo = false;
|
advancedemo = false;
|
||||||
F_StartTitleScreen();
|
F_StartTitleScreen();
|
||||||
CON_ToggleOff();
|
|
||||||
|
|
||||||
// Reset the palette
|
// Reset the palette
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
|
@ -1124,6 +1123,10 @@ void D_SRB2Main(void)
|
||||||
// Make backups of some SOCcable tables.
|
// Make backups of some SOCcable tables.
|
||||||
P_BackupTables();
|
P_BackupTables();
|
||||||
|
|
||||||
|
// Setup character tables
|
||||||
|
// Have to be done here before files are loaded
|
||||||
|
M_InitCharacterTables();
|
||||||
|
|
||||||
mainwads = 0;
|
mainwads = 0;
|
||||||
|
|
||||||
#ifndef DEVELOP // md5s last updated 12/14/14
|
#ifndef DEVELOP // md5s last updated 12/14/14
|
||||||
|
@ -1397,13 +1400,13 @@ void D_SRB2Main(void)
|
||||||
}
|
}
|
||||||
else if (M_CheckParm("-skipintro"))
|
else if (M_CheckParm("-skipintro"))
|
||||||
{
|
{
|
||||||
CON_ToggleOff();
|
|
||||||
CON_ClearHUD();
|
|
||||||
F_StartTitleScreen();
|
F_StartTitleScreen();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
F_StartIntro(); // Tails 03-03-2002
|
F_StartIntro(); // Tails 03-03-2002
|
||||||
|
|
||||||
|
CON_ToggleOff();
|
||||||
|
|
||||||
if (dedicated && server)
|
if (dedicated && server)
|
||||||
{
|
{
|
||||||
levelstarttic = gametic;
|
levelstarttic = gametic;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#define __D_NET__
|
#define __D_NET__
|
||||||
|
|
||||||
// Max computers in a game
|
// Max computers in a game
|
||||||
#define MAXNETNODES 32
|
#define MAXNETNODES (MAXPLAYERS+4)
|
||||||
#define BROADCASTADDR MAXNETNODES
|
#define BROADCASTADDR MAXNETNODES
|
||||||
#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer
|
#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer
|
||||||
//#define NETSPLITSCREEN // Kart's splitscreen netgame feature
|
//#define NETSPLITSCREEN // Kart's splitscreen netgame feature
|
||||||
|
|
|
@ -1900,9 +1900,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
||||||
CONS_Printf(M_GetText("Speeding off to level...\n"));
|
CONS_Printf(M_GetText("Speeding off to level...\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
CON_ToggleOff();
|
|
||||||
CON_ClearHUD();
|
|
||||||
|
|
||||||
if (demoplayback && !timingdemo)
|
if (demoplayback && !timingdemo)
|
||||||
precache = false;
|
precache = false;
|
||||||
|
|
||||||
|
|
|
@ -304,11 +304,11 @@ static void clear_levels(void)
|
||||||
static boolean findFreeSlot(INT32 *num)
|
static boolean findFreeSlot(INT32 *num)
|
||||||
{
|
{
|
||||||
// Send the character select entry to a free slot.
|
// Send the character select entry to a free slot.
|
||||||
while (*num < 32 && (description[*num].used))
|
while (*num < MAXSKINS && (description[*num].used))
|
||||||
*num = *num+1;
|
*num = *num+1;
|
||||||
|
|
||||||
// No more free slots. :(
|
// No more free slots. :(
|
||||||
if (*num >= 32)
|
if (*num >= MAXSKINS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
|
||||||
|
@ -1160,6 +1160,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
||||||
#endif
|
#endif
|
||||||
else if (fastcmp(word, "MUSICTRACK"))
|
else if (fastcmp(word, "MUSICTRACK"))
|
||||||
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
|
mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1);
|
||||||
|
else if (fastcmp(word, "MUSICPOS"))
|
||||||
|
mapheaderinfo[num-1]->muspos = (UINT32)get_number(word2);
|
||||||
|
else if (fastcmp(word, "MUSICINTERFADEOUT"))
|
||||||
|
mapheaderinfo[num-1]->musinterfadeout = (UINT32)get_number(word2);
|
||||||
|
else if (fastcmp(word, "MUSICINTER"))
|
||||||
|
deh_strlcpy(mapheaderinfo[num-1]->musintername, word2,
|
||||||
|
sizeof(mapheaderinfo[num-1]->musintername), va("Level header %d: intermission music", num));
|
||||||
else if (fastcmp(word, "FORCECHARACTER"))
|
else if (fastcmp(word, "FORCECHARACTER"))
|
||||||
{
|
{
|
||||||
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
|
strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1);
|
||||||
|
@ -1264,6 +1271,13 @@ static void readlevelheader(MYFILE *f, INT32 num)
|
||||||
else
|
else
|
||||||
mapheaderinfo[num-1]->levelflags &= ~LF_SAVEGAME;
|
mapheaderinfo[num-1]->levelflags &= ~LF_SAVEGAME;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "MIXNIGHTSCOUNTDOWN"))
|
||||||
|
{
|
||||||
|
if (i || word2[0] == 'T' || word2[0] == 'Y')
|
||||||
|
mapheaderinfo[num-1]->levelflags |= LF_MIXNIGHTSCOUNTDOWN;
|
||||||
|
else
|
||||||
|
mapheaderinfo[num-1]->levelflags &= ~LF_MIXNIGHTSCOUNTDOWN;
|
||||||
|
}
|
||||||
|
|
||||||
// Individual triggers for menu flags
|
// Individual triggers for menu flags
|
||||||
else if (fastcmp(word, "HIDDEN"))
|
else if (fastcmp(word, "HIDDEN"))
|
||||||
|
@ -1460,6 +1474,10 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
|
||||||
{
|
{
|
||||||
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "MUSICPOS"))
|
||||||
|
{
|
||||||
|
cutscenes[num]->scene[scenenum].musswitchposition = (UINT32)get_number(word2);
|
||||||
|
}
|
||||||
else if (fastcmp(word, "MUSICLOOP"))
|
else if (fastcmp(word, "MUSICLOOP"))
|
||||||
{
|
{
|
||||||
cutscenes[num]->scene[scenenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
cutscenes[num]->scene[scenenum].musicloop = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y');
|
||||||
|
@ -7793,6 +7811,7 @@ struct {
|
||||||
|
|
||||||
// doomdef.h constants
|
// doomdef.h constants
|
||||||
{"TICRATE",TICRATE},
|
{"TICRATE",TICRATE},
|
||||||
|
{"MUSICRATE",MUSICRATE},
|
||||||
{"RING_DIST",RING_DIST},
|
{"RING_DIST",RING_DIST},
|
||||||
{"PUSHACCEL",PUSHACCEL},
|
{"PUSHACCEL",PUSHACCEL},
|
||||||
{"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into.
|
{"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into.
|
||||||
|
@ -7879,6 +7898,7 @@ struct {
|
||||||
{"LF_NORELOAD",LF_NORELOAD},
|
{"LF_NORELOAD",LF_NORELOAD},
|
||||||
{"LF_NOZONE",LF_NOZONE},
|
{"LF_NOZONE",LF_NOZONE},
|
||||||
{"LF_SAVEGAME",LF_SAVEGAME},
|
{"LF_SAVEGAME",LF_SAVEGAME},
|
||||||
|
{"LF_MIXNIGHTSCOUNTDOWN",LF_MIXNIGHTSCOUNTDOWN},
|
||||||
// And map flags
|
// And map flags
|
||||||
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
{"LF2_HIDEINMENU",LF2_HIDEINMENU},
|
||||||
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
{"LF2_HIDEINSTATS",LF2_HIDEINSTATS},
|
||||||
|
@ -9249,6 +9269,9 @@ static inline int lib_getenum(lua_State *L)
|
||||||
} else if (fastcmp(word,"mapmusflags")) {
|
} else if (fastcmp(word,"mapmusflags")) {
|
||||||
lua_pushinteger(L, mapmusflags);
|
lua_pushinteger(L, mapmusflags);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (fastcmp(word,"mapmusposition")) {
|
||||||
|
lua_pushinteger(L, mapmusposition);
|
||||||
|
return 1;
|
||||||
} else if (fastcmp(word,"server")) {
|
} else if (fastcmp(word,"server")) {
|
||||||
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -438,6 +438,37 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
(void)looppoint;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
(void)position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC PLAYBACK
|
// MUSIC PLAYBACK
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -545,3 +576,44 @@ int I_QrySongPlaying(int handle)
|
||||||
return (midi_pos==-1);
|
return (midi_pos==-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)source_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -373,6 +373,8 @@ typedef enum
|
||||||
#define NEWTICRATERATIO 1 // try 4 for 140 fps :)
|
#define NEWTICRATERATIO 1 // try 4 for 140 fps :)
|
||||||
#define NEWTICRATE (TICRATE*NEWTICRATERATIO)
|
#define NEWTICRATE (TICRATE*NEWTICRATERATIO)
|
||||||
|
|
||||||
|
#define MUSICRATE 1000 // sound timing is calculated by milliseconds
|
||||||
|
|
||||||
#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it
|
#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it
|
||||||
|
|
||||||
#define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.
|
#define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.
|
||||||
|
|
|
@ -33,8 +33,10 @@
|
||||||
extern INT16 gamemap;
|
extern INT16 gamemap;
|
||||||
extern char mapmusname[7];
|
extern char mapmusname[7];
|
||||||
extern UINT16 mapmusflags;
|
extern UINT16 mapmusflags;
|
||||||
|
extern UINT32 mapmusposition;
|
||||||
#define MUSIC_TRACKMASK 0x0FFF // ----************
|
#define MUSIC_TRACKMASK 0x0FFF // ----************
|
||||||
#define MUSIC_RELOADRESET 0x8000 // *---------------
|
#define MUSIC_RELOADRESET 0x8000 // *---------------
|
||||||
|
#define MUSIC_FORCERESET 0x4000 // -*--------------
|
||||||
// Use other bits if necessary.
|
// Use other bits if necessary.
|
||||||
|
|
||||||
extern INT16 maptol;
|
extern INT16 maptol;
|
||||||
|
@ -160,6 +162,7 @@ typedef struct
|
||||||
|
|
||||||
char musswitch[7];
|
char musswitch[7];
|
||||||
UINT16 musswitchflags;
|
UINT16 musswitchflags;
|
||||||
|
UINT32 musswitchposition;
|
||||||
|
|
||||||
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
|
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
|
||||||
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
|
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
|
||||||
|
@ -284,6 +287,7 @@ typedef struct
|
||||||
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
|
||||||
char musname[7]; ///< Music track to play. "" for no music.
|
char musname[7]; ///< Music track to play. "" for no music.
|
||||||
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
|
||||||
|
UINT32 muspos; ///< Music position to jump to.
|
||||||
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
|
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
|
||||||
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
|
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
|
||||||
INT16 skynum; ///< Sky number to use.
|
INT16 skynum; ///< Sky number to use.
|
||||||
|
@ -305,7 +309,7 @@ typedef struct
|
||||||
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
|
SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.)
|
||||||
SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.)
|
SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.)
|
||||||
|
|
||||||
UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below
|
UINT8 levelflags; ///< LF_flags: merged booleans into one UINT8 for space, see below
|
||||||
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus
|
||||||
|
|
||||||
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
|
char selectheading[22]; ///< Level select heading. Allows for controllable grouping.
|
||||||
|
@ -318,6 +322,10 @@ typedef struct
|
||||||
UINT8 numGradedMares; ///< Internal. For grade support.
|
UINT8 numGradedMares; ///< Internal. For grade support.
|
||||||
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
|
nightsgrades_t *grades; ///< NiGHTS grades. Allocated dynamically for space reasons. Be careful.
|
||||||
|
|
||||||
|
// Music stuff.
|
||||||
|
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||||
|
char musintername[7]; ///< Intermission screen music.
|
||||||
|
|
||||||
// Lua stuff.
|
// Lua stuff.
|
||||||
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
|
||||||
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
|
||||||
|
@ -331,6 +339,7 @@ typedef struct
|
||||||
#define LF_NORELOAD 8 ///< Don't reload level on death
|
#define LF_NORELOAD 8 ///< Don't reload level on death
|
||||||
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
|
#define LF_NOZONE 16 ///< Don't include "ZONE" on level title
|
||||||
#define LF_SAVEGAME 32 ///< Save the game upon loading this level
|
#define LF_SAVEGAME 32 ///< Save the game upon loading this level
|
||||||
|
#define LF_MIXNIGHTSCOUNTDOWN 64 ///< Play sfx_timeup instead of music change for NiGHTS countdown
|
||||||
|
|
||||||
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
|
#define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu
|
||||||
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen
|
#define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen
|
||||||
|
|
|
@ -95,6 +95,37 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
(void)looppoint;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
(void)position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC PLAYBACK
|
// MUSIC PLAYBACK
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -142,4 +173,45 @@ boolean I_SetSongTrack(int track)
|
||||||
{
|
{
|
||||||
(void)track;
|
(void)track;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)source_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -471,7 +471,6 @@ void F_StartIntro(void)
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
paused = false;
|
paused = false;
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
|
||||||
F_NewCutscene(introtext[0]);
|
F_NewCutscene(introtext[0]);
|
||||||
|
|
||||||
intro_scenenum = 0;
|
intro_scenenum = 0;
|
||||||
|
@ -1032,6 +1031,7 @@ static const char *credits[] = {
|
||||||
"Andrew \"orospakr\" Clunis",
|
"Andrew \"orospakr\" Clunis",
|
||||||
"Gregor \"Oogaland\" Dick",
|
"Gregor \"Oogaland\" Dick",
|
||||||
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
"Louis-Antoine \"LJSonic\" de Moulins", // for fixing 2.1's netcode (de Rochefort doesn't quite fit on the screen sorry lol)
|
||||||
|
"Victor \"Steel Titanium\" Fuentes",
|
||||||
"Julio \"Chaos Zero 64\" Guir",
|
"Julio \"Chaos Zero 64\" Guir",
|
||||||
"\"Jimita\"",
|
"\"Jimita\"",
|
||||||
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
|
||||||
|
@ -1042,7 +1042,6 @@ static const char *credits[] = {
|
||||||
"Colin \"Sonict\" Pfaff",
|
"Colin \"Sonict\" Pfaff",
|
||||||
"Sean \"Sryder13\" Ryder",
|
"Sean \"Sryder13\" Ryder",
|
||||||
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
"Tasos \"tatokis\" Sahanidis", // Corrected C FixedMul, making 64-bit builds netplay compatible
|
||||||
"\"Steel Titanium\"",
|
|
||||||
"Ben \"Cue\" Woodford",
|
"Ben \"Cue\" Woodford",
|
||||||
// Git contributors with 5+ approved merges of substantive quality,
|
// Git contributors with 5+ approved merges of substantive quality,
|
||||||
// or contributors with at least one groundbreaking merge, may be named.
|
// or contributors with at least one groundbreaking merge, may be named.
|
||||||
|
@ -1093,12 +1092,12 @@ static const char *credits[] = {
|
||||||
"Dan \"Blitzzo\" Hagerstrand",
|
"Dan \"Blitzzo\" Hagerstrand",
|
||||||
"Kepa \"Nev3r\" Iceta",
|
"Kepa \"Nev3r\" Iceta",
|
||||||
"Thomas \"Shadow Hog\" Igoe",
|
"Thomas \"Shadow Hog\" Igoe",
|
||||||
"Erik \"Torgo\" Nielsen",
|
|
||||||
"\"Kaito Sinclaire\"",
|
"\"Kaito Sinclaire\"",
|
||||||
"Wessel \"sphere\" Smit",
|
"Wessel \"sphere\" Smit",
|
||||||
"\"Spazzo\"",
|
"\"Spazzo\"",
|
||||||
"\"SSNTails\"",
|
"\"SSNTails\"",
|
||||||
"Rob Tisdell",
|
"Rob Tisdell",
|
||||||
|
"\"Torgo\"",
|
||||||
"Jarrett \"JEV3\" Voight",
|
"Jarrett \"JEV3\" Voight",
|
||||||
"Johnny \"Sonikku\" Wallbank",
|
"Johnny \"Sonikku\" Wallbank",
|
||||||
"Marco \"mazmazz\" Zafra",
|
"Marco \"mazmazz\" Zafra",
|
||||||
|
@ -1184,7 +1183,6 @@ void F_StartCredits(void)
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
paused = false;
|
paused = false;
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
|
|
||||||
S_ChangeMusicInternal("_creds", false);
|
S_ChangeMusicInternal("_creds", false);
|
||||||
|
@ -1230,16 +1228,34 @@ void F_CreditDrawer(void)
|
||||||
if (FixedMul(y,vid.dupy) > vid.height)
|
if (FixedMul(y,vid.dupy) > vid.height)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void F_CreditTicker(void)
|
||||||
|
{
|
||||||
|
// "Simulate" the drawing of the credits so that dedicated mode doesn't get stuck
|
||||||
|
UINT16 i;
|
||||||
|
fixed_t y = (80<<FRACBITS) - 5*(animtimer<<FRACBITS)/8;
|
||||||
|
|
||||||
|
// Draw credits text on top
|
||||||
|
for (i = 0; credits[i]; i++)
|
||||||
|
{
|
||||||
|
switch(credits[i][0])
|
||||||
|
{
|
||||||
|
case 0: y += 80<<FRACBITS; break;
|
||||||
|
case 1: y += 30<<FRACBITS; break;
|
||||||
|
default: y += 12<<FRACBITS; break;
|
||||||
|
}
|
||||||
|
if (FixedMul(y,vid.dupy) > vid.height)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do this here rather than in the drawer you doofus! (this is why dedicated mode broke at credits)
|
||||||
if (!credits[i] && y <= 120<<FRACBITS && !finalecount)
|
if (!credits[i] && y <= 120<<FRACBITS && !finalecount)
|
||||||
{
|
{
|
||||||
timetonext = 5*TICRATE+1;
|
timetonext = 5*TICRATE+1;
|
||||||
finalecount = 5*TICRATE;
|
finalecount = 5*TICRATE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void F_CreditTicker(void)
|
|
||||||
{
|
|
||||||
if (timetonext)
|
if (timetonext)
|
||||||
timetonext--;
|
timetonext--;
|
||||||
else
|
else
|
||||||
|
@ -1333,7 +1349,6 @@ void F_StartGameEvaluation(void)
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
paused = false;
|
paused = false;
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
|
||||||
|
|
||||||
finalecount = 0;
|
finalecount = 0;
|
||||||
}
|
}
|
||||||
|
@ -1443,7 +1458,6 @@ void F_StartGameEnd(void)
|
||||||
gameaction = ga_nothing;
|
gameaction = ga_nothing;
|
||||||
paused = false;
|
paused = false;
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
|
|
||||||
// In case menus are still up?!!
|
// In case menus are still up?!!
|
||||||
|
@ -1755,7 +1769,6 @@ void F_StartContinue(void)
|
||||||
keypressed = false;
|
keypressed = false;
|
||||||
paused = false;
|
paused = false;
|
||||||
CON_ToggleOff();
|
CON_ToggleOff();
|
||||||
CON_ClearHUD();
|
|
||||||
|
|
||||||
// In case menus are still up?!!
|
// In case menus are still up?!!
|
||||||
M_ClearMenus(true);
|
M_ClearMenus(true);
|
||||||
|
@ -1875,9 +1888,10 @@ static void F_AdvanceToNextScene(void)
|
||||||
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
|
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
|
||||||
|
|
||||||
if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
|
if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
|
||||||
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch,
|
S_ChangeMusicEx(cutscenes[cutnum]->scene[scenenum].musswitch,
|
||||||
cutscenes[cutnum]->scene[scenenum].musswitchflags,
|
cutscenes[cutnum]->scene[scenenum].musswitchflags,
|
||||||
cutscenes[cutnum]->scene[scenenum].musicloop);
|
cutscenes[cutnum]->scene[scenenum].musicloop,
|
||||||
|
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||||
|
|
||||||
// Fade to the next
|
// Fade to the next
|
||||||
dofadenow = true;
|
dofadenow = true;
|
||||||
|
@ -1929,8 +1943,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
||||||
|
|
||||||
F_NewCutscene(cutscenes[cutscenenum]->scene[0].text);
|
F_NewCutscene(cutscenes[cutscenenum]->scene[0].text);
|
||||||
|
|
||||||
CON_ClearHUD();
|
|
||||||
|
|
||||||
cutsceneover = false;
|
cutsceneover = false;
|
||||||
runningprecutscene = precutscene;
|
runningprecutscene = precutscene;
|
||||||
precutresetplayer = resetplayer;
|
precutresetplayer = resetplayer;
|
||||||
|
@ -1951,9 +1963,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
||||||
stoptimer = 0;
|
stoptimer = 0;
|
||||||
|
|
||||||
if (cutscenes[cutnum]->scene[0].musswitch[0])
|
if (cutscenes[cutnum]->scene[0].musswitch[0])
|
||||||
S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch,
|
S_ChangeMusicEx(cutscenes[cutnum]->scene[0].musswitch,
|
||||||
cutscenes[cutnum]->scene[0].musswitchflags,
|
cutscenes[cutnum]->scene[0].musswitchflags,
|
||||||
cutscenes[cutnum]->scene[0].musicloop);
|
cutscenes[cutnum]->scene[0].musicloop,
|
||||||
|
cutscenes[cutnum]->scene[scenenum].musswitchposition, 0, 0);
|
||||||
else
|
else
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
}
|
}
|
||||||
|
|
10
src/g_game.c
10
src/g_game.c
|
@ -71,6 +71,7 @@ static void G_DoWorldDone(void);
|
||||||
|
|
||||||
char mapmusname[7]; // Music name
|
char mapmusname[7]; // Music name
|
||||||
UINT16 mapmusflags; // Track and reset bit
|
UINT16 mapmusflags; // Track and reset bit
|
||||||
|
UINT32 mapmusposition; // Position to jump to
|
||||||
|
|
||||||
INT16 gamemap = 1;
|
INT16 gamemap = 1;
|
||||||
INT16 maptol;
|
INT16 maptol;
|
||||||
|
@ -2292,9 +2293,14 @@ void G_PlayerReborn(INT32 player)
|
||||||
{
|
{
|
||||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
||||||
mapmusname[6] = 0;
|
mapmusname[6] = 0;
|
||||||
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
|
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
||||||
|
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
|
||||||
}
|
}
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
|
||||||
|
// This is in S_Start, but this was not here previously.
|
||||||
|
// if (cv_resetmusic.value)
|
||||||
|
// S_StopMusic();
|
||||||
|
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gametype == GT_COOP)
|
if (gametype == GT_COOP)
|
||||||
|
|
|
@ -146,6 +146,18 @@ boolean I_SongPaused(void);
|
||||||
|
|
||||||
boolean I_SetSongSpeed(float speed);
|
boolean I_SetSongSpeed(float speed);
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void);
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint);
|
||||||
|
UINT32 I_GetSongLoopPoint(void);
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position);
|
||||||
|
UINT32 I_GetSongPosition(void);
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC PLAYBACK
|
// MUSIC PLAYBACK
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -216,6 +228,17 @@ void I_SetMusicVolume(UINT8 volume);
|
||||||
|
|
||||||
boolean I_SetSongTrack(INT32 track);
|
boolean I_SetSongTrack(INT32 track);
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume);
|
||||||
|
void I_StopFadingSong(void);
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void));
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms);
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping);
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// CD MUSIC I/O
|
// CD MUSIC I/O
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
|
10
src/i_tcp.c
10
src/i_tcp.c
|
@ -575,7 +575,7 @@ static boolean SOCK_Get(void)
|
||||||
if (c != ERRSOCKET)
|
if (c != ERRSOCKET)
|
||||||
{
|
{
|
||||||
// find remote node number
|
// find remote node number
|
||||||
for (j = 0; j <= MAXNETNODES; j++) //include LAN
|
for (j = 1; j <= MAXNETNODES; j++) //include LAN
|
||||||
{
|
{
|
||||||
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
|
if (SOCK_cmpaddr(&fromaddress, &clientaddress[j], 0))
|
||||||
{
|
{
|
||||||
|
@ -1286,8 +1286,12 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port)
|
||||||
while (runp != NULL)
|
while (runp != NULL)
|
||||||
{
|
{
|
||||||
// find ip of the server
|
// find ip of the server
|
||||||
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
if (sendto(mysockets[0], NULL, 0, 0, runp->ai_addr, runp->ai_addrlen) == 0)
|
||||||
runp = NULL;
|
{
|
||||||
|
memcpy(&clientaddress[newnode], runp->ai_addr, runp->ai_addrlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
runp = runp->ai_next;
|
||||||
}
|
}
|
||||||
I_freeaddrinfo(ai);
|
I_freeaddrinfo(ai);
|
||||||
return newnode;
|
return newnode;
|
||||||
|
|
|
@ -1015,7 +1015,8 @@ static int lib_pRestoreMusic(lua_State *L)
|
||||||
INLEVEL
|
INLEVEL
|
||||||
if (!player)
|
if (!player)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
P_RestoreMusic(player);
|
if (P_IsLocalPlayer(player))
|
||||||
|
P_RestoreMusic(player);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2283,7 +2284,7 @@ static int lib_sChangeMusic(lua_State *L)
|
||||||
{
|
{
|
||||||
#ifdef MUSICSLOT_COMPATIBILITY
|
#ifdef MUSICSLOT_COMPATIBILITY
|
||||||
const char *music_name;
|
const char *music_name;
|
||||||
UINT32 music_num;
|
UINT32 music_num, position, prefadems, fadeinms;
|
||||||
char music_compat_name[7];
|
char music_compat_name[7];
|
||||||
|
|
||||||
boolean looping;
|
boolean looping;
|
||||||
|
@ -2311,7 +2312,6 @@ static int lib_sChangeMusic(lua_State *L)
|
||||||
music_name = luaL_checkstring(L, 1);
|
music_name = luaL_checkstring(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
looping = (boolean)lua_opttrueboolean(L, 2);
|
looping = (boolean)lua_opttrueboolean(L, 2);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -2336,8 +2336,12 @@ static int lib_sChangeMusic(lua_State *L)
|
||||||
#endif
|
#endif
|
||||||
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
|
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
|
||||||
|
|
||||||
|
position = (UINT32)luaL_optinteger(L, 5, 0);
|
||||||
|
prefadems = (UINT32)luaL_optinteger(L, 6, 0);
|
||||||
|
fadeinms = (UINT32)luaL_optinteger(L, 7, 0);
|
||||||
|
|
||||||
if (!player || P_IsLocalPlayer(player))
|
if (!player || P_IsLocalPlayer(player))
|
||||||
S_ChangeMusic(music_name, music_flags, looping);
|
S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2354,10 +2358,8 @@ static int lib_sSpeedMusic(lua_State *L)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
}
|
}
|
||||||
if (!player || P_IsLocalPlayer(player))
|
if (!player || P_IsLocalPlayer(player))
|
||||||
lua_pushboolean(L, S_SpeedMusic(speed));
|
S_SpeedMusic(speed);
|
||||||
else
|
return 0;
|
||||||
lua_pushboolean(L, false);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lib_sStopMusic(lua_State *L)
|
static int lib_sStopMusic(lua_State *L)
|
||||||
|
@ -2375,6 +2377,110 @@ static int lib_sStopMusic(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_sSetInternalMusicVolume(lua_State *L)
|
||||||
|
{
|
||||||
|
UINT32 volume = (UINT32)luaL_checkinteger(L, 1);
|
||||||
|
player_t *player = NULL;
|
||||||
|
NOHUD
|
||||||
|
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||||
|
{
|
||||||
|
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
}
|
||||||
|
if (!player || P_IsLocalPlayer(player))
|
||||||
|
{
|
||||||
|
S_SetInternalMusicVolume(volume);
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_sStopFadingMusic(lua_State *L)
|
||||||
|
{
|
||||||
|
player_t *player = NULL;
|
||||||
|
NOHUD
|
||||||
|
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
|
||||||
|
{
|
||||||
|
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
}
|
||||||
|
if (!player || P_IsLocalPlayer(player))
|
||||||
|
{
|
||||||
|
S_StopFadingMusic();
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_sFadeMusic(lua_State *L)
|
||||||
|
{
|
||||||
|
UINT32 target_volume = (UINT32)luaL_checkinteger(L, 1);
|
||||||
|
UINT32 ms;
|
||||||
|
INT32 source_volume;
|
||||||
|
player_t *player = NULL;
|
||||||
|
NOHUD
|
||||||
|
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
|
||||||
|
{
|
||||||
|
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
ms = (UINT32)luaL_checkinteger(L, 2);
|
||||||
|
source_volume = -1;
|
||||||
|
}
|
||||||
|
else if (!lua_isnone(L, 4) && lua_isuserdata(L, 4))
|
||||||
|
{
|
||||||
|
player = *((player_t **)luaL_checkudata(L, 4, META_PLAYER));
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
source_volume = (INT32)luaL_checkinteger(L, 2);
|
||||||
|
ms = (UINT32)luaL_checkinteger(L, 3);
|
||||||
|
}
|
||||||
|
else if (luaL_optinteger(L, 3, INT32_MAX) == INT32_MAX)
|
||||||
|
{
|
||||||
|
ms = (UINT32)luaL_checkinteger(L, 2);
|
||||||
|
source_volume = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
source_volume = (INT32)luaL_checkinteger(L, 2);
|
||||||
|
ms = (UINT32)luaL_checkinteger(L, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
NOHUD
|
||||||
|
|
||||||
|
if (!player || P_IsLocalPlayer(player))
|
||||||
|
lua_pushboolean(L, S_FadeMusicFromVolume(target_volume, source_volume, ms));
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_sFadeOutStopMusic(lua_State *L)
|
||||||
|
{
|
||||||
|
UINT32 ms = (UINT32)luaL_checkinteger(L, 1);
|
||||||
|
player_t *player = NULL;
|
||||||
|
NOHUD
|
||||||
|
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
|
||||||
|
{
|
||||||
|
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
|
||||||
|
if (!player)
|
||||||
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
}
|
||||||
|
if (!player || P_IsLocalPlayer(player))
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, S_FadeOutStopMusic(ms));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_sOriginPlaying(lua_State *L)
|
static int lib_sOriginPlaying(lua_State *L)
|
||||||
{
|
{
|
||||||
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
void *origin = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
@ -2782,6 +2888,10 @@ static luaL_Reg lib[] = {
|
||||||
{"S_ChangeMusic",lib_sChangeMusic},
|
{"S_ChangeMusic",lib_sChangeMusic},
|
||||||
{"S_SpeedMusic",lib_sSpeedMusic},
|
{"S_SpeedMusic",lib_sSpeedMusic},
|
||||||
{"S_StopMusic",lib_sStopMusic},
|
{"S_StopMusic",lib_sStopMusic},
|
||||||
|
{"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume},
|
||||||
|
{"S_StopFadingMusic",lib_sStopFadingMusic},
|
||||||
|
{"S_FadeMusic",lib_sFadeMusic},
|
||||||
|
{"S_FadeOutStopMusic",lib_sFadeOutStopMusic},
|
||||||
{"S_OriginPlaying",lib_sOriginPlaying},
|
{"S_OriginPlaying",lib_sOriginPlaying},
|
||||||
{"S_IdPlaying",lib_sIdPlaying},
|
{"S_IdPlaying",lib_sIdPlaying},
|
||||||
{"S_SoundPlaying",lib_sSoundPlaying},
|
{"S_SoundPlaying",lib_sSoundPlaying},
|
||||||
|
|
|
@ -2031,6 +2031,12 @@ static int mapheaderinfo_get(lua_State *L)
|
||||||
lua_pushstring(L, header->musname);
|
lua_pushstring(L, header->musname);
|
||||||
else if (fastcmp(field,"mustrack"))
|
else if (fastcmp(field,"mustrack"))
|
||||||
lua_pushinteger(L, header->mustrack);
|
lua_pushinteger(L, header->mustrack);
|
||||||
|
else if (fastcmp(field,"muspos"))
|
||||||
|
lua_pushinteger(L, header->muspos);
|
||||||
|
else if (fastcmp(field,"musinterfadeout"))
|
||||||
|
lua_pushinteger(L, header->musinterfadeout);
|
||||||
|
else if (fastcmp(field,"musintername"))
|
||||||
|
lua_pushstring(L, header->musintername);
|
||||||
else if (fastcmp(field,"forcecharacter"))
|
else if (fastcmp(field,"forcecharacter"))
|
||||||
lua_pushstring(L, header->forcecharacter);
|
lua_pushstring(L, header->forcecharacter);
|
||||||
else if (fastcmp(field,"weather"))
|
else if (fastcmp(field,"weather"))
|
||||||
|
|
67
src/m_menu.c
67
src/m_menu.c
|
@ -117,44 +117,7 @@ typedef enum
|
||||||
const char *quitmsg[NUM_QUITMESSAGES];
|
const char *quitmsg[NUM_QUITMESSAGES];
|
||||||
|
|
||||||
// Stuff for customizing the player select screen Tails 09-22-2003
|
// Stuff for customizing the player select screen Tails 09-22-2003
|
||||||
// A rare case.
|
description_t description[MAXSKINS];
|
||||||
// External files modify this menu, so we can't call it static.
|
|
||||||
// And I'm too lazy to go through and rename it everywhere. ARRGH!
|
|
||||||
description_t description[32] =
|
|
||||||
{
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0},
|
|
||||||
{false, "???", "", "", 0, 0}
|
|
||||||
};
|
|
||||||
INT16 char_on = -1, startchar = 1;
|
INT16 char_on = -1, startchar = 1;
|
||||||
static char *char_notes = NULL;
|
static char *char_notes = NULL;
|
||||||
static fixed_t char_scroll = 0;
|
static fixed_t char_scroll = 0;
|
||||||
|
@ -2943,6 +2906,21 @@ void M_Init(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M_InitCharacterTables(void)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
// Setup description table
|
||||||
|
for (i = 0; i < MAXSKINS; i++)
|
||||||
|
{
|
||||||
|
description[i].used = false;
|
||||||
|
strcpy(description[i].notes, "???");
|
||||||
|
strcpy(description[i].picname, "");
|
||||||
|
strcpy(description[i].skinname, "");
|
||||||
|
description[i].prev = description[i].next = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// SPECIAL MENU OPTION DRAW ROUTINES GO HERE
|
// SPECIAL MENU OPTION DRAW ROUTINES GO HERE
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -4861,7 +4839,7 @@ static void M_Addons(INT32 choice)
|
||||||
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
if (addonsp[0]) // never going to have some provided but not all, saves individually checking
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < NUM_EXT+4; i++)
|
for (i = 0; i < NUM_EXT+5; i++)
|
||||||
W_UnlockCachedPatch(addonsp[i]);
|
W_UnlockCachedPatch(addonsp[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9450,7 +9428,7 @@ static void M_DrawControl(void)
|
||||||
#undef controlbuffer
|
#undef controlbuffer
|
||||||
|
|
||||||
static INT32 controltochange;
|
static INT32 controltochange;
|
||||||
static char controltochangetext[55];
|
static char controltochangetext[33];
|
||||||
|
|
||||||
static void M_ChangecontrolResponse(event_t *ev)
|
static void M_ChangecontrolResponse(event_t *ev)
|
||||||
{
|
{
|
||||||
|
@ -9522,7 +9500,8 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||||
}
|
}
|
||||||
else if (ch == KEY_PAUSE)
|
else if (ch == KEY_PAUSE)
|
||||||
{
|
{
|
||||||
static char tmp[158]; // 125 char message + 32 char control name
|
// This buffer assumes a 125-character message plus a 32-character control name (per controltochangetext buffer size)
|
||||||
|
static char tmp[158];
|
||||||
menu_t *prev = currentMenu->prevMenu;
|
menu_t *prev = currentMenu->prevMenu;
|
||||||
|
|
||||||
if (controltochange == gc_pause)
|
if (controltochange == gc_pause)
|
||||||
|
@ -9546,7 +9525,9 @@ static void M_ChangecontrolResponse(event_t *ev)
|
||||||
|
|
||||||
static void M_ChangeControl(INT32 choice)
|
static void M_ChangeControl(INT32 choice)
|
||||||
{
|
{
|
||||||
static char tmp[55];
|
// This buffer assumes a 35-character message (per below) plus a max control name limit of 32 chars (per controltochangetext)
|
||||||
|
// If you change the below message, then change the size of this buffer!
|
||||||
|
static char tmp[68];
|
||||||
|
|
||||||
if (tutorialmode && tutorialgcs) // don't allow control changes if temp control override is active
|
if (tutorialmode && tutorialgcs) // don't allow control changes if temp control override is active
|
||||||
return;
|
return;
|
||||||
|
@ -9554,7 +9535,7 @@ static void M_ChangeControl(INT32 choice)
|
||||||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||||
currentMenu->menuitems[choice].text);
|
currentMenu->menuitems[choice].text);
|
||||||
strncpy(controltochangetext, currentMenu->menuitems[choice].text, 55);
|
strlcpy(controltochangetext, currentMenu->menuitems[choice].text, 33);
|
||||||
|
|
||||||
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ void M_Drawer(void);
|
||||||
// Called by D_SRB2Main, loads the config file.
|
// Called by D_SRB2Main, loads the config file.
|
||||||
void M_Init(void);
|
void M_Init(void);
|
||||||
|
|
||||||
|
// Called by D_SRB2Main also, sets up the playermenu and description tables.
|
||||||
|
void M_InitCharacterTables(void);
|
||||||
|
|
||||||
// Called by intro code to force menu up upon a keypress,
|
// Called by intro code to force menu up upon a keypress,
|
||||||
// does nothing if menu is already up.
|
// does nothing if menu is already up.
|
||||||
void M_StartControlPanel(void);
|
void M_StartControlPanel(void);
|
||||||
|
@ -226,7 +229,7 @@ typedef struct
|
||||||
INT32 gamemap;
|
INT32 gamemap;
|
||||||
} saveinfo_t;
|
} saveinfo_t;
|
||||||
|
|
||||||
extern description_t description[32];
|
extern description_t description[MAXSKINS];
|
||||||
|
|
||||||
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort;
|
||||||
extern CV_PossibleValue_t gametype_cons_t[];
|
extern CV_PossibleValue_t gametype_cons_t[];
|
||||||
|
|
123
src/m_misc.c
123
src/m_misc.c
|
@ -91,7 +91,8 @@ typedef off_t off64_t;
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
#ifdef PNG_WRITE_SUPPORTED
|
||||||
#define USE_PNG // Only actually use PNG if write is supported.
|
#define USE_PNG // Only actually use PNG if write is supported.
|
||||||
#if defined (PNG_WRITE_APNG_SUPPORTED) //|| !defined(PNG_STATIC)
|
#if defined (PNG_WRITE_APNG_SUPPORTED) //|| !defined(PNG_STATIC)
|
||||||
#define USE_APNG
|
#include "apng.h"
|
||||||
|
#define USE_APNG
|
||||||
#endif
|
#endif
|
||||||
// See hardware/hw_draw.c for a similar check to this one.
|
// See hardware/hw_draw.c for a similar check to this one.
|
||||||
#endif
|
#endif
|
||||||
|
@ -820,13 +821,13 @@ static inline void M_PNGImage(png_structp png_ptr, png_infop png_info_ptr, PNG_C
|
||||||
#ifdef USE_APNG
|
#ifdef USE_APNG
|
||||||
static png_structp apng_ptr = NULL;
|
static png_structp apng_ptr = NULL;
|
||||||
static png_infop apng_info_ptr = NULL;
|
static png_infop apng_info_ptr = NULL;
|
||||||
|
static apng_infop apng_ainfo_ptr = NULL;
|
||||||
static png_FILE_p apng_FILE = NULL;
|
static png_FILE_p apng_FILE = NULL;
|
||||||
static png_uint_32 apng_frames = 0;
|
static png_uint_32 apng_frames = 0;
|
||||||
static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
|
|
||||||
#ifdef PNG_STATIC // Win32 build have static libpng
|
#ifdef PNG_STATIC // Win32 build have static libpng
|
||||||
#define apng_set_acTL png_set_acTL
|
#define aPNG_set_acTL png_set_acTL
|
||||||
#define apng_write_frame_head png_write_frame_head
|
#define aPNG_write_frame_head png_write_frame_head
|
||||||
#define apng_write_frame_tail png_write_frame_tail
|
#define aPNG_write_frame_tail png_write_frame_tail
|
||||||
#else // outside libpng may not have apng support
|
#else // outside libpng may not have apng support
|
||||||
|
|
||||||
#ifndef PNG_WRITE_APNG_SUPPORTED // libpng header may not have apng patch
|
#ifndef PNG_WRITE_APNG_SUPPORTED // libpng header may not have apng patch
|
||||||
|
@ -863,20 +864,20 @@ static png_byte acTL_cn[5] = { 97, 99, 84, 76, '\0'};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
typedef PNG_EXPORT(png_uint_32, (*P_png_set_acTL)) PNGARG((png_structp png_ptr,
|
typedef png_uint_32 (*P_png_set_acTL) (png_structp png_ptr,
|
||||||
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays));
|
png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays);
|
||||||
typedef PNG_EXPORT (void, (*P_png_write_frame_head)) PNGARG((png_structp png_ptr,
|
typedef void (*P_png_write_frame_head) (png_structp png_ptr,
|
||||||
png_infop info_ptr, png_bytepp row_pointers,
|
png_infop info_ptr, png_bytepp row_pointers,
|
||||||
png_uint_32 width, png_uint_32 height,
|
png_uint_32 width, png_uint_32 height,
|
||||||
png_uint_32 x_offset, png_uint_32 y_offset,
|
png_uint_32 x_offset, png_uint_32 y_offset,
|
||||||
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op,
|
||||||
png_byte blend_op));
|
png_byte blend_op);
|
||||||
|
|
||||||
typedef PNG_EXPORT (void, (*P_png_write_frame_tail)) PNGARG((png_structp png_ptr,
|
typedef void (*P_png_write_frame_tail) (png_structp png_ptr,
|
||||||
png_infop info_ptr));
|
png_infop info_ptr);
|
||||||
static P_png_set_acTL apng_set_acTL = NULL;
|
static P_png_set_acTL aPNG_set_acTL = NULL;
|
||||||
static P_png_write_frame_head apng_write_frame_head = NULL;
|
static P_png_write_frame_head aPNG_write_frame_head = NULL;
|
||||||
static P_png_write_frame_tail apng_write_frame_tail = NULL;
|
static P_png_write_frame_tail aPNG_write_frame_tail = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline boolean M_PNGLib(void)
|
static inline boolean M_PNGLib(void)
|
||||||
|
@ -885,7 +886,7 @@ static inline boolean M_PNGLib(void)
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
static void *pnglib = NULL;
|
static void *pnglib = NULL;
|
||||||
if (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail)
|
if (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail)
|
||||||
return true;
|
return true;
|
||||||
if (pnglib)
|
if (pnglib)
|
||||||
return false;
|
return false;
|
||||||
|
@ -905,16 +906,16 @@ static inline boolean M_PNGLib(void)
|
||||||
if (!pnglib)
|
if (!pnglib)
|
||||||
return false;
|
return false;
|
||||||
#ifdef HAVE_SDL
|
#ifdef HAVE_SDL
|
||||||
apng_set_acTL = hwSym("png_set_acTL", pnglib);
|
aPNG_set_acTL = hwSym("png_set_acTL", pnglib);
|
||||||
apng_write_frame_head = hwSym("png_write_frame_head", pnglib);
|
aPNG_write_frame_head = hwSym("png_write_frame_head", pnglib);
|
||||||
apng_write_frame_tail = hwSym("png_write_frame_tail", pnglib);
|
aPNG_write_frame_tail = hwSym("png_write_frame_tail", pnglib);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
apng_set_acTL = GetProcAddress("png_set_acTL", pnglib);
|
aPNG_set_acTL = GetProcAddress("png_set_acTL", pnglib);
|
||||||
apng_write_frame_head = GetProcAddress("png_write_frame_head", pnglib);
|
aPNG_write_frame_head = GetProcAddress("png_write_frame_head", pnglib);
|
||||||
apng_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib);
|
aPNG_write_frame_tail = GetProcAddress("png_write_frame_tail", pnglib);
|
||||||
#endif
|
#endif
|
||||||
return (apng_set_acTL && apng_write_frame_head && apng_write_frame_tail);
|
return (aPNG_set_acTL && aPNG_write_frame_head && aPNG_write_frame_tail);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,11 +929,6 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
||||||
|
|
||||||
apng_frames++;
|
apng_frames++;
|
||||||
|
|
||||||
#ifndef PNG_STATIC
|
|
||||||
if (apng_set_acTL)
|
|
||||||
#endif
|
|
||||||
apng_set_acTL(apng_ptr, apng_info_ptr, apng_frames, 0);
|
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
row_pointers[y] = png_buf;
|
row_pointers[y] = png_buf;
|
||||||
|
@ -940,9 +936,9 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PNG_STATIC
|
#ifndef PNG_STATIC
|
||||||
if (apng_write_frame_head)
|
if (aPNG_write_frame_head)
|
||||||
#endif
|
#endif
|
||||||
apng_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
|
aPNG_write_frame_head(apng_ptr, apng_info_ptr, row_pointers,
|
||||||
vid.width, /* width */
|
vid.width, /* width */
|
||||||
height, /* height */
|
height, /* height */
|
||||||
0, /* x offset */
|
0, /* x offset */
|
||||||
|
@ -955,57 +951,21 @@ static void M_PNGFrame(png_structp png_ptr, png_infop png_info_ptr, png_bytep pn
|
||||||
png_write_image(png_ptr, row_pointers);
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
#ifndef PNG_STATIC
|
#ifndef PNG_STATIC
|
||||||
if (apng_write_frame_tail)
|
if (aPNG_write_frame_tail)
|
||||||
#endif
|
#endif
|
||||||
apng_write_frame_tail(apng_ptr, apng_info_ptr);
|
aPNG_write_frame_tail(apng_ptr, apng_info_ptr);
|
||||||
|
|
||||||
png_free(png_ptr, (png_voidp)row_pointers);
|
png_free(png_ptr, (png_voidp)row_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline boolean M_PNGfind_acTL(void)
|
static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr,
|
||||||
|
apng_infop png_ainfo_ptr)
|
||||||
{
|
{
|
||||||
png_byte cn[8]; // 4 bytes for len then 4 byes for name
|
apng_set_acTL(png_ptr, png_info_ptr, png_ainfo_ptr, apng_frames, 0);
|
||||||
long endpos = ftell(apng_FILE); // not the real end of file, just what of libpng wrote
|
|
||||||
for (fseek(apng_FILE, 0, SEEK_SET); // let go to the start of the file
|
|
||||||
ftell(apng_FILE)+12 < endpos; // let not go over the file bound
|
|
||||||
fseek(apng_FILE, 1, SEEK_CUR) // we went 8 steps back and now we go 1 step forward
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (fread(cn, sizeof(cn), 1, apng_FILE) != 1) // read 8 bytes
|
|
||||||
return false; // failed to read data
|
|
||||||
if (fseek(apng_FILE, -8, SEEK_CUR) != 0) //rewind 8 bytes
|
|
||||||
return false; // failed to rewird
|
|
||||||
if (!png_memcmp(cn+4, acTL_cn, 4)) //cmp for chuck header
|
|
||||||
return true; // found it
|
|
||||||
}
|
|
||||||
return false; // acTL chuck not found
|
|
||||||
}
|
|
||||||
|
|
||||||
static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr)
|
|
||||||
{
|
|
||||||
png_byte data[16];
|
|
||||||
long oldpos;
|
|
||||||
|
|
||||||
#ifndef PNG_STATIC
|
|
||||||
if (apng_set_acTL)
|
|
||||||
#endif
|
|
||||||
apng_set_acTL(png_ptr, png_info_ptr, apng_frames, 0);
|
|
||||||
|
|
||||||
#ifndef NO_PNG_DEBUG
|
#ifndef NO_PNG_DEBUG
|
||||||
png_debug(1, "in png_write_acTL\n");
|
png_debug(1, "in png_write_acTL\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
png_ptr->num_frames_to_write = apng_frames;
|
|
||||||
|
|
||||||
png_save_uint_32(data, apng_frames);
|
|
||||||
png_save_uint_32(data + 4, 0);
|
|
||||||
|
|
||||||
oldpos = ftell(apng_FILE);
|
|
||||||
|
|
||||||
if (M_PNGfind_acTL())
|
|
||||||
png_write_chunk(png_ptr, (png_bytep)acTL_cn, data, (png_size_t)8);
|
|
||||||
|
|
||||||
fseek(apng_FILE, oldpos, SEEK_SET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
|
static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
|
||||||
|
@ -1037,6 +997,16 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apng_ainfo_ptr = apng_create_info_struct(apng_ptr);
|
||||||
|
if (!apng_ainfo_ptr)
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_RENDER, "M_StartMovie: Error on allocate for apng\n");
|
||||||
|
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
|
||||||
|
fclose(apng_FILE);
|
||||||
|
remove(filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
png_init_io(apng_ptr, apng_FILE);
|
png_init_io(apng_ptr, apng_FILE);
|
||||||
|
|
||||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||||
|
@ -1054,12 +1024,11 @@ static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
|
||||||
|
|
||||||
M_PNGText(apng_ptr, apng_info_ptr, true);
|
M_PNGText(apng_ptr, apng_info_ptr, true);
|
||||||
|
|
||||||
#ifndef PNG_STATIC
|
apng_set_set_acTL_fn(apng_ptr, apng_ainfo_ptr, aPNG_set_acTL);
|
||||||
if (apng_set_acTL)
|
|
||||||
#endif
|
|
||||||
apng_set_acTL(apng_ptr, apng_info_ptr, PNG_UINT_31_MAX, 0);
|
|
||||||
|
|
||||||
png_write_info(apng_ptr, apng_info_ptr);
|
apng_set_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr, PNG_UINT_31_MAX, 0);
|
||||||
|
|
||||||
|
apng_write_info(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||||
|
|
||||||
apng_frames = 0;
|
apng_frames = 0;
|
||||||
|
|
||||||
|
@ -1262,8 +1231,8 @@ void M_StopMovie(void)
|
||||||
|
|
||||||
if (apng_frames)
|
if (apng_frames)
|
||||||
{
|
{
|
||||||
M_PNGfix_acTL(apng_ptr, apng_info_ptr);
|
M_PNGfix_acTL(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||||
png_write_end(apng_ptr, apng_info_ptr);
|
apng_write_end(apng_ptr, apng_info_ptr, apng_ainfo_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
|
png_destroy_write_struct(&apng_ptr, &apng_info_ptr);
|
||||||
|
|
|
@ -2756,8 +2756,18 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
|
||||||
if (oldnightstime > 10*TICRATE
|
if (oldnightstime > 10*TICRATE
|
||||||
&& player->nightstime < 10*TICRATE)
|
&& player->nightstime < 10*TICRATE)
|
||||||
{
|
{
|
||||||
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
|
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
#ifdef _WIN32
|
||||||
|
// win32 MIDI volume hack means we cannot fade down the music
|
||||||
|
&& S_MusicType() != MU_MID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
S_FadeMusic(0, 10*MUSICRATE);
|
||||||
|
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2940,7 +2950,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage)
|
||||||
{
|
{
|
||||||
fixed_t fallbackspeed;
|
fixed_t fallbackspeed;
|
||||||
angle_t ang;
|
angle_t ang;
|
||||||
|
@ -3137,8 +3147,13 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
|
||||||
if (oldnightstime > 10*TICRATE
|
if (oldnightstime > 10*TICRATE
|
||||||
&& player->nightstime < 10*TICRATE)
|
&& player->nightstime < 10*TICRATE)
|
||||||
{
|
{
|
||||||
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
|
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
{
|
||||||
|
S_FadeMusic(0, 10*MUSICRATE);
|
||||||
|
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
148
src/p_polyobj.c
148
src/p_polyobj.c
|
@ -28,6 +28,10 @@
|
||||||
#include "r_state.h"
|
#include "r_state.h"
|
||||||
#include "r_defs.h"
|
#include "r_defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define POLYOBJECTS
|
||||||
|
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1150,7 +1154,7 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
|
||||||
//
|
//
|
||||||
// Moves a polyobject on the x-y plane.
|
// Moves a polyobject on the x-y plane.
|
||||||
//
|
//
|
||||||
static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y)
|
static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y, boolean checkmobjs)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
vertex_t vec;
|
vertex_t vec;
|
||||||
|
@ -1171,9 +1175,12 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y)
|
||||||
for (i = 0; i < po->numLines; ++i)
|
for (i = 0; i < po->numLines; ++i)
|
||||||
Polyobj_bboxAdd(po->lines[i]->bbox, &vec);
|
Polyobj_bboxAdd(po->lines[i]->bbox, &vec);
|
||||||
|
|
||||||
// check for blocking things (yes, it needs to be done separately)
|
if (checkmobjs)
|
||||||
for (i = 0; i < po->numLines; ++i)
|
{
|
||||||
hitflags |= Polyobj_clipThings(po, po->lines[i]);
|
// check for blocking things (yes, it needs to be done separately)
|
||||||
|
for (i = 0; i < po->numLines; ++i)
|
||||||
|
hitflags |= Polyobj_clipThings(po, po->lines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (hitflags & 2)
|
if (hitflags & 2)
|
||||||
{
|
{
|
||||||
|
@ -1191,7 +1198,8 @@ static boolean Polyobj_moveXY(polyobj_t *po, fixed_t x, fixed_t y)
|
||||||
po->spawnSpot.x += vec.x;
|
po->spawnSpot.x += vec.x;
|
||||||
po->spawnSpot.y += vec.y;
|
po->spawnSpot.y += vec.y;
|
||||||
|
|
||||||
Polyobj_carryThings(po, x, y);
|
if (checkmobjs)
|
||||||
|
Polyobj_carryThings(po, x, y);
|
||||||
Polyobj_removeFromBlockmap(po); // unlink it from the blockmap
|
Polyobj_removeFromBlockmap(po); // unlink it from the blockmap
|
||||||
Polyobj_removeFromSubsec(po); // unlink it from its subsector
|
Polyobj_removeFromSubsec(po); // unlink it from its subsector
|
||||||
Polyobj_linkToBlockmap(po); // relink to blockmap
|
Polyobj_linkToBlockmap(po); // relink to blockmap
|
||||||
|
@ -1358,7 +1366,7 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
|
||||||
//
|
//
|
||||||
// Rotates a polyobject around its start point.
|
// Rotates a polyobject around its start point.
|
||||||
//
|
//
|
||||||
static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings)
|
static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings, boolean checkmobjs)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
|
@ -1390,11 +1398,14 @@ static boolean Polyobj_rotate(polyobj_t *po, angle_t delta, UINT8 turnthings)
|
||||||
for (i = 0; i < po->numLines; ++i)
|
for (i = 0; i < po->numLines; ++i)
|
||||||
Polyobj_rotateLine(po->lines[i]);
|
Polyobj_rotateLine(po->lines[i]);
|
||||||
|
|
||||||
// check for blocking things
|
if (checkmobjs)
|
||||||
for (i = 0; i < po->numLines; ++i)
|
{
|
||||||
hitflags |= Polyobj_clipThings(po, po->lines[i]);
|
// check for blocking things
|
||||||
|
for (i = 0; i < po->numLines; ++i)
|
||||||
|
hitflags |= Polyobj_clipThings(po, po->lines[i]);
|
||||||
|
|
||||||
Polyobj_rotateThings(po, origin, delta, turnthings);
|
Polyobj_rotateThings(po, origin, delta, turnthings);
|
||||||
|
}
|
||||||
|
|
||||||
if (hitflags & 2)
|
if (hitflags & 2)
|
||||||
{
|
{
|
||||||
|
@ -1610,19 +1621,23 @@ void Polyobj_InitLevel(void)
|
||||||
// Called when a savegame is being loaded. Rotates and translates an
|
// Called when a savegame is being loaded. Rotates and translates an
|
||||||
// existing polyobject to its position when the game was saved.
|
// existing polyobject to its position when the game was saved.
|
||||||
//
|
//
|
||||||
|
// Monster Iestyn 05/04/19: Please do not interact with mobjs! You
|
||||||
|
// can cause I_Error crashes that way, and all the important mobjs are
|
||||||
|
// going to be deleted afterwards anyway.
|
||||||
|
//
|
||||||
void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y)
|
void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y)
|
||||||
{
|
{
|
||||||
fixed_t dx, dy;
|
fixed_t dx, dy;
|
||||||
|
|
||||||
// first, rotate to the saved angle
|
// first, rotate to the saved angle
|
||||||
Polyobj_rotate(po, angle, false);
|
Polyobj_rotate(po, angle, false, false);
|
||||||
|
|
||||||
// determine component distances to translate
|
// determine component distances to translate
|
||||||
dx = x - po->spawnSpot.x;
|
dx = x - po->spawnSpot.x;
|
||||||
dy = y - po->spawnSpot.y;
|
dy = y - po->spawnSpot.y;
|
||||||
|
|
||||||
// translate
|
// translate
|
||||||
Polyobj_moveXY(po, dx, dy);
|
Polyobj_moveXY(po, dx, dy, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thinker Functions
|
// Thinker Functions
|
||||||
|
@ -1662,7 +1677,7 @@ void T_PolyObjRotate(polyrotate_t *th)
|
||||||
|
|
||||||
// rotate by 'speed' angle per frame
|
// rotate by 'speed' angle per frame
|
||||||
// if distance == -1, this polyobject rotates perpetually
|
// if distance == -1, this polyobject rotates perpetually
|
||||||
if (Polyobj_rotate(po, th->speed, th->turnobjs) && th->distance != -1)
|
if (Polyobj_rotate(po, th->speed, th->turnobjs, true) && th->distance != -1)
|
||||||
{
|
{
|
||||||
INT32 avel = abs(th->speed);
|
INT32 avel = abs(th->speed);
|
||||||
|
|
||||||
|
@ -1746,7 +1761,7 @@ void T_PolyObjMove(polymove_t *th)
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the polyobject one step along its movement angle
|
// move the polyobject one step along its movement angle
|
||||||
if (Polyobj_moveXY(po, th->momx, th->momy))
|
if (Polyobj_moveXY(po, th->momx, th->momy, true))
|
||||||
{
|
{
|
||||||
INT32 avel = abs(th->speed);
|
INT32 avel = abs(th->speed);
|
||||||
|
|
||||||
|
@ -1860,7 +1875,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
fixed_t diffz;
|
fixed_t diffz;
|
||||||
amtx = (target->x - th->diffx) - po->centerPt.x;
|
amtx = (target->x - th->diffx) - po->centerPt.x;
|
||||||
amty = (target->y - th->diffy) - po->centerPt.y;
|
amty = (target->y - th->diffy) - po->centerPt.y;
|
||||||
Polyobj_moveXY(po, amtx, amty);
|
Polyobj_moveXY(po, amtx, amty, true);
|
||||||
// TODO: use T_MovePlane
|
// TODO: use T_MovePlane
|
||||||
amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2;
|
amtz = (po->lines[0]->backsector->ceilingheight - po->lines[0]->backsector->floorheight)/2;
|
||||||
diffz = po->lines[0]->backsector->floorheight - (target->z - amtz);
|
diffz = po->lines[0]->backsector->floorheight - (target->z - amtz);
|
||||||
|
@ -1876,7 +1891,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
if (po->isBad)
|
if (po->isBad)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Polyobj_moveXY(po, amtx, amty);
|
Polyobj_moveXY(po, amtx, amty, true);
|
||||||
// TODO: use T_MovePlane
|
// TODO: use T_MovePlane
|
||||||
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
po->lines[0]->backsector->floorheight += diffz; // move up/down by same amount as the parent did
|
||||||
po->lines[0]->backsector->ceilingheight += diffz;
|
po->lines[0]->backsector->ceilingheight += diffz;
|
||||||
|
@ -2039,7 +2054,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the polyobject
|
// Move the polyobject
|
||||||
Polyobj_moveXY(po, momx, momy);
|
Polyobj_moveXY(po, momx, momy, true);
|
||||||
// TODO: use T_MovePlane
|
// TODO: use T_MovePlane
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
po->lines[0]->backsector->floorheight += momz;
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
po->lines[0]->backsector->ceilingheight += momz;
|
||||||
|
@ -2054,7 +2069,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
|
||||||
if (po->isBad)
|
if (po->isBad)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Polyobj_moveXY(po, momx, momy);
|
Polyobj_moveXY(po, momx, momy, true);
|
||||||
// TODO: use T_MovePlane
|
// TODO: use T_MovePlane
|
||||||
po->lines[0]->backsector->floorheight += momz;
|
po->lines[0]->backsector->floorheight += momz;
|
||||||
po->lines[0]->backsector->ceilingheight += momz;
|
po->lines[0]->backsector->ceilingheight += momz;
|
||||||
|
@ -2103,7 +2118,7 @@ void T_PolyDoorSlide(polyslidedoor_t *th)
|
||||||
}
|
}
|
||||||
|
|
||||||
// move the polyobject one step along its movement angle
|
// move the polyobject one step along its movement angle
|
||||||
if (Polyobj_moveXY(po, th->momx, th->momy))
|
if (Polyobj_moveXY(po, th->momx, th->momy, true))
|
||||||
{
|
{
|
||||||
INT32 avel = abs(th->speed);
|
INT32 avel = abs(th->speed);
|
||||||
|
|
||||||
|
@ -2209,7 +2224,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
|
||||||
|
|
||||||
// rotate by 'speed' angle per frame
|
// rotate by 'speed' angle per frame
|
||||||
// if distance == -1, this polyobject rotates perpetually
|
// if distance == -1, this polyobject rotates perpetually
|
||||||
if (Polyobj_rotate(po, th->speed, false) && th->distance != -1)
|
if (Polyobj_rotate(po, th->speed, false, true) && th->distance != -1)
|
||||||
{
|
{
|
||||||
INT32 avel = abs(th->speed);
|
INT32 avel = abs(th->speed);
|
||||||
|
|
||||||
|
@ -2265,7 +2280,7 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// T_PolyObjDisplace: shift a polyobject based on a control sector's heights. -Red
|
// T_PolyObjDisplace: shift a polyobject based on a control sector's heights.
|
||||||
void T_PolyObjDisplace(polydisplace_t *th)
|
void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
{
|
{
|
||||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
@ -2274,10 +2289,10 @@ void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
|
|
||||||
if (!po)
|
if (!po)
|
||||||
#ifdef RANGECHECK
|
#ifdef RANGECHECK
|
||||||
I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum);
|
I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum);
|
CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||||
P_RemoveThinkerDelayed(&th->thinker);
|
P_RemoveThinkerDelayed(&th->thinker);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2301,7 +2316,46 @@ void T_PolyObjDisplace(polydisplace_t *th)
|
||||||
dx = FixedMul(th->dx, delta);
|
dx = FixedMul(th->dx, delta);
|
||||||
dy = FixedMul(th->dy, delta);
|
dy = FixedMul(th->dy, delta);
|
||||||
|
|
||||||
if (Polyobj_moveXY(po, dx, dy))
|
if (Polyobj_moveXY(po, dx, dy, true))
|
||||||
|
th->oldHeights = newheights;
|
||||||
|
}
|
||||||
|
|
||||||
|
// T_PolyObjRotDisplace: rotate a polyobject based on a control sector's heights.
|
||||||
|
void T_PolyObjRotDisplace(polyrotdisplace_t *th)
|
||||||
|
{
|
||||||
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
fixed_t newheights, delta;
|
||||||
|
fixed_t rotangle;
|
||||||
|
|
||||||
|
if (!po)
|
||||||
|
#ifdef RANGECHECK
|
||||||
|
I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
|
||||||
|
P_RemoveThinkerDelayed(&th->thinker);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// check for displacement due to override and reattach when possible
|
||||||
|
if (po->thinker == NULL)
|
||||||
|
{
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
// reset polyobject's thrust
|
||||||
|
po->thrust = FRACUNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
newheights = th->controlSector->floorheight+th->controlSector->ceilingheight;
|
||||||
|
delta = newheights-th->oldHeights;
|
||||||
|
|
||||||
|
if (!delta)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rotangle = FixedMul(th->rotscale, delta);
|
||||||
|
|
||||||
|
if (Polyobj_rotate(po, FixedAngle(rotangle), th->turnobjs, true))
|
||||||
th->oldHeights = newheights;
|
th->oldHeights = newheights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2764,6 +2818,52 @@ INT32 EV_DoPolyObjDisplace(polydisplacedata_t *prdata)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *prdata)
|
||||||
|
{
|
||||||
|
polyobj_t *po;
|
||||||
|
polyobj_t *oldpo;
|
||||||
|
polyrotdisplace_t *th;
|
||||||
|
INT32 start;
|
||||||
|
|
||||||
|
if (!(po = Polyobj_GetForNum(prdata->polyObjNum)))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", prdata->polyObjNum);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't allow line actions to affect bad polyobjects
|
||||||
|
if (po->isBad)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// create a new thinker
|
||||||
|
th = Z_Malloc(sizeof(polyrotdisplace_t), PU_LEVSPEC, NULL);
|
||||||
|
th->thinker.function.acp1 = (actionf_p1)T_PolyObjRotDisplace;
|
||||||
|
PolyObj_AddThinker(&th->thinker);
|
||||||
|
po->thinker = &th->thinker;
|
||||||
|
|
||||||
|
// set fields
|
||||||
|
th->polyObjNum = prdata->polyObjNum;
|
||||||
|
|
||||||
|
th->controlSector = prdata->controlSector;
|
||||||
|
th->oldHeights = th->controlSector->floorheight+th->controlSector->ceilingheight;
|
||||||
|
|
||||||
|
th->rotscale = prdata->rotscale;
|
||||||
|
th->turnobjs = prdata->turnobjs;
|
||||||
|
|
||||||
|
oldpo = po;
|
||||||
|
|
||||||
|
// apply action to mirroring polyobjects as well
|
||||||
|
start = 0;
|
||||||
|
while ((po = Polyobj_GetChild(oldpo, &start)))
|
||||||
|
{
|
||||||
|
prdata->polyObjNum = po->id; // change id to match child polyobject's
|
||||||
|
EV_DoPolyObjRotDisplace(prdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
// action was successful
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void T_PolyObjFlag(polymove_t *th)
|
void T_PolyObjFlag(polymove_t *th)
|
||||||
{
|
{
|
||||||
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
|
||||||
|
|
|
@ -207,6 +207,17 @@ typedef struct polydisplace_s
|
||||||
fixed_t oldHeights;
|
fixed_t oldHeights;
|
||||||
} polydisplace_t;
|
} polydisplace_t;
|
||||||
|
|
||||||
|
typedef struct polyrotdisplace_s
|
||||||
|
{
|
||||||
|
thinker_t thinker; // must be first
|
||||||
|
|
||||||
|
INT32 polyObjNum;
|
||||||
|
struct sector_s *controlSector;
|
||||||
|
fixed_t rotscale;
|
||||||
|
UINT8 turnobjs;
|
||||||
|
fixed_t oldHeights;
|
||||||
|
} polyrotdisplace_t;
|
||||||
|
|
||||||
typedef struct polyfade_s
|
typedef struct polyfade_s
|
||||||
{
|
{
|
||||||
thinker_t thinker; // must be first
|
thinker_t thinker; // must be first
|
||||||
|
@ -280,6 +291,14 @@ typedef struct polydisplacedata_s
|
||||||
fixed_t dy;
|
fixed_t dy;
|
||||||
} polydisplacedata_t;
|
} polydisplacedata_t;
|
||||||
|
|
||||||
|
typedef struct polyrotdisplacedata_s
|
||||||
|
{
|
||||||
|
INT32 polyObjNum;
|
||||||
|
struct sector_s *controlSector;
|
||||||
|
fixed_t rotscale;
|
||||||
|
UINT8 turnobjs;
|
||||||
|
} polyrotdisplacedata_t;
|
||||||
|
|
||||||
typedef struct polyfadedata_s
|
typedef struct polyfadedata_s
|
||||||
{
|
{
|
||||||
INT32 polyObjNum;
|
INT32 polyObjNum;
|
||||||
|
@ -310,6 +329,7 @@ void T_PolyObjWaypoint (polywaypoint_t *);
|
||||||
void T_PolyDoorSlide(polyslidedoor_t *);
|
void T_PolyDoorSlide(polyslidedoor_t *);
|
||||||
void T_PolyDoorSwing(polyswingdoor_t *);
|
void T_PolyDoorSwing(polyswingdoor_t *);
|
||||||
void T_PolyObjDisplace (polydisplace_t *);
|
void T_PolyObjDisplace (polydisplace_t *);
|
||||||
|
void T_PolyObjRotDisplace (polyrotdisplace_t *);
|
||||||
void T_PolyObjFlag (polymove_t *);
|
void T_PolyObjFlag (polymove_t *);
|
||||||
void T_PolyObjFade (polyfade_t *);
|
void T_PolyObjFade (polyfade_t *);
|
||||||
|
|
||||||
|
@ -318,6 +338,7 @@ INT32 EV_DoPolyObjMove(polymovedata_t *);
|
||||||
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *);
|
||||||
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
INT32 EV_DoPolyObjRotate(polyrotdata_t *);
|
||||||
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
INT32 EV_DoPolyObjDisplace(polydisplacedata_t *);
|
||||||
|
INT32 EV_DoPolyObjRotDisplace(polyrotdisplacedata_t *);
|
||||||
INT32 EV_DoPolyObjFlag(struct line_s *);
|
INT32 EV_DoPolyObjFlag(struct line_s *);
|
||||||
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
INT32 EV_DoPolyObjFade(polyfadedata_t *);
|
||||||
|
|
||||||
|
|
|
@ -1312,6 +1312,7 @@ typedef enum
|
||||||
tc_polyswingdoor,
|
tc_polyswingdoor,
|
||||||
tc_polyflag,
|
tc_polyflag,
|
||||||
tc_polydisplace,
|
tc_polydisplace,
|
||||||
|
tc_polyrotdisplace,
|
||||||
tc_polyfade,
|
tc_polyfade,
|
||||||
#endif
|
#endif
|
||||||
tc_end
|
tc_end
|
||||||
|
@ -2088,6 +2089,17 @@ static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
WRITEFIXED(save_p, ht->oldHeights);
|
WRITEFIXED(save_p, ht->oldHeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SavePolyrotdisplaceThinker(const thinker_t *th, const UINT8 type)
|
||||||
|
{
|
||||||
|
const polyrotdisplace_t *ht = (const void *)th;
|
||||||
|
WRITEUINT8(save_p, type);
|
||||||
|
WRITEINT32(save_p, ht->polyObjNum);
|
||||||
|
WRITEUINT32(save_p, SaveSector(ht->controlSector));
|
||||||
|
WRITEFIXED(save_p, ht->rotscale);
|
||||||
|
WRITEUINT8(save_p, ht->turnobjs);
|
||||||
|
WRITEFIXED(save_p, ht->oldHeights);
|
||||||
|
}
|
||||||
|
|
||||||
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
|
||||||
{
|
{
|
||||||
const polyfade_t *ht = (const void *)th;
|
const polyfade_t *ht = (const void *)th;
|
||||||
|
@ -2333,6 +2345,11 @@ static void P_NetArchiveThinkers(void)
|
||||||
SavePolydisplaceThinker(th, tc_polydisplace);
|
SavePolydisplaceThinker(th, tc_polydisplace);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace)
|
||||||
|
{
|
||||||
|
SavePolyrotdisplaceThinker(th, tc_polyrotdisplace);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
|
||||||
{
|
{
|
||||||
SavePolyfadeThinker(th, tc_polyfade);
|
SavePolyfadeThinker(th, tc_polyfade);
|
||||||
|
@ -3217,6 +3234,18 @@ static inline void LoadPolydisplaceThinker(actionf_p1 thinker)
|
||||||
P_AddThinker(&ht->thinker);
|
P_AddThinker(&ht->thinker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void LoadPolyrotdisplaceThinker(actionf_p1 thinker)
|
||||||
|
{
|
||||||
|
polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
|
||||||
|
ht->thinker.function.acp1 = thinker;
|
||||||
|
ht->polyObjNum = READINT32(save_p);
|
||||||
|
ht->controlSector = LoadSector(READUINT32(save_p));
|
||||||
|
ht->rotscale = READFIXED(save_p);
|
||||||
|
ht->turnobjs = READUINT8(save_p);
|
||||||
|
ht->oldHeights = READFIXED(save_p);
|
||||||
|
P_AddThinker(&ht->thinker);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// LoadPolyfadeThinker
|
// LoadPolyfadeThinker
|
||||||
//
|
//
|
||||||
|
@ -3446,6 +3475,10 @@ static void P_NetUnArchiveThinkers(void)
|
||||||
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case tc_polyrotdisplace:
|
||||||
|
LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace);
|
||||||
|
break;
|
||||||
|
|
||||||
case tc_polyfade:
|
case tc_polyfade:
|
||||||
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -212,6 +212,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||||
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
|
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
|
||||||
mapheaderinfo[num]->musname[6] = 0;
|
mapheaderinfo[num]->musname[6] = 0;
|
||||||
mapheaderinfo[num]->mustrack = 0;
|
mapheaderinfo[num]->mustrack = 0;
|
||||||
|
mapheaderinfo[num]->muspos = 0;
|
||||||
|
mapheaderinfo[num]->musinterfadeout = 0;
|
||||||
|
mapheaderinfo[num]->musintername[0] = '\0';
|
||||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||||
mapheaderinfo[num]->weather = 0;
|
mapheaderinfo[num]->weather = 0;
|
||||||
mapheaderinfo[num]->skynum = 1;
|
mapheaderinfo[num]->skynum = 1;
|
||||||
|
@ -1428,19 +1431,33 @@ static void P_LoadRawSideDefs2(void *data)
|
||||||
{
|
{
|
||||||
M_Memcpy(process,msd->bottomtexture,8);
|
M_Memcpy(process,msd->bottomtexture,8);
|
||||||
process[8] = '\0';
|
process[8] = '\0';
|
||||||
sd->bottomtexture = get_number(process)-1;
|
sd->bottomtexture = get_number(process);
|
||||||
}
|
}
|
||||||
M_Memcpy(process,msd->toptexture,8);
|
|
||||||
process[8] = '\0';
|
|
||||||
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
|
|
||||||
|
|
||||||
// If they type in O_ or D_ and their music name, just shrug,
|
if (!(msd->midtexture[0] == '-' && msd->midtexture[1] == '\0') || msd->midtexture[1] != '\0')
|
||||||
// then copy the rest instead.
|
{
|
||||||
if ((process[0] == 'O' || process[0] == 'D') && process[7])
|
M_Memcpy(process,msd->midtexture,8);
|
||||||
M_Memcpy(sd->text, process+2, 6);
|
process[8] = '\0';
|
||||||
else // Assume it's a proper music name.
|
sd->midtexture = get_number(process);
|
||||||
M_Memcpy(sd->text, process, 6);
|
}
|
||||||
sd->text[6] = 0;
|
|
||||||
|
// always process if back sidedef, because we need that - symbol
|
||||||
|
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
|
||||||
|
if (i == 1 || msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
|
||||||
|
{
|
||||||
|
M_Memcpy(process,msd->toptexture,8);
|
||||||
|
process[8] = '\0';
|
||||||
|
|
||||||
|
// If they type in O_ or D_ and their music name, just shrug,
|
||||||
|
// then copy the rest instead.
|
||||||
|
if ((process[0] == 'O' || process[0] == 'D') && process[7])
|
||||||
|
M_Memcpy(sd->text, process+2, 6);
|
||||||
|
else // Assume it's a proper music name.
|
||||||
|
M_Memcpy(sd->text, process, 6);
|
||||||
|
sd->text[6] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sd->text[0] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -264,7 +264,7 @@ void P_SpawnSlope_Line(int linenum)
|
||||||
|
|
||||||
if(!line->frontsector || !line->backsector)
|
if(!line->frontsector || !line->backsector)
|
||||||
{
|
{
|
||||||
CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n");
|
CONS_Debug(DBG_SETUP, "P_SpawnSlope_Line used on a line without two sides. (line number %i)\n", linenum);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
243
src/p_spec.c
243
src/p_spec.c
|
@ -1412,6 +1412,34 @@ static boolean PolyDisplace(line_t *line)
|
||||||
return EV_DoPolyObjDisplace(&pdd);
|
return EV_DoPolyObjDisplace(&pdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Similar to PolyDisplace().
|
||||||
|
*/
|
||||||
|
static boolean PolyRotDisplace(line_t *line)
|
||||||
|
{
|
||||||
|
polyrotdisplacedata_t pdd;
|
||||||
|
fixed_t anginter, distinter;
|
||||||
|
|
||||||
|
pdd.polyObjNum = line->tag;
|
||||||
|
pdd.controlSector = line->frontsector;
|
||||||
|
|
||||||
|
// Rotate 'anginter' interval for each 'distinter' interval from the control sector.
|
||||||
|
// Use default values if not provided as fallback.
|
||||||
|
anginter = sides[line->sidenum[0]].rowoffset ? sides[line->sidenum[0]].rowoffset : 90*FRACUNIT;
|
||||||
|
distinter = sides[line->sidenum[0]].textureoffset ? sides[line->sidenum[0]].textureoffset : 128*FRACUNIT;
|
||||||
|
pdd.rotscale = FixedDiv(anginter, distinter);
|
||||||
|
|
||||||
|
// Same behavior as other rotators when carrying things.
|
||||||
|
if (line->flags & ML_NOCLIMB)
|
||||||
|
pdd.turnobjs = 0;
|
||||||
|
else if (line->flags & ML_EFFECT4)
|
||||||
|
pdd.turnobjs = 2;
|
||||||
|
else
|
||||||
|
pdd.turnobjs = 1;
|
||||||
|
|
||||||
|
return EV_DoPolyObjRotDisplace(&pdd);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ifdef POLYOBJECTS
|
#endif // ifdef POLYOBJECTS
|
||||||
|
|
||||||
/** Changes a sector's tag.
|
/** Changes a sector's tag.
|
||||||
|
@ -2593,16 +2621,68 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
|
||||||
// console player only unless NOCLIMB is set
|
// console player only unless NOCLIMB is set
|
||||||
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
|
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
|
||||||
{
|
{
|
||||||
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
|
boolean musicsame = (!sides[line->sidenum[0]].text[0] || !strnicmp(sides[line->sidenum[0]].text, S_MusicName(), 7));
|
||||||
|
UINT16 tracknum = (UINT16)max(sides[line->sidenum[0]].bottomtexture, 0);
|
||||||
|
INT32 position = (INT32)max(sides[line->sidenum[0]].midtexture, 0);
|
||||||
|
UINT32 prefadems = (UINT32)max(sides[line->sidenum[0]].textureoffset >> FRACBITS, 0);
|
||||||
|
UINT32 postfadems = (UINT32)max(sides[line->sidenum[0]].rowoffset >> FRACBITS, 0);
|
||||||
|
UINT8 fadetarget = (UINT8)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].textureoffset >> FRACBITS : 0, 0);
|
||||||
|
INT16 fadesource = (INT16)max((line->sidenum[1] != 0xffff) ? sides[line->sidenum[1]].rowoffset >> FRACBITS : -1, -1);
|
||||||
|
|
||||||
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
|
// Seek offset from current song position
|
||||||
mapmusname[6] = 0;
|
if (line->flags & ML_EFFECT1)
|
||||||
|
{
|
||||||
|
// adjust for loop point if subtracting
|
||||||
|
if (position < 0 && S_GetMusicLength() &&
|
||||||
|
S_GetMusicPosition() > S_GetMusicLoopPoint() &&
|
||||||
|
S_GetMusicPosition() + position < S_GetMusicLoopPoint())
|
||||||
|
position = max(S_GetMusicLength() - (S_GetMusicLoopPoint() - (S_GetMusicPosition() + position)), 0);
|
||||||
|
else
|
||||||
|
position = max(S_GetMusicPosition() + position, 0);
|
||||||
|
}
|
||||||
|
|
||||||
mapmusflags = tracknum & MUSIC_TRACKMASK;
|
// Fade current music to target volume (if music won't be changed)
|
||||||
if (!(line->flags & ML_BLOCKMONSTERS))
|
if ((line->flags & ML_EFFECT2) && fadetarget && musicsame)
|
||||||
mapmusflags |= MUSIC_RELOADRESET;
|
{
|
||||||
|
// 0 fadesource means fade from current volume.
|
||||||
|
// meaning that we can't specify volume 0 as the source volume -- this starts at 1.
|
||||||
|
if (!fadesource)
|
||||||
|
fadesource = -1;
|
||||||
|
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
|
if (!postfadems)
|
||||||
|
S_SetInternalMusicVolume(fadetarget);
|
||||||
|
else
|
||||||
|
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
|
||||||
|
|
||||||
|
if (position)
|
||||||
|
S_SetMusicPosition(position);
|
||||||
|
}
|
||||||
|
// Change the music and apply position/fade operations
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
|
||||||
|
mapmusname[6] = 0;
|
||||||
|
|
||||||
|
mapmusflags = tracknum & MUSIC_TRACKMASK;
|
||||||
|
if (!(line->flags & ML_BLOCKMONSTERS))
|
||||||
|
mapmusflags |= MUSIC_RELOADRESET;
|
||||||
|
if (line->flags & ML_BOUNCY)
|
||||||
|
mapmusflags |= MUSIC_FORCERESET;
|
||||||
|
|
||||||
|
mapmusposition = position;
|
||||||
|
|
||||||
|
S_ChangeMusicEx(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4), position,
|
||||||
|
!(line->flags & ML_EFFECT2) ? prefadems : 0,
|
||||||
|
!(line->flags & ML_EFFECT2) ? postfadems : 0);
|
||||||
|
|
||||||
|
if ((line->flags & ML_EFFECT2) && fadetarget)
|
||||||
|
{
|
||||||
|
if (!postfadems)
|
||||||
|
S_SetInternalMusicVolume(fadetarget);
|
||||||
|
else
|
||||||
|
S_FadeMusicFromVolume(fadetarget, fadesource, postfadems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
|
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
|
||||||
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
|
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
|
||||||
|
@ -7311,6 +7391,10 @@ void P_SpawnSpecials(INT32 fromnetsave)
|
||||||
case 31: // Polyobj_Displace
|
case 31: // Polyobj_Displace
|
||||||
PolyDisplace(&lines[i]);
|
PolyDisplace(&lines[i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 32: // Polyobj_RotDisplace
|
||||||
|
PolyRotDisplace(&lines[i]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -7654,11 +7738,22 @@ static void P_SpawnScrollers(void)
|
||||||
|
|
||||||
for (i = 0; i < numlines; i++, l++)
|
for (i = 0; i < numlines; i++, l++)
|
||||||
{
|
{
|
||||||
fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling
|
fixed_t dx = l->dx; // direction and speed of scrolling
|
||||||
fixed_t dy = l->dy >> SCROLL_SHIFT;
|
fixed_t dy = l->dy;
|
||||||
INT32 control = -1, accel = 0; // no control sector or acceleration
|
INT32 control = -1, accel = 0; // no control sector or acceleration
|
||||||
INT32 special = l->special;
|
INT32 special = l->special;
|
||||||
|
|
||||||
|
// If front texture X offset provided, override the amount with it.
|
||||||
|
if (sides[l->sidenum[0]].textureoffset != 0)
|
||||||
|
{
|
||||||
|
fixed_t len = sides[l->sidenum[0]].textureoffset;
|
||||||
|
fixed_t h = FixedHypot(dx, dy);
|
||||||
|
dx = FixedMul(FixedDiv(dx, h), len);
|
||||||
|
dy = FixedMul(FixedDiv(dy, h), len);
|
||||||
|
}
|
||||||
|
dx = dx >> SCROLL_SHIFT;
|
||||||
|
dy = dy >> SCROLL_SHIFT;
|
||||||
|
|
||||||
// These types are same as the ones they get set to except that the
|
// These types are same as the ones they get set to except that the
|
||||||
// first side's sector's heights cause scrolling when they change, and
|
// first side's sector's heights cause scrolling when they change, and
|
||||||
// this linedef controls the direction and speed of the scrolling. The
|
// this linedef controls the direction and speed of the scrolling. The
|
||||||
|
@ -7693,8 +7788,14 @@ static void P_SpawnScrollers(void)
|
||||||
|
|
||||||
case 513: // scroll effect ceiling
|
case 513: // scroll effect ceiling
|
||||||
case 533: // scroll and carry objects on ceiling
|
case 533: // scroll and carry objects on ceiling
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
if (l->tag == 0)
|
||||||
Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
Add_Scroller(sc_ceiling, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
|
Add_Scroller(sc_ceiling, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
||||||
|
}
|
||||||
|
|
||||||
if (special != 533)
|
if (special != 533)
|
||||||
break;
|
break;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
@ -7702,14 +7803,26 @@ static void P_SpawnScrollers(void)
|
||||||
case 523: // carry objects on ceiling
|
case 523: // carry objects on ceiling
|
||||||
dx = FixedMul(dx, CARRYFACTOR);
|
dx = FixedMul(dx, CARRYFACTOR);
|
||||||
dy = FixedMul(dy, CARRYFACTOR);
|
dy = FixedMul(dy, CARRYFACTOR);
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
if (l->tag == 0)
|
||||||
|
Add_Scroller(sc_carry_ceiling, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
|
Add_Scroller(sc_carry_ceiling, dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 510: // scroll effect floor
|
case 510: // scroll effect floor
|
||||||
case 530: // scroll and carry objects on floor
|
case 530: // scroll and carry objects on floor
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
if (l->tag == 0)
|
||||||
Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
Add_Scroller(sc_floor, -dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
|
Add_Scroller(sc_floor, -dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
||||||
|
}
|
||||||
|
|
||||||
if (special != 530)
|
if (special != 530)
|
||||||
break;
|
break;
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
|
@ -7717,8 +7830,14 @@ static void P_SpawnScrollers(void)
|
||||||
case 520: // carry objects on floor
|
case 520: // carry objects on floor
|
||||||
dx = FixedMul(dx, CARRYFACTOR);
|
dx = FixedMul(dx, CARRYFACTOR);
|
||||||
dy = FixedMul(dy, CARRYFACTOR);
|
dy = FixedMul(dy, CARRYFACTOR);
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
if (l->tag == 0)
|
||||||
|
Add_Scroller(sc_carry, dx, dy, control, l->frontsector - sectors, accel, l->flags & ML_NOCLIMB);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
|
Add_Scroller(sc_carry, dx, dy, control, s, accel, l->flags & ML_NOCLIMB);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// scroll wall according to linedef
|
// scroll wall according to linedef
|
||||||
|
@ -9081,43 +9200,77 @@ static void P_SpawnPushers(void)
|
||||||
line_t *l = lines;
|
line_t *l = lines;
|
||||||
register INT32 s;
|
register INT32 s;
|
||||||
mobj_t *thing;
|
mobj_t *thing;
|
||||||
|
pushertype_e pushertype;
|
||||||
|
fixed_t dx, dy;
|
||||||
|
|
||||||
for (i = 0; i < numlines; i++, l++)
|
for (i = 0; i < numlines; i++, l++)
|
||||||
|
{
|
||||||
switch (l->special)
|
switch (l->special)
|
||||||
{
|
{
|
||||||
case 541: // wind
|
case 541: // wind
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
pushertype = p_wind;
|
||||||
Add_Pusher(p_wind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
break;
|
||||||
break;
|
|
||||||
case 544: // current
|
case 544: // current
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
pushertype = p_current;
|
||||||
Add_Pusher(p_current, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
break;
|
||||||
break;
|
case 547: // push/pull
|
||||||
case 547: // push/pull
|
if (l->tag == 0)
|
||||||
|
{
|
||||||
|
s = l->frontsector - sectors;
|
||||||
|
if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect
|
||||||
|
Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
||||||
|
}
|
||||||
|
else
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
{
|
{
|
||||||
thing = P_GetPushThing(s);
|
if ((thing = P_GetPushThing(s)) != NULL) // No MT_P* means no effect
|
||||||
if (thing) // No MT_P* means no effect
|
|
||||||
Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
Add_Pusher(p_push, l->dx, l->dy, thing, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 545: // current up
|
continue;
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Pusher(p_upcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
case 545: // current up
|
||||||
break;
|
pushertype = p_upcurrent;
|
||||||
case 546: // current down
|
break;
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Pusher(p_downcurrent, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
case 546: // current down
|
||||||
break;
|
pushertype = p_downcurrent;
|
||||||
case 542: // wind up
|
break;
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Pusher(p_upwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
case 542: // wind up
|
||||||
break;
|
pushertype = p_upwind;
|
||||||
case 543: // wind down
|
break;
|
||||||
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
|
||||||
Add_Pusher(p_downwind, l->dx, l->dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
case 543: // wind down
|
||||||
break;
|
pushertype = p_downwind;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dx = l->dx;
|
||||||
|
dy = l->dy;
|
||||||
|
|
||||||
|
// Obtain versor and scale it up according to texture offset, if provided; line length is ignored in this case.
|
||||||
|
|
||||||
|
if (sides[l->sidenum[0]].textureoffset != 0)
|
||||||
|
{
|
||||||
|
fixed_t len = sides[l->sidenum[0]].textureoffset;
|
||||||
|
fixed_t h = FixedHypot(dx, dy);
|
||||||
|
dx = FixedMul(FixedDiv(dx, h), len);
|
||||||
|
dy = FixedMul(FixedDiv(dy, h), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->tag == 0)
|
||||||
|
Add_Pusher(pushertype, dx, dy, NULL, l->frontsector - sectors, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;)
|
||||||
|
Add_Pusher(pushertype, dx, dy, NULL, s, -1, l->flags & ML_NOCLIMB, l->flags & ML_EFFECT4);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void P_SearchForDisableLinedefs(void)
|
static void P_SearchForDisableLinedefs(void)
|
||||||
|
|
63
src/p_user.c
63
src/p_user.c
|
@ -629,6 +629,14 @@ static void P_DeNightserizePlayer(player_t *player)
|
||||||
player->marescore = player->spheres =\
|
player->marescore = player->spheres =\
|
||||||
player->rings = 0;
|
player->rings = 0;
|
||||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
|
||||||
|
|
||||||
|
// Reset music to beginning if MIXNIGHTSCOUNTDOWN
|
||||||
|
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
|
#ifdef _WIN32
|
||||||
|
&& S_MusicType() != MU_MID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
S_SetMusicPosition(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -639,7 +647,24 @@ static void P_DeNightserizePlayer(player_t *player)
|
||||||
player->oldscale = 0;
|
player->oldscale = 0;
|
||||||
|
|
||||||
// Restore from drowning music
|
// Restore from drowning music
|
||||||
P_RestoreMusic(player);
|
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
|
#ifdef _WIN32
|
||||||
|
&& S_MusicType() != MU_MID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
S_StopSoundByNum(sfx_timeup);
|
||||||
|
S_StopFadingMusic();
|
||||||
|
S_SetInternalMusicVolume(100);
|
||||||
|
|
||||||
|
// Reset the music if you did not destroy all the capsules, because you failed.
|
||||||
|
// Why make the all-capsules exception: because it's your reward for nearly finishing the level!
|
||||||
|
// (unless the player auto-loses upon denightserizing; for death case, see above.)
|
||||||
|
if (P_FindLowestMare() != UINT8_MAX || G_IsSpecialStage(gamemap))
|
||||||
|
S_SetMusicPosition(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
P_RestoreMusic(player);
|
||||||
|
|
||||||
P_RunDeNightserizeExecutors(player->mo);
|
P_RunDeNightserizeExecutors(player->mo);
|
||||||
}
|
}
|
||||||
|
@ -687,7 +712,16 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
|
||||||
player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE;
|
player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE;
|
||||||
player->bonustime = false;
|
player->bonustime = false;
|
||||||
|
|
||||||
P_RestoreMusic(player);
|
// Restore from drowning music
|
||||||
|
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
|
{
|
||||||
|
S_StopSoundByNum(sfx_timeup);
|
||||||
|
S_StopFadingMusic();
|
||||||
|
S_SetInternalMusicVolume(100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
P_RestoreMusic(player);
|
||||||
|
|
||||||
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS1);
|
P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS1);
|
||||||
|
|
||||||
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
if (gametype == GT_RACE || gametype == GT_COMPETITION)
|
||||||
|
@ -1292,13 +1326,13 @@ void P_RestoreMusic(player_t *player)
|
||||||
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
|
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
|
||||||
{
|
{
|
||||||
S_SpeedMusic(1.4f);
|
S_SpeedMusic(1.4f);
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
S_ChangeMusicInternal("_shoes", true);
|
S_ChangeMusicInternal("_shoes", true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -6344,14 +6378,18 @@ static void P_NiGHTSMovement(player_t *player)
|
||||||
{
|
{
|
||||||
P_DeNightserizePlayer(player);
|
P_DeNightserizePlayer(player);
|
||||||
S_StartScreamSound(player->mo, sfx_s3k66);
|
S_StartScreamSound(player->mo, sfx_s3k66);
|
||||||
// S_StopSoundByNum(sfx_timeup); // Kill the "out of time" music, if it's playing. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
|
|
||||||
P_RestoreMusic(player); // I have my doubts that this is the right place for this...
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
|
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
|
||||||
// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
|
{
|
||||||
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
|
||||||
|
{
|
||||||
|
S_FadeMusic(0, 10*MUSICRATE);
|
||||||
|
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false);
|
||||||
|
}
|
||||||
|
|
||||||
if (player->mo->z < player->mo->floorz)
|
if (player->mo->z < player->mo->floorz)
|
||||||
player->mo->z = player->mo->floorz;
|
player->mo->z = player->mo->floorz;
|
||||||
|
@ -9738,8 +9776,11 @@ void P_PlayerThink(player_t *player)
|
||||||
|
|
||||||
if (player->bot)
|
if (player->bot)
|
||||||
{
|
{
|
||||||
if (player->playerstate == PST_LIVE && B_CheckRespawn(player))
|
if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD)
|
||||||
player->playerstate = PST_REBORN;
|
{
|
||||||
|
if (B_CheckRespawn(player))
|
||||||
|
player->playerstate = PST_REBORN;
|
||||||
|
}
|
||||||
if (player->playerstate == PST_REBORN)
|
if (player->playerstate == PST_REBORN)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
68
src/r_segs.c
68
src/r_segs.c
|
@ -885,16 +885,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
leftheight -= viewz;
|
leftheight -= viewz;
|
||||||
rightheight -= viewz;
|
rightheight -= viewz;
|
||||||
|
|
||||||
#define OVERFLOWTEST(height, scale) \
|
#define CLAMPMAX INT32_MAX
|
||||||
overflow_test = (INT64)centeryfrac - (((INT64)height*scale)>>FRACBITS); \
|
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
|
||||||
if (overflow_test < 0) overflow_test = -overflow_test; \
|
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
|
||||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) continue;
|
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
|
||||||
|
if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX;
|
||||||
|
else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test;
|
||||||
|
else rlight->height = CLAMPMIN;
|
||||||
|
|
||||||
OVERFLOWTEST(leftheight, ds->scale1)
|
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
|
||||||
OVERFLOWTEST(rightheight, ds->scale2)
|
if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX;
|
||||||
|
else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test;
|
||||||
rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1);
|
else rlight->heightstep = CLAMPMIN;
|
||||||
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
|
||||||
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
|
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
|
||||||
#else
|
#else
|
||||||
if (light->height < *pfloor->bottomheight)
|
if (light->height < *pfloor->bottomheight)
|
||||||
|
@ -916,12 +918,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
leftheight -= viewz;
|
leftheight -= viewz;
|
||||||
rightheight -= viewz;
|
rightheight -= viewz;
|
||||||
|
|
||||||
OVERFLOWTEST(leftheight, ds->scale1)
|
// Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave.
|
||||||
OVERFLOWTEST(rightheight, ds->scale2)
|
overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS);
|
||||||
#undef OVERFLOWTEST
|
if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX;
|
||||||
|
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test;
|
||||||
|
else rlight->botheight = CLAMPMIN;
|
||||||
|
|
||||||
rlight->botheight = (centeryfrac) - FixedMul(leftheight, ds->scale1);
|
overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS);
|
||||||
rlight->botheightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX;
|
||||||
|
else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test;
|
||||||
|
else rlight->botheightstep = CLAMPMIN;
|
||||||
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
|
rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range);
|
||||||
#else
|
#else
|
||||||
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
|
lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight;
|
||||||
|
@ -1102,9 +1108,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CLAMPMAX INT32_MAX
|
|
||||||
#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out.
|
|
||||||
|
|
||||||
// draw the columns
|
// draw the columns
|
||||||
for (dc_x = x1; dc_x <= x2; dc_x++)
|
for (dc_x = x1; dc_x <= x2; dc_x++)
|
||||||
{
|
{
|
||||||
|
@ -2818,12 +2821,23 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
ffloor[i].f_pos >>= 4;
|
ffloor[i].f_pos >>= 4;
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
ffloor[i].f_pos_slope >>= 4;
|
ffloor[i].f_pos_slope >>= 4;
|
||||||
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
|
|
||||||
ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range);
|
|
||||||
#else
|
|
||||||
ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
|
|
||||||
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
|
|
||||||
#endif
|
#endif
|
||||||
|
if (linedef->special == 41) // Horizon lines extend FOFs in contact with them too.
|
||||||
|
{
|
||||||
|
ffloor[i].f_step = 0;
|
||||||
|
ffloor[i].f_frac = (centeryfrac>>4);
|
||||||
|
topfrac++; // Prevent 1px HOM
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
|
||||||
|
ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range);
|
||||||
|
#else
|
||||||
|
ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos);
|
||||||
|
ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3097,8 +3111,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
else
|
else
|
||||||
markceiling = false;
|
markceiling = false;
|
||||||
|
|
||||||
// Don't render the ceiling again when rendering polyobjects
|
// Don't mark ceiling flat lines for polys unless this line has an upper texture, otherwise we get flat leakage pulling downward
|
||||||
if (curline->polyseg)
|
// (If it DOES have an upper texture and we do this, the ceiling won't render at all)
|
||||||
|
if (curline->polyseg && !curline->sidedef->toptexture)
|
||||||
markceiling = false;
|
markceiling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3110,8 +3125,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||||
else
|
else
|
||||||
markfloor = false;
|
markfloor = false;
|
||||||
|
|
||||||
// Don't render the floor again when rendering polyobjects
|
// Don't mark floor flat lines for polys unless this line has a lower texture, otherwise we get flat leakage pulling upward
|
||||||
if (curline->polyseg)
|
// (If it DOES have a lower texture and we do this, the floor won't render at all)
|
||||||
|
if (curline->polyseg && !curline->sidedef->bottomtexture)
|
||||||
markfloor = false;
|
markfloor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2442,7 +2442,7 @@ void R_DrawMasked(void)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
INT32 numskins = 0;
|
INT32 numskins = 0;
|
||||||
skin_t skins[MAXSKINS+1];
|
skin_t skins[MAXSKINS];
|
||||||
// FIXTHIS: don't work because it must be inistilised before the config load
|
// FIXTHIS: don't work because it must be inistilised before the config load
|
||||||
//#define SKINVALUES
|
//#define SKINVALUES
|
||||||
#ifdef SKINVALUES
|
#ifdef SKINVALUES
|
||||||
|
@ -2955,7 +2955,7 @@ void R_AddSkins(UINT16 wadnum)
|
||||||
// advance by default
|
// advance by default
|
||||||
lastlump = lump + 1;
|
lastlump = lump + 1;
|
||||||
|
|
||||||
if (numskins > MAXSKINS)
|
if (numskins >= MAXSKINS)
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS);
|
CONS_Debug(DBG_RENDER, "ignored skin (%d skins maximum)\n", MAXSKINS);
|
||||||
continue; // so we know how many skins couldn't be added
|
continue; // so we know how many skins couldn't be added
|
||||||
|
|
|
@ -206,7 +206,7 @@ typedef struct drawnode_s
|
||||||
} drawnode_t;
|
} drawnode_t;
|
||||||
|
|
||||||
extern INT32 numskins;
|
extern INT32 numskins;
|
||||||
extern skin_t skins[MAXSKINS + 1];
|
extern skin_t skins[MAXSKINS];
|
||||||
|
|
||||||
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
void SetPlayerSkin(INT32 playernum,const char *skinname);
|
||||||
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
|
||||||
|
|
169
src/s_sound.c
169
src/s_sound.c
|
@ -39,6 +39,10 @@ extern INT32 msg_id;
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "m_misc.h" // for tunes command
|
#include "m_misc.h" // for tunes command
|
||||||
|
|
||||||
|
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
|
||||||
|
#include "lua_hook.h" // MusicChange hook
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HW3SOUND
|
#ifdef HW3SOUND
|
||||||
// 3D Sound Interface
|
// 3D Sound Interface
|
||||||
#include "hardware/hw3sound.h"
|
#include "hardware/hw3sound.h"
|
||||||
|
@ -1373,6 +1377,12 @@ static void *music_data;
|
||||||
static UINT16 music_flags;
|
static UINT16 music_flags;
|
||||||
static boolean music_looping;
|
static boolean music_looping;
|
||||||
|
|
||||||
|
static char queue_name[7];
|
||||||
|
static UINT16 queue_flags;
|
||||||
|
static boolean queue_looping;
|
||||||
|
static UINT32 queue_position;
|
||||||
|
static UINT32 queue_fadeinms;
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Music Status
|
/// Music Status
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -1407,6 +1417,11 @@ musictype_t S_MusicType(void)
|
||||||
return I_SongType();
|
return I_SongType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *S_MusicName(void)
|
||||||
|
{
|
||||||
|
return music_name;
|
||||||
|
}
|
||||||
|
|
||||||
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
|
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping)
|
||||||
{
|
{
|
||||||
if (!I_SongPlaying())
|
if (!I_SongPlaying())
|
||||||
|
@ -1437,6 +1452,35 @@ boolean S_SpeedMusic(float speed)
|
||||||
return I_SetSongSpeed(speed);
|
return I_SetSongSpeed(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Seeking
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 S_GetMusicLength(void)
|
||||||
|
{
|
||||||
|
return I_GetSongLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_SetMusicLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
return I_SetSongLoopPoint(looppoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 S_GetMusicLoopPoint(void)
|
||||||
|
{
|
||||||
|
return I_GetSongLoopPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_SetMusicPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
return I_SetSongPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 S_GetMusicPosition(void)
|
||||||
|
{
|
||||||
|
return I_GetSongPosition();
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Music Playback
|
/// Music Playback
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -1509,12 +1553,13 @@ static void S_UnloadMusic(void)
|
||||||
music_looping = false;
|
music_looping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean S_PlayMusic(boolean looping)
|
static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
|
||||||
{
|
{
|
||||||
if (S_MusicDisabled())
|
if (S_MusicDisabled())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!I_PlaySong(looping))
|
if ((!fadeinms && !I_PlaySong(looping)) ||
|
||||||
|
(fadeinms && !I_FadeInPlaySong(fadeinms, looping)))
|
||||||
{
|
{
|
||||||
S_UnloadMusic();
|
S_UnloadMusic();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1524,38 +1569,93 @@ static boolean S_PlayMusic(boolean looping)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
|
static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 fadeinms)
|
||||||
{
|
{
|
||||||
|
strncpy(queue_name, mmusic, 7);
|
||||||
|
queue_flags = mflags;
|
||||||
|
queue_looping = looping;
|
||||||
|
queue_position = position;
|
||||||
|
queue_fadeinms = fadeinms;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S_ClearQueue(void)
|
||||||
|
{
|
||||||
|
queue_name[0] = queue_flags = queue_looping = queue_position = queue_fadeinms = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void S_ChangeMusicToQueue(void)
|
||||||
|
{
|
||||||
|
S_ChangeMusicEx(queue_name, queue_flags, queue_looping, queue_position, 0, queue_fadeinms);
|
||||||
|
S_ClearQueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms)
|
||||||
|
{
|
||||||
|
char newmusic[7];
|
||||||
|
|
||||||
if (S_MusicDisabled())
|
if (S_MusicDisabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// No Music (empty string)
|
strncpy(newmusic, mmusic, 7);
|
||||||
if (mmusic[0] == 0)
|
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS)
|
||||||
{
|
if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms))
|
||||||
S_StopMusic();
|
return;
|
||||||
|
#endif
|
||||||
|
newmusic[6] = 0;
|
||||||
|
|
||||||
|
// No Music (empty string)
|
||||||
|
if (newmusic[0] == 0)
|
||||||
|
{
|
||||||
|
if (prefadems)
|
||||||
|
I_FadeSong(0, prefadems, &S_StopMusic);
|
||||||
|
else
|
||||||
|
S_StopMusic();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strnicmp(music_name, mmusic, 6))
|
if (prefadems && S_MusicPlaying()) // queue music change for after fade // allow even if the music is the same
|
||||||
{
|
{
|
||||||
S_StopMusic(); // shutdown old music
|
CONS_Debug(DBG_DETAILED, "Now fading out song %s\n", music_name);
|
||||||
|
S_QueueMusic(newmusic, mflags, looping, position, fadeinms);
|
||||||
|
I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET))
|
||||||
|
{
|
||||||
|
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);
|
||||||
|
|
||||||
if (!S_LoadMusic(mmusic))
|
S_StopMusic();
|
||||||
|
|
||||||
|
if (!S_LoadMusic(newmusic))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", mmusic);
|
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded!\n", newmusic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
music_flags = mflags;
|
music_flags = mflags;
|
||||||
music_looping = looping;
|
music_looping = looping;
|
||||||
|
|
||||||
if (!S_PlayMusic(looping))
|
if (!S_PlayMusic(looping, fadeinms))
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", mmusic);
|
CONS_Alert(CONS_ERROR, "Music %.6s could not be played!\n", newmusic);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (position)
|
||||||
|
I_SetSongPosition(position);
|
||||||
|
|
||||||
|
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
||||||
|
}
|
||||||
|
else if (fadeinms) // let fades happen with same music
|
||||||
|
{
|
||||||
|
I_SetSongPosition(position);
|
||||||
|
I_FadeSong(100, fadeinms, NULL);
|
||||||
|
}
|
||||||
|
else // reset volume to 100 with same music
|
||||||
|
{
|
||||||
|
I_StopFadingSong();
|
||||||
|
I_FadeSong(100, 500, NULL);
|
||||||
}
|
}
|
||||||
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_StopMusic(void)
|
void S_StopMusic(void)
|
||||||
|
@ -1636,6 +1736,32 @@ void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Fading
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void S_SetInternalMusicVolume(INT32 volume)
|
||||||
|
{
|
||||||
|
I_SetInternalMusicVolume(min(max(volume, 0), 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_StopFadingMusic(void)
|
||||||
|
{
|
||||||
|
I_StopFadingSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms)
|
||||||
|
{
|
||||||
|
if (source_volume < 0)
|
||||||
|
return I_FadeSong(target_volume, ms, NULL);
|
||||||
|
else
|
||||||
|
return I_FadeSongFromVolume(target_volume, source_volume, ms, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean S_FadeOutStopMusic(UINT32 ms)
|
||||||
|
{
|
||||||
|
return I_FadeSong(0, ms, &S_StopMusic);
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Init & Others
|
/// Init & Others
|
||||||
|
@ -1653,22 +1779,24 @@ void S_Start(void)
|
||||||
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
|
||||||
mapmusname[6] = 0;
|
mapmusname[6] = 0;
|
||||||
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
|
||||||
|
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_resetmusic.value)
|
if (cv_resetmusic.value)
|
||||||
S_StopMusic();
|
S_StopMusic();
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Command_Tunes_f(void)
|
static void Command_Tunes_f(void)
|
||||||
{
|
{
|
||||||
const char *tunearg;
|
const char *tunearg;
|
||||||
UINT16 tunenum, track = 0;
|
UINT16 tunenum, track = 0;
|
||||||
|
UINT32 position = 0;
|
||||||
const size_t argc = COM_Argc();
|
const size_t argc = COM_Argc();
|
||||||
|
|
||||||
if (argc < 2) //tunes slot ...
|
if (argc < 2) //tunes slot ...
|
||||||
{
|
{
|
||||||
CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
|
CONS_Printf("tunes <name/num> [track] [speed] [position] / <-show> / <-default> / <-none>:\n");
|
||||||
CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
|
CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
|
||||||
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
|
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
|
||||||
CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
|
CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
|
||||||
|
@ -1715,10 +1843,15 @@ static void Command_Tunes_f(void)
|
||||||
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
|
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
|
||||||
else
|
else
|
||||||
strncpy(mapmusname, tunearg, 7);
|
strncpy(mapmusname, tunearg, 7);
|
||||||
|
|
||||||
|
if (argc > 4)
|
||||||
|
position = (UINT32)atoi(COM_Argv(4));
|
||||||
|
|
||||||
mapmusname[6] = 0;
|
mapmusname[6] = 0;
|
||||||
mapmusflags = (track & MUSIC_TRACKMASK);
|
mapmusflags = (track & MUSIC_TRACKMASK);
|
||||||
|
mapmusposition = position;
|
||||||
|
|
||||||
S_ChangeMusic(mapmusname, mapmusflags, true);
|
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
|
||||||
|
|
||||||
if (argc > 3)
|
if (argc > 3)
|
||||||
{
|
{
|
||||||
|
|
|
@ -140,29 +140,49 @@ boolean S_MusicDisabled(void);
|
||||||
boolean S_MusicPlaying(void);
|
boolean S_MusicPlaying(void);
|
||||||
boolean S_MusicPaused(void);
|
boolean S_MusicPaused(void);
|
||||||
musictype_t S_MusicType(void);
|
musictype_t S_MusicType(void);
|
||||||
|
const char *S_MusicName(void);
|
||||||
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
|
boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping);
|
||||||
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
|
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
|
||||||
#define S_DigExists(a) S_MusicExists(a, false, true)
|
#define S_DigExists(a) S_MusicExists(a, false, true)
|
||||||
#define S_MIDIExists(a) S_MusicExists(a, true, false)
|
#define S_MIDIExists(a) S_MusicExists(a, true, false)
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Music Properties
|
// Music Effects
|
||||||
//
|
//
|
||||||
|
|
||||||
// Set Speed of Music
|
// Set Speed of Music
|
||||||
boolean S_SpeedMusic(float speed);
|
boolean S_SpeedMusic(float speed);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Music Routines
|
// Music Seeking
|
||||||
|
//
|
||||||
|
|
||||||
|
// Get Length of Music
|
||||||
|
UINT32 S_GetMusicLength(void);
|
||||||
|
|
||||||
|
// Set LoopPoint of Music
|
||||||
|
boolean S_SetMusicLoopPoint(UINT32 looppoint);
|
||||||
|
|
||||||
|
// Get LoopPoint of Music
|
||||||
|
UINT32 S_GetMusicLoopPoint(void);
|
||||||
|
|
||||||
|
// Set Position of Music
|
||||||
|
boolean S_SetMusicPosition(UINT32 position);
|
||||||
|
|
||||||
|
// Get Position of Music
|
||||||
|
UINT32 S_GetMusicPosition(void);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Music Playback
|
||||||
//
|
//
|
||||||
|
|
||||||
// Start music track, arbitrary, given its name, and set whether looping
|
// Start music track, arbitrary, given its name, and set whether looping
|
||||||
// note: music flags 12 bits for tracknum (gme, other formats with more than one track)
|
// note: music flags 12 bits for tracknum (gme, other formats with more than one track)
|
||||||
// 13-15 aren't used yet
|
// 13-15 aren't used yet
|
||||||
// and the last bit we ignore (internal game flag for resetting music on reload)
|
// and the last bit we ignore (internal game flag for resetting music on reload)
|
||||||
#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
|
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms);
|
||||||
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
|
#define S_ChangeMusicInternal(a,b) S_ChangeMusicEx(a,0,b,0,0,0)
|
||||||
|
#define S_ChangeMusic(a,b,c) S_ChangeMusicEx(a,b,c,0,0,0)
|
||||||
|
|
||||||
// Stops the music.
|
// Stops the music.
|
||||||
void S_StopMusic(void);
|
void S_StopMusic(void);
|
||||||
|
@ -171,6 +191,17 @@ void S_StopMusic(void);
|
||||||
void S_PauseAudio(void);
|
void S_PauseAudio(void);
|
||||||
void S_ResumeAudio(void);
|
void S_ResumeAudio(void);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Music Fading
|
||||||
|
//
|
||||||
|
|
||||||
|
void S_SetInternalMusicVolume(INT32 volume);
|
||||||
|
void S_StopFadingMusic(void);
|
||||||
|
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms);
|
||||||
|
#define S_FadeMusic(a, b) S_FadeMusicFromVolume(a, -1, b)
|
||||||
|
#define S_FadeInChangeMusic(a,b,c,d) S_ChangeMusicEx(a,b,c,0,0,d)
|
||||||
|
boolean S_FadeOutStopMusic(UINT32 ms);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Updates music & sounds
|
// Updates music & sounds
|
||||||
//
|
//
|
||||||
|
|
|
@ -70,6 +70,8 @@ if(${SDL2_FOUND})
|
||||||
set(SRB2_SDL2_TOTAL_SOURCES
|
set(SRB2_SDL2_TOTAL_SOURCES
|
||||||
${SRB2_CORE_SOURCES}
|
${SRB2_CORE_SOURCES}
|
||||||
${SRB2_CORE_HEADERS}
|
${SRB2_CORE_HEADERS}
|
||||||
|
${SRB2_PNG_SOURCES}
|
||||||
|
${SRB2_PNG_HEADERS}
|
||||||
${SRB2_CORE_RENDER_SOURCES}
|
${SRB2_CORE_RENDER_SOURCES}
|
||||||
${SRB2_CORE_GAME_SOURCES}
|
${SRB2_CORE_GAME_SOURCES}
|
||||||
${SRB2_LUA_SOURCES}
|
${SRB2_LUA_SOURCES}
|
||||||
|
@ -80,7 +82,8 @@ if(${SDL2_FOUND})
|
||||||
${SRB2_SDL2_HEADERS}
|
${SRB2_SDL2_HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS})
|
source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}
|
||||||
|
${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS})
|
||||||
source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES})
|
source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES})
|
||||||
source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES})
|
source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES})
|
||||||
source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
|
source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES})
|
||||||
|
|
|
@ -1,213 +1,163 @@
|
||||||
/* XPM */
|
/* XPM */
|
||||||
static const char *SDL_icon_xpm[] = {
|
const char * SDL_icon_xpm[] = {
|
||||||
/* columns rows colors chars-per-pixel */
|
"96 96 64 1",
|
||||||
"32 32 175 2 ",
|
" c None",
|
||||||
" c None",
|
". c #040656",
|
||||||
". c #2E2E2E",
|
"+ c #0100B2",
|
||||||
"X c #3C3C3C",
|
"@ c #04056E",
|
||||||
"o c #493939",
|
"# c #0000BD",
|
||||||
"O c #4E473F",
|
"$ c #0B0C09",
|
||||||
"+ c #161658",
|
"% c #0B0D26",
|
||||||
"@ c #131369",
|
"& c #090C42",
|
||||||
"# c #06067B",
|
"* c #060AA7",
|
||||||
"$ c #111173",
|
"= c #1604DA",
|
||||||
"% c #16167F",
|
"- c #020CD5",
|
||||||
"& c #252567",
|
"; c #100F8D",
|
||||||
"* c #372B7C",
|
"> c #040DE4",
|
||||||
"= c #3D3679",
|
", c #11129B",
|
||||||
"- c #41414A",
|
"' c #1D1A83",
|
||||||
"; c #575655",
|
") c #2A10FD",
|
||||||
": c #6A5841",
|
"! c #1318FA",
|
||||||
"> c #5B4B72",
|
"~ c #25225B",
|
||||||
", c #616160",
|
"{ c #252271",
|
||||||
"< c #7B7B7B",
|
"] c #312E2B",
|
||||||
"1 c #906E49",
|
"^ c #33334D",
|
||||||
"2 c #89685D",
|
"/ c #363775",
|
||||||
"3 c #A67B4A",
|
"( c #3D3B69",
|
||||||
"4 c #AA7F50",
|
"_ c #3A3B8B",
|
||||||
"5 c #9B7560",
|
": c #373AFF",
|
||||||
"6 c #856C78",
|
"< c #4142AA",
|
||||||
"7 c #997B7D",
|
"[ c #4B4864",
|
||||||
"8 c #B48552",
|
"} c #4D4B4A",
|
||||||
"9 c #BA8A55",
|
"| c #60492F",
|
||||||
"0 c #A48665",
|
"1 c #4F4C57",
|
||||||
"q c #B98F67",
|
"2 c #4A4A9E",
|
||||||
"w c #B9946A",
|
"3 c #4F4E85",
|
||||||
"e c #B7937A",
|
"4 c #474ADE",
|
||||||
"r c #C8955C",
|
"5 c #4E4FFE",
|
||||||
"t c #CA9966",
|
"6 c #5D5CB3",
|
||||||
"y c #DAA469",
|
"7 c #686663",
|
||||||
"u c #C9A37B",
|
"8 c #666682",
|
||||||
"i c #D7AB7B",
|
"9 c #676875",
|
||||||
"p c #DFB07D",
|
"0 c #66659E",
|
||||||
"a c #EBAE6A",
|
"a c #8B6538",
|
||||||
"s c #E5B27A",
|
"b c #6465D5",
|
||||||
"d c #F1B779",
|
"c c #7F694F",
|
||||||
"f c #0A0A83",
|
"d c #6767FF",
|
||||||
"g c #05058B",
|
"e c #7272FF",
|
||||||
"h c #060687",
|
"f c #91795C",
|
||||||
"j c #101089",
|
"g c #7677FD",
|
||||||
"k c #131382",
|
"h c #828396",
|
||||||
"l c #040494",
|
"i c #A78153",
|
||||||
"z c #02029D",
|
"j c #888989",
|
||||||
"x c #0C0B9C",
|
"k c #8D897E",
|
||||||
"c c #120F9E",
|
"l c #9190FD",
|
||||||
"v c #19199B",
|
"m c #CA9048",
|
||||||
"b c #382D84",
|
"n c #C09968",
|
||||||
"n c #39398D",
|
"o c #A9A8A1",
|
||||||
"m c #222296",
|
"p c #A6A8B0",
|
||||||
"M c #0101A6",
|
"q c #B0B1FB",
|
||||||
"N c #0A0AA2",
|
"r c #EEAC61",
|
||||||
"B c #0202AC",
|
"s c #E3B478",
|
||||||
"V c #1919A2",
|
"t c #C3C4BE",
|
||||||
"C c #1616AD",
|
"u c #FFC68C",
|
||||||
"Z c #0000B5",
|
"v c #FCCD90",
|
||||||
"A c #0202BC",
|
"w c #D4D7D3",
|
||||||
"S c #0C0CB6",
|
"x c #E3E5E0",
|
||||||
"D c #1313B3",
|
"y c #FCFFFB",
|
||||||
"F c #1011BD",
|
" ",
|
||||||
"G c #1B1BBE",
|
" ",
|
||||||
"H c #2B2BAC",
|
" ",
|
||||||
"J c #3737A1",
|
" ",
|
||||||
"K c #2A26BE",
|
" ",
|
||||||
"L c #2A29B4",
|
" ",
|
||||||
"P c #3B3BB8",
|
" ",
|
||||||
"I c #48478B",
|
" ",
|
||||||
"U c #57578A",
|
" ",
|
||||||
"Y c #4A499A",
|
" ttj7777777joot ",
|
||||||
"T c #524F95",
|
" 9hh8830000088hh9 ",
|
||||||
"R c #565399",
|
" 9888(//__<bbbb2////3[888hpp ",
|
||||||
"E c #4C4CA8",
|
" oj}^/_6bbbbgggggggb2///_bgbbbbb631kt ",
|
||||||
"W c #524DA7",
|
" (80066bgeeegggggggb22262/bbggeggb66081 ",
|
||||||
"Q c #5353A4",
|
" p9^jj pp8(_2bgggggeeeeeeeegb2~_bgb//6geegged5*'(hp ",
|
||||||
"! c #5555A9",
|
" ^2<3[7 j^/2bbggggeeeeeeeeeeggb2_({'4eb/2ggge5:!!!>-*{^kt ",
|
||||||
"~ c #5555B4",
|
" &,5b60^ (02<beggggeeeeeeeeeegb62__7}~:5g/_bgd5!))))))=+;20k ",
|
||||||
"^ c #5656B7",
|
" @#:egb3^ pp({4dgggeeeeeeeeeeeeegg6/__3im}+:e//bd:!)))))))))!#;87 ",
|
||||||
"/ c #6464A6",
|
" p'-!:dgb3] 7['4egeeeeeeeeeeeeeeeegg2/__[armc,-523<:!)))))))))))!>*{} ",
|
||||||
"( c #6F67B5",
|
" tp,-)!5egb3} ~_<4dgggeeeeeeeeeeeeeegb6/_2[amusf'#!<_'>))))))))))))!)>+{~ ",
|
||||||
") c #0404C3",
|
" p;-))!5gb2^^'#5eggeeeeeeeeeeeeeeegg6/_23amrusi{#!+;;>))))))))))))))!!-'8p ",
|
||||||
"_ c #0707CA",
|
" tp'#!)):d6(@*>5egeeeeeeeeeeeeeeeegg6_/<(amrrvvn{+)-,;>))))))!!!!!!)))!!>,~j ",
|
||||||
"` c #1414CB",
|
" p;#!))-'{'+-5eggeeeeeeeeeeeeeeeegb222(cmrruvvn{+)>,@>!)!!)!!>>>>======>-,/8 ",
|
||||||
"' c #1A1AC6",
|
" ;#)!-*.;-!5eggeeeeeeeeeeeeeeeegb2_<6|mrrsvvvn{+)!,.-!!!!>>=--######+++-#@(k ",
|
||||||
"] c #0A0AD3",
|
" h@-)+@.*>!5egeeeeeeeeeeeeeeeeeegb_</]mrrruvvvn{+))*@->>--###++++++###+;@{(9j ",
|
||||||
"[ c #0D0DDC",
|
" kh,#+@@,>!:dggeeeeeeeeeeeeeeeeeeebbb_]mrruuvvsf'#)!*.+-###+++++++##+*;'3(&^9 ",
|
||||||
"{ c #1A1AD4",
|
" 8*,@@*)):dggeeeeeeeeeeeeeeeeeeeeggg<(|iruvvvsc,=!!*.;*++++++++###+,@&1o ",
|
||||||
"} c #1010DF",
|
" 8@@@-!)!5eeeeeeeeeeeeeeeeeeeeeeeeeggb2[csvvvn^#)!!+@;*#+++++###*@~[ ",
|
||||||
"| c #1E1EDE",
|
" 9&@*!)):5geeeeeeeeeeeeeeeeeeeeeeeeegge637nsvf{>))!+;;*-######*;{.^ ",
|
||||||
" . c #1817DE",
|
" 9%;!!)):dgeeeeeeeeeeeeeeeeeeeeeeeeeeeggb_1ir7;>))!+;;,++++++*'(} ",
|
||||||
".. c #221FCA",
|
" 9{+!))!5egeeeeeeeeeeeeeeeeeddddeeeeeeeege2}|~#!))!#;@...@@@.^hp ",
|
||||||
"X. c #2B2BCC",
|
" 8,=!))):dggeeeeeeeeeeeeeeeeggggeeeeeeeeggb_~,>!))!+@@@;;;;@&^o ",
|
||||||
"o. c #2727C9",
|
" }(-)))))!:eegeeeeeeeeeeeeeegllllgeeeeeeeegd5+=))))!+;,#>--#,'/hj ",
|
||||||
"O. c #3434C3",
|
" o8.>))))))!:dgggeeeeeeeeeeellqqqqlgeeeeggg5:!!!)))))-*+>)!:55db631 ",
|
||||||
"+. c #3434D4",
|
" p8<*!)))))))!:5deggggggeeeegqqqqqqqqlggged5:!))))))))>->!!:5ddeegb3/ ",
|
||||||
"@. c #0F0FE2",
|
" oh'#!))))))))))!:ddeeeeeeeeglqqqqqqqqlgedd:!)))))))))))))!:dggggeggg239 ",
|
||||||
"#. c #1313E5",
|
" ^*>!))!)))))))))!::55dddeegglll600333_4:!!)))))))))))))):dggeeeeeeggb6(9o ",
|
||||||
"$. c #1515ED",
|
" ~+=-+#>))))))))))!!!:::::5554<3889988[/,=)))))))))))))):5gggeeeeeeeggb6087 ",
|
||||||
"%. c #1B1BEA",
|
" ~**@~'+>!))))))))))))))))!!>*{1kkooook7(,-!)))))))))))!:5deeeeeeeeeeeggb289 ",
|
||||||
"&. c #1C1CE4",
|
" ~,'1o7(*>!))))))))))))))))=,[jtttwxxxwto^;>!))))))))))!!!::5deggeeeeeeegbb3] ",
|
||||||
"*. c #1515F4",
|
" ~@/oxt7'#))))))))))))))))=,3ktwxxyyyyyyxk/+!))))))))))))))!:::5degggeeegggb3^ ",
|
||||||
"=. c #1818F3",
|
" ^&8xyyt^,)))))))))))))))>,3otwxyyyyyyyyyxh'>)))))))))))))))))):5ddeeeeeeeggb3^ ",
|
||||||
"-. c #1717FD",
|
" 771pyyyx7'=!)))))))))))!!#(jtxxyyyyyyyyyyyt3-)))))))))))))))))))!!::degggeeegb2[o ",
|
||||||
";. c #1818FF",
|
" 77tyyyxk/+!!)))))))))))-;9owxyyyyyyyyyyyywh*>)))))))))))))))))))))!::5ddgggggb68j ",
|
||||||
":. c #2B2BE9",
|
" owyyyyt8;>))))))))))))*(otwyyyyyyyyyyyyyxp'-)))))))))))))))))))))))!!:5deeeggg_8j ",
|
||||||
">. c #2424FF",
|
" jtxyyyyxh'>)))))))))!!#_ktxyyyyyyyyyyyyyyyt_+))))))))))))))))))))))))))!!:5deggg63j ",
|
||||||
",. c #2A2AFF",
|
" 7jwyyyyyyp/=))))))))))>,3owxyyyyyyyyyyyyyyyw/+))))))))))))))))))))))))))))!::5degb689 ",
|
||||||
"<. c #2222F1",
|
" 7xyyyyyyo[#))))))))))-/jtwyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))!:5dgg_/ ",
|
||||||
"1. c #3737FF",
|
" }xyyyyyyt9*=))))))))=*9owyyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))))!!:5d3} ",
|
||||||
"2. c #5D5DC3",
|
" }xyyyyyywj'#!))))))!#@7oxyyyyyyyyyyyyyyyyyw/*)))))))))))))))))))))))))))))))))))!!:4/7 ",
|
||||||
"3. c #5F5FC9",
|
" 7xyyyyyyxj&,!!))))!!,%}oyyyyyyyyyyyyyyyyyyw/*))))))))))))))))))))))))))))))))))))))>487 ",
|
||||||
"4. c #5655C2",
|
" 7xyyyyyywk$@!!)))!!-.$]oyyyyyyyyyyyyyyyyyyw/+))))))))))))))))))))))))))))))!!!!))))!>' ",
|
||||||
"5. c #4747D1",
|
" }xyyyyyywj$&+!!)!)>;%$]jyyyyyyyyyyyyyyyyyyt{#)))))))))))))))))))))!!!!!!))!)!!!!!!))!#' ",
|
||||||
"6. c #5B5BD4",
|
" 7xyyyyyyt7$%@-!)!>*[]$$jyyyyyyyyyyyyyyyyyxp;-))))))))))))))))))!!!!!!!!!!!!>>>>>>>>>>!,^ ",
|
||||||
"7. c #6565C8",
|
" 7xyyyyyyt}$][;-)=,(o7$$7yyyyyyyyyyyyyyyyyxp,-)))))))))))!!!!)!!!!>>>>=-----########--=+'9 ",
|
||||||
"8. c #6363DA",
|
" jwyyyyyyo}$}o(';@~7wj$$7yyyyyyyyyyyyyyyyywh*>)))))))))))!>>>=>=---#####+########+++***;@17 ",
|
||||||
"9. c #4545FF",
|
" otxyyyyyt}$7t7}1}7kw7$$7yyyyyyyyyyyyyyyyyt0-)))))))))!!!>--####+++++++++++++##+***,;''.&] ",
|
||||||
"0. c #4D4DFC",
|
" ooowyyyyyt}$}j7owwojo}$$jyyyyyyyyyyyyyyyyyp2>)))))))!!!=##++++++++++++++###+*;@.~[8[9hph ",
|
||||||
"q. c #5454FF",
|
" ojtyyyyywj$$}jwyyxo}$$]jyyyyyyyyyyyyyyyyyp'>))))))!>>-#++++++++++++####+,;'_3/&^}77kot ",
|
||||||
"w. c #5959FF",
|
" 7tyyyyyxo]$$oxyyyt]$$}tyyyyyyyyyyyyyyyyx0*!)))!!!>-#++++++++++++#+##+*;.&1ko ",
|
||||||
"e. c #6969E5",
|
" 7tyyyyyyx7]}xyyyyxj}]oxyyyyyyyyyyyyyyyyp<=)!!!!>-#++++++++++++####*;.(8h ",
|
||||||
"r. c #6B6CEA",
|
" owxyxxyytooywptwwtppxyyyyyyyyyyyyyyyxp3,-=!)!>-#++++++++++###+*,'_{&1k ",
|
||||||
"t. c #6666E7",
|
" jtwwttwtwwtj7kjowxyyyyyyyyyyyyyyyyxt7~'',+>=#+++++++++++###*;@&^j ",
|
||||||
"y. c #6B6BFE",
|
" ]joojj7}]}]|innfc7jtwyyyyyyyyyyyxtjcfnnnf[@*#+++++++++###+@.&%% ",
|
||||||
"u. c #6767F8",
|
" ]$}77}}$$$$]fsssnnifkkotwwwwwwwtpjkfinvvvsi}@*#++++++###*;@.@@&[ ",
|
||||||
"i. c #7070F6",
|
" o7$]]]]]$$]|isvvvvvusifckopppopok7cisvvvvvvvn(,#++++++#+*@.&@*#;3o ",
|
||||||
"p. c #7373FF",
|
" }}$]|||fnnsvvvuvvvuuvvsniffffffnnsvvvvuuuvvvc{*+#++##*@&.@*+#--<7 ",
|
||||||
"a. c #7C7CFF",
|
" }]cninsuvvvvuuuuuuvvvvusnnnnnssuvvvvvuuuuvvc~*+#+++*@.@;*##=>>,^ ",
|
||||||
"s. c #91918F",
|
" 7fvvvvvvuuuuuuuuuuuuvvvvvvvvvvvuuuuuuuuuvvc~*+#+#+,.@*###->!!*~ ",
|
||||||
"d. c #8F9090",
|
" pkivvvvuuuuuuuuuuuuuuuvvvvvvvvuuuvsnsuuuvvf~*+#++++*+++->!!)!#. ",
|
||||||
"f. c #979797",
|
" kfsuvvuuuuuuuuuuuuuuuuuuuuuuuuuvvnfsuvuvvc{++#++++###->!!))!-;h ",
|
||||||
"g. c #9C9C9C",
|
" kisvvvuuuuuuuuuuuuuuuuuuuuuuuvvvicsvvvvs1@##+++++++#>!!))))=,ho ",
|
||||||
"h. c #8585A1",
|
" 7imuvvvuuuuuuuuuuuuuuuuuuuuvusfcivvuvvn~;##+++++++#>!!))))!#8k ",
|
||||||
"j. c #9C9CA7",
|
" cimruuuuuvuuuuuuuuuuuuuuuuvsnfisuvvvsc@*#+++++++++#>!!))))-3} ",
|
||||||
"k. c #9292B6",
|
" 7amrruuuuuuuuuuuuuuuuuuuuvsnnsvvuvvi^,##++++++++++#>!!)))>/^ ",
|
||||||
"l. c #A4A4A4",
|
" kfamrruuuuvvvuuuuuuuuuuuuuvvvvvvvn1@+#++++++++++++#>!)))>{~ ",
|
||||||
"z. c #BDB2A4",
|
" 7|iimrrruuuuuuuuuuuuuuuuvvvvuusn1'+#########++++++->!))>; ",
|
||||||
"x. c #A4A4B1",
|
" 7cammrrrrruuuuuuvvvvvuuuuurrm|.*-#+#######+###+++->!!!*' ",
|
||||||
"c. c #BFBFBD",
|
" ookcaimmrrrrrruuuuurrrrrmi|]%.@@@@@;,*,*+########->!!*6o ",
|
||||||
"v. c #BABAB7",
|
" p7}|ainiimmmmmmmmmmminnia|$%.....{3322_{''',,**+#=!!#6k ",
|
||||||
"b. c #C8AA87",
|
" j7||aaiiiiiaa||7j ookok711^&.';,*+=!><k ",
|
||||||
"n. c #DAAE82",
|
" koooook hph[~@+>><k ",
|
||||||
"m. c #DBB081",
|
" ppppp tk7^3_,+<j ",
|
||||||
"M. c #EBBA85",
|
" o7^@3j ",
|
||||||
"N. c #F3BF84",
|
" 9jj ",
|
||||||
"B. c #F2BE88",
|
" o ",
|
||||||
"V. c #C2B3A3",
|
" ",
|
||||||
"C. c #FBC386",
|
" ",
|
||||||
"Z. c #FCC68C",
|
" ",
|
||||||
"A. c #FFC88F",
|
" ",
|
||||||
"S. c #F4C387",
|
" ",
|
||||||
"D. c #FFC990",
|
" ",
|
||||||
"F. c #C3C1BF",
|
" ",
|
||||||
"G. c #8F8FCB",
|
" ",
|
||||||
"H. c #BDBDC2",
|
" ",
|
||||||
"J. c #BDBDD1",
|
" "};
|
||||||
"K. c #8888F9",
|
|
||||||
"L. c #A4A4FB",
|
|
||||||
"P. c #CDCDCC",
|
|
||||||
"I. c #CECAC6",
|
|
||||||
"U. c #D3CFCA",
|
|
||||||
"Y. c #D3D0CC",
|
|
||||||
"T. c #C0C0D5",
|
|
||||||
"R. c #D6D5D4",
|
|
||||||
"E. c #D7D7DD",
|
|
||||||
"W. c #E1E1DF",
|
|
||||||
"Q. c #DEDEE1",
|
|
||||||
"!. c #E4E4E4",
|
|
||||||
"~. c #E8E8E8",
|
|
||||||
"^. c #F0F0EE",
|
|
||||||
"/. c #F5F5F2",
|
|
||||||
"(. c #FFFFFF",
|
|
||||||
/* pixels */
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" I Q T = ",
|
|
||||||
" Q 7.e.r.i.8.E E 3.r.6.J ",
|
|
||||||
" H ~ n 4.r.p.p.p.p.8.R > 5.^ w.,.-.{ v ",
|
|
||||||
" { 9.^ & P t.p.p.p.p.p.8.I 5 q K L <.;.;.;.-.' ",
|
|
||||||
" { %.H +.y.p.p.p.p.p.e.Y 2 a n.K F $.*.$.@.} ] N ",
|
|
||||||
" x D :.y.p.p.p.p.p.p.r.R 8 C.u ..F A ) A Z M h $ ",
|
|
||||||
" f =.q.p.p.p.p.p.p.p.p.i.( e 6 $.` l B M g ",
|
|
||||||
" ` ;.q.p.p.p.p.p.a.K.a.p.p.4.L -.` l N % ",
|
|
||||||
" V =.-.>.q.y.p.p.p.L.L.K.i.w.,.-.;.$.<.q.u.2. ",
|
|
||||||
" D { =.-.;.>.1.1.9.( h.h.Q &.-.-.-.;.9.p.p.p.r.! ",
|
|
||||||
" U j.o.-.;.-.;.-.P x.Q.^.R.~ *.-.;.;.>.1.q.y.p.i.2. ",
|
|
||||||
" H./.! *.;.;.;.o.x./.(.(.(.J.| -.-.;.-.-.;.,.9.u.p.7. ",
|
|
||||||
" !.(.k.#.;.-.=./ !.(.(.(.(.Q.X.-.;.;.;.;.-.-.;.;.1.w.6. ",
|
|
||||||
" ~.(.H.G ;.-.D j.(.(.(.(.(.!.O.-.-.;.;.;.-.;.-.;.-.;.,.O. ",
|
|
||||||
" ~.(.v.@ *.$.+ d.(.(.(.(.(.E.o.-.-.;.;.-.;.;.;.*.=.=.*.$.v ",
|
|
||||||
" ~.(.l.- Y T ; < (.(.(.(.(.J.&.-.;.;.$.@.[ ] _ ) ) Z B B f ",
|
|
||||||
" P.(.F.X c.I.X f.(.(.(.(.(.G.=.-.=.] A Z Z Z Z z f $ ",
|
|
||||||
" l.!.R.s.F.I.g.W.(.(.(.(.R.E .[ A Z Z Z B g $ ",
|
|
||||||
" . , ; - 0 M.b.V.U.R.Y.z.u n.7 c Z Z B g # + ",
|
|
||||||
" : w p Z.D.A.S.p u i M.A.A.S.* Z B h z ] C ",
|
|
||||||
" s D.D.A.A.A.A.A.A.A.i B.B.b A Z Z @.-.` ",
|
|
||||||
" 1 y C.D.A.A.A.A.A.M.u Z.e c A Z Z [ ;.&. ",
|
|
||||||
" 8 y d C.A.A.A.C.B.t * B Z Z Z A #.=.m ",
|
|
||||||
" 3 9 r t r 9 8 o @ $ # f j l B #.V ",
|
|
||||||
" j k ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" ",
|
|
||||||
" "
|
|
||||||
};
|
|
||||||
|
|
|
@ -164,6 +164,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\am_map.h" />
|
<ClInclude Include="..\am_map.h" />
|
||||||
|
<ClInclude Include="..\apng.h" />
|
||||||
<ClInclude Include="..\blua\lapi.h" />
|
<ClInclude Include="..\blua\lapi.h" />
|
||||||
<ClInclude Include="..\blua\lauxlib.h" />
|
<ClInclude Include="..\blua\lauxlib.h" />
|
||||||
<ClInclude Include="..\blua\lcode.h" />
|
<ClInclude Include="..\blua\lcode.h" />
|
||||||
|
@ -316,6 +317,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\am_map.c" />
|
<ClCompile Include="..\am_map.c" />
|
||||||
|
<ClCompile Include="..\apng.c" />
|
||||||
<ClCompile Include="..\blua\lapi.c" />
|
<ClCompile Include="..\blua\lapi.c" />
|
||||||
<ClCompile Include="..\blua\lauxlib.c" />
|
<ClCompile Include="..\blua\lauxlib.c" />
|
||||||
<ClCompile Include="..\blua\lbaselib.c" />
|
<ClCompile Include="..\blua\lbaselib.c" />
|
||||||
|
|
|
@ -294,6 +294,9 @@
|
||||||
<ClInclude Include="..\lua_script.h">
|
<ClInclude Include="..\lua_script.h">
|
||||||
<Filter>LUA</Filter>
|
<Filter>LUA</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\apng.h">
|
||||||
|
<Filter>M_Misc</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\md5.h">
|
<ClInclude Include="..\md5.h">
|
||||||
<Filter>M_Misc</Filter>
|
<Filter>M_Misc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -2834,6 +2834,50 @@
|
||||||
RelativePath="..\m_argv.h"
|
RelativePath="..\m_argv.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\apng.c"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|x64"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|x64"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\apng.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\m_bbox.c"
|
RelativePath="..\m_bbox.c"
|
||||||
>
|
>
|
||||||
|
|
|
@ -1401,7 +1401,13 @@ static int joy_open2(const char *fname)
|
||||||
void I_InitJoystick(void)
|
void I_InitJoystick(void)
|
||||||
{
|
{
|
||||||
I_ShutdownJoystick();
|
I_ShutdownJoystick();
|
||||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
|
||||||
|
if (M_CheckParm("-noxinput"))
|
||||||
|
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
|
if (M_CheckParm("-nohidapi"))
|
||||||
|
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
|
if (!strcmp(cv_usejoystick.string, "0") || M_CheckParm("-nojoy"))
|
||||||
return;
|
return;
|
||||||
if (joy_open(cv_usejoystick.string) != -1)
|
if (joy_open(cv_usejoystick.string) != -1)
|
||||||
|
@ -1417,7 +1423,13 @@ void I_InitJoystick(void)
|
||||||
void I_InitJoystick2(void)
|
void I_InitJoystick2(void)
|
||||||
{
|
{
|
||||||
I_ShutdownJoystick2();
|
I_ShutdownJoystick2();
|
||||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
|
||||||
|
if (M_CheckParm("-noxinput"))
|
||||||
|
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
|
if (M_CheckParm("-nohidapi"))
|
||||||
|
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||||
|
|
||||||
if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
|
if (!strcmp(cv_usejoystick2.string, "0") || M_CheckParm("-nojoy"))
|
||||||
return;
|
return;
|
||||||
if (joy_open2(cv_usejoystick2.string) != -1)
|
if (joy_open2(cv_usejoystick2.string) != -1)
|
||||||
|
@ -2044,8 +2056,8 @@ static void I_ShutdownTimer(void)
|
||||||
//
|
//
|
||||||
tic_t I_GetTime (void)
|
tic_t I_GetTime (void)
|
||||||
{
|
{
|
||||||
static Uint32 basetime = 0;
|
static Uint64 basetime = 0;
|
||||||
Uint32 ticks = SDL_GetTicks();
|
Uint64 ticks = SDL_GetTicks();
|
||||||
|
|
||||||
if (!basetime)
|
if (!basetime)
|
||||||
basetime = ticks;
|
basetime = ticks;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; };
|
1E44AF0D0B67CDE900BAD059 /* m_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AEFE0B67CDE900BAD059 /* m_fixed.c */; };
|
||||||
1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; };
|
1E44AF0F0B67CDE900BAD059 /* m_menu.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF000B67CDE900BAD059 /* m_menu.c */; };
|
||||||
1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; };
|
1E44AF110B67CDE900BAD059 /* m_misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* m_misc.c */; };
|
||||||
|
1E44AF110B67CDE900BAD059 /* apng.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF020B67CDE900BAD059 /* apng.c */; };
|
||||||
1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; };
|
1E44AF130B67CDE900BAD059 /* m_random.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF040B67CDE900BAD059 /* m_random.c */; };
|
||||||
1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; };
|
1E44AF1A0B67CE2A00BAD059 /* info.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF180B67CE2A00BAD059 /* info.c */; };
|
||||||
1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; };
|
1E44AF1E0B67CE3600BAD059 /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 1E44AF1C0B67CE3600BAD059 /* md5.c */; };
|
||||||
|
@ -253,7 +254,9 @@
|
||||||
1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; };
|
1E44AF000B67CDE900BAD059 /* m_menu.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_menu.c; path = ../../m_menu.c; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; };
|
1E44AF010B67CDE900BAD059 /* m_menu.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_menu.h; path = ../../m_menu.h; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
|
1E44AF020B67CDE900BAD059 /* m_misc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_misc.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
|
||||||
|
1E44AF020B67CDE900BAD059 /* apng.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.c; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; };
|
1E44AF030B67CDE900BAD059 /* m_misc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_misc.h; path = ../../m_misc.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
1E44AF020B67CDE900BAD059 /* apng.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = apng.h; path = ../../m_misc.c; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; };
|
1E44AF040B67CDE900BAD059 /* m_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = m_random.c; path = ../../m_random.c; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; };
|
1E44AF050B67CDE900BAD059 /* m_random.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_random.h; path = ../../m_random.h; sourceTree = SOURCE_ROOT; };
|
||||||
1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; };
|
1E44AF060B67CDE900BAD059 /* m_swap.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = m_swap.h; path = ../../m_swap.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
@ -679,6 +682,8 @@
|
||||||
1E44AEFF0B67CDE900BAD059 /* m_fixed.h */,
|
1E44AEFF0B67CDE900BAD059 /* m_fixed.h */,
|
||||||
1E44AF020B67CDE900BAD059 /* m_misc.c */,
|
1E44AF020B67CDE900BAD059 /* m_misc.c */,
|
||||||
1E44AF030B67CDE900BAD059 /* m_misc.h */,
|
1E44AF030B67CDE900BAD059 /* m_misc.h */,
|
||||||
|
1E44AF020B67CDE900BAD059 /* apng.c */,
|
||||||
|
1E44AF030B67CDE900BAD059 /* apng.h */,
|
||||||
676BB51C0E0DE06100C95963 /* m_queue.c */,
|
676BB51C0E0DE06100C95963 /* m_queue.c */,
|
||||||
676BB51D0E0DE06100C95963 /* m_queue.h */,
|
676BB51D0E0DE06100C95963 /* m_queue.h */,
|
||||||
1E44AF040B67CDE900BAD059 /* m_random.c */,
|
1E44AF040B67CDE900BAD059 /* m_random.c */,
|
||||||
|
|
|
@ -75,15 +75,41 @@
|
||||||
UINT8 sound_started = false;
|
UINT8 sound_started = false;
|
||||||
|
|
||||||
static Mix_Music *music;
|
static Mix_Music *music;
|
||||||
static UINT8 music_volume, sfx_volume;
|
static UINT8 music_volume, sfx_volume, internal_volume;
|
||||||
static float loop_point;
|
static float loop_point;
|
||||||
|
static float song_length; // length in seconds
|
||||||
static boolean songpaused;
|
static boolean songpaused;
|
||||||
|
static UINT32 music_bytes;
|
||||||
|
static boolean is_looping;
|
||||||
|
|
||||||
|
// fading
|
||||||
|
static boolean is_fading;
|
||||||
|
static UINT8 fading_source;
|
||||||
|
static UINT8 fading_target;
|
||||||
|
static UINT32 fading_timer;
|
||||||
|
static UINT32 fading_duration;
|
||||||
|
static INT32 fading_id;
|
||||||
|
static void (*fading_callback)(void);
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
static Music_Emu *gme;
|
static Music_Emu *gme;
|
||||||
static INT32 current_track;
|
static INT32 current_track;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void var_cleanup(void)
|
||||||
|
{
|
||||||
|
loop_point = song_length =\
|
||||||
|
music_bytes = fading_source = fading_target =\
|
||||||
|
fading_timer = fading_duration = 0;
|
||||||
|
|
||||||
|
songpaused = is_looping =\
|
||||||
|
is_fading = false;
|
||||||
|
|
||||||
|
fading_callback = NULL;
|
||||||
|
|
||||||
|
internal_volume = 100;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Audio System
|
/// Audio System
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -111,6 +137,8 @@ void I_StartupSound(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var_cleanup();
|
||||||
|
|
||||||
music = NULL;
|
music = NULL;
|
||||||
music_volume = sfx_volume = 0;
|
music_volume = sfx_volume = 0;
|
||||||
|
|
||||||
|
@ -336,6 +364,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
||||||
len = (info->play_length * 441 / 10) << 2;
|
len = (info->play_length * 441 / 10) << 2;
|
||||||
mem = malloc(len);
|
mem = malloc(len);
|
||||||
gme_play(emu, len >> 1, mem);
|
gme_play(emu, len >> 1, mem);
|
||||||
|
gme_free_info(info);
|
||||||
gme_delete(emu);
|
gme_delete(emu);
|
||||||
|
|
||||||
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
||||||
|
@ -408,6 +437,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
|
||||||
len = (info->play_length * 441 / 10) << 2;
|
len = (info->play_length * 441 / 10) << 2;
|
||||||
mem = malloc(len);
|
mem = malloc(len);
|
||||||
gme_play(emu, len >> 1, mem);
|
gme_play(emu, len >> 1, mem);
|
||||||
|
gme_free_info(info);
|
||||||
gme_delete(emu);
|
gme_delete(emu);
|
||||||
|
|
||||||
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
return Mix_QuickLoad_RAW((Uint8 *)mem, len);
|
||||||
|
@ -482,14 +512,102 @@ void I_SetSfxVolume(UINT8 volume)
|
||||||
sfx_volume = volume;
|
sfx_volume = volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// Music Utilities
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
static UINT32 get_real_volume(UINT8 volume)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (I_SongType() == MU_MID)
|
||||||
|
// HACK: Until we stop using native MIDI,
|
||||||
|
// disable volume changes
|
||||||
|
return ((UINT32)31*128/31); // volume = 31
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
// convert volume to mixer's 128 scale
|
||||||
|
// then apply internal_volume as a percentage
|
||||||
|
return ((UINT32)volume*128/31) * (UINT32)internal_volume / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT32 get_adjusted_position(UINT32 position)
|
||||||
|
{
|
||||||
|
// all in milliseconds
|
||||||
|
UINT32 length = I_GetSongLength();
|
||||||
|
UINT32 looppoint = I_GetSongLoopPoint();
|
||||||
|
if (length)
|
||||||
|
return position >= length ? (position % (length-looppoint)) : position;
|
||||||
|
else
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_fading_callback(void)
|
||||||
|
{
|
||||||
|
if (fading_callback)
|
||||||
|
(*fading_callback)();
|
||||||
|
fading_callback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Music Hooks
|
/// Music Hooks
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
|
||||||
|
static void count_music_bytes(int chan, void *stream, int len, void *udata)
|
||||||
|
{
|
||||||
|
(void)chan;
|
||||||
|
(void)stream;
|
||||||
|
(void)udata;
|
||||||
|
|
||||||
|
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||||
|
return;
|
||||||
|
music_bytes += len;
|
||||||
|
}
|
||||||
|
|
||||||
static void music_loop(void)
|
static void music_loop(void)
|
||||||
{
|
{
|
||||||
Mix_PlayMusic(music, 0);
|
if (is_looping)
|
||||||
Mix_SetMusicPosition(loop_point);
|
{
|
||||||
|
Mix_PlayMusic(music, 0);
|
||||||
|
Mix_SetMusicPosition(loop_point);
|
||||||
|
music_bytes = loop_point*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
I_StopSong();
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT32 music_fade(UINT32 interval, void *param)
|
||||||
|
{
|
||||||
|
(void)param;
|
||||||
|
|
||||||
|
if (!is_fading ||
|
||||||
|
internal_volume == fading_target ||
|
||||||
|
fading_duration == 0)
|
||||||
|
{
|
||||||
|
I_StopFadingSong();
|
||||||
|
do_fading_callback();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (songpaused) // don't decrement timer
|
||||||
|
return interval;
|
||||||
|
else if ((fading_timer -= 10) <= 0)
|
||||||
|
{
|
||||||
|
internal_volume = fading_target;
|
||||||
|
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||||
|
I_StopFadingSong();
|
||||||
|
do_fading_callback();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT8 delta = abs(fading_target - fading_source);
|
||||||
|
fixed_t factor = FixedDiv(fading_duration - fading_timer, fading_duration);
|
||||||
|
if (fading_target < fading_source)
|
||||||
|
internal_volume = max(min(internal_volume, fading_source - FixedMul(delta, factor)), fading_target);
|
||||||
|
else if (fading_target > fading_source)
|
||||||
|
internal_volume = min(max(internal_volume, fading_source + FixedMul(delta, factor)), fading_target);
|
||||||
|
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
|
@ -509,7 +627,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
|
||||||
|
|
||||||
// apply volume to stream
|
// apply volume to stream
|
||||||
for (i = 0, p = (short *)stream; i < len/2; i++, p++)
|
for (i = 0, p = (short *)stream; i < len/2; i++, p++)
|
||||||
*p = ((INT32)*p) * music_volume*2 / 42;
|
*p = ((INT32)*p) * (music_volume*internal_volume/100)*2 / 42;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -587,6 +705,194 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
INT32 length;
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
gme_info_t *info;
|
||||||
|
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||||
|
|
||||||
|
if (gme_e != NULL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||||
|
length = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// reconstruct info->play_length, from GME source
|
||||||
|
// we only want intro + 1 loop, not 2
|
||||||
|
length = info->length;
|
||||||
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
length = info->intro_length + info->loop_length; // intro + 1 loop
|
||||||
|
if (length <= 0)
|
||||||
|
length = 150 * 1000; // 2.5 minutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gme_free_info(info);
|
||||||
|
return max(length, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// VERY IMPORTANT to set your LENGTHMS= in your song files, folks!
|
||||||
|
// SDL mixer can't read music length itself.
|
||||||
|
length = (UINT32)(song_length*1000);
|
||||||
|
if (!length)
|
||||||
|
CONS_Debug(DBG_DETAILED, "Getting music length: music is missing LENGTHMS= tag. Needed for seeking.\n");
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
if (!music || I_SongType() == MU_GME || I_SongType() == MU_MOD || I_SongType() == MU_MID || !is_looping)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT32 length = I_GetSongLength();
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
looppoint %= length;
|
||||||
|
|
||||||
|
loop_point = max((float)(looppoint / 1000.0L), 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
INT32 looppoint;
|
||||||
|
gme_info_t *info;
|
||||||
|
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||||
|
|
||||||
|
if (gme_e != NULL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||||
|
looppoint = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
looppoint = info->intro_length > 0 ? info->intro_length : 0;
|
||||||
|
|
||||||
|
gme_free_info(info);
|
||||||
|
return max(looppoint, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (!music || I_SongType() == MU_MOD || I_SongType() == MU_MID)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return (UINT32)(loop_point * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
UINT32 length;
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
// this is unstable, so fail silently
|
||||||
|
return true;
|
||||||
|
// this isn't required technically, but GME thread-locks for a second
|
||||||
|
// if you seek too high from the counter
|
||||||
|
// length = I_GetSongLength();
|
||||||
|
// if (length)
|
||||||
|
// position = get_adjusted_position(position);
|
||||||
|
|
||||||
|
// SDL_LockAudio();
|
||||||
|
// gme_err_t gme_e = gme_seek(gme, position);
|
||||||
|
// SDL_UnlockAudio();
|
||||||
|
|
||||||
|
// if (gme_e != NULL)
|
||||||
|
// {
|
||||||
|
// CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (!music || I_SongType() == MU_MID)
|
||||||
|
return false;
|
||||||
|
else if (I_SongType() == MU_MOD)
|
||||||
|
return Mix_SetMusicPosition(position); // Goes by channels
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Because SDL mixer can't identify song length, if you have
|
||||||
|
// a position input greater than the real length, then
|
||||||
|
// music_bytes becomes inaccurate.
|
||||||
|
|
||||||
|
length = I_GetSongLength(); // get it in MS
|
||||||
|
if (length)
|
||||||
|
position = get_adjusted_position(position);
|
||||||
|
|
||||||
|
Mix_RewindMusic(); // needed for mp3
|
||||||
|
if(Mix_SetMusicPosition((float)(position/1000.0L)) == 0)
|
||||||
|
music_bytes = position/1000.0L*44100.0L*4; //assume 44.1khz, 4-byte length (see I_GetSongPosition)
|
||||||
|
else
|
||||||
|
// NOTE: This block fires on incorrect song format,
|
||||||
|
// NOT if position input is greater than song length.
|
||||||
|
music_bytes = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBGME
|
||||||
|
if (gme)
|
||||||
|
{
|
||||||
|
INT32 position = gme_tell(gme);
|
||||||
|
|
||||||
|
gme_info_t *info;
|
||||||
|
gme_err_t gme_e = gme_track_info(gme, &info, current_track);
|
||||||
|
|
||||||
|
if (gme_e != NULL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "GME error: %s\n", gme_e);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// adjust position, since GME's counter keeps going past loop
|
||||||
|
if (info->length > 0)
|
||||||
|
position %= info->length;
|
||||||
|
else if (info->intro_length + info->loop_length > 0)
|
||||||
|
position = position >= (info->intro_length + info->loop_length) ? (position % info->loop_length) : position;
|
||||||
|
else
|
||||||
|
position %= 150 * 1000; // 2.5 minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
gme_free_info(info);
|
||||||
|
return max(position, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (!music || I_SongType() == MU_MID)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return music_bytes/44100.0L*1000.0L/4; //assume 44.1khz
|
||||||
|
// 4 = byte length for 16-bit samples (AUDIO_S16SYS), stereo (2-channel)
|
||||||
|
// This is hardcoded in I_StartupSound. Other formats for factor:
|
||||||
|
// 8M: 1 | 8S: 2 | 16M: 2 | 16S: 4
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
/// Music Playback
|
/// Music Playback
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -596,9 +902,21 @@ boolean I_LoadSong(char *data, size_t len)
|
||||||
const char *key1 = "LOOP";
|
const char *key1 = "LOOP";
|
||||||
const char *key2 = "POINT=";
|
const char *key2 = "POINT=";
|
||||||
const char *key3 = "MS=";
|
const char *key3 = "MS=";
|
||||||
|
const char *key4 = "LENGTHMS=";
|
||||||
const size_t key1len = strlen(key1);
|
const size_t key1len = strlen(key1);
|
||||||
const size_t key2len = strlen(key2);
|
const size_t key2len = strlen(key2);
|
||||||
const size_t key3len = strlen(key3);
|
const size_t key3len = strlen(key3);
|
||||||
|
const size_t key4len = strlen(key4);
|
||||||
|
|
||||||
|
// for mp3 wide chars
|
||||||
|
const char *key1w = "L\0O\0O\0P\0";
|
||||||
|
const char *key2w = "P\0O\0I\0N\0T\0\0\0\xFF\xFE";
|
||||||
|
const char *key3w = "M\0S\0\0\0\xFF\xFE";
|
||||||
|
const char *key4w = "L\0E\0N\0G\0T\0H\0M\0S\0\0\0\xFF\xFE";
|
||||||
|
const char *wterm = "\0\0";
|
||||||
|
char wval[10];
|
||||||
|
|
||||||
|
size_t wstart, wp;
|
||||||
char *p = data;
|
char *p = data;
|
||||||
SDL_RWops *rw;
|
SDL_RWops *rw;
|
||||||
|
|
||||||
|
@ -609,6 +927,9 @@ boolean I_LoadSong(char *data, size_t len)
|
||||||
)
|
)
|
||||||
I_UnloadSong();
|
I_UnloadSong();
|
||||||
|
|
||||||
|
// always do this whether or not a music already exists
|
||||||
|
var_cleanup();
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if ((UINT8)data[0] == 0x1F
|
if ((UINT8)data[0] == 0x1F
|
||||||
&& (UINT8)data[1] == 0x8B)
|
&& (UINT8)data[1] == 0x8B)
|
||||||
|
@ -718,30 +1039,88 @@ boolean I_LoadSong(char *data, size_t len)
|
||||||
|
|
||||||
// Find the OGG loop point.
|
// Find the OGG loop point.
|
||||||
loop_point = 0.0f;
|
loop_point = 0.0f;
|
||||||
|
song_length = 0.0f;
|
||||||
|
|
||||||
while ((UINT32)(p - data) < len)
|
while ((UINT32)(p - data) < len)
|
||||||
{
|
{
|
||||||
if (strncmp(p++, key1, key1len))
|
if (fpclassify(loop_point) == FP_ZERO && !strncmp(p, key1, key1len))
|
||||||
continue;
|
|
||||||
p += key1len-1; // skip OOP (the L was skipped in strncmp)
|
|
||||||
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
|
||||||
{
|
{
|
||||||
p += key2len; // skip POINT=
|
p += key1len; // skip LOOP
|
||||||
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
|
if (!strncmp(p, key2, key2len)) // is it LOOPPOINT=?
|
||||||
// because SDL_Mixer is USELESS and can't even tell us
|
{
|
||||||
// something simple like the frequency of the streaming music,
|
p += key2len; // skip POINT=
|
||||||
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
|
loop_point = (float)((44.1L+atoi(p)) / 44100.0L); // LOOPPOINT works by sample count.
|
||||||
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
|
// because SDL_Mixer is USELESS and can't even tell us
|
||||||
|
// something simple like the frequency of the streaming music,
|
||||||
|
// we are unfortunately forced to assume that ALL MUSIC is 44100hz.
|
||||||
|
// This means a lot of tracks that are only 22050hz for a reasonable downloadable file size will loop VERY badly.
|
||||||
|
}
|
||||||
|
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
|
||||||
|
{
|
||||||
|
p += key3len; // skip MS=
|
||||||
|
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
|
||||||
|
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!strncmp(p, key3, key3len)) // is it LOOPMS=?
|
else if (fpclassify(song_length) == FP_ZERO && !strncmp(p, key4, key4len)) // is it LENGTHMS=?
|
||||||
{
|
{
|
||||||
p += key3len; // skip MS=
|
p += key4len; // skip LENGTHMS
|
||||||
loop_point = (float)(atoi(p) / 1000.0L); // LOOPMS works by real time, as miliseconds.
|
song_length = (float)(atoi(p) / 1000.0L);
|
||||||
// Everything that uses LOOPMS will work perfectly with SDL_Mixer.
|
}
|
||||||
|
// below: search MP3 or other tags that use wide char encoding
|
||||||
|
else if (fpclassify(loop_point) == FP_ZERO && !memcmp(p, key1w, key1len*2)) // LOOP wide char
|
||||||
|
{
|
||||||
|
p += key1len*2;
|
||||||
|
if (!memcmp(p, key2w, (key2len+1)*2)) // POINT= wide char
|
||||||
|
{
|
||||||
|
p += (key2len+1)*2;
|
||||||
|
wstart = (size_t)p;
|
||||||
|
wp = 0;
|
||||||
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
|
{
|
||||||
|
wval[wp] = *p;
|
||||||
|
p += 2;
|
||||||
|
wp = ((size_t)(p-wstart))/2;
|
||||||
|
}
|
||||||
|
wval[min(wp, 9)] = 0;
|
||||||
|
loop_point = (float)((44.1L+atoi(wval) / 44100.0L));
|
||||||
|
}
|
||||||
|
else if (!memcmp(p, key3w, (key3len+1)*2)) // MS= wide char
|
||||||
|
{
|
||||||
|
p += (key3len+1)*2;
|
||||||
|
wstart = (size_t)p;
|
||||||
|
wp = 0;
|
||||||
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
|
{
|
||||||
|
wval[wp] = *p;
|
||||||
|
p += 2;
|
||||||
|
wp = ((size_t)(p-wstart))/2;
|
||||||
|
}
|
||||||
|
wval[min(wp, 9)] = 0;
|
||||||
|
loop_point = (float)(atoi(wval) / 1000.0L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fpclassify(song_length) == FP_ZERO && !memcmp(p, key4w, (key4len+1)*2)) // LENGTHMS= wide char
|
||||||
|
{
|
||||||
|
p += (key4len+1)*2;
|
||||||
|
wstart = (size_t)p;
|
||||||
|
wp = 0;
|
||||||
|
while (wp < 9 && memcmp(p, wterm, 2))
|
||||||
|
{
|
||||||
|
wval[wp] = *p;
|
||||||
|
p += 2;
|
||||||
|
wp = ((size_t)(p-wstart))/2;
|
||||||
|
}
|
||||||
|
wval[min(wp, 9)] = 0;
|
||||||
|
song_length = (float)(atoi(wval) / 1000.0L);
|
||||||
}
|
}
|
||||||
// Neither?! Continue searching.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (fpclassify(loop_point) != FP_ZERO && fpclassify(song_length) != FP_ZERO && song_length > loop_point) // Got what we needed
|
||||||
|
// the last case is a sanity check, in case the wide char searches were false matches.
|
||||||
|
break;
|
||||||
|
else // continue searching
|
||||||
|
p++;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -765,7 +1144,6 @@ void I_UnloadSong(void)
|
||||||
|
|
||||||
boolean I_PlaySong(boolean looping)
|
boolean I_PlaySong(boolean looping)
|
||||||
{
|
{
|
||||||
boolean lpz = fpclassify(loop_point) == FP_ZERO;
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if (gme)
|
if (gme)
|
||||||
{
|
{
|
||||||
|
@ -779,21 +1157,37 @@ boolean I_PlaySong(boolean looping)
|
||||||
if (!music)
|
if (!music)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (fpclassify(song_length) == FP_ZERO && (I_SongType() == MU_OGG || I_SongType() == MU_MP3 || I_SongType() == MU_FLAC))
|
||||||
|
CONS_Debug(DBG_DETAILED, "This song is missing a LENGTHMS= tag! Required to make seeking work properly.\n");
|
||||||
|
|
||||||
if (Mix_PlayMusic(music, looping && lpz ? -1 : 0) == -1)
|
if (I_SongType() != MU_MOD && I_SongType() != MU_MID && Mix_PlayMusic(music, 0) == -1)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ((I_SongType() == MU_MOD || I_SongType() == MU_MID) && Mix_PlayMusic(music, looping ? -1 : 0) == -1) // if MOD, loop forever
|
||||||
{
|
{
|
||||||
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
|
||||||
|
|
||||||
if (!lpz)
|
is_looping = looping;
|
||||||
Mix_HookMusicFinished(music_loop);
|
|
||||||
|
I_SetMusicVolume(music_volume);
|
||||||
|
|
||||||
|
if (I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||||
|
Mix_HookMusicFinished(music_loop); // don't bother counting if MOD
|
||||||
|
|
||||||
|
if(I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||||
|
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopSong(void)
|
void I_StopSong(void)
|
||||||
{
|
{
|
||||||
|
I_StopFadingSong();
|
||||||
|
|
||||||
#ifdef HAVE_LIBGME
|
#ifdef HAVE_LIBGME
|
||||||
if (gme)
|
if (gme)
|
||||||
{
|
{
|
||||||
|
@ -803,19 +1197,40 @@ void I_StopSong(void)
|
||||||
#endif
|
#endif
|
||||||
if (music)
|
if (music)
|
||||||
{
|
{
|
||||||
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
Mix_HookMusicFinished(NULL);
|
Mix_HookMusicFinished(NULL);
|
||||||
Mix_HaltMusic();
|
Mix_HaltMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_PauseSong(void)
|
void I_PauseSong(void)
|
||||||
{
|
{
|
||||||
|
if(I_SongType() == MU_MID) // really, SDL Mixer? why can't you pause MIDI???
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||||
|
Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes);
|
||||||
|
|
||||||
Mix_PauseMusic();
|
Mix_PauseMusic();
|
||||||
songpaused = true;
|
songpaused = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_ResumeSong(void)
|
void I_ResumeSong(void)
|
||||||
{
|
{
|
||||||
|
if (I_SongType() == MU_MID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (I_SongType() != MU_GME && I_SongType() != MU_MOD && I_SongType() != MU_MID)
|
||||||
|
{
|
||||||
|
while(Mix_UnregisterEffect(MIX_CHANNEL_POST, count_music_bytes) != 0) { }
|
||||||
|
// HACK: fixes issue of multiple effect callbacks being registered
|
||||||
|
|
||||||
|
if(music && I_SongType() != MU_MOD && I_SongType() != MU_MID && !Mix_RegisterEffect(MIX_CHANNEL_POST, count_music_bytes, NULL, NULL))
|
||||||
|
CONS_Alert(CONS_WARNING, "Error registering SDL music position counter: %s\n", Mix_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
Mix_ResumeMusic();
|
Mix_ResumeMusic();
|
||||||
songpaused = false;
|
songpaused = false;
|
||||||
}
|
}
|
||||||
|
@ -834,7 +1249,7 @@ void I_SetMusicVolume(UINT8 volume)
|
||||||
#endif
|
#endif
|
||||||
music_volume = volume;
|
music_volume = volume;
|
||||||
|
|
||||||
Mix_VolumeMusic((UINT32)music_volume*128/31);
|
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean I_SetSongTrack(int track)
|
boolean I_SetSongTrack(int track)
|
||||||
|
@ -863,9 +1278,100 @@ boolean I_SetSongTrack(int track)
|
||||||
SDL_UnlockAudio();
|
SDL_UnlockAudio();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
if (I_SongType() == MU_MOD)
|
||||||
|
return !Mix_SetMusicPosition(track);
|
||||||
(void)track;
|
(void)track;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
internal_volume = volume;
|
||||||
|
if (!I_SongPlaying())
|
||||||
|
return;
|
||||||
|
Mix_VolumeMusic(get_real_volume(music_volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
if (fading_id)
|
||||||
|
SDL_RemoveTimer(fading_id);
|
||||||
|
is_fading = false;
|
||||||
|
fading_source = fading_target = fading_timer = fading_duration = fading_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
INT16 volume_delta;
|
||||||
|
|
||||||
|
source_volume = min(source_volume, 100);
|
||||||
|
volume_delta = (INT16)(target_volume - source_volume);
|
||||||
|
|
||||||
|
I_StopFadingSong();
|
||||||
|
|
||||||
|
if (!ms && volume_delta)
|
||||||
|
{
|
||||||
|
I_SetInternalMusicVolume(target_volume);
|
||||||
|
if (callback)
|
||||||
|
(*callback)();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!volume_delta)
|
||||||
|
{
|
||||||
|
if (callback)
|
||||||
|
(*callback)();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round MS to nearest 10
|
||||||
|
// If n - lower > higher - n, then round up
|
||||||
|
ms = (ms - ((ms / 10) * 10) > (((ms / 10) * 10) + 10) - ms) ?
|
||||||
|
(((ms / 10) * 10) + 10) // higher
|
||||||
|
: ((ms / 10) * 10); // lower
|
||||||
|
|
||||||
|
if (!ms)
|
||||||
|
I_SetInternalMusicVolume(target_volume);
|
||||||
|
else if (source_volume != target_volume)
|
||||||
|
{
|
||||||
|
fading_id = SDL_AddTimer(10, music_fade, NULL);
|
||||||
|
if (fading_id)
|
||||||
|
{
|
||||||
|
is_fading = true;
|
||||||
|
fading_timer = fading_duration = ms;
|
||||||
|
fading_source = source_volume;
|
||||||
|
fading_target = target_volume;
|
||||||
|
fading_callback = callback;
|
||||||
|
|
||||||
|
if (internal_volume != source_volume)
|
||||||
|
I_SetInternalMusicVolume(source_volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_fading;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
return I_FadeSongFromVolume(target_volume, internal_volume, ms, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
return I_FadeSongFromVolume(0, internal_volume, ms, &I_StopSong);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
if (I_PlaySong(looping))
|
||||||
|
return I_FadeSongFromVolume(100, 0, ms, NULL);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1375,6 +1375,37 @@ boolean I_SetSongSpeed(float speed)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
// MUSIC SEEKING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
(void)looppoint;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
(void)position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC PLAYBACK
|
// MUSIC PLAYBACK
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
|
@ -1443,6 +1474,47 @@ boolean I_SetSongTrack(int track)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)source_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// ------------------------
|
/// ------------------------
|
||||||
// MUSIC LOADING AND CLEANUP
|
// MUSIC LOADING AND CLEANUP
|
||||||
// \todo Split logic between loading and playing,
|
// \todo Split logic between loading and playing,
|
||||||
|
|
BIN
src/sdl/srb2icon.png
Normal file
BIN
src/sdl/srb2icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -229,6 +229,7 @@ sfxinfo_t S_sfx[NUMSFX] =
|
||||||
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"},
|
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"},
|
||||||
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
|
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
|
||||||
{"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"},
|
{"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"},
|
||||||
|
{"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous Countdown"},
|
||||||
{"ngjump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
|
{"ngjump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
|
||||||
{"peww", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pew"},
|
{"peww", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pew"},
|
||||||
|
|
||||||
|
|
|
@ -295,6 +295,7 @@ typedef enum
|
||||||
sfx_hoop3,
|
sfx_hoop3,
|
||||||
sfx_hidden,
|
sfx_hidden,
|
||||||
sfx_prloop,
|
sfx_prloop,
|
||||||
|
sfx_timeup,
|
||||||
sfx_ngjump,
|
sfx_ngjump,
|
||||||
sfx_peww,
|
sfx_peww,
|
||||||
|
|
||||||
|
|
36
src/w_wad.c
36
src/w_wad.c
|
@ -198,6 +198,7 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors)
|
||||||
static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
||||||
{
|
{
|
||||||
UINT16 posStart, posEnd;
|
UINT16 posStart, posEnd;
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0);
|
posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0);
|
||||||
if (posStart != INT16_MAX)
|
if (posStart != INT16_MAX)
|
||||||
{
|
{
|
||||||
|
@ -206,6 +207,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum, boolean mainfile)
|
||||||
for (; posStart < posEnd; posStart++)
|
for (; posStart < posEnd; posStart++)
|
||||||
LUA_LoadLump(wadnum, posStart);
|
LUA_LoadLump(wadnum, posStart);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0);
|
posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0);
|
||||||
if (posStart != INT16_MAX)
|
if (posStart != INT16_MAX)
|
||||||
{
|
{
|
||||||
|
@ -806,9 +808,11 @@ UINT16 W_InitFile(const char *filename, boolean mainfile)
|
||||||
CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfile->filename);
|
CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfile->filename);
|
||||||
DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile);
|
DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0, mainfile);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
case RET_LUA:
|
case RET_LUA:
|
||||||
LUA_LoadLump(numwadfiles - 1, 0);
|
LUA_LoadLump(numwadfiles - 1, 0);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1155,6 +1159,23 @@ void zerr(int ret)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define NO_PNG_LUMPS
|
||||||
|
|
||||||
|
#ifdef NO_PNG_LUMPS
|
||||||
|
static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l)
|
||||||
|
{
|
||||||
|
if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/
|
||||||
|
return;
|
||||||
|
// Check for PNG file signature using memcmp
|
||||||
|
// As it may be faster on CPUs with slow unaligned memory access
|
||||||
|
// Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
|
||||||
|
if (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0)
|
||||||
|
{
|
||||||
|
I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .PNG - please convert to either Doom or Flat (raw) image format.", l, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Reads bytes from the head of a lump.
|
/** Reads bytes from the head of a lump.
|
||||||
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
* Note: If the lump is compressed, the whole thing has to be read anyway.
|
||||||
*
|
*
|
||||||
|
@ -1194,7 +1215,15 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
switch(wadfiles[wad]->lumpinfo[lump].compression)
|
switch(wadfiles[wad]->lumpinfo[lump].compression)
|
||||||
{
|
{
|
||||||
case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read.
|
case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read.
|
||||||
|
#ifdef NO_PNG_LUMPS
|
||||||
|
{
|
||||||
|
size_t bytesread = fread(dest, 1, size, handle);
|
||||||
|
ErrorIfPNG(dest, bytesread, wadfiles[wad]->filename, l->name2);
|
||||||
|
return bytesread;
|
||||||
|
}
|
||||||
|
#else
|
||||||
return fread(dest, 1, size, handle);
|
return fread(dest, 1, size, handle);
|
||||||
|
#endif
|
||||||
case CM_LZF: // Is it LZF compressed? Used by ZWADs.
|
case CM_LZF: // Is it LZF compressed? Used by ZWADs.
|
||||||
{
|
{
|
||||||
#ifdef ZWAD
|
#ifdef ZWAD
|
||||||
|
@ -1229,11 +1258,15 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
M_Memcpy(dest, decData + offset, size);
|
M_Memcpy(dest, decData + offset, size);
|
||||||
Z_Free(rawData);
|
Z_Free(rawData);
|
||||||
Z_Free(decData);
|
Z_Free(decData);
|
||||||
|
#ifdef NO_PNG_LUMPS
|
||||||
|
ErrorIfPNG(dest, size, wadfiles[wad]->filename, l->name2);
|
||||||
|
#endif
|
||||||
return size;
|
return size;
|
||||||
#else
|
#else
|
||||||
//I_Error("ZWAD files not supported on this platform.");
|
//I_Error("ZWAD files not supported on this platform.");
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
|
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
|
||||||
|
@ -1286,6 +1319,9 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
|
||||||
Z_Free(rawData);
|
Z_Free(rawData);
|
||||||
Z_Free(decData);
|
Z_Free(decData);
|
||||||
|
|
||||||
|
#ifdef NO_PNG_LUMPS
|
||||||
|
ErrorIfPNG(dest, size, wadfiles[wad]->filename, l->name2);
|
||||||
|
#endif
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -182,6 +182,7 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\am_map.c" />
|
<ClCompile Include="..\am_map.c" />
|
||||||
|
<ClCompile Include="..\apng.c" />
|
||||||
<ClCompile Include="..\blua\lapi.c" />
|
<ClCompile Include="..\blua\lapi.c" />
|
||||||
<ClCompile Include="..\blua\lauxlib.c" />
|
<ClCompile Include="..\blua\lauxlib.c" />
|
||||||
<ClCompile Include="..\blua\lbaselib.c" />
|
<ClCompile Include="..\blua\lbaselib.c" />
|
||||||
|
@ -330,6 +331,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\am_map.h" />
|
<ClInclude Include="..\am_map.h" />
|
||||||
|
<ClInclude Include="..\apng.h" />
|
||||||
<ClInclude Include="..\blua\lapi.h" />
|
<ClInclude Include="..\blua\lapi.h" />
|
||||||
<ClInclude Include="..\blua\lauxlib.h" />
|
<ClInclude Include="..\blua\lauxlib.h" />
|
||||||
<ClInclude Include="..\blua\lcode.h" />
|
<ClInclude Include="..\blua\lcode.h" />
|
||||||
|
|
|
@ -2851,6 +2851,50 @@
|
||||||
RelativePath="..\m_misc.h"
|
RelativePath="..\m_misc.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\apng.c"
|
||||||
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|x64"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|x64"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\apng.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\m_queue.c"
|
RelativePath="..\m_queue.c"
|
||||||
>
|
>
|
||||||
|
|
|
@ -815,6 +815,60 @@ void I_SetMusicVolume(UINT8 volume)
|
||||||
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
FMR_MUSIC(FMOD_Channel_SetVolume(music_channel, music_volume / 31.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLength(void)
|
||||||
|
{
|
||||||
|
UINT32 length;
|
||||||
|
if (I_SongType() == MU_MID)
|
||||||
|
return 0;
|
||||||
|
FMR_MUSIC(FMOD_Sound_GetLength(music_stream, &length, FMOD_TIMEUNIT_MS));
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongLoopPoint(UINT32 looppoint)
|
||||||
|
{
|
||||||
|
(void)looppoint;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongLoopPoint(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_SetSongPosition(UINT32 position)
|
||||||
|
{
|
||||||
|
FMOD_RESULT e;
|
||||||
|
if(I_SongType() == MU_MID)
|
||||||
|
// Dummy out; this works for some MIDI, but not others.
|
||||||
|
// SDL does not support this for any MIDI.
|
||||||
|
return false;
|
||||||
|
e = FMOD_Channel_SetPosition(music_channel, position, FMOD_TIMEUNIT_MS);
|
||||||
|
if (e == FMOD_OK)
|
||||||
|
return true;
|
||||||
|
else if (e == FMOD_ERR_UNSUPPORTED // Only music modules, numbnuts!
|
||||||
|
|| e == FMOD_ERR_INVALID_POSITION) // Out-of-bounds!
|
||||||
|
return false;
|
||||||
|
else // Congrats, you horribly broke it somehow
|
||||||
|
{
|
||||||
|
FMR_MUSIC(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 I_GetSongPosition(void)
|
||||||
|
{
|
||||||
|
FMOD_RESULT e;
|
||||||
|
unsigned int fmposition = 0;
|
||||||
|
if(I_SongType() == MU_MID)
|
||||||
|
// Dummy out because unsupported, even though FMOD does this correctly.
|
||||||
|
return 0;
|
||||||
|
e = FMOD_Channel_GetPosition(music_channel, &fmposition, FMOD_TIMEUNIT_MS);
|
||||||
|
if (e == FMOD_OK)
|
||||||
|
return (UINT32)fmposition;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
boolean I_SetSongTrack(INT32 track)
|
boolean I_SetSongTrack(INT32 track)
|
||||||
{
|
{
|
||||||
if (track != current_track) // If the track's already playing, then why bother?
|
if (track != current_track) // If the track's already playing, then why bother?
|
||||||
|
@ -859,3 +913,46 @@ boolean I_SetSongTrack(INT32 track)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ------------------------
|
||||||
|
/// MUSIC FADING
|
||||||
|
/// ------------------------
|
||||||
|
|
||||||
|
void I_SetInternalMusicVolume(UINT8 volume)
|
||||||
|
{
|
||||||
|
(void)volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void I_StopFadingSong(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)source_volume;
|
||||||
|
(void)ms;
|
||||||
|
(void)callback;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void))
|
||||||
|
{
|
||||||
|
(void)target_volume;
|
||||||
|
(void)ms;
|
||||||
|
(void)callback;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeOutStopSong(UINT32 ms)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean I_FadeInPlaySong(UINT32 ms, boolean looping)
|
||||||
|
{
|
||||||
|
(void)ms;
|
||||||
|
(void)looping;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -833,7 +833,17 @@ void Y_Ticker(void)
|
||||||
|
|
||||||
if (!intertic) // first time only
|
if (!intertic) // first time only
|
||||||
{
|
{
|
||||||
S_ChangeMusicInternal("_clear", false); // don't loop it
|
if (mapheaderinfo[gamemap-1]->musinterfadeout
|
||||||
|
#ifdef _WIN32
|
||||||
|
// can't fade midi due to win32 volume hack
|
||||||
|
&& S_MusicType() != MU_MID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
|
||||||
|
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
|
||||||
|
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
|
||||||
|
else
|
||||||
|
S_ChangeMusicInternal("_clear", false); // don't loop it
|
||||||
tallydonetic = -1;
|
tallydonetic = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -898,7 +908,17 @@ void Y_Ticker(void)
|
||||||
|
|
||||||
if (!intertic) // first time only
|
if (!intertic) // first time only
|
||||||
{
|
{
|
||||||
S_ChangeMusicInternal("_clear", false); // don't loop it
|
if (mapheaderinfo[gamemap-1]->musinterfadeout
|
||||||
|
#ifdef _WIN32
|
||||||
|
// can't fade midi due to win32 volume hack
|
||||||
|
&& S_MusicType() != MU_MID
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
|
||||||
|
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
|
||||||
|
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
|
||||||
|
else
|
||||||
|
S_ChangeMusicInternal("_clear", false); // don't loop it
|
||||||
tallydonetic = -1;
|
tallydonetic = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue