diff --git a/engine/client/cd_win.c b/engine/client/cd_win.c index 7e633df29..b75e3dfbc 100644 --- a/engine/client/cd_win.c +++ b/engine/client/cd_win.c @@ -23,7 +23,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "winquake.h" -#ifdef WINRT +#ifndef HAVE_CDPLAYER + //nothing +#elif defined(WINRT) #include "cd_null.c" #else @@ -54,7 +56,7 @@ int CDAudio_GetAudioDiskInfo(void) mciStatusParms.dwItem = MCI_STATUS_READY; mciStatusParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); if (dwReturn) { Con_DPrintf("CDAudio: drive ready test - get status failed\n"); @@ -68,7 +70,7 @@ int CDAudio_GetAudioDiskInfo(void) mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; mciStatusParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); if (dwReturn) { Con_DPrintf("CDAudio: get tracks - status failed\n"); @@ -86,7 +88,7 @@ qboolean CDAudio_Startup(void) { DWORD dwReturn; static MCI_OPEN_PARMSA mciOpenParms; - static MCI_SET_PARMS mciSetParms; + static MCI_SET_PARMS mciSetParms; if (initializefailed) return false; @@ -105,17 +107,17 @@ qboolean CDAudio_Startup(void) } wDeviceID = mciOpenParms.wDeviceID; - // Set the time format to frames. vista+ simply cannot come with converting to/from seconds, or something (notifies don't work, status stays playing, position stops updating at about 3 frames from the end of the track). - mciSetParms.dwTimeFormat = MCI_FORMAT_MSF; + // Set the time format to frames. vista+ simply cannot come with converting to/from seconds, or something (notifies don't work, status stays playing, position stops updating at about 3 frames from the end of the track). + mciSetParms.dwTimeFormat = MCI_FORMAT_MSF; mciSetParms.dwCallback = (DWORD_PTR)mainwindow; dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &mciSetParms); - if (dwReturn) - { + if (dwReturn) + { Con_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", (int)dwReturn); - mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)NULL); + mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)NULL); initializefailed = true; return 0; - } + } initialized = true; @@ -143,7 +145,7 @@ void CDAudio_Eject(void) DWORD dwReturn; dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD_PTR)NULL); - if (dwReturn) + if (dwReturn) Con_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", (int)dwReturn); } @@ -152,7 +154,7 @@ void CDAudio_CloseDoor(void) DWORD dwReturn; dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD_PTR)NULL); - if (dwReturn) + if (dwReturn) Con_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", (int)dwReturn); } @@ -187,7 +189,7 @@ DWORD FramesToMSF(DWORD in) void CDAudio_Play(int track) { DWORD dwReturn; - static MCI_PLAY_PARMS mciPlayParms; + static MCI_PLAY_PARMS mciPlayParms; static MCI_STATUS_PARMS mciStatusParms; DWORD trackstartposition; @@ -201,7 +203,7 @@ void CDAudio_Play(int track) mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK; mciStatusParms.dwTrack = track; mciStatusParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); if (dwReturn) { Con_DPrintf("MCI_STATUS failed (%i)\n", (int)dwReturn); @@ -217,7 +219,7 @@ void CDAudio_Play(int track) mciStatusParms.dwItem = MCI_STATUS_POSITION; mciStatusParms.dwTrack = track; mciStatusParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); if (dwReturn) { Con_DPrintf("MCI_STATUS failed (%i)\n", (int)dwReturn); @@ -229,7 +231,7 @@ void CDAudio_Play(int track) mciStatusParms.dwItem = MCI_STATUS_LENGTH; mciStatusParms.dwTrack = track; mciStatusParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); + dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms); if (dwReturn) { Con_DPrintf("MCI_STATUS failed (%i)\n", (int)dwReturn); @@ -237,10 +239,10 @@ void CDAudio_Play(int track) } //set up to play from start to start+length - mciPlayParms.dwFrom = trackstartposition; + mciPlayParms.dwFrom = trackstartposition; mciPlayParms.dwTo = resumeend = FramesToMSF(MSFToFrames(trackstartposition) + MSFToFrames(mciStatusParms.dwReturn) - 8); //-8 to avoid microsoft's potential fuck ups - mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)(LPVOID) &mciPlayParms); + mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; + dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)(LPVOID) &mciPlayParms); if (dwReturn) { Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", (int)dwReturn); @@ -263,7 +265,7 @@ void CDAudio_Stop(void) pollneeded = false; dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD_PTR)NULL); - if (dwReturn) + if (dwReturn) Con_DPrintf("MCI_STOP failed (%i)\n", (int)dwReturn); } @@ -278,7 +280,7 @@ void CDAudio_Pause(void) mciGenericParms.dwCallback = (DWORD_PTR)mainwindow; dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD_PTR)(LPVOID) &mciGenericParms); - if (dwReturn) + if (dwReturn) Con_DPrintf("MCI_PAUSE failed (%i)\n", (int)dwReturn); pollneeded = false; @@ -288,15 +290,15 @@ void CDAudio_Pause(void) void CDAudio_Resume(void) { DWORD dwReturn; - static MCI_PLAY_PARMS mciPlayParms; + static MCI_PLAY_PARMS mciPlayParms; if (!bgmvolume.value) return; - mciPlayParms.dwFrom = resumeend; - mciPlayParms.dwTo = resumeend; - mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; - dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR)(LPVOID) &mciPlayParms); + mciPlayParms.dwFrom = resumeend; + mciPlayParms.dwTo = resumeend; + mciPlayParms.dwCallback = (DWORD_PTR)mainwindow; + dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR)(LPVOID) &mciPlayParms); if (dwReturn) { Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", (int)dwReturn); diff --git a/engine/client/cdaudio.h b/engine/client/cdaudio.h index 9c7f4133b..953733b97 100644 --- a/engine/client/cdaudio.h +++ b/engine/client/cdaudio.h @@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CDPLAYER void CDAudio_Init(void); qboolean CDAudio_Startup(void); //called when the cd isn't currently valid. returns if its valid or not. int CDAudio_GetAudioDiskInfo(void);//returns number of tracks available, or 0 if the cd is not valid. @@ -29,7 +30,11 @@ void CDAudio_Eject(void); void CDAudio_CloseDoor(void); void CDAudio_Shutdown(void); void CDAudio_Update(void); - -void CDAudio_TrackEnded(void); - +#else +#define CDAudio_Update() +#define CDAudio_Init() +#define CDAudio_Shutdown() +#define CDAudio_Pause() +#define CDAudio_Resume() +#endif diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 347cd37fd..a796a343c 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -5043,7 +5043,7 @@ double Host_Frame (double time) double idlesec = 1.0 / cl_idlefps.value; if (idlesec > 0.1) idlesec = 0.1; // limit to at least 10 fps -#if !defined(NOMEDIA) +#ifdef HAVE_MEDIA_ENCODER if (Media_Capturing()) idlesec = 0; #endif @@ -5101,7 +5101,7 @@ double Host_Frame (double time) maxfps = 10; if (maxfps > 0 -#if !defined(NOMEDIA) +#ifdef HAVE_MEDIA_ENCODER && Media_Capturing() != 2 #endif ) @@ -5416,7 +5416,7 @@ void CL_StartCinematicOrMenu(void) } //and any startup cinematics -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER #ifndef CLIENTONLY if (!sv.state) #endif @@ -5438,7 +5438,7 @@ void CL_StartCinematicOrMenu(void) Media_PlayFilm("video/idlog.cin", true); #ifndef NOLEGACY - //and for fun: + //and for fun (blame spirit): if (COM_FCheckExists("data/local/video/New_Bliz640x480.bik")) Media_PlayFilm("av:data/local/video/New_Bliz640x480.bik", true); if (COM_FCheckExists("data/local/video/BlizNorth640x480.bik")) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 64224bc4c..a5fea9ecf 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -26,6 +26,7 @@ void CL_GetNumberedEntityInfo (int num, float *org, float *ang); void CLDP_ParseDarkPlaces5Entities(void); static void CL_SetStatNumeric (int pnum, int stat, int ivalue, float fvalue); #define CL_SetStatInt(pnum,stat,ival) do{int thevalue=ival; CL_SetStatNumeric(pnum,stat,thevalue,thevalue);}while(0) +#define CL_SetStatFloat(pnum,stat,fval) do{float thevalue=fval; CL_SetStatNumeric(pnum,stat,thevalue,thevalue);}while(0) static qboolean CL_CheckModelResources (char *name); #ifdef NQPROT static char *CLNQ_ParseProQuakeMessage (char *s); @@ -1617,7 +1618,7 @@ void CL_RequestNextDownload (void) if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED) { Con_Printf("\n\n-------------\n" CON_ERROR "Couldn't download \"%s\" - cannot fully connect\n", cl.worldmodel?cl.worldmodel->name:"unknown"); -#if !defined(NOMEDIA) +#ifdef HAVE_MEDIA_ENCODER if (cls.demoplayback && Media_Capturing()) { Con_Printf(CON_ERROR "Aborting capture\n"); @@ -3730,7 +3731,8 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); void CLNQ_ParseClientdata (void) { int i; - player_state_t *pl = &cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playerview[0].playernum]; + const int seat = 0; + player_state_t *pl = &cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playerview[seat].playernum]; unsigned int bits; @@ -3754,16 +3756,14 @@ void CLNQ_ParseClientdata (void) for (i=0 ; i<3 ; i++) { if (bits & (SU_PUNCH1<capturing = 0; +#ifdef HAVE_MEDIA_ENCODER + outptr->capturing = Media_Capturing(); #else - outptr->capturing = Media_Capturing(); + outptr->capturing = 0; #endif } diff --git a/engine/client/client.h b/engine/client/client.h index bbc5ccdb9..c1e55d95b 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -665,7 +665,10 @@ struct playerview_s float predicted_step; #endif - float punchangle; // temporary view kick from weapon firing + //temporary view kick from weapon firing, angles+origins + float punchangle_cl; // qw-style angles + vec3_t punchangle_sv; // nq-style + vec3_t punchorigin; // nq-style float v_dmg_time; //various view knockbacks. float v_dmg_roll; @@ -1578,6 +1581,9 @@ void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale); struct model_s; void CL_AddVWeapModel(entity_t *player, struct model_s *model); +typedef struct cin_s cin_t; +#ifdef HAVE_MEDIA_DECODER + /*q2 cinematics*/ struct cinematics_s; void CIN_StopCinematic (struct cinematics_s *cin); @@ -1594,26 +1600,13 @@ typedef enum CINSTATE_ENDED, CINSTATE_FLUSHED, //video will restart from beginning } cinstates_t; -typedef struct cin_s cin_t; -#ifdef NOMEDIA -#define Media_Playing() false -#define Media_Init() (void)0 -#define Media_PlayingFullScreen() false -#define Media_PlayFilm(n,e) false -#define Media_StopFilm(a) (void)true -#else /*media playing system*/ qboolean Media_PlayingFullScreen(void); -void Media_Init(void); qboolean Media_PlayFilm(char *name, qboolean enqueue); qboolean Media_StopFilm(qboolean all); struct cin_s *Media_StartCin(char *name); texid_tf Media_UpdateForShader(cin_t *cin); void Media_ShutdownCin(cin_t *cin); -#endif -qboolean Media_NamedTrack(const char *initialtrack, const char *looptrack); //new background music interface -void Media_NumberedTrack(unsigned int initialtrack, unsigned int looptrack); //legacy cd interface for protocols that only support numbered tracks. -void Media_EndedTrack(void); //cd is no longer running, media code needs to pick a new track (cd track or faketrack) //these accept NULL for cin to mean the current fullscreen video void Media_Send_Command(cin_t *cin, const char *command); @@ -1626,6 +1619,18 @@ void Media_SetState(cin_t *cin, cinstates_t newstate); cinstates_t Media_GetState(cin_t *cin); const char *Media_Send_GetProperty(cin_t *cin, const char *key); +#else +#define Media_Playing() false +#define Media_PlayingFullScreen() false +#define Media_PlayFilm(n,e) false +#define Media_StopFilm(a) (void)true +#endif + +void Media_Init(void); +qboolean Media_NamedTrack(const char *initialtrack, const char *looptrack); //new background music interface +void Media_NumberedTrack(unsigned int initialtrack, unsigned int looptrack); //legacy cd interface for protocols that only support numbered tracks. +void Media_EndedTrack(void); //cd is no longer running, media code needs to pick a new track (cd track or faketrack) + void MVD_Interpolate(void); int Stats_GetKills(int playernum); diff --git a/engine/client/clq2_cin.c b/engine/client/clq2_cin.c index 30c7db3b0..3e5cecdd2 100644 --- a/engine/client/clq2_cin.c +++ b/engine/client/clq2_cin.c @@ -1,5 +1,5 @@ #include "quakedef.h" -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER typedef struct { diff --git a/engine/client/console.c b/engine/client/console.c index 629ad7b84..a314d2286 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -875,7 +875,7 @@ void Con_PrintCon (console_t *con, const char *txt, unsigned int parseflags) if (parseflags & PFS_NONOTIFY) con->current->flags |= CONL_NONOTIFY; -#if defined(_WIN32) && !defined(NOMEDIA) && !defined(WINRT) +#if defined(HAVE_SPEECHTOTEXT) if (con->current) TTS_SayConString((conchar_t*)(con->current+1)); #endif @@ -2321,7 +2321,7 @@ void Con_DrawConsole (int lines, qboolean noback) if (shader) { int top = 8; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER cin_t *cin = R_ShaderGetCinematic(shader); if (cin) { diff --git a/engine/client/keys.c b/engine/client/keys.c index 4cb2d3c1f..8a56fcc80 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -424,7 +424,7 @@ int Con_Navigate(console_t *con, char *line) { if (con->backshader) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER cin_t *cin = R_ShaderGetCinematic(con->backshader); if (cin) { @@ -1034,7 +1034,7 @@ void Key_ConsoleRelease(console_t *con, int key, int unicode) // if (con->buttonsdown == CB_MOVE) //window title(move) con->buttonsdown = CB_NONE; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (con->backshader) { cin_t *cin = R_ShaderGetCinematic(con->backshader); @@ -1513,7 +1513,7 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key) //console does not have any way to accept input, so don't try giving it any. if (!con->linebuffered) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (con->backshader) { cin_t *cin = R_ShaderGetCinematic(con->backshader); @@ -2497,7 +2497,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down if (Key_Dest_Has(kdm_gmenu)) MP_Keyup (key, unicode, devid); #endif -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (Media_PlayingFullScreen()) Media_Send_KeyEvent(NULL, key, unicode, down?0:1); #endif @@ -2556,7 +2556,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down Key_Dest_Remove(kdm_cwindows); } -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (Media_PlayingFullScreen()) { Media_Send_KeyEvent(NULL, key, unicode, down?0:1); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 6521a03f1..2cf27603a 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -8,21 +8,109 @@ #endif #include "shader.h" -#if !defined(NOMEDIA) -#if defined(_WIN32) && !defined(WINRT) && !defined(NOMEDIAMENU) -//#define WINAMP +#if defined(HAVE_JUKEBOX) + #if defined(_WIN32) && !defined(WINRT) && !defined(NOMEDIAMENU) + //#define WINAMP + #endif #endif -#if defined(_WIN32) && !defined(WINRT) -#define WINAVI +#if (defined(HAVE_MEDIA_DECODER) || defined(HAVE_MEDIA_ENCODER)) && defined(_WIN32) && !defined(WINRT) + #define HAVE_API_VFW #endif -#if defined(__linux__) && !defined(ANDROID) - //should really include posix 2001 systems in general - #define HAVE_STATVFS +#ifdef HAVE_MEDIA_ENCODER + #if defined(__linux__) && !defined(ANDROID) + //should really include posix 2001 systems in general + #define HAVE_STATVFS + #endif + #ifdef HAVE_STATVFS + #include + #endif #endif -#ifdef HAVE_STATVFS - #include + + +#ifdef _WIN32 + #include "winquake.h" #endif +#if defined(AVAIL_MP3_ACM) || defined(HAVE_API_VFW) +//equivelent to +//#include +#undef CDECL //windows is stupid at times. +#define CDECL __cdecl + +#if defined(_MSC_VER) && (_MSC_VER < 1300) + #define DWORD_PTR DWORD +#endif + +DECLARE_HANDLE(HACMSTREAM); +typedef HACMSTREAM *LPHACMSTREAM; +DECLARE_HANDLE(HACMDRIVER); +typedef struct { + DWORD cbStruct; + DWORD fdwStatus; + DWORD_PTR dwUser; + LPBYTE pbSrc; + DWORD cbSrcLength; + DWORD cbSrcLengthUsed; + DWORD_PTR dwSrcUser; + LPBYTE pbDst; + DWORD cbDstLength; + DWORD cbDstLengthUsed; + DWORD_PTR dwDstUser; + DWORD dwReservedDriver[10]; +} ACMSTREAMHEADER, *LPACMSTREAMHEADER; +#define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004 + + + + +//mingw workarounds +#define LPWAVEFILTER void * +#include + +MMRESULT (WINAPI *qacmStreamUnprepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare); +MMRESULT (WINAPI *qacmStreamConvert) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert); +MMRESULT (WINAPI *qacmStreamPrepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare); +MMRESULT (WINAPI *qacmStreamOpen) (LPHACMSTREAM phas, HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, LPWAVEFILTER pwfltr, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); +MMRESULT (WINAPI *qacmStreamClose) (HACMSTREAM has, DWORD fdwClose); + +static qboolean qacmStartup(void) +{ + static int inited; + static dllhandle_t *module; + if (!inited) + { + dllfunction_t funcs[] = + { + {(void*)&qacmStreamUnprepareHeader, "acmStreamUnprepareHeader"}, + {(void*)&qacmStreamConvert, "acmStreamConvert"}, + {(void*)&qacmStreamPrepareHeader, "acmStreamPrepareHeader"}, + {(void*)&qacmStreamOpen, "acmStreamOpen"}, + {(void*)&qacmStreamClose, "acmStreamClose"}, + {NULL,NULL} + }; + inited = true; + module = Sys_LoadLibrary("msacm32.dll", funcs); + } + + return module?true:false; +} +#endif + +static char media_currenttrack[MAX_QPATH]; + +//higher bits have priority (if they have something to play). +#define MEDIA_GAMEMUSIC (1u<<0) //cd music. also music command etc. +#ifdef HAVE_JUKEBOX +#define MEDIA_CVARLIST (1u<<1) //cvar abuse. handy for preserving times when switching tracks. +#define MEDIA_PLAYLIST (1u<<2) // +static unsigned int media_playlisttypes; +static unsigned int media_playlistcurrent; + +//cvar abuse +static int music_playlist_last; +static cvar_t music_playlist_index = CVAR("music_playlist_index", "-1"); +// created dynamically: CVAR("music_playlist_list0+", ""), +// created dynamically: CVAR("music_playlist_sampleposition0+", "-1"), typedef struct mediatrack_s{ @@ -32,30 +120,43 @@ typedef struct mediatrack_s{ struct mediatrack_s *next; } mediatrack_t; -qboolean media_fadeout; -float media_fadeouttime; - //info about the current stuff that is playing. -static char media_currenttrack[MAX_QPATH]; static char media_friendlyname[MAX_QPATH]; + + + +int lasttrackplayed; + +cvar_t media_shuffle = CVAR("media_shuffle", "1"); +cvar_t media_repeat = CVAR("media_repeat", "1"); +#ifdef WINAMP +cvar_t media_hijackwinamp = CVAR("media_hijackwinamp", "0"); #endif -//higher bits have priority (if they have something to play). -#define MEDIA_GAMEMUSIC (1u<<0) //cd music. also music command etc. -#define MEDIA_CVARLIST (1u<<1) //cvar abuse. handy for preserving times when switching tracks. -#define MEDIA_PLAYLIST (1u<<2) // -#if !defined(NOMEDIA) -static unsigned int media_playlisttypes; -#endif -static unsigned int media_playlistcurrent; +int selectedoption=-1; +int numtracks; +int nexttrack=-1; +mediatrack_t *tracks; +char media_iofilename[MAX_OSPATH]=""; + +#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS) +void Media_LoadTrackNames (char *listname); +int loadedtracknames; +#endif +qboolean Media_EvaluateNextTrack(void); + +#else +#define NOMEDIAMENU //the media menu requires us to be able to queue up random tracks and stuff. +#endif + +#ifdef HAVE_CDPLAYER static int cdplayingtrack; //currently playing cd track (becomes 0 when paused) static int cdpausedtrack; //currently paused cd track //info about (fake)cd tracks that we want to play int cdplaytracknum; -static char cdplaytrack[MAX_QPATH]; -static char cdloopingtrack[MAX_QPATH]; + //info about (fake)cd tracks that we could play if asked. #define REMAPPED_TRACKS 256 static struct @@ -64,23 +165,115 @@ static struct } cdremap[REMAPPED_TRACKS]; static qboolean cdenabled; static int cdnumtracks; //maximum cd track we can play. - - -//cvar abuse -#if !defined(NOMEDIA) -static int music_playlist_last; -static cvar_t music_playlist_index = CVAR("music_playlist_index", "-1"); -// created dynamically: CVAR("music_playlist_list0+", ""), -// created dynamically: CVAR("music_playlist_sampleposition0+", "-1"), #endif +static char media_playtrack[MAX_QPATH]; //name of track to play next/now +static char media_loopingtrack[MAX_QPATH]; //name of track to loop afterwards +qboolean media_fadeout; +float media_fadeouttime; + +//whatever music track was previously playing has terminated. +//return value is the new sample to start playing. +//*starttime says the time into the track that we should resume playing at +//this is on the main thread with the mixer locked, its safe to do stuff, but try not to block +char *Media_NextTrack(int musicchannelnum, float *starttime) +{ + if (bgmvolume.value <= 0) + return NULL; + + if (media_fadeout) + { + if (S_Music_Playing(musicchannelnum)) + return NULL; //can't pick a new track until they've all stopped. + + //okay, it has actually stopped everywhere. + } + media_fadeout = false; //it has actually ended now + + Q_strncpyz(media_currenttrack, "", sizeof(media_currenttrack)); +#ifdef HAVE_JUKEBOX + Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); + + music_playlist_index.modified = false; + music_playlist_last = -1; + media_playlistcurrent = 0; + + if (!media_playlistcurrent && (media_playlisttypes & MEDIA_PLAYLIST)) + { +#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS) + if (!loadedtracknames) + Media_LoadTrackNames("sound/media.m3u"); +#endif + if (Media_EvaluateNextTrack()) + { + media_playlistcurrent = MEDIA_PLAYLIST; + return media_currenttrack; + } + } + if (!media_playlistcurrent && (media_playlisttypes & MEDIA_CVARLIST)) + { + if (music_playlist_index.ival >= 0) + { + cvar_t *list = Cvar_Get(va("music_playlist_list%i", music_playlist_index.ival), "", 0, "compat"); + if (list) + { + cvar_t *sampleposition = Cvar_Get(va("music_playlist_sampleposition%i", music_playlist_index.ival), "-1", 0, "compat"); + Q_snprintfz(media_currenttrack, sizeof(media_currenttrack), "sound/cdtracks/%s", list->string); + Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); + media_playlistcurrent = MEDIA_CVARLIST; + music_playlist_last = music_playlist_index.ival; + if (sampleposition) + { + *starttime = sampleposition->value; + if (*starttime == -1) + *starttime = 0; + } + else + *starttime = 0; + } + } + } + + if (!media_playlistcurrent && (media_playlisttypes & MEDIA_GAMEMUSIC)) +#endif + { +#ifdef HAVE_CDPLAYER + if (cdplaytracknum) + { + if (cdplayingtrack != cdplaytracknum && cdpausedtrack != cdplaytracknum) + { + CDAudio_Play(cdplaytracknum); + cdplayingtrack = cdplaytracknum; + } +#ifdef HAVE_JUKEBOX + media_playlistcurrent = MEDIA_GAMEMUSIC; +#endif + return ""; + } +#endif + if (*media_playtrack) + { + Q_strncpyz(media_currenttrack, media_playtrack, sizeof(media_currenttrack)); +#ifdef HAVE_JUKEBOX + Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); + media_playlistcurrent = MEDIA_GAMEMUSIC; +#endif + } + } + return media_currenttrack; +} + +//begin cross-fading static qboolean Media_Changed (unsigned int mediatype) { +#ifdef HAVE_JUKEBOX //something changed, but it has a lower priority so we don't care if (mediatype < media_playlistcurrent) return false; +#endif +#ifdef HAVE_CDPLAYER //make sure we're not playing any cd music. if (cdplayingtrack || cdpausedtrack) { @@ -88,14 +281,41 @@ static qboolean Media_Changed (unsigned int mediatype) cdpausedtrack = 0; CDAudio_Stop(); } - -#if !defined(NOMEDIA) +#endif media_fadeout = true; media_fadeouttime = realtime; -#endif return true; } +//returns the new volume the sample should be at, to support crossfading. +//if we return < 0, the mixer will know to kill whatever is currently playing, ready for a new track. +//this is on the main thread with the mixer locked, its safe to do stuff, but try not to block +float Media_CrossFade(int musicchanel, float vol, float time) +{ + if (media_fadeout) + { + float fadetime = 1; + float frac = (fadetime + media_fadeouttime - realtime)/fadetime; + vol *= frac; + } +#ifdef HAVE_JUKEBOX + else if (music_playlist_index.modified) + { + if (Media_Changed(MEDIA_CVARLIST)) + { + if (music_playlist_last >= 0) + { + cvar_t *sampleposition = Cvar_Get(va("music_playlist_sampleposition%i", music_playlist_last), "-1", 0, "compat"); + if (sampleposition && sampleposition->value != -1) + Cvar_SetValue(sampleposition, time); + } + vol = -1; //kill it NOW + } + } +#endif + return vol; +} + void Media_WriteCurrentTrack(sizebuf_t *buf) { //fixme: for demo playback @@ -103,11 +323,11 @@ void Media_WriteCurrentTrack(sizebuf_t *buf) MSG_WriteByte (buf, 0); } -//fake cd tracks. +//controls which music track should be playing right now +//track and looptrack will usually be the same thing, track is what to play NOW, looptrack is what to keep re-playing after, or "-" for stop. qboolean Media_NamedTrack(const char *track, const char *looptrack) { unsigned int tracknum; -#if !defined(NOMEDIA) static char *path[] = { "music/", @@ -118,8 +338,10 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) static char *ext[] = { "", +#ifdef AVAIL_OGGVORBIS ".ogg", -#ifdef WINAVI +#endif +#if defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB) ".mp3", #endif ".wav", @@ -128,7 +350,6 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) char trackname[MAX_QPATH]; int ie, ip; qboolean found = false; -#endif char *trackend; if (!track || !*track) //ignore calls if the primary track is invalid. whatever is already playing will continue to play. @@ -136,10 +357,14 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) if (!looptrack || !*looptrack) //null or empty looptrack loops using the primary track, for compat with q3. looptrack = track; + if (!strcmp(looptrack, "-")) //- for the looptrack argument can be used to prevent looping. + looptrack = ""; + //check if its a proper number (0123456789 without any other weird stuff. if so, we can use fake track paths or actual cd tracks) - tracknum = strtoul(track, &trackend, 0); + tracknum = strtoul(track, &trackend, 10); if (*trackend) - tracknum = 0; + tracknum = 0; //not a single integer +#ifdef HAVE_CDPLAYER if (tracknum > 0 && tracknum < REMAPPED_TRACKS && *cdremap[tracknum].fname) { //remap the track if its remapped. track = cdremap[tracknum].fname; @@ -147,33 +372,41 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) if (*trackend) tracknum = 0; } +#endif - if (!strcmp(looptrack, "-")) //- for the looptrack argument can be used to prevent looping. - looptrack = ""; -#ifndef NOMEDIA +#ifdef NOLEGACY + if (!tracknum) //might as well require exact file + { + Q_snprintfz(trackname, sizeof(trackname), "%s", track); + found = COM_FCheckExists(trackname); + } + else +#endif for(ip = 0; path[ip] && !found; ip++) { if (tracknum) { - if (tracknum <= 999) + if (*path[ip]) { - for(ie = 0; ext[ie] && !found; ie++) + if (tracknum <= 999) { - Q_snprintfz(trackname, sizeof(trackname), "%strack%03i%s", path[ip], tracknum, ext[ie]); - found = COM_FCheckExists(trackname); + for(ie = 0; ext[ie] && !found; ie++) + { + Q_snprintfz(trackname, sizeof(trackname), "%strack%03u%s", path[ip], tracknum, ext[ie]); + found = COM_FCheckExists(trackname); + } } - } - if (tracknum <= 99) - { - for(ie = 0; ext[ie] && !found; ie++) + if (tracknum <= 99) { - Q_snprintfz(trackname, sizeof(trackname), "%strack%02i%s", path[ip], tracknum, ext[ie]); - found = COM_FCheckExists(trackname); + for(ie = 0; ext[ie] && !found; ie++) + { + Q_snprintfz(trackname, sizeof(trackname), "%strack%02u%s", path[ip], tracknum, ext[ie]); + found = COM_FCheckExists(trackname); + } } } } - - if (!found) + else { for(ie = 0; ext[ie] && !found; ie++) { @@ -185,16 +418,19 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) if (found) { +#ifdef HAVE_CDPLAYER cdplaytracknum = 0; - Q_strncpyz(cdplaytrack, trackname, sizeof(cdplaytrack)); - Q_strncpyz(cdloopingtrack, looptrack, sizeof(cdloopingtrack)); +#endif + Q_strncpyz(media_playtrack, trackname, sizeof(media_playtrack)); + Q_strncpyz(media_loopingtrack, looptrack, sizeof(media_loopingtrack)); Media_Changed(MEDIA_GAMEMUSIC); return true; } -#endif + +#ifdef HAVE_CDPLAYER if (tracknum && cdenabled) { - Q_strncpyz(cdloopingtrack, looptrack, sizeof(cdloopingtrack)); + Q_strncpyz(media_loopingtrack, looptrack, sizeof(media_loopingtrack)); //couldn't do a faketrack, resort to actual cd tracks, if we're allowed if (!CDAudio_Startup()) @@ -212,11 +448,11 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack) return true; //already playing, don't need to do anything cdplaytracknum = tracknum; - Q_strncpyz(cdplaytrack, "", sizeof(cdplaytrack)); - Q_strncpyz(cdloopingtrack, "", sizeof(cdloopingtrack)); + Q_strncpyz(media_playtrack, "", sizeof(media_playtrack)); Media_Changed(MEDIA_GAMEMUSIC); return true; } +#endif return false; } @@ -239,19 +475,184 @@ void Media_NumberedTrack(unsigned int initialtrack, unsigned int looptrack) void Media_EndedTrack(void) { +#ifdef HAVE_CDPLAYER cdplayingtrack = 0; cdpausedtrack = 0; +#endif - if (*cdloopingtrack) - Media_NamedTrack(cdloopingtrack, cdloopingtrack); + if (*media_loopingtrack) + Media_NamedTrack(media_loopingtrack, media_loopingtrack); } -#if !defined(NOMEDIA) + +void Media_SetPauseTrack(qboolean paused) +{ +#ifdef HAVE_CDPLAYER + if (paused) + { + if (!cdplayingtrack) + return; + cdpausedtrack = cdplayingtrack; + cdplayingtrack = 0; + CDAudio_Pause(); + } + else + { + if (!cdpausedtrack) + return; + cdplayingtrack = cdpausedtrack; + cdpausedtrack = 0; + CDAudio_Resume(); + } +#endif +} + +#ifdef HAVE_CDPLAYER +void CD_f (void) +{ + char *command; + int ret; + int n; + + if (Cmd_Argc() < 2) + return; + + command = Cmd_Argv (1); + + if (Q_strcasecmp(command, "play") == 0) + { + Media_NamedTrack(Cmd_Argv(2), "-"); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + if (Cmd_Argc() < 4) + Media_NamedTrack(Cmd_Argv(2), NULL); + else + Media_NamedTrack(Cmd_Argv(2), Cmd_Argv(3)); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < REMAPPED_TRACKS; n++) + if (*cdremap[n].fname) + Con_Printf(" %u -> %s\n", n, cdremap[n].fname); + return; + } + for (n = 1; n <= ret; n++) + Q_strncpyz(cdremap[n].fname, Cmd_Argv (n+1), sizeof(cdremap[n].fname)); + return; + } + + if (Q_strcasecmp(command, "stop") == 0) + { + *media_playtrack = *media_loopingtrack = 0; + cdplaytracknum = 0; + Media_Changed(MEDIA_GAMEMUSIC); + return; + } + + if (!bgmvolume.value) + { + Con_Printf("Background music is disabled: %s is 0\n", bgmvolume.name); + return; + } + + if (!CDAudio_Startup()) + { + Con_Printf("No cd drive detected\n"); + return; + } + + if (Q_strcasecmp(command, "on") == 0) + { + cdenabled = true; + return; + } + + if (Q_strcasecmp(command, "off") == 0) + { + if (cdplayingtrack || cdpausedtrack) + CDAudio_Stop(); + cdenabled = false; + + *media_playtrack = *media_loopingtrack = 0; + cdplaytracknum = 0; + Media_Changed(MEDIA_GAMEMUSIC); + return; + } + + if (Q_strcasecmp(command, "reset") == 0) + { + cdenabled = true; + if (cdplayingtrack || cdpausedtrack) + CDAudio_Stop(); + for (n = 0; n < REMAPPED_TRACKS; n++) + strcpy(cdremap[n].fname, ""); + cdnumtracks = CDAudio_GetAudioDiskInfo(); + return; + } + + if (Q_strcasecmp(command, "close") == 0) + { + CDAudio_CloseDoor(); + return; + } + + if (cdnumtracks <= 0) + { + cdnumtracks = CDAudio_GetAudioDiskInfo(); + if (cdnumtracks < 0) + { + Con_Printf("No CD in player.\n"); + return; + } + } + + if (Q_strcasecmp(command, "pause") == 0) + { + Media_SetPauseTrack(true); + return; + } + + if (Q_strcasecmp(command, "resume") == 0) + { + Media_SetPauseTrack(false); + return; + } + + if (Q_strcasecmp(command, "eject") == 0) + { + if (cdplayingtrack || cdpausedtrack) + CDAudio_Stop(); + CDAudio_Eject(); + cdnumtracks = -1; + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + Con_Printf("%u tracks\n", cdnumtracks); + if (cdplayingtrack > 0) + Con_Printf("Currently %s track %u\n", *media_loopingtrack ? "looping" : "playing", cdplayingtrack); + else if (cdpausedtrack > 0) + Con_Printf("Paused %s track %u\n", *media_loopingtrack ? "looping" : "playing", cdpausedtrack); + return; + } +} +#endif -#include "winquake.h" + + +#ifdef HAVE_JUKEBOX #ifdef WINAMP @@ -262,22 +663,6 @@ HWND hwnd_winamp; qboolean Media_EvaluateNextTrack(void); -int lasttrackplayed; - -cvar_t media_shuffle = CVAR("media_shuffle", "1"); -cvar_t media_repeat = CVAR("media_repeat", "1"); -#ifdef WINAMP -cvar_t media_hijackwinamp = CVAR("media_hijackwinamp", "0"); -#endif - -int selectedoption=-1; -int numtracks; -int nexttrack=-1; -mediatrack_t *tracks; - -char media_iofilename[MAX_OSPATH]=""; - -int loadedtracknames; #ifdef WINAMP qboolean WinAmp_GetHandle (void) @@ -438,164 +823,6 @@ qboolean Media_EvaluateNextTrack(void) return true; } -void Media_SetPauseTrack(qboolean paused) -{ - if (paused) - { - if (!cdplayingtrack) - return; - cdpausedtrack = cdplayingtrack; - cdplayingtrack = 0; - CDAudio_Pause(); - } - else - { - if (!cdpausedtrack) - return; - cdplayingtrack = cdpausedtrack; - cdpausedtrack = 0; - CDAudio_Resume(); - } -} - -void CD_f (void) -{ - char *command; - int ret; - int n; - - if (Cmd_Argc() < 2) - return; - - command = Cmd_Argv (1); - - if (Q_strcasecmp(command, "play") == 0) - { - Media_NamedTrack(Cmd_Argv(2), "-"); - return; - } - - if (Q_strcasecmp(command, "loop") == 0) - { - if (Cmd_Argc() < 4) - Media_NamedTrack(Cmd_Argv(2), NULL); - else - Media_NamedTrack(Cmd_Argv(2), Cmd_Argv(3)); - return; - } - - if (Q_strcasecmp(command, "remap") == 0) - { - ret = Cmd_Argc() - 2; - if (ret <= 0) - { - for (n = 1; n < REMAPPED_TRACKS; n++) - if (*cdremap[n].fname) - Con_Printf(" %u -> %s\n", n, cdremap[n].fname); - return; - } - for (n = 1; n <= ret; n++) - Q_strncpyz(cdremap[n].fname, Cmd_Argv (n+1), sizeof(cdremap[n].fname)); - return; - } - - if (Q_strcasecmp(command, "stop") == 0) - { - *cdplaytrack = *cdloopingtrack = 0; - cdplaytracknum = 0; - Media_Changed(MEDIA_GAMEMUSIC); - return; - } - - if (!bgmvolume.value) - { - Con_Printf("Background music is disabled: %s is 0\n", bgmvolume.name); - return; - } - - if (!CDAudio_Startup()) - { - Con_Printf("No cd drive detected\n"); - return; - } - - if (Q_strcasecmp(command, "on") == 0) - { - cdenabled = true; - return; - } - - if (Q_strcasecmp(command, "off") == 0) - { - if (cdplayingtrack || cdpausedtrack) - CDAudio_Stop(); - cdenabled = false; - - *cdplaytrack = *cdloopingtrack = 0; - cdplaytracknum = 0; - Media_Changed(MEDIA_GAMEMUSIC); - return; - } - - if (Q_strcasecmp(command, "reset") == 0) - { - cdenabled = true; - if (cdplayingtrack || cdpausedtrack) - CDAudio_Stop(); - for (n = 0; n < REMAPPED_TRACKS; n++) - strcpy(cdremap[n].fname, ""); - cdnumtracks = CDAudio_GetAudioDiskInfo(); - return; - } - - if (Q_strcasecmp(command, "close") == 0) - { - CDAudio_CloseDoor(); - return; - } - - if (cdnumtracks <= 0) - { - cdnumtracks = CDAudio_GetAudioDiskInfo(); - if (cdnumtracks < 0) - { - Con_Printf("No CD in player.\n"); - return; - } - } - - if (Q_strcasecmp(command, "pause") == 0) - { - Media_SetPauseTrack(true); - return; - } - - if (Q_strcasecmp(command, "resume") == 0) - { - Media_SetPauseTrack(false); - return; - } - - if (Q_strcasecmp(command, "eject") == 0) - { - if (cdplayingtrack || cdpausedtrack) - CDAudio_Stop(); - CDAudio_Eject(); - cdnumtracks = -1; - return; - } - - if (Q_strcasecmp(command, "info") == 0) - { - Con_Printf("%u tracks\n", cdnumtracks); - if (cdplayingtrack > 0) - Con_Printf("Currently %s track %u\n", *cdloopingtrack ? "looping" : "playing", cdplayingtrack); - else if (cdpausedtrack > 0) - Con_Printf("Paused %s track %u\n", *cdloopingtrack ? "looping" : "playing", cdpausedtrack); - return; - } -} - //actually, this func just flushes and states that it should be playing. the ambientsound func actually changes the track. void Media_Next_f (void) { @@ -1142,116 +1369,7 @@ void Media_LoadTrackNames (char *listname) } #endif -//mixer is locked, its safe to do stuff, but try not to block -float Media_CrossFade(int musicchanel, float vol, float time) -{ - if (media_fadeout) - { - float fadetime = 1; - float frac = (fadetime + media_fadeouttime - realtime)/fadetime; - vol *= frac; - } - else if (music_playlist_index.modified) - { - if (Media_Changed(MEDIA_CVARLIST)) - { - if (music_playlist_last >= 0) - { - cvar_t *sampleposition = Cvar_Get(va("music_playlist_sampleposition%i", music_playlist_last), "-1", 0, "compat"); - if (sampleposition && sampleposition->value != -1) - Cvar_SetValue(sampleposition, time); - } - vol = -1; //kill it NOW - } - } - return vol; -} - -//mixer is locked, its safe to do stuff, but try not to block -char *Media_NextTrack(int musicchannelnum, float *starttime) -{ - if (bgmvolume.value <= 0) - return NULL; - - if (media_fadeout) - { - if (S_Music_Playing(musicchannelnum)) - return NULL; //can't pick a new track until they've all stopped. - - //okay, it has actually stopped everywhere. - } - media_fadeout = false; //it has actually ended now - - music_playlist_index.modified = false; - music_playlist_last = -1; - media_playlistcurrent = 0; - Q_strncpyz(media_currenttrack, "", sizeof(media_currenttrack)); - Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); - if (!media_playlistcurrent && (media_playlisttypes & MEDIA_PLAYLIST)) - { -#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS) - if (!loadedtracknames) - Media_LoadTrackNames("sound/media.m3u"); #endif - if (Media_EvaluateNextTrack()) - { - media_playlistcurrent = MEDIA_PLAYLIST; - return media_currenttrack; - } - } - if (!media_playlistcurrent && (media_playlisttypes & MEDIA_CVARLIST)) - { - if (music_playlist_index.ival >= 0) - { - cvar_t *list = Cvar_Get(va("music_playlist_list%i", music_playlist_index.ival), "", 0, "compat"); - if (list) - { - cvar_t *sampleposition = Cvar_Get(va("music_playlist_sampleposition%i", music_playlist_index.ival), "-1", 0, "compat"); - Q_snprintfz(media_currenttrack, sizeof(media_currenttrack), "sound/cdtracks/%s", list->string); - Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); - media_playlistcurrent = MEDIA_CVARLIST; - music_playlist_last = music_playlist_index.ival; - if (sampleposition) - { - *starttime = sampleposition->value; - if (*starttime == -1) - *starttime = 0; - } - else - *starttime = 0; - } - } - } - if (!media_playlistcurrent && (media_playlisttypes & MEDIA_GAMEMUSIC)) - { - if (cdplaytracknum) - { - if (cdplayingtrack != cdplaytracknum && cdpausedtrack != cdplaytracknum) - { - CDAudio_Play(cdplaytracknum); - cdplayingtrack = cdplaytracknum; - } - media_playlistcurrent = MEDIA_GAMEMUSIC; - } - else if (*cdplaytrack) - { - Q_strncpyz(media_currenttrack, cdplaytrack, sizeof(media_currenttrack)); - Q_strncpyz(media_friendlyname, "", sizeof(media_friendlyname)); - media_playlistcurrent = MEDIA_GAMEMUSIC; - } - } - - return media_currenttrack; -} - - - - - - - - - @@ -1269,69 +1387,7 @@ char *Media_NextTrack(int musicchannelnum, float *starttime) #include "roq.h" -#ifdef WINAVI -#undef CDECL //windows is stupid at times. -#define CDECL __cdecl - -#if defined(_MSC_VER) && (_MSC_VER < 1300) -#define DWORD_PTR DWORD -#endif - -#if 0 -#include -#else -DECLARE_HANDLE(HACMSTREAM); -typedef HACMSTREAM *LPHACMSTREAM; -DECLARE_HANDLE(HACMDRIVER); -typedef struct { - DWORD cbStruct; - DWORD fdwStatus; - DWORD_PTR dwUser; - LPBYTE pbSrc; - DWORD cbSrcLength; - DWORD cbSrcLengthUsed; - DWORD_PTR dwSrcUser; - LPBYTE pbDst; - DWORD cbDstLength; - DWORD cbDstLengthUsed; - DWORD_PTR dwDstUser; - DWORD dwReservedDriver[10]; -} ACMSTREAMHEADER, *LPACMSTREAMHEADER; -#define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004 -#endif - -//mingw workarounds -#define LPWAVEFILTER void * -#include - -MMRESULT (WINAPI *qacmStreamUnprepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare); -MMRESULT (WINAPI *qacmStreamConvert) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert); -MMRESULT (WINAPI *qacmStreamPrepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare); -MMRESULT (WINAPI *qacmStreamOpen) (LPHACMSTREAM phas, HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, LPWAVEFILTER pwfltr, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen); -MMRESULT (WINAPI *qacmStreamClose) (HACMSTREAM has, DWORD fdwClose); - -static qboolean qacmStartup(void) -{ - static int inited; - static dllhandle_t *module; - if (!inited) - { - dllfunction_t funcs[] = - { - {(void*)&qacmStreamUnprepareHeader, "acmStreamUnprepareHeader"}, - {(void*)&qacmStreamConvert, "acmStreamConvert"}, - {(void*)&qacmStreamPrepareHeader, "acmStreamPrepareHeader"}, - {(void*)&qacmStreamOpen, "acmStreamOpen"}, - {(void*)&qacmStreamClose, "acmStreamClose"}, - {NULL,NULL} - }; - inited = true; - module = Sys_LoadLibrary("msacm32.dll", funcs); - } - - return module?true:false; -} - +#ifdef HAVE_API_VFW #if 0 #include #else @@ -1441,6 +1497,8 @@ static qboolean qAVIStartup(void) } #endif +#ifdef HAVE_MEDIA_DECODER + static char *cin_prop_buf; static size_t cin_prop_bufsize; struct cin_s @@ -1466,7 +1524,7 @@ struct cin_s texid_t texture; -#ifdef WINAVI +#ifdef HAVE_API_VFW struct { AVISTREAMINFOA vidinfo; PAVISTREAM pavivideo; @@ -1524,7 +1582,7 @@ shader_t *videoshader; ////////////////////////////////////////////////////////////////////////////////// //AVI Support (windows) -#ifdef WINAVI +#ifdef HAVE_API_VFW static void Media_WinAvi_Shutdown(struct cin_s *cin) { qAVIStreamGetFrameClose(cin->avi.pgf); @@ -2302,7 +2360,7 @@ cin_t *Media_StartCin(char *name) if (!cin) cin = Media_RoQ_TryLoad(name); #endif -#ifdef WINAVI +#ifdef HAVE_API_VFW if (!cin) cin = Media_WinAvi_TryLoad(name); #endif @@ -2717,6 +2775,9 @@ void Media_PlayVideoWindowed_f (void) Con_SetActive(con); } +#else +qboolean Media_ShowFilm(void){return false;} +#endif //HAVE_MEDIA_DECODER @@ -2731,9 +2792,7 @@ void Media_PlayVideoWindowed_f (void) - - - +#ifdef HAVE_MEDIA_ENCODER soundcardinfo_t *capture_fakesounddevice; @@ -2762,7 +2821,7 @@ int offscreen_captureframe; enum uploadfmt offscreen_format; #define CAPTURECODECDESC_DEFAULT "tga" -#ifdef WINAVI +#ifdef HAVE_API_VFW #define CAPTUREDRIVERDESC_AVI "avi: capture directly to avi (capturecodec should be a fourcc value).\n" #define CAPTURECODECDESC_AVI "With (win)avi, this should be a fourcc code like divx or xvid, may be blank for raw video.\n" #else @@ -2907,7 +2966,7 @@ static media_encoder_funcs_t capture_raw = capture_raw_end }; #endif -#if defined(WINAVI) +#if defined(HAVE_API_VFW) /*screenshot capture*/ struct capture_avi_ctx @@ -3906,8 +3965,20 @@ void Media_RecordDemo_f(void) if (!currentcapture_funcs) CL_Stopdemo_f(); //capturing failed for some reason } +#else -#if defined(_WIN32) && !defined(WINRT) +void Media_CaptureDemoEnd(void) {} +qboolean Media_PausedDemo(qboolean fortiming) {return false;} +double Media_TweekCaptureFrameTime(double oldtime, double time) { return oldtime+time ; } +void Media_RecordFrame (void) {} + +#endif + + + + + +#ifdef HAVE_SPEECHTOTEXT typedef struct ISpNotifySink ISpNotifySink; typedef void *ISpNotifyCallback; typedef void __stdcall SPNOTIFYCALLBACK(WPARAM wParam, LPARAM lParam); @@ -4596,88 +4667,12 @@ void STT_Init_f(void) } #endif -qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed); - -void Media_Init(void) -{ - int i; -#if defined(_WIN32) && !defined(WINRT) - Cmd_AddCommand("tts", TTS_Say_f); - Cmd_AddCommand("stt", STT_Init_f); - Cvar_Register(&tts_mode, "Gimmicks"); -#endif - -#if defined(WINAVI) - Media_RegisterEncoder(NULL, &capture_avi); -#endif -#ifdef _DEBUG - Media_RegisterEncoder(NULL, &capture_null); -#endif - Media_RegisterEncoder(NULL, &capture_raw); - - Cmd_AddCommand("playclip", Media_PlayVideoWindowed_f); - Cmd_AddCommand("playvideo", Media_PlayFilm_f); - Cmd_AddCommand("playfilm", Media_PlayFilm_f); - Cmd_AddCommand("cinematic", Media_PlayFilm_f); - Cmd_AddCommand("music_fforward", Media_FForward_f); - Cmd_AddCommand("music_rewind", Media_Rewind_f); - Cmd_AddCommand("music_next", Media_Next_f); - Cmd_AddCommand("media_next", Media_Next_f); - Cmd_AddCommand("music", Media_NamedTrack_f); - - Cvar_Register(&music_playlist_index, "compat"); - for (i = 0; i < 6; i++) - { - Cvar_Get(va("music_playlist_list%i", i), "", 0, "compat"); - Cvar_Get(va("music_playlist_sampleposition%i", i), "-1", 0, "compat"); - } - music_playlist_last = -1; - - Cmd_AddCommand("cd", CD_f); - cdenabled = false; - if (COM_CheckParm("-nocdaudio")) - cdenabled = false; - if (COM_CheckParm("-cdaudio")) - cdenabled = true; - - media_playlisttypes = MEDIA_PLAYLIST | MEDIA_GAMEMUSIC | MEDIA_CVARLIST; - - Cmd_AddCommand("capture", Media_RecordFilm_f); - Cmd_AddCommand("capturedemo", Media_RecordDemo_f); - Cmd_AddCommand("capturestop", Media_StopRecordFilm_f); - Cmd_AddCommand("capturepause", Media_CapturePause_f); - - Cvar_Register(&capturemessage, "AVI capture controls"); - Cvar_Register(&capturesound, "AVI capture controls"); - Cvar_Register(&capturerate, "AVI capture controls"); - Cvar_Register(&capturewidth, "AVI capture controls"); - Cvar_Register(&captureheight, "AVI capture controls"); - Cvar_Register(&capturedriver, "AVI capture controls"); - Cvar_Register(&capturecodec, "AVI capture controls"); - Cvar_Register(&capturethrottlesize, "AVI capture controls"); - -#if defined(WINAVI) - Cvar_Register(&capturesoundbits, "AVI capture controls"); - Cvar_Register(&capturesoundchannels, "AVI capture controls"); - - S_RegisterSoundInputPlugin(S_LoadMP3Sound); -#endif - -#ifdef WINAMP - Cvar_Register(&media_hijackwinamp, "Media player things"); -#endif - Cvar_Register(&media_shuffle, "Media player things"); - Cvar_Register(&media_repeat, "Media player things"); - Cmd_AddCommand ("media_add", M_Media_Add_f); - Cmd_AddCommand ("media_remove", M_Media_Remove_f); -#if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS) - Cmd_AddCommand ("menu_media", M_Menu_Media_f); -#endif -} -#ifdef WINAVI + + +#ifdef AVAIL_MP3_ACM typedef struct { HACMSTREAM acm; @@ -4897,25 +4892,87 @@ qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed) +void Media_Init(void) +{ +#ifdef HAVE_JUKEBOX + int i; + Cmd_AddCommand("music_fforward", Media_FForward_f); + Cmd_AddCommand("music_rewind", Media_Rewind_f); + Cmd_AddCommand("music_next", Media_Next_f); + Cmd_AddCommand("media_next", Media_Next_f); -#else -void M_Media_Draw (void){} -void M_Media_Key (int key) {} -qboolean Media_ShowFilm(void){return false;} + Cvar_Register(&music_playlist_index, "compat"); + for (i = 0; i < 6; i++) + { + Cvar_Get(va("music_playlist_list%i", i), "", 0, "compat"); + Cvar_Get(va("music_playlist_sampleposition%i", i), "-1", 0, "compat"); + } + music_playlist_last = -1; + media_playlisttypes = MEDIA_PLAYLIST | MEDIA_GAMEMUSIC | MEDIA_CVARLIST; -double Media_TweekCaptureFrameTime(double oldtime, double time) { return oldtime+time ; } -void Media_RecordFrame (void) {} -void Media_CaptureDemoEnd(void) {} -void Media_RecordDemo_f(void) {} -//void Media_RecordAudioFrame (short *sample_buffer, int samples) {} -void Media_StopRecordFilm_f (void) {} -void Media_RecordFilm_f (void){} -void M_Menu_Media_f (void) {} -float Media_CrossFade(int ch, float vol, float time) {return vol;} - -char *Media_NextTrack(int musicchannelnum, float *time) {return NULL;} -qboolean Media_PausedDemo(qboolean fortiming) {return false;} - -int filmtexture; + #ifdef WINAMP + Cvar_Register(&media_hijackwinamp, "Media player things"); + #endif + Cvar_Register(&media_shuffle, "Media player things"); + Cvar_Register(&media_repeat, "Media player things"); + Cmd_AddCommand ("media_add", M_Media_Add_f); + Cmd_AddCommand ("media_remove", M_Media_Remove_f); + #if !defined(NOMEDIAMENU) && !defined(NOBUILTINMENUS) + Cmd_AddCommand ("menu_media", M_Menu_Media_f); + #endif #endif +#ifdef HAVE_SPEECHTOTEXT + Cmd_AddCommand("tts", TTS_Say_f); + Cmd_AddCommand("stt", STT_Init_f); + Cvar_Register(&tts_mode, "Gimmicks"); +#endif +#ifdef AVAIL_MP3_ACM + S_RegisterSoundInputPlugin(S_LoadMP3Sound); +#endif + + +#ifdef HAVE_CDPLAYER + Cmd_AddCommand("cd", CD_f); + cdenabled = false; + if (COM_CheckParm("-nocdaudio")) + cdenabled = false; + if (COM_CheckParm("-cdaudio")) + cdenabled = true; +#endif + +#ifdef HAVE_MEDIA_ENCODER + #if defined(HAVE_API_VFW) + Media_RegisterEncoder(NULL, &capture_avi); + #endif + #ifdef _DEBUG + Media_RegisterEncoder(NULL, &capture_null); + #endif + Media_RegisterEncoder(NULL, &capture_raw); + + Cmd_AddCommand("capture", Media_RecordFilm_f); + Cmd_AddCommand("capturedemo", Media_RecordDemo_f); + Cmd_AddCommand("capturestop", Media_StopRecordFilm_f); + Cmd_AddCommand("capturepause", Media_CapturePause_f); + + Cvar_Register(&capturemessage, "Video Capture Controls"); + Cvar_Register(&capturesound, "Video Capture Controls"); + Cvar_Register(&capturerate, "Video Capture Controls"); + Cvar_Register(&capturewidth, "Video Capture Controls"); + Cvar_Register(&captureheight, "Video Capture Controls"); + Cvar_Register(&capturedriver, "Video Capture Controls"); + Cvar_Register(&capturecodec, "Video Capture Controls"); + Cvar_Register(&capturethrottlesize, "Video Capture Controls"); + Cvar_Register(&capturesoundbits, "Video Capture Controls"); + Cvar_Register(&capturesoundchannels, "Video Capture Controls"); +#endif + +#ifdef HAVE_MEDIA_DECODER + Cmd_AddCommand("playclip", Media_PlayVideoWindowed_f); + Cmd_AddCommand("playvideo", Media_PlayFilm_f); + Cmd_AddCommand("playfilm", Media_PlayFilm_f); + Cmd_AddCommand("cinematic", Media_PlayFilm_f); +#endif + + Cmd_AddCommand("music", Media_NamedTrack_f); +} diff --git a/engine/client/m_single.c b/engine/client/m_single.c index 4d3037fd9..2e4bde95f 100644 --- a/engine/client/m_single.c +++ b/engine/client/m_single.c @@ -1038,6 +1038,7 @@ void M_Menu_Demos_f (void) M_Demo_Reselect(info, info->fs->selname); } +#ifdef HAVE_JUKEBOX void M_Menu_MediaFiles_f (void) { demomenu_t *info; @@ -1054,10 +1055,11 @@ void M_Menu_MediaFiles_f (void) info->fs = &mediareenterloc; info->numext = 0; +#ifdef HAVE_JUKEBOX info->ext[info->numext] = ".m3u"; info->command[info->numext] = "mediaplaylist"; info->numext++; -#if defined(_WIN32) || defined(FTE_TARGET_WEB) +#if defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB) info->ext[info->numext] = ".mp3"; info->command[info->numext] = "media_add"; info->numext++; @@ -1070,7 +1072,9 @@ void M_Menu_MediaFiles_f (void) info->command[info->numext] = "media_add"; info->numext++; #endif +#endif +#ifdef HAVE_MEDIA_DECODER info->ext[info->numext] = ".roq"; info->command[info->numext] = "playfilm"; info->numext++; @@ -1078,6 +1082,7 @@ void M_Menu_MediaFiles_f (void) info->ext[info->numext] = ".avi"; info->command[info->numext] = "playfilm"; info->numext++; +#endif #endif MC_AddWhiteText(menu, 24, 170, 8, "Media List", false); @@ -1093,3 +1098,4 @@ void M_Menu_MediaFiles_f (void) M_Demo_Reselect(info, info->fs->selname); } #endif +#endif diff --git a/engine/client/menu.c b/engine/client/menu.c index 15b5eadbe..a48196023 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -1300,7 +1300,9 @@ void M_Init (void) #endif //demo menu is allowed to see outside of the quakedir. you can't replicate that in qc's sandbox. Cmd_AddCommand ("menu_demo", M_Menu_Demos_f); +#ifdef HAVE_JUKEBOX Cmd_AddCommand ("menu_mediafiles", M_Menu_MediaFiles_f); +#endif diff --git a/engine/client/pr_clcmd.c b/engine/client/pr_clcmd.c index a30c935eb..cf057bf9d 100644 --- a/engine/client/pr_clcmd.c +++ b/engine/client/pr_clcmd.c @@ -439,7 +439,7 @@ void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER // #487 float(string name, string video="http:") gecko_create void QCBUILTIN PF_cs_media_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index e913b9c5d..5149f4d35 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -6077,7 +6077,7 @@ static struct { //DP_QC_GETSURFACEPOINTATTRIBUTE {"getsurfacepointattribute",PF_getsurfacepointattribute, 486}, // #486vector(entity e, float s, float n, float a) getsurfacepointattribute -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER //DP_GECKO_SUPPORT {"gecko_create", PF_cs_media_create, 487}, // #487 float(string name) {"gecko_destroy", PF_cs_media_destroy, 488}, // #488 void(string name) diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 1f4850786..cefb505c9 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -2202,7 +2202,7 @@ static struct { {"drawsetcliparea", PF_CL_drawsetcliparea, 458}, {"drawresetcliparea", PF_CL_drawresetcliparea, 459}, {"drawgetimagesize", PF_CL_drawgetimagesize, 460}, -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER {"cin_open", PF_cs_media_create, 461}, {"cin_close", PF_cs_media_destroy, 462}, {"cin_setstate", PF_cs_media_setstate, 463}, @@ -2233,7 +2233,7 @@ static struct { {"strreplace", PF_strreplace, 484}, {"strireplace", PF_strireplace, 485}, //486 -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER {"gecko_create", PF_cs_media_create, 487}, {"gecko_destroy", PF_cs_media_destroy, 488}, {"gecko_navigate", PF_cs_media_command, 489}, diff --git a/engine/client/roq_read.c b/engine/client/roq_read.c index 481d18a40..9eb897729 100644 --- a/engine/client/roq_read.c +++ b/engine/client/roq_read.c @@ -22,7 +22,7 @@ #include "quakedef.h" -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER static int VFS_GETC(vfsfile_t *fp) diff --git a/engine/client/view.c b/engine/client/view.c index fc1ca0d78..ad01f28d3 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1497,7 +1497,11 @@ void V_CalcRefdef (playerview_t *pv) // set up the refresh position if (v_gunkick.value) - r_refdef.viewangles[PITCH] += pv->punchangle*v_gunkick.value; + { + r_refdef.viewangles[PITCH] += pv->punchangle_cl*v_gunkick.value; + VectorMA(r_refdef.viewangles, v_gunkick.value, pv->punchangle_sv, r_refdef.viewangles); + VectorMA(r_refdef.vieworg, v_gunkick.value, pv->punchorigin, r_refdef.vieworg); + } if (chase_active.ival && cls.allow_cheats) //cheat restriction might be lifted some time when any wallhacks are solved. @@ -1551,17 +1555,17 @@ DropPunchAngle */ void DropPunchAngle (playerview_t *pv) { - if (pv->punchangle < 0) + if (pv->punchangle_cl < 0) { - pv->punchangle += 10*host_frametime; - if (pv->punchangle > 0) - pv->punchangle = 0; + pv->punchangle_cl += 10*host_frametime; + if (pv->punchangle_cl > 0) + pv->punchangle_cl = 0; } else { - pv->punchangle -= 10*host_frametime; - if (pv->punchangle < 0) - pv->punchangle = 0; + pv->punchangle_cl -= 10*host_frametime; + if (pv->punchangle_cl < 0) + pv->punchangle_cl = 0; } } diff --git a/engine/client/wastes.ico b/engine/client/wastes.ico new file mode 100644 index 000000000..deb28b14a Binary files /dev/null and b/engine/client/wastes.ico differ diff --git a/engine/client/winquake.h b/engine/client/winquake.h index efaced7a9..3f70b2816 100644 --- a/engine/client/winquake.h +++ b/engine/client/winquake.h @@ -69,9 +69,11 @@ extern unsigned int sys_parentheight; #ifndef SERVERONLY +#ifdef HAVE_CDPLAYER #ifdef _WIN32 LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); #endif +#endif //shell32 stuff that doesn't exist in win95 diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 879527067..9ebc77cc6 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -162,11 +162,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PACKAGE_Q1PAK #define PACKAGE_PK3 #define AVAIL_GZDEC - #define PACKAGE_WAD //quake's image wad support + #define PACKAGE_TEXWAD //quake's image wad support #ifdef GLQUAKE #define HEADLESSQUAKE #endif + #define AVAIL_MP3_ACM //microsoft's Audio Compression Manager api #ifdef NOLEGACY //these are only the features that really make sense in a more modern engine @@ -201,7 +202,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef AVAIL_PNGLIB //no png support #undef AVAIL_OPENAL //just bloat... #undef AVAIL_GZDEC - #define NOMEDIA //NO playing of avis/cins/roqs #define Q1BSPS #define SPRMODELS //quake1 sprite models @@ -299,6 +299,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PSET_CLASSIC //#define PSET_DARKPLACES + + #define HAVE_CDPLAYER //includes cd playback. actual cds. faketracks are supported regardless. + #define HAVE_JUKEBOX //includes built-in jukebox crap + #define HAVE_MEDIA_DECODER //can play cin/roq, more with plugins + #define HAVE_MEDIA_ENCODER //capture/capturedemo work. + #define HAVE_SPEECHTOTEXT //windows speech-to-text thing + #define VOICECHAT #if defined(_WIN32) && !defined(FTE_SDL) && !defined(MULTITHREAD) //always thread on win32 non-minimal builds @@ -370,6 +377,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef AVAIL_GZDEC #endif +#if !defined(_WIN32) || defined(WINRT) + #undef HAVE_SPEECHTOTEXT + #undef AVAIL_MP3_ACM +#endif + +#ifdef NOMEDIA + #undef HAVE_CDPLAYER //includes cd playback. actual cds. faketracks are supported regardless. + #undef HAVE_JUKEBOX //includes built-in jukebox crap + #undef HAVE_MEDIA_DECODER //can play cin/roq, more with plugins + #undef HAVE_MEDIA_ENCODER //capture/capturedemo work. + #undef AVAIL_MP3_ACM //microsoft's Audio Compression Manager api + #undef HAVE_SPEECHTOTEXT //windows speech-to-text thing +#endif + #ifdef FTE_TARGET_WEB //try to trim the fat #undef VOICECHAT //too lazy to compile speex @@ -814,11 +835,21 @@ STAT_ITEMS = 15, STAT_VIEWHEIGHT = 16, //same as zquake STAT_TIME = 17, //zquake STAT_MATCHSTARTTIME = 18, -STAT_IDEALPITCH = 19, +//STAT_UNUSED = 19, #ifdef SIDEVIEWS STAT_VIEW2 = 20, #endif STAT_VIEWZOOM = 21, // DP +//STAT_UNUSED = 22, +//STAT_UNUSED = 23, +//STAT_UNUSED = 24, +STAT_IDEALPITCH = 25, //nq-emu +STAT_PUNCHANGLE_X = 26, //nq-emu +STAT_PUNCHANGLE_Y = 27, //nq-emu +STAT_PUNCHANGLE_Z = 28, //nq-emu +STAT_PUNCHVECTOR_X = 29, +STAT_PUNCHVECTOR_Y = 30, +STAT_PUNCHVECTOR_Z = 31, //these stats are used only when running a hexen2 mod/hud, and will never be used for a quake mod/hud/generic code. STAT_H2_LEVEL = 32, // changes stat bar @@ -883,7 +914,7 @@ STAT_MOVEVARS_AIRCONTROL_PENALTY = 221, // DP STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222, // DP STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223, // DP STAT_MOVEVARS_AIRCONTROL_POWER = 224, // DP -STAT_MOVEFLAGS = 225, // DP +STAT_MOVEFLAGS = 225, // DP STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL = 226, // DP STAT_MOVEVARS_WARSOWBUNNY_ACCEL = 227, // DP STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED = 228, // DP diff --git a/engine/common/common.c b/engine/common/common.c index 17fbf77a5..05ad85576 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4813,7 +4813,7 @@ void COM_Version_f (void) #else Con_Printf(" Ogg Vorbis(dynamic)"); #endif -#if defined(_WIN32) && !defined(WINRT) && !defined(NOMEDIA) +#if defined(AVAIL_MP3_ACM) Con_Printf(" mp3(system)"); #endif Con_Printf("\n"); diff --git a/engine/common/config_wastes.h b/engine/common/config_wastes.h index 570bbd066..c9ecb8796 100644 --- a/engine/common/config_wastes.h +++ b/engine/common/config_wastes.h @@ -51,6 +51,12 @@ #endif +//various package formats +#define PACKAGE_PK3 +#undef PACKAGE_Q1PAK //also q2 +#undef PACKAGE_DOOMWAD //doom wad support (generates various file names, and adds support for doom's audio, sprites, etc) +#undef PACKAGE_TEXWAD //quake's image wad support + //map formats #define Q3BSPS #undef Q1BSPS @@ -81,6 +87,7 @@ #undef AVAIL_GZDEC //.gz decompression #undef AVAIL_PNGLIB //.png image format support (read+screenshots) #undef AVAIL_JPEGLIB //.jpeg image format support (read+screenshots) +#undef AVAIL_MP3_ACM //.mp3 support (in windows). #undef IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load. #undef IMAGEFMT_BLP //legacy crap #undef NETPREPARSE //allows for running both nq+qw on the same server (if not, protocol used must match gamecode). @@ -108,12 +115,12 @@ #undef PLUGINS //support for external plugins (like huds or fancy menus or whatever) #undef SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections. #undef PSET_CLASSIC //support the 'classic' particle system, for that classic quake feel. +#undef HAVE_CDPLAYER //includes cd playback. actual cds. named/numbered tracks are supported regardless (though you need to use the 'music' command to play them without this). +#undef HAVE_JUKEBOX //includes built-in jukebox crap +#undef HAVE_MEDIA_DECODER //can play cin/roq, more with plugins +#undef HAVE_MEDIA_ENCODER //capture/capturedemo work. +#undef HAVE_SPEECHTOTEXT //windows speech-to-text thing -//various package formats -#define PACKAGE_PK3 -#undef PACKAGE_Q1PAK //also q2 -#undef PACKAGE_DOOMWAD //doom wad support (generates various file names, and adds support for doom's audio, sprites, etc) -#undef PACKAGE_WAD //quake's image wad support diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 98e1ff982..9f320c70e 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -544,18 +544,22 @@ static qintptr_t VARGS Plug_ExportNative(void *offset, quintptr_t mask, const qi currentplug->blockcloses++; } */ -#if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY) +#if defined(PLUGINS) && !defined(SERVERONLY) +#ifdef HAVE_MEDIA_DECODER else if (!strcmp(name, "Media_VideoDecoder")) { Media_RegisterDecoder(currentplug, func); // currentplug->blockcloses++; } +#endif +#ifdef HAVE_MEDIA_ENCODER else if (!strcmp(name, "Media_VideoEncoder")) { Media_RegisterEncoder(currentplug, func); // currentplug->blockcloses++; } #endif +#endif #ifndef SERVERONLY else if (!strcmp(name, "S_LoadSound")) //a hook for loading extra types of sound (wav, mp3, ogg, midi, whatever you choose to support) @@ -1991,9 +1995,13 @@ void Plug_Close(plugin_t *plug) Con_DPrintf("Closing plugin %s\n", plug->name); //ensure any active contexts provided by the plugin are closed (stuff with destroy callbacks) -#if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY) +#if defined(PLUGINS) && !defined(SERVERONLY) +#ifdef HAVE_MEDIA_DECODER Media_UnregisterDecoder(plug, NULL); +#endif +#ifdef HAVE_MEDIA_ENCODER Media_UnregisterEncoder(plug, NULL); +#endif #endif FS_UnRegisterFileSystemModule(plug); Mod_UnRegisterAllModelFormats(plug); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 20062c0ce..b2a3d6f8d 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -6228,7 +6228,7 @@ lh_extension_t QSG_Extensions[] = { // {"FTE_GFX_MODELEVENTS", 1, NULL, {"processmodelevents", "getnextmodelevent", "getmodeleventidx"}, "Provides a query for per-animation events in model files, including from progs/foo.mdl.events files."}, {"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}, "Allows you to check if a client has too many reliable messages pending."}, {"FTE_MEMALLOC", 4, NULL, {"memalloc", "memfree", "memcpy", "memfill8"}, "Allows dynamically allocating memory. Use pointers to access this memory. Memory will not be saved into saved games."}, -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER #if defined(_WIN32) && !defined(WINRT) {"FTE_MEDIA_AVI", 0, NULL, {NULL}, "playfilm command supports avi files."}, #endif @@ -6271,7 +6271,9 @@ lh_extension_t QSG_Extensions[] = { #ifdef QCGC {"FTE_QC_PERSISTENTTEMPSTRINGS", NOBI "Supersedes DP_QC_MULTIPLETEMPSTRINGS. Temp strings are garbage collected automatically, and do not expire while they're still in use. This makes strzone redundant."}, #endif +#ifdef RAGDOLL {"FTE_QC_RAGDOLL_WIP", 1, NULL, {"ragupdate", "skel_set_bone_world", "skel_mmap"}}, +#endif {"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}, "Allows the use of out-of-band udp packets to/from other hosts. Includes the SV_ParseConnectionlessPacket event."}, {"FTE_QC_STUFFCMDFLAGS", 1, NULL, {"stuffcmdflags"}, "Variation on regular stuffcmd that gives control over how spectators/mvds should be treated."}, {"FTE_QC_TRACETRIGGER"}, diff --git a/engine/common/protocol.h b/engine/common/protocol.h index f5f97c2aa..4761cd6b3 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -1124,6 +1124,8 @@ typedef struct entity_state_t *entities; int fixangles[MAX_SPLITS]; //these should not be in here vec3_t fixedangles[MAX_SPLITS]; + vec3_t punchangle[MAX_SPLITS]; + vec3_t punchorigin[MAX_SPLITS]; qbyte *bonedata; size_t bonedatacur; diff --git a/engine/d3d/d3d11_backend.c b/engine/d3d/d3d11_backend.c index db4aa3e87..3196e40fc 100644 --- a/engine/d3d/d3d11_backend.c +++ b/engine/d3d/d3d11_backend.c @@ -1090,7 +1090,7 @@ static void SelectPassTexture(unsigned int tu, const shaderpass_t *pass) BindTexture(tu, T_Gen_CurrentRender()); break; case T_GEN_VIDEOMAP: -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (pass->cin) { BindTexture(tu, Media_UpdateForShader(pass->cin)); @@ -3472,7 +3472,7 @@ void D3D11BE_BaseEntTextures(void) { batch_t *batches[SHADER_SORT_COUNT]; BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode); - D3D11BE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + D3D11BE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); BE_SelectEntity(&r_worldentity); } @@ -3617,7 +3617,7 @@ void D3D11BE_DrawWorld (batch_t **worldbatches) BE_SelectMode(BEM_STANDARD); RSpeedRemark(); - D3D11BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + D3D11BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); RSpeedEnd(RSPEED_WORLD); #ifdef RTLIGHTS @@ -3627,7 +3627,7 @@ void D3D11BE_DrawWorld (batch_t **worldbatches) RSpeedEnd(RSPEED_STENCILSHADOWS); #endif - D3D11BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_DECAL, SHADER_SORT_COUNT); + D3D11BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_SEETHROUGH+1, SHADER_SORT_COUNT); } else { diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index 7c92d916e..9ea459685 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -776,10 +776,10 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass) FIXME: no code to grab the current screen and convert to a texture break;*/ case T_GEN_VIDEOMAP: -#ifdef NOMEDIA - BindTexture(tu, missing_texture); -#else +#ifdef HAVE_MEDIA_DECODER BindTexture(tu, Media_UpdateForShader(pass->cin)); +#else + BindTexture(tu, missing_texture); #endif break; } @@ -3457,7 +3457,7 @@ void D3D9BE_BaseEntTextures(void) { batch_t *batches[SHADER_SORT_COUNT]; BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode); - D3D9BE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + D3D9BE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); BE_SelectEntity(&r_worldentity); } @@ -3543,7 +3543,7 @@ void D3D9BE_DrawWorld (batch_t **worldbatches) BE_SelectMode(BEM_STANDARD); RSpeedRemark(); - D3D9BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + D3D9BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); RSpeedEnd(RSPEED_WORLD); #ifdef RTLIGHTS @@ -3558,7 +3558,7 @@ void D3D9BE_DrawWorld (batch_t **worldbatches) BE_SelectMode(BEM_STANDARD); - D3D9BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_DECAL, SHADER_SORT_COUNT); + D3D9BE_SubmitMeshes(worldbatches, batches, SHADER_SORT_SEETHROUGH+1, SHADER_SORT_COUNT); } else { diff --git a/engine/d3d/d3d_shader.c b/engine/d3d/d3d_shader.c index 4111dce6b..fcab1d810 100644 --- a/engine/d3d/d3d_shader.c +++ b/engine/d3d/d3d_shader.c @@ -434,6 +434,8 @@ void D3D9Shader_DeleteProg(program_t *prog) prog->permu[permu].h.hlsl.ctabf = NULL; IUnknown_Release(fct); } + prog->permu[permu].numparms = 0; + BZ_Free(prog->permu[permu].parm); } } diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index ab7274551..8d61afa75 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -9,8 +9,8 @@ #include "winquake.h" #if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) - #define HMONITOR_DECLARED - DECLARE_HANDLE(HMONITOR); + #define HMONITOR_DECLARED + DECLARE_HANDLE(HMONITOR); #endif #include @@ -378,7 +378,7 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mmi->ptMinTrackSize.y = 200 + ((windowrect.bottom - windowrect.top) - (clientrect.bottom - clientrect.top)); } return 0; - case WM_SIZE: + case WM_SIZE: d3d_resized = true; break; @@ -390,7 +390,7 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA Cbuf_AddText("\nquit\n", RESTRICT_LOCAL); } - break; + break; case WM_ACTIVATE: fActive = LOWORD(wParam); @@ -405,25 +405,27 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; - case WM_DESTROY: - { + case WM_DESTROY: + { // if (dibwindow) // DestroyWindow (dibwindow); - } - break; + } + break; +#ifdef HAVE_CDPLAYER case MM_MCINOTIFY: - lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); break; +#endif - default: - /* pass all unhandled messages to DefWindowProc */ - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - break; - } + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } - /* return 1 if handled message, 0 if not */ - return lRet; + /* return 1 if handled message, 0 if not */ + return lRet; } static void D3D9_VID_SwapBuffers(void) @@ -463,10 +465,10 @@ static void resetD3D9(void) #if (WINVER < 0x500) && !defined(__GNUC__) typedef struct tagMONITORINFO { - DWORD cbSize; - RECT rcMonitor; - RECT rcWork; - DWORD dwFlags; + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; } MONITORINFO, *LPMONITORINFO; #endif @@ -1052,7 +1054,7 @@ static qboolean (D3D9_SCR_UpdateScreen) (void) if (uimenu != 1) { if (r_worldentity.model && cls.state == ca_active) - V_RenderView (); + V_RenderView (); else { noworld = true; diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index 6b1b155af..7b5080bed 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -55,8 +55,8 @@ ID3D11DeviceContext *d3ddevctx; #endif #define DEFINE_QGUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID DECLSPEC_SELECTANY name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + const GUID DECLSPEC_SELECTANY name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } DEFINE_QGUID(qIID_ID3D11Texture2D,0x6f15aaf2,0xd208,0x4e89,0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c); @@ -520,7 +520,7 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR mmi->ptMinTrackSize.y = 200 + ((windowrect.bottom - windowrect.top) - (clientrect.bottom - clientrect.top)); } return 0; - case WM_SIZE: + case WM_SIZE: d3d_resized = true; D3DVID_UpdateWindowStatus(mainwindow); @@ -571,37 +571,38 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR lRet = 1; break; - case WM_DESTROY: - { + case WM_DESTROY: + { // if (dibwindow) // DestroyWindow (dibwindow); - } - break; - + } + break; +#ifdef HAVE_CDPLAYER case MM_MCINOTIFY: - lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); break; +#endif #endif case WM_ERASEBKGND: return 1; - default: - /* pass all unhandled messages to DefWindowProc */ - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - break; - } + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } - /* return 1 if handled message, 0 if not */ - return lRet; + /* return 1 if handled message, 0 if not */ + return lRet; } #endif #if (WINVER < 0x500) && !defined(__GNUC__) typedef struct tagMONITORINFO { - DWORD cbSize; - RECT rcMonitor; - RECT rcWork; - DWORD dwFlags; + DWORD cbSize; + RECT rcMonitor; + RECT rcWork; + DWORD dwFlags; } MONITORINFO, *LPMONITORINFO; #endif @@ -1310,7 +1311,7 @@ static qboolean (D3D11_SCR_UpdateScreen) (void) if (uimenu != 1) { if (r_worldentity.model && cls.state == ca_active) - V_RenderView (); + V_RenderView (); else { noworld = true; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 85746cd75..e377af64d 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1222,10 +1222,10 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass) return; case T_GEN_VIDEOMAP: -#ifdef NOMEDIA - t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex; -#else +#ifdef HAVE_MEDIA_DECODER t = Media_UpdateForShader(pass->cin); +#else + t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex; #endif break; @@ -1336,7 +1336,7 @@ void Shader_LightPass(const char *shortname, shader_t *s, const void *args) { char shadertext[8192*2]; extern cvar_t r_drawflat; - sprintf(shadertext, LIGHTPASS_SHADER, (r_lightmap.ival||r_drawflat.ival)?"#FLAT":""); + sprintf(shadertext, LIGHTPASS_SHADER, (r_lightmap.ival||r_drawflat.ival)?"#FLAT=1.0":""); Shader_DefaultScript(shortname, s, shadertext); } @@ -5568,7 +5568,7 @@ void GLBE_DrawWorld (batch_t **worldbatches) BE_SelectMode(BEM_STANDARD); RSpeedRemark(); - GLBE_SubmitMeshes(worldbatches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + GLBE_SubmitMeshes(worldbatches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); RSpeedEnd(RSPEED_WORLD); #ifdef RTLIGHTS @@ -5586,7 +5586,7 @@ void GLBE_DrawWorld (batch_t **worldbatches) shaderstate.identitylighting = 1; - GLBE_SubmitMeshes(worldbatches, SHADER_SORT_DECAL, SHADER_SORT_NEAREST); + GLBE_SubmitMeshes(worldbatches, SHADER_SORT_SEETHROUGH+1, SHADER_SORT_NEAREST); /* if (r_refdef.gfog_alpha) { diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 191bb7ae3..577b8eb7d 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -2783,7 +2783,7 @@ static void Shaderpass_VideoMap (shader_t *shader, shaderpass_t *pass, char **pt { char *token = Shader_ParseSensString (ptr); -#ifdef NOMEDIA +#ifndef HAVE_MEDIA_DECODER (void)token; #else if (pass->cin) @@ -3430,7 +3430,7 @@ static shaderkey_t shaderpasskeys[] = void Shader_FreePass (shaderpass_t *pass) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if ( pass->flags & SHADER_PASS_VIDEOMAP ) { Media_ShutdownCin(pass->cin); @@ -3867,14 +3867,14 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass) //mode deluxemaps //17,18,19 }; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER cin_t *cin = R_ShaderGetCinematic(shader); #endif //if the glsl doesn't specify all samplers, just trim them. pass->numMergedPasses = pass->prog->numsamplers; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (cin && R_ShaderGetCinematic(shader) == cin) cin = NULL; #endif @@ -3892,7 +3892,7 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass) pass[pass->numMergedPasses].flags &= ~SHADER_PASS_DEPTHCMP; if (defaulttgen[i].gen == T_GEN_SHADOWMAP) pass[pass->numMergedPasses].flags |= SHADER_PASS_DEPTHCMP; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (!i && cin) { pass[pass->numMergedPasses].texgen = T_GEN_VIDEOMAP; @@ -3903,7 +3903,7 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass) #endif { pass[pass->numMergedPasses].texgen = defaulttgen[i].gen; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER pass[pass->numMergedPasses].cin = NULL; #endif } @@ -3915,7 +3915,7 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass) //must have at least one texture. if (!pass->numMergedPasses) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER pass[0].texgen = cin?T_GEN_VIDEOMAP:T_GEN_DIFFUSE; pass[0].cin = cin; #else @@ -3923,7 +3923,7 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass) #endif pass->numMergedPasses = 1; } -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER else if (cin) Media_ShutdownCin(cin); #endif @@ -4624,7 +4624,7 @@ done:; if (best->anim_frames[0] && *best->anim_frames[0]->ident != '$') s->defaulttextures->base = best->anim_frames[0]; } -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER else if (pass->texgen == T_GEN_VIDEOMAP && pass->cin) s->defaulttextures->base = Media_UpdateForShader(best->cin); #endif @@ -4830,14 +4830,14 @@ done:; //mode deluxemaps //17,18,19 }; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER cin_t *cin = R_ShaderGetCinematic(s); #endif //if the glsl doesn't specify all samplers, just trim them. s->numpasses = s->prog->numsamplers; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (cin && R_ShaderGetCinematic(s) == cin) cin = NULL; #endif @@ -4852,7 +4852,7 @@ done:; s->passes[s->numpasses].flags &= ~SHADER_PASS_DEPTHCMP; if (defaulttgen[i].gen == T_GEN_SHADOWMAP) s->passes[s->numpasses].flags |= SHADER_PASS_DEPTHCMP; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (!i && cin) { s->passes[s->numpasses].texgen = T_GEN_VIDEOMAP; @@ -4863,7 +4863,7 @@ done:; #endif { s->passes[s->numpasses].texgen = defaulttgen[i].gen; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER s->passes[s->numpasses].cin = NULL; #endif } @@ -4875,7 +4875,7 @@ done:; //must have at least one texture. if (!s->numpasses) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER s->passes[0].texgen = cin?T_GEN_VIDEOMAP:T_GEN_DIFFUSE; s->passes[0].cin = cin; #else @@ -4883,7 +4883,7 @@ done:; #endif s->numpasses = 1; } -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER else if (cin) Media_ShutdownCin(cin); #endif @@ -6818,7 +6818,7 @@ void Shader_NeedReload(qboolean rescanfs) cin_t *R_ShaderGetCinematic(shader_t *s) { -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER int j; if (!s) return NULL; @@ -6858,10 +6858,10 @@ shader_t *R_ShaderFind(const char *name) cin_t *R_ShaderFindCinematic(const char *name) { -#ifdef NOMEDIA - return NULL; -#else +#ifdef HAVE_MEDIA_DECODER return R_ShaderGetCinematic(R_ShaderFind(name)); +#else + return NULL; #endif } diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index a22e8e827..233e911ea 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1852,7 +1852,24 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int if (ver != 100) #endif { - Q_snprintfz(verline, sizeof(verline), "#version %u\n", ver); + //known versions: + //100 == gles2 + //110 == gl2.0 + //120 == gl2.1 + //130 == gl3.0 + //140 == gl3.1 + //150 [core|compatibility] == gl3.2 + //330, 400, 410, 420, 430 [core|compatibility] == gl?.?? + //300 ES == gles3 + if (gl_config_gles && ver != 100) + Q_snprintfz(verline, sizeof(verline), "#version %u ES\n", ver); + else if (!gl_config_gles && ver >= 150 && !gl_config_nofixedfunc) + //favour compatibility profile, simply because we want ftransform to work properly + //note that versions 130+140 are awkward due to deprecation stuff, both assume compatibility profiles where supported. + // however, 130 REMOVED ftransform in revision 2 and then re-added it as deprecated in revision 4 (of 10). + Q_snprintfz(verline, sizeof(verline), "#version %u compatibility\n", ver); + else + Q_snprintfz(verline, sizeof(verline), "#version %u\n", ver); //core assumed, where defined prstrings[strings] = verline; length[strings] = strlen(prstrings[strings]); strings++; @@ -1891,13 +1908,14 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int if (ver >= 130) { prstrings[strings] = - //gl3+ deprecated the varying keyword for geometry shaders to work properly + //gl3+ deprecated the some things. these are removed in forwards-compatible / core contexts. + //varying became either in or out, which is important if you have geometry shaders... "#define varying in\n" - //it also deprecated the numerous texture functions. now only the 'texture' function exists, with overloads for each sampler type. + //now only the 'texture' function exists, with overloads for each sampler type. "#define texture2D texture\n" "#define textureCube texture\n" "#define shadow2D texture\n" - //gl_FragColor and gl_FragData got deprecated too + //gl_FragColor and gl_FragData got deprecated too, need to make manual outputs "out vec4 fte_fragdata;\n" "#define gl_FragColor fte_fragdata\n" ; @@ -2018,7 +2036,7 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int length[strings] = strlen(prstrings[strings]); strings++; } - if (gl_config_nofixedfunc || ver >= 130) + if (gl_config_nofixedfunc) { prstrings[strings] = "attribute vec3 v_position1;\n" diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index d8efa76fe..8ecba8adc 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -2520,6 +2520,12 @@ void MainThreadWndProc(void *ctx, void *data, size_t msg, size_t ex) break; ClearAllStates (); //FIXME: thread break; + +#ifdef HAVE_CDPLAYER + case MM_MCINOTIFY: + CDAudio_MessageHandler (mainwindow, uMsg, ctx, data); + break; +#endif } } #endif @@ -2707,7 +2713,7 @@ static LONG WINAPI GLMainWndProc ( PostQuitMessage(0); break; case WM_USER: -#ifndef NOMEDIA +#ifdef HAVE_SPEECHTOTEXT STT_Event(); #endif break; @@ -2809,9 +2815,14 @@ static LONG WINAPI GLMainWndProc ( } break; -#ifndef WTHREAD +#ifdef HAVE_CDPLAYER case MM_MCINOTIFY: +#ifdef WTHREAD + COM_AddWork(WG_MAIN, MainThreadWndProc, wParam, lParam, uMsg, 0); + lRet = 0; +#else lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); //FIXME: thread +#endif break; #endif diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 123d25508..4a312d681 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -9965,7 +9965,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "#define tcbase tcoffsetmap\n" "#endif\n" "#if defined(FLAT)\n" -"vec3 bases = vec3(1.0);\n" +"vec3 bases = vec3(FLAT);\n" "#else\n" "vec3 bases = vec3(texture2D(s_diffuse, tcbase));\n" "#endif\n" @@ -11084,7 +11084,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "{\n" "float3 col = l_lightcolour;\n" "col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\n" +"#ifdef FLAT\n" +"float3 diff = FLAT;\n" +"#else\n" "float3 diff = tex2D(s_diffuse, inp.tc);\n" +"#endif\n" "return float4(diff * col, 1);\n" "}\n" "#endif\n" diff --git a/engine/gl/shader.h b/engine/gl/shader.h index a2883f167..0d2841bf1 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -174,7 +174,7 @@ typedef struct shaderpass_s { struct programshared_s *prog; -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER struct cin_s *cin; #endif diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 7bc66135e..e27598295 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -726,7 +726,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int if (oneclient) { if (oneclient != split) - continue; + { + if (split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track]) + ; + else + continue; + } } else if (mask) { @@ -795,7 +800,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int break; #endif case SCP_QUAKEWORLD: - if (reliable) + if (reliable) { ClientReliableCheckBlock(client, sv.multicast.cursize); ClientReliableWrite_SZ(client, sv.multicast.data, sv.multicast.cursize); @@ -893,7 +898,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int if (oneclient) { if (oneclient != split) - continue; + { + if (split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track]) + ; + else + continue; + } } else if (svprogfuncs) { @@ -1110,7 +1120,12 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, int dimension_mask, void (*ca if (oneclient) { if (oneclient != split) - continue; + { + if (split->spectator && split->spec_track >= 0 && oneclient == &svs.clients[split->spec_track]) + ; + else + continue; + } } else if (svprogfuncs) { @@ -1670,7 +1685,7 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) ent = client->edict; if (progstype != PROG_QW) { - if (ISQWCLIENT(client)) + if (ISQWCLIENT(client) && !(client->fteprotocolextensions2 & PEXT2_PREDINFO)) { //quakeworld clients drop the punch angle themselves. while (ent->xv->punchangle[0] < -3) @@ -1686,25 +1701,6 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) ent->xv->punchangle[1] = 0; ent->xv->punchangle[2] = 0; } - else - { - for (i = 0; i < 3; i++) - { - //nq clients require the server to do it (interpolating, if its a decent client). - if (ent->xv->punchangle[i] < 0) - { - ent->xv->punchangle[i] += 10 * (1/77.0); - if (ent->xv->punchangle[i] > 0) - ent->xv->punchangle[i] = 0; - } - if (ent->xv->punchangle[i] < 0) - { - ent->xv->punchangle[i] -= 10 * (1/77.0); - if (ent->xv->punchangle[i] < 0) - ent->xv->punchangle[i] = 0; - } - } - } } if (ISQWCLIENT(client)) @@ -1738,8 +1734,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) if (ent->v->view_ofs[2] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT; -// if (ent->v->idealpitch) -// bits |= SU_IDEALPITCH; + if (ent->xv->idealpitch) + bits |= SU_IDEALPITCH; // stuff the sigil bits into the high bits of items for sbar, or else // mix in items2 @@ -1764,6 +1760,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) { if (ent->xv->punchangle[i]) bits |= (SU_PUNCH1<protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7) && ent->xv->punchvector[i]) +// bits |= (DPSU_PUNCHVEC1<v->velocity[i]) bits |= (SU_VELOCITY1<v->view_ofs[2]); -// if (bits & SU_IDEALPITCH) -// MSG_WriteChar (msg, ent->v->idealpitch); + if (bits & SU_IDEALPITCH) + MSG_WriteChar (msg, ent->xv->idealpitch); for (i=0 ; i<3 ; i++) { @@ -1838,6 +1836,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) else MSG_WriteChar (msg, ent->xv->punchangle[i]); } +// if ((client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7) && (bits & (DPSU_PUNCHVEC1<xv->punchvector); if (bits & (SU_VELOCITY1<protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7) @@ -2120,6 +2120,11 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf statsi[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28); statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2]; + + statsf[STAT_PUNCHANGLE_X] = ent->xv->punchangle[0]; + statsf[STAT_PUNCHANGLE_Y] = ent->xv->punchangle[1]; + statsf[STAT_PUNCHANGLE_Z] = ent->xv->punchangle[2]; + #ifdef PEXT_VIEW2 if (ent->xv->view2) statsi[STAT_VIEW2] = NUM_FOR_EDICT(svprogfuncs, PROG_TO_EDICT(svprogfuncs, ent->xv->view2)); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index ef6a0986b..52f08c29e 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1002,7 +1002,7 @@ void SV_SendClientPrespawnInfo(client_t *client) ClientReliableWrite_Byte (client, track); if (!track && *sv.h2miditrack) - SV_StuffcmdToClient(client, va("cd loop \"%s\"\n", sv.h2miditrack)); + SV_StuffcmdToClient(client, va("music \"%s\"\n", sv.h2miditrack)); } else if (client->prespawn_idx == 2) { @@ -6737,6 +6737,22 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) } + for (i = 0; i < 3; i++) + { + if (sv_player->xv->punchangle[i] < 0) + { + sv_player->xv->punchangle[i] += 10 * host_frametime; + if (sv_player->xv->punchangle[i] > 0) + sv_player->xv->punchangle[i] = 0; + } + if (sv_player->xv->punchangle[i] > 0) + { + sv_player->xv->punchangle[i] -= 10 * host_frametime; + if (sv_player->xv->punchangle[i] < 0) + sv_player->xv->punchangle[i] = 0; + } + } + if (!host_client->spectator) { vec_t oldvz; @@ -8400,6 +8416,7 @@ static void SV_WaterJump (void) void SV_ClientThink (void) { + int i; vec3_t v_angle; cmd = host_client->lastcmd; @@ -8429,6 +8446,21 @@ void SV_ClientThink (void) velocity = sv_player->v->velocity; // DropPunchAngle (); + for (i = 0; i < 3; i++) + { + if (sv_player->xv->punchangle[i] < 0) + { + sv_player->xv->punchangle[i] += 10 * host_frametime; + if (sv_player->xv->punchangle[i] > 0) + sv_player->xv->punchangle[i] = 0; + } + if (sv_player->xv->punchangle[i] > 0) + { + sv_player->xv->punchangle[i] -= 10 * host_frametime; + if (sv_player->xv->punchangle[i] < 0) + sv_player->xv->punchangle[i] = 0; + } + } // // if dead, behave differently diff --git a/engine/shaders/glsl/rtlight.glsl b/engine/shaders/glsl/rtlight.glsl index 830d7948d..39a058aa5 100644 --- a/engine/shaders/glsl/rtlight.glsl +++ b/engine/shaders/glsl/rtlight.glsl @@ -324,7 +324,7 @@ void main () #define tcbase tcoffsetmap #endif #if defined(FLAT) - vec3 bases = vec3(1.0); + vec3 bases = vec3(FLAT); #else vec3 bases = vec3(texture2D(s_diffuse, tcbase)); #endif diff --git a/engine/shaders/hlsl9/rtlight.hlsl b/engine/shaders/hlsl9/rtlight.hlsl index 5f867e2e2..381da4ce0 100644 --- a/engine/shaders/hlsl9/rtlight.hlsl +++ b/engine/shaders/hlsl9/rtlight.hlsl @@ -55,7 +55,11 @@ { float3 col = l_lightcolour; col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0); +#ifdef FLAT + float3 diff = FLAT; +#else float3 diff = tex2D(s_diffuse, inp.tc); +#endif return float4(diff * col, 1); } #endif \ No newline at end of file diff --git a/engine/sw/sw_vidwin.c b/engine/sw/sw_vidwin.c index b34cb72c1..0803ab3f3 100644 --- a/engine/sw/sw_vidwin.c +++ b/engine/sw/sw_vidwin.c @@ -136,7 +136,7 @@ qboolean DIB_Init(void) ** create the DIB section */ hDIBSection = CreateDIBSection( mainhDC, - pbmiDIB, + pbmiDIB, DIB_RGB_COLORS, (void**)&pDIBBase, NULL, @@ -149,17 +149,17 @@ qboolean DIB_Init(void) } if (pbmiDIB->bmiHeader.biHeight < 0) - { + { // bottom up screenbuffer = pDIBBase + ( vid.pixelheight - 1 ) * vid.pixelwidth * 4; screenpitch = -(int)vid.pixelwidth; - } - else - { + } + else + { // top down screenbuffer = pDIBBase; screenpitch = vid.pixelwidth; - } + } /* ** clear the DIB memory buffer @@ -305,10 +305,10 @@ qboolean SWAppActivate(BOOL fActive, BOOL minimize) } LONG WINAPI MainWndProc ( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { LONG lRet = 0; int fActive, fMinimized, temp; @@ -346,8 +346,8 @@ LONG WINAPI MainWndProc ( VID_SetMode ((int)vid_fullscreen_mode.value, vid_curpal); */ break; - case SC_SCREENSAVE: - case SC_MONITORPOWER: + case SC_SCREENSAVE: + case SC_MONITORPOWER: if (w32sw.isfullscreen) { // don't call DefWindowProc() because we don't want to start @@ -574,7 +574,7 @@ LONG WINAPI MainWndProc ( } break; */ - case WM_CLOSE: + case WM_CLOSE: // this causes Close in the right-click task bar menu not to work, but right // now bad things happen if Close is handled in that case (garbage and a // crash on Win95) @@ -588,18 +588,20 @@ LONG WINAPI MainWndProc ( } break; +#ifdef HAVE_CDPLAYER case MM_MCINOTIFY: - lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); break; +#endif default: - /* pass all unhandled messages to DefWindowProc */ - lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); - break; - } + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } - /* return 0 if handled message, 1 if not */ - return lRet; + /* return 0 if handled message, 1 if not */ + return lRet; } @@ -632,18 +634,18 @@ void VID_CreateWindow(int width, int height, qboolean fullscreen) } /* Register the frame class */ - wc.style = 0; - wc.lpfnWndProc = (WNDPROC)MainWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = global_hInstance; - wc.hIcon = 0; - wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = global_hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); wc.hbrBackground = (void *)COLOR_GRAYTEXT; - wc.lpszMenuName = 0; - wc.lpszClassName = WINDOW_CLASS_NAME; + wc.lpszMenuName = 0; + wc.lpszClassName = WINDOW_CLASS_NAME; - RegisterClass(&wc); + RegisterClass(&wc); r.left = 0; r.top = 0; diff --git a/engine/vk/vk_backend.c b/engine/vk/vk_backend.c index 0138124d0..737900d5d 100644 --- a/engine/vk/vk_backend.c +++ b/engine/vk/vk_backend.c @@ -1665,11 +1665,9 @@ static texid_t SelectPassTexture(const shaderpass_t *pass) case T_GEN_CURRENTRENDER: return shaderstate.tex_currentrender; case T_GEN_VIDEOMAP: -#ifndef NOMEDIA +#ifdef HAVE_MEDIA_DECODER if (pass->cin) - { return Media_UpdateForShader(pass->cin); - } #endif return r_nulltex; @@ -5602,7 +5600,7 @@ void VKBE_BaseEntTextures(void) { batch_t *batches[SHADER_SORT_COUNT]; BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode); - VKBE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + VKBE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); VKBE_SelectEntity(&r_worldentity); } @@ -6087,7 +6085,7 @@ void VKBE_DrawWorld (batch_t **worldbatches) VKBE_SelectMode(BEM_STANDARD); - VKBE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL); + VKBE_SubmitMeshes(worldbatches, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1); RSpeedEnd(RSPEED_WORLD); #ifdef RTLIGHTS @@ -6098,7 +6096,7 @@ void VKBE_DrawWorld (batch_t **worldbatches) #endif } - VKBE_SubmitMeshes(worldbatches, batches, SHADER_SORT_DECAL, SHADER_SORT_COUNT); + VKBE_SubmitMeshes(worldbatches, batches, SHADER_SORT_SEETHROUGH+1, SHADER_SORT_COUNT); if (r_wireframe.ival)