tcpconnect fixes

lots of hexen2 fixes
fixed clipped decals again, still not using any...
fixed zips over 2g
rewrote bloom to use glsl. should be slightly more usable now.
lots more hexen2 fixes

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3957 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-01-17 07:57:46 +00:00
parent 5651e77c30
commit fb214142a3
91 changed files with 4584 additions and 1270 deletions

View file

@ -945,7 +945,7 @@ void CLNQ_ParseEntity(unsigned int bits)
{
int i;
int num, pnum;
entity_state_t *state, *from;
entity_state_t *state;//, *from;
entity_state_t *base;
static float lasttime;
packet_entities_t *pack;
@ -995,7 +995,7 @@ void CLNQ_ParseEntity(unsigned int bits)
state = &pack->entities[pack->num_entities++];
}
from = CL_FindOldPacketEntity(num); //this could be optimised.
// from = CL_FindOldPacketEntity(num); //this could be optimised.
if (!CL_CheckBaselines(num))
Host_EndGame("CLNQ_ParseEntity: check baselines failed with size %i", num);
@ -1132,14 +1132,6 @@ void CLNQ_ParseEntity(unsigned int bits)
if (bits & DPU_MODEL2)
state->modelindex |= MSG_ReadByte() << 8;
}
if (cls.demoplayback != DPB_NONE)
for (pnum = 0; pnum < cl.splitclients; pnum++)
if (num == cl.viewentity[pnum])
{
state->angles[0] = cl.viewangles[pnum][0]/-3;
state->angles[1] = cl.viewangles[pnum][1];
state->angles[2] = cl.viewangles[pnum][2];
}
}
#endif
#ifdef PEXT_SETVIEW

View file

@ -795,11 +795,15 @@ void CL_CheckForResend (void)
CLQ3_SendAuthPacket(adr);
#endif
if (connect_tries == 0)
NET_EnsureRoute(cls.sockets, "conn", cls.servername, false);
Con_TPrintf (TLC_CONNECTINGTO, cls.servername);
if (connect_tries == 0)
if (!NET_EnsureRoute(cls.sockets, "conn", cls.servername, false))
{
Con_Printf ("Unable to establish connection to %s\n", cls.servername);
return;
}
contype |= 1; /*always try qw type connections*/
// if ((connect_tries&3)==3) || (connect_defaultport==26000))
contype |= 2; /*try nq connections periodically (or if its the default nq port)*/
@ -2286,7 +2290,7 @@ void CL_ConnectionlessPacket (void)
}
}
if (cls.demoplayback == DPB_NONE)
if (cls.demoplayback == DPB_NONE && net_from.type != NA_LOOPBACK)
Con_TPrintf (TL_ST_COLON, NET_AdrToString (adr, sizeof(adr), net_from));
// Con_DPrintf ("%s", net_message.data + 4);
@ -2521,7 +2525,8 @@ void CL_ConnectionlessPacket (void)
#ifdef Q2CLIENT
client_connect: //fixme: make function
#endif
Con_TPrintf (TLC_GOTCONNECTION);
if (net_from.type != NA_LOOPBACK)
Con_TPrintf (TLC_GOTCONNECTION);
if (cls.state >= ca_connected)
{
if (cls.demoplayback == DPB_NONE)
@ -2537,7 +2542,8 @@ client_connect: //fixme: make function
#endif
CL_SendClientCommand(true, "new");
cls.state = ca_connected;
Con_TPrintf (TLC_CONNECTED);
if (cls.netchan.remote_address.type != NA_LOOPBACK)
Con_TPrintf (TLC_CONNECTED);
allowremotecmd = false; // localid required now for remote cmds
total_loading_size = 100;

View file

@ -5320,17 +5320,17 @@ void CLQW_ParseServerMessage (void)
cl.completed_time = cl.gametime;
vid.recalc_refdef = true; // go to full screen
for (i=0 ; i<3 ; i++)
cl.simorg[0][i] = MSG_ReadCoord ();
cl.simorg[destsplit][i] = MSG_ReadCoord ();
for (i=0 ; i<3 ; i++)
cl.simangles[0][i] = MSG_ReadAngle ();
VectorClear (cl.simvel[0]);
VectorCopy (cl.simvel[0], cl.simvel[1]);
VectorCopy (cl.simangles[0], cl.simangles[1]);
VectorCopy (cl.simorg[0], cl.simorg[1]);
cl.simangles[destsplit][i] = MSG_ReadAngle ();
VectorClear (cl.simvel[destsplit]);
break;
case svc_finale:
if (!cl.intermission)
for (i = 0; i < MAX_SPLITS; i++)
cl.simorg[i][2] += cl.viewheight[i];
cl.intermission = 2;
cl.completed_time = cl.gametime;
vid.recalc_refdef = true; // go to full screen

View file

@ -1002,8 +1002,19 @@ out:
void CL_PredictMove (void)
{
int i;
//work out which packet entities are solid
CL_SetSolidEntities ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(false);
// do client side motion prediction
for (i = 0; i < cl.splitclients; i++)
CL_PredictMovePNum(i);
// Set up prediction for other players
CL_SetUpPlayerPrediction(true);
}

View file

@ -254,6 +254,7 @@ typedef struct {
unsigned int flags;
conchar_t string[1024];
char titleimage[MAX_QPATH];
unsigned int charcount;
float time_start; // for slow victory printing
float time_off;
@ -332,8 +333,12 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
p = &scr_centerprint[pnum];
p->flags = 0;
p->titleimage[0] = 0;
if (cl.intermission)
p->flags |= CPRINT_TYPEWRITER | CPRINT_PERSIST;
{
p->flags |= CPRINT_TYPEWRITER | CPRINT_PERSIST | CPRINT_TALIGN;
Q_strncpyz(p->titleimage, "gfx/finale.lmp", sizeof(p->titleimage));
}
while (*str == '/')
{
@ -344,17 +349,31 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
break;
}
else if (str[1] == 'P')
{
p->flags |= CPRINT_PERSIST | CPRINT_BACKGROUND;
p->flags &= ~CPRINT_TALIGN;
}
else if (str[1] == 'O')
p->flags = CPRINT_OBITUARTY;
p->flags ^= CPRINT_OBITUARTY;
else if (str[1] == 'B')
p->flags |= CPRINT_BALIGN; //Note: you probably want to add some blank lines...
p->flags ^= CPRINT_BALIGN; //Note: you probably want to add some blank lines...
else if (str[1] == 'T')
p->flags |= CPRINT_TALIGN;
p->flags ^= CPRINT_TALIGN;
else if (str[1] == 'L')
p->flags |= CPRINT_LALIGN;
p->flags ^= CPRINT_LALIGN;
else if (str[1] == 'R')
p->flags |= CPRINT_RALIGN;
p->flags ^= CPRINT_RALIGN;
else if (str[1] == 'I')
{
char *e = strchr(str+=2, ':');
int l = e - str;
if (l >= sizeof(p->titleimage))
l = sizeof(p->titleimage)-1;
strncpy(p->titleimage, str, l);
p->titleimage[l] = 0;
str = e+1;
continue;
}
else
break;
str += 2;
@ -403,6 +422,7 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
int top;
int bottom;
int remaining;
shader_t *pic;
conchar_t *line_start[MAX_CPRINT_LINES];
conchar_t *line_end[MAX_CPRINT_LINES];
@ -417,20 +437,51 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
p->erase_center = 0;
if (*p->titleimage)
pic = R2D_SafeCachePic (p->titleimage);
else
pic = NULL;
if (p->flags & CPRINT_BACKGROUND)
{ //hexen2 style plaque.
if (rect->width > 320)
if (rect->width > (pic?pic->width:320))
{
rect->x = (rect->x + rect->width/2) - (160);
rect->width = 320;
rect->x = (rect->x + rect->width/2) - ((pic?pic->width:320) / 2);
rect->width = pic?pic->width:320;
}
if (rect->width < 32)
return;
rect->x += 16;
rect->width -= 32;
/*keep the text inside the image too*/
if (pic)
{
if (rect->height > (pic->height))
{
rect->y = (rect->y + rect->height/2) - (pic->height/2);
rect->height = pic->height;
}
rect->y += 16;
rect->height -= 32;
}
}
Font_BeginString(font_conchar, rect->x, rect->y, &left, &top);
y = rect->y;
if (pic)
{
if (!(p->flags & CPRINT_BACKGROUND))
{
y+= 16;
R2D_ScalePic ( (vid.width-pic->width)/2, 16, pic->width, pic->height, pic);
y+= pic->height;
y+= 8;
}
}
Font_BeginString(font_conchar, rect->x, y, &left, &top);
Font_BeginString(font_conchar, 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);
@ -441,8 +492,6 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
else if (p->flags & CPRINT_OBITUARTY)
//'obituary' messages appear at the bottom of the screen
y = (bottom-top - Font_CharHeight()*linecount) * 0.65 + top;
else if (p->flags & CPRINT_TYPEWRITER)
Font_BeginString(font_conchar, 48, rect->y, &y, &top);
else
{
if (linecount <= 4)
@ -463,7 +512,10 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p)
px = rect->x;
py = ( y * vid.height) / (float)vid.pixelheight;
pw = rect->width+8;
Draw_TextBox(px-16, py-8-8, pw/8, linecount+2);
if (*p->titleimage)
R2D_ScalePic (px-16, py-16, pw + 16, linecount*8 + 32, pic);
else
Draw_TextBox(px-16, py-8-8, pw/8, linecount+2);
}
for (l = 0; l < linecount; l++, y += Font_CharHeight())
@ -545,6 +597,8 @@ void SCR_DrawCursor(int prydoncursornum)
p = R2D_SafeCachePic(va("gfx/prydoncursor%03i.lmp", prydoncursornum));
else
p = R2D_SafeCachePic(cl_cursor.string);
if (!p)
p = R2D_SafeCachePic("gfx/cursor.lmp");
if (p)
{
R2D_ImageColours(1, 1, 1, 1);
@ -1007,7 +1061,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
memset(&tr, 0, sizeof(tr));
tr.fraction = 1;
cl.worldmodel->funcs.Trace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, &tr);
cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr);
start[2]-=16;
if (tr.fraction == 1)
{
@ -2105,7 +2159,7 @@ void SCR_TileClear (void)
if (cl.splitclients>1)
return; //splitclients always takes the entire screen.
#ifdef PLUGINS
/*#ifdef PLUGINS
if (plug_sbar.ival)
{
if (scr_vrect.x > 0)
@ -2132,6 +2186,7 @@ void SCR_TileClear (void)
}
else
#endif
*/
{
if (scr_vrect.x > 0)
{

View file

@ -202,7 +202,9 @@ typedef struct
int type;
vec3_t angles;
vec3_t avel;
int flags;
float gravity;
float alpha;
float start;
float framerate;
@ -389,6 +391,7 @@ void P_LoadedModel(model_t *mod)
P_DefaultTrail(mod);
}
void CL_RefreshCustomTEnts(void);
void CL_RegisterParticles(void)
{
model_t *mod;
@ -460,6 +463,8 @@ void CL_RegisterParticles(void)
ptfte_lightning3_end = P_FindParticleType("TE_LIGHTNING3_END");
ptfte_bullet = P_FindParticleType("TE_BULLET");
ptfte_superbullet = P_FindParticleType("TE_SUPERBULLET");
CL_RefreshCustomTEnts();
}
#ifdef Q2CLIENT
@ -512,6 +517,18 @@ void CL_ClearTEnts (void)
memset (&cl_explosions, 0, sizeof(cl_explosions));
}
static void CL_ClearExplosion(explosion_t *exp)
{
exp->gravity = 0;
exp->flags = 0;
exp->model = NULL;
exp->firstframe = -1;
exp->framerate = 10;
VectorClear(exp->velocity);
VectorClear(exp->angles);
VectorClear(exp->avel);
}
/*
=================
CL_AllocExplosion
@ -527,8 +544,7 @@ explosion_t *CL_AllocExplosion (void)
{
if (!cl_explosions[i].model)
{
cl_explosions[i].firstframe = -1;
cl_explosions[i].framerate = 10;
CL_ClearExplosion(&cl_explosions[i]);
return &cl_explosions[i];
}
}
@ -536,8 +552,7 @@ explosion_t *CL_AllocExplosion (void)
if (i == explosions_running && i != MAX_EXPLOSIONS)
{
explosions_running++;
cl_explosions[i].firstframe = -1;
cl_explosions[i].framerate = 10;
CL_ClearExplosion(&cl_explosions[i]);
return &cl_explosions[i];
}
@ -551,8 +566,7 @@ explosion_t *CL_AllocExplosion (void)
time = cl_explosions[i].start;
index = i;
}
cl_explosions[index].firstframe = -1;
cl_explosions[index].framerate = 10;
CL_ClearExplosion(&cl_explosions[index]);
return &cl_explosions[index];
}
@ -828,6 +842,10 @@ void CL_ParseStream (int type)
b->model = Mod_ForName("models/stmedgaz.mdl", true);
b->particleeffect = P_FindParticleType("te_stream_gaze");
break;
case TEH2_STREAM_FAMINE:
b->model = Mod_ForName("models/fambeam.mdl", true);
b->particleeffect = P_FindParticleType("te_stream_famine");
break;
default:
Con_Printf("CL_ParseStream: type %i\n", type);
break;
@ -1649,14 +1667,14 @@ void CL_ParseCustomTEnt(void)
}
else
{
MSG_ReadPos (pos);
VectorCopy(pos, pos2);
if (t->netstyle & CTE_CUSTOMCOUNT)
count = MSG_ReadByte();
else
count = 1;
MSG_ReadPos (pos);
VectorCopy(pos, pos2);
if (t->netstyle & CTE_CUSTOMVELOCITY)
{
dir[0] = MSG_ReadCoord();
@ -1717,6 +1735,12 @@ void CL_ParseCustomTEnt(void)
*/
}
}
void CL_RefreshCustomTEnts(void)
{
int i;
for (i = 0; i < sizeof(customtenttype)/sizeof(customtenttype[0]); i++)
customtenttype[i].particleeffecttype = P_FindParticleType(customtenttype[i].name);
}
void CL_ClearCustomTEnts(void)
{
int i;
@ -1849,9 +1873,11 @@ void CL_ParseParticleEffect4 (void)
P_RunParticleEffect4 (org, radius, color, effect, msgcount);
}
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe, int framecount, int framerate, float alpha)
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity)
{
explosion_t *ex;
vec3_t spos;
float dlen;
ex = CL_AllocExplosion ();
VectorCopy (org, ex->origin);
@ -1862,12 +1888,25 @@ void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe
ex->framerate = framerate;
ex->alpha = alpha;
ex->angles[0] = 0;
ex->angles[1] = 0;
ex->angles[2] = 0;
if (randspin)
{
ex->angles[0] = frandom()*360;
ex->angles[1] = frandom()*360;
ex->angles[2] = frandom()*360;
ex->avel[0] = crandom()*randspin;
ex->avel[1] = crandom()*randspin;
ex->avel[2] = crandom()*randspin;
}
ex->gravity = gravity;
if (dir)
{
VectorCopy(dir, ex->velocity);
dlen = -10/VectorLength(dir);
VectorMA(ex->origin, dlen, dir, spos);
TraceLineN(spos, org, ex->origin, NULL);
}
else
VectorClear(ex->velocity);
}
@ -1900,7 +1939,7 @@ void CL_ParseEffect (qboolean effect2)
framerate = MSG_ReadByte();
CL_SpawnSpriteEffect(org, vec3_origin, cl.model_precache[modelindex], startframe, framecount, framerate, 1);
CL_SpawnSpriteEffect(org, vec3_origin, cl.model_precache[modelindex], startframe, framecount, framerate, 1, 0, 0);
}
#ifdef Q2CLIENT
@ -2999,6 +3038,12 @@ void CL_UpdateExplosions (void)
explosion_t *ex;
entity_t *ent;
int lastrunningexplosion = -1;
vec3_t pos, norm;
static float oldtime;
float frametime = cl.time - oldtime;
if (frametime < 0 || frametime > 100)
frametime = 0;
oldtime = cl.time;
for (i=0, ex=cl_explosions; i < explosions_running; i++, ex++)
{
@ -3031,7 +3076,37 @@ void CL_UpdateExplosions (void)
ent = CL_NewTempEntity ();
if (!ent)
return;
VectorMA (ex->origin, f, ex->velocity, ent->origin);
if (ex->gravity)
{
VectorMA(ex->origin, frametime, ex->velocity, pos);
if (ex->velocity[0] || ex->velocity[1] || ex->velocity[2])
{
VectorClear(norm);
if (TraceLineN(ex->origin, pos, ent->origin, norm))
{
float sc = DotProduct(ex->velocity, norm) * -1.5;
VectorMA(ex->velocity, sc, norm, ex->velocity);
VectorScale(ex->velocity, 0.9, ex->velocity);
if (norm[2] > 0.7 && DotProduct(ex->velocity, ex->velocity) < 10)
{
VectorClear(ex->velocity);
VectorClear(ex->avel);
}
}
else
ex->velocity[2] -= ex->gravity * frametime;
VectorCopy(ent->origin, ex->origin);
}
else
VectorCopy(ex->origin, ent->origin);
}
else
{
VectorMA (ex->origin, f, ex->velocity, ent->origin);
}
VectorMA(ex->angles, frametime, ex->avel, ex->angles);
VectorCopy (ex->oldorigin, ent->oldorigin);
VectorCopy (ex->angles, ent->angles);
ent->skinnum = ex->skinnum;
@ -3055,7 +3130,7 @@ void CL_UpdateExplosions (void)
ent->shaderRGBAf[1] = ((d_8to24rgbtable[ex->skinnum & 0xFF] >> 8) & 0xFF)/255.0;
ent->shaderRGBAf[2] = ((d_8to24rgbtable[ex->skinnum & 0xFF] >> 16) & 0xFF)/255.0;
}
else
else if (ex->skinnum < 0)
{
ent->skinnum = 7*f/(numframes);
}

