r_softwarebanding is now a bit more generic and can now palettize rgb textures.

fix r_renderscale nearest/linear switching needing a vid_restart.
fix q3 spamming input packets.
fix ^8
prepare for nicer entity editing via eg csaddon.
fix vulkan crash + vulkan overbrights

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5027 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2016-11-25 08:14:54 +00:00
parent dca2ea4207
commit 732a89f7c1
34 changed files with 470 additions and 205 deletions

View File

@ -2001,8 +2001,13 @@ void CL_SendCmd (double frametime, qboolean mainloop)
#endif
#ifdef Q3CLIENT
case CP_QUAKE3:
msecs -= (double)msecstouse;
CLQ3_SendCmd(&independantphysics[0]);
memset(&independantphysics[0], 0, sizeof(independantphysics[0]));
//don't bank too much, because that results in banking speedcheats
if (msecs > 200)
msecs = 200;
return; // Q3 does it's own thing
#endif
default:

View File

@ -3547,13 +3547,46 @@ static void Image_8_BGR_RGB_Swap(qbyte *data, unsigned int w, unsigned int h)
}
}
static void Image_ChangeFormat(struct pendingtextureinfo *mips, uploadfmt_t origfmt)
static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt)
{
int mip;
if (mips->type != PTI_2D)
return; //blurgh
if (flags & IF_PALETTIZE)
{
if (mips->encoding == PTI_RGBX8)
{
mips->encoding = PTI_R8;
for (mip = 0; mip < mips->mipcount; mip++)
{
unsigned int i;
unsigned char *out;
unsigned char *in;
void *needfree = NULL;
in = mips->mip[mip].data;
if (mips->mip[mip].needfree)
out = in;
else
{
needfree = in;
out = BZ_Malloc(mips->mip[mip].width*mips->mip[mip].height*sizeof(*out));
mips->mip[mip].data = out;
}
mips->mip[mip].datasize = mips->mip[mip].width*mips->mip[mip].height;
mips->mip[mip].needfree = true;
for (i = 0; i < mips->mip[mip].width*mips->mip[mip].height; i++, in+=4)
out[i] = GetPaletteIndex(in[0], in[1], in[2]);
if (needfree)
BZ_Free(needfree);
}
}
}
//if that format isn't supported/desired, try converting it.
if (sh_config.texfmt[mips->encoding])
return;
@ -3721,7 +3754,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
//8bit opaque data
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
flags |= IF_NOPICMIP;
if (!r_dodgymiptex.ival && mips->mip[0].width == imgwidth && mips->mip[0].height == imgheight)
if (/*!r_dodgymiptex.ival &&*/ mips->mip[0].width == imgwidth && mips->mip[0].height == imgheight)
{
unsigned int pixels =
(imgwidth>>0) * (imgheight>>0) +
@ -4153,7 +4186,7 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd
return false;
}
Image_GenerateMips(mips, flags);
Image_ChangeFormat(mips, fmt);
Image_ChangeFormat(mips, flags, fmt);
tex->width = imgwidth;
tex->height = imgheight;
@ -4612,7 +4645,7 @@ image_t *Image_FindTexture(const char *identifier, const char *subdir, unsigned
tex = Hash_Get(&imagetable, identifier);
while(tex)
{
if (!((tex->flags ^ flags) & IF_CLAMP))
if (!((tex->flags ^ flags) & (IF_CLAMP|IF_PALETTIZE)))
{
#ifdef PURGEIMAGES
if (!strcmp(subdir, tex->subpath?tex->subpath:""))
@ -4847,7 +4880,7 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
if (!Image_GenMip0(&mips, flags, data, palette, width, height, fmt, false))
return;
Image_GenerateMips(&mips, flags);
Image_ChangeFormat(&mips, fmt);
Image_ChangeFormat(&mips, flags, fmt);
rf->IMG_LoadTextureMips(tex, &mips);
tex->width = width;
tex->height = height;

View File

@ -48,7 +48,7 @@ vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefil
#ifndef SVNREVISION
#define SVNREVISION -
#endif
#define DOWNLOADABLESARGS "?ver=" STRINGIFY(SVNREVISION) PHPVK PHPGL PHPD3D PHPMIN PHPLEG PHPDBG "&arch="PLATFORM "_" ARCH_CPU_POSTFIX
#define DOWNLOADABLESARGS "ver=" STRINGIFY(SVNREVISION) PHPVK PHPGL PHPD3D PHPMIN PHPLEG PHPDBG "&arch="PLATFORM "_" ARCH_CPU_POSTFIX
@ -81,6 +81,7 @@ extern cvar_t fs_downloads_url;
#define DPF_HIDDEN 0x80 //wrong arch, file conflicts, etc. still listed if actually installed.
#define DPF_ENGINE 0x100 //engine update. replaces old autoupdate mechanism
#define DPF_PURGE 0x200 //package should be completely removed (ie: the dlcache dir too). if its still marked then it should be reinstalled anew. available on cached or corrupt packages, implied by native.
#define DPF_MANIFEST 0x400 //package was named by the manifest, and should only be uninstalled after a warning.
//pak.lst
//priories <0
@ -172,8 +173,10 @@ typedef struct package_s {
static qboolean loadedinstalled;
static package_t *availablepackages;
static int numpackages;
static char *manifestpackage; //metapackage named by the manicfest.
static qboolean domanifestinstall;
qboolean doautoupdate; //updates will be marked (but not applied without the user's actions)
static qboolean doautoupdate; //updates will be marked (but not applied without the user's actions)
//FIXME: these are allocated for the life of the exe. changing basedir should purge the list.
static int numdownloadablelists = 0;
@ -185,7 +188,7 @@ static struct
qboolean save; //written into our local file
struct dl_download *curdl; //the download context
} downloadablelist[32];
int downloadablessequence; //bumped any time any package is purged
static int downloadablessequence; //bumped any time any package is purged
static void PM_FreePackage(package_t *p)
{
@ -222,6 +225,9 @@ static void PM_FreePackage(package_t *p)
for (i = 0; i < countof(p->mirror); i++)
Z_Free(p->mirror[i]);
Z_Free(p->name);
Z_Free(p->category);
Z_Free(p->title);
Z_Free(p->description);
Z_Free(p->author);
Z_Free(p->license);
@ -665,6 +671,7 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c
char *arch = NULL;
char *qhash = NULL;
char *title = NULL;
char *category = NULL;
char *description = NULL;
char *license = NULL;
char *author = NULL;
@ -683,8 +690,10 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c
char *arg = Cmd_Argv(i);
if (!strncmp(arg, "url=", 4))
url = arg+4;
else if (!strncmp(arg, "title=", 8))
title = arg+8;
else if (!strncmp(arg, "category=", 9))
category = arg+9;
else if (!strncmp(arg, "title=", 6))
title = arg+6;
else if (!strncmp(arg, "gamedir=", 8))
gamedir = arg+8;
else if (!strncmp(arg, "ver=", 4))
@ -740,13 +749,31 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c
}
}
if (*prefix)
Q_snprintfz(pathname, sizeof(pathname), "%s/%s", prefix, fullname);
if (category)
{
p->name = Z_StrDup(fullname);
if (*prefix)
Q_snprintfz(pathname, sizeof(pathname), "%s/%s", prefix, category);
else
Q_snprintfz(pathname, sizeof(pathname), "%s", category);
if (*pathname)
{
if (pathname[strlen(pathname)-1] != '/')
Q_strncatz(pathname, "/", sizeof(pathname));
}
p->category = Z_StrDup(pathname);
}
else
Q_snprintfz(pathname, sizeof(pathname), "%s", fullname);
p->name = Z_StrDup(COM_SkipPath(pathname));
*COM_SkipPath(pathname) = 0;
p->category = Z_StrDup(pathname);
{
if (*prefix)
Q_snprintfz(pathname, sizeof(pathname), "%s/%s", prefix, fullname);
else
Q_snprintfz(pathname, sizeof(pathname), "%s", fullname);
p->name = Z_StrDup(COM_SkipPath(pathname));
*COM_SkipPath(pathname) = 0;
p->category = Z_StrDup(pathname);
}
if (!title)
title = p->name;
@ -1219,6 +1246,7 @@ static void PM_PrintChanges(void)
Con_Printf("<%i package(s) changed>\n", changes);
}
static void PM_ApplyChanges(void);
static void PM_ListDownloaded(struct dl_download *dl)
{
@ -1246,16 +1274,46 @@ static void PM_ListDownloaded(struct dl_download *dl)
else
downloadablelist[i].received = -1;
if (!doautoupdate)
if (!doautoupdate && !domanifestinstall)
return; //don't spam this.
for (i = 0; i < numdownloadablelists; i++)
{
if (!downloadablelist[i].received)
break;
}
if (i == numdownloadablelists)
if (domanifestinstall)
{
package_t *meta;
meta = PM_MarkedPackage(manifestpackage);
if (!meta)
meta = PM_FindPackage(manifestpackage);
if (meta)
{
PM_RevertChanges();
PM_MarkPackage(meta);
PM_ApplyChanges();
#ifdef DOWNLOADMENU
if (!isDedicated)
{
if (Key_Dest_Has(kdm_emenu))
{
Key_Dest_Remove(kdm_emenu);
m_state = m_none;
}
#ifdef MENU_DAT
if (Key_Dest_Has(kdm_gmenu))
MP_Toggle(0);
#endif
Cmd_ExecuteString("menu_download\n", RESTRICT_LOCAL);
}
#endif
return;
}
}
if (doautoupdate && i == numdownloadablelists)
{
doautoupdate = true;
if (PM_MarkUpdates())
{
#ifdef DOWNLOADMENU
@ -1282,6 +1340,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
static void PM_UpdatePackageList(qboolean autoupdate, int retry)
{
unsigned int i;
int setting;
if (retry>1 || fs_downloads_url.modified)
PM_Shutdown();
@ -1303,7 +1362,11 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
if (downloadablelist[i].curdl)
continue;
downloadablelist[i].curdl = HTTP_CL_Get(va("%s"DOWNLOADABLESARGS, downloadablelist[i].url), NULL, PM_ListDownloaded);
setting = Sys_GetAutoUpdateSetting();
// if (setting == UPD_UNSUPPORTED)
// setting = autoupdatesetting+1;
downloadablelist[i].curdl = HTTP_CL_Get(va("%s%s"DOWNLOADABLESARGS"%s", downloadablelist[i].url, strchr(downloadablelist[i].url,'?')?"&":"?", (setting>=UPD_TESTING)?"test=1":""), NULL, PM_ListDownloaded);
if (downloadablelist[i].curdl)
{
downloadablelist[i].curdl->user_num = i;
@ -1441,7 +1504,7 @@ static void PM_WriteInstalledPackages(void)
if (p->description)
{
Q_strncatz(buf, " ", sizeof(buf));
COM_QuotedConcat(va("description=%s", p->description), buf, sizeof(buf));
COM_QuotedConcat(va("desc=%s", p->description), buf, sizeof(buf));
}
if (p->license)
{
@ -1735,23 +1798,60 @@ static char *PM_GetTempName(package_t *p)
return Z_StrDup(destname);
}
static void PM_AddDownloadedPackage(const char *filename)
{
char pathname[1024];
package_t *p;
Q_snprintfz(pathname, sizeof(pathname), "%s/%s", "Cached", filename);
p->name = Z_StrDup(COM_SkipPath(pathname));
*COM_SkipPath(pathname) = 0;
p->category = Z_StrDup(pathname);
Q_strncpyz(p->version, "", sizeof(p->version));
Q_snprintfz(p->gamedir, sizeof(p->gamedir), "%s", "");
p->fsroot = FS_ROOT;
p->extract = EXTRACT_COPY;
p->priority = 0;
p->flags = DPF_INSTALLED;
p->title = Z_StrDup(p->name);
p->arch = NULL;
p->qhash = NULL; //FIXME
p->description = NULL;
p->license = NULL;
p->author = NULL;
p->previewimage = NULL;
}
int PM_IsApplying(void)
{
package_t *p;
int count = 0;
int i;
for (p = availablepackages; p ; p=p->next)
{
if (p->download)
count++;
}
for (i = 0; i < numdownloadablelists; i++)
{
if (downloadablelist[i].curdl)
count++;
}
return count;
}
//looks for the next package that needs downloading, and grabs it
static void PM_StartADownload(void)
{
vfsfile_t *tmpfile;
char *temp;
// char native[MAX_OSPATH];
package_t *p;
int simultaneous = 1;
const int simultaneous = 1;
int i;
for (p = availablepackages; p ; p=p->next)
{
if (p->download)
simultaneous--;
}
for (p = availablepackages; p && simultaneous > 0; p=p->next)
for (p = availablepackages; p && simultaneous > PM_IsApplying(); p=p->next)
{
if (p->trymirrors)
{ //flagged for a (re?)download
@ -1848,8 +1948,6 @@ static void PM_StartADownload(void)
VFS_CLOSE(tmpfile);
FS_Remove(temp, p->fsroot);
}
simultaneous--;
}
}
}
@ -1862,7 +1960,9 @@ static void PM_ApplyChanges(void)
for (link = &availablepackages; *link ; )
{
p = *link;
if ((p->flags & DPF_PURGE) || (!(p->flags&DPF_MARKED) && (p->flags&DPF_INSTALLED)))
if (p->download)
; //erk, dude, don't do two!
else if ((p->flags & DPF_PURGE) || (!(p->flags&DPF_MARKED) && (p->flags&DPF_INSTALLED)))
{ //if we don't want it but we have it anyway:
qboolean reloadpacks = false;
struct packagedep_s *dep;
@ -1941,6 +2041,20 @@ static void PM_ApplyChanges(void)
PM_StartADownload(); //and try to do those downloads.
}
void PM_ManifestPackage(const char *metaname, qboolean mark)
{
domanifestinstall = mark;
Z_Free(manifestpackage);
if (metaname)
{
manifestpackage = Z_StrDup(metaname);
if (mark)
PM_UpdatePackageList(false, false);
}
else
manifestpackage = NULL;
}
void PM_Command_f(void)
{
package_t *p;
@ -1990,7 +2104,7 @@ void PM_Command_f(void)
else
status = "";
Con_Printf(" ^[%s%s%s%s^] %s %s\n", markup, p->name, p->arch?":":"", p->arch?p->arch:"", status, strcmp(p->name, p->title)?p->title:"");
Con_Printf(" ^[%s%s%s%s^] %s^9 %s\n", markup, p->name, p->arch?":":"", p->arch?p->arch:"", status, strcmp(p->name, p->title)?p->title:"");
}
Con_Printf("<end of list>\n");
}
@ -2252,7 +2366,7 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
}
}
n = p->name;
n = p->title;
if (p->flags & DPF_DISPLAYVERSION)
n = va("%s (%s)", n, *p->version?p->version:"unversioned");
@ -2361,10 +2475,10 @@ static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct men
char *settings[] =
{
"Unsupported",
"Revert",
"Revert Engine",
"Off",
"Stable Updates",
"Unsable Updates"
"Test Updates"
};
char *text;
int setting = Sys_GetAutoUpdateSetting();

View File

@ -158,6 +158,9 @@ enum mlverbosity_e
MLV_ERROR
};
const char *Mod_GetEntitiesString(struct model_s *mod);
void Mod_SetEntitiesStringLen(struct model_s *mod, const char *str, size_t strsize);
void Mod_SetEntitiesString(struct model_s *mod, const char *str, qboolean docopy);
extern void Mod_ClearAll (void);
extern void Mod_Purge (enum mod_purge_e type);
extern struct model_s *Mod_FindName (const char *name); //find without loading. needload should be set.
@ -166,7 +169,7 @@ extern struct model_s *Mod_LoadModel (struct model_s *mod, enum mlverbosity_e
extern void *Mod_Extradata (struct model_s *mod); // handles caching
extern void Mod_TouchModel (const char *name);
extern const char *Mod_FixName (const char *modname, const char *worldname); //remaps the name appropriately
char *Mod_ParseWorldspawnKey (const char *ents, const char *key, char *buffer, size_t sizeofbuffer);
const char *Mod_ParseWorldspawnKey (struct model_s *mod, const char *key, char *buffer, size_t sizeofbuffer);
extern void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, int surfaceidx, const char *name);

View File

@ -3246,7 +3246,7 @@ static void QCBUILTIN PF_cs_getentitytoken (pubprogfuncs_t *prinst, struct globa
{
const char *s = PR_GetStringOfs(prinst, OFS_PARM0);
if (*s == 0)
s = cl.worldmodel?cl.worldmodel->entities:NULL;
s = Mod_GetEntitiesString(cl.worldmodel);
csqcmapentitydata = s;
G_INT(OFS_RETURN) = 0;
return;
@ -6939,14 +6939,14 @@ void CSQC_WorldLoaded(void)
CSQC_FindGlobals(false);
csqcmapentitydataloaded = true;
csqcmapentitydata = cl.worldmodel?cl.worldmodel->entities:NULL;
csqcmapentitydata = Mod_GetEntitiesString(cl.worldmodel);
csqc_world.worldmodel = cl.worldmodel;
World_RBE_Start(&csqc_world);
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
worldent->v->solid = SOLID_BSP;
wmodelindex = CS_FindModel(cl.worldmodel->name, &tmp);
wmodelindex = CS_FindModel(cl.worldmodel?cl.worldmodel->name:"", &tmp);
tmp = csqc_worldchanged;
csqc_setmodel(csqcprogs, worldent, wmodelindex);
csqc_worldchanged = tmp;

View File

@ -1597,6 +1597,7 @@ texid_t R2D_RT_Configure(const char *id, int width, int height, uploadfmt_t rtfm
if (rtfmt)
{
tid->flags = (tid->flags & ~(IF_NEAREST|IF_LINEAR)) | (imageflags & (IF_NEAREST|IF_LINEAR));
Image_Upload(tid, rtfmt, NULL, NULL, width, height, imageflags);
tid->width = width;
tid->height = height;

View File

@ -1429,7 +1429,7 @@ qboolean QDECL D3_LoadMap_CollisionMap(model_t *mod, void *buf, size_t bufsize)
/*load up the .map so we can get some entities (anyone going to bother making a qc mod compatible with this?)*/
COM_StripExtension(mod->name, token, sizeof(token));
mod->entities = FS_LoadMallocFile(va("%s.map", token), NULL);
Mod_SetEntitiesString(mod, FS_LoadMallocFile(va("%s.map", token), NULL), true);
mod->funcs.FindTouchedLeafs = D3_FindTouchedLeafs;
mod->funcs.NativeTrace = D3_Trace;

View File

@ -403,6 +403,7 @@ enum imageflags
IF_MIPCAP = 1<<10,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_PALETTIZE = 1<<21,
IF_NOPURGE = 1<<22,
IF_HIGHPRIORITY = 1<<23,
IF_LOWPRIORITY = 1<<24,
@ -506,7 +507,7 @@ struct llightinfo_s;
void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int surfnum); //version that is aware of bsp trees
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, qbyte surf_styles[4], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale); //special version that doesn't know what a face is or anything.
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, struct model_s *model, qboolean shadows);
void LightReloadEntities(struct relight_ctx_s *ctx, char *entstring, qboolean ignorestyles);
void LightReloadEntities(struct relight_ctx_s *ctx, const char *entstring, qboolean ignorestyles);
void LightShutdown(struct relight_ctx_s *ctx, struct model_s *mod);
extern const size_t lightthreadctxsize;
#endif

View File

@ -1222,7 +1222,7 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
{
if (newr->renderer->rtype == qrenderer && currentrendererstate.renderer)
{
R_SetRenderer(newr->renderer);
R_SetRenderer(newr->renderer);
return true; //no point
}

View File

@ -3546,7 +3546,7 @@ qboolean Sys_DoInstall(void)
int pct = -100;
char fname[MAX_OSPATH];
memset(&wc, 0, sizeof(wc));
wc.style = 0;
wc.style = 0;
wc.lpfnWndProc = NoCloseWindowProc;//Progress_Wnd;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
@ -3613,7 +3613,7 @@ qboolean Sys_DoInstall(void)
}
/*create startmenu icon*/
if (MessageBoxU(NULL, va("Create Startmenu icon for %s?", fs_gamename.string), fs_gamename.string, MB_YESNO|MB_ICONQUESTION|MB_TOPMOST) == IDYES)
if (MessageBoxU(NULL, va("Create start-menu icon for %s?", fs_gamename.string), fs_gamename.string, MB_YESNO|MB_ICONQUESTION|MB_TOPMOST) == IDYES)
{
HRESULT hres;
IShellLinkW *psl;

View File

@ -42,6 +42,9 @@ void W_CleanupName (const char *in, char *out)
{
int i;
int c;
if (!strncmp(in, "textures/", 9))
in += 9;
for (i=0 ; i<16 ; i++ )
{
@ -694,7 +697,7 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
{
char token[4096];
char key[128];
char *data = wmodel->entities;
const char *data = Mod_GetEntitiesString(wmodel);
mapskys_t *msky;
cl.skyrotate = 0;
@ -730,7 +733,7 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
break; // error
if (!strcmp("wad", key)) // for HalfLife maps
{
if (wmodel->fromgame == fg_halflife || wmodel->type == mod_heightmap)
if (1)
{
Q_strncatz(wads, ";", sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet)
Q_strncatz(wads, token, sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet)
@ -834,8 +837,8 @@ qboolean Wad_NextDownload (void)
{
char wadname[4096+9]="textures/";
int i, j, k;
if (*wads) //now go about checking the wads
model_t *wmodel = cl.worldmodel;
if (wmodel && (wmodel->fromgame == fg_halflife || wmodel->type == mod_heightmap) && *wads) //now go about checking the wads
{
j = 0;
wads[4095] = '\0';

View File

@ -3155,22 +3155,7 @@ static void *Q1MDL_LoadSkins_GL (galiasinfo_t *galias, dmdl_t *pq1inmodel, model
galiasskin_t *outskin = galias->ofsskins;
const char *slash;
unsigned int texflags;
const char *defaultshader;
if (r_softwarebanding && qrenderer == QR_OPENGL && sh_config.progs_supported)
{
defaultshader =
"{\n"
"program defaultskin#EIGHTBIT\n"
"affine\n"
"{\n"
"map $colourmap\n"
"}\n"
"}\n"
;
}
else
defaultshader = NULL;
const char *defaultshader = NULL;
s = pq1inmodel->skinwidth*pq1inmodel->skinheight;
for (i = 0; i < pq1inmodel->numskins; i++)

View File

@ -108,7 +108,7 @@ cvar_t gameversion = CVARFD("gameversion","", CVAR_SERVERINFO, "gamecode version
cvar_t gameversion_min = CVARD("gameversion_min","", "gamecode version for server browsers");
cvar_t gameversion_max = CVARD("gameversion_max","", "gamecode version for server browsers");
cvar_t fs_gamename = CVARAFD("com_fullgamename", NULL, "fs_gamename", CVAR_NOSET, "The filesystem is trying to run this game");
cvar_t fs_downloads_url = CVARFD("fs_downloads_url", NULL, CVAR_NOSET, "The URL of a package updates list.");
cvar_t fs_downloads_url = CVARFD("fs_downloads_url", NULL, CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET, "The URL of a package updates list.");
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
@ -2715,17 +2715,18 @@ consolecolours_t consolecolours[MAXCONCOLOURS] = {
};
// This is for remapping the Q3 color codes to character masks, including ^9
// if using this table, make sure the truecolour flag is disabled first.
conchar_t q3codemasks[MAXQ3COLOURS] = {
0x00000000, // 0, black
0x0c000000, // 1, red
0x0a000000, // 2, green
0x0e000000, // 3, yellow
0x09000000, // 4, blue
0x0b000000, // 5, cyan
0x0d000000, // 6, magenta
0x0f000000, // 7, white
0x0f100000, // 8, half-alpha white (BX_COLOREDTEXT)
0x07000000 // 9, "half-intensity" (BX_COLOREDTEXT)
COLOR_BLACK << CON_FGSHIFT, // 0, black
COLOR_RED << CON_FGSHIFT, // 1, red
COLOR_GREEN << CON_FGSHIFT, // 2, green
COLOR_YELLOW << CON_FGSHIFT, // 3, yellow
COLOR_BLUE << CON_FGSHIFT, // 4, blue
COLOR_CYAN << CON_FGSHIFT, // 5, cyan
COLOR_MAGENTA << CON_FGSHIFT, // 6, magenta
COLOR_WHITE << CON_FGSHIFT, // 7, white
(COLOR_WHITE << CON_FGSHIFT)|CON_HALFALPHA, // 8, half-alpha white (BX_COLOREDTEXT)
COLOR_GREY << CON_FGSHIFT // 9, "half-intensity" (BX_COLOREDTEXT)
};
//Converts a conchar_t string into a char string. returns the null terminator. pass NULL for stop to calc it
@ -3203,7 +3204,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
{ //q3 colour codes
if (ext & CON_RICHFORECOLOUR)
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR));
ext = q3codemasks[str[1]-'0'] | (ext&~CON_Q3MASK); //change colour only.
ext = q3codemasks[str[1]-'0'] | (ext&~(CON_WHITEMASK|CON_HALFALPHA)); //change colour only.
}
else if (str[1] == '&') // extended code
{

View File

@ -55,7 +55,6 @@ extern conchar_t q3codemasks[MAXQ3COLOURS];
#define CON_RICHGSHIFT 24
#define CON_RICHRSHIFT 28 //high nibble
#define CON_Q3MASK 0x0F100000
#define CON_WHITEMASK 0x0F000000 // must be constant. things assume this
#define CON_DEFAULTCHAR (CON_WHITEMASK | 32)

View File

@ -3948,6 +3948,7 @@ void FS_Shutdown(void)
if (!fs_thread_mutex)
return;
PM_ManifestPackage(NULL, false);
FS_FreePaths();
Sys_DestroyMutex(fs_thread_mutex);
fs_thread_mutex = NULL;
@ -4185,6 +4186,8 @@ static char fspdl_finalpath[MAX_OSPATH];
static void FS_BeginNextPackageDownload(void);
qboolean FS_DownloadingPackage(void)
{
if (PM_IsApplying())
return true;
return !fs_manifest || !!curpackagedownload;
}
//vfsfile_t *FS_DecompressXZip(vfsfile_t *infile, vfsfile_t *outfile);
@ -4370,6 +4373,8 @@ static void FS_PackageDownloaded(struct dl_download *dl)
{
Con_Printf("Unable to rename \"%s\" to \"%s\"\n", fspdl_temppath, fspdl_finalpath);
}
// else
// PM_AddDownloadedPackage(fspdl_finalpath);
}
}
Sys_remove (fspdl_temppath);
@ -4715,6 +4720,7 @@ static void FS_ManifestUpdated(struct dl_download *dl)
void FS_BeginManifestUpdates(void)
{
ftemanifest_t *man = fs_manifest;
PM_ManifestPackage(man->installupd, man->doinstall);
if (curpackagedownload || !man)
return;
@ -4914,6 +4920,8 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
if (fs_manifest && fs_manifest->downloadsurl)
olddownloadsurl = Z_StrDup(fs_manifest->downloadsurl);
else if (!fs_manifest && man->downloadsurl)
olddownloadsurl = Z_StrDup(man->downloadsurl);
else
olddownloadsurl = NULL;
@ -4935,7 +4943,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
}
fs_manifest = man;
if (!man->doinstall)
if (!man->doinstall && strcmp(man->downloadsurl?man->downloadsurl:"", olddownloadsurl?olddownloadsurl:""))
{ //make sure we only fuck over the user if this is a 'secure' manifest, and not hacked in some way.
Z_Free(man->downloadsurl);
man->downloadsurl = olddownloadsurl;
@ -5167,6 +5175,7 @@ void FS_CreateBasedir(const char *path)
com_installer = false;
Q_strncpyz (com_gamepath, path, sizeof(com_gamepath));
COM_CreatePath(com_gamepath);
fs_manifest->doinstall = true;
FS_ChangeGame(fs_manifest, true, false);
if (host_parms.manifest)

View File

@ -68,6 +68,8 @@ void FS_UnRegisterFileSystemModule(void *module);
void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, const char *pakpath, const char *qhash, const char *pakprefix);
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
int PM_IsApplying(void);
void PM_ManifestPackage(const char *name, qboolean doinstall);
void Menu_Download_Update(void);
int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr);

View File

@ -56,6 +56,7 @@ qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l);
qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l);
void Mod_LoadEntities (model_t *loadmodel, qbyte *mod_base, lump_t *l);
extern void BuildLightMapGammaTable (float g, float c);
@ -1497,7 +1498,7 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean li
unsigned short lmshift, lmscale;
char buf[64];
lmscale = atoi(Mod_ParseWorldspawnKey(mod->entities, "lightmap_scale", buf, sizeof(buf)));
lmscale = atoi(Mod_ParseWorldspawnKey(mod, "lightmap_scale", buf, sizeof(buf)));
if (!lmscale)
lmshift = LMSHIFT_DEFAULT;
else
@ -2036,20 +2037,6 @@ qboolean CModQ2_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l)
return true;
}
/*
=================
CMod_LoadEntityString
=================
*/
void CMod_LoadEntityString (model_t *mod, qbyte *mod_base, lump_t *l)
{
// if (l->filelen > MAX_Q2MAP_ENTSTRING)
// Host_Error ("Map has too large entity lump");
mod->entities = Z_Malloc(l->filelen+1);
memcpy (mod->entities, mod_base + l->fileofs, l->filelen);
}
#ifdef Q3BSPS
qboolean CModQ3_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l)
{
@ -4101,7 +4088,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
noerrors = noerrors && CModQ3_LoadSubmodels (mod, mod_base, &header.lumps[Q3LUMP_MODELS]);
noerrors = noerrors && CModQ3_LoadVisibility (mod, mod_base, &header.lumps[Q3LUMP_VISIBILITY]);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q3LUMP_ENTITIES]);
Mod_LoadEntities (mod, mod_base, &header.lumps[Q3LUMP_ENTITIES]);
if (!noerrors)
{
@ -4203,7 +4190,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]);
noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
#ifndef CLIENTONLY
mod->funcs.FatPVS = Q2BSP_FatPVS;
@ -4234,7 +4221,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]);
noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], header.version == BSPVERSION_Q2W);
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], false);
noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]);
@ -4310,7 +4297,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
Q_snprintfz (name, sizeof(name), "*%i:%s", i, wmod->name);
mod = Mod_FindName (name);
*mod = *wmod;
mod->entities = NULL;
mod->entities_raw = NULL;
mod->submodelof = wmod;
Q_strncpyz(mod->name, name, sizeof(mod->name));
memset(&mod->memgroup, 0, sizeof(mod->memgroup));

