Fixed openmohaa.exe compilation (only 102 linker errors)

This commit is contained in:
L 2023-05-07 21:28:54 +02:00
parent 7030c23994
commit 72f090b289
29 changed files with 5413 additions and 2738 deletions

View file

@ -216,31 +216,41 @@ if (WITH_CLIENT)
INSTALL(TARGETS cgame DESTINATION "${TARGET_BASE_GAME}")
### Executable
# file(GLOB_RECURSE SOURCES_CLIENT "code/client/*.c" "code/client/*.cpp")
# set(SOURCES_CLIENT_APP ${SOURCES_APP} ${SOURCES_SERVER} ${SOURCES_CLIENT})
#
# add_executable(openmohaa ${SOURCES_CLIENT_APP} ${SOURCES_PLATFORM_SPECIFIC})
# target_compile_definitions(openmohaa PRIVATE NO_SCRIPTENGINE APP_MODULE TARGET_GAME_TYPE=${TARGET_GAME_TYPE})
# target_compile_features(openmohaa PUBLIC cxx_nullptr)
# target_compile_features(openmohaa PUBLIC c_variadic_macros)
# # Gamespy dependency
# add_dependencies(openmohaa gcd)
# target_link_libraries(openmohaa PRIVATE gcd)
# target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/SDL2/include")
# set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa{TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
#
# if(WIN32)
# if (MSVC)
# target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
# endif()
# target_link_libraries(openmohaa PRIVATE wsock32 ws2_32)
# target_link_libraries(openmohaa PRIVATE winmm)
# elseif(UNIX)
# find_package(Threads)
# target_link_libraries(openmohaa PRIVATE ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
# target_link_libraries(openmohaa PRIVATE m)
# target_link_libraries(openmohaa PRIVATE stdc++)
# endif()
#
# INSTALL(TARGETS openmohaa DESTINATION "./")
file(GLOB_RECURSE SOURCES_CLIENT "code/client/*.c" "code/client/*.cpp")
file(GLOB_RECURSE SOURCES_UILIB "code/uilib/*.c" "code/uilib/*.cpp")
file(GLOB_RECURSE SOURCES_LIBS "code/sdl/*.c")
set(SOURCES_CLIENT_APP ${SOURCES_APP} ${SOURCES_SERVER} ${SOURCES_CLIENT} ${SOURCES_UILIB} ${SOURCES_LIBS})
add_executable(openmohaa ${SOURCES_CLIENT_APP} ${SOURCES_PLATFORM_SPECIFIC})
target_compile_definitions(openmohaa PRIVATE NO_SCRIPTENGINE APP_MODULE TARGET_GAME_TYPE=${TARGET_GAME_TYPE})
target_compile_features(openmohaa PUBLIC cxx_nullptr)
target_compile_features(openmohaa PUBLIC c_variadic_macros)
# Gamespy dependency
add_dependencies(openmohaa gcd)
target_link_libraries(openmohaa PRIVATE gcd)
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/SDL2/include")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}${TARGET_CONFIG_SUFFIX}")
if(WIN32)
if (MSVC)
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
add_library(sdl2 SHARED IMPORTED)
set_target_properties(sdl2 PROPERTIES
IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/code/libs/win32/SDL2.lib"
)
target_link_libraries(openmohaa PRIVATE sdl2)
endif()
target_link_libraries(openmohaa PRIVATE wsock32 ws2_32)
target_link_libraries(openmohaa PRIVATE winmm)
elseif(UNIX)
find_package(Threads)
target_link_libraries(openmohaa PRIVATE ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(openmohaa PRIVATE m)
target_link_libraries(openmohaa PRIVATE stdc++)
endif()
INSTALL(TARGETS openmohaa DESTINATION "./")
endif()

View file

@ -255,6 +255,8 @@ typedef struct {
qboolean secondaryColorAvailable;
qboolean VAR;
qboolean fence;
// ioq3
int numTextureUnits;
} glconfig_t;
#if !defined _WIN32

View file

@ -519,7 +519,7 @@ CL_StartLocalSound
====================
*/
void CL_StartLocalSound(const char* soundName, qboolean forceLoad) {
S_StartLocalSound(soundName, qfalse );
S_StartLocalSoundByName(soundName, qfalse );
}
/*
@ -606,8 +606,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->S_StartLocalSound = CL_StartLocalSound;
cgi->S_StopSound = S_StopSound;
cgi->S_AddLoopingSound = S_AddLoopingSound;
cgi->S_ClearLoopingSounds = S_ClearLoopingSounds;
cgi->S_Respatialize = S_Respatialize;
cgi->S_ClearLoopingSounds = S_ClearLoopingSoundsNoParam;
cgi->S_Respatialize = S_RespatializeOld;
cgi->S_BeginRegistration = S_BeginRegistration;
cgi->S_EndRegistration = S_EndRegistration;
cgi->S_UpdateEntity = S_UpdateEntity;

View file

@ -3660,7 +3660,7 @@ sfxHandle_t UI_RegisterSound( const char *sample, qboolean streamed ) {
}
void UI_StartLocalSound( const char *sound_name ) {
S_StartLocalSound( sound_name, qtrue );
S_StartLocalSoundByName( sound_name, qtrue );
}
/*

View file

@ -246,6 +246,9 @@ typedef struct {
// big stuff at end of structure so most offsets are 15 bits or less
netchan_t netchan;
float aviVideoFrameRemainder;
float aviSoundFrameRemainder;
} clientConnection_t;
extern clientConnection_t clc;
@ -422,6 +425,17 @@ extern cvar_t *cl_consoleKeys;
extern cvar_t *cg_gametype;
extern cvar_t* j_pitch;
extern cvar_t* j_yaw;
extern cvar_t* j_forward;
extern cvar_t* j_side;
extern cvar_t* j_up;
extern cvar_t* j_pitch_axis;
extern cvar_t* j_yaw_axis;
extern cvar_t* j_forward_axis;
extern cvar_t* j_side_axis;
extern cvar_t* j_up_axis;
//=================================================
//

View file

@ -260,6 +260,43 @@ typedef enum {
K_EURO,
K_UNDO,
// Gamepad controls
// Ordered to match SDL2 game controller buttons and axes
// Do not change this order without also changing IN_GamepadMove() in SDL_input.c
K_PAD0_A,
K_PAD0_B,
K_PAD0_X,
K_PAD0_Y,
K_PAD0_BACK,
K_PAD0_GUIDE,
K_PAD0_START,
K_PAD0_LEFTSTICK_CLICK,
K_PAD0_RIGHTSTICK_CLICK,
K_PAD0_LEFTSHOULDER,
K_PAD0_RIGHTSHOULDER,
K_PAD0_DPAD_UP,
K_PAD0_DPAD_DOWN,
K_PAD0_DPAD_LEFT,
K_PAD0_DPAD_RIGHT,
K_PAD0_LEFTSTICK_LEFT,
K_PAD0_LEFTSTICK_RIGHT,
K_PAD0_LEFTSTICK_UP,
K_PAD0_LEFTSTICK_DOWN,
K_PAD0_RIGHTSTICK_LEFT,
K_PAD0_RIGHTSTICK_RIGHT,
K_PAD0_RIGHTSTICK_UP,
K_PAD0_RIGHTSTICK_DOWN,
K_PAD0_LEFTTRIGGER,
K_PAD0_RIGHTTRIGGER,
K_PAD0_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */
K_PAD0_PADDLE1, /* Xbox Elite paddle P1 */
K_PAD0_PADDLE2, /* Xbox Elite paddle P3 */
K_PAD0_PADDLE3, /* Xbox Elite paddle P2 */
K_PAD0_PADDLE4, /* Xbox Elite paddle P4 */
K_PAD0_TOUCHPAD, /* PS4/PS5 touchpad button */
// Pseudo-key that brings the console down
K_CONSOLE,

View file

@ -37,8 +37,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../AL/al.h"
#include "../AL/alc.h"
#else
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__APPLE__)
// MSVC users must install the OpenAL SDK which doesn't use the AL/*.h scheme.
// OSX framework also needs this
#include <al.h>
#include <alc.h>
#else

View file

