diff --git a/engine/Makefile b/engine/Makefile index 015f159e..96860d9f 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -356,7 +356,7 @@ PROFILE_CFLAGS=-pg DX7SDK=-I./libs/dxsdk7/include/ GLCFLAGS=-DGLQUAKE -D3DCFLAGS=-DD3D9QUAKE -DD3D11QUAKE +D3DCFLAGS=-DD3D9QUAKE NPFTECFLAGS=-DNPFTE SPEEXCFLAGS=-DSPEEX_STATIC -I$(BASE_DIR)/libs/speex/include -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" @@ -780,7 +780,7 @@ ifeq ($(FTE_TARGET),vc) RELEASE_LDFLAGS = /LTCG:PGOPTIMIZE DO_CC=@$(CC) /nologo $(ALL_CFLAGS) -Fo$@ -c $< - DO_LD=@"$(MSVCPATH)link" /nologo /out:"$@" /nodefaultlib:libc.lib /nodefaultlib:MSVCRT $(MSVCLIB) /manifest:no /OPT:REF wsock32.lib user32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib + DO_LD=@"$(MSVCPATH)link" /nologo /out:"$@" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) /manifest:no /OPT:REF wsock32.lib user32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib PRECOMPHEADERS = NODEPS = 1 @@ -804,6 +804,9 @@ ifeq ($(FTE_TARGET),vc) GLCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SPEEX_OBJS) gl_vidnt.o snd_win.o snd_directx.o cd_win.o fs_win32.o in_win.o sys_win.o sys_win_threads.o resources.o GL_OBJS= + MINGL_DIR=mingl_vc$(BITS) + MINGL_EXE_NAME=../fteminglqw$(BITS).exe + D3DCL_OBJS=$(D3DQUAKE_OBJS) $(SPEEX_OBJS) snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o sys_win_threads.o $(D3DGL_OBJS) fs_win32.o $(LTO_END) resources.o $(LTO_START) D3D_EXE_NAME=../fted3dqw$(BITS).exe D3DCL_EXE_NAME=../fted3dclqw$(BITS).exe diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index 295297fc..e4d82c8f 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -571,22 +571,25 @@ void Cam_FinishMove(int pnum, usercmd_t *cmd) nb |= (cmd->forwardmove>0)?32:0; nb |= (cmd->upmove<0)?64:0; nb |= (cmd->upmove>0)?128:0; - if (nb & (nb ^ oldbuttons[pnum]) & 4) - Cvar_SetValue(&cl_demospeed, max(cl_demospeed.value - 0.1, 0)); - if (nb & (nb ^ oldbuttons[pnum]) & 8) - Cvar_SetValue(&cl_demospeed, min(cl_demospeed.value + 0.1, 10)); - if (nb & (nb ^ oldbuttons[pnum]) & (4|8)) - Con_Printf("playback speed: %g%%\n", cl_demospeed.value*100); - if (nb & (nb ^ oldbuttons[pnum]) & 16) - Cbuf_AddText("demo_jump +10", RESTRICT_LOCAL); - if (nb & (nb ^ oldbuttons[pnum]) & 32) - Cbuf_AddText("demo_jump -10", RESTRICT_LOCAL); - if (nb & (nb ^ oldbuttons[pnum]) & (4|8)) - Con_Printf("playback speed: %g%%\n", cl_demospeed.value*100); - if (nb & (nb ^ oldbuttons[pnum]) & 64) - Cvar_SetValue(&cl_splitscreen, max(cl_splitscreen.ival - 1, 0)); - if (nb & (nb ^ oldbuttons[pnum]) & 128) - Cvar_SetValue(&cl_splitscreen, min(cl_splitscreen.ival + 1, MAX_SPLITS-1)); + if (Cam_TrackNum(pnum) >= 0) + { + if (nb & (nb ^ oldbuttons[pnum]) & 4) + Cvar_SetValue(&cl_demospeed, max(cl_demospeed.value - 0.1, 0)); + if (nb & (nb ^ oldbuttons[pnum]) & 8) + Cvar_SetValue(&cl_demospeed, min(cl_demospeed.value + 0.1, 10)); + if (nb & (nb ^ oldbuttons[pnum]) & (4|8)) + Con_Printf("playback speed: %g%%\n", cl_demospeed.value*100); + if (nb & (nb ^ oldbuttons[pnum]) & 16) + Cbuf_AddText("demo_jump +10", RESTRICT_LOCAL); + if (nb & (nb ^ oldbuttons[pnum]) & 32) + Cbuf_AddText("demo_jump -10", RESTRICT_LOCAL); + if (nb & (nb ^ oldbuttons[pnum]) & (4|8)) + Con_Printf("playback speed: %g%%\n", cl_demospeed.value*100); + if (nb & (nb ^ oldbuttons[pnum]) & 64) + Cvar_SetValue(&cl_splitscreen, max(cl_splitscreen.ival - 1, 0)); + if (nb & (nb ^ oldbuttons[pnum]) & 128) + Cvar_SetValue(&cl_splitscreen, min(cl_splitscreen.ival + 1, MAX_SPLITS-1)); + } oldbuttons[pnum] = (oldbuttons[pnum] & 3) | (nb & ~3); if (cmd->impulse) { diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index 6d0170ba..bc64a08f 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -784,10 +784,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case CG_R_CLEARSCENE: //clear scene (not rtlights, only dynamic ones) - cl_numvisedicts = 0; - cl_numstrisidx = 0; - cl_numstrisvert = 0; - cl_numstris = 0; + CL_ClearEntityLists(); rtlights_first = RTL_FIRST; break; case CG_R_ADDPOLYTOSCENE: diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 588559ff..af31e3a5 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -72,6 +72,7 @@ void CL_StopPlayback (void) cls.demoinfile = NULL; cls.state = ca_disconnected; cls.demoplayback = DPB_NONE; + cls.demoseeking = false; //just in case if (cls.timedemo) CL_FinishTimeDemo (); @@ -310,7 +311,7 @@ void CL_ProgressDemoTime(void) return; } - if (cl_demospeed.value >= 0) + if (cl_demospeed.value >= 0 && cls.state == ca_active) demtime += host_frametime*cl_demospeed.value; else demtime += host_frametime; @@ -347,17 +348,20 @@ void CL_DemoJump_f(void) else newtime = atoi(s); } + if (newtime < 0) + newtime = 0; if (newtime >= demtime) - demtime = newtime; + cls.demoseektime = newtime; else { Con_Printf("Rewinding demo\n"); CL_PlayDemo(lastdemoname); //now fastparse it. - demtime = newtime; + cls.demoseektime = newtime; } + cls.demoseeking = true; } /* @@ -544,7 +548,13 @@ readnext: // decide if it is time to grab the next message - if (cls.timedemo) + if (cls.demoseeking) + { + demtime = demotime; //warp + if (demtime >= cls.demoseektime) + cls.demoseeking = false; + } + else if (cls.timedemo) { if (cls.td_lastframe < 0) cls.td_lastframe = demotime; @@ -1226,7 +1236,7 @@ void CL_Record_f (void) if (memcmp(es, &nullentitystate, sizeof(nullentitystate))) { MSG_WriteByte (&buf,svc_spawnbaseline); - MSG_WriteShort (&buf, i); + MSG_WriteEntity (&buf, i); MSG_WriteByte (&buf, es->modelindex); MSG_WriteByte (&buf, es->frame); diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index a0e5fa12..ca8e6fe8 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -94,9 +94,10 @@ void CL_FreeDlights(void) { #ifdef RTLIGHTS int i; - for (i = 0; i < rtlights_max; i++) - if (cl_dlights[i].worldshadowmesh) - SH_FreeShadowMesh(cl_dlights[i].worldshadowmesh); + if (cl_dlights) + for (i = 0; i < rtlights_max; i++) + if (cl_dlights[i].worldshadowmesh) + SH_FreeShadowMesh(cl_dlights[i].worldshadowmesh); #endif rtlights_max = cl_maxdlights = 0; @@ -422,11 +423,6 @@ void CLQW_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboole i = MSG_ReadByte(); to->dpflags = i; - to->flags = 0; - if (i & RENDER_VIEWMODEL) - to->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; - if (i & RENDER_EXTERIORMODEL) - to->flags |= Q2RF_EXTERNALMODEL; } if (!(cls.fteprotocolextensions & PEXT_DPFLAGS)) { @@ -649,7 +645,7 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t * news->hexen2flags = MSG_ReadByte(); if (bits & UF_TAGINFO) { - news->tagentity = MSG_ReadShort(); + news->tagentity = MSGCL_ReadEntity(); news->tagindex = MSG_ReadByte(); } if (bits & UF_LIGHT) @@ -670,8 +666,10 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t * news->colormod[1] = MSG_ReadByte(); news->colormod[2] = MSG_ReadByte(); } - if (bits & UF_GLOWMOD) + if (bits & UF_GLOW) { + news->glowsize = MSG_ReadByte(); + news->glowcolour = MSG_ReadByte(); news->glowmod[0] = MSG_ReadByte(); news->glowmod[1] = MSG_ReadByte(); news->glowmod[2] = MSG_ReadByte(); @@ -696,7 +694,7 @@ void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant) { int entnum = 0; if (numberisimportant) - entnum = MSG_ReadShort(); + entnum = MSGCL_ReadEntity(); CLFTE_ReadDelta(entnum, es, &nullentitystate, &nullentitystate); } @@ -708,10 +706,11 @@ void CLFTE_ParseEntities(void) { int oldpacket, newpacket; packet_entities_t *oldp, *newp, nullp; - unsigned short newnum, oldnum; + unsigned int newnum, oldnum; int oldindex; qboolean isvalid = false; entity_state_t *e; + qboolean removeflag; // int i; // for (i = cl.validsequence+1; i < cls.netchan.incoming_sequence; i++) @@ -747,8 +746,15 @@ void CLFTE_ParseEntities(void) oldindex = 0; while(1) { - newnum = MSG_ReadShort(); - if (!newnum || msg_badread) + //high bit means remove, second high bit means 22bit index + newnum = (unsigned short)(short)MSG_ReadShort(); + removeflag = !!(newnum & 0x8000); + if (newnum & 0x4000) + newnum = (newnum & 0x3fff) | (MSG_ReadByte()<<14); + else + newnum &= ~0x8000; + + if ((!newnum && !removeflag) || msg_badread) { /*reached the end, don't forget old entities*/ while(oldindex < oldp->num_entities) @@ -762,20 +768,11 @@ void CLFTE_ParseEntities(void) } break; } - if (newnum == 0x8000) - { - /*removal of world - means forget all entities*/ - if (cl_shownet.ival >= 3) - Con_Printf("%3i: Reset all\n", msg_readcount); - newp->num_entities = 0; - isvalid = true; - continue; - } - oldnum = oldindex >= oldp->num_entities ? 0xffff : oldp->entities[oldindex].number; + oldnum = (oldindex >= oldp->num_entities) ? 0xffffffff : oldp->entities[oldindex].number; /*if we skipped some, then they were unchanged*/ - while ((newnum&0x7fff) > oldnum) + while (newnum > oldnum) { if (newp->num_entities >= newp->max_entities) { @@ -784,14 +781,25 @@ void CLFTE_ParseEntities(void) } newp->entities[newp->num_entities++] = oldp->entities[oldindex++]; - oldnum = oldindex >= oldp->num_entities ? 0xffff : oldp->entities[oldindex].number; + oldnum = (oldindex >= oldp->num_entities) ? 0xffffffff : oldp->entities[oldindex].number; } - if (newnum & 0x8000) + if (removeflag) { if (cl_shownet.ival >= 3) - Con_Printf("%3i: Remove %i @ %i\n", msg_readcount, (newnum&32767), cls.netchan.incoming_sequence); - if (oldnum == (newnum&0x7fff)) + Con_Printf("%3i: Remove %i @ %i\n", msg_readcount, newnum, cls.netchan.incoming_sequence); + + if (!newnum) + { + /*removal of world - means forget all entities*/ + if (cl_shownet.ival >= 3) + Con_Printf("%3i: Reset all\n", msg_readcount); + newp->num_entities = 0; + isvalid = true; + continue; + } + + if (oldnum == newnum) oldindex++; continue; } @@ -853,7 +861,7 @@ An svc_packetentities has just been parsed, deal with the rest of the data stream. ================== */ -void CL_ParsePacketEntities (qboolean delta) +void CLQW_ParsePacketEntities (qboolean delta) { int oldpacket, newpacket; packet_entities_t *oldp, *newp, dummy; @@ -1130,11 +1138,6 @@ void DP5_ParseDelta(entity_state_t *s) { int i = MSG_ReadByte(); s->dpflags = i; - s->flags = 0; - if (i & RENDER_VIEWMODEL) - s->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; - if (i & RENDER_EXTERIORMODEL) - s->flags |= Q2RF_EXTERNALMODEL; } if (bits & E5_ORIGIN) { @@ -1199,7 +1202,7 @@ void DP5_ParseDelta(entity_state_t *s) s->colormap = MSG_ReadByte(); if (bits & E5_ATTACHMENT) { - s->tagentity = MSG_ReadShort(); + s->tagentity = MSGCL_ReadEntity(); s->tagindex = MSG_ReadByte(); } if (bits & E5_LIGHT) @@ -1278,7 +1281,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( if (read == oldpack.entities[oldi].number) { from = &oldpack.entities[oldi]; - from->flags |= 0x80000000; //so we don't copy it. + from->inactiveflag |= 1; //so we don't copy it. break; } } @@ -1300,7 +1303,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( memcpy(to, from, sizeof(*to)); to->number = read; DP5_ParseDelta(to); - to->flags &= ~0x80000000; + to->inactiveflag &= ~1; } /*we're writing into the old one, clear it out prematurely (to make the malloc below trigger, and free it at the end)*/ @@ -1324,7 +1327,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( else { from = &oldpack.entities[oldi]; - if (from->flags & 0x80000000) + if (from->inactiveflag & 1) { oldi++; continue; @@ -1336,7 +1339,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( lowestv = 0x7ffffffe; for(newi = 0; newi < newpack.num_entities; newi++) { - if (newpack.entities[newi].flags & 0x80000000) + if (newpack.entities[newi].inactiveflag & 1) continue; if (newpack.entities[newi].number < lowestv) { @@ -1350,7 +1353,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( if (!from || (from->number > lowestv && lowestv)) { from = &newpack.entities[lowesti]; - from->flags |= 0x80000000; + from->inactiveflag |= 1; lowestv = 0; /*find the next oldest*/ newremaining--; } @@ -1360,7 +1363,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( to = &pack->entities[pack->num_entities]; pack->num_entities++; memcpy(to, from, sizeof(*to)); - to->flags &= ~0x80000000; + to->inactiveflag &= ~1; } BZ_Free(oldpack.entities); @@ -1400,7 +1403,7 @@ void CLNQ_ParseEntity(unsigned int bits) } if (bits & NQU_LONGENTITY) - num = MSG_ReadShort (); + num = MSGCL_ReadEntity (); else num = MSG_ReadByte (); @@ -1696,9 +1699,8 @@ void V_AddAxisEntity(entity_t *in) { entity_t *ent; - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) { - Con_DPrintf("Visedict list is full!\n"); return; // object list is full } ent = &cl_visedicts[cl_numvisedicts]; @@ -1706,13 +1708,20 @@ void V_AddAxisEntity(entity_t *in) *ent = *in; } +void V_ClearEntity(entity_t *e) +{ + memset(e, 0, sizeof(*e)); + e->playerindex = -1; + e->topcolour = TOP_DEFAULT; + e->bottomcolour = BOTTOM_DEFAULT; + e->h2playerclass = 0; +} entity_t *V_AddEntity(entity_t *in) { entity_t *ent; - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) { - Con_DPrintf("Visedict list is full!\n"); return NULL; // object list is full } ent = &cl_visedicts[cl_numvisedicts]; @@ -1761,18 +1770,24 @@ int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float return CL_NewDlightRGB (entsource, org, quant, -0.1, r, g, b) - cl_dlights; } -static void CLQ1_AddCube(shader_t *shader, vec3_t mins, vec3_t maxs, float r, float g, float b, float a) +void CLQ1_AddOrientedHalfSphere(shader_t *shader, float radius, float gap, float *matrix, float r, float g, float b, float a) { - int v; + //use simple algo + //a series of cylinders that gets progressively narrower + int latsteps = 16; + int lngsteps = 16; + float cradius; + int v, i, j; scenetris_t *t; + vec3_t corner; + float x,y; + int flags = BEF_NODLIGHT|BEF_NOSHADOWS; if (!r && !g && !b) return; - if (g && !b) - b = 0; /*reuse the previous trigroup if its the same shader*/ - if (cl_numstris && cl_stris[cl_numstris-1].shader == shader) + if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags) t = &cl_stris[cl_numstris-1]; else { @@ -1787,12 +1802,297 @@ static void CLQ1_AddCube(shader_t *shader, vec3_t mins, vec3_t maxs, float r, fl t->numvert = 0; t->firstidx = cl_numstrisidx; t->firstvert = cl_numstrisvert; + t->flags = flags; + } + + if (cl_numstrisvert + latsteps*lngsteps > cl_maxstrisvert) + { + cl_maxstrisvert = cl_numstrisvert + latsteps*lngsteps; + + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+latsteps*(lngsteps-1)*6) + { + cl_maxstrisidx = cl_numstrisidx+latsteps*(lngsteps-1)*6 + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + for (i = 0; i < latsteps; i++) + { + x = sin(i * 2 * M_PI / latsteps); + y = cos(i * 2 * M_PI / latsteps); + for (j = 0; j < lngsteps; j++) + { + v = i*lngsteps + j; + cradius = sin(j * 0.5 * M_PI / (lngsteps-1))*radius; + corner[0] = x*cradius; + corner[1] = y*cradius; + corner[2] = (cos(j * 0.5 * M_PI / (lngsteps-1))*-radius) - gap; + Matrix3x4_RM_Transform3(matrix, corner, cl_strisvertv[cl_numstrisvert+v]); + + cl_strisvertt[cl_numstrisvert+v][0] = 0; + cl_strisvertt[cl_numstrisvert+v][1] = 0; + + cl_strisvertc[cl_numstrisvert+v][0] = r; + cl_strisvertc[cl_numstrisvert+v][1] = g; + cl_strisvertc[cl_numstrisvert+v][2] = b; + cl_strisvertc[cl_numstrisvert+v][3] = a; + } + } + + if (radius < 0) + { + for (i = 0; i < lngsteps-1; i++) + { + v = latsteps-1; + for (v = 0; v < latsteps-1; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + } + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + } + } + else + { + for (i = 0; i < lngsteps-1; i++) + { + v = latsteps-1; + for (v = 0; v < latsteps-1; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+lngsteps+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + } + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + i; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*lngsteps + i; + } + } + + t->numvert += lngsteps*latsteps; + t->numidx = cl_numstrisidx - t->firstidx; + cl_numstrisvert += lngsteps*latsteps; +} + +void CLQ1_AddOrientedCylinder(shader_t *shader, float radius, float height, qboolean capsule, float *matrix, float r, float g, float b, float a) +{ + int sides = 16; + int v; + scenetris_t *t; + vec3_t corner; + int flags = BEF_NODLIGHT|BEF_NOSHADOWS; + + if (!r && !g && !b) + return; + + radius *= 0.5; + height *= 0.5; + + if (capsule) + height -= radius; + + if (height > 0) + { + /*reuse the previous trigroup if its the same shader*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = shader; + t->numidx = 0; + t->numvert = 0; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + t->flags = flags; + } + + if (cl_numstrisvert + sides*2 > cl_maxstrisvert) + { + cl_maxstrisvert = cl_numstrisvert + sides*2; + + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+sides*6) + { + cl_maxstrisidx = cl_numstrisidx+sides*6 + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + + for (v = 0; v < sides*2; v++) + { + corner[0] = sin((v>>1) * 2 * M_PI / sides)*radius; + corner[1] = cos((v>>1) * 2 * M_PI / sides)*radius; + corner[2] = (v & 1)?height:-height; + Matrix3x4_RM_Transform3(matrix, corner, cl_strisvertv[cl_numstrisvert+v]); + + cl_strisvertt[cl_numstrisvert+v][0] = 0; + cl_strisvertt[cl_numstrisvert+v][1] = 0; + + cl_strisvertc[cl_numstrisvert+v][0] = r; + cl_strisvertc[cl_numstrisvert+v][1] = g; + cl_strisvertc[cl_numstrisvert+v][2] = b; + cl_strisvertc[cl_numstrisvert+v][3] = a; + } + for (v = 0; v < sides-1; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 + v*2; + } + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 + v*2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; + + if (!capsule) + { + for (v = 4; v < sides*2; v+=2) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+(v-2); + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; + + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+(v-2)+1; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v+1; + } + } + + t->numvert += sides*2; + t->numidx = cl_numstrisidx - t->firstidx; + cl_numstrisvert += sides*2; + } + + if (capsule) + { + CLQ1_AddOrientedHalfSphere(shader, radius, height, matrix, r, g, b, a); + CLQ1_AddOrientedHalfSphere(shader, -radius, -height, matrix, r, g, b, a); + } +} +void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, float b, float a) +{ + scenetris_t *t; + int flags = BEF_NODLIGHT|BEF_NOSHADOWS|BEF_LINES; + + if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = shader; + t->numidx = 0; + t->numvert = 0; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + t->flags = flags; + } + if (cl_numstrisvert + 2 > cl_maxstrisvert) + { + cl_maxstrisvert = cl_numstrisvert + 2; + + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+2) + { + cl_maxstrisidx = cl_numstrisidx+2; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + VectorCopy(v1, cl_strisvertv[cl_numstrisvert+0]); + cl_strisvertt[cl_numstrisvert+0][0] = 0; + cl_strisvertt[cl_numstrisvert+0][1] = 0; + cl_strisvertc[cl_numstrisvert+0][0] = r; + cl_strisvertc[cl_numstrisvert+0][1] = g; + cl_strisvertc[cl_numstrisvert+0][2] = b; + cl_strisvertc[cl_numstrisvert+0][3] = a; + + VectorCopy(v2, cl_strisvertv[cl_numstrisvert+1]); + cl_strisvertt[cl_numstrisvert+1][0] = 0; + cl_strisvertt[cl_numstrisvert+1][1] = 0; + cl_strisvertc[cl_numstrisvert+1][0] = r; + cl_strisvertc[cl_numstrisvert+1][1] = g; + cl_strisvertc[cl_numstrisvert+1][2] = b; + cl_strisvertc[cl_numstrisvert+1][3] = a; + + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert-t->firstvert+0; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert-t->firstvert+1; + + t->numvert += 2; + t->numidx = cl_numstrisidx - t->firstidx; + cl_numstrisvert += 2; +} +void CLQ1_AddOrientedCube(shader_t *shader, vec3_t mins, vec3_t maxs, float *matrix, float r, float g, float b, float a) +{ + int v; + scenetris_t *t; + vec3_t corner; + int flags = BEF_NODLIGHT|BEF_NOSHADOWS; + + if (!r && !g && !b) + return; + + /*reuse the previous trigroup if its the same shader*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags && cl_stris[cl_numstris-1].numvert + 8 <= MAX_INDICIES) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = shader; + t->numidx = 0; + t->numvert = 0; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + t->flags = flags; } if (cl_numstrisvert + 8 > cl_maxstrisvert) { - cl_maxstrisvert = cl_numstrisvert + 8; + cl_maxstrisvert = cl_numstrisvert + 8 + 1024; cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); @@ -1800,16 +2100,20 @@ static void CLQ1_AddCube(shader_t *shader, vec3_t mins, vec3_t maxs, float r, fl } if (cl_maxstrisidx < cl_numstrisidx+6*6) { - cl_maxstrisidx = cl_numstrisidx+6*6 + 64; + cl_maxstrisidx = cl_numstrisidx + 6*6 + 1024; cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); } for (v = 0; v < 8; v++) { - cl_strisvertv[cl_numstrisvert+v][0] = (v & 1)?mins[0]:maxs[0]; - cl_strisvertv[cl_numstrisvert+v][1] = (v & 2)?mins[1]:maxs[1]; - cl_strisvertv[cl_numstrisvert+v][2] = (v & 4)?mins[2]:maxs[2]; + corner[0] = (v & 1)?mins[0]:maxs[0]; + corner[1] = (v & 2)?mins[1]:maxs[1]; + corner[2] = (v & 4)?mins[2]:maxs[2]; + if (matrix) + Matrix3x4_RM_Transform3(matrix, corner, cl_strisvertv[cl_numstrisvert+v]); + else + VectorCopy(corner, cl_strisvertv[cl_numstrisvert+v]); cl_strisvertt[cl_numstrisvert+v][0] = 0; cl_strisvertt[cl_numstrisvert+v][1] = 0; @@ -1821,52 +2125,52 @@ static void CLQ1_AddCube(shader_t *shader, vec3_t mins, vec3_t maxs, float r, fl } /*top*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; /*bottom*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7 - t->firstvert; /*'left'*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 - t->firstvert; /*right*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3 - t->firstvert; /*urm, the other way*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+6 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+4 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+2 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+0 - t->firstvert; /*and its oposite*/ - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3; - cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+7 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+1 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+3 - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+5 - t->firstvert; t->numvert += 8; t->numidx = cl_numstrisidx - t->firstidx; @@ -1935,7 +2239,7 @@ void CLQ1_AddVisibleBBoxes(void) mod = cl.model_precache[state->modelindex]; VectorAdd(state->origin, mod->mins, min); VectorAdd(state->origin, mod->maxs, max); - CLQ1_AddCube(s, min, max, 0.1, 0, 0, 1); + CLQ1_AddOrientedCube(s, min, max, NULL, 0.1, 0, 0, 1); } } else @@ -1947,7 +2251,7 @@ void CLQ1_AddVisibleBBoxes(void) max[2] = 8*((state->solid>>10) & 63) - 32; VectorAdd(state->origin, min, min); VectorAdd(state->origin, max, max); - CLQ1_AddCube(s, min, max, 0.1, 0, 0, 1); + CLQ1_AddOrientedCube(s, min, max, NULL, 0.1, 0, 0, 1); } } } @@ -2002,10 +2306,99 @@ void CLQ1_AddVisibleBBoxes(void) VectorCopy(e->v->absmin, min); VectorCopy(e->v->absmax, max); } - CLQ1_AddCube(s, min, max, (e->v->solid || e->v->movetype)?0.1:0, (e->v->movetype == MOVETYPE_STEP || e->v->movetype == MOVETYPE_TOSS || e->v->movetype == MOVETYPE_BOUNCE)?0.1:0, ((int)e->v->flags & (FL_ONGROUND | ((e->v->movetype == MOVETYPE_STEP)?FL_FLY:0)))?0.1:0, 1); + CLQ1_AddOrientedCube(s, min, max, NULL, (e->v->solid || e->v->movetype)?0.1:0, (e->v->movetype == MOVETYPE_STEP || e->v->movetype == MOVETYPE_TOSS || e->v->movetype == MOVETYPE_BOUNCE)?0.1:0, ((int)e->v->flags & (FL_ONGROUND | ((e->v->movetype == MOVETYPE_STEP)?FL_FLY:0)))?0.1:0, 1); } } +void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t rgbvalue, float alphavalue) +{ + int num, v; + vec3_t tang; + float radius = 1; + float *verts; + float tx, ty, tz; + scenetris_t *t; + float l, s; + + VectorNegate(up, up); + CrossProduct(up, side, tang); + + s = sqrt(DotProduct(side, side)); + l = sqrt(DotProduct(tang, tang)); + + VectorScale(tang, s/l, tang); + + num = Q1BSP_ClipDecal(origin, up, side, tang, 2, &verts); + + if (!num) + return; + num*=3; + + VectorScale(tang, 0.5/(s*s), tang); + VectorScale(side, 0.5/(s*s), side); + l = sqrt(DotProduct(up, up)); + VectorScale(up, 1/(l*l), up); + + tx = DotProduct(origin, tang) + 0.5; + ty = DotProduct(origin, side) + 0.5; + tz = DotProduct(origin, up); + + /*reuse the previous trigroup if its the same shader*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS)) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = shader; + t->numidx = 0; + t->numvert = 0; + t->flags = BEF_NODLIGHT|BEF_NOSHADOWS; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + } + + + if (cl_numstrisvert + num > cl_maxstrisvert) + { + cl_maxstrisvert = cl_numstrisvert + num; + + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+num) + { + cl_maxstrisidx = cl_numstrisidx+num + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + + for (v = 0; v < num; v++) + { + VectorCopy(verts, cl_strisvertv[cl_numstrisvert+v]); + cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(verts, tang) - tx); + cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(verts, side) - ty); + cl_strisvertc[cl_numstrisvert+v][0] = rgbvalue[0]; + cl_strisvertc[cl_numstrisvert+v][1] = rgbvalue[1]; + cl_strisvertc[cl_numstrisvert+v][2] = rgbvalue[2]; + cl_strisvertc[cl_numstrisvert+v][3] = alphavalue * (1-(DotProduct(verts, up) - tz)); + verts+=3; + } + for (v = 0; v < num; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert; + } + + t->numvert += num; + t->numidx += num; + cl_numstrisvert += num; +} + void CLQ1_AddShadow(entity_t *ent) { float radius; @@ -2063,7 +2456,7 @@ void CLQ1_AddShadow(entity_t *ent) tz = DotProduct(shadoworg, axis[2]); /*reuse the previous trigroup if its the same shader*/ - if (cl_numstris && cl_stris[cl_numstris-1].shader == s) + if (cl_numstris && cl_stris[cl_numstris-1].shader == s && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS)) t = &cl_stris[cl_numstris-1]; else { @@ -2074,6 +2467,7 @@ void CLQ1_AddShadow(entity_t *ent) } t = &cl_stris[cl_numstris++]; t->shader = s; + t->flags = BEF_NODLIGHT|BEF_NOSHADOWS; t->numidx = 0; t->numvert = 0; t->firstidx = cl_numstrisidx; @@ -2122,7 +2516,7 @@ void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects if (!(effects & (EF_BLUE | EF_RED)) || !v_powerupshell.value || !ent) return; - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) return; // object list is full shell = &cl_visedicts[cl_numvisedicts++]; @@ -2231,7 +2625,7 @@ void CL_LinkStaticEntities(void *pvs) for (i = 0; i < cl.num_statics; i++) { - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) break; stat = &cl_static_entities[i].ent; @@ -2315,10 +2709,17 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp sold = &oldpack->entities[oldpnum]; if (sold->number >= snew->number) { + oldpnum++; if (sold->number > snew->number) sold = NULL; //woo, it's a new entity. break; } + +#ifdef RAGDOLL + le = &cl.lerpents[sold->number]; + if (le->skeletalobject) + rag_removedeltaent(le); +#endif } if (!sold) //I'm lazy sold = snew; @@ -2637,9 +3038,8 @@ void CL_LinkPacketEntities (void) - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) { - Con_Printf("Too many visible entities\n"); break; } @@ -2649,6 +3049,10 @@ void CL_LinkPacketEntities (void) #endif ent = &cl_visedicts[cl_numvisedicts]; + ent->playerindex = -1; + ent->topcolour = TOP_DEFAULT; + ent->bottomcolour = BOTTOM_DEFAULT; + ent->h2playerclass = 0; ent->light_known = 0; ent->forcedshader = NULL; @@ -2737,10 +3141,6 @@ void CL_LinkPacketEntities (void) if (state->modelindex<1) continue; - // create a new entity - if (cl_numvisedicts == MAX_VISEDICTS) - break; // object list is full - if (CL_FilterModelindex(state->modelindex, state->frame)) continue; @@ -2763,7 +3163,11 @@ void CL_LinkPacketEntities (void) else ent->model = model; - ent->flags = state->flags; + ent->flags = 0; + if (state->dpflags & RENDER_VIEWMODEL) + ent->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; + if (state->dpflags & RENDER_EXTERIORMODEL) + ent->flags |= Q2RF_EXTERNALMODEL; if (state->effects & NQEF_ADDITIVE) ent->flags |= Q2RF_ADDITIVE; if (state->effects & EF_NODEPTHTEST) @@ -2783,15 +3187,15 @@ void CL_LinkPacketEntities (void) } */ // set colormap - if (state->colormap && (state->colormap <= MAX_CLIENTS) - && (gl_nocolors.value == -1 || (ent->model/* && state->modelindex == cl_playerindex*/))) + if (state->dpflags & RENDER_COLORMAPPED) { - // TODO: DP colormap/colormod extension? - ent->scoreboard = &cl.players[state->colormap-1]; + ent->topcolour = (state->colormap>>4) & 0xf; + ent->bottomcolour = (state->colormap>>0) & 0xf; } - else + else if (state->colormap > 0 && state->colormap <= MAX_CLIENTS) { - ent->scoreboard = NULL; + ent->topcolour = cl.players[state->colormap-1].ttopcolor; + ent->bottomcolour = cl.players[state->colormap-1].tbottomcolor; } // set skin @@ -2869,6 +3273,11 @@ void CL_LinkPacketEntities (void) VectorMA(dl->origin, 16, dl->axis[0], dl->origin); } +#ifdef RAGDOLL + if (ent->model->dollinfo) + rag_updatedeltaent(ent, le); +#endif + // add automatic particle trails if (!model || (!(model->flags&~MF_ROTATE) && model->particletrail<0 && model->particleeffect<0 && state->u.q1.traileffectnum==0)) continue; @@ -3049,7 +3458,7 @@ void CL_LinkProjectiles (void) for (i=0, pr=cl_projectiles ; iskinnum = 0; memset(&ent->framestate, 0, sizeof(ent->framestate)); ent->flags = 0; - ent->scoreboard = NULL; + ent->playerindex = -1; + ent->topcolour = TOP_DEFAULT; + ent->bottomcolour = BOTTOM_DEFAULT; + ent->h2playerclass = 0; #ifdef PEXT_SCALE ent->scale = 1; #endif @@ -3268,7 +3680,7 @@ void CL_ParsePlayerinfo (void) } } - if (cl.splitclients < MAX_SPLITS) + if (cl.splitclients < MAX_SPLITS && !cl.players[num].spectator) { extern cvar_t cl_splitscreen; if (cl.splitclients < cl_splitscreen.value+1) @@ -3282,6 +3694,7 @@ void CL_ParsePlayerinfo (void) autocam[cl.splitclients] = CAM_TRACK; spec_track[cl.splitclients] = num; cl.splitclients++; + Cam_Lock(i, num); } } } @@ -3515,6 +3928,7 @@ guess_pm_type: VectorCopy (state->origin, state->predorigin); } +/* void CL_ParseClientPersist(void) { player_info_t *info; @@ -3524,7 +3938,7 @@ void CL_ParseClientPersist(void) if (flags & 1) info->vweapindex = MSG_ReadShort(); } - +*/ /* ================ @@ -3765,7 +4179,7 @@ void CL_LinkPlayers (void) continue; */ // grab an entity to fill in - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) break; // object list is full ent = &cl_visedicts[cl_numvisedicts]; cl_numvisedicts++; @@ -3779,10 +4193,11 @@ void CL_LinkPlayers (void) CL_LerpNetFrameState(FS_REG, &ent->framestate, &cl.lerpplayers[j]); -// if (state->modelindex == cl_playerindex) - ent->scoreboard = info; // use custom skin -// else -// ent->scoreboard = NULL; + // set colormap + ent->playerindex = j; + ent->topcolour = info->ttopcolor; + ent->bottomcolour = info->tbottomcolor; + ent->h2playerclass = info->h2playerclass; #ifdef PEXT_SCALE ent->scale = state->scale; @@ -3877,9 +4292,7 @@ void CL_LinkPlayers (void) CL_AddFlagModels (ent, 0); else if (state->effects & QWEF_FLAG2) CL_AddFlagModels (ent, 1); - if (info->vweapindex) - CL_AddVWeapModel (ent, cl.model_precache[info->vweapindex]); - else if (state->command.impulse) + if (state->command.impulse) CL_AddVWeapModel (ent, cl.model_precache_vwep[state->command.impulse]); CLQ1_AddShadow(ent); @@ -3951,7 +4364,7 @@ void CL_LinkViewModel(void) if (alpha <= 0) return; - memset(&ent, 0, sizeof(ent)); + V_ClearEntity(&ent); ent.model = cl.viewent[r_refdef.currentplayernum].model; if (!ent.model) @@ -4285,13 +4698,30 @@ Builds the visedicts array for cl.time Made up of: clients, packet_entities, nails, and tents =============== */ -void CL_SwapEntityLists(void) +void CL_ClearEntityLists(void) { + if (cl_numvisedicts == cl_maxvisedicts) + { + int newnum = cl_maxvisedicts + 32; + entity_t *n = BZ_Realloc(cl_visedicts, newnum * sizeof(*n)); + if (n) + { + cl_visedicts = n; + cl_maxvisedicts = newnum; + } + } cl_numvisedicts = 0; cl_numstrisidx = 0; cl_numstrisvert = 0; cl_numstris = 0; } +void CL_FreeVisEdicts(void) +{ + BZ_Free(cl_visedicts); + cl_visedicts = NULL; + cl_maxvisedicts = 0; + cl_numvisedicts = 0; +} /* static void CL_WaterSplashes(void) { @@ -4333,6 +4763,7 @@ void CL_EmitEntities (void) #ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2) { + CL_ClearEntityLists(); CLQ2_AddEntities(); return; } @@ -4340,7 +4771,7 @@ void CL_EmitEntities (void) if (!cl.validsequence) return; - CL_SwapEntityLists(); + CL_ClearEntityLists(); CL_LinkPlayers (); CL_LinkPacketEntities (); diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index aa0c2b34..320611ea 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -854,8 +854,6 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso vec3_t temp; vec3_t cursor_impact_normal; - extern int mousecursor_x, mousecursor_y; - cursor_active = true; if (!cl_prydoncursor.ival) @@ -982,7 +980,7 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) MSG_WriteFloat (buf, cursor_impact[0]); MSG_WriteFloat (buf, cursor_impact[1]); MSG_WriteFloat (buf, cursor_impact[2]); - MSG_WriteShort (buf, cursor_entitynumber); + MSG_WriteEntity (buf, cursor_entitynumber); } } @@ -1425,7 +1423,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) MSG_WriteFloat(buf, cursor_impact[0]); MSG_WriteFloat(buf, cursor_impact[1]); MSG_WriteFloat(buf, cursor_impact[2]); - MSG_WriteShort(buf, cursor_entitynumber); + MSG_WriteEntity(buf, cursor_entitynumber); } else cursor_active = false; @@ -1527,7 +1525,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) } for (plnum = 0; plnum < cl.splitclients; plnum++) { - cmd = &cl.frames[i].cmd[0]; + cmd = &cl.frames[i].cmd[plnum]; memset(cmd, 0, sizeof(*cmd)); msecs += frametime*1000; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 317564ea..257565d9 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -77,23 +77,23 @@ cvar_t m_side = CVARF("m_side","0.8", CVAR_ARCHIVE); cvar_t cl_lerp_players = CVARD("cl_lerp_players", "0", "Set this to make other players smoother, though it may increase effective latency. Affects only QuakeWorld."); cvar_t cl_predict_players = CVARD("cl_predict_players", "1", "Clear this cvar to see ents exactly how they are on the server."); cvar_t cl_predict_players_frac = CVARD("cl_predict_players_frac", "0.9", "How much of other players to predict. Values less than 1 will help minimize overruns."); -cvar_t cl_solid_players = CVAR("cl_solid_players", "1"); +cvar_t cl_solid_players = CVARD("cl_solid_players", "1", "Consider other players as solid for player prediction."); cvar_t cl_noblink = CVARD("cl_noblink", "0", "Disable the ^^b text blinking feature."); -cvar_t cl_servername = CVAR("cl_servername", "none"); -cvar_t cl_serveraddress = CVAR("cl_serveraddress", "none"); +cvar_t cl_servername = CVARD("cl_servername", "none", "The hostname of the last server you connected to"); +cvar_t cl_serveraddress = CVARD("cl_serveraddress", "none", "The address of the last server you connected to"); cvar_t qtvcl_forceversion1 = CVAR("qtvcl_forceversion1", "0"); cvar_t qtvcl_eztvextensions = CVAR("qtvcl_eztvextensions", "0"); cvar_t cl_demospeed = CVARAF("cl_demospeed", "1", "demo_setspeed", 0); -cvar_t cl_loopbackprotocol = CVAR("cl_loopbackprotocol", "qw"); +cvar_t cl_loopbackprotocol = CVARD("cl_loopbackprotocol", "qw", "Which protocol to use for single-player/the internal client. Should be one of: qw, nqid, nq, fitz, dp6, dp7."); cvar_t cl_threadedphysics = CVAR("cl_threadedphysics", "0"); cvar_t localid = SCVAR("localid", ""); -cvar_t r_drawflame = CVAR("r_drawflame", "1"); +cvar_t r_drawflame = CVARD("r_drawflame", "1", "Set to -1 to disable ALL static entities. Set to 0 to disable only wall torches and standing flame. Set to 1 for everything drawn as normal."); static qboolean allowremotecmd = true; @@ -110,10 +110,10 @@ cvar_t skin = CVARF("skin", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t model = CVARF("model", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t topcolor = CVARF("topcolor", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t bottomcolor = CVARF("bottomcolor", "", CVAR_ARCHIVE | CVAR_USERINFO); -cvar_t rate = CVARF("rate", "10000"/*"6480"*/, CVAR_ARCHIVE | CVAR_USERINFO); -cvar_t drate = CVARF("drate", "100000", CVAR_ARCHIVE | CVAR_USERINFO); // :) +cvar_t rate = CVARFD("rate", "10000"/*"6480"*/, CVAR_ARCHIVE | CVAR_USERINFO, "A rough measure of the bandwidth to try to use while playing. Too high a value may result in 'buffer bloat'."); +cvar_t drate = CVARFD("drate", "100000", CVAR_ARCHIVE | CVAR_USERINFO, "A rough measure of the bandwidth to try to use while downloading."); // :) cvar_t noaim = CVARF("noaim", "", CVAR_ARCHIVE | CVAR_USERINFO); -cvar_t msg = CVARF("msg", "1", CVAR_ARCHIVE | CVAR_USERINFO); +cvar_t msg = CVARFD("msg", "1", CVAR_ARCHIVE | CVAR_USERINFO, "Filter console prints/messages. Only functions on QuakeWorld servers. 0=pickup messages. 1=death messages. 2=critical messages. 3=chat."); cvar_t b_switch = CVARF("b_switch", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t w_switch = CVARF("w_switch", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t cl_nofake = CVARD("cl_nofake", "2", "value 0: permits \\r chars in chat messages\nvalue 1: blocks all \\r chars\nvalue 2: allows \\r chars, but only from teammates"); @@ -149,12 +149,12 @@ cvar_t cl_muzzleflash = SCVAR("cl_muzzleflash", "1"); cvar_t cl_item_bobbing = CVARF("cl_model_bobbing", "0", CVAR_ARCHIVE); cvar_t cl_countpendingpl = SCVAR("cl_countpendingpl", "0"); -cvar_t cl_standardchat = SCVARF("cl_standardchat", "0", CVAR_ARCHIVE); -cvar_t msg_filter = SCVAR("msg_filter", "0"); //0 for neither, 1 for mm1, 2 for mm2, 3 for both -cvar_t cl_standardmsg = SCVARF("cl_standardmsg", "0", CVAR_ARCHIVE); +cvar_t cl_standardchat = CVARFD("cl_standardchat", "0", CVAR_ARCHIVE, "Disables auto colour coding in chat messages."); +cvar_t msg_filter = CVARD("msg_filter", "0", "Filter out chat messages: 0=neither. 1=broadcast chat. 2=team chat. 3=all chat."); +cvar_t cl_standardmsg = CVARFD("cl_standardmsg", "0", CVAR_ARCHIVE, "Disables auto colour coding in console prints."); cvar_t cl_parsewhitetext = CVARD("cl_parsewhitetext", "1", "When parsing chat messages, enable support for messages like: red{white}red"); -cvar_t cl_dlemptyterminate = SCVAR("cl_dlemptyterminate", "1"); +cvar_t cl_dlemptyterminate = CVAR("cl_dlemptyterminate", "1"); cvar_t host_mapname = CVARAF("mapname", "", "host_mapname", 0); @@ -200,7 +200,8 @@ int rtlights_first, rtlights_max; // this is double buffered so the last frame // can be scanned for oldorigins of trailing objects int cl_numvisedicts; -entity_t cl_visedicts[MAX_VISEDICTS]; +int cl_maxvisedicts; +entity_t *cl_visedicts; scenetris_t *cl_stris; vecV_t *cl_strisvertv; @@ -344,8 +345,8 @@ void CL_SupportedFTEExtensions(int *pext1, int *pext2) unsigned int fteprotextsupported = 0; unsigned int fteprotextsupported2 = 0; - fteprotextsupported = Net_PextMask(1); - fteprotextsupported2 = Net_PextMask(2); + fteprotextsupported = Net_PextMask(1, false); + fteprotextsupported2 = Net_PextMask(2, false); fteprotextsupported &= strtoul(cl_pext_mask.string, NULL, 16); // fteprotextsupported2 &= strtoul(cl_pext2_mask.string, NULL, 16); @@ -642,6 +643,11 @@ void CL_CheckForResend (void) cl.movemessages = 0; if (!strcmp(cl_loopbackprotocol.string, "qw")) cls.protocol = CP_QUAKEWORLD; + else if (!strcmp(cl_loopbackprotocol.string, "fitz")) //actually proquake, because we might as well use the extra angles + { + cls.protocol = CP_NETQUAKE; + cls.protocol_nq = CPNQ_FITZ666; + } else if (!strcmp(cl_loopbackprotocol.string, "nq")) //actually proquake, because we might as well use the extra angles { cls.protocol = CP_NETQUAKE; @@ -687,6 +693,8 @@ void CL_CheckForResend (void) while(NET_GetPacket (NS_SERVER, 0) >= 0) { } + net_message.packing = SZ_RAWBYTES; + net_message.cursize = 0; if (cls.protocol_nq == CPNQ_ID) { @@ -695,6 +703,13 @@ void CL_CheckForResend (void) SVC_DirectConnect(); } + else if (cls.protocol_nq == CPNQ_FITZ666) + { + net_from = adr; + Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\666\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false); + + SVC_DirectConnect(); + } else if (cls.protocol_nq == CPNQ_PROQUAKE3_4) { net_from = adr; @@ -706,7 +721,7 @@ void CL_CheckForResend (void) CL_ConnectToDarkPlaces("", adr); } else - CL_SendConnectPacket (8192-16, Net_PextMask(1), Net_PextMask(2), false); + CL_SendConnectPacket (8192-16, Net_PextMask(1, false), Net_PextMask(2, false), false); return; } #endif @@ -3685,8 +3700,8 @@ double Host_Frame (double time) SV_Frame(); RSpeedEnd(RSPEED_SERVER); host_frametime = ohft; - if (cls.protocol != CP_QUAKE3 && cls.protocol != CP_QUAKE2) - CL_ReadPackets (); //q3's cgame cannot cope with input commands with the same time as the most recent snapshot value +// if (cls.protocol != CP_QUAKE3 && cls.protocol != CP_QUAKE2) +// CL_ReadPackets (); //q3's cgame cannot cope with input commands with the same time as the most recent snapshot value } #endif CL_CalcClientTime(); @@ -3968,6 +3983,9 @@ void Host_Init (quakeparms_t *parms) COM_Init (); #ifdef Q2BSPS CM_Init(); +#endif +#ifdef TERRAIN + Terr_Init(); #endif Host_FixupModelNames(); @@ -4095,6 +4113,7 @@ void Host_Shutdown(void) MasterInfo_Shutdown(); #endif CL_FreeDlights(); + CL_FreeVisEdicts(); M_Shutdown(); #ifndef CLIENTONLY SV_Shutdown(); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index c9dffabc..3990b062 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1222,7 +1222,8 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) SCR_SetLoadingFile("csqc init"); if (CSQC_Inited()) { - CL_SendClientCommand(true, "enablecsqc"); + if (cls.fteprotocolextensions & PEXT_CSQC) + CL_SendClientCommand(true, "enablecsqc"); } else { @@ -1451,7 +1452,7 @@ void CL_RequestNextDownload (void) if (cls.demoplayback == DPB_EZTV) { if (CL_RemoveClientCommands("qtvspawn")) - Con_Printf("Multiple prespawns\n"); + Con_DPrintf("Multiple prespawns\n"); CL_SendClientCommand(true, "qtvspawn %i 0 %i", cl.servercount, COM_RemapMapChecksum(LittleLong(cl.worldmodel->checksum2))); SCR_SetLoadingStage(LS_NONE); } @@ -1459,9 +1460,14 @@ void CL_RequestNextDownload (void) { // done with modellist, request first of static signon messages if (CL_RemoveClientCommands("prespawn")) - Con_Printf("Multiple prespawns\n"); - // CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); - CL_SendClientCommand(true, prespawn_name, cl.servercount, COM_RemapMapChecksum(LittleLong(cl.worldmodel->checksum2))); + Con_DPrintf("Multiple prespawns\n"); + if (cls.protocol == CP_NETQUAKE) + CL_SendClientCommand(true, "prespawn"); + else + { + // CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); + CL_SendClientCommand(true, prespawn_name, cl.servercount, COM_RemapMapChecksum(LittleLong(cl.worldmodel->checksum2))); + } } } @@ -2532,7 +2538,7 @@ void CLQW_ParseServerData (void) if (cls.fteprotocolextensions & PEXT_PK3DOWNLOADS) //instead of going for a soundlist, go for the pk3 list instead. The server will make us go for the soundlist after. { if (CL_RemoveClientCommands("pk3list")) - Con_Printf("Multiple pk3lists\n"); + Con_DPrintf("Multiple pk3lists\n"); CL_SendClientCommand ("pk3list %i 0", cl.servercount, 0); } else @@ -2541,13 +2547,13 @@ void CLQW_ParseServerData (void) if (cls.demoplayback == DPB_EZTV) { if (CL_RemoveClientCommands("qtvsoundlist")) - Con_Printf("Multiple soundlists\n"); + Con_DPrintf("Multiple soundlists\n"); CL_SendClientCommand (true, "qtvsoundlist %i 0", cl.servercount); } else { if (CL_RemoveClientCommands("soundlist")) - Con_Printf("Multiple soundlists\n"); + Con_DPrintf("Multiple soundlists\n"); // ask for the sound list next // CL_SendClientCommand ("soundlist %i 0", cl.servercount); CL_SendClientCommand (true, soundlist_name, cl.servercount, 0); @@ -3161,7 +3167,7 @@ void CL_ParseSoundlist (qboolean lots) if (cls.demoplayback != DPB_EZTV) { if (CL_RemoveClientCommands("soundlist")) - Con_Printf("Multiple soundlists\n"); + Con_DPrintf("Multiple soundlists\n"); // CL_SendClientCommand("soundlist %i %i", cl.servercount, n); CL_SendClientCommand(true, soundlist_name, cl.servercount, (numsounds&0xff00) + n); } @@ -3183,13 +3189,13 @@ void CL_ParseSoundlist (qboolean lots) if (cls.demoplayback == DPB_EZTV) { if (CL_RemoveClientCommands("qtvmodellist")) - Con_Printf("Multiple modellists\n"); + Con_DPrintf("Multiple modellists\n"); CL_SendClientCommand (true, "qtvmodellist %i 0", cl.servercount); } else { if (CL_RemoveClientCommands("modellist")) - Con_Printf("Multiple modellists\n"); + Con_DPrintf("Multiple modellists\n"); // CL_SendClientCommand ("modellist %i 0", cl.servercount); CL_SendClientCommand (true, modellist_name, cl.servercount, 0); } @@ -3256,7 +3262,7 @@ void CL_ParseModellist (qboolean lots) if (cls.demoplayback != DPB_EZTV) { if (CL_RemoveClientCommands("modellist")) - Con_Printf("Multiple modellists\n"); + Con_DPrintf("Multiple modellists\n"); // CL_SendClientCommand("modellist %i %i", cl.servercount, n); CL_SendClientCommand(true, modellist_name, cl.servercount, (nummodels&0xff00) + n); } @@ -3497,8 +3503,8 @@ void CLFitz_ParseBaseline2 (entity_state_t *es) memcpy(es, &nullentitystate, sizeof(entity_state_t)); bits = MSG_ReadByte(); - es->modelindex = (bits & FITZB_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte(); - es->frame = (bits & FITZB_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte(); + es->modelindex = (bits & FITZ_B_LARGEMODEL) ? MSG_ReadShort() : MSG_ReadByte(); + es->frame = (bits & FITZ_B_LARGEFRAME) ? MSG_ReadShort() : MSG_ReadByte(); es->colormap = MSG_ReadByte(); es->skinnum = MSG_ReadByte(); @@ -3508,7 +3514,8 @@ void CLFitz_ParseBaseline2 (entity_state_t *es) es->angles[i] = MSG_ReadAngle (); } - es->trans = (bits & FITZB_ALPHA) ? MSG_ReadByte() : 255; + es->trans = (bits & FITZ_B_ALPHA) ? MSG_ReadByte() : 255; + es->scale = (bits & RMQFITZ_B_SCALE) ? MSG_ReadByte() : 16; } void CLQ2_Precache_f (void) @@ -3552,7 +3559,7 @@ void CL_ParseStatic (int version) if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) CLFTE_ParseBaseline(&es, false); else - CLQW_ParseDelta(&nullentitystate, &es, MSG_ReadShort(), true); + CLQW_ParseDelta(&nullentitystate, &es, (unsigned short)MSG_ReadShort(), true); if (!es.number) i = cl.num_statics++; @@ -3582,7 +3589,7 @@ void CL_ParseStatic (int version) cl_static_entities[i].emit = NULL; ent = &cl_static_entities[i].ent; - memset(ent, 0, sizeof(*ent)); + V_ClearEntity(ent); memset(&cl_static_entities[i].pvscache, 0, sizeof(cl_static_entities[i].pvscache)); ent->keynum = es.number; @@ -3604,7 +3611,11 @@ void CL_ParseStatic (int version) ent->fatness = es.fatness/16.0; ent->abslight = es.abslight; - ent->flags = es.flags; + ent->flags = 0; + if (es.dpflags & RENDER_VIEWMODEL) + ent->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; + if (es.dpflags & RENDER_EXTERIORMODEL) + ent->flags |= Q2RF_EXTERNALMODEL; if (es.effects & NQEF_ADDITIVE) ent->flags |= Q2RF_ADDITIVE; if (es.effects & EF_NODEPTHTEST) @@ -3682,7 +3693,7 @@ ACTION MESSAGES CL_ParseStartSoundPacket ================== */ -void CL_ParseStartSoundPacket(void) +void CLQW_ParseStartSoundPacket(void) { vec3_t pos; int channel, ent; @@ -3838,7 +3849,7 @@ void CLNQ_ParseStartSoundPacket(void) if (field_mask & DPSND_LARGEENTITY) { - ent = (unsigned short)MSG_ReadShort(); + ent = MSGCL_ReadEntity(); channel = MSG_ReadByte(); } else @@ -4269,7 +4280,7 @@ void CL_MuzzleFlash (int destsplit) extern cvar_t cl_muzzleflash; - i = MSG_ReadShort (); + i = MSGCL_ReadEntity (); //was it us? if (!cl_muzzleflash.ival) // remove all muzzleflashes @@ -4606,10 +4617,12 @@ char *CL_ParseChat(char *text, player_info_t **player) if (flags == 2 || (!cl.teamplay && flags)) suppress_talksound = TP_CheckSoundTrigger (text + offset); - if (!cl_chatsound.value || // no sound at all + if (cls.demoseeking || + !cl_chatsound.value || // no sound at all (cl_chatsound.value == 2 && flags != 2)) // only play sound in mm2 suppress_talksound = true; + if (!suppress_talksound) { if (flags & (TPM_OBSERVEDTEAM|TPM_TEAM) && cl.teamplay) @@ -5297,7 +5310,8 @@ void CLQW_ParseServerMessage (void) if ((msg = CL_ParseChat(s, &plr))) { CL_ParsePrint(s, i); - CL_PrintChat(plr, s, msg, msgflags); + if (!cls.demoseeking) + CL_PrintChat(plr, s, msg, msgflags); } } else @@ -5307,7 +5321,8 @@ void CLQW_ParseServerMessage (void) #endif { CL_ParsePrint(s, i); - CL_PrintStandardMessage(s, i); + if (!cls.demoseeking) + CL_PrintStandardMessage(s, i); } } break; @@ -5340,7 +5355,7 @@ void CLQW_ParseServerMessage (void) case svc_setview: if (!(cls.fteprotocolextensions & PEXT_SETVIEW)) Con_Printf("^1PEXT_SETVIEW is meant to be disabled\n"); - cl.viewentity[destsplit]=MSG_ReadShort(); + cl.viewentity[destsplit]=MSGCL_ReadEntity(); if (cl.viewentity[destsplit] == cl.playernum[destsplit]+1) cl.viewentity[destsplit] = 0; break; @@ -5399,7 +5414,7 @@ void CLQW_ParseServerMessage (void) #endif case svc_sound: - CL_ParseStartSoundPacket(); + CLQW_ParseStartSoundPacket(); break; #ifdef PEXT_SOUNDDBL case svcfte_soundextended: @@ -5449,7 +5464,7 @@ void CLQW_ParseServerMessage (void) break; case svc_spawnbaseline: - i = MSG_ReadShort (); + i = MSGCL_ReadEntity (); if (!CL_CheckBaselines(i)) Host_EndGame("CL_ParseServerMessage: svc_spawnbaseline failed with size %i", i); CL_ParseBaseline (cl_baselines + i); @@ -5620,12 +5635,12 @@ void CLQW_ParseServerMessage (void) #endif case svc_packetentities: - CL_ParsePacketEntities (false); + CLQW_ParsePacketEntities (false); cl.ackedinputsequence = cl.validsequence; break; case svc_deltapacketentities: - CL_ParsePacketEntities (true); + CLQW_ParsePacketEntities (true); cl.ackedinputsequence = cl.validsequence; break; case svcfte_updateentities: @@ -5648,9 +5663,9 @@ void CLQW_ParseServerMessage (void) CDAudio_Resume (); break; - case svc_ftesetclientpersist: - CL_ParseClientPersist(); - break; +// case svc_ftesetclientpersist: +// CL_ParseClientPersist(); +// break; #ifdef Q2BSPS case svc_setportalstate: i = MSG_ReadByte(); @@ -6176,7 +6191,7 @@ void CLNQ_ParseServerMessage (void) case svc_setview: if (!cl.viewentity[0]) { - cl.playernum[0] = (cl.viewentity[0] = MSG_ReadShort())-1; + cl.playernum[0] = (cl.viewentity[0] = MSGCL_ReadEntity())-1; if (cl.playernum[0] >= cl.allocated_client_slots) { Con_Printf(CON_WARNING "WARNING: Server put us in slot %i. We are not on the scoreboard.\n", cl.playernum[0]); @@ -6184,7 +6199,7 @@ void CLNQ_ParseServerMessage (void) } } else - cl.viewentity[0]=MSG_ReadShort(); + cl.viewentity[0]=MSGCL_ReadEntity(); break; case svc_signonnum: @@ -6212,7 +6227,7 @@ void CLNQ_ParseServerMessage (void) break; case svc_spawnbaseline: - i = MSG_ReadShort (); + i = MSGCL_ReadEntity (); if (!CL_CheckBaselines(i)) Host_EndGame("CLNQ_ParseServerMessage: svc_spawnbaseline failed with size %i", i); CL_ParseBaseline (cl_baselines + i); @@ -6235,6 +6250,8 @@ void CLNQ_ParseServerMessage (void) cl.gametime = MSG_ReadFloat(); cl.gametimemark = realtime; + cl.frames[cl.validsequence&UPDATE_MASK].receivedtime = realtime; + if (CPNQ_IS_DP) { int n = cls.netchan.incoming_sequence&UPDATE_MASK, o = (cls.netchan.incoming_sequence-1)&UPDATE_MASK; @@ -6406,7 +6423,7 @@ void CLNQ_ParseServerMessage (void) cl.fog_locked = !!cl.fog_density; break; case svcfitz_spawnbaseline2: - i = MSG_ReadShort (); + i = MSGCL_ReadEntity (); if (!CL_CheckBaselines(i)) Host_EndGame("CLNQ_ParseServerMessage: svcfitz_spawnbaseline2 failed with ent %i", i); CLFitz_ParseBaseline2 (cl_baselines + i); diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 2fb324f7..47d496bc 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -162,8 +162,11 @@ extern cvar_t scr_chatmodecvar; int mouseusedforgui; -int mousecursor_x, mousecursor_y; -int mousemove_x, mousemove_y; +float mousecursor_x, mousecursor_y; +float mousemove_x, mousemove_y; + +float multicursor_x[8], multicursor_y[8]; +qboolean multicursor_active[8]; float scr_con_current; float scr_conlines; // lines of console to display @@ -415,7 +418,7 @@ void SCR_EraseCenterString (void) } #define MAX_CPRINT_LINES 128 -void SCR_DrawCenterString (vrect_t *rect, cprint_t *p) +void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font) { int l; int y, x; @@ -483,8 +486,8 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p) } } - Font_BeginString(font_conchar, rect->x, y, &left, &top); - Font_BeginString(font_conchar, rect->x+rect->width, rect->y+rect->height, &right, &bottom); + Font_BeginString(font, rect->x, y, &left, &top); + Font_BeginString(font, rect->x+rect->width, rect->y+rect->height, &right, &bottom); linecount = Font_LineBreaks(p->string, p->string + p->charcount, right - left, MAX_CPRINT_LINES, line_start, line_end); if (p->flags & CPRINT_TALIGN) @@ -542,7 +545,7 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p) } Font_LineDraw(x, y, line_start[l], line_end[l]); } - Font_EndString(font_conchar); + Font_EndString(font); } void SCR_CheckDrawCenterString (void) @@ -568,7 +571,7 @@ extern qboolean sb_showscores; continue; SCR_VRectForPlayer(&rect, pnum); - SCR_DrawCenterString(&rect, p); + SCR_DrawCenterString(&rect, p, font_conchar); } } @@ -587,13 +590,12 @@ void R_DrawTextField(int x, int y, int w, int h, char *text, unsigned int defaul p.time_off = scr_centertime.value; p.time_start = cl.time; - SCR_DrawCenterString(&r, &p); + SCR_DrawCenterString(&r, &p, font_conchar); } void SCR_DrawCursor(int prydoncursornum) { extern cvar_t cl_cursor, cl_cursorbias, cl_cursorsize; - extern int mousecursor_x, mousecursor_y; mpic_t *p; if (!*cl_cursor.string || prydoncursornum>1) p = R2D_SafeCachePic(va("gfx/prydoncursor%03i.lmp", prydoncursornum)); @@ -608,14 +610,29 @@ void SCR_DrawCursor(int prydoncursornum) } else { - int x, y; - Font_BeginString(font_conchar, mousecursor_x, mousecursor_y, &x, &y); + float x, y; + Font_BeginScaledString(font_conchar, mousecursor_x, mousecursor_y, 8, 8, &x, &y); x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; y -= Font_CharHeight()/2; - Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK); + Font_DrawScaleChar(x, y, '+' | 0xe000 | CON_WHITEMASK); Font_EndString(font_conchar); } - +} +static void SCR_DrawSimMTouchCursor(void) +{ + int i; + float x, y; + for (i = 0; i < 8; i++) + { + if (multicursor_active[i]) + { + Font_BeginScaledString(font_conchar, multicursor_x[i], multicursor_y[i], 8, 8, &x, &y); + x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; + y -= Font_CharHeight()/2; + Font_DrawScaleChar(x, y, '+' | 0xe000 | CON_WHITEMASK); + Font_EndString(font_conchar); + } + } } //////////////////////////////////////////////////////////////// @@ -2367,5 +2384,9 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud) if (key_dest == key_console) SCR_DrawConsole (false); + if (Key_MouseShouldBeFree()) + SCR_DrawCursor(0); + SCR_DrawSimMTouchCursor(); + RSpeedEnd(RSPEED_2D); } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 6cb042f8..c95547a7 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -773,7 +773,7 @@ void CL_ParseBeam (int tent) int ent; vec3_t start, end; - ent = MSG_ReadShort (); + ent = MSGCL_ReadEntity (); start[0] = MSG_ReadCoord (); start[1] = MSG_ReadCoord (); @@ -795,7 +795,7 @@ void CL_ParseStream (int type) float duration; int skin; - ent = MSG_ReadShort(); + ent = MSGCL_ReadEntity(); flags = MSG_ReadByte(); tag = flags&15; flags-=tag; @@ -1336,6 +1336,10 @@ void CL_ParseTEnt (void) break; + case TEQW_BEAM: + CL_ParseBeam (5); + break; + case TE_RAILTRAIL: pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); @@ -1914,7 +1918,7 @@ void CL_ParseTrailParticles(void) vec3_t start, end; trailstate_t **ts; - entityindex = (unsigned short)MSG_ReadShort(); + entityindex = MSGCL_ReadEntity(); effectindex = (unsigned short)MSG_ReadShort(); start[0] = MSG_ReadCoord(); @@ -2972,13 +2976,17 @@ entity_t *CL_NewTempEntity (void) { entity_t *ent; - if (cl_numvisedicts == MAX_VISEDICTS) + if (cl_numvisedicts == cl_maxvisedicts) return NULL; ent = &cl_visedicts[cl_numvisedicts]; cl_numvisedicts++; ent->keynum = 0; memset (ent, 0, sizeof(*ent)); + ent->playerindex = -1; + ent->topcolour = TOP_DEFAULT; + ent->bottomcolour = BOTTOM_DEFAULT; + ent->h2playerclass = 0; #ifdef PEXT_SCALE ent->scale = 1; diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index d48d2218..5187ce7a 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -420,7 +420,7 @@ void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts) unsigned int v; scenetris_t *t; /*reuse the previous trigroup if its the same shader*/ - if (cl_numstris && cl_stris[cl_numstris-1].shader == s) + if (cl_numstris && cl_stris[cl_numstris-1].shader == s && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS)) t = &cl_stris[cl_numstris-1]; else { @@ -431,6 +431,7 @@ void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts) } t = &cl_stris[cl_numstris++]; t->shader = s; + t->flags = BEF_NODLIGHT|BEF_NOSHADOWS; t->numidx = 0; t->numvert = 0; t->firstidx = cl_numstrisidx; @@ -856,10 +857,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case UI_R_CLEARSCENE: //clear scene - cl_numvisedicts = 0; - cl_numstrisidx = 0; - cl_numstrisvert = 0; - cl_numstris = 0; + CL_ClearEntityLists(); break; case UI_R_ADDREFENTITYTOSCENE: //add ent to scene VQ3_AddEntity(VM_POINTER(arg[0])); diff --git a/engine/client/client.h b/engine/client/client.h index e95eea44..137aa16b 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -175,7 +175,7 @@ typedef struct player_info_s struct model_s *model; - unsigned short vweapindex; +// unsigned short vweapindex; unsigned char h2playerclass; int prevcount; @@ -403,6 +403,8 @@ typedef struct DPB_QUAKE2 #endif } demoplayback; + qboolean demoseeking; + float demoseektime; qboolean timedemo; vfsfile_t *demoinfile; float td_lastframe; // to meter out one message a frame @@ -483,7 +485,8 @@ typedef struct { vec3_t oldangle; //for further info - int sequence; + int skeletalobject; + int sequence; /*so csqc code knows that the ent is still valid*/ entity_state_t *entstate; } lerpents_t; // @@ -829,9 +832,9 @@ char *CL_TryingToConnect(void); void CL_ExecInitialConfigs(void); qboolean CL_CheckBootDownloads(void); -#define MAX_VISEDICTS 2048 extern int cl_numvisedicts; -extern entity_t cl_visedicts[]; +extern int cl_maxvisedicts; +extern entity_t *cl_visedicts; /*these are for q3 really*/ typedef struct { @@ -840,6 +843,7 @@ typedef struct { int firstidx; int numvert; int numidx; + unsigned int flags; } scenetris_t; extern scenetris_t *cl_stris; extern vecV_t *cl_strisvertv; @@ -1042,14 +1046,15 @@ void CL_TransitionEntities (void); /*call at the start of the frame*/ void CL_EmitEntities (void); void CL_ClearProjectiles (void); void CL_ParseProjectiles (int modelindex, qboolean nails2); -void CL_ParsePacketEntities (qboolean delta); +void CLQW_ParsePacketEntities (qboolean delta); void CLFTE_ParseEntities (void); void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant); void CL_SetSolidEntities (void); void CL_ParsePlayerinfo (void); void CL_ParseClientPersist(void); //these last ones are needed for csqc handling of engine-bound ents. -void CL_SwapEntityLists(void); +void CL_ClearEntityLists(void); +void CL_FreeVisEdicts(void); void CL_LinkViewModel(void); void CL_LinkPlayers (void); void CL_LinkPacketEntities (void); @@ -1283,8 +1288,8 @@ extern qboolean editoractive; extern qboolean editormodal; void Editor_Draw(void); void Editor_Init(void); -struct progfuncs_s; -void Editor_ProgsKilled(struct progfuncs_s *dead); +struct pubprogfuncs_s; +void Editor_ProgsKilled(struct pubprogfuncs_s *dead); #endif void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index b43c529d..1ff0bb15 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1211,7 +1211,10 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) ent.glowmod[1] = 1; ent.glowmod[2] = 1; ent.fatness = 0; - ent.scoreboard = NULL; + ent.topcolour = 1; + ent.bottomcolour = 1; + ent.h2playerclass = 0; + ent.playerindex = -1; // set frame if (effects & Q2EF_ANIM01) @@ -1305,7 +1308,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) if (!ent.model || ent.model->needload) ent.model = Mod_ForName("players/male/tris.md2", false); } - ent.scoreboard = player; + ent.playerindex = s1->skinnum%MAX_CLIENTS; player->model = ent.model; /* ci = &cl.clientinfo[s1->skinnum & 0xff]; // ent.skin = ci->skin; @@ -1920,10 +1923,6 @@ void CLQ2_AddEntities (void) r_refdef.currentplayernum = 0; - cl_numvisedicts = 0; - cl_numstrisidx = 0; - cl_numstrisvert = 0; - cl_numstris = 0; if (cl.time*1000 > cl.q2frame.servertime) { @@ -1954,7 +1953,7 @@ void CL_GetNumberedEntityInfo (int num, float *org, float *ang) { q2centity_t *ent; - if (num < 0 || num >= MAX_EDICTS) + if (num < 0 || num >= MAX_Q2EDICTS) Host_EndGame ("CL_GetNumberedEntityInfo: bad ent"); ent = &cl_entities[num]; diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index c7e6f155..73f4e8a9 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -988,11 +988,11 @@ void CLQ3_SendAuthPacket(netadr_t gameserver) { char *key = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth")->string; netadr_t authaddr; -#define AUTHORIZE_SERVER_NAME "authorize.quake3arena.com:27952" +#define Q3_AUTHORIZE_SERVER_NAME "authorize.quake3arena.com:27952" if (*key) { - Con_Printf("Resolving %s\n", AUTHORIZE_SERVER_NAME); - if (NET_StringToAdr(AUTHORIZE_SERVER_NAME, &authaddr)) + Con_Printf("Resolving %s\n", Q3_AUTHORIZE_SERVER_NAME); + if (NET_StringToAdr(Q3_AUTHORIZE_SERVER_NAME, &authaddr)) { msg.data = data; msg.cursize = 0; diff --git a/engine/client/console.c b/engine/client/console.c index ecb219b4..3171a6b5 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1220,12 +1220,30 @@ void Con_PrintToSys(void) conline_t *l; int i; conchar_t *t; + char buf[16]; + extern cvar_t com_parseutf8; + for (l = curcon->oldest; l; l = l->newer) { t = (conchar_t*)(l+1); //fixme: utf8? for (i = 0; i < l->length; i++) - Sys_Printf("%c", t[i]&0xff); + { + if (!(t[i] & CON_HIDDEN)) + { + if (com_parseutf8.ival>0) + { + int cl = utf8_encode(buf, t[i]&CON_CHARMASK, sizeof(buf)-1); + if (cl) + { + buf[cl] = 0; + Sys_Printf("%s", buf); + } + } + else + Sys_Printf("%c", t[i]&0xff); + } + } Sys_Printf("\n"); } } diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index fa6ae3a8..adc438c0 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -3,23 +3,20 @@ #include "quakedef.h" -extern qboolean mouse_active; - -static cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE); -static cvar_t m_accel = CVARF("m_accel", "0", CVAR_ARCHIVE); +extern qboolean mouse_active; + +static cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE); +static cvar_t m_accel = CVARF("m_accel", "0", CVAR_ARCHIVE); static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice."); -static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas."); -static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn."); -static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.5", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens)."); -static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "5", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens)."); - -extern cvar_t cl_forcesplitclient; //all devices claim to be a single player -extern cvar_t _windowed_mouse; - -int mousecursor_x, mousecursor_y; /*absolute position*/ -extern int mousemove_x, mousemove_y; - - +static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas."); +static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn."); +static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.5", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens)."); +static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "5", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens)."); + +extern cvar_t cl_forcesplitclient; //all devices claim to be a single player +extern cvar_t _windowed_mouse; + + #define EVENTQUEUELENGTH 128 struct eventlist_s { @@ -77,48 +74,48 @@ struct mouse_s vec2_t old_delta; //how far its moved previously, for mouse smoothing float wheeldelta; int down; -} ptr[MAXPOINTERS]; - - - -void IN_Shutdown(void) -{ - INS_Shutdown(); -} - -void IN_ReInit(void) -{ - int i; - +} ptr[MAXPOINTERS]; + + + +void IN_Shutdown(void) +{ + INS_Shutdown(); +} + +void IN_ReInit(void) +{ + int i; + events_avail = 0; - events_used = 0; - - for (i = 0; i < MAXPOINTERS; i++) - { - ptr[i].type = M_INVALID; - ptr[i].qdeviceid = i; - } - - INS_ReInit(); -} - -void IN_Init(void) -{ - Cvar_Register (&m_filter, "input controls"); - Cvar_Register (&m_accel, "input controls"); + events_used = 0; + + for (i = 0; i < MAXPOINTERS; i++) + { + ptr[i].type = M_INVALID; + ptr[i].qdeviceid = i; + } + + INS_ReInit(); +} + +void IN_Init(void) +{ + Cvar_Register (&m_filter, "input controls"); + Cvar_Register (&m_accel, "input controls"); Cvar_Register (&m_forcewheel, "Input Controls"); - Cvar_Register (&m_forcewheel_threshold, "Input Controls"); - Cvar_Register (&m_strafeonright, "input controls"); - Cvar_Register (&m_fatpressthreshold, "input controls"); - Cvar_Register (&m_slidethreshold, "input controls"); - - INS_Init(); -} - -/*a 'pointer' is either a multitouch pointer, or a separate device -note that mice use the keyboard button api, but separate devices*/ -void IN_Commands(void) -{ + Cvar_Register (&m_forcewheel_threshold, "Input Controls"); + Cvar_Register (&m_strafeonright, "input controls"); + Cvar_Register (&m_fatpressthreshold, "input controls"); + Cvar_Register (&m_slidethreshold, "input controls"); + + INS_Init(); +} + +/*a 'pointer' is either a multitouch pointer, or a separate device +note that mice use the keyboard button api, but separate devices*/ +void IN_Commands(void) +{ struct eventlist_s *ev; INS_Commands(); @@ -252,14 +249,11 @@ void IN_Commands(void) break; } events_used++; - } -} - -void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum) + } +} + +void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum) { - extern int mousecursor_x, mousecursor_y; - extern int mousemove_x, mousemove_y; - int mx, my; double mouse_x, mouse_y, mouse_deltadist; int mfwt; @@ -318,20 +312,23 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum) if (Key_MouseShouldBeFree()) { - mousecursor_x += mx; - mousecursor_y += my; + if (mx || my) + { + mousecursor_x += mx; + mousecursor_y += my; - if (mousecursor_y<0) - mousecursor_y=0; - if (mousecursor_x<0) - mousecursor_x=0; + if (mousecursor_y<0) + mousecursor_y=0; + if (mousecursor_x<0) + mousecursor_x=0; - if (mousecursor_x >= vid.width) - mousecursor_x = vid.width - 1; + if (mousecursor_x >= vid.width) + mousecursor_x = vid.width - 1; - if (mousecursor_y >= vid.height) - mousecursor_y = vid.height - 1; - mx=my=0; + if (mousecursor_y >= vid.height) + mousecursor_y = vid.height - 1; + mx=my=0; + } #ifdef PEXT_CSQC CSQC_MousePosition(mousecursor_x, mousecursor_y, mouse->qdeviceid); @@ -350,25 +347,25 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum) if (mouse->type == M_TOUCH) { - if (m_strafeonright.ival && mouse->downpos[0] > vid.pixelwidth/2 && movements != NULL && (key_dest == key_game)) - { - //if they're strafing, calculate the speed to move at based upon their displacement - if (mouse->down) - { - mx = (mouse->oldpos[0] - mouse->downpos[0])*0.1; - my = (mouse->oldpos[1] - mouse->downpos[1])*0.1; - } - else - { - mx = 0; - my = 0; - } - strafe_x = true; - strafe_y = true; - } - else - { - strafe_x = false; + if (m_strafeonright.ival && mouse->downpos[0] > vid.pixelwidth/2 && movements != NULL && (key_dest == key_game)) + { + //if they're strafing, calculate the speed to move at based upon their displacement + if (mouse->down) + { + mx = (mouse->oldpos[0] - mouse->downpos[0])*0.1; + my = (mouse->oldpos[1] - mouse->downpos[1])*0.1; + } + else + { + mx = 0; + my = 0; + } + strafe_x = true; + strafe_y = true; + } + else + { + strafe_x = false; strafe_y = false; } } @@ -449,15 +446,15 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum) else movements[0] -= m_forward.value * mouse_y; } -} - -void IN_Move (float *movements, int pnum) -{ - int i; - INS_Move(movements, pnum); - for (i = 0; i < MAXPOINTERS; i++) - IN_MoveMouse(&ptr[i], movements, pnum); -} +} + +void IN_Move (float *movements, int pnum) +{ + int i; + INS_Move(movements, pnum); + for (i = 0; i < MAXPOINTERS; i++) + IN_MoveMouse(&ptr[i], movements, pnum); +} void IN_KeyEvent(int devid, int down, int keycode, int unicode) { diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 1580b364..b6fc0509 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -56,6 +56,7 @@ static cvar_t m_filter = CVAR("m_filter","0"); static cvar_t m_accel = CVAR("m_accel", "0"); static cvar_t in_dinput = CVARF("in_dinput","0", CVAR_ARCHIVE); static cvar_t in_builtinkeymap = CVARF("in_builtinkeymap", "0", CVAR_ARCHIVE); +static cvar_t in_simulatemultitouch = CVAR("in_simulatemultitouch", "0"); static cvar_t m_accel_noforce = CVAR("m_accel_noforce", "0"); static cvar_t m_threshold_noforce = CVAR("m_threshold_noforce", "0"); @@ -63,6 +64,9 @@ static cvar_t m_threshold_noforce = CVAR("m_threshold_noforce", "0"); static cvar_t cl_keypad = CVAR("cl_keypad", "0"); extern cvar_t cl_forcesplitclient; +extern float multicursor_x[8], multicursor_y[8]; +extern qboolean multicursor_active[8]; + typedef struct { union { HANDLE rawinputhandle; @@ -509,7 +513,7 @@ void INS_UpdateGrabs(int fullscreen, int activeapp) if (!activeapp) grabmouse = false; - else if (fullscreen) + else if (fullscreen || in_simulatemultitouch.ival) grabmouse = true; else if (_windowed_mouse.value) { @@ -781,6 +785,7 @@ void INS_RawInput_DeInit(void) Z_Free(rawkbd); rawkbdcount = 0; } + memset(multicursor_active, 0, sizeof(multicursor_active)); } #endif @@ -1089,6 +1094,7 @@ void INS_Init (void) Cvar_Register (&in_dinput, "Input Controls"); Cvar_Register (&in_builtinkeymap, "Input Controls"); + Cvar_Register (&in_simulatemultitouch, "Input Controls"); Cvar_Register (&m_accel_noforce, "Input Controls"); Cvar_Register (&m_threshold_noforce, "Input Controls"); @@ -1214,7 +1220,6 @@ INS_MouseMove */ void INS_MouseMove (float *movements, int pnum) { - extern int mousecursor_x, mousecursor_y; extern int window_x, window_y; #ifdef AVAIL_DINPUT @@ -1327,7 +1332,7 @@ potentially called multiple times per frame. */ void INS_Accumulate (void) { - POINT current_pos; + static POINT current_pos; //static to avoid bugs in vista with largeaddressaware (this is fixed in win7). fixed exe base address prevents this from going above 2gb. if (mouseactive && !dinput) { @@ -1372,14 +1377,32 @@ void INS_RawInput_MouseRead(void) return; mouse = &rawmice[i]; + multicursor_active[mouse->qdeviceid&7] = 0; + // movement if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) { + if (in_simulatemultitouch.ival) + { + multicursor_active[mouse->qdeviceid&7] = true; + multicursor_x[mouse->qdeviceid&7] = raw->data.mouse.lLastX; + multicursor_y[mouse->qdeviceid&7] = raw->data.mouse.lLastY; + } IN_MouseMove(mouse->qdeviceid, true, raw->data.mouse.lLastX, raw->data.mouse.lLastY, 0, 0); } else // RELATIVE { - IN_MouseMove(mouse->qdeviceid, false, raw->data.mouse.lLastX, raw->data.mouse.lLastY, 0, 0); + if (in_simulatemultitouch.ival) + { + multicursor_active[mouse->qdeviceid&7] = true; + multicursor_x[mouse->qdeviceid&7] += raw->data.mouse.lLastX; + multicursor_y[mouse->qdeviceid&7] += raw->data.mouse.lLastY; + multicursor_x[mouse->qdeviceid&7] = bound(0, multicursor_x[mouse->qdeviceid&7], vid.pixelwidth); + multicursor_y[mouse->qdeviceid&7] = bound(0, multicursor_y[mouse->qdeviceid&7], vid.pixelheight); + IN_MouseMove(mouse->qdeviceid, true, multicursor_x[mouse->qdeviceid&7], multicursor_y[mouse->qdeviceid&7], 0, 0); + } + else + IN_MouseMove(mouse->qdeviceid, false, raw->data.mouse.lLastX, raw->data.mouse.lLastY, 0, 0); } // buttons diff --git a/engine/client/input.h b/engine/client/input.h index 95ab8c73..b9f99837 100644 --- a/engine/client/input.h +++ b/engine/client/input.h @@ -33,6 +33,9 @@ void IN_Move (float *movements, int pnum); extern cvar_t in_xflip; +extern float mousecursor_x, mousecursor_y; +extern float mousemove_x, mousemove_y; + #ifdef _SDL void IN_ActivateMouse(void); void IN_DeactivateMouse(void); diff --git a/engine/client/keys.c b/engine/client/keys.c index 8b3a8252..a98e0aff 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -411,8 +411,6 @@ void Con_Selectioncolour_Callback(struct cvar_s *var, char *oldvalue) qboolean Key_GetConsoleSelectionBox(int *sx, int *sy, int *ex, int *ey) { - extern int mousecursor_x, mousecursor_y; - *sx = *sy = *ex = *ey = 0; if (con_mousedown[2] == 1) @@ -641,6 +639,12 @@ void Key_DefaultLinkClicked(char *text, char *info) Cbuf_AddText(va("\ncmd %s\n", c), RESTRICT_LOCAL); return; } + c = Info_ValueForKey(info, "edit"); + if (*c && !strchr(c, ';') && !strchr(c, '\n')) + { + Cbuf_AddText(va("\nedit %s\n", c), RESTRICT_LOCAL); + return; + } c = Info_ValueForKey(info, "impulse"); if (*c && !strchr(c, ';') && !strchr(c, '\n')) { @@ -657,7 +661,6 @@ void Key_DefaultLinkClicked(char *text, char *info) void Key_ConsoleRelease(int key, int unicode) { - extern int mousecursor_x, mousecursor_y; char *buffer; if (key == K_MOUSE1) { @@ -860,7 +863,6 @@ void Key_Console (unsigned int unicode, int key) if ((key == K_MOUSE1 || key == K_MOUSE2)) { extern cvar_t vid_conwidth, vid_conheight; - extern int mousecursor_x, mousecursor_y; int xpos, ypos; xpos = (int)((mousecursor_x*vid.width)/(vid.pixelwidth*8)); ypos = (int)((mousecursor_y*vid.height)/(vid.pixelheight*8)); diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 6d4cf1c4..14030b4a 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -336,13 +336,12 @@ static qboolean MI_Selectable(menuoption_t *op) static void M_CheckMouseMove(void) { - extern int mousecursor_x, mousecursor_y; qboolean foundexclusive = false; int mgt; menu_t *menu; menuoption_t *option; - if (omousex != mousecursor_x || omousey != mousecursor_y) + if (omousex != (int)mousecursor_x || omousey != (int)mousecursor_y) mousemoved = true; else mousemoved = false; @@ -1514,31 +1513,6 @@ void M_MenuPop_f (void) M_RemoveMenu(firstmenu); } - -void DrawCursor(int prydoncursornum) -{ - extern int mousecursor_x, mousecursor_y; - mpic_t *p; - if (!*cl_cursor.string) - p = NULL; - else - p = R2D_SafeCachePic(cl_cursor.string); - if (p) - { - R2D_ImageColours(1, 1, 1, 1); - R2D_Image(mousecursor_x-cl_cursorbias.value, mousecursor_y-cl_cursorbias.value, cl_cursorsize.value, cl_cursorsize.value, 0, 0, 1, 1, p); - } - else - { - int x, y; - Font_BeginString(font_conchar, mousecursor_x, mousecursor_y, &x, &y); - x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; - y -= Font_CharHeight()/2; - Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK); - Font_EndString(font_conchar); - } -} - void M_Complex_Draw(void) { menu_t *menu, *cmenu; diff --git a/engine/client/m_master.c b/engine/client/m_master.c index 25bf0ac4..602ea965 100644 --- a/engine/client/m_master.c +++ b/engine/client/m_master.c @@ -92,7 +92,6 @@ static void SL_DrawColumnTitle (int *x, int y, int xlen, int mx, char *str, qboo static void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu) { int sf = Master_GetSortField(); - extern int mousecursor_x, mousecursor_y; int mx = mousecursor_x; qboolean filldraw = false; qbyte clr; @@ -117,7 +116,6 @@ static void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu) static qboolean SL_TitlesKey (menucustom_t *ths, menu_t *menu, int key) { int x; - extern int mousecursor_x, mousecursor_y; int mx = mousecursor_x/8; int sortkey; @@ -215,7 +213,6 @@ static servertypes_t flagstoservertype(int flags) static void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu) { - extern int mousecursor_x, mousecursor_y; serverlist_t *info = (serverlist_t*)(menu + 1); serverinfo_t *si; int thisone = (int)ths->data + info->scrollpos; @@ -264,7 +261,6 @@ static qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key) static int lastclick; int curtime; int oldselection; - extern int mousecursor_x, mousecursor_y; serverlist_t *info = (serverlist_t*)(menu + 1); serverinfo_t *server; char adr[MAX_ADR_SIZE]; @@ -465,7 +461,6 @@ static void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu) extern qboolean keydown[K_MAX]; if (keydown[K_MOUSE1]) { - extern int mousecursor_x, mousecursor_y; float my; serverlist_t *info = (serverlist_t*)(menu + 1); @@ -495,7 +490,6 @@ static qboolean SL_SliderKey (menucustom_t *ths, menu_t *menu, int key) { if (key == K_MOUSE1) { - extern int mousecursor_x, mousecursor_y; float my; serverlist_t *info = (serverlist_t*)(menu + 1); @@ -658,10 +652,16 @@ void M_Menu_ServerList2_f(void) MC_AddCheckBox(menu, 0, vid.height - 64+8*6, "Fraglimit", &sb_showfraglimit, 1); MC_AddCheckBox(menu, 0, vid.height - 64+8*7, "Timelimit", &sb_showtimelimit, 1); +#ifdef NQPROT MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*1, "List NQ ", SL_ReFilter, 1); +#endif MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*2, "List QW ", SL_ReFilter, 2); +#ifdef Q2CLIENT MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*3, "List Q2 ", SL_ReFilter, 3); +#endif +#ifdef Q3CLIENT MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*4, "List Q3 ", SL_ReFilter, 4); +#endif MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*5, "Only Favs ", SL_ReFilter, 5); MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*6, "Hide Empty", SL_ReFilter, 6); MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*7, "Hide Full ", SL_ReFilter, 7); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 6abab3a2..4655d007 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -2241,10 +2241,7 @@ qboolean Media_ShowFilm(void) else { if (cin->cursormove) - { - extern int mousecursor_x, mousecursor_y; cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height); - } if (cin->setsize) cin->setsize(cin, vid.pixelwidth, vid.pixelheight); @@ -3794,7 +3791,7 @@ void Media_Init(void) Cvar_Register(&capturesoundbits, "AVI capture controls"); Cvar_Register(&capturesoundchannels, "AVI capture controls"); -// S_RegisterSoundInputPlugin(S_LoadMP3Sound); + S_RegisterSoundInputPlugin(S_LoadMP3Sound); #endif #endif diff --git a/engine/client/m_options.c b/engine/client/m_options.c index cd75e529..3d35d60b 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -87,6 +87,7 @@ void M_Menu_Options_f (void) MB_SPACING(4), // removed hud options (cl_sbar, cl_hudswap, old-style chat, old-style msg) MB_CONSOLECMD("Video Options", "menu_video\n", "Set video resolution, color depth, refresh rate, and anti-aliasing options."), + MB_CONSOLECMD("Graphics Presets", "fps_preset\n", "Choose a different graphical preset to use."), MB_CONSOLECMD("Audio Options", "menu_audio\n", "Set audio quality and speaker setup options."), MB_SPACING(4), MB_CONSOLECMD("FPS Options", "menu_fps\n", "Set model filtering and graphical profile options."), diff --git a/engine/client/m_script.c b/engine/client/m_script.c index 7fe62d75..049cf51e 100644 --- a/engine/client/m_script.c +++ b/engine/client/m_script.c @@ -215,11 +215,11 @@ void M_MenuS_TextBig_f (void) Con_Printf("%s with no active menu\n", Cmd_Argv(0)); return; } - if (*command) + if (!*command) MC_AddConsoleCommandQBigFont(menu_script, x, y, text, command); else { - option = (menuoption_t *)MC_AddConsoleCommand(menu_script, x, y, text, va("set option %s\n%s\n", command, menualias.string)); + option = (menuoption_t *)MC_AddConsoleCommandQBigFont(menu_script, x, y, text, va("set option %s\n%s\n", command, menualias.string)); if (selectitem-- == 0) menu_script->selecteditem = option; } diff --git a/engine/client/menu.c b/engine/client/menu.c index 3b7edfc4..a9dd596c 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -1076,7 +1076,11 @@ void M_Draw (int uimenu) if ((!menu_script || scr_con_current) && !m_recursiveDraw) { - R2D_FadeScreen (); + extern menu_t *firstmenu; + if (m_state == m_complex && firstmenu && firstmenu->selecteditem && firstmenu->selecteditem->common.type == mt_slider && (firstmenu->selecteditem->slider.var == &v_gamma || firstmenu->selecteditem->slider.var == &v_contrast)) + /*no menu tint if we're trying to adjust gamma*/; + else + R2D_FadeScreen (); } else { diff --git a/engine/client/merged.h b/engine/client/merged.h index 137e4d25..40f747fb 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -1,5 +1,5 @@ //These are defined later in the source tree. This file should probably be moved to a later spot. -struct progfuncs_s; +struct pubprogfuncs_s; struct globalvars_s; struct texture_s; struct texnums_s; @@ -30,7 +30,7 @@ typedef struct { #endif int endbone; - } g[2]; + } g[FS_COUNT]; float *bonestate; int bonecount; diff --git a/engine/client/net_master.c b/engine/client/net_master.c index a1db5a1e..d5000c67 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -1550,7 +1550,6 @@ void MasterInfo_Refresh(void) //Master_AddMaster("telefrag.me:27000",MT_MASTERQW, "Telefrag.ME"); //Master_AddMaster("master.teamdamage.com:27000", MT_MASTERQW, "TeamDamage"); Master_AddMaster("master.quakeservers.net:27000", MT_MASTERQW, "QuakeServers.net"); - Master_AddMaster("qwmaster.fodquake.net:27000", MT_MASTERQW, "Fodquake.net"); Master_AddMaster("masterserver.exhale.de:27000", MT_MASTERQW, "team exhale"); Master_AddMaster("qwmaster.fodquake.net:27000", MT_MASTERQW, "Fodquake master server."); Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server."); diff --git a/engine/client/p_classic.c b/engine/client/p_classic.c index a6033f41..65cce06d 100644 --- a/engine/client/p_classic.c +++ b/engine/client/p_classic.c @@ -380,7 +380,7 @@ static void PClassic_DrawParticles(void) dvel = 4 * frametime; #ifdef POLYS - if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader) + if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader && cl_stris[cl_numstris-1].numvert + 8 <= MAX_INDICIES) scenetri = &cl_stris[cl_numstris-1]; else { @@ -391,6 +391,7 @@ static void PClassic_DrawParticles(void) } scenetri = &cl_stris[cl_numstris++]; scenetri->shader = classicshader; + scenetri->flags = BEF_NODLIGHT|BEF_NOSHADOWS; scenetri->firstidx = cl_numstrisidx; scenetri->firstvert = cl_numstrisvert; scenetri->numvert = 0; diff --git a/engine/client/p_script.c b/engine/client/p_script.c index ca77232f..621205f2 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -67,6 +67,7 @@ static int pe_default = P_INVALID; static int pe_size2 = P_INVALID; static int pe_size3 = P_INVALID; static int pe_defaulttrail = P_INVALID; +static qboolean pe_script_enabled; static float psintable[256]; @@ -481,7 +482,7 @@ static int PScript_FindParticleType(char *name) static void P_SetModified(void) //called when the particle system changes (from console). { - if (Cmd_FromGamecode()) + if (Cmd_IsInsecure()) return; //server stuffed particle descriptions don't count. f_modified_particles = true; @@ -698,6 +699,28 @@ static void P_ParticleEffect_f(void) return; } + if (!pe_script_enabled) + { + int depth = 1; + while(1) + { + buf = Cbuf_GetNext(Cmd_ExecLevel, false); + if (!*buf) + return; + + while (*buf && *buf <= ' ') + buf++; //no whitespace please. + if (*buf == '{') + depth++; + else if (*buf == '}') + { + if (--depth == 0) + break; + } + } + return; + } + var = Cmd_Argv(1); if (*var == '+') { @@ -2124,6 +2147,7 @@ static qboolean PScript_InitParticles (void) Cmd_AddCommand("pointfile", P_ReadPointFile_f); //load the leak info produced from qbsp into the particle system to show a line. :) Cmd_AddCommand("r_part", P_ParticleEffect_f); + pe_script_enabled = true; Cmd_AddCommand("r_exportbuiltinparticles", P_ExportBuiltinSet_f); Cmd_AddCommand("r_importeffectinfo", P_ImportEffectInfo_f); @@ -2174,6 +2198,8 @@ static qboolean PScript_InitParticles (void) static void PScript_Shutdown (void) { + pe_script_enabled = false; + if (fallback) fallback->ShutdownParticles(); @@ -2181,8 +2207,6 @@ static void PScript_Shutdown (void) Cmd_RemoveCommand("pointfile"); //load the leak info produced from qbsp into the particle system to show a line. :) - Cmd_RemoveCommand("r_part"); - Cmd_RemoveCommand("r_exportbuiltinparticles"); Cmd_RemoveCommand("r_importeffectinfo"); @@ -4456,37 +4480,40 @@ static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type) } } -static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *type) +static void R_AddLineSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type) { -#ifdef warningmsg -#pragma warningmsg("fixme: no line sparks") -#endif -#if 0 - particle_t *p; + vec3_t v, cr, o2; + float scale; - qglDisable(GL_TEXTURE_2D); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); - - while (count--) + if (cl_numstrisvert+2 > cl_maxstrisvert) { - p = *plist++; - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3f (p->org[0], p->org[1], p->org[2]); - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); + cl_maxstrisvert+=64*2; + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert); } - qglEnd(); -#endif + + Vector4Copy(p->rgba, cl_strisvertc[cl_numstrisvert+0]); + VectorCopy(p->rgba, cl_strisvertc[cl_numstrisvert+1]); + cl_strisvertc[cl_numstrisvert+1][3] = 0; + Vector2Set(cl_strisvertt[cl_numstrisvert+0], p->s1, p->t1); + Vector2Set(cl_strisvertt[cl_numstrisvert+1], p->s2, p->t2); + + VectorCopy(p->org, cl_strisvertv[cl_numstrisvert+0]); + VectorMA(p->org, -1/10, p->vel, cl_strisvertv[cl_numstrisvert+1]); + + if (cl_numstrisidx+2 > cl_maxstrisidx) + { + cl_maxstrisidx += 64*2; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 0; + cl_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 1; + + cl_numstrisvert += 2; + + t->numvert += 2; + t->numidx += 2; } static void R_AddTSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type) @@ -4892,9 +4919,9 @@ static void R_AddTexturedParticle(scenetris_t *t, particle_t *p, plooks_t *type) static void PScript_DrawParticleTypes (void) { - void (*sparklineparticles)(int count, particle_t **,plooks_t*)=GL_DrawLineSparkParticle; - void (*sparkfanparticles)(int count, particle_t **,plooks_t*)=GL_DrawTrifanParticle; - void (*sparktexturedparticles)(int count, particle_t **,plooks_t*)=GL_DrawTexturedSparkParticle; + void (*sparklineparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=R_AddLineSparkParticle; + void (*sparkfanparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=GL_DrawTrifanParticle; + void (*sparktexturedparticles)(scenetris_t *t, particle_t *p, plooks_t *type)=GL_DrawTexturedSparkParticle; qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal); void *pdraw, *bdraw; @@ -4984,7 +5011,7 @@ static void PScript_DrawParticleTypes (void) { if (type->clippeddecals) { - if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader) + if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS)) scenetri = &cl_stris[cl_numstris-1]; else { @@ -4995,6 +5022,7 @@ static void PScript_DrawParticleTypes (void) } scenetri = &cl_stris[cl_numstris++]; scenetri->shader = type->looks.shader; + scenetri->flags = BEF_NODLIGHT|BEF_NOSHADOWS; scenetri->firstidx = cl_numstrisidx; scenetri->firstvert = cl_numstrisvert; scenetri->numvert = 0; @@ -5096,7 +5124,7 @@ static void PScript_DrawParticleTypes (void) if (!tdraw || type->looks.shader->sort == SHADER_SORT_BLEND) scenetri = NULL; - else if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader) + else if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS)) scenetri = &cl_stris[cl_numstris-1]; else { @@ -5109,6 +5137,7 @@ static void PScript_DrawParticleTypes (void) scenetri->shader = type->looks.shader; scenetri->firstidx = cl_numstrisidx; scenetri->firstvert = cl_numstrisvert; + scenetri->flags = BEF_NODLIGHT|BEF_NOSHADOWS; scenetri->numvert = 0; scenetri->numidx = 0; } diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index a1406a22..4660b769 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -48,7 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define QCEditor NULL #endif -static progfuncs_t *csqcprogs; +static pubprogfuncs_t *csqcprogs; typedef struct csqctreadstate_s { float resumetime; @@ -60,7 +60,7 @@ typedef struct csqctreadstate_s { } csqctreadstate_t; static qboolean csprogs_promiscuous; -static unsigned int csprogs_checksum, csaddon_checksum; +static unsigned int csprogs_checksum; static csqctreadstate_t *csqcthreads; qboolean csqc_resortfrags; qboolean csqc_drawsbar; @@ -261,6 +261,8 @@ static void CSQC_FindGlobals(void) csqc_world.g.v_forward = csqcg.forward; csqc_world.g.v_right = csqcg.right; csqc_world.g.v_up = csqcg.up; + csqc_world.g.drawfont = (float*)PR_FindGlobal(csqcprogs, "drawfont", 0, NULL); + csqc_world.g.drawfontscale = (float*)PR_FindGlobal(csqcprogs, "drawfontscale", 0, NULL); if (!csqc_world.g.physics_mode) csqc_world.g.physics_mode = &csphysicsmode; @@ -269,7 +271,7 @@ static void CSQC_FindGlobals(void) *csqcg.maxclients = cl.allocated_client_slots; } -static void QCBUILTIN PF_cs_gettime (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gettime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int timer = G_FLOAT(OFS_PARM0); switch(timer) @@ -471,14 +473,14 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t out->bonecount = 0; out->bonestate = NULL; +#if defined(SKELETALOBJECTS) || defined(RAGDOLL) if (in->xv->skeletonindex) - { skel_lookup(csqcprogs, in->xv->skeletonindex, out); - } +#endif } -static void QCBUILTIN PF_cs_remove (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_remove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ed; @@ -495,7 +497,7 @@ static void QCBUILTIN PF_cs_remove (progfuncs_t *prinst, struct globalvars_s *pr ED_Free (prinst, (void*)ed); } -static void QCBUILTIN PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { cvar_t *var; char *str; @@ -523,14 +525,14 @@ static void QCBUILTIN PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_glob } //too specific to the prinst's builtins. -static void QCBUILTIN PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Fixme (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf("\n"); prinst->RunError(prinst, "\nBuiltin %i not implemented.\nCSQC is not compatible.", prinst->lastcalledbuiltinnumber); PR_BIError (prinst, "bulitin not implemented"); } -static void QCBUILTIN PF_NoCSQC (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_NoCSQC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf("\n"); @@ -538,13 +540,13 @@ static void QCBUILTIN PF_NoCSQC (progfuncs_t *prinst, struct globalvars_s *pr_gl PR_BIError (prinst, "bulitin not implemented"); } -static void QCBUILTIN PF_cl_cprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_cprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PF_VarString(prinst, 0, pr_globals); SCR_CenterPrint(csqc_lplayernum, str, true); } -static void QCBUILTIN PF_cs_makevectors (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_makevectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (!csqcg.forward || !csqcg.right || !csqcg.up) Host_EndGame("PF_makevectors: one of v_forward, v_right or v_up was not defined\n"); @@ -640,11 +642,24 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) } ival = in->v->colormap; + out->playerindex = -1; if (ival > 0 && ival <= MAX_CLIENTS) { - out->scoreboard = &cl.players[ival-1]; + out->playerindex = ival - 1; + out->topcolour = cl.players[ival-1].ttopcolor; + out->bottomcolour = cl.players[ival-1].tbottomcolor; + } + else if (ival >= 1024) + { + //DP COLORMAP extension + out->topcolour = (ival>>4) & 0x0f; + out->bottomcolour = ival & 0xf; + } + else + { + out->topcolour = TOP_DEFAULT; + out->bottomcolour = BOTTOM_DEFAULT; } - // TODO: DP COLORMAP extension? if (!in->xv->colormod[0] && !in->xv->colormod[1] && !in->xv->colormod[2]) { @@ -684,7 +699,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) return true; } -static void QCBUILTIN PF_cs_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //still does a remove. csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0); entity_t *ent; @@ -705,7 +720,7 @@ static void QCBUILTIN PF_cs_makestatic (progfuncs_t *prinst, struct globalvars_s PF_cs_remove(prinst, pr_globals); } -static void QCBUILTIN PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_AddEntity(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0); entity_t ent; @@ -716,10 +731,25 @@ static void QCBUILTIN PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *p } if (CopyCSQCEdictToEntity(in, &ent)) + { + CLQ1_AddShadow(&ent); V_AddAxisEntity(&ent); + } +} +void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t rgbvalue, float alphavalue); +static void QCBUILTIN PF_R_AddDecal(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + shader_t *shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL); + float *org = G_VECTOR(OFS_PARM1); + float *up = G_VECTOR(OFS_PARM2); + float *side = G_VECTOR(OFS_PARM3); + float *rgb = G_VECTOR(OFS_PARM4); + float alpha = G_FLOAT(OFS_PARM5); + if (shader) + CL_AddDecal(shader, org, up, side, rgb, alpha); } -static void QCBUILTIN PF_R_DynamicLight_Set(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; dlight_t *l; @@ -787,7 +817,7 @@ static void QCBUILTIN PF_R_DynamicLight_Set(progfuncs_t *prinst, struct globalva break; } } -static void QCBUILTIN PF_R_DynamicLight_Get(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { dlight_t *l; unsigned int lno = G_FLOAT(OFS_PARM0); @@ -848,14 +878,14 @@ static void QCBUILTIN PF_R_DynamicLight_Get(progfuncs_t *prinst, struct globalva } } -static void QCBUILTIN PF_R_DynamicLight_Add(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_DynamicLight_Add(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float radius = G_FLOAT(OFS_PARM1); float *rgb = G_VECTOR(OFS_PARM2); - float style = (*prinst->callargc > 3)?G_FLOAT(OFS_PARM3):0; - char *cubemapname = (*prinst->callargc > 4)?PR_GetStringOfs(prinst, OFS_PARM4):""; - int pflags = (*prinst->callargc > 5)?G_FLOAT(OFS_PARM5):PFLAGS_CORONA; + float style = (prinst->callargc > 3)?G_FLOAT(OFS_PARM3):0; + char *cubemapname = (prinst->callargc > 4)?PR_GetStringOfs(prinst, OFS_PARM4):""; + int pflags = (prinst->callargc > 5)?G_FLOAT(OFS_PARM5):PFLAGS_CORONA; wedict_t *self = PROG_TO_WEDICT(prinst, *csqcg.self); dlight_t *dl; @@ -873,7 +903,7 @@ static void QCBUILTIN PF_R_DynamicLight_Add(progfuncs_t *prinst, struct globalva G_FLOAT(OFS_RETURN) = dl - cl_dlights; } -static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_AddEntityMask(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int mask = G_FLOAT(OFS_PARM0); csqcedict_t *ent; @@ -911,7 +941,10 @@ static void QCBUILTIN PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_ } if (CopyCSQCEdictToEntity(ent, &rent)) + { + CLQ1_AddShadow(&rent); V_AddAxisEntity(&rent); + } } } *csqcg.self = oldself; @@ -934,17 +967,18 @@ static shader_t *csqc_poly_shader; static int csqc_poly_startvert; static int csqc_poly_startidx; static int csqc_poly_flags; + // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) -static void QCBUILTIN PF_R_PolygonBegin(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_R_PolygonBegin(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqc_poly_shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL); csqc_poly_startvert = cl_numstrisvert; csqc_poly_startidx = cl_numstrisidx; - csqc_poly_flags = (*prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0; + csqc_poly_flags = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0; } // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) -static void QCBUILTIN PF_R_PolygonVertex(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_R_PolygonVertex(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (cl_numstrisvert == cl_maxstrisvert) { @@ -962,17 +996,18 @@ static void QCBUILTIN PF_R_PolygonVertex(progfuncs_t *prinst, struct globalvars_ } // #308 void() R_EndPolygon (EXT_CSQC_???) -static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { scenetris_t *t; int i; int nv; + int flags = BEF_NOSHADOWS; if (!csqc_poly_shader) return; /*if the shader didn't change, continue with the old poly*/ - if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_poly_shader) + if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_poly_shader && cl_stris[cl_numstris-1].flags == flags) t = &cl_stris[cl_numstris-1]; else { @@ -983,6 +1018,7 @@ static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s * } t = &cl_stris[cl_numstris++]; t->shader = csqc_poly_shader; + t->flags = flags; t->firstidx = cl_numstrisidx; t->firstvert = csqc_poly_startvert; t->numvert = 0; @@ -1037,7 +1073,7 @@ static void QCBUILTIN PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s * qboolean csqc_rebuildmatricies; float csqc_proj_matrix[16]; float csqc_proj_matrix_inverse[16]; - void buildmatricies(void) +void buildmatricies(void) { float modelview[16]; float proj[16]; @@ -1054,7 +1090,7 @@ float csqc_proj_matrix_inverse[16]; csqc_rebuildmatricies = false; } -static void QCBUILTIN PF_cs_project (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_project (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (csqc_rebuildmatricies) buildmatricies(); @@ -1087,7 +1123,7 @@ static void QCBUILTIN PF_cs_project (progfuncs_t *prinst, struct globalvars_s *p out[2] *= -1; } } -static void QCBUILTIN PF_cs_unproject (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_unproject (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (csqc_rebuildmatricies) buildmatricies(); @@ -1121,9 +1157,9 @@ static void QCBUILTIN PF_cs_unproject (progfuncs_t *prinst, struct globalvars_s //float CalcFov (float fov_x, float width, float height); //clear scene, and set up the default stuff. -static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_ClearScene (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - if (*prinst->callargc > 0) + if (prinst->callargc > 0) CSQC_ChangeLocalPlayer(G_FLOAT(OFS_PARM0)); csqc_rebuildmatricies = true; @@ -1137,8 +1173,10 @@ static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s CL_PredictMove (); } +#if defined(SKELETALOBJECTS) || defined(RAGDOLLS) skel_dodelete(csqcprogs); - CL_SwapEntityLists(); +#endif + CL_ClearEntityLists(); V_CalcRefdef(csqc_lplayernum); //set up the defaults (for player 0) @@ -1146,7 +1184,7 @@ static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s csqc_drawsbar = false; } -static void QCBUILTIN PF_R_GetViewFlag(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_GetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { viewflags parametertype = G_FLOAT(OFS_PARM0); float *r = G_VECTOR(OFS_RETURN); @@ -1274,12 +1312,12 @@ static void QCBUILTIN PF_R_GetViewFlag(progfuncs_t *prinst, struct globalvars_s } } -static void QCBUILTIN PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { viewflags parametertype = G_FLOAT(OFS_PARM0); float *p = G_VECTOR(OFS_PARM1); - if (*prinst->callargc < 2) + if (prinst->callargc < 2) { csqc_deprecated("PF_R_SetViewFlag called with wrong argument count\n"); PF_R_GetViewFlag(prinst, pr_globals); @@ -1308,9 +1346,9 @@ static void QCBUILTIN PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s { float frustumx, frustumy; frustumy = tan(p[0] * (M_PI/360)) * 0.75; - if (*prinst->callargc > 2) + if (prinst->callargc > 2) frustumy *= G_FLOAT(OFS_PARM2); - frustumx = frustumy * vid.width / vid.height /* / vid.pixelheight*/; + frustumx = (frustumy * r_refdef.vrect.width) / r_refdef.vrect.height /* / vid.pixelheight*/; r_refdef.fov_x = atan2(frustumx, 1) * (360/M_PI); r_refdef.fov_y = atan2(frustumy, 1) * (360/M_PI); } @@ -1402,7 +1440,7 @@ static void QCBUILTIN PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s } void R2D_PolyBlend (void); -static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (cl.worldmodel) R_PushDlights (); @@ -1433,21 +1471,21 @@ static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s R2D_DrawCrosshair(); } -static void QCBUILTIN PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getstati(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int stnum = G_FLOAT(OFS_PARM0); G_INT(OFS_RETURN) = cl.playerview[csqc_lplayernum].stats[stnum]; } -static void QCBUILTIN PF_cs_getstatbits(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getstatbits(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //convert an int stat into a qc float. int stnum = G_FLOAT(OFS_PARM0); int val = cl.playerview[csqc_lplayernum].stats[stnum]; - if (*prinst->callargc > 1) + if (prinst->callargc > 1) { int first, count; first = G_FLOAT(OFS_PARM1); - if (*prinst->callargc > 2) + if (prinst->callargc > 2) count = G_FLOAT(OFS_PARM2); else count = 1; @@ -1456,7 +1494,7 @@ static void QCBUILTIN PF_cs_getstatbits(progfuncs_t *prinst, struct globalvars_s else G_FLOAT(OFS_RETURN) = cl.playerview[csqc_lplayernum].statsf[stnum]; } -static void QCBUILTIN PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getstats(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int stnum = G_FLOAT(OFS_PARM0); @@ -1476,7 +1514,7 @@ static void QCBUILTIN PF_cs_getstats(progfuncs_t *prinst, struct globalvars_s *p RETURN_TSTRING(out);*/ } -static void QCBUILTIN PF_cs_SetOrigin(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_SetOrigin(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0); float *org = G_VECTOR(OFS_PARM1); @@ -1486,7 +1524,7 @@ static void QCBUILTIN PF_cs_SetOrigin(progfuncs_t *prinst, struct globalvars_s * World_LinkEdict(&csqc_world, (wedict_t*)ent, false); } -static void QCBUILTIN PF_cs_SetSize(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_SetSize(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0); float *mins = G_VECTOR(OFS_PARM1); @@ -1518,7 +1556,7 @@ static void cs_settracevars(trace_t *tr) *csqcg.trace_ent = EDICT_TO_PROG(csqcprogs, (void*)csqc_world.edicts); } -static void QCBUILTIN PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_traceline(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *v1, *v2, *mins, *maxs; trace_t trace; @@ -1549,7 +1587,7 @@ static void QCBUILTIN PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s * cs_settracevars(&trace); } -static void QCBUILTIN PF_cs_tracebox(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_tracebox(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *v1, *v2, *mins, *maxs; trace_t trace; @@ -1614,7 +1652,7 @@ static trace_t CS_Trace_Toss (csqcedict_t *tossent, csqcedict_t *ignore) trace.fraction = 0; // not relevant return trace; } -static void QCBUILTIN PF_cs_tracetoss (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_tracetoss (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { trace_t trace; csqcedict_t *ent; @@ -1630,7 +1668,7 @@ static void QCBUILTIN PF_cs_tracetoss (progfuncs_t *prinst, struct globalvars_s cs_settracevars(&trace); } -static void QCBUILTIN PF_cs_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_pointcontents(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; @@ -1681,7 +1719,7 @@ static int FindModel(char *name, int *free) return 0; } -static void csqc_setmodel(progfuncs_t *prinst, csqcedict_t *ent, int modelindex) +static void csqc_setmodel(pubprogfuncs_t *prinst, csqcedict_t *ent, int modelindex) { model_t *model; @@ -1716,7 +1754,7 @@ static void csqc_setmodel(progfuncs_t *prinst, csqcedict_t *ent, int modelindex) World_LinkEdict(&csqc_world, (wedict_t*)ent, false); } -static void QCBUILTIN PF_cs_SetModel(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_SetModel(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0); char *modelname = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1736,14 +1774,14 @@ static void QCBUILTIN PF_cs_SetModel(progfuncs_t *prinst, struct globalvars_s *p csqc_setmodel(prinst, ent, modelindex); } -static void QCBUILTIN PF_cs_SetModelIndex(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_SetModelIndex(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (void*)G_EDICT(prinst, OFS_PARM0); int modelindex = G_FLOAT(OFS_PARM1); csqc_setmodel(prinst, ent, modelindex); } -static void QCBUILTIN PF_cs_PrecacheModel(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int modelindex, freei; char *modelname = PR_GetStringOfs(prinst, OFS_PARM0); @@ -1781,14 +1819,14 @@ static void QCBUILTIN PF_cs_PrecacheModel(progfuncs_t *prinst, struct globalvars G_FLOAT(OFS_RETURN) = modelindex; } -static void QCBUILTIN PF_cs_PrecacheSound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_PrecacheSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *soundname = PR_GetStringOfs(prinst, OFS_PARM0); Sound_CheckDownload(soundname); S_PrecacheSound(soundname); } -static void QCBUILTIN PF_cs_ModelnameForIndex(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_ModelnameForIndex(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int modelindex = G_FLOAT(OFS_PARM0); @@ -1798,7 +1836,7 @@ static void QCBUILTIN PF_cs_ModelnameForIndex(progfuncs_t *prinst, struct global G_INT(OFS_RETURN) = (int)PR_SetString(prinst, cl.model_name[modelindex]); } -static void QCBUILTIN PF_ReadByte(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadByte(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (csqc_fakereadbyte != -1) { @@ -1811,59 +1849,52 @@ static void QCBUILTIN PF_ReadByte(progfuncs_t *prinst, struct globalvars_s *pr_g } } -static void QCBUILTIN PF_ReadChar(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadChar(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadChar(); } -static void QCBUILTIN PF_ReadShort(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadShort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadShort(); } -static void QCBUILTIN PF_ReadEntityNum(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadEntityNum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - unsigned short val; - val = MSG_ReadShort(); - if (val & 0x8000) - { //our protocol only supports 15bits of revelent entity number (16th bit is used as 'remove'). - //so warn with badly coded mods. - Con_Printf("ReadEntityNumber read bad entity number\n"); - G_FLOAT(OFS_RETURN) = 0; - } - else - G_FLOAT(OFS_RETURN) = val; + unsigned int val; + val = MSGCL_ReadEntity(); + G_FLOAT(OFS_RETURN) = val; } -static void QCBUILTIN PF_ReadLong(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadLong(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadLong(); } -static void QCBUILTIN PF_ReadCoord(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadCoord(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadCoord(); } -static void QCBUILTIN PF_ReadFloat(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadFloat(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadFloat(); } -static void QCBUILTIN PF_ReadString(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadString(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *read = MSG_ReadString(); RETURN_TSTRING(read); } -static void QCBUILTIN PF_ReadAngle(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadAngle(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = MSG_ReadAngle(); } -static void QCBUILTIN PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_objerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; struct edict_s *ed; @@ -1873,11 +1904,11 @@ static void QCBUILTIN PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_ */ ed = PROG_TO_EDICT(prinst, *csqcg.self); /* ED_Print (ed); */ - ED_Print(prinst, ed); + prinst->ED_Print(prinst, ed); Con_Printf("%s", s); if (developer.value) - (*prinst->pr_trace) = 2; + prinst->pr_trace = 2; else { ED_Free (prinst, ed); @@ -1888,27 +1919,27 @@ static void QCBUILTIN PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_ } } -static void QCBUILTIN PF_cs_setsensativityscaler (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_setsensativityscaler (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { in_sensitivityscale = G_FLOAT(OFS_PARM0); } -static void QCBUILTIN PF_cs_pointparticles (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_pointparticles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int effectnum = G_FLOAT(OFS_PARM0)-1; float *org = G_VECTOR(OFS_PARM1); float *vel = G_VECTOR(OFS_PARM2); float count = G_FLOAT(OFS_PARM3); - if (*prinst->callargc < 3) + if (prinst->callargc < 3) vel = vec3_origin; - if (*prinst->callargc < 4) + if (prinst->callargc < 4) count = 1; P_RunParticleEffectType(org, vel, count, effectnum); } -static void QCBUILTIN PF_cs_trailparticles (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_trailparticles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int efnum; csqcedict_t *ent; @@ -1934,7 +1965,7 @@ static void QCBUILTIN PF_cs_trailparticles (progfuncs_t *prinst, struct globalva pe->ParticleTrail(start, end, efnum, -ent->entnum, &ent->trailstate); } -static void QCBUILTIN PF_cs_particleeffectnum (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particleeffectnum (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *effectname = PR_GetStringOfs(prinst, OFS_PARM0); @@ -1949,7 +1980,7 @@ static void QCBUILTIN PF_cs_particleeffectnum (progfuncs_t *prinst, struct globa } } -static void QCBUILTIN PF_cs_particleeffectquery (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particleeffectquery (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int id = G_FLOAT(OFS_PARM0); qboolean body = G_FLOAT(OFS_PARM1); @@ -1971,7 +2002,7 @@ static void QCBUILTIN PF_cs_particleeffectquery (progfuncs_t *prinst, struct glo G_INT(OFS_RETURN) = 0; } -static void QCBUILTIN PF_cs_sendevent (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_sendevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; int i; @@ -2007,7 +2038,7 @@ static void QCBUILTIN PF_cs_sendevent (progfuncs_t *prinst, struct globalvars_s { ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM2+i*3); MSG_WriteByte(&cls.netchan.message, ev_entity); - MSG_WriteShort(&cls.netchan.message, ent->xv->entnum); + MSG_WriteEntity(&cls.netchan.message, ent->xv->entnum); } else break; @@ -2077,7 +2108,7 @@ static void cs_get_input_state (usercmd_t *cmd) } //get the input commands, and stuff them into some globals. -static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int f; usercmd_t *cmd; @@ -2117,14 +2148,14 @@ static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvar //read lots of globals, run the default player physics, write lots of globals. //not intended to affect client state at all -static void QCBUILTIN PF_cs_runplayerphysics (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int msecs; extern vec3_t player_mins; extern vec3_t player_maxs; csqcedict_t *ent; - if (*prinst->callargc >= 1) + if (prinst->callargc >= 1) ent = (void*)G_EDICT(prinst, OFS_PARM0); else ent = NULL; @@ -2212,7 +2243,7 @@ static void QCBUILTIN PF_cs_runplayerphysics (progfuncs_t *prinst, struct global World_LinkEdict (&csqc_world, (wedict_t*)ent, true); } -static void QCBUILTIN PF_cs_getentitytoken (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getentitytoken (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (!csqcmapentitydata) { @@ -2239,7 +2270,7 @@ static void CheckSendPings(void) } } -static void QCBUILTIN PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_serverkey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *keyname = PF_VarString(prinst, 0, pr_globals); char *ret; @@ -2302,6 +2333,10 @@ static void QCBUILTIN PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s break; } } + else if (!strcmp(keyname, "challenge")) + { + ret = va("%u", cls.challenge); + } else { ret = Info_ValueForKey(cl.serverinfo, keyname); @@ -2314,7 +2349,7 @@ static void QCBUILTIN PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s } //string(float pnum, string keyname) -static void QCBUILTIN PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_getplayerkey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char buffer[64]; char *ret; @@ -2391,7 +2426,7 @@ static void QCBUILTIN PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars G_INT(OFS_RETURN) = 0; } -static void QCBUILTIN PF_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *extname = PR_GetStringOfs(prinst, OFS_PARM0); int i; @@ -2413,7 +2448,7 @@ static void QCBUILTIN PF_checkextension (progfuncs_t *prinst, struct globalvars_ G_FLOAT(OFS_RETURN) = false; } -static void QCBUILTIN PF_cs_sound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *sample; int channel; @@ -2429,7 +2464,7 @@ static void QCBUILTIN PF_cs_sound(progfuncs_t *prinst, struct globalvars_s *pr_g sample = PR_GetStringOfs(prinst, OFS_PARM2); volume = G_FLOAT(OFS_PARM3); attenuation = G_FLOAT(OFS_PARM4); - if (*prinst->callargc >= 6) + if (prinst->callargc >= 6) pitchpct = G_FLOAT(OFS_PARM5); else pitchpct = 0; @@ -2439,7 +2474,7 @@ static void QCBUILTIN PF_cs_sound(progfuncs_t *prinst, struct globalvars_s *pr_g S_StartSound(-entity->entnum, channel, sfx, entity->v->origin, volume, attenuation, 0, pitchpct); }; -static void QCBUILTIN PF_cs_pointsound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_pointsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *sample; float *origin; @@ -2453,7 +2488,7 @@ static void QCBUILTIN PF_cs_pointsound(progfuncs_t *prinst, struct globalvars_s sample = PR_GetStringOfs(prinst, OFS_PARM1); volume = G_FLOAT(OFS_PARM2); attenuation = G_FLOAT(OFS_PARM3); - if (*prinst->callargc >= 5) + if (prinst->callargc >= 5) pitchpct = G_FLOAT(OFS_PARM4); else pitchpct = 0; @@ -2463,7 +2498,7 @@ static void QCBUILTIN PF_cs_pointsound(progfuncs_t *prinst, struct globalvars_s S_StartSound(0, 0, sfx, origin, volume, attenuation, 0, pitchpct); } -static void QCBUILTIN PF_cs_particle(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particle(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float *dir = G_VECTOR(OFS_PARM1); @@ -2472,7 +2507,7 @@ static void QCBUILTIN PF_cs_particle(progfuncs_t *prinst, struct globalvars_s *p pe->RunParticleEffect(org, dir, colour, count); } -static void QCBUILTIN PF_cs_particle2(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particle2(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org, *dmin, *dmax; float colour; @@ -2489,7 +2524,7 @@ static void QCBUILTIN PF_cs_particle2(progfuncs_t *prinst, struct globalvars_s * pe->RunParticleEffect2 (org, dmin, dmax, colour, effect, count); } -static void QCBUILTIN PF_cs_particle3(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particle3(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org, *box; float colour; @@ -2505,7 +2540,7 @@ static void QCBUILTIN PF_cs_particle3(progfuncs_t *prinst, struct globalvars_s * pe->RunParticleEffect3(org, box, colour, effect, count); } -static void QCBUILTIN PF_cs_particle4(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_particle4(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org; float radius; @@ -2523,7 +2558,7 @@ static void QCBUILTIN PF_cs_particle4(progfuncs_t *prinst, struct globalvars_s * } -void QCBUILTIN PF_cl_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_effect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); char *name = PR_GetStringOfs(prinst, OFS_PARM1); @@ -2539,7 +2574,7 @@ void QCBUILTIN PF_cl_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals Con_Printf("PF_cl_effect: Couldn't load model %s\n", name); } -void QCBUILTIN PF_cl_ambientsound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_ambientsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *samp; float *pos; @@ -2553,14 +2588,14 @@ void QCBUILTIN PF_cl_ambientsound(progfuncs_t *prinst, struct globalvars_s *pr_g S_StaticSound (S_PrecacheSound (samp), pos, vol, attenuation); } -static void QCBUILTIN PF_cs_vectorvectors (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { VectorCopy(G_VECTOR(OFS_PARM0), csqcg.forward); VectorNormalize(csqcg.forward); VectorVectors(csqcg.forward, csqcg.right, csqcg.up); } -static void QCBUILTIN PF_cs_lightstyle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int stnum = G_FLOAT(OFS_PARM0); char *str = PR_GetStringOfs(prinst, OFS_PARM1); @@ -2576,7 +2611,7 @@ static void QCBUILTIN PF_cs_lightstyle (progfuncs_t *prinst, struct globalvars_s cl_lightstyle[stnum].length = Q_strlen(cl_lightstyle[stnum].map); } -static void QCBUILTIN PF_cs_changeyaw (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; float ideal, current, move, speed; @@ -2612,7 +2647,7 @@ static void QCBUILTIN PF_cs_changeyaw (progfuncs_t *prinst, struct globalvars_s ent->v->angles[1] = anglemod (current + move); } -static void QCBUILTIN PF_cs_changepitch (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; float ideal, current, move, speed; @@ -2649,7 +2684,7 @@ static void QCBUILTIN PF_cs_changepitch (progfuncs_t *prinst, struct globalvars_ ent->v->angles[0] = anglemod (current + move); } -static void QCBUILTIN PF_cs_findradius (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent, *chain; float rad; @@ -2683,7 +2718,7 @@ static void QCBUILTIN PF_cs_findradius (progfuncs_t *prinst, struct globalvars_s //entity(string field, float match) findchainflags = #450 //chained search for float, int, and entity reference fields -static void QCBUILTIN PF_cs_findchainflags (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; int s; @@ -2710,7 +2745,7 @@ static void QCBUILTIN PF_cs_findchainflags (progfuncs_t *prinst, struct globalva } //entity(string field, float match) findchainfloat = #403 -static void QCBUILTIN PF_cs_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; float s; @@ -2739,7 +2774,7 @@ static void QCBUILTIN PF_cs_findchainfloat (progfuncs_t *prinst, struct globalva //entity(string field, string match) findchain = #402 //chained search for strings in entity fields -static void QCBUILTIN PF_cs_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; char *s; @@ -2769,26 +2804,26 @@ static void QCBUILTIN PF_cs_findchain (progfuncs_t *prinst, struct globalvars_s RETURN_EDICT(prinst, (edict_t*)chain); } -static void QCBUILTIN PF_cl_te_gunshot (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_gunshot (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float scaler = 1; - if (*prinst->callargc >= 2) //fte is a quakeworld engine + if (prinst->callargc >= 2) //fte is a quakeworld engine scaler = G_FLOAT(OFS_PARM1); if (P_RunParticleEffectType(pos, NULL, scaler, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 20*scaler); } -static void QCBUILTIN PF_cl_te_bloodqw (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_bloodqw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float scaler = 1; - if (*prinst->callargc >= 2) //fte is a quakeworld engine + if (prinst->callargc >= 2) //fte is a quakeworld engine scaler = G_FLOAT(OFS_PARM1); if (P_RunParticleEffectType(pos, NULL, scaler, ptqw_blood)) if (P_RunParticleEffectType(pos, NULL, scaler, ptdp_blood)) P_RunParticleEffect (pos, vec3_origin, 73, 20*scaler); } -static void QCBUILTIN PF_cl_te_blooddp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_blooddp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float *dir = G_VECTOR(OFS_PARM1); @@ -2798,20 +2833,20 @@ static void QCBUILTIN PF_cl_te_blooddp (progfuncs_t *prinst, struct globalvars_s if (P_RunParticleEffectType(pos, dir, scaler, ptqw_blood)) P_RunParticleEffect (pos, dir, 73, 20*scaler); } -static void QCBUILTIN PF_cl_te_lightningblood (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_lightningblood (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectType(pos, NULL, 1, ptqw_lightningblood)) P_RunParticleEffect (pos, vec3_origin, 225, 50); } -static void QCBUILTIN PF_cl_te_spike (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_spike (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectType(pos, NULL, 1, pt_spike)) if (P_RunParticleEffectType(pos, NULL, 10, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 10); } -static void QCBUILTIN PF_cl_te_superspike (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_superspike (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectType(pos, NULL, 1, pt_superspike)) @@ -2819,7 +2854,7 @@ static void QCBUILTIN PF_cl_te_superspike (progfuncs_t *prinst, struct globalvar if (P_RunParticleEffectType(pos, NULL, 20, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 20); } -static void QCBUILTIN PF_cl_te_explosion (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_explosion (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); @@ -2848,14 +2883,14 @@ static void QCBUILTIN PF_cl_te_explosion (progfuncs_t *prinst, struct globalvars S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0); } -static void QCBUILTIN PF_cl_te_tarexplosion (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_tarexplosion (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); P_RunParticleEffectType(pos, NULL, 1, pt_tarexplosion); S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1, 0, 0); } -static void QCBUILTIN PF_cl_te_wizspike (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_wizspike (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectType(pos, NULL, 1, pt_wizspike)) @@ -2863,7 +2898,7 @@ static void QCBUILTIN PF_cl_te_wizspike (progfuncs_t *prinst, struct globalvars_ S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0, 0); } -static void QCBUILTIN PF_cl_te_knightspike (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_knightspike (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectType(pos, NULL, 1, pt_knightspike)) @@ -2871,24 +2906,24 @@ static void QCBUILTIN PF_cl_te_knightspike (progfuncs_t *prinst, struct globalva S_StartSound (-2, 0, cl_sfx_knighthit, pos, 1, 1, 0, 0); } -static void QCBUILTIN PF_cl_te_lavasplash (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_lavasplash (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); P_RunParticleEffectType(pos, NULL, 1, pt_lavasplash); } -static void QCBUILTIN PF_cl_te_teleport (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_teleport (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); P_RunParticleEffectType(pos, NULL, 1, pt_teleportsplash); } -static void QCBUILTIN PF_cl_te_gunshotquad (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_gunshotquad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_gunshotquad")) if (P_RunParticleEffectType(pos, NULL, 1, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 20); } -static void QCBUILTIN PF_cl_te_spikequad (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_spikequad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_spikequad")) @@ -2896,7 +2931,7 @@ static void QCBUILTIN PF_cl_te_spikequad (progfuncs_t *prinst, struct globalvars if (P_RunParticleEffectType(pos, NULL, 10, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 10); } -static void QCBUILTIN PF_cl_te_superspikequad (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_superspikequad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_superspikequad")) @@ -2905,7 +2940,7 @@ static void QCBUILTIN PF_cl_te_superspikequad (progfuncs_t *prinst, struct globa if (P_RunParticleEffectType(pos, NULL, 20, pt_gunshot)) P_RunParticleEffect (pos, vec3_origin, 0, 20); } -static void QCBUILTIN PF_cl_te_explosionquad (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_explosionquad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); if (P_RunParticleEffectTypeString(pos, vec3_origin, 1, "te_explosionquad")) @@ -2936,7 +2971,7 @@ static void QCBUILTIN PF_cl_te_explosionquad (progfuncs_t *prinst, struct global } //void(vector org, float radius, float lifetime, vector color) te_customflash -static void QCBUILTIN PF_cl_te_customflash (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_customflash (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float radius = G_FLOAT(OFS_PARM1); @@ -2955,10 +2990,10 @@ static void QCBUILTIN PF_cl_te_customflash (progfuncs_t *prinst, struct globalva dl->color[2] = colour[2]*0.5f; } -static void QCBUILTIN PF_cl_te_bloodshower (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_bloodshower (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } -static void QCBUILTIN PF_cl_te_particlecube (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_particlecube (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *minb = G_VECTOR(OFS_PARM0); float *maxb = G_VECTOR(OFS_PARM1); @@ -2970,16 +3005,16 @@ static void QCBUILTIN PF_cl_te_particlecube (progfuncs_t *prinst, struct globalv P_RunParticleCube(minb, maxb, vel, howmany, color, gravity, jitter); } -static void QCBUILTIN PF_cl_te_spark (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_spark (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } -static void QCBUILTIN PF_cl_te_smallflash (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_smallflash (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } -static void QCBUILTIN PF_cl_te_explosion2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_explosion2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } -static void QCBUILTIN PF_cl_te_lightning1 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_lightning1 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0); float *start = G_VECTOR(OFS_PARM1); @@ -2987,7 +3022,7 @@ static void QCBUILTIN PF_cl_te_lightning1 (progfuncs_t *prinst, struct globalvar CL_AddBeam(0, ent->entnum+MAX_EDICTS, start, end); } -static void QCBUILTIN PF_cl_te_lightning2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_lightning2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0); float *start = G_VECTOR(OFS_PARM1); @@ -2995,7 +3030,7 @@ static void QCBUILTIN PF_cl_te_lightning2 (progfuncs_t *prinst, struct globalvar CL_AddBeam(1, ent->entnum+MAX_EDICTS, start, end); } -static void QCBUILTIN PF_cl_te_lightning3 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_lightning3 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0); float *start = G_VECTOR(OFS_PARM1); @@ -3003,7 +3038,7 @@ static void QCBUILTIN PF_cl_te_lightning3 (progfuncs_t *prinst, struct globalvar CL_AddBeam(2, ent->entnum+MAX_EDICTS, start, end); } -static void QCBUILTIN PF_cl_te_beam (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_beam (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0); float *start = G_VECTOR(OFS_PARM1); @@ -3011,10 +3046,10 @@ static void QCBUILTIN PF_cl_te_beam (progfuncs_t *prinst, struct globalvars_s *p CL_AddBeam(5, ent->entnum+MAX_EDICTS, start, end); } -static void QCBUILTIN PF_cl_te_plasmaburn (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_plasmaburn (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } -static void QCBUILTIN PF_cl_te_explosionrgb (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_explosionrgb (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float *colour = G_VECTOR(OFS_PARM1); @@ -3045,7 +3080,7 @@ static void QCBUILTIN PF_cl_te_explosionrgb (progfuncs_t *prinst, struct globalv S_StartSound (-2, 0, cl_sfx_r_exp3, org, 1, 1, 0, 0); } -static void QCBUILTIN PF_cl_te_particlerain (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_particlerain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min = G_VECTOR(OFS_PARM0); float *max = G_VECTOR(OFS_PARM1); @@ -3055,7 +3090,7 @@ static void QCBUILTIN PF_cl_te_particlerain (progfuncs_t *prinst, struct globalv P_RunParticleWeather(min, max, vel, howmany, colour, "rain"); } -static void QCBUILTIN PF_cl_te_particlesnow (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_te_particlesnow (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min = G_VECTOR(OFS_PARM0); float *max = G_VECTOR(OFS_PARM1); @@ -3095,7 +3130,7 @@ void CSQC_RunThreads(void) } } -static void QCBUILTIN PF_cs_addprogs (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_addprogs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s = PR_GetStringOfs(prinst, OFS_PARM0); int newp; @@ -3110,7 +3145,7 @@ static void QCBUILTIN PF_cs_addprogs (progfuncs_t *prinst, struct globalvars_s * G_FLOAT(OFS_RETURN) = newp; } -static void QCBUILTIN PF_cs_OpenPortal (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef Q2BSPS if (cl.worldmodel->fromgame == fg_quake2) @@ -3121,7 +3156,7 @@ static void QCBUILTIN PF_cs_OpenPortal (progfuncs_t *prinst, struct globalvars_s #ifndef NOMEDIA // #487 float(string name) gecko_create( string name ) -static void QCBUILTIN PF_cs_gecko_create (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); cin_t *cin; @@ -3133,11 +3168,11 @@ static void QCBUILTIN PF_cs_gecko_create (progfuncs_t *prinst, struct globalvars G_FLOAT(OFS_RETURN) = 1; } // #488 void(string name) gecko_destroy( string name ) -static void QCBUILTIN PF_cs_gecko_destroy (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_destroy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { } // #489 void(string name) gecko_navigate( string name, string URI ) -static void QCBUILTIN PF_cs_gecko_navigate (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_navigate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); char *command = PR_GetStringOfs(prinst, OFS_PARM1); @@ -3150,7 +3185,7 @@ static void QCBUILTIN PF_cs_gecko_navigate (progfuncs_t *prinst, struct globalva Media_Send_Command(cin, command); } // #490 float(string name) gecko_keyevent( string name, float key, float eventtype ) -static void QCBUILTIN PF_cs_gecko_keyevent (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_keyevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); int key = G_FLOAT(OFS_PARM1); @@ -3163,7 +3198,7 @@ static void QCBUILTIN PF_cs_gecko_keyevent (progfuncs_t *prinst, struct globalva Media_Send_KeyEvent(cin, MP_TranslateDPtoFTECodes(key), (key>127)?0:key, eventtype); } // #491 void gecko_mousemove( string name, float x, float y ) -static void QCBUILTIN PF_cs_gecko_mousemove (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_mousemove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); float posx = G_FLOAT(OFS_PARM1); @@ -3176,7 +3211,7 @@ static void QCBUILTIN PF_cs_gecko_mousemove (progfuncs_t *prinst, struct globalv Media_Send_MouseMove(cin, posx, posy); } // #492 void gecko_resize( string name, float w, float h ) -static void QCBUILTIN PF_cs_gecko_resize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_resize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); float sizex = G_FLOAT(OFS_PARM1); @@ -3188,7 +3223,7 @@ static void QCBUILTIN PF_cs_gecko_resize (progfuncs_t *prinst, struct globalvars Media_Send_Resize(cin, sizex, sizey); } // #493 vector gecko_get_texture_extent( string name ) -static void QCBUILTIN PF_cs_gecko_get_texture_extent (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_gecko_get_texture_extent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); float *ret = G_VECTOR(OFS_RETURN); @@ -3210,7 +3245,7 @@ static void QCBUILTIN PF_cs_gecko_get_texture_extent (progfuncs_t *prinst, struc } #endif -static void QCBUILTIN PF_cs_droptofloor (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_droptofloor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; vec3_t end; @@ -3237,7 +3272,7 @@ static void QCBUILTIN PF_cs_droptofloor (progfuncs_t *prinst, struct globalvars_ } } -static void QCBUILTIN PF_cs_copyentity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_copyentity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *in, *out; @@ -3249,12 +3284,12 @@ static void QCBUILTIN PF_cs_copyentity (progfuncs_t *prinst, struct globalvars_s World_LinkEdict (&csqc_world, (wedict_t*)out, false); } -static void QCBUILTIN PF_cl_playingdemo (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_playingdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = !!cls.demoplayback; } -static void QCBUILTIN PF_cl_runningserver (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_runningserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef CLIENTONLY G_FLOAT(OFS_RETURN) = false; @@ -3263,7 +3298,7 @@ static void QCBUILTIN PF_cl_runningserver (progfuncs_t *prinst, struct globalvar #endif } -static void QCBUILTIN PF_cl_getlight (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cl_getlight (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { vec3_t ambient, diffuse, dir; cl.worldmodel->funcs.LightPointValues(cl.worldmodel, G_VECTOR(OFS_PARM0), ambient, diffuse, dir); @@ -3271,13 +3306,13 @@ static void QCBUILTIN PF_cl_getlight (progfuncs_t *prinst, struct globalvars_s * } /* -static void QCBUILTIN PF_Stub (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Stub (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf("Obsolete csqc builtin (%i) executed\n", prinst->lastcalledbuiltinnumber); } */ -static void QCBUILTIN PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_rotatevectorsbytag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0); int tagnum = G_FLOAT(OFS_PARM1); @@ -3335,7 +3370,7 @@ static void QCBUILTIN PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalv VectorCopy(srcorg, retorg); } -static void QCBUILTIN PF_shaderforname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_shaderforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); char *defaultbody = PF_VarString(prinst, 1, pr_globals); @@ -3357,7 +3392,7 @@ static void QCBUILTIN PF_shaderforname (progfuncs_t *prinst, struct globalvars_s -static void QCBUILTIN PF_cs_checkbottom (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_checkbottom (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; @@ -3366,15 +3401,15 @@ static void QCBUILTIN PF_cs_checkbottom (progfuncs_t *prinst, struct globalvars_ G_FLOAT(OFS_RETURN) = World_CheckBottom (&csqc_world, (wedict_t*)ent); } -static void QCBUILTIN PF_cs_break (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_break (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf ("break statement\n"); #ifdef TEXTEDITOR - (*prinst->pr_trace)++; + prinst->pr_trace++; #endif } -static void QCBUILTIN PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_walkmove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *ent; float yaw, dist; @@ -3386,7 +3421,7 @@ static void QCBUILTIN PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s * ent = (csqcedict_t*)PROG_TO_EDICT(prinst, *csqcg.self); yaw = G_FLOAT(OFS_PARM0); dist = G_FLOAT(OFS_PARM1); - if (*prinst->callargc >= 3 && G_FLOAT(OFS_PARM2)) + if (prinst->callargc >= 3 && G_FLOAT(OFS_PARM2)) settrace = true; else settrace = false; @@ -3412,7 +3447,7 @@ static void QCBUILTIN PF_cs_walkmove (progfuncs_t *prinst, struct globalvars_s * *csqcg.self = oldself; } -static void QCBUILTIN PF_cs_movetogoal (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_movetogoal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { wedict_t *ent; float dist; @@ -3427,7 +3462,7 @@ static void CS_ConsoleCommand_f(void) Q_snprintfz(cmd, sizeof(cmd), "%s %s", Cmd_Argv(0), Cmd_Args()); CSQC_ConsoleCommand(cmd); } -static void QCBUILTIN PF_cs_registercommand (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_registercommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PF_VarString(prinst, 0, pr_globals); if (!strcmp(str, "+showscores") || !strcmp(str, "-showscores") || @@ -3446,7 +3481,7 @@ qboolean CSQC_SettingListener(void) } return false; } -static void QCBUILTIN PF_cs_setlistener (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cs_setlistener (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *origin = G_VECTOR(OFS_PARM0); float *forward = G_VECTOR(OFS_PARM1); @@ -3784,14 +3819,14 @@ void CSQC_DeltaEnd(void) } } -static void QCBUILTIN PF_DeltaListen(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_DeltaListen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; char *mname = PR_GetStringOfs(prinst, OFS_PARM0); func_t func = G_INT(OFS_PARM1); unsigned int flags = G_FLOAT(OFS_PARM2); - if (PR_GetFuncArgCount(prinst, func) < 0) + if (prinst->GetFuncArgCount(prinst, func) < 0) { Con_Printf("PF_DeltaListen: Bad function index\n"); return; @@ -3822,7 +3857,7 @@ static void QCBUILTIN PF_DeltaListen(progfuncs_t *prinst, struct globalvars_s *p } } -static void QCBUILTIN PF_getentity(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_getentity(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum = G_FLOAT(OFS_PARM0); int fldnum = G_FLOAT(OFS_PARM1); @@ -3920,12 +3955,12 @@ static void QCBUILTIN PF_getentity(progfuncs_t *prinst, struct globalvars_s *pr_ #if 1 -//static void QCBUILTIN PF_ReadServerEntityState(progfuncs_t *prinst, struct globalvars_s *pr_globals) +//static void QCBUILTIN PF_ReadServerEntityState(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //{ //} #else packet_entities_t *CL_ProcessPacketEntities(float *servertime, qboolean nolerp); -static void QCBUILTIN PF_ReadServerEntityState(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ReadServerEntityState(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //read the arguments the csqc gave us unsigned int flags = G_FLOAT(OFS_PARM0); @@ -4354,15 +4389,15 @@ static struct { {"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_???) - {"drawstring", PF_CL_drawcolouredstring, 326}, // #326 - {"stringwidth", PF_CL_stringwidth, 327}, // #327 EXT_CSQC_'DARKPLACES' - {"drawsubpic", PF_CL_drawsubpic, 328}, // #328 EXT_CSQC_'DARKPLACES' + {"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' //330 - {"getstati", PF_cs_getstati, 330}, // #330 float(float stnum) getstati (EXT_CSQC) - {"getstatbits", PF_cs_getstatbits, 331}, // #331 float(float stnum) getstatbits (EXT_CSQC) - {"getstats", PF_cs_getstats, 332}, // #332 string(float firststnum) getstats (EXT_CSQC) + {"getstati", PF_cs_getstati, 330}, // #330 float(float stnum) getstati (EXT_CSQC) + {"getstatbits", PF_cs_getstatbits, 331}, // #331 float(float stnum) getstatbits (EXT_CSQC) + {"getstats", PF_cs_getstats, 332}, // #332 string(float firststnum) getstats (EXT_CSQC) {"setmodelindex", PF_cs_SetModelIndex, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) {"modelnameforindex", PF_cs_ModelnameForIndex, 334}, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC) @@ -4370,13 +4405,13 @@ static struct { {"trailparticles", PF_cs_trailparticles, 336}, // #336 void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC), {"pointparticles", PF_cs_pointparticles, 337}, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC) - {"cprint", PF_cl_cprint, 338}, // #338 void(string s) cprint (EXT_CSQC) - {"print", PF_print, 339}, // #339 void(string s) print (EXT_CSQC) + {"cprint", PF_cl_cprint, 338}, // #338 void(string s) cprint (EXT_CSQC) + {"print", PF_print, 339}, // #339 void(string s) print (EXT_CSQC) //340 {"keynumtostring", PF_cl_keynumtostring, 340}, // #340 string(float keynum) keynumtostring (EXT_CSQC) {"stringtokeynum", PF_cl_stringtokeynum, 341}, // #341 float(string keyname) stringtokeynum (EXT_CSQC) - {"getkeybind", PF_cl_getkeybind, 342}, // #342 string(float keynum) getkeybind (EXT_CSQC) + {"getkeybind", PF_cl_getkeybind, 342}, // #342 string(float keynum) getkeybind (EXT_CSQC) // {"?", PF_Fixme, 343}, // #343 {"getmousepos", PF_cl_getmousepos, 344}, // #344 This is a DP extension @@ -4388,41 +4423,42 @@ static struct { {"getplayerkeyvalue", PF_cs_getplayerkey, 348}, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC) - {"isdemo", PF_cl_playingdemo, 349}, // #349 float() isdemo (EXT_CSQC) + {"isdemo", PF_cl_playingdemo, 349}, // #349 float() isdemo (EXT_CSQC) //350 - {"isserver", PF_cl_runningserver, 350}, // #350 float() isserver (EXT_CSQC) + {"isserver", PF_cl_runningserver, 350}, // #350 float() isserver (EXT_CSQC) - {"SetListener", PF_cs_setlistener, 351}, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) + {"SetListener", PF_cs_setlistener, 351}, // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC) {"registercommand", PF_cs_registercommand, 352}, // #352 void(string cmdname) registercommand (EXT_CSQC) - {"wasfreed", PF_WasFreed, 353}, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too) + {"wasfreed", PF_WasFreed, 353}, // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too) - {"serverkey", PF_cs_serverkey, 354}, // #354 string(string key) serverkey; + {"serverkey", PF_cs_serverkey, 354}, // #354 string(string key) serverkey; {"getentitytoken", PF_cs_getentitytoken, 355}, // #355 string() getentitytoken; -// {"?", PF_Fixme, 356}, // #356 -// {"?", PF_Fixme, 357}, // #357 -// {"?", PF_Fixme, 358}, // #358 - {"sendevent", PF_cs_sendevent, 359}, // #359 void(string evname, string evargs, ...) (EXT_CSQC_1) + {"findfont", PF_CL_findfont, 356}, + {"loadfont", PF_CL_loadfont, 357}, +// {"?", PF_Fixme, 358}, // #358 + {"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) - {"readbyte", PF_ReadByte, 360}, // #360 float() readbyte (EXT_CSQC) - {"readchar", PF_ReadChar, 361}, // #361 float() readchar (EXT_CSQC) - {"readshort", PF_ReadShort, 362}, // #362 float() readshort (EXT_CSQC) - {"readlong", PF_ReadLong, 363}, // #363 float() readlong (EXT_CSQC) - {"readcoord", PF_ReadCoord, 364}, // #364 float() readcoord (EXT_CSQC) + {"readbyte", PF_ReadByte, 360}, // #360 float() readbyte (EXT_CSQC) + {"readchar", PF_ReadChar, 361}, // #361 float() readchar (EXT_CSQC) + {"readshort", PF_ReadShort, 362}, // #362 float() readshort (EXT_CSQC) + {"readlong", PF_ReadLong, 363}, // #363 float() readlong (EXT_CSQC) + {"readcoord", PF_ReadCoord, 364}, // #364 float() readcoord (EXT_CSQC) - {"readangle", PF_ReadAngle, 365}, // #365 float() readangle (EXT_CSQC) - {"readstring", PF_ReadString, 366}, // #366 string() readstring (EXT_CSQC) - {"readfloat", PF_ReadFloat, 367}, // #367 string() readfloat (EXT_CSQC) + {"readangle", PF_ReadAngle, 365}, // #365 float() readangle (EXT_CSQC) + {"readstring", PF_ReadString, 366}, // #366 string() readstring (EXT_CSQC) + {"readfloat", PF_ReadFloat, 367}, // #367 string() readfloat (EXT_CSQC) {"readentitynum", PF_ReadEntityNum, 368}, // #368 float() readentitynum (EXT_CSQC) // {"readserverentitystate", PF_ReadServerEntityState, 369}, // #369 void(float flags, float simtime) readserverentitystate (EXT_CSQC_1) // {"readsingleentitystate", PF_ReadSingleEntityState, 370}, - {"deltalisten", PF_DeltaListen, 371}, // #371 float(string modelname, float flags) deltalisten (EXT_CSQC_1) + {"deltalisten", PF_DeltaListen, 371}, // #371 float(string modelname, float flags) deltalisten (EXT_CSQC_1) {"dynamiclight_get", PF_R_DynamicLight_Get, 372}, {"dynamiclight_set", PF_R_DynamicLight_Set, 373}, {"particleeffectquery", PF_cs_particleeffectquery, 374}, + {"adddecal", PF_R_AddDecal, 375}, {"memalloc", PF_memalloc, 384}, {"memfree", PF_memfree, 385}, @@ -4630,6 +4666,8 @@ static struct { {"getsurfacenumtriangles",PF_getsurfacenumtriangles,628}, {"getsurfacetriangle", PF_getsurfacetriangle, 629}, + {"digest_hex", PF_digest_hex, 639}, + {NULL} }; @@ -4700,7 +4738,7 @@ void CSQC_ForgetThreads(void) } } -void CSQC_EntSpawn (struct edict_s *e, int loading) +void PDECL CSQC_EntSpawn (struct edict_s *e, int loading) { struct csqcedict_s *ent = (csqcedict_t*)e; #ifdef VM_Q1 @@ -4718,7 +4756,7 @@ void CSQC_EntSpawn (struct edict_s *e, int loading) } } -pbool CSQC_EntFree (struct edict_s *e) +pbool QDECL CSQC_EntFree (struct edict_s *e) { struct csqcedict_s *ent = (csqcedict_t*)e; ent->v->solid = SOLID_NOT; @@ -4808,18 +4846,12 @@ void CSQC_Shutdown(void) { if (csqcprogs) { - skel_reset(csqcprogs); - - search_close_progs(csqcprogs, false); - PR_fclose_progs(csqcprogs); - CSQC_ForgetThreads(); - CloseProgs(csqcprogs); + PR_ResetFonts(true); + PR_Common_Shutdown(csqcprogs, false); + csqcprogs->CloseProgs(csqcprogs); } -#ifdef TEXTEDITOR - Editor_ProgsKilled(csqcprogs); -#endif - csqcprogs = NULL; + csqc_world.progs = csqcprogs = NULL; #ifdef USEODE World_ODE_End(&csqc_world); @@ -4847,7 +4879,7 @@ void CSQC_Shutdown(void) } //when the qclib needs a file, it calls out to this function. -qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int bufsize) +qbyte *PDECL CSQC_PRLoadFile (const char *path, void *buffer, int bufsize) { qbyte *file; @@ -4902,7 +4934,7 @@ qbyte *CSQC_PRLoadFile (const char *path, void *buffer, int bufsize) return COM_LoadStackFile(path, buffer, bufsize); } -int CSQC_PRFileSize (const char *path) +int QDECL CSQC_PRFileSize (const char *path) { qbyte *file; @@ -4968,7 +5000,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks int i; string_t *str; csqcedict_t *worldent; - qboolean loaded; + qboolean loaded = false; csprogs_promiscuous = anycsqc; csprogs_checksum = checksum; @@ -5010,7 +5042,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks csqcprogparms.ReadFile = CSQC_PRLoadFile;//char *(*ReadFile) (char *fname, void *buffer, int *len); csqcprogparms.FileSize = CSQC_PRFileSize;//int (*FileSize) (char *fname); //-1 if file does not exist csqcprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len); - csqcprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...); + csqcprogparms.Printf = PR_Printf;//Con_Printf;//void (*printf) (char *, ...); csqcprogparms.Sys_Error = Sys_Error; csqcprogparms.Abort = CSQC_Abort; csqcprogparms.edictsize = sizeof(csqcedict_t); @@ -5817,6 +5849,7 @@ void CSQC_ParseEntities(void) void *pr_globals; int packetsize; int packetstart; + qboolean removeflag; if (!csqcprogs) Host_EndGame("CSQC needs to be initialized for this server.\n"); @@ -5841,13 +5874,28 @@ void CSQC_ParseEntities(void) for(;;) { - entnum = MSG_ReadShort(); + //replacement deltas now also includes 22bit entity num indicies. + if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + { + entnum = MSG_ReadShort(); + removeflag = !!(entnum & 0x8000); + if (entnum & 0x4000) + entnum = (entnum & 0x3fff) | (MSG_ReadByte()<<14); + else + entnum &= ~0x8000; + } + else + { + entnum = MSG_ReadShort(); + removeflag = !!(entnum & 0x8000); + entnum &= ~0x8000; + } + if (!entnum || msg_badread) break; - if (entnum & 0x8000) - { //remove - entnum &= ~0x8000; + if (removeflag) + { //remove if (!entnum) Host_EndGame("CSQC cannot remove world!\n"); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 5f1f5939..ecde71f3 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -222,7 +222,7 @@ int MP_TranslateDPtoFTECodes(int code) } //string findkeysforcommand(string command) = #610; -void QCBUILTIN PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0); int keynums[2]; @@ -238,13 +238,13 @@ void QCBUILTIN PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_ RETURN_TSTRING(keyname); } -void QCBUILTIN PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *binding = Key_GetBinding(G_FLOAT(OFS_PARM0)); RETURN_TSTRING(binding); } -void QCBUILTIN PF_cl_stringtokeynum(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; int modifier; @@ -262,7 +262,7 @@ void QCBUILTIN PF_cl_stringtokeynum(progfuncs_t *prinst, struct globalvars_s *pr } //string keynumtostring(float keynum) = #609; -void QCBUILTIN PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int code = G_FLOAT(OFS_PARM0); @@ -279,7 +279,7 @@ void QCBUILTIN PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *p //float drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #457; -void QCBUILTIN PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawfill (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float *size = G_VECTOR(OFS_PARM1); @@ -292,7 +292,7 @@ void QCBUILTIN PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_glob G_FLOAT(OFS_RETURN) = 1; } //void drawsetcliparea(float x, float y, float width, float height) = #458; -void QCBUILTIN PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawsetcliparea (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float x = G_FLOAT(OFS_PARM0), y = G_FLOAT(OFS_PARM1), w = G_FLOAT(OFS_PARM2), h = G_FLOAT(OFS_PARM3); @@ -322,7 +322,7 @@ void QCBUILTIN PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s * G_FLOAT(OFS_RETURN) = 0; } //void drawresetcliparea(void) = #459; -void QCBUILTIN PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawresetcliparea (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef GLQUAKE if (qrenderer == QR_OPENGL) @@ -335,7 +335,172 @@ void QCBUILTIN PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s G_FLOAT(OFS_RETURN) = 0; } -void QCBUILTIN PF_CL_DrawTextField (progfuncs_t *prinst, struct globalvars_s *pr_globals) +#define FONT_SLOTS 16 +#define FONT_SIZES 4 +struct { + char slotname[16]; + char facename[64]; + int sizes; + int size[4]; + struct font_s *font[4]; +} fontslot[FONT_SLOTS]; +void PR_CL_BeginString(pubprogfuncs_t *prinst, float vx, float vy, float szx, float szy, float *px, float *py) +{ + int fontidx = 0; //default by default... + world_t *world = prinst->parms->user; + struct font_s *font = font_conchar; + if (!world) + { + //menu progs. + if (mp_globs.drawfontscale) + { + szx *= mp_globs.drawfontscale[0]; + szy *= mp_globs.drawfontscale[1]; + } + if (mp_globs.drawfont) + { + fontidx = *mp_globs.drawfont; + } + } + else + { + if (world->g.drawfontscale) + { + szx *= world->g.drawfontscale[0]; + szy *= world->g.drawfontscale[1]; + } + if (world->g.drawfont) + { + fontidx = *world->g.drawfont; + } + } + + fontidx--; + if (fontidx >= 0 && fontidx < FONT_SLOTS) + { + int i, j; + int fontdiff = 10000; + for (i = 0; i < fontslot[fontidx].sizes; i++) + { + j = abs(szy - fontslot[fontidx].size[i]); + if (j < fontdiff && fontslot[fontidx].font) + { + fontdiff = j; + font = fontslot[fontidx].font[i]; + } + } + } + + Font_BeginScaledString(font, vx, vy, szx, szy, px, py); +} +int PR_findnamedfont(char *name, qboolean isslotname) +{ + int i; + if (isslotname) + { + for (i = 0; i < FONT_SLOTS; i++) + { + if (!stricmp(fontslot[i].slotname, name)) + return i; + } + } + else + { + for (i = 0; i < FONT_SLOTS; i++) + { + if (!stricmp(fontslot[i].facename, name)) + return i; + } + } + return -1; +} +void PR_ResetFonts(qboolean purge) +{ + int i, j; + for (i = 0; i < FONT_SLOTS; i++) + { + for (j = 0; j < fontslot[i].sizes; j++) + { + Font_Free(fontslot[i].font[j]); + fontslot[i].font[j] = NULL; + } + + if (purge) + { + fontslot[i].sizes = 0; + fontslot[i].slotname[0] = '\0'; + fontslot[i].facename[0] = '\0'; + } + else + { + for (j = 0; j < fontslot[i].sizes; j++) + fontslot[i].font[j] = Font_LoadFont(fontslot[i].size[j], fontslot[i].facename); + } + } +} +void QCBUILTIN PF_CL_findfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *slotname = PR_GetStringOfs(prinst, OFS_PARM0); + G_FLOAT(OFS_RETURN) = PR_findnamedfont(slotname, true) + 1; //return default on failure. +} +void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *slotname = PR_GetStringOfs(prinst, OFS_PARM0); + char *facename = PR_GetStringOfs(prinst, OFS_PARM1); + char *sizestr = PR_GetStringOfs(prinst, OFS_PARM2); + int slotnum = G_FLOAT(OFS_PARM3); + //float fix_scale = G_FLOAT(OFS_PARM4); + //float fix_voffset = G_FLOAT(OFS_PARM5); + int i, sz; + + G_FLOAT(OFS_RETURN) = 0; //return default on failure. + + if (slotnum == -1 && *slotname) + slotnum = PR_findnamedfont(slotname, true); + else if (slotnum == -1) + slotnum = PR_findnamedfont(facename, false); + if (slotnum == -1) + slotnum = PR_findnamedfont("", true); + if (slotnum == -1) + return; //eep. + + if ((unsigned)slotnum >= FONT_SLOTS) + return; + + //if its changed, purge it. + if (stricmp(fontslot[slotnum].slotname, slotname) || stricmp(fontslot[slotnum].facename, facename)) + { + Q_strncpyz(fontslot[slotnum].slotname, slotname, sizeof(fontslot[slotnum].slotname)); + Q_strncpyz(fontslot[slotnum].facename, facename, sizeof(fontslot[slotnum].facename)); + for (i = 0; i < fontslot[slotnum].sizes; i++) + { + Font_Free(fontslot[slotnum].font[i]); + fontslot[slotnum].font[i] = NULL; + } + } + + while(*sizestr) + { + sizestr = COM_Parse(sizestr); + sz = atoi(com_token); + for (i = 0; i < fontslot[slotnum].sizes; i++) + { + if (fontslot[slotnum].size[i] == sz) + break; + } + if (i == fontslot[slotnum].sizes) + { + if (i >= FONT_SIZES) + break; + fontslot[slotnum].size[i] = sz; + fontslot[slotnum].font[i] = Font_LoadFont(fontslot[slotnum].size[i], facename); + fontslot[slotnum].sizes++; + } + } + G_FLOAT(OFS_RETURN) = slotnum + 1; +} + +void QCBUILTIN PF_CL_DrawTextField (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float *size = G_VECTOR(OFS_PARM1); @@ -345,7 +510,7 @@ void QCBUILTIN PF_CL_DrawTextField (progfuncs_t *prinst, struct globalvars_s *pr } //float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455; -void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawcolouredstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); char *text = PR_GetStringOfs(prinst, OFS_PARM1); @@ -353,11 +518,11 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_ float alpha = 0; float flag = 0; float r, g, b; - - conchar_t buffer[2048], *str; float px, py, ipx; - if (*prinst->callargc >= 6) + conchar_t buffer[2048], *str; + + if (prinst->callargc >= 6) { r = G_FLOAT(OFS_PARM3 + 0); g = G_FLOAT(OFS_PARM3 + 1); @@ -383,7 +548,7 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_ COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), false); str = buffer; - Font_BeginScaledString(font_conchar, pos[0], pos[1], &px, &py); + PR_CL_BeginString(prinst, pos[0], pos[1], size[0], size[1], &px, &py); ipx = px; Font_ForceColour(r, g, b, alpha); while(*str) @@ -393,39 +558,28 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_ else if ((*str & CON_CHARMASK) == '\r') px = ipx; else - px = Font_DrawScaleChar(px, py, size[0], size[1], *str); + px = Font_DrawScaleChar(px, py, *str); str++; } Font_InvalidateColour(); - Font_EndString(font_conchar); + Font_EndString(NULL); } -void QCBUILTIN PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_stringwidth(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { conchar_t buffer[2048], *end; float px, py; char *text = PR_GetStringOfs(prinst, OFS_PARM0); int usecolours = G_FLOAT(OFS_PARM1); - float fontsize; - if (*prinst->callargc > 2) - fontsize = G_FLOAT(OFS_PARM2+1); - else - fontsize = 8; - - if (mp_globs.drawfontscale && !prinst->parms->user) - fontsize *= mp_globs.drawfontscale[1]; + float *size = (prinst->callargc > 2)?G_VECTOR(OFS_PARM2):NULL; end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), !usecolours); - Font_BeginScaledString(font_conchar, 0, 0, &px, &py); - fontsize /= Font_CharHeight(); + PR_CL_BeginString(prinst, 0, 0, size?size[0]:8, size?size[1]:8, &px, &py); px = Font_LineWidth(buffer, end); - Font_EndString(font_conchar); + Font_EndString(NULL); - if (mp_globs.drawfontscale && !prinst->parms->user) - px *= mp_globs.drawfontscale[1]; - - G_FLOAT(OFS_RETURN) = px * fontsize; + G_FLOAT(OFS_RETURN) = (px * vid.width) / vid.rotpixelwidth; } #define DRAWFLAG_NORMAL 0 @@ -448,7 +602,7 @@ static unsigned int PF_SelectDPDrawFlag(int flag) } //float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456; -void QCBUILTIN PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); char *picname = PR_GetStringOfs(prinst, OFS_PARM1); @@ -471,7 +625,7 @@ void QCBUILTIN PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globa G_FLOAT(OFS_RETURN) = 1; } -void QCBUILTIN PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawsubpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); float *size = G_VECTOR(OFS_PARM1); @@ -485,6 +639,8 @@ void QCBUILTIN PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_gl mpic_t *p; p = R2D_SafeCachePic(picname); + if (!p) + p = R2D_SafePicFromWad(picname); r2d_be_flags = PF_SelectDPDrawFlag(flag); R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha); @@ -501,7 +657,7 @@ void QCBUILTIN PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_gl -void QCBUILTIN PF_CL_is_cached_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_is_cached_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; @@ -513,14 +669,14 @@ void QCBUILTIN PF_CL_is_cached_pic (progfuncs_t *prinst, struct globalvars_s *pr G_FLOAT(OFS_RETURN) = 1; } -void QCBUILTIN PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_precache_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; mpic_t *pic; float fromwad; str = PR_GetStringOfs(prinst, OFS_PARM0); - if (*prinst->callargc > 1) + if (prinst->callargc > 1) fromwad = G_FLOAT(OFS_PARM1); else fromwad = false; @@ -545,7 +701,7 @@ void QCBUILTIN PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_ G_INT(OFS_RETURN) = 0; } -void QCBUILTIN PF_CL_free_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_free_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; @@ -554,9 +710,8 @@ void QCBUILTIN PF_CL_free_pic (progfuncs_t *prinst, struct globalvars_s *pr_glob //we don't support this. } - //float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) = #454; -void QCBUILTIN PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawcharacter (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); int chara = G_FLOAT(OFS_PARM1); @@ -577,16 +732,17 @@ void QCBUILTIN PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr if (chara < 32 && chara != '\t') chara |= 0xe000; - Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y); + PR_CL_BeginString(prinst, pos[0], pos[1], size[0], size[1], &x, &y); Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); - Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK | /*0xe000|*/chara); + Font_DrawScaleChar(x, y, CON_WHITEMASK | /*0xe000|*/chara); Font_InvalidateColour(); - Font_EndString(font_conchar); + Font_EndString(NULL); G_FLOAT(OFS_RETURN) = 1; } + //float drawrawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #455; -void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *pos = G_VECTOR(OFS_PARM0); char *text = PR_GetStringOfs(prinst, OFS_PARM1); @@ -603,16 +759,9 @@ void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr return; } - Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y); - x = pos[0]; - y = pos[1]; + PR_CL_BeginString(prinst, pos[0], pos[1], size[0], size[1], &x, &y); Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); - if (mp_globs.drawfontscale && !prinst->parms->user) - { - size[0] *= mp_globs.drawfontscale[0]; - size[1] *= mp_globs.drawfontscale[1]; - } while(*text) { //FIXME: which charset is this meant to be using? @@ -622,19 +771,19 @@ void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr c |= 0xe000; //if its a control char, just use the quake range instead. else if (c & 0x80) c |= 0xe000; //if its a high char, just use the quake range instead. we could colour it, but why bother - x = Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK|/*0xe000|*/c); + x = Font_DrawScaleChar(x, y, CON_WHITEMASK|/*0xe000|*/c); } Font_InvalidateColour(); - Font_EndString(font_conchar); + Font_EndString(NULL); } //void (float width, vector rgb, float alpha, float flags, vector pos1, ...) drawline; -void QCBUILTIN PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *rgb = G_VECTOR(OFS_PARM1); float alpha = G_FLOAT(OFS_PARM2); float *pos = G_VECTOR(OFS_PARM4); - int numpoints = *prinst->callargc-4; + int numpoints = prinst->callargc-4; #ifdef GLQUAKE // :( @@ -654,7 +803,7 @@ void QCBUILTIN PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_glob } //vector drawgetimagesize(string pic) = #460; -void QCBUILTIN PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_drawgetimagesize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *picname = PR_GetStringOfs(prinst, OFS_PARM0); mpic_t *p = R2D_SafeCachePic(picname); @@ -675,6 +824,30 @@ void QCBUILTIN PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s } } +//vector getmousepos(void) = #66; +void QCBUILTIN PF_cl_getmousepos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + float *ret = G_VECTOR(OFS_RETURN); + + if (Key_MouseShouldBeFree()) + { + ret[0] = mousecursor_x; + ret[1] = mousecursor_y; + } + else + { + ret[0] = mousemove_x; + ret[1] = mousemove_y; + } + + mousemove_x=0; + mousemove_y=0; + +// extern int mousecursor_x, mousecursor_y; +// ret[0] = mousecursor_x; +// ret[1] = mousecursor_y; + ret[2] = 0; +} #endif @@ -708,14 +881,14 @@ cvar_t pr_menuqc_coreonerror = SCVAR("pr_menuqc_coreonerror", "1"); //new generic functions. -void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_mod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int a = G_FLOAT(OFS_PARM0); int b = G_FLOAT(OFS_PARM1); if (b == 0) { Con_Printf("mod by zero\n"); - *prinst->pr_trace = 1; + prinst->pr_trace = 1; G_FLOAT(OFS_RETURN) = 0; } else @@ -747,7 +920,7 @@ char *RemapCvarNameFromDPToFTE(char *name) return name; } -static void QCBUILTIN PF_menu_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_menu_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { cvar_t *var; char *str; @@ -773,7 +946,7 @@ static void QCBUILTIN PF_menu_cvar (progfuncs_t *prinst, struct globalvars_s *pr G_FLOAT(OFS_RETURN) = 0; } } -static void QCBUILTIN PF_menu_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_menu_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *var_name, *val; cvar_t *var; @@ -785,7 +958,7 @@ static void QCBUILTIN PF_menu_cvar_set (progfuncs_t *prinst, struct globalvars_s var = Cvar_Get(var_name, val, 0, "QC variables"); Cvar_Set (var, val); } -static void QCBUILTIN PF_menu_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_menu_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); cvar_t *cv = Cvar_Get(RemapCvarNameFromDPToFTE(str), "", 0, "QC variables"); @@ -794,7 +967,7 @@ static void QCBUILTIN PF_menu_cvar_string (progfuncs_t *prinst, struct globalvar qboolean M_Vid_GetMode(int num, int *w, int *h); //a bit pointless really -void QCBUILTIN PF_cl_getresolution (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_getresolution (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float mode = G_FLOAT(OFS_PARM0); float *ret = G_VECTOR(OFS_RETURN); @@ -811,7 +984,7 @@ void QCBUILTIN PF_cl_getresolution (progfuncs_t *prinst, struct globalvars_s *pr -void QCBUILTIN PF_nonfatalobjerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_nonfatalobjerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; struct edict_s *ed; @@ -830,7 +1003,7 @@ void QCBUILTIN PF_nonfatalobjerror (progfuncs_t *prinst, struct globalvars_s *pr if (developer.value) - *prinst->pr_trace = 2; + prinst->pr_trace = 2; else { ED_Free (prinst, ed); @@ -846,7 +1019,7 @@ void QCBUILTIN PF_nonfatalobjerror (progfuncs_t *prinst, struct globalvars_s *pr //float isserver(void) = #60; -void QCBUILTIN PF_isserver (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_isserver (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef CLIENTONLY G_FLOAT(OFS_RETURN) = false; @@ -854,19 +1027,19 @@ void QCBUILTIN PF_isserver (progfuncs_t *prinst, struct globalvars_s *pr_globals G_FLOAT(OFS_RETURN) = sv.state != ss_dead; #endif } -void QCBUILTIN PF_isdemo (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_isdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = !!cls.demoplayback; } //float clientstate(void) = #62; -void QCBUILTIN PF_clientstate (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_clientstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = cls.state >= ca_connected ? 2 : 1; //fit in with netquake (we never run a menu.dat dedicated) } //too specific to the prinst's builtins. -static void QCBUILTIN PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Fixme (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf("\n"); @@ -876,7 +1049,7 @@ static void QCBUILTIN PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_glo -void QCBUILTIN PF_CL_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_precache_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; @@ -889,7 +1062,7 @@ void QCBUILTIN PF_CL_precache_sound (progfuncs_t *prinst, struct globalvars_s *p } //void setkeydest(float dest) = #601; -void QCBUILTIN PF_cl_setkeydest (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_setkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { switch((int)G_FLOAT(OFS_PARM0)) { @@ -911,7 +1084,7 @@ void QCBUILTIN PF_cl_setkeydest (progfuncs_t *prinst, struct globalvars_s *pr_gl } } //float getkeydest(void) = #602; -void QCBUILTIN PF_cl_getkeydest (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_getkeydest (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { switch(key_dest) { @@ -934,7 +1107,7 @@ void QCBUILTIN PF_cl_getkeydest (progfuncs_t *prinst, struct globalvars_s *pr_gl } //void setmousetarget(float trg) = #603; -void QCBUILTIN PF_cl_setmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_setmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { extern int mouseusedforgui; switch ((int)G_FLOAT(OFS_PARM0)) @@ -951,41 +1124,13 @@ void QCBUILTIN PF_cl_setmousetarget (progfuncs_t *prinst, struct globalvars_s *p } //float getmousetarget(void) = #604; -void QCBUILTIN PF_cl_getmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cl_getmousetarget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { extern int mouseusedforgui; G_FLOAT(OFS_RETURN) = mouseusedforgui?2:1; } -//vector getmousepos(void) = #66; -void QCBUILTIN PF_cl_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals) -{ - float *ret = G_VECTOR(OFS_RETURN); - extern int mousemove_x, mousemove_y; - extern int mousecursor_x, mousecursor_y; - - if (Key_MouseShouldBeFree()) - { - ret[0] = mousecursor_x; - ret[1] = mousecursor_y; - } - else - { - ret[0] = mousemove_x; - ret[1] = mousemove_y; - } - - mousemove_x=0; - mousemove_y=0; - -// extern int mousecursor_x, mousecursor_y; -// ret[0] = mousecursor_x; -// ret[1] = mousecursor_y; - ret[2] = 0; -} - - -static void QCBUILTIN PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Remove_ (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { menuedict_t *ed; @@ -1000,7 +1145,7 @@ static void QCBUILTIN PF_Remove_ (progfuncs_t *prinst, struct globalvars_s *pr_g ED_Free (prinst, (void*)ed); } -static void QCBUILTIN PF_CopyEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_CopyEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { menuedict_t *in, *out; @@ -1024,7 +1169,7 @@ typedef enum{ SLIST_SORTDESCENDING } hostcacheglobal_t; -void QCBUILTIN PF_M_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { hostcacheglobal_t hcg = G_FLOAT(OFS_PARM0); G_FLOAT(OFS_RETURN) = 0; @@ -1060,12 +1205,12 @@ void QCBUILTIN PF_M_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s } //void resethostcachemasks(void) = #615; -void QCBUILTIN PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Master_ClearMasks(); } //void sethostcachemaskstring(float mask, float fld, string str, float op) = #616; -void QCBUILTIN PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int mask = G_FLOAT(OFS_PARM0); int field = G_FLOAT(OFS_PARM1); @@ -1075,7 +1220,7 @@ void QCBUILTIN PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvar Master_SetMaskString(mask, field, str, op); } //void sethostcachemasknumber(float mask, float fld, float num, float op) = #617; -void QCBUILTIN PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int mask = G_FLOAT(OFS_PARM0); int field = G_FLOAT(OFS_PARM1); @@ -1085,22 +1230,22 @@ void QCBUILTIN PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvar Master_SetMaskInteger(mask, field, str, op); } //void resorthostcache(void) = #618; -void QCBUILTIN PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Master_SortServers(); } //void sethostcachesort(float fld, float descending) = #619; -void QCBUILTIN PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); } //void refreshhostcache(void) = #620; -void QCBUILTIN PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { MasterInfo_Refresh(); } //float gethostcachenumber(float fld, float hostnr) = #621; -void QCBUILTIN PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float ret = 0; int keynum = G_FLOAT(OFS_PARM0); @@ -1112,7 +1257,7 @@ void QCBUILTIN PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s G_FLOAT(OFS_RETURN) = ret; } -void QCBUILTIN PF_M_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *ret; int keynum = G_FLOAT(OFS_PARM0); @@ -1126,25 +1271,25 @@ void QCBUILTIN PF_M_gethostcachestring (progfuncs_t *prinst, struct globalvars_s } //float gethostcacheindexforkey(string key) = #622; -void QCBUILTIN PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *keyname = PR_GetStringOfs(prinst, OFS_PARM0); G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname); } //void addwantedhostcachekey(string key) = #623; -void QCBUILTIN PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { PF_M_gethostcacheindexforkey(prinst, pr_globals); } -void QCBUILTIN PF_M_getextresponse(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_M_getextresponse(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //this does something weird G_INT(OFS_RETURN) = 0; } -void QCBUILTIN PF_netaddress_resolve(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_netaddress_resolve(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *address = PR_GetStringOfs(prinst, OFS_PARM0); netadr_t adr; @@ -1156,30 +1301,30 @@ void QCBUILTIN PF_netaddress_resolve(progfuncs_t *prinst, struct globalvars_s *p } #else -void PF_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} -void PF_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;} +void PF_gethostcachevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} +void PF_gethostcachestring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;} //void resethostcachemasks(void) = #615; -void PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_resethostcachemasks(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} //void sethostcachemaskstring(float mask, float fld, string str, float op) = #616; -void PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_sethostcachemaskstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} //void sethostcachemasknumber(float mask, float fld, float num, float op) = #617; -void PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_sethostcachemasknumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} //void resorthostcache(void) = #618; -void PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_resorthostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} //void sethostcachesort(float fld, float descending) = #619; -void PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} //void refreshhostcache(void) = #620; -void PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals) {} +void PF_M_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) {} //float gethostcachenumber(float fld, float hostnr) = #621; -void PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} +void PF_M_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} //float gethostcacheindexforkey(string key) = #622; -void PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} +void PF_M_gethostcacheindexforkey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;} //void addwantedhostcachekey(string key) = #623; -void PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals){} +void PF_M_addwantedhostcachekey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals){} #endif -void QCBUILTIN PF_localsound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_localsound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *soundname = PR_GetStringOfs(prinst, OFS_PARM0); S_LocalSound (soundname); @@ -1191,24 +1336,24 @@ void QCBUILTIN PF_localsound (progfuncs_t *prinst, struct globalvars_s *pr_globa #define skip50 skip10 skip10 skip10 skip10 skip10 #define skip100 skip50 skip50 -void QCBUILTIN PF_menu_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_menu_checkextension (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //yeah, this is a stub... not sure what form extex G_FLOAT(OFS_RETURN) = 0; } -void QCBUILTIN PF_gettime (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_gettime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = *prinst->parms->gametime; } -void QCBUILTIN PF_CL_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_CL_precache_file (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_INT(OFS_RETURN) = G_INT(OFS_PARM0); } //entity findchainstring(.string _field, string match) = #26; -void QCBUILTIN PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_menu_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; char *s; @@ -1241,7 +1386,7 @@ void QCBUILTIN PF_menu_findchain (progfuncs_t *prinst, struct globalvars_s *pr_g RETURN_EDICT(prinst, (void*)chain); } //entity findchainfloat(.float _field, float match) = #27; -void QCBUILTIN PF_menu_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_menu_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; float s; @@ -1270,18 +1415,18 @@ void QCBUILTIN PF_menu_findchainfloat (progfuncs_t *prinst, struct globalvars_s RETURN_EDICT(prinst, (void*)chain); } -void QCBUILTIN PF_etof(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_etof(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = G_EDICTNUM(prinst, OFS_PARM0); } -void QCBUILTIN PF_ftoe(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_ftoe(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum = G_FLOAT(OFS_PARM0); RETURN_EDICT(prinst, EDICT_NUM(prinst, entnum)); } -void QCBUILTIN PF_IsNotNull(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_IsNotNull(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int str = G_INT(OFS_PARM0); G_FLOAT(OFS_RETURN) = !!str; @@ -1289,7 +1434,7 @@ void QCBUILTIN PF_IsNotNull(progfuncs_t *prinst, struct globalvars_s *pr_globals //float altstr_count(string str) = #82; //returns number of single quoted strings in the string. -void QCBUILTIN PF_altstr_count(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_altstr_count(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; int count = 0; @@ -1307,7 +1452,7 @@ void QCBUILTIN PF_altstr_count(progfuncs_t *prinst, struct globalvars_s *pr_glob G_FLOAT(OFS_RETURN) = count/2; } //string altstr_prepare(string str) = #83; -void QCBUILTIN PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_altstr_prepare(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char outstr[8192], *out; char *instr, *in; @@ -1334,7 +1479,7 @@ void QCBUILTIN PF_altstr_prepare(progfuncs_t *prinst, struct globalvars_s *pr_gl G_INT( OFS_RETURN ) = (int)PR_TempString( prinst, outstr ); } //string altstr_get(string str, float num) = #84; -void QCBUILTIN PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_altstr_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *altstr, *pos, outstr[8192], *out; int count, size; @@ -1380,7 +1525,7 @@ void QCBUILTIN PF_altstr_get(progfuncs_t *prinst, struct globalvars_s *pr_global G_INT( OFS_RETURN ) = (int)PR_SetString( prinst, outstr ); } //string altstr_set(string str, float num, string set) = #85 -void QCBUILTIN PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_altstr_set(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int num; char *altstr, *str; @@ -1432,31 +1577,31 @@ void QCBUILTIN PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_global } //string(string serveraddress) crypto_getkeyfp -void QCBUILTIN PF_crypto_getkeyfp(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crypto_getkeyfp(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //not supported. G_INT(OFS_RETURN) = 0; } //string(string serveraddress) crypto_getidfp -void QCBUILTIN PF_crypto_getidfp(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crypto_getidfp(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //not supported. G_INT(OFS_RETURN) = 0; } //string(string serveraddress) crypto_getencryptlevel -void QCBUILTIN PF_crypto_getencryptlevel(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crypto_getencryptlevel(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //not supported. G_INT(OFS_RETURN) = 0; } //string(float i) crypto_getmykeyfp -void QCBUILTIN PF_crypto_getmykeyfp(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crypto_getmykeyfp(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //not supported. G_INT(OFS_RETURN) = 0; } //string(float i) crypto_getmyidfp -void QCBUILTIN PF_crypto_getmyidfp(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crypto_getmyidfp(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //not supported. G_INT(OFS_RETURN) = 0; @@ -1656,6 +1801,7 @@ builtin_t menu_builtins[] = { //470 skip1 // #470 +//MERGES WITH CLIENT+SERVER BUILTIN MAPPINGS BELOW PF_asin, // #471 PF_acos, // #472 PF_atan, // #473 @@ -1779,7 +1925,7 @@ int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]); void M_DeInit_Internal (void); int inmenuprogs; -progfuncs_t *menuprogs; +pubprogfuncs_t *menuprogs; progparms_t menuprogparms; menuedict_t *menu_edicts; int num_menu_edicts; @@ -1817,26 +1963,21 @@ void MP_Shutdown (void) if (temp && !inmenuprogs) PR_ExecuteProgram(menuprogs, temp); - PR_fclose_progs(menuprogs); - search_close_progs(menuprogs, true); + PR_Common_Shutdown(menuprogs, false); + menuprogs->CloseProgs(menuprogs); + menuprogs = NULL; + PR_ResetFonts(true); #ifdef CL_MASTER Master_ClearMasks(); #endif - CloseProgs(menuprogs); -#ifdef TEXTEDITOR - Editor_ProgsKilled(menuprogs); -#endif - menuprogs = NULL; - key_dest = key_game; m_state = 0; mouseusedforgui = false; } -pbool QC_WriteFile(const char *name, void *data, int len); void *VARGS PR_CB_Malloc(int size); //these functions should be tracked by the library reliably, so there should be no need to track them ourselves. void VARGS PR_CB_Free(void *mem); @@ -1899,7 +2040,7 @@ qboolean MP_Init (void) menuprogparms.ReadFile = COM_LoadStackFile;//char *(*ReadFile) (char *fname, void *buffer, int *len); menuprogparms.FileSize = COM_FileSize;//int (*FileSize) (char *fname); //-1 if file does not exist menuprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len); - menuprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...); + menuprogparms.Printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...); menuprogparms.Sys_Error = Sys_Error; menuprogparms.Abort = Menu_Abort; menuprogparms.edictsize = sizeof(menuedict_t); diff --git a/engine/client/pr_skelobj.c b/engine/client/pr_skelobj.c index 17d0adbe..6370949c 100644 --- a/engine/client/pr_skelobj.c +++ b/engine/client/pr_skelobj.c @@ -35,8 +35,7 @@ qc must build the skeletal object still, which fills the skeletal object from th #include "quakedef.h" -#if defined(CSQC_DAT) || !defined(CLIENTONLY) -#define RAGDOLL +#if defined(RAGDOLL) || defined(SKELETALOBJECTS) #include "pr_common.h" #include "com_mesh.h" @@ -52,14 +51,12 @@ typedef struct doll_s model_t *model; struct doll_s *next; + qboolean drawn:1; + int numdefaultanimated; int numbodies; int numjoints; int numbones; - struct - { - char name[32]; - int bone; - } *body; + odebodyinfo_t *body; odejointinfo_t *joint; struct { @@ -69,20 +66,16 @@ typedef struct doll_s } *bone; } doll_t; -enum -{ - BF_ACTIVE, /*used to avoid traces if doll is stationary*/ - BF_INSOLID -}; typedef struct { odebody_t odebody; - int ownerent; /*multiple of 12*/ - int flags; +// int ownerent; /*multiple of 12*/ +// int flags; - float moment[12]; - float matrix[12]; +// float moment[12]; + float animstrength; + float animmatrix[12]; } body_t; #endif @@ -103,19 +96,78 @@ typedef struct skelobject_s float *bonematrix; #ifdef RAGDOLL + int numanimated; struct skelobject_s *animsource; unsigned int numbodies; body_t *body; int numjoints; odejoint_t *joint; doll_t *doll; + wedict_t *entity; //only valid for dolls. #endif } skelobject_t; +#ifdef RAGDOLL static doll_t *dolllist; +#endif static skelobject_t skelobjects[MAX_SKEL_OBJECTS]; static int numskelobjectsused; +//copes with src==dst to convert rel->abs +void skel_copy_toabs(skelobject_t *skelobjdst, skelobject_t *skelobjsrc, int startbone, int endbone) +{ + galiasbone_t *boneinfo = Mod_GetBoneInfo(skelobjsrc->model); + if (!boneinfo) + return; + if (skelobjsrc->type == SKOT_ABSOLUTE) + { + if (skelobjsrc != skelobjdst) + { + while(startbone < endbone) + { + Vector4Copy(skelobjsrc->bonematrix+12*startbone+0, skelobjdst->bonematrix+12*startbone+0); + Vector4Copy(skelobjsrc->bonematrix+12*startbone+4, skelobjdst->bonematrix+12*startbone+4); + Vector4Copy(skelobjsrc->bonematrix+12*startbone+8, skelobjdst->bonematrix+12*startbone+8); + startbone++; + } + } + } + else + { + if (skelobjsrc != skelobjdst) + { + while(startbone < endbone) + { + if (boneinfo[startbone].parent >= 0) + { + Matrix3x4_Multiply(skelobjsrc->bonematrix+12*startbone, skelobjdst->bonematrix+12*boneinfo[startbone].parent, skelobjdst->bonematrix+12*startbone); + } + else + { + Vector4Copy(skelobjsrc->bonematrix+12*startbone+0, skelobjdst->bonematrix+12*startbone+0); + Vector4Copy(skelobjsrc->bonematrix+12*startbone+4, skelobjdst->bonematrix+12*startbone+4); + Vector4Copy(skelobjsrc->bonematrix+12*startbone+8, skelobjdst->bonematrix+12*startbone+8); + } + startbone++; + } + } + else + { + float tmpmat[12]; + while(startbone < endbone) + { + if (boneinfo[startbone].parent >= 0) + { + Matrix3x4_Multiply(skelobjsrc->bonematrix+12*startbone, skelobjdst->bonematrix+12*boneinfo[startbone].parent, tmpmat); + memcpy(skelobjdst->bonematrix+12*startbone, tmpmat, sizeof(tmpmat)); + } + startbone++; + } + } + } + + skelobjdst->type = SKOT_ABSOLUTE; +} static void bonemat_fromidentity(float *out) { out[0] = 1; @@ -148,6 +200,21 @@ static void bonemat_fromqcvectors(float *out, const float vx[3], const float vy[ out[10] = vz[2]; out[11] = t[2]; } +static void bonemat_fromaxisorg(float *out, const vec3_t axis[3], const float t[3]) +{ + out[0] = axis[0][0]; + out[1] = axis[1][0]; + out[2] = axis[2][0]; + out[3] = t[0]; + out[4] = axis[0][1]; + out[5] = axis[1][1]; + out[6] = axis[2][1]; + out[7] = t[1]; + out[8] = axis[0][2]; + out[9] = axis[1][2]; + out[10]= axis[2][2]; + out[11]= t[2]; +} static void bonemat_fromentity(world_t *w, wedict_t *ed, float *trans) { vec3_t d[3], a; @@ -218,16 +285,343 @@ int rag_finddolljoint(doll_t *d, char *name) } return -1; } -doll_t *rag_loaddoll(model_t *mod, char *fname, int numbones) + +typedef struct { + qboolean errors; + doll_t *d; + galiasbone_t *bones; + + odebodyinfo_t *body; + odejointinfo_t *joint; + + odebodyinfo_t defbody; + odejointinfo_t defjoint; +} dollcreatectx_t; +dollcreatectx_t *rag_createdoll(model_t *mod, char *fname, int numbones) +{ + int i; + dollcreatectx_t *ctx; + int nummodbones = Mod_GetNumBones(mod, false); + if (nummodbones != numbones || !numbones) + return NULL; + + ctx = malloc(sizeof(*ctx)); + + ctx->bones = Mod_GetBoneInfo(mod); + ctx->errors = 0; + + memset(&ctx->defbody, 0, sizeof(ctx->defbody)); + ctx->defbody.animate = true; + ctx->defbody.shape = SOLID_PHYSICS_BOX; + ctx->defbody.dimensions[0] = 4; + ctx->defbody.dimensions[1] = 4; + ctx->defbody.dimensions[2] = 4; + ctx->defbody.mass = 1; + ctx->defbody.orient = false; + + memset(&ctx->defjoint, 0, sizeof(ctx->defjoint)); + ctx->defjoint.axis[1] = 1; + ctx->defjoint.axis2[2] = 1; + ctx->defjoint.ERP = 0.2; //use ODE defaults + ctx->defjoint.ERP2 = 0.2; + ctx->defjoint.CFM = 1e-5; + ctx->defjoint.CFM2 = 1e-5; + + ctx->d = BZ_Malloc(sizeof(*ctx->d)); + ctx->d->next = dolllist; + ctx->d->name = strdup(fname); + ctx->d->model = mod; + ctx->d->numbodies = 0; + ctx->d->body = NULL; + ctx->d->numjoints = 0; + ctx->d->uses = 0; + ctx->d->joint = NULL; + + ctx->d->numbones = numbones; + ctx->d->bone = BZ_Malloc(sizeof(*ctx->d->bone) * ctx->d->numbones); + for (i = 0; i < ctx->d->numbones; i++) + ctx->d->bone[i].bodyidx = -1; + + return ctx; +} +//returns true if the command was recognised. false if the command is for something else. +qboolean rag_dollline(dollcreatectx_t *ctx, int linenum) +{ + int i; + int argc; + char *cmd, *val; + doll_t *d = ctx->d; + + argc = Cmd_Argc(); + cmd = Cmd_Argv(0); + val = Cmd_Argv(1); + + if (!argc) + { + } + //create a new body + else if (argc == 3 && !stricmp(cmd, "body")) + { + int boneidx = Mod_TagNumForName(d->model, Cmd_Argv(2))-1; + ctx->joint = NULL; + ctx->body = NULL; + if (boneidx >= 0) + { + d->body = BZ_Realloc(d->body, sizeof(*d->body)*(d->numbodies+1)); + ctx->body = &d->body[d->numbodies]; + d->bone[boneidx].bodyidx = d->numbodies; + d->numbodies++; + + *ctx->body = ctx->defbody; + Q_strncpyz(ctx->body->name, Cmd_Argv(1), sizeof(ctx->body->name)); + ctx->body->bone = boneidx; + } + else if (!ctx->errors++) + Con_Printf("^[Unable to create body \"%s\" because bone \"%s\" does not exist in %s\\edit\\%s %i^]\n", Cmd_Argv(1), Cmd_Argv(2), d->model->name, d->name, linenum); + } + //create a new joint + else if (argc >= 2 && !stricmp(cmd, "joint")) + { + char *name; + ctx->joint = NULL; + ctx->body = NULL; + d->joint = BZ_Realloc(d->joint, sizeof(*d->joint)*(d->numjoints+1)); + ctx->joint = &d->joint[d->numjoints]; + *ctx->joint = ctx->defjoint; + Q_strncpyz(ctx->joint->name, Cmd_Argv(1), sizeof(ctx->joint->name)); + name = Cmd_Argv(2); + ctx->joint->body1 = *name?rag_finddollbody(d, name):-1; + if (*name && ctx->joint->body1 < 0) + { + if (!ctx->errors++) + Con_Printf("^[Joint \"%s\" joins invalid body \"%s\"\\edit\\%s %i^]\n", ctx->joint->name, name, d->name, linenum); + return true; + } + name = Cmd_Argv(3); + ctx->joint->body2 = *name?rag_finddollbody(d, name):-1; + if (*name && (ctx->joint->body2 < 0 || ctx->joint->body2 == ctx->joint->body1)) + { + if (!ctx->errors++) + { + if (ctx->joint->body2 == ctx->joint->body1) + Con_Printf("^[Joint \"%s\" joints body \"%s\" to itself\\edit\\%s %i^]\n", ctx->joint->name, name, d->name, linenum); + else + Con_Printf("^[Joint \"%s\" joints invalid body \"%s\"\\edit\\%s %i^]\n", ctx->joint->name, name, d->name, linenum); + } + return true; + } + ctx->joint->bonepivot = d->body[(ctx->joint->body2 >= 0)?ctx->joint->body2:ctx->joint->body1].bone; //default the pivot object to the bone of the second object. + + if (ctx->joint->body1 >= 0 || ctx->joint->body2 >= 0) + d->numjoints++; + else if (!ctx->errors++) + Con_Printf("^[Joint property \"%s\" not recognised\\edit\\%s %i^]\n", ctx->joint->name, d->name, linenum); + } + else if (argc == 2 && !stricmp(cmd, "updatebody")) + { + ctx->joint = NULL; + ctx->body = NULL; + if (!strcmp(val, "default")) + ctx->body = &ctx->defbody; + else + { + i = rag_finddollbody(d, val); + if (i >= 0) + ctx->body = &d->body[i]; + else if (!ctx->errors++) + Con_Printf("^[Cannot update body \"%s\"\\edit\\%s %i^]\n", ctx->body->name, d->name, linenum); + } + } + else if (argc == 2 && !stricmp(cmd, "updatejoint")) + { + ctx->joint = NULL; + ctx->body = NULL; + if (!strcmp(val, "default")) + ctx->joint = &ctx->defjoint; + else + { + i = rag_finddolljoint(d, val); + if (i >= 0) + ctx->joint = &d->joint[i]; + else if (!ctx->errors++) + Con_Printf("^[Cannot update joint \"%s\"\\edit\\%s %i^]\n", ctx->joint->name, d->name, linenum); + } + } + + //body properties + else if (ctx->body && argc == 2 && !stricmp(cmd, "shape")) + { + if (!stricmp(val, "box")) + ctx->body->shape = SOLID_PHYSICS_BOX; + else if (!stricmp(val, "sphere")) + ctx->body->shape = SOLID_PHYSICS_SPHERE; + else if (!stricmp(val, "cylinder")) + ctx->body->shape = SOLID_PHYSICS_CYLINDER; + else if (!stricmp(val, "capsule")) + ctx->body->shape = SOLID_PHYSICS_CAPSULE; + else if (!ctx->errors++) + Con_Printf("^[Joint shape \"%s\" not recognised\\edit\\%s %i^]\n", val, d->name, linenum); + } + else if (ctx->body && argc == 2 && !stricmp(cmd, "animate")) + ctx->body->animate = atof(val); + else if (ctx->body && argc == 2 && !stricmp(cmd, "draw")) + ctx->body->draw = atoi(val); + else if (ctx->body && argc == 2 && !stricmp(cmd, "mass")) + ctx->body->mass = atof(val); + else if (ctx->body && argc == 2 && (!stricmp(cmd, "dimensions") || !stricmp(cmd, "size"))) + ctx->body->dimensions[0] = ctx->body->dimensions[1] = ctx->body->dimensions[2] = atof(val); + else if (ctx->body && argc == 3 && (!stricmp(cmd, "dimensions") || !stricmp(cmd, "size"))) + { + ctx->body->dimensions[0] = ctx->body->dimensions[1] = atof(val); + ctx->body->dimensions[2] = atoi(Cmd_Argv(2)); + } + else if (ctx->body && argc == 4 && (!stricmp(cmd, "dimensions") || !stricmp(cmd, "size"))) + { + ctx->body->dimensions[0] = atof(val); + ctx->body->dimensions[1] = atof(Cmd_Argv(2)); + ctx->body->dimensions[2] = atof(Cmd_Argv(3)); + } + + //joint properties + else if (ctx->joint && argc == 2 && !stricmp(cmd, "type")) + { + if (!stricmp(val, "fixed")) + ctx->joint->type = JOINTTYPE_FIXED; + else if (!stricmp(val, "point")) + ctx->joint->type = JOINTTYPE_POINT; + else if (!stricmp(val, "hinge")) + ctx->joint->type = JOINTTYPE_HINGE; + else if (!stricmp(val, "slider")) + ctx->joint->type = JOINTTYPE_SLIDER; + else if (!stricmp(val, "universal")) + ctx->joint->type = JOINTTYPE_UNIVERSAL; + else if (!stricmp(val, "hinge2")) + ctx->joint->type = JOINTTYPE_HINGE2; + } + else if (ctx->joint && argc == 2 && !stricmp(cmd, "draw")) + ctx->joint->draw = atoi(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "ERP")) + ctx->joint->ERP = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "ERP2")) + ctx->joint->ERP2 = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "CFM")) + ctx->joint->CFM = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "CFM2")) + ctx->joint->CFM2 = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "FMax")) + ctx->joint->FMax = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "FMax2")) + ctx->joint->FMax2 = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "HiStop")) + ctx->joint->HiStop = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "HiStop2")) + ctx->joint->HiStop2 = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "LoStop")) + ctx->joint->LoStop = atof(val); + else if (ctx->joint && argc == 2 && !stricmp(cmd, "LoStop2")) + ctx->joint->LoStop2 = atof(val); + else if (ctx->joint && argc == 4 && !stricmp(cmd, "axis")) + { + ctx->joint->axis[0] = atof(val); + ctx->joint->axis[1] = atof(Cmd_Argv(2)); + ctx->joint->axis[2] = atof(Cmd_Argv(3)); + } + else if (ctx->joint && argc == 4 && !stricmp(cmd, "axis2")) + { + ctx->joint->axis2[0] = atof(val); + ctx->joint->axis2[1] = atof(Cmd_Argv(2)); + ctx->joint->axis2[2] = atof(Cmd_Argv(3)); + } + else if (ctx->joint && argc == 4 && !stricmp(cmd, "offset")) + { + ctx->joint->offset[0] = atof(val); + ctx->joint->offset[1] = atof(Cmd_Argv(2)); + ctx->joint->offset[2] = atof(Cmd_Argv(3)); + } + else if (ctx->joint && ctx->joint != &ctx->defjoint && (argc == 2 || argc == 5) && !stricmp(cmd, "pivot")) + { + //the origin is specified in base-frame model space + //we need to make it relative to the joint's bodies + char *bone = val; + i = Mod_TagNumForName(d->model, bone)-1; + if (argc > 2) + { + ctx->joint->offset[0] = atof(Cmd_Argv(2)); + ctx->joint->offset[1] = atof(Cmd_Argv(3)); + ctx->joint->offset[2] = atof(Cmd_Argv(4)); + } + if (i >= 0) + { + ctx->joint->bonepivot = i; + //Matrix3x4_Multiply(omat, bones[i].inverse, joint->orgmatrix); + } + else if (!ctx->errors++) + Con_Printf("^[Directive \"%s\" not understood or invalid\\edit\\%s %i^]\n", cmd, d->name, linenum); + } + else + return false; + + return true; +}; +doll_t *rag_finishdoll(dollcreatectx_t *ctx) +{ + doll_t *d = ctx->d; + int i; + + d->drawn = false; + for (i = 0; i < d->numbodies; i++) + { + if (d->body[i].draw) + { + d->drawn = true; + break; + } + } + if (i == d->numbodies) + for (i = 0; i < d->numjoints; i++) + { + if (d->joint[i].draw) + { + d->drawn = true; + break; + } + } + + free(ctx); + + if (!d->numbodies) + { + rag_freedoll(d); + return NULL; + } + return d; +}; + +doll_t *rag_createdollfromstring(model_t *mod, char *fname, int numbones, char *file) +{ + int linenum = 0; + dollcreatectx_t *ctx; + ctx = rag_createdoll(mod, fname, numbones); + if (!ctx) + return NULL; + + while(file && *file) + { + linenum++; + file = Cmd_TokenizeString(file, false, false); + + if (!rag_dollline(ctx, linenum)) + if (!ctx->errors++) + Con_Printf("^[Directive \"%s\" not understood or invalid\\edit\\%s %i^]\n", Cmd_Argv(0), ctx->d->name, linenum); + } + return rag_finishdoll(ctx); +} + +static doll_t *rag_loaddoll(model_t *mod, char *fname, int numbones) { doll_t *d; void *fptr = NULL; - char *file; int fsize; - int i; - char *cmd; - galiasbone_t *bones; - int errors = 0; for (d = dolllist; d; d = d->next) { @@ -236,168 +630,58 @@ doll_t *rag_loaddoll(model_t *mod, char *fname, int numbones) return d; } - bones = Mod_GetBoneInfo(mod); - if (!bones) - { - //model not skeletal. - return NULL; - } - fsize = FS_LoadFile(fname, &fptr); if (!fptr) - return NULL; - - d = malloc(sizeof(*d)); - d->next = dolllist; - dolllist = d; - d->name = strdup(fname); - d->model = mod; - d->numbodies = 0; - d->body = NULL; - d->numjoints = 0; - d->uses = 0; - d->joint = NULL; - d->numbones = numbones; - d->bone = malloc(sizeof(*d->bone) * d->numbones); - for (i = 0; i < d->numbones; i++) - d->bone[i].bodyidx = -1; - file = fptr; - while(file && *file) { - file = Cmd_TokenizeString(file, false, false); - cmd = Cmd_Argv(0); - - if (!stricmp(cmd, "body")) - { - int boneidx; - boneidx = Mod_TagNumForName(d->model, Cmd_Argv(2))-1; - if (boneidx >= 0) - { - d->body = realloc(d->body, sizeof(*d->body)*(d->numbodies+1)); - Q_strncpyz(d->body[d->numbodies].name, Cmd_Argv(1), sizeof(d->body[d->numbodies].name)); - d->bone[boneidx].bodyidx = d->numbodies; - d->body[d->numbodies].bone = boneidx; - d->numbodies++; - } - else if (!errors++) - Con_Printf("Unable to create body \"%s\" because bone \"%s\" does not exist in \"%s\"\n", Cmd_Argv(1), Cmd_Argv(2), mod->name); - } - else if (!stricmp(cmd, "joint")) - { - odejointinfo_t *joint; - char *name; - d->joint = realloc(d->joint, sizeof(*d->joint)*(d->numjoints+1)); - joint = &d->joint[d->numjoints]; - memset(joint, 0, sizeof(*joint)); - Q_strncpyz(joint->name, Cmd_Argv(1), sizeof(joint->name)); - name = Cmd_Argv(2); - joint->body1 = *name?rag_finddollbody(d, name):-1; - if (*name && joint->body1 < 0 && !errors++) - { - Con_Printf("Joint \"%s\" joints invalid body \"%s\" in \"%s\"\n", joint->name, name, fname); - continue; - } - name = Cmd_Argv(3); - joint->body2 = *name?rag_finddollbody(d, name):-1; - if (*name && (joint->body2 < 0 || joint->body2 == joint->body1) && !errors++) - { - if (joint->body2 == joint->body1) - Con_Printf("Joint \"%s\" joints body \"%s\" to itself in \"%s\"\n", joint->name, name, fname); - else - Con_Printf("Joint \"%s\" joints invalid body \"%s\" in \"%s\"\n", joint->name, name, fname); - continue; - } - joint->orgmatrix[0] = 1; - joint->orgmatrix[4] = 1; - joint->orgmatrix[8] = 1; - joint->bonepivot = d->body[(joint->body2 >= 0)?joint->body2:joint->body1].bone; //default the pivot object to the bone of the second object. - - joint->ERP = 0.4; - joint->ERP2 = 0.4; - joint->CFM = 0.1; - joint->CFM2 = 0.1; - - if (joint->body1 >= 0 || joint->body2 >= 0) - d->numjoints++; - else if (!errors++) - Con_Printf("Joint property \"%s\" not recognised in \"%s\"\n", joint->name, fname); - } - else if (!stricmp(cmd, "setjoint")) - { - int j = rag_finddolljoint(d, Cmd_Argv(1)); - if (j >= 0) - { - odejointinfo_t *joint = &d->joint[j]; - char *prop = Cmd_Argv(2); - char *val = Cmd_Argv(3); - if (!stricmp(prop, "type")) - { - if (!stricmp(val, "fixed")) - joint->type = JOINTTYPE_FIXED; - else if (!stricmp(val, "point")) - joint->type = JOINTTYPE_POINT; - else if (!stricmp(val, "hinge")) - joint->type = JOINTTYPE_HINGE; - else if (!stricmp(val, "slider")) - joint->type = JOINTTYPE_SLIDER; - else if (!stricmp(val, "universal")) - joint->type = JOINTTYPE_UNIVERSAL; - else if (!stricmp(val, "hinge2")) - joint->type = JOINTTYPE_HINGE2; - } - else if (!stricmp(prop, "ERP")) - joint->ERP = atof(val); - else if (!stricmp(prop, "ERP2")) - joint->ERP2 = atof(val); - else if (!stricmp(prop, "CFM")) - joint->CFM = atof(val); - else if (!stricmp(prop, "CFM2")) - joint->CFM2 = atof(val); - else if (!stricmp(prop, "FMax")) - joint->FMax = atof(val); - else if (!stricmp(prop, "FMax2")) - joint->FMax2 = atof(val); - else if (!stricmp(prop, "HiStop")) - joint->HiStop = atof(val); - else if (!stricmp(prop, "HiStop2")) - joint->HiStop2 = atof(val); - else if (!stricmp(prop, "LoStop")) - joint->LoStop = atof(val); - else if (!stricmp(prop, "LoStop2")) - joint->LoStop2 = atof(val); - else if (!stricmp(prop, "origin") || !stricmp(prop, "pivot")) - { - //the origin is specified in base-frame model space - //we need to make it relative to the joint's bodies - float omat[12] = { 1, 0, 0, atoi(Cmd_Argv(3)), - 0, 1, 0, atoi(Cmd_Argv(4)), - 0, 0, 1, atoi(Cmd_Argv(5))}; - char *bone = Cmd_Argv(6); - i = Mod_TagNumForName(d->model, Cmd_Argv(2))-1; - joint->bonepivot = i; - Matrix3x4_Multiply(omat, bones[i].inverse, joint->orgmatrix); - } - else if (!errors++) - Con_Printf("Joint property \"%s\" not recognised in \"%s\"\n", prop, fname); - } - else if (!errors++) - Con_Printf("Joint \"%s\" not yet defined in \"%s\"\n", Cmd_Argv(1), fname); - } +#ifndef SERVERONLY + CL_CheckOrEnqueDownloadFile(fname, NULL, 0); +#endif + return NULL; } + + d = rag_createdollfromstring(mod, fname, numbones, fptr); FS_FreeFile(fptr); + + if (d) + { + d->next = dolllist; + dolllist = d; + } return d; } void rag_freedoll(doll_t *doll) { - free(doll->bone); - free(doll->body); - free(doll->joint); - free(doll); + int i; + if (doll->uses) + { + for (i = 0; i < numskelobjectsused; i++) + { + if (skelobjects[i].doll == doll) + { + rag_uninstanciate(&skelobjects[i]); + if (!doll->uses) + break; + } + } + } + BZ_Free(doll->bone); + BZ_Free(doll->body); + BZ_Free(doll->joint); + free(doll->name); + BZ_Free(doll); } -void rag_flushdolls(void) +void rag_flushdolls(qboolean force) { doll_t *d, **link; + int i; + if (force) + { + for (i = 0; i < numskelobjectsused; i++) + { + rag_uninstanciate(&skelobjects[i]); + } + } for (link = &dolllist; *link; ) { d = *link; @@ -411,7 +695,7 @@ void rag_flushdolls(void) } } -void skel_integrate(progfuncs_t *prinst, skelobject_t *sko, skelobject_t *skelobjsrc, float ft, float mmat[12]) +void skel_integrate(pubprogfuncs_t *prinst, skelobject_t *sko, skelobject_t *skelobjsrc, float ft, float mmat[12]) { #if 0 trace_t t; @@ -531,13 +815,13 @@ void skel_integrate(progfuncs_t *prinst, skelobject_t *sko, skelobject_t *skelob #endif /*destroys all skeletons*/ -void skel_reset(progfuncs_t *prinst) +void skel_reset(pubprogfuncs_t *prinst) { int i; for (i = 0; i < numskelobjectsused; i++) { - if (skelobjects[i].world = prinst->parms->user) + if (skelobjects[i].world == prinst->parms->user) { rag_uninstanciate(&skelobjects[i]); skelobjects[i].numbones = 0; @@ -548,11 +832,11 @@ void skel_reset(progfuncs_t *prinst) while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse) numskelobjectsused--; - rag_flushdolls(); + rag_flushdolls(false); } /*deletes any skeletons marked for deletion*/ -void skel_dodelete(progfuncs_t *prinst) +void skel_dodelete(pubprogfuncs_t *prinst) { int skelidx; if (!pendingkill) @@ -572,58 +856,57 @@ void skel_dodelete(progfuncs_t *prinst) numskelobjectsused--; } -skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount) +skelobject_t *skel_create(pubprogfuncs_t *prinst, int bonecount) { - if (skelidx == 0) - { - //allocation - if (!bonecount) - return NULL; - - for (skelidx = 0; skelidx < numskelobjectsused; skelidx++) - { - if (!skelobjects[skelidx].inuse && skelobjects[skelidx].numbones == bonecount && skelobjects[skelidx].world == prinst->parms->user) - return &skelobjects[skelidx]; - } - - for (skelidx = 0; skelidx <= MAX_SKEL_OBJECTS; skelidx++) - { - if (!skelobjects[skelidx].inuse && - (!skelobjects[skelidx].numbones || skelobjects[skelidx].numbones == bonecount) && - (!skelobjects[skelidx].world || skelobjects[skelidx].world == prinst->parms->user)) - { - if (!skelobjects[skelidx].numbones) - { - skelobjects[skelidx].numbones = bonecount; - skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount); - } - skelobjects[skelidx].world = prinst->parms->user; - if (numskelobjectsused <= skelidx) - numskelobjectsused = skelidx + 1; - skelobjects[skelidx].model = NULL; - skelobjects[skelidx].inuse = 1; - return &skelobjects[skelidx]; - } - } - + unsigned int skelidx; + //invalid if the bonecount is not set... + if (bonecount <= 0 || bonecount > MAX_BONES) return NULL; - } - else + + for (skelidx = 0; skelidx < numskelobjectsused; skelidx++) { - skelidx--; - if ((unsigned int)skelidx >= numskelobjectsused) - return NULL; - if (skelobjects[skelidx].inuse != 1) - return NULL; - if (bonecount && skelobjects[skelidx].numbones != bonecount) - return NULL; - return &skelobjects[skelidx]; + if (!skelobjects[skelidx].inuse && skelobjects[skelidx].numbones == bonecount && skelobjects[skelidx].world == prinst->parms->user) + { + skelobjects[skelidx].inuse = 1; + return &skelobjects[skelidx]; + } } + + for (skelidx = 0; skelidx <= MAX_SKEL_OBJECTS; skelidx++) + { + if (!skelobjects[skelidx].inuse && + (!skelobjects[skelidx].numbones || skelobjects[skelidx].numbones == bonecount) && + (!skelobjects[skelidx].world || skelobjects[skelidx].world == prinst->parms->user)) + { + if (!skelobjects[skelidx].numbones) + { + skelobjects[skelidx].numbones = bonecount; + skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount); + } + skelobjects[skelidx].world = prinst->parms->user; + if (numskelobjectsused <= skelidx) + numskelobjectsused = skelidx + 1; + skelobjects[skelidx].model = NULL; + skelobjects[skelidx].inuse = 1; + return &skelobjects[skelidx]; + } + } + + return NULL; +} +skelobject_t *skel_get(pubprogfuncs_t *prinst, int skelidx) +{ + skelidx--; + if ((unsigned int)skelidx >= numskelobjectsused) + return NULL; + if (skelobjects[skelidx].inuse != 1) + return NULL; + return &skelobjects[skelidx]; } -void skel_lookup(progfuncs_t *prinst, int skelidx, framestate_t *out) +void skel_lookup(pubprogfuncs_t *prinst, int skelidx, framestate_t *out) { - skelobject_t *sko = skel_get(prinst, skelidx, 0); + skelobject_t *sko = skel_get(prinst, skelidx); if (sko && sko->inuse) { out->boneabs = sko->type; @@ -632,10 +915,10 @@ void skel_lookup(progfuncs_t *prinst, int skelidx, framestate_t *out) } } -void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_mmap(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); - skelobject_t *sko = skel_get(prinst, skelidx, 0); + skelobject_t *sko = skel_get(prinst, skelidx); if (!sko || sko->world != prinst->parms->user) G_INT(OFS_RETURN) = 0; else @@ -653,7 +936,7 @@ void rag_uninstanciate(skelobject_t *sko) { World_ODE_RagDestroyBody(sko->world, &sko->body[i].odebody); } - free(sko->body); + BZ_Free(sko->body); sko->body = NULL; sko->numbodies = 0; @@ -661,13 +944,43 @@ void rag_uninstanciate(skelobject_t *sko) { World_ODE_RagDestroyJoint(sko->world, &sko->joint[i]); } - free(sko->joint); + BZ_Free(sko->joint); sko->joint = NULL; sko->numjoints = 0; sko->doll->uses--; sko->doll = NULL; } +void rag_genbodymatrix(skelobject_t *sko, odebodyinfo_t *dollbody, float *emat, float *result) +{ + float *bmat; + int bone = dollbody->bone; + bmat = sko->bonematrix + bone*12; + R_ConcatTransforms((void*)emat, (void*)bmat, (void*)result); + + if (dollbody->orient) + { + float peer[12]; + bone = dollbody->orientpeer; + bmat = sko->bonematrix + bone*12; + + R_ConcatTransforms((void*)emat, (void*)bmat, (void*)peer); + } + + //FIXME: handle biasing it to point away from the parent bone towards an orientation bone +} +qboolean rag_animate(skelobject_t *sko, doll_t *doll, float *emat) +{ + //drive the various animated bodies to their updated positions + int i; + for (i = 0; i < sko->numbodies; i++) + { + if (!doll->body[i].animate) + continue; + rag_genbodymatrix(sko, &doll->body[i], emat, sko->body[i].animmatrix); + } + return true; +} qboolean rag_instanciate(skelobject_t *sko, doll_t *doll, float *emat, wedict_t *ent) { int i; @@ -679,21 +992,28 @@ qboolean rag_instanciate(skelobject_t *sko, doll_t *doll, float *emat, wedict_t odebody_t *body1, *body2; odejointinfo_t *j; sko->numbodies = doll->numbodies; - sko->body = malloc(sizeof(*sko->body) * sko->numbodies); + sko->body = BZ_Malloc(sizeof(*sko->body) * sko->numbodies); sko->doll = doll; doll->uses++; + sko->numanimated = 0; for (i = 0; i < sko->numbodies; i++) { memset(&sko->body[i], 0, sizeof(sko->body[i])); - bone = doll->body[i].bone; - bmat = sko->bonematrix + bone*12; - R_ConcatTransforms((void*)emat, (void*)bmat, (void*)bodymat); - if (!World_ODE_RagCreateBody(sko->world, &sko->body[i].odebody, bodymat, ent)) + sko->body[i].animstrength = doll->body[i].animate; + if (sko->body[i].animstrength) + sko->numanimated++; + + //spawn the body in the base pose, so we can add joints etc (also ignoring the entity matrix, we'll fix all that up later). + if (1) + Matrix3x4_Invert_Simple(bones[doll->body[i].bone].inverse, bodymat); + else + rag_genbodymatrix(sko, &doll->body[i], emat, bodymat); + if (!World_ODE_RagCreateBody(sko->world, &sko->body[i].odebody, &doll->body[i], bodymat, ent)) return false; } sko->numjoints = doll->numjoints; - sko->joint = malloc(sizeof(*sko->joint) * sko->numjoints); + sko->joint = BZ_Malloc(sizeof(*sko->joint) * sko->numjoints); memset(sko->joint, 0, sizeof(*sko->joint) * sko->numjoints); for(i = 0; i < sko->numjoints; i++) { @@ -704,28 +1024,42 @@ qboolean rag_instanciate(skelobject_t *sko, doll_t *doll, float *emat, wedict_t bone = j->bonepivot; bmat = sko->bonematrix + bone*12; - R_ConcatTransforms((void*)bmat, (void*)j->orgmatrix, (void*)bodymat); - R_ConcatTransforms((void*)emat, (void*)bodymat, (void*)worldmat); + if (1) + { + Matrix3x4_Invert_Simple(bones[j->bonepivot].inverse, worldmat); + } + else + { + memcpy(bodymat, bmat, sizeof(bodymat)); + bodymat[3] += j->offset[0]; + bodymat[3+4] += j->offset[1]; + bodymat[3+8] += j->offset[2]; + R_ConcatTransforms((void*)emat, (void*)bodymat, (void*)worldmat); + } aaa2[0][0] = worldmat[3]; aaa2[0][1] = worldmat[3+4]; aaa2[0][2] = worldmat[3+8]; -// P_RunParticleEffectTypeString(aaa2[0], vec3_origin, 1, "te_spike"); + VectorNormalize2(j->axis, aaa2[1]); + VectorNormalize2(j->axis2, aaa2[2]); - aaa2[1][0] = 1; - aaa2[1][1] = 0; - aaa2[1][2] = 0; - - aaa2[2][0] = 0; - aaa2[2][1] = 1; - aaa2[2][2] = 0; - -// VectorCopy(j->offset, aaa2[0]); //fixme: transform these vectors into world space, and transform to match the current positions of the bones. -// VectorCopy(j->axis, aaa2[1]); -// VectorCopy(j->axis2, aaa2[2]); World_ODE_RagCreateJoint(sko->world, &sko->joint[i], j, body1, body2, aaa2); } + + //now the joints have all their various properties, move the bones to their real positions. + //this might result in the body flying across the room... + for (i = 0; i < sko->numbodies; i++) + { + rag_genbodymatrix(sko, &doll->body[i], emat, bodymat); + World_ODE_RagMatrixToBody(&sko->body[i].odebody, bodymat); + } + + sko->doll->numdefaultanimated = sko->numanimated; return true; } + +void CLQ1_AddOrientedCube(shader_t *shader, vec3_t mins, vec3_t maxs, float *matrix, float r, float g, float b, float a); +void CLQ1_AddOrientedCylinder(shader_t *shader, float radius, float height, qboolean capsule, float *matrix, float r, float g, float b, float a); +void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, float b, float a); void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat) { doll_t *doll = sko->doll; @@ -734,19 +1068,106 @@ void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat) galiasbone_t *bones = Mod_GetBoneInfo(sko->model); int i; float invemat[12]; - float bodymat[12]; + float bodymat[12], rel[12]; Matrix3x4_Invert(emat, invemat); +#ifndef SERVERONLY + if (doll->drawn) + { + float rad; + vec3_t mins, maxs; + shader_t *debugshader = NULL; + shader_t *lineshader = NULL; + vec3_t start, end; + for (i = 0; i < sko->numbodies; i++) + { + if (!doll->body[i].draw) + continue; + + if (!debugshader) + debugshader = R_RegisterShader("boneshader", + "{\n" + "polygonoffset\n" + "{\n" + "map $whiteimage\n" + "blendfunc add\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n"); + + World_ODE_RagMatrixFromBody(sko->world, &sko->body[i].odebody, bodymat); + + switch(doll->body[i].shape) + { + default: + case SOLID_PHYSICS_BOX: + VectorScale(doll->body[i].dimensions, -0.5, mins); + VectorScale(doll->body[i].dimensions, 0.5, maxs); + CLQ1_AddOrientedCube(debugshader, mins, maxs, bodymat, 0.2, 0.2, 0.2, 1); + break; + case SOLID_PHYSICS_CYLINDER: + rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5; + CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], false, bodymat, 0.2, 0.2, 0.2, 1); + break; + case SOLID_PHYSICS_CAPSULE: + rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5; + CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], true, bodymat, 0.2, 0.2, 0.2, 1); + break; + case SOLID_PHYSICS_SPHERE: + rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1] + doll->body[i].dimensions[2])/3; + CLQ1_AddOrientedCylinder(debugshader, rad, rad, true, bodymat, 0.2, 0.2, 0.2, 1); + break; + } + } + mins[0] = mins[1] = mins[2] = -1; + maxs[0] = maxs[1] = maxs[2] = 1; + for (i = 0; i < doll->numjoints; i++) + { + if (!doll->joint[i].draw) + continue; + World_ODE_RagMatrixFromJoint(&sko->joint[i], &doll->joint[i], bodymat); + // CLQ1_AddOrientedCube(debugshader, mins, maxs, bodymat, 0, 0.2, 0, 1); + + if (!lineshader) + lineshader = R_RegisterShader("lineshader", + "{\n" + "polygonoffset\n" + "{\n" + "map $whiteimage\n" + "blendfunc add\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n"); + start[0] = bodymat[3]; + start[1] = bodymat[7]; + start[2] = bodymat[11]; + end[0] = bodymat[3] + bodymat[8]*4; + end[1] = bodymat[7] + bodymat[9]*4; + end[2] = bodymat[11] + bodymat[10]*4; + CLQ1_DrawLine(lineshader, start, end, 0, 1, 1, 1); + start[0] = bodymat[3] + bodymat[4]*-2; + start[1] = bodymat[7] + bodymat[5]*-2; + start[2] = bodymat[11] + bodymat[6]*-2; + end[0] = bodymat[3] + bodymat[4]*2; + end[1] = bodymat[7] + bodymat[5]*2; + end[2] = bodymat[11] + bodymat[6]*2; + CLQ1_DrawLine(lineshader, start, end, 1, 1, 0, 1); + } + } +#endif for (i = 0; i < doll->numbones; i++) { if (doll->bone[i].bodyidx >= 0) { + //bones with a body are given an absolute pose matching that body. World_ODE_RagMatrixFromBody(sko->world, &sko->body[doll->bone[i].bodyidx].odebody, bodymat); //that body matrix is in world space, so transform to model space for our result R_ConcatTransforms((void*)invemat, (void*)bodymat, (void*)((float*)bmat+i*12)); } - else if (amat) + else if (amat) //FIXME: don't do this when the bone has an unanimated child body. { //this bone has no joint object, use the anim sko's relative pose info instead if (bones[i].parent >= 0) @@ -754,43 +1175,174 @@ void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat) else memcpy((void*)((float*)bmat+i*12), (void*)((float*)amat+i*12), sizeof(float)*12); } + else + { + //copy from the base pose + Matrix3x4_Invert_Simple(bones[i].inverse, bodymat); + //that's the absolute pose... + if (bones[i].parent >= 0) + { + R_ConcatTransforms((void*)(bones[bones[i].parent].inverse), (void*)bodymat, (void*)rel); + R_ConcatTransforms((void*)(bmat + bones[i].parent*12), (void*)rel, (void*)((float*)bmat+i*12)); + } + else + { + //its all absolute when its the root. + memcpy((void*)((float*)bmat+i*12), bodymat, sizeof(float)*12); + } + } + } + + //if it wasn't before, it definitely is now. + sko->type = SKOT_ABSOLUTE; +} + +//called each physics frame to update the body velocities for animation +void rag_doallanimations(world_t *world) +{ + int i, j; + doll_t *doll; + skelobject_t *sko; + for (i = 0; i < numskelobjectsused; i++) + { + sko = &skelobjects[i]; + if (sko->world != world) + continue; + doll = sko->doll; + if (!doll || !sko->numanimated) + continue; + + for (j = 0; j < sko->numbodies; j++) + { + if (!doll->body[j].animate) + continue; + World_ODE_RagMatrixToBody(&sko->body[j].odebody, sko->body[j].animmatrix); + } } } +#ifndef SERVERONLY +void rag_removedeltaent(lerpents_t *le) +{ + extern world_t csqc_world; + int skelidx = le->skeletalobject; + skelobject_t *skelobj; + + if (!skelidx) + return; + le->skeletalobject = 0; + + skelobj = skel_get(csqc_world.progs, skelidx); + if (skelobj) + { + skelobj->inuse = 2; //2 means don't reuse yet. + skelobj->model = NULL; + pendingkill = true; + } +} + +void rag_updatedeltaent(entity_t *ent, lerpents_t *le) +{ + extern world_t csqc_world; + world_t *w; + model_t *mod = ent->model; + skelobject_t *sko; + float emat[12]; + skelobject_t skorel = {0}; + float relmat[MAX_BONES*12]; + skorel.bonematrix = relmat; + skorel.type = SKOT_RELATIVE; + + if (mod->dollinfo) + { + w = &csqc_world; + if (!w->ode.ode) + return; + + if (!le->skeletalobject) + { + sko = skel_create(w->progs, Mod_GetNumBones(mod, false)); + if (!sko) + return; //couldn't get one, ran out of memory or something? + sko->model = mod; + sko->type = SKOT_RELATIVE; + le->skeletalobject = (sko - skelobjects) + 1; + } + else + { + sko = skel_get(w->progs, le->skeletalobject); + if (!sko) + { + le->skeletalobject = 0; + return; //couldn't get one, ran out of memory or something? + } + } + + skorel.numbones = sko->numbones; + + //FIXME: provide some way for the animation to auto-trigger ragdoll (so framegroups can work automagically) + if (ent->framestate.g[FS_REG].frame[0] == 65535 || ent->framestate.g[FS_REG].frame[1] == 65535) + sko->numanimated = 0; + else if (sko->doll) + sko->numanimated = sko->doll->numdefaultanimated; + Mod_GetBoneRelations(mod, 0, skorel.numbones, &ent->framestate, skorel.bonematrix); + skorel.model = sko->model; + if (sko->numanimated || sko->doll != mod->dollinfo) + { + skel_copy_toabs(sko, &skorel, 0, sko->numbones); + } + + bonemat_fromaxisorg(emat, ent->axis, ent->origin); + + if (sko->doll != mod->dollinfo) + { + rag_uninstanciate(sko); + rag_instanciate(sko, mod->dollinfo, emat, NULL); + } + if (sko->numanimated) + rag_animate(sko, sko->doll, emat); + + rag_derive(sko, sko->numanimated?&skorel:NULL, emat); + + ent->framestate.bonestate = sko->bonematrix; + ent->framestate.bonecount = sko->numbones; + ent->framestate.boneabs = sko->type == SKOT_ABSOLUTE; + } +} +#endif +#endif + +#ifdef SKELETALOBJECTS //update a skeletal object to track its ragdoll/apply a ragdoll to a skeletal object. -void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_ragedit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //do we want to be able to generate a ragdoll object with this function too? #ifdef RAGDOLL wedict_t *wed = (wedict_t*)G_EDICT(prinst, OFS_PARM0); char *ragname = PR_GetStringOfs(prinst, OFS_PARM1); int parentskel = G_FLOAT(OFS_PARM2); - int skelidx = wed->xv->skeletonindex; + int skelidx; skelobject_t *sko, *psko; doll_t *doll; - int i; float emat[12]; - extern cvar_t temp1; - { - vec3_t d[3], a; - //fixme: respond to renderflags&USEAXIS? scale? - a[0] = wed->v->angles[0] * -1; /*mod_alias bug*/ - a[1] = wed->v->angles[1]; - a[2] = wed->v->angles[2]; - AngleVectors(a, d[0], d[1], d[2]); - bonemat_fromqcvectors(emat, d[0], d[1], d[2], wed->v->origin); - skelidx = wed->xv->skeletonindex; - } + vec3_t d[3], a; + //fixme: respond to renderflags&USEAXIS? scale? + a[0] = wed->v->angles[0] * -1; /*mod_alias bug*/ + a[1] = wed->v->angles[1]; + a[2] = wed->v->angles[2]; + AngleVectors(a, d[0], d[1], d[2]); + bonemat_fromqcvectors(emat, d[0], d[1], d[2], wed->v->origin); + skelidx = wed->xv->skeletonindex; G_FLOAT(OFS_RETURN) = 0; //the parent skeletal object must be relative, if specified. - psko = skel_get(prinst, parentskel, 0); + psko = skel_get(prinst, parentskel); if (psko && psko->type != SKOT_RELATIVE) return; - sko = skel_get(prinst, skelidx, 0); + sko = skel_get(prinst, skelidx); if (!sko) { Con_DPrintf("PF_skel_ragedit: invalid skeletal object\n"); @@ -803,47 +1355,86 @@ void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_glob return; } + if (sko->doll) //use the current doll + doll = sko->doll; + else if (sko->model) // + doll = sko->model->dollinfo; + else + doll = NULL; + if (*ragname) { - if (sko->doll && !strcmp(sko->doll->name, ragname)) - doll = sko->doll; - else - doll = rag_loaddoll(sko->model, ragname, sko->numbones); - if (!doll) + int idx; + char *cmd; + + ragname = Cmd_TokenizeString(ragname, false, false); + cmd = Cmd_Argv(0); + if (!stricmp(cmd, "enablejoint")) { - Con_DPrintf("PF_skel_ragedit: invalid doll\n"); + idx = rag_finddolljoint(sko->doll, Cmd_Argv(1)); + World_ODE_RagEnableJoint(&sko->joint[idx], atoi(Cmd_Argv(2))); + G_FLOAT(OFS_RETURN) = 1; + return; + } + else if (!stricmp(cmd, "animatebody")) + { + int body = rag_finddollbody(sko->doll, Cmd_Argv(1)); + float strength = atof(Cmd_Argv(2)); + if (body >= 0) + { + if (sko->body[body].animstrength) + sko->numanimated--; + sko->body[body].animstrength = strength; + if (sko->body[body].animstrength) + sko->numanimated++; + } + G_FLOAT(OFS_RETURN) = sko->numanimated; + return; + } + else if (!stricmp(cmd, "animate")) + { + float strength = atof(Cmd_Argv(1)); + int i; + sko->numanimated = 0; + + for (i = 0; i < sko->numbodies; i++) + { + sko->body[i].animstrength = sko->doll->body[i].animate * strength; + if (sko->body[i].animstrength) + sko->numanimated++; + } + + if (sko->numanimated) + { + //make sure the animation target is valid. + skel_copy_toabs(sko, psko?psko:sko, 0, sko->numbones); + rag_animate(sko, sko->doll, emat); + } + G_FLOAT(OFS_RETURN) = 1; + return; + } + else if (!stricmp(cmd, "doll")) + doll = rag_loaddoll(sko->model, Cmd_Argv(1), sko->numbones); + else if (!stricmp(cmd, "dollstring")) + doll = rag_createdollfromstring(sko->model, "", sko->numbones, ragname); + else if (!stricmp(cmd, "cleardoll")) + doll = NULL; + else + { + Con_Printf("PF_skel_ragedit: Unsupported command.\n"); return; } } - else - { - /*no doll name makes it revert to a normal skeleton*/ - rag_uninstanciate(sko); - G_FLOAT(OFS_RETURN) = 1; - return; - } - if (sko->type != SKOT_ABSOLUTE) + if (sko->doll != doll) { - float tmp[12]; - float *bmat = sko->bonematrix; - galiasbone_t *bones = Mod_GetBoneInfo(sko->model); - for (i = 0; i < sko->numbones; i++) + rag_uninstanciate(sko); + if (!doll) { - //bones without parents are technically already absolute - if (bones[i].parent >= 0) - { - //write to a tmp to avoid premature clobbering - R_ConcatTransforms((void*)(bmat + bones[i].parent*12), (void*)((float*)bmat+i*12), (void*)tmp); - memcpy((void*)(bmat+i*12), tmp, sizeof(tmp)); - } + G_FLOAT(OFS_RETURN) = 1; //technically success. + return; } - sko->type = SKOT_ABSOLUTE; - } - - if (sko->doll != doll || temp1.ival) - { - rag_uninstanciate(sko); + skel_copy_toabs(sko, psko?psko:sko, 0, sko->numbones); if (!rag_instanciate(sko, doll, emat, wed)) { rag_uninstanciate(sko); @@ -851,17 +1442,27 @@ void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_glob G_FLOAT(OFS_RETURN) = 0; return; } + if (sko->numanimated) + rag_animate(sko, doll, emat); + } + else if (!doll) + { + G_FLOAT(OFS_RETURN) = 1; //technically success. + return; + } + else if (sko->numanimated) + { + skel_copy_toabs(sko, psko?psko:sko, 0, sko->numbones); + rag_animate(sko, doll, emat); } rag_derive(sko, psko, emat); -// skel_integrate(prinst, sko, psko, host_frametime, emat); - G_FLOAT(OFS_RETURN) = 1; #endif } //float(float modelindex) skel_create (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; @@ -872,7 +1473,7 @@ void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_glob int type; midx = G_FLOAT(OFS_PARM0); - type = (*prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKOT_RELATIVE; + type = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKOT_RELATIVE; //default to failure G_FLOAT(OFS_RETURN) = 0; @@ -890,7 +1491,7 @@ void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_glob return; //this isn't a skeletal model. } - skelobj = skel_get(prinst, 0, numbones); + skelobj = skel_create(prinst, numbones); if (!skelobj) return; //couldn't get one, ran out of memory or something? @@ -910,7 +1511,7 @@ void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_glob } //float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone) skel_build (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_build(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); @@ -919,7 +1520,7 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global float retainfrac = G_FLOAT(OFS_PARM3); int firstbone = G_FLOAT(OFS_PARM4)-1; int lastbone = G_FLOAT(OFS_PARM5)-1; - float addition = (*prinst->callargc>6)?G_FLOAT(OFS_PARM6):1-retainfrac; + float addition = (prinst->callargc>6)?G_FLOAT(OFS_PARM6):1-retainfrac; int i, j; int numbones; @@ -946,7 +1547,10 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global return; //this isn't a skeletal model. } - skelobj = skel_get(prinst, skelidx, 0); + if (!skelidx) + skelobj = skel_create(prinst, numbones); + else + skelobj = skel_get(prinst, skelidx); if (!skelobj) return; //couldn't get one, ran out of memory or something? @@ -956,6 +1560,8 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global lastbone = numbones; if (firstbone < 0) firstbone = 0; + if (lastbone < firstbone) + lastbone = firstbone; if (skelobj->type != SKOT_RELATIVE) { @@ -969,9 +1575,10 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global if (retainfrac == 0) { - /*replace everything*/ - if (addition == 1) + if (addition == 1) /*replace everything*/ Mod_GetBoneRelations(model, firstbone, lastbone, &fstate, skelobj->bonematrix); + else if (addition == 0) /*wipe it*/ + memset(skelobj->bonematrix + firstbone*12, 0, sizeof(float)*12*(lastbone-firstbone)); else { //scale new @@ -1023,12 +1630,12 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global } //float(float skel) skel_get_numbones (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_get_numbones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); skelobject_t *skelobj; - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj) G_FLOAT(OFS_RETURN) = 0; @@ -1037,13 +1644,13 @@ void QCBUILTIN PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *p } //string(float skel, float bonenum) skel_get_bonename (FTE_CSQC_SKELETONOBJECTS) (returns tempstring) -void QCBUILTIN PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_get_bonename (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); int boneidx = G_FLOAT(OFS_PARM1); skelobject_t *skelobj; - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj) G_INT(OFS_RETURN) = 0; @@ -1054,13 +1661,13 @@ void QCBUILTIN PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *p } //float(float skel, float bonenum) skel_get_boneparent (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_get_boneparent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); int boneidx = G_FLOAT(OFS_PARM1); skelobject_t *skelobj; - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj) G_FLOAT(OFS_RETURN) = 0; @@ -1069,13 +1676,13 @@ void QCBUILTIN PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s } //float(float skel, string tagname) skel_find_bone (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_find_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); char *bname = PR_GetStringOfs(prinst, OFS_PARM1); skelobject_t *skelobj; - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj) G_FLOAT(OFS_RETURN) = 0; else @@ -1083,12 +1690,12 @@ void QCBUILTIN PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_g } //vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) -void QCBUILTIN PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_get_bonerel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); int boneidx = G_FLOAT(OFS_PARM1)-1; - skelobject_t *skelobj = skel_get(prinst, skelidx, 0); + skelobject_t *skelobj = skel_get(prinst, skelidx); if (!skelobj || (unsigned int)boneidx >= skelobj->numbones) bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN)); else if (skelobj->type!=SKOT_RELATIVE) @@ -1107,14 +1714,14 @@ void QCBUILTIN PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr } //vector(float skel, float bonenum) skel_get_boneabs (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc) -void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_get_boneabs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); int boneidx = G_FLOAT(OFS_PARM1)-1; float workingm[12], tempmatrix[3][4]; int i; - skelobject_t *skelobj = skel_get(prinst, skelidx, 0); + skelobject_t *skelobj = skel_get(prinst, skelidx); if (!skelobj || (unsigned int)boneidx >= skelobj->numbones) bonematident_toqcvectors(w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_RETURN)); @@ -1149,7 +1756,7 @@ void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr } //void(entity ent, float bonenum, vector org, optional fwd, right, up) skel_set_bone_world (FTE_CSQC_SKELETONOBJECTS2) (reads v_forward etc) -void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_set_bone_world (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; wedict_t *ent = G_WEDICT(prinst, OFS_PARM0); @@ -1160,7 +1767,7 @@ void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s float childworld[12], parentinv[12]; /*sort out the parameters*/ - if (*prinst->callargc == 4) + if (prinst->callargc == 4) { vec3_t d[3], a; a[0] = G_VECTOR(OFS_PARM3)[0] * -1; /*mod_alias bug*/ @@ -1171,7 +1778,7 @@ void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s } else { - if (*prinst->callargc > 5) + if (prinst->callargc > 5) { matrix[0] = G_VECTOR(OFS_PARM3); matrix[1] = G_VECTOR(OFS_PARM4); @@ -1187,7 +1794,7 @@ void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s } /*make sure the skeletal object is correct*/ - skelobj = skel_get(prinst, ent->xv->skeletonindex, 0); + skelobj = skel_get(prinst, ent->xv->skeletonindex); if (!skelobj || boneidx >= skelobj->numbones) return; @@ -1216,7 +1823,7 @@ void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s } //void(float skel, float bonenum, vector org) skel_set_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) -void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_set_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); @@ -1225,7 +1832,7 @@ void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl skelobject_t *skelobj; float *bone; - if (*prinst->callargc > 5) + if (prinst->callargc > 5) { matrix[0] = G_VECTOR(OFS_PARM3); matrix[1] = G_VECTOR(OFS_PARM4); @@ -1238,7 +1845,7 @@ void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl matrix[2] = w->g.v_up; } - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj || boneidx >= skelobj->numbones) return; @@ -1247,7 +1854,7 @@ void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl } //void(float skel, float bonenum, vector org [, vector fwd, vector right, vector up]) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) -void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_mul_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); @@ -1255,12 +1862,12 @@ void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl float temp[3][4]; float mult[3][4]; skelobject_t *skelobj; - if (*prinst->callargc > 5) + if (prinst->callargc > 5) bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM3), G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM2)); else bonemat_fromqcvectors((float*)mult, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_PARM2)); - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj || boneidx >= skelobj->numbones) return; //testme @@ -1271,7 +1878,7 @@ void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_gl } //void(float skel, float startbone, float endbone, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) -void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_mul_bones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; int skelidx = G_FLOAT(OFS_PARM0); @@ -1280,12 +1887,12 @@ void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_g float temp[3][4]; float mult[3][4]; skelobject_t *skelobj; - if (*prinst->callargc > 6) + if (prinst->callargc > 6) bonemat_fromqcvectors((float*)mult, G_VECTOR(OFS_PARM4), G_VECTOR(OFS_PARM5), G_VECTOR(OFS_PARM6), G_VECTOR(OFS_PARM3)); else bonemat_fromqcvectors((float*)mult, w->g.v_forward, w->g.v_right, w->g.v_up, G_VECTOR(OFS_PARM3)); - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (!skelobj) return; @@ -1308,7 +1915,7 @@ void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_g } //void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_copybones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skeldst = G_FLOAT(OFS_PARM0); int skelsrc = G_FLOAT(OFS_PARM1); @@ -1318,8 +1925,8 @@ void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_g skelobject_t *skelobjdst; skelobject_t *skelobjsrc; - skelobjdst = skel_get(prinst, skeldst, 0); - skelobjsrc = skel_get(prinst, skelsrc, 0); + skelobjdst = skel_get(prinst, skeldst); + skelobjsrc = skel_get(prinst, skelsrc); if (!skelobjdst || !skelobjsrc) return; if (startbone == -1) @@ -1345,35 +1952,22 @@ void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_g else if (skelobjsrc->type == SKOT_RELATIVE && skelobjdst->type == SKOT_ABSOLUTE) { /*copy from relative to absolute*/ - - galiasbone_t *boneinfo = Mod_GetBoneInfo(skelobjsrc->model); - if (!boneinfo) - return; - while(startbone < endbone) - { - if (boneinfo[startbone].parent >= 0) - { - Matrix3x4_Multiply(skelobjsrc->bonematrix+12*startbone, skelobjdst->bonematrix+12*boneinfo[startbone].parent, skelobjdst->bonematrix+12*startbone); - } - else - { - Vector4Copy(skelobjsrc->bonematrix+12*startbone+0, skelobjdst->bonematrix+12*startbone+0); - Vector4Copy(skelobjsrc->bonematrix+12*startbone+4, skelobjdst->bonematrix+12*startbone+4); - Vector4Copy(skelobjsrc->bonematrix+12*startbone+8, skelobjdst->bonematrix+12*startbone+8); - } - - startbone++; - } + skel_copy_toabs(skelobjdst, skelobjsrc, startbone, endbone); + } + else + { + /*copy from absolute to relative*/ + //FIXME } } //void(float skel) skel_delete (FTE_CSQC_SKELETONOBJECTS) -void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skel_delete (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int skelidx = G_FLOAT(OFS_PARM0); skelobject_t *skelobj; - skelobj = skel_get(prinst, skelidx, 0); + skelobj = skel_get(prinst, skelidx); if (skelobj) { skelobj->inuse = 2; //2 means don't reuse yet. @@ -1383,7 +1977,7 @@ void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_glob } //vector(entity ent, float tag) gettaginfo (DP_MD3_TAGSINFO) -void QCBUILTIN PF_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_gettaginfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; wedict_t *ent = G_WEDICT(prinst, OFS_PARM0); @@ -1421,7 +2015,7 @@ void QCBUILTIN PF_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globa } //vector(entity ent, string tagname) gettagindex (DP_MD3_TAGSINFO) -void QCBUILTIN PF_gettagindex (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; wedict_t *ent = G_WEDICT(prinst, OFS_PARM0); @@ -1437,7 +2031,7 @@ const char *Mod_FrameNameForNum(model_t *model, int num); const char *Mod_SkinNameForNum(model_t *model, int num); //string(float modidx, float framenum) frametoname -void QCBUILTIN PF_frametoname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; unsigned int modelindex = G_FLOAT(OFS_PARM0); @@ -1452,7 +2046,7 @@ void QCBUILTIN PF_frametoname (progfuncs_t *prinst, struct globalvars_s *pr_glob } //string(float modidx, float skinnum) skintoname -void QCBUILTIN PF_skintoname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; unsigned int modelindex = G_FLOAT(OFS_PARM0); @@ -1466,7 +2060,7 @@ void QCBUILTIN PF_skintoname (progfuncs_t *prinst, struct globalvars_s *pr_globa G_INT(OFS_RETURN) = 0; //null string (which is also empty in qc) } -void QCBUILTIN PF_frameforname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; unsigned int modelindex = G_FLOAT(OFS_PARM0); @@ -1478,7 +2072,7 @@ void QCBUILTIN PF_frameforname (progfuncs_t *prinst, struct globalvars_s *pr_glo else G_FLOAT(OFS_RETURN) = -1; } -void QCBUILTIN PF_frameduration (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; unsigned int modelindex = G_FLOAT(OFS_PARM0); @@ -1490,7 +2084,7 @@ void QCBUILTIN PF_frameduration (progfuncs_t *prinst, struct globalvars_s *pr_gl else G_FLOAT(OFS_RETURN) = 0; } -void QCBUILTIN PF_skinforname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifndef SERVERONLY world_t *w = prinst->parms->user; diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 42ace103..5a9eac1c 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -183,7 +183,8 @@ void R2D_Init(void) "program defaultfill\n" "{\n" "map $whiteimage\n" - "rgbgen vertex\n" + "rgbgen exactvertex\n" + "alphagen vertex\n" "}\n" "}\n"); shader_draw_fill_trans = R_RegisterShader("fill_trans", @@ -247,44 +248,7 @@ void R2D_Init(void) "{\n" "if $glsl && gl_menutint_shader != 0\n" "[\n" - "glslprogram\n" - "{\n" - "#ifdef VERTEX_SHADER\n" - "\ - attribute vec2 v_texcoord;\ - varying vec2 texcoord;\ - uniform vec3 rendertexturescale;\ - void main(void)\ - {\ - texcoord.x = v_texcoord.x*rendertexturescale.x;\ - texcoord.y = (1.0-v_texcoord.y)*rendertexturescale.y;\ - gl_Position = ftetransform();\ - }\ - \n" - "#endif\n" - "#ifdef FRAGMENT_SHADER\n" - "\ - varying vec2 texcoord;\ - uniform vec3 colorparam;\ - uniform sampler2D s_t0;\ - uniform int invert;\ - const vec3 lumfactors = vec3(0.299, 0.587, 0.114);\ - const vec3 invertvec = vec3(1.0, 1.0, 1.0);\ - void main(void)\ - {\ - vec3 texcolor = texture2D(s_t0, texcoord).rgb;\ - float luminance = dot(lumfactors, texcolor);\ - texcolor = vec3(luminance, luminance, luminance);\ - texcolor *= colorparam;\ - texcolor = (invert > 0) ? (invertvec - texcolor) : texcolor;\ - gl_FragColor = vec4(texcolor, 1.0);\ - }\n" - "#endif\n" - "}\n" - "param cvari r_menutint_inverse invert\n" - "param cvar3f r_menutint colorparam\n" - "param rendertexturescale rendertexturescale\n" - + "program menutint\n" "{\n" "map $currentrender\n" "}\n" @@ -631,20 +595,58 @@ void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue) } } +#ifdef _WIN32 +#include +#endif void R2D_Font_Callback(struct cvar_s *var, char *oldvalue) { if (font_conchar) Font_Free(font_conchar); + font_conchar = NULL; if (qrenderer == QR_NONE) + return; + +#ifdef _WIN32 + if (!strcmp(var->string, "?")) { - font_conchar = NULL; + LOGFONT lf = {0}; + CHOOSEFONT cf = {sizeof(cf)}; + extern HWND mainwindow; + extern qboolean WinNT; + font_conchar = Font_LoadFont(8, ""); + + cf.hwndOwner = mainwindow; + cf.iPointSize = (8 * vid.rotpixelheight)/vid.height; + cf.Flags = CF_FORCEFONTEXIST | CF_TTONLY; + cf.lpLogFont = &lf; + + if (ChooseFont(&cf)) + { + char fname[MAX_OSPATH]; + DWORD bufsz = sizeof(fname); + char *keyname; + keyname = va("%s%s%s (TrueType)", lf.lfFaceName, lf.lfWeight>=FW_BOLD?" Bold":"", lf.lfItalic?" Italic":""); + if (ERROR_SUCCESS == RegGetValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, RRF_RT_REG_SZ, NULL, fname, &bufsz)) + { + Cvar_Set(var, fname); + return; + } + keyname = va("%s (OpenType)", lf.lfFaceName); + if (ERROR_SUCCESS == RegGetValue(HKEY_LOCAL_MACHINE, WinNT?"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts":"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Fonts", keyname, RRF_RT_REG_SZ, NULL, fname, &bufsz)) + { + Cvar_Set(var, fname); + return; + } + } + Cvar_Set(var, ""); return; } +#endif - font_conchar = Font_LoadFont(8*vid.rotpixelheight/vid.height, var->string); + font_conchar = Font_LoadFont(8, var->string); if (!font_conchar && *var->string) - font_conchar = Font_LoadFont(8*vid.rotpixelheight/vid.height, ""); + font_conchar = Font_LoadFont(8, ""); } // console size manipulation callbacks @@ -726,6 +728,10 @@ void R2D_Console_Resize(void) Cvar_ForceCallback(&gl_font); +#if defined(MENU_DAT) || defined(CSQC_DAT) + PR_ResetFonts(false); +#endif + #ifdef PLUGINS Plug_ResChanged(); #endif @@ -1106,13 +1112,11 @@ void R2D_DrawCrosshair(void) for (sc = 0; sc < cl.splitclients; sc++) { SCR_CrosshairPosition(sc, &x, &y); - Font_BeginScaledString(font_conchar, x, y, &sx, &sy); - sizex = Font_CharWidth('+' | 0xe000 | CON_WHITEMASK) * size; - sizey = Font_CharHeight() * size; - sx -= sizex/2; - sy -= sizey/2; + Font_BeginScaledString(font_conchar, x, y, size, size, &sx, &sy); + sx -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; + sy -= Font_CharHeight()/2; Font_ForceColour(ch_color[0], ch_color[1], ch_color[2], crosshairalpha.value); - Font_DrawScaleChar(sx, sy, sizex, sizey, '+' | 0xe000 | CON_WHITEMASK); + Font_DrawScaleChar(sx, sy, '+' | 0xe000 | CON_WHITEMASK); Font_InvalidateColour(); Font_EndString(font_conchar); } diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index f210b095..c2267aa9 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2380,6 +2380,10 @@ void Surf_LightmapMode(void) switch(qrenderer) { + case QR_SOFTWARE: + lightmap_bytes = 4; + lightmap_bgra = true; + break; #ifdef D3DQUAKE case QR_DIRECT3D9: case QR_DIRECT3D11: diff --git a/engine/client/render.h b/engine/client/render.h index 8b38b361..96cd10b0 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -98,7 +98,10 @@ typedef struct entity_s struct model_s *model; // NULL = no model int skinnum; // for Alias models - struct player_info_s *scoreboard; // identify player + int playerindex; //for qw skins + int topcolour; //colourmapping + int bottomcolour; //colourmapping + int h2playerclass; //hexen2's quirky colourmapping // struct efrag_s *efrag; // linked list of efrags (FIXME) // int visframe; // last frame this entity was @@ -427,6 +430,7 @@ extern cvar_t r_shadow_realtime_dlight_ambient; extern cvar_t r_shadow_realtime_dlight_diffuse; extern cvar_t r_shadow_realtime_dlight_specular; extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_shadows; +extern cvar_t r_shadow_shadowmapping; extern cvar_t r_editlights_import_radius; extern cvar_t r_editlights_import_ambient; extern cvar_t r_editlights_import_diffuse; diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 31a96d53..eb4477ef 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -16,6 +16,8 @@ int sh_shadowframe; //index for msurf->shadowframe int r_framecount; struct texture_s *r_notexture_mip; +r_config_t r_config; + qboolean r_blockvidrestart; void R_InitParticleTexture (void); @@ -1060,6 +1062,8 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) pmove.numphysent = 0; + memset(&r_config, 0, sizeof(r_config)); + if (qrenderer != QR_NONE) //graphics stuff only when not dedicated { qbyte *data; @@ -1269,10 +1273,7 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n")); if (cl.worldmodel) { cl.worldmodel = NULL; - cl_numvisedicts = 0; - cl_numstrisidx = 0; - cl_numstrisvert = 0; - cl_numstris = 0; + CL_ClearEntityLists(); //shouldn't really be needed, but we're paranoid TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n")); for (i=1 ; i1 || scr_chatmode) { SCR_VRectForPlayer(&sbar_rect, pnum); } else { //single player sbar takes full screen - - extern cvar_t scr_centersbar; - sbar_rect.width = vid.width; sbar_rect.height = vid.height; sbar_rect.x = 0; sbar_rect.y = 0; - - if (scr_centersbar.ival || (scr_centersbar.ival == 2 && !cl.deathmatch)) - { - sbar_rect.x = (vid.width - 320)/2; - sbar_rect.width -= sbar_rect.x; - } } + sbarwidth = 320; + if (minidmoverlay && vid.width >= 640 && cl.teamplay) + sbarwidth += 320; + else if (minidmoverlay && vid.width >= 512) + sbarwidth += 192; + else + minidmoverlay = 0; + + if (scr_centersbar.ival) + { + int ofs = (sbar_rect.width - sbarwidth)/2; + sbar_rect.x += ofs; + sbar_rect.width -= ofs; + } + + sb_updates++; + + if (sbar_hexen2) { + //hexen2 hud if (sb_lines > 24 || sb_hexen2_extra_info[pnum]) { Sbar_Hexen2DrawExtra(pnum); @@ -2415,12 +2429,12 @@ void Sbar_Draw (void) Sbar_Hexen2DrawInventory(pnum); if (cl.deathmatch) - Sbar_MiniDeathmatchOverlay (); + Sbar_MiniDeathmatchOverlay (pnum); continue; } - - if (sbarfailed) //files failed to load. + else if (sbarfailed) //files failed to load. { + //fallback hud if (cl.playerview[pnum].stats[STAT_HEALTH] <= 0) //when dead, show nothing continue; @@ -2433,66 +2447,74 @@ void Sbar_Draw (void) Sbar_Voice(-24); continue; } - - sb_updates++; - - // top line - if (sb_lines > 24) + else { - if (!cl.spectator || autocam[pnum] == CAM_TRACK) - Sbar_DrawInventory (pnum); - if ((!headsup || sbar_rect.width<512) && cl.deathmatch) - Sbar_DrawFrags (); - } - - // main area - if (sb_lines > 0) - { - if (cl.spectator) + //standard quake(world) hud. + // top line + if (sb_lines > 24) { - if (autocam[pnum] != CAM_TRACK) - { - Sbar_DrawPic (0, 0, 320, 24, sb_scorebar); - Sbar_DrawString (160-7*8,4, "SPECTATOR MODE"); - Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera"); - } - else - { - if (sb_showscores || sb_showteamscores || cl.playerview[pnum].stats[STAT_HEALTH] <= 0) - Sbar_SoloScoreboard (); -// else if (cls.gamemode != GAME_DEATHMATCH) -// Sbar_CoopScoreboard (); - else - Sbar_DrawNormal (pnum); + if (!cl.spectator || autocam[pnum] == CAM_TRACK) + Sbar_DrawInventory (pnum); + if ((!headsup || sbar_rect.width<512) && cl.deathmatch) + Sbar_DrawFrags (); + } - if (hud_tracking_show.ival) + // main area + if (sb_lines > 0) + { + if (cl.spectator) + { + if (autocam[pnum] != CAM_TRACK) { - Q_snprintfz(st, sizeof(st), "Tracking %-.64s", - cl.players[spec_track[pnum]].name); - Sbar_DrawString(0, -8, st); + Sbar_DrawPic (0, 0, 320, 24, sb_scorebar); + Sbar_DrawString (160-7*8,4, "SPECTATOR MODE"); + Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera"); + } + else + { + if (sb_showscores || sb_showteamscores || cl.playerview[pnum].stats[STAT_HEALTH] <= 0) + Sbar_SoloScoreboard (); + // else if (cls.gamemode != GAME_DEATHMATCH) + // Sbar_CoopScoreboard (); + else + Sbar_DrawNormal (pnum); + + if (hud_tracking_show.ival) + { + Q_snprintfz(st, sizeof(st), "Tracking %-.64s", + cl.players[spec_track[pnum]].name); + Sbar_DrawString(0, -8, st); + } } } - } - else if (sb_showscores || sb_showteamscores || (cl.playerview[pnum].stats[STAT_HEALTH] <= 0 && cl.splitclients == 1)) - { - if (!pnum) + else if (sb_showscores || sb_showteamscores || (cl.playerview[pnum].stats[STAT_HEALTH] <= 0 && cl.splitclients == 1)) { - if (cls.gamemode != GAME_DEATHMATCH) - Sbar_CoopScoreboard (); - else - Sbar_SoloScoreboard (); + if (!pnum) + { + if (cls.gamemode != GAME_DEATHMATCH) + Sbar_CoopScoreboard (); + else + Sbar_SoloScoreboard (); + } } + else + Sbar_DrawNormal (pnum); } - else - Sbar_DrawNormal (pnum); - } - if (sb_lines > 24) - Sbar_Voice(-32); - else if (sb_lines > 0) - Sbar_Voice(-8); - else - Sbar_Voice(16); + if (sb_lines > 24) + Sbar_Voice(-32); + else if (sb_lines > 0) + Sbar_Voice(-8); + else + Sbar_Voice(16); + + if (minidmoverlay) + Sbar_MiniDeathmatchOverlay (pnum); + + if (sb_lines > 0) + Sbar_DrawTeamStatus(pnum); + R2D_ImageColours (1, 1, 1, 1); + } } if (cl_sbar.value == 1 || scr_viewsize.value<100) @@ -2505,13 +2527,6 @@ void Sbar_Draw (void) R2D_TileClear (sbar_rect.x + 320, sbar_rect.height - sb_lines, sbar_rect.width - (320), sb_lines); } - - if (sb_lines > 0) - Sbar_DrawTeamStatus(); - - if (sb_lines > 0 && cl.deathmatch) - Sbar_MiniDeathmatchOverlay (); - { extern int scr_chatmode; if (scr_chatmode) @@ -3115,7 +3130,7 @@ frags team name displayed to right of status bar if there's room ================== */ -void Sbar_MiniDeathmatchOverlay (void) +static void Sbar_MiniDeathmatchOverlay (int pnum) { int i, k; int top, bottom; @@ -3126,9 +3141,6 @@ void Sbar_MiniDeathmatchOverlay (void) char name[64+1]; team_t *tm; - if (sbar_rect.width < 512 || !sb_lines) - return; // not enuff room - // scores Sbar_SortFrags (false, false); if (sbar_rect.width >= 640) @@ -3138,14 +3150,14 @@ void Sbar_MiniDeathmatchOverlay (void) return; // no one there? // draw the text - y = sbar_rect.height - sb_lines - 1; + y = sbar_rect.y + sbar_rect.height - sb_lines - 1; numlines = sb_lines/8; if (numlines < 3) return; // not enough room // find us for (i=0 ; i < scoreboardlines; i++) - if (fragsort[i] == cl.playernum[0]) + if (fragsort[i] == cl.playernum[pnum]) break; if (i == scoreboardlines) // we're not there, we are probably a spectator, just display top @@ -3158,9 +3170,9 @@ void Sbar_MiniDeathmatchOverlay (void) if (i < 0) i = 0; - x = 324; + x = sbar_rect.x + 320 + 4; - for (/* */ ; i < scoreboardlines && y < sbar_rect.height - 8 + 1; i++) + for (/* */ ; i < scoreboardlines && y < sbar_rect.y + sbar_rect.height - 8 + 1; i++) { k = fragsort[i]; s = &cl.players[k]; @@ -3185,8 +3197,8 @@ void Sbar_MiniDeathmatchOverlay (void) Font_BeginString(font_conchar, x+24, y, &px, &py); Font_DrawChar ( px, py, num[2] | 0xe000 | CON_WHITEMASK); - if ((cl.spectator && k == spec_track[0]) || - (!cl.spectator && k == cl.playernum[0])) + if ((cl.spectator && k == spec_track[pnum]) || + (!cl.spectator && k == cl.playernum[pnum])) { Font_BeginString(font_conchar, x, y, &px, &py); Font_DrawChar ( px, py, 16 | 0xe000 | CON_WHITEMASK); @@ -3230,7 +3242,7 @@ void Sbar_MiniDeathmatchOverlay (void) sprintf (num, "%5i", tm->frags); Draw_FunString(x + 40, y, num); - if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) + if (!strncmp(cl.players[cl.playernum[pnum]].team, tm->team, 16)) { Font_BeginString(font_conchar, x-8, y, &px, &py); Font_DrawChar(px, py, 16|0xe000|CON_WHITEMASK); diff --git a/engine/client/screen.h b/engine/client/screen.h index 0f3785bf..b52498ce 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -96,20 +96,19 @@ int SCR_GetLoadingStage(void); void SCR_SetLoadingStage(int stage); void SCR_SetLoadingFile(char *str); - /*fonts*/ void Font_Init(void); void Font_Shutdown(void); struct font_s *Font_LoadFont(int height, char *fontfilename); void Font_Free(struct font_s *f); void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); -void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px, float *py); /*avoid using*/ +void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/ void Font_Transform(int vx, int vy, int *px, int *py); int Font_CharHeight(void); int Font_CharWidth(unsigned int charcode); int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode); int Font_DrawChar(int px, int py, unsigned int charcode); -float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int charcode); /*avoid using*/ +float Font_DrawScaleChar(float px, float py, unsigned int charcode); /*avoid using*/ void Font_EndString(struct font_s *font); void Font_ForceColour(float r, float g, float b, float a); //This colour will be applied while the char mask remains WHITE. If you print char by char, make sure to include the mask. void Font_InvalidateColour(void); @@ -119,6 +118,7 @@ int Font_LineWidth(conchar_t *start, conchar_t *end); void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end); extern struct font_s *font_conchar; extern struct font_s *font_tiny; +void PR_ResetFonts(qboolean purge); //for menu/csqc /*end fonts*/ void R_NetgraphInit(void); diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 4b0d6786..8bb27c53 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -1548,6 +1548,9 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f if (!sfx || !*sfx->name) //no named sounds would need specific starting. return; + if (cls.demoseeking) + return; + S_LockMixer(); for (sc = sndcardinfo; sc; sc = sc->next) S_StartSoundCard(sc, entnum, entchannel, sfx, origin, fvol, attenuation, -(int)(timeofs * sc->sn.speed), pitchadj); diff --git a/engine/client/sys_npfte.c b/engine/client/sys_npfte.c index 25bafd44..a1a96a22 100644 --- a/engine/client/sys_npfte.c +++ b/engine/client/sys_npfte.c @@ -689,10 +689,10 @@ NPError OSCALL NP_GetValue(void *instance, NPPVariable variable, void *value) switch(variable) { case NPPVpluginNameString: - *(char**)value = "FTE QuakeWorld"; + *(char**)value = FULLENGINENAME; break; case NPPVpluginDescriptionString: - *(char**)value = "FTE QuakeWorld"; + *(char**)value = FULLENGINENAME; break; default: return NPERR_INVALID_PARAM; diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 54664d1c..22c63e76 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -305,7 +305,7 @@ void *Sys_GetGameAPI (void *parms) #endif -#define MINIMUM_WIN_MEMORY 0x0800000 +#define MINIMUM_WIN_MEMORY MINIMUM_MEMORY #define MAXIMUM_WIN_MEMORY 0x8000000 int starttime; @@ -1143,11 +1143,47 @@ double Sys_DoubleTime (void) ///////////////////////////////////////////////////////////// //clipboard HANDLE clipboardhandle; +char *cliputf8; char *Sys_GetClipboard(void) { char *clipText; + unsigned short *clipWText; if (OpenClipboard(NULL)) { + extern cvar_t com_parseutf8; + //windows programs interpret CF_TEXT as ansi (aka: gibberish) + //so grab utf-16 text and convert it to utf-8 if our console parsing is set to accept that. + if (com_parseutf8.ival > 0) + { + clipboardhandle = GetClipboardData(CF_UNICODETEXT); + if (clipboardhandle) + { + clipWText = GlobalLock(clipboardhandle); + if (clipWText) + { + unsigned int l, c; + for (l = 0; clipWText[l]; l++) + ; + l = l*4 + 1; + clipText = cliputf8 = malloc(l); + while(*clipWText) + { + c = utf8_encode(clipText, *clipWText++, l); + if (!c) + break; + l -= c; + clipText += c; + } + *clipText = 0; + return cliputf8; + } + + //failed at the last hurdle + + GlobalUnlock(clipboardhandle); + } + } + clipboardhandle = GetClipboardData(CF_TEXT); if (clipboardhandle) { @@ -1170,6 +1206,8 @@ void Sys_CloseClipboard(char *bf) { if (clipboardhandle) { + free(cliputf8); + cliputf8 = NULL; GlobalUnlock(clipboardhandle); CloseClipboard(); clipboardhandle = NULL; @@ -1179,6 +1217,8 @@ void Sys_SaveClipboard(char *text) { HANDLE glob; char *temp; + unsigned short *tempw; + extern cvar_t com_parseutf8; if (!OpenClipboard(NULL)) return; EmptyClipboard(); @@ -1190,15 +1230,40 @@ void Sys_SaveClipboard(char *text) return; } - temp = GlobalLock(glob); - if (temp != NULL) + if (com_parseutf8.ival > 0) { - strcpy(temp, text); - GlobalUnlock(glob); - SetClipboardData(CF_TEXT, glob); + glob = GlobalAlloc(GMEM_MOVEABLE, (strlen(text) + 1)*2); + if (glob) + { + tempw = GlobalLock(glob); + if (tempw != NULL) + { + int error; + while(*text) + { + *tempw++ = utf8_decode(&error, text, &text); + } + *tempw = 0; + GlobalUnlock(glob); + SetClipboardData(CF_UNICODETEXT, glob); + } + else + GlobalFree(glob); + } } else - GlobalFree(glob); + { + //yes, quake chars will get mangled horribly. + temp = GlobalLock(glob); + if (temp != NULL) + { + strcpy(temp, text); + GlobalUnlock(glob); + SetClipboardData(CF_TEXT, glob); + } + else + GlobalFree(glob); + } CloseClipboard(); } @@ -1236,8 +1301,16 @@ char *Sys_ConsoleInput (void) if (numevents <= 0) break; - if (!ReadConsoleInput(hinput, recs, 1, &numread)) - Sys_Error ("Error reading console input"); + if (WinNT) + { + if (!ReadConsoleInputW(hinput, recs, 1, &numread)) + Sys_Error ("Error reading console input"); + } + else + { + if (!ReadConsoleInputA(hinput, recs, 1, &numread)) + Sys_Error ("Error reading console input"); + } if (numread != 1) Sys_Error ("Couldn't read console input"); @@ -1246,7 +1319,7 @@ char *Sys_ConsoleInput (void) { if (recs[0].Event.KeyEvent.bKeyDown) { - ch = recs[0].Event.KeyEvent.uChar.AsciiChar; + ch = recs[0].Event.KeyEvent.uChar.UnicodeChar; switch (ch) { @@ -1300,9 +1373,9 @@ char *Sys_ConsoleInput (void) } } else if (ch >= ' ') { - WriteFile(houtput, &ch, 1, &dummy, NULL); - text[len] = ch; - len = (len + 1) & 0xff; + i = utf8_encode(text+len, ch, sizeof(text)-1-len); + WriteFile(houtput, text+len, i, &dummy, NULL); + len += i; } break; @@ -1331,8 +1404,12 @@ BOOL WINAPI HandlerRoutine (DWORD dwCtrlType) return false; } +#ifndef CP_UTF8 +#define CP_UTF8 65001 +#endif qboolean Sys_InitTerminal (void) { + DWORD m; if (!AllocConsole()) return false; @@ -1345,10 +1422,15 @@ qboolean Sys_InitTerminal (void) #endif SetConsoleCtrlHandler (HandlerRoutine, TRUE); + SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8); SetConsoleTitle (FULLENGINENAME " dedicated server"); hinput = GetStdHandle (STD_INPUT_HANDLE); houtput = GetStdHandle (STD_OUTPUT_HANDLE); + GetConsoleMode(hinput, &m); + SetConsoleMode(hinput, m | 0x40 | 0x80); + return true; } void Sys_CloseTerminal (void) @@ -1896,6 +1978,212 @@ void Win7_TaskListInit(void) } #endif + +#if defined(SVNREVISION) + #if defined(OFFICIAL_RELEASE) + #define BUILDTYPE "dev" + #define UPDATE_URL "http://triptohell.info/moodles/" + #define UPDATE_URL_VERSION UPDATE_URL "version.txt" + #ifdef _WIN64 + #define UPDATE_URL_BUILD UPDATE_URL "win64/fte" EXETYPE ".exe" + #else + #define UPDATE_URL_BUILD UPDATE_URL "win32/fte" EXETYPE ".exe" + #endif + #else + #define BUILDTYPE "rel" + #endif +#endif + +#if defined(SERVERONLY) + #define EXETYPE "qwsv" //not gonna happen, but whatever. +#elif defined(GLQUAKE) && defined(D3DQUAKE) + #define EXETYPE "qw" +#elif defined(GLQUAKE) + #ifdef MINIMAL + #define EXETYPE "minglqw" + #else + #define EXETYPE "glqw" + #endif +#elif defiend(D3DQUAKE) + #define EXETYPE "d3dqw" +#elif defiend(SWQUAKE) + #define EXETYPE "swqw" +#else + //erm... + #define EXETYPE "qw" +#endif + +#ifdef UPDATE_URL + +void MyRegSetValue(HKEY base, char *keyname, char *valuename, int type, void *data, int datalen) +{ + HKEY subkey; + RegOpenKeyEx(HKEY_CURRENT_USER,keyname, 0, KEY_WRITE, &subkey); + RegSetValueEx(subkey, valuename, 0, type, data, datalen); + RegCloseKey (subkey); +} +void MyRegDeleteKeyValue(HKEY base, char *keyname, char *valuename) +{ + HKEY subkey; + RegOpenKeyEx(HKEY_CURRENT_USER,keyname, 0, KEY_WRITE, &subkey); + RegDeleteValue(subkey, valuename); + RegCloseKey (subkey); +} + +qboolean Update_GetHomeDirectory(char *homedir, int homedirsize) +{ + HMODULE shfolder = LoadLibrary("shfolder.dll"); + DWORD winver = (DWORD)LOBYTE(LOWORD(GetVersion())); + + if (shfolder) + { + HRESULT (WINAPI *dSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath); + dSHGetFolderPath = (void *)GetProcAddress(shfolder, "SHGetFolderPathA"); + if (dSHGetFolderPath) + { + char folder[MAX_PATH]; + // 0x5 == CSIDL_PERSONAL + if (dSHGetFolderPath(NULL, 0x5, NULL, 0, folder) == S_OK) + { + Q_snprintfz(homedir, homedirsize, "%s/My Games/%s/", folder, FULLENGINENAME); + return true; + } + } +// FreeLibrary(shfolder); + } + return false; +} + +#include "fs.h" +void Update_Version_Updated(struct dl_download *dl) +{ + //happens in a thread, avoid va + if (dl->file) + { + if (dl->status == DL_FINISHED) + { + char buf[8192]; + unsigned int size = 0, chunk; + char pendingname[MAX_OSPATH]; + vfsfile_t *pending; + Update_GetHomeDirectory(pendingname, sizeof(pendingname)); + Q_strncatz(pendingname, DISTRIBUTION BUILDTYPE EXETYPE".tmp", sizeof(pendingname)); + pending = VFSOS_Open(pendingname, "wb"); + if (pending) + { + while(1) + { + chunk = VFS_READ(dl->file, buf, sizeof(buf)); + if (!chunk) + break; + size += VFS_WRITE(pending, buf, chunk); + } + VFS_CLOSE(pending); + if (VFS_GETLEN(dl->file) == size) + { + MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1); + } + } + } + } +} +void Update_Versioninfo_Available(struct dl_download *dl) +{ + if (dl->file) + { + if (dl->status == DL_FINISHED) + { + char linebuf[1024]; + while(VFS_GETS(dl->file, linebuf, sizeof(linebuf))) + { + if (!strnicmp(linebuf, "Revision: ", 10)) + { + if (atoi(linebuf+10) > atoi(SVNREVISION)) + { + struct dl_download *dl; + Con_Printf("Downloading update: revision %i\n", atoi(linebuf+10)); + dl = HTTP_CL_Get(UPDATE_URL_BUILD, NULL, Update_Version_Updated); + dl->file = FS_OpenTemp(); +#ifdef MULTITHREAD + DL_CreateThread(dl, NULL, NULL); +#endif + } + } + } + } + } +} +static qboolean doupdatecheck; +void Update_Check(void) +{ + struct dl_download *dl; + if (doupdatecheck) + { + doupdatecheck = false; + dl = HTTP_CL_Get(UPDATE_URL_VERSION, NULL, Update_Versioninfo_Available); + dl->file = FS_OpenTemp(); +#ifdef MULTITHREAD + DL_CreateThread(dl, NULL, NULL); +#endif + } +} + +qboolean Sys_CheckUpdated(void) +{ + if (!strcmp(SVNREVISION, "-")) + return false; //no revision info in this build, meaning its custom built and thus cannot check against the available updated versions. + else if (COM_CheckParm("-noupdate") || COM_CheckParm("--noupdate")) + return false; + else if (!COM_CheckParm("-autoupdate") && !COM_CheckParm("--autoupdate")) + return false; + else if (!COM_CheckParm("--fromfrontend")) + { + char pendingpath[MAX_OSPATH]; + char updatedpath[MAX_QPATH]; + DWORD bufsz; + + PROCESS_INFORMATION childinfo; + STARTUPINFO startinfo; + char *cmdline = GetCommandLineA(); + + memset(&startinfo, 0, sizeof(startinfo)); + startinfo.cb = sizeof(startinfo); + + bufsz = sizeof(pendingpath); + *pendingpath = 0; + RegGetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, RRF_RT_REG_SZ, NULL, pendingpath, &bufsz); + if (*pendingpath) + { + MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE); + Update_GetHomeDirectory(updatedpath, sizeof(updatedpath)); + Q_strncatz(updatedpath, "cur" BUILDTYPE EXETYPE".exe", sizeof(updatedpath)); + if (MoveFile(pendingpath, updatedpath)) + MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1); + } + + bufsz = sizeof(updatedpath); + *updatedpath = 0; + RegGetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, RRF_RT_REG_SZ, NULL, updatedpath, &bufsz); + + if (*updatedpath) + { + if (CreateProcess(updatedpath, va("%s --fromfrontend", COM_Parse(cmdline)), NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo)) + return true; + } + } + doupdatecheck = true; + return false; +} +#else +qboolean Sys_CheckUpdated(void) +{ + return false; +} +void Update_Check(void) +{ +} +#endif + /* #ifdef _MSC_VER #include @@ -2027,6 +2315,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin COM_InitArgv (parms.argc, parms.argv); + if (Sys_CheckUpdated()) + return true; + isPlugin = !!COM_CheckParm("-plugin"); if (isPlugin) { @@ -2036,7 +2327,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin if (COM_CheckParm("--version") || COM_CheckParm("-v")) { - printf("version " DISTRIBUTION " " __TIME__ " " __DATE__ "\n"); + printf("version: %s\n", version_string()); return true; } if (COM_CheckParm("-outputdebugstring")) @@ -2148,6 +2439,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin fflush(stdout); } + Update_Check(); + /* main window message loop */ while (1) { diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 2d787ece..e9972b28 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -33,9 +33,7 @@ static cvar_t editaddcr = CVARD("edit_addcr", editaddcr_default, "make sure that static cvar_t edittabspacing = CVARD("edit_tabsize", "4", "How wide tab alignment is"); cvar_t debugger = CVARD("debugger", debugger_default, "When enabled, QC errors and debug events will enable step-by-step tracing."); -#undef pr_trace - -static progfuncs_t *editprogfuncs; +static pubprogfuncs_t *editprogfuncs; typedef struct fileblock_s { struct fileblock_s *next; @@ -64,13 +62,14 @@ static void E_Free(void *mem) #define GETBLOCK(s, ret) ret = (void *)E_Malloc(sizeof(fileblock_t) + s);ret->allocatedlength = s;ret->data = (char *)ret + sizeof(fileblock_t) -void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char *out, int outlen); fileblock_t *GenAsm(int statement) { char linebuf[256]; fileblock_t *b; int l; - PR_GenerateStatementString(editprogfuncs, statement, linebuf, sizeof(linebuf)); + if (!editprogfuncs) + return NULL; + editprogfuncs->GenerateStatementString(editprogfuncs, statement, linebuf, sizeof(linebuf)); l = strlen(linebuf); b = E_Malloc(sizeof(fileblock_t) + l); b->allocatedlength = l; @@ -221,6 +220,12 @@ static qboolean EditorSaveFile(char *s) //returns true if succesful int len=0; int pos=0; char *data; + char native[MAX_OSPATH]; + + if (!FS_NativePath(s, FS_GAMEONLY, native, sizeof(native))) + Con_Printf("Not saving.\n"); + + Con_Printf("Saving to \"%s\"\n", native); for (b = firstblock; b; b = b->next) //find total length required. { @@ -244,16 +249,7 @@ static qboolean EditorSaveFile(char *s) //returns true if succesful } COM_WriteFile(s, data, len); -/* - F = fopen(s, "wt"); - if (!F) - return false; - for (b = firstblock; b; b = b->next) - { - fprintf(F, "%s\n", b->data); - } - fclose(F); -*/ + madechanges = false; editenabled = true; executionlinenum = -1; @@ -447,7 +443,7 @@ void Editor_Key(int key, int unicode) { case K_ESCAPE: if (editprogfuncs) - *editprogfuncs->pr_trace = 0; + editprogfuncs->pr_trace = 0; useeval = false; return; case K_F3: @@ -552,11 +548,14 @@ void Editor_Key(int key, int unicode) } else { - cursorlinenum++; - nb = GenAsm(cursorlinenum); - nb->prev = cursorblock; - cursorblock->next = nb; - cursorblock = nb; + nb = GenAsm(cursorlinenum+1); + if (nb) + { + cursorlinenum++; + nb->prev = cursorblock; + cursorblock->next = nb; + cursorblock = nb; + } } } } @@ -565,7 +564,23 @@ void Editor_Key(int key, int unicode) // case K_BACK: case K_F1: -// Editor_f(); + Con_Printf( + "Editor help:\n" + "F1: Show help\n" + "F2: Open file named on cursor line\n" + "F3: Toggle expression evaluator\n" + "F4: Save file\n" + "F5: Stop tracing (run)\n" + "F6: Print stack trace\n" + "F7: Save file and recompile\n" + "F8: Change current point of execution\n" + "F9: Set breakpoint\n" + "F10: Save file, recompile, reload vm\n" + "F11: Single step\n" + "F12: \n" + "Escape: Abort call, close editor\n" + ); + Cbuf_AddText("toggleconsole\n", RESTRICT_LOCAL); break; // case K_FORWARD: case K_F2: @@ -597,7 +612,7 @@ void Editor_Key(int key, int unicode) case K_F5: /*stop debugging*/ editormodal = false; if (editprogfuncs) - *editprogfuncs->pr_trace = false; + editprogfuncs->pr_trace = false; break; case K_F6: if (editprogfuncs) @@ -605,8 +620,8 @@ void Editor_Key(int key, int unicode) break; case K_F7: /*save+recompile*/ EditorSaveFile(OpenEditorFile); - if (editprogfuncs) - Cbuf_AddText("compile\n", RESTRICT_LOCAL); + if (!editprogfuncs) + Cbuf_AddText("compile; toggleconsole\n", RESTRICT_LOCAL); break; case K_F8: /*move execution point to here - I hope you move to the same function!*/ executionlinenum = cursorlinenum; @@ -850,12 +865,11 @@ static void Draw_Line(int vy, fileblock_t *b, int cursorx) { int nx = 0; int y; - char *tooltip = NULL; + char *tooltip = NULL, *t; int nnx; qbyte *d = b->data; qbyte *c; int i; - extern int mousecursor_x, mousecursor_y; int smx = (mousecursor_x * vid.pixelwidth) / vid.width, smy = (mousecursor_y * vid.pixelheight) / vid.height; unsigned int colour; @@ -999,16 +1013,28 @@ static void Draw_Line(int vy, fileblock_t *b, int cursorx) if (tooltip) { + nx = ((mousecursor_x+16) * vid.pixelwidth) / vid.width; while(*tooltip) { - if (*tooltip == '\n') + for (t = tooltip, smx = nx; *tooltip; tooltip++) { - smy += Font_CharHeight(); - smx = (mousecursor_x * vid.pixelwidth) / vid.width; - tooltip++; + if (*tooltip == '\n') + break; + smx = Font_CharEndCoord(font_conchar, smx, *tooltip); } - else - smx = Font_DrawChar(smx, smy, (COLOR_CYAN<\n"); + Con_Printf("edit [line]\n"); return; } @@ -1288,6 +1315,13 @@ static void Editor_f(void) EditorSaveFile(OpenEditorFile); EditorOpenFile(Cmd_Argv(1), false); // EditorNewFile(); + + if (argc == 3) + { + int line = atoi(Cmd_Argv(2)); + for (cursorlinenum = 1, cursorblock = firstblock; cursorlinenum < line && cursorblock->next; cursorlinenum++) + cursorblock=cursorblock->next; + } } void Editor_Init(void) diff --git a/engine/client/view.c b/engine/client/view.c index 810d1057..293c1095 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1316,6 +1316,7 @@ void R2D_PolyBlend (void); void V_RenderPlayerViews(int plnum) { int oldnuments; + int oldstris; #ifdef SIDEVIEWS int viewnum; #endif @@ -1335,6 +1336,7 @@ void V_RenderPlayerViews(int plnum) } oldnuments = cl_numvisedicts; + oldstris = cl_numstris; CL_LinkViewModel (); Cam_SelfTrack(plnum); @@ -1343,6 +1345,7 @@ void V_RenderPlayerViews(int plnum) R_DrawNameTags(); cl_numvisedicts = oldnuments; + cl_numstris = oldstris; if (scr_chatmode == 2) { diff --git a/engine/client/view.h b/engine/client/view.h index 096d064b..91b25f18 100644 --- a/engine/client/view.h +++ b/engine/client/view.h @@ -32,7 +32,9 @@ void V_RenderView (void); float V_CalcRoll (vec3_t angles, vec3_t velocity); void V_UpdatePalette (qboolean force); void V_ClearCShifts (void); +void V_ClearEntity(entity_t *e); entity_t *V_AddEntity(entity_t *in); void VQ2_AddLerpEntity(entity_t *in); void V_AddAxisEntity(entity_t *in); +void CLQ1_AddShadow(entity_t *ent); int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b); diff --git a/engine/client/winquake.rc b/engine/client/winquake.rc index cefbe2c4..fc551e72 100644 --- a/engine/client/winquake.rc +++ b/engine/client/winquake.rc @@ -59,8 +59,8 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE FONT 16, "Times New Roman", 0, 0, 0x1 BEGIN - CTEXT "FTE QuakeWorld",IDC_STATIC,0,0,67,21,SS_CENTERIMAGE - CTEXT "http://www.fteqw.com",IDC_STATIC,0,23,66,17,SS_CENTERIMAGE + CTEXT FULLENGINENAME,IDC_STATIC,0,0,67,21,SS_CENTERIMAGE + CTEXT ENGINEWEBSITE,IDC_STATIC,0,23,66,17,SS_CENTERIMAGE END diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 1f43f45d..0a43c11d 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // release version #define FTE_VER_MAJOR 1 -#define FTE_VER_MINOR 1 +#define FTE_VER_MINOR 2 //#define VERSION 2.56 #ifndef DISTRIBUTION @@ -191,6 +191,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PSKMODELS //PSK model format (ActorX stuff from UT, though not the format the game itself uses) #define HALFLIFEMODELS //halflife model support (experimental) #define INTERQUAKEMODELS + #define RAGDOLL #define HUFFNETWORK //huffman network compression #define DOOMWADS //doom wad/sprite support @@ -331,6 +332,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef SQL #endif + +#if defined(CSQC_DAT) || !defined(CLIENTONLY) //use ode only if we have a constant world state, and the library is enbled in some form. + #define USEODE 1 + #if !(defined(ODE_STATIC) || defined(ODE_DYNAMIC)) + #undef USEODE + #endif +#endif + +#if defined(ZYMOTICMODELS) || defined(MD5MODELS) || defined(DPMMODELS) || defined(PSKMODELS) || defined(INTERQUAKEMODELS) + #define SKELETALMODELS //defined if we have a skeletal model. +#endif +#if (defined(CSQC_DAT) || !defined(CLIENTONLY)) && defined(SKELETALMODELS) + #define SKELETALOBJECTS //the skeletal objects API is only used if we actually have skeletal models, and gamecode that uses the builtins. +#endif +#if !defined(USEODE) || !defined(SKELETALMODELS) + #undef RAGDOLL //not possible to ragdoll if we don't have certain other features. +#endif + //remove any options that depend upon GL. #ifndef SERVERONLY // undefine things not supported yet for D3D @@ -495,7 +514,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // per-level limits // -#define MAX_EDICTS 32767 // FIXME: ouch! ouch! ouch! +//#define MAX_EDICTS ((1<<22)-1) // expandable up to 22 bits +#define MAX_EDICTS ((1<<18)-1) // expandable up to 22 bits #define MAX_LIGHTSTYLES 255 #define MAX_STANDARDLIGHTSTYLES 64 #define MAX_MODELS 1024 // these are sent over the net as bytes @@ -508,6 +528,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_STYLESTRING 64 +#define MAX_Q2EDICTS 1024 + // // stats are integers communicated to the client by the server // diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 056342f6..1c32e970 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -498,7 +498,7 @@ Cmd_Exec_f */ void Cmd_Exec_f (void) { - char *f; + char *f, *s; char name[256]; if (Cmd_Argc () != 2) @@ -531,8 +531,14 @@ void Cmd_Exec_f (void) if (cl_warncmd.ival || developer.ival) Con_TPrintf (TL_EXECING,name); + s = f; + if (s[0] == '\xef' && s[1] == '\xbb' && s[2] == '\xbf') + { + Con_DPrintf("Ignoring UTF-8 BOM\n"); + s+=3; + } // don't execute anything as if it was from server - Cbuf_InsertText (f, Cmd_FromGamecode() ? RESTRICT_INSECURE : Cmd_ExecLevel, true); + Cbuf_InsertText (s, Cmd_FromGamecode() ? RESTRICT_INSECURE : Cmd_ExecLevel, true); FS_FreeFile(f); } @@ -638,7 +644,7 @@ void Cmd_Alias_f (void) { if (Cvar_FindVar (s)) { - if (Cmd_FromGamecode()) + if (Cmd_IsInsecure()) { snprintf(cmd, sizeof(cmd), "%s_a", s); Con_Printf ("Can't register alias, %s is a cvar\nAlias has been named %s instead\n", s, cmd); @@ -654,7 +660,7 @@ void Cmd_Alias_f (void) // check for overlap with a command if (Cmd_Exists (s)) { - if (Cmd_FromGamecode()) + if (Cmd_IsInsecure()) { snprintf(cmd, sizeof(cmd), "%s_a", s); Con_Printf ("Can't register alias, %s is a command\nAlias has been named %s instead\n", s, cmd); @@ -1117,9 +1123,6 @@ char *Cmd_ExpandCvar(char *cvarname, int maxaccesslevel, int *len) result = strtol(cvarname, &end, 10); // do something with result - if (result == 0) - Con_DPrintf("Cmd_ExpandCvar() strtol returned zero cvar: %s\n", cvarname); - if (fixval && *end == '\0') //only expand $0 if its actually ${0} - this avoids conflicting with the $0 macro { //purely numerical ret = Cmd_Argv(atoi(cvarname)); @@ -1288,6 +1291,11 @@ char *Cmd_ExpandStringArguments (char *data, char *dest, int destlen) str = "%"; old_len = 2; } + else if (data[1] == '#') + { + str = va("\"%s\"", Cmd_Args()); + old_len = 2; + } else if (data[1] == '*') { str = Cmd_Args(); @@ -1817,7 +1825,8 @@ void Cmd_ForwardToServer (void) { if (cls.state == ca_disconnected) { - Con_TPrintf (TL_CANTXNOTCONNECTED, Cmd_Argv(0)); + if (cl_warncmd.ival) + Con_TPrintf (TL_CANTXNOTCONNECTED, Cmd_Argv(0)); return; } @@ -2618,16 +2627,29 @@ void Cmd_set_f(void) Q_strncpyz(name, Cmd_Argv(1), sizeof(name)); - if (Cmd_FromGamecode()) //AAHHHH!!! Q2 set command is different + if (!strcmp(Cmd_Argv(0), "setfl") || Cmd_FromGamecode()) //AAHHHH!!! Q2 set command is different { text = Cmd_Argv(3); - if (!strcmp(text, "u")) - forceflags = CVAR_USERINFO; - else if (!strcmp(text, "s")) - forceflags = CVAR_SERVERINFO; - else if (*text) //err - return; + while(*text) + { + switch(*text++) + { + case 'u': + forceflags |= CVAR_USERINFO; + break; + case 's': + forceflags |= CVAR_SERVERINFO; + break; + case 'a': + forceflags |= CVAR_ARCHIVE; + break; + default: + return; + } + } text = Cmd_Argv(2); + + /*desc = Cmd_Argv(4)*/ } else if (dpcompat_set.ival && !docalc) { @@ -2667,7 +2689,7 @@ void Cmd_set_f(void) if (var) { - if (var->flags & CVAR_NOTFROMSERVER && Cmd_FromGamecode()) + if (var->flags & CVAR_NOTFROMSERVER && Cmd_IsInsecure()) { Con_Printf ("Server tried setting %s cvar\n", var->name); return; @@ -2687,7 +2709,7 @@ void Cmd_set_f(void) if (docalc) text = If_Token(text, &end); Cvar_Set(var, text); - var->flags |= CVAR_USERCREATED; + var->flags |= CVAR_USERCREATED | forceflags; if (!stricmp(Cmd_Argv(0), "seta")) var->flags |= CVAR_ARCHIVE; @@ -2733,7 +2755,7 @@ void Cvar_Inc_f (void) Con_Printf ("Unknown variable \"%s\"\n", Cmd_Argv(1)); return; } - if (var->flags & CVAR_NOTFROMSERVER && Cmd_FromGamecode()) + if (var->flags & CVAR_NOTFROMSERVER && Cmd_IsInsecure()) { Con_Printf ("Server tried setting %s cvar\n", var->name); return; @@ -2985,6 +3007,7 @@ void Cmd_Init (void) Cmd_AddCommand ("toggle", Cmd_toggle_f); Cmd_AddCommand ("set", Cmd_set_f); + Cmd_AddCommand ("setfl", Cmd_set_f); Cmd_AddCommand ("set_calc", Cmd_set_f); Cmd_AddCommand ("seta", Cmd_set_f); Cmd_AddCommand ("seta_calc", Cmd_set_f); diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 2fc43d29..758c7204 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -1924,6 +1924,48 @@ void Mod_CompileTriangleNeighbours(galiasinfo_t *galias) #endif } +typedef struct +{ + int firstpose; + int posecount; + float fps; + qboolean loop; + char name[MAX_QPATH]; +} frameinfo_t; +static frameinfo_t *ParseFrameInfo(char *modelname, int *numgroups) +{ + int count = 0; + int maxcount = 0; + char *line, *file; + frameinfo_t *frames = NULL; + line = file = FS_LoadMallocFile(va("%s.framegroups", modelname)); + if (!file) + return NULL; + while(line && *line) + { + line = Cmd_TokenizeString(line, false, false); + if (Cmd_Argc()) + { + if (count == maxcount) + { + maxcount += 32; + frames = realloc(frames, sizeof(*frames)*maxcount); + } + + frames[count].firstpose = atoi(Cmd_Argv(0)); + frames[count].posecount = atoi(Cmd_Argv(1)); + frames[count].fps = atof(Cmd_Argv(2)); + frames[count].loop = !!atoi(Cmd_Argv(3)); + Q_strncpyz(frames[count].name, Cmd_Argv(4), sizeof(frames[count].name)); + count++; + } + } + BZ_Free(file); + + *numgroups = count; + return frames; +} + void Mod_BuildTextureVectors(galiasinfo_t *galias) //vec3_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx, int numverts) { @@ -2455,6 +2497,7 @@ static void *Q1_LoadSkins_SV (daliasskintype_t *pskintype, qboolean alpha) static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintranstype) { shader_t **shaders; + int *ofstexels; char skinname[MAX_QPATH]; int i; int s, t; @@ -2515,9 +2558,11 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran if (!TEXVALID(texture) || (loadmodel->engineflags & MDLF_NOTREPLACEMENTS)) { //we're not using 24bits - shaders = Hunk_Alloc(sizeof(*shaders)+s); - saved = (qbyte*)(shaders+1); - outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin; + shaders = Hunk_Alloc(sizeof(*shaders)+sizeof(*ofstexels)+s); + ofstexels = (int*)(shaders+1); + saved = (qbyte*)(ofstexels+1); + outskin->ofstexels = (qbyte *)ofstexels - (qbyte *)outskin; + ofstexels[0] = (qbyte *)saved - (qbyte *)ofstexels; memcpy(saved, pskintype+1, s); Mod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); @@ -2621,9 +2666,10 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran intervals = (daliasskininterval_t *)(count+1); outskin->numshaders = LittleLong(count->numskins); data = (qbyte *)(intervals + outskin->numshaders); - shaders = Hunk_Alloc(sizeof(*shaders)*outskin->numshaders); + shaders = Hunk_Alloc(sizeof(*shaders)*outskin->numshaders + sizeof(*ofstexels)*outskin->numshaders); + ofstexels = (int*)(shaders+outskin->numshaders); outskin->ofsshaders = (char *)shaders - (char *)outskin; - outskin->ofstexels = 0; + outskin->ofstexels = (char *)ofstexels - (char *)outskin; sinter = LittleFloat(intervals[0].interval); if (sinter <= 0) sinter = 0.1; @@ -2660,13 +2706,8 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran if (!TEXVALID(texture) || (!TEXVALID(fbtexture) && r_fb_models.ival)) { - if (t == 0) - { - saved = Hunk_Alloc(s); - outskin->ofstexels = (qbyte *)(saved) - (qbyte *)outskin; - } - else - saved = BZ_Malloc(s); + saved = Hunk_Alloc(s); + ofstexels[t] = (qbyte *)(saved) - (qbyte *)ofstexels; memcpy(saved, data, s); Mod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); if (!TEXVALID(texture)) @@ -2681,9 +2722,6 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran Q_snprintfz(skinname, sizeof(skinname), "%s_%i_%i_luma", loadname, i, t); fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA); } - - if (t != 0) //only keep the first. - BZ_Free(saved); } Q_snprintfz(skinname, sizeof(skinname), "%s_%i_%i", loadname, i, t); @@ -2810,7 +2848,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer) switch(qrenderer) { default: -#if defined(GLQUAKE) || defined(D3DQUAKE) +#ifndef SERVERONLY pinstverts = (dstvert_t *)Q1_LoadSkins_GL(skinstart, skintranstype); break; #endif @@ -4631,10 +4669,11 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer) #endif galiasbone_t *bones; galiasgroup_t *group; - float *animmatrix, *basematrix, *basematrix_inverse; + float *animmatrix, *basematrix; index_t *indexes; float vrad; int bonemap[MAX_BONES]; + char *e; pskpnts_t *pnts = NULL; pskvtxw_t *vtxw = NULL; @@ -4904,6 +4943,9 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer) for (i = 0; i < num_boneinfo; i++) { Q_strncpyz(bones[i].name, boneinfo[i].name, sizeof(bones[i].name)); + e = bones[i].name + strlen(bones[i].name); + while(e > bones[i].name && e[-1] == ' ') + *--e = 0; bones[i].parent = boneinfo[i].parent; if (i == 0 && bones[i].parent == 0) bones[i].parent = -1; @@ -4928,10 +4970,9 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer) R_ConcatTransforms((void*)(basematrix + bones[i].parent*12), (void*)tmp, (void*)(basematrix+i*12)); } - basematrix_inverse = Hunk_TempAllocMore(num_boneinfo*sizeof(float)*16); for (i = 0; i < num_boneinfo; i++) { - Matrix3x4_InvertTo4x4_Simple(basematrix+i*12, basematrix_inverse+i*16); + Matrix3x4_Invert_Simple(basematrix+i*12, bones[i].inverse); } @@ -4960,7 +5001,7 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer) vec3_t tmp; trans[num_trans].vertexindex = i; trans[num_trans].boneindex = rawweights[j].boneindex; - VectorTransform(pnts[rawweights[j].pntsindex].origin, (void*)(basematrix_inverse + rawweights[j].boneindex*16), tmp); + VectorTransform(pnts[rawweights[j].pntsindex].origin, (void*)bones[rawweights[j].boneindex].inverse, tmp); VectorScale(tmp, rawweights[j].weight, trans[num_trans].org); trans[num_trans].org[3] = rawweights[j].weight; num_trans++; @@ -5028,7 +5069,29 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer) if (animinfo && animkeys) { - if (dpcompat_psa_ungroup.ival) + int numgroups = 0; + frameinfo_t *frameinfo = ParseFrameInfo(mod->name, &numgroups); + if (numgroups) + { + /*externally supplied listing of frames. ignore all framegroups in the model and use only the pose info*/ + group = Hunk_Alloc(sizeof(galiasgroup_t)*numgroups + num_animkeys*sizeof(float)*12); + animmatrix = (float*)(group+numgroups); + for (j = 0; j < numgroups; j++) + { + //FIXME: bound check + group[j].poseofs = ((char*)animmatrix - (char*)&group[j]) + sizeof(float)*12*num_boneinfo*frameinfo[j].firstpose; + group[j].numposes = frameinfo[j].posecount; + if (*frameinfo[j].name) + snprintf(group[j].name, sizeof(group[j].name), "%s", frameinfo[j].name); + else + snprintf(group[j].name, sizeof(group[j].name), "frame_%i", j); + group[j].loop = frameinfo[j].loop; + group[j].rate = frameinfo[j].fps; + group[j].isheirachical = true; + } + num_animinfo = numgroups; + } + else if (dpcompat_psa_ungroup.ival) { /*unpack each frame of each animation to be a separate framegroup*/ unsigned int iframe; /*individual frame count*/ @@ -5552,8 +5615,6 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer) #endif //DPMMODELS - - #ifdef INTERQUAKEMODELS #define IQM_MAGIC "INTERQUAKEMODEL" #define IQM_VERSION1 1 @@ -5721,7 +5782,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) vec3_t *onorm1, *onorm2, *onorm3; vec4_t *oweight; byte_vec4_t *oindex; - float *opose; + float *opose,*oposebase; vec2_t *otcoords; @@ -5734,8 +5795,9 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) galiasbone_t *bones; index_t *idx; float basepose[12 * MAX_BONES]; - qboolean baseposeonly; qboolean noweights; + frameinfo_t *framegroups; + int numgroups; if (memcmp(h->magic, IQM_MAGIC, sizeof(h->magic))) { @@ -5779,6 +5841,10 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) if (!h->num_meshes) return NULL; + //a mesh must contain vertex coords or its not much of a mesh. + //we also require texcoords because we can. + //we don't require normals + //we don't require weights, but such models won't animate. if (h->num_vertexes > 0 && (!vpos || !tcoord)) { Con_Printf("%s is missing vertex array data\n", loadmodel->name); @@ -5791,10 +5857,40 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) return NULL; } - baseposeonly = !h->num_anims; - strings = buffer + h->ofs_text; + /*try to completely disregard all the info the creator carefully added to their model...*/ + numgroups = 0; + framegroups = NULL; + if (!numgroups) + framegroups = ParseFrameInfo(loadmodel->name, &numgroups); + if (!numgroups && h->num_anims) + { + /*use the model's framegroups*/ + numgroups = h->num_anims; + framegroups = malloc(sizeof(*framegroups)*numgroups); + + anim = (struct iqmanim*)(buffer + h->ofs_anims); + for (i = 0; i < numgroups; i++) + { + framegroups[i].firstpose = LittleLong(anim[i].first_frame); + framegroups[i].posecount = LittleLong(anim[i].num_frames); + framegroups[i].fps = LittleFloat(anim[i].framerate); + framegroups[i].loop = !!(LittleLong(anim[i].flags) & IQM_LOOP); + Q_strncpyz(framegroups[i].name, strings+anim[i].name, sizeof(fgroup[i].name)); + } + } + if (!numgroups) + { /*base frame only*/ + numgroups = 1; + framegroups = malloc(sizeof(*framegroups)); + framegroups->firstpose = -1; + framegroups->posecount = 1; + framegroups->fps = 10; + framegroups->loop = 1; + strcpy(framegroups->name, "base"); + } + mesh = (struct iqmmesh*)(buffer + h->ofs_meshes); /*allocate a nice big block of memory and figure out where stuff is*/ @@ -5802,7 +5898,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) #ifndef SERVERONLY sizeof(*skin)*h->num_meshes + sizeof(*shaders)*h->num_meshes + #endif - sizeof(*fgroup)*(baseposeonly?1:h->num_anims) + sizeof(float)*12*(baseposeonly?h->num_joints:(h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints + + sizeof(*fgroup)*numgroups + sizeof(float)*12*(h->num_joints + (h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints + (sizeof(*opos) + sizeof(*onorm1) + sizeof(*onorm2) + sizeof(*onorm3) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes); bones = (galiasbone_t*)(gai + h->num_meshes); opos = (vecV_t*)(bones + h->num_joints); @@ -5822,9 +5918,10 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) otcoords = (vec2_t*)(oweight + h->num_vertexes); } fgroup = (galiasgroup_t*)(otcoords + h->num_vertexes); - opose = (float*)(fgroup + (baseposeonly?1:h->num_anims)); + oposebase = (float*)(fgroup + numgroups); + opose = oposebase + 12*h->num_joints; #ifndef SERVERONLY - skin = (galiasskin_t*)(opose + 12*(baseposeonly?h->num_joints:h->num_poses*h->num_frames)); + skin = (galiasskin_t*)(opose + 12*(h->num_poses*h->num_frames)); shaders = (shader_t**)(skin + h->num_meshes); #endif @@ -5841,6 +5938,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) vec3_t scale; float mat[12]; + //joint info (mesh) for (i = 0; i < h->num_joints; i++) { Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(bones[i].name)); @@ -5855,6 +5953,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) Matrix3x4_Invert_Simple(&basepose[i*12], bones[i].inverse); } + //pose info (anim) for (i = 0; i < h->num_frames; i++) { for (j = 0, p = ipose; j < h->num_poses; j++, p++) @@ -5884,6 +5983,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) vec3_t scale; float mat[12]; + //joint info (mesh) for (i = 0; i < h->num_joints; i++) { Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(bones[i].name)); @@ -5898,6 +5998,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) Matrix3x4_Invert_Simple(&basepose[i*12], bones[i].inverse); } + //pose info (anim) for (i = 0; i < h->num_frames; i++) { for (j = 0, p = ipose; j < h->num_poses; j++, p++) @@ -5917,34 +6018,33 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) } } } + //basepose + memcpy(oposebase, basepose, sizeof(float)*12 * h->num_joints); - if (baseposeonly) + //now generate the animations. + for (i = 0; i < numgroups; i++) { - fgroup->isheirachical = false; - fgroup->loop = true; - Q_strncpyz(fgroup->name, "base", sizeof(fgroup->name)); - fgroup->numposes = 1; - fgroup->poseofs = (char*)opose - (char*)fgroup; - fgroup->rate = 10; - - memcpy(opose, basepose, sizeof(float)*12 * h->num_joints); - } - else - { - /*load the framegroup info*/ - anim = (struct iqmanim*)(buffer + h->ofs_anims); - for (i = 0; i < h->num_anims; i++) + if ((unsigned)framegroups[i].firstpose >= h->num_frames) + { + //invalid/basepose + fgroup[i].isheirachical = false; + fgroup[i].poseofs = (char*)oposebase - (char*)&fgroup[i]; + fgroup[i].numposes = 1; + } + else { fgroup[i].isheirachical = true; - fgroup[i].loop = !!(LittleLong(anim[i].flags) & IQM_LOOP); - Q_strncpyz(fgroup[i].name, strings+anim[i].name, sizeof(fgroup[i].name)); - fgroup[i].numposes = LittleLong(anim[i].num_frames); - fgroup[i].poseofs = (char*)(opose+LittleLong(anim[i].first_frame)*12*h->num_poses) - (char*)&fgroup[i]; - fgroup[i].rate = LittleFloat(anim[i].framerate); - if (!fgroup[i].rate) - fgroup[i].rate = 10; + fgroup[i].poseofs = (char*)(opose + framegroups[i].firstpose*12*h->num_poses) - (char*)&fgroup[i]; + fgroup[i].numposes = framegroups[i].posecount; } + fgroup[i].loop = framegroups[i].loop; + fgroup[i].rate = framegroups[i].fps; + Q_strncpyz(fgroup[i].name, framegroups[i].name, sizeof(fgroup[i].name)); + + if (fgroup[i].rate <= 0) + fgroup[i].rate = 10; } + free(framegroups); for (i = 0; i < h->num_meshes; i++) { @@ -5954,7 +6054,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) gai[i].shares_bones = 0; gai[i].numbones = h->num_joints; gai[i].ofsbones = (char*)bones - (char*)&gai[i]; - gai[i].groups = baseposeonly?1:h->num_anims; + gai[i].groups = numgroups; gai[i].groupofs = (char*)fgroup - (char*)&gai[i]; offset = LittleLong(mesh[i].first_vertex); @@ -6006,6 +6106,10 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) { Vector4Copy(vbone+i*4, oindex[i]); Vector4Scale(vweight+i*4, 1/255.0, oweight[i]); + + //FIXME: should we be normalising? + if (!oweight[i][0] && !oweight[i][1] && !oweight[i][2] && !oweight[i][3]) + oweight[i][0] = 1; } } for (i = 0; i < h->num_vertexes; i++) @@ -6698,7 +6802,7 @@ qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer) /* EXTERNALANIM -//File what specifies md5 model/anim stuff. +//File that specifies md5 model/anim stuff. model test/imp.md5mesh diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 71bf88fd..e2e0ddcc 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -2,8 +2,7 @@ #include "hash.h" #include "shader.h" -#if defined(ZYMOTICMODELS) || defined(MD5MODELS) -#define SKELETALMODELS +#ifdef SKELETALMODELS #include #endif diff --git a/engine/common/com_phys_ode.c b/engine/common/com_phys_ode.c index 8670cafe..30755f7a 100644 --- a/engine/common/com_phys_ode.c +++ b/engine/common/com_phys_ode.c @@ -270,7 +270,7 @@ void (ODE_API *dMassSetSphereTotal)(dMass *, dReal total_mass, dReal //void (ODE_API *dMassSetCapsule)(dMass *, dReal density, int direction, dReal radius, dReal length); void (ODE_API *dMassSetCapsuleTotal)(dMass *, dReal total_mass, int direction, dReal radius, dReal length); //void (ODE_API *dMassSetCylinder)(dMass *, dReal density, int direction, dReal radius, dReal length); -//void (ODE_API *dMassSetCylinderTotal)(dMass *, dReal total_mass, int direction, dReal radius, dReal length); +void (ODE_API *dMassSetCylinderTotal)(dMass *, dReal total_mass, int direction, dReal radius, dReal length); //void (ODE_API *dMassSetBox)(dMass *, dReal density, dReal lx, dReal ly, dReal lz); void (ODE_API *dMassSetBoxTotal)(dMass *, dReal total_mass, dReal lx, dReal ly, dReal lz); //void (ODE_API *dMassSetTrimesh)(dMass *, dReal density, dGeomID g); @@ -431,8 +431,8 @@ void (ODE_API *dJointGroupDestroy)(dJointGroupID); void (ODE_API *dJointGroupEmpty)(dJointGroupID); //int (ODE_API *dJointGetNumBodies)(dJointID); void (ODE_API *dJointAttach)(dJointID, dBodyID body1, dBodyID body2); -//void (ODE_API *dJointEnable)(dJointID); -//void (ODE_API *dJointDisable)(dJointID); +void (ODE_API *dJointEnable)(dJointID); +void (ODE_API *dJointDisable)(dJointID); //int (ODE_API *dJointIsEnabled)(dJointID); void (ODE_API *dJointSetData)(dJointID, void *data); void * (ODE_API *dJointGetData)(dJointID); @@ -496,31 +496,31 @@ void (ODE_API *dJointSetFixed)(dJointID); //void (ODE_API *dJointSetPlane2DXParam)(dJointID, int parameter, dReal value); //void (ODE_API *dJointSetPlane2DYParam)(dJointID, int parameter, dReal value); //void (ODE_API *dJointSetPlane2DAngleParam)(dJointID, int parameter, dReal value); -//void (ODE_API *dJointGetBallAnchor)(dJointID, dVector3 result); +void (ODE_API *dJointGetBallAnchor)(dJointID, dVector3 result); //void (ODE_API *dJointGetBallAnchor2)(dJointID, dVector3 result); //dReal (ODE_API *dJointGetBallParam)(dJointID, int parameter); -//void (ODE_API *dJointGetHingeAnchor)(dJointID, dVector3 result); +void (ODE_API *dJointGetHingeAnchor)(dJointID, dVector3 result); //void (ODE_API *dJointGetHingeAnchor2)(dJointID, dVector3 result); -//void (ODE_API *dJointGetHingeAxis)(dJointID, dVector3 result); +void (ODE_API *dJointGetHingeAxis)(dJointID, dVector3 result); //dReal (ODE_API *dJointGetHingeParam)(dJointID, int parameter); //dReal (ODE_API *dJointGetHingeAngle)(dJointID); //dReal (ODE_API *dJointGetHingeAngleRate)(dJointID); //dReal (ODE_API *dJointGetSliderPosition)(dJointID); //dReal (ODE_API *dJointGetSliderPositionRate)(dJointID); -//void (ODE_API *dJointGetSliderAxis)(dJointID, dVector3 result); +void (ODE_API *dJointGetSliderAxis)(dJointID, dVector3 result); //dReal (ODE_API *dJointGetSliderParam)(dJointID, int parameter); -//void (ODE_API *dJointGetHinge2Anchor)(dJointID, dVector3 result); +void (ODE_API *dJointGetHinge2Anchor)(dJointID, dVector3 result); //void (ODE_API *dJointGetHinge2Anchor2)(dJointID, dVector3 result); -//void (ODE_API *dJointGetHinge2Axis1)(dJointID, dVector3 result); -//void (ODE_API *dJointGetHinge2Axis2)(dJointID, dVector3 result); +void (ODE_API *dJointGetHinge2Axis1)(dJointID, dVector3 result); +void (ODE_API *dJointGetHinge2Axis2)(dJointID, dVector3 result); //dReal (ODE_API *dJointGetHinge2Param)(dJointID, int parameter); //dReal (ODE_API *dJointGetHinge2Angle1)(dJointID); //dReal (ODE_API *dJointGetHinge2Angle1Rate)(dJointID); //dReal (ODE_API *dJointGetHinge2Angle2Rate)(dJointID); -//void (ODE_API *dJointGetUniversalAnchor)(dJointID, dVector3 result); +void (ODE_API *dJointGetUniversalAnchor)(dJointID, dVector3 result); //void (ODE_API *dJointGetUniversalAnchor2)(dJointID, dVector3 result); -//void (ODE_API *dJointGetUniversalAxis1)(dJointID, dVector3 result); -//void (ODE_API *dJointGetUniversalAxis2)(dJointID, dVector3 result); +void (ODE_API *dJointGetUniversalAxis1)(dJointID, dVector3 result); +void (ODE_API *dJointGetUniversalAxis2)(dJointID, dVector3 result); //dReal (ODE_API *dJointGetUniversalParam)(dJointID, int parameter); //void (ODE_API *dJointGetUniversalAngles)(dJointID, dReal *angle1, dReal *angle2); //dReal (ODE_API *dJointGetUniversalAngle1)(dJointID); @@ -659,7 +659,7 @@ dGeomID (ODE_API *dCreateCapsule)(dSpaceID space, dReal radius, dReal le //void (ODE_API *dGeomCapsuleGetParams)(dGeomID ccylinder, dReal *radius, dReal *length); //dReal (ODE_API *dGeomCapsulePointDepth)(dGeomID ccylinder, dReal x, dReal y, dReal z); // -//dGeomID (ODE_API *dCreateCylinder)(dSpaceID space, dReal radius, dReal length); +dGeomID (ODE_API *dCreateCylinder)(dSpaceID space, dReal radius, dReal length); //void (ODE_API *dGeomCylinderSetParams)(dGeomID cylinder, dReal radius, dReal length); //void (ODE_API *dGeomCylinderGetParams)(dGeomID cylinder, dReal *radius, dReal *length); // @@ -735,7 +735,7 @@ static dllfunction_t odefuncs[] = // {"dMassSetCapsule", (void **) &dMassSetCapsule}, {(void **) &dMassSetCapsuleTotal, "dMassSetCapsuleTotal"}, // {"dMassSetCylinder", (void **) &dMassSetCylinder}, -// {"dMassSetCylinderTotal", (void **) &dMassSetCylinderTotal}, + {(void **) &dMassSetCylinderTotal, "dMassSetCylinderTotal"}, // {"dMassSetBox", (void **) &dMassSetBox}, {(void **) &dMassSetBoxTotal, "dMassSetBoxTotal"}, // {"dMassSetTrimesh", (void **) &dMassSetTrimesh}, @@ -896,8 +896,8 @@ static dllfunction_t odefuncs[] = {(void **) &dJointGroupEmpty, "dJointGroupEmpty"}, // {"dJointGetNumBodies", (void **) &dJointGetNumBodies}, {(void **) &dJointAttach, "dJointAttach"}, -// {"dJointEnable", (void **) &dJointEnable}, -// {"dJointDisable", (void **) &dJointDisable}, + {(void **) &dJointEnable, "dJointEnable"}, + {(void **) &dJointDisable, "dJointDisable"}, // {"dJointIsEnabled", (void **) &dJointIsEnabled}, {(void **) &dJointSetData, "dJointSetData"}, {(void **) &dJointGetData, "dJointGetData"}, @@ -961,31 +961,31 @@ static dllfunction_t odefuncs[] = // {"dJointSetPlane2DXParam", (void **) &dJointSetPlane2DXParam}, // {"dJointSetPlane2DYParam", (void **) &dJointSetPlane2DYParam}, // {"dJointSetPlane2DAngleParam", (void **) &dJointSetPlane2DAngleParam}, -// {"dJointGetBallAnchor", (void **) &dJointGetBallAnchor}, + {(void **) &dJointGetBallAnchor, "dJointGetBallAnchor"}, // {"dJointGetBallAnchor2", (void **) &dJointGetBallAnchor2}, // {"dJointGetBallParam", (void **) &dJointGetBallParam}, -// {"dJointGetHingeAnchor", (void **) &dJointGetHingeAnchor}, + {(void **) &dJointGetHingeAnchor, "dJointGetHingeAnchor"}, // {"dJointGetHingeAnchor2", (void **) &dJointGetHingeAnchor2}, -// {"dJointGetHingeAxis", (void **) &dJointGetHingeAxis}, + {(void **) &dJointGetHingeAxis, "dJointGetHingeAxis"}, // {"dJointGetHingeParam", (void **) &dJointGetHingeParam}, // {"dJointGetHingeAngle", (void **) &dJointGetHingeAngle}, // {"dJointGetHingeAngleRate", (void **) &dJointGetHingeAngleRate}, // {"dJointGetSliderPosition", (void **) &dJointGetSliderPosition}, // {"dJointGetSliderPositionRate", (void **) &dJointGetSliderPositionRate}, -// {"dJointGetSliderAxis", (void **) &dJointGetSliderAxis}, + {(void **) &dJointGetSliderAxis, "dJointGetSliderAxis"}, // {"dJointGetSliderParam", (void **) &dJointGetSliderParam}, // {"dJointGetHinge2Anchor", (void **) &dJointGetHinge2Anchor}, // {"dJointGetHinge2Anchor2", (void **) &dJointGetHinge2Anchor2}, -// {"dJointGetHinge2Axis1", (void **) &dJointGetHinge2Axis1}, -// {"dJointGetHinge2Axis2", (void **) &dJointGetHinge2Axis2}, + {(void **) &dJointGetHinge2Axis1, "dJointGetHinge2Axis1"}, + {(void **) &dJointGetHinge2Axis2, "dJointGetHinge2Axis2"}, // {"dJointGetHinge2Param", (void **) &dJointGetHinge2Param}, // {"dJointGetHinge2Angle1", (void **) &dJointGetHinge2Angle1}, // {"dJointGetHinge2Angle1Rate", (void **) &dJointGetHinge2Angle1Rate}, // {"dJointGetHinge2Angle2Rate", (void **) &dJointGetHinge2Angle2Rate}, -// {"dJointGetUniversalAnchor", (void **) &dJointGetUniversalAnchor}, + {(void **) &dJointGetUniversalAnchor, "dJointGetUniversalAnchor"}, // {"dJointGetUniversalAnchor2", (void **) &dJointGetUniversalAnchor2}, -// {"dJointGetUniversalAxis1", (void **) &dJointGetUniversalAxis1}, -// {"dJointGetUniversalAxis2", (void **) &dJointGetUniversalAxis2}, + {(void **) &dJointGetUniversalAxis1, "dJointGetUniversalAxis1"}, + {(void **) &dJointGetUniversalAxis2, "dJointGetUniversalAxis2"}, // {"dJointGetUniversalParam", (void **) &dJointGetUniversalParam}, // {"dJointGetUniversalAngles", (void **) &dJointGetUniversalAngles}, // {"dJointGetUniversalAngle1", (void **) &dJointGetUniversalAngle1}, @@ -1115,7 +1115,7 @@ static dllfunction_t odefuncs[] = // {"dGeomCapsuleSetParams", (void **) &dGeomCapsuleSetParams}, // {"dGeomCapsuleGetParams", (void **) &dGeomCapsuleGetParams}, // {"dGeomCapsulePointDepth", (void **) &dGeomCapsulePointDepth}, -// {"dCreateCylinder", (void **) &dCreateCylinder}, + {(void **) &dCreateCylinder, "dCreateCylinder"}, // {"dGeomCylinderSetParams", (void **) &dGeomCylinderSetParams}, // {"dGeomCylinderGetParams", (void **) &dGeomCylinderGetParams}, // {"dCreateRay", (void **) &dCreateRay}, @@ -1771,17 +1771,10 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed return true; } -qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, float *mat, wedict_t *ent) +qboolean World_ODE_RagMatrixToBody(odebody_t *bodyptr, float *mat) { dVector3 r[3]; - if (!world->ode.ode_space) - return false; - bodyptr->ode_geom = dCreateBox(world->ode.ode_space, 3, 3, 3); - bodyptr->ode_body = dBodyCreate(world->ode.ode_world); - dGeomSetBody(bodyptr->ode_geom, bodyptr->ode_body); - dGeomSetData(bodyptr->ode_geom, (void*)ent); - r[0][0] = mat[0]; r[0][1] = mat[1]; r[0][2] = mat[2]; @@ -1796,8 +1789,141 @@ qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, float *mat, dBodySetRotation(bodyptr->ode_body, r[0]); dBodySetLinearVel(bodyptr->ode_body, 0, 0, 0); dBodySetAngularVel(bodyptr->ode_body, 0, 0, 0); + return true; } +qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, odebodyinfo_t *bodyinfo, float *mat, wedict_t *ent) +{ + dMass mass; + float radius; + if (!world->ode.ode_space) + return false; + world->ode.hasodeents = true; //I don't like this, but we need the world etc to be solid. + world->ode.hasextraobjs = true; + + switch(bodyinfo->shape) + { + case SOLID_PHYSICS_CAPSULE: + radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; + bodyptr->ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, bodyinfo->dimensions[2]); + dMassSetCapsuleTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]); + //aligned along the geom's local z axis + break; + case SOLID_PHYSICS_SPHERE: + //radius + radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1] + bodyinfo->dimensions[2]) / 3; + bodyptr->ode_geom = dCreateSphere(world->ode.ode_space, radius); + dMassSetSphereTotal(&mass, bodyinfo->mass, radius); + //aligned along the geom's local z axis + break; + case SOLID_PHYSICS_CYLINDER: + //radius, length + radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; + bodyptr->ode_geom = dCreateCylinder(world->ode.ode_space, radius, bodyinfo->dimensions[2]); + dMassSetCylinderTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]); + //alignment is irreleevnt, thouse I suppose it might be scaled wierdly. + break; + default: + case SOLID_PHYSICS_BOX: + //diameter + bodyptr->ode_geom = dCreateBox(world->ode.ode_space, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); + dMassSetBoxTotal(&mass, bodyinfo->mass, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); + //monkey + break; + } + bodyptr->ode_body = dBodyCreate(world->ode.ode_world); + dBodySetMass(bodyptr->ode_body, &mass); + dGeomSetBody(bodyptr->ode_geom, bodyptr->ode_body); + dGeomSetData(bodyptr->ode_geom, (void*)ent); + + return World_ODE_RagMatrixToBody(bodyptr, mat); +} + +void World_ODE_RagMatrixFromJoint(odejoint_t *joint, odejointinfo_t *info, float *mat) +{ + dVector3 dr3; + switch(info->type) + { + case JOINTTYPE_POINT: + dJointGetBallAnchor(joint->ode_joint, dr3); + mat[3] = dr3[0]; + mat[7] = dr3[1]; + mat[11] = dr3[2]; + VectorClear(mat+4); + VectorClear(mat+8); + break; + + case JOINTTYPE_HINGE: + dJointGetHingeAnchor(joint->ode_joint, dr3); + mat[3] = dr3[0]; + mat[7] = dr3[1]; + mat[11] = dr3[2]; + + dJointGetHingeAxis(joint->ode_joint, dr3); + VectorCopy(dr3, mat+4); + VectorClear(mat+8); + + CrossProduct(mat+4, mat+8, mat+0); + return; + break; + case JOINTTYPE_HINGE2: + dJointGetHinge2Anchor(joint->ode_joint, dr3); + mat[3] = dr3[0]; + mat[7] = dr3[1]; + mat[11] = dr3[2]; + + dJointGetHinge2Axis1(joint->ode_joint, dr3); + VectorCopy(dr3, mat+4); + dJointGetHinge2Axis2(joint->ode_joint, dr3); + VectorCopy(dr3, mat+8); + break; + + case JOINTTYPE_SLIDER: + //no anchor point... + //get the two bodies and average their origin for a somewhat usable representation of an anchor. + { + const dReal *p1, *p2; + dReal n[3]; + dBodyID b1 = dJointGetBody(joint->ode_joint, 0), b2 = dJointGetBody(joint->ode_joint, 1); + if (b1) + p1 = dBodyGetPosition(b1); + else + { + p1 = n; + VectorClear(n); + } + if (b2) + p2 = dBodyGetPosition(b2); + else + p2 = p1; + dJointGetSliderAxis(joint->ode_joint, dr3 + 0); + VectorInterpolate(p1, 0.5, p2, dr3); + mat[3] = dr3[0]; + mat[7] = dr3[1]; + mat[11] = dr3[2]; + + VectorClear(mat+4); + VectorClear(mat+8); + } + break; + + case JOINTTYPE_UNIVERSAL: + dJointGetUniversalAnchor(joint->ode_joint, dr3); + mat[3] = dr3[0]; + mat[7] = dr3[1]; + mat[11] = dr3[2]; + + dJointGetUniversalAxis1(joint->ode_joint, dr3); + VectorCopy(dr3, mat+4); + dJointGetUniversalAxis2(joint->ode_joint, dr3); + VectorCopy(dr3, mat+8); + + CrossProduct(mat+4, mat+8, mat+0); + return; + break; + } + AngleVectorsFLU(vec3_origin, mat+0, mat+4, mat+8); +} void World_ODE_RagMatrixFromBody(world_t *world, odebody_t *bodyptr, float *mat) { @@ -1818,7 +1944,13 @@ void World_ODE_RagMatrixFromBody(world_t *world, odebody_t *bodyptr, float *mat) mat[10] = r[10]; mat[11] = o[2]; } - +void World_ODE_RagEnableJoint(odejoint_t *joint, qboolean enabled) +{ + if (enabled) + dJointEnable(joint->ode_joint); + else + dJointDisable(joint->ode_joint); +} void World_ODE_RagCreateJoint(world_t *world, odejoint_t *joint, odejointinfo_t *info, odebody_t *body1, odebody_t *body2, vec3_t aaa2[3]) { switch(info->type) @@ -2023,12 +2155,6 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed) if (movetype != MOVETYPE_PHYSICS) massval = 1.0f; - // get friction from entity - if (ed->xv->friction) - ed->ode.ode_friction = ed->xv->friction; - else - ed->ode.ode_friction = 1.0; - // check if we need to create or replace the geom if (!ed->ode.ode_physics || !VectorCompare(ed->ode.ode_mins, entmins) @@ -2380,9 +2506,17 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2) return; ed1 = (wedict_t *) dGeomGetData(o1); + ed2 = (wedict_t *) dGeomGetData(o2); + if (ed1 == ed2 && ed1) + { + //ragdolls don't make contact with the bbox of the doll entity + //the origional entity should probably not be solid anyway. + //these bodies should probably not collide against bboxes of other entities with ragdolls either, but meh. + if (ed1->ode.ode_body == b1 || ed2->ode.ode_body == b2) + return; + } if(!ed1 || ed1->isfree) ed1 = world->edicts; - ed2 = (wedict_t *) dGeomGetData(o2); if(!ed2 || ed2->isfree) ed2 = world->edicts; @@ -2454,7 +2588,12 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2) (physics_ode_contact_erp.value != -1 ? dContactSoftERP : 0) | (physics_ode_contact_cfm.value != -1 ? dContactSoftCFM : 0) | (bouncefactor1 > 0 ? dContactBounce : 0); - contact[i].surface.mu = physics_ode_contact_mu.value * ed1->ode.ode_friction * ed2->ode.ode_friction; + contact[i].surface.mu = physics_ode_contact_mu.value; + if (ed1->xv->friction) + contact[i].surface.mu *= ed1->xv->friction; + if (ed2->xv->friction) + contact[i].surface.mu *= ed2->xv->friction; + contact[i].surface.mu2 = 0; contact[i].surface.soft_erp = physics_ode_contact_erp.value + erp; contact[i].surface.soft_cfm = physics_ode_contact_cfm.value; contact[i].surface.bounce = bouncefactor1; @@ -2475,7 +2614,7 @@ void World_ODE_Frame(world_t *world, double frametime, double gravity) world->ode.ode_step = frametime / world->ode.ode_iterations; world->ode.ode_movelimit = physics_ode_movelimit.value / world->ode.ode_step; - if (world->ode.hasodeents) + if (world->ode.hasodeents || world->ode.hasextraobjs) { // copy physics properties from entities to physics engine for (i = 0;i < world->num_edicts;i++) @@ -2495,6 +2634,12 @@ void World_ODE_Frame(world_t *world, double frametime, double gravity) for (i = 0;i < world->ode.ode_iterations;i++) { + if (world->ode.hasextraobjs) + { +#ifdef RAGDOLL + rag_doallanimations(world); +#endif + } // set the gravity dWorldSetGravity(world->ode.ode_world, 0, 0, -gravity); // set the tolerance for closeness of objects diff --git a/engine/common/common.c b/engine/common/common.c index 5fee2d40..32d36e48 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -957,6 +957,79 @@ void MSG_WriteAngle (sizebuf_t *sb, float f) MSG_WriteAngle8 (sb, f); } +static unsigned int MSG_ReadEntity(void) +{ + unsigned int num; + num = MSG_ReadShort(); + if (num & 0x8000) + { + num = (num & 0x7fff) << 8; + num |= MSG_ReadByte(); + } + return num; +} +//we use the high bit of the entity number to state that this is a large entity. +#ifndef CLIENTONLY +unsigned int MSGSV_ReadEntity(client_t *fromclient) +{ + unsigned int num; + if (fromclient->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + num = MSG_ReadEntity(); + else + num = (unsigned short)(short)MSG_ReadEntity(); + if (num >= sv.world.max_edicts) + { + Con_Printf("client %s sent invalid entity\n", fromclient->name); + fromclient->drop = true; + return 0; + } + return num; +} +#endif +#ifndef SERVERONLY +unsigned int MSGCL_ReadEntity(void) +{ + unsigned int num; + if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + num = MSG_ReadEntity(); + else + num = (unsigned short)(short)MSG_ReadShort(); + return num; +} +//compat for ktx/ezquake's railgun +unsigned int MSGCLF_ReadEntity(qboolean *flagged) +{ + int s; + *flagged = false; + if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + return MSG_ReadEntity(); + else + { + s = MSG_ReadShort(); + if (s < 0) + { + *flagged = true; + return -1 -s; + } + else + return s; + } +} +#endif +void MSG_WriteEntity(sizebuf_t *sb, unsigned int entnum) +{ + if (entnum > MAX_EDICTS) + Host_EndGame("index %#x is not a valid entity\n", entnum); + + if (entnum >= 0x8000) + { + MSG_WriteShort(sb, (entnum>>8) | 0x8000); + MSG_WriteByte(sb, entnum & 0xff); + } + else + MSG_WriteShort(sb, entnum); +} + void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) { int bits; @@ -1617,6 +1690,23 @@ void SZ_Print (sizebuf_t *buf, const char *data) //============================================================================ +char *COM_TrimString(char *str) +{ + int i; + static char buffer[256]; + while (*str <= ' ' && *str>'\0') + str++; + + for (i = 0; i < 255; i++) + { + if (*str <= ' ') + break; + buffer[i] = *str++; + } + buffer[i] = '\0'; + return buffer; +} + /* ============ COM_SkipPath @@ -1826,6 +1916,199 @@ void COM_DefaultExtension (char *path, char *extension, int maxlen) +//errors: +//1 sequence error +//2 over-long +//3 invalid unicode char +//4 invalid utf-16 lead/high surrogate +//5 invalid utf-16 tail/low surrogate +unsigned int utf8_decode(int *error, const void *in, void **out) +{ + //uc is the output unicode char + unsigned int uc = 0xfffdu; //replacement character + //l is the length + unsigned int l = 1; + const unsigned char *str = in; + + if ((*str & 0xe0) == 0xc0) + { + if ((str[1] & 0xc0) == 0x80) + { + l = 2; + uc = ((str[0] & 0x1f)<<6) | (str[1] & 0x3f); + if (uc >= (1u<<7)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + else if ((*str & 0xf0) == 0xe0) + { + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) + { + l = 3; + uc = ((str[0] & 0x0f)<<12) | ((str[1] & 0x3f)<<6) | ((str[2] & 0x3f)<<0); + if (uc >= (1u<<11)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + else if ((*str & 0xf8) == 0xf0) + { + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80) + { + l = 4; + uc = ((str[0] & 0x07)<<18) | ((str[1] & 0x3f)<<12) | ((str[2] & 0x3f)<<6) | ((str[3] & 0x3f)<<0); + if (uc >= (1u<<16)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + else if ((*str & 0xfc) == 0xf8) + { + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) + { + l = 5; + uc = ((str[0] & 0x03)<<24) | ((str[1] & 0x3f)<<18) | ((str[2] & 0x3f)<<12) | ((str[3] & 0x3f)<<6) | ((str[4] & 0x3f)<<0); + if (uc >= (1u<<21)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + else if ((*str & 0xfe) == 0xfc) + { + //six bytes + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) + { + l = 6; + uc = ((str[0] & 0x01)<<30) | ((str[1] & 0x3f)<<24) | ((str[2] & 0x3f)<<18) | ((str[3] & 0x3f)<<12) | ((str[4] & 0x3f)<<6) | ((str[5] & 0x3f)<<0); + if (uc >= (1u<<26)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + //0xfe and 0xff, while plausable leading bytes, are not permitted. +#if 0 + else if ((*str & 0xff) == 0xfe) + { + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) + { + l = 7; + uc = 0 | ((str[1] & 0x3f)<<30) | ((str[2] & 0x3f)<<24) | ((str[3] & 0x3f)<<18) | ((str[4] & 0x3f)<<12) | ((str[5] & 0x3f)<<6) | ((str[6] & 0x3f)<<0); + if (uc >= (1u<<31)) + *error = 0; + else + *error = 2; + } + else *error = 1; + } + else if ((*str & 0xff) == 0xff) + { + if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) + { + l = 8; + uc = 0 | ((str[1] & 0x3f)<<36) | ((str[2] & 0x3f)<<30) | ((str[3] & 0x3f)<<24) | ((str[4] & 0x3f)<<18) | ((str[5] & 0x3f)<<12) | ((str[6] & 0x3f)<<6) | ((str[7] & 0x3f)<<0); + if (uc >= (1llu<<36)) + *error = false; + else + *error = 2; + } + else *error = 1; + } +#endif + else if (*str & 0x80) + { + //sequence error + *error = 1; + uc = 0xe000u + *str; + } + else + { + //ascii char + *error = 0; + uc = *str; + } + + *out = (void*)(str + l); + + if (!*error) + { + //try to deal with surrogates by decoding the low if we see a high. + if (uc >= 0xd800u && uc < 0xdc00u) + { +#if 0 + //cesu-8 + void *lowend; + unsigned int lowsur = utf_decode(&error, str + l, &lowend); + if (*error == 4 && lowsur >= 0xdc00u && lowsur < 0xe000u) + { + *out = lowend; + uc = (((uc&0x3ff) << 10) || (lowsur&0x3ff)) + 0x10000; + *error = false; + } + else +#endif + { + *error = 3; //bad lead surrogate. + } + } + if (uc >= 0xd800u && uc < 0xdc00u) + *error = 4; //bad tail surrogate + + //these are meant to be illegal too + if (uc == 0xfffeu || uc == 0xffffu || uc > 0x10ffff) + *error = 2; //illegal code + } + + return uc; +} +unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen) +{ + unsigned int bcount = 1; + unsigned int lim = 0x80; + unsigned int shift; + while (unicode >= lim) + { + if (bcount == 1) + lim <<= 4; + else if (bcount < 7) + lim <<= 5; + else + lim <<= 6; + bcount++; + } + + //error if needed + if (maxlen < bcount) + return 0; + + //output it. + if (bcount == 1) + *((unsigned char *)out)++ = (unsigned char)(unicode&0x7f); + else + { + shift = bcount*6; + shift = shift-6; + *((unsigned char *)out)++ = (unsigned char)((unicode>>shift)&(0x0000007f>>bcount)) | (0xffffff00 >> bcount); + do + { + shift = shift-6; + *((unsigned char *)out)++ = (unsigned char)((unicode>>shift)&0x3f) | 0x80; + } + while(shift); + } + return bcount; +} + ///===================================== @@ -2007,33 +2290,11 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q c = *str++ & 0xffff; if (com_parseutf8.ival > 0) { - //utf-8 - if (c > 0x7ff) - { - if (outsize<=3) - break; - outsize -= 3; - - *out++ = (unsigned char)((c>>12)&0x0f) | 0xe0; - *out++ = (unsigned char)((c>>6)&0x3f) | 0x80; - *out++ = (unsigned char)(c&0x3f) | 0x80; - } - else if (c > 0x7f) - { - if (outsize<=2) - break; - outsize -= 2; - - *out++ = (unsigned char)((c>>6)&0x1f) | 0xc0; - *out++ = (unsigned char)(c&0x3f) | 0x80; - } - else - { - if (outsize<=1) - break; - outsize -= 1; - *out++ = (unsigned char)(c&0x7f); - } + c = utf8_encode(out, c, outsize); + if (!c) + break; + outsize -= c; + out += c; } else if (com_parseutf8.ival) { @@ -2044,7 +2305,7 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q break; *out++ = (unsigned char)(c&255); } - else //any other quake char is not iso8859-1 + else //any other (quake?) char is not iso8859-1 { const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; if (outsize<=6) @@ -2103,7 +2364,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t { conchar_t extstack[4]; int extstackdepth = 0; - unsigned int uc, l; + unsigned int uc; int utf8 = com_parseutf8.ival; conchar_t linkinitflags = CON_WHITEMASK;/*doesn't need the init, but msvc is stupid*/ qboolean linkkeep = keepmarkup; @@ -2140,107 +2401,41 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t { if (*str & 0x80 && utf8 > 0) { //check for utf-8 - - //uc is the output unicode char - uc = 0; - //l is the length - l = 0; - - if ((*str & 0xc0) == 0x80) + int decodeerror; + void *end; + uc = utf8_decode(&decodeerror, str, &end); + if (decodeerror) { - //one byte... malformed - uc = '?'; - } - else if ((*str & 0xe0) == 0xc0) - { - //two bytes - if ((str[1] & 0xc0) == 0x80) - { - uc = ((str[0] & 0x1f)<<6) | (str[1] & 0x3f); - if (uc > 0x7f) - l = 2; - } - } - else if ((*str & 0xf0) == 0xe0) - { - //three bytes - if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80) - { - uc = ((str[0] & 0x0f)<<12) | ((str[1] & 0x3f)<<6) | ((str[2] & 0x3f)<<0); - if (uc > 0x7ff) - l = 3; - } - } - else if ((*str & 0xf8) == 0xf0) - { - //four bytes - if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80) - { - uc = ((str[0] & 0x07)<<18) | ((str[1] & 0x3f)<<12) | ((str[2] & 0x3f)<<6) | ((str[3] & 0x3f)<<0); - if (uc > 0xffff) - l = 4; - } - } - else if ((*str & 0xfc) == 0xf8) - { - //five bytes - if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) - { - uc = ((str[0] & 0x03)<<24) | ((str[1] & 0x3f)<<18) | ((str[2] & 0x3f)<<12) | ((str[3] & 0x3f)<<6) | ((str[4] & 0x3f)<<0); - if (uc > 0x1fffff) - l = 5; - } - } - else if ((*str & 0xfe) == 0xfc) - { - //six bytes - if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80) - { - uc = ((str[0] & 0x01)<<30) | ((str[1] & 0x3f)<<24) | ((str[2] & 0x3f)<<18) | ((str[3] & 0x3f)<<12) | ((str[4] & 0x3f)<<6) | ((str[5] & 0x3f)<<0); - if (uc > 0x3ffffff) - l = 6; - } - } - //0xfe and 0xff, while plausable leading bytes, are not permitted. - - if (l) - { - //note that we don't support utf-16 surrogates - if (uc == 0xd800 || uc == 0xdb7f || uc == 0xdb80 || uc == 0xdbff || uc == 0xdc00 || uc == 0xdf80 || uc == 0xdfff) - l = 0; - //these are meant to be illegal too - else if (uc == 0xfffe || uc == 0xffff) - uc = '?'; - //too big for our data types - else if (uc & ~CON_CHARMASK) - l = 0; + utf8 &= ~1; + //malformed encoding we just drop through and stop trying to decode. + //if its just a malformed or overlong string, we end up with a chunk of 'red' chars. } else - utf8 &= ~1; - - //l is set if we got a valid utf-8 byte sequence - if (l) { + if (uc > 0xffff) + uc = 0xfffd; if (!--outsize) break; *out++ = uc | ext; - str += l; + str = end; continue; } - - //malformed encoding we just drop through - //if its just a malformed or overlong string, we end up with a chunk of 'red' chars. } if (*str == '^') { if (str[1] >= '0' && str[1] <= '9') { + if (ext & CON_RICHFORECOLOUR) + ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR)); ext = q3codemasks[str[1]-'0'] | (ext&~CON_Q3MASK); //change colour only. } else if (str[1] == '&') // extended code { if (isextendedcode(str[2]) && isextendedcode(str[3])) { + if (ext & CON_RICHFORECOLOUR) + ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR)); + // foreground char if (str[2] == '-') // default for FG ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~CON_FGMASK); @@ -2403,38 +2598,30 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t int best = 1; float bd = 255*255*255, d; int c; - float r, g, b; + int r, g, b; if (str[2] >= '0' && str[2] <= '9') - r = (str[2]-'0') / (float)0xf; + r = (str[2]-'0'); else if (str[2] >= 'A' && str[2] <= 'F') - r = (str[2]-'A'+10) / (float)0xf; + r = (str[2]-'A'+10); else - r = (str[2]-'a'+10) / (float)0xf; + r = (str[2]-'a'+10); if (str[3] >= '0' && str[3] <= '9') - g = (str[3]-'0') / (float)0xf; + g = (str[3]-'0'); else if (str[3] >= 'A' && str[3] <= 'F') - g = (str[3]-'A'+10) / (float)0xf; + g = (str[3]-'A'+10); else - g = (str[3]-'a'+10) / (float)0xf; + g = (str[3]-'a'+10); if (str[4] >= '0' && str[4] <= '9') - b = (str[4]-'0') / (float)0xf; + b = (str[4]-'0'); else if (str[4] >= 'A' && str[4] <= 'F') - b = (str[4]-'A'+10) / (float)0xf; + b = (str[4]-'A'+10); else - b = (str[4]-'a'+10) / (float)0xf; + b = (str[4]-'a'+10); - 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); + ext = (ext & ~CON_RICHFOREMASK) | CON_RICHFORECOLOUR; + ext |= r<flags & CVAR_SERVEROVERRIDE && !force) latch = "variable %s is under server control - latched\n"; - else if (var->flags & CVAR_LATCH) + else if (var->flags & CVAR_LATCH && (sv_state || cls_state)) latch = "variable %s is latched and will be applied for the start of the next map\n"; // else if (var->flags & CVAR_LATCHFLUSH) // latch = "variable %s is latched (type flush)\n"; @@ -1110,7 +1110,7 @@ qboolean Cvar_Command (int level) return true; } - if (v->flags & CVAR_NOTFROMSERVER && Cmd_FromGamecode()) + if (v->flags & CVAR_NOTFROMSERVER && Cmd_IsInsecure()) { Con_Printf ("Server tried setting %s cvar\n", v->name); return true; @@ -1118,10 +1118,35 @@ qboolean Cvar_Command (int level) // perform a variable print or set if (Cmd_Argc() == 1) { - Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); if (v->latched_string) - Con_Printf ("Latched as \"%s\"\n", v->latched_string); - Con_Printf("Default: \"%s\"\n", v->defaultstr); + { + if (v->flags & CVAR_LATCH) + { + Con_Printf ("\"%s\" is currently \"%s\"\n", v->name, v->string); + Con_Printf ("Will be changed to \"%s\" on the next map\n", v->latched_string); + } + else if (v->flags & CVAR_RENDERERLATCH) + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); + Con_Printf ("Will be changed to \"%s\" on vid_restart\n", v->latched_string); + } + else + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->latched_string); + Con_Printf ("Effective value is \"%s\"\n", v->string); + } + Con_Printf("Default: \"%s\"\n", v->defaultstr); + } + else + { + if (!strcmp(v->string, v->defaultstr)) + Con_Printf ("\"%s\" is \"%s\" (default)\n", v->name, v->string); + else + { + Con_Printf ("\"%s\" is \"%s\"\n", v->name, v->string); + Con_Printf("Default: \"%s\"\n", v->defaultstr); + } + } return true; } diff --git a/engine/common/fs.c b/engine/common/fs.c index 0d4bd123..f683653c 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -176,7 +176,7 @@ searchpath_t *com_searchpaths; searchpath_t *com_purepaths; searchpath_t *com_base_searchpaths; // without gamedirs -int COM_FileSize(const char *path) +int QDECL COM_FileSize(const char *path) { int len; flocation_t loc; @@ -192,6 +192,7 @@ COM_Path_f */ void COM_Path_f (void) { + char path[MAX_OSPATH]; searchpath_t *s; Con_TPrintf (TL_CURRENTSEARCHPATH); @@ -201,9 +202,8 @@ void COM_Path_f (void) Con_Printf ("Pure paths:\n"); for (s=com_purepaths ; s ; s=s->nextpure) { - if (s->referenced) - Con_Printf("*"); - s->funcs->PrintPath(s->handle); + s->funcs->GetDisplayPath(s->handle, path, sizeof(path)); + Con_Printf("%s %s%s%s\n", path, s->referenced?"(ref)":"", s->istemporary?"(temp)":"", s->copyprotected?"(c)":""); } Con_Printf ("----------\n"); Con_Printf ("Impure paths:\n"); @@ -215,9 +215,8 @@ void COM_Path_f (void) if (s == com_base_searchpaths) Con_Printf ("----------\n"); - if (s->referenced) - Con_Printf("*"); - s->funcs->PrintPath(s->handle); + s->funcs->GetDisplayPath(s->handle, path, sizeof(path)); + Con_Printf("%s %s%s%s\n", path, s->referenced?"(ref)":"", s->istemporary?"(temp)":"", s->copyprotected?"(c)":""); } } @@ -260,18 +259,18 @@ COM_Locate_f */ void COM_Locate_f (void) { + char path[MAX_OSPATH]; flocation_t loc; if (FS_FLocateFile(Cmd_Argv(1), FSLFRT_LENGTH, &loc)>=0) { + loc.search->funcs->GetDisplayPath(loc.search->handle, path, sizeof(path)); if (!*loc.rawname) { - Con_Printf("File is %i bytes compressed inside ", loc.len); - loc.search->funcs->PrintPath(loc.search->handle); + Con_Printf("File is %i bytes compressed inside %s\n", loc.len, path); } else { - Con_Printf("Inside %s (%i bytes)\n", loc.rawname, loc.len); - loc.search->funcs->PrintPath(loc.search->handle); + Con_Printf("Inside %s (%i bytes)\n %s\n", loc.rawname, loc.len, path); } } else @@ -608,12 +607,11 @@ qboolean FS_GetPackageDownloadable(const char *package) { searchpath_t *search; - for (search = com_purepaths ; search ; search = search->nextpure) + for (search = com_searchpaths ; search ; search = search->next) { if (!strcmp(package, search->purepath)) return !search->copyprotected; } - return false; } @@ -691,7 +689,13 @@ char *FS_GetPackNames(char *buffer, int buffersize, int referencedonly, qboolean if (referencedonly == 0 && !search->referenced) continue; if (referencedonly == 2 && search->referenced) - Q_strncatz(buffer, "*", buffersize); + { + // '*' prefix is meant to mean 'referenced'. + //really all that means to the client is that it definitely wants to download it. + //if its copyrighted, the client shouldn't try to do so, as it won't be allowed. + if (search->copyprotected) + Q_strncatz(buffer, "*", buffersize); + } if (!ext) { @@ -1183,7 +1187,7 @@ void COM_LoadCacheFile (const char *path, struct cache_user_s *cu) } // uses temp hunk if larger than bufsize -qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize) +qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize) { qbyte *buf; @@ -1375,7 +1379,7 @@ static int FS_AddWildDataFiles (const char *descriptor, int size, void *vparam) snprintf (purefile, sizeof(purefile), "%s/%s", param->puredesc, descriptor); else Q_strncpyz(purefile, descriptor, sizeof(purefile)); - FS_AddPathHandle(purefile, pakfile, funcs, pak, true, false, false, (unsigned int)-1); + FS_AddPathHandle(purefile, pakfile, funcs, pak, !Q_strcasecmp(descriptor, "pak"), false, false, (unsigned int)-1); return true; } @@ -1802,12 +1806,15 @@ const gamemode_info_t gamemode_info[] = { //note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get. //this is to avoid having too many gamemodes anyway. -//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake +//mission packs should generally come after the main game to avoid prefering the main game. we violate this for hexen2 as the mission pack is mostly a superset. +//whereas the quake mission packs replace start.bsp making the original episodes unreachable. +//for quake, we also allow extracting all files from paks. some people think it loads faster that way or something. + //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name {"-quake", "q1", "DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"}, NULL, {"id1", "qw", "fte"}, "Quake"/*, "id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, - {"-hipnotic", "hipnotic", "Darkplaces-Hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"}, - {"-rogue", "rogue", "Darkplaces-Rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"}, + {"-hipnotic", "hipnotic", "Darkplaces-Hipnotic", {"hipnotic/pak0.pak"}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"}, + {"-rogue", "rogue", "Darkplaces-Rogue", {"rogue/pak0.pak"}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"}, {"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"}, {"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, NEXCFG, {"data", "ftedata"}, "Xonotic", "data/xonotic-20120308-data.pk3|http://localhost/xonotic-0.6.0.zip"}, {"-spark", "spark", "Spark", {"base/src/progs.src", diff --git a/engine/common/fs.h b/engine/common/fs.h index be6c7927..7ff7cfcf 100644 --- a/engine/common/fs.h +++ b/engine/common/fs.h @@ -10,7 +10,7 @@ extern int fs_hash_files; //for tracking efficiency. no functional use. typedef struct { - void (*PrintPath)(void *handle); + void (*GetDisplayPath)(void *handle, char *outpath, unsigned int pathsize); void (*ClosePath)(void *handle); void (*BuildHash)(void *handle, int depth); qboolean (*FindFile)(void *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL) diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index 6c23af9a..2b62a0b0 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -54,14 +54,14 @@ typedef struct #define MAX_FILES_IN_PACK 2048 -void FSPAK_PrintPath(void *handle) +void FSPAK_GetDisplayPath(void *handle, char *out, unsigned int outlen) { pack_t *pak = handle; if (pak->references != 1) - Con_Printf("%s (%i)\n", pak->descname, pak->references-1); + Q_snprintfz(out, outlen, "%s (%i)", pak->descname, pak->references-1); else - Con_Printf("%s\n", pak->descname); + Q_snprintfz(out, outlen, "%s", pak->descname); } void FSPAK_ClosePath(void *handle) { @@ -373,7 +373,7 @@ void FSPAK_ReadFile(void *handle, flocation_t *loc, char *buffer) } searchpathfuncs_t packfilefuncs = { - FSPAK_PrintPath, + FSPAK_GetDisplayPath, FSPAK_ClosePath, FSPAK_BuildHash, FSPAK_FLocate, @@ -559,7 +559,7 @@ newsection: return pack; } searchpathfuncs_t doomwadfilefuncs = { - FSPAK_PrintPath, + FSPAK_GetDisplayPath, FSPAK_ClosePath, FSPAK_BuildHash, FSPAK_FLocate, diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index 09d51a77..217e876a 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -212,10 +212,10 @@ static vfsfile_t *FSSTDIO_OpenVFS(void *handle, flocation_t *loc, const char *mo return f; } -static void FSSTDIO_PrintPath(void *handle) +static void FSSTDIO_GetDisplayPath(void *handle, char *out, unsigned int outlen) { stdiopath_t *np = handle; - Con_Printf("%s\n", np->rootpath); + Q_strncpyz(out, np->rootpath, outlen); } static void FSSTDIO_ClosePath(void *handle) { @@ -333,7 +333,7 @@ static int FSSTDIO_EnumerateFiles (void *handle, const char *match, int (*func)( } searchpathfuncs_t stdiofilefuncs = { - FSSTDIO_PrintPath, + FSSTDIO_GetDisplayPath, FSSTDIO_ClosePath, FSSTDIO_BuildHash, FSSTDIO_FLocate, diff --git a/engine/common/fs_win32.c b/engine/common/fs_win32.c index 1af80390..7fa7955b 100644 --- a/engine/common/fs_win32.c +++ b/engine/common/fs_win32.c @@ -191,10 +191,10 @@ static vfsfile_t *VFSW32_OpenVFS(void *handle, flocation_t *loc, const char *mod return VFSW32_Open(loc->rawname, mode); } -static void VFSW32_PrintPath(void *handle) +static void VFSW32_GetDisplayPath(void *handle, char *out, unsigned int outlen) { vfsw32path_t *wp = handle; - Con_Printf("%s\n", wp->rootpath); + Q_strncpyz(out, wp->rootpath, outlen); } static void VFSW32_ClosePath(void *handle) { @@ -323,7 +323,7 @@ static int VFSW32_EnumerateFiles (void *handle, const char *match, int (*func)(c searchpathfuncs_t w32filefuncs = { - VFSW32_PrintPath, + VFSW32_GetDisplayPath, VFSW32_ClosePath, VFSW32_BuildHash, VFSW32_FLocate, diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index b333e92d..186cf4e0 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -239,14 +239,14 @@ typedef struct zipfile_s } zipfile_t; -static void FSZIP_PrintPath(void *handle) +static void FSZIP_GetDisplayPath(void *handle, char *out, unsigned int outlen) { zipfile_t *zip = handle; if (zip->references != 1) - Con_Printf("%s (%i)\n", zip->filename, zip->references-1); + Q_snprintfz(out, outlen, "%s (%i)\n", zip->filename, zip->references-1); else - Con_Printf("%s\n", zip->filename); + Q_strncpyz(out, zip->filename, outlen); } static void FSZIP_ClosePath(void *handle) { @@ -696,7 +696,7 @@ vfsfile_t *FSZIP_OpenVFS(void *handle, flocation_t *loc, const char *mode) } searchpathfuncs_t zipfilefuncs = { - FSZIP_PrintPath, + FSZIP_GetDisplayPath, FSZIP_ClosePath, FSZIP_BuildHash, FSZIP_FLocate, diff --git a/engine/common/log.c b/engine/common/log.c index de9bc1ec..88a24f33 100644 --- a/engine/common/log.c +++ b/engine/common/log.c @@ -96,6 +96,7 @@ void Log_String (logtype_t lognum, char *s) char *t; char logbuf[1024]; int i; + char fname[MAX_QPATH]; if (!log_enable[lognum].value) return; @@ -179,7 +180,7 @@ void Log_String (logtype_t lognum, char *s) *t = 0; - f = va("%s/%s.log",d,f); // temp string in va() + Q_snprintfz(fname, sizeof(fname), "%s/%s.log",d,f); // file rotation if (log_rotate_size.value >= 4096 && log_rotate_files.value >= 1) @@ -188,7 +189,7 @@ void Log_String (logtype_t lognum, char *s) vfsfile_t *fi; // check file size, use x as temp - if ((fi = FS_OpenVFS(f, "rb", FS_ROOT))) + if ((fi = FS_OpenVFS(fname, "rb", FS_ROOT))) { x = VFS_GETLEN(fi); VFS_CLOSE(fi); diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index da292c42..c63a2ced 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -64,6 +64,7 @@ extern vec3_t vec3_origin; #define FloatInterpolate(a, bness, b, c) ((c) = (a) + (b - a)*bness) #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) +#define DotProduct2(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]) #define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3]) #define VectorSubtract(a,b,c) do{(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}while(0) #define VectorAdd(a,b,c) do{(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}while(0) diff --git a/engine/common/net.h b/engine/common/net.h index 9f8acb5c..b7a689cd 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -192,7 +192,7 @@ void VARGS Netchan_OutOfBandPrint (netsrc_t sock, netadr_t adr, char *format, .. void VARGS Netchan_OutOfBandTPrintf (netsrc_t sock, netadr_t adr, int language, translation_t text, ...); qboolean Netchan_Process (netchan_t *chan); void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport); -unsigned int Net_PextMask(int maskset); +unsigned int Net_PextMask(int maskset, qboolean fornq); extern cvar_t net_mtu; qboolean Netchan_CanPacket (netchan_t *chan, int rate); diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 71e9b06c..0cdf6006 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -89,12 +89,12 @@ cvar_t net_mtu = CVARD("net_mtu", "1450", "Specifies a maximum udp payload size, cvar_t pext_replacementdeltas = CVAR("debug_pext_replacementdeltas", "0"); /*rename once the extension is finalized*/ /*returns the entire bitmask of supported+enabled extensions*/ -unsigned int Net_PextMask(int maskset) +unsigned int Net_PextMask(int maskset, qboolean fornq) { unsigned int mask = 0; if (maskset == 1) /*FTEX*/ { - #ifdef PEXT_SCALE //dmw - protocol extensions + #ifdef PEXT_SCALE mask |= PEXT_SCALE; #endif #ifdef PEXT_LIGHTSTYLECOL @@ -166,6 +166,15 @@ unsigned int Net_PextMask(int maskset) #ifdef PEXT_DPFLAGS mask |= PEXT_DPFLAGS; #endif + + if (fornq) + { + //only ones that are tested + mask &= PEXT_CSQC | PEXT_FLOATCOORDS | PEXT_HLBSP | PEXT_Q2BSP | PEXT_Q3BSP; + + //these all depend fully upon the player/entity deltas, and don't make sense for NQ. Implement PEXT2_REPLACEMENTDELTAS instead. + mask &= ~(PEXT_SCALE|PEXT_TRANS|PEXT_ACCURATETIMINGS|PEXT_FATNESS|PEXT_HULLSIZE|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_COLOURMOD|PEXT_SPAWNSTATIC2|PEXT_256PACKETENTITIES|PEXT_SETATTACHMENT|PEXT_DPFLAGS); + } } else if (maskset == 2) { @@ -180,6 +189,12 @@ unsigned int Net_PextMask(int maskset) if (MAX_CLIENTS != QWMAX_CLIENTS) mask |= PEXT2_MAXPLAYERS; + + if (fornq) + { + //only ones that are tested + mask &= PEXT2_VOICECHAT | PEXT2_REPLACEMENTDELTAS; + } } return mask; diff --git a/engine/common/plugin.c b/engine/common/plugin.c index ebcb2a4d..cf358cbb 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -1477,6 +1477,7 @@ void Plug_Init(void) Plug_RegisterBuiltin("Plug_GetEngineFunction", Plug_GetBuiltin, 0);//plugin wishes to find a builtin number. Plug_RegisterBuiltin("Plug_ExportToEngine", Plug_ExportToEngine, 0); //plugin has a call back that we might be interested in. Plug_RegisterBuiltin("Plug_ExportNative", Plug_ExportNative, PLUG_BIF_DLLONLY); + Plug_RegisterBuiltin("Plug_GetPluginName", Plug_GetPluginName, 0); Plug_RegisterBuiltin("Con_Print", Plug_Con_Print, 0); //printf is not possible - qvm floats are never doubles, vararg floats in a cdecl call are always converted to doubles. Plug_RegisterBuiltin("Sys_Error", Plug_Sys_Error, 0); Plug_RegisterBuiltin("Sys_Milliseconds", Plug_Sys_Milliseconds, 0); @@ -1622,13 +1623,12 @@ qboolean Plug_Menu_Event(int eventtype, int param) //eventtype = draw/keydown/ke { plugin_t *oc=currentplug; qboolean ret; - extern int mousecursor_x, mousecursor_y; if (!menuplug) return false; currentplug = menuplug; - ret = VM_Call(menuplug->vm, menuplug->menufunction, eventtype, param, mousecursor_x, mousecursor_y); + ret = VM_Call(menuplug->vm, menuplug->menufunction, eventtype, param, (int)mousecursor_x, (int)mousecursor_y); currentplug=oc; return ret; } diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 50dcdb54..6c41074a 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -53,7 +53,7 @@ void PF_Common_RegisterCvars(void) } char *Translate(char *message); -char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_globals) +char *PF_VarString (pubprogfuncs_t *prinst, int first, struct globalvars_s *pr_globals) { #define VARSTRINGLEN 16384+8 int i; @@ -64,7 +64,7 @@ char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_glob out = buffer[(bufnum++)&1]; out[0] = 0; - for (i=first ; i<*prinst->callargc ; i++) + for (i=first ; icallargc ; i++) { // if (G_INT(OFS_PARM0+i*3) < 0 || G_INT(OFS_PARM0+i*3) >= 1024*1024); // break; @@ -81,10 +81,61 @@ char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_glob } return out; } +int PR_Printf (const char *fmt, ...) +{ + va_list argptr; + char msg[1024]; + char file[MAX_OSPATH]; + int line = -1; + char *ls, *ms, *nl; + + va_start (argptr,fmt); + vsnprintf (msg,sizeof(msg), fmt,argptr); + va_end (argptr); + + while (*msg) + { + nl = strchr(msg, '\n'); + if (nl) + *nl = 0; + *file = 0; + + ls = strchr(msg, ':'); + if (ls) + { + ms = strchr(ls+1, ':'); + if (ms) + { + *ms = '\0'; + if (!strchr(msg, ' ') && !strchr(msg, '\t') && !strchr(msg, '\r') && (ls - msg) < sizeof(file)-1) + { + memcpy(file, msg, ls - msg); + file[ls-msg] = 0; + line = strtoul(ls+1, NULL, 0); + } + *ms = ':'; + } + } + + if (*file) + Con_Printf ("^[%s\\edit\\%s %i^]", msg, file, line); + else + Con_Printf ("%s", msg); + + if (nl) + { + Con_Printf ("\n"); + memmove(msg, nl+1, strlen(nl+1)+1); + } + else + break; + } + return 0; +} #define MAX_TEMPSTRS ((int)pr_tempstringcount.value) #define MAXTEMPBUFFERLEN ((int)pr_tempstringsize.value) -string_t PR_TempString(progfuncs_t *prinst, const char *str) +string_t PR_TempString(pubprogfuncs_t *prinst, const char *str) { char *tmp; if (!prinst->tempstringbase) @@ -101,7 +152,7 @@ string_t PR_TempString(progfuncs_t *prinst, const char *str) return tmp - prinst->stringtable; } -void PF_InitTempStrings(progfuncs_t *prinst) +void PF_InitTempStrings(pubprogfuncs_t *prinst) { if (pr_tempstringcount.value > 0 && pr_tempstringcount.value < 2) pr_tempstringcount.value = 2; @@ -125,7 +176,7 @@ void PF_InitTempStrings(progfuncs_t *prinst) -void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) +void VARGS PR_BIError(pubprogfuncs_t *progfuncs, char *format, ...) { va_list argptr; static char string[2048]; @@ -138,7 +189,7 @@ void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) { struct globalvars_s *pr_globals = PR_globals(progfuncs, PR_CURRENT); Con_Printf("%s\n", string); - *progfuncs->pr_trace = 1; + progfuncs->pr_trace = 1; G_INT(OFS_RETURN)=0; //just in case it was a float and should be an ent... G_INT(OFS_RETURN+1)=0; G_INT(OFS_RETURN+2)=0; @@ -152,7 +203,7 @@ void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) } -pbool QC_WriteFile(const char *name, void *data, int len) +pbool QDECL QC_WriteFile(const char *name, void *data, int len) { char buffer[256]; Q_snprintfz(buffer, sizeof(buffer), "%s", name); @@ -175,7 +226,7 @@ void VARGS PR_CB_Free(void *mem) //model functions //DP_QC_GETSURFACE // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int surfnum; model_t *model; @@ -196,7 +247,7 @@ void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s * } } // #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacepoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int surfnum, pointnum; model_t *model; @@ -225,7 +276,7 @@ void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_g } } // #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacenormal(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int surfnum, pointnum; model_t *model; @@ -256,7 +307,7 @@ void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_ } } // #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacetexture(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { model_t *model; wedict_t *ent; @@ -280,7 +331,7 @@ void QCBUILTIN PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr G_INT(OFS_RETURN) = PR_TempString(prinst, surf->texinfo->texture->name); } // #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacenearpoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #define TriangleNormal(a,b,c,n) ( \ (n)[0] = ((a)[1] - (b)[1]) * ((c)[2] - (b)[2]) - ((a)[2] - (b)[2]) * ((c)[1] - (b)[1]), \ @@ -445,13 +496,13 @@ void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s * } // #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE) -void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfaceclippedpoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf("PF_getsurfaceclippedpoint not implemented\n"); } // #628 float(entity e, float s) getsurfacenumtriangles -void QCBUILTIN PF_getsurfacenumtriangles(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacenumtriangles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int surfnum; model_t *model; @@ -474,7 +525,7 @@ void QCBUILTIN PF_getsurfacenumtriangles(progfuncs_t *prinst, struct globalvars_ } } // #629 float(entity e, float s) getsurfacetriangle -void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacetriangle(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int surfnum, firstidx; model_t *model; @@ -506,7 +557,7 @@ void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *p } //vector(entity e, float s, float n, float a) getsurfacepointattribute -void QCBUILTIN PF_getsurfacepointattribute(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getsurfacepointattribute(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { wedict_t *ent = G_WEDICT(prinst, OFS_PARM0); unsigned int surfnum = G_FLOAT(OFS_PARM1); @@ -567,7 +618,7 @@ void QCBUILTIN PF_getsurfacepointattribute(progfuncs_t *prinst, struct globalvar } #ifndef TERRAIN -void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = false; } @@ -576,7 +627,7 @@ void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_glob //end model functions //////////////////////////////////////////////////// -void PF_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; wedict_t *ent = (wedict_t*)PROG_TO_EDICT(prinst, *w->g.self); @@ -590,7 +641,7 @@ void PF_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals) /* //entity(string field, float match) findchainflags = #450 //chained search for float, int, and entity reference fields -void PF_findchainflags (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; int s; @@ -619,7 +670,7 @@ void PF_findchainflags (progfuncs_t *prinst, struct globalvars_s *pr_globals) /* //entity(string field, float match) findchainfloat = #403 -void PF_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; float s; @@ -649,7 +700,7 @@ void PF_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) /* //entity(string field, string match) findchain = #402 //chained search for strings in entity fields -void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; char *s; @@ -682,7 +733,7 @@ void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals) //EXTENSION: DP_QC_FINDFLAGS //entity(entity start, float fld, float match) findflags = #449 -void QCBUILTIN PF_FindFlags (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_FindFlags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int e, f; int s; @@ -708,13 +759,13 @@ void QCBUILTIN PF_FindFlags (progfuncs_t *prinst, struct globalvars_s *pr_global } //entity(entity start, float fld, float match) findfloat = #98 -void QCBUILTIN PF_FindFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_FindFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int e, f; int s; wedict_t *ed; - if (*prinst->callargc != 3) //I can hate mvdsv if I want to. + if (prinst->callargc != 3) //I can hate mvdsv if I want to. { PR_BIError(prinst, "PF_FindFloat (#98): callargc != 3\nDid you mean to set pr_imitatemvdsv to 1?"); return; @@ -740,7 +791,7 @@ void QCBUILTIN PF_FindFloat (progfuncs_t *prinst, struct globalvars_s *pr_global } // entity (entity start, .string field, string match) find = #5; -void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_FindString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int e; int f; @@ -780,7 +831,7 @@ void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globa //Cvars //string(string cvarname) cvar_string -void QCBUILTIN PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); cvar_t *cv = Cvar_Get(str, "", 0, "QC variables"); @@ -788,7 +839,7 @@ void QCBUILTIN PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_glob } //string(string cvarname) cvar_defstring -void QCBUILTIN PF_cvar_defstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); cvar_t *cv = Cvar_Get(str, "", 0, "QC variables"); @@ -796,7 +847,7 @@ void QCBUILTIN PF_cvar_defstring (progfuncs_t *prinst, struct globalvars_s *pr_g } //string(string cvarname) cvar_description -void QCBUILTIN PF_cvar_description (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_description (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); cvar_t *cv = Cvar_Get(str, "", 0, "QC variables"); @@ -804,7 +855,7 @@ void QCBUILTIN PF_cvar_description (progfuncs_t *prinst, struct globalvars_s *pr } //float(string name) cvar_type -void QCBUILTIN PF_cvar_type (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); int ret = 0; @@ -827,7 +878,7 @@ void QCBUILTIN PF_cvar_type (progfuncs_t *prinst, struct globalvars_s *pr_global } //void(string cvarname, string newvalue) cvar -void QCBUILTIN PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *var_name, *val; cvar_t *var; @@ -841,7 +892,7 @@ void QCBUILTIN PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals Cvar_Set (var, val); } -void QCBUILTIN PF_cvar_setlatch (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_setlatch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *var_name, *val; cvar_t *var; @@ -855,7 +906,7 @@ void QCBUILTIN PF_cvar_setlatch (progfuncs_t *prinst, struct globalvars_s *pr_gl Cvar_LockFromServer(var, val); } -void QCBUILTIN PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_cvar_setf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *var_name; float val; @@ -872,7 +923,7 @@ void QCBUILTIN PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_global } //float(string name, string value) registercvar -void QCBUILTIN PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_registercvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name, *value; value = PR_GetStringOfs(prinst, OFS_PARM0); @@ -882,7 +933,7 @@ void QCBUILTIN PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_glo else { name = value; - if (*prinst->callargc > 1) + if (prinst->callargc > 1) value = PR_GetStringOfs(prinst, OFS_PARM1); else value = ""; @@ -898,16 +949,16 @@ void QCBUILTIN PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_glo //Cvars //////////////////////////////////////////////////// //memory stuff -void QCBUILTIN PF_memalloc (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_memalloc (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { void *ptr = prinst->AddressableAlloc(prinst, G_INT(OFS_PARM0)); G_INT(OFS_RETURN) = (char*)ptr - prinst->stringtable; } -void QCBUILTIN PF_memfree (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_memfree (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { prinst->AddressableFree(prinst, prinst->stringtable + G_INT(OFS_PARM0)); } -void QCBUILTIN PF_memcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_memcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dst = G_INT(OFS_PARM0); int src = G_INT(OFS_PARM1); @@ -924,7 +975,7 @@ void QCBUILTIN PF_memcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals) } memcpy(prinst->stringtable + dst, prinst->stringtable + src, size); } -void QCBUILTIN PF_memset (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_memset (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dst = G_INT(OFS_PARM0); int val = G_INT(OFS_PARM1); @@ -951,11 +1002,11 @@ typedef struct { int len; int ofs; int accessmode; - progfuncs_t *prinst; + pubprogfuncs_t *prinst; } pf_fopen_files_t; pf_fopen_files_t pf_fopen_files[MAX_QC_FILES]; -void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_fopen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name = PR_GetStringOfs(prinst, OFS_PARM0); int fmode = G_FLOAT(OFS_PARM1); @@ -1108,7 +1159,7 @@ void PF_fclose_i (int fnum) pf_fopen_files[fnum].prinst = NULL; } -void QCBUILTIN PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_fclose (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int fnum = G_FLOAT(OFS_PARM0)-FIRST_QC_FILE_INDEX; @@ -1127,7 +1178,7 @@ void QCBUILTIN PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals) PF_fclose_i(fnum); } -void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_fgets (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char c, *s, *o, *max, *eof; int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX; @@ -1196,7 +1247,7 @@ void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals) } } -static void PF_fwrite (progfuncs_t *prinst, int fnum, char *msg, int len) +static void PF_fwrite (pubprogfuncs_t *prinst, int fnum, char *msg, int len) { if (fnum < 0 || fnum >= MAX_QC_FILES) { @@ -1240,7 +1291,7 @@ static void PF_fwrite (progfuncs_t *prinst, int fnum, char *msg, int len) } } -void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_fputs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int fnum = G_FLOAT(OFS_PARM0) - FIRST_QC_FILE_INDEX; char *msg = PF_VarString(prinst, 1, pr_globals); @@ -1249,7 +1300,7 @@ void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals) PF_fwrite (prinst, fnum, msg, len); } -void PF_fcloseall (progfuncs_t *prinst) +void PF_fcloseall (pubprogfuncs_t *prinst) { int i; for (i = 0; i < MAX_QC_FILES; i++) @@ -1264,7 +1315,7 @@ void PF_fcloseall (progfuncs_t *prinst) //DP_QC_WHICHPACK -void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *srcname = PR_GetStringOfs(prinst, OFS_PARM0); flocation_t loc; @@ -1286,7 +1337,7 @@ void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_global typedef struct prvmsearch_s { int handle; - progfuncs_t *fromprogs; //share across menu/server + pubprogfuncs_t *fromprogs; //share across menu/server int entries; char **names; int *sizes; @@ -1296,7 +1347,7 @@ typedef struct prvmsearch_s { prvmsearch_t *prvmsearches; int prvm_nextsearchhandle; -void search_close (progfuncs_t *prinst, int handle) +void search_close (pubprogfuncs_t *prinst, int handle) { int i; prvmsearch_t *prev, *s; @@ -1332,7 +1383,7 @@ void search_close (progfuncs_t *prinst, int handle) } } //a progs was closed... hunt down it's searches, and warn about any searches left open. -void search_close_progs(progfuncs_t *prinst, qboolean complain) +void search_close_progs(pubprogfuncs_t *prinst, qboolean complain) { int i; prvmsearch_t *prev, *s; @@ -1388,7 +1439,7 @@ int search_enumerate(const char *name, int fsize, void *parm) } //float search_begin(string pattern, float caseinsensitive, float quiet) = #74; -void QCBUILTIN PF_search_begin (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //< 0 for error, > 0 for handle. char *pattern = PR_GetStringOfs(prinst, OFS_PARM0); // qboolean caseinsensative = G_FLOAT(OFS_PARM1); @@ -1412,13 +1463,13 @@ void QCBUILTIN PF_search_begin (progfuncs_t *prinst, struct globalvars_s *pr_glo G_FLOAT(OFS_RETURN) = s->handle; } //void search_end(float handle) = #75; -void QCBUILTIN PF_search_end (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_search_end (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int handle = G_FLOAT(OFS_PARM0); search_close(prinst, handle); } //float search_getsize(float handle) = #76; -void QCBUILTIN PF_search_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_search_getsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int handle = G_FLOAT(OFS_PARM0); prvmsearch_t *s; @@ -1439,7 +1490,7 @@ void QCBUILTIN PF_search_getsize (progfuncs_t *prinst, struct globalvars_s *pr_g } } //string search_getfilename(float handle, float num) = #77; -void QCBUILTIN PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int handle = G_FLOAT(OFS_PARM0); int num = G_FLOAT(OFS_PARM1); @@ -1467,7 +1518,7 @@ void QCBUILTIN PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s * } //closes filesystem type stuff for when a progs has stopped needing it. -void PR_fclose_progs (progfuncs_t *prinst) +void PR_fclose_progs (pubprogfuncs_t *prinst) { PF_fcloseall(prinst); search_close_progs(prinst, true); @@ -1478,28 +1529,28 @@ void PR_fclose_progs (progfuncs_t *prinst) //reflection //float isfunction(string function_name) -void QCBUILTIN PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_isfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name = PR_GetStringOfs(prinst, OFS_PARM0); G_FLOAT(OFS_RETURN) = !!PR_FindFunction(prinst, name, PR_CURRENT); } //void callfunction(...) -void QCBUILTIN PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_callfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name; func_t f; - if (*prinst->callargc < 1) + if (prinst->callargc < 1) PR_BIError(prinst, "callfunction needs at least one argument\n"); - name = PR_GetStringOfs(prinst, OFS_PARM0+(*prinst->callargc-1)*3); - *prinst->callargc -= 1; + name = PR_GetStringOfs(prinst, OFS_PARM0+(prinst->callargc-1)*3); + prinst->callargc -= 1; f = PR_FindFunction(prinst, name, PR_CURRENT); if (f) PR_ExecuteProgram(prinst, f); } //void loadfromfile(string file) -void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_loadfromfile (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *filename = PR_GetStringOfs(prinst, OFS_PARM0); char *file = COM_LoadTempFile(filename); @@ -1520,7 +1571,7 @@ void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_glo G_FLOAT(OFS_RETURN) = 0; } -void QCBUILTIN PF_writetofile(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_writetofile(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int fnum = G_FLOAT(OFS_PARM0)-FIRST_QC_FILE_INDEX; void *ed = G_EDICT(prinst, OFS_PARM1); @@ -1537,7 +1588,7 @@ void QCBUILTIN PF_writetofile(progfuncs_t *prinst, struct globalvars_s *pr_globa } } -void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_loadfromdata (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *file = PR_GetStringOfs(prinst, OFS_PARM0); @@ -1557,7 +1608,7 @@ void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_glo G_FLOAT(OFS_RETURN) = 0; } -void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_parseentitydata(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { void *ed = G_EDICT(prinst, OFS_PARM0); char *file = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1587,21 +1638,21 @@ void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_g //////////////////////////////////////////////////// //Entities -void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WasFreed (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { wedict_t *ent; ent = G_WEDICT(prinst, OFS_PARM0); G_FLOAT(OFS_RETURN) = ent->isfree; } -void QCBUILTIN PF_num_for_edict (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_num_for_edict (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { wedict_t *ent; ent = G_WEDICT(prinst, OFS_PARM0); G_FLOAT(OFS_RETURN) = ent->entnum; } -void QCBUILTIN PF_edict_for_num(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_edict_for_num(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; ent = (edict_t*)EDICT_NUM(prinst, G_FLOAT(OFS_PARM0)); @@ -1610,7 +1661,7 @@ void QCBUILTIN PF_edict_for_num(progfuncs_t *prinst, struct globalvars_s *pr_glo } //entity nextent(entity) -void QCBUILTIN PF_nextent (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_nextent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; wedict_t *ent; @@ -1634,7 +1685,7 @@ void QCBUILTIN PF_nextent (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //entity() spawn -void QCBUILTIN PF_Spawn (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_Spawn (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { struct edict_s *ed; ed = ED_Alloc(prinst); @@ -1647,20 +1698,20 @@ void QCBUILTIN PF_Spawn (progfuncs_t *prinst, struct globalvars_s *pr_globals) //String functions //PF_dprint -void QCBUILTIN PF_dprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_dprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_DPrintf ("%s",PF_VarString(prinst, 0, pr_globals)); } //PF_print -void QCBUILTIN PF_print (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_print (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_Printf ("%s",PF_VarString(prinst, 0, pr_globals)); } //FTE_STRINGS //C style strncasecmp (compare first n characters - case insensative) -void QCBUILTIN PF_strncasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *a = PR_GetStringOfs(prinst, OFS_PARM0); char *b = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1671,7 +1722,7 @@ void QCBUILTIN PF_strncasecmp (progfuncs_t *prinst, struct globalvars_s *pr_glob //FTE_STRINGS //C style strcasecmp (case insensative string compare) -void QCBUILTIN PF_strcasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strcasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *a = PR_GetStringOfs(prinst, OFS_PARM0); char *b = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1681,7 +1732,7 @@ void QCBUILTIN PF_strcasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globa //FTE_STRINGS //C style strncmp (compare first n characters - case sensative. Note that there is no strcmp provided) -void QCBUILTIN PF_strncmp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *a = PR_GetStringOfs(prinst, OFS_PARM0); char *b = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1691,7 +1742,7 @@ void QCBUILTIN PF_strncmp (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //uses qw style \key\value strings -void QCBUILTIN PF_infoget (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_infoget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *info = PR_GetStringOfs(prinst, OFS_PARM0); char *key = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1702,7 +1753,7 @@ void QCBUILTIN PF_infoget (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //uses qw style \key\value strings -void QCBUILTIN PF_infoadd (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_infoadd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *info = PR_GetStringOfs(prinst, OFS_PARM0); char *key = PR_GetStringOfs(prinst, OFS_PARM1); @@ -1717,7 +1768,7 @@ void QCBUILTIN PF_infoadd (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //string(float pad, string str1, ...) strpad -void QCBUILTIN PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char destbuf[4096]; char *dest = destbuf; @@ -1842,7 +1893,7 @@ static int chrchar_alpha(int i, int basec, int baset, int convc, int convt, int } //FTE_STRINGS //bulk convert a string. change case or colouring. -void QCBUILTIN PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strconv (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int ccase = G_FLOAT(OFS_PARM0); //0 same, 1 lower, 2 upper int redalpha = G_FLOAT(OFS_PARM1); //0 same, 1 white, 2 red, 5 alternate, 6 alternate-alternate @@ -1890,12 +1941,12 @@ void QCBUILTIN PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals) //FTE_STRINGS //returns a string containing one character per parameter (up to the qc max params of 8). -void QCBUILTIN PF_chr2str (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_chr2str (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; char string[16]; - for (i = 0; i < *prinst->callargc; i++) + for (i = 0; i < prinst->callargc; i++) string[i] = G_FLOAT(OFS_PARM0 + i*3); string[i] = '\0'; RETURN_TSTRING(string); @@ -1903,10 +1954,10 @@ void QCBUILTIN PF_chr2str (progfuncs_t *prinst, struct globalvars_s *pr_globals) //FTE_STRINGS //returns character at position X -void QCBUILTIN PF_str2chr (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *instr = PR_GetStringOfs(prinst, OFS_PARM0); - int ofs = (*prinst->callargc>1)?G_FLOAT(OFS_PARM1):0; + int ofs = (prinst->callargc>1)?G_FLOAT(OFS_PARM1):0; if (ofs < 0) ofs = strlen(instr)+ofs; @@ -1919,12 +1970,12 @@ void QCBUILTIN PF_str2chr (progfuncs_t *prinst, struct globalvars_s *pr_globals) //FTE_STRINGS //strstr, without generating a new string. Use in conjunction with FRIK_FILE's substring for more similar strstr. -void QCBUILTIN PF_strstrofs (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *instr = PR_GetStringOfs(prinst, OFS_PARM0); char *match = PR_GetStringOfs(prinst, OFS_PARM1); - int firstofs = (*prinst->callargc>2)?G_FLOAT(OFS_PARM2):0; + int firstofs = (prinst->callargc>2)?G_FLOAT(OFS_PARM2):0; if (firstofs && (firstofs < 0 || firstofs > strlen(instr))) { @@ -1940,7 +1991,7 @@ void QCBUILTIN PF_strstrofs (progfuncs_t *prinst, struct globalvars_s *pr_global } //float(string input) stof -void QCBUILTIN PF_stof (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_stof (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; @@ -1950,7 +2001,7 @@ void QCBUILTIN PF_stof (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //tstring(float input) ftos -void QCBUILTIN PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_ftos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float v; char pr_string_temp[64]; @@ -1966,7 +2017,7 @@ void QCBUILTIN PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //tstring(integer input) itos -void QCBUILTIN PF_itos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_itos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int v; char pr_string_temp[64]; @@ -1977,7 +2028,7 @@ void QCBUILTIN PF_itos (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //int(string input) stoi -void QCBUILTIN PF_stoi (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_stoi (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *input = PR_GetStringOfs(prinst, OFS_PARM0); @@ -1985,7 +2036,7 @@ void QCBUILTIN PF_stoi (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //tstring(integer input) htos -void QCBUILTIN PF_htos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_htos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int v; char pr_string_temp[64]; @@ -1996,7 +2047,7 @@ void QCBUILTIN PF_htos (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //int(string input) stoh -void QCBUILTIN PF_stoh (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_stoh (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *input = PR_GetStringOfs(prinst, OFS_PARM0); @@ -2005,7 +2056,7 @@ void QCBUILTIN PF_stoh (progfuncs_t *prinst, struct globalvars_s *pr_globals) //vector(string s) stov = #117 //returns vector value from a string -void QCBUILTIN PF_stov (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_stov (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; char *s; @@ -2033,7 +2084,7 @@ void QCBUILTIN PF_stov (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //tstring(vector input) vtos -void QCBUILTIN PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_vtos (pubprogfuncs_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]); @@ -2042,41 +2093,19 @@ void QCBUILTIN PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals) } -void QCBUILTIN PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_forgetstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { -#if 1 prinst->AddressableFree(prinst, prinst->stringtable + G_INT(OFS_PARM0)); -#else - char *s=PR_RemoveProgsString(prinst, G_INT(OFS_PARM0)); - if (!s) - { - Con_Printf("string was not strzoned\n"); - (*prinst->pr_trace) = 1; - return; - } -// char *s=PR_GetStringOfs(prinst, OFS_PARM0); - s-=8; - if (((int *)s)[0] != PRSTR) - { - Con_Printf("QC tried to free a non dynamic string: "); - Con_Printf("%s\n", s+8); //two prints, so that logged prints ensure the first is written. - (*prinst->pr_trace) = 1; - PR_StackTrace(prinst); - return; - } - ((int *)s)[0] = 0xabcd1234; - Z_TagFree(s); -#endif } -void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) //frik_file +void QCBUILTIN PF_dupstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //frik_file { char *buf; int len = 0; char *s[8]; int l[8]; int i; - for (i = 0; i < *prinst->callargc; i++) + for (i = 0; i < prinst->callargc; i++) { s[i] = PR_GetStringOfs(prinst, OFS_PARM0+i*3); l[i] = strlen(s[i]); @@ -2084,7 +2113,6 @@ void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals } len++; /*for the null*/ -#if 1 buf = prinst->AddressableAlloc(prinst, len); if (!buf) { @@ -2092,16 +2120,9 @@ void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals return; } G_INT(OFS_RETURN) = (char*)buf - prinst->stringtable; -#else - buf = Z_TagMalloc(len+8, Z_QC_TAG); - RETURN_SSTRING(buf+8); - ((int *)buf)[0] = PRSTR; - ((int *)buf)[1] = len; - buf += 8; -#endif len = 0; - for (i = 0; i < *prinst->callargc; i++) + for (i = 0; i < prinst->callargc; i++) { memcpy(buf, s[i], l[i]); buf += l[i]; @@ -2110,14 +2131,14 @@ void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals } //string(string str1, string str2) strcat -void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *buf; int len = 0; char *s[8]; int l[8]; int i; - for (i = 0; i < *prinst->callargc; i++) + for (i = 0; i < prinst->callargc; i++) { s[i] = PR_GetStringOfs(prinst, OFS_PARM0+i*3); l[i] = strlen(s[i]); @@ -2126,7 +2147,7 @@ void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals) len++; /*for the null*/ ((int *)pr_globals)[OFS_RETURN] = prinst->AllocTempString(prinst, &buf, len); len = 0; - for (i = 0; i < *prinst->callargc; i++) + for (i = 0; i < prinst->callargc; i++) { memcpy(buf, s[i], l[i]); buf += l[i]; @@ -2135,7 +2156,7 @@ void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //returns a section of a string as a tempstring -void QCBUILTIN PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int start, length, slen; char *s; @@ -2175,13 +2196,13 @@ void QCBUILTIN PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_global string[length] = '\0'; } -void QCBUILTIN PF_strlen(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strlen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = strlen(PR_GetStringOfs(prinst, OFS_PARM0)); } //float(string input, string token) instr -void QCBUILTIN PF_instr (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_instr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *sub; char *s1; @@ -2204,7 +2225,7 @@ void QCBUILTIN PF_instr (progfuncs_t *prinst, struct globalvars_s *pr_globals) RETURN_SSTRING(sub); //last as long as the original string } -void QCBUILTIN PF_strreplace (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strreplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char resultbuf[4096]; char *result = resultbuf; @@ -2233,7 +2254,7 @@ void QCBUILTIN PF_strreplace (progfuncs_t *prinst, struct globalvars_s *pr_globa else RETURN_TSTRING(subject); } -void QCBUILTIN PF_strireplace (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strireplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char resultbuf[4096]; char *result = resultbuf; @@ -2264,7 +2285,7 @@ void QCBUILTIN PF_strireplace (progfuncs_t *prinst, struct globalvars_s *pr_glob } //string(entity ent) etos = #65 -void QCBUILTIN PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_etos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char s[64]; snprintf (s, sizeof(s), "entity %i", G_EDICTNUM(prinst, OFS_PARM0)); @@ -2273,7 +2294,7 @@ void QCBUILTIN PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals) //DP_QC_STRINGCOLORFUNCTIONS // #476 float(string s) strlennocol - returns how many characters are in a string, minus color codes -void QCBUILTIN PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strlennocol (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *in = PR_GetStringOfs(prinst, OFS_PARM0); char result[8192]; @@ -2289,7 +2310,7 @@ void QCBUILTIN PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_glob //DP_QC_STRINGCOLORFUNCTIONS // string (string s) strdecolorize - returns the passed in string with color codes stripped -void QCBUILTIN PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strdecolorize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *in = PR_GetStringOfs(prinst, OFS_PARM0); char result[8192]; @@ -2301,7 +2322,7 @@ void QCBUILTIN PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_gl } //DP_QC_STRING_CASE_FUNCTIONS -void QCBUILTIN PF_strtolower (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strtolower (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *in = PR_GetStringOfs(prinst, OFS_PARM0); char result[8192]; @@ -2313,7 +2334,7 @@ void QCBUILTIN PF_strtolower (progfuncs_t *prinst, struct globalvars_s *pr_globa } //DP_QC_STRING_CASE_FUNCTIONS -void QCBUILTIN PF_strtoupper (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strtoupper (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *in = PR_GetStringOfs(prinst, OFS_PARM0); char result[8192]; @@ -2325,7 +2346,7 @@ void QCBUILTIN PF_strtoupper (progfuncs_t *prinst, struct globalvars_s *pr_globa } //DP_QC_STRFTIME -void QCBUILTIN PF_strftime (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *in = PF_VarString(prinst, 1, pr_globals); char result[8192]; @@ -2350,7 +2371,7 @@ void QCBUILTIN PF_strftime (progfuncs_t *prinst, struct globalvars_s *pr_globals //515's String functions struct strbuf { - progfuncs_t *prinst; + pubprogfuncs_t *prinst; char **strings; int used; int allocated; @@ -2359,7 +2380,7 @@ struct strbuf { #define NUMSTRINGBUFS 64 struct strbuf strbuflist[NUMSTRINGBUFS]; -void PF_buf_shutdown(progfuncs_t *prinst) +void PF_buf_shutdown(pubprogfuncs_t *prinst) { int i, bufno; @@ -2381,7 +2402,7 @@ void PF_buf_shutdown(progfuncs_t *prinst) } // #440 float() buf_create (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_create (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; @@ -2400,7 +2421,7 @@ void QCBUILTIN PF_buf_create (progfuncs_t *prinst, struct globalvars_s *pr_glob G_FLOAT(OFS_RETURN) = 0; } // #441 void(float bufhandle) buf_del (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_del (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_del (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; int bufno = G_FLOAT(OFS_PARM0)-1; @@ -2421,7 +2442,7 @@ void QCBUILTIN PF_buf_del (progfuncs_t *prinst, struct globalvars_s *pr_globals strbuflist[bufno].prinst = NULL; } // #442 float(float bufhandle) buf_getsize (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_getsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; @@ -2433,7 +2454,7 @@ void QCBUILTIN PF_buf_getsize (progfuncs_t *prinst, struct globalvars_s *pr_glo G_FLOAT(OFS_RETURN) = strbuflist[bufno].used; } // #443 void(float bufhandle_from, float bufhandle_to) buf_copy (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_copy (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_copy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int buffrom = G_FLOAT(OFS_PARM0)-1; int bufto = G_FLOAT(OFS_PARM1)-1; @@ -2451,7 +2472,7 @@ void QCBUILTIN PF_buf_copy (progfuncs_t *prinst, struct globalvars_s *pr_global Con_Printf("PF_buf_copy: stub\n"); } // #444 void(float bufhandle, float sortpower, float backward) buf_sort (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_sort (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_sort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; //int sortpower = G_FLOAT(OFS_PARM1); @@ -2465,7 +2486,7 @@ void QCBUILTIN PF_buf_sort (progfuncs_t *prinst, struct globalvars_s *pr_global Con_Printf("PF_buf_sort: stub\n"); } // #445 string(float bufhandle, string glue) buf_implode (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_buf_implode (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_implode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; //char *glue = PR_GetStringOfs(prinst, OFS_PARM1); @@ -2480,7 +2501,7 @@ void QCBUILTIN PF_buf_implode (progfuncs_t *prinst, struct globalvars_s *pr_glo RETURN_TSTRING(""); } // #446 string(float bufhandle, float string_index) bufstr_get (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_bufstr_get (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bufstr_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; int index = G_FLOAT(OFS_PARM1); @@ -2505,7 +2526,7 @@ void QCBUILTIN PF_bufstr_get (progfuncs_t *prinst, struct globalvars_s *pr_glob RETURN_TSTRING(strbuflist[bufno].strings[index]); } // #447 void(float bufhandle, float string_index, string str) bufstr_set (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_bufstr_set (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bufstr_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; int index = G_FLOAT(OFS_PARM1); @@ -2533,7 +2554,7 @@ void QCBUILTIN PF_bufstr_set (progfuncs_t *prinst, struct globalvars_s *pr_glob strbuflist[bufno].used = index+1; } // #448 float(float bufhandle, string str, float order) bufstr_add (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bufstr_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; char *string = PR_GetStringOfs(prinst, OFS_PARM1); @@ -2581,7 +2602,7 @@ void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_glob G_FLOAT(OFS_RETURN) = index; } // #449 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS) -void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bufstr_free (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; int index = G_FLOAT(OFS_PARM1); @@ -2599,7 +2620,7 @@ void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_glo strbuflist[bufno].strings[index] = NULL; } -void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_buf_cvarlist (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bufno = G_FLOAT(OFS_PARM0)-1; //char *pattern = PR_GetStringOfs(prinst, OFS_PARM1); @@ -2617,7 +2638,7 @@ void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_gl //////////////////////////////////////////////////// //float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16) -void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int insens = G_FLOAT(OFS_PARM0); char *str = PF_VarString(prinst, 1, pr_globals); @@ -2629,8 +2650,49 @@ void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = QCRC_Block(str, len); } +int SHA1(char *digest, int maxdigestsize, char *string); +void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *hashtype = PR_GetStringOfs(prinst, OFS_PARM0); + char *str = PF_VarString(prinst, 1, pr_globals); + int digestsize, i; + unsigned char digest[64]; + unsigned char hexdig[sizeof(digest)*2+1]; + + if (!strcmp(hashtype, "MD4")) + { + digestsize = 16; + Com_BlockFullChecksum(str, strlen(str), digest); + } + else if (!strcmp(hashtype, "SHA1")) + { + digestsize = SHA1(digest, sizeof(digest), str); + } + else if (!strcmp(hashtype, "CRC16")) + { + digestsize = 2; + *(unsigned short*)digest = QCRC_Block(str, strlen(str)); + } + else + digestsize = 0; + + if (digestsize) + { + for (i = 0; i < digestsize; i++) + { + const char *hex = "0123456789abcdef"; + hexdig[i*2+0] = hex[digest[i]>>4]; + hexdig[i*2+1] = hex[digest[i]&0xf]; + } + hexdig[i*2] = 0; + RETURN_TSTRING(hexdig); + } + else + G_INT(OFS_RETURN) = 0; +} + // #510 string(string in) uri_escape = #510; -void QCBUILTIN PF_uri_escape (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_uri_escape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { static const char *hex = "0123456789ABCDEF"; @@ -2656,7 +2718,7 @@ void QCBUILTIN PF_uri_escape (progfuncs_t *prinst, struct globalvars_s *pr_glob } // #511 string(string in) uri_unescape = #511; -void QCBUILTIN PF_uri_unescape (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_uri_unescape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned char *s = (unsigned char*)PR_GetStringOfs(prinst, OFS_PARM0); unsigned char resultbuf[8192]; @@ -2704,9 +2766,9 @@ void QCBUILTIN PF_uri_unescape (progfuncs_t *prinst, struct globalvars_s *pr_gl #ifdef WEBCLIENT static void PR_uri_get_callback(struct dl_download *dl) { - extern progfuncs_t *menuprogs; + extern pubprogfuncs_t *menuprogs; world_t *w = dl->user_ctx; - progfuncs_t *prinst = w?w->progs:menuprogs; + pubprogfuncs_t *prinst = w?w->progs:menuprogs; float id = dl->user_num; func_t func; @@ -2743,7 +2805,7 @@ static void PR_uri_get_callback(struct dl_download *dl) // uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned // returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string //float(string uril, float id) uri_get = #513; -void QCBUILTIN PF_uri_get (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef WEBCLIENT world_t *w = prinst->parms->user; @@ -2782,7 +2844,7 @@ static struct { } qctoken[MAXQCTOKENS]; unsigned int qctoken_count; -void QCBUILTIN PF_ArgC (progfuncs_t *prinst, struct globalvars_s *pr_globals) //85 //float() argc; +void QCBUILTIN PF_ArgC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //85 //float() argc; { G_FLOAT(OFS_RETURN) = qctoken_count; } @@ -2819,17 +2881,17 @@ int tokenizeqc(char *str, qboolean dpfuckage) } /*KRIMZON_SV_PARSECLIENTCOMMAND added these two - note that for compatibility with DP, this tokenize builtin is veeery vauge and doesn't match the console*/ -void QCBUILTIN PF_Tokenize (progfuncs_t *prinst, struct globalvars_s *pr_globals) //84 //void(string str) tokanize; +void QCBUILTIN PF_Tokenize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //84 //void(string str) tokanize; { G_FLOAT(OFS_RETURN) = tokenizeqc(PR_GetStringOfs(prinst, OFS_PARM0), true); } -void QCBUILTIN PF_tokenize_console (progfuncs_t *prinst, struct globalvars_s *pr_globals) //84 //void(string str) tokanize; +void QCBUILTIN PF_tokenize_console (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //84 //void(string str) tokanize; { G_FLOAT(OFS_RETURN) = tokenizeqc(PR_GetStringOfs(prinst, OFS_PARM0), false); } -void QCBUILTIN PF_tokenizebyseparator (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PR_GetStringOfs(prinst, OFS_PARM0); char *sep[7]; @@ -2839,7 +2901,7 @@ void QCBUILTIN PF_tokenizebyseparator (progfuncs_t *prinst, struct globalvars_s int tlen; qboolean found = true; - while (seps < *prinst->callargc - 1 && seps < 7) + while (seps < prinst->callargc - 1 && seps < 7) { sep[seps] = PR_GetStringOfs(prinst, OFS_PARM1 + seps*3); seplen[seps] = strlen(sep[seps]); @@ -2898,7 +2960,7 @@ void QCBUILTIN PF_tokenizebyseparator (progfuncs_t *prinst, struct globalvars_s G_FLOAT(OFS_RETURN) = qctoken_count; } -void QCBUILTIN PF_argv_start_index (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_argv_start_index (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int idx = G_FLOAT(OFS_PARM0); @@ -2912,7 +2974,7 @@ void QCBUILTIN PF_argv_start_index (progfuncs_t *prinst, struct globalvars_s *p G_FLOAT(OFS_RETURN) = qctoken[idx].start; } -void QCBUILTIN PF_argv_end_index (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_argv_end_index (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int idx = G_FLOAT(OFS_PARM0); @@ -2926,7 +2988,7 @@ void QCBUILTIN PF_argv_end_index (progfuncs_t *prinst, struct globalvars_s *pr_ G_FLOAT(OFS_RETURN) = qctoken[idx].end; } -void QCBUILTIN PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals) //86 //string(float num) argv; +void QCBUILTIN PF_ArgV (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //86 //string(float num) argv; { int idx = G_FLOAT(OFS_PARM0); @@ -2944,7 +3006,7 @@ void QCBUILTIN PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals) //////////////////////////////////////////////////// //Maths functions -void QCBUILTIN PF_random (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float num; @@ -2954,7 +3016,7 @@ void QCBUILTIN PF_random (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //float(float number, float quantity) bitshift = #218; -void QCBUILTIN PF_bitshift(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bitshift(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int bitmask; int shift; @@ -2971,19 +3033,19 @@ void QCBUILTIN PF_bitshift(progfuncs_t *prinst, struct globalvars_s *pr_globals) } //float(float a, floats) min = #94 -void QCBUILTIN PF_min (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_min (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; float f; - if (*prinst->callargc == 2) + if (prinst->callargc == 2) { G_FLOAT(OFS_RETURN) = min(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); } - else if (*prinst->callargc >= 3) + else if (prinst->callargc >= 3) { f = G_FLOAT(OFS_PARM0); - for (i = 1; i < *prinst->callargc; i++) + for (i = 1; i < prinst->callargc; i++) { if (G_FLOAT((OFS_PARM0 + i * 3)) < f) f = G_FLOAT((OFS_PARM0 + i * 3)); @@ -2995,19 +3057,19 @@ void QCBUILTIN PF_min (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //float(float a, floats) max = #95 -void QCBUILTIN PF_max (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_max (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; float f; - if (*prinst->callargc == 2) + if (prinst->callargc == 2) { G_FLOAT(OFS_RETURN) = max(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); } - else if (*prinst->callargc >= 3) + else if (prinst->callargc >= 3) { f = G_FLOAT(OFS_PARM0); - for (i = 1; i < *prinst->callargc; i++) { + for (i = 1; i < prinst->callargc; i++) { if (G_FLOAT((OFS_PARM0 + i * 3)) > f) f = G_FLOAT((OFS_PARM0 + i * 3)); } @@ -3020,7 +3082,7 @@ void QCBUILTIN PF_max (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //float(float minimum, float val, float maximum) bound = #96 -void QCBUILTIN PF_bound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_bound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (G_FLOAT(OFS_PARM1) > G_FLOAT(OFS_PARM2)) G_FLOAT(OFS_RETURN) = G_FLOAT(OFS_PARM2); @@ -3030,51 +3092,51 @@ void QCBUILTIN PF_bound (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = G_FLOAT(OFS_PARM1); } -void QCBUILTIN PF_Sin (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_Sin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_Cos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_Cos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_Sqrt (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_Sqrt (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_pow (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_pow (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = pow(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); } -void QCBUILTIN PF_asin (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_asin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = asin(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_acos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_acos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = acos(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_atan (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_atan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = atan(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_atan2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_atan2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = atan2(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1)); } -void QCBUILTIN PF_tan (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_tan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = tan(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_fabs (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_fabs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float v; v = G_FLOAT(OFS_PARM0); G_FLOAT(OFS_RETURN) = fabs(v); } -void QCBUILTIN PF_rint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_rint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float f; f = G_FLOAT(OFS_PARM0); @@ -3084,12 +3146,12 @@ void QCBUILTIN PF_rint (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = (int)(f - 0.5); } -void QCBUILTIN PF_floor (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_floor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0)); } -void QCBUILTIN PF_ceil (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_ceil (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0)); } @@ -3099,7 +3161,7 @@ void QCBUILTIN PF_ceil (progfuncs_t *prinst, struct globalvars_s *pr_globals) //Vector functions //vector() randomvec = #91 -void QCBUILTIN PF_randomvector (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_randomvector (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { vec3_t temp; do @@ -3112,7 +3174,7 @@ void QCBUILTIN PF_randomvector (progfuncs_t *prinst, struct globalvars_s *pr_glo } //float vectoyaw(vector) -void QCBUILTIN PF_vectoyaw (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1; float yaw; @@ -3132,7 +3194,7 @@ void QCBUILTIN PF_vectoyaw (progfuncs_t *prinst, struct globalvars_s *pr_globals } //float(vector) vlen -void QCBUILTIN PF_vlen (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1; float newv; @@ -3146,12 +3208,12 @@ void QCBUILTIN PF_vlen (progfuncs_t *prinst, struct globalvars_s *pr_globals) } //vector vectoangles(vector) -void QCBUILTIN PF_vectoangles (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1, *up; value1 = G_VECTOR(OFS_PARM0); - if (*prinst->callargc >= 2) + if (prinst->callargc >= 2) up = G_VECTOR(OFS_PARM1); else up = NULL; @@ -3160,7 +3222,7 @@ void QCBUILTIN PF_vectoangles (progfuncs_t *prinst, struct globalvars_s *pr_glob } //vector normalize(vector) -void QCBUILTIN PF_normalize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_normalize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1; vec3_t newvalue; @@ -3184,7 +3246,7 @@ void QCBUILTIN PF_normalize (progfuncs_t *prinst, struct globalvars_s *pr_global VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); } -void QCBUILTIN PF_rotatevectorsbyangles (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; @@ -3206,7 +3268,7 @@ void QCBUILTIN PF_rotatevectorsbyangles (progfuncs_t *prinst, struct globalvars_ VectorCopy(res[2], w->g.v_up); } -void QCBUILTIN PF_rotatevectorsbymatrix (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_rotatevectorsbymatrix (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; vec3_t src[3], trans[3], res[3]; @@ -3230,7 +3292,7 @@ void QCBUILTIN PF_rotatevectorsbymatrix (progfuncs_t *prinst, struct globalvars_ //////////////////////////////////////////////////// //Progs internals -void QCBUILTIN PF_Abort(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { prinst->AbortStack(prinst); } @@ -3238,7 +3300,7 @@ void QCBUILTIN PF_Abort(progfuncs_t *prinst, struct globalvars_s *pr_globals) //this func calls a function in annother progs //it works in the same way as the above func, except that it calls by reference to a function, as opposed to by it's name //used for entity function variables - not actually needed anymore -void QCBUILTIN PF_externrefcall (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_externrefcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int progsnum; func_t f; @@ -3249,11 +3311,11 @@ void QCBUILTIN PF_externrefcall (progfuncs_t *prinst, struct globalvars_s *pr_gl for (i = OFS_PARM0; i < OFS_PARM5; i+=3) VectorCopy(G_VECTOR(i+(2*3)), G_VECTOR(i)); - (*prinst->pr_trace)++; //continue debugging. + prinst->pr_trace++; //continue debugging. PR_ExecuteProgram(prinst, f); } -void QCBUILTIN PF_externset (progfuncs_t *prinst, struct globalvars_s *pr_globals) //set a value in annother progs +void QCBUILTIN PF_externset (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //set a value in annother progs { int n = G_PROG(OFS_PARM0); int v = G_INT(OFS_PARM1); @@ -3266,7 +3328,7 @@ void QCBUILTIN PF_externset (progfuncs_t *prinst, struct globalvars_s *pr_global var->_int = v; } -void QCBUILTIN PF_externvalue (progfuncs_t *prinst, struct globalvars_s *pr_globals) //return a value in annother progs +void QCBUILTIN PF_externvalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //return a value in annother progs { int n = G_PROG(OFS_PARM0); char *varname = PF_VarString(prinst, 1, pr_globals); @@ -3299,7 +3361,7 @@ void QCBUILTIN PF_externvalue (progfuncs_t *prinst, struct globalvars_s *pr_glob } } -void QCBUILTIN PF_externcall (progfuncs_t *prinst, struct globalvars_s *pr_globals) //this func calls a function in annother progs (by name) +void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //this func calls a function in annother progs (by name) { int progsnum; char *funcname; @@ -3316,7 +3378,7 @@ void QCBUILTIN PF_externcall (progfuncs_t *prinst, struct globalvars_s *pr_globa for (i = OFS_PARM0; i < OFS_PARM5; i+=3) VectorCopy(G_VECTOR(i+(2*3)), G_VECTOR(i)); - (*prinst->pr_trace)++; //continue debugging + prinst->pr_trace++; //continue debugging PR_ExecuteProgram(prinst, f); } else if (!f) @@ -3332,21 +3394,21 @@ void QCBUILTIN PF_externcall (progfuncs_t *prinst, struct globalvars_s *pr_globa VectorCopy(G_VECTOR(i+(1*3)), G_VECTOR(i)); G_INT(OFS_PARM0) = failedst; - (*prinst->pr_trace)++; //continue debugging + prinst->pr_trace++; //continue debugging PR_ExecuteProgram(prinst, f); } } -void QCBUILTIN PF_traceon (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_traceon (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - (*prinst->pr_trace) = true; + prinst->pr_trace = true; } -void QCBUILTIN PF_traceoff (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_traceoff (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - (*prinst->pr_trace) = false; + prinst->pr_trace = false; } -void QCBUILTIN PF_coredump (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_coredump (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int size = 1024*1024*8; char *buffer = BZ_Malloc(size); @@ -3354,7 +3416,7 @@ void QCBUILTIN PF_coredump (progfuncs_t *prinst, struct globalvars_s *pr_globals COM_WriteFile("core.txt", buffer, size); BZ_Free(buffer); } -void QCBUILTIN PF_eprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_eprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int size = 1024*1024; char *buffer = BZ_Malloc(size); @@ -3364,7 +3426,7 @@ void QCBUILTIN PF_eprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) BZ_Free(buffer); } -void QCBUILTIN PF_break (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_break (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef SERVERONLY //new break code char *s; @@ -3390,7 +3452,7 @@ void QCBUILTIN PF_break (progfuncs_t *prinst, struct globalvars_s *pr_globals) } } #elif defined(TEXTEDITOR) - (*prinst->pr_trace)++; + prinst->pr_trace++; #else //old break code Con_Printf ("break statement\n"); *(int *)-4 = 0; // dump to debugger @@ -3398,7 +3460,7 @@ Con_Printf ("break statement\n"); #endif } -void QCBUILTIN PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_error (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; @@ -3416,7 +3478,7 @@ void QCBUILTIN PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals) { // SV_Error ("Program error: %s", s); PF_break(prinst, pr_globals); - (*prinst->pr_trace) = 2; + prinst->pr_trace = 2; } else { @@ -3430,7 +3492,7 @@ void QCBUILTIN PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals) //System //Sends text over to the client's execution buffer -void QCBUILTIN PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_localcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; @@ -3441,7 +3503,7 @@ void QCBUILTIN PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals Cbuf_AddText (str, RESTRICT_INSECURE); } -void QCBUILTIN PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_calltimeofday (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { date_t date; func_t f; @@ -3463,7 +3525,7 @@ void QCBUILTIN PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_gl } } -void QCBUILTIN PF_sprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sprintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { const char *s, *s0; char outbuf[4096]; @@ -3486,11 +3548,11 @@ void QCBUILTIN PF_sprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals) s = PR_GetStringOfs(prinst, OFS_PARM0); -#define GETARG_FLOAT(a) (((a)>=1 && (a)<*prinst->callargc) ? (G_FLOAT(OFS_PARM0 + 3 * (a))) : 0) -#define GETARG_VECTOR(a) (((a)>=1 && (a)<*prinst->callargc) ? (G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyvec) -#define GETARG_INT(a) (((a)>=1 && (a)<*prinst->callargc) ? (G_INT(OFS_PARM0 + 3 * (a))) : 0) -#define GETARG_INTVECTOR(a) (((a)>=1 && (a)<*prinst->callargc) ? ((int*) G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyivec) -#define GETARG_STRING(a) (((a)>=1 && (a)<*prinst->callargc) ? (PR_GetStringOfs(prinst, OFS_PARM0 + 3 * (a))) : "") +#define GETARG_FLOAT(a) (((a)>=1 && (a)callargc) ? (G_FLOAT(OFS_PARM0 + 3 * (a))) : 0) +#define GETARG_VECTOR(a) (((a)>=1 && (a)callargc) ? (G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyvec) +#define GETARG_INT(a) (((a)>=1 && (a)callargc) ? (G_INT(OFS_PARM0 + 3 * (a))) : 0) +#define GETARG_INTVECTOR(a) (((a)>=1 && (a)callargc) ? ((int*) G_VECTOR(OFS_PARM0 + 3 * (a))) : dummyivec) +#define GETARG_STRING(a) (((a)>=1 && (a)callargc) ? (PR_GetStringOfs(prinst, OFS_PARM0 + 3 * (a))) : "") for(;;) { @@ -3782,23 +3844,20 @@ finished: RETURN_TSTRING(outbuf); } -fdef_t *ED_FieldInfo (progfuncs_t *progfuncs, unsigned int *count); -char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val); -pbool ED_ParseEval (progfuncs_t *progfuncs, eval_t *eval, int type, char *s); //float() -void QCBUILTIN PF_numentityfields (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_numentityfields (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int count = 0; - ED_FieldInfo(prinst, &count); + prinst->FieldInfo(prinst, &count); G_FLOAT(OFS_RETURN) = count; } //string(float fieldnum) -void QCBUILTIN PF_entityfieldname (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_entityfieldname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int fidx = G_FLOAT(OFS_PARM0); unsigned int count = 0; fdef_t *fdef; - fdef = ED_FieldInfo(prinst, &count); + fdef = prinst->FieldInfo(prinst, &count); if (fidx < count) { RETURN_TSTRING(fdef[fidx].name); @@ -3807,11 +3866,11 @@ void QCBUILTIN PF_entityfieldname (progfuncs_t *prinst, struct globalvars_s *pr_ G_INT(OFS_RETURN) = 0; } //float(float fieldnum) -void QCBUILTIN PF_entityfieldtype (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_entityfieldtype (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int fidx = G_FLOAT(OFS_PARM0); unsigned int count = 0; - fdef_t *fdef = ED_FieldInfo(prinst, &count); + fdef_t *fdef = prinst->FieldInfo(prinst, &count); if (fidx < count) { G_FLOAT(OFS_RETURN) = fdef[fidx].type; @@ -3820,41 +3879,60 @@ void QCBUILTIN PF_entityfieldtype (progfuncs_t *prinst, struct globalvars_s *pr_ G_FLOAT(OFS_RETURN) = 0; } //string(float fieldnum, entity ent) -void QCBUILTIN PF_getentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_getentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int fidx = G_FLOAT(OFS_PARM0); wedict_t *ent = (wedict_t *)G_EDICT(prinst, OFS_PARM1); eval_t *eval; unsigned int count = 0; - fdef_t *fdef = ED_FieldInfo(prinst, &count); + fdef_t *fdef = prinst->FieldInfo(prinst, &count); if (fidx < count) { eval = (eval_t *)&((float *)ent->v)[fdef[fidx].ofs]; - RETURN_TSTRING(PR_UglyValueString(prinst, fdef[fidx].type, eval)); + RETURN_TSTRING(prinst->UglyValueString(prinst, fdef[fidx].type, eval)); } else G_INT(OFS_RETURN) = 0; } //float(float fieldnum, entity ent, string s) -void QCBUILTIN PF_putentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int fidx = G_FLOAT(OFS_PARM0); wedict_t *ent = (wedict_t *)G_EDICT(prinst, OFS_PARM1); char *str = PR_GetStringOfs(prinst, OFS_PARM2); eval_t *eval; unsigned int count = 0; - fdef_t *fdef = ED_FieldInfo(prinst, &count); + fdef_t *fdef = prinst->FieldInfo(prinst, &count); if (fidx < count) { eval = (eval_t *)&((float *)ent->v)[fdef[fidx].ofs]; - G_FLOAT(OFS_RETURN) = ED_ParseEval(prinst, eval, fdef[fidx].type, str); + G_FLOAT(OFS_RETURN) = prinst->ParseEval(prinst, eval, fdef[fidx].type, str); } else G_FLOAT(OFS_RETURN) = 0; } + + + + + + +void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored) +{ +#if defined(SKELETALOBJECTS) || defined(RAGDOLLS) + skel_reset(progs); +#endif + PR_fclose_progs(progs); + search_close_progs(progs, !errored); +#ifdef TEXTEDITOR + Editor_ProgsKilled(progs); +#endif +} + + #define DEF_SAVEGLOBAL (1u<<15) -static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cvar_t *var) +static void PR_AutoCvarApply(pubprogfuncs_t *prinst, eval_t *val, etype_t type, cvar_t *var) { switch(type & ~DEF_SAVEGLOBAL) { @@ -3865,7 +3943,7 @@ static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cva val->_int = var->ival; break; case ev_string: - PR_RemoveProgsString(prinst, val->_int); + prinst->RemoveProgsString(prinst, val->_int); if (*var->string) val->_int = PR_SetString(prinst, var->string); else @@ -3886,7 +3964,7 @@ static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cva } } /*called when a var has changed*/ -void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var) +void PR_AutoCvar(pubprogfuncs_t *prinst, cvar_t *var) { char *gname; eval_t *val; @@ -3908,7 +3986,7 @@ void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var) } } -void PR_FoundPrefixedGlobals(progfuncs_t *progfuncs, char *name, eval_t *val, etype_t type) +void PDECL PR_FoundPrefixedGlobals(pubprogfuncs_t *progfuncs, char *name, eval_t *val, etype_t type) { cvar_t *var; char *vals; @@ -3946,7 +4024,7 @@ void PR_FoundPrefixedGlobals(progfuncs_t *progfuncs, char *name, eval_t *val, et PR_AutoCvarApply(progfuncs, val, type, var); } -void PR_AutoCvarSetup(progfuncs_t *prinst) +void PR_AutoCvarSetup(pubprogfuncs_t *prinst) { prinst->FindPrefixGlobals (prinst, "autocvar_", PR_FoundPrefixedGlobals); } diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 3c604a11..c80651bc 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -71,14 +71,14 @@ typedef struct lh_extension_s { extern lh_extension_t QSG_Extensions[]; extern unsigned int QSG_Extensions_count; -pbool QC_WriteFile(const char *name, void *data, int len); +pbool QDECL QC_WriteFile(const char *name, void *data, int len); void *VARGS PR_CB_Malloc(int size); //these functions should be tracked by the library reliably, so there should be no need to track them ourselves. void VARGS PR_CB_Free(void *mem); - -void PF_InitTempStrings(progfuncs_t *prinst); -string_t PR_TempString(progfuncs_t *prinst, const char *str); //returns a tempstring containing str -char *PF_TempStr(progfuncs_t *prinst); //returns a tempstring which can be filled in with whatever junk you want. +int PR_Printf (const char *fmt, ...); +void PF_InitTempStrings(pubprogfuncs_t *prinst); +string_t PR_TempString(pubprogfuncs_t *prinst, const char *str); //returns a tempstring containing str +char *PF_TempStr(pubprogfuncs_t *prinst); //returns a tempstring which can be filled in with whatever junk you want. #define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. #define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_TempString(prinst, s)) //temp (static but cycle buffers) @@ -89,233 +89,274 @@ int MP_TranslateFTEtoDPCodes(int code); int MP_TranslateDPtoFTECodes(int code); //pr_cmds.c builtins that need to be moved to a common. -void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); -void QCBUILTIN PF_print (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_dprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_rint (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_floor (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ceil (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Tokenize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_tokenizebyseparator (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_tokenize_console (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ArgV (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_argv_start_index (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_argv_end_index (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_nextent (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Sin (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Cos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Sqrt (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bound (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strlen(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ftos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_fabs (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_vtos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_stof (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_stov (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Spawn (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_min (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_max (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_pow (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_asin (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_acos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_atan (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_atan2 (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_tan (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_sprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_random (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_fclose (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_normalize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_vlen (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_vectoyaw (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_vectoangles (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_rotatevectorsbyangles (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_rotatevectorsbymatrix (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_coredump (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_traceon (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_traceoff (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_eprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void search_close_progs(progfuncs_t *prinst, qboolean complain); -void QCBUILTIN PF_search_begin (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_search_end (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_search_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_search_getfilename (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_isfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_callfunction (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_writetofile(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_loadfromfile (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_loadfromdata (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_parseentitydata(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WasFreed (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_break (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_crc16 (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cvar_type (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_uri_escape (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_uri_unescape (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_uri_get (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_itos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_stoi (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_stoh (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_htos (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PR_fclose_progs (progfuncs_t *prinst); -char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_globals); -void PR_AutoCvarSetup(progfuncs_t *prinst); -void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var); -void QCBUILTIN PF_numentityfields (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_entityfieldname (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_entityfieldtype (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_putentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void VARGS PR_BIError(pubprogfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); +void QCBUILTIN PF_print (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_dprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_error (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_rint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_floor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ceil (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Tokenize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_tokenize_console (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ArgV (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_argv_start_index (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_argv_end_index (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_FindString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_nextent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Sin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Cos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Sqrt (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strlen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ftos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_fabs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_vtos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_etos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_stof (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_mod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_stov (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_dupstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_forgetstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Spawn (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_min (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_max (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_registercvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_pow (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_asin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_acos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_atan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_atan2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_tan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_localcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_sprintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_fclose (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_fputs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_fgets (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_normalize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_rotatevectorsbymatrix (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_coredump (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_traceon (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_traceoff (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_eprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_search_end (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_search_getsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_isfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_callfunction (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_writetofile(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_loadfromfile (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_loadfromdata (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_parseentitydata(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WasFreed (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_break (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_crc16 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cvar_type (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_uri_escape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_uri_unescape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_itos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_stoi (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_stoh (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_htos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PR_fclose_progs (pubprogfuncs_t *prinst); +char *PF_VarString (pubprogfuncs_t *prinst, int first, struct globalvars_s *pr_globals); +void PR_AutoCvarSetup(pubprogfuncs_t *prinst); +void PR_AutoCvar(pubprogfuncs_t *prinst, cvar_t *var); +void QCBUILTIN PF_numentityfields (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_entityfieldname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_entityfieldtype (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfaceclippedpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacenumtriangles(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacetriangle(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getsurfacepointattribute(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_set_bone_world (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_build (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_get_numbones (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_get_bonename (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_get_boneparent (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_find_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_get_boneabs (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_mul_bone (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_mul_bones (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_copybones (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skel_delete (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_frametoname (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skintoname (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_frameforname (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_frameduration (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_skinforname (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void skel_lookup(progfuncs_t *prinst, int skelidx, framestate_t *out); -void skel_dodelete(progfuncs_t *prinst); -void skel_reset(progfuncs_t *prinst); -void QCBUILTIN PF_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_gettagindex (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_touchtriggers(progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacepoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacenormal(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacetexture(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacenearpoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfaceclippedpoint(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacenumtriangles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacetriangle(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_getsurfacepointattribute(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + +#ifndef SKELETALOBJECTS + #define PF_gettaginfo PF_Fixme + #define PF_gettagindex PF_Fixme + #define PF_skintoname PF_Fixme + #define PF_frametoname PF_Fixme + #define PF_skel_set_bone_world PF_Fixme + #define PF_skel_mmap PF_Fixme + #define PF_skel_ragedit PF_Fixme + #define PF_frameduration PF_Fixme + #define PF_frameforname PF_Fixme + #define PF_skel_delete PF_Fixme + #define PF_skel_copybones PF_Fixme + #define PF_skel_mul_bones PF_Fixme + #define PF_skel_mul_bone PF_Fixme + #define PF_skel_set_bone PF_Fixme + #define PF_skel_get_boneabs PF_Fixme + #define PF_skel_get_bonerel PF_Fixme + #define PF_skel_find_bone PF_Fixme + #define PF_skel_get_boneparent PF_Fixme + #define PF_skel_get_bonename PF_Fixme + #define PF_skel_get_numbones PF_Fixme + #define PF_skel_build PF_Fixme + #define PF_skel_create PF_Fixme + #define PF_skinforname PF_Fixme +#else + void QCBUILTIN PF_skel_set_bone_world (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_mmap(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_ragedit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_build (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_get_numbones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_get_bonename (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_get_boneparent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_find_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_get_bonerel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_get_boneabs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_set_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_mul_bone (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_mul_bones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_copybones (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skel_delete (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_frametoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skintoname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_frameforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_frameduration (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_gettaginfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +#endif +#if defined(SKELETALOBJECTS) || defined(RAGDOLL) + void skel_lookup(pubprogfuncs_t *prinst, int skelidx, framestate_t *out); + void skel_dodelete(pubprogfuncs_t *prinst); + void skel_reset(pubprogfuncs_t *prinst); +#endif +void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); //pr_cmds.c builtins that need to be moved to a common. -void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); -void QCBUILTIN PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ArgC (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_randomvec (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strreplace (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strireplace (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_randomvector (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void VARGS PR_BIError(pubprogfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); +void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cvar_setf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ArgC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_randomvec (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strreplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strireplace (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_randomvector (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_fopen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_FindFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_FindFlags (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_findchainflags (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bitshift(progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_FindString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_FindFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_FindFlags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bitshift(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_Abort(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_externcall (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_externrefcall (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_externvalue (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_externset (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_instr (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Abort(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_externrefcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_externvalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_externset (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_instr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strtolower (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strtoupper (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strftime (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strlennocol (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strdecolorize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strtolower (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strtoupper (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strstrofs (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_str2chr (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_chr2str (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strconv (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_infoadd (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_infoget (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strncmp (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strcasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strncasecmp (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_strpad (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_chr2str (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strconv (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_infoadd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_infoget (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strcasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_edict_for_num (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_num_for_edict (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cvar_defstring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cvar_description (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_digest_hex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + +void QCBUILTIN PF_edict_for_num (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_num_for_edict (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cvar_description (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); //these functions are from pr_menu.dat -void QCBUILTIN PF_CL_is_cached_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_precache_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_free_pic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_stringwidth (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_is_cached_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_precache_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_free_pic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawcharacter (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawcolouredstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawfill (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawsetcliparea (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawresetcliparea (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawgetimagesize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_stringwidth (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_drawsubpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_findfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +#if defined(CSQC_DAT) && !defined(SERVERONLY) +void QCBUILTIN PF_R_PolygonBegin(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_R_PolygonVertex(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +#else +#define PF_R_PolygonBegin PF_Fixme +#define PF_R_PolygonVertex PF_Fixme +#define PF_R_PolygonEnd PF_Fixme +#endif -void QCBUILTIN PF_cl_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_getmousepos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cl_keynumtostring (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cl_findkeysforcommand (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cl_stringtokeynum(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_cl_getkeybind (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_keynumtostring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void search_close_progs(progfuncs_t *prinst, qboolean complain); +void search_close_progs(pubprogfuncs_t *prinst, qboolean complain); -void QCBUILTIN PF_buf_create (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_del (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_getsize (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_copy (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_sort (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_implode (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bufstr_get (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bufstr_set (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_create (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_del (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_getsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_copy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_sort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_implode (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bufstr_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bufstr_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bufstr_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_bufstr_free (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_buf_cvarlist (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_memalloc (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_memfree (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_memcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_memset (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_memalloc (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_memfree (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_memcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_memset (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_calltimeofday (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_fclose_progs (progfuncs_t *prinst); -int QCEditor (progfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); +int QDECL QCEditor (pubprogfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); +void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored); @@ -325,33 +366,33 @@ int QCEditor (progfuncs_t *prinst, char *filename, int line, int statement, int #ifdef VM_Q1 model_t *SVPR_GetCModel(world_t *w, int modelindex); void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o); -void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_multicast (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_changelevel (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_multicast (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_svtraceline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_applylightstyle(int style, char *val, int col); void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuation); -void QCBUILTIN PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_logfrag (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ExecuteCommand (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_setspawnparms (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_ForceInfoKey(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_precache_vwep_model(progfuncs_t *prinst, struct globalvars_s *pr_globals); -int PF_checkclient_Internal (progfuncs_t *prinst); -void PF_precache_sound_Internal (progfuncs_t *prinst, char *s); -int PF_precache_model_Internal (progfuncs_t *prinst, char *s, qboolean queryonly); -void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m); +void QCBUILTIN PF_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ExecuteCommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_setspawnparms (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_ForceInfoKey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_precache_vwep_model(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +int PF_checkclient_Internal (pubprogfuncs_t *prinst); +void PF_precache_sound_Internal (pubprogfuncs_t *prinst, char *s); +int PF_precache_model_Internal (pubprogfuncs_t *prinst, char *s, qboolean queryonly); +void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, char *m); char *PF_infokey_Internal (int entnum, char *value); void PF_centerprint_Internal (int entnum, qboolean plaque, char *s); void PF_WriteString_Internal (int target, char *str); -pbool ED_CanFree (edict_t *ed); +pbool QDECL ED_CanFree (edict_t *ed); #endif #define MOVETYPE_NONE 0 // never moves @@ -384,6 +425,7 @@ pbool ED_CanFree (edict_t *ed); #define SOLID_PHYSICS_BOX 32 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) #define SOLID_PHYSICS_SPHERE 33 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) #define SOLID_PHYSICS_CAPSULE 34 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) +#define SOLID_PHYSICS_CYLINDER 35 #define JOINTTYPE_POINT 1 @@ -397,6 +439,11 @@ pbool ED_CanFree (edict_t *ed); #define DAMAGE_YES 1 #define DAMAGE_AIM 2 +#define CLIENTTYPE_DISCONNECTED 0 +#define CLIENTTYPE_REAL 1 +#define CLIENTTYPE_BOT 2 +#define CLIENTTYPE_NOTACLIENT 3 + //shared constants typedef enum { diff --git a/engine/common/protocol.h b/engine/common/protocol.h index efcc180b..33b6c29b 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -243,7 +243,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define svcfte_modellistshort 60 // [strings] #endif -#define svc_ftesetclientpersist 61 //ushort DATA +//#define svc_ftesetclientpersist 61 //ushort DATA #define svc_setportalstate 62 @@ -517,12 +517,13 @@ enum clcq2_ops_e #endif -//first byte contains the stuff that's most likely to change constantly*/ +//FTE Replacement Deltas +//first byte contains the stuff that's most likely to change constantly #define UF_FRAME (1u<<0) #define UF_ORIGINXY (1u<<1) #define UF_ORIGINZ (1u<<2) -#define UF_ANGLESXZ (1u<<4) -#define UF_ANGLESY (1u<<3) +#define UF_ANGLESXZ (1u<<3) +#define UF_ANGLESY (1u<<4) #define UF_EFFECTS (1u<<5) #define UF_PREDINFO (1u<<6) /*ent is predicted, probably a player*/ #define UF_EXTEND1 (1u<<7) @@ -548,7 +549,7 @@ enum clcq2_ops_e #define UF_EXTEND3 (1u<<23) #define UF_COLORMOD (1u<<24) -#define UF_GLOWMOD (1u<<25) +#define UF_GLOW (1u<<25) #define UF_FATNESS (1u<<26) #define UF_MODELINDEX2 (1u<<27) #define UF_GRAVITYDIR (1u<<28) @@ -674,6 +675,12 @@ enum clcq2_ops_e #define DEFAULT_SOUND_PACKET_VOLUME 255 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 +//baseline flags +#define FITZ_B_LARGEMODEL (1<<0) +#define FITZ_B_LARGEFRAME (1<<1) +#define FITZ_B_ALPHA (1<<2) +#define RMQFITZ_B_SCALE (1<<3) + #define DEFAULT_VIEWHEIGHT 22 @@ -701,17 +708,19 @@ enum { TE_LAVASPLASH = 10, TE_TELEPORT = 11, - TEQW_BLOOD = 12, - TENQ_EXPLOSION2 = 12, - TEQW_LIGHTNINGBLOOD = 13, - TENQ_BEAM = 13, + TEQW_BLOOD = 12, //implemented as a particle() in nq + TENQ_EXPLOSION2 = 12, //remapped to TEQW_EXPLOSION2 for qw + TEQW_LIGHTNINGBLOOD = 13, //implemented as a particle() in nq + TENQ_BEAM = 13, //remapped to TEQW_BEAM for qw #ifdef PEXT_TE_BULLET TE_BULLET = 14, TE_SUPERBULLET = 15, #endif - TE_RAILTRAIL = 17, + TE_RAILTRAIL = 17, //use the builtin, luke. + TEQW_BEAM = 18, //use the builtin, luke. + TEQW_EXPLOSION2 = 19, //use the builtin, luke. // hexen 2 TEH2_STREAM_LIGHTNING_SMALL = 24, @@ -796,10 +805,12 @@ enum { typedef struct entity_state_s { - unsigned short number; // edict index - unsigned short modelindex; + unsigned int number; // edict index - unsigned int flags; // nolerp, etc + unsigned short modelindex; + unsigned short inactiveflag; + +// unsigned int eflags; // nolerp, etc unsigned int effects; @@ -812,6 +823,7 @@ typedef struct entity_state_s { int renderfx; //q2 vec3_t old_origin; //q2/q3 + qbyte modelindex3; //q2 qbyte modelindex4; //q2 qbyte sound; //q2 @@ -824,8 +836,10 @@ typedef struct entity_state_s qbyte pmovetype; qbyte msec; unsigned short weaponframe; + short movement[3]; short velocity[3]; // 1/8th + unsigned char gravitydir[2]; //pitch/yaw, no roll unsigned short traileffectnum; } q1; @@ -1441,7 +1455,3 @@ typedef struct q1usercmd_s #define E5_EXTEND4 (1<<31) #define E5_ALLUNUSED (E5_UNUSED25|E5_UNUSED26|E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30) - -#define FITZB_LARGEMODEL (1<<0) // modelindex is short instead of byte -#define FITZB_LARGEFRAME (1<<1) // frame is short instead of byte -#define FITZB_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index f7ec367b..6a1c068f 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -1529,12 +1529,13 @@ static void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out) { //quad marks a full, independant quad int p; + float r; fragmentdecal_t dec; VectorCopy(center, dec.center); VectorCopy(normal, dec.normal); - dec.radius = size/2; dec.numtris = 0; + dec.radius = 0; VectorCopy(tangent1, dec.planenorm[0]); VectorNegate(tangent1, dec.planenorm[1]); @@ -1543,7 +1544,14 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen VectorCopy(dec.normal, dec.planenorm[4]); VectorNegate(dec.normal, dec.planenorm[5]); for (p = 0; p < 6; p++) - dec.planedist[p] = -(dec.radius - DotProduct(dec.center, dec.planenorm[p])); + { + r = sqrt(DotProduct(dec.planenorm[p], dec.planenorm[p])); + VectorScale(dec.planenorm[p], 1/r, dec.planenorm[p]); + r*= size/2; + if (r > dec.radius) + dec.radius = r; + dec.planedist[p] = -(r - DotProduct(dec.center, dec.planenorm[p])); + } dec.numplanes = 6; sh_shadowframe++; diff --git a/engine/common/world.h b/engine/common/world.h index 15459194..ce64b191 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -159,7 +159,7 @@ struct world_s unsigned int num_edicts; // increases towards MAX_EDICTS /*FTE_DEPRECATED*/ unsigned int edict_size; //still used in copyentity wedict_t *edicts; // can NOT be array indexed. - struct progfuncs_s *progs; + struct pubprogfuncs_s *progs; qboolean usesolidcorpse; //to disable SOLID_CORPSE when running hexen2 due to conflict. model_t *worldmodel; areanode_t areanodes[AREA_NODES]; @@ -189,6 +189,10 @@ struct world_s float *v_forward; float *v_right; float *v_up; + + //used by menu+csqc. + float *drawfont; + float *drawfontscale; } g; #ifdef USEODE @@ -208,10 +212,13 @@ void World_ODE_Start(world_t *world); void World_ODE_End(world_t *world); void World_ODE_Shutdown(void); -qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, float *mat, wedict_t *ed); -void World_ODE_RagDestroyBody(world_t *world, odebody_t *bodyptr); +qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, odebodyinfo_t *bodyinfo, float *mat, wedict_t *ent); +qboolean World_ODE_RagMatrixToBody(odebody_t *bodyptr, float *mat); void World_ODE_RagMatrixFromBody(world_t *world, odebody_t *bodyptr, float *mat); +void World_ODE_RagDestroyBody(world_t *world, odebody_t *bodyptr); void World_ODE_RagCreateJoint(world_t *world, odejoint_t *joint, odejointinfo_t *info, odebody_t *body1, odebody_t *body2, vec3_t aaa2[3]); +void World_ODE_RagEnableJoint(odejoint_t *joint, qboolean enabled); +void World_ODE_RagMatrixFromJoint(odejoint_t *joint, odejointinfo_t *info, float *mat); void World_ODE_RagDestroyJoint(world_t *world, odejoint_t *joint); #endif @@ -275,3 +282,5 @@ qboolean World_CheckBottom (world_t *world, wedict_t *ent); qboolean World_movestep (world_t *world, wedict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, void (*set_move_trace)(trace_t *trace, struct globalvars_s *pr_globals), struct globalvars_s *set_trace_globs); qboolean World_MoveToGoal (world_t *world, wedict_t *ent, float dist); +void WPhys_Init(void); +void World_Physics_Frame(world_t *w); diff --git a/engine/common/zone.c b/engine/common/zone.c index f7fb062c..a34e8ea4 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -29,9 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NOZONE #define NOCACHE -#ifdef _WIN32 -#define NOHIGH -#endif void Cache_FreeLow (int new_low_hunk); void Cache_FreeHigh (int new_high_hunk); @@ -1204,15 +1201,24 @@ typedef struct int size; // including sizeof(hunk_t), -1 = not allocated char name[8]; } hunk_t; +typedef struct hunkoverflow_s +{ + struct hunkoverflow_s *prev; + struct hunkoverflow_s *next; + hunk_t hunk[0]; +} hunkoverflow_t; -qbyte *hunk_base; -int hunk_size; +static hunkoverflow_t *hunkoverflow_first; +static hunkoverflow_t *hunkoverflow_top; -int hunk_low_used; -int hunk_high_used; +static qbyte *hunk_base; +static int hunk_size; -qboolean hunk_tempactive; -int hunk_tempmark; +static int hunk_low_used; +static int hunk_high_used; + +static qboolean hunk_tempactive; +static int hunk_tempmark; void R_FreeTextures (void); @@ -1363,10 +1369,8 @@ Hunk_AllocName */ void *Hunk_AllocName (int size, char *name) { -#ifdef NOHIGH int roundup; int roundupold; -#endif hunk_t *h; #ifdef PARANOID @@ -1375,39 +1379,54 @@ void *Hunk_AllocName (int size, char *name) if (size < 0) Sys_Error ("Hunk_Alloc: bad size: %i", size); - - size = sizeof(hunk_t) + HUNKDEBUG*2 + ((size+15)&~15); + + size = sizeof(hunk_t) + HUNKDEBUG*2 + size; + size = (size + 15) & ~15; -#ifndef _WIN32 if (hunk_size - hunk_low_used - hunk_high_used < size) -// Sys_Error ("Hunk_Alloc: failed on %i bytes",size); -#ifdef _WIN32 - Sys_Error ("Not enough RAM allocated on allocation of \"%s\". Try starting using \"-heapsize 16000\" on the QuakeWorld command line.", name); -#else - Sys_Error ("Not enough RAM allocated. Try starting using \"-mem %u\" on the QuakeWorld command line.", (hunk_size + 8*1024*1024) / 1024*1024); -#endif -#endif + { + Sys_Error ("Not enough RAM allocated. Try starting using \"-mem %u\" on the " FULLENGINENAME " command line.", (hunk_size + 8*1024*1024) / 1024*1024); + } h = (hunk_t *)(hunk_base + hunk_low_used); -#ifdef NOHIGH - - roundupold = hunk_low_used+sizeof(hunk_t); + roundupold = hunk_low_used; roundupold += 1024*128; roundupold &= ~(1024*128 - 1); - roundup = hunk_low_used+size+sizeof(hunk_t); + roundup = hunk_low_used+size; roundup += 1024*128; roundup &= ~(1024*128 - 1); - - if (!hunk_low_used || roundup != roundupold) - if (!VirtualAlloc (hunk_base, roundup, MEM_COMMIT, PAGE_READWRITE)) + if (hunkoverflow_top || roundup > hunk_size) { - char *buf; - Hunk_Print(true); - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); - Sys_Error ("VirtualCommit failed\nNot enough RAM allocated on allocation of \"%s\". Try starting using \"-heapsize %i\" on the QuakeWorld command line.", name, roundupold/512); + hunkoverflow_t *newtop; + newtop = BZ_Malloc(sizeof(*newtop)+size); + newtop->next = NULL; + if (!hunkoverflow_top) + { + hunkoverflow_top = hunkoverflow_first = newtop; + newtop->prev = NULL; + } + else + { + hunkoverflow_top->next = newtop; + newtop->prev = hunkoverflow_top; + hunkoverflow_top = newtop; + } + h = newtop->hunk; + } +#ifdef _WIN32 + else + { + if (!hunk_low_used || roundup != roundupold) + if (!VirtualAlloc (hunk_base, roundup, MEM_COMMIT, PAGE_READWRITE)) + { + char *buf; + Hunk_Print(true); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 0, NULL); + Sys_Error ("VirtualCommit failed\nNot enough RAM allocated on allocation of \"%s\". Try starting using \"-heapsize %i\" on the " FULLENGINENAME " command line.", name, roundupold/512); + } } #endif @@ -1453,10 +1472,26 @@ void Hunk_FreeToLowMark (int mark) { if (mark < 0 || mark > hunk_low_used) Sys_Error ("Hunk_FreeToLowMark: bad mark %i", mark); + + while(hunkoverflow_top) + { + if (mark > hunk_size) + { + hunkoverflow_t *top = hunkoverflow_top; + mark -= top->hunk[0].size; + hunk_low_used -= top->hunk[0].size; + hunkoverflow_top = top->prev; + hunkoverflow_top->next = NULL; + BZ_Free(top); + } + else + return; + } + memset (hunk_base + mark, 0, hunk_low_used - mark); hunk_low_used = mark; -#ifdef NOHIGH +#ifdef _WIN32 if (!VirtualAlloc (hunk_base, hunk_low_used+sizeof(hunk_t), MEM_COMMIT, PAGE_READWRITE)) { char *buf; @@ -1466,81 +1501,6 @@ void Hunk_FreeToLowMark (int mark) #endif } -int Hunk_HighMark (void) -{ - if (hunk_tempactive) - { - hunk_tempactive = false; - Hunk_FreeToHighMark (hunk_tempmark); - } - - return hunk_high_used; -} - -void Hunk_FreeToHighMark (int mark) -{ - if (hunk_tempactive) - { - hunk_tempactive = false; - Hunk_FreeToHighMark (hunk_tempmark); - } - if (mark < 0 || mark > hunk_high_used) - Sys_Error ("Hunk_FreeToHighMark: bad mark %i", mark); - memset (hunk_base + hunk_size - hunk_high_used, 0, hunk_high_used - mark); - hunk_high_used = mark; -} - - -/* -=================== -Hunk_HighAllocName -=================== -*/ -void *Hunk_HighAllocName (int size, char *name) -{ -#ifdef NOHIGH - Sys_Error("High hunk was disabled"); - return NULL; -#else - - hunk_t *h; - - if (size < 0) - Sys_Error ("Hunk_HighAllocName: bad size: %i", size); - - if (hunk_tempactive) - { - Hunk_FreeToHighMark (hunk_tempmark); - hunk_tempactive = false; - } - -#ifdef PARANOID - Hunk_Check (); -#endif - - size = sizeof(hunk_t) + ((size+15)&~15); - - if (hunk_size - hunk_low_used - hunk_high_used < size) - { - Con_Printf ("Hunk_HighAlloc: failed on %i bytes\n",size); - return NULL; - } - - hunk_high_used += size; - Cache_FreeHigh (hunk_high_used); - - h = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); - - memset (h, 0, size); - h->size = size; - h->sentinal = HUNK_SENTINAL; - Q_strncpyz (h->name, name, sizeof(h->name)); - - return (void *)(h+1); -#endif -} - - /* ================= Hunk_TempAlloc @@ -1549,7 +1509,6 @@ Return space from the top of the hunk clears old temp. ================= */ -#ifdef NOHIGH typedef struct hnktemps_s { struct hnktemps_s *next; #if TEMPDEBUG>0 @@ -1589,7 +1548,6 @@ void Hunk_TempFree(void) hnktemps = nt; } } -#endif //allocates without clearing previous temp. @@ -1597,7 +1555,6 @@ void Hunk_TempFree(void) void *Hunk_TempAllocMore (int size) { void *buf; -#ifdef NOHIGH #if TEMPDEBUG>0 hnktemps_t *nt; nt = (hnktemps_t*)malloc(size + sizeof(hnktemps_t) + TEMPDEBUG*2); @@ -1623,48 +1580,14 @@ void *Hunk_TempAllocMore (int size) memset(buf, 0, size); return buf; #endif -#else - - if (!hunk_tempactive) - return Hunk_TempAlloc(size); - - size = (size+15)&~15; - - hunk_tempactive = false; //so it doesn't wipe old temp. - buf = Hunk_HighAllocName (size, "mtmp"); - hunk_tempactive = true; - - return buf; -#endif } void *Hunk_TempAlloc (int size) { -#ifdef NOHIGH - Hunk_TempFree(); return Hunk_TempAllocMore(size); -#else - void *buf; - - size = (size+15)&~15; - - if (hunk_tempactive) - { - Hunk_FreeToHighMark (hunk_tempmark); - hunk_tempactive = false; - } - - hunk_tempmark = Hunk_HighMark (); - - buf = Hunk_HighAllocName (size, "temp"); - - hunk_tempactive = true; - - return buf; -#endif } /* @@ -1743,6 +1666,10 @@ void *Cache_Check(cache_user_t *c) void Cache_Flush(void) { + //this generically named function is hyjacked to flush models and sounds, as well as ragdolls etc +#ifdef RAGDOLL + rag_flushdolls(true); +#endif #ifndef SERVERONLY S_Purge(false); #endif @@ -1756,31 +1683,57 @@ void *Cache_Alloc (cache_user_t *c, int size, char *name) { void *buf; cache_system_t *nt; - - if (c->data) - Sys_Error ("Cache_Alloc: already allocated"); + qboolean resize = false; if (size <= 0) Sys_Error ("Cache_Alloc: size %i", size); -// size = (size + 15) & ~15; + if (c->data) + { + Sys_Error ("Cache_Alloc: %s already allocated", name); +/* + //resize instead + nt = c->data; + nt--; + nt = (cache_system_t*)BZ_Realloc(nt, size + sizeof(cache_system_t) + CACHEDEBUG*2); + + resize = true;*/ + } + else + { +// size = (size + 15) & ~15; + nt = (cache_system_t*)BZ_Malloc(size + sizeof(cache_system_t) + CACHEDEBUG*2); + } - nt = (cache_system_t*)BZ_Malloc(size + sizeof(cache_system_t) + CACHEDEBUG*2); if (!nt) Sys_Error("Cache_Alloc: failed on allocation of %i bytes", size); - nt->next = cache_head; - nt->prev = NULL; + + if (resize) + { + if (nt->next) + nt->next->prev = nt; + if (nt->prev) + nt->prev->next = nt; + else + cache_head = nt; + } + else + { + nt->next = cache_head; + nt->prev = NULL; + if (cache_head) + cache_head->prev = nt; + cache_head = nt; + } nt->user = c; nt->size = size; Q_strncpyz(nt->name, name, sizeof(nt->name)); - if (cache_head) - cache_head->prev = nt; - cache_head = nt; nt->user->fake = false; buf = (void *)(nt+1); memset(buf, sentinalkey, CACHEDEBUG); buf = (char*)buf+CACHEDEBUG; - memset(buf, 0, size); + if (!resize) + memset(buf, 0, size); memset((char *)buf+size, sentinalkey, CACHEDEBUG); c->data = buf; return c->data; @@ -2258,9 +2211,7 @@ void Memory_Init (void *buf, int size) void Memory_DeInit(void) { -#ifdef NOHIGH Hunk_TempFree(); -#endif Cache_Flush(); #ifdef MULTITHREAD diff --git a/engine/common/zone.h b/engine/common/zone.h index f3598f85..7a0d1273 100644 --- a/engine/common/zone.h +++ b/engine/common/zone.h @@ -121,15 +121,10 @@ void BZ_Free(void *ptr); void *Hunk_Alloc (int size); // returns 0 filled memory void *Hunk_AllocName (int size, char *name); -void *Hunk_HighAllocName (int size, char *name); - int Hunk_LowMark (void); void Hunk_FreeToLowMark (int mark); int Hunk_LowMemAvailable(void); -int Hunk_HighMark (void); -void Hunk_FreeToHighMark (int mark); - void *Hunk_TempAlloc (int size); void *Hunk_TempAllocMore (int size); //Don't clear old temp diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index 1e7483a5..3b771e83 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -33,7 +33,7 @@ Things to improve: -#define FORCESTATE +//#define FORCESTATE #ifdef FORCESTATE #pragma warningmsg("D3D9 FORCESTATE is active") @@ -156,6 +156,7 @@ typedef struct float curtime; const entity_t *curentity; const dlight_t *curdlight; + batch_t *curbatch, dummybatch; vec3_t curdlight_colours; shader_t *curshader; texnums_t *curtexnums; @@ -193,6 +194,10 @@ typedef struct unsigned int dyncol_offs; unsigned int dyncol_size; + IDirect3DVertexBuffer9 *dynnorm_buff; + unsigned int dynnorm_offs; + unsigned int dynnorm_size; + IDirect3DIndexBuffer9 *dynidx_buff; unsigned int dynidx_offs; unsigned int dynidx_size; @@ -449,6 +454,9 @@ void D3D9BE_Reset(qboolean before) IDirect3DVertexBuffer9_Release(shaderstate.dynst_buff[tmu]); shaderstate.dynst_buff[tmu] = NULL; } + if (shaderstate.dynnorm_buff) + IDirect3DVertexBuffer9_Release(shaderstate.dynnorm_buff); + shaderstate.dynnorm_buff = NULL; if (shaderstate.dyncol_buff) IDirect3DVertexBuffer9_Release(shaderstate.dyncol_buff); shaderstate.dyncol_buff = NULL; @@ -559,6 +567,7 @@ void D3D9BE_Reset(qboolean before) IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynxyz_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynxyz_buff, NULL); for (tmu = 0; tmu < D3D_VDEC_ST0; tmu++) IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynst_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynst_buff[tmu], NULL); + IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynnorm_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynnorm_buff, NULL); IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dyncol_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dyncol_buff, NULL); IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, shaderstate.dynidx_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFMT_QINDEX, D3DPOOL_DEFAULT, &shaderstate.dynidx_buff, NULL); @@ -599,6 +608,7 @@ void D3D9BE_Init(void) shaderstate.dynxyz_size = sizeof(vecV_t) * DYNVBUFFSIZE; shaderstate.dyncol_size = sizeof(byte_vec4_t) * DYNVBUFFSIZE; + shaderstate.dynnorm_size = sizeof(vec3_t)*3 * DYNVBUFFSIZE; shaderstate.dynst_size = sizeof(vec2_t) * DYNVBUFFSIZE; shaderstate.dynidx_size = sizeof(index_t) * DYNIBUFFSIZE; @@ -1680,9 +1690,9 @@ static void BE_ApplyUniforms(program_t *prog, int permu) case SP_M_VIEW: IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, r_refdef.m_view, 4); break; -// case SP_M_MODEL: -// IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, r_refdef.m_view, 4); -// break; + case SP_M_MODEL: + IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, shaderstate.m_model, 4); + break; case SP_V_EYEPOS: IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, r_origin, 1); @@ -1720,7 +1730,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu) Matrix4_Invert(shaderstate.m_model, inv); Matrix4x4_CM_Transform3(inv, shaderstate.curdlight->origin, t2); - IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, t2, 3); + IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, t2, 1); break; } @@ -1728,19 +1738,35 @@ static void BE_ApplyUniforms(program_t *prog, int permu) IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, &shaderstate.curdlight->radius, 1); break; case SP_LIGHTCOLOUR: - IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, shaderstate.curdlight_colours, 3); + IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, shaderstate.curdlight_colours, 1); + break; + + case SP_E_L_DIR: + IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, shaderstate.curentity->light_dir, 1); + break; + case SP_E_L_MUL: + IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, shaderstate.curentity->light_range, 1); + break; + case SP_E_L_AMBIENT: + IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, shaderstate.curentity->light_avg, 1); break; case SP_E_COLOURS: + IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, shaderstate.curentity->shaderRGBAf, 1); + break; case SP_E_COLOURSIDENT: + if (shaderstate.flags & BEF_FORCECOLOURMOD) + { + vec4_t tmp = {1, 1, 1, shaderstate.curentity->shaderRGBAf[3]}; + IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, tmp, 1); + } + else + IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, shaderstate.curentity->shaderRGBAf, 1); + break; case SP_E_TOPCOLOURS: case SP_E_BOTTOMCOLOURS: - case SP_E_L_DIR: - case SP_E_L_MUL: - case SP_E_L_AMBIENT: case SP_M_ENTBONES: - case SP_M_MODEL: case SP_M_MODELVIEW: case SP_RENDERTEXTURESCALE: @@ -1766,6 +1792,13 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i program_t *p = s->prog; + if (shaderstate.batchvbo && shaderstate.batchvbo->numbones) + { + if (p->permu[perm|PERMUTATION_SKELETAL].handle.glsl) + perm |= PERMUTATION_SKELETAL; + else + return; + } if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.hlsl.vert) perm |= PERMUTATION_BUMPMAP; if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.hlsl.vert) @@ -1774,8 +1807,12 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i perm |= PERMUTATION_UPPERLOWER; if (r_refdef.gfog_rgbd[3] && p->permu[perm|PERMUTATION_FOG].handle.hlsl.vert) perm |= PERMUTATION_FOG; -// if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert) -// perm |= PERMUTATION_OFFSET; + if (p->permu[perm|PERMUTATION_FRAMEBLEND].handle.hlsl.vert && shaderstate.batchvbo && shaderstate.batchvbo->coord2.d3d.buff) + perm |= PERMUTATION_FRAMEBLEND; + if (p->permu[perm|PERMUTATION_DELUXE].handle.hlsl.vert && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe) + perm |= PERMUTATION_DELUXE; + if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].handle.hlsl.vert) + perm |= PERMUTATION_LIGHTSTYLES; BE_ApplyUniforms(p, perm); @@ -1885,18 +1922,44 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMS, shaderstate.batchvbo->svector.d3d.buff, shaderstate.batchvbo->svector.d3d.offs, sizeof(vbovdata_t))); d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMT, shaderstate.batchvbo->tvector.d3d.buff, shaderstate.batchvbo->tvector.d3d.offs, sizeof(vbovdata_t))); } - else + else if (shaderstate.meshlist[0]->normals_array && shaderstate.meshlist[0]->snormals_array && shaderstate.meshlist[0]->tnormals_array) { - /*FIXME*/ - vdec &= ~D3D_VDEC_NORM; + int mno; + void *map; + mesh_t *m; + int tv = vertcount; + + allocvertexbuffer(shaderstate.dynnorm_buff, shaderstate.dynnorm_size, &shaderstate.dynnorm_offs, &map, vertcount*3*sizeof(vec3_t)); + for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++) + { + float *dest; + m = shaderstate.meshlist[mno]; + + dest = (float*)((char*)map+vertcount*sizeof(vec3_t)); + memcpy(dest, m->normals_array, m->numvertexes*sizeof(vec3_t)); + + dest += tv*3; + memcpy(dest, m->snormals_array, m->numvertexes*sizeof(vec3_t)); + + dest += tv*3; + memcpy(dest, m->tnormals_array, m->numvertexes*sizeof(vec3_t)); + + vertcount += m->numvertexes; + } + d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynnorm_buff)); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORM, shaderstate.dynnorm_buff, shaderstate.dynnorm_offs - vertcount*sizeof(vec3_t)*3, sizeof(vec3_t))); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMS, shaderstate.dynnorm_buff, shaderstate.dynnorm_offs - vertcount*sizeof(vec3_t)*2, sizeof(vec3_t))); + d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMT, shaderstate.dynnorm_buff, shaderstate.dynnorm_offs - vertcount*sizeof(vec3_t)*1, sizeof(vec3_t))); } + else + vdec &= ~D3D_VDEC_NORM; } /*bone weights+indexes*/ if (vdec & D3D_VDEC_SKEL) { /*FIXME*/ - vdec &= ~D3D_VDEC_NORM; + vdec &= ~D3D_VDEC_SKEL; } if (vdec != shaderstate.curvertdecl) @@ -2599,9 +2662,9 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod) Matrix4x4_CM_NewRotation(90, 1, 0, 0); Matrix4_Multiply(iv, m, mv); Matrix4_Multiply(mv, Matrix4x4_CM_NewRotation(-90, 1, 0, 0), iv); - Matrix4_Multiply(iv, Matrix4x4_CM_NewRotation(90, 0, 0, 1), mv); + Matrix4_Multiply(iv, Matrix4x4_CM_NewRotation(90, 0, 0, 1), m); - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)mv); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m); } else { @@ -2630,6 +2693,7 @@ void D3D9BE_SubmitBatch(batch_t *batch) shaderstate.meshlist = batch->mesh + batch->firstmesh; shaderstate.curshader = batch->shader; shaderstate.curtexnums = batch->skin; + shaderstate.curbatch = batch; shaderstate.flags = batch->flags; if (batch->lightmap[0] < 0) shaderstate.curlightmap = r_nulltex; @@ -2645,6 +2709,7 @@ void D3D9BE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vb shaderstate.curshader = shader; shaderstate.curtexnums = texnums; shaderstate.curlightmap = r_nulltex; + shaderstate.curbatch = &shaderstate.dummybatch; shaderstate.meshlist = meshlist; shaderstate.nummeshes = nummeshes; shaderstate.flags = beflags; diff --git a/engine/d3d/d3d_shader.c b/engine/d3d/d3d_shader.c index 49f50093..8f8f2d13 100644 --- a/engine/d3d/d3d_shader.c +++ b/engine/d3d/d3d_shader.c @@ -167,8 +167,9 @@ qboolean D3D9Shader_CreateProgram (program_t *prog, char *sname, int permu, char if (pD3DXCompileShader) { int consts; - for (consts = 2; precompilerconstants[consts]; consts++) + for (consts = 0; precompilerconstants[consts]; consts++) ; + consts+=2; if (consts >= sizeof(defines) / sizeof(defines[0])) return success; diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 5dc0223f..ff75cbe6 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -1091,9 +1091,6 @@ static void (D3D9_SCR_UpdateScreen) (void) Media_RecordFrame(); #endif - if (Key_MouseShouldBeFree()) - SCR_DrawCursor(0); - RSpeedEnd(RSPEED_TOTALREFRESH); RSpeedShow(); diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index 1794809a..17d635f9 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -1159,8 +1159,6 @@ static void (D3D11_SCR_UpdateScreen) (void) V_UpdatePalette (false); - if (Key_MouseShouldBeFree()) - SCR_DrawCursor(0); #if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif diff --git a/engine/dotnet2005/botlib.vcproj b/engine/dotnet2005/botlib.vcproj index bc698e8f..17179747 100644 --- a/engine/dotnet2005/botlib.vcproj +++ b/engine/dotnet2005/botlib.vcproj @@ -40,7 +40,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include" - PreprocessorDefinitions="BOTLIB" + PreprocessorDefinitions="BOTLIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" MinimalRebuild="true" BasicRuntimeChecks="3" SmallerTypeCheck="true" @@ -104,7 +104,7 @@ Name="VCCLCompilerTool" FavorSizeOrSpeed="0" OmitFramePointers="true" - PreprocessorDefinitions="BOTLIB" + PreprocessorDefinitions="BOTLIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" RuntimeLibrary="0" WarningLevel="3" Detect64BitPortabilityProblems="true" diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index b53e8944..6abbbdc9 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -71,8 +71,8 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|x64.ActiveCfg = Debug Dedicated Server|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|x64.Build.0 = Debug Dedicated Server|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|Win32.ActiveCfg = MDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.ActiveCfg = Debug Dedicated Server|x64 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.Build.0 = Debug Dedicated Server|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.ActiveCfg = D3DRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.Build.0 = D3DRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.ActiveCfg = GLDebug|x64 @@ -95,12 +95,12 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MinGLRelease|x64.Build.0 = MinGLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|Win32.ActiveCfg = MRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|Win32.Build.0 = MRelease|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|x64.ActiveCfg = MRelease|x64 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|x64.Build.0 = MRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|x64.ActiveCfg = MinGLDebug|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MRelease|x64.Build.0 = MinGLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|Win32.ActiveCfg = Release Dedicated Server|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|Win32.Build.0 = Release Dedicated Server|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.ActiveCfg = Release Dedicated Server|x64 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.Build.0 = Release Dedicated Server|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.ActiveCfg = GLRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.ActiveCfg = MRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.Build.0 = MRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|x64.ActiveCfg = GLRelease|x64 @@ -137,7 +137,7 @@ Global {F384725A-62D4-4063-9941-6D8D2D6C2A47}.Release|x64.Build.0 = Release Dedicated Server_SDL|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.Build.0 = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.ActiveCfg = GLDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DRelease|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|Win32.ActiveCfg = GLDebug|Win32 @@ -145,21 +145,18 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|Win32.ActiveCfg = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MDebug|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.ActiveCfg = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLDebug|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|Win32.Build.0 = GLRelease|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|x64.ActiveCfg = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MinGLRelease|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.MRelease|x64.ActiveCfg = GLDebug|Win32 @@ -170,14 +167,15 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.Build.0 = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.ActiveCfg = GLDebug|Win32 {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|Win32.ActiveCfg = Release - {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Debug + {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|x64.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DRelease|x64.Build.0 = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug Dedicated Server|Win32.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug Dedicated Server|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug|Win32.ActiveCfg = Debug - {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug|x64.ActiveCfg = Debug + {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug|x64.ActiveCfg = Release + {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug|x64.Build.0 = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.GLDebug|Win32.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.GLDebug|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.GLRelease|Win32.ActiveCfg = Release @@ -187,16 +185,16 @@ Global {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MinGLDebug|Win32.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MinGLDebug|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MinGLRelease|Win32.ActiveCfg = Release - {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MinGLRelease|x64.ActiveCfg = Release + {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MinGLRelease|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MRelease|Win32.ActiveCfg = Release - {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MRelease|x64.ActiveCfg = Release + {E0EE8B50-3A75-42A9-B80A-787675979B0C}.MRelease|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release Dedicated Server|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release Dedicated Server|x64.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|x64.ActiveCfg = Release {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|Win32.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|Win32.Build.0 = Release|Win32 - {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DDebug|x64.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DRelease|Win32.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DRelease|Win32.Build.0 = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.D3DRelease|x64.ActiveCfg = Release|Win32 @@ -205,7 +203,7 @@ Global {0018E098-B12A-4E4D-9B22-6772DA287080}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Debug|Win32.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Debug|Win32.Build.0 = Debug|Win32 - {0018E098-B12A-4E4D-9B22-6772DA287080}.Debug|x64.ActiveCfg = Debug|Win32 + {0018E098-B12A-4E4D-9B22-6772DA287080}.Debug|x64.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.GLDebug|Win32.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.GLDebug|Win32.Build.0 = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.GLDebug|x64.ActiveCfg = Debug|Win32 @@ -218,10 +216,10 @@ Global {0018E098-B12A-4E4D-9B22-6772DA287080}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.MinGLRelease|Win32.ActiveCfg = Release|Win32 - {0018E098-B12A-4E4D-9B22-6772DA287080}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {0018E098-B12A-4E4D-9B22-6772DA287080}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.MRelease|Win32.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.MRelease|Win32.Build.0 = Release|Win32 - {0018E098-B12A-4E4D-9B22-6772DA287080}.MRelease|x64.ActiveCfg = Release|Win32 + {0018E098-B12A-4E4D-9B22-6772DA287080}.MRelease|x64.ActiveCfg = Debug|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -229,7 +227,7 @@ Global {0018E098-B12A-4E4D-9B22-6772DA287080}.Release|Win32.Build.0 = Release|Win32 {0018E098-B12A-4E4D-9B22-6772DA287080}.Release|x64.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|Win32.ActiveCfg = Release|Win32 - {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.D3DDebug|x64.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|Win32.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.D3DRelease|x64.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 @@ -237,9 +235,8 @@ Global {2866F783-6B44-4655-A38D-D53874037454}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Debug|Win32.Build.0 = Debug|Win32 - {2866F783-6B44-4655-A38D-D53874037454}.Debug|x64.ActiveCfg = Debug|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.Debug|x64.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.ActiveCfg = Debug|Win32 - {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|Win32.Build.0 = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.GLDebug|x64.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.GLRelease|Win32.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.GLRelease|x64.ActiveCfg = Release|Win32 @@ -251,10 +248,10 @@ Global {2866F783-6B44-4655-A38D-D53874037454}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|Win32.Build.0 = Release|Win32 - {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.MRelease|Win32.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.MRelease|Win32.Build.0 = Release|Win32 - {2866F783-6B44-4655-A38D-D53874037454}.MRelease|x64.ActiveCfg = Release|Win32 + {2866F783-6B44-4655-A38D-D53874037454}.MRelease|x64.ActiveCfg = Debug|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -262,7 +259,7 @@ Global {2866F783-6B44-4655-A38D-D53874037454}.Release|Win32.Build.0 = Release|Win32 {2866F783-6B44-4655-A38D-D53874037454}.Release|x64.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|Win32.ActiveCfg = Release|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DDebug|x64.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|Win32.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.D3DRelease|x64.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 @@ -270,24 +267,21 @@ Global {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|Win32.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|Win32.Build.0 = Debug|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|x64.ActiveCfg = Debug|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Debug|x64.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|Win32.ActiveCfg = Debug|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|Win32.Build.0 = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLDebug|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLRelease|Win32.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.GLRelease|x64.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|Win32.ActiveCfg = Debug|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|Win32.Build.0 = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MDebug|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|Win32.Build.0 = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|Win32.Build.0 = Release|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|Win32.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|Win32.Build.0 = Release|Win32 - {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|x64.ActiveCfg = Release|Win32 + {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.MRelease|x64.ActiveCfg = Debug|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -295,13 +289,13 @@ Global {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|Win32.Build.0 = Release|Win32 {62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.ActiveCfg = Release|Win32 - {4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.ActiveCfg = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|x64.ActiveCfg = Debug|Win32 + {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.ActiveCfg = Release|Win32 @@ -311,15 +305,15 @@ Global {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|Win32.ActiveCfg = Release|Win32 - {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|Win32.ActiveCfg = Release|Win32 - {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|x64.ActiveCfg = Release|Win32 + {4735677B-6D5A-4BE6-A945-CB32A7282F56}.MRelease|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32A7282F56}.Release|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|Win32.ActiveCfg = Release|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DDebug|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 @@ -327,22 +321,21 @@ Global {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.Build.0 = Debug|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|x64.ActiveCfg = Debug|Win32 + {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|Win32.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MDebug|Win32.ActiveCfg = Debug|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.MDebug|Win32.Build.0 = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MDebug|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLRelease|Win32.Build.0 = Release|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {873CCE24-3549-49D4-A4B4-653F91B1532A}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.MRelease|Win32.Build.0 = Release|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.MRelease|x64.ActiveCfg = Release|Win32 + {873CCE24-3549-49D4-A4B4-653F91B1532A}.MRelease|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -351,7 +344,7 @@ Global {873CCE24-3549-49D4-A4B4-653F91B1532A}.Release|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|Win32.Build.0 = Release|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DDebug|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|Win32.Build.0 = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|x64.ActiveCfg = Release|Win32 @@ -360,23 +353,21 @@ Global {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.Build.0 = Debug|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|x64.ActiveCfg = Debug|Win32 + {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|Win32.ActiveCfg = Debug|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|Win32.Build.0 = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MDebug|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|Win32.Build.0 = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|Win32.Build.0 = Release|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {4877586B-E85B-4DF8-BCCE-59D31514D240}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|Win32.Build.0 = Release|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|x64.ActiveCfg = Release|Win32 + {4877586B-E85B-4DF8-BCCE-59D31514D240}.MRelease|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -385,7 +376,7 @@ Global {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|x64.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|Win32.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|Win32.Build.0 = Debug|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|x64.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|Win32.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|Win32.Build.0 = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|x64.ActiveCfg = Release|Win32 @@ -394,24 +385,22 @@ Global {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.Build.0 = Debug|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|x64.ActiveCfg = Debug|Win32 + {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|x64.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLDebug|Win32.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLDebug|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|Win32.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|Win32.Build.0 = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|x64.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|Win32.ActiveCfg = Debug|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|Win32.Build.0 = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|Win32.Build.0 = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|Win32.Build.0 = Release|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|Win32.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|Win32.Build.0 = Release|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|x64.ActiveCfg = Release|Win32 + {32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 @@ -420,7 +409,7 @@ Global {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DDebug|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DDebug|Win32.Build.0 = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DDebug|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DRelease|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DRelease|Win32.Build.0 = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DRelease|x64.ActiveCfg = Release|Win32 @@ -429,25 +418,22 @@ Global {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|Win32.Build.0 = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|x64.ActiveCfg = Debug|Win32 + {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLDebug|Win32.ActiveCfg = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLDebug|Win32.Build.0 = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLDebug|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLRelease|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLRelease|Win32.Build.0 = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.GLRelease|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MDebug|Win32.ActiveCfg = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MDebug|Win32.Build.0 = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MDebug|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLDebug|Win32.Build.0 = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLDebug|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLRelease|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLRelease|Win32.Build.0 = Release|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MinGLRelease|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MRelease|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MRelease|Win32.Build.0 = Release|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MRelease|x64.ActiveCfg = Release|Win32 + {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.MRelease|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Release Dedicated Server|Win32.Build.0 = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index cc6fc9ad..f824181d 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -16206,2622 +16206,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -34401,6 +31785,2202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - @@ -34595,22 +34171,6 @@ RelativePath="..\libs\dxsdk7\include\dsound.h" > - - - - - - - - @@ -34643,14 +34203,6 @@ RelativePath="..\gl\glsupp.h" > - - - - @@ -34751,30 +34303,10 @@ RelativePath="..\common\pr_common.h" > - - - - - - - - - - @@ -34791,14 +34323,6 @@ RelativePath="..\server\q3g_public.h" > - - - - diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 7e65f6b6..e7aeb744 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -191,6 +191,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e { galiasskin_t *skins; shader_t *shader; + skin_t *plskin; int frame; unsigned int subframe; extern int cl_playerindex; //so I don't have to strcmp @@ -218,22 +219,19 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e if (!gl_nocolors.ival || forced) { - if (e->scoreboard) + if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS) { - if (!e->scoreboard->skin) - Skin_Find(e->scoreboard); - tc = e->scoreboard->ttopcolor; - bc = e->scoreboard->tbottomcolor; - pc = e->scoreboard->h2playerclass; + if (!cl.players[e->playerindex].skin) + Skin_Find(&cl.players[e->playerindex]); + plskin = cl.players[e->playerindex].skin; } else - { - tc = 1; - bc = 1; - pc = 0; - } + plskin = NULL; + tc = e->topcolour; + bc = e->bottomcolour; + pc = e->h2playerclass; - if (forced || tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin)) + if (forced || tc != 1 || bc != 1 || plskin) { int inwidth, inheight; int tinwidth, tinheight; @@ -242,9 +240,9 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e galiascolourmapped_t *cm; char hashname[512]; - if (e->scoreboard && e->scoreboard->skin) + if (plskin) { - snprintf(hashname, sizeof(hashname), "%s$%s$%i", model->name, e->scoreboard->skin->name, surfnum); + snprintf(hashname, sizeof(hashname), "%s$%s$%i", model->name, plskin->name, surfnum); skinname = hashname; } else if (surfnum) @@ -314,6 +312,8 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e cm->subframe = subframe; cm->texnum.fullbright = r_nulltex; cm->texnum.base = r_nulltex; + cm->texnum.bump = r_nulltex; + cm->texnum.specular = r_nulltex; cm->texnum.loweroverlay = r_nulltex; cm->texnum.upperoverlay = r_nulltex; @@ -321,58 +321,58 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e { //model has no shaders, so just the skin directly shader = R_RegisterSkin(skinname, NULL); - if (e->scoreboard && e->scoreboard->skin) + if (plskin) { if (cls.protocol == CP_QUAKE2) { - original = Skin_Cache32(e->scoreboard->skin); + original = Skin_Cache32(plskin); if (original) { - inwidth = e->scoreboard->skin->width; - inheight = e->scoreboard->skin->height; - cm->texnum.base = R_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, IF_NOALPHA|IF_NOGAMMA); + inwidth = plskin->width; + inheight = plskin->height; + cm->texnum.base = R_LoadTexture32(plskin->name, inwidth, inheight, (unsigned int*)original, IF_NOALPHA|IF_NOGAMMA); return shader; } } else { - original = Skin_Cache8(e->scoreboard->skin); + original = Skin_Cache8(plskin); if (original) { - inwidth = e->scoreboard->skin->width; - inheight = e->scoreboard->skin->height; - cm->texnum.base = R_LoadTexture8(e->scoreboard->skin->name, inwidth, inheight, original, IF_NOALPHA|IF_NOGAMMA, 1); + inwidth = plskin->width; + inheight = plskin->height; + cm->texnum.base = R_LoadTexture8(plskin->name, inwidth, inheight, original, IF_NOALPHA|IF_NOGAMMA, 1); return shader; } } - if (TEXVALID(e->scoreboard->skin->tex_base)) + if (TEXVALID(plskin->tex_base)) { - cm->texnum.loweroverlay = e->scoreboard->skin->tex_lower; - cm->texnum.upperoverlay = e->scoreboard->skin->tex_upper; - cm->texnum.base = e->scoreboard->skin->tex_base; + cm->texnum.loweroverlay = plskin->tex_lower; + cm->texnum.upperoverlay = plskin->tex_upper; + cm->texnum.base = plskin->tex_base; return shader; } - cm->texnum.base = R_LoadHiResTexture(e->scoreboard->skin->name, "skins", IF_NOALPHA); + cm->texnum.base = R_LoadHiResTexture(plskin->name, "skins", IF_NOALPHA); return shader; } return shader; } cm->texnum.bump = shader->defaulttextures.bump; //can't colour bumpmapping - if (cls.protocol != CP_QUAKE2 && ((model==cl.model_precache[cl_playerindex] || model==cl.model_precache_vwep[0]) && e->scoreboard && e->scoreboard->skin)) + if (cls.protocol != CP_QUAKE2 && ((model==cl.model_precache[cl_playerindex] || model==cl.model_precache_vwep[0]) && plskin)) { /*q1 only reskins the player model, not gibbed heads (which have the same colourmap)*/ - original = Skin_Cache8(e->scoreboard->skin); - inwidth = e->scoreboard->skin->width; - inheight = e->scoreboard->skin->height; + original = Skin_Cache8(plskin); + inwidth = plskin->width; + inheight = plskin->height; - if (!original && TEXVALID(e->scoreboard->skin->tex_base)) + if (!original && TEXVALID(plskin->tex_base)) { - cm->texnum.loweroverlay = e->scoreboard->skin->tex_lower; - cm->texnum.upperoverlay = e->scoreboard->skin->tex_upper; - cm->texnum.base = e->scoreboard->skin->tex_base; + cm->texnum.loweroverlay = plskin->tex_lower; + cm->texnum.upperoverlay = plskin->tex_upper; + cm->texnum.base = plskin->tex_base; return shader; } } @@ -386,7 +386,9 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e { if (skins->ofstexels) { - original = (qbyte *)skins + skins->ofstexels; + int *offsets; + offsets = (int*)((qbyte *)skins + skins->ofstexels); + original = (qbyte*)offsets + offsets[subframe]; inwidth = skins->skinwidth; inheight = skins->skinheight; } @@ -424,21 +426,29 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e tinheight = inheight; //don't make scaled width any larger than it needs to be - for (i = 0; i < 10; i++) + if (r_config.texture_non_power_of_two) { - scaled_width = (1<= tinwidth) - break; //its covered + scaled_width = tinwidth; + scaled_height = tinheight; } + else + { + for (i = 0; i < 10; i++) + { + scaled_width = (1<= tinwidth) + break; //its covered + } + for (i = 0; i < 10; i++) + { + scaled_height = (1<= tinheight) + break; //its covered + } + } + if (scaled_width > gl_max_size.value) scaled_width = gl_max_size.value; //whoops, we made it too big - - for (i = 0; i < 10; i++) - { - scaled_height = (1<= tinheight) - break; //its covered - } if (scaled_height > gl_max_size.value) scaled_height = gl_max_size.value; //whoops, we made it too big @@ -966,9 +976,9 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches) /*switch model if we're the player model, and the player skin says a new model*/ { extern int cl_playerindex; - if (e->scoreboard && e->model == cl.model_precache[cl_playerindex]) + if (e->playerindex >= 0 && e->model == cl.model_precache[cl_playerindex]) { - clmodel = e->scoreboard->model; + clmodel = cl.players[e->playerindex].model; if (clmodel && clmodel->type == mod_alias) e->model = clmodel; } @@ -1930,7 +1940,7 @@ void BE_GenPolyBatches(batch_t **batches) b->lightmap[2] = -1; b->lightmap[3] = -1; b->surf_first = i; - b->flags = BEF_NODLIGHT|BEF_NOSHADOWS; + b->flags = BEF_NODLIGHT|BEF_NOSHADOWS | cl_stris[i].flags; b->vbo = 0; b->next = batches[shader->sort]; batches[shader->sort] = b; @@ -1942,19 +1952,25 @@ void BE_GenModelBatches(batch_t **batches) { int i; entity_t *ent; + unsigned int orig_numstris = cl_numstris; + unsigned int orig_numvisedicts = cl_numvisedicts; /*clear the batch list*/ for (i = 0; i < SHADER_SORT_COUNT; i++) batches[i] = NULL; #if defined(TERRAIN) - if (cl.worldmodel && cl.worldmodel->terrain) + if (cl.worldmodel && cl.worldmodel->terrain && !(r_refdef.flags & Q2RDF_NOWORLDMODEL)) Terr_DrawTerrainModel(batches, &r_worldentity); #endif if (!r_drawentities.ival) return; +#ifndef CLIENTONLY + SV_AddDebugPolygons(); +#endif + Alias_FlushCache(); // draw sprites seperately, because of alpha blending @@ -2042,6 +2058,9 @@ void BE_GenModelBatches(batch_t **batches) if (cl_numstris) BE_GenPolyBatches(batches); + + cl_numstris = orig_numstris; + cl_numvisedicts = orig_numvisedicts; } #endif // defined(GLQUAKE) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 6c80839a..ad07f272 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -49,6 +49,12 @@ static const char LIGHTPASS_SHADER[] = "\ {\n\ map $shadowmap\n\ }\n\ + {\n\ + map $loweroverlay\n\ + }\n\ + {\n\ + map $upperoverlay\n\ + }\n\ }"; @@ -66,6 +72,7 @@ extern cvar_t r_glsl_offsetmapping, r_noportals; static void BE_SendPassBlendDepthMask(unsigned int sbits); void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth); void GLBE_SubmitBatch(batch_t *batch); +static qboolean GLBE_RegisterLightShader(int mode); struct { //internal state @@ -399,19 +406,29 @@ void GL_LazyBind(int tmu, int target, texid_t texnum) GL_SelectTexture(tmu); shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; - if (target) - bindTexFunc (target, texnum.num); #ifndef FORCESTATE - if (shaderstate.curtexturetype[tmu] != target && !gl_config.nofixedfunc) + if (shaderstate.curtexturetype[tmu] != target) #endif { if (shaderstate.curtexturetype[tmu]) - qglDisable(shaderstate.curtexturetype[tmu]); - shaderstate.curtexturetype[tmu] = target; - if (target) - qglEnable(target); + bindTexFunc (shaderstate.curtexturetype[tmu], texnum.num); + if (gl_config.nofixedfunc) + { + shaderstate.curtexturetype[tmu] = target; + } + else + { + if (shaderstate.curtexturetype[tmu]) + qglDisable(shaderstate.curtexturetype[tmu]); + shaderstate.curtexturetype[tmu] = target; + if (target) + qglEnable(target); + } } + + if (target) + bindTexFunc (target, texnum.num); } } @@ -804,11 +821,17 @@ void GL_CullFace(unsigned int sflags) void R_FetchTopColour(int *retred, int *retgreen, int *retblue) { int i; + unsigned int cv = shaderstate.curentity->topcolour; - if (shaderstate.curentity->scoreboard) + if (cv >= 16) { - i = shaderstate.curentity->scoreboard->ttopcolor; + *retred = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0))>>8; + *retgreen = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1))>>8; + *retblue = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2))>>8; + return; } + if (cv >= 0) + i = cv; else i = TOP_RANGE>>4; if (i > 8) @@ -834,11 +857,17 @@ void R_FetchTopColour(int *retred, int *retgreen, int *retblue) void R_FetchBottomColour(int *retred, int *retgreen, int *retblue) { int i; + unsigned int cv = shaderstate.curentity->bottomcolour; - if (shaderstate.curentity->scoreboard) + if (cv >= 16) { - i = shaderstate.curentity->scoreboard->tbottomcolor; + *retred = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0))>>8; + *retgreen = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1))>>8; + *retblue = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2))>>8; + return; } + if (cv >= 0) + i = cv; else i = BOTTOM_RANGE>>4; if (i > 8) @@ -935,7 +964,7 @@ static void T_Gen_CurrentRender(int tmu) if (r_refdef.recurse) return; - if (gl_config.arb_texture_non_power_of_two) + if (r_config.texture_non_power_of_two) { vwidth = vid.pixelwidth; vheight = vid.pixelheight; @@ -1240,17 +1269,13 @@ void GLBE_Init(void) for (i = 0; i < MAXLIGHTMAPS; i++) shaderstate.dummybatch.lightmap[i] = -1; -#if FIXME - /*normally we load these lazily, but if they're probably going to be used anyway, load them now to avoid stalls.*/ - if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects) +#ifdef RTLIGHTS + if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival) { - shaderstate.inited_shader_rtlight = true; - shaderstate.shader_rtlight = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL); - } - if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_cubeproj && gl_config.arb_shader_objects) - { - shaderstate.inited_shader_cubeproj = true; - shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_cubeproj", Shader_LightPass_CubeProj, NULL); + if (r_shadow_shadowmapping.ival) + GLBE_RegisterLightShader(LSHADER_SMAP); + else + GLBE_RegisterLightShader(0); } #endif @@ -2405,6 +2430,10 @@ static void BE_SubmitMeshChain(void) int startv, starti, endv, endi; int m; mesh_t *mesh; + int batchtype = GL_TRIANGLES; + + if (shaderstate.flags & BEF_LINES) + batchtype = GL_LINES; #if 0 if (!shaderstate.currentebo) @@ -2412,7 +2441,7 @@ static void BE_SubmitMeshChain(void) if (shaderstate.meshcount == 1) { mesh = shaderstate.meshes[0]; - qglDrawRangeElements(GL_TRIANGLES, mesh->vbofirstvert, mesh->vbofirstvert+mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + mesh->vbofirstelement); + qglDrawRangeElements(batchtype, mesh->vbofirstvert, mesh->vbofirstvert+mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + mesh->vbofirstelement); RQuantAdd(RQUANT_DRAWS, 1); return; } @@ -2443,7 +2472,7 @@ static void BE_SubmitMeshChain(void) for (starti = 0; starti < mesh->numindexes; ) ilst[endi++] = mesh->vbofirstvert + mesh->indexes[starti++]; } - qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi, GL_INDEX_TYPE, ilst); + qglDrawRangeElements(batchtype, startv, endv, endi, GL_INDEX_TYPE, ilst); RQuantAdd(RQUANT_DRAWS, 1); } @@ -2494,7 +2523,7 @@ static void BE_SubmitMeshChain(void) } } - qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti); + qglDrawRangeElements(batchtype, startv, endv, endi-starti, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti); RQuantAdd(RQUANT_DRAWS, 1); } /* @@ -2627,7 +2656,7 @@ static void DrawPass(const shaderpass_t *pass) static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, qboolean entunchanged) { - vec3_t param3; + vec4_t param4; int r, g, b; int i; unsigned int ph; @@ -2762,24 +2791,24 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, break; case SP_E_TOPCOLOURS: R_FetchTopColour(&r, &g, &b); - param3[0] = r/255.0f; - param3[1] = g/255.0f; - param3[2] = b/255.0f; - qglUniform3fvARB(ph, 1, param3); + param4[0] = r/255.0f; + param4[1] = g/255.0f; + param4[2] = b/255.0f; + qglUniform3fvARB(ph, 1, param4); break; case SP_E_BOTTOMCOLOURS: R_FetchBottomColour(&r, &g, &b); - param3[0] = r/255.0f; - param3[1] = g/255.0f; - param3[2] = b/255.0f; - qglUniform3fvARB(ph, 1, param3); + param4[0] = r/255.0f; + param4[1] = g/255.0f; + param4[2] = b/255.0f; + qglUniform3fvARB(ph, 1, param4); break; case SP_RENDERTEXTURESCALE: - if (gl_config.arb_texture_non_power_of_two) + if (r_config.texture_non_power_of_two) { - param3[0] = 1; - param3[1] = 1; + param4[0] = 1; + param4[1] = 1; } else { @@ -2789,11 +2818,12 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, r *= 2; while (g < vid.pixelheight) g *= 2; - param3[0] = vid.pixelwidth/(float)r; - param3[1] = vid.pixelheight/(float)g; + param4[0] = vid.pixelwidth/(float)r; + param4[1] = vid.pixelheight/(float)g; } - param3[2] = 1; - qglUniform3fvARB(ph, 1, param3); + param4[2] = 0; + param4[3] = 0; + qglUniform4fvARB(ph, 1, param4); break; case SP_LIGHTSCREEN: @@ -2895,12 +2925,12 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, cvar_t *var = (cvar_t*)p->pval; char *vs = var->string; vs = COM_Parse(vs); - param3[0] = atof(com_token); + param4[0] = atof(com_token); vs = COM_Parse(vs); - param3[1] = atof(com_token); + param4[1] = atof(com_token); vs = COM_Parse(vs); - param3[2] = atof(com_token); - qglUniform3fvARB(ph, 1, param3); + param4[2] = atof(com_token); + qglUniform3fvARB(ph, 1, param4); } break; @@ -3004,7 +3034,7 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas qboolean GLBE_LightCullModel(vec3_t org, model_t *model) { #ifdef RTLIGHTS - if ((shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_STENCIL)) + if ((shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY)) { float dist; vec3_t disp; @@ -3805,7 +3835,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT) continue; if (batch->flags & BEF_NOSHADOWS) - if (shaderstate.mode == BEM_STENCIL) + if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) //fixme: depthonly is not just shadows. continue; if (batch->buildmeshes) diff --git a/engine/gl/gl_bloom.c b/engine/gl/gl_bloom.c index 341fd13d..63f01b2a 100644 --- a/engine/gl/gl_bloom.c +++ b/engine/gl/gl_bloom.c @@ -179,7 +179,7 @@ void R_BloomBlend (void) return; if (!gl_config.arb_shader_objects) return; - if (!gl_config.arb_texture_non_power_of_two) + if (!r_config.texture_non_power_of_two) return; /*whu?*/ diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index d23f9c5d..b8cd7420 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -312,7 +312,7 @@ void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue) } if (i == sizeof(modes)/sizeof(modes[0])) { - Con_Printf ("bad gl_texturemode name\n"); + Con_Printf ("bad gl_texturemode name - %s\n", var->string); return; } @@ -574,6 +574,10 @@ void GL_Set2D (qboolean flipped) Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999); Matrix4x4_Identity(r_refdef.m_view); } + r_refdef.pxrect.x = 0; + r_refdef.pxrect.y = 0; + r_refdef.pxrect.width = vid.width; + r_refdef.pxrect.height = vid.height; r_refdef.time = realtime; /*flush that gl state*/ qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); @@ -1030,7 +1034,7 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi void GL_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap) { - if (gl_config.arb_texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. + if (r_config.texture_non_power_of_two) //NPOT is a simple extension that relaxes errors. { TRACE(("dbg: GL_RoundDimensions: GL_ARB_texture_non_power_of_two\n")); } diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index 07eabf94..d891375e 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -12,13 +12,13 @@ void Font_Shutdown(void); struct font_s *Font_LoadFont(int height, char *fontfilename); void Font_Free(struct font_s *f); void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); -void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px, float *py); /*avoid using*/ +void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/ void Font_Transform(int vx, int vy, int *px, int *py); int Font_CharHeight(void); int Font_CharWidth(unsigned int charcode); int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode); int Font_DrawChar(int px, int py, unsigned int charcode); -float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int charcode); /*avoid using*/ +float Font_DrawScaleChar(float px, float py, unsigned int charcode); /*avoid using*/ void Font_EndString(struct font_s *font); int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends); struct font_s *font_conchar; @@ -225,6 +225,8 @@ static byte_vec4_t font_forecolour; static byte_vec4_t font_backcolour; static struct font_s *curfont; +static float curfont_scale[2]; +static qboolean curfont_scaled; //called at load time - initalises font buffers void Font_Init(void) @@ -656,7 +658,7 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, char *fontfilename) f = FS_OpenReadLocation(&loc); if (f && loc.len > 0) { - fbase = malloc(loc.len); + fbase = BZ_Malloc(loc.len); VFS_READ(f, fbase, loc.len); VFS_CLOSE(f); @@ -708,7 +710,7 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, char *fontfilename) } } if (fbase) - free(fbase); + BZ_Free(fbase); #endif return false; @@ -927,12 +929,13 @@ void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride) //creates a new font object from the given file, with each text row with the given height. //width is implicit and scales with height and choice of font. -struct font_s *Font_LoadFont(int height, char *fontfilename) +struct font_s *Font_LoadFont(int vheight, char *fontfilename) { struct font_s *f; int i = 0; int defaultplane; char *aname; + int height = (vheight * vid.rotpixelheight)/vid.height; f = Z_Malloc(sizeof(*f)); f->charheight = height; @@ -1062,7 +1065,7 @@ struct font_s *Font_LoadFont(int height, char *fontfilename) if (aname) { *aname = 0; - f->alt = Font_LoadFont(height, aname+1); + f->alt = Font_LoadFont(vheight, aname+1); } if (!Font_LoadFreeTypeFont(f, height, fontfilename)) { @@ -1129,11 +1132,13 @@ void Font_Free(struct font_s *f) { struct charcache_s **link; + //kill the alt font first. if (f->alt) { Font_Free(f->alt); f->alt = NULL; } + //walk all chars, unlinking any that appear to be within this font's char cache for (link = &fontplanes.oldestchar; *link; ) { if (*link >= f->chars && *link <= f->chars + FONTCHARS) @@ -1150,9 +1155,9 @@ void Font_Free(struct font_s *f) if (f->face) pFT_Done_Face(f->face); if (f->membuf) - free(f->membuf); + BZ_Free(f->membuf); #endif - free(f); + Z_Free(f); } //maps a given virtual screen coord to a pixel coord, which matches the font's height/width values @@ -1161,6 +1166,10 @@ void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py) curfont = font; *px = (vx*(int)vid.rotpixelwidth) / (float)vid.width; *py = (vy*(int)vid.rotpixelheight) / (float)vid.height; + + curfont_scale[0] = curfont->charheight; + curfont_scale[1] = curfont->charheight; + curfont_scaled = false; } void Font_Transform(int vx, int vy, int *px, int *py) { @@ -1169,11 +1178,24 @@ void Font_Transform(int vx, int vy, int *px, int *py) if (py) *py = (vy*(int)vid.rotpixelheight) / (float)vid.height; } -void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px, float *py) +void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py) { curfont = font; - *px = vx; - *py = vy; + *px = (vx*(float)vid.rotpixelwidth) / (float)vid.width; + *py = (vy*(float)vid.rotpixelheight) / (float)vid.height; + + //now that its in pixels, clamp it so the text is at least consistant with its position. + //an individual char may end straddling a pixel boundary, but at least the pixels won't jiggle around as the text moves. + *px = (int)*px; + *py = (int)*py; + + if ((int)(szx * vid.rotpixelheight/vid.height) == curfont->charheight && (int)(szy * vid.rotpixelheight/vid.height) == curfont->charheight) + curfont_scaled = false; + else + curfont_scaled = true; + + curfont_scale[0] = (szx * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height); + curfont_scale[1] = (szy * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height); } void Font_EndString(struct font_s *font) @@ -1392,24 +1414,47 @@ int Font_DrawChar(int px, int py, unsigned int charcode) return nextx; } - col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); - if (col != font_colourmask) + if (charcode & CON_RICHFORECOLOUR) { - if ((col ^ font_colourmask) & CON_NONCLEARBG) - Font_Flush(); - font_colourmask = col; + col = charcode & (CON_RICHFORECOLOUR|(0xfff<>CON_FGSHIFT; - font_forecolour[0] = consolecolours[col].fr*255; - font_forecolour[1] = consolecolours[col].fg*255; - font_forecolour[2] = consolecolours[col].fb*255; - font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; + font_forecolour[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11; + font_forecolour[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11; + font_forecolour[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11; + font_forecolour[3] = 255; - col = (charcode&CON_BGMASK)>>CON_BGSHIFT; - font_backcolour[0] = consolecolours[col].fr*255; - font_backcolour[1] = consolecolours[col].fg*255; - font_backcolour[2] = consolecolours[col].fb*255; - font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; + font_backcolour[0] = 0; + font_backcolour[1] = 0; + font_backcolour[2] = 0; + font_backcolour[3] = 0; + } + } + else + { + col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); + if (col != font_colourmask) + { + if ((col ^ font_colourmask) & CON_NONCLEARBG) + Font_Flush(); + font_colourmask = col; + + col = (charcode&CON_FGMASK)>>CON_FGSHIFT; + font_forecolour[0] = consolecolours[col].fr*255; + font_forecolour[1] = consolecolours[col].fg*255; + font_forecolour[2] = consolecolours[col].fb*255; + font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; + + col = (charcode&CON_BGMASK)>>CON_BGSHIFT; + font_backcolour[0] = consolecolours[col].fr*255; + font_backcolour[1] = consolecolours[col].fg*255; + font_backcolour[2] = consolecolours[col].fb*255; + font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; + } } s0 = (float)c->bmx/PLANEWIDTH; @@ -1480,7 +1525,7 @@ int Font_DrawChar(int px, int py, unsigned int charcode) } /*there is no sane way to make this pixel-correct*/ -float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int charcode) +float Font_DrawScaleChar(float px, float py, unsigned int charcode) { struct charcache_s *c; float s0, s1; @@ -1490,6 +1535,11 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch int col; int v; struct font_s *font = curfont; + float cw, ch; + +// if (!curfont_scaled) +// return Font_DrawChar(px, py, charcode); + if (charcode & CON_2NDCHARSETTEXT) { if (font->alt) @@ -1498,9 +1548,8 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch charcode |= 0xe000; } - cw /= font->charheight; - ch /= font->charheight; - + cw = curfont_scale[0]; + ch = curfont_scale[1]; //crash if there is no current font. c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); @@ -1523,24 +1572,47 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch return nextx; } - col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); - if (col != font_colourmask) + if (charcode & CON_RICHFORECOLOUR) { - if ((col ^ font_colourmask) & CON_NONCLEARBG) - Font_Flush(); - font_colourmask = col; + col = charcode & (CON_RICHFORECOLOUR|(0xfff<>CON_FGSHIFT; - font_forecolour[0] = consolecolours[col].fr*255; - font_forecolour[1] = consolecolours[col].fg*255; - font_forecolour[2] = consolecolours[col].fb*255; - font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; + font_forecolour[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11; + font_forecolour[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11; + font_forecolour[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11; + font_forecolour[3] = 255; - col = (charcode&CON_BGMASK)>>CON_BGSHIFT; - font_backcolour[0] = consolecolours[col].fr*255; - font_backcolour[1] = consolecolours[col].fg*255; - font_backcolour[2] = consolecolours[col].fb*255; - font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; + font_backcolour[0] = 0; + font_backcolour[1] = 0; + font_backcolour[2] = 0; + font_backcolour[3] = 0; + } + } + else + { + col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); + if (col != font_colourmask) + { + if (font_backcolour[3] != ((charcode & CON_NONCLEARBG)?127:0)) + Font_Flush(); + font_colourmask = col; + + col = (charcode&CON_FGMASK)>>CON_FGSHIFT; + font_forecolour[0] = consolecolours[col].fr*255; + font_forecolour[1] = consolecolours[col].fg*255; + font_forecolour[2] = consolecolours[col].fb*255; + font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255; + + col = (charcode&CON_BGMASK)>>CON_BGSHIFT; + font_backcolour[0] = consolecolours[col].fr*255; + font_backcolour[1] = consolecolours[col].fg*255; + font_backcolour[2] = consolecolours[col].fb*255; + font_backcolour[3] = (charcode & CON_NONCLEARBG)?127:0; + } } s0 = (float)c->bmx/PLANEWIDTH; @@ -1550,8 +1622,8 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch if (c->texplane >= DEFAULTPLANE) { - sx = ((px+c->left)); - sy = ((py+c->top)); + sx = ((px+c->left*cw)); + sy = ((py+c->top*ch)); sw = ((font->charheight*cw)); sh = ((font->charheight*ch)); @@ -1562,13 +1634,18 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch } else { - sx = ((px+(c->left*(int)vid.width) / (float)vid.rotpixelwidth)); - sy = ((py+(c->top*(int)vid.height) / (float)vid.rotpixelheight)); + sx = (px+c->left*cw); + sy = (py+c->top*ch); sw = ((c->bmw*cw)); sh = ((c->bmh*ch)); v = Font_BeginChar(fontplanes.texnum[c->texplane]); } + sx *= (int)vid.width / (float)vid.rotpixelwidth; + sy *= (int)vid.height / (float)vid.rotpixelheight; + sw *= (int)vid.width / (float)vid.rotpixelwidth; + sh *= (int)vid.height / (float)vid.rotpixelheight; + font_texcoord[v+0][0] = s0; font_texcoord[v+0][1] = t0; font_texcoord[v+1][0] = s1; diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 416c0a11..eebe1928 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -729,7 +729,7 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy //kill the haswater flag if its entirely above any possible water anyway. if (s->waterheight < s->minh) ds.flags &= ~TSF_HASWATER; - ds.flags &= TSF_HASCOLOURS; //recalculate + ds.flags &= ~TSF_HASCOLOURS; //recalculated Q_strncpyz(ds.texname[0], s->texname[0], sizeof(ds.texname[0])); Q_strncpyz(ds.texname[1], s->texname[1], sizeof(ds.texname[1])); @@ -832,8 +832,8 @@ static hmsection_t *Terr_GetSection(heightmap_t *hm, int x, int y, qboolean dolo { if (doload) { - while (hm->activesections > TERRAINACTIVESECTIONS) - Terr_Collect(hm); +// while (hm->activesections > TERRAINACTIVESECTIONS) +// Terr_Collect(hm); section = cluster->section[sx + sy*MAXSECTIONS] = Terr_LoadSection(hm, section, x, y); } } @@ -972,17 +972,22 @@ static void Terr_Collect(heightmap_t *hm) for (ln = &hm->recycle; ln->next != &hm->recycle; ) { s = (hmsection_t*)ln->next; - cx = s->sx/MAXSECTIONS; - cy = s->sy/MAXSECTIONS; - c = hm->cluster[cx + cy*MAXSECTIONS]; - sx = s->sx & (MAXSECTIONS-1); - sy = s->sy & (MAXSECTIONS-1); - if (c->section[sx+sy*MAXSECTIONS] != s) - Sys_Error("invalid section collection"); - c->section[sx+sy*MAXSECTIONS] = NULL; + if (s->flags & TSF_EDITED) + ln = &s->recycle; + else + { + cx = s->sx/MAXSECTIONS; + cy = s->sy/MAXSECTIONS; + c = hm->cluster[cx + cy*MAXSECTIONS]; + sx = s->sx & (MAXSECTIONS-1); + sy = s->sy & (MAXSECTIONS-1); + if (c->section[sx+sy*MAXSECTIONS] != s) + Sys_Error("invalid section collection"); + c->section[sx+sy*MAXSECTIONS] = NULL; - Terr_DestroySection(hm, s, true); - return; + Terr_DestroySection(hm, s, true); + return; + } } } @@ -1049,8 +1054,9 @@ void Terr_PurgeTerrainModel(model_t *mod, qboolean lightmapsonly, qboolean light void Terr_DrawTerrainWater(heightmap_t *hm, float *mins, float *maxs, float waterz, float r, float g, float b, float a) { scenetris_t *t; + int flags = BEF_NOSHADOWS; - if (cl_numstris && cl_stris[cl_numstris-1].shader == hm->watershader) + if (cl_numstris && cl_stris[cl_numstris-1].shader == hm->watershader && cl_stris[cl_numstris-1].flags == flags) { t = &cl_stris[cl_numstris-1]; } @@ -1063,6 +1069,7 @@ void Terr_DrawTerrainWater(heightmap_t *hm, float *mins, float *maxs, float wate } t = &cl_stris[cl_numstris++]; t->shader = hm->watershader; + t->flags = flags; t->firstidx = cl_numstrisidx; t->firstvert = cl_numstrisvert; t->numvert = 0; @@ -1504,7 +1511,6 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h) { vec3_t mins, maxs; hmsection_t *s; - mesh_t *mesh; int i; batch_t *b; heightmap_t *hm = ctx->hm; @@ -1539,7 +1545,6 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h) } } - mesh = &s->mesh; if (s->flags & TSF_DIRTY) { s->flags &= ~TSF_DIRTY; @@ -1580,7 +1585,7 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h) b->shader = hm->shader; b->flags = 0; b->mesh = &s->amesh; - b->mesh[0] = mesh; + b->mesh[0] = &s->mesh; b->meshes = 1; b->buildmeshes = NULL; b->skin = &s->textures; @@ -1637,6 +1642,10 @@ void Terr_DrawTerrainModel (batch_t **batches, entity_t *e) batch_t *b; int bounds[4]; struct tdibctx tdibctx; + + if (!r_refdef.recurse) + while (hm->activesections > TERRAINACTIVESECTIONS) + Terr_Collect(hm); if (hm->relight) ted_dorelight(hm); @@ -2136,11 +2145,14 @@ static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty) hmsection_t *s; unsigned int holebit; - if (tx < 0 || tx >= CHUNKLIMIT*(SECTHEIGHTSIZE-1)) - return; - if (ty < 0 || ty >= CHUNKLIMIT*(SECTHEIGHTSIZE-1)) - return; - s = Terr_GetSection(tr->hm, tx/(SECTHEIGHTSIZE-1), ty/(SECTHEIGHTSIZE-1), true); + sx = tx/(SECTHEIGHTSIZE-1); + sy = ty/(SECTHEIGHTSIZE-1); + if (sx < tr->hm->firstsegx || sx >= tr->hm->maxsegx) + s = NULL; + else if (sy < tr->hm->firstsegy || sy >= tr->hm->maxsegy) + s = NULL; + else + s = Terr_GetSection(tr->hm, sx, sy, true); if (!s) { @@ -2853,7 +2865,7 @@ static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float ra } } -void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *vmw = prinst->parms->user; int action = G_FLOAT(OFS_PARM0); @@ -3107,7 +3119,7 @@ void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_glob } } #else -void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = 0; } diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 961158e2..d7ed8b10 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -430,10 +430,6 @@ void RMod_Init (void) Cmd_AddCommand("mod_batchlist", RMod_BatchList_f); Cmd_AddCommand("mod_texturelist", RMod_TextureList_f); Cmd_AddCommand("mod_usetexture", RMod_BlockTextureColour_f); - -#ifdef TERRAIN - Terr_Init(); -#endif } void RMod_Shutdown (void) @@ -618,6 +614,14 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash) return mod; } +#ifdef RAGDOLL + if (mod->dollinfo) + { + rag_freedoll(mod->dollinfo); + mod->dollinfo = NULL; + } +#endif + // // load the file // @@ -878,6 +882,19 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash) TRACE(("RMod_LoadModel: Loaded\n")); +#ifdef RAGDOLL + { + int numbones = Mod_GetNumBones(mod, false); + if (numbones) + { + char *dollname = va("%s.doll", mod->name); + buf = (unsigned *)COM_LoadStackFile (dollname, stackbuf, sizeof(stackbuf)); + if (buf) + mod->dollinfo = rag_createdollfromstring(mod, dollname, numbones, (char*)buf); + } + } +#endif + return mod; } @@ -1721,9 +1738,15 @@ void RMod_LoadLighting (lump_t *l) else if (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T') { if (LittleLong(*(int *)&litdata[4]) == 1 && l->filelen && samples*3 != (com_filesize-8)) + { + litdata = NULL; Con_Printf("lit \"%s\" doesn't match level. Ignored.\n", litname); + } else if (LittleLong(*(int *)&litdata[4]) != 1) + { Con_Printf("lit \"%s\" isn't version 1.\n", litname); + litdata = NULL; + } else if (lumdata) { float prop; @@ -2788,6 +2811,9 @@ void RMod_Batches_Build(mesh_t *meshlist, model_t *mod, void (*build)(model_t *m currentmodel = mod; + if (!mod->textures) + return; + if (meshlist) meshlist += mod->firstmodelsurface; else if (!build) diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 09e13533..60491f8d 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -50,6 +50,14 @@ typedef enum { } shadersort_t; #define MAX_BONES 128 +struct doll_s; +void rag_flushdolls(qboolean force); +void rag_freedoll(struct doll_s *doll); +struct doll_s *rag_createdollfromstring(struct model_s *mod, char *fname, int numbones, char *file); +struct world_s; +void rag_doallanimations(struct world_s *world); +void rag_removedeltaent(lerpents_t *le); +void rag_updatedeltaent(entity_t *ent, lerpents_t *le); typedef struct mesh_s { @@ -955,6 +963,8 @@ typedef struct model_s q3lightgridinfo_t *lightgrid; char *entities; + struct doll_s *dollinfo; + struct { texture_t *tex; vbo_t *vbo; diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 71a8b6e3..0a8ad4a0 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -987,7 +987,7 @@ void R_Clear (void) /*tbh, this entire function should be in the backend*/ GL_ForceDepthWritable(); { - if (r_clear.ival && !r_secondaryview && !(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + if (r_clear.ival && !r_secondaryview && !r_refdef.currentplayernum && !(r_refdef.flags & Q2RDF_NOWORLDMODEL)) { qglClearColor(1, 0, 0, 0); qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1065,7 +1065,7 @@ static void R_RenderMotionBlur(void) #if !defined(ANDROID) && !defined(NACL) //figure out the size of our texture. - if (gl_config.arb_texture_non_power_of_two) + if (r_config.texture_non_power_of_two) { //we can use any size, supposedly vwidth = vid.pixelwidth; vheight = vid.pixelheight; @@ -1181,7 +1181,7 @@ qboolean R_RenderScene_Cubemap(void) prect.y = (vrect.y * vid.pixelheight)/vid.height; prect.height = (vrect.height * vid.pixelheight)/vid.height; - if (gl_config.arb_texture_non_power_of_two) + if (r_config.texture_non_power_of_two) { if (prect.width < prect.height) cmapsize = prect.width; @@ -1369,11 +1369,11 @@ void GLR_RenderView (void) checkglerror(); + GL_Set2D (false); + if (r_refdef.flags & Q2RDF_NOWORLDMODEL) return; - GL_Set2D (false); - if (r_bloom.value) R_BloomBlend(); diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 5e010327..237b365f 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -198,9 +198,6 @@ void GLSCR_UpdateScreen (void) SCR_DrawTwoDimensional(uimenu, nohud); - if (Key_MouseShouldBeFree()) - SCR_DrawCursor(0); - V_UpdatePalette (false); R2D_BrightenScreen(); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index b43287b8..69082064 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -76,9 +76,9 @@ qbyte FloatToByte( float x ) cvar_t r_detailtextures; -#define MAX_TOKEN_CHARS 1024 +#define MAX_TOKEN_CHARS sizeof(com_token) -char *COM_ParseExt (char **data_p, qboolean nl) +char *COM_ParseExt (char **data_p, qboolean nl, qboolean comma) { int c; int len; @@ -154,13 +154,13 @@ skipwhite: } data++; c = *data; - if (c == ',' && len) + if (c == ',' && len && comma) break; } while (c>32); if (len == MAX_TOKEN_CHARS) { -// Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS); + Con_DPrintf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS); len = 0; } com_token[len] = 0; @@ -216,12 +216,12 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode); //=========================================================================== -static qboolean Shader_EvaluateCondition(char **ptr) +static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr) { char *token; cvar_t *cv; qboolean conditiontrue = true; - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, false); if (*token == '!') { conditiontrue = false; @@ -300,9 +300,34 @@ static qboolean Shader_EvaluateCondition(char **ptr) conditiontrue = conditiontrue == false; break; } -#ifdef warningmsg -#pragma warningmsg("shader fixme") + } + else if (!Q_stricmp(token, "haveprogram") ) + { + conditiontrue = conditiontrue == !!shader->prog; + } + else if (!Q_stricmp(token, "programs") ) + { + switch(qrenderer) + { +#ifdef GLQUAKE + case QR_OPENGL: + conditiontrue = conditiontrue == gl_config.arb_shader_objects; //FIXME + break; #endif +#ifdef D3D9QUAKE + case QR_DIRECT3D9: + conditiontrue = conditiontrue == true; //FIXME + break; +#endif +#ifdef D3D11QUAKE + case QR_DIRECT3D11: + conditiontrue = conditiontrue == true; + break; +#endif + default: + conditiontrue = conditiontrue == false; + break; + } } else if (!Q_stricmp(token, "diffuse") ) conditiontrue = conditiontrue == true; @@ -328,14 +353,14 @@ static qboolean Shader_EvaluateCondition(char **ptr) Con_Printf("Shader_EvaluateCondition: '%s' is not a cvar\n", token); return conditiontrue; } - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, false); cv->flags |= CVAR_SHADERSYSTEM; if (*token) { float rhs; char cmp[4]; memcpy(cmp, token, 4); - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, false); rhs = atof(token); if (!strcmp(cmp, "!=")) conditiontrue = cv->value != rhs; @@ -358,15 +383,30 @@ static qboolean Shader_EvaluateCondition(char **ptr) conditiontrue = conditiontrue == !!cv->value; } } - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, false); if (!strcmp(token, "&&")) - return Shader_EvaluateCondition(ptr) && conditiontrue; + return Shader_EvaluateCondition(shader, ptr) && conditiontrue; if (!strcmp(token, "||")) - return Shader_EvaluateCondition(ptr) || conditiontrue; + return Shader_EvaluateCondition(shader, ptr) || conditiontrue; return conditiontrue; } +static char *Shader_ParseExactString(char **ptr) +{ + char *token; + + if ( !ptr || !(*ptr) ) { + return ""; + } + if ( !**ptr || **ptr == '}' ) { + return ""; + } + + token = COM_ParseExt(ptr, false, false); + return token; +} + static char *Shader_ParseString ( char **ptr ) { char *token; @@ -378,7 +418,7 @@ static char *Shader_ParseString ( char **ptr ) return ""; } - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, true); Q_strlwr ( token ); return token; @@ -395,7 +435,7 @@ static char *Shader_ParseSensString ( char **ptr ) return ""; } - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, true); return token; } @@ -412,7 +452,7 @@ static float Shader_ParseFloat(char **ptr) return 0; } - token = COM_ParseExt(ptr, false); + token = COM_ParseExt(ptr, false, true); if (*token == '$') { cvar_t *var; @@ -885,6 +925,22 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip } script = end; } + else if (!strncmp(script, "!!cvari", 7)) + { + script += 7; + while (*script == ' ' || *script == '\t') + script++; + end = script; + while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') + end++; + if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0])) + { + cvartypes[cvarcount] = SP_CVARI; + cvarnames[cvarcount++] = script; + cvarnames[cvarcount] = NULL; + } + script = end; + } else if (!strncmp(script, "!!cvarv", 7)) { script += 7; @@ -1539,8 +1595,8 @@ struct shader_field_names_s shader_unif_names[] = {"e_colour", SP_E_COLOURS}, {"e_colourident", SP_E_COLOURSIDENT}, {"e_glowmod", SP_E_GLOWMOD}, - {"e_topcolour", SP_E_TOPCOLOURS}, - {"e_bottomcolour", SP_E_BOTTOMCOLOURS}, + {"e_uppercolour", SP_E_TOPCOLOURS}, + {"e_lowercolour", SP_E_BOTTOMCOLOURS}, {"e_light_dir", SP_E_L_DIR}, {"e_light_mul", SP_E_L_MUL}, {"e_light_ambient", SP_E_L_AMBIENT}, @@ -1648,7 +1704,7 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, va("cvar_%s", tmpname)); if (uniformloc != -1) { - qglUniform1fARB(uniformloc, cvar->value); + //qglUniform1fARB(uniformloc, cvar->value); found = true; } prog->permu[p].parm[prog->numparams] = uniformloc; @@ -1813,11 +1869,11 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p { //pass the # postfixes from the shader name onto the generic glsl to use char newname[512]; - Q_snprintfz(newname, sizeof(newname), "%s%s", Shader_ParseString(ptr), hash); + Q_snprintfz(newname, sizeof(newname), "%s%s", Shader_ParseExactString(ptr), hash); shader->prog = Shader_FindGeneric(newname, qrtype); } else - shader->prog = Shader_FindGeneric(Shader_ParseString(ptr), qrtype); + shader->prog = Shader_FindGeneric(Shader_ParseExactString(ptr), qrtype); } static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr) @@ -2947,7 +3003,7 @@ static void Shader_MakeCache ( char *path ) if ( ptr - buf >= size ) break; - token = COM_ParseExt ( &ptr, true ); + token = COM_ParseExt (&ptr, true, true); if ( !token[0] || ptr - buf >= size ) break; @@ -2982,19 +3038,19 @@ char *Shader_Skip ( char *ptr ) int brace_count; // Opening brace - tok = COM_ParseExt ( &ptr, true ); + tok = COM_ParseExt(&ptr, true, true); if (!ptr) return NULL; if ( tok[0] != '{' ) { - tok = COM_ParseExt ( &ptr, true ); + tok = COM_ParseExt (&ptr, true, true); } for (brace_count = 1; brace_count > 0 ; ptr++) { - tok = COM_ParseExt ( &ptr, true ); + tok = COM_ParseExt (&ptr, true, true); if ( !tok[0] ) return NULL; @@ -3177,7 +3233,7 @@ void Shader_Readpass (shader_t *shader, char **ptr) while ( *ptr ) { - token = COM_ParseExt (ptr, true); + token = COM_ParseExt (ptr, true, true); if ( !token[0] ) { @@ -3190,11 +3246,11 @@ void Shader_Readpass (shader_t *shader, char **ptr) else if (!Q_stricmp(token, "if")) { int nest = 0; - qboolean conditionistrue = Shader_EvaluateCondition(ptr); + qboolean conditionistrue = Shader_EvaluateCondition(shader, ptr); while (*ptr) { - token = COM_ParseExt (ptr, true); + token = COM_ParseExt (ptr, true, true); if ( !token[0] ) continue; else if (token[0] == ']') @@ -3293,7 +3349,7 @@ static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey // Next Line while (ptr) { - token = COM_ParseExt ( ptr, false ); + token = COM_ParseExt(ptr, false, true); if ( !token[0] ) { break; @@ -4563,6 +4619,15 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args) "map $fullbright\n" "blendfunc add\n" "}\n" + "if $haveprogram\n" + "[\n" + "{\n" + "map $normalmap\n" + "}\n" + "{\n" + "map $specular\n" + "}\n" + "]\n" "}\n" ); } @@ -4628,7 +4693,7 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) while (shadersource) { - token = COM_ParseExt (&shadersource, true); + token = COM_ParseExt (&shadersource, true, true); if ( !token[0] ) continue; @@ -4637,11 +4702,11 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) else if (!Q_stricmp(token, "if")) { int nest = 0; - qboolean conditionistrue = Shader_EvaluateCondition(&shadersource); + qboolean conditionistrue = Shader_EvaluateCondition(s, &shadersource); while (shadersource) { - token = COM_ParseExt (&shadersource, true); + token = COM_ParseExt (&shadersource, true, true); if ( !token[0] ) continue; else if (token[0] == ']') @@ -4702,7 +4767,7 @@ static qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s) file = buf + offset; - token = COM_ParseExt (&file, true); + token = COM_ParseExt (&file, true, true); if ( !file || token[0] != '{' ) { FS_FreeFile(buf); diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 78df2069..6cfd4ef3 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -1002,6 +1002,9 @@ static struct { static void SHM_Shutdown(void) { SH_FreeShadowMesh_(&sh_tempshmesh); + BZ_Free(sh_tempshmesh.litleaves); + sh_tempshmesh.litleaves = NULL; + sh_tempshmesh.leafbytes = 0; free(cv.tris); free(cv.edges); free(cv.points); @@ -1417,20 +1420,25 @@ static qboolean Sh_LeafInView(qbyte *lightvis, qbyte *vvis) typedef struct { - int x; - int y; - int width; - int height; + float x; + float y; + float width; + float height; double dmin; double dmax; } srect_t; static void Sh_Scissor (srect_t r) { + float xs = vid.pixelwidth / (float)vid.width, ys = vid.pixelheight / (float)vid.height; switch(qrenderer) { #ifdef GLQUAKE case QR_OPENGL: - qglScissor(r.x, r.y, r.width, r.height); + qglScissor( + floor(r_refdef.pxrect.x + r.x*r_refdef.pxrect.width), + floor((r_refdef.pxrect.y + r.y*r_refdef.pxrect.height) - r_refdef.pxrect.height), + ceil(r.width * r_refdef.pxrect.width), + ceil(r.height * r_refdef.pxrect.height)); qglEnable(GL_SCISSOR_TEST); if (qglDepthBoundsEXT) @@ -1548,8 +1556,8 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, srect_t *r) r->x = 0; r->y = 0; - r->width = vid.pixelwidth; - r->height = vid.pixelheight; + r->width = 1; + r->height = 1; r->dmin = 0; r->dmax = 1; if (0)//!r_shadow_scissor.integer) @@ -1616,10 +1624,10 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, srect_t *r) if (z < z1) z1 = z; if (z > z2) z2 = z; } - x1 = ((1+x1) * r_refdef.vrect.width * vid.pixelwidth) / (vid.width * 2); - x2 = ((1+x2) * r_refdef.vrect.width * vid.pixelwidth) / (vid.width * 2); - y1 = ((1+y1) * r_refdef.vrect.height * vid.pixelheight) / (vid.height * 2); - y2 = ((1+y2) * r_refdef.vrect.height * vid.pixelheight) / (vid.height * 2); + x1 = (1+x1) / 2; + x2 = (1+x2) / 2; + y1 = (1+y1) / 2; + y2 = (1+y2) / 2; z1 = (1+z1) / 2; z2 = (1+z2) / 2; @@ -1631,21 +1639,21 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, srect_t *r) x2 = 0; if (y2 < 0) y2 = 0; - if (x1 > r_refdef.vrect.width * vid.pixelwidth / vid.width) - x1 = r_refdef.vrect.width * vid.pixelwidth / vid.width; - if (y1 > r_refdef.vrect.height * vid.pixelheight / vid.height) - y1 = r_refdef.vrect.height * vid.pixelheight / vid.height; - if (x2 > r_refdef.vrect.width * vid.pixelwidth / vid.width) - x2 = r_refdef.vrect.width * vid.pixelwidth / vid.width; - if (y2 > r_refdef.vrect.height * vid.pixelheight / vid.height) - y2 = r_refdef.vrect.height * vid.pixelheight / vid.height; - r->x = floor(x1); - r->y = floor(y1); - r->width = ceil(x2) - r->x; - r->height = ceil(y2) - r->y; + if (x1 > 1) + x1 = 1; + if (y1 > 1) + y1 = 1; + if (x2 > 1) + x2 = 1; + if (y2 > 1) + y2 = 1; + r->x = x1; + r->y = y1; + r->width = x2 - r->x; + r->height = y2 - r->y; + if (r->width == 0 || r->height == 0) + return true; //meh - r->x += r_refdef.vrect.x; - r->y += r_refdef.vrect.y; r->dmin = z1; r->dmax = z2; return false; @@ -1910,13 +1918,7 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p int smsize = SHADOWMAP_SIZE; - if (l->fov) - qglViewport (0, 0, smsize, smsize); - else - { - qglViewport ((face%3 * smsize), ((face>=3)*smsize), smsize, smsize); - } - +//FIXME: figure out the four lines bounding the light cone by just adding its +forward+/-right+/-up values. if any point towards a plane (and starts outside that plane), and the point of intersection with that line and the frustum side plane is infront of the near clip plane, then that light frustum needs to be rendered... switch(face) { case 0: @@ -1960,6 +1962,14 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p r_refdef.flipcull = false; break; } + + if (l->fov) + qglViewport (0, 0, smsize, smsize); + else + { + qglViewport ((face%3 * smsize), ((face>=3)*smsize), smsize, smsize); + } + //fixme GL_CullFace(0); R_SetFrustum(proj, r_refdef.m_view); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index fe4a5bf2..be5b000d 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -525,7 +525,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglRenderbufferStorageEXT = NULL; qglFramebufferTexture2DEXT = NULL; - gl_config.arb_texture_non_power_of_two = false; + r_config.texture_non_power_of_two = false; gl_config.sgis_generate_mipmap = false; gl_config.tex_env_combine = false; @@ -551,7 +551,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) } if (GL_CheckExtension("GL_ARB_texture_non_power_of_two") || GL_CheckExtension("GL_OES_texture_npot")) - gl_config.arb_texture_non_power_of_two = true; + r_config.texture_non_power_of_two = true; // if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken. // gl_config.sgis_generate_mipmap = true; diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 9cfd0aa8..aabd7281 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -939,7 +939,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) prots[0] = XInternAtom(vid_dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(vid_dpy, vid_window, prots, sizeof(prots)/sizeof(prots[0])); /*set caption*/ - XStoreName(vid_dpy, vid_window, "FTE QuakeWorld"); + XStoreName(vid_dpy, vid_window, FULLENGINENAME); /*make it visibl*/ XMapWindow(vid_dpy, vid_window); /*put it somewhere*/ diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 17eaac84..b63a376f 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -1540,18 +1540,20 @@ BOOL CheckForcePixelFormat(rendererstate_t *info) float fAttributes[] = {0,0}; UINT numFormats; int pixelformat; - int iAttributes[] = { WGL_DRAW_TO_WINDOW_ARB,GL_TRUE, - WGL_SUPPORT_OPENGL_ARB,GL_TRUE, - WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB, - WGL_COLOR_BITS_ARB,info->bpp, - WGL_ALPHA_BITS_ARB,8, - WGL_DEPTH_BITS_ARB,16, - WGL_STENCIL_BITS_ARB,8, - WGL_DOUBLE_BUFFER_ARB,GL_TRUE, - WGL_SAMPLE_BUFFERS_ARB,GL_TRUE, - WGL_SAMPLES_ARB, info->multisample, // Check For 4x Multisampling - WGL_STEREO_ARB, info->stereo, - 0,0}; + int iAttributes[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB, info->bpp, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 16, + WGL_STENCIL_BITS_ARB, 8, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + WGL_SAMPLES_ARB, info->multisample, // Check For 4x Multisampling + WGL_STEREO_ARB, info->stereo, + 0, 0 + }; TRACE(("dbg: bSetupPixelFormat: attempting wglChoosePixelFormatARB (multisample 4)\n")); hDC = GetDC(mainwindow); @@ -1642,7 +1644,7 @@ void FixPaletteInDescriptor(HDC hDC, PIXELFORMATDESCRIPTOR *pfd) BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info) { - static PIXELFORMATDESCRIPTOR pfd = { + PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW // support window @@ -1713,6 +1715,8 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info) } } + qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd); + if (qSetPixelFormat(hDC, pixelformat, &pfd) == FALSE) { Con_Printf("bSetupPixelFormat: SetPixelFormat failed (%i)\n", (int)GetLastError()); diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 679e2df3..f86c8e88 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -44,6 +44,12 @@ void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2); void ClearBounds (vec3_t mins, vec3_t maxs); +//optional features common to all renderers, so I don't have to check to see which one it is all the time. +typedef struct { + qboolean texture_non_power_of_two; +} r_config_t; +extern r_config_t r_config; + #ifdef GLQUAKE #if defined(ANDROID) /*FIXME: actually just to use standard GLES headers instead of full GL*/ #if 1 @@ -185,7 +191,6 @@ typedef struct { qboolean nv_tex_env_combine4; qboolean env_add; - qboolean arb_texture_non_power_of_two; qboolean sgis_generate_mipmap; qboolean arb_texture_env_combine; diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 79daa7a3..4c905217 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -492,6 +492,7 @@ mfog_t *CM_FogForOrigin(vec3_t org); #define BEF_NODLIGHT 64 //don't use a dlight pass #define BEF_NOSHADOWS 128 //don't appear in shadows #define BEF_FORCECOLOURMOD 256 //q3 shaders default to 'rgbgen identity', and ignore ent colours. this forces ent colours to be considered +#define BEF_LINES 512 //draw line pairs instead of triangles. #ifdef GLQUAKE void GLBE_Init(void); diff --git a/engine/http/ftpserver.c b/engine/http/ftpserver.c index 4ee0a476..9447f146 100644 --- a/engine/http/ftpserver.c +++ b/engine/http/ftpserver.c @@ -20,11 +20,9 @@ #include "netinc.h" -int ftpfilelistsocket; - static iwboolean ftpserverinitied = false; -iwboolean ftpserverfailed = false; -static int ftpserversocket; +static int ftpserversocket = INVALID_SOCKET; +qboolean ftpserverfailed; typedef struct FTPclient_s{ @@ -51,55 +49,75 @@ typedef struct FTPclient_s{ FTPclient_t *FTPclient; -qboolean FTP_ServerInit(int port) +int FTP_BeginListening(int aftype, int port) { - struct sockaddr_in address; + struct sockaddr_qstorage address; unsigned long _true = true; + unsigned long _false = false; int i; + int sock; - if ((ftpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) + if ((sock = socket ((aftype!=1)?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - IWebPrintf ("FTP_TCP_OpenSocket: socket: %s\n", strerror(qerrno)); - ftpserverfailed = true; - return false; + IWebPrintf ("FTP_BeginListening: socket: %s\n", strerror(qerrno)); + return INVALID_SOCKET; } - if (ioctlsocket (ftpserversocket, FIONBIO, &_true) == -1) + if (ioctlsocket (sock, FIONBIO, &_true) == -1) { - IWebPrintf ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); - ftpserverfailed = true; - return false; + IWebPrintf ("FTP_BeginListening: ioctl FIONBIO: %s", strerror(qerrno)); + return INVALID_SOCKET; } - address.sin_family = AF_INET; -//ZOID -- check for interface binding option - if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) { - address.sin_addr.s_addr = inet_addr(com_argv[i+1]); - Con_TPrintf(TL_NETBINDINTERFACE, - inet_ntoa(address.sin_addr)); - } else - address.sin_addr.s_addr = INADDR_ANY; + if (aftype == 1) + { + //1=ipv4 only + ((struct sockaddr_in*)&address)->sin_family = AF_INET; + //ZOID -- check for interface binding option + if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) { + ((struct sockaddr_in*)&address)->sin_addr.s_addr = inet_addr(com_argv[i+1]); + Con_TPrintf(TL_NETBINDINTERFACE, + inet_ntoa(((struct sockaddr_in*)&address)->sin_addr)); + } else + ((struct sockaddr_in*)&address)->sin_addr.s_addr = INADDR_ANY; - if (port == PORT_ANY) - address.sin_port = 0; + if (port == PORT_ANY) + ((struct sockaddr_in*)&address)->sin_port = 0; + else + ((struct sockaddr_in*)&address)->sin_port = htons((short)port); + } else - address.sin_port = htons((short)port); - - if( bind (ftpserversocket, (void *)&address, sizeof(address)) == -1) { - IWebPrintf("FTP_ServerInit: failed to bind socket\n"); - closesocket(ftpserversocket); - ftpserverfailed = true; - return false; + //0=ipv4+ipv6 + //2=ipv6 only + if (aftype == 0) + { + if (0 > setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&_false, sizeof(_false))) + { + //abort and do ipv4 only if hybrid sockets don't work. + closesocket(sock); + return FTP_BeginListening(1, port); + } + } + + memset(&address, 0, sizeof(address)); + ((struct sockaddr_in6*)&address)->sin6_family = AF_INET6; + if (port == PORT_ANY) + ((struct sockaddr_in6*)&address)->sin6_port = 0; + else + ((struct sockaddr_in6*)&address)->sin6_port = htons((short)port); } - listen(ftpserversocket, 3); + if( bind (sock, (void *)&address, sizeof(address)) == -1) + { + IWebPrintf("FTP_BeginListening: failed to bind socket\n"); + closesocket(ftpserversocket); + return INVALID_SOCKET; + } - ftpserverinitied = true; - ftpserverfailed = false; + listen(sock, 3); - IWebPrintf("FTP server is running\n"); - return true; + return sock; } void FTP_ServerShutdown(void) @@ -109,9 +127,10 @@ void FTP_ServerShutdown(void) IWebPrintf("FTP server is deactivated\n"); } +//we ought to filter this to remove duplicates. static int SendFileNameTo(const char *rawname, int size, void *param) { - int socket = ftpfilelistsocket; //64->32... this is safe due to where it's called from. It's just not so portable. + int socket = *(int*)param; // int i; char buffer[256+1]; char *slash; @@ -186,27 +205,65 @@ int FTP_SV_makelistensocket(unsigned long nblocking) return sock; } -iwboolean FTP_SVSocketToString (int socket, char *s) +iwboolean FTP_SVSocketPortToString (int socket, char *s) { - struct sockaddr_in addr; + struct sockaddr_qstorage addr; int adrlen = sizeof(addr); if (getsockname(socket, (struct sockaddr*)&addr, &adrlen) == -1) return false; - sprintf(s, "%i,%i,%i,%i,%i,%i", ((qbyte *)&addr.sin_addr)[0], ((qbyte *)&addr.sin_addr)[1], ((qbyte *)&addr.sin_addr)[2], ((qbyte *)&addr.sin_addr)[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]); + if (((struct sockaddr_in*)&addr)->sin_family == AF_INET6) + sprintf(s, "%i", ntohs(((struct sockaddr_in6*)&addr)->sin6_port)); + else + sprintf(s, "%i", ntohs(((struct sockaddr_in*)&addr)->sin_port)); return true; } -iwboolean FTP_SVRemoteSocketToString (int socket, char *s) +//only to be used for ipv4 sockets. +iwboolean FTP_SVSocketToString (int socket, char *s) { struct sockaddr_in addr; + qbyte *baddr; int adrlen = sizeof(addr); + char name[256]; - addr.sin_family = AF_INET; - if (getpeername(socket, (struct sockaddr*)&addr, &adrlen) == -1) + //get the port. + if (getsockname(socket, (struct sockaddr*)&addr, &adrlen) == -1) return false; - sprintf(s, "%i,%i,%i,%i,%i,%i", ((qbyte *)&addr.sin_addr)[0], ((qbyte *)&addr.sin_addr)[1], ((qbyte *)&addr.sin_addr)[2], ((qbyte *)&addr.sin_addr)[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]); + baddr = (qbyte *)&addr.sin_addr; + + if (gethostname(name, sizeof(name)) != -1) + { + struct hostent *hent = gethostbyname(name); + if (hent) + baddr = hent->h_addr_list[0]; + } + + sprintf(s, "%i,%i,%i,%i,%i,%i", baddr[0], baddr[1], baddr[2], baddr[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]); + return true; +} +iwboolean FTP_SVRemoteSocketToString (int socket, char *s, int slen) +{ + struct sockaddr_qstorage addr; + netadr_t na; + int adrlen = sizeof(addr); + +// addr.sin_family = AF_INET; + if (getpeername(socket, (struct sockaddr*)&addr, &adrlen) == -1) + { + *s = 0; + return false; + } + + SockadrToNetadr(&addr, &na); + NET_AdrToString(s, slen, na); + +// if (((struct sockaddr_in*)&addr)->sin_family == AF_INET6) +// { +// } +// else +// sprintf(s, "%i,%i,%i,%i,%i,%i", ((qbyte *)&addr.sin_addr)[0], ((qbyte *)&addr.sin_addr)[1], ((qbyte *)&addr.sin_addr)[2], ((qbyte *)&addr.sin_addr)[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]); return true; } /* @@ -249,7 +306,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) char *msg, *line; char mode[64]; - static char resource[8192]; + char resource[8192]; int _true = true; if (cl->datadir == 1) @@ -444,6 +501,33 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) *p = '\0'; QueueMessage (cl, "200 directory changed.\r\n"); } + else if (!stricmp(mode, "EPSV")) + { + int aftype = 0; + //one argument, "1"=ipv4, "2"=ipv6. if not present, use same as control connection + //reply: "229 Entering Extended Passive Mode (|||$PORTNUM|)\r\n" + + if (!cl->auth) + { + QueueMessage (cl, "530 Not logged in.\r\n"); + continue; + } + if (cl->datasock != INVALID_SOCKET) + { + closesocket(cl->datasock); + cl->datasock = INVALID_SOCKET; + } + + cl->datasock = FTP_BeginListening(aftype, 0); + if (cl->datasock == INVALID_SOCKET) + QueueMessage (cl, "425 server was unable to make a listen socket\r\n"); + else + { + FTP_SVSocketPortToString(cl->datasock, resource); + QueueMessageva (cl, "229 Entering Extended Passive Mode (|||%s|).\r\n", resource); + } + cl->dataislisten = true; + } else if (!stricmp(mode, "PASV")) { if (!cl->auth) @@ -457,7 +541,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) cl->datasock = INVALID_SOCKET; } - cl->datasock = FTP_SV_makelistensocket(true); + cl->datasock = FTP_BeginListening(1, 0); if (cl->datasock == INVALID_SOCKET) QueueMessage (cl, "425 server was unable to make a listen socket\r\n"); else @@ -467,6 +551,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) } cl->dataislisten = true; } +// else if (!stricmp(mode, "EPRT")) +// { + //eg: one of: + //EPRT |1|132.235.1.2|6275| + //EPRT |2|1080::8:800:200C:417A|5282| + + //reply: 522 Network protocol not supported, use (1,2) +// } else if (!stricmp(mode, "PORT")) { if (!cl->auth) @@ -528,7 +620,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) int err; int _true = true; int temp; - struct sockaddr_in adr; + struct sockaddr_qstorage adr; int adrlen = sizeof(adr); temp = accept(cl->datasock, (struct sockaddr *)&adr, &adrlen); err = qerrno; @@ -538,7 +630,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) if (cl->datasock == INVALID_SOCKET) { - QueueMessageva (cl, "425 Your client connected too slowly - %i.\r\n", err); + QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", err); continue; } else @@ -561,8 +653,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) strcat(buffer, "*"); QueueMessage (cl, "125 Opening FAKE ASCII mode data connection for file.\r\n"); - ftpfilelistsocket = cl->datasock; - COM_EnumerateFiles(buffer, SendFileNameTo, NULL); + COM_EnumerateFiles(buffer, SendFileNameTo, &cl->datasock); QueueMessage (cl, "226 Transfer complete.\r\n"); @@ -593,7 +684,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) if (cl->datasock == INVALID_SOCKET) { - QueueMessageva (cl, "425 Your client connected too slowly - %i.\r\n", qerrno); + QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", qerrno); continue; } else @@ -672,7 +763,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) if (cl->datasock == INVALID_SOCKET) { - QueueMessageva (cl, "425 Your client connected too slowly - %i.\r\n", qerrno); + QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", qerrno); continue; } else @@ -776,7 +867,7 @@ unsigned int WINAPI BlockingClient(FTPclient_t *cl) iwboolean FTP_ServerRun(iwboolean ftpserverwanted, int port) { FTPclient_t *cl, *prevcl; - struct sockaddr_in from; + struct sockaddr_qstorage from; int fromlen; int clientsock; unsigned long _true = true; @@ -784,7 +875,15 @@ unsigned long _true = true; if (!ftpserverinitied) { if (ftpserverwanted) - return FTP_ServerInit(port); + { + ftpserversocket = FTP_BeginListening(0, port); + if (ftpserversocket == INVALID_SOCKET) + { + ftpserverfailed = true; + IWebPrintf("Unable to establish listening FTP socket\n"); + } + ftpserverinitied = true; + } return false; } else if (!ftpserverwanted) @@ -827,9 +926,12 @@ unsigned long _true = true; } fromlen = sizeof(from); - clientsock = accept(ftpserversocket, (struct sockaddr *)&from, &fromlen); + if (ftpserversocket == INVALID_SOCKET) + clientsock = INVALID_SOCKET; + else + clientsock = accept(ftpserversocket, (struct sockaddr *)&from, &fromlen); - if (clientsock == -1) + if (clientsock == INVALID_SOCKET) { if (qerrno == EWOULDBLOCK) return false; @@ -860,7 +962,7 @@ unsigned long _true = true; } { char resource[256]; - FTP_SVRemoteSocketToString(clientsock, resource); + FTP_SVRemoteSocketToString(clientsock, resource, sizeof(resource)); IWebPrintf("FTP connect from %s\n", resource); } cl->controlsock = clientsock; @@ -869,7 +971,7 @@ unsigned long _true = true; cl->blocking = false; strcpy(cl->path, "/"); - QueueMessage(cl, "220-QuakeWorld FTP Server.\r\n220 Welcomes all new users.\r\n"); + QueueMessage(cl, "220-" FULLENGINENAME " FTP Server.\r\n220 Welcomes all new users.\r\n"); #if defined(WEBSVONLY) && defined(_WIN32) if (!CreateThread(NULL, 128, BlockingClient, cl, 0, NULL)) diff --git a/engine/http/httpclient.c b/engine/http/httpclient.c index 67f3d77c..1b814a10 100644 --- a/engine/http/httpclient.c +++ b/engine/http/httpclient.c @@ -513,8 +513,10 @@ qboolean DL_CreateThread(struct dl_download *dl, vfsfile_t *file, void (*NotifyF if (!dl) return false; - dl->file = file; - dl->notify = NotifyFunction; + if (file) + dl->file = file; + if (NotifyFunction) + dl->notify = NotifyFunction; dl->threadctx = Sys_CreateThread("download", DL_Thread_Work, dl, THREADP_NORMAL, 0); if (!dl->threadctx) @@ -599,11 +601,11 @@ void HTTP_CL_Think(void) #endif if (!con->poll(con)) { + *link = con->next; if (con->file) VFS_SEEK(con->file, 0); if (con->notify) con->notify(con); - *link = con->next; DL_Close(con); if (cls.downloadmethod == DL_HTTP) diff --git a/engine/qclib/Makefile b/engine/qclib/Makefile index 786d22e3..4c69b0b8 100644 --- a/engine/qclib/Makefile +++ b/engine/qclib/Makefile @@ -86,5 +86,7 @@ test.o: test.c testapp.bin: qcvm.so test.o $(CC) $(BASE_CFLAGS) -o testapp.bin -O3 $(BASE_LDFLAGS) qcvm.so test.o -regressiontest: testapp.bin - ./testapp.bin regression.dat -srcfile regression.src +tests: testapp.bin + @$(foreach a,$(wildcard tests/*.src), echo TEST: $a; ./testapp.bin progs.dat -srcfile $a; echo; echo) + +.PHONY: tests \ No newline at end of file diff --git a/engine/qclib/cmdlib.h b/engine/qclib/cmdlib.h index 768d899a..418b48ad 100644 --- a/engine/qclib/cmdlib.h +++ b/engine/qclib/cmdlib.h @@ -89,5 +89,8 @@ extern char qcc_token[1024]; extern int qcc_eof; +#define qcc_iswhite(c) ((c) == ' ' || (c) == '\r' || (c) == '\n' || (c) == '\t' || (c) == '\v') +#define qcc_iswhitesameline(c) ((c) == ' ' || (c) == '\t') + #endif diff --git a/engine/qclib/comprout.c b/engine/qclib/comprout.c index 6a46203b..a5efa169 100644 --- a/engine/qclib/comprout.c +++ b/engine/qclib/comprout.c @@ -48,6 +48,7 @@ void PostCompile(void) { if (!qccpersisthunk) qccClearHunk(); + QCC_PR_CloseProcessor(); if (asmfile) { @@ -92,7 +93,7 @@ pbool CompileParams(progfuncs_t *progfuncs, int doall, int nump, char **parms) if (!externs->useeditor) printf("Error in %s on line %i\n", errorfile, errorline); else - externs->useeditor(progfuncs, errorfile, errorline, 0, nump, parms); + externs->useeditor(&progfuncs->funcs, errorfile, errorline, 0, nump, parms); } return false; } @@ -108,17 +109,17 @@ pbool CompileParams(progfuncs_t *progfuncs, int doall, int nump, char **parms) return true; } -int Comp_Begin(progfuncs_t *progfuncs, int nump, char **parms) +int PDECL Comp_Begin(pubprogfuncs_t *progfuncs, int nump, char **parms) { comp_nump = nump; comp_parms = parms; - qccprogfuncs = progfuncs; + qccprogfuncs = (progfuncs_t*)progfuncs; *errorfile = '\0'; if (setjmp(qcccompileerror)) { PostCompile(); if (*errorfile) - externs->useeditor(progfuncs, errorfile, errorline, 0, nump, parms); + progfuncs->parms->useeditor(&qccprogfuncs->funcs, errorfile, errorline, 0, nump, parms); return false; } @@ -128,14 +129,14 @@ int Comp_Begin(progfuncs_t *progfuncs, int nump, char **parms) return true; } -int Comp_Continue(progfuncs_t *progfuncs) +int PDECL Comp_Continue(pubprogfuncs_t *progfuncs) { - qccprogfuncs = progfuncs; + qccprogfuncs = (progfuncs_t *)progfuncs; if (setjmp(qcccompileerror)) { PostCompile(); - if (*errorfile && externs->useeditor) - externs->useeditor(progfuncs, errorfile, errorline, 0, comp_nump, comp_parms); + if (*errorfile && progfuncs->parms->useeditor) + progfuncs->parms->useeditor(progfuncs, errorfile, errorline, 0, comp_nump, comp_parms); return false; } @@ -145,8 +146,8 @@ int Comp_Continue(progfuncs_t *progfuncs) { PostCompile(); - if (*errorfile && externs->useeditor) - externs->useeditor(progfuncs, errorfile, errorline, 0 , comp_nump, comp_parms); + if (*errorfile && progfuncs->parms->useeditor) + progfuncs->parms->useeditor(progfuncs, errorfile, errorline, 0 , comp_nump, comp_parms); return false; } diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 970465dd..45392a4b 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -36,14 +36,16 @@ #endif #ifdef DEBUGABLE -#define OPCODE (pr_trace?(st->op & ~0x8000):st->op) +#define OPCODE (progfuncs->funcs.pr_trace?(st->op & ~0x8000):st->op) #else #define OPCODE (st->op) #endif -#define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable) -#define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable) -#define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable) +#define ENGINEPOINTER(p) ((char*)(p) - progfuncs->funcs.stringtable) +#define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->funcs.stringtable) +#define QCPOINTERM(p) (eval_t *)((p)+progfuncs->funcs.stringtable) +#define QCPOINTERWRITEFAIL(p) ((unsigned int)p->_int-1 >= prinst.addressableused-1) //disallows null writes +#define QCPOINTERREADFAIL(p) ((unsigned int)p->_int >= prinst.addressableused) //permits null writes //rely upon just st { @@ -52,30 +54,30 @@ cont: //last statement may have been a breakpoint s = st-pr_statements; s+=1; - if (prinst->watch_ptr && prinst->watch_ptr->_int != prinst->watch_old._int) + if (prinst.watch_ptr && prinst.watch_ptr->_int != prinst.watch_old._int) { //this will fire on the next instruction after the variable got changed. pr_xstatement = s; - switch(prinst->watch_type) + switch(prinst.watch_type) { case ev_float: - printf("Watch point hit in %s, \"%s\" changed from %g to %g.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), prinst->watch_name, prinst->watch_old._float, prinst->watch_ptr->_float); + printf("Watch point hit in %s, \"%s\" changed from %g to %g.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name, prinst.watch_old._float, prinst.watch_ptr->_float); break; default: - printf("Watch point hit in %s, \"%s\" changed from %i to %i.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), prinst->watch_name, prinst->watch_old._int, prinst->watch_ptr->_int); + printf("Watch point hit in %s, \"%s\" changed from %i to %i.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name, prinst.watch_old._int, prinst.watch_ptr->_int); break; case ev_function: case ev_string: - printf("Watch point hit in %s, \"%s\" now set to %s.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), prinst->watch_name, PR_ValueString(progfuncs, prinst->watch_type, prinst->watch_ptr)); + printf("Watch point hit in %s, \"%s\" now set to %s.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name, PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr)); break; } - prinst->watch_old = *prinst->watch_ptr; -// prinst->watch_ptr = NULL; - if (pr_trace<1) - pr_trace=1; //this is what it's for + prinst.watch_old = *prinst.watch_ptr; +// prinst.watch_ptr = NULL; + if (progfuncs->funcs.pr_trace<1) + progfuncs->funcs.pr_trace=1; //this is what it's for } - if (pr_trace) + if (progfuncs->funcs.pr_trace) s=ShowStep(progfuncs, s); st = pr_statements + s; @@ -112,23 +114,26 @@ reeval: + OPA->_vector[2]*OPB->_vector[2]; break; case OP_MUL_FV: - OPC->_vector[0] = OPA->_float * OPB->_vector[0]; - OPC->_vector[1] = OPA->_float * OPB->_vector[1]; - OPC->_vector[2] = OPA->_float * OPB->_vector[2]; + tmpf = OPA->_float; + OPC->_vector[0] = tmpf * OPB->_vector[0]; + OPC->_vector[1] = tmpf * OPB->_vector[1]; + OPC->_vector[2] = tmpf * OPB->_vector[2]; break; case OP_MUL_VF: - OPC->_vector[0] = OPB->_float * OPA->_vector[0]; - OPC->_vector[1] = OPB->_float * OPA->_vector[1]; - OPC->_vector[2] = OPB->_float * OPA->_vector[2]; + tmpf = OPB->_float; + OPC->_vector[0] = tmpf * OPA->_vector[0]; + OPC->_vector[1] = tmpf * OPA->_vector[1]; + OPC->_vector[2] = tmpf * OPA->_vector[2]; break; case OP_DIV_F: OPC->_float = OPA->_float / OPB->_float; break; case OP_DIV_VF: - OPC->_vector[0] = OPB->_float / OPA->_vector[0]; - OPC->_vector[1] = OPB->_float / OPA->_vector[1]; - OPC->_vector[2] = OPB->_float / OPA->_vector[2]; + tmpf = OPB->_float; + OPC->_vector[0] = tmpf / OPA->_vector[0]; + OPC->_vector[1] = tmpf / OPA->_vector[1]; + OPC->_vector[2] = tmpf / OPA->_vector[2]; break; case OP_BITAND_F: @@ -206,7 +211,7 @@ reeval: OPC->_float = (float)(!OPA->_vector[0] && !OPA->_vector[1] && !OPA->_vector[2]); break; case OP_NOT_S: - OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(progfuncs, OPA->string)); + OPC->_float = (float)(!(OPA->string) || !*PR_StringToNative(&progfuncs->funcs, OPA->string)); break; case OP_NOT_FNC: OPC->_float = (float)(!(OPA->function & ~0xff000000)); @@ -236,20 +241,20 @@ reeval: OPC->_float = true; else if (!OPA->string) { - if (!OPB->string || !*PR_StringToNative(progfuncs, OPB->string)) + if (!OPB->string || !*PR_StringToNative(&progfuncs->funcs, OPB->string)) OPC->_float = true; else OPC->_float = false; } else if (!OPB->string) { - if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string)) + if (!OPA->string || !*PR_StringToNative(&progfuncs->funcs, OPA->string)) OPC->_float = true; else OPC->_float = false; } else - OPC->_float = (float)(!strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string))); + OPC->_float = (float)(!strcmp(PR_StringToNative(&progfuncs->funcs, OPA->string),PR_StringToNative(&progfuncs->funcs, OPB->string))); break; case OP_EQ_E: OPC->_float = (float)(OPA->_int == OPB->_int); @@ -272,20 +277,20 @@ reeval: OPC->_float = false; else if (!OPA->string) { - if (!OPB->string || !*(PR_StringToNative(progfuncs, OPB->string))) + if (!OPB->string || !*(PR_StringToNative(&progfuncs->funcs, OPB->string))) OPC->_float = false; else OPC->_float = true; } else if (!OPB->string) { - if (!OPA->string || !*PR_StringToNative(progfuncs, OPA->string)) + if (!OPA->string || !*PR_StringToNative(&progfuncs->funcs, OPA->string)) OPC->_float = false; else OPC->_float = true; } else - OPC->_float = (float)(strcmp(PR_StringToNative(progfuncs, OPA->string),PR_StringToNative(progfuncs, OPB->string))); + OPC->_float = (float)(strcmp(PR_StringToNative(&progfuncs->funcs, OPA->string),PR_StringToNative(&progfuncs->funcs, OPB->string))); break; case OP_NE_E: OPC->_float = (float)(OPA->_int != OPB->_int); @@ -319,19 +324,19 @@ reeval: //store a value to a pointer case OP_STOREP_IF: - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); ptr->_float = (float)OPA->_int; break; case OP_STOREP_FI: - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); ptr->_int = (int)OPA->_float; @@ -348,20 +353,20 @@ reeval: case OP_GSTOREP_S: case OP_STOREP_FNC: // pointers case OP_GSTOREP_FNC: - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(progfuncs, pr_xfunction->s_name), OPB->_int, prinst->addressableused); + 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->_int = OPA->_int; break; case OP_STOREP_V: case OP_GSTOREP_V: - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); ptr->_vector[0] = OPA->_vector[0]; @@ -370,10 +375,10 @@ reeval: break; case OP_STOREP_C: //store character in a string - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); *(unsigned char *)ptr = (char)OPA->_float; @@ -383,39 +388,41 @@ reeval: OPB->_float *= OPA->_float; break; case OP_MULSTORE_VF: // v *= f - OPB->_vector[0] *= OPA->_float; - OPB->_vector[1] *= OPA->_float; - OPB->_vector[2] *= OPA->_float; + tmpf = OPA->_float; + OPB->_vector[0] *= tmpf; + OPB->_vector[1] *= tmpf; + OPB->_vector[2] *= tmpf; break; case OP_MULSTOREP_F: // e.f *= f - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_float = (ptr->_float *= OPA->_float); break; case OP_MULSTOREP_VF: // e.v *= f - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } + tmpf = OPA->_float; ptr = QCPOINTER(OPB); - OPC->_vector[0] = (ptr->_vector[0] *= OPA->_float); - OPC->_vector[0] = (ptr->_vector[1] *= OPA->_float); - OPC->_vector[0] = (ptr->_vector[2] *= OPA->_float); + OPC->_vector[0] = (ptr->_vector[0] *= tmpf); + OPC->_vector[0] = (ptr->_vector[1] *= tmpf); + OPC->_vector[0] = (ptr->_vector[2] *= tmpf); break; case OP_DIVSTORE_F: // f /= f OPB->_float /= OPA->_float; break; case OP_DIVSTOREP_F: // e.f /= f - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_float = (ptr->_float /= OPA->_float); @@ -430,19 +437,19 @@ reeval: OPB->_vector[2] += OPA->_vector[2]; break; case OP_ADDSTOREP_F: // e.f += f - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_float = (ptr->_float += OPA->_float); break; case OP_ADDSTOREP_V: // e.v += v - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_vector[0] = (ptr->_vector[0] += OPA->_vector[0]); @@ -459,19 +466,19 @@ reeval: OPB->_vector[2] -= OPA->_vector[2]; break; case OP_SUBSTOREP_F: // e.f -= f - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_float = (ptr->_float -= OPA->_float); break; case OP_SUBSTOREP_V: // e.v -= v - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); OPC->_vector[0] = (ptr->_vector[0] -= OPA->_vector[0]); @@ -485,12 +492,12 @@ reeval: if ((unsigned)OPA->edict >= (unsigned)maxedicts) { #ifndef DEBUGABLE - pr_trace++; - printf("OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + progfuncs->funcs.pr_trace++; + printf("OP_ADDRESS references invalid entity in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); st--; goto cont; #else - PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); #endif } ed = PROG_TO_EDICT(progfuncs, OPA->edict); @@ -502,8 +509,8 @@ reeval: pr_xstatement = st-pr_statements; #ifndef DEBUGABLE //boot it over to the debugger - pr_trace++; - printf("assignment to read-only entity in %s\n", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + progfuncs->funcs.pr_trace++; + printf("assignment to read-only entity in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); st--; goto cont; #else @@ -511,8 +518,8 @@ reeval: ddef16_t *d16; fdef_t *f; d16 = ED_GlobalAtOfs16(progfuncs, st->a); - f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust); - printf ("assignment to read-only entity in %s (%s.%s)\n", PR_StringToNative(progfuncs, pr_xfunction->s_name), d16?PR_StringToNative(progfuncs, d16->s_name):NULL, f?f->name:NULL); + f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust); + printf ("assignment to read-only entity in %s (%s.%s)\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), d16?PR_StringToNative(&progfuncs->funcs, d16->s_name):NULL, f?f->name:NULL); } #endif } @@ -523,7 +530,7 @@ reeval: // pr_xstatement = st-pr_statements; // PR_RunError (progfuncs, "assignment to free entitiy in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); // } - OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust)); + OPC->_int = ENGINEPOINTER((((int *)edvars(ed)) + OPB->_int + progfuncs->funcs.fieldadjust)); break; //load a field to a value @@ -534,23 +541,23 @@ reeval: case OP_LOAD_S: case OP_LOAD_FNC: if ((unsigned)OPA->edict >= (unsigned)maxedicts) - PR_RunError (progfuncs, "OP_LOAD references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "OP_LOAD references invalid entity in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); ed = PROG_TO_EDICT(progfuncs, OPA->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // make sure it's in range #endif - ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust); + ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->funcs.fieldadjust); OPC->_int = ptr->_int; break; case OP_LOAD_V: if ((unsigned)OPA->edict >= (unsigned)maxedicts) - PR_RunError (progfuncs, "OP_LOAD_V references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "OP_LOAD_V references invalid entity in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); ed = PROG_TO_EDICT(progfuncs, OPA->edict); #ifdef PARANOID NUM_FOR_EDICT(ed); // make sure it's in range #endif - ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->fieldadjust); + ptr = (eval_t *)(((int *)edvars(ed)) + OPB->_int + progfuncs->funcs.fieldadjust); OPC->_vector[0] = ptr->_vector[0]; OPC->_vector[1] = ptr->_vector[1]; OPC->_vector[2] = ptr->_vector[2]; @@ -560,7 +567,7 @@ reeval: case OP_IFNOT_S: RUNAWAYCHECK(); - if (!OPA->string || !PR_StringToNative(progfuncs, OPA->string)) + if (!OPA->string || !PR_StringToNative(&progfuncs->funcs, OPA->string)) st += (sofs)st->b - 1; // offset the s++ break; @@ -578,7 +585,7 @@ reeval: case OP_IF_S: RUNAWAYCHECK(); - if (OPA->string && PR_StringToNative(progfuncs, OPA->string)) + if (OPA->string && PR_StringToNative(&progfuncs->funcs, OPA->string)) st += (sofs)st->b - 1; // offset the s++ break; @@ -631,9 +638,9 @@ reeval: pr_xstatement = st-pr_statements; if (OPCODE > OP_CALL8) - pr_argc = OPCODE - (OP_CALL1H-1); + progfuncs->funcs.callargc = OPCODE - (OP_CALL1H-1); else - pr_argc = OPCODE - OP_CALL0; + progfuncs->funcs.callargc = OPCODE - OP_CALL0; fnum = OPA->function; callerprogs=pr_typecurrent; //so we can revert to the right caller. @@ -647,9 +654,9 @@ reeval: PR_SwitchProgsParms(progfuncs, callerprogs); //break/skip the instruction. - printf(msg, PR_StringToNative(progfuncs, pr_xfunction->s_name)); + printf(msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); #ifndef DEBUGABLE - pr_trace++; + progfuncs->funcs.pr_trace++; st--; goto cont; #else @@ -671,15 +678,15 @@ reeval: } i = -newf->first_statement; // p = pr_typecurrent; - progfuncs->lastcalledbuiltinnumber = i; + progfuncs->funcs.lastcalledbuiltinnumber = i; if (i < externs->numglobalbuiltins) { - prinst->numtempstringsstack = prinst->numtempstrings; - (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); - if (prinst->continuestatement!=-1) + prinst.numtempstringsstack = prinst.numtempstrings; + (*externs->globalbuiltins[i]) (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals); + if (prinst.continuestatement!=-1) { - st=&pr_statements[prinst->continuestatement]; - prinst->continuestatement=-1; + st=&pr_statements[prinst.continuestatement]; + prinst.continuestatement=-1; break; } } @@ -691,10 +698,10 @@ reeval: // if (newf->first_statement == -0x7fffffff) // ((builtin_t)newf->profile) (progfuncs, (struct globalvars_s *)current_progstate->globals); // else - PR_RunError (progfuncs, "Bad builtin call number - %i", -newf->first_statement); + PR_RunError (&progfuncs->funcs, "Bad builtin call number - %i", -newf->first_statement); } else - current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals); + current_progstate->builtins [i] (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals); } // memcpy(&pr_progstate[p].globals[OFS_RETURN], ¤t_progstate->globals[OFS_RETURN], sizeof(vec3_t)); PR_SwitchProgsParms(progfuncs, (progsnum_t)callerprogs); @@ -730,7 +737,7 @@ reeval: */ s = PR_LeaveFunction (progfuncs); st = &pr_statements[s]; - if (pr_depth == prinst->exitdepth) + if (pr_depth == prinst.exitdepth) { return; // all done } @@ -738,7 +745,7 @@ reeval: // break; case OP_STATE: - externs->stateop(progfuncs, OPA->_float, OPB->function); + externs->stateop(&progfuncs->funcs, OPA->_float, OPB->function); break; case OP_ADD_I: @@ -838,14 +845,14 @@ reeval: break; case OP_LOADP_C: //load character from a string i = (unsigned int)OPA->_int + (unsigned int)OPB->_float; - if ((unsigned int)i >= prinst->addressableused) + if ((unsigned int)i >= prinst.addressableused) { i = (unsigned int)OPB->_float; - ptr = (eval_t*)PR_StringToNative(progfuncs, OPA->_int); + ptr = (eval_t*)PR_StringToNative(&progfuncs->funcs, OPA->_int); if ((size_t)i > strlen((char*)ptr)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), i, ptr); + PR_RunError (&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, ptr); } ptr = (eval_t*)((char*)ptr + i); } @@ -860,10 +867,10 @@ reeval: case OP_LOADP_S: case OP_LOADP_FNC: i = OPA->_int + OPB->_int*4; - if ((unsigned int)i >= prinst->addressableused) + if ((unsigned int)i >= prinst.addressableused) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer read in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTERM(OPA->_int + OPB->_int*4); OPC->_int = ptr->_int; @@ -871,10 +878,10 @@ reeval: case OP_LOADP_V: i = OPA->_int + OPB->_int*4; - if ((unsigned int)i >= prinst->addressableused) + if ((unsigned int)i >= prinst.addressableused) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer read in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTERM(i); OPC->_vector[0] = ptr->_vector[0]; @@ -900,7 +907,7 @@ reeval: i = (int)OPB->_float; if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int) { - PR_RunError(progfuncs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int); + PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int); } t = (eval_t *)&pr_globals[(uofs)st->a + i]; OPC->_int = t->_int; @@ -909,7 +916,8 @@ reeval: i = (int)OPB->_float; if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int) { - PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i); + pr_xstatement = st-pr_statements; + PR_RunError(&progfuncs->funcs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i); } t = (eval_t *)&pr_globals[(uofs)st->a + i*3]; OPC->_vector[0] = t->_vector[0]; @@ -918,15 +926,15 @@ reeval: break; case OP_CSTATE: - externs->cstateop(progfuncs, OPA->_float, OPB->_float, pr_xfunction - pr_functions); + externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_functions); break; case OP_CWSTATE: - externs->cwstateop(progfuncs, OPA->_float, OPB->_float, pr_xfunction - pr_functions); + externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_functions); break; case OP_THINKTIME: - externs->thinktimeop(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, OPA->edict), OPB->_float); + externs->thinktimeop(&progfuncs->funcs, (struct edict_s *)PROG_TO_EDICT(progfuncs, OPA->edict), OPB->_float); break; @@ -934,10 +942,10 @@ reeval: OPB->_float = (float)((int)OPB->_float | (int)OPA->_float); break; case OP_BITSETP: // .b (+) a - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); ptr->_float = (float)((int)ptr->_float | (int)OPA->_float); @@ -946,10 +954,10 @@ reeval: OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float)); break; case OP_BITCLRP: // .b (-) a - if ((unsigned int)OPB->_int >= prinst->addressableused) + if (QCPOINTERWRITEFAIL(OPB)) { pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "bad pointer write in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); } ptr = QCPOINTER(OPB); ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float)); @@ -1034,9 +1042,9 @@ reeval: RUNAWAYCHECK(); st += (sofs)st->b-1; // -1 to offset the s++ } - if ((!swtch->_int && PR_StringToNative(progfuncs, OPA->string)) || (!OPA->_int && PR_StringToNative(progfuncs, swtch->string))) //one is null (cannot be not both). + if ((!swtch->_int && PR_StringToNative(&progfuncs->funcs, OPA->string)) || (!OPA->_int && PR_StringToNative(&progfuncs->funcs, swtch->string))) //one is null (cannot be not both). break; - if (!strcmp(PR_StringToNative(progfuncs, swtch->string), PR_StringToNative(progfuncs, OPA->string))) + if (!strcmp(PR_StringToNative(&progfuncs->funcs, swtch->string), PR_StringToNative(&progfuncs->funcs, OPA->string))) { RUNAWAYCHECK(); st += (sofs)st->b-1; // -1 to offset the s++ @@ -1050,7 +1058,7 @@ reeval: } break; default: - PR_RunError (progfuncs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype); + PR_RunError (&progfuncs->funcs, "OP_CASE with bad/missing OP_SWITCH %i", swtchtype); break; } break; @@ -1065,7 +1073,7 @@ reeval: } break; default: - PR_RunError (progfuncs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype); + PR_RunError (&progfuncs->funcs, "OP_CASERANGE with bad/missing OP_SWITCH %i", swtchtype); } break; @@ -1098,14 +1106,16 @@ reeval: break; case OP_MUL_VI: - OPC->_vector[0] = OPA->_vector[0] * OPB->_int; - OPC->_vector[1] = OPA->_vector[0] * OPB->_int; - OPC->_vector[2] = OPA->_vector[0] * OPB->_int; + tmpi = OPB->_int; + OPC->_vector[0] = OPA->_vector[0] * tmpi; + OPC->_vector[1] = OPA->_vector[0] * tmpi; + OPC->_vector[2] = OPA->_vector[0] * tmpi; break; case OP_MUL_IV: - OPC->_vector[0] = OPB->_int * OPA->_vector[0]; - OPC->_vector[1] = OPB->_int * OPA->_vector[1]; - OPC->_vector[2] = OPB->_int * OPA->_vector[2]; + tmpi = OPA->_int; + OPC->_vector[0] = tmpi * OPB->_vector[0]; + OPC->_vector[1] = tmpi * OPB->_vector[1]; + OPC->_vector[2] = tmpi * OPB->_vector[2]; break; case OP_DIV_IF: @@ -1155,14 +1165,18 @@ reeval: case OP_GLOAD_S: case OP_GLOAD_FNC: pr_xstatement = st-pr_statements; - PR_RunError(progfuncs, "Extra opcode not implemented\n"); + PR_RunError(&progfuncs->funcs, "Extra opcode not implemented\n"); break; case OP_BOUNDCHECK: if ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b) { - pr_xstatement = st-pr_statements; - PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i. Must be between %u and %u", OPA->_int, st->c, st->b); + printf("Progs boundcheck failed. Value is %i. Must be between %u and %u\n", OPA->_int, st->c, st->b); + s=ShowStep(progfuncs, st - pr_statements); + if (st == pr_statements + s) + PR_RunError(&progfuncs->funcs, "unable to resume boundcheck"); + st = pr_statements + s; + goto restart; } break; /* case OP_PUSH: @@ -1190,9 +1204,9 @@ reeval: { pr_xstatement = s = st-pr_statements; - printf("Break point hit in %s.\n", PR_StringToNative(progfuncs, pr_xfunction->s_name)); - if (pr_trace<1) - pr_trace=1; //this is what it's for + printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + if (progfuncs->funcs.pr_trace<1) + progfuncs->funcs.pr_trace=1; //this is what it's for s = ShowStep(progfuncs, s); st = &pr_statements[s]; //let the user move execution @@ -1201,7 +1215,7 @@ reeval: goto reeval; //reexecute } pr_xstatement = st-pr_statements; - PR_RunError (progfuncs, "Bad opcode %i", st->op); + PR_RunError (&progfuncs->funcs, "Bad opcode %i", st->op); } } diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 31266e6b..94932e54 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -1,16 +1,15 @@ #define PROGSUSED #include "progsint.h" #include - typedef struct prmemb_s { struct prmemb_s *prev; int level; } prmemb_t; -void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount) +void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, char *name) { prmemb_t *mem; ammount = sizeof(prmemb_t)+((ammount + 3)&~3); - mem = memalloc(ammount); + mem = progfuncs->funcs.parms->memalloc(ammount); memset(mem, 0, ammount); mem->prev = memb; if (!memb) @@ -21,6 +20,10 @@ void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount) return ((char *)mem)+sizeof(prmemb_t); } +void *PDECL QC_HunkAlloc(pubprogfuncs_t *ppf, int ammount, char *name) +{ + return PRHunkAlloc((progfuncs_t*)ppf, ammount, name); +} int PRHunkMark(progfuncs_t *progfuncs) { @@ -36,7 +39,7 @@ void PRHunkFree(progfuncs_t *progfuncs, int mark) omem = memb; memb = memb->prev; - memfree(omem); + externs->memfree(omem); } return; } @@ -48,29 +51,29 @@ void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int o edictrun_t *e; for (i=0 ; iedicttable[i]); + e = (edictrun_t *)(prinst.edicttable[i]); if (e && (char*)e->fields >= oldb && (char*)e->fields < oldb+oldlen) e->fields = ((char*)e->fields - oldb) + newb; } - if (progfuncs->stringtable >= oldb && progfuncs->stringtable < oldb+oldlen) - progfuncs->stringtable = (progfuncs->stringtable - oldb) + newb; + if (progfuncs->funcs.stringtable >= oldb && progfuncs->funcs.stringtable < oldb+oldlen) + progfuncs->funcs.stringtable = (progfuncs->funcs.stringtable - oldb) + newb; for (i=0; i < maxprogs; i++) { - if ((char*)prinst->progstate[i].globals >= oldb && (char*)prinst->progstate[i].globals < oldb+oldlen) - prinst->progstate[i].globals = (float*)(((char*)prinst->progstate[i].globals - oldb) + newb); - if (prinst->progstate[i].strings >= oldb && prinst->progstate[i].strings < oldb+oldlen) - prinst->progstate[i].strings = (prinst->progstate[i].strings - oldb) + newb; + if ((char*)prinst.progstate[i].globals >= oldb && (char*)prinst.progstate[i].globals < oldb+oldlen) + prinst.progstate[i].globals = (float*)(((char*)prinst.progstate[i].globals - oldb) + newb); + if (prinst.progstate[i].strings >= oldb && prinst.progstate[i].strings < oldb+oldlen) + prinst.progstate[i].strings = (prinst.progstate[i].strings - oldb) + newb; } - for (i = 0; i < numfields; i++) + for (i = 0; i < prinst.numfields; i++) { - if (field[i].name >= oldb && field[i].name < oldb+oldlen) - field[i].name = (field[i].name - oldb) + newb; + if (prinst.field[i].name >= oldb && prinst.field[i].name < oldb+oldlen) + prinst.field[i].name = (prinst.field[i].name - oldb) + newb; } - externs->addressablerelocated(progfuncs, oldb, newb, oldlen); + externs->addressablerelocated(&progfuncs->funcs, oldb, newb, oldlen); } //for 64bit systems. :) @@ -79,7 +82,7 @@ void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int o void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount) { ammount = (ammount + 4)&~3; //round up to 4 - if (prinst->addressableused + ammount > prinst->addressablesize) + if (prinst.addressableused + ammount > prinst.addressablesize) { /*only do this if the caller states that it can cope with addressable-block relocations/resizes*/ if (externs->addressablerelocated) @@ -89,46 +92,46 @@ void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount) #if 0//def _DEBUG int oldtot = addressablesize; #endif - int newsize = (prinst->addressableused + ammount + 4096) & ~(4096-1); - newblock = VirtualAlloc (NULL, prinst->addressablesize, MEM_RESERVE, PAGE_NOACCESS); + int newsize = (prinst.addressableused + ammount + 4096) & ~(4096-1); + newblock = VirtualAlloc (NULL, prinst.addressablesize, MEM_RESERVE, PAGE_NOACCESS); if (newblock) { - VirtualAlloc (newblock, prinst->addressableused, MEM_COMMIT, PAGE_READWRITE); - memcpy(newblock, prinst->addressablehunk, prinst->addressableused); + VirtualAlloc (newblock, prinst.addressableused, MEM_COMMIT, PAGE_READWRITE); + memcpy(newblock, prinst.addressablehunk, prinst.addressableused); #if 0//def _DEBUG - VirtualAlloc (prinst->addressablehunk, oldtot, MEM_RESERVE, PAGE_NOACCESS); + VirtualAlloc (prinst.addressablehunk, oldtot, MEM_RESERVE, PAGE_NOACCESS); #else - VirtualFree (prinst->addressablehunk, 0, MEM_RELEASE); + VirtualFree (prinst.addressablehunk, 0, MEM_RELEASE); #endif - PRAddressableRelocate(progfuncs, prinst->addressablehunk, newblock, prinst->addressableused); - prinst->addressablehunk = newblock; - prinst->addressablesize = newsize; + PRAddressableRelocate(progfuncs, prinst.addressablehunk, newblock, prinst.addressableused); + prinst.addressablehunk = newblock; + prinst.addressablesize = newsize; } #else char *newblock; - int newsize = (prinst->addressableused + ammount + 1024*1024) & ~(1024*1024-1); - newblock = realloc(newblock, prinst->addressablesize); + int newsize = (prinst.addressableused + ammount + 1024*1024) & ~(1024*1024-1); + newblock = realloc(newblock, prinst.addressablesize); if (newblock) { - PRAddressableRelocate(progfuncs, prinst->addressablehunk, newblock, prinst->addressableused); - prinst->addressablehunk = newblock; - prinst->addressablesize = newsize; + PRAddressableRelocate(progfuncs, prinst.addressablehunk, newblock, prinst.addressableused); + prinst.addressablehunk = newblock; + prinst.addressablesize = newsize; } #endif } - if (prinst->addressableused + ammount > prinst->addressablesize) + if (prinst.addressableused + ammount > prinst.addressablesize) Sys_Error("Not enough addressable memory for progs VM"); } - prinst->addressableused += ammount; + prinst.addressableused += ammount; #ifdef _WIN32 - if (!VirtualAlloc (prinst->addressablehunk, prinst->addressableused, MEM_COMMIT, PAGE_READWRITE)) + if (!VirtualAlloc (prinst.addressablehunk, prinst.addressableused, MEM_COMMIT, PAGE_READWRITE)) Sys_Error("VirtualAlloc failed. Blame windows."); #endif - return &prinst->addressablehunk[prinst->addressableused-ammount]; + return &prinst.addressablehunk[prinst.addressableused-ammount]; } @@ -149,14 +152,14 @@ static void PF_fmem_unlink(progfuncs_t *pr, qcmemfreeblock_t *p) qcmemfreeblock_t *np; if (p->prev) { - np = (qcmemfreeblock_t*)(pr->stringtable + p->prev); + np = (qcmemfreeblock_t*)(pr->funcs.stringtable + p->prev); np->next = p->next; } else - pr->inst->mfreelist = p->next; + pr->inst.mfreelist = p->next; if (p->next) { - np = (qcmemfreeblock_t*)(pr->stringtable + p->next); + np = (qcmemfreeblock_t*)(pr->funcs.stringtable + p->next); np->prev = p->prev; } } @@ -166,59 +169,60 @@ static void PR_memvalidate (progfuncs_t *progfuncs) qcmemusedblock_t *ub = NULL; unsigned int b,l; - b = prinst->mfreelist; + b = prinst.mfreelist; l = 0; while (b) { - if (b < 0 || b >= prinst->addressableused) + if (b < 0 || b >= prinst.addressableused) { printf("PF_memalloc: memory corruption\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return; } - p = (qcmemfreeblock_t*)(progfuncs->stringtable + b); + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + b); if (p->prev != l || p->next && p->next < b + p->size || - p->next >= prinst->addressableused || - b + p->size >= prinst->addressableused || + p->next >= prinst.addressableused || + b + p->size >= prinst.addressableused || p->prev >= b) { printf("PF_memalloc: memory corruption\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return; } l = b; b = p->next; } } -static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size) +static void *PDECL PR_memalloc (pubprogfuncs_t *ppf, unsigned int size) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; qcmemfreeblock_t *p, *np; qcmemusedblock_t *ub = NULL; unsigned int b,n; /*round size up*/ size = (size+sizeof(qcmemusedblock_t) + 63) & ~63; - b = prinst->mfreelist; + b = prinst.mfreelist; while (b) { - if (b < 0 || b >= prinst->addressableused) + if (b < 0 || b >= prinst.addressableused) { printf("PF_memalloc: memory corruption\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return NULL; } - p = (qcmemfreeblock_t*)(progfuncs->stringtable + b); + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + b); if (p->size >= size) { if (p->next && p->next < b + p->size || - p->next >= prinst->addressableused || - b + p->size >= prinst->addressableused || + p->next >= prinst.addressableused || + b + p->size >= prinst.addressableused || p->prev >= b) { printf("PF_memalloc: memory corruption\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return NULL; } @@ -227,20 +231,20 @@ static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size) { /*make a new header just after it, with basically the same properties, and shift the important fields over*/ n = b + size; - np = (qcmemfreeblock_t*)(progfuncs->stringtable + b + size); + np = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + b + size); np->prev = p->prev; np->next = p->next; np->size = p->size - size; if (np->prev) { - p = (qcmemfreeblock_t*)(progfuncs->stringtable + np->prev); + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + np->prev); p->next = n; } else - prinst->mfreelist = n; + prinst.mfreelist = n; if (p->next) { - p = (qcmemfreeblock_t*)(progfuncs->stringtable + np->next); + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + np->next); p->prev = n; } } @@ -262,7 +266,7 @@ static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size) if (!ub) { printf("PF_memalloc: memory exausted\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return NULL; } } @@ -274,66 +278,67 @@ static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size) return ub+1; } -static void PR_memfree (progfuncs_t *progfuncs, void *memptr) +static void PDECL PR_memfree (pubprogfuncs_t *ppf, void *memptr) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; qcmemusedblock_t *ub; qcmemfreeblock_t *p, *np, *pp; unsigned int pa, na; //prev addr, next addr unsigned int size; - unsigned int ptr = memptr?((char*)memptr - progfuncs->stringtable):0; + unsigned int ptr = memptr?((char*)memptr - progfuncs->funcs.stringtable):0; /*freeing NULL is ignored*/ if (!ptr) return; // PR_memvalidate(progfuncs); - if (ptr < sizeof(qcmemusedblock_t) || ptr >= prinst->addressableused) + if (ptr < sizeof(qcmemusedblock_t) || ptr >= prinst.addressableused) { if (ptr < sizeof(qcmemusedblock_t) && !*(char*)memptr) { //the empty string is a point of contention. while we can detect it from fteqcc, its best to not give any special favours (other than nicer debugging, where possible) //we might not actually spot it from other qccs, so warning about it where possible is probably a very good thing. - printf("PF_memfree: unable to free the non-null empty string constant\n", ptr, prinst->addressableused); + printf("PF_memfree: unable to free the non-null empty string constant\n", ptr, prinst.addressableused); } else - printf("PF_memfree: pointer invalid - out of range (%u >= %u)\n", ptr, prinst->addressableused); - PR_StackTrace(progfuncs); + printf("PF_memfree: pointer invalid - out of range (%u >= %u)\n", ptr, prinst.addressableused); + PR_StackTrace(&progfuncs->funcs); return; } - ub = (qcmemusedblock_t*)(progfuncs->stringtable + ptr); + ub = (qcmemusedblock_t*)(progfuncs->funcs.stringtable + ptr); ub--; - ptr = (char*)ub - progfuncs->stringtable; - if (ub->marker != MARKER || ub->size <= sizeof(*ub) || ptr + ub->size > (unsigned int)prinst->addressableused) + ptr = (char*)ub - progfuncs->funcs.stringtable; + if (ub->marker != MARKER || ub->size <= sizeof(*ub) || ptr + ub->size > (unsigned int)prinst.addressableused) { printf("PR_memfree: pointer lacks marker - double-freed?\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return; } ub->marker = 0; size = ub->size; - for (na = prinst->mfreelist, pa = 0; ;) + for (na = prinst.mfreelist, pa = 0; ;) { - if (na < 0 || na >= prinst->addressableused) + if (na < 0 || na >= prinst.addressableused) { printf("PF_memfree: memory corruption\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return; } if (!na || na >= ptr) { - np = (qcmemfreeblock_t*)(progfuncs->stringtable + pa); + np = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + pa); if (pa && pa+np->size>ptr) { printf("PF_memfree: double free\n"); - PR_StackTrace(progfuncs); + PR_StackTrace(&progfuncs->funcs); return; } /*generate the free block, now we know its proper values*/ - p = (qcmemfreeblock_t*)(progfuncs->stringtable + ptr); - np = na?(qcmemfreeblock_t*)(progfuncs->stringtable + na):NULL; - pp = pa?(qcmemfreeblock_t*)(progfuncs->stringtable + pa):NULL; + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + ptr); + np = na?(qcmemfreeblock_t*)(progfuncs->funcs.stringtable + na):NULL; + pp = pa?(qcmemfreeblock_t*)(progfuncs->funcs.stringtable + pa):NULL; p->prev = pa; p->next = na; @@ -354,7 +359,7 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr) /*update the link to get here*/ if (!pa) - prinst->mfreelist = ptr; + prinst.mfreelist = ptr; else { pp->next = ptr; @@ -371,7 +376,7 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr) } pa = na; - p = (qcmemfreeblock_t*)(progfuncs->stringtable + pa); + p = (qcmemfreeblock_t*)(progfuncs->funcs.stringtable + pa); na = p->next; } @@ -380,49 +385,50 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr) void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount) { - prinst->addressableused = 0; + prinst.addressableused = 0; if (totalammount < 0) //flush { - totalammount = prinst->addressablesize; + totalammount = prinst.addressablesize; // return; } #ifdef _WIN32 - if (prinst->addressablehunk && prinst->addressablesize != totalammount) + if (prinst.addressablehunk && prinst.addressablesize != totalammount) { - VirtualFree(prinst->addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p - prinst->addressablehunk = NULL; + VirtualFree(prinst.addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p + prinst.addressablehunk = NULL; } - if (!prinst->addressablehunk) - prinst->addressablehunk = VirtualAlloc (prinst->addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS); + if (!prinst.addressablehunk) + prinst.addressablehunk = VirtualAlloc (prinst.addressablehunk, totalammount, MEM_RESERVE, PAGE_NOACCESS); #else - if (prinst->addressablehunk && prinst->addressablesize != totalammount) + if (prinst.addressablehunk && prinst.addressablesize != totalammount) { - free(prinst->addressablehunk); - prinst->addressablehunk = NULL; + free(prinst.addressablehunk); + prinst.addressablehunk = NULL; } - if (!prinst->addressablehunk) - prinst->addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy. -// memset(prinst->addressablehunk, 0xff, totalammount); + if (!prinst.addressablehunk) + prinst.addressablehunk = malloc(totalammount); //linux will allocate-on-use anyway, which is handy. +// memset(prinst.addressablehunk, 0xff, totalammount); #endif - if (!prinst->addressablehunk) + if (!prinst.addressablehunk) Sys_Error("Out of memory\n"); - prinst->addressablesize = totalammount; + prinst.addressablesize = totalammount; } -int PR_InitEnts(progfuncs_t *progfuncs, int max_ents) +int PDECL PR_InitEnts(pubprogfuncs_t *ppf, int max_ents) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; maxedicts = max_ents; sv_num_edicts = 0; max_fields_size = fields_size; - prinst->edicttable = PRHunkAlloc(progfuncs, maxedicts*sizeof(struct edicts_s *)); - sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize); - prinst->edicttable[0] = sv_edicts; - ((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableExtend(progfuncs, max_fields_size); - QC_ClearEdict(progfuncs, sv_edicts); + prinst.edicttable = PRHunkAlloc(progfuncs, maxedicts*sizeof(struct edicts_s *), "edicttable"); + sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize, "edict0"); + prinst.edicttable[0] = sv_edicts; + ((edictrun_t*)prinst.edicttable[0])->fields = PRAddressableExtend(progfuncs, max_fields_size); + QC_ClearEdict(&progfuncs->funcs, sv_edicts); sv_num_edicts = 1; if (externs->entspawn) @@ -431,26 +437,27 @@ int PR_InitEnts(progfuncs_t *progfuncs, int max_ents) return max_fields_size; } edictrun_t tempedict; //used as a safty buffer -float tempedictfields[2048]; +static float tempedictfields[2048]; -void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) //can be used to wipe all memory +void PDECL PR_Configure (pubprogfuncs_t *ppf, int addressable_size, int max_progs) //can be used to wipe all memory { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int i; edictrun_t *e; max_fields_size=0; fields_size = 0; - progfuncs->stringtable = 0; + progfuncs->funcs.stringtable = 0; QC_StartShares(progfuncs); QC_InitShares(progfuncs); for ( i=1 ; iedicttable[i]); - prinst->edicttable[i] = NULL; + e = (edictrun_t *)(prinst.edicttable[i]); + prinst.edicttable[i] = NULL; // e->entnum = i; if (e) - memfree(e); + externs->memfree(e); } PRHunkFree(progfuncs, 0); //clear mem - our hunk may not be a real hunk. @@ -458,7 +465,7 @@ void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) addressable_size = 8*1024*1024; PRAddressableFlush(progfuncs, addressable_size); - pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * max_progs); + pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * max_progs, "progstatetable"); /* for(a = 0; a < max_progs; a++) { @@ -469,10 +476,10 @@ void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) maxprogs = max_progs; pr_typecurrent=-1; - prinst->reorganisefields = false; + prinst.reorganisefields = false; maxedicts = 1; - prinst->edicttable = &sv_edicts; + prinst.edicttable = &sv_edicts; sv_num_edicts = 1; //set up a safty buffer so things won't go horribly wrong too often sv_edicts=(struct edict_s *)&tempedict; tempedict.readonly = true; @@ -482,8 +489,9 @@ void PR_Configure (progfuncs_t *progfuncs, int addressable_size, int max_progs) -struct globalvars_s *PR_globals (progfuncs_t *progfuncs, progsnum_t pnum) +struct globalvars_s *PDECL PR_globals (pubprogfuncs_t *ppf, progsnum_t pnum) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; if (pnum < 0) { if (!current_progstate) @@ -496,16 +504,19 @@ struct globalvars_s *PR_globals (progfuncs_t *progfuncs, progsnum_t pnum) return (struct globalvars_s *)pr_progstate[pnum].globals; } -struct entvars_s *PR_entvars (progfuncs_t *progfuncs, struct edict_s *ed) +struct entvars_s *PDECL PR_entvars (pubprogfuncs_t *ppf, struct edict_s *ed) { +// progfuncs_t *progfuncs = (progfuncs_t*)ppf; if (((edictrun_t *)ed)->isfree) return NULL; return (struct entvars_s *)edvars(ed); } -int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func) +int PDECL PR_GetFuncArgCount(pubprogfuncs_t *ppf, func_t func) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; + unsigned int pnum; unsigned int fnum; dfunction_t *f; @@ -524,8 +535,9 @@ int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func) } } -func_t PR_FindFunc(progfuncs_t *progfuncs, char *funcname, progsnum_t pnum) +func_t PDECL PR_FindFunc(pubprogfuncs_t *ppf, char *funcname, progsnum_t pnum) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; dfunction_t *f=NULL; if (pnum == PR_ANY) { @@ -577,8 +589,9 @@ func_t PR_FindFunc(progfuncs_t *progfuncs, char *funcname, progsnum_t pnum) return 0; } -void QC_FindPrefixedGlobals(progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ) +void PDECL QC_FindPrefixedGlobals(pubprogfuncs_t *ppf, char *prefix, void (PDECL *found) (pubprogfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int i; ddef16_t *def16; ddef32_t *def32; @@ -597,8 +610,8 @@ void QC_FindPrefixedGlobals(progfuncs_t *progfuncs, char *prefix, void (*found) for (i=1 ; inumglobaldefs ; i++) { def16 = &pr_progstate[pnum].globaldefs16[i]; - if (!strncmp(def16->s_name+progfuncs->stringtable,prefix, len)) - found(progfuncs, def16->s_name+progfuncs->stringtable, (eval_t *)&pr_progstate[pnum].globals[def16->ofs], def16->type); + if (!strncmp(def16->s_name+progfuncs->funcs.stringtable,prefix, len)) + found(&progfuncs->funcs, def16->s_name+progfuncs->funcs.stringtable, (eval_t *)&pr_progstate[pnum].globals[def16->ofs], def16->type); } break; case PST_QTEST: @@ -606,16 +619,17 @@ void QC_FindPrefixedGlobals(progfuncs_t *progfuncs, char *prefix, void (*found) for (i=1 ; inumglobaldefs ; i++) { def32 = &pr_progstate[pnum].globaldefs32[i]; - if (!strncmp(def32->s_name+progfuncs->stringtable,prefix, len)) - found(progfuncs, def32->s_name+progfuncs->stringtable, (eval_t *)&pr_progstate[pnum].globals[def32->ofs], def32->type); + if (!strncmp(def32->s_name+progfuncs->funcs.stringtable,prefix, len)) + found(&progfuncs->funcs, def32->s_name+progfuncs->funcs.stringtable, (eval_t *)&pr_progstate[pnum].globals[def32->ofs], def32->type); } break; } } } -eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum, etype_t *type) +eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *ppf, char *globname, progsnum_t pnum, etype_t *type) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int i; ddef16_t *var16; ddef32_t *var32; @@ -628,7 +642,7 @@ eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum, e { if (!pr_progstate[i].progs) continue; - ev = PR_FindGlobal(progfuncs, globname, i, type); + ev = PR_FindGlobal(&progfuncs->funcs, globname, i, type); if (ev) return ev; } @@ -659,23 +673,25 @@ eval_t *PR_FindGlobal(progfuncs_t *progfuncs, char *globname, progsnum_t pnum, e return NULL; } -void SetGlobalEdict(progfuncs_t *progfuncs, struct edict_s *ed, int ofs) +void PDECL SetGlobalEdict(pubprogfuncs_t *ppf, struct edict_s *ed, int ofs) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; ((int*)pr_globals)[ofs] = EDICT_TO_PROG(progfuncs, ed); } -char *PR_VarString (progfuncs_t *progfuncs, int first) +char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int i; static char out[1024]; char *s; out[0] = 0; - for (i=first ; ifuncs.callargc ; i++) { if (G_STRING(OFS_PARM0+i*3)) { - s=G_STRING((OFS_PARM0+i*3)) + progfuncs->stringtable; + s=G_STRING((OFS_PARM0+i*3)) + progfuncs->funcs.stringtable; if (strlen(out) + strlen(s) + 1 >= sizeof(out)) return out; strcat (out, s); @@ -684,8 +700,9 @@ char *PR_VarString (progfuncs_t *progfuncs, int first) return out; } -int PR_QueryField (progfuncs_t *progfuncs, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache) +int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; fdef_t *var; var = ED_FieldAtOfs(progfuncs, fieldoffset); if (!var) @@ -704,8 +721,9 @@ int PR_QueryField (progfuncs_t *progfuncs, unsigned int fieldoffset, etype_t *ty return true; } -eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *name, evalc_t *cache) +eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *ppf, struct edict_s *ed, char *name, evalc_t *cache) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; fdef_t *var; if (!cache) { @@ -734,60 +752,63 @@ eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *nam return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[cache->ofs32->ofs]); } -struct edict_s *ProgsToEdict (progfuncs_t *progfuncs, int progs) +struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; if ((unsigned)progs >= (unsigned)maxedicts) { printf("Bad entity index %i\n", progs); progs = 0; } - return (struct edict_s *)PROG_TO_EDICT(progfuncs, progs); + return (struct edict_s *)PROG_TO_EDICT(progfuncs.inst, progs); } -int EdictToProgs (progfuncs_t *progfuncs, struct edict_s *ed) +int PDECL EdictToProgs (pubprogfuncs_t *ppf, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; return EDICT_TO_PROG(progfuncs, ed); } -string_t PR_StringToProgs (progfuncs_t *progfuncs, char *str) +string_t PDECL PR_StringToProgs (pubprogfuncs_t *ppf, char *str) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; char **ntable; int i, free=-1; if (!str) return 0; - if (str >= progfuncs->stringtable && str < progfuncs->stringtable + prinst->addressableused) - return str - progfuncs->stringtable; + if (str >= progfuncs->funcs.stringtable && str < progfuncs->funcs.stringtable + prinst.addressableused) + return str - progfuncs->funcs.stringtable; - for (i = prinst->numallocedstrings-1; i >= 0; i--) + for (i = prinst.numallocedstrings-1; i >= 0; i--) { - if (prinst->allocedstrings[i] == str) + if (prinst.allocedstrings[i] == str) return (string_t)((unsigned int)i | 0x80000000); - if (!prinst->allocedstrings[i]) + if (!prinst.allocedstrings[i]) free = i; } if (free != -1) { i = free; - prinst->allocedstrings[i] = str; + prinst.allocedstrings[i] = str; return (string_t)((unsigned int)i | 0x80000000); } - prinst->maxallocedstrings += 1024; - ntable = memalloc(sizeof(char*) * prinst->maxallocedstrings); - memcpy(ntable, prinst->allocedstrings, sizeof(char*) * prinst->numallocedstrings); - memset(ntable + prinst->numallocedstrings, 0, sizeof(char*) * (prinst->maxallocedstrings - prinst->numallocedstrings)); - prinst->numallocedstrings = prinst->maxallocedstrings; - if (prinst->allocedstrings) - memfree(prinst->allocedstrings); - prinst->allocedstrings = ntable; + prinst.maxallocedstrings += 1024; + ntable = progfuncs->funcs.parms->memalloc(sizeof(char*) * prinst.maxallocedstrings); + memcpy(ntable, prinst.allocedstrings, sizeof(char*) * prinst.numallocedstrings); + memset(ntable + prinst.numallocedstrings, 0, sizeof(char*) * (prinst.maxallocedstrings - prinst.numallocedstrings)); + prinst.numallocedstrings = prinst.maxallocedstrings; + if (prinst.allocedstrings) + progfuncs->funcs.parms->memfree(prinst.allocedstrings); + prinst.allocedstrings = ntable; - for (i = prinst->numallocedstrings-1; i >= 0; i--) + for (i = prinst.numallocedstrings-1; i >= 0; i--) { - if (!prinst->allocedstrings[i]) + if (!prinst.allocedstrings[i]) { - prinst->allocedstrings[i] = str; + prinst.allocedstrings[i] = str; return (string_t)((unsigned int)i | 0x80000000); } } @@ -795,8 +816,9 @@ string_t PR_StringToProgs (progfuncs_t *progfuncs, char *str) return 0; } -char *PR_RemoveProgsString (progfuncs_t *progfuncs, string_t str) +char *PDECL PR_RemoveProgsString (pubprogfuncs_t *ppf, string_t str) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; char *ret; //input string is expected to be an allocated string @@ -806,79 +828,81 @@ char *PR_RemoveProgsString (progfuncs_t *progfuncs, string_t str) if ((unsigned int)str & 0x80000000) { int i = str & ~0x80000000; - if (i >= prinst->numallocedstrings) + if (i >= prinst.numallocedstrings) { - pr_trace = 1; + progfuncs->funcs.pr_trace = 1; return NULL; } - if (prinst->allocedstrings[i]) + if (prinst.allocedstrings[i]) { - ret = prinst->allocedstrings[i]; - prinst->allocedstrings[i] = NULL; //remove it + ret = prinst.allocedstrings[i]; + prinst.allocedstrings[i] = NULL; //remove it return ret; } else { - pr_trace = 1; + progfuncs->funcs.pr_trace = 1; return NULL; //urm, was freed... } } } - pr_trace = 1; + progfuncs->funcs.pr_trace = 1; return NULL; } -char *ASMCALL PR_StringToNative (progfuncs_t *progfuncs, string_t str) +char *ASMCALL PR_StringToNative (pubprogfuncs_t *ppf, string_t str) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; if ((unsigned int)str & 0xc0000000) { if ((unsigned int)str & 0x80000000) { int i = str & ~0x80000000; - if (i >= prinst->numallocedstrings) + if (i >= prinst.numallocedstrings) { printf("invalid string %x\n", str); - PR_StackTrace(progfuncs); - pr_trace = 1; + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; return ""; } - if (prinst->allocedstrings[i]) - return prinst->allocedstrings[i]; + if (prinst.allocedstrings[i]) + return prinst.allocedstrings[i]; else { printf("invalid string %x\n", str); - PR_StackTrace(progfuncs); - pr_trace = 1; + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; return ""; //urm, was freed... } } if ((unsigned int)str & 0x40000000) { int i = str & ~0x40000000; - if (i >= prinst->numtempstrings) + if (i >= prinst.numtempstrings) { printf("invalid temp string %x\n", str); - PR_StackTrace(progfuncs); - pr_trace = 1; + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; return ""; } - return prinst->tempstrings[i]; + return prinst.tempstrings[i]; } } - if ((unsigned int)str >= (unsigned int)prinst->addressableused) + if ((unsigned int)str >= (unsigned int)prinst.addressableused) { printf("invalid string offset %x\n", str); - PR_StackTrace(progfuncs); - pr_trace = 1; + PR_StackTrace(&progfuncs->funcs); + progfuncs->funcs.pr_trace = 1; return ""; } - return progfuncs->stringtable + str; + return progfuncs->funcs.stringtable + str; } -string_t PR_AllocTempString (progfuncs_t *progfuncs, const char *str) +string_t PDECL PR_AllocTempString (pubprogfuncs_t *ppf, const char *str) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; char **ntable; int newmax; int i; @@ -886,31 +910,32 @@ string_t PR_AllocTempString (progfuncs_t *progfuncs, const char *str) if (!str) return 0; - if (prinst->numtempstrings == prinst->maxtempstrings) + if (prinst.numtempstrings == prinst.maxtempstrings) { - newmax = prinst->maxtempstrings += 1024; - prinst->maxtempstrings += 1024; - ntable = memalloc(sizeof(char*) * newmax); - memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings); - prinst->maxtempstrings = newmax; - if (prinst->tempstrings) - memfree(prinst->tempstrings); - prinst->tempstrings = ntable; + newmax = prinst.maxtempstrings += 1024; + prinst.maxtempstrings += 1024; + ntable = progfuncs->funcs.parms->memalloc(sizeof(char*) * newmax); + memcpy(ntable, prinst.tempstrings, sizeof(char*) * prinst.numtempstrings); + prinst.maxtempstrings = newmax; + if (prinst.tempstrings) + progfuncs->funcs.parms->memfree(prinst.tempstrings); + prinst.tempstrings = ntable; } - i = prinst->numtempstrings; + i = prinst.numtempstrings; if (i == 0x10000000) return 0; - prinst->numtempstrings++; + prinst.numtempstrings++; - prinst->tempstrings[i] = memalloc(strlen(str)+1); - strcpy(prinst->tempstrings[i], str); + prinst.tempstrings[i] = progfuncs->funcs.parms->memalloc(strlen(str)+1); + strcpy(prinst.tempstrings[i], str); return (string_t)((unsigned int)i | 0x40000000); } -string_t PR_AllocTempStringLen (progfuncs_t *progfuncs, char **str, unsigned int len) +string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigned int len) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; char **ntable; int newmax; int i; @@ -918,26 +943,26 @@ string_t PR_AllocTempStringLen (progfuncs_t *progfuncs, char **str, unsigned i if (!str) return 0; - if (prinst->numtempstrings == prinst->maxtempstrings) + if (prinst.numtempstrings == prinst.maxtempstrings) { - newmax = prinst->maxtempstrings += 1024; - prinst->maxtempstrings += 1024; - ntable = memalloc(sizeof(char*) * newmax); - memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings); - prinst->maxtempstrings = newmax; - if (prinst->tempstrings) - memfree(prinst->tempstrings); - prinst->tempstrings = ntable; + newmax = prinst.maxtempstrings += 1024; + prinst.maxtempstrings += 1024; + ntable = progfuncs->funcs.parms->memalloc(sizeof(char*) * newmax); + memcpy(ntable, prinst.tempstrings, sizeof(char*) * prinst.numtempstrings); + prinst.maxtempstrings = newmax; + if (prinst.tempstrings) + progfuncs->funcs.parms->memfree(prinst.tempstrings); + prinst.tempstrings = ntable; } - i = prinst->numtempstrings; + i = prinst.numtempstrings; if (i == 0x10000000) return 0; - prinst->numtempstrings++; + prinst.numtempstrings++; - prinst->tempstrings[i] = memalloc(len); - *str = prinst->tempstrings[i]; + prinst.tempstrings[i] = progfuncs->funcs.parms->memalloc(len); + *str = prinst.tempstrings[i]; return (string_t)((unsigned int)i | 0x40000000); } @@ -945,34 +970,30 @@ string_t PR_AllocTempStringLen (progfuncs_t *progfuncs, char **str, unsigned i void PR_FreeTemps (progfuncs_t *progfuncs, int depth) { int i; - if (depth > prinst->numtempstrings) + if (depth > prinst.numtempstrings) { Sys_Error("QC Temp stack inverted\n"); return; } - for (i = depth; i < prinst->numtempstrings; i++) + for (i = depth; i < prinst.numtempstrings; i++) { - memfree(prinst->tempstrings[i]); + externs->memfree(prinst.tempstrings[i]); } - prinst->numtempstrings = depth; + prinst.numtempstrings = depth; } +static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf); -struct qcthread_s *PR_ForkStack (progfuncs_t *progfuncs); -void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread); -void PR_AbortStack (progfuncs_t *progfuncs); +static void PDECL RegisterBuiltin(pubprogfuncs_t *progfncs, char *name, builtin_t func); - -void RegisterBuiltin(progfuncs_t *progfncs, char *name, builtin_t func); - -progfuncs_t deffuncs = { +pubprogfuncs_t deffuncs = { PROGSTRUCT_VERSION, + PR_CloseProgs, PR_Configure, PR_LoadProgs, PR_InitEnts, PR_ExecuteProgram, - PR_SwitchProgs, PR_globals, PR_entvars, PR_RunError, @@ -980,15 +1001,15 @@ progfuncs_t deffuncs = { ED_Alloc, ED_Free, - EDICT_NUM, - NUM_FOR_EDICT, + QC_EDICT_NUM, + QC_NUM_FOR_EDICT, SetGlobalEdict, PR_VarString, - NULL, + NULL, //progstate PR_FindFunc, #ifdef MINIMAL NULL, @@ -1001,56 +1022,56 @@ progfuncs_t deffuncs = { filefromprogs, NULL,//filefromnewprogs, - SaveEnts, - LoadEnts, + ED_Print, + PR_SaveEnts, + PR_LoadEnts, - SaveEnt, - RestoreEnt, + PR_SaveEnt, + PR_RestoreEnt, PR_FindGlobal, ED_NewString, - (void*)PRHunkAlloc, + QC_HunkAlloc, - GetEdictFieldValue, + QC_GetEdictFieldValue, ProgsToEdict, EdictToProgs, - EvaluateDebugString, + PR_EvaluateDebugString, - NULL, + 0,//trace PR_StackTrace, PR_ToggleBreakpoint, - 0, - NULL, + 0, //numprogs + NULL, //parms #ifdef MINIMAL - NULL, + NULL, //decompile #else - Decompile, + QC_Decompile, #endif - NULL, - NULL, + 0, //callargc RegisterBuiltin, - 0, - 0, + 0, //string table(pointer base address) + 0, //string table size + 0, //field adjust(aditional field offset) PR_ForkStack, PR_ResumeThread, PR_AbortStack, - 0, + 0, //called builtin number QC_RegisterFieldVar, - 0, - 0, + NULL, //user tempstringbase + 0, //user tempstringnum PR_AllocTempString, PR_StringToProgs, PR_StringToNative, - 0, PR_QueryField, QC_ClearEdict, QC_FindPrefixedGlobals, @@ -1058,6 +1079,15 @@ progfuncs_t deffuncs = { PR_AllocTempStringLen, PR_memfree, PR_SetWatchPoint, + + QC_AddSharedVar, + QC_AddSharedFieldVar, + PR_RemoveProgsString, + PR_GetFuncArgCount, + PR_GenerateStatementString, + ED_FieldInfo, + PR_UglyValueString, + ED_ParseEval }; #undef printf @@ -1115,24 +1145,21 @@ progexterns_t defexterns = { #undef maxedicts #undef sv_num_edicts - -#ifdef QCLIBDLL_EXPORTS -__declspec(dllexport) -#endif -void CloseProgs(progfuncs_t *inst) +static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf) { // extensionbuiltin_t *eb; void (VARGS *f) (void *); + progfuncs_t *inst = (progfuncs_t*)ppf; unsigned int i; edictrun_t *e; - f = inst->parms->memfree; + f = inst->funcs.parms->memfree; - for ( i=1 ; iinst->maxedicts; i++) + for ( i=1 ; iinst.maxedicts; i++) { - e = (edictrun_t *)(inst->inst->edicttable[i]); - inst->inst->edicttable[i] = NULL; + e = (edictrun_t *)(inst->inst.edicttable[i]); + inst->inst.edicttable[i] = NULL; if (e) { // e->entnum = i; @@ -1143,44 +1170,43 @@ void CloseProgs(progfuncs_t *inst) PRHunkFree(inst, 0); #ifdef _WIN32 - VirtualFree(inst->inst->addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p + VirtualFree(inst->inst.addressablehunk, 0, MEM_RELEASE); //doesn't this look complicated? :p #else - free(inst->inst->addressablehunk); + free(inst->inst.addressablehunk); #endif - if (inst->inst->allocedstrings) - f(inst->inst->allocedstrings); - inst->inst->allocedstrings = NULL; - if (inst->inst->tempstrings) - f(inst->inst->tempstrings); - inst->inst->tempstrings = NULL; + if (inst->inst.allocedstrings) + f(inst->inst.allocedstrings); + inst->inst.allocedstrings = NULL; + if (inst->inst.tempstrings) + f(inst->inst.tempstrings); + inst->inst.tempstrings = NULL; - free(inst->inst->watch_name); + free(inst->inst.watch_name); /* - while(inst->prinst->extensionbuiltin) + while(inst->prinst.extensionbuiltin) { - eb = inst->prinst->extensionbuiltin->prev; - f(inst->prinst->extensionbuiltin); - inst->prinst->extensionbuiltin = eb; + eb = inst->prinst.extensionbuiltin->prev; + f(inst->prinst.extensionbuiltin); + inst->prinst.extensionbuiltin = eb; } */ - if (inst->inst->field) - f(inst->inst->field); - if (inst->inst->shares) - f(inst->inst->shares); //free memory - f(inst->inst); + if (inst->inst.field) + f(inst->inst.field); + if (inst->inst.shares) + f(inst->inst.shares); //free memory f(inst); } -void RegisterBuiltin(progfuncs_t *progfuncs, char *name, builtin_t func) +static void PDECL RegisterBuiltin(pubprogfuncs_t *progfuncs, char *name, builtin_t func) { /* extensionbuiltin_t *eb; eb = memalloc(sizeof(extensionbuiltin_t)); - eb->prev = progfuncs->prinst->extensionbuiltin; - progfuncs->prinst->extensionbuiltin = eb; + eb->prev = progfuncs->prinst.extensionbuiltin; + progfuncs->prinst.extensionbuiltin = eb; eb->name = name; eb->func = func; */ @@ -1193,7 +1219,7 @@ void RegisterBuiltin(progfuncs_t *progfuncs, char *name, builtin_t func) #if defined(QCLIBDLL_EXPORTS) __declspec(dllexport) #endif -progfuncs_t * InitProgs(progexterns_t *ext) +pubprogfuncs_t * PDECL InitProgs(progexterns_t *ext) { progfuncs_t *funcs; @@ -1210,24 +1236,19 @@ progfuncs_t * InitProgs(progexterns_t *ext) *(int *)((char *)ext+i) = *(int *)((char *)&defexterns+i); } #undef memalloc -#undef pr_trace #undef pr_progstate #undef pr_argc funcs = ext->memalloc(sizeof(progfuncs_t)); - memcpy(funcs, &deffuncs, sizeof(progfuncs_t)); + memcpy(&funcs->funcs, &deffuncs, sizeof(pubprogfuncs_t)); + memset(&funcs->inst, 0, sizeof(funcs->inst)); - funcs->inst = ext->memalloc(sizeof(prinst_t)); - memset(funcs->inst,0, sizeof(prinst_t)); + funcs->funcs.progstate = &funcs->inst.progstate; - funcs->pr_trace = &funcs->inst->pr_trace; - funcs->progstate = &funcs->inst->progstate; - funcs->callargc = &funcs->inst->pr_argc; - - funcs->parms = ext; + funcs->funcs.parms = ext; SetEndian(); - return funcs; + return &funcs->funcs; } diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index f508c089..61995e01 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -8,12 +8,8 @@ Setting them should be fine. #define __PR_COMP_H__ -/*this distinction is made as the execution uses c pointers while compiler uses pointers from the start of the string table of the current progs*/ -#ifdef COMPILER -typedef int QCC_string_t; -#else -//typedef char *string_t; -#endif +typedef int dstring_t; +#define QCC_string_t dstring_t //typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer, ev_integer, ev_struct, ev_union} etype_t; // 0 1 2 3 4 5 6 7 8 9 10 @@ -356,6 +352,9 @@ enum qcop_e { OP_LOADA_STRUCT, OP_STOREP_P, + OP_BINARYNOT_F, + OP_BINARYNOT_I, + OP_NUMOPS }; @@ -391,7 +390,6 @@ typedef struct qtest_function_s int parm_size[MAX_PARMS]; // ints instead of bytes... } qtest_function_t; -#ifndef COMPILER typedef struct statement16_s { unsigned short op; @@ -402,22 +400,11 @@ typedef struct statement32_s unsigned int op; unsigned int a,b,c; } dstatement32_t; -#else -typedef struct QCC_statement16_s -{ - unsigned short op; - unsigned short a,b,c; -} QCC_dstatement16_t; -typedef struct QCC_statement32_s -{ - unsigned int op; - unsigned int a,b,c; -} QCC_dstatement32_t; -#define QCC_dstatement_t QCC_dstatement32_t -#endif +#define QCC_dstatement16_t dstatement16_t +#define QCC_dstatement_t dstatement32_t +#define QCC_dstatement32_t dstatement32_t //these should be the same except the string type -#ifndef COMPILER typedef struct ddef16_s { unsigned short type; // if DEF_SAVEGLOBAL bit is set @@ -435,7 +422,7 @@ typedef struct ddef32_s } ddef32_t; typedef void *ddefXX_t; -#else + typedef struct QCC_ddef16_s { unsigned short type; // if DEF_SAVEGLOBAL bit is set @@ -451,14 +438,11 @@ typedef struct QCC_ddef32_s unsigned int ofs; QCC_string_t s_name; } QCC_ddef32_t; - #define QCC_ddef_t QCC_ddef32_t -#endif #define DEF_SAVEGLOBAL (1<<15) #define DEF_SHARED (1<<14) -#ifndef COMPILER typedef struct { int first_statement; // negative numbers are builtins @@ -473,7 +457,6 @@ typedef struct int numparms; qbyte parm_size[MAX_PARMS]; } dfunction_t; -#else typedef struct { unsigned int first_statement; // negative numbers are builtins @@ -488,7 +471,6 @@ typedef struct int numparms; qbyte parm_size[MAX_PARMS]; } QCC_dfunction_t; -#endif #define PROG_QTESTVERSION 3 #define PROG_VERSION 6 diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 2bd7028e..9a04c909 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -23,8 +23,9 @@ QC_ClearEdict Sets everything to NULL ================= */ -void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed) +void PDECL QC_ClearEdict (pubprogfuncs_t *ppf, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; edictrun_t *e = (edictrun_t *)ed; int num = e->entnum; memset (e->fields, 0, fields_size); @@ -36,11 +37,11 @@ edictrun_t *ED_AllocIntoTable (progfuncs_t *progfuncs, int num) { edictrun_t *e; - prinst->edicttable[num] = *(struct edict_s **)&e = (void*)memalloc(externs->edictsize); + prinst.edicttable[num] = *(struct edict_s **)&e = (void*)externs->memalloc(externs->edictsize); memset(e, 0, externs->edictsize); e->fields = PRAddressableExtend(progfuncs, fields_size); e->entnum = num; - QC_ClearEdict(progfuncs, (struct edict_s*)e); + QC_ClearEdict(&progfuncs->funcs, (struct edict_s*)e); return e; } @@ -56,12 +57,16 @@ instead of being removed and recreated, which can cause interpolated angles and bad trails. ================= */ -struct edict_s *ED_Alloc (progfuncs_t *progfuncs) +struct edict_s *PDECL ED_Alloc (pubprogfuncs_t *ppf) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int i; edictrun_t *e; - for ( i=0 ; ifuncs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -81,7 +86,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs) if (i >= maxedicts-1) //try again, but use timed out ents. { - for ( i=0 ; ifuncs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -102,25 +107,37 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs) if (i >= maxedicts-2) { printf("Running out of edicts\n"); - pr_trace = 1; //trip the debugger whilst it's still valid + progfuncs->funcs.pr_trace = 1; //trip the debugger whilst it's still valid } if (i >= maxedicts-1) { int size; char *buf; - buf = progfuncs->save_ents(progfuncs, NULL, &size, 0); - progfuncs->parms->WriteFile("edalloc.dump", buf, size); - Sys_Error ("ED_Alloc: no free edicts (max is %i)", sv_num_edicts); + buf = PR_SaveEnts(&progfuncs->funcs, NULL, &size, 0); + progfuncs->funcs.parms->WriteFile("edalloc.dump", buf, size); + Sys_Error ("ED_Alloc: no free edicts (max is %i)", maxedicts); } } + while(sv_num_edicts < i) + { + e = (edictrun_t*)EDICT_NUM(progfuncs, sv_num_edicts); + if (!e) + { + e = ED_AllocIntoTable(progfuncs, sv_num_edicts); + if (externs->entspawn) + externs->entspawn((struct edict_s *) e, false); + e->isfree = true; + } + sv_num_edicts++; + } sv_num_edicts++; e = (edictrun_t*)EDICT_NUM(progfuncs, i); if (!e) e = ED_AllocIntoTable(progfuncs, i); else - QC_ClearEdict (progfuncs, (struct edict_s*)e); + QC_ClearEdict (&progfuncs->funcs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -136,19 +153,20 @@ Marks the edict as free FIXME: walk all entities and NULL out references to this entity ================= */ -void ED_Free (progfuncs_t *progfuncs, struct edict_s *ed) +void PDECL ED_Free (pubprogfuncs_t *ppf, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; edictrun_t *e = (edictrun_t *)ed; // SV_UnlinkEdict (ed); // unlink from world bsp if (e->isfree) //this happens on start.bsp where an onlyregistered trigger killtargets itself (when all of this sort die after 1 trigger anyway). { if (pr_depth) - printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->stringtable); + printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->funcs.stringtable); else printf("Engine tried to free free entity\n"); // if (developer.value == 1) -// pr_trace = true; +// progfuncs->funcs.pr_trace = true; return; } @@ -217,17 +235,18 @@ fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs) // ddef_t *def; unsigned int i; - for (i=0 ; inumglobaldefs ; i++) { def = &pr_globaldefs16[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; @@ -273,7 +292,7 @@ ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name) for (i=1 ; inumglobaldefs ; i++) { def = &pr_globaldefs32[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; @@ -306,7 +325,7 @@ ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs16[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; @@ -319,7 +338,7 @@ ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs32[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) return def; } return NULL; @@ -333,7 +352,7 @@ ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, prog for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs16[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) { if (pr_progstate[prnum].types) { @@ -357,7 +376,7 @@ ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, prog for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs32[i]; - if (!strcmp(def->s_name+progfuncs->stringtable,name) ) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable,name) ) { if (pr_progstate[prnum].types) { @@ -442,7 +461,7 @@ dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pr for (i=1 ; inumfunctions ; i++) { func = &pr_progstate[pnum].functions[i]; - if (!strcmp(func->s_name+progfuncs->stringtable,name) ) + if (!strcmp(func->s_name+progfuncs->funcs.stringtable,name) ) return func; } return NULL; @@ -452,7 +471,7 @@ dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pr ============ PR_ValueString -Returns a string describing *data in a type specific manner +Returns a string describing *data in a human-readable type specific manner ============= */ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) @@ -477,7 +496,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) sprintf (line, "union"); break; case ev_string: - sprintf (line, "%s", PR_StringToNative(progfuncs, val->string)); + sprintf (line, "%s", PR_StringToNative(&progfuncs->funcs, val->string)); break; case ev_entity: fielddef = ED_FindField(progfuncs, "classname"); @@ -487,7 +506,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) string_t *v; ed = (edictrun_t *)EDICT_NUM(progfuncs, val->edict); v = (string_t *)((char *)edvars(ed) + fielddef->ofs*4); - sprintf (line, "entity %i(%s)", val->edict, PR_StringToNative(progfuncs, *v)); + sprintf (line, "entity %i(%s)", val->edict, PR_StringToNative(&progfuncs->funcs, *v)); } else sprintf (line, "entity %i", val->edict); @@ -506,7 +525,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) else { f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable); + sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->funcs.stringtable); } } } @@ -522,13 +541,13 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) sprintf (line, "void type"); break; case ev_float: - sprintf (line, "%5.1f", val->_float); + sprintf (line, "%g", val->_float); break; case ev_integer: sprintf (line, "%i", val->_int); break; case ev_vector: - sprintf (line, "'%5.1f %5.1f %5.1f'", val->_vector[0], val->_vector[1], val->_vector[2]); + sprintf (line, "'%g %g %g'", val->_vector[0], val->_vector[1], val->_vector[2]); break; case ev_pointer: sprintf (line, "pointer"); @@ -567,8 +586,9 @@ Returns a string describing *data in a type specific manner Easier to parse than PR_ValueString ============= */ -char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) +char *PDECL PR_UglyValueString (pubprogfuncs_t *ppf, etype_t type, eval_t *val) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; static char line[256]; fdef_t *fielddef; dfunction_t *f; @@ -593,7 +613,7 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) { char *outs = line; int outb = sizeof(line)-2; - char *ins = PR_StringToNative(progfuncs, val->string); + char *ins = PR_StringToNative(&progfuncs->funcs, val->string); //markup the output string. while(*ins && outb > 0) { @@ -641,7 +661,7 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) else { f = pr_progstate[(unsigned)i].functions + j; - sprintf (line, "%i:%s", i, f->s_name+progfuncs->stringtable); + sprintf (line, "%i:%s", i, f->s_name+progfuncs->funcs.stringtable); } } break; @@ -698,14 +718,14 @@ char *PR_UglyOldValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) sprintf (line, "unions cannot yet be saved"); break; case ev_string: - sprintf (line, "%s", PR_StringToNative(progfuncs, val->string)); + sprintf (line, "%s", PR_StringToNative(&progfuncs->funcs, val->string)); break; case ev_entity: sprintf (line, "%i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict))); break; case ev_function: f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%s", f->s_name+progfuncs->stringtable); + sprintf (line, "%s", f->s_name+progfuncs->funcs.stringtable); break; case ev_field: fielddef = ED_FieldAtOfs (progfuncs, val->_int ); @@ -802,7 +822,7 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs) else { s = PR_ValueString (progfuncs, def16->type, val); - sprintf (line,"%i(%s)%s", ofs, def16->s_name+progfuncs->stringtable, s); + sprintf (line,"%i(%s)%s", ofs, def16->s_name+progfuncs->funcs.stringtable, s); } i = strlen(line); @@ -819,7 +839,7 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs) else { s = PR_ValueString (progfuncs, def32->type, val); - sprintf (line,"%i(%s)%s", ofs, def32->s_name+progfuncs->stringtable, s); + sprintf (line,"%i(%s)%s", ofs, def32->s_name+progfuncs->funcs.stringtable, s); } i = strlen(line); @@ -847,7 +867,7 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs) if (!def16) sprintf (line,"%i(?""?""?)", ofs); else - sprintf (line,"%i(%s)", ofs, def16->s_name+progfuncs->stringtable); + sprintf (line,"%i(%s)", ofs, def16->s_name+progfuncs->funcs.stringtable); break; case PST_QTEST: case PST_FTE32: @@ -855,7 +875,7 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs) if (!def32) sprintf (line,"%i(?""?""?)", ofs); else - sprintf (line,"%i(%s)", ofs, def32->s_name+progfuncs->stringtable); + sprintf (line,"%i(%s)", ofs, def32->s_name+progfuncs->funcs.stringtable); break; default: Sys_Error("Bad struct type in PR_GlobalStringNoContents"); @@ -877,8 +897,9 @@ ED_Print For debugging ============= */ -void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed) +void PDECL ED_Print (pubprogfuncs_t *ppf, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int l; fdef_t *d; int *v; @@ -893,9 +914,9 @@ void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed) } printf("\nEDICT %i:\n", NUM_FOR_EDICT(progfuncs, (struct edict_s *)ed)); - for (i=1 ; iname; l = strlen(name); if (l >= 2 && name[l-2] == '_') @@ -927,7 +948,7 @@ void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed) void ED_PrintNum (progfuncs_t *progfuncs, int ent) { - ED_Print (progfuncs, EDICT_NUM(progfuncs, ent)); + ED_Print (&progfuncs->funcs, EDICT_NUM(progfuncs, ent)); } /* @@ -992,8 +1013,9 @@ void ED_Count (progfuncs_t *progfuncs) ED_NewString ============= */ -char *ED_NewString (progfuncs_t *progfuncs, char *string, int minlength) +char *PDECL ED_NewString (pubprogfuncs_t *ppf, char *string, int minlength) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; char *newc, *new_p; int i,l; @@ -1001,9 +1023,9 @@ char *ED_NewString (progfuncs_t *progfuncs, char *string, int minlength) l = strlen(string) + 1; - newc = progfuncs->AddressableAlloc (progfuncs, lfuncs.AddressableAlloc (&progfuncs->funcs, lstringtable; + return progfuncs->funcs.stringtable; new_p = newc; @@ -1033,8 +1055,9 @@ Can parse either fields or globals returns false if error ============= */ -pbool ED_ParseEval (progfuncs_t *progfuncs, eval_t *eval, int type, char *s) +pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, char *s) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int i; char string[128]; fdef_t *def; @@ -1045,7 +1068,7 @@ pbool ED_ParseEval (progfuncs_t *progfuncs, eval_t *eval, int type, char *s) switch (type & ~DEF_SAVEGLOBAL) { case ev_string: - st = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, s, 0)); + st = PR_StringToProgs(&progfuncs->funcs, ED_NewString (&progfuncs->funcs, s, 0)); eval->string = st; break; @@ -1129,16 +1152,16 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int switch (type) { case ev_string: - st = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, s, 0)); - *(string_t *)(progfuncs->stringtable + qcptr) = st; + st = PR_StringToProgs(&progfuncs->funcs, ED_NewString (&progfuncs->funcs, s, 0)); + *(string_t *)(progfuncs->funcs.stringtable + qcptr) = st; break; case ev_float: - *(float *)(progfuncs->stringtable + qcptr) = (float)atof (s); + *(float *)(progfuncs->funcs.stringtable + qcptr) = (float)atof (s); break; case ev_integer: - *(int *)(progfuncs->stringtable + qcptr) = atoi (s); + *(int *)(progfuncs->funcs.stringtable + qcptr) = atoi (s); break; case ev_vector: @@ -1151,20 +1174,20 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int v++; if (!*v) { - ((float *)(progfuncs->stringtable + qcptr))[i] = (float)atof (w); + ((float *)(progfuncs->funcs.stringtable + qcptr))[i] = (float)atof (w); w = v; } else { *v = 0; - ((float *)(progfuncs->stringtable + qcptr))[i] = (float)atof (w); + ((float *)(progfuncs->funcs.stringtable + qcptr))[i] = (float)atof (w); w = v = v+1; } } break; case ev_entity: - *(int *)(progfuncs->stringtable + qcptr) = atoi (s); + *(int *)(progfuncs->funcs.stringtable + qcptr) = atoi (s); break; case ev_field: @@ -1174,13 +1197,13 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int printf ("Can't find field %s\n", s); return false; } - *(int *)(progfuncs->stringtable + qcptr) = def->ofs; + *(int *)(progfuncs->funcs.stringtable + qcptr) = def->ofs; break; case ev_function: if (s[1]==':'&&s[2]=='\0') { - *(func_t *)(progfuncs->stringtable + qcptr) = 0; + *(func_t *)(progfuncs->funcs.stringtable + qcptr) = 0; return true; } func = ED_FindFunction (progfuncs, s, &i, -1); @@ -1189,7 +1212,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int printf ("Can't find function %s\n", s); return false; } - *(func_t *)(progfuncs->stringtable + qcptr) = (func - pr_progstate[i].functions) | (i<<24); + *(func_t *)(progfuncs->funcs.stringtable + qcptr) = (func - pr_progstate[i].functions) | (i<<24); break; default: @@ -1291,14 +1314,14 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) if (!strcmp(keyname, "light")) //Quake lighthack - allows a field name and a classname to go by the same thing in the level editor if ((key = ED_FindField (progfuncs, "light_lev"))) goto cont; - if (externs->badfield && externs->badfield(progfuncs, (struct edict_s*)ent, keyname, qcc_token)) + if (externs->badfield && externs->badfield(&progfuncs->funcs, (struct edict_s*)ent, keyname, qcc_token)) continue; printf ("'%s' is not a field\n", keyname); continue; } cont: - if (!ED_ParseEpair (progfuncs, (char*)ent->fields - progfuncs->stringtable, key->ofs, key->type, qcc_token)) + if (!ED_ParseEpair (progfuncs, (char*)ent->fields - progfuncs->funcs.stringtable, key->ofs, key->type, qcc_token)) { continue; // Sys_Error ("ED_ParseEdict: parse error on entities"); @@ -1347,7 +1370,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. for (i=0 ; inumglobaldefs ; i++) { def16 = &pr_globaldefs16[i]; - name = def16->s_name + progfuncs->stringtable; + name = def16->s_name + progfuncs->funcs.stringtable; len = strlen(name); if (!*name) continue; @@ -1368,9 +1391,9 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. v = (int *)¤t_progstate->globals[def16->ofs]; if ((v[0]&0xff000000)>>24 == (unsigned)curprogs) //same progs { - if (!progfuncs->stringtable[current_progstate->functions[v[0]&0x00ffffff].s_name]) + if (!progfuncs->funcs.stringtable[current_progstate->functions[v[0]&0x00ffffff].s_name]) continue; - else if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //names match. Assume function is at initial value. + else if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->funcs.stringtable, name)) //names match. Assume function is at initial value. continue; } @@ -1378,9 +1401,9 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. if ((v[0]&0xff000000)>>24 == 0) if (!ED_FindFunction(progfuncs, name, NULL, curprogs)) //defined as extern { - if (!progfuncs->stringtable[pr_progstate[0].functions[v[0]&0x00ffffff].s_name]) + if (!progfuncs->funcs.stringtable[pr_progstate[0].functions[v[0]&0x00ffffff].s_name]) continue; - else if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name + progfuncs->stringtable, name)) //same name. + else if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name + progfuncs->funcs.stringtable, name)) //same name. continue; } @@ -1405,7 +1428,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. add16: AddS (qcva("\"%s\" ", name)); - AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, def16->type&~DEF_SAVEGLOBAL, (eval_t *)v))); + AddS (qcva("\"%s\"\n", PR_UglyValueString(&progfuncs->funcs, def16->type&~DEF_SAVEGLOBAL, (eval_t *)v))); } break; case PST_QTEST: @@ -1413,7 +1436,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. for (i=0 ; inumglobaldefs ; i++) { def32 = &pr_globaldefs32[i]; - name = def32->s_name + progfuncs->stringtable; + name = def32->s_name + progfuncs->funcs.stringtable; if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars (vector components, which are saved as one vector not 3 floats) @@ -1430,13 +1453,13 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. { v = (int *)¤t_progstate->globals[def32->ofs]; if ((v[0]&0xff000000)>>24 == (unsigned)curprogs) //same progs - if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //names match. Assume function is at initial value. + if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->funcs.stringtable, name)) //names match. Assume function is at initial value. continue; if (curprogs!=0) if ((v[0]&0xff000000)>>24 == 0) if (!ED_FindFunction(progfuncs, name, NULL, curprogs)) //defined as extern - if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //same name. + if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name+ progfuncs->funcs.stringtable, name)) //same name. continue; //else function has been redirected externally. @@ -1459,7 +1482,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. continue; add32: AddS (qcva("\"%s\" ", name)); - AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, def32->type&~DEF_SAVEGLOBAL, (eval_t *)v))); + AddS (qcva("\"%s\"\n", PR_UglyValueString(&progfuncs->funcs, def32->type&~DEF_SAVEGLOBAL, (eval_t *)v))); } break; default: @@ -1478,10 +1501,11 @@ char *ED_WriteEdict(progfuncs_t *progfuncs, edictrun_t *ed, char *buffer, pbool char *name; int type; int len; + char *tmp; - for (i=0 ; iname; len = strlen(name); if (len>4 && (name[len-2] == '_' && (name[len-1] == 'x' || name[len-1] == 'y' || name[len-1] == 'z'))) @@ -1503,8 +1527,14 @@ char *ED_WriteEdict(progfuncs_t *progfuncs, edictrun_t *ed, char *buffer, pbool continue; //add it to the file - AddS (qcva("\"%s\" ",name)); - AddS (qcva("\"%s\"\n", (q1compatible?PR_UglyOldValueString:PR_UglyValueString)(progfuncs, d->type, (eval_t *)v))); + tmp = qcva("\"%s\"\n", name); + AddS (tmp); + if (q1compatible) + tmp = PR_UglyOldValueString(progfuncs, d->type, (eval_t *)v); + else + tmp = PR_UglyValueString(&progfuncs->funcs, d->type, (eval_t *)v); + tmp = qcva("\"%s\"\n", tmp); + AddS (tmp); } return buffer; @@ -1551,9 +1581,9 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s) AddS (buffer); } if (!f->s_file) - sprintf(buffer, "\t\"%i:%s\"\n", progs, f->s_name+progfuncs->stringtable); + sprintf(buffer, "\t\"%i:%s\"\n", progs, f->s_name+progfuncs->funcs.stringtable); else - sprintf(buffer, "\t\"%i:%s\" //%s\n", progs, f->s_name+progfuncs->stringtable, f->s_file+progfuncs->stringtable); + sprintf(buffer, "\t\"%i:%s\" //%s\n", progs, f->s_name+progfuncs->funcs.stringtable, f->s_file+progfuncs->funcs.stringtable); AddS (buffer); AddS ("\t{\n"); @@ -1567,10 +1597,10 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s) { if (local->type == ev_entity) { - sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->stringtable, ((eval_t*)(globalbase - f->locals+arg))->edict); + sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->funcs.stringtable, ((eval_t*)(globalbase - f->locals+arg))->edict); } else - sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); + sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name+progfuncs->funcs.stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); if (local->type == ev_vector) arg+=2; @@ -1592,8 +1622,9 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s) //there are two ways of saving everything. //0 is to save just the entities. //1 is to save the entites, and all the progs info so that all the variables are saved off, and it can be reloaded to exactly how it was (provided no files or data has been changed outside, like the progs.dat for example) -char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata) +char *PDECL PR_SaveEnts(pubprogfuncs_t *ppf, char *mem, int *len, int alldata) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; #define AddS(str) strcpy(s, str);s+=strlen(str); char *s, *os; unsigned int a; @@ -1604,7 +1635,7 @@ char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata) os = s = mem; } else - os = s = memalloc(5*1024*1024); + os = s = externs->memalloc(5*1024*1024); if (alldata == 2) { //special Q1 savegame compatability mode. @@ -1618,7 +1649,7 @@ char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata) } if (!pr_progstate[0].progs || a != maxprogs) //the state of the progs wasn't Q1 compatible. { - memfree(os); + externs->memfree(os); return NULL; } @@ -1705,7 +1736,7 @@ char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata) { edictrun_t *ed = (edictrun_t *)EDICT_NUM(progfuncs, a); - if (ed->isfree) + if (!ed || ed->isfree) continue; AddS (qcva("entity %i{\n", a)); @@ -1724,8 +1755,9 @@ char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *len, int alldata) int header_crc; //if 'general' block is found, this is a compleate state, otherwise, we should spawn entities like -int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) +int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, char *file, float killonspawnflags) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; eval_t *fulldata; //this is part of FTE_FULLSPAWNDATA char *datastart; @@ -1761,7 +1793,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) { isloadgame = false; - fulldata = PR_FindGlobal(progfuncs, "__fullspawndata", PR_ANY, NULL); + fulldata = PR_FindGlobal(&progfuncs->funcs, "__fullspawndata", PR_ANY, NULL); } while(1) @@ -1779,7 +1811,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) { if (entsize == 0 && resethunk) //edicts have not yet been initialized, and this is a compleate load (memsize has been set) { - entsize = PR_InitEnts(progfuncs, maxedicts); + entsize = PR_InitEnts(&progfuncs->funcs, maxedicts); // sv_num_edicts = numents; for (num = 0; num < numents; num++) @@ -1802,7 +1834,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (qcc_token[0] != '{') Sys_Error("Progs loading found %s, not '{'", qcc_token); if (!resethunk) - ed = (edictrun_t *)ED_Alloc(progfuncs); + ed = (edictrun_t *)ED_Alloc(&progfuncs->funcs); else { ed = (edictrun_t *)EDICT_NUM(progfuncs, num); @@ -1820,7 +1852,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (killonspawnflags) { - var = GetEdictFieldValue (progfuncs, (struct edict_s *)&ed, "spawnflags", &spawnflagscache); + var = QC_GetEdictFieldValue (&progfuncs->funcs, (struct edict_s *)&ed, "spawnflags", &spawnflagscache); if (var) { if ((int)var->_float & (int)killonspawnflags) @@ -1834,14 +1866,14 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (!resethunk) { dfunction_t *f; - if ((var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL))) + if ((var = QC_GetEdictFieldValue (&progfuncs->funcs, (struct edict_s *)ed, "classname", NULL))) { - f = ED_FindFunction(progfuncs, var->string + progfuncs->stringtable, NULL, -1); + f = ED_FindFunction(progfuncs, var->string + progfuncs->funcs.stringtable, NULL, -1); if (f) { var = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self")); var->edict = EDICT_TO_PROG(progfuncs, ed); - PR_ExecuteProgram(progfuncs, f-pr_functions); + PR_ExecuteProgram(&progfuncs->funcs, f-pr_functions); } } } @@ -1904,7 +1936,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) { if (entsize == 0 && resethunk) //by the time we parse some globals, we MUST have loaded all progs { - entsize = PR_InitEnts(progfuncs, maxedicts); + entsize = PR_InitEnts(&progfuncs->funcs, maxedicts); // sv_num_edicts = numents; for (num = 0; num < numents; num++) @@ -1950,7 +1982,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) else { file = QCC_COM_Parse(file); - ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d16->ofs, d16->type, qcc_token); + ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->funcs.stringtable, d16->ofs, d16->type, qcc_token); } break; case PST_QTEST: @@ -1963,7 +1995,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) else { file = QCC_COM_Parse(file); - ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d32->ofs, d32->type, qcc_token); + ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->funcs.stringtable, d32->ofs, d32->type, qcc_token); } break; default: @@ -2027,12 +2059,12 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) PRAddressableFlush(progfuncs, -1); resethunk=true; - pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * maxprogs); + pr_progstate = PRHunkAlloc(progfuncs, sizeof(progstate_t) * maxprogs, "progstatetable"); pr_typecurrent=0; sv_num_edicts = 1; //set up a safty buffer so things won't go horribly wrong too often sv_edicts=(struct edict_s *)&tempedict; - prinst->edicttable = &sv_edicts; + prinst.edicttable = &sv_edicts; sv_num_edicts = numents; //should be fine @@ -2065,7 +2097,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) else { file = QCC_COM_Parse(file); - ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d16->ofs, d16->type, qcc_token); + ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->funcs.stringtable, d16->ofs, d16->type, qcc_token); } break; case PST_QTEST: @@ -2078,7 +2110,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) else { file = QCC_COM_Parse(file); - ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->stringtable, d32->ofs, d32->type, qcc_token); + ED_ParseEpair(progfuncs, (char*)pr_globals - progfuncs->funcs.stringtable, d32->ofs, d32->type, qcc_token); } break; default: @@ -2105,7 +2137,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (entsize == 0 && resethunk) //edicts have not yet been initialized, and this is a compleate load (memsize has been set) { - entsize = PR_InitEnts(progfuncs, maxedicts); + entsize = PR_InitEnts(&progfuncs->funcs, maxedicts); // sv_num_edicts = numents; for (num = 0; num < numents; num++) @@ -2123,7 +2155,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (!ed) //first entity ed = (edictrun_t *)EDICT_NUM(progfuncs, 0); else - ed = (edictrun_t *)ED_Alloc(progfuncs); + ed = (edictrun_t *)ED_Alloc(&progfuncs->funcs); ed->isfree = false; if (externs->entspawn) externs->entspawn((struct edict_s *) ed, true); @@ -2131,7 +2163,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) if (killonspawnflags) { - var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "spawnflags", &spawnflagscache); + var = QC_GetEdictFieldValue (&progfuncs->funcs, (struct edict_s *)ed, "spawnflags", &spawnflagscache); if (var) { if ((int)var->_float & (int)killonspawnflags) @@ -2148,13 +2180,13 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) char *eclassname; func_t f; if (!CheckSpawn) - CheckSpawn = PR_FindFunc(progfuncs, "CheckSpawn", -2); + CheckSpawn = PR_FindFunc(&progfuncs->funcs, "CheckSpawn", -2); - var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL); - if (!var || !var->string || !*PR_StringToNative(progfuncs, var->string)) + var = QC_GetEdictFieldValue (&progfuncs->funcs, (struct edict_s *)ed, "classname", NULL); + if (!var || !var->string || !*PR_StringToNative(&progfuncs->funcs, var->string)) { printf("No classname\n"); - ED_Free(progfuncs, (struct edict_s *)ed); + ED_Free(&progfuncs->funcs, (struct edict_s *)ed); } else { @@ -2163,52 +2195,52 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) { //essentually, it passes the ent's spawn info to the ent. char *nl; //otherwise it sees only the named fields of char *spawndata;//a standard quake ent. - spawndata = PRHunkAlloc(progfuncs, file - datastart +1); + spawndata = PRHunkAlloc(progfuncs, file - datastart +1, "fullspawndata"); strncpy(spawndata, datastart, file - datastart); spawndata[file - datastart] = '\0'; for (nl = spawndata; *nl; nl++) if (*nl == '\n') *nl = '\t'; - fulldata->string = PR_StringToProgs(progfuncs, spawndata); + fulldata->string = PR_StringToProgs(&progfuncs->funcs, spawndata); } if (!selfvar) - selfvar = PR_FindGlobal(progfuncs, "self", PR_ANY, NULL); + selfvar = PR_FindGlobal(&progfuncs->funcs, "self", PR_ANY, NULL); if (selfvar) selfvar->edict = EDICT_TO_PROG(progfuncs, ed); //DP_SV_SPAWNFUNC_PREFIX support - eclassname = PR_StringToNative(progfuncs, var->string); + eclassname = PR_StringToNative(&progfuncs->funcs, var->string); #ifdef _WIN32 _snprintf(filename, sizeof(filename), "spawnfunc_%s", eclassname); filename[sizeof(filename)-1] = 0; #else snprintf(filename, sizeof(filename), "spawnfunc_%s", eclassname); #endif - f = PR_FindFunc(progfuncs, filename, PR_ANYBACK); + f = PR_FindFunc(&progfuncs->funcs, filename, PR_ANYBACK); if (!f) - f = PR_FindFunc(progfuncs, eclassname, PR_ANYBACK); + f = PR_FindFunc(&progfuncs->funcs, eclassname, PR_ANYBACK); if (f) { if (CheckSpawn) { G_INT(OFS_PARM0) = f; - PR_ExecuteProgram(progfuncs, CheckSpawn); + PR_ExecuteProgram(&progfuncs->funcs, CheckSpawn); //call the spawn func or remove. } else - PR_ExecuteProgram(progfuncs, f); + PR_ExecuteProgram(&progfuncs->funcs, f); } else if (CheckSpawn) { G_INT(OFS_PARM0) = 0; - PR_ExecuteProgram(progfuncs, CheckSpawn); + PR_ExecuteProgram(&progfuncs->funcs, CheckSpawn); //the mod is responsible for freeing unrecognised ents. } else { - printf("Couldn't find spawn function %s\n", PR_StringToNative(progfuncs, var->string)); - ED_Free(progfuncs, (struct edict_s *)ed); + printf("Couldn't find spawn function %s\n", PR_StringToNative(&progfuncs->funcs, var->string)); + ED_Free(&progfuncs->funcs, (struct edict_s *)ed); } } } @@ -2239,8 +2271,9 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) #define AddS(str) strcpy(s, str);s+=strlen(str); -char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) +char *PDECL PR_SaveEnt (pubprogfuncs_t *ppf, char *buf, int *size, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; fdef_t *d; int *v; unsigned int i;unsigned int j; @@ -2255,11 +2288,11 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) AddS ("{\n"); - for (i=0 ; iname; len = strlen(name); // should we skip vars with no name? if (len > 2 && name[len-2] == '_') @@ -2277,7 +2310,7 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) //add it to the file AddS (qcva("\"%s\" ",name)); - AddS (qcva("\"%s\"\n", PR_UglyValueString(progfuncs, d->type, (eval_t *)v))); + AddS (qcva("\"%s\"\n", PR_UglyValueString(&progfuncs->funcs, d->type, (eval_t *)v))); } AddS ("}\n"); @@ -2286,8 +2319,9 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) return buf; } -struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) +struct edict_s *PDECL PR_RestoreEnt (pubprogfuncs_t *ppf, char *buf, int *size, struct edict_s *ed) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; edictrun_t *ent; char *start = buf; @@ -2299,7 +2333,7 @@ struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct Sys_Error("Restore Ent with no opening brace"); if (!ed) - ent = (edictrun_t *)ED_Alloc(progfuncs); + ent = (edictrun_t *)ED_Alloc(&progfuncs->funcs); else ent = (edictrun_t *)ed; ent->isfree = false; @@ -2360,7 +2394,7 @@ void PR_TestForWierdness(progfuncs_t *progfuncs) if ((pr_globaldefs16[i].type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string) { if (G_INT(pr_globaldefs16[i].ofs) < 0 || G_INT(pr_globaldefs16[i].ofs) >= addressableused) - printf("String type irregularity on \"%s\" \"%s\"\n", pr_globaldefs16[i].s_name+progfuncs->stringtable, G_INT(pr_globaldefs16[i].ofs)+progfuncs->stringtable); + printf("String type irregularity on \"%s\" \"%s\"\n", pr_globaldefs16[i].s_name+progfuncs->funcs.stringtable, G_INT(pr_globaldefs16[i].ofs)+progfuncs->funcs.stringtable); } } @@ -2374,7 +2408,7 @@ void PR_TestForWierdness(progfuncs_t *progfuncs) if (ed->isfree) continue; if (((int *)ed->fields)[field[i].ofs] < 0 || ((int *)ed->fields)[field[i].ofs] >= addressableused) - printf("String type irregularity \"%s\" \"%s\"\n", field[i].name, ((int *)ed->fields)[field[i].ofs]+progfuncs->stringtable); + printf("String type irregularity \"%s\" \"%s\"\n", field[i].name, ((int *)ed->fields)[field[i].ofs]+progfuncs->funcs.stringtable); } } } @@ -2412,7 +2446,7 @@ int PR_ReallyLoadProgs (progfuncs_t *progfuncs, char *filename, int headercrc, p int hmark=0xffffffff; - int reorg = prinst->reorganisefields || numfields; + int reorg = prinst.reorganisefields || prinst.numfields; int stringadjust; @@ -2462,7 +2496,7 @@ retry: } hmark = PRHunkMark(progfuncs); - pr_progs = PRHunkAlloc(progfuncs, len+1); + pr_progs = PRHunkAlloc(progfuncs, len+1, "proginfo"); if (!externs->ReadFile(filename, pr_progs, len+1)) { if (!complain) @@ -2595,7 +2629,7 @@ retry: default: Sys_Error("Bad struct type"); } - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dstatements"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_statements16), len, 2, (char *)(((int *)pr_statements16)+1), s); current_progstate->statements = (dstatement16_t *)s; @@ -2613,7 +2647,7 @@ retry: default: Sys_Error("Bad struct type"); } - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dglobaldefs"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_globaldefs16), len, 2, (char *)(((int *)pr_globaldefs16)+1), s); gd16 = *(ddef16_t**)¤t_progstate->globaldefs = (ddef16_t *)s; @@ -2631,7 +2665,7 @@ retry: default: Sys_Error("Bad struct type"); } - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "progfieldtable"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_fielddefs16), len, 2, (char *)(((int *)pr_fielddefs16)+1), s); *(ddef16_t**)¤t_progstate->fielddefs = (ddef16_t *)s; @@ -2639,7 +2673,7 @@ retry: if (pr_progs->blockscompressed & 8) //functions { len=sizeof(dfunction_t)*pr_progs->numfunctions; - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dfunctiontable"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_functions), len, 2, (char *)(((int *)pr_functions)+1), s); fnc = pr_functions = (dfunction_t *)s; @@ -2647,7 +2681,7 @@ retry: if (pr_progs->blockscompressed & 16) //string table { len=sizeof(char)*pr_progs->numstrings; - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dstringtable"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_strings), len, 2, (char *)(((int *)pr_strings)+1), s); pr_strings = (char *)s; @@ -2655,7 +2689,7 @@ retry: if (pr_progs->blockscompressed & 32) //globals { len=sizeof(float)*pr_progs->numglobals; - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dglobaltable"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_globals), len, 2, (char *)(((int *)pr_globals)+1), s); glob = pr_globals = (float *)s; @@ -2663,7 +2697,7 @@ retry: if (pr_linenums && pr_progs->blockscompressed & 64) //line numbers { len=sizeof(int)*pr_progs->numstatements; - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dlinenumtable"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_linenums), len, 2, (char *)(((int *)pr_linenums)+1), s); pr_linenums = (int *)s; @@ -2671,7 +2705,7 @@ retry: if (pr_types && pr_progs->blockscompressed & 128) //types { len=sizeof(typeinfo_t)*pr_progs->numtypes; - s = PRHunkAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len, "dtypes"); QC_decode(progfuncs, PRLittleLong(*(int *)pr_types), len, 2, (char *)(((int *)pr_types)+1), s); pr_types = (typeinfo_t *)s; @@ -2688,8 +2722,8 @@ retry: memcpy(s, pr_globals, len); glob = pr_globals = (float *)s; - if (progfuncs->stringtable) - stringadjust = pr_strings - progfuncs->stringtable; + if (progfuncs->funcs.stringtable) + stringadjust = pr_strings - progfuncs->funcs.stringtable; else stringadjust = 0; @@ -2707,7 +2741,7 @@ retry: strcat(lnoname, ".lno"); if ((len=externs->FileSize(lnoname))>0) { - file = PRHunkAlloc(progfuncs, len+1); + file = PRHunkAlloc(progfuncs, len+1, "line numbers"); if (externs->ReadFile(lnoname, file, len+1)) { if ( file[0] != lnotype @@ -2844,26 +2878,26 @@ retry: else type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); - if (progfuncs->fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in their original place. - QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1); + if (progfuncs->funcs.fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in their original place. + QC_RegisterFieldVar(&progfuncs->funcs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->funcs.fieldadjust), -1); else if (type == ev_vector) //emit vector vars early, so their fields cannot be alocated before the vector itself. (useful against scramblers) { - QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, -1, fld16[i].ofs); + QC_RegisterFieldVar(&progfuncs->funcs, type, fld16[i].s_name+pr_strings, -1, fld16[i].ofs); } } else { fdef_t *nf; - if (numfields+1>maxfields) + if (prinst.numfields+1>prinst.maxfields) { - i = maxfields; - maxfields += 32; - nf = memalloc(sizeof(fdef_t) * maxfields); - memcpy(nf, field, sizeof(fdef_t) * i); - memfree(field); - field = nf; + i = prinst.maxfields; + prinst.maxfields += 32; + nf = externs->memalloc(sizeof(fdef_t) * prinst.maxfields); + memcpy(nf, prinst.field, sizeof(fdef_t) * i); + externs->memfree(prinst.field); + prinst.field = nf; } - nf = &field[numfields]; + nf = &prinst.field[prinst.numfields]; nf->name = fld16[i].s_name+pr_strings; nf->type = fld16[i].type; nf->progsofs = fld16[i].ofs; @@ -2872,11 +2906,11 @@ retry: if (fields_size < (nf->ofs+type_size[nf->type])*4) fields_size = (nf->ofs+type_size[nf->type])*4; - numfields++; + prinst.numfields++; } fld16[i].s_name += stringadjust; } - if (reorg && !(progfuncs->fieldadjust && !pr_typecurrent)) + if (reorg && !(progfuncs->funcs.fieldadjust && !pr_typecurrent)) for (i=0 ; inumfielddefs ; i++) { if (pr_types) @@ -2884,7 +2918,7 @@ retry: else type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); if (type != ev_vector) - QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings-stringadjust, -1, fld16[i].ofs); + QC_RegisterFieldVar(&progfuncs->funcs, type, fld16[i].s_name+pr_strings-stringadjust, -1, fld16[i].ofs); } break; @@ -2932,14 +2966,14 @@ retry: type = pr_types[pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].type; else type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); - if (progfuncs->fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in their original place. - QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, 4*(pr_fielddefs32[i].ofs+progfuncs->fieldadjust), -1); + if (progfuncs->funcs.fieldadjust && !pr_typecurrent) //we need to make sure all fields appear in their original place. + QC_RegisterFieldVar(&progfuncs->funcs, type, pr_fielddefs32[i].s_name+pr_strings, 4*(pr_fielddefs32[i].ofs+progfuncs->funcs.fieldadjust), -1); else if (type == ev_vector) - QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, -1, pr_fielddefs32[i].ofs); + QC_RegisterFieldVar(&progfuncs->funcs, type, pr_fielddefs32[i].s_name+pr_strings, -1, pr_fielddefs32[i].ofs); } pr_fielddefs32[i].s_name += stringadjust; } - if (reorg && !(progfuncs->fieldadjust && !pr_typecurrent)) + if (reorg && !(progfuncs->funcs.fieldadjust && !pr_typecurrent)) for (i=0 ; inumfielddefs ; i++) { if (pr_types) @@ -2947,7 +2981,7 @@ retry: else type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); if (type != ev_vector) - QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings-stringadjust, -1, pr_fielddefs32[i].ofs); + QC_RegisterFieldVar(&progfuncs->funcs, type, pr_fielddefs32[i].s_name+pr_strings-stringadjust, -1, pr_fielddefs32[i].ofs); } break; default: @@ -3068,15 +3102,15 @@ retry: { gd16[i].type &= ~DEF_SHARED; if (pr_types) - QC_AddSharedVar(progfuncs, gd16[i].ofs, pr_types[gd16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size); + QC_AddSharedVar(&progfuncs->funcs, gd16[i].ofs, pr_types[gd16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size); else - QC_AddSharedVar(progfuncs, gd16[i].ofs, type_size[type]); + QC_AddSharedVar(&progfuncs->funcs, gd16[i].ofs, type_size[type]); } switch(type) { case ev_field: if (reorg) - QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust); + QC_AddSharedFieldVar(&progfuncs->funcs, i, pr_strings - stringadjust); break; case ev_string: if (((unsigned int *)glob)[gd16[i].ofs]>=progstate->progs->numstrings) @@ -3115,14 +3149,14 @@ retry: { pr_globaldefs32[i].type &= ~DEF_SHARED; if (pr_types) - QC_AddSharedVar(progfuncs, pr_globaldefs32[i].ofs, pr_types[pr_globaldefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size); + QC_AddSharedVar(&progfuncs->funcs, pr_globaldefs32[i].ofs, pr_types[pr_globaldefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL)].size); else - QC_AddSharedVar(progfuncs, pr_globaldefs32[i].ofs, type_size[type]); + QC_AddSharedVar(&progfuncs->funcs, pr_globaldefs32[i].ofs, type_size[type]); } switch(type) { case ev_field: - QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust); + QC_AddSharedFieldVar(&progfuncs->funcs, i, pr_strings - stringadjust); break; case ev_string: if (pr_strings[((int *)glob)[pr_globaldefs32[i].ofs]]) //quakec uses string tables. 0 must remain null, or 'if (s)' can break. @@ -3168,13 +3202,13 @@ retry: } pr_strings+=stringadjust; - if (!progfuncs->stringtable) - progfuncs->stringtable = pr_strings; + if (!progfuncs->funcs.stringtable) + progfuncs->funcs.stringtable = pr_strings; - if (progfuncs->stringtablesize + progfuncs->stringtable < pr_strings + pr_progs->numstrings) - progfuncs->stringtablesize = (pr_strings + pr_progs->numstrings) - progfuncs->stringtable; + if (progfuncs->funcs.stringtablesize + progfuncs->funcs.stringtable < pr_strings + pr_progs->numstrings) + progfuncs->funcs.stringtablesize = (pr_strings + pr_progs->numstrings) - progfuncs->funcs.stringtable; - eval = PR_FindGlobal(progfuncs, "thisprogs", progstype, NULL); + eval = PR_FindGlobal(&progfuncs->funcs, "thisprogs", progstype, NULL); if (eval) eval->prog = progstype; @@ -3195,7 +3229,7 @@ retry: return false; } - ((int *)glob)[d16->ofs] = PR_FindFunc(progfuncs, s, PR_ANY); + ((int *)glob)[d16->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY); if (!((int *)glob)[d16->ofs]) printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); /* @@ -3236,7 +3270,7 @@ retry: break; } - eval = PR_FindGlobal(progfuncs, "__ext__fasttrackarrays", PR_CURRENT, NULL); + eval = PR_FindGlobal(&progfuncs->funcs, "__ext__fasttrackarrays", PR_CURRENT, NULL); if (eval) //we support these opcodes eval->_float = true; @@ -3245,16 +3279,18 @@ retry: -struct edict_s *EDICT_NUM(progfuncs_t *progfuncs, unsigned int n) +struct edict_s *PDECL QC_EDICT_NUM(pubprogfuncs_t *ppf, unsigned int n) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; if (n >= maxedicts) Sys_Error ("QCLIB: EDICT_NUM: bad number %i", n); - return prinst->edicttable[n]; + return prinst.edicttable[n]; } -unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e) +unsigned int PDECL QC_NUM_FOR_EDICT(pubprogfuncs_t *ppf, struct edict_s *e) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; edictrun_t *er = (edictrun_t*)e; if (er->entnum >= maxedicts) Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%p)", e); diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index fedda46b..1b91634a 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -104,8 +104,9 @@ static void VARGS QC_snprintfz (char *dest, size_t size, const char *fmt, ...) #define QC_snprintfz snprintf #endif -void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char *out, int outlen) +void PDECL PR_GenerateStatementString (pubprogfuncs_t *ppf, int statementnum, char *out, int outlen) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int op; unsigned int arg[3]; @@ -173,7 +174,7 @@ void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char if (op == OP_IF_F || op == OP_IFNOT_F) { - QC_snprintfz (out, outlen, "%sbranch %i",PR_GlobalString(progfuncs, arg[0]),arg[1]); + QC_snprintfz (out, outlen, "%sbranch %i",PR_GlobalStringNoContents(progfuncs, arg[0]),arg[1]); outlen -= strlen(out); out += strlen(out); } @@ -185,7 +186,7 @@ void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char } else if ( (unsigned)(op - OP_STORE_F) < 6) { - QC_snprintfz (out, outlen, "%s",PR_GlobalString(progfuncs, arg[0])); + QC_snprintfz (out, outlen, "%s",PR_GlobalStringNoContents(progfuncs, arg[0])); outlen -= strlen(out); out += strlen(out); QC_snprintfz (out, outlen, "%s", PR_GlobalStringNoContents(progfuncs, arg[1])); @@ -196,13 +197,13 @@ void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char { if (arg[0]) { - QC_snprintfz (out, outlen, "%s",PR_GlobalString(progfuncs, arg[0])); + QC_snprintfz (out, outlen, "%s",PR_GlobalStringNoContents(progfuncs, arg[0])); outlen -= strlen(out); out += strlen(out); } if (arg[1]) { - QC_snprintfz (out, outlen, "%s",PR_GlobalString(progfuncs, arg[1])); + QC_snprintfz (out, outlen, "%s",PR_GlobalStringNoContents(progfuncs, arg[1])); outlen -= strlen(out); out += strlen(out); } @@ -239,8 +240,9 @@ char *QC_ucase(char *str) return s; } -void PR_StackTrace (progfuncs_t *progfuncs) +void PDECL PR_StackTrace (pubprogfuncs_t *ppf) { + progfuncs_t *progfuncs = (progfuncs_t *)ppf; dfunction_t *f; int i; int progs; @@ -280,13 +282,13 @@ void PR_StackTrace (progfuncs_t *progfuncs) printf ("<%s>\n", pr_progstate[progs].filename); } if (!f->s_file) - printf ("stripped : %s\n", f->s_name+progfuncs->stringtable); + printf ("stripped : %s\n", f->s_name+progfuncs->funcs.stringtable); else { if (pr_progstate[progs].linenums) - printf ("%12s %i : %s\n", f->s_file+progfuncs->stringtable, pr_progstate[progs].linenums[pr_stack[i].s], f->s_name+progfuncs->stringtable); + printf ("%12s:%i: %s\n", f->s_file+progfuncs->funcs.stringtable, pr_progstate[progs].linenums[pr_stack[i].s], f->s_name+progfuncs->funcs.stringtable); else - printf ("%12s : %s\n", f->s_file+progfuncs->stringtable, f->s_name+progfuncs->stringtable); + printf ("%12s : %s\n", f->s_file+progfuncs->funcs.stringtable, f->s_name+progfuncs->funcs.stringtable); } #ifdef STACKTRACE @@ -363,7 +365,7 @@ PR_RunError Aborts the currently executing function ============ */ -void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) +void VARGS PR_RunError (pubprogfuncs_t *progfuncs, char *error, ...) { va_list argptr; char string[1024]; @@ -379,14 +381,14 @@ void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) // PR_PrintStatement (pr_statements + pr_xstatement); PR_StackTrace (progfuncs); - printf ("\n"); + progfuncs->parms->Printf ("\n"); //editbadfile(pr_strings + pr_xfunction->s_file, -1); // pr_depth = 0; // dump the stack so host_error can shutdown functions // prinst->exitdepth = 0; - Abort ("%s", string); + progfuncs->parms->Abort ("%s", string); } /* @@ -404,7 +406,6 @@ PR_EnterFunction Returns the new program statement counter ==================== */ -void PR_AbortStack (progfuncs_t *progfuncs); int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum) { int i, j, c, o; @@ -417,13 +418,13 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsn if (pr_depth == MAX_STACK_DEPTH) { pr_depth--; - PR_StackTrace (progfuncs); + PR_StackTrace (&progfuncs->funcs); - printf ("stack overflow on call to %s\n", progfuncs->stringtable+f->s_name); + printf ("stack overflow on call to %s\n", progfuncs->funcs.stringtable+f->s_name); //comment this out if you want the progs to try to continue anyway (could cause infinate loops) - PR_AbortStack(progfuncs); - Abort("Stack Overflow in %s\n", progfuncs->stringtable+f->s_name); + PR_AbortStack(&progfuncs->funcs); + externs->Abort("Stack Overflow in %s\n", progfuncs->funcs.stringtable+f->s_name); return pr_xstatement; } @@ -435,7 +436,7 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsn { localstack_used -= pr_spushed; pr_depth--; - PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack overflow\n"); + PR_RunError (&progfuncs->funcs, "PR_ExecuteProgram: locals stack overflow\n"); } for (i=0 ; i < c ; i++) @@ -473,7 +474,7 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) c = pr_xfunction->locals; localstack_used -= c; if (localstack_used < 0) - PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack underflow\n"); + PR_RunError (&progfuncs->funcs, "PR_ExecuteProgram: locals stack underflow\n"); for (i=0 ; i < c ; i++) ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i]; @@ -509,7 +510,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) def16 = ED_GlobalAtOfs16(progfuncs, pr_xfunction->parm_start+i); if (!def16) continue; - if (!strcmp(def16->s_name+progfuncs->stringtable, name)) + if (!strcmp(def16->s_name+progfuncs->funcs.stringtable, name)) { *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i]; @@ -538,7 +539,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) def32 = ED_GlobalAtOfs32(progfuncs, pr_xfunction->parm_start+i); if (!def32) continue; - if (!strcmp(def32->s_name+progfuncs->stringtable, name)) + if (!strcmp(def32->s_name+progfuncs->funcs.stringtable, name)) { *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i]; @@ -560,7 +561,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) return &def; } -char *COM_TrimString(char *str) +static char *COM_TrimString(char *str) { int i; static char buffer[256]; @@ -648,18 +649,19 @@ pbool LocateDebugTerm(progfuncs_t *progfuncs, char *key, eval_t **result, etype_ return true; } -pbool PR_SetWatchPoint(progfuncs_t *progfuncs, char *key) +pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *ppf, char *key) { + progfuncs_t *progfuncs = (progfuncs_t *)ppf; eval_t *val; eval_t fakeval; etype_t type; if (!key) { - free(prinst->watch_name); - prinst->watch_name = NULL; - prinst->watch_ptr = NULL; - prinst->watch_type = ev_void; + free(prinst.watch_name); + prinst.watch_name = NULL; + prinst.watch_ptr = NULL; + prinst.watch_type = ev_void; return false; } if (!LocateDebugTerm(progfuncs, key, &val, &type, &fakeval)) @@ -678,16 +680,17 @@ pbool PR_SetWatchPoint(progfuncs_t *progfuncs, char *key) type = ev_float; } - free(prinst->watch_name); - prinst->watch_name = strdup(key); - prinst->watch_ptr = val; - prinst->watch_old = *prinst->watch_ptr; - prinst->watch_type = type; + free(prinst.watch_name); + prinst.watch_name = strdup(key); + prinst.watch_ptr = val; + prinst.watch_old = *prinst.watch_ptr; + prinst.watch_type = type; return true; } -char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) +char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *ppf, char *key) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; static char buf[256]; fdef_t *fdef; eval_t *val; @@ -755,7 +758,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) switch (type&~DEF_SAVEGLOBAL) { case ev_string: - *(string_t *)val = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, assignment, 0)); + *(string_t *)val = PR_StringToProgs(&progfuncs->funcs, ED_NewString (&progfuncs->funcs, assignment, 0)); break; case ev_float: @@ -852,7 +855,6 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key) return buf; } -int debugstatement; //int EditorHighlightLine(window_t *wnd, int line); void SetExecutionToLine(progfuncs_t *progfuncs, int linenum) { @@ -882,13 +884,14 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum) Sys_Error("Bad struct type"); snum = 0; } - debugstatement = snum; + prinst.debugstatement = snum; // EditorHighlightLine(editwnd, pr_progstate[pn].linenums[snum]); } //0 clear. 1 set, 2 toggle, 3 check -int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag) //write alternate route to work by function name. +int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum, int flag) //write alternate route to work by function name. { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int ret=0; unsigned int fl; unsigned int i; @@ -908,7 +911,7 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++) { - if (!stricmp(f->s_file+progfuncs->stringtable, filename)) + if (!stricmp(f->s_file+progfuncs->funcs.stringtable, filename)) { for (i = f->first_statement; ; i++) { @@ -987,7 +990,7 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int { for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++) { - if (!strcmp(f->s_name+progfuncs->stringtable, filename)) + if (!strcmp(f->s_name+progfuncs->funcs.stringtable, filename)) { i = f->first_statement; switch(pr_progstate[pn].structtype) @@ -1076,16 +1079,16 @@ static char *lastfile = 0; { if (pr_progstate[pn].linenums) { - if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->stringtable) + if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->funcs.stringtable) return statement; //no info/same line as last time lastline = pr_progstate[pn].linenums[statement]; } else lastline = -1; - lastfile = f->s_file+progfuncs->stringtable; + lastfile = f->s_file+progfuncs->funcs.stringtable; - lastline = externs->useeditor(progfuncs, lastfile, lastline, statement, 0, NULL); + lastline = externs->useeditor(&progfuncs->funcs, lastfile, lastline, statement, 0, NULL); if (lastline < 0) return -lastline; if (!pr_progstate[pn].linenums) @@ -1108,9 +1111,9 @@ static char *lastfile = 0; } else if (f) //annoying. { - if (*(f->s_file+progfuncs->stringtable)) //if we can't get the filename, then it was stripped, and debugging it like this is useless + if (*(f->s_file+progfuncs->funcs.stringtable)) //if we can't get the filename, then it was stripped, and debugging it like this is useless if (externs->useeditor) - externs->useeditor(progfuncs, f->s_file+progfuncs->stringtable, -1, 0, 0, NULL); + externs->useeditor(&progfuncs->funcs, f->s_file+progfuncs->funcs.stringtable, -1, 0, 0, NULL); return statement; } @@ -1138,33 +1141,33 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) eval_t *ptr; float *glob; + float tmpf; + int tmpi; - int fnum; - - if (prinst->watch_ptr && prinst->watch_ptr->_int != prinst->watch_old._int) + if (prinst.watch_ptr && prinst.watch_ptr->_int != prinst.watch_old._int) { - switch(prinst->watch_type) + switch(prinst.watch_type) { case ev_float: - printf("Watch point \"%s\" changed by engine from %g to %g.\n", prinst->watch_name, prinst->watch_old._float, prinst->watch_ptr->_float); + printf("Watch point \"%s\" changed by engine from %g to %g.\n", prinst.watch_name, prinst.watch_old._float, prinst.watch_ptr->_float); break; default: - printf("Watch point \"%s\" changed by engine from %i to %i.\n", prinst->watch_name, prinst->watch_old._int, prinst->watch_ptr->_int); + printf("Watch point \"%s\" changed by engine from %i to %i.\n", prinst.watch_name, prinst.watch_old._int, prinst.watch_ptr->_int); break; case ev_function: case ev_string: - printf("Watch point \"%s\" set by engine to %s.\n", prinst->watch_name, PR_ValueString(progfuncs, prinst->watch_type, prinst->watch_ptr)); + printf("Watch point \"%s\" set by engine to %s.\n", prinst.watch_name, PR_ValueString(progfuncs, prinst.watch_type, prinst.watch_ptr)); break; } - prinst->watch_old = *prinst->watch_ptr; + prinst.watch_old = *prinst.watch_ptr; //we can't dump stack or anything, as we don't really know the stack frame that it happened in. //stop watching - prinst->watch_ptr = NULL; +// prinst->watch_ptr = NULL; } - prinst->continuestatement = -1; + prinst.continuestatement = -1; #ifdef QCJIT if (current_progstate->jit) { @@ -1172,7 +1175,6 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) return; } #endif - fnum = pr_xfunction - pr_functions; runaway = 100000000; @@ -1181,9 +1183,9 @@ void PR_ExecuteCode (progfuncs_t *progfuncs, int s) if (!--runaway) \ { \ pr_xstatement = st-pr_statements; \ - PR_StackTrace(progfuncs); \ + PR_StackTrace(&progfuncs->funcs); \ printf ("runaway loop error\n"); \ - while(pr_depth > prinst->exitdepth) \ + while(pr_depth > prinst.exitdepth) \ PR_LeaveFunction(progfuncs); \ pr_spushed = 0; \ return; \ @@ -1201,7 +1203,7 @@ restart: //jumped to when the progs might have changed. case PST_QTEST: #define INTSIZE 16 st16 = &pr_statements16[s]; - while (pr_trace || prinst->watch_ptr) + while (progfuncs->funcs.pr_trace || prinst.watch_ptr) { #define DEBUGABLE #ifdef SEPARATEINCLUDES @@ -1223,7 +1225,7 @@ restart: //jumped to when the progs might have changed. case PST_FTE32: #define INTSIZE 32 st32 = &pr_statements32[s]; - while (pr_trace || prinst->watch_ptr) + while (progfuncs->funcs.pr_trace || prinst.watch_ptr) { #define DEBUGABLE #ifdef SEPARATEINCLUDES @@ -1251,8 +1253,9 @@ restart: //jumped to when the progs might have changed. } -void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum) +void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; dfunction_t *f; int i; unsigned int initial_progs; @@ -1287,7 +1290,7 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum) return; } - oldexitdepth = prinst->exitdepth; + oldexitdepth = prinst.exitdepth; f = &pr_functions[fnum & ~0xff000000]; @@ -1296,7 +1299,7 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum) i = -f->first_statement; if (i < externs->numglobalbuiltins) - (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals); + (*externs->globalbuiltins[i]) (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals); else { i -= externs->numglobalbuiltins; @@ -1307,31 +1310,31 @@ void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum) PR_SwitchProgs(progfuncs, initial_progs); return; } - current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals); + current_progstate->builtins [i] (&progfuncs->funcs, (struct globalvars_s *)current_progstate->globals); } PR_SwitchProgsParms(progfuncs, initial_progs); return; } - if (pr_trace) - pr_trace--; + if (progfuncs->funcs.pr_trace) + progfuncs->funcs.pr_trace--; // make a stack frame - prinst->exitdepth = pr_depth; + prinst.exitdepth = pr_depth; s = PR_EnterFunction (progfuncs, f, initial_progs); - tempdepth = prinst->numtempstringsstack; + tempdepth = prinst.numtempstringsstack; PR_ExecuteCode(progfuncs, s); PR_SwitchProgsParms(progfuncs, initial_progs); PR_FreeTemps(progfuncs, tempdepth); - prinst->numtempstringsstack = tempdepth; + prinst.numtempstringsstack = tempdepth; - prinst->exitdepth = oldexitdepth; + prinst.exitdepth = oldexitdepth; } @@ -1354,13 +1357,14 @@ typedef struct qcthread_s { progsnum_t xprogs; } qcthread_t; -struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs) +struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) { //QC code can call builtins that call qc code. //to get around the problems of restoring the builtins we simply don't save the thread over the builtin. + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int i, l; - int ed = prinst->exitdepth; + int ed = prinst.exitdepth; int localsoffset, baselocalsoffset; - qcthread_t *thread = memalloc(sizeof(qcthread_t)); + qcthread_t *thread = externs->memalloc(sizeof(qcthread_t)); dfunction_t *f; //copy out the functions stack. @@ -1423,8 +1427,9 @@ struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs) return thread; } -void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) +void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; dfunction_t *f, *oldf; int i,l,ls; progsnum_t initial_progs; @@ -1437,10 +1442,10 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) int fnum = thread->xfunction; if (localstack_used + thread->lstackused > LOCALSTACK_SIZE) - PR_RunError(progfuncs, "Too many locals on resumtion of QC thread\n"); + PR_RunError(&progfuncs->funcs, "Too many locals on resumtion of QC thread\n"); if (pr_depth + thread->fstackdepth > MAX_STACK_DEPTH) - PR_RunError(progfuncs, "Too large stack on resumtion of QC thread\n"); + PR_RunError(&progfuncs->funcs, "Too large stack on resumtion of QC thread\n"); //do progs switching stuff as appropriate. (fteqw only) @@ -1448,14 +1453,14 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) PR_SwitchProgsParms(progfuncs, prnum); - oldexitdepth = prinst->exitdepth; - prinst->exitdepth = pr_depth; + oldexitdepth = prinst.exitdepth; + prinst.exitdepth = pr_depth; ls = 0; //add on the callstack. for (i = 0; i < thread->fstackdepth; i++) { - if (pr_depth == prinst->exitdepth) + if (pr_depth == prinst.exitdepth) { pr_stack[pr_depth].f = pr_xfunction; pr_stack[pr_depth].s = pr_xstatement; @@ -1482,7 +1487,7 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) } if (ls != thread->lstackused) - PR_RunError(progfuncs, "Thread stores incorrect locals count\n"); + PR_RunError(&progfuncs->funcs, "Thread stores incorrect locals count\n"); f = &pr_functions[fnum]; @@ -1503,22 +1508,23 @@ void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread) pr_xfunction = f; s = thread->xstatement; - tempdepth = prinst->numtempstringsstack; + tempdepth = prinst.numtempstringsstack; PR_ExecuteCode(progfuncs, s); PR_SwitchProgsParms(progfuncs, initial_progs); PR_FreeTemps(progfuncs, tempdepth); - prinst->numtempstringsstack = tempdepth; + prinst.numtempstringsstack = tempdepth; - prinst->exitdepth = oldexitdepth; + prinst.exitdepth = oldexitdepth; pr_xfunction = oldf; } -void PR_AbortStack (progfuncs_t *progfuncs) +void PDECL PR_AbortStack (pubprogfuncs_t *ppf) { - while(pr_depth > prinst->exitdepth+1) + progfuncs_t *progfuncs = (progfuncs_t*)ppf; + while(pr_depth > prinst.exitdepth+1) PR_LeaveFunction(progfuncs); - prinst->continuestatement = 0; + prinst.continuestatement = 0; } diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index 13055312..e12c528f 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -27,7 +27,7 @@ pbool PR_SwitchProgs(progfuncs_t *progfuncs, progsnum_t type) current_progstate = NULL; return true; } - PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", type); + PR_RunError(&progfuncs->funcs, "QCLIB: Bad prog type - %i", type); // Sys_Error("Bad prog type - %i", type); } @@ -93,8 +93,9 @@ pbool PR_SwitchProgsParms(progfuncs_t *progfuncs, progsnum_t newpr) //from 2 to return PR_SwitchProgs(progfuncs, newpr); } -progsnum_t PR_LoadProgs(progfuncs_t *progfuncs, char *s, int headercrc, builtin_t *builtins, int numbuiltins) +progsnum_t PDECL PR_LoadProgs(pubprogfuncs_t *ppf, char *s, int headercrc, builtin_t *builtins, int numbuiltins) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; unsigned int a; progsnum_t oldtype; oldtype = pr_typecurrent; @@ -108,8 +109,8 @@ progsnum_t PR_LoadProgs(progfuncs_t *progfuncs, char *s, int headercrc, builtin_ { current_progstate->builtins = builtins; current_progstate->numbuiltins = numbuiltins; - if (a <= progfuncs->numprogs) - progfuncs->numprogs = a+1; + if (a <= progfuncs->funcs.numprogs) + progfuncs->funcs.numprogs = a+1; #ifdef QCJIT current_progstate->jit = PR_GenerateJit(progfuncs); @@ -154,11 +155,12 @@ void QC_StartShares(progfuncs_t *progfuncs) numshares = 0; maxshares = 32; if (shares) - memfree(shares); - shares = memalloc(sizeof(sharedvar_t)*maxshares); + externs->memfree(shares); + shares = externs->memalloc(sizeof(sharedvar_t)*maxshares); } -void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size) //fixme: make offset per progs and optional +void PDECL QC_AddSharedVar(pubprogfuncs_t *ppf, int start, int size) //fixme: make offset per progs and optional { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int ofs; unsigned int a; @@ -167,11 +169,11 @@ void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size) //fixme: make void *buf; buf = shares; maxshares += 16; - shares = memalloc(sizeof(sharedvar_t)*maxshares); + shares = externs->memalloc(sizeof(sharedvar_t)*maxshares); memcpy(shares, buf, sizeof(sharedvar_t)*numshares); - memfree(buf); + externs->memfree(buf); } ofs = start; for (a = 0; a < numshares; a++) @@ -197,14 +199,14 @@ void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size) //fixme: make void QC_InitShares(progfuncs_t *progfuncs) { // ShowWatch(); - if (!field) //don't make it so we will just need to remalloc everything + if (!prinst.field) //don't make it so we will just need to remalloc everything { - maxfields = 64; - field = memalloc(sizeof(fdef_t) * maxfields); + prinst.maxfields = 64; + prinst.field = externs->memalloc(sizeof(fdef_t) * prinst.maxfields); } - numfields = 0; - progfuncs->fieldadjust = 0; + prinst.numfields = 0; + progfuncs->funcs.fieldadjust = 0; } void QC_FlushProgsOffsets(progfuncs_t *progfuncs) @@ -212,8 +214,8 @@ void QC_FlushProgsOffsets(progfuncs_t *progfuncs) //fields are matched by name to other progs //not by offset unsigned int i; - for (i = 0; i < numfields; i++) - field[i].progsofs = -1; + for (i = 0; i < prinst.numfields; i++) + prinst.field[i].progsofs = -1; } @@ -227,8 +229,9 @@ void QC_FlushProgsOffsets(progfuncs_t *progfuncs) //origionaloffs is used to track matching field offsets. fields with the same progs offset overlap //note: we probably suffer from progs with renamed system globals. -int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long engineofs, signed long progsofs) +int PDECL QC_RegisterFieldVar(pubprogfuncs_t *ppf, unsigned int type, char *name, signed long engineofs, signed long progsofs) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; // progstate_t *p; // int pnum; unsigned int i; @@ -239,73 +242,73 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, s if (!name) //engine can use this to offset all progs fields { //which fixes constant field offsets (some ktpro arrays) - progfuncs->fieldadjust = fields_size/4; + progfuncs->funcs.fieldadjust = fields_size/4; return 0; } - prinst->reorganisefields = true; + prinst.reorganisefields = true; //look for an existing match - for (i = 0; i < numfields; i++) + for (i = 0; i < prinst.numfields; i++) { - if (!strcmp(name, field[i].name)) + if (!strcmp(name, prinst.field[i].name)) { - if (field[i].type != type) + if (prinst.field[i].type != type) { /*Hexen2/DP compat hack: if the new type is a float and the original type is a vector, make the new def alias to the engine's _x field this 'works around' the unused .vector color field used for rtlight colours vs the .float color used for particle colours (the float initialisers in map files will expand into the x slot safely). qc/hc can work around this by just using .vector color/color_x instead, which is the same as this hack, but would resolve defs to allow rtlight colours. */ - if (field[i].type != ev_vector || type != ev_float) + if (prinst.field[i].type != ev_vector || type != ev_float) { - printf("Field type mismatch on \"%s\". %i != %i\n", name, field[i].type, type); + printf("Field type mismatch on \"%s\". %i != %i\n", name, prinst.field[i].type, type); continue; } } - if (!progfuncs->fieldadjust && engineofs>=0) - if ((unsigned)engineofs/4 != field[i].ofs) + if (!progfuncs->funcs.fieldadjust && engineofs>=0) + if ((unsigned)engineofs/4 != prinst.field[i].ofs) Sys_Error("Field %s at wrong offset", name); - if (field[i].progsofs == -1) - field[i].progsofs = progsofs; -// printf("Dupfield %s %i -> %i\n", name, field[i].progsofs,field[i].ofs); - return field[i].ofs-progfuncs->fieldadjust; //got a match + if (prinst.field[i].progsofs == -1) + prinst.field[i].progsofs = progsofs; +// printf("Dupfield %s %i -> %i\n", name, prinst.field[i].progsofs,field[i].ofs); + return prinst.field[i].ofs-progfuncs->funcs.fieldadjust; //got a match } } - if (numfields+1>maxfields) + if (prinst.numfields+1>prinst.maxfields) { fdef_t *nf; - i = maxfields; - maxfields += 32; - nf = memalloc(sizeof(fdef_t) * maxfields); - memcpy(nf, field, sizeof(fdef_t) * i); - memfree(field); - field = nf; + i = prinst.maxfields; + prinst.maxfields += 32; + nf = externs->memalloc(sizeof(fdef_t) * prinst.maxfields); + memcpy(nf, prinst.field, sizeof(fdef_t) * i); + externs->memfree(prinst.field); + prinst.field = nf; } //try to add a new one - fnum = numfields; - numfields++; - field[fnum].name = name; + fnum = prinst.numfields; + prinst.numfields++; + prinst.field[fnum].name = name; if (type == ev_vector) { char *n; namelen = strlen(name)+5; - n=PRHunkAlloc(progfuncs, namelen); + n=PRHunkAlloc(progfuncs, namelen, "str"); sprintf(n, "%s_x", name); - ofs = QC_RegisterFieldVar(progfuncs, ev_float, n, engineofs, progsofs); - field[fnum].ofs = ofs+progfuncs->fieldadjust; + ofs = QC_RegisterFieldVar(&progfuncs->funcs, ev_float, n, engineofs, progsofs); + prinst.field[fnum].ofs = ofs+progfuncs->funcs.fieldadjust; - n=PRHunkAlloc(progfuncs, namelen); + n=PRHunkAlloc(progfuncs, namelen, "str"); sprintf(n, "%s_y", name); - QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+4), (progsofs==-1)?-1:progsofs+1); + QC_RegisterFieldVar(&progfuncs->funcs, ev_float, n, (engineofs==-1)?-1:(engineofs+4), (progsofs==-1)?-1:progsofs+1); - n=PRHunkAlloc(progfuncs, namelen); + n=PRHunkAlloc(progfuncs, namelen, "str"); sprintf(n, "%s_z", name); - QC_RegisterFieldVar(progfuncs, ev_float, n, (engineofs==-1)?-1:(engineofs+8), (progsofs==-1)?-1:progsofs+2); + QC_RegisterFieldVar(&progfuncs->funcs, ev_float, n, (engineofs==-1)?-1:(engineofs+8), (progsofs==-1)?-1:progsofs+2); } else if (engineofs >= 0) { //the engine is setting up a list of required field indexes. @@ -326,21 +329,21 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, s }*/ if (engineofs&3) Sys_Error("field %s is %i&3", name, (int)engineofs); - field[fnum].ofs = ofs = engineofs/4; + prinst.field[fnum].ofs = ofs = engineofs/4; } else { //we just found a new fieldname inside a progs - field[fnum].ofs = ofs = fields_size/4; //add on the end + prinst.field[fnum].ofs = ofs = fields_size/4; //add on the end //if the progs field offset matches annother offset in the same progs, make it match up with the earlier one. if (progsofs>=0) { - for (i = 0; i < numfields-1; i++) + for (i = 0; i < prinst.numfields-1; i++) { - if (field[i].progsofs == (unsigned)progsofs) + if (prinst.field[i].progsofs == (unsigned)progsofs) { // printf("found union field %s %i -> %i\n", field[i].name, field[i].progsofs, field[i].ofs); - field[fnum].ofs = ofs = field[i].ofs; + prinst.field[fnum].ofs = ofs = prinst.field[i].ofs; break; } } @@ -352,20 +355,21 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, s if (max_fields_size && fields_size > max_fields_size) Sys_Error("Allocated too many additional fields after ents were inited."); - field[fnum].type = type; + prinst.field[fnum].type = type; - field[fnum].progsofs = progsofs; + prinst.field[fnum].progsofs = progsofs; // printf("Field %s %i -> %i\n", name, field[fnum].progsofs,field[fnum].ofs); //we've finished setting the structure - return ofs - progfuncs->fieldadjust; + return ofs - progfuncs->funcs.fieldadjust; } //called if a global is defined as a field -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) +void PDECL QC_AddSharedFieldVar(pubprogfuncs_t *ppf, int num, char *stringtable) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; // progstate_t *p; // int pnum; unsigned int i, o; @@ -396,7 +400,7 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) if (!strcmp(pr_fielddefs16[i].s_name+stringtable, pr_globaldefs16[num].s_name+stringtable)) { // int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs]; - *(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); + *(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(&progfuncs->funcs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); // printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); return; @@ -405,13 +409,13 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) s = pr_globaldefs16[num].s_name+stringtable; - for (i = 0; i < numfields; i++) + for (i = 0; i < prinst.numfields; i++) { - o = field[i].progsofs; + o = prinst.field[i].progsofs; if (o == *(unsigned int *)&pr_globals[pr_globaldefs16[num].ofs]) { // int old = *(int *)&pr_globals[pr_globaldefs16[num].ofs]; - *(int *)&pr_globals[pr_globaldefs16[num].ofs] = field[i].ofs-progfuncs->fieldadjust; + *(int *)&pr_globals[pr_globaldefs16[num].ofs] = prinst.field[i].ofs-progfuncs->funcs.fieldadjust; // printf("Field %s %i -> %i\n", pr_globaldefs16[num].s_name+stringtable, old, *(int *)&pr_globals[pr_globaldefs16[num].ofs]); return; } @@ -427,19 +431,19 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) { if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable)) { - *(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs]); + *(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(&progfuncs->funcs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs]); return; } } s = pr_globaldefs32[num].s_name+stringtable; - for (i = 0; i < numfields; i++) + for (i = 0; i < prinst.numfields; i++) { - o = field[i].progsofs; + o = prinst.field[i].progsofs; if (o == *(unsigned int *)&pr_globals[pr_globaldefs32[num].ofs]) { - *(int *)&pr_globals[pr_globaldefs32[num].ofs] = field[i].ofs-progfuncs->fieldadjust; + *(int *)&pr_globals[pr_globaldefs32[num].ofs] = prinst.field[i].ofs-progfuncs->funcs.fieldadjust; return; } } diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 0f0f6075..ae3074ff 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -1,8 +1,14 @@ #ifdef _WIN32 #ifndef _CRT_SECURE_NO_WARNINGS - #define _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS #endif #define _CRT_NONSTDC_NO_WARNINGS + #ifndef _CRT_SECURE_NO_DEPRECATE + #define _CRT_SECURE_NO_DEPRECATE + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif #ifndef AVAIL_ZLIB #ifdef _MSC_VER //#define AVAIL_ZLIB @@ -10,8 +16,6 @@ #endif #include - - enum{false, true}; #else #include #include @@ -24,8 +28,6 @@ #ifndef __declspec #define __declspec(mode) #endif - - typedef enum{false, true} boolean; //#define _inline inline #endif typedef unsigned char qbyte; @@ -36,20 +38,135 @@ typedef unsigned char qbyte; #define PROGSUSED #endif +#define false 0 +#define true 1 + #include "progtype.h" #include "progslib.h" +#include "pr_comp.h" + #ifdef _MSC_VER #pragma warning(disable : 4244) #pragma warning(disable : 4267) #endif //extern progfuncs_t *progfuncs; +typedef struct sharedvar_s +{ + int varofs; + int size; +} sharedvar_t; +typedef struct +{ + int s; + dfunction_t *f; + int progsnum; + int pushed; +} prstack_t; + +typedef struct prinst_s + { + char **tempstrings; + int maxtempstrings; + int numtempstrings; + int numtempstringsstack; + + char **allocedstrings; + int maxallocedstrings; + int numallocedstrings; + + struct progstate_s * progstate; +#define pr_progstate prinst.progstate + + progsnum_t pr_typecurrent; +#define pr_typecurrent prinst.pr_typecurrent + unsigned int maxprogs; +#define maxprogs prinst.maxprogs + + struct progstate_s *current_progstate; +#define current_progstate prinst.current_progstate + + char * watch_name; + eval_t * watch_ptr; + eval_t watch_old; + etype_t watch_type; + + unsigned int numshares; +#define numshares prinst.numshares + sharedvar_t *shares; //shared globals, not including parms +#define shares prinst.shares + unsigned int maxshares; +#define maxshares prinst.maxshares + + struct prmemb_s *memblocks; +#define memb prinst.memblocks + + unsigned int maxfields; + unsigned int numfields; + fdef_t *field; //biggest size + +int reorganisefields; + + +//pr_exec.c +#define MAX_STACK_DEPTH 64 + prstack_t pr_stack[MAX_STACK_DEPTH]; +#define pr_stack prinst.pr_stack + int pr_depth; +#define pr_depth prinst.pr_depth + int spushed; +#define pr_spushed prinst.spushed + +#define LOCALSTACK_SIZE 4096 + int localstack[LOCALSTACK_SIZE]; +#define localstack prinst.localstack + int localstack_used; +#define localstack_used prinst.localstack_used + + int debugstatement; + int continuestatement; + int exitdepth; + + dfunction_t *pr_xfunction; +#define pr_xfunction prinst.pr_xfunction + int pr_xstatement; +#define pr_xstatement prinst.pr_xstatement + +//pr_edict.c + + unsigned int maxedicts; +#define maxedicts prinst.maxedicts + + evalc_t spawnflagscache; +#define spawnflagscache prinst.spawnflagscache + + + + + unsigned int fields_size; // in bytes +#define fields_size prinst.fields_size + unsigned int max_fields_size; +#define max_fields_size prinst.max_fields_size + + +//initlib.c + int mfreelist; + char * addressablehunk; + unsigned int addressableused; + unsigned int addressablesize; + + struct edict_s **edicttable; +} prinst_t; + +typedef struct progfuncs_s +{ + struct pubprogfuncs_s funcs; + struct prinst_s inst; //private fields. Leave alone. +} progfuncs_t; #define prinst progfuncs->inst -#define externs progfuncs->parms - -#include "pr_comp.h" +#define externs progfuncs->funcs.parms #include "qcd.h" @@ -77,16 +194,12 @@ extern QCC_opcode_t pr_opcodes[]; // sized by initialization #define sv_num_edicts (*externs->sv_num_edicts) #define sv_edicts (*externs->sv_edicts) -#define printf externs->printf +#define printf externs->Printf #define Sys_Error externs->Sys_Error -#define Abort externs->Abort - -#define memalloc externs->memalloc -#define memfree externs->memfree int PRHunkMark(progfuncs_t *progfuncs); void PRHunkFree(progfuncs_t *progfuncs, int mark); -void *PRHunkAlloc(progfuncs_t *progfuncs, int size); +void *PRHunkAlloc(progfuncs_t *progfuncs, int size, char *name); void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount); #ifdef printf @@ -98,11 +211,11 @@ void *PRAddressableExtend(progfuncs_t *progfuncs, int ammount); char *VARGS qcva (char *text, ...) LIKEPRINTF(1); void QC_InitShares(progfuncs_t *progfuncs); void QC_StartShares(progfuncs_t *progfuncs); -void QC_AddSharedVar(progfuncs_t *progfuncs, int num, int type); -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable); -int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long requestedpos, signed long originalofs); -pbool Decompile(progfuncs_t *progfuncs, char *fname); -int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag); +void PDECL QC_AddSharedVar(pubprogfuncs_t *progfuncs, int num, int type); +void PDECL QC_AddSharedFieldVar(pubprogfuncs_t *progfuncs, int num, char *stringtable); +int PDECL QC_RegisterFieldVar(pubprogfuncs_t *progfuncs, unsigned int type, char *name, signed long requestedpos, signed long originalofs); +pbool PDECL QC_Decompile(pubprogfuncs_t *progfuncs, char *fname); +int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *progfuncs, char *filename, int linenum, int flag); void StripExtension (char *path); @@ -147,16 +260,16 @@ typedef struct edictrun_s } edictrun_t; -int Comp_Begin(progfuncs_t *progfuncs, int nump, char **parms); -int Comp_Continue(progfuncs_t *progfuncs); +int PDECL Comp_Begin(pubprogfuncs_t *progfuncs, int nump, char **parms); +int PDECL Comp_Continue(pubprogfuncs_t *progfuncs); -pbool PR_SetWatchPoint(progfuncs_t *progfuncs, char *key); -char *EvaluateDebugString(progfuncs_t *progfuncs, char *key); -char *SaveEnts(progfuncs_t *progfuncs, char *mem, int *size, int mode); -int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags); -char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); -struct edict_s *RestoreEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); -void PR_StackTrace (progfuncs_t *progfuncs); +pbool PDECL PR_SetWatchPoint(pubprogfuncs_t *progfuncs, char *key); +char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *progfuncs, char *key); +char *PDECL PR_SaveEnts(pubprogfuncs_t *progfuncs, char *mem, int *size, int mode); +int PDECL PR_LoadEnts(pubprogfuncs_t *progfuncs, char *file, float killonspawnflags); +char *PDECL PR_SaveEnt (pubprogfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); +struct edict_s *PDECL PR_RestoreEnt (pubprogfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed); +void PDECL PR_StackTrace (pubprogfuncs_t *progfuncs); extern int noextensions; @@ -236,21 +349,21 @@ typedef struct extensionbuiltin_s { void PR_Init (void); -void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum); -int PR_LoadProgs(progfuncs_t *progfncs, char *s, int headercrc, builtin_t *builtins, int numbuiltins); +void PDECL PR_ExecuteProgram (pubprogfuncs_t *progfuncs, func_t fnum); +int PDECL PR_LoadProgs(pubprogfuncs_t *progfncs, char *s, int headercrc, builtin_t *builtins, int numbuiltins); int PR_ReallyLoadProgs (progfuncs_t *progfuncs, char *filename, int headercrc, progstate_t *progstate, pbool complain); -void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount); +void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, char *name); void PR_Profile_f (void); -struct edict_s *ED_Alloc (progfuncs_t *progfuncs); -void ED_Free (progfuncs_t *progfuncs, struct edict_s *ed); +struct edict_s *PDECL ED_Alloc (pubprogfuncs_t *progfuncs); +void PDECL ED_Free (pubprogfuncs_t *progfuncs, struct edict_s *ed); -char *ED_NewString (progfuncs_t *progfuncs, char *string, int minlength); +char *PDECL ED_NewString (pubprogfuncs_t *progfuncs, char *string, int minlength); // returns a copy of the string allocated from the server's string heap -void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed); +void PDECL ED_Print (pubprogfuncs_t *progfuncs, struct edict_s *ed); //void ED_Write (FILE *f, edictrun_t *ed); char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent); @@ -262,13 +375,16 @@ void ED_ParseGlobals (char *data); //define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size)) //define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size) -struct edict_s *EDICT_NUM(progfuncs_t *progfuncs, unsigned int n); -unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e); +struct edict_s *PDECL QC_EDICT_NUM(pubprogfuncs_t *progfuncs, unsigned int n); +unsigned int PDECL QC_NUM_FOR_EDICT(pubprogfuncs_t *progfuncs, struct edict_s *e); + +#define EDICT_NUM(pf, num) QC_EDICT_NUM(&pf->funcs,num) +#define NUM_FOR_EDICT(pf, e) QC_NUM_FOR_EDICT(&pf->funcs,e) //#define NEXT_EDICT(e) ((edictrun_t *)( (byte *)e + pr_edict_size)) #define EDICT_TO_PROG(pf, e) (((edictrun_t*)e)->entnum) -#define PROG_TO_EDICT(pf, e) ((struct edictrun_s *)prinst->edicttable[e]) +#define PROG_TO_EDICT(pf, e) ((struct edictrun_s *)prinst.edicttable[e]) //============================================================================ @@ -297,7 +413,7 @@ const extern unsigned int type_size[]; extern unsigned short pr_crc; -void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) LIKEPRINTF(2); +void VARGS PR_RunError (pubprogfuncs_t *progfuncs, char *error, ...) LIKEPRINTF(2); void ED_PrintEdicts (progfuncs_t *progfuncs); void ED_PrintNum (progfuncs_t *progfuncs, int ent); @@ -309,7 +425,11 @@ pbool PR_SwitchProgsParms(progfuncs_t *progfuncs, progsnum_t newprogs); -eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *name, evalc_t *cache); +eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *progfuncs, struct edict_s *ed, char *name, evalc_t *cache); +void PDECL PR_GenerateStatementString (pubprogfuncs_t *progfuncs, int statementnum, char *out, int outlen); +fdef_t *PDECL ED_FieldInfo (pubprogfuncs_t *progfuncs, unsigned int *count); +char *PDECL PR_UglyValueString (pubprogfuncs_t *progfuncs, etype_t type, eval_t *val); +pbool PDECL ED_ParseEval (pubprogfuncs_t *progfuncs, eval_t *eval, int type, char *s); #endif @@ -326,132 +446,18 @@ eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *nam #endif -typedef struct { - int varofs; - int size; -} sharedvar_t; -typedef struct -{ - int s; - dfunction_t *f; - int progsnum; - int pushed; -} prstack_t; - //pr_multi.c void PR_SetBuiltins(int type); -#define var(type, name) type name -#define vars(type, name, size) type name[size] - -typedef struct prinst_s { - char **tempstrings; - int maxtempstrings; - int numtempstrings; - int numtempstringsstack; - - char **allocedstrings; - int maxallocedstrings; - int numallocedstrings; - -var(progstate_t *, progstate); -#define pr_progstate prinst->progstate - -var(progsnum_t, pr_typecurrent); -#define pr_typecurrent prinst->pr_typecurrent -var(unsigned int, maxprogs); -#define maxprogs prinst->maxprogs - -var(progstate_t *,current_progstate); -#define current_progstate prinst->current_progstate - -var(char *, watch_name); -var(eval_t *, watch_ptr); -var(eval_t, watch_old); -var(etype_t, watch_type); - -var(unsigned int, numshares); -#define numshares prinst->numshares -var(sharedvar_t *,shares); //shared globals, not including parms -#define shares prinst->shares -var(unsigned int, maxshares); -#define maxshares prinst->maxshares - -var(struct prmemb_s *, memblocks); -#define memb prinst->memblocks - -var(unsigned int, maxfields); -#define maxfields prinst->maxfields -var(unsigned int, numfields); -#define numfields prinst->numfields -var(fdef_t*, field); //biggest size -#define field prinst->field - -int reorganisefields; - - -//pr_exec.c -#define MAX_STACK_DEPTH 64 -vars(prstack_t, pr_stack, MAX_STACK_DEPTH); -#define pr_stack prinst->pr_stack -var(int, pr_depth); -#define pr_depth prinst->pr_depth -var(int, spushed); -#define pr_spushed prinst->spushed - -#define LOCALSTACK_SIZE 4096 -vars(int, localstack, LOCALSTACK_SIZE); -#define localstack prinst->localstack -var(int, localstack_used); -#define localstack_used prinst->localstack_used - -var(int, continuestatement); -var(int, exitdepth); - -var(int, pr_trace); -#define pr_trace prinst->pr_trace -var(dfunction_t *, pr_xfunction); -#define pr_xfunction prinst->pr_xfunction -var(int, pr_xstatement); -#define pr_xstatement prinst->pr_xstatement - -var(int, pr_argc); -#define pr_argc prinst->pr_argc - -//pr_edict.c - -var(unsigned int, maxedicts); -#define maxedicts prinst->maxedicts - -var(evalc_t, spawnflagscache); -#define spawnflagscache prinst->spawnflagscache - - - - -var(unsigned int, fields_size); // in bytes -#define fields_size prinst->fields_size -var(unsigned int, max_fields_size); -#define max_fields_size prinst->max_fields_size - - -//initlib.c -int mfreelist; -var(char *, addressablehunk); -var(unsigned int, addressableused); -var(unsigned int, addressablesize); - - -//var(extensionbuiltin_t *, extensionbuiltin); -//#define extensionbuiltin prinst->extensionbuiltin - - struct edict_s **edicttable; -} prinst_t; extern vec3_t vec3_origin; -eval_t *PR_FindGlobal(progfuncs_t *prfuncs, char *globname, progsnum_t pnum, etype_t *type); +struct qcthread_s *PDECL PR_ForkStack (pubprogfuncs_t *progfuncs); +void PDECL PR_ResumeThread (pubprogfuncs_t *progfuncs, struct qcthread_s *thread); +void PDECL PR_AbortStack (pubprogfuncs_t *progfuncs); + +eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *prfuncs, char *globname, progsnum_t pnum, etype_t *type); ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type); ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum_t prnum, int type); ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum); @@ -459,11 +465,11 @@ ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum fdef_t *ED_FindField (progfuncs_t *progfuncs, char *name); fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs); dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pnum, progsnum_t fromprogs); -func_t PR_FindFunc(progfuncs_t *progfncs, char *funcname, progsnum_t pnum); -void PR_Configure (progfuncs_t *progfncs, int addressable_size, int max_progs); -int PR_InitEnts(progfuncs_t *progfncs, int maxents); +func_t PDECL PR_FindFunc(pubprogfuncs_t *progfncs, char *funcname, progsnum_t pnum); +void PDECL PR_Configure (pubprogfuncs_t *progfncs, int addressable_size, int max_progs); +int PDECL PR_InitEnts(pubprogfuncs_t *progfncs, int maxents); char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val); -void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed); +void PDECL QC_ClearEdict (pubprogfuncs_t *progfuncs, struct edict_s *ed); void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount); void QC_FlushProgsOffsets(progfuncs_t *progfuncs); @@ -472,8 +478,8 @@ ddef16_t *ED_FindGlobal16 (progfuncs_t *progfuncs, char *name); ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name); ddef32_t *ED_GlobalAtOfs32 (progfuncs_t *progfuncs, unsigned int ofs); -string_t PR_StringToProgs (progfuncs_t *inst, char *str); -char *ASMCALL PR_StringToNative (progfuncs_t *inst, string_t str); +string_t PDECL PR_StringToProgs (pubprogfuncs_t *inst, char *str); +char *ASMCALL PR_StringToNative (pubprogfuncs_t *inst, string_t str); void PR_FreeTemps (progfuncs_t *progfuncs, int depth); diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 32277df8..dbba654c 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -18,20 +18,26 @@ //#define QCJIT #endif +#define QCBUILTIN ASMCALL + +#ifdef _WIN32 +#define PDECL __cdecl +#else +#define PDECL +#endif + #ifdef QCJIT #define ASMCALL VARGS #else -#define ASMCALL +#define ASMCALL PDECL #endif -#define QCBUILTIN ASMCALL - struct edict_s; struct entvars_s; struct globalvars_s; struct qcthread_s; -typedef struct progfuncs_s progfuncs_t; -typedef void (ASMCALL *builtin_t) (progfuncs_t *prinst, struct globalvars_s *gvars); +typedef struct pubprogfuncs_s pubprogfuncs_t; +typedef void (ASMCALL *builtin_t) (pubprogfuncs_t *prinst, struct globalvars_s *gvars); //used by progs engine. All nulls is reset. typedef struct { @@ -54,130 +60,138 @@ typedef struct fdef_s //the number of pointers to variables (as opposed to functions - those are fine) in these structures is excessive. //Many of the functions are also obsolete. -struct progfuncs_s { +struct pubprogfuncs_s +{ int progsversion; //PROGSTRUCT_VERSION + void (PDECL *CloseProgs) (pubprogfuncs_t *inst); - void (*Configure) (progfuncs_t *prinst, int addressablesize, int max_progs); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM. - progsnum_t (*LoadProgs) (progfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs - int (*InitEnts) (progfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro - void (*ExecuteProgram) (progfuncs_t *prinst, func_t fnum); //start execution - pbool (*SwitchProgs) (progfuncs_t *prinst, progsnum_t num); //switch to a different progs - this should be obsolete. - struct globalvars_s *(*globals) (progfuncs_t *prinst, progsnum_t num); //get the globals of a progs - struct entvars_s *(*entvars) (progfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete. + void (PDECL *Configure) (pubprogfuncs_t *prinst, int addressablesize, int max_progs); //configure buffers and memory. Used to reset and must be called first. Flushes a running VM. + progsnum_t (PDECL *LoadProgs) (pubprogfuncs_t *prinst, char *s, int headercrc, builtin_t *builtins, int numbuiltins); //load a progs + int (PDECL *InitEnts) (pubprogfuncs_t *prinst, int max_ents); //returns size of edicts for use with nextedict macro + void (PDECL *ExecuteProgram) (pubprogfuncs_t *prinst, func_t fnum); //start execution + struct globalvars_s *(PDECL *globals) (pubprogfuncs_t *prinst, progsnum_t num); //get the globals of a progs + struct entvars_s *(PDECL *entvars) (pubprogfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete. - void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem - void (*PrintEdict) (progfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print') + void (VARGS *RunError) (pubprogfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem + void (PDECL *PrintEdict) (pubprogfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print') - struct edict_s *(*EntAlloc) (progfuncs_t *prinst); - void (*EntFree) (progfuncs_t *prinst, struct edict_s *ed); + struct edict_s *(PDECL *EntAlloc) (pubprogfuncs_t *prinst); + void (PDECL *EntFree) (pubprogfuncs_t *prinst, struct edict_s *ed); - struct edict_s *(*EDICT_NUM) (progfuncs_t *prinst, unsigned int n); //get the nth edict - unsigned int (*NUM_FOR_EDICT) (progfuncs_t *prinst, struct edict_s *e); //so you can find out what that 'n' will be + struct edict_s *(PDECL *EDICT_NUM) (pubprogfuncs_t *prinst, unsigned int n); //get the nth edict + unsigned int (PDECL *NUM_FOR_EDICT) (pubprogfuncs_t *prinst, struct edict_s *e); //so you can find out what that 'n' will be - void (*SetGlobalEdict) (progfuncs_t *prinst, struct edict_s *ed, int ofs); //set a global to an edict (partially obsolete) + void (PDECL *SetGlobalEdict) (pubprogfuncs_t *prinst, struct edict_s *ed, int ofs); //set a global to an edict (partially obsolete) - char *(*VarString) (progfuncs_t *prinst, int first); //returns a string made up of multiple arguments + char *(PDECL *VarString) (pubprogfuncs_t *prinst, int first); //returns a string made up of multiple arguments struct progstate_s **progstate; //internal to the library. - func_t (*FindFunction) (progfuncs_t *prinst, char *funcname, progsnum_t num); + func_t (PDECL *FindFunction) (pubprogfuncs_t *prinst, char *funcname, progsnum_t num); - int (*StartCompile) (progfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile - int (*ContinueCompile) (progfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed + int (PDECL *StartCompile) (pubprogfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile + int (PDECL *ContinueCompile) (pubprogfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed - char *(*filefromprogs) (progfuncs_t *prinst, progsnum_t prnum, char *fname, int *size, char *buffer); //reveals encoded/added files from already loaded progs - char *(*filefromnewprogs) (progfuncs_t *prinst, char *prname, char *fname, int *size, char *buffer); //reveals encoded/added files from a progs on the disk somewhere + char *(PDECL *filefromprogs) (pubprogfuncs_t *prinst, progsnum_t prnum, char *fname, int *size, char *buffer); //reveals encoded/added files from already loaded progs + char *(PDECL *filefromnewprogs) (pubprogfuncs_t *prinst, char *prname, char *fname, int *size, char *buffer); //reveals encoded/added files from a progs on the disk somewhere - char *(*save_ents) (progfuncs_t *prinst, char *buf, int *size, int mode); //dump the entire progs info into one big self allocated string - int (*load_ents) (progfuncs_t *prinst, char *s, float killonspawnflags); //restore the entire progs state (or just add some more ents) (returns edicts ize) + void (PDECL *ED_Print) (pubprogfuncs_t *prinst, struct edict_s *ed); + char *(PDECL *save_ents) (pubprogfuncs_t *prinst, char *buf, int *size, int mode); //dump the entire progs info into one big self allocated string + int (PDECL *load_ents) (pubprogfuncs_t *prinst, char *s, float killonspawnflags); //restore the entire progs state (or just add some more ents) (returns edicts ize) - char *(*saveent) (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will save just one entities vars - struct edict_s *(*restoreent) (progfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will restore the entity that had it's values saved (can use NULL for ed) + char *(PDECL *saveent) (pubprogfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will save just one entities vars + struct edict_s *(PDECL *restoreent) (pubprogfuncs_t *prinst, char *buf, int *size, struct edict_s *ed); //will restore the entity that had it's values saved (can use NULL for ed) - union eval_s *(*FindGlobal) (progfuncs_t *prinst, char *name, progsnum_t num, etype_t *type); //find a pointer to the globals value - char *(*AddString) (progfuncs_t *prinst, char *val, int minlength); //dump a string into the progs memory (for setting globals and whatnot) - void *(*Tempmem) (progfuncs_t *prinst, int ammount, char *whatfor); //grab some mem for as long as the progs stays loaded + union eval_s *(PDECL *FindGlobal) (pubprogfuncs_t *prinst, char *name, progsnum_t num, etype_t *type); //find a pointer to the globals value + char *(PDECL *AddString) (pubprogfuncs_t *prinst, char *val, int minlength); //dump a string into the progs memory (for setting globals and whatnot) + void *(PDECL *Tempmem) (pubprogfuncs_t *prinst, int ammount, char *whatfor); //grab some mem for as long as the progs stays loaded - union eval_s *(*GetEdictFieldValue) (progfuncs_t *prinst, struct edict_s *ent, char *name, evalc_t *s); //get an entityvar (cache it) and return the possible values - struct edict_s *(*ProgsToEdict) (progfuncs_t *prinst, int progs); //edicts are stored as ints and need to be adjusted - int (*EdictToProgs) (progfuncs_t *prinst, struct edict_s *ed); //edicts are stored as ints and need to be adjusted + union eval_s *(PDECL *GetEdictFieldValue)(pubprogfuncs_t *prinst, struct edict_s *ent, char *name, evalc_t *s); //get an entityvar (cache it) and return the possible values + struct edict_s *(PDECL *ProgsToEdict) (pubprogfuncs_t *prinst, int progs); //edicts are stored as ints and need to be adjusted + int (PDECL *EdictToProgs) (pubprogfuncs_t *prinst, struct edict_s *ed); //edicts are stored as ints and need to be adjusted - char *(*EvaluateDebugString) (progfuncs_t *prinst, char *key); //evaluate a string and return it's value (according to current progs) (expands edict vars) + char *(PDECL *EvaluateDebugString) (pubprogfuncs_t *prinst, char *key); //evaluate a string and return it's value (according to current progs) (expands edict vars) - int *pr_trace; //start calling the editor for each line executed + int pr_trace; //start calling the editor for each line executed - void (*StackTrace) (progfuncs_t *prinst); + void (PDECL *StackTrace) (pubprogfuncs_t *prinst); - int (*ToggleBreak) (progfuncs_t *prinst, char *filename, int linenum, int mode); + int (PDECL *ToggleBreak) (pubprogfuncs_t *prinst, char *filename, int linenum, int mode); int numprogs; struct progexterns_s *parms; //these are the initial parms, they may be changed - pbool (*Decompile) (progfuncs_t *prinst, char *fname); + pbool (PDECL *Decompile) (pubprogfuncs_t *prinst, char *fname); - - struct prinst_s *inst; //internal variables. Leave alone. - - int *callargc; //number of args of built-in call - void (*RegisterBuiltin) (progfuncs_t *prinst, char *, builtin_t); + int callargc; //number of args of built-in call + void (PDECL *RegisterBuiltin) (pubprogfuncs_t *prinst, char *, builtin_t); char *stringtable; //qc strings are all relative. add to a qc string. this is required for support of frikqcc progs that strip string immediates. + int stringtablesize; int fieldadjust; //FrikQCC style arrays can cause problems due to field remapping. This causes us to leave gaps but offsets identical. - struct qcthread_s *(*Fork) (progfuncs_t *prinst); //returns a pointer to a thread which can be resumed via RunThread. - void (*RunThread) (progfuncs_t *prinst, struct qcthread_s *thread); - void (*AbortStack) (progfuncs_t *prinst); //annigilates the current stack, positioning on a return statement. It is expected that this is only used via a builtin! + struct qcthread_s *(PDECL *Fork) (pubprogfuncs_t *prinst); //returns a pointer to a thread which can be resumed via RunThread. + void (PDECL *RunThread) (pubprogfuncs_t *prinst, struct qcthread_s *thread); + void (PDECL *AbortStack) (pubprogfuncs_t *prinst); //annigilates the current stack, positioning on a return statement. It is expected that this is only used via a builtin! int lastcalledbuiltinnumber; //useful with non-implemented opcodes. - int (*RegisterFieldVar) (progfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs); + int (PDECL *RegisterFieldVar) (pubprogfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs); char *tempstringbase; //for engine's use. Store your base tempstring pointer here. int tempstringnum; //for engine's use. - string_t (*TempString) (progfuncs_t *prinst, const char *str); + string_t (PDECL *TempString) (pubprogfuncs_t *prinst, const char *str); - string_t (*StringToProgs) (progfuncs_t *prinst, char *str); - char *(ASMCALL *StringToNative) (progfuncs_t *prinst, string_t str); - int stringtablesize; + string_t (PDECL *StringToProgs) (pubprogfuncs_t *prinst, char *str); + char *(ASMCALL *StringToNative) (pubprogfuncs_t *prinst, string_t str); - int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset + int (PDECL *QueryField) (pubprogfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset - void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e); - void (*FindPrefixGlobals) (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ); + void (PDECL *EntClear) (pubprogfuncs_t *progfuncs, struct edict_s *e); + void (PDECL *FindPrefixGlobals) (pubprogfuncs_t *progfuncs, char *prefix, void (PDECL *found) (pubprogfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) ); - void *(*AddressableAlloc) (progfuncs_t *progfuncs, unsigned int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/ + void *(PDECL *AddressableAlloc) (pubprogfuncs_t *progfuncs, unsigned int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/ - string_t (*AllocTempString) (progfuncs_t *prinst, char **str, unsigned int len); - void (*AddressableFree) (progfuncs_t *progfuncs, void *mem); /*frees a block of addressable memory*/ - pbool (*SetWatchPoint) (progfuncs_t *prinst, char *key); + string_t (PDECL *AllocTempString) (pubprogfuncs_t *prinst, char **str, unsigned int len); + void (PDECL *AddressableFree) (pubprogfuncs_t *progfuncs, void *mem); /*frees a block of addressable memory*/ + pbool (PDECL *SetWatchPoint) (pubprogfuncs_t *prinst, char *key); + + void (PDECL *AddSharedVar) (pubprogfuncs_t *progfuncs, int start, int size); + void (PDECL *AddSharedFieldVar) (pubprogfuncs_t *progfuncs, int num, char *relstringtable); + char *(PDECL *RemoveProgsString) (pubprogfuncs_t *progfuncs, string_t str); + int (PDECL *GetFuncArgCount) (pubprogfuncs_t *progfuncs, func_t func); + void (PDECL *GenerateStatementString) (pubprogfuncs_t *progfuncs, int statementnum, char *out, int outlen); + fdef_t *(PDECL *FieldInfo) (pubprogfuncs_t *progfuncs, unsigned int *count); + char *(PDECL *UglyValueString) (pubprogfuncs_t *progfuncs, etype_t type, union eval_s *val); + pbool (PDECL *ParseEval) (pubprogfuncs_t *progfuncs, union eval_s *eval, int type, char *s); }; typedef struct progexterns_s { int progsversion; //PROGSTRUCT_VERSION - unsigned char *(*ReadFile) (const char *fname, void *buffer, int len); - int (*FileSize) (const char *fname); //-1 if file does not exist - pbool (*WriteFile) (const char *name, void *data, int len); - int (VARGS *printf) (const char *, ...) LIKEPRINTF(1); + unsigned char *(PDECL *ReadFile) (const char *fname, void *buffer, int len); + int (PDECL *FileSize) (const char *fname); //-1 if file does not exist + pbool (PDECL *WriteFile) (const char *name, void *data, int len); + int (VARGS *Printf) (const char *, ...) LIKEPRINTF(1); void (VARGS *Sys_Error) (const char *, ...) LIKEPRINTF(1); void (VARGS *Abort) (char *, ...) LIKEPRINTF(1); int edictsize; //size of edict_t - void (*entspawn) (struct edict_s *ent, int loading); //ent has been spawned, but may not have all the extra variables (that may need to be set) set - pbool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed - void (ASMCALL *stateop) (progfuncs_t *prinst, float var, func_t func); //what to do on qc's state opcode. - void (ASMCALL *cstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. - void (ASMCALL *cwstateop) (progfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. - void (ASMCALL *thinktimeop) (progfuncs_t *prinst, struct edict_s *ent, float varb); //a hexen2 opcode. + void (PDECL *entspawn) (struct edict_s *ent, int loading); //ent has been spawned, but may not have all the extra variables (that may need to be set) set + pbool (PDECL *entcanfree) (struct edict_s *ent); //return true to stop ent from being freed + void (ASMCALL *stateop) (pubprogfuncs_t *prinst, float var, func_t func); //what to do on qc's state opcode. + void (ASMCALL *cstateop) (pubprogfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. + void (ASMCALL *cwstateop) (pubprogfuncs_t *prinst, float vara, float varb, func_t currentfunc); //a hexen2 opcode. + void (ASMCALL *thinktimeop) (pubprogfuncs_t *prinst, struct edict_s *ent, float varb); //a hexen2 opcode. //used when loading a game - builtin_t *(*builtinsfor) (int num, int headercrc); //must return a pointer to the builtins that were used before the state was saved. - void (*loadcompleate) (int edictsize); //notification to reset any pointers. - pbool (*badfield)(progfuncs_t *prinst, struct edict_s *ent, const char *keyname, const char *value); //called for any fields that are not registered + builtin_t *(PDECL *builtinsfor) (int num, int headercrc); //must return a pointer to the builtins that were used before the state was saved. + void (PDECL *loadcompleate) (int edictsize); //notification to reset any pointers. + pbool (PDECL *badfield)(pubprogfuncs_t *prinst, struct edict_s *ent, const char *keyname, const char *value); //called for any fields that are not registered void *(VARGS *memalloc) (int size); //small string allocation malloced and freed randomly by the executor. (use malloc if you want) void (VARGS *memfree) (void * mem); @@ -193,29 +207,17 @@ typedef struct progexterns_s { struct edict_s **sv_edicts; //pointer to the engine's reference to world. unsigned int *sv_num_edicts; //pointer to the engine's edict count. - int (*useeditor) (progfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); //called on syntax errors or step-by-step debugging. - void (*addressablerelocated) (progfuncs_t *progfuncs, char *oldb, char *newb, int oldlen); //called when the progs memory was resized. you must fix up all pointers to globals, strings, fields, addressable blocks. + int (PDECL *useeditor) (pubprogfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); //called on syntax errors or step-by-step debugging. + void (PDECL *addressablerelocated) (pubprogfuncs_t *progfuncs, char *oldb, char *newb, int oldlen); //called when the progs memory was resized. you must fix up all pointers to globals, strings, fields, addressable blocks. void *user; /*contains the owner's world reference in FTE*/ } progparms_t, progexterns_t; -//FIXMEs -void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size); -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *relstringtable); -void ED_Print(progfuncs_t *progfuncs, struct edict_s *ed); -char *PR_RemoveProgsString(progfuncs_t *progfuncs, string_t str); -int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func); - #if defined(QCLIBDLL_EXPORTS) __declspec(dllexport) #endif -progfuncs_t * InitProgs(progparms_t *ext); -#if defined(QCLIBDLL_EXPORTS) -__declspec(dllexport) -#endif -void CloseProgs(progfuncs_t *inst); +pubprogfuncs_t * PDECL InitProgs(progparms_t *ext); -#ifndef COMPILER typedef union eval_s { string_t string; @@ -226,7 +228,6 @@ typedef union eval_s int edict; float prog; //so it can easily be changed } eval_t; -#endif #define PR_CURRENT -1 #define PR_ANY -2 //not always valid. Use for finding funcs @@ -239,7 +240,6 @@ typedef union eval_s #define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->LoadProgs) (pf, s, headercrc, builtins, numb) #define PR_InitEnts(pf, maxents) (*pf->InitEnts) (pf, maxents) #define PR_ExecuteProgram(pf, fnum) (*pf->ExecuteProgram) (pf, fnum) -#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num) #define PR_globals(pf, num) (*pf->globals) (pf, num) #define PR_entvars(pf, ent) (*pf->entvars) (pf, ent) diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index e60d358e..72ab9e65 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -52,10 +52,10 @@ extern int MAX_FIELDS; extern int MAX_STATEMENTS; extern int MAX_FUNCTIONS; -#define MAX_SOUNDS 1024 //convert to int? -#define MAX_TEXTURES 1024 //convert to int? -#define MAX_MODELS 1024 //convert to int? -#define MAX_FILES 1024 //convert to int? +#define QCC_MAX_SOUNDS 1024 //convert to int? +#define QCC_MAX_TEXTURES 1024 //convert to int? +#define QCC_MAX_MODELS 1024 //convert to int? +#define QCC_MAX_FILES 1024 //convert to int? #define MAX_DATA_PATH 64 extern int MAX_CONSTANTS; @@ -63,7 +63,7 @@ extern int MAX_CONSTANTS; #define MAXCONSTANTPARAMLENGTH 32 #define MAXCONSTANTPARAMS 32 -typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_DARKPLACES, QCF_FTE, QCF_FTEDEBUG, QCF_KK7, QCF_QTEST} qcc_targetformat_t; +typedef enum {QCF_STANDARD, QCF_HEXEN2, QCF_DARKPLACES, QCF_FTE, QCF_FTEDEBUG, QCF_FTEH2, QCF_KK7, QCF_QTEST} qcc_targetformat_t; extern qcc_targetformat_t qcc_targetformat; @@ -310,6 +310,7 @@ typedef struct QCC_type_s char *name; } QCC_type_t; int typecmp(QCC_type_t *a, QCC_type_t *b); +int typecmp_lax(QCC_type_t *a, QCC_type_t *b); typedef struct temp_s { gofs_t ofs; @@ -562,13 +563,14 @@ void QCC_PR_Expect (char *string); pbool QCC_PR_CheckKeyword(int keywordenabled, char *string); #endif void VARGS QCC_PR_ParseError (int errortype, char *error, ...); -void VARGS QCC_PR_ParseWarning (int warningtype, char *error, ...); +pbool VARGS QCC_PR_ParseWarning (int warningtype, char *error, ...); pbool VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...); void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...); void QCC_PR_ParsePrintDef (int warningtype, QCC_def_t *def); void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...); int QCC_WarningForName(char *name); +char *QCC_NameForWarning(int idx); //QccMain.c must be changed if this is changed. enum { @@ -627,6 +629,7 @@ enum { WARN_CONSTANTCOMPARISON, WARN_UNSAFEFUNCTIONRETURNTYPE, WARN_MISSINGOPTIONAL, + WARN_SYSTEMCRC, ERR_PARSEERRORS, //caused by qcc_pr_parseerror being called. @@ -753,7 +756,10 @@ typedef struct { } compiler_flag_t; extern compiler_flag_t compiler_flag[]; -extern pbool qccwarningdisabled[WARN_MAX]; +#define WA_IGNORE 0 +#define WA_WARN 1 +#define WA_ERROR 2 +extern unsigned char qccwarningaction[WARN_MAX]; extern jmp_buf pr_parse_abort; // longjump with this on parse error extern int pr_source_line; @@ -789,7 +795,6 @@ extern QCC_def_t *extra_parms[MAX_EXTRA_PARMS]; #else extern char pr_parm_names[MAX_PARMS][MAX_NAME]; #endif -extern pbool pr_trace; #define G_FLOAT(o) (qcc_pr_globals[o]) #define G_INT(o) (*(int *)&qcc_pr_globals[o]) @@ -799,7 +804,7 @@ extern pbool pr_trace; char *QCC_PR_ValueString (etype_t type, void *val); -void QCC_PR_ClearGrabMacros (void); +void QCC_PR_ClearGrabMacros (pbool newfile); pbool QCC_PR_CompileFile (char *string, char *filename); void QCC_PR_ResetErrorScope(void); @@ -929,6 +934,7 @@ void editbadfile(char *fname, int line); char *TypeName(QCC_type_t *type); void QCC_PR_IncludeChunk (char *data, pbool duplicate, char *filename); void QCC_PR_IncludeChunkEx(char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst); +void QCC_PR_CloseProcessor(void); pbool QCC_PR_UnInclude(void); extern void *(*pHash_Get)(hashtable_t *table, const char *name); extern void *(*pHash_GetNext)(hashtable_t *table, const char *name, void *old); diff --git a/engine/qclib/qcc_cmdlib.c b/engine/qclib/qcc_cmdlib.c index b3c4b6b8..807e01eb 100644 --- a/engine/qclib/qcc_cmdlib.c +++ b/engine/qclib/qcc_cmdlib.c @@ -229,14 +229,12 @@ char *QCC_COM_Parse (char *data) // skip whitespace skipwhite: - while ( (c = *data) <= ' ') - { - if (c == 0) - { - qcc_eof = true; - return NULL; // end of file; - } + while ((c = *data) && qcc_iswhite(c)) data++; + if (!c) + { + qcc_eof = true; + return NULL; } // skip // comments @@ -283,7 +281,10 @@ skipwhite: qcc_token[len] = 0; return data; } - qcc_token[len] = c; + if (len >= sizeof(qcc_token)-1) + ; + else + qcc_token[len] = c; len++; } while (1); } @@ -300,13 +301,16 @@ skipwhite: // parse a regular word do { - qcc_token[len] = c; + if (len >= sizeof(qcc_token)-1) + ; + else + qcc_token[len] = c; data++; len++; c = *data; if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':' || c=='\"' || c==',') break; - } while (c>32); + } while (!qcc_iswhite(c)); qcc_token[len] = 0; return data; @@ -326,14 +330,12 @@ char *QCC_COM_Parse2 (char *data) // skip whitespace skipwhite: - while ( (c = *data) <= ' ') - { - if (c == 0) - { - qcc_eof = true; - return NULL; // end of file; - } + while ((c = *data) && qcc_iswhite(c)) data++; + if (!c) + { + qcc_eof = true; + return NULL; } // skip // comments @@ -362,7 +364,10 @@ skipwhite: data++; } else if (c=='\"'||c=='\0') - qcc_token[len] = c; + if (len >= sizeof(qcc_token)-1) + ; + else + qcc_token[len] = c; len++; } while (1); } @@ -391,7 +396,10 @@ skipwhite: { for(;;) { //parse regular number - qcc_token[len] = c; + if (len >= sizeof(qcc_token)-1) + ; + else + qcc_token[len] = c; data++; len++; c = *data; @@ -408,7 +416,10 @@ skipwhite: { do { - qcc_token[len] = c; + if (len >= sizeof(qcc_token)-1) + ; + else + qcc_token[len] = c; data++; len++; c = *data; @@ -807,7 +818,7 @@ void ResizeBuf(int hand, int newsize) // if (wasmal) free(qccfile[hand].buff); // else -// memfree(qccfile[hand].buff); +// externs->memfree(qccfile[hand].buff); qccfile[hand].buff = nb; qccfile[hand].buffsize = newsize; } @@ -840,11 +851,108 @@ void SafeClose(int hand) // if (qccfile[hand].buffismalloc) free(qccfile[hand].buff); // else -// memfree(qccfile[hand].buff); +// externs->memfree(qccfile[hand].buff); qccfile[hand].buff = NULL; } qcc_cachedsourcefile_t *qcc_sourcefile; + +enum +{ + UTF16LE, + UTF16BE, + UTF32LE, + UTF32BE, +}; +//read utf-16 chars and output the 'native' utf-8. +//we don't expect essays written in code, so we don't need much actual support for utf-8. +static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, int *outlen) +{ + char *utf8, *start; + unsigned int inc; + unsigned int chars, i; + int w, maxperchar; + switch(type) + { + case UTF16LE: + w = 2; + maxperchar = 3; + break; + case UTF16BE: + w = 2; + maxperchar = 3; + break; + case UTF32LE: + w = 4; + maxperchar = 4; //we adhere to RFC3629 and clamp to U+10FFFF, which is only 4 bytes. + break; + case UTF32BE: + w = 4; + maxperchar = 4; + break; + } + chars = inbytes / w; + utf8 = start = qccHunkAlloc(chars * maxperchar + 2); + for (i = 0; i < chars; i++) + { + switch(type) + { + case UTF16LE: + inc = *inputf++; + inc|= (*inputf++)<<8; + break; + case UTF16BE: + inc = (*inputf++)<<8; + inc|= *inputf++; + break; + case UTF32LE: + inc = *inputf++; + inc|= (*inputf++)<<8; + inc|= (*inputf++)<<16; + inc|= (*inputf++)<<24; + break; + case UTF32BE: + inc = (*inputf++)<<24; + inc|= (*inputf++)<<16; + inc|= (*inputf++)<<8; + inc|= *inputf++; + break; + } + if (inc > 0x10FFFF) + inc = 0xFFFD; + + if (inc <= 127) + *utf8++ = inc; + else if (inc <= 0x7ff) + { + *utf8++ = ((inc>>6) & 0x1f) | 0xc0; + *utf8++ = ((inc>>0) & 0x3f) | 0x80; + } + else if (inc <= 0xffff) + { + *utf8++ = ((inc>>12) & 0xf) | 0xe0; + *utf8++ = ((inc>>6) & 0x3f) | 0x80; + *utf8++ = ((inc>>0) & 0x3f) | 0x80; + } + else if (inc <= 0x1fffff) + { + *utf8++ = ((inc>>18) & 0x07) | 0xf0; + *utf8++ = ((inc>>12) & 0x3f) | 0x80; + *utf8++ = ((inc>> 6) & 0x3f) | 0x80; + *utf8++ = ((inc>> 0) & 0x3f) | 0x80; + } + else + { + inc = 0xFFFD; + *utf8++ = ((inc>>12) & 0xf) | 0xe0; + *utf8++ = ((inc>>6) & 0x3f) | 0x80; + *utf8++ = ((inc>>0) & 0x3f) | 0x80; + } + } + *outlen = utf8 - start; + return start; +} + long QCC_LoadFile (char *filename, void **bufferptr) { char *mem; @@ -853,23 +961,44 @@ long QCC_LoadFile (char *filename, void **bufferptr) if (len < 0) { QCC_Error(ERR_COULDNTOPENFILE, "Couldn't open file %s", filename); -// if (!Abort) +// if (!externs->Abort) return -1; -// Abort("failed to find file %s", filename); +// externs->Abort("failed to find file %s", filename); } mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+2); ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile; qcc_sourcefile = (qcc_cachedsourcefile_t*)mem; - qcc_sourcefile->size = len; mem += sizeof(qcc_cachedsourcefile_t); + + externs->ReadFile(filename, mem, len+2); + + if (len >= 4 && mem[0] == '\xff' && mem[1] == '\xfe' && mem[2] == '\x00' && mem[3] == '\x00') + mem = decodeUTF(UTF32LE, (unsigned char*)mem+4, len-4, &len); + else if (len >= 4 && mem[0] == '\x00' && mem[1] == '\x00' && mem[2] == '\xfe' && mem[3] == '\xff') + mem = decodeUTF(UTF32BE, (unsigned char*)mem+4, len-4, &len); + else if (len >= 2 && mem[0] == '\xff' && mem[1] == '\xfe') + mem = decodeUTF(UTF16LE, (unsigned char*)mem+2, len-2, &len); + else if (len >= 2 && mem[0] == '\xfe' && mem[1] == '\xff') + mem = decodeUTF(UTF16BE, (unsigned char*)mem+2, len-2, &len); + //utf-8 BOM, for compat with broken text editors (like windows notepad). + else if (len >= 3 && mem[0] == '\xef' && mem[1] == '\xbb' && mem[2] == '\xbf') + { + mem += 3; + len -= 3; + } + //actual utf-8 handling is somewhat up to the engine. the qcc can only ensure that utf8 works in symbol names etc. + //its only in strings where it actually makes a difference, and the interpretation of those is basically entirely up to the engine. + //that said, we could insert a utf-8 BOM into ones with utf-8 chars, but that would mess up a lot of builtins+mods, so we won't. + + mem[len] = '\n'; + mem[len+1] = '\0'; + strcpy(qcc_sourcefile->filename, filename); + qcc_sourcefile->size = len; qcc_sourcefile->file = mem; qcc_sourcefile->type = FT_CODE; - externs->ReadFile(filename, mem, len+2); - mem[len] = '\n'; - mem[len+1] = '\0'; *bufferptr=mem; return len; @@ -880,7 +1009,7 @@ void QCC_AddFile (char *filename) int len; len = externs->FileSize(filename); if (len < 0) - Abort("failed to find file %s", filename); + externs->Abort("failed to find file %s", filename); mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+1); ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile; @@ -899,14 +1028,14 @@ void *FS_ReadToMem(char *filename, void *mem, int *len) if (!mem) { *len = externs->FileSize(filename); - mem = memalloc(*len); + mem = externs->memalloc(*len); } return externs->ReadFile(filename, mem, *len); } void FS_CloseFromMem(void *mem) { - memfree(mem); + externs->memfree(mem); } diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 09be89e2..020f409e 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -136,6 +136,8 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a QCC_type_t *QCC_PR_FindType (QCC_type_t *type); QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto); QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto); +QCC_def_t *QCC_PR_Term (int exprflags); +QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], int argcount); void QCC_PR_ParseState (void); pbool simplestore; @@ -443,7 +445,7 @@ QCC_opcode_t pr_opcodes[] = {7, "+", "ADD_SF", 4, ASSOC_LEFT, &type_string, &type_float, &type_string}, {7, "-", "SUB_S", 4, ASSOC_LEFT, &type_string, &type_string, &type_float}, {7, "", "STOREP_C", 1, ASSOC_RIGHT, &type_string, &type_float, &type_float}, - {7, "", "LOADP_C", 1, ASSOC_LEFT, &type_string, &type_void, &type_float}, + {7, "", "LOADP_C", 1, ASSOC_LEFT, &type_string, &type_float, &type_float}, //------------------------------------- @@ -545,7 +547,9 @@ QCC_opcode_t pr_opcodes[] = {7, "=", "LOADA_STRUCT", 6, ASSOC_LEFT, &type_float, &type_integer, &type_float}, - {7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_pointer}, + {7, "=", "STOREP_P", 6, ASSOC_RIGHT, &type_pointer, &type_pointer, &type_pointer}, + {7, "~", "BINARYNOT_F", -1, ASSOC_LEFT, &type_float, &type_void, &type_float}, + {7, "~", "BINARYNOT_I", -1, ASSOC_LEFT, &type_integer, &type_void, &type_integer}, {0, NULL} }; @@ -856,6 +860,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) if (num <= OP_CALL8H) //CALLXH are fixed up. This is to provide more dynamic switching...?? return true; return false; + case QCF_FTEH2: case QCF_FTE: case QCF_FTEDEBUG: //no emulated opcodes @@ -1092,6 +1097,7 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) #define EXPR_WARN_ABOVE_1 2 #define EXPR_DISALLOW_COMMA 4 +#define EXPR_DISALLOW_ARRAYASSIGN 8 QCC_def_t *QCC_PR_Expression (int priority, int exprflags); int QCC_AStatementJumpsTo(int targ, int first, int last); pbool QCC_StatementIsAJump(int stnum, int notifdest); @@ -1173,11 +1179,11 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal) if (o == 0) //type already matches return var; if (flag_typeexplicit) - QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name); + QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], basictypenames[var->type->type]); if (o < 0) { if (fatal) - QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name); + QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], basictypenames[var->type->type]); else return var; } @@ -1757,7 +1763,13 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_ return QCC_MakeIntConst(G_INT(var_a->ofs) * G_INT(var_b->ofs)); case OP_DIV_I: optres_constantarithmatic++; - return QCC_MakeIntConst(G_INT(var_a->ofs) / G_INT(var_b->ofs)); + if (G_INT(var_b->ofs) == 0) + { + QCC_PR_ParseWarning(WARN_CONSTANTCOMPARISON, "Division by constant 0"); + return QCC_MakeIntConst(0); + } + else + return QCC_MakeIntConst(G_INT(var_a->ofs) / G_INT(var_b->ofs)); case OP_ADD_I: optres_constantarithmatic++; return QCC_MakeIntConst(G_INT(var_a->ofs) + G_INT(var_b->ofs)); @@ -2128,8 +2140,87 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_ case OP_LOADA_STRUCT: /*emit this anyway. if it reaches runtime then you messed up. this is valid only if you do &foo[0]*/ +// QCC_PR_ParseWarning(0, "OP_LOADA_STRUCT: cannot emulate"); break; + case OP_ADD_I: + { + QCC_def_t *arg[2] = {var_a, var_b}; + numstatements--; + def_parms[0].type = type_integer; + def_parms[1].type = type_integer; + var_c = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "AddInt", NULL, true, 0, false), arg, 2); + var_c->type = type_integer; + return var_c; + } + break; + case OP_SUB_I: + { + QCC_def_t *arg[2] = {var_a, var_b}; + numstatements--; + def_parms[0].type = type_integer; + def_parms[1].type = type_integer; + var_c = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "SubInt", NULL, true, 0, false), arg, 2); + var_c->type = type_integer; + return var_c; + } + break; + case OP_MUL_I: + { + QCC_def_t *arg[2] = {var_a, var_b}; + numstatements--; + def_parms[0].type = type_integer; + def_parms[1].type = type_integer; + var_c = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "MulInt", NULL, true, 0, false), arg, 2); + var_c->type = type_integer; + return var_c; + } + break; + case OP_DIV_I: + { + QCC_def_t *arg[2] = {var_a, var_b}; + numstatements--; + def_parms[0].type = type_integer; + def_parms[1].type = type_integer; + var_c = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "DivInt", NULL, true, 0, false), arg, 2); + var_c->type = type_integer; + return var_c; + } + break; + + case OP_CONV_ITOF: + case OP_STORE_IF: + op = pr_opcodes+OP_STORE_F; + if (var_a->constant) + var_a = QCC_MakeFloatConst(G_INT(var_a->ofs)); + else + { + numstatements--; + def_parms[0].type = type_integer; + var_a = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "itof", NULL, true, 0, false), &var_a, 1); + var_a->type = type_float; + statement = &statements[numstatements]; + numstatements++; + } + break; + case OP_CONV_FTOI: + case OP_STORE_FI: + op = pr_opcodes+OP_STORE_I; + if (var_a->constant) + var_a = QCC_MakeFloatConst(G_INT(var_a->ofs)); + else + { + numstatements--; + def_parms[0].type = type_float; + var_a = QCC_PR_GenerateFunctionCall(QCC_PR_GetDef(type_function, "ftoi", NULL, true, 0, false), &var_a, 1); + var_a->type = type_integer; + statement = &statements[numstatements]; + numstatements++; + } + break; + case OP_STORE_I: + op = pr_opcodes+OP_STORE_F; + break; case OP_IF_S: var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false); @@ -2225,6 +2316,24 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_ var_a = var_c; var_c = var_a; break; + case OP_SUBSTORE_I: + op = &pr_opcodes[OP_SUB_I]; + var_c = var_b; + var_b = var_a; + var_a = var_c; + var_c = var_a; + break; + + case OP_BINARYNOT_I: + op = &pr_opcodes[OP_SUB_I]; + var_b = var_a; + var_a = QCC_MakeIntConst(~0); + break; + case OP_BINARYNOT_F: + op = &pr_opcodes[OP_SUB_F]; + var_b = var_a; + var_a = QCC_MakeFloatConst(0xffffff); //due to fpu precision, we only use 24 bits. + break; case OP_DIVSTORE_F: op = &pr_opcodes[OP_DIV_F]; @@ -2247,6 +2356,13 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_ var_a = var_c; var_c = var_a; break; + case OP_DIVSTORE_I: + op = &pr_opcodes[OP_DIV_I]; + var_c = var_b; + var_b = var_a; + var_a = var_c; + var_c = var_a; + break; case OP_MULSTORE_F: op = &pr_opcodes[OP_MUL_F]; @@ -2772,7 +2888,7 @@ void QCC_PrecacheSound (QCC_def_t *e, int ch) for (i=0 ; itype->size * 4 * e->arraysize); + if (!e->arraysize) + sz = 1; + else + sz = e->arraysize; + sz *= e->type->size; + sz *= 4; + QCC_FreeTemp(e); + return QCC_MakeIntConst(sz); } } if (!strcmp(func->name, "_")) @@ -3776,9 +3900,10 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL); else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant? e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL); - else if ((p->type == ev_function && p->type == ev_string) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs]) - { //you're allowed to use int 0 to pass a null function pointer + else if ((p->type == ev_function || p->type == ev_string || p->type == ev_pointer) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs]) + { //you're allowed to use int 0 to pass a null function/string/pointer //this is basically because __NULL__ is defined as 0i (int 0) + //note that we don't allow passing 0.0f for null. } else if (p->type != ev_variant && e->type->type != ev_variant) //can cast to variant whatever happens { @@ -4448,7 +4573,7 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign) } else if (d->type->type == ev_vector && d->arraysize == 0) { - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); d->type = type_float; } else if (QCC_OPCodeValid(&pr_opcodes[OP_LOADA_F])) @@ -4458,33 +4583,33 @@ QCC_def_t *QCC_PR_ParseArrayPointer (QCC_def_t *d, pbool allowarrayassign) switch(t->type) { case ev_pointer: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_float: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_F], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_integer: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_I], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_string: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_S], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_vector: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_V], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_entity: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_ENT], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_field: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FLD], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_function: - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; case ev_struct: case ev_union: //FIXME... - d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_STRUCT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL); + d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_STRUCT], d, QCC_SupplyConversion(idx, ev_integer, true), (QCC_dstatement_t **)0xffffffff); break; default: QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler"); @@ -4650,21 +4775,84 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign) if (pr_token_type == tt_immediate) return QCC_PR_ParseImmediate (); - if (QCC_PR_CheckToken("[")) //reacc support - { //looks like a funky vector. :) - vec3_t v; - pr_immediate_type = type_vector; - v[0] = pr_immediate._float; - QCC_PR_Lex(); - v[1] = pr_immediate._float; - QCC_PR_Lex(); - v[2] = pr_immediate._float; - pr_immediate.vector[0] = v[0]; - pr_immediate.vector[1] = v[1]; - pr_immediate.vector[2] = v[2]; - pr_immediate_type = type_vector; - d = QCC_PR_ParseImmediate(); + if (QCC_PR_CheckToken("[")) + { + //originally used for reacc - taking the form of [5 84 2] + //we redefine it to include statements - [a+b, c, 3+(d*2)] + //and to not need the 2nd/3rd parts if you're lazy - [5] or [5,6] - FIXME: should we accept 1-d vector? or is that too risky with arrays and weird error messages? + //note the addition of commas. + //if we're parsing reacc code, we will still accept [(a+b) c (3+(d*2))], as QCC_PR_Term contains the () handling. We do also allow optional commas. + QCC_def_t *x,*y,*z; + if (flag_acc) + { + x = QCC_PR_Term(EXPR_DISALLOW_COMMA); + QCC_PR_CheckToken(","); + y = QCC_PR_Term(EXPR_DISALLOW_COMMA); + QCC_PR_CheckToken(","); + z = QCC_PR_Term(EXPR_DISALLOW_COMMA); + } + else + { + x = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); + + if (QCC_PR_CheckToken(",")) + y = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); + else + y = QCC_MakeFloatConst(0); + + if (QCC_PR_CheckToken(",")) + z = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); + else + z = QCC_MakeFloatConst(0); + } + QCC_PR_Expect("]"); + + if ((x->type->type != ev_float && x->type->type != ev_integer) || + (y->type->type != ev_float && y->type->type != ev_integer) || + (z->type->type != ev_float && z->type->type != ev_integer)) + { + QCC_PR_ParseError(ERR_TYPEMISMATCH, "Argument not a single numeric value in vector constructor"); + return QCC_MakeVectorConst(0, 0, 0); + } + + //return a constant if we can. + if (x->constant && y->constant && z->constant) + { + d = QCC_MakeVectorConst( + (x->type->type==ev_float)?G_FLOAT(x->ofs):G_INT(x->ofs), + (y->type->type==ev_float)?G_FLOAT(y->ofs):G_INT(y->ofs), + (z->type->type==ev_float)?G_FLOAT(z->ofs):G_INT(z->ofs)); + QCC_FreeTemp(x); + QCC_FreeTemp(y); + QCC_FreeTemp(z); + return d; + } + + //pack the variables into a vector + d = QCC_GetTemp(type_vector); + d->type = type_float; + if (x->type->type == ev_float) + QCC_PR_Statement(pr_opcodes + OP_STORE_F, x, d, (QCC_dstatement_t **)0xffffffff); + else + QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, x, d, (QCC_dstatement_t **)0xffffffff); + d->ofs++; + if (y->type->type == ev_float) + QCC_PR_Statement(pr_opcodes + OP_STORE_F, y, d, (QCC_dstatement_t **)0xffffffff); + else + QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, y, d, (QCC_dstatement_t **)0xffffffff); + d->ofs++; + if (z->type->type == ev_float) + QCC_PR_Statement(pr_opcodes + OP_STORE_F, z, d, (QCC_dstatement_t **)0xffffffff); + else + QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, z, d, (QCC_dstatement_t **)0xffffffff); + d->ofs++; + d->ofs -= 3; + d->type = type_vector; + + QCC_FreeTemp(x); + QCC_FreeTemp(y); + QCC_FreeTemp(z); return d; } name = QCC_PR_ParseName (); @@ -4809,7 +4997,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign) PR_Term ============ */ -QCC_def_t *QCC_PR_Term (void) +QCC_def_t *QCC_PR_Term (int exprflags) { QCC_def_t *e, *e2; etype_t t; @@ -4818,7 +5006,7 @@ QCC_def_t *QCC_PR_Term (void) if (QCC_PR_CheckToken("++")) { qcc_usefulstatement=true; - e = QCC_PR_Term (); + e = QCC_PR_Term (0); if (e->constant) QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", e->name); if (e->temp) @@ -4840,7 +5028,7 @@ QCC_def_t *QCC_PR_Term (void) else if (QCC_PR_CheckToken("--")) { qcc_usefulstatement=true; - e = QCC_PR_Term (); + e = QCC_PR_Term (0); if (e->constant) QCC_PR_ParseWarning(WARN_ASSIGNMENTTOCONSTANT, "Assignment to constant %s", e->name); if (e->temp) @@ -4885,7 +5073,21 @@ QCC_def_t *QCC_PR_Term (void) } return e2; } - + else if (QCC_PR_CheckToken ("~")) + { + e = QCC_PR_Expression (NOT_PRIORITY, EXPR_DISALLOW_COMMA|EXPR_WARN_ABOVE_1); + t = e->type->type; + if (t == ev_float) + e2 = QCC_PR_Statement (&pr_opcodes[OP_BINARYNOT_F], e, 0, NULL); + else if (t == ev_integer) + e2 = QCC_PR_Statement (&pr_opcodes[OP_BINARYNOT_I], e, 0, NULL); //functions are integer values too. + else + { + e2 = NULL; // shut up compiler warning; + QCC_PR_ParseError (ERR_BADNOTTYPE, "type mismatch for binary not"); + } + return e2; + } else if (QCC_PR_CheckToken ("&")) { int st = numstatements; @@ -5159,7 +5361,7 @@ QCC_def_t *QCC_PR_Term (void) return e; } } - return QCC_PR_ParseValue (pr_classtype, true); + return QCC_PR_ParseValue (pr_classtype, !(exprflags&EXPR_DISALLOW_ARRAYASSIGN)); } @@ -5217,7 +5419,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) etype_t type_a, type_b, type_c; if (priority == 0) - return QCC_PR_Term (); + return QCC_PR_Term (exprflags); e = QCC_PR_Expression (priority-1, exprflags); @@ -5236,7 +5438,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_IFNOT_I], e, NULL, &fromj)); e = QCC_PR_Expression(TOP_PRIORITY, 0); e2 = QCC_GetTemp(e->type); - QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, NULL)); + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, (QCC_dstatement_t **)0xffffffff)); //e2 can be stomped upon until its reused anyway QCC_UnFreeTemp(e2); @@ -5247,7 +5449,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) if (typecmp(e->type, e2->type) != 0) QCC_PR_ParseError(0, "Ternary operator with mismatching types\n"); - QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, NULL)); + QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[(e2->type->size>=3)?OP_STORE_V:OP_STORE_F], e, e2, (QCC_dstatement_t **)0xffffffff)); QCC_UnFreeTemp(e2); elsej->a = &statements[numstatements] - elsej; @@ -5343,7 +5545,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags) QCC_PR_Statement3(&pr_opcodes[OP_IF_I], e, NULL, NULL, false); } - e2 = QCC_PR_Expression (priority-1, exprflags); + e2 = QCC_PR_Expression (priority-1, exprflags | EXPR_DISALLOW_ARRAYASSIGN); } // type check @@ -8274,7 +8476,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool continue; // in a different function } - if (def->isstatic && def->s_file != s_file) + if (def->isstatic && strcmp(strings+def->s_file, strings+s_file)) { //warn? or would that be pointless? foundstatic = def; def = Hash_GetNext(&globalstable, name, def); @@ -8407,8 +8609,12 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool if (scope) { - if (QCC_PR_GetDef(type, name, NULL, false, arraysize, false)) + def = QCC_PR_GetDef(type, name, NULL, false, arraysize, false); + if (def) + { QCC_PR_ParseWarning(WARN_SAMENAMEASGLOBAL, "Local \"%s\" defined with name of a global", name); + QCC_PR_ParsePrintDef(WARN_SAMENAMEASGLOBAL, def); + } } ofs = numpr_globals; @@ -8773,18 +8979,19 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type def->references++; for (i = 0; (unsigned)i < type->size; ) { - rhs.type = lhs.type = type_float; lhs.ofs = offset+i; tmp->references++; rhs.ofs = tmp->ofs+i; if (type->size - i >= 3) { + rhs.type = lhs.type = type_vector; QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_V], &rhs, &lhs, NULL)); i+=3; } else { + rhs.type = lhs.type = type_float; QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_F], &rhs, &lhs, NULL)); i++; } @@ -9352,22 +9559,33 @@ void QCC_PR_ParseDefs (char *classname) if ( QCC_PR_CheckToken ("[") ) { char *oldprfile = pr_file_p; + int depth; arraysize = 0; if (QCC_PR_CheckToken("]")) { QCC_PR_Expect("="); QCC_PR_Expect("{"); - QCC_PR_Lex(); arraysize++; + depth = 1; while(1) { if(pr_token_type == tt_eof) + { + QCC_PR_ParseError (ERR_EOF, "EOF inside definition of %s", name); break; - if (QCC_PR_CheckToken(",")) + } + else if (depth == 1 && QCC_PR_CheckToken(",")) arraysize++; - if (QCC_PR_CheckToken("}")) - break; - QCC_PR_Lex(); + else if (QCC_PR_CheckToken("{") || QCC_PR_CheckToken("[")) + depth++; + else if (QCC_PR_CheckToken("}") || QCC_PR_CheckToken("]")) + { + depth--; + if (depth == 0) + break; + } + else + QCC_PR_Lex(); } pr_file_p = oldprfile; QCC_PR_Lex(); @@ -9431,7 +9649,7 @@ void QCC_PR_ParseDefs (char *classname) if (isstatic) { - if (def->s_file == s_file) + if (!strcmp(strings+def->s_file, strings+s_file)) def->isstatic = isstatic; else //if (type->type != ev_function && defaultstatic) //functions don't quite consitiute a definition QCC_PR_ParseErrorPrintDef (ERR_REDECLARATION, def, "can't redefine non-static as static"); @@ -9566,7 +9784,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) if (!pr.memory) QCC_Error (ERR_INTERNAL, "PR_CompileFile: Didn't clear"); - QCC_PR_ClearGrabMacros (); // clear the frame macros + QCC_PR_ClearGrabMacros (true); // clear the frame macros compilingfile = filename; diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index f7590755..ce53aa52 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -56,13 +56,13 @@ extern pbool expandedemptymacro; char *pr_punctuation[] = // longer symbols must be before a shorter partial match -{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "(-)", "|=", "&~=", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "^", ":", NULL}; +{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "(-)", "|=", "&~=", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "^", "~", ":", NULL}; char *pr_punctuationremap[] = //a nice bit of evilness. //(+) -> |= //-> -> . //(-) -> &~= -{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "&~=", "|=", "&~=", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "^", ":", NULL}; +{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "&~=", "|=", "&~=", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "^", "~", ":", NULL}; // simple types. function types are dynamically allocated QCC_type_t *type_void;// = {ev_void/*, &def_void*/}; @@ -103,6 +103,10 @@ void QCC_PR_LexWhitespace (void); //for compiler constants and file includes. qcc_includechunk_t *currentchunk; +void QCC_PR_CloseProcessor(void) +{ + currentchunk = NULL; +} void QCC_PR_IncludeChunkEx (char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst) { qcc_includechunk_t *chunk = qccHunkAlloc(sizeof(qcc_includechunk_t)); @@ -195,7 +199,10 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath) strcpy(end, currentfile); end = end+strlen(end); #else - strcpy(fullname, currentfile); + if (currentfile) + strcpy(fullname, currentfile); + else + *fullname = 0; end = fullname+strlen(fullname); #endif @@ -227,92 +234,173 @@ void QCC_AddFile (char *filename); void QCC_PR_LexString (void); pbool QCC_PR_SimpleGetToken (void); -int ParsePrecompilerIf(void) +#define PPI_VALUE 0 +#define PPI_NOT 1 +#define PPI_DEFINED 2 +#define PPI_COMPARISON 3 +#define PPI_LOGICAL 4 +#define PPI_TOPLEVEL 5 +int ParsePrecompilerIf(int level) { CompilerConstant_t *c; int eval = 0; pbool notted = false; - - /*skip whitespace*/ - while (*pr_file_p && *pr_file_p <= ' ' && *pr_file_p != '\n') + + //single term end-of-chain + if (level == PPI_VALUE) { - pr_file_p++; - } - if (*pr_file_p == '!') - { - pr_file_p++; - notted = true; - while (*pr_file_p && *pr_file_p <= ' ' && *pr_file_p != '\n') + /*skip whitespace*/ + while (*pr_file_p && qcc_iswhite(*pr_file_p) && *pr_file_p != '\n') { pr_file_p++; } - } - if (!QCC_PR_SimpleGetToken()) - { if (*pr_file_p == '(') - { + { //try brackets pr_file_p++; - eval = ParsePrecompilerIf(); + eval = ParsePrecompilerIf(PPI_TOPLEVEL); while (*pr_file_p == ' ' || *pr_file_p == '\t') pr_file_p++; if (*pr_file_p != ')') QCC_PR_ParseError(ERR_EXPECTED, "unclosed bracket condition\n"); pr_file_p++; } - else - QCC_PR_ParseError(ERR_EXPECTED, "expected bracket or constant\n"); - } - else if (!strcmp(pr_token, "defined")) - { - while (*pr_file_p == ' ' || *pr_file_p == '\t') - pr_file_p++; - if (*pr_file_p != '(') - QCC_PR_ParseError(ERR_EXPECTED, "no opening bracket after defined\n"); - else - { - pr_file_p++; - - QCC_PR_SimpleGetToken(); - eval = !!QCC_PR_CheckCompConstDefined(pr_token); - - while (*pr_file_p == ' ' || *pr_file_p == '\t') - pr_file_p++; - if (*pr_file_p != ')') - QCC_PR_ParseError(ERR_EXPECTED, "unclosed defined condition\n"); + else if (*pr_file_p == '!') + { //try brackets pr_file_p++; + eval = !ParsePrecompilerIf(PPI_NOT); } - } - else - { - c = QCC_PR_CheckCompConstDefined(pr_token); - if (!c) - eval = atoi(pr_token); else - eval = atoi(c->value); + { //simple token... + if (!strncmp(pr_file_p, "defined", 7)) + { + pr_file_p+=7; + while (*pr_file_p == ' ' || *pr_file_p == '\t') + pr_file_p++; + if (*pr_file_p != '(') + { + eval = false; + QCC_PR_ParseError(ERR_EXPECTED, "no opening bracket after defined\n"); + } + else + { + pr_file_p++; + + QCC_PR_SimpleGetToken(); + eval = !!QCC_PR_CheckCompConstDefined(pr_token); + + while (*pr_file_p == ' ' || *pr_file_p == '\t') + pr_file_p++; + if (*pr_file_p != ')') + QCC_PR_ParseError(ERR_EXPECTED, "unclosed defined condition\n"); + pr_file_p++; + } + } + else + { + if (!QCC_PR_SimpleGetToken()) + QCC_PR_ParseError(ERR_EXPECTED, "unexpected end-of-line\n"); + c = QCC_PR_CheckCompConstDefined(pr_token); + if (!c) + eval = atoi(pr_token); + else + eval = atoi(c->value); + } + } + return eval; } - if (notted) - eval = !eval; + eval = ParsePrecompilerIf(level-1); - QCC_PR_SimpleGetToken(); - if (!strcmp(pr_token, "||")) - eval = ParsePrecompilerIf()||eval; - else if (!strcmp(pr_token, "&&")) - eval = ParsePrecompilerIf()&&eval; - else if (!strcmp(pr_token, "<=")) - eval = eval <= ParsePrecompilerIf(); - else if (!strcmp(pr_token, ">=")) - eval = eval >= ParsePrecompilerIf(); - else if (!strcmp(pr_token, "<")) - eval = eval < ParsePrecompilerIf(); - else if (!strcmp(pr_token, ">")) - eval = eval > ParsePrecompilerIf(); - else if (!strcmp(pr_token, "!=")) - eval = eval != ParsePrecompilerIf(); + while (*pr_file_p && qcc_iswhite(*pr_file_p) && *pr_file_p != '\n') + { + pr_file_p++; + } + switch(level) + { + case PPI_LOGICAL: + if (!strncmp(pr_file_p, "||", 2)) + { + pr_file_p+=2; + eval = ParsePrecompilerIf(level)||eval; + } + else if (!strncmp(pr_file_p, "&&", 2)) + { + pr_file_p+=2; + eval = ParsePrecompilerIf(level)&&eval; + } + break; + case PPI_COMPARISON: + if (!strncmp(pr_file_p, "<=", 2)) + { + pr_file_p+=2; + eval = eval <= ParsePrecompilerIf(level); + } + else if (!strncmp(pr_file_p, ">=", 2)) + { + pr_file_p += 2; + eval = eval >= ParsePrecompilerIf(level); + } + else if (!strncmp(pr_file_p, "<", 1)) + { + pr_file_p += 1; + eval = eval < ParsePrecompilerIf(level); + } + else if (!strncmp(pr_file_p, ">", 1)) + { + pr_file_p += 1; + eval = eval > ParsePrecompilerIf(level); + } + else if (!strncmp(pr_file_p, "!=", 2)) + { + pr_file_p += 2; + eval = eval != ParsePrecompilerIf(level); + } + else if (!strncmp(pr_file_p, "==", 2)) + { + pr_file_p += 2; + eval = eval == ParsePrecompilerIf(level); + } + break; + } return eval; } + +static void QCC_PR_SkipToEndOfLine(void) +{ + while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line + { + if (*pr_file_p == '/' && pr_file_p[1] == '*') + { + pr_file_p += 2; + while(*pr_file_p) + { + if (*pr_file_p == '*' && pr_file_p[1] == '/') + { + pr_file_p+=2; + break; + } + if (*pr_file_p == '\n') + pr_source_line++; + *pr_file_p++; + } + } + else if (*pr_file_p == '\\' && pr_file_p[1] == '\r' && pr_file_p[2] == '\n') + { /*windows endings*/ + pr_file_p+=3; + pr_source_line++; + } + else if (*pr_file_p == '\\' && pr_file_p[1] == '\n') + { /*linux endings*/ + pr_file_p+=2; + + pr_source_line++; + } + else + pr_file_p++; + } +} /* ============== QCC_PR_Precompiler @@ -343,39 +431,33 @@ pbool QCC_PR_Precompiler(void) { pr_file_p = directive; QCC_PR_ConditionCompilation(); - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } else if (!strncmp(directive, "undef", 5)) { pr_file_p = directive+5; - while(*pr_file_p <= ' ') + while(qcc_iswhitesameline(*pr_file_p)) pr_file_p++; QCC_PR_SimpleGetToken (); QCC_PR_UndefineName(pr_token); // QCC_PR_ConditionCompilation(); - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } else if (!strncmp(directive, "if", 2)) { int originalline = pr_source_line; pr_file_p = directive+2; - if (!strncmp(pr_file_p, "def ", 4)) + if (!strncmp(pr_file_p, "def", 3)) { ifmode = 0; - pr_file_p+=4; + pr_file_p+=3; } - else if (!strncmp(pr_file_p, "ndef ", 5)) + else if (!strncmp(pr_file_p, "ndef", 4)) { ifmode = 1; - pr_file_p+=5; + pr_file_p+=4; } else { @@ -384,77 +466,78 @@ pbool QCC_PR_Precompiler(void) //QCC_PR_ParseError("bad \"#if\" type"); } - if (ifmode == 2) - { - eval = ParsePrecompilerIf(); - - if(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - QCC_PR_ParseError (ERR_NOENDIF, "junk on the end of #if line"); - } - } - else + if (!qcc_iswhite(*pr_file_p)) { + pr_file_p = directive; QCC_PR_SimpleGetToken (); - - // if (!STRCMP(pr_token, "COOP_MODE")) - // eval = false; - if (QCC_PR_CheckCompConstDefined(pr_token)) - eval = true; - - if (ifmode == 1) - eval = eval?false:true; + QCC_PR_ParseWarning(WARN_BADPRAGMA, "Unknown pragma \'%s\'", qcc_token); } - - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } - level = 1; - - if (eval) - ifs+=1; else { - while (1) + if (ifmode == 2) { - while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t')) - pr_file_p++; + eval = ParsePrecompilerIf(PPI_TOPLEVEL); - if (!*pr_file_p) + if(*pr_file_p != '\r' && *pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line { - pr_source_line = originalline; - QCC_PR_ParseError (ERR_NOENDIF, "#if with no endif"); + QCC_PR_ParseError (ERR_NOENDIF, "junk on the end of #if line"); } + } + else + { + QCC_PR_SimpleGetToken (); - if (*pr_file_p == '#') + // if (!STRCMP(pr_token, "COOP_MODE")) + // eval = false; + if (QCC_PR_CheckCompConstDefined(pr_token)) + eval = true; + + if (ifmode == 1) + eval = eval?false:true; + } + + QCC_PR_SkipToEndOfLine(); + level = 1; + + if (eval) + ifs+=1; + else + { + while (1) { - pr_file_p++; - while(*pr_file_p==' ' || *pr_file_p == '\t') + while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t')) pr_file_p++; - if (!strncmp(pr_file_p, "endif", 5)) - level--; - if (!strncmp(pr_file_p, "if", 2)) - level++; - if (!strncmp(pr_file_p, "else", 4) && level == 1) - { - ifs+=1; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } - break; - } - } - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; + if (!*pr_file_p) + { + pr_source_line = originalline; + QCC_PR_ParseError (ERR_NOENDIF, "#if with no endif"); + } + + if (*pr_file_p == '#') + { + pr_file_p++; + while(*pr_file_p==' ' || *pr_file_p == '\t') + pr_file_p++; + if (!strncmp(pr_file_p, "endif", 5)) + level--; + if (!strncmp(pr_file_p, "if", 2)) + level++; + if (!strncmp(pr_file_p, "else", 4) && level == 1) + { + ifs+=1; + QCC_PR_SkipToEndOfLine(); + break; + } + } + + QCC_PR_SkipToEndOfLine(); + + if (level <= 0) + break; + pr_file_p++; //next line + pr_source_line++; } - if (level <= 0) - break; - pr_file_p++; //next line - pr_source_line++; } } } @@ -465,10 +548,7 @@ pbool QCC_PR_Precompiler(void) ifs -= 1; level = 1; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); while (1) { while(*pr_file_p && (*pr_file_p==' ' || *pr_file_p == '\t')) @@ -497,10 +577,7 @@ pbool QCC_PR_Precompiler(void) } } - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); if (level <= 0) break; pr_file_p++; //go off the end @@ -509,10 +586,7 @@ pbool QCC_PR_Precompiler(void) } else if (!strncmp(directive, "endif", 5)) { - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); if (ifs <= 0) QCC_PR_ParseError(ERR_NOPRECOMPILERIF, "unmatched #endif"); else @@ -531,10 +605,7 @@ pbool QCC_PR_Precompiler(void) msg[a] = '\0'; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line, yes, I KNOW we are going to register an error, and not properly leave this function tree, but... - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); QCC_PR_ParseError(ERR_HASHERROR, "#Error: %s", msg); } @@ -546,10 +617,7 @@ pbool QCC_PR_Precompiler(void) msg[a-1] = '\0'; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); QCC_PR_ParseWarning(WARN_PRECOMPILERMESSAGE, "#warning: %s", msg); } @@ -561,10 +629,7 @@ pbool QCC_PR_Precompiler(void) msg[a-1] = '\0'; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); printf("#message: %s\n", msg); } @@ -576,10 +641,7 @@ pbool QCC_PR_Precompiler(void) msg[a-1] = '\0'; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); if (strlen(msg) >= sizeof(QCC_copyright)) QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Copyright message is too long\n"); @@ -628,17 +690,18 @@ pbool QCC_PR_Precompiler(void) msg[a-1] = '\0'; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } else if (!strncmp(directive, "includelist", 11)) { pr_file_p=directive+11; - while(*pr_file_p <= ' ') + while(qcc_iswhite(*pr_file_p)) + { + if (*pr_file_p == '\n') + pr_source_line++; pr_file_p++; + } while(1) { @@ -662,16 +725,10 @@ pbool QCC_PR_Precompiler(void) if (*pr_file_p == '\r') pr_file_p++; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } else if (!strncmp(directive, "include", 7)) { @@ -679,7 +736,7 @@ pbool QCC_PR_Precompiler(void) pr_file_p=directive+7; - while(*pr_file_p <= ' ') + while(qcc_iswhitesameline(*pr_file_p)) pr_file_p++; msg[0] = '\0'; @@ -710,20 +767,17 @@ pbool QCC_PR_Precompiler(void) pr_file_p++; - while(*pr_file_p != '\n' && *pr_file_p != '\0' && *pr_file_p <= ' ') + while(*pr_file_p != '\n' && *pr_file_p != '\0' && qcc_iswhitesameline(*pr_file_p)) pr_file_p++; - while(*pr_file_p != '\n' && *pr_file_p != '\0') //read on until the end of the line - { - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(); } else if (!strncmp(directive, "datafile", 8)) { pr_file_p=directive+8; - while(*pr_file_p <= ' ') + while(qcc_iswhitesameline(*pr_file_p)) pr_file_p++; QCC_PR_LexString(); @@ -747,7 +801,7 @@ pbool QCC_PR_Precompiler(void) extern char destfile[1024]; pr_file_p=directive+6; - while(*pr_file_p <= ' ') + while(qcc_iswhitesameline(*pr_file_p)) pr_file_p++; QCC_PR_LexString(); @@ -769,7 +823,7 @@ pbool QCC_PR_Precompiler(void) else if (!strncmp(directive, "pragma", 6)) { pr_file_p=directive+6; - while(*pr_file_p <= ' ') + while(qcc_iswhitesameline(*pr_file_p)) pr_file_p++; qcc_token[0] = '\0'; @@ -788,7 +842,7 @@ pbool QCC_PR_Precompiler(void) msg[a] = '\0'; { char *end; - for (end = msg + a-1; end>=msg && *end <= ' '; end--) + for (end = msg + a-1; end>=msg && qcc_iswhite(*end); end--) *end = '\0'; } @@ -800,7 +854,7 @@ pbool QCC_PR_Precompiler(void) { char *end; - for (end = msg + a-1; end>=msg && *end <= ' '; end--) + for (end = msg + a-1; end>=msg && qcc_iswhite(*end); end--) *end = '\0'; } @@ -874,31 +928,37 @@ pbool QCC_PR_Precompiler(void) } else if (!QC_strcasecmp(qcc_token, "TARGET")) { - if (qcc_targetformat == QCF_HEXEN2 && numstatements) - QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg); - else if (!QC_strcasecmp(msg, "H2") || !QC_strcasecmp(msg, "HEXEN2")) - { - if (numstatements) - QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch to hexen2 target \'%s\'. Ignored.", msg); - else - qcc_targetformat = QCF_HEXEN2; - } + int newtype = qcc_targetformat; + if (!QC_strcasecmp(msg, "H2") || !QC_strcasecmp(msg, "HEXEN2")) + newtype = QCF_HEXEN2; else if (!QC_strcasecmp(msg, "KK7")) - qcc_targetformat = QCF_KK7; + newtype = QCF_KK7; else if (!QC_strcasecmp(msg, "DP") || !QC_strcasecmp(msg, "DARKPLACES")) - qcc_targetformat = QCF_DARKPLACES; + newtype = QCF_DARKPLACES; else if (!QC_strcasecmp(msg, "FTEDEBUG")) - qcc_targetformat = QCF_FTEDEBUG; + newtype = QCF_FTEDEBUG; else if (!QC_strcasecmp(msg, "FTE")) - qcc_targetformat = QCF_FTE; + newtype = QCF_FTE; + else if (!QC_strcasecmp(msg, "FTEH2")) + newtype = QCF_FTEH2; else if (!QC_strcasecmp(msg, "STANDARD") || !QC_strcasecmp(msg, "ID")) - qcc_targetformat = QCF_STANDARD; + newtype = QCF_STANDARD; else if (!QC_strcasecmp(msg, "DEBUG")) - qcc_targetformat = QCF_FTEDEBUG; + newtype = QCF_FTEDEBUG; else if (!QC_strcasecmp(msg, "QTEST")) - qcc_targetformat = QCF_QTEST; + newtype = QCF_QTEST; else QCC_PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", msg); + + if (numstatements > 1) + { + if ((qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2) && (newtype != QCF_HEXEN2 && newtype != QCF_FTEH2)) + QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\'. Ignored.", msg); + if ((newtype == QCF_HEXEN2 || newtype == QCF_FTEH2) && (qcc_targetformat != QCF_HEXEN2 && qcc_targetformat != QCF_FTEH2)) + QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch to hexen2 target \'%s\'. Ignored.", msg); + } + + qcc_targetformat = newtype; } else if (!QC_strcasecmp(qcc_token, "PROGS_SRC")) { //doesn't make sence, but silenced if you are switching between using a certain precompiler app used with CuTF. @@ -994,11 +1054,13 @@ pbool QCC_PR_Precompiler(void) char *s; s = QCC_COM_Parse(msg); if (!stricmp(qcc_token, "enable") || !stricmp(qcc_token, "on")) - st = 0; - else if (!stricmp(qcc_token, "disable") || !stricmp(qcc_token, "off")) - st = 1; + st = WA_WARN; + else if (!stricmp(qcc_token, "disable") || !stricmp(qcc_token, "off") || !stricmp(qcc_token, "ignore")) + st = WA_IGNORE; + else if (!stricmp(qcc_token, "error")) + st = WA_ERROR; else if (!stricmp(qcc_token, "toggle")) - st = 2; + st = 3; else { QCC_PR_ParseWarning(WARN_BADPRAGMA, "warning state not recognised"); @@ -1013,10 +1075,10 @@ pbool QCC_PR_Precompiler(void) QCC_PR_ParseWarning(WARN_BADPRAGMA, "warning id not recognised"); else { - if (st == 2) //toggle - qccwarningdisabled[wn] = true - qccwarningdisabled[wn]; + if (st == 3) //toggle + qccwarningaction[wn] = !!qccwarningaction[wn]; else - qccwarningdisabled[wn] = st; + qccwarningaction[wn] = st; } } } @@ -1180,22 +1242,24 @@ void QCC_PR_LexString (void) else if (c == '"') c = '"'; else if (c == 't') - c = '\t'; + c = '\t'; //tab else if (c == 'a') - c = '\a'; + c = '\a'; //bell else if (c == 'v') - c = '\v'; + c = '\v'; //vertical tab else if (c == 'f') - c = '\f'; + c = '\f'; //form feed else if (c == 's' || c == 'b') { texttype ^= 128; continue; } + //else if (c == 'b') + // c = '\b'; else if (c == '[') - c = 16; + c = 16; //quake specific else if (c == ']') - c = 17; + c = 17; //quake specific else if (c == '{') { int d; @@ -1213,6 +1277,60 @@ void QCC_PR_LexString (void) c = 30; else if (c == '>') c = 31; + else if (c == 'u' || c == 'U') + { + //lower case u specifies exactly 4 nibbles. + //upper case U specifies variable length. terminate with a double-doublequote pair, or some other non-hex char. + int count = 0; + unsigned long d; + unsigned long unicode; + unicode = 0; + for(;;) + { + d = (unsigned char)*pr_file_p; + if (d >= '0' && d <= '9') + unicode = (unicode*16) + (d - '0'); + else if (d >= 'A' && d <= 'F') + unicode = (unicode*16) + (d - 'A') + 10; + else if (d >= 'a' && d <= 'f') + unicode = (unicode*16) + (d - 'a') + 10; + else + break; + count++; + pr_file_p++; + } + if (!count || ((c=='u')?(count!=4):(count>8)) || unicode > 0x10FFFFu) //RFC 3629 imposes the same limit as UTF-16 surrogate pairs. + QCC_PR_ParseWarning(ERR_BADCHARACTERCODE, "Bad character code"); + + //figure out the count of bytes required to encode this char + count = 1; + d = 0x7f; + while (unicode > d) + { + count++; + d = (d<<5) | 0x1f; + } + + //error if needed + if (len+count >= sizeof(pr_token)) + QCC_Error(ERR_INVALIDSTRINGIMMEDIATE, "String length exceeds %i", sizeof(pr_token)-1); + + //output it. + if (count == 1) + pr_token[len++] = (unsigned char)(c&0x7f); + else + { + c = count*6; + pr_token[len++] = (unsigned char)((unicode>>c)&(0x0000007f>>count)) | (0xffffff00 >> count); + do + { + c = c-6; + pr_token[len++] = (unsigned char)((unicode>>c)&0x3f) | 0x80; + } + while(c); + } + continue; + } else if (c == 'x' || c == 'X') { int d; @@ -1244,7 +1362,7 @@ void QCC_PR_LexString (void) c = '\\'; else if (c == '\'') c = '\''; - else if (c >= '0' && c <= '9') + else if (c >= '0' && c <= '9') //WARNING: This is not octal, but uses 'yellow' numbers instead (as on hud). c = 18 + c - '0'; else if (c == '\r') { //sigh @@ -1265,7 +1383,7 @@ void QCC_PR_LexString (void) if (len >= sizeof(pr_immediate_string)-1) QCC_Error(ERR_INVALIDSTRINGIMMEDIATE, "String length exceeds %i", sizeof(pr_immediate_string)-1); - while(*pr_file_p && *pr_file_p <= ' ') + while(*pr_file_p && qcc_iswhite(*pr_file_p)) { if (*pr_file_p == '\n') { @@ -1290,7 +1408,7 @@ void QCC_PR_LexString (void) { for (end = pr_file_p; ; end++) { - if (*end <= ' ') + if (qcc_iswhite(*end)) break; if (*end == ')' @@ -1673,7 +1791,7 @@ void QCC_PR_LexWhitespace (void) while (1) { // skip whitespace - while ( (c = *pr_file_p) <= ' ') + while ((c = *pr_file_p) && qcc_iswhite(c)) { if (c=='\n') { @@ -1683,12 +1801,10 @@ void QCC_PR_LexWhitespace (void) return; } else - { - if (c == 0) - return; // end of file pr_file_p++; - } } + if (c == 0) + return; // end of file // skip // comments if (c=='/' && pr_file_p[1] == '/') @@ -1738,10 +1854,11 @@ int pr_nummacros, pr_oldmacros; int pr_macrovalue; int pr_savedmacro; -void QCC_PR_ClearGrabMacros (void) +void QCC_PR_ClearGrabMacros (pbool newfile) { + if (!newfile) + pr_nummacros = 0; pr_oldmacros = pr_nummacros; -// pr_nummacros = 0; pr_macrovalue = 0; pr_savedmacro = -1; } @@ -1790,12 +1907,14 @@ pbool QCC_PR_SimpleGetToken (void) pr_token[0] = 0; // skip whitespace - while ( (c = *pr_file_p) <= ' ') + while ((c = *pr_file_p) && qcc_iswhite(c)) { - if (c=='\n' || c == 0) + if (c=='\n') return false; pr_file_p++; } + if (c == 0) //eof + return false; if (pr_file_p[0] == '/') { if (pr_file_p[1] == '/') @@ -1809,8 +1928,10 @@ pbool QCC_PR_SimpleGetToken (void) } i = 0; - while ( (c = *pr_file_p) > ' ' && c != ',' && c != ';' && c != ')' && c != '(' && c != ']') + while ((c = *pr_file_p) && !qcc_iswhite(c) && c != ',' && c != ';' && c != ')' && c != '(' && c != ']') { + if (i == sizeof(qcc_token)-1) + QCC_Error (ERR_INTERNAL, "token exceeds %i chars", i); pr_token[i] = c; i++; pr_file_p++; @@ -1827,12 +1948,14 @@ pbool QCC_PR_LexMacroName(void) pr_token[0] = 0; // skip whitespace - while ( (c = *pr_file_p) <= ' ') + while ((c = *pr_file_p) && qcc_iswhite(c)) { - if (c=='\n' || c == 0) + if (c=='\n') return false; pr_file_p++; } + if (!c) + return false; if (pr_file_p[0] == '/') { if (pr_file_p[1] == '/') @@ -1848,6 +1971,8 @@ pbool QCC_PR_LexMacroName(void) i = 0; while ( (c = *pr_file_p) > ' ' && c != '\n' && c != ',' && c != ';' && c != ')' && c != '(' && c != ']' && !(pr_file_p[0] == '.' && pr_file_p[1] == '.')) { + if (i == sizeof(qcc_token)-1) + QCC_Error (ERR_INTERNAL, "token exceeds %i chars", i); pr_token[i] = c; i++; pr_file_p++; @@ -1903,7 +2028,7 @@ void QCC_PR_LexGrab (void) pr_file_p++; // skip the $ // if (!QCC_PR_SimpleGetToken ()) // QCC_PR_ParseError ("hanging $"); - if (*pr_file_p <= ' ') + if (qcc_iswhite(*pr_file_p)) QCC_PR_ParseError (ERR_BADFRAMEMACRO, "hanging $"); QCC_PR_LexMacroName(); if (!*pr_token) @@ -1929,7 +2054,7 @@ void QCC_PR_LexGrab (void) } else if (!STRCMP (pr_token, "flush")) { - QCC_PR_ClearGrabMacros(); + QCC_PR_ClearGrabMacros(true); while (QCC_PR_LexMacroName ()) ; QCC_PR_Lex (); @@ -2194,7 +2319,7 @@ int QCC_PR_CheckCompConst(void) char *end; for (end = pr_file_p; ; end++) { - if (*end <= ' ') + if (!*end || qcc_iswhite(*end)) break; if (*end == ')' @@ -2305,7 +2430,7 @@ int QCC_PR_CheckCompConst(void) { whitestart = bufferlen; starttok = pr_file_p; - while(*pr_file_p <= ' ') //copy across whitespace + while(qcc_iswhite(*pr_file_p)) //copy across whitespace { if (!*pr_file_p) break; @@ -2570,7 +2695,7 @@ void QCC_PR_Lex (void) // if the first character is a valid identifier, parse until a non-id // character is reached - if ( c == '~' || c == '%') //let's see which one we make into an operator first... possibly both... + if ((c == '~' || c == '%') && pr_file_p[1] >= '0' && pr_file_p[1] <= '9') //let's see which one we make into an operator first... possibly both... { QCC_PR_ParseWarning(0, "~ or %% prefixes to denote integers are deprecated. Please use a postfix of 'i'"); pr_file_p++; @@ -2640,7 +2765,7 @@ void QCC_PR_Lex (void) void QCC_PR_ParsePrintDef (int type, QCC_def_t *def) { - if (qccwarningdisabled[type]) + if (!qccwarningaction[type]) return; if (def->s_file) { @@ -2680,6 +2805,7 @@ Aborts the current file load #ifndef QCC void editbadfile(char *file, int line); #endif +//will abort. void VARGS QCC_PR_ParseError (int errortype, char *error, ...) { va_list argptr; @@ -2701,6 +2827,7 @@ void VARGS QCC_PR_ParseError (int errortype, char *error, ...) longjmp (pr_parse_abort, 1); } +//will abort. void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error, ...) { va_list argptr; @@ -2723,86 +2850,96 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error longjmp (pr_parse_abort, 1); } -void VARGS QCC_PR_ParseWarning (int type, char *error, ...) + +pbool VARGS QCC_PR_PrintWarning (int type, char *file, int line, char *string) { - va_list argptr; - char string[1024]; - - if (type < ERR_PARSEERRORS && qccwarningdisabled[type]) - return; - - va_start (argptr,error); - QC_vsnprintf (string,sizeof(string)-1, error,argptr); - va_end (argptr); + char *wnam = QCC_NameForWarning(type); + if (!wnam) + wnam = ""; QCC_PR_PrintScope(); if (type >= ERR_PARSEERRORS) { - if (flag_msvcstyle) - printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string); + if (!file) + printf ("error%s: %s\n", wnam, string); + else if (flag_msvcstyle) + printf ("%s(%i) : error%s: %s\n", file, line, wnam, string); else - printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); + printf ("%s:%i: error%s: %s\n", file, line, wnam, string); + pr_error_count++; + } + else if (qccwarningaction[type] == 2) + { //-werror + if (!file) + printf ("werror%s: %s\n", wnam, string); + else if (flag_msvcstyle) + printf ("%s(%i) : werror%s: %s\n", file, line, wnam, string); + else + printf ("%s:%i: werror%s: %s\n", file, line, wnam, string); pr_error_count++; } else { - if (flag_msvcstyle) - printf ("%s(%i) : warning: %s\n", strings + s_file, pr_source_line, string); + if (!file) + printf ("warning%s: %s\n", wnam, string); + else if (flag_msvcstyle) + printf ("%s(%i) : warning%s: %s\n", file, line, wnam, string); else - printf ("%s:%i: warning: %s\n", strings + s_file, pr_source_line, string); + printf ("%s:%i: warning%s: %s\n", file, line, wnam, string); pr_warning_count++; } + return true; } - -void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...) -{ - va_list argptr; - char string[1024]; - - if (qccwarningdisabled[type]) - return; - - va_start (argptr,error); - QC_vsnprintf (string,sizeof(string)-1, error,argptr); - va_end (argptr); - - QCC_PR_PrintScope(); - if (file) - { - if (flag_msvcstyle) - printf ("%s(%i) : note: %s\n", file, line, string); - else - printf ("%s:%i: note: %s\n", file, line, string); - } - else - printf ("note: %s\n", string); -} - pbool VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...) { va_list argptr; char string[1024]; - if (qccwarningdisabled[type]) + if (!qccwarningaction[type]) return false; va_start (argptr,error); QC_vsnprintf (string,sizeof(string)-1, error,argptr); va_end (argptr); - QCC_PR_PrintScope(); - if (file) - { - if (flag_msvcstyle) - printf ("%s(%i) : warning: %s\n", file, line, string); - else - printf ("%s:%i: warning: %s\n", file, line, string); - } - else - printf ("warning: %s\n", string); - pr_warning_count++; + return QCC_PR_PrintWarning(type, file, line, string); +} - return true; +//can be used for errors, qcc execution will continue. +pbool VARGS QCC_PR_ParseWarning (int type, char *error, ...) +{ + va_list argptr; + char string[1024]; + + if (!qccwarningaction[type]) + return false; + + va_start (argptr,error); + QC_vsnprintf (string,sizeof(string)-1, error,argptr); + va_end (argptr); + + return QCC_PR_PrintWarning(type, strings + s_file, pr_source_line, string); +} + +void VARGS QCC_PR_Note (int type, char *file, int line, char *error, ...) +{ + va_list argptr; + char string[1024]; + + if (!qccwarningaction[type]) + return; + + va_start (argptr,error); + QC_vsnprintf (string,sizeof(string)-1, error,argptr); + va_end (argptr); + + QCC_PR_PrintScope(); + if (!file) + printf ("note: %s\n", string); + else if (flag_msvcstyle) + printf ("%s(%i) : note: %s\n", file, line, string); + else + printf ("%s:%i: note: %s\n", file, line, string); } diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c index 9bcd9077..2911ed60 100644 --- a/engine/qclib/qccgui.c +++ b/engine/qclib/qccgui.c @@ -1652,7 +1652,8 @@ static LONG CALLBACK MainWndProc(HWND hWnd,UINT message, } } break; - + case WM_CTLCOLORBTN: + return GetSysColorBrush(COLOR_HIGHLIGHT);//COLOR_BACKGROUND; case WM_DESTROY: mainwindow = NULL; break; @@ -1781,7 +1782,6 @@ static LONG CALLBACK OutputWindowProc(HWND hWnd,UINT message, case WM_SIZE: GetClientRect(hWnd, &rect); SetWindowPos(outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0); - default: return DefMDIChildProc(hWnd,message,wParam,lParam); } @@ -1847,10 +1847,12 @@ int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour) cf.crTextColor = colour; SendMessage(wnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); Edit_SetSel(wnd,start+len,start+len); + Edit_ScrollCaret(wnd); return start + len; } int outlen; +int outstatus; int GUIprintf(const char *msg, ...) { va_list argptr; @@ -1872,15 +1874,38 @@ int GUIprintf(const char *msg, ...) if (!*buf) { + /*clear text*/ SetWindowText(outputbox,""); outlen = 0; + + /*make sure its active so we can actually scroll. stupid windows*/ + SetFocus(outputwindow); + SetFocus(outputbox); + + /*colour background to default*/ + TreeView_SetBkColor(projecttree, -1); + outstatus = 0; return 0; } if (strstr(buf, "warning: ")) + { + if (outstatus < 1) + { + TreeView_SetBkColor(projecttree, RGB(255, 255, 0)); + outstatus = 1; + } col = RGB(128, 128, 0); + } else if (strstr(buf, "error: ")) + { + if (outstatus < 2) + { + TreeView_SetBkColor(projecttree, RGB(255, 0, 0)); + outstatus = 2; + } col = RGB(255, 0, 0); + } else col = RGB(0, 0, 0); @@ -1975,13 +2000,13 @@ void RunCompiler(char *args) } memset(&funcs, 0, sizeof(funcs)); - funcs.parms = &ext; + funcs.funcs.parms = &ext; memset(&ext, 0, sizeof(ext)); - funcs.parms->ReadFile = GUIReadFile; - funcs.parms->FileSize = GUIFileSize; - funcs.parms->WriteFile = QCC_WriteFile; - funcs.parms->printf = GUIprintf; - funcs.parms->Sys_Error = Sys_Error; + ext.ReadFile = GUIReadFile; + ext.FileSize = GUIFileSize; + ext.WriteFile = QCC_WriteFile; + ext.Printf = GUIprintf; + ext.Sys_Error = Sys_Error; GUIprintf(""); if (logfile) diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index b88bc62c..e8a3695c 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -6,6 +6,7 @@ #ifdef _WIN32 #include #endif +#include #include "errno.h" @@ -17,7 +18,6 @@ extern int optres_test1; extern int optres_test2; int writeasm; -static pbool pr_werror; pbool verbose; @@ -45,6 +45,7 @@ int numtemps; char sourcefileslist[MAXSOURCEFILESLIST][1024]; int currentsourcefile; int numsourcefiles; +extern char *compilingfile; void QCC_PR_ResetErrorScope(void); @@ -105,7 +106,7 @@ hashtable_t stringconstdefstable; hashtable_t stringconstdefstable_trans; extern int dotranslate_count; -pbool qccwarningdisabled[WARN_MAX]; +unsigned char qccwarningaction[WARN_MAX]; //0 = disabled, 1 = warn, 2 = error. qcc_targetformat_t qcc_targetformat; @@ -121,22 +122,48 @@ struct { int index; } warningnames[] = { - {"Q302", WARN_NOTREFERENCED}, // {"", WARN_NOTREFERENCEDCONST}, // {"", WARN_CONFLICTINGRETURNS}, - {"Q105", WARN_TOOFEWPARAMS}, - {"Q101", WARN_TOOMANYPARAMS}, + {" Q100", WARN_PRECOMPILERMESSAGE}, + {" Q101", WARN_TOOMANYPARAMS}, + //102: Indirect function: too many parameters + //103: vararg func cannot have more than + //104: type mismatch on parm %i + {" Q105", WARN_TOOFEWPARAMS}, // {"", WARN_UNEXPECTEDPUNCT}, - {"Q106", WARN_ASSIGNMENTTOCONSTANT}, - {"Q203", WARN_MISSINGRETURNVALUE}, - {"Q204", WARN_WRONGRETURNTYPE}, - {"Q205", WARN_POINTLESSSTATEMENT}, - {"Q206", WARN_MISSINGRETURN}, - {"Q207", WARN_DUPLICATEDEFINITION}, - {"Q100", WARN_PRECOMPILERMESSAGE}, + {" Q106", WARN_ASSIGNMENTTOCONSTANT}, + //107: Array index should be type int + //108: Mixed float and int types + //109: Expecting int, float a parameter found + //110: Expecting int, float b parameter found + //112: Null 'if' statement + //113: Null 'else' statement + //114: Type mismatch on redeclaration + //115: redeclared with different number of parms + //116: Local %s redeclared + //117: too many initializers + //118: Too many closing braces + //119: Too many #endifs + {" Q120", WARN_BADPRAGMA}, + //121: unknown directive + //122: strofs exceeds limit + //123: numstatements exceeds limit + //124: numfunctions exceeds limit + //125: numglobaldefs exceeds limit + //126: numfielddefs exceeds limit + //127: numpr_globals exceeds limit + //128: rededeclared with different parms + {" Q203", WARN_MISSINGRETURNVALUE}, + {" Q204", WARN_WRONGRETURNTYPE}, + {" Q205", WARN_POINTLESSSTATEMENT}, + {" Q206", WARN_MISSINGRETURN}, + {" Q207", WARN_DUPLICATEDEFINITION}, //redeclared different scope + {" Q208", WARN_SYSTEMCRC}, // {"", WARN_STRINGTOOLONG}, // {"", WARN_BADTARGET}, - {"Q120", WARN_BADPRAGMA}, + //301: %s defined as local in %s + {" Q302", WARN_NOTREFERENCED}, //302: Unreferenced local variable %s from line %i + //401: In function %s parameter %s is unused // {"", WARN_HANGINGSLASHR}, // {"", WARN_NOTDEFINED}, // {"", WARN_SWITCHTYPEMISMATCH}, @@ -145,18 +172,41 @@ struct { // {"", WARN_ENUMFLAGS_NOTINTEGER}, // {"", WARN_ENUMFLAGS_NOTBINARY}, // {"", WARN_CASEINSENSATIVEFRAMEMACRO}, - {"Q111", WARN_DUPLICATELABEL}, - {"Q201", WARN_ASSIGNMENTINCONDITIONAL}, - {"F300", WARN_DEADCODE}, + {" Q111", WARN_DUPLICATELABEL}, + {" Q201", WARN_ASSIGNMENTINCONDITIONAL}, + {" F300", WARN_DEADCODE}, + + //frikqcc errors + //Q608: PrecacheSound: numsounds + //Q609: PrecacheModels: nummodels + //Q610: PrecacheFile: numfiles + //Q611: Bad parm order + //Q612: PR_CompileFile: Didn't clear (internal error) + //Q614: PR_DefForFieldOfs: couldn't find + //Q613: Error writing error.log + //Q615: Error writing + //Q616: No function named + //Q617: Malloc failure + //Q618: Ran out of mem pointer space (malloc failure again) {NULL} }; +char *QCC_NameForWarning(int idx) +{ + int i; + for (i = 0; warningnames[i].name; i++) + { + if (warningnames[i].index == idx) + return warningnames[i].name; + } + return NULL; +} int QCC_WarningForName(char *name) { int i; for (i = 0; warningnames[i].name; i++) { - if (!stricmp(name, warningnames[i].name)) + if (!stricmp(name, warningnames[i].name+1)) return warningnames[i].index; } return -1; @@ -266,6 +316,7 @@ struct { {QCF_KK7, "version7"}, {QCF_KK7, "kkqwsv"}, {QCF_FTE, "fte"}, + {QCF_FTEH2, "fteh2"}, {QCF_DARKPLACES,"darkplaces"}, {QCF_DARKPLACES,"dp"}, {QCF_QTEST, "qtest"}, @@ -617,23 +668,29 @@ pbool QCC_WriteData (int crc) printf("Forcing target to FTE32 due to numpr_globals\n"); outputsttype = PST_FTE32; } + else if (qcc_targetformat == QCF_FTEH2) + { + printf("Progs execution will require FTE\n"); + break; + } else if (qcc_targetformat == QCF_HEXEN2) { - printf("Progs execution requires a Hexen2 compatible engine\n"); + printf("Progs execution requires a Hexen2 compatible HCVM\n"); break; } else { if (numpr_globals >= 32768) //not much of a different format. Rewrite output to get it working on original executors? - printf("An enhanced executor will be required (FTE/QF/KK)\n"); + printf("An enhanced QCVM will be required (FTE/QF/KK)\n"); else - printf("Progs should run on any Quake executor\n"); + printf("Progs should run on any QuakeC VM\n"); break; } - //intentional - qcc_targetformat = QCF_FTE; + qcc_targetformat = (qcc_targetformat==QCF_HEXEN2)?QCF_FTEH2:QCF_FTE; + //intentional fallthrough case QCF_FTEDEBUG: case QCF_FTE: + case QCF_FTEH2: case QCF_DARKPLACES: if (qcc_targetformat == QCF_FTEDEBUG) debugtarget = true; @@ -950,7 +1007,7 @@ strofs = (strofs+3)&~3; progs.ofs_statements = SafeSeek (h, 0, SEEK_CUR); progs.numstatements = numstatements; - if (qcc_targetformat == QCF_HEXEN2) + if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2) { for (i=0 ; icode && !f->builtin) ) if (d->initialized==0) { - s_file = d->s_file; if (!strncmp(d->name, "ArrayGet*", 9)) { QCC_PR_EmitArrayGetFunction(d, d->name+9); @@ -1764,12 +1820,11 @@ int QCC_PR_FinishCompilation (void) } else { - QCC_PR_ParseWarning(ERR_NOFUNC, "function %s was not defined",d->name); + QCC_PR_Warning(ERR_NOFUNC, strings + d->s_file, d->s_line, "function %s has no body",d->name); QCC_PR_ParsePrintDef(ERR_NOFUNC, d); bodylessfuncs = true; errors = true; } - s_file = 0; // errors = true; } else if (d->initialized==2) @@ -1916,7 +1971,7 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) //ADD3: crc but don't dump ADD("\n/* "); - if (qcc_targetformat == QCF_HEXEN2) + if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2) ADD3("generated by hcc, do not modify"); else ADD3("file generated by qcc, do not modify"); @@ -2084,10 +2139,10 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) break; case 17105: case 32199: //outdated ext_csqc - printf("Recognised progs as outdated CSQC module\n"); + QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "Recognised progs as outdated CSQC module\n"); break; - case 52195: - printf("Recognised progs as outdated CSQC module\n"); + case 52195: //this is what DP requires. don't print it as the warning that it is as that would royally piss off xonotic and their use of -Werror. + printf("Recognised progs as DP-specific CSQC module\n"); break; case 10020: if (verbose) @@ -2095,10 +2150,10 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) break; case 32401: - printf("Warning: please update your tenebrae system defs.\n"); + QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "Warning: please update your tenebrae system defs.\n"); break; default: - printf("Warning: progs CRC not recognised from quake nor clones\n"); + QCC_PR_Warning(WARN_SYSTEMCRC, NULL, 0, "Warning: progs CRC not recognised from quake nor clones\n"); break; } @@ -2514,8 +2569,9 @@ void QCC_CopyFiles (void) void QCC_PR_CommandLinePrecompilerOptions (void) { CompilerConstant_t *cnst; - int i, p; + int i, j, p; char *name, *val; + pbool werror = false; for (i = 1;i= 0) + qccwarningaction[p] = WA_ERROR; + } + else if (!strnicmp(myargv[i]+2, "no-", 3)) + { + p = QCC_WarningForName(myargv[i]+5); + if (p >= 0) + qccwarningaction[p] = WA_IGNORE; } else { - for (p = 0; warningnames[p].name; p++) - if (!stricmp(myargv[i]+2, warningnames[p].name)) - { - qccwarningdisabled[warningnames[p].index] = false; - break; - } + p = QCC_WarningForName(myargv[i]+2); + if (p >= 0) + qccwarningaction[p] = WA_WARN; } - if (!warningnames[p].name) + if (p < 0) QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised warning parameter (%s)", myargv[i]); } } } + + if (werror) + { + for (j = 0; j < ERR_PARSEERRORS; j++) + if (qccwarningaction[j]) + qccwarningaction[j] = WA_ERROR; + } } /* @@ -2773,6 +2844,8 @@ void QCC_SetDefaultProperties (void) qcc_targetformat = QCF_HEXEN2; else if (QCC_CheckParm ("-fte")) qcc_targetformat = QCF_FTE; + else if (QCC_CheckParm ("-fteh2")) + qcc_targetformat = QCF_FTEH2; else if (QCC_CheckParm ("-dp")) qcc_targetformat = QCF_DARKPLACES; else @@ -2780,36 +2853,32 @@ void QCC_SetDefaultProperties (void) //enable all warnings - memset(qccwarningdisabled, 0, sizeof(qccwarningdisabled)); + for (i = 0; i < ERR_PARSEERRORS; i++) + qccwarningaction[i] = WA_WARN; + for (; i < WARN_MAX; i++) + qccwarningaction[i] = WA_ERROR; //play with default warnings. - qccwarningdisabled[WARN_NOTREFERENCEDCONST] = true; - qccwarningdisabled[WARN_MACROINSTRING] = true; -// qccwarningdisabled[WARN_ASSIGNMENTTOCONSTANT] = true; - qccwarningdisabled[WARN_FIXEDRETURNVALUECONFLICT] = true; - qccwarningdisabled[WARN_EXTRAPRECACHE] = true; - qccwarningdisabled[WARN_DEADCODE] = true; - qccwarningdisabled[WARN_INEFFICIENTPLUSPLUS] = true; - qccwarningdisabled[WARN_FTE_SPECIFIC] = true; - qccwarningdisabled[WARN_EXTENSION_USED] = true; - qccwarningdisabled[WARN_IFSTRING_USED] = true; - qccwarningdisabled[WARN_CORRECTEDRETURNTYPE] = true; - - - - if (QCC_CheckParm("-nowarn") || QCC_CheckParm("-Wnone")) - memset(qccwarningdisabled, 1, sizeof(qccwarningdisabled)); - if (QCC_CheckParm("-Wall")) - memset(qccwarningdisabled, 0, sizeof(qccwarningdisabled)); + qccwarningaction[WARN_NOTREFERENCEDCONST] = WA_IGNORE; + qccwarningaction[WARN_MACROINSTRING] = WA_IGNORE; +// qccwarningaction[WARN_ASSIGNMENTTOCONSTANT] = true; + qccwarningaction[WARN_FIXEDRETURNVALUECONFLICT] = WA_IGNORE; + qccwarningaction[WARN_EXTRAPRECACHE] = WA_IGNORE; + qccwarningaction[WARN_DEADCODE] = WA_IGNORE; + qccwarningaction[WARN_INEFFICIENTPLUSPLUS] = WA_IGNORE; + qccwarningaction[WARN_FTE_SPECIFIC] = WA_IGNORE; + qccwarningaction[WARN_EXTENSION_USED] = WA_IGNORE; + qccwarningaction[WARN_IFSTRING_USED] = WA_IGNORE; + qccwarningaction[WARN_CORRECTEDRETURNTYPE] = WA_IGNORE; if (QCC_CheckParm("-h2")) - qccwarningdisabled[WARN_CASEINSENSATIVEFRAMEMACRO] = true; + qccwarningaction[WARN_CASEINSENSATIVEFRAMEMACRO] = WA_IGNORE; //Check the command line QCC_PR_CommandLinePrecompilerOptions(); - if (qcc_targetformat == QCF_HEXEN2) //force on the thinktime keyword if hexen2 progs. + if (qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2) //force on the thinktime keyword if hexen2 progs. keyword_thinktime = true; if (QCC_CheckParm("/Debug")) //disable any debug optimisations @@ -2886,6 +2955,7 @@ char *originalqccmsrc; //for autoprototype. void QCC_main (int argc, char **argv) //as part of the quake engine { extern int pr_bracelevel; + time_t long_time; int p; @@ -2972,7 +3042,8 @@ void QCC_main (int argc, char **argv) //as part of the quake engine } */ - strcpy(QCC_copyright, "This file was created with ForeThought's modified QuakeC compiler\nThanks to ID Software"); + time(&long_time); + strftime(QCC_copyright, sizeof(QCC_copyright), "Compiled [%Y/%m/%d]", localtime( &long_time )); for (p = 0; p < 5; p++) strcpy(QCC_Packname[p], ""); @@ -2980,7 +3051,6 @@ void QCC_main (int argc, char **argv) //as part of the quake engine { *compiler_flag[p].enabled = compiler_flag[p].flags & FLAG_ASDEFAULT; } - pr_werror = false; QCC_SetDefaultProperties(); @@ -3047,22 +3117,22 @@ void QCC_main (int argc, char **argv) //as part of the quake engine memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); - precache_sounds = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*MAX_SOUNDS); - precache_sounds_block = (void *)qccHunkAlloc(sizeof(int)*MAX_SOUNDS); - precache_sounds_used = (void *)qccHunkAlloc(sizeof(int)*MAX_SOUNDS); + precache_sounds = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_SOUNDS); + precache_sounds_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_SOUNDS); + precache_sounds_used = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_SOUNDS); numsounds=0; - precache_textures = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*MAX_TEXTURES); - precache_textures_block = (void *)qccHunkAlloc(sizeof(int)*MAX_TEXTURES); + precache_textures = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_TEXTURES); + precache_textures_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_TEXTURES); numtextures=0; - precache_models = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*MAX_MODELS); - precache_models_block = (void *)qccHunkAlloc(sizeof(int)*MAX_MODELS); - precache_models_used = (void *)qccHunkAlloc(sizeof(int)*MAX_MODELS); + precache_models = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_MODELS); + precache_models_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_MODELS); + precache_models_used = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_MODELS); nummodels=0; - precache_files = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*MAX_FILES); - precache_files_block = (void *)qccHunkAlloc(sizeof(int)*MAX_FILES); + precache_files = (void *)qccHunkAlloc(sizeof(char)*MAX_DATA_PATH*QCC_MAX_FILES); + precache_files_block = (void *)qccHunkAlloc(sizeof(int)*QCC_MAX_FILES); numfiles = 0; qcc_typeinfo = (void *)qccHunkAlloc(sizeof(QCC_type_t)*maxtypeinfos); @@ -3129,6 +3199,8 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); QCC_PR_BeginCompilation ((void *)qccHunkAlloc (0x100000), 0x100000); + QCC_PR_ClearGrabMacros (false); + if (flag_acc) { if (!QCC_FindQCFiles()) @@ -3185,8 +3257,6 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); #endif newstylesource = false; - while(*qccmsrc && *qccmsrc < ' ') - qccmsrc++; pr_file_p = QCC_COM_Parse(qccmsrc); if (QCC_CheckParm ("-qc")) @@ -3202,6 +3272,7 @@ memset(pr_immediate_string, 0, sizeof(pr_immediate_string)); goto newstyle; } + compilingfile = qccmprogsdat; if (*qcc_token == '#') { void StartNewStyleCompile(void); @@ -3414,9 +3485,6 @@ void QCC_FinishCompile(void) } }*/ - if (pr_werror && pr_warning_count != 0) - QCC_Error (ERR_PARSEERRORS, "compilation errors"); - // write progdefs.h crc = QCC_PR_WriteProgdefs ("progdefs.h"); @@ -3495,7 +3563,6 @@ void QCC_FinishCompile(void) -extern char *compilingfile; extern QCC_string_t s_file, s_file2; extern char *pr_file_p; extern int pr_source_line; @@ -3520,9 +3587,6 @@ void StartNewStyleCompile(void) return; } - - QCC_PR_ClearGrabMacros (); // clear the frame macros - compilingfile = qccmprogsdat; pr_file_p = qccmsrc; diff --git a/engine/qclib/qcd.h b/engine/qclib/qcd.h index fd7817eb..1c755a2e 100644 --- a/engine/qclib/qcd.h +++ b/engine/qclib/qcd.h @@ -2,6 +2,6 @@ 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); -char *filefromprogs(progfuncs_t *progfuncs, progsnum_t prnum, char *fname, int *size, char *buffer); -char *filefromnewprogs(progfuncs_t *progfuncs, char *prname, char *fname, int *size, char *buffer);//fixme - remove parm 1 +char *PDECL filefromprogs(pubprogfuncs_t *progfuncs, progsnum_t prnum, char *fname, int *size, char *buffer); +char *filefromnewprogs(pubprogfuncs_t *progfuncs, char *prname, char *fname, int *size, char *buffer);//fixme - remove parm 1 diff --git a/engine/qclib/qcd_main.c b/engine/qclib/qcd_main.c index 20c6f7ca..e38588d5 100644 --- a/engine/qclib/qcd_main.c +++ b/engine/qclib/qcd_main.c @@ -156,8 +156,9 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle) } #endif -char *filefromprogs(progfuncs_t *progfuncs, progsnum_t prnum, char *fname, int *size, char *buffer) +char *PDECL filefromprogs(pubprogfuncs_t *ppf, progsnum_t prnum, char *fname, int *size, char *buffer) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; int num; includeddatafile_t *s; if (!pr_progstate[prnum].progs) diff --git a/engine/qclib/qcdecomp.c b/engine/qclib/qcdecomp.c index 8e0b2788..b1e80d8b 100644 --- a/engine/qclib/qcdecomp.c +++ b/engine/qclib/qcdecomp.c @@ -61,7 +61,7 @@ QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed); jmp_buf decompilestatementfailure; #if 0 -pbool Decompile(progfuncs_t *progfuncs, char *fname) +pbool QC_Decompile(progfuncs_t *progfuncs, char *fname) { return false; } @@ -86,7 +86,6 @@ void VARGS writes(int hand, char *msg, ...) SafeWrite(hand, buf, strlen(buf)); }; -char *PR_UglyValueString (etype_t type, eval_t *val); ddef16_t *ED_GlobalAtOfs16 (progfuncs_t *progfuncs, int ofs); char *VarAtOfs(progfuncs_t *progfuncs, int ofs) { @@ -119,7 +118,7 @@ char *VarAtOfs(progfuncs_t *progfuncs, int ofs) } return buf; } - if (!def->s_name[progfuncs->stringtable] || !strcmp(progfuncs->stringtable+def->s_name, "IMMEDIATE")) + if (!def->s_name[progfuncs->funcs.stringtable] || !strcmp(progfuncs->funcs.stringtable+def->s_name, "IMMEDIATE")) { if (current_progstate->types) typen = current_progstate->types[def->type & ~DEF_SHARED].type; @@ -180,7 +179,7 @@ evaluateimmediate: return buf; } } - return def->s_name+progfuncs->stringtable; + return def->s_name+progfuncs->funcs.stringtable; } @@ -314,10 +313,10 @@ void WriteStatementProducingOfs(progfuncs_t *progfuncs, progstate_t *progs, int def = ED_GlobalAtOfs16(progfuncs, ofs); if (def) { - if (!strcmp(def->s_name+progfuncs->stringtable, "IMMEDIATE")) + if (!strcmp(def->s_name+progfuncs->funcs.stringtable, "IMMEDIATE")) writes(file, "%s", VarAtOfs(progfuncs, ofs)); else - writes(file, "%s", progfuncs->stringtable+def->s_name); + writes(file, "%s", progfuncs->funcs.stringtable+def->s_name); } else writes(file, "%s", VarAtOfs(progfuncs, ofs)); @@ -464,12 +463,12 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int writes(f, ", "); st = (void *)0xffff; - if (!def->s_name[progfuncs->stringtable]) + if (!def->s_name[progfuncs->funcs.stringtable]) { char mem[64]; sprintf(mem, "_p_%i", def->ofs); - def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; - strcpy(def->s_name+progfuncs->stringtable, mem); + def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->funcs.stringtable; + strcpy(def->s_name+progfuncs->funcs.stringtable, mem); } if (current_progstate->types) @@ -478,19 +477,19 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) { case ev_string: - writes(f, "%s %s", "string", progfuncs->stringtable+def->s_name); + writes(f, "%s %s", "string", progfuncs->funcs.stringtable+def->s_name); break; case ev_float: - writes(f, "%s %s", "float", progfuncs->stringtable+def->s_name); + writes(f, "%s %s", "float", progfuncs->funcs.stringtable+def->s_name); break; case ev_entity: - writes(f, "%s %s", "entity", progfuncs->stringtable+def->s_name); + writes(f, "%s %s", "entity", progfuncs->funcs.stringtable+def->s_name); break; case ev_vector: - writes(f, "%s %s", "vector", progfuncs->stringtable+def->s_name); + writes(f, "%s %s", "vector", progfuncs->funcs.stringtable+def->s_name); break; default: - writes(f, "%s %s", "randomtype", progfuncs->stringtable+def->s_name); + writes(f, "%s %s", "randomtype", progfuncs->funcs.stringtable+def->s_name); break; } } @@ -498,23 +497,23 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int for (ofs = progs->functions[num].parm_start+progs->functions[num].numparms, i = progs->functions[num].numparms; i < progs->functions[num].locals; i++, ofs+=1) ofsflags[ofs] |= 4; - if (!progfuncs->stringtable[progs->functions[num].s_name]) + if (!progfuncs->funcs.stringtable[progs->functions[num].s_name]) { char mem[64]; if (!functionname) { sprintf(mem, "_bi_%i", num); - progs->functions[num].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; - strcpy(progs->functions[num].s_name+progfuncs->stringtable, mem); + progs->functions[num].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->funcs.stringtable; + strcpy(progs->functions[num].s_name+progfuncs->funcs.stringtable, mem); } else { - progs->functions[num].s_name = (char*)malloc(strlen(functionname)+1)-progfuncs->stringtable; - strcpy(progs->functions[num].s_name+progfuncs->stringtable, functionname); + progs->functions[num].s_name = (char*)malloc(strlen(functionname)+1)-progfuncs->funcs.stringtable; + strcpy(progs->functions[num].s_name+progfuncs->funcs.stringtable, functionname); } } - writes(f, ") %s", progfuncs->stringtable+progs->functions[num].s_name); + writes(f, ") %s", progfuncs->funcs.stringtable+progs->functions[num].s_name); if (stn < 0) { @@ -579,34 +578,34 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int writes(f, "\tlocal %s %s;\r\n", current_progstate->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, def->s_name); else { - if (!progfuncs->stringtable[def->s_name]) + if (!progfuncs->funcs.stringtable[def->s_name]) { char mem[64]; sprintf(mem, "_l_%i", def->ofs); - def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; - strcpy(def->s_name+progfuncs->stringtable, mem); + def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->funcs.stringtable; + strcpy(def->s_name+progfuncs->funcs.stringtable, mem); } switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) { case ev_string: - writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->funcs.stringtable+def->s_name); break; case ev_float: - writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->funcs.stringtable+def->s_name); break; case ev_entity: - writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->funcs.stringtable+def->s_name); break; case ev_vector: if (v->_vector[0] || v->_vector[1] || v->_vector[2]) - writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); + writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->funcs.stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); else - writes(f, "\tlocal %s %s;\r\n", "vector", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "vector", progfuncs->funcs.stringtable+def->s_name); ofs+=2; //skip floats; break; default: - writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->funcs.stringtable+def->s_name); break; } } @@ -677,7 +676,7 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int } else { - if (!strcmp(progfuncs->stringtable+progs->functions[num].s_name, "SUB_Remove")) + if (!strcmp(progfuncs->funcs.stringtable+progs->functions[num].s_name, "SUB_Remove")) file = 0; file = f; @@ -695,34 +694,34 @@ void WriteAsmStatements(progfuncs_t *progfuncs, progstate_t *progs, int num, int writes(f, "\tlocal %s %s;\r\n", current_progstate->types[def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)].name, def->s_name); else { - if (!def->s_name[progfuncs->stringtable]) + if (!def->s_name[progfuncs->funcs.stringtable]) { char mem[64]; sprintf(mem, "_l_%i", def->ofs); - def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; - strcpy(def->s_name+progfuncs->stringtable, mem); + def->s_name = (char*)malloc(strlen(mem)+1)-progfuncs->funcs.stringtable; + strcpy(def->s_name+progfuncs->funcs.stringtable, mem); } switch(def->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) { case ev_string: - writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "string", progfuncs->funcs.stringtable+def->s_name); break; case ev_float: - writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "float", progfuncs->funcs.stringtable+def->s_name); break; case ev_entity: - writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "entity", progfuncs->funcs.stringtable+def->s_name); break; case ev_vector: if (v->_vector[0] || v->_vector[1] || v->_vector[2]) - writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); + writes(f, "\tlocal vector %s = '%f %f %f';\r\n", progfuncs->funcs.stringtable+def->s_name, v->_vector[0], v->_vector[1], v->_vector[2]); else - writes(f, "\tlocal %s %s;\r\n", "vector",progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "vector",progfuncs->funcs.stringtable+def->s_name); ofs+=2; //skip floats; break; default: - writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->stringtable+def->s_name); + writes(f, "\tlocal %s %s;\r\n", "randomtype", progfuncs->funcs.stringtable+def->s_name); break; } } @@ -848,8 +847,9 @@ void FigureOutTypes(progfuncs_t *progfuncs) } } -pbool Decompile(progfuncs_t *progfuncs, char *fname) +pbool PDECL QC_Decompile(pubprogfuncs_t *ppf, char *fname) { + progfuncs_t *progfuncs = (progfuncs_t*)ppf; extern progfuncs_t *qccprogfuncs; unsigned int i; unsigned int fld=0; @@ -875,7 +875,7 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) for (i = 1; i < progs.progs->numglobaldefs; i++) { - if (!strcmp(progfuncs->stringtable+pr_globaldefs16[i].s_name, "IMMEDIATE")) + if (!strcmp(progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name, "IMMEDIATE")) continue; if (ofsflags[pr_globaldefs16[i].ofs] & 4) @@ -887,7 +887,7 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) type = pr_globaldefs16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); v = (eval_t *)&((int *)progs.globals)[pr_globaldefs16[i].ofs]; - if (!progfuncs->stringtable[pr_globaldefs16[i].s_name]) + if (!progfuncs->funcs.stringtable[pr_globaldefs16[i].s_name]) { char mem[64]; if (ofsflags[pr_globaldefs16[i].ofs] & 3) @@ -897,36 +897,36 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) } sprintf(mem, "_g_%i", pr_globaldefs16[i].ofs); - pr_globaldefs16[i].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->stringtable; - strcpy(pr_globaldefs16[i].s_name+progfuncs->stringtable, mem); + pr_globaldefs16[i].s_name = (char*)malloc(strlen(mem)+1)-progfuncs->funcs.stringtable; + strcpy(pr_globaldefs16[i].s_name+progfuncs->funcs.stringtable, mem); } switch(type) { case ev_void: - writes(f, "void %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "void %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_string: if (v->string && *(pr_strings+v->_int)) - writes(f, "string %s = \"%s\";\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, pr_strings+v->_int); + writes(f, "string %s = \"%s\";\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name, pr_strings+v->_int); else - writes(f, "string %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "string %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_float: if (v->_float) - writes(f, "float %s = %f;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, v->_float); + writes(f, "float %s = %f;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name, v->_float); else - writes(f, "float %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "float %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_vector: if (v->_vector[0] || v->_vector[1] || v->_vector[2]) - writes(f, "vector %s = '%f %f %f';\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name, v->_vector[0], v->_vector[1], v->_vector[2]); + writes(f, "vector %s = '%f %f %f';\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name, v->_vector[0], v->_vector[1], v->_vector[2]); else - writes(f, "vector %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "vector %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); i+=3;//skip the floats break; case ev_entity: - writes(f, "entity %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "entity %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_field: //wierd @@ -936,27 +936,27 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) switch(pr_fielddefs16[fld].type) { case ev_string: - writes(f, ".string %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, ".string %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_float: - writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, ".float %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_vector: - writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, ".float %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_entity: - writes(f, ".float %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, ".float %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_function: - writes(f, ".void() %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, ".void() %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; default: - writes(f, "field %s;", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "field %s;", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; } if (v->_int) @@ -966,21 +966,21 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) case ev_function: //wierd - WriteAsmStatements(progfuncs, &progs, ((int *)progs.globals)[pr_globaldefs16[i].ofs], f, pr_globaldefs16[i].s_name+progfuncs->stringtable); + WriteAsmStatements(progfuncs, &progs, ((int *)progs.globals)[pr_globaldefs16[i].ofs], f, pr_globaldefs16[i].s_name+progfuncs->funcs.stringtable); break; case ev_pointer: - writes(f, "pointer %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "pointer %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_integer: - writes(f, "integer %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "integer %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_union: - writes(f, "union %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "union %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; case ev_struct: - writes(f, "struct %s;\r\n", progfuncs->stringtable+pr_globaldefs16[i].s_name); + writes(f, "struct %s;\r\n", progfuncs->funcs.stringtable+pr_globaldefs16[i].s_name); break; default: break; diff --git a/engine/qclib/test.c b/engine/qclib/test.c index 8875d2eb..97973009 100644 --- a/engine/qclib/test.c +++ b/engine/qclib/test.c @@ -18,7 +18,7 @@ //builtins and builtin management. -void PF_prints (progfuncs_t *prinst, struct globalvars_s *gvars) +void PF_prints (pubprogfuncs_t *prinst, struct globalvars_s *gvars) { char *s; s = prinst->VarString(prinst, 0); @@ -26,18 +26,18 @@ void PF_prints (progfuncs_t *prinst, struct globalvars_s *gvars) printf("%s", s); } -void PF_printv (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_printv (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { printf("%f %f %f\n", G_FLOAT(OFS_PARM0+0), G_FLOAT(OFS_PARM0+1), G_FLOAT(OFS_PARM0+2)); } -void PF_printf (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_printf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { printf("%f\n", G_FLOAT(OFS_PARM0)); } -void PF_bad (progfuncs_t *prinst, struct globalvars_s *gvars) +void PF_bad (pubprogfuncs_t *prinst, struct globalvars_s *gvars) { printf("bad builtin\n"); } @@ -118,7 +118,7 @@ pbool Sys_WriteFile (char *fname, void *data, int len) void runtest(char *progsname) { - progfuncs_t *pf; + pubprogfuncs_t *pf; func_t func; progsnum_t pn; @@ -129,7 +129,7 @@ void runtest(char *progsname) ext.ReadFile = Sys_ReadFile; ext.FileSize= Sys_FileSize; ext.Abort = Sys_Abort; - ext.printf = printf; + ext.Printf = printf; ext.numglobalbuiltins = sizeof(builtins)/sizeof(builtins[0]); ext.globalbuiltins = builtins; @@ -155,7 +155,7 @@ void runtest(char *progsname) else pf->ExecuteProgram(pf, func); //call the function } - CloseProgs(pf); + pf->CloseProgs(pf); } @@ -163,7 +163,7 @@ void runtest(char *progsname) //Note that this could be done with an autocompile of PR_COMPILEALWAYS. void compile(int argc, char **argv) { - progfuncs_t *pf; + pubprogfuncs_t *pf; progparms_t ext; @@ -190,7 +190,7 @@ void compile(int argc, char **argv) ext.FileSize= Sys_FileSize; ext.WriteFile= Sys_WriteFile; ext.Abort = Sys_Abort; - ext.printf = printf; + ext.Printf = printf; pf = InitProgs(&ext); if (pf->StartCompile) @@ -203,7 +203,7 @@ void compile(int argc, char **argv) } else printf("no compiler in this qcvm build\n"); - CloseProgs(pf); + pf->CloseProgs(pf); } int main(int argc, char **argv) diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index caa9c028..268cf319 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -177,6 +177,8 @@ static void pp_identity_flush(client_t *cl, sizebuf_t *msg, enum protocol_type * MSG_WriteByte(msg, pd[i].id); break; case PPT_ENT: + MSG_WriteEntity(msg, pd[i].id); + break; case PPT_SHORT: MSG_WriteShort(msg, pd[i].id); break; @@ -304,7 +306,7 @@ void NPP_NQWriteEntity(int dest, short data) { union protocol_data pd; pd.id = (unsigned short)data; - pp_entry(dest, PPT_COORD, pd); + pp_entry(dest, PPT_ENTITY, pd); } void NPP_QWWriteByte(int dest, qbyte data) @@ -355,7 +357,7 @@ static void pp_svc_temp_entity_beam_flush(client_t *cl, sizebuf_t *msg, enum pro { MSG_WriteByte(msg, pd[0].id); MSG_WriteByte(msg, pd[1].id); - MSG_WriteShort(msg, pd[2].id); + MSG_WriteEntity(msg, pd[2].id); MSG_WriteCoord(msg, pd[3].fd); MSG_WriteCoord(msg, pd[4].fd); MSG_WriteCoord(msg, pd[5].fd); @@ -607,7 +609,7 @@ void NPP_SetInfo(client_t *cl, char *key, char *value) if (!*Info_ValueForKey (cl->userinfo, "name")) cl->name[0] = '\0'; else // process any changed values - SV_ExtractFromUserinfo (cl); + SV_ExtractFromUserinfo (cl, false); i = cl - svs.clients; MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); @@ -996,7 +998,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) switch(data) { case TENQ_BEAM: - data = TE_LIGHTNING1; //QW doesn't do te_beam. Replace with lightning1. + data = TEQW_BEAM; //QW doesn't do te_beam. Replace with lightning1. //fallthrough case TE_LIGHTNING1: case TE_LIGHTNING2: @@ -1035,6 +1037,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) ignoreprotocol = true; break; case TENQ_EXPLOSION2: + data = TEQW_EXPLOSION2; protocollen = sizeof(qbyte)*4 + destprim->coordsize*3; multicastpos=2; multicasttype=MULTICAST_PHS_R; @@ -1362,13 +1365,13 @@ void NPP_NQWriteEntity(int dest, short data) //replacement write func (nq to qw) else if (!ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(short)); - ClientReliableWrite_Short(cl, data); + ClientReliableWrite_Entity(cl, data); return; } } } else - MSG_WriteShort (NQWriteDest(dest), data); + MSG_WriteEntity (NQWriteDest(dest), data); #endif NPP_AddData(&data, sizeof(short)); @@ -1503,7 +1506,7 @@ void NPP_QWFlush(void) { Q_strncpyz(svs.clients[j].userinfo, (buffer+6), sizeof(svs.clients[j].userinfo)); if (*Info_ValueForKey(svs.clients[j].userinfo, "name")) - SV_ExtractFromUserinfo(&svs.clients[j]); + SV_ExtractFromUserinfo(&svs.clients[j], false); else *svs.clients[j].name = '\0'; } @@ -1874,9 +1877,14 @@ void NPP_QWWriteShort(int dest, short data) //replacement write func (nq to qw) qbyte b[2]; short s; } u; - u.s = LittleShort(data); - NPP_QWWriteByte(dest, u.b[0]); - NPP_QWWriteByte(dest, u.b[1]); + if (bufferlen == 2 && majortype == svc_temp_entity) + NPP_QWWriteEntity(dest, data); + else + { + u.s = LittleShort(data); + NPP_QWWriteByte(dest, u.b[0]); + NPP_QWWriteByte(dest, u.b[1]); + } } void NPP_QWWriteFloat(int dest, float data) //replacement write func (nq to qw) @@ -1978,17 +1986,18 @@ void NPP_QWWriteString(int dest, char *data) //replacement write func (nq to qw) } void NPP_QWWriteEntity(int dest, short data) //replacement write func (nq to qw) { - union { - qbyte b[2]; - short s; - } u; - u.s = LittleShort(data); - NPP_QWWriteByte(dest, u.b[0]); - NPP_QWWriteByte(dest, u.b[1]); + if (data >= 0x8000) + { + NPP_QWWriteByte(dest, ((data>> 0) & 0xff)); + NPP_QWWriteByte(dest, ((data>> 8) & 0x7f) | 0x80); + NPP_QWWriteByte(dest, ((data>>15) & 0xff)); + } + else + { + NPP_QWWriteByte(dest, (data>>0) & 0xff); + NPP_QWWriteByte(dest, (data>>8) & 0x7f); + } } - - - #endif diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 3da8d44b..cb87564a 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -36,14 +36,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PF_sqlreadfloat PF_Fixme #endif -#define Z_QC_TAG 2 - #ifndef CLIENTONLY #include "pr_common.h" //okay, so these are a quick but easy hack -void ED_Print (struct progfuncs_s *progfuncs, struct edict_s *ed); int PR_EnableEBFSBuiltin(char *name, int binum); int PR_CSQC_BuiltinValid(char *name, int num); @@ -61,20 +58,20 @@ cvar_t saved3 = CVARF("saved3", "0", CVAR_ARCHIVE); cvar_t saved4 = CVARF("saved4", "0", CVAR_ARCHIVE); cvar_t temp1 = CVARF("temp1", "0", CVAR_ARCHIVE); cvar_t noexit = CVAR("noexit", "0"); -cvar_t pr_ssqc_memsize = CVAR("pr_ssqc_memsize", "-1"); +cvar_t pr_ssqc_memsize = CVARD("pr_ssqc_memsize", "-1", "The ammount of memory available to the QC vm. This has a theoretical maximum of 1gb, but that value can only really be used in 64bit builds. -1 will attempt to use some conservative default, but you may need to increase it. Consider also clearing pr_fixbrokenqccarrays if you need to change this cvar."); /*cvars purely for compat with others*/ -cvar_t dpcompat_trailparticles = CVAR("dpcompat_trailparticles", "0"); -cvar_t pr_imitatemvdsv = CVARF("pr_imitatemvdsv", "0", CVAR_LATCH); +cvar_t dpcompat_trailparticles = CVARD("dpcompat_trailparticles", "0", "Swaps the parameter order of the trailparticles builtin so that mods that target DP only can still run."); +cvar_t pr_imitatemvdsv = CVARFD("pr_imitatemvdsv", "0", CVAR_LATCH, "Enables mvdsv-specific builtins, and fakes identifiers so that mods made for mvdsv can run properly and with the full feature set."); /*compat with frikqcc's arrays (ensures that unknown fields are at the same offsets*/ -cvar_t pr_fixbrokenqccarrays = CVARF("pr_fixbrokenqccarrays", "1", CVAR_LATCH); +cvar_t pr_fixbrokenqccarrays = CVARFD("pr_fixbrokenqccarrays", "1", CVAR_LATCH, "When set, ensures that fields are not relocated unless remapped, working around stripped/immediate field offsets. This results in higher memory usage."); /*other stuff*/ -cvar_t pr_maxedicts = CVARAF("pr_maxedicts", "8192", "max_edicts", CVAR_LATCH); +cvar_t pr_maxedicts = CVARAFD("pr_maxedicts", "8192", "max_edicts", CVAR_LATCH, "Maximum number of entities spawnable on the map at once. Low values will crash the server on some maps/mods. High values will result in excessive memory useage (see pr_ssqc_memsize). Illegible server messages may occur with old/other clients above 32k. FTE's network protocols have a maximum at a little over 4 million. Please don't ever make a mod that actually uses that many..."); -cvar_t pr_no_playerphysics = CVARF("pr_no_playerphysics", "0", CVAR_LATCH); -cvar_t pr_no_parsecommand = CVARF("pr_no_parsecommand", "0", 0); +cvar_t pr_no_playerphysics = CVARFD("pr_no_playerphysics", "0", CVAR_LATCH, "Prevents support of the 'SV_PlayerPhysics' QC function. This allows servers to prevent needless breakage of player prediction."); +cvar_t pr_no_parsecommand = CVARFD("pr_no_parsecommand", "0", 0, "Provides a way around invalid mod usage of SV_ParseClientCommand, eg xonotic."); cvar_t pr_ssqc_progs = CVARAF("progs", "", "sv_progs", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER); cvar_t qc_nonetaccess = CVAR("qc_nonetaccess", "0"); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc. @@ -82,16 +79,16 @@ cvar_t qc_netpreparse = CVAR("qc_netpreparse", "1"); //server-side writebyte pro cvar_t pr_overridebuiltins = CVAR("pr_overridebuiltins", "1"); -cvar_t pr_compatabilitytest = CVARF("pr_compatabilitytest", "0", CVAR_LATCH); +cvar_t pr_compatabilitytest = CVARFD("pr_compatabilitytest", "0", CVAR_LATCH, "Only enables builtins if the extension they are part of was queried."); cvar_t pr_ssqc_coreonerror = CVAR("pr_coreonerror", "1"); cvar_t pr_droptofloorunits = CVAR("pr_droptofloorunits", ""); cvar_t sv_gameplayfix_honest_tracelines = CVAR("sv_gameplayfix_honest_tracelines", "1"); -cvar_t sv_gameplayfix_blowupfallenzombies = CVAR("sv_gameplayfix_blowupfallenzombies", "0"); -cvar_t sv_gameplayfix_setmodelrealbox = CVAR("sv_gameplayfix_setmodelrealbox", "0"); -cvar_t sv_gameplayfix_setmodelsize_qw = CVAR("sv_gameplayfix_setmodelsize_qw", "0"); +cvar_t sv_gameplayfix_blowupfallenzombies = CVARD("sv_gameplayfix_blowupfallenzombies", "0", "Allow findradius to find non-solid entities. This may break certain mods."); +cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "0", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model."); +cvar_t sv_gameplayfix_setmodelsize_qw = CVARD("sv_gameplayfix_setmodelsize_qw", "0", "The setmodel builtin will act as a setsize for QuakeWorld mods also."); cvar_t sv_addon[MAXADDONS]; char cvargroup_progs[] = "Progs variables"; @@ -102,8 +99,8 @@ int pr_teamfield; unsigned int h2infoplaque[2]; /*hexen2 stat*/ static void PRSV_ClearThreads(void); -void PR_fclose_progs(progfuncs_t*); -void PF_InitTempStrings(progfuncs_t *prinst); +void PR_fclose_progs(pubprogfuncs_t*); +void PF_InitTempStrings(pubprogfuncs_t *prinst); void PR_DumpPlatform_f(void); @@ -142,6 +139,7 @@ struct { func_t RunClientCommand; //EXT_CSQC_1 func_t ClassChangeWeapon;//hexen2 support + func_t AddDebugPolygons; } gfuncs; func_t SpectatorConnect; //QW func_t SpectatorThink; //QW @@ -155,7 +153,7 @@ qboolean pr_items2; //hipnotic (or was it rogue?) globalptrs_t realpr_global_ptrs; globalptrs_t *pr_global_ptrs = &realpr_global_ptrs; -progfuncs_t *svprogfuncs; +pubprogfuncs_t *svprogfuncs; progparms_t svprogparms; progstype_t progstype; @@ -168,7 +166,7 @@ char *QC_ProgsNameForEnt(edict_t *ent) return "?"; } -void ED_Spawned (struct edict_s *ent, int loading) +void PDECL ED_Spawned (struct edict_s *ent, int loading) { #ifdef VM_Q1 if (!ent->xv) @@ -188,7 +186,7 @@ void ED_Spawned (struct edict_s *ent, int loading) } } -pbool ED_CanFree (edict_t *ed) +pbool PDECL ED_CanFree (edict_t *ed) { if (ed == (edict_t*)sv.world.edicts) { @@ -196,7 +194,7 @@ pbool ED_CanFree (edict_t *ed) { Con_TPrintf(STL_CANTFREEWORLD); PR_StackTrace(svprogfuncs); - *svprogfuncs->pr_trace = 1; + svprogfuncs->pr_trace = 1; } return false; } @@ -204,7 +202,7 @@ pbool ED_CanFree (edict_t *ed) { Con_TPrintf(STL_CANTFREEPLAYERS); PR_StackTrace(svprogfuncs); - *svprogfuncs->pr_trace = 1; + svprogfuncs->pr_trace = 1; return false; } World_UnlinkEdict ((wedict_t*)ed); // unlink from world bsp @@ -247,7 +245,7 @@ pbool ED_CanFree (edict_t *ed) return true; } -void ASMCALL StateOp (progfuncs_t *prinst, float var, func_t func) +void ASMCALL StateOp (pubprogfuncs_t *prinst, float var, func_t func) { stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v; if (progstype == PROG_H2) @@ -257,7 +255,7 @@ void ASMCALL StateOp (progfuncs_t *prinst, float var, func_t func) vars->think = func; vars->frame = var; } -void ASMCALL CStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc) +void ASMCALL CStateOp (pubprogfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc) { stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v; @@ -293,7 +291,7 @@ void ASMCALL CStateOp (progfuncs_t *prinst, float startFrame, float endFrame, fu vars->frame = startFrame; } } -void ASMCALL CWStateOp (progfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc) +void ASMCALL CWStateOp (pubprogfuncs_t *prinst, float startFrame, float endFrame, func_t currentfunc) { stdentvars_t *vars = PROG_TO_EDICT(prinst, pr_global_struct->self)->v; @@ -330,13 +328,13 @@ void ASMCALL CWStateOp (progfuncs_t *prinst, float startFrame, float endFrame, f } } -void ASMCALL ThinkTimeOp (progfuncs_t *prinst, edict_t *ed, float var) +void ASMCALL ThinkTimeOp (pubprogfuncs_t *prinst, edict_t *ed, float var) { stdentvars_t *vars = ed->v; vars->nextthink = pr_global_struct->time+var; } -pbool SV_BadField(progfuncs_t *inst, edict_t *foo, const char *keyname, const char *value) +pbool PDECL SV_BadField(pubprogfuncs_t *inst, edict_t *foo, const char *keyname, const char *value) { /*Worldspawn only fields...*/ if (NUM_FOR_EDICT(inst, foo) == 0) @@ -368,7 +366,7 @@ void PR_SV_FillWorldGlobals(world_t *w) w->g.v_up = *pr_global_ptrs->v_up; } -void PR_SSQC_Relocated(progfuncs_t *pr, char *oldb, char *newb, int oldlen) +void PDECL PR_SSQC_Relocated(pubprogfuncs_t *pr, char *oldb, char *newb, int oldlen) { edict_t *ent; int i; @@ -412,8 +410,8 @@ void QC_Clear(void); builtin_t pr_builtin[]; extern int pr_numbuiltins; -int QCLibEditor(progfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); -int QCEditor (progfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms) +int QCLibEditor(pubprogfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms); +int QDECL QCEditor (pubprogfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms) { #ifdef TEXTEDITOR static char oldfuncname[64]; @@ -529,7 +527,7 @@ void Q_SetProgsParms(qboolean forcompiler) svprogparms.ReadFile = COM_LoadStackFile;//char *(*ReadFile) (char *fname, void *buffer, int *len); svprogparms.FileSize = COM_FileSize;//int (*FileSize) (char *fname); //-1 if file does not exist svprogparms.WriteFile = QC_WriteFile;//bool (*WriteFile) (char *name, void *data, int len); - svprogparms.printf = (void *)Con_Printf;//Con_Printf;//void (*printf) (char *, ...); + svprogparms.Printf = PR_Printf;//Con_Printf;//void (*printf) (char *, ...); svprogparms.Sys_Error = Sys_Error; svprogparms.Abort = SV_Error; svprogparms.edictsize = sizeof(edict_t); @@ -587,18 +585,14 @@ void Q_SetProgsParms(qboolean forcompiler) void PR_Deinit(void) { int i; -#ifdef USEODE - World_ODE_End(&sv.world); -#endif PRSV_ClearThreads(); if (svprogfuncs) { - PR_fclose_progs(svprogfuncs); + PR_Common_Shutdown(svprogfuncs, false); if (svprogfuncs->parms) - CloseProgs(svprogfuncs); - - Z_FreeTags(Z_QC_TAG); + svprogfuncs->CloseProgs(svprogfuncs); + svprogfuncs=NULL; for (i = 0; i < MAX_LIGHTSTYLES; i++) { @@ -607,15 +601,14 @@ void PR_Deinit(void) } } +#ifdef USEODE + World_ODE_End(&sv.world); +#endif + #ifdef SQL SQL_KillServers(); #endif -#ifdef TEXTEDITOR - Editor_ProgsKilled(svprogfuncs); -#endif - svprogfuncs=NULL; - //clear out function pointers (so changing game modes cannot lead to confusions) memset(&gfuncs, 0, sizeof(gfuncs)); SpectatorConnect = 0; @@ -803,6 +796,7 @@ void PR_LoadGlabalStruct(void) gfuncs.ShouldPause = PR_FindFunction(svprogfuncs, "SV_ShouldPause", PR_ANY); gfuncs.ClassChangeWeapon = PR_FindFunction(svprogfuncs, "ClassChangeWeapon", PR_ANY); gfuncs.RunClientCommand = PR_FindFunction(svprogfuncs, "SV_RunClientCommand", PR_ANY); + gfuncs.AddDebugPolygons = PR_FindFunction(svprogfuncs, "SV_AddDebugPolygons", PR_ANY); if (pr_no_playerphysics.ival) SV_PlayerPhysicsQC = 0; @@ -811,9 +805,9 @@ void PR_LoadGlabalStruct(void) EndFrameQC = PR_FindFunction (svprogfuncs, "EndFrame", PR_ANY); v = (int *)PR_globals(svprogfuncs, PR_CURRENT); - QC_AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->self-v, 1); - QC_AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->other-v, 1); - QC_AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->time-v, 1); + svprogfuncs->AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->self-v, 1); + svprogfuncs->AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->other-v, 1); + svprogfuncs->AddSharedVar(svprogfuncs, (int *)(pr_global_ptrs)->time-v, 1); pr_items2 = !!PR_FindGlobal(svprogfuncs, "items2", 0, NULL); @@ -2130,7 +2124,7 @@ static int SV_CustomTEnt_Spawn(int index, float *org, float *org2, int count, fl int externcallsdepth; float PR_LoadAditionalProgs(char *s); -static void QCBUILTIN PF_addprogs(progfuncs_t *prinst, globalvars_t *pr_globals) +static void QCBUILTIN PF_addprogs(pubprogfuncs_t *prinst, globalvars_t *pr_globals) { char *s = PR_GetStringOfs(prinst, OFS_PARM0); if (!s || !*s) @@ -2171,7 +2165,7 @@ removed, but the level can continue. objerror(value) ================= */ -static void QCBUILTIN PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_objerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; edict_t *ed; @@ -2181,18 +2175,18 @@ static void QCBUILTIN PF_objerror (progfuncs_t *prinst, struct globalvars_s *pr_ */ ed = PROG_TO_EDICT(prinst, pr_global_struct->self); /* ED_Print (ed); */ - ED_Print(prinst, ed); + prinst->ED_Print(prinst, ed); Con_Printf("%s", s); if (developer.value) - (*prinst->pr_trace) = 2; + prinst->pr_trace = 2; else { Con_Printf("Program error: %s\n", s); if (developer.value) { struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT); - *prinst->pr_trace = 1; + prinst->pr_trace = 1; G_INT(OFS_RETURN)=0; //just in case it was a float and should be an ent... G_INT(OFS_RETURN+1)=0; G_INT(OFS_RETURN+2)=0; @@ -2219,7 +2213,7 @@ Writes new values for v_forward, v_up, and v_right based on angles makevectors(vector) ============== */ -static void QCBUILTIN PF_makevectors (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_makevectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { AngleVectors (G_VECTOR(OFS_PARM0), P_VEC(v_forward), P_VEC(v_right), P_VEC(v_up)); } @@ -2233,7 +2227,7 @@ This is the only valid way to move an object without using the physics of the wo setorigin (entity, origin) ================= */ -static void QCBUILTIN PF_setorigin (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_setorigin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e; float *org; @@ -2254,7 +2248,7 @@ the size box is rotated by the current angle setsize (entity, minvector, maxvector) ================= */ -static void QCBUILTIN PF_setsize (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_setsize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e; float *min, *max; @@ -2265,7 +2259,7 @@ static void QCBUILTIN PF_setsize (progfuncs_t *prinst, struct globalvars_s *pr_g if (progstype != PROG_H2) { Con_TPrintf(STL_EDICTWASFREE, "setsize"); - (*prinst->pr_trace) = 1; + prinst->pr_trace = 1; } return; } @@ -2286,7 +2280,7 @@ setmodel(entity, model) Also sets size, mins, and maxs for inline bmodels ================= */ -void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) +void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, char *m) { int i; model_t *mod; @@ -2425,7 +2419,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) } } -static void QCBUILTIN PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_setmodel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e; char *m; @@ -2436,7 +2430,7 @@ static void QCBUILTIN PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_ PF_setmodel_Internal(prinst, e, m); } -static void QCBUILTIN PF_h2set_puzzle_model (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2set_puzzle_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //qc/hc lacks string manipulation. edict_t *e; char *shortname; @@ -2457,7 +2451,7 @@ broadcast print to everyone on server bprint(value) ================= */ -static void QCBUILTIN PF_bprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_bprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; int level; @@ -2491,7 +2485,7 @@ single print to a specific client sprint(clientent, value) ================= */ -static void QCBUILTIN PF_sprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; client_t *client; @@ -2531,7 +2525,7 @@ static void QCBUILTIN PF_sprint (progfuncs_t *prinst, struct globalvars_s *pr_gl //When a client is backbuffered, it's generally not a brilliant plan to send a bazillion stuffcmds. You have been warned. //This handy function will let the mod know when it shouldn't send more. (use instead of a timer, and you'll never get clients overflowing. yay.) -static void QCBUILTIN PF_isbackbuffered (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_isbackbuffered (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum; client_t *client; @@ -2593,7 +2587,7 @@ void PF_centerprint_Internal (int entnum, qboolean plaque, char *s) } } -static void QCBUILTIN PF_centerprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_centerprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; int entnum; @@ -2610,7 +2604,7 @@ PF_vhlen scalar vhlen(vector) ================= */ -static void QCBUILTIN PF_vhlen (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_vhlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1; float newv; @@ -2623,7 +2617,7 @@ static void QCBUILTIN PF_vhlen (progfuncs_t *prinst, struct globalvars_s *pr_glo G_FLOAT(OFS_RETURN) = newv; } -static void QCBUILTIN PF_anglemod (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float v = G_FLOAT(OFS_PARM0); @@ -2642,7 +2636,7 @@ PF_particle particle(origin, color, count) ================= */ -static void QCBUILTIN PF_particle (progfuncs_t *prinst, globalvars_t *pr_globals) //I said it was for compatability only. +static void QCBUILTIN PF_particle (pubprogfuncs_t *prinst, globalvars_t *pr_globals) //I said it was for compatability only. { float *org, *dir; float color; @@ -2723,7 +2717,7 @@ static void QCBUILTIN PF_particle (progfuncs_t *prinst, globalvars_t *pr_globals SV_MulticastProtExt(org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0); } -static void QCBUILTIN PF_te_blooddp (progfuncs_t *prinst, globalvars_t *pr_globals) +static void QCBUILTIN PF_te_blooddp (pubprogfuncs_t *prinst, globalvars_t *pr_globals) { float count; float *org, *dir; @@ -2768,7 +2762,7 @@ PF_particle2 - hexen2 particle(origin, dmin, dmax, color, effect, count) ================= */ -static void QCBUILTIN PF_particle2 (progfuncs_t *prinst, globalvars_t *pr_globals) +static void QCBUILTIN PF_particle2 (pubprogfuncs_t *prinst, globalvars_t *pr_globals) { float *org, *dmin, *dmax; float color; @@ -2808,7 +2802,7 @@ PF_particle3 - hexen2 particle(origin, box, color, effect, count) ================= */ -static void QCBUILTIN PF_particle3 (progfuncs_t *prinst, globalvars_t *pr_globals) +static void QCBUILTIN PF_particle3 (pubprogfuncs_t *prinst, globalvars_t *pr_globals) { float *org, *box; float color; @@ -2843,7 +2837,7 @@ PF_particle4 - hexen2 particle(origin, radius, color, effect, count) ================= */ -static void QCBUILTIN PF_particle4 (progfuncs_t *prinst, globalvars_t *pr_globals) +static void QCBUILTIN PF_particle4 (pubprogfuncs_t *prinst, globalvars_t *pr_globals) { float *org; float radius; @@ -2870,7 +2864,7 @@ static void QCBUILTIN PF_particle4 (progfuncs_t *prinst, globalvars_t *pr_global SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_HEXEN2, 0); } -static void QCBUILTIN PF_h2particleexplosion(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2particleexplosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org; int color,radius,counter; @@ -2930,7 +2924,7 @@ void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuat SV_Multicast(pos, MULTICAST_ALL_R); } -static void QCBUILTIN PF_ambientsound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ambientsound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *samp; float *pos; @@ -2960,7 +2954,7 @@ pitchadj is a percent. values greater than 100 will result in a lower pitch, les ================= */ -static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *sample; int channel; @@ -2975,11 +2969,11 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo sample = PR_GetStringOfs(prinst, OFS_PARM2); volume = G_FLOAT(OFS_PARM3) * 255; attenuation = G_FLOAT(OFS_PARM4); - if (*svprogfuncs->callargc > 5) + if (svprogfuncs->callargc > 5) pitchadj = G_FLOAT(OFS_PARM5); else pitchadj = 0; - if (*svprogfuncs->callargc > 6) + if (svprogfuncs->callargc > 6) { flags = G_FLOAT(OFS_PARM5); if (channel < 0) @@ -3002,7 +2996,7 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo } //an evil one from telejano. -static void QCBUILTIN PF_LocalSound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_LocalSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifndef SERVERONLY sfx_t *sfx; @@ -3055,7 +3049,7 @@ if the tryents flag is set. traceline (vector1, vector2, tryents) ================= */ -void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_svtraceline (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *v1, *v2, *mins, *maxs; trace_t trace; @@ -3066,7 +3060,7 @@ void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_glob v1 = G_VECTOR(OFS_PARM0); v2 = G_VECTOR(OFS_PARM1); nomonsters = G_FLOAT(OFS_PARM2); - if (*svprogfuncs->callargc == 3) // QTEST + if (svprogfuncs->callargc == 3) // QTEST ent = PROG_TO_EDICT(prinst, pr_global_struct->self); else ent = G_EDICT(prinst, OFS_PARM3); @@ -3074,7 +3068,7 @@ void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_glob if (sv_antilag.ival == 2) nomonsters |= MOVE_LAGGED; - if (*svprogfuncs->callargc == 6) + if (svprogfuncs->callargc == 6) { mins = G_VECTOR(OFS_PARM4); maxs = G_VECTOR(OFS_PARM5); @@ -3093,7 +3087,7 @@ void QCBUILTIN PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_glob set_trace_globals(&trace, pr_globals); } -static void QCBUILTIN PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_traceboxh2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *v1, *v2, *mins, *maxs; trace_t trace; @@ -3116,7 +3110,7 @@ static void QCBUILTIN PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *p set_trace_globals(&trace, pr_globals); } -static void QCBUILTIN PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_traceboxdp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *v1, *v2, *mins, *maxs; trace_t trace; @@ -3139,7 +3133,7 @@ static void QCBUILTIN PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *p set_trace_globals(&trace, pr_globals); } -static void QCBUILTIN PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_TraceToss (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { trace_t trace; edict_t *ent; @@ -3160,7 +3154,7 @@ static void QCBUILTIN PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr qbyte checkpvsbuffer[MAX_MAP_LEAFS/8]; qbyte *checkpvs; -int PF_newcheckclient (progfuncs_t *prinst, int check) +int PF_newcheckclient (pubprogfuncs_t *prinst, int check) { int i; // qbyte *pvs; @@ -3226,7 +3220,7 @@ name checkclient () */ #define MAX_CHECK 16 int c_invis, c_notvis; -int PF_checkclient_Internal (progfuncs_t *prinst) +int PF_checkclient_Internal (pubprogfuncs_t *prinst) { edict_t *ent, *self; int l; @@ -3262,7 +3256,7 @@ c_invis++; return w->lastcheck; } -static void QCBUILTIN PF_checkclient (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_checkclient (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { RETURN_EDICT(prinst, EDICT_NUM(prinst, PF_checkclient_Internal(prinst))); } @@ -3279,7 +3273,7 @@ Sends text over to the client's execution buffer stuffcmd (clientent, value) ================= */ -static void QCBUILTIN PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_stuffcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum; char *str; @@ -3372,7 +3366,7 @@ static void QCBUILTIN PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_ } //DP_QC_DROPCLIENT -static void QCBUILTIN PF_dropclient (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_dropclient (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum; client_t *cl; @@ -3397,7 +3391,7 @@ static void QCBUILTIN PF_dropclient (progfuncs_t *prinst, struct globalvars_s *p //DP_SV_BOTCLIENT //entity() spawnclient = #454; -static void QCBUILTIN PF_spawnclient (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_spawnclient (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; for (i = 0; i < sv.allocated_client_slots; i++) @@ -3406,6 +3400,7 @@ static void QCBUILTIN PF_spawnclient (progfuncs_t *prinst, struct globalvars_s * { svs.clients[i].protocol = SCP_BAD; //marker for bots svs.clients[i].state = cs_spawned; + sv.spawned_client_slots++; svs.clients[i].netchan.message.allowoverflow = true; svs.clients[i].netchan.message.maxsize = 0; svs.clients[i].datagram.allowoverflow = true; @@ -3422,24 +3417,24 @@ static void QCBUILTIN PF_spawnclient (progfuncs_t *prinst, struct globalvars_s * //DP_SV_BOTCLIENT //float(entity client) clienttype = #455; -static void QCBUILTIN PF_clienttype (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_clienttype (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int entnum = G_EDICTNUM(prinst, OFS_PARM0); if (entnum < 1 || entnum > sv.allocated_client_slots) { - G_FLOAT(OFS_RETURN) = 3; //not a client slot + G_FLOAT(OFS_RETURN) = CLIENTTYPE_NOTACLIENT; //not a client slot return; } entnum--; if (svs.clients[entnum].state < cs_connected) { - G_FLOAT(OFS_RETURN) = 0; //disconnected + G_FLOAT(OFS_RETURN) = CLIENTTYPE_DISCONNECTED; //disconnected return; } if (svs.clients[entnum].protocol == SCP_BAD) - G_FLOAT(OFS_RETURN) = 2; //an active, bot client. + G_FLOAT(OFS_RETURN) = CLIENTTYPE_BOT; //an active, bot client. else - G_FLOAT(OFS_RETURN) = 1; //an active, not-bot client. + G_FLOAT(OFS_RETURN) = CLIENTTYPE_REAL; //an active, not-bot client. } /* @@ -3449,7 +3444,7 @@ PF_cvar float cvar (string) ================= */ -static void QCBUILTIN PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str; @@ -3484,7 +3479,7 @@ static void QCBUILTIN PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_glob } } -static void QCBUILTIN PF_sv_getlight (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_getlight (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { /*not shared with client - clients get more lights*/ float *point = G_VECTOR(OFS_PARM0); @@ -3512,7 +3507,7 @@ Returns a chain of entities that have origins within a spherical area findradius (origin, radius) ================= */ -static void QCBUILTIN PF_findradius (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent, *chain; float rad; @@ -3550,12 +3545,12 @@ static void QCBUILTIN PF_findradius (progfuncs_t *prinst, struct globalvars_s *p PF_conprint ========= */ -static void QCBUILTIN PF_conprint (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_conprint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Sys_Printf ("%s",PF_VarString(prinst, 0, pr_globals)); } -static void QCBUILTIN PF_h2dprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2dprintf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char temp[256]; char printable[2048]; @@ -3580,7 +3575,7 @@ static void QCBUILTIN PF_h2dprintf (progfuncs_t *prinst, struct globalvars_s *pr Con_DPrintf ("%s", printable); } -static void QCBUILTIN PF_h2dprintv (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2dprintv (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char temp[256]; char printable[2048]; @@ -3599,14 +3594,14 @@ static void QCBUILTIN PF_h2dprintv (progfuncs_t *prinst, struct globalvars_s *pr Con_DPrintf ("%s", printable); } -static void QCBUILTIN PF_h2spawn_temp (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2spawn_temp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ed; ed = ED_Alloc(prinst); RETURN_EDICT(prinst, ed); } -static void QCBUILTIN PF_Remove (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Remove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ed; @@ -3635,7 +3630,7 @@ void PR_CheckEmptyString (char *s) PR_RunError ("Bad string"); } */ -static void QCBUILTIN PF_precache_file (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_precache_file (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { // precache_file is only used to copy files with qcc, it does nothing char *s = PR_GetStringOfs(prinst, OFS_PARM0); @@ -3645,7 +3640,7 @@ static void QCBUILTIN PF_precache_file (progfuncs_t *prinst, struct globalvars_s FS_FLocateFile(s, FSLFRT_IFFOUND, NULL); } -void PF_precache_sound_Internal (progfuncs_t *prinst, char *s) +void PF_precache_sound_Internal (pubprogfuncs_t *prinst, char *s) { int i; @@ -3683,7 +3678,7 @@ void PF_precache_sound_Internal (progfuncs_t *prinst, char *s) } PR_BIError (prinst, "PF_precache_sound: overflow"); } -static void QCBUILTIN PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_precache_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; @@ -3694,7 +3689,7 @@ static void QCBUILTIN PF_precache_sound (progfuncs_t *prinst, struct globalvars_ PF_precache_sound_Internal(prinst, s); } -int PF_precache_model_Internal (progfuncs_t *prinst, char *s, qboolean queryonly) +int PF_precache_model_Internal (pubprogfuncs_t *prinst, char *s, qboolean queryonly) { int i; @@ -3753,7 +3748,7 @@ int PF_precache_model_Internal (progfuncs_t *prinst, char *s, qboolean queryonly PR_BIError (prinst, "PF_precache_model: overflow"); return 0; } -static void QCBUILTIN PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_precache_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; @@ -3764,7 +3759,7 @@ static void QCBUILTIN PF_precache_model (progfuncs_t *prinst, struct globalvars_ PF_precache_model_Internal(prinst, s, false); } -static void QCBUILTIN PF_h2precache_puzzle_model (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2precache_puzzle_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //qc/hc lacks string manipulation. char *shortname; char fullname[MAX_QPATH]; @@ -3774,14 +3769,14 @@ static void QCBUILTIN PF_h2precache_puzzle_model (progfuncs_t *prinst, struct gl PF_precache_model_Internal(prinst, fullname, false); } -static void QCBUILTIN PF_getmodelindex (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_getmodelindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s = PR_GetStringOfs(prinst, OFS_PARM0); - qboolean queryonly = (*svprogfuncs->callargc >= 2)?G_FLOAT(OFS_PARM1):false; + qboolean queryonly = (svprogfuncs->callargc >= 2)?G_FLOAT(OFS_PARM1):false; G_FLOAT(OFS_RETURN) = PF_precache_model_Internal(prinst, s, queryonly); } -void QCBUILTIN PF_precache_vwep_model (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_precache_vwep_model (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; char *s; @@ -3825,7 +3820,7 @@ void QCBUILTIN PF_precache_vwep_model (progfuncs_t *prinst, struct globalvars_s // warning: ‘PF_svcoredump’ defined but not used /* -static void QCBUILTIN PF_svcoredump (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_svcoredump (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int size = 1024*1024*8; char *buffer = BZ_Malloc(size); @@ -3835,7 +3830,7 @@ static void QCBUILTIN PF_svcoredump (progfuncs_t *prinst, struct globalvars_s *p } */ -static void QCBUILTIN PF_sv_movetogoal (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_movetogoal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { wedict_t *ent; float dist; @@ -3851,7 +3846,7 @@ PF_walkmove float(float yaw, float dist) walkmove =============== */ -static void QCBUILTIN PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_walkmove (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; float yaw, dist; @@ -3863,7 +3858,7 @@ static void QCBUILTIN PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_ ent = PROG_TO_EDICT(prinst, pr_global_struct->self); yaw = G_FLOAT(OFS_PARM0); dist = G_FLOAT(OFS_PARM1); - if (*svprogfuncs->callargc >= 3 && G_FLOAT(OFS_PARM2)) + if (svprogfuncs->callargc >= 3 && G_FLOAT(OFS_PARM2)) settrace = true; else settrace = false; @@ -3908,7 +3903,7 @@ PF_droptofloor void() droptofloor =============== */ -static void QCBUILTIN PF_droptofloor (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_droptofloor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; vec3_t end; @@ -4012,14 +4007,14 @@ PF_lightstyle void(float style, string value [, float colour]) lightstyle =============== */ -static void QCBUILTIN PF_lightstyle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int style; char *val; #ifdef PEXT_LIGHTSTYLECOL int col; - if (*svprogfuncs->callargc >= 3) + if (svprogfuncs->callargc >= 3) { col = G_FLOAT(OFS_PARM2); if (IS_NAN(col) || !col || col > 0x111) @@ -4034,7 +4029,7 @@ static void QCBUILTIN PF_lightstyle (progfuncs_t *prinst, struct globalvars_s *p PF_applylightstyle(style, val, col); } -static void QCBUILTIN PF_lightstylevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_lightstylevalue (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int style; style = G_FLOAT(OFS_PARM0); @@ -4046,7 +4041,7 @@ static void QCBUILTIN PF_lightstylevalue (progfuncs_t *prinst, struct globalvars G_FLOAT(OFS_RETURN) = *sv.strings.lightstyles[style] - 'a'; } -static void QCBUILTIN PF_lightstylestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_lightstylestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int style; int num; @@ -4062,7 +4057,7 @@ static void QCBUILTIN PF_lightstylestatic (progfuncs_t *prinst, struct globalvar #ifdef PEXT_LIGHTSTYLECOL int col; - if (*svprogfuncs->callargc >= 3) + if (svprogfuncs->callargc >= 3) { col = G_FLOAT(OFS_PARM2); if (IS_NAN(col) || !col || col > 0x111) @@ -4087,7 +4082,7 @@ static void QCBUILTIN PF_lightstylestatic (progfuncs_t *prinst, struct globalvar PF_checkbottom ============= */ -static void QCBUILTIN PF_checkbottom (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_checkbottom (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; @@ -4101,7 +4096,7 @@ static void QCBUILTIN PF_checkbottom (progfuncs_t *prinst, struct globalvars_s * PF_pointcontents ============= */ -static void QCBUILTIN PF_pointcontents (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_pointcontents (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { world_t *w = prinst->parms->user; @@ -4135,7 +4130,7 @@ vector aim(entity, missilespeed) */ //cvar_t sv_aim = {"sv_aim", "0.93"}; cvar_t sv_aim = SCVAR("sv_aim", "2"); -static void QCBUILTIN PF_aim (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent, *check, *bestent; vec3_t start, dir, end, bestdir; @@ -4227,7 +4222,7 @@ PF_changeyaw This was a major timewaster in progs, so it was converted to C ============== */ -static void QCBUILTIN PF_changeyaw (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; float ideal, current, move, speed; @@ -4265,7 +4260,7 @@ static void QCBUILTIN PF_changeyaw (progfuncs_t *prinst, struct globalvars_s *pr } //void() changepitch = #63; -static void QCBUILTIN PF_changepitch (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; float ideal, current, move, speed; @@ -4436,7 +4431,7 @@ client_t *Write_GetClient(void) } extern sizebuf_t csqcmsgbuffer; -void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4478,7 +4473,7 @@ void QCBUILTIN PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_global #endif } -void QCBUILTIN PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4519,7 +4514,7 @@ void QCBUILTIN PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_global #endif } -void QCBUILTIN PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4560,7 +4555,7 @@ void QCBUILTIN PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globa #endif } -void QCBUILTIN PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4601,7 +4596,7 @@ void QCBUILTIN PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_global #endif } -void QCBUILTIN PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4642,7 +4637,7 @@ void QCBUILTIN PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globa #endif } -void QCBUILTIN PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4683,7 +4678,7 @@ void QCBUILTIN PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globa #endif } -void QCBUILTIN PF_WriteFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) @@ -4735,19 +4730,19 @@ void PF_WriteString_Internal (int target, char *str) #endif } -static void QCBUILTIN PF_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_WriteString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PF_VarString(prinst, 1, pr_globals); PF_WriteString_Internal(G_FLOAT(OFS_PARM0), str); } -void QCBUILTIN PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dest = G_FLOAT(OFS_PARM0); if (dest == MSG_CSQC) { //csqc buffers are always written. - MSG_WriteShort(&csqcmsgbuffer, G_EDICTNUM(prinst, OFS_PARM1)); + MSG_WriteEntity(&csqcmsgbuffer, G_EDICTNUM(prinst, OFS_PARM1)); return; } @@ -4776,16 +4771,16 @@ void QCBUILTIN PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_glob if (!cl) return; ClientReliableCheckBlock(cl, 2); - ClientReliableWrite_Short(cl, G_EDICTNUM(prinst, OFS_PARM1)); + ClientReliableWrite_Entity(cl, G_EDICTNUM(prinst, OFS_PARM1)); } else - MSG_WriteShort (QWWriteDest(dest), G_EDICTNUM(prinst, OFS_PARM1)); + MSG_WriteEntity (QWWriteDest(dest), G_EDICTNUM(prinst, OFS_PARM1)); #endif } //small wrapper function. //void(float target, string str, ...) WriteString2 = #33; -static void QCBUILTIN PF_WriteString2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_WriteString2 (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int old; char *str; @@ -4808,68 +4803,68 @@ static void QCBUILTIN PF_WriteString2 (progfuncs_t *prinst, struct globalvars_s G_FLOAT(OFS_PARM1) = old; } -static void QCBUILTIN PF_qtSingle_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteByte(MSG_PRERELONE, (qbyte)G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteChar(MSG_PRERELONE, (char)G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteShort(MSG_PRERELONE, (short)G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteLong(MSG_PRERELONE, G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteAngle(MSG_PRERELONE, G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteCoord(MSG_PRERELONE, G_FLOAT(OFS_PARM1)); } -static void QCBUILTIN PF_qtSingle_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteString(MSG_PRERELONE, PF_VarString(prinst, 1, pr_globals)); } -static void QCBUILTIN PF_qtSingle_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtSingle_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteEntity(MSG_PRERELONE, (short)G_EDICTNUM(prinst, OFS_PARM1)); } -static void QCBUILTIN PF_qtBroadcast_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteByte(MSG_BROADCAST, (qbyte)G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteChar(MSG_BROADCAST, (char)G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteShort(MSG_BROADCAST, (short)G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteLong(MSG_BROADCAST, G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteAngle(MSG_BROADCAST, G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteCoord(MSG_BROADCAST, G_FLOAT(OFS_PARM0)); } -static void QCBUILTIN PF_qtBroadcast_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteString(MSG_BROADCAST, PF_VarString(prinst, 0, pr_globals)); } -static void QCBUILTIN PF_qtBroadcast_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_qtBroadcast_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { NPP_NQWriteEntity(MSG_BROADCAST, (short)G_EDICTNUM(prinst, OFS_PARM0)); } @@ -4979,7 +4974,7 @@ void SV_beam_tempentity (int ownerent, vec3_t start, vec3_t end, int type) { MSG_WriteByte (&sv.multicast, svc_temp_entity); MSG_WriteByte (&sv.multicast, type); - MSG_WriteShort (&sv.multicast, ownerent); + MSG_WriteEntity (&sv.multicast, ownerent); MSG_WriteCoord (&sv.multicast, start[0]); MSG_WriteCoord (&sv.multicast, start[1]); MSG_WriteCoord (&sv.multicast, start[2]); @@ -4987,36 +4982,21 @@ void SV_beam_tempentity (int ownerent, vec3_t start, vec3_t end, int type) MSG_WriteCoord (&sv.multicast, end[1]); MSG_WriteCoord (&sv.multicast, end[2]); #ifdef NQPROT - if (type == TE_LIGHTNING2 && ownerent<0) //special handling for TE_BEAM (don't do TE_RAILGUN - it's a tomaz extension) - { - MSG_WriteByte (&sv.nqmulticast, svc_temp_entity); - MSG_WriteByte (&sv.nqmulticast, TENQ_BEAM); - MSG_WriteShort (&sv.nqmulticast, -1-ownerent); - MSG_WriteCoord (&sv.nqmulticast, start[0]); - MSG_WriteCoord (&sv.nqmulticast, start[1]); - MSG_WriteCoord (&sv.nqmulticast, start[2]); - MSG_WriteCoord (&sv.nqmulticast, end[0]); - MSG_WriteCoord (&sv.nqmulticast, end[1]); - MSG_WriteCoord (&sv.nqmulticast, end[2]); - } - else - { - MSG_WriteByte (&sv.nqmulticast, svc_temp_entity); - MSG_WriteByte (&sv.nqmulticast, type); - MSG_WriteShort (&sv.nqmulticast, ownerent); - MSG_WriteCoord (&sv.nqmulticast, start[0]); - MSG_WriteCoord (&sv.nqmulticast, start[1]); - MSG_WriteCoord (&sv.nqmulticast, start[2]); - MSG_WriteCoord (&sv.nqmulticast, end[0]); - MSG_WriteCoord (&sv.nqmulticast, end[1]); - MSG_WriteCoord (&sv.nqmulticast, end[2]); - } + MSG_WriteByte (&sv.nqmulticast, svc_temp_entity); + MSG_WriteByte (&sv.nqmulticast, (type==TEQW_BEAM)?TENQ_BEAM:type); + MSG_WriteEntity (&sv.nqmulticast, ownerent); + MSG_WriteCoord (&sv.nqmulticast, start[0]); + MSG_WriteCoord (&sv.nqmulticast, start[1]); + MSG_WriteCoord (&sv.nqmulticast, start[2]); + MSG_WriteCoord (&sv.nqmulticast, end[0]); + MSG_WriteCoord (&sv.nqmulticast, end[1]); + MSG_WriteCoord (&sv.nqmulticast, end[2]); #endif SV_MulticastProtExt (start, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0); } /* -void PF_tempentity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void PF_tempentity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), G_FLOAT(OFS_PARM1), 1); } @@ -5026,7 +5006,7 @@ void PF_tempentity (progfuncs_t *prinst, struct globalvars_s *pr_globals) int SV_ModelIndex (char *name); -void QCBUILTIN PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; int mdlindex; @@ -5045,7 +5025,6 @@ void QCBUILTIN PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globa state = &sv_staticentities[sv.num_static_entities++]; memset(state, 0, sizeof(*state)); state->number = sv.num_static_entities; - state->flags = 0; VectorCopy (ent->v->origin, state->origin); VectorCopy (ent->v->angles, state->angles); state->modelindex = mdlindex;//ent->v->modelindex; @@ -5077,7 +5056,7 @@ void QCBUILTIN PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globa PF_setspawnparms ============== */ -void QCBUILTIN PF_setspawnparms (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_setspawnparms (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; int i; @@ -5104,7 +5083,7 @@ void QCBUILTIN PF_setspawnparms (progfuncs_t *prinst, struct globalvars_s *pr_gl PF_changelevel ============== */ -void QCBUILTIN PF_changelevel (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s, *spot; @@ -5113,7 +5092,7 @@ void QCBUILTIN PF_changelevel (progfuncs_t *prinst, struct globalvars_s *pr_glob return; sv.mapchangelocked = true; - if (*svprogfuncs->callargc == 2) + if (svprogfuncs->callargc == 2) { s = PR_GetStringOfs(prinst, OFS_PARM0); spot = PR_GetStringOfs(prinst, OFS_PARM1); @@ -5134,7 +5113,7 @@ PF_logfrag logfrag (killer, killee) ============== */ -void QCBUILTIN PF_logfrag (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent1, *ent2; int e1, e2; @@ -5192,20 +5171,71 @@ char *PF_infokey_Internal (int entnum, char *key) else if (entnum <= sv.allocated_client_slots) { value = ov; - if (!strcmp(key, "ip") || !strcmp(key, "realip")) //note: FTE doesn't support mvdsv's realip stuff, so pretend that we do if the mod asks + if (!strcmp(key, "ip")) NET_BaseAdrToString (ov, sizeof(ov), svs.clients[entnum-1].netchan.remote_address); + else if (!strcmp(key, "realip")) + { + if (svs.clients[entnum-1].realip_status) + NET_BaseAdrToString (ov, sizeof(ov), svs.clients[entnum-1].realip); + else //FIXME: should we report the spoofable/proxy address if the real ip is not known? + NET_BaseAdrToString (ov, sizeof(ov), svs.clients[entnum-1].netchan.remote_address); + } + else if (!strcmp(key, "csqcactive")) + sprintf(ov, "%d", svs.clients[entnum-1].csqcactive); else if (!strcmp(key, "ping")) sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1], false)); else if (!strcmp(key, "svping")) sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1], true)); else if (!strcmp(key, "guid")) sprintf(ov, "%s", svs.clients[entnum-1].guid); + else if (!strcmp(key, "challenge")) + sprintf(ov, "%u", svs.clients[entnum-1].challenge); else if (!strcmp(key, "*userid")) sprintf(ov, "%d", svs.clients[entnum-1].userid); else if (!strcmp(key, "download")) sprintf(ov, "%d", svs.clients[entnum-1].download != NULL ? (int)(100*svs.clients[entnum-1].downloadcount/svs.clients[entnum-1].downloadsize) : -1); // else if (!strcmp(key, "login")) //mvdsv // value = ""; + else if (!strcmp(key, "protocol")) + { + value = ""; + switch(svs.clients[entnum-1].protocol) + { + case SCP_BAD: + value = ""; //could be a writebyted bot... + break; + case SCP_QUAKEWORLD: + if (!svs.clients[entnum-1].fteprotocolextensions && !svs.clients[entnum-1].fteprotocolextensions) + value = "quakeworld"; + else + value = "quakeworld+"; + break; + case SCP_QUAKE2: + value = "quake2"; //shouldn't happen + break; + case SCP_QUAKE3: + value = "quake3"; //can actually happen. + break; + case SCP_NETQUAKE: + value = "quake"; + break; + case SCP_PROQUAKE: + value = "proquake"; + break; + case SCP_FITZ666: + if (svs.clients[entnum-1].netchan.netprim.coordsize != 2) + value = "rmq999"; + else + value = "fitz666"; + break; + case SCP_DARKPLACES6: + value = "dpp6"; + break; + case SCP_DARKPLACES7: + value = "dpp7"; + break; + } + } else if (!strcmp(key, "trustlevel")) //info for progs. { #ifdef SVRANKING @@ -5226,7 +5256,7 @@ char *PF_infokey_Internal (int entnum, char *key) return value; } -static void QCBUILTIN PF_infokey (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_infokey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e; int e1; @@ -5250,7 +5280,7 @@ PF_multicast void(vector where, float set) multicast ============== */ -void QCBUILTIN PF_multicast (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_multicast (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *o; int to; @@ -5264,7 +5294,7 @@ void QCBUILTIN PF_multicast (progfuncs_t *prinst, struct globalvars_s *pr_global } -static void QCBUILTIN PF_Fixme (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Fixme (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; qboolean printedheader = false; @@ -5296,13 +5326,13 @@ qboolean printedheader = false; PR_BIError (prinst, "builtin not implemented"); } -static void QCBUILTIN PF_Ignore(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Ignore(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_INT(OFS_RETURN) = 0; } #define PRSTR 0xa6ffb3d7 -static void QCBUILTIN PF_newstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) //mvdsv +static void QCBUILTIN PF_newstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //mvdsv { char *s; int len; @@ -5310,20 +5340,17 @@ static void QCBUILTIN PF_newstring(progfuncs_t *prinst, struct globalvars_s *pr_ char *in = PR_GetStringOfs(prinst, OFS_PARM0); len = strlen(in)+1; - if (*prinst->callargc == 2 && G_FLOAT(OFS_PARM1) > len) + if (prinst->callargc == 2 && G_FLOAT(OFS_PARM1) > len) len = G_FLOAT(OFS_PARM1); - s = Z_TagMalloc(len+8, Z_QC_TAG); - ((int *)s)[0] = PRSTR; - ((int *)s)[1] = len; - strcpy(s+8, in); - - RETURN_SSTRING(s+8); + s = prinst->AddressableAlloc(prinst, len); + G_INT(OFS_RETURN) = (char*)s - prinst->stringtable; + strcpy(s, in); } // warning: ‘PF_strcatp’ defined but not used /* -static void QCBUILTIN PF_strcatp(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_strcatp(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *buf = PR_GetStringOfs(prinst, OFS_PARM0); char *add = PR_GetStringOfs(prinst, OFS_PARM1); int wantedlen = G_FLOAT(OFS_PARM2); @@ -5349,7 +5376,7 @@ static void QCBUILTIN PF_strcatp(progfuncs_t *prinst, struct globalvars_s *pr_gl // warning: ‘PF_redstring’ defined but not used /* -static void QCBUILTIN PF_redstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_redstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *string = PR_GetStringOfs(prinst, OFS_PARM0), *s; static char buf[1024]; @@ -5364,7 +5391,7 @@ static void QCBUILTIN PF_redstring(progfuncs_t *prinst, struct globalvars_s *pr_ #ifdef SVCHAT void SV_Chat(char *filename, float starttag, edict_t *edict); -static void QCBUILTIN PF_chat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_chat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_Chat(PR_GetStringOfs(prinst, OFS_PARM0), G_FLOAT(OFS_PARM1), G_EDICT(prinst, OFS_PARM2)); } @@ -5379,7 +5406,7 @@ static void QCBUILTIN PF_chat (progfuncs_t *prinst, struct globalvars_s *pr_glob /* FTE_SQL builtins */ #ifdef SQL -void PF_sqlconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlconnect (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *paramstr[SQL_CONNECT_PARAMS]; char *driver; @@ -5394,7 +5421,7 @@ void PF_sqlconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) // check and fit connection parameters for (i = 0; i < SQL_CONNECT_PARAMS; i++) { - if (*svprogfuncs->callargc <= (i + 1)) + if (svprogfuncs->callargc <= (i + 1)) paramstr[i] = ""; else paramstr[i] = PR_GetStringOfs(prinst, OFS_PARM0+i*3); @@ -5410,7 +5437,7 @@ void PF_sqlconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) paramstr[3] = sql_defaultdb.string; // verify/switch driver choice - if (*svprogfuncs->callargc >= (SQL_CONNECT_PARAMS + 1)) + if (svprogfuncs->callargc >= (SQL_CONNECT_PARAMS + 1)) driver = PR_GetStringOfs(prinst, OFS_PARM0 + SQL_CONNECT_PARAMS * 3); else driver = ""; @@ -5421,7 +5448,7 @@ void PF_sqlconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = SQL_NewServer(driver, paramstr); } -void PF_sqldisconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqldisconnect (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; @@ -5436,7 +5463,7 @@ void PF_sqldisconnect (progfuncs_t *prinst, struct globalvars_s *pr_globals) } } -void PF_sqlopenquery (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlopenquery (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; int callfunc = G_INT(OFS_PARM1); @@ -5472,7 +5499,7 @@ void PF_sqlopenquery (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = -1; } -void PF_sqlclosequery (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlclosequery (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; queryresult_t *qres; @@ -5494,7 +5521,7 @@ void PF_sqlclosequery (progfuncs_t *prinst, struct globalvars_s *pr_globals) // else nothing to close } -void PF_sqlreadfield (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlreadfield (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; queryresult_t *qres; @@ -5521,7 +5548,7 @@ void PF_sqlreadfield (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_INT(OFS_RETURN) = 0; } -void PF_sqlreadfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlreadfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; queryresult_t *qres; @@ -5548,7 +5575,7 @@ void PF_sqlreadfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) G_FLOAT(OFS_RETURN) = 0; } -void PF_sqlerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; int serverref = G_FLOAT(OFS_PARM0); @@ -5558,7 +5585,7 @@ void PF_sqlerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) server = SQL_GetServer(G_FLOAT(OFS_PARM0), true); if (server) { - if (*svprogfuncs->callargc == 2) + if (svprogfuncs->callargc == 2) { // query-specific error request if (server->active) // didn't check this earlier so check it now { @@ -5581,7 +5608,7 @@ void PF_sqlerror (progfuncs_t *prinst, struct globalvars_s *pr_globals) RETURN_TSTRING(""); } -void PF_sqlescape (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlescape (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; char *toescape; @@ -5605,7 +5632,7 @@ void PF_sqlescape (progfuncs_t *prinst, struct globalvars_s *pr_globals) RETURN_TSTRING(""); } -void PF_sqlversion (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_sqlversion (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { sqlserver_t *server; @@ -5687,7 +5714,7 @@ lh_extension_t *checkfteextensioncl(int mask, char *name) //true if the cient ex lh_extension_t *checkfteextensionsv(char *name) //true if the server supports an protocol extension. { - return checkfteextensioncl(Net_PextMask(1), name); + return checkfteextensioncl(Net_PextMask(1, false), name); } lh_extension_t *checkextension(char *name) @@ -5712,7 +5739,7 @@ returns true if the extension is supported by the server checkextension(string extensionname, [entity client]) ================= */ -static void QCBUILTIN PF_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { lh_extension_t *ext = NULL; char *s = PR_GetStringOfs(prinst, OFS_PARM0); @@ -5720,7 +5747,7 @@ static void QCBUILTIN PF_checkextension (progfuncs_t *prinst, struct globalvars_ ext = checkextension(s); if (!ext) { - if (*svprogfuncs->callargc == 2) + if (svprogfuncs->callargc == 2) { int clnum = NUM_FOR_EDICT(prinst, G_EDICT(prinst, OFS_PARM1)); if (clnum >= 1 && clnum <= sv.allocated_client_slots) //valid client as second parameter @@ -5769,7 +5796,7 @@ static void QCBUILTIN PF_checkextension (progfuncs_t *prinst, struct globalvars_ } -static void QCBUILTIN PF_builtinsupported (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_builtinsupported (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s = PR_GetStringOfs(prinst, OFS_PARM0); @@ -5780,7 +5807,7 @@ static void QCBUILTIN PF_builtinsupported (progfuncs_t *prinst, struct globalvar //mvdsv builtins. -void QCBUILTIN PF_ExecuteCommand (progfuncs_t *prinst, struct globalvars_s *pr_globals) //83 //void() exec; +void QCBUILTIN PF_ExecuteCommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) //83 //void() exec; { int old_other, old_self; // mod_consolecmd will be executed, so we need to store this @@ -5801,7 +5828,7 @@ string teamfield(.string field) ================= */ -static void QCBUILTIN PF_teamfield (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_teamfield (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { pr_teamfield = G_INT(OFS_PARM0)+prinst->fieldadjust; } @@ -5814,7 +5841,7 @@ string substr(string str, float start, float len) ================= */ -static void QCBUILTIN PF_substr (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_substr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char dest[4096]; char *s; @@ -5855,7 +5882,7 @@ float str2byte (string str) ================= */ -static void QCBUILTIN PF_str2byte (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_str2byte (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = (float) *PR_GetStringOfs(prinst, OFS_PARM0); } @@ -5868,7 +5895,7 @@ float str2short (string str) ================= */ -static void QCBUILTIN PF_str2short (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_str2short (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { G_FLOAT(OFS_RETURN) = (float) LittleShort(*(short*)PR_GetStringOfs(prinst, OFS_PARM0)); } @@ -5881,7 +5908,7 @@ string readmcmd (string str) ================= */ -static void QCBUILTIN PF_readcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_readcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; static char output[8000]; @@ -5921,7 +5948,7 @@ void redirectcmd (entity to, string str) ================= */ /* -static void QCBUILTIN PF_redirectcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_redirectcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; int entnum; @@ -5953,7 +5980,7 @@ if argument 'now' is set, frame is written instantly ================= */ -static void QCBUILTIN PF_forcedemoframe (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_forcedemoframe (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { demo.forceFrame = 1; // if (G_FLOAT(OFS_PARM0) == 1) @@ -5970,7 +5997,7 @@ FIXME: check for null pointers first? ================= */ -static void QCBUILTIN PF_MVDSV_strcpy (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_MVDSV_strcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dst = G_INT(OFS_PARM0); char *src = PR_GetStringOfs(prinst, OFS_PARM1); @@ -5994,7 +6021,7 @@ FIXME: check for null pointers first? ================= */ -static void QCBUILTIN PF_MVDSV_strncpy (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_MVDSV_strncpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int dst = G_INT(OFS_PARM0); char *src = PR_GetStringOfs(prinst, OFS_PARM1); @@ -6018,7 +6045,7 @@ string strstr(string str, string sub) ================= */ -static void QCBUILTIN PF_strstr (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_strstr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str, *sub, *p; @@ -6084,7 +6111,7 @@ void log(string name, float console, string text) ================= */ -static void QCBUILTIN PF_log(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_log(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char name[MAX_OSPATH], *text; vfsfile_t *file; @@ -6110,7 +6137,7 @@ static void QCBUILTIN PF_log(progfuncs_t *prinst, struct globalvars_s *pr_global #ifdef Q2BSPS -static void QCBUILTIN PF_OpenPortal (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_OpenPortal (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { if (sv.world.worldmodel->fromgame == fg_quake2) { @@ -6138,7 +6165,7 @@ static void QCBUILTIN PF_OpenPortal (progfuncs_t *prinst, struct globalvars_s *p //void(entity from, entity to) copyentity = #400 //copies data from one entity to another -static void QCBUILTIN PF_copyentity (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_copyentity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *in, *out; @@ -6154,7 +6181,7 @@ static void QCBUILTIN PF_copyentity (progfuncs_t *prinst, struct globalvars_s *p //entity(string field, string match) findchain = #402 //chained search for strings in entity fields -static void QCBUILTIN PF_sv_findchain (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_findchain (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; char *s; @@ -6188,7 +6215,7 @@ static void QCBUILTIN PF_sv_findchain (progfuncs_t *prinst, struct globalvars_s //entity(string field, float match) findchainfloat = #403 //chained search for float, int, and entity reference fields -static void QCBUILTIN PF_sv_findchainfloat (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_findchainfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; float s; @@ -6218,7 +6245,7 @@ static void QCBUILTIN PF_sv_findchainfloat (progfuncs_t *prinst, struct globalva //entity(string field, float match) findchainflags = #450 //chained search for float, int, and entity reference fields -static void QCBUILTIN PF_sv_findchainflags (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_findchainflags (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i, f; int s; @@ -6248,7 +6275,7 @@ static void QCBUILTIN PF_sv_findchainflags (progfuncs_t *prinst, struct globalva //void(vector dir) vectorvectors = #432 //Writes new values for v_forward, v_up, and v_right based on the given forward vector -static void QCBUILTIN PF_vectorvectors (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { VectorCopy(G_VECTOR(OFS_PARM0), P_VEC(v_forward)); VectorNormalize(P_VEC(v_forward)); @@ -6259,7 +6286,7 @@ static void QCBUILTIN PF_vectorvectors (progfuncs_t *prinst, struct globalvars_s //void(entity e, string s) clientcommand = #440 //executes a command string as if it came from the specified client -static void QCBUILTIN PF_clientcommand (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_clientcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { client_t *temp_client; int i; @@ -6286,7 +6313,7 @@ static void QCBUILTIN PF_clientcommand (progfuncs_t *prinst, struct globalvars_s } -static void QCBUILTIN PF_h2AdvanceFrame(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2AdvanceFrame(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *Ent; float Start,End,Result; @@ -6331,7 +6358,7 @@ static void QCBUILTIN PF_h2AdvanceFrame(progfuncs_t *prinst, struct globalvars_s G_FLOAT(OFS_RETURN) = Result; } -static void QCBUILTIN PF_h2RewindFrame(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2RewindFrame(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *Ent; float Start,End,Result; @@ -6365,7 +6392,7 @@ static void QCBUILTIN PF_h2RewindFrame(progfuncs_t *prinst, struct globalvars_s #define WF_CYCLE_WRAPPED 2 #define WF_LAST_FRAME 3 -static void QCBUILTIN PF_h2advanceweaponframe (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2advanceweaponframe (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent; float startframe,endframe; @@ -6402,6 +6429,19 @@ static void QCBUILTIN PF_h2advanceweaponframe (progfuncs_t *prinst, struct globa G_FLOAT(OFS_RETURN) = state; } +void SV_AddDebugPolygons(void) +{ + int i; + if (gfuncs.AddDebugPolygons) + { + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + for (i = 0; i < MAX_CLIENTS; i++) + if (svs.clients[i].netchan.remote_address.type == NA_LOOPBACK) + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict); + PR_ExecuteProgram (svprogfuncs, gfuncs.AddDebugPolygons); + } +} + void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc) { char temp[16]; @@ -6448,7 +6488,7 @@ void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc) } } -static void QCBUILTIN PF_h2setclass (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2setclass (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float NewClass; int entnum; @@ -6477,7 +6517,7 @@ static void QCBUILTIN PF_h2setclass (progfuncs_t *prinst, struct globalvars_s *p client->sendinfo = true; } -static void QCBUILTIN PF_h2v_factor(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2v_factor(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) // returns (v_right * factor_x) + (v_forward * factor_y) + (v_up * factor_z) { float *range; @@ -6500,7 +6540,7 @@ static void QCBUILTIN PF_h2v_factor(progfuncs_t *prinst, struct globalvars_s *pr VectorCopy (result, G_VECTOR(OFS_RETURN)); } -static void QCBUILTIN PF_h2v_factorrange(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2v_factorrange(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) // returns (v_right * factor_x) + (v_forward * factor_y) + (v_up * factor_z) { float num,*minv,*maxv; @@ -6532,7 +6572,7 @@ static void QCBUILTIN PF_h2v_factorrange(progfuncs_t *prinst, struct globalvars_ } char *T_GetString(int num); -static void QCBUILTIN PF_h2plaque_draw(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2plaque_draw(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s; @@ -6575,7 +6615,7 @@ static void QCBUILTIN PF_h2plaque_draw(progfuncs_t *prinst, struct globalvars_s } } -static void QCBUILTIN PF_h2movestep (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2movestep (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { vec3_t v; edict_t *ent; @@ -6598,7 +6638,7 @@ static void QCBUILTIN PF_h2movestep (progfuncs_t *prinst, struct globalvars_s *p pr_global_struct->self = oldself; } -static void QCBUILTIN PF_h2concatv(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2concatv(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *in,*range; vec3_t result; @@ -6617,7 +6657,7 @@ static void QCBUILTIN PF_h2concatv(progfuncs_t *prinst, struct globalvars_s *pr_ VectorCopy (result, G_VECTOR(OFS_RETURN)); } -static void QCBUILTIN PF_h2matchAngleToSlope(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2matchAngleToSlope(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *actor; vec3_t v_forward, old_forward, old_right, new_angles2 = { 0, 0, 0 }; @@ -6650,7 +6690,7 @@ static void QCBUILTIN PF_h2matchAngleToSlope(progfuncs_t *prinst, struct globalv actor->v->angles[2] = (1-fabs(dot))*pitch*mod; } /*objective type stuff, this goes into a stat*/ -static void QCBUILTIN PF_h2updateinfoplaque(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2updateinfoplaque(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int idx = G_FLOAT(OFS_PARM0); int mode = G_FLOAT(OFS_PARM1); /*0=toggle, 1=force, 2=clear*/ @@ -6890,7 +6930,7 @@ void SV_RegisterH2CustomTents(void) h2customtents[ce_chunk_24] = SV_CustomTEnt_Register("ce_chunk_bone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL); } } -static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2starteffect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min, *max, *angle, *size; float colour; @@ -7144,7 +7184,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s Con_Printf("FTE-H2 FIXME: Effect %i doesn't have an effect registered\nTell Spike!\n", efnum); } -static void QCBUILTIN PF_h2endeffect(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2endeffect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int ign = G_FLOAT(OFS_PARM0); int index = G_FLOAT(OFS_PARM1); @@ -7152,7 +7192,7 @@ static void QCBUILTIN PF_h2endeffect(progfuncs_t *prinst, struct globalvars_s *p Con_DPrintf("Stop effect %i\n", index); } -static void QCBUILTIN PF_h2rain_go(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2rain_go(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { /* float *min = G_VECTOR(OFS_PARM0); @@ -7165,7 +7205,7 @@ static void QCBUILTIN PF_h2rain_go(progfuncs_t *prinst, struct globalvars_s *pr_ Con_DPrintf("FTE-H2 FIXME: rain_go not implemented\n"); } -static void QCBUILTIN PF_h2StopSound(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2StopSound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int channel; edict_t *entity; @@ -7176,12 +7216,12 @@ static void QCBUILTIN PF_h2StopSound(progfuncs_t *prinst, struct globalvars_s *p SVQ1_StartSound ((wedict_t*)entity, channel, "", 1, 0, 0); } -static void QCBUILTIN PF_h2updatesoundpos(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2updatesoundpos(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { Con_DPrintf("FTE-H2 FIXME: updatesoundpos not implemented\n"); } -static void QCBUILTIN PF_h2whiteflash(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2whiteflash(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { /* broadcast a stuffcmd, I guess, to flash the screen white @@ -7190,13 +7230,13 @@ static void QCBUILTIN PF_h2whiteflash(progfuncs_t *prinst, struct globalvars_s * Con_DPrintf("FTE-H2 FIXME: whiteflash not implemented\n"); } -static void QCBUILTIN PF_h2getstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_h2getstring(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *s = T_GetString(G_FLOAT(OFS_PARM0)-1); RETURN_PSTRING(s); } -static void QCBUILTIN PF_RegisterTEnt(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_RegisterTEnt(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int arg; int i; @@ -7250,14 +7290,14 @@ static void QCBUILTIN PF_RegisterTEnt(progfuncs_t *prinst, struct globalvars_s * } } - if (arg != *prinst->callargc) + if (arg != prinst->callargc) Con_Printf("Bad argument count\n"); G_FLOAT(OFS_RETURN) = i; } -static void QCBUILTIN PF_CustomTEnt(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_CustomTEnt(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int type; int arg; @@ -7282,7 +7322,7 @@ static void QCBUILTIN PF_CustomTEnt(progfuncs_t *prinst, struct globalvars_s *pr arg++; mcd = MULTICAST_ALL_R; - if (arg == *prinst->callargc) + if (arg == prinst->callargc) { MSG_WriteShort(&sv.multicast, id | 0x8000); SV_MulticastProtExt (vec3_origin, mcd, pr_global_struct->dimension_send, PEXT_CUSTOMTEMPEFFECTS, 0); //now send the new multicast to all that will. @@ -7326,14 +7366,14 @@ static void QCBUILTIN PF_CustomTEnt(progfuncs_t *prinst, struct globalvars_s *pr arg++; } } - if (arg != *prinst->callargc) + if (arg != prinst->callargc) Con_Printf("PF_CusromTEnt: bad number of arguments for particle type\n"); SV_MulticastProtExt (org, mcd, pr_global_struct->dimension_send, PEXT_CUSTOMTEMPEFFECTS, 0); //now send the new multicast to all that will. } //float(string effectname) particleeffectnum (EXT_CSQC) -static void QCBUILTIN PF_sv_particleeffectnum(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_particleeffectnum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef PEXT_CSQC #ifdef warningmsg @@ -7346,7 +7386,7 @@ static void QCBUILTIN PF_sv_particleeffectnum(progfuncs_t *prinst, struct global #endif } //void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC), -static void QCBUILTIN PF_sv_trailparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_trailparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef PEXT_CSQC int efnum; @@ -7367,7 +7407,7 @@ static void QCBUILTIN PF_sv_trailparticles(progfuncs_t *prinst, struct globalvar } MSG_WriteByte(&sv.multicast, svcfte_trailparticles); - MSG_WriteShort(&sv.multicast, ednum); + MSG_WriteEntity(&sv.multicast, ednum); MSG_WriteShort(&sv.multicast, efnum); MSG_WriteCoord(&sv.multicast, start[0]); MSG_WriteCoord(&sv.multicast, start[1]); @@ -7377,7 +7417,7 @@ static void QCBUILTIN PF_sv_trailparticles(progfuncs_t *prinst, struct globalvar MSG_WriteCoord(&sv.multicast, end[2]); MSG_WriteByte(&sv.nqmulticast, svcdp_trailparticles); - MSG_WriteShort(&sv.nqmulticast, ednum); + MSG_WriteEntity(&sv.nqmulticast, ednum); MSG_WriteShort(&sv.nqmulticast, efnum); MSG_WriteCoord(&sv.nqmulticast, start[0]); MSG_WriteCoord(&sv.nqmulticast, start[1]); @@ -7390,7 +7430,7 @@ static void QCBUILTIN PF_sv_trailparticles(progfuncs_t *prinst, struct globalvar #endif } //void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC) -static void QCBUILTIN PF_sv_pointparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef PEXT_CSQC int efnum = G_FLOAT(OFS_PARM0); @@ -7499,7 +7539,7 @@ static void PRSV_ClearThreads(void) } } -static void QCBUILTIN PF_Sleep(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Sleep(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { qcstate_t *state; struct qcthread_s *thread; @@ -7520,13 +7560,13 @@ static void QCBUILTIN PF_Sleep(progfuncs_t *prinst, struct globalvars_s *pr_glob svprogfuncs->AbortStack(svprogfuncs); } -static void QCBUILTIN PF_Fork(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_Fork(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { qcstate_t *state; struct qcthread_s *thread; float sleeptime; - if (*svprogfuncs->callargc >= 1) + if (svprogfuncs->callargc >= 1) sleeptime = G_FLOAT(OFS_PARM0); else sleeptime = 0; @@ -7548,20 +7588,20 @@ static void QCBUILTIN PF_Fork(progfuncs_t *prinst, struct globalvars_s *pr_globa //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_gunshot = #418; -static void QCBUILTIN PF_te_gunshot(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_gunshot(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int count; - if (*svprogfuncs->callargc >= 2) + if (svprogfuncs->callargc >= 2) count = G_FLOAT(OFS_PARM1); else count = 1; SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_GUNSHOT, count); } //DP_TE_QUADEFFECTS1 -static void QCBUILTIN PF_te_gunshotquad(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_gunshotquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int count; - if (*svprogfuncs->callargc >= 2) + if (svprogfuncs->callargc >= 2) count = G_FLOAT(OFS_PARM1); else count = 1; @@ -7570,28 +7610,28 @@ static void QCBUILTIN PF_te_gunshotquad(progfuncs_t *prinst, struct globalvars_s //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_spike = #419; -static void QCBUILTIN PF_te_spike(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_spike(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_SPIKE, 1); } //DP_TE_QUADEFFECTS1 -static void QCBUILTIN PF_te_spikequad(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_spikequad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TEDP_SPIKEQUAD, 1); } // FTE_TE_STANDARDEFFECTBUILTINS -static void QCBUILTIN PF_te_lightningblood(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_lightningblood(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TEQW_LIGHTNINGBLOOD, 1); } // FTE_TE_STANDARDEFFECTBUILTINS -static void QCBUILTIN PF_te_bloodqw(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_bloodqw(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int count; - if (*svprogfuncs->callargc >= 2) + if (svprogfuncs->callargc >= 2) count = G_FLOAT(OFS_PARM1); else count = 1; @@ -7600,66 +7640,66 @@ static void QCBUILTIN PF_te_bloodqw(progfuncs_t *prinst, struct globalvars_s *pr //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_superspike = #420; -static void QCBUILTIN PF_te_superspike(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_superspike(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_SUPERSPIKE, 1); } //DP_TE_QUADEFFECTS1 -static void QCBUILTIN PF_te_superspikequad(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_superspikequad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TEDP_SUPERSPIKEQUAD, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_explosion = #421; -static void QCBUILTIN PF_te_explosion(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_explosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_EXPLOSION, 1); } //DP_TE_QUADEFFECTS1 -static void QCBUILTIN PF_te_explosionquad(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_explosionquad(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TEDP_EXPLOSIONQUAD, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_tarexplosion = #422; -static void QCBUILTIN PF_te_tarexplosion(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_tarexplosion(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_TAREXPLOSION, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_wizspike = #423; -static void QCBUILTIN PF_te_wizspike(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_wizspike(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_WIZSPIKE, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_knightspike = #424; -static void QCBUILTIN PF_te_knightspike(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_knightspike(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_KNIGHTSPIKE, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_lavasplash = #425; -static void QCBUILTIN PF_te_lavasplash(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_lavasplash(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_LAVASPLASH, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org) te_teleport = #426; -static void QCBUILTIN PF_te_teleport(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_teleport(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_TELEPORT, 1); } //DP_TE_STANDARDEFFECTBUILTINS //void(vector org, float color) te_explosion2 = #427; -static void QCBUILTIN PF_te_explosion2(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_explosion2(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { //FIXME: QW doesn't support TE_EXPLOSION2... SV_point_tempentity(G_VECTOR(OFS_PARM0), TE_EXPLOSION, 1); @@ -7667,34 +7707,34 @@ static void QCBUILTIN PF_te_explosion2(progfuncs_t *prinst, struct globalvars_s //DP_TE_STANDARDEFFECTBUILTINS //void(entity own, vector start, vector end) te_lightning1 = #428; -static void QCBUILTIN PF_te_lightning1(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_lightning1(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_beam_tempentity(G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TE_LIGHTNING1); } //DP_TE_STANDARDEFFECTBUILTINS //void(entity own, vector start, vector end) te_lightning2 = #429; -static void QCBUILTIN PF_te_lightning2(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_lightning2(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_beam_tempentity(G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TE_LIGHTNING2); } //DP_TE_STANDARDEFFECTBUILTINS //void(entity own, vector start, vector end) te_lightning3 = #430; -static void QCBUILTIN PF_te_lightning3(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_lightning3(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { SV_beam_tempentity(G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TE_LIGHTNING3); } //DP_TE_STANDARDEFFECTBUILTINS //void(entity own, vector start, vector end) te_beam = #431; -static void QCBUILTIN PF_te_beam(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_beam(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - SV_beam_tempentity(-1 -G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TE_LIGHTNING2); + SV_beam_tempentity(G_EDICTNUM(prinst, OFS_PARM0), G_VECTOR(OFS_PARM1), G_VECTOR(OFS_PARM2), TEQW_BEAM); } //DP_TE_SPARK -static void QCBUILTIN PF_te_spark(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_spark(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); @@ -7733,14 +7773,14 @@ static void QCBUILTIN PF_te_spark(progfuncs_t *prinst, struct globalvars_s *pr_g } // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH) -static void QCBUILTIN PF_te_smallflash(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_smallflash(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); SV_point_tempentity(org, TEDP_SMALLFLASH, 0); } // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH) -static void QCBUILTIN PF_te_customflash(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_customflash(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); @@ -7781,7 +7821,7 @@ static void QCBUILTIN PF_te_customflash(progfuncs_t *prinst, struct globalvars_s } //#408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE) -static void QCBUILTIN PF_te_particlecube(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_particlecube(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min = G_VECTOR(OFS_PARM0); float *max = G_VECTOR(OFS_PARM1); @@ -7837,7 +7877,7 @@ static void QCBUILTIN PF_te_particlecube(progfuncs_t *prinst, struct globalvars_ SV_Multicast(org, MULTICAST_PVS); } -static void QCBUILTIN PF_te_explosionrgb(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_explosionrgb(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float *colour = G_VECTOR(OFS_PARM0); @@ -7867,7 +7907,7 @@ static void QCBUILTIN PF_te_explosionrgb(progfuncs_t *prinst, struct globalvars_ SV_Multicast(org, MULTICAST_PVS); } -static void QCBUILTIN PF_te_particlerain(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_particlerain(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min = G_VECTOR(OFS_PARM0); float *max = G_VECTOR(OFS_PARM1); @@ -7921,7 +7961,7 @@ static void QCBUILTIN PF_te_particlerain(progfuncs_t *prinst, struct globalvars_ SV_Multicast(NULL, MULTICAST_ALL); } -static void QCBUILTIN PF_te_particlesnow(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_particlesnow(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *min = G_VECTOR(OFS_PARM0); float *max = G_VECTOR(OFS_PARM1); @@ -7976,7 +8016,7 @@ static void QCBUILTIN PF_te_particlesnow(progfuncs_t *prinst, struct globalvars_ } // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER) -static void QCBUILTIN PF_te_bloodshower(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_bloodshower(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { // [vector] min [vector] max [coord] explosionspeed [short] count float *min = G_VECTOR(OFS_PARM0); @@ -8024,7 +8064,7 @@ static void QCBUILTIN PF_te_bloodshower(progfuncs_t *prinst, struct globalvars_s //DP_SV_EFFECT //void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; -static void QCBUILTIN PF_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_effect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); char *name = PR_GetStringOfs(prinst, OFS_PARM1); @@ -8038,14 +8078,14 @@ static void QCBUILTIN PF_effect(progfuncs_t *prinst, struct globalvars_s *pr_glo //DP_TE_PLASMABURN //void(vector org) te_plasmaburn = #433; -static void QCBUILTIN PF_te_plasmaburn(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_te_plasmaburn(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); SV_point_tempentity(org, 75, 0); } -void QCBUILTIN PF_ForceInfoKey(progfuncs_t *prinst, struct globalvars_s *pr_globals) +void QCBUILTIN PF_ForceInfoKey(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e; int e1; @@ -8068,7 +8108,7 @@ void QCBUILTIN PF_ForceInfoKey(progfuncs_t *prinst, struct globalvars_s *pr_glob { //woo. we found a client. Info_SetValueForStarKey(svs.clients[e1-1].userinfo, key, value, sizeof(svs.clients[e1-1].userinfo)); - SV_ExtractFromUserinfo (&svs.clients[e1-1]); + SV_ExtractFromUserinfo (&svs.clients[e1-1], false); if (SV_UserInfoIsBasic(key)) Info_SetValueForKey (svs.clients[e1-1].userinfobasic, key, value, sizeof(svs.clients[e1-1].userinfobasic)); @@ -8098,7 +8138,7 @@ setcolors(clientent, value) */ //from lh -static void QCBUILTIN PF_setcolors (progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_setcolors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { client_t *client; int entnum, i; @@ -8139,7 +8179,7 @@ static void QCBUILTIN PF_setcolors (progfuncs_t *prinst, struct globalvars_s *pr MSG_WriteString (&sv.reliable_datagram, "bottomcolor"); MSG_WriteString (&sv.reliable_datagram, number); } - SV_ExtractFromUserinfo (client); + SV_ExtractFromUserinfo (client, true); } @@ -8184,7 +8224,7 @@ static void ParamNegateFix ( float * xx, float * yy, int Zone ) xx[0] = x; yy[0] = y; } -static void QCBUILTIN PF_ShowPic(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ShowPic(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *slot = PR_GetStringOfs(prinst, OFS_PARM0); char *picname = PR_GetStringOfs(prinst, OFS_PARM1); @@ -8197,7 +8237,7 @@ static void QCBUILTIN PF_ShowPic(progfuncs_t *prinst, struct globalvars_s *pr_gl ParamNegateFix( &x, &y, zone ); - if (*prinst->callargc==6) + if (prinst->callargc==6) { //to a single client entnum = G_EDICTNUM(prinst, OFS_PARM5)-1; if (entnum < 0 || entnum >= sv.allocated_client_slots) @@ -8215,7 +8255,7 @@ static void QCBUILTIN PF_ShowPic(progfuncs_t *prinst, struct globalvars_s *pr_gl } else { - *prinst->callargc = 6; + prinst->callargc = 6; for (entnum = 0; entnum < sv.allocated_client_slots; entnum++) { G_INT(OFS_PARM5) = EDICT_TO_PROG(prinst, EDICT_NUM(prinst, entnum+1)); @@ -8224,13 +8264,13 @@ static void QCBUILTIN PF_ShowPic(progfuncs_t *prinst, struct globalvars_s *pr_gl } }; -static void QCBUILTIN PF_HidePic(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_HidePic(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { client_t *cl; char *slot = PR_GetStringOfs(prinst, OFS_PARM0); int entnum; - if (*prinst->callargc==2) + if (prinst->callargc==2) { //to a single client entnum = G_EDICTNUM(prinst, OFS_PARM1)-1; if (entnum < 0 || entnum >= sv.allocated_client_slots) @@ -8244,7 +8284,7 @@ static void QCBUILTIN PF_HidePic(progfuncs_t *prinst, struct globalvars_s *pr_gl } else { - *prinst->callargc = 2; + prinst->callargc = 2; for (entnum = 0; entnum < sv.allocated_client_slots; entnum++) { G_INT(OFS_PARM1) = EDICT_TO_PROG(prinst, EDICT_NUM(prinst, entnum+1)); @@ -8254,7 +8294,7 @@ static void QCBUILTIN PF_HidePic(progfuncs_t *prinst, struct globalvars_s *pr_gl }; -static void QCBUILTIN PF_MovePic(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_MovePic(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *slot = PR_GetStringOfs(prinst, OFS_PARM0); float x = G_FLOAT(OFS_PARM1); @@ -8265,7 +8305,7 @@ static void QCBUILTIN PF_MovePic(progfuncs_t *prinst, struct globalvars_s *pr_gl ParamNegateFix( &x, &y, zone ); - if (*prinst->callargc==5) + if (prinst->callargc==5) { //to a single client entnum = G_EDICTNUM(prinst, OFS_PARM4)-1; if (entnum < 0 || entnum >= sv.allocated_client_slots) @@ -8282,7 +8322,7 @@ static void QCBUILTIN PF_MovePic(progfuncs_t *prinst, struct globalvars_s *pr_gl } else { - *prinst->callargc = 5; + prinst->callargc = 5; for (entnum = 0; entnum < sv.allocated_client_slots; entnum++) { G_INT(OFS_PARM4) = EDICT_TO_PROG(prinst, EDICT_NUM(prinst, entnum+1)); @@ -8291,14 +8331,14 @@ static void QCBUILTIN PF_MovePic(progfuncs_t *prinst, struct globalvars_s *pr_gl } }; -static void QCBUILTIN PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_ChangePic(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *slot = PR_GetStringOfs(prinst, OFS_PARM0); char *newpic= PR_GetStringOfs(prinst, OFS_PARM1); int entnum; client_t *cl; - if (*prinst->callargc==3) + if (prinst->callargc==3) { //to a single client entnum = G_EDICTNUM(prinst, OFS_PARM2)-1; if (entnum < 0 || entnum >= sv.allocated_client_slots) @@ -8313,7 +8353,7 @@ static void QCBUILTIN PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_ } else { - *prinst->callargc = 3; + prinst->callargc = 3; for (entnum = 0; entnum < sv.allocated_client_slots; entnum++) { G_INT(OFS_PARM2) = EDICT_TO_PROG(prinst, EDICT_NUM(prinst, entnum+1)); @@ -8335,7 +8375,7 @@ int SV_TagForName(int modelindex, char *tagname) return Mod_TagNumForName(model, tagname); } -static void QCBUILTIN PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *e = G_EDICT(prinst, OFS_PARM0); edict_t *tagentity = G_EDICT(prinst, OFS_PARM1); @@ -8367,7 +8407,7 @@ static void QCBUILTIN PF_setattachment(progfuncs_t *prinst, struct globalvars_s //the first implementation of this function was (float type, float num, string name) //it is now float num, float type, .field //EXT_CSQC_1 -static void QCBUILTIN PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_clientstat(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { #if 0 //this is the old code char *name = PF_VarString(prinst, 2, pr_globals); @@ -8378,7 +8418,7 @@ static void QCBUILTIN PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr } //EXT_CSQC_1 //void(float num, float type, string name) globalstat -static void QCBUILTIN PF_globalstat(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_globalstat(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char *name = PF_VarString(prinst, 2, pr_globals); #if 0 //this is the old code @@ -8389,7 +8429,7 @@ static void QCBUILTIN PF_globalstat(progfuncs_t *prinst, struct globalvars_s *pr } //EXT_CSQC_1 -static void QCBUILTIN PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { unsigned int i, n; extern vec3_t player_maxs, player_mins; @@ -8445,9 +8485,10 @@ static void QCBUILTIN PF_runclientphys(progfuncs_t *prinst, struct globalvars_s while(msecs) //break up longer commands { - pmove.cmd.msec = msecs; - if (pmove.cmd.msec > 50) + if (msecs > 50) pmove.cmd.msec = 50; + else + pmove.cmd.msec = msecs; msecs -= pmove.cmd.msec; PM_PlayerMove(1); @@ -8614,7 +8655,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd) qbyte qcpvs[(MAX_MAP_LEAFS+7)/8]; //#240 float(vector viewpos, entity viewee) checkpvs (FTE_QC_CHECKPVS) //note: this requires a correctly setorigined entity. -static void QCBUILTIN PF_checkpvs(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_checkpvs(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *viewpos = G_VECTOR(OFS_PARM0); edict_t *ent = G_EDICT(prinst, OFS_PARM1); @@ -8627,14 +8668,14 @@ static void QCBUILTIN PF_checkpvs(progfuncs_t *prinst, struct globalvars_s *pr_g } //entity(string match [, float matchnum]) matchclient = #241; -static void QCBUILTIN PF_matchclient(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_matchclient(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int clnum=-1; char *name = PR_GetStringOfs(prinst, OFS_PARM0); int matchnum = G_FLOAT(OFS_PARM1); client_t *cl; - if (*prinst->callargc < 2) + if (prinst->callargc < 2) { cl = SV_GetClientForString(name, &clnum); if (!cl) @@ -8660,7 +8701,7 @@ static void QCBUILTIN PF_matchclient(progfuncs_t *prinst, struct globalvars_s *p G_INT(OFS_RETURN) = 0; //world } -static void QCBUILTIN PF_SendPacket(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_SendPacket(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { netadr_t to; char *address = PR_GetStringOfs(prinst, OFS_PARM0); @@ -8704,10 +8745,12 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"precache_model", PF_precache_model, 20, 20, 20, 0, "void(string s)"}, {"stuffcmd", PF_stuffcmd, 21, 21, 21, 0, "void(entity client, string s)"}, {"findradius", PF_findradius, 22, 22, 22, 0, "entity(vector org, float rad)"}, - {"bprint", PF_bprint, 23, 23, 23, 0, "void(string s)"}, -//FIXME: distinguish between qw and nq parameters here? - {"sprint", PF_sprint, 24, 0, 24, 0, "void(entity client, string s)"}, - {"sprint", PF_sprint, 0, 24, 0, 0, "void(entity client, float lvl, string s)"}, + //both bprint and sprint accept different arguments in QW vs NQ/H2 + {"bprint", PF_bprint, 23, 0, 23, 0, "void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)"}, + {"bprint", PF_bprint, 0, 23, 23, 0, "void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"}, + {"sprint", PF_sprint, 24, 0, 24, 0, "void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"}, + {"sprint", PF_sprint, 0, 24, 0, 0, "void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6)"}, + //these have subtly different behaviour, and are implemented using different internal builtins, which is a bit weird in the extensions file. documentation is documentation. {"dprint", PF_dprint, 25, 0, 25, 0, "void(string s, ...)"}, {"dprint", PF_print, 0, 25, 0, 0, "void(string s, ...)"}, {"ftos", PF_ftos, 26, 26, 26, 0, "string(float val)"}, @@ -8795,7 +8838,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"lightstylevalue", PF_lightstylevalue, 0, 0, 71, 0, "float(float lstyle)"}, //70 {"cvar_set", PF_cvar_set, 72, 72, 72, 0, "void(string cvarname, string valuetoset)"}, //72 - {"centerprint", PF_centerprint, 73, 73, 73, 0, "void(entity ent, string text, ...)"}, //73 + {"centerprint", PF_centerprint, 73, 73, 73, 0, "void(entity ent, string text, optional string text2, optional string text3, optional string text4, optional string text5, optional string text6, optional string text7)"}, //73 {"ambientsound", PF_ambientsound, 74, 74, 74, 0, "void (vector pos, string samp, float vol, float atten)"}, //74 @@ -8803,7 +8846,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"precache_sound2", PF_precache_sound, 76, 76, 76, 0, "void(string str)"}, //76 // precache_sound2 is different only for qcc {"precache_file2", PF_precache_file, 77, 77, 0, 0, "void(string str)"}, //77 - {"setspawnparms", PF_setspawnparms, 78, 78, 78, 0, "void()"}, //78 + {"setspawnparms", PF_setspawnparms, 78, 78, 78, 0, "void(entity player)"}, //78 {"plaque_draw", PF_h2plaque_draw, 0, 0, 79, 0, "void(entity targ, float stringno)"}, //79 {"logfrag", PF_logfrag, 0, 79, 0, 79, "void(entity killer, entity killee)"}, //79 @@ -8987,7 +9030,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"clientstat", PF_clientstat, 0, 0, 0, 232, "void(float num, float type, .void fld)"}, //EXT_CSQC {"globalstat", PF_globalstat, 0, 0, 0, 233, "void(float num, float type, string name)"}, //EXT_CSQC_1 actually //END EXT_CSQC - {"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234, "void(entity player)"}, + {"isbackbuffered", PF_isbackbuffered, 0, 0, 0, 234, "float(entity player)"}, {"rotatevectorsbyangle",PF_rotatevectorsbyangles,0,0, 0, 235, "void(vector angle)"}, // #235 {"rotatevectorsbyvectors",PF_rotatevectorsbymatrix,0,0, 0, 236, "void(vector fwd, vector right, vector up)"}, // #236 {"skinforname", PF_skinforname, 0, 0, 0, 237, "float(float mdlindex, string skinname)"}, // #237 @@ -9000,11 +9043,17 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs // {"bulleten", PF_bulleten, 0, 0, 0, 243}, (removed builtin) - {"rotatevectorsbytag", PF_Fixme, 0, 0, 0, 244, "vector(entity ent, float tagnum)"}, // #234 + {"rotatevectorsbytag", PF_Fixme, 0, 0, 0, 244, "vector(entity ent, float tagnum)"}, + +// {"empty", PF_Fixme, 0, 0, 0, 245, "void()"}, +// {"empty", PF_Fixme, 0, 0, 0, 246, "void()"}, +// {"empty", PF_Fixme, 0, 0, 0, 247, "void()"}, +// {"empty", PF_Fixme, 0, 0, 0, 248, "void()"}, +// {"empty", PF_Fixme, 0, 0, 0, 249, "void()"}, {"sqlconnect", PF_sqlconnect, 0, 0, 0, 250, "float(optional string host, optional string user, optional string pass, optional string defaultdb, optional string driver)"}, // sqlconnect (FTE_SQL) {"sqldisconnect", PF_sqldisconnect, 0, 0, 0, 251, "void(float serveridx)"}, // sqldisconnect (FTE_SQL) - {"sqlopenquery", PF_sqlopenquery, 0, 0, 0, 252, "float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query)"}, // sqlopenquery (FTE_SQL) + {"sqlopenquery", PF_sqlopenquery, 0, 0, 0, 252, "float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof, float firstrow) callback, float querytype, string query)"}, // sqlopenquery (FTE_SQL) {"sqlclosequery", PF_sqlclosequery, 0, 0, 0, 253, "void(float serveridx, float queryidx)"}, // sqlclosequery (FTE_SQL) {"sqlreadfield", PF_sqlreadfield, 0, 0, 0, 254, "string(float serveridx, float queryidx, float row, float column)"}, // sqlreadfield (FTE_SQL) {"sqlerror", PF_sqlerror, 0, 0, 0, 255, "string(float serveridx, optional float queryidx)"}, // sqlerror (FTE_SQL) @@ -9033,10 +9082,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"frameforname", PF_frameforname, 0, 0, 0, 276, "float(float modidx, string framename)"},// (FTE_CSQC_SKELETONOBJECTS) {"frameduration", PF_frameduration, 0, 0, 0, 277, "float(float modidx, float framenum)"},// (FTE_CSQC_SKELETONOBJECTS) - {"terrain_edit", PF_terrain_edit, 0, 0, 0, 278, "void(float action, vector pos, float radius, float quant)"},// (??FTE_TERRAIN_EDIT?? + {"terrain_edit", PF_terrain_edit, 0, 0, 0, 278, "void(float action, optional vector pos, optional float radius, optional float quant, ...)"},// (??FTE_TERRAIN_EDIT?? {"touchtriggers", PF_touchtriggers, 0, 0, 0, 279, "void()"},// {"writefloat", PF_WriteFloat, 0, 0, 0, 280, "void(float buf, float fl)"},// - {"skel_ragupdate", PF_skel_ragedit, 0, 0, 0, 281, "float(entity skelent, string dollname, float parentskel)" NYI}, // (FTE_CSQC_RAGDOLL) + {"skel_ragupdate", PF_skel_ragedit, 0, 0, 0, 281, "float(entity skelent, string dollcmd, float animskel)" NYI}, // (FTE_CSQC_RAGDOLL) {"skel_mmap", PF_skel_mmap, 0, 0, 0, 282, "float*(float skel)"},// (FTE_QC_RAGDOLL) {"skel_set_bone_world",PF_skel_set_bone_world,0,0, 0, 283, "void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up)"}, {"frametoname", PF_frametoname, 0, 0, 0, 284, "string(float modidx, float framenum)"}, @@ -9053,9 +9102,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"dynamiclight_add",PF_Fixme, 0, 0, 0, 305, "float(vector org, float radius, vector lightcolours)"},// (EXT_CSQC) - {"R_BeginPolygon", PF_Fixme, 0, 0, 0, 306, "void(string texturename, optional float flags)"},// (EXT_CSQC_???) - {"R_PolygonVertex", PF_Fixme, 0, 0, 0, 307, "void(vector org, vector texcoords, vector rgb, float alpha)"},// (EXT_CSQC_???) - {"R_EndPolygon", PF_Fixme, 0, 0, 0, 308, "void()"},// (EXT_CSQC_???) + //gonna expose these to ssqc as a debugging extension + {"R_BeginPolygon", PF_R_PolygonBegin,0,0, 0, 306, "void(string texturename, optional float flags)"},// (EXT_CSQC_???) + {"R_PolygonVertex", PF_R_PolygonVertex,0,0, 0, 307, "void(vector org, vector texcoords, vector rgb, float alpha)"},// (EXT_CSQC_???) + {"R_EndPolygon", PF_R_PolygonEnd,0, 0, 0, 308, "void()"},// (EXT_CSQC_???) {"getproperty", PF_Fixme, 0, 0, 0, 309, "#define getviewprop getproperty\n__variant(float property)"},// (EXT_CSQC_1) @@ -9119,6 +9169,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"wasfreed", PF_WasFreed,0, 0, 0, 353, "float(entity ent)"},//(EXT_CSQC) (should be availabe on server too) {"serverkey", PF_Fixme, 0, 0, 0, 354, "string(string key)"},// {"getentitytoken", PF_Fixme, 0, 0, 0, 355, "string()"},//; + {"findfont", PF_Fixme, 0, 0, 0, 356, "float(string s)"},//; + {"loadfont", PF_Fixme, 0, 0, 0, 357, "float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)"}, {"sendevent", PF_Fixme, 0, 0, 0, 359, "void(string evname, string evargs, ...)"},// (EXT_CSQC_1) {"readbyte", PF_Fixme, 0, 0, 0, 360, "float()"},// (EXT_CSQC) @@ -9139,6 +9191,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"dynamiclight_get",PF_Fixme, 0, 0, 0, 372, "__variant(float lno, float fld)"}, {"dynamiclight_set",PF_Fixme, 0, 0, 0, 373, "void(float lno, float fld, __variant value)"}, {"particleeffectquery",PF_Fixme,0, 0, 0, 374, "string(float efnum, float body)"}, + + {"adddecal", PF_Fixme, 0, 0, 0, 375, "void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha)"}, //END EXT_CSQC {"memalloc", PF_memalloc, 0, 0, 0, 384, "void*(int size)"}, @@ -9200,185 +9254,166 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"te_lightning2", PF_te_lightning2, 0, 0, 0, 429, "void(entity own, vector start, vector end)"},// #429 te_lightning2 {"te_lightning3", PF_te_lightning3, 0, 0, 0, 430, "void(entity own, vector start, vector end)"},// #430 te_lightning3 {"te_beam", PF_te_beam, 0, 0, 0, 431, "void(entity own, vector start, vector end)"},// #431 te_beam -//DP_QC_VECTORVECTORS {"vectorvectors", PF_vectorvectors, 0, 0, 0, 432, "void(vector dir)"},// (DP_QC_VECTORVECTORS) - {"te_plasmaburn", PF_te_plasmaburn, 0, 0, 0, 433, "void(vector org)"},// (DP_TE_PLASMABURN) - {"getsurfacenumpoints",PF_getsurfacenumpoints,0,0, 0, 434, "float(entity e, float s)"},// (DP_QC_GETSURFACE) {"getsurfacepoint",PF_getsurfacepoint, 0, 0, 0, 435, "vector(entity e, float s, float n)"},// (DP_QC_GETSURFACE) {"getsurfacenormal",PF_getsurfacenormal,0, 0, 0, 436, "vector(entity e, float s)"},// (DP_QC_GETSURFACE) {"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437, "string(entity e, float s)"},// (DP_QC_GETSURFACE) {"getsurfacenearpoint",PF_getsurfacenearpoint,0,0, 0, 438, "float(entity e, vector p)"},// (DP_QC_GETSURFACE) {"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439, "vector(entity e, float s, vector p)" STUB},// (DP_QC_GETSURFACE) - -//KRIMZON_SV_PARSECLIENTCOMMAND {"clientcommand", PF_clientcommand, 0, 0, 0, 440, "void(entity e, string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND) {"tokenize", PF_Tokenize, 0, 0, 0, 441, "float(string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND) {"argv", PF_ArgV, 0, 0, 0, 442, "string(float n)"},// (KRIMZON_SV_PARSECLIENTCOMMAND - -//DP_GFX_QUAKE3MODELTAGS {"setattachment", PF_setattachment, 0, 0, 0, 443, "void(entity e, entity tagentity, string tagname)"},// (DP_GFX_QUAKE3MODELTAGS) - {"search_begin", PF_search_begin, 0, 0, 0, 444, "float(string pattern, float caseinsensitive, float quiet)"}, {"search_end", PF_search_end, 0, 0, 0, 445, "void(float handle)"}, {"search_getsize", PF_search_getsize, 0, 0, 0, 446, "float(float handle)"}, {"search_getfilename", PF_search_getfilename,0, 0, 0, 447, "string(float handle, float num)"}, -//DP_QC_CVAR_STRING - {"cvar_string", PF_cvar_string, 0, 0, 0, 448, "string(string cvarname)"},// - -//DP_QC_FINDFLAGS - {"findflags", PF_FindFlags, 0, 0, 0, 449, "entity(entity start, .float fld, float match)"},// -//DP_QC_FINDCHAINFLAGS - {"findchainflags", PF_sv_findchainflags,0, 0, 0, 450, "entity(.float fld, float match)"},// -//DP_MD3_TAGSINFO + {"cvar_string", PF_cvar_string, 0, 0, 0, 448, "string(string cvarname)"},//DP_QC_CVAR_STRING + {"findflags", PF_FindFlags, 0, 0, 0, 449, "entity(entity start, .float fld, float match)"},//DP_QC_FINDFLAGS + {"findchainflags", PF_sv_findchainflags,0, 0, 0, 450, "entity(.float fld, float match)"},//DP_QC_FINDCHAINFLAGS {"gettagindex", PF_gettagindex, 0, 0, 0, 451, "float(entity ent, string tagname)"},// (DP_MD3_TAGSINFO) {"gettaginfo", PF_gettaginfo, 0, 0, 0, 452, "vector(entity ent, float tagindex)"},// (DP_MD3_TAGSINFO) -//DP_SV_BOTCLIENT {"dropclient", PF_dropclient, 0, 0, 0, 453, "void(entity player)"},//DP_SV_BOTCLIENT - {"spawnclient", PF_spawnclient, 0, 0, 0, 454, "entity()"},//DP_SV_BOTCLIENT {"clienttype", PF_clienttype, 0, 0, 0, 455, "float(entity client)"},//botclient - {"WriteUnterminatedString",PF_WriteString2,0, 0, 0, 456, "void(float target, string str)"}, //writestring but without the null terminator. makes things a little nicer. - -//DP_TE_FLAMEJET -// {"te_flamejet", PF_te_flamejet, 0, 0, 0, 457, "void(vector org, vector vel, float howmany)"}, - - //no 458 documented. - -//DP_QC_EDICT_NUM - {"edict_num", PF_edict_for_num, 0, 0, 0, 459, "entity(float entnum)"},// - -//DP_QC_STRINGBUFFERS - {"buf_create", PF_buf_create, 0, 0, 0, 460, "float()"},// - {"buf_del", PF_buf_del, 0, 0, 0, 461, "void(float bufhandle)"},// - {"buf_getsize", PF_buf_getsize, 0, 0, 0, 462, "float(float bufhandle)"},// - {"buf_copy", PF_buf_copy, 0, 0, 0, 463, "void(float bufhandle_from, float bufhandle_to)"},// - {"buf_sort", PF_buf_sort, 0, 0, 0, 464, "void(float bufhandle, float sortpower, float backward)"},// - {"buf_implode", PF_buf_implode, 0, 0, 0, 465, "string(float bufhandle, string glue)"},// - {"bufstr_get", PF_bufstr_get, 0, 0, 0, 466, "string(float bufhandle, float string_index)"},// - {"bufstr_set", PF_bufstr_set, 0, 0, 0, 467, "void(float bufhandle, float string_index, string str)"},// - {"bufstr_add", PF_bufstr_add, 0, 0, 0, 468, "float(float bufhandle, string str, float order)"},// - {"bufstr_free", PF_bufstr_free, 0, 0, 0, 469, "void(float bufhandle, float string_index)"},// - - //no 470 documented - -//DP_QC_ASINACOSATANATAN2TAN - {"asin", PF_asin, 0, 0, 0, 471, "float(float s)"}, - {"acos", PF_acos, 0, 0, 0, 472, "float(float c)"}, - {"atan", PF_atan, 0, 0, 0, 473, "float(float t)"}, - {"atan2", PF_atan2, 0, 0, 0, 474, "float(float c, float s)"}, - {"tan", PF_tan, 0, 0, 0, 475, "float(float a)"}, - - -//DP_QC_STRINGCOLORFUNCTIONS - {"strlennocol", PF_strlennocol, 0, 0, 0, 476, "float(string s)"}, - {"strdecolorize", PF_strdecolorize, 0, 0, 0, 477, "string(string s)"}, - -//DP_QC_STRFTIME - {"strftime", PF_strftime, 0, 0, 0, 478, "string(float uselocaltime, string format, ...)"}, - -//DP_QC_TOKENIZEBYSEPARATOR - {"tokenizebyseparator",PF_tokenizebyseparator,0,0, 0, 479, "float(string s, string separator1, ...)"}, - -//DP_QC_STRING_CASE_FUNCTIONS - {"strtolower", PF_strtolower, 0, 0, 0, 480, "string(string s)"}, - {"strtoupper", PF_strtoupper, 0, 0, 0, 481, "string(string s)"}, - -//DP_QC_CVAR_DEFSTRING - {"cvar_defstring", PF_cvar_defstring, 0, 0, 0, 482, "string(string s)"}, - -//DP_SV_POINTSOUND - {"pointsound", PF_pointsound, 0, 0, 0, 483, "void(vector origin, string sample, float volume, float attenuation)"}, - -//DP_QC_STRREPLACE - {"strreplace", PF_strreplace, 0, 0, 0, 484, "string(string search, string replace, string subject)"}, - {"strireplace", PF_strireplace, 0, 0, 0, 485, "string(string search, string replace, string subject)"}, - - -//DP_QC_GETSURFACEPOINTATTRIBUTE - {"getsurfacepointattribute",PF_getsurfacepointattribute,0,0,0, 486, "vector(entity e, float s, float n, float a)"}, - -//DP_GECKO_SUPPORT - {"gecko_create", PF_gecko_create, 0, 0, 0, 487, "float(string name)"}, - {"gecko_destroy", PF_gecko_destroy, 0, 0, 0, 488, "void(string name)"}, - {"gecko_navigate", PF_gecko_navigate, 0, 0, 0, 489, "void(string name, string URI)"}, - {"gecko_keyevent", PF_gecko_keyevent, 0, 0, 0, 490, "float(string name, float key, float eventtype)"}, - {"gecko_mousemove", PF_gecko_mousemove, 0, 0, 0, 491, "void(string name, float x, float y)"}, - {"gecko_resize", PF_gecko_resize, 0, 0, 0, 492, "void(string name, float w, float h)"}, - {"gecko_get_texture_extent",PF_gecko_get_texture_extent,0,0,0, 493, "vector(string name)"}, - -//DP_QC_CRC16 - {"crc16", PF_crc16, 0, 0, 0, 494, "float(float caseinsensitive, string s, ...)"}, - -//DP_QC_CVAR_TYPE - {"cvar_type", PF_cvar_type, 0, 0, 0, 495, "float(string name)"},// - -//DP_QC_ENTITYDATA - {"numentityfields", PF_numentityfields, 0, 0, 0, 496, "float()"},// - {"entityfieldname", PF_entityfieldname, 0, 0, 0, 497, "string(float fieldnum)"},// - {"entityfieldtype", PF_entityfieldtype, 0, 0, 0, 498, "float(float fieldnum)"},// - {"getentityfieldstring",PF_getentityfieldstring,0,0, 0, 499, "string(float fieldnum, entity ent)"},// - {"putentityfieldstring",PF_putentityfieldstring,0,0, 0, 500, "float(float fieldnum, entity ent, string s)"},// - -//DP_SV_WRITEPICTURE - {"WritePicture", PF_WritePicture, 0, 0, 0, 501, "void(float to, string s, float sz)"},// - {"ReadPicture", PF_Fixme, 0, 0, 0, 501, "string()"},// - +// {"te_flamejet", PF_te_flamejet, 0, 0, 0, 457, "void(vector org, vector vel, float howmany)"},//DP_TE_FLAMEJET +// {"undefined", PF_Fixme, 0, 0, 0, 458, ""}, + {"edict_num", PF_edict_for_num, 0, 0, 0, 459, "entity(float entnum)"},//DP_QC_EDICT_NUM + {"buf_create", PF_buf_create, 0, 0, 0, 460, "float()"},//DP_QC_STRINGBUFFERS + {"buf_del", PF_buf_del, 0, 0, 0, 461, "void(float bufhandle)"},//DP_QC_STRINGBUFFERS + {"buf_getsize", PF_buf_getsize, 0, 0, 0, 462, "float(float bufhandle)"},//DP_QC_STRINGBUFFERS + {"buf_copy", PF_buf_copy, 0, 0, 0, 463, "void(float bufhandle_from, float bufhandle_to)"},//DP_QC_STRINGBUFFERS + {"buf_sort", PF_buf_sort, 0, 0, 0, 464, "void(float bufhandle, float sortpower, float backward)"},//DP_QC_STRINGBUFFERS + {"buf_implode", PF_buf_implode, 0, 0, 0, 465, "string(float bufhandle, string glue)"},//DP_QC_STRINGBUFFERS + {"bufstr_get", PF_bufstr_get, 0, 0, 0, 466, "string(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS + {"bufstr_set", PF_bufstr_set, 0, 0, 0, 467, "void(float bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS + {"bufstr_add", PF_bufstr_add, 0, 0, 0, 468, "float(float bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS + {"bufstr_free", PF_bufstr_free, 0, 0, 0, 469, "void(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS +// {"undefined", PF_Fixme, 0, 0, 0, 470, ""}, +//MENU VM BUILTINS SHARE THE BELOW BUILTINS + {"asin", PF_asin, 0, 0, 0, 471, "float(float s)"},//DP_QC_ASINACOSATANATAN2TAN + {"acos", PF_acos, 0, 0, 0, 472, "float(float c)"},//DP_QC_ASINACOSATANATAN2TAN + {"atan", PF_atan, 0, 0, 0, 473, "float(float t)"},//DP_QC_ASINACOSATANATAN2TAN + {"atan2", PF_atan2, 0, 0, 0, 474, "float(float c, float s)"},//DP_QC_ASINACOSATANATAN2TAN + {"tan", PF_tan, 0, 0, 0, 475, "float(float a)"},//DP_QC_ASINACOSATANATAN2TAN + {"strlennocol", PF_strlennocol, 0, 0, 0, 476, "float(string s)"},//DP_QC_STRINGCOLORFUNCTIONS + {"strdecolorize", PF_strdecolorize, 0, 0, 0, 477, "string(string s)"},//DP_QC_STRINGCOLORFUNCTIONS + {"strftime", PF_strftime, 0, 0, 0, 478, "string(float uselocaltime, string format, ...)"}, //DP_QC_STRFTIME + {"tokenizebyseparator",PF_tokenizebyseparator,0,0, 0, 479, "float(string s, string separator1, ...)"}, //DP_QC_TOKENIZEBYSEPARATOR + {"strtolower", PF_strtolower, 0, 0, 0, 480, "string(string s)"}, //DP_QC_STRING_CASE_FUNCTIONS + {"strtoupper", PF_strtoupper, 0, 0, 0, 481, "string(string s)"}, //DP_QC_STRING_CASE_FUNCTIONS + {"cvar_defstring", PF_cvar_defstring, 0, 0, 0, 482, "string(string s)"}, //DP_QC_CVAR_DEFSTRING + {"pointsound", PF_pointsound, 0, 0, 0, 483, "void(vector origin, string sample, float volume, float attenuation)"},//DP_SV_POINTSOUND + {"strreplace", PF_strreplace, 0, 0, 0, 484, "string(string search, string replace, string subject)"},//DP_QC_STRREPLACE + {"strireplace", PF_strireplace, 0, 0, 0, 485, "string(string search, string replace, string subject)"},//DP_QC_STRREPLACE + {"getsurfacepointattribute",PF_getsurfacepointattribute,0,0,0, 486, "vector(entity e, float s, float n, float a)"},//DP_QC_GETSURFACEPOINTATTRIBUTE + {"gecko_create", PF_gecko_create, 0, 0, 0, 487, "float(string name)"},//DP_GECKO_SUPPORT + {"gecko_destroy", PF_gecko_destroy, 0, 0, 0, 488, "void(string name)"},//DP_GECKO_SUPPORT + {"gecko_navigate", PF_gecko_navigate, 0, 0, 0, 489, "void(string name, string URI)"},//DP_GECKO_SUPPORT + {"gecko_keyevent", PF_gecko_keyevent, 0, 0, 0, 490, "float(string name, float key, float eventtype)"},//DP_GECKO_SUPPORT + {"gecko_mousemove", PF_gecko_mousemove, 0, 0, 0, 491, "void(string name, float x, float y)"},//DP_GECKO_SUPPORT + {"gecko_resize", PF_gecko_resize, 0, 0, 0, 492, "void(string name, float w, float h)"},//DP_GECKO_SUPPORT + {"gecko_get_texture_extent",PF_gecko_get_texture_extent,0,0,0, 493, "vector(string name)"},//DP_GECKO_SUPPORT + {"crc16", PF_crc16, 0, 0, 0, 494, "float(float caseinsensitive, string s, ...)"},//DP_QC_CRC16 + {"cvar_type", PF_cvar_type, 0, 0, 0, 495, "float(string name)"},//DP_QC_CVAR_TYPE + {"numentityfields", PF_numentityfields, 0, 0, 0, 496, "float()"},//DP_QC_ENTITYDATA + {"entityfieldname", PF_entityfieldname, 0, 0, 0, 497, "string(float fieldnum)"},//DP_QC_ENTITYDATA + {"entityfieldtype", PF_entityfieldtype, 0, 0, 0, 498, "float(float fieldnum)"},//DP_QC_ENTITYDATA + {"getentityfieldstring",PF_getentityfieldstring,0,0, 0, 499, "string(float fieldnum, entity ent)"},//DP_QC_ENTITYDATA + {"putentityfieldstring",PF_putentityfieldstring,0,0, 0, 500, "float(float fieldnum, entity ent, string s)"},//DP_QC_ENTITYDATA + {"WritePicture", PF_WritePicture, 0, 0, 0, 501, "void(float to, string s, float sz)"},//DP_SV_WRITEPICTURE + {"ReadPicture", PF_Fixme, 0, 0, 0, 501, "string()"},//DP_SV_WRITEPICTURE // {"boxparticles", PF_Fixme, 0, 0, 0, 502, "void(float effectindex, entity own, vector org_from, vector org_to, vector dir_from, vector dir_to, float countmultiplier, float flags)"}, - -//DP_QC_WHICHPACK - {"whichpack", PF_whichpack, 0, 0, 0, 503, "string(string filename)"},// -//DP_CSQC_QUERYRENDERENTITY - {"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, float fieldnum)"}, - -//DP_QC_URI_ESCAPE - {"uri_escape", PF_uri_escape, 0, 0, 0, 510, "string(string in)"},// - {"uri_unescape", PF_uri_unescape, 0, 0, 0, 511, "string(string in)"},// - -//DP_QC_NUM_FOR_EDICT - {"num_for_edict", PF_num_for_edict, 0, 0, 0, 512, "float(entity ent)"},// - -//DP_QC_URI_GET - {"uri_get", PF_uri_get, 0, 0, 0, 513, "float(string uril, float id)" STUB},// - + {"whichpack", PF_whichpack, 0, 0, 0, 503, "string(string filename)"},//DP_QC_WHICHPACK + {"getentity", PF_Fixme, 0, 0, 0, 504, "__variant(float entnum, float fieldnum)"},//DP_CSQC_QUERYRENDERENTITY +// {"undefined", PF_Fixme, 0, 0, 0, 505, ""}, +// {"undefined", PF_Fixme, 0, 0, 0, 506, ""}, +// {"undefined", PF_Fixme, 0, 0, 0, 507, ""}, +// {"undefined", PF_Fixme, 0, 0, 0, 508, ""}, +// {"undefined", PF_Fixme, 0, 0, 0, 509, ""}, + {"uri_escape", PF_uri_escape, 0, 0, 0, 510, "string(string in)"},//DP_QC_URI_ESCAPE + {"uri_unescape", PF_uri_unescape, 0, 0, 0, 511, "string(string in)"},//DP_QC_URI_ESCAPE + {"num_for_edict", PF_num_for_edict, 0, 0, 0, 512, "float(entity ent)"},//DP_QC_NUM_FOR_EDICT + {"uri_get", PF_uri_get, 0, 0, 0, 513, "float(string uril, float id)" STUB},//DP_QC_URI_GET {"tokenize_console",PF_tokenize_console,0, 0, 0, 514, "float(string str)"}, {"argv_start_index",PF_argv_start_index,0, 0, 0, 515, "float(float idx)"}, {"argv_end_index", PF_argv_end_index, 0, 0, 0, 516, "float(float idx)"}, {"buf_cvarlist", PF_buf_cvarlist, 0, 0, 0, 517, "void(float strbuf)" STUB}, {"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"}, {"gettime", PF_Fixme, 0, 0, 0, 519, "float(optional float timetype)"}, - +// {"keynumtostring", PF_Fixme, 0, 0, 0, 520, "string(float keynum)"}, +// {"findkeysforcommand",PF_Fixme, 0, 0, 0, 521, "string(string command, optional float bindmap)"}, +// {"initparticlespawner",PF_Fixme, 0, 0, 0, 522, "void(float max_themes)"}, +// {"resetparticle", PF_Fixme, 0, 0, 0, 523, "void()"}, +// {"particletheme", PF_Fixme, 0, 0, 0, 524, "void(float theme)"}, +// {"particlethemesave",PF_Fixme, 0, 0, 0, 525, "void(float theme)"}, +// {"particlethemefree",PF_Fixme, 0, 0, 0, 526, "void()"}, +// {"particle", PF_Fixme, 0, 0, 0, 527, "float(vector org, vector vel, optional float theme)"}, +// {"delayedparticle", PF_Fixme, 0, 0, 0, 528, "float(vector org, vector vel, float delay, float collisiondelay, optional float theme)"}, {"loadfromdata", PF_loadfromdata, 0, 0, 0, 529, "void(string s)"}, {"loadfromfile", PF_loadfromfile, 0, 0, 0, 530, "void(string s)"}, // {"setpause", VM_SV_setpause, 0, 0, 0, 531, "void(float pause)" STUB}, - //end dp extras + //begin mvdsv extras {"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"}, + //end mvdsv extras //restart dp extras -// {"log", VM_Fixme, 0, 0, 0, 532, "float(string mname)", true}, +// {"log", PF_Fixme, 0, 0, 0, 532, "float(string mname)", true}, // {"getsoundtime", VM_getsoundtime, 0, 0, 0, 533, "float(entity e, float channel)" STUB}, // {"soundlength", VM_soundlength, 0, 0, 0, 534, "float(string sample)" STUB}, - - +// {"buf_loadfile", PF_Fixme, 0, 0, 0, 535, "float(string filename, float bufhandle)"}, +// {"buf_writefile", PF_Fixme, 0, 0, 0, 536, "float(float filehandle, float bufhandle, float startpos, float numstrings)"}, +// {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"}, +// {"matchpattern", PF_Fixme, 0, 0, 0, 538, "float(string s, string pattern, float matchrule)"}, +// {"undefined", PF_Fixme, 0, 0, 0, 539, ""}, {"physics_enable", PF_Ignore, 0, 0, 0, 540, "void(entity e, float physics_enabled)" STUB}, {"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB}, {"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB}, +// {"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"}, +// {"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"}, +// {"setmousetarget", PF_Fixme, 0, 0, 0, 603, "void(float trg)"}, +// {"getmousetarget", PF_Fixme, 0, 0, 0, 604, "float()"}, {"callfunction", PF_callfunction, 0, 0, 0, 605, "void(.../*, string funcname*/)"}, {"writetofile", PF_writetofile, 0, 0, 0, 606, "void(float fh, entity e)"}, {"isfunction", PF_isfunction, 0, 0, 0, 607, "float(string s)"}, - {"parseentitydata", PF_parseentitydata, 0, 0, 0, 608, "void(entity e, string s)"}, - -//VM_SV_getextresponse, // #624 string getextresponse(void) - +// {"getresolution", PF_Fixme, 0, 0, 0, 608, "vector(float number, optional float forfullscreen)"}, +// {"keynumtostring", PF_Fixme, 0, 0, 0, 609, "string(float keynum)"}, +// {"findkeysforcommand",PF_Fixme, 0, 0, 0, 610, "string()"}, +// {"gethostcachevalue",PF_Fixme, 0, 0, 0, 611, "float(float type)"}, +// {"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"}, + {"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, "void(entity e, string s)"}, +// {"stringtokeynum", PF_Fixme, 0, 0, 0, 614, "float(string key)"}, +// {"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"}, +// {"sethostcachemaskstring",PF_Fixme, 0, 0, 0, 616, "void(float mask, float fld, string str, float op)"}, +// {"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"}, +// {"resorthostcache", PF_Fixme, 0, 0, 0, 618, "void()"}, +// {"sethostcachesort",PF_Fixme, 0, 0, 0, 619, "void(float fld, float descending)"}, +// {"refreshhostcache",PF_Fixme, 0, 0, 0, 620, "void()"}, +// {"gethostcachenumber",PF_Fixme, 0, 0, 0, 621, "float(float fld, float hostnr)"}, +// {"gethostcacheindexforkey",PF_Fixme, 0, 0, 0, 622, "float(string key)"}, +// {"addwantedhostcachekey",PF_Fixme, 0, 0, 0, 623, "void(string key)"}, +// {"getextresponse", PF_Fixme, 0, 0, 0, 624, "string()"}, +// {"netaddress_resolve",PF_Fixme, 0, 0, 0, 625, "string(string, float)"}, +// {"getgamedirinfo", PF_Fixme, 0, 0, 0, 626, "string(float n, float prop)"}, {"sprintf", PF_sprintf, 0, 0, 0, 627, "string(string fmt, ...)"}, - {"getsurfacenumtriangles",PF_getsurfacenumtriangles,0,0, 0, 628, "float(entity e, float s)"}, - {"getsurfacetriangle",PF_getsurfacetriangle,0,0, 0, 629, "vector(entity e, float s, float n)"}, - -//VM_digest_hex, // #639 - + {"getsurfacenumtriangles",PF_getsurfacenumtriangles,0,0,0, 628, "float(entity e, float s)"}, + {"getsurfacetriangle",PF_getsurfacetriangle,0, 0, 0, 629, "vector(entity e, float s, float n)"}, +// {"setkeybind", PF_Fixme, 0, 0, 0, 630, "float(float key, string bind, optional float bindmap)"}, +// {"getbindmaps", PF_Fixme, 0, 0, 0, 631, "vector()"}, +// {"setbindmaps", PF_Fixme, 0, 0, 0, 632, "float(vector bm)"}, +// {"crypto_getkeyfp", PF_Fixme, 0, 0, 0, 633, "string(string addr)"}, +// {"crypto_getidfp", PF_Fixme, 0, 0, 0, 634, "string(string addr)"}, +// {"crypto_getencryptlevel",PF_Fixme, 0, 0, 0, 635, "string(string addr)"}, +// {"crypto_getmykeyfp",PF_Fixme, 0, 0, 0, 636, "string(string addr)"}, +// {"crypto_getmyidfp",PF_Fixme, 0, 0, 0, 637, "string(float addr)"}, +// {"VM_CL_RotateMoves",PF_Fixme, 0, 0, 0, 638, ""}, + {"digest_hex", PF_digest_hex, 0, 0, 0, 639, "string(string digest, string data, ...)"}, +// {"V_CalcRefdef", PF_Fixme, 0, 0, 0, 640, "void(entity e)"}, + {"crypto_getmyidstatus",PF_Fixme, 0, 0, 0, 641, "float(float i)"}, //end dp extras @@ -9597,7 +9632,7 @@ void PR_SVExtensionList_f(void) if (i < 32) { - if (!(Net_PextMask(1) & (1<entnum; } -static int Q1QVMPF_EdictToProgs(progfuncs_t *pf, edict_t *e) +static int QDECL Q1QVMPF_EdictToProgs(pubprogfuncs_t *pf, edict_t *e) { return e->entnum*sv.world.edict_size; } -static edict_t *Q1QVMPF_ProgsToEdict(progfuncs_t *pf, int num) +static edict_t *QDECL Q1QVMPF_ProgsToEdict(pubprogfuncs_t *pf, int num) { if (num % sv.world.edict_size) Con_Printf("Edict To Progs with remainder\n"); @@ -386,7 +386,7 @@ void Q1QVMED_ClearEdict (edict_t *e, qboolean wipe) e->entnum = num; } -static void Q1QVMPF_EntRemove(progfuncs_t *pf, edict_t *e) +static void QDECL Q1QVMPF_EntRemove(pubprogfuncs_t *pf, edict_t *e) { if (!ED_CanFree(e)) return; @@ -394,7 +394,7 @@ static void Q1QVMPF_EntRemove(progfuncs_t *pf, edict_t *e) e->freetime = sv.time; } -static edict_t *Q1QVMPF_EntAlloc(progfuncs_t *pf) +static edict_t *QDECL Q1QVMPF_EntAlloc(pubprogfuncs_t *pf) { int i; edict_t *e; @@ -445,7 +445,7 @@ static edict_t *Q1QVMPF_EntAlloc(progfuncs_t *pf) return (struct edict_s *)e; } -static int Q1QVMPF_LoadEnts(progfuncs_t *pf, char *mapstring, float spawnflags) +static int QDECL Q1QVMPF_LoadEnts(pubprogfuncs_t *pf, char *mapstring, float spawnflags) { q1qvmentstring = mapstring; VM_Call(q1qvm, GAME_LOADENTS); @@ -453,7 +453,7 @@ static int Q1QVMPF_LoadEnts(progfuncs_t *pf, char *mapstring, float spawnflags) return sv.world.edict_size; } -static eval_t *Q1QVMPF_GetEdictFieldValue(progfuncs_t *pf, edict_t *e, char *fieldname, evalc_t *cache) +static eval_t *QDECL Q1QVMPF_GetEdictFieldValue(pubprogfuncs_t *pf, edict_t *e, char *fieldname, evalc_t *cache) { if (!strcmp(fieldname, "message")) { @@ -462,22 +462,22 @@ static eval_t *Q1QVMPF_GetEdictFieldValue(progfuncs_t *pf, edict_t *e, char *fie return NULL; } -static eval_t *Q1QVMPF_FindGlobal (progfuncs_t *prinst, char *name, progsnum_t num, etype_t *type) +static eval_t *QDECL Q1QVMPF_FindGlobal (pubprogfuncs_t *prinst, char *name, progsnum_t num, etype_t *type) { return NULL; } -static globalvars_t *Q1QVMPF_Globals(progfuncs_t *prinst, int prnum) +static globalvars_t *QDECL Q1QVMPF_Globals(pubprogfuncs_t *prinst, int prnum) { return NULL; } -static string_t Q1QVMPF_StringToProgs(progfuncs_t *prinst, char *str) +static string_t QDECL Q1QVMPF_StringToProgs(pubprogfuncs_t *prinst, char *str) { return (string_t)(str - (char*)VM_MemoryBase(q1qvm)); } -static char *ASMCALL Q1QVMPF_StringToNative(progfuncs_t *prinst, string_t str) +static char *ASMCALL QDECL Q1QVMPF_StringToNative(pubprogfuncs_t *prinst, string_t str) { return (char*)VM_MemoryBase(q1qvm) + str; } @@ -511,7 +511,7 @@ static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qi break; } } - svprogfuncs->callargc = &argnum; + svprogfuncs->callargc = argnum; gv.ret.i = 0; func(svprogfuncs, &gv); return gv.ret.i; diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index 4b9035fc..6c90a4e8 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -362,20 +362,27 @@ comextqcfields } comentvars_t; #endif - -#if defined(CSQC_DAT) || !defined(CLIENTONLY) - #define USEODE 1 - #if !(defined(ODE_STATIC) || defined(ODE_DYNAMIC)) - #undef USEODE - #endif -#endif - #ifdef USEODE typedef struct { void *ode_body; void *ode_geom; } odebody_t; +typedef struct +{ + //doll info + char name[32]; + int bone; + float animate; + qboolean draw:1; + qboolean orient:1; + int orientpeer; + + //ode info + int shape; + vec3_t dimensions; + float mass; +} odebodyinfo_t; typedef struct { @@ -383,7 +390,12 @@ typedef struct } odejoint_t; typedef struct { + //doll info char name[32]; +// unsigned int disablebits; + qboolean draw:1; + + //ode info int type; int body1; //handled by the ragdoll code, rather than the physics library. int body2; //handled by the ragdoll code. @@ -397,8 +409,6 @@ typedef struct float Vel, Vel2; vec3_t offset, offset2; vec3_t axis, axis2; - - float orgmatrix[12]; } odejointinfo_t; typedef struct @@ -424,7 +434,6 @@ typedef struct vec_t ode_movelimit; // smallest component of (maxs[]-mins[]) float ode_offsetmatrix[16]; float ode_offsetimatrix[16]; - float ode_friction; int ode_joint_type; int ode_joint_enemy; int ode_joint_aiment; diff --git a/engine/server/progs.h b/engine/server/progs.h index 7aa1b528..e0116027 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -35,7 +35,7 @@ void PR_LoadGlabalStruct(void); void Q_InitProgs(void); void PR_RegisterFields(void); void PR_Init(void); -void ED_Spawned (struct edict_s *ent, int loading); +void QDECL ED_Spawned (struct edict_s *ent, int loading); qboolean SV_RunFullQCMovement(struct client_s *client, usercmd_t *ucmd); qboolean PR_KrimzonParseCommand(char *s); qboolean PR_UserCmd(char *cmd); @@ -106,7 +106,7 @@ typedef struct edict_s extern globalptrs_t *pr_global_ptrs; -extern progfuncs_t *svprogfuncs; //instance +extern pubprogfuncs_t *svprogfuncs; //instance extern progparms_t svprogparms; extern progsnum_t svmainprogs; extern progsnum_t clmainprogs; @@ -125,7 +125,7 @@ qboolean PR_QCChat(char *text, int say_type); void PR_ClientUserInfoChanged(char *name, char *oldivalue, char *newvalue); void PR_LocalInfoChanged(char *name, char *oldivalue, char *newvalue); -void PF_InitTempStrings(progfuncs_t *prinst); +void PF_InitTempStrings(pubprogfuncs_t *prinst); #ifdef VM_Q1 struct client_s; diff --git a/engine/server/server.h b/engine/server/server.h index 19c5c672..3cc4c329 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -293,7 +293,7 @@ typedef struct vec3_t playerpositions[MAX_CLIENTS]; //where each player was in this frame, for antilag qboolean playerpresent[MAX_CLIENTS]; //whether the player was actually present packet_entities_t entities; //package containing entity states that were sent in this frame, for deltaing - unsigned short *resendentnum; //the number of each entity that was sent in this frame + unsigned int *resendentnum; //the number of each entity that was sent in this frame unsigned int *resendentbits; //the bits of each entity that were sent in this frame } client_frame_t; @@ -331,10 +331,27 @@ typedef struct //merge? #define MAX_BACK_BUFFERS 16 +enum +{ + PRESPAWN_INVALID=0, + PRESPAWN_SERVERINFO, + PRESPAWN_SOUNDLIST, //nq skips these + PRESPAWN_MODELLIST, + PRESPAWN_MAPCHECK, //wait for old prespawn command + PRESPAWN_CUSTOMTENTS, + PRESPAWN_SIGNON_BUF, + PRESPAWN_SPAWNSTATIC, + PRESPAWN_BASELINES, + PRESPAWN_DONE +}; + typedef struct client_s { client_conn_state_t state; + unsigned int prespawn_stage; + unsigned int prespawn_idx; + int spectator; // non-interactive int redirect; @@ -445,8 +462,8 @@ typedef struct client_s #endif #ifdef PEXT_CSQC int csqclastsentsequence; - int csqcentsequence[MAX_EDICTS];//the sequence number a csqc entity was sent in - int csqcentversions[MAX_EDICTS];//the version of the entity when it was sent in that sequenced packet. + int *csqcentsequence;//the sequence number a csqc entity was sent in + int *csqcentversions;//the version of the entity when it was sent in that sequenced packet. #endif //true/false/persist @@ -546,9 +563,9 @@ typedef struct client_s int language; //the clients language - struct { - qbyte vweap; - } otherclientsknown[MAX_CLIENTS]; //updated as needed. Flag at a time, or all flags. +// struct { +// qbyte vweap; +// } otherclientsknown[MAX_CLIENTS]; //updated as needed. Flag at a time, or all flags. struct client_s *controller; /*first in splitscreen chain, NULL=nosplitscreen*/ struct client_s *controlled; /*next in splitscreen chain*/ @@ -906,6 +923,8 @@ extern vfsfile_t *sv_fraglogfile; //=========================================================== +void SV_AddDebugPolygons(void); + // // sv_main.c // @@ -938,7 +957,7 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC); void SV_InitOperatorCommands (void); void SV_SendServerinfo (client_t *client); -void SV_ExtractFromUserinfo (client_t *cl); +void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose); void SV_SaveInfos(vfsfile_t *f); @@ -988,11 +1007,9 @@ qboolean SVQ3_Command(void); // // sv_phys.c // -void WPhys_Init(void); void SV_SetMoveVars(void); void WPhys_RunNewmis (world_t *w); qboolean SV_Physics (void); -void World_Physics_Frame(world_t *w); void WPhys_CheckVelocity (world_t *w, wedict_t *ent); trace_t WPhys_Trace_Toss (world_t *w, wedict_t *ent, wedict_t *ignore); void SV_ProgStartFrame (void); @@ -1063,6 +1080,8 @@ void SV_PreRunCmd(void); void SV_RunCmd (usercmd_t *ucmd, qboolean recurse); void SV_PostRunCmd(void); +void SV_SendClientPrespawnInfo(client_t *client); + //sv_master.c void SVM_Think(int port); @@ -1117,6 +1136,7 @@ void ClientReliableWrite_Float(client_t *cl, float f); void ClientReliableWrite_Coord(client_t *cl, float f); void ClientReliableWrite_Long(client_t *cl, int c); void ClientReliableWrite_Short(client_t *cl, int c); +void ClientReliableWrite_Entity(client_t *cl, int c); void ClientReliableWrite_String(client_t *cl, char *s); void ClientReliableWrite_SZ(client_t *cl, void *data, int len); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 7b054c70..a26c8865 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -1124,7 +1124,7 @@ void SV_ForceName_f (void) { Info_SetValueForKey(cl->userinfo, "name", Cmd_Argv(2), MAX_INFO_STRING); SV_LogPlayer(cl, "name forced"); - SV_ExtractFromUserinfo(cl); + SV_ExtractFromUserinfo(cl, true); Q_strncpyz(cl->name, Cmd_Argv(2), sizeof(cl->namebuf)); i = cl - svs.clients; MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 66a3fc1b..8852f3b7 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -252,13 +252,29 @@ static qboolean SV_AddCSQCUpdate (client_t *client, edict_t *ent) #endif } sizebuf_t csqcmsgbuffer; + +static void SV_EmitDeltaEntIndex(sizebuf_t *msg, unsigned int entnum, qboolean remove, qboolean big) +{ + unsigned int rflag = remove?0x8000:0; + if (big) + { + if (entnum >= 0x4000) + { + MSG_WriteShort(msg, (entnum&0x3fff) | 0x4000 | rflag); + MSG_WriteByte(msg, entnum >> 14); + } + else + MSG_WriteShort(msg, entnum | rflag); + } + else + MSG_WriteShort(msg, entnum | rflag); +} void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) { #ifdef PEXT_CSQC qbyte messagebuffer[1024]; int en; int currentsequence = client->netchan.outgoing_sequence; - unsigned short mask; globalvars_t *pr_globals; edict_t *ent; qboolean writtenheader = false; @@ -287,6 +303,24 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) { ent = csqcent[en]; +#if 0 + if ((int)ent->xv->Version != sv.csqcentversion[ent->entnum]) + { + sv.csqcentversion[ent->entnum] = (int)ent->xv->Version; + for (j = 0; j < sv.allocated_client_slots; j++) + svs.client[j].pendingentbits[j] = 0xffffffff; + } + + if (!client->pendingentbits[j]) + continue; + + csqcmsgbuffer.cursize = 0; + csqcmsgbuffer.currentbit = 0; + //Ask CSQC to write a buffer for it. + G_INT(OFS_PARM0) = viewerent; + G_FLOAT(OFS_PARM1) = client->pendingentbits[j]; //psudo compatibility with SendFlags (fte doesn't support properly) + client->pendingentbits[j] = 0; +#else if (ent->xv->SendFlags) { ent->xv->SendFlags = 0; @@ -308,6 +342,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) //Ask CSQC to write a buffer for it. G_INT(OFS_PARM0) = viewerent; G_FLOAT(OFS_PARM1) = 0xffffff; //psudo compatibility with SendFlags (fte doesn't support properly) +#endif pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); if (G_INT(OFS_RETURN)) //0 means not to tell the client about it. @@ -323,7 +358,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) writtenheader=true; MSG_WriteByte(msg, svcnumber); } - MSG_WriteShort(msg, ent->entnum); + SV_EmitDeltaEntIndex(msg, ent->entnum, false, client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS); if (sv.csqcdebug) //optional extra. { if (!csqcmsgbuffer.cursize) @@ -343,15 +378,14 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) MSG_WriteByte(msg, svcfte_csqcentities); } - mask = (unsigned)ent->entnum | 0x8000; - MSG_WriteShort(msg, mask); + SV_EmitDeltaEntIndex(msg, ent->entnum, true, client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS); // Con_Printf("Sending remove 2 packet\n"); } client->csqcentversions[ent->entnum] = sv.csqcentversion[ent->entnum]; client->csqcentsequence[ent->entnum] = currentsequence; } //now remove any out dated ones - for (en = 1; en < sv.world.num_edicts; en++) + for (en = 1; en < sv.world.num_edicts && en < client->max_net_ents; en++) { ent = EDICT_NUM(svprogfuncs, en); if (client->csqcentversions[en] > 0 && client->csqcentversions[en] != ent->xv->Version) @@ -371,8 +405,9 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) } // Con_Printf("Sending remove packet %i\n", en); - mask = (unsigned)en | 0x8000; - MSG_WriteShort(msg, mask); + + + SV_EmitDeltaEntIndex(msg, en, true, client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS); client->csqcentversions[en] = 0; client->csqcentsequence[en] = currentsequence; @@ -403,7 +438,7 @@ void SV_CSQC_DroppedPacket(client_t *client, int sequence) if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) { unsigned int *f = client->frameunion.frames[sequence & UPDATE_MASK].resendentbits; - unsigned short *n = client->frameunion.frames[sequence & UPDATE_MASK].resendentnum; + unsigned int *n = client->frameunion.frames[sequence & UPDATE_MASK].resendentnum; // Con_Printf("SV: Resend %i\n", sequence); i = client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities; while (i > 0) @@ -569,7 +604,7 @@ void SVQW_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, evenmorebits |= U_COLOURMOD; if (to->glowsize != from->glowsize) - to->dpflags |= 2; // RENDER_GLOWTRAIL + to->dpflags |= RENDER_GLOWTRAIL; if (to->dpflags != from->dpflags && (protext & PEXT_DPFLAGS)) evenmorebits |= U_DPFLAGS; @@ -693,7 +728,7 @@ void SVQW_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, if (evenmorebits & U_TAGINFO) { - MSG_WriteShort (msg, to->tagentity); + MSG_WriteEntity (msg, to->tagentity); MSG_WriteShort (msg, to->tagindex); } @@ -811,8 +846,8 @@ static unsigned int SVFTE_DeltaCalcBits(entity_state_t *from, entity_state_t *to if (to->colormod[0]!=from->colormod[0]||to->colormod[1]!=from->colormod[1]||to->colormod[2]!=from->colormod[2]) bits |= UF_COLORMOD; - if (to->glowmod[0]!=from->glowmod[0]||to->glowmod[1]!=from->glowmod[1]||to->glowmod[2]!=from->glowmod[2]) - bits |= UF_GLOWMOD; + if (to->glowsize!=from->glowsize||to->glowcolour!=from->glowcolour||to->glowmod[0]!=from->glowmod[0]||to->glowmod[1]!=from->glowmod[1]||to->glowmod[2]!=from->glowmod[2]) + bits |= UF_GLOW; if (to->tagentity != from->tagentity || to->tagindex != from->tagindex) bits |= UF_TAGINFO; @@ -985,7 +1020,7 @@ static void SVFTE_WriteUpdate(unsigned int bits, entity_state_t *state, sizebuf_ MSG_WriteByte(msg, state->hexen2flags); if (bits & UF_TAGINFO) { - MSG_WriteShort(msg, state->tagentity); + MSG_WriteEntity(msg, state->tagentity); MSG_WriteByte(msg, state->tagindex); } if (bits & UF_LIGHT) @@ -1006,8 +1041,10 @@ static void SVFTE_WriteUpdate(unsigned int bits, entity_state_t *state, sizebuf_ MSG_WriteByte(msg, state->colormod[1]); MSG_WriteByte(msg, state->colormod[2]); } - if (bits & UF_GLOWMOD) + if (bits & UF_GLOW) { + MSG_WriteByte(msg, state->glowsize); + MSG_WriteByte(msg, state->glowcolour); MSG_WriteByte(msg, state->glowmod[0]); MSG_WriteByte(msg, state->glowmod[1]); MSG_WriteByte(msg, state->glowmod[2]); @@ -1034,7 +1071,7 @@ void SVFTE_EmitBaseline(entity_state_t *to, qboolean numberisimportant, sizebuf_ { unsigned int bits; if (numberisimportant) - MSG_WriteShort(msg, to->number); + MSG_WriteEntity(msg, to->number); bits = UF_RESET | SVFTE_DeltaCalcBits(&nullentitystate, to); SVFTE_WriteUpdate(bits, to, msg); } @@ -1052,7 +1089,7 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t unsigned int j; unsigned int bits; unsigned int *resendbits; - unsigned short *resendnum; + unsigned int *resendnum; unsigned int outno, outmax; qboolean reset = (client->delta_sequence == -1) || (client->pendingentbits[0] & UF_REMOVE); @@ -1150,7 +1187,7 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t if (bits & UF_REMOVE) { - MSG_WriteShort(msg, j | 0x8000); + SV_EmitDeltaEntIndex(msg, j, true, true); resendbits[outno] = UF_REMOVE; // Con_Printf("REMOVE %i @ %i\n", j, client->netchan.incoming_sequence); } @@ -1173,7 +1210,8 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t } else resendbits[outno] = bits; - MSG_WriteShort(msg, j); + + SV_EmitDeltaEntIndex(msg, j, false, true); SVFTE_WriteUpdate(bits, &client->sentents.entities[j], msg); } resendnum[outno++] = j; @@ -1516,7 +1554,7 @@ void SVDP_EmitEntityDelta(entity_state_t *from, entity_state_t *to, sizebuf_t *m MSG_WriteByte(msg, to->colormap); if (bits & E5_ATTACHMENT) { - MSG_WriteShort(msg, to->tagentity); + MSG_WriteEntity(msg, to->tagentity); MSG_WriteByte(msg, to->tagindex); } if (bits & E5_LIGHT) @@ -1726,7 +1764,7 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent) if (ent->spectator == 2 && ent->weaponframe) //it's not us, but we are spectating, so we need the correct weaponframe pflags |= PF_WEAPONFRAME; - if (!ent->isself || ent->fteext & PEXT_SPLITSCREEN) + if (!ent->isself || (ent->fteext & PEXT_SPLITSCREEN)) { #ifdef PEXT_SCALE //this is graphics, not physics if (ent->fteext & PEXT_SCALE) @@ -1950,7 +1988,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * int j; client_t *cl; edict_t *ent, *vent; - int pflags; +// int pflags; demo_frame_t *demo_frame; demo_client_t *dcl; @@ -2334,7 +2372,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * //FIXME: Name flags //player is visible, now would be a good time to update what the player is like. - pflags = 0; +/* pflags = 0; #ifdef PEXT_VWEAP if (client->fteprotocolextensions & PEXT_VWEAP && client->otherclientsknown[j].vweap != ent->xv->vweapmodelindex) { @@ -2349,13 +2387,15 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * if (pflags & 1) ClientReliableWrite_Short(client, client->otherclientsknown[j].vweap); } +*/ } } void SVNQ_EmitEntityState(sizebuf_t *msg, entity_state_t *ent) { - entity_state_t *baseline = &EDICT_NUM(svprogfuncs, ent->number)->baseline; + edict_t *ed = EDICT_NUM(svprogfuncs, ent->number); + entity_state_t *baseline = &ed->baseline; int i, eff; float miss; @@ -2403,7 +2443,24 @@ int glowsize=0, glowcolor=0, colourmod=0; bits |= NQU_LONGENTITY; - if (0) + if (host_client->protocol == SCP_FITZ666) + { + if (baseline->trans != ent->trans) + bits |= FITZU_ALPHA; + + if (baseline->scale != ent->scale) + bits |= RMQU_SCALE; + + if ((baseline->frame&0xff00) != (ent->frame&0xff00)) + bits |= FITZU_FRAME2; + + if ((baseline->modelindex&0xff00) != (ent->modelindex&0xff00)) + bits |= FITZU_MODEL2; + + if (baseline->dpflags & RENDER_STEP) + bits |= FITZU_LERPFINISH; + } + else if (0) { #if 0 if (baseline.trans != ent->xv->alpha) @@ -2488,14 +2545,25 @@ int glowsize=0, glowcolor=0, colourmod=0; if (bits & NQU_ORIGIN3) MSG_WriteCoord (msg, ent->origin[2]); if (bits & NQU_ANGLE3) MSG_WriteAngle(msg, ent->angles[2]); - if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->trans*255); - if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->scale*16); - if (bits & DPU_EFFECTS2) MSG_WriteByte(msg, eff >> 8); - if (bits & DPU_GLOWSIZE) MSG_WriteByte(msg, glowsize); - if (bits & DPU_GLOWCOLOR) MSG_WriteByte(msg, glowcolor); - if (bits & DPU_COLORMOD) MSG_WriteByte(msg, colourmod); - if (bits & DPU_FRAME2) MSG_WriteByte(msg, (int)ent->frame >> 8); - if (bits & DPU_MODEL2) MSG_WriteByte(msg, (int)ent->modelindex >> 8); + if (host_client->protocol == SCP_FITZ666) + { + if (bits & FITZU_ALPHA) MSG_WriteByte(msg, ent->trans); + if (bits & RMQU_SCALE) MSG_WriteByte(msg, ent->scale); + if (bits & FITZU_FRAME2) MSG_WriteByte(msg, ent->frame>>8); + if (bits & FITZU_MODEL2) MSG_WriteByte(msg, ent->modelindex>>8); + if (bits & FITZU_LERPFINISH)MSG_WriteByte(msg, (ed->v->nextthink - sv.world.physicstime) * 255); + } + else + { + if (bits & DPU_ALPHA) MSG_WriteByte(msg, ent->trans*255); + if (bits & DPU_SCALE) MSG_WriteByte(msg, ent->scale*16); + if (bits & DPU_EFFECTS2) MSG_WriteByte(msg, eff >> 8); + if (bits & DPU_GLOWSIZE) MSG_WriteByte(msg, glowsize); + if (bits & DPU_GLOWCOLOR) MSG_WriteByte(msg, glowcolor); + if (bits & DPU_COLORMOD) MSG_WriteByte(msg, colourmod); + if (bits & DPU_FRAME2) MSG_WriteByte(msg, (int)ent->frame >> 8); + if (bits & DPU_MODEL2) MSG_WriteByte(msg, (int)ent->modelindex >> 8); + } } typedef struct gibfilter_s { @@ -2772,7 +2840,6 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli if (ent->v->movetype == MOVETYPE_STEP) state->dpflags |= RENDER_STEP; - state->flags = 0; VectorCopy (ent->v->origin, state->origin); VectorCopy (ent->v->angles, state->angles); state->modelindex = ent->v->modelindex; @@ -3406,7 +3473,7 @@ void SV_CleanupEnts(void) ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH; MSG_WriteByte(&sv.multicast, svc_muzzleflash); - MSG_WriteShort(&sv.multicast, e); + MSG_WriteEntity(&sv.multicast, e); VectorCopy(ent->v->origin, org); if (progstype == PROG_H2) org[2] += 24; diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 1c316208..02504f2f 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -525,7 +525,7 @@ void SV_UnspawnServer (void) //terminate the running server. for (i = 0; i < sv.allocated_client_slots; i++) { if (svs.clients[i].state) - SV_DropClient(svs.clients+i); + SV_DropClient(&svs.clients[i]); } PR_Deinit(); #ifdef Q2SERVER @@ -876,7 +876,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us { if (svprogfuncs) //we don't want the q1 stuff anymore. { - CloseProgs(svprogfuncs); + svprogfuncs->CloseProgs(svprogfuncs); sv.world.progs = svprogfuncs = NULL; } } @@ -1074,8 +1074,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us } #ifdef PEXT_CSQC - memset(svs.clients[i].csqcentsequence, 0, sizeof(svs.clients[i].csqcentsequence)); - memset(svs.clients[i].csqcentversions, 0, sizeof(svs.clients[i].csqcentversions)); + if (svs.clients[i].csqcentsequence) + memset(svs.clients[i].csqcentsequence, 0, sizeof(svs.clients[i].csqcentsequence)); + if (svs.clients[i].csqcentversions) + memset(svs.clients[i].csqcentversions, 0, sizeof(svs.clients[i].csqcentversions)); #endif } for (; i < MAX_CLIENTS; i++) @@ -1438,7 +1440,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us if (host_client->state == cs_connected && host_client->protocol == SCP_BAD) { sv_player = host_client->edict; - SV_ExtractFromUserinfo(host_client); + SV_ExtractFromUserinfo(host_client, true); // copy spawn parms out of the client_t for (j=0 ; j< NUM_SPAWN_PARMS ; j++) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 827cdec7..1cf1a711 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -369,6 +369,20 @@ void VARGS Host_Error (char *error, ...) } #endif +#ifdef SERVERONLY +void VARGS Host_EndGame (char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,error); + vsnprintf (string,sizeof(string)-1, error,argptr); + va_end (argptr); + + SV_Error("%s", string); +} +#endif + /* ================== SV_FinalMessage @@ -618,6 +632,14 @@ void SV_DropClient (client_t *drop) memset(&drop->sentents.entities, 0, sizeof(drop->sentents.entities)); } + if (drop->csqcentversions) + Z_Free(drop->csqcentversions); + drop->csqcentversions = NULL; + if (drop->csqcentsequence) + Z_Free(drop->csqcentsequence); + drop->csqcentsequence = NULL; + drop->csqcactive = false; + if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM) //gamecode should do it all for us. { // send notification to all remaining clients @@ -1404,7 +1426,7 @@ void SVC_GetChallenge (void) #ifdef PROTOCOL_VERSION_FTE unsigned int mask; //tell the client what fte extensions we support - mask = Net_PextMask(1); + mask = Net_PextMask(1, false); if (mask) { lng = LittleLong(PROTOCOL_VERSION_FTE); @@ -1416,7 +1438,7 @@ void SVC_GetChallenge (void) over+=sizeof(lng); } //tell the client what fte extensions we support - mask = Net_PextMask(2); + mask = Net_PextMask(2, false); if (mask) { lng = LittleLong(PROTOCOL_VERSION_FTE2); @@ -1735,7 +1757,7 @@ client_t *SVC_DirectConnect(void) unsigned int protextsupported=0; unsigned int protextsupported2=0; - extern cvar_t pr_maxedicts; + extern cvar_t pr_maxedicts, sv_protocol_nq; char *name; @@ -1842,6 +1864,8 @@ client_t *SVC_DirectConnect(void) protocol = SCP_NETQUAKE; //because we can if (atoi(Info_ValueForKey(Cmd_Argv(4), "mod")) == 1) protocol = SCP_PROQUAKE; + else if (atoi(Info_ValueForKey(Cmd_Argv(4), "mod")) == 666) + protocol = SCP_FITZ666; } else if (version != PROTOCOL_VERSION_QW) { @@ -1985,6 +2009,34 @@ client_t *SVC_DirectConnect(void) newcl = &temp; memset (newcl, 0, sizeof(client_t)); + + if (protocol >= SCP_NETQUAKE && protocol < SCP_DARKPLACES6) + { //NQ protocols lack stuff like protocol extensions. + //its the wild west where nothing is known about the client and everything breaks. + switch(sv_protocol_nq.ival) + { + case RMQ_PROTOCOL_VERSION: + case FITZ_PROTOCOL_VERSION: + protocol = SCP_FITZ666; + break; + case 15: + //don't trip up on proquake's angle change. + protocol = (protocol==SCP_PROQUAKE)?SCP_PROQUAKE:SCP_NETQUAKE; + break; + case DP6_PROTOCOL_VERSION: + protocol = SCP_DARKPLACES6; + break; + case DP7_PROTOCOL_VERSION: + protocol = SCP_DARKPLACES7; + break; + default: + Con_Printf("sv_protocol_nq set incorrectly\n"); + case 0: + //change nothing + break; + } + } + newcl->userid = nextuserid; newcl->fteprotocolextensions = protextsupported; newcl->fteprotocolextensions2 = protextsupported2; @@ -1997,7 +2049,7 @@ client_t *SVC_DirectConnect(void) if (newcl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) { //you need to reconnect for this to update, of course. so make sure its not *too* low... - newcl->max_net_ents = bound(512, pr_maxedicts.ival, 32768); + newcl->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS); newcl->maxmodels = MAX_MODELS; //protocol limited to 14 bits. } else @@ -2015,10 +2067,16 @@ client_t *SVC_DirectConnect(void) else if (ISDPCLIENT(newcl)) { newcl->max_net_ents = bound(512, pr_maxedicts.ival, 32768); - newcl->maxmodels = 1024; //protocol limit of 16bits. 15bits for late precaches. client limit of 1k + newcl->maxmodels = 1024; //protocol limit of 16 bits. 15 bits for late precaches. client limit of 1k + } + else if (newcl->protocol == SCP_FITZ666) + { + newcl->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently. + newcl->maxmodels = 1024; + maxpacketentities = 512; } else - newcl->max_net_ents = 600; + newcl->max_net_ents = bound(512, pr_maxedicts.ival, 600); if (sv.msgfromdemo) newcl->wasrecorded = true; @@ -2313,7 +2371,7 @@ client_t *SVC_DirectConnect(void) ptr = Z_Malloc( sizeof(client_frame_t)*UPDATE_BACKUP+ sizeof(*temp.pendingentbits)*temp.max_net_ents+ sizeof(unsigned int)*maxents*UPDATE_BACKUP+ - sizeof(unsigned short)*maxents*UPDATE_BACKUP); + sizeof(unsigned int)*maxents*UPDATE_BACKUP); temp.frameunion.frames = (void*)ptr; ptr += sizeof(*temp.frameunion.frames)*UPDATE_BACKUP; temp.pendingentbits = (void*)ptr; @@ -2399,7 +2457,7 @@ client_t *SVC_DirectConnect(void) newcl->playerclass = newcl->edict->xv->playerclass; // parse some info from the info strings - SV_ExtractFromUserinfo (newcl); + SV_ExtractFromUserinfo (newcl, true); SV_GenerateBasicUserInfo (newcl); // JACK: Init the floodprot stuff. @@ -2605,7 +2663,7 @@ client_t *SVC_DirectConnect(void) else Info_RemoveKey (cl->userinfo, "*spectator"); - SV_ExtractFromUserinfo (cl); + SV_ExtractFromUserinfo (cl, true); SV_GetNewSpawnParms(cl); } @@ -4664,7 +4722,7 @@ Pull specific info from a newly changed userinfo string into a more C freindly form. ================= */ -void SV_ExtractFromUserinfo (client_t *cl) +void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose) { char *val, *p; int i; @@ -4722,7 +4780,7 @@ void SV_ExtractFromUserinfo (client_t *cl) if (strncmp(newname, cl->name, sizeof(cl->namebuf)-1)) { - if (cl->ismuted && *cl->name) + if (cl->ismuted && *cl->name && verbose) //!verbose is a gamecode-forced update, where the gamecode is expected to know what its doing. SV_ClientTPrintf (cl, PRINT_HIGH, STL_NONAMEASMUTE); else { @@ -4735,7 +4793,7 @@ void SV_ExtractFromUserinfo (client_t *cl) cl->lastnamecount = 0; cl->lastnametime = realtime; } - else if (cl->lastnamecount++ > 4) + else if (cl->lastnamecount++ > 4 && verbose) { SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTKICKEDNAMESPAM, cl->name); SV_ClientTPrintf (cl, PRINT_HIGH, STL_YOUWEREKICKEDNAMESPAM); @@ -4744,7 +4802,7 @@ void SV_ExtractFromUserinfo (client_t *cl) } } - if (*cl->name && cl->state >= cs_spawned && !cl->spectator) + if (*cl->name && cl->state >= cs_spawned && !cl->spectator && verbose) { SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTNAMECHANGE, cl->name, newname); } @@ -4757,7 +4815,7 @@ void SV_ExtractFromUserinfo (client_t *cl) #endif #ifdef SVRANKING } - else if (cl->state >= cs_spawned && *rank_filename.string) + else if (cl->state >= cs_spawned && *rank_filename.string && verbose) SV_ClientPrintf(cl, PRINT_HIGH, "Your rankings name has not been changed\n"); #endif } @@ -4869,9 +4927,7 @@ void SV_Demo_Init(void); void SV_Init (quakeparms_t *parms) { int i; -#ifndef SERVERONLY if (isDedicated) -#endif { COM_InitArgv (parms->argc, parms->argv); @@ -4897,12 +4953,22 @@ void SV_Init (quakeparms_t *parms) R_SetRenderer(NULL); #endif COM_Init (); - Mod_Init (); - } - -#if defined(SERVERONLY) || !(defined(CSQC_DAT) || defined(MENU_DAT)) - PF_Common_RegisterCvars(); +#ifdef Q2BSPS + CM_Init(); #endif +#ifdef TERRAIN + Terr_Init(); +#endif + Mod_Init (); + + PF_Common_RegisterCvars(); + } + else + { +#if defined(SERVERONLY) || !(defined(CSQC_DAT) || defined(MENU_DAT)) + PF_Common_RegisterCvars(); +#endif + } PR_Init (); diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 51cae22d..26f60c18 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -1594,7 +1594,10 @@ static qboolean SV_MVD_Record (mvddest_t *dest) if (sv_demoExtensions.ival == 2) { /*more limited subset supported by ezquake*/ - demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS|PEXT_256PACKETENTITIES|PEXT_FLOATCOORDS|PEXT_ACCURATETIMINGS|PEXT_TRANS|PEXT_HLBSP|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SPAWNSTATIC2; + demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS|PEXT_256PACKETENTITIES|PEXT_FLOATCOORDS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SPAWNSTATIC2; +// demo.recorder.fteprotocolextensions |= PEXT_HLBSP; /*ezquake DOES have this, but it is pointless and should have been in some feature mask rather than protocol extensions*/ +// demo.recorder.fteprotocolextensions |= PEXT_ACCURATETIMINGS; /*ezquake does not support this any more*/ +// demo.recorder.fteprotocolextensions |= PEXT_TRANS; /*ezquake has no support for .alpha*/ demo.recorder.fteprotocolextensions2 = PEXT2_VOICECHAT; demo.recorder.zquake_extensions = Z_EXT_PM_TYPE | Z_EXT_PM_TYPE_NEW | Z_EXT_VIEWHEIGHT | Z_EXT_SERVERTIME | Z_EXT_PITCHLIMITS | Z_EXT_JOIN_OBSERVE | Z_EXT_VWEP; } diff --git a/engine/server/sv_nchan.c b/engine/server/sv_nchan.c index 1789cec5..78f571f3 100644 --- a/engine/server/sv_nchan.c +++ b/engine/server/sv_nchan.c @@ -172,6 +172,16 @@ void ClientReliableWrite_Short(client_t *cl, int c) else MSG_WriteShort(&cl->netchan.message, c); } +void ClientReliableWrite_Entity(client_t *cl, int c) +{ + if (cl->num_backbuf) + { + MSG_WriteEntity(&cl->backbuf, c); + ClientReliable_FinishWrite(cl); + } + else + MSG_WriteEntity(&cl->netchan.message, c); +} void ClientReliableWrite_String(client_t *cl, char *s) { diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 93041bd9..5947e459 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -70,19 +70,19 @@ cvar_t pm_walljump = SCVARF("pm_walljump", "0", CVAR_SERVERINFO); #define cvargroup_serverphysics "server physics variables" void WPhys_Init(void) { - Cvar_Register (&sv_maxvelocity, cvargroup_serverphysics); - Cvar_Register (&sv_gravity, cvargroup_serverphysics); - Cvar_Register (&sv_stopspeed, cvargroup_serverphysics); - Cvar_Register (&sv_maxspeed, cvargroup_serverphysics); - Cvar_Register (&sv_spectatormaxspeed, cvargroup_serverphysics); - Cvar_Register (&sv_accelerate, cvargroup_serverphysics); - Cvar_Register (&sv_airaccelerate, cvargroup_serverphysics); - Cvar_Register (&sv_wateraccelerate, cvargroup_serverphysics); - Cvar_Register (&sv_friction, cvargroup_serverphysics); - Cvar_Register (&sv_waterfriction, cvargroup_serverphysics); - Cvar_Register (&sv_sound_watersplash, cvargroup_serverphysics); - Cvar_Register (&sv_sound_land, cvargroup_serverphysics); - Cvar_Register (&sv_stepheight, cvargroup_serverphysics); + Cvar_Register (&sv_maxvelocity, cvargroup_serverphysics); + Cvar_Register (&sv_gravity, cvargroup_serverphysics); + Cvar_Register (&sv_stopspeed, cvargroup_serverphysics); + Cvar_Register (&sv_maxspeed, cvargroup_serverphysics); + Cvar_Register (&sv_spectatormaxspeed, cvargroup_serverphysics); + Cvar_Register (&sv_accelerate, cvargroup_serverphysics); + Cvar_Register (&sv_airaccelerate, cvargroup_serverphysics); + Cvar_Register (&sv_wateraccelerate, cvargroup_serverphysics); + Cvar_Register (&sv_friction, cvargroup_serverphysics); + Cvar_Register (&sv_waterfriction, cvargroup_serverphysics); + Cvar_Register (&sv_sound_watersplash, cvargroup_serverphysics); + Cvar_Register (&sv_sound_land, cvargroup_serverphysics); + Cvar_Register (&sv_stepheight, cvargroup_serverphysics); Cvar_Register (&sv_gameplayfix_noairborncorpse, cvargroup_serverphysics); Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics); @@ -692,13 +692,14 @@ SV_Push */ static qboolean WPhys_Push (world_t *w, wedict_t *pusher, vec3_t move, vec3_t amove) { +#define PUSHABLE_LIMIT 32768 int i, e; wedict_t *check, *block; vec3_t mins, maxs; vec3_t pushorig; int num_moved; - wedict_t *moved_edict[MAX_EDICTS]; - vec3_t moved_from[MAX_EDICTS]; + wedict_t *moved_edict[PUSHABLE_LIMIT]; + vec3_t moved_from[PUSHABLE_LIMIT]; float oldsolid; if (amove[0] || amove[1] || amove[2]) @@ -758,6 +759,9 @@ static qboolean WPhys_Push (world_t *w, wedict_t *pusher, vec3_t move, vec3_t am if (block) continue; + if (num_moved == PUSHABLE_LIMIT) + break; + VectorCopy (check->v->origin, moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; diff --git a/engine/server/sv_rankin.c b/engine/server/sv_rankin.c index e0b8b02d..ae16aa56 100644 --- a/engine/server/sv_rankin.c +++ b/engine/server/sv_rankin.c @@ -2,12 +2,6 @@ #ifndef CLIENTONLY -#if defined(_WIN32) && !defined(MINGW) -#define inline //_inline //fix for stupid VC -#elif defined(CLANG) -#define inline // fix for stupid clang -#endif - #ifdef SVRANKING typedef struct { @@ -35,7 +29,7 @@ char rank_cvargroup[] = "server rankings"; #define RANKFILE_VERSION ((NUM_RANK_SPAWN_PARMS==32)?0:0x00000001) #define RANKFILE_IDENT *(int*)"RANK" -void inline READ_PLAYERSTATS(int x, rankstats_t *os) +static void READ_PLAYERSTATS(int x, rankstats_t *os) { int i; size_t result; @@ -57,7 +51,7 @@ void inline READ_PLAYERSTATS(int x, rankstats_t *os) // os->pad3 = (os->pad3); } -void inline WRITE_PLAYERSTATS(int x, rankstats_t *os) +static void WRITE_PLAYERSTATS(int x, rankstats_t *os) { rankstats_t ns; int i; @@ -77,7 +71,7 @@ void inline WRITE_PLAYERSTATS(int x, rankstats_t *os) VFS_WRITE(rankfile, &ns, sizeof(rankstats_t)); } -void inline READ_PLAYERHEADER(int x, rankheader_t *oh) +static void READ_PLAYERHEADER(int x, rankheader_t *oh) { size_t result; @@ -95,7 +89,7 @@ void inline READ_PLAYERHEADER(int x, rankheader_t *oh) oh->score = swapfloat(oh->score); } -void inline WRITE_PLAYERHEADER(int x, rankheader_t *oh) +static void WRITE_PLAYERHEADER(int x, rankheader_t *oh) { rankheader_t nh; @@ -110,13 +104,13 @@ void inline WRITE_PLAYERHEADER(int x, rankheader_t *oh) VFS_WRITE(rankfile, &nh, sizeof(rankheader_t)); } -void inline READ_PLAYERINFO(int x, rankinfo_t *inf) +static void READ_PLAYERINFO(int x, rankinfo_t *inf) { READ_PLAYERHEADER(x, &inf->h); READ_PLAYERSTATS(x, &inf->s); } -void inline WRITEHEADER(void) +static void WRITEHEADER(void) { rankfileheader_t nh; @@ -165,7 +159,7 @@ qboolean Rank_OpenRankings(void) result = VFS_READ(rankfile, &rankfileheader, sizeof(rankfileheader_t)); if (result != sizeof(rankfileheader_t)) - Con_Printf("Rank_OpenRankings() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankfileheader_t),(unsigned int)result); + Con_Printf("Rank_OpenRankings() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankfileheader_t),(unsigned int)result, rank_filename.string); rankfileheader.version = swaplong(rankfileheader.version); rankfileheader.usedslots = swaplong(rankfileheader.usedslots); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 911a3944..9f282529 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -954,7 +954,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam MSG_WriteByte (&sv.multicast, pitchadj); if (extfield_mask & DPSND_LARGEENTITY) { - MSG_WriteShort (&sv.multicast, ent); + MSG_WriteEntity (&sv.multicast, ent); MSG_WriteByte (&sv.multicast, channel); } else @@ -1009,7 +1009,7 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam MSG_WriteByte (&sv.nqmulticast, pitchadj); if (extfield_mask & DPSND_LARGEENTITY) { - MSG_WriteShort (&sv.nqmulticast, ent); + MSG_WriteEntity (&sv.nqmulticast, ent); MSG_WriteByte (&sv.nqmulticast, channel); } else @@ -1809,7 +1809,7 @@ qboolean SV_SendClientDatagram (client_t *client) msg.overflowed = false; msg.prim = client->datagram.prim; - if (!client->netchan.fragmentsize) + if (client->protocol != SCP_FITZ666 && !client->netchan.fragmentsize) msg.maxsize = MAX_DATAGRAM; if (sv.world.worldmodel && !client->controller) @@ -1995,7 +1995,7 @@ void SV_UpdateToReliableMessages (void) Info_SetValueForKey(host_client->userinfo, "topcolor", va("%i", (int)host_client->edict->xv->clientcolors/16), sizeof(host_client->userinfo)); Info_SetValueForKey(host_client->userinfo, "bottomcolor", va("%i", (int)host_client->edict->xv->clientcolors&15), sizeof(host_client->userinfo)); { - SV_ExtractFromUserinfo (host_client); //this will take care of nq for us anyway. + SV_ExtractFromUserinfo (host_client, true); //this will take care of nq for us anyway. MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, i); @@ -2019,7 +2019,7 @@ void SV_UpdateToReliableMessages (void) Con_DPrintf("Client %s programatically renamed to %s\n", host_client->name, name); Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo)); - SV_ExtractFromUserinfo (host_client); + SV_ExtractFromUserinfo (host_client, true); if (strcmp(oname, host_client->name)) { @@ -2383,6 +2383,8 @@ void SV_SendClientMessages (void) SV_SendClientDatagram (c); else { + SV_SendClientPrespawnInfo(c); + SV_DarkPlacesDownloadChunk(c, &c->datagram); fnum = c->netchan.outgoing_sequence; sentbytes = Netchan_Transmit (&c->netchan, c->datagram.cursize, c->datagram.data, SV_RateForClient(c)); // just update reliable diff --git a/engine/server/sv_sql.c b/engine/server/sv_sql.c index 2f7c4b3a..2b214b94 100644 --- a/engine/server/sv_sql.c +++ b/engine/server/sv_sql.c @@ -1047,7 +1047,7 @@ void SQL_Killall_f (void) SQL_KillServers(); } -void SQL_ServerCycle (progfuncs_t *prinst, struct globalvars_s *pr_globals) +void SQL_ServerCycle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { int i; diff --git a/engine/server/sv_sql.h b/engine/server/sv_sql.h index c546bbe9..7ffbb0f2 100644 --- a/engine/server/sv_sql.h +++ b/engine/server/sv_sql.h @@ -89,7 +89,7 @@ void SQL_Disconnect(sqlserver_t *server); void SQL_Escape(sqlserver_t *server, char *src, char *dst, int dstlen); const char *SQL_Info(sqlserver_t *server); qboolean SQL_Available(void); -void SQL_ServerCycle (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void SQL_ServerCycle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); extern cvar_t sql_driver; extern cvar_t sql_host; diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 8f298b9a..1ecda763 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -769,107 +769,12 @@ void Sys_Printf (char *fmt, ...) if (sys_colorconsole.value && hconsoleout) { -#if 1 conchar_t out[MAXPRINTMSG], *c, *end; end = COM_ParseFunString(CON_WHITEMASK, msg, out, sizeof(out), false); for (c = out; c < end; c++) Sys_PrintColouredChar (*c); -#else - int ext = CON_WHITEMASK; - int extstack[4]; - int extstackdepth = 0; - unsigned char *str = (unsigned char*)msg; - - - 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; - } - Sys_PrintColouredChar('^' | ext); - // else invalid code - } - 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 == '^') - { - Sys_PrintColouredChar('^' | ext); - str++; - } - else - { - Sys_PrintColouredChar('^' | ext); - Sys_PrintColouredChar ((*str++) | ext); - } - continue; - } - Sys_PrintColouredChar ((*str++) | ext); - } -#endif ApplyColour(CON_WHITEMASK); } else diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 5ffc7bed..5f31a62a 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -219,6 +219,9 @@ void SV_New_f (void) int splitnum; client_t *split; + host_client->prespawn_stage = PRESPAWN_INVALID; + host_client->prespawn_idx = 0; + if (host_client->state == cs_spawned) return; @@ -402,53 +405,15 @@ void SV_New_f (void) ClientReliableWrite_Float(host_client, movevars.waterfriction); ClientReliableWrite_Float(host_client, movevars.entgravity); -#ifdef SERVER_DEMO_PLAYBACK - // send server info string - if (sv.demostatevalid) - { - ClientReliableWrite_Begin(host_client, svc_stufftext, 20 + strlen(sv.demoinfo)); - ClientReliableWrite_String (host_client, va("fullserverinfo \"%s\"\n", sv.demoinfo) ); - } - else -#endif - { - ClientReliableWrite_Begin(host_client, svc_stufftext, 20 + strlen(svs.info)); - ClientReliableWrite_String (host_client, va("fullserverinfo \"%s\"\n", svs.info) ); - } - host_client->csqcactive = false; host_client->realip_num = rand()+(host_client->challenge<<16); SV_CheckRealIP(host_client, false); - // send music - ClientReliableWrite_Begin(host_client, svc_cdtrack, 2); - if (progstype == PROG_H2) - ClientReliableWrite_Byte (host_client, sv.h2cdtrack); - else if (svprogfuncs) - ClientReliableWrite_Byte (host_client, ((edict_t*)sv.world.edicts)->v->sounds); - else - ClientReliableWrite_Byte (host_client, 0); - SV_LogPlayer(host_client, "new (QW)"); - - - { - char buffer[1024]; - - FS_GetPackNames(buffer, sizeof(buffer), 2, true); /*retain extensions, or we'd have to assume pk3*/ - ClientReliableWrite_Begin(host_client, svc_stufftext, 1+11+strlen(buffer)+1+1); - ClientReliableWrite_SZ(host_client, "//paknames ", 11); - ClientReliableWrite_SZ(host_client, buffer, strlen(buffer)); - ClientReliableWrite_String(host_client, "\n"); - - FS_GetPackHashes(buffer, sizeof(buffer), false); - ClientReliableWrite_Begin(host_client, svc_stufftext, 1+7+strlen(buffer)+1+1); - ClientReliableWrite_SZ(host_client, "//paks ", 7); - ClientReliableWrite_SZ(host_client, buffer, strlen(buffer)); - ClientReliableWrite_String(host_client, "\n"); - } + host_client->prespawn_stage = PRESPAWN_SERVERINFO; + host_client->prespawn_idx = 0; } #define GAME_DEATHMATCH 0 @@ -458,6 +423,8 @@ void SVNQ_New_f (void) extern cvar_t coop; char message[2048]; int i; + int maxents; + extern cvar_t pr_maxedicts; if (host_client->redirect) { @@ -469,8 +436,9 @@ void SVNQ_New_f (void) if (!host_client->pextknown) { - MSG_WriteByte (&host_client->netchan.message, svc_stufftext); - MSG_WriteString (&host_client->netchan.message, "cmd pext\n"); + char *msg = va("cmd pext\n"); + ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(msg)); + ClientReliableWrite_String (host_client, msg); return; } @@ -478,6 +446,12 @@ void SVNQ_New_f (void) Q_snprintfz (message, sizeof(message), "%c\n%s server\n", 2, version_string()); MSG_WriteString (&host_client->netchan.message,message); + + Z_Free(host_client->csqcentversions); + host_client->csqcentversions = NULL; + Z_Free(host_client->csqcentsequence); + host_client->csqcentsequence = NULL; + host_client->csqcactive = false; if (host_client->protocol == SCP_DARKPLACES6 || host_client->protocol == SCP_DARKPLACES7) { extern cvar_t allow_download; @@ -516,6 +490,7 @@ void SVNQ_New_f (void) MSG_WriteLong (&host_client->netchan.message, host_client->fteprotocolextensions2); } + maxents = host_client->max_net_ents; switch(host_client->protocol) { #ifdef NQPROT @@ -523,7 +498,7 @@ void SVNQ_New_f (void) case SCP_PROQUAKE: case SCP_FITZ666: SV_LogPlayer(host_client, "new (NQ)"); - if (sv.nqdatagram.prim.anglesize != 1 || sv.nqdatagram.prim.coordsize != 2 || sv_protocol_nq.ival == 666 || host_client->protocol == SCP_FITZ666) + if (sv.nqdatagram.prim.anglesize != 1 || sv.nqdatagram.prim.coordsize != 2 || host_client->protocol == SCP_FITZ666) { int rmqfl = ((sv.nqdatagram.prim.coordsize==4)?RMQFL_FLOATCOORD:0) | @@ -540,12 +515,20 @@ void SVNQ_New_f (void) { MSG_WriteLong (&host_client->netchan.message, FITZ_PROTOCOL_VERSION); } + + host_client->maxmodels = 1024; } else { host_client->protocol = (host_client->protocol==SCP_PROQUAKE)?SCP_PROQUAKE:SCP_NETQUAKE; //identical other than the client->server angles + if (host_client->protocol==SCP_PROQUAKE) + host_client->max_net_ents = bound(512, pr_maxedicts.ival, 32767); //modified engines will all want to use proquake's improved aiming protocol. + else //if this breaks your client, upgrade. + host_client->max_net_ents = bound(512, pr_maxedicts.ival, 600); MSG_WriteLong (&host_client->netchan.message, NQ_PROTOCOL_VERSION); host_client->datagram.maxsize = MAX_NQDATAGRAM; + + host_client->maxmodels = 256; } MSG_WriteByte (&host_client->netchan.message, (sv.allocated_client_slots>16)?16:sv.allocated_client_slots); break; @@ -565,6 +548,10 @@ void SVNQ_New_f (void) break; } + //the protocol limits were recalculated to avoid any nasty surprises when things default to forcing a protocol + if (maxents != host_client->max_net_ents && !(host_client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)) + host_client->max_net_ents = maxents; + if (!coop.value && deathmatch.value) MSG_WriteByte (&host_client->netchan.message, GAME_DEATHMATCH); else @@ -597,7 +584,7 @@ void SVNQ_New_f (void) // set view MSG_WriteByte (&host_client->netchan.message, svc_setview); - MSG_WriteShort (&host_client->netchan.message, NUM_FOR_EDICT(svprogfuncs, host_client->edict)); + MSG_WriteEntity (&host_client->netchan.message, NUM_FOR_EDICT(svprogfuncs, host_client->edict)); MSG_WriteByte (&host_client->netchan.message, svc_signonnum); MSG_WriteByte (&host_client->netchan.message, 1); @@ -607,6 +594,9 @@ void SVNQ_New_f (void) // host_client->sendsignon = true; // host_client->spawned = false; // need prespawn, spawn, etc + + host_client->prespawn_stage = PRESPAWN_MAPCHECK; + host_client->prespawn_idx = 0; } @@ -866,172 +856,15 @@ void SVQ2_NextServer_f (void) } #endif -void SV_PK3List_f (void) -{ -#ifndef PEXT_PK3DOWNLOADS - Con_Printf ("pk3list not valid -- It's not implemented!\n"); - return; -#else - int crc; - char *name; - int i; - - - if (host_client->state != cs_connected) - { //fixme: send prints instead - Con_Printf ("pk3list not valid -- already spawned\n"); - return; - } - - // handle the case of a level changing while a client was connecting - if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo) - { - Con_Printf ("SV_PK3List_f from different level\n"); - SV_New_f (); - return; - } - - i = atoi(Cmd_Argv(2)); - -//NOTE: This doesn't go through ClientReliableWrite since it's before the user -//spawns. These functions are written to not overflow - if (host_client->num_backbuf) - { - char *msg = va("cmd pk3list %s %s\n", Cmd_Argv(1), Cmd_Argv(2)); - Con_TPrintf(STL_BACKBUFSET, host_client->name, host_client->netchan.message.cursize); - ClientReliableWrite_Begin(host_client, svc_stufftext, 2+strlen(msg)); - ClientReliableWrite_String(&host_client->netchan.message, msg); - return; - } - if (i < 0) - { - Con_Printf ("SV_PK3List_f: %s tried to crash us\n", host_client->name); - SV_DropClient(host_client); - return; - } - - for (; ; i++) - { - if (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) - { //user's buffer was too small - MSG_WriteByte(&host_client->netchan.message, svc_stufftext); - MSG_WriteString(&host_client->netchan.message, va("cmd pk3list %i %i\n", svs.spawncount, 0)); - return; //and stop before we flood them - } - - name = COM_GetPathInfo(i, &crc); - - if (name && *name) - { - MSG_WriteByte(&host_client->netchan.message, svc_stufftext); - MSG_WriteString(&host_client->netchan.message, va("echo packfile %s\n", name)); - continue; //try the next. - } - //that's all folks, move on to sound. - MSG_WriteByte(&host_client->netchan.message, svc_stufftext); - MSG_WriteString(&host_client->netchan.message, va("soundlist %i 0\n", svs.spawncount)); - return; - } -#endif -} - /* ================== SV_Soundlist_f ================== */ -void SV_Soundlist_f (void) +void SVQW_Soundlist_f (void) { - unsigned int i; - //char **s; - unsigned int n; - unsigned int maxclientsupportedsounds; - - if (host_client->state != cs_connected) - { - Con_Printf ("soundlist not valid -- already spawned\n"); - return; - } - - // handle the case of a level changing while a client was connecting - if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo) - { - Con_Printf ("SV_Soundlist_f from different level\n"); - SV_New_f (); - return; - } - - n = atoi(Cmd_Argv(2)); - -//NOTE: This doesn't go through ClientReliableWrite since it's before the user -//spawns. These functions are written to not overflow - if (host_client->num_backbuf) - { - char *msg = va("cmd soundlist %s %s\n", Cmd_Argv(1), Cmd_Argv(2)); - Con_TPrintf(STL_BACKBUFSET, host_client->name, host_client->netchan.message.cursize); - ClientReliableWrite_Begin(host_client, svc_stufftext, 1+strlen(msg)); - ClientReliableWrite_String(host_client, msg); - return; - } - - if (n >= MAX_SOUNDS) - { - SV_EndRedirect(); - Con_Printf ("SV_Soundlist_f: %s send an invalid index\n", host_client->name); - SV_DropClient(host_client); - return; - } - -#ifdef PEXT_SOUNDDBL - if (n > 255) - { - MSG_WriteByte (&host_client->netchan.message, svcfte_soundlistshort); - MSG_WriteShort (&host_client->netchan.message, n); - } - else -#endif - { - MSG_WriteByte (&host_client->netchan.message, svc_soundlist); - MSG_WriteByte (&host_client->netchan.message, n); - } - - maxclientsupportedsounds = 256; -#ifdef PEXT_SOUNDDBL - if (host_client->fteprotocolextensions & PEXT_SOUNDDBL) - maxclientsupportedsounds *= 2; -#endif - -#ifdef SERVER_DEMO_PLAYBACK - if (sv.democausesreconnect) //read the list from somewhere else - { - for (i = 1+n; - *sv.demsound_precache[i] && host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2); - i++, n++) - MSG_WriteString (&host_client->netchan.message, sv.demsound_precache[i]); - - - if (!*sv.demsound_precache[i]) - n = 0; - } - else -#endif - { - for (i = 1+n; - i < maxclientsupportedsounds && *sv.strings.sound_precache[i] && host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2); - i++, n++) - { - MSG_WriteString (&host_client->netchan.message, sv.strings.sound_precache[i]); - if (((n&255)==255) && n != i-1) - break; - } - - if (!*sv.strings.sound_precache[i]) - n = 0; - } - MSG_WriteByte (&host_client->netchan.message, 0); - - // next msg - MSG_WriteByte (&host_client->netchan.message, n & 0xff); + if (host_client->prespawn_stage == PRESPAWN_SOUNDLIST) + host_client->prespawn_idx &= ~0x80000000; } /* @@ -1039,128 +872,454 @@ void SV_Soundlist_f (void) SV_Modellist_f ================== */ -void SV_Modellist_f (void) +void SVQW_Modellist_f (void) { - unsigned int i; - unsigned int n; - qboolean initial; + if (host_client->prespawn_stage == PRESPAWN_MODELLIST) + host_client->prespawn_idx &= ~0x80000000; +} - if (host_client->state != cs_connected) +void SV_SendClientPrespawnInfo(client_t *client) +{ + qboolean started; + int i; + entity_state_t *state; + edict_t *ent; + svcustomtents_t *ctent; + //much of this function is written to fill packets enough to overflow them (assuming max packet sizes are large enough), but some bits are lazy and just backbuffer as needed. + + if (client->num_backbuf) { - Con_Printf ("modellist not valid -- already spawned\n"); + //don't spam too much. return; } - // handle the case of a level changing while a client was connecting - if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo) + if (client->prespawn_stage == PRESPAWN_SERVERINFO) { - Con_Printf ("SV_Modellist_f from different level\n"); - SV_New_f (); - return; - } + char buffer[1024]; - n = atoi(Cmd_Argv(2)); - - if (n >= MAX_MODELS) - { - SV_EndRedirect(); - Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name); - SV_DropClient(host_client); - return; - } - -//NOTE: This doesn't go through ClientReliableWrite since it's before the user -//spawns. These functions are written to not overflow - if (host_client->num_backbuf) - { - char *msg = va("cmd modellist %s %s\n", Cmd_Argv(1), Cmd_Argv(2)); - Con_TPrintf(STL_BACKBUFSET, host_client->name, host_client->netchan.message.cursize); - ClientReliableWrite_Begin(host_client, svc_stufftext, 1+strlen(msg)); - ClientReliableWrite_String(host_client, msg); - return; - } - - initial = (n==0); - -#ifdef PEXT_MODELDBL - if (n > 255) - { - MSG_WriteByte (&host_client->netchan.message, svcfte_modellistshort); - MSG_WriteShort (&host_client->netchan.message, n); - } - else -#endif - { - MSG_WriteByte (&host_client->netchan.message, svc_modellist); - MSG_WriteByte (&host_client->netchan.message, n); - } - -#ifdef SERVER_DEMO_PLAYBACK - if (sv.democausesreconnect) //read the list from somewhere else - { - for (i = 1+n; - *sv.demmodel_precache[i] && ((n&255)==0||host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)); - i++, n++) - MSG_WriteString (&host_client->netchan.message, sv.demmodel_precache[i]); - - if (!*sv.demmodel_precache[i]) - n = 0; - } - else -#endif - { - for (i = 1+n; - i < host_client->maxmodels && sv.strings.model_precache[i] && (((i-1)&255)==0 || host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)); //make sure we don't send a 0 next... - i++) + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) { - MSG_WriteString (&host_client->netchan.message, sv.strings.model_precache[i]); - } - n = i-1; - - if (!sv.strings.model_precache[i]) - n = 0; - } - - if (i == host_client->maxmodels) - n = 0; //doh! - - MSG_WriteByte (&host_client->netchan.message, 0); - - // next msg - MSG_WriteByte (&host_client->netchan.message, n & 0xff); - - - if (initial && (host_client->zquake_extensions & Z_EXT_VWEP)) - { - char mname[MAX_QPATH]; - char vweaplist[1024] = "//vwep"; - //int pos = strlen(vweaplist); // warning: unused variable ‘pos’ - - for (i = 0; sv.strings.vw_model_precache[i]; i++) - { - //grab the model name... without a progs/ prefix if it has one - if (!strncmp(sv.strings.vw_model_precache[i], "progs/", 6)) - Q_strncpy(mname, sv.strings.vw_model_precache[i]+6, sizeof(mname)); + if (client->prespawn_idx == 0) + { + ClientReliableWrite_Begin(client, svc_stufftext, 20 + strlen(svs.info)); + ClientReliableWrite_String (client, va("fullserverinfo \"%s\"\n", svs.info) ); + } + else if (client->prespawn_idx == 1) + { + ClientReliableWrite_Begin(client, svc_cdtrack, 2); + if (progstype == PROG_H2) + ClientReliableWrite_Byte (client, sv.h2cdtrack); + else if (svprogfuncs) + ClientReliableWrite_Byte (client, ((edict_t*)sv.world.edicts)->v->sounds); + else + ClientReliableWrite_Byte (client, 0); + } + else if (client->prespawn_idx == 2) + { + FS_GetPackNames(buffer, sizeof(buffer), 2, true); /*retain extensions, or we'd have to assume pk3*/ + ClientReliableWrite_Begin(client, svc_stufftext, 1+11+strlen(buffer)+1+1); + ClientReliableWrite_SZ(client, "//paknames ", 11); + ClientReliableWrite_SZ(client, buffer, strlen(buffer)); + ClientReliableWrite_String(client, "\n"); + } + else if (client->prespawn_idx == 3) + { + FS_GetPackHashes(buffer, sizeof(buffer), false); + ClientReliableWrite_Begin(client, svc_stufftext, 1+7+strlen(buffer)+1+1); + ClientReliableWrite_SZ(client, "//paks ", 7); + ClientReliableWrite_SZ(client, buffer, strlen(buffer)); + ClientReliableWrite_String(client, "\n"); + } else - Q_strncpy(mname, sv.strings.vw_model_precache[i], sizeof(mname)); - - //strip .mdl extensions - if (!strcmp(COM_FileExtension(mname), "mdl")) - COM_StripExtension(mname, mname, sizeof(mname)); - - //add it to the vweap command, taking care of any remaining spaces in names. - if (strchr(mname, ' ')) - Q_strncatz(vweaplist, va(" \"%s\"", mname), sizeof(vweaplist)); - else - Q_strncatz(vweaplist, va(" %s", mname), sizeof(vweaplist)); + { + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + client->prespawn_idx++; } + } - if (strlen(vweaplist) <= sizeof(vweaplist)-2) + if (client->prespawn_stage == PRESPAWN_SOUNDLIST) + { + int maxclientsupportedsounds = 256; +#ifdef PEXT_SOUNDDBL + if (client->fteprotocolextensions & PEXT_SOUNDDBL) + maxclientsupportedsounds = MAX_SOUNDS; +#endif + started = false; + + //allows stalling for the soundlist command, for compat. + if (host_client->prespawn_idx & 0x80000000) + return; + + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) { - Q_strncatz(vweaplist, "\n", sizeof(vweaplist)); + if (!started) + { + started = true; +#ifdef PEXT_SOUNDDBL + if (client->prespawn_idx > 255) + { + MSG_WriteByte (&client->netchan.message, svcfte_soundlistshort); + MSG_WriteShort (&client->netchan.message, client->prespawn_idx); + } + else +#endif + { + MSG_WriteByte (&client->netchan.message, svc_soundlist); + MSG_WriteByte (&client->netchan.message, client->prespawn_idx); + } + } + client->prespawn_idx++; - ClientReliableWrite_Begin(host_client, svc_stufftext, 2+strlen(vweaplist)); - ClientReliableWrite_String(host_client, vweaplist); + if (client->prespawn_idx >= maxclientsupportedsounds || !*sv.strings.sound_precache[client->prespawn_idx]) + { + //write final-end-of-list + MSG_WriteByte (&client->netchan.message, 0); + MSG_WriteByte (&client->netchan.message, 0); + started = 0; + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + else + MSG_WriteString (&client->netchan.message, sv.strings.sound_precache[client->prespawn_idx]); + } + if (started) + { + //write end-of-packet + MSG_WriteByte (&client->netchan.message, 0); + MSG_WriteByte (&client->netchan.message, (client->prespawn_idx&0xff)?client->prespawn_idx:0xff); + + if (!(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)) + host_client->prespawn_idx |= 0x80000000; + } + } + if (client->prespawn_stage == PRESPAWN_MODELLIST) + { + started = false; + + //allows stalling for the soundlist command, for compat. + if (host_client->prespawn_idx & 0x80000000) + return; + + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) + { + if (!started) + { + started = true; +#ifdef PEXT_SOUNDDBL + if (client->prespawn_idx > 255) + { + MSG_WriteByte (&client->netchan.message, svcfte_modellistshort); + MSG_WriteShort (&client->netchan.message, client->prespawn_idx); + } + else +#endif + { + MSG_WriteByte (&client->netchan.message, svc_modellist); + MSG_WriteByte (&client->netchan.message, client->prespawn_idx); + } + } + client->prespawn_idx++; + + if (client->prespawn_idx >= client->maxmodels || !sv.strings.model_precache[client->prespawn_idx]) + { + //write final-end-of-list + MSG_WriteByte (&client->netchan.message, 0); + MSG_WriteByte (&client->netchan.message, 0); + started = 0; + + if (client->zquake_extensions & Z_EXT_VWEP) + { + char mname[MAX_QPATH]; + char vweaplist[1024] = "//vwep"; + + for (i = 0; sv.strings.vw_model_precache[i]; i++) + { + //grab the model name... without a progs/ prefix if it has one + if (!strncmp(sv.strings.vw_model_precache[i], "progs/", 6)) + Q_strncpy(mname, sv.strings.vw_model_precache[i]+6, sizeof(mname)); + else + Q_strncpy(mname, sv.strings.vw_model_precache[i], sizeof(mname)); + + //strip .mdl extensions, for compat with ezquake + if (!strcmp(COM_FileExtension(mname), "mdl")) + COM_StripExtension(mname, mname, sizeof(mname)); + + //add it to the vweap command, taking care of any remaining spaces in names. + if (strchr(mname, ' ') || !*mname) + Q_strncatz(vweaplist, va(" \"%s\"", mname), sizeof(vweaplist)); + else + Q_strncatz(vweaplist, va(" %s", mname), sizeof(vweaplist)); + } + + if (strlen(vweaplist) <= sizeof(vweaplist)-2) + { + Q_strncatz(vweaplist, "\n", sizeof(vweaplist)); + + ClientReliableWrite_Begin(client, svc_stufftext, 2+strlen(vweaplist)); + ClientReliableWrite_String(client, vweaplist); + } + } + + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + else + MSG_WriteString (&client->netchan.message, sv.strings.model_precache[client->prespawn_idx]); + } + if (started) + { + //write end-of-packet + MSG_WriteByte (&client->netchan.message, 0); + MSG_WriteByte (&client->netchan.message, (client->prespawn_idx&0xff)?client->prespawn_idx:0xff); + + if (!(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)) + host_client->prespawn_idx |= 0x80000000; + } + } + + if (client->prespawn_stage == PRESPAWN_MAPCHECK) + { + //can't progress beyond this as we're waiting for the client. + host_client->prespawn_idx = client->prespawn_idx; + return; + } + + if (client->prespawn_stage == PRESPAWN_CUSTOMTENTS) + { + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) + { + if (client->prespawn_idx >= 255) + { + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + + ctent = &sv.customtents[client->prespawn_idx]; + + if (*ctent->particleeffecttype) + { + if (client->fteprotocolextensions & PEXT_CUSTOMTEMPEFFECTS) + { + MSG_WriteByte(&client->netchan.message, svcfte_customtempent); + MSG_WriteByte(&client->netchan.message, 255); + MSG_WriteByte(&client->netchan.message, client->prespawn_idx); + MSG_WriteByte(&client->netchan.message, ctent->netstyle); + MSG_WriteString(&client->netchan.message, ctent->particleeffecttype); + if (ctent->netstyle & CTE_STAINS) + { + MSG_WriteChar(&client->netchan.message, ctent->stain[0]); + MSG_WriteChar(&client->netchan.message, ctent->stain[0]); + MSG_WriteChar(&client->netchan.message, ctent->stain[0]); + MSG_WriteByte(&client->netchan.message, ctent->radius); + } + if (ctent->netstyle & CTE_GLOWS) + { + MSG_WriteByte(&client->netchan.message, ctent->dlightrgb[0]); + MSG_WriteByte(&client->netchan.message, ctent->dlightrgb[1]); + MSG_WriteByte(&client->netchan.message, ctent->dlightrgb[2]); + MSG_WriteByte(&client->netchan.message, ctent->dlightradius); + MSG_WriteByte(&client->netchan.message, ctent->dlighttime); + } + } + } + client->prespawn_idx++; + } + } + + if (client->prespawn_stage == PRESPAWN_SIGNON_BUF) + { + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) + { + if (client->prespawn_idx >= sv.num_signon_buffers) + { + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + + if (client->netchan.message.cursize+sv.signon_buffer_size[client->prespawn_idx]+30 < client->netchan.message.maxsize) + { + SZ_Write (&client->netchan.message, + sv.signon_buffers[client->prespawn_idx], + sv.signon_buffer_size[client->prespawn_idx]); + } + else + break; + client->prespawn_idx++; + } + } + + if (client->prespawn_stage == PRESPAWN_SPAWNSTATIC) + { + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) //static entities + { + if (client->prespawn_idx >= sv.num_static_entities) + { + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + + state = &sv_staticentities[client->prespawn_idx]; + client->prespawn_idx++; + + if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + { + MSG_WriteByte(&client->netchan.message, svc_spawnstatic2); + SVFTE_EmitBaseline(state, false, &client->netchan.message); + continue; + } + if (client->fteprotocolextensions & PEXT_SPAWNSTATIC2) + { + /*if it uses some new feature, use the updated spawnstatic*/ + if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight) + { + MSG_WriteByte(&client->netchan.message, svc_spawnstatic2); + SVQW_WriteDelta(&nullentitystate, state, &client->netchan.message, true, client->fteprotocolextensions); + continue; + } + } + /*couldn't use protocol extensions? + use the fallback, unless the model is invalid as that's silly*/ + if (state->modelindex < 256) + { + MSG_WriteByte(&client->netchan.message, svc_spawnstatic); + + MSG_WriteByte (&client->netchan.message, state->modelindex); + + MSG_WriteByte (&client->netchan.message, state->frame); + MSG_WriteByte (&client->netchan.message, (int)state->colormap); + MSG_WriteByte (&client->netchan.message, (int)state->skinnum); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&client->netchan.message, state->origin[i]); + MSG_WriteAngle(&client->netchan.message, state->angles[i]); + } + continue; + } + } + } + + if (client->prespawn_stage == PRESPAWN_BASELINES) + { + while (client->netchan.message.cursize < (client->netchan.message.maxsize/2)) //baselines + { + if (client->prespawn_idx >= sv.world.num_edicts) + { + client->prespawn_stage++; + client->prespawn_idx = 0; + break; + } + + ent = EDICT_NUM(svprogfuncs, client->prespawn_idx); + + if (!ent) + state = &nullentitystate; + else + state = &ent->baseline; + + if (!state->number || !state->modelindex) + { //ent doesn't have a baseline + client->prespawn_idx++; + continue; + } + + if (state->number >= client->max_net_ents || state->modelindex >= client->maxmodels) + { + /*can't send this ent*/ + } + else if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) + { + MSG_WriteByte(&client->netchan.message, svcfte_spawnbaseline2); + SVFTE_EmitBaseline(state, true, &client->netchan.message); + } + else if (client->fteprotocolextensions & PEXT_SPAWNSTATIC2) + { + MSG_WriteByte(&client->netchan.message, svcfte_spawnbaseline2); + SVQW_WriteDelta(&nullentitystate, state, &client->netchan.message, true, client->fteprotocolextensions); + } + else if (ISDPCLIENT(client) && (state->modelindex > 255 || state->frame > 255)) + { + MSG_WriteByte(&client->netchan.message, svcdp_spawnbaseline2); + MSG_WriteEntity (&client->netchan.message, state->number); + + MSG_WriteShort (&client->netchan.message, state->modelindex); + MSG_WriteShort (&client->netchan.message, state->frame); + MSG_WriteByte (&client->netchan.message, (int)state->colormap); + MSG_WriteByte (&client->netchan.message, (int)state->skinnum); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&client->netchan.message, state->origin[i]); + MSG_WriteAngle(&client->netchan.message, state->angles[i]); + } + } + else if (client->protocol == SCP_FITZ666 && (state->modelindex > 255 || state->frame > 255 || state->trans != 255 || state->scale != 16)) + { + int fl = 0; + if (state->modelindex > 255) fl |= FITZ_B_LARGEMODEL; + if (state->frame > 255) fl |= FITZ_B_LARGEFRAME; + if (state->trans != 255) fl |= FITZ_B_ALPHA; + if (state->scale != 16) fl |= RMQFITZ_B_SCALE; + + MSG_WriteByte(&client->netchan.message, svcfitz_spawnbaseline2); + MSG_WriteEntity (&client->netchan.message, state->number); + MSG_WriteByte(&client->netchan.message, fl); + if (fl & FITZ_B_LARGEMODEL) + MSG_WriteShort (&client->netchan.message, state->modelindex); + else + MSG_WriteByte (&client->netchan.message, state->modelindex); + if (fl & FITZ_B_LARGEFRAME) + MSG_WriteShort (&client->netchan.message, state->frame); + else + MSG_WriteByte (&client->netchan.message, state->frame); + MSG_WriteByte (&client->netchan.message, state->colormap); + MSG_WriteByte (&client->netchan.message, state->skinnum); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&client->netchan.message, state->origin[i]); + MSG_WriteAngle(&client->netchan.message, state->angles[i]); + } + if (fl & FITZ_B_ALPHA) + MSG_WriteByte (&client->netchan.message, state->trans); + if (fl & RMQFITZ_B_SCALE) + MSG_WriteByte (&client->netchan.message, state->scale); + } + else if (state->modelindex) + { + MSG_WriteByte(&client->netchan.message, svc_spawnbaseline); + MSG_WriteEntity (&client->netchan.message, state->number); + + if (state->modelindex > 255) + MSG_WriteByte (&client->netchan.message, 0); //invalid modelindex. at least try to give something + else + MSG_WriteByte (&client->netchan.message, state->modelindex); + MSG_WriteByte (&client->netchan.message, state->frame&255); + MSG_WriteByte (&client->netchan.message, (int)state->colormap); + MSG_WriteByte (&client->netchan.message, (int)state->skinnum); + for (i=0 ; i<3 ; i++) + { + MSG_WriteCoord(&client->netchan.message, state->origin[i]); + MSG_WriteAngle(&client->netchan.message, state->angles[i]); + } + } + + client->prespawn_idx++; + } + } + if (client->prespawn_stage == PRESPAWN_DONE) + { + if (!client->prespawn_idx) + { + //we'll spawn the client and then send all the updating stuff only when we know the channel is clear, by pinging the client for it. + MSG_WriteByte (&client->netchan.message, svc_stufftext); + MSG_WriteString (&client->netchan.message, va("cmd spawn %i\n",svs.spawncount) ); + client->prespawn_idx++; } } } @@ -1170,44 +1329,32 @@ void SV_Modellist_f (void) SV_PreSpawn_f ================== */ -enum -{ - PRESPAWN_MAPCHECK=0, - PRESPAWN_CUSTOMTENTS, - PRESPAWN_SIGNON_BUF, - PRESPAWN_SPAWNSTATIC, - PRESPAWN_BASELINES, - PRESPAWN_DONE -}; void SVQW_PreSpawn_f (void) { - unsigned initbuf; unsigned check; - unsigned int ps_type; - unsigned int ps_idx; if (host_client->state != cs_connected) { Con_Printf ("prespawn not valid -- already spawned\n"); return; } + if (host_client->prespawn_stage != PRESPAWN_MAPCHECK) + { + Con_Printf("Wrong stage for prespawn command\n"); + return; + } // handle the case of a level changing while a client was connecting if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo) { Con_Printf ("SV_PreSpawn_f from different level\n"); + //FIXME: we shouldn't need the following line. SV_New_f (); return; } - initbuf = atoi(Cmd_Argv(2)); - - ps_type = (initbuf & 0xff000000) >> 24; - ps_idx = (initbuf & 0x00ffffff); - - if (ps_type == PRESPAWN_MAPCHECK) + if (host_client->prespawn_stage == PRESPAWN_MAPCHECK) { - // should be three numbers following containing checksums check = COM_RemapMapChecksum(atoi(Cmd_Argv(3))); // Con_DPrintf("Client check = %d\n", check); @@ -1231,238 +1378,10 @@ void SVQW_PreSpawn_f (void) return; } host_client->checksum = check; - ps_type++; - ps_idx = 0; - } - -//NOTE: This doesn't go through ClientReliableWrite since it's before the user -//spawns. These functions are written to not overflow - if (host_client->num_backbuf) - { - char *msg = va("cmd prespawn %s %s %s\n", Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3)); - Con_TPrintf(STL_BACKBUFSET, host_client->name, host_client->netchan.message.cursize); - ClientReliableWrite_Begin(host_client, svc_stufftext, 1+strlen(msg)); - ClientReliableWrite_String(host_client, msg); + host_client->prespawn_stage = PRESPAWN_MAPCHECK+1; + host_client->prespawn_idx = 0; return; } - -#ifdef SERVER_DEMO_PLAYBACK - if (sv.democausesreconnect) - { - if (host_client->netchan.message.cursize+sv.demosignon_buffer_size[buf]+30 < host_client->netchan.message.maxsize) - { - SZ_Write (&host_client->netchan.message, - sv.demosignon_buffers[buf], - sv.demosignon_buffer_size[buf]); - buf++; - } - start = sv.num_demosignon_buffers; - } - else -#endif - { - int i; - entity_state_t *state; - edict_t *ent; - svcustomtents_t *ctent; - - if (ps_type == PRESPAWN_CUSTOMTENTS) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) - { - if (ps_idx >= 255) - { - ps_type++; - ps_idx = 0; - break; - } - - ctent = &sv.customtents[ps_idx]; - - if (*ctent->particleeffecttype) - { - if (host_client->fteprotocolextensions & PEXT_CUSTOMTEMPEFFECTS) - { - MSG_WriteByte(&host_client->netchan.message, svcfte_customtempent); - MSG_WriteByte(&host_client->netchan.message, 255); - MSG_WriteByte(&host_client->netchan.message, ps_idx); - MSG_WriteByte(&host_client->netchan.message, ctent->netstyle); - MSG_WriteString(&host_client->netchan.message, ctent->particleeffecttype); - if (ctent->netstyle & CTE_STAINS) - { - MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]); - MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]); - MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]); - MSG_WriteByte(&host_client->netchan.message, ctent->radius); - } - if (ctent->netstyle & CTE_GLOWS) - { - MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[0]); - MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[1]); - MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[2]); - MSG_WriteByte(&host_client->netchan.message, ctent->dlightradius); - MSG_WriteByte(&host_client->netchan.message, ctent->dlighttime); - } - } - } - ps_idx++; - } - } - - if (ps_type == PRESPAWN_SIGNON_BUF) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) - { - if (ps_idx >= sv.num_signon_buffers) - { - ps_type++; - ps_idx = 0; - break; - } - - if (host_client->netchan.message.cursize+sv.signon_buffer_size[ps_idx]+30 < host_client->netchan.message.maxsize) - { - SZ_Write (&host_client->netchan.message, - sv.signon_buffers[ps_idx], - sv.signon_buffer_size[ps_idx]); - } - else - break; - ps_idx++; - } - } - - if (ps_type == PRESPAWN_SPAWNSTATIC) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //static entities - { - if (ps_idx >= sv.num_static_entities) - { - ps_type++; - ps_idx = 0; - break; - } - - state = &sv_staticentities[ps_idx]; - ps_idx++; - - if (host_client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2); - SVFTE_EmitBaseline(state, false, &host_client->netchan.message); - continue; - } - if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2) - { - /*if it uses some new feature, use the updated spawnstatic*/ - if (state->hexen2flags || state->trans || state->modelindex >= 256 || state->frame > 255 || state->scale || state->abslight) - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2); - SVQW_WriteDelta(&nullentitystate, state, &host_client->netchan.message, true, host_client->fteprotocolextensions); - continue; - } - } - /*couldn't use protocol extensions? - use the fallback, unless the model is invalid as that's silly*/ - if (state->modelindex < 256) - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic); - - MSG_WriteByte (&host_client->netchan.message, state->modelindex); - - MSG_WriteByte (&host_client->netchan.message, state->frame); - MSG_WriteByte (&host_client->netchan.message, (int)state->colormap); - MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum); - for (i=0 ; i<3 ; i++) - { - MSG_WriteCoord(&host_client->netchan.message, state->origin[i]); - MSG_WriteAngle(&host_client->netchan.message, state->angles[i]); - } - continue; - } - } - } - - if (ps_type == PRESPAWN_BASELINES) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines - { - if (ps_idx >= sv.world.num_edicts) - { - ps_type++; - ps_idx = 0; - break; - } - - ent = EDICT_NUM(svprogfuncs, ps_idx); - - if (!ent) - state = &nullentitystate; - else - state = &ent->baseline; - - if (!state->number || !state->modelindex) - { //ent doesn't have a baseline - ps_idx++; - continue; - } - - if (state->number >= host_client->max_net_ents || state->modelindex >= host_client->maxmodels) - { - /*can't send this ent*/ - } - else if (host_client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) - { - MSG_WriteByte(&host_client->netchan.message, svcfte_spawnbaseline2); - SVFTE_EmitBaseline(state, true, &host_client->netchan.message); - } - else if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2) - { - MSG_WriteByte(&host_client->netchan.message, svcfte_spawnbaseline2); - SVQW_WriteDelta(&nullentitystate, state, &host_client->netchan.message, true, host_client->fteprotocolextensions); - } - else if (state->modelindex < 256) - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline); - - MSG_WriteShort (&host_client->netchan.message, ps_idx); - - MSG_WriteByte (&host_client->netchan.message, state->modelindex); - - MSG_WriteByte (&host_client->netchan.message, state->frame); - MSG_WriteByte (&host_client->netchan.message, (int)state->colormap); - MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum); - for (i=0 ; i<3 ; i++) - { - MSG_WriteCoord(&host_client->netchan.message, state->origin[i]); - MSG_WriteAngle(&host_client->netchan.message, state->angles[i]); - } - } - - ps_idx++; - } - } - } - - if (ps_type > PRESPAWN_DONE || (ps_type == PRESPAWN_DONE && ps_idx)) - { - SV_EndRedirect(); - Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name); - SV_DropClient(host_client); - return; - } - - if (ps_type == PRESPAWN_DONE) - { // all done prespawning - MSG_WriteByte (&host_client->netchan.message, svc_stufftext); - MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) ); - } - else - { // need to prespawn more - MSG_WriteByte (&host_client->netchan.message, svc_stufftext); - MSG_WriteString (&host_client->netchan.message, - va("cmd prespawn %i %i\n", svs.spawncount, (ps_type<<24) | ps_idx) ); - } } /* @@ -1483,6 +1402,12 @@ void SVQW_Spawn_f (void) Con_Printf ("Spawn not valid -- already spawned\n"); return; } + if (host_client->prespawn_stage != PRESPAWN_DONE) + { + Con_Printf ("client sent spawn without prespawn!\n"); + SV_New_f (); + return; + } // handle the case of a level changing while a client was connecting if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo) @@ -1654,7 +1579,7 @@ void SV_Begin_Core(client_t *split) if (ge) { ge->ClientUserinfoChanged (split->q2edict, split->userinfo); //tell the gamecode - SV_ExtractFromUserinfo(split); //let the server routines know + SV_ExtractFromUserinfo(split, true); //let the server routines know ge->ClientBegin(split->q2edict); split->istobeloaded = false; @@ -2634,7 +2559,7 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam char *p; for (p = name; *p; p++) - *p = (char)tolower(*p); + *p = (char)tolower((unsigned char)*p); } @@ -3532,7 +3457,7 @@ void SV_Rate_f (void) } Info_SetValueForKey (host_client->userinfo, "rate", Cmd_Argv(1), sizeof(host_client->userinfo)); - SV_ExtractFromUserinfo (host_client); + SV_ExtractFromUserinfo (host_client, true); SV_ClientTPrintf (host_client, PRINT_HIGH, STL_RATESETTO, SV_RateForClient(host_client)); } @@ -3633,7 +3558,7 @@ void SV_SetInfo_f (void) return; // key hasn't changed // process any changed values - SV_ExtractFromUserinfo (host_client); + SV_ExtractFromUserinfo (host_client, true); if (progstype != PROG_QW && !strcmp(Cmd_Argv(1), "bottomcolor")) { //team fortress has a nasty habit of booting people without this @@ -4381,7 +4306,13 @@ void SV_EnableClientsCSQC(void) { #ifdef PEXT_CSQC // if ((host_client->fteprotocolextensions & PEXT_CSQC) || atoi(Cmd_Argv(1))) + { host_client->csqcactive = true; + if (!host_client->csqcentversions) + host_client->csqcentversions = Z_Malloc(sizeof(*host_client->csqcentversions) * host_client->max_net_ents); + if (!host_client->csqcentsequence) + host_client->csqcentsequence = Z_Malloc(sizeof(*host_client->csqcentsequence) * host_client->max_net_ents); + } // else // SV_ClientPrintf(host_client, PRINT_HIGH, "CSQC entities not enabled - no support from network protocol\n"); #endif @@ -4611,113 +4542,11 @@ void SVNQ_Begin_f (void) } void SVNQ_PreSpawn_f (void) { - edict_t *ent; - entity_state_t *state; - int i, e; - int buf = atoi(Cmd_Argv(1)); - int st; - if (host_client->state != cs_connected) + if (host_client->prespawn_stage == PRESPAWN_MAPCHECK) { - Con_Printf ("prespawn not valid -- already spawned\n"); - return; - } - - st = 0; - - if (buf >= st) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) - { - i = buf-st; - if (i >= sv.num_signon_buffers) - break; - buf++; - SZ_Write (&host_client->netchan.message, sv.signon_buffers[i], sv.signon_buffer_size[i]); - } - } - st += sv.num_signon_buffers; - - if (buf >= st) - { - while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines - { - e = buf-st; - if (e >= sv.world.num_edicts) - { - if (e < sv.world.max_edicts) - buf += sv.world.max_edicts - sv.world.num_edicts; - break; - } - buf++; - - ent = EDICT_NUM(svprogfuncs, e); - state = &ent->baseline; - - if (!state->number || !state->modelindex) - { //ent doesn't have a baseline - continue; - } - - if (!ent) - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline); - - MSG_WriteShort (&host_client->netchan.message, e); - - MSG_WriteByte (&host_client->netchan.message, 0); - - MSG_WriteByte (&host_client->netchan.message, 0); - MSG_WriteByte (&host_client->netchan.message, 0); - MSG_WriteByte (&host_client->netchan.message, 0); - for (i=0 ; i<3 ; i++) - { - MSG_WriteCoord(&host_client->netchan.message, 0); - MSG_WriteAngle(&host_client->netchan.message, 0); - } - } - else - { - if (ISDPCLIENT(host_client) && (state->modelindex > 255 || state->frame > 255)) - { - MSG_WriteByte(&host_client->netchan.message, svcdp_spawnbaseline2); - - MSG_WriteShort (&host_client->netchan.message, e); - - MSG_WriteShort (&host_client->netchan.message, state->modelindex); - MSG_WriteShort (&host_client->netchan.message, state->frame); - } - else - { - MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline); - - MSG_WriteShort (&host_client->netchan.message, e); - - MSG_WriteByte (&host_client->netchan.message, state->modelindex&255); - MSG_WriteByte (&host_client->netchan.message, state->frame&255); - } - - MSG_WriteByte (&host_client->netchan.message, (int)state->colormap); - MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum); - for (i=0 ; i<3 ; i++) - { - MSG_WriteCoord(&host_client->netchan.message, state->origin[i]); - MSG_WriteAngle(&host_client->netchan.message, state->angles[i]); - } - } - } - } - st += sv.world.max_edicts; - - if (st == buf) - { - MSG_WriteByte (&host_client->netchan.message, svc_signonnum); - MSG_WriteByte (&host_client->netchan.message, 2); - } - else - { - char *s = va("cmd prespawn %i\n", buf); - ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(s)); - ClientReliableWrite_String (host_client, s); + host_client->checksum = ~0u; + host_client->prespawn_stage = PRESPAWN_MAPCHECK+1; + host_client->prespawn_idx = 0; } host_client->send_message = true; @@ -4770,7 +4599,7 @@ void SVNQ_NQColour_f (void) break; } - SV_ExtractFromUserinfo (host_client); + SV_ExtractFromUserinfo (host_client, true); MSG_WriteByte (&sv.reliable_datagram, svc_setinfo); MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients); @@ -4824,10 +4653,10 @@ void SV_Pext_f(void) switch(strtoul(tag, NULL, 0)) { case PROTOCOL_VERSION_FTE: - host_client->fteprotocolextensions = strtoul(val, NULL, 0) & Net_PextMask(1); + host_client->fteprotocolextensions = strtoul(val, NULL, 0) & Net_PextMask(1, ISNQCLIENT(host_client)); break; case PROTOCOL_VERSION_FTE2: - host_client->fteprotocolextensions2 = strtoul(val, NULL, 0) & Net_PextMask(2); + host_client->fteprotocolextensions2 = strtoul(val, NULL, 0) & Net_PextMask(2, ISNQCLIENT(host_client)); break; } } @@ -4898,11 +4727,8 @@ ucmd_t ucmds[] = { /*connection process*/ {"new", SV_New_f, true}, -#ifdef PEXT_PK3DOWNLOADS - {"pk3list", SV_PK3List_f, true}, -#endif - {"modellist", SV_Modellist_f, true}, - {"soundlist", SV_Soundlist_f, true}, + {"modellist", SVQW_Modellist_f, true}, + {"soundlist", SVQW_Soundlist_f, true}, {"prespawn", SVQW_PreSpawn_f, true}, {"spawn", SVQW_Spawn_f, true}, {"begin", SV_Begin_f, true}, @@ -5784,6 +5610,27 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) } WPhys_RunThink (&sv.world, (wedict_t*)sv_player); + + if (host_client->state && host_client->protocol == SCP_BAD) + { + //botclients update their movement during prethink. make sure we use that stuff. + ucmd->angles[0] = (int)(sv_player->v->v_angle[0] * (65535/360.0f)); + ucmd->angles[1] = (int)(sv_player->v->v_angle[1] * (65535/360.0f)); + ucmd->angles[2] = (int)(sv_player->v->v_angle[2] * (65535/360.0f)); + + if (host_frametime) + { + ucmd->forwardmove = sv_player->xv->movement[0] / host_frametime; + ucmd->sidemove = sv_player->xv->movement[1] / host_frametime; + ucmd->upmove = sv_player->xv->movement[2] / host_frametime; + } + else + { + ucmd->forwardmove = 0; + ucmd->sidemove = 0; + ucmd->upmove = 0; + } + } } // memset(&pmove, 0, sizeof(pmove)); @@ -6075,7 +5922,7 @@ void SV_ReadPrydonCursor(void) f = MSG_ReadFloat(); if (cursor_impact) cursor_impact->_vector[2] = f; - entnum = (unsigned short)MSG_ReadShort(); + entnum = MSGSV_ReadEntity(host_client); if (entnum >= sv.world.max_edicts) { Con_DPrintf("SV_ReadPrydonCursor: client send bad cursor_entitynumber\n"); @@ -6093,7 +5940,7 @@ void SV_ReadPrydonCursor(void) void SV_ReadQCRequest(void) { int e; - char args[7]; + char args[8]; char *rname; func_t f; int i; @@ -6109,7 +5956,7 @@ void SV_ReadQCRequest(void) for (i = 0; ; i++) { - if (i >= sizeof(args)) + if (i >= sizeof(args)-1) { if (MSG_ReadByte() != ev_void) { @@ -6142,7 +5989,7 @@ void SV_ReadQCRequest(void) break; case ev_entity: args[i] = 'e'; - e = MSG_ReadShort(); + e = MSGSV_ReadEntity(host_client); if (e < 0 || e >= sv.world.num_edicts) e = 0; G_INT(OFS_PARM0+i*3) = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, e)); @@ -6671,7 +6518,7 @@ void SVQ2_ExecuteClientMessage (client_t *cl) case clcq2_userinfo: strncpy (cl->userinfo, MSG_ReadString (), sizeof(cl->userinfo)-1); ge->ClientUserinfoChanged (cl->q2edict, cl->userinfo); //tell the gamecode - SV_ExtractFromUserinfo(cl); //let the server routines know + SV_ExtractFromUserinfo(cl, true); //let the server routines know break; case clcq2_stringcmd: diff --git a/engine/server/svhl_game.c b/engine/server/svhl_game.c index df671817..bbf06aa3 100644 --- a/engine/server/svhl_game.c +++ b/engine/server/svhl_game.c @@ -600,7 +600,7 @@ void QDECL GHL_WriteString(char *string) } void QDECL GHL_WriteEntity(int entnum) { - MSG_WriteShort(&sv.multicast, entnum); + MSG_WriteEntity(&sv.multicast, entnum); } diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index c9695843..1b9e557d 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -858,7 +858,7 @@ static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, case G_SET_USERINFO://int num, char *buffer 20 Q_strncpyz(svs.clients[VM_LONG(arg[0])].userinfo, VM_POINTER(arg[1]), sizeof(svs.clients[0].userinfo)); - SV_ExtractFromUserinfo(&svs.clients[VM_LONG(arg[0])]); + SV_ExtractFromUserinfo(&svs.clients[VM_LONG(arg[0])], false); break; case G_LINKENTITY: // ( gentity_t *ent ); 30 @@ -2373,7 +2373,7 @@ void SVQ3Q1_ConvertEntStateQ1ToQ3(entity_state_t *q1, q3entityState_t *q3) q3->legsAnim = 0; q3->groundEntityNum = 0; q3->pos.trType = 0; - q3->eFlags = q1->flags; + q3->eFlags = 0; q3->otherEntityNum = 0; q3->weapon = 0; q3->clientNum = q1->colormap; @@ -2895,7 +2895,7 @@ void SVQ3_UpdateUserinfo_f(client_t *cl) { Q_strncpyz(cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo)); - SV_ExtractFromUserinfo (cl); + SV_ExtractFromUserinfo (cl, true); if (svs.gametype == GT_QUAKE3) VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, (int)(cl-svs.clients)); @@ -3180,7 +3180,7 @@ void SVQ3_DirectConnect(void) //Actually connect the client, use up a slot, and cl->state = cs_connected; cl->name = cl->namebuf; cl->team = cl->teambuf; - SV_ExtractFromUserinfo(cl); + SV_ExtractFromUserinfo(cl, true); Netchan_Setup(NS_SERVER, &cl->netchan, net_from, qport); cl->netchan.outgoing_sequence = 1; diff --git a/engine/server/world.c b/engine/server/world.c index ecd6bba4..5a51711a 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -1293,13 +1293,13 @@ static model_t *WorldQ2_ModelForEntity (world_t *w, q2edict_t *ent) void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip ) { int i, num; - q2edict_t *touchlist[MAX_EDICTS], *touch; + q2edict_t *touchlist[MAX_Q2EDICTS], *touch; trace_t trace; model_t *model; float *angles; num = WorldQ2_AreaEdicts (w, clip->boxmins, clip->boxmaxs, touchlist - , MAX_EDICTS, AREA_SOLID); + , MAX_Q2EDICTS, AREA_SOLID); // be careful, it is possible to have an entity in this // list removed before we get to it (killtriggered) diff --git a/engine/sw/sw.h b/engine/sw/sw.h index 4fe36135..2a36acbe 100644 --- a/engine/sw/sw.h +++ b/engine/sw/sw.h @@ -147,7 +147,7 @@ texid_tf SW_LoadTexture8Pal24(char *identifier, int width, int height, qbyte *da texid_tf SW_LoadTexture8Pal32(char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags); texid_tf SW_LoadCompressed(char *name); texid_tf SW_FindTexture(char *identifier, unsigned int flags); -texid_tf SW_AllocNewTexture(char *identifier, int w, int h); +texid_tf SW_AllocNewTexture(char *identifier, int w, int h, unsigned int flags); void SW_Upload(texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags); void SW_DestroyTexture(texid_t tex); diff --git a/engine/sw/sw_image.c b/engine/sw/sw_image.c index 934016a7..b0530b5f 100644 --- a/engine/sw/sw_image.c +++ b/engine/sw/sw_image.c @@ -4,7 +4,7 @@ -texid_tf SW_AllocNewTexture(char *identifier, int w, int h) +texid_tf SW_AllocNewTexture(char *identifier, int w, int h, unsigned int flags) { texid_t n; swimage_t *img; @@ -72,7 +72,7 @@ texid_tf SW_LoadTexture(char *identifier, int width, int height, uploadfmt_t fmt { texid_t img = SW_FindTexture(identifier, flags); if (!img.ptr) - img = SW_AllocNewTexture(identifier, width, height); + img = SW_AllocNewTexture(identifier, width, height, flags); if (!img.ptr) return r_nulltex; switch(fmt) diff --git a/engine/sw/sw_vidwin.c b/engine/sw/sw_vidwin.c index 843e8af2..8877cfc0 100644 --- a/engine/sw/sw_vidwin.c +++ b/engine/sw/sw_vidwin.c @@ -276,7 +276,7 @@ qboolean SWAppActivate(BOOL fActive, BOOL minimize) sound_active = true; } - IN_UpdateGrabs(false, ActiveApp); + INS_UpdateGrabs(false, ActiveApp); /* if (fActive) @@ -542,7 +542,7 @@ LONG WINAPI MainWndProc ( if (wParam & MK_XBUTTON7) temp |= 512; - IN_MouseEvent (temp); + INS_MouseEvent (temp); } break; // JACK: This is the mouse wheel with the Intellimouse @@ -564,7 +564,7 @@ LONG WINAPI MainWndProc ( break; case WM_INPUT: // raw input handling - IN_RawInput_Read((HANDLE)lParam); + INS_RawInput_Read((HANDLE)lParam); break; /* case WM_DISPLAYCHANGE: if (!in_mode_set && (modestate == MS_WINDOWED) && !vid_fulldib_on_focus_mode) @@ -711,7 +711,7 @@ void SW_VID_SwapBuffers(void) DIB_SwapBuffers(); framenumber++; - IN_UpdateGrabs(false, ActiveApp); + INS_UpdateGrabs(false, ActiveApp); // memset( pDIBBase, 0, vid.pixelwidth * vid.pixelheight * 4); @@ -753,7 +753,23 @@ void SW_VID_ShiftPalette(unsigned char *palette) } char *SW_VID_GetRGBInfo(int prepad, int *truevidwidth, int *truevidheight) { - return NULL; + char *buf = NULL; + char *src, *dst; + int w, h; + buf = BZ_Malloc(prepad + (vid.pixelwidth * vid.pixelheight * 3)); + dst = buf + prepad; + for (h = 0; h < vid.pixelheight; h++) + { + for (w = 0, src = (char*)screenbuffer + (h * vid.pixelwidth*4); w < vid.pixelwidth; w++, dst += 3, src += 4) + { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } + } + *truevidwidth = vid.pixelwidth; + *truevidheight = vid.pixelheight; + return buf; } void SW_VID_SetWindowCaption(char *msg) {