1
0
Fork 0
forked from fte/fteqw

Added csqc->ssqc requests.

Fixed up cl_indepphysics. Sending is fully independent, bar sync points.
Fixed so #if 0 works in qc code.
Fixed up error conditions in qclib when features are not supported.
The webpage generator will now refcount properly.
Fixed error conditions when using glsl shaders.
If MULTITHREAD is defined, r_loadlit will not light inside a separate thread.
We now generate VBOs for bsp objects. Shaders/rtlights don't use them yet.
Fixed up MVD/multiview playback a bit. It now looks like it works! (cl_hightrack will no longer track the same person in all views).
Fixed error conditions when attempting to download versioned csprogs.
Reduced the number of places that a q3-style marked up string is expanded. I think there are a couple places left still though. Approximated ezquake colour codes.
Memory mapped read file access in win32, where we can. Not sure about this. Lets see how things pan out.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3195 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2009-05-24 10:11:17 +00:00
parent 48e757c860
commit 9cd988a836
69 changed files with 1694 additions and 1041 deletions

View file

@ -596,13 +596,13 @@ ifeq ($(FTE_TARGET),win32)
SV_EXE_NAME=../fteqwsv.exe
SV_LDFLAGS=libs/zlib.lib -lwsock32 -lwinmm
SV_DIR=sv_mingw
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) resources.o
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o
ifeq ($(USEASM),true)
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
else
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
endif
GL_EXE_NAME=../fteglqw.exe
GLCL_EXE_NAME=../fteglqwcl.exe
@ -612,9 +612,9 @@ endif
GLCL_DIR=glcl_mgw
ifeq ($(USEASM),true)
NPQTVCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o npplug.o sys_npqtv.o ../../ftequake/npapi.def
NPQTVCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o npplug.o sys_npqtv.o ../../ftequake/npapi.def
else
NPQTVCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o npplug.o sys_npqtv.o ../../ftequake/npapi.def
NPQTVCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o npplug.o sys_npqtv.o ../../ftequake/npapi.def
endif
NPQTV_DLL_NAME=../npqtv.dll
NPQTVCL_DLL_NAME=../npqtvcl.dll
@ -624,9 +624,9 @@ endif
NPQTVCL_DIR=npqtvcl_mgw
ifeq ($(USEASM),true)
SWCL_OBJS=$(SOFTWARE_OBJS) vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
SWCL_OBJS=$(SOFTWARE_OBJS) fs_win32.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
else
SWCL_OBJS=$(SOFTWARE_OBJS) vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
SWCL_OBJS=$(SOFTWARE_OBJS) fs_win32.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
endif
SW_EXE_NAME=../fteswqw.exe
SWCL_EXE_NAME=../fteswqwcl.exe
@ -636,9 +636,9 @@ endif
SWCL_DIR=swcl_mgw
ifeq ($(USEASM),true)
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidnt.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) fs_win32.o gl_vidnt.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_dosa.o resources.o
else
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidnt.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
MCL_OBJS=$(GLQUAKE_OBJS) $(SOFTWARE_OBJS) fs_win32.o gl_vidnt.o vid_ddraw.o vid_dib.o vid_win2.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o
endif
M_EXE_NAME=../fteqw.exe
MCL_EXE_NAME=../fteqwcl.exe

View file

@ -357,21 +357,37 @@ static void Cam_CheckHighTarget(int pnum)
{
int i, j, max;
player_info_t *s;
int sp;
j = -1;
for (i = 0, max = -9999; i < MAX_CLIENTS; i++)
{
s = &cl.players[i];
if (s->name[0] && !s->spectator && s->frags > max)
{
for (sp = pnum-1; sp >= 0; sp--)
{
if (Cam_TrackNum(sp) == i)
break;
}
if (sp == -1)
{
max = s->frags;
j = i;
}
}
}
if (j >= 0)
{
if (!locked[pnum] || cl.players[j].frags > cl.players[spec_track[pnum]].frags)
{
Cam_Lock(pnum, j);
for (sp = pnum+1; sp < cl.splitclients; sp++)
{
if (Cam_TrackNum(sp) == j)
locked[sp] = false;
}
}
}
else
Cam_Unlock(pnum);

View file

@ -949,7 +949,8 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *
VM_LONG(ret) = Sys_Milliseconds();
break;
case CG_REAL_TIME:
VM_FLOAT(ret) = realtime;
//really local time
VM_LONG(ret) = Sys_Milliseconds();
break;
case CG_SNAPVECTOR: // ( float *v )
@ -1114,6 +1115,7 @@ void CG_Stop (void)
void CG_Start (void)
{
SCR_SetLoadingStage(0);
if (cls.protocol != CP_QUAKE3)
{ //q3 clients only.
CG_Stop();
@ -1140,8 +1142,8 @@ void CG_Start (void)
cgvm = VM_Create(NULL, "vm/cgame", CG_SystemCalls, CG_SystemCallsEx);
if (cgvm)
{ //hu... cgame doesn't appear to have a query version call!
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playernum[0]);
SCR_EndLoadingPlaque();
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playernum[0]);
}
else
{

View file

@ -3185,6 +3185,8 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
struct predicted_player *pplayer;
extern cvar_t cl_nopred;
int s;
playertime = realtime - cls.latency + 0.02;
if (playertime > realtime)
playertime = realtime;
@ -3226,12 +3228,16 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
// note that the local player is special, since he moves locally
// we use his last predicted postition
if (j == cl.playernum[0])
for (s = 0; s < cl.splitclients; s++)
{
VectorCopy(cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum[0]].origin,
if (j == cl.playernum[s])
{
VectorCopy(cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].playerstate[cl.playernum[s]].origin,
pplayer->origin);
break;
}
else
}
if (s == cl.splitclients)
{
// only predict half the move to minimize overruns
msec = 500*(playertime - state->state_time);
@ -3358,7 +3364,6 @@ void CL_EmitEntities (void)
CL_LinkPacketEntities ();
CL_LinkProjectiles ();
CL_UpdateTEnts ();
CL_LinkViewModel ();
}
@ -3415,6 +3420,7 @@ static void MVD_InitInterpolation(void)
frame_t *frame, *oldframe;
vec3_t dist;
struct predicted_player *pplayer;
int s;
#define ISDEAD(i) ( (i) >= 41 && (i) <= 102 )
@ -3460,7 +3466,12 @@ static void MVD_InitInterpolation(void)
}
// we dont interpolate ourself if we are spectating
if (i == cl.playernum[0] && cl.spectator)
for (s = 0; s < cl.splitclients; s++)
{
if (i == cl.playernum[s] && cl.spectator)
break;
}
if (s != cl.splitclients)
continue;
memset(state->velocity, 0, sizeof(state->velocity));
@ -3508,15 +3519,19 @@ void MVD_Interpolate(void)
struct predicted_player *pplayer;
static float old;
extern float demtime;
int s;
self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[0]];
oldself = &cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].playerstate[cl.playernum[0]];
for (s = 0; s < cl.splitclients; s++)
{
self = &cl.frames[cl.parsecount & UPDATE_MASK].playerstate[cl.playernum[s]];
oldself = &cl.frames[(cls.netchan.outgoing_sequence - 1) & UPDATE_MASK].playerstate[cl.playernum[s]];
self->messagenum = cl.parsecount;
VectorCopy(oldself->origin, self->origin);
VectorCopy(oldself->velocity, self->velocity);
VectorCopy(oldself->viewangles, self->viewangles);
}
if (old != nextdemotime)
{

View file

@ -44,6 +44,7 @@ cvar_t cl_instantrotate = SCVARF("cl_instantrotate", "1", CVAR_SEMICHEAT);
cvar_t prox_inmenu = SCVAR("prox_inmenu", "0");
usercmd_t independantphysics[MAX_SPLITS];
vec3_t mousemovements[MAX_SPLITS];
/*
===============================================================================
@ -448,7 +449,7 @@ CL_AdjustAngles
Moves the local angle positions
================
*/
void CL_AdjustAngles (int pnum)
void CL_AdjustAngles (int pnum, double frametime)
{
float speed, quant;
float up, down;
@ -456,12 +457,12 @@ void CL_AdjustAngles (int pnum)
if (in_speed.state[pnum] & 1)
{
if (ruleset_allow_frj.value)
speed = host_frametime * cl_anglespeedkey.value;
speed = frametime * cl_anglespeedkey.value;
else
speed = host_frametime * bound(-2, cl_anglespeedkey.value, 2);
speed = frametime * bound(-2, cl_anglespeedkey.value, 2);
}
else
speed = host_frametime;
speed = frametime;
if (in_rotate && pnum==0 && !(cl.fpd & FPD_LIMIT_YAW))
{
@ -1013,7 +1014,10 @@ unsigned long _stdcall CL_IndepPhysicsThread(void *param)
time -= spare/1000.0f;
EnterCriticalSection(&indepcriticialsection);
if (cls.state)
CL_SendCmd(time - lasttime);
{
Sys_SendKeyEvents();
CL_SendCmd(time - lasttime, false);
}
lasttime = time;
LeaveCriticalSection(&indepcriticialsection);
}
@ -1110,7 +1114,7 @@ void *CL_IndepPhysicsThread(void *param)
time -= spare/1000.0f;
pthread_mutex_lock(&indepcriticalsection);
if (cls.state)
CL_SendCmd(time - lasttime);
CL_SendCmd(time - lasttime, false);
lasttime = time;
pthread_mutex_unlock(&indepcriticalsection);
}
@ -1369,7 +1373,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf)
return dontdrop;
}
void CL_SendCmd (double frametime)
void CL_SendCmd (double frametime, qboolean mainloop)
{
extern cvar_t cl_indepphysics;
sizebuf_t buf;
@ -1388,6 +1392,23 @@ void CL_SendCmd (double frametime)
extern cvar_t cl_maxfps;
clcmdbuf_t *next;
if (runningindepphys)
{
double curtime;
static double lasttime;
curtime = Sys_DoubleTime();
frametime = curtime - lasttime;
lasttime = curtime;
/* for (plnum = 0; plnum < cl.splitclients; plnum++)
{
CL_AdjustAngles(plnum, frametime);
IN_Move(mousemovements[plnum], plnum);
}
return;
*/
}
CL_ProxyMenuHooks();
if (cls.demoplayback != DPB_NONE)
@ -1413,12 +1434,16 @@ void CL_SendCmd (double frametime)
cmd->msec = frametime*1000;
independantphysics[0].msec = 0;
CL_AdjustAngles (plnum);
CL_AdjustAngles (plnum, frametime);
// get basic movement from keyboard
CL_BaseMove (cmd, plnum, 1, 1);
// allow mice or other external controllers to add to the move
IN_Move (cmd, plnum);
IN_Move (mousemovements[plnum], plnum);
independantphysics[plnum].forwardmove += mousemovements[plnum][0];
independantphysics[plnum].sidemove += mousemovements[plnum][1];
independantphysics[plnum].upmove += mousemovements[plnum][2];
VectorClear(mousemovements[plnum]);
// if we are spectator, try autocam
if (cl.spectator)
@ -1461,6 +1486,8 @@ void CL_SendCmd (double frametime)
msecs=0; //erm.
msecstouse = (int)msecs; //casts round down.
if (msecstouse == 0)
return;
#ifdef IRCCONNECT
if (cls.netchan.remote_address.type != NA_IRC)
#endif
@ -1479,7 +1506,7 @@ void CL_SendCmd (double frametime)
fullsend = true;
if (!cl_indepphysics.value)
if (!runningindepphys)
{
// while we're not playing send a slow keepalive fullsend to stop mvdsv from screwing up
if (cls.state < ca_active && CL_FilterTime(msecstouse,
@ -1511,8 +1538,12 @@ void CL_SendCmd (double frametime)
for (plnum = 0; plnum < cl.splitclients; plnum++)
{
// CL_BaseMove (&independantphysics[plnum], plnum, (msecstouse - independantphysics[plnum].msec), wantfps);
CL_AdjustAngles (plnum);
IN_Move (&independantphysics[plnum], plnum);
CL_AdjustAngles (plnum, frametime);
IN_Move (mousemovements[plnum], plnum);
independantphysics[plnum].forwardmove += mousemovements[plnum][0];
independantphysics[plnum].sidemove += mousemovements[plnum][1];
independantphysics[plnum].upmove += mousemovements[plnum][2];
VectorClear(mousemovements[plnum]);
for (i=0 ; i<3 ; i++)
independantphysics[plnum].angles[i] = ((int)(cl.viewangles[plnum][i]*65536.0/360)&65535);
@ -1530,6 +1561,10 @@ void CL_SendCmd (double frametime)
independantphysics[plnum].msec = msecstouse;
}
//the main loop isn't allowed to send
if (runningindepphys && mainloop)
return;
// if (skipcmd)
// return;
#ifdef NQPROT
@ -1606,7 +1641,7 @@ void CL_SendCmd (double frametime)
return; // Q3 does it's own thing
#endif
default:
Host_Error("Invalid protocol in CL_SendCmd: %i", cls.protocol);
Host_EndGame("Invalid protocol in CL_SendCmd: %i", cls.protocol);
return;
}
}

View file

@ -1162,7 +1162,10 @@ void CL_Disconnect (void)
cls.downloadqw = NULL;
}
if (!cls.downloadmethod)
*cls.downloadname = '\0';
{
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
}
{
downloadlist_t *next;
@ -2661,7 +2664,7 @@ void CL_Download_f (void)
void CL_DownloadSize_f(void)
{
downloadlist_t *dl;
char *name;
char *rname;
char *size;
char *redirection;
@ -2670,37 +2673,37 @@ void CL_DownloadSize_f(void)
if (cls.demoplayback)
return;
name = Cmd_Argv(1);
rname = Cmd_Argv(1);
size = Cmd_Argv(2);
if (!strcmp(size, "e"))
{
Con_Printf("Download of \"%s\" failed. Not found.\n", name);
CL_DownloadFailed(name);
Con_Printf("Download of \"%s\" failed. Not found.\n", rname);
CL_DownloadFailed(rname);
}
else if (!strcmp(size, "p"))
{
Con_Printf("Download of \"%s\" failed. Not allowed.\n", name);
CL_DownloadFailed(name);
Con_Printf("Download of \"%s\" failed. Not allowed.\n", rname);
CL_DownloadFailed(rname);
}
else if (!strcmp(size, "r"))
{
redirection = Cmd_Argv(3);
dl = CL_DownloadFailed(name);
dl = CL_DownloadFailed(rname);
if (allow_download_redirection.value)
{
Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", name, redirection);
Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection);
CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags);
}
else
Con_Printf("Download of \"%s\" redirected to \"%s\". Prevented by allow_download_redirection.\n", name, redirection);
Con_Printf("Download of \"%s\" redirected to \"%s\". Prevented by allow_download_redirection.\n", rname, redirection);
}
else
{
for (dl = cl.downloadlist; dl; dl = dl->next)
{
if (!strcmp(dl->name, name))
if (!strcmp(dl->rname, rname))
{
dl->size = strtoul(size, NULL, 0);
return;
@ -2728,7 +2731,7 @@ void CL_ForceStopDownload (qboolean finish)
cls.downloadqw = NULL;
if (finish)
CL_DownloadFinished(cls.downloadname, cls.downloadtempname);
CL_DownloadFinished();
else
{
char *tempname;
@ -2736,14 +2739,15 @@ void CL_ForceStopDownload (qboolean finish)
if (*cls.downloadtempname)
tempname = cls.downloadtempname;
else
tempname = cls.downloadname;
tempname = cls.downloadlocalname;
if (strncmp(tempname,"skins/",6))
FS_Remove(tempname, FS_GAME);
else
FS_Remove(tempname+6, FS_SKINS);
}
*cls.downloadname = '\0';
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
cls.downloadpercent = 0;
// get another file if needed
@ -3344,8 +3348,6 @@ void Host_Frame (double time)
// fetch results from server
CL_ReadPackets ();
CL_AllowIndependantSendCmd(true);
// send intentions now
// resend a connection request if necessary
if (cls.state == ca_disconnected)
@ -3355,15 +3357,14 @@ void Host_Frame (double time)
}
else
{
extern qboolean runningindepphys;
if (!runningindepphys)
CL_SendCmd (host_frametime/cl.gamespeed);
CL_SendCmd (host_frametime/cl.gamespeed, true);
if (cls.state == ca_onserver && cl.validsequence && cl.worldmodel)
{ // first update is the final signon stage
CL_MakeActive("QuakeWorld");
}
}
CL_AllowIndependantSendCmd(true);
RSpeedEnd(RSPEED_PROTOCOL);

View file

@ -307,7 +307,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
for (dl = cl.faileddownloads; dl; dl = dl->next) //yeah, so it failed... Ignore it.
{
if (!strcmp(dl->name, filename))
if (!strcmp(dl->rname, filename))
{
if (flags & DLLF_VERBOSE)
Con_Printf("We've failed to download \"%s\" already\n", filename);
@ -318,7 +318,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
for (dl = cl.downloadlist; dl; dl = dl->next) //It's already on our list. Ignore it.
{
if (!strcmp(dl->name, filename))
if (!strcmp(dl->rname, filename))
{
if (flags & DLLF_VERBOSE)
Con_Printf("Already waiting for \"%s\"\n", filename);
@ -326,7 +326,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
}
}
if (!strcmp(cls.downloadname, filename))
if (!strcmp(cls.downloadremotename, filename))
{
if (flags & DLLF_VERBOSE)
Con_Printf("Already downloading \"%s\"\n", filename);
@ -340,7 +340,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
}
dl = Z_Malloc(sizeof(downloadlist_t));
Q_strncpyz(dl->name, filename, sizeof(dl->name));
Q_strncpyz(dl->rname, filename, sizeof(dl->rname));
Q_strncpyz(dl->localname, localname, sizeof(dl->localname));
dl->next = cl.downloadlist;
cl.downloadlist = dl;
@ -352,7 +352,7 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
| PEXT_PK3DOWNLOADS
#endif
))
CL_SendClientCommand(true, "dlsize \"%s\"", dl->name);
CL_SendClientCommand(true, "dlsize \"%s\"", dl->rname);
if (flags & DLLF_VERBOSE)
Con_Printf("Enqued download of \"%s\"\n", filename);
@ -391,7 +391,7 @@ void CL_DisenqueDownload(char *filename)
downloadlist_t *dl, *nxt;
if(cl.downloadlist) //remove from enqued download list
{
if (!strcmp(cl.downloadlist->name, filename))
if (!strcmp(cl.downloadlist->rname, filename))
{
dl = cl.downloadlist;
cl.downloadlist = cl.downloadlist->next;
@ -401,7 +401,7 @@ void CL_DisenqueDownload(char *filename)
{
for (dl = cl.downloadlist; dl->next; dl = dl->next)
{
if (!strcmp(dl->next->name, filename))
if (!strcmp(dl->next->rname, filename))
{
nxt = dl->next->next;
Z_Free(dl->next);
@ -413,10 +413,11 @@ void CL_DisenqueDownload(char *filename)
}
}
void CL_SendDownloadRequest(char *filename, char *localname)
void CL_SendDownloadStartRequest(char *filename, char *localname)
{
strcpy (cls.downloadname, localname);
Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadname);
strcpy (cls.downloadremotename, filename);
strcpy (cls.downloadlocalname, localname);
Con_TPrintf (TL_DOWNLOADINGFILE, cls.downloadlocalname);
// download to a temp name, and only rename
// to the real name when done, so if interrupted
@ -434,13 +435,16 @@ void CL_SendDownloadRequest(char *filename, char *localname)
}
//Do any reloading for the file that just reloaded.
void CL_DownloadFinished(char *filename, char *tempname)
void CL_DownloadFinished(void)
{
int i;
extern int mod_numknown;
char *ext;
extern model_t mod_known[];
char *filename = cls.downloadlocalname;
char *tempname = cls.downloadtempname;
COM_RefreshFSCache_f();
cls.downloadmethod = DL_NONE;
@ -577,7 +581,7 @@ qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned
downloadlist_t *dl;
for (dl = cl.faileddownloads; dl; dl = dl->next)
{
if (!strcmp(dl->name, filename))
if (!strcmp(dl->rname, filename))
{
//if its on the failed list, don't block waiting for it to download
return true;
@ -710,7 +714,8 @@ static qboolean CL_CheckModelResources (char *name)
return false;
// checking for skins in the model
file = COM_LoadMallocFile (name);
FS_LoadFile(name, &file);
if (!file)
{
return false; // couldn't load it
@ -723,7 +728,7 @@ static qboolean CL_CheckModelResources (char *name)
ret = CL_CheckQ2BspWals(file);
else
ret = false;
BZ_Free(file);
FS_FreeFile(file);
return ret;
}
@ -1022,10 +1027,10 @@ void Sound_CheckDownloads (void)
// Con_TPrintf (TLC_CHECKINGSOUNDS);
#ifdef CSQC_DAT
if (cls.fteprotocolextensions & PEXT_CSQC)
// if (cls.fteprotocolextensions & PEXT_CSQC)
{
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
if (*s) //only allow csqc if the server says so, and the 'checksum' matches.
{
extern cvar_t allow_download_csprogs;
unsigned int chksum = strtoul(s, NULL, 0);
@ -1106,11 +1111,11 @@ void CL_RequestNextDownload (void)
dl = cl.downloadlist;
if ((dl->flags & DLLF_OVERWRITE) || !COM_FCheckExists (dl->localname))
CL_SendDownloadRequest(dl->name, dl->localname);
CL_SendDownloadStartRequest(dl->rname, dl->localname);
else
{
Con_Printf("Already have %s\n", dl->localname);
CL_DisenqueDownload(dl->name);
CL_DisenqueDownload(dl->rname);
//recurse a bit.
CL_RequestNextDownload();
@ -1275,10 +1280,10 @@ downloadlist_t *CL_DownloadFailed(char *name)
failed = Z_Malloc(sizeof(downloadlist_t));
failed->next = cl.faileddownloads;
cl.faileddownloads = failed;
Q_strncpyz(failed->name, name, sizeof(failed->name));
Q_strncpyz(failed->rname, name, sizeof(failed->rname));
//if this is what we're currently downloading, close it up now.
if (!stricmp(cls.downloadname, name) || !*name)
if (!stricmp(cls.downloadremotename, name) || !*name)
{
cls.downloadmethod = DL_NONE;
@ -1288,14 +1293,15 @@ downloadlist_t *CL_DownloadFailed(char *name)
cls.downloadqw = NULL;
CL_SendClientCommand(true, "stopdownload");
}
*cls.downloadname = 0;
*cls.downloadlocalname = 0;
*cls.downloadremotename = 0;
}
link = &cl.downloadlist;
while(*link)
{
dl = *link;
if (!strcmp(dl->name, name))
if (!strcmp(dl->rname, name))
{
*link = dl->next;
failed->flags |= dl->flags;
@ -1361,6 +1367,7 @@ void CL_ParseChunkedDownload(void)
else
Con_Printf("Couldn't find file \"%s\" on the server\n", svname);
cls.downloadmethod = 0;
CL_DownloadFailed(svname);
CL_RequestNextDownload();
@ -1370,9 +1377,8 @@ void CL_ParseChunkedDownload(void)
if (cls.downloadmethod == DL_QWCHUNKS)
Host_EndGame("Received second download - \"%s\"\n", svname);
if (stricmp(cls.downloadname, svname))
if (stricmp(svname, "csprogs.dat") || strnicmp(cls.downloadname, "csprogsvers/", 12))
Host_EndGame("Server sent the wrong download - \"%s\" instead of \"%s\"\n", svname, cls.downloadname);
if (stricmp(cls.downloadremotename, svname))
Host_EndGame("Server sent the wrong download - \"%s\" instead of \"%s\"\n", svname, cls.downloadremotename);
//start the new download
@ -1500,11 +1506,12 @@ int CL_RequestADownloadChunk(void)
cls.downloadqw = NULL;
CL_SendClientCommand(true, "stopdownload");
CL_DownloadFinished(cls.downloadname, cls.downloadtempname);
CL_DownloadFinished();
Con_Printf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads());
*cls.downloadname = '\0';
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
cls.downloadpercent = 0;
return -1;
@ -1546,12 +1553,14 @@ void CL_ParseDownload (void)
return; // not in demo playback
}
if (!*cls.downloadname) //huh... that's not right...
if (!*cls.downloadlocalname) //huh... that's not right...
{
Con_Printf(CON_WARNING "Warning: Server sending unknown file.\n");
strcpy(cls.downloadname, "unknown.txt");
strcpy(cls.downloadlocalname, "unknown.txt");
strcpy(cls.downloadtempname, "unknown.tmp");
}
if (!*cls.downloadremotename)
strcpy(cls.downloadremotename, "unknown.txt");
if (size < 0)
{
@ -1562,15 +1571,8 @@ void CL_ParseDownload (void)
VFS_CLOSE (cls.downloadqw);
cls.downloadqw = NULL;
}
if (cl.downloadlist && !strcmp(cl.downloadlist->name, cls.downloadname))
{
downloadlist_t *next;
next = cl.downloadlist->next;
Z_Free(cl.downloadlist);
cl.downloadlist = next;
}
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
CL_RequestNextDownload ();
return;
@ -1595,7 +1597,7 @@ void CL_ParseDownload (void)
{
msg_readcount += size;
Con_TPrintf (TL_FAILEDTOOPEN, cls.downloadtempname);
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
CL_RequestNextDownload ();
return;
}
@ -1647,8 +1649,9 @@ void CL_ParseDownload (void)
{
VFS_CLOSE (cls.downloadqw);
CL_DownloadFinished(cls.downloadname, cls.downloadtempname);
*cls.downloadname = '\0';
CL_DownloadFinished();
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
cls.downloadqw = NULL;
cls.downloadpercent = 0;
@ -1733,7 +1736,7 @@ void CLDP_ParseDownloadBegin(char *s)
}
}
else
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
downloadstarttime = Sys_DoubleTime();
}
@ -1768,7 +1771,7 @@ void CLDP_ParseDownloadFinished(char *s)
else
{
Con_Printf("Download failed: unable to check CRC of download\n");
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
return;
}
@ -1776,18 +1779,19 @@ void CLDP_ParseDownloadFinished(char *s)
if (size != atoi(Cmd_Argv(1)))
{
Con_Printf("Download failed: wrong file size\n");
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
return;
}
if (runningcrc != atoi(Cmd_Argv(2)))
{
Con_Printf("Download failed: wrong crc\n");
CL_DownloadFailed(cls.downloadname);
CL_DownloadFailed(cls.downloadremotename);
return;
}
CL_DownloadFinished(cls.downloadname, cls.downloadtempname);
*cls.downloadname = '\0';
CL_DownloadFinished();
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
cls.downloadqw = NULL;
cls.downloadpercent = 0;
@ -2039,6 +2043,9 @@ void CL_ParseServerData (void)
int i;
MSG_ReadFloat();
cl.playernum[0] = MAX_CLIENTS - 1;
cl.playernum[1] = MAX_CLIENTS - 2;
cl.playernum[2] = MAX_CLIENTS - 3;
cl.playernum[3] = MAX_CLIENTS - 4;
cl.spectator = true;
for (i = 0; i < UPDATE_BACKUP; i++)
cl.frames[i].playerstate[cl.playernum[0]].pm_type = PM_SPECTATOR;
@ -2754,6 +2761,7 @@ void CL_ParseModellist (qboolean lots)
return;
}
Sound_CheckDownloads();
Model_CheckDownloads();
CL_AllowIndependantSendCmd(false); //stop it now, the indep stuff *could* require model tracing.
@ -4064,12 +4072,12 @@ void CL_ParsePrint(char *msg, int level)
}
// CL_PlayerColor: returns color and mask for player_info_t
int CL_PlayerColor(player_info_t *plr, int *name_ormask)
int CL_PlayerColor(player_info_t *plr, qboolean *name_coloured)
{
char *t;
int c;
*name_ormask = 0;
*name_coloured = false;
if (cl.teamfortress) //override based on team
{
@ -4078,35 +4086,35 @@ int CL_PlayerColor(player_info_t *plr, int *name_ormask)
{ //translate q1 skin colours to console colours
case 10:
case 1:
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 4: //red
c = 1;
break;
case 11:
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 3: // green
c = 2;
break;
case 5:
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 12:
c = 3;
break;
case 6:
case 7:
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 8:
case 9:
c = 6;
break;
case 2: // light blue
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 13: //blue
case 14: //blue
c = 5;
break;
default:
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
case 0: // white
c = 7;
break;
@ -4133,7 +4141,7 @@ int CL_PlayerColor(player_info_t *plr, int *name_ormask)
}
if ((c / 7) & 1)
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
c = 1 + (c % 7);
}
@ -4151,7 +4159,7 @@ int CL_PlayerColor(player_info_t *plr, int *name_ormask)
c = plr->userid; // Quake2 can start from 0
if ((c / 7) & 1)
*name_ormask = CON_HIGHCHARSMASK;
*name_coloured = true;
c = 1 + (c % 7);
}
@ -4165,10 +4173,12 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
{
char *name = NULL;
int c;
int name_ormask = 0;
qboolean name_coloured = false;
extern cvar_t cl_parsewhitetext;
qboolean memessage = false;
char fullchatmessage[2048];
fullchatmessage[0] = 0;
if (plrflags & TPM_FAKED)
{
name = rawmsg; // use rawmsg pointer and msg modification to generate null-terminated string
@ -4187,7 +4197,7 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
if (cl_standardchat.value)
{
name_ormask = CON_HIGHCHARSMASK;
name_coloured = true;
c = 7;
}
else
@ -4199,16 +4209,16 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
c = 0; // blacken () on observers
else
{
name_ormask = CON_HIGHCHARSMASK;
name_coloured = true;
c = 7;
}
}
else if (plr)
c = CL_PlayerColor(plr, &name_ormask);
c = CL_PlayerColor(plr, &name_coloured);
else
{
// defaults for fake clients
name_ormask = CON_HIGHCHARSMASK;
name_coloured = true;
c = 7;
}
}
@ -4219,44 +4229,41 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
{
if (memessage)
{
con_ormask = CON_HIGHCHARSMASK;
if (!cl_standardchat.value && (plrflags & TPM_SPECTATOR))
Con_Printf ("^0*^7 ");
Q_strncatz(fullchatmessage, "^m^0*^7 ", sizeof(fullchatmessage));
else
Con_Printf ("* ");
Q_strncatz(fullchatmessage, "^m* ", sizeof(fullchatmessage));
}
if (plrflags & (TPM_TEAM|TPM_OBSERVEDTEAM)) // for team chat don't highlight the name, just the brackets
{
// color is reset every printf so we're safe here
con_ormask = name_ormask;
Con_Printf("^%c(", c);
con_ormask = CON_HIGHCHARSMASK;
Con_Printf("%s", name);
con_ormask = name_ormask;
Con_Printf("^%c)", c);
Q_strncatz(fullchatmessage, va("\1%s^%c(", name_coloured?"":"^m", c), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("%s%s^d", name_coloured?"^m":"", name), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("%s^%c)", name_coloured?"^m":"", c), sizeof(fullchatmessage));
}
else if (cl_standardchat.value)
{
Q_strncatz(fullchatmessage, va("\1%s", name), sizeof(fullchatmessage));
}
else
{
con_ormask = name_ormask;
Con_Printf("^%c%s", c, name);
Q_strncatz(fullchatmessage, va("\1%s^%c%s^d", name_coloured?"":"^m", c, name), sizeof(fullchatmessage));
}
if (!memessage)
{
// only print seperator with an actual player name
con_ormask = CON_HIGHCHARSMASK;
if (!cl_standardchat.value && (plrflags & TPM_SPECTATOR))
Con_Printf ("^0:^7 ");
Q_strncatz(fullchatmessage, "^0: ^d", sizeof(fullchatmessage));
else
Con_Printf (": ");
Q_strncatz(fullchatmessage, ": ", sizeof(fullchatmessage));
}
else
Con_Printf (" ");
Q_strncatz(fullchatmessage, " ", sizeof(fullchatmessage));
}
// print message
con_ormask = CON_HIGHCHARSMASK;
if (cl_parsewhitetext.value && (cl_parsewhitetext.value == 1 || (plrflags & (TPM_TEAM|TPM_OBSERVEDTEAM))))
{
char *t, *u;
@ -4268,35 +4275,35 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
{
*t = 0;
*u = 0;
Con_Printf("%s", msg);
con_ormask = 0;
Con_Printf("%s", t+1);
con_ormask = CON_HIGHCHARSMASK;
Q_strncatz(fullchatmessage, va("%s", msg), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("^m%s^m", t+1), sizeof(fullchatmessage));
msg = u+1;
}
else
break;
}
Con_Printf("%s", msg);
con_ormask = 0;
Q_strncatz(fullchatmessage, va("%s", msg), sizeof(fullchatmessage));
}
else
{
Con_Printf ("%s", msg);
Q_strncatz(fullchatmessage, va("%s", msg), sizeof(fullchatmessage));
}
con_ormask = 0;
CSQC_ParsePrint(fullchatmessage, PRINT_CHAT);
}
// CL_PrintStandardMessage: takes non-chat net messages and performs name coloring
// NOTE: msg is considered destroyable
char acceptedchars[] = {'.', '?', '!', '\'', ',', ':', ' ', '\0'};
void CL_PrintStandardMessage(char *msg)
void CL_PrintStandardMessage(char *msg, int printlevel)
{
int i;
player_info_t *p;
extern cvar_t cl_standardmsg;
char *begin = msg;
char fullmessage[2048];
fullmessage[0] = 0;
// search for player names in message
for (i = 0, p = cl.players; i < MAX_CLIENTS; p++, i++)
@ -4304,7 +4311,7 @@ void CL_PrintStandardMessage(char *msg)
char *v;
char *name;
int len;
int ormask;
qboolean coloured;
char c;
name = p->name;
@ -4340,30 +4347,29 @@ void CL_PrintStandardMessage(char *msg)
}
*v = 0; // cut off message
con_ormask = 0;
// print msg chunk
Con_Printf("%s", msg);
Q_strncatz(fullmessage, msg, sizeof(fullmessage));
msg = v + len; // update search point
// get name color
if (p->spectator || cl_standardmsg.value)
{
ormask = 0;
coloured = false;
c = '7';
}
else
c = '0' + CL_PlayerColor(p, &ormask);
c = '0' + CL_PlayerColor(p, &coloured);
// print name
con_ormask = ormask;
Con_Printf("^%c%s^7", c, name);
Q_strncatz(fullmessage, va("%s^%c%s^7", coloured?"\1":"", c, name), sizeof(fullmessage));
break;
}
}
// print final chunk
con_ormask = 0;
Con_Printf("%s", msg);
Q_strncatz(fullmessage, msg, sizeof(fullmessage));
CSQC_ParsePrint(fullmessage, printlevel);
}
char stufftext[4096];
@ -4626,7 +4632,7 @@ void CL_ParseServerMessage (void)
#endif
{
CL_ParsePrint(s, i);
CL_PrintStandardMessage(s);
CL_PrintStandardMessage(s, i);
}
}
break;
@ -5135,10 +5141,9 @@ void CLQ2_ParseServerMessage (void)
#endif
{
CL_ParsePrint(s, i);
CL_PrintStandardMessage(s);
CL_PrintStandardMessage(s, i);
}
}
con_ormask = 0;
break;
case svcq2_stufftext: //11 // [string] stuffed into client's console buffer, should be \n terminated
s = MSG_ReadString ();
@ -5372,10 +5377,9 @@ void CLNQ_ParseServerMessage (void)
#endif
{
CL_ParsePrint(s, PRINT_HIGH);
CL_PrintStandardMessage(s);
CL_PrintStandardMessage(s, PRINT_HIGH);
}
}
con_ormask = 0;
break;
case svc_disconnect:

