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 #endif
#ifdef Q3CLIENT #ifdef Q3CLIENT
case CP_QUAKE3: case CP_QUAKE3:
msecs -= (double)msecstouse;
CLQ3_SendCmd(&independantphysics[0]); CLQ3_SendCmd(&independantphysics[0]);
memset(&independantphysics[0], 0, sizeof(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 return; // Q3 does it's own thing
#endif #endif
default: 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; int mip;
if (mips->type != PTI_2D) if (mips->type != PTI_2D)
return; //blurgh 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 that format isn't supported/desired, try converting it.
if (sh_config.texfmt[mips->encoding]) if (sh_config.texfmt[mips->encoding])
return; return;
@ -3721,7 +3754,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
//8bit opaque data //8bit opaque data
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags); Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
flags |= IF_NOPICMIP; 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 = unsigned int pixels =
(imgwidth>>0) * (imgheight>>0) + (imgwidth>>0) * (imgheight>>0) +
@ -4153,7 +4186,7 @@ static qboolean Image_LoadRawTexture(texid_t tex, unsigned int flags, void *rawd
return false; return false;
} }
Image_GenerateMips(mips, flags); Image_GenerateMips(mips, flags);
Image_ChangeFormat(mips, fmt); Image_ChangeFormat(mips, flags, fmt);
tex->width = imgwidth; tex->width = imgwidth;
tex->height = imgheight; tex->height = imgheight;
@ -4612,7 +4645,7 @@ image_t *Image_FindTexture(const char *identifier, const char *subdir, unsigned
tex = Hash_Get(&imagetable, identifier); tex = Hash_Get(&imagetable, identifier);
while(tex) while(tex)
{ {
if (!((tex->flags ^ flags) & IF_CLAMP)) if (!((tex->flags ^ flags) & (IF_CLAMP|IF_PALETTIZE)))
{ {
#ifdef PURGEIMAGES #ifdef PURGEIMAGES
if (!strcmp(subdir, tex->subpath?tex->subpath:"")) 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)) if (!Image_GenMip0(&mips, flags, data, palette, width, height, fmt, false))
return; return;
Image_GenerateMips(&mips, flags); Image_GenerateMips(&mips, flags);
Image_ChangeFormat(&mips, fmt); Image_ChangeFormat(&mips, flags, fmt);
rf->IMG_LoadTextureMips(tex, &mips); rf->IMG_LoadTextureMips(tex, &mips);
tex->width = width; tex->width = width;
tex->height = height; tex->height = height;

View file

@ -48,7 +48,7 @@ vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefil
#ifndef SVNREVISION #ifndef SVNREVISION
#define SVNREVISION - #define SVNREVISION -
#endif #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_HIDDEN 0x80 //wrong arch, file conflicts, etc. still listed if actually installed.
#define DPF_ENGINE 0x100 //engine update. replaces old autoupdate mechanism #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_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 //pak.lst
//priories <0 //priories <0
@ -172,8 +173,10 @@ typedef struct package_s {
static qboolean loadedinstalled; static qboolean loadedinstalled;
static package_t *availablepackages; static package_t *availablepackages;
static int numpackages; 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. //FIXME: these are allocated for the life of the exe. changing basedir should purge the list.
static int numdownloadablelists = 0; static int numdownloadablelists = 0;
@ -185,7 +188,7 @@ static struct
qboolean save; //written into our local file qboolean save; //written into our local file
struct dl_download *curdl; //the download context struct dl_download *curdl; //the download context
} downloadablelist[32]; } 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) 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++) for (i = 0; i < countof(p->mirror); i++)
Z_Free(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->description);
Z_Free(p->author); Z_Free(p->author);
Z_Free(p->license); 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 *arch = NULL;
char *qhash = NULL; char *qhash = NULL;
char *title = NULL; char *title = NULL;
char *category = NULL;
char *description = NULL; char *description = NULL;
char *license = NULL; char *license = NULL;
char *author = 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); char *arg = Cmd_Argv(i);
if (!strncmp(arg, "url=", 4)) if (!strncmp(arg, "url=", 4))
url = arg+4; url = arg+4;
else if (!strncmp(arg, "title=", 8)) else if (!strncmp(arg, "category=", 9))
title = arg+8; category = arg+9;
else if (!strncmp(arg, "title=", 6))
title = arg+6;
else if (!strncmp(arg, "gamedir=", 8)) else if (!strncmp(arg, "gamedir=", 8))
gamedir = arg+8; gamedir = arg+8;
else if (!strncmp(arg, "ver=", 4)) else if (!strncmp(arg, "ver=", 4))
@ -740,6 +749,23 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c
} }
} }
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
{
if (*prefix) if (*prefix)
Q_snprintfz(pathname, sizeof(pathname), "%s/%s", prefix, fullname); Q_snprintfz(pathname, sizeof(pathname), "%s/%s", prefix, fullname);
else else
@ -747,6 +773,7 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c
p->name = Z_StrDup(COM_SkipPath(pathname)); p->name = Z_StrDup(COM_SkipPath(pathname));
*COM_SkipPath(pathname) = 0; *COM_SkipPath(pathname) = 0;
p->category = Z_StrDup(pathname); p->category = Z_StrDup(pathname);
}
if (!title) if (!title)
title = p->name; title = p->name;
@ -1219,6 +1246,7 @@ static void PM_PrintChanges(void)
Con_Printf("<%i package(s) changed>\n", changes); Con_Printf("<%i package(s) changed>\n", changes);
} }
static void PM_ApplyChanges(void);
static void PM_ListDownloaded(struct dl_download *dl) static void PM_ListDownloaded(struct dl_download *dl)
{ {
@ -1246,16 +1274,46 @@ static void PM_ListDownloaded(struct dl_download *dl)
else else
downloadablelist[i].received = -1; downloadablelist[i].received = -1;
if (!doautoupdate) if (!doautoupdate && !domanifestinstall)
return; //don't spam this. return; //don't spam this.
for (i = 0; i < numdownloadablelists; i++) for (i = 0; i < numdownloadablelists; i++)
{ {
if (!downloadablelist[i].received) if (!downloadablelist[i].received)
break; 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()) if (PM_MarkUpdates())
{ {
#ifdef DOWNLOADMENU #ifdef DOWNLOADMENU
@ -1282,6 +1340,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
static void PM_UpdatePackageList(qboolean autoupdate, int retry) static void PM_UpdatePackageList(qboolean autoupdate, int retry)
{ {
unsigned int i; unsigned int i;
int setting;
if (retry>1 || fs_downloads_url.modified) if (retry>1 || fs_downloads_url.modified)
PM_Shutdown(); PM_Shutdown();
@ -1303,7 +1362,11 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
if (downloadablelist[i].curdl) if (downloadablelist[i].curdl)
continue; 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) if (downloadablelist[i].curdl)
{ {
downloadablelist[i].curdl->user_num = i; downloadablelist[i].curdl->user_num = i;
@ -1441,7 +1504,7 @@ static void PM_WriteInstalledPackages(void)
if (p->description) if (p->description)
{ {
Q_strncatz(buf, " ", sizeof(buf)); 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) if (p->license)
{ {
@ -1735,23 +1798,60 @@ static char *PM_GetTempName(package_t *p)
return Z_StrDup(destname); 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 //looks for the next package that needs downloading, and grabs it
static void PM_StartADownload(void) static void PM_StartADownload(void)
{ {
vfsfile_t *tmpfile; vfsfile_t *tmpfile;
char *temp; char *temp;
// char native[MAX_OSPATH];
package_t *p; package_t *p;
int simultaneous = 1; const int simultaneous = 1;
int i; int i;
for (p = availablepackages; p ; p=p->next) for (p = availablepackages; p && simultaneous > PM_IsApplying(); p=p->next)
{
if (p->download)
simultaneous--;
}
for (p = availablepackages; p && simultaneous > 0; p=p->next)
{ {
if (p->trymirrors) if (p->trymirrors)
{ //flagged for a (re?)download { //flagged for a (re?)download
@ -1848,8 +1948,6 @@ static void PM_StartADownload(void)
VFS_CLOSE(tmpfile); VFS_CLOSE(tmpfile);
FS_Remove(temp, p->fsroot); FS_Remove(temp, p->fsroot);
} }
simultaneous--;
} }
} }
} }
@ -1862,7 +1960,9 @@ static void PM_ApplyChanges(void)
for (link = &availablepackages; *link ; ) for (link = &availablepackages; *link ; )
{ {
p = *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: { //if we don't want it but we have it anyway:
qboolean reloadpacks = false; qboolean reloadpacks = false;
struct packagedep_s *dep; struct packagedep_s *dep;
@ -1941,6 +2041,20 @@ static void PM_ApplyChanges(void)
PM_StartADownload(); //and try to do those downloads. 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) void PM_Command_f(void)
{ {
package_t *p; package_t *p;
@ -1990,7 +2104,7 @@ void PM_Command_f(void)
else else
status = ""; 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"); 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) if (p->flags & DPF_DISPLAYVERSION)
n = va("%s (%s)", n, *p->version?p->version:"unversioned"); 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[] = char *settings[] =
{ {
"Unsupported", "Unsupported",
"Revert", "Revert Engine",
"Off", "Off",
"Stable Updates", "Stable Updates",
"Unsable Updates" "Test Updates"
}; };
char *text; char *text;
int setting = Sys_GetAutoUpdateSetting(); int setting = Sys_GetAutoUpdateSetting();

View file

@ -158,6 +158,9 @@ enum mlverbosity_e
MLV_ERROR 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_ClearAll (void);
extern void Mod_Purge (enum mod_purge_e type); 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. 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_Extradata (struct model_s *mod); // handles caching
extern void Mod_TouchModel (const char *name); extern void Mod_TouchModel (const char *name);
extern const char *Mod_FixName (const char *modname, const char *worldname); //remaps the name appropriately 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 void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, int surfaceidx, const char *name); 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); const char *s = PR_GetStringOfs(prinst, OFS_PARM0);
if (*s == 0) if (*s == 0)
s = cl.worldmodel?cl.worldmodel->entities:NULL; s = Mod_GetEntitiesString(cl.worldmodel);
csqcmapentitydata = s; csqcmapentitydata = s;
G_INT(OFS_RETURN) = 0; G_INT(OFS_RETURN) = 0;
return; return;
@ -6939,14 +6939,14 @@ void CSQC_WorldLoaded(void)
CSQC_FindGlobals(false); CSQC_FindGlobals(false);
csqcmapentitydataloaded = true; csqcmapentitydataloaded = true;
csqcmapentitydata = cl.worldmodel?cl.worldmodel->entities:NULL; csqcmapentitydata = Mod_GetEntitiesString(cl.worldmodel);
csqc_world.worldmodel = cl.worldmodel; csqc_world.worldmodel = cl.worldmodel;
World_RBE_Start(&csqc_world); World_RBE_Start(&csqc_world);
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0); worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
worldent->v->solid = SOLID_BSP; worldent->v->solid = SOLID_BSP;
wmodelindex = CS_FindModel(cl.worldmodel->name, &tmp); wmodelindex = CS_FindModel(cl.worldmodel?cl.worldmodel->name:"", &tmp);
tmp = csqc_worldchanged; tmp = csqc_worldchanged;
csqc_setmodel(csqcprogs, worldent, wmodelindex); csqc_setmodel(csqcprogs, worldent, wmodelindex);
csqc_worldchanged = tmp; 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) if (rtfmt)
{ {
tid->flags = (tid->flags & ~(IF_NEAREST|IF_LINEAR)) | (imageflags & (IF_NEAREST|IF_LINEAR));
Image_Upload(tid, rtfmt, NULL, NULL, width, height, imageflags); Image_Upload(tid, rtfmt, NULL, NULL, width, height, imageflags);
tid->width = width; tid->width = width;
tid->height = height; 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?)*/ /*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)); 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.FindTouchedLeafs = D3_FindTouchedLeafs;
mod->funcs.NativeTrace = D3_Trace; mod->funcs.NativeTrace = D3_Trace;

View file

@ -403,6 +403,7 @@ enum imageflags
IF_MIPCAP = 1<<10, IF_MIPCAP = 1<<10,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_PALETTIZE = 1<<21,
IF_NOPURGE = 1<<22, IF_NOPURGE = 1<<22,
IF_HIGHPRIORITY = 1<<23, IF_HIGHPRIORITY = 1<<23,
IF_LOWPRIORITY = 1<<24, 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 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. 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); 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); void LightShutdown(struct relight_ctx_s *ctx, struct model_s *mod);
extern const size_t lightthreadctxsize; extern const size_t lightthreadctxsize;
#endif #endif

View file

@ -3613,7 +3613,7 @@ qboolean Sys_DoInstall(void)
} }
/*create startmenu icon*/ /*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; HRESULT hres;
IShellLinkW *psl; IShellLinkW *psl;

View file

@ -43,6 +43,9 @@ void W_CleanupName (const char *in, char *out)
int i; int i;
int c; int c;
if (!strncmp(in, "textures/", 9))
in += 9;
for (i=0 ; i<16 ; i++ ) for (i=0 ; i<16 ; i++ )
{ {
c = in[i]; c = in[i];
@ -694,7 +697,7 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
{ {
char token[4096]; char token[4096];
char key[128]; char key[128];
char *data = wmodel->entities; const char *data = Mod_GetEntitiesString(wmodel);
mapskys_t *msky; mapskys_t *msky;
cl.skyrotate = 0; cl.skyrotate = 0;
@ -730,7 +733,7 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
break; // error break; // error
if (!strcmp("wad", key)) // for HalfLife maps 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, ";", 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) 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/"; char wadname[4096+9]="textures/";
int i, j, k; int i, j, k;
model_t *wmodel = cl.worldmodel;
if (*wads) //now go about checking the wads if (wmodel && (wmodel->fromgame == fg_halflife || wmodel->type == mod_heightmap) && *wads) //now go about checking the wads
{ {
j = 0; j = 0;
wads[4095] = '\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; galiasskin_t *outskin = galias->ofsskins;
const char *slash; const char *slash;
unsigned int texflags; unsigned int texflags;
const char *defaultshader; const char *defaultshader = NULL;
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;
s = pq1inmodel->skinwidth*pq1inmodel->skinheight; s = pq1inmodel->skinwidth*pq1inmodel->skinheight;
for (i = 0; i < pq1inmodel->numskins; i++) 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_min = CVARD("gameversion_min","", "gamecode version for server browsers");
cvar_t gameversion_max = CVARD("gameversion_max","", "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_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_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_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."); 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 // 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] = { conchar_t q3codemasks[MAXQ3COLOURS] = {
0x00000000, // 0, black COLOR_BLACK << CON_FGSHIFT, // 0, black
0x0c000000, // 1, red COLOR_RED << CON_FGSHIFT, // 1, red
0x0a000000, // 2, green COLOR_GREEN << CON_FGSHIFT, // 2, green
0x0e000000, // 3, yellow COLOR_YELLOW << CON_FGSHIFT, // 3, yellow
0x09000000, // 4, blue COLOR_BLUE << CON_FGSHIFT, // 4, blue
0x0b000000, // 5, cyan COLOR_CYAN << CON_FGSHIFT, // 5, cyan
0x0d000000, // 6, magenta COLOR_MAGENTA << CON_FGSHIFT, // 6, magenta
0x0f000000, // 7, white COLOR_WHITE << CON_FGSHIFT, // 7, white
0x0f100000, // 8, half-alpha white (BX_COLOREDTEXT) (COLOR_WHITE << CON_FGSHIFT)|CON_HALFALPHA, // 8, half-alpha white (BX_COLOREDTEXT)
0x07000000 // 9, "half-intensity" (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 //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 { //q3 colour codes
if (ext & CON_RICHFORECOLOUR) if (ext & CON_RICHFORECOLOUR)
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|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 else if (str[1] == '&') // extended code
{ {

View file

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

View file

@ -3948,6 +3948,7 @@ void FS_Shutdown(void)
if (!fs_thread_mutex) if (!fs_thread_mutex)
return; return;
PM_ManifestPackage(NULL, false);
FS_FreePaths(); FS_FreePaths();
Sys_DestroyMutex(fs_thread_mutex); Sys_DestroyMutex(fs_thread_mutex);
fs_thread_mutex = NULL; fs_thread_mutex = NULL;
@ -4185,6 +4186,8 @@ static char fspdl_finalpath[MAX_OSPATH];
static void FS_BeginNextPackageDownload(void); static void FS_BeginNextPackageDownload(void);
qboolean FS_DownloadingPackage(void) qboolean FS_DownloadingPackage(void)
{ {
if (PM_IsApplying())
return true;
return !fs_manifest || !!curpackagedownload; return !fs_manifest || !!curpackagedownload;
} }
//vfsfile_t *FS_DecompressXZip(vfsfile_t *infile, vfsfile_t *outfile); //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); Con_Printf("Unable to rename \"%s\" to \"%s\"\n", fspdl_temppath, fspdl_finalpath);
} }
// else
// PM_AddDownloadedPackage(fspdl_finalpath);
} }
} }
Sys_remove (fspdl_temppath); Sys_remove (fspdl_temppath);
@ -4715,6 +4720,7 @@ static void FS_ManifestUpdated(struct dl_download *dl)
void FS_BeginManifestUpdates(void) void FS_BeginManifestUpdates(void)
{ {
ftemanifest_t *man = fs_manifest; ftemanifest_t *man = fs_manifest;
PM_ManifestPackage(man->installupd, man->doinstall);
if (curpackagedownload || !man) if (curpackagedownload || !man)
return; return;
@ -4914,6 +4920,8 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
if (fs_manifest && fs_manifest->downloadsurl) if (fs_manifest && fs_manifest->downloadsurl)
olddownloadsurl = Z_StrDup(fs_manifest->downloadsurl); olddownloadsurl = Z_StrDup(fs_manifest->downloadsurl);
else if (!fs_manifest && man->downloadsurl)
olddownloadsurl = Z_StrDup(man->downloadsurl);
else else
olddownloadsurl = NULL; olddownloadsurl = NULL;
@ -4935,7 +4943,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
} }
fs_manifest = man; 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. { //make sure we only fuck over the user if this is a 'secure' manifest, and not hacked in some way.
Z_Free(man->downloadsurl); Z_Free(man->downloadsurl);
man->downloadsurl = olddownloadsurl; man->downloadsurl = olddownloadsurl;
@ -5167,6 +5175,7 @@ void FS_CreateBasedir(const char *path)
com_installer = false; com_installer = false;
Q_strncpyz (com_gamepath, path, sizeof(com_gamepath)); Q_strncpyz (com_gamepath, path, sizeof(com_gamepath));
COM_CreatePath(com_gamepath); COM_CreatePath(com_gamepath);
fs_manifest->doinstall = true;
FS_ChangeGame(fs_manifest, true, false); FS_ChangeGame(fs_manifest, true, false);
if (host_parms.manifest) 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 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); 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); void Menu_Download_Update(void);
int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr); 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_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_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l); 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); 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; unsigned short lmshift, lmscale;
char buf[64]; 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) if (!lmscale)
lmshift = LMSHIFT_DEFAULT; lmshift = LMSHIFT_DEFAULT;
else else
@ -2036,20 +2037,6 @@ qboolean CModQ2_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l)
return true; 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 #ifdef Q3BSPS
qboolean CModQ3_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l) 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_LoadSubmodels (mod, mod_base, &header.lumps[Q3LUMP_MODELS]);
noerrors = noerrors && CModQ3_LoadVisibility (mod, mod_base, &header.lumps[Q3LUMP_VISIBILITY]); noerrors = noerrors && CModQ3_LoadVisibility (mod, mod_base, &header.lumps[Q3LUMP_VISIBILITY]);
if (noerrors) if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q3LUMP_ENTITIES]); Mod_LoadEntities (mod, mod_base, &header.lumps[Q3LUMP_ENTITIES]);
if (!noerrors) 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_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]);
noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]); noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]);
if (noerrors) if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]); Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
#ifndef CLIENTONLY #ifndef CLIENTONLY
mod->funcs.FatPVS = Q2BSP_FatPVS; 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_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]);
noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname); noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname);
if (noerrors) 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 && 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 && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], false);
noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]); 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); Q_snprintfz (name, sizeof(name), "*%i:%s", i, wmod->name);
mod = Mod_FindName (name); mod = Mod_FindName (name);
*mod = *wmod; *mod = *wmod;
mod->entities = NULL; mod->entities_raw = NULL;
mod->submodelof = wmod; mod->submodelof = wmod;
Q_strncpyz(mod->name, name, sizeof(mod->name)); Q_strncpyz(mod->name, name, sizeof(mod->name));
memset(&mod->memgroup, 0, sizeof(mod->memgroup)); 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_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_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 #endif

View file

@ -4825,22 +4825,38 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
switch(action) 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: case ter_ents_wipe:
G_INT(OFS_RETURN) = PR_TempString(prinst, mod->entities); G_INT(OFS_RETURN) = PR_TempString(prinst, Mod_GetEntitiesString(mod));
mod->entities = Z_Malloc(1); Mod_SetEntitiesString(mod, "", true);
return; return;
case ter_ents_concat: case ter_ents_concat:
{ {
char *olds = mod->entities; char *newv;
const char *olds = Mod_GetEntitiesString(mod);
const char *news = PR_GetStringOfs(prinst, OFS_PARM1); const char *news = PR_GetStringOfs(prinst, OFS_PARM1);
size_t oldlen = strlen(olds); size_t oldlen = strlen(olds);
size_t newlen = strlen(news); size_t newlen = strlen(news);
mod->entities = Z_Malloc(oldlen + newlen + 1); newv = Z_Malloc(oldlen + newlen + 1);
memcpy(mod->entities, olds, oldlen); memcpy(newv, olds, oldlen);
memcpy(mod->entities+oldlen, news, newlen); memcpy(newv+oldlen, news, newlen);
mod->entities[oldlen + newlen] = 0; newv[oldlen + newlen] = 0;
Z_Free(olds); Z_Free((char*)olds);
G_FLOAT(OFS_RETURN) = oldlen + newlen; G_FLOAT(OFS_RETURN) = oldlen + newlen;
Mod_SetEntitiesString(mod, newv, false);
if (mod->terrain) if (mod->terrain)
{ {
hm = mod->terrain; hm = mod->terrain;
@ -4849,7 +4865,7 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
} }
return; return;
case ter_ents_get: case ter_ents_get:
G_INT(OFS_RETURN) = PR_TempString(prinst, mod->entities); G_INT(OFS_RETURN) = PR_TempString(prinst, Mod_GetEntitiesString(mod));
return; return;
case ter_save: case ter_save:
if (mod->terrain) if (mod->terrain)
@ -5087,10 +5103,11 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
} }
#endif #endif
void Terr_ParseEntityLump(char *data, heightmap_t *heightmap) void Terr_ParseEntityLump(model_t *mod, heightmap_t *heightmap)
{ {
char key[128]; char key[128];
char value[2048]; char value[2048];
const char *data = Mod_GetEntitiesString(mod);
heightmap->sectionsize = 1024; heightmap->sectionsize = 1024;
heightmap->mode = HMM_TERRAIN; heightmap->mode = HMM_TERRAIN;
@ -5309,7 +5326,7 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
if (mod->submodelof) if (mod->submodelof)
mod = mod->submodelof; mod = mod->submodelof;
hm->entsdirty = false; 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. //FIXME: figure out some way to hint this without having to relight the entire frigging world.
for (bt = hm->brushtextures; bt; bt = bt->next) for (bt = hm->brushtextures; bt; bt = bt->next)
@ -6685,7 +6702,7 @@ void Terr_WriteMapFile(vfsfile_t *file, model_t *mod)
{ {
char token[8192]; char token[8192];
int nest = 0; int nest = 0;
const char *start, *entities = mod->entities; const char *start, *entities = Mod_GetEntitiesString(mod);
int i; int i;
unsigned int entnum = 0; unsigned int entnum = 0;
heightmap_t *hm; heightmap_t *hm;
@ -6803,7 +6820,8 @@ void Mod_Terrain_Save_f(void)
Con_Printf("unable to open %s\n", fname); Con_Printf("unable to open %s\n", fname);
else else
{ {
VFS_WRITE(file, mod->entities, strlen(mod->entities)); const char *s = Mod_GetEntitiesString(mod);
VFS_WRITE(file, s, strlen(s));
VFS_CLOSE(file); VFS_CLOSE(file);
} }
} }
@ -6826,7 +6844,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
char token[8192]; char token[8192];
int nest = 0; int nest = 0;
int buflen = strlen(entities); int buflen = strlen(entities);
char *out, *start; char *out, *outstart, *start;
int i; int i;
int submodelnum = 0; int submodelnum = 0;
qboolean isdetail = false; qboolean isdetail = false;
@ -6847,7 +6865,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
#endif #endif
/*FIXME: we need to re-form the entities lump to insert model fields as appropriate*/ /*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) while(entities)
{ {
@ -6914,8 +6932,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
if (submod->loadstate == MLS_NOTLOADED) if (submod->loadstate == MLS_NOTLOADED)
{ {
submod->type = mod_heightmap; submod->type = mod_heightmap;
if (!submod->entities) Mod_SetEntitiesString(submod, "", true);
submod->entities = Z_Malloc(1);
subhm = submod->terrain = Mod_LoadTerrainInfo(submod, submod->name, true); subhm = submod->terrain = Mod_LoadTerrainInfo(submod, submod->name, true);
subhm->exteriorcontents = FTECONTENTS_EMPTY; subhm->exteriorcontents = FTECONTENTS_EMPTY;
@ -7149,7 +7166,9 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
while(start < entities) while(start < entities)
*out++ = *start++; *out++ = *start++;
} }
*out++ = 0; *out = 0;
Mod_SetEntitiesString(mod, outstart, false);
mod->numsubmodels = submodelnum; 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 hm->exteriorcontents = exterior; //sky outside the map
Terr_ParseEntityLump(mod->entities, hm); Terr_ParseEntityLump(mod, hm);
if (hm->firstsegx != hm->maxsegx) if (hm->firstsegx != hm->maxsegx)
{ {
@ -7252,7 +7271,7 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
#ifdef RUNTIMELIGHTING #ifdef RUNTIMELIGHTING
if (hm->relightcontext) if (hm->relightcontext)
{ {
LightReloadEntities(hm->relightcontext, mod->entities, true); LightReloadEntities(hm->relightcontext, Mod_GetEntitiesString(mod), true);
hm->entsdirty = false; hm->entsdirty = false;
} }
#endif #endif
@ -7265,11 +7284,11 @@ void *Mod_LoadTerrainInfo(model_t *mod, char *loadname, qboolean force)
{ {
heightmap_t *hm; heightmap_t *hm;
heightmap_t potential; heightmap_t potential;
if (!mod->entities) if (!Mod_GetEntitiesString(mod))
return NULL; return NULL;
memset(&potential, 0, sizeof(potential)); memset(&potential, 0, sizeof(potential));
Terr_ParseEntityLump(mod->entities, &potential); Terr_ParseEntityLump(mod, &potential);
if (potential.firstsegx >= potential.maxsegx || potential.firstsegy >= potential.maxsegy) 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"; groundheight = Cmd_Argv(5); if (!*groundheight) groundheight = "0";
watername = Cmd_Argv(6); if (!*watername) watername = ""; watername = Cmd_Argv(6); if (!*watername) watername = "";
waterheight = Cmd_Argv(7); if (!*waterheight) waterheight = "1024"; waterheight = Cmd_Argv(7); if (!*waterheight) waterheight = "1024";
mod.entities = va( Mod_SetEntitiesString(&mod, va(
"{\n" "{\n"
"classname \"worldspawn\"\n" "classname \"worldspawn\"\n"
"message \"%s\"\n" "message \"%s\"\n"
@ -7368,11 +7387,11 @@ void Mod_Terrain_Create_f(void)
"classname info_player_start\n" "classname info_player_start\n"
"origin \"0 0 1024\"\n" "origin \"0 0 1024\"\n"
"}\n" "}\n"
, Cmd_Argv(2)); , Cmd_Argv(2)), true);
mod.type = mod_heightmap; mod.type = mod_heightmap;
mod.terrain = hm = Z_Malloc(sizeof(*hm)); mod.terrain = hm = Z_Malloc(sizeof(*hm));
Terr_ParseEntityLump(mod.entities, hm); Terr_ParseEntityLump(&mod, hm);
hm->entitylock = Sys_CreateMutex(); hm->entitylock = Sys_CreateMutex();
ClearLink(&hm->recycle); ClearLink(&hm->recycle);
Q_strncpyz(hm->path, Cmd_Argv(1), sizeof(hm->path)); 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); Con_Printf("Wrote %s\n", mname);
FS_FlushFSHashWritten(); FS_FlushFSHashWritten();
} }
Mod_SetEntitiesString(&mod, NULL, false);
Terr_FreeModel(&mod); Terr_FreeModel(&mod);
} }
#endif #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 Mod_ClearAll
@ -538,8 +582,7 @@ void Mod_Purge(enum mod_purge_e ptype)
mod->meshinfo = NULL; mod->meshinfo = NULL;
} }
Z_Free(mod->entities); Mod_SetEntitiesString(mod, NULL, false);
mod->entities = NULL;
#ifdef PSET_SCRIPT #ifdef PSET_SCRIPT
PScript_ClearSurfaceParticles(mod); 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. //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 keyname[64];
char value[1024]; char value[1024];
const char *ents = Mod_GetEntitiesString(mod);
while(ents && *ents) while(ents && *ents)
{ {
ents = COM_ParseOut(ents, keyname, sizeof(keyname)); ents = COM_ParseOut(ents, keyname, sizeof(keyname));
@ -2120,6 +2164,7 @@ static void Mod_SaveEntFile_f(void)
char fname[MAX_QPATH]; char fname[MAX_QPATH];
model_t *mod = NULL; model_t *mod = NULL;
char *n = Cmd_Argv(1); char *n = Cmd_Argv(1);
const char *ents;
if (*n) if (*n)
mod = Mod_ForName(n, MLV_WARN); mod = Mod_ForName(n, MLV_WARN);
#ifndef CLIENTONLY #ifndef CLIENTONLY
@ -2137,7 +2182,8 @@ static void Mod_SaveEntFile_f(void)
Con_Printf("Map not loaded\n"); Con_Printf("Map not loaded\n");
return; return;
} }
if (!mod->entities) ents = Mod_GetEntitiesString(mod);
if (!ents)
{ {
Con_Printf("Map is not a map, and has no entities\n"); Con_Printf("Map is not a map, and has no entities\n");
return; return;
@ -2155,7 +2201,7 @@ static void Mod_SaveEntFile_f(void)
Q_strncatz(fname, ".ent", sizeof(fname)); 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; size_t sz;
char keyname[64]; char keyname[64];
char value[1024]; char value[1024];
char *ents, *k; char *ents = NULL, *k;
int t; int t;
loadmodel->entitiescrc = 0; Mod_SetEntitiesString(loadmodel, NULL, false);
loadmodel->entities = NULL;
if (!l->filelen) if (!l->filelen)
return; 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)) if (!strncmp(loadmodel->name, "maps/", 5))
{ {
Q_snprintfz(fname, sizeof(fname), "maps/%s/%s", mod_loadentfiles_dir.string, loadmodel->name+5); Q_snprintfz(fname, sizeof(fname), "maps/%s/%s", mod_loadentfiles_dir.string, loadmodel->name+5);
COM_StripExtension(fname, fname, sizeof(fname)); COM_StripExtension(fname, fname, sizeof(fname));
Q_strncatz(fname, ".ent", 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)); COM_StripExtension(loadmodel->name, fname, sizeof(fname));
Q_strncatz(fname, ".ent", 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 { //tenebrae compat
COM_StripExtension(loadmodel->name, fname, sizeof(fname)); COM_StripExtension(loadmodel->name, fname, sizeof(fname));
Q_strncatz(fname, ".edo", 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); ents = Z_Malloc(l->filelen + 1);
memcpy (loadmodel->entities, mod_base + l->fileofs, l->filelen); memcpy (ents, mod_base + l->fileofs, l->filelen);
loadmodel->entities[l->filelen] = 0; ents[l->filelen] = 0;
} }
else 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) while(ents && *ents)
{ {
ents = COM_ParseOut(ents, keyname, sizeof(keyname)); 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)); 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) if (!lmscale)
lmshift = LMSHIFT_DEFAULT; lmshift = LMSHIFT_DEFAULT;
else else
@ -4880,7 +4926,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
submod->numclusters = bm->visleafs; submod->numclusters = bm->visleafs;
if (i) if (i)
submod->entities = NULL; submod->entities_raw = NULL;
memset(&submod->batches, 0, sizeof(submod->batches)); memset(&submod->batches, 0, sizeof(submod->batches));
submod->vbos = NULL; submod->vbos = NULL;
@ -4916,7 +4962,7 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
if (lightmodel == mod) if (lightmodel == mod)
{ {
lightcontext = LightStartup(NULL, lightmodel, true); lightcontext = LightStartup(NULL, lightmodel, true);
LightReloadEntities(lightcontext, lightmodel->entities, false); LightReloadEntities(lightcontext, Mod_GetEntitiesString(lightmodel), false);
} }
#endif #endif
TRACE(("LoadBrushModel %i\n", __LINE__)); TRACE(("LoadBrushModel %i\n", __LINE__));

View file

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

View file

@ -694,7 +694,7 @@ void R_PushDlights (void)
//rtlight loading //rtlight loading
#ifdef RTLIGHTS #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; 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_first = RTL_FIRST;
rtlights_max = RTL_FIRST; rtlights_max = RTL_FIRST;
if (!strcmp(Cmd_Argv(1), "bsp")) if (!strcmp(Cmd_Argv(1), "bsp"))
R_ImportRTLights(cl.worldmodel->entities); R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
else if (!strcmp(Cmd_Argv(1), "rtlights")) else if (!strcmp(Cmd_Argv(1), "rtlights"))
R_LoadRTLights(); R_LoadRTLights();
else if (strcmp(Cmd_Argv(1), "none")) else if (strcmp(Cmd_Argv(1), "none"))
{ {
R_LoadRTLights(); R_LoadRTLights();
if (rtlights_first == rtlights_max) if (rtlights_first == rtlights_max)
R_ImportRTLights(cl.worldmodel->entities); R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
} }
for (i = 0; i < cl.num_statics; i++) for (i = 0; i < cl.num_statics; i++)

View file

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

View file

@ -719,10 +719,13 @@ texid_t R_LoadColourmapImage(void)
{ {
size_t sz; size_t sz;
qbyte *pcx = FS_LoadMallocFile("pics/colormap.pcx", &sz); qbyte *pcx = FS_LoadMallocFile("pics/colormap.pcx", &sz);
if (pcx)
{
colourmappal = Z_Malloc(256*VID_GRADES); colourmappal = Z_Malloc(256*VID_GRADES);
ReadPCXData(pcx, sz, 256, VID_GRADES, colourmappal); ReadPCXData(pcx, sz, 256, VID_GRADES, colourmappal);
BZ_Free(pcx); BZ_Free(pcx);
} }
}
if (colourmappal) if (colourmappal)
{ {
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++) for (x = 0; x < sizeof(data)/sizeof(data[0]); x++)
@ -730,8 +733,17 @@ texid_t R_LoadColourmapImage(void)
} }
else else
{ //erk { //erk
//fixme: generate a proper colourmap
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++) 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); BZ_Free(colourmappal);
return R_LoadTexture("$colourmap", w, h, TF_RGBA32, data, IF_NOMIPMAP|IF_NOPICMIP|IF_NEAREST|IF_NOGAMMA|IF_CLAMP); 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)) if ((shader->flags & SHADER_HASPALETTED) && !TEXVALID(tex->paletted))
{ {
/*dlights/realtime lighting needs some stuff*/ if (!TEXVALID(tex->paletted) && *tex->mapname)
// if (!TEXVALID(tex->paletted) && *tex->mapname) tex->paletted = R_LoadHiResTexture(va("%s", tex->mapname), NULL, 0|IF_NEAREST|IF_PALETTIZE);
// tex->paletted = R_LoadHiResTexture(va("%s_pal", tex->mapname), NULL, 0|IF_NEAREST); if (!TEXVALID(tex->paletted))
// if (!TEXVALID(tex->paletted)) tex->paletted = R_LoadHiResTexture(va("%s", imagename), subpath, ((*imagename=='{')?0:IF_NOALPHA)|IF_NEAREST|IF_PALETTIZE);
// tex->paletted = R_LoadHiResTexture(va("%s_pal", imagename), subpath, ((*imagename=='{')?0:IF_NOALPHA)|IF_NEAREST);
} }
imageflags |= IF_LOWPRIORITY; imageflags |= IF_LOWPRIORITY;
@ -5229,6 +5240,16 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
if (Shader_ParseShader("defaultwall", s)) if (Shader_ParseShader("defaultwall", s))
return; 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) if (!builtin && r_lightmap.ival)
builtin = ( builtin = (
"{\n" "{\n"
@ -5605,17 +5626,6 @@ void Shader_DefaultBSPQ2(const char *shortname, shader_t *s, const void *args)
"}\n" "}\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 else
Shader_DefaultBSPLM(shortname, s, args); 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) if (builtin)
Shader_DefaultScript(shortname, s, builtin); Shader_DefaultScript(shortname, s, builtin);
else else
@ -5843,6 +5840,20 @@ void Shader_DefaultSkin(const char *shortname, shader_t *s, const void *args)
if (Shader_ParseShader("defaultskin", s)) if (Shader_ParseShader("defaultskin", s))
return; 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, Shader_DefaultScript(shortname, s,
"{\n" "{\n"
"if $lpp\n" "if $lpp\n"

View file

@ -3435,7 +3435,7 @@ void Sh_PreGenerateLights(void)
if (!okay) if (!okay)
okay |= R_LoadRTLights(); okay |= R_LoadRTLights();
if (!okay) 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) if (!okay && r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value != 1)
{ {
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 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); void R_ReloadRTLights_f(void);
qboolean R_LoadRTLights(void); qboolean R_LoadRTLights(void);
qboolean R_ImportRTLights(char *entlump); qboolean R_ImportRTLights(const char *entlump);
void R_SaveRTLights_f(void); void R_SaveRTLights_f(void);
//doom //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; ctx->models[ctx->nummodels++] = model;
return ctx; 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 #define DEFAULTLIGHTLEVEL 300
mentity_t *mapent; mentity_t *mapent;

View file

@ -4482,6 +4482,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#endif #endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall", {QR_OPENGL, 110, "defaultwall",
"!!ver 110 130\n"
"!!permu DELUXE\n" "!!permu DELUXE\n"
"!!permu FULLBRIGHT\n" "!!permu FULLBRIGHT\n"
"!!permu FOG\n" "!!permu FOG\n"
@ -4494,6 +4495,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/defs.h\"\n" "#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 //this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead. //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. //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. //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. //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" "#define lm0 lmcoord0\n"
"#endif\n" "#endif\n"
@ -4675,6 +4688,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"}\n" "}\n"
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef VKQUAKE #ifdef VKQUAKE

View file

@ -179,7 +179,7 @@ typedef struct botlib_import_s
//check if the point is in potential visible sight //check if the point is in potential visible sight
int (QDECL *inPVS)(vec3_t p1, vec3_t p2); int (QDECL *inPVS)(vec3_t p1, vec3_t p2);
//retrieve the BSP entity data lump //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); void (QDECL *BSPModelMinsMaxsOrigin)(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
//send a bot client command //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; extern cvar_t allow_download_refpackages;
func_t f; func_t f;
char *file; const char *file;
extern cvar_t pr_maxedicts; extern cvar_t pr_maxedicts;
gametype_e newgametype; gametype_e newgametype;
@ -1451,7 +1451,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
else else
Info_SetValueForStarKey(svs.info, "*entfile", "", MAX_SERVERINFO_STRING); Info_SetValueForStarKey(svs.info, "*entfile", "", MAX_SERVERINFO_STRING);
file = sv.world.worldmodel->entities; file = Mod_GetEntitiesString(sv.world.worldmodel);
if (!file) if (!file)
file = ""; file = "";

View file

@ -80,7 +80,7 @@ void SVQ3_CreateBaseline(void);
void SVQ3_ClientThink(client_t *cl); void SVQ3_ClientThink(client_t *cl);
void SVQ3Q1_ConvertEntStateQ1ToQ3(entity_state_t *q1, q3entityState_t *q3); void SVQ3Q1_ConvertEntStateQ1ToQ3(entity_state_t *q1, q3entityState_t *q3);
char *mapentspointer; const char *mapentspointer;
#define Q3SOLID_BMODEL 0xffffff #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 { // on success, apparently returns 0
return VM_FSeek((int)f, offset, seektype, Z_TAG_BOTLIB)?0:-1; 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) 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); SVQ3_SetConfigString(1, sysinfo);
mapentspointer = sv.world.worldmodel->entities; mapentspointer = Mod_GetEntitiesString(sv.world.worldmodel);
VM_Call(q3gamevm, GAME_INIT, 0, (int)rand(), false); VM_Call(q3gamevm, GAME_INIT, 0, (int)rand(), false);
CM_InitBoxHull(); CM_InitBoxHull();

View file

@ -1,3 +1,4 @@
!!ver 110 130
!!permu DELUXE !!permu DELUXE
!!permu FULLBRIGHT !!permu FULLBRIGHT
!!permu FOG !!permu FOG
@ -10,6 +11,12 @@
#include "sys/defs.h" #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 //this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead. //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. //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. //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. //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 #define lm0 lmcoord0
#endif #endif
@ -191,3 +204,4 @@ void main ()
#endif #endif
} }
#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++) 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; extern cvar_t gl_overbright;
unsigned char s = shaderstate.curbatch?shaderstate.curbatch->lmlightstyle[i]:0; unsigned char s = shaderstate.curbatch?shaderstate.curbatch->lmlightstyle[i]:0;
float sc; float sc;
@ -4321,13 +4321,15 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
} }
break; break;
} }
#else
float sc = 1;
#endif
if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT) if (shaderstate.curentity->model && shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT)
sc = (1<<bound(0, gl_overbright.ival, 2)) * shaderstate.identitylighting; sc = (1<<bound(0, gl_overbright.ival, 2)) * shaderstate.identitylighting;
else else
sc = shaderstate.identitylighting; sc = shaderstate.identitylighting;
sc *= d_lightstylevalue[s]/256.0f; // sc *= d_lightstylevalue[s]/256.0f;
*/
float sc = 1;
Vector4Set(cbe->e_lmscale[i], sc, sc, sc, 1); Vector4Set(cbe->e_lmscale[i], sc, sc, sc, 1);
} }

View file

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