Removed limit on strcat builtin's length.

Fixed issues with DP7 protocol.
Fixed .fatness.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3965 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-01-28 10:30:44 +00:00
parent aa72d14cec
commit 4496bb6ea0
28 changed files with 555 additions and 213 deletions

View File

@ -1149,6 +1149,7 @@ help:
@-echo "SDL - Attempt to use sdl for the current target"
@-echo "win32 - Mingw compile for win32"
@-echo "vc - Attempts to use msvc8+ to compile. Note: uses profile guided optimisations. You must build+run the relevent profile target before a release target will compile properly. Debug doesn't care."
@-echo "android is different - use 'make droid-help' for explicit help."
install:
-cp debug/*.* /opt/quake/
@ -1201,11 +1202,25 @@ droid-rel: droid/build.xml droid/ftekeystore
mkdir -p droid/libs/armeabi
@cp $(RELEASE_DIR)/libftedroid.so droid/libs/armeabi/
@cd droid && $(ANT) release
ifneq ($(DROID_PACKSC),)
@echo
@echo
@echo Adding custom data files (non-compressed)
@echo
zip droid/bin/FTEDroid-release-unsigned.apk -0 -j $(DROID_PACKSU)
endif
ifneq ($(DROID_PACKSU),)
@echo
@echo
@echo Adding custom data files (compressed)
@echo
zip droid/bin/FTEDroid-release-unsigned.apk -9 -j $(DROID_PACKSC)
endif
@echo
@echo
@echo Signing package... I hope you remember your password.
@echo
$(JAVATOOL)jarsigner -digestalg SHA1 -sigalg MD5withRSA -keystore droid/ftekeystore droid/bin/FTEDroid-release-unsigned.apk autogen
$(JAVATOOL)jarsigner $(JARSIGNARGS) -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-release-unsigned.apk $(RELEASE_DIR)/FTEDroid.apk
@ -1224,3 +1239,19 @@ droid-dbg: droid/build.xml
@cd droid && $(ANT) debug && $(ANT) debug install
cp droid/bin/FTEDroid-debug.apk $(DEBUG_DIR)/FTEDroid.apk
droid-help:
@-echo "make droid-dbg - compiles engine with debug info and signs package with debug key. Attempts to install onto emulator."
@-echo "make droid-opt - compiles engine with optimisations, but does not sign package. Not useful."
@-echo "make droid-rel - compiles engine with optimisations, adds custom data files, signs with private key, requires password."
@-echo
@-echo "Android Settings:
@-echo "DROID_PACKSC: specifies additional pak or pk3 files to compress into the package, which avoids extra configuration. Only used in release builds. You probably shouldn't use this except for really small packages. Any file seeks will give really poor performance."
@-echo "DROID_PACKSU: like DROID_PACKSC, but without compression. Faster loading times, but bigger. Use for anything that is already compressed (especially pk3s)."
@-echo "DROID_SDK_PATH: path to the android sdk install path."
@-echo "DROID_NDK_PATH: path to the android ndk install path."
@-echo "ANT: path and name of apache ant. Probably doesn't need to be set if you're on linux."
@-echo "JAVA_HOME: path of your java install. Commonly already set in environment settings."
@-echo "JAVATOOL: path to your java install's bin directory. Doesn't need to be set if its already in your path."
@-echo "JARSIGNARGS: Additional optional arguments to java's jarsigner program. You may want to put -storepass FOO in here, but what ever you do - keep it secure. Avoid bash history snooping, etc. If its not present, you will safely be prompted as required."
@-echo
@-echo "Note that 'make droid-rel' will automatically generate a keystore. If you forget the password, just do a 'make dist-clean'."

View File

@ -745,6 +745,9 @@ void DP5_ParseDelta(entity_state_t *s)
s->trans = 255;
s->scale = 16;
s->number = num;
s->colormod[0] = 32;
s->colormod[1] = 32;
s->colormod[2] = 32;
// s->active = true;
}
if (bits & E5_FLAGS)
@ -852,32 +855,30 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
//well, they come in in order of priorities, but that's not useful to us.
//I guess this means we'll have to go slowly.
packet_entities_t *pack, *oldpack;
//dp deltas update in-place
//this gets in the way of tracking multiple frames, and thus doesn't match fte too well
packet_entities_t *pack, oldpack;
static packet_entities_t newpack;
entity_state_t *to, *from;
unsigned short read;
int oldi;
int oldi, newi, lowesti, lowestv, newremaining;
qboolean remove;
cl_latestframenum = MSG_ReadLong();
cl_latestframenum = MSG_ReadLong(); /*server sequence to be acked*/
if (cls.protocol_nq >= CPNQ_DP7)
cl.ackedinputsequence = MSG_ReadLong();
cl.ackedinputsequence = MSG_ReadLong(); /*client input sequence which has been acked*/
cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].receivedtime = realtime;
pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities;
pack->servertime = cl.gametime;
oldpack = &cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities;
from = oldpack->entities;
oldpack = *pack;
oldi = 0;
pack->num_entities = 0;
for (oldi = 0; oldi < oldpack->num_entities; oldi++)
{
from = &oldpack->entities[oldi];
from->flags &= ~0x80000000;
}
newpack.num_entities = 0;
for (read = MSG_ReadShort(); read!=0x8000; read = MSG_ReadShort())
{
if (msg_badread)
@ -890,11 +891,11 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
from = &defaultstate;
for (oldi=0 ; oldi<oldpack->num_entities ; oldi++)
for (oldi=0 ; oldi<oldpack.num_entities ; oldi++)
{
if (read == oldpack->entities[oldi].number)
if (read == oldpack.entities[oldi].number)
{
from = &oldpack->entities[oldi];
from = &oldpack.entities[oldi];
from->flags |= 0x80000000; //so we don't copy it.
break;
}
@ -905,40 +906,82 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o(
continue;
}
if (pack->num_entities==pack->max_entities)
if (newpack.num_entities==newpack.max_entities)
{
pack->max_entities = pack->num_entities+16;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
newpack.max_entities = newpack.num_entities+16;
newpack.entities = BZ_Realloc(newpack.entities, sizeof(entity_state_t)*newpack.max_entities);
}
to = &pack->entities[pack->num_entities];
pack->num_entities++;
to = &newpack.entities[newpack.num_entities];
newpack.num_entities++;
memcpy(to, from, sizeof(*to));
to->number = read;
DP5_ParseDelta(to);
to->flags &= ~0x80000000;
}
//the pack has all the new ones in it, now copy the old ones in that wern't removed (or changed).
for (oldi = 0; oldi < oldpack->num_entities; oldi++)
{
from = &oldpack->entities[oldi];
if (from->flags & 0x80000000)
continue;
/*we're writing into the old one, clear it out prematurely (to make the malloc below trigger, and free it at the end)*/
pack->max_entities = 0;
pack->entities = NULL;
if (pack->num_entities==pack->max_entities)
//make sure there's enough space for both lists
if (oldpack.num_entities + newpack.num_entities>=pack->max_entities)
{
pack->max_entities = oldpack.num_entities + newpack.num_entities;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
}
pack->num_entities = 0;
//we're read all the new states, so have current info
//merge the packets, sorting the new ones (so the output is always sorted)
for (oldi = 0, lowesti=0, lowestv = 0, newremaining = newpack.num_entities; newremaining || oldi < oldpack.num_entities; )
{
if (oldi == oldpack.num_entities)
from = NULL;
else
{
pack->max_entities = pack->num_entities+16;
pack->entities = BZ_Realloc(pack->entities, sizeof(entity_state_t)*pack->max_entities);
from = &oldpack.entities[oldi];
if (from->flags & 0x80000000)
{
oldi++;
continue;
}
}
if (newremaining && !lowestv)
{
lowestv = 0x7ffffffe;
for(newi = 0; newi < newpack.num_entities; newi++)
{
if (newpack.entities[newi].flags & 0x80000000)
continue;
if (newpack.entities[newi].number < lowestv)
{
lowestv = newpack.entities[newi].number;
lowesti = newi;
}
}
}
/*use the new packet instead if we need to*/
if (!from || (from->number > lowestv && lowestv))
{
from = &newpack.entities[lowesti];
from->flags |= 0x80000000;
lowestv = 0; /*find the next oldest*/
newremaining--;
}
else
oldi++;
to = &pack->entities[pack->num_entities];
pack->num_entities++;
from = &oldpack->entities[oldi];
memcpy(to, from, sizeof(*to));
to->flags &= ~0x80000000;
}
BZ_Free(oldpack.entities);
}
void CLNQ_ParseEntity(unsigned int bits)
@ -1902,6 +1945,7 @@ void CL_TransitionEntities (void)
/*transition the ents and stuff*/
packnew = &cl.frames[newf].packet_entities;
packold = &cl.frames[oldf].packet_entities;
CL_TransitionPacketEntities(packnew, packold, servertime);
cl.currentpacktime = servertime;
cl.currentpackentities = packnew;
@ -2694,16 +2738,16 @@ void CL_ParsePlayerinfo (void)
state->fatness = 0;
#ifdef PEXT_SCALE
if (flags & PF_SCALE_Z && cls.fteprotocolextensions & PEXT_SCALE)
if (flags & PF_SCALE && cls.fteprotocolextensions & PEXT_SCALE)
state->scale = (float)MSG_ReadByte()/50;
#endif
#ifdef PEXT_TRANS
if (flags & PF_TRANS_Z && cls.fteprotocolextensions & PEXT_TRANS)
if (flags & PF_TRANS && cls.fteprotocolextensions & PEXT_TRANS)
state->alpha = MSG_ReadByte();
#endif
#ifdef PEXT_FATNESS
if (flags & PF_FATNESS_Z && cls.fteprotocolextensions & PEXT_FATNESS)
state->fatness = (float)MSG_ReadChar() / 16;
if (flags & PF_FATNESS && cls.fteprotocolextensions & PEXT_FATNESS)
state->fatness = (float)MSG_ReadChar();
#endif
#ifdef PEXT_HULLSIZE
if (cls.fteprotocolextensions & PEXT_HULLSIZE)
@ -3077,7 +3121,7 @@ void CL_LinkPlayers (void)
if (state->alpha != 255)
ent->flags |= Q2RF_TRANSLUCENT;
ent->fatness = state->fatness/16;
ent->fatness = state->fatness;
//
// angles
//

View File

@ -1567,7 +1567,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
cmd = &cl.frames[i].cmd[0];
*cmd = independantphysics[0];
cl.frames[i].senttime = realtime;
cl.frames[i].receivedtime = 0; // nq doesn't allow us to find our own packetloss
cl.frames[i].receivedtime = -1; // nq doesn't allow us to find our own packetloss
#ifdef CSQC_DAT
CSQC_Input_Frame(0, cmd);

View File

@ -3705,6 +3705,10 @@ void CL_ParseClientdata (void)
cl.parsecount = i;
i &= UPDATE_MASK;
parsecountmod = i;
if (CPNQ_IS_DP)
i = cls.netchan.incoming_sequence & UPDATE_MASK;
frame = &cl.frames[i];
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
frame->senttime = realtime - host_frametime;
@ -6021,7 +6025,19 @@ void CLNQ_ParseServerMessage (void)
cl.gametime = MSG_ReadFloat();
cl.gametimemark = realtime;
if (!CPNQ_IS_DP)
if (CPNQ_IS_DP)
{
int n = cls.netchan.incoming_sequence&UPDATE_MASK, o = (cls.netchan.incoming_sequence-1)&UPDATE_MASK;
cl.frames[n].packet_entities.num_entities = cl.frames[o].packet_entities.num_entities;
if (cl.frames[n].packet_entities.max_entities < cl.frames[o].packet_entities.num_entities)
{
cl.frames[n].packet_entities.max_entities = cl.frames[o].packet_entities.max_entities;
cl.frames[n].packet_entities.entities = BZ_Realloc(cl.frames[n].packet_entities.entities, sizeof(entity_state_t) * cl.frames[n].packet_entities.max_entities);
}
memcpy(cl.frames[n].packet_entities.entities, cl.frames[o].packet_entities.entities, sizeof(entity_state_t) * cl.frames[o].packet_entities.num_entities);
cl.frames[n].packet_entities.servertime = cl.frames[o].packet_entities.servertime;
}
else
{
// cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0;

View File

@ -1340,7 +1340,7 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles)
case MT_MASTERDP:
{
char *str;
str = va("%c%c%c%cgetservers %s %u empty full\x0A\n", 255, 255, 255, 255, com_protocolname.string, 3);
str = va("%c%c%c%cgetservers %s %u empty full"/*\x0A\n"*/, 255, 255, 255, 255, com_protocolname.string, 3);
NET_SendPollPacket (strlen(str), str, mast->adr);
}
break;
@ -1491,7 +1491,7 @@ void MasterInfo_Refresh(void)
// if (q1servers) //qw master servers
{
Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quakeworld", MT_MASTERHTTPQW, "gameaholic's QW master");
// Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quakeworld", MT_MASTERHTTPQW, "gameaholic's QW master");
//Master_AddMaster("satan.idsoftware.com:27000", MT_MASTERQW, "id Limbo");
//Master_AddMaster("satan.idsoftware.com:27002", MT_MASTERQW, "id CTF");
//Master_AddMaster("satan.idsoftware.com:27003", MT_MASTERQW, "id TeamFortress");
@ -1507,26 +1507,26 @@ void MasterInfo_Refresh(void)
//Master_AddMaster("kubus.rulez.pl:27000",MT_MASTERQW, "Kubus");
//Master_AddMaster("telefrag.me:27000",MT_MASTERQW, "Telefrag.ME");
//Master_AddMaster("master.teamdamage.com:27000", MT_MASTERQW, "TeamDamage");
Master_AddMaster("master.quakeservers.net:27000", MT_MASTERQW, "QuakeServers.net");
Master_AddMaster("qwmaster.fodquake.net:27000", MT_MASTERQW, "Fodquake.net");
Master_AddMaster("masterserver.exhale.de:27000", MT_MASTERQW, "team exhale");
Master_AddMaster("asgaard.morphos-team.net:27000", MT_MASTERQW, "Asgaard master server.");
Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server.");
Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers.");
// Master_AddMaster("master.quakeservers.net:27000", MT_MASTERQW, "QuakeServers.net");
// Master_AddMaster("qwmaster.fodquake.net:27000", MT_MASTERQW, "Fodquake.net");
// Master_AddMaster("masterserver.exhale.de:27000", MT_MASTERQW, "team exhale");
// Master_AddMaster("asgaard.morphos-team.net:27000", MT_MASTERQW, "Asgaard master server.");
// Master_AddMaster("qwmaster.ocrana.de:27000", MT_MASTERQW, "Ocrana2 master server.");
// Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers.");
}
// if (q1servers) //nq master servers
{
//Master_AddMaster("12.166.196.192:27950", MT_MASTERDP, "DarkPlaces Master 3");
Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTPNQ, "gameaholic's NQ master");
Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, "quakeone's server listing");
Master_AddMaster("ghdigital.com:27950", MT_MASTERDP, "DarkPlaces Master 1"); // LordHavoc
Master_AddMaster("dpmaster.deathmask.net:27950", MT_MASTERDP, "DarkPlaces Master 2"); // Willis
Master_AddMaster("dpmaster.tchr.no:27950", MT_MASTERDP, "DarkPlaces Master 3"); // tChr
// Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTPNQ, "gameaholic's NQ master");
// Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, "quakeone's server listing");
Master_AddMaster("69.59.212.88:27950"/*"ghdigital.com:27950"*/, MT_MASTERDP, "DarkPlaces Master 1"); // LordHavoc
Master_AddMaster("64.22.107.125:27950"/*"dpmaster.deathmask.net:27950"*/, MT_MASTERDP, "DarkPlaces Master 2"); // Willis
Master_AddMaster("92.62.40.73:27950"/*"dpmaster.tchr.no:27950"*/, MT_MASTERDP, "DarkPlaces Master 3"); // tChr
#ifdef IPPROTO_IPV6
//Master_AddMaster("[2001:41d0:2:1628::4450]:27950", MT_MASTERDP, "DarkPlaces Master 4"); // dpmaster.div0.qc.to (admin: divVerent)
#endif
Master_AddMaster("255.255.255.255:26000", MT_BCASTNQ, "Nearby Quake1 servers");
// Master_AddMaster("255.255.255.255:26000", MT_BCASTNQ, "Nearby Quake1 servers");
Master_AddMaster("255.255.255.255:26000", MT_BCASTDP, "Nearby DarkPlaces servers");
}
@ -1536,19 +1536,19 @@ void MasterInfo_Refresh(void)
//Master_AddMaster("satan.idsoftware.com:27900", MT_MASTERQ2, "id q2 Master.");
//Master_AddMaster("master.planetgloom.com:27900",MT_MASTERQ2, "Planetgloom.com");
//Master_AddMaster("master.q2servers.com:27900", MT_MASTERQ2, "q2servers.com");
Master_AddMaster("netdome.biz:27900", MT_MASTERQ2, "Netdome.biz");
Master_AddMaster("masterserver.exhale.de:27900",MT_MASTERQ2, "team exhale");
Master_AddMaster("255.255.255.255:27910", MT_BCASTQ2, "Nearby Quake2 UDP servers.");
// Master_AddMaster("netdome.biz:27900", MT_MASTERQ2, "Netdome.biz");
// Master_AddMaster("masterserver.exhale.de:27900",MT_MASTERQ2, "team exhale");
// Master_AddMaster("255.255.255.255:27910", MT_BCASTQ2, "Nearby Quake2 UDP servers.");
#ifdef USEIPX
Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers.");
// Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers.");
#endif
}
//q3
{
//Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake3", MT_MASTERHTTPQW, "gameaholic's Q3 master");
Master_AddMaster("master.quake3arena.com:27950", MT_MASTERQ3, "Quake3 master server.");
Master_AddMaster("masterserver.exhale.de:27950", MT_MASTERQ3, "team exhale");
// Master_AddMaster("master.quake3arena.com:27950", MT_MASTERQ3, "Quake3 master server.");
// Master_AddMaster("masterserver.exhale.de:27950", MT_MASTERQ3, "team exhale");
//Master_AddMaster("master3.quake3arena.com:27950", MT_MASTERQ3, "Quake3 master3 server.");
Master_AddMaster("255.255.255.255:27960", MT_BCASTQ3, "Nearby Quake3 UDP servers.");
}

