From 6c79e35c255b842da2fa4fd3fc50787a40e8ffd2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 26 Dec 2023 22:14:14 +0100 Subject: [PATCH] Backend update from GZDoom. --- source/common/audio/music/music.cpp | 51 ++- source/common/audio/music/s_music.h | 3 +- source/common/audio/sound/oalsound.h | 2 +- source/common/audio/sound/thirdparty/alext.h | 287 ++++++++++++-- source/common/engine/sc_man.cpp | 10 +- source/common/engine/sc_man.h | 2 + source/common/filesystem/include/fs_files.h | 3 +- .../filesystem/source/file_directory.cpp | 12 +- .../common/scripting/interface/vmnatives.cpp | 358 ++++++++++++++++++ source/common/utility/vectors.h | 12 +- source/core/music/s_advsound.cpp | 11 +- 11 files changed, 683 insertions(+), 68 deletions(-) diff --git a/source/common/audio/music/music.cpp b/source/common/audio/music/music.cpp index 43e05cb5c69..8749f4ba339 100644 --- a/source/common/audio/music/music.cpp +++ b/source/common/audio/music/music.cpp @@ -57,6 +57,7 @@ #include "c_cvars.h" #include "md5.h" + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- extern int nomusic; @@ -94,11 +95,6 @@ EXTERN_CVAR(Float, fluid_gain) CVAR(Bool, mus_calcgain, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song. CVAR(Bool, mus_usereplaygain, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // changing this will only take effect for the next song. -CUSTOM_CVAR(Float, mus_gainoffset, 0.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // for customizing the base volume -{ - if (self > 10.f) self = 10.f; - mus_playing.replayGainFactor = dBToAmplitude(mus_playing.replayGain + mus_gainoffset); -} // CODE -------------------------------------------------------------------- @@ -167,12 +163,12 @@ static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata) if (mus_playing.isfloat) { written = ZMusic_FillStream(mus_playing.handle, buff, len); - if (mus_playing.replayGainFactor != 1.f) + if (mus_playing.musicVolume != 1.f) { float* fbuf = (float*)buff; for (int i = 0; i < len / 4; i++) { - fbuf[i] *= mus_playing.replayGainFactor; + fbuf[i] *= mus_playing.musicVolume; } } } @@ -184,7 +180,7 @@ static bool FillStream(SoundStream* stream, void* buff, int len, void* userdata) float* fbuf = (float*)buff; for (int i = 0; i < len / 4; i++) { - fbuf[i] = convert[i] * mus_playing.replayGainFactor * (1.f/32768.f); + fbuf[i] = convert[i] * mus_playing.musicVolume * (1.f/32768.f); } } @@ -508,21 +504,19 @@ CCMD(setreplaygain) if (argv.argc() < 2) { Printf("Usage: setreplaygain {dB}\n"); - Printf("Current replay gain is %f dB\n", mus_playing.replayGain); + Printf("Current replay gain is %f dB\n", AmplitudeTodB(mus_playing.musicVolume)); return; } float dB = (float)strtod(argv[1], nullptr); if (dB > 10) dB = 10; // don't blast the speakers. Values above 2 or 3 are very rare. gainMap.Insert(mus_playing.hash, dB); SaveGains(); - mus_playing.replayGain = dB; - mus_playing.replayGainFactor = (float)dBToAmplitude(mus_playing.replayGain + mus_gainoffset); + mus_playing.musicVolume = (float)dBToAmplitude(dB); } static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const char *playparam) { - mus_playing.replayGain = 0.f; - mus_playing.replayGainFactor = dBToAmplitude(mus_gainoffset); + mus_playing.musicVolume = 1; fluid_gain->Callback(); mod_dumb_mastervolume->Callback(); if (!mus_usereplaygain) return; @@ -539,8 +533,7 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const auto entry = gainMap.CheckKey(hash); if (entry) { - mus_playing.replayGain = *entry; - mus_playing.replayGainFactor = dBToAmplitude(mus_playing.replayGain + mus_gainoffset); + mus_playing.musicVolume = dBToAmplitude(*entry); return; } if (!mus_calcgain) return; @@ -624,19 +617,18 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const } ZMusic_Close(handle); - GainAnalyzer analyzer; - int result = analyzer.InitGainAnalysis(fmt.mSampleRate); + auto analyzer = std::make_unique(); + int result = analyzer->InitGainAnalysis(fmt.mSampleRate); if (result == GAIN_ANALYSIS_OK) { - result = analyzer.AnalyzeSamples(lbuffer.Data(), rbuffer.Size() == 0 ? nullptr : rbuffer.Data(), lbuffer.Size(), rbuffer.Size() == 0 ? 1 : 2); + result = analyzer->AnalyzeSamples(lbuffer.Data(), rbuffer.Size() == 0 ? nullptr : rbuffer.Data(), lbuffer.Size(), rbuffer.Size() == 0 ? 1 : 2); if (result == GAIN_ANALYSIS_OK) { - auto gain = analyzer.GetTitleGain(); - Printf("Calculated replay gain for %s at %f dB\n", hash.GetChars(), gain); + auto gain = analyzer->GetTitleGain(); + Printf("Calculated replay gain for %s (%s) at %f dB\n", musicname, hash.GetChars(), gain); gainMap.Insert(hash, gain); - mus_playing.replayGain = gain; - mus_playing.replayGainFactor = dBToAmplitude(mus_playing.replayGain + mus_gainoffset); + mus_playing.musicVolume = dBToAmplitude(gain); SaveGains(); } } @@ -726,8 +718,16 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) } else { + auto volp = MusicVolumes.CheckKey(musicname); + if (volp) + { + mus_playing.musicVolume = *volp; - CheckReplayGain(musicname, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); + } + else + { + CheckReplayGain(musicname, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); + } auto mreader = GetMusicReader(reader); // this passes the file reader to the newly created wrapper. mus_playing.handle = ZMusic_OpenSong(mreader, devp ? (EMidiDevice)devp->device : MDEV_DEFAULT, devp ? devp->args.GetChars() : ""); if (mus_playing.handle == nullptr) @@ -743,13 +743,12 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) if (mus_playing.handle != 0) { // play it - auto volp = MusicVolumes.CheckKey(musicname); - float vol = volp ? *volp : 1.f; - if (!S_StartMusicPlaying(mus_playing.handle, looping, vol, order)) + if (!S_StartMusicPlaying(mus_playing.handle, looping, 1.f, order)) { Printf("Unable to start %s: %s\n", mus_playing.name.GetChars(), ZMusic_GetLastError()); return false; } + S_CreateStream(); mus_playing.baseorder = order; return true; diff --git a/source/common/audio/music/s_music.h b/source/common/audio/music/s_music.h index 6ae4017c9e0..e697613cde0 100644 --- a/source/common/audio/music/s_music.h +++ b/source/common/audio/music/s_music.h @@ -79,8 +79,7 @@ struct MusPlayingInfo FString name; ZMusic_MusicStream handle; int baseorder; - float replayGain; - float replayGainFactor; + float musicVolume; bool loop; bool isfloat; FString LastSong; // last music that was played diff --git a/source/common/audio/sound/oalsound.h b/source/common/audio/sound/oalsound.h index 4b277bc25ae..6e5c93a87a6 100644 --- a/source/common/audio/sound/oalsound.h +++ b/source/common/audio/sound/oalsound.h @@ -21,7 +21,7 @@ #include "alc.h" #endif -#include "alext.h" +#include "thirdparty/alext.h" class OpenALSoundStream; diff --git a/source/common/audio/sound/thirdparty/alext.h b/source/common/audio/sound/thirdparty/alext.h index 7d2a95274a7..edfae47353b 100644 --- a/source/common/audio/sound/thirdparty/alext.h +++ b/source/common/audio/sound/thirdparty/alext.h @@ -13,8 +13,8 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Or go to http://www.gnu.org/copyleft/lgpl.html */ @@ -22,22 +22,22 @@ #define AL_ALEXT_H #include -/* Define int64_t and uint64_t types */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(_WIN32) && defined(__GNUC__) +/* Define int64 and uint64 types */ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus >= 201103L) #include +typedef int64_t _alsoft_int64_t; +typedef uint64_t _alsoft_uint64_t; #elif defined(_WIN32) -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; +typedef __int64 _alsoft_int64_t; +typedef unsigned __int64 _alsoft_uint64_t; #else /* Fallback if nothing above works */ -#include +#include +typedef int64_t _alsoft_int64_t; +typedef uint64_t _alsoft_uint64_t; #endif -#include "alc.h" -#include "al.h" - #ifdef __cplusplus extern "C" { #endif @@ -97,6 +97,31 @@ extern "C" { #ifndef AL_EXT_MCFORMATS #define AL_EXT_MCFORMATS 1 +/* Provides support for surround sound buffer formats with 8, 16, and 32-bit + * samples. + * + * QUAD8: Unsigned 8-bit, Quadraphonic (Front Left, Front Right, Rear Left, + * Rear Right). + * QUAD16: Signed 16-bit, Quadraphonic. + * QUAD32: 32-bit float, Quadraphonic. + * REAR8: Unsigned 8-bit, Rear Stereo (Rear Left, Rear Right). + * REAR16: Signed 16-bit, Rear Stereo. + * REAR32: 32-bit float, Rear Stereo. + * 51CHN8: Unsigned 8-bit, 5.1 Surround (Front Left, Front Right, Front Center, + * LFE, Side Left, Side Right). Note that some audio systems may label + * 5.1's Side channels as Rear or Surround; they are equivalent for the + * purposes of this extension. + * 51CHN16: Signed 16-bit, 5.1 Surround. + * 51CHN32: 32-bit float, 5.1 Surround. + * 61CHN8: Unsigned 8-bit, 6.1 Surround (Front Left, Front Right, Front Center, + * LFE, Rear Center, Side Left, Side Right). + * 61CHN16: Signed 16-bit, 6.1 Surround. + * 61CHN32: 32-bit float, 6.1 Surround. + * 71CHN8: Unsigned 8-bit, 7.1 Surround (Front Left, Front Right, Front Center, + * LFE, Rear Left, Rear Right, Side Left, Side Right). + * 71CHN16: Signed 16-bit, 7.1 Surround. + * 71CHN32: 32-bit float, 7.1 Surround. + */ #define AL_FORMAT_QUAD8 0x1204 #define AL_FORMAT_QUAD16 0x1205 #define AL_FORMAT_QUAD32 0x1206 @@ -133,9 +158,9 @@ extern "C" { #ifndef AL_EXT_STATIC_BUFFER #define AL_EXT_STATIC_BUFFER 1 -typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei); +typedef void (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq); +AL_API void AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq); #endif #endif @@ -168,9 +193,9 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void); #define AL_SOFT_buffer_sub_data 1 #define AL_BYTE_RW_OFFSETS_SOFT 0x1031 #define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032 -typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei); +typedef void (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length); +AL_API void AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length); #endif #endif @@ -318,8 +343,8 @@ ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffe #define AL_SOFT_source_latency 1 #define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 #define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 -typedef int64_t ALint64SOFT; -typedef uint64_t ALuint64SOFT; +typedef _alsoft_int64_t ALint64SOFT; +typedef _alsoft_uint64_t ALuint64SOFT; typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble); typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble); typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*); @@ -356,11 +381,11 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 #ifndef AL_SOFT_deferred_updates #define AL_SOFT_deferred_updates 1 #define AL_DEFERRED_UPDATES_SOFT 0xC002 -typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void); -typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void); +typedef void (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void); +typedef void (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void); #ifdef AL_ALEXT_PROTOTYPES -AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void); -AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void); +AL_API void AL_APIENTRY alDeferUpdatesSOFT(void); +AL_API void AL_APIENTRY alProcessUpdatesSOFT(void); #endif #endif @@ -393,6 +418,224 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device); #endif #endif +#ifndef AL_EXT_BFORMAT +#define AL_EXT_BFORMAT 1 +/* Provides support for B-Format ambisonic buffers (first-order, FuMa scaling + * and layout). + * + * BFORMAT2D_8: Unsigned 8-bit, 3-channel non-periphonic (WXY). + * BFORMAT2D_16: Signed 16-bit, 3-channel non-periphonic (WXY). + * BFORMAT2D_FLOAT32: 32-bit float, 3-channel non-periphonic (WXY). + * BFORMAT3D_8: Unsigned 8-bit, 4-channel periphonic (WXYZ). + * BFORMAT3D_16: Signed 16-bit, 4-channel periphonic (WXYZ). + * BFORMAT3D_FLOAT32: 32-bit float, 4-channel periphonic (WXYZ). + */ +#define AL_FORMAT_BFORMAT2D_8 0x20021 +#define AL_FORMAT_BFORMAT2D_16 0x20022 +#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023 +#define AL_FORMAT_BFORMAT3D_8 0x20031 +#define AL_FORMAT_BFORMAT3D_16 0x20032 +#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033 +#endif + +#ifndef AL_EXT_MULAW_BFORMAT +#define AL_EXT_MULAW_BFORMAT 1 +#define AL_FORMAT_BFORMAT2D_MULAW 0x10031 +#define AL_FORMAT_BFORMAT3D_MULAW 0x10032 +#endif + +#ifndef ALC_SOFT_HRTF +#define ALC_SOFT_HRTF 1 +#define ALC_HRTF_SOFT 0x1992 +#define ALC_DONT_CARE_SOFT 0x0002 +#define ALC_HRTF_STATUS_SOFT 0x1993 +#define ALC_HRTF_DISABLED_SOFT 0x0000 +#define ALC_HRTF_ENABLED_SOFT 0x0001 +#define ALC_HRTF_DENIED_SOFT 0x0002 +#define ALC_HRTF_REQUIRED_SOFT 0x0003 +#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004 +#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005 +#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994 +#define ALC_HRTF_SPECIFIER_SOFT 0x1995 +#define ALC_HRTF_ID_SOFT 0x1996 +typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index); +typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs); +#ifdef AL_ALEXT_PROTOTYPES +ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index); +ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs); +#endif +#endif + +#ifndef AL_SOFT_gain_clamp_ex +#define AL_SOFT_gain_clamp_ex 1 +#define AL_GAIN_LIMIT_SOFT 0x200E +#endif + +#ifndef AL_SOFT_source_resampler +#define AL_SOFT_source_resampler +#define AL_NUM_RESAMPLERS_SOFT 0x1210 +#define AL_DEFAULT_RESAMPLER_SOFT 0x1211 +#define AL_SOURCE_RESAMPLER_SOFT 0x1212 +#define AL_RESAMPLER_NAME_SOFT 0x1213 +typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index); +#ifdef AL_ALEXT_PROTOTYPES +AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index); +#endif +#endif + +#ifndef AL_SOFT_source_spatialize +#define AL_SOFT_source_spatialize +#define AL_SOURCE_SPATIALIZE_SOFT 0x1214 +#define AL_AUTO_SOFT 0x0002 +#endif + +#ifndef ALC_SOFT_output_limiter +#define ALC_SOFT_output_limiter +#define ALC_OUTPUT_LIMITER_SOFT 0x199A +#endif + +#ifndef ALC_SOFT_device_clock +#define ALC_SOFT_device_clock 1 +typedef _alsoft_int64_t ALCint64SOFT; +typedef _alsoft_uint64_t ALCuint64SOFT; +#define ALC_DEVICE_CLOCK_SOFT 0x1600 +#define ALC_DEVICE_LATENCY_SOFT 0x1601 +#define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602 +#define AL_SAMPLE_OFFSET_CLOCK_SOFT 0x1202 +#define AL_SEC_OFFSET_CLOCK_SOFT 0x1203 +typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values); +#ifdef AL_ALEXT_PROTOTYPES +ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values); +#endif +#endif + +#ifndef AL_SOFT_direct_channels_remix +#define AL_SOFT_direct_channels_remix 1 +#define AL_DROP_UNMATCHED_SOFT 0x0001 +#define AL_REMIX_UNMATCHED_SOFT 0x0002 +#endif + +#ifndef AL_SOFT_bformat_ex +#define AL_SOFT_bformat_ex 1 +#define AL_AMBISONIC_LAYOUT_SOFT 0x1997 +#define AL_AMBISONIC_SCALING_SOFT 0x1998 + +/* Ambisonic layouts */ +#define AL_FUMA_SOFT 0x0000 +#define AL_ACN_SOFT 0x0001 + +/* Ambisonic scalings (normalization) */ +/*#define AL_FUMA_SOFT*/ +#define AL_SN3D_SOFT 0x0001 +#define AL_N3D_SOFT 0x0002 +#endif + +#ifndef ALC_SOFT_loopback_bformat +#define ALC_SOFT_loopback_bformat 1 +#define ALC_AMBISONIC_LAYOUT_SOFT 0x1997 +#define ALC_AMBISONIC_SCALING_SOFT 0x1998 +#define ALC_AMBISONIC_ORDER_SOFT 0x1999 +#define ALC_MAX_AMBISONIC_ORDER_SOFT 0x199B + +#define ALC_BFORMAT3D_SOFT 0x1507 + +/* Ambisonic layouts */ +#define ALC_FUMA_SOFT 0x0000 +#define ALC_ACN_SOFT 0x0001 + +/* Ambisonic scalings (normalization) */ +/*#define ALC_FUMA_SOFT*/ +#define ALC_SN3D_SOFT 0x0001 +#define ALC_N3D_SOFT 0x0002 +#endif + +#ifndef AL_SOFT_effect_target +#define AL_SOFT_effect_target +#define AL_EFFECTSLOT_TARGET_SOFT 0x199C +#endif + +#ifndef AL_SOFT_events +#define AL_SOFT_events 1 +#define AL_EVENT_CALLBACK_FUNCTION_SOFT 0x19A2 +#define AL_EVENT_CALLBACK_USER_PARAM_SOFT 0x19A3 +#define AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT 0x19A4 +#define AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT 0x19A5 +#define AL_EVENT_TYPE_DISCONNECTED_SOFT 0x19A6 +typedef void (AL_APIENTRY*ALEVENTPROCSOFT)(ALenum eventType, ALuint object, ALuint param, + ALsizei length, const ALchar *message, + void *userParam); +typedef void (AL_APIENTRY*LPALEVENTCONTROLSOFT)(ALsizei count, const ALenum *types, ALboolean enable); +typedef void (AL_APIENTRY*LPALEVENTCALLBACKSOFT)(ALEVENTPROCSOFT callback, void *userParam); +typedef void* (AL_APIENTRY*LPALGETPOINTERSOFT)(ALenum pname); +typedef void (AL_APIENTRY*LPALGETPOINTERVSOFT)(ALenum pname, void **values); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, ALboolean enable); +AL_API void AL_APIENTRY alEventCallbackSOFT(ALEVENTPROCSOFT callback, void *userParam); +AL_API void* AL_APIENTRY alGetPointerSOFT(ALenum pname); +AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values); +#endif +#endif + +#ifndef ALC_SOFT_reopen_device +#define ALC_SOFT_reopen_device +typedef ALCboolean (ALC_APIENTRY*LPALCREOPENDEVICESOFT)(ALCdevice *device, + const ALCchar *deviceName, const ALCint *attribs); +#ifdef AL_ALEXT_PROTOTYPES +ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, const ALCchar *deviceName, + const ALCint *attribs); +#endif +#endif + +#ifndef AL_SOFT_callback_buffer +#define AL_SOFT_callback_buffer +#define AL_BUFFER_CALLBACK_FUNCTION_SOFT 0x19A0 +#define AL_BUFFER_CALLBACK_USER_PARAM_SOFT 0x19A1 +typedef ALsizei (AL_APIENTRY*ALBUFFERCALLBACKTYPESOFT)(ALvoid *userptr, ALvoid *sampledata, ALsizei numbytes); +typedef void (AL_APIENTRY*LPALBUFFERCALLBACKSOFT)(ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr); +typedef void (AL_APIENTRY*LPALGETBUFFERPTRSOFT)(ALuint buffer, ALenum param, ALvoid **value); +typedef void (AL_APIENTRY*LPALGETBUFFER3PTRSOFT)(ALuint buffer, ALenum param, ALvoid **value1, ALvoid **value2, ALvoid **value3); +typedef void (AL_APIENTRY*LPALGETBUFFERPTRVSOFT)(ALuint buffer, ALenum param, ALvoid **values); +#ifdef AL_ALEXT_PROTOTYPES +AL_API void AL_APIENTRY alBufferCallbackSOFT(ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr); +AL_API void AL_APIENTRY alGetBufferPtrSOFT(ALuint buffer, ALenum param, ALvoid **ptr); +AL_API void AL_APIENTRY alGetBuffer3PtrSOFT(ALuint buffer, ALenum param, ALvoid **ptr0, ALvoid **ptr1, ALvoid **ptr2); +AL_API void AL_APIENTRY alGetBufferPtrvSOFT(ALuint buffer, ALenum param, ALvoid **ptr); +#endif +#endif + +#ifndef AL_SOFT_UHJ +#define AL_SOFT_UHJ +#define AL_FORMAT_UHJ2CHN8_SOFT 0x19A2 +#define AL_FORMAT_UHJ2CHN16_SOFT 0x19A3 +#define AL_FORMAT_UHJ2CHN_FLOAT32_SOFT 0x19A4 +#define AL_FORMAT_UHJ3CHN8_SOFT 0x19A5 +#define AL_FORMAT_UHJ3CHN16_SOFT 0x19A6 +#define AL_FORMAT_UHJ3CHN_FLOAT32_SOFT 0x19A7 +#define AL_FORMAT_UHJ4CHN8_SOFT 0x19A8 +#define AL_FORMAT_UHJ4CHN16_SOFT 0x19A9 +#define AL_FORMAT_UHJ4CHN_FLOAT32_SOFT 0x19AA + +#define AL_STEREO_MODE_SOFT 0x19B0 +#define AL_NORMAL_SOFT 0x0000 +#define AL_SUPER_STEREO_SOFT 0x0001 +#define AL_SUPER_STEREO_WIDTH_SOFT 0x19B1 +#endif + +#ifndef ALC_SOFT_output_mode +#define ALC_SOFT_output_mode +#define ALC_OUTPUT_MODE_SOFT 0x19AC +#define ALC_ANY_SOFT 0x19AD +/*#define ALC_MONO_SOFT 0x1500*/ +/*#define ALC_STEREO_SOFT 0x1501*/ +#define ALC_STEREO_BASIC_SOFT 0x19AE +#define ALC_STEREO_UHJ_SOFT 0x19AF +#define ALC_STEREO_HRTF_SOFT 0x19B2 +/*#define ALC_QUAD_SOFT 0x1503*/ +#define ALC_SURROUND_5_1_SOFT 0x1504 +#define ALC_SURROUND_6_1_SOFT 0x1505 +#define ALC_SURROUND_7_1_SOFT 0x1506 +#endif + #ifdef __cplusplus } #endif diff --git a/source/common/engine/sc_man.cpp b/source/common/engine/sc_man.cpp index 9849c2e21ed..ac7b4799f77 100644 --- a/source/common/engine/sc_man.cpp +++ b/source/common/engine/sc_man.cpp @@ -260,6 +260,7 @@ void FScanner::PrepareScript () StateOptions = false; StringBuffer[0] = '\0'; BigStringBuffer = ""; + ParseError = false; } //========================================================================== @@ -1089,13 +1090,14 @@ void FScanner::ScriptError (const char *message, ...) va_end (arglist); } + ParseError = true; if (NoFatalErrors) { - Printf(TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), + Printf(TEXTCOLOR_RED "%sScript error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", PrependMessage.GetChars(), ScriptName.GetChars(), AlreadyGot ? AlreadyGotLine : Line, composed.GetChars()); return; } - I_Error ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(), + I_Error ("%sScript error, \"%s\" line %d:\n%s\n", PrependMessage.GetChars(), ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } @@ -1121,7 +1123,8 @@ void FScanner::ScriptMessage (const char *message, ...) va_end (arglist); } - Printf (TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), + ParseError = true; + Printf (TEXTCOLOR_RED "%sScript error, \"%s\"" TEXTCOLOR_RED " line %d:\n" TEXTCOLOR_RED "%s\n", PrependMessage.GetChars(), ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } @@ -1383,4 +1386,3 @@ int ParseHex(const char* hex, FScriptPosition* sc) return num; } - diff --git a/source/common/engine/sc_man.h b/source/common/engine/sc_man.h index 32848a4a630..5873523a12c 100644 --- a/source/common/engine/sc_man.h +++ b/source/common/engine/sc_man.h @@ -192,6 +192,7 @@ class FScanner void ScriptError(const char *message, ...) GCCPRINTF(2,3); void ScriptMessage(const char *message, ...) GCCPRINTF(2,3); + void SetPrependMessage(const FString& message) { PrependMessage = message; } bool isText(); @@ -238,6 +239,7 @@ class FScanner bool StateOptions; bool Escape; VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default + FString PrependMessage = ""; bool ScanValue(bool allowfloat, bool evaluate); diff --git a/source/common/filesystem/include/fs_files.h b/source/common/filesystem/include/fs_files.h index 463ede7ae4e..7702f68de3f 100644 --- a/source/common/filesystem/include/fs_files.h +++ b/source/common/filesystem/include/fs_files.h @@ -89,7 +89,8 @@ class FileData if (own) { length = len; - memory = allocate(len); + memory = malloc(len); + owned = true; if (memory_) memcpy(memory, memory_, len); } else diff --git a/source/common/filesystem/source/file_directory.cpp b/source/common/filesystem/source/file_directory.cpp index 01eee7bf2a1..8fb082c0ca1 100644 --- a/source/common/filesystem/source/file_directory.cpp +++ b/source/common/filesystem/source/file_directory.cpp @@ -44,10 +44,6 @@ namespace FileSys { std::string FS_FullPath(const char* directory); -#ifdef _WIN32 -std::wstring toWide(const char* str); -#endif - //========================================================================== // // Zip file @@ -58,6 +54,8 @@ class FDirectory : public FResourceFile { const bool nosubdir; const char* mBasePath; + const char** SystemFilePath; + int AddDirectory(const char* dirpath, LumpFilterInfo* filter, FileSystemMessageFunc Printf); @@ -102,6 +100,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy { mBasePath = nullptr; AllocateEntries((int)list.size()); + SystemFilePath = (const char**)stringpool->Alloc(list.size() * sizeof(const char*)); for(auto& entry : list) { if (mBasePath == nullptr) @@ -131,6 +130,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy } // for internal access we use the normalized form of the relative path. Entries[count].FileName = NormalizeFileName(entry.FilePathRel.c_str()); + SystemFilePath[count] = Entries[count].FileName; Entries[count].CompressedSize = Entries[count].Length = entry.Length; Entries[count].Flags = RESFF_FULLPATH; Entries[count].ResourceID = -1; @@ -153,6 +153,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { NumLumps = AddDirectory(FileName, filter, Printf); + PostProcessArchive(filter); return true; } @@ -167,7 +168,8 @@ FileReader FDirectory::GetEntryReader(uint32_t entry, int readertype, int) FileReader fr; if (entry < NumLumps) { - std::string fn = mBasePath; fn += Entries[entry].FileName; + std::string fn = mBasePath; + fn += SystemFilePath[entry]; fr.OpenFile(fn.c_str()); if (readertype == READER_CACHED) { diff --git a/source/common/scripting/interface/vmnatives.cpp b/source/common/scripting/interface/vmnatives.cpp index 7480f4c329a..48425f64eba 100644 --- a/source/common/scripting/interface/vmnatives.cpp +++ b/source/common/scripting/interface/vmnatives.cpp @@ -1407,3 +1407,361 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Translation, MakeID, MakeTransID) ACTION_RETURN_INT(MakeTransID(g, t)); } +// DObject-based wrapper around FScanner, for ZScript. +class DScriptScanner : public DObject +{ + DECLARE_CLASS(DScriptScanner, DObject) +public: + FScanner wrapped; + +}; + +IMPLEMENT_CLASS(DScriptScanner, false, false); + +static void OpenLumpNum(DScriptScanner* self, int lump) { return self->wrapped.OpenLumpNum(lump); } +static void OpenString(DScriptScanner* self, const FString* name, FString* script) { return self->wrapped.OpenString(name->GetChars(), *script); } +static void SavePos(DScriptScanner* self, FScanner::SavedPos *pos) { *pos = self->wrapped.SavePos(); } +static void RestorePos(DScriptScanner* self, const FScanner::SavedPos* pos) { return self->wrapped.RestorePos(*pos); } +static void GetStringContents(DScriptScanner* self, FString* str) { *str = self->wrapped.String; } +static void UnGet(DScriptScanner* self) { return self->wrapped.UnGet(); } +static int isText(DScriptScanner* self) { return self->wrapped.isText(); } +static int GetMessageLine(DScriptScanner* self) { return self->wrapped.GetMessageLine(); } +static void Close(DScriptScanner* self) { return self->wrapped.Close(); } +static void SetCMode(DScriptScanner* self, int cmode) { return self->wrapped.SetCMode(cmode); } +static void SetNoOctals(DScriptScanner* self, int cmode) { return self->wrapped.SetNoOctals(cmode); } +static void SetEscape(DScriptScanner* self, int esc) { return self->wrapped.SetNoOctals(esc); } +static void SetNoFatalErrors(DScriptScanner* self, int cmode) { return self->wrapped.SetNoFatalErrors(cmode); } +static void AddSymbolUint(DScriptScanner* self, const FString* name, uint32_t value) { return self->wrapped.AddSymbol(name->GetChars(), value); } +static void AddSymbolInt(DScriptScanner* self, const FString* name, int32_t value) { return self->wrapped.AddSymbol(name->GetChars(), value); } +static void AddSymbolDouble(DScriptScanner* self, const FString* name, double value) { return self->wrapped.AddSymbol(name->GetChars(), value); } +static int GetString(DScriptScanner* self) { return self->wrapped.GetString(); } +static int GetNumber(DScriptScanner* self, int evaluate) { return self->wrapped.GetNumber(evaluate); } +static int GetFloat(DScriptScanner* self, int evaluate) { return self->wrapped.GetFloat(evaluate); } +static int CheckValue(DScriptScanner* self, int allowfloat, int evaluate) { return self->wrapped.CheckValue(allowfloat, evaluate); } +static int CheckNumber(DScriptScanner* self, int evaluate) { return self->wrapped.CheckNumber(evaluate); } +static int CheckBoolToken(DScriptScanner* self) { return self->wrapped.CheckBoolToken(); } +static int CheckString(DScriptScanner* self, const FString* name) { return self->wrapped.CheckString(name->GetChars()); } +static int CheckFloat(DScriptScanner* self, int evaluate) { return self->wrapped.CheckFloat(evaluate); } +static void SetPrependMessage(DScriptScanner* self, const FString* message) { return self->wrapped.SetPrependMessage(*message); } +static void SkipToEndOfBlock(DScriptScanner* self) { return self->wrapped.SkipToEndOfBlock(); } +static int StartBraces(DScriptScanner* self, FScanner::SavedPos* braceend) { return self->wrapped.StartBraces(braceend); } +static int FoundEndBrace(DScriptScanner* self, FScanner::SavedPos* braceend) { return self->wrapped.FoundEndBrace(*braceend); } +static void MustGetValue(DScriptScanner* self, int allowfloat, int evaluate) { return self->wrapped.MustGetValue(allowfloat, evaluate); } +static void MustGetFloat(DScriptScanner* self, int evaluate) { return self->wrapped.MustGetFloat(evaluate); } +static void MustGetNumber(DScriptScanner* self, int evaluate) { return self->wrapped.MustGetNumber(evaluate); } +static void MustGetString(DScriptScanner* self) { return self->wrapped.MustGetString(); } +static void MustGetStringName(DScriptScanner* self, const FString* name) { return self->wrapped.MustGetStringName(name->GetChars()); } +static void MustGetBoolToken(DScriptScanner* self) { return self->wrapped.MustGetBoolToken(); } + + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, OpenLumpNum, OpenLumpNum) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_INT(lump); + + OpenLumpNum(self, lump); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, OpenString, OpenString) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + PARAM_STRING_VAL(script); + + OpenString(self, &name, &script); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SavePos, SavePos) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_POINTER(pos, FScanner::SavedPos); + + SavePos(self, pos); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, RestorePos, RestorePos) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_POINTER(pos, FScanner::SavedPos); + + RestorePos(self, pos); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, GetStringContents, GetStringContents) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + ACTION_RETURN_STRING(self->wrapped.String); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, UnGet, UnGet) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + UnGet(self); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, isText, isText) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + ACTION_RETURN_BOOL(isText(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, GetMessageLine, GetMessageLine) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + ACTION_RETURN_INT(GetMessageLine(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, AddSymbol, AddSymbolInt) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + PARAM_INT(value); + + AddSymbolInt(self, &name, value); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, AddSymbolUnsigned, AddSymbolUint) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + PARAM_UINT(value); + + AddSymbolUint(self, &name, value); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, AddSymbolFloat, AddSymbolDouble) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + PARAM_FLOAT(value); + + AddSymbolDouble(self, &name, value); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, GetString, GetString) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + ACTION_RETURN_BOOL(GetString(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, GetNumber, GetNumber) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + ACTION_RETURN_BOOL(GetNumber(self, evaluate)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, GetFloat, GetFloat) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + ACTION_RETURN_BOOL(GetFloat(self, evaluate)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, CheckValue, CheckValue) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(allowfloat); + PARAM_BOOL(evaluate); + + ACTION_RETURN_BOOL(CheckValue(self, allowfloat, evaluate)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, CheckBoolToken, CheckBoolToken) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + ACTION_RETURN_BOOL(CheckBoolToken(self)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, CheckNumber, CheckNumber) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + ACTION_RETURN_BOOL(CheckNumber(self, evaluate)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, CheckString, CheckString) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + + ACTION_RETURN_BOOL(CheckString(self, &name)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, CheckFloat, CheckFloat) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + ACTION_RETURN_BOOL(CheckFloat(self, evaluate)); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SetPrependMessage, SetPrependMessage) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(message); + + SetPrependMessage(self, &message); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SetCMode, SetCMode) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(cmode); + + SetCMode(self, cmode); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SetNoOctals, SetNoOctals) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(cmode); + + SetNoOctals(self, cmode); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SetEscape, SetEscape) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(esc); + + SetEscape(self, esc); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SkipToEndOfBlock, SkipToEndOfBlock) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + SkipToEndOfBlock(self); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, StartBraces, StartBraces) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_POINTER(braceend, FScanner::SavedPos); + + StartBraces(self, braceend); // the return value of this is useless. + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, FoundEndBrace, FoundEndBrace) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_POINTER(braceend, FScanner::SavedPos); + + ACTION_RETURN_BOOL(FoundEndBrace(self, braceend)); +} + +DEFINE_ACTION_FUNCTION(DScriptScanner, ScriptError) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + FString s = FStringFormat(VM_ARGS_NAMES); + self->wrapped.ScriptError("%s", s.GetChars()); + return 0; +} + +DEFINE_ACTION_FUNCTION(DScriptScanner, ScriptMessage) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + FString s = FStringFormat(VM_ARGS_NAMES); + self->wrapped.ScriptMessage("%s", s.GetChars()); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetValue, MustGetValue) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(allowfloat); + PARAM_BOOL(evaluate); + + MustGetValue(self, allowfloat, evaluate); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetNumber, MustGetNumber) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + MustGetNumber(self, evaluate); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetFloat, MustGetFloat) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(evaluate); + + MustGetFloat(self, evaluate); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetString, MustGetString) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + MustGetString(self); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetStringName, MustGetStringName) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_STRING(name); + + MustGetStringName(self, &name); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, MustGetBoolToken, MustGetBoolToken) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + MustGetBoolToken(self); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, Close, Close) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + + Close(self); + return 0; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DScriptScanner, SetNoFatalErrors, SetNoFatalErrors) +{ + PARAM_SELF_PROLOGUE(DScriptScanner); + PARAM_BOOL(cmode); + + SetNoFatalErrors(self, cmode); + return 0; +} + +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.Line, Line); +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.Float, Float); +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.Number, Number); +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.End, End); +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.Crossed, Crossed); +DEFINE_FIELD_NAMED_X(ScriptScanner, DScriptScanner, wrapped.ParseError, ParseError); diff --git a/source/common/utility/vectors.h b/source/common/utility/vectors.h index c861ffdfa97..77e41d2a9e4 100644 --- a/source/common/utility/vectors.h +++ b/source/common/utility/vectors.h @@ -60,12 +60,12 @@ namespace pi #if __has_include("math/cmath.h") #include "math/cmath.h" #else -double g_cosdeg(double v) { return cos(v * (pi::pi() / 180.)); } -double g_sindeg(double v) { return sin(v * (pi::pi() / 180.)); } -double g_cos(double v) { return cos(v); } -double g_sin(double v) { return sin(v); } -double g_sqrt(double v) { return sqrt(v); } -double g_atan2(double v, double w) { return atan2(v, w); } +inline double g_cosdeg(double v) { return cos(v * (pi::pi() / 180.)); } +inline double g_sindeg(double v) { return sin(v * (pi::pi() / 180.)); } +inline double g_cos(double v) { return cos(v); } +inline double g_sin(double v) { return sin(v); } +inline double g_sqrt(double v) { return sqrt(v); } +inline double g_atan2(double v, double w) { return atan2(v, w); } #endif diff --git a/source/core/music/s_advsound.cpp b/source/core/music/s_advsound.cpp index 3ee731f02ca..b125580ad22 100644 --- a/source/core/music/s_advsound.cpp +++ b/source/core/music/s_advsound.cpp @@ -42,6 +42,8 @@ #include "s_music.h" #include "sc_man.h" #include "s_soundinternal.h" +#include "i_music.h" + #include "gamecontrol.h" #include @@ -232,7 +234,14 @@ static void S_AddSNDINFO (int lump) case SI_MusicVolume: { sc.MustGetString(); FName musname (sc.String); - sc.MustGetFloat(); + if (!sc.CheckFloat()) + { + sc.MustGetString(); + char* p; + double f = strtod(sc.String, &p); + if (!stricmp(p, "db")) sc.Float = dBToAmplitude((float)sc.Float); + else sc.ScriptError("Bad value for music volume: %s", sc.String); + } MusicVolumes[musname] = (float)sc.Float; } break;