misc bugfixes for things reported by 1path0gen1.

and a few added bugs for fun.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4562 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-12-08 20:06:55 +00:00
parent a62660d5e7
commit 483403dc9a
19 changed files with 237 additions and 61 deletions

View file

@ -630,6 +630,7 @@ void CL_CheckForResend (void)
char data[2048];
double t1, t2;
int contype = 0;
qboolean keeptrying = true;
#ifndef CLIENTONLY
if (!cls.state && sv.state)
@ -828,6 +829,8 @@ void CL_CheckForResend (void)
if (!NET_EnsureRoute(cls.sockets, "conn", cls.servername, false))
{
Con_Printf ("Unable to establish connection to %s\n", cls.servername);
connect_time = -1;
SCR_EndLoadingPlaque();
return;
}
@ -839,7 +842,7 @@ void CL_CheckForResend (void)
if (contype & 1)
{
Q_snprintfz (data, sizeof(data), "%c%c%c%cgetchallenge\n", 255, 255, 255, 255);
NET_SendPacket (NS_CLIENT, strlen(data), data, &adr);
keeptrying &= NET_SendPacket (NS_CLIENT, strlen(data), data, &adr);
}
/*NQ*/
#ifdef NQPROT
@ -871,11 +874,18 @@ void CL_CheckForResend (void)
MSG_WriteString(&sb, "getchallenge");
*(int*)sb.data = LongSwap(NETFLAG_CTL | sb.cursize);
NET_SendPacket (NS_CLIENT, sb.cursize, sb.data, &adr);
keeptrying &= NET_SendPacket (NS_CLIENT, sb.cursize, sb.data, &adr);
}
#endif
connect_tries++;
if (!keeptrying)
{
Con_TPrintf ("No route to host, giving up\n");
connect_time = -1;
SCR_EndLoadingPlaque();
}
}
void CL_BeginServerConnect(int port)

View file