View File

@ -39,16 +39,25 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
}
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
jint width, jint height)
jint width, jint height, jstring path)
{
vid.pixelwidth = width;
vid.pixelheight = height;
if (!sys_running)
{
char *args [] =
{
"ftedroid",
"-basepack",
(*env)->GetStringUTFChars(env, path, 0),
"",
""
//we should do this somewhere... (*env)->ReleaseStringUTFChars(env, path, parms.basedir);
};
quakeparms_t parms;
parms.basedir = "/sdcard/fte";
parms.argc = 0;
parms.argv = NULL;
parms.argc = 3;
parms.argv = args;
parms.memsize = sys_memheap = 8*1024*1024;
parms.membase = malloc(parms.memsize);
if (!parms.membase)
@ -57,7 +66,7 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
return;
}
Sys_Printf("Starting up\n");
Sys_Printf("Starting up (%s)\n", args[2]);
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();
@ -364,7 +373,8 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const
return true;
}
/*
#if 0
#include <android/asset_manager.h>
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm)
{
qboolean go = true;
@ -385,6 +395,7 @@ Sys_Printf("Found %s\n", f);
AAssetDir_close(ad);
return 0;
}
typedef struct
{
vfsfile_t funcs;
@ -445,4 +456,4 @@ vfsfile_t *Sys_OpenAsset(char *fname)
return (vfsfile_t*)file;
}
*/
#endif