View file

@ -255,103 +255,6 @@ int scr_center_lines[MAX_SPLITS];
int scr_erase_lines[MAX_SPLITS];
int scr_erase_center[MAX_SPLITS];
void CopyAndMarkup(conchar_t *dest, qbyte *src, int maxlength)
{
conchar_t ext = CON_WHITEMASK;
conchar_t extstack[20];
int extstackdepth = 0;
if (maxlength < 0)
return; // ...
while(*src && maxlength>0)
{
if (*src == '^')
{
src++;
if (*src >= '0' && *src <= '9')
{
ext = q3codemasks[*src - '0'] | (ext&~CON_Q3MASK);
src++;
continue;
}
else if (*src == '&') // extended code
{
if (isextendedcode(src[1]) && isextendedcode(src[2]))
{
src++; // foreground char
if (*src == '-') // default for FG
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK);
else if (*src >= 'A')
ext = ((*src - ('A' - 10)) << CON_FGSHIFT) | (ext&~CON_FGMASK);
else
ext = ((*src - '0') << CON_FGSHIFT) | (ext&~CON_FGMASK);
src++; // background char
if (*src == '-') // default (clear) for BG
ext &= ~CON_BGMASK & ~CON_NONCLEARBG;
else if (*src >= 'A')
ext = ((*src - ('A' - 10)) << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
else
ext = ((*src - '0') << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
src++;
continue;
}
// else invalid code
*dest++ = '^' | ext;
maxlength--;
if (maxlength <= 0)
break; // need an extra check for writing length
}
else if (*src == 'b') // toggle blink bit
{
src++;
ext ^= CON_BLINKTEXT;
continue;
}
else if (*src == 'a') // toggle alternate charset
{
src++;
ext ^= CON_2NDCHARSETTEXT;
continue;
}
else if (*src == 'h')
{
src++;
ext ^= CON_HALFALPHA;
continue;
}
else if (*src == 's')
{
src++;
if (extstackdepth < sizeof(extstack)/sizeof(extstack[0]))
{
extstack[extstackdepth] = ext;
extstackdepth++;
}
continue;
}
else if (*src == 'r')
{
src++;
if (extstackdepth)
{
extstackdepth--;
ext = extstack[extstackdepth];
}
continue;
}
else if (*src != '^')
src--;
}
if (*src == '\n')
*dest++ = *src++;
else
*dest++ = *src++ | ext;
maxlength--;
}
*dest = 0;
}
// SCR_StringToRGB: takes in "<index>" or "<r> <g> <b>" and converts to an RGB vector
void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale)
{
@ -455,7 +358,7 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
Cbuf_AddText("f_centerprint\n", RESTRICT_LOCAL);
}
CopyAndMarkup (scr_centerstring[pnum], str, sizeof(scr_centerstring[pnum]));
COM_ParseFunString(CON_WHITEMASK, str, scr_centerstring[pnum], sizeof(scr_centerstring[pnum]));
scr_centertime_off[pnum] = scr_centertime.value;
scr_centertime_start[pnum] = cl.time;
@ -735,7 +638,7 @@ void SCR_ShowPics_Draw(void)
for (failed = cl.faileddownloads; failed; failed = failed->next)
{ //don't try displaying ones that we know to have failed.
if (!strcmp(failed->name, sp->picname))
if (!strcmp(failed->rname, sp->picname))
break;
}
if (failed)
@ -1573,7 +1476,7 @@ void SCR_DrawLoading (void)
//downloading files?
if (cls.downloadmethod)
Draw_String(x+8, y+4, va("Downloading %s... %i%%",
cls.downloadname,
cls.downloadlocalname,
cls.downloadpercent));
if (tsize > 1024*1024*16)

View file

