random hacks to get rtshadows working in the gles/webgl port, no longer depend upon GL_ARB_shadow.

gles renderer can use fbos now.
webgl now saves configs+savedgames persistently using localstorage.
misc startup/manifest refinements.
make nacl compile again.
webgl port can now use #stuff to select different manifest files.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4733 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-08-27 08:41:31 +00:00
parent 957afd8c3b
commit 258a4163ae
40 changed files with 611 additions and 390 deletions

View file

@ -754,6 +754,7 @@ ifeq ($(FTE_TARGET),nacl)
BASELDFLAGS = -lm -lppapi_gles2 -lnosys -lppapi
IMAGELDFLAGS =
GL_CFLAGS=$(GLCFLAGS)
GL_CFLAGS+=$(SPEEXCFLAGS)
GL_CFLAGS+=-I$(realpath $(NACL_SDK_ROOT)/include)
BASELDFLAGS+=-L$(realpath $(NACL_SDK_ROOT)/lib/$(NACLLIBS))

View file

@ -3851,8 +3851,8 @@ void Host_RunFileNotify(struct dl_download *dl)
#define HRF_ABORT (1<<3)
#define HRF_OPENED (1<<4)
// (1<<5)
// (1<<6)
#define HRF_DOWNLOADED (1<<5) //file was actually downloaded, and not from the local system
#define HRF_WAITING (1<<6) //file looks important enough that we should wait for it to start to download or something to see what file type it is.
// (1<<7)
#define HRF_DEMO_MVD (1<<8)
@ -3894,6 +3894,12 @@ void Host_BeginFileDownload(struct dl_download *dl, char *mimetype)
//at this point the file is still downloading, so don't copy it out just yet.
hrf_t *f = dl->user_ctx;
if (f->flags & HRF_WAITING)
{
f->flags &= ~HRF_WAITING;
waitingformanifest--;
}
if (mimetype && !(f->flags & HRF_FILETYPES))
{
if (!strcmp(mimetype, "application/x-qtv")) //what uses this?
@ -3988,6 +3994,14 @@ void Host_RunFilePrompted(void *ctx, int button)
Host_DoRunFile(f);
}
static qboolean isurl(char *url)
{
#ifdef FTE_TARGET_WEB
return true; //assume EVERYTHING is a url, because the local filesystem is pointless.
#endif
return !strncmp(url, "http://", 7) || !strncmp(url, "https://", 8);
}
void Host_DoRunFile(hrf_t *f)
{
char qname[MAX_QPATH];
@ -3996,6 +4010,12 @@ void Host_DoRunFile(hrf_t *f)
qboolean isnew = false;
qboolean haschanged = false;
if (f->flags & HRF_WAITING)
{
f->flags &= ~HRF_WAITING;
waitingformanifest--;
}
if (f->flags & HRF_ABORT)
{
if (f->flags & HRF_MANIFEST)
@ -4014,15 +4034,17 @@ void Host_DoRunFile(hrf_t *f)
char *ext;
#ifdef WEBCLIENT
if ((!strncmp(f->fname, "http://", 7) || !strncmp(f->fname, "https://", 8)) && !f->srcfile)
if (isurl(f->fname) && !f->srcfile)
{
if (!(f->flags & HRF_OPENED))
{
struct dl_download *dl;
f->flags |= HRF_OPENED;
f->flags |= HRF_OPENED|HRF_DOWNLOADED|HRF_WAITING;
dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
dl->notifystarted = Host_BeginFileDownload;
dl->user_ctx = f;
waitingformanifest++;
return;
}
}
@ -4105,11 +4127,21 @@ void Host_DoRunFile(hrf_t *f)
else
{
man = FS_Manifest_Parse(NULL, fdata);
if (man)
{
if (!man->updateurl)
man->updateurl = Z_StrDup(f->fname);
// if (f->flags & HRF_DOWNLOADED)
man->blockupdate = true;
BZ_Free(fdata);
FS_ChangeGame(man, true);
}
else
{
Con_Printf("Manifest file %s does not appear valid\n", f->fname);
BZ_Free(fdata);
}
}
f->flags |= HRF_ABORT;
Host_DoRunFile(f);
@ -4132,7 +4164,7 @@ void Host_DoRunFile(hrf_t *f)
if (!f->srcfile)
{
#ifdef WEBCLIENT
if (!strncmp(f->fname, "http://", 7))
if (isurl(f->fname))
{
struct dl_download *dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
dl->notifystarted = Host_BeginFileDownload;
@ -4288,6 +4320,8 @@ Runs all active servers
extern cvar_t cl_netfps;
extern cvar_t cl_sparemsec;
qboolean startuppending;
void CL_StartCinematicOrMenu(void);
int nopacketcount;
void SNDDMA_SetUnderWater(qboolean underwater);
double Host_Frame (double time)
@ -4336,6 +4370,8 @@ double Host_Frame (double time)
Host_FinishLoading();
return 0;
}
if (startuppending)
CL_StartCinematicOrMenu();
#ifdef PLUGINS
Plug_Tick();
@ -4629,9 +4665,19 @@ void CL_ReadCDKey(void)
//============================================================================
void CL_StartCinematicOrMenu(void)
{
if (cls.download)
{
startuppending = true;
return;
}
if (startuppending)
{
startuppending = false;
Key_Dest_Remove(kdm_console); //make sure console doesn't stay up weirdly.
}
//start up the ui now we have a renderer
#ifdef VM_UI
UI_Start();
@ -4685,9 +4731,11 @@ void CL_StartCinematicOrMenu(void)
{
if (qrenderer > QR_NONE && !m_state)
{
if (cl_demoreel.ival)
if (!cls.state && !m_state && !*FS_GetGamedir(false))
M_Menu_Mods_f();
if (!cls.state && !m_state && cl_demoreel.ival)
CL_NextDemo();
if (!cls.state)
if (!cls.state && !m_state)
M_ToggleMenu_f();
}
//Con_ForceActiveNow();

View file

@ -1458,7 +1458,7 @@ void CL_RequestNextDownload (void)
current_loading_size = cl.contentstage;
if (stage < 0)
return;
SCR_SetLoadingFile("prespawn");
SCR_SetLoadingFile("receiving game state");
cl.sendprespawn = false;
#ifdef warningmsg
#pragma warningmsg("timedemo timer should start here")

View file

@ -226,6 +226,7 @@ void SCR_ScreenShot_f (void);
void SCR_RSShot_f (void);
void SCR_CPrint_f(void);
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
cvar_t show_fps = SCVARF("show_fps", "0", CVAR_ARCHIVE);
cvar_t show_fps_x = SCVAR("show_fps_x", "-1");
cvar_t show_fps_y = SCVAR("show_fps_y", "-1");
@ -245,6 +246,7 @@ void CLSCR_Init(void)
{
Cmd_AddCommand("cprint", SCR_CPrint_f);
Cvar_Register(&con_stayhidden, cl_screengroup);
Cvar_Register(&scr_loadingrefresh, cl_screengroup);
Cvar_Register(&show_fps, cl_screengroup);
Cvar_Register(&show_fps_x, cl_screengroup);
@ -1425,7 +1427,7 @@ void SCR_SetLoadingStage(int stage)
SCR_SetLoadingFile("starting server...");
break;
case LS_CLIENT:
SCR_SetLoadingFile("initial state");
SCR_SetLoadingFile("receiving map info");
break;
}
loading_stage = stage;
@ -1706,7 +1708,7 @@ void SCR_SetUpToDrawConsole (void)
//android has an onscreen imm that we don't want to obscure
fullscreenpercent = scr_consize.value;
#endif
if ((!Key_Dest_Has(~(kdm_console|kdm_game))) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->needload))
if (!con_stayhidden.ival && (!Key_Dest_Has(~(kdm_console|kdm_game))) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->needload))
{
//force console to fullscreen if we're loading stuff
// Key_Dest_Add(kdm_console);
@ -1720,9 +1722,25 @@ void SCR_SetUpToDrawConsole (void)
scr_con_current = scr_conlines = 0;
else
#endif
{
if (cls.state < ca_demostart)
{
if (con_stayhidden.ival)
{
extern qboolean startuppending;
if (SCR_GetLoadingStage() == LS_NONE)
{
if (CL_TryingToConnect()) //if we're trying to connect, make sure there's a loading/connecting screen showing instead of forcing the menu visible
SCR_SetLoadingStage(LS_CONNECTION);
else if (!m_state && !startuppending) //don't force anything until the startup stuff has been done
M_ToggleMenu_f();
}
}
else
Key_Dest_Add(kdm_console);
if (Key_Dest_Has(kdm_console))
}
}
if (!con_stayhidden.ival && Key_Dest_Has(kdm_console))
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
}
else if (Key_Dest_Has(kdm_console) || scr_chatmode)

View file

@ -453,6 +453,7 @@ void Con_ToggleConsole_Force(void)
}
void Con_ToggleConsole_f (void)
{
extern cvar_t con_stayhidden;
#ifdef CSQC_DAT
if (!(key_dest_mask & kdm_editor) && CSQC_ConsoleCommand("toggleconsole"))
{
@ -461,6 +462,9 @@ void Con_ToggleConsole_f (void)
}
#endif
if (con_stayhidden.ival >= 2)
return; //its hiding!
Con_ToggleConsole_Force();
}

View file

@ -1968,7 +1968,8 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
if (key == K_ESCAPE)
if (shift_down)
{
if (down)
extern cvar_t con_stayhidden;
if (down && con_stayhidden.ival < 3)
{
if (!Key_Dest_Has(kdm_console)) //don't toggle it when the console is already down. this allows typing blind to not care if its already active.
Con_ToggleConsole_Force();

View file

@ -1912,15 +1912,21 @@ static qboolean MC_GuiKey(int key, menu_t *menu)
qboolean MC_Main_Key (int key, menu_t *menu) //here purly to restart demos.
{
if (key == K_ESCAPE)
if (key == K_ESCAPE || key == K_MOUSE2)
{
extern int m_save_demonum;
extern cvar_t cl_demoreel;
extern cvar_t cl_demoreel, con_stayhidden;
if (cls.demonum != -1 && !cls.demoplayback && cls.state == ca_disconnected && cl_demoreel.ival)
CL_NextDemo ();
//don't spam menu open+close events if we're not going to be allowing the console to appear
if (con_stayhidden.ival && cls.state == ca_disconnected)
if (!CL_TryingToConnect())
return true;
Key_Dest_Remove(kdm_menu);
m_state = m_none;
cls.demonum = m_save_demonum;
if (cls.demonum != -1 && !cls.demoplayback && cls.state == ca_disconnected && cl_demoreel.ival)
CL_NextDemo ();
return true;
}
return false;
@ -2088,13 +2094,17 @@ void M_Menu_Main_f (void)
mainm->selecteditem = (menuoption_t *)
MC_AddConsoleCommandQBigFont (mainm, 72, 32, "Single ", "menu_single\n");
MC_AddConsoleCommandQBigFont (mainm, 72, 52, "Multiplayer", "menu_multi\n");
MC_AddConsoleCommandQBigFont (mainm, 72, 52, "Multiplayer ", "menu_multi\n");
MC_AddConsoleCommandQBigFont (mainm, 72, 72, "Options ", "menu_options\n");
if (m_helpismedia.value)
MC_AddConsoleCommandQBigFont(mainm, 72, 92, "Media ", "menu_media\n");
else
MC_AddConsoleCommandQBigFont(mainm, 72, 92, "Help ", "help\n");
#ifdef FTE_TARGET_WEB
MC_AddConsoleCommandQBigFont (mainm, 72, 112,"Save Settings", "menu_quit\n");
#else
MC_AddConsoleCommandQBigFont (mainm, 72, 112,"Quit ", "menu_quit\n");
#endif
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
}
@ -2150,7 +2160,11 @@ void M_Menu_Main_f (void)
b->common.width = p->width;
b->common.height = 20;
b=MC_AddConsoleCommand (mainm, 72, 312, 112, "", "menu_quit\n");
#ifdef FTE_TARGET_WEB
b->common.tooltip = "Save settings to local storage.";
#else
b->common.tooltip = "Exit to DOS.";
#endif
b->common.width = p->width;
b->common.height = 20;

View file

@ -1438,9 +1438,10 @@ void M_Menu_Singleplayer_Cheats_Quake (void)
cursorpositionY = (y + 24);
#ifndef CLIENTONLY
currentskill = skill.value;
if ( !currentskill )
if ( !*skill.string )
currentskill = 4; // no skill selected
else
currentskill = skill.value;
for (currentmap = sizeof(maplist_q1)/sizeof(maplist_q1[0]) - 1; currentmap > 0; currentmap--)
if (!strcmp(host_mapname.string, maplist_q1[currentmap]))
@ -1551,11 +1552,11 @@ void M_Menu_Singleplayer_Cheats_Quake2 (void)
cursorpositionY = (y + 24);
#ifndef CLIENTONLY
if ( !*skill.string )
currentskill = 3; // no skill selected
else
currentskill = skill.value;
if ( !currentskill )
currentskill = 4; // no skill selected
for (currentmap = sizeof(maplist_q2)/sizeof(maplist_q2[0]) - 1; currentmap > 0; currentmap--)
if (!strcmp(host_mapname.string, maplist_q2[currentmap]))
break;
@ -1835,10 +1836,10 @@ void M_Menu_Singleplayer_Cheats_Hexen2 (void)
cursorpositionY = (y + 24);
#ifndef CLIENTONLY
currentskill = skill.value;
if ( !currentskill )
if ( !*skill.string )
currentskill = 4; // no skill selected
else
currentskill = skill.value;
#endif
if ( strcmp ( host_mapname.string, "" ) == 0)

View file

@ -573,7 +573,7 @@ void M_Menu_Help_f (void)
{
for (i = 0; i < sizeof(helpstyles)/sizeof(helpstyles[0]); i++)
{
if (COM_FDepthFile(va(helpstyles[i].pattern, num_help_pages+helpstyles[i].base), true))
if (COM_FCheckExists(va(helpstyles[i].pattern, num_help_pages+helpstyles[i].base)))
break;
}
if (i == sizeof(helpstyles)/sizeof(helpstyles[0]))
@ -602,11 +602,13 @@ void M_Help_Key (int key)
switch (key)
{
case K_ESCAPE:
case K_MOUSE2:
M_Menu_Main_f ();
break;
case K_UPARROW:
case K_RIGHTARROW:
case K_MOUSE1:
S_LocalSound ("misc/menu2.wav");
if (++help_page >= num_help_pages)
help_page = 0;
@ -893,7 +895,10 @@ qboolean MC_SaveQuit_Key (int key, menu_t *menu)
{
switch (key)
{
case 'o':
case 'O':
case K_ESCAPE:
case K_MOUSE2:
M_RemoveMenu(menu);
break;
@ -902,16 +907,20 @@ qboolean MC_SaveQuit_Key (int key, menu_t *menu)
case 'n':
case 'N':
M_RemoveMenu(menu);
#ifndef FTE_TARGET_WEB
CL_Disconnect ();
Sys_Quit ();
#endif
break;
case 'Y':
case 'y':
M_RemoveMenu(menu);
Cmd_ExecuteString("cfg_save", RESTRICT_LOCAL);
#ifndef FTE_TARGET_WEB
CL_Disconnect ();
Sys_Quit ();
#endif
break;
default:
@ -921,6 +930,7 @@ qboolean MC_SaveQuit_Key (int key, menu_t *menu)
return true;
}
//quit menu
void M_Menu_Quit_f (void)
{
menu_t *quitmenu;
@ -946,17 +956,19 @@ void M_Menu_Quit_f (void)
if (!strcmp(arg, "prompt"))
mode = 1;
else if (!strcmp(arg, "noprompt"))
mode = 1;
else
mode = 0;
else
mode = 1;
}
}
switch(mode)
{
case 0:
#ifndef FTE_TARGET_WEB
CL_Disconnect ();
Sys_Quit ();
#endif
break;
case 2:
Key_Dest_Add(kdm_menu);
@ -971,9 +983,14 @@ void M_Menu_Quit_f (void)
MC_AddWhiteText(quitmenu, 64, 0, 100, " save them now? ", false);
quitmenu->selecteditem = (menuoption_t *)
#ifdef FTE_TARGET_WEB
MC_AddConsoleCommand (quitmenu, 64, 0, 116, "Yes", "cfg_save; menupop\n");
MC_AddConsoleCommand (quitmenu, 224,0, 116, "Cancel", "menupop\n");
#else
MC_AddConsoleCommand (quitmenu, 64, 0, 116, "Yes", "menu_quit forcesave\n");
MC_AddConsoleCommand (quitmenu, 144,0, 116, "No", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 224,0, 116, "Cancel", "menupop\n");
#endif
MC_AddBox (quitmenu, 56, 76, 25, 5);
break;
@ -986,17 +1003,25 @@ void M_Menu_Quit_f (void)
quitmenu->key = MC_Quit_Key;
i = rand()&7;
#ifdef FTE_TARGET_WEB
// MC_AddWhiteText(quitmenu, 64, 0, 84, " ", false);
MC_AddWhiteText(quitmenu, 64, 0, 92, " There is nothing to save ", false);
// MC_AddWhiteText(quitmenu, 64, 0, 100, " ", false);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 120, 0, 116, "Oh", "menupop\n");
#else
i = rand()&7;
MC_AddWhiteText(quitmenu, 64, 0, 84, quitMessage[i*4+0], false);
MC_AddWhiteText(quitmenu, 64, 0, 92, quitMessage[i*4+1], false);
MC_AddWhiteText(quitmenu, 64, 0, 100, quitMessage[i*4+2], false);
MC_AddWhiteText(quitmenu, 64, 0, 108, quitMessage[i*4+3], false);
quitmenu->selecteditem = (menuoption_t *)
MC_AddConsoleCommand (quitmenu, 120, 0, 116, "Yes", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 208, 0, 116, "No", "menupop\n");
MC_AddConsoleCommand (quitmenu, 100, 0, 116, "Quit", "menu_quit force\n");
MC_AddConsoleCommand (quitmenu, 194, 0, 116, "Cancel", "menupop\n");
#endif
MC_AddBox (quitmenu, 56, 76, 24, 5);
break;
}

View file

@ -108,6 +108,7 @@ void M_Keydown (int key, int unicode);
void M_Keyup (int key, int unicode);
void M_Draw (int uimenu);
void M_ToggleMenu_f (void);
void M_Menu_Mods_f (void); //used at startup if the current gamedirs look dodgy.
mpic_t *M_CachePic (char *path);
void M_DrawTextBox (int x, int y, int width, int lines);
void M_Menu_Quit_f (void);

View file

@ -2319,14 +2319,6 @@ void MP_Keydown(int key, int unicode)
return;
}
}
if (key == K_ESCAPE)
{
if (keydown[K_LSHIFT] || keydown[K_RSHIFT])
{
Con_ToggleConsole_Force();
return;
}
}
menutime = Sys_DoubleTime();
if (menu_world.g.time)

View file

@ -14,8 +14,6 @@ entity_t *currententity; //nnggh
int r_framecount;
struct texture_s *r_notexture_mip;
r_config_t r_config;
qboolean r_blockvidrestart;
int r_regsequence;
@ -1036,8 +1034,6 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
pmove.numphysent = 0;
memset(&r_config, 0, sizeof(r_config));
if (qrenderer != QR_NONE) //graphics stuff only when not dedicated
{
qbyte *data;
@ -1169,17 +1165,16 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
TRACE(("dbg: R_ApplyRenderer: reloading server map\n"));
sv.world.worldmodel = Mod_ForName (sv.modelname, MLV_WARN);
TRACE(("dbg: R_ApplyRenderer: loaded\n"));
if (sv.world.worldmodel->needload)
{
SV_Error("Bsp went missing on render restart\n");
}
TRACE(("dbg: R_ApplyRenderer: doing that funky phs thang\n"));
SV_CalcPHS ();
TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
World_ClearWorld (&sv.world);
if (svs.gametype == GT_PROGS)
if (sv.world.worldmodel->needload)
SV_UnspawnServer();
else if (svs.gametype == GT_PROGS)
{
for (i = 0; i < MAX_MODELS; i++)
{

View file

@ -297,10 +297,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef Q3SERVER //trying to trim memory use
#undef Q2BSPS //emscripten can't cope with bss, leading to increased download time. too lazy to fix.
#undef Q3BSPS //emscripten can't cope with bss, leading to increased download time. too lazy to fix.
#undef PSET_SCRIPT //bss+size
// #undef PSET_SCRIPT //bss+size
#define GLSLONLY //pointless having the junk
#define GLESONLY //should reduce the conditions a little
#define R_MAX_RECURSE 2 //less bss
#undef RTLIGHTS
// #undef RTLIGHTS
#endif
#ifdef WINRT
#undef TCPCONNECT //err...
@ -319,6 +320,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef VOICECHAT
#endif
#undef TEXTEDITOR
#define GLESONLY //should reduce the conditions a little
#endif
#if defined(NACL)
#undef SUPPORT_ICE
@ -327,6 +329,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef WEBSERVER //no sockets support (certainly no servers)
#undef TCPCONNECT
#undef IRCCONNECT
#define GLSLONLY //pointless having the junk
#define GLESONLY //should reduce the conditions a little
#endif
#ifndef MULTITHREAD

View file

@ -2855,7 +2855,7 @@ void Cmd_WriteConfig_f(void)
snprintf(fname, sizeof(fname), "fte.cfg");
FS_NativePath(fname, FS_GAMEONLY, sysname, sizeof(sysname));
FS_CreatePath(fname, FS_GAMEONLY);
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
f = FS_OpenVFS(fname, "wbp", FS_GAMEONLY);
}
else
{
@ -2869,7 +2869,7 @@ void Cmd_WriteConfig_f(void)
FS_NativePath(fname, FS_BASEGAMEONLY, sysname, sizeof(sysname));
FS_CreatePath(fname, FS_BASEGAMEONLY);
f = FS_OpenVFS(fname, "wb", FS_BASEGAMEONLY);
f = FS_OpenVFS(fname, "wbp", FS_BASEGAMEONLY);
}
if (!f)
{

View file

@ -12,7 +12,7 @@
#include "winquake.h"
#endif
void fs_game_callback(cvar_t *var, char *oldvalue);
static void fs_game_callback(cvar_t *var, char *oldvalue);
hashtable_t filesystemhash;
qboolean com_fschanged = true;
qboolean fs_readonly;
@ -28,7 +28,7 @@ static int fs_referencetype;
int fs_finds;
void COM_CheckRegistered (void);
void fs_game_callback(cvar_t *var, char *oldvalue)
static void fs_game_callback(cvar_t *var, char *oldvalue)
{
static qboolean runaway = false;
char buf[MAX_OSPATH];
@ -1363,13 +1363,15 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r
if (!filename)
return NULL;
#ifdef _DEBUG
if (strcmp(mode, "rb"))
if (strcmp(mode, "r+b"))
if (strcmp(mode, "wb"))
if (strcmp(mode, "w+b"))
if (strcmp(mode, "ab"))
if (strcmp(mode, "wbp"))
return NULL; //urm, unable to write/append
#endif
//if there can only be one file (eg: write access) find out where it is.
switch (relativeto)
@ -1538,7 +1540,7 @@ qboolean FS_Copy(const char *source, const char *dest, enum fs_relative relative
s = FS_OpenVFS(source, "rb", relativesource);
if (s)
{
d = FS_OpenVFS(dest, "wb", relativedest);
d = FS_OpenVFS(dest, "wbp", relativedest);
if (d)
{
result = true;
@ -2027,11 +2029,16 @@ void COM_FlushFSCache(void)
}
}
if (com_fs_cache.ival)
#ifdef FTE_TARGET_WEB
//web target doesn't support filesystem enumeration, so make sure the cache is kept invalid and disabled.
com_fschanged = true;
#else
if (com_fs_cache.ival && com_fschanged)
{
//rebuild it if needed
FS_RebuildFSHash();
}
#endif
}
/*since should start as 0, otherwise this can be used to poll*/
@ -2210,128 +2217,6 @@ void COM_Gamedir (const char *dir)
Z_Free(dup);
}
FS_ChangeGame(man, cfg_reload_on_gamedir.ival);
#if 0
char thispath[64];
searchpath_t *next;
qboolean isbase;
//don't allow leading dots, hidden files are evil.
//don't allow complex paths. those are evil too.
if (!*dir || *dir == '.' || !strcmp(dir, ".") || strstr(dir, "..") || strstr(dir, "/")
|| strstr(dir, "\\") || strstr(dir, ":") )
{
Con_TPrintf (TL_GAMEDIRAINTPATH);
return;
}
isbase = false;
for (next = com_searchpaths; next; next = next->next)
{
if (next == com_base_searchpaths)
isbase = true;
if (next->funcs == &osfilefuncs)
{
FS_CleanDir(next->purepath, thispath, sizeof(thispath));
if (!strcmp(dir, thispath))
{
if (isbase && com_searchpaths == com_base_searchpaths)
{
Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile));
return;
}
if (!isbase)
return;
break;
}
}
}
FS_ForceToPure(NULL, NULL, 0);
#ifndef SERVERONLY
// Host_WriteConfiguration(); //before we change anything.
#endif
Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile));
#ifndef CLIENTONLY
sv.gamedirchanged = true;
#endif
#ifndef SERVERONLY
cl.gamedirchanged = true;
#endif
FS_FlushFSHashReally();
//
// free up any current game dir info
//
while (com_searchpaths != com_base_searchpaths)
{
com_searchpaths->handle->ClosePath(com_searchpaths->handle);
next = com_searchpaths->next;
Z_Free (com_searchpaths);
com_searchpaths = next;
}
com_fschanged = true;
//
// flush all data, so it will be forced to reload
//
Cache_Flush ();
if (strchr(dir, ';'))
{
//separate case because parsestringset splits by whitespace too
while ((dir = COM_ParseStringSet(dir)))
{
if (!strcmp(dir, ";"))
continue;
if (!*dir)
continue;
FS_AddGameDirectory(dir, va("%s%s", com_gamepath, com_token), ~0, SPF_EXPLICIT);
if (com_homepathenabled)
FS_AddGameDirectory(dir, va("%s%s", com_homepath, com_token), ~0, SPF_EXPLICIT);
}
}
else
{
FS_AddGameDirectory(dir, va("%s%s", com_gamepath, dir), ~0, SPF_EXPLICIT);
if (com_homepathenabled)
FS_AddGameDirectory(dir, va("%s%s", com_homepath, dir), ~0, SPF_EXPLICIT);
}
#ifndef SERVERONLY
if (!isDedicated)
{
// if (qrenderer != QR_NONE) //only do this if we have already started the renderer
// Cbuf_InsertText("vid_restart\n", RESTRICT_LOCAL);
if (COM_FDepthFile("config.cfg", true) <= (com_homepathenabled?1:0))
{
Cbuf_InsertText("cl_warncmd 0\n"
"exec config.cfg\n"
"exec fte.cfg\n"
"cl_warncmd 1\n", RESTRICT_LOCAL, false);
}
}
Shader_Init(); //FIXME!
COM_Effectinfo_Clear();
Validation_FlushFileList(); //prevent previous hacks from making a difference.
//FIXME: load new palette, if different cause a vid_restart.
#endif
#endif
}
#define QCFG "set allow_download_refpackages 0\n"
@ -3722,7 +3607,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
"FTEMANIFEST 1\n"
"game \"\"\n"
"name \"" FULLENGINENAME "\"\n"
"defaultexec \\\"vid_fullscreen 0; gl_font cour;vid_width 640; vid_height 480; menu_mods\"\n"
"defaultexec \\\"vid_fullscreen 0; gl_font cour;vid_width 640; vid_height 480\"\n"
);
}
}

