log file defaults changed to be more readable. timestamps now included by default. also fixed a bug in the location the log is written.

fixed numerous shadowmapping bugs. actually seems to work now. appears to draw more lights than is actually needed, however.
changed how keyboard focus works. can now have menu+console open at once, although you probably need shift+escape to get at it.
fixed a few issues with nexuiz compat. there are *still* other issues.
greatly refactored cd playback code. cd driver code is now a backend only and does not provide its own commands. track remapping accepts named faketracks. worked around missing notifications in vista+, so looping will now work.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4491 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-10-08 14:28:11 +00:00
parent b965a21c3b
commit d396450a0a
107 changed files with 3704 additions and 2325 deletions

View File

@ -40,22 +40,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <linux/cdrom.h>
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean initialized = false;
static qboolean enabled = true;
static qboolean playLooping = false;
static qbyte remap[100];
static qbyte playTrack;
static qbyte maxTrack;
static int cdfile = -1;
static char cd_dev[64] = "/dev/cdrom";
static void CDAudio_Eject(void)
{
if (cdfile == -1 || !enabled)
if (cdfile == -1)
return; // no cd init'd
if ( ioctl(cdfile, CDROMEJECT) == -1 )
@ -65,7 +55,7 @@ static void CDAudio_Eject(void)
static void CDAudio_CloseDoor(void)
{
if (cdfile == -1 || !enabled)
if (cdfile == -1)
return; // no cd init'd
if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 )
@ -76,7 +66,8 @@ static int CDAudio_GetAudioDiskInfo(void)
{
struct cdrom_tochdr tochdr;
cdValid = false;
if (cdfile == -1)
return -1;
if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 )
{
@ -90,10 +81,7 @@ static int CDAudio_GetAudioDiskInfo(void)
return -1;
}
cdValid = true;
maxTrack = tochdr.cdth_trk1;
return 0;
return tochdr.cdth_trk1;
}
@ -102,23 +90,8 @@ void CDAudio_Play(int track, qboolean looping)
struct cdrom_tocentry entry;
struct cdrom_ti ti;
if (cdfile == -1 || !enabled)
if (cdfile == -1)
return;
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
return;
}
track = remap[track];
if (track < 1 || track > maxTrack)
{
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
return;
}
// don't try to play a non-audio track
entry.cdte_track = track;
@ -134,13 +107,6 @@ void CDAudio_Play(int track, qboolean looping)
return;
}
if (playing)
{
if (playTrack == track)
return;
CDAudio_Stop();
}
ti.cdti_trk0 = track;
ti.cdti_trk1 = track;
ti.cdti_ind0 = 1;
@ -155,10 +121,6 @@ void CDAudio_Play(int track, qboolean looping)
if ( ioctl(cdfile, CDROMRESUME) == -1 )
Con_DPrintf("ioctl cdromresume failed\n");
playLooping = looping;
playTrack = track;
playing = true;
if (!bgmvolume.value)
CDAudio_Pause ();
}
@ -166,181 +128,30 @@ void CDAudio_Play(int track, qboolean looping)
void CDAudio_Stop(void)
{
if (cdfile == -1 || !enabled)
return;
if (!playing)
if (cdfile == -1)
return;
if ( ioctl(cdfile, CDROMSTOP) == -1 )
Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
wasPlaying = false;
playing = false;
}
void CDAudio_Pause(void)
{
if (cdfile == -1 || !enabled)
return;
if (!playing)
if (cdfile == -1)
return;
if ( ioctl(cdfile, CDROMPAUSE) == -1 )
Con_DPrintf("ioctl cdrompause failed\n");
wasPlaying = playing;
playing = false;
}
void CDAudio_Resume(void)
{
if (cdfile == -1 || !enabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
if (cdfile == -1)
return;
if ( ioctl(cdfile, CDROMRESUME) == -1 )
Con_DPrintf("ioctl cdromresume failed\n");
playing = true;
}
static void CD_f (void)
{
char *command;
int ret;
int n;
if (Cmd_Argc() < 2)
return;
command = Cmd_Argv (1);
if (Q_strcasecmp(command, "on") == 0)
{
enabled = true;
return;
}
if (Q_strcasecmp(command, "off") == 0)
{
if (playing)
CDAudio_Stop();
enabled = false;
return;
}
if (Q_strcasecmp(command, "reset") == 0)
{
enabled = true;
if (playing)
CDAudio_Stop();
for (n = 0; n < 100; n++)
remap[n] = n;
CDAudio_GetAudioDiskInfo();
return;
}
if (Q_strcasecmp(command, "remap") == 0)
{
ret = Cmd_Argc() - 2;
if (ret <= 0)
{
for (n = 1; n < 100; n++)
if (remap[n] != n)
Con_Printf(" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = Q_atoi(Cmd_Argv (n+1));
return;
}
if (Q_strcasecmp(command, "close") == 0)
{
CDAudio_CloseDoor();
return;
}
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
{
Con_Printf("No CD in player.\n");
return;
}
}
if (Q_strcasecmp(command, "play") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp(command, "loop") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true);
return;
}
if (Q_strcasecmp(command, "stop") == 0)
{
CDAudio_Stop();
return;
}
if (Q_strcasecmp(command, "pause") == 0)
{
CDAudio_Pause();
return;
}
if (Q_strcasecmp(command, "resume") == 0)
{
CDAudio_Resume();
return;
}
if (Q_strcasecmp(command, "eject") == 0)
{
if (playing)
CDAudio_Stop();
CDAudio_Eject();
cdValid = false;
return;
}
if (Q_strcasecmp(command, "info") == 0)
{
Con_Printf("%u tracks\n", maxTrack);
if (playing)
Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
else if (wasPlaying)
Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
return;
}
}
void BGMVolume_Callback(struct cvar_s *var, char *oldvalue)
{
int cdvolume;
if (!enabled)
return;
cdvolume = atof(oldvalue);
if (cdvolume && !var->ival)
CDAudio_Pause ();
else if (!cdvolume && var->ival)
CDAudio_Resume ();
}
void CDAudio_Update(void)
@ -348,19 +159,19 @@ void CDAudio_Update(void)
struct cdrom_subchnl subchnl;
static time_t lastchk;
if (!enabled)
return;
if (playing && lastchk < time(NULL)) {
lastchk = time(NULL) + 2; //two seconds between chks
if (playing && lastchk < time(NULL))
{
lastchk = time(NULL) + 2; //two seconds between checks
subchnl.cdsc_format = CDROM_MSF;
if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 )
{
Con_DPrintf("ioctl cdromsubchnl failed\n");
playing = false;
return;
}
if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED)
{
playing = false;
if (playLooping)
CDAudio_Play(playTrack, true);
@ -368,57 +179,43 @@ void CDAudio_Update(void)
}
}
int CDAudio_Init(void)
qboolean CDAudio_Startup(void)
{
int i;
#if 0
if (cls.state == ca_dedicated)
return -1;
#endif
if (cdfile != -1)
return true;
if (COM_CheckParm("-nocdaudio"))
return -1;
if (!bgmvolume.value)
return false;
if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) {
if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1)
{
Q_strncpyz(cd_dev, com_argv[i + 1], sizeof(cd_dev));
cd_dev[sizeof(cd_dev) - 1] = 0;
}
if ((cdfile = open(cd_dev, O_RDONLY)) == -1) {
if ((cdfile = open(cd_dev, O_RDONLY)) == -1)
{
Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno);
cdfile = -1;
return -1;
return false;
}
for (i = 0; i < 100; i++)
remap[i] = i;
initialized = true;
enabled = true;
return true;
}
if (CDAudio_GetAudioDiskInfo())
{
Con_Printf("CDAudio_Init: No CD in player.\n");
cdValid = false;
}
Cmd_AddCommand ("cd", CD_f);
Cvar_Hook(&bgmvolume, BGMVolume_Callback);
Con_Printf("CD Audio Initialized\n");
return 0;
void CDAudio_Init(void)
{
}
void CDAudio_Shutdown(void)
{
if (!initialized)
if (cdfile == -1)
return;
CDAudio_Stop();
close(cdfile);
cdfile = -1;
Cvar_Unhook(&bgmvolume);
}
#endif

View File

@ -17,12 +17,11 @@ void CDAudio_Update(void)
{
}
int CDAudio_Init(void)
void CDAudio_Init(void)
{
return -1;
}
void CDAudio_Play(int track, qboolean looping)
void CDAudio_Play(int track)
{
}
@ -37,3 +36,21 @@ void CDAudio_Pause(void)
void CDAudio_Resume(void)
{
}
void CDAudio_Eject(void)
{
}
void CDAudio_CloseDoor(void)
{
}
int CDAudio_GetAudioDiskInfo(void)
{
return -2;
}
int CDAudio_Startup(void)
{
return -2;
}

View File

@ -4,91 +4,48 @@
extern cvar_t bgmvolume;
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean initialized = false;
static qboolean enabled = false;
static qboolean playLooping = false;
static qbyte remap[100];
static qbyte playTrack;
static qbyte maxTrack;
static SDL_CD *cddevice;
static void CDAudio_Eject(void)
void CDAudio_Eject(void)
{
if (SDL_CDEject(cddevice))
Con_DPrintf("SDL_CDEject failed\n");
}
static void CDAudio_CloseDoor(void)
void CDAudio_CloseDoor(void)
{
Con_Printf("SDL does not support this\n");
}
static int CDAudio_GetAudioDiskInfo(void)
int CDAudio_GetAudioDiskInfo(void)
{
cdValid = false;
switch (SDL_CDStatus(cddevice))
{
case CD_ERROR:
Con_Printf("SDL_CDStatus returned error\n");
return -1;
case CD_TRAYEMPTY:
cdValid = false;
return 1;
return 0;
default:
break;
}
cdValid = true;
maxTrack = cddevice->numtracks;
return 0;
return cddevice->numtracks;
}
void CDAudio_Play(int track, qboolean looping)
void CDAudio_Play(int track)
{
if (!enabled)
return;
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
return;
}
track = remap[track];
if (track < 1 || track > maxTrack)
{
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
return;
}
if (playing)
{
if (playTrack == track)
return;
CDAudio_Stop();
}
if (SDL_CDPlayTracks(cddevice, track, 0, track+1, 0))
if (SDL_CDPlayTracks(cddevice, track, 0, 1, 0))
{
Con_Printf("CDAudio: track %i is not audio\n", track);
return;
}
playLooping = looping;
playTrack = track;
playing = true;
if (!bgmvolume.value)
CDAudio_Pause ();
@ -98,225 +55,25 @@ void CDAudio_Play(int track, qboolean looping)
void CDAudio_Stop(void)
{
if (!enabled)
return;
if (!playing)
return;
if (SDL_CDStop(cddevice))
Con_DPrintf("CDAudio: SDL_CDStop failed");
wasPlaying = false;
playing = false;
}
void CDAudio_Pause(void)
{
if (!enabled)
return;
if (!playing)
return;
if (SDL_CDPause(cddevice))
Con_DPrintf("CDAudio: SDL_CDPause failed");
wasPlaying = playing;
playing = false;
}
void CDAudio_Resume(void)
{
if (!enabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
return;
if (SDL_CDResume(cddevice))
{
Con_DPrintf("CDAudio: SDL_CDResume failed\n");
return;
}
playing = true;
}
static void CD_f (void)
{
char *command;
int ret;
int n;
if (!initialized)
return;
if (Cmd_Argc() < 2)
return;
command = Cmd_Argv (1);
if (Q_strcasecmp(command, "on") == 0)
{
enabled = true;
return;
}
if (Q_strcasecmp(command, "off") == 0)
{
if (playing)
CDAudio_Stop();
enabled = false;
return;
}
if (Q_strcasecmp(command, "reset") == 0)
{
enabled = true;
if (playing)
CDAudio_Stop();
for (n = 0; n < 100; n++)
remap[n] = n;
CDAudio_GetAudioDiskInfo();
return;
}
if (Q_strcasecmp(command, "remap") == 0)
{
ret = Cmd_Argc() - 2;
if (ret <= 0)
{
for (n = 1; n < 100; n++)
if (remap[n] != n)
Con_Printf(" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = Q_atoi(Cmd_Argv (n+1));
return;
}
if (Q_strcasecmp(command, "close") == 0)
{
CDAudio_CloseDoor();
return;
}
if (Q_strcasecmp(command, "play") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp(command, "eject") == 0)
{
if (playing)
CDAudio_Stop();
CDAudio_Eject();
cdValid = false;
return;
}
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
{
Con_Printf("No CD in player.\n");
return;
}
}
if (Q_strcasecmp(command, "loop") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true);
return;
}
if (Q_strcasecmp(command, "stop") == 0)
{
CDAudio_Stop();
return;
}
if (Q_strcasecmp(command, "pause") == 0)
{
CDAudio_Pause();
return;
}
if (Q_strcasecmp(command, "resume") == 0)
{
CDAudio_Resume();
return;
}
if (Q_strcasecmp(command, "info") == 0)
{
Con_Printf("%u tracks\n", maxTrack);
if (playing)
Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
else if (wasPlaying)
Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
return;
}
}
/*
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (lParam != wDeviceID)
return 1;
switch (wParam)
{
case MCI_NOTIFY_SUCCESSFUL:
if (playing)
{
playing = false;
if (playLooping)
CDAudio_Play(playTrack, true);
}
break;
case MCI_NOTIFY_ABORTED:
case MCI_NOTIFY_SUPERSEDED:
break;
case MCI_NOTIFY_FAILURE:
Con_DPrintf("MCI_NOTIFY_FAILURE\n");
CDAudio_Stop ();
cdValid = false;
break;
default:
Con_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
return 1;
}
return 0;
}
*/
void BGMVolume_Callback(struct cvar_s *var, char *oldvalue)
{
int cdvolume;
if (!enabled)
return;
cdvolume = atof(oldvalue);
if (cdvolume && !var->ival)
CDAudio_Pause ();
else if (!cdvolume && var->ival)
CDAudio_Resume ();
}
void CDAudio_Update(void)
@ -324,53 +81,36 @@ void CDAudio_Update(void)
}
int CDAudio_Init(void)
void CDAudio_Init(void)
{
int n;
}
#if 0 // QW
if (cls.state == ca_dedicated)
return -1;
#endif
if (COM_CheckParm("-nocdaudio"))
return -1;
qboolean CDAudio_Startup(void)
{
if (initialized)
return !!cddevice;
if (!bgmvolume.value)
return false;
initialized = true;
SDL_InitSubSystem(SDL_INIT_CDROM|SDL_INIT_NOPARACHUTE);
if(!SDL_CDNumDrives())
{
Con_DPrintf("CDAudio_Init: No CD drives\n");
return -1;
return false;
}
cddevice = SDL_CDOpen(0);
if (!cddevice)
{
Con_Printf("CDAudio_Init: SDL_CDOpen failed\n");
return -1;
return false;
}
for (n = 0; n < 100; n++)
remap[n] = n;
initialized = true;
enabled = true;
if (CDAudio_GetAudioDiskInfo())
{
Con_Printf("CDAudio_Init: No CD in player.\n");
cdValid = false;
enabled = false;
}
Cmd_AddCommand ("cd", CD_f);
Cvar_Hook(&bgmvolume, BGMVolume_Callback);
// Con_Printf("CD Audio Initialized\n");
return 0;
return true;
}
void CDAudio_Shutdown(void)
{
if (!initialized)
@ -380,6 +120,4 @@ void CDAudio_Shutdown(void)
SDL_CDClose(cddevice);
cddevice = NULL;
initialized = false;
Cvar_Unhook(&bgmvolume);
}

View File

@ -30,43 +30,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern HWND mainwindow;
extern cvar_t bgmvolume;
static qboolean cdValid = false;
static qboolean playing = false;
static qboolean wasPlaying = false;
static qboolean initialized = false;
static qboolean initializefailed = false;
static qboolean enabled = false;
static qboolean playLooping = false;
static qbyte remap[100];
static qbyte playTrack;
static qbyte maxTrack;
static qboolean initialized;
static qboolean initializefailed;
static DWORD resumeend;
static qboolean pollneeded; //workaround for windows vista/7 bug, where notification simply does not work for end of tracks.
static UINT wDeviceID;
static void BGMVolume_Callback(struct cvar_s *var, char *oldvalue)
{
int cdvolume;
if (!enabled)
return;
cdvolume = atof(oldvalue);
if (cdvolume && !var->ival)
CDAudio_Pause ();
else if (!cdvolume && var->ival)
CDAudio_Resume ();
}
static int CDAudio_GetAudioDiskInfo(void)
int CDAudio_GetAudioDiskInfo(void)
{
DWORD dwReturn;
MCI_STATUS_PARMS mciStatusParms;
static MCI_STATUS_PARMS mciStatusParms;
if (!CDAudio_Startup())
return -1;
cdValid = false;
if (!initialized)
return -1;
mciStatusParms.dwItem = MCI_STATUS_READY;
mciStatusParms.dwCallback = (DWORD_PTR)mainwindow;
dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
if (dwReturn)
{
@ -80,6 +63,7 @@ static 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);
if (dwReturn)
{
@ -92,28 +76,22 @@ static int CDAudio_GetAudioDiskInfo(void)
return -1;
}
cdValid = true;
maxTrack = mciStatusParms.dwReturn;
return 0;
return mciStatusParms.dwReturn;
}
static qboolean CDAudio_Startup(void)
qboolean CDAudio_Startup(void)
{
DWORD dwReturn;
MCI_OPEN_PARMS mciOpenParms;
MCI_SET_PARMS mciSetParms;
int n;
static MCI_OPEN_PARMS mciOpenParms;
static MCI_SET_PARMS mciSetParms;
if (initializefailed)
return false;
if (!bgmvolume.value)
return false;
if (initialized)
return true;
mciOpenParms.lpstrDeviceType = "cdaudio";
mciOpenParms.dwCallback = (DWORD_PTR)mainwindow;
dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD_PTR) (LPVOID) &mciOpenParms);
if (dwReturn)
{
@ -123,8 +101,9 @@ static qboolean CDAudio_Startup(void)
}
wDeviceID = mciOpenParms.wDeviceID;
// Set the time format to track/minute/second/frame (TMSF).
mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
// 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)
{
@ -134,26 +113,19 @@ static qboolean CDAudio_Startup(void)
return 0;
}
for (n = 0; n < 100; n++)
remap[n] = n;
initialized = true;
enabled = true;
if (CDAudio_GetAudioDiskInfo())
if (CDAudio_GetAudioDiskInfo() <= 0)
{
Con_Printf("CDAudio_Init: No CD in player.\n");
cdValid = false;
enabled = false;
}
Cvar_Hook(&bgmvolume, BGMVolume_Callback);
return true;
}
void CDAudio_Shutdown(void)
{
if (initialized)
{
Cvar_Unhook(&bgmvolume);
CDAudio_Stop();
if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD_PTR)NULL))
Con_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n");
@ -162,7 +134,7 @@ void CDAudio_Shutdown(void)
initialized = false;
}
static void CDAudio_Eject(void)
void CDAudio_Eject(void)
{
DWORD dwReturn;
@ -171,8 +143,7 @@ static void CDAudio_Eject(void)
Con_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", (int)dwReturn);
}
static void CDAudio_CloseDoor(void)
void CDAudio_CloseDoor(void)
{
DWORD dwReturn;
@ -181,41 +152,42 @@ static void CDAudio_CloseDoor(void)
Con_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", (int)dwReturn);
}
void CDAudio_Play(int track, qboolean looping)
//try to add time values sensibly because:
//a) microsoft api SUCKS and does not directly support frames.
//b) microsoft buggily stops 3 frames short of the end of the track if we use tmsf...
//c) frames added together will break things
//d) we can subtract an offset so we can actually detect when its reached the end of a track
//e) we need to do frames so we don't break if some track is exactly a multiple of a second long
DWORD MSFToFrames(DWORD base)
{
int m = MCI_MSF_MINUTE(base);
int s = MCI_MSF_SECOND(base);
int f = MCI_MSF_FRAME(base);
s += m*60;
f += 75*s; //75 frames per second.
return f;
}
DWORD FramesToMSF(DWORD in)
{
DWORD m, s, f;
f = in % 75;
in /= 75;
s = in % 60;
in /= 60;
m = in;
return MCI_MAKE_MSF(m, s, f);
}
void CDAudio_Play(int track)
{
DWORD dwReturn;
MCI_PLAY_PARMS mciPlayParms;
MCI_STATUS_PARMS mciStatusParms;
static MCI_PLAY_PARMS mciPlayParms;
static MCI_STATUS_PARMS mciStatusParms;
DWORD trackstartposition;
#ifndef NOMEDIA
if (Media_FakeTrack(track, looping))
{
if (playing)
CDAudio_Stop();
return;
}
#endif
if (!enabled)
{
return;
}
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
{
return;
}
}
if (!CDAudio_Startup())
return;
track = remap[track];
if (track < 1 || track > maxTrack)
if (track < 1)
{
Con_DPrintf("CDAudio: Bad track number %u.\n", track);
return;
@ -224,6 +196,7 @@ void CDAudio_Play(int track, qboolean looping)
// don't try to play a non-audio 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);
if (dwReturn)
{
@ -236,9 +209,22 @@ void CDAudio_Play(int track, qboolean looping)
return;
}
// get the start of the track to be played
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);
if (dwReturn)
{
Con_DPrintf("MCI_STATUS failed (%i)\n", (int)dwReturn);
return;
}
trackstartposition = mciStatusParms.dwReturn;
// get the length of the track to be played
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);
if (dwReturn)
{
@ -246,15 +232,9 @@ void CDAudio_Play(int track, qboolean looping)
return;
}
if (playing)
{
if (playTrack == track)
return;
CDAudio_Stop();
}
mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
//set up to play from start to start+length
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);
if (dwReturn)
@ -263,9 +243,7 @@ void CDAudio_Play(int track, qboolean looping)
return;
}
playLooping = looping;
playTrack = track;
playing = true;
pollneeded = true;
if (!bgmvolume.value)
CDAudio_Pause ();
@ -278,61 +256,38 @@ void CDAudio_Stop(void)
{
DWORD dwReturn;
if (!enabled)
return;
if (!playing)
return;
pollneeded = false;
dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD_PTR)NULL);
if (dwReturn)
Con_DPrintf("MCI_STOP failed (%i)", (int)dwReturn);
wasPlaying = false;
playing = false;
}
void CDAudio_Pause(void)
{
DWORD dwReturn;
MCI_GENERIC_PARMS mciGenericParms;
if (!enabled)
return;
if (!playing)
return;
static MCI_GENERIC_PARMS mciGenericParms;
mciGenericParms.dwCallback = (DWORD_PTR)mainwindow;
dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD_PTR)(LPVOID) &mciGenericParms);
if (dwReturn)
Con_DPrintf("MCI_PAUSE failed (%i)", (int)dwReturn);
wasPlaying = playing;
playing = false;
pollneeded = false;
}
void CDAudio_Resume(void)
{
DWORD dwReturn;
MCI_PLAY_PARMS mciPlayParms;
if (!enabled)
return;
if (!cdValid)
return;
if (!wasPlaying)
return;
static MCI_PLAY_PARMS mciPlayParms;
if (!bgmvolume.value)
return;
mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0);
mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0);
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)
@ -340,133 +295,8 @@ void CDAudio_Resume(void)
Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", (int)dwReturn);
return;
}
playing = true;
}
static 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)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), false);
return;
}
if (Q_strcasecmp(command, "loop") == 0)
{
CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true);
return;
}
if (!CDAudio_Startup())
{
Con_Printf("No cd drive detected\n");
return;
}
if (Q_strcasecmp(command, "on") == 0)
{
enabled = true;
return;
}
if (Q_strcasecmp(command, "off") == 0)
{
if (playing)
CDAudio_Stop();
enabled = false;
return;
}
if (Q_strcasecmp(command, "reset") == 0)
{
enabled = true;
if (playing)
CDAudio_Stop();
for (n = 0; n < 100; n++)
remap[n] = n;
CDAudio_GetAudioDiskInfo();
return;
}
if (Q_strcasecmp(command, "remap") == 0)
{
ret = Cmd_Argc() - 2;
if (ret <= 0)
{
for (n = 1; n < 100; n++)
if (remap[n] != n)
Con_Printf(" %u -> %u\n", n, remap[n]);
return;
}
for (n = 1; n <= ret; n++)
remap[n] = Q_atoi(Cmd_Argv (n+1));
return;
}
if (Q_strcasecmp(command, "close") == 0)
{
CDAudio_CloseDoor();
return;
}
if (!cdValid)
{
CDAudio_GetAudioDiskInfo();
if (!cdValid)
{
Con_Printf("No CD in player.\n");
return;
}
}
if (Q_strcasecmp(command, "stop") == 0)
{
CDAudio_Stop();
return;
}
if (Q_strcasecmp(command, "pause") == 0)
{
CDAudio_Pause();
return;
}
if (Q_strcasecmp(command, "resume") == 0)
{
CDAudio_Resume();
return;
}
if (Q_strcasecmp(command, "eject") == 0)
{
if (playing)
CDAudio_Stop();
CDAudio_Eject();
cdValid = false;
return;
}
if (Q_strcasecmp(command, "info") == 0)
{
Con_Printf("%u tracks\n", maxTrack);
if (playing)
Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
else if (wasPlaying)
Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
return;
}
pollneeded = true;
}
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@ -477,12 +307,8 @@ LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (wParam)
{
case MCI_NOTIFY_SUCCESSFUL:
if (playing)
{
playing = false;
if (playLooping)
CDAudio_Play(playTrack, true);
}
pollneeded = false;
Media_EndedTrack();
break;
case MCI_NOTIFY_ABORTED:
@ -492,7 +318,8 @@ LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case MCI_NOTIFY_FAILURE:
Con_DPrintf("MCI_NOTIFY_FAILURE\n");
CDAudio_Stop ();
cdValid = false;
CDAudio_Shutdown();
// Media_EndedTrack();
break;
default:
@ -505,23 +332,34 @@ LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
void CDAudio_Update(void)
{
//workaround for vista bug where MCI_NOTIFY does not work to signal the end of the track.
if (pollneeded)
{
MCI_STATUS_PARMS mciStatusParms;
mciStatusParms.dwCallback = (DWORD_PTR)mainwindow;
mciStatusParms.dwItem = MCI_STATUS_POSITION;
mciStatusParms.dwReturn = resumeend;
mciStatusParms.dwTrack = 0;
if (0 == mciSendCommand(wDeviceID, MCI_STATUS, MCI_WAIT|MCI_STATUS_ITEM, (DWORD_PTR)&mciStatusParms))
{
unsigned int c, f;
int cm = MCI_MSF_MINUTE(mciStatusParms.dwReturn);
int cs = MCI_MSF_SECOND(mciStatusParms.dwReturn);
int cf = MCI_MSF_FRAME(mciStatusParms.dwReturn);
int fm = MCI_MSF_MINUTE(resumeend);
int fs = MCI_MSF_SECOND(resumeend);
int ff = MCI_MSF_FRAME(resumeend);
c = cf | (cs<<8) | (cm<<16);
f = ff | (fs<<8) | (fm<<16);
if (c >= f)
{
pollneeded = false;
Media_EndedTrack();
}
}
}
}
int CDAudio_Init(void)
void CDAudio_Init(void)
{
Cmd_AddCommand ("cd", CD_f);
#if 0 // QW
if (cls.state == ca_dedicated)
return -1;
#endif
if (COM_CheckParm("-nocdaudio"))
initializefailed = true;
else
initializefailed = false;
return 0;
}

View File

@ -18,11 +18,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
int CDAudio_Init(void);
void CDAudio_Play(int track, qboolean looping);
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.
void CDAudio_Play(int track);
void CDAudio_Stop(void);
void CDAudio_Pause(void);
void CDAudio_Resume(void);
void CDAudio_Eject(void);
void CDAudio_CloseDoor(void);
void CDAudio_Shutdown(void);
void CDAudio_Update(void);

View File

@ -468,21 +468,28 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
if (cl_chasecam.value || scr_chatmode == 2)
{
float *neworg;
// float *newang;
if (pv->nolocalplayer)
neworg = cl.lerpents[pv->viewentity].origin;
else
neworg = player->origin;
if (scr_chatmode != 2)
pv->cam_lastviewtime = realtime;
VectorCopy(player->viewangles, pv->viewangles);
if (memcmp(player->origin, &self->origin, sizeof(player->origin)) != 0)
// VectorCopy(newang, pv->viewangles);
if (memcmp(neworg, &self->origin, sizeof(vec3_t)) != 0)
{
if (!cls.demoplayback)
{
MSG_WriteByte (&cls.netchan.message, clc_tmove);
MSG_WriteCoord (&cls.netchan.message, player->origin[0]);
MSG_WriteCoord (&cls.netchan.message, player->origin[1]);
MSG_WriteCoord (&cls.netchan.message, player->origin[2]);
MSG_WriteCoord (&cls.netchan.message, neworg[0]);
MSG_WriteCoord (&cls.netchan.message, neworg[1]);
MSG_WriteCoord (&cls.netchan.message, neworg[2]);
}
// move there locally immediately
VectorCopy(player->origin, self->origin);
VectorCopy(neworg, self->origin);
}
self->weaponframe = player->weaponframe;

View File

@ -533,7 +533,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_UPDATESCREEN: //force a buffer swap cos loading won't refresh it soon.
if (key_dest != key_console)
if (!Key_Dest_Has(kdm_console))
scr_con_current = 0;
SCR_UpdateScreen();
break;

View File

@ -454,7 +454,8 @@ qboolean CL_GetDemoMessage (void)
cls.td_startframe = host_framecount;
//force the console up, we're done loading.
key_dest = key_game;
Key_Dest_Remove(kdm_console);
Key_Dest_Remove(kdm_menu);
scr_con_current = 0;
}
@ -588,7 +589,7 @@ readnext:
cls.td_startframe = host_framecount;
//force the console up, we're done loading.
key_dest = key_game;
Key_Dest_Remove(kdm_console);
scr_con_current = 0;
}
if (cls.td_startframe == host_framecount+1)
@ -1910,7 +1911,7 @@ void CL_QTVPoll (void)
if (!sourcesmenu)
{
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, 32, 144, "gfx/qplaque.lmp");

View File