@ -337,7 +337,8 @@ typedef struct
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_DARKPLACES, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
vfsfile_t *downloadqw; // file transfer from server
char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH];
char downloadlocalname[MAX_OSPATH];
char downloadremotename[MAX_OSPATH];
int downloadpercent;
int downloadchunknum;
@ -401,7 +402,7 @@ extern client_static_t cls;
extern int nq_dp_protocol;
typedef struct downloadlist_s {
char name[128];
char rname[128];
char localname[128];
unsigned int size;
unsigned int flags;
@ -753,7 +754,7 @@ void CL_MakeActive(char *gamename);
void CL_RegisterSplitCommands(void);
void CL_InitInput (void);
void CL_SendCmd (double frametime);
void CL_SendCmd (double frametime, qboolean mainloop);
void CL_SendMove (usercmd_t *cmd);
#ifdef NQPROT
void CL_ParseTEnt (qboolean nqprot);

View file

@ -414,8 +414,8 @@ void CLQ3_ParseDownload(void)
{
VFS_CLOSE(cls.downloadqw);
cls.downloadqw = NULL;
FS_Rename(cls.downloadtempname, cls.downloadname, FS_ROOT); // ->
*cls.downloadtempname = *cls.downloadname = 0;
FS_Rename(cls.downloadtempname, cls.downloadlocalname, FS_ROOT); // ->
*cls.downloadtempname = *cls.downloadlocalname = *cls.downloadremotename = 0;
cls.downloadmethod = DL_NONE;
FS_ReloadPackFiles();
@ -492,7 +492,8 @@ qboolean CLQ3_SystemInfoChanged(char *str)
Con_Printf("Sending request to download %s\n", com_token);
CLQ3_SendClientCommand("download %s.pk3", com_token);
ccs.downloadchunknum = 0;
snprintf(cls.downloadname, sizeof(cls.downloadname), "%s.pk3", com_token);
snprintf(cls.downloadlocalname, sizeof(cls.downloadlocalname), "%s.pk3", com_token);
snprintf(cls.downloadremotename, sizeof(cls.downloadremotename), "%s.pk3", com_token);
snprintf(cls.downloadtempname, sizeof(cls.downloadtempname), "%s.tmp", com_token);
cls.downloadmethod = DL_Q3;
cls.downloadpercent = 0;

View file

@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
conchar_t con_ormask;
console_t con_main;
console_t *con_current; // point to either con_main
@ -569,126 +568,31 @@ If no console is visible, the notify window will pop up.
================
*/
#define INVIS_CHAR1 (char)12 //red
#define INVIS_CHAR2 (char)138 //green
#define INVIS_CHAR3 (char)160 //blue
void Con_PrintCon (console_t *con, char *txt)
{
conchar_t expanded[4096];
conchar_t *c;
int y;
int c, l;
int l;
static int cr;
int mask;
int maskstack[4];
int maskstackdepth = 0;
COM_ParseFunString(CON_WHITEMASK, txt, expanded, sizeof(expanded));
con->unseentext = true;
if (txt[0] == 1 || txt[0] == 2)
c = expanded;
while (*c)
{
mask = CON_HIGHCHARSMASK|CON_WHITEMASK; // go to colored text
txt++;
}
else
mask = CON_WHITEMASK;
while ( (c = *txt) )
{
if (c == '^')
{
if (txt[1]>='0' && txt[1]<='9')
{
mask = q3codemasks[txt[1]-'0'] + (mask&~CON_Q3MASK); //change colour only.
txt+=2;
continue;
}
if (txt[1] == '&') // extended code
{
if (isextendedcode(txt[2]) && isextendedcode(txt[3]))
{
if (txt[2] == '-') // default for FG
mask = (COLOR_WHITE << CON_FGSHIFT) | (mask&~CON_FGMASK);
else if (txt[2] >= 'A')
mask = ((txt[2] - ('A' - 10)) << CON_FGSHIFT) | (mask&~CON_FGMASK);
else
mask = ((txt[2] - '0') << CON_FGSHIFT) | (mask&~CON_FGMASK);
if (txt[3] == '-') // default (clear) for BG
mask &= ~CON_BGMASK & ~CON_NONCLEARBG;
else if (txt[3] >= 'A')
mask = ((txt[3]- ('A' - 10)) << CON_BGSHIFT) | (mask&~CON_BGMASK) | CON_NONCLEARBG;
else
mask = ((txt[3] - '0') << CON_BGSHIFT) | (mask&~CON_BGMASK) | CON_NONCLEARBG;
txt+=4;
continue;
}
}
if (txt[1] == 'b')
{
mask ^= CON_BLINKTEXT;
txt+=2;
continue;
}
if (txt[1] == 'a')
{
mask ^= CON_2NDCHARSETTEXT;
txt+=2;
continue;
}
if (txt[1] == 'h')
{
mask ^= CON_HALFALPHA;
txt+=2;
continue;
}
if (txt[1] == 's')
{
if (maskstackdepth < sizeof(maskstack)/sizeof(maskstack[0]))
{
maskstack[maskstackdepth] = mask;
maskstackdepth++;
}
txt+=2;
continue;
}
if (txt[1] == 'r')
{
if (maskstackdepth)
{
maskstackdepth--;
mask = maskstack[maskstackdepth];
}
txt+=2;
continue;
}
}
if (c == '&' && txt[1] == 'c')
{
// ezQuake color codes
if (ishexcode(txt[2]) && ishexcode(txt[3]) && ishexcode(txt[4]))
{
// Just strip it for now
// TODO: Colorize the console properly
txt += 5;
continue;
}
}
if (c=='\t')
c = ' ';
if (*c&CON_CHARMASK=='\t')
*c = (*c&~CON_CHARMASK)|' ';
// count word length
for (l=0 ; l< con->linewidth ; l++)
if ( txt[l] <= ' ')
if ( c[l]&CON_CHARMASK <= ' ')
break;
// word wrap
if (l != con->linewidth && (con->x + l > con->linewidth) )
con->x = 0;
txt++;
if (cr)
{
con->current--;
@ -703,7 +607,7 @@ void Con_PrintCon (console_t *con, char *txt)
con_times[con->current % NUM_CON_TIMES] = realtime;
}
switch (c)
switch (*c & (CON_CHARMASK&~CON_HIGHCHARSMASK))
{
case '\n':
con->x = 0;
@ -716,12 +620,13 @@ void Con_PrintCon (console_t *con, char *txt)
default: // display character and advance
y = con->current % con->totallines;
con->text[y*con->linewidth+con->x] = (qbyte)c | mask | con_ormask;
con->text[y*con->linewidth+con->x] = *c;
con->x++;
if (con->x >= con->linewidth)
con->x = 0;
break;
}
c++;
}
}
@ -1404,7 +1309,7 @@ void Con_DrawConsole (int lines, qboolean noback)
{
unsigned int count, total;
qboolean extra;
progresstext = cls.downloadname;
progresstext = cls.downloadlocalname;
progresspercent = cls.downloadpercent;
if ((int)(realtime/2)&1)

View file

@ -49,7 +49,7 @@ void IN_ModeChanged (void)
}
// called whenever screen dimensions change
void IN_Move (usercmd_t *cmd, int pnum)
void IN_Move (float *movements, int pnum)
{
float tx, ty, filterfrac;
@ -71,7 +71,7 @@ void IN_Move (usercmd_t *cmd, int pnum)
if ((in_strafe.state[pnum] & 1) || (lookstrafe.value && in_mlook.state[pnum]))
{
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
}
else
{
@ -88,7 +88,7 @@ void IN_Move (usercmd_t *cmd, int pnum)
}
else
{
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
mouse_x = mouse_y = 0.0;

View file

@ -297,7 +297,7 @@ void IN_Init (void)
#endif
IN_ReInit();
}
void IN_Move (usercmd_t *cmd, int pnum) //add mouse movement to cmd
void IN_Move (float *movements, int pnum) //add mouse movement to cmd
{
mouse_x *= sensitivity.value*in_sensitivityscale;
mouse_y *= sensitivity.value*in_sensitivityscale;
@ -307,7 +307,7 @@ void IN_Move (usercmd_t *cmd, int pnum) //add mouse movement to cmd
{
// add mouse X/Y movement to cmd
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
else
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
@ -323,9 +323,9 @@ void IN_Move (usercmd_t *cmd, int pnum) //add mouse movement to cmd
else
{
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
cmd->upmove -= m_forward.value * mouse_y;
movements[2] -= m_forward.value * mouse_y;
else
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
}

View file

@ -280,7 +280,7 @@ void IN_RawInput_DeInit(void);
// forward-referenced functions
void IN_StartupJoystick (void);
void Joy_AdvancedUpdate_f (void);
void IN_JoyMove (usercmd_t *cmd, int pnum);
void IN_JoyMove (float *movements, int pnum);
/*
===========
@ -1397,7 +1397,7 @@ void IN_MouseEvent (int mstate)
}
}
static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
{
extern int mousecursor_x, mousecursor_y;
extern int mousemove_x, mousemove_y;
@ -1522,7 +1522,7 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
}
if (!cmd)
if (!movements)
{
return;
}
@ -1532,7 +1532,7 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
// add mouse X/Y movement to cmd
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
else
{
// if ((int)((cl.viewangles[pnum][PITCH]+89.99)/180) & 1)
@ -1552,9 +1552,9 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
else
{
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
cmd->upmove -= m_forward.value * mouse_y;
movements[2] -= m_forward.value * mouse_y;
else
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
}
@ -1565,7 +1565,7 @@ static void ProcessMouse(mouse_t *mouse, usercmd_t *cmd, int pnum)
IN_MouseMove
===========
*/
void IN_MouseMove (usercmd_t *cmd, int pnum)
void IN_MouseMove (float *movements, int pnum)
{
#ifdef RGLQUAKE
extern int glwidth, glheight;
@ -1744,22 +1744,22 @@ void IN_MouseMove (usercmd_t *cmd, int pnum)
for (x = 0; x < rawmicecount; x++)
{
ProcessMouse(rawmice + x, cmd, 0);
ProcessMouse(rawmice + x, movements, 0);
}
}
else if (pnum < rawmicecount)
{
ProcessMouse(rawmice + pnum, cmd, pnum);
ProcessMouse(rawmice + pnum, movements, pnum);
}
}
#endif
if (pnum == 0)
ProcessMouse(&sysmouse, cmd, pnum);
ProcessMouse(&sysmouse, movements, pnum);
#ifdef SERIALMOUSE
if (pnum == 1 || cl.splitclients<2)
ProcessMouse(&serialmouse, cmd, pnum);
ProcessMouse(&serialmouse, movements, pnum);
#endif
}
@ -1769,14 +1769,14 @@ void IN_MouseMove (usercmd_t *cmd, int pnum)
IN_Move
===========
*/
void IN_Move (usercmd_t *cmd, int pnum)
void IN_Move (float *movements, int pnum)
{
if (ActiveApp && !Minimized)
{
IN_MouseMove (cmd, pnum);
IN_MouseMove (movements, pnum);
if (pnum == 1 || cl.splitclients<2)
IN_JoyMove (cmd, pnum);
IN_JoyMove (movements, pnum);
}
}
@ -2219,7 +2219,7 @@ qboolean IN_ReadJoystick (void)
IN_JoyMove
===========
*/
void IN_JoyMove (usercmd_t *cmd, int pnum)
void IN_JoyMove (float *movements, int pnum)
{
float speed, aspeed;
float fAxisValue, fTemp;
@ -2313,7 +2313,7 @@ void IN_JoyMove (usercmd_t *cmd, int pnum)
// user wants forward control to be forward control
if (fabs(fAxisValue) > joy_forwardthreshold.value)
{
cmd->forwardmove += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value;
movements[0] += (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value;
}
}
break;
@ -2321,7 +2321,7 @@ void IN_JoyMove (usercmd_t *cmd, int pnum)
case AxisSide:
if (fabs(fAxisValue) > joy_sidethreshold.value)
{
cmd->sidemove += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
movements[1] += (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
}
break;
@ -2331,7 +2331,7 @@ void IN_JoyMove (usercmd_t *cmd, int pnum)
// user wants turn control to become side control
if (fabs(fAxisValue) > joy_sidethreshold.value)
{
cmd->sidemove -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
movements[2] -= (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value;
}
}
else

View file

@ -28,7 +28,7 @@ void IN_Shutdown (void);
void IN_Commands (void);
// oportunity for devices to stick commands on the script buffer
void IN_Move (usercmd_t *cmd, int pnum);
void IN_Move (float *movements, int pnum);
// add additional movement on top of the keyboard move cmd
void IN_ModeChanged (void);

View file

@ -1229,34 +1229,35 @@ cin_t *Media_Static_TryLoad(char *name)
int imagewidth;
int imageheight;
int fsize;
char fullname[MAX_QPATH];
qbyte *file;
sprintf(fullname, "%s", name);
file = COM_LoadMallocFile(fullname); //read file
fsize = FS_LoadFile(fullname, &file);
if (!file)
{
sprintf(fullname, "pics/%s", name);
file = COM_LoadMallocFile(fullname); //read file
fsize = FS_LoadFile(fullname, &file);
if (!file)
return NULL;
}
if ((staticfilmimage = ReadPCXFile(file, com_filesize, &imagewidth, &imageheight)) || //convert to 32 rgba if not corrupt
(staticfilmimage = ReadTargaFile(file, com_filesize, &imagewidth, &imageheight, false)) ||
if ((staticfilmimage = ReadPCXFile(file, fsize, &imagewidth, &imageheight)) || //convert to 32 rgba if not corrupt
(staticfilmimage = ReadTargaFile(file, fsize, &imagewidth, &imageheight, false)) ||
#ifdef AVAIL_JPEGLIB
(staticfilmimage = ReadJPEGFile(file, com_filesize, &imagewidth, &imageheight)) ||
(staticfilmimage = ReadJPEGFile(file, fsize, &imagewidth, &imageheight)) ||
#endif
#ifdef AVAIL_PNGLIB
(staticfilmimage = ReadPNGFile(file, com_filesize, &imagewidth, &imageheight, fullname)) ||
(staticfilmimage = ReadPNGFile(file, fsize, &imagewidth, &imageheight, fullname)) ||
#endif
0)
{
BZ_Free(file); //got image data
FS_FreeFile(file); //got image data
}
else
{
BZ_Free(file); //got image data
FS_FreeFile(file); //got image data
Con_Printf("Static cinematic format not supported.\n"); //not supported format
return NULL;
}

View file

@ -268,22 +268,22 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
extern qbyte translationTable[256];
setupmenu_t *info = menu->data;
mpic_t *p;
qbyte *f;
void *f;
if (info->skinedit->modified)
{
info->skinedit->modified = false;
f = COM_LoadMallocFile (va("gfx/player/%s.lmp", info->skinedit->text));
FS_LoadFile(va("gfx/player/%s.lmp", info->skinedit->text), &f);
if (!f)
f = COM_LoadMallocFile("gfx/menuplyr.lmp");
FS_LoadFile("gfx/menuplyr.lmp", &f);
if (f)
{
info->tiwidth = ((int*)f)[0];
info->tiheight = ((int*)f)[1];
memcpy(info->translationimage, f+8, info->tiwidth*info->tiheight);
BZ_Free(f);
FS_FreeFile(f);
}
}

View file

@ -1445,14 +1445,15 @@ static void P_LoadParticleSet(char *name, qboolean first)
Cbuf_AddText(particle_set_tsshaft, RESTRICT_LOCAL);
else
{
char *file = COM_LoadMallocFile(va("particles/%s.cfg", name));
char *file;
FS_LoadFile(va("particles/%s.cfg", name), (void**)&file);
if (!file)
file = COM_LoadMallocFile(va("%s.cfg", name));
FS_LoadFile(va("%s.cfg", name), (void**)&file);
if (file)
{
Cbuf_AddText(file, restrictlevel);
Cbuf_AddText("\n", restrictlevel);
BZ_Free(file);
FS_FreeFile(file);
}
else if (first)
{

View file

@ -65,6 +65,8 @@ static int csqc_fakereadbyte;
static int csqc_lplayernum;
static qboolean csqc_isdarkplaces;
static char csqc_printbuffer[8192];
#define CSQCPROGSGROUP "CSQC progs control"
cvar_t pr_csmaxedicts = SCVAR("pr_csmaxedicts", "3072");
cvar_t cl_csqcdebug = SCVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...)
@ -145,6 +147,7 @@ typedef enum
globalfunction(draw_function, "CSQC_UpdateView"); \
globalfunction(parse_stuffcmd, "CSQC_Parse_StuffCmd"); \
globalfunction(parse_centerprint, "CSQC_Parse_CenterPrint"); \
globalfunction(parse_print, "CSQC_Parse_Print"); \
globalfunction(input_event, "CSQC_InputEvent"); \
globalfunction(input_frame, "CSQC_Input_Frame");/*EXT_CSQC_1*/ \
globalfunction(console_command, "CSQC_ConsoleCommand"); \
@ -2133,6 +2136,51 @@ static void PF_cs_particleeffectnum (progfuncs_t *prinst, struct globalvars_s *p
G_FLOAT(OFS_RETURN) = pe->FindParticleType(effectname)+1;
}
static void PF_cs_sendevent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent;
int i;
char *eventname = PR_GetStringOfs(prinst, OFS_PARM0);
char *argtypes = PR_GetStringOfs(prinst, OFS_PARM1);
MSG_WriteByte(&cls.netchan.message, clc_qcrequest);
for (i = 0; i < 6; i++)
{
if (argtypes[i] == 's')
{
MSG_WriteByte(&cls.netchan.message, ev_string);
MSG_WriteString(&cls.netchan.message, PR_GetStringOfs(prinst, OFS_PARM2+i*3));
}
else if (argtypes[i] == 'f')
{
MSG_WriteByte(&cls.netchan.message, ev_float);
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3));
}
else if (argtypes[i] == 'i')
{
MSG_WriteByte(&cls.netchan.message, ev_integer);
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3));
}
else if (argtypes[i] == 'v')
{
MSG_WriteByte(&cls.netchan.message, ev_vector);
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3+0));
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3+1));
MSG_WriteFloat(&cls.netchan.message, G_FLOAT(OFS_PARM2+i*3+2));
}
else if (argtypes[i] == 'e')
{
ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM2+i*3);
MSG_WriteByte(&cls.netchan.message, ev_entity);
MSG_WriteShort(&cls.netchan.message, ent->v->entnum);
}
else
break;
}
MSG_WriteByte(&cls.netchan.message, 0);
MSG_WriteString(&cls.netchan.message, eventname);
}
static void cs_set_input_state (usercmd_t *cmd)
{
if (csqcg.input_timelength)
@ -5105,13 +5153,13 @@ static struct {
{"freepic", PF_CL_free_pic, 319}, // #319 void(string name) freepic (EXT_CSQC)
//320
{"drawcharacter", PF_CL_drawcharacter, 320}, // #320 float(vector position, float character, vector scale, vector rgb, float alpha [, float flag]) drawcharacter (EXT_CSQC, [EXT_CSQC_???])
{"drawstring", PF_CL_drawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???])
{"drawrawstring", PF_CL_drawrawstring, 321}, // #321 float(vector position, string text, vector scale, vector rgb, float alpha [, float flag]) drawstring (EXT_CSQC, [EXT_CSQC_???])
{"drawpic", PF_CL_drawpic, 322}, // #322 float(vector position, string pic, vector size, vector rgb, float alpha [, float flag]) drawpic (EXT_CSQC, [EXT_CSQC_???])
{"drawfill", PF_CL_drawfill, 323}, // #323 float(vector position, vector size, vector rgb, float alpha [, float flag]) drawfill (EXT_CSQC, [EXT_CSQC_???])
{"drawsetcliparea", PF_CL_drawsetcliparea, 324}, // #324 void(float x, float y, float width, float height) drawsetcliparea (EXT_CSQC_???)
{"drawresetcliparea", PF_CL_drawresetcliparea, 325}, // #325 void(void) drawresetcliparea (EXT_CSQC_???)
{"drawcolorcodedstring", PF_CL_drawstring, 326}, // #326
{"drawstring", PF_CL_drawcolouredstring, 326}, // #326
{"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES'
{"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES'
// {"?", PF_Fixme, 329}, // #329 EXT_CSQC_'DARKPLACES'
@ -5158,7 +5206,7 @@ static struct {
// {"?", PF_Fixme, 356}, // #356
// {"?", PF_Fixme, 357}, // #357
// {"?", PF_Fixme, 358}, // #358
// {"?", PF_Fixme, 359}, // #359
{"sendevent", PF_cs_sendevent, 359}, // #359 void(string evname, string evargs, ...) (EXT_CSQC_1)
//360
//note that 'ReadEntity' is pretty hard to implement reliably. Modders should use a combination of ReadShort, and findfloat, and remember that it might not be known clientside (pvs culled or other reason)
@ -5622,15 +5670,21 @@ qboolean CSQC_Init (unsigned int checksum)
CSQC_InitFields(); //let the qclib know the field order that the engine needs.
csqc_isdarkplaces = false;
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 32199, NULL, 0) < 0) //no per-progs builtins.
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) < 0) //no per-progs builtins.
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) < 0) //no per-progs builtins.
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) < 0) //no per-progs builtins.
{
CSQC_Shutdown();
//failed to load or something
return false;
}
}
else
csqc_isdarkplaces = true;
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n");
}
if (setjmp(csqc_abort))
{
@ -5873,7 +5927,7 @@ qboolean CSQC_DrawView(void)
*/
if (csqcg.cltime)
*csqcg.cltime = cl.time;
if (csqcg.cltime)
if (csqcg.svtime)
*csqcg.svtime = cl.servertime;
CSQC_RunThreads(); //wake up any qc threads
@ -5971,6 +6025,64 @@ qboolean CSQC_LoadResource(char *resname, char *restype)
return !!G_FLOAT(OFS_RETURN);
}
void CSQC_ParsePrint(char *message, int printlevel)
{
void *pr_globals;
int bufferpos;
char *nextline;
qboolean doflush;
if (!csqcprogs || !csqcg.parse_print)
{
Con_Printf("%s", message);
return;
}
bufferpos = strlen(csqc_printbuffer);
//fix-up faked bot chat
if (*message == '\1' && *csqc_printbuffer == '\1')
message++;
while(*message)
{
nextline = strchr(message, '\n');
if (nextline)
{
nextline+=1;
doflush = true;
}
else
{
nextline = message+strlen(message);
doflush = false;
}
if (bufferpos + nextline-message >= sizeof(csqc_printbuffer))
{
//if this would overflow the buffer, cap its length and flush the buffer
//this copes with too many strings and too long strings.
nextline = message + sizeof(csqc_printbuffer)-1 - bufferpos;
doflush = true;
}
memcpy(csqc_printbuffer+bufferpos, message, nextline-message);
bufferpos += nextline-message;
csqc_printbuffer[bufferpos] = '\0';
message = nextline;
if (doflush)
{
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, csqc_printbuffer));
G_FLOAT(OFS_PARM1) = printlevel;
PR_ExecuteProgram (csqcprogs, csqcg.parse_print);
bufferpos = 0;
csqc_printbuffer[bufferpos] = 0;
}
}
}
qboolean CSQC_StuffCmd(int lplayernum, char *cmd)
{
void *pr_globals;

View file

@ -382,8 +382,8 @@ void PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_FLOAT(OFS_RETURN) = 1;
}
//float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
void PF_CL_drawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
//float drawrawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455;
void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *pos = G_VECTOR(OFS_PARM0);
char *text = PR_GetStringOfs(prinst, OFS_PARM1);
@ -406,10 +406,36 @@ void PF_CL_drawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
}
//float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455;
void PF_CL_drawcolouredstring (progfuncs_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);
// float *alpha = G_FLOAT(OFS_PARM3);
// float flag = G_FLOAT(OFS_PARM4);
if (!text)
{
G_FLOAT(OFS_RETURN) = -1; //was null..
return;
}
Draw_FunString(pos[0], pos[1], text);
}
void PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
PF_strlen(prinst, pr_globals);
// G_FLOAT(OFS_RETURN)*=8;
char *text = PR_GetStringOfs(prinst, OFS_PARM0);
qboolean usecolours = G_FLOAT(OFS_PARM1);
if (usecolours)
{
G_FLOAT(OFS_RETURN) = COM_FunStringLength(text)*8;
}
else
{
G_FLOAT(OFS_RETURN) = strlen(text)*8;
}
}
#define DRAWFLAG_NORMAL 0
@ -1389,7 +1415,7 @@ builtin_t menu_builtins[] = {
PF_CL_precache_pic,//2
PF_CL_free_pic,//3
PF_CL_drawcharacter,//4
PF_CL_drawstring,//5
PF_CL_drawrawstring,//5
PF_CL_drawpic,//6
PF_CL_drawfill,//7
PF_CL_drawsetcliparea,//8

View file

@ -146,222 +146,32 @@ int Sbar_BottomColour(player_info_t *p)
return p->rbottomcolor;
}
void Draw_FunString(int x, int y, unsigned char *str)
void Draw_ExpandedString(int x, int y, conchar_t *str)
{
int ext = CON_WHITEMASK;
int extstack[4];
int extstackdepth = 0;
while(*str)
{
if (*str == '^')
{
str++;
if (*str >= '0' && *str <= '9')
{
ext = q3codemasks[*str++-'0'] | (ext&~CON_Q3MASK); //change colour only.
continue;
}
else if (*str == '&') // extended code
{
if (isextendedcode(str[1]) && isextendedcode(str[2]))
{
str++;// foreground char
if (*str == '-') // default for FG
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK);
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_FGSHIFT) | (ext&~CON_FGMASK);
else
ext = ((*str - '0') << CON_FGSHIFT) | (ext&~CON_FGMASK);
str++; // background char
if (*str == '-') // default (clear) for BG
ext &= ~CON_BGMASK & ~CON_NONCLEARBG;
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
else
ext = ((*str - '0') << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
str++;
continue;
}
// else invalid code
goto messedup;
}
else if (*str == 'a')
{
str++;
ext ^= CON_2NDCHARSETTEXT;
continue;
}
else if (*str == 'b')
{
str++;
ext ^= CON_BLINKTEXT;
continue;
}
else if (*str == 'h')
{
str++;
ext ^= CON_HALFALPHA;
continue;
}
else if (*str == 's') //store on stack (it's great for names)
{
str++;
if (extstackdepth < sizeof(extstack)/sizeof(extstack[0]))
{
extstack[extstackdepth] = ext;
extstackdepth++;
}
continue;
}
else if (*str == 'r') //restore from stack (it's great for names)
{
str++;
if (extstackdepth)
{
extstackdepth--;
ext = extstack[extstackdepth];
}
continue;
}
else if (*str == '^')
{
Draw_ColouredCharacter(x, y, '^' | ext);
str++;
}
else
{
Draw_ColouredCharacter(x, y, '^' | ext);
x += 8;
Draw_ColouredCharacter (x, y, (*str++) | ext);
}
x += 8;
continue;
}
if (*str == '&' && str[1] == 'c')
{
// ezQuake color codes
if (ishexcode(str[2]) && ishexcode(str[3]) && ishexcode(str[4]))
{
// Just strip it for now
// TODO: Colorize the console properly
str += 5;
continue;
}
}
messedup:
Draw_ColouredCharacter (x, y, (*str++) | ext);
Draw_ColouredCharacter (x, y, *str++);
x += 8;
}
}
void Draw_FunStringLen(int x, int y, unsigned char *str, int len)
void Draw_FunString(int x, int y, unsigned char *str)
{
int ext = CON_WHITEMASK;
int extstack[4];
int extstackdepth = 0;
conchar_t buffer[2048];
COM_ParseFunString(CON_WHITEMASK, str, buffer, sizeof(buffer));
Draw_ExpandedString(x, y, buffer);
}
while(*str)
{
if (*str == '^')
{
str++;
if (*str >= '0' && *str <= '9')
{
ext = q3codemasks[*str++-'0'] | (ext&~CON_Q3MASK); //change colour only.
continue;
}
else if (*str == '&') // extended code
{
if (isextendedcode(str[1]) && isextendedcode(str[2]))
{
str++; // foreground char
if (*str == '-') // default for FG
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK);
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_FGSHIFT) | (ext&~CON_FGMASK);
else
ext = ((*str - '0') << CON_FGSHIFT) | (ext&~CON_FGMASK);
str++; // background char
if (*str == '-') // default (clear) for BG
ext &= ~CON_BGMASK & ~CON_NONCLEARBG;
else if (*str >= 'A')
ext = ((*str - ('A' - 10)) << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
else
ext = ((*str - '0') << CON_BGSHIFT) | (ext&~CON_BGMASK) | CON_NONCLEARBG;
str++;
continue;
}
// else invalid code
Draw_ColouredCharacter(x, y, '^' | ext);
Draw_ColouredCharacter(x, y, '&' | ext);
str++;
continue;
}
else if (*str == 'a')
{
str++;
ext ^= CON_2NDCHARSETTEXT;
continue;
}
else if (*str == 'b')
{
str++;
ext ^= CON_BLINKTEXT;
continue;
}
else if (*str == 'h')
{
str++;
ext ^= CON_HALFALPHA;
continue;
}
else if (*str == 's') //store on stack (it's great for names)
{
str++;
if (extstackdepth < sizeof(extstack)/sizeof(extstack[0]))
{
extstack[extstackdepth] = ext;
extstackdepth++;
}
}
else if (*str == 'r') //restore from stack (it's great for names)
{
str++;
if (extstackdepth)
{
extstackdepth--;
ext = extstack[extstackdepth];
}
continue;
}
else if (*str == '^')
{
if (--len< 0)
break;
Draw_ColouredCharacter(x, y, '^' | ext);
str++;
}
else
{
if (--len< 0)
break;
if (--len< 0)
break;
Draw_ColouredCharacter(x, y, '^' | ext);
x += 8;
Draw_ColouredCharacter (x, y, (*str++) | ext);
}
x += 8;
continue;
}
if (--len< 0)
break;
Draw_ColouredCharacter (x, y, (*str++) | ext);
x += 8;
}
void Draw_FunStringLen(int x, int y, unsigned char *str, int numchars)
{
conchar_t buffer[2048];
if (numchars > sizeof(buffer)-1)
numchars = sizeof(buffer)-1;
COM_ParseFunString(CON_WHITEMASK, str, buffer, numchars+1);
Draw_ExpandedString(x, y, buffer);
}
static qboolean largegame = false;

