forked from fte/fteqw
1
0
Fork 0

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

@ -55,12 +55,25 @@ endif
DROID_NDK_PATH?=~/droid/android-ndk-r6b
DROID_SDK_PATH?=~/droid/android-sdk-linux_x86
ANT?=ant
JAVATOOL="$(JAVA_HOME)"/bin/
ifeq ($(FTE_TARGET),droid)
#if we're running under windows, then we want to run some other binary
ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
#set up for linux
NDK_PATH:=$(shell echo $(DROID_NDK_PATH))
SDK_PATH:=$(shell echo $(DROID_SDK_PATH))
TOOLCHAIN:=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-
else
#we're running upon windows
NDK_PATH:=$(shell cygpath -m $(DROID_NDK_PATH))
SDK_PATH:=$(shell cygpath -m $(DROID_SDK_PATH))
TOOLCHAIN:=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-
#make can't cope with absolute paths in dependancy files
NODEPS = 1
endif
NDK_PATH:=$(shell echo $(DROID_NDK_PATH))
SDK_PATH:=$(shell echo $(DROID_SDK_PATH))
DROID_API_LEVEL=3
DROID_API_LEVEL=4
#there are 3 ABI targets
#armv5 (works on all arm droids)
@ -68,8 +81,8 @@ ifeq ($(FTE_TARGET),droid)
#armv7+neon
DROID_ABI?=-mfloat-abi=softfp
STRIP=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-strip
CC=$(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc -I$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm/usr/include/ -DANDROID $(DROID_ABI)
STRIP=$(TOOLCHAIN)strip
CC=$(TOOLCHAIN)gcc -I$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm/usr/include/ -DANDROID $(DROID_ABI)
DO_LD=$(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack --sysroot=$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm -L$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/arch-arm/usr/lib -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) -llog -lc -lz -lm
endif
@ -1166,7 +1179,8 @@ distclean: clean
#makes an ant project for us
droid/build.xml:
cd droid && PATH=$$PATH:$(DROID_SDK_PATH)/tools:$(DROID_NDK_PATH) android update project -t 1 -p . -n FTEDroid
-cd droid && PATH=$$PATH:$(DROID_SDK_PATH)/tools:$(DROID_NDK_PATH) android update project -t 1 -p . -n FTEDroid
-cd droid && PATH=$$PATH:$(DROID_SDK_PATH)/tools:$(DROID_NDK_PATH) android.bat update project -t 1 -p . -n FTEDroid
#build FTE as a library, then build the java+package (release)
droid/ftekeystore:
@ -1180,26 +1194,26 @@ droid/ftekeystore:
@echo Just press control-c if you don\'t want to proceed.
@echo Morality warning: never distribute droid/ftekeystore - always do make distclean before distributing.
@echo
keytool -genkey -v -keystore $@ -alias autogen -keyalg RSA -keysize 2048 -validity 10000
$(JAVATOOL)keytool -genkey -v -keystore $@ -alias autogen -keyalg RSA -keysize 2048 -validity 10000
droid-rel: droid/build.xml droid/ftekeystore
$(MAKE) FTE_TARGET=droid gl-rel
mkdir -p droid/libs/armeabi
@cp $(RELEASE_DIR)/libftedroid.so droid/libs/armeabi/
@cd droid && ant release
@cd droid && $(ANT) release
@echo
@echo
@echo Signing package... I hope you remember your password.
@echo
jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore droid/ftekeystore droid/bin/FTEDroid-unsigned.apk autogen
$(JAVATOOL)jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore droid/ftekeystore droid/bin/FTEDroid-release-unsigned.apk autogen
-rm -f $(RELEASE_DIR)/FTEDroid.apk
$(DROID_SDK_PATH)/tools/zipalign 4 droid/bin/FTEDroid-unsigned.apk $(RELEASE_DIR)/FTEDroid.apk
$(DROID_SDK_PATH)/tools/zipalign 4 droid/bin/FTEDroid-release-unsigned.apk $(RELEASE_DIR)/FTEDroid.apk
droid-opt: droid/build.xml droid/ftekeystore
$(MAKE) FTE_TARGET=droid gl-rel
mkdir -p droid/libs/armeabi
@cp $(RELEASE_DIR)/libftedroid.so droid/libs/armeabi/
@cd droid && ant release
@cd droid && $(ANT) release
cp droid/bin/FTEDroid-unsigned.apk $(RELEASE_DIR)/FTEDroid.apk
#build FTE as a library, then build the java+package (release). also installs it onto the 'current' device.
@ -1207,6 +1221,6 @@ droid-dbg: droid/build.xml
$(MAKE) FTE_TARGET=droid gl-dbg
@mkdir -p droid/libs/armeabi
@cp $(DEBUG_DIR)/libftedroid.so droid/libs/armeabi/
@cd droid && ant debug install
@cd droid && $(ANT) debug && $(ANT) debug install
cp droid/bin/FTEDroid-debug.apk $(DEBUG_DIR)/FTEDroid.apk

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);

View File

@ -152,16 +152,6 @@ typedef struct
#define Q1CONTENTS_LAVA -5
#define Q1CONTENTS_SKY -6
#define FTECONTENTS_EMPTY 0
#define FTECONTENTS_SOLID 1
#define FTECONTENTS_WATER 2
#define FTECONTENTS_SLIME 4
#define FTECONTENTS_LAVA 8
#define FTECONTENTS_SKY 16
#define FTECONTENTS_LADDER 32
#define FTECONTENTS_FLUID (FTECONTENTS_WATER|FTECONTENTS_SLIME|FTECONTENTS_LAVA|FTECONTENTS_SKY) //sky is a fluid for q1 code.
#define FTECONTENTS_PLAYERCLIP 64
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
{
@ -507,15 +497,27 @@ typedef struct
// these definitions also need to be in q_shared.h!
#define FTECONTENTS_EMPTY 0
#define FTECONTENTS_SOLID 1
//2
//4
#define FTECONTENTS_LAVA 8
#define FTECONTENTS_SLIME 16
#define FTECONTENTS_WATER 32
//#define FTECONTENTS_LADDER 32
#define FTECONTENTS_FLUID (FTECONTENTS_WATER|FTECONTENTS_SLIME|FTECONTENTS_LAVA|FTECONTENTS_SKY) //sky is a fluid for q1 code.
#define FTECONTENTS_PLAYERCLIP 0x00010000
#define FTECONTENTS_BODY 0x02000000
#define FTECONTENTS_SKY 0x80000000
// lower bits are stronger, and will eat weaker brushes completely
#define Q2CONTENTS_SOLID 1 // an eye is never valid in a solid
#define Q2CONTENTS_SOLID FTECONTENTS_SOLID //1
#define Q2CONTENTS_WINDOW 2 // translucent, but not watery
#define Q2CONTENTS_AUX 4
#define Q2CONTENTS_LAVA 8
#define Q2CONTENTS_SLIME 16
#define Q2CONTENTS_WATER 32
#define Q2CONTENTS_LAVA FTECONTENTS_LAVA //8
#define Q2CONTENTS_SLIME FTECONTENTS_SLIME //16
#define Q2CONTENTS_WATER FTECONTENTS_WATER //32
#define Q2CONTENTS_MIST 64
#define Q2LAST_VISIBLE_CONTENTS 64
// remaining contents are non-visible, and don't eat brushes
@ -534,15 +536,45 @@ typedef struct
#define Q2CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
#define Q2CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game
#define Q2CONTENTS_MONSTER FTECONTENTS_BODY //0x2000000 // should never be on a brush, only in game
#define Q2CONTENTS_DEADMONSTER 0x4000000
#define Q2CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
#define Q2CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define Q2CONTENTS_LADDER 0x20000000
#define Q3CONTENTS_SOLID Q2CONTENTS_SOLID // should never be on a brush, only in game
#define Q3CONTENTS_BODY 0x2000000 // should never be on a brush, only in game
#define Q3CONTENTS_TRANSLUCENT 0x20000000
#define Q3CONTENTS_SOLID FTECONTENTS_SOLID //1 // should never be on a brush, only in game
//2
//4
#define Q3CONTENTS_LAVA FTECONTENTS_LAVA //8
#define Q3CONTENTS_SLIME FTECONTENTS_SLIME //16
#define Q3CONTENTS_WATER FTECONTENTS_WATER //32
//64
#define Q3CONTENTS_NOTTEAM1 0x00000080
#define Q3CONTENTS_NOTTEAM2 0x00000100
#define Q3CONTENTS_NOBOTCLIP 0x00000200
//0x00000400
//0x00000800
//0x00001000
//0x00002000
//0x00004000
#define Q3CONTENTS_AREAPORTAL 0x00008000
#define Q3CONTENTS_PLAYERCLIP Q2CONTENTS_PLAYERCLIP //0x00010000
#define Q3CONTENTS_MONSTERCLIP Q2CONTENTS_MONSTERCLIP //0x00020000
#define Q3CONTENTS_TELEPORTER 0x00040000
#define Q3CONTENTS_JUMPPAD 0x00080000
#define Q3CONTENTS_CLUSTERPORTAL 0x00100000
#define Q3CONTENTS_DONOTENTER 0x00200000
#define Q3CONTENTS_BOTCLIP 0x00400000
#define Q3CONTENTS_MOVER 0x00800000
#define Q3CONTENTS_ORIGIN Q2CONTENTS_ORIGIN //0x01000000
#define Q3CONTENTS_BODY 0x02000000
#define Q3CONTENTS_CORPSE Q2CONTENTS_DEADMONSTER //0x04000000
#define Q3CONTENTS_DETAIL Q2CONTENTS_DETAIL //0x08000000
#define Q3CONTENTS_STRUCTURAL 0x10000000
#define Q3CONTENTS_TRANSLUCENT 0x20000000
#define Q3CONTENTS_TRIGGER 0x40000000
#define Q3CONTENTS_NODROP FTECONTENTS_SKY //0x80000000
//Texinfo flags - warning: these mix with q3 surface flags
@ -562,16 +594,18 @@ typedef struct
//Surface flags
#define Q3SURF_LADDER 0x8 //wee
// content masks
#define MASK_ALL (-1)
#define MASK_SOLID (Q2CONTENTS_SOLID|Q2CONTENTS_WINDOW)
#define MASK_PLAYERSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW|Q2CONTENTS_MONSTER)
#define MASK_DEADSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW)
#define MASK_MONSTERSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_MONSTERCLIP|Q2CONTENTS_WINDOW|Q2CONTENTS_MONSTER)
#define MASK_WATER (Q2CONTENTS_WATER|Q2CONTENTS_LAVA|Q2CONTENTS_SLIME)
#define MASK_OPAQUE (Q2CONTENTS_SOLID|Q2CONTENTS_SLIME|Q2CONTENTS_LAVA)
#define MASK_SHOT (Q2CONTENTS_SOLID|Q2CONTENTS_MONSTER|Q2CONTENTS_WINDOW|Q2CONTENTS_DEADMONSTER)
#define MASK_CURRENT (Q2CONTENTS_CURRENT_0|Q2CONTENTS_CURRENT_90|Q2CONTENTS_CURRENT_180|Q2CONTENTS_CURRENT_270|Q2CONTENTS_CURRENT_UP|Q2CONTENTS_CURRENT_DOWN)
// content masks. Allow q2contents_window in here
//#define MASK_ALL (-1)
#define MASK_WORLDSOLID (FTECONTENTS_SOLID|Q2CONTENTS_WINDOW) /*default trace type for something simple that ignores non-bsp stuff*/
#define MASK_POINTSOLID (FTECONTENTS_SOLID|Q2CONTENTS_WINDOW|FTECONTENTS_BODY) /*default trace type for an entity of no size*/
#define MASK_BOXSOLID (FTECONTENTS_SOLID|FTECONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW|FTECONTENTS_BODY) /*default trace type for an entity that does have size*/
#define MASK_PLAYERSOLID MASK_BOXSOLID
//#define MASK_DEADSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_PLAYERCLIP|Q2CONTENTS_WINDOW)
//#define MASK_MONSTERSOLID (Q2CONTENTS_SOLID|Q2CONTENTS_MONSTERCLIP|Q2CONTENTS_WINDOW|Q2CONTENTS_MONSTER)
#define MASK_WATER (FTECONTENTS_WATER|FTECONTENTS_LAVA|FTECONTENTS_SLIME)
//#define MASK_OPAQUE (Q2CONTENTS_SOLID|Q2CONTENTS_SLIME|Q2CONTENTS_LAVA)
//#define MASK_SHOT (Q2CONTENTS_SOLID|Q2CONTENTS_MONSTER|Q2CONTENTS_WINDOW|Q2CONTENTS_DEADMONSTER)
#define Q2MASK_CURRENT (Q2CONTENTS_CURRENT_0|Q2CONTENTS_CURRENT_90|Q2CONTENTS_CURRENT_180|Q2CONTENTS_CURRENT_270|Q2CONTENTS_CURRENT_UP|Q2CONTENTS_CURRENT_DOWN)

View File

@ -2121,6 +2121,19 @@ const char *retstring(const char *s)
strcpy(ret->str, s);
return ret->str;
}
const char *retint(int f)
{
char s[1024];
tempstack_t *ret;
if (!f)
return "";
sprintf(s, "%d", f);
ret = (tempstack_t*)Z_Malloc(sizeof(tempstack_t)+strlen(s));
ret->next = ifstack;
ifstack=ret;
strcpy(ret->str, s);
return ret->str;
}
const char *retfloat(float f)
{
char s[1024];
@ -2185,7 +2198,7 @@ const char *If_Token(const char *func, const char **end)
else if (!strcmp(com_token, "int"))
{
func = If_Token(s, end);
return retfloat(atof(func));
return retint(atoi(func));
}
else if (!strcmp(com_token, "strlen"))
{
@ -2627,7 +2640,7 @@ void Cmd_set_f(void)
return;
text = Cmd_Argv(2);
}
else if (dpcompat_set.ival)
else if (dpcompat_set.ival && !docalc)
{
text = Cmd_Argv(2);
/*desc = Cmd_Argv(3)*/

View File

@ -1662,7 +1662,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
//The whole reason why model loading is supported in the server.
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentsmask, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
galiasgroup_t *group;
@ -2765,6 +2765,8 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
#endif
galias->nextsurf = 0;
loadmodel->numframes = pq1inmodel->numframes;
//skins
skinstart = (daliasskintype_t *)((char*)pq1inmodel+hdrsize);
@ -2977,7 +2979,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -3317,7 +3319,7 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -4108,7 +4110,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -4438,7 +4440,7 @@ qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -5124,7 +5126,7 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -5479,7 +5481,7 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -6609,7 +6611,7 @@ qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}
@ -6816,7 +6818,7 @@ qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer)
Hunk_FreeToLowMark (hunkstart);
mod->funcs.Trace = Mod_Trace;
mod->funcs.NativeTrace = Mod_Trace;
return true;
}

View File

@ -231,6 +231,8 @@ void COM_Path_f (void)
Con_Printf ("Pure paths:\n");
for (s=com_purepaths ; s ; s=s->nextpure)
{
if (s->referenced)
Con_Printf("*");
s->funcs->PrintPath(s->handle);
}
Con_Printf ("----------\n");
@ -243,6 +245,8 @@ void COM_Path_f (void)
if (s == com_base_searchpaths)
Con_Printf ("----------\n");
if (s->referenced)
Con_Printf("*");
s->funcs->PrintPath(s->handle);
}
}
@ -529,9 +533,9 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
{
if (search->funcs->FindFile(search->handle, loc, filename, pf))
{
search->referenced |= fs_referencetype;
if (loc)
{
search->referenced |= fs_referencetype;
loc->search = search;
len = loc->len;
}
@ -670,7 +674,7 @@ char *FS_GetPackNames(char *buffer, int buffersize, int referencedonly, qboolean
if (referencedonly == 0 && !search->referenced)
continue;
if (referencedonly == 2 && search->referenced)
Q_strncatz(buffer, "*", sizeof(buffer));
Q_strncatz(buffer, "*", buffersize);
if (!ext)
{
@ -1339,6 +1343,8 @@ static int FS_AddWildDataFiles (const char *descriptor, int size, void *vparam)
if (!search->funcs->FindFile(search->handle, &loc, descriptor, NULL))
return true; //not found..
vfs = search->funcs->OpenVFS(search->handle, &loc, "rb");
if (!vfs)
return true;
pak = funcs->OpenNew (vfs, pakfile);
if (!pak)
return true;
@ -1727,7 +1733,7 @@ void COM_Gamedir (const char *dir)
/*some modern non-compat settings*/
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n"
/*set some stuff so our regular qw client appears more like hexen2*/
#define HEX2CFG "set r_particlesdesc \"spikeset tsshaft h2part\"\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
#define HEX2CFG "set_calc cl_playerclass int (random * 5) + 1\nset r_particlesdesc \"spikeset tsshaft h2part\"\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "gl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\n"
@ -1771,6 +1777,8 @@ const gamemode_info_t gamemode_info[] = {
{"FTE-JK2", "jk2", "-jk2", {"base/assets0.pk3"}, NULL, {"base", "fte"}, "Jedi Knight II: Jedi Outcast"},
{"FTE-HalfLife", "hl", "-halflife", {"valve/liblist.gam"}, NULL, {"valve", "ftehl"}, "Half-Life"},
{"FTE-Doom", "doom", "-doom", {"doom.wad"}, NULL, { "ftedoom"}, "Doom"},
{"FTE-Doom2", "doom2", "-doom2", {"doom2.wad"}, NULL, { "ftedoom"}, "Doom2"},
{NULL}
};
@ -2013,6 +2021,24 @@ char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum)
return buffer;
}
#ifdef DOOMWADS
void FS_AddRootWads(void)
{
vfsfile_t *vfs;
char *fname = "doom.wad";
void *pak;
extern searchpathfuncs_t doomwadfilefuncs;
vfs = FS_OpenVFS(fname, "rb", FS_ROOT);
pak = doomwadfilefuncs.OpenNew(vfs, fname);
if (!pak)
return;
FS_AddPathHandle(fname, fname, &doomwadfilefuncs, pak, true, false, false, (unsigned int)-1);
}
#endif
/*
================
FS_ReloadPackFiles
@ -2056,6 +2082,10 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
com_base_searchpaths = NULL;
#ifdef DOOMWADS
FS_AddRootWads();
#endif
while(oldpaths)
{
next = oldpaths->nextpure;
@ -2369,6 +2399,10 @@ void FS_StartupWithGame(int gamenum)
Cvar_Set(&com_protocolname, gamemode_info[gamenum].protocolname);
Cvar_ForceSet(&fs_gamename, gamemode_info[gamenum].poshname);
#ifdef DOOMWADS
FS_AddRootWads();
#endif
//
// start up with id1 by default
//

View File

@ -389,7 +389,7 @@ searchpathfuncs_t packfilefuncs = {
#ifdef DOOMWADS
void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, char *desc)
void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, const char *desc)
{
dwadheader_t header;
int i;

View File

@ -57,6 +57,7 @@ static int VFSW32_WriteBytes (struct vfsfile_s *file, const void *buffer, int by
}
static qboolean VFSW32_Seek (struct vfsfile_s *file, unsigned long pos)
{
unsigned long upper, lower;
vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap)
{
@ -64,7 +65,10 @@ static qboolean VFSW32_Seek (struct vfsfile_s *file, unsigned long pos)
return true;
}
return SetFilePointer(intfile->hand, pos, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
lower = (pos & 0xffffffff);
upper = ((pos>>16)>>16);
return SetFilePointer(intfile->hand, lower, &upper, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
}
static unsigned long VFSW32_Tell (struct vfsfile_s *file)
{

View File

@ -468,18 +468,31 @@ typedef struct {
int index;
int startpos;
} vfszip_t;
void VFSZIP_MakeActive(vfszip_t *vfsz)
qboolean VFSZIP_MakeActive(vfszip_t *vfsz)
{
int i;
char buffer[8192]; //must be power of two
if ((vfszip_t*)vfsz->parent->currentfile == vfsz)
return; //already us
return true; //already us
if (vfsz->parent->currentfile)
unzCloseCurrentFile(vfsz->parent->handle);
unzLocateFileMy(vfsz->parent->handle, vfsz->index, vfsz->startpos);
unzOpenCurrentFile(vfsz->parent->handle);
if (unzOpenCurrentFile(vfsz->parent->handle) == UNZ_BADZIPFILE)
{
unz_file_info file_info;
buffer[0] = '?';
buffer[1] = 0;
if (unzGetCurrentFileInfo (vfsz->parent->handle, &file_info, buffer, sizeof(buffer), NULL, 0, NULL, 0) != UNZ_OK)
Con_Printf("Zip Error\n");
if (file_info.compression_method && file_info.compression_method != Z_DEFLATED)
Con_Printf("unsupported compression method on %s/%s\n", vfsz->parent->filename, buffer);
else
Con_Printf("corrupt file within zip, %s/%s\n", vfsz->parent->filename, buffer);
vfsz->parent->currentfile = NULL;
return false;
}
if (vfsz->pos > 0)
@ -493,6 +506,7 @@ void VFSZIP_MakeActive(vfszip_t *vfsz)
}
vfsz->parent->currentfile = (vfsfile_t*)vfsz;
return true;
}
int VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
@ -505,7 +519,8 @@ int VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
if (vfsz->iscompressed)
{
VFSZIP_MakeActive(vfsz);
if (!VFSZIP_MakeActive(vfsz))
return 0;
read = unzReadCurrentFile(vfsz->parent->handle, buffer, bytestoread);
}
else
@ -535,37 +550,44 @@ qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos)
return VFS_SEEK(vfsz->defer, pos);
//This is *really* inefficient
if (vfsz->parent->currentfile == file)
{
if (vfsz->iscompressed)
{ //if they're going to seek on a file in a zip, let's just copy it out
char buffer[8192];
unsigned int chunk;
unsigned int i;
unsigned int length;
if (vfsz->iscompressed)
{ //if they're going to seek on a file in a zip, let's just copy it out
char buffer[8192];
unsigned int chunk;
unsigned int i;
unsigned int length;
vfsz->defer = FS_OpenTemp();
if (vfsz->defer)
vfsz->defer = FS_OpenTemp();
if (vfsz->defer)
{
if (vfsz->pos)
{
unzCloseCurrentFile(vfsz->parent->handle);
vfsz->parent->currentfile = NULL; //make it not us
}
length = vfsz->length;
i = 0;
vfsz->pos = 0;
VFSZIP_MakeActive(vfsz);
while (1)
{
chunk = length - i;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
if (chunk == 0)
break;
unzReadCurrentFile(vfsz->parent->handle, buffer, chunk);
VFS_WRITE(vfsz->defer, buffer, chunk);
length = vfsz->length;
i = 0;
vfsz->pos = 0;
if (!VFSZIP_MakeActive(vfsz))
{
/*shouldn't really happen*/
VFS_CLOSE(vfsz->defer);
vfsz->defer = NULL;
return false;
}
i += chunk;
}
while (1)
{
chunk = length - i;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
if (chunk == 0)
break;
unzReadCurrentFile(vfsz->parent->handle, buffer, chunk);
VFS_WRITE(vfsz->defer, buffer, chunk);
i += chunk;
}
}
@ -574,10 +596,13 @@ qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos)
if (vfsz->defer)
return VFS_SEEK(vfsz->defer, pos);
else
{
unzCloseCurrentFile(vfsz->parent->handle);
vfsz->parent->currentfile = NULL; //make it not us, so the next read starts at the right place
}
}
if (pos < 0 || pos > vfsz->length)
return false;
vfsz->pos = pos;
@ -653,6 +678,15 @@ vfsfile_t *FSZIP_OpenVFS(void *handle, flocation_t *loc, const char *mode)
Z_Free(vfsz);
return NULL;
}
else if (!VFSZIP_MakeActive(vfsz)) /*this is called purely as a test*/
{
/*
windows explorer tends to use deflate64 on large files, which zlib and thus we, do not support, thus this is a 'common' failure path
this might also trigger from other errors, of course.
*/
Z_Free(vfsz);
return NULL;
}
zip->references++;

View File