@ -2,12 +2,12 @@
Copyright 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Netherlands.
All Rights Reserved
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior permission.
@ -25,7 +25,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/*
** Intel/DVI ADPCM coder/decoder.
**
** The algorithm for this coder was taken from the IMA Compatability Project
** The algorithm for this coder was taken from the IMA Compatibility Project
** proceedings, Vol 2, Number 2; May 1992.
**
** Version 1.2, 18-Dec-92.
@ -35,55 +35,55 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Intel ADPCM step variation table */
static int indexTable[ 16 ] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8,
static int indexTable[16] = {
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8,
};
static int stepsizeTable[ 89 ] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
static int stepsizeTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
void S_AdpcmEncode( short indata[], char outdata[], int len, struct adpcm_state *state ) {
short *inp; /* Input buffer pointer */
signed char *outp; /* output buffer pointer */
int val; /* Current input sample value */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int diff; /* Difference between val and sample */
int step; /* Stepsize */
int valpred; /* Predicted output value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int outputbuffer; /* place to keep previous 4-bit value */
int bufferstep; /* toggle between outputbuffer/output */
short *inp; /* Input buffer pointer */
signed char *outp; /* output buffer pointer */
int val; /* Current input sample value */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int diff; /* Difference between val and sample */
int step; /* Stepsize */
int valpred; /* Predicted output value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int outputbuffer; /* place to keep previous 4-bit value */
int bufferstep; /* toggle between outputbuffer/output */
outp = ( signed char * )outdata;
inp = indata;
valpred = state->sample;
index = state->index;
step = stepsizeTable[ index ];
outp = (signed char *)outdata;
inp = indata;
valpred = state->sample;
index = state->index;
step = stepsizeTable[index];
outputbuffer = 0; // quiet a compiler warning
bufferstep = 1;
bufferstep = 1;
for( ; len > 0; len-- ) {
for ( ; len > 0 ; len-- ) {
val = *inp++;
/* Step 1 - compute difference with previous value */
diff = val - valpred;
sign = ( diff < 0 ) ? 8 : 0;
if( sign ) diff = ( -diff );
sign = (diff < 0) ? 8 : 0;
if ( sign ) diff = (-diff);
/* Step 2 - Divide and clamp */
/* Note:
@ -95,101 +95,99 @@ void S_AdpcmEncode( short indata[], char outdata[], int len, struct adpcm_state
** good use since the fixup would be too expensive.
*/
delta = 0;
vpdiff = ( step >> 3 );
if( diff >= step ) {
vpdiff = (step >> 3);
if ( diff >= step ) {
delta = 4;
diff -= step;
vpdiff += step;
}
step >>= 1;
if( diff >= step ) {
if ( diff >= step ) {
delta |= 2;
diff -= step;
vpdiff += step;
}
step >>= 1;
if( diff >= step ) {
if ( diff >= step ) {
delta |= 1;
vpdiff += step;
}
/* Step 3 - Update previous value */
if( sign )
valpred -= vpdiff;
if ( sign )
valpred -= vpdiff;
else
valpred += vpdiff;
valpred += vpdiff;
/* Step 4 - Clamp previous value to 16 bits */
if( valpred > 32767 )
valpred = 32767;
else if( valpred < -32768 )
valpred = -32768;
if ( valpred > 32767 )
valpred = 32767;
else if ( valpred < -32768 )
valpred = -32768;
/* Step 5 - Assemble value, update index and step values */
delta |= sign;
index += indexTable[ delta ];
if( index < 0 ) index = 0;
if( index > 88 ) index = 88;
step = stepsizeTable[ index ];
index += indexTable[delta];
if ( index < 0 ) index = 0;
if ( index > 88 ) index = 88;
step = stepsizeTable[index];
/* Step 6 - Output value */
if( bufferstep ) {
outputbuffer = ( delta << 4 ) & 0xf0;
}
else {
*outp++ = ( delta & 0x0f ) | outputbuffer;
if ( bufferstep ) {
outputbuffer = (delta << 4) & 0xf0;
} else {
*outp++ = (delta & 0x0f) | outputbuffer;
}
bufferstep = !bufferstep;
}
}
/* Output last step, if needed */
if( !bufferstep )
*outp++ = outputbuffer;
state->sample = valpred;
state->index = index;
/* Output last step, if needed */
if ( !bufferstep )
*outp++ = outputbuffer;
state->sample = valpred;
state->index = index;
}
/* static */ void S_AdpcmDecode( const char indata[], short *outdata, int len, struct adpcm_state *state ) {
signed char *inp; /* Input buffer pointer */
int outp; /* output buffer pointer */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int step; /* Stepsize */
int valpred; /* Predicted value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int inputbuffer; /* place to keep next 4-bit value */
int bufferstep; /* toggle between inputbuffer/input */
signed char *inp; /* Input buffer pointer */
int outp; /* output buffer pointer */
int sign; /* Current adpcm sign bit */
int delta; /* Current adpcm output value */
int step; /* Stepsize */
int valpred; /* Predicted value */
int vpdiff; /* Current change to valpred */
int index; /* Current step change index */
int inputbuffer; /* place to keep next 4-bit value */
int bufferstep; /* toggle between inputbuffer/input */
outp = 0;
inp = ( signed char * )indata;
outp = 0;
inp = (signed char *)indata;
valpred = state->sample;
index = state->index;
step = stepsizeTable[ index ];
bufferstep = 0;
inputbuffer = 0; // quiet a compiler warning
for( ; len > 0; len-- ) {
valpred = state->sample;
index = state->index;
step = stepsizeTable[index];
bufferstep = 0;
inputbuffer = 0; // quiet a compiler warning
for ( ; len > 0 ; len-- ) {
/* Step 1 - get the delta value */
if( bufferstep ) {
if ( bufferstep ) {
delta = inputbuffer & 0xf;
}
else {
} else {
inputbuffer = *inp++;
delta = ( inputbuffer >> 4 ) & 0xf;
delta = (inputbuffer >> 4) & 0xf;
}
bufferstep = !bufferstep;
/* Step 2 - Find new index value (for later) */
index += indexTable[ delta ];
if( index < 0 ) index = 0;
if( index > 88 ) index = 88;
index += indexTable[delta];
if ( index < 0 ) index = 0;
if ( index > 88 ) index = 88;
/* Step 3 - Separate sign and magnitude */
sign = delta & 8;
@ -201,31 +199,31 @@ void S_AdpcmEncode( short indata[], char outdata[], int len, struct adpcm_state
** in adpcm_coder.
*/
vpdiff = step >> 3;
if( delta & 4 ) vpdiff += step;
if( delta & 2 ) vpdiff += step >> 1;
if( delta & 1 ) vpdiff += step >> 2;
if ( delta & 4 ) vpdiff += step;
if ( delta & 2 ) vpdiff += step>>1;
if ( delta & 1 ) vpdiff += step>>2;
if( sign )
valpred -= vpdiff;
if ( sign )
valpred -= vpdiff;
else
valpred += vpdiff;
valpred += vpdiff;
/* Step 5 - clamp output value */
if( valpred > 32767 )
valpred = 32767;
else if( valpred < -32768 )
valpred = -32768;
if ( valpred > 32767 )
valpred = 32767;
else if ( valpred < -32768 )
valpred = -32768;
/* Step 6 - Update step value */
step = stepsizeTable[ index ];
step = stepsizeTable[index];
/* Step 7 - Output value */
outdata[ outp ] = valpred;
outdata[outp] = valpred;
outp++;
}
}
state->sample = valpred;
state->index = index;
state->sample = valpred;
state->index = index;
}
@ -244,7 +242,7 @@ int S_AdpcmMemoryNeeded( const wavinfo_t *info ) {
int headerMemory;
// determine scale to convert from input sampling rate to desired sampling rate
scale = ( float )info->rate / dma.speed;
scale = (float)info->rate / dma.speed;
// calc number of samples at playback sampling rate
scaledSampleCount = info->samples / scale;
@ -259,7 +257,7 @@ int S_AdpcmMemoryNeeded( const wavinfo_t *info ) {
}
// calc memory needed to store the block headers
headerMemory = blockCount * sizeof( adpcm_state_t );
headerMemory = blockCount * sizeof(adpcm_state_t);
return sampleMemory + headerMemory;
}
@ -270,7 +268,7 @@ int S_AdpcmMemoryNeeded( const wavinfo_t *info ) {
S_AdpcmGetSamples
====================
*/
void S_AdpcmGetSamples( sndBuffer *chunk, short *to ) {
void S_AdpcmGetSamples(sndBuffer *chunk, short *to) {
adpcm_state_t state;
byte *out;
@ -278,9 +276,9 @@ void S_AdpcmGetSamples( sndBuffer *chunk, short *to ) {
state.index = chunk->adpcm.index;
state.sample = chunk->adpcm.sample;
out = ( byte * )chunk->sndChunk;
out = (byte *)chunk->sndChunk;
// get samples
S_AdpcmDecode( ( char * )out, to, SND_CHUNK_SIZE_BYTE * 2, &state );
S_AdpcmDecode((char *) out, to, SND_CHUNK_SIZE_BYTE*2, &state );
}
@ -300,32 +298,31 @@ void S_AdpcmEncodeSound( sfx_t *sfx, short *samples ) {
inOffset = 0;
count = sfx->soundLength;
state.index = 0;
state.sample = samples[ 0 ];
state.sample = samples[0];
chunk = NULL;
while( count ) {
n = count;
if( n > SND_CHUNK_SIZE_BYTE * 2 ) {
n = SND_CHUNK_SIZE_BYTE * 2;
if( n > SND_CHUNK_SIZE_BYTE*2 ) {
n = SND_CHUNK_SIZE_BYTE*2;
}
newchunk = SND_malloc();
if( sfx->soundData == NULL ) {
if (sfx->soundData == NULL) {
sfx->soundData = newchunk;
}
else if( chunk != NULL ) {
} else if (chunk != NULL) {
chunk->next = newchunk;
}
chunk = newchunk;
// output the header
chunk->adpcm.index = state.index;
chunk->adpcm.index = state.index;
chunk->adpcm.sample = state.sample;
out = ( byte * )chunk->sndChunk;
out = (byte *)chunk->sndChunk;
// encode the samples
S_AdpcmEncode( samples + inOffset, ( char * )out, n, &state );
S_AdpcmEncode( samples + inOffset, (char *) out, n, &state );
inOffset += n;
count -= n;

229
code/client/snd_altivec.c Normal file
View file

@ -0,0 +1,229 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
/* This file is only compiled for PowerPC builds with Altivec support.
Altivec intrinsics need to be in a separate file, so GCC's -maltivec
command line can enable them, but give us the option to _not_ use that
on other files, where the compiler might then generate Altivec
instructions for normal floating point, crashing on G3 (etc) processors. */
#include "client.h"
#include "snd_local.h"
#if idppc_altivec
#if !defined(__APPLE__)
#include <altivec.h>
#endif
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata[2], fdiv, fleftvol, frightvol;
if (sc->soundChannels <= 0) {
return;
}
samp = &paintbuffer[ bufferOffset ];
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
if ( sc->soundChannels == 2 ) {
sampleOffset *= sc->soundChannels;
if ( sampleOffset & 1 ) {
sampleOffset &= ~1;
}
}
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if (!chunk) {
chunk = sc->soundData;
}
}
if (!ch->doppler || ch->dopplerScale==1.0f) {
vector signed short volume_vec;
vector unsigned int volume_shift;
int vectorCount, samplesLeft, chunkSamplesLeft;
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
((short *)&volume_vec)[0] = leftvol;
((short *)&volume_vec)[1] = leftvol;
((short *)&volume_vec)[4] = leftvol;
((short *)&volume_vec)[5] = leftvol;
((short *)&volume_vec)[2] = rightvol;
((short *)&volume_vec)[3] = rightvol;
((short *)&volume_vec)[6] = rightvol;
((short *)&volume_vec)[7] = rightvol;
volume_shift = vec_splat_u32(8);
i = 0;
while(i < count) {
/* Try to align destination to 16-byte boundary */
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
if ( sc->soundChannels == 2 ) {
data = samples[sampleOffset++];
}
samp[i].right += (data * rightvol)>>8;
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
i++;
}
/* Destination is now aligned. Process as many 8-sample
chunks as we can before we run out of room from the current
sound chunk. We do 8 per loop to avoid extra source data reads. */
samplesLeft = count - i;
chunkSamplesLeft = SND_CHUNK_SIZE - sampleOffset;
if(samplesLeft > chunkSamplesLeft)
samplesLeft = chunkSamplesLeft;
vectorCount = samplesLeft / 8;
if(vectorCount)
{
vector unsigned char tmp;
vector short s0, s1, sampleData0, sampleData1;
vector signed int merge0, merge1;
vector signed int d0, d1, d2, d3;
vector unsigned char samplePermute0 =
VECCONST_UINT8(0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7);
vector unsigned char samplePermute1 =
VECCONST_UINT8(8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15);
vector unsigned char loadPermute0, loadPermute1;
// Rather than permute the vectors after we load them to do the sample
// replication and rearrangement, we permute the alignment vector so
// we do everything in one step below and avoid data shuffling.
tmp = vec_lvsl(0,&samples[sampleOffset]);
loadPermute0 = vec_perm(tmp,tmp,samplePermute0);
loadPermute1 = vec_perm(tmp,tmp,samplePermute1);
s0 = *(vector short *)&samples[sampleOffset];
while(vectorCount)
{
/* Load up source (16-bit) sample data */
s1 = *(vector short *)&samples[sampleOffset+7];
/* Load up destination sample data */
d0 = *(vector signed int *)&samp[i];
d1 = *(vector signed int *)&samp[i+2];
d2 = *(vector signed int *)&samp[i+4];
d3 = *(vector signed int *)&samp[i+6];
sampleData0 = vec_perm(s0,s1,loadPermute0);
sampleData1 = vec_perm(s0,s1,loadPermute1);
merge0 = vec_mule(sampleData0,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData0,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d0 = vec_add(merge0,d0);
d1 = vec_add(merge1,d1);
merge0 = vec_mule(sampleData1,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData1,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d2 = vec_add(merge0,d2);
d3 = vec_add(merge1,d3);
/* Store destination sample data */
*(vector signed int *)&samp[i] = d0;
*(vector signed int *)&samp[i+2] = d1;
*(vector signed int *)&samp[i+4] = d2;
*(vector signed int *)&samp[i+6] = d3;
i += 8;
vectorCount--;
s0 = s1;
sampleOffset += 8;
}
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
}
}
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
fdata[0] = fdata[1] = 0;
for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
if ( sc->soundChannels == 2 ) {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
} else {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
}
}
fdiv = 256 * (boff-aoff) / sc->soundChannels;
samp[i].left += (fdata[0] * fleftvol)/fdiv;
samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}
#endif

View file

@ -28,71 +28,90 @@ static snd_codec_t *codecs;
/*
=================
S_FileExtension
S_CodecGetSound
Opens/loads a sound, tries codec based on the sound's file extension
then tries all supported codecs.
=================
*/
static char *S_FileExtension(const char *fni)
static void *S_CodecGetSound(const char *filename, snd_info_t *info)
{
// we should search from the ending to the last '/'
snd_codec_t *codec;
snd_codec_t *orgCodec = NULL;
qboolean orgNameFailed = qfalse;
char localName[ MAX_QPATH ];
const char *ext;
char altName[ MAX_QPATH ];
void *rtn = NULL;
char *fn = (char *) fni + strlen(fni) - 1;
char *eptr = NULL;
Q_strncpyz(localName, filename, MAX_QPATH);
while(*fn != '/' && fn != fni)
ext = COM_GetExtension(localName);
if( *ext )
{
if(*fn == '.')
// Look for the correct loader and use it
for( codec = codecs; codec; codec = codec->next )
{
eptr = fn;
break;
}
fn--;
}
return eptr;
}
/*
=================
S_FindCodecForFile
Select an appropriate codec for a file based on its extension
=================
*/
static snd_codec_t *S_FindCodecForFile(const char *filename)
{
char *ext = S_FileExtension(filename);
snd_codec_t *codec = codecs;
if(!ext)
{
// No extension - auto-detect
while(codec)
{
char fn[MAX_QPATH];
// there is no extension so we do not need to subtract 4 chars
Q_strncpyz(fn, filename, MAX_QPATH);
COM_DefaultExtension(fn, MAX_QPATH, codec->ext);
// Check it exists
if( FS_ReadFile( fn, NULL ) != -1 )
return codec;
// Nope. Next!
codec = codec->next;
if( !Q_stricmp( ext, codec->ext ) )
{
// Load
if( info )
rtn = codec->load(localName, info);
else
rtn = codec->open(localName);
break;
}
}
// Nothin'
return NULL;
// A loader was found
if( codec )
{
if( !rtn )
{
// Loader failed, most likely because the file isn't there;
// try again without the extension
orgNameFailed = qtrue;
orgCodec = codec;
COM_StripExtension( filename, localName, MAX_QPATH );
}
else
{
// Something loaded
return rtn;
}
}
}
while(codec)
// Try and find a suitable match using all
// the sound codecs supported
for( codec = codecs; codec; codec = codec->next )
{
if(!Q_stricmp(ext, codec->ext))
return codec;
codec = codec->next;
if( codec == orgCodec )
continue;
Com_sprintf( altName, sizeof (altName), "%s.%s", localName, codec->ext );
// Load
if( info )
rtn = codec->load(altName, info);
else
rtn = codec->open(altName);
if( rtn )
{
if( orgNameFailed )
{
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s not present, using %s instead\n",
filename, altName );
}
return rtn;
}
}
Com_Printf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);
return NULL;
}
@ -104,13 +123,17 @@ S_CodecInit
void S_CodecInit()
{
codecs = NULL;
S_CodecRegister(&wav_codec);
#ifdef USE_CODEC_OPUS
S_CodecRegister(&opus_codec);
#endif
#ifdef USE_CODEC_VORBIS
S_CodecRegister(&ogg_codec);
#endif
#if USE_CODEC_MP3
S_CodecRegister(&mp3_codec);
#endif
// Register wav codec last so that it is always tried first when a file extension was not found
S_CodecRegister(&wav_codec);
}
/*
@ -141,20 +164,7 @@ S_CodecLoad
*/
void *S_CodecLoad(const char *filename, snd_info_t *info)
{
snd_codec_t *codec;
char fn[MAX_QPATH];
codec = S_FindCodecForFile(filename);
if(!codec)
{
Com_Printf("Unknown extension for %s\n", filename);
return NULL;
}
strncpy(fn, filename, sizeof(fn));
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
return codec->load(fn, info);
return S_CodecGetSound(filename, info);
}
/*
@ -164,20 +174,7 @@ S_CodecOpenStream
*/
snd_stream_t *S_CodecOpenStream(const char *filename)
{
snd_codec_t *codec;
char fn[MAX_QPATH];
codec = S_FindCodecForFile(filename);
if(!codec)
{
Com_Printf("Unknown extension for %s\n", filename);
return NULL;
}
strncpy(fn, filename, sizeof(fn));
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
return codec->open(fn);
return S_CodecGetSound(filename, NULL);
}
void S_CodecCloseStream(snd_stream_t *stream)
@ -208,7 +205,7 @@ snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec)
length = FS_FOpenFileRead(filename, &hnd, qtrue, qtrue);
if(!hnd)
{
Com_Printf("Can't read sound file %s\n", filename);
Com_DPrintf("Can't read sound file %s\n", filename);
return NULL;
}

View file

@ -27,10 +27,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct snd_info_s
{
int rate;
@ -99,17 +95,13 @@ void S_OGG_CodecCloseStream(snd_stream_t *stream);
int S_OGG_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif // USE_CODEC_VORBIS
#if USE_CODEC_MP3
// MP3 codec
extern snd_codec_t mp3_codec;
void *S_MP3_CodecLoad(const char *filename, snd_info_t *info);
snd_stream_t *S_MP3_CodecOpenStream(const char *filename);
void S_MP3_CodecCloseStream(snd_stream_t *stream);
int S_MP3_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif
#ifdef __cplusplus
}
#endif
// Ogg Opus codec
#ifdef USE_CODEC_OPUS
extern snd_codec_t opus_codec;
void *S_OggOpus_CodecLoad(const char *filename, snd_info_t *info);
snd_stream_t *S_OggOpus_CodecOpenStream(const char *filename);
void S_OggOpus_CodecCloseStream(snd_stream_t *stream);
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif // USE_CODEC_OPUS
#endif // !_SND_CODEC_H_

View file

@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// includes for the OGG codec
#include <errno.h>
#define OV_EXCLUDE_STATIC_CALLBACKS
#include <vorbis/vorbisfile.h>
// The OGG codec can return the samples in a number of different formats,
@ -40,7 +41,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// Q3 OGG codec
snd_codec_t ogg_codec =
{
".ogg",
"ogg",
S_OGG_CodecLoad,
S_OGG_CodecOpenStream,
S_OGG_CodecReadStream,
@ -128,7 +129,7 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence)
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_SET);
// something has gone wrong, so we return here
if(!(retVal == 0))
if(retVal < 0)
{
return retVal;
}
@ -144,7 +145,7 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence)
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_CUR);
// something has gone wrong, so we return here
if(!(retVal == 0))
if(retVal < 0)
{
return retVal;
}
@ -156,14 +157,11 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence)
case SEEK_END :
{
// Quake 3 seems to have trouble with FS_SEEK_END
// so we use the file length and FS_SEEK_SET
// set the file position in the actual file with the Q3 function
retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET);
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END);
// something has gone wrong, so we return here
if(!(retVal == 0))
if(retVal < 0)
{
return retVal;
}
@ -198,15 +196,19 @@ int S_OGG_Callback_close(void *datasource)
// ftell() replacement
long S_OGG_Callback_tell(void *datasource)
{
snd_stream_t *stream;
// check if input is valid
if(!datasource)
{
errno = EBADF;
errno = EBADF;
return -1;
}
// we keep track of the file position in stream->pos
return (long) (((snd_stream_t *) datasource) -> pos);
// snd_stream_t in the generic pointer
stream = (snd_stream_t *) datasource;
return (long) FS_FTell(stream->file);
}
// the callback structure
@ -445,8 +447,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info)
// allocate a buffer
// this buffer must be free-ed by the caller of this function
// buffer = Z_Malloc(info->size);
buffer = Hunk_AllocateTempMemory(info->size);
buffer = Hunk_AllocateTempMemory(info->size);
if(!buffer)
{
S_OGG_CodecCloseStream(stream);
@ -460,7 +461,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info)
// we don't even have read a single byte
if(bytesRead <= 0)
{
Z_Free(buffer);
Hunk_FreeTempMemory(buffer);
S_OGG_CodecCloseStream(stream);
return NULL;

View file

@ -0,0 +1,449 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
Copyright (C) 2005 Stuart Dalton (badcdev@gmail.com)
Copyright (C) 2005-2006 Joerg Dietrich <dietrich_joerg@gmx.de>
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// Ogg Opus support is enabled by this define
#ifdef USE_CODEC_OPUS
// includes for the Q3 sound system
#include "client.h"
#include "snd_codec.h"
// includes for the Ogg Opus codec
#include <errno.h>
#include <opusfile.h>
// samples are 16 bit
#define OPUS_SAMPLEWIDTH 2
// Q3 Ogg Opus codec
snd_codec_t opus_codec =
{
"opus",
S_OggOpus_CodecLoad,
S_OggOpus_CodecOpenStream,
S_OggOpus_CodecReadStream,
S_OggOpus_CodecCloseStream,
NULL
};
// callbacks for opusfile
// fread() replacement
int S_OggOpus_Callback_read(void *datasource, unsigned char *ptr, int size )
{
snd_stream_t *stream;
int bytesRead = 0;
// check if input is valid
if(!ptr)
{
errno = EFAULT;
return -1;
}
if(!size)
{
// It's not an error, caller just wants zero bytes!
errno = 0;
return 0;
}
if (size < 0)
{
errno = EINVAL;
return -1;
}
if(!datasource)
{
errno = EBADF;
return -1;
}
// we use a snd_stream_t in the generic pointer to pass around
stream = (snd_stream_t *) datasource;
// read it with the Q3 function FS_Read()
bytesRead = FS_Read(ptr, size, stream->file);
// update the file position
stream->pos += bytesRead;
return bytesRead;
}
// fseek() replacement
int S_OggOpus_Callback_seek(void *datasource, opus_int64 offset, int whence)
{
snd_stream_t *stream;
int retVal = 0;
// check if input is valid
if(!datasource)
{
errno = EBADF;
return -1;
}
// snd_stream_t in the generic pointer
stream = (snd_stream_t *) datasource;
// we must map the whence to its Q3 counterpart
switch(whence)
{
case SEEK_SET :
{
// set the file position in the actual file with the Q3 function
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_SET);
// something has gone wrong, so we return here
if(retVal < 0)
{
return retVal;
}
// keep track of file position
stream->pos = (int) offset;
break;
}
case SEEK_CUR :
{
// set the file position in the actual file with the Q3 function
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_CUR);
// something has gone wrong, so we return here
if(retVal < 0)
{
return retVal;
}
// keep track of file position
stream->pos += (int) offset;
break;
}
case SEEK_END :
{
// set the file position in the actual file with the Q3 function
retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END);
// something has gone wrong, so we return here
if(retVal < 0)
{
return retVal;
}
// keep track of file position
stream->pos = stream->length + (int) offset;
break;
}
default :
{
// unknown whence, so we return an error
errno = EINVAL;
return -1;
}
}
// stream->pos shouldn't be smaller than zero or bigger than the filesize
stream->pos = (stream->pos < 0) ? 0 : stream->pos;
stream->pos = (stream->pos > stream->length) ? stream->length : stream->pos;
return 0;
}
// fclose() replacement
int S_OggOpus_Callback_close(void *datasource)
{
// we do nothing here and close all things manually in S_OggOpus_CodecCloseStream()
return 0;
}
// ftell() replacement
opus_int64 S_OggOpus_Callback_tell(void *datasource)
{
snd_stream_t *stream;
// check if input is valid
if(!datasource)
{
errno = EBADF;
return -1;
}
// snd_stream_t in the generic pointer
stream = (snd_stream_t *) datasource;
return (opus_int64) FS_FTell(stream->file);
}
// the callback structure
const OpusFileCallbacks S_OggOpus_Callbacks =
{
&S_OggOpus_Callback_read,
&S_OggOpus_Callback_seek,
&S_OggOpus_Callback_tell,
&S_OggOpus_Callback_close
};
/*
=================
S_OggOpus_CodecOpenStream
=================
*/
snd_stream_t *S_OggOpus_CodecOpenStream(const char *filename)
{
snd_stream_t *stream;
// Opus codec control structure
OggOpusFile *of;
// some variables used to get informations about the file
const OpusHead *opusInfo;
ogg_int64_t numSamples;
// check if input is valid
if(!filename)
{
return NULL;
}
// Open the stream
stream = S_CodecUtilOpen(filename, &opus_codec);
if(!stream)
{
return NULL;
}
// open the codec with our callbacks and stream as the generic pointer
of = op_open_callbacks(stream, &S_OggOpus_Callbacks, NULL, 0, NULL );
if (!of)
{
S_CodecUtilClose(&stream);
return NULL;
}
// the stream must be seekable
if(!op_seekable(of))
{
op_free(of);
S_CodecUtilClose(&stream);
return NULL;
}
// get the info about channels and rate
opusInfo = op_head(of, -1);
if(!opusInfo)
{
op_free(of);
S_CodecUtilClose(&stream);
return NULL;
}
if(opusInfo->stream_count != 1)
{
op_free(of);
S_CodecUtilClose(&stream);
Com_Printf("Only Ogg Opus files with one stream are support\n");
return NULL;
}
if(opusInfo->channel_count != 1 && opusInfo->channel_count != 2)
{
op_free(of);
S_CodecUtilClose(&stream);
Com_Printf("Only mono and stereo Ogg Opus files are supported\n");
return NULL;
}
// get the number of sample-frames in the file
numSamples = op_pcm_total(of, -1);
// fill in the info-structure in the stream
stream->info.rate = 48000;
stream->info.width = OPUS_SAMPLEWIDTH;
stream->info.channels = opusInfo->channel_count;
stream->info.samples = numSamples;
stream->info.size = stream->info.samples * stream->info.channels * stream->info.width;
stream->info.dataofs = 0;
// We use stream->pos for the file pointer in the compressed ogg file
stream->pos = 0;
// We use the generic pointer in stream for the opus codec control structure
stream->ptr = of;
return stream;
}
/*
=================
S_OggOpus_CodecCloseStream
=================
*/
void S_OggOpus_CodecCloseStream(snd_stream_t *stream)
{
// check if input is valid
if(!stream)
{
return;
}
// let the opus codec cleanup its stuff
op_free((OggOpusFile *) stream->ptr);
// close the stream
S_CodecUtilClose(&stream);
}
/*
=================
S_OggOpus_CodecReadStream
=================
*/
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer)
{
// buffer handling
int samplesRead, samplesLeft, c;
opus_int16 *bufPtr;
// check if input is valid
if(!(stream && buffer))
{
return 0;
}
if(bytes <= 0)
{
return 0;
}
samplesRead = 0;
samplesLeft = bytes / stream->info.channels / stream->info.width;
bufPtr = buffer;
if(samplesLeft <= 0)
{
return 0;
}
// cycle until we have the requested or all available bytes read
while(-1)
{
// read some samples from the opus codec
c = op_read((OggOpusFile *) stream->ptr, bufPtr + samplesRead * stream->info.channels, samplesLeft * stream->info.channels, NULL);
// no more samples are left
if(c <= 0)
{
break;
}
samplesRead += c;
samplesLeft -= c;
// we have enough samples
if(samplesLeft <= 0)
{
break;
}
}
return samplesRead * stream->info.channels * stream->info.width;
}
/*
=====================================================================
S_OggOpus_CodecLoad
We handle S_OggOpus_CodecLoad as a special case of the streaming functions
where we read the whole stream at once.
======================================================================
*/
void *S_OggOpus_CodecLoad(const char *filename, snd_info_t *info)
{
snd_stream_t *stream;
byte *buffer;
int bytesRead;
// check if input is valid
if(!(filename && info))
{
return NULL;
}
// open the file as a stream
stream = S_OggOpus_CodecOpenStream(filename);
if(!stream)
{
return NULL;
}
// copy over the info
info->rate = stream->info.rate;
info->width = stream->info.width;
info->channels = stream->info.channels;
info->samples = stream->info.samples;
info->size = stream->info.size;
info->dataofs = stream->info.dataofs;
// allocate a buffer
// this buffer must be free-ed by the caller of this function
buffer = Hunk_AllocateTempMemory(info->size);
if(!buffer)
{
S_OggOpus_CodecCloseStream(stream);
return NULL;
}
// fill the buffer
bytesRead = S_OggOpus_CodecReadStream(stream, info->size, buffer);
// we don't even have read a single byte
if(bytesRead <= 0)
{
Hunk_FreeTempMemory(buffer);
S_OggOpus_CodecCloseStream(stream);
return NULL;
}
S_OggOpus_CodecCloseStream(stream);
return buffer;
}
#endif // USE_CODEC_OPUS

