13 Sep 2010

This commit is contained in:
g-cont 2010-09-13 00:00:00 +04:00 committed by Alibek Omarov
parent 9835598587
commit c44aba6a7d
18 changed files with 439 additions and 640 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 ));
int skip = Com_RandomLong( 0, (long)( 0.1f * check->sfx->cache->rate ));
if( skip >= target_chan->end )
skip = target_chan->end - 1;
target_chan->pos += skip;
target_chan->end -= skip;
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 );
}

View File

@ -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;
int i, data;
int *lscale, *rscale;
if( ch->leftvol > 255 ) ch->leftvol = 255;
if( ch->rightvol > 255 ) ch->rightvol = 255;
lscale = snd_scaletable[volume[0] >> 3];
rscale = snd_scaletable[volume[1] >> 3];
lscale = snd_scaletable[ch->leftvol>>3];
rscale = snd_scaletable[ch->rightvol>>3];
sfx = (signed char *)sc->buffer + ch->pos;
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;
int *lscale, *rscale;
uint left, right;
word *data;
int i;
if( ch->leftvol > 255 ) ch->leftvol = 255;
if( ch->rightvol > 255 ) ch->rightvol = 255;
lscale = snd_scaletable[volume[0] >> 3];
rscale = snd_scaletable[volume[1] >> 3];
data = (word *)pData;
lscale = snd_scaletable[ch->leftvol>>3];
rscale = snd_scaletable[ch->rightvol>>3];
data = (unsigned short *)sc->buffer + ch->pos;
samp = &paintbuffer[offset];
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];
lscale = volume[0] * snd_vol;
rscale = volume[1] * snd_vol;
data = (uint *)pData;
leftvol = ch->leftvol * snd_vol;
rightvol = ch->rightvol * snd_vol;
for( i = 0; i < count; i++, samp++, data++ )
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;
// get playback pitch
if( ch->isSentence )
ch->pitch = VOX_ModifyPitch( ch, ch->basePitch * 0.01f );
else ch->pitch = ch->basePitch * 0.01f;
while( ltime < end )
// 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 );
}
}
}

View File

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

View File

@ -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;
@ -265,3 +265,28 @@ 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;
}

View File

@ -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
@ -326,6 +338,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 )

View File

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

View File

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

View File

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

View File

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