@ -3748,7 +3748,6 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
#endif
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
loadmodel->funcs.NativeTrace = CM_NativeTrace;
loadmodel->funcs.NativeContents = CM_NativeContents;
@ -3845,7 +3844,6 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.MarkLights = NULL;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
loadmodel->funcs.NativeTrace = CM_NativeTrace;
loadmodel->funcs.NativeContents = CM_NativeContents;
@ -3896,7 +3894,6 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
loadmodel->funcs.Trace = CM_Trace;
loadmodel->funcs.PointContents = Q2BSP_PointContents;
loadmodel->funcs.NativeTrace = CM_NativeTrace;
loadmodel->funcs.NativeContents = CM_NativeContents;
@ -4079,7 +4076,6 @@ void CM_InitBoxHull (void)
#endif
box_model.funcs.LeafPVS = CM_LeafnumPVS;
box_model.funcs.LeafnumForPoint = CM_PointLeafnum;
box_model.funcs.Trace = CM_Trace;
box_model.funcs.NativeContents = CM_NativeContents;
box_model.funcs.NativeTrace = CM_NativeTrace;
@ -5180,14 +5176,6 @@ trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
return trace_trace;
}
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
if (maxs[0] - mins[0])
*trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_PLAYERSOLID);
else
*trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_SOLID);
return trace->fraction != 1;
}
qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace)
{
*trace = CM_BoxTrace(model, start, end, mins, maxs, contents);
@ -5707,18 +5695,7 @@ unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p)
{
int pc, ret = FTECONTENTS_EMPTY;
pc = CM_PointContents (mod, p);
if (pc & (Q2CONTENTS_SOLID|Q2CONTENTS_WINDOW))
ret |= FTECONTENTS_SOLID;
if (pc & Q2CONTENTS_LAVA)
ret |= FTECONTENTS_LAVA;
if (pc & Q2CONTENTS_SLIME)
ret |= FTECONTENTS_SLIME;
if (pc & Q2CONTENTS_WATER)
ret |= FTECONTENTS_WATER;
if (pc & Q2CONTENTS_LADDER)
ret |= FTECONTENTS_LADDER;
return ret;
return pc;
}

View File

@ -83,7 +83,7 @@ void NET_SendPacket (netsrc_t socket, int length, void *data, netadr_t to);
int NET_LocalAddressForRemote(struct ftenet_connections_s *collection, netadr_t *remote, netadr_t *local, int idx);
void NET_PrintAddresses(struct ftenet_connections_s *collection);
qboolean NET_AddressSmellsFunny(netadr_t a);
void NET_EnsureRoute(struct ftenet_connections_s *collection, char *routename, char *host, qboolean islisten);
qboolean NET_EnsureRoute(struct ftenet_connections_s *collection, char *routename, char *host, qboolean islisten);
qboolean NET_CompareAdr (netadr_t a, netadr_t b);
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b);

View File

@ -255,7 +255,7 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
if (a.type == NA_LOOPBACK)
return true;
if (a.type == NA_IP)
if (a.type == NA_IP || a.type == NA_TCP)
{
if ((memcmp(a.address.ip, b.address.ip, sizeof(a.address.ip)) == 0))
return true;
@ -507,6 +507,13 @@ char *NET_BaseAdrToString (char *s, int len, netadr_t a)
a.address.ip[2],
a.address.ip[3]);
break;
case NA_TCP:
snprintf (s, len, "tcp://%i.%i.%i.%i",
a.address.ip[0],
a.address.ip[1],
a.address.ip[2],
a.address.ip[3]);
break;
#ifdef IPPROTO_IPV6
case NA_BROADCAST_IP6:
case NA_IPV6:
@ -2081,6 +2088,7 @@ closesvstream:
if (con->generic.thesocket != INVALID_SOCKET && con->active < 256)
{
int newsock;
fromlen = sizeof(from);
newsock = accept(con->generic.thesocket, (struct sockaddr*)&from, &fromlen);
if (newsock != INVALID_SOCKET)
{
@ -2126,6 +2134,7 @@ qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
if (NET_CompareAdr(to, st->remoteaddr))
{
unsigned short slen = BigShort((unsigned short)length);
#pragma warningmsg("TCPConnect: these calls can fail, corrupting the message stream")
send(st->socketnum, (char*)&slen, sizeof(slen), 0);
send(st->socketnum, data, length, 0);
@ -2168,11 +2177,15 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
netadr_t adr;
struct sockaddr_qstorage qs;
int family;
if (!strncmp(address, "tcp://", 6))
address += 6;
if (isserver)
{
if (!NET_PortToAdr(affamily, address, &adr))
return NULL; //couldn't resolve the name
if (adr.type == NA_IP)
adr.type = NA_TCP;
temp = NetadrToSockadr(&adr, &qs);
family = ((struct sockaddr_in*)&qs)->sin_family;
@ -2200,6 +2213,9 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
{
if (!NET_PortToAdr(affamily, address, &adr))
return NULL; //couldn't resolve the name
if (adr.type == NA_IP)
adr.type = NA_TCP;
newsocket = TCP_OpenStream(adr);
if (newsocket == INVALID_SOCKET)
return NULL;
@ -2218,7 +2234,7 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
newcon->generic.SendPacket = FTENET_TCPConnect_SendPacket;
newcon->generic.Close = FTENET_TCPConnect_Close;
newcon->generic.islisten = true;
newcon->generic.islisten = isserver;
newcon->generic.addrtype[0] = adr.type;
newcon->generic.addrtype[1] = NA_INVALID;
@ -2947,7 +2963,7 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
Con_Printf("No route - open some ports\n");
}
void NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char *host, qboolean islisten)
qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char *host, qboolean islisten)
{
netadr_t adr;
NET_StringToAdr(host, &adr);
@ -2956,23 +2972,27 @@ void NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char *ho
{
#ifdef TCPCONNECT
case NA_TCP:
FTENET_AddToCollection(collection, routename, host, FTENET_TCP4Connect_EstablishConnection, islisten);
if (!FTENET_AddToCollection(collection, routename, host, FTENET_TCP4Connect_EstablishConnection, islisten))
return false;
break;
#ifdef IPPROTO_IPV6
case NA_TCPV6:
FTENET_AddToCollection(collection, routename, host, FTENET_TCP6Connect_EstablishConnection, islisten);
if (!FTENET_AddToCollection(collection, routename, host, FTENET_TCP6Connect_EstablishConnection, islisten))
return false;
break;
#endif
#endif
#ifdef IRCCONNECT
case NA_IRC:
FTENET_AddToCollection(collection, routename, host, FTENET_IRCConnect_EstablishConnection, islisten);
if (!FTENET_AddToCollection(collection, routename, host, FTENET_IRCConnect_EstablishConnection, islisten))
return false;
break;
#endif
default:
//not recognised, or not needed
break;
}
return true;
}
void NET_PrintAddresses(ftenet_connections_t *collection)
@ -3009,12 +3029,17 @@ int TCP_OpenStream (netadr_t remoteaddr)
int newsocket;
int temp;
struct sockaddr_qstorage qs;
struct sockaddr_qstorage loc;
temp = NetadrToSockadr(&remoteaddr, &qs);
if ((newsocket = socket (((struct sockaddr_in*)&qs)->sin_family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
return INVALID_SOCKET;
// memset(&loc, 0, sizeof(loc));
// ((struct sockaddr*)&loc)->sa_family = ((struct sockaddr*)&loc)->sa_family;
// bind(newsocket, (struct sockaddr *)&loc, ((struct sockaddr_in*)&qs)->sin_family == AF_INET?sizeof(struct sockaddr_in):sizeof(struct sockaddr_in6));
if (connect(newsocket, (struct sockaddr *)&qs, temp) == INVALID_SOCKET)
{
closesocket(newsocket);

View File

@ -126,6 +126,7 @@ typedef struct {
int (*ParticleTypeForName) (char *name);
int (*FindParticleType) (char *name);
qboolean (*ParticleQuery) (int type, int body, char *outstr, int outstrlen);
int (*RunParticleEffectTypeString) (vec3_t org, vec3_t dir, float count, char *name);
int (*ParticleTrail) (vec3_t startpos, vec3_t end, int type, int dlkey, trailstate_t **tsk);

View File

@ -59,6 +59,7 @@ static void PM_AddTouchedEnt (int num)
return; // already added
pmove.touchindex[pmove.numtouch] = num;
VectorCopy(pmove.velocity, pmove.touchvel[pmove.numtouch]);
pmove.numtouch++;
}
@ -759,7 +760,7 @@ void PM_CategorizePosition (void)
}
}
if (cont & FTECONTENTS_LADDER)
if (cont & Q2CONTENTS_LADDER && pmove.physents[0].model->fromgame == fg_quake2)
pmove.onladder = true;
else
pmove.onladder = false;
@ -785,7 +786,7 @@ void PM_CategorizePosition (void)
pmove.onground = false; // too steep
}
}
if (cont & FTECONTENTS_LADDER && pmove.physents[0].model->fromgame == fg_quake2)
if (cont & Q2CONTENTS_LADDER && pmove.physents[0].model->fromgame == fg_quake2)
{
trace_t t;
vec3_t flatforward, fwd1;
@ -812,7 +813,7 @@ void PM_CategorizePosition (void)
//bsp objects marked as ladders mark regions to stand in to be classed as on a ladder.
cont = PM_ExtraBoxContents(pmove.origin);
if (cont & FTECONTENTS_LADDER)
if ((cont & Q2CONTENTS_LADDER) && (pmove.physents[0].model->fromgame == fg_quake2 || pmove.physents[0].model->fromgame == fg_halflife))
{
pmove.onladder = true;
pmove.onground = false; // too steep

View File

@ -74,6 +74,7 @@ typedef struct
// results
int numtouch;
int touchindex[MAX_PHYSENTS];
vec3_t touchvel[MAX_PHYSENTS];
qboolean onground;
int groundent; // index in physents array, only valid
// when onground is true

View File

@ -215,7 +215,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
{
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
model->funcs.Trace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, trace);
model->funcs.NativeTrace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
}
else
{
@ -226,7 +226,7 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
if (start_l[i]+player_maxs[i] < model->mins[i] && end_l[i] + player_maxs[i] < model->mins[i])
return false;
}
model->funcs.Trace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, trace);
model->funcs.NativeTrace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
}
}
else

View File

@ -458,4 +458,4 @@ enum lightfield_e
lfield_ambientscale=10,
lfield_diffusescale=11,
lfield_specularscale=12
};
};

View File

@ -375,7 +375,7 @@ unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
return Q1BSP_HullPointContents(&model->hulls[0], point);
}
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, trace_t *trace)
{
hull_t *hull;
vec3_t size;
@ -1390,6 +1390,6 @@ void Q1BSP_SetModelFuncs(model_t *mod)
mod->funcs.LeafnumForPoint = Q1BSP_LeafnumForPoint;
mod->funcs.LeafPVS = Q1BSP_LeafnumPVS;
mod->funcs.Trace = Q1BSP_Trace;
mod->funcs.NativeTrace = Q1BSP_Trace;
mod->funcs.PointContents = Q1BSP_PointContents;
}

View File

@ -481,7 +481,7 @@ void PMQ2_AddCurrents (vec3_t wishvel)
// add water currents
//
if (q2pm->watertype & MASK_CURRENT)
if (q2pm->watertype & Q2MASK_CURRENT) /*FIXME: q3bsp*/
{
memset(v, 0, sizeof(vec3_t));

View File

@ -894,4 +894,5 @@ char *T_GetInfoString(int num)
return info_strings_table[num];
}
#endif
#endif

View File

@ -209,7 +209,8 @@ local unsigned long unzlocal_SearchCentralDir(vfsfile_t *fin) {
if (!VFS_SEEK(fin, uReadPos))
break;
if (VFS_READ(fin,buf,(unsigned int)uReadSize)!=uReadSize) break;
if (VFS_READ(fin,buf,uReadSize)!=uReadSize)
break;
for (i=(int)uReadSize-3; (i--)>0;)
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
@ -218,7 +219,8 @@ local unsigned long unzlocal_SearchCentralDir(vfsfile_t *fin) {
break;
}
if (uPosFound!=0) break;
if (uPosFound!=0)
break;
}
TRYFREE(buf);
return uPosFound;

View File

@ -103,11 +103,12 @@ typedef struct q2trace_s
//13
#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature
#define FL_MOVECHAIN_ANGLE (1<<15) // hexen2 - when in a move chain, will update the angle
#define FL_LAGGEDMOVE (1<<16)
//17
#define FLQW_LAGGEDMOVE (1<<16)
#define FLH2_HUNTFACE (1<<16)
#define FLH2_NOZ (1<<17)
//18
//19
//20
#define FL_HUBSAVERESET (1<<20) //hexen2, ent is reverted to original state on map changes.
#define FL_CLASS_DEPENDENT (1<<21) //hexen2
@ -249,7 +250,7 @@ void VARGS WorldQ2_LinkEdict(world_t *w, q2edict_t *ent);
void VARGS WorldQ2_UnlinkEdict(world_t *w, q2edict_t *ent);
int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t **list,
int maxcount, int areatype);
trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict);
trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitcontentsmask, q2edict_t *passedict);
unsigned int Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *buffer, unsigned int buffersize, qboolean add);
qboolean Q2BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs);

View File

@ -20539,6 +20539,170 @@
<Filter
Name="nonwin"
>
<File
RelativePath="..\gl\gl_viddroid.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_vidlinuxglx.c"
>
@ -22015,6 +22179,170 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\sys_droid.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\sys_linux.c"
>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -110,6 +110,7 @@ struct {
int fbo_diffuse;
texid_t tex_sourcecol; /*this is used by $sourcecolour tgen*/
texid_t tex_sourcedepth;
int fbo_depthless;
qboolean force2d;
int currenttmu;
@ -135,6 +136,7 @@ struct {
mesh_t **meshes;
unsigned int meshcount;
float modelmatrix[16];
float modelmatrixinv[16];
float modelviewmatrix[16];
int pendingvertexvbo;
@ -759,9 +761,7 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass, qboolea
case T_GEN_3DMAP:
t = pass->anim_frames[0];
checkglerror();
GL_LazyBind(tmu, GL_TEXTURE_3D, t, useclientarray);
checkglerror();
return;
case T_GEN_VIDEOMAP:
@ -2331,12 +2331,25 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
break;
case SP_E_LMSCALE:
if (shaderstate.mode == BEM_DEPTHDARK)
qglUniform1fARB(p->handle[perm], 0.0f);
else if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
qglUniform1fARB(p->handle[perm], 1<<bound(0, gl_overbright.ival, 2));
else
qglUniform1fARB(p->handle[perm], 1.0f);
{
vec4_t colscale;
if (shaderstate.mode == BEM_DEPTHDARK)
{
VectorClear(colscale);
}
else if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
{
float sc = 1<<bound(0, gl_overbright.ival, 2);
VectorScale(shaderstate.curentity->shaderRGBAf, sc, colscale);
}
else
{
VectorCopy(shaderstate.curentity->shaderRGBAf, colscale);
}
colscale[3] = shaderstate.curentity->shaderRGBAf[3];
qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)colscale);
}
break;
case SP_E_GLOWMOD:
@ -2426,19 +2439,15 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
{
/*eye position in model space*/
vec3_t t2;
Matrix4x4_CM_Transform3(shaderstate.modelmatrix, r_origin, t2);
Matrix4x4_CM_Transform3(shaderstate.modelmatrixinv, r_origin, t2);
qglUniform3fvARB(p->handle[perm], 1, t2);
}
break;
case SP_LIGHTPOSITION:
{
/*light position in model space*/
float inv[16];
vec3_t t2;
qboolean Matrix4_Invert(const float *m, float *out);
Matrix4_Invert(shaderstate.modelmatrix, inv);
Matrix4x4_CM_Transform3(inv, shaderstate.lightorg, t2);
Matrix4x4_CM_Transform3(shaderstate.modelmatrixinv, shaderstate.lightorg, t2);
qglUniform3fvARB(p->handle[perm], 1, t2);
}
break;
@ -2753,6 +2762,7 @@ void GLBE_SelectEntity(entity_t *ent)
shaderstate.curentity = ent;
currententity = ent;
R_RotateForEntity(shaderstate.modelmatrix, shaderstate.modelviewmatrix, shaderstate.curentity, shaderstate.curentity->model);
Matrix4_Invert(shaderstate.modelmatrix, shaderstate.modelmatrixinv);
if (qglLoadMatrixf)
qglLoadMatrixf(shaderstate.modelviewmatrix);
if (shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange)
@ -3260,9 +3270,7 @@ static void BE_UpdateLightmaps(void)
glRect_t *theRect;
lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange;
checkglerror();
GL_MTBind(0, GL_TEXTURE_2D, lightmap_textures[lm]);
checkglerror();
switch (lightmap_bytes)
{
case 4:
@ -3285,7 +3293,6 @@ static void BE_UpdateLightmaps(void)
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkglerror();
if (lightmap[lm]->deluxmodified)
{
@ -3299,11 +3306,9 @@ static void BE_UpdateLightmaps(void)
theRect->t = LMBLOCK_HEIGHT;
theRect->h = 0;
theRect->w = 0;
checkglerror();
}
}
}
checkglerror();
}
batch_t *GLBE_GetTempBatch(void)
@ -3327,6 +3332,29 @@ void GLBE_BaseEntTextures(void)
}
#endif
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth)
{
shaderstate.tex_sourcecol = sourcecol;
shaderstate.tex_sourcedepth = sourcedepth;
if (!destcol.num)
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
else
{
if (!shaderstate.fbo_depthless)
{
qglGenFramebuffersEXT(1, &shaderstate.fbo_depthless);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
qglReadBuffer(GL_NONE);
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, destcol.num, 0);
}
}
void GLBE_DrawLightPrePass(qbyte *vis, batch_t **batches)
{
extern cvar_t temp1;
@ -3461,8 +3489,6 @@ void GLBE_DrawWorld (qbyte *vis)
batch_t *batches[SHADER_SORT_COUNT];
RSpeedLocals();
checkglerror();
GL_DoSwap();
if (!r_refdef.recurse)
@ -3552,8 +3578,6 @@ void GLBE_DrawWorld (qbyte *vis)
BE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime = realtime;
checkglerror();
shaderstate.identitylighting = 1;
}
#endif

View File

@ -20,11 +20,223 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// gl_bloom.c: 2D lighting post process effect
/*
info about bloom algo:
bloom is basically smudging.
screen is nearest-downsampled to some usable scale and filtered to remove low-value light (this is what stops non-bright stuff from blooming)
this filtered image is then downsized multiple times
the downsized image is then blured
the downsized images are then blured horizontally, and then vertically.
final pass simply adds each blured level to the original image.
all samples are then added together for final rendering (with some kind of tone mapping if you want proper hdr).
note: the horizontal/vertical bluring is a guassian filter
note: bloom comes from the fact that the most downsampled image doesn't have too many pixels. the pixels that it does have are spread over a large area.
http://prideout.net/archive/bloom/ contains some sample code
*/
//http://www.quakesrc.org/forums/viewtopic.php?t=4340&start=0
#include "quakedef.h"
#ifdef GLQUAKE
#include "shader.h"
#include "glquake.h"
cvar_t r_bloom = CVARAFD("r_bloom", "0", "gl_bloom", CVAR_ARCHIVE, "Enables bloom (light bleeding from bright objects)");
static shader_t *bloomfilter;
static shader_t *bloomrescale;
static shader_t *bloomblur;
static shader_t *bloomfinal;
#define MAXLEVELS 3
texid_t scrtex;
texid_t pingtex[2][MAXLEVELS];
static int scrwidth, scrheight;
static int texwidth[MAXLEVELS], texheight[MAXLEVELS];
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
void R_BloomRegister(void)
{
Cvar_Register (&r_bloom, "bloom");
}
static void R_SetupBloomTextures(int w, int h)
{
int i, j;
char name[64];
if (w == scrwidth && h == scrheight)
return;
scrwidth = w;
scrheight = h;
w /= 2;
h /= 2;
for (i = 0; i < MAXLEVELS; i++)
{
w /= 2;
h /= 2;
/*I'm paranoid*/
if (w < 4)
w = 4;
if (h < 4)
h = 4;
texwidth[i] = w;
texheight[i] = h;
}
/*we should be doing this outside of this code*/
if (!TEXVALID(scrtex))
scrtex = GL_AllocNewTexture("", scrwidth, scrheight);
GL_MTBind(0, GL_TEXTURE_2D, scrtex);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, scrwidth, scrheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
/*top level uses nearest sampling*/
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
/*now create textures for each level*/
for (j = 0; j < MAXLEVELS; j++)
{
for (i = 0; i < 2; i++)
{
if (!TEXVALID(pingtex[i][j]))
{
sprintf(name, "***bloom*%c*%i***", 'a'+i, j);
TEXASSIGN(pingtex[i][j], GL_AllocNewTexture(name, texwidth[j], texheight[j]));
}
GL_MTBind(0, GL_TEXTURE_2D, pingtex[i][j]);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texwidth[j], texheight[j], 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
bloomfilter = R_RegisterShader("bloom_filter",
"{\n"
"cull none\n"
"program bloom_filter\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"}\n");
bloomrescale = R_RegisterShader("bloom_rescale",
"{\n"
"cull none\n"
"program default2d\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"}\n");
bloomblur = R_RegisterShader("bloom_blur",
"{\n"
"cull none\n"
"program bloom_blur\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"}\n");
bloomfinal = R_RegisterShader("bloom_final",
"{\n"
"cull none\n"
"program bloom_final\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $loweroverlay\n"
"}\n"
"{\n"
"map $upperoverlay\n"
"}\n"
"}\n");
bloomfinal->defaulttextures.base = pingtex[0][0];
bloomfinal->defaulttextures.loweroverlay = pingtex[0][1];
bloomfinal->defaulttextures.upperoverlay = pingtex[0][2];
}
void R_BloomBlend (void)
{
int i;
if (!gl_config.ext_framebuffer_objects)
return;
if (!gl_config.arb_shader_objects)
return;
/*whu?*/
if (!r_refdef.pxrect.width || !r_refdef.pxrect.height)
return;
GL_Set2D(false);
/*update textures if we need to resize them*/
R_SetupBloomTextures(r_refdef.pxrect.width, r_refdef.pxrect.height);
/*grab the screen, because we failed to do it earlier*/
GL_MTBind(0, GL_TEXTURE_2D, scrtex);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_refdef.pxrect.x, r_refdef.pxrect.y - r_refdef.pxrect.height, r_refdef.pxrect.width, r_refdef.pxrect.height);
/*filter the screen into a downscaled image*/
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], r_nulltex, false);
qglViewport (0, 0, texwidth[0], texheight[0]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter);
/*and downscale that multiple times*/
for (i = 1; i < MAXLEVELS; i++)
{
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale);
}
/*gaussian filter the mips to bloom more smoothly*/
for (i = 0; i < MAXLEVELS; i++)
{
/*must be 1.2th of a pixel*/
r_worldentity.glowmod[0] = 1.2 / texwidth[i];
r_worldentity.glowmod[1] = 0;
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
for (i = 0; i < MAXLEVELS; i++)
{
r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 1.2 / texheight[i];
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
GL_Set2D(false);
/*combine them onto the screen*/
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, r_nulltex, false);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y + r_refdef.vrect.height, r_refdef.vrect.width, -r_refdef.vrect.height, bloomfinal);
}
void R_InitBloomTextures(void)
{
bloomfilter = NULL;
bloomblur = NULL;
bloomfinal = NULL;
scrwidth = 0, scrheight = 0;
if (!gl_config.ext_framebuffer_objects)
return;
}
#elif defined(GLQUAKE)
#include "glquake.h"
/*

View File

@ -191,7 +191,8 @@ static gltexture_t *GL_AllocNewGLTexture(char *ident, int w, int h)
qglGenTextures(1, &glt->texnum.num);
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
if (*glt->identifier)
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
return glt;
}
@ -456,7 +457,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
GL_BeginRendering ();
TRACE(("dbg: GLDraw_ReInit: SCR_DrawLoading\n"));
GL_Set2D();
GL_Set2D(false);
qglClear(GL_COLOR_BUFFER_BIT);
{
@ -539,7 +540,7 @@ GL_Set2D
Setup as if the screen was 320*200
================
*/
void GL_Set2D (void)
void GL_Set2D (qboolean flipped)
{
extern cvar_t gl_screenangle;
float rad, ang;
@ -563,7 +564,10 @@ void GL_Set2D (void)
}
else
{
Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999);
if (flipped)
Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, 0, vid.height, -99999, 99999);
else
Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999);
Matrix4x4_Identity(r_refdef.m_view);
}
r_refdef.time = realtime;

View File