View file

@ -592,7 +592,7 @@ void VQ3_RenderView(const q3refdef_t *ref)
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
GL_Set2D ();
GL_Set2D (false);
}
#endif

View file

@ -221,7 +221,7 @@ typedef struct
typedef struct
{
int destcolor[3];
int percent; // 0-256
float percent; // 0-256
} cshift_t;
#define CSHIFT_CONTENTS 0
@ -995,7 +995,7 @@ void CL_ParseParticleEffect4 (void);
void CLDP_ParseTrailParticles(void);
void CLDP_ParsePointParticles(qboolean compact);
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, int framerate, float alpha); /*called from the particlesystem*/
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, float framerate, float alpha, float randspin, float gravity); /*called from the particlesystem*/
//
// cl_ents.c

View file

@ -603,7 +603,7 @@ void Con_PrintCon (console_t *con, char *txt)
#if defined(_WIN32) && !defined(NOMEDIA)
if (con->current)
TTS_SayConString(con->current+1);
TTS_SayConString((conchar_t*)(con->current+1));
#endif
con->current->newer = Z_Malloc(sizeof(conline_t) + sizeof(conchar_t));
@ -844,7 +844,7 @@ void Con_DrawInput (int left, int right, int y)
if (con_current->commandcompletion)
{
if (text[1] == '/' || Cmd_IsCommand(text+1))
if (cl_chatmode.ival && (text[1] == '/' || (cl_chatmode.ival == 2 && Cmd_IsCommand(text+1))))
{ //color the first token yellow, it's a valid command
for (p = 1; (maskedtext[p]&CON_CHARMASK)>' '; p++)
maskedtext[p] = (maskedtext[p]&CON_CHARMASK) | (COLOR_YELLOW<<CON_FGSHIFT);

View file

@ -1059,18 +1059,22 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
{
cin->filmstarttime = curtime;
cin->avi.resettimer = 0;
newframe = 0;
newframei = newframe;
}
newframe = (((curtime - cin->filmstarttime) * cin->avi.vidinfo.dwRate) / cin->avi.vidinfo.dwScale) + cin->avi.vidinfo.dwInitialFrames;
newframei = newframe;
if (newframei>=cin->avi.num_frames)
cin->ended = true;
if (newframei == cin->currentframe)
else
{
cin->outunchanged = true;
return true;
newframe = (((curtime - cin->filmstarttime) * cin->avi.vidinfo.dwRate) / cin->avi.vidinfo.dwScale) + cin->avi.vidinfo.dwInitialFrames;
newframei = newframe;
if (newframei>=cin->avi.num_frames)
cin->ended = true;
if (newframei == cin->currentframe)
{
cin->outunchanged = true;
return true;
}
}
cin->outunchanged = false;
@ -2905,7 +2909,7 @@ void TTS_SayChatString(char **stringtosay)
return;
}
TTS_SayAsciiString(stringtosay);
TTS_SayAsciiString(*stringtosay);
}
void TTS_SayConString(conchar_t *stringtosay)
{

View file

@ -125,8 +125,6 @@ static int PClassic_FindParticleType(char *name)
return BLOBEXPLOSION_POINT;
if (!stricmp("te_lavasplash", name))
return LAVASPLASH_POINT;
if (!stricmp("te_lavasplash", name))
return LAVASPLASH_POINT;
if (!stricmp("te_explosion", name))
return EXPLOSION_POINT;
if (!stricmp("te_teleport", name))
@ -135,6 +133,61 @@ static int PClassic_FindParticleType(char *name)
return P_INVALID;
}
qboolean PClassic_Query(int type, int body, char *outstr, int outstrlen)
{
char *n = NULL;
switch(type)
{
case ROCKET_TRAIL:
n = "tr_rocket";
break;
case ALT_ROCKET_TRAIL:
n = "tr_altrocket";
break;
case BLOOD_TRAIL:
n = "tr_slightblood";
break;
case GRENADE_TRAIL:
n = "tr_grenade";
break;
case BIG_BLOOD_TRAIL:
n = "tr_blood";
break;
case TRACER1_TRAIL:
n = "tr_wizspike";
break;
case TRACER2_TRAIL:
n = "tr_knightspike";
break;
case VOOR_TRAIL:
n = "tr_vorespike";
break;
case BLOBEXPLOSION_POINT:
n = "te_tarexplosion";
break;
case LAVASPLASH_POINT:
n = "te_lavasplash";
break;
case EXPLOSION_POINT:
n = "te_explosion";
break;
case TELEPORTSPLASH_POINT:
n = "te_teleport";
break;
}
if (!n)
return false;
if (body == 0)
{
Q_strncpyz(outstr, n, outstrlen);
return true;
}
return false;
}
//returns a valid effect if both its existance is known, and it is fully functional
static int PClassic_ParticleTypeForName(char *name)
{
@ -860,6 +913,7 @@ particleengine_t pe_classic =
PClassic_ParticleTypeForName,
PClassic_FindParticleType,
PClassic_Query,
PClassic_RunParticleEffectTypeString,
PClassic_ParticleTrail,

View file

@ -62,6 +62,7 @@ particleengine_t pe_null =
PNULL_ParticleTypeForName,
PNULL_FindParticleType,
NULL,
PNULL_RunParticleEffectTypeString,
PNULL_ParticleTrail,

View file

@ -159,17 +159,21 @@ typedef struct {
float scale;
float rotation;
} ramp_t;
typedef struct {
char name[MAX_QPATH];
model_t *model;
float framestart;
float frameend;
float framerate;
float alpha;
} partmodels_t;
// TODO: merge in alpha with rgb to gain benefit of vector opts
typedef struct part_type_s {
char name[MAX_QPATH];
char texname[MAX_QPATH];
char modelname[MAX_QPATH];
model_t *model;
float modelframestart;
float modelframeend;
float modelframerate;
float modelalpha;
int nummodels;
partmodels_t *models;
vec3_t rgb; //initial colour
float alpha;
@ -184,7 +188,7 @@ typedef struct part_type_s {
float scale; //initial scale
float scalerand; //with up to this much extra
float die, randdie; //how long it lasts (plus some rand)
float randomvel, randomvelvert; //random velocity (unaligned)
float randomvel, randomvelvert, randomvelvertbias; //random velocity (unaligned=worldspace)
float veladd; //scale the incoming velocity by this much
float orgadd; //spawn the particle this far along its velocity direction
float spawnvel, spawnvelvert; //spawn the particle with a velocity based upon its spawn type (generally so it flies outwards)
@ -504,10 +508,12 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
texnums_t tn;
char *defaultshader;
char *namepostfix;
int i;
if (qrenderer == QR_NONE)
return;
ptype->model = NULL;
for (i = 0; i < ptype->nummodels; i++)
ptype->models[i].model = NULL;
if (*ptype->texname)
{
@ -535,7 +541,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
// "polygonoffset\n"
"polygonoffset\n"
"}\n"
;
break;
@ -551,7 +557,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
// "polygonoffset\n"
"polygonoffset\n"
"}\n"
;
break;
@ -567,7 +573,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
// "polygonoffset\n"
"polygonoffset\n"
"}\n"
;
break;
@ -583,7 +589,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
// "polygonoffset\n"
"polygonoffset\n"
"}\n"
;
break;
@ -599,7 +605,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
// "polygonoffset\n"
"polygonoffset\n"
"}\n"
;
break;
@ -744,6 +750,8 @@ static void P_ParticleEffect_f(void)
st = ptype->skytris;
if (ptype->ramp)
BZ_Free(ptype->ramp);
if (ptype->models)
BZ_Free(ptype->models);
while (ptype->particles) // empty particle list
{
@ -951,17 +959,35 @@ static void P_ParticleEffect_f(void)
setalphadelta = true;
}
else if (!strcmp(var, "die"))
{
ptype->die = atof(value);
if (Cmd_Argc()>2)
ptype->randdie = atof(Cmd_Argv(2)) - ptype->die;
}
else if (!strcmp(var, "diesubrand"))
ptype->randdie = atof(value);
else if (!strcmp(var, "randomvel"))
{
ptype->randomvel = atof(value);
if (Cmd_Argc()>2)
if (Cmd_Argc()>3)
{
ptype->randomvelvertbias = atof(Cmd_Argv(2));
ptype->randomvelvert = atof(Cmd_Argv(3));
ptype->randomvelvert -= ptype->randomvelvertbias; /*make vert be the total range*/
ptype->randomvelvert /= 2; /*vert is actually +/- 1, not 0 to 1, so rescale it*/
ptype->randomvelvertbias += ptype->randomvelvert; /*and bias must be centered to the range*/
}
else if (Cmd_Argc()>2)
{
ptype->randomvelvert = atof(Cmd_Argv(2));
ptype->randomvelvertbias = 0;
}
else
{
ptype->randomvelvert = ptype->randomvel;
ptype->randomvelvertbias = 0;
}
}
else if (!strcmp(var, "veladd"))
ptype->veladd = atof(value);
@ -1002,11 +1028,13 @@ static void P_ParticleEffect_f(void)
}
else if (!strcmp(var, "model"))
{
Q_strncpyz(ptype->modelname, Cmd_Argv(1), sizeof(ptype->modelname));
ptype->modelframestart = atof(Cmd_Argv(2));
ptype->modelframeend = atof(Cmd_Argv(3));
ptype->modelframerate = atof(Cmd_Argv(4));
ptype->modelalpha = atof(Cmd_Argv(5));
ptype->models = BZ_Realloc(ptype->models, sizeof(partmodels_t)*(ptype->nummodels+1));
Q_strncpyz(ptype->models[ptype->nummodels].name, Cmd_Argv(1), sizeof(ptype->models[ptype->nummodels].name));
ptype->models[ptype->nummodels].framestart = atof(Cmd_Argv(2));
ptype->models[ptype->nummodels].frameend = atof(Cmd_Argv(3));
ptype->models[ptype->nummodels].framerate = atof(Cmd_Argv(4));
ptype->models[ptype->nummodels].alpha = atof(Cmd_Argv(5));
ptype->nummodels++;
}
else if (!strcmp(var, "colorindex"))
{
@ -1407,6 +1435,168 @@ static void P_ParticleEffect_f(void)
r_plooksdirty = true;
}
qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
{
int i;
part_type_t *ptype = &part_type[typenum];
if (typenum < 0 || typenum >= numparticletypes)
return false;
if (body == 0)
{
Q_strncpyz(outstr, ptype->name, outstrlen);
return true;
}
if (body == 1)
{
*outstr = 0;
if (!ptype->loaded)
return true;
Q_strncatz(outstr, va("//this functionality is incomplete\n"), outstrlen);
for (i = 0; i < ptype->nummodels; i++)
{
Q_strncatz(outstr, va("model %s %g %g %g %g\n", ptype->models[i].name, ptype->models[i].framestart, ptype->models[i].frameend, ptype->models[i].framerate, ptype->models[i].alpha), outstrlen);
}
if (*ptype->texname)
Q_strncatz(outstr, va("texture %s\n", ptype->texname), outstrlen);
if (ptype->count)
Q_strncatz(outstr, va("count %g\n", ptype->count), outstrlen);
if (ptype->rgb[0] || ptype->rgb[1] || ptype->rgb[2])
Q_strncatz(outstr, va("rgb %g %g %g\n", ptype->rgb[0]*255, ptype->rgb[1]*255, ptype->rgb[2]*255), outstrlen);
if (ptype->rgbrand[0] || ptype->rgbrand[1] || ptype->rgbrand[2])
Q_strncatz(outstr, va("rgbrand %g %g %g\n", ptype->rgbrand[0]*255, ptype->rgbrand[1]*255, ptype->rgbrand[2]*255), outstrlen);
if (ptype->rgbrandsync[0] || ptype->rgbrandsync[1] || ptype->rgbrandsync[2])
Q_strncatz(outstr, va("rgbrandsync %g %g %g\n", ptype->rgbrandsync[0], ptype->rgbrandsync[1], ptype->rgbrandsync[2]), outstrlen);
if (ptype->rgbchange[0] || ptype->rgbchange[1] || ptype->rgbchange[2])
Q_strncatz(outstr, va("rgbchange %g %g %g\n", ptype->rgbchange[0]*255, ptype->rgbchange[1]*255, ptype->rgbchange[2]*255), outstrlen);
if (ptype->rgbchangetime)
Q_strncatz(outstr, va("rgbchangetime %g\n", ptype->rgbchangetime), outstrlen);
if (ptype->colorindex)
Q_strncatz(outstr, va("colorindex %i\n", ptype->colorindex), outstrlen);
if (ptype->colorrand)
Q_strncatz(outstr, va("colorrand %i\n", ptype->colorrand), outstrlen);
if (ptype->alpha)
Q_strncatz(outstr, va("alpha %g\n", ptype->alpha), outstrlen);
if (ptype->alpharand)
Q_strncatz(outstr, va("alpharand %g\n", ptype->alpharand), outstrlen);
if (ptype->alphachange)
Q_strncatz(outstr, va("alphadelta %g\n", ptype->alphachange), outstrlen);
if (ptype->scale || ptype->scalerand)
Q_strncatz(outstr, va("scale %g %g\n", ptype->scale, ptype->scale+ptype->scalerand), outstrlen);
// if (ptype->looks.scalefactor)
Q_strncatz(outstr, va("scalefactor %g\n", ptype->looks.scalefactor), outstrlen);
if (ptype->scaledelta)
Q_strncatz(outstr, va("scaledelta %g\n", ptype->scaledelta), outstrlen);
if (ptype->die || ptype->randdie)
Q_strncatz(outstr, va("die %g %g\n", ptype->die, ptype->die+ptype->randdie), outstrlen);
if (ptype->randomvel || ptype->randomvelvert || ptype->randomvelvertbias)
Q_strncatz(outstr, va("randomvel %g %g %g\n", ptype->randomvel, ptype->randomvelvertbias - ptype->randomvelvert, ptype->randomvelvertbias + ptype->randomvelvert), outstrlen);
if (ptype->veladd)
Q_strncatz(outstr, va("veladd %g\n", ptype->veladd), outstrlen);
if (ptype->orgadd)
Q_strncatz(outstr, va("orgadd %g\n", ptype->orgadd), outstrlen);
if (ptype->spawnvel || ptype->spawnvelvert)
Q_strncatz(outstr, va("spawnvel %g %g\n", ptype->spawnvel, ptype->spawnvelvert), outstrlen);
if (ptype->assoc != P_INVALID)
Q_strncatz(outstr, va("assoc %s\n", part_type[ptype->assoc].name), outstrlen);
Q_strncatz(outstr, va("tcoords %g %g %g %g %g %i %g\n", ptype->s1, ptype->t1, ptype->s2, ptype->t2, 1.0f, ptype->randsmax, ptype->texsstride), outstrlen);
Q_strncatz(outstr, va("rotationstart %g %g\n", ptype->rotationstartmin*180/M_PI, (ptype->rotationstartmin+ptype->rotationstartrand)*180/M_PI), outstrlen);
Q_strncatz(outstr, va("rotationspeed %g %g\n", ptype->rotationmin*180/M_PI, (ptype->rotationmin+ptype->rotationrand)*180/M_PI), outstrlen);
return true;
#if 0
plooks_t *slooks; //shared looks, so state switches don't apply between particles so much
plooks_t looks;
float spawntime; //time limit for trails
float spawnchance; //if < 0, particles might not spawn so many
float scaledelta;
int countextra;
float count;
float countrand;
int cliptype;
int inwater;
float clipcount;
int emit;
float emittime;
float emitrand;
float emitstart;
float areaspread;
float areaspreadvert;
float spawnparam1;
float spawnparam2;
/* float spawnparam3; */
float offsetup; // make this into a vec3_t later with dir, possibly for mdls
enum {
SM_BOX, //box = even spread within the area
SM_CIRCLE, //circle = around edge of a circle
SM_BALL, //ball = filled sphere
SM_SPIRAL, //spiral = spiral trail
SM_TRACER, //tracer = tracer trail
SM_TELEBOX, //telebox = q1-style telebox
SM_LAVASPLASH, //lavasplash = q1-style lavasplash
SM_UNICIRCLE, //unicircle = uniform circle
SM_FIELD, //field = synced field (brightfield, etc)
SM_DISTBALL // uneven distributed ball
} spawnmode;
float gravity;
vec3_t friction;
float clipbounce;
int stainonimpact;
vec3_t dl_rgb;
float dl_radius;
float dl_time;
vec4_t dl_decay;
vec3_t stain_rgb;
float stain_radius;
enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode;
int rampindexes;
ramp_t *ramp;
int loaded;
particle_t *particles;
clippeddecal_t *clippeddecals;
beamseg_t *beams;
skytris_t *skytris;
struct part_type_s *nexttorun;
unsigned int flags;
#define PT_CITRACER 0x008 // Q1-style tracer behavior for colorindex
#define PT_INVFRAMETIME 0x010 // apply inverse frametime to count (causes emits to be per frame)
#define PT_AVERAGETRAIL 0x020 // average trail points from start to end, useful with t_lightning, etc
#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...)
#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle
#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle
#endif
}
return false;
}
#if _DEBUG
// R_BeamInfo_f - debug junk
static void P_BeamInfo_f (void)
@ -2405,14 +2595,248 @@ static vec2_t avelocities[NUMVERTEXNORMALS];
// float timescale = 0.01;
static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, int dlkey)
static void PScript_ApplyOrgVel(vec3_t oorg, vec3_t ovel, vec3_t eforg, vec3_t efdir, int pno, int pmax, part_type_t *ptype)
{
if (*ptype->modelname)
vec3_t ofsvec, arsvec;
float k,l,m;
int spawnspc, i=pno, j;
l=0;
j=0;
k=0;
m=0;
spawnspc = 8;
switch (ptype->spawnmode)
{
if (!ptype->model)
ptype->model = Mod_ForName(ptype->modelname, false);
if (ptype->model && !ptype->model->needload)
CL_SpawnSpriteEffect(org, dir, ptype->model, ptype->modelframestart, (ptype->modelframeend?ptype->modelframeend:(ptype->model->numframes - ptype->modelframestart)), ptype->modelframerate?ptype->modelframerate:10, ptype->modelalpha?ptype->modelalpha:1);
case SM_UNICIRCLE:
m = pmax;
if (ptype->looks.type == PT_BEAM)
m--;
if (m < 1)
m = 0;
else
m = (M_PI*2)/m;
if (ptype->spawnparam1) /* use for weird shape hacks */
m *= ptype->spawnparam1;
break;
case SM_TELEBOX:
spawnspc = 4;
l = -ptype->areaspreadvert;
case SM_LAVASPLASH:
j = k = -ptype->areaspread;
if (ptype->spawnparam1)
m = ptype->spawnparam1;
else
m = 0.55752; /* default weird number for tele/lavasplash used in vanilla Q1 */
if (ptype->spawnparam2)
spawnspc = (int)ptype->spawnparam2;
break;
case SM_FIELD:
if (!avelocities[0][0])
{
for (j=0 ; j<NUMVERTEXNORMALS*2 ; j++)
avelocities[0][j] = (rand()&255) * 0.01;
}
j = 0;
m = 0;
break;
default: //others don't need intitialisation
break;
}
// randomvel
ovel[0] = crandom()*ptype->randomvel;
ovel[1] = crandom()*ptype->randomvel;
ovel[2] = crandom()*ptype->randomvelvert + ptype->randomvelvertbias;
// handle spawn modes (org/vel)
switch (ptype->spawnmode)
{
case SM_BOX:
ofsvec[0] = crandom();
ofsvec[1] = crandom();
ofsvec[2] = crandom();
arsvec[0] = ofsvec[0]*ptype->areaspread;
arsvec[1] = ofsvec[1]*ptype->areaspread;
arsvec[2] = ofsvec[2]*ptype->areaspreadvert;
break;
case SM_TELEBOX:
ofsvec[0] = k;
ofsvec[1] = j;
ofsvec[2] = l+4;
VectorNormalize(ofsvec);
VectorScale(ofsvec, 1.0-(frandom())*m, ofsvec);
// org is just like the original
arsvec[0] = j + (rand()%spawnspc);
arsvec[1] = k + (rand()%spawnspc);
arsvec[2] = l + (rand()%spawnspc);
// advance telebox loop
j += spawnspc;
if (j >= ptype->areaspread)
{
j = -ptype->areaspread;
k += spawnspc;
if (k >= ptype->areaspread)
{
k = -ptype->areaspread;
l += spawnspc;
if (l >= ptype->areaspreadvert)
l = -ptype->areaspreadvert;
}
}
break;
case SM_LAVASPLASH:
// calc directions, org with temp vector
ofsvec[0] = k + (rand()%spawnspc);
ofsvec[1] = j + (rand()%spawnspc);
ofsvec[2] = 256;
arsvec[0] = ofsvec[0];
arsvec[1] = ofsvec[1];
arsvec[2] = frandom()*ptype->areaspreadvert;
VectorNormalize(ofsvec);
VectorScale(ofsvec, 1.0-(frandom())*m, ofsvec);
// advance splash loop
j += spawnspc;
if (j >= ptype->areaspread)
{
j = -ptype->areaspread;
k += spawnspc;
if (k >= ptype->areaspread)
k = -ptype->areaspread;
}
break;
case SM_UNICIRCLE:
ofsvec[0] = cos(m*i);
ofsvec[1] = sin(m*i);
ofsvec[2] = 0;
VectorScale(ofsvec, ptype->areaspread, arsvec);
break;
case SM_FIELD:
arsvec[0] = cl.time * (avelocities[i][0] + m);
arsvec[1] = cl.time * (avelocities[i][1] + m);
arsvec[2] = cos(arsvec[1]);
ofsvec[0] = arsvec[2]*cos(arsvec[0]);
ofsvec[1] = arsvec[2]*sin(arsvec[0]);
ofsvec[2] = -sin(arsvec[1]);
arsvec[0] = r_avertexnormals[j][0]*ptype->areaspread + ofsvec[0]*BEAMLENGTH;
arsvec[1] = r_avertexnormals[j][1]*ptype->areaspread + ofsvec[1]*BEAMLENGTH;
arsvec[2] = r_avertexnormals[j][2]*ptype->areaspreadvert + ofsvec[2]*BEAMLENGTH;
VectorNormalize(ofsvec);
j++;
if (j >= NUMVERTEXNORMALS)
{
j = 0;
m += 0.1762891; // some BS number to try to "randomize" things
}
break;
case SM_DISTBALL:
{
float rdist;
rdist = ptype->spawnparam2 - crandom()*(1-(crandom() * ptype->spawnparam1));
// this is a strange spawntype, which is based on the fact that
// crandom()*crandom() provides something similar to an exponential
// probability curve
ofsvec[0] = hrandom();
ofsvec[1] = hrandom();
if (ptype->areaspreadvert)
ofsvec[2] = hrandom();
else
ofsvec[2] = 0;
VectorNormalize(ofsvec);
VectorScale(ofsvec, rdist, ofsvec);
arsvec[0] = ofsvec[0]*ptype->areaspread;
arsvec[1] = ofsvec[1]*ptype->areaspread;
arsvec[2] = ofsvec[2]*ptype->areaspreadvert;
}
break;
default: // SM_BALL, SM_CIRCLE
ofsvec[0] = hrandom();
ofsvec[1] = hrandom();
if (ptype->areaspreadvert)
ofsvec[2] = hrandom();
else
ofsvec[2] = 0;
VectorNormalize(ofsvec);
if (ptype->spawnmode != SM_CIRCLE)
VectorScale(ofsvec, frandom(), ofsvec);
arsvec[0] = ofsvec[0]*ptype->areaspread;
arsvec[1] = ofsvec[1]*ptype->areaspread;
arsvec[2] = ofsvec[2]*ptype->areaspreadvert;
break;
}
oorg[0] = eforg[0] + arsvec[0];
oorg[1] = eforg[1] + arsvec[1];
oorg[2] = eforg[2] + arsvec[2] + ptype->offsetup;
// apply arsvec+ofsvec
if (efdir)
{
ovel[0] += efdir[0]*ptype->veladd+ofsvec[0]*ptype->spawnvel;
ovel[1] += efdir[1]*ptype->veladd+ofsvec[1]*ptype->spawnvel;
ovel[2] += efdir[2]*ptype->veladd+ofsvec[2]*ptype->spawnvelvert;
oorg[0] += efdir[0]*ptype->orgadd;
oorg[1] += efdir[1]*ptype->orgadd;
oorg[2] += efdir[2]*ptype->orgadd;
}
else
{
ovel[0] += ofsvec[0]*ptype->spawnvel;
ovel[1] += ofsvec[1]*ptype->spawnvel;
ovel[2] += ofsvec[2]*ptype->spawnvelvert - ptype->veladd;
oorg[2] -= ptype->orgadd;
}
}
static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir, int dlkey, float countscale)
{
if (ptype->nummodels)
{
int count = ptype->countextra + countscale*(ptype->count+ptype->countrand*frandom());
int i;
partmodels_t *mod;
if (!ptype->countextra && !ptype->count)
count = countscale;
for (i = 0; i < count; i++)
{
mod = &ptype->models[rand() % ptype->nummodels];
if (!mod->model)
mod->model = Mod_ForName(mod->name, false);
if (mod->model && !mod->model->needload)
{
vec3_t morg, mdir;
PScript_ApplyOrgVel(morg, mdir, org, dir, i, count, ptype);
CL_SpawnSpriteEffect(morg, mdir, mod->model, mod->framestart, (mod->frameend?mod->frameend:(mod->model->numframes - mod->framestart)), mod->framerate?mod->framerate:10, ptype->alpha?ptype->alpha:1, ptype->rotationmin*180/M_PI, ptype->gravity);
}
}
}
if (ptype->dl_radius)
{
@ -2489,7 +2913,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
while(ptype)
{
PScript_EffectSpawned(ptype, org, dir, 0);
PScript_EffectSpawned(ptype, org, dir, 0, count);
if (ptype->looks.type == PT_DECAL)
{
@ -2531,7 +2955,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
VectorSubtract(org, t2, tangent);
VectorAdd(org, t2, t2);
if (cl.worldmodel->funcs.Trace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, &tr))
if (cl.worldmodel->funcs.NativeTrace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr))
{
if (tr.fraction < dist)
{
@ -2546,17 +2970,19 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
VectorNormalize(dir);
VectorNormalize(vec);
CrossProduct(dir, vec, tangent);
CrossProduct(dir, vec, t2);
Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, dir[0], dir[1], dir[2]), t2, tangent);
CrossProduct(dir, tangent, t2);
sw = ptype->s2 - ptype->s1;
sb = ptype->s1 + sw/2;
tw = ptype->t2 - ptype->t1;
tb = ptype->t1 + tw/2;
sw /= ptype->scale;
tw /= ptype->scale;
m = ptype->scale + frandom() * ptype->scalerand;
sw /= m;
tw /= m;
decalcount = Q1BSP_ClipDecal(org, dir, tangent, t2, ptype->scale, &decverts);
decalcount = Q1BSP_ClipDecal(org, dir, tangent, t2, m, &decverts);
while(decalcount)
{
if (!free_decals)
@ -2787,7 +3213,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
// randomvel
p->vel[0] = crandom()*ptype->randomvel;
p->vel[1] = crandom()*ptype->randomvel;
p->vel[2] = crandom()*ptype->randomvelvert;
p->vel[2] = crandom()*ptype->randomvelvert + ptype->randomvelvertbias;
// handle spawn modes (org/vel)
switch (ptype->spawnmode)
@ -3298,7 +3724,7 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
else
ts = NULL;
PScript_EffectSpawned(ptype, start, vec3_origin, dlkey);
PScript_EffectSpawned(ptype, start, vec3_origin, dlkey, 1);
if (ptype->assoc>=0)
{
@ -4128,42 +4554,41 @@ static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
}
}
static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *type)
static void R_AddClippedDecal(scenetris_t *t, clippeddecal_t *d, plooks_t *type)
{
clippeddecal_t *d;
while (count--)
if (cl_numstrisvert+4 > cl_maxstrisvert)
{
d = *dlist++;
if (pscripttmesh.numvertexes >= BUFFERVERTS-3)
{
pscripttmesh.numindexes = pscripttmesh.numvertexes;
BE_DrawMesh_Single(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures, 0);
pscripttmesh.numvertexes = 0;
}
Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+0]);
Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+1]);
Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+2]);
Vector2Copy(d->texcoords[0], pscripttexcoords[pscripttmesh.numvertexes+0]);
Vector2Copy(d->texcoords[1], pscripttexcoords[pscripttmesh.numvertexes+1]);
Vector2Copy(d->texcoords[2], pscripttexcoords[pscripttmesh.numvertexes+2]);
VectorCopy(d->vertex[0], pscriptverts[pscripttmesh.numvertexes+0]);
VectorCopy(d->vertex[1], pscriptverts[pscripttmesh.numvertexes+1]);
VectorCopy(d->vertex[2], pscriptverts[pscripttmesh.numvertexes+2]);
pscripttmesh.numvertexes += 3;
cl_maxstrisvert+=64*4;
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);
}
if (pscripttmesh.numvertexes)
Vector4Copy(d->rgba, cl_strisvertc[cl_numstrisvert+0]);
Vector4Copy(d->rgba, cl_strisvertc[cl_numstrisvert+1]);
Vector4Copy(d->rgba, cl_strisvertc[cl_numstrisvert+2]);
Vector2Copy(d->texcoords[0], cl_strisvertt[cl_numstrisvert+0]);
Vector2Copy(d->texcoords[1], cl_strisvertt[cl_numstrisvert+1]);
Vector2Copy(d->texcoords[2], cl_strisvertt[cl_numstrisvert+2]);
VectorCopy(d->vertex[0], cl_strisvertv[cl_numstrisvert+0]);
VectorCopy(d->vertex[1], cl_strisvertv[cl_numstrisvert+1]);
VectorCopy(d->vertex[2], cl_strisvertv[cl_numstrisvert+2]);
if (cl_numstrisidx+3 > cl_maxstrisidx)
{
pscripttmesh.numindexes = pscripttmesh.numvertexes;
BE_DrawMesh_Single(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures, 0);
pscripttmesh.numvertexes = 0;
cl_maxstrisidx += 64*3;
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_strisidx[cl_numstrisidx++] = (cl_numstrisvert - t->firstvert) + 2;
cl_numstrisvert += 3;
t->numvert += 3;
t->numidx += 3;
}
static void R_AddTexturedParticle(scenetris_t *t, particle_t *p, plooks_t *type)
@ -4339,6 +4764,23 @@ static void PScript_DrawParticleTypes (void)
{
if (type->clippeddecals)
{
if (cl_numstris && cl_stris[cl_numstris-1].shader == type->looks.shader)
scenetri = &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);
}
scenetri = &cl_stris[cl_numstris++];
scenetri->shader = type->looks.shader;
scenetri->firstidx = cl_numstrisidx;
scenetri->firstvert = cl_numstrisvert;
scenetri->numvert = 0;
scenetri->numidx = 0;
}
for ( ;; )
{
dkill = type->clippeddecals;
@ -4393,7 +4835,7 @@ static void PScript_DrawParticleTypes (void)
d->rgba[3] += pframetime*type->alphachange;
}
GL_DrawClippedDecal(1, &d, &type->looks);
R_AddClippedDecal(scenetri, d, type->slooks);
}
}
@ -4857,6 +5299,7 @@ particleengine_t pe_script =
PScript_ParticleTypeForName,
PScript_FindParticleType,
PScript_Query,
PScript_RunParticleEffectTypeString,
PScript_ParticleTrail,

