1
0
mirror of https://github.com/jummy0/sb2-decomp synced 2025-03-14 20:23:30 +01:00

directmusic was pissing me off so bad i replaced it with bassmidi (toggleable)

This commit is contained in:
jummy 2024-11-08 00:12:28 -06:00
parent 0120173489
commit 42b0b3660c
24 changed files with 5766 additions and 260 deletions

View File

@ -77,7 +77,7 @@
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>_WIN32;WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>dxsdk3\sdk\inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>dxsdk3\sdk\inc;bass\inc</AdditionalIncludeDirectories>
<UndefinePreprocessorDefinitions>UNICODE;_UNICODE</UndefinePreprocessorDefinitions>
<PrecompiledHeaderFile />
</ClCompile>
@ -85,9 +85,9 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalOptions>/DYNAMICBASE "legacy_stdio_definitions.lib" %(AdditionalOptions) /VERBOSE</AdditionalOptions>
<AdditionalLibraryDirectories>dxsdk3\sdk\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>dxsdk3\sdk\lib;bass\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<TreatLinkerWarningAsErrors>false</TreatLinkerWarningAsErrors>
<AdditionalDependencies>dxsdk3/sdk/lib/*.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxsdk3/sdk/lib/*.lib;bass/lib/*.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<OptimizeReferences>true</OptimizeReferences>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
@ -103,7 +103,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WIN32;WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>dxsdk3\sdk\inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>dxsdk3\sdk\inc;bass\inc</AdditionalIncludeDirectories>
<UndefinePreprocessorDefinitions>UNICODE;_UNICODE</UndefinePreprocessorDefinitions>
</ClCompile>
<Link>
@ -111,11 +111,11 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>dxsdk3\sdk\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>dxsdk3\sdk\lib;bass\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
<AdditionalOptions>/DYNAMICBASE "legacy_stdio_definitions.lib" %(AdditionalOptions) /VERBOSE</AdditionalOptions>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalDependencies>dxsdk3/sdk/lib/*.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>dxsdk3/sdk/lib/*.lib;bass/lib/*.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>

BIN
bass/bass.dll Normal file

Binary file not shown.

2352
bass/bass.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
bass/bassmidi.dll Normal file

Binary file not shown.

734
bass/bassmidi.txt Normal file
View File

@ -0,0 +1,734 @@
BASSMIDI 2.4
Copyright (c) 2006-2024 Un4seen Developments Ltd. All rights reserved.
Files that you should have found in the BASSMIDI package
========================================================
Win32 version
-------------
BASSMIDI.TXT This file
BASSMIDI.DLL BASSMIDI module
BASSMIDI.CHM BASSMIDI documentation
X64\
BASSMIDI.DLL 64-bit BASSMIDI module
C\ C/C++ API and examples...
BASSMIDI.H BASSMIDI C/C++ header file
BASSMIDI.LIB BASSMIDI import library
BASSMIDI.SLN Visual Studio solution for examples
MAKEFILE Makefile for examples
MAKEFILE.IN Makefile helper macros
X64\
BASSMIDI.LIB 64-bit BASSMIDI import library
MIDITEST\ MIDI playback example
...
SF2PACK\ Soundfont packer
...
SYNTH\ Real-time MIDI example
...
BIN\ Precompiled examples
MIDITEST.EXE
SF2PACK.EXE
SYNTH.EXE
VB\ Visual Basic API and examples...
BASSMIDI.BAS BASSMIDI Visual Basic module
MIDITEST\ MIDI playback example
...
DELPHI\ Delphi API and examples...
BASSMIDI.PAS BASSMIDI Delphi unit
MIDITEST\ MIDI playback example
...
SYNTH\ Real-time MIDI example
...
NOTE: You may need to "Unblock" the BASSMIDI.CHM file in its "Properties" to
view it on Windows 7. The documentation can also be viewed online at
the BASS website.
NOTE: To run the example EXEs, first you will have to copy BASSMIDI.DLL and
BASS.DLL into the same directory as them.
NOTE: To build the examples, you will need to copy the BASS API into the same
directory as the BASSMIDI API.
NOTE: The Delphi and VB examples may not always be up to date with the C
examples, so the latter should be preferred as references if possible.
macOS version
-------------
BASSMIDI.TXT This file
LIBBASSMIDI.DYLIB BASSMIDI module
BASSMIDI.CHM BASSMIDI documentation
BASSMIDI.H BASSMIDI C/C++ header file
BASSMIDI.XCODEPROJ Xcode project for examples
MIDITEST\ MIDI playback example
...
SF2PACK\ Soundfont packer
...
SYNTH\ Real-time MIDI example
...
NOTE: To build the examples, you will need to copy the BASS API into the same
directory as the BASSMIDI API.
Linux version
-------------
BASSMIDI.TXT This file
BASSMIDI.CHM BASSMIDI documentation
BASSMIDI.H BASSMIDI C/C++ header file
MAKEFILE Makefile for examples
MAKEFILE.IN Makefile helper macros
LIBS\ BASSMIDI modules
...
MIDITEST\ MIDI playback example
...
SF2PACK\ Soundfont packer
...
SYNTH\ Real-time MIDI example
...
NOTE: To build the examples, you will need to copy the BASS API into the same
directory as the BASSMIDI API.
Android version
---------------
BASSMIDI.TXT This file
BASSMIDI.CHM BASSMIDI documentation
LIBS\ BASSMIDI modules
...
C\ C/C++ API...
BASSMIDI.H BASSMIDI C/C++ header file
JAVA\COM\UN4SEEN\BASS\
BASSMIDI.JAVA BASSMIDI Java class
EXAMPLES\ Java examples
BUILD.GRADLE Android Studio build script for examples
SETTINGS.GRADLE
PROGUARD-BASS.PRO
MIDITEST\ MIDI playback example
...
NOTE: To build the examples, you will need to copy the BASS API into the same
directory as the BASSMIDI API.
iOS version
-----------
BASSMIDI.TXT This file
BASSMIDI.XCFRAMEWORK BASSMIDI framework
BASSMIDI.CHM BASSMIDI documentation
BASSMIDI.H BASSMIDI C/C++ header file
What's the point?
=================
BASSMIDI is an extension to the BASS audio library, enabling the playing of
MIDI files and custom event sequences, using SF2 (including SF2PACK and SF3)
and/or SFZ soundfonts to provide the sounds. MIDI input is also supported.
Requirements
============
BASS 2.4 is required.
Using BASSMIDI
==============
The MIDI format is used in very much the same way as any of the built-in BASS
stream formats; simply call the MIDI stream creation function instead of the
BASS built-in functions. The BASS plugin system (see BASS_PluginLoad) is also
supported.
SF2 and SFZ soundfonts are used to provide the sounds. There are several
soundfonts available on the internet, including a couple on the BASS webpage.
On Windows, the Creative 28MB (28MBGM.SF2), 8MB (CT8MGM.SF2), 4MB (CT4MGM.SF2),
or 2MB (CT2MGM.SF2) soundfont will be used by default when present in the
Windows system directory.
The usage information in the BASS.TXT file (from the BASS package) is also
applicable to BASSMIDI and other add-ons.
TIP: The BASSMIDI.CHM file should be put in the same directory as the BASS.CHM
file, so that the BASSMIDI documentation can be accessed from within the
BASS documentation.
iOS version
-----------
The CoreMIDI framework is required for MIDI input, so that should be added to
the "Link Binary With Libraries" build phase in Xcode.
Latest Version
==============
The latest versions of BASSMIDI & BASS can be found at the BASS website:
www.un4seen.com
Licence
=======
BASSMIDI is free to use with BASS.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, BASSMIDI IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND/OR FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS SHALL NOT BE HELD
LIABLE FOR ANY DAMAGE THAT MAY RESULT FROM THE USE OF BASSMIDI. YOU USE
BASSMIDI ENTIRELY AT YOUR OWN RISK.
Usage of BASSMIDI indicates that you agree to the above conditions.
All trademarks and other registered names contained in the BASSMIDI
package are the property of their respective owners.
History
=======
These are the major (and not so major) changes in each release, along with the
functions/options that are introduced/affected by them. There are other little
tweaks and fixes made along the way too.
2.4.15 - 9/10/2024
------------------
* Support for Key On Velocity to attackModEnv/decayModEnv/releaseModEnv and
Key Number to startAddrsOffset SF2 modulators
BASS_MIDI_FontInit/User
* Support for fileg_vel2attack/fileg_vel2decay/fileg_vel2release/pitcheg_vel2attack/
pitcheg_vel2decay/pitcheg_vel2release SFZ opcodes
BASS_MIDI_FontInit/User
* Improved SFZ variable parsing compatibility (uses the shortest match)
BASS_MIDI_FontInit/User
* Support for high-pass filter in fil_type SFZ opcode
BASS_MIDI_FontInit/User
* SoundBlaster hardware limit emulation is disabled by default for modern SF2 soundfonts
BASS_MIDI_FONT_SBLIMITS/NOSBLIMITS (BASS_MIDI_FontInit/User flags)
* Extended filter cutoff range when SB limits are disabled
BASS_MIDI_FONT_NOSBLIMITS (BASS_MIDI_FontInit/User flag)
* Improved single note releasing when there are overlapping instances of the same note
BASS_MIDI_NOTEOFF1 (BASS_MIDI_StreamCreateFile/User/URL flag)
* Ports above 7 are mapped to lower ports (modulo 8)
BASS_MIDI_StreamCreateFile
* Higher ports are shifted to lower channels when lower ports are unused
BASS_MIDI_StreamCreateFile
* Default per-drum USERFX levels to 127 instead of 0 in all modes
BASS_MIDI_NODRUMPARAMUSER (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
* Per-drum key settings may be applied to all keys at once
MIDI_EVENT_DRUM_xxx (BASS_MIDI_StreamEvent/s)
* System mode/reset events are ignored from additional ports
BASS_MIDI_StreamCreateFile/User/URL
BASS_MIDI_StreamEvents
* Sequencer specific meta-event retrieval
BASS_MIDI_MARK_SEQSPEC (BASS_MIDI_StreamGetMark type)
* Queued event buffer preallocation
BASS_ATTRIB_MIDI_QUEUE_TICK/BYTE/ASYNC (BASS_ChannelSetAttribute options)
* Faster SFZ info retrieval
BASS_MIDI_FontGetInfo
* Support for SF2 soundfonts embedded in RMID files
BASS_MIDI_StreamCreateFile/User/URL
* RIFF/RMID "INFO" tag support
BASS_TAG_RIFF_INFO (BASS_ChannelGetTags type)
* MIDI filename retrieval
BASS_CHANNELINFO (filename member)
* Approximate support for AWE32 filter NRPN (7f15/7f16)
MIDI_EVENT_CUTOFF/RESONANCE
* Maximum voices is practically unlimited (~14 million)
BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
2.4.14 - 3/5/2022
-----------------
* Support for Key On Velocity to startAddrsOffset/modEnvToFilterFc and CC21-24 to initialFilterFc/
initialAttenuation/attackVolEnv/decayVolEnv/releaseVolEnv/releaseModEnv/modEnvToFilterFc SF2 modulators
BASS_MIDI_FontInit/User
* Support for all Key On Velocity to initialAttenuation SF2 modulator curve types
BASS_MIDI_FontInit/User
* Support for SF3 (compressed SF2) soundfonts
BASS_MIDI_FontInit/User
* Soundfont flag setting/retrieval
BASS_MIDI_FontFlags
* Retrieval of currently loading samples
BASS_CONFIG_MIDI_SAMPLELOADING (BASS_GetConfig option)
* Channel-specific soundfont configuration
BASS_MIDI_FONT_EX2 (BASS_MIDI_StreamSetFonts/GetFonts flag)
BASS_MIDI_FONTEX2 structure
* MIDI port meta-event support (for more than 16 channels)
BASS_MIDI_StreamCreateFile/User/URL
BASS_MIDI_StreamEvents
BASS_MIDI_ConvertEvents
* Asynchronous processing of live events
BASS_MIDI_ASYNC (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
BASS_MIDI_EVENTS_ASYNC (BASS_MIDI_StreamEvents flag)
BASS_MIDI_EVENTS_FLUSH (BASS_MIDI_StreamEvents flag)
SYNTH example updated
* Filtering of live events
BASS_MIDI_EVENTS_FILTER (BASS_MIDI_StreamEvents flag)
* Improved reverb effect
* Reverb/chorus levels raised (closer to Roland/Yamaha levels)
* Current reverb/chorus type retrieval
MIDI_EVENT_REVERB_MACRO (BASS_MIDI_StreamGetEvent)
MIDI_EVENT_CHORUS_MACRO (BASS_MIDI_StreamGetEvent)
* Treat soundfont reverb/chorus levels as minimums
BASS_MIDI_FONT_MINFX (BASS_MIDI_FontInit/User/Flags flag)
* Default per-drum reverb/chorus levels now apply in all modes and can be disabled
BASS_MIDI_NODRUMPARAM (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
* Default drum channel configuration
BASS_EVENT_DEFDRUMS (BASS_MIDI_StreamEvent/s and BASS_MIDI_StreamCreateEvents)
* Support for master tuning
MIDI_EVENT_MASTER_FINETUNE/COARSETUNE (BASS_MIDI_StreamEvent/s)
* Omni-on/off (CC124/125) are treated as all-notes-off (CC123)
BASS_MIDI_StreamCreateFile/User/URL
BASS_MIDI_StreamEvents
BASS_MIDI_ConvertEvents
* 16 point sinc interpolation support on ARM platforms with NEON
BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
* Version number retrieval
BASS_MIDI_GetVersion
* BASS_CONFIG_MIDI_SFZHEAD value changed (was same as BASS_CONFIG_MIDI_SAMPLEREAD)
BASS_CONFIG_MIDI_SFZHEAD (BASS_SetConfigPtr option)
* MIDI implementation chart added to documentation
2.4.13 - 16/9/2020
------------------
* Vibrato rate/depth/delay adjustment
MIDI_EVENT_VIBRATO_RATE/DEPTH/DELAY (BASS_MIDI_StreamEvent/s)
* Support for Key Number to initialAttenuation/initialFilterFc/pan and Key On Velocity
to decayVolEnv/releaseVolEnv SF2 modulators
BASS_MIDI_FontInit/User
* Support for amp_keycenter/amp_keytrack/ampeg_vel2release/delay_beats/fil_keycenter/
fil_keytrack/locc67/hicc67/pan_keycenter/pan_keytrack/sw_default/sw_last/sw_lokey/
sw_lolast/sw_hikey/sw_hilast SFZ opcodes
BASS_MIDI_FontInit/User
* Support for global and master headers and #define directive in SFZ files
BASS_MIDI_FontInit/User
* SFZ files share memory for common sample files
BASS_MIDI_FontInit/User
* Partial sample loading and unloading
BASS_MIDI_FontLoadEx
SYNTH example updated
* Non-interpolated resampling option
BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
* Tempo modification attribute
BASS_ATTRIB_MIDI_SPEED (BASS_ChannelSetAttribute option)
MIDITEST example updated
* Mix level control
BASS_ATTRIB_MIDI_VOL (BASS_ChannelSetAttribute option)
* Reverb level modification
BASS_ATTRIB_MIDI_REVERB (BASS_ChannelSetAttribute option)
* Global SFZ headers
BASS_CONFIG_MIDI_SFZHEAD (BASS_SetConfigPtr option)
* Linear volume envelopes option
BASS_MIDI_FONT_LINDECVOL (BASS_MIDI_FontInit/User flag)
* Disabling of sample ramping-in
BASS_MIDI_FONT_NORAMPIN (BASS_MIDI_FontInit/User flag)
* Disabling of Creative/SoundBlaster hardware limit emulation
BASS_MIDI_FONT_NOLIMITS (BASS_MIDI_FontInit flag)
* Duplicate soundfonts will be reloaded instead of shared if modified in the meantime
BASS_MIDI_FontInit
* Memory-mapped support for default soundfont option
BASS_CONFIG_MIDI_DEFFONT
* Retrieval of total memory usage for sample data
BASS_CONFIG_MIDI_SAMPLEMEM (BASS_GetConfig option)
* Total sample data size available for SFZ files
BASS_MIDI_FontGetInfo
* Adjustable asynchronous sample loading chunks
BASS_CONFIG_MIDI_SAMPLEREAD (BASS_SetConfig option)
* CPU usage limiting is enabled by default during playback
BASS_MIDI_StreamCreate/Events/File/User/URL
BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
* Option to limit sample loading waiting without killing voices
BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
* Tick-based timing for realtime event streams
BASS_MIDI_StreamCreate
BASS_MIDI_StreamEvents
BASS_ATTRIB_MIDI_PPQN (BASS_ChannelSetAttribute option)
* 48000 Hz soundfont data encoding option
BASS_MIDI_PACK_48KHZ (BASS_MIDI_FontPack flag)
* macOS examples rewritten in Objective-C/Cocoa
2.4.12 - 9/11/2018
------------------
* Support for more than 16 MIDI channels in custom event sequences
BASS_MIDI_StreamCreateEvents
* Absolute timing option for custom events
BASS_MIDI_EVENTS_ABSTIME (BASS_MIDI_StreamEvents flag)
* Retrieval of note-on events
MIDI_EVENT_NOTES (BASS_MIDI_StreamGetEvents/Ex filter)
* Soundfont config can be modified without stopping currently playing notes
BASS_MIDI_StreamSetFonts
* Memory-mapped soundfonts can be preloaded/mapped
BASS_MIDI_FontLoad
* Support for Key On Velocity to initialAttenuation SF2 modulators
BASS_MIDI_FontInit/User
* Linear attack phase option for SF2 modulation envelopes
BASS_MIDI_FONT_LINATTMOD (BASS_MIDI_FontInit/User flag)
* The attack phase of SFZ pitch/filter envelopes is now linear instead of convex
* Support for trigger/rt_decay/delay/amplfo_fade/fillfo_fade/pitchlfo_fade/pitch_random/
xfin_lokey/xfin_hikey/xfout_lokey/xfout_hikey/xf_keycurve/xfin_lovel/xfin_hivel/
xfout_lovel/xfout_hivel/xf_velcurve SFZ opcodes
BASS_MIDI_FontInit/User
* Support for separate amplifier/filter/pitch LFOs in SFZ
BASS_MIDI_FontInit/User
* Support for UTF-8 sample SFZ opcodes on Windows (already on other platforms)
BASS_MIDI_FontInit/User
* Support for #include directive in SFZ files
BASS_MIDI_FontInit
* SFZ files are no longer kept open/locked after being loaded
BASS_MIDI_FontInit
* Samples given more time to load asynchronously when CPU usage is low
BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
* BASS_MIDI_SINCINTER flag deprecated in favour of BASS_ATTRIB_MIDI_SRC attribute
BASS_MIDI_StreamCreate/Events/File/User/URL
* Smoother low-pass filter activation and deactivation
* Fix for transpose/tune SFZ opcodes with encoded samples
2.4.11 - 30/3/2017
------------------
* Event modification/filtering
BASS_MIDI_StreamSetFilter
MIDIFILTERPROC
* Simpler tempo modification
MIDI_EVENT_SPEED (BASS_MIDI_StreamEvent)
MIDITEST example updated
* Checking whether individual notes are playing
MIDI_EVENT_NOTE (BASS_MIDI_StreamGetEvent)
* Retrieval of total number of notes playing in a channel
MIDI_EVENT_NOTES (BASS_MIDI_StreamGetEvent)
* Retrieval of currently active voices in a channel
MIDI_EVENT_VOICES (BASS_MIDI_StreamGetEvent)
* Retrieval of currently in use presets
BASS_MIDI_StreamGetPreset
* SFZ filenames are used as preset names
BASS_MIDI_FontGetPreset
* Support for loop info in FLAC samples used with SFZ (requires BASSFLAC 2.4.3)
* Faster loading of very large MIDI files
BASS_MIDI_StreamCreateFile/User/URL
* Faster unfiltered event counting
BASS_MIDI_StreamGetEvents/Ex
BASS_MIDI_ConvertEvents
* 24-bit paramater passed to MIDI_EVENT_TEMPO event sync callbacks
BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
* When getting the number of events, only those in the specified range are counted
BASS_MIDI_StreamGetEventsEx
* Invalid event types in custom sequences will give an error instead of being ignored
BASS_MIDI_StreamCreateEvents
2.4.10 - 8/12/2016
------------------
* 16 point sinc interpolation option
BASS_ATTRIB_MIDI_SRC (BASS_ChannelSetAttribute option)
* Support for lorand/hirand/locc1/hicc1/locc64/hicc64/off_mode/default_path SFZ opcodes
BASS_MIDI_FontInit/User
* Support for Key On Velocity to initialFilterFc/attackVolEnv SF2 modulators
BASS_MIDI_FontInit/User
* Conversion of raw MIDI data to BASS_MIDI_EVENT
BASS_MIDI_ConvertEvents
* Modulation (CC1) destination control
MIDI_EVENT_MOD_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
MIDI_EVENT_MODRANGE superseded by MIDI_EVENT_MOD_VIBRATO
* Sostenuto
MIDI_EVENT_SOSTENUTO (BASS_MIDI_StreamEvent/s)
* Legato channel mode
MIDI_EVENT_MODE (BASS_MIDI_StreamEvent)
* Partial retrieval of events
BASS_MIDI_StreamGetEventsEx
* Bulk MIDI state retrieval/setting
BASS_ATTRIB_MIDI_STATE (BASS_ChannelGet/SetAttributeEx option)
* Support for delaying custom events, including delta-time info in raw MIDI data
BASS_MIDI_EVENTS_TIME (BASS_MIDI_StreamEvents flag)
* Cancellation of pending custom events
BASS_MIDI_EVENTS_CANCEL (BASS_MIDI_StreamEvents flag)
* Marker for the start of each track in SMF2 files
BASS_MIDI_MARK_TRACKSTART (BASS_MIDI_StreamGetMark type)
* Ignoring of soundfont effect levels
BASS_MIDI_FONT_NOFX (BASS_MIDI_FontInit/Ex flag)
* Maximum voice limit increased to 100000
BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
* Unicode support for default soundfont option on Windows
BASS_CONFIG_MIDI_DEFFONT
* BASS_CONFIG_UNICODE option support for input device names
BASS_MIDI_InGetDeviceInfo
* Improved seeking with MIDI files that have events for a channel in multiple tracks
BASS_ChannelSetPosition
* Fix for 2GB size limit when unpacking a soundfont on Windows
BASS_MIDI_FontUnpack
2.4.9 - 4/12/2014
-----------------
* SFZ soundfont support
BASS_MIDI_FontInit/User
* Support for XG drums in bank 127 of SF2 soundfonts
BASS_MIDI_FONT_XGDRUMS (BASS_MIDI_FontInit/Ex flag)
* Key pressure/aftertouch support
MIDI_EVENT_KEYPRES (BASS_MIDI_StreamEvent/s)
MIDI_EVENT_KEYPRES_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
* 3rd effect path for custom processing
BASS_MIDI_CHAN_USERFX (BASS_MIDI_StreamGetChannel option)
MIDI_EVENT_USERFX (BASS_MIDI_StreamEvent/s)
MIDI_EVENT_USERFX_LEVEL (BASS_MIDI_StreamEvent/s)
MIDI_EVENT_USERFX_REVERB (BASS_MIDI_StreamEvent/s)
MIDI_EVENT_USERFX_CHORUS (BASS_MIDI_StreamEvent/s)
* Custom reverb/chorus effect processing
BASS_MIDI_CHAN_CHORUS/REVERB (BASS_MIDI_StreamGetChannel options)
* Custom channel processing output routed to reverb/chorus/custom effects
BASS_MIDI_StreamGetChannel
* Default drum reverb/chorus levels set to XG spec in XG mode (GS/GM modes too)
MIDI_EVENT_DRUM_REVERB/CHORUS (BASS_MIDI_StreamEvent/s)
* Decay time event
MIDI_EVENT_DECAY (BASS_MIDI_StreamEvent/s)
* Support for up to 65536 presets per bank
BASS_MIDI_StreamSetFonts
MIDI_EVENT_PROGRAM (BASS_MIDI_StreamEvent/s)
* Input ports to receive MIDI data from other software on Linux
BASS_MIDI_InInit
BASS_CONFIG_MIDI_IN_PORTS (BASS_SetConfig option)
SYNTH example updated
* Single note releasing when there are overlapping instances of the same note
BASS_MIDI_NOTEOFF1 (BASS_MIDI_StreamCreateFile/User/URL flag)
* Ignoring of system resets with unchanged mode
BASS_MIDI_NOSYSRESET (BASS_MIDI_StreamCreateFile/User/URL flag)
MIDI_EVENT_SYSTEM (BASS_MIDI_StreamEvent/s)
* Disabling of running status
BASS_MIDI_EVENTS_NORSTATUS (BASS_MIDI_StreamEvents flag)
* Maximum voice limit increased to 1000
BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
* Reduction of 24-bit data to 16-bit when packing soundfont samples
BASS_MIDI_PACK_16BIT (BASS_MIDI_FontPack flag)
* Support for remaining SF2 generators: fixed key, fixed velocity, key to vol/mod envelope hold/decay
* Fix for multi-track custom event sequence stream creation
BASS_MIDI_StreamCreateEvents
2.4.8 - 2/5/2013
----------------
* User file soundfont loading
BASS_MIDI_FontInitUser
* Retrieval of all of a soundfont's preset numbers
BASS_MIDI_FontGetPresets
* More flexible soundfont preset mapping
BASS_MIDI_FONT_EX (BASS_MIDI_StreamSetFonts/GetFonts flag)
BASS_MIDI_FONTEX structure
* Bank LSB controller support
MIDI_EVENT_BANK_LSB (BASS_MIDI_StreamEvent/s)
BASS_MIDI_FONTEX structure
* Modulation depth range control
MIDI_EVENT_MODRANGE (BASS_MIDI_StreamEvent/s)
* Channel pressure destination control
MIDI_EVENT_CHANPRES_VIBRATO/PITCH/FILTER/VOLUME (BASS_MIDI_StreamEvent/s)
* Unhandled controller event
MIDI_EVENT_CONTROL (BASS_MIDI_StreamEvent/s)
* Reverb send level default changed to 40 (was 0)
MIDI_EVENT_REVERB (BASS_MIDI_StreamEvent/s)
* Retrieval of events from all tracks at once
BASS_MIDI_StreamGetEvents
* Copyright/instrument/track name markers
BASS_MIDI_MARK_COPY (BASS_MIDI_StreamGetMark type)
BASS_MIDI_MARK_INST (BASS_MIDI_StreamGetMark type)
BASS_MIDI_MARK_TRACK (BASS_MIDI_StreamGetMark type)
* Retrieval of all markers at once
BASS_MIDI_StreamGetMarks
* New sync type that supports all marker types
BASS_SYNC_MIDI_MARK (BASS_ChannelSetSync type)
* Non-removal of empty space at the end of a MIDI file
BASS_MIDI_NOCROP (BASS_MIDI_StreamCreateFile/User/URL flag)
* Omission of a WAVE header when packing soundfont samples
BASS_MIDI_PACK_NOHEAD (BASS_MIDI_FontPack flag)
* Streams created via the plugin system use the output device's sample rate
BASS_StreamCreateFile/etc
* Automatic BASS_UNICODE flag use in C++ and Delphi
BASS_MIDI_StreamCreateFile/URL
BASS_MIDI_FontInit/Pack/Unpack
2.4.7 - 29/6/2012
-----------------
* Custom event sequence streams
BASS_MIDI_StreamCreateEvents
* Sinc interpolated sample mixing
BASS_MIDI_SINCINTER (BASS_MIDI_StreamCreate/Events/File/User/URL flag)
* Asynchronous sample loading
BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
* Preset unloading
BASS_MIDI_FontUnload
* Note stopping without sustain/decay
BASS_EVENT_NOTE (BASS_MIDI_StreamEvent/s)
* Syncing on all event types
BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
* Marker tick position retrieval
BASS_MIDI_MARK_TICK (BASS_MIDI_StreamGetMark flag)
* Maximum voice limit increased to 500
BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
* Default voice limit raised to 40 on Android/iOS
BASS_CONFIG_MIDI_VOICES (BASS_SetConfig option)
* Active voice count retrieval
BASS_ATTRIB_MIDI_VOICES_ACTIVE (BASS_ChannelGetAttribute option)
* Use of the device's current output rate
BASS_MIDI_StreamCreate/Events/File/User/URL
* Memory-mapped soundfont loading
BASS_MIDI_FONT_MMAP (BASS_MIDI_FontInit flag)
* Fix for applying multiple events in BASS_MIDI_EVENTS_STRUCT mode
BASS_MIDI_StreamEvents
* Marker sync compatibility (with mixer/splitter/tempo/reverse streams) fix
BASS_SYNC_MIDI_MARKER/CUE/LYRIC (BASS_ChannelSetSync types)
* MIDI sysex input compatibility fix for some drivers on Windows
MIDIINPROC
2.4.6 - 30/3/2011
-----------------
* MIDI input device support
BASS_MIDI_InGetDeviceInfo
BASS_MIDI_InInit
BASS_MIDI_InFree
BASS_MIDI_InStart
BASS_MIDI_InStop
MIDIINPROC
SYNTH example updated
* Multiple event processing including support for raw MIDI data
BASS_MIDI_StreamEvents
* CPU usage limiting
BASS_ATTRIB_MIDI_CPU (BASS_ChannelSetAttribute option)
* Scale/octave tuning
MIDI_EVENT_SCALETUNING (BASS_MIDI_StreamEvent/s)
* Soft pedal event
MIDI_EVENT_SOFT (BASS_MIDI_StreamEvent/s)
* Random panning
MIDI_EVENT_PAN (BASS_MIDI_StreamEvent/s)
* System reset event
MIDI_EVENT_SYSTEM/EX (BASS_MIDI_StreamEvent/s)
* Resetting of overridden drum key pan/reverb/chorus back to normal
MIDI_EVENT_DRUM_PAN/REVERB/CHORUS (BASS_MIDI_StreamEvent)
* Retrieval of drum key event values
BASS_MIDI_StreamGetEvent
* All events initialized to a MIDI file's 1st tick values
BASS_MIDI_StreamGetEvent
* Adjustable MIDI channel count
BASS_ATTRIB_MIDI_CHANS (BASS_ChannelSetAttribute option)
* Adjustable voice limit
BASS_ATTRIB_MIDI_VOICES (BASS_ChannelSetAttribute option)
* Preloaded presets are not automatically compacted
BASS_MIDI_FontLoad
BASS_CONFIG_MIDI_COMPACT (BASS_SetConfig option)
* Multiple instances of a soundfont
BASS_MIDI_FontInit
* Xcode examples project added for OSX
2.4.5 - 8/2/2010
----------------
* Key signature retrieval
BASS_MIDI_MARK_KEYSIG (BASS_MIDI_StreamGetMark type)
BASS_SYNC_MIDI_KEYSIG (BASS_ChannelSetSync type)
* Tempo event initialized to MIDI file's 1st tick value
MIDI_EVENT_TEMPO (BASS_MIDI_StreamGetEvent)
* UTF-16 support on OSX
BASS_UNICODE (BASS_MIDI_StreamCreateFile/BASS_MIDI_FontInit/Pack/Unpack flag)
2.4.4 - 24/8/2009
-----------------
* Attack & release time events
MIDI_EVENT_ATTACK/RELEASE (BASS_MIDI_StreamEvent)
* Drum key level NRPN event
MIDI_EVENT_DRUM_LEVEL (BASS_MIDI_StreamEvent)
* MIDI file event retrieval
BASS_MIDI_StreamGetEvents
* Time signature retrieval
BASS_MIDI_MARK_TIMESIG (BASS_MIDI_StreamGetMark type)
BASS_SYNC_MIDI_TIMESIG (BASS_ChannelSetSync type)
* Default soundfont configuration
BASS_CONFIG_MIDI_DEFFONT (BASS_SetConfig option)
2.4.3 - 19/3/2009
-----------------
* Possibility of applying DSP/FX to individual MIDI channels
BASS_MIDI_StreamGetChannel
* Per-track volume control
BASS_ATTRIB_MIDI_TRACK_VOL (BASS_ChannelSetAttribute option)
* Support for all tracks in format 2 MIDI files
BASS_MIDI_StreamCreateFile/User/URL
2.4.2 - 28/10/2008
------------------
* Decaying of old sound when seeking
BASS_MIDI_DECAYSEEK (BASS_MIDI_StreamCreateFile/User/URL flag)
MIDITEST example updated (C version)
* End decaying now also applies when looping
BASS_MIDI_DECAYEND (BASS_MIDI_StreamCreateFile/User/URL flag)
* Support for 28MBGM.SF2 and CT8MGM.SF2 as default soundfonts
2.4.1 - 9/7/2008
----------------
* Ticks-per-beat retrieval
BASS_ATTRIB_MIDI_PPQN (BASS_ChannelGetAttribute option)
2.4 - 2/4/2008
--------------
* Tick-based positioning
BASS_POS_MIDI_TICK (BASS_ChannelGetLength/GetPosition/SetPosition mode)
BASS_SYNC_MIDI_TICK (BASS_ChannelSetSync type)
* Preset name retrieval
BASS_MIDI_FontGetPreset
* Text markers
BASS_MIDI_MARK_TEXT (BASS_MIDI_StreamGetMark type)
BASS_SYNC_MIDI_TEXT (BASS_ChannelSetSync type)
* Individual marker retrieval
BASS_MIDI_StreamGetMark
BASS_MIDI_StreamGetMarks *removed*
* Marker index passed to marker sync callbacks
BASS_SYNC_MIDI_MARKER/CUE/LYRIC
* Use of BASS_Init sample rate
BASS_MIDI_StreamCreate/File/User/URL
* Support for updated user file stream system
BASS_MIDI_StreamCreateFileUser
* 64-bit file positioning
BASS_MIDI_StreamCreateFile
* Callback "user" parameters changed to pointers
BASS_MIDI_StreamCreateURL
BASS_MIDI_StreamCreateFileUser
2.3.0.3 - 10/7/2007
-------------------
* Syncing on events
BASS_SYNC_MIDI_EVENT (BASS_ChannelSetSync type)
2.3.0.2 - 26/2/2007
-------------------
* Reverb and chorus
MIDI_EVENT_REVERB/CHORUS (BASS_MIDI_StreamEvent)
MIDI_EVENT_REVERB_TIME/DELAY/LOCUTOFF/HICUTOFF/LEVEL (BASS_MIDI_StreamEvent)
MIDI_EVENT_CHORUS_DELAY/DEPTH/RATE/FEEDBACK/LEVEL/REVERB (BASS_MIDI_StreamEvent)
BASS_MIDI_NOFX (BASS_MIDI_StreamCreate/File/User/URL flag)
* Resonant low-pass filters
MIDI_EVENT_CUTOFF/RESONANCE (BASS_MIDI_StreamEvent)
* Portamento
MIDI_EVENT_PORTAMENTO/TIME/NOTE (BASS_MIDI_StreamEvent)
* Fine-tuning
MIDI_EVENT_FINETUNE/COARSETUNE (BASS_MIDI_StreamEvent)
* Drum key specific parameters
MIDI_EVENT_DRUM_FINETUNE/COARSETUNE/PAN/REVERB/CHORUS/CUTOFF/RESONANCE (BASS_MIDI_StreamEvent)
* Support for mono channel mode
MIDI_EVENT_MODE (BASS_MIDI_StreamEvent)
* Support for master volume
MIDI_EVENT_MASTERVOL (BASS_MIDI_StreamEvent)
* Channel level control
MIDI_EVENT_MIXLEVEL (BASS_MIDI_StreamEvent)
* Channel transposing
MIDI_EVENT_TRANSPOSE (BASS_MIDI_StreamEvent)
* Retrieval of current event values
BASS_MIDI_StreamGetEvent
* Soundfont volume control
BASS_MIDI_FontSetVolume/GetVolume
* Track number added to markers and syncs
BASS_MIDI_MARK (track member)
BASS_SYNC_MIDI_MARKER/CUE/LYRIC
2.3.0.1 - 1/12/2006
-------------------
* Optionally apply matching soundfonts to all banks
BASS_CONFIG_MIDI_AUTOFONT (BASS_SetConfig option)
* Support for 0 length notes
2.3 - 14/11/2006
----------------
* First release
Bug reports, Suggestions, Comments, Enquiries, etc
==================================================
If you have any of the aforementioned please visit the BASS forum at the
website.

1149
bass/inc/bass.h Normal file

File diff suppressed because it is too large Load Diff

442
bass/inc/bassmidi.h Normal file
View File

@ -0,0 +1,442 @@
/*
BASSMIDI 2.4 C/C++ header file
Copyright (c) 2006-2024 Un4seen Developments Ltd.
See the BASSMIDI.CHM file for more detailed documentation
*/
#ifndef BASSMIDI_H
#define BASSMIDI_H
#include "bass.h"
#if BASSVERSION!=0x204
#error conflicting BASS and BASSMIDI versions
#endif
#ifdef __OBJC__
typedef int BOOL32;
#define BOOL BOOL32 // override objc's BOOL
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BASSMIDIDEF
#define BASSMIDIDEF(f) WINAPI f
#else
#define NOBASSMIDIOVERLOADS
#endif
typedef DWORD HSOUNDFONT; // soundfont handle
// Additional error codes returned by BASS_ErrorGetCode
#define BASS_ERROR_MIDI_INCLUDE 7000 // SFZ include file could not be opened
// Additional BASS_SetConfig options
#define BASS_CONFIG_MIDI_COMPACT 0x10400
#define BASS_CONFIG_MIDI_VOICES 0x10401
#define BASS_CONFIG_MIDI_AUTOFONT 0x10402
#define BASS_CONFIG_MIDI_IN_PORTS 0x10404
#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406
#define BASS_CONFIG_MIDI_SAMPLEMEM 0x10407
#define BASS_CONFIG_MIDI_SAMPLEREAD 0x10408
#define BASS_CONFIG_MIDI_SAMPLELOADING 0x1040a
// Additional BASS_SetConfigPtr options
#define BASS_CONFIG_MIDI_DEFFONT 0x10403
#define BASS_CONFIG_MIDI_SFZHEAD 0x10409
// Additional sync types
#define BASS_SYNC_MIDI_MARK 0x10000
#define BASS_SYNC_MIDI_MARKER 0x10000
#define BASS_SYNC_MIDI_CUE 0x10001
#define BASS_SYNC_MIDI_LYRIC 0x10002
#define BASS_SYNC_MIDI_TEXT 0x10003
#define BASS_SYNC_MIDI_EVENT 0x10004
#define BASS_SYNC_MIDI_TICK 0x10005
#define BASS_SYNC_MIDI_TIMESIG 0x10006
#define BASS_SYNC_MIDI_KEYSIG 0x10007
// Additional BASS_MIDI_StreamCreateFile/etc flags
#define BASS_MIDI_NODRUMPARAMUSER 0x200
#define BASS_MIDI_NODRUMPARAM 0x400
#define BASS_MIDI_NOSYSRESET 0x800
#define BASS_MIDI_DECAYEND 0x1000
#define BASS_MIDI_NOFX 0x2000
#define BASS_MIDI_DECAYSEEK 0x4000
#define BASS_MIDI_NOCROP 0x8000
#define BASS_MIDI_NOTEOFF1 0x10000
#define BASS_MIDI_ASYNC 0x400000
#define BASS_MIDI_SINCINTER 0x800000
// BASS_MIDI_FontInit flags
#define BASS_MIDI_FONT_MEM 0x10000
#define BASS_MIDI_FONT_MMAP 0x20000
#define BASS_MIDI_FONT_XGDRUMS 0x40000
#define BASS_MIDI_FONT_NOFX 0x80000
#define BASS_MIDI_FONT_LINATTMOD 0x100000
#define BASS_MIDI_FONT_LINDECVOL 0x200000
#define BASS_MIDI_FONT_NORAMPIN 0x400000
#define BASS_MIDI_FONT_NOSBLIMITS 0x800000
#define BASS_MIDI_FONT_NOLIMITS BASS_MIDI_FONT_NOSBLIMITS
#define BASS_MIDI_FONT_MINFX 0x1000000
#define BASS_MIDI_FONT_SBLIMITS 0x2000000
typedef struct {
HSOUNDFONT font; // soundfont
int preset; // preset number (-1=all)
int bank;
} BASS_MIDI_FONT;
typedef struct {
HSOUNDFONT font; // soundfont
int spreset; // source preset number
int sbank; // source bank number
int dpreset; // destination preset/program number
int dbank; // destination bank number
int dbanklsb; // destination bank number LSB
} BASS_MIDI_FONTEX;
typedef struct {
HSOUNDFONT font; // soundfont
int spreset; // source preset number
int sbank; // source bank number
int dpreset; // destination preset/program number
int dbank; // destination bank number
int dbanklsb; // destination bank number LSB
DWORD minchan; // minimum channel number
DWORD numchan; // number of channels from minchan
} BASS_MIDI_FONTEX2;
// BASS_MIDI_StreamSet/GetFonts flag
#define BASS_MIDI_FONT_EX 0x1000000 // BASS_MIDI_FONTEX
#define BASS_MIDI_FONT_EX2 0x2000000 // BASS_MIDI_FONTEX2
typedef struct {
const char *name;
const char *copyright;
const char *comment;
DWORD presets; // number of presets/instruments
DWORD samsize; // total size (in bytes) of the sample data
DWORD samload; // amount of sample data currently loaded
DWORD samtype; // sample format (CTYPE) if packed
} BASS_MIDI_FONTINFO;
typedef struct {
DWORD track; // track containing marker
DWORD pos; // marker position
const char *text; // marker text
} BASS_MIDI_MARK;
// Marker types
#define BASS_MIDI_MARK_MARKER 0 // marker
#define BASS_MIDI_MARK_CUE 1 // cue point
#define BASS_MIDI_MARK_LYRIC 2 // lyric
#define BASS_MIDI_MARK_TEXT 3 // text
#define BASS_MIDI_MARK_TIMESIG 4 // time signature
#define BASS_MIDI_MARK_KEYSIG 5 // key signature
#define BASS_MIDI_MARK_COPY 6 // copyright notice
#define BASS_MIDI_MARK_TRACK 7 // track name
#define BASS_MIDI_MARK_INST 8 // instrument name
#define BASS_MIDI_MARK_TRACKSTART 9 // track start (SMF2)
#define BASS_MIDI_MARK_SEQSPEC 10 // sequencer-specific
#define BASS_MIDI_MARK_TICK 0x10000 // flag: get position in ticks (otherwise bytes)
// MIDI events
#define MIDI_EVENT_NOTE 1
#define MIDI_EVENT_PROGRAM 2
#define MIDI_EVENT_CHANPRES 3
#define MIDI_EVENT_PITCH 4
#define MIDI_EVENT_PITCHRANGE 5
#define MIDI_EVENT_DRUMS 6
#define MIDI_EVENT_FINETUNE 7
#define MIDI_EVENT_COARSETUNE 8
#define MIDI_EVENT_MASTERVOL 9
#define MIDI_EVENT_BANK 10
#define MIDI_EVENT_MODULATION 11
#define MIDI_EVENT_VOLUME 12
#define MIDI_EVENT_PAN 13
#define MIDI_EVENT_EXPRESSION 14
#define MIDI_EVENT_SUSTAIN 15
#define MIDI_EVENT_SOUNDOFF 16
#define MIDI_EVENT_RESET 17
#define MIDI_EVENT_NOTESOFF 18
#define MIDI_EVENT_PORTAMENTO 19
#define MIDI_EVENT_PORTATIME 20
#define MIDI_EVENT_PORTANOTE 21
#define MIDI_EVENT_MODE 22
#define MIDI_EVENT_REVERB 23
#define MIDI_EVENT_CHORUS 24
#define MIDI_EVENT_CUTOFF 25
#define MIDI_EVENT_RESONANCE 26
#define MIDI_EVENT_RELEASE 27
#define MIDI_EVENT_ATTACK 28
#define MIDI_EVENT_DECAY 29
#define MIDI_EVENT_REVERB_MACRO 30
#define MIDI_EVENT_CHORUS_MACRO 31
#define MIDI_EVENT_REVERB_TIME 32
#define MIDI_EVENT_REVERB_DELAY 33
#define MIDI_EVENT_REVERB_LOCUTOFF 34
#define MIDI_EVENT_REVERB_HICUTOFF 35
#define MIDI_EVENT_REVERB_LEVEL 36
#define MIDI_EVENT_CHORUS_DELAY 37
#define MIDI_EVENT_CHORUS_DEPTH 38
#define MIDI_EVENT_CHORUS_RATE 39
#define MIDI_EVENT_CHORUS_FEEDBACK 40
#define MIDI_EVENT_CHORUS_LEVEL 41
#define MIDI_EVENT_CHORUS_REVERB 42
#define MIDI_EVENT_USERFX 43
#define MIDI_EVENT_USERFX_LEVEL 44
#define MIDI_EVENT_USERFX_REVERB 45
#define MIDI_EVENT_USERFX_CHORUS 46
#define MIDI_EVENT_DRUM_FINETUNE 50
#define MIDI_EVENT_DRUM_COARSETUNE 51
#define MIDI_EVENT_DRUM_PAN 52
#define MIDI_EVENT_DRUM_REVERB 53
#define MIDI_EVENT_DRUM_CHORUS 54
#define MIDI_EVENT_DRUM_CUTOFF 55
#define MIDI_EVENT_DRUM_RESONANCE 56
#define MIDI_EVENT_DRUM_LEVEL 57
#define MIDI_EVENT_DRUM_USERFX 58
#define MIDI_EVENT_SOFT 60
#define MIDI_EVENT_SYSTEM 61
#define MIDI_EVENT_TEMPO 62
#define MIDI_EVENT_SCALETUNING 63
#define MIDI_EVENT_CONTROL 64
#define MIDI_EVENT_CHANPRES_VIBRATO 65
#define MIDI_EVENT_CHANPRES_PITCH 66
#define MIDI_EVENT_CHANPRES_FILTER 67
#define MIDI_EVENT_CHANPRES_VOLUME 68
#define MIDI_EVENT_MOD_VIBRATO 69
#define MIDI_EVENT_MODRANGE 69
#define MIDI_EVENT_BANK_LSB 70
#define MIDI_EVENT_KEYPRES 71
#define MIDI_EVENT_KEYPRES_VIBRATO 72
#define MIDI_EVENT_KEYPRES_PITCH 73
#define MIDI_EVENT_KEYPRES_FILTER 74
#define MIDI_EVENT_KEYPRES_VOLUME 75
#define MIDI_EVENT_SOSTENUTO 76
#define MIDI_EVENT_MOD_PITCH 77
#define MIDI_EVENT_MOD_FILTER 78
#define MIDI_EVENT_MOD_VOLUME 79
#define MIDI_EVENT_VIBRATO_RATE 80
#define MIDI_EVENT_VIBRATO_DEPTH 81
#define MIDI_EVENT_VIBRATO_DELAY 82
#define MIDI_EVENT_MASTER_FINETUNE 83
#define MIDI_EVENT_MASTER_COARSETUNE 84
#define MIDI_EVENT_MIXLEVEL 0x10000
#define MIDI_EVENT_TRANSPOSE 0x10001
#define MIDI_EVENT_SYSTEMEX 0x10002
#define MIDI_EVENT_SPEED 0x10004
#define MIDI_EVENT_DEFDRUMS 0x10006
#define MIDI_EVENT_END 0
#define MIDI_EVENT_END_TRACK 0x10003
#define MIDI_EVENT_NOTES 0x20000
#define MIDI_EVENT_VOICES 0x20001
#define MIDI_SYSTEM_DEFAULT 0
#define MIDI_SYSTEM_GM1 1
#define MIDI_SYSTEM_GM2 2
#define MIDI_SYSTEM_XG 3
#define MIDI_SYSTEM_GS 4
typedef struct {
DWORD event; // MIDI_EVENT_xxx
DWORD param;
DWORD chan;
DWORD tick; // event position (ticks)
DWORD pos; // event position (bytes)
} BASS_MIDI_EVENT;
// BASS_MIDI_StreamEvents modes
#define BASS_MIDI_EVENTS_STRUCT 0 // BASS_MIDI_EVENT structures
#define BASS_MIDI_EVENTS_RAW 0x10000 // raw MIDI event data
#define BASS_MIDI_EVENTS_SYNC 0x1000000 // flag: trigger event syncs
#define BASS_MIDI_EVENTS_NORSTATUS 0x2000000 // flag: no running status
#define BASS_MIDI_EVENTS_CANCEL 0x4000000 // flag: cancel pending events
#define BASS_MIDI_EVENTS_TIME 0x8000000 // flag: delta-time info is present
#define BASS_MIDI_EVENTS_ABSTIME 0x10000000 // flag: absolute time info is present
#define BASS_MIDI_EVENTS_ASYNC 0x20000000 // flag: process asynchronously
#define BASS_MIDI_EVENTS_FILTER 0x40000000 // flag: apply filtering
#define BASS_MIDI_EVENTS_FLUSH 0x80000000 // flag: flush async events
// BASS_MIDI_StreamGetChannel special channels
#define BASS_MIDI_CHAN_CHORUS (DWORD)-1
#define BASS_MIDI_CHAN_REVERB (DWORD)-2
#define BASS_MIDI_CHAN_USERFX (DWORD)-3
// BASS_CHANNELINFO type
#define BASS_CTYPE_STREAM_MIDI 0x10d00
// Additional attributes
#define BASS_ATTRIB_MIDI_PPQN 0x12000
#define BASS_ATTRIB_MIDI_CPU 0x12001
#define BASS_ATTRIB_MIDI_CHANS 0x12002
#define BASS_ATTRIB_MIDI_VOICES 0x12003
#define BASS_ATTRIB_MIDI_VOICES_ACTIVE 0x12004
#define BASS_ATTRIB_MIDI_STATE 0x12005
#define BASS_ATTRIB_MIDI_SRC 0x12006
#define BASS_ATTRIB_MIDI_KILL 0x12007
#define BASS_ATTRIB_MIDI_SPEED 0x12008
#define BASS_ATTRIB_MIDI_REVERB 0x12009
#define BASS_ATTRIB_MIDI_VOL 0x1200a
#define BASS_ATTRIB_MIDI_QUEUE_TICK 0x1200b
#define BASS_ATTRIB_MIDI_QUEUE_BYTE 0x1200c
#define BASS_ATTRIB_MIDI_QUEUE_ASYNC 0x1200d
#define BASS_ATTRIB_MIDI_TRACK_VOL 0x12100 // + track #
// Additional tag type
#define BASS_TAG_MIDI_TRACK 0x11000 // + track #, track text : array of null-terminated ANSI strings
// BASS_ChannelGetLength/GetPosition/SetPosition mode
#define BASS_POS_MIDI_TICK 2 // tick position
typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, int track, BASS_MIDI_EVENT *event, BOOL seeking, void *user);
/* Event filtering callback function.
handle : MIDI stream handle
track : Track containing the event
event : The event
seeking: TRUE = the event is being processed while seeking, FALSE = it is being played
user : The 'user' parameter value given when calling BASS_MIDI_StreamSetFilter
RETURN : TRUE = process the event, FALSE = drop the event */
// BASS_MIDI_FontLoadEx flags
#define BASS_MIDI_FONTLOAD_NOWAIT 1 // don't want for the samples to load
#define BASS_MIDI_FONTLOAD_COMPACT 2 // compact samples
#define BASS_MIDI_FONTLOAD_NOLOAD 4 // don't load (only compact)
#define BASS_MIDI_FONTLOAD_TIME 8 // length is in milliseconds
#define BASS_MIDI_FONTLOAD_KEEPDEC 16 // keep decoders
// BASS_MIDI_FontPack flags
#define BASS_MIDI_PACK_NOHEAD 1 // don't send a WAV header to the encoder
#define BASS_MIDI_PACK_16BIT 2 // discard low 8 bits of 24-bit sample data
#define BASS_MIDI_PACK_48KHZ 4 // set encoding rate to 48000 Hz (else 44100 Hz)
typedef struct {
const char *name; // description
DWORD id;
DWORD flags;
} BASS_MIDI_DEVICEINFO;
typedef void (CALLBACK MIDIINPROC)(DWORD device, double time, const BYTE *buffer, DWORD length, void *user);
/* MIDI input callback function.
device : MIDI input device
time : Timestamp
buffer : Buffer containing MIDI data
length : Number of bytes of data
user : The 'user' parameter value given when calling BASS_MIDI_InInit */
DWORD BASSMIDIDEF(BASS_MIDI_GetVersion)(void);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateEvents)(const BASS_MIDI_EVENT *events, DWORD ppqn, DWORD flags, DWORD freq);
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark);
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetMarks)(HSTREAM handle, int track, DWORD type, BASS_MIDI_MARK *marks);
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const void *fonts, DWORD count);
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, void *fonts, DWORD count);
BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle);
BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param);
DWORD BASSMIDIDEF(BASS_MIDI_StreamEvents)(HSTREAM handle, DWORD mode, const void *events, DWORD length);
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event);
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events);
DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEventsEx)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events, DWORD start, DWORD count);
BOOL BASSMIDIDEF(BASS_MIDI_StreamGetPreset)(HSTREAM handle, DWORD chan, BASS_MIDI_FONT *font);
HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan);
BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFilter)(HSTREAM handle, BOOL seeking, MIDIFILTERPROC *proc, void *user);
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags);
HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInitUser)(const BASS_FILEPROCS *procs, void *user, DWORD flags);
BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle);
BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info);
BOOL BASSMIDIDEF(BASS_MIDI_FontGetPresets)(HSOUNDFONT handle, DWORD *presets);
const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank);
BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank);
BOOL BASSMIDIDEF(BASS_MIDI_FontLoadEx)(HSOUNDFONT handle, int preset, int bank, DWORD length, DWORD flags);
BOOL BASSMIDIDEF(BASS_MIDI_FontUnload)(HSOUNDFONT handle, int preset, int bank);
BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle);
BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags);
BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags);
DWORD BASSMIDIDEF(BASS_MIDI_FontFlags)(HSOUNDFONT handle, DWORD flags, DWORD mask);
BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
DWORD BASSMIDIDEF(BASS_MIDI_ConvertEvents)(const BYTE *data, DWORD length, BASS_MIDI_EVENT *events, DWORD count, DWORD flags);
BOOL BASSMIDIDEF(BASS_MIDI_InGetDeviceInfo)(DWORD device, BASS_MIDI_DEVICEINFO *info);
BOOL BASSMIDIDEF(BASS_MIDI_InInit)(DWORD device, MIDIINPROC *proc, void *user);
BOOL BASSMIDIDEF(BASS_MIDI_InFree)(DWORD device);
BOOL BASSMIDIDEF(BASS_MIDI_InStart)(DWORD device);
BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device);
#ifdef __cplusplus
}
#ifndef NOBASSMIDIOVERLOADS
static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count)
{
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX);
}
static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX2 *fonts, DWORD count)
{
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX2);
}
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX *fonts, DWORD count)
{
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX);
}
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX2 *fonts, DWORD count)
{
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX2);
}
#if __cplusplus >= 200707 || _MSC_VER >= 1600
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, decltype(nullptr) fonts, DWORD count)
{
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count);
}
#endif
#ifdef _WIN32
static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq)
{
return BASS_MIDI_StreamCreateFile(mem, (const void*)file, offset, length, flags | BASS_UNICODE, freq);
}
static inline HSTREAM BASS_MIDI_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq)
{
return BASS_MIDI_StreamCreateURL((const char*)url, offset, flags | BASS_UNICODE, proc, user, freq);
}
static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags)
{
return BASS_MIDI_FontInit((const void*)file, flags|BASS_UNICODE);
}
static inline BOOL BASS_MIDI_FontPack(HSOUNDFONT handle, const WCHAR *outfile, const WCHAR *encoder, DWORD flags)
{
return BASS_MIDI_FontPack(handle, (const void*)outfile, (const void*)encoder, flags | BASS_UNICODE);
}
static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, DWORD flags)
{
return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags | BASS_UNICODE);
}
#endif
#endif
#endif
#ifdef __OBJC__
#undef BOOL
#endif
#endif