@ -129,9 +129,11 @@ static void CL_ClearDlight(dlight_t *dl, int key)
dl->color[2] = 1;
dl->corona = bound(0, r_flashblend.value * 0.25, 1);
dl->coronascale = bound(0, r_flashblendscale.value, 1);
#ifdef RTLIGHTS
dl->lightcolourscales[0] = r_shadow_realtime_dlight_ambient.value;
dl->lightcolourscales[1] = r_shadow_realtime_dlight_diffuse.value;
dl->lightcolourscales[2] = r_shadow_realtime_dlight_specular.value;
#endif
// if (r_shadow_realtime_dlight_shadowmap.value)
// dl->flags |= LFLAG_SHADOWMAP;
}
@ -722,7 +724,6 @@ void CLFTE_ParseEntities(void)
unsigned int newnum, oldnum;
int oldindex;
qboolean isvalid = false;
entity_state_t *e;
qboolean removeflag;
int inputframe = cls.netchan.incoming_sequence;
@ -4500,6 +4501,12 @@ void CL_LinkViewModel(void)
if (r_refdef.playerview->stats[STAT_HEALTH] <= 0)
return;
if (cl.intermission)
return;
if (pv->stats[STAT_WEAPON] <= 0 || pv->stats[STAT_WEAPON] >= MAX_MODELS)
return;
if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1)
alpha = r_drawviewmodel.value;
else
@ -4515,10 +4522,6 @@ void CL_LinkViewModel(void)
V_ClearEntity(&ent);
ent.model = r_refdef.playerview->viewent.model;
if (!ent.model)
return;
#ifdef PEXT_SCALE
ent.scale = 1;
#endif
@ -4540,11 +4543,15 @@ void CL_LinkViewModel(void)
ent.flags |= Q2RF_TRANSLUCENT;
}
ent.model = cl.model_precache[pv->stats[STAT_WEAPON]];
if (!ent.model)
return;
#ifdef HLCLIENT
if (!CLHL_AnimateViewEntity(&ent))
#endif
{
ent.framestate.g[FS_REG].frame[0] = pv->viewent.framestate.g[FS_REG].frame[0];
ent.framestate.g[FS_REG].frame[0] = pv->stats[STAT_WEAPONFRAME];
ent.framestate.g[FS_REG].frame[1] = pv->oldframe;
if (ent.framestate.g[FS_REG].frame[0] != pv->prevframe)

View File

@ -630,11 +630,11 @@ void CL_CheckForResend (void)
char data[2048];
double t1, t2;
int contype = 0;
unsigned int pext1, pext2;
#ifndef CLIENTONLY
if (!cls.state && sv.state)
{
unsigned int pext1, pext2;
pext1 = 0;
pext2 = 0;
Q_strncpyz (cls.servername, "internalserver", sizeof(cls.servername));
@ -3849,10 +3849,11 @@ int nopacketcount;
void SNDDMA_SetUnderWater(qboolean underwater);
double Host_Frame (double time)
{
static double time0 = 0;
static double time1 = 0;
static double time2 = 0;
static double time3 = 0;
int pass1, pass2, pass3;
int pass0, pass1, pass2, pass3;
// float fps;
double newrealtime;
static double spare;
@ -3906,8 +3907,8 @@ double Host_Frame (double time)
#ifdef VM_UI
UI_MenuState() != 0 ||
#endif
key_dest == key_menu ||
key_dest == key_editor ||
Key_Dest_Has(kdm_menu) ||
Key_Dest_Has(kdm_editor) ||
cl.paused;
// TODO: check if minimized or unfocused
@ -4048,6 +4049,9 @@ double Host_Frame (double time)
RSpeedEnd(RSPEED_PROTOCOL);
if (host_speeds.ival)
time0 = Sys_DoubleTime ();
#ifndef CLIENTONLY
if (sv.state)
{
@ -4106,12 +4110,13 @@ double Host_Frame (double time)
if (host_speeds.ival)
{
pass1 = (time1 - time3)*1000;
pass0 = (time0 - time3)*1000000;
time3 = Sys_DoubleTime ();
pass2 = (time2 - time1)*1000;
pass3 = (time3 - time2)*1000;
Con_TPrintf (TLC_HOSTSPEEDSOUTPUT,
pass1+pass2+pass3, pass1, pass2, pass3);
pass1 = (time1 - time0)*1000000;
pass2 = (time2 - time1)*1000000;
pass3 = (time3 - time2)*1000000;
Con_Printf ("%4i tot %4i idle %4i server %4i gfx %4i snd\n",
pass0+pass1+pass2+pass3, pass0, pass1, pass2, pass3);
}
@ -4307,7 +4312,7 @@ void CL_ExecInitialConfigs(char *resetcommand)
//if the renderer is already up and running, be prepared to reload content to match the new conback/font/etc
if (qrenderer != QR_NONE)
Cbuf_AddText ("vid_reload\n", RESTRICT_LOCAL);
if (key_dest == key_menu)
if (Key_Dest_Has(kdm_menu))
Cbuf_AddText ("closemenu\ntogglemenu\n", RESTRICT_LOCAL); //make sure the menu has the right content loaded.
Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to

View File

@ -3290,6 +3290,7 @@ void CL_ParseModellist (qboolean lots)
int nummodels;
char *str;
int n;
int vwplayerindex = -1;
// precache models and note certain default indexes
if (lots)
@ -3311,6 +3312,8 @@ void CL_ParseModellist (qboolean lots)
cl_spikeindex = nummodels;
if (!strcmp(cl.model_name[nummodels],"progs/player.mdl"))
cl_playerindex = nummodels;
if (*cl.model_name_vwep[0] && !strcmp(cl.model_name[nummodels],cl.model_name_vwep[0]) && cl_playerindex == -1)
cl_playerindex = nummodels;
if (!strcmp(cl.model_name[nummodels],"progs/h_player.mdl"))
cl_h_playerindex = nummodels;
if (!strcmp(cl.model_name[nummodels],"progs/flag.mdl"))
@ -3457,7 +3460,7 @@ void CLQ2_ParseConfigString (void)
else if (i == Q2CS_CDTRACK)
{
// if (cl.refresh_prepped)
CDAudio_Play (atoi(s), true);
Media_NumberedTrack (atoi(s), atoi(s));
}
else if (i >= Q2CS_MODELS && i < Q2CS_MODELS+Q2MAX_MODELS)
{
@ -5698,7 +5701,7 @@ void CLQW_ParseServerMessage (void)
case svc_cdtrack:
cl.cdtrack = MSG_ReadByte ();
CDAudio_Play ((qbyte)cl.cdtrack, true);
Media_NumberedTrack ((qbyte)cl.cdtrack, (qbyte)cl.cdtrack);
break;
case svc_intermission:
@ -6350,7 +6353,7 @@ void CLNQ_ParseServerMessage (void)
cl.cdtrack = MSG_ReadByte ();
MSG_ReadByte ();
CDAudio_Play ((qbyte)cl.cdtrack, true);
Media_NumberedTrack ((qbyte)cl.cdtrack, (qbyte)cl.cdtrack);
break;
case svc_setview:

View File

@ -27,19 +27,19 @@ qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t
Plug_Menu_Event(3, 0);
menuplug = NULL;
currentplug = oldplug;
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
}
if (VM_LONG(arg[0]) != 1)
return 1;
//give us menu control
menuplug = currentplug;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_plugin;
return 1;
case 2: //weather it's us or not.
return currentplug == menuplug && m_state == m_plugin;
case 3: //weather a menu is active
return key_dest == key_menu;
return !!Key_Dest_Has(kdm_menu);
default:
return 0;
}
@ -561,7 +561,7 @@ void Plug_Client_Close(plugin_t *plug)
if (menuplug == plug)
{
menuplug = NULL;
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
}
if (protocolclientplugin == plug)
{

View File

@ -32,7 +32,7 @@ extern usercmd_t independantphysics[MAX_SPLITS];
#ifdef Q2CLIENT
#define MAX_PARSE_ENTITIES 1024
extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
extern entity_state_t clq2_parse_entities[MAX_PARSE_ENTITIES];
char *Get_Q2ConfigString(int i);
@ -113,7 +113,7 @@ void CLQ2_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t en
for (i=0 ; i<cl.q2frame.num_entities ; i++)
{
num = (cl.q2frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
ent = &cl_parse_entities[num];
ent = &clq2_parse_entities[num];
if (!ent->solid)
continue;
@ -202,7 +202,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
for (i=0 ; i<cl.q2frame.num_entities ; i++)
{
num = (cl.q2frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
ent = &cl_parse_entities[num];
ent = &clq2_parse_entities[num];
if (ent->solid != 31) // special value for bmodel
continue;
@ -726,6 +726,8 @@ static void CL_EntStateToPlayerState(player_state_t *plstate, entity_state_t *st
plstate->pm_type = pmtype;
VectorCopy(state->origin, plstate->origin);
VectorScale(state->u.q1.velocity, 1/8.0, plstate->velocity);
VectorCopy(state->angles, plstate->viewangles);
plstate->viewangles[0] *= -3;
a[0] = ((-192-state->u.q1.gravitydir[0])/256.0f) * 360;
a[1] = (state->u.q1.gravitydir[1]/256.0f) * 360;
@ -1126,11 +1128,13 @@ Con_DPrintf("%i:%f %f %i:%f (%f)\n", fromframe, fromtime, simtime, toframe, toti
pv->simorg[i] = (1-f)*fromstate->origin[i] + f*tostate->origin[i];
pv->simvel[i] = (1-f)*fromstate->velocity[i] + f*tostate->velocity[i];
/* if (cl.spectator && Cam_TrackNum(vnum) >= 0)
pv->simangles[i] = LerpAngles16(from->playerstate[pnum].command.angles[i], to->playerstate[pnum].command.angles[i], f) * (360.0/65535);
else if (cls.demoplayback == DPB_QUAKEWORLD)
pv->simangles[i] = LerpAngles16(cmdfrom->cmd[vnum].angles[i], cmdto->cmd[vnum].angles[i], f) * (360.0/65535);
*/ }
if (pv->viewentity != pv->playernum+1)
{
pv->simangles[i] = LerpAngles360(fromstate->viewangles[i], tostate->viewangles[i], f);// * (360.0/65535);
// pv->viewangles[i] = LerpAngles16(fromstate->command.angles[i], tostate->command.angles[i], f) * (360.0/65535);
}
}
}
CL_CatagorizePosition(pv);
@ -1140,8 +1144,11 @@ Con_DPrintf("%i:%f %f %i:%f (%f)\n", fromframe, fromtime, simtime, toframe, toti
{
//keep the entity tracking the prediction position, so mirrors don't go all weird
VectorCopy(tostate->origin, le->origin);
VectorScale(pv->simangles, 1, le->angles);
le->angles[0] *= -0.333;
if (pv->stats[STAT_HEALTH] > 0)
{
VectorScale(pv->simangles, 1, le->angles);
le->angles[0] *= -0.333;
}
}
// if (cls.demoplayback)

View File

@ -64,6 +64,7 @@ void RSpeedShow(void)
RSpNames[RSPEED_FINISH] = "glFinish";
memset(RQntNames, 0, sizeof(RQntNames));
RQntNames[RQUANT_MSECS] = "Microseconds";
RQntNames[RQUANT_EPOLYS] = "Entity Polys";
RQntNames[RQUANT_WPOLYS] = "World Polys";
@ -72,24 +73,33 @@ void RSpeedShow(void)
RQntNames[RQUANT_WORLDBATCHES] = "World Batches";
RQntNames[RQUANT_ENTBATCHES] = "Ent Batches";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow Edges";
RQntNames[RQUANT_SHADOWSIDES] = "Shadowmap Sides";
RQntNames[RQUANT_LITFACES] = "Lit faces";
RQntNames[RQUANT_RTLIGHT_DRAWN] = "Lights Drawn";
RQntNames[RQUANT_RTLIGHT_CULL_FRUSTUM] = "Lights offscreen";
RQntNames[RQUANT_RTLIGHT_CULL_PVS] = "Lights PVS Culled";
RQntNames[RQUANT_RTLIGHT_CULL_SCISSOR] = "Lights Scissored";
if (r_speeds.ival > 1)
{
for (i = 0; i < RSPEED_MAX; i++)
{
s = va("%i %-20s", samplerspeeds[i], RSpNames[i]);
s = va("%g %-20s", samplerspeeds[i]/100.0, RSpNames[i]);
Draw_FunString(vid.width-strlen(s)*8, i*8, s);
}
}
for (i = 0; i < RQUANT_MAX; i++)
{
s = va("%i %-20s", samplerquant[i], RQntNames[i]);
s = va("%g %-20s", samplerquant[i]/100.0, RQntNames[i]);
Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
}
if (r_speeds.ival > 1)
{
s = va("%f %-20s", 100000000.0f/(samplerspeeds[RSPEED_TOTALREFRESH]+samplerspeeds[RSPEED_FINISH]), "Framerate");
Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
}
s = va("%f %-20s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate");
Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
if (++framecount>=100)
{
@ -161,7 +171,6 @@ int scr_chatmode;
extern cvar_t scr_chatmodecvar;
int mouseusedforgui;
float mousecursor_x, mousecursor_y;
float mousemove_x, mousemove_y;
@ -550,7 +559,7 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
void SCR_CheckDrawCenterString (void)
{
extern qboolean sb_showscores;
extern qboolean sb_showscores;
int pnum;
cprint_t *p;
vrect_t rect;
@ -564,7 +573,7 @@ extern qboolean sb_showscores;
p->time_off -= host_frametime;
if (key_dest != key_game) //don't let progs guis/centerprints interfere with the game menu
if (Key_Dest_Has(~kdm_game)) //don't let progs guis/centerprints interfere with the game menu
continue;
if (sb_showscores) //this was annoying
@ -1296,7 +1305,7 @@ void SCR_DrawPause (void)
if (!cl.paused)
return;
if (key_dest == key_menu)
if (Key_Dest_Has(kdm_menu))
return;
pic = R2D_SafeCachePic ("gfx/pause.lmp");
@ -1586,7 +1595,7 @@ void SCR_ImageName (char *mapname)
GL_BeginRendering ();
SCR_DrawLoading();
SCR_SetUpToDrawConsole();
if (key_dest == key_console || !*levelshotname)
if (Key_Dest_Has(kdm_console) || !*levelshotname)
SCR_DrawConsole(!!*levelshotname);
GL_EndRendering();
scr_drawloading = false;
@ -1622,24 +1631,27 @@ void SCR_SetUpToDrawConsole (void)
//android has an onscreen imm that we don't want to obscure
fullscreenpercent = scr_consize.value;
#endif
if ((key_dest == key_console || key_dest == key_game) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->needload))
if ((!Key_Dest_Has(~(kdm_console|kdm_game))) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->needload))
{
key_dest = key_console;
//force console to fullscreen if we're loading stuff
Key_Dest_Add(kdm_console);
scr_conlines = scr_con_current = vid.height * fullscreenpercent;
}
else if ((key_dest == key_console || key_dest == key_game) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
else if ((!Key_Dest_Has(~(kdm_console|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
{
//go fullscreen if we're not doing anything
#ifdef VM_UI
if (key_dest == key_game && (UI_MenuState() || UI_OpenMenu()))
if (UI_MenuState() || UI_OpenMenu())
;
else
#endif
if (cls.state < ca_demostart)
key_dest = key_console;
Key_Dest_Add(kdm_console);
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
}
else if (key_dest == key_console || scr_chatmode)
else if (Key_Dest_Has(kdm_console) || scr_chatmode)
{
//go half-screen if we're meant to have the console visible
scr_conlines = vid.height*scr_consize.value; // half screen
if (scr_conlines < 32)
scr_conlines = 32; //prevent total loss of console.
@ -1690,7 +1702,7 @@ void SCR_DrawConsole (qboolean noback)
}
else
{
if (key_dest == key_game || key_dest == key_message)
if (!Key_Dest_Has(kdm_console|kdm_menu))
Con_DrawNotify (); // only draw notify in game
}
}
@ -2125,6 +2137,7 @@ void SCR_TileClear (void)
// The 2d refresh stuff.
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
{
qboolean consolefocused = !!Key_Dest_Has(kdm_console);
RSpeedMark();
R2D_ImageColours(1, 1, 1, 1);
@ -2183,7 +2196,8 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
Editor_Draw();
#endif
if (key_dest != key_console)
//if the console is not focused, show it scrolling back up behind the menu
if (!consolefocused)
SCR_DrawConsole (false);
M_Draw (uimenu);
@ -2191,7 +2205,8 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
MP_Draw();
#endif
if (key_dest == key_console)
//but if the console IS focused, then always show it infront.
if (consolefocused)
SCR_DrawConsole (false);
if (Key_MouseShouldBeFree())

View File

@ -955,7 +955,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
Key_ClearStates();
break;
case UI_KEY_GETCATCHER:
if (key_dest == key_console)
if (Key_Dest_Has(kdm_console))
VM_LONG(ret) = keycatcher | 1;
else
VM_LONG(ret) = keycatcher;
@ -1414,8 +1414,6 @@ void UI_DrawMenu(void)
if (uivm)
{
VM_Call(uivm, UI_REFRESH, (int)(realtime * 1000));
if (keycatcher&2 && key_dest != key_console)
key_dest = key_game;
}
}
@ -1461,7 +1459,7 @@ void UI_Reset(void)
int UI_MenuState(void)
{
if (key_dest == key_menu)
if (Key_Dest_Has(kdm_menu))
{
return false;
}
@ -1589,7 +1587,6 @@ qboolean UI_OpenMenu(void)
VM_Call(uivm, UI_SET_ACTIVE_MENU, 2);
else
VM_Call(uivm, UI_SET_ACTIVE_MENU, 1);
key_dest = key_game;
return true;
}
return false;

View File

@ -1460,7 +1460,7 @@ int CLHL_ParseGamePacket(void)
case svc_cdtrack:
cl.cdtrack = MSG_ReadByte();
MSG_ReadByte();
CDAudio_Play ((qbyte)cl.cdtrack, true);
CDAudio_Play ((qbyte)cl.cdtrack, (qbyte)cl.cdtrack);
break;
case 35: //svc_weaponanimation:

View File

@ -271,7 +271,9 @@ typedef struct dlight_s
float minlight; // don't add when contributing less
float color[3];
float channelfade[3];
#ifdef RTLIGHTS
vec3_t lightcolourscales; //ambient, diffuse, specular
#endif
float corona;
float coronascale;
@ -570,7 +572,9 @@ struct playerview_s
CAM_TRACK = 1
} cam_auto; //
entity_t viewent; // is this not utterly redundant yet?
vec3_t vw_axis[3]; //weapons should be positioned relative to this
vec3_t vw_origin; //weapons should be positioned relative to this
// entity_t viewent; // is this not utterly redundant yet?
struct model_s *oldmodel;
float lerptime;
float frameduration;
@ -1297,6 +1301,7 @@ extern qboolean care_f_modified;
void CLQ2_ParseTEnt (void);
void CLQ2_AddEntities (void);
void CLQ2_ParseBaseline (void);
void CLQ2_ClearParticleState(void);
void CLQ2_ParseFrame (void);
void CLQ2_RunMuzzleFlash2 (int ent, int flash_number);
int CLQ2_RegisterTEntModels (void);
@ -1370,7 +1375,9 @@ struct cin_s *Media_StartCin(char *name);
texid_tf Media_UpdateForShader(cin_t *cin);
void Media_ShutdownCin(cin_t *cin);
qboolean Media_FakeTrack(int i, qboolean loop);
qboolean Media_BackgroundTrack(char *track, char *looptrack);
qboolean Media_BackgroundTrack(char *initialtrack, char *looptrack);
void Media_NumberedTrack(int initialtrack, int looptrack);
void Media_EndedTrack(void); //cd is no longer running, media code needs to pick a new track (cd track or faketrack)
#endif
//these accept NULL for cin to mean the current fullscreen video

View File

@ -107,8 +107,8 @@ void CLQ2_BlasterTrail2(vec3_t oldorg, vec3_t neworg){};
#define MAX_PARSE_ENTITIES 1024
q2centity_t cl_entities[MAX_Q2EDICTS];
entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
static q2centity_t cl_entities[MAX_Q2EDICTS];
entity_state_t clq2_parse_entities[MAX_PARSE_ENTITIES];
void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float fvol, float attenuation, float timeofs);
void CL_SmokeAndFlash(vec3_t origin);
@ -629,6 +629,15 @@ void CLQ2_ParseDelta (entity_state_t *from, entity_state_t *to, int number, int
to->solid = MSG_ReadShort ();
}
void CLQ2_ClearParticleState(void)
{
int i;
for (i = 0; i < MAX_Q2EDICTS; i++)
{
P_DelinkTrailstate(&cl_entities[i].trailstate);
}
}
/*
==================
CL_DeltaEntity
@ -637,14 +646,14 @@ Parses deltas from the given base and adds the resulting entity
to the current frame
==================
*/
void CLQ2_DeltaEntity (q2frame_t *frame, int newnum, entity_state_t *old, int bits)
static void CLQ2_DeltaEntity (q2frame_t *frame, int newnum, entity_state_t *old, int bits)
{
q2centity_t *ent;
entity_state_t *state;
ent = &cl_entities[newnum];
state = &cl_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
state = &clq2_parse_entities[cl.parse_entities & (MAX_PARSE_ENTITIES-1)];
cl.parse_entities++;
frame->num_entities++;
@ -700,7 +709,7 @@ An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*/
void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
static void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
{
int newnum;
int bits;
@ -722,7 +731,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldstate = &clq2_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldnum = oldstate->number;
}
}
@ -751,7 +760,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldstate = &clq2_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldnum = oldstate->number;
}
}
@ -769,7 +778,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldstate = &clq2_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldnum = oldstate->number;
}
continue;
@ -787,7 +796,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldstate = &clq2_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldnum = oldstate->number;
}
continue;
@ -816,7 +825,7 @@ void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
oldnum = 99999;
else
{
oldstate = &cl_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldstate = &clq2_parse_entities[(oldframe->parse_entities+oldindex) & (MAX_PARSE_ENTITIES-1)];
oldnum = oldstate->number;
}
}
@ -974,7 +983,7 @@ void CLQ2_FireEntityEvents (q2frame_t *frame)
for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
{
num = (frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1);
s1 = &cl_parse_entities[num];
s1 = &clq2_parse_entities[num];
if (s1->u.q2.event)
CLQ2_EntityEvent (s1);
@ -1191,7 +1200,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
for (pnum = 0 ; pnum<frame->num_entities ; pnum++)
{
s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
s1 = &clq2_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
cent = &cl_entities[s1->number];
@ -1744,9 +1753,9 @@ CL_AddViewWeapon
void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops)
{
entity_t gun; // view model
entity_t *view;
extern cvar_t cl_gunx, cl_guny, cl_gunz;
extern cvar_t cl_gunanglex, cl_gunangley, cl_gunanglez;
playerview_t *pv = &cl.playerview[0];
// allow the gun to be completely removed
if (!r_drawviewmodel.value)
@ -1760,10 +1769,9 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops)
return;
//generate root matrix..
view = &cl.playerview[0].viewent;
VectorCopy(cl.playerview[0].simorg, view->origin);
AngleVectors(cl.playerview[0].simangles, view->axis[0], view->axis[1], view->axis[2]);
VectorInverse(view->axis[1]);
VectorCopy(cl.playerview[0].simorg, pv->vw_origin);
AngleVectors(cl.playerview[0].simangles, pv->vw_axis[0], pv->vw_axis[1], pv->vw_axis[2]);
VectorInverse(pv->vw_axis[1]);
memset (&gun, 0, sizeof(gun));

View File

@ -914,7 +914,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
cmd->upmove = 100;
cmd->buttons &= ~2;
}
if (key_dest != key_game || (keycatcher&3))
if (Key_Dest_Has(~kdm_game) || (keycatcher&3))
cmd->buttons |= 2; //add in the 'at console' button
cl.outframes[cl.movesequence&Q3UPDATE_MASK].cmd[0] = *cmd;

View File

@ -437,22 +437,17 @@ void Con_ToggleConsole_Force(void)
SCR_EndLoadingPlaque();
Key_ClearTyping ();
if (key_dest == key_console)
{
if (m_state)
key_dest = key_menu;
else
key_dest = key_game;
}
if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
else
key_dest = key_console;
Key_Dest_Add(kdm_console);
}
void Con_ToggleConsole_f (void)
{
#ifdef CSQC_DAT
if (key_dest == key_game && CSQC_ConsoleCommand("toggleconsole"))
if (!(key_dest_mask & kdm_editor) && CSQC_ConsoleCommand("toggleconsole"))
{
key_dest = key_game;
Key_Dest_Remove(kdm_console);
return;
}
#endif
@ -460,24 +455,6 @@ void Con_ToggleConsole_f (void)
Con_ToggleConsole_Force();
}
/*
================
Con_ToggleChat_f
================
*/
void Con_ToggleChat_f (void)
{
Key_ClearTyping ();
if (key_dest == key_console)
{
if (cls.state == ca_active)
key_dest = key_game;
}
else
key_dest = key_console;
}
void Con_ClearCon(console_t *con)
{
conline_t *t;
@ -551,7 +528,8 @@ Con_MessageMode_f
void Con_MessageMode_f (void)
{
chat_team = false;
key_dest = key_message;
Key_Dest_Add(kdm_message);
Key_Dest_Remove(kdm_console);
}
/*
@ -562,12 +540,13 @@ Con_MessageMode2_f
void Con_MessageMode2_f (void)
{
chat_team = true;
key_dest = key_message;
Key_Dest_Add(kdm_message);
Key_Dest_Remove(kdm_console);
}
void Con_ForceActiveNow(void)
{
key_dest = key_console;
Key_Dest_Add(kdm_console);
scr_conlines = scr_con_current = vid.height;
}
@ -604,7 +583,6 @@ void Con_Init (void)
Cvar_Register (&con_separatechat, "Console controls");
Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
Cmd_AddCommand ("togglechat", Con_ToggleChat_f);
Cmd_AddCommand ("messagemode", Con_MessageMode_f);
Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
Cmd_AddCommand ("clear", Con_Clear_f);
@ -1255,7 +1233,7 @@ void Con_DrawNotify (void)
Con_DrawNotifyOne(con);
}
if (key_dest == key_message)
if (Key_Dest_Has(kdm_message))
{
int x, y;
conchar_t *starts[8];
@ -1798,7 +1776,7 @@ void Con_DrawConsole (int lines, qboolean noback)
y -= Font_CharHeight();
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
y = Con_DrawInput (con_current, key_dest == key_console, x, ex - x, y, selactive, selsx, selex, selsy, seley);
y = Con_DrawInput (con_current, Key_Dest_Has(kdm_console), x, ex - x, y, selactive, selsx, selex, selsy, seley);
l = con_current->display;
@ -1826,7 +1804,7 @@ void Con_DrawOneConsole(console_t *con, struct font_s *font, float fx, float fy,
Font_BeginString(font, fx, fy, &x, &y);
Font_BeginString(font, fx+fsx, fy+fsy, &sx, &sy);
if (con == con_current && key_dest == key_console)
if (con == con_current && Key_Dest_Has(kdm_console))
{
selactive = false; //don't change selections if this is the main console and we're looking at the console, because that main console has focus instead anyway.
selsx = selsy = selex = seley = 0;
@ -1972,6 +1950,7 @@ Con_NotifyBox
void Con_NotifyBox (char *text)
{
double t1, t2;
qboolean hadconsole;
// during startup for sound / cd warnings
Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
@ -1982,7 +1961,8 @@ void Con_NotifyBox (char *text)
Con_Printf("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
key_count = -2; // wait for a key down and up
key_dest = key_console;
hadconsole = !!Key_Dest_Has(kdm_console);
Key_Dest_Add(kdm_console);
do
{
@ -1994,5 +1974,7 @@ void Con_NotifyBox (char *text)
} while (key_count < 0);
Con_Printf ("\n");
key_dest = key_game;
if (!hadconsole)
Key_Dest_Remove(kdm_console);
}

View File

@ -336,6 +336,8 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
}
else
{
mousecursor_x += mx;
mousecursor_y += my;
#ifdef VM_UI
if (UI_MousePosition(mx, my))
{
@ -347,7 +349,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
if (mouse->type == M_TOUCH)
{
if (m_strafeonright.ival && mouse->downpos[0] > vid.pixelwidth/2 && movements != NULL && (key_dest == key_game))
if (m_strafeonright.ival && mouse->downpos[0] > vid.pixelwidth/2 && movements != NULL && !Key_Dest_Has(kdm_game))
{
//if they're strafing, calculate the speed to move at based upon their displacement
if (mouse->down)
@ -386,6 +388,13 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
}
else
{
//if game is not focused, kill any mouse look
if (Key_Dest_Has(~kdm_game))
{
mx = 0;
my = 0;
}
if (mx || my)
if (CSQC_MouseMove(mx, my, mouse->qdeviceid))
{

View File

@ -36,30 +36,6 @@ void IN_DeactivateMouse(void)
SDL_WM_GrabInput(SDL_GRAB_OFF);
}
void IN_UpdateGrabs(int fullscreen, int activeapp)
{
if (!vid_isfullscreen)
{
if (!_windowed_mouse.value)
{
if (mouseactive)
{
IN_DeactivateMouse ();
}
}
else
{
if ((key_dest == key_game||mouseusedforgui) && ActiveApp)
IN_ActivateMouse ();
else if (!(key_dest == key_game || mouseusedforgui) || !ActiveApp)
IN_DeactivateMouse ();
}
}
}
#define tenoh 0,0,0,0,0, 0,0,0,0,0
#define fiftyoh tenoh, tenoh, tenoh, tenoh, tenoh
#define hundredoh fiftyoh, fiftyoh

View File

@ -39,7 +39,9 @@ int key_lastpress;
int edit_line=0;
int history_line=0;
keydest_t key_dest;
unsigned int key_dest_mask;
qboolean key_dest_console;
unsigned int key_dest_absolutemouse;
int key_count; // incremented every key event
@ -1299,7 +1301,7 @@ void Key_Message (int key, int unicode)
CL_Say(chat_team, "");
}
key_dest = key_game;
Key_Dest_Remove(kdm_message);
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
@ -1307,7 +1309,7 @@ void Key_Message (int key, int unicode)
if (key == K_ESCAPE)
{
key_dest = key_game;
Key_Dest_Remove(kdm_message);
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
@ -1689,6 +1691,9 @@ void Key_Init (void)
key_lines[i][0] = ']';
}
key_linepos = 1;
key_dest_mask = kdm_game;
key_dest_absolutemouse = kdm_console | kdm_editor;
//
// init ascii characters in console mode
@ -1783,20 +1788,17 @@ qboolean Key_MouseShouldBeFree(void)
//if true, the input code is expected to return mouse cursor positions rather than deltas
extern cvar_t cl_prydoncursor;
extern int mouseusedforgui;
if (mouseusedforgui) //I don't like this
if (key_dest_absolutemouse & key_dest_mask)
return true;
// if (!ActiveApp)
// return true;
if (key_dest == key_menu)
if (Key_Dest_Has(kdm_menu))
{
if (m_state == m_complex || m_state == m_plugin /*|| m_state == m_menu_dat*/)
return true;
}
if (key_dest == key_console || key_dest == key_editor)
return true;
#ifdef VM_UI
if (UI_MenuState())
@ -1876,7 +1878,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
}
}
if (keydown[k] && (key_dest != key_console && key_dest != key_message))
if (keydown[k] && !Key_Dest_Has(~kdm_game))
{
deltaused[k][keystate] = true;
@ -1940,8 +1942,8 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
}
//yes, csqc is allowed to steal the escape key.
if (key != '`' && (!down || key != K_ESCAPE || (key_dest == key_game && !shift_down)))
if (key_dest == key_game && !Media_PlayingFullScreen())
if (key != '`' && (!down || key != K_ESCAPE || (!Key_Dest_Has(~kdm_game) && !shift_down)))
if (!Key_Dest_Has(~kdm_game) && !Media_PlayingFullScreen())
{
#ifdef CSQC_DAT
if (CSQC_KeyPress(key, unicode, down, devid)) //give csqc a chance to handle it.
@ -1960,7 +1962,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
{
#ifdef VM_UI
#ifdef TEXTEDITOR
if (key_dest == key_game)
if (!Key_Dest_Has(~kdm_game))
#endif
{
if (down && Media_PlayingFullScreen())
@ -1974,50 +1976,35 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
#endif
if (!down)
{
if (key_dest == key_menu)
M_Keyup (key, unicode);
return;
}
switch (key_dest)
if (Key_Dest_Has(kdm_console))
{
case key_message:
Key_Message (key, unicode);
break;
case key_menu:
M_Keydown (key, unicode);
break;
#ifdef TEXTEDITOR
case key_editor:
if (cls.state || Key_Dest_Has(~(kdm_console|kdm_game)))
Key_Dest_Remove(kdm_console);
else
M_ToggleMenu_f ();
}
else if (Key_Dest_Has(kdm_editor))
Editor_Key (key, unicode);
break;
#endif
case key_game:
else if (Key_Dest_Has(kdm_menu))
M_Keydown (key, unicode);
else if (Key_Dest_Has(kdm_message))
Key_Dest_Remove(kdm_message);
else
{
if (Media_PlayingFullScreen())
{
Media_StopFilm(true);
break;
if (!cls.state)
M_ToggleMenu_f ();
}
case key_console:
if (cls.state && key_dest == key_console)
key_dest = key_game;
else
M_ToggleMenu_f ();
break;
default:
Sys_Error ("Bad key_dest");
}
return;
}
#ifndef NOMEDIA
if (key_dest == key_game && Media_PlayingFullScreen())
{
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
return;
}
#endif
//
// key up events only generate commands if the game key binding is
// a button command (leading + sign). These will occur even in console mode,
@ -2027,19 +2014,16 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
//
if (!down)
{
switch (key_dest)
if (Key_Dest_Has(kdm_console))
{
case key_menu:
M_Keyup (key, unicode);
break;
case key_console:
con_current->mousecursor[0] = mousecursor_x;
con_current->mousecursor[1] = mousecursor_y;
Key_ConsoleRelease(con_current, key, unicode);
break;
default:
break;
}
if (Key_Dest_Has(kdm_menu))
M_Keyup (key, unicode);
if (Media_PlayingFullScreen())
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
if (!deltaused[key][keystate]) //this wasn't down, so don't make it leave down state.
return;
@ -2077,7 +2061,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
//
// during demo playback, most keys bring up the main menu
//
if (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV && down && conkey && key != K_TAB && key_dest == key_game)
if (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV && down && conkey && key != K_TAB && !Key_Dest_Has(~kdm_game))
{
M_ToggleMenu_f ();
return;
@ -2088,90 +2072,76 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
//
#ifdef VM_UI
if (key != '`' && key != '~')
if (key_dest == key_game || !down)
if (!Key_Dest_Has(~kdm_game) || !down)
{
if (UI_KeyPress(key, unicode, down) && down) //UI is allowed to take these keydowns. Keyups are always maintained.
return;
}
#endif
if (key && ((key_dest == key_menu && menubound[key])
|| (key_dest == key_console && !conkey)
|| (key_dest == key_game && ( cls.state == ca_active || (!conkey) ) ) ))
if (conkey && Key_Dest_Has(kdm_console))
{
/*don't auto-repeat binds as it breaks too many scripts*/
if (key_repeats[key] > 1)
return;
deltaused[key][keystate] = true;
if (devid)
Q_snprintfz (p, sizeof(p), "p %i ", devid+1);
else
*p = 0;
if (key == K_RALT) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_ALT;
if (key == K_RCTRL) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_CTRL;
if (key == K_RSHIFT)//simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_SHIFT;
kb = keybindings[key][keystate];
if (kb)
{
if (kb[0] == '+')
{ // button commands add keynum as a parm
Q_snprintfz (cmd, sizeof(cmd), "+%s%s %i\n", p, kb+1, key+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[key][keystate]);
}
else
{
if (*p)Cbuf_AddText (p, bindcmdlevel[key][keystate]);
Cbuf_AddText (kb, bindcmdlevel[key][keystate]);
Cbuf_AddText ("\n", bindcmdlevel[key][keystate]);
}
}
return;
}
if (!down)
{
switch (key_dest)
{
case key_menu:
M_Keyup (key, unicode);
break;
default:
break;
}
return; // other systems only care about key down events
}
switch (key_dest)
{
case key_message:
Key_Message (key, unicode);
break;
case key_menu:
M_Keydown (key, unicode);
break;
#ifdef TEXTEDITOR
case key_editor:
Editor_Key (key, unicode);
break;
#endif
case key_game:
case key_console:
if ((key && unicode) || key == K_ENTER || key == K_KP_ENTER || key == K_TAB)
key_dest = key_console;
con_current->mousecursor[0] = mousecursor_x;
con_current->mousecursor[1] = mousecursor_y;
Key_Console (con_current, unicode, key);
break;
default:
Sys_Error ("Bad key_dest");
return;
}
if (Key_Dest_Has(kdm_editor))
{
Editor_Key (key, unicode);
return;
}
if (Key_Dest_Has(kdm_menu))
{
M_Keydown (key, unicode);
return;
}
if (Key_Dest_Has(kdm_message))
{
Key_Message (key, unicode);
return;
}
if (Media_PlayingFullScreen())
{
Media_Send_KeyEvent(NULL, key, unicode, down?0:1);
return;
}
//anything else is a key binding.
/*don't auto-repeat binds as it breaks too many scripts*/
if (key_repeats[key] > 1)
return;
deltaused[key][keystate] = true;
if (devid)
Q_snprintfz (p, sizeof(p), "p %i ", devid+1);
else
*p = 0;
if (key == K_RALT) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_ALT;
if (key == K_RCTRL) //simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_CTRL;
if (key == K_RSHIFT)//simulate a singular alt for binds. really though, this code should translate to csqc/menu keycodes and back to resolve the weirdness instead.
key = K_SHIFT;
kb = keybindings[key][keystate];
if (kb)
{
if (kb[0] == '+')
{ // button commands add keynum as a parm
Q_snprintfz (cmd, sizeof(cmd), "+%s%s %i\n", p, kb+1, key+oldstate*256);
Cbuf_AddText (cmd, bindcmdlevel[key][keystate]);
}
else
{
if (*p)Cbuf_AddText (p, bindcmdlevel[key][keystate]);
Cbuf_AddText (kb, bindcmdlevel[key][keystate]);
Cbuf_AddText ("\n", bindcmdlevel[key][keystate]);
}
}
}

View File

@ -170,9 +170,23 @@ K_MAX = 256
#define K_CTRL K_LCTRL
#define K_ALT K_LALT
typedef enum {key_game, key_console, key_message, key_menu, key_editor} keydest_t;
typedef enum //highest has priority
{
kdm_game = 1u<<0, //should always be set
kdm_message = 1u<<1,
kdm_menu = 1u<<2,
kdm_editor = 1u<<3,
kdm_console = 1u<<4,
} keydestmask_t;
extern keydest_t key_dest;
//unsigned int Key_Dest_Get(void); //returns highest priority destination
#define Key_Dest_Add(kdm) (key_dest_mask |= (kdm))
#define Key_Dest_Remove(kdm) (key_dest_mask &= ~(kdm))
#define Key_Dest_Has(kdm) (key_dest_mask & (kdm))
#define Key_Dest_Toggle(kdm) do {if (key_dest_mask & kdm) Key_Dest_Remove(kdm); else Key_Dest_Add(kdm);}while(0)
extern unsigned int key_dest_absolutemouse; //if the active key dest bit is set, the mouse is absolute.
extern unsigned int key_dest_mask;
extern char *keybindings[K_MAX][8];
extern int key_repeats[K_MAX];
extern int key_count; // incremented every key event

View File

@ -764,7 +764,7 @@ void Menu_DownloadStuff_f (void)
menu_t *menu;
dlmenu_t *info;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(dlmenu_t));

View File

@ -1526,7 +1526,7 @@ void M_Complex_Draw(void)
if (!firstmenu)
{
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
return;
}
@ -1853,7 +1853,7 @@ qboolean MC_Main_Key (int key, menu_t *menu) //here purly to restart demos.
if (key == K_ESCAPE)
{
extern int m_save_demonum;
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
cls.demonum = m_save_demonum;
if (cls.demonum != -1 && !cls.demoplayback && cls.state == ca_disconnected && COM_CheckParm("-demos"))
@ -1912,7 +1912,7 @@ void M_Menu_Main_f (void)
if (R2D_SafeCachePic("pics/m_main_game"))
{
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
@ -1963,7 +1963,7 @@ void M_Menu_Main_f (void)
else if (mgt == MGT_HEXEN2)
{
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
mainm = M_CreateMenu(0);
mainm->key = MC_Main_Key;
@ -2003,7 +2003,7 @@ void M_Menu_Main_f (void)
else if (QBigFontWorks())
{
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
mainm = M_CreateMenu(0);
p = R2D_SafeCachePic("gfx/ttl_main.lmp");
@ -2037,7 +2037,7 @@ void M_Menu_Main_f (void)
else
{
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
mainm = M_CreateMenu(0);
p = R2D_SafeCachePic("gfx/ttl_main.lmp");

View File

@ -592,7 +592,7 @@ void M_Menu_ServerList2_f(void)
return;
}
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(serverlist_t));
@ -761,7 +761,7 @@ void M_QuickConnect_f(void)
menucustom_t *cust;
menu_t *menu;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
MasterInfo_Refresh();

View File

@ -28,8 +28,8 @@ HWND hwnd_winamp;
qboolean Media_EvaluateNextTrack(void);
typedef struct mediatrack_s{
char filename[128];
char nicename[128];
char filename[MAX_QPATH];
char nicename[MAX_QPATH];
int length;
struct mediatrack_s *next;
} mediatrack_t;
@ -212,69 +212,150 @@ qboolean Media_EvaluateNextTrack(void)
return true;
}
static char cdloopingtrack[MAX_QPATH];
static qboolean fakecdactive;
#define REMAPPED_TRACKS 100
static struct
{
char fname[MAX_QPATH];
} cdremap[REMAPPED_TRACKS];
static qboolean cdenabled;
static int cdplayingtrack; //currently playing cd track (becomes 0 when paused)
static int cdpausedtrack; //currently paused cd track
static int cdnumtracks; //maximum cd track we can play.
//flushes music channel on all soundcards, and the tracks that arn't decoded yet.
void Media_Clear (void)
{
//make sure we're not playing any cd music.
if (cdplayingtrack || cdpausedtrack)
{
cdplayingtrack = 0;
cdpausedtrack = 0;
CDAudio_Stop();
}
Q_strncpyz(currenttrack.filename, "", sizeof(currenttrack.filename));
fakecdactive = false;
media_playing = false;
S_Music_Clear(NULL);
}
qboolean fakecdactive;
//fake cd tracks.
qboolean Media_BackgroundTrack(char *track, char *looptrack)
{
char *ext[] = {
unsigned int tracknum;
static char *path[] =
{
"music/",
"sound/cdtracks/",
"",
NULL
};
static char *ext[] =
{
"",
".ogg",
#ifdef WINAVI
".mp3",
#endif
".wav",
NULL};
NULL
};
char *trackend;
char trackname[MAX_QPATH];
int i;
if (!track || !*track)
int ie, ip;
qboolean found = false;
if (!track || !*track) //ignore calls if the primary track is invalid. whatever is already playing will continue to play.
return false;
if (!looptrack || !*looptrack)
if (!looptrack || !*looptrack) //null or empty looptrack loops using the primary track, for compat with q3.
looptrack = track;
for(i = 0; ext[i]; i++)
{
Q_snprintfz(trackname, sizeof(name), "%s%s", track, ext[i]);
if (COM_FCheckExists(trackname))
{
Media_Clear();
strcpy(currenttrack.filename, trackname);
fakecdactive = true;
media_playing = true;
return true;
}
//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);
if (*trackend)
tracknum = 0;
if (tracknum > 0 && tracknum < REMAPPED_TRACKS && *cdremap[tracknum].fname)
{ //remap the track if its remapped.
track = cdremap[tracknum].fname;
tracknum = strtoul(track, &trackend, 0);
if (*trackend)
tracknum = 0;
}
return false;
}
qboolean Media_FakeTrack(int i, qboolean loop)
{
char trackname[512];
qboolean found;
if (i > 0 && i <= 999)
if (!strcmp(looptrack, "-")) //- for the looptrack argument can be used to prevent looping.
looptrack = "";
for(ip = 0; path[ip] && !found; ip++)
{
found = false;
if (!found && i <= 99)
if (tracknum)
{
sprintf(trackname, "music/track%02i", i);
if (Media_BackgroundTrack(trackname, loop?trackname:NULL))
return true;
if (tracknum <= 999)
{
for(ie = 0; ext[ie] && !found; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%strack%03i%s", path[ip], tracknum, ext[ie]);
found = COM_FCheckExists(trackname);
}
}
if (tracknum <= 99)
{
for(ie = 0; ext[ie] && !found; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%strack%02i%s", path[ip], tracknum, ext[ie]);
found = COM_FCheckExists(trackname);
}
}
}
if (!found)
{
sprintf(trackname, "sound/cdtracks/track%03i", i);
if (Media_BackgroundTrack(trackname, loop?trackname:NULL))
return true;
for(ie = 0; ext[ie] && !found; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%s%s%s", path[ip], track, ext[ie]);
found = COM_FCheckExists(trackname);
}
}
}
fakecdactive = false;
if (found)
{
Q_strncpyz(cdloopingtrack, looptrack, sizeof(cdloopingtrack));
Media_Clear();
Q_strncpyz(currenttrack.filename, trackname, sizeof(currenttrack.filename));
fakecdactive = true;
media_playing = true;
return true;
}
if (tracknum && cdenabled)
{
Q_strncpyz(cdloopingtrack, looptrack, sizeof(cdloopingtrack));
//couldn't do a faketrack, resort to actual cd tracks, if we're allowed
if (!CDAudio_Startup())
return false;
if (cdnumtracks <= 0)
cdnumtracks = CDAudio_GetAudioDiskInfo();
if (tracknum > cdnumtracks)
{
Con_DPrintf("CDAudio: Bad track number %u.\n", tracknum);
return false; //can't play that, sorry. its not an available track
}
if (cdplayingtrack == tracknum)
return true; //already playing, don't need to do anything
Media_Clear();
cdpausedtrack = 0;
cdplayingtrack = tracknum;
CDAudio_Play(tracknum);
return true;
}
return false;
}
@ -287,6 +368,168 @@ void Media_NamedTrack_f(void)
Media_BackgroundTrack(Cmd_Argv(1), Cmd_Argv(1));
}
void Media_SetPauseTrack(qboolean paused)
{
if (paused)
{
cdpausedtrack = cdplayingtrack;
cdplayingtrack = 0;
CDAudio_Pause();
}
else
{
cdplayingtrack = cdpausedtrack;
cdpausedtrack = 0;
CDAudio_Resume();
}
}
void Media_NumberedTrack(int initialtrack, int looptrack)
{
char *init = initialtrack?va("%i", initialtrack):NULL;
char *loop = looptrack?va("%i", looptrack):NULL;
Media_BackgroundTrack(init, loop);
}
void Media_EndedTrack(void)
{
cdplayingtrack = 0;
cdpausedtrack = 0;
if (cdloopingtrack)
Media_BackgroundTrack(cdloopingtrack, cdloopingtrack);
}
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_BackgroundTrack(Cmd_Argv(2), "-");
return;
}
if (Q_strcasecmp(command, "loop") == 0)
{
Media_BackgroundTrack(Cmd_Argv(2), NULL);
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 (!bgmvolume.ival)
{
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;
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, "stop") == 0)
{
CDAudio_Stop();
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)
{
@ -310,8 +553,9 @@ void Media_Next_f (void)
void M_Menu_Media_f (void) {
key_dest = key_menu;
void M_Menu_Media_f (void)
{
Key_Dest_Add(kdm_menu);
m_state = m_media;
}
@ -575,7 +819,7 @@ void M_Media_Key (int key)
mediatrack_t *newtrack;
newtrack = Z_Malloc(sizeof(mediatrack_t));
Q_strncpyz(newtrack->filename, media_iofilename, sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, COM_SkipPath(media_iofilename), sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, COM_SkipPath(media_iofilename), sizeof(newtrack->nicename));
newtrack->length = 0;
newtrack->next = tracks;
tracks = newtrack;
@ -715,7 +959,7 @@ void Media_LoadTrackNames (char *listname)
else
#endif
Q_strncpyz(newtrack->filename, filename, sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, trackname, sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, trackname, sizeof(newtrack->nicename));
newtrack->length = atoi(len);
newtrack->next = tracks;
tracks = newtrack;
@ -739,7 +983,7 @@ void Media_LoadTrackNames (char *listname)
newtrack = Z_Malloc(sizeof(mediatrack_t));
Q_strncpyz(newtrack->filename, filename, sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, COM_SkipPath(trackname), sizeof(newtrack->filename));
Q_strncpyz(newtrack->nicename, COM_SkipPath(trackname), sizeof(newtrack->nicename));
newtrack->length = 0;
newtrack->next = tracks;
tracks = newtrack;
@ -764,6 +1008,9 @@ char *Media_NextTrack(int musicchannelnum)
if (bgmvolume.value <= 0 || !media_playing)
return NULL;
if (!fakecdactive)
Media_EndedTrack();
if (!loadedtracknames)
Media_LoadTrackNames("sound/media.m3u");
if (!tracks && !fakecdactive)
@ -774,6 +1021,7 @@ char *Media_NextTrack(int musicchannelnum)
media_playing = false;
return NULL;
}
fakecdactive = false;
// if (cursndcard == sndcardinfo) //figure out the next track (primary sound card, we could actually get different tracks on different cards (and unfortunatly do))
// {
@ -2288,12 +2536,12 @@ qboolean Media_PlayFilm(char *name, qboolean enqueue)
CDAudio_Stop();
SCR_EndLoadingPlaque();
if (key_dest == key_menu)
if (Key_Dest_Has(kdm_menu))
{
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
}
if (key_dest != key_console)
if (!Key_Dest_Has(kdm_console))
scr_con_current=0;
return true;
}
@ -2841,7 +3089,7 @@ qboolean Media_PausedDemo (void)
//capturedemo doesn't record any frames when the console is visible
//but that's okay, as we don't load any demo frames either.
if ((cls.demoplayback && Media_Capturing()) || capturepaused)
if (key_dest != key_game || scr_con_current > 0 || !cl.validsequence || capturepaused)
if (Key_Dest_Has(~kdm_game) || scr_con_current > 0 || !cl.validsequence || capturepaused)
return true;
return false;
@ -3172,7 +3420,7 @@ void Media_RecordDemo_f(void)
Cmd_ShiftArgs(1, false);
Media_RecordFilm_f();
scr_con_current=0;
key_dest = key_game;
Key_Dest_Remove(kdm_console|kdm_menu);
if (currentcapture_funcs)
recordingdemo = true;
@ -3891,6 +4139,13 @@ void Media_Init(void)
Cmd_AddCommand("music_next", Media_Next_f);
Cmd_AddCommand("music", Media_NamedTrack_f);
Cmd_AddCommand("cd", CD_f);
cdenabled = false;
if (COM_CheckParm("-nocdaudio"))
cdenabled = false;
if (COM_CheckParm("-cdaudio"))
cdenabled = true;
#if defined(GLQUAKE)
Cmd_AddCommand("capture", Media_RecordFilm_f);
Cmd_AddCommand("capturedemo", Media_RecordDemo_f);

View File

@ -17,7 +17,7 @@ void M_Menu_MultiPlayer_f (void)
int mgt;
p = NULL;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
mgt = M_GameType();
@ -340,7 +340,7 @@ void M_Menu_Setup_f (void)
mpic_t *p;
menucustom_t *cu;
m_state = m_complex;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
menu = M_CreateMenu(sizeof(setupmenu_t));
info = menu->data;
@ -388,7 +388,7 @@ void M_Menu_Setup_f (void)
return;
}
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(setupmenu_t));
@ -573,7 +573,7 @@ void M_Menu_GameOptions_f (void)
int mgt;
int players;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(newmultimenu_t));

View File

@ -9,7 +9,7 @@ menu_t *M_Options_Title(int *y, int infosize)
struct menu_s *menu;
*y = 32;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(infosize);
@ -215,7 +215,7 @@ void M_Menu_Audio_Speakers_f (void)
audiomenuinfo_t *info;
menu_t *menu;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(audiomenuinfo_t));
@ -1074,6 +1074,8 @@ void M_Menu_Lighting_f (void)
int y;
menu_t *menu = M_Options_Title(&y, sizeof(lightingmenuinfo_t));
#ifdef RTLIGHTS
int lightselect, dlightselect;
if (r_shadow_realtime_world.ival)
@ -1105,6 +1107,7 @@ void M_Menu_Lighting_f (void)
dlightselect = 1;
else
dlightselect = 0;
#endif
{
lightingmenuinfo_t *info = menu->data;
@ -1112,10 +1115,13 @@ void M_Menu_Lighting_f (void)
{
MB_REDTEXT("Lighting Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
#ifdef RTLIGHTS
MB_COMBORETURN("Lighting Mode", lightingopts, lightselect, info->lightcombo, "Selects method used for world lighting. Realtime lighting requires appropriate realtime lighting files for maps."),
MB_COMBORETURN("Dynamic Lighting Mode", dlightopts, dlightselect, info->dlightcombo, "Selects method used for dynamic lighting such as explosion lights and muzzle flashes."),
MB_CHECKBOXCVARTIP("Soft Shadows", r_shadow_shadowmapping, 0, "Enables softer shadows instead of course-edged pixelated shadows."),
MB_CMD("Apply Lighting", M_VideoApplyShadowLighting, "Applies set lighting modes and restarts video."),
MB_SPACING(4),
#endif
MB_COMBOCVAR("LIT Loading", r_loadlits, loadlitopts, loadlitvalues, "Determines if the engine should use external colored lighting for maps. The generated setting will cause the engine to generate colored lighting for maps that don't have the associated data."),
MB_CHECKBOXCVAR("Lightstyle Lerp", r_lightstylesmooth, 0),
MB_SPACING(4),

View File

@ -43,8 +43,7 @@ void M_MenuS_Script_f (void) //create a menu.
extern menu_t *currentmenu;
menu_t *oldmenu;
char *alias = Cmd_Argv(1);
// if (key_dest != key_console)
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
selectitem = 0;

View File

@ -72,7 +72,7 @@ void M_Menu_Save_f (void)
if (cl.intermission)
return;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(loadsavemenuinfo_t));
@ -96,7 +96,7 @@ void M_Menu_Load_f (void)
menu_t *menu;
int i;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(loadsavemenuinfo_t));
@ -130,7 +130,7 @@ void M_Menu_SinglePlayer_f (void)
mpic_t *p;
#endif
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
#ifdef CLIENTONLY
@ -721,7 +721,7 @@ void M_Menu_Demos_f (void)
demomenu_t *info;
menu_t *menu;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(demomenu_t));
@ -759,7 +759,7 @@ void M_Menu_MediaFiles_f (void)
demomenu_t *info;
menu_t *menu;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(sizeof(demomenu_t));

