moving q2 temporary entities to particle configs.

fix 'bind alt_k' result.
don't generate a luma from 8bit if there's a custom diffuse image.
add support for #append.
#includelist now supports macro expansion.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4657 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-05-16 01:34:58 +00:00
parent e693c6956b
commit d7f83cbdc7
17 changed files with 473 additions and 198 deletions

View file

@ -595,15 +595,40 @@ qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *
} }
#include "com_mesh.h" #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) qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, const qintptr_t *arg)
{ {
#ifdef SKELETALMODELS #ifdef SKELETALMODELS
static modplugfuncs_t funcs = static modplugfuncs_t funcs =
{ {
Mod_RegisterModelFormatText, MODPLUGFUNCS_VERSION,
Mod_RegisterModelFormatMagic,
Mod_UnRegisterModelFormat, Plug_RegisterModelFormatText,
Mod_UnRegisterAllModelFormats, Plug_RegisterModelFormatMagic,
Plug_UnRegisterModelFormat,
Plug_UnRegisterAllModelFormats,
ZG_Malloc, ZG_Malloc,
R_ConcatTransforms, R_ConcatTransforms,
@ -616,7 +641,7 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons
R_RegisterSkin, R_RegisterSkin,
R_BuildDefaultTexnums R_BuildDefaultTexnums
}; };
if (VM_LONG(arg[0]) == sizeof(funcs)) if (VM_LONG(arg[0]) >= sizeof(funcs))
return (qintptr_t)&funcs; return (qintptr_t)&funcs;
else else
#endif #endif

View file

@ -23,65 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "particles.h" #include "particles.h"
entity_state_t *CL_FindPacketEntity(int num); 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 #ifdef Q2CLIENT
typedef enum typedef enum
{ {
@ -156,8 +97,9 @@ typedef enum
CRTE_STAIN, CRTE_STAIN,
CRTE_FIRE, CRTE_FIRE,
CRTE_CABLEGUT, CRTE_CABLEGUT,
CRTE_SMOKE CRTE_SMOKE,
//CODERED //CODERED
Q2TE_MAX
} temp_event_t; } temp_event_t;
#define Q2SPLASH_UNKNOWN 0 #define Q2SPLASH_UNKNOWN 0
@ -167,8 +109,150 @@ typedef enum
#define Q2SPLASH_SLIME 4 #define Q2SPLASH_SLIME 4
#define Q2SPLASH_LAVA 5 #define Q2SPLASH_LAVA 5
#define Q2SPLASH_BLOOD 6 #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 #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 typedef struct
{ {
int entity; int entity;
@ -463,6 +547,9 @@ void CL_RegisterParticles(void)
if (cls.protocol == CP_QUAKE2) 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"); ptq2_blood = P_FindParticleType("q2part.TEQ2_BLOOD");
rtq2_railtrail = P_FindParticleType("q2part.TR_RAILTRAIL"); rtq2_railtrail = P_FindParticleType("q2part.TR_RAILTRAIL");
rtq2_blastertrail = P_FindParticleType("q2part.TR_BLASTERTRAIL"); rtq2_blastertrail = P_FindParticleType("q2part.TR_BLASTERTRAIL");
@ -474,6 +561,8 @@ void CL_RegisterParticles(void)
} }
else else
{ {
for (i = 0; i < sizeof(pt_q2)/sizeof(pt_q2[0]); i++)
pt_q2[i] = P_INVALID;
ptq2_blood = P_INVALID; ptq2_blood = P_INVALID;
rtq2_railtrail = P_INVALID; rtq2_railtrail = P_INVALID;
rtq2_blastertrail = 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"); btype = P_FindParticleType("te_grapple_cable");
etype = P_FindParticleType("te_grapple_cable_end"); etype = P_FindParticleType("te_grapple_cable_end");
break; break;
case 6:
mname = "models/proj/beam/tris.md2";
btype = P_FindParticleType("te_heatbeam");
etype = P_FindParticleType("te_heatbeam_end");
break;
#endif #endif
} }
@ -2322,6 +2416,7 @@ void Q2S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx, float
void CLQ2_ParseTEnt (void) void CLQ2_ParseTEnt (void)
{ {
int type; int type;
int pt;
vec3_t pos, pos2, dir; vec3_t pos, pos2, dir;
explosion_t *ex; explosion_t *ex;
int cnt; int cnt;
@ -2332,36 +2427,113 @@ void CLQ2_ParseTEnt (void)
type = MSG_ReadByte (); 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) 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_ReadPos (pos);
MSG_ReadDir (dir); MSG_ReadDir (dir);
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_gunshot"); P_RunParticleEffectType(pos, dir, 1, pt);
break; break;
case Q2TE_BLOOD: case Q2TE_RAILTRAIL: //blue spiral, grey particles
MSG_ReadPos (pos); case Q2TE_BUBBLETRAIL: //grey sparse trail, slow riser
MSG_ReadDir (dir); case Q2TE_BFG_LASER: //green lazor
P_RunParticleEffectTypeString(pos, dir, 1, "q2part.teq2_blood"); case Q2TE_DEBUGTRAIL: //long lived blue trail
break; case Q2TE_BUBBLETRAIL2: //grey rising trail
case Q2TE_SHOTGUN: case Q2TE_BLUEHYPERBLASTER: //TE_BLASTER without model+light
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
MSG_ReadPos (pos); MSG_ReadPos (pos);
MSG_ReadPos (pos2); MSG_ReadPos (pos2);
if (P_ParticleTrail(pos, pos2, rtq2_railtrail, 0, NULL)) P_ParticleTrail(pos, pos2, pt, 0, NULL);
P_ParticleTrailIndex(pos, pos2, 0x74, 8, NULL);
Q2S_StartSound (pos, 0, 0, S_PrecacheSound ("weapons/railgf1a.wav"), 1, ATTN_NORM, 0);
break; 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: default:
goto fixme; goto fixme;
// Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type); // Host_EndGame ("CLQ2_ParseTEnt: bad/non-implemented type %i", type);
@ -2579,6 +2751,7 @@ fixme:
ex->firstframe = 30; ex->firstframe = 30;
ex->flags |= RF_TRANSLUCENT; ex->flags |= RF_TRANSLUCENT;
ex->numframes = 19; ex->numframes = 19;
ex->skinnum = -1;
} }
break; break;
/* /*
@ -2675,6 +2848,7 @@ fixme:
else else
ex->firstframe = 0; ex->firstframe = 0;
ex->numframes = 15; ex->numframes = 15;
ex->skinnum = -1;
} }
break; break;
/* /*

View file

@ -1640,8 +1640,10 @@ void Key_Bind_f (void)
if (c == 2) if (c == 2)
{ {
if (keybindings[b][0]) if (modifier == ~0) //modifier unspecified. default to no modifier
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b][0] ); modifier = 0;
if (keybindings[b][modifier])
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv(1), keybindings[b][modifier] );
else else
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) ); Con_Printf ("\"%s\" is not bound\n", Cmd_Argv(1) );
return; return;

View file

@ -231,6 +231,8 @@ void M_ToggleMenu_f (void)
return; return;
} }
if (Key_Dest_Has(kdm_console)) if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
/*
{ {
if (cls.state != ca_active) if (cls.state != ca_active)
{ {
@ -240,7 +242,7 @@ void M_ToggleMenu_f (void)
else else
Con_ToggleConsole_Force (); Con_ToggleConsole_Force ();
} }
else else*/
{ {
M_Menu_Main_f (); M_Menu_Main_f ();
} }

View file

@ -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://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_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("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 Master_AddMaster("92.62.40.73:27950"/*"dpmaster.tchr.no:27950"*/, MT_MASTERUDP, MP_DP, "DarkPlaces Master 3"); // tChr
#ifdef IPPROTO_IPV6 #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("[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 #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_NQ, "Nearby Quake1 servers");
Master_AddMaster("255.255.255.255:26000", MT_BCAST, MP_DP, "Nearby DarkPlaces servers"); Master_AddMaster("255.255.255.255:26000", MT_BCAST, MP_DP, "Nearby DarkPlaces servers");

View file

@ -923,7 +923,8 @@ static void P_ParticleEffect_f(void)
ptype = P_GetParticleType(config, var); ptype = P_GetParticleType(config, var);
//'weak' configs do not replace 'strong' configs //'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; int depth = 1;
while(1) while(1)

View file

@ -2838,7 +2838,7 @@ void QCBUILTIN PF_getsoundtime (pubprogfuncs_t *prinst, struct globalvars_s *pr_
wedict_t *entity = G_WEDICT(prinst, OFS_PARM0); wedict_t *entity = G_WEDICT(prinst, OFS_PARM0);
int channel = G_FLOAT(OFS_PARM1); 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) static void QCBUILTIN PF_cs_sound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {

View file

@ -434,10 +434,10 @@ void Mod_NowLoadExternal(void);
void GLR_LoadSkys (void); void GLR_LoadSkys (void);
void R_BloomRegister(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 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)); int 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 Mod_UnRegisterModelFormat(void *module, int idx);
void QDECL Mod_UnRegisterAllModelFormats(void *module); void Mod_UnRegisterAllModelFormats(void *module);
#ifdef RUNTIMELIGHTING #ifdef RUNTIMELIGHTING
void LightFace (int surfnum); void LightFace (int surfnum);

View file

@ -2810,7 +2810,7 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA);
if (TEXVALID(texture)) 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); snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadmodel->name, i);
fbtexture = R_LoadReplacementTexture(skinname, "models", 0); fbtexture = R_LoadReplacementTexture(skinname, "models", 0);
@ -2823,18 +2823,23 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintran
} }
else else
{ {
//try with a stripped model name
snprintf(skinname, sizeof(skinname), "%s_%i.", loadname, i); snprintf(skinname, sizeof(skinname), "%s_%i.", loadname, i);
texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); 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); if (r_fb_models.ival)
fbtexture = R_LoadReplacementTexture(skinname, "models", 0); {
} snprintf(skinname, sizeof(skinname), "%s_%i_luma.", loadname, i);
if (TEXVALID(texture) && r_loadbumpmapping) fbtexture = R_LoadReplacementTexture(skinname, "models", 0);
{ }
snprintf(skinname, sizeof(skinname), "%s_%i_bump.", loadname, i); if (r_loadbumpmapping)
bumptexture = R_LoadBumpmapTexture(skinname, "models"); {
snprintf(skinname, sizeof(skinname), "%s_%i_bump.", loadname, i);
bumptexture = R_LoadBumpmapTexture(skinname, "models");
}
} }
//else ...
} }
//but only preload it if we have no replacement. //but only preload it if we have no replacement.

