Some bugs fixed. I wonder what I've broken.

Oh yeah, hud scoreboard stuff works now.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1883 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-01-21 00:06:49 +00:00
parent 44476382fe
commit e3cb464de9
23 changed files with 487 additions and 56 deletions

View File

@ -851,6 +851,9 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
char string[2048];
clcmdbuf_t *buf, *prev;
if (cls.demoplayback)
return; //no point.
va_start (argptr, format);
_vsnprintf (string,sizeof(string)-1, format,argptr);
va_end (argptr);

View File

@ -579,7 +579,12 @@ void CL_CheckForResend (void)
}
if (adr.port == 0)
adr.port = BigShort (27500);
{
if (connect_type)
adr.port = BigShort (26000); //assume a different port for nq
else
adr.port = BigShort (27500);
}
t2 = Sys_DoubleTime ();
connect_time = realtime+t2-t1; // for retransmit requests

View File

@ -827,6 +827,11 @@ void CL_RequestNextDownload (void)
else
#endif
{
if (cl.worldmodel->needload)
{
Con_Printf("\n\n-------------\nCouldn't download %s - cannot fully connect\n", cl.worldmodel->name);
return;
}
// done with modellist, request first of static signon messages
if (CL_RemoveClientCommands("prespawn"))
Con_Printf("Multiple prespawns\n");

View File

@ -200,7 +200,11 @@ int VARGS Plug_Draw_Image(void *offset, unsigned int mask, const long *arg)
else if (pluginimagearray[i].picfromwad)
return 0; //wasn't loaded.
else
pic = Draw_CachePic(pluginimagearray[i].name);
{
pic = Draw_SafeCachePic(pluginimagearray[i].name);
if (!pic)
return -1;
}
Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), pic);
return 1;
@ -339,6 +343,61 @@ int VARGS Plug_CL_GetStats(void *offset, unsigned int mask, const long *arg)
return max;
}
#define PLUGMAX_SCOREBOARDNAME 64
typedef struct {
int topcolour;
int bottomcolour;
int frags;
char name[PLUGMAX_SCOREBOARDNAME];
int ping;
int pl;
int starttime;
int userid;
int spectator;
char userinfo[1024];
char team[8];
} vmplugclientinfo_t;
int VARGS Plug_GetPlayerInfo(void *offset, unsigned int mask, const long *arg)
{
int i, pt;
vmplugclientinfo_t *out;
if (VM_OOB(arg[1], sizeof(vmplugclientinfo_t)))
return -1;
if (VM_LONG(arg[0]) < -1 || VM_LONG(arg[0] ) >= MAX_CLIENTS)
return -2;
i = VM_LONG(arg[0]);
out = VM_POINTER(arg[1]);
if (i == -1)
{
i = cl.playernum[0];
if (i < 0)
{
memset(out, 0, sizeof(*out));
return 0;
}
}
out->bottomcolour = cl.players[i].bottomcolor;
out->frags = cl.players[i].frags;
Q_strncpyz(out->name, cl.players[i].name, PLUGMAX_SCOREBOARDNAME);
out->ping = cl.players[i].ping;
out->pl = cl.players[i].pl;
out->starttime = cl.players[i].entertime;
out->topcolour = cl.players[i].topcolor;
out->userid = cl.players[i].userid;
out->spectator = cl.players[i].spectator;
Q_strncpyz(out->userinfo, cl.players[i].userinfo, sizeof(out->userinfo));
Q_strncpyz(out->team, cl.players[i].team, sizeof(out->team));
pt = Cam_TrackNum(0);
if (pt < 0)
return (cl.playernum[0] == i);
else
return pt == i;
}
int VARGS Plug_Con_SubPrint(void *offset, unsigned int mask, const long *arg)
{
@ -458,6 +517,8 @@ void Plug_Client_Init(void)
Plug_RegisterBuiltin("LocalSound", Plug_LocalSound, PLUG_BIF_NEEDSRENDERER);
Plug_RegisterBuiltin("SCR_CenterPrint", Plug_SCR_CenterPrint, PLUG_BIF_NEEDSRENDERER);
Plug_RegisterBuiltin("Media_ShowFrameRGBA_32", Plug_Media_ShowFrameRGBA_32, PLUG_BIF_NEEDSRENDERER);
Plug_RegisterBuiltin("GetPlayerInfo", Plug_GetPlayerInfo, PLUG_BIF_NEEDSRENDERER);
}
void Plug_Client_Close(plugin_t *plug)

View File