BIN
bass/lib/bass.lib Normal file

Binary file not shown.

BIN
bass/lib/bassmidi.lib Normal file

Binary file not shown.

BIN
bass/x64/bass.lib Normal file

Binary file not shown.

BIN
bass/x64/bassmidi.lib Normal file

Binary file not shown.

View File

@ -824,7 +824,7 @@ void CDecor::BlupiStep()
}
if (m_keyPress & KEY_DOWN &&
!(m_keyPress & KEY_JUMP) &&
!(m_keyPress & (KEY_JUMP | KEY_LEFT | KEY_RIGHT)) &&
IsBlupiStanding() &&
m_blupiAction != ACTION_DOWN &&
m_blupiAction != ACTION_STOPPOP &&

View File

@ -193,7 +193,7 @@ BOOL CDecor::SomethingMissionPath(int gamer, int mission, BOOL bUser)
return FALSE;
}
BOOL CDecor::MissionStart(int gamer, int mission, BOOL bUser)
BOOL CDecor::CurrentWrite(int gamer, int mission, BOOL bUser)
{
char filename[MAX_PATH];
FILE* file = NULL;
@ -363,7 +363,7 @@ error:
return FALSE;
}
BOOL CDecor::CurrentWrite(int gamer, int mission, char* param3)
BOOL CDecor::MissionStart(int gamer, int mission, char* param3)
{
char filename[MAX_PATH];
FILE* file = NULL;

View File

@ -874,15 +874,15 @@ void CDecor::DrawInfo()
m_pPixmap->QuickIcon(CHELEMENT, 252, POINT( 505, 414 ));
}
if (m_blupiCle | CLE_RED) {
if (m_blupiCle & CLE_RED) {
m_pPixmap->QuickIcon(CHELEMENT, 215, POINT( 520, 418 ));
}
if (m_blupiCle | CLE_GREEN) {
if (m_blupiCle & CLE_GREEN) {
m_pPixmap->QuickIcon(CHELEMENT, 222, POINT( 530, 418 ));
}
if (m_blupiCle | CLE_BLUE) {
if (m_blupiCle & CLE_BLUE) {
m_pPixmap->QuickIcon(CHELEMENT, 229, POINT( 540, 418 ));
}
@ -908,9 +908,68 @@ void CDecor::DrawInfo()
if (m_blupiPos.x > 788) m_blupiPos.x = 788;
break;
}
// tutorial text...
POINT cel = { (m_blupiPos.x + DIMBLUPIX / 2) / DIMOBJX, (m_blupiPos.y + DIMBLUPIY / 2) / DIMOBJY };
for (i = 0; table_tutorial[i * 6 + 0] != -1; i++)
{
if (cel.x >= table_tutorial[i * 6 + 0] &&
cel.x <= table_tutorial[i * 6 + 1] &&
cel.y >= table_tutorial[i * 6 + 2] &&
cel.y <= table_tutorial[i * 6 + 3])
{
if (table_tutorial[i * 6 + 4] == -1 || table_tutorial[i * 6 + 4] == m_nbTresor)
{
if (m_bJoystick)
{
LoadString(table_tutorial[i * 6 + 5] + 100, text, 100);
}
else
{
LoadString(table_tutorial[i * 6 + 5], text, 100);
}
DrawTextCenter(m_pPixmap, POINT(360, 460), text);
break;
}
}
}
}
// more...
}
if (m_phase == WM_PHASE_BUILD)
{
if (m_posCelHili.x != -1)
{
int icon = 0;
if (m_2ndPositionCalculationSlot != -1)
{
icon = 31;
}
if (m_dimCelHili.x > 0)
{
pos.x = m_posCelHili.x * DIMOBJX - m_posDecor.x;
int j = 0;
for (i = 0; i < m_dimCelHili.x; i++)
{
pos.y = m_posCelHili.y * DIMOBJY - m_posDecor.y;
for (j = 0; j < m_dimCelHili.y; j++)
{
m_pPixmap->QuickIcon(CHOBJECT, icon, pos);
pos.y += DIMOBJY;
}
pos.x += DIMOBJX;
}
}
}
if (m_phase == WM_PHASE_BUILD) // again???
{
LoadString(0x66, text, 100);
DrawText(m_pPixmap, POINT(200, 460), text, FONTGOLD);
}
}
if (m_phase == WM_PHASE_PLAYTEST)
{
LoadString(0x67, text, 100);
DrawText(m_pPixmap, POINT(200, 460), text, FONTGOLD);
}
}
@ -1760,9 +1819,9 @@ BOOL CDecor::SearchWorld(int world, POINT *cel, POINT *newBlupiPos)
BOOL CDecor::SearchDoor(int n, POINT *cel)
{
for (int x = 0; x < MAXCELX; x++)
for (int y = MAXCELY - 1; y > 0; y--)
{
for (int y = 0; y < MAXCELY; y++)
for (int x = MAXCELX - 1; x > 0; x--)
{
if (m_decor[x][y].icon == 183)
{
@ -1816,9 +1875,9 @@ void CDecor::AdaptDoors(BOOL bPrivate, int mission)
}
}
}
for (int x = 0; x < MAXCELX; x++)
for (int x = MAXCELX - 1; x > 0; x--)
{
for (int y = 0; y < MAXCELY; y++)
for (int y = MAXCELY - 1; y > 0; y--)
{
int icon = m_decor[x][y].icon;
if (icon >= Object::World_1 && icon <= Object::World_8 && (!m_doors[icon - Object::World_1 + 1] || m_bCheatDoors))
@ -1897,12 +1956,12 @@ void CDecor::OpenDoor(POINT cel)
void CDecor::OpenDoorsWin()
{
m_doors[m_mission + 1] = 1;
m_doors[m_mission + 1] = 0;
}
void CDecor::OpenGoldsWin()
{
m_doors[180 + m_mission / 10] = 1;
m_doors[180 + m_mission / 10] = 0;
}
void CDecor::DoorsLost()

View File

@ -399,9 +399,9 @@ public:
BOOL Write(int gamer, int mission, BOOL bUser);
BOOL Read(int gamer, int mission, BOOL bUser);
BOOL SomethingMissionPath(int gamer, int mission, BOOL bUser);
BOOL MissionStart(int gamer, int mission, BOOL bUser);
BOOL CurrentWrite(int gamer, int mission, BOOL bUser=FALSE);
BOOL CurrentRead(int gamer, int mission, BOOL *pbMission, BOOL *pbPrivate);
BOOL CurrentWrite(int gamer, int mission, char* param3);
BOOL MissionStart(int gamer, int mission, char* param3);
BOOL SearchWorld(int world, POINT *cel, POINT *newBlupiPos);
BOOL SearchDoor(int n, POINT *cel);

View File

@ -624,4 +624,21 @@ extern int table_blupi[] = {
290, 290, 1, 1, 0
};
extern int table_tutorial[] = {
0, 2, 0, 7, -1, 0x190,
3, 3, 0, 7, 0, 0x191,
3, 4, 0, 7, -1, 0x192,
6, 8, 0, 7, -1, 0x193,
12, 12, 0, 7, 1, 0x194,
12, 13, 0, 7, -1, 0x195,
14, 15, 0, 7, -1, 0x196,
16, 17, 0, 1, -1, 0x197,
22, 23, 0, 7, -1, 0x198,
29, 30, 0, 7, -1, 0x199,
41, 44, 0, 7, -1, 0x19a,
54, 63, 0, 7, -1, 0x19b,
69, 70, 0, 7, -1, 0x19c,
-1
};
#endif

View File

@ -21,6 +21,7 @@
#define _BYE !_EGAMES // if TRUE, show exit image (like _INTRO)
#define _LEGACY FALSE // if TRUE, keep broken/quirky legacy code
#define _DREAM TRUE // if TRUE, allow Dream blocks when loading levels
#define _BASS TRUE // if TRUE, use BASS audio library instead of DirectMusic (wip)
#define MAXGAMER 8
#define MAXNETPLAYER 4
@ -33,6 +34,8 @@
#define MAXCHAT 6
#define MAXSAVE 6
#define LIFT_RANGE_Y 30
#define MAXDEMO 9999
#define MAXINDEX 20
#define LXIMAGE 640 // dimensions de la fenêtre de jeu
#define LYIMAGE 480
@ -515,18 +518,17 @@ enum {
#define SPRITE_ARROW 1
#define SPRITE_POINTER 2
#define SPRITE_MAP 3
#define SPRITE_ARROWU 4
#define SPRITE_ARROWD 5
#define SPRITE_ARROWL 6
#define SPRITE_ARROWR 7
#define SPRITE_ARROWUL 8
#define SPRITE_ARROWUR 9
#define SPRITE_ARROWDL 10
#define SPRITE_ARROWDR 11
#define SPRITE_WAIT 12
#define SPRITE_EMPTY 13
#define SPRITE_FILL 14
#define SPRITE_ARROWU 3
#define SPRITE_ARROWD 4
#define SPRITE_ARROWL 5
#define SPRITE_ARROWR 6
#define SPRITE_ARROWUL 7
#define SPRITE_ARROWUR 8
#define SPRITE_ARROWDL 9
#define SPRITE_ARROWDR 10
#define SPRITE_WAIT 11
#define SPRITE_EMPTY 12
#define SPRITE_DISABLE 13
// User define message

View File

@ -21,10 +21,7 @@
#include "misc.h"
#include "network.h"
#define DEF_TIME_HELP 10000
#define DEF_TIME_DEMO 1000
#define MAXDEMO 2000
#define MAXINDEX 20
typedef struct
{
@ -1769,61 +1766,40 @@ CEvent::CEvent()
m_bFullScreen = TRUE;
m_mouseType = MOUSETYPEGRA;
m_index = -1;
m_exercice = 0;
m_mission = 0;
m_private = 0;
m_maxMission = 0;
m_fileIndex = 0;
m_fileTime[10] = 0;
m_fileWorld[10] = 0;
m_rankCheat = -1;
m_nbVies = 3;
m_mission = 1;
m_private = 1;
m_multi = 1;
m_phase = 0;
m_bSchool = FALSE;
m_bPrivate = FALSE;
m_bMulti = FALSE;
m_bBuildOfficialMissions = FALSE;
m_bRunMovie = FALSE;
m_bBuildModify = FALSE;
m_bMousePress = FALSE;
m_bMouseDown = FALSE;
m_bHili = FALSE;
m_oldMousePos.x = 0;
m_oldMousePos.y = 0;
m_mouseSprite = 0;
m_bFillMouse = FALSE;
m_bWaitMouse = FALSE;
m_bHideMouse = FALSE;
m_bShowMouse = FALSE;
m_bDisableMouse = FALSE;
m_bMouseRelease = FALSE;
m_tryPhase = 0;
m_rankCheat = -1;
m_posCheat = 0;
m_speed = 1;
m_bMovie = TRUE;
m_bAllMissions = FALSE;
m_bHiliInfoButton = TRUE;
m_bSpeed = FALSE;
m_bHelp = FALSE;
m_bChangeCheat = FALSE;
m_scrollSpeed = 1;
m_bPause = FALSE;
m_bShift = FALSE;
m_shiftPhase = 0;
m_movieToStart[0] = 0;
m_bInfoHelp = FALSE;
m_movieToStart[0] = '\0';
m_bDemoRec = FALSE;
m_bDemoPlay = FALSE;
m_pDemoBuffer = NULL;
m_bDrawMap = NULL;
m_choiceIndex = NULL;
m_saveIndex = NULL;
m_bMulti = NULL;
m_phaseAfterMovie = NULL;
m_choicePageOffset = NULL;
m_nbChoices = NULL;
//m_bNamesExist = NULL;
m_demoTime = 0;
m_bCtrlDown = FALSE;
m_keyPress = 0;
m_menuIndex = 0;
ZeroMemory(m_menuDecor, sizeof(m_menuDecor));
m_menuDecor[10] = 1;
}
// Destructor
@ -1985,14 +1961,14 @@ void CEvent::RestoreGame()
{
if (m_phase == WM_PHASE_PLAY || m_phase == WM_PHASE_PLAYTEST)
{
HideMouse(FALSE);
WaitMouse(TRUE);
WaitMouse(FALSE);
return;
HideMouse(TRUE);
}
else
{
WaitMouse(FALSE);
DisableMouse(TRUE);
DisableMouse(FALSE); // force le changement de sprite !
}
FillMouse(TRUE);
return;
}
void CEvent::FlushInput()
@ -2157,7 +2133,7 @@ void CEvent::ReadInput()
// CNetwork function needs to be implemented
void CEvent::NetSetPause(BOOL bPause, int players)
void CEvent::NetSetPause(BOOL bPause, BOOL bMulti)
{
BOOL bPause_;
@ -2174,7 +2150,7 @@ void CEvent::NetSetPause(BOOL bPause, int players)
m_pSound->SuspendMusic();
}
}
if ((m_bMulti != FALSE) && (players != 0))
if ((m_bMulti != FALSE) && (bMulti != 0))
{
m_pNetwork->Send(&bPause, 3, DPSEND_GUARANTEED);
}
@ -2569,30 +2545,31 @@ BOOL CEvent::DrawButtons()
if (m_phase == WM_PHASE_PLAY || m_phase == WM_PHASE_PLAYTEST)
{
if (m_pDecor->GetPause() == 0)
if (m_pDecor->GetPause())
{
if (m_bDemoRec != 0)
if (m_pDecor->GetTime() % 20 < 15)
{
LoadString(TX_DEMOREC, res, 100);
DrawTextLeft(m_pPixmap, pos, res, FONTGOLD);
}
if (m_bDemoPlay != 0)
{
LoadString(TX_DEMOPLAY, res, 100);
DrawTextLeft(m_pPixmap, pos, res, FONTGOLD);
DrawTextCenter(TX_PAUSE, LXIMAGE / 2, LYIMAGE / 2, 0);
}
}
else
{
if (m_pDecor->GetTime() % 20 < 15)
if (m_bDemoRec)
{
DrawTextCenter(TX_PAUSE, 320, 240, 0);
LoadString(TX_DEMOREC, res, 100);
DrawTextLeft(m_pPixmap, POINT(10, 10), res, FONTGOLD);
}
if (m_bDemoPlay)
{
LoadString(TX_DEMOPLAY, res, 100);
DrawTextLeft(m_pPixmap, POINT(10, 10), res, FONTGOLD);
}
}
if (m_speed > 1)
{
sprintf(res, "x%d", m_speed);
DrawTextLeft(m_pPixmap, pos, res, FONTWHITE);
DrawTextLeft(m_pPixmap, POINT(64, LYIMAGE - DIMTEXTY + 1), res, FONTWHITE);
}
}
if (m_phase == WM_PHASE_STOP)
@ -3167,20 +3144,25 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
}
if (m_rankCheat == 11)
{
m_pDecor->SetDrawSecret(!m_pDecor->GetDrawSecret());
bEnable = m_pDecor->GetDrawSecret();
bEnable = !m_pDecor->GetDrawSecret();
m_pDecor->SetDrawSecret(bEnable);
}
if (m_rankCheat == 19)
{
// Add NetPacked
bEnable = !m_pDecor->GetNetPacked();
m_pDecor->SetNetPacked(bEnable);
}
if (m_rankCheat == 20)
{
// Add Net Debug
bEnable = !m_pDecor->GetNetDebug();
m_pDecor->SetNetDebug(bEnable);
}
if (m_rankCheat == 21)
{
// Add NetMovePredict
bEnable = !m_pDecor->GetNetMovePredict();
m_pDecor->SetNetMovePredict(bEnable);
}
if (m_phase != WM_PHASE_PLAY && m_phase != WM_PHASE_PLAYTEST)
{
@ -3334,29 +3316,31 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
return TRUE;
case WM_PHASE_GREAD:
case WM_PHASE_GREADp:
/*
if (m_choiceIndex >= 0 && FUN_21890(m_choiceIndex))
if (m_choiceIndex >= 0 && CurrentRead(m_choiceIndex))
{
ChangePhase(WM_PHASE_PLAY);
}
return TRUE;
*/
case WM_PHASE_GWRITE:
/*
if (m_choiceIndex >= 0 && FUN_218f0(m_choiceIndex))
if (m_choiceIndex >= 0 && CurrentWrite(m_choiceIndex))
{
ChangePhase(WM_PHASE_PLAY);
}
return TRUE;
*/
default:
return TRUE;
}
case VK_SHIFT:
m_keyPress |= KEY_FIRE;
break;
case VK_CONTROL:
m_keyPress |= KEY_JUMP;
break;
case VK_PAUSE:
NetSetPause((m_pDecor->GetPause()), TRUE);
break;
case VK_LEFT:
m_keyPress |= KEY_LEFT;
break;
@ -3370,7 +3354,7 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
m_keyPress |= KEY_DOWN;
break;
case VK_HOME:
return TRUE;
break;
case VK_SPACE:
if (m_bRunMovie)
{
@ -3380,14 +3364,30 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
}
m_keyPress |= KEY_FIRE;
break;
case VK_PAUSE:
m_bPause = !m_bPause;
NetSetPause((m_pDecor->GetPause()), m_bPause);
return TRUE;
case VK_CONTROL:
m_keyPress |= KEY_JUMP;
case VK_F1:
if (this->m_phase == WM_PHASE_PLAY)
{
ChangePhase(WM_PHASE_HELP);
}
break;
case VK_F2:
if (this->m_phase == WM_PHASE_PLAY)
{
ChangePhase(WM_PHASE_SETUPp);
}
break;
case VK_F3:
if (this->m_phase == WM_PHASE_PLAY)
{
ChangePhase(WM_PHASE_GWRITE);
}
break;
case VK_F4:
if (this->m_phase != WM_PHASE_PLAY)
{
ChangePhase(WM_PHASE_GREADp);
}
break;
}
if (m_phase != WM_PHASE_PLAY && m_phase != WM_PHASE_PLAYTEST && m_phase != WM_PHASE_BUILD)
@ -3396,6 +3396,7 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
}
m_pDecor->SetInput(m_keyPress);
DemoRecEvent();
return TRUE;
// Unknown Function
@ -3477,7 +3478,6 @@ BOOL CEvent::TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam)
{
if (!m_bShowMouse)
{
ShowCursor(TRUE); // montre la souris
m_pPixmap->MouseShow(FALSE); // cache sprite
m_bShowMouse = TRUE;
}
@ -3921,13 +3921,13 @@ int CEvent::MousePosToSprite(POINT pos)
sprite = SPRITE_POINTER;
if (m_phase == WM_PHASE_PLAY ||
m_phase == WM_PHASE_PLAYTEST ||
m_phase == WM_PHASE_BUILD ||
m_phase == WM_PHASE_BYE ||
if (m_phase != WM_PHASE_PLAY &&
m_phase != WM_PHASE_PLAYTEST &&
m_phase != WM_PHASE_BUILD &&
m_phase != WM_PHASE_BYE &&
!MouseOnButton(pos))
{
sprite = SPRITE_POINTER;
sprite = SPRITE_ARROW;
}
if (m_bWaitMouse)
{
@ -3937,9 +3937,9 @@ int CEvent::MousePosToSprite(POINT pos)
{
sprite = SPRITE_EMPTY;
}
if (m_bFillMouse)
if (m_bDisableMouse)
{
sprite = SPRITE_FILL;
sprite = SPRITE_DISABLE;
}
return sprite;
@ -3971,7 +3971,8 @@ void CEvent::WaitMouse(BOOL bWait)
void CEvent::HideMouse(BOOL bHide)
{
m_bWaitMouse = bHide;
m_bHideMouse = bHide;
m_bDisableMouse = FALSE;
if ( bHide )
{
@ -3985,13 +3986,13 @@ void CEvent::HideMouse(BOOL bHide)
ChangeSprite(m_mouseSprite);
}
void CEvent::FillMouse(int bFill)
void CEvent::DisableMouse(int bDisable)
{
m_bFillMouse = bFill;
m_bDisableMouse = bDisable;
if (bFill)
if (bDisable)
{
m_mouseSprite = SPRITE_FILL;
m_mouseSprite = SPRITE_DISABLE;
}
else
{
@ -4152,7 +4153,7 @@ void CEvent::ReadAll()
if ((-1 < m_choiceIndex) && (*(int*)((int)(m_filenameBuffer + -1) + m_choiceIndex * 4 + 216) != 0))
{
mission = m_pDecor->MissionStart(m_gamer, 999, bUser);
mission = m_pDecor->CurrentWrite(m_gamer, 999, bUser);
if (mission != FALSE)
{
@ -4174,7 +4175,7 @@ BOOL CEvent::SaveState(int rank)
BOOL bUser = FALSE;
char str[100];
bMission = m_pDecor->MissionStart(m_gamer, rank, bUser);
bMission = m_pDecor->CurrentWrite(m_gamer, rank, bUser);
if (bMission == FALSE)
{
@ -4349,7 +4350,7 @@ BOOL CEvent::ChangePhase(UINT phase)
if (phase == WM_PHASE_GAMER || phase == WM_PHASE_PLAY)
{
OutputNetDebug("CEvent::ChangePhase_[WriteInfo]\r\n");
OutputNetDebug("CEvent::ChangePhase [WriteInfo]\r\n");
WriteInfo(m_gamer);
}
@ -4895,7 +4896,7 @@ BOOL CEvent::ChangePhase(UINT phase)
WaitMouse(FALSE);
if (m_phase == WM_PHASE_PLAY || m_phase == WM_PHASE_PLAYTEST)
{
FillMouse(TRUE);
DisableMouse(TRUE);
}
m_pDecor->VehicleSoundsPhase(phase);
OutputNetDebug("CEvent::ChangePhase [End]");
@ -5312,16 +5313,17 @@ void CEvent::DemoStep()
m_demoTime++;
}
void CEvent::DemoRecEvent(UINT message, UINT input, WPARAM wParam, LPARAM lParam)
void CEvent::DemoRecEvent()
{
if (m_demoIndex > 0 &&
m_pDemoBuffer[m_demoIndex - 1].time == m_demoTime &&
m_pDemoBuffer[m_demoIndex - 1].input == m_keyPress)
m_demoIndex++;
if (m_demoIndex >= MAXDEMO)
if (m_bDemoRec)
{
DemoRecStop();
m_pDemoBuffer[m_demoIndex].time = m_demoTime;
m_pDemoBuffer[m_demoIndex].input == m_keyPress;
m_demoIndex++;
if (m_demoIndex > MAXDEMO)
{
DemoRecStop();
}
}
}
@ -5752,14 +5754,14 @@ int CEvent::GameSave(int save)
{
char buffer[100];
if (m_pDecor->MissionStart(m_gamer, save, TRUE))
if (m_pDecor->CurrentWrite(m_gamer, save, TRUE))
{
//LoadString()
m_pDecor->NotifPush(buffer);
m_quicksaveIndex = save;
return 1;
}
return m_pDecor->MissionStart(m_gamer, save, TRUE);
return m_pDecor->CurrentWrite(m_gamer, save, TRUE);
}
BOOL CEvent::CopyMission(char *srcFileName, char *dstFileName)
@ -5825,3 +5827,32 @@ void CEvent::NetAdjustLobbyButtons()
{
// TODO
}
BOOL CEvent::CurrentRead(int rank)
{
char buf[100];
int mission;
BOOL bPrivate;
if (m_pDecor->CurrentRead(m_gamer, rank, &mission, &bPrivate))
{
m_bPrivate = bPrivate;
SetMission(mission);
m_quicksaveIndex = rank;
return TRUE;
}
return FALSE;
}
BOOL CEvent::CurrentWrite(int rank)
{
char buf[100];
if (m_pDecor->CurrentWrite(m_gamer, rank))
{
LoadString(0x120u, buf, 100);
m_pDecor->NotifPush(buf);
m_quicksaveIndex = rank;
return TRUE;
}
return FALSE;
}

View File

@ -98,7 +98,7 @@ public:
void SomethingDecor();
BOOL IsMouseRelease();
void NetSetPause(BOOL bPause, int players);
void NetSetPause(BOOL bPause, BOOL bMulti);
void NetSendLobby();
BOOL DrawButtons();
@ -107,7 +107,7 @@ public:
void MouseSprite(POINT pos);
void WaitMouse(BOOL bWait);
void HideMouse(BOOL bHide);
void FillMouse(int bFill);
void DisableMouse(int bFill);
POINT GetLastMousePos();
BOOL TreatEvent(UINT message, WPARAM wParam, LPARAM lParam);
BOOL TreatEventBase(UINT message, WPARAM wParam, LPARAM lParam);
@ -172,7 +172,7 @@ protected:
void DemoRecStop();
BOOL DemoPlayStart();
void DemoPlayStop();
void DemoRecEvent(UINT message, UINT input, WPARAM wParam, LPARAM lParam);
void DemoRecEvent();
// Network Functions
BOOL NetCreate(int session);
@ -194,6 +194,9 @@ protected:
BOOL CheckWorld1();
void NetAdjustLobbyButtons();
BOOL CurrentRead(BOOL bPrivate);
BOOL CurrentWrite(int rank);
protected:
int m_speed;
@ -256,7 +259,7 @@ protected:
char m_textToolTips[50];
char m_textToolTips2[50];
int m_mouseSprite;
BOOL m_bFillMouse;
BOOL m_bDisableMouse;
BOOL m_bWaitMouse;
BOOL m_bHideMouse;
BOOL m_bShowMouse;

View File

@ -43,7 +43,6 @@ void ChangeSprite(int sprite)
if ( sprite == SPRITE_ARROW ) hCursor = LoadCursorA(g_hInstance, "IDC_ARROW");
if ( sprite == SPRITE_POINTER ) hCursor = LoadCursorA(g_hInstance, "IDC_POINTER");
if ( sprite == SPRITE_MAP ) hCursor = LoadCursorA(g_hInstance, "IDC_MAP");
if ( sprite == SPRITE_ARROWU ) hCursor = LoadCursorA(g_hInstance, "IDC_ARROWU");
if ( sprite == SPRITE_ARROWD ) hCursor = LoadCursorA(g_hInstance, "IDC_ARROWD");
if ( sprite == SPRITE_ARROWL ) hCursor = LoadCursorA(g_hInstance, "IDC_ARROWL");
@ -54,7 +53,6 @@ void ChangeSprite(int sprite)
if ( sprite == SPRITE_ARROWDR ) hCursor = LoadCursorA(g_hInstance, "IDC_ARROWDR");
if ( sprite == SPRITE_WAIT ) hCursor = LoadCursorA(g_hInstance, "IDC_WAIT");
if ( sprite == SPRITE_EMPTY ) hCursor = LoadCursorA(g_hInstance, "IDC_EMPTY");
if ( sprite == SPRITE_FILL ) hCursor = LoadCursorA(g_hInstance, "IDC_FILL");
SetCursor(hCursor);
g_lastSprite = sprite;

View File

@ -1538,6 +1538,7 @@ void CPixmap::SetMousePosSprite(POINT pos, int sprite, BOOL bDemoPlay)
}
}
/*
// Positionne la souris.
void CPixmap::SetMousePos(POINT pos, BOOL bDemoPlay)
@ -1552,6 +1553,7 @@ void CPixmap::SetMousePos(POINT pos, BOOL bDemoPlay)
MouseUpdate();
}
}
*/
// Change le lutin de la souris.
@ -1584,6 +1586,7 @@ void CPixmap::MouseUpdate()
if ( m_lpDDSurface[CHELEMENT] == NULL ) return;
if ( m_mouseType != MOUSETYPEGRA ) return;
if ( m_mouseSprite == SPRITE_EMPTY ) return;
if (m_mouseSprite == SPRITE_DISABLE) return;
if ( !m_bMouseShow ) return;
oldRect.left = m_mouseBackPos.x;
@ -1661,7 +1664,7 @@ void CPixmap::MouseInvalidate()
void CPixmap::MouseBackClear()
{
if ( m_mouseType != MOUSETYPEGRA ) return;
if ( m_mouseType != MOUSETYPEGRA || m_mouseSprite == SPRITE_DISABLE) return;
MouseBackRestore(); // enl<6E>ve la souris dans m_lpDDSBack
}
@ -1674,7 +1677,7 @@ void CPixmap::MouseBackDraw()
if ( m_lpDDSurface[CHELEMENT] == NULL ) return;
if ( m_mouseType != MOUSETYPEGRA ) return;
if ( m_mouseSprite == SPRITE_EMPTY ) return;
if ( m_mouseSprite == SPRITE_EMPTY || m_mouseSprite == SPRITE_DISABLE) return;
if ( !m_bMouseShow ) return;
MouseBackSave(); // sauve ce qui sera sous la souris
@ -1717,7 +1720,7 @@ void CPixmap::MouseBackSave()
if ( m_lpDDSurface[CHELEMENT] == NULL ) return;
if ( m_mouseType != MOUSETYPEGRA ) return;
if ( m_mouseSprite == SPRITE_EMPTY ) return;
if ( m_mouseSprite == SPRITE_EMPTY || m_mouseSprite == SPRITE_DISABLE) return;
if ( !m_bMouseShow ) return;
m_mouseBackPos.x = m_mousePos.x - m_mouseHotSpot.x;
@ -1870,7 +1873,7 @@ void CPixmap::MouseRectSprite(RECT *rect, POINT *offset)
rank = 37;
if ( m_mouseSprite == SPRITE_POINTER ) rank = 38;
if ( m_mouseSprite == 11 ) rank = 39;
if ( m_mouseSprite == SPRITE_WAIT ) rank = 39;
rect->left = table_icon_element[rank * 6 + 0 + 1];
rect->right = rect->left + table_icon_element[rank * 6 + 4 + 1];
@ -1888,29 +1891,18 @@ void CPixmap::MouseHotSpot()
{
int rank;
static int table_mouse_hotspot[14*2] =
static int table_mouse_hotspot[4*2] =
{
25, 0,
30, 30, // SPRITE_ARROW
20, 15, // SPRITE_POINTER
31, 26, // SPRITE_MAP
25, 14, // SPRITE_ARROWU
24, 35, // SPRITE_ARROWD
15, 24, // SPRITE_ARROWL
35, 24, // SPRITE_ARROWR
18, 16, // SPRITE_ARROWUL
32, 18, // SPRITE_ARROWUR
17, 30, // SPRITE_ARROWDL
32, 32, // SPRITE_ARROWDR
30, 30, // SPRITE_WAIT
30, 30, // SPRITE_EMPTY
21, 51, // SPRITE_FILL
};
rank = m_mouseSprite;
if ( m_mouseSprite >= SPRITE_ARROW &&
m_mouseSprite <= SPRITE_FILL )
m_mouseSprite <= SPRITE_WAIT )
{
rank = m_mouseSprite - SPRITE_ARROW; // rank <- 0..n
m_mouseHotSpot.x = table_mouse_hotspot[rank*2+0];
m_mouseHotSpot.y = table_mouse_hotspot[rank*2+1];
}

View File

@ -1,18 +1,46 @@
// sound.cpp
//
#include "def.h"
#if _BASS && !_LEGACY
#include <dsound.h>
#include <stdio.h>
#include "sound.h"
#include "misc.h"
#include "def.h"
#include "resource.h"
#include "bass.h"
#include "bassmidi.h"
/////////////////////////////////////////////////////////////////////////////
// The following macro are used for proper error handling for DirectSound.
#define TRY_DS(exp) { { HRESULT rval = exp; if (rval != DS_OK) { TraceErrorDS(rval, __FILE__, __LINE__); return FALSE; } } }
static const float table[21] =
{
(float)0x00000000 / 0xFFFFFFFF,
(float)0x11111111 / 0xFFFFFFFF,
(float)0x22222222 / 0xFFFFFFFF,
(float)0x33333333 / 0xFFFFFFFF,
(float)0x44444444 / 0xFFFFFFFF,
(float)0x55555555 / 0xFFFFFFFF,
(float)0x66666666 / 0xFFFFFFFF,
(float)0x77777777 / 0xFFFFFFFF,
(float)0x88888888 / 0xFFFFFFFF,
(float)0x99999999 / 0xFFFFFFFF,
(float)0xAAAAAAAA / 0xFFFFFFFF,
(float)0xBBBBBBBB / 0xFFFFFFFF,
(float)0xCCCCCCCC / 0xFFFFFFFF,
(float)0xDDDDDDDD / 0xFFFFFFFF,
(float)0xEEEEEEEE / 0xFFFFFFFF,
(float)0xF222F222 / 0xFFFFFFFF,
(float)0xF555F555 / 0xFFFFFFFF,
(float)0xF777F777 / 0xFFFFFFFF,
(float)0xFAAAFAAA / 0xFFFFFFFF,
(float)0xFDDDFDDD / 0xFFFFFFFF,
(float)0xFFFFFFFF / 0xFFFFFFFF,
};
struct WaveHeader
{
@ -233,55 +261,7 @@ BOOL CSound::PlaySoundDS(DWORD dwSound, DWORD dwFlags)
void InitMidiVolume(int volume)
{
int nb, i, n;
MMRESULT result;
HMIDIOUT hmo = 0;
static int table[21] =
{
0x00000000,
0x11111111,
0x22222222,
0x33333333,
0x44444444,
0x55555555,
0x66666666,
0x77777777,
0x88888888,
0x99999999,
0xAAAAAAAA,
0xBBBBBBBB,
0xCCCCCCCC,
0xDDDDDDDD,
0xEEEEEEEE,
0xF222F222,
0xF555F555,
0xF777F777,
0xFAAAFAAA,
0xFDDDFDDD,
0xFFFFFFFF,
};
if (volume < 0) volume = 0;
if (volume > MAXVOLUME) volume = MAXVOLUME;
nb = midiOutGetNumDevs();
for (i = 0; i<nb; i++)
{
result = midiOutOpen((LPHMIDIOUT)&hmo, i, 0L, 0L, 0L);
if (result != MMSYSERR_NOERROR)
{
continue;
}
result = midiOutSetVolume(hmo, table[volume]);
if (result != MMSYSERR_NOERROR)
{
n = 1;
}
midiOutClose(hmo);
hmo = 0;
}
// :)
}
@ -297,11 +277,13 @@ CSound::CSound()
m_bEnable = FALSE;
m_bState = FALSE;
m_MidiDeviceID = 0;
m_MIDIFilename[0] = 0;
m_music = 0;
m_audioVolume = 20;
m_midiVolume = 15;
m_lastMidiVolume = 0;
m_nbSuspendSkip = 0;
BASS_Init(-1, 22050, BASS_DEVICE_FREQ, m_hWnd, NULL);
BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, "data\\GM.DLS.sf2");
m_lpDS = NULL;
@ -563,50 +545,25 @@ BOOL CSound::PlayMusic(HWND hWnd, int music)
if (!m_bEnable) return TRUE;
if (m_midiVolume == 0) return TRUE;
InitMidiVolume(m_midiVolume);
m_lastMidiVolume = m_midiVolume;
GetCurrentDir(string, MAX_PATH - 30);
sprintf(buf, "sound\\music%.3d.blp", music - 1);
strcat(string, buf);
// Open the device by specifying the device and filename.
// MCI will attempt to choose the MIDI mapper as the output port.
mciOpenParms.dwCallback = 0;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrDeviceType = "sequencer";
mciOpenParms.lpstrElementName = string;
dwReturn = mciSendCommand(NULL,
MCI_OPEN,
MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID)&mciOpenParms);
if (dwReturn != 0)
if (music != m_music || !m_hBassStream)
{
OutputDebug("PlayMusic-1\n");
mciGetErrorStringA(dwReturn, string, 128);
OutputDebug(string);
// Failed to open device. Don't close it; just return error.
return FALSE;
if (m_hBassStream) BASS_ChannelFree(m_hBassStream);
InitMidiVolume(m_midiVolume);
m_lastMidiVolume = m_midiVolume;
GetCurrentDir(string, MAX_PATH - 30);
sprintf(buf, "sound\\music%.3d.blp", music - 1);
strcat(string, buf);
m_hBassStream = BASS_MIDI_StreamCreateFile(FALSE, string, 0, 0, BASS_SAMPLE_LOOP, 0);
BASS_ChannelSetAttribute(m_hBassStream, BASS_ATTRIB_VOL, table[m_midiVolume]);
BASS_ChannelSetAttribute(m_hBassStream, BASS_ATTRIB_MIDI_REVERB, 0);
BASS_ChannelStart(m_hBassStream);
}
// The device opened successfully; get the device ID.
m_MidiDeviceID = mciOpenParms.wDeviceID;
// Begin playback.
mciPlayParms.dwFrom = 0;
mciPlayParms.dwTo = 0;
mciPlayParms.dwCallback = (DWORD)hWnd;
dwReturn = mciSendCommand(m_MidiDeviceID,
MCI_PLAY,
MCI_NOTIFY,
(DWORD)(LPVOID)&mciPlayParms);
if (dwReturn != 0)
else
{
OutputDebug("PlayMusic-2\n");
mciGetErrorString(dwReturn, string, 128);
OutputDebug(string);
StopMusic();
return FALSE;
BASS_ChannelStart(m_hBassStream);
}
m_music = music;
@ -621,7 +578,7 @@ BOOL CSound::RestartMusic()
OutputDebug("RestartMusic\n");
if (!m_bEnable) return TRUE;
if (m_midiVolume == 0) return TRUE;
if (m_MIDIFilename[0] == 0) return FALSE;
if (m_music == 0) return FALSE;
return PlayMusic(m_hWnd, m_music);
}
@ -638,11 +595,10 @@ void CSound::SuspendMusic()
return;
}
if (m_MidiDeviceID && m_midiVolume != 0)
if (m_hBassStream && m_midiVolume != 0)
{
mciSendCommand(m_MidiDeviceID, MCI_CLOSE, 0, NULL);
BASS_ChannelPause(m_hBassStream);
}
m_MidiDeviceID = 0;
}
// Shuts down the MIDI player.
@ -650,14 +606,14 @@ void CSound::SuspendMusic()
void CSound::StopMusic()
{
SuspendMusic();
m_MIDIFilename[0] = 0;
m_music = 0;
}
// Retourne TRUE si une musique est en cours.
BOOL CSound::IsPlayingMusic()
{
return (m_MIDIFilename[0] != 0);
return (m_music != 0);
}
// Adapte le volume de la musique en cours, si n<>cessaire.
@ -755,3 +711,5 @@ BOOL CSound::PlayCDAudio(HWND hWnd, int track)
return TRUE;
}
#endif

View File

@ -6,6 +6,11 @@
#include "dsound.h"
#include <stdio.h>
#if _BASS && !_LEGACY
#include "bass.h"
#include "bassmidi.h"
#endif
///////////////////////////////////////////////////////////////////////////
#define MAXSOUND 100
@ -62,13 +67,17 @@ protected:
LPDIRECTSOUND m_lpDS;
LPDIRECTSOUNDBUFFER m_lpDSB[MAXSOUND];
short m_channelBlupi[MAXBLUPI];
#if _BASS && !_LEGACY
HSTREAM m_hBassStream;
#else
UINT m_MidiDeviceID;
#endif
int m_music;
char m_MIDIFilename[50];
int m_audioVolume;
int m_midiVolume;
int m_lastMidiVolume;
int m_nbSuspendSkip;
};
#endif