View file

@ -164,10 +164,11 @@ typedef struct galiasinfo_s
typedef struct 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 version;
int (QDECL *RegisterModelFormatMagic)(void *module, const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize)); 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 *UnRegisterModelFormat)(int idx);
void (QDECL *UnRegisterAllModelFormats)(void *module); void (QDECL *UnRegisterAllModelFormats)(void);
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, int size); 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); shader_t *(QDECL *RegisterSkin) (const char *shadername, const char *modname);
void (QDECL *BuildDefaultTexnums)(texnums_t *tn, shader_t *shader); void (QDECL *BuildDefaultTexnums)(texnums_t *tn, shader_t *shader);
} modplugfuncs_t; } modplugfuncs_t;
#define MODPLUGFUNCS_VERSION 0
#ifdef SKELETALMODELS #ifdef SKELETALMODELS
void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout); void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weights, int numweights, vecV_t *xyzout, vec3_t *normout);

View file

@ -1649,6 +1649,7 @@ void Plug_Close(plugin_t *plug)
Media_UnregisterEncoder(plug, NULL); Media_UnregisterEncoder(plug, NULL);
#endif #endif
FS_UnRegisterFileSystemModule(plug); FS_UnRegisterFileSystemModule(plug);
Mod_UnRegisterAllModelFormats(plug);
//tell the plugin that everything is closed and that it should free up any lingering memory/stuff //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. //it is still allowed to create/have open files.

