Skip to content
This repository has been archived by the owner on Aug 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3 from noodlecollie/update-master-from-upstream
Browse files Browse the repository at this point in the history
Update master from upstream
  • Loading branch information
noodlecollie committed Apr 7, 2023
2 parents f829562 + 3fbe6d1 commit 4aa37fc
Show file tree
Hide file tree
Showing 130 changed files with 1,516 additions and 2,615 deletions.
2 changes: 1 addition & 1 deletion 3rdparty/mainui
Submodule mainui updated 1 files
+2 −1 BMPUtils.h
2 changes: 1 addition & 1 deletion 3rdparty/opus/opus
Submodule opus updated 3 files
+11 −1 celt/kiss_fft.h
+1 −1 opus.m4
+2 −2 silk/MacroDebug.h
22 changes: 22 additions & 0 deletions Documentation/extensions/mp3-loops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Looping MP3 extension

It is now possible to loop MP3 file in Xash3D FWGS by adding a custom text tag with `LOOP_START` or `LOOPSTART` in description and time point (in raw samples) in value.

### Example with foobar2000
1. Open Foobar2000
2. Add your .mp3 file to playlist
3. Right click to newly added file and select Properties
4. In Metadata tab, at the bottom of the table, select "+add new"
5. In newly added line replace `«input field name»` with `LOOP_START` (without any symbols).
6. Press Tab and enter loop time point in raw samples. For example, `0` will replay sound file from beginning to end indefinitely.

### Possible alternatives
1. Classic WAV files looping. HQ WAV files can take too much disk space, and recommended software supporting cue points is paid, outdated and can't run on modern systems. (Although there is alternative that's proven to work with idTech-based engines called LoopAuditioneer.)
2. Vorbis looping through comment. Engine doesn't support Vorbis but this extension was highly inspired by this hack.

### Known bugs and limitations
1. At this time using MP3 as SFX requires complete decoding. This can cause noticeable stutters, so keep MP3 file length in mind.
2. We deliberately only support modern ID3v2.3 and ID3v2.4 tags. Using ID3v1 is not possible.



8 changes: 6 additions & 2 deletions common/defaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ SETUP BACKENDS DEFINITIONS
#define XASH_MESSAGEBOX MSGBOX_ANDROID
#endif // XASH_MESSAGEBOX

#define XASH_USE_EVDEV
#define XASH_USE_EVDEV 1
#define XASH_DYNAMIC_DLADDR
#elif XASH_LINUX
// we are building for Linux without SDL2, can draw only to framebuffer yet
Expand All @@ -86,7 +86,7 @@ SETUP BACKENDS DEFINITIONS
#define XASH_SOUND SOUND_ALSA
#endif // XASH_SOUND

#define XASH_USE_EVDEV
#define XASH_USE_EVDEV 1
#elif XASH_DOS4GW
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_DOS
Expand Down Expand Up @@ -191,6 +191,10 @@ Default build-depended cvar and constant values
#define DEFAULT_M_IGNORE "0"
#endif // DEFAULT_M_IGNORE

#ifndef DEFAULT_JOY_DEADZONE
#define DEFAULT_JOY_DEADZONE "4096"
#endif // DEFAULT_JOY_DEADZONE

#ifndef DEFAULT_DEV
#define DEFAULT_DEV 0
#endif // DEFAULT_DEV
Expand Down
10 changes: 8 additions & 2 deletions common/mathlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ typedef vec_t vec4_t[4]; // x,y,z,w
struct mplane_s;

extern vec3_t vec3_origin;
extern int nanmask;

#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#ifdef XASH_IRIX
#undef isnan
#endif
#ifdef isnan // check for C99 isnan
#define IS_NAN isnan
#else
#define IS_NAN(x) (((*(int *)&x) & (255<<23)) == (255<<23))
#endif

#ifndef VECTOR_H
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
Expand Down
1 change: 0 additions & 1 deletion engine/client/avi/avi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ int AVI_GetAudioChunk( movie_state_t *Avi, char *audiodata, int offset, int leng
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time );
int AVI_GetVideoFrameCount( movie_state_t *Avi );
void AVI_CloseVideo( movie_state_t *Avi );
qboolean AVI_IsActive( movie_state_t *Avi );
void AVI_FreeVideo( movie_state_t *Avi );
Expand Down
5 changes: 0 additions & 5 deletions engine/client/avi/avi_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
return 0;
}

int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
return 0;
}