View file

@ -1393,6 +1393,7 @@ void R_DrawNameTags(void)
void V_RenderPlayerViews(int plnum)
{
int oldnuments;
#ifdef SIDEVIEWS
int viewnum;
#endif
@ -1416,6 +1417,9 @@ void V_RenderPlayerViews(int plnum)
V_CalcRefdef (plnum);
}
oldnuments = cl_numvisedicts;
CL_LinkViewModel ();
#ifdef SWQUAKE
if (cl.splitclients>1)
r_viewchanged = true;
@ -1432,6 +1436,8 @@ void V_RenderPlayerViews(int plnum)
R_DrawNameTags();
}
cl_numvisedicts = oldnuments;
if (scr_chatmode == 2)
{
extern vec3_t desired_position[MAX_SPLITS];

View file

@ -521,9 +521,10 @@ void Cmd_Exec_f (void)
else
Q_strncpyz(name, Cmd_Argv(1), sizeof(name));
if ((f = (char *)COM_LoadMallocFile(name)))
FS_LoadFile(name, &f);
if (FS_LoadFile(name, &f) != -1)
;
else if ((f = (char *)COM_LoadMallocFile(va("%s.cfg", name))))
else if (FS_LoadFile(va("%s.cfg", name), &f) != -1)
;
else
{
@ -535,7 +536,7 @@ void Cmd_Exec_f (void)
// don't execute anything as if it was from server
Cbuf_InsertText (f, Cmd_FromGamecode() ? RESTRICT_INSECURE : Cmd_ExecLevel, true);
BZ_Free(f);
FS_FreeFile(f);
}

View file

@ -1665,7 +1665,7 @@ conchar_t q3codemasks[MAXQ3COLOURS] = {
//Strips out the flags
void COM_DeFunString(unsigned long *str, char *out, int outsize, qboolean ignoreflags)
void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflags)
{
if (ignoreflags)
{
@ -1746,12 +1746,30 @@ void COM_DeFunString(unsigned long *str, char *out, int outsize, qboolean ignore
}
//Takes a q3-style fun string, and returns an expanded string-with-flags
void COM_ParseFunString(char *str, unsigned long *out, int outsize)
void COM_ParseFunString(conchar_t defaultflags, char *str, conchar_t *out, int outsize)
{
int ext = CON_WHITEMASK;
int extstack[4];
conchar_t extstack[4];
int extstackdepth = 0;
conchar_t ext;
#if 0
while(*str)
{
*out++ = CON_WHITEMASK|(unsigned char)*str++;
}
*out = 0;
return;
#endif
if (*str == 1 || *str == 2)
{
defaultflags |= CON_HIGHCHARSMASK;
str++;
}
ext = defaultflags;
while(*str)
{
if (*str == '^')
@ -1798,6 +1816,18 @@ void COM_ParseFunString(char *str, unsigned long *out, int outsize)
ext ^= CON_BLINKTEXT;
continue;
}
else if (*str == 'd')
{
str++;
ext = defaultflags;
continue;
}
else if (*str == 'm')
{
str++;
ext ^= CON_HIGHCHARSMASK;
continue;
}
else if (*str == 'h')
{
str++;
@ -1838,14 +1868,62 @@ void COM_ParseFunString(char *str, unsigned long *out, int outsize)
*out++ = '^' | ext;
if (!--outsize)
break;
*out++ = (*str++) | ext;
*out++ = (unsigned char)(*str++) | ext;
}
continue;
}
if (*str == '&' && str[1] == 'c')
{
// ezQuake color codes
if (ishexcode(str[2]) && ishexcode(str[3]) && ishexcode(str[4]))
{
//we don't support the full 12bit colour depth (only 4-bit CGA)
//so find the closest that we do support
int best = 1;
float bd = 255*255*255, d;
int c;
float r, g, b;
if (str[2] >= '0' && str[2] <= '9')
r = (str[2]-'0') / (float)0xf;
else if (str[2] >= 'A' && str[2] <= 'F')
r = (str[2]-'A'+10) / (float)0xf;
else
r = (str[2]-'a'+10) / (float)0xf;
if (str[3] >= '0' && str[3] <= '9')
g = (str[3]-'0') / (float)0xf;
else if (str[3] >= 'A' && str[3] <= 'F')
g = (str[3]-'A'+10) / (float)0xf;
else
g = (str[3]-'a'+10) / (float)0xf;
if (str[4] >= '0' && str[4] <= '9')
b = (str[4]-'0') / (float)0xf;
else if (str[4] >= 'A' && str[4] <= 'F')
b = (str[4]-'A'+10) / (float)0xf;
else
b = (str[4]-'a'+10) / (float)0xf;
for (c = 0; c < sizeof(consolecolours)/sizeof(consolecolours[0]); c++)
{
d = (consolecolours[c].fr-r)*(consolecolours[c].fr-r) +
(consolecolours[c].fg-g)*(consolecolours[c].fg-g) +
(consolecolours[c].fb-b)*(consolecolours[c].fb-b);
if (d < bd)
{
best = c;
bd = d;
}
}
ext = (best << CON_FGSHIFT) | (ext&~CON_FGMASK);
str += 5;
continue;
}
}
messedup:
if (!--outsize)
break;
*out++ = (*str++) | ext;
*out++ = (unsigned char)(*str++) | ext;
}
*out = 0;
}
@ -1888,6 +1966,12 @@ int COM_FunStringLength(unsigned char *str)
}
continue;
}
if (*str == '&' && str[1] == 'c' && ishexcode(str[2]) && ishexcode(str[3]) && ishexcode(str[4]))
{
//ezquake colour codes
str += 5;
continue;
}
messedup:
len++;
str++;
@ -2983,7 +3067,7 @@ void COM_Effectinfo_Reload(void)
COM_Effectinfo_Add(dpnames[i]);
f = COM_LoadMallocFile("effectinfo.txt");
FS_LoadFile("effectinfo.txt", &f);
if (!f)
return;
while (*f)
@ -3004,6 +3088,7 @@ void COM_Effectinfo_Reload(void)
} while(*f && strcmp(com_token, "\n"));
}
}
FS_FreeFile(f);
}
unsigned int COM_Effectinfo_ForName(const char *efname)

View file

@ -256,14 +256,16 @@ void COM_Init (void);
void COM_InitArgv (int argc, const char **argv);
void COM_ParsePlusSets (void);
typedef unsigned int conchar_t;
void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflags);
void COM_ParseFunString(conchar_t ext, char *str, conchar_t *out, int outsize); //ext is usually CON_WHITEMASK
int COM_FunStringLength(unsigned char *str);
char *COM_SkipPath (const char *pathname);
void COM_StripExtension (const char *in, char *out, int outlen);
void COM_FileBase (const char *in, char *out, int outlen);
int COM_FileSize(const char *path);
void COM_DefaultExtension (char *path, char *extension, int maxlen);
void COM_DeFunString(unsigned long *str, char *out, int outsize, qboolean ignoreflags);
void COM_ParseFunString(char *str, unsigned long *out, int outsize);
int COM_FunStringLength(unsigned char *str);
char *COM_FileExtension (const char *in);
void COM_CleanUpPath(char *str);
@ -367,7 +369,6 @@ qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize);
qbyte *COM_LoadTempFile (const char *path);
qbyte *COM_LoadTempFile2 (const char *path); //allocates a little bit more without freeing old temp
qbyte *COM_LoadHunkFile (const char *path);
qbyte *COM_LoadMallocFile (const char *path);
void COM_LoadCacheFile (const char *path, struct cache_user_s *cu);
void COM_CreatePath (char *path);
void COM_Gamedir (const char *dir);
@ -377,6 +378,9 @@ char *COM_NextPath (char *prevpath);
void COM_FlushFSCache(void); //a file was written using fopen
void COM_RefreshFSCache_f(void);
int FS_LoadFile(char *name, void **file);
void FS_FreeFile(void *file);
qboolean COM_LoadMapPackFile(const char *name, int offset);
void COM_FlushTempoaryPacks(void);

View file

@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// console
//
typedef unsigned int conchar_t;
#define MAXCONCOLOURS 16
typedef struct {
float fr, fg, fb;
@ -109,8 +107,6 @@ typedef struct console_s
extern console_t con_main;
extern console_t *con_current; // point to either con_main or con_chat
extern conchar_t con_ormask;
extern int scr_chatmode;
//extern int con_totallines;

View file

@ -1265,10 +1265,12 @@ qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize)
}
/*warning: at some point I'll change this function to return only read-only buffers*/
int FS_LoadFile(char *name, void **file)
{
*file = COM_LoadMallocFile(name);
if (!*file)
return -1;
return com_filesize;
}
void FS_FreeFile(void *file)
@ -1581,9 +1583,9 @@ char *COM_NextPath (char *prevpath)
#ifndef CLIENTONLY
char *COM_GetPathInfo (int i, int *crc)
{
#ifdef WEBSERVER
extern cvar_t httpserver;
#endif
//#ifdef WEBSERVER
// extern cvar_t httpserver;
//#endif
searchpath_t *s;
static char name[MAX_OSPATH];
@ -2000,6 +2002,9 @@ void FS_ReloadPackFiles_f(void)
#ifdef _WIN32
#include <windows.h>
#ifdef MINGW
#define byte BYTE //some versions of mingw headers are broken slightly. this lets it compile.
#endif
#include <shlobj.h>
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen)
{
@ -2131,7 +2136,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
//append SteamApps\common\hexen 2
}
#ifndef NPQTV //this is *really* unfortunate, but doing this crashes the browser
#if !defined(NPQTV) && !defined(SERVERONLY) //this is *really* unfortunate, but doing this crashes the browser
//I assume its because the client
if (poshname)