View file

@ -1095,17 +1095,8 @@ static void QCBUILTIN PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s
if (cl.worldmodel)
{
//work out which packet entities are solid
CL_SetSolidEntities ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(false);
// do client side motion prediction
CL_PredictMove ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(true);
}
skel_dodelete(csqcprogs);
@ -1383,7 +1374,7 @@ static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
GL_Set2D ();
GL_Set2D (false);
}
#endif
#ifdef D3DQUAKE
@ -1932,6 +1923,28 @@ 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)
{
int id = G_FLOAT(OFS_PARM0);
qboolean body = G_FLOAT(OFS_PARM1);
char retstr[8192];
if (csqc_isdarkplaces)
{
//keep the effectinfo synced between server and client.
id = COM_Effectinfo_ForName(COM_Effectinfo_ForNumber(id));
}
else
id = id - 1;
if (pe->ParticleQuery && pe->ParticleQuery(id, body, retstr, sizeof(retstr)))
{
RETURN_TSTRING(retstr);
}
else
G_INT(OFS_RETURN) = 0;
}
static void QCBUILTIN PF_cs_sendevent (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent;
@ -2486,7 +2499,7 @@ void QCBUILTIN PF_cl_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals
mdl = Mod_ForName(name, false);
if (mdl)
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, 1);
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, 1, 0, 0);
else
Con_Printf("PF_cl_effect: Couldn't load model %s\n", name);
}
@ -4289,6 +4302,7 @@ static struct {
{"dynamiclight_get", PF_R_DynamicLight_Get, 372},
{"dynamiclight_set", PF_R_DynamicLight_Set, 373},
{"particleeffectquery", PF_cs_particleeffectquery, 374},
//400
{"copyentity", PF_cs_copyentity, 400}, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)