void AVI_CloseVideo( movie_state_t *Avi )
{
;
Expand Down
23 changes: 12 additions & 11 deletions engine/client/avi/avi_win.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
avi_win.c - playing AVI files (based on original AVIKit code, Win32 version)
Copyright (c) 2003-2004, Ruari O'Sullivan
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -63,7 +64,7 @@ static int (_stdcall *pAVIStreamTimeToSample)( PAVISTREAM pavi, LONG lTime );
static void* (_stdcall *pAVIStreamGetFrame)( PGETFRAME pg, LONG lPos );
static int (_stdcall *pAVIStreamGetFrameClose)( PGETFRAME pg );
static dword (_stdcall *pAVIStreamRelease)( PAVISTREAM pavi );
static int (_stdcall *pAVIFileOpen)( PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileOpenW)( PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileGetStream)( PAVIFILE pfile, PAVISTREAM *ppavi, DWORD fccType, LONG lParam );
static int (_stdcall *pAVIStreamReadFormat)( PAVISTREAM pavi, LONG lPos,LPVOID lpFormat, LONG *lpcbFormat );
static int (_stdcall *pAVIStreamStart)( PAVISTREAM pavi );
Expand All @@ -76,7 +77,7 @@ static dllfunc_t avifile_funcs[] =
{ "AVIFileExit", (void **) &pAVIFileExit },
{ "AVIFileGetStream", (void **) &pAVIFileGetStream },
{ "AVIFileInit", (void **) &pAVIFileInit },
{ "AVIFileOpenA", (void **) &pAVIFileOpen },
{ "AVIFileOpenW", (void **) &pAVIFileOpenW },
{ "AVIFileRelease", (void **) &pAVIFileRelease },
{ "AVIStreamGetFrame", (void **) &pAVIStreamGetFrame },
{ "AVIStreamGetFrameClose", (void **) &pAVIStreamGetFrameClose },
Expand Down Expand Up @@ -278,14 +279,6 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
return (time * Avi->video_fps);
}

int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
if( !Avi->active )
return 0;

return Avi->video_frames;
}

int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
{
if( !Avi->active || !Avi->audio_stream )
Expand Down Expand Up @@ -493,6 +486,7 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
AVISTREAMINFO stream_info;
int opened_streams = 0;
LONG hr;
wchar_t pathBuffer[MAX_PATH];

// default state: non-working.
Avi->active = false;
Expand All @@ -501,8 +495,15 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
// can't load Video For Windows :-(
if( !avi_initialized ) return;

// convert to wide char
if( MultiByteToWideChar( CP_UTF8, 0, filename, -1, pathBuffer, ARRAYSIZE( pathBuffer )) <= 0 )
{
Con_DPrintf( S_ERROR "filename buffer limit exceeded\n" );
return;
}

// load the AVI
hr = pAVIFileOpen( &Avi->pfile, filename, OF_SHARE_DENY_WRITE, 0L );
hr = pAVIFileOpenW( &Avi->pfile, pathBuffer, OF_SHARE_DENY_WRITE, 0L );

if( hr != 0 ) // error opening AVI:
{
Expand Down
2 changes: 1 addition & 1 deletion engine/client/cl_custom.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
}

MSG_BeginClientCmd( msg, clc_stringcmd );
MSG_WriteString( msg, va( "dlfile %s", filepath ));
MSG_WriteStringf( msg, "dlfile %s", filepath );
host.downloadcount++;

return false;
Expand Down
40 changes: 0 additions & 40 deletions engine/client/cl_efrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,46 +33,6 @@ static mnode_t *r_pefragtopnode;
static vec3_t r_emins, r_emaxs;
static cl_entity_t *r_addent;

/*
================
R_RemoveEfrags
Call when removing an object from the world or moving it to another position
================
*/
void R_RemoveEfrags( cl_entity_t *ent )
{
efrag_t *ef, *old, *walk, **prev;

ef = ent->efrag;

while( ef )
{
prev = &ef->leaf->efrags;
while( 1 )
{
walk = *prev;
if( !walk ) break;

if( walk == ef )
{
// remove this fragment
*prev = ef->leafnext;
break;
}
else prev = &walk->leafnext;
}

old = ef;
ef = ef->entnext;

// put it on the free list
old->entnext = clgame.free_efrags;
clgame.free_efrags = old;
}
ent->efrag = NULL;
}

/*
===================
R_SplitEntityOnNode
Expand Down
20 changes: 0 additions & 20 deletions engine/client/cl_efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,26 +142,6 @@ void CL_FreeParticles( void )
cl_particles = NULL;
}

/*
================
CL_FreeParticle
move particle to freelist
================
*/
void CL_FreeParticle( particle_t *p )
{
if( p->deathfunc )
{
// call right the deathfunc before die
p->deathfunc( p );
p->deathfunc = NULL;
}

p->next = cl_free_particles;
cl_free_particles = p;
}

/*
================
CL_AllocParticleFast
Expand Down
12 changes: 12 additions & 0 deletions engine/client/cl_font.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,18 @@ int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *fon
return draw_len;
}

int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];

va_start( va, fmt );
Q_vsnprintf( buf, sizeof( buf ), fmt, va );
va_end( va );

return CL_DrawString( x, y, buf, color, font, flags );
}

void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
{
if( !font || !font->valid ) return;
Expand Down
30 changes: 20 additions & 10 deletions engine/client/cl_frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ CL_GetStudioEstimatedFrame
====================
*/
float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
static float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
studiohdr_t *pstudiohdr;
mstudioseqdesc_t *pseqdesc;
Expand All @@ -255,7 +255,7 @@ float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc );
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc, cl.time );
}
}

Expand Down Expand Up @@ -971,9 +971,25 @@ all the visible entities should pass this filter
*/
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
{
qboolean draw_player = true;

if( !ent || !ent->model )
return false;

// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;

if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
{
// we don't draw player in default renderer in firstperson mode
// but let the client.dll know about player entity anyway
// for use in custom renderers
draw_player = false;
}
}

// check for adding this entity
if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name ))
{
Expand All @@ -983,14 +999,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false;
}

// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;

if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
}
if( !draw_player )
return false;

if( entityType == ET_BEAM )
{
Expand Down
Loading

0 comments on commit 4aa37fc

Please sign in to comment.