View File

@ -177,10 +177,10 @@ int m_save_demonum;
void M_CloseMenu_f (void)
{
if (key_dest != key_menu)
if (!Key_Dest_Has(kdm_menu))
return;
M_RemoveAllMenus();
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
}
/*
@ -192,15 +192,14 @@ void M_ToggleMenu_f (void)
{
if (m_state)
{
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
return;
}
#ifdef CSQC_DAT
if (CSQC_ConsoleCommand("togglemenu"))
{
if (key_dest == key_console)
key_dest = key_game;
Key_Dest_Remove(kdm_console);
return;
}
#endif
@ -213,13 +212,14 @@ void M_ToggleMenu_f (void)
return;
#endif
if (key_dest == key_menu)
//it IS a toggle, so close the menu if its already active
if (Key_Dest_Has(kdm_menu))
{
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
return;
}
if (key_dest == key_console)
if (Key_Dest_Has(kdm_console))
{
if (cls.state != ca_active)
M_Menu_Main_f();
@ -364,7 +364,7 @@ void M_Menu_Keys_f (void)
int mgt;
extern cvar_t cl_splitscreen, cl_forcesplitclient;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
menu = M_CreateMenu(0);
@ -511,7 +511,7 @@ int helppagemin;
void M_Menu_Help_f (void)
{
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_help;
help_page = 0;
@ -619,7 +619,7 @@ void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, char *m1, char *m2
promptmenu_t *m;
char *t;
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
m = (promptmenu_t*)M_CreateMenuInfront(sizeof(*m) - sizeof(m->m) + strlen(m1)+strlen(m2)+strlen(m3)+strlen(optionyes)+strlen(optionyes)+strlen(optioncancel)+6);
@ -827,7 +827,7 @@ qboolean MC_Quit_Key (int key, menu_t *menu)
case 'Y':
case 'y':
M_RemoveMenu(menu);
key_dest = key_console;
Key_Dest_Add(kdm_console);
CL_Disconnect ();
Sys_Quit ();
break;
@ -910,7 +910,7 @@ void M_Menu_Quit_f (void)
Sys_Quit ();
break;
case 2:
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
quitmenu = M_CreateMenuInfront(0);
@ -928,7 +928,7 @@ void M_Menu_Quit_f (void)
MC_AddBox (quitmenu, 56, 76, 25, 5);
break;
case 1:
key_dest = key_menu;
Key_Dest_Add(kdm_menu);
m_state = m_complex;
quitmenu = M_CreateMenuInfront(0);
@ -1166,7 +1166,7 @@ void M_Draw (int uimenu)
{
M_RemoveAllMenus();
}
if (key_dest != key_menu)
if (!Key_Dest_Has(kdm_menu))
{
m_state = m_none;
return;
@ -1225,7 +1225,7 @@ void M_Keydown (int key, int unicode)
switch (m_state)
{
case m_none:
key_dest = key_console;
Key_Dest_Remove(kdm_menu);
return;
case m_help:

View File

@ -266,8 +266,6 @@ typedef enum backendmode_e
BEM_DEPTHNORM, //all opaque stuff drawn using 'depthnorm' shader
BEM_FOG, //drawing a fog volume
BEM_LIGHT, //we have a valid light
BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap
BEM_SMAPLIGHT //we have a light using a shadowmap
} backendmode_t;
typedef struct rendererinfo_s {
@ -322,7 +320,7 @@ typedef struct rendererinfo_s {
//Uploads all modified lightmaps
void (*BE_UploadAllLightmaps)(void);
void (*BE_SelectEntity)(struct entity_s *ent);
void (*BE_SelectDLight)(struct dlight_s *dl, vec3_t colour);
qboolean (*BE_SelectDLight)(struct dlight_s *dl, vec3_t colour, unsigned int lmode);
void (*BE_Scissor)(srect_t *rect);
/*check to see if an ent should be drawn for the selected light*/
qboolean (*BE_LightCullModel)(vec3_t org, struct model_s *model);

View File

@ -637,8 +637,8 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"}\n"
;
break;
case BM_INVMOD:
namepostfix = "_invmod";
case BM_INVMODA:
namepostfix = "_invmoda";
defaultshader =
"{\n"
"program defaultsprite\n"
@ -653,6 +653,22 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"}\n"
;
break;
case BM_INVMODC:
namepostfix = "_invmodc";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_ZERO GL_ONE_MINUS_SRC_COLOR\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
"}\n"
;
break;
case BM_SUBTRACT:
namepostfix = "_sub";
defaultshader =
@ -718,21 +734,95 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
}
}
static void P_ResetToDefaults(part_type_t *ptype)
{
particle_t *parts;
skytris_t *st;
part_type_t *torun;
char tnamebuf[sizeof(ptype->name)];
// go with a lazy clear of list.. mark everything as DEAD and let
// the beam rendering handle removing nodes
beamseg_t *beamsegs = ptype->beams;
while (beamsegs)
{
beamsegs->flags |= BS_DEAD;
beamsegs = beamsegs->next;
}
// forget any particles before its wiped
while (ptype->particles)
{
parts = ptype->particles->next;
ptype->particles->next = free_particles;
free_particles = ptype->particles;
ptype->particles = parts;
}
// if we're in the runstate loop through and remove from linked list
if (ptype->state & PS_INRUNLIST)
{
if (part_run_list == ptype)
part_run_list = part_run_list->nexttorun;
else
{
for (torun = part_run_list; torun != NULL; torun = torun->nexttorun)
{
if (torun->nexttorun == ptype)
torun->nexttorun = torun->nexttorun->nexttorun;
}
}
}
//some things need to be preserved before we clear everything.
beamsegs = ptype->beams;
st = ptype->skytris;
strcpy(tnamebuf, ptype->name);
//free uneeded info
if (ptype->ramp)
BZ_Free(ptype->ramp);
if (ptype->models)
BZ_Free(ptype->models);
//reset everything we're too lazy to specifically set
memset(ptype, 0, sizeof(*ptype));
//now set any non-0 defaults.
ptype->beams = beamsegs;
ptype->skytris = st;
strcpy(ptype->name, tnamebuf);
ptype->assoc=P_INVALID;
ptype->inwater = P_INVALID;
ptype->cliptype = P_INVALID;
ptype->emit = P_INVALID;
ptype->alpha = 1;
ptype->alphachange = 1;
ptype->clipbounce = 0.8;
ptype->colorindex = -1;
ptype->rotationstartmin = -M_PI; //start with a random angle
ptype->rotationstartrand = M_PI-ptype->rotationstartmin;
ptype->spawnchance = 1;
ptype->dl_time = 5000;
VectorSet(ptype->dl_rgb, 1, 1, 1);
ptype->randsmax = 1;
ptype->s2 = 1;
ptype->t2 = 1;
}
//Uses FTE's multiline console stuff.
//This is the function that loads the effect descriptions (via console).
static void P_ParticleEffect_f(void)
{
char *var, *value;
char *buf;
particle_t *parts;
beamseg_t *beamsegs;
skytris_t *st;
qboolean settype = false;
qboolean setalphadelta = false;
qboolean setbeamlen = false;
part_type_t *ptype, *torun;
char tnamebuf[sizeof(ptype->name)];
part_type_t *ptype;
int pnum, assoc;
char *config = part_parsenamespace;
@ -841,67 +931,7 @@ static void P_ParticleEffect_f(void)
pnum = ptype-part_type;
st = ptype->skytris;
if (ptype->ramp)
BZ_Free(ptype->ramp);
if (ptype->models)
BZ_Free(ptype->models);
while (ptype->particles) // empty particle list
{
parts = ptype->particles->next;
ptype->particles->next = free_particles;
free_particles = ptype->particles;
ptype->particles = parts;
}
// go with a lazy clear of list.. mark everything as DEAD and let
// the beam rendering handle removing nodes
beamsegs = ptype->beams;
while (beamsegs)
{
beamsegs->flags |= BS_DEAD;
beamsegs = beamsegs->next;
}
beamsegs = ptype->beams;
// if we're in the runstate loop through and remove from linked list
if (ptype->state & PS_INRUNLIST)
{
if (part_run_list == ptype)
part_run_list = part_run_list->nexttorun;
else
{
for (torun = part_run_list; torun != NULL; torun = torun->nexttorun)
{
if (torun->nexttorun == ptype)
torun->nexttorun = torun->nexttorun->nexttorun;
}
}
}
strcpy(tnamebuf, ptype->name);
memset(ptype, 0, sizeof(*ptype));
// ptype->particles = parts;
ptype->beams = beamsegs;
ptype->skytris = st;
strcpy(ptype->name, tnamebuf);
ptype->assoc=P_INVALID;
ptype->inwater = P_INVALID;
ptype->cliptype = P_INVALID;
ptype->emit = P_INVALID;
ptype->alpha = 1;
ptype->alphachange = 1;
ptype->clipbounce = 0.8;
ptype->colorindex = -1;
ptype->rotationstartmin = -M_PI; //start with a random angle
ptype->rotationstartrand = M_PI-ptype->rotationstartmin;
ptype->spawnchance = 1;
ptype->randsmax = 1;
ptype->s2 = 1;
ptype->t2 = 1;
P_ResetToDefaults(ptype);
while(1)
{
@ -1229,8 +1259,10 @@ static void P_ParticleEffect_f(void)
ptype->looks.blendmode = BM_ADD;
else if (!strcmp(value, "subtract"))
ptype->looks.blendmode = BM_SUBTRACT;
else if (!strcmp(value, "invmod"))
ptype->looks.blendmode = BM_INVMOD;
else if (!strcmp(value, "invmoda") || !strcmp(value, "invmod"))
ptype->looks.blendmode = BM_INVMODA;
else if (!strcmp(value, "invmodc"))
ptype->looks.blendmode = BM_INVMODC;
else if (!strcmp(value, "blendcolour") || !strcmp(value, "blendcolor"))
ptype->looks.blendmode = BM_BLENDCOLOUR;
else
@ -1959,6 +1991,7 @@ static void P_ImportEffectInfo_f(void)
break;
}
}
// P_ResetToDefaults(ptype);
ptype->loaded = part_parseweak?1:2;
ptype->scale = 1;
ptype->alpha = 0;
@ -1969,7 +2002,6 @@ static void P_ImportEffectInfo_f(void)
ptype->rgb[0] = 1;
ptype->rgb[1] = 1;
ptype->rgb[2] = 1;
ptype->colorindex = -1;
ptype->spawnmode = SM_BOX;
@ -1980,6 +2012,8 @@ static void P_ImportEffectInfo_f(void)
ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_BLEND;
ptype->looks.stretch = 1;
ptype->dl_time = 100;
}
else if (!ptype)
{
@ -1995,12 +2029,12 @@ static void P_ImportEffectInfo_f(void)
if (!strcmp(arg[1], "decal") || !strcmp(arg[1], "cdecal"))
{
ptype->looks.type = PT_CDECAL;
ptype->looks.blendmode = BM_INVMOD;
ptype->looks.blendmode = BM_INVMODC;
}
else if (!strcmp(arg[1], "udecal"))
{
ptype->looks.type = PT_UDECAL;
ptype->looks.blendmode = BM_INVMOD;
ptype->looks.blendmode = BM_INVMODC;
}
else if (!strcmp(arg[1], "alphastatic"))
{
@ -2020,6 +2054,7 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[1], "spark"))
{
ptype->looks.type = PT_TEXTUREDSPARK;
ptype->looks.blendmode = BM_ADD;
}
else if (!strcmp(arg[1], "bubble"))
{
@ -2029,7 +2064,7 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[1], "blood"))
{
ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_INVMOD;
ptype->looks.blendmode = BM_INVMODC;
ptype->gravity = 800*1;
}
else if (!strcmp(arg[1], "beam"))
@ -2142,7 +2177,7 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[0], "blend") && args == 2)
{
if (!strcmp(arg[1], "invmod"))
ptype->looks.blendmode = BM_INVMOD;
ptype->looks.blendmode = BM_INVMODC;
else if (!strcmp(arg[1], "alpha"))
ptype->looks.blendmode = BM_BLEND;
else if (!strcmp(arg[1], "add"))
@ -2152,15 +2187,15 @@ static void P_ImportEffectInfo_f(void)
}
else if (!strcmp(arg[0], "orientation") && args == 2)
{
// if (!strcmp(arg[1], "billboard"))
// ;
// else if (!strcmp(arg[1], "spark"))
// ;
// else if (!strcmp(arg[1], "oriented"))
// ;
// else if (!strcmp(arg[1], "beam"))
// ;
// else
if (!strcmp(arg[1], "billboard"))
ptype->looks.type = PT_NORMAL;
else if (!strcmp(arg[1], "spark"))
ptype->looks.type = PT_TEXTUREDSPARK;
else if (!strcmp(arg[1], "oriented")) //FIXME: not sure this points the right way. also, its double-sided in dp.
ptype->looks.type = PT_UDECAL;
else if (!strcmp(arg[1], "beam"))
ptype->looks.type = PT_BEAM;
else
Con_Printf("effectinfo 'orientation %s' not supported\n", arg[1]);
}
else if (!strcmp(arg[0], "lightradius") && args == 2)

View File

@ -122,10 +122,13 @@ extern sfx_t *cl_sfx_r_exp3;
globalfunction(parse_tempentity, "CSQC_Parse_TempEntity");/*EXT_CSQC_ABSOLUTLY_VILE*/ \
\
/*These are pointers to the csqc's globals.*/ \
globalfloat(svtime, "time"); /*float Written before entering most qc functions*/ \
globalfloat(frametime, "frametime"); /*float Written before entering most qc functions*/ \
globalfloat(gamespeed, "gamespeed"); /*float Written before entering most qc functions*/ \
globalfloat(cltime, "cltime"); /*float Written before entering most qc functions*/ \
globalfloat(simtime, "time"); /*float The simulation(aka: smoothed server) time, speed drifts based upon latency*/ \
globalfloat(frametime, "frametime"); /*float Client render frame interval*/ \
globalfloat(gamespeed, "gamespeed"); /*float Multiplier for real time -> simulation time*/ \
globalfloat(cltime, "cltime"); /*float Clientside map uptime indepent of gamespeed, latency, and the server in general*/ \
globalfloat(netnewtime, "servertime"); /*float Server time of latest inbound network frame*/ \
globalfloat(netoldtime, "serverprevtime"); /*float Server time of previous inbound network frame */ \
globalfloat(netdeltatime, "serverdeltatime"); /*float new-old */ \
globalfloat(physics_mode, "physics_mode"); /*float Written before entering most qc functions*/ \
globalentity(self, "self"); /*entity Written before entering most qc functions*/ \
globalentity(other, "other"); /*entity Written before entering most qc functions*/ \
@ -263,8 +266,8 @@ static void CSQC_FindGlobals(void)
#undef globalstring
#undef globalfunction
if (csqcg.svtime)
*csqcg.svtime = cl.servertime;
if (csqcg.simtime)
*csqcg.simtime = cl.servertime;
if (csqcg.cltime)
*csqcg.cltime = cl.time;
@ -276,7 +279,7 @@ static void CSQC_FindGlobals(void)
csqc_world.g.physics_mode = csqcg.physics_mode;
csqc_world.g.frametime = csqcg.frametime;
csqc_world.g.newmis = (int*)PR_FindGlobal(csqcprogs, "newmis", 0, NULL);
csqc_world.g.time = csqcg.svtime;
csqc_world.g.time = csqcg.simtime;
csqc_world.g.v_forward = csqcg.forward;
csqc_world.g.v_right = csqcg.right;
csqc_world.g.v_up = csqcg.up;
@ -468,8 +471,8 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t
out->g[FST_BASE].lerpfrac = in->xv->baselerpfrac;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->g[FST_BASE].frametime[0] = *csqcg.svtime - in->xv->baseframe1time;
out->g[FST_BASE].frametime[1] = *csqcg.svtime - in->xv->baseframe2time;
out->g[FST_BASE].frametime[0] = *csqcg.simtime - in->xv->baseframe1time;
out->g[FST_BASE].frametime[1] = *csqcg.simtime - in->xv->baseframe2time;
}
else
{
@ -484,8 +487,8 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t
out->g[FS_REG].lerpfrac = in->xv->lerpfrac;
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{
out->g[FS_REG].frametime[0] = *csqcg.svtime - in->xv->frame1time;
out->g[FS_REG].frametime[1] = *csqcg.svtime - in->xv->frame2time;
out->g[FS_REG].frametime[0] = *csqcg.simtime - in->xv->frame1time;
out->g[FS_REG].frametime[1] = *csqcg.simtime - in->xv->frame2time;
}
else
{
@ -969,9 +972,12 @@ static void QCBUILTIN PF_R_AddEntityMask(pubprogfuncs_t *prinst, struct globalva
ent = (void*)EDICT_NUM(prinst, e);
if (ent->isfree)
continue;
WPhys_RunThink (&csqc_world, (wedict_t*)ent);
if (ent->isfree)
continue;
if (ent->v->think)
{
WPhys_RunThink (&csqc_world, (wedict_t*)ent);
if (ent->isfree)
continue;
}
if (ent->xv->predraw)
{
*csqcg.self = EDICT_TO_PROG(prinst, (void*)ent);
@ -1574,15 +1580,19 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
static void QCBUILTIN PF_cs_getstati(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
G_INT(OFS_RETURN) = csqc_playerview->stats[stnum];
if (stnum >= 128)
G_FLOAT(OFS_RETURN) = csqc_playerview->statsf[stnum];
else
G_INT(OFS_RETURN) = csqc_playerview->stats[stnum];
}
static void QCBUILTIN PF_cs_getstatbits(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //convert an int stat into a qc float.
{ //read a numeric stat into a qc float.
//if bits offsets are specified, reads explicitly the integer version of the stat, allowing high bits to be read for items2/serverflags. the float stat should have the same value, just with lower precision as a float can't hold a 32bit value. maybe we should just use doubles.
int stnum = G_FLOAT(OFS_PARM0);
int val = csqc_playerview->stats[stnum];
if (prinst->callargc > 1)
{
int val = csqc_playerview->stats[stnum];
int first, count;
first = G_FLOAT(OFS_PARM1);
if (prinst->callargc > 2)
@ -2080,7 +2090,7 @@ static void QCBUILTIN PF_cs_setsensativityscaler (pubprogfuncs_t *prinst, struct
static void QCBUILTIN PF_cs_pointparticles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int effectnum = G_FLOAT(OFS_PARM0)-1;
int effectnum = G_FLOAT(OFS_PARM0);
float *org = G_VECTOR(OFS_PARM1);
float *vel = G_VECTOR(OFS_PARM2);
float count = G_FLOAT(OFS_PARM3);
@ -2108,7 +2118,7 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
}
else
{
efnum = G_FLOAT(OFS_PARM0)-1;
efnum = G_FLOAT(OFS_PARM0);
ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM1);
}
efnum = CL_TranslateParticleFromServer(efnum);
@ -2119,6 +2129,9 @@ static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globa
pe->ParticleTrail(start, end, efnum, -ent->entnum, &ent->trailstate);
}
//0 for error, non-0 for success.
//>0 match server
//<0 are client-only.
static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i;
@ -2133,7 +2146,7 @@ static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct gl
return;
}
}
//use the server's index first.
//then look for an existing client id
for (i = 1; i < MAX_CSPARTICLESPRE && cl.particle_csname[i]; i++)
{
if (!strcmp(cl.particle_csname[i], effectname))
@ -2149,16 +2162,12 @@ static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct gl
cl.particle_csprecache[i] = 1+P_FindParticleType(effectname);
if (cl.particle_csprecache[i])
cl.particle_csname[i] = strdup(effectname);
G_FLOAT(OFS_RETURN) = -i;
}
if (csqc_isdarkplaces)
{
//keep the effectinfo synced between server and client.
G_FLOAT(OFS_RETURN) = COM_Effectinfo_ForName(effectname);
}
else
{
G_FLOAT(OFS_RETURN) = pe->FindParticleType(effectname)+1;
}
G_FLOAT(OFS_RETURN) = 0;
//if we're using dp network protocols, we should use the effectinfo.txt file as a lookup table instead.
//G_FLOAT(OFS_RETURN) = COM_Effectinfo_ForName(effectname);
}
static void QCBUILTIN PF_cs_particleeffectquery (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -3600,9 +3609,6 @@ static void CS_ConsoleCommand_f(void)
static void QCBUILTIN PF_cs_registercommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *str = PF_VarString(prinst, 0, pr_globals);
if (!strcmp(str, "+showscores") || !strcmp(str, "-showscores") ||
!strcmp(str, "+showteamscores") || !strcmp(str, "-showteamscores"))
return;
if (!Cmd_Exists(str))
Cmd_AddCommand(str, CS_ConsoleCommand_f);
}
@ -4372,6 +4378,7 @@ static struct {
{"pow", PF_pow, 97}, // #97 float(float value) pow (DP_QC_SINCOSSQRTPOW)
{"findfloat", PF_FindFloat, 98}, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT)
{"checkextension", PF_checkextension, 99}, // #99 float(string extname) checkextension (EXT_CSQC)
{"anglemod", PF_anglemod, 102},
//110
{"fopen", PF_fopen, 110}, // #110 float(string strname, float accessmode) fopen (FRIK_FILE)
@ -4965,7 +4972,7 @@ void CSQC_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
*csqcg.self = EDICT_TO_PROG(w->progs, (edict_t*)s);
*csqcg.other = EDICT_TO_PROG(w->progs, (edict_t*)o);
*csqcg.svtime = w->physicstime;
*csqcg.simtime = w->physicstime;
PR_ExecuteProgram (w->progs, s->v->touch);
@ -4977,7 +4984,7 @@ void CSQC_Event_Think(world_t *w, wedict_t *s)
{
*csqcg.self = EDICT_TO_PROG(w->progs, (edict_t*)s);
*csqcg.other = EDICT_TO_PROG(w->progs, (edict_t*)w->edicts);
*csqcg.svtime = w->physicstime;
*csqcg.simtime = w->physicstime;
PR_ExecuteProgram (w->progs, s->v->think);
}
@ -5007,7 +5014,7 @@ qboolean CSQC_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwaterty
{
void *pr_globals = PR_globals(w->progs, PR_CURRENT);
*csqcg.self = EDICT_TO_PROG(w->progs, ent);
*csqcg.svtime = w->physicstime;
*csqcg.simtime = w->physicstime;
G_FLOAT(OFS_PARM0) = oldwatertype;
G_FLOAT(OFS_PARM1) = newwatertype;
PR_ExecuteProgram (w->progs, ent->xv->contentstransition);
@ -5028,10 +5035,9 @@ void CSQC_World_GetFrameState(world_t *w, wedict_t *win, framestate_t *out)
void CSQC_Shutdown(void)
{
extern int mouseusedforgui;
if (csqcprogs)
{
mouseusedforgui = false;
key_dest_absolutemouse &= ~kdm_game;
CSQC_ForgetThreads();
PR_ResetFonts(true);
PR_Common_Shutdown(csqcprogs, false);
@ -5290,6 +5296,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
csqcprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
csqcprogparms.user = &csqc_world;
csqc_world.keydestmask = kdm_game;
csqctime = Sys_DoubleTime();
if (!csqcprogs)
@ -5325,7 +5332,10 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
else
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) >= 0)
{
csqc_isdarkplaces = true;
loaded = true;
}
else if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) >= 0)
loaded = true;
else
@ -5696,7 +5706,11 @@ qboolean CSQC_DrawView(void)
if (csqcg.frametime)
*csqcg.frametime = host_frametime;
if (!csqc_isdarkplaces)
if (csqc_isdarkplaces)
{
csqc_world.physicstime = cl.servertime;
}
else
{
while(1)
{
@ -5762,8 +5776,18 @@ qboolean CSQC_DrawView(void)
if (csqcg.cltime)
*csqcg.cltime = realtime;
if (csqcg.svtime)
*csqcg.svtime = cl.servertime;
if (csqcg.simtime)
*csqcg.simtime = cl.servertime;
if (cl.currentpackentities && cl.previouspackentities)
{
if (csqcg.netnewtime)
*csqcg.netnewtime = cl.currentpackentities->servertime;
if (csqcg.netoldtime)
*csqcg.netoldtime = cl.previouspackentities->servertime;
if (csqcg.netdeltatime)
*csqcg.netdeltatime = cl.currentpackentities->servertime - cl.previouspackentities->servertime;
}
CSQC_RunThreads(); //wake up any qc threads
@ -6064,7 +6088,7 @@ qboolean CSQC_CenterPrint(int lplayernum, char *cmd)
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, cmd));
PR_ExecuteProgram (csqcprogs, csqcg.parse_centerprint);
return G_FLOAT(OFS_RETURN);
return G_FLOAT(OFS_RETURN) || csqc_isdarkplaces;
}
void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd)
@ -6074,8 +6098,8 @@ void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd)
CSQC_ChangeLocalPlayer(lplayernum);
if (csqcg.svtime)
*csqcg.svtime = cl.servertime;
if (csqcg.simtime)
*csqcg.simtime = cl.servertime;
if (csqcg.cltime)
*csqcg.cltime = cl.time;
@ -6168,11 +6192,18 @@ void CSQC_ParseEntities(void)
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
CL_CalcClientTime();
if (csqcg.svtime) //estimated server time
*csqcg.svtime = cl.servertime;
if (csqcg.simtime) //estimated server time
*csqcg.simtime = cl.servertime;
if (csqcg.cltime) //smooth client time.
*csqcg.cltime = cl.time;
if (csqcg.netnewtime)
*csqcg.netnewtime = cl.gametime;
if (csqcg.netoldtime)
*csqcg.netoldtime = cl.oldgametime;
if (csqcg.netdeltatime)
*csqcg.netdeltatime = cl.gametime - cl.oldgametime;
if (csqcg.clientcommandframe)
*csqcg.clientcommandframe = cl.movesequence;
if (csqcg.servercommandframe)

