Backend update from GZDoom.

This commit is contained in:
Christoph Oelckers 2023-12-26 22:14:14 +01:00
parent 5b4aa573b1
commit 6c79e35c25
11 changed files with 683 additions and 68 deletions

View file

@ -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<GainAnalyzer>();
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;

View file

@ -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

View file

@ -21,7 +21,7 @@
#include "alc.h"
#endif
#include "alext.h"
#include "thirdparty/alext.h"
class OpenALSoundStream;

View file

@ -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 <stddef.h>
/* Define int64_t and uint64_t types */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(_WIN32) && defined(__GNUC__)
/* Define int64 and uint64 types */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
(defined(__cplusplus) && __cplusplus >= 201103L)
#include <stdint.h>
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 <inttypes.h>
#include <stdint.h>
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

View file

@ -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;
}

View file

@ -192,6 +192,7 @@ public:
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 @@ protected:
bool StateOptions;
bool Escape;
VersionInfo ParseVersion = { 0, 0, 0 }; // no ZScript extensions by default
FString PrependMessage = "";
bool ScanValue(bool allowfloat, bool evaluate);

View file

@ -89,7 +89,8 @@ public:
if (own)
{
length = len;
memory = allocate(len);
memory = malloc(len);
owned = true;
if (memory_) memcpy(memory, memory_, len);
}
else

View file

@ -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)
{

View file

@ -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);

View file

@ -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

View file

@ -42,6 +42,8 @@
#include "s_music.h"
#include "sc_man.h"
#include "s_soundinternal.h"
#include "i_music.h"
#include "gamecontrol.h"
#include <zmusic.h>
@ -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;