View File

@ -764,7 +764,14 @@ enum terrainedit_e
// ter_autopaint_h, //vector pos, float radius, float percent, string tex1, string tex2 (paint tex1/tex2
// ter_autopaint_n //vector pos, float radius, float percent, string tex1, string tex2
ter_tex_mask //string tex
ter_tex_mask, //string tex
ter_ent_get, //int idx -> string
ter_ent_set, //int idx, string keyvals
ter_ent_add, //string keyvals -> int
ter_ent_count, // -> int
// ter_cmd_count
};
#endif

View File

@ -4825,22 +4825,38 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
switch(action)
{
case ter_ent_get:
{
int idx = G_INT(OFS_PARM1);
G_INT(OFS_RETURN) = 0;
}
return;
case ter_ent_set:
{
int idx = G_INT(OFS_PARM1);
const char *news = PR_GetStringOfs(prinst, OFS_PARM2);
G_INT(OFS_RETURN) = 0;
}
return;
case ter_ents_wipe:
G_INT(OFS_RETURN) = PR_TempString(prinst, mod->entities);
mod->entities = Z_Malloc(1);
G_INT(OFS_RETURN) = PR_TempString(prinst, Mod_GetEntitiesString(mod));
Mod_SetEntitiesString(mod, "", true);
return;
case ter_ents_concat:
{
char *olds = mod->entities;
char *newv;
const char *olds = Mod_GetEntitiesString(mod);
const char *news = PR_GetStringOfs(prinst, OFS_PARM1);
size_t oldlen = strlen(olds);
size_t newlen = strlen(news);
mod->entities = Z_Malloc(oldlen + newlen + 1);
memcpy(mod->entities, olds, oldlen);
memcpy(mod->entities+oldlen, news, newlen);
mod->entities[oldlen + newlen] = 0;
Z_Free(olds);
newv = Z_Malloc(oldlen + newlen + 1);
memcpy(newv, olds, oldlen);
memcpy(newv+oldlen, news, newlen);
newv[oldlen + newlen] = 0;
Z_Free((char*)olds);
G_FLOAT(OFS_RETURN) = oldlen + newlen;
Mod_SetEntitiesString(mod, newv, false);
if (mod->terrain)
{
hm = mod->terrain;
@ -4849,7 +4865,7 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
}
return;
case ter_ents_get:
G_INT(OFS_RETURN) = PR_TempString(prinst, mod->entities);
G_INT(OFS_RETURN) = PR_TempString(prinst, Mod_GetEntitiesString(mod));
return;
case ter_save:
if (mod->terrain)
@ -5087,10 +5103,11 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
}
#endif
void Terr_ParseEntityLump(char *data, heightmap_t *heightmap)
void Terr_ParseEntityLump(model_t *mod, heightmap_t *heightmap)
{
char key[128];
char value[2048];
const char *data = Mod_GetEntitiesString(mod);
heightmap->sectionsize = 1024;
heightmap->mode = HMM_TERRAIN;
@ -5309,7 +5326,7 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
if (mod->submodelof)
mod = mod->submodelof;
hm->entsdirty = false;
LightReloadEntities(hm->relightcontext, mod->entities, true);
LightReloadEntities(hm->relightcontext, Mod_GetEntitiesString(mod), true);
//FIXME: figure out some way to hint this without having to relight the entire frigging world.
for (bt = hm->brushtextures; bt; bt = bt->next)
@ -6685,7 +6702,7 @@ void Terr_WriteMapFile(vfsfile_t *file, model_t *mod)
{
char token[8192];
int nest = 0;
const char *start, *entities = mod->entities;
const char *start, *entities = Mod_GetEntitiesString(mod);
int i;
unsigned int entnum = 0;
heightmap_t *hm;
@ -6803,7 +6820,8 @@ void Mod_Terrain_Save_f(void)
Con_Printf("unable to open %s\n", fname);
else
{
VFS_WRITE(file, mod->entities, strlen(mod->entities));
const char *s = Mod_GetEntitiesString(mod);
VFS_WRITE(file, s, strlen(s));
VFS_CLOSE(file);
}
}
@ -6826,7 +6844,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
char token[8192];
int nest = 0;
int buflen = strlen(entities);
char *out, *start;
char *out, *outstart, *start;
int i;
int submodelnum = 0;
qboolean isdetail = false;
@ -6847,7 +6865,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
#endif
/*FIXME: we need to re-form the entities lump to insert model fields as appropriate*/
mod->entities = out = Z_Malloc(buflen+1);
outstart = out = Z_Malloc(buflen+1);
while(entities)
{
@ -6914,8 +6932,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
if (submod->loadstate == MLS_NOTLOADED)
{
submod->type = mod_heightmap;
if (!submod->entities)
submod->entities = Z_Malloc(1);
Mod_SetEntitiesString(submod, "", true);
subhm = submod->terrain = Mod_LoadTerrainInfo(submod, submod->name, true);
subhm->exteriorcontents = FTECONTENTS_EMPTY;
@ -7149,7 +7166,9 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
while(start < entities)
*out++ = *start++;
}
*out++ = 0;
*out = 0;
Mod_SetEntitiesString(mod, outstart, false);
mod->numsubmodels = submodelnum;
@ -7209,7 +7228,7 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
}
hm->exteriorcontents = exterior; //sky outside the map
Terr_ParseEntityLump(mod->entities, hm);
Terr_ParseEntityLump(mod, hm);
if (hm->firstsegx != hm->maxsegx)
{
@ -7252,7 +7271,7 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
#ifdef RUNTIMELIGHTING
if (hm->relightcontext)
{
LightReloadEntities(hm->relightcontext, mod->entities, true);
LightReloadEntities(hm->relightcontext, Mod_GetEntitiesString(mod), true);
hm->entsdirty = false;
}
#endif
@ -7265,11 +7284,11 @@ void *Mod_LoadTerrainInfo(model_t *mod, char *loadname, qboolean force)
{
heightmap_t *hm;
heightmap_t potential;
if (!mod->entities)
if (!Mod_GetEntitiesString(mod))
return NULL;
memset(&potential, 0, sizeof(potential));
Terr_ParseEntityLump(mod->entities, &potential);
Terr_ParseEntityLump(mod, &potential);
if (potential.firstsegx >= potential.maxsegx || potential.firstsegy >= potential.maxsegy)
{
@ -7347,7 +7366,7 @@ void Mod_Terrain_Create_f(void)
groundheight = Cmd_Argv(5); if (!*groundheight) groundheight = "0";
watername = Cmd_Argv(6); if (!*watername) watername = "";
waterheight = Cmd_Argv(7); if (!*waterheight) waterheight = "1024";
mod.entities = va(
Mod_SetEntitiesString(&mod, va(
"{\n"
"classname \"worldspawn\"\n"
"message \"%s\"\n"
@ -7368,11 +7387,11 @@ void Mod_Terrain_Create_f(void)
"classname info_player_start\n"
"origin \"0 0 1024\"\n"
"}\n"
, Cmd_Argv(2));
, Cmd_Argv(2)), true);
mod.type = mod_heightmap;
mod.terrain = hm = Z_Malloc(sizeof(*hm));
Terr_ParseEntityLump(mod.entities, hm);
Terr_ParseEntityLump(&mod, hm);
hm->entitylock = Sys_CreateMutex();
ClearLink(&hm->recycle);
Q_strncpyz(hm->path, Cmd_Argv(1), sizeof(hm->path));
@ -7411,6 +7430,7 @@ void Mod_Terrain_Create_f(void)
Con_Printf("Wrote %s\n", mname);
FS_FlushFSHashWritten();
}
Mod_SetEntitiesString(&mod, NULL, false);
Terr_FreeModel(&mod);
}
#endif

View File

@ -449,6 +449,50 @@ void Mod_ResortShaders(void)
}
}
}
const char *Mod_GetEntitiesString(model_t *mod)
{
if (!mod)
return NULL;
if (mod->entities_raw) //still cached/correct
return mod->entities_raw;
if (!mod->numentityinfo)
return NULL;
//reform the entities back into a full string now that we apparently need it
return mod->entities_raw;
}
void Mod_SetEntitiesString(model_t *mod, const char *str, qboolean docopy)
{
size_t j;
for (j = 0; j < mod->numentityinfo; j++)
Z_Free(mod->entityinfo[j].keyvals);
mod->numentityinfo = 0;
Z_Free(mod->entityinfo);
mod->entityinfo = NULL;
Z_Free((char*)mod->entities_raw);
mod->entities_raw = NULL;
if (str)
{
if (docopy)
str = Z_StrDup(str);
mod->entities_raw = str;
}
}
void Mod_SetEntitiesStringLen(model_t *mod, const char *str, size_t strsize)
{
if (str)
{
char *cpy = BZ_Malloc(strsize+1);
memcpy(cpy, str, strsize);
cpy[strsize] = 0;
Mod_SetEntitiesString(mod, cpy, false);
}
else
Mod_SetEntitiesString(mod, str, false);
}
/*
===================
Mod_ClearAll
@ -538,8 +582,7 @@ void Mod_Purge(enum mod_purge_e ptype)
mod->meshinfo = NULL;
}
Z_Free(mod->entities);
mod->entities = NULL;
Mod_SetEntitiesString(mod, NULL, false);
#ifdef PSET_SCRIPT
PScript_ClearSurfaceParticles(mod);
@ -2088,10 +2131,11 @@ void Mod_LoadVisibility (model_t *loadmodel, qbyte *mod_base, lump_t *l, qbyte *
}
//scans through the worldspawn for a single specific key.
char *Mod_ParseWorldspawnKey(const char *ents, const char *key, char *buffer, size_t sizeofbuffer)
const char *Mod_ParseWorldspawnKey(model_t *mod, const char *key, char *buffer, size_t sizeofbuffer)
{
char keyname[64];
char value[1024];
const char *ents = Mod_GetEntitiesString(mod);
while(ents && *ents)
{
ents = COM_ParseOut(ents, keyname, sizeof(keyname));
@ -2120,6 +2164,7 @@ static void Mod_SaveEntFile_f(void)
char fname[MAX_QPATH];
model_t *mod = NULL;
char *n = Cmd_Argv(1);
const char *ents;
if (*n)
mod = Mod_ForName(n, MLV_WARN);
#ifndef CLIENTONLY
@ -2137,7 +2182,8 @@ static void Mod_SaveEntFile_f(void)
Con_Printf("Map not loaded\n");
return;
}
if (!mod->entities)
ents = Mod_GetEntitiesString(mod);
if (!ents)
{
Con_Printf("Map is not a map, and has no entities\n");
return;
@ -2155,7 +2201,7 @@ static void Mod_SaveEntFile_f(void)
Q_strncatz(fname, ".ent", sizeof(fname));
}
COM_WriteFile(fname, FS_GAMEONLY, mod->entities, strlen(mod->entities));
COM_WriteFile(fname, FS_GAMEONLY, ents, strlen(ents));
}
/*
@ -2169,46 +2215,46 @@ void Mod_LoadEntities (model_t *loadmodel, qbyte *mod_base, lump_t *l)
size_t sz;
char keyname[64];
char value[1024];
char *ents, *k;
char *ents = NULL, *k;
int t;
loadmodel->entitiescrc = 0;
loadmodel->entities = NULL;
Mod_SetEntitiesString(loadmodel, NULL, false);
if (!l->filelen)
return;
if (mod_loadentfiles.value && !loadmodel->entities && *mod_loadentfiles_dir.string)
if (mod_loadentfiles.value && !ents && *mod_loadentfiles_dir.string)
{
if (!strncmp(loadmodel->name, "maps/", 5))
{
Q_snprintfz(fname, sizeof(fname), "maps/%s/%s", mod_loadentfiles_dir.string, loadmodel->name+5);
COM_StripExtension(fname, fname, sizeof(fname));
Q_strncatz(fname, ".ent", sizeof(fname));
loadmodel->entities = FS_LoadMallocFile(fname, &sz);
ents = FS_LoadMallocFile(fname, &sz);
}
}
if (mod_loadentfiles.value && !loadmodel->entities)
if (mod_loadentfiles.value && !ents)
{
COM_StripExtension(loadmodel->name, fname, sizeof(fname));
Q_strncatz(fname, ".ent", sizeof(fname));
loadmodel->entities = FS_LoadMallocFile(fname, &sz);
ents = FS_LoadMallocFile(fname, &sz);
}
if (mod_loadentfiles.value && !loadmodel->entities)
if (mod_loadentfiles.value && !ents)
{ //tenebrae compat
COM_StripExtension(loadmodel->name, fname, sizeof(fname));
Q_strncatz(fname, ".edo", sizeof(fname));
loadmodel->entities = FS_LoadMallocFile(fname, &sz);
ents = FS_LoadMallocFile(fname, &sz);
}
if (!loadmodel->entities)
if (!ents)
{
loadmodel->entities = Z_Malloc(l->filelen + 1);
memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen);
loadmodel->entities[l->filelen] = 0;
ents = Z_Malloc(l->filelen + 1);
memcpy (ents, mod_base + l->fileofs, l->filelen);
ents[l->filelen] = 0;
}
else
loadmodel->entitiescrc = QCRC_Block(loadmodel->entities, strlen(loadmodel->entities));
loadmodel->entitiescrc = QCRC_Block(ents, strlen(ents));
Mod_SetEntitiesString(loadmodel, ents, false);
ents = loadmodel->entities;
while(ents && *ents)
{
ents = COM_ParseOut(ents, keyname, sizeof(keyname));
@ -2579,7 +2625,7 @@ qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, lump_t *
memset(&overrides, 0, sizeof(overrides));
lmscale = atoi(Mod_ParseWorldspawnKey(loadmodel->entities, "lightmap_scale", buf, sizeof(buf)));
lmscale = atoi(Mod_ParseWorldspawnKey(loadmodel, "lightmap_scale", buf, sizeof(buf)));
if (!lmscale)
lmshift = LMSHIFT_DEFAULT;
else
@ -4880,7 +4926,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
submod->numclusters = bm->visleafs;
if (i)
submod->entities = NULL;
submod->entities_raw = NULL;
memset(&submod->batches, 0, sizeof(submod->batches));
submod->vbos = NULL;
@ -4916,7 +4962,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
if (lightmodel == mod)
{
lightcontext = LightStartup(NULL, lightmodel, true);
LightReloadEntities(lightcontext, lightmodel->entities, false);
LightReloadEntities(lightcontext, Mod_GetEntitiesString(lightmodel), false);
}
#endif
TRACE(("LoadBrushModel %i\n", __LINE__));

View File

@ -953,7 +953,9 @@ typedef struct model_s
q3lightgridinfo_t *lightgrid;
mfog_t *fogs;
int numfogs;
char *entities;
struct {char *keyvals;} *entityinfo;
size_t numentityinfo;
const char *entities_raw;
int entitiescrc;
struct doll_s *dollinfo;

View File

@ -694,7 +694,7 @@ void R_PushDlights (void)
//rtlight loading
#ifdef RTLIGHTS
qboolean R_ImportRTLights(char *entlump)
qboolean R_ImportRTLights(const char *entlump)
{
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_NONE, LIGHTTYPE_SUN, LIGHTTYPE_MINUSXX} lighttype_t;
@ -1257,14 +1257,14 @@ void R_ReloadRTLights_f(void)
rtlights_first = RTL_FIRST;
rtlights_max = RTL_FIRST;
if (!strcmp(Cmd_Argv(1), "bsp"))
R_ImportRTLights(cl.worldmodel->entities);
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
else if (!strcmp(Cmd_Argv(1), "rtlights"))
R_LoadRTLights();
else if (strcmp(Cmd_Argv(1), "none"))
{
R_LoadRTLights();
if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities);
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
}
for (i = 0; i < cl.num_statics; i++)

View File

@ -1762,7 +1762,7 @@ void GLR_RenderView (void)
double time1 = 0, time2;
texid_t sourcetex = r_nulltex;
shader_t *custompostproc = NULL;
float renderscale = r_renderscale.value; //extreme, but whatever
float renderscale; //extreme, but whatever
int oldfbo = 0;
checkglerror();
@ -1790,9 +1790,16 @@ void GLR_RenderView (void)
Surf_SetupFrame();
r_refdef.flags &= ~(RDF_ALLPOSTPROC|RDF_RENDERSCALE);
if (!(r_refdef.flags & RDF_NOWORLDMODEL))
if (dofbo || (r_refdef.flags & RDF_NOWORLDMODEL))
{
renderscale = 1;
}
else
{
renderscale = r_renderscale.value;
if (R_CanBloom())
r_refdef.flags |= RDF_BLOOM;
}
//check if we can do underwater warp
if (cls.protocol != CP_QUAKE2) //quake2 tells us directly

View File

@ -719,9 +719,12 @@ texid_t R_LoadColourmapImage(void)
{
size_t sz;
qbyte *pcx = FS_LoadMallocFile("pics/colormap.pcx", &sz);
colourmappal = Z_Malloc(256*VID_GRADES);
ReadPCXData(pcx, sz, 256, VID_GRADES, colourmappal);
BZ_Free(pcx);
if (pcx)
{
colourmappal = Z_Malloc(256*VID_GRADES);
ReadPCXData(pcx, sz, 256, VID_GRADES, colourmappal);
BZ_Free(pcx);
}
}
if (colourmappal)
{
@ -730,8 +733,17 @@ texid_t R_LoadColourmapImage(void)
}
else
{ //erk
//fixme: generate a proper colourmap
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++)
data[x] = d_8to24rgbtable[x & 0xff];
{
int r, g, b;
float l = 1.0-((x/256)/(float)VID_GRADES);
r = d_8to24rgbtable[x & 0xff];
g = (r>>16)&0xff;
b = (r>>8)&0xff;
r = (r>>0)&0xff;
data[x] = d_8to24rgbtable[GetPaletteIndex(r*l,g*l,b*l)];
}
}
BZ_Free(colourmappal);
return R_LoadTexture("$colourmap", w, h, TF_RGBA32, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA|IF_CLAMP);
@ -4960,11 +4972,10 @@ void QDECL R_BuildDefaultTexnums(texnums_t *src, shader_t *shader)
if ((shader->flags & SHADER_HASPALETTED) && !TEXVALID(tex->paletted))
{
/*dlights/realtime lighting needs some stuff*/
// if (!TEXVALID(tex->paletted) && *tex->mapname)
// tex->paletted = R_LoadHiResTexture(va("%s_pal", tex->mapname), NULL, 0|IF_NEAREST);
// if (!TEXVALID(tex->paletted))
// tex->paletted = R_LoadHiResTexture(va("%s_pal", imagename), subpath, ((*imagename=='{')?0:IF_NOALPHA)|IF_NEAREST);
if (!TEXVALID(tex->paletted) && *tex->mapname)
tex->paletted = R_LoadHiResTexture(va("%s", tex->mapname), NULL, 0|IF_NEAREST|IF_PALETTIZE);
if (!TEXVALID(tex->paletted))
tex->paletted = R_LoadHiResTexture(va("%s", imagename), subpath, ((*imagename=='{')?0:IF_NOALPHA)|IF_NEAREST|IF_PALETTIZE);
}
imageflags |= IF_LOWPRIORITY;
@ -5229,6 +5240,16 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
if (Shader_ParseShader("defaultwall", s))
return;
if (!builtin && r_softwarebanding && (qrenderer == QR_OPENGL || qrenderer == QR_VULKAN) && sh_config.progs_supported)
builtin = (
"{\n"
"{\n"
"program defaultwall#EIGHTBIT\n"
"map $colourmap\n"
"}\n"
"}\n"
);
if (!builtin && r_lightmap.ival)
builtin = (
"{\n"
@ -5605,17 +5626,6 @@ void Shader_DefaultBSPQ2(const char *shortname, shader_t *s, const void *args)
"}\n"
);
}
else if (r_softwarebanding && (qrenderer == QR_OPENGL || qrenderer == QR_VULKAN) && sh_config.progs_supported)
{
Shader_DefaultScript(shortname, s,
"{\n"
"program defaultwall#EIGHTBIT\n"
"{\n"
"map $colourmap\n"
"}\n"
"}\n"
);
}
else
Shader_DefaultBSPLM(shortname, s, args);
}
@ -5766,19 +5776,6 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
);
}
if (!builtin && r_softwarebanding)
{
/*alpha bended*/
builtin = (
"{\n"
"program defaultwall#EIGHTBIT\n"
"{\n"
"map $colourmap\n"
"}\n"
"}\n"
);
}
if (builtin)
Shader_DefaultScript(shortname, s, builtin);
else
@ -5843,6 +5840,20 @@ void Shader_DefaultSkin(const char *shortname, shader_t *s, const void *args)
if (Shader_ParseShader("defaultskin", s))
return;
if (r_softwarebanding && qrenderer == QR_OPENGL && sh_config.progs_supported)
{
Shader_DefaultScript(shortname, s,
"{\n"
"program defaultskin#EIGHTBIT\n"
"affine\n"
"{\n"
"map $colourmap\n"
"}\n"
"}\n"
);
return;
}
Shader_DefaultScript(shortname, s,
"{\n"
"if $lpp\n"

View File

@ -3435,7 +3435,7 @@ void Sh_PreGenerateLights(void)
if (!okay)
okay |= R_LoadRTLights();
if (!okay)
okay |= R_ImportRTLights(cl.worldmodel->entities);
okay |= R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
if (!okay && r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value != 1)
{
r_shadow_realtime_world_lightmaps.value = 1;

View File

@ -402,7 +402,7 @@ void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void R_ReloadRTLights_f(void);
qboolean R_LoadRTLights(void);
qboolean R_ImportRTLights(char *entlump);
qboolean R_ImportRTLights(const char *entlump);
void R_SaveRTLights_f(void);
//doom

View File

@ -144,7 +144,7 @@ struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, model_t *model, qb
ctx->models[ctx->nummodels++] = model;
return ctx;
}
void LightReloadEntities(struct relight_ctx_s *ctx, char *entstring, qboolean ignorestyles)
void LightReloadEntities(struct relight_ctx_s *ctx, const char *entstring, qboolean ignorestyles)
{
#define DEFAULTLIGHTLEVEL 300
mentity_t *mapent;

View File

@ -4482,6 +4482,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall",
"!!ver 110 130\n"
"!!permu DELUXE\n"
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
@ -4494,6 +4495,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/defs.h\"\n"
"#if GL_VERSION >= 130\n"
"#define texture2D texture\n"
"#define textureCube texture\n"
"#define gl_FragColor gl_FragData[0]\n"
"#endif\n"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
@ -4578,7 +4585,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
"vec2 lmcoord0 = floor(lm0 * 512.0*16.0)/(512.0*16.0);\n"
"#if GL_VERSION >= 130\n"
"vec2 lmsize = vec2(textureSize(s_lightmap0, 0));\n"
"#else\n"
"#define lmsize vec2(128.0,2048.0)\n"
"#endif\n"
"#define texelstolightmap (16.0)\n"
"vec2 lmcoord0 = floor(lm0 * lmsize*texelstolightmap)/(lmsize*texelstolightmap);\n"
"#define lm0 lmcoord0\n"
"#endif\n"
@ -4675,6 +4688,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"}\n"
"#endif\n"
},
#endif
#ifdef VKQUAKE

View File

@ -179,7 +179,7 @@ typedef struct botlib_import_s
//check if the point is in potential visible sight
int (QDECL *inPVS)(vec3_t p1, vec3_t p2);
//retrieve the BSP entity data lump
char *(QDECL *BSPEntityData)(void);
const char *(QDECL *BSPEntityData)(void);
//
void (QDECL *BSPModelMinsMaxsOrigin)(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
//send a bot client command

View File

@ -781,7 +781,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
{
extern cvar_t allow_download_refpackages;
func_t f;
char *file;
const char *file;
extern cvar_t pr_maxedicts;
gametype_e newgametype;
@ -1451,7 +1451,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
else
Info_SetValueForStarKey(svs.info, "*entfile", "", MAX_SERVERINFO_STRING);
file = sv.world.worldmodel->entities;
file = Mod_GetEntitiesString(sv.world.worldmodel);
if (!file)
file = "";

View File

@ -80,7 +80,7 @@ void SVQ3_CreateBaseline(void);
void SVQ3_ClientThink(client_t *cl);
void SVQ3Q1_ConvertEntStateQ1ToQ3(entity_state_t *q1, q3entityState_t *q3);
char *mapentspointer;
const char *mapentspointer;
#define Q3SOLID_BMODEL 0xffffff
@ -1614,9 +1614,9 @@ static int QDECL BL_Seek(fileHandle_t f, long offset, int seektype)
{ // on success, apparently returns 0
return VM_FSeek((int)f, offset, seektype, Z_TAG_BOTLIB)?0:-1;
}
static char *QDECL BL_BSPEntityData(void)
static const char *QDECL BL_BSPEntityData(void)
{
return sv.world.worldmodel->entities;
return Mod_GetEntitiesString(sv.world.worldmodel);
}
static void QDECL BL_Trace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask)
{
@ -1836,7 +1836,7 @@ qboolean SVQ3_InitGame(void)
SVQ3_SetConfigString(1, sysinfo);
mapentspointer = sv.world.worldmodel->entities;
mapentspointer = Mod_GetEntitiesString(sv.world.worldmodel);
VM_Call(q3gamevm, GAME_INIT, 0, (int)rand(), false);
CM_InitBoxHull();

View File

@ -1,3 +1,4 @@
!!ver 110 130
!!permu DELUXE
!!permu FULLBRIGHT
!!permu FOG
@ -10,6 +11,12 @@
#include "sys/defs.h"
#if GL_VERSION >= 130
#define texture2D texture
#define textureCube texture
#define gl_FragColor gl_FragData[0]
#endif
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
@ -94,7 +101,13 @@ void main ()
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
vec2 lmcoord0 = floor(lm0 * 512.0*16.0)/(512.0*16.0);
#if GL_VERSION >= 130
vec2 lmsize = vec2(textureSize(s_lightmap0, 0));
#else
#define lmsize vec2(128.0,2048.0)
#endif
#define texelstolightmap (16.0)
vec2 lmcoord0 = floor(lm0 * lmsize*texelstolightmap)/(lmsize*texelstolightmap);
#define lm0 lmcoord0
#endif
@ -191,3 +204,4 @@ void main ()
#endif
}
#endif

View File

@ -4293,8 +4293,8 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
for (i = 0; i < MAXRLIGHTMAPS ; i++)
{
//FIXME: this is fucked
/*
//FIXME: this is fucked, the batch isn't known yet.
#if 0
extern cvar_t gl_overbright;
unsigned char s = shaderstate.curbatch?shaderstate.curbatch->lmlightstyle[i]:0;
float sc;
@ -4321,13 +4321,15 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
}
break;
}
#else
float sc = 1;
#endif
if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
sc = (1<<bound(0, gl_overbright.ival, 2)) * shaderstate.identitylighting;
else
sc = shaderstate.identitylighting;
sc *= d_lightstylevalue[s]/256.0f;
*/
float sc = 1;
// sc *= d_lightstylevalue[s]/256.0f;
Vector4Set(cbe->e_lmscale[i], sc, sc, sc, 1);
}

View File

@ -3267,7 +3267,6 @@ void VK_Shutdown(void)
Sys_DestroyConditional(vk.submitcondition);
memset(&vk, 0, sizeof(vk));
qrenderer = QR_NONE;
#ifdef VK_NO_PROTOTYPES
#define VKFunc(n) vk##n = NULL;