mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
PACKAGEMANAGER is now a compiletime feature in its own right, and can be enabled separately from WEBCLIENT (although won't be able to download without WEBCLIENT).
SAVEDGAMES is now a new compiletime feature. Deathmatch/dedicated servers can freely disable it. menuqc now makes sure that any fields it needs are actually present. developer 1 should now report glsl line numbers a bit more reliably. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5284 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
61c0b9f83b
commit
0b2be8f4ba
21 changed files with 330 additions and 164 deletions
|
@ -3,8 +3,7 @@
|
|||
//FIXME: block downloads of exe/dll/so/etc if not an https url (even if inside zips). also block such files from package lists over http.
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
#define PACKAGEMANAGER
|
||||
#ifdef PACKAGEMANAGER
|
||||
#if !defined(NOBUILTINMENUS) && !defined(SERVERONLY)
|
||||
#define DOWNLOADMENU
|
||||
#endif
|
||||
|
@ -134,7 +133,6 @@ typedef struct package_s {
|
|||
|
||||
struct package_s *alternative; //alternative (hidden) forms of this package.
|
||||
|
||||
unsigned int trymirrors;
|
||||
char *mirror[8]; //FIXME: move to two types of dep...
|
||||
char gamedir[16];
|
||||
enum fs_relative fsroot;
|
||||
|
@ -172,7 +170,10 @@ typedef struct package_s {
|
|||
char name[1];
|
||||
} *deps;
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
struct dl_download *download;
|
||||
unsigned int trymirrors;
|
||||
#endif
|
||||
|
||||
int flags;
|
||||
int priority;
|
||||
|
@ -190,8 +191,12 @@ static int domanifestinstall; //SECURITY_MANIFEST_*
|
|||
#ifdef PLUGINS
|
||||
static qboolean pluginpromptshown; //so we only show prompts for new externally-installed plugins once, instead of every time the file is reloaded.
|
||||
#endif
|
||||
#ifdef WEBCLIENT
|
||||
static qboolean doautoupdate; //updates will be marked (but not applied without the user's actions)
|
||||
static qboolean pkg_updating; //when flagged, further changes are blocked until completion.
|
||||
#else
|
||||
static const qboolean pkg_updating = false;
|
||||
#endif
|
||||
|
||||
//FIXME: these are allocated for the life of the exe. changing basedir should purge the list.
|
||||
static int numdownloadablelists = 0;
|
||||
|
@ -1152,11 +1157,13 @@ void PM_Shutdown(void)
|
|||
{
|
||||
numdownloadablelists--;
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
if (downloadablelist[numdownloadablelists].curdl)
|
||||
{
|
||||
DL_Close(downloadablelist[numdownloadablelists].curdl);
|
||||
downloadablelist[numdownloadablelists].curdl = NULL;
|
||||
}
|
||||
#endif
|
||||
downloadablelist[numdownloadablelists].received = 0;
|
||||
Z_Free(downloadablelist[numdownloadablelists].url);
|
||||
downloadablelist[numdownloadablelists].url = NULL;
|
||||
|
@ -1232,6 +1239,7 @@ static void PM_UnmarkPackage(package_t *package)
|
|||
return; //looks like its already deselected.
|
||||
package->flags &= ~(DPF_MARKED);
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
//Is this safe?
|
||||
package->trymirrors = 0; //if its enqueued, cancel that quickly...
|
||||
if (package->download)
|
||||
|
@ -1239,6 +1247,7 @@ static void PM_UnmarkPackage(package_t *package)
|
|||
DL_Close(package->download);
|
||||
package->download = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//remove stuff that depends on us
|
||||
for (o = availablepackages; o; o = o->next)
|
||||
|
@ -1530,7 +1539,7 @@ static void PM_PrintChanges(void)
|
|||
}
|
||||
|
||||
static void PM_ApplyChanges(void);
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
static void PM_ListDownloaded(struct dl_download *dl)
|
||||
{
|
||||
int i;
|
||||
|
@ -1619,6 +1628,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//retry 1==
|
||||
static void PM_UpdatePackageList(qboolean autoupdate, int retry)
|
||||
{
|
||||
|
@ -1633,6 +1643,10 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
|
|||
if (*pm_downloads_url.string)
|
||||
PM_AddSubList(pm_downloads_url.string, "", true, true);
|
||||
|
||||
#ifndef WEBCLIENT
|
||||
for (i = 0; i < numdownloadablelists; i++)
|
||||
downloadablelist[i].received = true;
|
||||
#else
|
||||
doautoupdate |= autoupdate;
|
||||
|
||||
//kick off the initial tier of list-downloads.
|
||||
|
@ -1673,6 +1687,7 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
|
|||
PM_PrintChanges();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1860,6 +1875,7 @@ static void PM_WriteInstalledPackages(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
//callback from PM_Download_Got, extracts each file from an archive
|
||||
static int QDECL PM_ExtractFiles(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
{ //this is gonna suck. threading would help, but gah.
|
||||
|
@ -2114,6 +2130,7 @@ static char *PM_GetTempName(package_t *p)
|
|||
Z_Free(ts);
|
||||
return Z_StrDup(destname);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*static void PM_AddDownloadedPackage(const char *filename)
|
||||
{
|
||||
|
@ -2143,8 +2160,9 @@ static char *PM_GetTempName(package_t *p)
|
|||
|
||||
int PM_IsApplying(qboolean listsonly)
|
||||
{
|
||||
package_t *p;
|
||||
int count = 0;
|
||||
#ifdef WEBCLIENT
|
||||
package_t *p;
|
||||
int i;
|
||||
if (!listsonly)
|
||||
{
|
||||
|
@ -2159,12 +2177,14 @@ int PM_IsApplying(qboolean listsonly)
|
|||
if (downloadablelist[i].curdl)
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
//looks for the next package that needs downloading, and grabs it
|
||||
static void PM_StartADownload(void)
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
vfsfile_t *tmpfile;
|
||||
char *temp;
|
||||
package_t *p;
|
||||
|
@ -2284,6 +2304,7 @@ static void PM_StartADownload(void)
|
|||
|
||||
//clear the updating flag once there's no more activity needed
|
||||
pkg_updating = downloading;
|
||||
#endif
|
||||
}
|
||||
//'just' starts doing all the things needed to remove/install selected packages
|
||||
static void PM_ApplyChanges(void)
|
||||
|
@ -2291,17 +2312,22 @@ static void PM_ApplyChanges(void)
|
|||
package_t *p, **link;
|
||||
char temp[MAX_OSPATH];
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
if (pkg_updating)
|
||||
return;
|
||||
pkg_updating = true;
|
||||
#endif
|
||||
|
||||
//delete any that don't exist
|
||||
for (link = &availablepackages; *link ; )
|
||||
{
|
||||
p = *link;
|
||||
#ifdef WEBCLIENT
|
||||
if (p->download)
|
||||
; //erk, dude, don't do two!
|
||||
else if ((p->flags & DPF_PURGE) || (!(p->flags&DPF_MARKED) && (p->flags&DPF_ENABLED)))
|
||||
else
|
||||
#endif
|
||||
if ((p->flags & DPF_PURGE) || (!(p->flags&DPF_MARKED) && (p->flags&DPF_ENABLED)))
|
||||
{ //if we don't want it but we have it anyway. don't bother to follow this logic when reinstalling
|
||||
qboolean reloadpacks = false;
|
||||
struct packagedep_s *dep;
|
||||
|
@ -2416,12 +2442,14 @@ static void PM_ApplyChanges(void)
|
|||
link = &(*link)->next;
|
||||
}
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
//and flag any new/updated ones for a download
|
||||
for (p = availablepackages; p ; p=p->next)
|
||||
{
|
||||
if ((p->flags&DPF_MARKED) && !(p->flags&DPF_ENABLED) && !p->download)
|
||||
p->trymirrors = ~0u;
|
||||
}
|
||||
#endif
|
||||
PM_StartADownload(); //and try to do those downloads.
|
||||
}
|
||||
|
||||
|
@ -2496,14 +2524,18 @@ static qboolean PM_DeclinedPackages(char *out, size_t outsize)
|
|||
}
|
||||
static void PM_PromptApplyChanges_Callback(void *ctx, int opt)
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
pkg_updating = false;
|
||||
#endif
|
||||
if (opt == 0)
|
||||
PM_ApplyChanges();
|
||||
}
|
||||
static void PM_PromptApplyChanges(void);
|
||||
static void PM_PromptApplyDecline_Callback(void *ctx, int opt)
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
pkg_updating = false;
|
||||
#endif
|
||||
if (opt == 1)
|
||||
{
|
||||
PM_DeclinedPackages(NULL, 0);
|
||||
|
@ -2514,6 +2546,7 @@ static void PM_PromptApplyChanges(void)
|
|||
{
|
||||
unsigned int changes;
|
||||
char text[8192];
|
||||
#ifdef WEBCLIENT
|
||||
//lock it down, so noone can make any changes while this prompt is still displayed
|
||||
if (pkg_updating)
|
||||
{
|
||||
|
@ -2521,6 +2554,7 @@ static void PM_PromptApplyChanges(void)
|
|||
return;
|
||||
}
|
||||
pkg_updating = true;
|
||||
#endif
|
||||
|
||||
strcpy(text, "Really decline the following\nrecommendedpackages?\n\n");
|
||||
if (PM_DeclinedPackages(text+strlen(text), sizeof(text)-strlen(text)))
|
||||
|
@ -2530,7 +2564,11 @@ static void PM_PromptApplyChanges(void)
|
|||
strcpy(text, "Apply the following changes?\n\n");
|
||||
changes = PM_ChangeList(text+strlen(text), sizeof(text)-strlen(text));
|
||||
if (!changes)
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
pkg_updating = false;//no changes...
|
||||
#endif
|
||||
}
|
||||
else
|
||||
M_Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel");
|
||||
}
|
||||
|
@ -2903,11 +2941,13 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
|
|||
if (p->alternative && (p->flags & DPF_HIDDEN))
|
||||
p = p->alternative;
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
if (p->download)
|
||||
Draw_FunString (x+4, y, va("%i", (int)p->download->qdownload.percent));
|
||||
else if (p->trymirrors)
|
||||
Draw_FunString (x+4, y, "PND");
|
||||
else
|
||||
else
|
||||
#endif
|
||||
{
|
||||
switch((p->flags & (DPF_ENABLED | DPF_MARKED)))
|
||||
{
|
||||
|
@ -3055,14 +3095,17 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef WEBCLIENT
|
||||
else
|
||||
p->trymirrors = 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m)
|
||||
{
|
||||
char *settings[] =
|
||||
|
@ -3094,6 +3137,17 @@ static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct menu_s *m, int
|
|||
return false;
|
||||
}
|
||||
|
||||
static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct menu_s *m,int key)
|
||||
{
|
||||
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
|
||||
{
|
||||
PM_MarkUpdates();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
qboolean MD_PopMenu (union menuoption_s *mo,struct menu_s *m,int key)
|
||||
{
|
||||
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
|
||||
|
@ -3114,15 +3168,6 @@ static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct menu_s *m,int k
|
|||
return false;
|
||||
}
|
||||
|
||||
static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct menu_s *m,int key)
|
||||
{
|
||||
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
|
||||
{
|
||||
PM_MarkUpdates();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static qboolean MD_RevertUpdates (union menuoption_s *mo,struct menu_s *m,int key)
|
||||
{
|
||||
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1)
|
||||
|
@ -3154,20 +3199,22 @@ static void MD_AddItemsToDownloadMenu(menu_t *m)
|
|||
y+=8;
|
||||
if (!prefixlen)
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
MC_AddCommand(m, 0, 170, y, "Mark Updates", MD_MarkUpdatesButton);
|
||||
y+=8;
|
||||
#endif
|
||||
|
||||
MC_AddCommand(m, 0, 170, y, "Revert Updates", MD_RevertUpdates);
|
||||
y+=8;
|
||||
}
|
||||
if (!prefixlen)
|
||||
{
|
||||
|
||||
#ifdef WEBCLIENT
|
||||
c = MC_AddCustom(m, 0, y, p, 0);
|
||||
c->draw = MD_AutoUpdate_Draw;
|
||||
c->key = MD_AutoUpdate_Key;
|
||||
c->common.width = 320;
|
||||
c->common.height = 8;
|
||||
y += 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
y+=4; //small gap
|
||||
|
|
|
@ -187,9 +187,6 @@ qboolean M_Options_InvertMouse (menucheck_t *option, struct menu_s *menu, chk_se
|
|||
void M_Menu_Options_f (void)
|
||||
{
|
||||
extern cvar_t crosshair, r_projection;
|
||||
#ifndef CLIENTONLY
|
||||
extern cvar_t sv_autosave;
|
||||
#endif
|
||||
int y;
|
||||
|
||||
static const char *projections[] = {
|
||||
|
@ -211,7 +208,8 @@ void M_Menu_Options_f (void)
|
|||
NULL
|
||||
};
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||
extern cvar_t sv_autosave;
|
||||
static const char *autosaveopts[] = {
|
||||
"Off",
|
||||
"30 secs",
|
||||
|
@ -234,8 +232,8 @@ void M_Menu_Options_f (void)
|
|||
|
||||
menubulk_t bulk[] = {
|
||||
MB_CONSOLECMD("Customize controls", "menu_keys\n", "Modify keyboard and mouse inputs."),
|
||||
#ifdef WEBCLIENT
|
||||
MB_CONSOLECMD("Updates and packages", "menu_download\n", "Modify keyboard and mouse inputs."),
|
||||
#ifdef PACKAGEMANAGER
|
||||
MB_CONSOLECMD("Updates and Packages", "menu_download\n", "Configure additional content and plugins."),
|
||||
#endif
|
||||
MB_CONSOLECMD("Go to console", "toggleconsole\nplay misc/menu2.wav\n", "Open up the engine console."),
|
||||
MB_CONSOLECMD("Reset to defaults", "cvarreset *\nexec default.cfg\nplay misc/menu2.wav\n", "Reloads the default configuration."),
|
||||
|
@ -250,7 +248,7 @@ void M_Menu_Options_f (void)
|
|||
MB_CHECKBOXCVAR("Lookspring", lookspring, 0),
|
||||
MB_CHECKBOXCVAR("Lookstrafe", lookstrafe, 0),
|
||||
MB_CHECKBOXCVAR("Windowed Mouse", _windowed_mouse, 0),
|
||||
#ifndef CLIENTONLY
|
||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||
MB_COMBOCVAR("Auto Save", sv_autosave, autosaveopts, autosavevals, NULL),
|
||||
#endif
|
||||
MB_SPACING(4),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "winquake.h"
|
||||
#include "shader.h"
|
||||
#ifndef NOBUILTINMENUS
|
||||
#ifndef CLIENTONLY
|
||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||
//=============================================================================
|
||||
/* LOAD/SAVE MENU */
|
||||
|
||||
|
@ -329,10 +329,10 @@ void M_Menu_SinglePlayer_f (void)
|
|||
MC_AddConsoleCommand (menu, 64, 170, 40, "Easy", va("closemenu; skill 0;deathmatch 0; coop %i;newgame\n", cl_splitscreen.ival>0));
|
||||
MC_AddConsoleCommand (menu, 64, 170, 48, "Medium", va("closemenu; skill 1;deathmatch 0; coop %i;newgame\n", cl_splitscreen.ival>0));
|
||||
MC_AddConsoleCommand (menu, 64, 170, 56, "Hard", va("closemenu; skill 2;deathmatch 0; coop %i;newgame\n", cl_splitscreen.ival>0));
|
||||
|
||||
#ifdef SAVEDGAMES
|
||||
MC_AddConsoleCommand (menu, 64, 170, 72, "Load Game", "menu_load\n");
|
||||
MC_AddConsoleCommand (menu, 64, 170, 80, "Save Game", "menu_save\n");
|
||||
|
||||
#endif
|
||||
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 48, 0, 40, NULL, false);
|
||||
return;
|
||||
#endif
|
||||
|
@ -455,8 +455,10 @@ void M_Menu_SinglePlayer_f (void)
|
|||
menu->selecteditem = (menuoption_t*)
|
||||
MC_AddConsoleCommandHexen2BigFont(menu, 80, y+=20, "New Game", "menu_single class demo1\n");
|
||||
}
|
||||
#ifdef SAVEDGAMES
|
||||
MC_AddConsoleCommandHexen2BigFont(menu, 80, y+=20, "Save Game", "menu_save\n");
|
||||
MC_AddConsoleCommandHexen2BigFont(menu, 80, y+=20, "Load Game", "menu_load\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
menu->cursoritem = (menuoption_t *)MC_AddCursor(menu, &resel, 56, menu->selecteditem?menu->selecteditem->common.posy:0);
|
||||
|
@ -474,8 +476,10 @@ void M_Menu_SinglePlayer_f (void)
|
|||
|
||||
menu->selecteditem = (menuoption_t*)
|
||||
MC_AddConsoleCommandQBigFont (menu, 72, 32, "New Game", "closemenu;disconnect;maxclients 1;samelevel \"\";deathmatch \"\";set_calc coop ($cl_splitscreen>0);startmap_sp\n");
|
||||
#ifdef SAVEDGAMES
|
||||
MC_AddConsoleCommandQBigFont (menu, 72, 52, "Load Game", "menu_load\n");
|
||||
MC_AddConsoleCommandQBigFont (menu, 72, 72, "Save Game", "menu_save\n");
|
||||
#endif
|
||||
|
||||
menu->cursoritem = (menuoption_t*)MC_AddCursor(menu, &resel, 54, 32);
|
||||
return;
|
||||
|
@ -525,12 +529,14 @@ void M_Menu_SinglePlayer_f (void)
|
|||
menu->selecteditem = (menuoption_t *)b;
|
||||
b->common.width = width;
|
||||
b->common.height = 20;
|
||||
#ifdef SAVEDGAMES
|
||||
b = MC_AddConsoleCommand (menu, 72, 304, 52, "", "menu_load\n");
|
||||
b->common.width = width;
|
||||
b->common.height = 20;
|
||||
b = MC_AddConsoleCommand (menu, 72, 304, 72, "", "menu_save\n");
|
||||
b->common.width = width;
|
||||
b->common.height = 20;
|
||||
#endif
|
||||
|
||||
#if MAX_SPLITS > 1
|
||||
b = (menubutton_t*)MC_AddCvarCombo(menu, 72, 72+width/2, 92, "", &cl_splitscreen, opts, vals);
|
||||
|
|
|
@ -1222,7 +1222,7 @@ void M_Init_Internal (void)
|
|||
return;
|
||||
internalmenusregistered = true;
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||
Cmd_AddCommand ("menu_save", M_Menu_Save_f);
|
||||
Cmd_AddCommand ("menu_load", M_Menu_Load_f);
|
||||
Cmd_AddCommand ("menu_loadgame", M_Menu_Load_f); //q2...
|
||||
|
@ -1371,7 +1371,7 @@ void M_Init (void)
|
|||
Cmd_AddCommand ("menu_servers", M_Menu_ServerList2_f);
|
||||
#endif
|
||||
//downloads menu needs sandboxing, so cannot be provided by qc.
|
||||
#ifdef WEBCLIENT
|
||||
#ifdef PACKAGEMANAGER
|
||||
Cmd_AddCommand ("menu_download", Menu_DownloadStuff_f);
|
||||
#endif
|
||||
//demo menu is allowed to see outside of the quakedir. you can't replicate that in qc's sandbox.
|
||||
|
|
|
@ -1817,6 +1817,8 @@ static void QCBUILTIN PF_m_setmodel(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
model_t *mod = Mod_ForName(modelname, MLV_WARN);
|
||||
if (modelval)
|
||||
modelval->string = G_INT(OFS_PARM1); //lets hope garbage collection is enough.
|
||||
else
|
||||
Con_Printf("PF_m_setmodel: no model field!\n");
|
||||
|
||||
if (mod)
|
||||
while(mod->loadstate == MLS_LOADING)
|
||||
|
@ -1834,7 +1836,10 @@ static void QCBUILTIN PF_m_setcustomskin(pubprogfuncs_t *prinst, struct globalva
|
|||
const char *skindata = PF_VarString(prinst, 2, pr_globals);
|
||||
eval_t *val = prinst->GetEdictFieldValue(prinst, (void*)ent, "skinobject", ev_string, &menuc_eval.skinobject);
|
||||
if (!val)
|
||||
{
|
||||
Con_Printf("PF_m_setcustomskin: no skinobject field!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val->_float > 0)
|
||||
{
|
||||
|
@ -1858,6 +1863,8 @@ static void QCBUILTIN PF_m_setorigin(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
eval_t *val = prinst->GetEdictFieldValue(prinst, (void*)ent, "origin", ev_vector, &menuc_eval.origin);
|
||||
if (val)
|
||||
VectorCopy(org, val->_vector);
|
||||
else
|
||||
Con_Printf("PF_m_setorigin: no origin field!\n");
|
||||
}
|
||||
static void QCBUILTIN PF_m_clearscene(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -2645,6 +2652,12 @@ qboolean MP_Init (void)
|
|||
|
||||
PR_ProgsAdded(menu_world.progs, mprogs, "menu.dat");
|
||||
|
||||
//ensure that there's space for these fields in.
|
||||
//other fields will always be referenced/defined by the qc, or 0.
|
||||
PR_RegisterFieldVar(menu_world.progs, ev_string, "model", -1, -1);
|
||||
PR_RegisterFieldVar(menu_world.progs, ev_vector, "origin", -1, -1);
|
||||
PR_RegisterFieldVar(menu_world.progs, ev_float, "skinobject", -1, -1);
|
||||
|
||||
menuentsize = PR_InitEnts(menu_world.progs, 8192);
|
||||
|
||||
|
||||
|
|
|
@ -1453,7 +1453,7 @@ void V_ClearRefdef(playerview_t *pv)
|
|||
r_refdef.fovv_x = 0;
|
||||
r_refdef.fovv_y = 0;
|
||||
|
||||
r_refdef.drawsbar = cl.intermissionmode == IM_NONE;
|
||||
r_refdef.drawsbar = (cl.intermissionmode == IM_NONE);
|
||||
r_refdef.flags = 0;
|
||||
|
||||
r_refdef.areabitsknown = false;
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
#define SUBSERVERS //Allows the server to fork itself, each acting as an MMO-style server instance of a single 'realm'.
|
||||
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
#define SAVEDGAMES //Can save the game.
|
||||
|
||||
// Networking options
|
||||
#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||
|
@ -124,6 +125,7 @@
|
|||
//#define IRCCONNECT //lame support for routing game packets via irc server. not a good idea.
|
||||
#define SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections.
|
||||
#define CL_MASTER //Clientside Server Browser functionality.
|
||||
#define PACKAGEMANAGER //Allows the user to enable/disable/download(with WEBCLIENT) packages and plugins.
|
||||
|
||||
// Audio Drivers
|
||||
#define AVAIL_OPENAL
|
||||
|
|
|
@ -113,6 +113,7 @@
|
|||
//#define SUBSERVERS //Allows the server to fork itself, each acting as an MMO-style server instance of a single 'realm'.
|
||||
////#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
////#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
//#define SAVEDGAMES //Can save the game.
|
||||
|
||||
// Networking options
|
||||
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||
|
@ -126,6 +127,7 @@
|
|||
//#define IRCCONNECT //lame support for routing game packets via irc server. not a good idea.
|
||||
//#define SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections.
|
||||
//#define CL_MASTER //Clientside Server Browser functionality.
|
||||
//#define PACKAGEMANAGER //Allows the user to enable/disable/download packages and plugins.
|
||||
|
||||
// Audio Drivers
|
||||
//#define AVAIL_OPENAL
|
||||
|
|
|
@ -110,6 +110,7 @@
|
|||
//#define SUBSERVERS //Allows the server to fork itself, each acting as an MMO-style server instance of a single 'realm'.
|
||||
//#define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
//#define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
#define SAVEDGAMES //Can save the game.
|
||||
|
||||
// Networking options
|
||||
//#define NQPROT //act as an nq client/server, with nq gamecode.
|
||||
|
@ -123,6 +124,7 @@
|
|||
//#define IRCCONNECT //lame support for routing game packets via irc server. not a good idea.
|
||||
#define SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections.
|
||||
#define CL_MASTER //Clientside Server Browser functionality.
|
||||
//#define PACKAGEMANAGER //Allows the user to enable/disable/download packages and plugins.
|
||||
|
||||
// Audio Drivers
|
||||
#define AVAIL_OPENAL
|
||||
|
|
|
@ -163,6 +163,8 @@
|
|||
#undef HAVE_MEDIA_DECODER //can play cin/roq, more with plugins
|
||||
#undef HAVE_MEDIA_ENCODER //capture/capturedemo work.
|
||||
#undef HAVE_SPEECHTOTEXT //windows speech-to-text thing
|
||||
//#define SAVEDGAMES //Can save the game.
|
||||
#undef PACKAGEMANAGER //Allows the user to enable/disable/download packages and plugins.
|
||||
|
||||
#ifdef COMPILE_OPTS
|
||||
//things to configure qclib, which annoyingly doesn't include this file itself
|
||||
|
|
|
@ -2242,6 +2242,11 @@ bspx_header_t *BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lu
|
|||
return h;
|
||||
}
|
||||
|
||||
#ifdef SERVERONLY
|
||||
void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base)
|
||||
{
|
||||
}
|
||||
#else
|
||||
/*
|
||||
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt);
|
||||
void BSPX_RenderEnvmaps(model_t *mod)
|
||||
|
@ -2408,9 +2413,6 @@ void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1//ndef SERVERONLY
|
||||
|
||||
struct bspxrw
|
||||
{
|
||||
fromgame_t fg;
|
||||
|
@ -2632,7 +2634,13 @@ unsigned int Mod_NearestCubeForSurf(msurface_t *surf, denvmap_t *envmap, size_t
|
|||
for (n = 0; n < nenvmap; n++)
|
||||
{
|
||||
VectorSubtract(mid, envmap[n].origin, diff);
|
||||
#if 1
|
||||
//axial distance
|
||||
dist = min(min(fabs(diff[0]), fabs(diff[1])), fabs(diff[2]));
|
||||
#else
|
||||
//radial distance (squared)
|
||||
dist = DotProduct(diff,diff);
|
||||
#endif
|
||||
if (bestdist > dist)
|
||||
{
|
||||
best = n;
|
||||
|
|
|
@ -736,10 +736,12 @@ void Mod_Purge(enum mod_purge_e ptype)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
void Mod_FindCubemaps_f(void);
|
||||
void Mod_Realign_f(void);
|
||||
void Mod_BSPX_List_f(void);
|
||||
void Mod_BSPX_Strip_f(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -777,10 +779,12 @@ void Mod_Init (qboolean initial)
|
|||
Cmd_AddCommand("sv_saveentfile", Mod_SaveEntFile_f);
|
||||
Cmd_AddCommand("version_modelformats", Mod_PrintFormats_f);
|
||||
|
||||
#ifndef SERVERONLY
|
||||
Cmd_AddCommandD("map_findcubemaps", Mod_FindCubemaps_f, "Scans the entities of a map to find reflection envmap sites and determines the nearest one to each surface.");
|
||||
Cmd_AddCommandD("map_realign", Mod_Realign_f, "Reads the named bsp and writes it back out with only alignment changes.");
|
||||
Cmd_AddCommandD("map_bspx_list", Mod_BSPX_List_f, "Lists all lumps (and their sizes) in the specified bsp.");
|
||||
Cmd_AddCommandD("map_bspx_strip", Mod_BSPX_Strip_f, "Strips a named extension lump from a bsp file.");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (initial)
|
||||
|
|
|
@ -1877,26 +1877,74 @@ static const char *glsl_hdrs[] =
|
|||
NULL
|
||||
};
|
||||
|
||||
qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *prstrings[], GLint length[], const char *shadersource)
|
||||
#define GLSLPARTS (64+16)
|
||||
struct glslparts_s
|
||||
{
|
||||
const GLchar *str[GLSLPARTS];
|
||||
GLint len[GLSLPARTS];
|
||||
const GLchar *file[GLSLPARTS];
|
||||
int line[GLSLPARTS];
|
||||
int strings;
|
||||
|
||||
const char *error;
|
||||
};
|
||||
|
||||
static void GLSlang_GenerateInternal(struct glslparts_s *glsl, const char *shadersource)
|
||||
{
|
||||
if (glsl->strings == GLSLPARTS)
|
||||
{
|
||||
glsl->error = "Too many parts";
|
||||
return;
|
||||
}
|
||||
glsl->str[glsl->strings] = shadersource;
|
||||
glsl->len[glsl->strings] = strlen(shadersource);
|
||||
glsl->file[glsl->strings] = NULL;
|
||||
glsl->line[glsl->strings] = 0;
|
||||
glsl->strings += 1;
|
||||
}
|
||||
|
||||
static void GLSlang_Generate(struct glslparts_s *glsl, const char *shadersource, GLint length, const char *filename, int linenumber)
|
||||
{
|
||||
if (glsl->strings == GLSLPARTS)
|
||||
{
|
||||
glsl->error = "Too many parts";
|
||||
return;
|
||||
}
|
||||
glsl->str[glsl->strings] = shadersource;
|
||||
glsl->len[glsl->strings] = length;
|
||||
glsl->file[glsl->strings] = filename;
|
||||
glsl->line[glsl->strings] = linenumber;
|
||||
glsl->strings += 1;
|
||||
}
|
||||
|
||||
static qboolean GLSlang_GenerateIncludes(struct glslparts_s *glsl, const char *shadersource, const char *filename, int linenumber)
|
||||
{
|
||||
int i;
|
||||
char *incline, *inc;
|
||||
char incname[256];
|
||||
while((incline=strstr(shadersource, "#include")))
|
||||
{
|
||||
if (*strings == maxstrings)
|
||||
return false;
|
||||
|
||||
/*emit up to the include*/
|
||||
if (incline - shadersource)
|
||||
{
|
||||
prstrings[*strings] = shadersource;
|
||||
length[*strings] = incline - shadersource;
|
||||
*strings += 1;
|
||||
char *e = incline;
|
||||
while(e > shadersource && (e[-1] == ' ' || e[-1] == '\t'))
|
||||
e--;
|
||||
if (e > shadersource && e[-1] == '\n')
|
||||
GLSlang_Generate(glsl, shadersource, e-shadersource, filename, linenumber);
|
||||
else
|
||||
GLSlang_Generate(glsl, shadersource, incline-shadersource, filename, linenumber);
|
||||
}
|
||||
|
||||
incline += 8;
|
||||
incline = COM_ParseOut (incline, incname, sizeof(incname));
|
||||
if (!incline)
|
||||
{
|
||||
glsl->error = "missing include name";
|
||||
return false;
|
||||
}
|
||||
while (*incline == ' ' || *incline == '\t')
|
||||
incline++;
|
||||
|
||||
if (!strncmp(incname, "cvar/", 5))
|
||||
{
|
||||
|
@ -1904,17 +1952,13 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
|
|||
if (var)
|
||||
{
|
||||
var->flags |= CVAR_SHADERSYSTEM;
|
||||
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, var->string))
|
||||
if (!GLSlang_GenerateIncludes(glsl, var->string, NULL, 0))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*dump something if the cvar doesn't exist*/
|
||||
if (*strings == maxstrings)
|
||||
return false;
|
||||
prstrings[*strings] = "0";
|
||||
length[*strings] = strlen("0");
|
||||
*strings += 1;
|
||||
GLSlang_Generate(glsl, "0", strlen("0"), filename, linenumber);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1923,38 +1967,39 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
|
|||
{
|
||||
if (!strcmp(incname, glsl_hdrs[i]))
|
||||
{
|
||||
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, glsl_hdrs[i+1]))
|
||||
if (!GLSlang_GenerateIncludes(glsl, glsl_hdrs[i+1], glsl_hdrs[i], 1))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!glsl_hdrs[i])
|
||||
{
|
||||
if (FS_LoadFile(incname, (void**)&inc) != (qofs_t)-1)
|
||||
size_t sz;
|
||||
inc = COM_LoadTempMoreFile(incname, &sz);
|
||||
if (inc)
|
||||
{
|
||||
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, inc))
|
||||
{
|
||||
FS_FreeFile(inc);
|
||||
if (!GLSlang_GenerateIncludes(glsl, inc, NULL, 1))
|
||||
return false;
|
||||
}
|
||||
FS_FreeFile(inc);
|
||||
}
|
||||
else
|
||||
{
|
||||
glsl->error = "include file not found";
|
||||
return false; //FIXME: add a warning
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*move the pointer past the include*/
|
||||
shadersource = incline;
|
||||
while (shadersource < incline)
|
||||
{
|
||||
if (*shadersource == '\n')
|
||||
linenumber++;
|
||||
shadersource++;
|
||||
}
|
||||
}
|
||||
if (*shadersource)
|
||||
{
|
||||
if (*strings == maxstrings)
|
||||
return false;
|
||||
|
||||
/*dump the remaining shader string*/
|
||||
prstrings[*strings] = shadersource;
|
||||
length[*strings] = strlen(prstrings[*strings]);
|
||||
*strings += 1;
|
||||
}
|
||||
if (*shadersource)
|
||||
GLSlang_Generate(glsl, shadersource, strlen(shadersource), filename, linenumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1965,11 +2010,12 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
{
|
||||
GLhandleARB shader;
|
||||
int i;
|
||||
const GLchar *prstrings[64+16];
|
||||
GLint length[sizeof(prstrings)/sizeof(prstrings[0])];
|
||||
int strings = 0;
|
||||
struct glslparts_s glsl;
|
||||
char verline[64];
|
||||
|
||||
glsl.strings = 0;
|
||||
glsl.error = NULL;
|
||||
|
||||
if (!shadersource)
|
||||
return 0;
|
||||
|
||||
|
@ -2013,44 +2059,32 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
Q_snprintfz(verline, sizeof(verline), "#version %u compatibility\n", ver);
|
||||
else
|
||||
Q_snprintfz(verline, sizeof(verline), "#version %u\n", ver); //core assumed, where defined
|
||||
prstrings[strings] = verline;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, verline);
|
||||
}
|
||||
}
|
||||
|
||||
while(*precompilerconstants)
|
||||
{
|
||||
prstrings[strings] = *precompilerconstants++;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
}
|
||||
GLSlang_GenerateInternal(&glsl, *precompilerconstants++);
|
||||
|
||||
prstrings[strings] = "#define ENGINE_"DISTRIBUTION"\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "#define ENGINE_"DISTRIBUTION"\n");
|
||||
|
||||
switch (shadertype)
|
||||
{
|
||||
case GL_FRAGMENT_SHADER_ARB:
|
||||
prstrings[strings] = "#define FRAGMENT_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "#define FRAGMENT_SHADER\n");
|
||||
if (gl_config.gles)
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
"#else\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
if (ver >= 130)
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
//gl3+ deprecated the some things. these are removed in forwards-compatible / core contexts.
|
||||
//varying became either in or out, which is important if you have geometry shaders...
|
||||
"#define varying in\n"
|
||||
|
@ -2071,20 +2105,16 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
"out vec4 fte_fragdata3;"
|
||||
"\n#endif\n" //gles3 requires this
|
||||
"#define gl_FragColor fte_fragdata0\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#define fte_fragdata0 gl_FragData[0]\n"
|
||||
"#define fte_fragdata1 gl_FragData[1]\n"
|
||||
"#define fte_fragdata2 gl_FragData[2]\n"
|
||||
"#define fte_fragdata3 gl_FragData[3]\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
|
||||
if (prog)
|
||||
|
@ -2127,82 +2157,62 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
for (i = 0; i < countof(defaultsamplernames); i++)
|
||||
{
|
||||
if (prog->defaulttextures & (1u<<i))
|
||||
{
|
||||
prstrings[strings] = defaultsamplernames[i];
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
}
|
||||
GLSlang_GenerateInternal(&glsl, defaultsamplernames[i]);
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < prog->numsamplers && i < countof(numberedsamplernames); i++)
|
||||
{
|
||||
prstrings[strings] = numberedsamplernames[i];
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
}
|
||||
GLSlang_GenerateInternal(&glsl, numberedsamplernames[i]);
|
||||
}
|
||||
break;
|
||||
case GL_GEOMETRY_SHADER_ARB:
|
||||
prstrings[strings] = "#define GEOMETRY_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "#define GEOMETRY_SHADER\n");
|
||||
break;
|
||||
case GL_TESS_CONTROL_SHADER_ARB:
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#define TESS_CONTROL_SHADER\n"
|
||||
"#if __VERSION__ < 400\n"
|
||||
"#extension GL_ARB_tessellation_shader : enable\n"
|
||||
"#endif\n";
|
||||
"#endif\n"
|
||||
//varyings are arrays, so don't bother defining that here.
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
break;
|
||||
case GL_TESS_EVALUATION_SHADER_ARB:
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#define TESS_EVALUATION_SHADER\n"
|
||||
"#if __VERSION__ < 400\n"
|
||||
"#extension GL_ARB_tessellation_shader : enable\n"
|
||||
"#endif\n"
|
||||
"#define varying out\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
"#define varying out\n"
|
||||
);
|
||||
break;
|
||||
case GL_VERTEX_SHADER_ARB:
|
||||
prstrings[strings] = "#define VERTEX_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "#define VERTEX_SHADER\n");
|
||||
#ifdef RTLIGHTS
|
||||
if (!r_shadow_shadowmapping.ival && ver >= 120)
|
||||
{
|
||||
prstrings[strings] = "invariant gl_Position;\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "invariant gl_Position;\n");
|
||||
}
|
||||
#endif
|
||||
if (gl_config.gles)
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
"#else\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
if (ver >= 130)
|
||||
{
|
||||
prstrings[strings] =
|
||||
"#define attribute in\n"
|
||||
"#define varying out\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#define attribute in\n"
|
||||
"#define varying out\n"
|
||||
);
|
||||
}
|
||||
if (gl_config_nofixedfunc)
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"attribute vec3 v_position1;\n"
|
||||
"#ifdef FRAMEBLEND\n"
|
||||
"attribute vec3 v_position2;\n"
|
||||
|
@ -2218,13 +2228,11 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
#else
|
||||
"#define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0))\n"
|
||||
#endif
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
prstrings[strings] =
|
||||
GLSlang_GenerateInternal(&glsl,
|
||||
"#ifdef FRAMEBLEND\n"
|
||||
"attribute vec3 v_position2;\n"
|
||||
"uniform vec2 e_vblend;\n"
|
||||
|
@ -2236,24 +2244,51 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
"uniform mat4 m_modelviewprojection;\n"
|
||||
"#define ftetransform ftransform\n"
|
||||
"#endif\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
prstrings[strings] = "#define UNKNOWN_SHADER\n";
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
GLSlang_GenerateInternal(&glsl, "#define UNKNOWN_SHADER\n");
|
||||
break;
|
||||
}
|
||||
|
||||
GLSlang_GenerateIncludes(sizeof(prstrings)/sizeof(prstrings[0]), &strings, prstrings, length, shadersource);
|
||||
GLSlang_GenerateIncludes(&glsl, shadersource, name, 1);
|
||||
|
||||
shader = qglCreateShaderObjectARB(shadertype);
|
||||
|
||||
if (gl_workaround_ati_shadersource.ival)
|
||||
if (developer.ival)
|
||||
{
|
||||
GLcharARB *combined;
|
||||
int totallen = 1;
|
||||
for (i = 0; i < glsl.strings; i++)
|
||||
totallen += glsl.len[i] + 64;
|
||||
combined = malloc(totallen);
|
||||
totallen = 0;
|
||||
combined[totallen] = 0;
|
||||
for (i = 0; i < glsl.strings; i++)
|
||||
{
|
||||
if (ver && !i)
|
||||
; //#version MUST be the first line, don't prefix it with a #line, it'll just break things.
|
||||
else if (!totallen || combined[totallen-1] == '\n')
|
||||
{ //last line was a newline, hurrah. safe to insert without breaking anything
|
||||
Q_snprintfz(combined+totallen, 64, "#line %i %i //%s\n", glsl.line[i], i, glsl.file[i]);
|
||||
totallen += strlen(combined+totallen);
|
||||
}
|
||||
else if (glsl.len[i] && *glsl.str[i] == '\n')
|
||||
{ //last line didn't end with a newline, but there is one after. that's okay too, but we need to play it safe.
|
||||
Q_snprintfz(combined+totallen, 64, "\n#line %i %i //%s\n", glsl.line[i], i, glsl.file[i]);
|
||||
totallen += strlen(combined+totallen);
|
||||
}
|
||||
//now shove stuff there.
|
||||
memcpy(combined+totallen, glsl.str[i], glsl.len[i]);
|
||||
totallen += glsl.len[i];
|
||||
combined[totallen] = 0;
|
||||
}
|
||||
qglShaderSourceARB(shader, 1, (const GLcharARB**)&combined, NULL);
|
||||
free(combined);
|
||||
}
|
||||
else if (gl_workaround_ati_shadersource.ival)
|
||||
{
|
||||
/*ATI Driver Bug: ATI drivers ignore the 'length' array.
|
||||
this code does what the drivers fail to do.
|
||||
|
@ -2262,22 +2297,22 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
|||
*/
|
||||
GLcharARB *combined;
|
||||
int totallen = 1;
|
||||
for (i = 0; i < strings; i++)
|
||||
totallen += length[i];
|
||||
for (i = 0; i < glsl.strings; i++)
|
||||
totallen += glsl.len[i];
|
||||
combined = malloc(totallen);
|
||||
totallen = 0;
|
||||
combined[totallen] = 0;
|
||||
for (i = 0; i < strings; i++)
|
||||
for (i = 0; i < glsl.strings; i++)
|
||||
{
|
||||
memcpy(combined + totallen, prstrings[i], length[i]);
|
||||
totallen += length[i];
|
||||
memcpy(combined + totallen, glsl.str[i], glsl.len[i]);
|
||||
totallen += glsl.len[i];
|
||||
combined[totallen] = 0;
|
||||
}
|
||||
qglShaderSourceARB(shader, 1, (const GLcharARB**)&combined, NULL);
|
||||
free(combined);
|
||||
}
|
||||
else
|
||||
qglShaderSourceARB(shader, strings, prstrings, length);
|
||||
qglShaderSourceARB(shader, glsl.strings, glsl.str, glsl.len);
|
||||
qglCompileShaderARB(shader);
|
||||
|
||||
return shader;
|
||||
|
|
|
@ -13621,7 +13621,7 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *s
|
|||
}
|
||||
else if (type->type == ev_field)
|
||||
{
|
||||
if (type->aux_type->type == ev_vector && !arraysize)
|
||||
if (type->aux_type->type == ev_vector && !arraysize && *def->name != ':')
|
||||
{
|
||||
//do the vector thing.
|
||||
QC_snprintfz(newname, sizeof(newname), "%s_x", def->name);
|
||||
|
|
|
@ -5625,11 +5625,12 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
d = QCC_PR_GetDef(NULL, membername, NULL, 0, 0, GDF_CONST);
|
||||
if (!d)
|
||||
{
|
||||
d = QCC_PR_GetDef(QCC_PR_FieldType(*basictypes[newparm->type]), membername, NULL, 2, 0, GDF_CONST|GDF_POSTINIT);
|
||||
d = QCC_PR_GetDef(QCC_PR_FieldType(*basictypes[newparm->type]), membername, NULL, 2, 0, GDF_CONST|GDF_POSTINIT|GDF_USED);
|
||||
// for (i = 0; (unsigned int)i < newparm->size*(arraysize?arraysize:1); i++)
|
||||
// d->symboldata[i]._int = pr.size_fields+i;
|
||||
// pr.size_fields += i;
|
||||
|
||||
d->used = true;
|
||||
d->referenced = true; //always referenced, so you can inherit safely.
|
||||
}
|
||||
if (d->arraysize < basicindex+(arraysize?arraysize:1))
|
||||
|
@ -5637,7 +5638,17 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
if (d->symboldata)
|
||||
QCC_PR_ParseError(ERR_INTERNAL, "array members are kinda limited, sorry. try rearranging them or adding padding for alignment\n"); //FIXME: add relocs to cope with this all of a type can then be contiguous and thus allow arrays.
|
||||
else
|
||||
d->arraysize = basicindex+(arraysize?arraysize:1);
|
||||
{
|
||||
int newsize = basicindex+(arraysize?arraysize:1);
|
||||
if (d->type->type == ev_union || d->type->type == ev_struct)
|
||||
d->arraysize = newsize;
|
||||
else while(d->arraysize < newsize)
|
||||
{
|
||||
QC_snprintfz(membername, sizeof(membername), "::%s[%i]", basictypenames[newparm->type], d->arraysize/d->type->size);
|
||||
QCC_PR_DummyDef(d->type, membername, d->scope, 0, d, d->arraysize, true, GDF_CONST);
|
||||
d->arraysize+=d->type->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
QCC_FreeDef(d);
|
||||
|
|
|
@ -604,6 +604,25 @@ void QCC_PrintStrings (void)
|
|||
}
|
||||
}*/
|
||||
|
||||
void QCC_SortFields (void)
|
||||
{
|
||||
int i, j;
|
||||
QCC_ddef32_t t;
|
||||
|
||||
// good 'ol bubble sort
|
||||
//(qsort doesn't guarentee ordering)
|
||||
for (i = 0; i < numfielddefs; i++)
|
||||
{
|
||||
for (j = i; j < numfielddefs; j++)
|
||||
if (fields[i].ofs > fields[j].ofs)
|
||||
{
|
||||
t = fields[i];
|
||||
fields[i] = fields[j];
|
||||
fields[j] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QCC_PrintFields (void)
|
||||
{
|
||||
extern char *basictypenames[];
|
||||
|
@ -1855,6 +1874,7 @@ pbool QCC_WriteData (int crc)
|
|||
printf("code: %s:%i: %s%s%s %s@%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs);
|
||||
#endif
|
||||
}
|
||||
QCC_SortFields();
|
||||
|
||||
if (dupewarncount > 10 && !verbose)
|
||||
QCC_PR_Note(WARN_NOTREFERENCED, NULL, 0, "suppressed %i more warnings about unreferenced variables, as you clearly don't care about the first 10.", dupewarncount-10);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "quakedef.h"
|
||||
#include "pr_common.h"
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
#if !defined(CLIENTONLY) && defined(SAVEDGAMES)
|
||||
|
||||
extern cvar_t skill;
|
||||
extern cvar_t deathmatch;
|
||||
|
@ -9,7 +9,7 @@ extern cvar_t coop;
|
|||
extern cvar_t teamplay;
|
||||
extern cvar_t pr_enable_profiling;
|
||||
|
||||
cvar_t sv_savefmt = CVARFD("sv_savefmt", "1", CVAR_SAVE, "Specifies the format used for the saved game.\n0=legacy.\n1=fte\n2=binary");
|
||||
cvar_t sv_savefmt = CVARFD("sv_savefmt", "", CVAR_SAVE, "Specifies the format used for the saved game.\n0=legacy.\n1=fte\n2=binary");
|
||||
cvar_t sv_autosave = CVARFD("sv_autosave", "5", CVAR_SAVE, "Interval for autosaves, in minutes. Set to 0 to disable autosave.");
|
||||
|
||||
void SV_Savegame_f (void);
|
||||
|
@ -78,7 +78,7 @@ void SV_SavegameComment (char *text, size_t textsize)
|
|||
|
||||
#ifndef QUAKETC
|
||||
//expects the version to have already been parsed
|
||||
void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
||||
static void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
|
||||
{
|
||||
//FIXME: Multiplayer save probably won't work with spectators.
|
||||
char mapname[MAX_QPATH];
|
||||
|
@ -394,7 +394,7 @@ static void SV_LegacySavegame (const char *savename)
|
|||
}
|
||||
|
||||
sprintf (name, "%s", savename);
|
||||
COM_RequireExtension (name, ".sav", sizeof(name));
|
||||
COM_RequireExtension (name, ".sav", sizeof(name)); //do NOT allow .pak etc
|
||||
if (!FS_NativePath(name, FS_GAMEONLY, native, sizeof(native)))
|
||||
return;
|
||||
Con_TPrintf (U8("Saving game to %s...\n"), native);
|
||||
|
@ -1109,7 +1109,7 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame)
|
|||
//FIXME: static entities
|
||||
//FIXME: midi track
|
||||
//FIXME: custom temp-ents?
|
||||
//FIXME: pending uri_gets? (if only just to report fails)
|
||||
//FIXME: pending uri_gets? (if only just to report fails on load)
|
||||
//FIXME: routing calls?
|
||||
//FIXME: sql queries?
|
||||
//FIXME: frik files?
|
||||
|
|
|
@ -116,7 +116,9 @@ typedef struct
|
|||
unsigned int csqcchecksum;
|
||||
qboolean mapchangelocked;
|
||||
|
||||
#ifdef SAVEDGAMES
|
||||
double autosave_time;
|
||||
#endif
|
||||
double time;
|
||||
double starttime;
|
||||
int framenum;
|
||||
|
@ -1572,7 +1574,6 @@ typedef struct
|
|||
int SV_MVD_GotQTVRequest(vfsfile_t *clientstream, char *headerstart, char *headerend, qtvpendingstate_t *p);
|
||||
|
||||
// savegame.c
|
||||
void SV_LegacySavegame_f(void);
|
||||
void SV_Savegame_f (void);
|
||||
void SV_Savegame_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx);
|
||||
void SV_Loadgame_f (void);
|
||||
|
|
|
@ -675,6 +675,7 @@ void SV_Map_f (void)
|
|||
if (!isrestart)
|
||||
SV_SaveSpawnparms ();
|
||||
|
||||
#ifdef SAVEDGAMES
|
||||
if (newunit)
|
||||
SV_FlushLevelCache(); //forget all on new unit
|
||||
else if (startspot && !isrestart && !newunit)
|
||||
|
@ -698,6 +699,7 @@ void SV_Map_f (void)
|
|||
#endif
|
||||
SV_SaveLevelCache(NULL, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q3SERVER
|
||||
{
|
||||
|
@ -783,7 +785,11 @@ void SV_Map_f (void)
|
|||
}
|
||||
|
||||
SCR_SetLoadingFile("spawnserver");
|
||||
if (newunit || !startspot || cinematic || !SV_LoadLevelCache(NULL, level, startspot, false))
|
||||
if (newunit || !startspot || cinematic
|
||||
#ifdef SAVEDGAMES
|
||||
|| !SV_LoadLevelCache(NULL, level, startspot, false)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (waschangelevel && !startspot)
|
||||
startspot = "";
|
||||
|
@ -854,12 +860,13 @@ void SV_Map_f (void)
|
|||
Cvar_Set(nsv, "");
|
||||
}
|
||||
|
||||
#ifdef SAVEDGAMES
|
||||
if (q2savetos0)
|
||||
{
|
||||
if (sv.state != ss_cinematic) //too weird.
|
||||
SV_Savegame("s0", true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (isDedicated)
|
||||
Mod_Purge(MP_MAPCHANGED);
|
||||
|
|
|
@ -650,7 +650,9 @@ void SV_UnspawnServer (void) //terminate the running server.
|
|||
free(svs.clients);
|
||||
svs.clients = NULL;
|
||||
svs.allocated_client_slots = 0;
|
||||
#ifdef SAVEDGAMES
|
||||
SV_FlushLevelCache();
|
||||
#endif
|
||||
NET_CloseServer ();
|
||||
SV_RunCmdCleanup();
|
||||
}
|
||||
|
@ -1614,7 +1616,9 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
|
||||
if (!startspot)
|
||||
{
|
||||
#ifdef SAVEDGAMES
|
||||
SV_FlushLevelCache(); //to make sure it's caught
|
||||
#endif
|
||||
for (i=0 ; i<sv.allocated_client_slots ; i++)
|
||||
{
|
||||
if (svs.clients[i].spawninfo)
|
||||
|
@ -1730,7 +1734,9 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
SV_SetMoveVars();
|
||||
|
||||
sv.starttime = Sys_DoubleTime() - sv.time;
|
||||
#ifdef SAVEDGAMES
|
||||
sv.autosave_time = sv.time + sv_autosave.value*60;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4899,8 +4899,10 @@ float SV_Frame (void)
|
|||
{
|
||||
isidle = false;
|
||||
|
||||
#ifdef SAVEDGAMES
|
||||
if (sv.time > sv.autosave_time)
|
||||
SV_AutoSave();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5203,10 +5205,9 @@ void SV_InitLocal (void)
|
|||
|
||||
Cmd_AddCommand ("openroute", SV_OpenRoute_f);
|
||||
|
||||
#ifndef NOBUILTINMENUS
|
||||
#ifndef SERVERONLY
|
||||
#ifdef SAVEDGAMES
|
||||
#if !defined(NOBUILTINMENUS) && !defined(SERVERONLY)
|
||||
Cvar_Register(&sv_autosave, cvargroup_servercontrol);
|
||||
#endif
|
||||
#endif
|
||||
Cvar_Register(&sv_savefmt, cvargroup_servercontrol);
|
||||
#ifndef QUAKETC
|
||||
|
@ -5216,6 +5217,7 @@ void SV_InitLocal (void)
|
|||
Cmd_AddCommandAD ("loadgame", SV_Loadgame_f, SV_Savegame_c, "Loads an existing saved game.");
|
||||
Cmd_AddCommandAD ("save", SV_Savegame_f, SV_Savegame_c, "Saves the game to the named location.");
|
||||
Cmd_AddCommandAD ("load", SV_Loadgame_f, SV_Savegame_c, "Loads an existing saved game.");
|
||||
#endif
|
||||
|
||||
SV_MVDInit();
|
||||
|
||||
|
|
Loading…
Reference in a new issue