View file

@ -1,38 +1,44 @@
#include "quakedef.h"
#include "fs.h"
#ifndef _WIN32
#define VFSSTDIO_Open VFSOS_Open
#define stdiofilefuncs osfilefuncs
#endif
#define FSSTDIO_OpenTemp FS_OpenTemp
typedef struct {
vfsfile_t funcs;
FILE *handle;
} vfsosfile_t;
int VFSOS_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
} vfsstdiofile_t;
static int VFSSTDIO_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return fread(buffer, 1, bytestoread, intfile->handle);
}
int VFSOS_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
static int VFSSTDIO_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return fwrite(buffer, 1, bytestoread, intfile->handle);
}
qboolean VFSOS_Seek (struct vfsfile_s *file, unsigned long pos)
static qboolean VFSSTDIO_Seek (struct vfsfile_s *file, unsigned long pos)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return fseek(intfile->handle, pos, SEEK_SET) == 0;
}
unsigned long VFSOS_Tell (struct vfsfile_s *file)
static unsigned long VFSSTDIO_Tell (struct vfsfile_s *file)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return ftell(intfile->handle);
}
void VFSOS_Flush(struct vfsfile_s *file)
static void VFSSTDIO_Flush(struct vfsfile_s *file)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
fflush(intfile->handle);
}
unsigned long VFSOS_GetSize (struct vfsfile_s *file)
static unsigned long VFSSTDIO_GetSize (struct vfsfile_s *file)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
unsigned int curpos;
unsigned int maxlen;
@ -43,39 +49,39 @@ unsigned long VFSOS_GetSize (struct vfsfile_s *file)
return maxlen;
}
void VFSOS_Close(vfsfile_t *file)
static void VFSSTDIO_Close(vfsfile_t *file)
{
vfsosfile_t *intfile = (vfsosfile_t*)file;
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
fclose(intfile->handle);
Z_Free(file);
}
vfsfile_t *FS_OpenTemp(void)
vfsfile_t *FSSTDIO_OpenTemp(void)
{
FILE *f;
vfsosfile_t *file;
vfsstdiofile_t *file;
f = tmpfile();
if (!f)
return NULL;
file = Z_Malloc(sizeof(vfsosfile_t));
file->funcs.ReadBytes = VFSOS_ReadBytes;
file->funcs.WriteBytes = VFSOS_WriteBytes;
file->funcs.Seek = VFSOS_Seek;
file->funcs.Tell = VFSOS_Tell;
file->funcs.GetLen = VFSOS_GetSize;
file->funcs.Close = VFSOS_Close;
file->funcs.Flush = VFSOS_Flush;
file = Z_Malloc(sizeof(vfsstdiofile_t));
file->funcs.ReadBytes = VFSSTDIO_ReadBytes;
file->funcs.WriteBytes = VFSSTDIO_WriteBytes;
file->funcs.Seek = VFSSTDIO_Seek;
file->funcs.Tell = VFSSTDIO_Tell;
file->funcs.GetLen = VFSSTDIO_GetSize;
file->funcs.Close = VFSSTDIO_Close;
file->funcs.Flush = VFSSTDIO_Flush;
file->handle = f;
return (vfsfile_t*)file;
}
vfsfile_t *VFSOS_Open(const char *osname, const char *mode)
vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
{
FILE *f;
vfsosfile_t *file;
vfsstdiofile_t *file;
qboolean read = !!strchr(mode, 'r');
qboolean write = !!strchr(mode, 'w');
qboolean append = !!strchr(mode, 'a');
@ -99,20 +105,20 @@ vfsfile_t *VFSOS_Open(const char *osname, const char *mode)
if (!f)
return NULL;
file = Z_Malloc(sizeof(vfsosfile_t));
file->funcs.ReadBytes = strchr(mode, 'r')?VFSOS_ReadBytes:NULL;
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSOS_WriteBytes:NULL;
file->funcs.Seek = VFSOS_Seek;
file->funcs.Tell = VFSOS_Tell;
file->funcs.GetLen = VFSOS_GetSize;
file->funcs.Close = VFSOS_Close;
file->funcs.Flush = VFSOS_Flush;
file = Z_Malloc(sizeof(vfsstdiofile_t));
file->funcs.ReadBytes = strchr(mode, 'r')?VFSSTDIO_ReadBytes:NULL;
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSSTDIO_WriteBytes:NULL;
file->funcs.Seek = VFSSTDIO_Seek;
file->funcs.Tell = VFSSTDIO_Tell;
file->funcs.GetLen = VFSSTDIO_GetSize;
file->funcs.Close = VFSSTDIO_Close;
file->funcs.Flush = VFSSTDIO_Flush;
file->handle = f;
return (vfsfile_t*)file;
}
vfsfile_t *FSOS_OpenVFS(void *handle, flocation_t *loc, const char *mode)
static vfsfile_t *FSSTDIO_OpenVFS(void *handle, flocation_t *loc, const char *mode)
{
char diskname[MAX_OSPATH];
@ -123,22 +129,22 @@ vfsfile_t *FSOS_OpenVFS(void *handle, flocation_t *loc, const char *mode)
return VFSOS_Open(diskname, mode);
}
void FSOS_PrintPath(void *handle)
static void FSSTDIO_PrintPath(void *handle)
{
Con_Printf("%s\n", handle);
}
void FSOS_ClosePath(void *handle)
static void FSSTDIO_ClosePath(void *handle)
{
Z_Free(handle);
}
int FSOS_RebuildFSHash(const char *filename, int filesize, void *data)
static int FSSTDIO_RebuildFSHash(const char *filename, int filesize, void *data)
{
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
char childpath[256];
sprintf(childpath, "%s*", filename);
Sys_EnumerateFiles((char*)data, childpath, FSOS_RebuildFSHash, data);
Sys_EnumerateFiles((char*)data, childpath, FSSTDIO_RebuildFSHash, data);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
@ -156,11 +162,11 @@ int FSOS_RebuildFSHash(const char *filename, int filesize, void *data)
fs_hash_dups++;
return true;
}
void FSOS_BuildHash(void *handle)
static void FSSTDIO_BuildHash(void *handle)
{
Sys_EnumerateFiles(handle, "*", FSOS_RebuildFSHash, handle);
Sys_EnumerateFiles(handle, "*", FSSTDIO_RebuildFSHash, handle);
}
qboolean FSOS_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
static qboolean FSSTDIO_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
FILE *f;
int len;
@ -198,7 +204,7 @@ qboolean FSOS_FLocate(void *handle, flocation_t *loc, const char *filename, void
return true;
}
void FSOS_ReadFile(void *handle, flocation_t *loc, char *buffer)
static void FSSTDIO_ReadFile(void *handle, flocation_t *loc, char *buffer)
{
FILE *f;
f = fopen(loc->rawname, "rb");
@ -208,19 +214,19 @@ void FSOS_ReadFile(void *handle, flocation_t *loc, char *buffer)
fread(buffer, 1, loc->len, f);
fclose(f);
}
int FSOS_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
static int FSSTDIO_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return Sys_EnumerateFiles(handle, match, func, parm);
}
searchpathfuncs_t osfilefuncs = {
FSOS_PrintPath,
FSOS_ClosePath,
FSOS_BuildHash,
FSOS_FLocate,
FSOS_ReadFile,
FSOS_EnumerateFiles,
searchpathfuncs_t stdiofilefuncs = {
FSSTDIO_PrintPath,
FSSTDIO_ClosePath,
FSSTDIO_BuildHash,
FSSTDIO_FLocate,
FSSTDIO_ReadFile,
FSSTDIO_EnumerateFiles,
NULL,
NULL,
FSOS_OpenVFS
FSSTDIO_OpenVFS
};

276
engine/common/fs_win32.c Normal file
View file

@ -0,0 +1,276 @@
#include "quakedef.h"
#include "fs.h"
#include <windows.h>
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ~0
#endif
//read-only memory mapped files.
//for write access, we use the stdio module as a fallback.
#define VFSW32_Open VFSOS_Open
#define w32filefuncs osfilefuncs
typedef struct {
vfsfile_t funcs;
HANDLE hand;
HANDLE mmh;
void *mmap;
unsigned int length;
unsigned int offset;
} vfsw32file_t;
static int VFSW32_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
DWORD read;
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
{
if (intfile->offset+bytestoread > intfile->length)
bytestoread = intfile->length-intfile->offset;
memcpy(buffer, (char*)intfile->mmap + intfile->offset, bytestoread);
intfile->offset += bytestoread;
return bytestoread;
}
if (!ReadFile(intfile->hand, buffer, bytestoread, &read, NULL))
return 0;
return read;
}
static int VFSW32_WriteBytes (struct vfsfile_s *file, const void *buffer, int bytestoread)
{
DWORD written;
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
{
if (intfile->offset+bytestoread > intfile->length)
bytestoread = intfile->length-intfile->offset;
memcpy((char*)intfile->mmap + intfile->offset, buffer, bytestoread);
intfile->offset += bytestoread;
return bytestoread;
}
if (!WriteFile(intfile->hand, buffer, bytestoread, &written, NULL))
return 0;
return written;
}
static qboolean VFSW32_Seek (struct vfsfile_s *file, unsigned long pos)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
{
intfile->offset = pos;
return true;
}
return SetFilePointer(intfile->hand, pos, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
}
static unsigned long VFSW32_Tell (struct vfsfile_s *file)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
return intfile->offset;
return SetFilePointer(intfile->hand, 0, NULL, FILE_CURRENT);
}
static void VFSW32_Flush(struct vfsfile_s *file)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
FlushViewOfFile(intfile->mmap, intfile->length);
FlushFileBuffers(intfile->hand);
}
static unsigned long VFSW32_GetSize (struct vfsfile_s *file)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
return intfile->length;
return GetFileSize(intfile->hand, NULL);
}
static void VFSW32_Close(vfsfile_t *file)
{
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
{
UnmapViewOfFile(intfile->mmap);
CloseHandle(intfile->mmh);
}
CloseHandle(intfile->hand);
Z_Free(file);
}
vfsfile_t *VFSW32_Open(const char *osname, const char *mode)
{
HANDLE h, mh;
unsigned int fsize;
void *mmap;
vfsw32file_t *file;
qboolean read = !!strchr(mode, 'r');
qboolean write = !!strchr(mode, 'w');
qboolean append = !!strchr(mode, 'a');
qboolean text = !!strchr(mode, 't');
write |= append;
if (write && read)
h = CreateFileA(osname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
else if (write)
h = CreateFileA(osname, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
else if (read)
h = CreateFileA(osname, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
return NULL;
if (write || append || text)
{
fsize = 0;
mh = INVALID_HANDLE_VALUE;
mmap = NULL;
}
else
{
fsize = GetFileSize(h, NULL);
mh = CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL);
if (mh == INVALID_HANDLE_VALUE)
mmap = NULL;
else
{
mmap = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, fsize);
if (mmap == NULL)
{
CloseHandle(mh);
mh = INVALID_HANDLE_VALUE;
}
}
}
file = Z_Malloc(sizeof(vfsw32file_t));
file->funcs.ReadBytes = read?VFSW32_ReadBytes:NULL;
file->funcs.WriteBytes = (write||append)?VFSW32_WriteBytes:NULL;
file->funcs.Seek = VFSW32_Seek;
file->funcs.Tell = VFSW32_Tell;
file->funcs.GetLen = VFSW32_GetSize;
file->funcs.Close = VFSW32_Close;
file->funcs.Flush = VFSW32_Flush;
file->hand = h;
file->mmh = mh;
file->mmap = mmap;
file->offset = 0;
file->length = fsize;
return (vfsfile_t*)file;
}
static vfsfile_t *VFSW32_OpenVFS(void *handle, flocation_t *loc, const char *mode)
{
char diskname[MAX_OSPATH];
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
return VFSW32_Open(diskname, mode);
}
static void VFSW32_PrintPath(void *handle)
{
Con_Printf("%s\n", handle);
}
static void VFSW32_ClosePath(void *handle)
{
Z_Free(handle);
}
static int VFSW32_RebuildFSHash(const char *filename, int filesize, void *data)
{
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
char childpath[256];
sprintf(childpath, "%s*", filename);
Sys_EnumerateFiles((char*)data, childpath, VFSW32_RebuildFSHash, data);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
{
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
strcpy((char *)(bucket+1), filename);
#ifdef _WIN32
Q_strlwr((char *)(bucket+1));
#endif
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
fs_hash_files++;
}
else
fs_hash_dups++;
return true;
}
static void VFSW32_BuildHash(void *handle)
{
Sys_EnumerateFiles(handle, "*", VFSW32_RebuildFSHash, handle);
}
static qboolean VFSW32_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
FILE *f;
int len;
char netpath[MAX_OSPATH];
if (hashedresult && (void *)hashedresult != handle)
return false;
/*
if (!static_registered)
{ // if not a registered version, don't ever go beyond base
if ( strchr (filename, '/') || strchr (filename,'\\'))
continue;
}
*/
// check a file in the directory tree
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
f = fopen(netpath, "rb");
if (!f)
return false;
fseek(f, 0, SEEK_END);
len = ftell(f);
fclose(f);
if (loc)
{
loc->len = len;
loc->offset = 0;
loc->index = 0;
Q_strncpyz(loc->rawname, filename, sizeof(loc->rawname));
}
return true;
}
static void VFSW32_ReadFile(void *handle, flocation_t *loc, char *buffer)
{
FILE *f;
f = fopen(loc->rawname, "rb");
if (!f) //err...
return;
fseek(f, loc->offset, SEEK_SET);
fread(buffer, 1, loc->len, f);
fclose(f);
}
static int VFSW32_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return Sys_EnumerateFiles(handle, match, func, parm);
}
searchpathfuncs_t w32filefuncs = {
VFSW32_PrintPath,
VFSW32_ClosePath,
VFSW32_BuildHash,
VFSW32_FLocate,
VFSW32_ReadFile,
VFSW32_EnumerateFiles,
NULL,
NULL,
VFSW32_OpenVFS
};

View file

@ -1042,7 +1042,7 @@ int VARGS Plug_FS_Open(void *offset, unsigned int mask, const int *arg)
if (arg[2] == 1)
{
data = COM_LoadMallocFile(VM_POINTER(arg[0]));
FS_LoadFile(VM_POINTER(arg[0]), (void**)&data);
if (!data)
return -1;
@ -1306,8 +1306,12 @@ void Plug_Net_Close_Internal(int handle)
{
case STREAM_FILE:
if (*pluginstreamarray[handle].file.filename)
{
COM_WriteFile(pluginstreamarray[handle].file.filename, pluginstreamarray[handle].file.buffer, pluginstreamarray[handle].file.curlen);
BZ_Free(pluginstreamarray[handle].file.buffer);
}
else
FS_FreeFile(pluginstreamarray[handle].file.buffer);
break;
case STREAM_NONE:
break;

View file

@ -1389,7 +1389,6 @@ void PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char pr_string_temp[64];
//sprintf (pr_string_temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
sprintf (pr_string_temp, "'%f %f %f'", G_VECTOR(OFS_PARM0)[0], G_VECTOR(OFS_PARM0)[1], G_VECTOR(OFS_PARM0)[2]);
PR_TempString(prinst, pr_string_temp);
RETURN_TSTRING(pr_string_temp);
}
@ -1531,7 +1530,7 @@ void PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_globals)
char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192];
unsigned long flagged[8192];
COM_ParseFunString(in, flagged, sizeof(flagged)/sizeof(flagged[0]));
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged)/sizeof(flagged[0]));
COM_DeFunString(flagged, result, sizeof(result), true);
RETURN_TSTRING(result);

View file

@ -251,7 +251,8 @@ void PF_CL_is_cached_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_free_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -335,6 +335,9 @@ enum clcq2_ops_e
#define clcdp_ackframe 50
#define clcdp_ackdownloaddata 51
#define clc_qcrequest 81
#define clc_prydoncursor 82
//==============================================

View file

@ -155,7 +155,6 @@ void QVM_UnloadDLL(dllhandle_t *handle)
// ------------------------- * QVM files * -------------------------
#define VM_MAGIC 0x12721444
#define VM_MAGIC2 0x12721445
#define LL(x) x = LittleLong(x)
#pragma pack(push,1)
typedef struct vmHeader_s
@ -318,47 +317,46 @@ typedef enum qvm_op_e
qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall)
{
char path[MAX_QPATH];
vmHeader_t *header;
vmHeader_t header, *srcheader;
qvm_t *qvm;
qbyte *raw;
int n;
int i;
sprintf(path, "%s.qvm", name);
raw = COM_LoadMallocFile(path);
// FS_LoadFile(path, &raw, false);
FS_LoadFile(path, &raw);
// file not found
if(!raw) return NULL;
header=(vmHeader_t*)raw;
srcheader=(vmHeader_t*)raw;
LL(header->vmMagic);
LL(header->instructionCount);
LL(header->codeOffset);
LL(header->codeLength);
LL(header->dataOffset);
LL(header->dataLength);
LL(header->litLength);
LL(header->bssLength);
header.vmMagic = LittleLong(srcheader->vmMagic);
header.instructionCount = LittleLong(srcheader->instructionCount);
header.codeOffset = LittleLong(srcheader->codeOffset);
header.codeLength = LittleLong(srcheader->codeLength);
header.dataOffset = LittleLong(srcheader->dataOffset);
header.dataLength = LittleLong(srcheader->dataLength);
header.litLength = LittleLong(srcheader->litLength);
header.bssLength = LittleLong(srcheader->bssLength);
if (header->vmMagic==VM_MAGIC2)
if (header.vmMagic==VM_MAGIC2)
{ //version2 cotains a jump table of sorts
//it is redundant information and can be ignored
//its also more useful for jit rather than bytecode
LL(header->jtrgLength);
header.jtrgLength = LittleLong(srcheader->jtrgLength);
}
// check file
if(header->vmMagic!=VM_MAGIC && header->vmMagic!=VM_MAGIC2 || header->instructionCount<=0 || header->codeLength<=0)
if(header.vmMagic!=VM_MAGIC && header.vmMagic!=VM_MAGIC2 || header.instructionCount<=0 || header.codeLength<=0)
{
Con_Printf("%s: invalid qvm file\n", name);
BZ_Free(raw);
FS_FreeFile(raw);
return NULL;
}
// create vitrual machine
qvm=Z_Malloc(sizeof(qvm_t));
qvm->len_cs=header->instructionCount+1; //bad opcode padding.
qvm->len_ds=header->dataLength+header->litLength+header->bssLength;
qvm->len_cs=header.instructionCount+1; //bad opcode padding.
qvm->len_ds=header.dataLength+header.litLength+header.bssLength;
qvm->len_ss=256*1024; // 256KB stack space
// memory
@ -399,9 +397,9 @@ qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall)
// load instructions
{
qbyte *src=raw+header->codeOffset;
qbyte *src=raw+header.codeOffset;
int *dst=(int*)qvm->cs;
int total=header->instructionCount;
int total=header.instructionCount;
qvm_op_t op;
for(n=0; n<total; n++)
@ -448,17 +446,17 @@ qvm_t *QVM_LoadVM(const char *name, sys_callqvm_t syscall)
// load data segment
{
int *src=(int*)(raw+header->dataOffset);
int *src=(int*)(raw+header.dataOffset);
int *dst=(int*)qvm->ds;
int total=header->dataLength/4;
int total=header.dataLength/4;
for(n=0; n<total; n++)
*dst++=LittleLong(*src++);
memcpy(dst, src, header->litLength);
memcpy(dst, src, header.litLength);
}
BZ_Free(raw);
FS_FreeFile(raw);
return qvm;
}