@ -154,6 +154,7 @@ static const char *imgs[] =
#define INVALIDPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-1)
#define BITMAPPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-2)
#define DEFAULTPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-3)
#define SINGLEPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-4)
#define PLANEWIDTH (1<<8)
#define PLANEHEIGHT PLANEWIDTH
@ -851,6 +852,46 @@ static texid_t Font_LoadDefaultConchars(void)
Sys_Error("Unable to load any conchars\n");
}
typedef struct
{
short width;
short height;
short leftoffset; // pixels to the left of origin
short topoffset; // pixels below the origin
int columnofs[1];
} doompatch_t;
typedef struct
{
unsigned char topdelta; // -1 is the last post in a column
unsigned char length; // length data bytes follows
} doomcolumn_t;
void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
{
doomcolumn_t *col;
unsigned char *src, *dst;
int x, y;
for (x = 0; x < p->width; x++)
{
col = (doomcolumn_t *)((unsigned char *)p + p->columnofs[x]);
while(col->topdelta != 0xff)
{
//exploit protection
if (col->length + col->topdelta > p->height)
break;
src = (unsigned char *)col + 3; /*why 3? why not, I suppose*/
dst = b + stride*col->topdelta;
for (y = 0; y < col->length; y++)
{
*dst = *src++;
dst += stride;
}
col = (doomcolumn_t *)((unsigned char*)col + col->length + 4);
}
b++;
}
}
//creates a new font object from the given file, with each text row with the given height.
//width is implicit and scales with height and choice of font.
struct font_s *Font_LoadFont(int height, char *fontfilename)
@ -861,6 +902,70 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
f = Z_Malloc(sizeof(*f));
f->charheight = height;
#ifdef DOOMWADS
if (!*fontfilename)
{
unsigned char buf[PLANEWIDTH*PLANEHEIGHT];
int i;
int x=0,y=0,h=0;
doompatch_t *dp;
memset(buf, 0, sizeof(buf));
for (i = '!'; i <= '_'; i++)
{
dp = NULL;
FS_LoadFile(va("wad/stcfn%.3d", i), &dp);
if (!dp)
break;
/*make sure it can fit*/
if (x + dp->width > PLANEWIDTH)
{
x = 0;
y += h;
h = 0;
}
f->chars[i].advance = dp->width; /*this is how much line space the char takes*/
f->chars[i].left = -dp->leftoffset;
f->chars[i].top = -dp->topoffset;
f->chars[i].nextchar = 0;
f->chars[i].pad = 0;
f->chars[i].texplane = SINGLEPLANE;
f->chars[i].bmx = x;
f->chars[i].bmy = y;
f->chars[i].bmh = dp->height;
f->chars[i].bmw = dp->width;
Doom_ExpandPatch(dp, &buf[y*PLANEWIDTH + x], PLANEWIDTH);
x += dp->width;
if (dp->height > h)
{
h = dp->height;
if (h > f->charheight)
f->charheight = h;
}
FS_FreeFile(dp);
}
/*if all loaded okay, replicate the chars to the quake-compat range (both white+red chars)*/
if (i == '_'+1)
{
f->chars[' '].advance = 8;
f->singletexture = R_LoadTexture8("doomfont", PLANEWIDTH, PLANEHEIGHT, buf, 0, true);
for (i = 0xe000; i <= 0xe0ff; i++)
{
f->chars[i] = f->chars[toupper(i&0x7f)];
}
return f;
}
}
#endif
if (!strcmp(fontfilename, "gfx/tinyfont"))
{
unsigned int *img;
@ -1215,25 +1320,36 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
s1 = (float)(c->bmx+c->bmw)/PLANEWIDTH;
t1 = (float)(c->bmy+c->bmh)/PLANEWIDTH;
if (c->texplane >= DEFAULTPLANE)
switch(c->texplane)
{
case DEFAULTPLANE:
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((curfont->charheight)*vid.width) / (float)vid.rotpixelwidth;
sh = ((curfont->charheight)*vid.height) / (float)vid.rotpixelheight;
if (c->texplane == DEFAULTPLANE)
v = Font_BeginChar(fontplanes.defaultfont);
else
v = Font_BeginChar(curfont->singletexture);
}
else
{
v = Font_BeginChar(fontplanes.defaultfont);
break;
case BITMAPPLANE:
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((curfont->charheight)*vid.width) / (float)vid.rotpixelwidth;
sh = ((curfont->charheight)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(curfont->singletexture);
break;
case SINGLEPLANE:
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(curfont->singletexture);
break;
default:
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
break;
}
font_texcoord[v+0][0] = s0;

View File

@ -528,7 +528,7 @@ Heightmap_Trace
Traces a line through a heightmap, sampling the terrain at various different positions.
This is inprecise, only supports points (or vertical lines), and can often travel though sticky out bits of terrain.
*/
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, trace_t *trace)
{
vec3_t org;
vec3_t dir;
@ -589,10 +589,6 @@ qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axi
return trace->fraction != 1;
}
qboolean Heightmap_NativeTrace(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 against, struct trace_s *trace)
{
return Heightmap_Trace(model, hulloverride, frame, axis, p1, p2, mins, maxs, trace);
}
#endif
unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned int pvssize, qboolean add)
@ -942,11 +938,10 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer)
}
}
mod->funcs.Trace = Heightmap_Trace;
mod->funcs.NativeTrace = Heightmap_Trace;
mod->funcs.PointContents = Heightmap_PointContents;
mod->funcs.NativeContents = Heightmap_NativeBoxContents;
mod->funcs.NativeTrace = Heightmap_NativeTrace;
mod->funcs.LightPointValues = Heightmap_LightPointValues;
mod->funcs.StainNode = Heightmap_StainNode;

View File

@ -172,10 +172,9 @@ BRUSH MODELS
*/
typedef struct {
//deals with FTECONTENTS (assumes against solid)
//model is being purged from memory.
void (*PurgeModel) (struct model_s *mod);
qboolean (*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);
unsigned int (*PointContents) (struct model_s *model, vec3_t axis[3], vec3_t p);
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
@ -515,7 +514,7 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, struct trace_s *trace);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
unsigned int Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct pvscache_s *ent, qbyte *pvs);

View File

@ -1145,7 +1145,7 @@ void GLR_RenderView (void)
// Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
}
if (qglGetError())
while (qglGetError())
Con_Printf("GL Error drawing scene\n");
if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
@ -1160,7 +1160,7 @@ void GLR_RenderView (void)
{
if (scenepp_waterwarp)
{
GL_Set2D();
GL_Set2D(false);
R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp);
}
}
@ -1175,7 +1175,7 @@ void GLR_RenderView (void)
shader_t *postproc = R_RegisterCustom(r_postprocshader.string, NULL, NULL);
if (postproc)
{
GL_Set2D();
GL_Set2D(false);
R2D_ScalePic(0, 0, vid.width, vid.height, postproc);
}
}

View File

@ -500,6 +500,7 @@ void GLR_NewMap (void)
AngleVectors(r_worldentity.angles, r_worldentity.axis[0], r_worldentity.axis[1], r_worldentity.axis[2]);
VectorInverse(r_worldentity.axis[1]);
r_worldentity.model = cl.worldmodel;
Vector4Set(r_worldentity.shaderRGBAf, 1, 1, 1, 1);
COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf, sizeof(namebuf));

View File

@ -174,7 +174,7 @@ void GLSCR_UpdateScreen (void)
else
GL_DoSwap();
GL_Set2D ();
GL_Set2D (false);
if (!noworld)
{

View File

@ -43,6 +43,7 @@ static qboolean shader_rescan_needed;
//cvars that affect shader generation
cvar_t r_vertexlight = CVARFD("r_vertexlight", "0", CVAR_SHADERSYSTEM, "Hack loaded shaders to remove detail pass and lightmap sampling for faster rendering.");
extern cvar_t r_glsl_offsetmapping_reliefmapping;
extern cvar_t r_deluxemapping;
extern cvar_t r_fastturb, r_fastsky, r_skyboxname;
extern cvar_t r_drawflat;
@ -804,7 +805,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
"#define FOG\n",
NULL
};
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + 64];
char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + 64 + 1];
unsigned int nopermutation = ~0u;
int nummodifiers;
int p, n, pn;
@ -813,6 +814,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
char *cvarnames[64];
int cvartypes[64];
int cvarcount = 0;
qboolean onefailed = false;
cvarnames[cvarcount] = NULL;
@ -891,36 +893,45 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
end = strchr(start, '#');
if (!end)
end = start + strlen(start);
permutationdefines[nummodifiers] = malloc(10 + end - start);
memcpy(permutationdefines[nummodifiers], "#define ", 8);
memcpy(permutationdefines[nummodifiers]+8, start, end - start);
memcpy(permutationdefines[nummodifiers]+8+(end-start), "\n", 2);
if (nummodifiers < 64)
{
permutationdefines[nummodifiers] = malloc(10 + end - start);
memcpy(permutationdefines[nummodifiers], "#define ", 8);
memcpy(permutationdefines[nummodifiers]+8, start, end - start);
memcpy(permutationdefines[nummodifiers]+8+(end-start), "\n", 2);
for (start = permutationdefines[nummodifiers]+8; *start; start++)
*start = toupper(*start);
nummodifiers++;
for (start = permutationdefines[nummodifiers]+8; *start; start++)
*start = toupper(*start);
nummodifiers++;
permutationdefines[nummodifiers] = NULL;
}
}
for (p = 0; p < PERMUTATIONS; p++)
{
if (nopermutation & p)
{
continue;
}
pn = nummodifiers;
for (n = 0; permutationname[n]; n++)
{
if (p & (1u<<n))
permutationdefines[pn++] = permutationname[n];
}
if (r_glsl_offsetmapping_reliefmapping.ival && (p & PERMUTATION_OFFSET))
permutationdefines[pn++] = "#define RELIEFMAPPING\n";
permutationdefines[pn++] = NULL;
if (qrenderer != qrtype)
{
}
#ifdef GLQUAKE
else if (qrenderer == QR_OPENGL)
{
if (nopermutation & p)
{
continue;
}
pn = nummodifiers;
for (n = 0; permutationname[n]; n++)
{
if (p & (1u<<n))
permutationdefines[pn++] = permutationname[n];
}
permutationdefines[pn++] = NULL;
prog->handle[p].glsl = GLSlang_CreateProgram(name, (((p & PERMUTATION_SKELETAL) && ver < 120)?120:ver), permutationdefines, script, script);
prog->handle[p].glsl = GLSlang_CreateProgram(name, (((p & PERMUTATION_SKELETAL) && ver < 120)?120:ver), permutationdefines, script, script, onefailed);
if (!prog->handle[p].glsl)
onefailed = true;
if (!p && !prog->handle[p].glsl)
break;
}
@ -928,17 +939,6 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
#ifdef D3DQUAKE
else if (qrenderer == QR_DIRECT3D)
{
if (nopermutation & p)
{
continue;
}
pn = nummodifiers;
for (n = 0; permutationname[n]; n++)
{
if (p & (1u<<n))
permutationdefines[pn++] = permutationname[n];
}
permutationdefines[pn++] = NULL;
if (!D3DShader_CreateProgram(prog, p, permutationdefines, script, script))
break;
}
@ -1131,11 +1131,11 @@ struct sbuiltin_s
//"uniform sampler2D s_t3;\n" /*tex_deluxmap*/
//"uniform sampler2D s_t4;\n" /*tex_fullbright*/
"varying mediump vec2 tc, lm;\n"
"uniform mediump float e_lmscale;\n"
"uniform mediump vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(e_lmscale, e_lmscale, e_lmscale, 1);\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"}\n"
"#endif\n"
},
@ -1185,26 +1185,19 @@ struct sbuiltin_s
"uniform sampler2D s_t4;\n" /*tex_fullbright*/
"#endif\n"
"varying vec2 tc, lm;\n"
"uniform float e_lmscale;\n"
"uniform vec4 e_lmscale;\n"
"#ifdef OFFSETMAPPING\n"
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(1, -1);\n"
"vec2 tcoffsetmap = tc;\n"
"#define tc tcoffsetmap\n"
"tc += OffsetVector;\n"
"OffsetVector *= 0.333;\n"
"tc -= OffsetVector * texture2D(s_t2, tc).w;\n"
"tc -= OffsetVector * texture2D(s_t2, tc).w;\n"
"tc -= OffsetVector * texture2D(s_t2, tc).w;\n"
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(e_lmscale, e_lmscale, e_lmscale, 1);\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"#ifdef FULLBRIGHT\n"
" gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n"
@ -1226,11 +1219,11 @@ struct sbuiltin_s
"varying vec2 lm;\n"
"uniform vec3 cvar_r_wallcolor;\n"
"uniform vec3 cvar_r_floorcolor;\n"
"uniform float e_lmscale;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
" col = vec4(e_lmscale/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), 1.0);\n"
" col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a);\n"
" lm = v_lmcoord;\n"
" gl_Position = ftetransform();\n"
"}\n"
@ -1740,11 +1733,11 @@ struct sbuiltin_s
//"uniform sampler2D s_t3;\n" /*tex_normalmap*/
//"uniform sampler2D s_t4;\n" /*tex_deluxmap*/
//"uniform sampler2D s_t5;\n" /*tex_fullbright*/
"uniform float e_lmscale;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
//"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(scale, scale, scale, 1.0);\n"
//"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"vec2 nst;\n"
"nst = tf.xy / tf.w;\n"
@ -2038,20 +2031,14 @@ struct sbuiltin_s
"uniform vec3 l_lightcolourscale;\n"
"#ifdef OFFSETMAPPING\n"
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(1, -1);\n"
"vec2 tcoffsetmap = tcbase;\n"
"#define tcbase tcoffsetmap\n"
"tcbase += OffsetVector;\n"
"OffsetVector *= 0.333;\n"
"tcbase -= OffsetVector * texture2D(s_t1, tcbase).w;\n"
"tcbase -= OffsetVector * texture2D(s_t1, tcbase).w;\n"
"tcbase -= OffsetVector * texture2D(s_t1, tcbase).w;\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"#define tcbase tcoffsetmap\n"
"#endif\n"
@ -2074,7 +2061,7 @@ struct sbuiltin_s
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec3 halfdir = normalize(lightvector) + normalize(eyevector);\n"
"vec3 halfdir = normalize(lightvector - normalize(eyevector));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 1.0 + 32.0 * specs.a);\n"
"diff += spec * specs.rgb * l_lightcolourscale.z;\n"
"#endif\n"
@ -2272,6 +2259,7 @@ struct sbuiltin_s
"#endif\n"
},
#endif
#include "r_bishaders.h"
{QR_NONE}
};
void Shader_UnloadProg(program_t *prog)
@ -4530,6 +4518,15 @@ void Shader_Finish (shader_t *s)
}
done:;
for (pass = s->passes, i = 0; i < s->numpasses; i++, pass++)
{
if ((pass->texgen == T_GEN_ANIMMAP || pass->texgen == T_GEN_SINGLEMAP) && !TEXVALID(s->defaulttextures.base))
s->defaulttextures.base = pass->anim_frames[0];
if (pass->texgen == T_GEN_VIDEOMAP && pass->cin && !TEXVALID(s->defaulttextures.base))
s->defaulttextures.base = Media_UpdateForShader(pass->cin);
}
pass = s->passes;
for (i = 0; i < s->numpasses; i++, pass++)
{
@ -4698,38 +4695,57 @@ void Shader_UpdateRegistration (void)
void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
{
/*dlights/realtime lighting needs some stuff*/
if (!TEXVALID(tn->base))
if (!TEXVALID(shader->defaulttextures.base))
{
tn->base = R_LoadHiResTexture(shader->name, NULL, IF_NOALPHA);
}
if (TEXVALID(tn->base))
shader->flags &= ~SHADER_NOIMAGE;
/*dlights/realtime lighting needs some stuff*/
if (!TEXVALID(tn->base))
{
tn->base = R_LoadHiResTexture(shader->name, NULL, IF_NOALPHA);
}
if (TEXVALID(tn->base))
shader->flags &= ~SHADER_NOIMAGE;
if (r_loadbumpmapping)
{
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->name), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_bump", shader->name), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("normalmaps/%s", shader->name), NULL, IF_NOALPHA);
TEXASSIGN(shader->defaulttextures.base, tn->base);
}
if (shader->flags & SHADER_HASTOPBOTTOM)
if (!TEXVALID(shader->defaulttextures.bump))
{
if (!TEXVALID(tn->loweroverlay))
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->name), NULL, 0); /*how rude*/
if (!TEXVALID(tn->upperoverlay))
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->name), NULL, 0);
if (r_loadbumpmapping)
{
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->name), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_bump", shader->name), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("normalmaps/%s", shader->name), NULL, IF_NOALPHA);
}
TEXASSIGN(shader->defaulttextures.bump, tn->bump);
}
TEXASSIGN(shader->defaulttextures.base, tn->base);
TEXASSIGN(shader->defaulttextures.specular, tn->specular);
TEXASSIGN(shader->defaulttextures.fullbright, tn->fullbright);
TEXASSIGN(shader->defaulttextures.bump, tn->bump);
TEXASSIGN(shader->defaulttextures.loweroverlay, tn->loweroverlay);
TEXASSIGN(shader->defaulttextures.upperoverlay, tn->upperoverlay);
if (!TEXVALID(shader->defaulttextures.loweroverlay))
{
if (shader->flags & SHADER_HASTOPBOTTOM)
{
if (!TEXVALID(tn->loweroverlay))
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->name), NULL, 0); /*how rude*/
}
TEXASSIGN(shader->defaulttextures.loweroverlay, tn->loweroverlay);
}
if (!TEXVALID(shader->defaulttextures.upperoverlay))
{
if (shader->flags & SHADER_HASTOPBOTTOM)
{
if (!TEXVALID(tn->upperoverlay))
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->name), NULL, 0);
}
TEXASSIGN(shader->defaulttextures.upperoverlay, tn->upperoverlay);
}
if (!TEXVALID(shader->defaulttextures.specular))
TEXASSIGN(shader->defaulttextures.specular, tn->specular);
if (!TEXVALID(shader->defaulttextures.fullbright))
TEXASSIGN(shader->defaulttextures.fullbright, tn->fullbright);
}
void Shader_DefaultScript(char *shortname, shader_t *s, const void *args)

View File

@ -385,6 +385,29 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
gl_config.nofixedfunc = false;
}
gl_config.maxglslversion = 0;
if (gl_config.gles && gl_config.glversion >= 2)
gl_config.maxglslversion = 100;
else if (gl_config.glversion >= 2)
{
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
const char *s = qglGetString (GL_SHADING_LANGUAGE_VERSION);
if (s)
{
gl_config.maxglslversion = atoi(s) * 100;
while(*s >= '0' && *s <= '9')
s++;
if (*s == '.')
s++;
gl_config.maxglslversion += atoi(s);
}
else
gl_config.maxglslversion = 110;
}
else
gl_config.maxglslversion = 110;
//multitexture
gl_mtexable = false;
gl_mtexarbable = 0;
@ -828,6 +851,34 @@ static const char *glsl_hdrs[] =
"#endif\n"
"#endif\n"
,
"sys/offsetmapping.h",
"uniform float cvar_r_glsl_offsetmapping_scale;\n"
"vec2 offsetmap(sampler2D normtex, vec2 base, vec3 eyevector)\n"
"{\n"
"#if defined(RELIEFMAPPING)\n"
"float i, f;\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0), -1.0);\n"
"vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n"
"OffsetVector /= 10.0;\n"
"for(i = 1.0; i < 10.0; ++i)\n"
"RT += OffsetVector * step(texture2D(normtex, RT.xy).a, RT.z);\n"
"for(i = 0.0, f = 1.0; i < 5.0; ++i, f *= 0.5)\n"
"RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);\n"
"return RT.xy;\n"
"#elif defined(OFFSETMAPPING)\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0);\n"
"vec2 tc = base;\n"
"tc += OffsetVector;\n"
"OffsetVector *= 0.333;\n"
"tc -= OffsetVector * texture2D(normtex, tc).w;\n"
"tc -= OffsetVector * texture2D(normtex, tc).w;\n"
"tc -= OffsetVector * texture2D(normtex, tc).w;\n"
"return tc;\n"
"#else\n"
"return base;\n"
"#endif\n"
"}\n"
,
NULL
};
@ -889,7 +940,7 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
// glslang helper api function definitions
// type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB
GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstants, const char *shadersource, GLenum shadertype)
GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstants, const char *shadersource, GLenum shadertype, qboolean silent)
{
GLhandleARB shader;
GLint compiled;
@ -901,6 +952,10 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
if (ver)
{
/*required version not supported, don't even try*/
if (ver > gl_config.maxglslversion)
return 0;
prstrings[strings] = va("#version %u\n", ver);
length[strings] = strlen(prstrings[strings]);
strings++;
@ -1011,31 +1066,34 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
{
qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
qglDeleteShaderObject_(shader);
switch (shadertype)
if (!silent)
{
case GL_FRAGMENT_SHADER_ARB:
Con_Printf("Fragment shader (%s) compilation error:\n----------\n%s----------\n", name, str);
break;
case GL_VERTEX_SHADER_ARB:
Con_Printf("Vertex shader (%s) compilation error:\n----------\n%s----------\n", name, str);
break;
default:
Con_Printf("Shader_CreateShader: This shouldn't happen ever\n");
break;
}
Con_DPrintf("Shader \"%s\" source:\n", name);
for (i = 0; i < strings; i++)
{
int j;
if (length[i] < 0)
Con_DPrintf("%s", prstrings[i]);
else
switch (shadertype)
{
for (j = 0; j < length[i]; j++)
Con_DPrintf("%c", prstrings[i][j]);
case GL_FRAGMENT_SHADER_ARB:
Con_Printf("Fragment shader (%s) compilation error:\n----------\n%s----------\n", name, str);
break;
case GL_VERTEX_SHADER_ARB:
Con_Printf("Vertex shader (%s) compilation error:\n----------\n%s----------\n", name, str);
break;
default:
Con_Printf("Shader_CreateShader: This shouldn't happen ever\n");
break;
}
Con_DPrintf("Shader \"%s\" source:\n", name);
for (i = 0; i < strings; i++)
{
int j;
if (length[i] < 0)
Con_DPrintf("%s", prstrings[i]);
else
{
for (j = 0; j < length[i]; j++)
Con_DPrintf("%c", prstrings[i][j]);
}
}
Con_DPrintf("%s\n", str);
}
Con_DPrintf("%s\n", str);
return 0;
}
@ -1058,7 +1116,7 @@ GLhandleARB GLSlang_CreateShader (char *name, int ver, char **precompilerconstan
return shader;
}
GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag)
GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag, qboolean silent)
{
GLhandleARB program;
GLint linked;
@ -1084,8 +1142,11 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag)
if(!linked)
{
qglGetProgramInfoLog_(program, sizeof(str), NULL, str);
Con_Printf("Program link error: %s\n", str);
if (!silent)
{
qglGetProgramInfoLog_(program, sizeof(str), NULL, str);
Con_Printf("Program link error: %s\n", str);
}
qglDeleteProgramObject_(program);
@ -1094,7 +1155,7 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag)
return program;
}
GLhandleARB GLSlang_CreateProgram(char *name, int ver, char **precompilerconstants, char *vert, char *frag)
GLhandleARB GLSlang_CreateProgram(char *name, int ver, char **precompilerconstants, char *vert, char *frag, qboolean silent)
{
GLhandleARB handle;
GLhandleARB vs;
@ -1107,13 +1168,13 @@ GLhandleARB GLSlang_CreateProgram(char *name, int ver, char **precompilerconstan
if (!precompilerconstants)
precompilerconstants = &nullconstants;
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB);
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB);
vs = GLSlang_CreateShader(name, ver, precompilerconstants, vert, GL_VERTEX_SHADER_ARB, silent);
fs = GLSlang_CreateShader(name, ver, precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB, silent);
if (!vs || !fs)
handle = 0;
else
handle = GLSlang_CreateProgramObject(vs, fs);
handle = GLSlang_CreateProgramObject(vs, fs, silent);
//delete ignores 0s.
qglDeleteShaderObject_(vs);
qglDeleteShaderObject_(fs);

View File

@ -89,6 +89,10 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
Cons: GL_EndRendering call will not swap buffers. Buffers will be swapped on return to java.
*/
if (gles2)
Sys_Printf("Loading GLES2 driver\n");
else
Sys_Printf("Loading GLES1 driver\n");
sys_gl_module = Sys_LoadLibrary(gles2?"libGLESv2.so":"libGLESv1_CM.so", NULL);
if (!sys_gl_module)
{
@ -96,7 +100,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
return false;
}
GLVID_SetPalette (palette);
GLVID_SetPalette (palette);
GL_Init(GLES_GetSymbol);
vid.recalc_refdef = 1;
return true;

View File