View file

@ -2022,15 +2022,6 @@ void MP_Draw(void)
if (setjmp(mp_abort))
return;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
GL_TexEnv(GL_MODULATE);
qglDisable(GL_ALPHA_TEST);
qglEnable(GL_BLEND);
}
#endif
menutime = Sys_DoubleTime();
if (mp_time)
*mp_time = menutime;

View file

@ -275,12 +275,21 @@ mpic_t *R2D_SafeCachePic (char *path)
char *failedpic; //easier this way
mpic_t *R2D_SafePicFromWad (char *name)
{
char newname[32];
char newnamewad[32];
char newnamegfx[32];
shader_t *s;
snprintf(newname, sizeof(newname), "gfx/%s.lmp", name);
s = R_RegisterPic(newname);
snprintf(newnamewad, sizeof(newnamewad), "wad/%s.lmp", name);
snprintf(newnamegfx, sizeof(newnamegfx), "gfx/%s.lmp", name);
s = R_RegisterPic(newnamewad);
if (!(s->flags & SHADER_NOIMAGE))
return s;
s = R_RegisterPic(newnamegfx);
if (!(s->flags & SHADER_NOIMAGE))
return s;
failedpic = name;
return NULL;
}
@ -693,7 +702,7 @@ void R2D_ScreenAngle_Callback(struct cvar_s *var, char *oldvalue)
R_PolyBlend
============
*/
//bright flashes and stuff
//bright flashes and stuff, game only, doesn't touch sbar
void R2D_PolyBlend (void)
{
if (!sw_blend[3])
@ -703,7 +712,7 @@ void R2D_PolyBlend (void)
return;
R2D_ImageColours (sw_blend[0], sw_blend[1], sw_blend[2], sw_blend[3]);
R2D_ScalePic(0, 0, vid.width, vid.height, shader_polyblend);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height, shader_polyblend);
R2D_ImageColours (1, 1, 1, 1);
}
@ -734,6 +743,9 @@ void R2D_BrightenScreen (void)
}
R2D_ImageColours (1, 1, 1, 1);
/*make sure the hud is drawn if needed*/
Sbar_Changed();
RSpeedEnd(RSPEED_PALETTEFLASHES);
}