@ -132,7 +132,7 @@ typedef struct
typedef struct player_info_s
{
int userid;
char userinfo[MAX_INFO_STRING];
char userinfo[EXTENDED_INFO_STRING];
// scoreboard information
char name[MAX_SCOREBOARDNAME];

View File

@ -1,7 +1,7 @@
#include "quakedef.h"
#ifdef WEBCLIENT
//#define DOWNLOADMENU
#define DOWNLOADMENU
#endif
#ifdef DOWNLOADMENU
@ -246,7 +246,7 @@ static void dlnotification(char *localfile, qboolean sucess)
int i;
vfsfile_t *f;
COM_RefreshFSCache_f();
f = FS_OpenVFS (localfile, "rb", FS_BASE);
f = FS_OpenVFS (localfile, "rb", FS_GAME);
if (f)
{
i = atoi(localfile+7);
@ -354,9 +354,9 @@ static void Menu_Download_Got(char *fname, qboolean successful)
}
if (*p->gamedir)
destname = va("%s/%s/%s", com_basedir, p->gamedir, p->dest);
destname = va("%s/%s", p->gamedir, p->dest);
else
destname = va("%s/%s", com_gamedir, p->dest);
destname = va("%s", p->dest);
if (!(p->flags & DPF_DOWNLOADING))
{
@ -367,7 +367,7 @@ static void Menu_Download_Got(char *fname, qboolean successful)
p->flags &= ~DPF_DOWNLOADING;
if (!rename(diskname, destname))
if (!FS_Rename2(diskname, destname, FS_GAME, *p->gamedir?FS_BASE:FS_GAME))
{
Con_Printf("Couldn't rename %s to %s. Removed instead.\nPerhaps you already have it\n", diskname, destname);
unlink(diskname);
@ -413,8 +413,13 @@ static qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int ke
{
if (!(p->flags&DPF_WANTTOINSTALL) && (p->flags&DPF_HAVEAVERSION))
{ //if we don't want it but we have it anyway:
char *fname = va("%s/%s", com_basedir, p->dest);
unlink(fname);
if (*p->gamedir)
{
char *fname = va("%s", p->gamedir, p->dest);
FS_Remove(fname, FS_BASE);
}
else
FS_Remove(p->dest, FS_GAME);
p->flags&=~DPF_HAVEAVERSION; //FIXME: This is error prone.
WriteInstalledPackages();
@ -441,7 +446,6 @@ static qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int ke
p->dlnum = dlcount++;
temp = va("dl_%i.tmp", p->dlnum);
Con_Printf("Downloading %s (to %s)\n", p->fullname, temp);
COM_CreatePath(va("%s/%s", com_gamedir, p->dest));
p->flags|=DPF_DOWNLOADING;
if (!HTTP_CL_Get(p->src, temp, Menu_Download_Got))
p->flags&=~DPF_DOWNLOADING;

View File

@ -6,6 +6,9 @@ int omousex;
int omousey;
qboolean mousemoved;
qboolean bindingactive;
extern cvar_t cl_cursor;
extern cvar_t cl_cursorsize;
extern cvar_t cl_cursorbias;
void Draw_TextBox (int x, int y, int width, int lines)
{
@ -158,7 +161,12 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
case mt_picture:
p = NULL;
if (menu->selecteditem && menu->selecteditem->common.posx == option->common.posx && menu->selecteditem->common.posy == option->common.posy)
p = Draw_SafeCachePic(va("%s_sel", option->picture.picturename));
{
char selname[MAX_QPATH];
Q_strncpyz(selname, option->picture.picturename, sizeof(selname));
COM_StripExtension(selname, selname);
p = Draw_SafeCachePic(va("%s_sel", selname));
}
if (!p)
p = Draw_SafeCachePic(option->picture.picturename);
@ -959,6 +967,7 @@ void M_Complex_Draw(void)
extern int mousecursor_x, mousecursor_y;
menu_t *menu, *cmenu;
qboolean foundexclusive = false;
mpic_t *p;
if (omousex != mousecursor_x || omousey != mousecursor_y)
mousemoved = true;
@ -987,7 +996,19 @@ void M_Complex_Draw(void)
}
MenuDraw(cmenu);
}
Draw_Character(mousecursor_x-4, mousecursor_y-4, '+');
if (!*cl_cursor.string)
p = NULL;
else
p = Draw_SafeCachePic(cl_cursor.string);
if (p)
{
Draw_ImageColours(1, 1, 1, 1);
Draw_Image(mousecursor_x-cl_cursorbias.value, mousecursor_y-cl_cursorbias.value, cl_cursorsize.value, cl_cursorsize.value, 0, 0, 1, 1, p);
// Draw_TransPic(mousecursor_x-4, mousecursor_y-4, p);
}
else
Draw_Character(mousecursor_x-4, mousecursor_y-4, '+');
}
menuoption_t *M_NextItem(menu_t *m, menuoption_t *old)
@ -1408,23 +1429,26 @@ void M_Menu_Main_f (void)
MC_AddPicture(mainm, (320-p->width)/2, 4, "gfx/ttl_main.lmp");
MC_AddPicture(mainm, 72, 32, "gfx/mainmenu.lmp");
b=MC_AddConsoleCommand (mainm, 16, 32, "", "menu_single\n");
p = Draw_SafeCachePic("gfx/mainmenu.lmp");
b=MC_AddConsoleCommand (mainm, 72, 32, "", "menu_single\n");
mainm->selecteditem = (menuoption_t *)b;
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 16, 52, "", "menu_multi\n");
b=MC_AddConsoleCommand (mainm, 72, 52, "", "menu_multi\n");
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 16, 72, "", "menu_options\n");
b=MC_AddConsoleCommand (mainm, 72, 72, "", "menu_options\n");
b->common.width = p->width;
b->common.height = 20;
if (m_helpismedia.value)
b=MC_AddConsoleCommand(mainm, 16, 92, "", "menu_media\n");
b=MC_AddConsoleCommand(mainm, 72, 92, "", "menu_media\n");
else
b=MC_AddConsoleCommand(mainm, 16, 92, "", "help\n");
b=MC_AddConsoleCommand(mainm, 72, 92, "", "help\n");
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 16, 112, "", "menu_quit\n");
b=MC_AddConsoleCommand (mainm, 72, 112, "", "menu_quit\n");
b->common.width = p->width;
b->common.height = 20;