@ -340,7 +340,7 @@ void M_Menu_SinglePlayer_f (void)
{
MC_AddPicture(menu, 72, 32, 232, 64, "gfx/sp_menu.lmp");
b = MC_AddConsoleCommand (menu, 16, 32, "", "closemenu\nmaxclients 1;deathmatch 0;coop 0;map start\n");
b = MC_AddConsoleCommand (menu, 16, 32, "", "closemenu;disconnect;maxclients 1;deathmatch 0;coop 0;map start\n");
menu->selecteditem = (menuoption_t *)b;
b->common.width = p->width;
b->common.height = 20;

View file

@ -1498,7 +1498,7 @@ static struct {
{"hash_getcb", PF_hash_getcb, 293},
{"checkcommand", PF_checkcommand, 294},
//gap
{"print", PF_print, 339},
{"print_csqc", PF_print, 339},
{"keynumtostring_csqc", PF_cl_keynumtostring, 340},
{"stringtokeynum", PF_cl_stringtokeynum, 341},
{"getkeybind", PF_cl_getkeybind, 342},
@ -1880,6 +1880,8 @@ qboolean MP_Init (void)
PR_ExecuteProgram(menu_world.progs, mp_init_function);
inmenuprogs--;
EDICT_NUM(menu_world.progs, 0)->readonly = true;
Con_DPrintf("Initialized menu.dat\n");
return true;
}

View file

@ -412,7 +412,8 @@ qbyte *R_MarkLeaves_Q3 (void);
void R_SetFrustum (float projmat[16], float viewmat[16]);
void R_SetRenderer(rendererinfo_t *ri);
void R_AnimateLight (void);
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base);
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
struct texture_s *R_TextureAnimation_Q2 (struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
void RQ_Init(void);
void RQ_Shutdown(void);

View file

@ -339,8 +339,8 @@ cvar_t r_shadows = SCVARF ("r_shadows", "0",
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
cvar_t r_lightprepass = CVARFD("r_lightprepass", "0", CVAR_SHADERSYSTEM, "Experimental. Attempt to use a different lighting mechanism.");
cvar_t r_shadow_bumpscale_basetexture = SCVAR ("r_shadow_bumpscale_basetexture", "4");
cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10");
cvar_t r_shadow_bumpscale_basetexture = CVARD ("r_shadow_bumpscale_basetexture", "0", "bumpyness scaler for generation of fallback normalmap textures from models");
cvar_t r_shadow_bumpscale_bumpmap = CVARD ("r_shadow_bumpscale_bumpmap", "4", "bumpyness scaler for _bump textures");
cvar_t r_glsl_offsetmapping = CVARF ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
@ -1742,6 +1742,29 @@ texture_t *R_TextureAnimation (int frame, texture_t *base)
return base;
}
texture_t *R_TextureAnimation_Q2 (texture_t *base)
{
int reletive;
int frame;
if (!base->anim_total)
return base;
//this is only ever used on world. everything other than rtlights have proper batches.
frame = cl.time*2; //q2 is lame
reletive = frame % base->anim_total;
while (reletive --> 0)
{
base = base->anim_next;
if (!base)
Sys_Error ("R_TextureAnimation: broken cycle");
}
return base;
}

View file

@ -92,7 +92,7 @@ void NET_CloseServer (void);
void UDP_CloseSocket (int socket);
void NET_Shutdown (void);
int NET_GetPacket (netsrc_t netsrc, int firstsock);
void NET_SendPacket (netsrc_t socket, int length, void *data, netadr_t *to);
qboolean NET_SendPacket (netsrc_t socket, int length, void *data, netadr_t *to);
int NET_LocalAddressForRemote(struct ftenet_connections_s *collection, netadr_t *remote, netadr_t *local, int idx);
void NET_PrintAddresses(struct ftenet_connections_s *collection);
qboolean NET_AddressSmellsFunny(netadr_t *a);

View file

@ -2716,6 +2716,8 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
{
Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost.
}
else if (err == ENOTCONN)
Con_Printf ("TCPConnect_GetPacket: connection failed\n");
else
Con_Printf ("TCPConnect_GetPacket: Error (%i): %s\n", err, strerror(err));
@ -4242,6 +4244,7 @@ typedef struct
qboolean havepacket;
qboolean failed;
int showerror;
} ftenet_websocket_connection_t;
static void websocketgot(void *user_data, int32_t result)
@ -4255,6 +4258,7 @@ static void websocketgot(void *user_data, int32_t result)
{
Sys_Printf("%s: %i\n", __func__, result);
wsc->failed = true;
wsc->showerror = result;
}
}
static void websocketconnected(void *user_data, int32_t result)
@ -4274,6 +4278,7 @@ static void websocketconnected(void *user_data, int32_t result)
Sys_Printf("%s: %i\n", __func__, result);
//some sort of error connecting, make it timeout now
wsc->failed = true;
wsc->showerror = result;
}
}
static void websocketclosed(void *user_data, int32_t result)
@ -4368,6 +4373,54 @@ static qboolean FTENET_NaClWebSocket_GetPacket(ftenet_generic_connection_t *gcon
}
return true;
}
if (wsc->showerror != PP_OK)
{
switch(wsc->showerror)
{
case PP_ERROR_FAILED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_FAILED\n");
break;
case PP_ERROR_ABORTED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ABORTED\n");
break;
case PP_ERROR_NOTSUPPORTED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_NOTSUPPORTED\n");
break;
case PP_ERROR_CONNECTION_CLOSED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_CLOSED\n");
break;
case PP_ERROR_CONNECTION_RESET:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_RESET\n");
break;
case PP_ERROR_CONNECTION_REFUSED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_REFUSED\n");
break;
case PP_ERROR_CONNECTION_ABORTED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_ABORTED\n");
break;
case PP_ERROR_CONNECTION_FAILED:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_FAILED\n");
break;
case PP_ERROR_CONNECTION_TIMEDOUT:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_CONNECTION_TIMEDOUT\n");
break;
case PP_ERROR_ADDRESS_INVALID:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_INVALID\n");
break;
case PP_ERROR_ADDRESS_UNREACHABLE:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_UNREACHABLE\n");
break;
case PP_ERROR_ADDRESS_IN_USE:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: PP_ERROR_ADDRESS_IN_USE\n");
break;
default:
Con_TPrintf ("FTENET_NaClWebSocket_GetPacket: error %i\n", wsc->showerror);
break;
}
wsc->showerror = PP_OK;
}
return false;
}
static qboolean FTENET_NaClWebSocket_SendPacket(ftenet_generic_connection_t *gcon, int length, void *data, netadr_t *to)
@ -4520,9 +4573,9 @@ int NET_LocalAddressForRemote(ftenet_connections_t *collection, netadr_t *remote
return collection->conn[remote->connum-1]->GetLocalAddress(collection->conn[remote->connum-1], local, idx);
}
void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
qboolean NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
{
char buffer[64];
// char buffer[64];
ftenet_connections_t *collection;
int i;
@ -4530,7 +4583,7 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
{
#ifdef CLIENTONLY
Sys_Error("NET_GetPacket: Bad netsrc");
return;
return false;
#else
collection = svs.sockets;
#endif
@ -4539,26 +4592,26 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
{
#ifdef SERVERONLY
Sys_Error("NET_GetPacket: Bad netsrc");
return;
return false;
#else
collection = cls.sockets;
#endif
}
if (!collection)
return;
return false;
if (net_fakeloss.value)
{
if (frandom () < net_fakeloss.value)
return;
return true;
}
if (to->connum)
{
if (collection->conn[to->connum-1])
if (collection->conn[to->connum-1]->SendPacket(collection->conn[to->connum-1], length, data, to))
return;
return true;
}
for (i = 0; i < MAX_CONNECTIONS; i++)
@ -4566,10 +4619,11 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
if (!collection->conn[i])
continue;
if (collection->conn[i]->SendPacket(collection->conn[i], length, data, to))
return;
return true;
}
Con_Printf("No route to %s - try reconnecting\n", NET_AdrToString(buffer, sizeof(buffer), to));
// Con_Printf("No route to %s - try reconnecting\n", NET_AdrToString(buffer, sizeof(buffer), to));
return false;
}
qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char *host, qboolean islisten)
@ -4586,6 +4640,7 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
case NA_IRC:
if (!FTENET_AddToCollection(collection, routename, host, adr.type, islisten))
return false;
Con_Printf("Establishing connection to %s\n", host);
break;
default:
//not recognised, or not needed