View file

@ -823,7 +823,7 @@ return;
D3_RecursiveSurfCheck (node->child[side^1], midf, p2f, mid, p2);
}
qboolean D3_Trace (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace)
qboolean D3_Trace (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, struct trace_s *trace)
{
int i;
float e1,e2;
@ -1281,7 +1281,7 @@ qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf)
mod->entities = FS_LoadMallocFile(va("%s.map", token));
mod->funcs.FindTouchedLeafs = D3_FindTouchedLeafs;
mod->funcs.Trace = D3_Trace;
mod->funcs.NativeTrace = D3_Trace;
mod->funcs.PointContents = D3_PointContents;
mod->funcs.FatPVS = D3_FatPVS;
mod->funcs.LeafnumForPoint = D3_LeafnumForPoint;
@ -1304,4 +1304,4 @@ qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf)
return true;
}
#endif
#endif

View file

@ -181,7 +181,7 @@ void P_Shutdown(void)
qboolean Q2TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{
vec3_t nul = {0,0,0};
trace_t trace = CM_BoxTrace(pmove.physents[0].model, start, end, nul, nul, MASK_SOLID);
trace_t trace = CM_BoxTrace(pmove.physents[0].model, start, end, nul, nul, MASK_WORLDSOLID);
if (trace.fraction < 1)
{
@ -223,10 +223,10 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{
AngleVectors(pe->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
pe->model->funcs.Trace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, &trace);
pe->model->funcs.NativeTrace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, MASK_WORLDSOLID, &trace);
}
else
pe->model->funcs.Trace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, &trace);
pe->model->funcs.NativeTrace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, MASK_WORLDSOLID, &trace);
if (trace.fraction<1)
{
VectorSubtract(trace.endpos, ts, delta);
@ -250,8 +250,8 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
normal[1] = -delta[1];
normal[2] = -delta[2];
}
VectorCopy (start, impact);
return true;
VectorCopy (end, impact);
return false;
}
}