View file

@ -131,7 +131,6 @@ S_ReadRIFFHeader
static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
{
char dump[16];
int wav_format;
int bits;
int fmtlen = 0;
@ -146,7 +145,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
}
// Save the parameters
wav_format = FGetLittleShort(file);
FGetLittleShort(file); // wav_format
info->channels = FGetLittleShort(file);
info->rate = FGetLittleLong(file);
FGetLittleLong(file);
@ -183,7 +182,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
// WAV codec
snd_codec_t wav_codec =
{
".wav",
"wav",
S_WAV_CodecLoad,
S_WAV_CodecOpenStream,
S_WAV_CodecReadStream,
@ -205,8 +204,6 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info)
FS_FOpenFileRead(filename, &file, qtrue, qtrue);
if(!file)
{
Com_Printf( S_COLOR_RED "ERROR: Could not open \"%s\"\n",
filename);
return NULL;
}
@ -220,9 +217,7 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info)
}
// Allocate some memory
// buffer = Z_Malloc(info->size);
buffer = Hunk_AllocateTempMemory(info->size);
if(!buffer)
{
FS_FCloseFile(file);

File diff suppressed because it is too large Load diff

View file

@ -26,18 +26,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "snd_public.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PAINTBUFFER_SIZE 4096 // this is in samples
#define SND_CHUNK_SIZE 1024 // samples
#define SND_CHUNK_SIZE_FLOAT (SND_CHUNK_SIZE/2) // floats
#define SND_CHUNK_SIZE_BYTE (SND_CHUNK_SIZE*2) // floats
#define SFX_FLAG_STREAMED 4
typedef struct {
int left; // the final values will be clamped to +/- 0x00ffff00 and shifted down
int right;
@ -55,15 +49,6 @@ typedef struct sndBuffer_s {
adpcm_state_t adpcm;
} sndBuffer;
typedef struct {
int channels;
int samples; // mono samples in buffer
int submission_chunk; // don't mix less than this #
int samplebits;
int speed;
byte *buffer;
} dma_t;
typedef struct sfx_s {
sndBuffer *soundData;
qboolean defaultSound; // couldn't be loaded, so use buzz
@ -71,73 +56,22 @@ typedef struct sfx_s {
qboolean soundCompressed; // not in Memory
int soundCompressionMethod;
int soundLength;
int soundChannels;
int soundChannels;
char soundName[MAX_QPATH];
int lastTimeUsed;
int iFlags;
struct sfx_s *next;
} sfx_t;
typedef struct {
char name[ MAX_QPATH ];
int loop_start;
int loop_end;
int max_number_playing;
float max_factor;
} sfx_info_t;
typedef struct {
vec3_t position;
vec3_t velocity;
int time;
qboolean use_listener;
} s_entity_t;
typedef struct {
char alias[ 32 ];
char path[ MAX_QPATH ];
int mood_num;
int flags;
float volume;
float fadetime;
int current_pos;
int current_state;
} song_t;
typedef struct {
int iFlags;
char szName[ MAX_QPATH ];
} sfxsavegame_t;
typedef struct channelbasesavegame_s {
qboolean bPlaying;
int iStatus;
sfxsavegame_t sfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iNextCheckObstructionTime;
int iEndTime;
int iFlags;
int iOffset;
int iLoopCount;
} channelbasesavegame_t;
typedef struct soundsystemsavegame_s {
channelbasesavegame_t Channels[ 96 ];
} soundsystemsavegame_t;
int channels;
int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this #
int samplebits;
int isfloat;
int speed;
byte *buffer;
} dma_t;
#define START_SAMPLE_IMMEDIATE 0x7fffffff
@ -158,7 +92,8 @@ typedef struct loopSound_s {
int framenum;
} loopSound_t;
typedef struct channel_s {
typedef struct
{
int allocTime;
int startSample; // START_SAMPLE_IMMEDIATE = set immediately on next mix
int entnum; // to allow overriding a specific sound
@ -188,20 +123,11 @@ typedef struct {
int dataofs; // chunk starts this many bytes from file start
} wavinfo_t;
typedef struct {
float volume;
float minDist;
float pitch;
float maxDist;
qboolean streamed;
int flags;
} sndparm_t;
// Interface between Q3 sound "api" and the sound backend
typedef struct
{
void (*Shutdown)(void);
void (*StartSound)( const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx );
void (*StartSound)(const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx );
void (*StartLocalSound)( sfxHandle_t sfx, int channelNum );
void (*StartBackgroundTrack)( const char *intro, const char *loop );
void (*StopBackgroundTrack)( void );
@ -212,12 +138,11 @@ typedef struct
void (*AddRealLoopingSound)( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx );
void (*StopLoopingSound)(int entityNum );
void (*Respatialize)( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater );
void (*UpdateEntity)( int entityNum, const vec3_t origin, const vec3_t velocity );
void (*UpdateEntityPosition)( int entityNum, const vec3_t origin );
void (*Update)( void );
void (*DisableSounds)( void );
void (*BeginRegistration)( void );
sfxHandle_t (*RegisterSound)( const char *sample, qboolean compressed );
qboolean (*IsSoundPlaying)( int channelNumber, const char *name );
void (*ClearSoundBuffer)( void );
void (*SoundInfo)( void );
void (*SoundList)( void );
@ -252,6 +177,15 @@ void SNDDMA_BeginPainting (void);
void SNDDMA_Submit(void);
#ifdef USE_VOIP
void SNDDMA_StartCapture(void);
int SNDDMA_AvailableCaptureSamples(void);
void SNDDMA_Capture(int samples, byte *data);
void SNDDMA_StopCapture(void);
void SNDDMA_MasterGain(float val);
#endif
//====================================================================
#define MAX_SOUNDCHANNELS 96
@ -278,26 +212,24 @@ extern cvar_t *s_doppler;
extern cvar_t *s_testsound;
extern sndparm_t soundparm;
qboolean S_LoadSound( sfx_t *sfx );
void SND_free( sndBuffer *v );
void SND_free(sndBuffer *v);
sndBuffer* SND_malloc( void );
void SND_setup( void );
void SND_shutdown( void );
void SND_shutdown(void);
void S_PaintChannels( int endtime );
void S_PaintChannels(int endtime);
void S_memoryLoad( sfx_t *sfx );
void S_memoryLoad(sfx_t *sfx);
// spatializes a channel
void S_Spatialize( channel_t *ch );
void S_Spatialize(channel_t *ch);
// adpcm functions
int S_AdpcmMemoryNeeded( const wavinfo_t *info );
void S_AdpcmEncodeSound( sfx_t *sfx, short *samples );
void S_AdpcmGetSamples( sndBuffer *chunk, short *to );
void S_AdpcmGetSamples(sndBuffer *chunk, short *to);
// wavelet function
@ -308,11 +240,11 @@ void S_FreeOldestSound( void );
#define NXStream byte
void encodeWavelet( sfx_t *sfx, short *packets );
void decodeWavelet( sndBuffer *stream, short *packets );
void encodeWavelet(sfx_t *sfx, short *packets);
void decodeWavelet( sndBuffer *stream, short *packets);
void encodeMuLaw( sfx_t *sfx, short *packets );
extern short mulawToShort[ 256 ];
void encodeMuLaw( sfx_t *sfx, short *packets);
extern short mulawToShort[256];
extern short *sfxScratchBuffer;
extern sfx_t *sfxScratchPointer;
@ -332,9 +264,8 @@ typedef enum
typedef int srcHandle_t;
void callbackServer( int entnum, int channel_number, const char *name );
qboolean S_AL_Init( soundInterface_t *si );
#ifdef __cplusplus
}
#ifdef idppc_altivec
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset );
#endif

File diff suppressed because it is too large Load diff

View file

@ -21,13 +21,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*****************************************************************************
* name: snd_mem.c
*
* desc: sound caching
*
* $Archive: /MissionPack/code/client/snd_mem.c $
*
*****************************************************************************/
* name: snd_mem.c
*
* desc: sound caching
*
* $Archive: /MissionPack/code/client/snd_mem.c $
*
*****************************************************************************/
#include "snd_local.h"
#include "snd_codec.h"
@ -51,59 +51,59 @@ short *sfxScratchBuffer = NULL;
sfx_t *sfxScratchPointer = NULL;
int sfxScratchIndex = 0;
void SND_free( sndBuffer *v ) {
*( sndBuffer ** )v = freelist;
freelist = ( sndBuffer* )v;
inUse += sizeof( sndBuffer );
void SND_free(sndBuffer *v) {
*(sndBuffer **)v = freelist;
freelist = (sndBuffer*)v;
inUse += sizeof(sndBuffer);
}
sndBuffer* SND_malloc( void ) {
sndBuffer* SND_malloc(void) {
sndBuffer *v;
redo:
if( freelist == NULL ) {
if (freelist == NULL) {
S_FreeOldestSound();
goto redo;
}
inUse -= sizeof( sndBuffer );
totalInUse += sizeof( sndBuffer );
inUse -= sizeof(sndBuffer);
totalInUse += sizeof(sndBuffer);
v = freelist;
freelist = *( sndBuffer ** )freelist;
freelist = *(sndBuffer **)freelist;
v->next = NULL;
return v;
}
void SND_setup( void ) {
void SND_setup(void) {
sndBuffer *p, *q;
cvar_t *cv;
int scs;
cv = Cvar_Get( "com_soundMegs", DEF_COMSOUNDMEGS, CVAR_LATCH | CVAR_ARCHIVE );
scs = ( cv->integer * 1536 );
scs = (cv->integer*1536);
buffer = malloc( scs*sizeof( sndBuffer ) );
buffer = malloc(scs*sizeof(sndBuffer) );
// allocate the stack based hunk allocator
sfxScratchBuffer = malloc( SND_CHUNK_SIZE * sizeof( short ) * 4 ); //Hunk_Alloc(SND_CHUNK_SIZE * sizeof(short) * 4);
sfxScratchBuffer = malloc(SND_CHUNK_SIZE * sizeof(short) * 4); //Hunk_Alloc(SND_CHUNK_SIZE * sizeof(short) * 4);
sfxScratchPointer = NULL;
inUse = scs*sizeof( sndBuffer );
inUse = scs*sizeof(sndBuffer);
p = buffer;;
q = p + scs;
while( --q > p )
*( sndBuffer ** )q = q - 1;
*( sndBuffer ** )q = NULL;
while (--q > p)
*(sndBuffer **)q = q-1;
*(sndBuffer **)q = NULL;
freelist = p + scs - 1;
Com_Printf( "Sound memory manager started\n" );
Com_Printf("Sound memory manager started\n");
}
void SND_shutdown( void )
void SND_shutdown(void)
{
free( sfxScratchBuffer );
free( buffer );
free(sfxScratchBuffer);
free(buffer);
}
/*
@ -121,41 +121,41 @@ static int ResampleSfx( sfx_t *sfx, int channels, int inrate, int inwidth, int s
int sample, samplefrac, fracstep;
int part;
sndBuffer *chunk;
stepscale = ( float )inrate / dma.speed; // this is usually 0.5, 1, or 2
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
outcount = samples / stepscale;
srcsample = 0;
samplefrac = 0;
fracstep = stepscale * 256 * channels;
chunk = sfx->soundData;
for( i = 0; i<outcount; i++ )
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 8;
srcsample += samplefrac >> 8;
samplefrac &= 255;
samplefrac += fracstep;
for( j = 0; j<channels; j++ )
for (j=0 ; j<channels ; j++)
{
if( inwidth == 2 ) {
sample = ( ( ( short * )data )[ srcsample + j ] );
sample = ( ((short *)data)[srcsample+j] );
} else {
sample = (unsigned int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
}
else {
sample = ( int )( ( unsigned char )( data[ srcsample + j ] ) - 128 ) << 8;
}
part = ( i*channels + j )&( SND_CHUNK_SIZE - 1 );
if( part == 0 ) {
part = (i*channels+j)&(SND_CHUNK_SIZE-1);
if (part == 0) {
sndBuffer *newchunk;
newchunk = SND_malloc();
if( chunk == NULL ) {
if (chunk == NULL) {
sfx->soundData = newchunk;
}
else {
} else {
chunk->next = newchunk;
}
chunk = newchunk;
}
chunk->sndChunk[ part ] = sample;
chunk->sndChunk[part] = sample;
}
}
@ -175,27 +175,28 @@ static int ResampleSfxRaw( short *sfx, int channels, int inrate, int inwidth, in
float stepscale;
int i, j;
int sample, samplefrac, fracstep;
stepscale = ( float )inrate / dma.speed; // this is usually 0.5, 1, or 2
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
outcount = samples / stepscale;
srcsample = 0;
samplefrac = 0;
fracstep = stepscale * 256 * channels;
for( i = 0; i<outcount; i++ )
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 8;
srcsample += samplefrac >> 8;
samplefrac &= 255;
samplefrac += fracstep;
for( j = 0; j<channels; j++ )
for (j=0 ; j<channels ; j++)
{
if( inwidth == 2 ) {
sample = LittleShort( ( ( short * )data )[ srcsample + j ] );
sample = LittleShort ( ((short *)data)[srcsample+j] );
} else {
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
}
else {
sample = ( int )( ( unsigned char )( data[ srcsample + j ] ) - 128 ) << 8;
}
sfx[ i*channels + j ] = sample;
sfx[i*channels+j] = sample;
}
}
return outcount;
@ -216,24 +217,24 @@ qboolean S_LoadSound( sfx_t *sfx )
byte *data;
short *samples;
snd_info_t info;
// int size;
// int size;
// load it in
data = S_CodecLoad( sfx->soundName, &info );
if( !data )
data = S_CodecLoad(sfx->soundName, &info);
if(!data)
return qfalse;
if( info.width == 1 ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: %s is a 8 bit audio file\n", sfx->soundName );
if ( info.width == 1 ) {
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit audio file\n", sfx->soundName);
}
if( info.rate != 22050 ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName );
if ( info.rate != 22050 ) {
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
}
samples = Hunk_AllocateTempMemory( info.channels * info.samples * sizeof( short ) * 2 );
samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2);
sfx->lastTimeUsed = Com_Milliseconds() + 1;
sfx->lastTimeUsed = Com_Milliseconds()+1;
// each of these compression schemes works just fine
// but the 16bit quality is much nicer and with a local
@ -241,40 +242,37 @@ qboolean S_LoadSound( sfx_t *sfx )
// manager to do the right thing for us and page
// sound in as needed
if( info.channels == 1 && sfx->soundCompressed == qtrue ) {
if( info.channels == 1 && sfx->soundCompressed == qtrue) {
sfx->soundCompressionMethod = 1;
sfx->soundData = NULL;
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs );
S_AdpcmEncodeSound( sfx, samples );
S_AdpcmEncodeSound(sfx, samples);
#if 0
}
else if( info.channels == 1 && info.samples>( SND_CHUNK_SIZE * 16 ) && info.width >1 ) {
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
sfx->soundCompressionMethod = 3;
sfx->soundData = NULL;
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, ( data + info.dataofs ) );
encodeMuLaw( sfx, samples );
}
else if( info.channels == 1 && info.samples>( SND_CHUNK_SIZE * 6400 ) && info.width >1 ) {
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
encodeMuLaw( sfx, samples);
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
sfx->soundCompressionMethod = 2;
sfx->soundData = NULL;
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, ( data + info.dataofs ) );
encodeWavelet( sfx, samples );
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
encodeWavelet( sfx, samples);
#endif
}
else {
} else {
sfx->soundCompressionMethod = 0;
sfx->soundData = NULL;
sfx->soundLength = ResampleSfx( sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse );
}
sfx->soundChannels = info.channels;
Hunk_FreeTempMemory( samples );
Hunk_FreeTempMemory( data );
Hunk_FreeTempMemory(samples);
Hunk_FreeTempMemory(data);
return qtrue;
}
void S_DisplayFreeMemory( void ) {
Com_Printf( "%d bytes free sound buffer memory, %d total used\n", inUse, totalInUse );
void S_DisplayFreeMemory(void) {
Com_Printf("%d bytes free sound buffer memory, %d total used\n", inUse, totalInUse);
}

View file

@ -23,123 +23,120 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "client.h"
#include "snd_local.h"
#if idppc_altivec && !defined(MACOS_X)
#include <altivec.h>
#endif
static portable_samplepair_t paintbuffer[ PAINTBUFFER_SIZE ];
static portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
static int snd_vol;
int* snd_p;
int* snd_p;
int snd_linear_count;
short* snd_out;
#if !id386 // if configured not to use asm
void S_WriteLinearBlastStereo16( void )
void S_WriteLinearBlastStereo16 (void)
{
int i;
int val;
for( i = 0; i<snd_linear_count; i += 2 )
for (i=0 ; i<snd_linear_count ; i+=2)
{
val = snd_p[ i ] >> 8;
if( val > 0x7fff )
snd_out[ i ] = 0x7fff;
else if( val < -32768 )
snd_out[ i ] = -32768;
val = snd_p[i]>>8;
if (val > 0x7fff)
snd_out[i] = 0x7fff;
else if (val < -32768)
snd_out[i] = -32768;
else
snd_out[ i ] = val;
snd_out[i] = val;
val = snd_p[ i + 1 ] >> 8;
if( val > 0x7fff )
snd_out[ i + 1 ] = 0x7fff;
else if( val < -32768 )
snd_out[ i + 1 ] = -32768;
val = snd_p[i+1]>>8;
if (val > 0x7fff)
snd_out[i+1] = 0x7fff;
else if (val < -32768)
snd_out[i+1] = -32768;
else
snd_out[ i + 1 ] = val;
snd_out[i+1] = val;
}
}
#elif defined(__GNUC__)
// uses snd_mixa.s
void S_WriteLinearBlastStereo16( void );
void S_WriteLinearBlastStereo16 (void);
#else
__declspec( naked ) void S_WriteLinearBlastStereo16( void )
__declspec( naked ) void S_WriteLinearBlastStereo16 (void)
{
__asm {
push edi
push ebx
mov ecx, ds:dword ptr[ snd_linear_count ]
mov ebx, ds : dword ptr[ snd_p ]
mov edi, ds : dword ptr[ snd_out ]
LWLBLoopTop :
mov eax, ds : dword ptr[ -8 + ebx + ecx * 4 ]
sar eax, 8
cmp eax, 07FFFh
jg LClampHigh
cmp eax, 0FFFF8000h
jnl LClampDone
mov eax, 0FFFF8000h
jmp LClampDone
LClampHigh :
mov eax, 07FFFh
LClampDone :
mov edx, ds : dword ptr[ -4 + ebx + ecx * 4 ]
sar edx, 8
cmp edx, 07FFFh
jg LClampHigh2
cmp edx, 0FFFF8000h
jnl LClampDone2
mov edx, 0FFFF8000h
jmp LClampDone2
LClampHigh2 :
mov edx, 07FFFh
LClampDone2 :
shl edx, 16
and eax, 0FFFFh
or edx, eax
mov ds : dword ptr[ -4 + edi + ecx * 2 ], edx
sub ecx, 2
jnz LWLBLoopTop
pop ebx
pop edi
ret
push edi
push ebx
mov ecx,ds:dword ptr[snd_linear_count]
mov ebx,ds:dword ptr[snd_p]
mov edi,ds:dword ptr[snd_out]
LWLBLoopTop:
mov eax,ds:dword ptr[-8+ebx+ecx*4]
sar eax,8
cmp eax,07FFFh
jg LClampHigh
cmp eax,0FFFF8000h
jnl LClampDone
mov eax,0FFFF8000h
jmp LClampDone
LClampHigh:
mov eax,07FFFh
LClampDone:
mov edx,ds:dword ptr[-4+ebx+ecx*4]
sar edx,8
cmp edx,07FFFh
jg LClampHigh2
cmp edx,0FFFF8000h
jnl LClampDone2
mov edx,0FFFF8000h
jmp LClampDone2
LClampHigh2:
mov edx,07FFFh
LClampDone2:
shl edx,16
and eax,0FFFFh
or edx,eax
mov ds:dword ptr[-4+edi+ecx*2],edx
sub ecx,2
jnz LWLBLoopTop
pop ebx
pop edi
ret
}
}
#endif
void S_TransferStereo16( unsigned long *pbuf, int endtime )
void S_TransferStereo16 (unsigned long *pbuf, int endtime)
{
int lpos;
int ls_paintedtime;
snd_p = ( int * )paintbuffer;
snd_p = (int *) paintbuffer;
ls_paintedtime = s_paintedtime;
while( ls_paintedtime < endtime )
while (ls_paintedtime < endtime)
{
// handle recirculating buffer issues
lpos = ls_paintedtime & ( ( dma.samples >> 1 ) - 1 );
// handle recirculating buffer issues
lpos = ls_paintedtime % dma.fullsamples;
snd_out = ( short * )pbuf + ( lpos << 1 );
snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels
snd_linear_count = ( dma.samples >> 1 ) - lpos;
if( ls_paintedtime + snd_linear_count > endtime )
snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime;
snd_linear_count <<= 1;
snd_linear_count <<= 1; // snd_linear_count *= dma.channels
// write a linear blast of samples
S_WriteLinearBlastStereo16();
// write a linear blast of samples
S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count;
ls_paintedtime += ( snd_linear_count >> 1 );
ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels
if( CL_VideoRecording() )
CL_WriteAVIAudioFrame( ( byte * )snd_out, snd_linear_count << 1 );
if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
}
}
@ -149,69 +146,102 @@ S_TransferPaintBuffer
===================
*/
void S_TransferPaintBuffer( int endtime )
void S_TransferPaintBuffer(int endtime)
{
int out_idx;
int count;
int out_mask;
int *p;
int step;
int val;
int i;
unsigned long *pbuf;
pbuf = ( unsigned long * )dma.buffer;
pbuf = (unsigned long *)dma.buffer;
if( s_testsound->integer ) {
int i;
if ( s_testsound->integer ) {
// write a fixed sine wave
count = ( endtime - s_paintedtime );
for( i = 0; i<count; i++ )
paintbuffer[ i ].left = paintbuffer[ i ].right = sin( ( s_paintedtime + i )*0.1 ) * 20000 * 256;
count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++)
paintbuffer[i].left = paintbuffer[i].right = sin((s_paintedtime+i)*0.1)*20000*256;
}
if( dma.samplebits == 16 && dma.channels == 2 )
if (dma.samplebits == 16 && dma.channels == 2)
{ // optimized case
S_TransferStereo16( pbuf, endtime );
S_TransferStereo16 (pbuf, endtime);
}
else
{ // general case
p = ( int * )paintbuffer;
count = ( endtime - s_paintedtime ) * dma.channels;
out_mask = dma.samples - 1;
out_idx = s_paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels;
out_idx = ((unsigned int)s_paintedtime * dma.channels) % dma.samples;
step = 3 - MIN(dma.channels, 2);
if( dma.samplebits == 16 )
if ((dma.isfloat) && (dma.samplebits == 32))
{
short *out = ( short * )pbuf;
while( count-- )
float *out = (float *) pbuf;
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p += step;
if( val > 0x7fff )
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if( val < -32768 )
val = -32768;
out[ out_idx ] = val;
out_idx = ( out_idx + 1 ) & out_mask;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767;
out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if( dma.samplebits == 8 )
else if (dma.samplebits == 16)
{
unsigned char *out = ( unsigned char * )pbuf;
while( count-- )
short *out = (short *) pbuf;
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p += step;
if( val > 0x7fff )
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if( val < -32768 )
else if (val < -32768)
val = -32768;
out[ out_idx ] = ( val >> 8 ) + 128;
out_idx = ( out_idx + 1 ) & out_mask;
out[out_idx] = val;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 8)
{
unsigned char *out = (unsigned char *) pbuf;
for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) % dma.samples;
}
}
}
@ -226,199 +256,6 @@ CHANNEL MIXING
===============================================================================
*/
#if idppc_altivec
static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata[ 2 ], fdiv, fleftvol, frightvol;
if( sc->soundChannels <= 0 ) {
return;
}
samp = &paintbuffer[ bufferOffset ];
if( ch->doppler ) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
if( sc->soundChannels == 2 ) {
sampleOffset *= sc->soundChannels;
if( sampleOffset & 1 ) {
sampleOffset &= ~1;
}
}
chunk = sc->soundData;
while( sampleOffset >= SND_CHUNK_SIZE ) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if( !chunk ) {
chunk = sc->soundData;
}
}
if( !ch->doppler || ch->dopplerScale == 1.0f ) {
vector signed short volume_vec;
vector unsigned int volume_shift;
int vectorCount, samplesLeft, chunkSamplesLeft;
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
( ( short * )&volume_vec )[ 0 ] = leftvol;
( ( short * )&volume_vec )[ 1 ] = leftvol;
( ( short * )&volume_vec )[ 4 ] = leftvol;
( ( short * )&volume_vec )[ 5 ] = leftvol;
( ( short * )&volume_vec )[ 2 ] = rightvol;
( ( short * )&volume_vec )[ 3 ] = rightvol;
( ( short * )&volume_vec )[ 6 ] = rightvol;
( ( short * )&volume_vec )[ 7 ] = rightvol;
volume_shift = vec_splat_u32( 8 );
i = 0;
while( i < count ) {
/* Try to align destination to 16-byte boundary */
while( i < count && ( ( ( unsigned long )&samp[ i ] & 0x1f ) || ( ( count - i ) < 8 ) || ( ( SND_CHUNK_SIZE - sampleOffset ) < 8 ) ) ) {
data = samples[ sampleOffset++ ];
samp[ i ].left += ( data * leftvol ) >> 8;
if( sc->soundChannels == 2 ) {
data = samples[ sampleOffset++ ];
}
samp[ i ].right += ( data * rightvol ) >> 8;
if( sampleOffset == SND_CHUNK_SIZE ) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
i++;
}
/* Destination is now aligned. Process as many 8-sample
chunks as we can before we run out of room from the current
sound chunk. We do 8 per loop to avoid extra source data reads. */
samplesLeft = count - i;
chunkSamplesLeft = SND_CHUNK_SIZE - sampleOffset;
if( samplesLeft > chunkSamplesLeft )
samplesLeft = chunkSamplesLeft;
vectorCount = samplesLeft / 8;
if( vectorCount )
{
vector unsigned char tmp;
vector short s0, s1, sampleData0, sampleData1;
vector signed int merge0, merge1;
vector signed int d0, d1, d2, d3;
vector unsigned char samplePermute0 =
VECCONST_UINT8( 0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7 );
vector unsigned char samplePermute1 =
VECCONST_UINT8( 8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15 );
vector unsigned char loadPermute0, loadPermute1;
// Rather than permute the vectors after we load them to do the sample
// replication and rearrangement, we permute the alignment vector so
// we do everything in one step below and avoid data shuffling.
tmp = vec_lvsl( 0, &samples[ sampleOffset ] );
loadPermute0 = vec_perm( tmp, tmp, samplePermute0 );
loadPermute1 = vec_perm( tmp, tmp, samplePermute1 );
s0 = *( vector short * )&samples[ sampleOffset ];
while( vectorCount )
{
/* Load up source (16-bit) sample data */
s1 = *( vector short * )&samples[ sampleOffset + 7 ];
/* Load up destination sample data */
d0 = *( vector signed int * )&samp[ i ];
d1 = *( vector signed int * )&samp[ i + 2 ];
d2 = *( vector signed int * )&samp[ i + 4 ];
d3 = *( vector signed int * )&samp[ i + 6 ];
sampleData0 = vec_perm( s0, s1, loadPermute0 );
sampleData1 = vec_perm( s0, s1, loadPermute1 );
merge0 = vec_mule( sampleData0, volume_vec );
merge0 = vec_sra( merge0, volume_shift ); /* Shift down to proper range */
merge1 = vec_mulo( sampleData0, volume_vec );
merge1 = vec_sra( merge1, volume_shift );
d0 = vec_add( merge0, d0 );
d1 = vec_add( merge1, d1 );
merge0 = vec_mule( sampleData1, volume_vec );
merge0 = vec_sra( merge0, volume_shift ); /* Shift down to proper range */
merge1 = vec_mulo( sampleData1, volume_vec );
merge1 = vec_sra( merge1, volume_shift );
d2 = vec_add( merge0, d2 );
d3 = vec_add( merge1, d3 );
/* Store destination sample data */
*( vector signed int * )&samp[ i ] = d0;
*( vector signed int * )&samp[ i + 2 ] = d1;
*( vector signed int * )&samp[ i + 4 ] = d2;
*( vector signed int * )&samp[ i + 6 ] = d3;
i += 8;
vectorCount--;
s0 = s1;
sampleOffset += 8;
}
if( sampleOffset == SND_CHUNK_SIZE ) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
}
}
}
else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for( i = 0; i<count; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
fdata[ 0 ] = fdata[ 1 ] = 0;
for( j = aoff; j<boff; j += sc->soundChannels ) {
if( j == SND_CHUNK_SIZE ) {
chunk = chunk->next;
if( !chunk ) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
if( sc->soundChannels == 2 ) {
fdata[ 0 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
fdata[ 1 ] += samples[ ( j + 1 )&( SND_CHUNK_SIZE - 1 ) ];
}
else {
fdata[ 0 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
fdata[ 1 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
}
}
fdiv = 256 * ( boff - aoff ) / sc->soundChannels;
samp[ i ].left += ( fdata[ 0 ] * fleftvol ) / fdiv;
samp[ i ].right += ( fdata[ 1 ] * frightvol ) / fdiv;
}
}
}
#endif
static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
@ -426,101 +263,99 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata[ 2 ], fdiv, fleftvol, frightvol;
float ooff, fdata[2], fdiv, fleftvol, frightvol;
if( sc->soundChannels <= 0 ) {
if (sc->soundChannels <= 0) {
return;
}
samp = &paintbuffer[ bufferOffset ];
if( ch->doppler ) {
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
if( sc->soundChannels == 2 ) {
if ( sc->soundChannels == 2 ) {
sampleOffset *= sc->soundChannels;
if( sampleOffset & 1 ) {
if ( sampleOffset & 1 ) {
sampleOffset &= ~1;
}
}
chunk = sc->soundData;
while( sampleOffset >= SND_CHUNK_SIZE ) {
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if( !chunk ) {
if (!chunk) {
chunk = sc->soundData;
}
}
if( !ch->doppler || ch->dopplerScale == 1.0f ) {
if (!ch->doppler || ch->dopplerScale==1.0f) {
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
for( i = 0; i<count; i++ ) {
data = samples[ sampleOffset++ ];
samp[ i ].left += ( data * leftvol ) >> 8;
for ( i=0 ; i<count ; i++ ) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
if( sc->soundChannels == 2 ) {
data = samples[ sampleOffset++ ];
if ( sc->soundChannels == 2 ) {
data = samples[sampleOffset++];
}
samp[ i ].right += ( data * rightvol ) >> 8;
samp[i].right += (data * rightvol)>>8;
if( sampleOffset == SND_CHUNK_SIZE ) {
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
}
}
else {
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for( i = 0; i<count; i++ ) {
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
fdata[ 0 ] = fdata[ 1 ] = 0;
for( j = aoff; j<boff; j += sc->soundChannels ) {
if( j == SND_CHUNK_SIZE ) {
fdata[0] = fdata[1] = 0;
for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if( !chunk ) {
if (!chunk) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
if( sc->soundChannels == 2 ) {
fdata[ 0 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
fdata[ 1 ] += samples[ ( j + 1 )&( SND_CHUNK_SIZE - 1 ) ];
}
else {
fdata[ 0 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
fdata[ 1 ] += samples[ j&( SND_CHUNK_SIZE - 1 ) ];
if ( sc->soundChannels == 2 ) {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
} else {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
}
}
fdiv = 256 * ( boff - aoff ) / sc->soundChannels;
samp[ i ].left += ( fdata[ 0 ] * fleftvol ) / fdiv;
samp[ i ].right += ( fdata[ 1 ] * frightvol ) / fdiv;
fdiv = 256 * (boff-aoff) / sc->soundChannels;
samp[i].left += (fdata[0] * fleftvol)/fdiv;
samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}
static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
#if idppc_altivec
if( com_altivec->integer ) {
// must be in a seperate function or G3 systems will crash.
S_PaintChannelFrom16_altivec( ch, sc, count, sampleOffset, bufferOffset );
if (com_altivec->integer) {
// must be in a separate translation unit or G3 systems will crash.
S_PaintChannelFrom16_altivec( paintbuffer, snd_vol, ch, sc, count, sampleOffset, bufferOffset );
return;
}
#endif
@ -541,28 +376,28 @@ void S_PaintChannelFromWavelet( channel_t *ch, sfx_t *sc, int count, int sampleO
i = 0;
samp = &paintbuffer[ bufferOffset ];
chunk = sc->soundData;
while( sampleOffset >= ( SND_CHUNK_SIZE_FLOAT * 4 ) ) {
while (sampleOffset>=(SND_CHUNK_SIZE_FLOAT*4)) {
chunk = chunk->next;
sampleOffset -= ( SND_CHUNK_SIZE_FLOAT * 4 );
sampleOffset -= (SND_CHUNK_SIZE_FLOAT*4);
i++;
}
if( i != sfxScratchIndex || sfxScratchPointer != sc ) {
S_AdpcmGetSamples( chunk, sfxScratchBuffer );
if (i!=sfxScratchIndex || sfxScratchPointer != sc) {
decodeWavelet(chunk, sfxScratchBuffer);
sfxScratchIndex = i;
sfxScratchPointer = sc;
}
samples = sfxScratchBuffer;
for( i = 0; i<count; i++ ) {
data = samples[ sampleOffset++ ];
samp[ i ].left += ( data * leftvol ) >> 8;
samp[ i ].right += ( data * rightvol ) >> 8;
for ( i=0 ; i<count ; i++ ) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
samp[i].right += (data * rightvol)>>8;
if( sampleOffset == SND_CHUNK_SIZE * 2 ) {
if (sampleOffset == SND_CHUNK_SIZE*2) {
chunk = chunk->next;
decodeWavelet( chunk, sfxScratchBuffer );
decodeWavelet(chunk, sfxScratchBuffer);
sfxScratchIndex++;
sampleOffset = 0;
}
@ -584,17 +419,17 @@ void S_PaintChannelFromADPCM( channel_t *ch, sfx_t *sc, int count, int sampleOff
samp = &paintbuffer[ bufferOffset ];
chunk = sc->soundData;
if( ch->doppler ) {
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
while( sampleOffset >= ( SND_CHUNK_SIZE * 4 ) ) {
while (sampleOffset>=(SND_CHUNK_SIZE*4)) {
chunk = chunk->next;
sampleOffset -= ( SND_CHUNK_SIZE * 4 );
sampleOffset -= (SND_CHUNK_SIZE*4);
i++;
}
if( i != sfxScratchIndex || sfxScratchPointer != sc ) {
if (i!=sfxScratchIndex || sfxScratchPointer != sc) {
S_AdpcmGetSamples( chunk, sfxScratchBuffer );
sfxScratchIndex = i;
sfxScratchPointer = sc;
@ -602,14 +437,14 @@ void S_PaintChannelFromADPCM( channel_t *ch, sfx_t *sc, int count, int sampleOff
samples = sfxScratchBuffer;
for( i = 0; i<count; i++ ) {
data = samples[ sampleOffset++ ];
samp[ i ].left += ( data * leftvol ) >> 8;
samp[ i ].right += ( data * rightvol ) >> 8;
for ( i=0 ; i<count ; i++ ) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
samp[i].right += (data * rightvol)>>8;
if( sampleOffset == SND_CHUNK_SIZE * 4 ) {
if (sampleOffset == SND_CHUNK_SIZE*4) {
chunk = chunk->next;
S_AdpcmGetSamples( chunk, sfxScratchBuffer );
S_AdpcmGetSamples( chunk, sfxScratchBuffer);
sampleOffset = 0;
sfxScratchIndex++;
}
@ -630,41 +465,40 @@ void S_PaintChannelFromMuLaw( channel_t *ch, sfx_t *sc, int count, int sampleOff
samp = &paintbuffer[ bufferOffset ];
chunk = sc->soundData;
while( sampleOffset >= ( SND_CHUNK_SIZE * 2 ) ) {
while (sampleOffset>=(SND_CHUNK_SIZE*2)) {
chunk = chunk->next;
sampleOffset -= ( SND_CHUNK_SIZE * 2 );
if( !chunk ) {
sampleOffset -= (SND_CHUNK_SIZE*2);
if (!chunk) {
chunk = sc->soundData;
}
}
if( !ch->doppler ) {
samples = ( byte * )chunk->sndChunk + sampleOffset;
for( i = 0; i<count; i++ ) {
data = mulawToShort[ *samples ];
samp[ i ].left += ( data * leftvol ) >> 8;
samp[ i ].right += ( data * rightvol ) >> 8;
if (!ch->doppler) {
samples = (byte *)chunk->sndChunk + sampleOffset;
for ( i=0 ; i<count ; i++ ) {
data = mulawToShort[*samples];
samp[i].left += (data * leftvol)>>8;
samp[i].right += (data * rightvol)>>8;
samples++;
if( chunk != NULL && samples == ( byte * )chunk->sndChunk + ( SND_CHUNK_SIZE * 2 ) ) {
if (chunk != NULL && samples == (byte *)chunk->sndChunk+(SND_CHUNK_SIZE*2)) {
chunk = chunk->next;
samples = ( byte * )chunk->sndChunk;
samples = (byte *)chunk->sndChunk;
}
}
}
else {
} else {
ooff = sampleOffset;
samples = ( byte * )chunk->sndChunk;
for( i = 0; i<count; i++ ) {
data = mulawToShort[ samples[ ( int )( ooff ) ] ];
samples = (byte *)chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
data = mulawToShort[samples[(int)(ooff)]];
ooff = ooff + ch->dopplerScale;
samp[ i ].left += ( data * leftvol ) >> 8;
samp[ i ].right += ( data * rightvol ) >> 8;
if( ooff >= SND_CHUNK_SIZE * 2 ) {
samp[i].left += (data * leftvol)>>8;
samp[i].right += (data * rightvol)>>8;
if (ooff >= SND_CHUNK_SIZE*2) {
chunk = chunk->next;
if( !chunk ) {
if (!chunk) {
chunk = sc->soundData;
}
samples = ( byte * )chunk->sndChunk;
samples = (byte *)chunk->sndChunk;
ooff = 0.0;
}
}
@ -685,111 +519,105 @@ void S_PaintChannels( int endtime ) {
int ltime, count;
int sampleOffset;
if( s_muted->integer )
if(s_muted->integer)
snd_vol = 0;
else
snd_vol = s_volume->value * 255;
snd_vol = s_volume->value*255;
//Com_Printf ("%i to %i\n", s_paintedtime, endtime);
while( s_paintedtime < endtime ) {
//Com_Printf ("%i to %i\n", s_paintedtime, endtime);
while ( s_paintedtime < endtime ) {
// if paintbuffer is smaller than DMA buffer
// we may need to fill it multiple times
end = endtime;
if( endtime - s_paintedtime > PAINTBUFFER_SIZE ) {
if ( endtime - s_paintedtime > PAINTBUFFER_SIZE ) {
end = s_paintedtime + PAINTBUFFER_SIZE;
}
// clear the paint buffer and mix any raw samples...
Com_Memset( paintbuffer, 0, sizeof( paintbuffer ) );
for( stream = 0; stream < MAX_RAW_STREAMS; stream++ ) {
if( s_rawend[ stream ] >= s_paintedtime ) {
Com_Memset(paintbuffer, 0, sizeof (paintbuffer));
for (stream = 0; stream < MAX_RAW_STREAMS; stream++) {
if ( s_rawend[stream] >= s_paintedtime ) {
// copy from the streaming sound source
const portable_samplepair_t *rawsamples = s_rawsamples[ stream ];
const int stop = ( end < s_rawend[ stream ] ) ? end : s_rawend[ stream ];
for( i = s_paintedtime; i < stop; i++ ) {
const int s = i&( MAX_RAW_SAMPLES - 1 );
paintbuffer[ i - s_paintedtime ].left += rawsamples[ s ].left;
paintbuffer[ i - s_paintedtime ].right += rawsamples[ s ].right;
const portable_samplepair_t *rawsamples = s_rawsamples[stream];
const int stop = (end < s_rawend[stream]) ? end : s_rawend[stream];
for ( i = s_paintedtime ; i < stop ; i++ ) {
const int s = i&(MAX_RAW_SAMPLES-1);
paintbuffer[i-s_paintedtime].left += rawsamples[s].left;
paintbuffer[i-s_paintedtime].right += rawsamples[s].right;
}
}
}
// paint in the channels.
ch = s_channels;
for( i = 0; i < MAX_SOUNDCHANNELS; i++, ch++ ) {
if( !ch->thesfx || ( ch->leftvol<0.25 && ch->rightvol<0.25 ) ) {
for ( i = 0; i < MAX_SOUNDCHANNELS ; i++, ch++ ) {
if ( !ch->thesfx || (ch->leftvol<0.25 && ch->rightvol<0.25 )) {
continue;
}
ltime = s_paintedtime;
sc = ch->thesfx;
if( sc->soundData == NULL || sc->soundLength == 0 ) {
if (sc->soundData==NULL || sc->soundLength==0) {
continue;
}
sampleOffset = ltime - ch->startSample;
count = end - ltime;
if( sampleOffset + count > sc->soundLength ) {
if ( sampleOffset + count > sc->soundLength ) {
count = sc->soundLength - sampleOffset;
}
if( count > 0 ) {
if( sc->soundCompressionMethod == 1 ) {
S_PaintChannelFromADPCM( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else if( sc->soundCompressionMethod == 2 ) {
S_PaintChannelFromWavelet( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else if( sc->soundCompressionMethod == 3 ) {
S_PaintChannelFromMuLaw( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else {
S_PaintChannelFrom16( ch, sc, count, sampleOffset, ltime - s_paintedtime );
if ( count > 0 ) {
if( sc->soundCompressionMethod == 1) {
S_PaintChannelFromADPCM (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else if( sc->soundCompressionMethod == 2) {
S_PaintChannelFromWavelet (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else if( sc->soundCompressionMethod == 3) {
S_PaintChannelFromMuLaw (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else {
S_PaintChannelFrom16 (ch, sc, count, sampleOffset, ltime - s_paintedtime);
}
}
}
// paint in the looped channels.
ch = loop_channels;
for( i = 0; i < numLoopChannels; i++, ch++ ) {
if( !ch->thesfx || ( !ch->leftvol && !ch->rightvol ) ) {
for ( i = 0; i < numLoopChannels ; i++, ch++ ) {
if ( !ch->thesfx || (!ch->leftvol && !ch->rightvol )) {
continue;
}
ltime = s_paintedtime;
sc = ch->thesfx;
if( sc->soundData == NULL || sc->soundLength == 0 ) {
if (sc->soundData==NULL || sc->soundLength==0) {
continue;
}
// we might have to make two passes if it
// is a looping sound effect and the end of
// the sample is hit
do {
sampleOffset = ( ltime % sc->soundLength );
sampleOffset = (ltime % sc->soundLength);
count = end - ltime;
if( sampleOffset + count > sc->soundLength ) {
if ( sampleOffset + count > sc->soundLength ) {
count = sc->soundLength - sampleOffset;
}
if( count > 0 ) {
if( sc->soundCompressionMethod == 1 ) {
S_PaintChannelFromADPCM( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else if( sc->soundCompressionMethod == 2 ) {
S_PaintChannelFromWavelet( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else if( sc->soundCompressionMethod == 3 ) {
S_PaintChannelFromMuLaw( ch, sc, count, sampleOffset, ltime - s_paintedtime );
}
else {
S_PaintChannelFrom16( ch, sc, count, sampleOffset, ltime - s_paintedtime );
if ( count > 0 ) {
if( sc->soundCompressionMethod == 1) {
S_PaintChannelFromADPCM (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else if( sc->soundCompressionMethod == 2) {
S_PaintChannelFromWavelet (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else if( sc->soundCompressionMethod == 3) {
S_PaintChannelFromMuLaw (ch, sc, count, sampleOffset, ltime - s_paintedtime);
} else {
S_PaintChannelFrom16 (ch, sc, count, sampleOffset, ltime - s_paintedtime);
}
ltime += count;
}
} while( ltime < end );
} while ( ltime < end);
}
// transfer out according to DMA format

2734
code/client/snd_openal.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -15,79 +15,60 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef struct soundsystemsavegame_s soundsystemsavegame_t;
typedef struct channelbasesavegame_s channelbasesavegame_t;
typedef struct channel_s channel_t;
void S_Init( void );
void S_SaveData( soundsystemsavegame_t *pSave );
void S_LoadData( soundsystemsavegame_t *pSave );
void S_InitBase( channelbasesavegame_t *pBase );
void S_StoreBase( channelbasesavegame_t *pBase, channel_t *channel );
void S_Shutdown( void );
void S_FadeSound( float fTime );
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound( const vec3_t origin, int entNum, int entChannel, sfxHandle_t sfxHandle, float volume, float minDist, float pitch, float maxDist, qboolean streamed );
void S_StartLocalSound( const char *sound_name, qboolean force_load );
void S_StartSound(const vec3_t origin, int entNum, int entChannel, sfxHandle_t sfxHandle, float volume, float minDist, float pitch, float maxDist, int streamed);
void S_StopSound(int entnum, int channel);
void S_StartLocalSound(sfxHandle_t sfx, int channelNum);
void S_StartLocalSoundByName(const char* sound_name, qboolean force_load);
void S_StartBackgroundTrack( const char *intro, const char *loop );
void S_StopBackgroundTrack( void );
// cinematics and voice-over-network will send raw samples
// 1.0 volume will be direct output of source samples
void S_RawSamples( int stream, int samples, int rate, int width, int channels,
const byte *data, float volume, int entityNum );
void S_StopSound( int entNum, int channel );
void S_RawSamples(int stream, int samples, int rate, int width, int channels,
const byte *data, float volume, int entityNum);
// stop all sounds and the background track
void S_StopAllSounds( qboolean stop_music );
void S_StopAllSounds(qboolean stop_music);
// all continuous looping sounds must be added before calling S_Update
void S_ClearLoopingSounds( void );
void S_AddLoopingSound( const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx, float volume, float minDist, float maxDist, float pitch, int flags );
void S_ClearLoopingSoundsNoParam(void);
void S_ClearLoopingSounds( qboolean killall );
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags);
void S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx );
void S_StopLoopingSound( int entityNum );
void S_StopLoopingSound(int entityNum );
// recompute the reletive volumes for all running sounds
// reletive to the given entityNum / orientation
void S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[ 3 ] );
void S_RespatializeEx( int entityNum, const vec3_t origin, vec3_t axis[ 3 ], int inwater );
float S_GetSoundTime( sfxHandle_t handle );
void S_SetGlobalAmbientVolumeLevel( float volume );
void S_SetReverb( int reverb_type, float reverb_level );
int S_IsSoundPlaying( int channelNumber, const char *name );
// recompute the relative volumes for all running sounds
// relative to the given entityNum / orientation
void S_Respatialize(int entityNum, const vec3_t origin, vec3_t axis[3], int inwater);
// let the sound system know where an entity currently is
void S_UpdateEntity( int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener );
void S_UpdateEntityPosition(int entityNum, const vec3_t origin);
void S_Update( void );
void S_DisableSounds( void );
void S_BeginRegistration( void );
void S_EndRegistration( void );
qboolean S_IsSoundRegistered( const char *name );
void S_BeginRegistration(void);
void S_EndRegistration(void);
qboolean S_IsSoundRegistered(const char* name);
// RegisterSound will allways return a valid sample, even if it
// has to create a placeholder. This prevents continuous filesystem
// checks for missing files
sfxHandle_t S_RegisterSound( const char *sample, qboolean compressed, qboolean force_load );
sfxHandle_t S_RegisterSound(const char *sample, qboolean compressed, qboolean streamed);
void S_DisplayFreeMemory( void );
void S_DisplayFreeMemory(void);
void S_ClearSoundBuffer( void );
@ -99,24 +80,38 @@ void S_UpdateBackgroundTrack( void );
void MUSIC_Pause();
void MUSIC_Unpause();
qboolean MUSIC_LoadSoundtrackFile( const char *filename );
qboolean MUSIC_SongValid( const char *mood );
qboolean MUSIC_Loaded( void );
void Music_Update( void );
void MUSIC_SongEnded( void );
void MUSIC_NewSoundtrack( const char *name );
void MUSIC_UpdateMood( int current, int fallback );
void MUSIC_UpdateVolume( float volume, float fade_time );
void MUSIC_StopAllSongs( void );
void MUSIC_FreeAllSongs( void );
qboolean MUSIC_Playing( void );
int MUSIC_FindSong( const char *name );
int MUSIC_CurrentSongChannel( void );
void MUSIC_StopChannel( int channel_number );
qboolean MUSIC_PlaySong( const char *alias );
void MUSIC_UpdateMusicVolumes( void );
void MUSIC_CheckForStoppedSongs( void );
qboolean MUSIC_LoadSoundtrackFile(const char* filename);
qboolean MUSIC_SongValid(const char* mood);
qboolean MUSIC_Loaded(void);
void Music_Update(void);
void MUSIC_SongEnded(void);
void MUSIC_NewSoundtrack(const char* name);
void MUSIC_UpdateMood(int current, int fallback);
void MUSIC_UpdateVolume(float volume, float fade_time);
void MUSIC_StopAllSongs(void);
void MUSIC_FreeAllSongs(void);
qboolean MUSIC_Playing(void);
int MUSIC_FindSong(const char* name);
int MUSIC_CurrentSongChannel(void);
void MUSIC_StopChannel(int channel_number);
qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes(void);
void MUSIC_CheckForStoppedSongs(void);
float S_GetSoundTime(sfxHandle_t handle);
void S_SetGlobalAmbientVolumeLevel(float volume);
void S_SetReverb(int reverb_type, float reverb_level);
int S_IsSoundPlaying(int channelNumber, const char* name);
void S_RespatializeOld(int entityNum, const vec3_t origin, vec3_t axis[3]);
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
void S_FadeSound(float fTime);
#ifdef USE_VOIP
void S_StartCapture( void );
int S_AvailableCaptureSamples( void );
void S_Capture( int samples, byte *data );
void S_StopCapture( void );
void S_MasterGain( float gain );
#endif
#ifdef __cplusplus
}
#endif

View file

@ -27,143 +27,141 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define C2 0.2241438680420134
#define C3 -0.1294095225512604
void daub4( float b[], unsigned long n, int isign )
void daub4(float b[], unsigned long n, int isign)
{
float wksp[ 4097 ] = { 0.0f };
float *a = b - 1; // numerical recipies so a[1] = b[0]
float wksp[4097] = { 0.0f };
#define a(x) b[(x)-1] // numerical recipies so a[1] = b[0]
unsigned long nh, nh1, i, j;
unsigned long nh,nh1,i,j;
if( n < 4 ) return;
if (n < 4) return;
nh1 = ( nh = n >> 1 ) + 1;
if( isign >= 0 ) {
for( i = 1, j = 1; j <= n - 3; j += 2, i++ ) {
wksp[ i ] = C0*a[ j ] + C1*a[ j + 1 ] + C2*a[ j + 2 ] + C3*a[ j + 3 ];
wksp[ i + nh ] = C3*a[ j ] - C2*a[ j + 1 ] + C1*a[ j + 2 ] - C0*a[ j + 3 ];
nh1=(nh=n >> 1)+1;
if (isign >= 0) {
for (i=1,j=1;j<=n-3;j+=2,i++) {
wksp[i] = C0*a(j)+C1*a(j+1)+C2*a(j+2)+C3*a(j+3);
wksp[i+nh] = C3*a(j)-C2*a(j+1)+C1*a(j+2)-C0*a(j+3);
}
wksp[ i ] = C0*a[ n - 1 ] + C1*a[ n ] + C2*a[ 1 ] + C3*a[ 2 ];
wksp[ i + nh ] = C3*a[ n - 1 ] - C2*a[ n ] + C1*a[ 1 ] - C0*a[ 2 ];
}
else {
wksp[ 1 ] = C2*a[ nh ] + C1*a[ n ] + C0*a[ 1 ] + C3*a[ nh1 ];
wksp[ 2 ] = C3*a[ nh ] - C0*a[ n ] + C1*a[ 1 ] - C2*a[ nh1 ];
for( i = 1, j = 3; i<nh; i++ ) {
wksp[ j++ ] = C2*a[ i ] + C1*a[ i + nh ] + C0*a[ i + 1 ] + C3*a[ i + nh1 ];
wksp[ j++ ] = C3*a[ i ] - C0*a[ i + nh ] + C1*a[ i + 1 ] - C2*a[ i + nh1 ];
wksp[i ] = C0*a(n-1)+C1*a(n)+C2*a(1)+C3*a(2);
wksp[i+nh] = C3*a(n-1)-C2*a(n)+C1*a(1)-C0*a(2);
} else {
wksp[1] = C2*a(nh)+C1*a(n)+C0*a(1)+C3*a(nh1);
wksp[2] = C3*a(nh)-C0*a(n)+C1*a(1)-C2*a(nh1);
for (i=1,j=3;i<nh;i++) {
wksp[j++] = C2*a(i)+C1*a(i+nh)+C0*a(i+1)+C3*a(i+nh1);
wksp[j++] = C3*a(i)-C0*a(i+nh)+C1*a(i+1)-C2*a(i+nh1);
}
}
for( i = 1; i <= n; i++ ) {
a[ i ] = wksp[ i ];
for (i=1;i<=n;i++) {
a(i)=wksp[i];
}
#undef a
}
void wt1( float a[], unsigned long n, int isign )
void wt1(float a[], unsigned long n, int isign)
{
unsigned long nn;
int inverseStartLength = n / 4;
if( n < inverseStartLength ) return;
if( isign >= 0 ) {
for( nn = n; nn >= inverseStartLength; nn >>= 1 ) daub4( a, nn, isign );
}
else {
for( nn = inverseStartLength; nn <= n; nn <<= 1 ) daub4( a, nn, isign );
int inverseStartLength = n/4;
if (n < inverseStartLength) return;
if (isign >= 0) {
for (nn=n;nn>=inverseStartLength;nn>>=1) daub4(a,nn,isign);
} else {
for (nn=inverseStartLength;nn<=n;nn<<=1) daub4(a,nn,isign);
}
}
/* The number of bits required by each value */
static unsigned char numBits[] = {
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
byte MuLawEncode( short s ) {
byte MuLawEncode(short s) {
unsigned long adjusted;
byte sign, exponent, mantissa;
sign = ( s<0 ) ? 0 : 0x80;
sign = (s<0)?0:0x80;
if( s<0 ) s = -s;
adjusted = ( long )s << ( 16 - sizeof( short ) * 8 );
if (s<0) s=-s;
adjusted = (long)s << (16-sizeof(short)*8);
adjusted += 128L + 4L;
if( adjusted > 32767 ) adjusted = 32767;
exponent = numBits[ ( adjusted >> 7 ) & 0xff ] - 1;
mantissa = ( adjusted >> ( exponent + 3 ) ) & 0xf;
return ~( sign | ( exponent << 4 ) | mantissa );
if (adjusted > 32767) adjusted = 32767;
exponent = numBits[(adjusted>>7)&0xff] - 1;
mantissa = (adjusted>>(exponent+3))&0xf;
return ~(sign | (exponent<<4) | mantissa);
}
short MuLawDecode( byte uLaw ) {
short MuLawDecode(byte uLaw) {
signed long adjusted;
byte exponent, mantissa;
uLaw = ~uLaw;
exponent = ( uLaw >> 4 ) & 0x7;
mantissa = ( uLaw & 0xf ) + 16;
adjusted = ( mantissa << ( exponent + 3 ) ) - 128 - 4;
exponent = (uLaw>>4) & 0x7;
mantissa = (uLaw&0xf) + 16;
adjusted = (mantissa << (exponent +3)) - 128 - 4;
return ( uLaw & 0x80 ) ? adjusted : -adjusted;
return (uLaw & 0x80)? adjusted : -adjusted;
}
short mulawToShort[ 256 ];
short mulawToShort[256];
static qboolean madeTable = qfalse;
static int NXStreamCount;
void NXPutc( NXStream *stream, char out ) {
stream[ NXStreamCount++ ] = out;
void NXPutc(NXStream *stream, char out) {
stream[NXStreamCount++] = out;
}
void encodeWavelet( sfx_t *sfx, short *packets ) {
float wksp[ 4097 ] = { 0 }, temp;
void encodeWavelet( sfx_t *sfx, short *packets) {
float wksp[4097] = {0}, temp;
int i, samples, size;
sndBuffer *newchunk, *chunk;
byte *out;
if( !madeTable ) {
for( i = 0; i<256; i++ ) {
mulawToShort[ i ] = ( float )MuLawDecode( ( byte )i );
if (!madeTable) {
for (i=0;i<256;i++) {
mulawToShort[i] = (float)MuLawDecode((byte)i);
}
madeTable = qtrue;
}
chunk = NULL;
samples = sfx->soundLength;
while( samples>0 ) {
while(samples>0) {
size = samples;
if( size>( SND_CHUNK_SIZE * 2 ) ) {
size = ( SND_CHUNK_SIZE * 2 );
if (size>(SND_CHUNK_SIZE*2)) {
size = (SND_CHUNK_SIZE*2);
}
if( size<4 ) {
if (size<4) {
size = 4;
}
newchunk = SND_malloc();
if( sfx->soundData == NULL ) {
if (sfx->soundData == NULL) {
sfx->soundData = newchunk;
}
else if( chunk != NULL ) {
} else if (chunk != NULL) {
chunk->next = newchunk;
}
chunk = newchunk;
for( i = 0; i<size; i++ ) {
wksp[ i ] = *packets;
for(i=0; i<size; i++) {
wksp[i] = *packets;
packets++;
}
wt1( wksp, size, 1 );
out = ( byte * )chunk->sndChunk;
wt1(wksp, size, 1);
out = (byte *)chunk->sndChunk;
for( i = 0; i<size; i++ ) {
temp = wksp[ i ];
if( temp > 32767 ) temp = 32767; else if( temp<-32768 ) temp = -32768;
out[ i ] = MuLawEncode( ( short )temp );
for(i=0;i<size;i++) {
temp = wksp[i];
if (temp > 32767) temp = 32767; else if (temp<-32768) temp = -32768;
out[i] = MuLawEncode((short)temp);
}
chunk->size = size;
@ -171,36 +169,36 @@ void encodeWavelet( sfx_t *sfx, short *packets ) {
}
}
void decodeWavelet( sndBuffer *chunk, short *to ) {
float wksp[ 4097 ] = { 0 };
void decodeWavelet(sndBuffer *chunk, short *to) {
float wksp[4097] = {0};
int i;
byte *out;
int size = chunk->size;
out = ( byte * )chunk->sndChunk;
for( i = 0; i<size; i++ ) {
wksp[ i ] = mulawToShort[ out[ i ] ];
out = (byte *)chunk->sndChunk;
for(i=0;i<size;i++) {
wksp[i] = mulawToShort[out[i]];
}
wt1( wksp, size, -1 );
wt1(wksp, size, -1);
if (!to) return;
if( !to ) return;
for( i = 0; i<size; i++ ) {
to[ i ] = wksp[ i ];
for(i=0; i<size; i++) {
to[i] = wksp[i];
}
}
void encodeMuLaw( sfx_t *sfx, short *packets ) {
void encodeMuLaw( sfx_t *sfx, short *packets) {
int i, samples, size, grade, poop;
sndBuffer *newchunk, *chunk;
byte *out;
if( !madeTable ) {
for( i = 0; i<256; i++ ) {
mulawToShort[ i ] = ( float )MuLawDecode( ( byte )i );
if (!madeTable) {
for (i=0;i<256;i++) {
mulawToShort[i] = (float)MuLawDecode((byte)i);
}
madeTable = qtrue;
}
@ -209,31 +207,29 @@ void encodeMuLaw( sfx_t *sfx, short *packets ) {
samples = sfx->soundLength;
grade = 0;
while( samples>0 ) {
while(samples>0) {
size = samples;
if( size>( SND_CHUNK_SIZE * 2 ) ) {
size = ( SND_CHUNK_SIZE * 2 );
if (size>(SND_CHUNK_SIZE*2)) {
size = (SND_CHUNK_SIZE*2);
}
newchunk = SND_malloc();
if( sfx->soundData == NULL ) {
if (sfx->soundData == NULL) {
sfx->soundData = newchunk;
}
else if( chunk != NULL ) {
} else if (chunk != NULL) {
chunk->next = newchunk;
}
chunk = newchunk;
out = ( byte * )chunk->sndChunk;
for( i = 0; i<size; i++ ) {
poop = packets[ 0 ] + grade;
if( poop>32767 ) {
out = (byte *)chunk->sndChunk;
for(i=0; i<size; i++) {
poop = packets[0]+grade;
if (poop>32767) {
poop = 32767;
}
else if( poop<-32768 ) {
} else if (poop<-32768) {
poop = -32768;
}
out[ i ] = MuLawEncode( ( short )poop );
grade = poop - mulawToShort[ out[ i ] ];
out[i] = MuLawEncode((short)poop);
grade = poop - mulawToShort[out[i]];
packets++;
}
chunk->size = size;
@ -241,15 +237,15 @@ void encodeMuLaw( sfx_t *sfx, short *packets ) {
}
}
void decodeMuLaw( sndBuffer *chunk, short *to ) {
void decodeMuLaw(sndBuffer *chunk, short *to) {
int i;
byte *out;
int size = chunk->size;
out = ( byte * )chunk->sndChunk;
for( i = 0; i<size; i++ ) {
to[ i ] = mulawToShort[ out[ i ] ];
out = (byte *)chunk->sndChunk;
for(i=0;i<size;i++) {
to[i] = mulawToShort[out[i]];
}
}

View file

@ -25,6 +25,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef __STACK_H__
#define __STACK_H__
#if defined(GAME_DLL)
//
// game dll specific defines
//
#include "g_local.h"
#define STACK_Error gi.Error
#define STACK_DPrintf gi.DPrintf
#define STACK_WDPrintf(text) gi.DPrintf(text)
#elif defined(CGAME_DLL)
//
// cgame dll specific defines
//
#include "cg_local.h"
#define STACK_Error cgi.Error
#define STACK_DPrintf cgi.DPrintf
#define STACK_WDPrintf(text) cgi.DPrintf(text)
#else
//
// client specific defines
//
#define STACK_Error Com_Error
#define STACK_DPrintf Com_DPrintf
#define STACK_WDPrintf(text) Com_DPrintf(text)
#endif
template <class Type>
class StackNode
{
@ -109,7 +139,7 @@ inline void Stack<Type>::Push
if( !tmp )
{
assert( NULL );
glbs.Error( ERR_DROP, "Stack::Push : Out of memory" );
STACK_Error( ERR_DROP, "Stack::Push : Out of memory" );
}
tmp->next = head;

View file

@ -42,437 +42,152 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void);
//===========================================================================
#define qglAccum glAccum
#define qglAlphaFunc glAlphaFunc
#define qglAreTexturesResident glAreTexturesResident
#define qglArrayElement glArrayElement
#define qglBegin glBegin
#define qglBindTexture glBindTexture
#define qglBitmap glBitmap
#define qglBlendFunc glBlendFunc
#define qglCallList glCallList
#define qglCallLists glCallLists
#define qglClear glClear
#define qglClearAccum glClearAccum
#define qglClearColor glClearColor
#define qglClearDepth glClearDepth
#define qglClearIndex glClearIndex
#define qglClearStencil glClearStencil
#define qglClipPlane glClipPlane
#define qglColor3b glColor3b
#define qglColor3bv glColor3bv
#define qglColor3d glColor3d
#define qglColor3dv glColor3dv
#define qglColor3f glColor3f
#define qglColor3fv glColor3fv
#define qglColor3i glColor3i
#define qglColor3iv glColor3iv
#define qglColor3s glColor3s
#define qglColor3sv glColor3sv
#define qglColor3ub glColor3ub
#define qglColor3ubv glColor3ubv
#define qglColor3ui glColor3ui
#define qglColor3uiv glColor3uiv
#define qglColor3us glColor3us
#define qglColor3usv glColor3usv
#define qglColor4b glColor4b
#define qglColor4bv glColor4bv
#define qglColor4d glColor4d
#define qglColor4dv glColor4dv
#define qglColor4f glColor4f
#define qglColor4fv glColor4fv
#define qglColor4i glColor4i
#define qglColor4iv glColor4iv
#define qglColor4s glColor4s
#define qglColor4sv glColor4sv
#define qglColor4ub glColor4ub
#define qglColor4ubv glColor4ubv
#define qglColor4ui glColor4ui
#define qglColor4uiv glColor4uiv
#define qglColor4us glColor4us
#define qglColor4usv glColor4usv
#define qglColorMask glColorMask
#define qglColorMaterial glColorMaterial
#define qglColorPointer glColorPointer
#define qglCopyPixels glCopyPixels
#define qglCopyTexImage1D glCopyTexImage1D
#define qglCopyTexImage2D glCopyTexImage2D
#define qglCopyTexSubImage1D glCopyTexSubImage1D
#define qglCopyTexSubImage2D glCopyTexSubImage2D
#define qglCullFace glCullFace
#define qglDeleteLists glDeleteLists
#define qglDeleteTextures glDeleteTextures
#define qglDepthFunc glDepthFunc
#define qglDepthMask glDepthMask
#define qglDepthRange glDepthRange
#define qglDisable glDisable
#define qglDisableClientState glDisableClientState
#define qglDrawArrays glDrawArrays
#define qglDrawBuffer glDrawBuffer
#define qglDrawElements glDrawElements
#define qglDrawPixels glDrawPixels
#define qglEdgeFlag glEdgeFlag
#define qglEdgeFlagPointer glEdgeFlagPointer
#define qglEdgeFlagv glEdgeFlagv
#define qglEnable glEnable
#define qglEnableClientState glEnableClientState
#define qglEnd glEnd
#define qglEndList glEndList
#define qglEvalCoord1d glEvalCoord1d
#define qglEvalCoord1dv glEvalCoord1dv
#define qglEvalCoord1f glEvalCoord1f
#define qglEvalCoord1fv glEvalCoord1fv
#define qglEvalCoord2d glEvalCoord2d
#define qglEvalCoord2dv glEvalCoord2dv
#define qglEvalCoord2f glEvalCoord2f
#define qglEvalCoord2fv glEvalCoord2fv
#define qglEvalMesh1 glEvalMesh1
#define qglEvalMesh2 glEvalMesh2
#define qglEvalPoint1 glEvalPoint1
#define qglEvalPoint2 glEvalPoint2
#define qglFeedbackBuffer glFeedbackBuffer
#define qglFinish glFinish
#define qglFlush glFlush
#define qglFogf glFogf
#define qglFogfv glFogfv
#define qglFogi glFogi
#define qglFogiv glFogiv
#define qglFrontFace glFrontFace
#define qglFrustum glFrustum
#define qglGenLists glGenLists
#define qglGenTextures glGenTextures
#define qglGetBooleanv glGetBooleanv
#define qglGetClipPlane glGetClipPlane
#define qglGetDoublev glGetDoublev
#define qglGetError glGetError
#define qglGetFloatv glGetFloatv
#define qglGetIntegerv glGetIntegerv
#define qglGetLightfv glGetLightfv
#define qglGetLightiv glGetLightiv
#define qglGetMapdv glGetMapdv
#define qglGetMapfv glGetMapfv
#define qglGetMapiv glGetMapiv
#define qglGetMaterialfv glGetMaterialfv
#define qglGetMaterialiv glGetMaterialiv
#define qglGetPixelMapfv glGetPixelMapfv
#define qglGetPixelMapuiv glGetPixelMapuiv
#define qglGetPixelMapusv glGetPixelMapusv
#define qglGetPointerv glGetPointerv
#define qglGetPolygonStipple glGetPolygonStipple
#define qglGetString glGetString
#define qglGetTexGendv glGetTexGendv
#define qglGetTexGenfv glGetTexGenfv
#define qglGetTexGeniv glGetTexGeniv
#define qglGetTexImage glGetTexImage
#define qglGetTexLevelParameterfv glGetTexLevelParameterfv
#define qglGetTexLevelParameteriv glGetTexLevelParameteriv
#define qglGetTexParameterfv glGetTexParameterfv
#define qglGetTexParameteriv glGetTexParameteriv
#define qglHint glHint
#define qglIndexMask glIndexMask
#define qglIndexPointer glIndexPointer
#define qglIndexd glIndexd
#define qglIndexdv glIndexdv
#define qglIndexf glIndexf
#define qglIndexfv glIndexfv
#define qglIndexi glIndexi
#define qglIndexiv glIndexiv
#define qglIndexs glIndexs
#define qglIndexsv glIndexsv
#define qglIndexub glIndexub
#define qglIndexubv glIndexubv
#define qglInitNames glInitNames
#define qglInterleavedArrays glInterleavedArrays
#define qglIsEnabled glIsEnabled
#define qglIsList glIsList
#define qglIsTexture glIsTexture
#define qglLightModelf glLightModelf
#define qglLightModelfv glLightModelfv
#define qglLightModeli glLightModeli
#define qglLightModeliv glLightModeliv
#define qglLightf glLightf
#define qglLightfv glLightfv
#define qglLighti glLighti
#define qglLightiv glLightiv
#define qglLineStipple glLineStipple
#define qglLineWidth glLineWidth
#define qglListBase glListBase
#define qglLoadIdentity glLoadIdentity
#define qglLoadMatrixd glLoadMatrixd
#define qglLoadMatrixf glLoadMatrixf
#define qglLoadName glLoadName
#define qglLogicOp glLogicOp
#define qglMap1d glMap1d
#define qglMap1f glMap1f
#define qglMap2d glMap2d
#define qglMap2f glMap2f
#define qglMapGrid1d glMapGrid1d
#define qglMapGrid1f glMapGrid1f
#define qglMapGrid2d glMapGrid2d
#define qglMapGrid2f glMapGrid2f
#define qglMaterialf glMaterialf
#define qglMaterialfv glMaterialfv
#define qglMateriali glMateriali
#define qglMaterialiv glMaterialiv
#define qglMatrixMode glMatrixMode
#define qglMultMatrixd glMultMatrixd
#define qglMultMatrixf glMultMatrixf
#define qglNewList glNewList
#define qglNormal3b glNormal3b
#define qglNormal3bv glNormal3bv
#define qglNormal3d glNormal3d
#define qglNormal3dv glNormal3dv
#define qglNormal3f glNormal3f
#define qglNormal3fv glNormal3fv
#define qglNormal3i glNormal3i
#define qglNormal3iv glNormal3iv
#define qglNormal3s glNormal3s
#define qglNormal3sv glNormal3sv
#define qglNormalPointer glNormalPointer
#define qglOrtho glOrtho
#define qglPassThrough glPassThrough
#define qglPixelMapfv glPixelMapfv
#define qglPixelMapuiv glPixelMapuiv
#define qglPixelMapusv glPixelMapusv
#define qglPixelStoref glPixelStoref
#define qglPixelStorei glPixelStorei
#define qglPixelTransferf glPixelTransferf
#define qglPixelTransferi glPixelTransferi
#define qglPixelZoom glPixelZoom
#define qglPointSize glPointSize
#define qglPolygonMode glPolygonMode
#define qglPolygonOffset glPolygonOffset
#define qglPolygonStipple glPolygonStipple
#define qglPopAttrib glPopAttrib
#define qglPopClientAttrib glPopClientAttrib
#define qglPopMatrix glPopMatrix
#define qglPopName glPopName
#define qglPrioritizeTextures glPrioritizeTextures
#define qglPushAttrib glPushAttrib
#define qglPushClientAttrib glPushClientAttrib
#define qglPushMatrix glPushMatrix
#define qglPushName glPushName
#define qglRasterPos2d glRasterPos2d
#define qglRasterPos2dv glRasterPos2dv
#define qglRasterPos2f glRasterPos2f
#define qglRasterPos2fv glRasterPos2fv
#define qglRasterPos2i glRasterPos2i
#define qglRasterPos2iv glRasterPos2iv
#define qglRasterPos2s glRasterPos2s
#define qglRasterPos2sv glRasterPos2sv
#define qglRasterPos3d glRasterPos3d
#define qglRasterPos3dv glRasterPos3dv
#define qglRasterPos3f glRasterPos3f
#define qglRasterPos3fv glRasterPos3fv
#define qglRasterPos3i glRasterPos3i
#define qglRasterPos3iv glRasterPos3iv
#define qglRasterPos3s glRasterPos3s
#define qglRasterPos3sv glRasterPos3sv
#define qglRasterPos4d glRasterPos4d
#define qglRasterPos4dv glRasterPos4dv
#define qglRasterPos4f glRasterPos4f
#define qglRasterPos4fv glRasterPos4fv
#define qglRasterPos4i glRasterPos4i
#define qglRasterPos4iv glRasterPos4iv
#define qglRasterPos4s glRasterPos4s
#define qglRasterPos4sv glRasterPos4sv
#define qglReadBuffer glReadBuffer
#define qglReadPixels glReadPixels
#define qglRectd glRectd
#define qglRectdv glRectdv
#define qglRectf glRectf
#define qglRectfv glRectfv
#define qglRecti glRecti
#define qglRectiv glRectiv
#define qglRects glRects
#define qglRectsv glRectsv
#define qglRenderMode glRenderMode
#define qglRotated glRotated
#define qglRotatef glRotatef
#define qglScaled glScaled
#define qglScalef glScalef
#define qglScissor glScissor
#define qglSelectBuffer glSelectBuffer
#define qglShadeModel glShadeModel
#define qglStencilFunc glStencilFunc
#define qglStencilMask glStencilMask
#define qglStencilOp glStencilOp
#define qglTexCoord1d glTexCoord1d
#define qglTexCoord1dv glTexCoord1dv
#define qglTexCoord1f glTexCoord1f
#define qglTexCoord1fv glTexCoord1fv
#define qglTexCoord1i glTexCoord1i
#define qglTexCoord1iv glTexCoord1iv
#define qglTexCoord1s glTexCoord1s
#define qglTexCoord1sv glTexCoord1sv
#define qglTexCoord2d glTexCoord2d
#define qglTexCoord2dv glTexCoord2dv
#define qglTexCoord2f glTexCoord2f
#define qglTexCoord2fv glTexCoord2fv
#define qglTexCoord2i glTexCoord2i
#define qglTexCoord2iv glTexCoord2iv
#define qglTexCoord2s glTexCoord2s
#define qglTexCoord2sv glTexCoord2sv
#define qglTexCoord3d glTexCoord3d
#define qglTexCoord3dv glTexCoord3dv
#define qglTexCoord3f glTexCoord3f
#define qglTexCoord3fv glTexCoord3fv
#define qglTexCoord3i glTexCoord3i
#define qglTexCoord3iv glTexCoord3iv
#define qglTexCoord3s glTexCoord3s
#define qglTexCoord3sv glTexCoord3sv
#define qglTexCoord4d glTexCoord4d
#define qglTexCoord4dv glTexCoord4dv
#define qglTexCoord4f glTexCoord4f
#define qglTexCoord4fv glTexCoord4fv
#define qglTexCoord4i glTexCoord4i
#define qglTexCoord4iv glTexCoord4iv
#define qglTexCoord4s glTexCoord4s
#define qglTexCoord4sv glTexCoord4sv
#define qglTexCoordPointer glTexCoordPointer
#define qglTexEnvf glTexEnvf
#define qglTexEnvfv glTexEnvfv
#define qglTexEnvi glTexEnvi
#define qglTexEnviv glTexEnviv
#define qglTexGend glTexGend
#define qglTexGendv glTexGendv
#define qglTexGenf glTexGenf
#define qglTexGenfv glTexGenfv
#define qglTexGeni glTexGeni
#define qglTexGeniv glTexGeniv
#define qglTexImage1D glTexImage1D
#define qglTexImage2D glTexImage2D
#define qglTexParameterf glTexParameterf
#define qglTexParameterfv glTexParameterfv
#define qglTexParameteri glTexParameteri
#define qglTexParameteriv glTexParameteriv
#define qglTexSubImage1D glTexSubImage1D
#define qglTexSubImage2D glTexSubImage2D
#define qglTranslated glTranslated
#define qglTranslatef glTranslatef
#define qglVertex2d glVertex2d
#define qglVertex2dv glVertex2dv
#define qglVertex2f glVertex2f
#define qglVertex2fv glVertex2fv
#define qglVertex2i glVertex2i
#define qglVertex2iv glVertex2iv
#define qglVertex2s glVertex2s
#define qglVertex2sv glVertex2sv
#define qglVertex3d glVertex3d
#define qglVertex3dv glVertex3dv
#define qglVertex3f glVertex3f
#define qglVertex3fv glVertex3fv
#define qglVertex3i glVertex3i
#define qglVertex3iv glVertex3iv
#define qglVertex3s glVertex3s
#define qglVertex3sv glVertex3sv
#define qglVertex4d glVertex4d
#define qglVertex4dv glVertex4dv
#define qglVertex4f glVertex4f
#define qglVertex4fv glVertex4fv
#define qglVertex4i glVertex4i
#define qglVertex4iv glVertex4iv
#define qglVertex4s glVertex4s
#define qglVertex4sv glVertex4sv
#define qglVertexPointer glVertexPointer
#define qglViewport glViewport
// GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
// get missing functions from code/SDL2/include/SDL_opengl.h
// GL_EXT_draw_range_elements
extern void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
// OpenGL 1.0/1.1, OpenGL ES 1.0, and OpenGL 3.2 core profile
#define QGL_1_1_PROCS \
GLE(void, BindTexture, GLenum target, GLuint texture) \
GLE(void, BlendFunc, GLenum sfactor, GLenum dfactor) \
GLE(void, ClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) \
GLE(void, Clear, GLbitfield mask) \
GLE(void, ClearStencil, GLint s) \
GLE(void, ColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) \
GLE(void, CopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) \
GLE(void, CullFace, GLenum mode) \
GLE(void, DeleteTextures, GLsizei n, const GLuint *textures) \
GLE(void, DepthFunc, GLenum func) \
GLE(void, DepthMask, GLboolean flag) \
GLE(void, Disable, GLenum cap) \
GLE(void, DrawArrays, GLenum mode, GLint first, GLsizei count) \
GLE(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) \
GLE(void, Enable, GLenum cap) \
GLE(void, Finish, void) \
GLE(void, Flush, void) \
GLE(void, GenTextures, GLsizei n, GLuint *textures ) \
GLE(void, GetBooleanv, GLenum pname, GLboolean *params) \
GLE(GLenum, GetError, void) \
GLE(void, GetIntegerv, GLenum pname, GLint *params) \
GLE(const GLubyte *, GetString, GLenum name) \
GLE(void, LineWidth, GLfloat width) \
GLE(void, PolygonOffset, GLfloat factor, GLfloat units) \
GLE(void, ReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) \
GLE(void, Scissor, GLint x, GLint y, GLsizei width, GLsizei height) \
GLE(void, StencilFunc, GLenum func, GLint ref, GLuint mask) \
GLE(void, StencilMask, GLuint mask) \
GLE(void, StencilOp, GLenum fail, GLenum zfail, GLenum zpass) \
GLE(void, TexImage2D, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(void, TexParameterf, GLenum target, GLenum pname, GLfloat param) \
GLE(void, TexParameteri, GLenum target, GLenum pname, GLint param) \
GLE(void, TexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(void, Translatef, GLfloat x, GLfloat y, GLfloat z) \
GLE(void, Viewport, GLint x, GLint y, GLsizei width, GLsizei height) \
// GL_EXT_multi_draw_arrays
extern void (APIENTRY * qglMultiDrawArraysEXT) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
extern void (APIENTRY * qglMultiDrawElementsEXT) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
// OpenGL 1.0/1.1 and OpenGL ES 1.x but not OpenGL 3.2 core profile
#define QGL_1_1_FIXED_FUNCTION_PROCS \
GLE(void, AlphaFunc, GLenum func, GLclampf ref) \
GLE(void, Color4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
GLE(void, ColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, DisableClientState, GLenum cap) \
GLE(void, EnableClientState, GLenum cap) \
GLE(void, LoadIdentity, void) \
GLE(void, LoadMatrixf, const GLfloat *m) \
GLE(void, MatrixMode, GLenum mode) \
GLE(void, PopMatrix, void) \
GLE(void, PushMatrix, void) \
GLE(void, ShadeModel, GLenum mode) \
GLE(void, TexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, TexEnvf, GLenum target, GLenum pname, GLfloat param) \
GLE(void, VertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
// GL_ARB_shading_language_100
#ifndef GL_ARB_shading_language_100
#define GL_ARB_shading_language_100
#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
#endif
// OpenGL 1.0/1.1 and 3.2 core profile but not OpenGL ES 1.x
#define QGL_DESKTOP_1_1_PROCS \
GLE(void, ClearDepth, GLclampd depth) \
GLE(void, DepthRange, GLclampd near_val, GLclampd far_val) \
GLE(void, DrawBuffer, GLenum mode) \
GLE(void, PolygonMode, GLenum face, GLenum mode) \
// GL_ARB_vertex_program
extern void (APIENTRY * qglVertexAttrib4fARB) (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
extern void (APIENTRY * qglVertexAttrib4fvARB) (GLuint, const GLfloat *);
extern void (APIENTRY * qglVertexAttribPointerARB) (GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid * pointer);
extern void (APIENTRY * qglEnableVertexAttribArrayARB) (GLuint index);
extern void (APIENTRY * qglDisableVertexAttribArrayARB) (GLuint index);
// OpenGL 1.0/1.1 but not OpenGL 3.2 core profile or OpenGL ES 1.x
#define QGL_DESKTOP_1_1_FIXED_FUNCTION_PROCS \
GLE(void, ArrayElement, GLint i) \
GLE(void, Begin, GLenum mode) \
GLE(void, ClipPlane, GLenum plane, const GLdouble *equation) \
GLE(void, Color3f, GLfloat red, GLfloat green, GLfloat blue) \
GLE(void, Color4ubv, const GLubyte *v) \
GLE(void, End, void) \
GLE(void, Frustum, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) \
GLE(void, Ortho, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) \
GLE(void, TexCoord2f, GLfloat s, GLfloat t) \
GLE(void, TexCoord2fv, const GLfloat *v) \
GLE(void, Vertex2f, GLfloat x, GLfloat y) \
GLE(void, Vertex3f, GLfloat x, GLfloat y, GLfloat z) \
GLE(void, Vertex3fv, const GLfloat *v) \
// GL_ARB_vertex_buffer_object
extern void (APIENTRY * qglBindBufferARB) (GLenum target, GLuint buffer);
extern void (APIENTRY * qglDeleteBuffersARB) (GLsizei n, const GLuint * buffers);
extern void (APIENTRY * qglGenBuffersARB) (GLsizei n, GLuint * buffers);
extern GLboolean(APIENTRY * qglIsBufferARB) (GLuint buffer);
extern void (APIENTRY * qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
extern void (APIENTRY * qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
extern void (APIENTRY * qglGetBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data);
extern void (APIENTRY * qglGetBufferParameterivARB) (GLenum target, GLenum pname, GLint * params);
extern void (APIENTRY * qglGetBufferPointervARB) (GLenum target, GLenum pname, GLvoid * *params);
// OpenGL ES 1.1 and OpenGL ES 2.0 but not desktop OpenGL 1.x
#define QGL_ES_1_1_PROCS \
GLE(void, ClearDepthf, GLclampf depth) \
GLE(void, DepthRangef, GLclampf near_val, GLclampf far_val) \
// GL_ARB_shader_objects
extern void (APIENTRY * qglDeleteObjectARB) (GLhandleARB obj);
extern GLhandleARB(APIENTRY * qglGetHandleARB) (GLenum pname);
extern void (APIENTRY * qglDetachObjectARB) (GLhandleARB containerObj, GLhandleARB attachedObj);
extern GLhandleARB(APIENTRY * qglCreateShaderObjectARB) (GLenum shaderType);
extern void (APIENTRY * qglShaderSourceARB) (GLhandleARB shaderObj, GLsizei count, const GLcharARB * *string,
const GLint * length);
extern void (APIENTRY * qglCompileShaderARB) (GLhandleARB shaderObj);
extern GLhandleARB(APIENTRY * qglCreateProgramObjectARB) (void);
extern void (APIENTRY * qglAttachObjectARB) (GLhandleARB containerObj, GLhandleARB obj);
extern void (APIENTRY * qglLinkProgramARB) (GLhandleARB programObj);
extern void (APIENTRY * qglUseProgramObjectARB) (GLhandleARB programObj);
extern void (APIENTRY * qglValidateProgramARB) (GLhandleARB programObj);
extern void (APIENTRY * qglUniform1fARB) (GLint location, GLfloat v0);
extern void (APIENTRY * qglUniform2fARB) (GLint location, GLfloat v0, GLfloat v1);
extern void (APIENTRY * qglUniform3fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
extern void (APIENTRY * qglUniform4fARB) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
extern void (APIENTRY * qglUniform1iARB) (GLint location, GLint v0);
extern void (APIENTRY * qglUniform2iARB) (GLint location, GLint v0, GLint v1);
extern void (APIENTRY * qglUniform3iARB) (GLint location, GLint v0, GLint v1, GLint v2);
extern void (APIENTRY * qglUniform4iARB) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
extern void (APIENTRY * qglUniform1fvARB) (GLint location, GLsizei count, const GLfloat * value);
extern void (APIENTRY * qglUniform2fvARB) (GLint location, GLsizei count, const GLfloat * value);
extern void (APIENTRY * qglUniform3fvARB) (GLint location, GLsizei count, const GLfloat * value);
extern void (APIENTRY * qglUniform4fvARB) (GLint location, GLsizei count, const GLfloat * value);
extern void (APIENTRY * qglUniform2ivARB) (GLint location, GLsizei count, const GLint * value);
extern void (APIENTRY * qglUniform3ivARB) (GLint location, GLsizei count, const GLint * value);
extern void (APIENTRY * qglUniform4ivARB) (GLint location, GLsizei count, const GLint * value);
extern void (APIENTRY * qglUniformMatrix2fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
extern void (APIENTRY * qglUniformMatrix3fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
extern void (APIENTRY * qglUniformMatrix4fvARB) (GLint location, GLsizei count, GLboolean transpose, const GLfloat * value);
extern void (APIENTRY * qglGetObjectParameterfvARB) (GLhandleARB obj, GLenum pname, GLfloat * params);
extern void (APIENTRY * qglGetObjectParameterivARB) (GLhandleARB obj, GLenum pname, GLint * params);
extern void (APIENTRY * qglGetInfoLogARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog);
extern void (APIENTRY * qglGetAttachedObjectsARB) (GLhandleARB containerObj, GLsizei maxCount, GLsizei * count,
GLhandleARB * obj);
extern GLint(APIENTRY * qglGetUniformLocationARB) (GLhandleARB programObj, const GLcharARB * name);
extern void (APIENTRY * qglGetActiveUniformARB) (GLhandleARB programObj, GLuint index, GLsizei maxIndex, GLsizei * length,
GLint * size, GLenum * type, GLcharARB * name);
extern void (APIENTRY * qglGetUniformfvARB) (GLhandleARB programObj, GLint location, GLfloat * params);
extern void (APIENTRY * qglGetUniformivARB) (GLhandleARB programObj, GLint location, GLint * params);
extern void (APIENTRY * qglGetShaderSourceARB) (GLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * source);
// OpenGL ES 1.1 but not OpenGL ES 2.0 or desktop OpenGL 1.x
#define QGL_ES_1_1_FIXED_FUNCTION_PROCS \
GLE(void, ClipPlanef, GLenum plane, const GLfloat *equation) \
GLE(void, Frustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val) \
GLE(void, Orthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val) \
// GL_ARB_vertex_shader
extern void (APIENTRY * qglBindAttribLocationARB) (GLhandleARB programObj, GLuint index, const GLcharARB * name);
extern void (APIENTRY * qglGetActiveAttribARB) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei * length,
GLint * size, GLenum * type, GLcharARB * name);
extern GLint(APIENTRY * qglGetAttribLocationARB) (GLhandleARB programObj, const GLcharARB * name);
// OpenGL 1.3, was GL_ARB_texture_compression
#define QGL_1_3_PROCS \
GLE(void, ActiveTexture, GLenum texture) \
GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \
// GL_ARB_texture_compression
extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
GLvoid *img);
// GL_ARB_occlusion_query, built-in to OpenGL 1.5 but not OpenGL ES 2.0
#define QGL_ARB_occlusion_query_PROCS \
GLE(void, GenQueries, GLsizei n, GLuint *ids) \
GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
GLE(void, BeginQuery, GLenum target, GLuint id) \
GLE(void, EndQuery, GLenum target) \
GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \
// OpenGL 1.5, was GL_ARB_vertex_buffer_object
#define QGL_1_5_PROCS \
GLE(void, BindBuffer, GLenum target, GLuint buffer) \
GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
GLE(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) \
GLE(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) \
// OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
#define QGL_2_0_PROCS \
GLE(void, AttachShader, GLuint program, GLuint shader) \
GLE(void, BindAttribLocation, GLuint program, GLuint index, const GLchar *name) \
GLE(void, CompileShader, GLuint shader) \
GLE(GLuint, CreateProgram, void) \
GLE(GLuint, CreateShader, GLenum type) \
GLE(void, DeleteProgram, GLuint program) \
GLE(void, DeleteShader, GLuint shader) \
GLE(void, DetachShader, GLuint program, GLuint shader) \
GLE(void, DisableVertexAttribArray, GLuint index) \
GLE(void, EnableVertexAttribArray, GLuint index) \
GLE(void, GetActiveUniform, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) \
GLE(void, GetProgramiv, GLuint program, GLenum pname, GLint *params) \
GLE(void, GetProgramInfoLog, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
GLE(void, GetShaderiv, GLuint shader, GLenum pname, GLint *params) \
GLE(void, GetShaderInfoLog, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) \
GLE(void, GetShaderSource, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) \
GLE(GLint, GetUniformLocation, GLuint program, const GLchar *name) \
GLE(void, LinkProgram, GLuint program) \
GLE(void, ShaderSource, GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) \
GLE(void, UseProgram, GLuint program) \
GLE(void, Uniform1f, GLint location, GLfloat v0) \
GLE(void, Uniform2f, GLint location, GLfloat v0, GLfloat v1) \
GLE(void, Uniform3f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
GLE(void, Uniform4f, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
GLE(void, Uniform1i, GLint location, GLint v0) \
GLE(void, Uniform1fv, GLint location, GLsizei count, const GLfloat *value) \
GLE(void, UniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
GLE(void, ValidateProgram, GLuint program) \
GLE(void, VertexAttribPointer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) \
// GL_NVX_gpu_memory_info
#ifndef GL_NVX_gpu_memory_info
@ -522,167 +237,38 @@ extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
#define GL_HALF_FLOAT_ARB 0x140B
#endif
// GL_EXT_framebuffer_object
extern GLboolean (APIENTRY * qglIsRenderbufferEXT)(GLuint renderbuffer);
extern void (APIENTRY * qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
extern void (APIENTRY * qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
extern void (APIENTRY * qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
extern void (APIENTRY * qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
extern void (APIENTRY * qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
extern GLboolean (APIENTRY * qglIsFramebufferEXT)(GLuint framebuffer);
extern void (APIENTRY * qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
extern void (APIENTRY * qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
extern void (APIENTRY * qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
extern GLenum (APIENTRY * qglCheckFramebufferStatusEXT)(GLenum target);
extern void (APIENTRY * qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
GLint level);
extern void (APIENTRY * qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
GLint level);
extern void (APIENTRY * qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
GLint level, GLint zoffset);
extern void (APIENTRY * qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget,
GLuint renderbuffer);
extern void (APIENTRY * qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
extern void (APIENTRY * qglGenerateMipmapEXT)(GLenum target);
// OpenGL 3.0 specific
#define QGL_3_0_PROCS \
GLE(const GLubyte *, GetStringi, GLenum name, GLuint index) \
#ifndef GL_EXT_framebuffer_object
#define GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER_EXT 0x8D40
#define GL_RENDERBUFFER_EXT 0x8D41
#define GL_STENCIL_INDEX1_EXT 0x8D46
#define GL_STENCIL_INDEX4_EXT 0x8D47
#define GL_STENCIL_INDEX8_EXT 0x8D48
#define GL_STENCIL_INDEX16_EXT 0x8D49
#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
#endif
// GL_ARB_framebuffer_object, built-in to OpenGL 3.0
#define QGL_ARB_framebuffer_object_PROCS \
GLE(void, BindRenderbuffer, GLenum target, GLuint renderbuffer) \
GLE(void, DeleteRenderbuffers, GLsizei n, const GLuint *renderbuffers) \
GLE(void, GenRenderbuffers, GLsizei n, GLuint *renderbuffers) \
GLE(void, RenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) \
GLE(void, BindFramebuffer, GLenum target, GLuint framebuffer) \
GLE(void, DeleteFramebuffers, GLsizei n, const GLuint *framebuffers) \
GLE(void, GenFramebuffers, GLsizei n, GLuint *framebuffers) \
GLE(GLenum, CheckFramebufferStatus, GLenum target) \
GLE(void, FramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
GLE(void, FramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
GLE(void, GenerateMipmap, GLenum target) \
GLE(void, BlitFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) \
GLE(void, RenderbufferStorageMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
// GL_EXT_packed_depth_stencil
#ifndef GL_EXT_packed_depth_stencil
#define GL_EXT_packed_depth_stencil
#define GL_DEPTH_STENCIL_EXT 0x84F9
#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
#define GL_DEPTH24_STENCIL8_EXT 0x88F0
#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
#endif
// GL_ARB_vertex_array_object, built-in to OpenGL 3.0
#define QGL_ARB_vertex_array_object_PROCS \
GLE(void, BindVertexArray, GLuint array) \
GLE(void, DeleteVertexArrays, GLsizei n, const GLuint *arrays) \
GLE(void, GenVertexArrays, GLsizei n, GLuint *arrays) \
// GL_ARB_occlusion_query
extern void (APIENTRY * qglGenQueriesARB)(GLsizei n, GLuint *ids);
extern void (APIENTRY * qglDeleteQueriesARB)(GLsizei n, const GLuint *ids);
extern GLboolean (APIENTRY * qglIsQueryARB)(GLuint id);
extern void (APIENTRY * qglBeginQueryARB)(GLenum target, GLuint id);
extern void (APIENTRY * qglEndQueryARB)(GLenum target);
extern void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
extern void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
#ifndef GL_ARB_occlusion_query
#define GL_ARB_occlusion_query
#define GL_SAMPLES_PASSED_ARB 0x8914
#define GL_QUERY_COUNTER_BITS_ARB 0x8864
#define GL_CURRENT_QUERY_ARB 0x8865
#define GL_QUERY_RESULT_ARB 0x8866
#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
#endif
// GL_EXT_framebuffer_blit
extern void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
#endif
// GL_EXT_framebuffer_multisample
extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
#ifndef GL_EXT_framebuffer_multisample
#define GL_EXT_framebuffer_multisample
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
#define GL_MAX_SAMPLES_EXT 0x8D57
#endif
#ifndef GL_EXT_texture_sRGB
#define GL_EXT_texture_sRGB
#define GL_SRGB_EXT 0x8C40
#define GL_SRGB8_EXT 0x8C41
#define GL_SRGB_ALPHA_EXT 0x8C42
#define GL_SRGB8_ALPHA8_EXT 0x8C43
#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
#define GL_SLUMINANCE_EXT 0x8C46
#define GL_SLUMINANCE8_EXT 0x8C47
#define GL_COMPRESSED_SRGB_EXT 0x8C48
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#endif
#ifndef GL_EXT_framebuffer_sRGB
#define GL_EXT_framebuffer_sRGB
#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
#endif
#ifndef GL_EXT_texture_compression_latc
#define GL_EXT_texture_compression_latc
#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
#ifndef GL_ARB_texture_compression_rgtc
#define GL_ARB_texture_compression_rgtc
#define GL_COMPRESSED_RED_RGTC1 0x8DBB
#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
#define GL_COMPRESSED_RG_RGTC2 0x8DBD
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
#endif
#ifndef GL_ARB_texture_compression_bptc
@ -693,29 +279,6 @@ extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLs
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
#endif
// GL_ARB_draw_buffers
extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
#ifndef GL_ARB_draw_buffers
#define GL_ARB_draw_buffers
#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
#define GL_DRAW_BUFFER0_ARB 0x8825
#define GL_DRAW_BUFFER1_ARB 0x8826
#define GL_DRAW_BUFFER2_ARB 0x8827
#define GL_DRAW_BUFFER3_ARB 0x8828
#define GL_DRAW_BUFFER4_ARB 0x8829
#define GL_DRAW_BUFFER5_ARB 0x882A
#define GL_DRAW_BUFFER6_ARB 0x882B
#define GL_DRAW_BUFFER7_ARB 0x882C
#define GL_DRAW_BUFFER8_ARB 0x882D
#define GL_DRAW_BUFFER9_ARB 0x882E
#define GL_DRAW_BUFFER10_ARB 0x882F
#define GL_DRAW_BUFFER11_ARB 0x8830
#define GL_DRAW_BUFFER12_ARB 0x8831
#define GL_DRAW_BUFFER13_ARB 0x8832
#define GL_DRAW_BUFFER14_ARB 0x8833
#define GL_DRAW_BUFFER15_ARB 0x8834
#endif
#ifndef GL_ARB_depth_clamp
#define GL_ARB_depth_clamp
#define GL_DEPTH_CLAMP 0x864F
@ -726,47 +289,50 @@ extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
#endif
// GL_ARB_vertex_array_object
extern void (APIENTRY * qglBindVertexArrayARB)(GLuint array);
extern void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays);
extern void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays);
extern GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array);
#ifndef GL_ARB_vertex_array_object
#define GL_ARB_vertex_array_object
#define GL_VERTEX_ARRAY_BINDING_ARB 0x85B5
#endif
// GL_EXT_direct_state_access
#define QGL_EXT_direct_state_access_PROCS \
GLE(GLvoid, BindMultiTextureEXT, GLenum texunit, GLenum target, GLuint texture) \
GLE(GLvoid, TextureParameterfEXT, GLuint texture, GLenum target, GLenum pname, GLfloat param) \
GLE(GLvoid, TextureParameteriEXT, GLuint texture, GLenum target, GLenum pname, GLint param) \
GLE(GLvoid, TextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(GLvoid, TextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(GLvoid, CopyTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) \
GLE(GLvoid, CompressedTextureImage2DEXT, GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) \
GLE(GLvoid, CompressedTextureSubImage2DEXT, GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) \
GLE(GLvoid, GenerateTextureMipmapEXT, GLuint texture, GLenum target) \
GLE(GLvoid, ProgramUniform1iEXT, GLuint program, GLint location, GLint v0) \
GLE(GLvoid, ProgramUniform1fEXT, GLuint program, GLint location, GLfloat v0) \
GLE(GLvoid, ProgramUniform2fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1) \
GLE(GLvoid, ProgramUniform3fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) \
GLE(GLvoid, ProgramUniform4fEXT, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) \
GLE(GLvoid, ProgramUniform1fvEXT, GLuint program, GLint location, GLsizei count, const GLfloat *value) \
GLE(GLvoid, ProgramUniformMatrix4fvEXT, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) \
GLE(GLvoid, NamedRenderbufferStorageEXT, GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) \
GLE(GLvoid, NamedRenderbufferStorageMultisampleEXT, GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) \
GLE(GLenum, CheckNamedFramebufferStatusEXT, GLuint framebuffer, GLenum target) \
GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \
#define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__);
QGL_1_1_PROCS;
QGL_1_1_FIXED_FUNCTION_PROCS;
QGL_DESKTOP_1_1_PROCS;
QGL_DESKTOP_1_1_FIXED_FUNCTION_PROCS;
QGL_ES_1_1_PROCS;
QGL_ES_1_1_FIXED_FUNCTION_PROCS;
QGL_1_3_PROCS;
QGL_1_5_PROCS;
QGL_2_0_PROCS;
QGL_3_0_PROCS;
QGL_ARB_occlusion_query_PROCS;
QGL_ARB_framebuffer_object_PROCS;
QGL_ARB_vertex_array_object_PROCS;
QGL_EXT_direct_state_access_PROCS;
#undef GLE
#if defined(WIN32)
// WGL_ARB_create_context
#ifndef WGL_ARB_create_context
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
#endif
extern HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
#endif
#if 0 //defined(__linux__)
// GLX_ARB_create_context
#ifndef GLX_ARB_create_context
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#endif
extern GLXContext (APIENTRY * qglXCreateContextAttribsARB) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#endif
extern int qglMajorVersion, qglMinorVersion;
extern int qglesMajorVersion, qglesMinorVersion;
#define QGL_VERSION_ATLEAST( major, minor ) ( qglMajorVersion > major || ( qglMajorVersion == major && qglMinorVersion >= minor ) )
#define QGLES_VERSION_ATLEAST( major, minor ) ( qglesMajorVersion > major || ( qglesMajorVersion == major && qglesMinorVersion >= minor ) )
#endif

View file

@ -86,6 +86,7 @@ extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared duri
extern qboolean textureFilterAnisotropic;
extern int maxAnisotropy;
extern float displayAspect;
extern qboolean haveClampToEdge;
//
// cvars

View file

@ -281,7 +281,13 @@ typedef struct {
// input event handling
void (*IN_Init)(void *windowData);
void (*IN_Shutdown)(void);
void (*IN_Restart)(void);
void (*IN_Restart)(void);
// system stuff
void (*Sys_SetEnv)(const char* name, const char* value);
void (*Sys_GLimpSafeInit)(void);
void (*Sys_GLimpInit)(void);
qboolean(*Sys_LowPhysicalMemory)(void);
} refimport_t;

View file

@ -619,7 +619,7 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder, qbool
mode.w = glConfig.vidWidth;
mode.h = glConfig.vidHeight;
mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_VariableIntegerValue( "r_displayRefresh" );
mode.refresh_rate = glConfig.displayFrequency = ri.Cvar_Get( "r_displayRefresh", "", 0)->integer;
mode.driverdata = NULL;
if( SDL_SetWindowDisplayMode( SDL_window, &mode ) < 0 )
@ -771,7 +771,7 @@ static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qbool
ri.Cvar_Set( "r_sdlDriver", driverName );
}
if (fullscreen && ri.Cvar_VariableIntegerValue( "in_nograb" ) )
if (fullscreen && ri.Cvar_Get( "in_nograb", "", 0)->integer )
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );
@ -997,7 +997,7 @@ void GLimp_Init( qboolean fixedFunction )
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE | CVAR_LATCH );
if( ri.Cvar_VariableIntegerValue( "com_abnormalExit" ) )
if( ri.Cvar_Get( "com_abnormalExit", "", 0))
{
ri.Cvar_Set( "r_mode", va( "%d", R_MODE_FALLBACK ) );
ri.Cvar_Set( "r_fullscreen", "0" );
@ -1111,7 +1111,7 @@ void GLimp_EndFrame( void )
// Find out the current state
fullscreen = !!( SDL_GetWindowFlags( SDL_window ) & SDL_WINDOW_FULLSCREEN );
if( r_fullscreen->integer && ri.Cvar_VariableIntegerValue( "in_nograb" ) )
if( r_fullscreen->integer && ri.Cvar_Get( "in_nograb", "", 0))
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );

View file

@ -1186,7 +1186,7 @@ void IN_Frame( void )
IN_JoyMove( );
// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
loading = ( clc.state != CA_DISCONNECTED && clc.state != CA_ACTIVE );
loading = ( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );
// update isFullscreen since it might of changed since the last vid_restart
cls.glconfig.isFullscreen = Cvar_VariableIntegerValue( "r_fullscreen" ) != 0;

View file

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "ui_local.h"
#include "scriptexception.h"
Event EV_Layout_Menu
(