View File

@ -77,17 +77,11 @@ struct {
struct font_s *font[4];
} fontslot[FONT_SLOTS];
static struct font_s *PR_CL_ChooseFont(pubprogfuncs_t *prinst, float szx, float szy)
static struct font_s *PR_CL_ChooseFont(world_t *world, float szx, float szy)
{
int fontidx = 0; //default by default...
world_t *world = prinst->parms->user;
struct font_s *font = font_conchar;
if (world->g.drawfontscale)
{
szx *= world->g.drawfontscale[0];
szy *= world->g.drawfontscale[1];
}
if (world->g.drawfont)
{
fontidx = *world->g.drawfont;
@ -111,8 +105,13 @@ static struct font_s *PR_CL_ChooseFont(pubprogfuncs_t *prinst, float szx, float
}
void PR_CL_BeginString(pubprogfuncs_t *prinst, float vx, float vy, float szx, float szy, float *px, float *py)
{
struct font_s *font = PR_CL_ChooseFont(prinst, szx, szy);
world_t *world = prinst->parms->user;
struct font_s *font = PR_CL_ChooseFont(world, szx, szy);
if (world->g.drawfontscale && (world->g.drawfontscale[0] || world->g.drawfontscale[1]))
{
szx *= world->g.drawfontscale[0];
szy *= world->g.drawfontscale[1];
}
Font_BeginScaledString(font, vx, vy, szx, szy, px, py);
}
int PR_findnamedfont(char *name, qboolean isslotname)
@ -449,7 +448,7 @@ void QCBUILTIN PF_CL_drawcharacter (pubprogfuncs_t *prinst, struct globalvars_s
//float drawrawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
{
float *pos = G_VECTOR(OFS_PARM0);
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
float *size = G_VECTOR(OFS_PARM2);
@ -567,8 +566,10 @@ void QCBUILTIN PF_CL_drawgetimagesize (pubprogfuncs_t *prinst, struct globalvars
void QCBUILTIN PF_cl_getmousepos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *ret = G_VECTOR(OFS_RETURN);
world_t *world = prinst->parms->user;
unsigned int target = world->keydestmask;
if (Key_MouseShouldBeFree())
if (key_dest_absolutemouse & target)
{
ret[0] = mousecursor_x;
ret[1] = mousecursor_y;
@ -656,10 +657,17 @@ void QCBUILTIN PF_SubConDraw (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
float *size = G_VECTOR(OFS_PARM2);
float fontsize = G_FLOAT(OFS_PARM3);
console_t *con = Con_FindConsole(conname);
world_t *world = prinst->parms->user;
if (!con)
return;
Con_DrawOneConsole(con, PR_CL_ChooseFont(prinst, fontsize, fontsize), pos[0], pos[1], size[0], size[1]);
if (world->g.drawfontscale)
{
// szx *= world->g.drawfontscale[0];
fontsize *= world->g.drawfontscale[1];
}
Con_DrawOneConsole(con, PR_CL_ChooseFont(world, fontsize, fontsize), pos[0], pos[1], size[0], size[1]);
}
qboolean Key_Console (console_t *con, unsigned int unicode, int key);
void Key_ConsoleRelease (console_t *con, unsigned int unicode, int key);
@ -690,7 +698,7 @@ void QCBUILTIN PF_SubConInput (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
break;
case CSIE_MOUSEABS:
//x, y
if (con == con_current && key_dest == key_console)
if (con == con_current && (key_dest_mask & kdm_console))
break; //no interfering with the main console!
con->mousecursor[0] = pa;
con->mousecursor[1] = pb;
@ -932,16 +940,21 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
{
case 0:
// key_game
key_dest = ((cls.state == ca_active)?key_game:key_console);
if (!(cls.state == ca_active))
Key_Dest_Add(kdm_console);
Key_Dest_Remove(kdm_menu);
Key_Dest_Remove(kdm_message);
break;
case 2:
// key_menu
key_dest = key_menu;
m_state = m_menu_dat;
Key_Dest_Remove(kdm_message);
Key_Dest_Add(kdm_menu);
break;
case 1:
// key_message
// key_dest = key_message
//Key_Dest_Remove(kdm_menu);
//Key_Dest_Add(kdm_message);
// break;
default:
PR_BIError (prinst, "PF_setkeydest: wrong destination %i !\n",(int)G_FLOAT(OFS_PARM0));
@ -950,37 +963,31 @@ void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr
//float getkeydest(void) = #602;
void QCBUILTIN PF_cl_getkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
switch(key_dest)
if (Key_Dest_Has(kdm_menu))
{
case key_game:
G_FLOAT(OFS_RETURN) = 0;
break;
case key_menu:
if (m_state == m_menu_dat)
G_FLOAT(OFS_RETURN) = 2;
else
G_FLOAT(OFS_RETURN) = 3;
break;
case 1:
// key_message
// key_dest = key_message
// break;
default:
G_FLOAT(OFS_RETURN) = 3;
}
// else if (Key_Dest_Has(kdm_message))
// G_FLOAT(OFS_RETURN) = 1;
else
G_FLOAT(OFS_RETURN) = 0;
}
//void setmousetarget(float trg) = #603;
void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern int mouseusedforgui;
world_t *world = prinst->parms->user;
unsigned int target = world->keydestmask;
switch ((int)G_FLOAT(OFS_PARM0))
{
case 1: //1 is delta-based.
mouseusedforgui = false;
case 1: //1 is delta-based (mt_menu).
key_dest_absolutemouse &= ~target;
break;
case 2: //2 is absolute.
mouseusedforgui = true;
case 2: //2 is absolute (mt_client).
key_dest_absolutemouse |= target;
break;
default:
PR_BIError(prinst, "PF_setmousetarget: not a valid destination\n");
@ -990,8 +997,9 @@ void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s
//float getmousetarget(void) = #604;
void QCBUILTIN PF_cl_getmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern int mouseusedforgui;
G_FLOAT(OFS_RETURN) = mouseusedforgui?2:1;
world_t *world = prinst->parms->user;
unsigned int target = world->keydestmask;
G_FLOAT(OFS_RETURN) = (key_dest_absolutemouse&target)?2:1;
}
static void QCBUILTIN PF_Remove_ (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -1655,7 +1663,6 @@ jmp_buf mp_abort;
void MP_Shutdown (void)
{
extern int mouseusedforgui;
func_t temp;
if (!menu_world.progs)
return;
@ -1683,10 +1690,10 @@ void MP_Shutdown (void)
Master_ClearMasks();
#endif
key_dest = key_game;
Key_Dest_Remove(kdm_menu);
m_state = 0;
mouseusedforgui = false;
key_dest_absolutemouse &= ~kdm_menu;
}
void *VARGS PR_CB_Malloc(int size); //these functions should be tracked by the library reliably, so there should be no need to track them ourselves.
@ -1787,6 +1794,7 @@ qboolean MP_Init (void)
menuprogparms.useeditor = NULL;//sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
menuprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
menuprogparms.user = &menu_world;
menu_world.keydestmask = kdm_menu;
menutime = Sys_DoubleTime();
if (!menu_world.progs)

View File

@ -492,8 +492,6 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque)
{
float a;
int w, h;
if (!conback)
return;
w = vid.width;
h = vid.height;
@ -515,7 +513,13 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque)
h>>=1;
w>>=1;
}
if (a >= 1)
if (!conback)
{
R2D_ImageColours(0, 0, 0, a);
R2D_FillBlock(0, lastline-(int)vid.height, w, h);
R2D_ImageColours(1, 1, 1, 1);
}
else if (a >= 1)
{
R2D_ImageColours(1, 1, 1, 1);
R2D_ScalePic(0, lastline-(int)vid.height, w, h, conback);
@ -579,7 +583,7 @@ void R2D_TileClear (float x, float y, float w, float h)
void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
{
if (qrenderer == QR_NONE)
if (qrenderer == QR_NONE || !strcmp(var->string, "none"))
{
conback = NULL;
return;

View File

@ -92,6 +92,9 @@ void R_ParticleSystem_Callback(struct cvar_s *var, char *oldvalue)
{
CL_ClearTEntParticleState();
CL_ClearLerpEntsParticleState();
#ifdef Q2CLIENT
CLQ2_ClearParticleState();
#endif
pe->ShutdownParticles();
}

View File

@ -630,7 +630,7 @@ static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest)
{
deluxmap = surf->samples - currentmodel->lightdata + currentmodel->deluxdata;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -649,7 +649,7 @@ static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest)
{
deluxmap = (surf->samples - currentmodel->lightdata)*3 + currentmodel->deluxdata;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -911,7 +911,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
blocklights[i] = t;
}
for (maps = 0 ; maps < MAXLIGHTMAPS ; maps++)
for (maps = 0 ; maps < MAXQ1LIGHTMAPS ; maps++)
{
surf->cached_light[maps] = -1-ambient;
surf->cached_colour[maps] = 0xff;
@ -978,7 +978,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
else if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb
{
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -1014,7 +1014,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
}
else
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -1116,7 +1116,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
if (lightmap)
{
if (currentmodel->engineflags & MDLF_RGBLIGHTING) //rgb
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/3;
@ -1128,7 +1128,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
else
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -1185,7 +1185,7 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
}
else
{
for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && fa->styles[maps] != 255 ;
maps++)
if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps]
|| cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps])
@ -1930,20 +1930,25 @@ void Surf_SetupFrame(void)
static mleaf_t fakeleaf;
mleaf_t *leaf;
r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps.
//FIXME: do we still need this fakeleaf stuff?
r_viewleaf = &fakeleaf;
r_viewleaf->contents = Q1CONTENTS_EMPTY;
r_viewleaf2 = NULL;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_refdef.recurse)
{
leaf = Mod_PointInLeaf (cl.worldmodel, r_refdef.pvsorigin);
r_viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, r_refdef.pvsorigin);
}
else
{
leaf = Mod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, r_origin);
}
r_viewcluster = r_viewcluster2 = leaf->cluster;
r_viewcontents = leaf->contents & (FTECONTENTS_LAVA|FTECONTENTS_SLIME|FTECONTENTS_WATER);
// check above and below so crossing solid water doesn't draw wrong
if (!leaf->contents)
{ // look down a bit
@ -2489,10 +2494,14 @@ int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe)
int first = numlightmaps;
int i;
char nname[MAX_QPATH];
qboolean odd = (count & 1) && deluxe;
if (!count)
return -1;
if (odd)
count++;
i = numlightmaps + count;
lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(i));
while(i > first)
@ -2516,6 +2525,17 @@ int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe)
lightmap[i]->height = image_height;
}
if (odd)
{
i = numlightmaps+count-1;
if (!TEXVALID(lightmap[i]->lightmap_texture))
{ //FIXME: no deluxemaps after all...
Z_Free(lightmap[i]);
lightmap[i] = NULL;
count--;
}
}
numlightmaps += count;
return first;
@ -2560,6 +2580,7 @@ void Surf_BuildModelLightmaps (model_t *m)
COM_StripAllExtensions(m->name, pattern, sizeof(pattern));
Q_strncatz(pattern, "/lm_%04u.tga", sizeof(pattern));
newfirst = Surf_NewExternalLightmaps(m->lightmaps.count, pattern, m->lightmaps.deluxemapping);
m->lightmaps.count = numlightmaps - newfirst;
}
else
newfirst = Surf_NewLightmaps(m->lightmaps.count, m->lightmaps.width, m->lightmaps.height, m->lightmaps.deluxemapping);
@ -2569,7 +2590,7 @@ void Surf_BuildModelLightmaps (model_t *m)
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
for (i = 0; i < MAXLIGHTMAPS; i++)
for (i = 0; i < MAXRLIGHTMAPS; i++)
{
if (batch->lightmap[i] < 0)
continue;
@ -2648,7 +2669,7 @@ void Surf_BuildModelLightmaps (model_t *m)
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
for (j = 0; j < 4; j++)
for (j = 0; j < MAXRLIGHTMAPS; j++)
{
if (surf->lightmaptexturenums[j] < m->lightmaps.first)
{

View File

@ -170,7 +170,7 @@ typedef struct
qboolean externalview; /*draw external models and not viewmodels*/
qboolean recurse; /*in a mirror/portal/half way through drawing something else*/
qboolean forcevis; /*if true, vis comes from the forcedvis field instead of recalculated*/
qboolean flipcull; /*reflected/flipped view, requires inverted culling*/
unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/
qboolean useperspective; /*not orthographic*/
int postprocshader; /*if set, renders to texture then invokes this shader*/
@ -186,7 +186,7 @@ extern struct texture_s *r_notexture_mip;
extern entity_t r_worldentity;
void BE_GenModelBatches(struct batch_s **batches);
void BE_GenModelBatches(struct batch_s **batches, const struct dlight_s *dl, unsigned int bemode); //if dl, filters based upon the dlight.
//gl_alias.c
void GL_GAliasFlushSkinCache(void);
@ -502,10 +502,17 @@ enum {
RQUANT_ENTBATCHES,
RQUANT_WORLDBATCHES,
RQUANT_2DBATCHES,
RQUANT_SHADOWFACES,
RQUANT_SHADOWEDGES,
RQUANT_SHADOWSIDES,
RQUANT_LITFACES,
RQUANT_RTLIGHT_DRAWN,
RQUANT_RTLIGHT_CULL_FRUSTUM,
RQUANT_RTLIGHT_CULL_PVS,
RQUANT_RTLIGHT_CULL_SCISSOR,
RQUANT_MAX
};
extern int rquant[RQUANT_MAX];

View File

@ -345,25 +345,6 @@ cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04
cvar_t r_glsl_offsetmapping_reliefmapping = CVARF("r_glsl_offsetmapping_reliefmapping", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
cvar_t r_glsl_turbscale = CVARF ("r_glsl_turbscale", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
#ifdef FTE_TARGET_WEB
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE);
#else
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
#endif
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_ambient = SCVAR ("r_shadow_realtime_dlight_ambient", "0");
cvar_t r_shadow_realtime_dlight_diffuse = SCVAR ("r_shadow_realtime_dlight_diffuse", "1");
cvar_t r_shadow_realtime_dlight_specular = SCVAR ("r_shadow_realtime_dlight_specular", "4"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_editlights_import_radius = SCVAR ("r_editlights_import_radius", "1");
cvar_t r_editlights_import_ambient = SCVAR ("r_editlights_import_ambient", "0");
cvar_t r_editlights_import_diffuse = SCVAR ("r_editlights_import_diffuse", "1");
cvar_t r_editlights_import_specular = SCVAR ("r_editlights_import_specular", "1"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0);
cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8");
cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE);
cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections");
cvar_t r_slimestyle = CVARFD ("r_slimestyle", "", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only slime. If empty, defers to r_waterstyle.");
cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava. If empty, defers to r_waterstyle.");
@ -630,17 +611,8 @@ void Renderer_Init(void)
Cvar_Register (&r_flashblend, GRAPHICALNICETIES);
Cvar_Register (&r_flashblendscale, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_world, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_world_shadows, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight_ambient, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight_diffuse, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight_specular, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight_shadows, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_world_lightmaps, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_shadowmapping, GRAPHICALNICETIES);
Cvar_Register (&r_sun_dir, GRAPHICALNICETIES);
Cvar_Register (&r_sun_colour, GRAPHICALNICETIES);
Sh_RegisterCvars();
Cvar_Register (&r_waterstyle, GRAPHICALNICETIES);
Cvar_Register (&r_lavastyle, GRAPHICALNICETIES);
Cvar_Register (&r_wireframe, GRAPHICALNICETIES);
@ -1226,6 +1198,7 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
cl.worldmodel = NULL;
CL_ClearEntityLists(); //shouldn't really be needed, but we're paranoid
//FIXME: this code should not be here. call CL_LoadModels instead? that does csqc loading etc though. :s
TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
for (i=1 ; i<MAX_MODELS ; i++)
{
@ -1234,7 +1207,13 @@ TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n"));
cl.model_precache[i] = NULL;
TRACE(("dbg: R_ApplyRenderer: reloading model %s\n", cl.model_name[i]));
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
#ifdef Q2CLIENT //skip vweps
if (cls.protocol == CP_QUAKE2 && *cl.model_name[i] == '#')
cl.model_precache[i] = NULL;
else
#endif
cl.model_precache[i] = Mod_ForName (cl.model_name[i], false);
if (!cl.model_precache[i] && i == 1)
{

View File

@ -383,6 +383,8 @@ int i;
}
if(ri->buf != NULL)
BZ_Free(ri->buf);
if (ri->audio)
BZ_Free(ri->audio);
BZ_Free(ri);
}

View File

@ -1851,6 +1851,9 @@ void Sbar_DrawScoreboard (void)
if (cls.protocol == CP_QUAKE2)
return;
if (Key_Dest_Has(~kdm_game))
return;
#ifndef CLIENTONLY
/*no scoreboard in single player (if you want bots, set deathmatch)*/
if (sv.state && !cls.deathmatch && sv.allocated_client_slots == 1)

View File

@ -152,7 +152,7 @@ void Sys_Quit (void)
//SDL provides no file enumeration facilities.
#if defined(_WIN32)
#include <windows.h>
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, void *), void *parm, void *spath)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{
HANDLE r;
WIN32_FIND_DATA fd;
@ -452,17 +452,11 @@ int QDECL main(int argc, char **argv)
{
float time, newtime, oldtime;
quakeparms_t parms;
int t;
int delay = 1;
memset(&parms, 0, sizeof(parms));
#ifdef FTE_TARGET_WEB
parms.basedir = "";
#else
parms.basedir = ".";
#endif
parms.argc = argc;
parms.argv = (const char**)argv;
@ -480,11 +474,6 @@ int QDECL main(int argc, char **argv)
oldtime = Sys_DoubleTime ();
#ifdef FTE_TARGET_WEB
//-1 fps should give vsync
emscripten_set_main_loop(Sys_MainLoop, -1, false);
#else
//client console should now be initialized.
/* main window message loop */
@ -519,7 +508,7 @@ int QDECL main(int argc, char **argv)
Sys_Sleep(sleeptime);
}
}
#endif
return 0;
}
@ -702,44 +691,4 @@ void Sys_Sleep (double seconds)
SDL_Delay(seconds * 1000);
}
#ifdef FTE_TARGET_WEB
//emscripten does not support the full set of sdl functions, so we stub the extras.
int SDL_GetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable)
{
return -1;
}
int SDL_SetGammaRamp(const Uint16 *redtable, const Uint16 *greentable, const Uint16 *bluetable)
{
return -1;
}
//SDL_GL_GetAttribute
void SDL_UnloadObject(void *object)
{
}
void *SDL_LoadObject(const char *sofile)
{
return NULL;
}
void *SDL_LoadFunction(void *handle, const char *name)
{
return NULL;
}
Uint8 SDL_GetAppState(void)
{
return SDL_APPACTIVE;
}
#define socklen_t int
int getsockname(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
int getpeername(int socket, struct sockaddr *address, socklen_t *address_len)
{
return -1;
}
ssize_t sendto(int socket, const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
{
return -1;
}
#endif

View File

@ -40,8 +40,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PRINTGLARRAYS
#endif
#ifdef _DEBUG
#if _MSC_VER >= 1300
#if defined(_DEBUG) || defined(DEBUG)
#if 1//_MSC_VER >= 1300
#define CATCHCRASH
#endif
#endif
@ -273,6 +273,34 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
MINIDUMPWRITEDUMP fnMiniDumpWriteDump;
HMODULE hKernel;
BOOL (WINAPI *pIsDebuggerPresent)(void);
DWORD (WINAPI *pSymSetOptions)(DWORD SymOptions);
BOOL (WINAPI *pSymInitialize)(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess);
BOOL (WINAPI *pSymFromAddr)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol);
#ifdef _WIN64
#define DBGHELP_POSTFIX "64"
BOOL (WINAPI *pStackWalkX)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
PVOID (WINAPI *pSymFunctionTableAccessX)(HANDLE hProcess, DWORD64 AddrBase);
DWORD64 (WINAPI *pSymGetModuleBaseX)(HANDLE hProcess, DWORD64 qwAddr);
BOOL (WINAPI *pSymGetLineFromAddrX)(HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64);
#else
#define DBGHELP_POSTFIX ""
BOOL (WINAPI *pStackWalkX)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
PVOID (WINAPI *pSymFunctionTableAccessX)(HANDLE hProcess, DWORD AddrBase);
DWORD (WINAPI *pSymGetModuleBaseX)(HANDLE hProcess, DWORD dwAddr);
BOOL (WINAPI *pSymGetLineFromAddrX)(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line);
#endif
dllfunction_t debughelpfuncs[] =
{
{(void*)&pSymFromAddr, "SymFromAddr"},
{(void*)&pSymSetOptions, "SymSetOptions"},
{(void*)&pSymInitialize, "SymInitialize"},
{(void*)&pStackWalkX, "StackWalk"DBGHELP_POSTFIX},
{(void*)&pSymFunctionTableAccessX, "SymFunctionTableAccess"DBGHELP_POSTFIX},
{(void*)&pSymGetModuleBaseX, "SymGetModuleBase"DBGHELP_POSTFIX},
{(void*)&pSymGetLineFromAddrX, "SymGetLineFromAddr"DBGHELP_POSTFIX},
{NULL, NULL}
};
#ifdef PRINTGLARRAYS
if (!iswatchdog && qrenderer == QR_OPENGL)
@ -303,8 +331,123 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
{
}
else
{
DestroyWindow(mainwindow);
if (Sys_LoadLibrary("DBGHELP", debughelpfuncs))
{
STACKFRAME stack;
CONTEXT *pcontext = exceptionInfo->ContextRecord;
IMAGEHLP_LINE line;
struct
{
SYMBOL_INFO sym;
char name[1024];
} sym;
int frameno;
char stacklog[8192];
int logpos, logstart;
char *logline;
stacklog[logpos=0] = 0;
pSymInitialize(hProc, NULL, TRUE);
pSymSetOptions(SYMOPT_LOAD_LINES);
memset(&stack, 0, sizeof(stack));
#ifdef _WIN64
#define IMAGE_FILE_MACHINE_THIS IMAGE_FILE_MACHINE_AMD64
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrPC.Offset = pcontext->Rip;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrFrame.Offset = pcontext->Rbp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrStack.Offset = pcontext->Rsp;
#else
#define IMAGE_FILE_MACHINE_THIS IMAGE_FILE_MACHINE_I386
stack.AddrPC.Mode = AddrModeFlat;
stack.AddrPC.Offset = pcontext->Eip;
stack.AddrFrame.Mode = AddrModeFlat;
stack.AddrFrame.Offset = pcontext->Ebp;
stack.AddrStack.Mode = AddrModeFlat;
stack.AddrStack.Offset = pcontext->Esp;
#endif
Q_strncpyz(stacklog+logpos, FULLENGINENAME " has crashed. The following stack dump been copied to your windows clipboard.\n"
#ifdef _MSC_VER
"Would you like to generate a core dump too?\n"
#endif
"\n", sizeof(stacklog)-logpos);
logstart = logpos += strlen(stacklog+logpos);
//so I know which one it is
#if defined(DEBUG) || defined(_DEBUG)
#define BUILDDEBUGREL "Debug"
#else
#define BUILDDEBUGREL "Optimised"
#endif
#ifdef MINIMAL
#define BUILDMINIMAL "Min"
#else
#define BUILDMINIMAL ""
#endif
#if defined(GLQUAKE) && !defined(D3DQUAKE)
#define BUILDTYPE "GL"
#elif !defined(GLQUAKE) && defined(D3DQUAKE)
#define BUILDTYPE "D3D"
#else
#define BUILDTYPE "Merged"
#endif
Q_snprintfz(stacklog+logpos, sizeof(stacklog)-logpos, "Build: %s %s %s: %s\r\n", BUILDDEBUGREL, PLATFORM, BUILDMINIMAL BUILDTYPE, version_string());
logpos += strlen(stacklog+logpos);
for(frameno = 0; ; frameno++)
{
DWORD64 symdisp;
DWORD linedisp;
DWORD_PTR symaddr;
if (!pStackWalkX(IMAGE_FILE_MACHINE_THIS, hProc, GetCurrentThread(), &stack, pcontext, NULL, pSymFunctionTableAccessX, pSymGetModuleBaseX, NULL))
break;
memset(&line, 0, sizeof(line));
line.SizeOfStruct = sizeof(line);
symdisp = 0;
memset(&sym, 0, sizeof(sym));
sym.sym.MaxNameLen = sizeof(sym.name);
symaddr = stack.AddrPC.Offset;
sym.sym.SizeOfStruct = sizeof(sym.sym);
if (pSymFromAddr(hProc, symaddr, &symdisp, &sym.sym))
{
if (pSymGetLineFromAddrX(hProc, stack.AddrPC.Offset, &linedisp, &line))
logline = va("%-20s - %s:%i\r\n", sym.sym.Name, line.FileName, line.LineNumber);
else
logline = va("%-20s+%#x\r\n", sym.sym.Name, (unsigned int)symdisp);
}
else
logline = va("0x%p\r\n", (void*)(DWORD_PTR)stack.AddrPC.Offset);
Q_strncpyz(stacklog+logpos, logline, sizeof(stacklog)-logpos);
logpos += strlen(stacklog+logpos);
if (logpos+1 >= sizeof(stacklog))
break;
}
Sys_SaveClipboard(stacklog+logstart);
#ifdef _MSC_VER
if (MessageBox(0, stacklog, "KABOOM!", MB_ICONSTOP|MB_YESNO) != IDYES)
return EXCEPTION_EXECUTE_HANDLER;
#else
MessageBox(0, stacklog, "KABOOM!", MB_ICONSTOP);
return EXCEPTION_EXECUTE_HANDLER;
#endif
}
else
{
if (MessageBox(NULL, "KABOOM! We crashed!\nBlame the monkey in the corner.\nI hope you saved your work.\nWould you like to take a dump now?", DISTRIBUTION " Sucks", MB_ICONSTOP|MB_YESNO) != IDYES)
return EXCEPTION_EXECUTE_HANDLER;
}
}
//generate a minidump, but only if we were compiled by something that used usable debugging info. its a bit pointless otherwise.
#ifdef _MSC_VER
hDbgHelp = LoadLibrary ("DBGHELP");
if (hDbgHelp)
fnMiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress (hDbgHelp, "MiniDumpWriteDump");
@ -325,14 +468,14 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
return EXCEPTION_EXECUTE_HANDLER;
}
}
else
{
if (MessageBox(NULL, "KABOOM! We crashed!\nBlame the monkey in the corner.\nI hope you saved your work.\nWould you like to take a dump now?", DISTRIBUTION " Sucks", MB_ICONSTOP|MB_YESNO) != IDYES)
return EXCEPTION_EXECUTE_HANDLER;
}
/*take a dump*/
GetTempPath (sizeof(dumpPath)-16, dumpPath);
if (*com_homedir)
Q_strncpyz(dumpPath, com_homedir, sizeof(dumpPath));
else if (*com_quakedir)
Q_strncpyz(dumpPath, com_quakedir, sizeof(dumpPath));
else
GetTempPath (sizeof(dumpPath)-16, dumpPath);
Q_strncatz(dumpPath, DISTRIBUTION"CrashDump.dmp", sizeof(dumpPath));
dumpfile = CreateFile (dumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (dumpfile)
@ -344,7 +487,7 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
if (fnMiniDumpWriteDump(hProc, procid, dumpfile, MiniDumpWithIndirectlyReferencedMemory|MiniDumpWithDataSegs, &crashinfo, NULL, NULL))
{
CloseHandle(dumpfile);
Q_snprintfz(msg, sizeof(msg), "You can find the crashdump at\n%s\nPlease send this file to someone.\n\nWarning: sensitive information (like your current user name) might be present in the dump.\nYou will probably want to compress it.", dumpPath);
Q_snprintfz(msg, sizeof(msg), "You can find the crashdump at:\n%s\nPlease send this file to someone.\n\nWarning: sensitive information (like your current user name) might be present in the dump.\nYou will probably want to compress it.", dumpPath);
MessageBox(NULL, msg, DISTRIBUTION " Sucks", 0);
}
else
@ -358,16 +501,31 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
}
else
MessageBox(NULL, "Kaboom! Sorry. No MiniDumpWriteDump function.", DISTRIBUTION " Sucks", 0);
#endif
return EXCEPTION_EXECUTE_HANDLER;
}
//most compilers do not support __try. perhaps we should avoid its use entirely?
LONG CALLBACK nonmsvc_CrashExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
DWORD foo = CrashExceptionHandler(false, ExceptionInfo->ExceptionRecord->ExceptionCode, ExceptionInfo);
//we have no handler. thus we handle it by exiting.
if (foo == EXCEPTION_EXECUTE_HANDLER)
exit(1);
return foo;
}
volatile int watchdogframe; //incremented each frame.
int watchdogthread(void *arg)
{
#ifdef _MSC_VER
int oldframe = watchdogframe;
int newframe;
int secs = 0;
while(1)
{
{
newframe = watchdogframe;
if (oldframe != newframe)
{
@ -391,6 +549,7 @@ int watchdogthread(void *arg)
}
Sleep(1000);
}
#endif
return 0;
}
#endif
@ -818,39 +977,6 @@ void VARGS Sys_Error (const char *error, ...)
exit (1);
}
static wchar_t dequake(conchar_t chr)
{
chr &= CON_CHARMASK;
/*only this range are quake chars*/
if (chr >= 0xe000 && chr < 0xe100)
{
chr &= 0xff;
if (chr >= 146 && chr < 156)
chr = chr - 146 + '0';
if (chr >= 0x12 && chr <= 0x1b)
chr = chr - 0x12 + '0';
if (chr == 143)
chr = '.';
if (chr == 128 || chr == 129 || chr == 130 || chr == 157 || chr == 158 || chr == 159)
chr = '-';
if (chr >= 128)
chr -= 128;
if (chr == 16)
chr = '[';
if (chr == 17)
chr = ']';
if (chr == 0x1c)
chr = 249;
}
/*this range contains pictograms*/
if (chr >= 0xe100 && chr < 0xe200)
{
chr = '?';
}
return chr;
}
void VARGS Sys_Printf (char *fmt, ...)
{
va_list argptr;
@ -876,7 +1002,7 @@ void VARGS Sys_Printf (char *fmt, ...)
{
if (!(*in & CON_HIDDEN))
{
*out++ = dequake(*in & CON_CHARMASK);
*out++ = COM_DeQuake(*in & CON_CHARMASK);
wlen++;
}
}
@ -992,49 +1118,66 @@ HANDLE clipboardhandle;
char *cliputf8;
char *Sys_GetClipboard(void)
{
char *clipText;
unsigned short *clipWText;
if (OpenClipboard(NULL))
{
//windows programs interpret CF_TEXT as ansi (aka: gibberish)
//so grab utf-16 text and convert it to utf-8 if our console parsing is set to accept that.
if (com_parseutf8.ival > 0)
clipboardhandle = GetClipboardData(CF_UNICODETEXT);
if (clipboardhandle)
{
clipboardhandle = GetClipboardData(CF_UNICODETEXT);
if (clipboardhandle)
unsigned short *clipWText = GlobalLock(clipboardhandle);
if (clipWText)
{
clipWText = GlobalLock(clipboardhandle);
if (clipWText)
unsigned int l, c;
char *utf8;
for (l = 0; clipWText[l]; l++)
;
l = l*4 + 1;
utf8 = cliputf8 = malloc(l);
while(*clipWText)
{
unsigned int l, c;
for (l = 0; clipWText[l]; l++)
;
l = l*4 + 1;
clipText = cliputf8 = malloc(l);
while(*clipWText)
{
c = utf8_encode(clipText, *clipWText++, l);
if (!c)
break;
l -= c;
clipText += c;
}
*clipText = 0;
return cliputf8;
if (clipWText[0] == '\r' && clipWText[1] == '\n') //bloomin microsoft.
clipWText++;
c = utf8_encode(utf8, *clipWText++, l);
if (!c)
break;
l -= c;
utf8 += c;
}
//failed at the last hurdle
GlobalUnlock(clipboardhandle);
*utf8 = 0;
return cliputf8;
}
//failed at the last hurdle
GlobalUnlock(clipboardhandle);
}
clipboardhandle = GetClipboardData(CF_TEXT);
if (clipboardhandle)
{
clipText = GlobalLock(clipboardhandle);
char *clipText = GlobalLock(clipboardhandle);
if (clipText)
return clipText;
{
unsigned int l, c;
char *utf8;
for (l = 0; clipText[l]; l++)
;
l = l*4 + 1;
utf8 = cliputf8 = malloc(l);
while(*clipText)
{
if (clipText[0] == '\r' && clipText[1] == '\n') //bloomin microsoft.
clipText++;
c = utf8_encode(utf8, *clipText++, l);
if (!c)
break;
l -= c;
utf8 += c;
}
*utf8 = 0;
return cliputf8;
}
//failed at the last hurdle
@ -1067,13 +1210,6 @@ void Sys_SaveClipboard(char *text)
return;
EmptyClipboard();
glob = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
if (glob == NULL)
{
CloseClipboard();
return;
}
if (com_parseutf8.ival > 0)
{
glob = GlobalAlloc(GMEM_MOVEABLE, (strlen(text) + 1)*2);
@ -1085,6 +1221,7 @@ void Sys_SaveClipboard(char *text)
int error;
while(*text)
{
//NOTE: should be \r\n and not just \n
*tempw++ = utf8_decode(&error, text, &text);
}
*tempw = 0;
@ -1097,16 +1234,27 @@ void Sys_SaveClipboard(char *text)
}
else
{
//yes, quake chars will get mangled horribly.
temp = GlobalLock(glob);
if (temp != NULL)
glob = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
if (glob)
{
strcpy(temp, text);
GlobalUnlock(glob);
SetClipboardData(CF_TEXT, glob);
//yes, quake chars will get mangled horribly.
temp = GlobalLock(glob);
if (temp != NULL)
{
int error;
while (*text)
{
//NOTE: should be \r\n and not just \n
*temp++ = utf8_decode(&error, text, &text);
}
*temp = 0;
strcpy(temp, text);
GlobalUnlock(glob);
SetClipboardData(CF_TEXT, glob);
}
else
GlobalFree(glob);
}
else
GlobalFree(glob);
}
CloseClipboard();
@ -2290,7 +2438,11 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
#endif
#ifdef CATCHCRASH
#ifdef _MSC_VER
__try
#else
AddVectoredExceptionHandler(true, nonmsvc_CrashExceptionHandler);
#endif
#endif
{
/*
@ -2565,7 +2717,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
SetHookState(ActiveApp);
/*sleep if its not yet time for a frame*/
Sys_Sleep(sleeptime);
if (sleeptime)
Sys_Sleep(sleeptime);
#else
Sys_Error("wut?");
#endif
@ -2573,10 +2726,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
}
}
#ifdef CATCHCRASH
#ifdef _MSC_VER
__except (CrashExceptionHandler(false, GetExceptionCode(), GetExceptionInformation()))
{
return 1;
}
#endif
#endif
/* return success of application */

View File

@ -84,7 +84,6 @@ static char OpenEditorFile[256];
qboolean editoractive; //(export)
keydest_t editor_oldkeydest = key_game;
qboolean editormodal; //doesn't return. (export)
static qboolean madechanges;
static qboolean editenabled;
@ -189,10 +188,7 @@ static void CloseEditor(void)
{
fileblock_t *b;
if (key_dest == key_editor)
key_dest = editor_oldkeydest;
if (key_dest == key_editor)
key_dest = key_game;
Key_Dest_Remove(kdm_editor);
editoractive = false;
editprogfuncs = NULL;
cursorblock = NULL;
@ -213,7 +209,7 @@ static void CloseEditor(void)
firstblock = NULL;
executionlinenum = -1;
executionlinenum = 0;
}
static qboolean EditorSaveFile(char *s) //returns true if succesful
@ -257,7 +253,7 @@ static qboolean EditorSaveFile(char *s) //returns true if succesful
madechanges = false;
editenabled = true;
executionlinenum = -1;
executionlinenum = 0;
return true;
}
@ -284,10 +280,9 @@ static void EditorNewFile(void)
viewportystartblock = NULL;
madechanges = true;
executionlinenum = -1;
executionlinenum = 0;
editor_oldkeydest = key_dest;
key_dest = key_editor;
Key_Dest_Add(kdm_editor);
editoractive = true;
editenabled = true;
}
@ -312,7 +307,7 @@ static void EditorOpenFile(char *name, qboolean readonly)
{
Con_Printf("Couldn't open file \"%s\"\nA new file will be created\n", name);
strcpy(OpenEditorFile, name);
key_dest = key_console;
Key_Dest_Add(kdm_console);
EditorNewFile();
return;
}
@ -393,11 +388,10 @@ static void EditorOpenFile(char *name, qboolean readonly)
viewportystartblock = NULL;
madechanges = false;
executionlinenum = -1;
executionlinenum = 0;
editenabled = !readonly;
editor_oldkeydest = key_dest;
key_dest = key_editor;
Key_Dest_Add(kdm_editor);
editoractive = true;
editprogfuncs = epf;
}
@ -410,7 +404,7 @@ void Editor_Key(int key, int unicode)
if (keybindings[key][0])
if (!strcmp(keybindings[key][0], "toggleconsole"))
{
key_dest = key_console;
Key_Dest_Add(kdm_console);
return;
}
@ -515,6 +509,8 @@ void Editor_Key(int key, int unicode)
case K_MWHEELUP:
case K_UPARROW:
case K_PGUP:
if (!cursorblock)
break;
GetCursorpos();
{
int a;
@ -686,9 +682,15 @@ void Editor_Key(int key, int unicode)
break;
// case K_STOP:
case K_ESCAPE:
if (editprogfuncs)
if (editprogfuncs && editormodal)
{
editprogfuncs->AbortStack(editprogfuncs);
CloseEditor();
CloseEditor();
executionlinenum = 0;
stepasm = true;
}
else
CloseEditor();
editormodal = false;
break;
@ -1092,16 +1094,6 @@ void Editor_Draw(void)
int c;
fileblock_t *b;
if (key_dest != key_console)
{
if (editor_oldkeydest == key_menu && !editormodal)
{
CloseEditor();
return;
}
key_dest = key_editor;
}
if ((editoractive && cls.state == ca_disconnected) || editormodal)
R2D_EditorBackground();
@ -1301,7 +1293,6 @@ int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement,
if (!parms)
{
int oldkeydest = key_dest;
double oldrealtime = realtime;
editormodal = true;
@ -1319,8 +1310,6 @@ int QCLibEditor(pubprogfuncs_t *prfncs, char *filename, int line, int statement,
}
realtime = oldrealtime;
if (oldkeydest != key_console)
key_dest = oldkeydest;
editormodal = false;
}

View File

@ -72,31 +72,21 @@ static void Validation_Version(void)
extern cvar_t r_shadow_realtime_world, r_drawflat;
switch(qrenderer)
{
#ifdef GLQUAKE
case QR_OPENGL:
s = sr;
//print certain allowed 'cheat' options.
//realtime lighting (shadows can show around corners)
//drawflat is just lame
//24bits can be considered eeeevil, by some.
if (r_shadow_realtime_world.ival)
*s++ = 'W';
else if (r_shadow_realtime_dlight.ival)
*s++ = 'S';
if (r_drawflat.ival)
*s++ = 'F';
if (gl_load24bit.ival)
*s++ = 'H';
*s = *"";
break;
s = sr;
//print certain allowed 'cheat' options.
//realtime lighting (shadows can show around corners)
//drawflat is just lame
//24bits can be considered eeeevil, by some.
#ifdef RTLIGHTS
if (r_shadow_realtime_world.ival)
*s++ = 'W';
else if (r_shadow_realtime_dlight.ival)
*s++ = 'S';
#endif
default:
*sr = *"";
break;
}
if (r_drawflat.ival)
*s++ = 'F';
if (gl_load24bit.ival)
*s++ = 'H';
*s = '\0';

View File

@ -806,6 +806,7 @@ void V_CalcGunPositionAngle (playerview_t *pv, float bob)
float yaw, pitch, move;
static float oldyaw = 0;
static float oldpitch = 0;
vec3_t vw_angles;
int i;
yaw = r_refdef.viewangles[YAW];
@ -847,37 +848,36 @@ void V_CalcGunPositionAngle (playerview_t *pv, float bob)
oldyaw = yaw;
oldpitch = pitch;
pv->viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw;
pv->viewent.angles[PITCH] = r_refdef.viewangles[PITCH] + pitch;
vw_angles[YAW] = r_refdef.viewangles[YAW] + yaw;
vw_angles[PITCH] = r_refdef.viewangles[PITCH] + pitch;
pv->viewent.angles[YAW] = r_refdef.viewangles[YAW];
pv->viewent.angles[PITCH] = r_refdef.viewangles[PITCH];
pv->viewent.angles[ROLL] = r_refdef.viewangles[ROLL];
vw_angles[YAW] = r_refdef.viewangles[YAW];
vw_angles[PITCH] = r_refdef.viewangles[PITCH];
vw_angles[ROLL] = r_refdef.viewangles[ROLL];
AngleVectors(pv->viewent.angles, pv->viewent.axis[0], pv->viewent.axis[1], pv->viewent.axis[2]);
VectorInverse(pv->viewent.axis[1]);
pv->viewent.angles[PITCH]*=-1;
AngleVectors(vw_angles, pv->vw_axis[0], pv->vw_axis[1], pv->vw_axis[2]);
VectorInverse(pv->vw_axis[1]);
VectorCopy (r_refdef.vieworg, pv->viewent.origin);
VectorCopy (r_refdef.vieworg, pv->vw_origin);
for (i=0 ; i<3 ; i++)
{
pv->viewent.origin[i] += pv->viewent.axis[0][i]*bob*0.4;
// pv->viewent.origin[i] += pv->viewent.axis[1][i]*sin(cl.time*5.5342452354235)*0.1;
// pv->viewent.origin[i] += pv->viewent.axis[2][i]*bob*0.8;
pv->vw_origin[i] += pv->vw_axis[0][i]*bob*0.4;
// pv->vw_origin[i] += pv->vw_axis[1][i]*sin(cl.time*5.5342452354235)*0.1;
// pv->vw_origin[i] += pv->vw_axis[2][i]*bob*0.8;
}
// fudge position around to keep amount of weapon visible
// roughly equal with different FOV
if (scr_viewsize.value == 110)
pv->viewent.origin[2] += 1;
pv->vw_origin[2] += 1;
else if (scr_viewsize.value == 100)
pv->viewent.origin[2] += 2;
pv->vw_origin[2] += 2;
else if (scr_viewsize.value == 90)
pv->viewent.origin[2] += 1;
pv->vw_origin[2] += 1;
else if (scr_viewsize.value == 80)
pv->viewent.origin[2] += 0.5;
pv->vw_origin[2] += 0.5;
}
/*
@ -939,9 +939,9 @@ void V_AddIdle (playerview_t *pv)
r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*pitch_cycle) * pitch_level;
r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*yaw_cycle) * yaw_level;
pv->viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*roll_cycle) * roll_level;
pv->viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*pitch_cycle) * pitch_level;
pv->viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*yaw_cycle) * yaw_level;
// pv->viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*roll_cycle) * roll_level;
// pv->viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*pitch_cycle) * pitch_level;
// pv->viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*yaw_cycle) * yaw_level;
}
@ -997,15 +997,10 @@ V_CalcIntermissionRefdef
*/
void V_CalcIntermissionRefdef (playerview_t *pv)
{
entity_t *view;
float old;
// view is the weapon model
view = &pv->viewent;
VectorCopy (pv->simorg, r_refdef.vieworg);
VectorCopy (pv->simangles, r_refdef.viewangles);
view->model = NULL;
// always idle in intermission
old = v_idlescale.value;
@ -1211,7 +1206,6 @@ V_CalcRefdef
*/
void V_CalcRefdef (playerview_t *pv)
{
entity_t *view;
float bob;
float viewheight;
r_refdef.playerview = pv;
@ -1224,9 +1218,6 @@ void V_CalcRefdef (playerview_t *pv)
VectorCopy(cl.fog_colour, r_refdef.gfog_rgbd);
r_refdef.gfog_rgbd[3] = cl.fog_density / 64;
// view is the weapon model (only visible from inside body)
view = &pv->viewent;
if (v_viewheight.value < -7)
bob=-7;
else if (v_viewheight.value > 4)
@ -1280,15 +1271,6 @@ void V_CalcRefdef (playerview_t *pv)
// set up gun position
V_CalcGunPositionAngle (pv, bob);
if (pv->statsf[STAT_HEALTH] <= 0 || (unsigned int)pv->stats[STAT_WEAPON] >= MAX_MODELS)
view->model = NULL;
else
view->model = cl.model_precache[pv->stats[STAT_WEAPON]];
#ifdef HLCLIENT
if (!CLHL_AnimateViewEntity(view))
#endif
view->framestate.g[FS_REG].frame[0] = pv->stats[STAT_WEAPONFRAME];
// set up the refresh position
if (v_gunkick.value)
r_refdef.viewangles[PITCH] += pv->punchangle*v_gunkick.value;

View File

@ -237,7 +237,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define R_XFLIP //allow view to be flipped horizontally
#define TEXTEDITOR
#define DDS //a sort of image file format.
#ifndef RTLIGHTS
#define RTLIGHTS //realtime lighting
#endif
#define VM_Q1 //q1 qvm gamecode interface

View File

@ -220,7 +220,12 @@ typedef struct
unsigned int v[2]; // vertex numbers
} dledge_t;
#define MAXLIGHTMAPS 4
#ifdef Q3BSPS
#define MAXRLIGHTMAPS 4 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1)
#else
#define MAXRLIGHTMAPS 1 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1)
#endif
#define MAXQ1LIGHTMAPS 4
typedef struct
{
short planenum;
@ -231,7 +236,7 @@ typedef struct
short texinfo;
// lighting info
qbyte styles[MAXLIGHTMAPS];
qbyte styles[MAXQ1LIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dsface_t;
typedef struct
@ -244,7 +249,7 @@ typedef struct
int texinfo;
// lighting info
qbyte styles[MAXLIGHTMAPS];
qbyte styles[MAXQ1LIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples
} dlface_t;

View File

@ -1668,7 +1668,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
}
if (r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival || qrenderer != QR_OPENGL)
if (Sh_StencilShadowsActive() || qrenderer != QR_OPENGL)
{
mesh->xyz2_array = NULL;
mesh->xyz_blendw[0] = 1;
@ -1898,7 +1898,6 @@ static void Mod_ClampModelSize(model_t *mod)
#endif
}
#ifdef GLQUAKE
static int R_FindTriangleWithEdge (index_t *indexes, int numtris, int start, int end, int ignore)
{
int i;
@ -1940,20 +1939,15 @@ static void Mod_BuildTriangleNeighbours ( int *neighbours, index_t *indexes, int
n[2] = R_FindTriangleWithEdge (indexes, numtris, index[0], index[2], i);
}
}
#endif
void Mod_CompileTriangleNeighbours(galiasinfo_t *galias)
{
#ifdef GLQUAKE
if (qrenderer != QR_OPENGL)
return;
if (r_shadow_realtime_dlight_shadows.ival || r_shadow_realtime_world_shadows.ival)
if (Sh_StencilShadowsActive())
{
int *neighbours;
neighbours = ZG_Malloc(&loadmodel->memgroup, sizeof(int)*galias->numindexes/3*3);
galias->ofs_trineighbours = neighbours;
Mod_BuildTriangleNeighbours(neighbours, galias->ofs_indexes, galias->numindexes/3);
}
#endif
}
typedef struct

View File

@ -1177,7 +1177,7 @@ void World_ODE_Init(void)
const char* dllname =
{
# if defined(WIN64)
"libode1_64"
"libode1"
# elif defined(WIN32)
"ode_double"
# elif defined(MACOSX)

View File

@ -2724,6 +2724,15 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
}
else if (str[1] == '[' && !linkstart)
{
if (keepmarkup)
{
if (!--outsize)
break;
*out++ = '^' | CON_HIDDEN;
}
if (!--outsize)
break;
//preserved flags and reset to white. links must contain their own colours.
linkinitflags = ext;
ext = COLOR_RED << CON_FGSHIFT;
@ -2738,6 +2747,15 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
}
else if (str[1] == ']' && linkstart)
{
if (keepmarkup)
{
if (!--outsize)
break;
*out++ = '^' | CON_HIDDEN;
}
if (!--outsize)
break;
*out++ = ']';
//its a valid link, so we can hide it all now
@ -2987,6 +3005,43 @@ messedup:
return out;
}
//remaps conchar_t character values to something valid in unicode, such that it is likely to be printable with standard char sets.
//unicode-to-ascii is not provided. you're expected to utf-8 the result or something.
//does not handle colour codes or hidden chars. add your own escape sequences if you need that.
//does not guarentee removal of control codes if eg the code was specified as an explicit unicode char.
unsigned int COM_DeQuake(conchar_t chr)
{
chr &= CON_CHARMASK;
/*only this range are quake chars*/
if (chr >= 0xe000 && chr < 0xe100)
{
chr &= 0xff;
if (chr >= 146 && chr < 156)
chr = chr - 146 + '0';
if (chr >= 0x12 && chr <= 0x1b)
chr = chr - 0x12 + '0';
if (chr == 143)
chr = '.';
if (chr == 128 || chr == 129 || chr == 130 || chr == 157 || chr == 158 || chr == 159)
chr = '-';
if (chr >= 128)
chr -= 128;
if (chr == 16)
chr = '[';
if (chr == 17)
chr = ']';
if (chr == 0x1c)
chr = 249;
}
/*this range contains pictograms*/
if (chr >= 0xe100 && chr < 0xe200)
{
chr = '?';
}
return chr;
}
//============================================================================
#define TOKENSIZE sizeof(com_token)

View File

@ -301,6 +301,7 @@ unsigned int utf8_decode(int *error, const void *in, char **out);
unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen);
unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen);
unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen);
unsigned int COM_DeQuake(conchar_t chr);
//handles whatever charset is active, including ^U stuff.
unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs);