View file

@ -1823,6 +1823,26 @@ char *particle_set_minimal =
char *particle_set_h2part =
"r_part t_rocket\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"tcoords 1 1 63 63 256 2 64\n"
"step 32\n"
"scale 64\n"
"alpha 0.6\n"
"die 1\n"
"randomvel 64\n"
"veladd 10\n"
"rotationspeed 90\n"
"rotationstart 0 360\n"
"rgb 16 32 16\n"
"rgbrand 16 64 16\n"
"gravity 200\n"
"scalefactor 0.8\n"
"scaledelta -10\n"
"stains 2\n"
"}\n"
"r_part ce_white_smoke_05\n"
"{\n"
"model models/whtsmk1.spr 0 0 20 0.5\n"
@ -1974,7 +1994,7 @@ char *particle_set_h2part =
"}\n"
"r_part ce_magic_missile_explosion\n"
"{\n"
"model models/mm_explod.spr 0 0 20 1\n"
"model models/mm_expld.spr 0 0 20 1\n"
"}\n"
// ce_ghost
"r_part ce_bone_explosion\n"
@ -2051,6 +2071,286 @@ char *particle_set_h2part =
"{\n"
"model models/biggy.spr 0 0 20 1\n"
"}\n"
"r_part ce_boneshard\n"
"{\n"
"model models/boneshot.mdl 0 1 1 1\n"
"rotationspeed 425\n"
"veladd 2\n"
"}\n"
"r_part ce_boneshrapnel\n"
"{\n"
"model models/boneshrd.mdl 0 1 1 1\n"
"rotationspeed 425\n"
"veladd 2\n"
"}\n"
"r_part ce_chunk_greystone\n"
"{\n"
"model models/schunk1.mdl 0 1 0.25 1\n"
"model models/schunk2.mdl 0 1 0.25 1\n"
"model models/schunk3.mdl 0 1 0.25 1\n"
"model models/schunk4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_wood\n"
"{\n"
"model models/splnter1.mdl 0 1 0.25 1\n"
"model models/splnter2.mdl 0 1 0.25 1\n"
"model models/splnter3.mdl 0 1 0.25 1\n"
"model models/splnter4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_metal\n"
"{\n"
"model models/metlchk1.mdl 0 1 0.25 1\n"
"model models/metlchk2.mdl 0 1 0.25 1\n"
"model models/metlchk3.mdl 0 1 0.25 1\n"
"model models/metlchk4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_flesh\n"
"{\n"
"model models/flesh1.mdl 0 1 0.25 1\n"
"model models/flesh2.mdl 0 1 0.25 1\n"
"model models/flesh3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
//r_part ce_chunk_fire
//{
//}
"r_part ce_chunk_clay\n"
"{\n"
"model models/clshard1.mdl 0 1 0.25 1\n"
"model models/clshard2.mdl 0 1 0.25 1\n"
"model models/clshard3.mdl 0 1 0.25 1\n"
"model models/clshard4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_leaves\n"
"{\n"
"model models/leafchk1.mdl 0 1 0.25 1\n"
"model models/leafchk2.mdl 0 1 0.25 1\n"
"model models/leafchk3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_hay\n"
"{\n"
"model models/hay1.mdl 0 1 0.25 1\n"
"model models/hay2.mdl 0 1 0.25 1\n"
"model models/hay3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_brownstone\n"
"{\n"
"model models/schunk1.mdl 1 1 0.25 1\n"
"model models/schunk2.mdl 1 1 0.25 1\n"
"model models/schunk3.mdl 1 1 0.25 1\n"
"model models/schunk4.mdl 1 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_cloth\n"
"{\n"
"model models/clthchk1.mdl 0 1 0.25 1\n"
"model models/clthchk2.mdl 0 1 0.25 1\n"
"model models/clthchk3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_wood_leaf\n"
"{\n"
"model models/splnter1.mdl 0 1 0.25 1\n"
"model models/splnter2.mdl 0 1 0.25 1\n"
"model models/splnter3.mdl 0 1 0.25 1\n"
"model models/splnter4.mdl 0 1 0.25 1\n"
"model models/leafchk1.mdl 0 1 0.25 1\n"
"model models/leafchk2.mdl 0 1 0.25 1\n"
"model models/leafchk3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_wood_metal\n"
"{\n"
"model models/splnter1.mdl 0 1 0.25 1\n"
"model models/splnter2.mdl 0 1 0.25 1\n"
"model models/splnter3.mdl 0 1 0.25 1\n"
"model models/splnter4.mdl 0 1 0.25 1\n"
"model models/metlchk1.mdl 0 1 0.25 1\n"
"model models/metlchk2.mdl 0 1 0.25 1\n"
"model models/metlchk3.mdl 0 1 0.25 1\n"
"model models/metlchk4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_wood_stone\n"
"{\n"
"model models/splnter1.mdl 0 1 0.25 1\n"
"model models/splnter2.mdl 0 1 0.25 1\n"
"model models/splnter3.mdl 0 1 0.25 1\n"
"model models/splnter4.mdl 0 1 0.25 1\n"
"model models/schunk1.mdl 0 1 0.25 1\n"
"model models/schunk2.mdl 0 1 0.25 1\n"
"model models/schunk3.mdl 0 1 0.25 1\n"
"model models/schunk4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_metal_stone\n"
"{\n"
"model models/metlchk1.mdl 0 1 0.25 1\n"
"model models/metlchk2.mdl 0 1 0.25 1\n"
"model models/metlchk3.mdl 0 1 0.25 1\n"
"model models/metlchk4.mdl 0 1 0.25 1\n"
"model models/schunk1.mdl 0 1 0.25 1\n"
"model models/schunk2.mdl 0 1 0.25 1\n"
"model models/schunk3.mdl 0 1 0.25 1\n"
"model models/schunk4.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_metal_cloth\n"
"{\n"
"model models/metlchk1.mdl 0 1 0.25 1\n"
"model models/metlchk2.mdl 0 1 0.25 1\n"
"model models/metlchk3.mdl 0 1 0.25 1\n"
"model models/metlchk4.mdl 0 1 0.25 1\n"
"model models/clthchk1.mdl 0 1 0.25 1\n"
"model models/clthchk2.mdl 0 1 0.25 1\n"
"model models/clthchk3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_webs\n"
"{\n"
"model models/shard1.mdl 3 1 0.25 0.5\n"
"model models/shard2.mdl 3 1 0.25 0.5\n"
"model models/shard3.mdl 3 1 0.25 0.5\n"
"model models/shard4.mdl 3 1 0.25 0.5\n"
"model models/shard5.mdl 3 1 0.25 0.5\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 500\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_glass\n"
"{\n"
"model models/shard1.mdl 0 1 0.25 1\n"
"model models/shard2.mdl 0 1 0.25 1\n"
"model models/shard3.mdl 0 1 0.25 1\n"
"model models/shard4.mdl 0 1 0.25 1\n"
"model models/shard5.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_ice\n"
"{\n"
"model models/shard.mdl 0 1 0.25 0.5\n"
"model models/shard.mdl 1 1 0.25 0.5\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"}\n"
"r_part ce_chunk_clearglass\n"
"{\n"
"model models/shard1.mdl 1 1 0.25 0.5\n"
"model models/shard2.mdl 1 1 0.25 0.5\n"
"model models/shard3.mdl 1 1 0.25 0.5\n"
"model models/shard4.mdl 1 1 0.25 0.5\n"
"model models/shard5.mdl 1 1 0.25 0.5\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_redglass\n"
"{\n"
"model models/shard1.mdl 2 1 0.25 1\n"
"model models/shard2.mdl 2 1 0.25 1\n"
"model models/shard3.mdl 2 1 0.25 1\n"
"model models/shard4.mdl 2 1 0.25 1\n"
"model models/shard5.mdl 2 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_acid\n"
"{\n"
"model models/sucwp2p.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_meteor\n"
"{\n"
"model models/tempmetr.mdl 0 1 0.25 1\n"
"randomvel 360\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_greenflesh\n"
"{\n"
"model models/sflesh1.mdl 0 1 0.25 1\n"
"model models/sflesh2.mdl 0 1 0.25 1\n"
"model models/sflesh3.mdl 0 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
"r_part ce_chunk_bone\n"
"{\n"
"model models/clshard1.mdl 1 1 0.25 1\n"
"model models/clshard2.mdl 1 1 0.25 1\n"
"model models/clshard3.mdl 1 1 0.25 1\n"
"model models/clshard4.mdl 1 1 0.25 1\n"
"randomvel 210 70 280\n"
"spawnorg 0\n"
"gravity 800\n"
"rotationspeed 425\n"
"}\n"
;

View file