View file

@ -6247,6 +6247,10 @@ SOURCE=..\common\fs_stdio.c
# End Source File
# Begin Source File
SOURCE=..\common\fs_win32.c
# End Source File
# Begin Source File
SOURCE=..\common\fs_zip.c
# End Source File
# Begin Source File
@ -6365,7 +6369,7 @@ SOURCE=..\qclib\execloop.h
!IF "$(CFG)" == "ftequake - Win32 Release"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6387,7 +6391,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6409,7 +6413,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6431,7 +6435,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6453,7 +6457,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6475,7 +6479,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6497,7 +6501,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6519,7 +6523,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6541,7 +6545,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6563,7 +6567,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6585,7 +6589,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6607,7 +6611,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6629,7 +6633,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \
@ -6651,7 +6655,7 @@ BuildCmds= \
!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug"
# Begin Custom Build
InputDir=\Quake\ftesrc\engine\QCLIB
InputDir=\Games\Quake\ftesrc\engine\QCLIB
InputPath=..\qclib\execloop.h
BuildCmds= \

View file

@ -380,7 +380,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
char *mem;
char alternatename[MAX_QPATH];
snprintf(alternatename, sizeof(alternatename), "pics/%s.pcx", path);
data = COM_LoadMallocFile (alternatename);
FS_LoadFile(alternatename, (void**)&data);
if (data)
{
strcpy(pic->name, path);
@ -400,7 +400,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
glmenu_numcachepics++;
return &pic->pic;
}
BZ_Free(data);
FS_FreeFile(data);
}
}
@ -408,7 +408,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
char *mem;
char alternatename[MAX_QPATH];
snprintf(alternatename, MAX_QPATH-1, "%s", path);
data = COM_LoadMallocFile (alternatename);
FS_LoadFile(alternatename, &data);
if (data)
{
strcpy(pic->name, path);
@ -441,7 +441,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
glmenu_numcachepics++;
return &pic->pic;
}
BZ_Free(data);
FS_FreeFile(data);
}
}
@ -450,7 +450,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
char *mem;
char alternatename[MAX_QPATH];
snprintf(alternatename, MAX_QPATH-1,"%s.jpg", path);
data = COM_LoadMallocFile (alternatename);
FS_LoadFile(alternatename, (void**)&data);
if (data)
{
strcpy(pic->name, path);
@ -470,7 +470,7 @@ mpic_t *GLDraw_SafeCachePic (char *path)
glmenu_numcachepics++;
return &pic->pic;
}
BZ_Free(data);
FS_FreeFile(data);
}
}
#endif
@ -863,8 +863,9 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
{
//gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system.
char *tempchars = COM_LoadMallocFile("gfx/menu/conchars.lmp");
char *tempchars;
char *in, *out;
FS_LoadFile("gfx/menu/conchars.lmp", (void**)&tempchars);
if (tempchars)
{
draw_chars = BZ_Malloc(8*8*256*8);
@ -900,7 +901,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
*out++ = *in++;
}
}
Z_Free(tempchars);
FS_FreeFile(tempchars);
// add ocrana leds
if (con_ocranaleds.value && con_ocranaleds.value != 2)
@ -999,7 +1000,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
glmenu_numcachepics++;
}
TRACE(("dbg: GLDraw_ReInit: gfx/menu/bigfont\n"));
bigfont = (qpic_t *)COM_LoadMallocFile ("gfx/menu/bigfont.lmp");
FS_LoadFile("gfx/menu/bigfont.lmp", (void**)&bigfont);
if (bigfont)
{
char *data;
@ -1019,6 +1020,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
gl->sh = 1;
gl->th = 1;
glmenu_numcachepics++;
FS_FreeFile(bigfont);
}

View file