View File

@ -2111,7 +2111,7 @@ void COM_Gamedir (const char *dir)
/*set some stuff so our regular qw client appears more like hexen2*/
#define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
/*yay q2!*/
#define Q2CFG "gl_font \":?col=0.44 1 0.2\"\ncom_nogamedirnativecode 0\n"
#define Q2CFG "com_nogamedirnativecode 0\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "gl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\n"
#define RMQCFG "sv_bigcoords 1\n"

View File

@ -16,6 +16,14 @@ typedef struct {
unsigned int mtime;
unsigned char xflags;
unsigned char os;
//unsigned short xlen;
//unsigned char xdata[xlen];
//unsigned char fname[];
//unsigned char fcomment[];
//unsigned short fhcrc;
//unsigned char compresseddata[];
//unsigned int crc32;
//unsigned int isize;
} gzheader_t;
#define sizeofgzheader_t 10

View File

@ -346,7 +346,7 @@ cvar_t r_subdivisions = SCVAR("r_subdivisions", "2");
int CM_NumInlineModels (model_t *model);
cmodel_t *CM_InlineModel (char *name);
void CM_InitBoxHull (void);
void FloodAreaConnections (void);
static void FloodAreaConnections (void);
static int c_pointcontents;
@ -357,8 +357,8 @@ static vecV_t *map_verts; //3points
static int numvertexes;
static vec2_t *map_vertstmexcoords;
static vec2_t *map_vertlstmexcoords[MAXLIGHTMAPS];
static vec4_t *map_colors4f_array[MAXLIGHTMAPS];
static vec2_t *map_vertlstmexcoords[MAXRLIGHTMAPS];
static vec4_t *map_colors4f_array[MAXRLIGHTMAPS];
static vec3_t *map_normals_array;
static vec3_t *map_svector_array;
static vec3_t *map_tvector_array;
@ -1394,7 +1394,7 @@ qboolean CMod_LoadFaces (lump_t *l)
// lighting info
for (i=0 ; i<MAXLIGHTMAPS ; i++)
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
@ -2085,7 +2085,7 @@ qboolean CModQ3_LoadVertexes (lump_t *l)
tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
map_verts = out;
map_vertstmexcoords = stout;
for (i = 0; i < MAXLIGHTMAPS; i++)
for (i = 0; i < MAXRLIGHTMAPS; i++)
{
map_vertlstmexcoords[i] = lmout;
map_colors4f_array[i] = cout;
@ -2142,14 +2142,14 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out));
stout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*stout));
lmout = ZG_Malloc(&loadmodel->memgroup, MAXLIGHTMAPS*count*sizeof(*lmout));
cout = ZG_Malloc(&loadmodel->memgroup, MAXLIGHTMAPS*count*sizeof(*cout));
lmout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*lmout));
cout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*cout));
nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout));
tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout));
map_verts = out;
map_vertstmexcoords = stout;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
map_vertlstmexcoords[sty] = lmout + sty*count;
map_colors4f_array[sty] = cout + sty*count;
@ -2169,10 +2169,10 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
for ( j=0 ; j < 2 ; j++)
{
stout[i][j] = LittleFloat ( ((float *)in->texcoords)[j] );
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
map_vertlstmexcoords[sty][i][j] = LittleFloat ( ((float *)in->texcoords)[j+2*(sty+1)] );
}
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
for ( j=0 ; j < 4 ; j++)
{
@ -2477,14 +2477,14 @@ void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patc
// fill in
Patch_Evaluate ( map_verts[firstvert], patch_cp, step, mesh->xyz_array[0], sizeof(vecV_t)/sizeof(vec_t));
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
if (mesh->colors4f_array[sty])
Patch_Evaluate ( map_colors4f_array[sty][firstvert], patch_cp, step, mesh->colors4f_array[sty][0], 4 );
}
Patch_Evaluate ( map_normals_array[firstvert], patch_cp, step, mesh->normals_array[0], 3 );
Patch_Evaluate ( map_vertstmexcoords[firstvert], patch_cp, step, mesh->st_array[0], 2 );
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
if (mesh->lmst_array[sty])
Patch_Evaluate ( map_vertlstmexcoords[sty][firstvert], patch_cp, step, mesh->lmst_array[sty][0], 2 );
@ -2548,7 +2548,7 @@ void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, void *cookie)
{
VectorCopy(map_verts[fv + i], out->mesh->xyz_array[i]);
Vector2Copy(map_vertstmexcoords[fv + i], out->mesh->st_array[i]);
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
Vector2Copy(map_vertlstmexcoords[sty][fv + i], out->mesh->lmst_array[sty][i]);
Vector4Copy(map_colors4f_array[sty][fv + i], out->mesh->colors4f_array[sty][i]);
@ -2708,7 +2708,7 @@ qboolean CModQ3_LoadRFaces (lump_t *l)
out->light_s[0] = LittleLong(in->lightmap_x);
out->light_t[0] = LittleLong(in->lightmap_y);
out->styles[0] = 255;
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
for (sty = 1; sty < MAXRLIGHTMAPS; sty++)
{
out->styles[sty] = 255;
out->lightmaptexturenums[sty] = -1;
@ -2821,7 +2821,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l)
out->plane = pl;
out->texinfo = loadmodel->texinfo + LittleLong(in->shadernum);
in->facetype = LittleLong(in->facetype);
for (j = 0; j < 4 && j < MAXLIGHTMAPS; j++)
for (j = 0; j < 4 && j < MAXRLIGHTMAPS; j++)
{
out->lightmaptexturenums[j] = LittleLong(in->lightmapnum[j]);
out->light_s[j] = LittleLong(in->lightmap_offs[0][j]);
@ -3358,6 +3358,9 @@ void CModQ3_LoadLighting (lump_t *l)
gl_overbright.flags |= CVAR_LATCH;
BuildLightMapGammaTable(1, (1<<(2-gl_overbright.ival)));
if (!samples)
return;
loadmodel->engineflags |= MDLF_RGBLIGHTING;
loadmodel->lightdata = out = ZG_Malloc(&loadmodel->memgroup, samples);
@ -5636,7 +5639,7 @@ qbyte *Mod_ClusterPVS (int cluster, model_t *model)
model);
}
*/
void CM_DecompressVis (qbyte *in, qbyte *out)
static void CM_DecompressVis (qbyte *in, qbyte *out)
{
int c;
qbyte *out_p;
@ -5678,8 +5681,8 @@ void CM_DecompressVis (qbyte *in, qbyte *out)
} while (out_p - out < row);
}
qbyte pvsrow[MAX_MAP_LEAFS/8];
qbyte phsrow[MAX_MAP_LEAFS/8];
static qbyte pvsrow[MAX_MAP_LEAFS/8];
static qbyte phsrow[MAX_MAP_LEAFS/8];
@ -5744,7 +5747,7 @@ AREAPORTALS
===============================================================================
*/
void FloodArea_r (q2carea_t *area, int floodnum)
static void FloodArea_r (q2carea_t *area, int floodnum)
{
int i;
q2dareaportal_t *p;
@ -5773,7 +5776,7 @@ FloodAreaConnections
====================
*/
void FloodAreaConnections (void)
static void FloodAreaConnections (void)
{
int i, j;
q2carea_t *area;

View File

@ -13,52 +13,21 @@ cvar_t log_enable[LOG_TYPES] = { CVARF("log_enable", "0", CVAR_NOTFROMSERVER),
cvar_t log_name[LOG_TYPES] = { CVARFC("log_name", "", CVAR_NOTFROMSERVER, Log_Name_Callback),
CVARFC("log_name_players", "", CVAR_NOTFROMSERVER, Log_Name_Callback)};
cvar_t log_dir = CVARFC("log_dir", "", CVAR_NOTFROMSERVER, Log_Dir_Callback);
cvar_t log_readable = CVARF("log_readable", "0", CVAR_NOTFROMSERVER);
cvar_t log_readable = CVARFD("log_readable", "7", CVAR_NOTFROMSERVER, "Bitfield describing what to convert/strip. If 0, exact byte representation will be used.\n&1: Dequakify text.\n&2: Strip special markup.\n&4: Strip ansi control codes.");
cvar_t log_developer = CVARF("log_developer", "0", CVAR_NOTFROMSERVER);
cvar_t log_rotate_files = CVARF("log_rotate_files", "0", CVAR_NOTFROMSERVER);
cvar_t log_rotate_size = CVARF("log_rotate_size", "131072", CVAR_NOTFROMSERVER);
cvar_t log_timestamps = CVARF("log_timestamps", "1", CVAR_NOTFROMSERVER);
#ifdef _WIN32
cvar_t log_dosformat = CVARF("log_dosformat", "1", CVAR_NOTFROMSERVER);
#else
cvar_t log_dosformat = CVARF("log_dosformat", "0", CVAR_NOTFROMSERVER);
#endif
qboolean log_newline[LOG_TYPES];
// externals
extern char gamedirfile[];
// table of readable characters, same as ezquake
char readable[256] =
{
'.', '_', '_', '_', '_', '.', '_', '_',
'_', '_', '\n', '_', '\n', '>', '.', '.',
'[', ']', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '.', '_', '_', '_',
' ', '!', '\"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '_',
'_', '_', '_', '_', '_', '.', '_', '_',
'_', '_', '_', '_', '_', '>', '.', '.',
'[', ']', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '.', '_', '_', '_',
' ', '!', '\"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '_'
};
// Log_Dir_Callback: called when a log_dir is changed
void Log_Dir_Callback (struct cvar_s *var, char *oldvalue)
{
@ -94,17 +63,20 @@ void Log_String (logtype_t lognum, char *s)
char *d; // directory
char *f; // filename
char *t;
char logbuf[1024];
char utf8[2048];
int i;
char fname[MAX_QPATH];
conchar_t cline[2048], *c;
unsigned int u;
if (!log_enable[lognum].value)
return;
// get directory/filename
d = gamedirfile;
if (log_dir.string[0])
d = log_dir.string;
else
d = "";//gamedirfile;
f = NULL;
switch(lognum)
@ -124,63 +96,44 @@ void Log_String (logtype_t lognum, char *s)
if (!f)
return;
// readable translation and Q3 code removal, use t for final string to write
t = logbuf;
// max debuglog buf is 1024
for (i = 0; i < 1023; i++, s++)
COM_ParseFunString(CON_WHITEMASK, s, cline, sizeof(cline), !(log_readable.ival & 2));
t = utf8;
for (c = cline; *c; c++)
{
if (*s == 0)
break;
else if (((int)(log_readable.value) & 2) && *s == '^')
{
// log_readable 2 removes Q3 codes as well
char c = s[1];
if ((c >= '0' && c <= '9') || c == 'a' || c == 'b' || c == 'h' || c == 's' || c == 'r')
{
i--;
s++;
}
else if (c == '&')
{
if (isextendedcode(s[2]) && isextendedcode(s[3]))
{
i--;
s += 3;
}
}
else
{
*t = '^';
t++;
}
}
else if (log_dosformat.value && *s == '\n')
{
// convert \n to \r\n
*t = '\r';
t++;
i++;
if (i < 1023)
{
*t = '\n';
t++;
}
}
if ((*c & CON_HIDDEN) && (log_readable.ival & 2))
continue;
if (log_readable.ival&1)
u = COM_DeQuake(*c);
else
{
// use readable table to convert quake chars to reabable text
if ((int)(log_readable.value) & 1)
*t = readable[(unsigned char)(*s)]; // translate
else
*t = *s; // copy
t++;
}
}
u = *c&CON_CHARMASK;
//at the start of a new line, we might want a timestamp (so timestamps are correct for the first char of the line, instead of the preceeding \n)
if (log_newline[lognum])
{
if (log_timestamps.ival)
{
time_t unixtime = time(NULL);
strftime(t, utf8+sizeof(utf8)-1-t, "%Y-%m-%d %H:%M:%S ", localtime(&unixtime));
t += strlen(t);
}
log_newline[lognum] = false;
}
//make sure control codes are stripped. no exploiting xterm bugs please.
if ((log_readable.ival & 4) && ((u < 32 && u != '\t' && u != '\n') || u == 127 || (u >= 128 && u < 128+32))) //\r is stripped too
u = '?';
//if dos format logs, we insert a \r before every \n (also flag next char as the start of a new line)
if (u == '\n')
{
log_newline[lognum] = true;
if (log_dosformat.ival)
t += utf8_encode(t, '\r', utf8+sizeof(utf8)-1-t);
}
t += utf8_encode(t, u, utf8+sizeof(utf8)-1-t);
}
*t = 0;
Q_snprintfz(fname, sizeof(fname), "%s/%s.log",d,f);
Q_snprintfz(fname, sizeof(fname), "%s%s.log", d, f);
// file rotation
if (log_rotate_size.value >= 4096 && log_rotate_files.value >= 1)
@ -189,11 +142,11 @@ void Log_String (logtype_t lognum, char *s)
vfsfile_t *fi;
// check file size, use x as temp
if ((fi = FS_OpenVFS(fname, "rb", FS_ROOT)))
if ((fi = FS_OpenVFS(fname, "rb", FS_GAMEONLY)))
{
x = VFS_GETLEN(fi);
VFS_CLOSE(fi);
x += i; // add string size to file size to never go over
x += strlen(utf8); // add string size to file size to never go over
}
else
x = 0;
@ -206,22 +159,22 @@ void Log_String (logtype_t lognum, char *s)
i = log_rotate_files.value;
// unlink file at the top of the chain
snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, i);
FS_Remove(oldf, FS_ROOT);
snprintf(oldf, sizeof(oldf)-1, "%s%s.%i", d, f, i);
FS_Remove(oldf, FS_GAMEONLY);
// rename files through chain
for (x = i-1; x > 0; x--)
{
strcpy(newf, oldf);
snprintf(oldf, sizeof(oldf)-1, "%s.%i", f, x);
snprintf(oldf, sizeof(oldf)-1, "%s%s.%i", d, f, x);
// check if file exists, otherwise skip
if ((fi = FS_OpenVFS(oldf, "rb", FS_ROOT)))
if ((fi = FS_OpenVFS(oldf, "rb", FS_GAMEONLY)))
VFS_CLOSE(fi);
else
continue; // skip nonexistant files
if (!FS_Rename(oldf, newf, FS_ROOT))
if (!FS_Rename(oldf, newf, FS_GAMEONLY))
{
// rename failed, disable log and bug out
Cvar_ForceSet(&log_enable[lognum], "0");
@ -231,8 +184,8 @@ void Log_String (logtype_t lognum, char *s)
}
// TODO: option to compress file somewhere in here?
// rename our base file, which better exist...
if (!FS_Rename(f, oldf, FS_ROOT))
// rename our base file, which had better exist...
if (!FS_Rename(fname, oldf, FS_GAMEONLY))
{
// rename failed, disable log and bug out
Cvar_ForceSet(&log_enable[lognum], "0");
@ -242,10 +195,10 @@ void Log_String (logtype_t lognum, char *s)
}
}
FS_CreatePath(f, FS_ROOT);
if ((fi = FS_OpenVFS(f, "ab", FS_ROOT)))
FS_CreatePath(fname, FS_GAMEONLY);
if ((fi = FS_OpenVFS(fname, "ab", FS_GAMEONLY)))
{
VFS_WRITE(fi, logbuf, strlen(logbuf));
VFS_WRITE(fi, utf8, strlen(utf8));
VFS_CLOSE(fi);
}
else
@ -278,10 +231,10 @@ void SV_LogPlayer(client_t *cl, char *msg)
return; //don't log botclients
snprintf(line, sizeof(line),
"%s\\%s\\%i\\%s\\%s\\%i%s\n",
"%s\\%s\\%i\\%s\\%s\\%i\\guid\\%s%s\n",
msg, cl->name, cl->userid,
NET_BaseAdrToString(remote_adr, sizeof(remote_adr), &cl->netchan.remote_address), (cl->realip_status > 0 ? NET_BaseAdrToString(realip_adr, sizeof(realip_adr), &cl->realip) : "??"),
cl->netchan.remote_address.port, cl->userinfo);
cl->netchan.remote_address.port, cl->guid, cl->userinfo);
Log_String(LOG_PLAYER, line);
}
@ -365,6 +318,7 @@ void Log_Init(void)
{
Cvar_Register (&log_enable[i], CONLOGGROUP);
Cvar_Register (&log_name[i], CONLOGGROUP);
log_newline[i] = true;
}
Cvar_Register (&log_dir, CONLOGGROUP);
Cvar_Register (&log_readable, CONLOGGROUP);
@ -372,6 +326,7 @@ void Log_Init(void)
Cvar_Register (&log_rotate_size, CONLOGGROUP);
Cvar_Register (&log_rotate_files, CONLOGGROUP);
Cvar_Register (&log_dosformat, CONLOGGROUP);
Cvar_Register (&log_timestamps, CONLOGGROUP);
Cmd_AddCommand("logfile", Log_Logfile_f);

View File

@ -77,7 +77,7 @@ typedef struct trailstate_s {
#define PARTICLE_Z_CLIP 8.0
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT, BM_INVMOD } blendmode_t;
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT, BM_INVMODA, BM_INVMODC } blendmode_t;
#define frandom() (rand()*(1.0f/RAND_MAX))
#define crandom() (rand()*(2.0f/RAND_MAX)-1.0f)

View File

@ -2063,10 +2063,9 @@ void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
pad = 0;
Q_strncpyz(dest+pad, src, MAXTEMPBUFFERLEN-pad);
while(pad--)
while(pad)
{
pad--;
dest[pad] = ' ';
dest[--pad] = ' ';
}
}
else
@ -3295,9 +3294,14 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
{
#ifdef WEBCLIENT
world_t *w = prinst->parms->user;
struct dl_download *dl;
unsigned char *url = PR_GetStringOfs(prinst, OFS_PARM0);
float id = G_FLOAT(OFS_PARM1);
struct dl_download *dl;
char *mimetype = (prinst->callargc >= 3)?PR_GetStringOfs(prinst, OFS_PARM2):"";
char *dataorsep = PR_GetStringOfs(prinst, OFS_PARM3);
int strbufid = G_FLOAT(OFS_PARM4);
//float cryptokey = G_FLOAT(OFS_PARM5); //DP feature, not supported in FTE.
if (!pr_enable_uriget.ival)
{
@ -3305,9 +3309,29 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
G_FLOAT(OFS_RETURN) = 0;
return;
}
Con_DPrintf("PF_uri_get(%s,%g)\n", url, id);
dl = HTTP_CL_Get(url, NULL, PR_uri_get_callback);
if (*mimetype)
{
char *data;
Con_DPrintf("PF_uri_post(%s,%g)\n", url, id);
if (strbufid)
{
//convert the string buffer into a simple string using dataorsep as a separator
//not supported at this time
dl = NULL;
}
else
{
//simple data post.
data = dataorsep;
dl = HTTP_CL_Put(url, mimetype, data, strlen(data), PR_uri_get_callback);
}
}
else
{
Con_DPrintf("PF_uri_get(%s,%g)\n", url, id);
dl = HTTP_CL_Get(url, NULL, PR_uri_get_callback);
}
if (dl)
{
dl->user_ctx = w;
@ -3657,6 +3681,18 @@ void QCBUILTIN PF_ceil (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0));
}
void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float v = G_FLOAT(OFS_PARM0);
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
G_FLOAT(OFS_RETURN) = v;
}
//Maths functions
////////////////////////////////////////////////////
//Vector functions
@ -4691,6 +4727,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QC_UNLIMITEDTEMPSTRINGS"},
{"DP_QC_URI_ESCAPE", 2, NULL, {"uri_escape", "uri_unescape"}},
{"DP_QC_URI_GET", 1, NULL, {"uri_get"}},
//test {"DP_QC_URI_POST", 1, NULL, {"uri_get"}},
{"DP_QC_VECTOANGLES_WITH_ROLL"},
{"DP_QC_VECTORVECTORS", 1, NULL, {"vectorvectors"}},
{"DP_QC_WHICHPACK", 1, NULL, {"whichpack"}},
@ -4729,7 +4766,8 @@ lh_extension_t QSG_Extensions[] = {
{"_DP_TE_QUADEFFECTS1", 4, NULL, {"te_gunshotquad", "te_spikequad", "te_superspikequad", "te_explosionquad"}},
{"DP_TE_SMALLFLASH", 1, NULL, {"te_smallflash"}},
{"DP_TE_SPARK", 1, NULL, {"te_spark"}},
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}},
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, { "te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike",
"te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}},
{"DP_VIEWZOOM"},
{"EXT_BITSHIFT", 1, NULL, {"bitshift"}},
{"EXT_DIMENSION_VISIBILITY"},
@ -4743,6 +4781,9 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_CSQC_SERVERBROWSER", 12, NULL, { "gethostcachevalue", "gethostcachestring", "resethostcachemasks", "sethostcachemaskstring", "sethostcachemasknumber",
"resorthostcache", "sethostcachesort", "refreshhostcache", "gethostcachenumber", "gethostcacheindexforkey",
"addwantedhostcachekey", "getextresponse"}}, //normally only available to the menu. this also adds them to csqc.
{"FTE_CSQC_SKELETONOBJECTS", 15, NULL, { "skel_create", "skel_build", "skel_get_numbones", "skel_get_bonename", "skel_get_boneparent", "skel_find_bone",
"skel_get_bonerel", "skel_get_boneabs", "skel_set_bone", "skel_mul_bone", "skel_mul_bones", "skel_copybones",
"skel_delete", "frameforname", "frameduration"}},
{"FTE_ENT_SKIN_CONTENTS"}, //self.skin = CONTENTS_WATER; makes a brush entity into water. use -16 for a ladder.
{"FTE_ENT_UNIQUESPAWNID"},
{"FTE_EXTENDEDTEXTCODES"},
@ -4767,9 +4808,10 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_QC_CHECKCOMMAND", 1, NULL, {"checkcommand"}},
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
{"FTE_QC_HASHTABLES", 6, NULL, {"hash_createtab", "hash_destroytab", "hash_add", "hash_get", "hash_delete", "hash_getkey"}},
{"FTE_QC_INTCONV", 4, NULL, {"stoi", "itos", "stoh", "htos"}},
{"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclientname"}},
{"FTE_QC_PAUSED"},
{"FTE_QC_INTCONV", 4, NULL, {"stoi", "itos", "stoh", "htos"}},
{"FTE_QC_RAGDOLL_WIP", 1, NULL, {"ragupdate", "skel_set_bone_world", "skel_mmap"}},
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}}, //includes the SV_ParseConnectionlessPacket event.
{"FTE_QC_TRACETRIGGER"},
{"FTE_SOLID_LADDER"}, //Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS

View File

