13 Sep 2010
This commit is contained in:
parent
9835598587
commit
c44aba6a7d
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: client - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
client.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
16
dlls/hl.plg
16
dlls/hl.plg
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: hl - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
hl.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -384,6 +384,7 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam )
|
|||
ShowWindow( host.hWnd, SW_SHOWMINNOACTIVE );
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
if( !in_mouseactive ) break;
|
||||
if(( short )HIWORD( wParam ) > 0 )
|
||||
{
|
||||
Sys_QueEvent( -1, SE_KEY, K_MWHEELUP, true, 0, NULL );
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: engine - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
engine.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: gameui - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
gameui.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,71 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: launch - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB2.tmp" with contents
|
||||
[
|
||||
/nologo /MD /W3 /GX /O2 /I "./" /I "imagelib" /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\launch\!release/" /Fd"..\temp\launch\!release/" /FD /c
|
||||
"D:\Xash3D\src_main\launch\filesystem.c"
|
||||
]
|
||||
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB2.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB3.tmp" with contents
|
||||
[
|
||||
zlib.lib png.lib jpg.lib ogg.lib vorbis.lib user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc" /nodefaultlib:"libcmt" /out:"..\temp\launch\!release/launch.dll" /implib:"..\temp\launch\!release/launch.lib" /libpath:"./imagelib" /libpath:"./soundlib" /opt:nowin98
|
||||
"\Xash3D\src_main\temp\launch\!release\cmd.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\console.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\cpuinfo.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\crclib.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\cvar.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\export.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\filesystem.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_bmp.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_dds.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_jpg.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_main.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_pcx.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_png.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_tga.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_utils.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_vtf.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\img_wad.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\library.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\memlib.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\network.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\parselib.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\snd_main.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\snd_ogg.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\snd_raw.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\snd_utils.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\snd_wav.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\stdlib.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\system.obj"
|
||||
"\Xash3D\src_main\temp\launch\!release\utils.obj"
|
||||
]
|
||||
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB3.tmp""
|
||||
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB4.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\launch\!release\launch.dll "D:\Xash3D\bin\launch.dll"
|
||||
]
|
||||
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP1FB4.bat""
|
||||
Compiling...
|
||||
filesystem.c
|
||||
D:\Xash3D\src_main\launch\filesystem.c(3668) : error C2039: 'compress' : is not a member of 'vfile_s'
|
||||
D:\Xash3D\src_main\launch\filesystem.c(63) : see declaration of 'vfile_s'
|
||||
D:\Xash3D\src_main\launch\filesystem.c(4053) : error C2065: 'CMP_ZLIB' : undeclared identifier
|
||||
D:\Xash3D\src_main\launch\filesystem.c(4053) : error C2051: case expression not constant
|
||||
D:\Xash3D\src_main\launch\filesystem.c(4110) : error C2051: case expression not constant
|
||||
Error executing cl.exe.
|
||||
<h3>Output Window</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
launch.dll - 4 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// baserc_api.h - xash resource library
|
||||
//=======================================================================
|
||||
#ifndef BASERC_API_H
|
||||
#define BASERC_API_H
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
BASERC.DLL INTERFACE
|
||||
|
||||
just a resource package library
|
||||
==============================================================================
|
||||
*/
|
||||
typedef struct baserc_exp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(baserc_exp_t)
|
||||
size_t com_size; // must matched with sizeof(stdlib_api_t)
|
||||
|
||||
byte *(*LoadFile)( const char *filename, fs_offset_t *size );
|
||||
} baserc_exp_t;
|
||||
|
||||
#endif//BASERC_API_H
|
|
@ -1,232 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// qfiles_ref.h - xash supported formats
|
||||
//=======================================================================
|
||||
#ifndef REF_DFILES_H
|
||||
#define REF_DFILES_H
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
.WAD archive format (WhereAllData - WAD)
|
||||
|
||||
List of compressed files, that can be identify only by TYPE_*
|
||||
|
||||
<format>
|
||||
header: dwadinfo_t[dwadinfo_t]
|
||||
file_1: byte[dwadinfo_t[num]->disksize]
|
||||
file_2: byte[dwadinfo_t[num]->disksize]
|
||||
file_3: byte[dwadinfo_t[num]->disksize]
|
||||
...
|
||||
file_n: byte[dwadinfo_t[num]->disksize]
|
||||
infotable dlumpinfo_t[dwadinfo_t->numlumps]
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDWAD3HEADER (('3'<<24)+('D'<<16)+('A'<<8)+'W')
|
||||
|
||||
// dlumpinfo_t->compression
|
||||
#define CMP_NONE 0 // compression none
|
||||
#define CMP_LZSS 1 // currently not used
|
||||
#define CMP_ZLIB 2 // zip-archive compression
|
||||
|
||||
// dlumpinfo_t->type
|
||||
#define TYPE_QPAL 64 // quake palette
|
||||
#define TYPE_QTEX 65 // probably was never used
|
||||
#define TYPE_QPIC 66 // quake1 and hl pic (lmp_t)
|
||||
#define TYPE_MIPTEX 67 // half-life (mip_t) previous was TYP_SOUND but never used in quake1
|
||||
#define TYPE_QMIP 68 // quake1 (mip_t) (replaced with TYPE_MIPTEX while loading)
|
||||
#define TYPE_RAW 69 // raw data
|
||||
#define TYPE_QFONT 70 // half-life font (qfont_t)
|
||||
#define TYPE_SOUND 71 // hl2 type
|
||||
#define TYPE_SCRIPT 73 // .qc scripts (xash ext)
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.QFONT image format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define QCHAR_WIDTH 16
|
||||
#define QFONT_WIDTH 16 // valve fonts used contant sizes
|
||||
#define QFONT_HEIGHT ((128 - 32) / 16)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short startoffset;
|
||||
short charwidth;
|
||||
} charset_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int rowcount;
|
||||
int rowheight;
|
||||
charset_t fontinfo[256];
|
||||
byte data[4]; // variable sized
|
||||
} qfont_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
SPRITE MODELS
|
||||
|
||||
.spr extended version (Half-Life compatible sprites with some xash extensions)
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define IDSPRITEHEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') // little-endian "IDSP"
|
||||
#define SPRITE_VERSION 2 // Half-Life sprites
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ST_SYNC = 0,
|
||||
ST_RAND
|
||||
} synctype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FRAME_SINGLE = 0,
|
||||
FRAME_GROUP,
|
||||
FRAME_ANGLED // xash ext
|
||||
} frametype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPR_NORMAL = 0,
|
||||
SPR_ADDITIVE,
|
||||
SPR_INDEXALPHA,
|
||||
SPR_ALPHTEST,
|
||||
SPR_ADDGLOW // xash ext
|
||||
} drawtype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPR_FWD_PARALLEL_UPRIGHT = 0,
|
||||
SPR_FACING_UPRIGHT,
|
||||
SPR_FWD_PARALLEL,
|
||||
SPR_ORIENTED,
|
||||
SPR_FWD_PARALLEL_ORIENTED,
|
||||
} angletype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SPR_CULL_FRONT = 0, // oriented sprite will be draw with one face
|
||||
SPR_CULL_NONE, // oriented sprite will be draw back face too
|
||||
} facetype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident; // LittleLong 'ISPR'
|
||||
int version; // current version 3
|
||||
angletype_t type; // camera align
|
||||
drawtype_t texFormat; // rendering mode (Xash3D ext)
|
||||
int boundingradius; // quick face culling
|
||||
int bounds[2]; // minsmaxs
|
||||
int numframes; // including groups
|
||||
facetype_t facetype; // cullface (Xash3D ext)
|
||||
synctype_t synctype; // animation synctype
|
||||
} dsprite_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int origin[2];
|
||||
int width;
|
||||
int height;
|
||||
} dspriteframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numframes;
|
||||
} dspritegroup_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float interval;
|
||||
} dspriteinterval_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
frametype_t type;
|
||||
} dframetype_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.LMP image format (Half-Life gfx.wad lumps)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct lmp_s
|
||||
{
|
||||
uint width;
|
||||
uint height;
|
||||
} lmp_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MIP image format (half-Life textures)
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
typedef struct mip_s
|
||||
{
|
||||
char name[16];
|
||||
uint width;
|
||||
uint height;
|
||||
uint offsets[4]; // four mip maps stored
|
||||
} mip_t;
|
||||
|
||||
#include "studio.h"
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
ROQ FILES
|
||||
|
||||
The .roq file are vector-compressed movies
|
||||
========================================================================
|
||||
*/
|
||||
#define RoQ_HEADER1 4228
|
||||
#define RoQ_HEADER2 -1
|
||||
#define RoQ_HEADER3 30
|
||||
#define RoQ_FRAMERATE 30
|
||||
|
||||
// RoQ markers
|
||||
#define RoQ_INFO 0x1001
|
||||
#define RoQ_QUAD_CODEBOOK 0x1002
|
||||
#define RoQ_QUAD_VQ 0x1011
|
||||
#define RoQ_SOUND_MONO 0x1020
|
||||
#define RoQ_SOUND_STEREO 0x1021
|
||||
|
||||
// RoQ movie type
|
||||
#define RoQ_ID_MOT 0x00
|
||||
#define RoQ_ID_FCC 0x01
|
||||
#define RoQ_ID_SLD 0x02
|
||||
#define RoQ_ID_CCC 0x03
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte y[4];
|
||||
byte u;
|
||||
byte v;
|
||||
} dcell_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte idx[4];
|
||||
} dquadcell_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
word id;
|
||||
uint size;
|
||||
word argument;
|
||||
} droqchunk_t;
|
||||
|
||||
// other limits
|
||||
#define MAX_KEY 128
|
||||
#define MAX_VALUE 1024
|
||||
|
||||
#endif//REF_DFILES_H
|
|
@ -209,7 +209,7 @@ sfx_t *S_FindName( const char *name, int *pfInCache )
|
|||
S_FreeSound
|
||||
==================
|
||||
*/
|
||||
static void S_FreeSound( sfx_t *sfx )
|
||||
void S_FreeSound( sfx_t *sfx )
|
||||
{
|
||||
sfx_t *hashSfx;
|
||||
sfx_t **prev;
|
||||
|
|
|
@ -89,9 +89,11 @@ S_FreeChannel
|
|||
*/
|
||||
void S_FreeChannel( channel_t *ch )
|
||||
{
|
||||
ch->isSentence = false;
|
||||
ch->sfx = NULL;
|
||||
ch->use_loop = false;
|
||||
ch->isSentence = false;
|
||||
|
||||
Mem_Set( &ch->pMixer, 0, sizeof( ch->pMixer ));
|
||||
|
||||
SND_CloseMouth( ch );
|
||||
}
|
||||
|
@ -156,6 +158,7 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx )
|
|||
int ch_idx;
|
||||
int first_to_die;
|
||||
int life_left;
|
||||
int timeleft;
|
||||
|
||||
// check for replacement sound, or find the best one to replace
|
||||
first_to_die = -1;
|
||||
|
@ -183,9 +186,16 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx )
|
|||
if( ch->sfx && S_IsClient( ch->entnum ) && !S_IsClient( entnum ))
|
||||
continue;
|
||||
|
||||
if( ch->end - paintedtime < life_left )
|
||||
// try to pick the sound with the least amount of data left to play
|
||||
timeleft = 0;
|
||||
if( ch->sfx )
|
||||
{
|
||||
life_left = ch->end - paintedtime;
|
||||
timeleft = 1; //ch->end - paintedtime
|
||||
}
|
||||
|
||||
if( timeleft < life_left )
|
||||
{
|
||||
life_left = timeleft;
|
||||
first_to_die = ch_idx;
|
||||
}
|
||||
}
|
||||
|
@ -497,22 +507,16 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
|||
// Init client entity mouth movement vars
|
||||
SND_InitMouth( ent, chan );
|
||||
|
||||
target_chan->pos = 0;
|
||||
target_chan->end = paintedtime + sfx->cache->samples;
|
||||
|
||||
for( ch_idx = 0, check = channels; ch_idx < MAX_DYNAMIC_CHANNELS; ch_idx++, check++ )
|
||||
{
|
||||
if( check == target_chan ) continue;
|
||||
|
||||
if( check->sfx == sfx && !check->pos )
|
||||
if( check->sfx == sfx && !check->pMixer.sample )
|
||||
{
|
||||
// skip up to 0.1 seconds of audio
|
||||
int skip = Com_RandomLong( 0, (long)( 0.1f * dma.speed ));
|
||||
|
||||
if( skip >= target_chan->end )
|
||||
skip = target_chan->end - 1;
|
||||
target_chan->pos += skip;
|
||||
target_chan->end -= skip;
|
||||
int skip = Com_RandomLong( 0, (long)( 0.1f * check->sfx->cache->rate ));
|
||||
|
||||
S_SetSampleStart( check, sfx->cache, skip );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -606,9 +610,6 @@ void S_StaticSound( const vec3_t pos, int ent, int chan, sound_t handle, float f
|
|||
ch->entnum = ent;
|
||||
ch->entchannel = chan;
|
||||
|
||||
ch->pos = 0;
|
||||
ch->end = paintedtime + sfx->cache->samples;
|
||||
|
||||
SND_Spatialize( ch );
|
||||
}
|
||||
|
||||
|
|
409
snd_dx/s_mix.c
409
snd_dx/s_mix.c
|
@ -129,119 +129,306 @@ CHANNEL MIXING
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
void S_PaintChannelFrom8( channel_t *ch, wavdata_t *sc, int count, int offset )
|
||||
void S_PaintMonoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount )
|
||||
{
|
||||
int data;
|
||||
int *lscale, *rscale;
|
||||
byte *sfx;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
|
||||
if( ch->leftvol > 255 ) ch->leftvol = 255;
|
||||
if( ch->rightvol > 255 ) ch->rightvol = 255;
|
||||
int i, data;
|
||||
int *lscale, *rscale;
|
||||
|
||||
lscale = snd_scaletable[ch->leftvol>>3];
|
||||
rscale = snd_scaletable[ch->rightvol>>3];
|
||||
sfx = (signed char *)sc->buffer + ch->pos;
|
||||
lscale = snd_scaletable[volume[0] >> 3];
|
||||
rscale = snd_scaletable[volume[1] >> 3];
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
for( i = 0; i < count; i++, samp++ )
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
data = sfx[i];
|
||||
samp->left += lscale[data];
|
||||
samp->right += rscale[data];
|
||||
data = pData[i];
|
||||
pbuf[i].left += lscale[data];
|
||||
pbuf[i].right += rscale[data];
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintStereoFrom8( channel_t *ch, wavdata_t *sc, int count, int offset )
|
||||
void S_PaintStereoFrom8( portable_samplepair_t *pbuf, int *volume, byte *pData, int outCount )
|
||||
{
|
||||
int *lscale, *rscale;
|
||||
uint left, right;
|
||||
unsigned short *data;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
|
||||
if( ch->leftvol > 255 ) ch->leftvol = 255;
|
||||
if( ch->rightvol > 255 ) ch->rightvol = 255;
|
||||
|
||||
lscale = snd_scaletable[ch->leftvol>>3];
|
||||
rscale = snd_scaletable[ch->rightvol>>3];
|
||||
data = (unsigned short *)sc->buffer + ch->pos;
|
||||
int *lscale, *rscale;
|
||||
uint left, right;
|
||||
word *data;
|
||||
int i;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
lscale = snd_scaletable[volume[0] >> 3];
|
||||
rscale = snd_scaletable[volume[1] >> 3];
|
||||
data = (word *)pData;
|
||||
|
||||
for( i = 0; i < count; i++, samp++, data++ )
|
||||
for( i = 0; i < outCount; i++, data++ )
|
||||
{
|
||||
left = (byte)((*data & 0x00FF));
|
||||
right = (byte)((*data & 0xFF00) >> 8);
|
||||
samp->left += lscale[left];
|
||||
samp->right += rscale[right];
|
||||
pbuf[i].left += lscale[left];
|
||||
pbuf[i].right += rscale[right];
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintChannelFrom16( channel_t *ch, wavdata_t *sc, int count, int offset )
|
||||
void S_PaintMonoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount )
|
||||
{
|
||||
int data;
|
||||
int left, right;
|
||||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
int i, data;
|
||||
int left, right;
|
||||
int lscale, rscale;
|
||||
|
||||
leftvol = ch->leftvol * snd_vol;
|
||||
rightvol = ch->rightvol * snd_vol;
|
||||
sfx = (signed short *)sc->buffer + ch->pos;
|
||||
lscale = volume[0] * snd_vol;
|
||||
rscale = volume[1] * snd_vol;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
for( i = 0; i < count; i++, samp++ )
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
data = sfx[i];
|
||||
left = ( data * leftvol ) >> 8;
|
||||
right = (data * rightvol) >> 8;
|
||||
samp->left += left;
|
||||
samp->right += right;
|
||||
data = pData[i];
|
||||
left = ( data * lscale ) >> 8;
|
||||
right = (data * rscale ) >> 8;
|
||||
pbuf[i].left += left;
|
||||
pbuf[i].right += right;
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintStereoFrom16( channel_t *ch, wavdata_t *sc, int count, int offset )
|
||||
void S_PaintStereoFrom16( portable_samplepair_t *pbuf, int *volume, short *pData, int outCount )
|
||||
{
|
||||
uint *data;
|
||||
int leftvol, rightvol;
|
||||
int left, right;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
uint *data;
|
||||
int lscale, rscale;
|
||||
int left, right;
|
||||
int i;
|
||||
|
||||
data = (uint *)sc->buffer + ch->pos;
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
leftvol = ch->leftvol * snd_vol;
|
||||
rightvol = ch->rightvol * snd_vol;
|
||||
|
||||
for( i = 0; i < count; i++, samp++, data++ )
|
||||
lscale = volume[0] * snd_vol;
|
||||
rscale = volume[1] * snd_vol;
|
||||
data = (uint *)pData;
|
||||
|
||||
for( i = 0; i < outCount; i++, data++ )
|
||||
{
|
||||
left = (signed short)((*data & 0x0000FFFF));
|
||||
right = (signed short)((*data & 0xFFFF0000) >> 16);
|
||||
|
||||
left = (left * leftvol ) >> 8;
|
||||
right = (right * rightvol) >> 8;
|
||||
left = (left * lscale ) >> 8;
|
||||
right = (right * rscale) >> 8;
|
||||
|
||||
samp->left += left;
|
||||
samp->right += right;
|
||||
pbuf[i].left += left;
|
||||
pbuf[i].right += right;
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_Mix8Mono( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
|
||||
{
|
||||
int i, sampleIndex = 0;
|
||||
uint sampleFrac = inputOffset;
|
||||
int *lscale, *rscale;
|
||||
|
||||
// Not using pitch shift?
|
||||
if( rateScaleFix == FIX( 1 ))
|
||||
{
|
||||
S_PaintMonoFrom8( pbuf, volume, pData, outCount );
|
||||
return;
|
||||
}
|
||||
|
||||
lscale = snd_scaletable[volume[0] >> 3];
|
||||
rscale = snd_scaletable[volume[1] >> 3];
|
||||
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
pbuf[i].left += lscale[pData[sampleIndex]];
|
||||
pbuf[i].right += rscale[pData[sampleIndex]];
|
||||
sampleFrac += rateScaleFix;
|
||||
sampleIndex += FIX_INTPART( sampleFrac );
|
||||
sampleFrac = FIX_FRACPART( sampleFrac );
|
||||
}
|
||||
}
|
||||
|
||||
void S_Mix8Stereo( portable_samplepair_t *pbuf, int *volume, byte *pData, int inputOffset, uint rateScaleFix, int outCount )
|
||||
{
|
||||
int i, sampleIndex = 0;
|
||||
uint sampleFrac = inputOffset;
|
||||
int *lscale, *rscale;
|
||||
|
||||
// Not using pitch shift?
|
||||
if( rateScaleFix == FIX( 1 ))
|
||||
{
|
||||
S_PaintStereoFrom8( pbuf, volume, pData, outCount );
|
||||
return;
|
||||
}
|
||||
|
||||
lscale = snd_scaletable[volume[0] >> 3];
|
||||
rscale = snd_scaletable[volume[1] >> 3];
|
||||
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
pbuf[i].left += lscale[pData[sampleIndex+0]];
|
||||
pbuf[i].right += rscale[pData[sampleIndex+1]];
|
||||
sampleFrac += rateScaleFix;
|
||||
sampleIndex += FIX_INTPART( sampleFrac )<<1;
|
||||
sampleFrac = FIX_FRACPART( sampleFrac );
|
||||
}
|
||||
}
|
||||
|
||||
void S_Mix16Mono( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
|
||||
{
|
||||
int i, sampleIndex = 0;
|
||||
uint sampleFrac = inputOffset;
|
||||
int lscale, rscale;
|
||||
|
||||
// Not using pitch shift?
|
||||
if( rateScaleFix == FIX( 1 ))
|
||||
{
|
||||
S_PaintMonoFrom16( pbuf, volume, pData, outCount );
|
||||
return;
|
||||
}
|
||||
|
||||
lscale = volume[0] * snd_vol;
|
||||
rscale = volume[1] * snd_vol;
|
||||
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
pbuf[i].left += (lscale * (int)( pData[sampleIndex] ))>>8;
|
||||
pbuf[i].right += (rscale * (int)( pData[sampleIndex] ))>>8;
|
||||
sampleFrac += rateScaleFix;
|
||||
sampleIndex += FIX_INTPART( sampleFrac );
|
||||
sampleFrac = FIX_FRACPART( sampleFrac );
|
||||
}
|
||||
}
|
||||
|
||||
void S_Mix16Stereo( portable_samplepair_t *pbuf, int *volume, short *pData, int inputOffset, uint rateScaleFix, int outCount )
|
||||
{
|
||||
int i, sampleIndex = 0;
|
||||
uint sampleFrac = inputOffset;
|
||||
int lscale, rscale;
|
||||
|
||||
// Not using pitch shift?
|
||||
if( rateScaleFix == FIX( 1 ))
|
||||
{
|
||||
S_PaintStereoFrom16( pbuf, volume, pData, outCount );
|
||||
return;
|
||||
}
|
||||
|
||||
lscale = volume[0] * snd_vol;
|
||||
rscale = volume[1] * snd_vol;
|
||||
|
||||
for( i = 0; i < outCount; i++ )
|
||||
{
|
||||
pbuf[i].left += (lscale * (int)( pData[sampleIndex+0] ))>>8;
|
||||
pbuf[i].right += (rscale * (int)( pData[sampleIndex+1] ))>>8;
|
||||
|
||||
sampleFrac += rateScaleFix;
|
||||
sampleIndex += FIX_INTPART(sampleFrac)<<1;
|
||||
sampleFrac = FIX_FRACPART(sampleFrac);
|
||||
}
|
||||
}
|
||||
|
||||
int S_MixDataToDevice( channel_t *pChannel, int sampleCount, int outputRate, int outputOffset )
|
||||
{
|
||||
// save this to compute total output
|
||||
int startingOffset = outputOffset;
|
||||
float inputRate = ( pChannel->pitch * pChannel->sfx->cache->rate );
|
||||
float rate = inputRate / outputRate;
|
||||
int pvol[2];
|
||||
|
||||
// shouldn't be playing this if finished, but return if we are
|
||||
if( pChannel->pMixer.finished )
|
||||
return 0;
|
||||
|
||||
// If we are terminating this wave prematurely, then make sure we detect the limit
|
||||
if( pChannel->pMixer.forcedEndSample )
|
||||
{
|
||||
// how many total input samples will we need?
|
||||
int samplesRequired = (int)(sampleCount * rate);
|
||||
|
||||
// will this hit the end?
|
||||
if( pChannel->pMixer.sample + samplesRequired >= pChannel->pMixer.forcedEndSample )
|
||||
{
|
||||
// yes, mark finished and truncate the sample request
|
||||
pChannel->pMixer.finished = true;
|
||||
sampleCount = (int)(( pChannel->pMixer.forcedEndSample - pChannel->pMixer.sample ) / rate );
|
||||
}
|
||||
}
|
||||
|
||||
pvol[0] = pChannel->leftvol;
|
||||
pvol[1] = pChannel->rightvol;
|
||||
|
||||
while( sampleCount > 0 )
|
||||
{
|
||||
double sampleFraction;
|
||||
portable_samplepair_t *pbuf;
|
||||
bool advanceSample = true;
|
||||
int availableSamples, outputSampleCount;
|
||||
wavdata_t *pSource = pChannel->sfx->cache;
|
||||
bool use_loop = pChannel->use_loop;
|
||||
char *pData = NULL;
|
||||
|
||||
// compute number of input samples required
|
||||
double end = pChannel->pMixer.sample + rate * sampleCount;
|
||||
int inputSampleCount = (int)(ceil( end ) - floor( pChannel->pMixer.sample ));
|
||||
|
||||
availableSamples = S_GetOutputData( pSource, &pData, pChannel->pMixer.sample, inputSampleCount, use_loop );
|
||||
|
||||
// none available, bail out
|
||||
if( !availableSamples ) break;
|
||||
|
||||
sampleFraction = pChannel->pMixer.sample - floor( pChannel->pMixer.sample );
|
||||
|
||||
if( availableSamples < inputSampleCount )
|
||||
{
|
||||
// how many samples are there given the number of input samples and the rate.
|
||||
outputSampleCount = (int)ceil(( availableSamples - sampleFraction ) / rate );
|
||||
}
|
||||
else
|
||||
{
|
||||
outputSampleCount = sampleCount;
|
||||
}
|
||||
|
||||
// Verify that we won't get a buffer overrun.
|
||||
ASSERT( floor( sampleFraction + rate * ( outputSampleCount - 1 )) <= availableSamples );
|
||||
|
||||
// mix this data to all active paintbuffers
|
||||
pbuf = &paintbuffer[outputOffset];
|
||||
|
||||
if( pSource->channels == 1 )
|
||||
{
|
||||
if( pSource->width == 1 )
|
||||
S_Mix8Mono( pbuf, pvol, (char *)pData, FIX_FLOAT(sampleFraction), FIX_FLOAT(rate), outputSampleCount );
|
||||
else S_Mix16Mono( pbuf, pvol, (short *)pData, FIX_FLOAT(sampleFraction), FIX_FLOAT(rate), outputSampleCount );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pSource->width == 1 )
|
||||
S_Mix8Stereo( pbuf, pvol, (char *)pData, FIX_FLOAT(sampleFraction), FIX_FLOAT(rate), outputSampleCount );
|
||||
else S_Mix16Stereo( pbuf, pvol, (short *)pData, FIX_FLOAT(sampleFraction), FIX_FLOAT(rate), outputSampleCount );
|
||||
}
|
||||
|
||||
if( advanceSample )
|
||||
{
|
||||
pChannel->pMixer.sample += outputSampleCount * rate;
|
||||
}
|
||||
|
||||
outputOffset += outputSampleCount;
|
||||
sampleCount -= outputSampleCount;
|
||||
}
|
||||
|
||||
// Did we run out of samples? if so, mark finished
|
||||
if( sampleCount > 0 )
|
||||
{
|
||||
pChannel->pMixer.finished = true;
|
||||
}
|
||||
|
||||
// total number of samples mixed !!! at the output clock rate !!!
|
||||
return outputOffset - startingOffset;
|
||||
}
|
||||
|
||||
bool S_ShouldContinueMixing( channel_t *ch )
|
||||
{
|
||||
if( ch->isSentence )
|
||||
{
|
||||
if( ch->currentWord )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return !ch->pMixer.finished;
|
||||
}
|
||||
|
||||
void S_MixAllChannels( int endtime, int end )
|
||||
{
|
||||
channel_t *ch;
|
||||
wavdata_t *sc;
|
||||
int i, count = 0;
|
||||
int ltime;
|
||||
int i, count = end - paintedtime;
|
||||
|
||||
// paint in the channels.
|
||||
for( i = 0, ch = channels; i < total_channels; i++, ch++ )
|
||||
|
@ -259,74 +446,40 @@ void S_MixAllChannels( int endtime, int end )
|
|||
if( s_listener.inmenu && !ch->localsound )
|
||||
{
|
||||
// play only local sounds, keep pause for other
|
||||
ch->end = paintedtime + sc->samples - ch->pos;
|
||||
continue;
|
||||
}
|
||||
else if( !s_listener.inmenu && !s_listener.active && !ch->staticsound )
|
||||
{
|
||||
// play only ambient sounds, keep pause for other
|
||||
ch->end = paintedtime + sc->samples - ch->pos;
|
||||
continue;
|
||||
}
|
||||
else if( s_listener.paused )
|
||||
{
|
||||
// play only ambient sounds, keep pause for other
|
||||
ch->end = paintedtime + sc->samples - ch->pos;
|
||||
continue;
|
||||
}
|
||||
|
||||
ltime = paintedtime;
|
||||
|
||||
while( ltime < end )
|
||||
// get playback pitch
|
||||
if( ch->isSentence )
|
||||
ch->pitch = VOX_ModifyPitch( ch, ch->basePitch * 0.01f );
|
||||
else ch->pitch = ch->basePitch * 0.01f;
|
||||
|
||||
// check volume
|
||||
ch->leftvol = bound( 0, ch->leftvol, 255 );
|
||||
ch->rightvol = bound( 0, ch->rightvol, 255 );
|
||||
|
||||
if( si.GetClientEdict( ch->entnum ) && ( ch->entchannel == CHAN_VOICE ))
|
||||
{
|
||||
// max painting is to the end of the buffer
|
||||
count = end - ltime;
|
||||
SND_MoveMouth8( ch, sc, count );
|
||||
}
|
||||
|
||||
// might be stopped by running out of data
|
||||
if( ch->end - ltime < count ) count = ch->end - ltime;
|
||||
if( ch->isSentence )
|
||||
VOX_MixDataToDevice( ch, count, dma.speed, 0 );
|
||||
else S_MixDataToDevice( ch, count, dma.speed, 0 );
|
||||
|
||||
if( count > 0 )
|
||||
{
|
||||
if( sc->channels == 1 )
|
||||
{
|
||||
if( sc->width == 1 )
|
||||
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
|
||||
else S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sc->width == 1 )
|
||||
S_PaintStereoFrom8( ch, sc, count, ltime - paintedtime );
|
||||
else S_PaintStereoFrom16( ch, sc, count, ltime - paintedtime );
|
||||
}
|
||||
ltime += count;
|
||||
}
|
||||
|
||||
if( si.GetClientEdict( ch->entnum ) && ( ch->entchannel == CHAN_VOICE ))
|
||||
{
|
||||
SND_MoveMouth8( ch, sc, count );
|
||||
}
|
||||
|
||||
// if at end of loop, restart
|
||||
if( ltime >= ch->end )
|
||||
{
|
||||
if( ch->isSentence )
|
||||
{
|
||||
sc = VOX_LoadNextWord( ch );
|
||||
if( !sc ) break; // sentence is finished
|
||||
}
|
||||
else if( sc->loopStart >= 0 && ch->use_loop )
|
||||
{
|
||||
ch->pos = sc->loopStart;
|
||||
ch->end = ltime + sc->samples - ch->pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
// channel just stopped
|
||||
S_FreeChannel( ch );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !S_ShouldContinueMixing( ch ))
|
||||
{
|
||||
S_FreeChannel( ch );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ void SND_MoveMouth8( channel_t *ch, wavdata_t *pSource, int count )
|
|||
char *pdata = NULL;
|
||||
mouth_t *pMouth = NULL;
|
||||
int savg, data;
|
||||
int scount;
|
||||
int scount, pos = 0;
|
||||
uint i;
|
||||
|
||||
clientEntity = si.GetClientEdict( ch->entnum );
|
||||
|
@ -56,7 +56,14 @@ void SND_MoveMouth8( channel_t *ch, wavdata_t *pSource, int count )
|
|||
|
||||
pMouth = &clientEntity->mouth;
|
||||
|
||||
count = S_GetOutputData( pSource, &pdata, ch->pos, count );
|
||||
if( ch->isSentence )
|
||||
{
|
||||
if( ch->currentWord )
|
||||
pos = ch->currentWord->sample;
|
||||
}
|
||||
else pos = ch->pMixer.sample;
|
||||
|
||||
count = S_GetOutputData( pSource, &pdata, pos, count, ch->use_loop );
|
||||
if( pdata == NULL ) return;
|
||||
|
||||
i = 0;
|
||||
|
|
|
@ -206,13 +206,13 @@ int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample )
|
|||
// Input : samplePosition - absolute position
|
||||
// Output : int - looped position
|
||||
//-----------------------------------------------------------------------------
|
||||
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition )
|
||||
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, bool use_loop )
|
||||
{
|
||||
// if the wave is looping and we're past the end of the sample
|
||||
// convert to a position within the loop
|
||||
// At the end of the loop, we return a short buffer, and subsequent call
|
||||
// will loop back and get the rest of the buffer
|
||||
if( pSource->loopStart >= 0 && samplePosition >= pSource->samples )
|
||||
if( pSource->loopStart >= 0 && samplePosition >= pSource->samples && use_loop )
|
||||
{
|
||||
// size of loop
|
||||
int loopSize = pSource->samples - pSource->loopStart;
|
||||
|
@ -230,13 +230,13 @@ int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition )
|
|||
return samplePosition;
|
||||
}
|
||||
|
||||
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount )
|
||||
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, bool use_loop )
|
||||
{
|
||||
int totalSampleCount;
|
||||
int sampleSize;
|
||||
|
||||
// handle position looping
|
||||
samplePosition = S_ConvertLoopedPosition( pSource, samplePosition );
|
||||
samplePosition = S_ConvertLoopedPosition( pSource, samplePosition, use_loop );
|
||||
|
||||
// how many samples are available (linearly not counting looping)
|
||||
totalSampleCount = pSource->samples - samplePosition;
|
||||
|
@ -264,4 +264,29 @@ int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int s
|
|||
}
|
||||
|
||||
return sampleCount;
|
||||
}
|
||||
|
||||
// move the current position to newPosition
|
||||
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition )
|
||||
{
|
||||
if( pSource )
|
||||
newPosition = S_ZeroCrossingAfter( pSource, newPosition );
|
||||
|
||||
pChan->pMixer.sample = newPosition;
|
||||
}
|
||||
|
||||
// end playback at newEndPosition
|
||||
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition )
|
||||
{
|
||||
// forced end of zero means play the whole sample
|
||||
if( !newEndPosition ) newEndPosition = 1;
|
||||
|
||||
if( pSource )
|
||||
newEndPosition = S_ZeroCrossingBefore( pSource, newEndPosition );
|
||||
|
||||
// past current position? limit.
|
||||
if( newEndPosition < pChan->pMixer.sample )
|
||||
newEndPosition = pChan->pMixer.sample;
|
||||
|
||||
pChan->pMixer.forcedEndSample = newEndPosition;
|
||||
}
|
119
snd_dx/s_vox.c
119
snd_dx/s_vox.c
|
@ -51,7 +51,7 @@ static char *ScanForwardUntil( char *string, char scan )
|
|||
{
|
||||
while( string[0] )
|
||||
{
|
||||
if ( string[0] == scan )
|
||||
if( string[0] == scan )
|
||||
return string;
|
||||
string++;
|
||||
}
|
||||
|
@ -65,13 +65,13 @@ static char *VOX_GetDirectory( char *szpath, char *psz )
|
|||
{
|
||||
char c;
|
||||
int cb = 0;
|
||||
char *pszscan = psz + com.strlen( psz ) - 1;
|
||||
char *p = psz + com.strlen( psz ) - 1;
|
||||
|
||||
// scan backwards until first '/' or start of string
|
||||
c = *pszscan;
|
||||
while( pszscan > psz && c != '/' )
|
||||
c = *p;
|
||||
while( p > psz && c != '/' )
|
||||
{
|
||||
c = *( --pszscan );
|
||||
c = *( --p );
|
||||
cb++;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ static char *VOX_GetDirectory( char *szpath, char *psz )
|
|||
Mem_Copy( szpath, psz, cb );
|
||||
szpath[cb] = 0;
|
||||
|
||||
return pszscan + 1;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
// scan g_Sentences, looking for pszin sentence name
|
||||
|
@ -121,7 +121,7 @@ char *VOX_LookupString( const char *pSentenceName, int *psentencenum )
|
|||
char **VOX_ParseString( char *psz )
|
||||
{
|
||||
int i, fdone = 0;
|
||||
char c, *pszscan = psz;
|
||||
char c, *p = psz;
|
||||
|
||||
Mem_Set( rgpparseword, 0, sizeof( char* ) * CVOXWORDMAX );
|
||||
|
||||
|
@ -133,15 +133,15 @@ char **VOX_ParseString( char *psz )
|
|||
while( !fdone && i < CVOXWORDMAX )
|
||||
{
|
||||
// scan up to next word
|
||||
c = *pszscan;
|
||||
c = *p;
|
||||
while( c && !IsNextWord( c ))
|
||||
c = *(++pszscan);
|
||||
c = *(++p);
|
||||
|
||||
// if '(' then scan for matching ')'
|
||||
if( c == '(' )
|
||||
{
|
||||
pszscan = ScanForwardUntil( pszscan, ')' );
|
||||
c = *(++pszscan);
|
||||
p = ScanForwardUntil( p, ')' );
|
||||
c = *(++p);
|
||||
if( !c ) fdone = 1;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ char **VOX_ParseString( char *psz )
|
|||
{
|
||||
// if . or , insert pause into rgpparseword,
|
||||
// unless this is the last character
|
||||
if(( c == '.' || c == ',' ) && *(pszscan+1) != '\n' && *(pszscan+1) != '\r' && *(pszscan+1) != 0 )
|
||||
if(( c == '.' || c == ',' ) && *(p+1) != '\n' && *(p+1) != '\r' && *(p+1) != 0 )
|
||||
{
|
||||
if( c == '.' ) rgpparseword[i++] = voxperiod;
|
||||
else rgpparseword[i++] = voxcomma;
|
||||
|
@ -163,15 +163,15 @@ char **VOX_ParseString( char *psz )
|
|||
}
|
||||
|
||||
// null terminate substring
|
||||
*pszscan++ = 0;
|
||||
*p++ = 0;
|
||||
|
||||
// skip whitespace
|
||||
c = *pszscan;
|
||||
c = *p;
|
||||
while( c && IsSkipSpace( c ))
|
||||
c = *(++pszscan);
|
||||
c = *(++p);
|
||||
|
||||
if( !c ) fdone = 1;
|
||||
else rgpparseword[i++] = pszscan;
|
||||
else rgpparseword[i++] = p;
|
||||
}
|
||||
}
|
||||
return rgpparseword;
|
||||
|
@ -179,7 +179,7 @@ char **VOX_ParseString( char *psz )
|
|||
|
||||
float VOX_GetVolumeScale( channel_t *pchan )
|
||||
{
|
||||
if( pchan->currentWord.pData )
|
||||
if( pchan->currentWord )
|
||||
{
|
||||
if ( pchan->words[pchan->wordIndex].volume )
|
||||
{
|
||||
|
@ -194,7 +194,7 @@ void VOX_SetChanVol( channel_t *ch )
|
|||
{
|
||||
float scale;
|
||||
|
||||
if( !ch->currentWord.pData )
|
||||
if( !ch->currentWord )
|
||||
return;
|
||||
|
||||
scale = VOX_GetVolumeScale( ch );
|
||||
|
@ -204,6 +204,18 @@ void VOX_SetChanVol( channel_t *ch )
|
|||
ch->leftvol = (int)(ch->leftvol * scale);
|
||||
}
|
||||
|
||||
float VOX_ModifyPitch( channel_t *ch, float pitch )
|
||||
{
|
||||
if( ch->currentWord )
|
||||
{
|
||||
if ( ch->words[ch->wordIndex].pitch > 0 )
|
||||
{
|
||||
pitch += ( ch->words[ch->wordIndex].pitch - PITCH_NORM ) * 0.01f;
|
||||
}
|
||||
}
|
||||
return pitch;
|
||||
}
|
||||
|
||||
//===============================================================================
|
||||
// Get any pitch, volume, start, end params into voxword
|
||||
// and null out trailing format characters
|
||||
|
@ -325,6 +337,10 @@ void VOX_LoadWord( channel_t *pchan )
|
|||
{
|
||||
int start = pchan->words[pchan->wordIndex].start;
|
||||
int end = pchan->words[pchan->wordIndex].end;
|
||||
|
||||
// apply mixer
|
||||
pchan->currentWord = &pchan->pMixer;
|
||||
pchan->currentWord->pData = pSource;
|
||||
|
||||
// don't allow overlapped ranges
|
||||
if( end <= start ) end = 0;
|
||||
|
@ -335,22 +351,31 @@ void VOX_LoadWord( channel_t *pchan )
|
|||
|
||||
if( start )
|
||||
{
|
||||
pchan->currentWord.sample = S_ZeroCrossingAfter( pSource, (int)(sampleCount * 0.01f * start));
|
||||
S_SetSampleStart( pchan, pSource, (int)(sampleCount * 0.01f * start));
|
||||
}
|
||||
|
||||
if( end )
|
||||
{
|
||||
pchan->currentWord.forcedEndSample = S_ZeroCrossingBefore( pSource, (int)(sampleCount * 0.01f * end) );
|
||||
|
||||
// past current position? limit.
|
||||
if( pchan->currentWord.forcedEndSample < pchan->currentWord.sample )
|
||||
pchan->currentWord.forcedEndSample = pchan->currentWord.sample;
|
||||
S_SetSampleEnd( pchan, pSource, (int)(sampleCount * 0.01f * end));
|
||||
}
|
||||
}
|
||||
pchan->currentWord.pData = pSource;
|
||||
}
|
||||
}
|
||||
else pchan->currentWord.pData = NULL; // sentence is finished
|
||||
}
|
||||
|
||||
void VOX_FreeWord( channel_t *pchan )
|
||||
{
|
||||
pchan->currentWord = NULL; // sentence is finished
|
||||
Mem_Set( &pchan->pMixer, 0, sizeof( pchan->pMixer ));
|
||||
|
||||
if( pchan->words[pchan->wordIndex].sfx )
|
||||
{
|
||||
// If this wave wasn't precached by the game code
|
||||
if( !pchan->words[pchan->wordIndex].fKeepCached )
|
||||
{
|
||||
S_FreeSound( pchan->words[pchan->wordIndex].sfx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VOX_LoadFirstWord( channel_t *pchan, voxword_t *pwords )
|
||||
|
@ -369,22 +394,36 @@ void VOX_LoadFirstWord( channel_t *pchan, voxword_t *pwords )
|
|||
VOX_LoadWord( pchan );
|
||||
}
|
||||
|
||||
wavdata_t *VOX_LoadNextWord( channel_t *pchan )
|
||||
// return number of samples mixed
|
||||
int VOX_MixDataToDevice( channel_t *pchan, int sampleCount, int outputRate, int outputOffset )
|
||||
{
|
||||
pchan->wordIndex++;
|
||||
VOX_LoadWord( pchan );
|
||||
// save this to compute total output
|
||||
int startingOffset = outputOffset;
|
||||
|
||||
// set new word
|
||||
if( pchan->currentWord.pData )
|
||||
if( !pchan->currentWord )
|
||||
return 0;
|
||||
|
||||
while( sampleCount > 0 && pchan->currentWord )
|
||||
{
|
||||
pchan->sfx = pchan->words[pchan->wordIndex].sfx;
|
||||
pchan->pos = pchan->currentWord.sample;
|
||||
pchan->end = paintedtime + pchan->currentWord.forcedEndSample;
|
||||
return pchan->currentWord.pData;
|
||||
}
|
||||
int outputCount = S_MixDataToDevice( pchan, sampleCount, outputRate, outputOffset );
|
||||
|
||||
S_FreeChannel( pchan ); // channel stopped
|
||||
return NULL;
|
||||
outputOffset += outputCount;
|
||||
sampleCount -= outputCount;
|
||||
|
||||
// if we finished load a next word
|
||||
if( pchan->currentWord->finished )
|
||||
{
|
||||
VOX_FreeWord( pchan );
|
||||
pchan->wordIndex++;
|
||||
VOX_LoadWord( pchan );
|
||||
|
||||
if( pchan->currentWord )
|
||||
{
|
||||
pchan->sfx = pchan->words[pchan->wordIndex].sfx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputOffset - startingOffset;
|
||||
}
|
||||
|
||||
// link all sounds in sentence, start playing first word.
|
||||
|
@ -514,7 +553,6 @@ void VOX_ParseLineCommands( char *pSentenceData, int sentenceIndex )
|
|||
g_Sentences[sentenceIndex].length = com.atof( pSentenceData + 3 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
|
@ -599,8 +637,7 @@ void VOX_ReadSentenceFile( const char *psentenceFileName )
|
|||
pch++;
|
||||
|
||||
// insert null terminator
|
||||
if( pch < pchlast )
|
||||
*pch++ = 0;
|
||||
if( pch < pchlast ) *pch++ = 0;
|
||||
|
||||
// If we have some sentence data, parse out any line commands
|
||||
if( pSentenceData && pSentenceData < pchlast )
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: snd_dx - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
snd_dx.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -22,6 +22,16 @@ extern byte *sndpool;
|
|||
#define SND_LOCALSOUND (1<<9) // not paused, not looped, for internal use
|
||||
#define SND_STOP_LOOPING (1<<10) // stop all looping sounds on the entity.
|
||||
|
||||
// fixed point stuff for real-time resampling
|
||||
#define FIX_BITS 28
|
||||
#define FIX_SCALE (1 << FIX_BITS)
|
||||
#define FIX_MASK ((1 << FIX_BITS)-1)
|
||||
#define FIX_FLOAT(a) ((int)((a) * FIX_SCALE))
|
||||
#define FIX(a) (((int)(a)) << FIX_BITS)
|
||||
#define FIX_INTPART(a) (((int)(a)) >> FIX_BITS)
|
||||
#define FIX_FRACTION(a,b) (FIX(a)/(b))
|
||||
#define FIX_FRACPART(a) ((a) & FIX_MASK)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
|
@ -68,15 +78,12 @@ typedef struct
|
|||
|
||||
wavdata_t *pData;
|
||||
double forcedEndSample;
|
||||
bool m_finished;
|
||||
int delaySamples;
|
||||
bool finished;
|
||||
} mixer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; // sfx number
|
||||
int end; // end time in global paintsamples
|
||||
int pos; // sample position in sfx
|
||||
|
||||
int leftvol; // 0-255 left volume
|
||||
int rightvol; // 0-255 right volume
|
||||
|
@ -92,10 +99,11 @@ typedef struct
|
|||
bool use_loop; // don't loop default and local sounds
|
||||
bool staticsound; // use origin instead of fetching entnum's origin
|
||||
bool localsound; // it's a local menu sound (not looped, not paused)
|
||||
mixer_t pMixer;
|
||||
|
||||
// sentence mixer
|
||||
int wordIndex;
|
||||
mixer_t currentWord;
|
||||
mixer_t *currentWord; // NULL if sentence is finished
|
||||
voxword_t words[CVOXWORDMAX];
|
||||
} channel_t;
|
||||
|
||||
|
@ -175,11 +183,16 @@ void S_PrintDeviceName( void );
|
|||
void S_FreeChannel( channel_t *ch );
|
||||
void S_BeginFrame( void );
|
||||
|
||||
//
|
||||
// s_mix.c
|
||||
//
|
||||
int S_MixDataToDevice( channel_t *pChannel, int sampleCount, int outputRate, int outputOffset );
|
||||
|
||||
// s_load.c
|
||||
bool S_TestSoundChar( const char *pch, char c );
|
||||
char *S_SkipSoundChar( const char *pch );
|
||||
sfx_t *S_FindName( const char *name, int *pfInCache );
|
||||
void S_FreeSound( sfx_t *sfx );
|
||||
|
||||
// s_dsp.c
|
||||
void SX_Init( void );
|
||||
|
@ -227,7 +240,9 @@ void S_StopBackgroundTrack( void );
|
|||
//
|
||||
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
|
||||
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
|
||||
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount );
|
||||
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, bool use_loop );
|
||||
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition );
|
||||
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition );
|
||||
|
||||
//
|
||||
// s_vox.c
|
||||
|
@ -236,8 +251,8 @@ void VOX_Init( void );
|
|||
void VOX_Shutdown( void );
|
||||
void VOX_SetChanVol( channel_t *ch );
|
||||
void VOX_LoadSound( channel_t *pchan, const char *psz );
|
||||
wavdata_t *VOX_LoadNextWord( channel_t *pchan );
|
||||
|
||||
float VOX_ModifyPitch( channel_t *ch, float pitch );
|
||||
int VOX_MixDataToDevice( channel_t *pChannel, int sampleCount, int outputRate, int outputOffset );
|
||||
|
||||
void S_BeginRegistration( void );
|
||||
sound_t S_RegisterSound( const char *sample );
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: vid_gl - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
vid_gl.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: xtools - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
xtools.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue