15 Jun 2008

This commit is contained in:
g-cont 2008-06-15 00:00:00 +04:00 committed by Alibek Omarov
parent bee955e12f
commit eacc0fb70e
38 changed files with 694 additions and 3529 deletions

View File

@ -800,7 +800,7 @@ void CreateDirectLights (void)
{
e = &entities[i];
name = ValueForKey (e, "classname");
if (strncmp (name, "light", 5))
if( com.strncmp (name, "light", 5 ))
continue;
numdlights++;
@ -819,9 +819,8 @@ void CreateDirectLights (void)
dl->next = directlights[cluster];
directlights[cluster] = dl;
intensity = FloatForKey (e, "light");
if (!intensity)
intensity = FloatForKey (e, "_light");
intensity = FloatForKey( e, "light" );
if( !intensity ) intensity = FloatForKey( e, "_light" );
if (!intensity)
intensity = 300;
_color = ValueForKey (e, "_color");

View File

@ -71,5 +71,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
quake.exe -log -game tmpQuArK -debug -dev 3 +map walk_test
quake.exe -log -game tmpQuArK -debug -dev 3 +map start
:done

View File

@ -12,8 +12,8 @@ cvar_t *con_speed;
vec4_t console_color = {1.0, 1.0, 1.0, 1.0};
int g_console_field_width = 78;
#define NUM_CON_TIMES 4
#define CON_TEXTSIZE MAX_INPUTLINE * 8 // 128 kb buffer
#define NUM_CON_TIMES 5 // need for 4 lines
#define CON_TEXTSIZE MAX_INPUTLINE * 8 // 128 kb buffer
#define DEFAULT_CONSOLE_WIDTH 78
typedef struct
@ -53,7 +53,7 @@ void Con_ToggleConsole_f (void)
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;
Con_ClearNotify ();
Con_ClearNotify();
if (cls.key_dest == key_console)
{
@ -90,7 +90,7 @@ void Con_ToggleChat_f (void)
}
else cls.key_dest = key_console;
Con_ClearNotify ();
Con_ClearNotify();
}
/*
@ -112,12 +112,12 @@ void Con_Clear_f (void)
Con_ClearNotify
================
*/
void Con_ClearNotify (void)
void Con_ClearNotify( void )
{
int i;
for (i = 0; i < NUM_CON_TIMES; i++)
con.times[i] = 0;
for( i = 0; i < NUM_CON_TIMES; i++ )
con.times[i] = 0.0f;
}
@ -234,7 +234,7 @@ void Con_Init (void)
Cmd_AddCommand ("messagemode2", Con_MessageMode2_f, "input a chat message to say to only your team" );
Cmd_AddCommand ("clear", Con_Clear_f, "clear console history" );
con.initialized = true;
MsgDev(D_INFO, "Console initialized.\n");
MsgDev( D_NOTE, "Console initialized.\n" );
}
@ -243,14 +243,14 @@ void Con_Init (void)
Con_Linefeed
===============
*/
void Con_Linefeed (bool skipnotify)
void Con_Linefeed( bool skipnotify )
{
int i;
// mark time for transparent overlay
if (con.current >= 0)
{
if(skipnotify) con.times[con.current % NUM_CON_TIMES] = 0.0f;
if( skipnotify ) con.times[con.current % NUM_CON_TIMES] = 0.0f;
else con.times[con.current % NUM_CON_TIMES] = cls.realtime;
}
@ -280,7 +280,7 @@ void Con_Print( const char *txt )
if(host.type == HOST_DEDICATED) return;
if(!con.initialized) return;
if(!strncmp( txt, "[skipnotify]", 12 ))
if(!com.strncmp( txt, "[skipnotify]", 12 ))
{
skipnotify = true;
txt += 12;
@ -330,9 +330,9 @@ void Con_Print( const char *txt )
}
// mark time for transparent overlay
if (con.current >= 0)
if( con.current >= 0 )
{
if ( skipnotify )
if( skipnotify )
{
prev = con.current % NUM_CON_TIMES - 1;
if ( prev < 0 ) prev = NUM_CON_TIMES - 1;
@ -389,22 +389,22 @@ void Con_DrawNotify( void )
currentColor = 7;
re->SetColor( g_color_table[currentColor] );
for (i = con.current - NUM_CON_TIMES + 1; i <= con.current; i++)
for( i = con.current - NUM_CON_TIMES + 1; i <= con.current; i++ )
{
if (i < 0) continue;
if( i < 0 ) continue;
time = con.times[i % NUM_CON_TIMES];
if (time == 0) continue;
if( time == 0.0f ) continue;
time = cls.realtime - time;
if (time > con_notifytime->value) continue;
if( time > con_notifytime->value ) continue;
text = con.text + (i % con.totallines) * con.linewidth;
for (x = 0 ; x < con.linewidth ; x++)
for( x = 0; x < con.linewidth; x++)
{
if ( ( text[x] & 0xff ) == ' ' ) continue;
if ( ( (text[x]>>8)&7 ) != currentColor )
if((text[x] & 0xff ) == ' ' ) continue;
if(((text[x]>>8)&7 ) != currentColor )
{
currentColor = (text[x]>>8)&7;
re->SetColor( g_color_table[currentColor] );
re->SetColor(g_color_table[currentColor]);
}
SCR_DrawSmallChar( con.xadjust + (x+1)*SMALLCHAR_WIDTH, v, text[x] & 0xff );
}
@ -414,7 +414,7 @@ void Con_DrawNotify( void )
re->SetColor( NULL );
// draw the chat line
if ( cls.key_dest == key_message )
if( cls.key_dest == key_message )
{
if (chat_team)
{
@ -625,7 +625,7 @@ void Con_Bottom( void )
void Con_Close( void )
{
Field_Clear( &g_consoleField );
Con_ClearNotify ();
Con_ClearNotify();
con.finalFrac = 0; // none visible
con.displayFrac = 0;
}

View File

@ -76,12 +76,11 @@ int CL_ParseEntityBits( sizebuf_t *msg, uint *bits )
}
// count the bits for net profiling
for (i = 0; i < 32; i++)
if (total&(1<<i)) bitcounts[i]++;
for( i = 0; i < 32; i++ )
if( total&(1<<i)) bitcounts[i]++;
if (total & U_NUMBER16) number = MSG_ReadShort (msg);
else number = MSG_ReadByte (msg);
*bits = total;
return number;
@ -162,8 +161,7 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram
// delta from the entities present in oldframe
oldindex = 0;
if (!oldframe)
oldnum = 99999;
if( !oldframe ) oldnum = 99999;
else
{
if (oldindex >= oldframe->num_entities)
@ -182,7 +180,7 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram
Host_Error("CL_ParsePacketEntities: bad number:%i\n", newnum);
if (msg->readcount > msg->cursize)
Host_Error("CL_ParsePacketEntities: end of message\n");
Host_Error("CL_ParsePacketEntities: end of message %d > %d\n", msg->readcount, msg->cursize );
if (!newnum) break;
@ -204,16 +202,14 @@ void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newfram
}
if (bits & U_REMOVE)
{ // the entity present in oldframe is not in the current frame
if (cl_shownet->value == 3)
Msg (" remove: %i\n", newnum);
if (oldnum != newnum)
Msg ("U_REMOVE: oldnum != newnum\n");
{
// the entity present in oldframe is not in the current frame
if( cl_shownet->value == 3 ) Msg(" remove: %i\n", newnum);
if( oldnum != newnum ) Msg("U_REMOVE: oldnum != newnum\n");
oldindex++;
if (oldindex >= oldframe->num_entities)
oldnum = 99999;
if( oldindex >= oldframe->num_entities ) oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
@ -963,7 +959,7 @@ void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity )
}
// if a brush model, offset the origin
if( cent->current.solid == SOLID_BMODEL )
if( VectorIsNull( origin ))
{
cmodel = cl.model_clip[cent->current.modelindex];
if(!cmodel) return;
@ -994,6 +990,7 @@ void CL_AddLoopingSounds( void )
{
num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
ent = &cl_parse_entities[num];
if(!ent->soundindex) continue;
se->AddLoopingSound( ent->number, cl.sound_precache[ent->soundindex], 1.0f, ATTN_IDLE );
}
}

View File

@ -88,20 +88,21 @@ void CL_RunLightStyles (void)
}
void CL_SetLightstyle (int i)
void CL_SetLightstyle( int i )
{
char *s;
int j, k;
s = cl.configstrings[i+CS_LIGHTS];
j = strlen (s);
if (j >= MAX_QPATH)
Host_Error("CL_SetLightStyle: lightstyle %s is too long\n", s );
Msg("CL_SetLightStyle: %d (%s)\n", i, s );
j = com.strlen( s );
if( j >= MAX_QPATH ) Host_Error("CL_SetLightStyle: lightstyle %s is too long\n", s );
cl_lightstyle[i].length = j;
for (k=0 ; k<j ; k++)
for( k = 0; k < j; k++ )
cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
}
@ -279,11 +280,9 @@ typedef struct cparticle_s
#define PARTICLE_GRAVITY 40
*/
cparticle_t *active_particles, *free_particles;
cparticle_t particles[MAX_PARTICLES];
int cl_numparticles = MAX_PARTICLES;
cparticle_t *active_particles, *free_particles;
cparticle_t particles[MAX_PARTICLES];
int cl_numparticles = MAX_PARTICLES;
/*
@ -291,16 +290,16 @@ int cl_numparticles = MAX_PARTICLES;
CL_ClearParticles
===============
*/
void CL_ClearParticles (void)
void CL_ClearParticles( void )
{
int i;
free_particles = &particles[0];
active_particles = NULL;
for (i=0 ;i<cl_numparticles ; i++)
particles[i].next = &particles[i+1];
particles[cl_numparticles-1].next = NULL;
for( i = 0; i < cl_numparticles; i++ )
particles[i].next = &particles[i + 1];
particles[cl_numparticles - 1].next = NULL;
}
@ -344,6 +343,54 @@ void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count)
}
}
/*
===============
CL_TeleportSplash
===============
*/
void CL_TeleportSplash( vec3_t org )
{
int i, j, k;
cparticle_t *p;
float vel;
vec3_t dir;
for( i = -16; i < 16; i += 4 )
{
for( j = -16; j < 16; j += 4 )
{
for( k = -24; k < 32; k += 4 )
{
if(!free_particles) return;
p = free_particles;
free_particles = p->next;
p->next = active_particles;
active_particles = p;
p->time = cl.time + RANDOM_FLOAT( 0.02f, 0.2f );
p->color = 0xdb;
dir[0] = j * 8;
dir[1] = i * 8;
dir[2] = k * 8;
p->org[0] = org[0] + i + (rand()&3);
p->org[1] = org[1] + j + (rand()&3);
p->org[2] = org[2] + k + (rand()&3);
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alphavel = -0.5;
p->alpha = 1.0;
VectorNormalize( dir );
vel = 50 + (rand()&63);
VectorScale( dir, vel, p->vel );
}
}
}
}
/*
===============
@ -1380,14 +1427,14 @@ void CL_AddParticles (void)
active = NULL;
tail = NULL;
for (p=active_particles ; p ; p=next)
for( p = active_particles; p; p = next )
{
next = p->next;
// PMM - added INSTANT_PARTICLE handling for heat beam
if (p->alphavel != INSTANT_PARTICLE)
if( p->alphavel != INSTANT_PARTICLE )
{
time = (cl.time - p->time)*0.001;
time = (cl.time - p->time);
alpha = p->alpha + time*p->alphavel;
if (alpha <= 0)
{ // faded out

View File

@ -241,7 +241,7 @@ void Field_CompleteCommand( field_t *field )
{
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING );
}
else if(!stricmp(Cmd_Argv(0), "play" ) || !stricmp(Cmd_Argv(0), "\\play" ))
else if(!stricmp(Cmd_Argv(0), "playsound" ) || !stricmp(Cmd_Argv(0), "\\playsound" ))
{
result = Cmd_GetSoundList(Cmd_Argv(1), filename, MAX_STRING );
}
@ -261,11 +261,15 @@ void Field_CompleteCommand( field_t *field )
{
result = Cmd_GetFontList(Cmd_Argv(1), filename, MAX_STRING );
}
else if(!stricmp(Cmd_Argv(0), "music" ) || !stricmp(Cmd_Argv(0), "\\music" ))
{
result = Cmd_GetMusicList(Cmd_Argv(1), filename, MAX_STRING );
}
if( result )
{
com.sprintf( completionField->buffer, "%s %s", Cmd_Argv(0), filename );
completionField->cursor = strlen( completionField->buffer );
completionField->cursor = com.strlen( completionField->buffer );
return;
}
}
@ -273,9 +277,9 @@ void Field_CompleteCommand( field_t *field )
if( matchCount == 1 )
{
com.sprintf( completionField->buffer, "\\%s", shortestMatch );
if ( Cmd_Argc() == 1 ) strncat( completionField->buffer, " ", sizeof( completionField->buffer ));
if ( Cmd_Argc() == 1 ) com.strncat( completionField->buffer, " ", sizeof( completionField->buffer ));
else ConcatRemaining( temp.buffer, completionString );
completionField->cursor = strlen( completionField->buffer );
completionField->cursor = com.strlen( completionField->buffer );
return;
}

View File

@ -1150,7 +1150,6 @@ void CL_InitLocal (void)
cl_showmiss = Cvar_Get ("cl_showmiss", "0", 0);
cl_showclamp = Cvar_Get ("showclamp", "0", 0);
cl_timeout = Cvar_Get ("cl_timeout", "120", 0);
cl_paused = Cvar_Get ("paused", "0", 0);
rcon_client_password = Cvar_Get ("rcon_password", "", 0);
rcon_address = Cvar_Get ("rcon_address", "", 0);
@ -1431,6 +1430,7 @@ void CL_Init( void )
// all archived variables will now be loaded
scr_loading = Cvar_Get("scr_loading", "0", 0 );
cl_paused = Cvar_Get( "paused", "0", 0 );
Con_Init();
VID_Init();

View File

@ -47,6 +47,7 @@ typedef struct
// and broadcast.
typedef enum
{
TE_TELEPORT = 0,
TE_GUNSHOT,
TE_BLOOD,
TE_BLASTER,
@ -79,7 +80,6 @@ typedef enum
TE_TUNNEL_SPARKS,
TE_FLASHLIGHT,
TE_DEBUGTRAIL,
} temp_event_t;
@ -489,6 +489,10 @@ void CL_ParseTEnt( sizebuf_t *msg )
switch (type)
{
case TE_TELEPORT:
MSG_ReadPos32( msg, pos );
CL_TeleportSplash( pos );
break;
case TE_BLOOD: // bullet hitting flesh
MSG_ReadPos32(msg, pos);
MSG_ReadPos32(msg, dir);

View File

@ -155,7 +155,7 @@ V_AddLightStyle
=====================
*/
void V_AddLightStyle (int style, float r, float g, float b)
void V_AddLightStyle( int style, float r, float g, float b )
{
lightstyle_t *ls;

View File

@ -394,6 +394,8 @@ void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count);
// ========
// PGM
#define MAX_PARTICLES 32768
typedef struct cparticle_s
{
struct cparticle_s *next;
@ -430,6 +432,7 @@ void CL_IonripperTrail (vec3_t start, vec3_t end);
// ========
// PGM
void CL_TeleportSplash( vec3_t org );
void CL_BlasterParticles2 (vec3_t org, vec3_t dir, unsigned int color);
void CL_BlasterTrail2 (vec3_t start, vec3_t end);
void CL_DebugTrail (vec3_t start, vec3_t end);
@ -557,7 +560,7 @@ void CL_FreeClientProgs( void );
// if origin is NULL, the sound will be dynamically sourced from the entity
#define S_StartStreaming se->StartStreaming
#define S_RegisterSound se->RegisterSound
#define S_StartSound( a, b, c, d ) se->StartSound( a, b, c, d, 1.0f, ATTN_NORM );
#define S_StartSound( a, b, c, d ) se->StartSound( a, b, c, d, 1.0f, ATTN_NORM, true );
#define S_StartLocalSound se->StartLocalSound
#define S_StartBackgroundTrack se->StartBackgroundTrack
#define S_StopBackgroundTrack se->StopBackgroundTrack

View File

@ -546,7 +546,7 @@ void VM_RandomLong( void )
if(!VM_ValidateArgs( "RandomLong", 2 ))
return;
PRVM_G_FLOAT(OFS_RETURN) = RANDOM_LONG(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
PRVM_G_FLOAT(OFS_RETURN) = Com_RandomLong(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
}
/*
@ -561,7 +561,7 @@ void VM_RandomFloat( void )
if(!VM_ValidateArgs( "RandomFloat", 2 ))
return;
PRVM_G_FLOAT(OFS_RETURN) = RANDOM_FLOAT(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
PRVM_G_FLOAT(OFS_RETURN) = Com_RandomFloat(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
}
/*
@ -1601,7 +1601,7 @@ Cmd_GetMapList
Prints or complete map filename
=====================================
*/
bool Cmd_GetMapList (const char *s, char *completedname, int length )
bool Cmd_GetMapList( const char *s, char *completedname, int length )
{
search_t *t;
file_t *f;
@ -1738,7 +1738,7 @@ Cmd_GetFontList
Prints or complete font filename
=====================================
*/
bool Cmd_GetFontList (const char *s, char *completedname, int length )
bool Cmd_GetFontList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
@ -1783,7 +1783,7 @@ Cmd_GetDemoList
Prints or complete demo filename
=====================================
*/
bool Cmd_GetDemoList (const char *s, char *completedname, int length )
bool Cmd_GetDemoList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
@ -1828,7 +1828,7 @@ Cmd_GetMovieList
Prints or complete movie filename
=====================================
*/
bool Cmd_GetMovieList (const char *s, char *completedname, int length )
bool Cmd_GetMovieList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
@ -1866,6 +1866,51 @@ bool Cmd_GetMovieList (const char *s, char *completedname, int length )
return true;
}
/*
=====================================
Cmd_GetMusicList
Prints or complete background track filename
=====================================
*/
bool Cmd_GetMusicList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numtracks;
t = FS_Search(va("music/%s*.ogg", s ), true);
if(!t) return false;
FS_FileBase(t->filenames[0], matchbuf );
if(completedname && length) strncpy( completedname, matchbuf, length );
if(t->numfilenames == 1) return true;
for(i = 0, numtracks = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp(ext, "ogg" )) continue;
FS_FileBase(t->filenames[i], matchbuf );
Msg("%16s\n", matchbuf );
numtracks++;
}
Msg("\n^3 %i soundtracks found.\n", numtracks );
Mem_Free(t);
// cut shortestMatch to the amount common with s
if(completedname && length)
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
/*
=====================================
Cmd_GetSoundList
@ -1873,25 +1918,28 @@ Cmd_GetSoundList
Prints or complete sound filename
=====================================
*/
bool Cmd_GetSoundList (const char *s, char *completedname, int length )
bool Cmd_GetSoundList( const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numsounds;
const char *snddir = "sound/"; // constant
t = FS_Search(va("sound/%s*.wav", s ), true);
t = FS_Search(va("%s%s*.*", snddir, s ), true);
if(!t) return false;
FS_FileBase(t->filenames[0], matchbuf );
if(completedname && length) com.strncpy( completedname, matchbuf, length );
com.strncpy( matchbuf, t->filenames[0] + com.strlen(snddir), MAX_STRING );
FS_StripExtension( matchbuf );
if( completedname && length ) com.strncpy( completedname, matchbuf, length );
if(t->numfilenames == 1) return true;
for(i = 0, numsounds = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp(ext, "wav" )) continue;
FS_FileBase(t->filenames[i], matchbuf );
if(com.stricmp(ext, "wav") && com.stricmp(ext, "ogg")) continue;
com.strncpy( matchbuf, t->filenames[i] + com.strlen(snddir), MAX_STRING );
FS_StripExtension( matchbuf );
Msg("%16s\n", matchbuf );
numsounds++;
}
@ -1899,7 +1947,7 @@ bool Cmd_GetSoundList (const char *s, char *completedname, int length )
Mem_Free(t);
// cut shortestMatch to the amount common with s
if(completedname && length)
if( completedname && length )
{
for( i = 0; matchbuf[i]; i++ )
{

View File

@ -386,6 +386,7 @@ bool Cmd_GetMapList(const char *s, char *completedname, int length );
bool Cmd_GetFontList(const char *s, char *completedname, int length );
bool Cmd_GetDemoList(const char *s, char *completedname, int length );
bool Cmd_GetMovieList(const char *s, char *completedname, int length );
bool Cmd_GetMusicList(const char *s, char *completedname, int length );
bool Cmd_GetSoundList(const char *s, char *completedname, int length );
void Sys_Error( const char *msg, ... );
void Sys_SendKeyEvents( void );

View File

@ -200,7 +200,6 @@ typedef enum
#define MAX_ENTITIES 512 // refdef ents
#define MAX_DLIGHTS 64
#define MAX_CLIENTS 256 // absolute limit
#define MAX_PARTICLES 512
#define MAX_LIGHTSTYLES 256
#define MAX_SOUNDS 512 // so they cannot be blindly increased
#define MAX_IMAGES 256 // hud graphics

View File

@ -50,7 +50,6 @@ void SV_UpdateEntityState( edict_t *ent)
ent->priv.sv->s.renderfx = (int)ent->progs.sv->renderfx; // renderer flags
ent->priv.sv->s.alpha = ent->progs.sv->alpha; // alpha value
ent->priv.sv->s.animtime = ent->progs.sv->animtime; // auto-animating time
ent->priv.sv->s.soundindex = ent->progs.sv->loopsound;
}
/*
@ -105,7 +104,7 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
// in any bytes being emited if the entity has not changed at all
// note that players are always 'newentities', this updates their oldorigin always
// and prevents warping
MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
MSG_WriteDeltaEntity( oldent, newent, msg, false, newent->number <= maxclients->value );
oldindex++;
newindex++;
continue;
@ -118,14 +117,13 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
continue;
}
if (newnum > oldnum)
if( newnum > oldnum )
{
// the old entity isn't present in the new message
bits = U_REMOVE;
if (oldnum >= 256) bits |= U_NUMBER16 | U_MOREBITS1;
MSG_WriteByte (msg, bits&255 );
if (bits & 0x0000ff00) MSG_WriteByte (msg, (bits>>8)&255 );
MSG_WriteByte( msg, bits & 255 );
if( bits & 0x0000ff00 ) MSG_WriteByte( msg, (bits>>8) & 255 );
if (bits & U_NUMBER16)
{
@ -139,7 +137,7 @@ void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t
continue;
}
}
MSG_WriteShort (msg, 0); // end of packetentities
MSG_WriteShort( msg, 0 ); // end of packetentities
}
@ -352,7 +350,7 @@ Decides which entities are going to be visible to the client, and
copies off the playerstat and areabits.
=============
*/
void SV_BuildClientFrame (client_state_t *client)
void SV_BuildClientFrame( client_state_t *client )
{
int e, i;
vec3_t org;
@ -404,7 +402,7 @@ void SV_BuildClientFrame (client_state_t *client)
ent = PRVM_EDICT_NUM(e);
// ignore ents without visible models unless they have an effect
if (!ent->progs.sv->modelindex && !ent->progs.sv->effects && !ent->progs.sv->loopsound && !ent->priv.sv->event)
if( !ent->progs.sv->modelindex && !ent->progs.sv->effects && !ent->priv.sv->s.soundindex && !ent->priv.sv->event )
continue;
// ignore if not touching a PV leaf
@ -430,7 +428,7 @@ void SV_BuildClientFrame (client_state_t *client)
{
// FIXME: if an ent has a model and a sound, but isn't
// in the PVS, only the PHS, clear the model
if (ent->progs.sv->loopsound ) bitvector = clientphs;
if (ent->priv.sv->s.soundindex ) bitvector = clientphs;
else bitvector = clientpvs;
// check individual leafs
@ -460,15 +458,25 @@ void SV_BuildClientFrame (client_state_t *client)
}
else continue;
}
if (!ent->progs.sv->modelindex)
if( !ent->progs.sv->modelindex )
{
// don't send sounds if they will be attenuated away
vec3_t delta;
vec3_t delta, entorigin;
float len;
VectorSubtract (org, ent->progs.sv->origin, delta);
len = VectorLength (delta);
if (len > 400) continue;
if(VectorIsNull( ent->progs.sv->origin ))
{
VectorAdd( ent->progs.sv->mins, ent->progs.sv->maxs, entorigin );
VectorScale( entorigin, 0.5, entorigin );
}
else
{
VectorCopy( ent->progs.sv->origin, entorigin );
}
VectorSubtract( org, entorigin, delta );
len = VectorLength( delta );
if( len > 400 ) continue;
}
}
}

View File

@ -101,7 +101,7 @@ void SV_CreateBaseline (void)
{
svent = PRVM_EDICT_NUM(entnum);
if (svent->priv.sv->free) continue;
if (!svent->progs.sv->modelindex && !svent->progs.sv->loopsound && !svent->progs.sv->effects)
if (!svent->progs.sv->modelindex && !svent->priv.sv->s.soundindex && !svent->progs.sv->effects)
continue;
svent->priv.sv->serialnumber = entnum;

View File

@ -493,17 +493,21 @@ void Sav_LoadLocals( lump_t *l )
ent->priv.sv->free = false;
// parse an edict
PRVM_ED_ParseEdict(ents, ent);
PRVM_ED_ParseEdict( ents, ent );
ent->priv.sv->serialnumber = entnum++; // increase serialnumber
// link it into the bsp tree
if (!ent->priv.sv->free)
if(!ent->priv.sv->free)
{
SV_LinkEdict( ent );
SV_CreatePhysBody( ent );
SV_SetPhysForce( ent ); // restore forces ...
SV_SetMassCentre( ent ); // and mass force
}
if( ent->progs.sv->loopsound )
{
ent->priv.sv->s.soundindex = SV_SoundIndex(PRVM_GetString(ent->progs.sv->loopsound));
}
}
}
@ -1455,15 +1459,19 @@ void EmitAmbientSound(entity e, string samp)
void PF_ambientsound( void )
{
const char *samp;
edict_t *soundent;
edict_t *ent;
if(!VM_ValidateArgs( "EmitAmbientSound", 2 )) return;
soundent = PRVM_G_EDICT(OFS_PARM0);
ent = PRVM_G_EDICT(OFS_PARM0);
samp = PRVM_G_STRING(OFS_PARM1);
if( !ent ) return;
// check to see if samp was properly precached
if( soundent ) soundent->progs.sv->loopsound = SV_SoundIndex( samp );
//SV_AmbientSound( soundent, SV_SoundIndex( samp ), 0.0f, 0.0f ); // unused parms
ent->progs.sv->loopsound = PRVM_G_INT(OFS_PARM1);
ent->priv.sv->s.soundindex = SV_SoundIndex( samp );
if(!ent->progs.sv->modelindex ) SV_LinkEdict( ent );
//SV_AmbientSound( ent, SV_SoundIndex( samp ), 0.0f, 0.0f ); // unused parms
}
/*
@ -1785,7 +1793,7 @@ void PF_lightstyle( void )
style = (int)PRVM_G_FLOAT(OFS_PARM0);
val = PRVM_G_STRING(OFS_PARM1);
if((uint) style >= MAX_LIGHTSTYLES )
if((uint)style >= MAX_LIGHTSTYLES )
PRVM_ERROR( "PF_lightstyle: style: %i >= %d", style, MAX_LIGHTSTYLES );
SV_ConfigString( CS_LIGHTS + style, val );
}
@ -1902,7 +1910,7 @@ void PF_ClientPrint( void )
type = (int)PRVM_G_FLOAT( OFS_PARM0 );
if( num < 1 || num > maxclients->value || svs.clients[num - 1].state != cs_spawned )
{
VM_Warning("ClientPrint: tried print to a non-client!\n");
VM_Warning("ClientPrint: tired print to a non-client!\n");
return;
}
client = svs.clients + num - 1;

30
launch/common/Random.h Normal file
View File

@ -0,0 +1,30 @@
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose: Generalized 32-bit random number generator
// Range is 0x00000000 - 0x7FFFFFFF
//
// $NoKeywords: $
//=============================================================================
#ifndef RANDOM_H
#define RANDOM_H
#ifdef _WIN32
#pragma once
#endif
// the random number seeding is automatic
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
// restarts random generator
// setting lSeed to 0 causes the current time to be used as the seed
// random number generator will automatically seed itself on first use with current time if this is not called
extern void SeedRandomNumberGenerator(long lSeed = 0);
// returns a random integer of range [low, high]
extern long RandomLong( long lLow, long lHigh );
// returns a random float of range [low, high)
extern float RandomFloat( float flLow, float flHigh );
#endif // RANDOM_H

View File

@ -2737,9 +2737,9 @@ FS_Search
Allocate and fill a search structure with information on matching filenames.
===========
*/
static search_t *_FS_Search(const char *pattern, int caseinsensitive, int quiet )
static search_t *_FS_Search( const char *pattern, int caseinsensitive, int quiet )
{
search_t *search;
search_t *search = NULL;
searchpath_t *searchpath;
pack_t *pak;
int i, k, basepathlength, numfiles, numchars, resultlistindex, dirlistindex;
@ -2750,29 +2750,28 @@ static search_t *_FS_Search(const char *pattern, int caseinsensitive, int quiet
char netpath[MAX_OSPATH];
char temp[MAX_OSPATH];
for (i = 0; pattern[i] == '.' || pattern[i] == ':' || pattern[i] == '/' || pattern[i] == '\\'; i++);
for( i = 0; pattern[i] == '.' || pattern[i] == ':' || pattern[i] == '/' || pattern[i] == '\\'; i++ );
if (i > 0)
if( i > 0 )
{
Msg("Don't use punctuation at the beginning of a search pattern!\n");
MsgDev( D_INFO, "FS_Search: don't use punctuation at the beginning of a search pattern!\n");
return NULL;
}
stringlistinit(&resultlist);
stringlistinit(&dirlist);
search = NULL;
slash = com_strrchr(pattern, '/');
backslash = com_strrchr(pattern, '\\');
colon = com_strrchr(pattern, ':');
separator = max(slash, backslash);
separator = max(separator, colon);
basepathlength = separator ? (separator + 1 - pattern) : 0;
basepath = Malloc(basepathlength + 1);
if (basepathlength) Mem_Copy(basepath, pattern, basepathlength);
basepath = Malloc( basepathlength + 1 );
if( basepathlength ) Mem_Copy(basepath, pattern, basepathlength);
basepath[basepathlength] = 0;
// search through the path, one element at a time
for (searchpath = fs_searchpaths;searchpath;searchpath = searchpath->next)
for( searchpath = fs_searchpaths; searchpath; searchpath = searchpath->next )
{
// is the element a pak file?
if (searchpath->pack)
@ -2784,7 +2783,7 @@ static search_t *_FS_Search(const char *pattern, int caseinsensitive, int quiet
com_strncpy(temp, pak->files[i].name, sizeof(temp));
while (temp[0])
{
if (matchpattern(temp, (char *)pattern, true))
if( matchpattern(temp, (char *)pattern, true))
{
for (resultlistindex = 0;resultlistindex < resultlist.numstrings;resultlistindex++)
if (!com_strcmp(resultlist.strings[resultlistindex], temp))

106
launch/common/random.c Normal file
View File

@ -0,0 +1,106 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// stdlib.c - std lib portable utils
//=======================================================================
#include "launch.h"
#include "mathlib.h"
static long idum = 0;
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
#define IA 16807
#define IM 2147483647
#define IQ 127773
#define IR 2836
#define NTAB 32
#define NDIV (1+(IM-1)/NTAB)
#define AM (1.0/IM)
#define EPS 1.2e-7
#define RNMX (1.0 - EPS)
void SeedRandomNumberGenerator( long lSeed )
{
if( lSeed ) idum = lSeed;
else idum = -time( NULL );
if( 1000 < idum ) idum = -idum;
else if( -1000 < idum ) idum -= 22261048;
}
long lran1( void )
{
int j;
long k;
static long iy = 0;
static long iv[NTAB];
if( idum <= 0 || !iy )
{
if(-(idum) < 1) idum=1;
else idum = -(idum);
for( j = NTAB + 7; j >= 0; j-- )
{
k = (idum) / IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
if( j < NTAB ) iv[j] = idum;
}
iy = iv[0];
}
k = (idum)/IQ;
idum = IA * (idum - k * IQ) - IR * k;
if( idum < 0 ) idum += IM;
j = iy / NDIV;
iy = iv[j];
iv[j] = idum;
return iy;
}
// fran1 -- return a random floating-point number on the interval [0,1)
float fran1( void )
{
float temp = (float)AM * lran1();
if( temp > RNMX ) return (float)RNMX;
else return temp;
}
float Com_RandomFloat( float flLow, float flHigh )
{
float fl;
if( idum == 0 ) SeedRandomNumberGenerator(0);
fl = fran1(); // float in [0, 1)
return (fl * (flHigh - flLow)) + flLow; // float in [low, high)
}
long Com_RandomLong( long lLow, long lHigh )
{
dword maxAcceptable;
dword n, x = lHigh-lLow + 1;
if( idum == 0 ) SeedRandomNumberGenerator(0);
if( x <= 0 || MAX_RANDOM_RANGE < x-1 )
return lLow;
// The following maps a uniform distribution on the interval [0, MAX_RANDOM_RANGE]
// to a smaller, client-specified range of [0,x-1] in a way that doesn't bias
// the uniform distribution unfavorably. Even for a worst case x, the loop is
// guaranteed to be taken no more than half the time, so for that worst case x,
// the average number of times through the loop is 2. For cases where x is
// much smaller than MAX_RANDOM_RANGE, the average number of times through the
// loop is very close to 1.
//
maxAcceptable = MAX_RANDOM_RANGE - ((MAX_RANDOM_RANGE+1) % x );
do
{
n = lran1();
} while( n > maxAcceptable );
return lLow + (n % x);
}

View File

@ -124,7 +124,6 @@ void Sys_GetStdAPI( void )
com.Cmd_DelCommand = Cmd_RemoveCommand;
com.Cmd_TokenizeString = Cmd_TokenizeString;
// real filesystem
com.fopen = FS_Open; // same as fopen
com.fclose = FS_Close; // same as fclose
@ -158,6 +157,9 @@ void Sys_GetStdAPI( void )
com.Com_GetProcAddress = Sys_GetProcAddress; // gpa
com.Com_DoubleTime = Sys_DoubleTime; // hi-res timer
com.Com_RandomLong = Com_RandomLong;
com.Com_RandomFloat = Com_RandomFloat;
// stdlib.c funcs
com.strnupr = com_strnupr;
com.strnlwr = com_strnlwr;

View File

@ -56,8 +56,8 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98
# ADD LINK32 common\zlib.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
# Begin Custom Build
TargetDir=\XASH3D\src_main\temp\launch\!release
InputPath=\XASH3D\src_main\temp\launch\!release\launch.dll
TargetDir=\Xash3D\src_main\temp\launch\!release
InputPath=\Xash3D\src_main\temp\launch\!release\launch.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\launch.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -92,8 +92,8 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 common\zlib.lib user32.lib gdi32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /pdbtype:sept
# Begin Custom Build
TargetDir=\XASH3D\src_main\temp\launch\!debug
InputPath=\XASH3D\src_main\temp\launch\!debug\launch.dll
TargetDir=\Xash3D\src_main\temp\launch\!debug
InputPath=\Xash3D\src_main\temp\launch\!debug\launch.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\launch.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -132,11 +132,11 @@ SOURCE=.\common\cvar.c
# End Source File
# Begin Source File
SOURCE=.\common\filesystem.c
SOURCE=.\common\export.c
# End Source File
# Begin Source File
SOURCE=.\common\export.c
SOURCE=.\common\filesystem.c
# End Source File
# Begin Source File
@ -148,6 +148,10 @@ SOURCE=.\common\parselib.c
# End Source File
# Begin Source File
SOURCE=.\common\random.c
# End Source File
# Begin Source File
SOURCE=.\common\stdlib.c
# End Source File
# Begin Source File

View File

@ -187,6 +187,12 @@ char *com_pretifymem( float value, int digitsafterdecimal );
char *va(const char *format, ...);
#define copystring(str) com_stralloc(str, __FILE__, __LINE__)
//
// random.c
//
long Com_RandomLong( long lMin, long lMax );
float Com_RandomFloat( float fMin, float fMax );
//
// memlib.c
//

View File

@ -97,6 +97,7 @@ _inline double DoubleSwap( double swap )
#define LittleFloat(l) (l)
#define BigDouble(l) DoubleSwap(l)
#define LittleDouble(l) (l)
static bool big_endian = false;
#else
// big endian
#define BigShort(l) (l)
@ -107,6 +108,7 @@ _inline double DoubleSwap( double swap )
#define LittleFloat(l) FloatSwap(l)
#define BigDouble(l) (l)
#define LittleDouble(l) DoubleSwap(l)
static bool big_endian = true;
#endif
//extract from buffer

View File

@ -565,7 +565,7 @@ typedef struct vsound_exp_s
sound_t (*RegisterSound)( const char *name );
void (*EndRegistration)( void );
void (*StartSound)( const vec3_t pos, int entnum, int channel, sound_t sfx, float vol, float attn );
void (*StartSound)( const vec3_t pos, int entnum, int channel, sound_t sfx, float vol, float attn, bool use_loop );
void (*StreamRawSamples)( int samples, int rate, int width, int channels, const byte *data );
bool (*AddLoopingSound)( int entnum, sound_t handle, float volume, float attn );
bool (*StartLocalSound)( const char *name );

View File

@ -178,6 +178,7 @@ _inline bool VectorIsNull( const vec3_t v )
int i;
float result = 0;
if(!v) return true;
for (i = 0; i< 3; i++) result += v[i];
if(result != 0) return false;
return true;

View File

@ -151,6 +151,10 @@ typedef struct stdilib_api_s
void*(*Com_GetProcAddress)( dll_info_t *dll, const char* name ); // gpa
double (*Com_DoubleTime)( void ); // hi-res timer
// random generator
long (*Com_RandomLong)( long lMin, long lMax ); // returns random integer
float (*Com_RandomFloat)( float fMin, float fMax ); // returns random float
// stdlib.c funcs
void (*strnupr)(const char *in, char *out, size_t size_out); // convert string to upper case
void (*strnlwr)(const char *in, char *out, size_t size_out); // convert string to lower case
@ -364,6 +368,8 @@ misc utils
#define ThreadLock com.Com_ThreadLock
#define ThreadUnlock com.Com_ThreadUnlock
#define RunThreadsOnIndividual com.Com_CreateThread
#define Com_RandomLong com.Com_RandomLong
#define Com_RandomFloat com.Com_RandomFloat
/*
===========================================

View File

@ -71,5 +71,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
quake.exe -game tmpQuArK -dev 3 -debug -log
quake.exe -game tmpQuArK -dev 3 -debug -log +map walk_test
:done

View File

@ -505,9 +505,7 @@ void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
for (i=0 ; i<3 ; i++)
scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
if ( scale[0] == 1.0F &&
scale[1] == 1.0F &&
scale[2] == 1.0F )
if ( scale[0] == 1.0F && scale[1] == 1.0F && scale[2] == 1.0F )
{
for (i=0 ; i<size ; i++, bl+=3)
{

View File

@ -865,10 +865,10 @@ void R_DrawBrushModel ( int passnum )
//currententity = e;
gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
if (e->angles[0] || e->angles[1] || e->angles[2])
if( !VectorIsNull( e->angles ))
{
rotated = true;
for (i=0 ; i<3 ; i++)
for( i = 0; i < 3; i++ )
{
mins[i] = e->origin[i] - currentmodel->radius;
maxs[i] = e->origin[i] + currentmodel->radius;

View File

@ -10,6 +10,14 @@ SprExplorer
fopen завешивает приложение, при попытке создать файл в несуществующей директории. Ну вылетал бы чтоли, или ошибку
возвращал.
Отложенные задачи:
1. Поддержка loop для ogg vorbis
2. oggenc в виде отдельной утилиты (с импортом cue points)
3. сохранение в DXTC формат
0. Полная переработка звукового движка
1. Добавить signon message
2. Вырезать нахрен меню от quake2
@ -19,14 +27,6 @@ fopen
6. физика игрока на ньютоне
7. избавиться от sv.moved_edicts
Звуковой движок:
1. Сделать OpenAL совместимый движок OK
2. Поддержка OGG Vorbis OK
3. Сделать поддержку loop звуков OK
4. registration_sequence OK
5. упорядочить переменные OK
6.
Физика игрока:
1. Убрать отскоки от стен
2. Исправить код деформации хулла

View File

@ -54,10 +54,10 @@ void PRVM_MEM_Alloc(void)
PRVM_MEM_IncreaseEdicts
===============
*/
void PRVM_MEM_IncreaseEdicts(void)
void PRVM_MEM_IncreaseEdicts( void )
{
int i;
int oldmaxedicts = vm.prog->max_edicts;
int i;
int oldmaxedicts = vm.prog->max_edicts;
void *oldedictsfields = vm.prog->edictsfields;
void *oldedictprivate = vm.prog->edictprivate;
@ -567,11 +567,11 @@ void PRVM_ED_Print(edict_t *ed)
tempstring[0] = 0;
com.sprintf(tempstring, "\n%s EDICT %i:\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ed));
for (i=1 ; i<vm.prog->progs->numfielddefs ; i++)
for( i = 1; i < vm.prog->progs->numfielddefs; i++ )
{
d = &vm.prog->fielddefs[i];
name = PRVM_GetString(d->s_name);
if (name[com.strlen(name)-2] == '_')
if(name[com.strlen(name)-2] == '_')
continue; // skip _x, _y, _z vars
v = (int *)((char *)ed->progs.vp + d->ofs*4);
@ -866,11 +866,10 @@ bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
prvm_eval_t *val;
mfunction_t *func;
if (ent)
val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs);
else
val = (prvm_eval_t *)((int *)vm.prog->globals.gp + key->ofs);
switch (key->type & ~DEF_SAVEGLOBAL)
if( ent ) val = (prvm_eval_t *)((int *)ent->progs.vp + key->ofs);
else val = (prvm_eval_t *)((int *)vm.prog->globals.gp + key->ofs);
switch( key->type & ~DEF_SAVEGLOBAL )
{
case ev_string:
l = (int)com.strlen(s) + 1;
@ -891,28 +890,20 @@ bool PRVM_ED_ParseEpair(edict_t *ent, ddef_t *key, const char *s)
*new_p++ = s[i];
}
break;
case ev_float:
while (*s && *s <= ' ')
s++;
while(*s && *s <= ' ') s++;
val->_float = com.atof(s);
break;
case ev_vector:
for (i = 0;i < 3;i++)
for (i = 0; i < 3; i++)
{
while (*s && *s <= ' ')
s++;
if (!*s)
break;
while (*s && *s <= ' ') s++;
if (!*s) break;
val->vector[i] = com.atof(s);
while (*s > ' ')
s++;
if (!*s)
break;
while (*s > ' ') s++;
if (!*s) break;
}
break;
case ev_entity:
while (*s && *s <= ' ')
s++;
@ -1051,10 +1042,11 @@ const char *PRVM_ED_ParseEdict (const char *data, edict_t *ent)
// keynames with a leading underscore are used for utility comments,
// and are immediately discarded by quake
if (keyname[0] == '_') continue;
if(!stricmp( keyname, "light" )) continue; // ignore lightvalue
if( keyname[0] == '_' ) continue;
key = PRVM_ED_FindField( keyname );
if (!key)
if( !key )
{
MsgDev(D_NOTE, "%s: unknown field '%s'\n", PRVM_NAME, keyname);
continue;

View File

@ -4,6 +4,7 @@
//=======================================================================
#include "sound.h"
#include "s_stream.h"
#define MAX_SFX 4096
static sfx_t s_knownSfx[MAX_SFX];
@ -11,6 +12,13 @@ static int s_numSfx = 0;
int s_registration_sequence = 0;
bool s_registering = false;
typedef struct loadformat_s
{
char *formatstring;
char *ext;
bool (*loadfunc)( const char *name, byte **wav, wavinfo_t *info );
} loadformat_t;
/*
=================
S_SoundList_f
@ -219,9 +227,7 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
{
iff_dataPtr += 32;
info->loopstart = S_GetLittleLong();
Msg("found 'cue '\n" );
// if the next chunk is a LIST chunk, look for a cue length marker
S_FindNextChunk("LIST");
S_FindNextChunk("LIST"); // if the next chunk is a LIST chunk, look for a cue length marker
if( iff_dataPtr )
{
if(!com.strncmp ((const char *)iff_dataPtr + 28, "mark", 4))
@ -229,7 +235,6 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
// this is not a proper parse, but it works with CoolEdit...
iff_dataPtr += 24;
info->samples = info->loopstart + S_GetLittleLong(); // samples in loop
Msg("loopstart = %d, samples %d\n", info->loopstart, info->samples );
}
}
}
@ -276,6 +281,153 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
return true;
}
/*
=======================================================================
OGG LOADING
=======================================================================
*/
typedef struct
{
byte *buffer;
ogg_int64_t ind;
ogg_int64_t buffsize;
} ov_decode_t;
static size_t ovc_read( void *ptr, size_t size, size_t nb, void *datasource )
{
ov_decode_t *sound = (ov_decode_t *)datasource;
size_t remain, length;
remain = sound->buffsize - sound->ind;
length = size * nb;
if( remain < length ) length = remain - remain % size;
Mem_Copy( ptr, sound->buffer + sound->ind, length );
sound->ind += length;
return length / size;
}
static int ovc_seek ( void *datasource, ogg_int64_t offset, int whence )
{
ov_decode_t *sound = (ov_decode_t*)datasource;
switch( whence )
{
case SEEK_SET:
break;
case SEEK_CUR:
offset += sound->ind;
break;
case SEEK_END:
offset += sound->buffsize;
break;
default:
return -1;
}
if( offset < 0 || offset > sound->buffsize )
return -1;
sound->ind = offset;
return 0;
}
static int ovc_close( void *datasource )
{
return 0;
}
static long ovc_tell (void *datasource)
{
return ((ov_decode_t*)datasource)->ind;
}
/*
=================
S_LoadOGG
=================
*/
static bool S_LoadOGG( const char *name, byte **wav, wavinfo_t *info )
{
vorbisfile_t vf;
vorbis_info_t *vi;
vorbis_comment_t *vc;
fs_offset_t filesize;
ov_decode_t ov_decode;
ogg_int64_t length, done = 0;
ov_callbacks_t ov_callbacks = { ovc_read, ovc_seek, ovc_close, ovc_tell };
byte *data, *buffer;
const char *comm;
int dummy;
long ret;
// load the file
data = FS_LoadFile( name, &filesize );
if( !data ) return false;
// Open it with the VorbisFile API
ov_decode.buffer = data;
ov_decode.ind = 0;
ov_decode.buffsize = filesize;
if( ov_open_callbacks( &ov_decode, &vf, NULL, 0, ov_callbacks ) < 0 )
{
MsgDev( D_ERROR, "S_LoadOGG: couldn't open ogg stream %s\n", name );
Mem_Free( data );
return false;
}
// get the stream information
vi = ov_info( &vf, -1 );
if( vi->channels != 1 )
{
MsgDev( D_ERROR, "S_LoadOGG: only mono OGG files supported (%s)\n", name );
ov_clear( &vf );
Mem_Free( data );
return false;
}
info->channels = vi->channels;
info->rate = vi->rate;
info->width = 2; // always 16-bit PCM
info->loopstart = -1;
length = ov_pcm_total( &vf, -1 ) * vi->channels * 2; // 16 bits => "* 2"
if( !length )
{
// bad ogg file
MsgDev( D_ERROR, "S_LoadOGG: (%s) is probably corrupted\n", name );
ov_clear( &vf );
Mem_Free( data );
return false;
}
buffer = (byte *)Z_Malloc( length );
// decompress ogg into pcm wav format
while((ret = ov_read( &vf, &buffer[done], (int)(length - done), big_endian, 2, 1, &dummy )) > 0)
done += ret;
info->samples = done / ( vi->channels * 2 );
vc = ov_comment( &vf, -1 );
if( vc )
{
comm = vorbis_comment_query( vc, "LOOP_START", 0 );
if( comm )
{
//FXIME: implement
Msg("ogg 'cue' %d\n", com.atoi(comm) );
//info->loopstart = bound( 0, com.atoi(comm), info->samples );
}
}
// close file
ov_clear( &vf );
Mem_Free( data );
*wav = buffer; // load the data
return true;
}
/*
=================
S_UploadSound
@ -342,36 +494,60 @@ static void S_CreateDefaultSound( byte **wav, wavinfo_t *info )
S_LoadSound
=================
*/
loadformat_t load_formats[] =
{
{"sound/%s.%s", "ogg", S_LoadOGG},
{"sound/%s.%s", "wav", S_LoadWAV},
{"%s.%s", "ogg", S_LoadOGG},
{"%s.%s", "wav", S_LoadWAV},
{NULL, NULL}
};
bool S_LoadSound( sfx_t *sfx )
{
string name;
byte *data;
wavinfo_t info;
const char *ext;
string loadname, path;
loadformat_t *format;
bool anyformat;
if( !sfx ) return false;
if( sfx->name[0] == '*' ) return false;
if( sfx->loaded ) return true; // see if still in memory
// load it from disk
if( sfx->name[0] == '#' )
com.snprintf( name, sizeof(name), "%s", &sfx->name[1]);
else com.snprintf( name, sizeof(name), "sound/%s", sfx->name );
ext = FS_FileExtension( sfx->name );
anyformat = !com.stricmp(ext, "") ? true : false;
if(!S_LoadWAV(name, &data, &info))
com.strncpy( loadname, sfx->name, sizeof(loadname) - 1);
FS_StripExtension( loadname ); // remove extension if needed
// developer warning
if(!anyformat) MsgDev(D_NOTE, "Note: %s will be loading only with ext .%s\n", loadname, ext );
// now try all the formats in the selected list
for( format = load_formats; format->formatstring; format++ )
{
sfx->default_sound = true;
MsgDev(D_WARN, "couldn't load %s\n", sfx->name );
S_CreateDefaultSound( &data, &info );
info.loopstart = -1;
if( anyformat || !com.stricmp( ext, format->ext ))
{
com.sprintf( path, format->formatstring, loadname, format->ext );
if( format->loadfunc( path, &data, &info ))
goto snd_loaded;
}
}
sfx->default_sound = true;
MsgDev(D_WARN, "FS_LoadSound: couldn't load %s\n", sfx->name );
S_CreateDefaultSound( &data, &info );
info.loopstart = -1;
snd_loaded:
// load it in
sfx->loopstart = info.loopstart;
sfx->samples = info.samples;
sfx->rate = info.rate;
S_UploadSound( data, info.width, info.channels, sfx );
sfx->loaded = true;
Mem_Free( data );
return true;

View File

@ -5,7 +5,7 @@
#include "sound.h"
#define MAX_PLAYSOUNDS 128
#define MAX_PLAYSOUNDS 256
#define MAX_CHANNELS 64
static playSound_t s_playSounds[MAX_PLAYSOUNDS];
@ -23,7 +23,7 @@ cvar_t *s_soundfx;
cvar_t *s_check_errors;
cvar_t *s_volume; // master volume
cvar_t *s_musicvolume; // background track volume
cvar_t *s_pause;
cvar_t *s_minDistance;
cvar_t *s_maxDistance;
cvar_t *s_rolloffFactor;
@ -131,22 +131,15 @@ static void S_PlayChannel( channel_t *ch, sfx_t *sfx )
palSourcei(ch->sourceNum, AL_BUFFER, sfx->bufferNum);
palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound);
palSourcei(ch->sourceNum, AL_SOURCE_RELATIVE, false);
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
if( sfx->loopstart > -1 )
if( ch->loopstart >= 0 )
{
if( sfx->loopfirst )
{
sfx->loopfirst = false;
Msg( "loopsound playing at first\n" );
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
}
else
{
Msg( "loopsound playing loop from %d\n", sfx->loopstart );
if( ch->state == CHAN_FIRSTPLAY )
ch->state = CHAN_LOOPED;
else if( ch->state == CHAN_LOOPED )
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, sfx->loopstart );
}
}
else palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
palSourcePlay( ch->sourceNum );
}
@ -214,23 +207,22 @@ S_PickChannel
Tries to find a free channel, or tries to replace an active channel
=================
*/
channel_t *S_PickChannel( int entnum, int entChannel )
channel_t *S_PickChannel( int entnum, int channel )
{
channel_t *ch;
int i;
int firstToDie = -1;
int oldestTime = Sys_DoubleTime();
float oldestTime = Sys_DoubleTime();
if( entnum < 0 || entChannel < 0 )
Host_Error( "S_PickChannel: entnum or entChannel less than 0" );
if( entnum < 0 || channel < 0 ) return NULL; // invalid channel or entnum
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
{
// don't let game sounds override streaming sounds
if( ch->streaming )continue;
if( ch->streaming ) continue;
// check if this channel is active
if( !ch->sfx )
if( channel == CHAN_AUTO && !ch->sfx )
{
// free channel
firstToDie = i;
@ -238,7 +230,7 @@ channel_t *S_PickChannel( int entnum, int entChannel )
}
// channel 0 never overrides
if( entChannel != 0 && (ch->entnum == entnum && ch->entchannel == entChannel))
if( channel != CHAN_AUTO && (ch->entnum == entnum && ch->entchannel == channel))
{
// always override sound from same entity
firstToDie = i;
@ -261,12 +253,13 @@ channel_t *S_PickChannel( int entnum, int entChannel )
ch = &s_channels[firstToDie];
ch->entnum = entnum;
ch->entchannel = entChannel;
ch->entchannel = channel;
ch->startTime = Sys_DoubleTime();
ch->state = CHAN_NORMAL; // remove any loop sound
ch->loopstart = -1; // clear loopstate
// Make sure this channel is stopped
palSourceStop(ch->sourceNum);
palSourcei(ch->sourceNum, AL_BUFFER, 0);
// make sure this channel is stopped
S_StopChannel( ch );
return ch;
}
@ -384,15 +377,9 @@ static void S_IssuePlaySounds( void )
{
ps = s_pendingPlaySounds.next;
if(ps == &s_pendingPlaySounds)
{
Msg("no more pending playsounds\n");
break; // no more pending playSounds
}
if( ps->beginTime > Sys_DoubleTime())
{
Msg("no more pending playsounds\n");
break; // No more pending playSounds this frame
}
// pick a channel and start the sound effect
ch = S_PickChannel( ps->entnum, ps->entchannel );
if(!ch)
@ -402,10 +389,13 @@ static void S_IssuePlaySounds( void )
S_FreePlaySound( ps );
continue;
}
// check for looping sounds with "cue " marker
if( ps->sfx->loopstart > -1 )
if( ps->use_loop && ps->sfx->loopstart >= 0 )
{
ps->sfx->loopfirst = true;
// jump to loopstart at next playing
ch->state = CHAN_FIRSTPLAY;
ch->loopstart = ps->sfx->loopstart;
}
ch->fixedPosition = ps->fixedPosition;
@ -420,16 +410,6 @@ static void S_IssuePlaySounds( void )
// free the playSound
S_FreePlaySound( ps );
if( S_ChannelState( ch ) == AL_STOPPED )
{
if( ch->sfx->loopstart > -1 )
{
Msg("playing %s again form offset %d\n", ch->sfx->name, ch->sfx->loopstart );
S_PlayChannel( ch, ch->sfx );
}
}
}
}
@ -442,7 +422,7 @@ if origin is NULL, the sound will be dynamically sourced from the entity.
entchannel 0 will never override a playing sound.
=================
*/
void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t handle, float volume, float attenuation )
void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, float vol, float attn, bool use_loop )
{
playSound_t *ps, *sort;
sfx_t *sfx = NULL;
@ -451,7 +431,7 @@ void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t ha
return;
sfx = S_GetSfxByHandle( handle );
if( !sfx ) return;
Msg("CL_StartSound %s ( entnum %d, channel %d)\n", sfx->name, entnum, entChannel );
// Make sure the sound is loaded
if(!S_LoadSound(sfx)) return;
@ -465,21 +445,22 @@ void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t ha
}
ps->sfx = sfx;
ps->entnum = entnum;
ps->entchannel = entChannel;
ps->entchannel = channel;
ps->use_loop = use_loop;
if( position )
if( pos )
{
ps->fixedPosition = true;
VectorCopy( position, ps->position );
VectorCopy( pos, ps->position );
}
else ps->fixedPosition = false;
ps->volume = volume;
ps->attenuation = attenuation;
ps->volume = vol;
ps->attenuation = attn;
ps->beginTime = Sys_DoubleTime();
// Sort into the pending playSounds list
for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds&& sort->beginTime < ps->beginTime; sort = sort->next );
for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds && sort->beginTime < ps->beginTime; sort = sort->next );
ps->next = sort;
ps->prev = sort->prev;
@ -502,7 +483,7 @@ bool S_StartLocalSound( const char *name )
return false;
sfxHandle = S_RegisterSound( name );
S_StartSound( NULL, al_state.clientnum, CHAN_BODY, sfxHandle, 1.0f, ATTN_NONE );
S_StartSound( NULL, al_state.clientnum, CHAN_AUTO, sfxHandle, 1.0f, ATTN_NONE, false );
return true;
}
@ -577,13 +558,15 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
channel_t *ch;
int i;
if(!al_state.initialized ) return;
// Bump frame count
if(!al_state.initialized ) return;
//if( s_pause->integer ) return;
// bump frame count
al_state.framecount++;
al_state.clientnum = clientnum;
// Set up listener
// set up listener
VectorSet( s_listener.position, position[1], position[2], -position[0]);
VectorSet( s_listener.velocity, velocity[1], velocity[2], -velocity[0]);
@ -631,14 +614,18 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
continue;
}
}
else
else if( ch->loopstart >= 0 )
{
if( S_ChannelState( ch ) == AL_STOPPED )
{
S_StopChannel( ch );
continue;
S_PlayChannel( ch, ch->sfx );
}
}
else if( S_ChannelState( ch ) == AL_STOPPED )
{
S_StopChannel( ch );
continue;
}
// respatialize channel
S_SpatializeChannel( ch );
@ -672,23 +659,14 @@ void S_Activate( bool active )
S_Play_f
=================
*/
void S_Play_f( void )
void S_PlaySound_f( void )
{
int i = 1;
string name;
if( Cmd_Argc() == 1 )
{
Msg("Usage: play <soundfile> [...]\n");
Msg("Usage: playsound <soundfile>\n");
return;
}
while ( i < Cmd_Argc())
{
if ( !com.strrchr(Cmd_Argv(i), '.')) com.sprintf( name, "%s.wav", Cmd_Argv(1) );
else com.strncpy( name, Cmd_Argv(i), sizeof(name) );
S_StartLocalSound( name );
i++;
}
S_StartLocalSound(Cmd_Argv(1));
}
/*
@ -747,6 +725,8 @@ void S_SoundInfo_f( void )
*/
void S_Init( void *hInst )
{
int num_mono_src, num_stereo_src;
host_sound = Cvar_Get("host_sound", "1", CVAR_SYSTEMINFO );
s_alDevice = Cvar_Get("s_device", "Generic Software", CVAR_LATCH|CVAR_ARCHIVE );
s_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH|CVAR_ARCHIVE );
@ -758,8 +738,9 @@ void S_Init( void *hInst )
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.0", CVAR_ARCHIVE );
s_dopplerFactor = Cvar_Get("s_dopplerfactor", "1.0", CVAR_ARCHIVE );
s_dopplerVelocity = Cvar_Get("s_dopplervelocity", "10976.0", CVAR_ARCHIVE );
s_pause = Cvar_Get( "paused", "0", 0 );
Cmd_AddCommand("play", S_Play_f, "playing a specified sound file" );
Cmd_AddCommand("playsound", S_PlaySound_f, "playing a specified sound file" );
Cmd_AddCommand("music", S_Music_f, "starting a background track" );
Cmd_AddCommand("s_stop", S_StopSound_f, "stop all sounds" );
Cmd_AddCommand("s_info", S_SoundInfo_f, "print sound system information" );
@ -777,6 +758,10 @@ void S_Init( void *hInst )
return;
}
palcGetIntegerv( al_state.hDevice, ALC_MONO_SOURCES, sizeof(int), &num_mono_src );
palcGetIntegerv( al_state.hDevice, ALC_STEREO_SOURCES, sizeof(int), &num_stereo_src );
Msg("Mono sources %d, stereo %d\n", num_mono_src, num_stereo_src );
sndpool = Mem_AllocPool("Sound Zone");
al_state.initialized = true;