760
src/soundold.cpp Normal file
View File

@ -0,0 +1,760 @@
// sound.cpp
//
#include "def.h"
#if !_BASS || _LEGACY
#include <dsound.h>
#include <stdio.h>
#include "sound.h"
#include "misc.h"
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
// The following macro are used for proper error handling for DirectSound.
#define TRY_DS(exp) { { HRESULT rval = exp; if (rval != DS_OK) { TraceErrorDS(rval, __FILE__, __LINE__); return FALSE; } } }
struct WaveHeader
{
BYTE RIFF[4]; // "RIFF"
DWORD dwSize; // Size of data to follow
BYTE WAVE[4]; // "WAVE"
BYTE fmt_[4]; // "fmt "
DWORD dw16; // 16
WORD wOne_0; // 1
WORD wChnls; // Number of Channels
DWORD dwSRate; // Sample Rate
DWORD BytesPerSec; // Sample Rate
WORD wBlkAlign; // 1
WORD BitsPerSample; // Sample size
BYTE DATA[4]; // "DATA"
DWORD dwDSize; // Number of Samples
};
// Creates a DirectSound buffer.
BOOL CSound::CreateSoundBuffer(int dwBuf, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
{
PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc;
// Set up wave format structure.
memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = bStereo ? 2 : 1;
pcmwf.wf.nSamplesPerSec = dwFreq;
pcmwf.wf.nBlockAlign = (WORD)dwBlkAlign;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = (WORD)dwBitsPerSample;
// Set up DSBUFFERDESC structure.
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME;
dsbdesc.dwBufferBytes = dwBufSize;
dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
TRY_DS(m_lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSB[dwBuf], NULL), 63)
return TRUE;
}
// I dunno what the fuck this does.
/*
BOOL CSound::ErrorSomething()
{
if (m_lpDS ||
m_lpDSB != 0)
{
m_lpDS, m_lpDSB->TraceErrorDS;
return FALSE;
}
return TRUE;
}
*/
// Reads in data from a wave file.
BOOL CSound::ReadData(LPDIRECTSOUNDBUFFER lpDSB, FILE* pFile, DWORD dwSize, DWORD dwPos)
{
// Seek to correct position in file (if necessary)
if (dwPos != 0xffffffff)
{
if (fseek(pFile, dwPos, SEEK_SET) != 0)
{
return FALSE;
}
}
// Lock data in buffer for writing
LPVOID pData1;
DWORD dwData1Size;
LPVOID pData2;
DWORD dwData2Size;
HRESULT rval;
rval = lpDSB->Lock(0, dwSize, &pData1, &dwData1Size, &pData2, &dwData2Size, DSBLOCK_FROMWRITECURSOR);
if (rval != DS_OK)
{
return FALSE;
}
// Read in first chunk of data
if (dwData1Size > 0)
{
if (fread(pData1, dwData1Size, 1, pFile) != 1)
{
char holder[256];
wsprintfA(holder, "Data1 : %d, dwdata: %d, pFile: %d", pData1, dwData1Size, pFile);
OutputDebug(holder);
return FALSE;
}
}
// read in second chunk if necessary
if (dwData2Size > 0)
{
if (fread(pData2, dwData2Size, 1, pFile) != 1)
{
return FALSE;
}
}
// Unlock data in buffer
rval = lpDSB->Unlock(pData1, dwData1Size, pData2, dwData2Size);
if (rval != DS_OK)
{
return FALSE;
}
return TRUE;
}
// Creates a DirectSound buffer from a wave file.
BOOL CSound::CreateBufferFromWaveFile(int dwBuf, char *pFileName)
{
// Open the wave file
FILE* pFile = fopen(pFileName, "rb");
if (pFile == NULL) return FALSE;
// Read in the wave header
WaveHeader wavHdr;
if (fread(&wavHdr, sizeof(wavHdr), 1, pFile) != 1)
{
fclose(pFile);
return NULL;
}
// Figure out the size of the data region
DWORD dwSize = wavHdr.dwDSize;
// Is this a stereo or mono file?
BOOL bStereo = wavHdr.wChnls > 1 ? TRUE : FALSE;
// Create the sound buffer for the wave file
if (!CreateSoundBuffer(dwBuf, dwSize, wavHdr.dwSRate,
wavHdr.BitsPerSample, wavHdr.wBlkAlign, bStereo))
{
// Close the file
fclose(pFile);
return FALSE;
}
// Read the data for the wave file into the sound buffer
if (!ReadData(m_lpDSB[dwBuf], pFile, dwSize, sizeof(wavHdr)))
{
fclose(pFile);
return FALSE;
}
// Close out the wave file
fclose(pFile);
return TRUE;
}
// Stops all sounds.
BOOL CSound::StopAllSounds()
{
// Make sure we have a valid sound buffer
for (int i = 0; i < MAXSOUND; i++)
{
if (m_lpDSB[i])
{
DWORD dwStatus;
TRY_DS(m_lpDSB[i]->GetStatus(&dwStatus));
if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
TRY_DS(m_lpDSB[i]->Stop())
}
}
}
return TRUE;
}
// Plays a sound using direct sound.
BOOL CSound::PlaySoundDS(DWORD dwSound, DWORD dwFlags)
{
// Make sure the sound is valid
if (dwSound >= MAXSOUND) return FALSE;
// Make sure we have a valid sound buffer
if (m_lpDSB[dwSound])
{
DWORD dwStatus;
TRY_DS(m_lpDSB[dwSound]->GetStatus(&dwStatus));
if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
{
// Play the sound
TRY_DS(m_lpDSB[dwSound]->Play(0, 0, dwFlags));
}
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// Modifie le volume midi.
// Le volume est compris entre 0 et 20 !
void InitMidiVolume(int volume)
{
int nb, i, n;
MMRESULT result;
HMIDIOUT hmo = 0;
static int table[21] =
{
0x00000000,
0x11111111,
0x22222222,
0x33333333,
0x44444444,
0x55555555,
0x66666666,
0x77777777,
0x88888888,
0x99999999,
0xAAAAAAAA,
0xBBBBBBBB,
0xCCCCCCCC,
0xDDDDDDDD,
0xEEEEEEEE,
0xF222F222,
0xF555F555,
0xF777F777,
0xFAAAFAAA,
0xFDDDFDDD,
0xFFFFFFFF,
};
if (volume < 0) volume = 0;
if (volume > MAXVOLUME) volume = MAXVOLUME;
nb = midiOutGetNumDevs();
for (i = 0; i<nb; i++)
{
result = midiOutOpen((LPHMIDIOUT)&hmo, i, 0L, 0L, 0L);
if (result != MMSYSERR_NOERROR)
{
continue;
}
result = midiOutSetVolume(hmo, table[volume]);
if (result != MMSYSERR_NOERROR)
{
n = 1;
}
midiOutClose(hmo);
hmo = 0;
}
}
/////////////////////////////////////////////////////////////////////////////
// Constructeur.
CSound::CSound()
{
int i;
m_bEnable = FALSE;
m_bState = FALSE;
m_MidiDeviceID = 0;
m_MIDIFilename[0] = 0;
m_audioVolume = 20;
m_midiVolume = 15;
m_lastMidiVolume = 0;
m_nbSuspendSkip = 0;
m_lpDS = NULL;
for (i = 0; i<MAXSOUND; i++)
{
m_lpDSB[i] = NULL;
}
for (i = 0; i<MAXBLUPI; i++)
{
m_channelBlupi[i] = -1;
}
}
// Destructeur.
CSound::~CSound()
{
int i;
if (m_bEnable)
{
InitMidiVolume(15); // remet un volume moyen !
}
for (i = 0; i<MAXSOUND; i++)
{
if (m_lpDSB[i] != NULL)
{
//? m_lpDSB[i]->Release();
m_lpDSB[i] = NULL;
}
}
if (m_lpDS != NULL)
{
m_lpDS->Release();
m_lpDS = NULL;
}
}
// Initialisation de DirectSound.
BOOL CSound::Create(HWND hWnd)
{
if (!DirectSoundCreate(NULL, &m_lpDS, NULL) == DS_OK)
{
OutputDebug("Fatal error: DirectSoundCreate\n");
m_bEnable = FALSE;
return FALSE;
}
m_lpDS->SetCooperativeLevel(hWnd, DSSCL_NORMAL);
m_bEnable = TRUE;
m_hWnd = hWnd;
return TRUE;
}
// Retourne l'<27>tat de DirectSound.
BOOL CSound::GetEnable()
{
return m_bEnable;
}
// Enclenche ou d<>clenche le son.
void CSound::SetState(BOOL bState)
{
m_bState = bState;
}
// Gestion des volumes audio (.wav) et midi (.mid).
void CSound::SetAudioVolume(int volume)
{
m_audioVolume = volume;
}
int CSound::GetAudioVolume()
{
if (!m_bEnable) return 0;
return m_audioVolume;
}
void CSound::SetMidiVolume(int volume)
{
m_midiVolume = volume;
}
int CSound::GetMidiVolume()
{
if (!m_bEnable) return 0;
return m_midiVolume;
}
// Cache tous les ficheirs son (.wav).
void CSound::CacheAll()
{
int i;
char name[50];
if (!m_bEnable) return;
for (i = 0; i<MAXSOUND; i++)
{
sprintf(name, "sound\\sound%.3d.blp", i);
if (!Cache(i, name)) break;
}
}
// Charge un fichier son (.wav).
BOOL CSound::Cache(int channel, char *pFilename)
{
if (!m_bEnable) return FALSE;
if (channel < 0 || channel >= MAXSOUND) return FALSE;
if (m_lpDSB[channel] != NULL)
{
Flush(channel);
}
return CreateBufferFromWaveFile(channel, pFilename);
}
// D<>charge un son.
void CSound::Flush(int channel)
{
if (!m_bEnable) return;
if (channel < 0 || channel >= MAXSOUND) return;
if (m_lpDSB[channel] != NULL)
{
m_lpDSB[channel]->Release();
m_lpDSB[channel] = NULL;
}
}
// Fait entendre un son.
// Le volume est compris entre 0 (max) et -10000 (silence).
// Le panoramique est compris entre -10000 (gauche), 0 (centre)
// et +10000 (droite).
BOOL CSound::Play(int channel, int volume, int pan)
{
if (!m_bEnable) return TRUE;
if (!m_bState || m_audioVolume == 0) return TRUE;
volume -= (MAXVOLUME - m_audioVolume)*((10000 / 4) / MAXVOLUME);
//? if ( volume == -10000 ) return TRUE;
if (volume <= -10000 / 4) return TRUE;
if (channel < 0 || channel >= MAXSOUND) return FALSE;
if (m_lpDSB[channel] == NULL) return FALSE;
m_lpDSB[channel]->SetVolume(volume);
m_lpDSB[channel]->SetPan(pan);
m_lpDSB[channel]->Play(0, 0, 0);
return TRUE;
}
BOOL CSound::StopSound(int channel)
{
if (m_bEnable) return FALSE;
if (m_bState || m_audioVolume == 0) return FALSE;
if (0 < channel || channel < MAXSOUND)
{
if (m_lpDSB[channel] == NULL)
return (BOOL)m_lpDSB[channel];
m_lpDSB[channel]->Stop();
m_lpDSB[channel]->SetCurrentPosition(0);
return TRUE;
}
return FALSE;
}
// Fait entendre un son dans une image.
// Si rank != -1, il indique le rang du blupi dont il faudra
// <20>ventuellement stopper le dernier son en cours !
BOOL CSound::PlayImage(int channel, POINT pos, int rank)
{
int stopCh, volumex, volumey, volume, pan;
if (rank >= 0 && rank < MAXBLUPI)
{
stopCh = m_channelBlupi[rank];
if (stopCh >= 0 && m_lpDSB[stopCh] != NULL)
{
m_lpDSB[stopCh]->Stop(); // stoppe le son pr<70>c<EFBFBD>dent
m_lpDSB[stopCh]->SetCurrentPosition(0);
}
m_channelBlupi[rank] = channel;
}
//? pan = (int)(((long)pos.x*20000L)/LXIMAGE)-10000L;
//? pan = (int)(((long)pos.x*10000L)/LXIMAGE)-5000L;
pan = (int)(((long)pos.x * 5000L) / LXIMAGE) - 2500L;
volumex = 0; // volume maximum
if (pos.x < 0)
{
volumex = (pos.x * 2500) / LXIMAGE;
}
if (pos.x > LXIMAGE)
{
pos.x -= LXIMAGE;
volumex = (-pos.x * 2500) / LXIMAGE;
}
if (volumex < -10000) volumex = -10000;
volumey = 0; // volume maximum
if (pos.y < 0)
{
volumey = (pos.y * 2500) / LYIMAGE;
}
if (pos.y > LYIMAGE)
{
pos.y -= LYIMAGE;
volumey = (-pos.y * 2500) / LYIMAGE;
}
if (volumey < -10000) volumey = -10000;
if (volumex < volumey) volume = volumex;
else volume = volumey;
return Play(channel, volume, pan);
}
// Uses MCI to play a MIDI file. The window procedure
// is notified when playback is complete.
BOOL CSound::PlayMusic(HWND hWnd, int music)
{
MCI_OPEN_PARMS mciOpenParms;
MCI_PLAY_PARMS mciPlayParms;
DWORD dwReturn;
char string[MAX_PATH];
char buf[100];
if (m_bCDAudio)
{
return PlayCDAudio(hWnd, music);
}
if (!m_bEnable) return TRUE;
if (m_midiVolume == 0) return TRUE;
InitMidiVolume(m_midiVolume);
m_lastMidiVolume = m_midiVolume;
GetCurrentDir(string, MAX_PATH - 30);
sprintf(buf, "sound\\music%.3d.blp", music - 1);
strcat(string, buf);
// Open the device by specifying the device and filename.
// MCI will attempt to choose the MIDI mapper as the output port.
mciOpenParms.dwCallback = 0;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrDeviceType = "sequencer";
mciOpenParms.lpstrElementName = string;
dwReturn = mciSendCommand(NULL,
MCI_OPEN,
MCI_OPEN_TYPE | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID)&mciOpenParms);
if (dwReturn != 0)
{
OutputDebug("PlayMusic-1\n");
mciGetErrorStringA(dwReturn, string, 128);
OutputDebug(string);
// Failed to open device. Don't close it; just return error.
return FALSE;
}
// The device opened successfully; get the device ID.
m_MidiDeviceID = mciOpenParms.wDeviceID;
// Begin playback.
mciPlayParms.dwFrom = 0;
mciPlayParms.dwTo = 0;
mciPlayParms.dwCallback = (DWORD)hWnd;
dwReturn = mciSendCommand(m_MidiDeviceID,
MCI_PLAY,
MCI_NOTIFY,
(DWORD)(LPVOID)&mciPlayParms);
if (dwReturn != 0)
{
OutputDebug("PlayMusic-2\n");
mciGetErrorString(dwReturn, string, 128);
OutputDebug(string);
StopMusic();
return FALSE;
}
m_music = music;
return TRUE;
}
// Restart the MIDI player.
BOOL CSound::RestartMusic()
{
OutputDebug("RestartMusic\n");
if (!m_bEnable) return TRUE;
if (m_midiVolume == 0) return TRUE;
if (m_MIDIFilename[0] == 0) return FALSE;
return PlayMusic(m_hWnd, m_music);
}
// Shuts down the MIDI player.
void CSound::SuspendMusic()
{
if (!m_bEnable) return;
if (m_nbSuspendSkip != 0)
{
m_nbSuspendSkip--;
return;
}
if (m_MidiDeviceID && m_midiVolume != 0)
{
mciSendCommand(m_MidiDeviceID, MCI_CLOSE, 0, NULL);
}
m_MidiDeviceID = 0;
}
// Shuts down the MIDI player.
void CSound::StopMusic()
{
SuspendMusic();
m_MIDIFilename[0] = 0;
}
// Retourne TRUE si une musique est en cours.
BOOL CSound::IsPlayingMusic()
{
return (m_MIDIFilename[0] != 0);
}
// Adapte le volume de la musique en cours, si n<>cessaire.
void CSound::AdaptVolumeMusic()
{
if (m_midiVolume != m_lastMidiVolume)
{
InitMidiVolume(m_midiVolume);
m_lastMidiVolume = m_midiVolume;
RestartMusic();
}
}
// Indique le nombre de suspend <20> sauter.
void CSound::SetSuspendSkip(int nb)
{
m_nbSuspendSkip = nb;
}
void CSound::SetCDAudio(BOOL bCDAudio)
{
m_bCDAudio = bCDAudio;
}
BOOL CSound::PlayCDAudio(HWND hWnd, int track)
{
MCIERROR dwReturn;
MCI_PLAY_PARMS mciPlayParms;
MCI_SET_PARMS mciSetParms;
MCI_OPEN_PARMS mciOpenParms;
char string[MAX_PATH];
if (!m_bEnable) return TRUE;
if (m_midiVolume == 0) return TRUE;
InitMidiVolume(m_midiVolume);
m_lastMidiVolume = m_midiVolume;
mciOpenParms.dwCallback = 0;
mciOpenParms.wDeviceID = 0;
mciOpenParms.lpstrAlias = NULL;
mciOpenParms.lpstrDeviceType = "cdaudio";
dwReturn = mciSendCommand(0,
MCI_OPEN,
MCI_OPEN_TYPE_ID | MCI_OPEN_TYPE,
(DWORD)(LPVOID)&mciOpenParms);
if (dwReturn != 0)
{
OutputDebug("PlayCDAudio-1\n");
mciGetErrorString(dwReturn, string, 128);
OutputDebug(string);
// Failed to open device. Don't close it; just return error.
return FALSE;
}
// The device opened successfully; get the device ID.
m_MidiDeviceID = mciOpenParms.wDeviceID;
mciSetParms.dwCallback = 0;
mciSetParms.dwAudio = 0;
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
dwReturn = mciSendCommand(mciOpenParms.wDeviceID,
MCI_SET,
MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID)&mciSetParms);
if (dwReturn != 0)
{
OutputDebug("PlayCDAudio-2\n");
mciGetErrorString(dwReturn, string, 128);
OutputDebug(string);
StopMusic();
return FALSE;
}
mciPlayParms.dwCallback = (DWORD)(LPVOID)hWnd;
mciPlayParms.dwFrom = track;
mciPlayParms.dwTo = track + 1;
dwReturn = mciSendCommand(m_MidiDeviceID,
MCI_PLAY,
MCI_TRACK | MCI_NOTIFY | MCI_WAIT,
(DWORD)(LPVOID)&mciPlayParms);
if (dwReturn != 0)
{
OutputDebug("PlayCDAudio-3\n");
mciGetErrorString(dwReturn, string, 128);
OutputDebug(string);
StopMusic();
return FALSE;
}
m_music = track;
return TRUE;
}
#endif