diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 65fc9e040..6cf2011a8 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -595,15 +595,40 @@ qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t * } #include "com_mesh.h" + +#ifdef SKELETALMODELS +int QDECL Plug_RegisterModelFormatText(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)) +{ + void *module = currentplug; + return Mod_RegisterModelFormatText(module, formatname, magictext, load); +} +int QDECL Plug_RegisterModelFormatMagic(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)) +{ + void *module = currentplug; + return Mod_RegisterModelFormatMagic(module, formatname, magic, load); +} +void QDECL Plug_UnRegisterModelFormat(int idx) +{ + void *module = currentplug; + Mod_UnRegisterModelFormat(module, idx); +} +void QDECL Plug_UnRegisterAllModelFormats(void) +{ + void *module = currentplug; + Mod_UnRegisterAllModelFormats(module); +} +#endif qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, const qintptr_t *arg) { #ifdef SKELETALMODELS static modplugfuncs_t funcs = { - Mod_RegisterModelFormatText, - Mod_RegisterModelFormatMagic, - Mod_UnRegisterModelFormat, - Mod_UnRegisterAllModelFormats, + MODPLUGFUNCS_VERSION, + + Plug_RegisterModelFormatText, + Plug_RegisterModelFormatMagic, + Plug_UnRegisterModelFormat, + Plug_UnRegisterAllModelFormats, ZG_Malloc, R_ConcatTransforms, @@ -616,7 +641,7 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons R_RegisterSkin, R_BuildDefaultTexnums }; - if (VM_LONG(arg[0]) == sizeof(funcs)) + if (VM_LONG(arg[0]) >= sizeof(funcs)) return (qintptr_t)&funcs; else #endif diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 0da79954a..31c65a4d7 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -23,65 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "particles.h" entity_state_t *CL_FindPacketEntity(int num); -int - pt_muzzleflash=P_INVALID, - pt_gunshot=P_INVALID, - ptdp_gunshotquad=P_INVALID, - pt_spike=P_INVALID, - ptdp_spikequad=P_INVALID, - pt_superspike=P_INVALID, - ptdp_superspikequad=P_INVALID, - pt_wizspike=P_INVALID, - pt_knightspike=P_INVALID, - pt_explosion=P_INVALID, - ptdp_explosionquad=P_INVALID, - pt_tarexplosion=P_INVALID, - pt_teleportsplash=P_INVALID, - pt_lavasplash=P_INVALID, - ptdp_smallflash=P_INVALID, - ptdp_flamejet=P_INVALID, - ptdp_flame=P_INVALID, - ptdp_blood=P_INVALID, - ptdp_spark=P_INVALID, - ptdp_plasmaburn=P_INVALID, - ptdp_tei_g3=P_INVALID, - ptdp_tei_smoke=P_INVALID, - ptdp_tei_bigexplosion=P_INVALID, - ptdp_tei_plasmahit=P_INVALID, - ptdp_stardust=P_INVALID, - rt_rocket=P_INVALID, - rt_grenade=P_INVALID, - rt_blood=P_INVALID, - rt_wizspike=P_INVALID, - rt_slightblood=P_INVALID, - rt_knightspike=P_INVALID, - rt_vorespike=P_INVALID, - rtdp_neharasmoke=P_INVALID, - rtdp_nexuizplasma=P_INVALID, - rtdp_glowtrail=P_INVALID, - - ptqw_blood=P_INVALID, - ptqw_lightningblood=P_INVALID, - - ptq2_blood=P_INVALID, - rtq2_railtrail=P_INVALID, - rtq2_blastertrail=P_INVALID, - ptq2_blasterparticles=P_INVALID, - rtq2_bubbletrail=P_INVALID, - rtq2_gib=P_INVALID, - rtq2_rocket=P_INVALID, - rtq2_grenade=P_INVALID, - - rtqw_railtrail=P_INVALID, - rtfte_lightning1=P_INVALID, - ptfte_lightning1_end=P_INVALID, - rtfte_lightning2=P_INVALID, - ptfte_lightning2_end=P_INVALID, - rtfte_lightning3=P_INVALID, - ptfte_lightning3_end=P_INVALID, - ptfte_bullet=P_INVALID, - ptfte_superbullet=P_INVALID; - #ifdef Q2CLIENT typedef enum { @@ -156,8 +97,9 @@ typedef enum CRTE_STAIN, CRTE_FIRE, CRTE_CABLEGUT, - CRTE_SMOKE + CRTE_SMOKE, //CODERED + Q2TE_MAX } temp_event_t; #define Q2SPLASH_UNKNOWN 0 @@ -167,8 +109,150 @@ typedef enum #define Q2SPLASH_SLIME 4 #define Q2SPLASH_LAVA 5 #define Q2SPLASH_BLOOD 6 +#define Q2SPLASH_MAX 7 + +static const char *q2efnames[] = +{ + "GUNSHOT", + "BLOOD", + "BLASTER", + "RAILTRAIL", + "SHOTGUN", + "EXPLOSION1", + "EXPLOSION2", + "ROCKET_EXPLOSION", + "GRENADE_EXPLOSION", + "SPARKS", + "SPLASH", + "BUBBLETRAIL", + "SCREEN_SPARKS", + "SHIELD_SPARKS", + "BULLET_SPARKS", + "LASER_SPARKS", + "PARASITE_ATTACK", + "ROCKET_EXPLOSION_WATER", + "GRENADE_EXPLOSION_WATER", + "MEDIC_CABLE_ATTACK", + "BFG_EXPLOSION", + "BFG_BIGEXPLOSION", + "BOSSTPORT", + "BFG_LASER", + "GRAPPLE_CABLE", + "WELDING_SPARKS", + "GREENBLOOD", + "BLUEHYPERBLASTER", + "PLASMA_EXPLOSION", + "TUNNEL_SPARKS", + "BLASTER2", + "RAILTRAIL2", + "FLAME", + "LIGHTNING", + "DEBUGTRAIL", + "PLAIN_EXPLOSION", + "FLASHLIGHT", + "FORCEWALL", + "HEATBEAM", + "MONSTER_HEATBEAM", + "STEAM", + "BUBBLETRAIL2", + "MOREBLOOD", + "HEATBEAM_SPARKS", + "HEATBEAM_STEAM", + "CHAINFIST_SMOKE", + "ELECTRIC_SPARKS", + "TRACKER_EXPLOSION", + "TELEPORT_EFFECT", + "DBALL_GOAL", + "WIDOWBEAMOUT", + "NUKEBLAST", + "WIDOWSPLASH", + "EXPLOSION1_BIG", + "EXPLOSION1_NP", + "FLECHETTE", + "CR_LEADERBLASTER", + "CR_BLASTER_MUZZLEFLASH", + "CR_BLUE_MUZZLEFLASH", + "CR_SMART_MUZZLEFLASH", + "CR_LEADERFIELD", + "CR_DEATHFIELD", + "CR_BLASTERBEAM", + "CR_STAIN", + "CR_FIRE", + "CR_CABLEGUT", + "CR_SMOKE", + + + //q2te_max+ + "SPLASH_UNKNOWN", + "SPLASH_SPARKS", + "SPLASH_BLUE_WATER", + "SPLASH_BROWN_WATER", + "SPLASH_SLIME", + "SPLASH_LAVA", + "SPLASH_BLOOD", +}; +int pt_q2[sizeof(q2efnames)/sizeof(q2efnames[0])]; #endif +int + pt_muzzleflash=P_INVALID, + pt_gunshot=P_INVALID, + ptdp_gunshotquad=P_INVALID, + pt_spike=P_INVALID, + ptdp_spikequad=P_INVALID, + pt_superspike=P_INVALID, + ptdp_superspikequad=P_INVALID, + pt_wizspike=P_INVALID, + pt_knightspike=P_INVALID, + pt_explosion=P_INVALID, + ptdp_explosionquad=P_INVALID, + pt_tarexplosion=P_INVALID, + pt_teleportsplash=P_INVALID, + pt_lavasplash=P_INVALID, + ptdp_smallflash=P_INVALID, + ptdp_flamejet=P_INVALID, + ptdp_flame=P_INVALID, + ptdp_blood=P_INVALID, + ptdp_spark=P_INVALID, + ptdp_plasmaburn=P_INVALID, + ptdp_tei_g3=P_INVALID, + ptdp_tei_smoke=P_INVALID, + ptdp_tei_bigexplosion=P_INVALID, + ptdp_tei_plasmahit=P_INVALID, + ptdp_stardust=P_INVALID, + rt_rocket=P_INVALID, + rt_grenade=P_INVALID, + rt_blood=P_INVALID, + rt_wizspike=P_INVALID, + rt_slightblood=P_INVALID, + rt_knightspike=P_INVALID, + rt_vorespike=P_INVALID, + rtdp_neharasmoke=P_INVALID, + rtdp_nexuizplasma=P_INVALID, + rtdp_glowtrail=P_INVALID, + + ptqw_blood=P_INVALID, + ptqw_lightningblood=P_INVALID, + + ptq2_blood=P_INVALID, + rtq2_railtrail=P_INVALID, + rtq2_blastertrail=P_INVALID, + ptq2_blasterparticles=P_INVALID, + rtq2_bubbletrail=P_INVALID, + rtq2_gib=P_INVALID, + rtq2_rocket=P_INVALID, + rtq2_grenade=P_INVALID, + + rtqw_railtrail=P_INVALID, + rtfte_lightning1=P_INVALID, + ptfte_lightning1_end=P_INVALID, + rtfte_lightning2=P_INVALID, + ptfte_lightning2_end=P_INVALID, + rtfte_lightning3=P_INVALID, + ptfte_lightning3_end=P_INVALID, + ptfte_bullet=P_INVALID, + ptfte_superbullet=P_INVALID; + typedef struct { int entity; @@ -463,6 +547,9 @@ void CL_RegisterParticles(void) if (cls.protocol == CP_QUAKE2) { + for (i = 0; i < sizeof(pt_q2)/sizeof(pt_q2[0]); i++) + pt_q2[i] = P_FindParticleType(va("q2part.TEQ2_%s", q2efnames[i])); + ptq2_blood = P_FindParticleType("q2part.TEQ2_BLOOD"); rtq2_railtrail = P_FindParticleType("q2part.TR_RAILTRAIL"); rtq2_blastertrail = P_FindParticleType("q2part.TR_BLASTERTRAIL"); @@ -474,6 +561,8 @@ void CL_RegisterParticles(void) } else { + for (i = 0; i < sizeof(pt_q2)/sizeof(pt_q2[0]); i++) + pt_q2[i] = P_INVALID; ptq2_blood = P_INVALID; rtq2_railtrail = P_INVALID; rtq2_blastertrail = P_INVALID; @@ -736,6 +825,11 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n btype = P_FindParticleType("te_grapple_cable"); etype = P_FindParticleType("te_grapple_cable_end"); break; + case 6: + mname = "models/proj/beam/tris.md2"; + btype = P_FindParticleType("te_heatbeam"); + etype = P_FindParticleType("te_heatbeam_end"); + break; #endif } @@ -2322,6 +2416,7 @@ void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float void CLQ2_ParseTEnt (void) { int type; + int pt; vec3_t pos, pos2, dir; explosion_t *ex; int cnt; @@ -2332,36 +2427,113 @@ void CLQ2_ParseTEnt (void) type = MSG_ReadByte (); + if (type < sizeof(q2efnames)/sizeof(q2efnames[0])) + pt = pt_q2[type]; + else + pt = P_INVALID; + + if (pt == P_INVALID) + goto fixme; switch (type) { - case Q2TE_GUNSHOT: + case Q2TE_GUNSHOT: //grey tall thing with smoke+sparks + case Q2TE_BLOOD: //red tall thing + case Q2TE_SPARKS: //orange tall thing (with not many particles) + case Q2TE_BLASTER: //regular blaster + case Q2TE_SHOTGUN: //gunshot with less particles + case Q2TE_SCREEN_SPARKS://green+grey tall + case Q2TE_SHIELD_SPARKS://blue+grey tall + case Q2TE_BULLET_SPARKS://orange+grey tall+smoke + case Q2TE_GREENBLOOD: //yellow... + case Q2TE_BLASTER2: //green version of te_blaster + case Q2TE_MOREBLOOD: //te_blood*2 + case Q2TE_HEATBEAM_SPARKS://white outwards puffs + case Q2TE_HEATBEAM_STEAM://orange outwards puffs + case Q2TE_ELECTRIC_SPARKS://blue tall + case Q2TE_FLECHETTE: //grey version of te_blaster MSG_ReadPos (pos); MSG_ReadDir (dir); - P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_gunshot"); + P_RunParticleEffectType(pos, dir, 1, pt); break; - case Q2TE_BLOOD: - MSG_ReadPos (pos); - MSG_ReadDir (dir); - P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_blood"); - break; - case Q2TE_SHOTGUN: - MSG_ReadPos (pos); - MSG_ReadDir (dir); - P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_shotgun"); - break; - case Q2TE_BLASTER: - MSG_ReadPos (pos); - MSG_ReadDir (dir); - P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_blaster"); - break; - - case Q2TE_RAILTRAIL: // railgun effect + case Q2TE_RAILTRAIL: //blue spiral, grey particles + case Q2TE_BUBBLETRAIL: //grey sparse trail, slow riser + case Q2TE_BFG_LASER: //green lazor + case Q2TE_DEBUGTRAIL: //long lived blue trail + case Q2TE_BUBBLETRAIL2: //grey rising trail + case Q2TE_BLUEHYPERBLASTER: //TE_BLASTER without model+light MSG_ReadPos (pos); MSG_ReadPos (pos2); - if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL)) - P_ParticleTrailIndex(pos, pos2, 0x74, 8, NULL); - Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0); + P_ParticleTrail(pos, pos2, pt, 0, NULL); break; + case Q2TE_EXPLOSION1: //column + case Q2TE_EXPLOSION2: //splits + case Q2TE_ROCKET_EXPLOSION://top blob/column + case Q2TE_GRENADE_EXPLOSION://indistinguishable from TE_EXPLOSION2 + case Q2TE_ROCKET_EXPLOSION_WATER://rocket but with different sound + case Q2TE_GRENADE_EXPLOSION_WATER://different sound + case Q2TE_BFG_EXPLOSION://green light+sprite + case Q2TE_BFG_BIGEXPLOSION://green+white fast particles + case Q2TE_BOSSTPORT://splitting+merging+upwards particles. + case Q2TE_PLASMA_EXPLOSION://looks like rocket explosion to me + case Q2TE_PLAIN_EXPLOSION://looks like rocket explosion to me + case Q2TE_CHAINFIST_SMOKE://small smoke + case Q2TE_TRACKER_EXPLOSION://black light, slow particles + case Q2TE_TELEPORT_EFFECT://q1-style teleport + case Q2TE_DBALL_GOAL://q1-style teleport + case Q2TE_NUKEBLAST://dome expansion (blue/white particles) + case Q2TE_WIDOWSPLASH://dome (orange+gravity) + case Q2TE_EXPLOSION1_BIG://buggy model + case Q2TE_EXPLOSION1_NP://looks like a rocket explosion to me + MSG_ReadPos (pos); + P_RunParticleEffectType(pos, NULL, 1, pt); + break; + case Q2TE_SPLASH: + cnt = MSG_ReadByte (); + MSG_ReadPos (pos); + MSG_ReadDir (dir); + r = MSG_ReadByte (); + if (r >= Q2SPLASH_MAX) + r = Q2SPLASH_UNKNOWN; + pt = pt_q2[Q2TE_MAX + r]; + P_RunParticleEffectType(pos, NULL, 1, pt); + break; + + case Q2TE_PARASITE_ATTACK: + case Q2TE_MEDIC_CABLE_ATTACK: + CL_ParseBeam (3); + break; + case Q2TE_HEATBEAM: + case Q2TE_MONSTER_HEATBEAM: + CL_ParseBeam (6); + break; + case Q2TE_GRAPPLE_CABLE: + CL_ParseBeam (4); + MSG_ReadPos (pos); + break; +/* + case Q2TE_LASER_SPARKS: + case Q2TE_WELDING_SPARKS: + case Q2TE_TUNNEL_SPARKS: + break; + + //Q2TE_RAILTRAIL2, ? + //Q2TE_FLAME, ? + case Q2TE_LIGHTNING: + break; + + case Q2TE_FLASHLIGHT: + break; + case Q2TE_FORCEWALL: + break; + + case Q2TE_STEAM: + break; + + case Q2TE_WIDOWBEAMOUT: + break; +*/ + + default: goto fixme; // Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type); @@ -2579,6 +2751,7 @@ fixme: ex->firstframe = 30; ex->flags |= RF_TRANSLUCENT; ex->numframes = 19; + ex->skinnum = -1; } break; /* @@ -2675,6 +2848,7 @@ fixme: else ex->firstframe = 0; ex->numframes = 15; + ex->skinnum = -1; } break; /* diff --git a/engine/client/keys.c b/engine/client/keys.c index 3186306da..d6a48fcf5 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -1640,8 +1640,10 @@ void Key_Bind_f (void) if (c == 2) { - if (keybindings[b][0]) - Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b][0] ); + if (modifier == ~0) //modifier unspecified. default to no modifier + modifier = 0; + if (keybindings[b][modifier]) + Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b][modifier] ); else Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); return; diff --git a/engine/client/menu.c b/engine/client/menu.c index 238198709..a7026a1d4 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -231,6 +231,8 @@ void M_ToggleMenu_f (void) return; } if (Key_Dest_Has(kdm_console)) + Key_Dest_Remove(kdm_console); +/* { if (cls.state != ca_active) { @@ -240,7 +242,7 @@ void M_ToggleMenu_f (void) else Con_ToggleConsole_Force (); } - else + else*/ { M_Menu_Main_f (); } diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 63a113b11..2a94c4c46 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -1595,10 +1595,12 @@ void MasterInfo_Refresh(void) Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTP, MP_NQ, "gameaholic's NQ master"); Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, MP_NQ, "quakeone's server listing"); Master_AddMaster("69.59.212.88:27950"/*"ghdigital.com:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 1"); // LordHavoc - Master_AddMaster("64.22.107.125:27950"/*"dpmaster.deathmask.net:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 2"); // Willis +// Master_AddMaster("64.22.107.125:27950"/*"dpmaster.deathmask.net:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 2"); // Willis +// Master_AddMaster("107.161.23.68:27950"/*"dpmaster.deathmask.net:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 2"); // Willis (dpmaster.deathmask.net) Master_AddMaster("92.62.40.73:27950"/*"dpmaster.tchr.no:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 3"); // tChr #ifdef IPPROTO_IPV6 //Master_AddMaster("[2001:41d0:2:1628::4450]:27950", MT_MASTERUDP, MP_DP, "DarkPlaces Master 4"); // dpmaster.div0.qc.to (admin: divVerent) + //Master_AddMaster("[2604:180::4ac:98c1]:27950", MT_MASTERUDP, MP_DP, "DarkPlaces Master 4"); // dpmaster.deathmask.net (Willis) #endif Master_AddMaster("255.255.255.255:26000", MT_BCAST, MP_NQ, "Nearby Quake1 servers"); Master_AddMaster("255.255.255.255:26000", MT_BCAST, MP_DP, "Nearby DarkPlaces servers"); diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 5d65884d2..114140610 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -923,7 +923,8 @@ static void P_ParticleEffect_f(void) ptype = P_GetParticleType(config, var); //'weak' configs do not replace 'strong' configs - if (!pe_script_enabled || (part_parseweak && ptype->loaded)) + //we allow weak to replace weak as a solution to the +assoc chain thing (to add, we effectively need to 'replace'). + if (!pe_script_enabled || (part_parseweak && ptype->loaded==2)) { int depth = 1; while(1) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index b95819c2d..17d3a4cb3 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -2838,7 +2838,7 @@ void QCBUILTIN PF_getsoundtime (pubprogfuncs_t *prinst, struct globalvars_s *pr_ wedict_t *entity = G_WEDICT(prinst, OFS_PARM0); int channel = G_FLOAT(OFS_PARM1); - G_FLOAT(OFS_RETURN) = S_GetSoundTime(entity, channel); + G_FLOAT(OFS_RETURN) = S_GetSoundTime(entity->entnum, channel); } static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { diff --git a/engine/client/render.h b/engine/client/render.h index e384cbd25..a06270b7f 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -434,10 +434,10 @@ void Mod_NowLoadExternal(void); void GLR_LoadSkys (void); void R_BloomRegister(void); -int QDECL Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); -int QDECL Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); -void QDECL Mod_UnRegisterModelFormat(int idx); -void QDECL Mod_UnRegisterAllModelFormats(void *module); +int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); +int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); +void Mod_UnRegisterModelFormat(void *module, int idx); +void Mod_UnRegisterAllModelFormats(void *module); #ifdef RUNTIMELIGHTING void LightFace (int surfnum); diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 77eb6407c..b0192bd20 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -2810,7 +2810,7 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); if (TEXVALID(texture)) { - if (TEXVALID(texture) && r_fb_models.ival) + if (r_fb_models.ival) { snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadmodel->name, i); fbtexture = R_LoadReplacementTexture(skinname, "models", 0); @@ -2823,18 +2823,23 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran } else { + //try with a stripped model name snprintf(skinname, sizeof(skinname), "%s_%i.", loadname, i); texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); - if (TEXVALID(texture) && r_fb_models.ival) + if (TEXVALID(texture)) { - snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadname, i); - fbtexture = R_LoadReplacementTexture(skinname, "models", 0); - } - if (TEXVALID(texture) && r_loadbumpmapping) - { - snprintf(skinname, sizeof(skinname), "%s_%i_bump.", loadname, i); - bumptexture = R_LoadBumpmapTexture(skinname, "models"); + if (r_fb_models.ival) + { + snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadname, i); + fbtexture = R_LoadReplacementTexture(skinname, "models", 0); + } + if (r_loadbumpmapping) + { + snprintf(skinname, sizeof(skinname), "%s_%i_bump.", loadname, i); + bumptexture = R_LoadBumpmapTexture(skinname, "models"); + } } + //else ... } //but only preload it if we have no replacement. diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 8acff65fc..25d9fea77 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -164,10 +164,11 @@ typedef struct galiasinfo_s typedef struct { - int (QDECL *RegisterModelFormatText)(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); - int (QDECL *RegisterModelFormatMagic)(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); + int version; + int (QDECL *RegisterModelFormatText)(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); + int (QDECL *RegisterModelFormatMagic)(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); void (QDECL *UnRegisterModelFormat)(int idx); - void (QDECL *UnRegisterAllModelFormats)(void *module); + void (QDECL *UnRegisterAllModelFormats)(void); void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, int size); @@ -181,6 +182,7 @@ typedef struct shader_t *(QDECL *RegisterSkin) (const char *shadername, const char *modname); void (QDECL *BuildDefaultTexnums)(texnums_t *tn, shader_t *shader); } modplugfuncs_t; +#define MODPLUGFUNCS_VERSION 0 #ifdef SKELETALMODELS void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout); diff --git a/engine/common/plugin.c b/engine/common/plugin.c index b1636d185..0992bbd33 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -1649,6 +1649,7 @@ void Plug_Close(plugin_t *plug) Media_UnregisterEncoder(plug, NULL); #endif FS_UnRegisterFileSystemModule(plug); + Mod_UnRegisterAllModelFormats(plug); //tell the plugin that everything is closed and that it should free up any lingering memory/stuff //it is still allowed to create/have open files. diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index cf1c94605..07e3df3ba 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -729,7 +729,7 @@ static struct qboolean (QDECL *load) (model_t *mod, void *buffer, size_t buffersize); } modelloaders[64]; -int QDECL Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize)) +int Mod_RegisterModelFormatText(void *module, const char *formatname, char *magictext, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize)) { int i, free = -1; for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) @@ -753,7 +753,7 @@ int QDECL Mod_RegisterModelFormatText(void *module, const char *formatname, char return free+1; } -int QDECL Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize)) +int Mod_RegisterModelFormatMagic(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (model_t *mod, void *buffer, size_t fsize)) { int i, free = -1; for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) @@ -780,11 +780,13 @@ int QDECL Mod_RegisterModelFormatMagic(void *module, const char *formatname, uns return free+1; } -void QDECL Mod_UnRegisterModelFormat(int idx) +void Mod_UnRegisterModelFormat(void *module, int idx) { idx--; if ((unsigned int)(idx) >= sizeof(modelloaders)/sizeof(modelloaders[0])) return; + if (modelloaders[idx].module != module) + return; Z_Free(modelloaders[idx].ident); modelloaders[idx].ident = NULL; @@ -797,13 +799,13 @@ void QDECL Mod_UnRegisterModelFormat(int idx) //FS_Restart will be needed } -void QDECL Mod_UnRegisterAllModelFormats(void *module) +void Mod_UnRegisterAllModelFormats(void *module) { int i; for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) { if (modelloaders[i].module == module) - Mod_UnRegisterModelFormat(i+1); + Mod_UnRegisterModelFormat(module, i+1); } } @@ -1323,6 +1325,7 @@ static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps) qboolean alphaed; int j; int pixels = mt->width*mt->height/64*85; + qboolean using8bit = false; if (!Q_strncmp(mt->name,"sky",3)) { @@ -1350,7 +1353,10 @@ static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps) { tn->base = R_LoadReplacementTexture(mt->name, "bmodels", alphaed?0:IF_NOALPHA); if (base && !TEXVALID(tn->base)) + { tn->base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, (alphaed?0:IF_NOALPHA)); + using8bit = true; + } } BZ_Free(base); } @@ -1382,20 +1388,24 @@ static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps) { tn->base = R_LoadReplacementTexture(mt->name, "bmodels", ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP); if (!TEXVALID(tn->base)) + { tn->base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP, 1); + using8bit = true; + } } } if (maps & LMT_FULLBRIGHT) { snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); - if (gl_load24bit.value) + if (gl_load24bit.value) //allows fullbright replacement without diffuse { tn->fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP); if (!TEXVALID(tn->fullbright)) tn->fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); } - if ((*mt->name != '{') && !TEXVALID(tn->fullbright)) //generate one (if possible). + //only use 8bit luma if 8bit diffuse was also used. + if (using8bit && (*mt->name != '{') && !TEXVALID(tn->fullbright)) //generate one (if possible). tn->fullbright = R_LoadTextureFB(altname, mipwidth, mipheight, mipbase, IF_NOGAMMA|IF_MIPCAP); } } @@ -1408,19 +1418,19 @@ static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps) tn->bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); if (!TEXVALID(tn->bump)) { - if (gl_load24bit.value) + if (gl_load24bit.value) //allows bumpmaps replacement without diffuse { snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); tn->bump = R_LoadBumpmapTexture(altname, loadname); if (!TEXVALID(tn->bump)) tn->bump = R_LoadBumpmapTexture(altname, "bmodels"); } - else - snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); } - if (!TEXVALID(tn->bump) && loadmodel->fromgame != fg_halflife) + //only use 8bit bumps if the 8bit diffuse was used. + if (using8bit && !TEXVALID(tn->bump) && loadmodel->fromgame != fg_halflife) { + snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); //no mip levels here, would be absurd. base = (qbyte *)(mt+1); //convert to greyscale. for (j = 0; j < pixels; j++) @@ -1428,15 +1438,15 @@ static void Mod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps) tn->bump = R_LoadTexture8BumpPal(altname, tx->width, tx->height, base, true); //normalise it and then bump it. } + } - //don't do any complex quake 8bit -> glossmap. It would likly look a little ugly... - if (maps & LMT_SPEC && gl_load24bit.value) - { - snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name); - tn->specular = R_LoadHiResTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP); - if (!TEXVALID(tn->specular)) - tn->specular = R_LoadHiResTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); - } + //don't do any complex quake 8bit -> glossmap. It would likly look a little ugly... + if ((maps & LMT_SPEC) && gl_load24bit.value) //allows bumpmaps replacement without diffuse + { + snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name); + tn->specular = R_LoadHiResTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP); + if (!TEXVALID(tn->specular)) + tn->specular = R_LoadHiResTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); } } #endif diff --git a/engine/http/ftpserver.c b/engine/http/ftpserver.c index 215c6b6ac..eb6623d4b 100644 --- a/engine/http/ftpserver.c +++ b/engine/http/ftpserver.c @@ -475,7 +475,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) if (!stricmp(resource, "A")) //ascii { - QueueMessage (cl, "200 asci selected.\r\n"); + QueueMessage (cl, "200 ascii selected.\r\n"); } else if (!stricmp(resource, "I")) //binary { @@ -483,7 +483,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) } else { - QueueMessage (cl, "200 asci selected.\r\n"); + QueueMessage (cl, "200 ascii selected.\r\n"); } } else if (!stricmp(mode, "PWD")) diff --git a/engine/partcfgs/q2part.cfg b/engine/partcfgs/q2part.cfg index 5994a5b78..1e0caf930 100644 --- a/engine/partcfgs/q2part.cfg +++ b/engine/partcfgs/q2part.cfg @@ -1,3 +1,4 @@ +r_part namespace q2part r_part pe_default { diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 521c8c800..727f3af01 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -1018,6 +1018,10 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) int num; num = op - pr_opcodes; + //never any emulated opcodes + if (num >= OP_NUMREALOPS) + return false; + switch(qcc_targetformat) { case QCF_STANDARD: @@ -1037,19 +1041,12 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op) case QCF_FTEH2: case QCF_FTE: case QCF_FTEDEBUG: - //no emulated opcodes - if (num >= OP_NUMREALOPS) - return false; return true; case QCF_DARKPLACES: //all id opcodes. if (num < OP_MULSTORE_F) return true; - //no emulated opcodes - if (num >= OP_NUMREALOPS) - return false; - //extended opcodes. //DPFIXME: this is a list of the extended opcodes. I was conservative regarding supported ones. // at the time of writing, these are the ones that look like they'll work just fine in Blub\0's patch. @@ -3061,7 +3058,7 @@ QCC_def_t *QCC_PR_StatementFlags (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t return QCC_PR_StatementFlags(&pr_opcodes[OP_LT_F], var_a, var_b, NULL, flags&STFL_PRESERVEB); default: - QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target", op->name, op->opname); + QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target. Consider the use of: #pragma target fte\n", op->name, op->opname); break; } } @@ -3148,7 +3145,7 @@ QCC_statement_t *QCC_PR_SimpleStatement( int op, int var_a, int var_b, int var_c if (!force && !QCC_OPCodeValid(pr_opcodes+op)) { - QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", pr_opcodes[op].name, pr_opcodes[op].opname); + QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target. Consider the use of: #pragma target fte\n", pr_opcodes[op].name, pr_opcodes[op].opname); } statement = &statements[numstatements]; @@ -3170,7 +3167,7 @@ void QCC_PR_Statement3 ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_b, Q { // outputversion = op->extension; // if (noextensions) - QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target\n", op->name, op->opname); + QCC_PR_ParseError(ERR_BADEXTENSION, "Opcode \"%s|%s\" not valid for target. Consider the use of: #pragma target fte\n", op->name, op->opname); } statement = &statements[numstatements]; @@ -3314,7 +3311,7 @@ QCC_ref_t *QCC_PR_GenerateAddressOf(QCC_ref_t *retbuf, QCC_ref_t *operand) if (operand->type == REF_GLOBAL || operand->type == REF_ARRAY) { if (!QCC_OPCodeValid(&pr_opcodes[OP_GLOBALADDRESS])) - QCC_PR_ParseError (ERR_BADEXTENSION, "Address-of operator is not supported in this form without extensions. Please use the FTE target."); + QCC_PR_ParseError (ERR_BADEXTENSION, "Address-of operator is not supported in this form without extensions. Consider the use of: #pragma target fte"); //&foo (or &((&foo)[5]), which is basically an array). the result is a temp and thus cannot be assigned to (but should be possible to dereference further). return QCC_PR_BuildRef(retbuf, @@ -3331,7 +3328,7 @@ QCC_ref_t *QCC_PR_GenerateAddressOf(QCC_ref_t *retbuf, QCC_ref_t *operand) if (operand->index) { if (!QCC_OPCodeValid(&pr_opcodes[OP_ADD_PIW])) - QCC_PR_ParseError (ERR_BADEXTENSION, "Address-of operator is not supported in this form without extensions. Please use the FTE target."); + QCC_PR_ParseError (ERR_BADEXTENSION, "Address-of operator is not supported in this form without extensions. Consider the use of: #pragma target fte"); addr = QCC_PR_Statement(&pr_opcodes[OP_ADD_PIW], operand->base, QCC_SupplyConversion(operand->index, ev_integer, true), NULL); } else diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 9cae43667..9875da25c 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -10,10 +10,11 @@ #define STRCMP(s1,s2) (((*s1)!=(*s2)) || strcmp(s1+1,s2+1)) //saves about 2-6 out of 120 - expansion of idea from fastqcc -void QCC_PR_ConditionCompilation(void); +void QCC_PR_PreProcessor_Define(pbool append); pbool QCC_PR_UndefineName(char *name); char *QCC_PR_CheckCompConstString(char *def); CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def); +int QCC_PR_CheckCompConst(void); pbool QCC_Include(char *filename); char *compilingfile; @@ -470,7 +471,13 @@ pbool QCC_PR_Precompiler(void) if (!strncmp(directive, "define", 6)) { pr_file_p = directive; - QCC_PR_ConditionCompilation(); + QCC_PR_PreProcessor_Define(false); + QCC_PR_SkipToEndOfLine(true); + } + else if (!strncmp(directive, "append", 6)) + { + pr_file_p = directive; + QCC_PR_PreProcessor_Define(true); QCC_PR_SkipToEndOfLine(true); } else if (!strncmp(directive, "undef", 5)) @@ -726,22 +733,31 @@ pbool QCC_PR_Precompiler(void) } else if (!strncmp(directive, "includelist", 11)) { + int defines=0; pr_file_p=directive+11; - while(qcc_iswhite(*pr_file_p)) - { - if (*pr_file_p == '\n') - pr_source_line++; - pr_file_p++; - } + QCC_PR_SkipToEndOfLine(true); while(1) { QCC_PR_LexWhitespace(false); + if (QCC_PR_CheckCompConst()) + { + defines++; + continue; + } if (!QCC_PR_SimpleGetToken()) { if (!*pr_file_p) + { + if (defines>0) + { + defines--; + QCC_PR_UnInclude(); + continue; + } QCC_Error(ERR_EOF, "eof in includelist"); + } else { pr_file_p++; @@ -760,7 +776,7 @@ pbool QCC_PR_Precompiler(void) if (*pr_file_p == '\r') pr_file_p++; - QCC_PR_SkipToEndOfLine(true); +// QCC_PR_SkipToEndOfLine(true); } } else if (!strncmp(directive, "include", 7)) @@ -958,7 +974,7 @@ pbool QCC_PR_Precompiler(void) int o; extern pbool qcc_nopragmaoptimise; if (pr_scope) - QCC_PR_ParseWarning(WARN_BADPRAGMA, "pragma %s: unable to change optimisation options mid-function", qcc_token, msg); + QCC_PR_ParseWarning(WARN_BADPRAGMA, "pragma %s: unable to change optimisation options mid-function", qcc_token); else if (qcc_nopragmaoptimise) QCC_PR_ParseWarning(WARN_BADPRAGMA, "pragma %s %s: overriden by commandline", qcc_token, msg); else if (*msg >= '0' && *msg <= '3') @@ -1038,14 +1054,14 @@ pbool QCC_PR_Precompiler(void) else if (!QC_strcasecmp(qcc_token, "QTEST")) newtype = QCF_QTEST; else - QCC_PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.", qcc_token); + QCC_PR_ParseWarning(WARN_BADTARGET, "Unknown target \'%s\'. Ignored.\nValid targets are: ID, HEXEN2, FTE, FTEH2, KK7, DP(patched)", qcc_token); 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); + QCC_PR_ParseWarning(WARN_BADTARGET, "Cannot switch from hexen2 target \'%s\' after the first statement. 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_PR_ParseWarning(WARN_BADTARGET, "Cannot switch to hexen2 target \'%s\' after the first statement. Ignored.", msg); } qcc_targetformat = newtype; @@ -2004,6 +2020,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor) pr_file_p++; if (!inhibitpreprocessor) QCC_PR_NewLine (false); + else + pr_source_line++; if (!pr_file_p) return; } @@ -2023,6 +2041,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor) pr_file_p++; //don't break on eof. if (!inhibitpreprocessor) QCC_PR_NewLine(false); + else + pr_source_line++; continue; } @@ -2037,6 +2057,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor) { if (!inhibitpreprocessor) QCC_PR_NewLine(true); + else + pr_source_line++; } if (pr_file_p[1] == 0) { @@ -2367,30 +2389,24 @@ void QCC_PR_Undefine(void) // QCC_PR_ParseError("%s was not defined.", pr_token); } -void QCC_PR_ConditionCompilation(void) +void QCC_PR_PreProcessor_Define(pbool append) { - char *oldval; char *d; char *dbuf; int dbuflen; char *s; int quote=false; pbool preprocessorhack = false; - CompilerConstant_t *cnst; + CompilerConstant_t *cnst, *oldcnst; QCC_PR_SimpleGetToken (); if (!QCC_PR_SimpleGetToken ()) QCC_PR_ParseError(ERR_NONAME, "No name defined for compiler constant"); - cnst = pHash_Get(&compconstantstable, pr_token); - if (cnst) - { - oldval = cnst->value; - Hash_Remove(&compconstantstable, pr_token); - } - else - oldval = NULL; + oldcnst = pHash_Get(&compconstantstable, pr_token); + if (oldcnst) + Hash_Remove(&compconstantstable, oldcnst->name); cnst = QCC_PR_DefineName(pr_token); @@ -2432,16 +2448,58 @@ void QCC_PR_ConditionCompilation(void) } if(!*pr_file_p++) { - QCC_PR_ParseError(ERR_EXPECTED, "missing ) in macro parameter list", MAXCONSTANTPARAMS); + QCC_PR_ParseError(ERR_EXPECTED, "missing ) in macro parameter list"); break; } } } else cnst->numparams = -1; + //disable append mode if they're trying to do something stupid + if (append) + { + if (!oldcnst) + append = false; //append with no previous define is treated as just a regular define. huzzah. + else if (cnst->numparams != oldcnst->numparams || cnst->varg != oldcnst->varg) + { + QCC_PR_ParseWarning(WARN_DUPLICATEPRECOMPILER, "different number of macro arguments in macro append"); + append = false; + } + else + { + int i; + //arguments need to be specified, if only so that appends with arguments are still vaugely readable. + //argument names need to match because the expansion is too lame to cope if they're different. + for (i = 0; i < cnst->numparams; i++) + { + if (strcmp(cnst->params[i], oldcnst->params[i])) + break; + } + if (i < cnst->numparams) + { + QCC_PR_ParseWarning(WARN_DUPLICATEPRECOMPILER, "arguments differ in macro append"); + append = false; + } + else + append = true; + } + } + s = pr_file_p; d = dbuf = NULL; dbuflen = 0; + + if (append) + { + //start with the old value + int olen = strlen(oldcnst->value); + dbuflen = olen + 128; + dbuf = qccHunkAlloc(dbuflen); + memcpy(dbuf, oldcnst->value, olen); + d = dbuf + olen; + *d++ = ' '; + } + while(*s == ' ' || *s == '\t') s++; while(1) @@ -2541,10 +2599,10 @@ so if present, the preceeding \\\n and following \\\n must become an actual \n i cnst->value = dbuf; - if (oldval) + if (oldcnst && !append) { //we always warn if it was already defined //we use different warning codes so that -Wno-mundane can be used to ignore identical redefinitions. - if (strcmp(oldval, cnst->value)) + if (strcmp(oldcnst->value, cnst->value)) QCC_PR_ParseWarning(WARN_DUPLICATEPRECOMPILER, "Alternate precompiler definition of %s", pr_token); else QCC_PR_ParseWarning(WARN_IDENTICALPRECOMPILER, "Identical precompiler definition of %s", pr_token); @@ -2821,76 +2879,64 @@ int QCC_PR_CheckCompConst(void) expandedemptymacro = true; QCC_PR_IncludeChunkEx(c->value, false, NULL, c); } - - QCC_PR_Lex(); return true; } if (!strncmp(pr_file_p, "__TIME__", 8)) { - static char retbuf[128]; + char retbuf[128]; time_t long_time; time( &long_time ); strftime( retbuf, sizeof(retbuf), "\"%H:%M\"", localtime( &long_time )); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; - + QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL); return true; } if (!strncmp(pr_file_p, "__DATE__", 8)) { - static char retbuf[128]; + char retbuf[128]; time_t long_time; time( &long_time ); strftime( retbuf, sizeof(retbuf), "\"%a %d %b %Y\"", localtime( &long_time )); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; + pr_file_p += 8; + QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL); return true; } if (!strncmp(pr_file_p, "__FILE__", 8)) { - static char retbuf[256]; + char retbuf[256]; sprintf(retbuf, "\"%s\"", strings + s_file); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; + pr_file_p += 8; + QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL); return true; } if (!strncmp(pr_file_p, "__LINE__", 8)) { - static char retbuf[256]; + char retbuf[256]; sprintf(retbuf, "\"%i\"", pr_source_line); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; + pr_file_p += 8; + QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL); return true; } if (!strncmp(pr_file_p, "__FUNC__", 8)) { - static char retbuf[256]; + char retbuf[256]; sprintf(retbuf, "\"%s\"",pr_scope?pr_scope->name:""); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; + pr_file_p += 8; + QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL); return true; } if (!strncmp(pr_file_p, "__NULL__", 8)) { - static char retbuf[256]; - sprintf(retbuf, "0i"); - pr_file_p = retbuf; - QCC_PR_Lex(); //translate the macro's value - pr_file_p = oldpr_file_p+8; + pr_file_p += 8; + QCC_PR_IncludeChunkEx("0i", false, NULL, NULL); return true; } return false; @@ -3055,8 +3101,11 @@ void QCC_PR_Lex (void) QCC_PR_ParseError(ERR_CONSTANTNOTDEFINED, "Explicit precompiler usage when not defined %s", pr_token); } else + { + QCC_PR_Lex(); if (pr_token_type == tt_eof) QCC_PR_Lex(); + } return; } @@ -3066,6 +3115,9 @@ void QCC_PR_Lex (void) if (flag_hashonly || !QCC_PR_CheckCompConst()) //look for a macro. QCC_PR_LexName (); else + { + //we expanded a macro. we need to read the tokens out of it now though + QCC_PR_Lex(); if (pr_token_type == tt_eof) { if (QCC_PR_UnInclude()) @@ -3075,6 +3127,7 @@ void QCC_PR_Lex (void) } pr_token_type = tt_eof; } + } return; } diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 3145fc85d..adfe962ff 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -357,7 +357,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) csqcmsgbuffer.cursize = 0; csqcmsgbuffer.currentbit = 0; //Ask CSQC to write a buffer for it. - G_INT(OFS_PARM0) = viewerent; + G_INT(OFS_PARM0) = pr_global_struct->other = 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);