View File

@ -282,6 +282,7 @@ bindnames_t qwbindnames[] =
{
{"+attack", "attack"},
{"impulse 10", "change weapon"},
{"impulse 12", "prev weapon"},
{"+jump", "jump / swim up"},
{"+forward", "walk forward"},
{"+back", "backpedal"},

View File

@ -4359,6 +4359,7 @@ void P_DrawParticles (void)
#if defined(RGLQUAKE)
if (qrenderer == QR_OPENGL)
{
extern int gldepthfunc;
extern cvar_t r_drawflat;
P_FlushRenderer();
@ -4367,6 +4368,9 @@ void P_DrawParticles (void)
qglPolygonOffset(-1, 0);
qglEnable(GL_POLYGON_OFFSET_FILL);
qglEnable(GL_BLEND);
qglDepthFunc(gldepthfunc);
qglDisable(GL_ALPHA_TEST);
qglBegin(GL_QUADS);
if (r_drawflat.value == 2)
@ -4376,6 +4380,8 @@ void P_DrawParticles (void)
qglEnd();
qglDisable(GL_POLYGON_OFFSET_FILL);
RSpeedRemark();
qglBegin(GL_QUADS);
RQ_RenderDistAndClear();

View File

@ -121,7 +121,7 @@ cvar_group_t *Cvar_GetGroup(const char *gname)
g = (cvar_group_t*)Z_Malloc(sizeof(cvar_group_t) + strlen(gname)+1);
g->name = (char*)(g+1);
strcpy(g->name, gname);
strcpy((char*)g->name, gname);
g->next = NULL;
g->next = cvar_groups;
cvar_groups = g;

View File

@ -1663,6 +1663,61 @@ vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto)
return NULL;
}
void FS_Rename2(char *oldf, char *newf, int oldrelativeto, int newrelativeto)
{
char oldfullname[MAX_OSPATH];
char newfullname[MAX_OSPATH];
switch (oldrelativeto)
{
case FS_GAME:
if (*com_homedir)
_snprintf(oldfullname, sizeof(oldfullname), "%s/%s/", com_homedir, gamedirfile);
else
_snprintf(oldfullname, sizeof(oldfullname), "%s/%s/", com_quakedir, gamedirfile);
break;
case FS_SKINS:
if (*com_homedir)
_snprintf(oldfullname, sizeof(oldfullname), "%s/qw/skins/", com_homedir);
else
_snprintf(oldfullname, sizeof(oldfullname), "%s/qw/skins/", com_quakedir);
break;
case FS_BASE:
if (*com_homedir)
_snprintf(oldfullname, sizeof(oldfullname), "%s/", com_homedir);
else
_snprintf(oldfullname, sizeof(oldfullname), "%s/", com_quakedir);
break;
default:
Sys_Error("FS_Rename case not handled\n");
}
switch (newrelativeto)
{
case FS_GAME:
if (*com_homedir)
_snprintf(newfullname, sizeof(newfullname), "%s/%s/", com_homedir, gamedirfile);
else
_snprintf(newfullname, sizeof(newfullname), "%s/%s/", com_quakedir, gamedirfile);
break;
case FS_SKINS:
if (*com_homedir)
_snprintf(newfullname, sizeof(newfullname), "%s/qw/skins/", com_homedir);
else
_snprintf(newfullname, sizeof(newfullname), "%s/qw/skins/", com_quakedir);
break;
case FS_BASE:
if (*com_homedir)
_snprintf(newfullname, sizeof(newfullname), "%s/", com_homedir);
else
_snprintf(newfullname, sizeof(newfullname), "%s/", com_quakedir);
break;
default:
Sys_Error("FS_Rename case not handled\n");
}
rename(va("%s%s", oldfullname, oldf), va("%s%s", newfullname, newf));
}
void FS_Rename(char *oldf, char *newf, int relativeto)
{
char fullname[MAX_OSPATH];

View File

@ -3207,7 +3207,7 @@ void CM_OpenAllPortals(char *ents) //this is a compleate hack. About as compleat
}
#ifndef CLIENTONLY
void CMQ3_CalcPHS (void)
{
int rowbytes, rowwords;
@ -3276,6 +3276,7 @@ void CMQ3_CalcPHS (void)
Con_Printf ("Average clusters visible / hearable / total: %i / %i / %i\n"
, vcount/numclusters, count/numclusters, numclusters);
}
#endif
qbyte *CM_LeafnumPVS (model_t *model, int leafnum, qbyte *buffer)
{
@ -3427,9 +3428,11 @@ void SWR_Q2BSP_StainNode (mnode_t *node, float *parms)
#endif
#ifndef CLIENTONLY
void Q2BSP_FatPVS (model_t *mod, vec3_t org, qboolean add);
qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent);
void Q2BSP_FindTouchedLeafs(model_t *mod, edict_t *ent);
#endif
void GLQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void SWQ2BSP_LightPointValues(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -3594,9 +3597,11 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
CModQ3_LoadVisibility (&header.lumps[Q3LUMP_VISIBILITY]);
CMod_LoadEntityString (&header.lumps[Q3LUMP_ENTITIES]);
#ifndef CLIENTONLY
loadmodel->funcs.FatPVS = Q2BSP_FatPVS;
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
#endif
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
@ -3634,7 +3639,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
CM_CreatePatchesForLeafs (); //for clipping
#ifndef CLIENTONLY
CMQ3_CalcPHS();
#endif
// BZ_Free(map_verts);
BZ_Free(map_faces);
@ -3679,9 +3686,11 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
CMod_LoadAreaPortals (&header.lumps[Q2LUMP_AREAPORTALS]);
CMod_LoadEntityString (&header.lumps[Q2LUMP_ENTITIES]);
#ifndef CLIENTONLY
loadmodel->funcs.FatPVS = Q2BSP_FatPVS;
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
#endif
loadmodel->funcs.LightPointValues = NULL;
loadmodel->funcs.StainNode = NULL;
loadmodel->funcs.MarkLights = NULL;
@ -3717,10 +3726,11 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
CMod_LoadAreas (&header.lumps[Q2LUMP_AREAS]);
CMod_LoadAreaPortals (&header.lumps[Q2LUMP_AREAPORTALS]);
CMod_LoadEntityString (&header.lumps[Q2LUMP_ENTITIES]);
#ifndef CLIENTONLY
loadmodel->funcs.FatPVS = Q2BSP_FatPVS;
loadmodel->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
loadmodel->funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
#endif
loadmodel->funcs.LightPointValues = GLQ2BSP_LightPointValues;
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
@ -3940,9 +3950,12 @@ void CM_InitBoxHull (void)
q2cbrushside_t *s;
#ifndef CLIENTONLY
box_model.funcs.FatPVS = Q2BSP_FatPVS;
box_model.funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS;
box_model.funcs.FindTouchedLeafs_Q1 = Q2BSP_FindTouchedLeafs;
#endif
#ifndef SERVERONLY
box_model.funcs.MarkLights = Q2BSP_MarkLights;
#endif

View File

@ -1496,6 +1496,8 @@ int Plug_ConnectionlessClientPacket(char *buffer, int size)
#ifndef SERVERONLY
void Plug_SBar(void)
{
extern qboolean sb_showscores, sb_showteamscores;
plugin_t *oc=currentplug;
int cp;
vrect_t rect;
@ -1511,7 +1513,7 @@ void Plug_SBar(void)
for (cp = 0; cp < cl.splitclients; cp++)
{ //if you don't use splitscreen, use a full videosize rect.
SCR_VRectForPlayer(&rect, cp);
VM_Call(currentplug->vm, currentplug->sbarlevel[0], cp, rect.x, rect.y, rect.width, rect.height);
VM_Call(currentplug->vm, currentplug->sbarlevel[0], cp, rect.x, rect.y, rect.width, rect.height, sb_showscores+sb_showteamscores*2);
}
break;
}
@ -1532,7 +1534,7 @@ void Plug_SBar(void)
for (cp = 0; cp < cl.splitclients; cp++)
{ //if you don't use splitscreen, use a full videosize rect.
SCR_VRectForPlayer(&rect, cp);
VM_Call(currentplug->vm, currentplug->sbarlevel[1], cp, rect.x, rect.y, rect.width, rect.height);
VM_Call(currentplug->vm, currentplug->sbarlevel[1], cp, rect.x, rect.y, rect.width, rect.height, sb_showscores+sb_showteamscores*2);
}
}
}
@ -1544,7 +1546,7 @@ void Plug_SBar(void)
for (cp = 0; cp < cl.splitclients; cp++)
{ //if you don't use splitscreen, use a full videosize rect.
SCR_VRectForPlayer(&rect, cp);
VM_Call(currentplug->vm, currentplug->sbarlevel[2], cp, rect.x, rect.y, rect.width, rect.height);
VM_Call(currentplug->vm, currentplug->sbarlevel[2], cp, rect.x, rect.y, rect.width, rect.height, sb_showscores+sb_showteamscores*2);
}
}
}