View File

@ -1298,7 +1298,19 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
mesh->normals_array = p1n;
mesh->snormals_array = p1s;
mesh->tnormals_array = p1t;
mesh->xyz_array = p1v;
if (expand)
{
for (i = 0; i < mesh->numvertexes; i++)
{
mesh->xyz_array[i][0] = p1v[i][0] + p1n[i][0]*expand;
mesh->xyz_array[i][1] = p1v[i][1] + p1n[i][1]*expand;
mesh->xyz_array[i][2] = p1v[i][2] + p1n[i][2]*expand;
}
return;
}
else
mesh->xyz_array = p1v;
}
else
{
@ -1312,20 +1324,8 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
mesh->xyz_array[i][1] = p1v[i][1]*lerp + p2v[i][1]*blerp;
mesh->xyz_array[i][2] = p1v[i][2]*lerp + p2v[i][2]*blerp;
}
}
if (expand)
{
if (mesh->xyz_array == p1v)
{
for (i = 0; i < mesh->numvertexes; i++)
{
mesh->xyz_array[i][0] = p1v[i][0] + mesh->normals_array[i][0]*expand;
mesh->xyz_array[i][1] = p1v[i][1] + mesh->normals_array[i][1]*expand;
mesh->xyz_array[i][2] = p1v[i][2] + mesh->normals_array[i][2]*expand;
}
}
else
if (expand)
{
for (i = 0; i < mesh->numvertexes; i++)
{

View File

@ -1681,11 +1681,14 @@ char *COM_FileExtension (const char *in)
{
static char exten[8];
int i;
char *dot;
while (*in && *in != '.')
in++;
if (!*in)
for (dot = in + strlen(in); dot >= in && *dot != '.'; dot--)
;
if (dot < in)
return "";
in = dot;
in++;
for (i=0 ; i<7 && *in ; i++,in++)
exten[i] = *in;
@ -1714,6 +1717,7 @@ void COM_CleanUpPath(char *str)
}
while ((dots = strstr(str, "..")))
{
critisize = 0;
for (slash = dots-2; slash >= str; slash--)
{
if (*slash == '/')
@ -1723,6 +1727,11 @@ void COM_CleanUpPath(char *str)
break;
}
}
if (critisize != 3)
{
memmove(dots, dots+2, strlen(dots+2)+1);
critisize = 3;
}
}
while(*str == '/')
{

View File

@ -25,9 +25,10 @@ struct
{
const char *extension;
searchpathfuncs_t *funcs;
qboolean loadscan;
} searchpathformats[64];
int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs)
int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs, qboolean loadscan)
{
unsigned int i;
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
@ -42,6 +43,7 @@ int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs)
searchpathformats[i].extension = extension;
searchpathformats[i].funcs = funcs;
searchpathformats[i].loadscan = loadscan;
com_fschanged = true;
return i+1;
@ -1441,7 +1443,7 @@ static searchpath_t *FS_AddPathHandle(const char *purepath, const char *probable
{
for (i = 0; i < sizeof(searchpathformats)/sizeof(searchpathformats[0]); i++)
{
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew)
if (!searchpathformats[i].extension || !searchpathformats[i].funcs || !searchpathformats[i].funcs->OpenNew || !searchpathformats[i].loadscan)
continue;
if (loadstuff & (1<<i))
{
@ -1754,7 +1756,7 @@ const gamemode_info_t gamemode_info[] = {
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
//protocol name(dpmaster) exename cmdline switch identifying file exec dir1 dir2 dir3 dir(fte) full name
{"Darkplaces-Quake", "q1", "-quake", {"id1/pak0.pak"}, NULL, {"id1", "qw", "fte"}, "Quake"},
{"DarkPlaces-Quake", "q1", "-quake", {"id1/pak0.pak"}, NULL, {"id1", "qw", "fte"}, "Quake"},
{"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"},
{"Darkplaces-Rogue", "rogue", "-rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"},
{"Nexuiz", "nexuiz", "-nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"},
@ -2035,7 +2037,7 @@ void FS_AddRootWads(void)
if (!pak)
return;
FS_AddPathHandle(fname, fname, &doomwadfilefuncs, pak, true, false, false, (unsigned int)-1);
FS_AddPathHandle(fname, fname, &doomwadfilefuncs, pak, true, false, true, (unsigned int)-1);
}
#endif
@ -2053,7 +2055,7 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
searchpath_t *next;
//a lame way to fix pure paks
//a lame way to fix pure paks (securitywise, the rest of the engine doesn't care if the filesystem changes too much)
#ifndef SERVERONLY
if (cls.state && com_purepaths)
{
@ -2093,10 +2095,10 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
if (oldbase == oldpaths)
com_base_searchpaths = com_searchpaths;
if (oldpaths->funcs == &osfilefuncs)
FS_AddGameDirectory(oldpaths->purepath, oldpaths->handle, reloadflags);
oldpaths->funcs->ClosePath(oldpaths->handle);
if (oldpaths->isexplicit)
FS_AddPathHandle(oldpaths->purepath, oldpaths->purepath, oldpaths->funcs, oldpaths->handle, oldpaths->copyprotected, false, true, reloadflags);
else
oldpaths->funcs->ClosePath(oldpaths->handle);
Z_Free(oldpaths);
oldpaths = next;
}
@ -2390,7 +2392,7 @@ void FS_Shutdown(void)
void FS_StartupWithGame(int gamenum)
{
int i;
int i, j;
#ifdef AVAIL_ZLIB
LibZ_Init();
@ -2403,6 +2405,47 @@ void FS_StartupWithGame(int gamenum)
FS_AddRootWads();
#endif
i = COM_CheckParm ("-basepack");
while (i && i < com_argc-1)
{
// Con_Printf("found -basepack: %s\n", com_argv[i+1]);
char *ext = COM_FileExtension(com_argv[i+1]);
vfsfile_t *vfs = VFSOS_Open(com_argv[i+1], "rb");
void *pak;
if (!vfs)
Con_Printf("Unable to open %s - missing?\n", com_argv[i+1]);
else
{
for (j = 0; j < sizeof(searchpathformats)/sizeof(searchpathformats[0]); j++)
{
if (!searchpathformats[j].extension || !searchpathformats[j].funcs || !searchpathformats[j].funcs->OpenNew)
continue;
if (!strcmp(ext, searchpathformats[j].extension))
{
pak = searchpathformats[j].funcs->OpenNew(vfs, com_argv[i+1]);
if (pak)
{
FS_AddPathHandle("", com_argv[i+1], searchpathformats[j].funcs, pak, true, false, true, (unsigned int)-1);
}
else
{
Con_Printf("Unable to open %s - corrupt?\n", com_argv[i+1]);
VFS_CLOSE(vfs);
}
vfs = NULL;
break;
}
}
if (vfs)
{
VFS_CLOSE(vfs);
Con_Printf("Unable to open %s - unsupported?\n", com_argv[i+1]);
}
}
i = COM_CheckNextParm ("-basepack", i);
}
//
// start up with id1 by default
//
@ -2734,16 +2777,18 @@ extern searchpathfuncs_t zipfilefuncs;
extern searchpathfuncs_t doomwadfilefuncs;
void FS_RegisterDefaultFileSystems(void)
{
FS_RegisterFileSystemType("pak", &packfilefuncs);
FS_RegisterFileSystemType("pak", &packfilefuncs, true);
#if !defined(_WIN32) && !defined(ANDROID)
/*for systems that have case sensitive paths, also include *.PAK */
FS_RegisterFileSystemType("PAK", &packfilefuncs);
FS_RegisterFileSystemType("PAK", &packfilefuncs, true);
#endif
#ifdef AVAIL_ZLIB
FS_RegisterFileSystemType("pk3", &zipfilefuncs);
FS_RegisterFileSystemType("pk4", &zipfilefuncs);
FS_RegisterFileSystemType("pk3", &zipfilefuncs, true);
FS_RegisterFileSystemType("pk4", &zipfilefuncs, true);
FS_RegisterFileSystemType("apk", &zipfilefuncs, false);
FS_RegisterFileSystemType("zip", &zipfilefuncs, false);
#endif
#ifdef DOOMWADS
FS_RegisterFileSystemType("wad", &doomwadfilefuncs);
FS_RegisterFileSystemType("wad", &doomwadfilefuncs, true);
#endif
}

View File

@ -27,5 +27,5 @@ extern searchpathfuncs_t osfilefuncs;
vfsfile_t *VFSOS_Open(const char *osname, const char *mode);
vfsfile_t *FS_DecompressGZip(vfsfile_t *infile);
int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs);
int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs, qboolean loadscan);
void FS_UnRegisterFileSystemType(int idx);

View File

@ -246,6 +246,7 @@ void *FSPAK_LoadPackFile (vfsfile_t *file, const char *desc)
CRC_ProcessByte(&crc, ((qbyte *)&info)[j]);
*/
strcpy (newfiles[i].name, info.name);
newfiles[i].name[MAX_QPATH-1] = 0; //paranoid
COM_CleanUpPath(newfiles[i].name); //blooming tanks.
newfiles[i].filepos = LittleLong(info.filepos);
newfiles[i].filelen = LittleLong(info.filelen);

View File

@ -602,6 +602,10 @@ qboolean VFSZIP_Seek (struct vfsfile_s *file, unsigned long pos)
vfsz->parent->currentfile = NULL; //make it not us, so the next read starts at the right place
}
}
else
{
vfsz->parent->currentfile = NULL;
}
if (pos < 0 || pos > vfsz->length)
return false;

View File

@ -935,32 +935,42 @@ void QCBUILTIN PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals)
G_INT(OFS_RETURN) = PR_SetString(prinst, pf_fopen_files[fnum].data);
return;
}
//read up to the next \n, ignoring any \rs.
o = pr_string_temp;
max = o + sizeof(pr_string_temp)-1;
s = pf_fopen_files[fnum].data+pf_fopen_files[fnum].ofs;
eof = pf_fopen_files[fnum].data+pf_fopen_files[fnum].len;
while(s < eof)
if (pf_fopen_files[fnum].accessmode == FRIK_FILE_READNL)
{
c = *s++;
if (c == '\n' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL)
break;
if (c == '\r' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL)
continue;
if (o == max)
break;
*o++ = c;
if (pf_fopen_files[fnum].ofs >= pf_fopen_files[fnum].len)
G_INT(OFS_RETURN) = 0; //EOF
else
RETURN_TSTRING(pf_fopen_files[fnum].data);
}
*o = '\0';
pf_fopen_files[fnum].ofs = s - pf_fopen_files[fnum].data;
if (!pr_string_temp[0] && s == eof)
G_INT(OFS_RETURN) = 0; //EOF
else
RETURN_TSTRING(pr_string_temp);
{
//read up to the next \n, ignoring any \rs.
o = pr_string_temp;
max = o + sizeof(pr_string_temp)-1;
s = pf_fopen_files[fnum].data+pf_fopen_files[fnum].ofs;
eof = pf_fopen_files[fnum].data+pf_fopen_files[fnum].len;
while(s < eof)
{
c = *s++;
if (c == '\n' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL)
break;
if (c == '\r' && pf_fopen_files[fnum].accessmode != FRIK_FILE_READNL)
continue;
if (o == max)
break;
*o++ = c;
}
*o = '\0';
pf_fopen_files[fnum].ofs = s - pf_fopen_files[fnum].data;
if (!pr_string_temp[0] && s >= eof)
G_INT(OFS_RETURN) = 0; //EOF
else
RETURN_TSTRING(pr_string_temp);
}
}
static void PF_fwrite (progfuncs_t *prinst, int fnum, char *msg, int len)
@ -1833,64 +1843,98 @@ void QCBUILTIN PF_forgetstring(progfuncs_t *prinst, struct globalvars_s *pr_glob
void QCBUILTIN PF_dupstring(progfuncs_t *prinst, struct globalvars_s *pr_globals) //frik_file
{
char *s, *in;
int len;
in = PF_VarString(prinst, 0, pr_globals);
len = strlen(in)+1;
s = Z_TagMalloc(len+8, Z_QC_TAG);
((int *)s)[0] = PRSTR;
((int *)s)[1] = len;
strcpy(s+8, in);
RETURN_SSTRING(s+8);
char *buf;
int len = 0;
char *s[8];
int l[8];
int i;
for (i = 0; i < *prinst->callargc; i++)
{
s[i] = PR_GetStringOfs(prinst, OFS_PARM0+i*3);
l[i] = strlen(s[i]);
len += l[i];
}
len++; /*for the null*/
buf = Z_TagMalloc(len+8, Z_QC_TAG);
RETURN_SSTRING(buf+8);
((int *)buf)[0] = PRSTR;
((int *)buf)[1] = len;
buf += 8;
len = 0;
for (i = 0; i < *prinst->callargc; i++)
{
memcpy(buf, s[i], l[i]);
buf += l[i];
}
*buf = '\0';
}
//string(string str1, string str2) strcat
void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char *buf;
int len = 0;
char *s[8];
int l[8];
int i;
for (i = 0; i < *prinst->callargc; i++)
{
s[i] = PR_GetStringOfs(prinst, OFS_PARM0+i*3);
l[i] = strlen(s[i]);
len += l[i];
}
len++; /*for the null*/
((int *)pr_globals)[OFS_RETURN] = prinst->AllocTempString(prinst, &buf, len);
len = 0;
for (i = 0; i < *prinst->callargc; i++)
{
memcpy(buf, s[i], l[i]);
buf += l[i];
}
*buf = '\0';
}
//returns a section of a string as a tempstring
void QCBUILTIN PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int i, start, length;
int start, length, slen;
char *s;
char string[4096];
char *string;
s = PR_GetStringOfs(prinst, OFS_PARM0);
start = G_FLOAT(OFS_PARM1);
length = G_FLOAT(OFS_PARM2);
slen = strlen(s);
if (start < 0)
start = strlen(s)-start;
start = slen-start;
if (length < 0)
length = strlen(s)-start+(length+1);
length = slen-start+(length+1);
if (start < 0)
{
// length += start;
start = 0;
}
if (start >= strlen(s) || length<=0 || !*s)
if (start >= slen || length<=0)
{
RETURN_TSTRING("");
return;
}
if (length >= MAXTEMPBUFFERLEN)
length = MAXTEMPBUFFERLEN-1;
s += start;
slen -= start;
for (i = 0; i < start && *s; i++, s++)
;
if (length > slen)
length = slen;
for (i = 0; *s && i < length; i++, s++)
string[i] = *s;
string[i] = 0;
((int *)pr_globals)[OFS_RETURN] = prinst->AllocTempString(prinst, &string, length+1);
RETURN_TSTRING(string);
}
//string(string str1, string str2) strcat
void QCBUILTIN PF_strcat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char dest[4096];
char *src = PF_VarString(prinst, 0, pr_globals);
Q_strncpyz(dest, src, MAXTEMPBUFFERLEN);
RETURN_TSTRING(dest);
memcpy(string, s, length);
string[length] = '\0';
}
void QCBUILTIN PF_strlen(progfuncs_t *prinst, struct globalvars_s *pr_globals)