View file

@ -729,7 +729,7 @@ static struct
qboolean (QDECL *load) (model_t *mod, void *buffer, size_t buffersize); qboolean (QDECL *load) (model_t *mod, void *buffer, size_t buffersize);
} modelloaders[64]; } 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; int i, free = -1;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) 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; 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; int i, free = -1;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) 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; return free+1;
} }
void QDECL Mod_UnRegisterModelFormat(int idx) void Mod_UnRegisterModelFormat(void *module, int idx)
{ {
idx--; idx--;
if ((unsigned int)(idx) >= sizeof(modelloaders)/sizeof(modelloaders[0])) if ((unsigned int)(idx) >= sizeof(modelloaders)/sizeof(modelloaders[0]))
return; return;
if (modelloaders[idx].module != module)
return;
Z_Free(modelloaders[idx].ident); Z_Free(modelloaders[idx].ident);
modelloaders[idx].ident = NULL; modelloaders[idx].ident = NULL;
@ -797,13 +799,13 @@ void QDECL Mod_UnRegisterModelFormat(int idx)
//FS_Restart will be needed //FS_Restart will be needed
} }
void QDECL Mod_UnRegisterAllModelFormats(void *module) void Mod_UnRegisterAllModelFormats(void *module)
{ {
int i; int i;
for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++) for (i = 0; i < sizeof(modelloaders)/sizeof(modelloaders[0]); i++)
{ {
if (modelloaders[i].module == module) 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; qboolean alphaed;
int j; int j;
int pixels = mt->width*mt->height/64*85; int pixels = mt->width*mt->height/64*85;
qboolean using8bit = false;
if (!Q_strncmp(mt->name,"sky",3)) 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); tn->base = R_LoadReplacementTexture(mt->name, "bmodels", alphaed?0:IF_NOALPHA);
if (base && !TEXVALID(tn->base)) if (base && !TEXVALID(tn->base))
{
tn->base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, (alphaed?0:IF_NOALPHA)); tn->base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, (alphaed?0:IF_NOALPHA));
using8bit = true;
}
} }
BZ_Free(base); 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); tn->base = R_LoadReplacementTexture(mt->name, "bmodels", ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP);
if (!TEXVALID(tn->base)) if (!TEXVALID(tn->base))
{
tn->base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP, 1); tn->base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP, 1);
using8bit = true;
}
} }
} }
if (maps & LMT_FULLBRIGHT) if (maps & LMT_FULLBRIGHT)
{ {
snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); 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); tn->fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
if (!TEXVALID(tn->fullbright)) if (!TEXVALID(tn->fullbright))
tn->fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); 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); 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); tn->bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
if (!TEXVALID(tn->bump)) 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); snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name);
tn->bump = R_LoadBumpmapTexture(altname, loadname); tn->bump = R_LoadBumpmapTexture(altname, loadname);
if (!TEXVALID(tn->bump)) if (!TEXVALID(tn->bump))
tn->bump = R_LoadBumpmapTexture(altname, "bmodels"); 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. //no mip levels here, would be absurd.
base = (qbyte *)(mt+1); //convert to greyscale. base = (qbyte *)(mt+1); //convert to greyscale.
for (j = 0; j < pixels; j++) 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. 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... //don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
if (maps & LMT_SPEC && gl_load24bit.value) if ((maps & LMT_SPEC) && gl_load24bit.value) //allows bumpmaps replacement without diffuse
{ {
snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name); snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name);
tn->specular = R_LoadHiResTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP); tn->specular = R_LoadHiResTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
if (!TEXVALID(tn->specular)) if (!TEXVALID(tn->specular))
tn->specular = R_LoadHiResTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP); tn->specular = R_LoadHiResTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
}
} }
} }
#endif #endif