@ -1165,17 +1165,10 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa)
glRect_t *theRect;
int smax, tmax;
if (!fa->mesh)
return;
//surfaces without lightmaps
if (fa->lightmaptexturenum<0)
return;
//surfaces with lightmaps that do not animate, supposedly
if (fa->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP))
return;
// check for lightmap modification
if (!fa->samples)
{
@ -1271,10 +1264,6 @@ void Surf_RenderAmbientLightmaps (msurface_t *fa, int ambient)
if (fa->lightmaptexturenum<0)
return;
//surfaces with lightmaps that do not animate, supposedly
if (fa->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP))
return;
if (fa->cached_light[0] != ambient || fa->cached_colour[0] != 0xff)
goto dynamic;
@ -2031,7 +2020,7 @@ void Surf_DrawWorld (void)
currententity = &r_worldentity;
#ifdef MAP_DOOM
if (currentmodel->fromgame = fg_doom)
if (currentmodel->fromgame == fg_doom)
GLR_DoomWorld();
else
#endif
@ -2431,6 +2420,11 @@ static void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
surf->lightmaptexturenum = -1;
if (surf->texinfo->flags & TEX_SPECIAL)
surf->lightmaptexturenum = -1;
//surfaces with lightmaps that do not animate, supposedly
if (surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP))
surf->lightmaptexturenum = -1;
if (surf->lightmaptexturenum<0)
{
surf->lightmaptexturenum = -1;

View file

@ -312,12 +312,13 @@ cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10"
cvar_t r_glsl_offsetmapping = CVARF ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE);
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
cvar_t r_glsl_offsetmapping_reliefmapping = CVARF("r_glsl_offsetmapping_reliefmapping", "1", CVAR_RENDERERLATCH);
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0.8", 0);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0");
@ -386,6 +387,7 @@ void GLRenderer_Init(void)
Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
#ifdef R_XFLIP
@ -965,6 +967,8 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
if (host_basepal)
BZ_Free(host_basepal);
host_basepal = (qbyte *)FS_LoadMallocFile ("gfx/palette.lmp");
if (!host_basepal)
host_basepal = (qbyte *)FS_LoadMallocFile ("wad/playpal");
if (!host_basepal)
{
qbyte *pcx=NULL;

View file

@ -2494,17 +2494,15 @@ void Sbar_Draw (void)
Sbar_Voice(16);
}
#ifdef GLQUAKE
if (cl_sbar.value == 1 || scr_viewsize.value<100)
{
if (cl.splitclients==1 && sbar_rect.x>0)
{ // left
R2D_TileClear (0, sbar_rect.height - sb_lines, sbar_rect.x, sb_lines);
R2D_TileClear (0, sbar_rect.height - sb_lines, sbar_rect.x, sb_lines);
}
if (sbar_rect.x + 320 <= sbar_rect.width && !headsup)
R2D_TileClear (sbar_rect.x + 320, sbar_rect.height - sb_lines, sbar_rect.width - (320), sb_lines);
}
#endif
if (sb_lines > 0)
@ -3288,8 +3286,5 @@ void Sbar_FinaleOverlay (void)
if (UI_DrawFinale()>0)
return;
#endif
pic = R2D_SafeCachePic ("gfx/finale.lmp");
if (pic)
R2D_ScalePic ( (vid.width-pic->width)/2, 16, pic->width, pic->height, pic);
}

View file

@ -676,7 +676,7 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
{
// format data from Unofficial Doom Specs v1.6
unsigned short *dataus;
int samples, rate, len;
int samples, rate;
if (datalen < 8)
return NULL;
@ -695,7 +695,7 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
if (datalen != samples)
return NULL;
COM_CharBias(data, sc->length);
COM_CharBias(data, datalen);
ResampleSfx (s, rate, 1, 1, samples, -1, data);

View file

@ -1,447 +1,448 @@
#include <jni.h>
#include <errno.h>
#include <android/log.h>
#include "quakedef.h"
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <dirent.h>
#ifndef isDedicated
#ifdef SERVERONLY
qboolean isDedicated = true;
#else
qboolean isDedicated = false;
#endif
#endif
void *sys_window; /*public so the renderer can attach to the correct place*/
static qboolean sys_running = false;
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DISTRIBUTION"Droid", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, DISTRIBUTION"Droid", __VA_ARGS__))
static void *sys_memheap;
static unsigned int sys_lastframe;
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject obj)
{
#ifdef SERVERONLY
SV_Frame();
#else
unsigned int now = Sys_Milliseconds();
double tdelta = (now - sys_lastframe) * 0.001;
Host_Frame(tdelta);
sys_lastframe = now;
#endif
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
jint width, jint height)
{
vid.pixelwidth = width;
vid.pixelheight = height;
if (!sys_running)
{
quakeparms_t parms;
parms.basedir = "/sdcard/fte";
parms.argc = 0;
parms.argv = NULL;
parms.memsize = sys_memheap = 8*1024*1024;
parms.membase = malloc(parms.memsize);
if (!parms.membase)
{
Sys_Printf("Unable to alloc heap\n");
return;
}
Sys_Printf("Starting up\n");
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();
#ifdef SERVERONLY
SV_Init(&parms);
#else
Host_Init(&parms);
#endif
sys_running = true;
sys_lastframe = Sys_Milliseconds();
}
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_keypress(JNIEnv *env, jobject obj,
jint down, jint keycode, jint unicode)
{
Key_Event(0, keycode, unicode, down);
}
int mousecursor_x, mousecursor_y;
float mouse_x, mouse_y;
static float omouse_x, omouse_y;
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject obj,
jint act, jfloat x, jfloat y)
{
static float totalmoved;
static qboolean down;
float dx, dy;
dx = x - omouse_x;
dy = y - omouse_y;
omouse_x = x;
omouse_y = y;
mousecursor_x = x;
mousecursor_y = y;
if (down)
{
mouse_x += dx;
mouse_y += dy;
totalmoved += fabs(dx) + fabs(dy);
}
switch(act)
{
case 0: /*move*/
break;
case 1: /*down*/
totalmoved = 0;
down = true;
break;
case 2: /*up*/
down = false;
/*if it didn't move far, treat it as a regular click, if it did move a little then sorry if you just wanted a small turn!*/
if (totalmoved < 3)
{
Key_Event(0, K_MOUSE1, 0, 1);
Key_Event(0, K_MOUSE1, 0, 0);
}
break;
}
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_accelerometer(JNIEnv *env, jobject obj,
jfloat x, jfloat y, jfloat z)
{
// Con_Printf("Accelerometer: %f %f %f\n", x, y, z);
}
static int secbase;
double Sys_DoubleTime(void)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000000.0;
}
return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
}
unsigned int Sys_Milliseconds(void)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000;
}
return (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
}
void Sys_Shutdown(void)
{
free(sys_memheap);
}
void Sys_Quit(void)
{
#ifndef SERVERONLY
Host_Shutdown ();
#else
SV_Shutdown();
#endif
exit (0);
}
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, error);
vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
LOGW("%s", string);
exit(1);
}
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string,sizeof(string)-1, fmt,argptr);
va_end (argptr);
LOGI("%s", string);
}
void Sys_Warn (char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string,sizeof(string)-1, fmt,argptr);
va_end (argptr);
LOGW("%s", string);
}
void Sys_CloseLibrary(dllhandle_t *lib)
{
dlclose(lib);
}
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
dllhandle_t *h;
h = dlopen(name, RTLD_LAZY);
return h;
}
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
{
return dlsym(module, exportname);
}
void *Sys_GetGameAPI (void *parms)
{
return NULL;
}
void Sys_UnloadGame(void)
{
}
char *Sys_ConsoleInput (void)
{
return NULL;
}
void Sys_mkdir (char *path) //not all pre-unix systems have directories (including dos 1)
{
}
qboolean Sys_remove (char *path)
{
return false;
}
void Sys_Init(void)
{
}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{
*width = 320;
*height = 240;
*bpp = 16;
*refreshrate = 60;
return false;
}
qboolean Sys_RandomBytes(qbyte *string, int len)
{
qboolean res = false;
int fd = open("/dev/urandom", 0);
if (fd >= 0)
{
res = (read(fd, string, len) == len);
close(fd);
}
return res;
}
void Sys_ServerActivity(void)
{
/*FIXME: flash window*/
}
qboolean Sys_InitTerminal(void)
{
/*switching to dedicated mode, show text window*/
return false;
}
void Sys_CloseTerminal(void)
{
}
char *Sys_GetClipboard(void)
{
return NULL;
}
void Sys_CloseClipboard(char *buf)
{
}
void Sys_SaveClipboard(char *text)
{
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
DIR *dir;
char apath[MAX_OSPATH];
char file[MAX_OSPATH];
char truepath[MAX_OSPATH];
char *s;
struct dirent *ent;
struct stat st;
//printf("path = %s\n", gpath);
//printf("match = %s\n", match);
if (!gpath)
gpath = "";
*apath = '\0';
Q_strncpyz(apath, match, sizeof(apath));
for (s = apath+strlen(apath)-1; s >= apath; s--)
{
if (*s == '/')
{
s[1] = '\0';
match += s - apath+1;
break;
}
}
if (s < apath) //didn't find a '/'
*apath = '\0';
Q_snprintfz(truepath, sizeof(truepath), "%s/%s", gpath, apath);
//printf("truepath = %s\n", truepath);
//printf("gamepath = %s\n", gpath);
//printf("apppath = %s\n", apath);
//printf("match = %s\n", match);
dir = opendir(truepath);
if (!dir)
{
Con_DPrintf("Failed to open dir %s\n", truepath);
return true;
}
do
{
ent = readdir(dir);
if (!ent)
break;
if (*ent->d_name != '.')
{
if (wildcmp(match, ent->d_name))
{
Q_snprintfz(file, sizeof(file), "%s/%s", truepath, ent->d_name);
if (stat(file, &st) == 0)
{
Q_snprintfz(file, sizeof(file), "%s%s%s", apath, ent->d_name, S_ISDIR(st.st_mode)?"/":"");
if (!func(file, st.st_size, parm))
{
closedir(dir);
return false;
}
}
else
printf("Stat failed for \"%s\"\n", file);
}
}
} while(1);
closedir(dir);
return true;
}
/*
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
qboolean go = true;
const char *f;
struct AAssetDir *ad;
ad = AAssetManager_openDir(assetmgr, gpath);
while(go && (f = AAssetDir_getNextFileName(ad)))
{
if (wildcmp(match, f))
{
Sys_Printf("Found %s\n", f);
go = func(f, 0, parm);
}
}
AAssetDir_close(ad);
return 0;
}
typedef struct
{
vfsfile_t funcs;
AAsset *handle;
} assetfile_t;
static int AF_ReadBytes(vfsfile_t *h, void *buf, int len)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_read(f->handle, buf, len);
}
static qboolean AF_Seek(vfsfile_t *h, unsigned long offs)
{
assetfile_t *f = (assetfile_t*)h;
AAsset_seek(f->handle, offs, SEEK_SET);
return true;
}
static unsigned long AF_Tell(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_seek(f->handle, 0, SEEK_CUR);
}
static unsigned long AF_GetSize(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_getLength(f->handle);
}
static void AF_Close(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
AAsset_close(f->handle);
Z_Free(f);
}
static void AF_Flush(vfsfile_t *h)
{
}
vfsfile_t *Sys_OpenAsset(char *fname)
{
assetfile_t *file;
AAsset *a;
a = AAssetManager_open(assetmgr, fname, AASSET_MODE_UNKNOWN);
if (!a)
{
Sys_Printf("Unable to open asset %s\n", fname);
return NULL;
}
Sys_Printf("opened asset %s\n", fname);
file = Z_Malloc(sizeof(assetfile_t));
file->funcs.ReadBytes = AF_ReadBytes;
file->funcs.WriteBytes = NULL;
file->funcs.Seek = AF_Seek;
file->funcs.Tell = AF_Tell;
file->funcs.GetLen = AF_GetSize;
file->funcs.Close = AF_Close;
file->funcs.Flush = AF_Flush;
file->handle = a;
return (vfsfile_t*)file;
}
*/
#include <jni.h>
#include <errno.h>
#include <android/log.h>
#include "quakedef.h"
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/stat.h>
#include <dirent.h>
#ifndef isDedicated
#ifdef SERVERONLY
qboolean isDedicated = true;
#else
qboolean isDedicated = false;
#endif
#endif
void *sys_window; /*public so the renderer can attach to the correct place*/
static qboolean sys_running = false;
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DISTRIBUTION"Droid", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, DISTRIBUTION"Droid", __VA_ARGS__))
static void *sys_memheap;
static unsigned int sys_lastframe;
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject obj)
{
#ifdef SERVERONLY
SV_Frame();
#else
unsigned int now = Sys_Milliseconds();
double tdelta = (now - sys_lastframe) * 0.001;
Host_Frame(tdelta);
sys_lastframe = now;
#endif
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
jint width, jint height)
{
vid.pixelwidth = width;
vid.pixelheight = height;
if (!sys_running)
{
quakeparms_t parms;
parms.basedir = "/sdcard/fte";
parms.argc = 0;
parms.argv = NULL;
parms.memsize = sys_memheap = 8*1024*1024;
parms.membase = malloc(parms.memsize);
if (!parms.membase)
{
Sys_Printf("Unable to alloc heap\n");
return;
}
Sys_Printf("Starting up\n");
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();
#ifdef SERVERONLY
SV_Init(&parms);
#else
Host_Init(&parms);
#endif
sys_running = true;
sys_lastframe = Sys_Milliseconds();
}
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_keypress(JNIEnv *env, jobject obj,
jint down, jint keycode, jint unicode)
{
Key_Event(0, keycode, unicode, down);
}
int mousecursor_x, mousecursor_y;
float mouse_x, mouse_y;
static float omouse_x, omouse_y;
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject obj,
jint act, jfloat x, jfloat y)
{
static float totalmoved;
static qboolean down;
float dx, dy;
dx = x - omouse_x;
dy = y - omouse_y;
omouse_x = x;
omouse_y = y;
mousecursor_x = x;
mousecursor_y = y;
if (down)
{
mouse_x += dx;
mouse_y += dy;
totalmoved += fabs(dx) + fabs(dy);
}
switch(act)
{
case 0: /*move*/
break;
case 1: /*down*/
totalmoved = 0;
down = true;
break;
case 2: /*up*/
down = false;
/*if it didn't move far, treat it as a regular click, if it did move a little then sorry if you just wanted a small turn!*/
if (totalmoved < 3)
{
Key_Event(0, K_MOUSE1, 0, 1);
Key_Event(0, K_MOUSE1, 0, 0);
}
break;
}
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_accelerometer(JNIEnv *env, jobject obj,
jfloat x, jfloat y, jfloat z)
{
// Con_Printf("Accelerometer: %f %f %f\n", x, y, z);
}
static int secbase;
double Sys_DoubleTime(void)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000000.0;
}
return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
}
unsigned int Sys_Milliseconds(void)
{
struct timeval tp;
struct timezone tzp;
gettimeofday(&tp, &tzp);
if (!secbase)
{
secbase = tp.tv_sec;
return tp.tv_usec/1000;
}
return (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
}
void Sys_Shutdown(void)
{
free(sys_memheap);
}
void Sys_Quit(void)
{
#ifndef SERVERONLY
Host_Shutdown ();
#else
SV_Shutdown();
#endif
exit (0);
}
void Sys_Error (const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, error);
vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
LOGW("%s", string);
exit(1);
}
void Sys_Printf (char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string,sizeof(string)-1, fmt,argptr);
va_end (argptr);
LOGI("%s", string);
}
void Sys_Warn (char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string,sizeof(string)-1, fmt,argptr);
va_end (argptr);
LOGW("%s", string);
}
void Sys_CloseLibrary(dllhandle_t *lib)
{
dlclose(lib);
}
dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
{
dllhandle_t *h;
h = dlopen(name, RTLD_LAZY);
return h;
}
void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname)
{
return dlsym(module, exportname);
}
void *Sys_GetGameAPI (void *parms)
{
return NULL;
}
void Sys_UnloadGame(void)
{
}
char *Sys_ConsoleInput (void)
{
return NULL;
}
void Sys_mkdir (char *path) //not all pre-unix systems have directories (including dos 1)
{
mkdir(path, 0777);
}
qboolean Sys_remove (char *path)
{
return !unlink(path);
}
void Sys_Init(void)
{
}
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{
*width = 320;
*height = 240;
*bpp = 16;
*refreshrate = 60;
return false;
}
qboolean Sys_RandomBytes(qbyte *string, int len)
{
qboolean res = false;
int fd = open("/dev/urandom", 0);
if (fd >= 0)
{
res = (read(fd, string, len) == len);
close(fd);
}
return res;
}
void Sys_ServerActivity(void)
{
/*FIXME: flash window*/
}
qboolean Sys_InitTerminal(void)
{
/*switching to dedicated mode, show text window*/
return false;
}
void Sys_CloseTerminal(void)
{
}
char *Sys_GetClipboard(void)
{
return NULL;
}
void Sys_CloseClipboard(char *buf)
{
}
void Sys_SaveClipboard(char *text)
{
}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
DIR *dir;
char apath[MAX_OSPATH];
char file[MAX_OSPATH];
char truepath[MAX_OSPATH];
char *s;
struct dirent *ent;
struct stat st;
//printf("path = %s\n", gpath);
//printf("match = %s\n", match);
if (!gpath)
gpath = "";
*apath = '\0';
Q_strncpyz(apath, match, sizeof(apath));
for (s = apath+strlen(apath)-1; s >= apath; s--)
{
if (*s == '/')
{
s[1] = '\0';
match += s - apath+1;
break;
}
}
if (s < apath) //didn't find a '/'
*apath = '\0';
Q_snprintfz(truepath, sizeof(truepath), "%s/%s", gpath, apath);
//printf("truepath = %s\n", truepath);
//printf("gamepath = %s\n", gpath);
//printf("apppath = %s\n", apath);
//printf("match = %s\n", match);
dir = opendir(truepath);
if (!dir)
{
Con_DPrintf("Failed to open dir %s\n", truepath);
return true;
}
do
{
ent = readdir(dir);
if (!ent)
break;
if (*ent->d_name != '.')
{
if (wildcmp(match, ent->d_name))
{
Q_snprintfz(file, sizeof(file), "%s/%s", truepath, ent->d_name);
if (stat(file, &st) == 0)
{
Q_snprintfz(file, sizeof(file), "%s%s%s", apath, ent->d_name, S_ISDIR(st.st_mode)?"/":"");
if (!func(file, st.st_size, parm))
{
closedir(dir);
return false;
}
}
else
printf("Stat failed for \"%s\"\n", file);
}
}
} while(1);
closedir(dir);
return true;
}
/*
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
qboolean go = true;
const char *f;
struct AAssetDir *ad;
ad = AAssetManager_openDir(assetmgr, gpath);
while(go && (f = AAssetDir_getNextFileName(ad)))
{
if (wildcmp(match, f))
{
Sys_Printf("Found %s\n", f);
go = func(f, 0, parm);
}
}
AAssetDir_close(ad);
return 0;
}
typedef struct
{
vfsfile_t funcs;
AAsset *handle;
} assetfile_t;
static int AF_ReadBytes(vfsfile_t *h, void *buf, int len)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_read(f->handle, buf, len);
}
static qboolean AF_Seek(vfsfile_t *h, unsigned long offs)
{
assetfile_t *f = (assetfile_t*)h;
AAsset_seek(f->handle, offs, SEEK_SET);
return true;
}
static unsigned long AF_Tell(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_seek(f->handle, 0, SEEK_CUR);
}
static unsigned long AF_GetSize(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
return AAsset_getLength(f->handle);
}
static void AF_Close(vfsfile_t *h)
{
assetfile_t *f = (assetfile_t*)h;
AAsset_close(f->handle);
Z_Free(f);
}
static void AF_Flush(vfsfile_t *h)
{
}
vfsfile_t *Sys_OpenAsset(char *fname)
{
assetfile_t *file;
AAsset *a;
a = AAssetManager_open(assetmgr, fname, AASSET_MODE_UNKNOWN);
if (!a)
{
Sys_Printf("Unable to open asset %s\n", fname);
return NULL;
}
Sys_Printf("opened asset %s\n", fname);
file = Z_Malloc(sizeof(assetfile_t));
file->funcs.ReadBytes = AF_ReadBytes;
file->funcs.WriteBytes = NULL;
file->funcs.Seek = AF_Seek;
file->funcs.Tell = AF_Tell;
file->funcs.GetLen = AF_GetSize;
file->funcs.Close = AF_Close;
file->funcs.Flush = AF_Flush;
file->handle = a;
return (vfsfile_t*)file;
}
*/