@ -1,16 +1,11 @@
#include "quakedef.h"
#ifdef MAP_DOOM
#ifdef GLQUAKE
#include "glquake.h"
#include "shader.h"
#include "doommap.h"
int SignbitsForPlane (mplane_t *out);
int PlaneTypeForNormal ( vec3_t normal );
#undef strncpy
//coded from file specifications provided by:
//Matthew S Fell (msfell@aol.com)
//Unofficial Doom Specs
@ -18,15 +13,6 @@ int PlaneTypeForNormal ( vec3_t normal );
//(aol suck)
void Doom_SetModelFunc(model_t *mod);
//skill/dm is appears in rather than quake's excuded in.
#define THING_EASY 1
#define THING_MEDIUM 2
#define THING_HARD 4
#define THING_DEAF 8
#define THING_DEATHMATCH 16
//other bits are ignored
int Doom_SectorNearPoint(vec3_t p);
//assumptions:
@ -38,6 +24,167 @@ int Doom_SectorNearPoint(vec3_t p);
enum {
THING_PLAYER = 1,
THING_PLAYER2 = 2,
THING_PLAYER3 = 3,
THING_PLAYER4 = 4,
THING_DMSPAWN = 11,
//we need to balance weapons according to ammo types.
THING_WCHAINSAW = 2005, //-> quad
THING_WSHOTGUN1 = 2001, //-> ng
THING_WSHOTGUN2 = 82, //-> sng
THING_WCHAINGUN = 2002, //-> ssg
THING_WROCKETL = 2003, //-> lightning
THING_WPLASMA = 2004, //-> grenade
THING_WBFG = 2006 //-> rocket
} THING_TYPES;
//thing flags
//skill/dm is appears in rather than quake's excuded in.
#define THING_EASY 1
#define THING_MEDIUM 2
#define THING_HARD 4
#define THING_DEAF 8
#define THING_DEATHMATCH 16
//other bits are ignored
typedef struct {
short xpos;
short ypos;
short angle;
unsigned short type;
unsigned short flags;
} dthing_t;
typedef struct {
short xpos;
short ypos;
} ddoomvertex_t;
typedef struct {
float xpos;
float ypos;
} mdoomvertex_t;
typedef struct {
unsigned short vert[2];
unsigned short flags;
short types;
short tag;
unsigned short sidedef[2]; //(0xffff is none for sidedef[1])
} dlinedef_t;
#define LINEDEF_IMPASSABLE 1
#define LINEDEF_BLOCKMONSTERS 2
#define LINEDEF_TWOSIDED 4
#define LINEDEF_UPPERUNPEGGED 8
#define LINEDEF_LOWERUNPEGGED 16
#define LINEDEF_SECRET 32 //seen as singlesided on automap, does nothing else.
#define LINEDEF_BLOCKSOUND 64
#define LINEDEF_NOTONMAP 128 //doesn't appear on automap.
#define LINEDEF_STARTONMAP 256
//others are ignored.
typedef struct {
short texx;
short texy;
char uppertex[8];
char lowertex[8];
char middletex[8];
unsigned short sector;
} dsidedef_t;
typedef struct {
float texx;
float texy;
int uppertex;
int lowertex;
int middletex;
unsigned short sector;
} msidedef_t;
typedef struct { //figure out which linedef to use and throw the rest away.
unsigned short vert[2];
short angle;
unsigned short linedef;
short direction;
short offset;
} dseg_t;
typedef struct {
unsigned short vert[2];
unsigned short linedef;
short direction;
unsigned short Partner; //the one on the other side of the owner's linedef
} dgl_seg1_t;
typedef struct {
unsigned int vert[2];
unsigned short linedef;
short direction;
unsigned int Partner; //the one on the other side of the owner's linedef
} dgl_seg3_t;
typedef struct {
unsigned short segcount;
unsigned short first;
} dssector_t;
typedef struct {
short x;
short y;
short dx;
short dy;
short y1upper;
short y1lower;
short x1lower;
short x1upper;
short y2upper;
short y2lower;
short x2lower;
short x2upper;
unsigned short node1;
unsigned short node2;
} ddoomnode_t;
#define NODE_IS_SSECTOR 0x8000
typedef struct {
short floorheight;
short ceilingheight;
char floortexture[8];
char ceilingtexture[8];
short lightlevel;
short specialtype;
short tag;
} dsector_t;
typedef struct {
int visframe;
shader_t *floortex;
shader_t *ceilingtex;
short floorheight;
short ceilingheight;
qbyte lightlev;
qbyte pad;
int numflattris;
short tag;
short specialtype;
unsigned short *flats;
} msector_t;
typedef struct {
short xorg;
short yorg;
short columns;
short rows;
} blockmapheader_t;
ddoomnode_t *nodel;
dssector_t *ssectorsl;
dthing_t *thingsl;
@ -64,9 +211,459 @@ extern model_t *loadmodel;
extern char loadname[];
#ifdef _MSC_VER
//#pragma comment (lib, "../../../glbsp/glbsp-2.05/plugin/libglbsp.a")
////////////////////////////////////////////////////////////////////////////////////////////
//physics
/*walk the bsp tree*/
int Doom_SectorNearPoint(vec3_t p)
{
ddoomnode_t *node;
plane_t *plane;
int num;
int seg;
float d;
num = nodec-1;
while (1)
{
if (num & NODE_IS_SSECTOR)
{
num -= NODE_IS_SSECTOR;
for (seg = ssectorsl[num].first; seg < ssectorsl[num].first + ssectorsl[num].segcount; seg++)
if (segsl[seg].linedef != 0xffff)
break;
return sidedefsm[linedefsl[segsl[seg].linedef].sidedef[segsl[seg].direction]].sector;
}
node = nodel + num;
plane = nodeplanes + num;
// if (plane->type < 3)
// d = p[plane->type] - plane->dist;
// else
d = DotProduct (plane->normal, p) - plane->dist;
if (d < 0)
num = node->node2;
else
num = node->node1;
}
return num;
}
int Doom_PointContents(model_t *model, vec3_t axis[3], vec3_t p)
{
int sec = Doom_SectorNearPoint(p);
if (p[2] < sectorm[sec].floorheight)
return FTECONTENTS_SOLID;
if (p[2] > sectorm[sec].ceilingheight)
return FTECONTENTS_SOLID;
return FTECONTENTS_EMPTY;
}
qboolean Doom_Trace(model_t *model, int hulloverride, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int contentstype, trace_t *trace)
{
#if 0
#define TRACESTEP 16
unsigned short *linedefs;
dlinedef_t *ld;
int bmi, obmi;
vec3_t delta;
int sec1 = Doom_SectorNearPoint(start);
vec3_t p1, pointonplane, ofs;
float d1, d2, c1, c2, planedist;
plane_t *lp;
mdoomvertex_t *v1, *v2;
int j;
float p2f;
float clipfrac;
#define DIST_EPSILON (0.03125)
// Con_Printf("%i\n", sec1);
if (start[2] < sectorm[sec1].floorheight-mins[2]) //whoops, started outside... ?
{
trace->fraction = 0;
trace->allsolid = trace->startsolid = true;
trace->endpos[0] = start[0];
trace->endpos[1] = start[1];
trace->endpos[2] = start[2]; //yeah, we do mean this - startsolid
// if (IS_NAN(trace->endpos[2]))
// Con_Printf("Nanny\n");
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = 1;
trace->plane.dist = sectorm[sec1].floorheight-mins[2];
return false;
}
if (start[2] > sectorm[sec1].ceilingheight-maxs[2]) //whoops, started outside... ?
{
trace->fraction = 0;
trace->allsolid = trace->startsolid = true;
trace->endpos[0] = start[0];
trace->endpos[1] = start[1];
trace->endpos[2] = start[2];
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = -1;
trace->plane.dist = -(sectorm[sec1].ceilingheight-maxs[2]);
return false;
}
obmi = -1;
VectorSubtract(end, start, delta);
p2f = Length(delta)+DIST_EPSILON;
if (IS_NAN(p2f) || p2f > 100000)
p2f = 100000;
VectorNormalize(delta);
trace->endpos[0] = end[0];
trace->endpos[1] = end[1];
trace->endpos[2] = end[2];
trace->fraction = 1;
while(1)
{
bmi = ((int)p1[0] - blockmapl->xorg)/128 + (((int)p1[1] - blockmapl->yorg)/128)*blockmapl->columns;
// Con_Printf("%i of %i ", bmi, blockmapl->rows*blockmapl->columns);
if (bmi >= 0 && bmi < blockmapl->rows*blockmapl->columns)
if (bmi != obmi)
{
#if 1
short dummy;
linedefs = &dummy;
for (dummy = 0; dummy < linedefsc; dummy++)
#else
for(linedefs = (short*)blockmapl + blockmapofs[bmi]+1; *linedefs != 0xffff; linedefs++)
#endif
{
ld = linedefsl + *linedefs;
if (ld->sidedef[1] != 0xffff)
{
if (sectorm[sidedefsm[ld->sidedef[0]].sector].floorheight == sectorm[sidedefsm[ld->sidedef[1]].sector].floorheight &&
sectorm[sidedefsm[ld->sidedef[0]].sector].ceilingheight == sectorm[sidedefsm[ld->sidedef[1]].sector].ceilingheight)
continue;
}
lp = lineplanes + *linedefs;
if (1)
{ //figure out how far to move the plane out by
for (j=0 ; j<2 ; j++)
{
if (lp->normal[j] < 0)
ofs[j] = maxs[j];
else
ofs[j] = mins[j];
}
ofs[2] = 0;
planedist = lp->dist - DotProduct (ofs, lp->normal);
}
else
planedist = lp->dist;
d1 = DotProduct(lp->normal, start) - (planedist);
d2 = DotProduct(lp->normal, end) - (planedist);
if (d1 > 0 && d2 > 0)
continue; //both points on the front side.
if (d1 < 0) //start on back side
{
if (ld->sidedef[1] != 0xffff) //two sided (optimisation)
{
planedist = -planedist+lp->dist;
if (/*d1 < planedist*-1 &&*/ d1 > planedist*2)
{ //right, we managed to end up just on the other side of a wall's plane.
v1 = &vertexesl[ld->vert[0]];
v2 = &vertexesl[ld->vert[1]];
if (!(d1 - d2))
continue;
if (d1<0) //back to front.
c1 = (d1+DIST_EPSILON) / (d1 - d2);
else
c1 = (d1-DIST_EPSILON) / (d1 - d2);
c2 = 1-c1;
pointonplane[0] = start[0]*c2 + p2[0]*c1;
/* if (pointonplane[0] > v1->xpos+DIST_EPSILON*2+hull->clip_maxs[0] && pointonplane[0] > v2->xpos+DIST_EPSILON*2+hull->clip_maxs[0])
continue;
if (pointonplane[0] < v1->xpos-DIST_EPSILON*2+hull->clip_mins[0] && pointonplane[0] < v2->xpos-DIST_EPSILON*2+hull->clip_mins[0])
continue;
*/ pointonplane[1] = start[1]*c2 + p2[1]*c1;
/* if (pointonplane[1] > v1->ypos+DIST_EPSILON*2+hull->clip_maxs[1] && pointonplane[1] > v2->ypos+DIST_EPSILON*2+hull->clip_maxs[1])
continue;
if (pointonplane[1] < v1->ypos-DIST_EPSILON*2+hull->clip_mins[1] && pointonplane[1] < v2->ypos-DIST_EPSILON*2+hull->clip_mins[1])
continue;
*/
pointonplane[2] = start[2]*c2 + p2[2]*c1;
Con_Printf("Started in wall\n");
j = sidedefsm[ld->sidedef[d1 < planedist]].sector;
//yup, we are in the thing
//prevent ourselves from entering the back-sector's floor/ceiling
if (pointonplane[2] < sectorm[j].floorheight-hull->clip_mins[2]) //whoops, started outside... ?
{
Con_Printf("Started in floor\n");
trace->allsolid = trace->startsolid = false;
trace->endpos[2] = sectorm[j].floorheight-hull->clip_mins[2];
trace->fraction = fabs(trace->endpos[2] - start[2]) / fabs(p2[2] - start[2]);
trace->endpos[0] = start[0]+delta[0]*trace->fraction*p2f;
trace->endpos[1] = start[1]+delta[1]*trace->fraction*p2f;
// if (IS_NAN(trace->endpos[2]))
// Con_Printf("Nanny\n");
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = 1;
trace->plane.dist = sectorm[j].floorheight-hull->clip_mins[2];
continue;
}
if (pointonplane[2] > sectorm[j].ceilingheight-hull->clip_maxs[2]) //whoops, started outside... ?
{
Con_Printf("Started in ceiling\n");
trace->allsolid = trace->startsolid = false;
trace->endpos[0] = pointonplane[0];
trace->endpos[1] = pointonplane[1];
trace->endpos[2] = sectorm[j].ceilingheight-hull->clip_maxs[2];
trace->fraction = fabs(trace->endpos[2] - start[2]) / fabs(p2[2] - start[2]);
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = -1;
trace->plane.dist = -(sectorm[j].ceilingheight-hull->clip_maxs[2]);
continue;
}
}
}
if (d2 < 0)
continue; //both points on the reverse side.
}
//line crosses plane.
v1 = &vertexesl[ld->vert[0]];
v2 = &vertexesl[ld->vert[1]];
if (d1<0) //back to front.
{
if (ld->sidedef[1] == 0xffff)
continue; //hack to allow them to pass
c1 = (d1+DIST_EPSILON) / (d1 - d2);
}
else
c1 = (d1-DIST_EPSILON) / (d1 - d2);
c2 = 1-c1;
pointonplane[0] = start[0]*c2 + p2[0]*c1;
if (pointonplane[0] > v1->xpos+DIST_EPSILON*2+hull->clip_maxs[0] && pointonplane[0] > v2->xpos+DIST_EPSILON*2+hull->clip_maxs[0])
continue;
if (pointonplane[0] < v1->xpos-DIST_EPSILON*2+hull->clip_mins[0] && pointonplane[0] < v2->xpos-DIST_EPSILON*2+hull->clip_mins[0])
continue;
pointonplane[1] = start[1]*c2 + p2[1]*c1;
if (pointonplane[1] > v1->ypos+DIST_EPSILON*2+hull->clip_maxs[1] && pointonplane[1] > v2->ypos+DIST_EPSILON*2+hull->clip_maxs[1])
continue;
if (pointonplane[1] < v1->ypos-DIST_EPSILON*2+hull->clip_mins[1] && pointonplane[1] < v2->ypos-DIST_EPSILON*2+hull->clip_mins[1])
continue;
pointonplane[2] = start[2]*c2 + p2[2]*c1;
if (ld->flags & LINEDEF_IMPASSABLE || ld->sidedef[1] == 0xffff) //unconditionally unpassable.
{ //unconditionally clipped.
}
else
{ //ensure that the side we are passing on to passes the clip (no ceiling/floor clips happened first)
msector_t *sec2;
if (d1<0)
sec2 = &sectorm[sidedefsm[ld->sidedef[1]].sector];
else
sec2 = &sectorm[sidedefsm[ld->sidedef[0]].sector];
if (pointonplane[2] < sec2->floorheight-hull->clip_mins[2])
{ //hit the floor first.
c1 = fabs(sectorm[sec1].floorheight-hull->clip_mins[2] - start[2]);
c2 = fabs(p2[2] - start[2]);
if (!c2)
c1 = 1;
else
c1 = (c1-DIST_EPSILON) / c2;
if (trace->fraction > c1)
{
// Con_Printf("Hit floor\n");
trace->fraction = c1;
trace->allsolid = trace->startsolid = true;
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = 1;
trace->plane.dist = sectorm[sec1].floorheight-hull->clip_mins[2];
}
continue;
}
if (pointonplane[2] > sec2->ceilingheight-hull->clip_maxs[2])
{ //hit the floor first.
c1 = fabs((sectorm[sec1].ceilingheight-hull->clip_maxs[2]) - start[2]);
c2 = fabs(p2[2] - start[2]);
if (!c2)
c1 = 1;
else
c1 = (c1-DIST_EPSILON) / c2;
if (trace->fraction > c1)
{
// Con_Printf("Hit ceiling\n");
trace->fraction = c1;
trace->allsolid = trace->startsolid = true;
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = -1;
trace->plane.dist = -(sectorm[sec1].ceilingheight-hull->clip_maxs[2]);
}
continue;
}
if (d1<0)
sec2 = &sectorm[sidedefsm[ld->sidedef[0]].sector];
else
sec2 = &sectorm[sidedefsm[ld->sidedef[1]].sector];
if(sec2->ceilingheight == sec2->floorheight)
sec2->ceilingheight += 64;
if (pointonplane[2] > sec2->floorheight-hull->clip_mins[2] &&
pointonplane[2] < sec2->ceilingheight-hull->clip_maxs[2])
{
Con_Printf("Two sided passed\n");
continue;
}
// Con_Printf("blocked by two sided line\n");
// sec2->floorheight--;
}
if (d1<0) //back to front.
c1 = (d1+DIST_EPSILON) / (d1 - d2);
else
c1 = (d1-DIST_EPSILON) / (d1 - d2);
clipfrac = c1;
if (clipfrac < 0)
clipfrac = 0;
if (clipfrac > 1)
clipfrac = 1;
if (trace->fraction > clipfrac)
{
trace->fraction = clipfrac;
VectorMA(pointonplane, 0, lp->normal, trace->endpos);
VectorMA(trace->endpos, -0.1, delta, trace->endpos);
// if (IS_NAN(trace->endpos[2]))
// Con_Printf("Buggy clipping\n");
VectorCopy(lp->normal, trace->plane.normal);
trace->plane.dist = planedist;
// if (IS_NAN(trace->plane.normal[2]))
// Con_Printf("Buggy clipping\n");
if (clipfrac)
Con_Printf("Clip Wall %f\n", clipfrac);
}
}
obmi = bmi;
}
p1f += TRACESTEP;
if (p1f >= p2f)
break;
VectorMA(p1, TRACESTEP, delta, p1);
}
// VectorMA(start, p2f*trace->fraction, delta, p2);
if (p2[2] != start[2])
{
if (sec1 == Doom_SectorNearPoint(p2)) //special test.
{
if (p2[2] <= sectorm[sec1].floorheight-hull->clip_mins[2]) //whoops, started outside... ?
{
p1f = fabs(sectorm[sec1].floorheight-hull->clip_mins[2] - start[2]);
p2f = fabs(p2[2] - start[2]);
if (!p2f)
c1 = 1;
else
c1 = (p1f-DIST_EPSILON) / p2f;
if (trace->fraction > c1)
{
trace->fraction = c1;
trace->allsolid = trace->startsolid = false;
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = 1;
trace->plane.dist = sectorm[sec1].floorheight-hull->clip_mins[2];
}
// if (IS_NAN(trace->endpos[2]))
// Con_Printf("Nanny\n");
}
if (p2[2] >= sectorm[sec1].ceilingheight-hull->clip_maxs[2]) //whoops, started outside... ?
{
p1f = fabs(sectorm[sec1].ceilingheight-hull->clip_maxs[2] - start[2]);
p2f = fabs(p2[2] - start[2]);
if (!p2f)
c1 = 1;
else
c1 = (p1f-DIST_EPSILON) / p2f;
if (trace->fraction > c1)
{
trace->fraction = c1;
trace->allsolid = trace->startsolid = false;
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
trace->plane.normal[0] = 0;
trace->plane.normal[1] = 0;
trace->plane.normal[2] = -1;
trace->plane.dist = -(sectorm[sec1].ceilingheight-hull->clip_maxs[2]);
}
// if (IS_NAN(trace->endpos[2]))
// Con_Printf("Nanny\n");
}
}
}
//we made it all the way through. yay.
trace->allsolid = trace->startsolid = false;
//Con_Printf("total = %f\n", trace->fraction);
return trace->fraction==1;
#endif
}
@ -130,7 +727,11 @@ typedef struct
shader_t *shader;
unsigned short width;
unsigned short height;
batch_t *batch;
batch_t batch;
mesh_t *meshptr;
mesh_t mesh;
int maxverts;
int maxindicies;
} gldoomtexture_t;
gldoomtexture_t *gldoomtextures;
int numgldoomtextures;
@ -138,9 +739,11 @@ int numgldoomtextures;
static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float frontfloor, float x2, float y2, float backfloor, qboolean unpegged, unsigned int colour4b)
{
gldoomtexture_t *tex = gldoomtextures+texnum;
mesh_t *mesh = &tex->mesh;
float len = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
float s1, s2;
float t1, t2;
unsigned int col;
s1 = s/tex->width;
s2 = s1 + len/tex->width;
@ -156,21 +759,44 @@ static void GLR_DrawWall(int texnum, int s, int t, float x1, float y1, float fro
t2 = t1 + (backfloor-frontfloor)/tex->height;
}
if (mesh->numvertexes+4 > tex->maxverts)
{
tex->maxverts = mesh->numvertexes+4;
mesh->colors4b_array = BZ_Realloc(mesh->colors4b_array, sizeof(*mesh->colors4b_array) * tex->maxverts);
mesh->xyz_array = BZ_Realloc(mesh->xyz_array, sizeof(*mesh->xyz_array) * tex->maxverts);
mesh->st_array = BZ_Realloc(mesh->st_array, sizeof(*mesh->st_array) * tex->maxverts);
}
if (mesh->numindexes+6 > tex->maxindicies)
{
tex->maxindicies = mesh->numvertexes+6;
mesh->indexes = BZ_Realloc(mesh->colors4b_array, sizeof(*mesh->indexes) * tex->maxindicies);
}
#if 0
GL_Bind(tex->gltexture);
col = colour4b * 0x01010101;
((unsigned int*)&col)[3] = 0xff;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+0] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+1] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+2] = col;
*(unsigned int*)mesh->colors4b_array[mesh->numvertexes+3] = col;
VectorSet(mesh->xyz_array[mesh->numvertexes+0], x1, y1, frontfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+1], x1, y1, backfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+2], x2, y2, backfloor);
VectorSet(mesh->xyz_array[mesh->numvertexes+3], x2, y2, frontfloor);
Vector2Set(mesh->st_array[mesh->numvertexes+0], s1, t2);
Vector2Set(mesh->st_array[mesh->numvertexes+0], s1, t1);
Vector2Set(mesh->st_array[mesh->numvertexes+0], s2, t1);
Vector2Set(mesh->st_array[mesh->numvertexes+0], s2, t2);
qglBegin(GL_QUADS);
qglTexCoord2f(s1, t2);
qglVertex3f(x1, y1, frontfloor);
qglTexCoord2f(s1, t1);
qglVertex3f(x1, y1, backfloor);
qglTexCoord2f(s2, t1);
qglVertex3f(x2, y2, backfloor);
qglTexCoord2f(s2, t2);
qglVertex3f(x2, y2, frontfloor);
qglEnd();
#endif
mesh->indexes[mesh->numindexes+0] = mesh->numvertexes;
mesh->indexes[mesh->numindexes+1] = mesh->numvertexes;
mesh->indexes[mesh->numindexes+2] = mesh->numvertexes;
mesh->indexes[mesh->numindexes+0] = mesh->numvertexes;
mesh->indexes[mesh->numindexes+2] = mesh->numvertexes;
mesh->indexes[mesh->numindexes+3] = mesh->numvertexes;
mesh->numvertexes += 4;
mesh->numindexes += 6;
}
static void GLR_DrawSSector(unsigned int ssec)
@ -404,7 +1030,8 @@ void GLR_DoomWorld(void)
r_visframecount++;
GLR_RecursiveDoomNode(nodec-1);
}
#endif
//find the first ssector, go through it's list/
//grab the lines into multiple arrays.
@ -420,8 +1047,6 @@ void GLR_DoomWorld(void)
//pick a point, follow along the walls making a triangle fan, until an angle of > 180, throw out fan, rebuild arrays.
//at new point, start a new fan. Be prepared to not be able to generate one.
#ifdef GLQUAKE
#define MAX_REGIONS 256
#define MAX_POLYVERTS (MAX_FLATTRIS*3)
#define MAX_FLATTRIS 1024
@ -647,7 +1272,6 @@ static unsigned short *Triangulate_Finish(int *numtris, unsigned short *old, int
return out;
}
#endif
static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
{
@ -656,7 +1280,6 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
sectorm = Z_Malloc(sectorc * sizeof(*sectorm));
#ifdef GLQUAKE
if (glbspinuse)
{
for (i = 0; i < ssectorsc; i++)
@ -700,7 +1323,7 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
sectorm[sec].flats = Triangulate_Finish(&sectorm[sec].numflattris, sectorm[sec].flats, sectorm[sec].numflattris);
}
}
#endif
/*
for (i = 0; i < ssectorsc; i++)
{ //only do linedefs.
@ -723,10 +1346,8 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
for (i = 0; i < sectorc; i++)
{
#ifdef GLQUAKE
sectorm[i].ceilingtex = Doom_LoadFlat(sectorl[i].ceilingtexture);
sectorm[i].floortex = Doom_LoadFlat(sectorl[i].floortexture);
#endif
sectorm[i].lightlev = sectorl[i].lightlevel;
sectorm[i].specialtype = sectorl[i].specialtype;
sectorm[i].tag = sectorl[i].tag;
@ -734,6 +1355,7 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse)
sectorm[i].floorheight = sectorl[i].floorheight;
}
}
#ifndef SERVERONLY
static void *textures1;
static void *textures2;
@ -899,7 +1521,7 @@ static int Doom_LoadPatch(char *name)
strncpy(gldoomtextures[texnum].name, name, 8);
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\n}\n}\n");
gldoomtextures[texnum].shader = R_RegisterShader(name, "{\n{\nmap $diffuse\nrgbgen vertex\n}\n}\n");
if (textures1)
{
@ -916,8 +1538,25 @@ static int Doom_LoadPatch(char *name)
//all else failed.
gldoomtextures[texnum].width = image_width;
gldoomtextures[texnum].height = image_height;
gldoomtextures[texnum].meshptr = &gldoomtextures[texnum].mesh;
gldoomtextures[texnum].batch.mesh = &gldoomtextures[texnum].meshptr;
gldoomtextures[texnum].batch.next = loadmodel->batches[gldoomtextures[texnum].shader->sort];
loadmodel->batches[gldoomtextures[texnum].shader->sort] = &gldoomtextures[texnum].batch;
return texnum;
}
static void Doom_Purge (struct model_s *mod)
{
int texnum;
for (texnum = 0; texnum < numgldoomtextures; texnum++)
{
BZ_Free(gldoomtextures[texnum].mesh.colors4b_array);
BZ_Free(gldoomtextures[texnum].mesh.st_array);
BZ_Free(gldoomtextures[texnum].mesh.xyz_array);
BZ_Free(gldoomtextures[texnum].mesh.indexes);
}
BZ_Free(gldoomtextures);
gldoomtextures = NULL;
}
#endif
static void CleanWalls(dsidedef_t *sidedefsl)
{
@ -1046,7 +1685,7 @@ void QuakifyThings(dthing_t *thingsl)
point[1] = thingsl[i].ypos;
point[2] = 0;
sector = Doom_SectorNearPoint(point);
zpos = sectorm[sector].floorheight + 24;
zpos = sectorm[sector].floorheight + 24; //things have no z coord, so find the sector they're in
spawnflags = SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_DEATHMATCH;
if (thingsl[i].flags & THING_EASY)
@ -1424,34 +2063,38 @@ void Doom_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec
res_ambient[2] = sec->lightlev;
}
//return pvs bits for point
unsigned int Doom_FatPVS(struct model_s *model, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean merge)
{
//FIXME: use REJECT lump.
return 0;
}
//check if an ent is within the given pvs
qboolean Doom_EdictInFatPVS(struct model_s *model, struct pvscache_s *edict, qbyte *pvsbuffer)
{ //FIXME: use REJECT lump.
return true;
}
//generate useful info for correct functioning of Doom_EdictInFatPVS.
void Doom_FindTouchedLeafs(struct model_s *model, struct pvscache_s *ent, vec3_t cullmins, vec3_t cullmaxs)
{
//work out the sectors this ent is in for easy pvs.
}
//requires lightmaps - not supported.
void Doom_StainNode(struct mnode_s *node, float *parms)
{
//not supported
}
//requires lightmaps - not supported.
void Doom_MarkLights(struct dlight_s *light, int bit, struct mnode_s *node)
{
//not supported
}
void Doom_SetModelFunc(model_t *mod)
{
//mod->funcs.PurgeModel = ;
mod->funcs.PurgeModel = Doom_Purge;
mod->funcs.FatPVS = Doom_FatPVS;
mod->funcs.EdictInFatPVS = Doom_EdictInFatPVS;
@ -1463,7 +2106,10 @@ void Doom_SetModelFunc(model_t *mod)
// mod->funcs.LeafPVS) (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize);
Doom_SetCollisionFuncs(mod);
mod->funcs.NativeTrace = Doom_Trace;
mod->funcs.PointContents = Doom_PointContents;
//Doom_SetCollisionFuncs(mod);
}
#endif

View File

@ -73,6 +73,7 @@ void ClearBounds (vec3_t mins, vec3_t maxs);
#define GLclampd GLclampf
#define GLdouble GLfloat
#define GL_CLAMP GL_CLAMP_TO_EDGE
#define GL_NONE 0
#define GL_FILL (Sys_Error("GL_FILL was used"),0)
#define GL_QUADS (Sys_Error("GL_QUADS was used"),0)
@ -153,6 +154,7 @@ qboolean GL_CheckExtension(char *extname);
typedef struct {
float glversion;
int maxglslversion;
qboolean nofixedfunc;
qboolean gles;
qboolean tex_env_combine;
@ -332,7 +334,7 @@ void FTE_DEPRECATED R_IBrokeTheArrays(void);
//
#ifdef GLQUAKE
texid_tf GL_LoadPicTexture (qpic_t *pic);
void GL_Set2D (void);
void GL_Set2D (qboolean flipped);
#endif
//
@ -832,7 +834,7 @@ extern FTEPFNGLUNIFORM1IARBPROC qglUniform1iARB;
extern FTEPFNGLUNIFORM1FARBPROC qglUniform1fARB;
//glslang helper api
GLhandleARB GLSlang_CreateProgram(char *name, int ver, char **precompilerconstants, char *vert, char *frag);
GLhandleARB GLSlang_CreateProgram(char *name, int ver, char **precompilerconstants, char *vert, char *frag, qboolean silent);
GLint GLSlang_GetUniformLocation (int prog, char *name);
void GL_SelectProgram(int program);
#define GLSlang_UseProgram(prog) GL_SelectProgram(prog)

View File

@ -61,7 +61,7 @@ vec_t CastRay (vec3_t p1, vec3_t p2)
trace_t trace;
vec3_t move;
lightmodel->funcs.Trace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, &trace);
lightmodel->funcs.NativeTrace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &trace);
if (trace.fraction < 1)
return -1;

View File

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

View File

@ -358,7 +358,7 @@ reeval:
case OP_MULSTORE_F: // f *= f
OPB->_float *= OPA->_float;
break;
case OP_MULSTORE_V: // v *= f
case OP_MULSTORE_VF: // v *= f
OPB->_vector[0] *= OPA->_float;
OPB->_vector[1] *= OPA->_float;
OPB->_vector[2] *= OPA->_float;
@ -372,7 +372,7 @@ reeval:
ptr = QCPOINTER(OPB);
OPC->_float = (ptr->_float *= OPA->_float);
break;
case OP_MULSTOREP_V: // e.v *= f
case OP_MULSTOREP_VF: // e.v *= f
if ((unsigned int)OPB->_int >= addressableused)
{
pr_xstatement = st-pr_statements;
@ -866,7 +866,7 @@ reeval:
i = (int)OPB->_float;
if(i < 0 || i > ((eval_t *)&glob[st->a-1])->_int)
{
PR_RunError(progfuncs, "array index out of bounds: %s[%d]", PR_GlobalStringNoContents(progfuncs, st->a), i);
PR_RunError(progfuncs, "array index out of bounds: %s[%d] (max %d)", PR_GlobalStringNoContents(progfuncs, st->a), i, ((eval_t *)&glob[st->a-1])->_int);
}
t = (eval_t *)&pr_globals[(uofs)st->a + i];
OPC->_int = t->_int;

View File

@ -112,9 +112,9 @@ enum qcop_e {
//these following ones are Hexen 2 constants.
OP_MULSTORE_F,
OP_MULSTORE_V,
OP_MULSTORE_VF,
OP_MULSTOREP_F,
OP_MULSTOREP_V,
OP_MULSTOREP_VF,
OP_DIVSTORE_F, //70
OP_DIVSTOREP_F,
@ -350,7 +350,10 @@ enum qcop_e {
OP_SUBSTORE_FI,
OP_SUBSTOREP_FI,
OP_NUMOPS //246
OP_MULSTORE_VI,
OP_MULSTOREP_VI,
OP_NUMOPS
};
#define MAX_PARMS 8

View File

@ -492,6 +492,8 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
if (assignment)
{
assignment++;
while(*assignment == ' ')
assignment++;
switch (type&~DEF_SAVEGLOBAL)
{
case ev_string:
@ -499,7 +501,10 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
break;
case ev_float:
*(float *)val = (float)atof (assignment);
if (assignment[0] == '0' && (assignment[1] == 'x' || assignment[1] == 'X'))
*(float*)val = strtoul(assignment, NULL, 0);
else
*(float *)val = (float)atof (assignment);
break;
case ev_integer:

View File

@ -373,7 +373,7 @@ typedef union QCC_eval_s
const extern unsigned int type_size[];
//extern QCC_def_t *def_for_type[9];
extern QCC_type_t *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_integer, *type_variant, *type_floatfield;
extern QCC_type_t *type_void, *type_string, *type_float, *type_vector, *type_entity, *type_field, *type_function, *type_pointer, *type_floatpointer, *type_intpointer, *type_integer, *type_variant, *type_floatfield;
struct QCC_function_s
{
@ -484,6 +484,7 @@ extern pbool flag_fasttrackarrays;
extern pbool flag_assume_integer;
extern pbool flag_msvcstyle;
extern pbool flag_filetimes;
extern pbool flag_typeexplicit;
extern pbool opt_overlaptemps;
extern pbool opt_shortenifnots;

View File

@ -78,6 +78,7 @@ pbool flag_fasttrackarrays; //Faster arrays, dynamically detected, activated onl
pbool flag_msvcstyle; //MSVC style warnings, so msvc's ide works properly
pbool flag_assume_integer; //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead?
pbool flag_filetimes;
pbool flag_typeexplicit; //no implicit type conversions, you must do the casts yourself.
pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
pbool opt_assignments; //STORE_F isn't used if an operation wrote to a temp.
@ -293,9 +294,9 @@ QCC_opcode_t pr_opcodes[] =
//these are hexen2
{7, "*=", "MULSTORE_F", 6, ASSOC_RIGHT_RESULT, &type_float, &type_float, &type_float},
{7, "*=", "MULSTORE_V", 6, ASSOC_RIGHT_RESULT, &type_vector, &type_float, &type_vector},
{7, "*=", "MULSTORE_VF", 6, ASSOC_RIGHT_RESULT, &type_vector, &type_float, &type_vector},
{7, "*=", "MULSTOREP_F", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_float},
{7, "*=", "MULSTOREP_V", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_vector},
{7, "*=", "MULSTOREP_VF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_vector},
{7, "/=", "DIVSTORE_F", 6, ASSOC_RIGHT_RESULT, &type_float, &type_float, &type_float},
{7, "/=", "DIVSTOREP_F", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_float},
@ -522,23 +523,26 @@ QCC_opcode_t pr_opcodes[] =
{7, "+=", "ADDSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_integer},
{7, "-=", "SUBSTOREP_I", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_integer},
{7, "*=", "OP_MULSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "*=", "OP_MULSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "/=", "OP_DIVSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "/=", "OP_DIVSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "+=", "OP_ADDSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "+=", "OP_ADDSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "-=", "OP_SUBSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "-=", "OP_SUBSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_float, &type_integer},
{7, "*=", "MULSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_float, &type_float},
{7, "*=", "MULSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_intpointer, &type_float, &type_float},
{7, "/=", "DIVSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_float, &type_float},
{7, "/=", "DIVSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_intpointer, &type_float, &type_float},
{7, "+=", "ADDSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_float, &type_float},
{7, "+=", "ADDSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_intpointer, &type_float, &type_float},
{7, "-=", "SUBSTORE_IF", 6, ASSOC_RIGHT_RESULT, &type_integer, &type_float, &type_float},
{7, "-=", "SUBSTOREP_IF", 6, ASSOC_RIGHT_RESULT, &type_intpointer, &type_float, &type_float},
{7, "*=", "OP_MULSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "*=", "OP_MULSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "/=", "OP_DIVSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "/=", "OP_DIVSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "+=", "OP_ADDSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "+=", "OP_ADDSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "-=", "OP_SUBSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "-=", "OP_SUBSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_float},
{7, "*=", "MULSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_float, &type_integer, &type_float},
{7, "*=", "MULSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_floatpointer, &type_integer, &type_float},
{7, "/=", "DIVSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_float, &type_integer, &type_float},
{7, "/=", "DIVSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_floatpointer, &type_integer, &type_float},
{7, "+=", "ADDSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_float, &type_integer, &type_float},
{7, "+=", "ADDSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_floatpointer, &type_integer, &type_float},
{7, "-=", "SUBSTORE_FI", 6, ASSOC_RIGHT_RESULT, &type_float, &type_integer, &type_float},
{7, "-=", "SUBSTOREP_FI", 6, ASSOC_RIGHT_RESULT, &type_floatpointer, &type_integer, &type_float},
{7, "*=", "MULSTORE_VI", 6, ASSOC_RIGHT_RESULT, &type_vector, &type_integer, &type_vector},
{7, "*=", "MULSTOREP_VI", 6, ASSOC_RIGHT_RESULT, &type_pointer, &type_integer, &type_vector},
{0, NULL}
};
@ -656,11 +660,17 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
&pr_opcodes[OP_MUL_F],
&pr_opcodes[OP_MUL_V],
&pr_opcodes[OP_MUL_FV],
&pr_opcodes[OP_MUL_IV],
&pr_opcodes[OP_MUL_VF],
&pr_opcodes[OP_MUL_VI],
&pr_opcodes[OP_MUL_I],
&pr_opcodes[OP_MUL_FI],
&pr_opcodes[OP_MUL_IF],
&pr_opcodes[OP_DIV_F],
&pr_opcodes[OP_DIV_I],
&pr_opcodes[OP_DIV_FI],
&pr_opcodes[OP_DIV_IF],
&pr_opcodes[OP_DIV_VF],
&pr_opcodes[OP_BITAND_F],
@ -764,12 +774,14 @@ QCC_opcode_t *opcodeprioritized[TOP_PRIORITY+1][128] =
&pr_opcodes[OP_DIVSTOREP_IF],
&pr_opcodes[OP_DIVSTOREP_FI],
&pr_opcodes[OP_MULSTORE_F],
&pr_opcodes[OP_MULSTORE_V],
&pr_opcodes[OP_MULSTORE_VF],
&pr_opcodes[OP_MULSTORE_VI],
&pr_opcodes[OP_MULSTORE_I],
&pr_opcodes[OP_MULSTORE_IF],
&pr_opcodes[OP_MULSTORE_FI],
&pr_opcodes[OP_MULSTOREP_F],
&pr_opcodes[OP_MULSTOREP_V],
&pr_opcodes[OP_MULSTOREP_VF],
&pr_opcodes[OP_MULSTOREP_VI],
&pr_opcodes[OP_MULSTOREP_I],
&pr_opcodes[OP_MULSTOREP_IF],
&pr_opcodes[OP_MULSTOREP_FI],
@ -1010,9 +1022,9 @@ pbool QCC_OPCodeValid(QCC_opcode_t *op)
return false; //DPFIXME: dp's bounds check may give false positives with expected uses.
case OP_MULSTORE_F:
case OP_MULSTORE_V:
case OP_MULSTORE_VF:
case OP_MULSTOREP_F:
case OP_MULSTOREP_V: // e.v *= f
case OP_MULSTOREP_VF: // e.v *= f
case OP_DIVSTORE_F:
case OP_DIVSTOREP_F:
case OP_STORE_IF:
@ -1134,7 +1146,7 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal)
if (pr_classtype)
{ //load self.var into a temp
QCC_def_t *self;
self = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
self = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
switch(wanted)
{
case ev_float:
@ -1157,6 +1169,8 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted, pbool fatal)
if (o == 0) //type already matches
return var;
if (flag_typeexplicit)
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, var, "Implicit type mismatch. Needed %s, got %s.", basictypenames[wanted], var->type->name);
if (o < 0)
{
if (fatal)
@ -1515,7 +1529,7 @@ static void QCC_fprintfLocals(FILE *f, gofs_t paramstart, gofs_t paramend)
{
if (var->ofs >= paramstart && var->ofs < paramend)
continue;
if (var->arraysize != 1)
if (var->arraysize)
fprintf(f, "local %s %s[%i];\n", TypeName(var->type), var->name, var->arraysize);
else
fprintf(f, "local %s %s;\n", TypeName(var->type), var->name);
@ -2097,7 +2111,7 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
switch(op - pr_opcodes)
{
case OP_IF_S:
var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 1, false);
var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
numstatements--;
var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
statement = &statements[numstatements];
@ -2108,7 +2122,7 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
break;
case OP_IFNOT_S:
var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 1, false);
var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
numstatements--;
var_a = QCC_PR_Statement(&pr_opcodes[OP_NE_S], var_a, var_c, NULL);
statement = &statements[numstatements];
@ -2251,13 +2265,20 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
var_c = var_a;
break;
case OP_MULSTORE_V:
case OP_MULSTORE_VF:
op = &pr_opcodes[OP_MUL_VF];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_MULSTORE_VI:
op = &pr_opcodes[OP_MUL_VI];
var_c = var_b;
var_b = var_a;
var_a = var_c;
var_c = var_a;
break;
case OP_BITSET_I:
op = &pr_opcodes[OP_BITOR_I];
@ -2304,7 +2325,8 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
case OP_DIVSTOREP_FI:
case OP_DIVSTOREP_IF:
case OP_MULSTOREP_V:
case OP_MULSTOREP_VF:
case OP_MULSTOREP_VI:
case OP_SUBSTOREP_V:
case OP_ADDSTOREP_V:
@ -2365,9 +2387,12 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
case OP_ADDSTOREP_V:
statement->op = OP_ADD_V;
break;
case OP_MULSTOREP_V:
case OP_MULSTOREP_VF:
statement->op = OP_MUL_VF;
break;
case OP_MULSTOREP_VI:
statement->op = OP_MUL_VI;
break;
case OP_SUBSTOREP_F:
statement->op = OP_SUB_F;
break;
@ -2887,7 +2912,7 @@ QCC_def_t *QCC_PR_GenerateFunctionCall (QCC_def_t *func, QCC_def_t *arglist[], i
//FIXME: problems could occur with hexen2 calling conventions when parm0/1 is 'self'
//thiscall. copy the right ent into 'self' (if it's not the same offset)
d = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
d = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
if (statements[laststatement-1].a != d->ofs)
{
oself = QCC_GetTemp(type_entity);
@ -3493,7 +3518,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
{
char genfunc[2048];
sprintf(genfunc, "Class*%s", rettype->name);
func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 1, false);
func = QCC_PR_GetDef(type_function, genfunc, NULL, true, 0, false);
func->references++;
}
QCC_PR_SimpleStatement(OP_CALL0, func->ofs, 0, 0, false);
@ -3641,7 +3666,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
if (pr_classtype && e->type->type == ev_field && p->type != ev_field)
{ //convert.
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 1, false);
oself = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
switch(e->type->aux_type->type)
{
case ev_string:
@ -3766,7 +3791,7 @@ QCC_def_t *QCC_MakeIntConst(int value)
cn->constant = true;
cn->initialized = 1;
cn->scope = NULL; // always share immediates
cn->arraysize = 1;
cn->arraysize = 0;
if (!value)
G_INT(cn->ofs) = 0;
@ -3818,7 +3843,7 @@ QCC_def_t *QCC_MakeVectorConst(float a, float b, float c)
cn->constant = true;
cn->initialized = 1;
cn->scope = NULL; // always share immediates
cn->arraysize = 1;
cn->arraysize = 0;
// copy the immediate to the global area
cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_vector->type]);
@ -3859,7 +3884,7 @@ QCC_def_t *QCC_MakeFloatConst(float value)
cn->constant = true;
cn->initialized = 1;
cn->scope = NULL; // always share immediates
cn->arraysize = 1;
cn->arraysize = 0;
// copy the immediate to the global area
cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
@ -3905,7 +3930,7 @@ static QCC_def_t *QCC_MakeStringConstInternal(char *value, pbool translate)
cn->constant = true;
cn->initialized = 1;
cn->scope = NULL; // always share immediates
cn->arraysize = 1;
cn->arraysize = 0;
// copy the immediate to the global area
cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]);
@ -4011,7 +4036,7 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
f = QCC_MemberInParentClass(mt->name, clas->parentclass);
if (f)
{
if (m->arraysize>1)
if (m->arraysize)
QCC_Error(ERR_INTERNAL, "FTEQCC does not support overloaded arrays of members");
a=0;
for (o = 0; o < m->type->size; o++)
@ -4019,7 +4044,7 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
continue;
}
for (a = 0; a < m->arraysize; a++)
for (a = 0; a < (m->arraysize?m->arraysize:1); a++)
{
/*if it was already set, don't go recursive and generate 500 fields for a one-member class that was intheritted from 500 times*/
if (((int *)qcc_pr_globals)[o+a*mt->size+m->ofs])
@ -4032,7 +4057,7 @@ void QCC_PR_EmitFieldsForMembers(QCC_type_t *clas)
ft->size = ft->aux_type->size;
ft = QCC_PR_FindType(ft);
sprintf(membername, "__f_%s_%i", ft->name, ++basictypefield[mt->type]);
f = QCC_PR_GetDef(ft, membername, NULL, true, 1, true);
f = QCC_PR_GetDef(ft, membername, NULL, true, 0, true);
for (o = 0; o < m->type->size; o++)
((int *)qcc_pr_globals)[o+a*mt->size+m->ofs] = ((int *)qcc_pr_globals)[o+f->ofs];
@ -4071,7 +4096,7 @@ void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_
if (type->type == ev_function) //FIXME: inheritance will not install all the member functions.
{
sprintf(membername, "%s::"MEMBERFIELDNAME, clas->name, type->name);
member = QCC_PR_GetDef(NULL, membername, NULL, false, 1, false);
member = QCC_PR_GetDef(NULL, membername, NULL, false, 0, false);
if (!member)
{
QCC_PR_Warning(0, NULL, 0, "Member function %s was not defined", membername);
@ -4083,7 +4108,7 @@ void QCC_PR_EmitClassFunctionTable(QCC_type_t *clas, QCC_type_t *childclas, QCC_
}
point = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], ed, member, NULL);
sprintf(membername, "%s::%s", clas->name, type->name);
virt = QCC_PR_GetDef(type, membername, NULL, false, 1, false);
virt = QCC_PR_GetDef(type, membername, NULL, false, 0, false);
QCC_PR_Statement(&pr_opcodes[OP_STOREP_FNC], virt, point, NULL);
}
}
@ -4131,7 +4156,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
G_FUNCTION(scope->ofs) = df - functions;
//locals here...
ed = QCC_PR_GetDef(type_entity, "ent", pr_scope, true, 1, false);
ed = QCC_PR_GetDef(type_entity, "ent", pr_scope, true, 0, false);
virt = QCC_PR_GetDef(type_function, "spawn", NULL, false, 0, false);
if (!virt)
@ -4148,7 +4173,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, char *tname)
if (constructor)
{ //self = ent;
self = QCC_PR_GetDef(type_entity, "self", NULL, false, 0, false);
oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 1, false);
oself = QCC_PR_GetDef(type_entity, "oself", scope, true, 0, false);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], self, oself, NULL));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], ed, self, NULL)); //return to our old self. boom boom.
QCC_PR_SimpleStatement(OP_CALL0, constructor->ofs, 0, 0, false);
@ -4237,26 +4262,26 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
(!strcmp(name, "entnum")) ||
(!strcmp(name, "_"))) //intrinsics, any old function with no args will do.
{
d = QCC_PR_GetDef (type_function, name, NULL, true, 1, false);
d = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
d->initialized = 0;
}
else if (keyword_class && !strcmp(name, "this"))
{
if (!pr_classtype)
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'this' outside of an OO function\n");
od = QCC_PR_GetDef(NULL, "self", NULL, true, 1, false);
d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 1, od->ofs, true, false);
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
d = QCC_PR_DummyDef(pr_classtype, "this", pr_scope, 0, od->ofs, true, false);
}
else if (keyword_class && !strcmp(name, "super"))
{
if (!pr_classtype)
QCC_PR_ParseError(ERR_NOTANAME, "Cannot use 'super' outside of an OO function\n");
od = QCC_PR_GetDef(NULL, "self", NULL, true, 1, false);
d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 1, od->ofs, true, false);
od = QCC_PR_GetDef(NULL, "self", NULL, true, 0, false);
d = QCC_PR_DummyDef(pr_classtype, "super", pr_scope, 0, od->ofs, true, false);
}
else
{
d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 1, false);
d = QCC_PR_GetDef (type_variant, name, pr_scope, true, 0, false);
if (!d)
QCC_PR_ParseError (ERR_UNKNOWNVALUE, "Unknown value \"%s\"", name);
else
@ -4275,7 +4300,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
tmp = QCC_PR_Expression (TOP_PRIORITY, 0);
QCC_PR_Expect("]");
if (!idx && t->type == ev_pointer && d->arraysize == 1)
if (!idx && t->type == ev_pointer && !d->arraysize)
t = t->aux_type;
if (!idx && d->type->type == ev_pointer)
@ -4284,7 +4309,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
}
else if (tmp->constant)
{
int i;
unsigned int i;
if (tmp->type->type == ev_integer)
i = G_INT(tmp->ofs);
else if (tmp->type->type == ev_float)
@ -4314,7 +4339,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
}
else if ((t->type == ev_pointer || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
{
if (!idx && t->type == ev_pointer && d->arraysize == 1)
if (!idx && t->type == ev_pointer && !d->arraysize)
t = t->aux_type;
for (t = t->param; t; t = t->next)
@ -4422,7 +4447,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
d->references++;
tmp = (void *)qccHunkAlloc (sizeof(QCC_def_t));
memcpy (tmp, d, sizeof(QCC_def_t));
tmp->arraysize = 1;
tmp->arraysize = 0;
tmp->ofs = d->ofs + (cidx * type_size[d->type->type]);
d = tmp;
@ -4434,7 +4459,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
QCC_def_t *args[2], *funcretr, *rhs;
d->references++;
funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 1, false);
funcretr = QCC_PR_GetDef(type_function, qcva("ArraySet*%s", d->name), NULL, true, 0, false);
rhs = QCC_PR_Expression(TOP_PRIORITY, 0);
if (rhs->type->type != d->type->type)
@ -4448,28 +4473,34 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
}
else if (QCC_OPCodeValid(&pr_opcodes[OP_FETCH_GBL_F]))
{
if (!d->arraysize)
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on non-array");
if (d->temp)
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCH, d, "array lookup on a temp");
/*hexen2 format has opcodes to read arrays (but has no way to write)*/
switch(t->type)
{
case ev_float:
d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_F], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
st->a = d->ofs;
// st->a = d->ofs;
break;
case ev_vector:
d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_V], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
st->a = d->ofs;
// st->a = d->ofs;
break;
case ev_string:
d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_S], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
st->a = d->ofs;
// st->a = d->ofs;
break;
case ev_entity:
d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_E], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
st->a = d->ofs;
// st->a = d->ofs;
break;
case ev_function:
d = QCC_PR_Statement(&pr_opcodes[OP_FETCH_GBL_FNC], d, QCC_SupplyConversion(idx, ev_float, true), &st); //get pointer to precise def.
st->a = d->ofs;
// st->a = d->ofs;
break;
default:
QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
@ -4487,7 +4518,7 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
/*make sure the function type that we're calling exists*/
def_parms[0].type = type_float;
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 1, false);
funcretr = QCC_PR_GetDef(type_function, qcva("ArrayGet*%s", d->name), NULL, true, 0, false);
args[0] = QCC_SupplyConversion(idx, ev_float, true);
d = QCC_PR_GenerateFunctionCall(funcretr, args, 1);
@ -4793,8 +4824,12 @@ QCC_def_t *QCC_PR_Term (void)
QCC_PR_Expect (")");
e = QCC_PR_Expression (UNARY_PRIORITY, EXPR_DISALLOW_COMMA);
/*you may cast from a type to itself*/
if (!typecmp(e->type, newtype))
{
}
/*you may cast from const 0 to any type of same size for free (from either int or float for simplicity)*/
if (newtype->size == e->type->size && (e->type->type == ev_integer || e->type->type == ev_float) && e->constant && !G_INT(e->ofs))
else if (newtype->size == e->type->size && (e->type->type == ev_integer || e->type->type == ev_float) && e->constant && !G_INT(e->ofs))
{
}
/*cast from int->float will convert*/
@ -5007,8 +5042,8 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
if (pr_token_type == tt_immediate)
{
if (pr_immediate_type->type == ev_float)
if (pr_immediate._float < 0) //hehehe... was a minus all along...
if ((pr_immediate_type->type == ev_float && pr_immediate._float < 0) ||
(pr_immediate_type->type == ev_integer && pr_immediate._int < 0)) //hehehe... was a minus all along...
{
QCC_PR_IncludeChunk(pr_token, true, NULL);
strcpy(pr_token, "+");//two negatives would make a positive.
@ -5137,6 +5172,7 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
{//assignment
if (op->type_a == &type_pointer) //ent var
{
/*FIXME: I don't like this code*/
if (e->type->type != ev_pointer)
c = -200; //don't cast to a pointer.
else if ((*op->type_c)->type == ev_void && op->type_b == &type_pointer && e2->type->type == ev_pointer)
@ -5151,6 +5187,8 @@ QCC_def_t *QCC_PR_Expression (int priority, int exprflags)
c=QCC_canConv(e2, (*op->type_b)->type);
if (type_a != (*op->type_a)->type) //in this case, a is the final assigned value
c = -300; //don't use this op, as we must not change var b's type
else if ((*op->type_a)->type == ev_pointer && e->type->aux_type->type != (*op->type_a)->aux_type->type)
c = -300; //don't use this op if its a pointer to a different type
}
}
else
@ -5495,7 +5533,7 @@ void QCC_PR_ParseStatement (void)
{
e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), NULL));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
}*/
if (QCC_PR_CheckToken (";"))
@ -6439,7 +6477,7 @@ void QCC_PR_ParseState (void)
name = QCC_PR_ParseName ();
pr_scope = NULL;
def = QCC_PR_GetDef (type_function, name, NULL, true, 1, false);
def = QCC_PR_GetDef (type_function, name, NULL, true, 0, false);
pr_scope = sc;
QCC_PR_Expect ("]");
@ -6998,6 +7036,7 @@ void QCC_Marshal_Locals(int first, int laststatement)
{
QCC_def_t *local;
unsigned int newofs;
int size;
// if (!opt_overlaptemps) //clear these after each function. we arn't overlapping them so why do we need to keep track of them?
// {
@ -7033,9 +7072,11 @@ void QCC_Marshal_Locals(int first, int laststatement)
if (local->constant)
continue;
newofs += local->type->size*local->arraysize;
if (local->arraysize>1)
newofs++;
size = local->type->size*(local->arraysize?local->arraysize:1);
if (local->arraysize)
size++;
newofs += size;
}
locals_start = MAX_REGS;
@ -7052,12 +7093,14 @@ void QCC_Marshal_Locals(int first, int laststatement)
if (((int*)qcc_pr_globals)[local->ofs])
QCC_PR_ParseError(ERR_INTERNAL, "Marshall of a set value");
newofs -= local->type->size*local->arraysize;
if (local->arraysize>1)
newofs--;
size = local->type->size*(local->arraysize?local->arraysize:1);
if (local->arraysize)
size++;
QCC_RemapOffsets(first, laststatement, local->ofs, local->ofs+local->type->size*local->arraysize, newofs);
QCC_FreeOffset(local->ofs, local->type->size*local->arraysize);
newofs -= size;
QCC_RemapOffsets(first, laststatement, local->ofs, local->ofs+size, newofs);
QCC_FreeOffset(local->ofs, size);
local->ofs = newofs;
}
@ -7223,7 +7266,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
{
if (!*pr_parm_names[i])
QCC_PR_ParseError(ERR_PARAMWITHNONAME, "Parameter is not named");
defs[i] = QCC_PR_GetDef (parm, pr_parm_names[i], pr_scope, true, 1, false);
defs[i] = QCC_PR_GetDef (parm, pr_parm_names[i], pr_scope, true, 0, false);
defs[i]->references++;
if (i < MAX_PARMS)
@ -7268,9 +7311,9 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
/*if (pr_classtype)
{
QCC_def_t *e, *e2;
e = QCC_PR_GetDef(pr_classtype, "__oself", pr_scope, true, 1);
e2 = QCC_PR_GetDef(type_entity, "self", NULL, true, 1);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), e, NULL));
e = QCC_PR_GetDef(pr_classtype, "__oself", pr_scope, true, 0);
e2 = QCC_PR_GetDef(type_entity, "self", NULL, true, 0);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), e, NULL));
}*/
//
@ -7293,7 +7336,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
do {
name = QCC_PR_ParseName();
QCC_PR_Expect(":");
e2 = QCC_PR_GetDef(QCC_PR_ParseType(false, false), name, pr_scope, true, 1, false);
e2 = QCC_PR_GetDef(QCC_PR_ParseType(false, false), name, pr_scope, true, 0, false);
QCC_PR_Expect(";");
} while(!QCC_PR_CheckToken("{"));
}
@ -7358,7 +7401,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_type_t *type)
QCC_def_t *e, *e2;
e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 1, e2->ofs, false), NULL));
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
}*/
QCC_PR_Statement (pr_opcodes, 0,0, NULL);
@ -7476,7 +7519,7 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
QCC_dfunction_t *df;
QCC_def_t *temp, *index, *func;
func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 1, false);
func = QCC_PR_GetDef(type_function, qcva("ArrayGetVec*%s", array->name), NULL, true, 0, false);
pr_scope = func;
@ -7492,9 +7535,9 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_def_t *array)
df->parm_size[0] = 1;
df->numparms = 1;
df->parm_start = numpr_globals;
index = QCC_PR_GetDef(type_float, "index___", func, true, 1, false);
index = QCC_PR_GetDef(type_float, "index___", func, true, 0, false);
index->references++;
temp = QCC_PR_GetDef(type_float, "div3___", func, true, 1, false);
temp = QCC_PR_GetDef(type_float, "div3___", func, true, 0, false);
locals_end = numpr_globals;
df->locals = locals_end - df->parm_start;
QCC_PR_Statement3(pr_opcodes+OP_DIV_F, index, QCC_MakeFloatConst(3), temp, false);
@ -7522,7 +7565,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
QCC_def_t *fasttrackpossible;
if (flag_fasttrackarrays)
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 1, false);
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
else
fasttrackpossible = NULL;
@ -7549,7 +7592,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
df->parm_size[0] = 1;
df->numparms = 1;
df->parm_start = numpr_globals;
index = QCC_PR_GetDef(type_float, "indexg___", def, true, 1, false);
index = QCC_PR_GetDef(type_float, "indexg___", def, true, 0, false);
G_FUNCTION(scope->ofs) = df - functions;
@ -7578,8 +7621,8 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
//we need to work out which part, x/y/z that it's stored in.
//0,1,2 = i - ((int)i/3 *) 3;
div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 1, false);
intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 1, false);
div3 = QCC_PR_GetDef(type_float, "div3___", def, true, 0, false);
intdiv3 = QCC_PR_GetDef(type_float, "intdiv3___", def, true, 0, false);
eq = QCC_PR_Statement(pr_opcodes+OP_GE_F, index, QCC_MakeFloatConst((float)def->arraysize), NULL); //escape clause - should call some sort of error function instead.. that'd rule!
QCC_FreeTemp(QCC_PR_Statement(pr_opcodes+OP_IFNOT_I, eq, 0, &st));
@ -7594,7 +7637,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, char *arrayname)
QCC_PR_Statement3(pr_opcodes+OP_STORE_F, index, &def_parms[0], NULL, false);
QCC_PR_Statement3(pr_opcodes+OP_CALL1, vectortrick, NULL, NULL, false);
vectortrick->references++;
ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 1, false);
ret = QCC_PR_GetDef(type_vector, "vec__", pr_scope, true, 0, false);
ret->references+=4;
QCC_PR_Statement3(pr_opcodes+OP_STORE_V, &def_ret, ret, NULL, false);
QCC_FreeTemp(&def_ret);
@ -7686,7 +7729,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
QCC_def_t *fasttrackpossible;
if (flag_fasttrackarrays)
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 1, false);
fasttrackpossible = QCC_PR_GetDef(type_float, "__ext__fasttrackarrays", NULL, true, 0, false);
else
fasttrackpossible = NULL;
@ -7706,8 +7749,8 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, char *arrayname)
df->parm_size[1] = def->type->size;
df->numparms = 2;
df->parm_start = numpr_globals;
index = QCC_PR_GetDef(type_float, "indexs___", def, true, 1, false);
value = QCC_PR_GetDef(def->type, "value___", def, true, 1, false);
index = QCC_PR_GetDef(type_float, "indexs___", def, true, 0, false);
value = QCC_PR_GetDef(def->type, "value___", def, true, 0, false);
locals_end = numpr_globals;
df->locals = locals_end - df->parm_start;
@ -7781,7 +7824,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
KEYWORD(asm);
}
for (a = 0; a < arraysize; a++)
for (a = 0; a < (arraysize?arraysize:1); a++)
{
if (a == 0)
*array = '\0';
@ -7797,7 +7840,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
def = (void *)qccHunkAlloc (sizeof(QCC_def_t));
memset (def, 0, sizeof(*def));
def->next = NULL;
def->arraysize = arraysize;
def->arraysize = a?0:arraysize;
if (name)
{
pr.def_tail->next = def;
@ -7841,14 +7884,14 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
{
case ev_vector:
sprintf(newname, "%s%s.%s", name, array, parttype->name);
QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, saved);
QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
sprintf(newname, "%s%s.%s_x", name, array, parttype->name);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, false);
sprintf(newname, "%s%s.%s_y", name, array, parttype->name);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs+1, false, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+1, false, false);
sprintf(newname, "%s%s.%s_z", name, array, parttype->name);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a + parttype->ofs+2, false, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a + parttype->ofs+2, false, false);
break;
case ev_float:
@ -7861,12 +7904,12 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
case ev_union:
case ev_variant: //for lack of any better alternative
sprintf(newname, "%s%s.%s", name, array, parttype->name);
QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a + parttype->ofs, false, saved);
QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a + parttype->ofs, false, saved);
break;
case ev_function:
sprintf(newname, "%s%s.%s", name, array, parttype->name);
QCC_PR_DummyDef(parttype, newname, scope, 1, ofs + type->size*a +parttype->ofs, false, saved)->initialized = true;
QCC_PR_DummyDef(parttype, newname, scope, 0, ofs + type->size*a +parttype->ofs, false, saved)->initialized = true;
break;
case ev_void:
break;
@ -7877,11 +7920,11 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
else if (type->type == ev_vector)
{ //do the vector thing.
sprintf(newname, "%s%s_x", name, array);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+0, referable, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+0, referable, false);
sprintf(newname, "%s%s_y", name, array);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+1, referable, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+1, referable, false);
sprintf(newname, "%s%s_z", name, array);
QCC_PR_DummyDef(type_float, newname, scope, 1, ofs + type->size*a+2, referable, false);
QCC_PR_DummyDef(type_float, newname, scope, 0, ofs + type->size*a+2, referable, false);
}
else if (type->type == ev_field)
{
@ -7889,11 +7932,11 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
{
//do the vector thing.
sprintf(newname, "%s%s_x", name, array);
QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+0, referable, false);
QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+0, referable, false);
sprintf(newname, "%s%s_y", name, array);
QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+1, referable, false);
QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+1, referable, false);
sprintf(newname, "%s%s_z", name, array);
QCC_PR_DummyDef(type_floatfield, newname, scope, 1, ofs + type->size*a+2, referable, false);
QCC_PR_DummyDef(type_floatfield, newname, scope, 0, ofs + type->size*a+2, referable, false);
}
}
first->deftail = pr.def_tail;
@ -7903,7 +7946,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_def_t *scope, int a
{
if (!pHash_Get(&globalstable, "end_sys_fields"))
first->references++; //anything above needs to be left in, and so warning about not using it is just going to pee people off.
if (arraysize <= 1 && first->type->type != ev_field)
if (!arraysize && first->type->type != ev_field)
first->constant = false;
if (scope)
pHash_Add(&localstable, first->name, first, qccHunkAlloc(sizeof(bucket_t)));
@ -7923,6 +7966,9 @@ PR_GetDef
If type is NULL, it will match any type
If allocate is true, a new def will be allocated if it can't be found
If arraysize=0, its not an array and has 1 element.
If arraysize>0, its an array and requires array notation
If arraysize<0, its an array with undefined size - GetDef will fail if its not already allocated.
============
*/
@ -7934,6 +7980,9 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
unsigned int i;
QCC_def_t *foundstatic = NULL;
if (!allocate)
arraysize = -1;
if (scope)
{
def = Hash_Get(&localstable, name);
@ -7948,7 +7997,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
if (type && typecmp(def->type, type))
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
if (def->arraysize != arraysize && arraysize)
if (def->arraysize != arraysize && arraysize>=0)
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
if (allocate && scope)
{
@ -7984,7 +8033,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
if (!pr_scope)
QCC_PR_ParseErrorPrintDef (ERR_TYPEMISMATCHREDEC, def, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
}
if (def->arraysize != arraysize && arraysize)
if (def->arraysize != arraysize && arraysize>=0)
QCC_PR_ParseErrorPrintDef(ERR_TYPEMISMATCHARRAYSIZE, def, "Array sizes for redecleration of %s do not match",name);
if (allocate && scope)
{
@ -8018,7 +8067,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
if (type && typecmp(def->type, type))
QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
if (def->arraysize != arraysize && arraysize)
if (def->arraysize != arraysize && arraysize>=0)
QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
if (allocate && scope)
{
@ -8054,7 +8103,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
if (!pr_scope)
QCC_PR_ParseError (ERR_TYPEMISMATCHREDEC, "Type mismatch on redeclaration of %s. %s, should be %s",name, TypeName(type), TypeName(def->type));
}
if (def->arraysize != arraysize && arraysize)
if (def->arraysize != arraysize && arraysize>=0)
QCC_PR_ParseError (ERR_TYPEMISMATCHARRAYSIZE, "Array sizes for redecleration of %s do not match",name);
if (allocate && scope)
{
@ -8082,7 +8131,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
if (!allocate)
return NULL;
if (arraysize < 1)
if (arraysize < 0)
{
QCC_PR_ParseError (ERR_ARRAYNEEDSSIZE, "First declaration of array %s with no size",name);
}
@ -8094,7 +8143,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
}
ofs = numpr_globals;
if (arraysize > 1)
if (arraysize)
{ //write the array size
ofs = QCC_GetFreeOffsetSpace(1 + (type->size * arraysize));
@ -8102,14 +8151,14 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, QCC_def_t *scope, pbool
ofs++;
}
else
ofs = QCC_GetFreeOffsetSpace(type->size * arraysize);
ofs = QCC_GetFreeOffsetSpace(type->size);
def = QCC_PR_DummyDef(type, name, scope, arraysize, ofs, true, saved);
//fix up fields.
if (type->type == ev_field && allocate != 2)
{
for (i = 0; i < type->size*arraysize; i++) //make arrays of fields work.
for (i = 0; i < type->size*(arraysize?arraysize:1); i++) //make arrays of fields work.
*(int *)&qcc_pr_globals[def->ofs+i] = pr.size_fields+i;
pr.size_fields += i;
@ -8136,7 +8185,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
startfield = *fieldofs;
maxfield = startfield;
for (a = 0; a < arraysize; a++)
for (a = 0; a < (arraysize?arraysize:1); a++)
{
if (a == 0)
*array = '\0';
@ -8214,10 +8263,10 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
ftype->aux_type = parttype;
if (parttype->type == ev_vector)
ftype->size = parttype->size; //vector fields create a _y and _z too, so we need this still.
def = QCC_PR_GetDef(NULL, newname, scope, false, 1, saved);
def = QCC_PR_GetDef(NULL, newname, scope, false, 0, saved);
if (!def)
{
def = QCC_PR_GetDef(ftype, newname, scope, true, 1, saved);
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
}
else
{
@ -8233,7 +8282,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_def_t *scope,
sprintf(newname, "%s%s", parttype->name, array);
ftype = QCC_PR_NewType("FIELD TYPE", ev_field);
ftype->aux_type = parttype;
def = QCC_PR_GetDef(ftype, newname, scope, true, 1, saved);
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
def->initialized = true;
((int *)qcc_pr_globals)[def->ofs] = *fieldofs;
*fieldofs += parttype->size;
@ -8270,13 +8319,13 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
QCC_def_t *tmp;
int i;
if (arraysize > 1)
if (arraysize)
{
//arrays go recursive
QCC_PR_Expect("{");
for (i = 0; i < arraysize; i++)
{
QCC_PR_ParseInitializerType(1, def, type, offset + i*type->size);
QCC_PR_ParseInitializerType(0, def, type, offset + i*type->size);
if (!QCC_PR_CheckToken(","))
break;
}
@ -8377,12 +8426,31 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *def, QCC_type_t *type
{
QCC_def_t *dt;
sprintf(trname, "dotranslate_%i", ++dotranslate_count);
dt = QCC_PR_DummyDef(type_string, trname, pr_scope, 1, offset, true, true);
dt = QCC_PR_DummyDef(type_string, trname, pr_scope, 0, offset, true, true);
dt->references = 1;
dt->constant = 1;
dt->initialized = 1;
}
}
else if (type->type == ev_struct || type->type == ev_union)
{
//structs go recursive
QCC_type_t *parttype;
int partnum;
int parms;
pbool isunion;
QCC_PR_Expect("{");
isunion = ((type)->type == ev_union);
for (partnum = 0, parttype = (type)->param, parms = (type)->num_parms; partnum < parms; partnum++, parttype = parttype->next)
{
QCC_PR_ParseInitializerType(parttype->arraysize, def, parttype, offset + parttype->ofs);
if (isunion || !QCC_PR_CheckToken(","))
break;
}
QCC_PR_Expect("}");
return;
}
else
{
tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
@ -8736,7 +8804,7 @@ void QCC_PR_ParseDefs (char *classname)
if (accglobalsblock == 3)
{
if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 1, false);
QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
}
QCC_PR_ParseName();
@ -8755,11 +8823,11 @@ void QCC_PR_ParseDefs (char *classname)
if (accglobalsblock == 3)
{
if (!QCC_PR_GetDef(type_void, "end_sys_fields", NULL, false, 0, false))
QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 1, false);
QCC_PR_GetDef(type_void, "end_sys_fields", NULL, true, 0, false);
}
else
if (!QCC_PR_GetDef(type_void, "end_sys_globals", NULL, false, 0, false))
QCC_PR_GetDef(type_void, "end_sys_globals", NULL, true, 1, false);
QCC_PR_GetDef(type_void, "end_sys_globals", NULL, true, 0, false);
accglobalsblock = 3;
}
}
@ -8780,12 +8848,12 @@ void QCC_PR_ParseDefs (char *classname)
break;
}
if (QCC_PR_CheckKeyword(keyword_object, "object"))
QCC_PR_GetDef(type_entity, name, NULL, true, 1, true);
QCC_PR_GetDef(type_entity, name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_string, "string"))
QCC_PR_GetDef(type_string, name, NULL, true, 1, true);
QCC_PR_GetDef(type_string, name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_real, "real"))
{
def = QCC_PR_GetDef(type_float, name, NULL, true, 1, true);
def = QCC_PR_GetDef(type_float, name, NULL, true, 0, true);
if (QCC_PR_CheckToken("="))
{
G_FLOAT(def->ofs) = pr_immediate._float;
@ -8794,7 +8862,7 @@ void QCC_PR_ParseDefs (char *classname)
}
else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
{
def = QCC_PR_GetDef(type_vector, name, NULL, true, 1, true);
def = QCC_PR_GetDef(type_vector, name, NULL, true, 0, true);
if (QCC_PR_CheckToken("="))
{
QCC_PR_Expect("[");
@ -8808,7 +8876,7 @@ void QCC_PR_ParseDefs (char *classname)
}
}
else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
QCC_PR_GetDef(type_function, name, NULL, true, 1, true);
QCC_PR_GetDef(type_function, name, NULL, true, 0, true);
else
QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
QCC_PR_Expect (";");
@ -8835,15 +8903,15 @@ void QCC_PR_ParseDefs (char *classname)
break;
}
if (QCC_PR_CheckKeyword(keyword_object, "object"))
QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 1, true);
QCC_PR_GetDef(QCC_PR_FieldType(type_entity), name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_string, "string"))
QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 1, true);
QCC_PR_GetDef(QCC_PR_FieldType(type_string), name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_real, "real"))
QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 1, true);
QCC_PR_GetDef(QCC_PR_FieldType(type_float), name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_vector, "vector"))
QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 1, true);
QCC_PR_GetDef(QCC_PR_FieldType(type_vector), name, NULL, true, 0, true);
else if (QCC_PR_CheckKeyword(keyword_pfunc, "pfunc"))
QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 1, true);
QCC_PR_GetDef(QCC_PR_FieldType(type_function), name, NULL, true, 0, true);
else
QCC_PR_ParseError(ERR_BADNOTTYPE, "Bad type\n");
QCC_PR_Expect (";");
@ -8895,7 +8963,7 @@ void QCC_PR_ParseDefs (char *classname)
QCC_PR_Expect("(");
type = QCC_PR_ParseFunctionTypeReacc(false, type);
QCC_PR_Expect(";");
def = QCC_PR_GetDef (type, name, NULL, true, 1, false);
def = QCC_PR_GetDef (type, name, NULL, true, 0, false);
if (autoprototype)
{ //ignore the code and stuff
@ -9038,11 +9106,11 @@ void QCC_PR_ParseDefs (char *classname)
if (arraysize < 1)
{
QCC_PR_ParseError (ERR_BADARRAYSIZE, "Definition of array (%s) size is not of a numerical value", name);
arraysize=0; //grrr...
arraysize=1; //grrr...
}
}
else
arraysize = 1;
arraysize = 0;
if (QCC_PR_CheckToken("("))
{

View File

@ -74,6 +74,8 @@ QCC_type_t *type_function;// = {ev_function/*, &def_function*/,NULL,&type_void};
QCC_type_t *type_pointer;// = {ev_pointer/*, &def_pointer*/};
QCC_type_t *type_integer;// = {ev_integer/*, &def_integer*/};
QCC_type_t *type_variant;// = {ev_integer/*, &def_integer*/};
QCC_type_t *type_floatpointer;
QCC_type_t *type_intpointer;
QCC_type_t *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
@ -1367,7 +1369,7 @@ int QCC_PR_LexInteger (void)
len++;
pr_file_p++;
c = *pr_file_p;
} while ((c >= '0' && c<= '9') || c == '.' || (c>='a' && c <= 'f'));
} while ((c >= '0' && c<= '9') || (c == '.'&&pr_file_p[1]!='.') || (c>='a' && c <= 'f'));
pr_token[len] = 0;
return atoi (pr_token);
}
@ -1420,7 +1422,7 @@ void QCC_PR_LexNumber (void)
num*=base;
num += c -'A'+10;
}
else if (c == '.')
else if (c == '.' && pr_file_p[1]!='.')
{
pr_token[tokenlen++] = c;
pr_file_p++;
@ -1447,6 +1449,15 @@ void QCC_PR_LexNumber (void)
pr_immediate._float = (float)atof(pr_token);
return;
}
else if (c == 'f')
{
pr_token[tokenlen++] = c;
pr_token[tokenlen++] = 0;
pr_file_p++;
pr_immediate_type = type_float;
pr_immediate._float = num*sign;
return;
}
else if (c == 'i')
{
pr_token[tokenlen++] = c;
@ -1500,6 +1511,8 @@ float QCC_PR_LexFloat (void)
pr_file_p++;
c = *pr_file_p;
} while ((c >= '0' && c<= '9') || (c == '.'&&pr_file_p[1]!='.')); //only allow a . if the next isn't too...
if (*pr_file_p == 'f')
pr_file_p++;
pr_token[len] = 0;
return (float)atof (pr_token);
}
@ -2561,7 +2574,7 @@ void QCC_PR_Lex (void)
QCC_PR_LexNumber();
return;
}
if ( (c == '.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') )
if ( (c == '.'&&pr_file_p[1]!='.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') )
{
pr_token_type = tt_immediate;
QCC_PR_LexNumber ();
@ -3469,7 +3482,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
fieldtype = QCC_PR_NewType(newparm->name, ev_field);
fieldtype->aux_type = newparm;
fieldtype->size = newparm->size;
QCC_PR_GetDef(fieldtype, membername, pr_scope, 2, 1, false);
QCC_PR_GetDef(fieldtype, membername, pr_scope, 2, 0, false);
newparm->ofs = 0;//newt->size;
@ -3523,7 +3536,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
else
newparm->name = QCC_CopyString("")+strings;
newparm->ofs = newt->size;
newt->size += newparm->size*newparm->arraysize;
newt->size += newparm->size*(newparm->arraysize?newparm->arraysize:1);
newt->num_parms++;
if (type)
@ -3546,6 +3559,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
newparm = NULL;
while (!QCC_PR_CheckToken("}"))
{
int arraysize;
if (QCC_PR_CheckToken(","))
{
if (!newparm)
@ -3568,8 +3582,11 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
QCC_PR_Expect(";");
}
newparm->ofs = 0;
if (newparm->size > newt->size*newparm->arraysize)
newt->size = newparm->size*newparm->arraysize;
arraysize = newparm->arraysize;
if (!arraysize)
arraysize = 1;
if (newparm->size*arraysize > newt->size)
newt->size = newparm->size*arraysize;
newt->num_parms++;
if (type)

View File

@ -247,6 +247,7 @@ compiler_flag_t compiler_flag[] = {
{&flag_assume_integer, FLAG_MIDCOMPILE,"assumeint", "Assume Integers", "Numerical constants are assumed to be integers, instead of floats."},
{&pr_subscopedlocals, FLAG_MIDCOMPILE,"subscope", "Subscoped Locals", "Restrict the scope of locals to the block they are actually defined within, as in C."},
{&verbose, FLAG_MIDCOMPILE,"verbose", "Verbose", "Lots of extra compiler messages."},
{&flag_typeexplicit, FLAG_MIDCOMPILE,"typeexplicit", "Explicit types", "All type conversions must be explicit or directly supported by instruction set."},
{NULL}
};
@ -1610,7 +1611,7 @@ QCC_type_t *QCC_PR_NewType (char *name, int basictype)
qcc_typeinfo[numtypeinfos].num_parms = 0;
qcc_typeinfo[numtypeinfos].param = NULL;
qcc_typeinfo[numtypeinfos].size = type_size[basictype];
qcc_typeinfo[numtypeinfos].arraysize = 1;
qcc_typeinfo[numtypeinfos].arraysize = 0;
numtypeinfos++;
@ -1675,11 +1676,11 @@ void QCC_PR_BeginCompilation (void *memory, int memsize)
if (output_parms)
{ //this tends to confuse the brains out of decompilers. :)
numpr_globals = 1;
QCC_PR_GetDef(type_vector, "RETURN", NULL, true, 1, false)->references++;
QCC_PR_GetDef(type_vector, "RETURN", NULL, true, 0, false)->references++;
for (i = 0; i < MAX_PARMS; i++)
{
sprintf(name, "PARM%i", i);
QCC_PR_GetDef(type_vector, name, NULL, true, 1, false)->references++;
QCC_PR_GetDef(type_vector, name, NULL, true, 0, false)->references++;
}
}
else
@ -2768,6 +2769,7 @@ void QCC_SetDefaultProperties (void)
qccwarningdisabled[WARN_FTE_SPECIFIC] = true;
qccwarningdisabled[WARN_EXTENSION_USED] = true;
qccwarningdisabled[WARN_IFSTRING_USED] = true;
qccwarningdisabled[WARN_CORRECTEDRETURNTYPE] = true;

View File

@ -51,6 +51,8 @@ extern QCC_type_t *type_function;// = {ev_function/*, &def_function*/,NULL,&type
// type_function is a void() function used for state defs
extern QCC_type_t *type_pointer;// = {ev_pointer/*, &def_pointer*/};
extern QCC_type_t *type_integer;// = {ev_integer/*, &def_integer*/};
extern QCC_type_t *type_floatpointer;
extern QCC_type_t *type_intpointer;
extern QCC_type_t *type_floatfield;// = {ev_field/*, &def_field*/, NULL, &type_float};
QCC_type_t *QCC_PR_NewType (char *name, int basictype);

View File

@ -655,27 +655,38 @@ void NPP_NQFlush(void)
if (cl->state == cs_spawned && ISQWCLIENT(cl))
{
char *h2finale = NULL;
char *h2title = NULL;
if (cl->zquake_extensions & Z_EXT_SERVERTIME)
{
ClientReliableCheckBlock(cl, 6);
/* ClientReliableCheckBlock(cl, 6);
ClientReliableWrite_Byte(cl, svc_updatestatlong);
ClientReliableWrite_Byte(cl, STAT_TIME);
ClientReliableWrite_Long(cl, (int)(sv.world.physicstime * 1000));
cl->nextservertimeupdate = sv.world.physicstime+10;
}
*/ }
if (progstype == PROG_H2)
{
/*hexen2 does something like this in the client, but we don't support those protocols, so translate to something usable*/
int lookup[13] = {394, 395, 356, 357, 358, 411, 386+6, 386+7, 386+8, 391, 538, 545, 561};
char *title[13] = {"gfx/finale.lmp", "gfx/meso.lmp", "gfx/egypt.lmp", "gfx/roman.lmp", "gfx/castle.lmp", "gfx/castle.lmp", "gfx/end-1.lmp", "gfx/end-2.lmp", "gfx/end-3.lmp", "gfx/castle.lmp", "gfx/mpend.lmp", "gfx/mpmid.lmp", "gfx/end-3.lmp"};
int lookup[13] = {394, 395, 396, 397, 358, 411, 386+6, 386+7, 386+8, 391, 538, 545, 561};
if (buffer[1] < 13)
{
h2title = title[buffer[1]];
h2finale = T_GetString(lookup[buffer[1]]);
}
}
if (h2finale)
{
ClientReliableCheckBlock(cl, 16);
ClientReliableCheckBlock(cl, 3 + strlen(h2title) + 3 + strlen(h2finale) + 1);
ClientReliableWrite_Byte(cl, svc_finale);
ClientReliableWrite_Byte(cl, '/');
ClientReliableWrite_Byte(cl, 'I');
ClientReliableWrite_SZ(cl, h2title, strlen(h2title));
ClientReliableWrite_Byte(cl, ':');
ClientReliableWrite_Byte(cl, '/');
ClientReliableWrite_Byte(cl, 'P');
ClientReliableWrite_String(cl, h2finale);
}
else

View File

@ -2905,6 +2905,7 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo
int volume;
float attenuation;
int pitchadj;
int flags;
entity = G_EDICT(prinst, OFS_PARM0);
channel = G_FLOAT(OFS_PARM1);
@ -2915,6 +2916,15 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo
pitchadj = G_FLOAT(OFS_PARM5);
else
pitchadj = 0;
if (*svprogfuncs->callargc > 6)
{
flags = G_FLOAT(OFS_PARM5);
if (channel < 0)
channel = 0;
channel &= 7;
}
else
flags = (channel & 8)?1:0;
if (volume < 0) //erm...
return;
@ -2922,6 +2932,9 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo
if (volume > 255)
volume = 255;
if (flags & 1)
channel |= 8;
SVQ1_StartSound ((wedict_t*)entity, channel, sample, volume, attenuation, pitchadj);
}
@ -3476,11 +3489,12 @@ static void QCBUILTIN PF_conprint (progfuncs_t *prinst, struct globalvars_s *pr_
Sys_Printf ("%s",PF_VarString(prinst, 0, pr_globals));
}
static void QCBUILTIN PF_h2printf (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void QCBUILTIN PF_h2dprintf (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char temp[256];
char printable[2048];
float v;
char *pct;
v = G_FLOAT(OFS_PARM1);
@ -3489,16 +3503,34 @@ static void QCBUILTIN PF_h2printf (progfuncs_t *prinst, struct globalvars_s *pr_
else
sprintf (temp, "%5.1f",v);
Con_Printf (PR_GetStringOfs(prinst, OFS_PARM0),temp);
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
while(pct = strstr(printable, "%s"))
{
if ((pct-printable) + strlen(temp) + strlen(pct) > sizeof(printable))
break;
memmove(pct + strlen(temp), pct+2, strlen(pct+2)+1);
memcpy(pct, temp, strlen(temp));
}
Con_DPrintf ("%s", printable);
}
static void QCBUILTIN PF_h2printv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
static void QCBUILTIN PF_h2dprintv (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char temp[256];
char printable[2048];
char *pct;
sprintf (temp, "'%5.1f %5.1f %5.1f'", G_VECTOR(OFS_PARM1)[0], G_VECTOR(OFS_PARM1)[1], G_VECTOR(OFS_PARM1)[2]);
Con_Printf (PR_GetStringOfs(prinst, OFS_PARM0),temp);
Q_strncpyz(printable, PR_GetStringOfs(prinst, OFS_PARM0), sizeof(printable));
while(pct = strstr(printable, "%s"))
{
if ((pct-printable) + strlen(temp) + strlen(pct) > sizeof(printable))
break;
memmove(pct + strlen(temp), pct+2, strlen(pct+2)+1);
memcpy(pct, temp, strlen(temp));
}
Con_DPrintf ("%s", printable);
}
static void QCBUILTIN PF_h2spawn_temp (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -3625,7 +3657,7 @@ int PF_precache_model_Internal (progfuncs_t *prinst, char *s, qboolean queryonly
sv.strings.model_precache[i] = PR_AddString(prinst, s, 0);
s = sv.strings.model_precache[i];
if (!strcmp(s + strlen(s) - 4, ".bsp") || sv_gameplayfix_setmodelrealbox.ival)
sv.models[i] = Mod_FindName(s);
sv.models[i] = Mod_ForName(s, false);
else
{
/*touch the file, so any packs will be referenced*/
@ -6299,22 +6331,36 @@ void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc)
{
char temp[16];
if (classnum < 1)
return; //reject it (it would crash the (standard hexen2) mod)
return; //reject it (it would crash the (standard hexen2) mod)
if (classnum > 5)
return;
/*ignore it if they already have a class, this fixes some h2mp crashes*/
if (cl->playerclass)
return;
if (!fromqc)
{
if (progstype != PROG_H2)
return;
/*if they already have a class, only switch to the class already set by the gamecode
this is awkward, but matches hexen2*/
if (cl->playerclass)
{
if (cl->edict->xv->playerclass)
classnum = cl->edict->xv->playerclass;
else if (cl->playerclass)
classnum = cl->playerclass;
}
}
if (classnum)
sprintf(temp,"%i",(int)classnum);
else
*temp = 0;
Info_SetValueForKey (cl->userinfo, "cl_playerclass", temp, sizeof(cl->userinfo));
if (cl->playerclass != classnum)
{
cl->edict->xv->playerclass = classnum;
cl->playerclass = classnum;
sprintf(temp,"%i",(int)classnum);
Info_SetValueForKey (cl->userinfo, "cl_playerclass", temp, sizeof(cl->userinfo));
if (!fromqc)
{
cl->sendinfo = true;
@ -6629,6 +6675,31 @@ enum
ce_grey_smoke_15,
ce_grey_smoke_100,
ce_chunk_1,
ce_chunk_2,
ce_chunk_3,
ce_chunk_4,
ce_chunk_5,
ce_chunk_6,
ce_chunk_7,
ce_chunk_8,
ce_chunk_9,
ce_chunk_10,
ce_chunk_11,
ce_chunk_12,
ce_chunk_13,
ce_chunk_14,
ce_chunk_15,
ce_chunk_16,
ce_chunk_17,
ce_chunk_18,
ce_chunk_19,
ce_chunk_20,
ce_chunk_21,
ce_chunk_22,
ce_chunk_23,
ce_chunk_24,
ce_max
};
int h2customtents[ce_max];
@ -6677,11 +6748,11 @@ void SV_RegisterH2CustomTents(void)
h2customtents[ce_magic_missile_explosion] = SV_CustomTEnt_Register("ce_magic_missile_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_ghost
h2customtents[ce_bone_explosion] = SV_CustomTEnt_Register("ce_bone_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_redcloud
h2customtents[ce_redcloud] = SV_CustomTEnt_Register("ce_redcloud", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterpuffs] = SV_CustomTEnt_Register("ce_teleporterpuffs", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterbody] = SV_CustomTEnt_Register("ce_teleporterbody", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
// ce_boneshard
// ce_boneshrapnel
h2customtents[ce_boneshard] = SV_CustomTEnt_Register("ce_boneshard", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_boneshrapnel] = SV_CustomTEnt_Register("ce_boneshrapnel", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_flamestream] = SV_CustomTEnt_Register("ce_flamestream", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
// ce_snow,
h2customtents[ce_gravitywell] = SV_CustomTEnt_Register("ce_gravitywell", 0, NULL, 0, NULL, 0, 0, NULL);
@ -6718,6 +6789,31 @@ void SV_RegisterH2CustomTents(void)
h2customtents[ce_green_smoke_20] = SV_CustomTEnt_Register("ce_green_smoke_20", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_grey_smoke_15] = SV_CustomTEnt_Register("ce_grey_smoke_15", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_grey_smoke_100] = SV_CustomTEnt_Register("ce_grey_smoke_100", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_1] = SV_CustomTEnt_Register("ce_chunk_greystone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_2] = SV_CustomTEnt_Register("ce_chunk_wood", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_3] = SV_CustomTEnt_Register("ce_chunk_metal", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_4] = SV_CustomTEnt_Register("ce_chunk_flesh", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_5] = SV_CustomTEnt_Register("ce_chunk_fire", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_6] = SV_CustomTEnt_Register("ce_chunk_clay", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_7] = SV_CustomTEnt_Register("ce_chunk_leaves", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_8] = SV_CustomTEnt_Register("ce_chunk_hay", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_9] = SV_CustomTEnt_Register("ce_chunk_brownstone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_10] = SV_CustomTEnt_Register("ce_chunk_cloth", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_11] = SV_CustomTEnt_Register("ce_chunk_wood_leaf", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_12] = SV_CustomTEnt_Register("ce_chunk_wood_metal", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_13] = SV_CustomTEnt_Register("ce_chunk_wood_stone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_14] = SV_CustomTEnt_Register("ce_chunk_metal_stone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_15] = SV_CustomTEnt_Register("ce_chunk_metal_cloth", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_16] = SV_CustomTEnt_Register("ce_chunk_webs", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_17] = SV_CustomTEnt_Register("ce_chunk_glass", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_18] = SV_CustomTEnt_Register("ce_chunk_ice", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_19] = SV_CustomTEnt_Register("ce_chunk_clearglass", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_20] = SV_CustomTEnt_Register("ce_chunk_redglass", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_21] = SV_CustomTEnt_Register("ce_chunk_acid", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_22] = SV_CustomTEnt_Register("ce_chunk_meteor", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_23] = SV_CustomTEnt_Register("ce_chunk_greenflesh", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_chunk_24] = SV_CustomTEnt_Register("ce_chunk_bone", CTE_CUSTOMVELOCITY|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
}
}
static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -6725,6 +6821,7 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s
// float *min, *max, *angle, *size;
// float colour, wait, radius, frame, framelength, duration;
// int flags, type, skin;
int type;
float *org, *dir;
int count;
@ -6934,17 +7031,22 @@ static void QCBUILTIN PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s
break;
case ce_chunk:
org = G_VECTOR(OFS_PARM1);
//type = G_FLOAT(OFS_PARM2); /*FIXME: discarded*/
type = G_FLOAT(OFS_PARM2);
dir = G_VECTOR(OFS_PARM3);
count = G_FLOAT(OFS_PARM4);
/*convert it to the requested chunk type*/
efnum = ce_chunk_1 + type - 1;
if (efnum < ce_chunk_1 && efnum > ce_chunk_24)
efnum = ce_chunk;
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, count, dir);
return;
}
Con_Printf("FTE-H2 FIXME: ce_chunk not supported!\n");
Con_Printf("FTE-H2 FIXME: ce_chunk type=%i not supported!\n", type);
return;
@ -8482,7 +8584,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"lightstylestatic",PF_lightstylestatic,0, 0, 5, 5, "void(float style, float val)"},
{"break", PF_break, 6, 6, 6, 0, "void()"},
{"random", PF_random, 7, 7, 7, 0, "float()"},
{"sound", PF_sound, 8, 8, 8, 0, "void(entity e, float chan, string samp, float vol, float atten, optional float speedpct)"},
{"sound", PF_sound, 8, 8, 8, 0, "void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags)"},
{"normalize", PF_normalize, 9, 9, 9, 0, "vector(vector v)"},
{"error", PF_error, 10, 10, 10, 0, "void(string e)"},
{"objerror", PF_objerror, 11, 11, 11, 0, "void(string e)"},
@ -8561,14 +8663,14 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"bwriteentity", PF_qtBroadcast_WriteEntity}, //66
{"printfloat", PF_h2printf, 0, 0, 60}, //60
{"printfloat", PF_h2dprintf, 0, 0, 60}, //60
{"sin", PF_Sin, 0, 0, 62, 60, "float(float angle)"}, //60
{"cos", PF_Cos, 0, 0, 61, 61, "float(float angle)"}, //61
{"sqrt", PF_Sqrt, 0, 0, 84, 62, "float(float value)"}, //62
{"AdvanceFrame", PF_h2AdvanceFrame, 0, 0, 63, 0},
{"printvec", PF_h2printv, 0, 0, 64, 0}, //64
{"printvec", PF_h2dprintv, 0, 0, 64, 0}, //64
{"RewindFrame", PF_h2RewindFrame, 0, 0, 65, 0},
{"particleexplosion",PF_h2particleexplosion,0, 0, 81, 0},
{"movestep", PF_h2movestep, 0, 0, 82, 0},
@ -8761,7 +8863,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"map_builtin", PF_builtinsupported,0, 0, 0, 220, "", true}, //like #100 - takes 2 args. arg0 is builtinname, 1 is number to map to.
//FTE_STRINGS
{"strstrofs", PF_strstrofs, 0, 0, 0, 221, "float(string s1, string sub)"},
{"strstrofs", PF_strstrofs, 0, 0, 0, 221, "float(string s1, string sub, optional float startidx)"},
{"str2chr", PF_str2chr, 0, 0, 0, 222, "float(string str, float index)"},
{"chr2str", PF_chr2str, 0, 0, 0, 223, "string(float chr, ...)"},
{"strconv", PF_strconv, 0, 0, 0, 224, "string(float ccase, float redalpha, float redchars, string str, ...)"},
@ -8930,6 +9032,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"dynamiclight_get",PF_Fixme, 0, 0, 0, 372, "__variant(float lno, float fld)"},
{"dynamiclight_set",PF_Fixme, 0, 0, 0, 373, "void(float lno, float fld, __variant value)"},
{"particleeffectquery",PF_Fixme,0, 0, 0, 374, "string(float efnum, float body)"},
//END EXT_CSQC
//end fte extras
@ -9766,7 +9869,7 @@ void PR_DumpPlatform_f(void)
{"FL_WATERJUMP", "const float", QW|NQ|CS, FL_WATERJUMP},
{"FL_FINDABLE_NONSOLID","const float", QW|NQ|CS, FL_FINDABLE_NONSOLID},
// {"FL_MOVECHAIN_ANGLE", "const float", QW|NQ, FL_MOVECHAIN_ANGLE},
{"FL_LAGGEDMOVE", "const float", QW|NQ, FL_LAGGEDMOVE},
{"FL_LAGGEDMOVE", "const float", QW|NQ, FLQW_LAGGEDMOVE},
// {"FL_CLASS_DEPENDENT", "const float", QW|NQ, FL_CLASS_DEPENDENT},
{"MOVE_NORMAL", "const float", QW|NQ|CS, MOVE_NORMAL},

View File

@ -678,6 +678,7 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
PR_LoadGlabalStruct();
pr_global_struct->serverflags = svs.serverflags;
pr_global_struct->time = sv.time = sv.world.physicstime = time;
sv.starttime = Sys_DoubleTime() - sv.time;
@ -740,8 +741,40 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
if (ent->isfree)
continue;
World_LinkEdict (&sv.world, (wedict_t*)ent, false); // force retouch even for stationary
World_LinkEdict (&sv.world, (wedict_t*)ent, false);
}
for (i=0 ; i<sv.world.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);
if (ent->isfree)
continue;
/*hexen2 instead overwrites ents, which can theoretically be unreliable (ents with this flag are not saved in the first place, and thus are effectively reset instead of reloaded).
fte purges all ents beforehand in a desperate attempt to remain sane.
this behaviour does not match exactly, but is enough for vanilla hexen2/POP.
*/
if ((unsigned int)ent->v->flags & FL_HUBSAVERESET)
{
func_t f;
/*set some minimal fields*/
ent->v->solid = SOLID_NOT;
ent->v->use = 0;
ent->v->touch = 0;
ent->v->think = 0;
ent->v->nextthink = 0;
/*reinvoke the spawn function*/
pr_global_struct->time = 0.1;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
f = PR_FindFunction(svprogfuncs, PR_GetString(svprogfuncs, ent->v->classname), PR_ANY);
svprogfuncs->ToggleBreak(svprogfuncs, PR_GetString(svprogfuncs, ent->v->classname), 0, 1);
svprogfuncs->ToggleBreak(svprogfuncs, "trigger_crosslevel_target_think", 0, 1);
if (f)
PR_ExecuteProgram(svprogfuncs, f);
}
}
pr_global_struct->time = sv.world.physicstime;
return true; //yay
}
@ -836,6 +869,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
}
else if (SpectatorDisconnect)
{
@ -866,7 +900,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
for (i=1 ; i<MAX_MODELS ; i++)
{
if (sv.strings.model_precache[i])
if (sv.strings.model_precache[i] && *sv.strings.model_precache[i])
VFS_PRINTF (f, "%s\n", sv.strings.model_precache[i]);
else
break;

View File

@ -141,6 +141,7 @@ typedef struct
qbyte h2cdtrack;
int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up)
int spawned_client_slots; //number of PLAYER slots which are active (ie: putclientinserver was called)
model_t *models[MAX_MODELS];
qbyte *pvs, *phs; // fully expanded and decompressed
@ -989,6 +990,8 @@ trace_t WPhys_Trace_Toss (world_t *w, wedict_t *ent, wedict_t *ignore);
void SV_ProgStartFrame (void);
void WPhys_RunEntity (world_t *w, wedict_t *ent);
qboolean WPhys_RunThink (world_t *w, wedict_t *ent);
void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *initial_origin, float *initial_angle); /*here for player movement to do movechains too*/
//
// sv_send.c
//

View File

@ -1416,7 +1416,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen)
//stage 1: check against their origin
VectorAdd(viewer->v->origin, viewer->v->view_ofs, start);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, NULL, start, seen->v->origin, vec3_origin, vec3_origin, &tr))
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, start, seen->v->origin, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //wasn't blocked
//stage 2: check against their bbox
@ -1427,7 +1427,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen)
end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, NULL, start, end, vec3_origin, vec3_origin, &tr))
if (!sv.world.worldmodel->funcs.NativeTrace (sv.world.worldmodel, 1, 0, NULL, start, end, vec3_origin, vec3_origin, FTECONTENTS_SOLID, &tr))
return false; //this trace went through, so don't cull
}