View file

@ -772,7 +772,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
tinheight = inheight;
//don't make scaled width any larger than it needs to be
if (r_config.texture_non_power_of_two)
if (gl_config.texture_non_power_of_two)
{
scaled_width = tinwidth;
scaled_height = tinheight;

View file

@ -230,6 +230,7 @@ static void BE_PolyOffset(qboolean pushdepth)
}
}
#ifndef GLSLONLY
void GL_TexEnv(GLenum mode)
{
#ifndef FORCESTATE
@ -302,6 +303,7 @@ static void BE_SetPassBlendMode(int tmu, int pbm)
}
}
}
#endif
/*OpenGL requires glDepthMask(GL_TRUE) or glClear(GL_DEPTH_BUFFER_BIT) will fail*/
void GL_ForceDepthWritable(void)
@ -927,7 +929,7 @@ static void RevertToKnownState(void)
}
GL_SelectTexture(0);
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
{
BE_SetPassBlendMode(0, PBM_REPLACE);
@ -935,6 +937,7 @@ static void RevertToKnownState(void)
GL_DeSelectProgram();
}
#endif
shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY|SBITS_MASK_BITS|SBITS_AFFINE);
shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE;
@ -989,7 +992,6 @@ int GLBE_SetupForShadowMap(texid_t shadowmaptex, int texwidth, int texheight, fl
if (qglShadeModel)
qglShadeModel(GL_FLAT);
BE_SetPassBlendMode(0, PBM_REPLACE);
GL_ForceDepthWritable();
// qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@ -1007,7 +1009,7 @@ static void T_Gen_CurrentRender(int tmu)
if (r_refdef.recurse)
return;
if (r_config.texture_non_power_of_two)
if (gl_config.texture_non_power_of_two_limited)
{
vwidth = pwidth;
vheight = pheight;
@ -3040,7 +3042,7 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
break;
case SP_RENDERTEXTURESCALE:
if (r_config.texture_non_power_of_two)
if (gl_config.texture_non_power_of_two_limited)
{
param4[0] = 1;
param4[1] = 1;
@ -3317,7 +3319,20 @@ void GLBE_SelectMode(backendmode_t mode)
default:
break;
case BEM_DEPTHONLY:
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
{
BE_SetPassBlendMode(0, PBM_REPLACE);
GL_DeSelectProgram();
}
else
#endif
if (!shaderstate.allblackshader)
{
const char *defs[] = {NULL};
shaderstate.allblackshader = GLSlang_CreateProgram("allblackprogram", gl_config_gles?100:110, defs, "#include \"sys/skeletal.h\"\nvoid main(){gl_Position = skeletaltransform();}", "void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);}", false, NULL);
shaderstate.allblack_mvp = qglGetUniformLocationARB(shaderstate.allblackshader, "m_modelviewprojection");
}
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
while(shaderstate.lastpasstmus>0)
{
@ -3327,7 +3342,6 @@ void GLBE_SelectMode(backendmode_t mode)
//we don't write or blend anything (maybe alpha test... but mneh)
BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHWRITE | SBITS_MASK_BITS);
BE_SetPassBlendMode(0, PBM_REPLACE);
GL_CullFace(SHADER_CULL_FRONT);
break;
@ -3348,6 +3362,7 @@ void GLBE_SelectMode(backendmode_t mode)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
}
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
{
GL_DeSelectProgram();
@ -3355,6 +3370,7 @@ void GLBE_SelectMode(backendmode_t mode)
//replace mode please
BE_SetPassBlendMode(0, PBM_REPLACE);
}
#endif
//we don't write or blend anything (maybe alpha test... but mneh)
BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHCLOSERONLY | SBITS_MASK_BITS);
@ -3400,7 +3416,10 @@ void GLBE_SelectMode(backendmode_t mode)
Vector4Set(shaderstate.pendingcolourflat, 1, 1, 1, 1);
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
BE_SetPassBlendMode(0, PBM_MODULATE);
#endif
BE_SendPassBlendDepthMask(SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_DEPTHEQUALONLY);
break;
}
@ -3451,10 +3470,12 @@ static qboolean GLBE_RegisterLightShader(int mode)
{
if (!shaderstate.inited_shader_light[mode])
{
char *name = va("rtlight%s%s%s",
char *name = va("rtlight%s%s%s%s",
(mode & LSHADER_SMAP)?"#PCF":"",
(mode & LSHADER_SPOT)?"#SPOT":"",
(mode & LSHADER_CUBE)?"#CUBE":"");
(mode & LSHADER_CUBE)?"#CUBE":"",
(gl_config.arb_shadow && (mode & (LSHADER_SMAP|LSHADER_SPOT|LSHADER_CUBE)))?"#USE_ARB_SHADOW":""
);
shaderstate.inited_shader_light[mode] = true;
shaderstate.shader_light[mode] = R_RegisterCustom(name, SUF_NONE, Shader_LightPass, NULL);
@ -3847,7 +3868,18 @@ static void DrawMeshes(void)
case BEM_WIREFRAME:
//FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster.
//FIXME: we need to use a shader for vertex blending. not really an issue with mdl, but more significant with iqms (base pose!).
#ifndef GLSLONLY
if (!gl_config_nofixedfunc)
{
BE_SetPassBlendMode(0, PBM_REPLACE);
GL_DeSelectProgram();
}
else
#endif
{
break;
}
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
Vector4Set(shaderstate.pendingcolourflat, 1, 1, 1, 1);
@ -3855,14 +3887,13 @@ static void DrawMeshes(void)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
}
BE_SetPassBlendMode(0, PBM_REPLACE);
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits | SBITS_MISC_NODEPTHTEST);
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain();
break;
case BEM_DEPTHDARK:
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright) && !gl_config_nofixedfunc)
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright))
{
if (gl_config.arb_shader_objects)
{
@ -3875,7 +3906,7 @@ static void DrawMeshes(void)
GL_SelectProgram(shaderstate.allblackshader);
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
BE_EnableShaderAttributes(1u<<VATTR_LEG_VERTEX, 0);
BE_EnableShaderAttributes(gl_config_nofixedfunc?(1u<<VATTR_VERTEX1):(1u<<VATTR_LEG_VERTEX), 0);
if (shaderstate.allblackshader != shaderstate.lastuniform && shaderstate.allblack_mvp != -1)
{
float m16[16];
@ -3885,8 +3916,10 @@ static void DrawMeshes(void)
BE_SubmitMeshChain();
shaderstate.lastuniform = shaderstate.allblackshader;
break;
}
else
#ifndef GLSLONLY
else if (!gl_config_nofixedfunc)
{
GL_DeSelectProgram();
shaderstate.pendingcolourvbo = 0;
@ -3902,9 +3935,10 @@ static void DrawMeshes(void)
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
BE_SubmitMeshChain();
}
break;
}
#endif
}
//fallthrough
case BEM_STANDARD:
default:
@ -4613,6 +4647,8 @@ void GLBE_FBO_Destroy(fbostate_t *state)
//state->colour is created if usedepth is set and it doesn't previously exist
int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, int mrt, texid_t destdepth, int width, int height)
{
GLenum allcolourattachments[] ={GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT,GL_COLOR_ATTACHMENT2_EXT,GL_COLOR_ATTACHMENT3_EXT,
GL_COLOR_ATTACHMENT4_EXT,GL_COLOR_ATTACHMENT5_EXT,GL_COLOR_ATTACHMENT6_EXT,GL_COLOR_ATTACHMENT7_EXT};
int i;
int old;
@ -4635,12 +4671,10 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
{
qglGenFramebuffersEXT(1, &state->fbo);
old = GLBE_FBO_Push(state);
enables |= FBO_RESET;
}
else
old = GLBE_FBO_Push(state);
if (state->rb_size[0] != width || state->rb_size[1] != height || (enables & FBO_RESET))
{
if (state->rb_depth && !(enables & FBO_RB_DEPTH))
@ -4657,19 +4691,25 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
state->rb_size[1] = height;
enables |= FBO_RESET;
if (mrt)
{
{ //be careful here, gles2 doesn't support glDrawBuffer. hopefully it'll make things up, but this is worrying.
if (qglDrawBuffers)
qglDrawBuffers(mrt, allcolourattachments);
else if (qglDrawBuffer)
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
if (qglReadBuffer)
qglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
else
{
if (qglDrawBuffers)
qglDrawBuffers(0, NULL);
else if (qglDrawBuffer)
qglDrawBuffer(GL_NONE);
if (qglReadBuffer)
qglReadBuffer(GL_NONE);
}
}
if (enables & FBO_TEX_DEPTH)
{
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, destdepth.num, 0);
@ -4681,9 +4721,8 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
{
//create an unnamed depth buffer
qglGenRenderbuffersEXT(1, &state->rb_depth);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_depth);
if (!gl_config.ext_packed_depth_stencil)
qglGenRenderbuffersEXT(1, &state->rb_stencil);
// if (!gl_config.ext_packed_depth_stencil)
// qglGenRenderbuffersEXT(1, &state->rb_stencil);
enables |= FBO_RESET; //make sure it gets instanciated
}
@ -4694,10 +4733,9 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, state->rb_size[0], state->rb_size[1]);
else
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, state->rb_size[0], state->rb_size[1]);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, state->rb_size[0], state->rb_size[1]);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16_ARB, state->rb_size[0], state->rb_size[1]);
// qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_stencil);
// qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, state->rb_size[0], state->rb_size[1]);
}
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, state->rb_depth);
if (gl_config.ext_packed_depth_stencil)
@ -4709,6 +4747,38 @@ int GLBE_FBO_Update(fbostate_t *state, unsigned int enables, texid_t *destcol, i
for (i = 0; i < mrt; i++)
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, destcol[i].num, 0);
i = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (GL_FRAMEBUFFER_COMPLETE_EXT != i)
{
switch(i)
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_FORMATS\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
Con_Printf("glCheckFramebufferStatus reported GL_FRAMEBUFFER_UNSUPPORTED\n");
break;
default:
Con_Printf("glCheckFramebufferStatus returned %#x\n", i);
break;
}
}
return old;
}
/*

View file

@ -114,7 +114,7 @@ static void R_SetupBloomTextures(int w, int h)
if (!TEXVALID(pingtex[i][j]))
{
sprintf(name, "***bloom*%c*%i***", 'a'+i, j);
TEXASSIGN(pingtex[i][j], GL_AllocNewTexture(name, texwidth[j], texheight[j], IF_NOMIPMAP|IF_NOPICMIP|IF_LINEAR));
TEXASSIGN(pingtex[i][j], GL_AllocNewTexture(name, texwidth[j], texheight[j], IF_CLAMP|IF_NOMIPMAP|IF_NOPICMIP|IF_LINEAR));
}
GL_MTBind(0, GL_TEXTURE_2D, pingtex[i][j]);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texwidth[j], texheight[j], 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@ -180,7 +180,7 @@ qboolean R_CanBloom(void)
return false;
if (!gl_config.arb_shader_objects)
return false;
if (!r_config.texture_non_power_of_two)
if (!gl_config.texture_non_power_of_two_limited)
return false;
return true;

View file

@ -1075,10 +1075,14 @@ static qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_heigh
void GL_RoundDimensions(int *scaled_width, int *scaled_height, unsigned int flags)
{
if (r_config.texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
if (gl_config.texture_non_power_of_two) //NPOT is a simple extension that relaxes errors.
{
TRACE(("dbg: GL_RoundDimensions: GL_ARB_texture_non_power_of_two\n"));
}
else if (gl_config.texture_non_power_of_two_limited && (flags&IF_NOMIPMAP) && (flags&IF_CLAMP))
{
//clamped mipless textures will work as-is in gles2/webgl
}
else
{
int width = *scaled_width;
@ -1089,6 +1093,7 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, unsigned int flag
;
/*round npot textures down if we're running on an embedded system*/
/*
if (gl_config.gles)
{
if (*scaled_width != width)
@ -1096,6 +1101,7 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, unsigned int flag
if (*scaled_height != height)
*scaled_height >>= 1;
}
*/
}
if (flags & IF_NOMIPMAP)
@ -1251,10 +1257,10 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
{
glcolormode = GL_RGBA; /*our input is RGBA or RGBX, with the internal format restriction, we must therefore always have an alpha value*/
if (gl_config.webgl_ie)
{
if (1)//gl_config.webgl_ie)
{ //fixme: I think my npot mips don't work properly.
type = GL_UNSIGNED_BYTE;
glcolormode = GL_RGBA; //I hope its 1. note that samples matching colormode means we can't use packed formats, and I'm too lazy to strip it
glcolormode = GL_RGBA; //I hope alpha is 1. note that samples matching colormode means we can't use packed formats, and I'm too lazy to strip it
}
else if (flags & IF_NOALPHA)
{

View file

@ -544,7 +544,7 @@ void R_RenderScene (void)
#ifdef GL_STEREO
GLint glb;
qglGetIntegerv(GL_STEREO, &glb);
if (!glb)
if (!glb || !qglDrawBuffer)
#endif
stereomode = 0; //we are not a stereo context, so no stereoscopic rendering (this encourages it to otherwise be left enabled, which means the user is more likely to spot that they asked it to give a slower context.
}
@ -1283,7 +1283,7 @@ static void R_RenderMotionBlur(void)
shader_t *shader;
//figure out the size of our texture.
if (r_config.texture_non_power_of_two)
if (gl_config.texture_non_power_of_two_limited)
{ //we can use any size, supposedly
vwidth = vid.pixelwidth;
vheight = vid.pixelheight;
@ -1402,7 +1402,7 @@ qboolean R_RenderScene_Cubemap(void)
// prect.y = (vrect.y * vid.pixelheight)/vid.height;
// prect.height = (vrect.height * vid.pixelheight)/vid.height;
if (r_config.texture_non_power_of_two)
if (r_config.texture_non_power_of_two_limited)
{
if (prect.width < prect.height)
cmapsize = prect.width;
@ -1596,7 +1596,7 @@ void GLR_RenderView (void)
}
//disable stuff if its simply not supported.
if (dofbo || !gl_config.arb_shader_objects || !gl_config.ext_framebuffer_objects || !r_config.texture_non_power_of_two)
if (dofbo || !gl_config.arb_shader_objects || !gl_config.ext_framebuffer_objects || !gl_config.texture_non_power_of_two_limited)
r_refdef.flags &= ~(RDF_ALLPOSTPROC); //block all of this stuff

View file

@ -314,6 +314,10 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
else
{
float lhs;
if (*token >= '0' && *token <= '9')
lhs = strtod(token, NULL);
else
{
cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (cv)
{
@ -321,13 +325,10 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
lhs = cv->value;
}
else
{
if (*token < '0' || *token > '9')
{
Con_Printf("Shader_EvaluateCondition: '%s' is not a cvar\n", token);
return conditiontrue;
}
lhs = strtod(token, NULL);
}
if (*token)
token = COM_ParseExt(ptr, false, false);
@ -356,7 +357,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
else
{
if (cv)
conditiontrue = conditiontrue == !!cv->value;
conditiontrue = conditiontrue == !!lhs;
}
}
if (*token)

View file

@ -52,23 +52,23 @@ cvar_t r_shadow_shadowmapping_nearclip = CVAR("r_shadow_shadowmapping_nearclip",
cvar_t r_shadow_shadowmapping_bias = CVAR("r_shadow_shadowmapping_bias", "0.03");
cvar_t r_shadow_scissor = CVAR("r_shadow_scissor", "1");
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
cvar_t r_shadow_realtime_world = CVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = CVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = CVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
#ifdef FTE_TARGET_WEB
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight = CVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE);
#else
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight = CVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
#endif
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_ambient = SCVAR ("r_shadow_realtime_dlight_ambient", "0");
cvar_t r_shadow_realtime_dlight_diffuse = SCVAR ("r_shadow_realtime_dlight_diffuse", "1");
cvar_t r_shadow_realtime_dlight_specular = SCVAR ("r_shadow_realtime_dlight_specular", "4"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_editlights_import_radius = SCVAR ("r_editlights_import_radius", "1");
cvar_t r_editlights_import_ambient = SCVAR ("r_editlights_import_ambient", "0");
cvar_t r_editlights_import_diffuse = SCVAR ("r_editlights_import_diffuse", "1");
cvar_t r_editlights_import_specular = SCVAR ("r_editlights_import_specular", "1"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_shadow_shadowmapping = SCVARF ("r_shadow_shadowmapping", "1", 0);
cvar_t r_shadow_realtime_dlight_shadows = CVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_ambient = CVAR ("r_shadow_realtime_dlight_ambient", "0");
cvar_t r_shadow_realtime_dlight_diffuse = CVAR ("r_shadow_realtime_dlight_diffuse", "1");
cvar_t r_shadow_realtime_dlight_specular = CVAR ("r_shadow_realtime_dlight_specular", "4"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_editlights_import_radius = CVAR ("r_editlights_import_radius", "1");
cvar_t r_editlights_import_ambient = CVAR ("r_editlights_import_ambient", "0");
cvar_t r_editlights_import_diffuse = CVAR ("r_editlights_import_diffuse", "1");
cvar_t r_editlights_import_specular = CVAR ("r_editlights_import_specular", "1"); //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_shadow_shadowmapping = CVARD ("r_shadow_shadowmapping", "1", "Enables soft shadows");
cvar_t r_shadow_shadowmapping_precision = CVARD ("r_shadow_shadowmapping_precision", "1", "Scales the shadowmap detail level up or down.");
extern cvar_t r_shadow_shadowmapping_nearclip;
extern cvar_t r_shadow_shadowmapping_bias;
@ -88,7 +88,7 @@ void Sh_Reset(void)
#ifdef GLQUAKE
if (shadow_fbo_id)
{
qglDeleteRenderbuffersEXT(1, &shadow_fbo_id);
qglDeleteFramebuffersEXT(1, &shadow_fbo_id);
shadow_fbo_id = 0;
shadow_fbo_depth_num = 0;
}
@ -109,7 +109,7 @@ void Sh_Reset(void)
}
if (crepuscular_fbo_id)
{
qglDeleteRenderbuffersEXT(1, &crepuscular_fbo_id);
qglDeleteFramebuffersEXT(1, &crepuscular_fbo_id);
crepuscular_fbo_id = 0;
}
#endif
@ -772,6 +772,7 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
SHM_RecursiveWorldNodeQ1_r (dl, node->children[!side]);
}
#ifdef Q2BSPS
static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
{
int c, side;
@ -966,7 +967,6 @@ static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
SHM_RecursiveWorldNodeQ2_r (dl, node->children[!side]);
}
#ifdef Q2BSPS
static void SHM_MarkLeavesQ2(dlight_t *dl, unsigned char *lvis, unsigned char *vvis)
{
mnode_t *node;
@ -2025,7 +2025,9 @@ void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
// qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2);
// qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);
if (qglDrawBuffer)
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
if (qglReadBuffer)
qglReadBuffer(GL_NONE);
}
else
@ -2044,7 +2046,11 @@ void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
{
qglGenFramebuffersEXT(1, &shadow_fbo_id);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo_id);
if (qglDrawBuffers)
qglDrawBuffers(0, NULL);
else if (qglDrawBuffer)
qglDrawBuffer(GL_NONE);
if (qglReadBuffer)
qglReadBuffer(GL_NONE);
}
else
@ -2370,25 +2376,29 @@ qboolean Sh_GenShadowMap (dlight_t *l, qbyte *lvis, int smsize)
#ifdef DBG_COLOURNOTDEPTH
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
if (gl_config.gles)
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
#endif
}
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
#if 1//def DBG_COLOURNOTDEPTH
#if 0//def DBG_COLOURNOTDEPTH
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#else
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#endif
//in case we're using shadow samplers
if (gl_config.arb_shadow)
{
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
}
}
/*set framebuffer*/
GL_BeginRenderBuffer_DepthOnly(shadowmap[isspot]);
@ -3230,6 +3240,7 @@ void Sh_PurgeShadowMeshes(void)
}
free(edge);
edge = NULL;
maxedge = 0;
}
void Sh_PreGenerateLights(void)
@ -3309,8 +3320,14 @@ void Sh_CheckSettings(void)
{
#ifdef GLQUAKE
case QR_OPENGL:
canshadowless = true; //falls back to crappy texture env
if (gl_config.arb_shader_objects && gl_config.ext_framebuffer_objects && gl_config.arb_shadow)
canshadowless = gl_config.arb_shader_objects || !gl_config_nofixedfunc; //falls back to crappy texture env
if (!gl_config.arb_shader_objects)
Con_Printf("No arb_shader_objects\n");
if (!gl_config.ext_framebuffer_objects)
Con_Printf("No ext_framebuffer_objects\n");
if (!gl_config.arb_depth_texture)
Con_Printf("No arb_depth_texture\n");
if (gl_config.arb_shader_objects && gl_config.ext_framebuffer_objects && gl_config.arb_depth_texture)// && gl_config.arb_shadow)
cansmap = true;
if (gl_stencilbits)
canstencil = true;
@ -3337,14 +3354,12 @@ void Sh_CheckSettings(void)
break;
#endif
default:
r_shadow_realtime_world.ival = 0;
r_shadow_realtime_dlight.ival = 0;
return;
break;
}
if (!canstencil && !cansmap && !canshadowless)
{
//no shadow methods available at all.
//can't even do lighting
if (r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival)
Con_Printf("Missing driver extensions: realtime lighting is not possible.\n");
r_shadow_realtime_world.ival = 0;

View file

@ -181,8 +181,9 @@ void (APIENTRY *qglBindVertexArray)(GLuint vaoarray);
const GLubyte * (APIENTRY * qglGetStringi) (GLenum name, GLuint index);
void (APIENTRY * qglGetPointerv) (GLenum pname, GLvoid **parms);
void (APIENTRY *qglDrawBuffers)(GLsizei n, GLsizei *ids); //gl2
#ifndef GL_STATIC
void (APIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint* ids);
void (APIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint *ids);
void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id);
void (APIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId);
@ -442,8 +443,20 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
s++;
gl_minor_version = atoi(s);
}
if (webgl)
gl_major_version+=1;
if (webgl) //webgl version 1 equates to gles 2.
{
if (gl_major_version < 1)
{ //ie reports a bollocks version. don't try using fixed function stuff.
gl_major_version = 2;
gl_minor_version = 0;
}
else if (gl_major_version == 1)
gl_major_version += 1;
//webgl2 is not defined yet. either 2 will be gles3 or they'll skip it or something I don't know.
//so assume webgl2 is still equivelent to gles2, to avoid confusions.
}
//FIXME: verify gles3 works properly.
//yes, I know, this can't cope with minor versions of 10+... I don't care yet.
gl_config.glversion += gl_major_version + (gl_minor_version/10.f);
@ -577,22 +590,6 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglGenProgramsARB = NULL;
*/
r_config.texture_non_power_of_two = false;
gl_config.sgis_generate_mipmap = false;
gl_config.tex_env_combine = false;
gl_config.env_add = false;
gl_config.nv_tex_env_combine4 = false;
gl_config.arb_texture_env_combine = false;
gl_config.arb_texture_env_dot3 = false;
gl_config.arb_texture_cube_map = false;
gl_config.arb_shader_objects = false;
gl_config.ext_framebuffer_objects = false;
gl_config.ext_texture_filter_anisotropic = 0;
gl_config.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil");
if (GL_CheckExtension("GL_EXT_texture_filter_anisotropic"))
@ -603,7 +600,10 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
}
if (GL_CheckExtension("GL_ARB_texture_non_power_of_two") || GL_CheckExtension("GL_OES_texture_npot"))
r_config.texture_non_power_of_two = true;
gl_config.texture_non_power_of_two = true;
//gles2 has limited npot as standard, which is sufficient to make the hud not look like poo. lets use it.
if ((gl_config.gles && gl_config.glversion >= 2) || gl_config.texture_non_power_of_two)
gl_config.texture_non_power_of_two_limited = true;
// if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken.
// gl_config.sgis_generate_mipmap = true;
@ -950,11 +950,25 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglBindVertexArray = NULL;
}
if (gl_config.gles)
{ //gles has different TexImage2D arguments for specifying quality.
gl_config.arb_depth_texture = GL_CheckExtension("GL_OES_depth_texture"); //gles2
gl_config.arb_depth_texture |= GL_CheckExtension("GL_CHROMIUM_depth_texture"); //nacl
gl_config.arb_depth_texture |= GL_CheckExtension("GL_WEBGL_depth_texture"); //webgl. duh.
}
else
{
gl_config.arb_depth_texture = GL_CheckExtension("GL_ARB_depth_texture");
}
gl_config.arb_shadow = GL_CheckExtension("GL_ARB_shadow");
gl_config.arb_shadow |= GL_CheckExtension("GL_EXT_shadow_samplers"); //gles2
//gl_config.arb_shadow |= GL_CheckExtension("GL_EXT_shadow_samplers"); //gles2. nvidia fucks up. depend on brute-force. :s
#ifndef GL_STATIC
if (GL_CheckExtension("GL_ARB_framebuffer_object"))
#ifdef GL_STATIC
gl_config.ext_framebuffer_objects = true; //exists as core in gles2
#else
if ((gl_config.gles && gl_config.glversion >= 2) || //exists as core in gles2
(!gl_config.gles && gl_config.glversion >= 3) || //exists as core in gl3
GL_CheckExtension("GL_ARB_framebuffer_object")) //exists as an extension in gl2
{
gl_config.ext_framebuffer_objects = true;
qglGenFramebuffersEXT = (void *)getglext("glGenFramebuffers");
@ -2012,13 +2026,19 @@ void GL_Init(void *(*getglfunction) (char *name))
GL_CheckExtensions (getglfunction);
if ((gl_config.gles && gl_config.glversion >= 3) || (!gl_config.gles && gl_config.glversion >= 2))
qglDrawBuffers = (void *)getglext("glDrawBuffers");
else
qglDrawBuffers = NULL;
if (gl_config.gles && gl_config.glversion >= 2)
{
/*no matricies in gles, so don't try!*/
/*these functions do not exist in gles2, they only exist on some platforms because they were provided for gl1*/
qglLoadMatrixf = NULL;
qglPolygonMode = NULL;
qglShadeModel = NULL;
qglDepthRange = NULL;
qglDrawBuffer = NULL;
qglEnableClientState = GL_ClientStateStub;
qglDisableClientState = GL_ClientStateStub;
@ -2031,6 +2051,7 @@ void GL_Init(void *(*getglfunction) (char *name))
qglPolygonMode = NULL;
qglShadeModel = NULL;
qglDepthRange = NULL;
qglDrawBuffer = NULL;
qglEnableClientState = GL_ClientStateStub;
qglDisableClientState = GL_ClientStateStub;
@ -2044,11 +2065,6 @@ void GL_Init(void *(*getglfunction) (char *name))
if (qglShadeModel)
qglShadeModel (GL_FLAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
#ifdef DEBUG
if (qglDebugMessageControlARB)
qglDebugMessageControlARB(0, 0, 0, 0, NULL, true);

View file

@ -52,12 +52,6 @@ void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
void ClearBounds (vec3_t mins, vec3_t maxs);
//optional features common to all renderers, so I don't have to check to see which one it is all the time.
typedef struct {
qboolean texture_non_power_of_two;
} r_config_t;
extern r_config_t r_config;
#ifdef GLQUAKE
#if defined(ANDROID) /*FIXME: actually just to use standard GLES headers instead of full GL*/
#if 1
@ -218,10 +212,14 @@ typedef struct {
qboolean arb_texture_env_dot3;
qboolean arb_texture_cube_map;
qboolean texture_non_power_of_two; //full npot support.
qboolean texture_non_power_of_two_limited; //mipless,clamped npot works, but generic npot doesn't.
qboolean arb_texture_compression;
// qboolean arb_fragment_program;
qboolean arb_shader_objects;
qboolean arb_shadow;
qboolean arb_depth_texture;
qboolean ext_framebuffer_objects;
qboolean ext_stencil_wrap;
qboolean ext_packed_depth_stencil;
@ -731,6 +729,7 @@ extern void *(APIENTRY *qglMapBufferARB)(GLenum target, GLenum access);
extern GLboolean (APIENTRY *qglUnmapBufferARB)(GLenum target);
#endif
extern void (APIENTRY *qglDrawBuffers)(GLsizei n, GLsizei *ids); //gl2
//non-gles2 gl functions
extern void (APIENTRY *qglAccum) (GLenum op, GLfloat value);

View file

@ -13,8 +13,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT (some colour value)
"uniform float cvar_r_glsl_turbscale;\n"
"#ifndef FRESNEL\n"
"#define FRESNEL 5.0\n"
"#endif\n"
@ -49,6 +47,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float cvar_r_glsl_turbscale;\n"
"uniform sampler2D s_t0; //refract\n"
"uniform sampler2D s_t1; //normalmap\n"
"uniform sampler2D s_t2; //diffuse/reflection\n"
@ -176,7 +175,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//the bloom filter
//filter out any texels which are not to bloom
"uniform vec3 cvar_r_bloom_filter;\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
@ -188,6 +186,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform vec3 cvar_r_bloom_filter;\n"
"uniform sampler2D s_t0;\n"
"void main ()\n"
"{\n"
@ -199,7 +198,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef GLQUAKE
{QR_OPENGL, 110, "bloom_final",
"!!cvarf r_bloom\n"
"uniform float cvar_r_bloom;\n"
//add them together
//optionally apply tonemapping
@ -218,6 +216,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform sampler2D s_t1;\n"
"uniform sampler2D s_t2;\n"
"uniform sampler2D s_t3;\n"
"uniform float cvar_r_bloom;\n"
"void main ()\n"
"{\n"
"gl_FragColor = \n"
@ -1695,6 +1694,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvardf r_glsl_pcf\n"
"#ifndef USE_ARB_SHADOW\n"
//fall back on regular samplers if we must
"#define sampler2DShadow sampler2D\n"
"#endif\n"
//this is the main shader responsible for realtime dlights.
//texture units:
@ -1706,7 +1710,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//CUBESHADOW
"#ifndef r_glsl_pcf\n"
"#error r_glsl_pcf wasn't defined\n"
"#error r_glsl_pcf wasnt defined\n"
"#endif\n"
"#if r_glsl_pcf < 1\n"
"#undef r_glsl_pcf\n"
@ -1728,12 +1732,15 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
"varying vec4 vtexprojcoord;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#if defined(PCF) || defined(CUBE) || defined(SPOT)\n"
"uniform mat4 l_cubematrix;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"uniform vec3 l_lightposition;\n"
"attribute vec2 v_texcoord;\n"
@ -1872,7 +1879,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.\n"
"#else\n"
"#ifdef USE_ARB_SHADOW\n"
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r\n"
"#else\n"
//this will probably be a bit blocky.
"#define dosamp(x,y) float(texture2D(s_t4, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)\n"
"#endif\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
"s += dosamp(0.0, 0.0);\n"
@ -1973,6 +1986,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3D9QUAKE

View file

@ -638,11 +638,14 @@ typedef struct
extern sh_config_t sh_config;
#ifdef GLSLONLY
#define gl_config_nofixedfunc true
#define gl_config_gles true
#define gl_config_nofixedfunc true
#else
#define gl_config_nofixedfunc gl_config.nofixedfunc
#define gl_config_gles gl_config.gles
#define gl_config_nofixedfunc gl_config.nofixedfunc
#endif
#ifdef GLESONLY
#define gl_config_gles true
#else
#define gl_config_gles gl_config.gles
#endif
#ifdef GLQUAKE

View file

@ -265,7 +265,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_EndRendering();
GL_DoSwap();
GLVID_SwapBuffers();
// vid.pixelwidth = info->width;
// vid.pixelheight = info->height;
@ -280,7 +280,7 @@ void GLVID_Shutdown (void)
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GL_EndRendering();
GL_DoSwap();
GLVID_SwapBuffers();
ppb_core->ReleaseResource(glcontext);
// glTerminatePPAPI();

View file

@ -319,7 +319,7 @@ void startquake(char *manif)
args[parms.argc++] = manif;
}
Sys_Printf("Starting up\n");
Sys_Printf("Starting up (Built "__DATE__ ", " __TIME__")\n");
COM_InitArgv(parms.argc, parms.argv);
TL_InitLanguages();

View file

@ -2295,7 +2295,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, float killonspawnfl
}
}
else
Sys_Error("Command %s not recognised", qcc_token);
Sys_Error("Bad entity lump: '%s' not recognised (last ent was %i)", qcc_token, ed?ed->entnum:0);
}
if (resethunk)
{

View file

@ -891,7 +891,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
}
#endif
f = FS_OpenVFS (name, "wb", FS_GAMEONLY);
f = FS_OpenVFS (name, "wbp", FS_GAMEONLY);
if (!f)
{
Con_TPrintf ("ERROR: couldn't open %s.\n", name);

View file

@ -1325,7 +1325,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
#ifdef VM_Q1
if (svs.gametype != GT_Q1QVM) //we cannot do this with qvm
#endif
svprogfuncs->SetStringField(svprogfuncs, ent, &ent->v->model, sv.world.worldmodel->name, true);
svprogfuncs->SetStringField(svprogfuncs, ent, &ent->v->model, sv.strings.model_precache[1], true);
ent->v->modelindex = 1; // world model
ent->v->solid = SOLID_BSP;
ent->v->movetype = MOVETYPE_PUSH;
@ -1400,6 +1400,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
// load and spawn all other entities
SCR_SetLoadingFile("entities");
if (!deathmatch.value && !*skill.string) //skill was left blank so it doesn't polute serverinfo on deathmatch servers. in single player, we ensure that it gets a proper value.
Cvar_Set(&skill, "1");
if (progstype == PROG_H2)
{
extern cvar_t coop;

View file

@ -6,8 +6,6 @@
//modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT (some colour value)
uniform float cvar_r_glsl_turbscale;
#ifndef FRESNEL
#define FRESNEL 5.0
#endif
@ -42,6 +40,7 @@ void main (void)
}
#endif
#ifdef FRAGMENT_SHADER
uniform float cvar_r_glsl_turbscale;
uniform sampler2D s_t0; //refract
uniform sampler2D s_t1; //normalmap
uniform sampler2D s_t2; //diffuse/reflection

View file

@ -2,7 +2,6 @@
//the bloom filter
//filter out any texels which are not to bloom
uniform vec3 cvar_r_bloom_filter;
varying vec2 tc;
#ifdef VERTEX_SHADER
@ -14,6 +13,7 @@ void main ()
}
#endif
#ifdef FRAGMENT_SHADER
uniform vec3 cvar_r_bloom_filter;
uniform sampler2D s_t0;
void main ()
{

View file

@ -1,5 +1,4 @@
!!cvarf r_bloom
uniform float cvar_r_bloom;
//add them together
//optionally apply tonemapping
@ -18,6 +17,7 @@ uniform sampler2D s_t0;
uniform sampler2D s_t1;
uniform sampler2D s_t2;
uniform sampler2D s_t3;
uniform float cvar_r_bloom;
void main ()
{
gl_FragColor =

View file

@ -7,6 +7,11 @@
!!cvardf r_glsl_pcf
#ifndef USE_ARB_SHADOW
//fall back on regular samplers if we must
#define sampler2DShadow sampler2D
#endif
//this is the main shader responsible for realtime dlights.
//texture units:
@ -18,7 +23,7 @@
//CUBESHADOW
#ifndef r_glsl_pcf
#error r_glsl_pcf wasn't defined
#error r_glsl_pcf wasnt defined
#endif
#if r_glsl_pcf < 1
#undef r_glsl_pcf
@ -40,12 +45,15 @@ varying vec3 lightvector;
#if defined(SPECULAR) || defined(OFFSETMAPPING)
varying vec3 eyevector;
#endif
#if defined(PCF) || defined(CUBE) || defined(SPOT)
varying vec4 vtexprojcoord;
#endif
#ifdef VERTEX_SHADER
#if defined(PCF) || defined(CUBE) || defined(SPOT)
uniform mat4 l_cubematrix;
#endif
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
uniform vec3 l_lightposition;
attribute vec2 v_texcoord;
@ -184,7 +192,13 @@ float ShadowmapFilter(void)
return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
#else
#ifdef USE_ARB_SHADOW
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r
#else
//this will probably be a bit blocky.
#define dosamp(x,y) float(texture2D(s_t4, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)
#endif
float s = 0.0;
#if r_glsl_pcf >= 1 && r_glsl_pcf < 5
s += dosamp(0.0, 0.0);
@ -285,3 +299,4 @@ void main ()
gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);
}
#endif

View file

@ -64,6 +64,15 @@ static qboolean QDECL VFSWEB_Close(vfsfile_t *file)
Z_Free(file);
return true;
}
static qboolean QDECL VFSWEB_ClosePersist(vfsfile_t *file)
{
vfswebfile_t *intfile = (vfswebfile_t*)file;
#ifdef _DEBUG
Con_DPrintf("Persisting file %s\n", file->dbgname);
#endif
emscriptenfte_buf_pushtolocalstore(intfile->handle);
return VFSWEB_Close(file);
}
vfsfile_t *FSWEB_OpenTemp(void)
{
@ -99,11 +108,13 @@ vfsfile_t *VFSWEB_Open(const char *osname, const char *mode, qboolean *needsflus
vfswebfile_t *file;
//qboolean read = !!strchr(mode, 'r');
qboolean write = !!strchr(mode, 'w');
qboolean update = !!strchr(mode, '+');
qboolean append = !!strchr(mode, 'a');
qboolean persist = !!strchr(mode, 'p');
if (needsflush)
*needsflush = false;
f = emscriptenfte_buf_open(osname, write||append);
f = emscriptenfte_buf_open(osname, (write && !update)?2:(write||append));
if (f == -1)
return NULL;
@ -122,6 +133,9 @@ vfsfile_t *VFSWEB_Open(const char *osname, const char *mode, qboolean *needsflus
file->funcs.Seek = VFSWEB_Seek;
file->funcs.Tell = VFSWEB_Tell;
file->funcs.GetLen = VFSWEB_GetSize;
if (persist && (write || append))
file->funcs.Close = VFSWEB_ClosePersist;
else
file->funcs.Close = VFSWEB_Close;
file->funcs.Flush = VFSWEB_Flush;
file->handle = f;
@ -233,7 +247,7 @@ static void QDECL FSWEB_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, ch
result = VFS_READ(f, buffer, loc->len); // do soemthing with result
if (result != loc->len)
Con_Printf("FSWEB_ReadFile() fread: Filename: %s, expected %i, result was %u \n",loc->rawname,loc->len,(unsigned int)result);
Con_Printf("FSWEB_ReadFile() fread: Filename: %s, expected %u, result was %u \n",loc->rawname,(unsigned int)loc->len,(unsigned int)result);
VFS_CLOSE(f);
}

View file

@ -1,23 +1,25 @@
//emscripten's download mechanism lacks usable progress indicators.
void emscriptenfte_async_wget_data2(const char *url, void *ctx, void (*onload)(void*ctx,void*buf,int sz), void (*onerror)(void*ctx,int code), void (*onprogress)(void*ctx,int prog,int total));
//filesystem buffers are implemented in javascript so that we are not bound by power-of-two heap limitations quite so much.
//also, we can't use emscripten's stdio because it reserves 16m file handles or something.
//these buffers do not track file offsets nor file access permissions.
int emscriptenfte_buf_create(void);
int emscriptenfte_buf_open(const char *name, int createifneeded);
int emscriptenfte_buf_rename(const char *oldname, const char *newname);
int emscriptenfte_buf_delete(const char *fname);
void emscriptenfte_buf_release(int handle);
unsigned int emscriptenfte_buf_getsize(int handle);
int emscriptenfte_buf_read(int handle, int offset, void *data, int len);
int emscriptenfte_buf_write(int handle, int offset, const void *data, int len);
int emscriptenfte_buf_open(const char *name, int createifneeded); //open
int emscriptenfte_buf_rename(const char *oldname, const char *newname); //rename files (if it was open, the handle now refers to the new file instead)
int emscriptenfte_buf_delete(const char *fname); //delete the named file. there may be problems if its currently open
void emscriptenfte_buf_release(int handle); //close
void emscriptenfte_buf_pushtolocalstore(int handle); //make a copy in the browser's local storage, if possible.
unsigned int emscriptenfte_buf_getsize(int handle); //get the size of the file buffer
int emscriptenfte_buf_read(int handle, int offset, void *data, int len);//read data
int emscriptenfte_buf_write(int handle, int offset, const void *data, int len);//write data. no access checks.
//websocket is implemented in javascript because there is no usable C api (emscripten's javascript implementation is shite).
int emscriptenfte_ws_connect(const char *url);
void emscriptenfte_ws_close(int sockid);
int emscriptenfte_ws_cansend(int sockid, int extra, int maxpending);
int emscriptenfte_ws_send(int sockid, const void *data, int len);
int emscriptenfte_ws_recv(int sockid, void *data, int len);
//websocket is implemented in javascript because there is no usable C api (emscripten's javascript implementation is shite and has fatal errors).
int emscriptenfte_ws_connect(const char *url); //open a websocket connect to a specific host
void emscriptenfte_ws_close(int sockid); //close it again
int emscriptenfte_ws_cansend(int sockid, int extra, int maxpending); //returns false if we're blocking for some reason. avoids overflowing. everything is otherwise reliable.
int emscriptenfte_ws_send(int sockid, const void *data, int len); //send data to the peer. queues data. never dropped.
int emscriptenfte_ws_recv(int sockid, void *data, int len); //receive data from the peer.
//misc stuff for printf replacements
void emscriptenfte_alert(const char *msg);
@ -33,6 +35,7 @@ int emscriptenfte_setupcanvas(
void(*Resized)(int newwidth, int newheight),
void(*Mouse)(int devid,int abs,float x,float y,float z,float size),
void(*Button)(int devid, int down, int mbutton),
int(*Keyboard)(int devid, int down, int keycode, int unicode)
int(*Keyboard)(int devid, int down, int keycode, int unicode),
void(*Hash)(char *newhash)
);

View file

@ -11,13 +11,14 @@ mergeInto(LibraryManager.library,
$FTEC:
{
linebuffer:'',
w: -1,
h: -1,
donecb:0,
evcb: {
resize:0,
mouse:0,
key:0,
key:0
},
handleevent : function(event)
@ -101,12 +102,13 @@ mergeInto(LibraryManager.library,
}
},
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser'],
emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk)
emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk,evh)
{
FTEC.evcb.resize = evresz;
FTEC.evcb.mouse = evm;
FTEC.evcb.button = evb;
FTEC.evcb.key = evk;
FTEC.evcb.hashchange = evh;
if (!FTEC.donecb)
{
FTEC.donecb = 1;
@ -128,21 +130,36 @@ mergeInto(LibraryManager.library,
var ctx = Browser.createContext(Module['canvas'], true, true);
if (!ctx)
return 0;
Browser.setCanvasSize(nw, nh, false);
// Browser.setCanvasSize(nw, nh, false);
window.onresize = function()
{
//emscripten's browser library will revert sizes wrongly or something when we're fullscreen, so make sure that doesn't happen.
if (Browser.isFullScreen)
{
Browser.windowedWidth = window.innerWidth;
Browser.windowedHeight = window.innerHeight;
}
else
// if (Browser.isFullScreen)
// {
// Browser.windowedWidth = window.innerWidth;
// Browser.windowedHeight = window.innerHeight;
// }
// else
Browser.setCanvasSize(window.innerWidth, window.innerHeight, false);
if (FTEC.evcb.resize != 0)
Runtime.dynCall('vii', FTEC.evcb.resize, [Module['canvas'].width, Module['canvas'].height]);
};
window.onresize();
if (FTEC.evcb.hashchange)
window.onhashchange = function()
{
if (FTEC.evcb.hashchange != 0)
{
var val = location.hash;
var ptr = _malloc(val.length);
writeStringToMemory(val, ptr);
Runtime.dynCall('vi', FTEC.evcb.hashchange, [ptr]);
_free(ptr);
}
};
return 1;
},
@ -161,7 +178,15 @@ mergeInto(LibraryManager.library,
//FIXME: split+merge by \n
emscriptenfte_print : function(msg)
{
console.log(Pointer_stringify(msg));
FTEC.linebuffer += Pointer_stringify(msg);
for(;;)
{
nl = FTEC.linebuffer.indexOf("\n");
if (nl == -1)
break;
console.log(FTEC.linebuffer.substring(0, nl));
FTEC.linebuffer = FTEC.linebuffer.substring(nl+1);
}
},
emscriptenfte_ticks_ms : function()
{
@ -192,7 +217,7 @@ mergeInto(LibraryManager.library,
b.h = _emscriptenfte_handle_alloc(b);
return b.h;
},
//temp files
//filesystem emulation
emscriptenfte_buf_open__deps : ['emscriptenfte_buf_create'],
emscriptenfte_buf_open : function(name, createifneeded)
{
@ -201,6 +226,25 @@ mergeInto(LibraryManager.library,
var r = -1;
if (f == null)
{
if (window.localStorage && createifneeded != 2)
{
var str = window.localStorage.getItem(name);
if (str != null)
{
console.log('read file '+name+': ' + str);
var len = str.length;
var buf = new Uint8Array(len);
for (var i = 0; i < len; i++)
buf[i] = str.charCodeAt(i);
var b = {h:-1, r:2, l:len,m:len,d:buf, n:name};
r = b.h = _emscriptenfte_handle_alloc(b);
FTEH.f[name] = b;
return b.h;
}
}
if (createifneeded)
r = _emscriptenfte_buf_create();
if (r != -1)
@ -218,6 +262,8 @@ mergeInto(LibraryManager.library,
f.r+=1;
r = f.h;
}
if (f != null && createifneeded == 2)
f.l = 0; //truncate it.
return r;
},
emscriptenfte_buf_rename : function(oldname, newname)
@ -248,6 +294,30 @@ console.log('deleted '+name);
}
return 0;
},
emscriptenfte_buf_pushtolocalstore : function(handle)
{
var b = FTEH.h[handle];
if (b == null)
{
Module.printError('emscriptenfte_buf_pushtolocalstore with invalid handle');
return;
}
if (b.n == null)
return;
var data = b.d;
var len = b.l;
if (window.localStorage)
{
var foo = "";
//use a divide and conquer implementation instead for speed?
for (var i = 0; i < len; i++)
foo += String.fromCharCode(data[i]);
window.localStorage.setItem(b.n, foo);
console.log('saved '+b.n+' persistantly: '+foo);
}
else
console.log('local storage not supported');
},
emscriptenfte_buf_release : function(handle)
{
var b = FTEH.h[handle];

View file

@ -35,7 +35,7 @@ static unsigned int domkeytoquake(unsigned int code)
/* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0,
/* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0,0,0,0,K_ESCAPE,0,0,0,0,
/* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0,
/* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,0,0,0,
/* 48*/ '0','1','2','3','4','5','6','7', '8','9',0,0,0,'=',0,0,
/* 64*/ 0,'a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o',
/* 80*/ 'p','q','r','s','t','u','v','w', 'x','y','z',K_LWIN,K_RWIN,K_APP,0,0,
@ -43,7 +43,7 @@ static unsigned int domkeytoquake(unsigned int code)
/*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8,K_F9,K_F10,K_F11,K_F12,0,0,0,0,
/*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*160*/ 0,0,0,'#',0,0,0,0, 0,0,0,0,0,0,0,0,
/*160*/ 0,0,0,'#',0,0,0,0, 0,0,0,0,0,'-',0,0,
/*176*/ 0,0,0,0,0,0,0,0, 0,0,';','=',',','-','.','/',
/*192*/ '`',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'[','\\',']','\'','`',
@ -70,7 +70,7 @@ static unsigned int domkeytoshift(unsigned int code)
/* 0*/ 0,0,0,0,0,0,0,0, K_BACKSPACE,K_TAB,0,0,0,K_ENTER,0,0,
/* 16*/ K_SHIFT,K_CTRL,K_ALT,K_PAUSE,K_CAPSLOCK,0,0,0,0,0,0,K_ESCAPE,0,0,0,0,
/* 32*/ ' ',K_PGUP,K_PGDN,K_END,K_HOME,K_LEFTARROW,K_UPARROW,K_RIGHTARROW, K_DOWNARROW,0,0,0,K_PRINTSCREEN,K_INS,K_DEL,0,
/* 48*/ ')','!','\"',0/*£*/,'$','%','^','&', '*','(',0,0,0,0,0,0,
/* 48*/ ')','!','\"',0/*£*/,'$','%','^','&', '*','(',0,0,0,'+',0,0,
/* 64*/ 0,'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O',
/* 80*/ 'P','Q','R','S','T','U','V','W', 'X','Y','Z',K_LWIN,K_RWIN,K_APP,0,0,
@ -78,7 +78,7 @@ static unsigned int domkeytoshift(unsigned int code)
/*112*/ K_F1,K_F2,K_F3,K_F4,K_F5,K_F6,K_F7,K_F8,K_F9,K_F10,K_F11,K_F12,0,0,0,0,
/*128*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*144*/ K_KP_NUMLOCK,K_SCRLCK,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*160*/ 0,0,0,'~',0,0,0,0, 0,0,0,0,0,0,0,0,
/*160*/ 0,0,0,'~',0,0,0,0, 0,0,0,0,0,'_',0,0,
/*176*/ 0,0,0,0,0,0,0,0, 0,0,':','+','<','_','>','?',
/*192*/ '`',0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
/*208*/ 0,0,0,0,0,0,0,0, 0,0,0,'{','|','}','@','`',
@ -151,7 +151,11 @@ static void DOM_ButtonEvent(int devid, int down, int button)
IN_KeyEvent(0, down, K_MOUSE1+button, 0);
}
}
void DOM_HashChanged(char *loc)
{
//try and open it. generally downloading it from the server.
Host_RunFile(loc+1, strlen(loc+1), NULL);
}
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
{
int flags;
@ -164,7 +168,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
VID_Resized,
IN_MouseMove,
DOM_ButtonEvent,
DOM_KeyEvent
DOM_KeyEvent,
DOM_HashChanged
))
{
Con_Printf("Couldn't set up canvas\n");
@ -177,6 +182,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
VID_Resized(vid.pixelwidth, vid.pixelheight);
mouseactive = false;
return true;
@ -186,7 +193,7 @@ void GLVID_DeInit (void)
{
ActiveApp = false;
emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL);
emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL);
}

View file

@ -1,20 +1,18 @@
Module['preRun'] = function()
{
//FS.createPath('/', 'id1', true, true);
//FS.createPath('/', 'qw', true, true);
//FS.createPath('/', 'fte', true, true);
//FS.createPath('/', 'tmp', true, true);
//FS.createPreloadedFile('/id1/', 'pak0.pak', '/pak0.pak', true, false);
//FS.createPreloadedFile('/id1/', 'pak1.pak', '/pak1.pak', true, false);
//FS.createPreloadedFile('/id1/', 'pak2.pak', '/pak2.pak', true, false);
//FS.createPreloadedFile('/id1/', 'pak3.pak', '/pak3.pak', true, false);
};
Module['arguments'] = ['-nohome', '-manifest', document.location + '.fmf'];
// use query string in URL as command line
if (!document.referrer) {
{
Module['arguments'] = ['-nohome'];
var man = window.location.protocol+'//'+window.location.host+window.location.pathname + '.fmf';
if (window.location.hash != "")
man = window.location.hash.substring(1);
Module['arguments'] = Module['arguments'].concat(['-manifest', man]);
// use query string in URL as command line
if (!document.referrer) {
qstring = decodeURIComponent(window.location.search.substring(1)).split(" ");
Module['arguments'] = Module['arguments'].concat(qstring);
}
}