View File

@ -25,6 +25,8 @@ typedef struct alcontext_s alcontext;
#define ALC_ALL_ATTRIBUTES 0x1003
#define ALC_FREQUENCY 0x1007
#define ALC_MAX_AUXILIARY_SENDS 0x20003
#define ALC_MONO_SOURCES 0x1010
#define ALC_STEREO_SOURCES 0x1011
#define AL_SOURCE_RELATIVE 0x202
#define AL_CONE_INNER_ANGLE 0x1001

View File

@ -51,9 +51,6 @@ static int ovc_seek ( void *datasource, ogg_int64_t offset, int whence )
static int ovc_close( void *datasource )
{
bg_track_t *track = (bg_track_t *)datasource;
//FIXME: FS_Close( track->file );
return 0;
}
@ -158,7 +155,7 @@ void S_StreamBackgroundTrack( void )
// stream from disk
while( size < BUFFER_SIZE )
{
read = ov_read( s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, 0, 2, 1, &dummy );
read = ov_read( s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, big_endian, 2, 1, &dummy );
if( read == 0 )
{
// end of file

View File

@ -177,6 +177,9 @@ typedef struct vorbisfile_s
// libvorbis exports
int ov_open_callbacks( void *datasource, vorbisfile_t *vf, char *initial, long ibytes, ov_callbacks_t callbacks );
long ov_read( vorbisfile_t *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream );
char *vorbis_comment_query( vorbis_comment_t *vc, char *tag, int count );
vorbis_comment_t *ov_comment( vorbisfile_t *vf, int link );
ogg_int64_t ov_pcm_total( vorbisfile_t *vf, int i );
vorbis_info_t *ov_info( vorbisfile_t *vf, int link );
int ov_raw_seek( vorbisfile_t *vf, ogg_int64_t pos );
ogg_int64_t ov_raw_tell( vorbisfile_t *vf );

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,13 @@ extern stdlib_api_t com;
extern vsound_imp_t si;
extern byte *sndpool;
enum
{
CHAN_FIRSTPLAY,
CHAN_LOOPED,
CHAN_NORMAL,
};
typedef struct
{
int rate;
@ -35,7 +42,6 @@ typedef struct sfx_s
string name;
bool loaded;
int loopstart; // looping point (in samples)
bool loopfirst; // check it for set properly offset in samples
int samples;
int rate;
uint format;
@ -67,22 +73,27 @@ typedef struct playsound_s
int entnum;
int entchannel;
bool fixedPosition; // Use position instead of fetching entity's origin
bool use_loop; // ignore looping sounds for local sound
vec3_t position; // Only use if fixedPosition is set
float volume;
float attenuation;
int beginTime; // Begin at this time
float beginTime; // Begin at this time
} playSound_t;
typedef struct
{
bool streaming;
sfx_t *sfx; // NULL if unused
int state; // channel state
int entnum; // to allow overriding a specific sound
int entchannel;
int startTime; // for overriding oldest sounds
float startTime; // for overriding oldest sounds
bool loopsound; // is looping sound ?
int loopnum; // looping entity number
int loopframe; // for stopping looping sounds
int loopstart; // check it for set properly offset in samples
bool fixedPosition; // use position instead of fetching entity's origin
vec3_t position; // only use if fixedPosition is set
float volume;
@ -146,7 +157,7 @@ void S_Shutdown( void );
void S_Activate( bool active );
void S_SoundList_f( void );
void S_CheckForErrors( void );
void S_StartSound( const vec3_t origin, int entnum, int entchannel, sound_t sfx, float vol, float attn );
void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t sfx, float vol, float attn, bool use_loop );
void S_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );