From 4496bb6ea0ed7a3dbafbcf71cb3a7269dbe9ca66 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 28 Jan 2012 10:30:44 +0000 Subject: [PATCH] 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 --- engine/Makefile | 33 +++- engine/client/cl_ents.c | 122 +++++++++----- engine/client/cl_input.c | 2 +- engine/client/cl_parse.c | 18 ++- engine/client/net_master.c | 40 ++--- engine/client/sys_droid.c | 23 ++- engine/common/com_mesh.c | 28 ++-- engine/common/common.c | 15 +- engine/common/fs.c | 75 +++++++-- engine/common/fs.h | 2 +- engine/common/fs_pak.c | 1 + engine/common/fs_zip.c | 4 + engine/common/pr_bgcmd.c | 152 +++++++++++------- engine/common/protocol.h | 6 +- engine/dotnet2005/ftequake.sln | 26 +++ engine/dotnet2005/ftequake.vcproj | 2 + .../droid/src/com/fteqw/FTEDroidActivity.java | 19 ++- .../droid/src/com/fteqw/FTEDroidEngine.java | 2 +- engine/http/httpserver.c | 2 + engine/qclib/execloop.h | 13 +- engine/qclib/initlib.c | 35 +++- engine/qclib/pr_comp.h | 2 + engine/qclib/progslib.h | 2 + engine/qclib/qcc_pr_comp.c | 101 +++++++++--- engine/qclib/qccmain.c | 5 + engine/server/sv_ents.c | 16 +- engine/server/sv_main.c | 19 +-- engine/server/sv_send.c | 3 - 28 files changed, 555 insertions(+), 213 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 17e408e1..1a6171e5 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -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'." diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 2a15405f..72de0ab8 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -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 ; oldinum_entities ; oldi++) + for (oldi=0 ; oldientities[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 // diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index e3101a9e..71073561 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -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); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 02a330db..bea6287e 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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; diff --git a/engine/client/net_master.c b/engine/client/net_master.c index d73be4b9..598b4a4b 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -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."); } diff --git a/engine/client/sys_droid.c b/engine/client/sys_droid.c index 447cf31b..08e807cc 100644 --- a/engine/client/sys_droid.c +++ b/engine/client/sys_droid.c @@ -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 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 diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 5b2d1a93..0c313f10 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -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++) { diff --git a/engine/common/common.c b/engine/common/common.c index c72f8764..be1872a4 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -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 == '/') { diff --git a/engine/common/fs.c b/engine/common/fs.c index 5bbc1219..811777a2 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -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<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 } diff --git a/engine/common/fs.h b/engine/common/fs.h index f38c5988..ca35fd3c 100644 --- a/engine/common/fs.h +++ b/engine/common/fs.h @@ -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); diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index 6cb40203..18c645fe 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -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); diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index 21291bfc..eb6df847 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -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; diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index c78dbd6d..fb71fed1 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -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) diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 8974cbf5..8fcb233d 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -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) diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index 799d3a18..0b8da452 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -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 diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 4bfff5e7..0ed2a595 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -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" diff --git a/engine/droid/src/com/fteqw/FTEDroidActivity.java b/engine/droid/src/com/fteqw/FTEDroidActivity.java index f0942f0d..bea0158b 100644 --- a/engine/droid/src/com/fteqw/FTEDroidActivity.java +++ b/engine/droid/src/com/fteqw/FTEDroidActivity.java @@ -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); diff --git a/engine/droid/src/com/fteqw/FTEDroidEngine.java b/engine/droid/src/com/fteqw/FTEDroidEngine.java index f0c20ad5..9174c888 100644 --- a/engine/droid/src/com/fteqw/FTEDroidEngine.java +++ b/engine/droid/src/com/fteqw/FTEDroidEngine.java @@ -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); diff --git a/engine/http/httpserver.c b/engine/http/httpserver.c index dea76dc6..092b70cf 100644 --- a/engine/http/httpserver.c +++ b/engine/http/httpserver.c @@ -443,6 +443,8 @@ notimplemented: { VFS_CLOSE(cl->file); cl->file = NULL; + + IWebPrintf("Download complete\n"); } else cl->outbufferused+=ammount; diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index d2dfb442..b385b79e 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -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: diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index d78b853c..07076477 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -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 diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index 322133b6..c76e6b22 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -353,6 +353,8 @@ enum qcop_e { OP_MULSTORE_VI, OP_MULSTOREP_VI, + OP_LOADA_STRUCT, + OP_NUMOPS }; diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 1c57db16..1160959b 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -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 { diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 583aa027..03ba3a8d 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -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; } /* diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 90dfaec4..3cb170f7 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -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; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 79af33de..35cad45b 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -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 } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index bd9b25e9..f62bb0d4 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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 ; iname, 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);