View File

@ -395,13 +395,13 @@ enum clcq2_ops_e
#define PF_EXTRA_PFS (1<<15)
#ifdef PEXT_SCALE
#define PF_SCALE_Z (1<<16)
#define PF_SCALE (1<<16)
#endif
#ifdef PEXT_TRANS
#define PF_TRANS_Z (1<<17)
#define PF_TRANS (1<<17)
#endif
#ifdef PEXT_FATNESS
#define PF_FATNESS_Z (1<<18)
#define PF_FATNESS (1<<18)
#endif
#define PF_COLOURMOD (1<<19)

View File

@ -20,6 +20,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fteqcc", "..\qclib\dotnet20
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\dotnet2005\qtvprox.vcproj", "{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "droid", "droid\droid.vcproj", "{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
D3DDebug|Win32 = D3DDebug|Win32
@ -296,6 +298,30 @@ Global
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|Win32.ActiveCfg = Release|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|Win32.Build.0 = Release|Win32
{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}.Release|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.D3DDebug|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.D3DRelease|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.D3DRelease|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Debug|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Debug|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.GLDebug|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.GLDebug|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.GLRelease|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.GLRelease|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MDebug|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MDebug|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MinGLDebug|x64.ActiveCfg = Debug|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MinGLRelease|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MinGLRelease|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MRelease|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.MRelease|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -664,6 +664,7 @@
BasicRuntimeChecks="3"
RuntimeLibrary="1"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="2"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="quakedef.h"
@ -1683,6 +1684,7 @@
StringPooling="true"
ExceptionHandling="0"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
FloatingPointModel="2"
RuntimeTypeInfo="false"
UsePrecompiledHeader="2"

View File

@ -32,6 +32,21 @@ public class FTEDroidActivity extends Activity
private class FTERenderer implements GLSurfaceView.Renderer
{
private boolean inited;
private String basedir;
FTERenderer(Context ctx)
{
try
{
android.content.pm.PackageInfo info = ctx.getPackageManager().getPackageInfo("com.fteqw", 0);
basedir = info.applicationInfo.sourceDir;
}
catch(android.content.pm.PackageManager.NameNotFoundException e)
{
/*oh well, can just use the homedir instead*/
}
}
@Override
public void onDrawFrame(GL10 gl)
{
@ -43,7 +58,7 @@ public class FTEDroidActivity extends Activity
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
FTEDroidEngine.init(width, height);
FTEDroidEngine.init(width, height, basedir);
inited = true;
}
@Override
@ -135,7 +150,7 @@ public class FTEDroidActivity extends Activity
{
super(context);
rndr = new FTERenderer();
rndr = new FTERenderer(getContext());
// setEGLConfigChooser(new FTEEGLConfig());
setRenderer(rndr);
setFocusable(true);

View File

@ -2,7 +2,7 @@ package com.fteqw;
public class FTEDroidEngine
{
public static native void init(int w, int h); /* init/reinit */
public static native void init(int w, int h, String basedir); /* init/reinit */
public static native void frame();
public static native void keypress(int down, int qkey, int unicode);
public static native void motion(int act, float x, float y);

View File

@ -443,6 +443,8 @@ notimplemented:
{
VFS_CLOSE(cl->file);
cl->file = NULL;
IWebPrintf("Download complete\n");
}
else
cl->outbufferused+=ammount;

View File

@ -813,10 +813,17 @@ reeval:
i = (unsigned int)OPA->_int + (unsigned int)OPB->_float;
if ((unsigned int)i >= addressableused)
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "bad pointer read in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name));
i = (unsigned int)OPB->_float;
ptr = (eval_t*)PR_StringToNative(progfuncs, OPA->_int);
if (i > strlen((char*)ptr))
{
pr_xstatement = st-pr_statements;
PR_RunError (progfuncs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), i, ptr);
}
ptr = (eval_t*)((char*)ptr + i);
}
ptr = QCPOINTERM(i);
else
ptr = QCPOINTERM(i);
OPC->_float = *(unsigned char *)ptr;
break;
case OP_LOADP_I:

View File

@ -658,6 +658,38 @@ string_t PR_AllocTempString (progfuncs_t *progfuncs, char *str)
return (string_t)((unsigned int)i | 0x40000000);
}
string_t PR_AllocTempStringLen (progfuncs_t *progfuncs, char **str, int len)
{
char **ntable;
int newmax;
int i;
if (!str)
return 0;
if (prinst->numtempstrings == prinst->maxtempstrings)
{
newmax = prinst->maxtempstrings += 1024;
prinst->maxtempstrings += 1024;
ntable = memalloc(sizeof(char*) * newmax);
memcpy(ntable, prinst->tempstrings, sizeof(char*) * prinst->numtempstrings);
prinst->maxtempstrings = newmax;
if (prinst->tempstrings)
memfree(prinst->tempstrings);
prinst->tempstrings = ntable;
}
i = prinst->numtempstrings;
if (i == 0x10000000)
return 0;
prinst->numtempstrings++;
prinst->tempstrings[i] = memalloc(len);
*str = prinst->tempstrings[i];
return (string_t)((unsigned int)i | 0x40000000);
}
void PR_FreeTemps (progfuncs_t *progfuncs, int depth)
{
@ -771,7 +803,8 @@ progfuncs_t deffuncs = {
PR_QueryField,
QC_ClearEdict,
QC_FindPrefixedGlobals,
PRAddressableAlloc
PRAddressableAlloc,
PR_AllocTempStringLen
};
#undef printf

View File

@ -353,6 +353,8 @@ enum qcop_e {
OP_MULSTORE_VI,
OP_MULSTOREP_VI,
OP_LOADA_STRUCT,
OP_NUMOPS
};

View File

@ -140,6 +140,8 @@ struct progfuncs_s {
void (*FindPrefixGlobals) (progfuncs_t *progfuncs, char *prefix, void (*found) (progfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type) );
void *(*AddressableAlloc) (progfuncs_t *progfuncs, int ammount); /*returns memory within the qc block, use stringtoprogs to get a usable qc pointer/string*/
string_t (*AllocTempString) (progfuncs_t *prinst, char **str, unsigned int len);
};
typedef struct progexterns_s {

View File

@ -544,6 +544,8 @@ QCC_opcode_t pr_opcodes[] =
{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},
{7, "=", "LOADA_STRUCT", 6, ASSOC_LEFT, &type_float, &type_integer, &type_float},
{0, NULL}
};
@ -2110,6 +2112,12 @@ 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_LOADA_STRUCT:
/*emit this anyway. if it reaches runtime then you messed up.
this is valid only if you do &foo[0]*/
break;
case OP_IF_S:
var_c = QCC_PR_GetDef(type_string, "string_null", NULL, true, 0, false);
numstatements--;
@ -2331,6 +2339,8 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
case OP_ADDSTOREP_V:
case OP_SUBSTOREP_F:
case OP_SUBSTOREP_I:
case OP_ADDSTOREP_I:
case OP_ADDSTOREP_F:
case OP_MULSTOREP_F:
case OP_DIVSTOREP_F:
@ -2344,35 +2354,57 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
{
int st;
int need_lock = false;
for (st = numstatements-2; st>=0; st--)
if (var_b->temp)
{
if (statements[st].op == OP_ADDRESS)
for (st = numstatements-2; st>=0; st--)
{
if (statements[st].op == OP_ADDRESS)
if (statements[st].c == var_b->ofs)
break;
if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
need_lock = true;
if (statements[st].c == var_b->ofs)
{
st = -1;
break;
if ((statements[st].op >= OP_CALL0 && statements[st].op <= OP_CALL8) || (statements[st].op >= OP_CALL1H && statements[st].op <= OP_CALL8H))
need_lock = true;
if (statements[st].c == var_b->ofs)
QCC_PR_ParseWarning(0, "Temp-reuse may have broken your %s", op->name);
}
}
}
if (st < 0)
QCC_PR_ParseError(ERR_INTERNAL, "XSTOREP_F: pointer was not generated from previous statement");
else
st = -1;
var_c = QCC_GetTemp(*op->type_c);
if (need_lock)
QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
if (st < 0)
{
/*generate new OP_LOADP instruction*/
statement->op = ((*op->type_c)->type==ev_vector)?OP_LOADP_V:OP_LOADP_F;
statement->a = var_b->ofs;
statement->b = var_c->ofs;
statement->c = 0;
}
else
{
/*it came from an OP_ADDRESS - st says the instruction*/
var_c = QCC_GetTemp(*op->type_c);
if (need_lock)
QCC_LockTemp(var_c); /*that temp needs to be preserved over calls*/
statement_linenums[statement-statements] = statement_linenums[st];
statement->op = OP_ADDRESS;
statement->a = statements[st].a;
statement->b = statements[st].b;
statement->c = statements[st].c;
/*generate new OP_ADDRESS instruction - FIXME: the arguments may have changed since the original instruction*/
statement_linenums[statement-statements] = statement_linenums[st];
statement->op = OP_ADDRESS;
statement->a = statements[st].a;
statement->b = statements[st].b;
statement->c = statements[st].c;
statement_linenums[st] = pr_source_line;
statements[st].op = ((*op->type_c)->type==ev_vector)?OP_LOAD_V:OP_LOAD_F;
statements[st].a = statements[st].a;
statements[st].b = statements[st].b;
statements[st].c = var_c->ofs;
/*convert old one to an OP_LOAD*/
statement_linenums[st] = pr_source_line;
statements[st].op = ((*op->type_c)->type==ev_vector)?OP_LOAD_V:OP_LOAD_F;
statements[st].a = statements[st].a;
statements[st].b = statements[st].b;
statements[st].c = var_c->ofs;
}
}
statement = &statements[numstatements];
@ -2396,6 +2428,9 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
case OP_SUBSTOREP_F:
statement->op = OP_SUB_F;
break;
case OP_SUBSTOREP_I:
statement->op = OP_SUB_I;
break;
case OP_SUBSTOREP_IF:
statement->op = OP_SUB_IF;
break;
@ -2423,6 +2458,9 @@ QCC_def_t *QCC_PR_Statement (QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var_
case OP_ADDSTOREP_F:
statement->op = OP_ADD_F;
break;
case OP_ADDSTOREP_I:
statement->op = OP_ADD_I;
break;
case OP_MULSTOREP_F:
statement->op = OP_MUL_F;
break;
@ -3703,7 +3741,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could
e = QCC_PR_Statement(pr_opcodes+OP_CONV_FTOI, e, NULL, NULL);
else if (p->type == ev_float && e->type->type == ev_integer) //convert float -> int... is this a constant?
e = QCC_PR_Statement(pr_opcodes+OP_CONV_ITOF, e, NULL, NULL);
else if (p->type == ev_function && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
else if ((p->type == ev_function && p->type == ev_string) && e->type->type == ev_integer && e->constant && !((int*)qcc_pr_globals)[e->ofs])
{ //you're allowed to use int 0 to pass a null function pointer
//this is basically because __NULL__ is defined as ~0 (int 0)
}
@ -4448,6 +4486,11 @@ QCC_def_t *QCC_PR_ParseValue (QCC_type_t *assumeclass, pbool allowarrayassign)
case ev_function:
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_FNC], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
break;
case ev_struct:
case ev_union:
//FIXME...
d = QCC_PR_Statement(&pr_opcodes[OP_LOADA_STRUCT], d, QCC_SupplyConversion(idx, ev_integer, true), NULL);
break;
default:
QCC_PR_ParseError(ERR_NOVALIDOPCODES, "No op available. Try assembler");
}
@ -4846,6 +4889,15 @@ QCC_def_t *QCC_PR_Term (void)
/*you may cast from const 0 to any type of same size for free (from either int or float for simplicity)*/
else if (newtype->size == e->type->size && (e->type->type == ev_integer || e->type->type == ev_float) && e->constant && !G_INT(e->ofs))
{
//direct cast
e2 = (void *)qccHunkAlloc (sizeof(QCC_def_t));
memset (e2, 0, sizeof(QCC_def_t));
e2->type = newtype;
e2->ofs = e->ofs;
e2->constant = true;
e2->temp = e->temp;
return e2;
}
/*cast from int->float will convert*/
else if (newtype->type == ev_float && e->type->type == ev_integer)
@ -4993,6 +5045,9 @@ int QCC_canConv(QCC_def_t *from, etype_t to)
if (from->type->type == ev_integer && to == ev_function)
return 1;
if (from->constant && from->arraysize == 0 && (from->type->type == ev_integer || from->type->type == ev_float) && !G_INT(from->ofs))
return 2;
return -100;
}
/*

View File

@ -1664,6 +1664,11 @@ void QCC_PR_BeginCompilation (void *memory, int memsize)
type_floatfield->aux_type = type_float;
type_pointer->aux_type = QCC_PR_NewType("pointeraux", ev_float);
type_intpointer = QCC_PR_NewType("__intpointer", ev_pointer);
type_intpointer->aux_type = type_integer;
type_floatpointer = QCC_PR_NewType("__floatpointer", ev_pointer);
type_floatpointer->aux_type = type_float;
type_function->aux_type = type_void;
//type_field->aux_type = type_float;

View File

@ -1232,19 +1232,19 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
#ifdef PEXT_SCALE //this is graphics, not physics
if (ent->fteext & PEXT_SCALE)
{
if (ent->scale && ent->scale != 1) pflags |= PF_SCALE_Z;
if (ent->scale && ent->scale != 1) pflags |= PF_SCALE;
}
#endif
#ifdef PEXT_TRANS
if (ent->fteext & PEXT_TRANS)
{
if (ent->transparency) pflags |= PF_TRANS_Z;
if (ent->transparency) pflags |= PF_TRANS;
}
#endif
#ifdef PEXT_FATNESS
if (ent->fteext & PEXT_FATNESS)
{
if (ent->fatness) pflags |= PF_FATNESS_Z;
if (ent->fatness) pflags |= PF_FATNESS;
}
#endif
}
@ -1384,16 +1384,16 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
MSG_WriteByte (msg, ent->weaponframe);
#ifdef PEXT_SCALE
if (pflags & PF_SCALE_Z)
if (pflags & PF_SCALE)
MSG_WriteByte (msg, ent->scale*50);
#endif
#ifdef PEXT_TRANS
if (pflags & PF_TRANS_Z)
if (pflags & PF_TRANS)
MSG_WriteByte (msg, (qbyte)(ent->transparency*255));
#endif
#ifdef PEXT_FATNESS
if (pflags & PF_FATNESS_Z)
MSG_WriteChar (msg, ent->fatness*10);
if (pflags & PF_FATNESS)
MSG_WriteChar (msg, ent->fatness);
#endif
#ifdef PEXT_HULLSIZE //shrunken or crouching in halflife levels. (possibly enlarged)
if (pflags & PF_HULLSIZE_Z)
@ -2337,7 +2337,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
}
#endif
#ifdef PEXT_FATNESS
state->fatness = ent->xv->fatness*16;
state->fatness = ent->xv->fatness;
#endif
}

View File

@ -1055,18 +1055,6 @@ void SVC_Status (void)
slots++;
}
//No. Not a good idea.
/* if (slots>16)
Con_Printf ("5016 35 54 114 \"annigilator\" \"soldier\" 0 0\n");
if (slots>14)
Con_Printf ("5012 32 85 162 \"FatBastard\" \"hacker\" 1 4\n");
if (slots>12)
Con_Printf ("5013 23 64 94 \"DeathBunny\" \"soldier\" 13 13\n");
if (slots>10)
Con_Printf ("5010 32 85 162 \"??\" \"hacker\" 13 13\n");
if (slots>8)
Con_Printf ("5011 32 85 162 \"??a???\" \"hacker\" 4 4\n");
*/
SV_EndRedirect ();
}
@ -1083,6 +1071,9 @@ void SVC_GetInfo (char *challenge, int fullstatus)
char *gamestatus;
eval_t *v;
if (!sv_listen_nq.ival && !sv_listen_dp.ival)
return;
for (i=0 ; i<MAX_CLIENTS ; i++)
{
cl = &svs.clients[i];
@ -1118,7 +1109,7 @@ void SVC_GetInfo (char *challenge, int fullstatus)
//first line is the serverinfo
Q_strncpyz(resp, svs.info, sizeof(response) - (resp-response));
//this is a DP protocol, so some QW fields are not needed
//this is a DP protocol query, so some QW fields are not needed
Info_RemoveKey(resp, "maxclients");
Info_RemoveKey(resp, "map");
Info_SetValueForKey(resp, "gamename", com_protocolname.string, sizeof(response) - (resp-response));
@ -4336,7 +4327,7 @@ void Master_Heartbeat (void)
}
break;
case MP_DARKPLACES:
if (sv_listen_dp.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
if (sv_listen_dp.value || sv_listen_nq.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{
if (sv_reportheartbeats.value)
Con_Printf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), sv_masterlist[i].adr), sv_masterlist[i].cv.string);

View File

@ -1937,9 +1937,6 @@ void SV_UpdateToReliableMessages (void)
char oname[80];
Q_strncpyz(oname, host_client->name, sizeof(oname));
#pragma warningmsg("Debug line to try to find OneManClan's issue\n");
Con_Printf("DEBUG: .netname= \"%s\" -> \"%s\" (f=%x n=%p b=%p)\n", oname, name, host_client->edict->v->netname, host_client->name, host_client->namebuf);
Con_DPrintf("Client %s programatically renamed to %s\n", host_client->name, name);
Info_SetValueForKey(host_client->userinfo, "name", name, sizeof(host_client->userinfo));
SV_ExtractFromUserinfo (host_client);