View File

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
float pm_stepheight = 18;
#ifdef Q2BSPS
#if defined(Q2CLIENT) || defined(Q2SERVER)
#define Q2PMF_DUCKED 1
#define Q2PMF_JUMP_HELD 2

View File

@ -44,7 +44,7 @@ void Cache_FreeHigh (int new_high_hunk);
#define TEMPDEBUG 4
#define ZONEDEBUG 4
#define HUNKDEBUG 4
#define CACHEDEBUG 640
#define CACHEDEBUG 4
//these need to be defined because it makes some bits of code simpler
#ifndef HUNKDEBUG

View File

@ -1304,7 +1304,7 @@ void GLDraw_ColouredCharacter (int x, int y, unsigned int num)
// render character with foreground color
col = (num & CON_FGMASK) >> CON_FGSHIFT;
qglColor3f(consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb);
qglColor4f(consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb, (num & CON_HALFALPHA)?0.5:1);
Draw_Character(x, y, num);
}
/*

View File

@ -3112,10 +3112,11 @@ void R_DrawWorld (void)
{
int leafnum;
int clientarea;
#ifdef QUAKE2
if (cls.protocol == CP_QUAKE2) //we can get server sent info
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
else
#endif
{ //generate the info each frame.
leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
clientarea = CM_LeafArea (cl.worldmodel, leafnum);

View File

@ -102,12 +102,14 @@ func_t ChatMessage;
func_t getplayerstat[MAX_CL_STATS];
func_t getplayerstati[MAX_CL_STATS];
//mvdsv stuff
func_t mod_UserCmd, SV_ParseClientCommand;
func_t mod_UserCmd, SV_ParseClientCommand, SV_ParseConnectionlessPacket;
func_t mod_ConsoleCmd;
func_t UserInfo_Changed;
func_t localinfoChanged;
func_t pr_SV_PausedTic;
func_t pr_SV_ShouldPause;
func_t SV_PlayerPhysicsQC; //DP's DP_SV_PLAYERPHYSICS extension
func_t EndFrameQC;
@ -514,6 +516,7 @@ void PR_LoadGlabalStruct(void)
}
SV_ParseClientCommand = PR_FindFunction(svprogfuncs, "SV_ParseClientCommand", PR_ANY);
SV_ParseConnectionlessPacket = PR_FindFunction(svprogfuncs, "SV_ParseConnectionlessPacket", PR_ANY);
UserInfo_Changed = PR_FindFunction(svprogfuncs, "UserInfo_Changed", PR_ANY);
localinfoChanged = PR_FindFunction(svprogfuncs, "localinfoChanged", PR_ANY);
@ -521,6 +524,9 @@ void PR_LoadGlabalStruct(void)
mod_UserCmd = PR_FindFunction(svprogfuncs, "UserCmd", PR_ANY);
mod_ConsoleCmd = PR_FindFunction(svprogfuncs, "ConsoleCmd", PR_ANY);
pr_SV_PausedTic = PR_FindFunction(svprogfuncs, "SV_PausedTic", PR_ANY);
pr_SV_ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY);
if (pr_no_playerphysics.value)
SV_PlayerPhysicsQC = 0;
else
@ -1285,6 +1291,76 @@ qboolean PR_QCChat(char *text, int say_type)
return false;
}
qboolean PR_GameCodePausedTic(float pausedtime)
{ //notications to the gamecode that the server is paused.
globalvars_t *pr_globals;
if (!svprogfuncs || !pr_SV_ShouldPause)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = pausedtime;
PR_ExecuteProgram (svprogfuncs, pr_SV_PausedTic);
if (G_FLOAT(OFS_RETURN))
return true;
return false;
}
qboolean PR_ShouldTogglePause(client_t *initiator, qboolean newpaused)
{
globalvars_t *pr_globals;
if (!svprogfuncs || !pr_SV_ShouldPause)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
if (initiator)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, initiator->edict);
else
pr_global_struct->self = 0;
G_FLOAT(OFS_PARM0) = newpaused;
PR_ExecuteProgram (svprogfuncs, pr_SV_ShouldPause);
return G_FLOAT(OFS_RETURN);
}
qboolean PR_GameCodePacket(char *s)
{
globalvars_t *pr_globals;
int i;
client_t *cl;
if (!SV_ParseConnectionlessPacket)
return false;
if (!svprogfuncs)
return false;
pr_globals = PR_globals(svprogfuncs, PR_CURRENT);
pr_global_struct->time = sv.time;
// check for packets from connected clients
pr_global_struct->self = 0;
for (i=0, cl=svs.clients ; i<MAX_CLIENTS ; i++,cl++)
{
if (cl->state == cs_free)
continue;
if (!NET_CompareAdr (net_from, cl->netchan.remote_address))
continue;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
break;
}
G_INT(OFS_PARM0) = (int)NET_AdrToString (net_from);
G_INT(OFS_PARM1) = (int)PR_SetString(svprogfuncs, s);
PR_ExecuteProgram (svprogfuncs, SV_ParseConnectionlessPacket);
return G_FLOAT(OFS_RETURN);
}
qboolean PR_KrimzonParseCommand(char *s)
{
globalvars_t *pr_globals;
@ -1293,6 +1369,8 @@ qboolean PR_KrimzonParseCommand(char *s)
if (ge)
return false;
#endif
if (!svprogfuncs)
return false;
if (SV_ParseClientCommand)
{ //the QC is expected to send it back to use via a builtin.
@ -1320,6 +1398,8 @@ qboolean PR_UserCmd(char *s)
return true; //the dll will convert it to chat.
}
#endif
if (!svprogfuncs)
return false;
if (SV_ParseClientCommand)
{ //the QC is expected to send it back to use via a builtin.
@ -6175,7 +6255,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_ENT_EXTERIORMODELTOCLIENT"},
//only in dp6 currently {"DP_ENT_GLOW"},
{"DP_ENT_VIEWMODEL"},
//Might be buggy {"DP_GFX_QUAKE3MODELTAGS"},
{"DP_GFX_QUAKE3MODELTAGS"},
{"DP_GFX_SKINFILES"},
{"DP_GFX_SKYBOX"}, //according to the spec. :)
{"DP_HALFLIFE_MAP_CVAR"},
@ -6210,6 +6290,9 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QUAKE2_SPRITE"},
{"DP_QUAKE3_MODEL"},
{"DP_REGISTERCVAR", 1, NULL, {"registercvar"}},
{"DP_SND_STEREOWAV"},
{"DP_SND_OGGVORBIS"},
{"DP_SOLIDCORPSE"},
{"DP_SPRITE32"}, //hmm... is it legal to advertise this one?
{"DP_SV_CLIENTCOLORS"},
{"DP_SV_CLIENTNAME"},
@ -6225,13 +6308,13 @@ lh_extension_t QSG_Extensions[] = {
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
{"DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}},
{"DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}},
//explosionrgb
{"DP_TE_EXPLOSIONRGB"},
//flamejet
{"DP_TE_PARTICLECUBE", 1, NULL, {"te_particlecube"}},
//particlerain
//particlesnow
{"DP_TE_PLASMABURN", 1, NULL, {"te_plasmaburn"}},
//quadeffects1
{"DP_TE_QUADEFFECTS1"},
{"DP_TE_SMALLFLASH", 1, NULL, {"te_smallflash"}},
{"DP_TE_SPARK", 1, NULL, {"te_spark"}},
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}},
@ -6242,6 +6325,7 @@ lh_extension_t QSG_Extensions[] = {
{"EXT_DIMENSION_GHOST"},
{"FRIK_FILE", 11, NULL, {"stof", "fopen","fclose","fgets","fputs","strlen","strcat","substring","stov","strzone","strunzone"}},
{"FTE_CALLTIMEOFDAY", 1, NULL, {"calltimeofday"}},
{"FTE_EXTENDEDTEXTCODES"},
{"FTE_FORCEINFOKEY", 1, NULL, {"forceinfokey"}},
{"FTE_GFX_QUAKE3SHADERS"},
{"FTE_ISBACKBUFFERED", 1, NULL, {"isbackbuffered"}},
@ -6258,17 +6342,22 @@ lh_extension_t QSG_Extensions[] = {
#endif
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
{"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclient"}},
{"FTE_QC_PAUSED"},
{"FTE_QC_TRACETRIGGER"},
{"FTE_SOLID_LADDER"}, //part of a worthy hl implementation. Allows a simple trigger to remove effects of gravity (solid 20)
//eperimental advanced strings functions.
//reuses the FRIK_FILE builtins (with substring extension)
{"FTE_STRINGS", 16, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone",
"strstrofs", "str2chr", "chr2str", "strconv", "infoadd", "infoget", "strncmp", "strcasecmp", "strncasecmp"}},
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}},
{"FTE_SV_REENTER"},
{"FTE_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash",
"te_teleport", "te_lightning1", "te_lightning2", "te_lightning3", "te_lightningblood", "te_bloodqw"}},
{"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system.
{"NEH_CMD_PLAY2"},
{"NEH_RESTOREGAME"},
//{"PRYDON_CLIENTCURSOR"},
{"QSG_CVARSTRING", 1, NULL, {"cvar_string"}},
{"QW_ENGINE", 1, NULL, {"infokey", "stof", "logfrag"}}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ.
@ -9031,6 +9120,16 @@ void PF_matchclient(progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_INT(OFS_RETURN) = 0; //world
}
void PF_SendPacket(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
netadr_t to;
char *address = PR_GetStringOfs(prinst, OFS_PARM0);
char *contents = PF_VarString(prinst, 1, pr_globals);
NET_StringToAdr(address, &to);
NET_SendPacket(NS_SERVER, strlen(contents), contents, to);
}
BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"fixme", PF_Fixme, 0, 0, 0},
{"ignore", PF_Ignore, 0, 0, 0},
@ -9338,7 +9437,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"te_bloodqw", PF_te_bloodqw, 0, 0, 0, 239},
{"checkpvs", PF_checkpvs, 0, 0, 0, 240},
{"matchclientname", PF_matchclient, 0, 0, 0, 241},
{"matchclientname", PF_matchclient, 0, 0, 0, 241},
{"sendpacket", PF_SendPacket, 0, 0, 0, 242}, //void(string dest, string content) sendpacket = #242; (FTE_QC_SENDPACKET)
//end fte extras

View File

@ -114,6 +114,7 @@ typedef struct
double lastchecktime; // for monster ai
qboolean paused; // are we paused?
float pausedstart;
//check player/eyes models for hacks
unsigned model_player_checksum;
@ -994,7 +995,7 @@ void SV_ExecuteClientMessage (client_t *cl);
void SVQ2_ExecuteClientMessage (client_t *cl);
int SV_PMTypeForClient (client_t *cl);
void SV_UserInit (void);
void SV_TogglePause (void);
qboolean SV_TogglePause (client_t *cl);
void SV_ClientThink (void);
@ -1017,6 +1018,15 @@ void SV_EndRedirect (void);
//
void SV_Status_f (void);
qboolean PR_GameCodePacket(char *s);
qboolean PR_GameCodePausedTic(float pausedtime);
qboolean PR_ShouldTogglePause(client_t *initiator, qboolean pausedornot);
//
// sv_ents.c
//

View File

@ -2189,7 +2189,6 @@ void SVC_RemoteCommand (void)
SV_EndRedirect ();
}
/*
=================
SV_ConnectionlessPacket
@ -2266,7 +2265,7 @@ qboolean SV_ConnectionlessPacket (void)
#endif
else if (!strcmp(c, "rcon"))
SVC_RemoteCommand ();
else
else if (!PR_GameCodePacket(net_message.data+4))
Con_Printf ("bad connectionless packet from %s:\n%s\n"
, NET_AdrToString (net_from), s);
@ -2741,8 +2740,8 @@ void SV_CheckTimeouts (void)
}
if (sv.paused && !nclients) {
// nobody left, unpause the server
SV_TogglePause();
SV_BroadcastTPrintf(PRINT_HIGH, STL_CLIENTLESSUNPAUSE);
if (SV_TogglePause(NULL))
SV_BroadcastTPrintf(PRINT_HIGH, STL_CLIENTLESSUNPAUSE);
}
}
@ -2998,8 +2997,14 @@ void SV_MVDStream_Poll(void);
// move autonomous things around if enough time has passed
if (!sv.paused)
{
if (SV_Physics ())
return;
}
else
{
PR_GameCodePausedTic(Sys_DoubleTime() - sv.pausedstart);
}
while(SV_ReadMVD());

View File

@ -1257,8 +1257,17 @@ void SV_Begin_f (void)
#endif
if (split->istobeloaded)
{
func_t f;
sendangles = true;
split->istobeloaded = false;
f = PR_FindFunc(svprogfuncs, "RestoreGame", PR_ANY);
if (f)
{
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict);
PR_ExecuteProgram (svprogfuncs, f);
}
}
else
{
@ -2111,24 +2120,34 @@ void SV_Kill_f (void)
SV_TogglePause
==================
*/
void SV_TogglePause (void)
qboolean SV_TogglePause (client_t *initiator)
{
int i;
client_t *cl;
int newv;
sv.paused ^= 1;
newv = sv.paused^1;
if (!PR_ShouldTogglePause(initiator, newv))
return false;
sv.paused = newv;
sv.pausedstart = Sys_DoubleTime();
// send notification to all clients
for (i=0, cl = svs.clients ; i<MAX_CLIENTS ; i++, cl++)
{
if (!cl->state)
continue;
if (!ISQ2CLIENT(host_client) && !cl->controller)
if (!ISQ2CLIENT(cl) && !cl->controller)
{
ClientReliableWrite_Begin (cl, svc_setpause, 2);
ClientReliableWrite_Byte (cl, sv.paused);
}
}
return true;
}
@ -2151,11 +2170,13 @@ void SV_Pause_f (void)
return;
}
SV_TogglePause();
if (sv.paused)
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTPAUSED, host_client->name);
else
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTUNPAUSED, host_client->name);
if (SV_TogglePause(host_client))
{
if (sv.paused)
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTPAUSED, host_client->name);
else
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTUNPAUSED, host_client->name);
}
}