View file

@ -475,7 +475,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (!stricmp(resource, "A")) //ascii 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 else if (!stricmp(resource, "I")) //binary
{ {
@ -483,7 +483,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
} }
else else
{ {
QueueMessage (cl, "200 asci selected.\r\n"); QueueMessage (cl, "200 ascii selected.\r\n");
} }
} }
else if (!stricmp(mode, "PWD")) else if (!stricmp(mode, "PWD"))

View file

@ -1,3 +1,4 @@
r_part namespace q2part
r_part pe_default r_part pe_default
{ {

View file

@ -1018,6 +1018,10 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
int num; int num;
num = op - pr_opcodes; num = op - pr_opcodes;
//never any emulated opcodes
if (num >= OP_NUMREALOPS)
return false;
switch(qcc_targetformat) switch(qcc_targetformat)
{ {
case QCF_STANDARD: case QCF_STANDARD:
@ -1037,19 +1041,12 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
case QCF_FTEH2: case QCF_FTEH2:
case QCF_FTE: case QCF_FTE:
case QCF_FTEDEBUG: case QCF_FTEDEBUG:
//no emulated opcodes
if (num >= OP_NUMREALOPS)
return false;
return true; return true;
case QCF_DARKPLACES: case QCF_DARKPLACES:
//all id opcodes. //all id opcodes.
if (num < OP_MULSTORE_F) if (num < OP_MULSTORE_F)
return true; return true;
//no emulated opcodes
if (num >= OP_NUMREALOPS)
return false;
//extended opcodes. //extended opcodes.
//DPFIXME: this is a list of the extended opcodes. I was conservative regarding supported ones. //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. // 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); return QCC_PR_StatementFlags(&pr_opcodes[OP_LT_F], var_a, var_b, NULL, flags&STFL_PRESERVEB);
default: 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; 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)) 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]; 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; // outputversion = op->extension;
// if (noextensions) // 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]; 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 (operand->type == REF_GLOBAL || operand->type == REF_ARRAY)
{ {
if (!QCC_OPCodeValid(&pr_opcodes[OP_GLOBALADDRESS])) 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). //&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, 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 (operand->index)
{ {
if (!QCC_OPCodeValid(&pr_opcodes[OP_ADD_PIW])) 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); addr = QCC_PR_Statement(&pr_opcodes[OP_ADD_PIW], operand->base, QCC_SupplyConversion(operand->index, ev_integer, true), NULL);
} }
else else

View file

@ -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 #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); pbool QCC_PR_UndefineName(char *name);
char *QCC_PR_CheckCompConstString(char *def); char *QCC_PR_CheckCompConstString(char *def);
CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def); CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def);
int QCC_PR_CheckCompConst(void);
pbool QCC_Include(char *filename); pbool QCC_Include(char *filename);
char *compilingfile; char *compilingfile;
@ -470,7 +471,13 @@ pbool QCC_PR_Precompiler(void)
if (!strncmp(directive, "define", 6)) if (!strncmp(directive, "define", 6))
{ {
pr_file_p = directive; 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); QCC_PR_SkipToEndOfLine(true);
} }
else if (!strncmp(directive, "undef", 5)) else if (!strncmp(directive, "undef", 5))
@ -726,22 +733,31 @@ pbool QCC_PR_Precompiler(void)
} }
else if (!strncmp(directive, "includelist", 11)) else if (!strncmp(directive, "includelist", 11))
{ {
int defines=0;
pr_file_p=directive+11; pr_file_p=directive+11;
while(qcc_iswhite(*pr_file_p)) QCC_PR_SkipToEndOfLine(true);
{
if (*pr_file_p == '\n')
pr_source_line++;
pr_file_p++;
}
while(1) while(1)
{ {
QCC_PR_LexWhitespace(false); QCC_PR_LexWhitespace(false);
if (QCC_PR_CheckCompConst())
{
defines++;
continue;
}
if (!QCC_PR_SimpleGetToken()) if (!QCC_PR_SimpleGetToken())
{ {
if (!*pr_file_p) if (!*pr_file_p)
{
if (defines>0)
{
defines--;
QCC_PR_UnInclude();
continue;
}
QCC_Error(ERR_EOF, "eof in includelist"); QCC_Error(ERR_EOF, "eof in includelist");
}
else else
{ {
pr_file_p++; pr_file_p++;
@ -760,7 +776,7 @@ pbool QCC_PR_Precompiler(void)
if (*pr_file_p == '\r') if (*pr_file_p == '\r')
pr_file_p++; pr_file_p++;
QCC_PR_SkipToEndOfLine(true); // QCC_PR_SkipToEndOfLine(true);
} }
} }
else if (!strncmp(directive, "include", 7)) else if (!strncmp(directive, "include", 7))
@ -958,7 +974,7 @@ pbool QCC_PR_Precompiler(void)
int o; int o;
extern pbool qcc_nopragmaoptimise; extern pbool qcc_nopragmaoptimise;
if (pr_scope) 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) else if (qcc_nopragmaoptimise)
QCC_PR_ParseWarning(WARN_BADPRAGMA, "pragma %s %s: overriden by commandline", qcc_token, msg); QCC_PR_ParseWarning(WARN_BADPRAGMA, "pragma %s %s: overriden by commandline", qcc_token, msg);
else if (*msg >= '0' && *msg <= '3') else if (*msg >= '0' && *msg <= '3')
@ -1038,14 +1054,14 @@ pbool QCC_PR_Precompiler(void)
else if (!QC_strcasecmp(qcc_token, "QTEST")) else if (!QC_strcasecmp(qcc_token, "QTEST"))
newtype = QCF_QTEST; newtype = QCF_QTEST;
else 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 (numstatements > 1)
{ {
if ((qcc_targetformat == QCF_HEXEN2 || qcc_targetformat == QCF_FTEH2) && (newtype != QCF_HEXEN2 && newtype != QCF_FTEH2)) 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)) 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; qcc_targetformat = newtype;
@ -2004,6 +2020,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
pr_file_p++; pr_file_p++;
if (!inhibitpreprocessor) if (!inhibitpreprocessor)
QCC_PR_NewLine (false); QCC_PR_NewLine (false);
else
pr_source_line++;
if (!pr_file_p) if (!pr_file_p)
return; return;
} }
@ -2023,6 +2041,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
pr_file_p++; //don't break on eof. pr_file_p++; //don't break on eof.
if (!inhibitpreprocessor) if (!inhibitpreprocessor)
QCC_PR_NewLine(false); QCC_PR_NewLine(false);
else
pr_source_line++;
continue; continue;
} }
@ -2037,6 +2057,8 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor)
{ {
if (!inhibitpreprocessor) if (!inhibitpreprocessor)
QCC_PR_NewLine(true); QCC_PR_NewLine(true);
else
pr_source_line++;
} }
if (pr_file_p[1] == 0) if (pr_file_p[1] == 0)
{ {
@ -2367,30 +2389,24 @@ void QCC_PR_Undefine(void)
// QCC_PR_ParseError("%s was not defined.", pr_token); // 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 *d;
char *dbuf; char *dbuf;
int dbuflen; int dbuflen;
char *s; char *s;
int quote=false; int quote=false;
pbool preprocessorhack = false; pbool preprocessorhack = false;
CompilerConstant_t *cnst; CompilerConstant_t *cnst, *oldcnst;
QCC_PR_SimpleGetToken (); QCC_PR_SimpleGetToken ();
if (!QCC_PR_SimpleGetToken ()) if (!QCC_PR_SimpleGetToken ())
QCC_PR_ParseError(ERR_NONAME, "No name defined for compiler constant"); QCC_PR_ParseError(ERR_NONAME, "No name defined for compiler constant");
cnst = pHash_Get(&compconstantstable, pr_token); oldcnst = pHash_Get(&compconstantstable, pr_token);
if (cnst) if (oldcnst)
{ Hash_Remove(&compconstantstable, oldcnst->name);
oldval = cnst->value;
Hash_Remove(&compconstantstable, pr_token);
}
else
oldval = NULL;
cnst = QCC_PR_DefineName(pr_token); cnst = QCC_PR_DefineName(pr_token);
@ -2432,16 +2448,58 @@ void QCC_PR_ConditionCompilation(void)
} }
if(!*pr_file_p++) 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; break;
} }
} }
} }
else cnst->numparams = -1; 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; s = pr_file_p;
d = dbuf = NULL; d = dbuf = NULL;
dbuflen = 0; 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') while(*s == ' ' || *s == '\t')
s++; s++;
while(1) while(1)
@ -2541,10 +2599,10 @@ so if present, the preceeding \\\n and following \\\n must become an actual \n i
cnst->value = dbuf; cnst->value = dbuf;
if (oldval) if (oldcnst && !append)
{ //we always warn if it was already defined { //we always warn if it was already defined
//we use different warning codes so that -Wno-mundane can be used to ignore identical redefinitions. //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); QCC_PR_ParseWarning(WARN_DUPLICATEPRECOMPILER, "Alternate precompiler definition of %s", pr_token);
else else
QCC_PR_ParseWarning(WARN_IDENTICALPRECOMPILER, "Identical precompiler definition of %s", pr_token); QCC_PR_ParseWarning(WARN_IDENTICALPRECOMPILER, "Identical precompiler definition of %s", pr_token);
@ -2821,76 +2879,64 @@ int QCC_PR_CheckCompConst(void)
expandedemptymacro = true; expandedemptymacro = true;
QCC_PR_IncludeChunkEx(c->value, false, NULL, c); QCC_PR_IncludeChunkEx(c->value, false, NULL, c);
} }
QCC_PR_Lex();
return true; return true;
} }
if (!strncmp(pr_file_p, "__TIME__", 8)) if (!strncmp(pr_file_p, "__TIME__", 8))
{ {
static char retbuf[128]; char retbuf[128];
time_t long_time; time_t long_time;
time( &long_time ); time( &long_time );
strftime( retbuf, sizeof(retbuf), strftime( retbuf, sizeof(retbuf),
"\"%H:%M\"", localtime( &long_time )); "\"%H:%M\"", localtime( &long_time ));
pr_file_p = retbuf; QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
QCC_PR_Lex(); //translate the macro's value
pr_file_p = oldpr_file_p+8;
return true; return true;
} }
if (!strncmp(pr_file_p, "__DATE__", 8)) if (!strncmp(pr_file_p, "__DATE__", 8))
{ {
static char retbuf[128]; char retbuf[128];
time_t long_time; time_t long_time;
time( &long_time ); time( &long_time );
strftime( retbuf, sizeof(retbuf), strftime( retbuf, sizeof(retbuf),
"\"%a %d %b %Y\"", localtime( &long_time )); "\"%a %d %b %Y\"", localtime( &long_time ));
pr_file_p = retbuf; pr_file_p += 8;
QCC_PR_Lex(); //translate the macro's value QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
pr_file_p = oldpr_file_p+8;
return true; return true;
} }
if (!strncmp(pr_file_p, "__FILE__", 8)) if (!strncmp(pr_file_p, "__FILE__", 8))
{ {
static char retbuf[256]; char retbuf[256];
sprintf(retbuf, "\"%s\"", strings + s_file); 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; return true;
} }
if (!strncmp(pr_file_p, "__LINE__", 8)) if (!strncmp(pr_file_p, "__LINE__", 8))
{ {
static char retbuf[256]; char retbuf[256];
sprintf(retbuf, "\"%i\"", pr_source_line); sprintf(retbuf, "\"%i\"", pr_source_line);
pr_file_p = retbuf; pr_file_p += 8;
QCC_PR_Lex(); //translate the macro's value QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
pr_file_p = oldpr_file_p+8;
return true; return true;
} }
if (!strncmp(pr_file_p, "__FUNC__", 8)) if (!strncmp(pr_file_p, "__FUNC__", 8))
{ {
static char retbuf[256]; char retbuf[256];
sprintf(retbuf, "\"%s\"",pr_scope?pr_scope->name:"<NO FUNCTION>"); sprintf(retbuf, "\"%s\"",pr_scope?pr_scope->name:"<NO FUNCTION>");
pr_file_p = retbuf; pr_file_p += 8;
QCC_PR_Lex(); //translate the macro's value QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
pr_file_p = oldpr_file_p+8;
return true; return true;
} }
if (!strncmp(pr_file_p, "__NULL__", 8)) if (!strncmp(pr_file_p, "__NULL__", 8))
{ {
static char retbuf[256]; pr_file_p += 8;
sprintf(retbuf, "0i"); QCC_PR_IncludeChunkEx("0i", false, NULL, NULL);
pr_file_p = retbuf;
QCC_PR_Lex(); //translate the macro's value
pr_file_p = oldpr_file_p+8;
return true; return true;
} }
return false; 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); QCC_PR_ParseError(ERR_CONSTANTNOTDEFINED, "Explicit precompiler usage when not defined %s", pr_token);
} }
else else
{
QCC_PR_Lex();
if (pr_token_type == tt_eof) if (pr_token_type == tt_eof)
QCC_PR_Lex(); QCC_PR_Lex();
}
return; return;
} }
@ -3066,6 +3115,9 @@ void QCC_PR_Lex (void)
if (flag_hashonly || !QCC_PR_CheckCompConst()) //look for a macro. if (flag_hashonly || !QCC_PR_CheckCompConst()) //look for a macro.
QCC_PR_LexName (); QCC_PR_LexName ();
else 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 (pr_token_type == tt_eof)
{ {
if (QCC_PR_UnInclude()) if (QCC_PR_UnInclude())
@ -3075,6 +3127,7 @@ void QCC_PR_Lex (void)
} }
pr_token_type = tt_eof; pr_token_type = tt_eof;
} }
}
return; return;
} }

View file

@ -357,7 +357,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
csqcmsgbuffer.cursize = 0; csqcmsgbuffer.cursize = 0;
csqcmsgbuffer.currentbit = 0; csqcmsgbuffer.currentbit = 0;
//Ask CSQC to write a buffer for it. //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) G_FLOAT(OFS_PARM1) = 0xffffff; //psudo compatibility with SendFlags (fte doesn't support properly)
#endif #endif
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);