View file

@ -527,6 +527,20 @@ void V_BonusFlash_f (void)
cl.cshifts[CSHIFT_BONUS].percent = 50*v_bonusflash.value;
}
}
void V_DarkFlash_f (void)
{
cl.cshifts[CSHIFT_BONUS].destcolor[0] = 0;
cl.cshifts[CSHIFT_BONUS].destcolor[1] = 0;
cl.cshifts[CSHIFT_BONUS].destcolor[2] = 0;
cl.cshifts[CSHIFT_BONUS].percent = 255;
}
void V_WhiteFlash_f (void)
{
cl.cshifts[CSHIFT_BONUS].destcolor[0] = 255;
cl.cshifts[CSHIFT_BONUS].destcolor[1] = 255;
cl.cshifts[CSHIFT_BONUS].destcolor[2] = 255;
cl.cshifts[CSHIFT_BONUS].percent = 255;
}
/*
=============
@ -693,7 +707,7 @@ void V_UpdatePalette (qboolean force)
float newhw_blend[4];
int ir, ig, ib;
float ftime;
static float oldtime;
static double oldtime;
RSpeedMark();
ftime = cl.time - oldtime;
@ -1269,8 +1283,8 @@ void R_DrawNameTags(void)
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
void GL_Set2D (void);
GL_Set2D();
// void GL_Set2D (void);
// GL_Set2D(false);
}
#endif
@ -1468,18 +1482,8 @@ void V_RenderView (void)
CL_TransitionEntities();
//work out which packet entities are solid
CL_SetSolidEntities ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(false);
// do client side motion prediction
CL_PredictMove ();
// Set up prediction for other players
CL_SetUpPlayerPrediction(true);
// build a refresh entity list
CL_EmitEntities ();
@ -1514,6 +1518,8 @@ void V_Init (void)
#endif
Cmd_AddCommand ("v_cshift", V_cshift_f);
Cmd_AddCommand ("bf", V_BonusFlash_f);
Cmd_AddCommand ("df", V_DarkFlash_f);
Cmd_AddCommand ("wf", V_WhiteFlash_f);
// Cmd_AddCommand ("centerview", V_StartPitchDrift);
Cvar_Register (&v_centermove, VIEWVARS);