View File

@ -1477,7 +1477,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
SV_FilterImpulseInit();
Info_SetValueForKey (svs.info, "map", sv.name, MAX_SERVERINFO_STRING);
Con_TPrintf (STL_SERVERSPAWNED); //misc filenotfounds can be misleading.
if (sv.allocated_client_slots != 1)
Con_TPrintf (STL_SERVERSPAWNED); //misc filenotfounds can be misleading.
if (!startspot)
{
@ -1536,6 +1537,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
sv.spawned_client_slots++;
// send notification to all clients
host_client->sendinfo = true;

View File

@ -127,6 +127,7 @@ cvar_t allow_download_textures = CVAR("allow_download_textures", "1");
cvar_t allow_download_packages = CVAR("allow_download_packages", "1");
cvar_t allow_download_wads = CVAR("allow_download_wads", "1");
cvar_t allow_download_configs = CVAR("allow_download_configs", "0");
cvar_t allow_download_copyrighted = CVAR("allow_download_copyrighted", "0");
cvar_t sv_public = CVAR("sv_public", "0");
cvar_t sv_listen_qw = CVARAF("sv_listen_qw", "1", "sv_listen", 0);
@ -490,6 +491,7 @@ void SV_DropClient (client_t *drop)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, drop->edict);
if (pr_global_ptrs->ClientDisconnect)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
}
else if (SpectatorDisconnect)
{
@ -3475,6 +3477,7 @@ void SV_CheckTimeouts (void)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
host_client->istobeloaded=false;
@ -3635,6 +3638,7 @@ void SV_Impulse_f (void)
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
sv.spawned_client_slots++;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
@ -3654,6 +3658,7 @@ void SV_Impulse_f (void)
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
svs.clients[i].state = cs_free;
}
@ -3709,7 +3714,11 @@ float SV_Frame (void)
sv.gamespeed = 1;
#ifndef SERVERONLY
if ((sv.paused & 4) != ((!isDedicated && sv.allocated_client_slots == 1 && key_dest != key_game && cls.state == ca_active)?4:0))
isidle = !isDedicated && sv.allocated_client_slots == 1 && key_dest != key_game && cls.state == ca_active;
/*server is effectively paused if there are no clients*/
if (sv.spawned_client_slots == 0)
isidle = true;
if ((sv.paused & 4) != (isidle?4:0))
sv.paused ^= 4;
#endif
@ -3730,15 +3739,14 @@ float SV_Frame (void)
timedelta = 0;
}
if (isDedicated)
realtime += sv.time - oldtime;
if (sv.paused && sv.time > 1.5)
{
sv.starttime += sv.time - oldtime; //move the offset
sv.time = oldtime; //and keep time as it was.
}
if (isDedicated)
realtime += sv.time - oldtime;
}
@ -3797,7 +3805,7 @@ void SV_MVDStream_Poll(void);
}
// move autonomous things around if enough time has passed
if (!sv.paused || sv.time < 1.5)
if (!sv.paused || (sv.world.physicstime < 1 && sv.spawned_client_slots))
{
#ifdef Q2SERVER
//q2 is idle even if clients sent packets.
@ -4036,6 +4044,7 @@ void SV_InitLocal (void)
Cvar_Register (&allow_download_packages,cvargroup_serverpermissions);
Cvar_Register (&allow_download_wads, cvargroup_serverpermissions);
Cvar_Register (&allow_download_root, cvargroup_serverpermissions);
Cvar_Register (&allow_download_copyrighted, cvargroup_serverpermissions);
Cvar_Register (&secure, cvargroup_serverpermissions);
Cvar_Register (&sv_highchars, cvargroup_servercontrol);

View File

@ -121,13 +121,17 @@ qboolean World_movestep (world_t *world, wedict_t *ent, vec3_t move, qboolean re
trace_t trace;
int i;
wedict_t *enemy = world->edicts;
int eflags = ent->v->flags;
if (progstype != PROG_H2)
eflags &= ~FLH2_NOZ|FLH2_HUNTFACE;
// try the move
VectorCopy (ent->v->origin, oldorg);
VectorAdd (ent->v->origin, move, neworg);
// flying monsters don't step up
if ( (int)ent->v->flags & (FL_SWIM | FL_FLY) )
if ( eflags & (FL_SWIM | FL_FLY) && !(eflags & (FLH2_NOZ|FLH2_HUNTFACE)))
{
// try one move with vertical motion, then one without
for (i=0 ; i<2 ; i++)
@ -139,6 +143,8 @@ qboolean World_movestep (world_t *world, wedict_t *ent, vec3_t move, qboolean re
if (i == 0 && enemy->entnum)
{
dz = ent->v->origin[2] - ((wedict_t*)PROG_TO_EDICT(world->progs, ent->v->enemy))->v->origin[2];
if (eflags & FLH2_HUNTFACE) /*get the ent's origin_z to match its victims face*/
dz += ((wedict_t*)PROG_TO_EDICT(world->progs, ent->v->enemy))->v->view_ofs[2];
if (dz > 40)
neworg[2] -= 8;
if (dz < 30)
@ -151,7 +157,7 @@ qboolean World_movestep (world_t *world, wedict_t *ent, vec3_t move, qboolean re
if (trace.fraction == 1)
{
if ( ((int)ent->v->flags & FL_SWIM) && !(World_PointContents(world, trace.endpos) & FTECONTENTS_FLUID))
if ( (eflags & FL_SWIM) && !(World_PointContents(world, trace.endpos) & FTECONTENTS_FLUID))
continue; // swim monster left water
VectorCopy (trace.endpos, ent->v->origin);
@ -301,6 +307,8 @@ qboolean World_StepDirection (world_t *world, wedict_t *ent, float yaw, float di
move[1] = sin(yaw)*dist;
move[2] = 0;
//FIXME: Hexen2: ent flags & FL_SET_TRACE
VectorCopy (ent->v->origin, oldorigin);
if (World_movestep (world, ent, move, false, false, NULL, NULL))
{

View File

@ -478,7 +478,7 @@ static trace_t WPhys_PushEntity (world_t *w, wedict_t *ent, vec3_t push, unsigne
VectorAdd (ent->v->origin, push, end);
if ((int)ent->v->flags&FL_LAGGEDMOVE)
if ((int)ent->v->flags&FLQW_LAGGEDMOVE)
traceflags |= MOVE_LAGGED;
if (ent->v->movetype == MOVETYPE_FLYMISSILE)
@ -489,6 +489,17 @@ static trace_t WPhys_PushEntity (world_t *w, wedict_t *ent, vec3_t push, unsigne
else
trace = World_Move (w, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL|traceflags, (wedict_t*)ent);
/*hexen2's movetype_swim does not allow swimming entities to move out of water. this implementation is quite hacky, but matches hexen2 well enough*/
if (ent->v->movetype == MOVETYPE_H2SWIM)
{
if (!(w->worldmodel->funcs.PointContents(w->worldmodel, NULL, trace.endpos) & (FTECONTENTS_WATER|FTECONTENTS_SLIME|FTECONTENTS_LAVA)))
{
VectorCopy(ent->v->origin, trace.endpos);
trace.fraction = 0;
trace.ent = w->edicts;
}
}
// if (trace.ent)
// VectorMA(trace.endpos, sv_impactpush.value, trace.plane.normal, ent->v->origin);
// else
@ -547,8 +558,6 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
pushed_p->ent = pusher;
VectorCopy (pusher->v->origin, pushed_p->origin);
VectorCopy (pusher->v->angles, pushed_p->angles);
// if (pusher->client)
// pushed_p->deltayaw = pusher->client->ps.pmove.delta_angles[YAW];
pushed_p++;
// move the pusher to it's final position
@ -569,17 +578,12 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
|| check->v->movetype == MOVETYPE_ANGLENOCLIP)
continue;
#if 1
oldsolid = pusher->v->solid;
pusher->v->solid = SOLID_NOT;
block = World_TestEntityPosition (w, check);
pusher->v->solid = oldsolid;
if (block)
continue;
#else
if (!check->area.prev)
continue; // not linked in anywhere
#endif
// if the entity is standing on the pusher, it will definitely be moved
if ( ! ( ((int)check->v->flags & FL_ONGROUND)
@ -610,10 +614,6 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
// try moving the contacted entity
VectorAdd (check->v->origin, move, check->v->origin);
// if (check->client)
// { // FIXME: doesn't rotate monsters?
// check->client->ps.pmove.delta_angles[YAW] += amove[YAW];
// }
VectorAdd (check->v->angles, amove, check->v->angles);
// figure movement due to the pusher's amove
@ -679,10 +679,6 @@ static qboolean WPhys_PushAngles (world_t *w, wedict_t *pusher, vec3_t move, vec
{
VectorCopy (p->origin, p->ent->v->origin);
VectorCopy (p->angles, p->ent->v->angles);
// if (p->ent->client)
// {
// p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw;
// }
World_LinkEdict (w, p->ent, false);
}
return false;
@ -1765,7 +1761,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent)
}
#endif
static void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *initial_origin, float *initial_angle)
void WPhys_MoveChain(world_t *w, wedict_t *ent, wedict_t *movechain, float *initial_origin, float *initial_angle)
{
qboolean callfunc;
if ((callfunc=DotProduct(ent->v->origin, initial_origin)) || DotProduct(ent->v->angles, initial_angle))

View File

@ -1646,6 +1646,8 @@ void SV_Begin_Core(client_t *split)
}
else
{
sv.spawned_client_slots++;
if (svprogfuncs)
{
eval_t *eval, *eval2;
@ -2468,6 +2470,16 @@ qboolean SV_AllowDownload (const char *name)
extern cvar_t allow_download_wads;
extern cvar_t allow_download_root;
extern cvar_t allow_download_configs;
extern cvar_t allow_download_copyrighted;
char cleanname[MAX_QPATH];
int i=0;
if (strlen(name) >= MAX_QPATH)
return false;
do
{
cleanname[i++] = *name;
} while(*name++);
name = cleanname;
//allowed at all?
if (!allow_download.value)
@ -2488,8 +2500,10 @@ qboolean SV_AllowDownload (const char *name)
if (!strcmp("pk4", COM_FileExtension(name)) || !strcmp("pk3", COM_FileExtension(name)) || !strcmp("pak", COM_FileExtension(name)))
{
/*do not permit 'id1/pak1.pak' or 'baseq3/pak0.pk3' or any similarly named packages. such packages would violate copyright, and must be obtained through other means (like buying the damn game)*/
if (!strstr(name, "/pak"))
if (FS_GetPackageDownloadable(name+8))
return !!allow_download_packages.value;
else
return !!allow_download_copyrighted.ival;
}
return false;
}
@ -2523,8 +2537,12 @@ qboolean SV_AllowDownload (const char *name)
//pak/pk3s.
if (!strcmp("pk4", COM_FileExtension(name)) || !strcmp("pk3", COM_FileExtension(name)) || !strcmp("pak", COM_FileExtension(name)))
{
if (strnicmp(name, "pak", 3)) //don't give out core pak/pk3 files. This matches q3 logic.
return !!allow_download_packages.value;
else
return !!allow_download_copyrighted.value;
}
if (!strcmp("cfg", COM_FileExtension(name)))
return !!allow_download_configs.value;
@ -2587,17 +2605,14 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
if (!strncmp(name, "package/", 8))
{
vfsfile_t *f;
if (FS_GetPackageDownloadable(name+8))
vfsfile_t *f = FS_OpenVFS(name+8, "rb", FS_ROOT);
if (f)
{
f = FS_OpenVFS(name+8, "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
return -5; //found package
}
VFS_CLOSE(f);
return -5; //found package
}
return -1; //not found
else
return -1; //not found/unable to open
}
else
found = FS_FLocateFile(name, FSLFRT_IFFOUND, loc);
@ -3892,15 +3907,21 @@ void Cmd_Give_f (void)
break;
}
}
else if (developer.value || host_client->netchan.remote_address.type == NA_LOOPBACK) //we don't want clients doing nasty things... like setting movetype 3123
else
{
int oldself;
oldself = pr_global_struct->self;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
SV_ClientPrintf(host_client, PRINT_HIGH, "Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
pr_global_struct->self = oldself;
if (developer.value < 2 && host_client->netchan.remote_address.type != NA_LOOPBACK) //we don't want clients doing nasty things... like setting movetype 3123
{
SV_PrintToClient(host_client, PRINT_HIGH, "'give' debugging command requires developer 2 set on the server before you may use it\n");
}
else
{
int oldself;
oldself = pr_global_struct->self;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
SV_ClientPrintf(host_client, PRINT_HIGH, "Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args()));
pr_global_struct->self = oldself;
}
}
}
void Cmd_Noclip_f (void)
@ -4115,6 +4136,7 @@ void Cmd_Join_f (void)
pr_global_struct->time = sv.world.physicstime;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer);
sv.spawned_client_slots++;
// send notification to all clients
host_client->old_frags = host_client->edict->v->frags;
@ -4177,6 +4199,7 @@ void Cmd_Observe_f (void)
// this will set the body to a dead frame, among other things
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientDisconnect);
sv.spawned_client_slots--;
SV_SetUpClientEdict (host_client, host_client->edict);
@ -4438,6 +4461,8 @@ void SVNQ_Begin_f (void)
}
else
{
sv.spawned_client_slots++;
// copy spawn parms out of the client_t
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
{
@ -4951,6 +4976,7 @@ ucmd_t nqucmds[] =
{"pext", SV_Pext_f},
{"enablecsqc", SV_EnableClientsCSQC},
{"disablecsqc", SV_DisableClientsCSQC},
{"challengeconnect", NULL},
#ifdef VOICECHAT
{"voicetarg", SV_Voice_Target_f},
@ -5816,7 +5842,14 @@ if (sv_player->v->health > 0 && before && !after )
continue;
if (ent->v->touch)
{
if (progstype != PROG_QW && VectorCompare(sv_player->v->velocity, old_vel))
{
VectorCopy(pmove.touchvel[i], old_vel);
VectorCopy(pmove.touchvel[i], sv_player->v->velocity);
}
sv.world.Event_Touch(&sv.world, (wedict_t*)ent, (wedict_t*)sv_player);
}
playertouch[n/8] |= 1 << (n%8);
if (sv_player->v->touch && !ent->isfree)

View File

@ -1574,7 +1574,7 @@ extern vec3_t player_maxs;
pe->forcecontentsmask = FTECONTENTS_SKY;
break;
case -16:
pe->forcecontentsmask = FTECONTENTS_LADDER;
pe->forcecontentsmask = Q2CONTENTS_LADDER;
break;
default:
pe->forcecontentsmask = 0;

View File

@ -560,10 +560,10 @@ static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent)
else
mod = Mod_ForName(va("*%i", ent->s.modelindex), false);
if (mod->needload || !mod->funcs.Trace)
if (mod->needload || !mod->funcs.NativeTrace)
return false;
mod->funcs.Trace(mod, 0, 0, NULL, vec3_origin, vec3_origin, mins, maxs, &tr);
mod->funcs.NativeTrace(mod, 0, 0, NULL, vec3_origin, vec3_origin, mins, maxs, 0xffffffff, &tr);
if (tr.startsolid)
return true;

View File

@ -41,6 +41,7 @@ typedef struct
float *start, *end;
trace_t trace;
int type;
int hitcontentsmask;
wedict_t *passedict;
#ifdef Q2SERVER
q2edict_t *q2passedict;
@ -899,7 +900,7 @@ qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
//wrapper function. Rotates the start and end positions around the angles if needed.
//qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t angles)
qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace, vec3_t origin, vec3_t angles)
qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace, vec3_t origin, vec3_t angles, unsigned int hitcontentsmask)
{
vec3_t start_l, end_l;
vec3_t axis[3];
@ -928,11 +929,11 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
{
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
result = model->funcs.Trace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, trace);
result = model->funcs.NativeTrace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, hitcontentsmask, trace);
}
else
{
result = model->funcs.Trace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, trace);
result = model->funcs.NativeTrace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, hitcontentsmask, trace);
}
VectorAdd (trace->endpos, origin, trace->endpos);
@ -1011,7 +1012,7 @@ Handles selection or creation of a clipping hull, and offseting (and
eventually rotation) of the end points
==================
*/
static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel) //hullnum overrides min/max for q1 style bsps
static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel, unsigned int hitcontentsmask) //hullnum overrides min/max for q1 style bsps
{
trace_t trace;
model_t *model;
@ -1036,42 +1037,37 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
if (ent->v->solid != SOLID_BSP)
{
ent->v->angles[0]*=-1; //carmack made bsp models rotate wrongly.
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles);
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
ent->v->angles[0]*=-1;
}
else
{
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles);
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
}
// fix trace up by the offset
if (trace.fraction != 1)
// if using hitmodel, we know it hit the bounding box, so try a proper trace now.
if (hitmodel && trace.fraction != 1 && ent->v->solid != SOLID_BSP && ent->v->modelindex != 0)
{
if (!model && hitmodel && ent->v->solid != SOLID_BSP && ent->v->modelindex > 0)
//okay, we hit the bbox
model_t *model;
model = w->Get_CModel(w, ent->v->modelindex);
if (model && model->funcs.NativeTrace)
{
//okay, we hit the bbox
model_t *model;
if (ent->v->modelindex < 1 || ent->v->modelindex >= MAX_MODELS)
Host_Error("SV_ClipMoveToEntity: modelindex out of range\n");
model = w->Get_CModel(w, ent->v->modelindex);
if (model && model->funcs.Trace)
{
//do the second trace
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles);
}
//do the second trace
TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles, hitcontentsmask);
}
}
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid )
if (trace.fraction < 1 || trace.startsolid)
trace.ent = ent;
return trace;
}
#ifdef Q2SERVER
static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, unsigned int hitcontentsmask)
{
trace_t trace;
model_t *model;
@ -1093,7 +1089,7 @@ static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t star
}
// trace a line through the apropriate clipping hull
TransformedTrace(model, 0, 0, start, end, mins, maxs, &trace, ent->s.origin, ent->s.angles);
TransformedTrace(model, 0, 0, start, end, mins, maxs, &trace, ent->s.origin, ent->s.angles, hitcontentsmask);
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid )
@ -1295,7 +1291,7 @@ static model_t *WorldQ2_ModelForEntity (world_t *w, q2edict_t *ent)
#endif
#ifdef Q2SERVER
void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip, int contentsmask )
void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip )
{
int i, num;
q2edict_t *touchlist[MAX_EDICTS], *touch;
@ -1326,7 +1322,7 @@ void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip, int contentsmask
}
if (touch->svflags & SVF_DEADMONSTER)
if ( !(contentsmask & Q2CONTENTS_DEADMONSTER))
if ( !(clip->hitcontentsmask & Q2CONTENTS_DEADMONSTER))
continue;
// might intersect, so do an exact clip
@ -1337,11 +1333,11 @@ void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip, int contentsmask
if (touch->svflags & SVF_MONSTER)
trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins2, clip->maxs2, contentsmask,
clip->mins2, clip->maxs2, clip->hitcontentsmask,
touch->s.origin, angles);
else
trace = CM_TransformedBoxTrace (model, clip->start, clip->end,
clip->mins, clip->maxs, contentsmask,
clip->mins, clip->maxs, clip->hitcontentsmask,
touch->s.origin, angles);
if (trace.allsolid || trace.startsolid ||
@ -1434,9 +1430,9 @@ static void World_ClipToEverything (world_t *w, moveclip_t *clip)
}
if ((int)touch->v->flags & FL_MONSTER)
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
else
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
@ -1535,9 +1531,9 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
}
if ((int)touch->v->flags & FL_MONSTER)
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
else
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL, clip->hitcontentsmask);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
@ -1608,7 +1604,7 @@ static void WorldQ2_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
continue; // don't clip against owner
}
trace = WorldQ2_ClipMoveToEntity (w, touch, clip->start, clip->mins, clip->maxs, clip->end);
trace = WorldQ2_ClipMoveToEntity (w, touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hitcontentsmask);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
@ -1706,8 +1702,15 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
}
#endif
if (type & MOVE_NOMONSTERS)
clip.hitcontentsmask = MASK_WORLDSOLID; /*solid only to world*/
else if (maxs[0] - mins[0])
clip.hitcontentsmask = MASK_BOXSOLID; /*impacts playerclip*/
else
clip.hitcontentsmask = MASK_POINTSOLID; /*ignores playerclip but hits everything else*/
// clip to world
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false);
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false, clip.hitcontentsmask);
clip.start = start;
clip.end = end;
@ -1830,7 +1833,7 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
continue; // don't clip against owner
}
trace = World_ClipMoveToEntity (w, touch, lp, clip.start, clip.mins, clip.maxs, clip.end, clip.hullnum, clip.type & MOVE_HITMODEL);
trace = World_ClipMoveToEntity (w, touch, lp, clip.start, clip.mins, clip.maxs, clip.end, clip.hullnum, clip.type & MOVE_HITMODEL, clip.hitcontentsmask);
if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
{
@ -1860,14 +1863,14 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
return clip.trace;
}
#ifdef Q2SERVER
trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict)
trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitcontentsmask, q2edict_t *passedict)
{
moveclip_t clip;
memset ( &clip, 0, sizeof ( moveclip_t ) );
// clip to world
clip.trace = CM_BoxTrace(w->worldmodel, start, end, mins, maxs, type);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end );
clip.trace = CM_BoxTrace(w->worldmodel, start, end, mins, maxs, hitcontentsmask);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end );
clip.trace.ent = ge->edicts;
if (clip.trace.fraction == 0)
@ -1877,7 +1880,8 @@ trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t
clip.end = end;
clip.mins = mins;
clip.maxs = maxs;
clip.type = type;
clip.type = MOVE_NORMAL;
clip.hitcontentsmask = hitcontentsmask;
clip.passedict = NULL;
clip.q2passedict = passedict;
@ -1890,7 +1894,7 @@ trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t
// clip to entities
#ifdef Q2BSPS
if (w->worldmodel->fromgame == fg_quake2 || w->worldmodel->fromgame == fg_quake3)
WorldQ2_ClipMoveToEntities(w, &clip, type);
WorldQ2_ClipMoveToEntities(w, &clip);
else
#endif
WorldQ2_ClipToLinks (w, w->areanodes, &clip );

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <string.h>
char shaders[][64] =
{
"bloom_blur",
"bloom_filter",
"bloom_final",
""
};
void dumpprogstring(FILE *out, FILE *src)
{
int j;
char line[1024];
while(fgets(line, sizeof(line), src))
{
j = 0;
while (line[j] == ' ' || line[j] == '\t')
j++;
if ((line[j] == '/' && line[j] == '/') || line[j] == '\r' || line[j] == '\n')
{
while (line[j])
fputc(line[j++], out);
}
else
{
fputc('\"', out);
while (line[j] && line[j] != '\r' && line[j] != '\n')
{
if (line[j] == '\t')
fputc(' ', out);
else if (line[j] == '\"')
{
fputc('\\', out);
fputc(line[j], out);
}
else
fputc(line[j], out);
j++;
}
fputs("\\n\"\n", out);
}
}
}
int main(void)
{
FILE *c, *s;
char line[1024];
int i, j, a;
c = fopen("../gl/r_bishaders.h", "wt");
if (!c)
{
printf("unable to open a file\n");
return;
}
fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n");
for (i = 0; *shaders[i]; i++)
{
for (a = 0; a < 3; a++)
{
if (a == 0)
sprintf(line, "glsl/%s.glsl", shaders[i]);
else if (a == 1)
sprintf(line, "gles/%s.glsl", shaders[i]);
else
sprintf(line, "hlsl/%s.hlsl", shaders[i]);
s = fopen(line, "rt");
if (!s)
{
printf("unable to open %s\n", line);
continue;
}
if (a == 0)
{
fprintf(c, "#ifdef GLQUAKE\n");
fprintf(c, "{QR_OPENGL, 110, \"%s\",\n", shaders[i]);
}
else if (a == 1)
{
fprintf(c, "#ifdef GLQUAKE\n");
fprintf(c, "{QR_OPENGL, 100, \"%s\",\n", shaders[i]);
}
else
{
fprintf(c, "#ifdef D3DQUAKE\n");
fprintf(c, "{QR_DIRECT3D, 9, \"%s\",\n", shaders[i]);
}
while(fgets(line, sizeof(line), s))
{
j = 0;
while (line[j] == ' ' || line[j] == '\t')
j++;
if ((line[j] == '/' && line[j] == '/') || line[j] == '\r' || line[j] == '\n')
{
while (line[j])
fputc(line[j++], c);
}
else
{
fputc('\"', c);
while (line[j] && line[j] != '\r' && line[j] != '\n')
{
if (line[j] == '\t')
fputc(' ', c);
else if (line[j] == '\"')
{
fputc('\\', c);
fputc(line[j], c);
}
else
fputc(line[j], c);
j++;
}
fputs("\\n\"\n", c);
}
}
fputs("},\n", c);
fprintf(c, "#endif\n");
fclose(s);
}
}
fclose(c);
}

View File

@ -0,0 +1,24 @@
//apply gaussian filter
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
/*offset should be 1.2 pixels away from the center*/
uniform vec3 e_glowmod;
uniform sampler2D s_t0;
void main ()
{
gl_FragColor =
0.3125 * texture2D(s_t0, tc - e_glowmod.st) +
0.375 * texture2D(s_t0, tc) +
0.3125 * texture2D(s_t0, tc + e_glowmod.st);
}
#endif

View File

@ -0,0 +1,20 @@
//the bloom filter
//filter out any texels which are not to bloom
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
void main ()
{
gl_FragColor = (texture2D(s_t0, tc) - vec4(0.5, 0.5, 0.5, 0.0)) * vec4(2.0,2.0,2.0,1.0);
}
#endif

View File

@ -0,0 +1,27 @@
//add them together
//optionally apply tonemapping
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform sampler2D s_t1;
uniform sampler2D s_t2;
uniform sampler2D s_t3;
void main ()
{
gl_FragColor =
texture2D(s_t0, tc) +
texture2D(s_t1, tc) +
texture2D(s_t2, tc) +
texture2D(s_t3, tc) ;
}
#endif