@ -97,6 +97,7 @@ void QCBUILTIN PF_error (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
void QCBUILTIN PF_rint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_floor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_ceil (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_Tokenize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_tokenize_console (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View File

@ -155,6 +155,7 @@ struct world_s
model_t *(*Get_CModel)(struct world_s *w, int modelindex);
void (*Get_FrameState)(struct world_s *w, wedict_t *s, framestate_t *fstate);
unsigned int keydestmask; //menu:kdm_menu, csqc:kdm_game, server:0
unsigned int max_edicts; //limiting factor... 1024 fields*4*MAX_EDICTS == a heck of a lot.
unsigned int num_edicts; // increases towards MAX_EDICTS
/*FTE_DEPRECATED*/ unsigned int edict_size; //still used in copyentity

View File

@ -1648,7 +1648,7 @@ static void D3D11BE_Cull(unsigned int cullflags)
D3D11_RASTERIZER_DESC rasterdesc;
ID3D11RasterizerState *newrasterizerstate;
cullflags |= r_refdef.flipcull;
cullflags ^= r_refdef.flipcull;
if (shaderstate.curcull != cullflags)
{
@ -2685,7 +2685,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist)
if (!view || VectorCompare(view->origin, view->oldorigin))
{
r_refdef.flipcull ^= true;
r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane);
}
else

View File

@ -1984,7 +1984,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
void D3D9BE_Cull(unsigned int cullflags)
{
cullflags |= r_refdef.flipcull;
cullflags ^= r_refdef.flipcull;
if (shaderstate.curcull != cullflags)
{
shaderstate.curcull = cullflags;
@ -2944,7 +2944,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist)
if (!view || VectorCompare(view->origin, view->oldorigin))
{
r_refdef.flipcull ^= true;
r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane);
}
else

View File

@ -752,12 +752,6 @@ static void (D3D9_R_NewMap) (void)
R_SetSky(cl.skyname);
#ifdef RTLIGHTS
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
{
R_LoadRTLights();
if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
}
Sh_PreGenerateLights();
#endif
}

View File

@ -816,12 +816,6 @@ static void (D3D11_R_NewMap) (void)
R_SetSky(cl.skyname);
#ifdef RTLIGHTS
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
{
R_LoadRTLights();
if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
}
Sh_PreGenerateLights();
#endif
}

View File

@ -138,6 +138,7 @@ Global
{2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.Build.0 = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.Debug|x64.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.Build.0 = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLDebug|x64.ActiveCfg = Debug|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.ActiveCfg = Release|Win32
{2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.Build.0 = Release|Win32
@ -507,7 +508,6 @@ Global
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.Debug|x64.Build.0 = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLDebug|Win32.ActiveCfg = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLDebug|x64.ActiveCfg = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLDebug|x64.Build.0 = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLRelease|Win32.ActiveCfg = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLRelease|x64.ActiveCfg = Debug Dedicated Server|x64
{482A886A-5755-4DAE-AD5F-D7CD4A990F9E}.GLRelease|x64.Build.0 = Debug Dedicated Server|x64

File diff suppressed because it is too large Load Diff

View File

@ -123,7 +123,7 @@
Name="GLDebug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
@ -152,11 +152,10 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\client;../common;../server;../gl;../sw;../qclib;../libs;../libs/dxsdk7/include;../libs/freetype2/include;../libs/speex"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS"
AdditionalIncludeDirectories="..\client;../common;../server;../gl;../sw;../qclib;../libs;../libs/dxsdk7/include;../libs/freetype2/include;../libs/speex;../"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;NPQTV;MULTITHREAD"
RuntimeLibrary="1"
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
PrecompiledHeaderFile=".\GLDebug/qwcl.pch"
AssemblerListingLocation=".\GLDebug/"
@ -182,7 +181,7 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="comctl32.lib wsock32.lib winmm.lib odbc32.lib odbccp32.lib"
OutputFile="../../fteglqw_dbg64.exe"
OutputFile="../../npfte64_dbg.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="../libs/dxsdk7/lib"

View File

@ -991,19 +991,18 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
if ((r_refdef.externalview || r_refdef.recurse) && e->flags & Q2RF_WEAPONMODEL)
return;
clmodel = e->model;
/*switch model if we're the player model, and the player skin says a new model*/
{
extern int cl_playerindex;
if (e->playerindex >= 0 && e->model == cl.model_precache[cl_playerindex])
{
clmodel = cl.players[e->playerindex].model;
if (clmodel && clmodel->type == mod_alias)
e->model = clmodel;
if (!clmodel || clmodel->type != mod_alias)
clmodel = e->model; //oops, never mind
}
}
clmodel = e->model;
if (!(e->flags & Q2RF_WEAPONMODEL) && !e->framestate.bonestate)
{
if (R_CullEntityBox (e, clmodel->mins, clmodel->maxs))
@ -1529,13 +1528,6 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris,
qboolean BE_ShouldDraw(entity_t *e)
{
if (!r_refdef.externalview && (e->flags & Q2RF_EXTERNALMODEL))
return false;
return true;
}
#ifdef Q3CLIENT
//q3 lightning gun
static void R_DB_LightningBeam(batch_t *batch)
@ -1705,12 +1697,12 @@ static void R_DB_Sprite(batch_t *batch)
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.playerview->viewentity > 0)
{
sprorigin[0] = r_refdef.playerview->viewent.origin[0];
sprorigin[1] = r_refdef.playerview->viewent.origin[1];
sprorigin[2] = r_refdef.playerview->viewent.origin[2];
VectorMA(sprorigin, e->origin[0], r_refdef.playerview->viewent.axis[0], sprorigin);
VectorMA(sprorigin, e->origin[1], r_refdef.playerview->viewent.axis[1], sprorigin);
VectorMA(sprorigin, e->origin[2], r_refdef.playerview->viewent.axis[2], sprorigin);
sprorigin[0] = r_refdef.playerview->vw_origin[0];
sprorigin[1] = r_refdef.playerview->vw_origin[1];
sprorigin[2] = r_refdef.playerview->vw_origin[2];
VectorMA(sprorigin, e->origin[0], r_refdef.playerview->vw_axis[0], sprorigin);
VectorMA(sprorigin, e->origin[1], r_refdef.playerview->vw_axis[1], sprorigin);
VectorMA(sprorigin, e->origin[2], r_refdef.playerview->vw_axis[2], sprorigin);
VectorMA(sprorigin, 12, vpn, sprorigin);
batch->flags |= BEF_FORCENODEPTH;
@ -1745,7 +1737,7 @@ static void R_DB_Sprite(batch_t *batch)
{
vec3_t ea[3];
AngleVectors (e->angles, ea[0], ea[1], ea[2]);
Matrix3_Multiply(ea, r_refdef.playerview->viewent.axis, spraxis);
Matrix3_Multiply(ea, r_refdef.playerview->vw_axis, spraxis);
}
else
AngleVectors (e->angles, spraxis[0], spraxis[1], spraxis[2]);
@ -1963,7 +1955,7 @@ void BE_GenPolyBatches(batch_t **batches)
}
void R_HalfLife_GenerateBatches(entity_t *e, batch_t **batches);
void BE_GenModelBatches(batch_t **batches)
void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemode)
{
int i;
entity_t *ent;
@ -1982,20 +1974,35 @@ void BE_GenModelBatches(batch_t **batches)
if (!r_drawentities.ival)
return;
if (bemode == BEM_STANDARD)
{
#ifndef CLIENTONLY
SV_AddDebugPolygons();
SV_AddDebugPolygons();
#endif
Alias_FlushCache();
//the alias cache is a backend thing that provides support for multiple entities using the same skeleton.
//thus it needs to be cleared so that it won't reuse the cache over multiple frames.
Alias_FlushCache();
}
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
{
ent = &cl_visedicts[i];
if (!BE_ShouldDraw(ent))
if (!r_refdef.externalview && (ent->flags & Q2RF_EXTERNALMODEL))
continue;
if (bemode == BEM_STENCIL || bemode == BEM_DEPTHONLY)
{
if (ent->flags & (RF_NOSHADOW | Q2RF_ADDITIVE | RF_NODEPTHTEST | Q2RF_TRANSLUCENT)) //noshadow often isn't enough for legacy content.
continue;
if (ent->keynum == dl->key && ent->keynum) //shadows are not cast from the entity that owns the light. it is expected to be inside.
continue;
if (ent->model && ent->model->engineflags & MDLF_FLAME)
continue;
}
switch(ent->rtype)
{
case RT_MODEL:

View File

@ -57,16 +57,6 @@ static const char LIGHTPASS_SHADER[] = "\
}\n\
}";
enum
{
LSHADER_STANDARD,
LSHADER_CUBE,
LSHADER_SMAP,
LSHADER_SPOT,
LSHADER_MODES
};
extern cvar_t r_glsl_offsetmapping, r_noportals;
static void BE_SendPassBlendDepthMask(unsigned int sbits);
@ -86,8 +76,10 @@ struct {
const shader_t *crepskyshader;
const shader_t *crepopaqueshader;
const shader_t *depthonlyshader;
GLhandleARB allblackshader;
int allblack_mvp;
qboolean initeddepthnorm;
const shader_t *depthnormshader;
@ -178,6 +170,7 @@ struct {
const batch_t *curbatch;
const texnums_t *curtexnums;
const mfog_t *fog;
const dlight_t *curdlight;
float curtime;
float updatetime;
@ -190,7 +183,9 @@ struct {
texid_t lighttexture;
texid_t lightcubemap;
float lightprojmatrix[16]; /*world space*/
vec2_t lightshadowmapscale;
vec4_t lightshadowmapinfo;
vec4_t lightshadowmapproj;
};
int wbatch;
@ -573,6 +568,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
break;
}
break;
#if MAXRLIGHTMAPS > 1
case VATTR_COLOUR2:
GL_SelectVBO(shaderstate.sourcevbo->colours[1].gl.vbo);
qglVertexAttribPointer(VATTR_COLOUR2, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[1].gl.addr);
@ -585,6 +581,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
GL_SelectVBO(shaderstate.sourcevbo->colours[3].gl.vbo);
qglVertexAttribPointer(VATTR_COLOUR4, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[3].gl.addr);
break;
#endif
case VATTR_TEXCOORD:
GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo);
qglVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->texcoord.gl.addr);
@ -601,6 +598,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
qglVertexAttribPointer(VATTR_LMCOORD, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[0].gl.addr);
}
break;
#if MAXRLIGHTMAPS > 1
case VATTR_LMCOORD2:
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[1].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD2, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[1].gl.addr);
@ -613,6 +611,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
GL_SelectVBO(shaderstate.sourcevbo->lmcoord[3].gl.vbo);
qglVertexAttribPointer(VATTR_LMCOORD4, 2, GL_FLOAT, GL_FALSE, 0, shaderstate.sourcevbo->lmcoord[3].gl.addr);
break;
#endif
case VATTR_NORMALS:
if (!shaderstate.sourcevbo->normals.gl.addr)
{
@ -786,11 +785,11 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
BE_EnableShaderAttributes(gl_config.nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX), 0);
if (shaderstate.allblackshader != shaderstate.lastuniform)
if (shaderstate.allblackshader != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
{
float m16[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
qglUniformMatrix4fvARB(qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection"), 1, false, m16);
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
}
shaderstate.lastuniform = shaderstate.allblackshader;
@ -805,13 +804,14 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
//draw cached world shadow mesh
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
}
RQuantAdd(RQUANT_SHADOWFACES, numindicies);
RQuantAdd(RQUANT_SHADOWFACES, numindicies/3);
shaderstate.dummyvbo.indicies.gl.vbo = 0;
shaderstate.sourcevbo = NULL;
}
void GL_CullFace(unsigned int sflags)
{
sflags ^= r_refdef.flipcull;
#ifndef FORCESTATE
if (shaderstate.curcull == sflags)
return;
@ -821,12 +821,12 @@ void GL_CullFace(unsigned int sflags)
if (shaderstate.curcull & SHADER_CULL_FRONT)
{
qglEnable(GL_CULL_FACE);
qglCullFace(r_refdef.flipcull?GL_BACK:GL_FRONT);
qglCullFace(GL_FRONT);
}
else if (shaderstate.curcull & SHADER_CULL_BACK)
{
qglEnable(GL_CULL_FACE);
qglCullFace(r_refdef.flipcull?GL_FRONT:GL_BACK);
qglCullFace(GL_BACK);
}
else
{
@ -957,10 +957,19 @@ void R_IBrokeTheArrays(void)
//called from gl_shadow
void GLBE_SetupForShadowMap(texid_t shadowmaptex, int texwidth, int texheight, float shadowscale)
{
shaderstate.lightshadowmapinfo[0] = 1.0/texwidth;
shaderstate.lightshadowmapinfo[1] = 1.0/texheight;
shaderstate.lightshadowmapinfo[2] = 1.0;
shaderstate.lightshadowmapinfo[3] = shadowscale;
extern cvar_t r_shadow_shadowmapping_bias;
extern cvar_t r_shadow_shadowmapping_nearclip;
//FIXME: this is used for rendering, not for shadow generation!
#define SHADOWMAP_SIZE 512
//projection frustum, slots 10+11. scaled by 0.5
//lightshadowmapproj is a projection matrix packed into a vec4, with various texture scaling stuff built in.
shaderstate.lightshadowmapproj[0] = shadowscale * (1.0-(1.0/texwidth)) * 0.5/3.0;
shaderstate.lightshadowmapproj[1] = shadowscale * (1.0-(1.0/texheight)) * 0.5/2.0;
shaderstate.lightshadowmapproj[2] = 0.5*(shaderstate.lightradius+r_shadow_shadowmapping_nearclip.value)/(r_shadow_shadowmapping_nearclip.value-shaderstate.lightradius);
shaderstate.lightshadowmapproj[3] = (shaderstate.lightradius*r_shadow_shadowmapping_nearclip.value)/(r_shadow_shadowmapping_nearclip.value-shaderstate.lightradius) - 0.5*r_shadow_shadowmapping_bias.value*r_shadow_shadowmapping_nearclip.value*(1024/texheight);
shaderstate.lightshadowmapscale[0] = 1.0/(SHADOWMAP_SIZE*3);
shaderstate.lightshadowmapscale[1] = 1.0/(SHADOWMAP_SIZE*2);
shaderstate.curshadowmap = shadowmaptex;
while(shaderstate.lastpasstmus>0)
@ -1300,7 +1309,7 @@ void GLBE_Init(void)
shaderstate.identitylighting = 1;
shaderstate.identitylightmap = 1;
for (i = 0; i < MAXLIGHTMAPS; i++)
for (i = 0; i < MAXRLIGHTMAPS; i++)
shaderstate.dummybatch.lightmap[i] = -1;
#ifdef RTLIGHTS
@ -1324,6 +1333,14 @@ void GLBE_Init(void)
shaderstate.fogtexture = r_nulltex;
shaderstate.depthonlyshader = R_RegisterShader("depthonly", SUF_NONE,
"{\n"
"program depthonly\n"
"{\n"
"depthwrite\n"
"}\n"
"}\n"
);
//make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1;
@ -1647,17 +1664,21 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds
case RGB_GEN_VERTEX_LIGHTING:
if (mesh->colors4f_array[1])
{
float lm[4];
float lm[MAXRLIGHTMAPS];
lm[0] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f*shaderstate.identitylighting;
#if MAXRLIGHTMAPS > 1
lm[1] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[1]]/256.0f*shaderstate.identitylighting;
lm[2] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[2]]/256.0f*shaderstate.identitylighting;
lm[3] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[3]]/256.0f*shaderstate.identitylighting;
#endif
while((cnt)--)
{
VectorScale( mesh->colors4f_array[0][cnt], lm[0], dst[cnt]);
#if MAXRLIGHTMAPS > 1
VectorMA(dst[cnt], lm[1], mesh->colors4f_array[1][cnt], dst[cnt]);
VectorMA(dst[cnt], lm[2], mesh->colors4f_array[2][cnt], dst[cnt]);
VectorMA(dst[cnt], lm[3], mesh->colors4f_array[3][cnt], dst[cnt]);
#endif
}
break;
}
@ -2655,7 +2676,7 @@ static void DrawPass(const shaderpass_t *pass)
//second pass should be an ADD
//this depends upon rgbgens for light levels, so each pass *must* be pushed to hardware individually
for (j = 1; j < MAXLIGHTMAPS && shaderstate.curbatch->lightmap[j] >= 0; j++)
for (j = 1; j < MAXRLIGHTMAPS && shaderstate.curbatch->lightmap[j] >= 0; j++)
{
if (j == 1)
BE_SetPassBlendMode(tmu, PBM_REPLACE);
@ -2797,16 +2818,17 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
break;
case SP_E_VLSCALE:
#if MAXRLIGHTMAPS > 1
if (perm & PERMUTATION_LIGHTSTYLES)
{
vec4_t colscale[MAXLIGHTMAPS];
vec4_t colscale[MAXRLIGHTMAPS];
int j, s;
for (j = 0; j < MAXLIGHTMAPS ; j++)
for (j = 0; j < MAXRLIGHTMAPS ; j++)
{
s = shaderstate.curbatch->vtlightstyle[j];
if (s == 255)
{
for (; j < MAXLIGHTMAPS ; j++)
for (; j < MAXRLIGHTMAPS ; j++)
{
colscale[j][0] = 0;
colscale[j][1] = 0;
@ -2832,17 +2854,19 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
qglUniform4fvARB(ph, j, (GLfloat*)colscale);
shaderstate.lastuniform = 0;
}
#endif
case SP_E_LMSCALE:
#if MAXRLIGHTMAPS > 1
if (perm & PERMUTATION_LIGHTSTYLES)
{
vec4_t colscale[MAXLIGHTMAPS];
vec4_t colscale[MAXRLIGHTMAPS];
int j, s;
for (j = 0; j < MAXLIGHTMAPS ; j++)
for (j = 0; j < MAXRLIGHTMAPS ; j++)
{
s = shaderstate.curbatch->lmlightstyle[j];
if (s == 255)
{
for (; j < MAXLIGHTMAPS ; j++)
for (; j < MAXRLIGHTMAPS ; j++)
{
colscale[j][0] = 0;
colscale[j][1] = 0;
@ -2869,6 +2893,7 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
shaderstate.lastuniform = 0;
}
else
#endif
{
vec4_t colscale[4];
if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
@ -2989,23 +3014,19 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
case SP_LIGHTCOLOURSCALE:
qglUniform3fvARB(ph, 1, shaderstate.lightcolourscale);
break;
case SP_LIGHTPROJMATRIX:
{
float t[16];
Matrix4x4_CM_Projection_Far(t, 90, 90, 4, 3000);
qglUniformMatrix4fvARB(ph, 1, false, t);
}
break;
case SP_LIGHTCUBEMATRIX:
/*light's texture projection matrix*/
{
float t[16];
Matrix4_Multiply(shaderstate.modelmatrix, shaderstate.lightprojmatrix, t);
Matrix4_Multiply(shaderstate.lightprojmatrix, shaderstate.modelmatrix, t);
qglUniformMatrix4fvARB(ph, 1, false, t);
}
break;
case SP_LIGHTSHADOWMAPINFO:
qglUniform4fvARB(ph, 1, shaderstate.lightshadowmapinfo);
case SP_LIGHTSHADOWMAPPROJ:
qglUniform4fvARB(ph, 1, shaderstate.lightshadowmapproj);
break;
case SP_LIGHTSHADOWMAPSCALE:
qglUniform2fvARB(ph, 1, shaderstate.lightshadowmapscale);
break;
/*static lighting info*/
@ -3083,8 +3104,10 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
perm |= PERMUTATION_FOG;
if (p->permu[perm|PERMUTATION_DELUXE].handle.glsl && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
perm |= PERMUTATION_DELUXE;
#if MAXRLIGHTMAPS > 1
if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.glsl)
perm |= PERMUTATION_LIGHTSTYLES;
#endif
GL_SelectProgram(p->permu[perm].handle.glsl);
#ifndef FORCESTATE
@ -3106,6 +3129,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
{
Shader_BindTextureForPass(i, pass+i);
}
#if MAXRLIGHTMAPS > 1
if (perm & PERMUTATION_LIGHTSTYLES)
{
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[1] >= 0?lightmap[shaderstate.curbatch->lightmap[1]]->lightmap_texture:r_nulltex);
@ -3120,6 +3144,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
shaderstate.lastpasstmus = pass->numMergedPasses+3;
}
else
#endif
{
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
@ -3214,6 +3239,7 @@ void GLBE_SelectMode(backendmode_t mode)
{
char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config.gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
}
//disable all tmus
@ -3332,66 +3358,67 @@ static qboolean GLBE_RegisterLightShader(int mode)
shaderstate.inited_shader_light[mode] = true;
shaderstate.shader_light[mode] = R_RegisterCustom(name, SUF_NONE, Shader_LightPass, NULL);
//make sure it has a program and forget it if it doesn't, to save a compare.
if (!shaderstate.shader_light[mode] || !shaderstate.shader_light[mode]->prog)
{
shaderstate.shader_light[mode] = NULL;
}
}
if (shaderstate.shader_light[mode])
{
//make sure it has a program and forget it if it doesn't, to save a compare.
if (!shaderstate.shader_light[mode]->prog)
{
shaderstate.shader_light[mode] = NULL;
return false;
}
return true;
}
return false;
}
#endif
void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, unsigned int lmode)
{
float view[16];
int lmode;
extern cvar_t gl_specular;
extern cvar_t r_shadow_shadowmapping;
#ifdef RTLIGHTS
float view[16];
extern cvar_t r_shadow_shadowmapping, r_shadow_shadowmapping_nearclip;
/*generate light projection information*/
float nearplane = 4;
if (dl->fov)
if (lmode == LSHADER_SPOT)
{
float proj[16];
Matrix4x4_CM_Projection_Far(proj, dl->fov, dl->fov, nearplane, dl->radius);
Matrix4x4_CM_Projection_Far(proj, dl->fov, dl->fov, r_shadow_shadowmapping_nearclip.value, dl->radius);
Matrix4x4_CM_ModelViewMatrixFromAxis(view, dl->axis[0], dl->axis[1], dl->axis[2], dl->origin);
Matrix4_Multiply(proj, view, shaderstate.lightprojmatrix);
}
else
if (lmode == LSHADER_SMAP)
{
// Matrix4x4_CM_Projection_Far(proj, 90, 90, nearplane, dl->radius);
Matrix4x4_CM_ModelViewMatrixFromAxis(shaderstate.lightprojmatrix, dl->axis[0], dl->axis[1], dl->axis[2], dl->origin);
}
#endif
shaderstate.curdlight = dl;
shaderstate.lightmode = 1u<<lmode;
if (lmode != LSHADER_SPOT)
{
if (TEXVALID(shaderstate.lightcubemap) && GLBE_RegisterLightShader(shaderstate.lightmode | (1u<<LSHADER_CUBE)))
shaderstate.lightmode |= 1u<<LSHADER_CUBE;
}
if (!GLBE_RegisterLightShader(shaderstate.lightmode))
return false;
/*simple info*/
shaderstate.lightradius = dl->radius;
VectorCopy(dl->origin, shaderstate.lightorg);
VectorCopy(dl->lightcolourscales, shaderstate.lightcolourscale);
shaderstate.lightcolourscale[2] *= gl_specular.value;
VectorCopy(colour, shaderstate.lightcolours);
#ifdef RTLIGHTS
VectorCopy(dl->lightcolourscales, shaderstate.lightcolourscale);
shaderstate.lightcubemap = dl->cubetexture;
#endif
shaderstate.lastuniform = 0;
lmode = 0;
#ifdef RTLIGHTS
if (((dl->flags & LFLAG_SHADOWMAP) || r_shadow_shadowmapping.ival) && GLBE_RegisterLightShader(lmode | (1u<<LSHADER_SMAP)))
lmode |= 1u<<LSHADER_SMAP;
else
GLBE_RegisterLightShader(lmode); //make sure either shadowmapping or non-shadowmapping is loaded...
if (TEXVALID(shaderstate.lightcubemap) && GLBE_RegisterLightShader(lmode | (1u<<LSHADER_CUBE)))
lmode |= 1u<<LSHADER_CUBE;
else if (dl->fov && GLBE_RegisterLightShader(lmode | (1u<<LSHADER_SPOT)))
lmode |= 1u<<LSHADER_SPOT;
#endif
shaderstate.lightmode = lmode;
return true;
}
void GLBE_Scissor(srect_t *rect)
@ -3413,7 +3440,12 @@ void GLBE_Scissor(srect_t *rect)
}
else
{
qglDisable(GL_SCISSOR_TEST);
/* qglScissor(
r_refdef.pxrect.x,
r_refdef.pxrect.y - r_refdef.pxrect.height,
r_refdef.pxrect.width,
r_refdef.pxrect.height);
*/ qglDisable(GL_SCISSOR_TEST);
if (qglDepthBoundsEXT)
qglDisable(GL_DEPTH_BOUNDS_TEST_EXT);
}
@ -3577,6 +3609,7 @@ static void DrawMeshes(void)
{
const shaderpass_t *p;
int passno;
int flags;
passno = 0;
if (shaderstate.force2d)
@ -3592,20 +3625,21 @@ static void DrawMeshes(void)
RQuantAdd(RQUANT_ENTBATCHES, 1);
}
flags = shaderstate.curshader->flags;
#ifndef FORCESTATE
if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)))
if (shaderstate.curcull != ((flags^r_refdef.flipcull) & (SHADER_CULL_FRONT|SHADER_CULL_BACK)))
#endif
{
shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK));
shaderstate.curcull = ((flags^r_refdef.flipcull) & (SHADER_CULL_FRONT|SHADER_CULL_BACK));
if (shaderstate.curcull & SHADER_CULL_FRONT)
{
qglEnable(GL_CULL_FACE);
qglCullFace(r_refdef.flipcull?GL_BACK:GL_FRONT);
qglCullFace(GL_FRONT);
}
else if (shaderstate.curcull & SHADER_CULL_BACK)
{
qglEnable(GL_CULL_FACE);
qglCullFace(r_refdef.flipcull?GL_FRONT:GL_BACK);
qglCullFace(GL_BACK);
}
else
{
@ -3637,14 +3671,6 @@ static void DrawMeshes(void)
Host_Error("Shader system is not meant to accept stencil meshes\n");
break;
#ifdef RTLIGHTS
case BEM_SMAPLIGHTSPOT:
// if (shaderstate.shader_spot->prog)
// BE_RenderMeshProgram(shaderstate.shader_spot, shaderstate.shader_spot->passes);
// break;
case BEM_SMAPLIGHT:
// if (shaderstate.shader_smap->prog)
// BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes);
// break;
case BEM_LIGHT:
if (!shaderstate.shader_light[shaderstate.lightmode])
BE_LegacyLighting();
@ -3662,12 +3688,17 @@ static void DrawMeshes(void)
BE_RenderMeshProgram(shaderstate.crepopaqueshader, shaderstate.crepopaqueshader->passes);
break;
case BEM_DEPTHONLY:
GL_DeSelectProgram();
if (shaderstate.depthonlyshader)
BE_RenderMeshProgram(shaderstate.depthonlyshader, shaderstate.depthonlyshader->passes);
else
{
GL_DeSelectProgram();
#ifdef warningmsg
#pragma warningmsg("fixme: support alpha test")
#endif
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
BE_SubmitMeshChain();
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX), 0);
BE_SubmitMeshChain();
}
break;
case BEM_FOG:
@ -3699,18 +3730,21 @@ static void DrawMeshes(void)
{
if (gl_config.arb_shader_objects)
{
char *defs[] = {NULL};
if (!shaderstate.allblackshader)
{
char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config.gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
}
GL_SelectProgram(shaderstate.allblackshader);
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
BE_EnableShaderAttributes(1u<<VATTR_LEG_VERTEX, 0);
if (shaderstate.allblackshader != shaderstate.lastuniform)
if (shaderstate.allblackshader != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
{
float m16[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
qglUniformMatrix4fvARB(qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection"), 1, false, m16);
qglUniformMatrix4fvARB(shaderstate.allblack_mvp, 1, false, m16);
}
BE_SubmitMeshChain();
@ -4065,7 +4099,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
continue;
if (batch->flags & BEF_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT)
if (shaderstate.mode == BEM_LIGHT)
continue;
if (batch->flags & BEF_NOSHADOWS)
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows.
@ -4084,7 +4118,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->shader->flags & SHADER_NODRAW)
continue;
if (batch->shader->flags & SHADER_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT)
if (shaderstate.mode == BEM_LIGHT)
continue;
if (batch->shader->flags & SHADER_SKY)
{
@ -4336,7 +4370,7 @@ void GLBE_BaseEntTextures(void)
batch_t *batches[SHADER_SORT_COUNT];
batch_t **ob = shaderstate.mbatches;
shaderstate.mbatches = batches;
BE_GenModelBatches(batches);
BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode);
GLBE_SubmitMeshes(false, SHADER_SORT_PORTAL, SHADER_SORT_DECAL);
GLBE_SelectEntity(&r_worldentity);
shaderstate.mbatches = ob;
@ -4600,7 +4634,9 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
Sh_Reset();
#endif
}
BE_GenModelBatches(batches);
//memset(batches, 0, sizeof(batches));
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD);
R_GenDlightBatches(batches);
shaderstate.curentity = &r_worldentity;
if (cl.paused || cls.state < ca_active)
@ -4684,6 +4720,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
#endif
shaderstate.curdlight = NULL;
}
else
{

View File

@ -980,7 +980,15 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
f->charheight = height;
Q_strncpyz(f->name, fontfilename, sizeof(f->name));
VectorSet(f->alttint, 1.16, 0.54, 0.41);
switch(M_GameType())
{
case MGT_QUAKE2:
VectorSet(f->alttint, 0.44, 1.0, 0.2);
break;
default:
VectorSet(f->alttint, 1.16, 0.54, 0.41);
break;
}
#ifdef DOOMWADS
if (!*fontfilename)

View File

@ -127,13 +127,16 @@ void Mod_BatchList_f(void)
{
for (batch = mod->batches[i]; batch; batch = batch->next)
{
#if MAXRLIGHTMAPS > 1
if (batch->lightmap[3] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->lightmap[2], batch->lmlightstyle[2], batch->lightmap[3], batch->lmlightstyle[3], batch->maxmeshes);
else if (batch->lightmap[2] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->lightmap[2], batch->lmlightstyle[2], batch->maxmeshes);
else if (batch->lightmap[1] >= 0)
Con_Printf("%s lm=(%i:%i %i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->lightmap[1], batch->lmlightstyle[1], batch->maxmeshes);
else if (batch->lmlightstyle[0] != 255)
else
#endif
if (batch->lmlightstyle[0] != 255)
Con_Printf("%s lm=(%i:%i) surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->lmlightstyle[0], batch->maxmeshes);
else
Con_Printf("%s lm=%i surfs=%u\n", batch->texture->shader->name, batch->lightmap[0], batch->maxmeshes);
@ -883,10 +886,11 @@ model_t *Mod_LoadModel (model_t *mod, qboolean crash)
break;
#endif
case BSPVERSION_LONG1:
Con_Printf("WARNING: %s is in a deprecated format\n", mod->name);
case 30: //hl
case 29: //q1
case 28: //prerel
case BSPVERSION_LONG1:
case BSPVERSION_LONG2:
TRACE(("Mod_LoadModel: hl/q1 bsp\n"));
if (!Mod_LoadBrushModel (mod, buf))
@ -2330,7 +2334,7 @@ qboolean Mod_LoadFaces (lump_t *l, qboolean lm, mesh_t **meshlist)
out->firstedge = LittleLong(inl->firstedge);
out->numedges = LittleLong(inl->numedges);
tn = LittleLong (inl->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
for (i=0 ; i<MAXRLIGHTMAPS ; i++)
out->styles[i] = inl->styles[i];
lofs = LittleLong(inl->lightofs);
inl++;
@ -2342,7 +2346,7 @@ qboolean Mod_LoadFaces (lump_t *l, qboolean lm, mesh_t **meshlist)
out->firstedge = LittleLong(ins->firstedge);
out->numedges = LittleShort(ins->numedges);
tn = LittleShort (ins->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
out->styles[i] = ins->styles[i];
lofs = LittleLong(ins->lightofs);
ins++;
@ -2506,7 +2510,7 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi
vbo.colours[sty].dummy = ptr;
ptr += sizeof(vec4_t)*maxverts;
}
for (; sty < MAXLIGHTMAPS; sty++)
for (; sty < MAXRLIGHTMAPS; sty++)
vbo.colours[sty].dummy = NULL;
vbo.texcoord.dummy = ptr;
ptr += sizeof(vec2_t)*maxverts;
@ -2516,7 +2520,7 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi
vbo.lmcoord[sty].dummy = ptr;
ptr += sizeof(vec2_t)*maxverts;
}
for (; sty < MAXLIGHTMAPS; sty++)
for (; sty < MAXRLIGHTMAPS; sty++)
vbo.lmcoord[sty].dummy = NULL;
vbo.normals.dummy = ptr;
ptr += sizeof(vec3_t)*maxverts;
@ -2547,7 +2551,7 @@ static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindi
//set up the arrays. the arrangement is required for the backend to optimise vbos
mesh->xyz_array = (vecV_t*)vbo.coord.dummy + mesh->vbofirstvert;
mesh->st_array = (vec2_t*)vbo.texcoord.dummy + mesh->vbofirstvert;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
if (vbo.lmcoord[sty].dummy)
mesh->lmst_array[sty] = (vec2_t*)vbo.lmcoord[sty].dummy + mesh->vbofirstvert;
@ -2629,9 +2633,11 @@ static void Mod_Batches_Generate(model_t *mod)
lbatch->lightmap[0] == surf->lightmaptexturenums[0] &&
Vector4Compare(plane, lbatch->plane) &&
lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) &&
#if MAXRLIGHTMAPS > 1
lbatch->lightmap[1] == surf->lightmaptexturenums[1] &&
lbatch->lightmap[2] == surf->lightmaptexturenums[2] &&
lbatch->lightmap[3] == surf->lightmaptexturenums[3] &&
#endif
lbatch->fog == surf->fog)
batch = lbatch;
else
@ -2643,9 +2649,11 @@ static void Mod_Batches_Generate(model_t *mod)
batch->lightmap[0] == surf->lightmaptexturenums[0] &&
Vector4Compare(plane, batch->plane) &&
batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES &&
#if MAXRLIGHTMAPS > 1
batch->lightmap[1] == surf->lightmaptexturenums[1] &&
batch->lightmap[2] == surf->lightmaptexturenums[2] &&
batch->lightmap[3] == surf->lightmaptexturenums[3] &&
#endif
batch->fog == surf->fog)
break;
}
@ -2654,9 +2662,11 @@ static void Mod_Batches_Generate(model_t *mod)
{
batch = ZG_Malloc(&loadmodel->memgroup, sizeof(*batch));
batch->lightmap[0] = surf->lightmaptexturenums[0];
#if MAXRLIGHTMAPS > 1
batch->lightmap[1] = surf->lightmaptexturenums[1];
batch->lightmap[2] = surf->lightmaptexturenums[2];
batch->lightmap[3] = surf->lightmaptexturenums[3];
#endif
batch->texture = surf->texinfo->texture;
batch->next = mod->batches[sortid];
batch->ent = &r_worldentity;
@ -2779,7 +2789,7 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
surf = (msurface_t*)batch->mesh[0];
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
batch->lightmap[sty] = surf->lightmaptexturenums[sty];
batch->lmlightstyle[sty] = surf->styles[sty];
@ -2788,7 +2798,7 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
for (j = 1; j < batch->maxmeshes; j++)
{
surf = (msurface_t*)batch->mesh[j];
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
if (surf->lightmaptexturenums[sty] != batch->lightmap[sty] ||
//fixme: we should merge later (reverted matching) surfaces into the prior batch
@ -2796,7 +2806,7 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
surf->vlstyles[sty] != batch->vtlightstyle[sty])
break;
}
if (sty < MAXLIGHTMAPS)
if (sty < MAXRLIGHTMAPS)
{
nb = ZG_Malloc(&loadmodel->memgroup, sizeof(*batch));
*nb = *batch;
@ -2805,7 +2815,7 @@ static void Mod_Batches_SplitLightmaps(model_t *mod)
nb->mesh = batch->mesh + j*2;
nb->maxmeshes = batch->maxmeshes - j;
batch->maxmeshes = j;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
nb->lightmap[sty] = surf->lightmaptexturenums[sty];
nb->lmlightstyle[sty] = surf->styles[sty];
@ -2846,9 +2856,9 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
{
surf = (msurface_t*)batch->mesh[0];
Mod_LightmapAllocSurf (&lmallocator, surf, 0);
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
for (sty = 1; sty < MAXRLIGHTMAPS; sty++)
surf->lightmaptexturenums[sty] = -1;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
{
batch->lightmap[sty] = surf->lightmaptexturenums[sty];
batch->lmlightstyle[sty] = 255;//don't do special backend rendering of lightstyles.
@ -2859,7 +2869,7 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
{
surf = (msurface_t*)batch->mesh[j];
Mod_LightmapAllocSurf (&lmallocator, surf, 0);
for (sty = 1; sty < MAXLIGHTMAPS; sty++)
for (sty = 1; sty < MAXRLIGHTMAPS; sty++)
surf->lightmaptexturenums[sty] = -1;
if (surf->lightmaptexturenums[0] != batch->lightmap[0])
{
@ -2870,7 +2880,7 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
nb->mesh = batch->mesh + j*2;
nb->maxmeshes = batch->maxmeshes - j;
batch->maxmeshes = j;
for (sty = 0; sty < MAXLIGHTMAPS; sty++)
for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
nb->lightmap[sty] = surf->lightmaptexturenums[sty];
memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes);

View File

@ -29,6 +29,7 @@ struct trace_s;
struct wedict_s;
struct model_s;
struct world_s;
struct dlight_s;
typedef enum {
SHADER_SORT_NONE,
@ -81,8 +82,8 @@ typedef struct mesh_s
vec3_t *snormals_array;/*required for rtlighting*/
vec3_t *tnormals_array;/*required for rtlighting*/
vec2_t *st_array; /*texture coords*/
vec2_t *lmst_array[MAXLIGHTMAPS]; /*second texturecoord set (merely dubbed lightmap, one for each potential lightstyle)*/
avec4_t *colors4f_array[MAXLIGHTMAPS];/*floating point colours array*/
vec2_t *lmst_array[MAXRLIGHTMAPS]; /*second texturecoord set (merely dubbed lightmap, one for each potential lightstyle)*/
avec4_t *colors4f_array[MAXRLIGHTMAPS];/*floating point colours array*/
byte_vec4_t *colors4b_array;/*byte colours array*/
index_t *indexes;
@ -115,9 +116,9 @@ typedef struct batch_s
entity_t *ent; /*used for shader properties*/
struct mfog_s *fog;
short lightmap[MAXLIGHTMAPS]; /*used for shader lightmap textures*/
unsigned char lmlightstyle[MAXLIGHTMAPS];
unsigned char vtlightstyle[MAXLIGHTMAPS];
short lightmap[MAXRLIGHTMAPS]; /*used for shader lightmap textures*/
unsigned char lmlightstyle[MAXRLIGHTMAPS];
unsigned char vtlightstyle[MAXRLIGHTMAPS];
unsigned int maxmeshes; /*not used by backend*/
unsigned int flags; /*backend flags (force transparency etc)*/
@ -262,13 +263,13 @@ typedef struct vbo_s
vboarray_t coord;
vboarray_t coord2;
vboarray_t texcoord;
vboarray_t lmcoord[MAXLIGHTMAPS];
vboarray_t lmcoord[MAXRLIGHTMAPS];
vboarray_t normals;
vboarray_t svector;
vboarray_t tvector;
vboarray_t colours[MAXLIGHTMAPS];
vboarray_t colours[MAXRLIGHTMAPS];
vboarray_t bonenums;
@ -359,15 +360,6 @@ typedef struct mfog_s
mplane_t **planes;
} mfog_t;
#if MAX_SWDECALS
typedef struct decal_s {
int xpos, ypos;
struct msurface_s *owner;
struct decal_s *next;
struct decal_s *prev;
} decal_t;
#endif
typedef struct msurface_s
{
@ -380,7 +372,7 @@ typedef struct msurface_s
short texturemins[2];
short extents[2];
unsigned short light_s[MAXLIGHTMAPS], light_t[MAXLIGHTMAPS]; // gl lightmap coordinates
unsigned short light_s[MAXRLIGHTMAPS], light_t[MAXRLIGHTMAPS]; // gl lightmap coordinates
mfog_t *fog;
mesh_t *mesh;
@ -394,19 +386,16 @@ typedef struct msurface_s
int dlightframe;
int dlightbits;
int lightmaptexturenums[MAXLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
qbyte styles[MAXLIGHTMAPS];
qbyte vlstyles[MAXLIGHTMAPS];
int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap
int lightmaptexturenums[MAXRLIGHTMAPS]; //rbsp+fbsp formats have multiple lightmaps
qbyte styles[MAXQ1LIGHTMAPS];
qbyte vlstyles[MAXRLIGHTMAPS];
int cached_light[MAXQ1LIGHTMAPS]; // values currently used in lightmap
qboolean cached_dlight; // true if dynamic light in cache
qbyte cached_colour[MAXLIGHTMAPS];
qbyte cached_colour[MAXQ1LIGHTMAPS];
#ifndef NOSTAINS
qboolean stained;
#endif
qbyte *samples; // [numstyles*surfsize]
#ifdef MAX_SWDECALS
decal_t *decal;
#endif
} msurface_t;
typedef struct mbrush_s
@ -463,12 +452,11 @@ typedef struct mleaf_s
msurface_t **firstmarksurface;
int nummarksurfaces;
int key; // BSP sequence number for leaf's contents
qbyte ambient_sound_level[NUM_AMBIENTS];
#if defined(Q2BSPS) || defined(Q3BSPS)
int cluster;
struct mleaf_s *vischain;
// struct mleaf_s *vischain;
#endif
#ifdef Q2BSPS
//it's a q2 thing

View File

@ -328,7 +328,7 @@ void R_GenDlightMesh(struct batch_s *batch)
static mesh_t *meshptr;
dlight_t *l = cl_dlights + batch->surf_first;
BE_SelectDLight(l, l->color);
BE_SelectDLight(l, l->color, LSHADER_STANDARD);
if (!R_BuildDlightMesh (l, 2, 1, true))
{
@ -1123,7 +1123,7 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -1137,7 +1137,7 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
{
lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
@ -1288,7 +1288,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
@ -1317,7 +1317,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
@ -1346,7 +1346,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING)
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;
@ -1366,7 +1366,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
else
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]]/256.0f;

View File

@ -232,28 +232,27 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod
{
if ((e->flags & Q2RF_WEAPONMODEL) && r_refdef.playerview->viewentity > 0)
{
entity_t *view = &r_refdef.playerview->viewent;
float em[16];
float vm[16];
vm[0] = view->axis[0][0];
vm[1] = view->axis[0][1];
vm[2] = view->axis[0][2];
vm[0] = r_refdef.playerview->vw_axis[0][0];
vm[1] = r_refdef.playerview->vw_axis[0][1];
vm[2] = r_refdef.playerview->vw_axis[0][2];
vm[3] = 0;
vm[4] = view->axis[1][0];
vm[5] = view->axis[1][1];
vm[6] = view->axis[1][2];
vm[4] = r_refdef.playerview->vw_axis[1][0];
vm[5] = r_refdef.playerview->vw_axis[1][1];
vm[6] = r_refdef.playerview->vw_axis[1][2];
vm[7] = 0;
vm[8] = view->axis[2][0];
vm[9] = view->axis[2][1];
vm[10] = view->axis[2][2];
vm[8] = r_refdef.playerview->vw_axis[2][0];
vm[9] = r_refdef.playerview->vw_axis[2][1];
vm[10] = r_refdef.playerview->vw_axis[2][2];
vm[11] = 0;
vm[12] = view->origin[0];
vm[13] = view->origin[1];
vm[14] = view->origin[2];
vm[12] = r_refdef.playerview->vw_origin[0];
vm[13] = r_refdef.playerview->vw_origin[1];
vm[14] = r_refdef.playerview->vw_origin[2];
vm[15] = 1;
em[0] = e->axis[0][0];
@ -425,13 +424,7 @@ void R_SetupGL (float stereooffset)
if (r_refdef.useperspective)
{
int stencilshadows = 0;
#ifdef RTLIGHTS
stencilshadows |= r_shadow_realtime_dlight.ival && r_shadow_realtime_dlight_shadows.ival;
stencilshadows |= r_shadow_realtime_world.ival && r_shadow_realtime_world_shadows.ival;
//if (r_shadow_shadowmapping.ival)
stencilshadows = false;
#endif
int stencilshadows = Sh_StencilShadowsActive();
if ((!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp)
{
@ -827,7 +820,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype)
{
case 1: /*fbo explicit mirror (fucked depth, working clip plane)*/
//fixme: pvs is surely wrong?
r_refdef.flipcull ^= true;
r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane);
break;
@ -896,7 +889,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype)
}
else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin))
{
r_refdef.flipcull ^= true;
r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane);
}
else
@ -1324,6 +1317,11 @@ void GLR_RenderView (void)
if (!r_worldentity.model || !cl.worldmodel)
{
GL_DoSwap();
GL_Set2D (false);
R2D_ImageColours(0, 0, 0, 1);
R2D_FillBlock(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height);
R2D_ImageColours(1, 1, 1, 1);
return;
}
// Sys_Error ("R_RenderView: NULL worldmodel");

View File

@ -487,7 +487,7 @@ R_NewMap
void GLR_NewMap (void)
{
char namebuf[MAX_QPATH];
extern cvar_t host_mapname, r_shadow_realtime_dlight, r_shadow_realtime_world;
extern cvar_t host_mapname;
int i;
for (i=0 ; i<256 ; i++)
@ -543,7 +543,10 @@ TRACE(("dbg: GLR_NewMap: tp\n"));
void GLR_PreNewMap(void)
{
r_loadbumpmapping = r_deluxemapping.ival || r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival || r_glsl_offsetmapping.ival;
r_loadbumpmapping = r_deluxemapping.ival || r_glsl_offsetmapping.ival;
#ifdef RTLIGHTS
r_loadbumpmapping |= r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival;
#endif
r_viewleaf = NULL;
r_oldviewleaf = NULL;
r_viewleaf2 = NULL;

View File

@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void GLBE_ClearVBO(vbo_t *vbo)
{
int vboh[6 + MAXLIGHTMAPS];
int vboh[6 + MAXRLIGHTMAPS];
int i, j;
vboh[0] = vbo->indicies.gl.vbo;
vboh[1] = vbo->coord.gl.vbo;
@ -36,7 +36,7 @@ void GLBE_ClearVBO(vbo_t *vbo)
vboh[3] = vbo->normals.gl.vbo;
vboh[4] = vbo->svector.gl.vbo;
vboh[5] = vbo->tvector.gl.vbo;
for (i = 0; i < MAXLIGHTMAPS; i++)
for (i = 0; i < MAXRLIGHTMAPS; i++)
vboh[6+i] = vbo->lmcoord[i].gl.vbo;
for (i = 0; i < 7; i++)
@ -90,7 +90,7 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
vbo->texcoord.gl.addr = (vec2_t*)((char*)vbo->texcoord.gl.addr - (char*)vdata);
vaostatic |= VATTR_TEXCOORD;
}
for (s = 0; s < MAXLIGHTMAPS; s++)
for (s = 0; s < MAXRLIGHTMAPS; s++)
{
if (vbo->colours[s].gl.addr)
{
@ -99,9 +99,11 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
switch(s)
{
default: vaostatic |= VATTR_COLOUR; break;
#if MAXRLIGHTMAPS > 1
case 1: vaostatic |= VATTR_COLOUR2; break;
case 2: vaostatic |= VATTR_COLOUR3; break;
case 3: vaostatic |= VATTR_COLOUR4; break;
#endif
}
}
if (vbo->lmcoord[s].gl.addr)
@ -111,9 +113,11 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
switch(s)
{
default: vaostatic |= VATTR_LMCOORD; break;
#if MAXRLIGHTMAPS > 1
case 1: vaostatic |= VATTR_LMCOORD2; break;
case 2: vaostatic |= VATTR_LMCOORD3; break;
case 3: vaostatic |= VATTR_LMCOORD4; break;
#endif
}
}
}
@ -176,11 +180,11 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
vecV_t *coord;
vec2_t *texcoord;
vec2_t *lmcoord[MAXLIGHTMAPS];
vec2_t *lmcoord[MAXRLIGHTMAPS];
vec3_t *normals;
vec3_t *svector;
vec3_t *tvector;
vec4_t *colours[MAXLIGHTMAPS];
vec4_t *colours[MAXRLIGHTMAPS];
index_t *indicies;
batch_t *batch;
int vbosize;
@ -224,14 +228,14 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
vbo->texcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
for (s = 0; s < lightmaps; s++)
vbo->lmcoord[s].gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
for (; s < MAXLIGHTMAPS; s++)
for (; s < MAXRLIGHTMAPS; s++)
vbo->lmcoord[s].gl.addr = NULL;
vbo->normals.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->svector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->tvector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
for (s = 0; s < lightmaps; s++)
vbo->colours[s].gl.addr = allocbuf(&p, maxvboverts, sizeof(vec4_t));
for (; s < MAXLIGHTMAPS; s++)
for (; s < MAXRLIGHTMAPS; s++)
vbo->lmcoord[s].gl.addr = NULL;
vbosize = (char*)p - (char*)vbo->coord.gl.addr;
if ((char*)p - (char*)vbo->vertdata > (maxvboverts+1)*pervertsize)
@ -240,7 +244,7 @@ void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch
coord = vbo->coord.gl.addr;
texcoord = vbo->texcoord.gl.addr;
for (s = 0; s < MAXLIGHTMAPS; s++)
for (s = 0; s < MAXRLIGHTMAPS; s++)
{
lmcoord[s] = vbo->lmcoord[s].gl.addr;
colours[s] = vbo->colours[s].gl.addr;

View File

@ -72,8 +72,9 @@ void GLSCR_UpdateScreen (void)
if (scr_disabled_for_loading)
{
extern float scr_disabled_time;
if (Sys_DoubleTime() - scr_disabled_time > 60 || key_dest != key_game)
if (Sys_DoubleTime() - scr_disabled_time > 60 || !Key_Dest_Has(~kdm_game))
{
//FIXME: instead of reenabling the screen, we should just draw the relevent things skipping only the game.
scr_disabled_for_loading = false;
}
else
@ -115,7 +116,7 @@ void GLSCR_UpdateScreen (void)
#endif
R2D_BrightenScreen();
if (key_dest == key_console)
if (key_dest_mask & kdm_console)
Con_DrawConsole(vid.height/2, false);
GL_EndRendering ();
GL_DoSwap();
@ -199,7 +200,9 @@ void GLSCR_UpdateScreen (void)
RSpeedEnd(RSPEED_TOTALREFRESH);
RSpeedShow();
RSpeedRemark();
GL_EndRendering ();
RSpeedEnd(RSPEED_FINISH);
}

View File

@ -915,9 +915,10 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
"#define LIGHTSTYLED\n",
NULL
};
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + 64 + 1];
#define MAXMODIFIERS 64
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + MAXMODIFIERS + 1];
unsigned int nopermutation = ~0u;
int nummodifiers;
int nummodifiers = 0;
int p, n, pn;
char *end;
@ -941,6 +942,26 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
script++;
if (!strncmp(script, "!!fixed", 7))
prog->nofixedcompat = false;
else if (!strncmp(script, "!!cvardf", 8))
{
script += 8;
while (*script == ' ' || *script == '\t')
script++;
end = script;
while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_')
end++;
if (nummodifiers < MAXMODIFIERS && end - script < 64)
{
cvar_t *var;
char namebuf[64];
memcpy(namebuf, script, end - script);
namebuf[end - script] = 0;
var = Cvar_Get(namebuf, "0", CVAR_SHADERSYSTEM, "GLSL Variables");
if (var)
permutationdefines[nummodifiers++] = Z_StrDup(va("#define %s %g\n", namebuf, var->value));
}
script = end;
}
else if (!strncmp(script, "!!cvarf", 7))
{
script += 7;
@ -1024,18 +1045,20 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
break;
};
nummodifiers = 0;
if (gl_specular.value)
permutationdefines[nummodifiers++] = strdup("#define SPECULAR\n");
{
if (nummodifiers < MAXMODIFIERS)
permutationdefines[nummodifiers++] = Z_StrDup("#define SPECULAR\n");
}
for (end = strchr(name, '#'); end && *end; )
{
char *start = end+1;
end = strchr(start, '#');
if (!end)
end = start + strlen(start);
if (nummodifiers < 64)
if (nummodifiers < MAXMODIFIERS)
{
permutationdefines[nummodifiers] = malloc(10 + end - start);
permutationdefines[nummodifiers] = BZ_Malloc(10 + end - start);
memcpy(permutationdefines[nummodifiers], "#define ", 8);
memcpy(permutationdefines[nummodifiers]+8, start, end - start);
memcpy(permutationdefines[nummodifiers]+8+(end-start), "\n", 2);
@ -1108,7 +1131,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
#endif
}
while(nummodifiers)
free(permutationdefines[--nummodifiers]);
Z_Free(permutationdefines[--nummodifiers]);
Shader_ProgAutoFields(prog, cvarnames, cvartypes);
@ -1588,7 +1611,7 @@ void Shader_WriteOutGenerics_f(void)
struct shader_field_names_s shader_attr_names[] =
{
/*vertex attributes*/
{"v_position", VATTR_VERTEX1},
{"v_position1", VATTR_VERTEX1},
{"v_position2", VATTR_VERTEX2},
{"v_colour", VATTR_COLOUR},
{"v_texcoord", VATTR_TEXCOORD},
@ -1598,9 +1621,16 @@ struct shader_field_names_s shader_attr_names[] =
{"v_tvector", VATTR_TNORMALS},
{"v_bone", VATTR_BONENUMS},
{"v_weight", VATTR_BONEWEIGHTS},
#if MAXRLIGHTMAPS > 1
{"v_lmcoord1", VATTR_LMCOORD},
{"v_lmcoord2", VATTR_LMCOORD2},
{"v_lmcoord3", VATTR_LMCOORD3},
{"v_lmcoord4", VATTR_LMCOORD4},
{"v_colour1", VATTR_COLOUR},
{"v_colour2", VATTR_COLOUR2},
{"v_colour3", VATTR_COLOUR3},
{"v_colour4", VATTR_COLOUR4},
#endif
{NULL}
};
@ -1641,9 +1671,9 @@ struct shader_field_names_s shader_unif_names[] =
{"l_lightcolour", SP_LIGHTCOLOUR},
{"l_lightposition", SP_LIGHTPOSITION},
{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},
{"l_projmatrix", SP_LIGHTPROJMATRIX},
{"l_cubematrix", SP_LIGHTCUBEMATRIX},
{"l_shadowmapinfo", SP_LIGHTSHADOWMAPINFO},
{"l_shadowmapproj", SP_LIGHTSHADOWMAPPROJ},
{"l_shadowmapscale", SP_LIGHTSHADOWMAPSCALE},
{"e_rendertexturescale", SP_RENDERTEXTURESCALE},
{NULL}

View File

@ -33,26 +33,44 @@ static void SHM_Shutdown(void);
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
#define nearplane (4)
static texid_t shadowmap[2];
static int shadow_fbo_id;
static int shadow_fbo_depth_num;
static int crepuscular_fbo_id;
texid_t crepuscular_texture_id;
shader_t *crepuscular_shader;
cvar_t r_shadow_shadowmapping_nearclip = CVAR("r_shadow_shadowmapping_nearclip", "1");
cvar_t r_shadow_shadowmapping_bias = CVAR("r_shadow_shadowmapping_bias", "0.03");
cvar_t r_shadow_scissor = CVAR("r_shadow_scissor", "1");
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
#ifdef FTE_TARGET_WEB
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE);
#else
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
#endif
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_ambient = SCVAR ("r_shadow_realtime_dlight_ambient", "0");
cvar_t r_shadow_realtime_dlight_diffuse = SCVAR ("r_shadow_realtime_dlight_diffuse", "1");
cvar_t r_shadow_realtime_dlight_specular = SCVAR ("r_shadow_realtime_dlight_specular", "4"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_editlights_import_radius = SCVAR ("r_editlights_import_radius", "1");
cvar_t r_editlights_import_ambient = SCVAR ("r_editlights_import_ambient", "0");
cvar_t r_editlights_import_diffuse = SCVAR ("r_editlights_import_diffuse", "1");
cvar_t r_editlights_import_specular = SCVAR ("r_editlights_import_specular", "1"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0);
cvar_t r_shadow_shadowmapping_precision = CVARD ("r_shadow_shadowmapping_precision", "1", "Scales the shadowmap detail level up or down.");
extern cvar_t r_shadow_shadowmapping_nearclip;
extern cvar_t r_shadow_shadowmapping_bias;
cvar_t r_sun_dir = CVARD ("r_sun_dir", "0.2 0.5 0.8", "Specifies the direction that crepusular rays appear along");
cvar_t r_sun_colour = CVARFD ("r_sun_colour", "0 0 0", CVAR_ARCHIVE, "Specifies the colour of sunlight that appears in the form of crepuscular rays.");
static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour);
static struct {
int numlights;
int shadowsurfcount;
int numfrustumculled;
int numpvsculled;
int numscissorculled;
} bench;
/*
called on framebuffer resize.
@ -65,6 +83,7 @@ void Sh_Reset(void)
{
qglDeleteRenderbuffersEXT(1, &shadow_fbo_id);
shadow_fbo_id = 0;
shadow_fbo_depth_num = 0;
}
if (shadowmap[0].num)
{
@ -107,9 +126,9 @@ typedef struct shadowmesh_s
{
enum
{
SMT_STENCILVOLUME,
SMT_SHADOWLESS,
SMT_SURFACES
SMT_STENCILVOLUME, //build edges mesh (and surface list)
SMT_SHADOWMAP, //build front faces mesh (and surface list)
SMT_SHADOWLESS //build surface list only
} type;
unsigned int numindicies;
unsigned int maxindicies;
@ -196,6 +215,44 @@ static void SHM_Vertex3fv (const float *v)
}
}
static void SHM_MeshFrontOnly(int numverts, vecV_t *verts, int numidx, index_t *idx)
{
int first = sh_shmesh->numverts;
int v, i;
vecV_t *outv;
index_t *outi;
/*make sure there's space*/
v = (sh_shmesh->numverts+numverts + inc)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxverts < v)
{
v += 1024;
sh_shmesh->maxverts = v;
sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, v * sizeof(*sh_shmesh->verts));
}
outv = sh_shmesh->verts + sh_shmesh->numverts;
for (v = 0; v < numverts; v++)
{
VectorCopy(verts[v], outv[v]);
}
v = (sh_shmesh->numindicies+numidx + inc)&~(inc-1); //and a bit of padding
if (sh_shmesh->maxindicies < v)
{
v += 1024;
sh_shmesh->maxindicies = v;
sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies));
}
outi = sh_shmesh->indicies + sh_shmesh->numindicies;
for (i = 0; i < numidx; i++)
{
outi[i] = first + idx[i];
}
sh_shmesh->numverts += numverts;
sh_shmesh->numindicies += numidx;
}
static void SHM_TriangleFan(int numverts, vecV_t *verts, vec3_t lightorg, float pd)
{
int v, i, idxs;
@ -292,6 +349,8 @@ static void SH_FreeShadowMesh_(shadowmesh_t *sm)
sm->indicies = NULL;
Z_Free(sm->verts);
sm->verts = NULL;
sm->numindicies = 0;
sm->numverts = 0;
switch (qrenderer)
{
@ -381,7 +440,7 @@ static void SHM_BeginShadowMesh(dlight_t *dl, int type)
{
/*this shouldn't happen too often*/
if (sh_shmesh)
{
{ //FIXME: if the light is the same light, reuse the memory allocations where possible...
SH_FreeShadowMesh(sh_shmesh);
}
@ -628,6 +687,11 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
if ((s*s+t*t+dot*dot) < maxdist)
{
SHM_Shadow_Cache_Surface(surf);
if (sh_shmesh->type == SMT_SHADOWMAP)
{
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
continue;
}
if (sh_shmesh->type != SMT_STENCILVOLUME)
continue;
@ -977,7 +1041,10 @@ static void SHM_RecursiveWorldNodeQ3_r (dlight_t *dl, mnode_t *node)
continue;
surf->shadowframe = sh_shadowframe;
//FIXME: radius check
SHM_Shadow_Cache_Surface(surf);
if (sh_shmesh->type == SMT_SHADOWMAP)
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
}
return;
}
@ -1314,8 +1381,23 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
else*/
{
SHM_BeginShadowMesh(dl, type);
#if 0
{
int i;
msurface_t *surf;
for (i = 0; i < cl.worldmodel->numsurfaces; i+=2)
{
surf = &cl.worldmodel->surfaces[i];
SHM_Shadow_Cache_Surface(surf);
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
}
memset(sh_shmesh->litleaves, 0xff, sh_shmesh->leafbytes);
}
#else
SHM_MarkLeavesQ1(dl, lvis);
SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes);
#endif
}
break;
#ifdef Q2BSPS
@ -1328,11 +1410,26 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
#ifdef Q3BSPS
case fg_quake3:
/*q3 doesn't have edge info*/
SHM_BeginShadowMesh(dl, true);
SHM_BeginShadowMesh(dl, type);
#if 0
{
int i;
msurface_t *surf;
for (i = 0; i < cl.worldmodel->numsurfaces; i++)
{
surf = &cl.worldmodel->surfaces[i];
SHM_Shadow_Cache_Surface(surf);
SHM_MeshFrontOnly(surf->mesh->numvertexes, surf->mesh->xyz_array, surf->mesh->numindexes, surf->mesh->indexes);
}
memset(sh_shmesh->litleaves, 0xff, sh_shmesh->leafbytes);
}
#else
sh_shadowframe++;
SHM_RecursiveWorldNodeQ3_r(dl, cl.worldmodel->nodes);
if (type == SMT_STENCILVOLUME)
SHM_ComposeVolume_BruteForce(dl);
#endif
break;
#endif
default:
@ -1342,11 +1439,6 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
/*generate edge polys for map types that need it (q1/q2)*/
switch (type)
{
case SMT_SURFACES:
{
}
break;
case SMT_STENCILVOLUME:
SHM_BeginQuads();
while(firstedge)
@ -1597,8 +1689,12 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, srect_t *r)
r->height = 1;
r->dmin = 0;
r->dmax = 1;
if (0)//!r_shadow_scissor.integer)
if (!r_shadow_scissor.ival)
{
r->x = 0;
r->y = 0;
r->width = 1;
r->height = 1;
return false;
}
/*if view is inside the box, then skip this maths*/
@ -1928,8 +2024,12 @@ void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo_id);
if (TEXVALID(depthtexture))
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthtexture.num, 0);
if (shadow_fbo_depth_num != depthtexture.num)
{
shadow_fbo_depth_num = depthtexture.num;
if (TEXVALID(depthtexture))
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthtexture.num, 0);
}
}
}
#endif
@ -1946,9 +2046,37 @@ void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize)
}
}
//determine the 5 bounding points of a shadowmap light projection side
static void Sh_LightFrustumPlanes(dlight_t *l, vec4_t *planes, int face)
{
vec3_t tmp;
int axis0, axis1, axis2;
int dir;
int i;
//+x,+y,+z,-x,-y,-z
axis0 = (face+0)%3; //our major axis
axis1 = (face+1)%3;
axis2 = (face+2)%3;
dir = (face >= 3)?-1:1;
//center point is always the same
VectorCopy(l->origin, planes[4]);
VectorScale(l->axis[axis0], dir, planes[4]);
VectorNormalize(planes[4]);
planes[4][3] = r_shadow_shadowmapping_nearclip.value + DotProduct(planes[4], l->origin);
for (i = 0; i < 4; i++)
{
VectorScale(l->axis[axis0], dir, tmp);
VectorMA(tmp, ((i&1)?1:-1), l->axis[axis1], tmp);
VectorMA(tmp, ((i&2)?1:-1), l->axis[axis2], planes[i]);
VectorNormalize(planes[i]);
planes[i][3] = DotProduct(planes[i], l->origin);
}
}
static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, int smsize, float proj[16])
{
qboolean oxv;
vec3_t t1,t2;
texture_t *tex;
int tno;
@ -1959,21 +2087,21 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, int sms
case 0:
//+x - forward
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[0], l->axis[1], l->axis[2], l->origin);
r_refdef.flipcull = false;
r_refdef.flipcull = 0;
break;
case 1:
//+y - right
VectorNegate(l->axis[0], t1);
VectorNegate(l->axis[1], t2);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t2, t1, l->axis[2], l->origin);
r_refdef.flipcull = true;
r_refdef.flipcull = SHADER_CULL_FLIP;
break;
case 2:
//+z - down
VectorNegate(l->axis[0], t1);
VectorNegate(l->axis[2], t2);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t2, l->axis[1], t1, l->origin);
r_refdef.flipcull = true;
r_refdef.flipcull = SHADER_CULL_FLIP;
break;
case 3:
//-x - back
@ -1981,20 +2109,20 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, int sms
// VectorNegate(l->axis[1], t2);
// VectorNegate(l->axis[2], t3);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t1, l->axis[1], l->axis[2], l->origin);
r_refdef.flipcull = true;
r_refdef.flipcull = SHADER_CULL_FLIP;
break;
case 4:
//-y - left
VectorNegate(l->axis[1], t1);
VectorNegate(l->axis[0], t2);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[1], t2, l->axis[2], l->origin);
r_refdef.flipcull = false;
r_refdef.flipcull = 0;
break;
case 5:
//-z - up
VectorNegate(l->axis[0], t2);
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[2], l->axis[1], t2, l->origin);
r_refdef.flipcull = false;
r_refdef.flipcull = 0;
break;
}
@ -2005,8 +2133,6 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, int sms
qglViewport ((face%3 * SHADOWMAP_SIZE) + (SHADOWMAP_SIZE-smsize)/2, ((face>=3)*SHADOWMAP_SIZE) + (SHADOWMAP_SIZE-smsize)/2, smsize, smsize);
}
//fixme
GL_CullFace(0);
R_SetFrustum(proj, r_refdef.m_view);
#ifdef DBG_COLOURNOTDEPTH
@ -2014,15 +2140,16 @@ GL_CullFace(0);
#else
BE_SelectMode(BEM_DEPTHONLY);
#endif
/*shadow meshes are always drawn as an external view*/
oxv = r_refdef.externalview;
r_refdef.externalview = true;
BE_SelectEntity(&r_worldentity);
GL_CullFace(SHADER_CULL_FRONT);
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
GLBE_RenderShadowBuffer(smesh->numverts, smesh->vebo[0], NULL, smesh->numindicies, smesh->vebo[1], NULL);
{
GLBE_RenderShadowBuffer(smesh->numverts, smesh->vebo[0], smesh->verts, smesh->numindicies, smesh->vebo[1], smesh->indicies);
}
else
#endif
{
@ -2055,8 +2182,6 @@ GL_CullFace(0);
break;
}
r_refdef.externalview = oxv;
/*
{
int i;
@ -2083,14 +2208,57 @@ GL_CullFace(0);
*/
}
void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
qboolean Sh_GenShadowMap (dlight_t *l, qbyte *lvis, int smsize)
{
int f;
int smsize = SHADOWMAP_SIZE;
float oproj[16], oview[16];
shadowmesh_t *smesh;
int isspot = (l->fov != 0);
extern cvar_t temp1;
extern cvar_t r_shadow_shadowmapping_precision;
int sidevisible;
int oldflip = r_refdef.flipcull;
int oldexternalview = r_refdef.externalview;
if (!R_CullSphere(l->origin, 0))
sidevisible = l->fov?1:0x3f; //assume all are visible if the central point is onscreen
else
{
sidevisible = 0;
//FIXME: if the fov is < 90, we need to clip by the near lightplane first
for (f = 0; f < (l->fov?1:6); f++)
{
vec4_t planes[5];
float dist;
int fp,lp;
Sh_LightFrustumPlanes(l, planes, f);
for (fp = 0; fp < FRUSTUMPLANES; fp++)
{
vec3_t nearest;
//make a guess based upon the frustum plane
VectorMA(l->origin, l->radius, frustum[fp].normal, nearest);
//clip that point to the various planes
for(lp = 0; lp < 5; lp++)
{
dist = DotProduct(nearest, planes[lp]) - planes[lp][3];
if (dist < 0)
VectorMA(nearest, dist, planes[lp], nearest);
}
// P_RunParticleEffect(nearest, vec3_origin, 15, 1);
//give up if the best point for any frustum plane is offscreen
dist = DotProduct(frustum[fp].normal, nearest) - frustum[fp].dist;
if (dist <= 0)
break;
}
if (fp == FRUSTUMPLANES)
sidevisible |= 1u<<f;
}
}
//if nothing is visible, then there's no point generating any shadowmaps at all...
if (!sidevisible)
return false;
if (!TEXVALID(shadowmap[isspot]))
{
@ -2099,7 +2267,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap2dspot***", SHADOWMAP_SIZE, SHADOWMAP_SIZE, 0);
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
#ifdef DBG_COLOURNOTDEPTH
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SHADOWMAP_SIZE, SHADOWMAP_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_ARB, SHADOWMAP_SIZE, SHADOWMAP_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
#endif
@ -2109,7 +2277,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap2dcube***", SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0);
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
#ifdef DBG_COLOURNOTDEPTH
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize*3, smsize*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
#endif
@ -2133,12 +2301,11 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
smesh = SHM_BuildShadowMesh(l, lvis, NULL, true);
smsize = bound(16, temp1.ival, SHADOWMAP_SIZE);
/*set framebuffer*/
GL_BeginRenderBuffer_DepthOnly(shadowmap[isspot]);
GLBE_SetupForShadowMap(shadowmap[isspot], isspot?smsize:smsize*3, isspot?smsize:smsize*2, (smsize-4) / (float)SHADOWMAP_SIZE);
BE_Scissor(NULL);
qglViewport(0, 0, smsize*3, smsize*2);
qglClear (GL_DEPTH_BUFFER_BIT);
#ifdef DBG_COLOURNOTDEPTH
@ -2148,35 +2315,27 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
memcpy(oproj, r_refdef.m_projection, sizeof(oproj));
memcpy(oview, r_refdef.m_view, sizeof(oview));
if (l->fov)
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, l->fov, l->fov, nearplane, l->radius);
if (!gl_config.nofixedfunc)
{
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
}
/*single face*/
Sh_GenShadowFace(l, smesh, 0, smsize, r_refdef.m_projection);
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, l->fov?l->fov:90, l->fov?l->fov:90, r_shadow_shadowmapping_nearclip.value, l->radius);
if (!gl_config.nofixedfunc)
{
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
}
else
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, 90, 90, nearplane, l->radius);
if (!gl_config.nofixedfunc)
{
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
}
/*generate faces*/
for (f = 0; f < 6; f++)
r_refdef.externalview = true; //never any viewmodels
/*generate faces*/
for (f = 0; f < 6; f++)
{
if (sidevisible & (1u<<f))
{
RQuantAdd(RQUANT_SHADOWSIDES, 1);
Sh_GenShadowFace(l, smesh, f, smsize, r_refdef.m_projection);
}
}
/*end framebuffer*/
GL_EndRenderBuffer_DepthOnly(shadowmap[isspot], smsize);
@ -2193,7 +2352,11 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
qglViewport(r_refdef.pxrect.x, vid.pixelheight - r_refdef.pxrect.y, r_refdef.pxrect.width, r_refdef.pxrect.height);
r_refdef.flipcull = oldflip;
r_refdef.externalview = oldexternalview;
R_SetFrustum(r_refdef.m_projection, r_refdef.m_view);
return true;
}
static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
@ -2202,10 +2365,11 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
qbyte *lvis;
qbyte lvisb[MAX_MAP_LEAFS/8];
srect_t rect;
int smsize;
if (R_CullSphere(l->origin, l->radius))
{
bench.numfrustumculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_FRUSTUM, 1);
return; //this should be the more common case
}
@ -2219,7 +2383,7 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
if (Sh_ScissorForBox(mins, maxs, &rect))
{
bench.numscissorculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_SCISSOR, 1);
return;
}
@ -2231,8 +2395,8 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
//fixme: check head node first?
if (!Sh_LeafInView(l->worldshadowmesh->litleaves, vvis))
{
bench.numpvsculled++;
return;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return;
}
}
else
@ -2242,7 +2406,7 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
bench.numpvsculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return;
}
}
@ -2250,19 +2414,37 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
else
lvis = NULL;
BE_Scissor(NULL);
Sh_GenShadowMap(l, lvis);
if (l->fov != 0)
smsize = SHADOWMAP_SIZE;
else
{
//Stolen from DP. Actually, LH pasted it to me in IRC.
vec3_t nearestpoint;
vec3_t d;
float distance, lodlinear;
nearestpoint[0] = bound(l->origin[0]-l->radius, r_origin[0], l->origin[0]+l->radius);
nearestpoint[1] = bound(l->origin[1]-l->radius, r_origin[1], l->origin[1]+l->radius);
nearestpoint[2] = bound(l->origin[2]-l->radius, r_origin[2], l->origin[2]+l->radius);
VectorSubtract(nearestpoint, r_origin, d);
distance = VectorLength(d);
lodlinear = (l->radius * r_shadow_shadowmapping_precision.value) / sqrt(max(1.0f, distance / l->radius));
smsize = bound(16, lodlinear, SHADOWMAP_SIZE);
}
bench.numlights++;
if (!BE_SelectDLight(l, colour, l->fov?LSHADER_SPOT:LSHADER_SMAP))
return; //can't get a shader loaded
if (!Sh_GenShadowMap(l, lvis, smsize))
return;
RQuantAdd(RQUANT_RTLIGHT_DRAWN, 1);
//may as well use scissors
BE_Scissor(&rect);
BE_SelectEntity(&r_worldentity);
GLBE_SelectDLight(l, colour);
BE_SelectMode(l->fov?BEM_SMAPLIGHTSPOT:BEM_SMAPLIGHT);
BE_SelectMode(BEM_LIGHT);
Sh_DrawEntLighting(l, colour);
}
@ -2322,7 +2504,9 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
tex = cl.worldmodel->shadowbatches[tno].tex;
if (tex->shader->flags & SHADER_NODLIGHT)
continue;
//FIXME: it may be worth building a dedicated ebo
BE_DrawMesh_List(tex->shader, sm->batches[tno].count, sm->batches[tno].s, cl.worldmodel->shadowbatches[tno].vbo, &tex->shader->defaulttextures, 0);
RQuantAdd(RQUANT_LITFACES, sm->batches[tno].count);
}
switch(qrenderer)
@ -2504,10 +2688,9 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
if (ent->flags & (RF_NOSHADOW|Q2RF_BEAM))
continue;
{
if (ent->keynum == dl->key && ent->keynum)
continue;
}
if (ent->keynum == dl->key && ent->keynum)
continue;
if (!ent->model)
continue;
@ -2553,7 +2736,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
if (R_CullSphere(dl->origin, dl->radius))
{
bench.numfrustumculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_FRUSTUM, 1);
return false; //this should be the more common case
}
@ -2570,7 +2753,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
//fixme: check head node first?
if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis))
{
bench.numpvsculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return false;
}
lvis = NULL;
@ -2582,7 +2765,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
bench.numpvsculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return false;
}
}
@ -2590,12 +2773,12 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
//sets up the gl scissor (and culls to view)
if (Sh_ScissorForBox(mins, maxs, &rect))
{
bench.numscissorculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_SCISSOR, 1);
return false; //this doesn't cull often.
}
bench.numlights++;
RQuantAdd(RQUANT_RTLIGHT_DRAWN, 1);
BE_SelectDLight(dl, colour);
BE_SelectDLight(dl, colour, LSHADER_STANDARD);
BE_SelectMode(BEM_STENCIL);
//The backend doesn't maintain scissor state.
@ -2786,7 +2969,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
if (R_CullSphere(dl->origin, dl->radius))
{
bench.numfrustumculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_FRUSTUM, 1);
return; //this should be the more common case
}
@ -2795,7 +2978,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
//fixme: check head node first?
if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis))
{
bench.numpvsculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return;
}
}
@ -2812,7 +2995,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
bench.numpvsculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
return;
}
}
@ -2829,16 +3012,16 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
//sets up the gl scissor (actually just culls to view)
if (Sh_ScissorForBox(mins, maxs, &rect))
{
bench.numscissorculled++;
RQuantAdd(RQUANT_RTLIGHT_CULL_SCISSOR, 1);
return; //was culled.
}
//should we actually scissor here? there's not really much point I suppose.
BE_Scissor(NULL);
bench.numlights++;
RQuantAdd(RQUANT_RTLIGHT_DRAWN, 1);
BE_SelectDLight(dl, colour);
BE_SelectDLight(dl, colour, LSHADER_STANDARD);
BE_SelectMode(BEM_LIGHT);
Sh_DrawEntLighting(dl, colour);
}
@ -2918,7 +3101,7 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
GLBE_RenderToTexture(r_nulltex, r_nulltex, crepuscular_texture_id, r_nulltex, false);
BE_SelectMode(BEM_CREPUSCULAR);
BE_SelectDLight(dl, colours);
BE_SelectDLight(dl, colours, LSHADER_STANDARD);
GLBE_SubmitMeshes(true, SHADER_SORT_PORTAL, SHADER_SORT_BLEND);
GLBE_RenderToTexture(crepuscular_texture_id, r_nulltex, r_nulltex, r_nulltex, false);
@ -2949,7 +3132,7 @@ void Sh_PreGenerateLights(void)
{
unsigned int ignoreflags;
dlight_t *dl;
qboolean shadow;
int shadowtype;
int leaf;
qbyte *lvis;
qbyte lvisb[MAX_MAP_LEAFS/8];
@ -2957,7 +3140,8 @@ void Sh_PreGenerateLights(void)
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
{
R_LoadRTLights();
if (rtlights_first == rtlights_max)
R_LoadRTLights();
if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
}
@ -2966,25 +3150,34 @@ void Sh_PreGenerateLights(void)
for (dl = cl_dlights+rtlights_first, i=rtlights_first; i<rtlights_max; i++, dl++)
{
if (!dl->radius)
continue; //dead
if (dl->radius)
{
if (dl->flags & ignoreflags)
{
if (dl->flags & LFLAG_CREPUSCULAR)
continue;
if (!(dl->flags & ignoreflags))
continue;
if (((!dl->die)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
shadowtype = SMT_SHADOWLESS;
else if (dl->flags & LFLAG_SHADOWMAP || r_shadow_shadowmapping.ival)
shadowtype = SMT_SHADOWMAP;
else
shadowtype = SMT_STENCILVOLUME;
if (dl->flags & LFLAG_CREPUSCULAR)
continue;
else if (((!dl->die)?!r_shadow_realtime_world_shadows.ival:!r_shadow_realtime_dlight_shadows.ival) || dl->flags & LFLAG_NOSHADOWS)
shadow = false;
else if (dl->flags & LFLAG_SHADOWMAP)
shadow = false;
else
shadow = true;
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin);
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
SHM_BuildShadowMesh(dl, lvis, NULL, shadowtype);
continue;
}
}
SHM_BuildShadowMesh(dl, lvis, NULL, !shadow);
if (dl->worldshadowmesh)
{
SH_FreeShadowMesh(dl->worldshadowmesh);
dl->worldshadowmesh = NULL;
dl->rebuildcache = true;
}
}
}
@ -3004,10 +3197,6 @@ void Sh_DrawLights(qbyte *vis)
dlight_t *dl;
int i;
unsigned int ignoreflags;
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_dlight;
extern cvar_t r_shadow_realtime_world_shadows, r_shadow_realtime_dlight_shadows;
extern cvar_t r_sun_dir, r_sun_colour;
extern cvar_t r_shadow_shadowmapping;
if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival)
{
@ -3149,3 +3338,41 @@ void Sh_DrawLights(qbyte *vis)
// memset(&bench, 0, sizeof(bench));
}
#endif
//stencil shadows generally require that the farclip distance is really really far away
//so this little function is used to check if its needed or not.
qboolean Sh_StencilShadowsActive(void)
{
#ifdef RTLIGHTS
//if shadowmapping is forced on all lights then we don't need special depth stuff
// if (r_shadow_shadowmapping.ival)
// return false;
return (r_shadow_realtime_dlight.ival && r_shadow_realtime_dlight_shadows.ival) ||
(r_shadow_realtime_world.ival && r_shadow_realtime_world_shadows.ival);
#else
return false;
#endif
}
void Sh_RegisterCvars(void)
{
#ifdef RTLIGHTS
#define REALTIMELIGHTING "Realtime Lighting"
Cvar_Register (&r_shadow_scissor, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_world, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_world_shadows, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_dlight, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_dlight_ambient, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_dlight_diffuse, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_dlight_specular, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_dlight_shadows, REALTIMELIGHTING);
Cvar_Register (&r_shadow_realtime_world_lightmaps, REALTIMELIGHTING);
Cvar_Register (&r_shadow_shadowmapping, REALTIMELIGHTING);
Cvar_Register (&r_shadow_shadowmapping_precision, REALTIMELIGHTING);
Cvar_Register (&r_shadow_shadowmapping_nearclip, REALTIMELIGHTING);
Cvar_Register (&r_shadow_shadowmapping_bias, REALTIMELIGHTING);
Cvar_Register (&r_sun_dir, REALTIMELIGHTING);
Cvar_Register (&r_sun_colour, REALTIMELIGHTING);
#endif
}

View File

@ -1292,11 +1292,13 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
if (gl_config.nofixedfunc)
{
prstrings[strings] =
"attribute vec3 v_position;\n"
"attribute vec3 v_position1;\n"
"#ifdef FRAMEBLEND\n"
"attribute vec3 v_position2;\n"
"uniform vec2 e_vblend;\n"
"#define v_position ((v_position*e_vblend.x)+(v_position2*e_vblend.y))\n"
"#else\n"
"#define v_position v_position1\n"
"#endif\n"
"#define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0))\n"
"uniform mat4 m_modelviewprojection;\n"
@ -1429,14 +1431,18 @@ GLhandleARB GLSlang_CreateProgramObject (char *name, GLhandleARB vert, GLhandleA
qglBindAttribLocationARB(program, VATTR_VERTEX1, "v_position");
qglBindAttribLocationARB(program, VATTR_COLOUR, "v_colour");
#if MAXRLIGHTMAPS > 1
qglBindAttribLocationARB(program, VATTR_COLOUR2, "v_colour2");
qglBindAttribLocationARB(program, VATTR_COLOUR3, "v_colour3");
qglBindAttribLocationARB(program, VATTR_COLOUR4, "v_colour4");
#endif
qglBindAttribLocationARB(program, VATTR_TEXCOORD, "v_texcoord");
qglBindAttribLocationARB(program, VATTR_LMCOORD, "v_lmcoord");
#if MAXRLIGHTMAPS > 1
qglBindAttribLocationARB(program, VATTR_LMCOORD2, "v_lmcoord2");
qglBindAttribLocationARB(program, VATTR_LMCOORD3, "v_lmcoord3");
qglBindAttribLocationARB(program, VATTR_LMCOORD4, "v_lmcoord4");
#endif
qglBindAttribLocationARB(program, VATTR_NORMALS, "v_normal");
qglBindAttribLocationARB(program, VATTR_SNORMALS, "v_svector");
qglBindAttribLocationARB(program, VATTR_TNORMALS, "v_tvector");

View File

@ -844,16 +844,8 @@ static qboolean CreateMainWindow(rendererstate_t *info)
qboolean stat;
if (!info->fullscreen)
{
if (_windowed_mouse.value && (key_dest == key_game || key_dest == key_menu))
{
TRACE(("dbg: GLVID_SetMode: VID_SetWindowedMode\n"));
stat = VID_SetWindowedMode(info);
}
else
{
TRACE(("dbg: GLVID_SetMode: VID_SetWindowedMode 2\n"));
stat = VID_SetWindowedMode(info);
}
TRACE(("dbg: GLVID_SetMode: VID_SetWindowedMode\n"));
stat = VID_SetWindowedMode(info);
}
else
{

View File

@ -120,16 +120,13 @@ void GL_DoSwap (void)
{
if (!_windowed_mouse.value)
{
if (mouseactive)
{
IN_DeactivateMouse ();
}
IN_DeactivateMouse ();
}
else
{
if ((key_dest == key_game||mouseusedforgui) && ActiveApp)
if (!Key_MouseShouldBeFree() && ActiveApp)
IN_ActivateMouse ();
else if (!(key_dest == key_game || mouseusedforgui) || !ActiveApp)
else
IN_DeactivateMouse ();
}
}

View File

@ -302,8 +302,8 @@ towards the center until it is valid.
typedef struct
{
vec3_t lightmaps[MAXLIGHTMAPS][SINGLEMAP];
vec3_t lightnorm[MAXLIGHTMAPS][SINGLEMAP];
vec3_t lightmaps[MAXQ1LIGHTMAPS][SINGLEMAP];
vec3_t lightnorm[MAXQ1LIGHTMAPS][SINGLEMAP];
int numlightstyles;
vec_t *light;
vec_t facedist;
@ -628,7 +628,7 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
norms = l->lightnorm[mapnum];
if (mapnum == l->numlightstyles)
{ // init a new light map
if (mapnum == MAXLIGHTMAPS)
if (mapnum == MAXQ1LIGHTMAPS)
{
printf ("WARNING: Too many light styles on a face\n");
return;
@ -715,7 +715,7 @@ static void FixMinlight (llightinfo_t *l)
}
if (i == l->numlightstyles)
{
if (l->numlightstyles == MAXLIGHTMAPS)
if (l->numlightstyles == MAXQ1LIGHTMAPS)
return; // oh well..
for (j=0 ; j<l->numsurfpt ; j++)
{
@ -819,7 +819,7 @@ void LightFace (int surfnum)
if (size > SINGLEMAP)
Error ("Bad lightmap size");
for (i=0 ; i<MAXLIGHTMAPS ; i++)
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
l.lightstyles[i] = 255;
//
@ -843,14 +843,14 @@ void LightFace (int surfnum)
}
#ifndef UTILITY
for (j=0 ; j<MAXLIGHTMAPS ; j++)
for (j=0 ; j<MAXQ1LIGHTMAPS ; j++)
f->styles[j] = 255;
#endif
//
// save out the values
//
for (i=0 ; i <MAXLIGHTMAPS ; i++)
for (i=0 ; i <MAXQ1LIGHTMAPS ; i++)
f->styles[i] = l.lightstyles[i];

View File

@ -354,6 +354,34 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "depthonly",
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
//standard shader used for drawing shadowmap depth.
//also used for masking off portals and other things that want depth and no colour.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"void main ()\n"
"{\n"
"gl_Position = skeletaltransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"void main ()\n"
"{\n"
//must always draw something, supposedly. It might as well be black.
"gl_FragColor = vec4(0, 0, 0, 1);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
@ -979,7 +1007,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))\n"
"uniform sampler2D s_t2; //normal.rgb+height.a\n"
"#endif\n"
"#ifdef DELUXE\n"
"uniform sampler2D s_t3; //deluxe0\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4; //fullbright\n"
"#endif\n"
@ -1271,46 +1301,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultgammacb",
//this shader is applies gamma/contrast/brightness to the source image, and dumps it out.
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_projection, inp.pos);\n"
"outp.tc = inp.tc;\n"
"outp.vcol = inp.vcol;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture;\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return pow(shaderTexture.Sample(SampleType, inp.tc) * inp.vcol.g, inp.vcol.r) + inp.vcol.b;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "drawflat_wall",
"!!cvarv r_floorcolor\n"
@ -1601,10 +1591,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef GLQUAKE
{QR_OPENGL, 110, "rtlight",
"!!permu BUMP\n"
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
"!!permu UPPERLOWER\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvardf r_glsl_pcf\n"
//this is the main shader responsible for realtime dlights.
@ -1612,10 +1605,18 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
//custom modifiers:
//PCF(shadowmap)
//CUBE(projected cubemap)
//CUBEPROJ(projected cubemap)
//SPOT(projected circle
//CUBESHADOW
"#ifndef r_glsl_pcf\n"
"#error r_glsl_pcf wasn't defined\n"
"#endif\n"
"#if r_glsl_pcf < 1\n"
"#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
"#extension GL_ARB_texture_gather : enable\n"
"#endif\n"
@ -1635,9 +1636,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
"varying vec4 vtexprojcoord;\n"
"uniform mat4 l_cubematrix;\n"
"#ifndef SPOT\n"
"uniform mat4 l_projmatrix;\n"
"#endif\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
@ -1709,68 +1707,65 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightcolourscale;\n"
"#ifdef PCF\n"
"uniform vec4 l_shadowmapinfo; //xy are the texture scale, z is 1, w is the scale.\n"
"uniform vec4 l_shadowmapproj; //light projection matrix info\n"
"uniform vec2 l_shadowmapscale; //xy are the texture scale, z is 1, w is the scale.\n"
"#endif\n"
"#ifdef PCF\n"
//#define shadow2DProj(t,c) (vec2(1.0,1.0))
//#define shadow2DProj(t,c) texture2DProj(t,c).rg
"float ShadowmapFilter(void)\n"
"vec3 ShadowmapCoord(void)\n"
"{\n"
//dehomogonize input
"vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);\n"
"#ifdef CUBESHADOW\n"
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
"#else\n"
"#ifdef SPOT\n"
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
"shadowcoord.xyz = (shadowcoord.xyz + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
"vtexprojcoord.z -= 0.015;\n"
"return (vtexprojcoord.xyz/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
"#else\n"
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
"vec3 dir = abs(shadowcoord);\n"
"vec3 dir = abs(vtexprojcoord.xyz);\n"
//assume z is the major axis (ie: forward from the light)
"vec3 t = shadowcoord;\n"
"vec3 t = vtexprojcoord.xyz;\n"
"float ma = dir.z;\n"
"vec3 axis = vec3(1.0, 1.0, 1.0);\n"
"vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
"if (dir.x > ma)\n"
"{\n"
"ma = dir.x;\n"
"t = shadowcoord.zyx;\n"
"axis.x = 3.0;\n"
"t = vtexprojcoord.zyx;\n"
"axis.x = 0.5;\n"
"}\n"
"if (dir.y > ma)\n"
"{\n"
"ma = dir.y;\n"
"t = shadowcoord.xzy;\n"
"axis.x = 5.0;\n"
"t = vtexprojcoord.xzy;\n"
"axis.x = 2.5/3.0;\n"
"}\n"
//if the axis is negative, flip it.
"if (t.z > 0.0)\n"
"{\n"
"axis.y = 3.0;\n"
"axis.y = 1.5/2.0;\n"
"t.z = -t.z;\n"
"}\n"
//we also need to pass the result through the light's projection matrix too
"vec4 nsc =l_projmatrix*vec4(t, 1.0);\n"
"shadowcoord = (nsc.xyz / nsc.w);\n"
//scale to match the light's precision and pinch inwards, so we never sample over the edge
"shadowcoord.st *= l_shadowmapinfo.w * (1.0-l_shadowmapinfo.st);\n"
//now bias and relocate it
"shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
"return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);\n"
"#endif\n"
"}\n"
"float ShadowmapFilter(void)\n"
"{\n"
"vec3 shadowcoord = ShadowmapCoord();\n"
"#if 0//def GL_ARB_texture_gather\n"
"vec2 ipart, fpart;\n"
@ -1787,8 +1782,19 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.\n"
"#else\n"
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapinfo.xyz)).r\n"
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
"s += dosamp(0.0, 0.0);\n"
"return s;\n"
"#elif r_glsl_pcf >= 5 && r_glsl_pcf < 9\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(0.0, -1.0);\n"
"s += dosamp(0.0, 0.0);\n"
"s += dosamp(0.0, 1.0);\n"
"s += dosamp(1.0, 0.0);\n"
"return s/5.0;\n"
"#else\n"
"s += dosamp(-1.0, -1.0);\n"
"s += dosamp(-1.0, 0.0);\n"
"s += dosamp(-1.0, 1.0);\n"

View File

@ -305,7 +305,9 @@ enum{
PERMUTATION_SKELETAL = 16,
PERMUTATION_FOG = 32,
PERMUTATION_FRAMEBLEND = 64,
#if MAXRLIGHTMAPS > 1
PERMUTATION_LIGHTSTYLES = 128,
#endif
PERMUTATIONS = 256
};
@ -321,12 +323,14 @@ enum shaderattribs_e
VATTR_TNORMALS,
VATTR_BONENUMS, /*skeletal only*/
VATTR_BONEWEIGHTS, /*skeletal only*/
#if MAXRLIGHTMAPS > 1
VATTR_LMCOORD2,
VATTR_LMCOORD3,
VATTR_LMCOORD4,
VATTR_COLOUR2,
VATTR_COLOUR3,
VATTR_COLOUR4,
#endif
VATTR_LEG_VERTEX, //note: traditionally this is actually index 0.
@ -381,9 +385,9 @@ typedef struct {
SP_LIGHTCOLOURSCALE,
SP_LIGHTPOSITION,
SP_LIGHTSCREEN,
SP_LIGHTPROJMATRIX,
SP_LIGHTCUBEMATRIX,
SP_LIGHTSHADOWMAPINFO,
SP_LIGHTSHADOWMAPPROJ,
SP_LIGHTSHADOWMAPSCALE,
//things that are set immediatly
SP_FIRSTIMMEDIATE, //never set
@ -459,6 +463,7 @@ struct shader_s
polyoffset_t polyoffset;
#define SHADER_CULL_FLIP (SHADER_CULL_FRONT|SHADER_CULL_BACK)
enum {
SHADER_SKY = 1 << 0,
SHADER_NOMIPMAPS = 1 << 1,
@ -547,6 +552,15 @@ mfog_t *CM_FogForOrigin(vec3_t org);
#define BEF_FORCECOLOURMOD 256 //q3 shaders default to 'rgbgen identity', and ignore ent colours. this forces ent colours to be considered
#define BEF_LINES 512 //draw line pairs instead of triangles.
enum
{
LSHADER_STANDARD, //stencil or shadowless
LSHADER_CUBE, //has a cubemap
LSHADER_SMAP, //shadowmap
LSHADER_SPOT, //spotlight+shadowmap
LSHADER_MODES
};
#ifdef GLQUAKE
void GLBE_Init(void);
void GLBE_Shutdown(void);
@ -561,7 +575,7 @@ void GLBE_UploadAllLightmaps(void);
void GLBE_DrawWorld (qboolean drawworld, qbyte *vis);
qboolean GLBE_LightCullModel(vec3_t org, model_t *model);
void GLBE_SelectEntity(entity_t *ent);
void GLBE_SelectDLight(dlight_t *dl, vec3_t colour);
qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, unsigned int lmode);
void GLBE_Scissor(srect_t *rect);
void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
@ -631,6 +645,7 @@ void BE_DrawNonWorld (void);
//Builds a hardware shader from the software representation
void BE_GenerateProgram(shader_t *shader);
void Sh_RegisterCvars(void);
#ifdef RTLIGHTS
//
void GLBE_PushOffsetShadow(qboolean foobar);
@ -648,6 +663,9 @@ void SH_FreeShadowMesh(struct shadowmesh_s *sm);
void Sh_Shutdown(void);
//resize any textures to match new screen resize
void Sh_Reset(void);
qboolean Sh_StencilShadowsActive(void);
#else
#define Sh_StencilShadowsActive() false
#endif
struct shader_field_names_s

View File

@ -84,6 +84,12 @@ qboolean DL_Decide(struct dl_download *dl)
if (!*url)
url = dl->url;
if (dl->postdata)
{
DL_Abort(dl);
return false; //safe to destroy it now
}
if (dl->ctx)
{
if (dl->status == DL_FAILED || dl->status == DL_FINISHED)
@ -222,6 +228,12 @@ qboolean DL_Decide(struct dl_download *dl)
if (!*url)
url = dl->url;
if (dl->postdata)
{
DL_Abort(dl);
return false; //safe to destroy it now
}
if (dl->ctx)
{
if (dl->status == DL_FAILED || dl->status == DL_FINISHED)
@ -263,7 +275,7 @@ It doesn't use persistant connections.
struct http_dl_ctx_s {
struct dl_download *dlctx;
SOCKET sock;
SOCKET sock; //FIXME: support https.
char *buffer;
@ -693,15 +705,38 @@ void HTTPDL_Establish(struct dl_download *dl)
return;
}
ExpandBuffer(con, 512*1024);
sprintf(con->buffer,
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n"
"Accept-Encoding: gzip\r\n"
"User-Agent: "FULLENGINENAME"\r\n"
"\r\n", uri, server);
con->bufferused = strlen(con->buffer);
if (dl->postdata)
{
ExpandBuffer(con, 1024 + strlen(uri) + strlen(server) + strlen(con->dlctx->postmimetype) + dl->postlen);
Q_snprintfz(con->buffer, con->bufferlen,
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Length: %i\r\n"
"Content-Type: %s\r\n"
"Connection: close\r\n"
#ifndef NPFTE
"Accept-Encoding: gzip\r\n"
#endif
"User-Agent: "FULLENGINENAME"\r\n"
"\r\n", uri, server, dl->postlen, dl->postmimetype);
con->bufferused = strlen(con->buffer);
memcpy(con->buffer + con->bufferused, dl->postdata, dl->postlen);
con->bufferused += dl->postlen;
}
else
{
ExpandBuffer(con, 512*1024);
Q_snprintfz(con->buffer, con->bufferlen,
"GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n"
#ifndef NPFTE
"Accept-Encoding: gzip\r\n"
#endif
"User-Agent: "FULLENGINENAME"\r\n"
"\r\n", uri, server);
con->bufferused = strlen(con->buffer);
}
con->contentlength = -1;
}
@ -850,6 +885,8 @@ void DL_Close(struct dl_download *dl)
dl->abort(dl);
if (dl->file)
VFS_CLOSE(dl->file);
if (dl->postdata)
BZ_Free(dl->postdata);
free(dl);
}
@ -876,6 +913,20 @@ struct dl_download *HTTP_CL_Get(const char *url, const char *localfile, void (*N
return newdl;
}
struct dl_download *HTTP_CL_Put(const char *url, const char *mime, const char *data, size_t datalen, void (*NotifyFunction)(struct dl_download *dl))
{
struct dl_download *dl;
if (!*mime)
return NULL;
dl = HTTP_CL_Get(url, NULL, NotifyFunction);
Q_strncpyz(dl->postmimetype, mime, sizeof(dl->postmimetype));
dl->postdata = BZ_Malloc(datalen);
memcpy(dl->postdata, data, datalen);
dl->postlen = datalen;
return dl;
}
void HTTP_CL_Think(void)
{
struct dl_download *dl = activedownloads;

View File

@ -113,6 +113,10 @@ struct dl_download
char localname[MAX_OSPATH]; /*leave empty for a temp file*/
struct vfsfile_s *file; /*downloaded to, if not already set when starting will open localname or a temp file*/
char postmimetype[64];
char *postdata; /*if set, this is a post and not a get*/
size_t postlen;
/*stream status*/
enum
{
@ -143,6 +147,7 @@ struct dl_download
void HTTP_CL_Think(void);
struct dl_download *HTTP_CL_Get(const char *url, const char *localfile, void (*NotifyFunction)(struct dl_download *dl));
struct dl_download *HTTP_CL_Put(const char *url, const char *mime, const char *data, size_t datalen, void (*NotifyFunction)(struct dl_download *dl));
struct dl_download *DL_Create(const char *url);
qboolean DL_CreateThread(struct dl_download *dl, vfsfile_t *file, void (*NotifyFunction)(struct dl_download *dl));

View File

@ -785,6 +785,11 @@ struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs)
if ((unsigned)progs >= (unsigned)maxedicts)
{
printf("Bad entity index %i\n", progs);
if (pr_depth)
{
PR_StackTrace (ppf);
// progfuncs->funcs.pr_trace += 1;
}
progs = 0;
}
return (struct edict_s *)PROG_TO_EDICT(progfuncs.inst, progs);

View File

@ -643,15 +643,17 @@ pbool LocateDebugTerm(progfuncs_t *progfuncs, char *key, eval_t **result, etype_
return false;
if (c)*c = '\0';
c2 = COM_TrimString(c2);
def = ED_FindLocalOrGlobal(progfuncs, c2, &fval);
if (def && def->type == ev_field)
fdef = ED_FindField(progfuncs, c2);
if (!fdef)
{
fofs = fval->_int + progfuncs->funcs.fieldadjust;
fdef = ED_FieldAtOfs(progfuncs, fofs);
c2 = COM_TrimString(c2);
def = ED_FindLocalOrGlobal(progfuncs, c2, &fval);
if (def && def->type == ev_field)
{
fofs = fval->_int + progfuncs->funcs.fieldadjust;
fdef = ED_FieldAtOfs(progfuncs, fofs);
}
}
else
fdef = ED_FindField(progfuncs, c2);
if (c)*c = '.';
if (!fdef)
@ -934,11 +936,12 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum,
if (!pr_progstate[pn].linenums)
continue;
//we need to use the function table in order to set breakpoints in the right file.
for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++)
{
if (!stricmp(f->s_file+progfuncs->funcs.stringtable, filename))
{
for (i = f->first_statement; ; i++)
for (i = f->first_statement; i < pr_progstate[pn].progs->numstatements; i++)
{
if (pr_progstate[pn].linenums[i] >= linenum)
{

View File

@ -655,7 +655,7 @@ pbool QCC_PR_Precompiler(void)
msg[a] = '\0';
QCC_PR_SkipToEndOfLine(true);
QCC_PR_SkipToEndOfLine(false);
QCC_PR_ParseError(ERR_HASHERROR, "#Error: %s", msg);
}
@ -667,7 +667,7 @@ pbool QCC_PR_Precompiler(void)
msg[a-1] = '\0';
QCC_PR_SkipToEndOfLine(true);
QCC_PR_SkipToEndOfLine(false);
QCC_PR_ParseWarning(WARN_PRECOMPILERMESSAGE, "#warning: %s", msg);
}
@ -693,7 +693,7 @@ pbool QCC_PR_Precompiler(void)
msg[a-1] = '\0';
QCC_PR_SkipToEndOfLine(true);
QCC_PR_SkipToEndOfLine(false);
if (strlen(msg) >= sizeof(QCC_copyright))
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n");
@ -732,13 +732,6 @@ pbool QCC_PR_Precompiler(void)
ForcedCRC = QCC_PR_LexInteger();
pr_file_p++;
for (a = 0; a < sizeof(msg)-1 && pr_file_p[a] != '\n' && pr_file_p[a] != '\0'; a++)
msg[a] = pr_file_p[a];
msg[a-1] = '\0';
QCC_PR_SkipToEndOfLine(true);
}
else if (!strncmp(directive, "includelist", 11))

View File

@ -2643,18 +2643,6 @@ static void QCBUILTIN PF_vhlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_
G_FLOAT(OFS_RETURN) = newv;
}
static void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float v = G_FLOAT(OFS_PARM0);
while (v >= 360)
v = v - 360;
while (v < 0)
v = v + 360;
G_FLOAT(OFS_RETURN) = v;
}
/*
=================
PF_particle
@ -9768,7 +9756,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"uri_escape", PF_uri_escape, 0, 0, 0, 510, "string(string in)"},//DP_QC_URI_ESCAPE
{"uri_unescape", PF_uri_unescape, 0, 0, 0, 511, "string(string in)"},//DP_QC_URI_ESCAPE
{"num_for_edict", PF_num_for_edict, 0, 0, 0, 512, "float(entity ent)"},//DP_QC_NUM_FOR_EDICT
{"uri_get", PF_uri_get, 0, 0, 0, 513, "float(string uril, float id)"},//DP_QC_URI_GET
{"uri_get", PF_uri_get, 0, 0, 0, 513, "float(string uril, float id, optional string postmimetype, optional string postdata)"},//DP_QC_URI_GET
{"tokenize_console",PF_tokenize_console,0, 0, 0, 514, "float(string str)"},
{"argv_start_index",PF_argv_start_index,0, 0, 0, 515, "float(float idx)"},
{"argv_end_index", PF_argv_end_index, 0, 0, 0, 516, "float(float idx)"},
@ -9970,7 +9958,7 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
for (i = 0; BuiltinList[i].name; i++)
{
if (!strcmp(BuiltinList[i].name, com_token))
if (!strcmp(BuiltinList[i].name, com_token) && (BuiltinList[i].bifunc != PF_Fixme||!i))
{
pr_builtin[binum] = BuiltinList[i].bifunc;
break;

View File

@ -154,6 +154,7 @@ cvar_t sv_gamespeed = CVAR("sv_gamespeed", "1");
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
cvar_t pausable = CVAR("pausable", "1");
cvar_t sv_banproxies = CVARD("banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
//
@ -580,10 +581,10 @@ void SV_DropClient (client_t *drop)
{
Netchan_Transmit(&drop->netchan, 0, "", SV_RateForClient(drop));
#ifdef warningmsg
#pragma warningmsg("This mans that we may not see the reason we kicked ourselves.")
#pragma warningmsg("This means that we may not see the reason we kicked ourselves.")
#endif
CL_Disconnect();
drop->state = cs_free; //don't do zombie stuff
CL_Disconnect();
}
else
#endif
@ -2014,13 +2015,34 @@ client_t *SVC_DirectConnect(void)
{
if (!sv_listen_qw.value && net_from.type != NA_LOOPBACK)
{
SV_RejectMessage (SCP_BAD, "QuakeWorld protocols are not permitted on this server.\n");
SV_RejectMessage (protocol, "QuakeWorld protocols are not permitted on this server.\n");
Con_Printf ("* rejected connect from quakeworld\n");
return NULL;
}
}
if (sv_banproxies.ival)
{
//FIXME: allow them to spectate but not join
if (*Info_ValueForKey(userinfo[0], "*qwfwd"))
{
SV_RejectMessage (protocol, "Proxies are not permitted on this server.\n");
Con_Printf ("* rejected connect from qwfwd proxy\n");
return NULL;
}
if (*Info_ValueForKey(userinfo[0], "Qizmo"))
{
SV_RejectMessage (protocol, "Proxies are not permitted on this server.\n");
Con_Printf ("* rejected connect from qizmo proxy\n");
return NULL;
}
if (*Info_ValueForKey(userinfo[0], "*qtv"))
{
SV_RejectMessage (protocol, "Proxies are not permitted on this server.\n");
Con_Printf ("* rejected connect from qtv proxy (udp)\n");
return NULL;
}
}
while(!msg_badread)
{
@ -3990,7 +4012,7 @@ float SV_Frame (void)
sv.gamespeed = 1;
#ifndef SERVERONLY
isidle = !isDedicated && sv.allocated_client_slots == 1 && key_dest != key_game && cls.state == ca_active;
isidle = !isDedicated && sv.allocated_client_slots == 1 && Key_Dest_Has(~kdm_game) && cls.state == ca_active;
/*server is effectively paused if there are no clients*/
if (sv.spawned_client_slots == 0 && sv.spawned_observer_slots == 0 && (cls.state != ca_connected))
isidle = true;
@ -4309,6 +4331,7 @@ void SV_InitLocal (void)
#endif
Cvar_Set(&sv_public, "1");
Cvar_Register (&sv_banproxies, "Server Permissions");
Cvar_Register (&sv_master, cvargroup_servercontrol);
Cvar_Register (&sv_masterport, cvargroup_servercontrol);

View File

@ -1223,7 +1223,42 @@ qboolean SV_MVDWritePackets (int num)
return true;
}
extern char readable[256];
// table of readable characters, same as ezquake
char readable[256] =
{
'.', '_', '_', '_', '_', '.', '_', '_',
'_', '_', '\n', '_', '\n', '>', '.', '.',
'[', ']', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '.', '_', '_', '_',
' ', '!', '\"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '_',
'_', '_', '_', '_', '_', '.', '_', '_',
'_', '_', '_', '_', '_', '>', '.', '.',
'[', ']', '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', '.', '_', '_', '_',
' ', '!', '\"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '_'
};
#define chartbl readable
void MVD_Init (void)

View File

@ -139,7 +139,7 @@ void WPhys_CheckVelocity (world_t *w, wedict_t *ent)
{
if (IS_NAN(ent->v->velocity[i]))
{
Con_Printf ("Got a NaN velocity on %s\n", PR_GetString(w->progs, ent->v->classname));
Con_DPrintf ("Got a NaN velocity on %s\n", PR_GetString(w->progs, ent->v->classname));
ent->v->velocity[i] = 0;
}
if (IS_NAN(ent->v->origin[i]))

View File

@ -567,6 +567,17 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
mask = CM_ClusterPVS (sv.world.worldmodel, cluster, NULL, 0);
break;
case MULTICAST_ONE_R:
reliable = true;
case MULTICAST_ONE:
if (svprogfuncs)
{
edict_t *ent = PROG_TO_EDICT(svprogfuncs, pr_global_struct->msg_entity);
pnum = NUM_FOR_EDICT(svprogfuncs, ent) - 1;
}
mask = NULL;
break;
default:
mask = NULL;
SV_Error ("SV_Multicast: bad to:%i", to);
@ -592,7 +603,12 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
}
}
if (mask)
if (!mask)
{
if (pnum != j)
continue;
}
else
{
#ifdef Q2SERVER
if (ge)

View File

@ -916,8 +916,7 @@ void Signal_Error_Handler (int sig)
void StartQuakeServer(void)
{
quakeparms_t parms;
static char bindir[MAX_OSPATH]; //unused variable
int t;
static char bindir[MAX_OSPATH];
memset(&parms, 0, sizeof(parms));

View File

@ -4922,7 +4922,7 @@ ucmd_t ucmds[] =
{"demoinfo", SV_MVDInfo_f},
{"dlsize", SV_DownloadSize_f},
{"download", SV_BeginDownload_f},
{"nextdl", SV_NextDownload_f},
{"nextdl", SV_NextDownload_f, true},
/*quakeworld specific things*/
{"join", Cmd_Join_f},
@ -4930,8 +4930,8 @@ ucmd_t ucmds[] =
{"snap", SV_NoSnap_f},
{"ptrack", SV_PTrack_f}, //ZOID - used with autocam
{"enablecsqc", SV_EnableClientsCSQC},
{"disablecsqc", SV_DisableClientsCSQC},
{"enablecsqc", SV_EnableClientsCSQC, true},
{"disablecsqc", SV_DisableClientsCSQC, true},
{"vote", SV_Vote_f},
@ -5040,7 +5040,7 @@ ucmd_t nqucmds[] =
#endif
/*various misc extensions*/
{"pext", SV_Pext_f},
{"pext", SV_Pext_f, true},
{"enablecsqc", SV_EnableClientsCSQC},
{"disablecsqc", SV_DisableClientsCSQC},
{"challengeconnect", NULL},

Some files were not shown because too many files have changed in this diff Show More