diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index b594e2f8b..ab2c27717 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1227,7 +1227,9 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) { SCR_SetLoadingFile("wads"); if (cl.worldmodel && cl.worldmodel->loadstate == MLS_LOADING) - return stage; + return -1; + if (cl.worldmodel && cl.worldmodel->loadstate == MLS_LOADING) + COM_WorkerPartialSync(cl.worldmodel, &cl.worldmodel->loadstate, MLS_LOADING); Mod_ParseInfoFromEntityLump(cl.worldmodel); Wad_NextDownload(); @@ -4060,12 +4062,10 @@ void CL_ParseStatic (int version) VectorInverse(ent->axis[1]); if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED) - { - Con_TPrintf ("Warning: Parsestatic and no map loaded yet\n"); return; - } if (ent->model) { + //FIXME: wait for model to load so we know the correct size? /*FIXME: compensate for angle*/ VectorAdd(es.origin, ent->model->mins, mins); VectorAdd(es.origin, ent->model->maxs, maxs); diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 1f9cfd7a2..c5034c84d 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2635,6 +2635,9 @@ void Surf_BuildModelLightmaps (model_t *m) int ptype; int newfirst; + if (m->loadstate != MLS_LOADED) + return; + if (!lightmap_bytes) return; @@ -2649,8 +2652,6 @@ void Surf_BuildModelLightmaps (model_t *m) if (!m->lightmaps.count) return; - if (m->loadstate != MLS_LOADED) - return; currentmodel = m; shift = Surf_LightmapShift(currentmodel); @@ -2790,6 +2791,11 @@ void Surf_BuildModelLightmaps (model_t *m) surf->lightmaptexturenums[j] = -1; continue; } + if (surf->lightmaptexturenums[j] >= m->lightmaps.first+m->lightmaps.count) + { + surf->lightmaptexturenums[j] = -1; + continue; + } surf->lightmaptexturenums[j] = surf->lightmaptexturenums[0] - m->lightmaps.first + newfirst; lm = lightmap[surf->lightmaptexturenums[j]]; diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index a476c2636..23113e6f9 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -2645,7 +2645,7 @@ void S_UpdateAmbientSounds (soundcardinfo_t *sc) // calc ambient sound levels - if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame != fg_quake) + if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame != fg_quake || cl.worldmodel->loadstate != MLS_LOADED) return; l = Q1BSP_LeafForPoint(cl.worldmodel, listener_origin); diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index ecfd7166b..c79c3c849 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -345,7 +345,7 @@ dblbreak: return true; } -char *COM_ParseOut (const char *data, char *out, int outlen) +char *COM_ParseType (const char *data, char *out, int outlen, com_tokentype_t *toktype) { int c; int len; @@ -355,6 +355,8 @@ char *COM_ParseOut (const char *data, char *out, int outlen) len = 0; out[0] = 0; + if (toktype) + *toktype = TTP_EOF; if (!data) return NULL; @@ -398,6 +400,9 @@ skipwhite: // handle quoted strings specially if (c == '\"') { + if (toktype) + *toktype = TTP_STRING; + data++; while (1) { @@ -419,6 +424,8 @@ skipwhite: } // parse a regular word + if (toktype) + *toktype = TTP_RAWTOKEN; do { if (len >= outlen-1) diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 6525bf25e..44f2b805c 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -2649,6 +2649,10 @@ static void Update_CreatePath (char *path) } } +void Update_UserAcked(void *ctx, int foo) +{ +} + #include "fs.h" void Update_Version_Updated(struct dl_download *dl) { @@ -2677,12 +2681,17 @@ void Update_Version_Updated(struct dl_download *dl) size += VFS_WRITE(pending, buf, chunk); } VFS_CLOSE(pending); - if (VFS_GETLEN(dl->file) == size) + if (VFS_GETLEN(dl->file) != size) + Con_Printf("Download was the wrong size / corrupt\n"); + else { MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1); + M_Menu_Prompt(Update_UserAcked, NULL, "An update was downloaded", "Restart to activate.", "", "", "", "Okay"); } } } + else + Con_Printf("Update download failed\n"); } } void Update_Versioninfo_Available(struct dl_download *dl) @@ -2706,6 +2715,9 @@ void Update_Versioninfo_Available(struct dl_download *dl) DL_CreateThread(dl, NULL, NULL); #endif } + else + Con_Printf("autoupdate: already at latest version\n"); + return; } } } @@ -2760,6 +2772,11 @@ qboolean Sys_CheckUpdated(void) DeleteFile(updatedpath); if (MoveFile(pendingpath, updatedpath)) MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, UPD_BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1); + else + { + MessageBox(NULL, va("Unable to rename %s to %s", pendingpath, updatedpath), FULLENGINENAME" autoupdate", 0); + DeleteFile(pendingpath); + } } MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, UPD_BUILDTYPE EXETYPE, updatedpath, sizeof(updatedpath)); diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 53c4a1122..da85cd0e3 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -788,7 +788,8 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate) #endif if (showpackets.value) - Con_Printf ("%s --> s=%i(%i) a=%i(%i) %i\n" + Con_Printf ("%f %s --> s=%i(%i) a=%i(%i) %i\n" + , Sys_DoubleTime() , chan->sock == NS_SERVER?"s2c":"c2s" , chan->outgoing_sequence , send_reliable @@ -846,7 +847,8 @@ qboolean Netchan_Process (netchan_t *chan) sequence_ack &= ~(1<<31); if (showpackets.value) - Con_Printf ("%s <-- s=%i(%i) a=%i(%i) %i%s\n" + Con_Printf ("%f %s <-- s=%i(%i) a=%i(%i) %i%s\n" + , Sys_DoubleTime() , chan->sock == NS_SERVER?"c2s":"s2c" , sequence , reliable_message diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 4ff0cb8a0..5d876810c 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -4825,7 +4825,8 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e) if (!strcmp(bt->shadername, "clip")) bt->shader = R_RegisterShader(bt->shadername, SUF_LIGHTMAP, "{\nsurfaceparm nodraw\n}"); else - bt->shader = R_RegisterShader_Lightmap(bt->shadername); + bt->shader = R_RegisterCustom (bt->shadername, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL); +// bt->shader = R_RegisterShader_Lightmap(bt->shadername); R_BuildDefaultTexnums(NULL, bt->shader); } @@ -5110,6 +5111,8 @@ void Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities) else brushcontents = FTECONTENTS_WATER; } + else if (!strcmp(token, "clip")) + brushcontents = FTECONTENTS_PLAYERCLIP; else brushcontents = FTECONTENTS_SOLID; @@ -5196,8 +5199,8 @@ void Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities) if (!scale[1]) scale[1] = 1; VectorScale(texplane[0], 1.0/scale[0], faces[numplanes].sdir); VectorScale(texplane[1], 1.0/scale[1], faces[numplanes].tdir); - faces[numplanes].sdir[3] = -texplane[0][3]; - faces[numplanes].tdir[3] = -texplane[1][3]; + faces[numplanes].sdir[3] = texplane[0][3]; + faces[numplanes].tdir[3] = texplane[1][3]; numplanes++; continue; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 0829b3471..37f5caa6c 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -867,6 +867,8 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b) P_LoadedModel(mod); #endif + mod->loadstate = a; + #ifdef TERRAIN if (mod->terrain) Terr_FinishTerrain(mod); @@ -907,8 +909,6 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b) } #endif - mod->loadstate = a; - switch(verbose) { default: @@ -2944,15 +2944,20 @@ typedef struct int lmnum; qboolean deluxe; } lmalloc_t; +#define LM_FIRST 0x4000 static void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe) { memset(lmallocator, 0, sizeof(*lmallocator)); lmallocator->deluxe = hasdeluxe; + lmallocator->lmnum = LM_FIRST; } static void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod) { - mod->lightmaps.first = 1; - mod->lightmaps.count = lmallocator->lmnum; + mod->lightmaps.first = LM_FIRST; + mod->lightmaps.count = (lmallocator->lmnum - LM_FIRST); + if (lmallocator->allocated[0]) + mod->lightmaps.count++; + if (lmallocator->deluxe) { mod->lightmaps.first*=2; @@ -2967,9 +2972,6 @@ static void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigne int best, best2; int i, j; - if (!lmallocator->lmnum) - lmallocator->lmnum = 1; - for(;;) { best = LMBLOCK_HEIGHT; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 3e8a70333..e6223fba4 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -3962,7 +3962,7 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader) /*dlights/realtime lighting needs some stuff*/ if (!TEXVALID(tn->base)) { - tn->base = R_LoadHiResTexture(imagename, subpath, IF_NOALPHA); + tn->base = R_LoadHiResTexture(imagename, subpath, (*imagename=='{')?0:IF_NOALPHA); } TEXASSIGN(shader->defaulttextures.base, tn->base); diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index be68e046f..e0be8eac7 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -1,11 +1,6 @@ #define PROGSUSED #include "progsint.h" #include -#define STRING_SPECMASK 0xc0000000 // -#define STRING_TEMP 0x80000000 //temp string, will be collected. -#define STRING_STATIC 0xc0000000 //pointer to non-qcvm string. -#define STRING_NORMAL_ 0x00000000 //stringtable/mutable. should always be a fallthrough -#define STRING_NORMAL2_ 0x40000000 //stringtable/mutable. should always be a fallthrough typedef struct prmemb_s { struct prmemb_s *prev; diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 3345b5f04..9f726ef28 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -525,7 +525,10 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool v QC_snprintfz (line, sizeof(line), "union"); break; case ev_string: - QC_snprintfz (line, sizeof(line), "%s", PR_StringToNative(&progfuncs->funcs, val->string)); + if (((unsigned int)val->string & STRING_SPECMASK) == STRING_TEMP) + return ""; + else + QC_snprintfz (line, sizeof(line), "%s", PR_StringToNative(&progfuncs->funcs, val->string)); break; case ev_entity: fielddef = ED_FindField(progfuncs, "classname"); @@ -642,7 +645,11 @@ char *PDECL PR_UglyValueString (pubprogfuncs_t *ppf, etype_t type, eval_t *val) { char *outs = line; int outb = sizeof(line)-2; - const char *ins = PR_StringToNative(&progfuncs->funcs, val->string); + const char *ins; + if (((unsigned int)val->string & STRING_SPECMASK) == STRING_TEMP) + return ""; + else + ins = PR_StringToNative(&progfuncs->funcs, val->string); //markup the output string. while(*ins && outb > 0) { @@ -933,7 +940,6 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs) return line; } - /* ============= ED_Print @@ -989,7 +995,7 @@ void PDECL ED_Print (pubprogfuncs_t *ppf, struct edict_s *ed) printf ("%s\n", PR_ValueString(progfuncs, d->type, (eval_t *)v, false)); } } - +#if 0 void ED_PrintNum (progfuncs_t *progfuncs, int ent) { ED_Print (&progfuncs->funcs, EDICT_NUM(progfuncs, ent)); @@ -1046,7 +1052,7 @@ void ED_Count (progfuncs_t *progfuncs) // Con_Printf ("step :%3i\n", step); } - +#endif //============================================================================ diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 92095c3a3..d2ec42979 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -173,6 +173,12 @@ typedef struct progfuncs_s #include "qcd.h" +#define STRING_SPECMASK 0xc0000000 // +#define STRING_TEMP 0x80000000 //temp string, will be collected. +#define STRING_STATIC 0xc0000000 //pointer to non-qcvm string. +#define STRING_NORMAL_ 0x00000000 //stringtable/mutable. should always be a fallthrough +#define STRING_NORMAL2_ 0x40000000 //stringtable/mutable. should always be a fallthrough + typedef struct { int targetflags; //weather we need to mark the progs as a newer version diff --git a/engine/server/savegame.c b/engine/server/savegame.c index ec29aeb3e..af8c706dc 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -448,6 +448,14 @@ void SV_LegacySavegame_f (void) s = PR_SaveEnts(svprogfuncs, NULL, &len, 0, 1); VFS_PUTS(f, s); VFS_PUTS(f, "\n"); + /* + // DarkPlaces extended savegame + sv.lightstyles %i %s + sv.model_precache %i %s + sv.sound_precache %i %s + sv.buffer %i %i "string" + sv.bufstr %i %i "%s" + */ svprogfuncs->parms->memfree(s); VFS_CLOSE(f); @@ -456,7 +464,8 @@ void SV_LegacySavegame_f (void) -#define CACHEGAME_VERSION 513 +#define CACHEGAME_VERSION_OLD 513 +#define CACHEGAME_VERSION_VERBOSE 514 @@ -616,10 +625,10 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea VFS_GETS(f, str, sizeof(str)); version = atoi(str); - if (version != CACHEGAME_VERSION) + if (version != CACHEGAME_VERSION_OLD) { VFS_CLOSE (f); - Con_TPrintf ("Savegame is version %i, not %i\n", version, CACHEGAME_VERSION); + Con_TPrintf ("Savegame is version %i, not %i\n", version, CACHEGAME_VERSION_OLD); return false; } VFS_GETS(f, str, sizeof(str)); //comment @@ -834,6 +843,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame) int i; char comment[SAVEGAME_COMMENT_LENGTH+1]; levelcache_t *cache; + int version = CACHEGAME_VERSION_OLD; if (!sv.state) return; @@ -899,11 +909,15 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame) return; } - VFS_PRINTF (f, "%i\n", CACHEGAME_VERSION); + VFS_PRINTF (f, "%i\n", version); SV_SavegameComment (comment); VFS_PRINTF (f, "%s\n", comment); + if (!dontharmgame) { + //map-change caches require the players to have been de-spawned + //saved games require players to retain their fields. + //probably this should happen elsewhere. for (cl = svs.clients, clnum=0; clnum < sv.allocated_client_slots; cl++,clnum++)//fake dropping { if (cl->state < cs_spawned && !cl->istobeloaded) //don't drop if they are still connecting @@ -928,39 +942,91 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame) } } } - VFS_PRINTF (f, "%d\n", progstype); - VFS_PRINTF (f, "%f\n", skill.value); - VFS_PRINTF (f, "%f\n", deathmatch.value); - VFS_PRINTF (f, "%f\n", coop.value); - VFS_PRINTF (f, "%f\n", teamplay.value); - VFS_PRINTF (f, "%s\n", sv.name); - VFS_PRINTF (f, "%f\n",sv.time); + + if (version == CACHEGAME_VERSION_VERBOSE) + { + char buf[8192]; + char *mode = "?"; + switch(progstype) + { + case PROG_NONE: break; + case PROG_QW: mode = "QW"; break; + case PROG_NQ: mode = "NQ"; break; + case PROG_H2: mode = "H2"; break; + case PROG_PREREL: mode = "PREREL"; break; + case PROG_UNKNOWN: mode = "UNKNOWN"; break; + } + VFS_PRINTF (f, "vmmode %s\n", COM_QuotedString(mode, buf, sizeof(buf), false)); + VFS_PRINTF (f, "skill %s\n", COM_QuotedString(skill.string, buf, sizeof(buf), false)); + VFS_PRINTF (f, "deathmatch %s\n", COM_QuotedString(deathmatch.string, buf, sizeof(buf), false)); + VFS_PRINTF (f, "coop %s\n", COM_QuotedString(coop.string, buf, sizeof(buf), false)); + VFS_PRINTF (f, "teamplay %s\n", COM_QuotedString(teamplay.string, buf, sizeof(buf), false)); + VFS_PRINTF (f, "map %s\n", COM_QuotedString(sv.name, buf, sizeof(buf), false)); + VFS_PRINTF (f, "time %f\n", sv.time); + + for (i=0 ; i