View file

@ -124,6 +124,9 @@
#ifdef EACCES
#undef EACCES
#endif
#ifdef ENOTCONN
#undef ENOTCONN
#endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS

View file

@ -122,6 +122,7 @@ typedef struct q2trace_s
#define MOVE_EVERYTHING 32 //can return triggers and non-solid items if they're marked with FINDABLE_NONSOLID (works even if the items are not properly linked)
#define MOVE_LAGGED 64 //trace touches current last-known-state, instead of actual ents (just affects players for now)
#define MOVE_ENTCHAIN 128 //chain of impacted ents, otherwise result shows only world
#define MOVE_ONLYENT 256 //test the trace against a single entity, ignoring non-solid/owner/etc flags (but respecting contents).
typedef struct areanode_s
{

View file

@ -2754,10 +2754,7 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
else if (batch->texture)
{
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
batch->skin = &batch->shader->defaulttextures;
}
if (batch->shader->flags & SHADER_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT)
@ -3037,9 +3034,6 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
else
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
/*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/
BE_SelectMode(BEM_DEPTHONLY);

View file

@ -3467,10 +3467,10 @@ void GLBE_Scissor(srect_t *rect)
{
qglScissor(
floor(r_refdef.pxrect.x + rect->x*r_refdef.pxrect.width),
floor((r_refdef.pxrect.y + rect->y*r_refdef.pxrect.height) - r_refdef.pxrect.maxheight),
floor(r_refdef.pxrect.y + rect->y*r_refdef.pxrect.height),// - r_refdef.pxrect.maxheight),
ceil(rect->width * r_refdef.pxrect.width),
ceil(rect->height * r_refdef.pxrect.height));
// qglEnable(GL_SCISSOR_TEST);
qglEnable(GL_SCISSOR_TEST);
if (qglDepthBoundsEXT)
{
@ -4115,9 +4115,6 @@ static void GLBE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
// else
// batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
/*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/
GLBE_SelectMode(BEM_DEPTHONLY);
@ -4200,6 +4197,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
if ((batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME)
{
float oldil;
int oldbem;
//these flags require rendering some view as an fbo
if (r_refdef.recurse)
@ -4207,6 +4205,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
if (shaderstate.mode != BEM_STANDARD && shaderstate.mode != BEM_DEPTHDARK)
continue;
oldbem = shaderstate.mode;
oldil = shaderstate.identitylighting;
if ((batch->shader->flags & SHADER_HASREFLECT) && gl_config.ext_framebuffer_objects)
{
@ -4344,6 +4343,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
GL_ViewportUpdate();
}
BE_SelectMode(oldbem);
shaderstate.identitylighting = oldil;
}
GLBE_SubmitBatch(batch);

View file

@ -89,7 +89,7 @@ void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void
texid_t GL_LoadTextureFmt (char *name, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags)
{
extern cvar_t r_shadow_bumpscale_basetexture;
extern cvar_t r_shadow_bumpscale_basetexture, r_shadow_bumpscale_bumpmap;
switch(fmt)
{
case TF_INVALID:
@ -117,8 +117,9 @@ texid_t GL_LoadTextureFmt (char *name, int width, int height, enum uploadfmt fmt
return GL_LoadTexture(name, width, height, data, flags, 4);
case TF_HEIGHT8PAL:
case TF_HEIGHT8:
return GL_LoadTexture8Bump(name, width, height, data, flags, r_shadow_bumpscale_basetexture.value);
case TF_HEIGHT8:
return GL_LoadTexture8Bump(name, width, height, data, flags, r_shadow_bumpscale_bumpmap.value);
default:
Sys_Error("Unsupported image format type\n");

View file

@ -2601,7 +2601,10 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
if (!sm->batches[tno].count)
continue;
tex = cl.worldmodel->shadowbatches[tno].tex;
shader = R_TextureAnimation(false, tex)->shader;
if (cl.worldmodel->fromgame == fg_quake2)
shader = R_TextureAnimation_Q2(tex)->shader;
else
shader = R_TextureAnimation(false, tex)->shader;
if (shader->flags & SHADER_NODLIGHT)
continue;
//FIXME: it may be worth building a dedicated ebo
@ -3248,9 +3251,9 @@ void Sh_PreGenerateLights(void)
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
{
if (rtlights_first == rtlights_max)
if (RTL_FIRST == rtlights_max)
R_LoadRTLights();
if (rtlights_first == rtlights_max)
if (RTL_FIRST == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
}

View file

@ -342,17 +342,11 @@ reeval:
ptr->_int = (int)OPA->_float;
break;
case OP_STOREP_I:
case OP_GSTOREP_I:
case OP_STOREP_F:
case OP_GSTOREP_F:
case OP_STOREP_ENT:
case OP_GSTOREP_ENT:
case OP_STOREP_FLD: // integers
case OP_GSTOREP_FLD:
case OP_STOREP_S:
case OP_GSTOREP_S:
case OP_STOREP_FNC: // pointers
case OP_GSTOREP_FNC:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
@ -362,11 +356,10 @@ reeval:
ptr->_int = OPA->_int;
break;
case OP_STOREP_V:
case OP_GSTOREP_V:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
ptr->_vector[0] = OPA->_vector[0];
@ -378,7 +371,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
*(unsigned char *)ptr = (char)OPA->_float;
@ -397,7 +390,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_float = (ptr->_float *= OPA->_float);
@ -406,7 +399,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
tmpf = OPA->_float;
ptr = QCPOINTER(OPB);
@ -422,7 +415,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_float = (ptr->_float /= OPA->_float);
@ -440,7 +433,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_float = (ptr->_float += OPA->_float);
@ -449,7 +442,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]);
@ -469,7 +462,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_float = (ptr->_float -= OPA->_float);
@ -478,7 +471,7 @@ reeval:
if (QCPOINTERWRITEFAIL(OPB))
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = QCPOINTER(OPB);
OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]);
@ -664,6 +657,7 @@ reeval:
PR_SwitchProgsParms(progfuncs, callerprogs);
//break/skip the instruction.
PR_StackTrace(&progfuncs->funcs);
printf(msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
#ifndef DEBUGABLE
progfuncs->funcs.pr_trace++;
@ -1168,14 +1162,61 @@ reeval:
break;
case OP_GADDRESS: //return glob[aint+bfloat]
//this instruction is not implemented due to the weirdness of it.
//its theoretically a more powerful load... but untyped?
//or is it meant to be an LEA instruction (that could simply be switched with
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "OP_GADDRESS not implemented (found in %s)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name));
break;
case OP_GLOAD_I:
case OP_GLOAD_F:
case OP_GLOAD_FLD:
case OP_GLOAD_ENT:
case OP_GLOAD_S:
case OP_GLOAD_FNC:
pr_xstatement = st-pr_statements;
PR_RunError(&progfuncs->funcs, "Extra opcode not implemented\n");
if (OPA->_int < 0 || OPA->_int*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = ((eval_t *)&glob[OPA->_int]);
OPC->_int = ptr->_int;
break;
case OP_GLOAD_V:
if (OPA->_int < 0 || (OPA->_int+2)*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = ((eval_t *)&glob[OPA->_int]);
OPC->_vector[0] = ptr->_vector[0];
OPC->_vector[1] = ptr->_vector[1];
OPC->_vector[2] = ptr->_vector[2];
break;
case OP_GSTOREP_I:
case OP_GSTOREP_F:
case OP_GSTOREP_ENT:
case OP_GSTOREP_FLD:
case OP_GSTOREP_S:
case OP_GSTOREP_FNC:
if (OPB->_int < 0 || OPB->_int*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = ((eval_t *)&glob[OPB->_int]);
ptr->_int = OPA->_int;
break;
case OP_GSTOREP_V:
if (OPB->_int < 0 || (OPB->_int+2)*4 >= current_progstate->globals_size)
{
pr_xstatement = st-pr_statements;
PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, prinst.addressableused);
}
ptr = ((eval_t *)&glob[OPB->_int]);
ptr->_vector[0] = OPA->_vector[0];
ptr->_vector[1] = OPA->_vector[1];
ptr->_vector[2] = OPA->_vector[2];
break;
case OP_BOUNDCHECK:

View file

@ -9551,11 +9551,11 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"pointparticles", PF_sv_pointparticles,0, 0, 0, 337, D("void(float effectnum, vector origin, optional vector dir, optional float count)", "Spawn a load of particles from the given effect at the given point traveling or aiming along the direction specified. The number of particles are scaled by the count argument.")},// (EXT_CSQC)
{"cprint", PF_Fixme, 0, 0, 0, 338, D("void(string s, ...)", "Print into the center of the screen just as ssqc's centerprint would appear.")},//(EXT_CSQC)
{"print", PF_print, 0, 0, 0, 339, D("void(string s, ...)", "Unambiguously print on the local system's console, even in ssqc (doesn't care about the value of the developer cvar).")},//(EXT_CSQC)
{"print", PF_print, 0, 0, 0, 339, D("void(string s, ...)", "Unconditionally print on the local system's console, even in ssqc (doesn't care about the value of the developer cvar).")},//(EXT_CSQC)
{"keynumtostring", PF_Fixme, 0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (EXT_CSQC)
{"keynumtostring_csqc", PF_Fixme, 0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (found in menuqc)
{"keynumtostring_csqc",PF_Fixme,0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (found in menuqc)
{"stringtokeynum", PF_Fixme, 0, 0, 0, 341, D("float(string keyname)", "Looks up the key name in the same way that the bind command would, returning the keycode for that key.")},// (EXT_CSQC)
{"getkeybind", PF_Fixme, 0, 0, 0, 342, D("string(float keynum)", "Finds the current binding for the given key (ignores modifiers like shift/alt/ctrl).")},// (EXT_CSQC)

View file

@ -549,7 +549,7 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
#ifdef Q2SERVER
if (gametype == GT_QUAKE2)
{
char syspath[MAX_OSPATH];
flocation_t loc;
SV_SpawnServer (level, startspot, false, false);
World_ClearWorld(&sv.world);
@ -559,10 +559,17 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
return false;
}
if (!FS_NativePath(name, FS_GAME, syspath, sizeof(syspath)))
if (!FS_FLocateFile(name, FSLFRT_IFFOUND, &loc))
{
Con_Printf("Couldn't find %s.\n", name);
return false;
ge->ReadLevel(syspath);
}
if (!*loc.rawname || loc.offset)
{
Con_Printf("%s is inside a package and cannot be used by the quake2 gamecode.\n", name);
return false;
}
ge->ReadLevel(loc.rawname);
for (i=0 ; i<100 ; i++) //run for 10 secs to iron out a few bugs.
ge->RunFrame ();
@ -1068,6 +1075,18 @@ void SV_Savegame (char *savename)
VFS_PRINTF (f, "%s\n", sv.name);
VFS_CLOSE(f);
#ifdef Q2SERVER
//save the player's inventory and other map-persistant state that is owned by the gamecode.
if (ge)
{
char syspath[256];
if (!FS_NativePath(va("saves/%s/game.gsv", savename), FS_GAMEONLY, syspath, sizeof(syspath)))
return;
ge->WriteGame(syspath, false);
FS_FlushFSHashReally();
}
#endif
}
void SV_Savegame_f (void)
@ -1264,6 +1283,24 @@ void SV_Loadgame_f (void)
VFS_CLOSE(f);
#ifdef Q2SERVER
if (gametype == GT_QUAKE2)
{
flocation_t loc;
char *name = va("saves/%s/game.gsv", savename);
if (!FS_FLocateFile(name, FSLFRT_IFFOUND, &loc))
Con_Printf("Couldn't find %s.\n", name);
else if (!*loc.rawname || loc.offset)
Con_Printf("%s is inside a package and cannot be used by the quake2 gamecode.\n", name);
else
{
SVQ2_InitGameProgs();
if (ge)
ge->ReadGame(loc.rawname);
}
}
#endif
svs.gametype = gametype;
SV_LoadLevelCache(savename, str, "", true);
sv.allocated_client_slots = slots;

View file

@ -724,7 +724,7 @@ qboolean SVQ2_InitGameProgs(void)
}
// unload anything we have now
if (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife) //we don't support q1 or hl maps yet... If ever.
if (sv.world.worldmodel && (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife)) //we don't support q1 or hl maps yet... If ever.
{
SVQ2_ShutdownGameProgs();
return false;
@ -790,7 +790,7 @@ qboolean SVQ2_InitGameProgs(void)
import.SetAreaPortalState = CMQ2_SetAreaPortalState;
import.AreasConnected = PFQ2_AreasConnected;
if (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife)
if (sv.world.worldmodel && (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife))
{
return false;
/*

View file

@ -1709,6 +1709,13 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
else
clip.hitcontentsmask = MASK_POINTSOLID; /*ignores playerclip but hits everything else*/
if (type & MOVE_ONLYENT)
{
if (!passedict)
passedict = w->edicts;
return World_ClipMoveToEntity (w, passedict, passedict->v->origin, start, mins, maxs, end, hullnum, clip.type & MOVE_HITMODEL, clip.hitcontentsmask);
}
// clip to world
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false, clip.hitcontentsmask);

View file

@ -495,8 +495,6 @@ static void SWBE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
else if (batch->texture)
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
if (batch->shader->flags & SHADER_NODRAW)
continue;