@ -205,9 +205,7 @@ void GLMod_Shutdown (void)
Cmd_RemoveCommand("mod_texturelist");
Cmd_RemoveCommand("mod_usetexture");
#ifdef RUNTIMELIGHTING
lightmodel = NULL;
#endif
GLMod_ClearAll();
}
/*
@ -276,6 +274,24 @@ mleaf_t *GLMod_PointInLeaf (model_t *model, vec3_t p)
return NULL; // never reached
}
#if defined(RUNTIMELIGHTING) && defined(MULTITHREAD)
void *relightthread;
volatile qboolean wantrelight;
void RelightThread(void *arg)
{
while (wantrelight && relitsurface < lightmodel->numsurfaces)
{
LightFace(relitsurface);
lightmodel->surfaces[relitsurface].cached_dlight = -1;
relitsurface++;
lightmodel->surfaces[relitsurface].cached_dlight = -1;
}
}
#endif
/*
===================
Mod_ClearAll
@ -284,17 +300,47 @@ Mod_ClearAll
void GLMod_ClearAll (void)
{
int i;
int t;
model_t *mod;
#ifdef RUNTIMELIGHTING
#ifdef MULTITHREAD
if (relightthread)
{
wantrelight = false;
Sys_WaitOnThread(relightthread);
relightthread = NULL;
}
#endif
lightmodel = NULL;
#endif
//when the hunk is reset, all bsp models need to be reloaded
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
{
if (mod->needload)
continue;
if (mod->type == mod_brush)
{
for (t = 0; t < mod->numtextures; t++)
{
if (!mod->textures[t])
continue;
if (mod->textures[t]->gl_vboe)
qglDeleteBuffersARB(1, &mod->textures[t]->gl_vboe);
if (mod->textures[t]->gl_vbov)
qglDeleteBuffersARB(1, &mod->textures[t]->gl_vbov);
mod->textures[t]->gl_vboe = 0;
mod->textures[t]->gl_vbov = 0;
}
}
if (mod->type != mod_alias
&& mod->type != mod_halflife
)
mod->needload = true;
}
}
void GLMod_Think (void)
@ -306,21 +352,31 @@ void GLMod_Think (void)
{
return;
}
#ifdef MULTITHREAD
if (!relightthread)
{
wantrelight = true;
relightthread = Sys_CreateThread(RelightThread, lightmodel, 0);
}
#else
LightFace(relitsurface);
GLMod_UpdateLightmap(relitsurface);
relitsurface++;
#endif
if (relitsurface >= lightmodel->numsurfaces)
{
char filename[MAX_QPATH];
char *f;
Con_Printf("Finished lighting level\n");
Con_Printf("Finished lighting %s\n", lightmodel->name);
strcpy(filename, lightmodel->name);
f = COM_SkipPath(filename);
*f = '\0';
#ifdef MULTITHREAD
if (relightthread)
{
wantrelight = false;
Sys_WaitOnThread(relightthread);
relightthread = NULL;
}
#endif
if (lightmodel->deluxdata)
{
@ -410,7 +466,6 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash)
unsigned *buf = NULL;
qbyte stackbuf[1024]; // avoid dirtying the cache heap
char mdlbase[MAX_QPATH];
qboolean lastload = false;
char *replstr;
qboolean doomsprite = false;
@ -730,10 +785,10 @@ static char *GLMod_TD_Section(char *file, const char *sectionname)
void GLMod_InitTextureDescs(char *mapname)
{
if (advtexturedesc)
BZ_Free(advtexturedesc);
advtexturedesc = COM_LoadMallocFile(va("maps/shaders/%s.shaders", mapname));
FS_FreeFile(advtexturedesc);
FS_LoadFile(va("maps/shaders/%s.shaders", mapname), (void**)&advtexturedesc);
if (!advtexturedesc)
advtexturedesc = COM_LoadMallocFile(va("shaders/%s.shaders", mapname));
FS_LoadFile(va("shaders/%s.shaders", mapname), (void**)&advtexturedesc);
if (advtexturedesc)
{
mapsection = advtexturedesc;
@ -741,7 +796,7 @@ void GLMod_InitTextureDescs(char *mapname)
}
else
{
advtexturedesc = COM_LoadMallocFile(va("map.shaders", mapname));
FS_LoadFile(va("map.shaders", mapname), (void**)&advtexturedesc);
mapsection = GLMod_TD_Section(advtexturedesc, mapname);
defaultsection = GLMod_TD_Section(advtexturedesc, "default");
}
@ -1045,7 +1100,8 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
char *star;
//find the *
if (!strcmp(gl_shadeq1_name.string, "*"))
tx->shader = R_RegisterCustom(mt->name, NULL); //just load the regular name.
// tx->shader = R_RegisterCustom(mt->name, NULL); //just load the regular name.
tx->shader = R_RegisterShader(mt->name); //just load the regular name.
else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(mt->name)+1>=sizeof(altname))) //it's got to fit.
tx->shader = R_RegisterCustom(gl_shadeq1_name.string, NULL);
else
@ -2082,7 +2138,7 @@ void GLMod_LoadCrouchHull(void)
COM_StripExtension(loadmodel->name, crouchhullname, sizeof(crouchhullname));
COM_DefaultExtension(crouchhullname, ".crh",sizeof(crouchhullname)); //crouch hull
crouchhullfile = COM_LoadMallocFile(crouchhullname); //or otherwise temporary storage. load on hunk if you want, but that would be a waste.
FS_LoadFile(crouchhullname, &crouchhullfile);
if (!crouchhullfile)
return;
@ -2816,7 +2872,7 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer)
if (crouchhullfile)
{
BZ_Free(crouchhullfile);
FS_FreeFile(crouchhullfile);
crouchhullfile=NULL;
}

View file

@ -70,6 +70,10 @@ typedef struct {
typedef struct mesh_s
{
unsigned int vbofirstvert;
unsigned int vbofirstelement;
int numvertexes;
vec3_t *xyz_array;
vec3_t *normals_array;
@ -176,6 +180,9 @@ typedef struct texture_s
struct shader_s *shader;
int gl_vbov;
int gl_vboe;
struct msurface_s *texturechain; // for gl_texsort drawing
int anim_total; // total tenths in sequence ( 0 = no)
int anim_min, anim_max; // time for this frame min <=time< max
@ -184,6 +191,9 @@ typedef struct texture_s
unsigned offsets[MIPLEVELS]; // four mip maps stored
} texture_t;
//the per-texture vbos have this stride (v_pos/st/lm_st)
#define VBOSTRIDE (3+2+2)*sizeof(float)
#define SURF_DRAWSKYBOX 0x00001
#define SURF_PLANEBACK 0x00002
#define SURF_DRAWSKY 0x00004

View file

@ -487,6 +487,123 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
qglDisable(GL_ALPHA_TEST);
}
static void PPL_BaseChain_VBO_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
{ //doesn't merge surfaces, but tells gl to do each vertex arrayed surface individually, which means no vertex copying.
int vi;
glRect_t *theRect;
varrayactive = false;
qglDisableClientState(GL_COLOR_ARRAY);
qglEnableClientState(GL_VERTEX_ARRAY);
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, tex->gl_vbov);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, tex->gl_vboe);
qglVertexPointer(3, GL_FLOAT, VBOSTRIDE, NULL);
if (tex->alphaed || currententity->shaderRGBAf[3]<1)
{
if (*tex->name == '{')
{
qglEnable(GL_ALPHA_TEST);
qglDisable(GL_BLEND);
GL_TexEnv(GL_REPLACE);
}
else
{
qglEnable(GL_BLEND);
GL_TexEnv(GL_MODULATE);
}
}
else
{
qglDisable(GL_BLEND);
GL_TexEnv(GL_REPLACE);
}
GL_MBind(GL_TEXTURE0_ARB, tex->gl_texturenum);
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglTexCoordPointer(2, GL_FLOAT, VBOSTRIDE, (void*)(3*sizeof(float)));
GL_SelectTexture(GL_TEXTURE1_ARB);
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
qglTexCoordPointer(2, GL_FLOAT, VBOSTRIDE, (void*)(5*sizeof(float)));
GL_TexEnv(GL_MODULATE);
/* if (currententity->shaderRGBAf[3]<1)
{
s->lightmaptexturenum = -1;
qglBlendFunc(GL_SRC_COLOR, GL_ONE);
}
*/
if (overbright != 1)
{
GL_TexEnv(GL_COMBINE_ARB);
qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, overbright); //this is the key
}
// numidxs = 0;
vi = -1;
for (; s ; s=s->texturechain)
{
if (!s->mesh) //urm.
continue;
if (s->mesh->numvertexes <= 1)
continue;
if (vi != s->lightmaptexturenum)
{
if (vi<0)
qglEnable(GL_TEXTURE_2D);
vi = s->lightmaptexturenum;
if (vi>=0)
{
GL_Bind(lightmap_textures[vi] );
if (lightmap[vi]->modified)
{
lightmap[vi]->modified = false;
theRect = &lightmap[vi]->rectchange;
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
lightmap[vi]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes);
theRect->l = LMBLOCK_WIDTH;
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
}
}
else
qglDisable(GL_TEXTURE_2D);
}
qglDrawRangeElements(GL_TRIANGLES, s->mesh->vbofirstvert, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, (index_t*)(s->mesh->vbofirstelement*sizeof(index_t)));
}
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
if (overbright != 1)
{
qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); //just in case
GL_TexEnv(GL_MODULATE);
}
//tmu 1 should be selected here
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_SelectTexture(GL_TEXTURE0_ARB);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglDisable(GL_TEXTURE_2D);
if (tex->alphaed)
qglDisable(GL_ALPHA_TEST);
}
/*
static void PPL_BaseChain_NoBump_2TMU_TEST(msurface_t *s, texture_t *tex)
{ //this was just me testing efficiency between arrays/glbegin.
@ -1534,6 +1651,7 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first)
static void PPL_BaseTextureChain(msurface_t *first)
{
texture_t *t;
shader_t *shader;
if (r_drawflat.value||!r_lightmapintensity)
{
if (r_drawflat.value == 2)
@ -1553,8 +1671,12 @@ static void PPL_BaseTextureChain(msurface_t *first)
return;
}
}
t = R_TextureAnimation (first->texinfo->texture);
#ifdef Q3SHADERS
if (first->texinfo->texture->shader)
shader = t->shader;
if (shader)// && shader->style != SSTYLE_LIGHTMAPPED)
{
meshbuffer_t mb;
msurface_t *s;
@ -1563,7 +1685,7 @@ static void PPL_BaseTextureChain(msurface_t *first)
int dlb;
glRect_t *theRect;
if (first->texinfo->texture->shader->flags & SHADER_FLARE )
if (shader->flags & SHADER_FLARE )
{
dlight_t *dl;
while(first)
@ -1588,7 +1710,7 @@ static void PPL_BaseTextureChain(msurface_t *first)
R_IBrokeTheArrays();
mb.entity = &r_worldentity;
mb.shader = first->texinfo->texture->shader;
mb.shader = shader;
mb.mesh = NULL;
mb.fog = NULL;
mb.infokey = -2;
@ -1675,10 +1797,6 @@ static void PPL_BaseTextureChain(msurface_t *first)
t = R_TextureAnimation (first->texinfo->texture);
if (first->flags & SURF_DRAWTURB)
{
GL_DisableMultitexture();
@ -1726,6 +1844,9 @@ static void PPL_BaseTextureChain(msurface_t *first)
{
// PPL_BaseChain_NoBump_2TMU_TEST(first, t);
// PPL_BaseChain_NoBump_2TMU(first, t);
if (t->gl_vbov)
PPL_BaseChain_VBO_NoBump_2TMU_Overbright(first, t);
else
PPL_BaseChain_NoBump_2TMU_Overbright(first, t);
}
}

View file

@ -3397,8 +3397,7 @@ void GL_BuildSurfaceDisplayList (msurface_t *fa)
if (lnumverts<3)
return; //q3 map.
//#ifdef Q3SHADERS
// if (fa->texinfo->texture->shader)
{ //build a nice mesh instead of a poly.
int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec3_t) + sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts;
mesh_t *mesh;
@ -3470,109 +3469,7 @@ void GL_BuildSurfaceDisplayList (msurface_t *fa)
mesh->colors_array[i][2] = 255;
mesh->colors_array[i][3] = 255;
}
return;
}
//#endif
//
// draw texture
//
/*
poly = Hunk_AllocName (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float), "SDList");
poly->next = fa->polys;
fa->polys = poly;
poly->numverts = lnumverts;
for (i=0 ; i<lnumverts ; i++)
{
lindex = currentmodel->surfedges[fa->firstedge + i];
if (lindex > 0)
{
r_pedge = &pedges[lindex];
vec = r_pcurrentvertbase[r_pedge->v[0]].position;
}
else
{
r_pedge = &pedges[-lindex];
vec = r_pcurrentvertbase[r_pedge->v[1]].position;
}
s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
VectorCopy (vec, poly->verts[i]);
poly->verts[i][3] = s/fa->texinfo->texture->width;
poly->verts[i][4] = t/fa->texinfo->texture->height;
//
// lightmap texture coordinates
//
s -= fa->texturemins[0];
lm = s*fa->light_t;
s += fa->light_s*16;
s += 8;
s /= LMBLOCK_WIDTH*16;
t -= fa->texturemins[1];
lm += t;
t += fa->light_t*16;
t += 8;
t /= LMBLOCK_HEIGHT*16;
poly->verts[i][5] = s;
poly->verts[i][6] = t;
#ifdef SPECULAR
if (fa->flags & SURF_PLANEBACK)
VectorNegate(fa->plane->normal, (poly->verts[i]+7));
else
VectorCopy(fa->plane->normal, (poly->verts[i]+7));
#endif
}
//
// remove co-linear points - Ed
//
if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) )
{
for (i = 0 ; i < lnumverts ; ++i)
{
vec3_t v1, v2;
float *prev, *this, *next;
prev = poly->verts[(i + lnumverts - 1) % lnumverts];
this = poly->verts[i];
next = poly->verts[(i + 1) % lnumverts];
VectorSubtract( this, prev, v1 );
VectorNormalize( v1 );
VectorSubtract( next, prev, v2 );
VectorNormalize( v2 );
// skip co-linear points
#define COLINEAR_EPSILON 0.001
if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) &&
(fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) &&
(fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON))
{
int j;
for (j = i + 1; j < lnumverts; ++j)
{
int k;
for (k = 0; k < VERTEXSIZE; ++k)
poly->verts[j - 1][k] = poly->verts[j][k];
}
--lnumverts;
++nColinElim;
// retry next vertex next time, which is now current vertex
--i;
}
}
}
poly->numverts = lnumverts;
*/
}
/*
@ -3643,6 +3540,84 @@ void GLSurf_DeInit(void)
numlightmaps=0;
}
void GL_GenBrushModelVBO(model_t *mod)
{
unsigned int maxvboverts;
unsigned int maxvboelements;
unsigned int t;
unsigned int i;
unsigned int vbov, vboe;
unsigned int v;
unsigned int vcount, ecount;
void *vbovdata;
index_t *vboedata;
mesh_t *m;
#define VBOSTRIDE (3+2+2)*4
if (!qglGenBuffersARB || !mod->numsurfaces)
return;
for (t = 0; t < mod->numtextures; t++)
{
if (!mod->textures[t])
continue;
mod->textures[t]->gl_vbov = 0;
mod->textures[t]->gl_vboe = 0;
maxvboverts = 0;
maxvboelements = 0;
for (i=0 ; i<mod->numsurfaces ; i++)
{
if (mod->surfaces[i].texinfo->texture != mod->textures[t])
continue;
m = mod->surfaces[i].mesh;
maxvboelements += m->numindexes;
maxvboverts += m->numvertexes;
}
if (maxvboverts > (1<<(sizeof(index_t)*8))-1)
continue;
if (!maxvboverts)
continue;
//fixme: stop this from leaking!
qglGenBuffersARB(1, &vbov);
qglGenBuffersARB(1, &vboe);
mod->textures[t]->gl_vbov = vbov;
mod->textures[t]->gl_vboe = vboe;
vcount = 0;
ecount = 0;
vbovdata = Hunk_TempAlloc(maxvboverts*VBOSTRIDE);
vboedata = Hunk_TempAllocMore(maxvboelements*sizeof(index_t));
for (i=0 ; i<mod->numsurfaces ; i++)
{
if (mod->surfaces[i].texinfo->texture != mod->textures[t])
continue;
m = mod->surfaces[i].mesh;
m->vbofirstvert = vcount;
m->vbofirstelement = ecount;
for (v = 0; v < m->numindexes; v++)
vboedata[ecount++] = vcount + m->indexes[v];
for (v = 0; v < m->numvertexes; v++)
{
memcpy((char*)vbovdata+(vcount+v)*VBOSTRIDE + 0, &m->xyz_array[v], sizeof(vec3_t));
if (m->st_array)
memcpy((char*)vbovdata+(vcount+v)*VBOSTRIDE + 12, &m->st_array[v], sizeof(vec2_t));
if (m->lmst_array)
memcpy((char*)vbovdata+(vcount+v)*VBOSTRIDE + 20, &m->lmst_array[v], sizeof(vec2_t));
}
vcount += v;
}
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbov);
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vcount*VBOSTRIDE, vbovdata, GL_STATIC_DRAW_ARB);
qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboe);
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ecount*sizeof(vboedata[0]), vboedata, GL_STATIC_DRAW_ARB);
qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
}
/*
==================
@ -3747,7 +3722,7 @@ void GL_BuildLightmaps (void)
for (t = 0; t < m->numtextures; t++)
{
for (i=0 ; i<m->numsurfaces ; i++)
{//extra surface loop so we get slightly less texture switches
{//extra texture loop so we get slightly less texture switches
if (m->surfaces[i].texinfo->texture == m->textures[t])
{
GL_CreateSurfaceLightmap (m->surfaces + i, shift);
@ -3758,6 +3733,8 @@ void GL_BuildLightmaps (void)
}
}
}
GL_GenBrushModelVBO(m);
}
//

View file

@ -628,7 +628,6 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
if (uniformloc == -1)
{
Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token);
return;
}
else
{
@ -2144,6 +2143,8 @@ void Shader_DefaultBSP(char *shortname, shader_t *s)
s->features = MF_STCOORDS|MF_LMCOORDS|MF_TRNORMALS;
s->sort = SHADER_SORT_OPAQUE;
s->registration_sequence = 1;//fizme: registration_sequence;
s->style = SSTYLE_LIGHTMAPPED;
}
void Shader_DefaultBSPVertex(char *shortname, shader_t *s)

View file

@ -99,6 +99,12 @@ void (APIENTRY *qglFogfv) (GLenum pname, const GLfloat *params);
void (APIENTRY *qglDeleteTextures) (GLsizei n, const GLuint *textures);
void (APIENTRY *qglGenBuffersARB)(GLsizei n, GLuint* ids);
void (APIENTRY *qglDeleteBuffersARB)(GLsizei n, GLuint* ids);
void (APIENTRY *qglBindBufferARB)(GLenum target, GLuint id);
void (APIENTRY *qglBufferDataARB)(GLenum target, GLsizei size, const void* data, GLenum usage);
void (APIENTRY *qglBufferSubDataARB)(GLenum target, GLint offset, GLsizei size, void* data);
/*
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB;
@ -338,6 +344,15 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
if (gl_mtexarbable && gl_config.arb_texture_cube_map && gl_config.arb_texture_env_combine && gl_config.arb_texture_env_dot3 && !COM_CheckParm("-nobump") && gl_bump.value)
gl_bumpmappingpossible = true;
if (strstr(gl_extensions, "GL_ARB_vertex_buffer_object"))
{
qglGenBuffersARB = (void *)getglext("glGenBuffersARB");
qglDeleteBuffersARB = (void *)getglext("glDeleteBuffersARB");
qglBindBufferARB = (void *)getglext("glBindBufferARB");
qglBufferDataARB = (void *)getglext("glBufferDataARB");
qglBufferSubDataARB = (void *)getglext("glBufferSubDataARB");
}
/*
if (!!strstr(gl_extensions, "GL_ARB_fragment_program"))
{

View file

@ -1030,7 +1030,7 @@ void IN_Commands (void)
IN_Move
===========
*/
void IN_MouseMove (usercmd_t *cmd, int pnum)
void IN_MouseMove (float *movements, int pnum)
{
extern int mouseusedforgui, mousecursor_x, mousecursor_y;
extern int mousemove_x, mousemove_y;
@ -1088,11 +1088,11 @@ void IN_MouseMove (usercmd_t *cmd, int pnum)
if(in_xflip.value) mouse_x *= -1;
#endif
if (cmd)
if (movements)
{
// add mouse X/Y movement to cmd
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
else
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
@ -1107,17 +1107,17 @@ void IN_MouseMove (usercmd_t *cmd, int pnum)
else
{
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
cmd->upmove -= m_forward.value * mouse_y;
movements[2] -= m_forward.value * mouse_y;
else
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
}
mouse_x = mouse_y = 0.0;
}
void IN_Move (usercmd_t *cmd, int pnum)
void IN_Move (float *movements, int pnum)
{
IN_MouseMove(cmd, pnum);
IN_MouseMove(movements, pnum);
}
#endif

View file

@ -90,7 +90,7 @@ void IN_Commands(void)
{
}
void IN_Move(usercmd_t *cmd, int pnum)
void IN_Move(float *movements, int pnum)
{
}

View file

@ -820,6 +820,12 @@ extern BOOL (WINAPI *qSwapBuffers)(HDC);
extern void (APIENTRY *qglDrawRangeElements) (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
extern void (APIENTRY *qglGenBuffersARB)(GLsizei n, GLuint* ids);
extern void (APIENTRY *qglDeleteBuffersARB)(GLsizei n, GLuint* ids);
extern void (APIENTRY *qglBindBufferARB)(GLenum target, GLuint id);
extern void (APIENTRY *qglBufferDataARB)(GLenum target, GLsizei size, const void* data, GLenum usage);
extern void (APIENTRY *qglBufferSubDataARB)(GLenum target, GLint offset, GLsizei size, void* data);
/*
extern qboolean gl_arb_fragment_program;
extern PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;

View file

@ -542,6 +542,40 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_MULTISAMPLE_ARB 0x809D
#ifndef GL_ARB_vertex_buffer_object
#define GL_BUFFER_SIZE_ARB 0x8764
#define GL_BUFFER_USAGE_ARB 0x8765
#define GL_ARRAY_BUFFER_ARB 0x8892
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
#define GL_READ_ONLY_ARB 0x88B8
#define GL_WRITE_ONLY_ARB 0x88B9
#define GL_READ_WRITE_ARB 0x88BA
#define GL_BUFFER_ACCESS_ARB 0x88BB
#define GL_BUFFER_MAPPED_ARB 0x88BC
#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
#define GL_STREAM_DRAW_ARB 0x88E0
#define GL_STREAM_READ_ARB 0x88E1
#define GL_STREAM_COPY_ARB 0x88E2
#define GL_STATIC_DRAW_ARB 0x88E4
#define GL_STATIC_READ_ARB 0x88E5
#define GL_STATIC_COPY_ARB 0x88E6
#define GL_DYNAMIC_DRAW_ARB 0x88E8
#define GL_DYNAMIC_READ_ARB 0x88E9
#define GL_DYNAMIC_COPY_ARB 0x88EA
#endif

View file

@ -209,6 +209,11 @@ typedef struct {
} shaderprogparm_t;
typedef struct shader_s {
enum {
SSTYLE_CUSTOM,
SSTYLE_FULLBRIGHT,
SSTYLE_LIGHTMAPPED
} style;
int numpasses; //careful... 0 means it's not loaded... and not actually a proper shader.
struct shader_s *next;
char name[MAX_QPATH];

View file

@ -224,9 +224,10 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con
int len;
if (con->type == ftp_getting)
{
if (!cls.downloadmethod || (cls.downloadmethod == DL_FTP && !strcmp(cls.downloadname, con->localfile)))
if (!cls.downloadmethod || (cls.downloadmethod == DL_FTP && !strcmp(cls.downloadlocalname, con->localfile)))
{
strcpy(cls.downloadname, con->localfile);
strcpy(cls.downloadlocalname, con->localfile);
strcpy(cls.downloadremotename, con->localfile);
cls.downloadmethod = DL_FTP;
if (con->transfersize == -1)
cls.downloadpercent=50;
@ -640,7 +641,7 @@ void FTP_ClientThink (void)
if (con->NotifyFunction)
con->NotifyFunction(con->localfile, false);
if (cls.downloadmethod == DL_FTP && !strcmp(cls.downloadname, con->localfile))
if (cls.downloadmethod == DL_FTP && !strcmp(cls.downloadlocalname, con->localfile))
{ //this was us
cls.downloadmethod = DL_NONE;
}

View file

@ -369,11 +369,12 @@ void HTTP_CL_Think(void)
cls.downloadpercent = 50;
else
cls.downloadpercent = con->bufferused*100.0f/con->contentlength;
strcpy(cls.downloadname, con->filename);
strcpy(cls.downloadlocalname, con->filename);
strcpy(cls.downloadremotename, con->filename);
}
else if (cls.downloadmethod == DL_HTTP)
{
if (!strcmp(cls.downloadname, con->filename))
if (!strcmp(cls.downloadlocalname, con->filename))
{
if (con->state != HC_GETTING)
cls.downloadpercent = 0;

View file

@ -138,19 +138,19 @@ void HTTP_RunExisting (void)
int HTTPmarkup; //version
int localerrno;
HTTP_active_connections_t *prev, *cl = HTTP_ServerConnections;
HTTP_active_connections_t **link, *cl;
prev = NULL;
for (prev = NULL; cl; cl=(prev=cl)->next)
link = &HTTP_ServerConnections;
for (link = &HTTP_ServerConnections; *link;)
{
int ammount, wanted;
cl = *link;
if (cl->close)
{
if (prev)
prev->next = cl->next;
else
HTTP_ServerConnections = cl->next;
*link = cl->next;
closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET;
if (cl->inbuffer)
@ -161,10 +161,11 @@ void HTTP_RunExisting (void)
VFS_CLOSE(cl->file);
IWebFree(cl);
httpconnectioncount--;
cl = prev;
break;
continue;
}
link = &(*link)->next;
switch(cl->mode)
{
case HTTP_WAITINGFORREQUEST:
@ -332,14 +333,26 @@ cont:
else if (!stricmp(mode, "GET") || !stricmp(mode, "HEAD") || !stricmp(mode, "POST"))
{
if (*resource != '/')
{
resource[0] = '/';
resource[1] = 0; //I'm lazy, they need to comply
}
Con_Printf("Download request for \"%s\"\n", resource+1);
if (!strnicmp(mode, "P", 1)) //when stuff is posted, data is provided. Give an error message if we couldn't do anything with that data.
cl->file = IWebGenerateFile(resource+1, content, contentlen);
else if (!SV_AllowDownload(resource+1))
else
{
if (!SV_AllowDownload(resource+1))
cl->file = NULL;
else
cl->file = FS_OpenVFS(resource+1, "rb", FS_GAME);
if (!cl->file)
{
cl->file = IWebGenerateFile(resource+1, content, contentlen);
}
}
if (!cl->file)
{
if (HTTPmarkup >= 3)
@ -418,11 +431,11 @@ notimplemented:
break;
case HTTP_SENDING:
if (cl->outbufferused < 128)
if (cl->outbufferused < 8192)
{
if (cl->file)
{
ExpandOutBuffer(cl, 1500, true);
ExpandOutBuffer(cl, 32768, true);
wanted = cl->outbuffersize - cl->outbufferused;
ammount = VFS_READ(cl->file, cl->outbuffer+cl->outbufferused, wanted);
@ -483,10 +496,12 @@ notimplemented:
qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while true
{
struct sockaddr_in from;
struct sockaddr_qstorage from;
int fromlen;
int clientsock;
int _true = true;
char buf[128];
netadr_t na;
HTTP_active_connections_t *cl;
@ -534,7 +549,8 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr
return false;
}
Con_Printf("New connection\n");
SockadrToNetadr(&from, &na);
Con_Printf("New http connection from %s\n", NET_AdrToString(buf, sizeof(buf), na));
cl = IWebMalloc(sizeof(HTTP_active_connections_t));

View file

@ -25,11 +25,13 @@ void IWeb_MoreGeneratedResize(int newsize)
ob = IWeb_GenerationBuffer;
IWeb_GenerationBuffer = BZ_Malloc(sizeof(IWeb_GenerationBuffer) + newsize);
memset(IWeb_GenerationBuffer, 0, sizeof(*IWeb_GenerationBuffer));
IWeb_GenerationBuffer->data = (char *)(IWeb_GenerationBuffer+1);
if (ob)
{
memcpy(IWeb_GenerationBuffer->data, ob->data, ob->len);
IWeb_GenerationBuffer->len = ob->len;
BZ_Free(ob);
}
@ -378,12 +380,17 @@ unsigned long VFSGen_GetLen(vfsfile_t *f)
void VFSGen_Close(vfsfile_t *f)
{
int fnum;
vfsgen_t *g = (vfsgen_t*)f;
g->buffer->references--;
if (!g->buffer->references)
{
Z_Free(g->buffer->data);
Z_Free(g->buffer);
for (fnum = 0; fnum < sizeof(IWebFiles) / sizeof(IWebFile_t); fnum++)
if (IWebFiles[fnum].buffer == g->buffer)
IWebFiles[fnum].buffer = NULL;
}
Z_Free(g);
}
@ -401,6 +408,9 @@ vfsfile_t *VFSGen_Create(IWeb_FileGen_t *gen)
ret->funcs.GetLen = VFSGen_GetLen;
ret->funcs.Close = VFSGen_Close;
ret->buffer = gen;
gen->references++;
return (vfsfile_t*)ret;
}

View file

@ -1,4 +1,6 @@
QCC_OBJS=qccmain.o qcc_cmdlib.o qcc_pr_comp.o qcc_pr_lex.o comprout.o hash.o qcd_main.o
COMMON_OBJS=comprout.o hash.o qcc_cmdlib.o qcd_main.o
QCC_OBJS=qccmain.o qcc_pr_comp.o qcc_pr_lex.o
VM_OBJS=pr_exec.o pr_edict.o pr_multi.o initlib.o qcdecomp.o
GTKGUI_OBJS=qcc_gtk.o qccguistuff.o
WIN32GUI_OBJS=qccgui.o qccguistuff.o
LIB_OBJS=
@ -11,16 +13,16 @@ all: qcc
USEGUI_CFLAGS=
# set to -DUSEGUI when compiling the GUI
BASE_CFLAGS=-ggdb -DQCCONLY $(USEGUI_CFLAGS)
BASE_CFLAGS=-ggdb $(USEGUI_CFLAGS)
lib:
R_win_nocyg: $(QCC_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(WIN32GUI_OBJS) -mno-cygwin -mwindows -lcomctl32
R_nocyg: $(QCC_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(WIN32GUI_OBJS) -mno-cygwin -lcomctl32
R_win: $(QCC_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(WIN32GUI_OBJS) -mwindows -lcomctl32
R_win_nocyg: $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS) -mno-cygwin -mwindows -lcomctl32
R_nocyg: $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS) -mno-cygwin -lcomctl32
R_win: $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.exe -O3 -s $(QCC_OBJS) $(COMMON_OBJS) $(WIN32GUI_OBJS) -mwindows -lcomctl32
win_nocyg:
$(MAKE) USEGUI_CFLAGS=-DUSEGUI R_win_nocyg
nocyg:
@ -28,8 +30,8 @@ nocyg:
win:
$(MAKE) USEGUI_CFLAGS=-DUSEGUI R_win
qcc: $(QCC_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.bin -O3 -s $(QCC_OBJS)
qcc: $(QCC_OBJS) $(COMMON_OBJS)
$(CC) $(BASE_CFLAGS) -o fteqcc.bin -O3 -s $(QCC_OBJS) $(COMMON_OBJS)
qccmain.o: qccmain.c qcc.h
$(DO_CC)
@ -58,10 +60,23 @@ qccguistuff.o: qccguistuff.c qcc.h
qcc_gtk.o: qcc_gtk.c qcc.h
$(DO_CC) `pkg-config --cflags gtk+-2.0`
R_gtkgui: $(QCC_OBJS) $(GTKGUI_OBJS)
$(CC) $(BASE_CFLAGS) -DQCCONLY -DUSEGUI -o fteqccgui.bin -O3 $(GTKGUI_OBJS) $(QCC_OBJS) `pkg-config --libs gtk+-2.0`
R_gtkgui: $(QCC_OBJS) $(COMMON_OBJS) $(GTKGUI_OBJS)
$(CC) $(BASE_CFLAGS) $(USEGUI_CFLAGS) -o fteqccgui.bin -O3 $(GTKGUI_OBJS) $(QCC_OBJS) $(COMMON_OBJS) `pkg-config --libs gtk+-2.0`
gtkgui:
$(MAKE) USEGUI_CFLAGS=-DUSEGUI R_gtkgui
$(MAKE) USEGUI_CFLAGS="-DUSEGUI -DQCCONLY" R_gtkgui
clean:
$(RM) fteqcc.bin fteqcc.exe $(QCC_OBJS) $(GTKGUI_OBJS) $(WIN32GUI_OBJS)
$(RM) fteqcc.bin fteqcc.exe $(QCC_OBJS) $(COMMON_OBJS) $(VM_OBJS) $(GTKGUI_OBJS) $(WIN32GUI_OBJS)
qcvm.so: $(QCC_OBJS) $(VM_OBJS) $(COMMON_OBJS)
$(CC) $(BASE_CFLAGS) -o $@ -O3 -s $(QCC_OBJS) $(VM_OBJS) $(COMMON_OBJS) -shared
test.o: test.c
$(DO_CC)
testapp.bin: qcvm.so test.o
$(CC) $(BASE_CFLAGS) -o testapp.bin -O3 -s qcvm.so test.o
regressiontest: testapp.bin
./testapp.bin regression.dat -srcfile regression.src

View file

@ -2452,6 +2452,14 @@ retry:
return false;
}
if (pr_progs->version == PROG_EXTENDEDVERSION && pr_progs->blockscompressed && !QC_decodeMethodSupported(2))
{
printf ("%s uses compression\n", filename);
PRHunkFree(progfuncs, hmark);
pr_progs=NULL;
return false;
}
fnc = pr_functions = (dfunction_t *)((qbyte *)pr_progs + pr_progs->ofs_functions);
pr_strings = ((char *)pr_progs + pr_progs->ofs_strings);
current_progstate->globaldefs = *(void**)&gd16 = (void *)((qbyte *)pr_progs + pr_progs->ofs_globaldefs);

View file

@ -206,10 +206,10 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
Q_vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
{
void SV_EndRedirect (void);
SV_EndRedirect();
}
// {
// void SV_EndRedirect (void);
// SV_EndRedirect();
// }
// PR_PrintStatement (pr_statements + pr_xstatement);
PR_StackTrace (progfuncs);

View file

@ -7374,7 +7374,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
QCC_def_t *fasttrackpossible;
if (flag_fasttrackarrays)
fasttrackpossible = QCC_PR_GetDef(NULL, "__ext__fasttrackarrays", NULL, true, 1, false);
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 1, false);
else
fasttrackpossible = NULL;

View file

@ -267,7 +267,7 @@ int ParsePrecompilerIf(void)
{
c = QCC_PR_CheckCompConstDefined(pr_token);
if (!c)
eval = false;
eval = atoi(pr_token);
else
eval = atoi(c->value);
}
@ -806,6 +806,11 @@ pbool QCC_PR_Precompiler(void)
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n");
strncpy(QCC_copyright, msg, sizeof(QCC_copyright)-1);
}
else if (!strncmp(qcc_token, "compress", 8))
{
extern pbool compressoutput;
compressoutput = atoi(msg);
}
else if (!strncmp(qcc_token, "forcecrc", 8))
{
ForcedCRC = atoi(msg);

View file

@ -1881,6 +1881,8 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
switch (crc)
{
case 12923: //#pragma sourcefile usage
break;
case 54730:
printf("Recognised progs as QuakeWorld\n");
break;
@ -1902,9 +1904,13 @@ unsigned short QCC_PR_WriteProgdefs (char *filename)
printf("Recognised progs as Hexen2 (demo)\n");
break;
case 32199:
case 22390: //EXT_CSQC_1
printf("Recognised progs as a CSQC module\n");
break;
case 17105:
case 32199: //outdated ext_csqc
printf("Recognised progs as outdated CSQC module\n");
break;
case 52195:
printf("Recognised progs as outdated CSQC module\n");
break;

View file

@ -1,3 +1,4 @@
pbool QC_decodeMethodSupported(int method);
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer);
int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle);

View file

@ -1,17 +1,34 @@
#include "progsint.h"
//#include "qcc.h"
//#define AVAIL_ZLIB
#ifdef AVAIL_ZLIB
#ifdef _WIN32
#define ZEXPORT VARGS
#include "../libs/zlib.h"
//# pragma comment (lib, "zip/zlib.lib")
# pragma comment (lib, "../libs/zlib.lib")
#else
#include <zlib.h>
#endif
#endif
pbool QC_decodeMethodSupported(int method)
{
if (method == 0)
return true;
if (method == 1)
return true;
if (method == 2)
{
#ifdef AVAIL_ZLIB
return false;
#endif
}
return false;
}
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer)
{
int i;
@ -20,15 +37,15 @@ char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *
if (complen != len) Sys_Error("lengths do not match");
memcpy(buffer, info, len);
}
else if (method == 1) //encryption
else if (method == 1) //xor encryption
{
if (complen != len) Sys_Error("lengths do not match");
for (i = 0; i < len; i++)
buffer[i] = info[i] ^ 0xA5;
}
#ifdef AVAIL_ZLIB
else if (method == 2) //compression (ZLIB)
{
#ifdef AVAIL_ZLIB
z_stream strm = {
info,
complen,
@ -54,8 +71,8 @@ char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *
if (Z_STREAM_END != inflate(&strm, Z_FINISH)) //decompress it in one go.
Sys_Error("Failed block decompression\n");
inflateEnd(&strm);
}
#endif
}
//add your decryption/decompression routine here.
else
Sys_Error("Bad file encryption routine\n");
@ -76,16 +93,16 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
SafeWrite(handle, in, len);
return len;
}
else if (method == 1) //encryption
else if (method == 1) //xor encryption
{
for (i = 0; i < len; i++)
in[i] = in[i] ^ 0xA5;
SafeWrite(handle, in, len);
return len;
}
#ifdef AVAIL_ZLIB
else if (method == 2) //compression (ZLIB)
{
#ifdef AVAIL_ZLIB
char out[8192];
z_stream strm = {
@ -122,8 +139,10 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
i+=sizeof(out) - strm.avail_out;
deflateEnd(&strm);
return i;
}
#endif
Sys_Error("ZLIB compression not supported in this build");
return 0;
}
//add your compression/decryption routine here.
else
{

View file

@ -13,9 +13,6 @@
#include <stdio.h>
#include <string.h>
//the only function that is required externally. :/
void SV_EndRedirect (void) {}
@ -97,7 +94,7 @@ pbool Sys_WriteFile (char *fname, void *data, int len)
return 1;
}
void runtest(void)
void runtest(char *progsname)
{
progfuncs_t *pf;
func_t func;
@ -115,9 +112,9 @@ void runtest(void)
pf = InitProgs(&ext);
pf->Configure(pf, 1024*1024, 1); //memory quantity of 1mb. Maximum progs loadable into the instance of 1
//If you support multiple progs types, you should tell the VM the offsets here, via RegisterFieldVar
pn = pf->LoadProgs(pf, "testprogs.dat", 0, builtins, sizeof(builtins)/sizeof(builtins[0])); //load the progs, don't care about the crc, and use those builtins.
pn = pf->LoadProgs(pf, progsname, 0, builtins, sizeof(builtins)/sizeof(builtins[0])); //load the progs, don't care about the crc, and use those builtins.
if (pn < 0)
printf("Failed to load progs\n");
printf("test: Failed to load progs \"%s\"\n", progsname);
else
{
//allocate qc-acessable strings here for 64bit cpus. (allocate via AddString, tempstringbase is a holding area not used by the actual vm)
@ -139,12 +136,14 @@ void runtest(void)
//Run a compiler and nothing else.
//Note that this could be done with an autocompile of PR_COMPILEALWAYS.
void compile(void)
void compile(int argc, char **argv)
{
progfuncs_t *pf;
progparms_t ext;
if (0)
{
char *testsrcfile = //newstyle progs.src must start with a #.
//it's newstyle to avoid using multiple source files.
"#pragma PROGS_DAT \"testprogs.dat\"\r\n"
@ -158,6 +157,7 @@ void compile(void)
//so that the file exists. We could insert it via the callbacks instead
Sys_WriteFile("progs.src", testsrcfile, strlen(testsrcfile));
}
memset(&ext, 0, sizeof(ext));
ext.progsversion = PROGSTRUCT_VERSION;
@ -168,18 +168,29 @@ void compile(void)
ext.printf = printf;
pf = InitProgs(&ext);
if (pf->StartCompile(pf, 0, NULL))
if (pf->StartCompile)
{
if (pf->StartCompile(pf, argc, argv))
{
while(pf->ContinueCompile(pf) == 1)
;
}
}
else
printf("no compiler in this qcvm build\n");
CloseProgs(pf);
}
int main(void)
int main(int argc, char **argv)
{
compile();
runtest();
if (argc < 2)
{
printf("Invalid arguments!\nPlease run as, for example:\n%s testprogs.dat --srcfile progs.src\nThe first argument is the name of the progs.dat to run, the remaining arguments are the qcc args to use", argv[0]);
return 0;
}
compile(argc-2, argv+2);
runtest(argv[1]);
return 0;
}

View file

@ -469,6 +469,7 @@ typedef struct client_s
//===== NETWORK ============
int chokecount;
qboolean waschoked;
int delta_sequence; // -1 = no compression
int last_sequence;
netchan_t netchan;

View file

@ -568,7 +568,7 @@ void SV_Map_f (void)
{
cvar_t *gametype;
gametype = Cvar_Get("mapname", "0", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
gametype = Cvar_Get("mapname", "", CVAR_LATCH|CVAR_SERVERINFO, "Q3 compatability");
gametype->flags |= CVAR_SERVERINFO;
Cvar_ForceSet(gametype, level);

View file

@ -37,6 +37,7 @@ extern cvar_t sv_cheats;
extern cvar_t sv_bigcoords;
extern cvar_t sv_gamespeed;
extern cvar_t sv_csqcdebug;
extern cvar_t sv_csqc_progname;
extern qboolean sv_allow_cheats;
/*
@ -830,18 +831,29 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
//do we allow csprogs?
#ifdef PEXT_CSQC
file = COM_LoadTempFile("csprogs.dat");
if (*sv_csqc_progname.string)
file = COM_LoadTempFile(sv_csqc_progname.string);
else
file = NULL;
if (file)
{
char text[64];
sv.csqcchecksum = Com_BlockChecksum(file, com_filesize);
sprintf(text, "0x%x", sv.csqcchecksum);
Info_SetValueForStarKey(svs.info, "*csprogs", text, MAX_SERVERINFO_STRING);
sprintf(text, "0x%x", com_filesize);
Info_SetValueForStarKey(svs.info, "*csprogssize", text, MAX_SERVERINFO_STRING);
if (strcmp(sv_csqc_progname.string, "csprogs.dat"))
Info_SetValueForStarKey(svs.info, "*csprogsname", sv_csqc_progname.string, MAX_SERVERINFO_STRING);
else
Info_SetValueForStarKey(svs.info, "*csprogsname", "", MAX_SERVERINFO_STRING);
}
else
{
sv.csqcchecksum = 0;
Info_SetValueForStarKey(svs.info, "*csprogs", "", MAX_SERVERINFO_STRING);
Info_SetValueForStarKey(svs.info, "*csprogssize", "", MAX_SERVERINFO_STRING);
Info_SetValueForStarKey(svs.info, "*csprogsname", "", MAX_SERVERINFO_STRING);
}
sv.csqcdebug = sv_csqcdebug.value;

View file

@ -151,6 +151,7 @@ cvar_t sv_masterport = SCVAR("sv_masterport", "0");
cvar_t sv_voicechat = SCVAR("sv_voicechat", "0"); //still development.
cvar_t sv_gamespeed = SCVAR("sv_gamespeed", "1");
cvar_t sv_csqcdebug = SCVAR("sv_csqcdebug", "0");
cvar_t sv_csqc_progname = SCVAR("sv_csqc_progname", "csprogs.dat");
#ifdef TCPCONNECT
cvar_t sv_port_tcp = SCVARC("sv_port_tcp", "", SV_Tcpport_Callback);
#ifdef IPPROTO_IPV6
@ -595,25 +596,27 @@ void PIN_LoadMessages(void)
char message[1024];
int i;
char *file;
char *file, *end;
char *lstart;
int len;
dopinnedload = false;
while(pinned)
PIN_DeleteOldestMessage();
file = COM_LoadMallocFile("pinned.txt");
len = FS_LoadFile("pinned.txt", (void**)&file);
if (!file)
return;
end = file+len;
lstart = file;
for(;;)
{
while (*lstart <= ' ' && *lstart)
while (lstart<end && *lstart <= ' ')
lstart++;
for (i = 0; *lstart && i < sizeof(message)-1; i++)
for (i = 0; lstart<end && i < sizeof(message)-1; i++)
{
if (*lstart == '\n' || *lstart == '\r')
break;
@ -621,10 +624,10 @@ void PIN_LoadMessages(void)
}
message[i] = '\0';
while (*lstart <= ' ' && *lstart)
while (lstart<end && *lstart <= ' ')
lstart++;
for (i = 0; *lstart && i < sizeof(setby)-1; i++)
for (i = 0; lstart<end && i < sizeof(setby)-1; i++)
{
if (*lstart == '\n' || *lstart == '\r')
break;
@ -638,7 +641,7 @@ void PIN_LoadMessages(void)
PIN_MakeMessage(setby, message);
}
BZ_Free(file);
FS_FreeFile(file);
}
void PIN_SaveMessages(void)
{
@ -3916,7 +3919,10 @@ void Master_Shutdown (void)
}
#define iswhite(c) (c == ' ' || c == INVIS_CHAR1 || c == INVIS_CHAR2 || c == INVIS_CHAR3)
#define isinvalid(c) (c == '\r' || c == '\n')
#define isinvalid(c) (c == ':' || c == '\r' || c == '\n' || (unsigned char)(c) == '\xff')
//colon is so clients can't get confused while parsing chats
//255 is so fuhquake/ezquake don't end up with nameless players
//is allowed to shorten, out must be as long as in and min of "unnamed"+1
void SV_FixupName(char *in, char *out, unsigned int outlen)
{
@ -3929,7 +3935,7 @@ void SV_FixupName(char *in, char *out, unsigned int outlen)
len = outlen;
s = out;
while(iswhite(*in) || isinvalid(*in))
while(iswhite(*in) || isinvalid(*in) || *in == '\1' || *in == '\2') //1 and 2 are to stop clients from printing the entire line as chat. only do that for the leading charater.
in++;
while(*in && len > 0)
{

View file

@ -2153,8 +2153,10 @@ void SV_SendClientMessages (void)
if (!sv.paused && !Netchan_CanPacket (&c->netchan, SV_RateForClient(c)))
{
c->chokecount++;
c->waschoked = true;
continue; // bandwidth choke
}
c->waschoked = false;
if (c->state == cs_spawned)
SV_SendClientDatagram (c);

View file

@ -1778,6 +1778,9 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum)
if (!ezfilenum)
return;
if (host_client->waschoked)
return; //don't let chunked downloads flood out the standard packets.
if (!Netchan_CanPacket(&host_client->netchan, SV_RateForClient(host_client)))
return;
}
@ -3729,7 +3732,7 @@ void Cmd_FPSList_f(void)
client_t *cl;
int c;
int f;
double minf = DBL_MIN, maxf = DBL_MAX, this;
double minf = 1000, maxf = 0, this;
double ftime;
int frames;
@ -3749,11 +3752,14 @@ void Cmd_FPSList_f(void)
{
if (cl->frameunion.frames[f].move_msecs >= 0)
{
if (!cl->frameunion.frames[f].move_msecs)
this = 1001;
else
this = 1000.0f/cl->frameunion.frames[f].move_msecs;
ftime += this;
if (minf < this)
if (minf > this)
minf = this;
if (maxf > this)
if (maxf < this)
maxf = this;
frames++;
}
@ -5234,6 +5240,125 @@ void SV_PostRunCmd(void)
}
}
void SV_ReadPrydonCursor(void)
{
float f;
int entnum;
eval_t *cursor_screen, *cursor_start, *cursor_impact, *cursor_entitynumber;
if (svprogfuncs)
{
cursor_screen = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_screen", NULL);
cursor_start = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_start", NULL);
cursor_impact = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_impact", NULL);
cursor_entitynumber = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_entitynumber", NULL);
}
else
{
cursor_screen = NULL;
cursor_start = NULL;
cursor_impact = NULL;
cursor_entitynumber = NULL;
}
f = MSG_ReadShort() * (1.0f / 32767.0f);
if (cursor_screen) cursor_screen->_vector[0] = f;
f = MSG_ReadShort() * (1.0f / 32767.0f);
if (cursor_screen) cursor_screen->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[0] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[2] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[0] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[2] = f;
entnum = (unsigned short)MSG_ReadShort();
if (entnum >= sv.max_edicts)
{
Con_DPrintf("SV_ReadPrydonCursor: client send bad cursor_entitynumber\n");
entnum = 0;
}
// as requested by FrikaC, cursor_trace_ent is reset to world if the
// entity is free at time of receipt
if (!svprogfuncs || EDICT_NUM(svprogfuncs, entnum)->isfree)
entnum = 0;
if (msg_badread) Con_Printf("SV_ReadPrydonCursor: badread at %s:%i\n", __FILE__, __LINE__);
if (cursor_entitynumber) cursor_entitynumber->edict = entnum;
}
void SV_ReadQCRequest(void)
{
int e;
char args[9];
char *rname;
func_t f;
int i;
globalvars_t *pr_globals;
if (!svprogfuncs)
{
msg_badread = true;
return;
}
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
for (i = 0; ; i++)
{
if (i >= sizeof(args))
if (MSG_ReadByte() != ev_void)
{
msg_badread = true;
return;
}
switch(MSG_ReadByte())
{
case ev_void:
i = 6;
break;
case ev_float:
args[i] = 'f';
G_FLOAT(OFS_PARM0+i*3) = MSG_ReadFloat();
break;
case ev_vector:
args[i] = 'v';
G_FLOAT(OFS_PARM0+i*3+0) = MSG_ReadFloat();
G_FLOAT(OFS_PARM0+i*3+1) = MSG_ReadFloat();
G_FLOAT(OFS_PARM0+i*3+2) = MSG_ReadFloat();
break;
case ev_integer:
args[i] = 'i';
G_INT(OFS_PARM0+i*3) = MSG_ReadLong();
break;
case ev_string:
args[i] = 's';
G_INT(OFS_PARM0+i*3) = PR_TempString(svprogfuncs, MSG_ReadString());
break;
case ev_entity:
args[i] = 's';
e = MSG_ReadShort();
if (e < 0 || e >= sv.num_edicts)
e = 0;
G_INT(OFS_PARM0+i*3) = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, e));
break;
}
}
rname = MSG_ReadString();
f = PR_FindFunc(svprogfuncs, va("Cmd_%s_%s", rname, args), PR_ANY);
if (f)
PR_ExecuteProgram(svprogfuncs, f);
}
/*
===================
SV_ExecuteClientMessage
@ -5515,6 +5640,12 @@ haveannothergo:
sv_player = cl->edict;
break;
case clc_prydoncursor:
SV_ReadPrydonCursor();
break;
case clc_qcrequest:
SV_ReadQCRequest();
break;
case clc_stringcmd:
s = MSG_ReadString ();
@ -5762,47 +5893,7 @@ void SVNQ_ReadClientMove (usercmd_t *move)
if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7)
{
float f;
int entnum;
eval_t *cursor_screen, *cursor_start, *cursor_impact, *cursor_entitynumber;
cursor_screen = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_screen", NULL);
cursor_start = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_start", NULL);
cursor_impact = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_impact", NULL);
cursor_entitynumber = svprogfuncs->GetEdictFieldValue(svprogfuncs, host_client->edict, "cursor_entitynumber", NULL);
f = MSG_ReadShort() * (1.0f / 32767.0f);
if (cursor_screen) cursor_screen->_vector[0] = f;
f = MSG_ReadShort() * (1.0f / 32767.0f);
if (cursor_screen) cursor_screen->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[0] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_start) cursor_start->_vector[2] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[0] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[1] = f;
f = MSG_ReadFloat();
if (cursor_impact) cursor_impact->_vector[2] = f;
entnum = (unsigned short)MSG_ReadShort();
if (entnum >= sv.max_edicts)
{
Con_DPrintf("SV_ReadClientMessage: client send bad cursor_entitynumber\n");
entnum = 0;
}
// as requested by FrikaC, cursor_trace_ent is reset to world if the
// entity is free at time of receipt
if (EDICT_NUM(svprogfuncs, entnum)->isfree)
entnum = 0;
if (msg_badread) Con_Printf("SV_ReadClientMessage: badread at %s:%i\n", __FILE__, __LINE__);
if (cursor_entitynumber) cursor_entitynumber->edict = entnum;
SV_ReadPrydonCursor();
}
if (SV_RunFullQCMovement(host_client, move))

View file

@ -298,7 +298,7 @@ void IN_Move(usercmd_t *cmd, int pnum)
#endif
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
else
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
if (in_mlook.state[pnum] & 1)
@ -314,9 +314,9 @@ void IN_Move(usercmd_t *cmd, int pnum)
if (cmd)
{
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
cmd->upmove -= m_forward.value * mouse_y;
movements[2] -= m_forward.value * mouse_y;
else
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
}
mouse_x = mouse_y = 0.0;

View file

@ -81,7 +81,7 @@ void IN_Commands(void)
{
}
void IN_Move(usercmd_t *cmd, int pnum)
void IN_Move(float *movements, int pnum)
{
}

View file

@ -1360,7 +1360,7 @@ void IN_Commands (void)
}
extern int mousecursor_x, mousecursor_y;
void IN_Move (usercmd_t *cmd, int pnum)
void IN_Move (float *movements, int pnum)
{
float mx, my;
float mouse_deltadist;
@ -1414,7 +1414,7 @@ void IN_Move (usercmd_t *cmd, int pnum)
#endif
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
cmd->sidemove += m_side.value * mouse_x;
movements[1] += m_side.value * mouse_x;
else
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
if (in_mlook.state[pnum] & 1)
@ -1430,9 +1430,9 @@ void IN_Move (usercmd_t *cmd, int pnum)
if (cmd)
{
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
cmd->upmove -= m_forward.value * mouse_y;
movements[2] -= m_forward.value * mouse_y;
else
cmd->forwardmove -= m_forward.value * mouse_y;
movements[0] -= m_forward.value * mouse_y;
}
}
mouse_x = mouse_y = 0.0;