View File

@ -156,6 +156,8 @@ void D_RasterizeAliasPolySmooth8Asm (void);
void D_RasterizeAliasPolySmooth8C (void);
void D_PolysetScanLeftEdgeC (int height);
void D_PolysetRecursiveTriangle16C (int *lp1, int *lp2, int *lp3);
void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
fixed8_t endvertu, fixed8_t endvertv);
@ -477,7 +479,7 @@ split:
int pix;
*zbuf = z;
pix = d_pcolormap[apalremap[skintable[new[3]>>16][new[2]>>16]]];
pix = ((unsigned short *)d_pcolormap)[skintable[new[3]>>16][new[2]>>16]];
((unsigned short *)d_viewbuffer)[d_scantable[new[1]] + new[0]] = pix;//d_8to32table[pix];
}
@ -1130,6 +1132,32 @@ void D_PolysetDrawFinalVertsC (finalvert_t *fv, int numverts)
}
}
void D_PolysetDrawFinalVerts16C (finalvert_t *fv, int numverts)
{
int i, z;
short *zbuf;
for (i=0 ; i<numverts ; i++, fv++)
{
// valid triangle coordinates for filling can include the bottom and
// right clip edges, due to the fill rule; these shouldn't be drawn
if ((fv->v[0] < r_refdef.vrectright) &&
(fv->v[1] < r_refdef.vrectbottom))
{
z = fv->v[5]>>16;
zbuf = zspantable[fv->v[1]] + fv->v[0];
if (z >= *zbuf)
{
int pix;
*zbuf = z;
pix = skintable[fv->v[3]>>16][fv->v[2]>>16];
pix = ((unsigned short *)acolormap)[apalremap[pix] + (fv->v[4] & 0xFF00) ];
((unsigned short*)d_viewbuffer)[d_scantable[fv->v[1]] + fv->v[0]] = pix;
}
}
}
}
/*
================
@ -1162,12 +1190,17 @@ void D_DrawSubdivC (void)
{
if (r_pixbytes == 4)
drawfnc = D_PolysetRecursiveTriangle32Trans;
else if (r_pixbytes == 2)
drawfnc = D_PolysetRecursiveTriangle16C;
else if (r_pixbytes == 1)
drawfnc = D_PolysetRecursiveTriangleTrans;
}
else
#endif
drawfnc = D_PolysetRecursiveTriangleC;
if (r_pixbytes == 2)
drawfnc = D_PolysetRecursiveTriangle16C;
else
drawfnc = D_PolysetRecursiveTriangleC;
for (i=0 ; i<lnumtriangles ; i++)
{
@ -1195,7 +1228,7 @@ void D_DrawSubdivC (void)
index2->v[2] = stv->s;
index2->v[3] = stv->t;
/*
{
int z;
short *zbuf;
@ -1241,7 +1274,7 @@ void D_DrawSubdivC (void)
d_viewbuffer[d_scantable[index2->v[1]] + index2->v[0]] = pix;//Trans(d_viewbuffer[d_scantable[index0->v[1]] + index0->v[0]], pix);
}
}
*/
d_pcolormap = &((qbyte *)acolormap)[index0->v[4] & 0xFF00];
drawfnc(index0->v, index1->v, index2->v);
@ -1452,6 +1485,86 @@ nodraw:
D_PolysetRecursiveTriangleC (lp3, new, lp2);
}
void D_PolysetRecursiveTriangle16C (int *lp1, int *lp2, int *lp3)
{
int *temp;
int d;
int new[6];
int z;
short *zbuf;
d = lp2[0] - lp1[0];
if (d < -1 || d > 1)
goto split;
d = lp2[1] - lp1[1];
if (d < -1 || d > 1)
goto split;
d = lp3[0] - lp2[0];
if (d < -1 || d > 1)
goto split2;
d = lp3[1] - lp2[1];
if (d < -1 || d > 1)
goto split2;
d = lp1[0] - lp3[0];
if (d < -1 || d > 1)
goto split3;
d = lp1[1] - lp3[1];
if (d < -1 || d > 1)
{
split3:
temp = lp1;
lp1 = lp3;
lp3 = lp2;
lp2 = temp;
goto split;
}
return; // entire tri is filled
split2:
temp = lp1;
lp1 = lp2;
lp2 = lp3;
lp3 = temp;
split:
// split this edge
new[0] = (lp1[0] + lp2[0]) >> 1;
new[1] = (lp1[1] + lp2[1]) >> 1;
new[2] = (lp1[2] + lp2[2]) >> 1;
new[3] = (lp1[3] + lp2[3]) >> 1;
new[5] = (lp1[5] + lp2[5]) >> 1;
// draw the point if splitting a leading edge
if (lp2[1] > lp1[1])
goto nodraw;
if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
goto nodraw;
z = new[5]>>16;
zbuf = zspantable[new[1]] + new[0];
if (z >= *zbuf)
{
int pix;
// lptex = (qbyte *)((unsigned char *)r_affinetridesc.pskin+tex);
// lpdest[0] = ((unsigned short *)acolormap)[apalremap[*lptex] + (llight & 0xFF00)];
*zbuf = z;
pix = skintable[new[3]>>16][new[2]>>16];
((unsigned short *)d_viewbuffer)[d_scantable[new[1]] + new[0]] = pix;
}
nodraw:
// recursively continue
D_PolysetRecursiveTriangle16C (lp3, lp1, new);
D_PolysetRecursiveTriangle16C (lp3, new, lp2);
}
/*
================

View File

@ -596,19 +596,21 @@ void R_AliasPrepareUnclippedPoints (void)
r_anumverts = pmdl->numverts;
R_AliasTransformAndProjectFinalVerts (pfinalverts);
/*
if (r_affinetridesc.drawtype)
{
if (r_pixbytes == 4)
D_PolysetDrawFinalVerts32Trans (pfinalverts, r_anumverts);
else if (r_pixbytes == 2)
D_PolysetDrawFinalVerts16C (pfinalverts, r_anumverts);
#if 0//id386
else if (t_state & TT_ONE)
D_PolysetDrawFinalVertsAsm (pfinalverts, r_anumverts);
#endif
// else
// D_PolysetDrawFinalVertsC (pfinalverts, r_anumverts);
else
D_PolysetDrawFinalVertsC (pfinalverts, r_anumverts);
}
*/
r_affinetridesc.pfinalverts = pfinalverts;
r_affinetridesc.ptriangles = (mtriangle_t *)
((qbyte *)paliashdr + paliashdr->triangles);