added support for external capture plugins - and using avcodec as a plugin.c.

The ragdoll API is potentially usable now, but still really limited.
Enabled SQL requests by default using sqlite. Note that you'll need the sqlite dll to use this. MySQL should still be usable, but I didn't try. MySQL requires -DUSE_MYSQL to compile it, and a dll and -mysql argument to enable it.
Fixed nacl.
NPFTE plugin now invokes an exe to run the game rather than running the game within the browser.
externvalue builtin now accepts & prefix to return a pointer instead.
Fixed vector autocvars.
uri_get, bufstr_add, bufstr_free, now functional.
QC debugger can now show asm if line numbers are not available.
Added support for QC watchpoints. Use the watchpoint command.
gl_specular now give specular even without rtlights, thankfully not as blatently, but its there.
android will not crash due to supported audio formats, and gles2 can be selected via a cvar (requires full FTEDroidActivity/program restart).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4152 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-11-27 03:23:19 +00:00
parent 705e1ab0e0
commit 53a7b3d47c
159 changed files with 17179 additions and 30191 deletions

View file

@ -28,6 +28,35 @@ Note that there is no way to install the package with a different name at this t
Browser versions of FTE:
The FTE browser plugin is available only in windows.
Compile with 'make npfte-rel FTE_TARGET=win32'.
This will yield an npfte.dll file.
You can 'register' this dll by running 'regsvr32 npfte.dll' at a command prompt (this is the standard way to register an activex control - any setup software should provide some mechanism to do this at install time). This will register both the netscape/firefox/chrome/opera version, and the activex/IE version of the plugin.
Note that the plugin will run the engine in a separate process and thus requires a valid fteqw.exe file in the same directory as the plugin.
If given an 'npfte.txt' file that contains the line 'relexe foo', the plugin will try to run foo.exe instead of fteqw, basedir "foo" can be used to invoke it with a different basedir. You can use this if you'd rather run the mingl or gl-only version, or if you'd like to retarget npfte to invoke a different quake engine intead. Note that different quake engines will need to support the -plugin argument and the stdin/stdout parsing for embedding - at the time of writing, no others do.
The following chunk of html can then be included on a web page to embed it. Yes. Two nested objects.
<object name="ieplug" type="text/x-quaketvident" classid="clsid:7d676c9f-fb84-40b6-b3ff-e10831557eeb" width=100% height=100% ><param name="splash" value="http://127.0.0.1:27599/qtvsplash.jpg"><param name="game" value="q1"><param name="dataDownload" value=''><object name="npplug" type="text/x-quaketvident" width=100% height=100% ><param name="splash" value="http://127.0.0.1:27599/qtvsplash.jpg"><param name="game" value="q1"><param name="dataDownload" value=''>Plugin failed to load</object></object>
Nacl version of FTE:
make gl-rel FTE_TARGET=nacl NACL_SDK_ROOT=SOMEVALIDPATHHERE BITS=32
make gl-rel FTE_TARGET=nacl NACL_SDK_ROOT=SOMEVALIDPATHHERE BITS=64
in windows compile with cygwin, not minsys.
This will give you two 'nexe' files.
You can then embed the 'fteqw.nmf' file (its entire contents can be found on the following line) with mime type 'application/x-nacl' on your page. Give it a sane width/height.
{
"program": {
"x86-64": {"url": "fteqw_x86_64.nexe"},
"x86-32": {"url": "fteqw_x86_32.nexe"}
}
}
You can object.postMessage("join foo") / qtvplay / map to tell it to switch server/map/stream.
You can read console prints via listener.addEventListener('message', handleMessage, true);
Your users will need to explicitly allow nacl use outside of google play (in about:config or whatever it is), or you will need to submit your port of fte to google play.
This stuff has separate directories This stuff has separate directories
engine: FTEQW game engine itself. Both client and dedicated server. engine: FTEQW game engine itself. Both client and dedicated server.
engine/ftequake: location of old msvc6 project file. Might not work. engine/ftequake: location of old msvc6 project file. Might not work.

View file

@ -537,6 +537,7 @@ SERVER_OBJS = \
sv_ents.o \ sv_ents.o \
sv_send.o \ sv_send.o \
sv_user.o \ sv_user.o \
sv_sql.o \
sv_mvd.o \ sv_mvd.o \
sv_ccmds.o \ sv_ccmds.o \
sv_rankin.o \ sv_rankin.o \
@ -664,6 +665,8 @@ endif
#specific targets override those defaults as needed. #specific targets override those defaults as needed.
#google native client #google native client
ifeq ($(FTE_TARGET),nacl) ifeq ($(FTE_TARGET),nacl)
OGGVORBISLDFLAGS=
ifeq ($(shell uname -o 2>&1 | grep Cygwin),) ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
CC=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS) CC=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS)
STRIP=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-strip STRIP=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-strip

View file

@ -697,7 +697,7 @@ void Cam_TrackPlayer(int pnum, char *cmdname, char *plrarg)
c = plrarg; c = plrarg;
while (*c) while (*c)
{ {
if (!isdigit(*c)) if (*c < '0' || *c > '9')
{ {
Con_Printf("Couldn't find nick %s\n", plrarg); Con_Printf("Couldn't find nick %s\n", plrarg);
return; return;

View file

@ -34,7 +34,7 @@ char lastdemoname[256];
extern cvar_t qtvcl_forceversion1; extern cvar_t qtvcl_forceversion1;
extern cvar_t qtvcl_eztvextensions; extern cvar_t qtvcl_eztvextensions;
unsigned char demobuffer[1024*16]; unsigned char demobuffer[1024*66];
int demobuffersize; int demobuffersize;
int demopreparsedbytes; int demopreparsedbytes;
qboolean disablepreparse; qboolean disablepreparse;
@ -325,20 +325,19 @@ void CL_DemoJump_f(void)
if (!cls.demoplayback) if (!cls.demoplayback)
return; return;
if (*s == '+') if (*s == '+' || *s == '-')
{ {
if (colon) if (colon)
{ {
colon++; colon++;
demtime += atoi(colon); newtime = demtime + atoi(colon) + atoi(s)*60;
demtime += atoi(s)*60;
} }
else else
demtime += atoi(s); newtime = demtime + atoi(s);
} }
else else
{ {
//absolute seek time
if (colon) if (colon)
{ {
colon++; colon++;
@ -347,16 +346,17 @@ void CL_DemoJump_f(void)
} }
else else
newtime = atoi(s); newtime = atoi(s);
}
if (newtime >= demtime) if (newtime >= demtime)
demtime = newtime; demtime = newtime;
else else
{ {
Con_Printf("Rewinding demo\n"); Con_Printf("Rewinding demo\n");
CL_PlayDemo(lastdemoname); CL_PlayDemo(lastdemoname);
demtime = newtime; //now fastparse it.
} demtime = newtime;
} }
} }

View file

@ -2242,9 +2242,9 @@ void CL_LinkStaticEntities(void *pvs)
if ((!r_drawflame.ival) && (clmodel->engineflags & MDLF_FLAME)) if ((!r_drawflame.ival) && (clmodel->engineflags & MDLF_FLAME))
continue; continue;
/*pvs test*/
if (pvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &cl_static_entities[i].pvscache, pvs)) if (pvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &cl_static_entities[i].pvscache, pvs))
continue; continue;
/*pvs test*/
ent = &cl_visedicts[cl_numvisedicts++]; ent = &cl_visedicts[cl_numvisedicts++];
*ent = *stat; *ent = *stat;
@ -3255,11 +3255,13 @@ void CL_ParsePlayerinfo (void)
TP_ParsePlayerInfo(oldstate, state, info); TP_ParsePlayerInfo(oldstate, state, info);
//can't CL_SetStatInt as we don't know if its actually us or not
cl.players[num].stats[STAT_WEAPONFRAME] = state->weaponframe; cl.players[num].stats[STAT_WEAPONFRAME] = state->weaponframe;
cl.players[num].statsf[STAT_WEAPONFRAME] = state->weaponframe; cl.players[num].statsf[STAT_WEAPONFRAME] = state->weaponframe;
for (i = 0; i < cl.splitclients; i++) for (i = 0; i < cl.splitclients; i++)
{ {
if (cl.playernum[i] == num) if (spec_track[i] == num)
{ {
cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe; cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe; cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe;
@ -3484,9 +3486,10 @@ guess_pm_type:
TP_ParsePlayerInfo(oldstate, state, info); TP_ParsePlayerInfo(oldstate, state, info);
//can't CL_SetStatInt as we don't know if its actually us or not
for (i = 0; i < cl.splitclients; i++) for (i = 0; i < cl.splitclients; i++)
{ {
if (cl.playernum[i] == num) if (spec_track[i] == num)
{ {
cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe; cl.playerview[i].stats[STAT_WEAPONFRAME] = state->weaponframe;
cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe; cl.playerview[i].statsf[STAT_WEAPONFRAME] = state->weaponframe;
@ -3729,6 +3732,7 @@ void CL_LinkPlayers (void)
{ {
vec3_t org; vec3_t org;
VectorCopy(state->origin, org); VectorCopy(state->origin, org);
//make the light appear at the predicted position rather than anywhere else.
for (pnum = 0; pnum < cl.splitclients; pnum++) for (pnum = 0; pnum < cl.splitclients; pnum++)
if (cl.playernum[pnum] == j) if (cl.playernum[pnum] == j)
VectorCopy(cl.playerview[pnum].simorg, org); VectorCopy(cl.playerview[pnum].simorg, org);

View file

@ -102,7 +102,7 @@ extern int total_loading_size, current_loading_size, loading_stage;
// //
// info mirrors // info mirrors
// //
cvar_t password = CVARF("password", "", CVAR_USERINFO | CVAR_NOUNSAFEEXPAND); //this is parhaps slightly dodgy... cvar_t password = CVARAF("password", "", "pq_password", CVAR_USERINFO | CVAR_NOUNSAFEEXPAND); //this is parhaps slightly dodgy... added pq_password alias because baker seems to be using this for user accounts.
cvar_t spectator = CVARF("spectator", "", CVAR_USERINFO); cvar_t spectator = CVARF("spectator", "", CVAR_USERINFO);
cvar_t name = CVARFC("name", "unnamed", CVAR_ARCHIVE | CVAR_USERINFO, Name_Callback); cvar_t name = CVARFC("name", "unnamed", CVAR_ARCHIVE | CVAR_USERINFO, Name_Callback);
cvar_t team = CVARF("team", "", CVAR_ARCHIVE | CVAR_USERINFO); cvar_t team = CVARF("team", "", CVAR_ARCHIVE | CVAR_USERINFO);
@ -1089,6 +1089,7 @@ void CL_ClearState (void)
CL_ClearParseState(); CL_ClearParseState();
CL_ClearTEnts(); CL_ClearTEnts();
CL_ClearCustomTEnts(); CL_ClearCustomTEnts();
Surf_ClearLightmaps();
T_FreeInfoStrings(); T_FreeInfoStrings();
SCR_ShowPic_Clear(); SCR_ShowPic_Clear();
@ -1135,6 +1136,7 @@ void CL_ClearState (void)
cl.allocated_client_slots = QWMAX_CLIENTS; cl.allocated_client_slots = QWMAX_CLIENTS;
#ifndef CLIENTONLY #ifndef CLIENTONLY
//FIXME: we should just set it to 0 to make sure its set up properly elsewhere.
if (sv.state) if (sv.state)
cl.allocated_client_slots = sv.allocated_client_slots; cl.allocated_client_slots = sv.allocated_client_slots;
#endif #endif
@ -3406,6 +3408,8 @@ Writes key bindings and archived cvars to config.cfg
void Host_WriteConfiguration (void) void Host_WriteConfiguration (void)
{ {
vfsfile_t *f; vfsfile_t *f;
char savename[MAX_OSPATH];
char sysname[MAX_OSPATH];
if (host_initialized && cfg_save_name.string && *cfg_save_name.string) if (host_initialized && cfg_save_name.string && *cfg_save_name.string)
{ {
@ -3415,7 +3419,9 @@ void Host_WriteConfiguration (void)
return; return;
} }
f = FS_OpenVFS(va("%s.cfg",cfg_save_name.string), "wb", FS_GAMEONLY); Q_snprintfz(savename, sizeof(savename), "%s.cfg", cfg_save_name.string);
f = FS_OpenVFS(savename, "wb", FS_GAMEONLY);
if (!f) if (!f)
{ {
Con_TPrintf (TLC_CONFIGCFG_WRITEFAILED); Con_TPrintf (TLC_CONFIGCFG_WRITEFAILED);
@ -3426,6 +3432,9 @@ void Host_WriteConfiguration (void)
Cvar_WriteVariables (f, false); Cvar_WriteVariables (f, false);
VFS_CLOSE (f); VFS_CLOSE (f);
FS_NativePath(savename, FS_GAMEONLY, sysname, sizeof(sysname));
Con_Printf("Wrote %s\n", savename);
} }
} }
@ -3477,7 +3486,7 @@ double Host_Frame (double time)
static double time3 = 0; static double time3 = 0;
int pass1, pass2, pass3; int pass1, pass2, pass3;
// float fps; // float fps;
double realframetime; double realframetime, newrealtime;
static double spare; static double spare;
float maxfps; float maxfps;
qboolean maxfpsignoreserver; qboolean maxfpsignoreserver;
@ -3490,7 +3499,13 @@ double Host_Frame (double time)
return 0; // something bad happened, or the server disconnected return 0; // something bad happened, or the server disconnected
} }
realframetime = time = Media_TweekCaptureFrameTime(time); newrealtime = Media_TweekCaptureFrameTime(realtime, time);
realframetime = time = newrealtime - realtime;
realtime = newrealtime;
if (oldrealtime > realtime)
oldrealtime = 0;
// if (cls.demoplayback && cl_demospeed.value>0) // if (cls.demoplayback && cl_demospeed.value>0)
// realframetime *= cl_demospeed.value; // this probably screws up other timings // realframetime *= cl_demospeed.value; // this probably screws up other timings
@ -3508,11 +3523,6 @@ double Host_Frame (double time)
Plug_Tick(); Plug_Tick();
#endif #endif
// decide the simulation time
realtime += realframetime;
if (oldrealtime > realtime)
oldrealtime = 0;
if (cl.paused) if (cl.paused)
cl.gametimemark += time; cl.gametimemark += time;
@ -3570,7 +3580,7 @@ double Host_Frame (double time)
maxfps = 4; maxfps = 4;
} }
if (maxfps > 0) if (maxfps > 0 && Media_Capturing() != 2)
{ {
realtime += spare/1000; //don't use it all! realtime += spare/1000; //don't use it all!
spare = CL_FilterTime((realtime - oldrealtime)*1000, maxfps, maxfpsignoreserver); spare = CL_FilterTime((realtime - oldrealtime)*1000, maxfps, maxfpsignoreserver);
@ -3779,6 +3789,130 @@ void CL_ReadCDKey(void)
//============================================================================ //============================================================================
void CL_StartCinematicOrMenu(void)
{
//start up the ui now we have a renderer
#ifdef VM_UI
UI_Start();
#endif
Con_TPrintf (TLC_QUAKEWORLD_INITED, fs_gamename.string);
//there might be some console command or somesuch waiting for the renderer to begin (demos or map command or whatever all need model support).
realtime+=1;
Cbuf_Execute (); //server may have been waiting for the renderer
//and any startup cinematics
#ifndef NOMEDIA
if (!cls.demoinfile && !cls.state && !Media_PlayingFullScreen())
{
int ol_depth;
int idcin_depth;
int idroq_depth;
idcin_depth = COM_FDepthFile("video/idlog.cin", true); //q2
idroq_depth = COM_FDepthFile("video/idlogo.roq", true); //q2
ol_depth = COM_FDepthFile("video/openinglogos.roq", true); //jk2
if (ol_depth != 0x7fffffff && (ol_depth <= idroq_depth || ol_depth <= idcin_depth))
Media_PlayFilm("video/openinglogos.roq");
else if (idroq_depth != 0x7fffffff && idroq_depth <= idcin_depth)
Media_PlayFilm("video/idlogo.roq");
else if (idcin_depth != 0x7fffffff)
Media_PlayFilm("video/idlog.cin");
}
#endif
if (!cls.demoinfile && !*cls.servername && !Media_Playing())
{
#ifndef CLIENTONLY
if (!sv.state)
#endif
{
if (qrenderer > QR_NONE)
M_ToggleMenu_f();
//Con_ForceActiveNow();
}
}
}
//note that this does NOT include commandline.
void CL_ExecInitialConfigs(void)
{
int qrc, hrc, def, i;
Cbuf_AddText ("cl_warncmd 0\n", RESTRICT_LOCAL);
//who should we imitate?
qrc = COM_FDepthFile("quake.rc", true); //q1
hrc = COM_FDepthFile("hexen.rc", true); //h2
def = COM_FDepthFile("default.cfg", true); //q2/q3
if (qrc <= def && qrc <= hrc && qrc!=0x7fffffff)
Cbuf_AddText ("exec quake.rc\n", RESTRICT_LOCAL);
else if (hrc <= def && hrc!=0x7fffffff)
Cbuf_AddText ("exec hexen.rc\n", RESTRICT_LOCAL);
else
{ //they didn't give us an rc file!
Cbuf_AddText ("bind ~ toggleconsole\n", RESTRICT_LOCAL); //we expect default.cfg to not exist. :(
Cbuf_AddText ("exec default.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("config.cfg"))
Cbuf_AddText ("exec config.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("q3config.cfg"))
Cbuf_AddText ("exec q3config.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("exec autoexec.cfg\n", RESTRICT_LOCAL);
}
Cbuf_AddText ("exec fte.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("frontend.cfg"))
Cbuf_AddText ("exec frontend.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("cl_warncmd 1\n", RESTRICT_LOCAL); //and then it's allowed to start moaning.
{
extern cvar_t com_parseutf8;
com_parseutf8.ival = com_parseutf8.value;
}
// Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to
//assuming they didn't use any waits in their config (fools)
//the configs should be fully loaded.
//so convert the backwards compable commandline parameters in cvar sets.
if (COM_CheckParm ("-window") || COM_CheckParm ("-startwindowed"))
Cvar_Set(Cvar_FindVar("vid_fullscreen"), "0");
if (COM_CheckParm ("-fullscreen"))
Cvar_Set(Cvar_FindVar("vid_fullscreen"), "1");
if ((i = COM_CheckParm ("-width"))) //width on it's own also sets height
{
Cvar_Set(Cvar_FindVar("vid_width"), com_argv[i+1]);
Cvar_SetValue(Cvar_FindVar("vid_height"), (atoi(com_argv[i+1])/4)*3);
}
if ((i = COM_CheckParm ("-height")))
Cvar_Set(Cvar_FindVar("vid_height"), com_argv[i+1]);
if ((i = COM_CheckParm ("-conwidth"))) //width on it's own also sets height
{
Cvar_Set(Cvar_FindVar("vid_conwidth"), com_argv[i+1]);
Cvar_SetValue(Cvar_FindVar("vid_conheight"), (atoi(com_argv[i+1])/4)*3);
}
if ((i = COM_CheckParm ("-conheight")))
Cvar_Set(Cvar_FindVar("vid_conheight"), com_argv[i+1]);
if ((i = COM_CheckParm ("-bpp")))
Cvar_Set(Cvar_FindVar("vid_bpp"), com_argv[i+1]);
if (COM_CheckParm ("-current"))
Cvar_Set(Cvar_FindVar("vid_desktopsettings"), "1");
Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to
}
/* /*
==================== ====================
Host_Init Host_Init
@ -3786,12 +3920,8 @@ Host_Init
*/ */
void Host_Init (quakeparms_t *parms) void Host_Init (quakeparms_t *parms)
{ {
#ifndef NPFTE
int i;
int qrc, hrc, def;
#endif
extern cvar_t com_parseutf8; extern cvar_t com_parseutf8;
com_parseutf8.ival = 1; com_parseutf8.ival = 1; //enable utf8 parsing even before cvars are registered.
COM_InitArgv (parms->argc, parms->argv); COM_InitArgv (parms->argc, parms->argv);
@ -3875,117 +4005,27 @@ void Host_Init (quakeparms_t *parms)
host_initialized = true; host_initialized = true;
#ifdef NPFTE Sys_SendKeyEvents();
}
void Host_FinishInit(void)
{
int i;
int qrc, hrc, def;
#endif
Cbuf_AddText ("cl_warncmd 0\n", RESTRICT_LOCAL); //the engine is technically initialised at this point, except for the renderer. now we exec configs and bring up the renderer
//anything that needs models cannot be run yet, but it should be safe to allow console commands etc.
//if we get a map command, we'll just stick it on the end of the console command buffer.
//who should we imitate? Con_History_Load();
qrc = COM_FDepthFile("quake.rc", true); //q1
hrc = COM_FDepthFile("hexen.rc", true); //h2
def = COM_FDepthFile("default.cfg", true); //q2/q3
if (qrc <= def && qrc <= hrc && qrc!=0x7fffffff) CL_ExecInitialConfigs();
Cbuf_AddText ("exec quake.rc\n", RESTRICT_LOCAL);
else if (hrc <= def && hrc!=0x7fffffff)
Cbuf_AddText ("exec hexen.rc\n", RESTRICT_LOCAL);
else
{ //they didn't give us an rc file!
Cbuf_AddText ("bind ~ toggleconsole\n", RESTRICT_LOCAL); //we expect default.cfg to not exist. :(
Cbuf_AddText ("exec default.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("config.cfg"))
Cbuf_AddText ("exec config.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("q3config.cfg"))
Cbuf_AddText ("exec q3config.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("exec autoexec.cfg\n", RESTRICT_LOCAL);
}
Cbuf_AddText ("exec fte.cfg\n", RESTRICT_LOCAL);
if (COM_FCheckExists ("frontend.cfg"))
Cbuf_AddText ("exec frontend.cfg\n", RESTRICT_LOCAL);
Cbuf_AddText ("cl_warncmd 1\n", RESTRICT_LOCAL); //and then it's allowed to start moaning.
if (CL_CheckBootDownloads())
{ {
extern cvar_t com_parseutf8; Cmd_StuffCmds();
com_parseutf8.ival = com_parseutf8.value; Cbuf_Execute ();
} }
Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to
//assuming they didn't use any waits in their config (fools)
//the configs should be fully loaded.
//so convert the backwards compable commandline parameters in cvar sets.
if (COM_CheckParm ("-window") || COM_CheckParm ("-startwindowed"))
Cvar_Set(Cvar_FindVar("vid_fullscreen"), "0");
if (COM_CheckParm ("-fullscreen"))
Cvar_Set(Cvar_FindVar("vid_fullscreen"), "1");
if ((i = COM_CheckParm ("-width"))) //width on it's own also sets height
{
Cvar_Set(Cvar_FindVar("vid_width"), com_argv[i+1]);
Cvar_SetValue(Cvar_FindVar("vid_height"), (atoi(com_argv[i+1])/4)*3);
}
if ((i = COM_CheckParm ("-height")))
Cvar_Set(Cvar_FindVar("vid_height"), com_argv[i+1]);
if ((i = COM_CheckParm ("-conwidth"))) //width on it's own also sets height
{
Cvar_Set(Cvar_FindVar("vid_conwidth"), com_argv[i+1]);
Cvar_SetValue(Cvar_FindVar("vid_conheight"), (atoi(com_argv[i+1])/4)*3);
}
if ((i = COM_CheckParm ("-conheight")))
Cvar_Set(Cvar_FindVar("vid_conheight"), com_argv[i+1]);
if ((i = COM_CheckParm ("-bpp")))
Cvar_Set(Cvar_FindVar("vid_bpp"), com_argv[i+1]);
if (COM_CheckParm ("-current"))
Cvar_Set(Cvar_FindVar("vid_desktopsettings"), "1");
//now exec their commandline
Cmd_StuffCmds();
Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to
Renderer_Start();
#ifdef VM_UI
UI_Start();
#endif
#ifndef NOMEDIA
if (!cls.demoinfile && !cls.state && !Media_PlayingFullScreen())
{
int ol_depth;
int idcin_depth;
int idroq_depth;
idcin_depth = COM_FDepthFile("video/idlog.cin", true); //q2
idroq_depth = COM_FDepthFile("video/idlogo.roq", true); //q2
ol_depth = COM_FDepthFile("video/openinglogos.roq", true); //jk2
if (ol_depth != 0x7fffffff && (ol_depth <= idroq_depth || ol_depth <= idcin_depth))
Media_PlayFilm("video/openinglogos.roq");
else if (idroq_depth != 0x7fffffff && idroq_depth <= idcin_depth)
Media_PlayFilm("video/idlogo.roq");
else if (idcin_depth != 0x7fffffff)
Media_PlayFilm("video/idlog.cin");
}
#endif
Con_TPrintf (TL_NL); Con_TPrintf (TL_NL);
Con_Printf ("%s", version_string()); Con_Printf ("%s", version_string());
Con_TPrintf (TL_NL); Con_TPrintf (TL_NL);
Con_TPrintf (TLC_QUAKEWORLD_INITED, fs_gamename.string);
Con_DPrintf("This program is free software; you can redistribute it and/or " Con_DPrintf("This program is free software; you can redistribute it and/or "
"modify it under the terms of the GNU General Public License " "modify it under the terms of the GNU General Public License "
"as published by the Free Software Foundation; either version 2 " "as published by the Free Software Foundation; either version 2 "
@ -3997,20 +4037,9 @@ Con_TPrintf (TL_NL);
"\n" "\n"
"See the GNU General Public License for more details.\n"); "See the GNU General Public License for more details.\n");
realtime+=1; Renderer_Start();
Cbuf_Execute (); //server may have been waiting for the renderer
if (!cls.demoinfile && !*cls.servername && !Media_Playing()) CL_StartCinematicOrMenu();
{
#ifndef CLIENTONLY
if (!sv.state)
#endif
{
if (qrenderer > QR_NONE)
M_ToggleMenu_f();
//Con_ForceActiveNow();
}
}
} }
/* /*
@ -4045,6 +4074,9 @@ void Host_Shutdown(void)
S_Shutdown(); S_Shutdown();
IN_Shutdown (); IN_Shutdown ();
R_ShutdownRenderer(); R_ShutdownRenderer();
#ifdef CL_MASTER
MasterInfo_Shutdown();
#endif
CL_FreeDlights(); CL_FreeDlights();
M_Shutdown(); M_Shutdown();
#ifndef CLIENTONLY #ifndef CLIENTONLY

View file

@ -128,7 +128,8 @@ typedef struct serverinfo_s {
typedef struct master_s{ typedef struct master_s{
struct master_s *next; struct master_s *next;
netadr_t adr; netadr_t adr;
char *address; //text based address (http servers char *address; //text based address (http servers)
struct dl_download *dl;
int type; int type;
int servertype; //filled in for http servers int servertype; //filled in for http servers
int sends; /*needs to resend?*/ int sends; /*needs to resend?*/
@ -163,6 +164,7 @@ extern player_t *mplayers;
void Master_SetupSockets(void); void Master_SetupSockets(void);
void CL_QueryServers(void); void CL_QueryServers(void);
int Master_CheckPollSockets(void); int Master_CheckPollSockets(void);
void MasterInfo_Shutdown(void);
void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles); void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles);
serverinfo_t *Master_InfoForServer (netadr_t addr); serverinfo_t *Master_InfoForServer (netadr_t addr);
serverinfo_t *Master_InfoForNum (int num); serverinfo_t *Master_InfoForNum (int num);

View file

@ -233,7 +233,7 @@ char *svc_nqstrings[] =
"dpsvc_spawnbaseline2", //55 "dpsvc_spawnbaseline2", //55
"dpsvc_spawnstatic2", //56 obsolete "dpsvc_spawnstatic2", //56 obsolete
"dpsvc_entities", //57 "dpsvc_entities", //57
"NEW PROTOCOL", //58 "dpsvc_csqcentities", //58
"dpsvc_spawnstaticsound2", //59 "dpsvc_spawnstaticsound2", //59
"dpsvc_trailparticles", //60 "dpsvc_trailparticles", //60
"dpsvc_pointparticles", //61 "dpsvc_pointparticles", //61
@ -360,8 +360,11 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
char *ext; char *ext;
downloadlist_t *dl; downloadlist_t *dl;
qboolean webdl = false; qboolean webdl = false;
if (localname && !strncmp(filename, "http://", 7)) if (!strncmp(filename, "http://", 7))
{ {
if (!localname)
return false;
webdl = true; webdl = true;
} }
else else
@ -619,6 +622,7 @@ void CL_DownloadFinished(void)
CL_CheckModelResources(filename); CL_CheckModelResources(filename);
if (!cl.sendprespawn) if (!cl.sendprespawn)
{ {
/*
for (i = 0; i < mod_numknown; i++) //go and load this model now. for (i = 0; i < mod_numknown; i++) //go and load this model now.
{ {
if (!strcmp(mod_known[i].name, filename)) if (!strcmp(mod_known[i].name, filename))
@ -627,6 +631,7 @@ void CL_DownloadFinished(void)
break; break;
} }
} }
*/
for (i = 0; i < MAX_MODELS; i++) //go and load this model now. for (i = 0; i < MAX_MODELS; i++) //go and load this model now.
{ {
if (!strcmp(cl.model_name[i], filename)) if (!strcmp(cl.model_name[i], filename))
@ -637,6 +642,14 @@ void CL_DownloadFinished(void)
break; break;
} }
} }
for (i = 0; i < MAX_CSQCMODELS; i++) //go and load this model now.
{
if (!strcmp(cl.model_csqcname[i], filename))
{
cl.model_csqcprecache[i] = Mod_ForName(cl.model_csqcname[i], false); //throw away result.
break;
}
}
for (i = 0; i < MAX_VWEP_MODELS; i++) for (i = 0; i < MAX_VWEP_MODELS; i++)
{ {
if (!strcmp(cl.model_name_vwep[i], filename)) if (!strcmp(cl.model_name_vwep[i], filename))
@ -1589,12 +1602,10 @@ downloadlist_t *CL_DownloadFailed(char *name)
return failed; return failed;
} }
float downloadstarttime;
#ifdef PEXT_CHUNKEDDOWNLOADS #ifdef PEXT_CHUNKEDDOWNLOADS
#define MAXBLOCKS 512 //must be power of 2 #define MAXBLOCKS 512 //must be power of 2
#define DLBLOCKSIZE 1024 #define DLBLOCKSIZE 1024
int downloadsize; int downloadsize;
int receivedbytes;
struct struct
{ {
int chunkno; int chunkno;
@ -1605,7 +1616,7 @@ int download_file_number;
int CL_DownloadRate(void) int CL_DownloadRate(void)
{ {
return receivedbytes/(Sys_DoubleTime() - downloadstarttime); return cls.downloadedbytes/(Sys_DoubleTime() - cls.downloadstarttime);
} }
void CL_ParseChunkedDownload(void) void CL_ParseChunkedDownload(void)
@ -1664,7 +1675,7 @@ void CL_ParseChunkedDownload(void)
cls.downloadpercent = 0; cls.downloadpercent = 0;
downloadsize = totalsize; downloadsize = totalsize;
downloadstarttime = Sys_DoubleTime(); cls.downloadstarttime = Sys_DoubleTime();
/* /*
strcpy(cls.downloadname, svname); strcpy(cls.downloadname, svname);
@ -1696,7 +1707,7 @@ void CL_ParseChunkedDownload(void)
download_file_number++; download_file_number++;
firstblock = 0; firstblock = 0;
receivedbytes = 0; cls.downloadedbytes = 0;
blockcycle = -1; //so it requests 0 first. :) blockcycle = -1; //so it requests 0 first. :)
for (chunknum = 0; chunknum < MAXBLOCKS; chunknum++) for (chunknum = 0; chunknum < MAXBLOCKS; chunknum++)
dlblock[chunknum].chunkno = ~0u; dlblock[chunknum].chunkno = ~0u;
@ -1728,7 +1739,7 @@ void CL_ParseChunkedDownload(void)
dlblock[ridx].chunkno = ~0; dlblock[ridx].chunkno = ~0;
// Con_Printf("usable\n", chunknum); // Con_Printf("usable\n", chunknum);
receivedbytes+=DLBLOCKSIZE; cls.downloadedbytes+=DLBLOCKSIZE;
VFS_SEEK(cls.downloadqw, chunknum*DLBLOCKSIZE); VFS_SEEK(cls.downloadqw, chunknum*DLBLOCKSIZE);
if (downloadsize - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve. if (downloadsize - chunknum*DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve.
@ -1736,7 +1747,7 @@ void CL_ParseChunkedDownload(void)
else else
VFS_WRITE(cls.downloadqw, data, DLBLOCKSIZE); VFS_WRITE(cls.downloadqw, data, DLBLOCKSIZE);
cls.downloadpercent = receivedbytes/(float)downloadsize*100; cls.downloadpercent = cls.downloadedbytes/(float)downloadsize*100;
} }
int CL_CountQueuedDownloads(void) int CL_CountQueuedDownloads(void)
@ -1781,7 +1792,7 @@ int CL_RequestADownloadChunk(void)
CL_SendClientCommand(true, "stopdownload"); CL_SendClientCommand(true, "stopdownload");
CL_DownloadFinished(); CL_DownloadFinished();
Con_DPrintf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads()); Con_DPrintf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - cls.downloadstarttime), CL_CountQueuedDownloads());
*cls.downloadlocalname = '\0'; *cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0'; *cls.downloadremotename = '\0';
@ -1896,8 +1907,8 @@ void CL_ParseDownload (void)
return; return;
} }
downloadstarttime = Sys_DoubleTime(); cls.downloadstarttime = Sys_DoubleTime();
receivedbytes = 0; cls.downloadedbytes = 0;
SCR_EndLoadingPlaque(); SCR_EndLoadingPlaque();
} }
#ifdef PEXT_ZLIBDL #ifdef PEXT_ZLIBDL
@ -1918,9 +1929,9 @@ void CL_ParseDownload (void)
msg_readcount += size; msg_readcount += size;
} }
receivedbytes += size; cls.downloadedbytes += size;
if (cls.downloadpercent != percent) //try and guess the size (its most acurate when the percent value changes) if (cls.downloadpercent != percent) //try and guess the size (its most acurate when the percent value changes)
downloadsize = ((float)receivedbytes*100)/percent; downloadsize = ((float)cls.downloadedbytes*100)/percent;
if (cls.downloadmethod == DL_QWPENDING) if (cls.downloadmethod == DL_QWPENDING)
cls.downloadmethod = DL_QW; cls.downloadmethod = DL_QW;
@ -1949,7 +1960,7 @@ void CL_ParseDownload (void)
cls.downloadqw = NULL; cls.downloadqw = NULL;
cls.downloadpercent = 0; cls.downloadpercent = 0;
Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime)); Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - cls.downloadstarttime));
// get another file if needed // get another file if needed
@ -2002,6 +2013,12 @@ void CLDP_ParseDownloadBegin(char *s)
size = (unsigned int)atoi(Cmd_Argv(1)); size = (unsigned int)atoi(Cmd_Argv(1));
fname = Cmd_Argv(2); fname = Cmd_Argv(2);
if (strcmp(fname, cls.downloadlocalname))
{
Con_Printf("Warning: server started sending a file we did not request. Ignoring.\n");
return;
}
COM_StripExtension (fname, cls.downloadtempname, sizeof(cls.downloadtempname)-5); COM_StripExtension (fname, cls.downloadtempname, sizeof(cls.downloadtempname)-5);
strcat (cls.downloadtempname, ".tmp"); strcat (cls.downloadtempname, ".tmp");
@ -2017,6 +2034,10 @@ void CLDP_ParseDownloadBegin(char *s)
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "wb", FS_GAME); cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "wb", FS_GAME);
cls.downloadmethod = DL_DARKPLACES; cls.downloadmethod = DL_DARKPLACES;
Q_strncpyz(cls.downloadlocalname, fname, sizeof(cls.downloadlocalname));
cls.downloadstarttime = Sys_DoubleTime();
cls.downloadedbytes = 0;
if (cls.downloadqw) if (cls.downloadqw)
{ {
//fill the file with 0 bytes //fill the file with 0 bytes
@ -2032,7 +2053,7 @@ void CLDP_ParseDownloadBegin(char *s)
else else
CL_DownloadFailed(cls.downloadremotename); CL_DownloadFailed(cls.downloadremotename);
downloadstarttime = Sys_DoubleTime(); cls.downloadstarttime = Sys_DoubleTime();
} }
void CLDP_ParseDownloadFinished(char *s) void CLDP_ParseDownloadFinished(char *s)
@ -2089,7 +2110,7 @@ void CLDP_ParseDownloadFinished(char *s)
cls.downloadqw = NULL; cls.downloadqw = NULL;
cls.downloadpercent = 0; cls.downloadpercent = 0;
Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime)); Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - cls.downloadstarttime));
// get another file if needed // get another file if needed
@ -2758,8 +2779,15 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
Q_strncpyz (cl.levelname, str, sizeof(cl.levelname)); Q_strncpyz (cl.levelname, str, sizeof(cl.levelname));
// seperate the printfs so the server message can have a color // seperate the printfs so the server message can have a color
#if 1
Con_Printf ("\n\n");
Con_Printf ("^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f");
Con_Printf ("\n\n");
Con_Printf ("\1%s\n", str);
#else
Con_TPrintf (TLC_LINEBREAK_NEWLEVEL); Con_TPrintf (TLC_LINEBREAK_NEWLEVEL);
Con_TPrintf (TLC_PC_PS_NL, 2, str); Con_TPrintf (TLC_PC_PS_NL, 2, str);
#endif
SCR_BeginLoadingPlaque(); SCR_BeginLoadingPlaque();
@ -3545,6 +3573,7 @@ void CL_ParseStatic (int version)
ent = &cl_static_entities[i].ent; ent = &cl_static_entities[i].ent;
memset(ent, 0, sizeof(*ent)); memset(ent, 0, sizeof(*ent));
memset(&cl_static_entities[i].pvscache, 0, sizeof(cl_static_entities[i].pvscache));
ent->keynum = es.number; ent->keynum = es.number;
@ -3591,8 +3620,13 @@ void CL_ParseStatic (int version)
/*FIXME: compensate for angle*/ /*FIXME: compensate for angle*/
VectorAdd(es.origin, ent->model->mins, mins); VectorAdd(es.origin, ent->model->mins, mins);
VectorAdd(es.origin, ent->model->maxs, maxs); VectorAdd(es.origin, ent->model->maxs, maxs);
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &cl_static_entities[i].pvscache, mins, maxs);
} }
else
{
VectorCopy(es.origin, mins);
VectorCopy(es.origin, maxs);
}
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &cl_static_entities[i].pvscache, mins, maxs);
} }
/* /*
@ -3600,7 +3634,7 @@ void CL_ParseStatic (int version)
CL_ParseStaticSound CL_ParseStaticSound
=================== ===================
*/ */
void CL_ParseStaticSound (void) void CL_ParseStaticSound (qboolean large)
{ {
extern cvar_t cl_staticsounds; extern cvar_t cl_staticsounds;
vec3_t org; vec3_t org;
@ -3609,7 +3643,10 @@ void CL_ParseStaticSound (void)
for (i=0 ; i<3 ; i++) for (i=0 ; i<3 ; i++)
org[i] = MSG_ReadCoord (); org[i] = MSG_ReadCoord ();
sound_num = MSG_ReadByte (); if (large)
sound_num = (unsigned short)MSG_ReadShort();
else
sound_num = MSG_ReadByte ();
vol = MSG_ReadByte (); vol = MSG_ReadByte ();
atten = MSG_ReadByte (); atten = MSG_ReadByte ();
@ -5474,7 +5511,7 @@ void CLQW_ParseServerMessage (void)
break; break;
case svc_spawnstaticsound: case svc_spawnstaticsound:
CL_ParseStaticSound (); CL_ParseStaticSound (false);
break; break;
case svc_cdtrack: case svc_cdtrack:
@ -6157,7 +6194,7 @@ void CLNQ_ParseServerMessage (void)
break; break;
case svc_spawnstaticsound: case svc_spawnstaticsound:
CL_ParseStaticSound (); CL_ParseStaticSound (false);
break; break;
case svc_spawnstatic: case svc_spawnstatic:
@ -6386,6 +6423,10 @@ void CLNQ_ParseServerMessage (void)
CLDP_ParseDarkPlaces5Entities(); CLDP_ParseDarkPlaces5Entities();
break; break;
case svcdp_spawnstaticsound2:
CL_ParseStaticSound(true);
break;
#ifdef PEXT_CSQC #ifdef PEXT_CSQC
case svcdp_csqcentities: case svcdp_csqcentities:
CSQC_ParseEntities(); CSQC_ParseEntities();

View file

@ -1872,91 +1872,87 @@ int MipColor(int r, int g, int b)
return best; return best;
} }
qboolean SCR_ScreenShot (char *filename) qboolean SCR_ScreenShot (char *filename, void *rgb_buffer, int width, int height)
{ {
int truewidth, trueheight;
qbyte *buffer;
int i, c, temp; int i, c, temp;
#if defined(AVAIL_PNGLIB) || defined(AVAIL_JPEGLIB) #if defined(AVAIL_PNGLIB) || defined(AVAIL_JPEGLIB)
extern cvar_t scr_sshot_compression; extern cvar_t scr_sshot_compression;
#endif #endif
#define MAX_PREPAD 128
char *ext; char *ext;
ext = COM_FileExtension(filename); ext = COM_FileExtension(filename);
buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight); if (!rgb_buffer)
#ifdef warningmsg
#pragma warningmsg("Need to ensure that the various image writing routines can cope with ((width|height)&3")
#endif
if (!buffer)
return false; return false;
#ifdef AVAIL_PNGLIB #ifdef AVAIL_PNGLIB
if (!strcmp(ext, "png")) if (!strcmp(ext, "png"))
{ {
Image_WritePNG(filename, scr_sshot_compression.value, buffer+MAX_PREPAD, truewidth, trueheight); Image_WritePNG(filename, scr_sshot_compression.value, rgb_buffer, width, height);
} }
else else
#endif #endif
#ifdef AVAIL_JPEGLIB #ifdef AVAIL_JPEGLIB
if (!strcmp(ext, "jpeg") || !strcmp(ext, "jpg")) if (!strcmp(ext, "jpeg") || !strcmp(ext, "jpg"))
{ {
screenshotJPEG(filename, scr_sshot_compression.value, buffer+MAX_PREPAD, truewidth, trueheight); screenshotJPEG(filename, scr_sshot_compression.value, rgb_buffer, width, height);
} }
else else
#endif #endif
/* if (!strcmp(ext, "bmp")) /* if (!strcmp(ext, "bmp"))
{ {
WriteBMPFile(pcxname, buffer+MAX_PREPAD, truewidth, trueheight); WriteBMPFile(pcxname, rgb_buffer, width, height);
} }
else*/ else*/
if (!strcmp(ext, "pcx")) if (!strcmp(ext, "pcx"))
{ {
int y, x; int y, x;
qbyte *src, *dest; qbyte *src, *dest;
qbyte *newbuf = buffer + MAX_PREPAD; qbyte *newbuf = rgb_buffer;
// convert to eight bit // convert in-place to eight bit
for (y = 0; y < trueheight; y++) { for (y = 0; y < height; y++)
src = newbuf + (truewidth * 3 * y); {
dest = newbuf + (truewidth * y); src = newbuf + (width * 3 * y);
dest = newbuf + (width * y);
for (x = 0; x < truewidth; x++) { for (x = 0; x < width; x++) {
*dest++ = MipColor(src[0], src[1], src[2]); *dest++ = MipColor(src[0], src[1], src[2]);
src += 3; src += 3;
} }
} }
WritePCXfile (filename, newbuf, truewidth, trueheight, truewidth, host_basepal, false); WritePCXfile (filename, newbuf, width, height, width, host_basepal, false);
} }
else //tga else //tga
{ {
buffer+=MAX_PREPAD-18; vfsfile_t *vfs;
memset (buffer, 0, 18); FS_CreatePath(filename, FS_GAMEONLY);
buffer[2] = 2; // uncompressed type vfs = FS_OpenVFS(filename, "wb", FS_GAMEONLY);
buffer[12] = truewidth&255; if (vfs)
buffer[13] = truewidth>>8;
buffer[14] = trueheight&255;
buffer[15] = trueheight>>8;
buffer[16] = 24; // pixel size
// swap rgb to bgr
c = 18+truewidth*trueheight*3;
for (i=18 ; i<c ; i+=3)
{ {
temp = buffer[i]; unsigned char header[18];
buffer[i] = buffer[i+2]; memset (header, 0, 18);
buffer[i+2] = temp; header[2] = 2; // uncompressed type
header[12] = width&255;
header[13] = width>>8;
header[14] = height&255;
header[15] = height>>8;
header[16] = 24; // pixel size
VFS_WRITE(vfs, header, sizeof(header));
// swap rgb to bgr
c = width*height*3;
for (i=0 ; i<c ; i+=3)
{
temp = ((qbyte*)rgb_buffer)[i];
((qbyte*)rgb_buffer)[i] = ((qbyte*)rgb_buffer)[i+2];
((qbyte*)rgb_buffer)[i+2] = temp;
}
VFS_WRITE(vfs, rgb_buffer, c);
VFS_CLOSE(vfs);
} }
COM_WriteFile (filename, buffer, truewidth*trueheight*3 + 18 );
buffer-=MAX_PREPAD-18;
} }
BZ_Free (buffer);
return true; return true;
} }
@ -1971,6 +1967,8 @@ void SCR_ScreenShot_f (void)
char pcxname[80]; char pcxname[80];
int i; int i;
vfsfile_t *vfs; vfsfile_t *vfs;
void *rgbbuffer;
int width, height;
if (!VID_GetRGBInfo) if (!VID_GetRGBInfo)
{ {
@ -2015,10 +2013,18 @@ void SCR_ScreenShot_f (void)
FS_NativePath(pcxname, FS_GAMEONLY, sysname, sizeof(sysname)); FS_NativePath(pcxname, FS_GAMEONLY, sysname, sizeof(sysname));
if (SCR_ScreenShot(pcxname)) rgbbuffer = VID_GetRGBInfo(0, &width, &height);
Con_Printf ("Wrote %s\n", sysname); if (rgbbuffer)
else {
Con_Printf ("Screenshot failed\n"); if (SCR_ScreenShot(pcxname, rgbbuffer, width, height))
{
Con_Printf ("Wrote %s\n", sysname);
BZ_Free(rgbbuffer);
return;
}
BZ_Free(rgbbuffer);
}
Con_Printf ("Couldn't write %s\n", sysname);
} }

View file

@ -1165,8 +1165,8 @@ void CL_ParseTEnt (void)
dl = CL_AllocDlight (0); dl = CL_AllocDlight (0);
VectorCopy (pos, dl->origin); VectorCopy (pos, dl->origin);
dl->radius = 150 + r_explosionlight.value*200; dl->radius = 150 + r_explosionlight.value*200;
dl->die = cl.time + 1; dl->die = cl.time + 0.75;
dl->decay = 300; dl->decay = dl->radius*2;
dl->color[0] = 4.0; dl->color[0] = 4.0;
dl->color[1] = 2.0; dl->color[1] = 2.0;
@ -2890,7 +2890,7 @@ void CL_UpdateBeams (void)
int i, j; int i, j;
beam_t *b; beam_t *b;
vec3_t dist, org; vec3_t dist, org;
float *vieworg; float *vieworg, *viewang;
float d; float d;
entity_t *ent; entity_t *ent;
entity_state_t *st; entity_state_t *st;
@ -2937,11 +2937,20 @@ void CL_UpdateBeams (void)
float delta, f, len; float delta, f, len;
if (cl.spectator && autocam[j]) if (cl.spectator && autocam[j])
{ { //if we're tracking someone, use their origin explicitly.
vieworg = pl->origin; vieworg = pl->origin;
} }
else else
vieworg = cl.playerview[j].simorg; vieworg = cl.playerview[j].simorg;
viewang = cl.playerview[j].simangles;
if (cl_truelightning.ival >= 2 && cls.netchan.outgoing_sequence > cl_truelightning.ival)
{
frame_t *frame = &cl.frames[(cls.netchan.outgoing_sequence-cl_truelightning.ival)&UPDATE_MASK];
viewang = frame->playerstate[cl.playernum[j]].viewangles;
viewang[0] = (frame->playerstate[cl.playernum[j]].command.angles[0] * 360) / 65336.0;
viewang[1] = (frame->playerstate[cl.playernum[j]].command.angles[1] * 360) / 65336.0;
}
VectorCopy (vieworg, b->start); VectorCopy (vieworg, b->start);
b->start[2] += cl.crouch[j] + bound(-7, v_viewheight.value, 4); b->start[2] += cl.crouch[j] + bound(-7, v_viewheight.value, 4);
@ -2960,10 +2969,10 @@ void CL_UpdateBeams (void)
ang[0] = -ang[0]; ang[0] = -ang[0];
if (ang[0] < -180) if (ang[0] < -180)
ang[0] += 360; ang[0] += 360;
ang[0] += (cl.playerview[j].simangles[0] - ang[0]) * f; ang[0] += (viewang[0] - ang[0]) * f;
// lerp yaw // lerp yaw
delta = cl.playerview[j].simangles[1] - ang[1]; delta = viewang[1] - ang[1];
if (delta > 180) if (delta > 180)
delta -= 360; delta -= 360;
if (delta < -180) if (delta < -180)
@ -2974,7 +2983,7 @@ void CL_UpdateBeams (void)
AngleVectors (ang, fwd, ang, ang); AngleVectors (ang, fwd, ang, ang);
VectorCopy(fwd, ang); VectorCopy(fwd, ang);
VectorScale (fwd, len, fwd); VectorScale (fwd, len, fwd);
VectorCopy (cl.playerview[j].simorg, org); VectorCopy (vieworg, org);
org[2] += 16; org[2] += 16;
VectorAdd (org, fwd, b->end); VectorAdd (org, fwd, b->end);

View file

@ -1166,7 +1166,7 @@ void CLHL_LoadClientGame(void)
memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs)); memset(&CLHL_cgamefuncs, 0, sizeof(CLHL_cgamefuncs));
clg = Sys_LoadLibrary("C:/Incoming/d/Half-Life/sdks/hlsdk-2.3-p3/hlsdk-2.3-p3/multiplayer/cl_dll/Debug/client", funcs); clg = NULL;//Sys_LoadLibrary("C:/Incoming/d/Half-Life/sdks/hlsdk-2.3-p3/hlsdk-2.3-p3/multiplayer/cl_dll/Debug/client", funcs);
if (!clg) if (!clg)
{ {
path = NULL; path = NULL;

View file

@ -378,11 +378,13 @@ typedef struct
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_DARKPLACES, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod; enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_DARKPLACES, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
vfsfile_t *downloadqw; // file transfer from server vfsfile_t *downloadqw; // file transfer from server
char downloadtempname[MAX_OSPATH]; char downloadtempname[MAX_OSPATH]; //file its currently writing to.
char downloadlocalname[MAX_OSPATH]; char downloadlocalname[MAX_OSPATH]; //file its going to be renamed to.
char downloadremotename[MAX_OSPATH]; char downloadremotename[MAX_OSPATH]; //file its coming from.
int downloadpercent; float downloadpercent; //for progress indicator.
int downloadchunknum; int downloadchunknum; //for QW downloads only.
float downloadstarttime; //for speed info
unsigned int downloadedbytes; //number of bytes downloaded, for progress/speed info
// demo loop control // demo loop control
int demonum; // -1 = don't play demos int demonum; // -1 = don't play demos
@ -822,6 +824,9 @@ void CL_SetInfo (int pnum, char *key, char *value);
void CL_BeginServerConnect(int port); void CL_BeginServerConnect(int port);
char *CL_TryingToConnect(void); char *CL_TryingToConnect(void);
void CL_ExecInitialConfigs(void);
qboolean CL_CheckBootDownloads(void);
#define MAX_VISEDICTS 2048 #define MAX_VISEDICTS 2048
extern int cl_numvisedicts; extern int cl_numvisedicts;
extern entity_t cl_visedicts[]; extern entity_t cl_visedicts[];
@ -1347,6 +1352,14 @@ typedef struct
void (VARGS *getsize) (void *ctx, int *width, int *height); void (VARGS *getsize) (void *ctx, int *width, int *height);
void (VARGS *changestream) (void *ctx, char *streamname); void (VARGS *changestream) (void *ctx, char *streamname);
} media_decoder_funcs_t; } media_decoder_funcs_t;
typedef struct {
void *(VARGS *capture_begin) (char *streamname, int videorate, int width, int height, int *sndkhz, int *sndchannels, int *sndbits);
void (VARGS *capture_video) (void *ctx, void *data, int frame, int width, int height);
void (VARGS *capture_audio) (void *ctx, void *data, int bytes);
void (VARGS *capture_end) (void *ctx);
} media_encoder_funcs_t;
extern struct plugin_s *currentplug; extern struct plugin_s *currentplug;
qboolean Media_RegisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs); qboolean Media_RegisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs);
qboolean Media_UnregisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs); qboolean Media_UnregisterDecoder(struct plugin_s *plug, media_decoder_funcs_t *funcs);
qboolean Media_RegisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *funcs);
qboolean Media_UnregisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *funcs);

View file

@ -24,10 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
console_t con_main; console_t con_main;
console_t *con_current; // points to whatever is the visible console console_t *con_current; // points to whatever is the visible console
console_t *con_chat; // points to a chat console console_t *con_chat; // points to a chat console
conline_t *con_footerline; //temp text at the bottom of the console
#define Font_ScreenWidth() (vid.pixelwidth) #define Font_ScreenWidth() (vid.pixelwidth)
static int Con_DrawProgress(int left, int right, int y); static int Con_DrawProgress(int left, int right, int y);
static int Con_DrawConsoleLines(conline_t *l, int sx, int ex, int y, int top, qboolean selactive, int selsx, int selex, int selsy, int seley);
#ifdef QTERM #ifdef QTERM
#include <windows.h> #include <windows.h>
@ -66,11 +68,6 @@ cvar_t con_separatechat = CVAR("con_separatechat", "0");
#define NUM_CON_TIMES 24 #define NUM_CON_TIMES 24
#define MAXCMDLINE 256
extern unsigned char key_lines[32][MAXCMDLINE];
extern int edit_line;
extern int key_linepos;
static conline_t *selstartline, *selendline; static conline_t *selstartline, *selendline;
static unsigned int selstartoffset, selendoffset; static unsigned int selstartoffset, selendoffset;
@ -163,6 +160,14 @@ console_t *Con_Create(char *name, unsigned int flags)
void Con_SetActive (console_t *con) void Con_SetActive (console_t *con)
{ {
con_current = con; con_current = con;
if (con_footerline)
{
selstartline = NULL;
selendline = NULL;
Z_Free(con_footerline);
con_footerline = NULL;
}
} }
/*for enumerating consoles*/ /*for enumerating consoles*/
qboolean Con_NameForNum(int num, char *buffer, int buffersize) qboolean Con_NameForNum(int num, char *buffer, int buffersize)
@ -357,6 +362,55 @@ void Key_ClearTyping (void)
key_linepos = 1; key_linepos = 1;
} }
void Con_History_Load(void)
{
unsigned char *cr;
vfsfile_t *file = FS_OpenVFS("conhistory.txt", "rb", FS_ROOT);
for (edit_line=0 ; edit_line<=CON_EDIT_LINES_MASK ; edit_line++)
{
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
}
edit_line = 0;
key_linepos = 1;
if (file)
{
while (VFS_GETS(file, key_lines[edit_line]+1, sizeof(key_lines[edit_line])-1))
{
//strip a trailing \r if its from windows.
cr = key_lines[edit_line] + strlen(key_lines[edit_line]);
if (cr > key_lines[edit_line] && cr[-1] == '\r')
cr[-1] = '\0';
edit_line = (edit_line + 1) & CON_EDIT_LINES_MASK;
}
VFS_CLOSE(file);
}
history_line = edit_line;
}
void Con_History_Save(void)
{
vfsfile_t *file = FS_OpenVFS("conhistory.txt", "wb", FS_ROOT);
int line;
if (file)
{
line = edit_line - CON_EDIT_LINES_MASK;
if (line < 0)
line = 0;
for(; line < edit_line; line++)
{
VFS_PUTS(file, key_lines[line]+1);
#ifdef _WIN32 //use an \r\n for readability with notepad.
VFS_PUTS(file, "\r\n");
#else
VFS_PUTS(file, "\n");
#endif
}
VFS_CLOSE(file);
}
}
/* /*
================ ================
Con_ToggleConsole_f Con_ToggleConsole_f
@ -539,12 +593,20 @@ void Con_Init (void)
void Con_Shutdown(void) void Con_Shutdown(void)
{ {
Con_History_Save();
while(con_main.next) while(con_main.next)
{ {
Con_Destroy(con_main.next); Con_Destroy(con_main.next);
} }
con_initialized = false; con_initialized = false;
Con_Destroy(&con_main); Con_Destroy(&con_main);
selstartline = NULL;
selendline = NULL;
if (con_footerline)
Z_Free(con_footerline);
con_footerline = NULL;
} }
void TTS_SayConString(conchar_t *stringtosay); void TTS_SayConString(conchar_t *stringtosay);
@ -793,6 +855,47 @@ void VARGS Con_DPrintf (char *fmt, ...)
Con_PrintCon(&con_main, msg); Con_PrintCon(&con_main, msg);
} }
/*description text at the bottom of the console*/
void Con_Footerf(qboolean append, char *fmt, ...)
{
va_list argptr;
char msg[MAXPRINTMSG];
conchar_t marked[MAXPRINTMSG], *markedend;
int oldlen, newlen;
conline_t *newf;
va_start (argptr,fmt);
vsnprintf (msg,sizeof(msg)-1, fmt,argptr);
va_end (argptr);
markedend = COM_ParseFunString(COLOR_YELLOW << CON_FGSHIFT, msg, marked, sizeof(marked), false);
newlen = markedend - marked;
if (append)
oldlen = con_footerline->length;
else
oldlen = 0;
if (!newlen && !oldlen)
newf = NULL;
else
{
newf = Z_Malloc(sizeof(*newf) + (oldlen + newlen) * sizeof(conchar_t));
if (con_footerline)
memcpy(newf, con_footerline, sizeof(*con_footerline)+oldlen*sizeof(conchar_t));
markedend = (void*)(newf+1);
markedend += oldlen;
memcpy(markedend, marked, newlen*sizeof(conchar_t));
newf->length = oldlen + newlen;
}
if (selstartline == con_footerline)
selstartline = NULL;
if (selendline == con_footerline)
selendline = NULL;
Z_Free(con_footerline);
con_footerline = newf;
}
/* /*
============================================================================== ==============================================================================
@ -811,7 +914,7 @@ y is the bottom of the input
return value is the top of the region return value is the top of the region
================ ================
*/ */
int Con_DrawInput (int left, int right, int y) int Con_DrawInput (int left, int right, int y, qboolean selactive, int selsx, int selex, int selsy, int seley)
{ {
#ifdef _WIN32 #ifdef _WIN32
extern qboolean ActiveApp; extern qboolean ActiveApp;
@ -869,7 +972,7 @@ int Con_DrawInput (int left, int right, int y)
{ {
int cmdstart; int cmdstart;
cmdstart = text[1] == '/'?2:1; cmdstart = text[1] == '/'?2:1;
fname = Cmd_CompleteCommand(text+cmdstart, true, true, con_commandmatch); fname = Cmd_CompleteCommand(text+cmdstart, true, true, con_commandmatch, NULL);
if (fname) //we can compleate it to: if (fname) //we can compleate it to:
{ {
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>' '; p++) for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>' '; p++)
@ -931,43 +1034,9 @@ int Con_DrawInput (int left, int right, int y)
} }
/*if its getting completed to something, show some help about the command that is going to be used*/ /*if its getting completed to something, show some help about the command that is going to be used*/
if (!text[1]) if (con_footerline)
con_commandmatch = 0;
if (con_commandmatch && fname && Cmd_IsCommand(text+(text[1] == '/'?2:1)))
{ {
cvar_t *var; y = Con_DrawConsoleLines(con_footerline, left, right, y, 0, selactive, selsx, selex, selsy, seley);
char *desc = NULL;
if (!desc)
{
var = Cvar_FindVar(fname);
if (var && var->description)
desc = var->description;
}
if (!desc)
{
desc = Cmd_Describe(fname);
}
if (desc)
{
int lines;
conchar_t *starts[8];
conchar_t *ends[8];
conchar_t *end;
end = maskedtext;
end = COM_ParseFunString((COLOR_YELLOW<<CON_FGSHIFT), va("%s: %s", fname, desc), end, (maskedtext+sizeof(maskedtext)/sizeof(maskedtext[0])-1-end)*sizeof(maskedtext[0]), true);
lines = Font_LineBreaks(maskedtext, end, right - left, 8, starts, ends);
while(lines-->0)
{
rhs = left;
y -= Font_CharHeight();
for (cchar = starts[lines]; cchar < ends[lines]; cchar++)
{
rhs = Font_DrawChar(rhs, y, *cchar);
}
}
}
} }
/*just above that, we have the tab completion list*/ /*just above that, we have the tab completion list*/
@ -984,7 +1053,7 @@ int Con_DrawInput (int left, int right, int y)
for (i = 1; ; i++) for (i = 1; ; i++)
{ {
cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i); cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i, NULL);
if (!cmd) if (!cmd)
break; break;
@ -1188,20 +1257,13 @@ static int Con_DrawProgress(int left, int right, int y)
progresstext = cls.downloadlocalname; progresstext = cls.downloadlocalname;
progresspercent = cls.downloadpercent; progresspercent = cls.downloadpercent;
if ((int)(realtime/2)&1) CL_GetDownloadSizes(&count, &total, &extra);
sprintf(progresspercenttext, " %02d%% (%ukbps)", (int)progresspercent, CL_DownloadRate()/1000);
if ((int)(realtime/2)&1 || total == 0)
sprintf(progresspercenttext, " %5.1f%% (%ukbps)", progresspercent, CL_DownloadRate()/1000);
else else
{ {
CL_GetDownloadSizes(&count, &total, &extra); sprintf(progresspercenttext, " %5.1f%% (%u%skb)", progresspercent, total/1024, extra?"+":"");
if (total == 0)
{
//just show progress
sprintf(progresspercenttext, " %02f%%", progresspercent);
}
else
{
sprintf(progresspercenttext, " %02d%% (%u%skb)", (int)progresspercent, total/1024, extra?"+":"");
}
} }
} }
#ifdef RUNTIMELIGHTING #ifdef RUNTIMELIGHTING
@ -1342,72 +1404,40 @@ int Con_DrawAlternateConsoles(int lines)
return y; return y;
} }
/* //draws the conline_t list bottom-up within the width of the screen until the top of the screen is reached.
================ //if text is selected, the selstartline globals will be updated, so make sure the lines persist or check them.
Con_DrawConsole static int Con_DrawConsoleLines(conline_t *l, int sx, int ex, int y, int top, qboolean selactive, int selsx, int selex, int selsy, int seley)
Draws the console with the solid background
================
*/
void Con_DrawConsole (int lines, qboolean noback)
{ {
extern qboolean scr_con_forcedraw; int linecount;
int x, y, sx, ex, linecount, linelength; int linelength;
conline_t *l;
conchar_t *s;
int selsx, selsy, selex, seley, selactive;
int top;
conchar_t *starts[64], *ends[sizeof(starts)/sizeof(starts[0])]; conchar_t *starts[64], *ends[sizeof(starts)/sizeof(starts[0])];
conchar_t *s;
int i; int i;
qboolean haveprogress; int x;
int hidelines;
if (lines <= 0) //deactivate the selection if the start and end is outside
return; if (
(selsx < sx && selex < sx) ||
#ifdef QTERM (selsx > ex && selex > ex) ||
if (qterms) (selsy < top && seley < top) ||
QT_Update(); (selsy > y && seley > y)
#endif )
selactive = false;
// draw the background
if (!noback)
R2D_ConsoleBackground (0, lines, scr_con_forcedraw);
con_current->unseentext = false;
con_current->vislines = lines;
top = Con_DrawAlternateConsoles(lines);
x = 8;
y = lines;
selactive = Key_GetConsoleSelectionBox(&selsx, &selsy, &selex, &seley);
Font_BeginString(font_conchar, x, y, &x, &y);
Font_BeginString(font_conchar, selsx, selsy, &selsx, &selsy);
Font_BeginString(font_conchar, selex, seley, &selex, &seley);
ex = Font_ScreenWidth();
sx = x;
ex -= sx;
y -= Font_CharHeight();
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
y = Con_DrawInput (x, ex - x, y);
if (selactive) if (selactive)
{ {
if (selsx < x) //clip it
selsx = x; if (selsx < sx)
if (selex < x) selsx = sx;
selex = x; if (selex < sx)
selex = sx;
if (selsy > y) if (selsy > y)
selsy = y; selsy = y;
if (seley > y) if (seley > y)
seley = y; seley = y;
//scale the y coord to be in lines instead of pixels
selsy -= y; selsy -= y;
seley -= y; seley -= y;
selsy /= Font_CharHeight(); selsy /= Font_CharHeight();
@ -1415,6 +1445,7 @@ void Con_DrawConsole (int lines, qboolean noback)
selsy--; selsy--;
seley--; seley--;
//invert the selections to make sense, text-wise
if (selsy == seley) if (selsy == seley)
{ {
//single line selected backwards //single line selected backwards
@ -1441,19 +1472,6 @@ void Con_DrawConsole (int lines, qboolean noback)
seley += y; seley += y;
} }
if (!con_current->display)
con_current->display = con_current->current;
l = con_current->display;
hidelines = con_current->subline;
if (l != con_current->current)
{
y -= 8;
// draw arrows to show the buffer is backscrolled
for (x = sx ; x<ex; )
x = (Font_DrawChar (x, y, '^'|CON_WHITEMASK)-x)*4+x;
}
if (l && l == con_current->current && l->length == 0) if (l && l == con_current->current && l->length == 0)
l = l->older; l = l->older;
for (; l; l = l->older) for (; l; l = l->older)
@ -1470,14 +1488,6 @@ void Con_DrawConsole (int lines, qboolean noback)
} }
l->lines = linecount; l->lines = linecount;
if (hidelines > 0)
{
linecount -= hidelines;
if (linecount < 0)
linecount = 0;
hidelines -= linecount;
}
while (linecount-- > 0) while (linecount-- > 0)
{ {
s = starts[linecount]; s = starts[linecount];
@ -1554,6 +1564,74 @@ void Con_DrawConsole (int lines, qboolean noback)
if (y < top) if (y < top)
break; break;
} }
return y;
}
/*
================
Con_DrawConsole
Draws the console with the solid background
================
*/
void Con_DrawConsole (int lines, qboolean noback)
{
extern qboolean scr_con_forcedraw;
int x, y, sx, ex;
conline_t *l;
int selsx, selsy, selex, seley, selactive;
int top;
qboolean haveprogress;
if (lines <= 0)
return;
#ifdef QTERM
if (qterms)
QT_Update();
#endif
// draw the background
if (!noback)
R2D_ConsoleBackground (0, lines, scr_con_forcedraw);
con_current->unseentext = false;
con_current->vislines = lines;
top = Con_DrawAlternateConsoles(lines);
x = 8;
y = lines;
selstartline = NULL;
selendline = NULL;
selactive = Key_GetConsoleSelectionBox(&selsx, &selsy, &selex, &seley);
Font_BeginString(font_conchar, x, y, &x, &y);
Font_BeginString(font_conchar, selsx, selsy, &selsx, &selsy);
Font_BeginString(font_conchar, selex, seley, &selex, &seley);
ex = Font_ScreenWidth();
sx = x;
ex -= sx;
y -= Font_CharHeight();
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
y = Con_DrawInput (x, ex - x, y, selactive, selsx, selex, selsy, seley);
if (!con_current->display)
con_current->display = con_current->current;
l = con_current->display;
if (l != con_current->current)
{
y -= 8;
// draw arrows to show the buffer is backscrolled
for (x = sx ; x<ex; )
x = (Font_DrawChar (x, y, '^'|CON_WHITEMASK)-x)*4+x;
}
y = Con_DrawConsoleLines(l, sx, ex, y, top, selactive, selsx, selex, selsy, seley);
if (!haveprogress && lines == vid.height) if (!haveprogress && lines == vid.height)
{ {

View file

@ -7,6 +7,12 @@
//#include "d3dquake.h" //#include "d3dquake.h"
#endif #endif
#ifdef NPFTE
//#define Con_Printf(f, ...)
//hope you're on a littleendian machine
#define LittleShort(s) s
#define LittleLong(s) s
#else
cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upside down. cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upside down.
//This is due to a bug in tenebrae. //This is due to a bug in tenebrae.
//(normally) the textures are actually the right way around. //(normally) the textures are actually the right way around.
@ -16,6 +22,7 @@ cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upsid
cvar_t r_dodgypcxfiles = SCVAR("r_dodgypcxfiles", "0"); //Quake 2's PCX loading isn't complete, cvar_t r_dodgypcxfiles = SCVAR("r_dodgypcxfiles", "0"); //Quake 2's PCX loading isn't complete,
//and some Q2 mods include PCX files //and some Q2 mods include PCX files
//that only work with this assumption //that only work with this assumption
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h> #include <unistd.h>
@ -66,9 +73,10 @@ char *ReadGreyTargaFile (qbyte *data, int flen, tgaheader_t *tgahead, int asgrey
numPixels = columns * rows; numPixels = columns * rows;
flipped = !((tgahead->attribs & 0x20) >> 5); flipped = !((tgahead->attribs & 0x20) >> 5);
#ifndef NPFTE
if (r_dodgytgafiles.value) if (r_dodgytgafiles.value)
flipped = true; flipped = true;
#endif
if (tgahead->version == 1) if (tgahead->version == 1)
{ {
@ -173,8 +181,10 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *
tgaheader.attribs = buf[17]; tgaheader.attribs = buf[17];
flipped = !((tgaheader.attribs & 0x20) >> 5); flipped = !((tgaheader.attribs & 0x20) >> 5);
#ifndef NPFTE
if (r_dodgytgafiles.value) if (r_dodgytgafiles.value)
flipped = true; flipped = true;
#endif
data=buf+18; data=buf+18;
data += tgaheader.id_len; data += tgaheader.id_len;
@ -872,7 +882,7 @@ error:
#ifndef NPFTE
int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, int height) int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, int height)
{ {
char name[MAX_OSPATH]; char name[MAX_OSPATH];
@ -940,6 +950,7 @@ err:
fclose(fp); fclose(fp);
return true; return true;
} }
#endif
#endif #endif
@ -1340,6 +1351,7 @@ badjpeg:
} }
/*end read*/ /*end read*/
#ifndef NPFTE
/*begin write*/ /*begin write*/
#define OUTPUT_BUF_SIZE 4096 #define OUTPUT_BUF_SIZE 4096
typedef struct { typedef struct {
@ -1503,8 +1515,9 @@ void screenshotJPEG(char *filename, int compression, qbyte *screendata, int scre
#endif #endif
} }
#endif #endif
#endif
#ifndef NPFTE
/* /*
============== ==============
WritePCXfile WritePCXfile
@ -1575,7 +1588,7 @@ void WritePCXfile (const char *filename, qbyte *data, int width, int height,
else else
COM_WriteFile (filename, pcx, length); COM_WriteFile (filename, pcx, length);
} }
#endif
/* /*
@ -1622,9 +1635,11 @@ qbyte *ReadPCXFile(qbyte *buf, int length, int *width, int *height)
*width = swidth; *width = swidth;
*height = sheight; *height = sheight;
#ifndef NPFTE
if (r_dodgypcxfiles.value) if (r_dodgypcxfiles.value)
palette = host_basepal; palette = host_basepal;
else else
#endif
palette = buf + length-768; palette = buf + length-768;
data = (char *)(pcx+1); data = (char *)(pcx+1);
@ -2054,6 +2069,10 @@ qbyte *ReadBMPFile(qbyte *buf, int length, int *width, int *height)
return NULL; return NULL;
}*/ }*/
#ifndef NPFTE
// saturate function, stolen from jitspoe // saturate function, stolen from jitspoe
void SaturateR8G8B8(qbyte *data, int size, float sat) void SaturateR8G8B8(qbyte *data, int size, float sat)
{ {
@ -2214,14 +2233,14 @@ texid_tf GL_LoadTextureDDS(char *iname, unsigned char *buffer, int filesize)
divsize = 4; divsize = 4;
blocksize = 8; blocksize = 8;
} }
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT3") else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT2" || *(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT3")
{ {
intfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; intfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
pad = 8; pad = 8;
divsize = 4; divsize = 4;
blocksize = 16; blocksize = 16;
} }
else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT5") else if (*(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT4" || *(int*)&fmtheader.ddpfPixelFormat.dwFourCC == *(int*)"DXT5")
{ {
intfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; intfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
pad = 8; pad = 8;
@ -2458,6 +2477,20 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
return tex; return tex;
} }
#ifdef DDS
snprintf(fname, sizeof(fname)-1, "dds/%s.dds", nicename); /*should be safe if its null*/
if ((buf = COM_LoadFile (fname, 5)))
{
tex = GL_LoadTextureDDS(name, buf, com_filesize);
if (TEXVALID(tex))
{
BZ_Free(buf);
return tex;
}
BZ_Free(buf);
}
#endif
if (strchr(name, '/')) //never look in a root dir for the pic if (strchr(name, '/')) //never look in a root dir for the pic
i = 0; i = 0;
else else
@ -2489,7 +2522,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
#ifdef DDS #ifdef DDS
tex = GL_LoadTextureDDS(fname, buf, com_filesize); tex = GL_LoadTextureDDS(name, buf, com_filesize);
if (TEXVALID(tex)) if (TEXVALID(tex))
{ {
BZ_Free(buf); BZ_Free(buf);
@ -2746,3 +2779,4 @@ void AddOcranaLEDsIndexed (qbyte *image, int h, int w)
} }
} }
} }
#endif

View file

@ -403,7 +403,6 @@ static void INS_ActivateMouse (void)
ClipCursor (&window_rect); ClipCursor (&window_rect);
} }
Con_Printf("Mouse grabbed\n");
mouseactive = true; mouseactive = true;
} }
} }
@ -465,7 +464,6 @@ static void INS_DeactivateMouse (void)
ReleaseCapture (); ReleaseCapture ();
} }
Con_Printf("Mouse released\n");
mouseactive = false; mouseactive = false;
} }
} }
@ -1220,7 +1218,7 @@ void INS_MouseMove (float *movements, int pnum)
extern int window_x, window_y; extern int window_x, window_y;
#ifdef AVAIL_DINPUT #ifdef AVAIL_DINPUT
if (dinput) if (dinput && mouseactive)
{ {
DIDEVICEOBJECTDATA od; DIDEVICEOBJECTDATA od;
DWORD dwElements; DWORD dwElements;

View file

@ -30,7 +30,7 @@ void Editor_Key(int key, int unicode);
#define KEY_MODIFIERSTATES 8 #define KEY_MODIFIERSTATES 8
#define MAXCMDLINE 256 #define MAXCMDLINE 256
unsigned char key_lines[32][MAXCMDLINE]; unsigned char key_lines[CON_EDIT_LINES_MASK+1][MAXCMDLINE];
int key_linepos; int key_linepos;
int shift_down=false; int shift_down=false;
int key_lastpress; int key_lastpress;
@ -245,7 +245,7 @@ qboolean Cmd_IsCommand (char *line)
command[i] = s[i]; command[i] = s[i];
command[i] = 0; command[i] = 0;
cmd = Cmd_CompleteCommand (command, true, false, -1); cmd = Cmd_CompleteCommand (command, true, false, -1, NULL);
if (!cmd || strcmp (cmd, command) ) if (!cmd || strcmp (cmd, command) )
return false; // just a chat message return false; // just a chat message
return true; return true;
@ -268,18 +268,19 @@ void CompleteCommand (qboolean force)
{ {
int i; int i;
char *cmd, *s; char *cmd, *s;
char *desc;
s = key_lines[edit_line]+1; s = key_lines[edit_line]+1;
if (*s == '\\' || *s == '/') if (*s == '\\' || *s == '/')
s++; s++;
cmd = Cmd_CompleteCommand (s, true, true, 2); cmd = Cmd_CompleteCommand (s, true, true, 2, NULL);
if (!cmd || force) if (!cmd || force)
{ {
if (!force) if (!force)
cmd = Cmd_CompleteCommand (s, false, true, 1); cmd = Cmd_CompleteCommand (s, false, true, 1, &desc);
else else
cmd = Cmd_CompleteCommand (s, true, true, con_commandmatch); cmd = Cmd_CompleteCommand (s, true, true, con_commandmatch, &desc);
if (cmd) if (cmd)
{ {
key_lines[edit_line][1] = '/'; key_lines[edit_line][1] = '/';
@ -292,7 +293,7 @@ void CompleteCommand (qboolean force)
// if (strlen(cmd)>strlen(s)) // if (strlen(cmd)>strlen(s))
{ {
cmd = Cmd_CompleteCommand (s, true, true, 0); cmd = Cmd_CompleteCommand (s, true, true, 0, NULL);
if (cmd && !strcmp(s, cmd)) //also a compleate var if (cmd && !strcmp(s, cmd)) //also a compleate var
{ {
key_lines[edit_line][key_linepos] = ' '; key_lines[edit_line][key_linepos] = ' ';
@ -302,10 +303,13 @@ void CompleteCommand (qboolean force)
key_lines[edit_line][key_linepos] = 0; key_lines[edit_line][key_linepos] = 0;
if (!con_commandmatch) if (!con_commandmatch)
con_commandmatch = 1; con_commandmatch = 1;
if (desc)
Con_Footerf(false, "%s: %s", cmd, desc);
return; return;
} }
} }
cmd = Cmd_CompleteCommand (s, false, true, 0); cmd = Cmd_CompleteCommand (s, false, true, 0, &desc);
if (cmd) if (cmd)
{ {
i = key_lines[edit_line][1] == '/'?2:1; i = key_lines[edit_line][1] == '/'?2:1;
@ -323,13 +327,25 @@ void CompleteCommand (qboolean force)
if (!con_commandmatch) if (!con_commandmatch)
con_commandmatch = 1; con_commandmatch = 1;
if (desc)
Con_Footerf(false, "%s: %s", cmd, desc);
return; //don't alter con_commandmatch if we compleated a tiny bit more return; //don't alter con_commandmatch if we compleated a tiny bit more
} }
} }
con_commandmatch++; con_commandmatch++;
if (!Cmd_CompleteCommand(s, true, true, con_commandmatch)) if (Cmd_CompleteCommand(s, true, true, con_commandmatch, &desc))
{
if (desc)
Con_Footerf(false, "%s: %s", cmd, desc);
}
else
{
Con_Footerf(false, "");
con_commandmatch = 1; con_commandmatch = 1;
}
} }
//lines typed at the main console enter here //lines typed at the main console enter here
@ -338,6 +354,8 @@ void Con_ExecuteLine(console_t *con, char *line)
qboolean waschat = false; qboolean waschat = false;
con_commandmatch=1; con_commandmatch=1;
Con_Footerf(false, "");
if (cls.state >= ca_connected && cl_chatmode.value == 2) if (cls.state >= ca_connected && cl_chatmode.value == 2)
{ {
waschat = true; waschat = true;
@ -451,6 +469,192 @@ void Key_ConsoleInsert(char *instext)
} }
} }
void Key_DefaultLinkClicked(char *text, char *info)
{
char *c;
/*the engine supports specific default links*/
/*we don't support everything. a: there's no point. b: unbindall links are evil.*/
c = Info_ValueForKey(info, "player");
if (*c)
{
unsigned int player = atoi(c);
int i;
if (player >= MAX_CLIENTS || !*cl.players[player].name)
return;
c = Info_ValueForKey(info, "action");
if (*c)
{
if (!strcmp(c, "mute"))
{
if (!cl.players[player].vignored)
{
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] muted\n", cl.players[player].name, player);
}
else
{
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unmuted\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "ignore"))
{
if (!cl.players[player].ignored)
{
cl.players[player].ignored = true;
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] ignored\n", cl.players[player].name, player);
}
else
{
cl.players[player].ignored = false;
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unignored\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "spec"))
{
Cam_TrackPlayer(0, "spectate", cl.players[player].name);
}
else if (!strcmp(c, "kick"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nclientkick %i\n", player), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon kick %s\n", cl.players[player].name), RESTRICT_LOCAL);
}
else if (!strcmp(c, "ban"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nbanname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon banname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
return;
}
Con_Footerf(false, "^m#^m ^[%s\\player\\%i^]: %if %ims", cl.players[player].name, player, cl.players[player].frags, cl.players[player].ping);
for (i = 0; i < cl.splitclients; i++)
{
if (cl.playernum[i] == player)
break;
}
if (i == cl.splitclients)
{
extern cvar_t rcon_password;
if (cl.spectator || cls.demoplayback)
{
//we're spectating, or an mvd
Con_Footerf(true, " ^[Spectate\\player\\%i\\action\\spec^]", player);
}
else
{
//we're playing.
if (cls.protocol == CP_QUAKEWORLD && strcmp(cl.players[cl.playernum[0]].team, cl.players[player].team))
Con_Footerf(true, " ^[[Join Team %s]\\cmd\\setinfo team %s^]", cl.players[player].team, cl.players[player].team);
}
Con_Footerf(true, " ^[%sgnore\\player\\%i\\action\\ignore^]", cl.players[player].ignored?"Uni":"I", player);
// if (cl_voip_play.ival)
Con_Footerf(true, " ^[%sute\\player\\%i\\action\\mute^]", cl.players[player].vignored?"Unm":"M", player);
if (!cls.demoplayback && (*rcon_password.string
#ifndef CLIENTONLY
|| (sv.state && svs.clients[player].netchan.remote_address.type != NA_LOOPBACK)
#endif
))
{
Con_Footerf(true, " ^[Kick\\player\\%i\\action\\kick^]", player);
Con_Footerf(true, " ^[Ban\\player\\%i\\action\\ban^]", player);
}
}
else
{
char cmdprefix[6];
snprintf(cmdprefix, sizeof(cmdprefix), "%i ", i);
//hey look! its you!
if (cl.spectator || cls.demoplayback)
{
//need join option here or something
}
else
{
Con_Footerf(true, " ^[Suicide\\cmd\\kill^]");
#ifndef CLIENTONLY
if (!sv.state)
Con_Footerf(true, " ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats || (sv.state && sv.allocated_client_slots == 1))
#else
Con_Footerf(true, " ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats)
#endif
{
Con_Footerf(true, " ^[Noclip\\cmd\\noclip^]");
Con_Footerf(true, " ^[Fly\\cmd\\fly^]");
Con_Footerf(true, " ^[God\\cmd\\god^]");
Con_Footerf(true, " ^[Give\\impulse\\9^]");
}
}
}
return;
}
c = Info_ValueForKey(info, "desc");
if (*c)
{
Con_Footerf(false, "%s", c);
return;
}
c = Info_ValueForKey(info, "connect");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nconnect %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "qtv");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nqtvplay %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "demo");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nplaydemo %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "cmd");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\ncmd %s\n", c), RESTRICT_LOCAL);
return;
}
c = Info_ValueForKey(info, "impulse");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nimpulse %s\n", c), RESTRICT_LOCAL);
return;
}
if (!*info && *text == '/')
{
Q_strncpyz(key_lines[edit_line]+1, text, sizeof(key_lines[edit_line])-1);
key_linepos = strlen(key_lines[edit_line]);
return;
}
}
void Key_ConsoleRelease(int key, int unicode) void Key_ConsoleRelease(int key, int unicode)
{ {
extern int mousecursor_x, mousecursor_y; extern int mousecursor_x, mousecursor_y;
@ -461,6 +665,7 @@ void Key_ConsoleRelease(int key, int unicode)
if (abs(con_mousedown[0] - mousecursor_x) < 5 && abs(con_mousedown[1] - mousecursor_y) < 5) if (abs(con_mousedown[0] - mousecursor_x) < 5 && abs(con_mousedown[1] - mousecursor_y) < 5)
{ {
buffer = Con_CopyConsole(false); buffer = Con_CopyConsole(false);
Con_Footerf(false, "");
if (!buffer) if (!buffer)
return; return;
if (keydown[K_SHIFT]) if (keydown[K_SHIFT])
@ -506,156 +711,13 @@ void Key_ConsoleRelease(int key, int unicode)
{ {
if (end[0] == '^' && end[1] == ']') if (end[0] == '^' && end[1] == ']')
{ {
char *c;
//okay, its a valid link that they clicked //okay, its a valid link that they clicked
*end = 0; *end = 0;
#ifdef CSQC_DAT #ifdef CSQC_DAT
if (!CSQC_ConsoleLink(buffer+2, info)) if (!CSQC_ConsoleLink(buffer+2, info))
#endif #endif
{ {
/*the engine supports specific default links*/ Key_DefaultLinkClicked(buffer+2, info);
/*we don't support everything. a: there's no point. b: unbindall links are evil.*/
c = Info_ValueForKey(info, "player");
if (*c)
{
unsigned int player = atoi(c);
int i;
if (player >= MAX_CLIENTS)
break;
c = Info_ValueForKey(info, "action");
if (*c)
{
if (!strcmp(c, "mute"))
{
if (!cl.players[player].vignored)
{
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] muted\n", cl.players[player].name, player);
}
else
{
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unmuted\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "ignore"))
{
if (!cl.players[player].ignored)
{
cl.players[player].ignored = true;
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] ignored\n", cl.players[player].name, player);
}
else
{
cl.players[player].ignored = false;
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unignored\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "kick"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nclientkick %i\n", player), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon kick %s\n", cl.players[player].name), RESTRICT_LOCAL);
}
else if (!strcmp(c, "ban"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nbanname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon banname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
break;
}
Con_Printf("^m#^m ^[%s\\player\\%i^]: %if %ims", cl.players[player].name, player, cl.players[player].frags, cl.players[player].ping);
for (i = 0; i < cl.splitclients; i++)
{
if (cl.playernum[i] == player)
break;
}
if (i == cl.splitclients)
{
extern cvar_t rcon_password;
if (cls.protocol == CP_QUAKEWORLD && strcmp(cl.players[cl.playernum[0]].team, cl.players[player].team))
Con_Printf(" ^[[Join Team %s]\\cmd\\setinfo team %s^]", cl.players[player].team, cl.players[player].team);
Con_Printf(" ^[%sgnore\\player\\%i\\action\\ignore^]", cl.players[player].ignored?"Uni":"I", player);
// if (cl_voip_play.ival)
Con_Printf(" ^[%sute\\player\\%i\\action\\mute^]", cl.players[player].vignored?"Unm":"M", player);
if (*rcon_password.string
#ifndef CLIENTONLY
|| (sv.state && svs.clients[player].netchan.remote_address.type != NA_LOOPBACK)
#endif
)
{
Con_Printf(" ^[Kick\\player\\%i\\action\\kick^]", player);
Con_Printf(" ^[Ban\\player\\%i\\action\\ban^]", player);
}
}
else
{
char cmdprefix[6];
snprintf(cmdprefix, sizeof(cmdprefix), "%i ", i);
//hey look! its you!
Con_Printf(" ^[Suicide\\cmd\\kill^]");
#ifndef CLIENTONLY
if (!sv.state)
Con_Printf(" ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats || (sv.state && sv.allocated_client_slots == 1))
#else
Con_Printf(" ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats)
#endif
{
Con_Printf(" ^[Noclip\\cmd\\noclip^]");
Con_Printf(" ^[Fly\\cmd\\fly^]");
Con_Printf(" ^[God\\cmd\\god^]");
Con_Printf(" ^[Give\\impulse\\9^]");
}
}
Con_Printf("\r");
break;
}
c = Info_ValueForKey(info, "connect");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nconnect %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "qtv");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nqtvplay %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "cmd");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\ncmd %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "impulse");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nimpulse %s\n", c), RESTRICT_LOCAL);
break;
}
} }
break; break;
@ -669,6 +731,8 @@ void Key_ConsoleRelease(int key, int unicode)
} }
Z_Free(buffer); Z_Free(buffer);
} }
else
Con_Footerf(false, "");
} }
if (key == K_MOUSE2 && con_mousedown[2] == 2) if (key == K_MOUSE2 && con_mousedown[2] == 2)
{ {
@ -700,7 +764,7 @@ unsigned char *utf_left(unsigned char *start, unsigned char *cursor)
if (*cursor == ']' && cursor > start && cursor[-1] == '^') if (*cursor == ']' && cursor > start && cursor[-1] == '^')
{ {
//just stepped onto a link //just stepped onto a link
char *linkstart; unsigned char *linkstart;
linkstart = cursor-1; linkstart = cursor-1;
while(linkstart >= start) while(linkstart >= start)
{ {
@ -834,7 +898,7 @@ void Key_Console (unsigned int unicode, int key)
if (key == K_ENTER) if (key == K_ENTER)
{ // backslash text are commands, else chat { // backslash text are commands, else chat
int oldl = edit_line; int oldl = edit_line;
edit_line = (edit_line + 1) & 31; edit_line = (edit_line + 1) & (CON_EDIT_LINES_MASK);
history_line = edit_line; history_line = edit_line;
key_lines[edit_line][0] = ']'; key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = '\0'; key_lines[edit_line][1] = '\0';
@ -846,9 +910,12 @@ void Key_Console (unsigned int unicode, int key)
return; return;
} }
if (key == K_SPACE && con_current->commandcompletion) if (key == K_SPACE && keydown[K_CTRL] && con_current->commandcompletion)
{ {
if (keydown[K_CTRL] && Cmd_CompleteCommand(key_lines[edit_line]+1, true, true, con_current->commandcompletion)) char *txt = key_lines[edit_line]+1;
if (*txt == '/')
txt++;
if (Cmd_CompleteCommand(txt, true, true, con_current->commandcompletion, NULL))
{ {
CompleteCommand (true); CompleteCommand (true);
return; return;
@ -867,7 +934,7 @@ void Key_Console (unsigned int unicode, int key)
CompleteCommand (false); CompleteCommand (false);
return; return;
} }
if (key != K_SHIFT && con_commandmatch) if (key != K_CTRL && key != K_SHIFT && con_commandmatch)
con_commandmatch=1; con_commandmatch=1;
if (key == K_LEFTARROW) if (key == K_LEFTARROW)
@ -913,11 +980,11 @@ void Key_Console (unsigned int unicode, int key)
{ {
do do
{ {
history_line = (history_line - 1) & 31; history_line = (history_line - 1) & CON_EDIT_LINES_MASK;
} while (history_line != edit_line } while (history_line != edit_line
&& !key_lines[history_line][1]); && !key_lines[history_line][1]);
if (history_line == edit_line) if (history_line == edit_line)
history_line = (edit_line+1)&31; history_line = (edit_line+1)&CON_EDIT_LINES_MASK;
Q_strcpy(key_lines[edit_line], key_lines[history_line]); Q_strcpy(key_lines[edit_line], key_lines[history_line]);
key_linepos = Q_strlen(key_lines[edit_line]); key_linepos = Q_strlen(key_lines[edit_line]);
@ -936,7 +1003,7 @@ void Key_Console (unsigned int unicode, int key)
} }
do do
{ {
history_line = (history_line + 1) & 31; history_line = (history_line + 1) & CON_EDIT_LINES_MASK;
} }
while (history_line != edit_line while (history_line != edit_line
&& !key_lines[history_line][1]); && !key_lines[history_line][1]);
@ -1105,7 +1172,7 @@ void Key_Console (unsigned int unicode, int key)
} }
} }
if (keydown[K_ALT]) if (keydown[K_ALT] && key > 32 && key < 128)
key |= 128; // red char key |= 128; // red char
} }
@ -1524,7 +1591,7 @@ void Key_Init (void)
{ {
int i; int i;
for (i=0 ; i<32 ; i++) for (i=0 ; i<=CON_EDIT_LINES_MASK ; i++)
{ {
key_lines[i][0] = ']'; key_lines[i][0] = ']';
key_lines[i][1] = 0; key_lines[i][1] = 0;
@ -1611,9 +1678,9 @@ qboolean Key_MouseShouldBeFree(void)
//if true, the input code is expected to return mouse cursor positions rather than deltas //if true, the input code is expected to return mouse cursor positions rather than deltas
extern cvar_t cl_prydoncursor; extern cvar_t cl_prydoncursor;
// extern int mouseusedforgui; extern int mouseusedforgui;
// if (mouseusedforgui) //I don't like this if (mouseusedforgui) //I don't like this
// return true; return true;
// if (!ActiveApp) // if (!ActiveApp)
// return true; // return true;

View file

@ -803,3 +803,173 @@ void Menu_DownloadStuff_f (void)
#endif #endif
#ifdef AVAIL_ZLIB
static int numbootdownloads;
#include "fs.h"
extern searchpathfuncs_t zipfilefuncs;
static int CL_BootDownload_Extract(const char *fname, int fsize, void *ptr)
{
char buffer[512*1024];
int read;
void *zip = ptr;
flocation_t loc;
int slashes;
const char *s;
vfsfile_t *compressedpak;
vfsfile_t *decompressedpak;
if (zipfilefuncs.FindFile(zip, &loc, fname, NULL))
{
compressedpak = zipfilefuncs.OpenVFS(zip, &loc, "rb");
if (compressedpak)
{
//this extra logic is so we can handle things like nexuiz/data/blah.pk3
//as well as just data/blah.pk3
slashes = 0;
for (s = strchr(fname, '/'); s; s = strchr(s+1, '/'))
slashes++;
for (; slashes > 1; slashes--)
fname = strchr(fname, '/')+1;
if (!slashes)
{
FS_CreatePath(fname, FS_GAMEONLY);
decompressedpak = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
}
else
{
FS_CreatePath(fname, FS_ROOT);
decompressedpak = FS_OpenVFS(fname, "wb", FS_ROOT);
}
if (decompressedpak)
{
for(;;)
{
read = VFS_READ(compressedpak, buffer, sizeof(buffer));
if (read <= 0)
break;
if (VFS_WRITE(decompressedpak, buffer, read) != read)
{
Con_Printf("write failed writing %s. disk full?\n", fname);
break;
}
}
VFS_CLOSE(decompressedpak);
}
VFS_CLOSE(compressedpak);
}
}
return true;
}
static void CL_BootDownload_Complete(struct dl_download *dl)
{
void *zip;
/*
int sz;
char *buf;
FILE *f;
sz = VFS_GETLEN(dl->file);
buf = malloc(sz);
VFS_READ(dl->file, buf, sz);
f = fopen("C:/Games/Quake/test/emptybasedir/test.zip", "wb");
fwrite(buf, 1, sz, f);
fclose(f);
free(buf);
*/
if (dl->status == DL_FINISHED)
zip = zipfilefuncs.OpenNew(dl->file, dl->url);
else
zip = NULL;
/*the zip code will have eaten the file handle*/
dl->file = NULL;
if (zip)
{
/*scan it to extract its contents*/
zipfilefuncs.EnumerateFiles(zip, "*/*.pk3", CL_BootDownload_Extract, zip);
zipfilefuncs.EnumerateFiles(zip, "*/*.pak", CL_BootDownload_Extract, zip);
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pk3", CL_BootDownload_Extract, zip);
zipfilefuncs.EnumerateFiles(zip, "*/*/*.pak", CL_BootDownload_Extract, zip);
/*close it, delete the temp file from disk, etc*/
zipfilefuncs.ClosePath(zip);
/*restart the filesystem so those new files can be found*/
Cmd_ExecuteString("fs_restart\n", RESTRICT_LOCAL);
}
if (!--numbootdownloads)
{
CL_ExecInitialConfigs();
Cmd_StuffCmds();
Cbuf_Execute ();
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
}
}
qboolean CL_CheckBootDownloads(void)
{
char *downloads = fs_gamedownload.string;
char token[2048];
char *c, *s;
vfsfile_t *f;
struct dl_download *dl;
int mirrors;
while ((downloads = COM_ParseOut(downloads, token, sizeof(token))))
{
//FIXME: do we want to add some sort of file size indicator?
c = token;
while(*c && *c != ':' && *c != '|')
c++;
if (!*c) //erp?
continue;
*c++ = 0;
f = FS_OpenVFS(token, "rb", FS_ROOT);
if (f)
{
Con_DPrintf("Already have %s\n", token);
VFS_CLOSE(f);
continue;
}
mirrors = 1;
for (s = c; *s; s++)
{
if (*s == '|')
mirrors++;
}
mirrors = rand() % mirrors;
while(mirrors)
{
mirrors--;
while(*c != '|')
c++;
c++;
}
for (s = c; *s; s++)
{
if (*s == '|')
*s = 0;
}
Con_Printf("Attempting to download %s\n", c);
dl = HTTP_CL_Get(c, token, CL_BootDownload_Complete);
if (dl)
{
#ifdef MULTITHREAD
DL_CreateThread(dl, FS_OpenTemp(), CL_BootDownload_Complete);
#endif
numbootdownloads++;
}
}
return !numbootdownloads;
}
#else
qboolean CL_CheckBootDownloads(void)
{
return true;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -435,6 +435,8 @@ const char *presetexec[] =
"gl_specular 0;" "gl_specular 0;"
"r_loadlit 0;" "r_loadlit 0;"
"r_fastsky 1;" "r_fastsky 1;"
"r_waterstyle 0;"
"r_lavastyle 0;"
"r_shadow_realtime_dlight 0;" "r_shadow_realtime_dlight 0;"
"r_shadow_realtime_world 0;" "r_shadow_realtime_world 0;"
"r_glsl_offsetmapping 0;" "r_glsl_offsetmapping 0;"
@ -444,6 +446,7 @@ const char *presetexec[] =
"r_waterwarp 0;" "r_waterwarp 0;"
"r_lightstylesmooth 0;" "r_lightstylesmooth 0;"
"r_part_density 0.25;" "r_part_density 0.25;"
, // fast options , // fast options
"gl_texturemode ln;" "gl_texturemode ln;"
"r_particlesystem classic;" "r_particlesystem classic;"
@ -452,7 +455,10 @@ const char *presetexec[] =
"gl_flashblend 1;" "gl_flashblend 1;"
"r_loadlit 1;" "r_loadlit 1;"
"r_fastsky 0;" "r_fastsky 0;"
"r_waterstyle 1;"
"r_lavastyle 1;"
"r_nolightdir 0;" "r_nolightdir 0;"
, // normal options , // normal options
#ifdef MINIMAL #ifdef MINIMAL
"r_particlesystem classic;" "r_particlesystem classic;"
@ -467,6 +473,7 @@ const char *presetexec[] =
"gl_load24bit 1;" "gl_load24bit 1;"
"r_replacemodels \"md3 md2\";" "r_replacemodels \"md3 md2\";"
"r_waterwarp 1;" "r_waterwarp 1;"
, // nice options , // nice options
"r_stains 0.75;" "r_stains 0.75;"
"gl_texturemode ll;" "gl_texturemode ll;"
@ -476,14 +483,17 @@ const char *presetexec[] =
#endif #endif
"gl_specular 1;" "gl_specular 1;"
"r_loadlit 2;" "r_loadlit 2;"
"r_waterstyle 2;"
// "r_fastsky -1;" // "r_fastsky -1;"
"r_shadow_realtime_dlight 1;" "r_shadow_realtime_dlight 1;"
"gl_detail 1;" "gl_detail 1;"
"r_lightstylesmooth 1;" "r_lightstylesmooth 1;"
"gl_texture_anisotropic_filtering 4;" "gl_texture_anisotropic_filtering 4;"
, // realtime options , // realtime options
// "r_bloom 1;" // "r_bloom 1;"
"r_particledesc \"spikeset high tsshaft\";" "r_particledesc \"spikeset high tsshaft\";"
"r_waterstyle 3;"
"r_glsl_offsetmapping 1;" "r_glsl_offsetmapping 1;"
"r_shadow_realtime_world 1;" "r_shadow_realtime_world 1;"
"gl_texture_anisotropic_filtering 16;" "gl_texture_anisotropic_filtering 16;"

View file

@ -40,6 +40,7 @@ cvar_t slist_writeserverstxt = SCVAR("slist_writeservers", "0");
void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad); void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad);
void CL_QueryServers(void); void CL_QueryServers(void);
int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite); int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite);
void MasterInfo_RemoveAllPlayers(void);
master_t *master; master_t *master;
player_t *mplayers; player_t *mplayers;
@ -495,7 +496,7 @@ float Master_ReadKeyFloat(serverinfo_t *server, int keynum)
char *Master_ReadKeyString(serverinfo_t *server, int keynum) char *Master_ReadKeyString(serverinfo_t *server, int keynum)
{ {
char adr[MAX_ADR_SIZE]; static char adr[MAX_ADR_SIZE];
if (keynum < SLKEY_CUSTOM) if (keynum < SLKEY_CUSTOM)
{ {
@ -631,12 +632,26 @@ void Master_AddMaster (char *address, int type, char *description)
void MasterInfo_Shutdown(void) void MasterInfo_Shutdown(void)
{ {
master_t *mast; master_t *mast;
serverinfo_t *sv;
MasterInfo_RemoveAllPlayers();
while(firstserver)
{
sv = firstserver;
firstserver = sv->next;
Z_Free(sv);
}
while(master) while(master)
{ {
mast = master; mast = master;
master = mast->next; master = mast->next;
if (mast->dl)
DL_Close(mast->dl);
Z_Free(mast); Z_Free(mast);
} }
maxvisibleservers = 0;
numvisibleservers = 0;
Z_Free(visibleservers);
} }
void Master_AddMasterHTTP (char *address, int mastertype, char *description) void Master_AddMasterHTTP (char *address, int mastertype, char *description)
@ -1267,6 +1282,8 @@ void MasterInfo_ProcessHTTPJSON(struct dl_download *dl)
{ {
int len; int len;
char *buf; char *buf;
master_t *mast = dl->user_ctx;
mast->dl = NULL;
if (dl->file) if (dl->file)
{ {
len = VFS_GETLEN(dl->file); len = VFS_GETLEN(dl->file);
@ -1285,11 +1302,15 @@ void MasterInfo_ProcessHTTPJSON(struct dl_download *dl)
// wrapper functions for the different server types // wrapper functions for the different server types
void MasterInfo_ProcessHTTPNQ(struct dl_download *dl) void MasterInfo_ProcessHTTPNQ(struct dl_download *dl)
{ {
master_t *mast = dl->user_ctx;
mast->dl = NULL;
MasterInfo_ProcessHTTP(dl->file, SS_NETQUAKE); MasterInfo_ProcessHTTP(dl->file, SS_NETQUAKE);
} }
void MasterInfo_ProcessHTTPQW(struct dl_download *dl) void MasterInfo_ProcessHTTPQW(struct dl_download *dl)
{ {
master_t *mast = dl->user_ctx;
mast->dl = NULL;
MasterInfo_ProcessHTTP(dl->file, SS_GENERICQUAKEWORLD); MasterInfo_ProcessHTTP(dl->file, SS_GENERICQUAKEWORLD);
} }
#endif #endif
@ -1368,13 +1389,28 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles)
#endif #endif
#ifdef WEBCLIENT #ifdef WEBCLIENT
case MT_MASTERHTTPJSON: case MT_MASTERHTTPJSON:
HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPJSON); if (!mast->dl)
{
mast->dl = HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPJSON);
if (mast->dl)
mast->dl->user_ctx = mast;
}
break; break;
case MT_MASTERHTTPNQ: case MT_MASTERHTTPNQ:
HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPNQ); if (!mast->dl)
{
mast->dl = HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPNQ);
if (mast->dl)
mast->dl->user_ctx = mast;
}
break; break;
case MT_MASTERHTTPQW: case MT_MASTERHTTPQW:
HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPQW); if (!mast->dl)
{
mast->dl = HTTP_CL_Get(mast->address, NULL, MasterInfo_ProcessHTTPQW);
if (mast->dl)
mast->dl->user_ctx = mast;
}
break; break;
#endif #endif
} }
@ -1757,6 +1793,16 @@ serverinfo_t *Master_InfoForNum (int num)
return NULL; return NULL;
} }
void MasterInfo_RemoveAllPlayers(void)
{
player_t *p;
while(mplayers)
{
p = mplayers;
mplayers = p->next;
Z_Free(p);
}
}
void MasterInfo_RemovePlayers(netadr_t adr) void MasterInfo_RemovePlayers(netadr_t adr)
{ {
player_t *p, *prev; player_t *p, *prev;

View file

@ -1779,6 +1779,8 @@ static void P_ImportEffectInfo_f(void)
args--; args--;
} }
line = COM_StringParse(line, com_token, sizeof(com_token), false, false); line = COM_StringParse(line, com_token, sizeof(com_token), false, false);
if (!line)
break;
Q_strncpyz(arg[args], com_token, sizeof(arg[args])); Q_strncpyz(arg[args], com_token, sizeof(arg[args]));
args++; args++;
if (*com_token == '\n') if (*com_token == '\n')
@ -4655,8 +4657,13 @@ static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type)
c = b->next; c = b->next;
q = c->p; q = c->p;
if (!q)
continue;
p = b->p; p = b->p;
q->rgba[3] = 1;
p->rgba[3] = 1;
VectorSubtract(r_refdef.vieworg, q->org, v); VectorSubtract(r_refdef.vieworg, q->org, v);
VectorNormalize(v); VectorNormalize(v);
CrossProduct(c->dir, v, cr); CrossProduct(c->dir, v, cr);
@ -5108,7 +5115,11 @@ static void PScript_DrawParticleTypes (void)
{ {
while ((p=type->particles)) while ((p=type->particles))
{ {
if (pdraw) if (scenetri)
{
tdraw(scenetri, p, type->slooks);
}
else if (pdraw)
RQ_AddDistReorder(pdraw, p, type->slooks, p->org); RQ_AddDistReorder(pdraw, p, type->slooks, p->org);
// make sure emitter runs at least once // make sure emitter runs at least once

View file

@ -611,6 +611,13 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
cs_getframestate(in, rflags, &out->framestate); cs_getframestate(in, rflags, &out->framestate);
VectorCopy(in->v->origin, out->origin); VectorCopy(in->v->origin, out->origin);
VectorCopy(in->v->oldorigin, out->oldorigin);
if (in->v->enemy)
{
csqcedict_t *ed = (csqcedict_t*)PROG_TO_EDICT(csqcprogs, in->v->enemy);
VectorSubtract(out->oldorigin, ed->v->oldorigin, out->oldorigin);
}
if (rflags & CSQCRF_USEAXIS) if (rflags & CSQCRF_USEAXIS)
{ {
VectorCopy(csqcg.forward, out->axis[0]); VectorCopy(csqcg.forward, out->axis[0]);
@ -1394,6 +1401,7 @@ static void QCBUILTIN PF_R_SetViewFlag(progfuncs_t *prinst, struct globalvars_s
} }
} }
void R2D_PolyBlend (void);
static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
if (cl.worldmodel) if (cl.worldmodel)
@ -1404,13 +1412,7 @@ static void QCBUILTIN PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s
V_CalcGunPositionAngle(csqc_lplayernum, V_CalcBob(csqc_lplayernum, true)); V_CalcGunPositionAngle(csqc_lplayernum, V_CalcBob(csqc_lplayernum, true));
R_RenderView(); R_RenderView();
R2D_PolyBlend ();
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
GL_Set2D (false);
}
#endif
vid.recalc_refdef = 1; vid.recalc_refdef = 1;
@ -1686,7 +1688,7 @@ static void csqc_setmodel(progfuncs_t *prinst, csqcedict_t *ent, int modelindex)
ent->v->modelindex = modelindex; ent->v->modelindex = modelindex;
if (modelindex < 0) if (modelindex < 0)
{ {
if (modelindex <= -MAX_MODELS) if (modelindex <= -MAX_CSQCMODELS)
return; return;
ent->v->model = PR_SetString(prinst, cl.model_csqcname[-modelindex]); ent->v->model = PR_SetString(prinst, cl.model_csqcname[-modelindex]);
if (!cl.model_csqcprecache[-modelindex]) if (!cl.model_csqcprecache[-modelindex])
@ -3257,7 +3259,7 @@ static void QCBUILTIN PF_cl_runningserver (progfuncs_t *prinst, struct globalvar
#ifdef CLIENTONLY #ifdef CLIENTONLY
G_FLOAT(OFS_RETURN) = false; G_FLOAT(OFS_RETURN) = false;
#else #else
G_FLOAT(OFS_RETURN) = !!sv.active; G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
#endif #endif
} }
@ -4275,7 +4277,6 @@ static struct {
// {"bulleten", PF_bulleten, 243}, (removed builtin) // {"bulleten", PF_bulleten, 243}, (removed builtin)
{"rotatevectorsbytag", PF_rotatevectorsbytag, 244}, {"rotatevectorsbytag", PF_rotatevectorsbytag, 244},
#ifdef SQL
{"sqlconnect", PF_NoCSQC, 250}, // #250 float([string host], [string user], [string pass], [string defaultdb], [string driver]) sqlconnect (FTE_SQL) {"sqlconnect", PF_NoCSQC, 250}, // #250 float([string host], [string user], [string pass], [string defaultdb], [string driver]) sqlconnect (FTE_SQL)
{"sqldisconnect", PF_NoCSQC, 251}, // #251 void(float serveridx) sqldisconnect (FTE_SQL) {"sqldisconnect", PF_NoCSQC, 251}, // #251 void(float serveridx) sqldisconnect (FTE_SQL)
{"sqlopenquery", PF_NoCSQC, 252}, // #252 float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query) sqlopenquery (FTE_SQL) {"sqlopenquery", PF_NoCSQC, 252}, // #252 float(float serveridx, void(float serveridx, float queryidx, float rows, float columns, float eof) callback, float querytype, string query) sqlopenquery (FTE_SQL)
@ -4285,7 +4286,6 @@ static struct {
{"sqlescape", PF_NoCSQC, 256}, // #256 string(float serveridx, string data) sqlescape (FTE_SQL) {"sqlescape", PF_NoCSQC, 256}, // #256 string(float serveridx, string data) sqlescape (FTE_SQL)
{"sqlversion", PF_NoCSQC, 257}, // #257 string(float serveridx) sqlversion (FTE_SQL) {"sqlversion", PF_NoCSQC, 257}, // #257 string(float serveridx) sqlversion (FTE_SQL)
{"sqlreadfloat", PF_NoCSQC, 258}, // #258 float(float serveridx, float queryidx, float row, float column) sqlreadfloat (FTE_SQL) {"sqlreadfloat", PF_NoCSQC, 258}, // #258 float(float serveridx, float queryidx, float row, float column) sqlreadfloat (FTE_SQL)
#endif
{"stoi", PF_stoi, 259}, {"stoi", PF_stoi, 259},
{"itos", PF_itos, 260}, {"itos", PF_itos, 260},
@ -4293,7 +4293,7 @@ static struct {
{"htos", PF_htos, 262}, {"htos", PF_htos, 262},
{"skel_create", PF_skel_create, 263},//float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS) {"skel_create", PF_skel_create, 263},//float(float modlindex) skel_create = #263; // (FTE_CSQC_SKELETONOBJECTS)
{"skel_build", PF_skel_build, 264},//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS) {"skel_build", PF_skel_build, 264},//float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addition) skel_build = #264; // (FTE_CSQC_SKELETONOBJECTS)
{"skel_get_numbones", PF_skel_get_numbones, 265},//float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS) {"skel_get_numbones", PF_skel_get_numbones, 265},//float(float skel) skel_get_numbones = #265; // (FTE_CSQC_SKELETONOBJECTS)
{"skel_get_bonename", PF_skel_get_bonename, 266},//string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) (returns tempstring) {"skel_get_bonename", PF_skel_get_bonename, 266},//string(float skel, float bonenum) skel_get_bonename = #266; // (FTE_CSQC_SKELETONOBJECTS) (returns tempstring)
{"skel_get_boneparent", PF_skel_get_boneparent, 267},//float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS) {"skel_get_boneparent", PF_skel_get_boneparent, 267},//float(float skel, float bonenum) skel_get_boneparent = #267; // (FTE_CSQC_SKELETONOBJECTS)
@ -4623,6 +4623,8 @@ static struct {
{"isfunction", PF_isfunction, 607}, {"isfunction", PF_isfunction, 607},
{"parseentitydata", PF_parseentitydata, 608}, {"parseentitydata", PF_parseentitydata, 608},
{"findkeysforcommand", PF_cl_findkeysforcommand, 610},
{"sprintf", PF_sprintf, 627}, {"sprintf", PF_sprintf, 627},
{"getsurfacenumtriangles",PF_getsurfacenumtriangles,628}, {"getsurfacenumtriangles",PF_getsurfacenumtriangles,628},
@ -4831,6 +4833,10 @@ void CSQC_Shutdown(void)
memset(&deltafunction, 0, sizeof(deltafunction)); memset(&deltafunction, 0, sizeof(deltafunction));
memset(csqcdelta_playerents, 0, sizeof(csqcdelta_playerents)); memset(csqcdelta_playerents, 0, sizeof(csqcdelta_playerents));
Z_Free(csqcent);
csqcent = NULL;
maxcsqcentities = 0;
csqcmapentitydata = NULL; csqcmapentitydata = NULL;
csqcmapentitydataloaded = false; csqcmapentitydataloaded = false;
@ -5084,10 +5090,16 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
if (csqc_singlecheats || anycsqc) if (csqc_singlecheats || anycsqc)
{ {
Con_DPrintf("loading csaddon.dat...\n");
if (PR_LoadProgs(csqcprogs, "csaddon.dat", 0, NULL, 0) >= 0) if (PR_LoadProgs(csqcprogs, "csaddon.dat", 0, NULL, 0) >= 0)
{
Con_DPrintf("loaded csaddon.dat...\n");
loaded = true; loaded = true;
}
else
Con_DPrintf("unable to find csaddon.dat.\n");
} }
else
Con_DPrintf("skipping csaddon.dat due to cheat restrictions\n");
if (!loaded) if (!loaded)
{ {
@ -5188,9 +5200,8 @@ void CSQC_WorldLoaded(void)
#endif #endif
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0); worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
worldent->v->modelindex = 1;
worldent->v->model = PR_SetString(csqcprogs, cl.model_name[(int)worldent->v->modelindex]);
worldent->v->solid = SOLID_BSP; worldent->v->solid = SOLID_BSP;
csqc_setmodel(csqcprogs, worldent, 1);
if (csqcg.worldloaded) if (csqcg.worldloaded)
PR_ExecuteProgram(csqcprogs, csqcg.worldloaded); PR_ExecuteProgram(csqcprogs, csqcg.worldloaded);
@ -5357,7 +5368,7 @@ void CSQC_RegisterCvarsAndThings(void)
{ {
Cmd_AddCommand("coredump_csqc", CSQC_CoreDump); Cmd_AddCommand("coredump_csqc", CSQC_CoreDump);
Cmd_AddCommand ("extensionlist_csqc", PR_CSExtensionList_f); Cmd_AddCommand ("extensionlist_csqc", PR_CSExtensionList_f);
Cmd_AddCommand("cl_cmd", CSQC_GameCommand_f); Cmd_AddCommandD("cl_cmd", CSQC_GameCommand_f, "Calls the csqc's GameCommand function");
Cmd_AddCommand("breakpoint_csqc", CSQC_Breakpoint_f); Cmd_AddCommand("breakpoint_csqc", CSQC_Breakpoint_f);
Cvar_Register(&pr_csqc_memsize, CSQCPROGSGROUP); Cvar_Register(&pr_csqc_memsize, CSQCPROGSGROUP);

View file

@ -393,7 +393,8 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_
else if ((*str & CON_CHARMASK) == '\r') else if ((*str & CON_CHARMASK) == '\r')
px = ipx; px = ipx;
else else
px = Font_DrawScaleChar(px, py, size[0], size[1], *str++); px = Font_DrawScaleChar(px, py, size[0], size[1], *str);
str++;
} }
Font_InvalidateColour(); Font_InvalidateColour();
Font_EndString(font_conchar); Font_EndString(font_conchar);
@ -411,7 +412,7 @@ void QCBUILTIN PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_gl
else else
fontsize = 8; fontsize = 8;
if (mp_globs.drawfontscale) if (mp_globs.drawfontscale && !prinst->parms->user)
fontsize *= mp_globs.drawfontscale[1]; fontsize *= mp_globs.drawfontscale[1];
end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), !usecolours); end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), !usecolours);
@ -421,7 +422,7 @@ void QCBUILTIN PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_gl
px = Font_LineWidth(buffer, end); px = Font_LineWidth(buffer, end);
Font_EndString(font_conchar); Font_EndString(font_conchar);
if (mp_globs.drawfontscale) if (mp_globs.drawfontscale && !prinst->parms->user)
px *= mp_globs.drawfontscale[1]; px *= mp_globs.drawfontscale[1];
G_FLOAT(OFS_RETURN) = px * fontsize; G_FLOAT(OFS_RETURN) = px * fontsize;
@ -572,9 +573,13 @@ void QCBUILTIN PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr
return; return;
} }
//no control chars. use quake ones if so
if (chara < 32 && chara != '\t')
chara |= 0xe000;
Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y); Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y);
Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha);
Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK | /*0xe000|*/(chara&0xff)); Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK | /*0xe000|*/chara);
Font_InvalidateColour(); Font_InvalidateColour();
Font_EndString(font_conchar); Font_EndString(font_conchar);
@ -590,6 +595,7 @@ void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr
float alpha = G_FLOAT(OFS_PARM4); float alpha = G_FLOAT(OFS_PARM4);
// float flag = G_FLOAT(OFS_PARM5); // float flag = G_FLOAT(OFS_PARM5);
float x, y; float x, y;
unsigned int c;
if (!text) if (!text)
{ {
@ -602,7 +608,7 @@ void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr
y = pos[1]; y = pos[1];
Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha);
if (mp_globs.drawfontscale) if (mp_globs.drawfontscale && !prinst->parms->user)
{ {
size[0] *= mp_globs.drawfontscale[0]; size[0] *= mp_globs.drawfontscale[0];
size[1] *= mp_globs.drawfontscale[1]; size[1] *= mp_globs.drawfontscale[1];
@ -611,7 +617,12 @@ void QCBUILTIN PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr
{ {
//FIXME: which charset is this meant to be using? //FIXME: which charset is this meant to be using?
//quakes? 8859-1? utf8? some weird hacky mixture? //quakes? 8859-1? utf8? some weird hacky mixture?
x = Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK|/*0xe000|*/(*text++&0xff)); c = *text++&0xff;
if ((c&0x7f) < 32)
c |= 0xe000; //if its a control char, just use the quake range instead.
else if (c & 0x80)
c |= 0xe000; //if its a high char, just use the quake range instead. we could colour it, but why bother
x = Font_DrawScaleChar(x, y, size[0], size[1], CON_WHITEMASK|/*0xe000|*/c);
} }
Font_InvalidateColour(); Font_InvalidateColour();
Font_EndString(font_conchar); Font_EndString(font_conchar);
@ -704,6 +715,7 @@ void QCBUILTIN PF_mod (progfuncs_t *prinst, struct globalvars_s *pr_globals)
if (b == 0) if (b == 0)
{ {
Con_Printf("mod by zero\n"); Con_Printf("mod by zero\n");
*prinst->pr_trace = 1;
G_FLOAT(OFS_RETURN) = 0; G_FLOAT(OFS_RETURN) = 0;
} }
else else
@ -741,16 +753,25 @@ static void QCBUILTIN PF_menu_cvar (progfuncs_t *prinst, struct globalvars_s *pr
char *str; char *str;
str = PR_GetStringOfs(prinst, OFS_PARM0); str = PR_GetStringOfs(prinst, OFS_PARM0);
str = RemapCvarNameFromDPToFTE(str);
var = Cvar_Get(str, "", 0, "menu cvars"); if (!strcmp(str, "vid_conwidth"))
if (var) G_FLOAT(OFS_RETURN) = vid.width;
{ else if (!strcmp(str, "vid_conheight"))
if (var->latched_string) G_FLOAT(OFS_RETURN) = vid.height;
G_FLOAT(OFS_RETURN) = atof(var->latched_string); else
G_FLOAT(OFS_RETURN) = var->value;
}
else else
G_FLOAT(OFS_RETURN) = 0; {
str = RemapCvarNameFromDPToFTE(str);
var = Cvar_Get(str, "", 0, "menu cvars");
if (var)
{
if (var->latched_string)
G_FLOAT(OFS_RETURN) = atof(var->latched_string);
else
G_FLOAT(OFS_RETURN) = var->value;
}
else
G_FLOAT(OFS_RETURN) = 0;
}
} }
static void QCBUILTIN PF_menu_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_menu_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
@ -833,6 +854,10 @@ void QCBUILTIN PF_isserver (progfuncs_t *prinst, struct globalvars_s *pr_globals
G_FLOAT(OFS_RETURN) = sv.state != ss_dead; G_FLOAT(OFS_RETURN) = sv.state != ss_dead;
#endif #endif
} }
void QCBUILTIN PF_isdemo (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
G_FLOAT(OFS_RETURN) = !!cls.demoplayback;
}
//float clientstate(void) = #62; //float clientstate(void) = #62;
void QCBUILTIN PF_clientstate (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_clientstate (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -914,12 +939,12 @@ void QCBUILTIN PF_cl_setmousetarget (progfuncs_t *prinst, struct globalvars_s *p
extern int mouseusedforgui; extern int mouseusedforgui;
switch ((int)G_FLOAT(OFS_PARM0)) switch ((int)G_FLOAT(OFS_PARM0))
{ {
case 1: case 1: //1 is delta-based.
mouseusedforgui = true;
break;
case 2:
mouseusedforgui = false; mouseusedforgui = false;
break; break;
case 2: //2 is absolute.
mouseusedforgui = true;
break;
default: default:
PR_BIError(prinst, "PF_setmousetarget: not a valid destination\n"); PR_BIError(prinst, "PF_setmousetarget: not a valid destination\n");
} }
@ -929,7 +954,7 @@ void QCBUILTIN PF_cl_setmousetarget (progfuncs_t *prinst, struct globalvars_s *p
void QCBUILTIN PF_cl_getmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_cl_getmousetarget (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
extern int mouseusedforgui; extern int mouseusedforgui;
G_FLOAT(OFS_RETURN) = mouseusedforgui?1:2; G_FLOAT(OFS_RETURN) = mouseusedforgui?2:1;
} }
//vector getmousepos(void) = #66; //vector getmousepos(void) = #66;
@ -1406,6 +1431,37 @@ void QCBUILTIN PF_altstr_set(progfuncs_t *prinst, struct globalvars_s *pr_global
} }
//string(string serveraddress) crypto_getkeyfp
void QCBUILTIN PF_crypto_getkeyfp(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//not supported.
G_INT(OFS_RETURN) = 0;
}
//string(string serveraddress) crypto_getidfp
void QCBUILTIN PF_crypto_getidfp(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//not supported.
G_INT(OFS_RETURN) = 0;
}
//string(string serveraddress) crypto_getencryptlevel
void QCBUILTIN PF_crypto_getencryptlevel(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//not supported.
G_INT(OFS_RETURN) = 0;
}
//string(float i) crypto_getmykeyfp
void QCBUILTIN PF_crypto_getmykeyfp(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//not supported.
G_INT(OFS_RETURN) = 0;
}
//string(float i) crypto_getmyidfp
void QCBUILTIN PF_crypto_getmyidfp(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
//not supported.
G_INT(OFS_RETURN) = 0;
}
builtin_t menu_builtins[] = { builtin_t menu_builtins[] = {
//0 //0
PF_Fixme, PF_Fixme,
@ -1527,7 +1583,7 @@ builtin_t menu_builtins[] = {
PF_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS) PF_infoadd, // #226 string(string info, string key, string value, ...) infoadd (FTE_STRINGS)
PF_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS) PF_infoget, // #227 string(string info, string key) infoget (FTE_STRINGS)
PF_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS) PF_strncmp, // #228 float(string s1, string s2, float len) strncmp (FTE_STRINGS)
PF_strncasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS) PF_strcasecmp, // #229 float(string s1, string s2) strcasecmp (FTE_STRINGS)
//230 //230
PF_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS) PF_strncasecmp, // #230 float(string s1, string s2, float len) strncasecmp (FTE_STRINGS)
skip1 skip1
@ -1543,7 +1599,21 @@ builtin_t menu_builtins[] = {
skip10 skip10
skip50 skip50
//300 //300
skip100 skip10
skip10
skip10
skip10
skip1
skip1
skip1
skip1
skip1
skip1
skip1
skip1
skip1
PF_isdemo,
skip50
//400 //400
skip10 skip10
skip10 skip10
@ -1677,7 +1747,7 @@ builtin_t menu_builtins[] = {
PF_M_sethostcachemasknumber, PF_M_sethostcachemasknumber,
PF_M_resorthostcache, PF_M_resorthostcache,
PF_M_sethostcachesort, PF_M_sethostcachesort,
PF_M_refreshhostcache, PF_M_refreshhostcache, //600
PF_M_gethostcachenumber, PF_M_gethostcachenumber,
PF_M_gethostcacheindexforkey, PF_M_gethostcacheindexforkey,
PF_M_addwantedhostcachekey, PF_M_addwantedhostcachekey,
@ -1692,16 +1762,14 @@ builtin_t menu_builtins[] = {
PF_sprintf, /*sprintf*/ PF_sprintf, /*sprintf*/
skip1 /*not listed in dp*/ skip1 /*not listed in dp*/
skip1 /*not listed in dp*/ skip1 /*not listed in dp*/
skip1 /*setkeybind*/ skip1 /*setkeybind*/ //630
skip1 /*getbindmaps*/ skip1 /*getbindmaps*/
skip1 /*setbindmaps*/ skip1 /*setbindmaps*/
skip1 /*crypto*/ PF_crypto_getkeyfp, /*crypto*/
skip1 /*crypto*/ PF_crypto_getidfp, /*crypto*/
skip1 /*crypto*/ PF_crypto_getencryptlevel, /*crypto*/
skip1 /*crypto*/ PF_crypto_getmykeyfp, /*crypto*/
skip1 /*crypto #637*/ PF_crypto_getmyidfp, /*crypto #637*/
}; };
int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]); int menu_numbuiltins = sizeof(menu_builtins)/sizeof(menu_builtins[0]);
@ -1752,6 +1820,10 @@ void MP_Shutdown (void)
PR_fclose_progs(menuprogs); PR_fclose_progs(menuprogs);
search_close_progs(menuprogs, true); search_close_progs(menuprogs, true);
#ifdef CL_MASTER
Master_ClearMasks();
#endif
CloseProgs(menuprogs); CloseProgs(menuprogs);
#ifdef TEXTEDITOR #ifdef TEXTEDITOR
Editor_ProgsKilled(menuprogs); Editor_ProgsKilled(menuprogs);
@ -1762,12 +1834,6 @@ void MP_Shutdown (void)
m_state = 0; m_state = 0;
mouseusedforgui = false; mouseusedforgui = false;
if (inmenuprogs) //something in the menu caused the problem, so...
{
inmenuprogs = 0;
longjmp(mp_abort, 1);
}
} }
pbool QC_WriteFile(const char *name, void *data, int len); pbool QC_WriteFile(const char *name, void *data, int len);
@ -1797,6 +1863,12 @@ void VARGS Menu_Abort (char *format, ...)
} }
MP_Shutdown(); MP_Shutdown();
if (inmenuprogs) //something in the menu caused the problem, so...
{
inmenuprogs = 0;
longjmp(mp_abort, 1);
}
} }
void MP_CvarChanged(cvar_t *var) void MP_CvarChanged(cvar_t *var)
@ -1858,13 +1930,14 @@ qboolean MP_Init (void)
menuprogparms.sv_num_edicts = &num_menu_edicts; menuprogparms.sv_num_edicts = &num_menu_edicts;
menuprogparms.useeditor = NULL;//sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms); menuprogparms.useeditor = NULL;//sorry... QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
menuprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms);
menutime = Sys_DoubleTime(); menutime = Sys_DoubleTime();
if (!menuprogs) if (!menuprogs)
{ {
Con_DPrintf("Initializing menu.dat\n"); Con_DPrintf("Initializing menu.dat\n");
menuprogs = InitProgs(&menuprogparms); menuprogs = InitProgs(&menuprogparms);
PR_Configure(menuprogs, -1, 1); PR_Configure(menuprogs, 64*1024*1024, 1);
if (PR_LoadProgs(menuprogs, "menu.dat", 10020, NULL, 0) < 0) //no per-progs builtins. if (PR_LoadProgs(menuprogs, "menu.dat", 10020, NULL, 0) < 0) //no per-progs builtins.
{ {
//failed to load or something //failed to load or something
@ -1886,11 +1959,8 @@ qboolean MP_Init (void)
if (mp_time) if (mp_time)
*mp_time = Sys_DoubleTime(); *mp_time = Sys_DoubleTime();
#ifdef warningmsg mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL);
#pragma warningmsg("disabled until csqc gets forked or some such") mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL);
#endif
//mp_globs.drawfont = (float*)PR_FindGlobal(menuprogs, "drawfont", 0, NULL);
//mp_globs.drawfontscale = (float*)PR_FindGlobal(menuprogs, "drawfontscale", 0, NULL);
menuentsize = PR_InitEnts(menuprogs, 8192); menuentsize = PR_InitEnts(menuprogs, 8192);
@ -1971,6 +2041,12 @@ void MP_Draw(void)
void MP_Keydown(int key, int unicode) void MP_Keydown(int key, int unicode)
{ {
extern qboolean keydown[K_MAX]; extern qboolean keydown[K_MAX];
#ifdef TEXTEDITOR
if (editormodal)
return;
#endif
if (setjmp(mp_abort)) if (setjmp(mp_abort))
return; return;
@ -2008,6 +2084,11 @@ void MP_Keydown(int key, int unicode)
void MP_Keyup(int key, int unicode) void MP_Keyup(int key, int unicode)
{ {
#ifdef TEXTEDITOR
if (editormodal)
return;
#endif
if (setjmp(mp_abort)) if (setjmp(mp_abort))
return; return;
@ -2030,6 +2111,10 @@ qboolean MP_Toggle(void)
{ {
if (!menuprogs) if (!menuprogs)
return false; return false;
#ifdef TEXTEDITOR
if (editormodal)
return false;
#endif
if (setjmp(mp_abort)) if (setjmp(mp_abort))
return false; return false;

View file

@ -21,6 +21,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
this file deals with qc builtins to apply custom skeletal blending (skeletal objects extension), as well as the logic required to perform realtime ragdoll, if I ever implement that. this file deals with qc builtins to apply custom skeletal blending (skeletal objects extension), as well as the logic required to perform realtime ragdoll, if I ever implement that.
*/ */
/*
skeletal objects are just a set of bone poses.
they are separate from the entity they are attached to, and must be created/destroyed separately.
typically the bones are all stored relative to their parent.
qc must use skel_build to copy animation data from the file format into the skeletal object for rendering, but can build different bones using different animations or can override explicit bones.
ragdoll file is a description of the joints in the ragdoll.
a skeletal object, built from a doll instead of a model, has a series of physics objects created at key points (ie: not face).
these objects are absolute
qc must build the skeletal object still, which fills the skeletal object from the physics objects instead of animation data, for bones that have solid objects.
*/
#include "quakedef.h" #include "quakedef.h"
#if defined(CSQC_DAT) || !defined(CLIENTONLY) #if defined(CSQC_DAT) || !defined(CLIENTONLY)
@ -36,21 +48,25 @@ this file deals with qc builtins to apply custom skeletal blending (skeletal obj
typedef struct doll_s typedef struct doll_s
{ {
char *name; char *name;
int uses;
model_t *model; model_t *model;
struct doll_s *next; struct doll_s *next;
int numbodies; int numbodies;
int numjoints; int numjoints;
int numbones;
struct struct
{ {
char name[32];
int bone; int bone;
char *name; } *body;
} body[32]; odejointinfo_t *joint;
struct struct
{ {
int type; //easy lookup table for bone->body.
int body[2]; //most of these will be -1, which means 'import from animation object'
} joint[32]; int bodyidx;
} *bone;
} doll_t; } doll_t;
enum enum
@ -60,6 +76,8 @@ enum
}; };
typedef struct typedef struct
{ {
odebody_t odebody;
int ownerent; /*multiple of 12*/ int ownerent; /*multiple of 12*/
int flags; int flags;
@ -77,8 +95,8 @@ typedef struct skelobject_s
world_t *world; /*be it ssqc or csqc*/ world_t *world; /*be it ssqc or csqc*/
enum enum
{ {
SKOT_RELATIVE, SKOT_RELATIVE, //relative to parent
SKOT_ABSOLUTE SKOT_ABSOLUTE //relative to model
} type; } type;
unsigned int numbones; unsigned int numbones;
@ -88,6 +106,8 @@ typedef struct skelobject_s
struct skelobject_s *animsource; struct skelobject_s *animsource;
unsigned int numbodies; unsigned int numbodies;
body_t *body; body_t *body;
int numjoints;
odejoint_t *joint;
doll_t *doll; doll_t *doll;
#endif #endif
} skelobject_t; } skelobject_t;
@ -177,13 +197,37 @@ static void bonematident_toqcvectors(float vx[3], float vy[3], float vz[3], floa
static qboolean pendingkill; /*states that there is a skel waiting to be killed*/ static qboolean pendingkill; /*states that there is a skel waiting to be killed*/
#ifdef RAGDOLL #ifdef RAGDOLL
doll_t *rag_loaddoll(model_t *mod, char *fname) void rag_uninstanciate(skelobject_t *sko);
int rag_finddollbody(doll_t *d, char *bodyname)
{
int i;
for (i = 0; i < d->numbodies; i++)
{
if (!strcmp(d->body[i].name, bodyname))
return i;
}
return -1;
}
int rag_finddolljoint(doll_t *d, char *name)
{
int i;
for (i = 0; i < d->numjoints; i++)
{
if (!strcmp(d->joint[i].name, name))
return i;
}
return -1;
}
doll_t *rag_loaddoll(model_t *mod, char *fname, int numbones)
{ {
doll_t *d; doll_t *d;
void *fptr = NULL; void *fptr = NULL;
char *file; char *file;
int fsize; int fsize;
int i, j; int i;
char *cmd;
galiasbone_t *bones;
int errors = 0;
for (d = dolllist; d; d = d->next) for (d = dolllist; d; d = d->next)
{ {
@ -192,49 +236,180 @@ doll_t *rag_loaddoll(model_t *mod, char *fname)
return d; return d;
} }
bones = Mod_GetBoneInfo(mod);
if (!bones)
{
//model not skeletal.
return NULL;
}
fsize = FS_LoadFile(fname, &fptr); fsize = FS_LoadFile(fname, &fptr);
if (!fptr) if (!fptr)
return NULL; return NULL;
d = malloc(sizeof(*d)); d = malloc(sizeof(*d));
d->next = dolllist; d->next = dolllist;
dolllist = d; dolllist = d;
d->name = strdup(fname); d->name = strdup(fname);
d->model = mod; d->model = mod;
d->numbodies = 0; d->numbodies = 0;
d->body = NULL;
d->numjoints = 0; d->numjoints = 0;
d->uses = 0;
d->joint = NULL;
d->numbones = numbones;
d->bone = malloc(sizeof(*d->bone) * d->numbones);
for (i = 0; i < d->numbones; i++)
d->bone[i].bodyidx = -1;
file = fptr; file = fptr;
while(file) while(file && *file)
{ {
file = COM_Parse(file); file = Cmd_TokenizeString(file, false, false);
if (!strcmp(com_token, "body")) cmd = Cmd_Argv(0);
if (!stricmp(cmd, "body"))
{ {
file = COM_Parse(file); int boneidx;
d->body[d->numbodies].name = strdup(com_token); boneidx = Mod_TagNumForName(d->model, Cmd_Argv(2))-1;
file = COM_Parse(file); if (boneidx >= 0)
d->body[d->numbodies].bone = Mod_TagNumForName(d->model, com_token);
d->numbodies++;
}
else if (!strcmp(com_token, "joint"))
{
for (i = 0; i < 2; i++)
{ {
file = COM_Parse(file); d->body = realloc(d->body, sizeof(*d->body)*(d->numbodies+1));
d->joint[d->numjoints].body[i] = 0; Q_strncpyz(d->body[d->numbodies].name, Cmd_Argv(1), sizeof(d->body[d->numbodies].name));
for (j = 0; j < d->numbodies; j++) d->bone[boneidx].bodyidx = d->numbodies;
{ d->body[d->numbodies].bone = boneidx;
if (!strcmp(d->body[j].name, com_token)) d->numbodies++;
{
d->joint[d->numjoints].body[i] = j;
break;
}
}
} }
d->numjoints++; else if (!errors++)
Con_Printf("Unable to create body \"%s\" because bone \"%s\" does not exist in \"%s\"\n", Cmd_Argv(1), Cmd_Argv(2), mod->name);
}
else if (!stricmp(cmd, "joint"))
{
odejointinfo_t *joint;
char *name;
d->joint = realloc(d->joint, sizeof(*d->joint)*(d->numjoints+1));
joint = &d->joint[d->numjoints];
memset(joint, 0, sizeof(*joint));
Q_strncpyz(joint->name, Cmd_Argv(1), sizeof(joint->name));
name = Cmd_Argv(2);
joint->body1 = *name?rag_finddollbody(d, name):-1;
if (*name && joint->body1 < 0 && !errors++)
{
Con_Printf("Joint \"%s\" joints invalid body \"%s\" in \"%s\"\n", joint->name, name, fname);
continue;
}
name = Cmd_Argv(3);
joint->body2 = *name?rag_finddollbody(d, name):-1;
if (*name && (joint->body2 < 0 || joint->body2 == joint->body1) && !errors++)
{
if (joint->body2 == joint->body1)
Con_Printf("Joint \"%s\" joints body \"%s\" to itself in \"%s\"\n", joint->name, name, fname);
else
Con_Printf("Joint \"%s\" joints invalid body \"%s\" in \"%s\"\n", joint->name, name, fname);
continue;
}
joint->orgmatrix[0] = 1;
joint->orgmatrix[4] = 1;
joint->orgmatrix[8] = 1;
joint->bonepivot = d->body[(joint->body2 >= 0)?joint->body2:joint->body1].bone; //default the pivot object to the bone of the second object.
joint->ERP = 0.4;
joint->ERP2 = 0.4;
joint->CFM = 0.1;
joint->CFM2 = 0.1;
if (joint->body1 >= 0 || joint->body2 >= 0)
d->numjoints++;
else if (!errors++)
Con_Printf("Joint property \"%s\" not recognised in \"%s\"\n", joint->name, fname);
}
else if (!stricmp(cmd, "setjoint"))
{
int j = rag_finddolljoint(d, Cmd_Argv(1));
if (j >= 0)
{
odejointinfo_t *joint = &d->joint[j];
char *prop = Cmd_Argv(2);
char *val = Cmd_Argv(3);
if (!stricmp(prop, "type"))
{
if (!stricmp(val, "fixed"))
joint->type = JOINTTYPE_FIXED;
else if (!stricmp(val, "point"))
joint->type = JOINTTYPE_POINT;
else if (!stricmp(val, "hinge"))
joint->type = JOINTTYPE_HINGE;
else if (!stricmp(val, "slider"))
joint->type = JOINTTYPE_SLIDER;
else if (!stricmp(val, "universal"))
joint->type = JOINTTYPE_UNIVERSAL;
else if (!stricmp(val, "hinge2"))
joint->type = JOINTTYPE_HINGE2;
}
else if (!stricmp(prop, "ERP"))
joint->ERP = atof(val);
else if (!stricmp(prop, "ERP2"))
joint->ERP2 = atof(val);
else if (!stricmp(prop, "CFM"))
joint->CFM = atof(val);
else if (!stricmp(prop, "CFM2"))
joint->CFM2 = atof(val);
else if (!stricmp(prop, "FMax"))
joint->FMax = atof(val);
else if (!stricmp(prop, "FMax2"))
joint->FMax2 = atof(val);
else if (!stricmp(prop, "HiStop"))
joint->HiStop = atof(val);
else if (!stricmp(prop, "HiStop2"))
joint->HiStop2 = atof(val);
else if (!stricmp(prop, "LoStop"))
joint->LoStop = atof(val);
else if (!stricmp(prop, "LoStop2"))
joint->LoStop2 = atof(val);
else if (!stricmp(prop, "origin") || !stricmp(prop, "pivot"))
{
//the origin is specified in base-frame model space
//we need to make it relative to the joint's bodies
float omat[12] = { 1, 0, 0, atoi(Cmd_Argv(3)),
0, 1, 0, atoi(Cmd_Argv(4)),
0, 0, 1, atoi(Cmd_Argv(5))};
char *bone = Cmd_Argv(6);
i = Mod_TagNumForName(d->model, Cmd_Argv(2))-1;
joint->bonepivot = i;
Matrix3x4_Multiply(omat, bones[i].inverse, joint->orgmatrix);
}
else if (!errors++)
Con_Printf("Joint property \"%s\" not recognised in \"%s\"\n", prop, fname);
}
else if (!errors++)
Con_Printf("Joint \"%s\" not yet defined in \"%s\"\n", Cmd_Argv(1), fname);
} }
} }
FS_FreeFile(fptr); FS_FreeFile(fptr);
return d; return d;
} }
void rag_freedoll(doll_t *doll)
{
free(doll->bone);
free(doll->body);
free(doll->joint);
free(doll);
}
void rag_flushdolls(void)
{
doll_t *d, **link;
for (link = &dolllist; *link; )
{
d = *link;
if (!d->uses)
{
*link = d->next;
rag_freedoll(d);
}
else
link = &(*link)->next;
}
}
void skel_integrate(progfuncs_t *prinst, skelobject_t *sko, skelobject_t *skelobjsrc, float ft, float mmat[12]) void skel_integrate(progfuncs_t *prinst, skelobject_t *sko, skelobject_t *skelobjsrc, float ft, float mmat[12])
{ {
@ -364,6 +539,7 @@ void skel_reset(progfuncs_t *prinst)
{ {
if (skelobjects[i].world = prinst->parms->user) if (skelobjects[i].world = prinst->parms->user)
{ {
rag_uninstanciate(&skelobjects[i]);
skelobjects[i].numbones = 0; skelobjects[i].numbones = 0;
skelobjects[i].inuse = false; skelobjects[i].inuse = false;
skelobjects[i].bonematrix = NULL; skelobjects[i].bonematrix = NULL;
@ -372,6 +548,7 @@ void skel_reset(progfuncs_t *prinst)
while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse) while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse)
numskelobjectsused--; numskelobjectsused--;
rag_flushdolls();
} }
/*deletes any skeletons marked for deletion*/ /*deletes any skeletons marked for deletion*/
@ -385,7 +562,10 @@ void skel_dodelete(progfuncs_t *prinst)
for (skelidx = 0; skelidx < numskelobjectsused; skelidx++) for (skelidx = 0; skelidx < numskelobjectsused; skelidx++)
{ {
if (skelobjects[skelidx].inuse == 2) if (skelobjects[skelidx].inuse == 2)
{
rag_uninstanciate(&skelobjects[skelidx]);
skelobjects[skelidx].inuse = 0; skelobjects[skelidx].inuse = 0;
}
} }
while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse) while (numskelobjectsused && !skelobjects[numskelobjectsused-1].inuse)
@ -418,7 +598,7 @@ skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount)
skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount); skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount);
} }
skelobjects[skelidx].world = prinst->parms->user; skelobjects[skelidx].world = prinst->parms->user;
if (numskelobjectsused == skelidx) if (numskelobjectsused <= skelidx)
numskelobjectsused = skelidx + 1; numskelobjectsused = skelidx + 1;
skelobjects[skelidx].model = NULL; skelobjects[skelidx].model = NULL;
skelobjects[skelidx].inuse = 1; skelobjects[skelidx].inuse = 1;
@ -459,59 +639,223 @@ void QCBUILTIN PF_skel_mmap(progfuncs_t *prinst, struct globalvars_s *pr_globals
if (!sko || sko->world != prinst->parms->user) if (!sko || sko->world != prinst->parms->user)
G_INT(OFS_RETURN) = 0; G_INT(OFS_RETURN) = 0;
else else
G_INT(OFS_RETURN) = PR_SetString(prinst, (void*)sko->bonematrix); G_INT(OFS_RETURN) = (char*)sko->bonematrix - prinst->stringtable;
} }
//may not poke the skeletal object bone data.
void rag_uninstanciate(skelobject_t *sko)
{
int i;
if (!sko->doll)
return;
for (i = 0; i < sko->numbodies; i++)
{
World_ODE_RagDestroyBody(sko->world, &sko->body[i].odebody);
}
free(sko->body);
sko->body = NULL;
sko->numbodies = 0;
for (i = 0; i < sko->numjoints; i++)
{
World_ODE_RagDestroyJoint(sko->world, &sko->joint[i]);
}
free(sko->joint);
sko->joint = NULL;
sko->numjoints = 0;
sko->doll->uses--;
sko->doll = NULL;
}
qboolean rag_instanciate(skelobject_t *sko, doll_t *doll, float *emat, wedict_t *ent)
{
int i;
vec3_t org, porg;
float *bmat;
float bodymat[12], worldmat[12];
vec3_t aaa2[3];
galiasbone_t *bones = Mod_GetBoneInfo(sko->model);
int bone;
odebody_t *body1, *body2;
odejointinfo_t *j;
sko->numbodies = doll->numbodies;
sko->body = malloc(sizeof(*sko->body) * sko->numbodies);
sko->doll = doll;
doll->uses++;
for (i = 0; i < sko->numbodies; i++)
{
memset(&sko->body[i], 0, sizeof(sko->body[i]));
bone = doll->body[i].bone;
bmat = sko->bonematrix + bone*12;
R_ConcatTransforms((void*)emat, (void*)bmat, (void*)bodymat);
if (!World_ODE_RagCreateBody(sko->world, &sko->body[i].odebody, bodymat, ent))
return false;
}
sko->numjoints = doll->numjoints;
sko->joint = malloc(sizeof(*sko->joint) * sko->numjoints);
memset(sko->joint, 0, sizeof(*sko->joint) * sko->numjoints);
for(i = 0; i < sko->numjoints; i++)
{
j = &doll->joint[i];
body1 = j->body1>=0?&sko->body[j->body1].odebody:NULL;
body2 = j->body2>=0?&sko->body[j->body2].odebody:NULL;
bone = j->bonepivot;
bmat = sko->bonematrix + bone*12;
R_ConcatTransforms(bmat, j->orgmatrix, bodymat);
R_ConcatTransforms((void*)emat, (void*)bodymat, (void*)worldmat);
aaa2[0][0] = worldmat[3];
aaa2[0][1] = worldmat[3+4];
aaa2[0][2] = worldmat[3+8];
// P_RunParticleEffectTypeString(aaa2[0], vec3_origin, 1, "te_spike");
aaa2[1][0] = 1;
aaa2[1][1] = 0;
aaa2[1][2] = 0;
aaa2[2][0] = 0;
aaa2[2][1] = 1;
aaa2[2][2] = 0;
// VectorCopy(j->offset, aaa2[0]); //fixme: transform these vectors into world space, and transform to match the current positions of the bones.
// VectorCopy(j->axis, aaa2[1]);
// VectorCopy(j->axis2, aaa2[2]);
World_ODE_RagCreateJoint(sko->world, &sko->joint[i], j, body1, body2, aaa2);
}
return true;
}
void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat)
{
doll_t *doll = sko->doll;
float *bmat = sko->bonematrix;
float *amat = asko?asko->bonematrix:NULL;
galiasbone_t *bones = Mod_GetBoneInfo(sko->model);
int i;
float invemat[12];
float bodymat[12];
Matrix3x4_Invert(emat, invemat);
for (i = 0; i < doll->numbones; i++)
{
if (doll->bone[i].bodyidx >= 0)
{
World_ODE_RagMatrixFromBody(sko->world, &sko->body[doll->bone[i].bodyidx].odebody, bodymat);
//that body matrix is in world space, so transform to model space for our result
R_ConcatTransforms((void*)invemat, (void*)bodymat, (void*)((float*)bmat+i*12));
}
else if (amat)
{
//this bone has no joint object, use the anim sko's relative pose info instead
if (bones[i].parent >= 0)
R_ConcatTransforms((void*)(bmat + bones[i].parent*12), (void*)((float*)amat+i*12), (void*)((float*)bmat+i*12));
else
memcpy((void*)((float*)bmat+i*12), (void*)((float*)amat+i*12), sizeof(float)*12);
}
}
}
//update a skeletal object to track its ragdoll/apply a ragdoll to a skeletal object.
void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_skel_ragedit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
//do we want to be able to generate a ragdoll object with this function too?
#ifdef RAGDOLL #ifdef RAGDOLL
int skelidx = G_FLOAT(OFS_PARM0); wedict_t *wed = (wedict_t*)G_EDICT(prinst, OFS_PARM0);
char *skelname = PR_GetStringOfs(prinst, OFS_PARM1); char *ragname = PR_GetStringOfs(prinst, OFS_PARM1);
int parentskel = G_FLOAT(OFS_PARM2); int parentskel = G_FLOAT(OFS_PARM2);
float *entorg = G_VECTOR(OFS_PARM3); int skelidx = wed->xv->skeletonindex;
float *forward = G_VECTOR(OFS_PARM4);
float *right = G_VECTOR(OFS_PARM5);
float *up = G_VECTOR(OFS_PARM6);
skelobject_t *sko, *psko; skelobject_t *sko, *psko;
doll_t *doll; doll_t *doll;
int i; int i;
float emat[12]; float emat[12];
extern cvar_t temp1;
bonemat_fromqcvectors(emat, forward, right, up, entorg); {
vec3_t d[3], a;
//fixme: respond to renderflags&USEAXIS? scale?
a[0] = wed->v->angles[0] * -1; /*mod_alias bug*/
a[1] = wed->v->angles[1];
a[2] = wed->v->angles[2];
AngleVectors(a, d[0], d[1], d[2]);
bonemat_fromqcvectors(emat, d[0], d[1], d[2], wed->v->origin);
skelidx = wed->xv->skeletonindex;
}
G_FLOAT(OFS_RETURN) = 0; G_FLOAT(OFS_RETURN) = 0;
sko = skel_get(prinst, skelidx, 0); //the parent skeletal object must be relative, if specified.
if (!sko) psko = skel_get(prinst, parentskel, 0);
if (psko && psko->type != SKOT_RELATIVE)
return; return;
if (*skelname) sko = skel_get(prinst, skelidx, 0);
if (!sko)
{ {
doll = rag_loaddoll(sko->model, skelname); Con_DPrintf("PF_skel_ragedit: invalid skeletal object\n");
return;
}
if (!sko->world->ode.ode)
{
Con_DPrintf("PF_skel_ragedit: ODE not enabled\n");
return;
}
if (*ragname)
{
if (sko->doll && !strcmp(sko->doll->name, ragname))
doll = sko->doll;
else
doll = rag_loaddoll(sko->model, ragname, sko->numbones);
if (!doll) if (!doll)
{
Con_DPrintf("PF_skel_ragedit: invalid doll\n");
return; return;
}
} }
else else
{ {
/*no doll name makes it revert to a normal skeleton*/ /*no doll name makes it revert to a normal skeleton*/
sko->doll = NULL; rag_uninstanciate(sko);
G_FLOAT(OFS_RETURN) = 1; G_FLOAT(OFS_RETURN) = 1;
return; return;
} }
if (sko->doll != doll) if (sko->type != SKOT_ABSOLUTE)
{ {
sko->doll = doll; float tmp[12];
free(sko->body); float *bmat = sko->bonematrix;
sko->numbodies = doll->numbodies; galiasbone_t *bones = Mod_GetBoneInfo(sko->model);
sko->body = malloc(sko->numbodies * sizeof(*sko->body)); for (i = 0; i < sko->numbones; i++)
memset(sko->body, 0, sko->numbodies * sizeof(*sko->body)); {
// for (i = 0; i < sko->numbodies; i++) //bones without parents are technically already absolute
// sko->body[i].jointo = doll->body[i].bone * 12; if (bones[i].parent >= 0)
{
//write to a tmp to avoid premature clobbering
R_ConcatTransforms((void*)(bmat + bones[i].parent*12), (void*)((float*)bmat+i*12), (void*)tmp);
memcpy((void*)(bmat+i*12), tmp, sizeof(tmp));
}
}
sko->type = SKOT_ABSOLUTE;
} }
psko = skel_get(prinst, parentskel, 0); if (sko->doll != doll || temp1.ival)
skel_integrate(prinst, sko, psko, host_frametime, emat); {
rag_uninstanciate(sko);
if (!rag_instanciate(sko, doll, emat, wed))
{
rag_uninstanciate(sko);
Con_DPrintf("PF_skel_ragedit: unable to instanciate objects\n");
G_FLOAT(OFS_RETURN) = 0;
return;
}
}
rag_derive(sko, psko, emat);
// skel_integrate(prinst, sko, psko, host_frametime, emat);
G_FLOAT(OFS_RETURN) = 1; G_FLOAT(OFS_RETURN) = 1;
#endif #endif
@ -527,6 +871,7 @@ void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_glob
model_t *model; model_t *model;
int midx; int midx;
int type; int type;
int i;
midx = G_FLOAT(OFS_PARM0); midx = G_FLOAT(OFS_PARM0);
type = (*prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKOT_RELATIVE; type = (*prinst->callargc > 1)?G_FLOAT(OFS_PARM1):SKOT_RELATIVE;
@ -554,6 +899,15 @@ void QCBUILTIN PF_skel_create (progfuncs_t *prinst, struct globalvars_s *pr_glob
skelobj->model = model; skelobj->model = model;
skelobj->type = type; skelobj->type = type;
/*
for (i = 0; i < numbones; i++)
{
galiasbone_t *bones = Mod_GetBoneInfo(skelobj->model);
Matrix3x4_Invert_Simple(bones[i].inverse, skelobj->bonematrix + i*12);
}
skelobj->type = SKOT_ABSOLUTE;
*/
G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1; G_FLOAT(OFS_RETURN) = (skelobj - skelobjects) + 1;
} }
@ -605,6 +959,16 @@ void QCBUILTIN PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_global
if (firstbone < 0) if (firstbone < 0)
firstbone = 0; firstbone = 0;
if (skelobj->type != SKOT_RELATIVE)
{
if (firstbone > 0 || lastbone < skelobj->numbones || retainfrac)
{
Con_Printf("skel_build on non-relative skeleton\n");
return;
}
skelobj->type = SKOT_RELATIVE; //entire model will get replaced, convert it.
}
if (retainfrac == 0) if (retainfrac == 0)
{ {
/*replace everything*/ /*replace everything*/

View file

@ -218,7 +218,8 @@ int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_lis
typedef struct quakeparms_s typedef struct quakeparms_s
{ {
char *basedir; char *basedir; //working directory
char *binarydir; //exe directory
int argc; int argc;
const char **argv; const char **argv;
void *membase; void *membase;
@ -240,6 +241,7 @@ extern qboolean noclip_anglehack;
extern quakeparms_t host_parms; extern quakeparms_t host_parms;
extern cvar_t fs_gamename; extern cvar_t fs_gamename;
extern cvar_t fs_gamedownload;
extern cvar_t com_protocolname; extern cvar_t com_protocolname;
extern cvar_t com_modname; extern cvar_t com_modname;
extern cvar_t sys_ticrate; extern cvar_t sys_ticrate;

View file

@ -4,6 +4,7 @@
#include "gl_draw.h" #include "gl_draw.h"
texid_t missing_texture; texid_t missing_texture;
texid_t missing_texture_gloss;
texid_t translate_texture; texid_t translate_texture;
shader_t *translate_shader; shader_t *translate_shader;
@ -17,7 +18,9 @@ static mpic_t *draw_backtile;
static shader_t *shader_draw_fill, *shader_draw_fill_trans; static shader_t *shader_draw_fill, *shader_draw_fill_trans;
mpic_t *draw_disc; mpic_t *draw_disc;
shader_t *shader_brighten; shader_t *shader_contrastup;
shader_t *shader_contrastdown;
shader_t *shader_brightness;
shader_t *shader_polyblend; shader_t *shader_polyblend;
shader_t *shader_menutint; shader_t *shader_menutint;
@ -31,7 +34,7 @@ unsigned int r2d_be_flags;
extern cvar_t scr_conalpha; extern cvar_t scr_conalpha;
extern cvar_t gl_conback; extern cvar_t gl_conback;
extern cvar_t gl_font; extern cvar_t gl_font;
extern cvar_t gl_contrast; extern cvar_t gl_contrast, gl_brightness;
extern cvar_t gl_screenangle; extern cvar_t gl_screenangle;
extern cvar_t vid_conautoscale; extern cvar_t vid_conautoscale;
extern cvar_t vid_conheight; extern cvar_t vid_conheight;
@ -124,6 +127,8 @@ Image loading code must be ready for use at this point.
*/ */
void R2D_Init(void) void R2D_Init(void)
{ {
unsigned int nogloss[4*4];
int i;
conback = NULL; conback = NULL;
Shader_Init(); Shader_Init();
@ -144,7 +149,10 @@ void R2D_Init(void)
#pragma warningmsg("Fixme: move conwidth handling into here") #pragma warningmsg("Fixme: move conwidth handling into here")
#endif #endif
for (i = 0; i < 4*4; i++)
nogloss[i] = LittleLong(0xff101010);
missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0); missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0);
missing_texture_gloss = R_LoadTexture("no_texture_gloss", 4, 4, TF_RGBA32, (unsigned char*)nogloss, IF_NOGAMMA);
translate_texture = r_nulltex; translate_texture = r_nulltex;
ch_int_texture = r_nulltex; ch_int_texture = r_nulltex;
@ -182,10 +190,11 @@ void R2D_Init(void)
"blendfunc blend\n" "blendfunc blend\n"
"}\n" "}\n"
"}\n"); "}\n");
shader_brighten = R_RegisterShader("constrastshader", shader_contrastup = R_RegisterShader("constrastupshader",
"{\n" "{\n"
"program defaultfill\n" "program defaultfill\n"
"{\n" "{\n"
"nodepthtest\n"
"map $whiteimage\n" "map $whiteimage\n"
"blendfunc gl_dst_color gl_one\n" "blendfunc gl_dst_color gl_one\n"
"rgbgen vertex\n" "rgbgen vertex\n"
@ -193,6 +202,30 @@ void R2D_Init(void)
"}\n" "}\n"
"}\n" "}\n"
); );
shader_contrastdown = R_RegisterShader("constrastdownshader",
"{\n"
"program defaultfill\n"
"{\n"
"nodepthtest\n"
"map $whiteimage\n"
"blendfunc gl_dst_color gl_zero\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"}\n"
);
shader_brightness = R_RegisterShader("brightnessshader",
"{\n"
"program defaultfill\n"
"{\n"
"nodepthtest\n"
"map $whiteimage\n"
"blendfunc gl_one gl_one\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"}\n"
);
shader_polyblend = R_RegisterShader("polyblendshader", shader_polyblend = R_RegisterShader("polyblendshader",
"{\n" "{\n"
"program defaultfill\n" "program defaultfill\n"
@ -520,7 +553,9 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque)
void R2D_EditorBackground (void) void R2D_EditorBackground (void)
{ {
R2D_ScalePic(0, 0, vid.width, vid.height, conback); R2D_ImageColours(0, 0, 0, 1);
R2D_FillBlock(0, 0, vid.width, vid.height);
// R2D_ScalePic(0, 0, vid.width, vid.height, conback);
} }
/* /*
@ -760,7 +795,7 @@ void R2D_BrightenScreen (void)
RSpeedMark(); RSpeedMark();
if (gl_contrast.value <= 1.0) if (gl_contrast.value != 1.0 && gl_brightness.value != 0)
return; return;
if (r_refdef.flags & Q2RDF_NOWORLDMODEL) if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
@ -772,11 +807,27 @@ void R2D_BrightenScreen (void)
while (f > 1) while (f > 1)
{ {
if (f >= 2) if (f >= 2)
{
R2D_ImageColours (1, 1, 1, 1); R2D_ImageColours (1, 1, 1, 1);
f *= 0.5;
}
else else
{
R2D_ImageColours (f - 1, f - 1, f - 1, 1); R2D_ImageColours (f - 1, f - 1, f - 1, 1);
R2D_ScalePic(0, 0, vid.width, vid.height, shader_brighten); f = 1;
f *= 0.5; }
R2D_ScalePic(0, 0, vid.width, vid.height, shader_contrastup);
}
if (f < 1)
{
R2D_ImageColours (f, f, f, 1);
R2D_ScalePic(0, 0, vid.width, vid.height, shader_contrastdown);
}
if (gl_brightness.value)
{
R2D_ImageColours (gl_brightness.value, gl_brightness.value, gl_brightness.value, 1);
R2D_ScalePic(0, 0, vid.width, vid.height, shader_brightness);
} }
R2D_ImageColours (1, 1, 1, 1); R2D_ImageColours (1, 1, 1, 1);

View file

@ -1592,9 +1592,9 @@ char *particle_set_high =
"float f;\n" "float f;\n"
"nst = scoord.xy / scoord.w;\n" "nst = scoord.xy / scoord.w;\n"
"nst = (1.0 + nst)/2.0;\n" "nst = (1.0 + nst)/2.0;\n"
"f = 1 - length(tcoord);\n" "f = 1.0 - length(tcoord);\n"
// f = 1 - tcoord*tcoord; // f = 1.0 - tcoord*tcoord;
"if (f < 0) discard;\n" "if (f < 0.0) discard;\n"
"f *= alph;\n" "f *= alph;\n"
"gl_FragColor = texture2D(s_t0, nst - tcoord*f);\n" "gl_FragColor = texture2D(s_t0, nst - tcoord*f);\n"
"}\n" "}\n"

View file

@ -1418,6 +1418,14 @@ static qbyte *R_MarkLeafSurfaces_Q1 (void)
} }
#endif #endif
/*
static qbyte *Surf_MaskVis(qbyte *src, qbyte *dest)
{
int i;
if (cl.worldmodel->leafs[i].ma
}
*/
qbyte *frustumvis;
/* /*
================ ================
R_RecursiveWorldNode R_RecursiveWorldNode
@ -1456,6 +1464,9 @@ start:
{ {
pleaf = (mleaf_t *)node; pleaf = (mleaf_t *)node;
c = pleaf - cl.worldmodel->leafs;
frustumvis[c>>3] |= 1<<(c&7);
mark = pleaf->firstmarksurface; mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces; c = pleaf->nummarksurfaces;
@ -2019,6 +2030,9 @@ void Surf_SetupFrame(void)
case Q1CONTENTS_SKY: case Q1CONTENTS_SKY:
r_viewcontents |= FTECONTENTS_SKY; r_viewcontents |= FTECONTENTS_SKY;
break; break;
case Q1CONTENTS_SOLID:
r_viewcontents |= FTECONTENTS_SOLID;
break;
} }
} }
} }
@ -2176,7 +2190,9 @@ R_DrawWorld
void Surf_DrawWorld (void) void Surf_DrawWorld (void)
{ {
qbyte *vis; //surfvis vs entvis - the key difference is that surfvis is surfaces while entvis is volume. though surfvis should be frustum culled also for lighting. entvis doesn't care.
qbyte *surfvis, *entvis;
qbyte frustumvis_[MAX_MAP_LEAFS/8];
RSpeedLocals(); RSpeedLocals();
if (r_refdef.flags & Q2RDF_NOWORLDMODEL) if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
@ -2221,14 +2237,14 @@ void Surf_DrawWorld (void)
#ifdef Q3BSPS #ifdef Q3BSPS
if (currententity->model->fromgame == fg_quake3) if (currententity->model->fromgame == fg_quake3)
{ {
vis = R_MarkLeaves_Q3 (); entvis = surfvis = R_MarkLeaves_Q3 ();
Surf_RecursiveQ3WorldNode (cl.worldmodel->nodes, (1<<FRUSTUMPLANES)-1); Surf_RecursiveQ3WorldNode (cl.worldmodel->nodes, (1<<FRUSTUMPLANES)-1);
//Surf_LeafWorldNode (); //Surf_LeafWorldNode ();
} }
else else
#endif #endif
{ {
vis = R_MarkLeaves_Q2 (); entvis = surfvis = R_MarkLeaves_Q2 ();
VectorCopy (r_refdef.vieworg, modelorg); VectorCopy (r_refdef.vieworg, modelorg);
Surf_RecursiveQ2WorldNode (cl.worldmodel->nodes); Surf_RecursiveQ2WorldNode (cl.worldmodel->nodes);
} }
@ -2238,14 +2254,14 @@ void Surf_DrawWorld (void)
#ifdef MAP_PROC #ifdef MAP_PROC
if (cl.worldmodel->fromgame == fg_doom3) if (cl.worldmodel->fromgame == fg_doom3)
{ {
vis = D3_CalcVis(cl.worldmodel, r_origin); entvis = surfvis = D3_CalcVis(cl.worldmodel, r_origin);
} }
else else
#endif #endif
#ifdef MAP_DOOM #ifdef MAP_DOOM
if (currentmodel->fromgame == fg_doom) if (currentmodel->fromgame == fg_doom)
{ {
vis = NULL; entvis = surfvis = NULL;
GLR_DoomWorld(); GLR_DoomWorld();
} }
else else
@ -2253,37 +2269,42 @@ void Surf_DrawWorld (void)
#ifdef TERRAIN #ifdef TERRAIN
if (currentmodel->type == mod_heightmap) if (currentmodel->type == mod_heightmap)
{ {
vis = NULL; entvis = surfvis = NULL;
} }
else else
#endif #endif
{ {
//extern cvar_t temp1; //extern cvar_t temp1;
// if (0)//temp1.value) // if (0)//temp1.value)
// vis = R_MarkLeafSurfaces_Q1(); // entvis = surfvis = R_MarkLeafSurfaces_Q1();
// else // else
{ {
vis = R_MarkLeaves_Q1 (); entvis = R_MarkLeaves_Q1 ();
if (!(r_novis.ival & 2)) if (!(r_novis.ival & 2))
VectorCopy (r_origin, modelorg); VectorCopy (r_origin, modelorg);
frustumvis = frustumvis_;
memset(frustumvis, 0, (cl.worldmodel->numleafs + 7)>>3);
if (r_refdef.useperspective) if (r_refdef.useperspective)
Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0x1f); Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0x1f);
else else
Surf_OrthoRecursiveWorldNode (cl.worldmodel->nodes, 0x1f); Surf_OrthoRecursiveWorldNode (cl.worldmodel->nodes, 0x1f);
surfvis = frustumvis;
} }
} }
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{ {
CL_LinkStaticEntities(vis); // CL_LinkStaticEntities(entvis);
TRACE(("dbg: calling R_DrawParticles\n")); TRACE(("dbg: calling R_DrawParticles\n"));
P_DrawParticles (); if (!r_refdef.recurse)
P_DrawParticles ();
} }
RSpeedEnd(RSPEED_WORLDNODE); RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling BE_DrawWorld\n")); TRACE(("dbg: calling BE_DrawWorld\n"));
BE_DrawWorld(true, vis); BE_DrawWorld(true, surfvis);
/*FIXME: move this away*/ /*FIXME: move this away*/
if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife) if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife)
@ -2486,6 +2507,163 @@ int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe)
return first; return first;
} }
void Surf_BuildModelLightmaps (model_t *m)
{
int i, t;
int shift;
msurface_t *surf;
batch_t *batch;
int sortid;
int ptype;
int newfirst;
if (!lightmap_bytes)
return;
#ifdef TERRAIN
if (m->terrain)
Terr_PurgeTerrainModel(m, true, false);
#endif
if (m->type != mod_brush)
return;
if (!m->lightmaps.count)
return;
if (m->needload)
return;
currentmodel = m;
shift = Surf_LightmapShift(currentmodel);
if (*m->name == '*' && m->fromgame == fg_quake3) //FIXME: should be all bsp formats
newfirst = cl.model_precache[1]->lightmaps.first;
else
{
if (!m->lightdata && m->lightmaps.count && m->fromgame == fg_quake3)
{
char pattern[MAX_QPATH];
COM_StripAllExtensions(m->name, pattern, sizeof(pattern));
Q_strncatz(pattern, "/lm_%04u.tga", sizeof(pattern));
newfirst = Surf_NewExternalLightmaps(m->lightmaps.count, pattern, m->lightmaps.deluxemapping);
}
else
newfirst = Surf_NewLightmaps(m->lightmaps.count, m->lightmaps.width, m->lightmaps.height, m->lightmaps.deluxemapping);
}
//fixup batch lightmaps
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
for (i = 0; i < MAXLIGHTMAPS; i++)
{
if (batch->lightmap[i] < 0)
continue;
batch->lightmap[i] = batch->lightmap[i] - m->lightmaps.first + newfirst;
}
}
/*particle emision based upon texture. this is lazy code*/
if (m == cl.worldmodel)
{
for (t = m->numtextures-1; t >= 0; t--)
{
ptype = P_FindParticleType(va("tex_%s", m->textures[t]->name));
if (ptype != P_INVALID)
{
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
if (surf->texinfo->texture == m->textures[t])
P_EmitSkyEffectTris(m, surf, ptype);
}
}
}
}
if (m->fromgame == fg_quake3)
{
int j;
unsigned char *src;
unsigned char *dst;
for (i = 0; i < m->lightmaps.count; i++)
{
if (lightmap[newfirst+i]->external)
continue;
dst = lightmap[newfirst+i]->lightmaps;
src = m->lightdata + i*m->lightmaps.width*m->lightmaps.height*3;
if (lightmap_bytes == 4 && m->lightdata)
{
if (lightmap_bgra)
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = 255;
}
}
else
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = 255;
}
}
}
}
}
else
{
int j;
lightmapinfo_t *lm, *dlm;
qbyte *deluxemap;
//fixup surface lightmaps, and paint
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
for (j = 0; j < 4; j++)
{
if (surf->lightmaptexturenums[j] < m->lightmaps.first)
{
surf->lightmaptexturenums[j] = -1;
continue;
}
surf->lightmaptexturenums[j] = surf->lightmaptexturenums[0] - m->lightmaps.first + newfirst;
lm = lightmap[surf->lightmaptexturenums[j]];
if (lm->hasdeluxe)
{
dlm = lightmap[surf->lightmaptexturenums[j]+1];
deluxemap = dlm->lightmaps + (surf->light_t[j] * dlm->width + surf->light_s[j]) * lightmap_bytes;
}
else
deluxemap = NULL;
Surf_BuildLightMap (surf,
lm->lightmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * lightmap_bytes,
deluxemap,
lm->stainmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3,
shift, r_ambient.value*255);
}
}
}
m->lightmaps.first = newfirst;
}
void Surf_ClearLightmaps(void)
{
lightmap_bytes = 0;
}
/* /*
================== ==================
GL_BuildLightmaps GL_BuildLightmaps
@ -2497,14 +2675,8 @@ Groups surfaces into their respective batches (based on the lightmap number).
*/ */
void Surf_BuildLightmaps (void) void Surf_BuildLightmaps (void)
{ {
int i, j, t; int i, j;
model_t *m; model_t *m;
int shift;
msurface_t *surf;
batch_t *batch;
int sortid;
int ptype;
int newfirst;
r_framecount = 1; // no dlightcache r_framecount = 1; // no dlightcache
@ -2522,155 +2694,24 @@ void Surf_BuildLightmaps (void)
r_oldviewleaf2 = NULL; r_oldviewleaf2 = NULL;
r_oldviewcluster = -1; r_oldviewcluster = -1;
r_oldviewcluster2 = -1; r_oldviewcluster2 = -1;
numlightmaps = 0;
if (cl.worldmodel->fromgame == fg_doom) if (cl.worldmodel->fromgame == fg_doom)
return; //no lightmaps. return; //no lightmaps.
numlightmaps = 0;
for (j=1 ; j<MAX_MODELS ; j++) for (j=1 ; j<MAX_MODELS ; j++)
{ {
m = cl.model_precache[j]; m = cl.model_precache[j];
if (!m) if (!m)
break; break;
Surf_BuildModelLightmaps(m);
#ifdef TERRAIN }
if (m->terrain) for (j=1 ; j<MAX_CSQCMODELS ; j++)
Terr_PurgeTerrainModel(m, true, false); {
#endif m = cl.model_csqcprecache[j];
if (!m)
if (m->type != mod_brush) break;
continue; Surf_BuildModelLightmaps(m);
if (!m->lightmaps.count)
continue;
if (m->needload)
continue;
currentmodel = m;
shift = Surf_LightmapShift(currentmodel);
if (*m->name == '*' && m->fromgame == fg_quake3) //FIXME: should be all bsp formats
newfirst = cl.model_precache[1]->lightmaps.first;
else
{
if (!m->lightdata && m->lightmaps.count)
{
char pattern[MAX_QPATH];
COM_StripAllExtensions(m->name, pattern, sizeof(pattern));
Q_strncatz(pattern, "/lm_%04u.tga", sizeof(pattern));
newfirst = Surf_NewExternalLightmaps(m->lightmaps.count, pattern, m->lightmaps.deluxemapping);
}
else
newfirst = Surf_NewLightmaps(m->lightmaps.count, m->lightmaps.width, m->lightmaps.height, m->lightmaps.deluxemapping);
}
//fixup batch lightmaps
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
for (i = 0; i < MAXLIGHTMAPS; i++)
{
if (batch->lightmap[i] < 0)
continue;
batch->lightmap[i] = batch->lightmap[i] - m->lightmaps.first + newfirst;
}
}
/*particle emision based upon texture. this is lazy code*/
if (m == cl.worldmodel)
{
for (t = m->numtextures-1; t >= 0; t--)
{
ptype = P_FindParticleType(va("tex_%s", m->textures[t]->name));
if (ptype != P_INVALID)
{
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
if (surf->texinfo->texture == m->textures[t])
P_EmitSkyEffectTris(m, surf, ptype);
}
}
}
}
if (m->fromgame == fg_quake3)
{
int j;
unsigned char *src;
unsigned char *dst;
for (i = 0; i < m->lightmaps.count; i++)
{
if (lightmap[newfirst+i]->external)
continue;
dst = lightmap[newfirst+i]->lightmaps;
src = m->lightdata + i*m->lightmaps.width*m->lightmaps.height*3;
if (lightmap_bytes == 4 && m->lightdata)
{
if (lightmap_bgra)
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
dst[3] = 255;
}
}
else
{
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
{
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
dst[3] = 255;
}
}
}
}
}
else
{
int j;
lightmapinfo_t *lm, *dlm;
qbyte *deluxemap;
//fixup surface lightmaps, and paint
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
for (j = 0; j < 4; j++)
{
if (surf->lightmaptexturenums[j] < m->lightmaps.first)
{
surf->lightmaptexturenums[j] = -1;
continue;
}
surf->lightmaptexturenums[j] = surf->lightmaptexturenums[0] - m->lightmaps.first + newfirst;
lm = lightmap[surf->lightmaptexturenums[j]];
if (lm->hasdeluxe)
{
dlm = lightmap[surf->lightmaptexturenums[j]+1];
deluxemap = dlm->lightmaps + (surf->light_t[j] * dlm->width + surf->light_s[j]) * lightmap_bytes;
}
else
deluxemap = NULL;
Surf_BuildLightMap (surf,
lm->lightmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * lightmap_bytes,
deluxemap,
lm->stainmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3,
shift, r_ambient.value*255);
}
}
}
m->lightmaps.first = newfirst;
} }
BE_UploadAllLightmaps(); BE_UploadAllLightmaps();
} }

View file

@ -200,7 +200,9 @@ void Surf_LessenStains(void);
void Surf_WipeStains(void); void Surf_WipeStains(void);
void Surf_DeInit(void); void Surf_DeInit(void);
void Surf_Clear(struct model_s *mod); void Surf_Clear(struct model_s *mod);
void Surf_BuildLightmaps(void); void Surf_BuildLightmaps(void); //enables Surf_BuildModelLightmaps, calls it for each bsp.
void Surf_ClearLightmaps(void); //stops Surf_BuildModelLightmaps from working.
void Surf_BuildModelLightmaps (struct model_s *m); //rebuild lightmaps for a single bsp. beware of submodels.
void Surf_RenderDynamicLightmaps (struct msurface_s *fa); void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient); void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
int Surf_LightmapShift (struct model_s *model); int Surf_LightmapShift (struct model_s *model);
@ -360,7 +362,8 @@ qboolean Media_ShowFilm(void);
void Media_CaptureDemoEnd(void); void Media_CaptureDemoEnd(void);
void Media_RecordFrame (void); void Media_RecordFrame (void);
qboolean Media_PausedDemo (void); qboolean Media_PausedDemo (void);
double Media_TweekCaptureFrameTime(double time); int Media_Capturing (void);
double Media_TweekCaptureFrameTime(double oldtime, double time);
void MYgluPerspective(double fovx, double fovy, double zNear, double zFar); void MYgluPerspective(double fovx, double fovy, double zNear, double zFar);
@ -424,6 +427,7 @@ extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_shadows;
extern cvar_t r_mirroralpha; extern cvar_t r_mirroralpha;
extern cvar_t r_wateralpha; extern cvar_t r_wateralpha;
extern cvar_t r_waterstyle; extern cvar_t r_waterstyle;
extern cvar_t r_lavastyle;
extern cvar_t r_dynamic; extern cvar_t r_dynamic;
extern cvar_t r_novis; extern cvar_t r_novis;
extern cvar_t r_netgraph; extern cvar_t r_netgraph;

View file

@ -41,7 +41,7 @@ void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue);
void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue); void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue);
#endif #endif
cvar_t _vid_wait_override = CVARAF ("vid_wait", "", cvar_t _vid_wait_override = CVARAF ("vid_wait", "1",
"_vid_wait_override", CVAR_ARCHIVE); "_vid_wait_override", CVAR_ARCHIVE);
cvar_t _windowed_mouse = CVARF ("_windowed_mouse","1", cvar_t _windowed_mouse = CVARF ("_windowed_mouse","1",
@ -169,8 +169,8 @@ cvar_t scr_viewsize = CVARFC("viewsize", "100",
cvar_t vid_conautoscale = CVARF ("vid_conautoscale", "2", cvar_t vid_conautoscale = CVARF ("vid_conautoscale", "2",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK); CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
#else #else
cvar_t vid_conautoscale = CVARF ("vid_conautoscale", "0", cvar_t vid_conautoscale = CVARFD ("vid_conautoscale", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK); CVAR_ARCHIVE | CVAR_RENDERERCALLBACK, "Changes the 2d scale, including hud, console, and fonts. To specify an explicit font size, divide the desired 'point' size by 8 to get the scale. High values will be clamped to maintain at least a 320*200 virtual size.");
#endif #endif
cvar_t vid_conheight = CVARF ("vid_conheight", "0", cvar_t vid_conheight = CVARF ("vid_conheight", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
@ -256,13 +256,14 @@ cvar_t gl_compress = CVARF ("gl_compress", "0",
cvar_t gl_conback = CVARFC ("gl_conback", "", cvar_t gl_conback = CVARFC ("gl_conback", "",
CVAR_RENDERERCALLBACK, R2D_Conback_Callback); CVAR_RENDERERCALLBACK, R2D_Conback_Callback);
cvar_t gl_contrast = CVAR ("gl_contrast", "1"); cvar_t gl_contrast = CVAR ("gl_contrast", "1");
cvar_t gl_brightness = CVAR ("gl_brightness", "0");
cvar_t gl_detail = CVARF ("gl_detail", "0", cvar_t gl_detail = CVARF ("gl_detail", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t gl_detailscale = CVAR ("gl_detailscale", "5"); cvar_t gl_detailscale = CVAR ("gl_detailscale", "5");
cvar_t gl_font = CVARFD ("gl_font", "", cvar_t gl_font = CVARFD ("gl_font", "",
CVAR_RENDERERCALLBACK, ("Specifies the font file to use. a value such as FONT:ALTFONT specifies an alternative font to be used when ^^a is used." CVAR_RENDERERCALLBACK, ("Specifies the font file to use. a value such as FONT:ALTFONT specifies an alternative font to be used when ^^a is used.\n"
"When using TTF fonts, you will likely need to scale text to at least 150% - vid_conautoscale 1.5 will do this." "When using TTF fonts, you will likely need to scale text to at least 150% - vid_conautoscale 1.5 will do this.\n"
"TTF fonts may be loaded from your windows directory. \'gl_font cour\' loads eg: c:\\windows\\fonts\\cour.ttf." "TTF fonts may be loaded from your windows directory. \'gl_font cour:couri\' loads eg: c:\\windows\\fonts\\cour.ttf, and uses the italic version of courier for alternative text."
)); ));
cvar_t gl_lateswap = CVAR ("gl_lateswap", "0"); cvar_t gl_lateswap = CVAR ("gl_lateswap", "0");
cvar_t gl_lerpimages = CVARF ("gl_lerpimages", "1", CVAR_ARCHIVE); cvar_t gl_lerpimages = CVARF ("gl_lerpimages", "1", CVAR_ARCHIVE);
@ -337,6 +338,7 @@ cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10"
cvar_t r_glsl_offsetmapping = CVARF ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM); cvar_t r_glsl_offsetmapping = CVARF ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04"); cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
cvar_t r_glsl_offsetmapping_reliefmapping = CVARF("r_glsl_offsetmapping_reliefmapping", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM); cvar_t r_glsl_offsetmapping_reliefmapping = CVARF("r_glsl_offsetmapping_reliefmapping", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
cvar_t r_glsl_turbscale = CVARF ("r_glsl_turbscale", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE); 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_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
@ -346,15 +348,16 @@ cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_ligh
cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0); cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0);
cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8"); cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8");
cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE); cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE);
cvar_t r_waterstyle = CVARF ("r_waterstyle", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM); cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, slime, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections");
cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava.");
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0"); cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0");
cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "0"); cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "0");
cvar_t vid_hardwaregamma = SCVARF ("vid_hardwaregamma", "1", cvar_t vid_hardwaregamma = SCVARF ("vid_hardwaregamma", "1",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_desktopgamma = SCVARF ("vid_desktopgamma", "0", cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Apply gamma ramps upon the desktop rather than the window.");
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces) is typically more realistic, while 1 (matching FitzQuake and others) is more common."); cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
@ -420,8 +423,9 @@ void GLRenderer_Init(void)
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_turbscale, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
#ifdef R_XFLIP #ifdef R_XFLIP
Cvar_Register (&r_xflip, GLRENDEREROPTIONS); Cvar_Register (&r_xflip, GLRENDEREROPTIONS);
#endif #endif
@ -601,6 +605,7 @@ void Renderer_Init(void)
Cvar_Register (&r_sun_dir, GRAPHICALNICETIES); Cvar_Register (&r_sun_dir, GRAPHICALNICETIES);
Cvar_Register (&r_sun_colour, GRAPHICALNICETIES); Cvar_Register (&r_sun_colour, GRAPHICALNICETIES);
Cvar_Register (&r_waterstyle, GRAPHICALNICETIES); Cvar_Register (&r_waterstyle, GRAPHICALNICETIES);
Cvar_Register (&r_lavastyle, GRAPHICALNICETIES);
Cvar_Register (&r_wireframe, GRAPHICALNICETIES); Cvar_Register (&r_wireframe, GRAPHICALNICETIES);
Cvar_Register (&r_stereo_separation, GRAPHICALNICETIES); Cvar_Register (&r_stereo_separation, GRAPHICALNICETIES);
Cvar_Register (&r_stereo_method, GRAPHICALNICETIES); Cvar_Register (&r_stereo_method, GRAPHICALNICETIES);
@ -635,6 +640,8 @@ void Renderer_Init(void)
Cvar_Register(&r_fullbrightSkins, GRAPHICALNICETIES); Cvar_Register(&r_fullbrightSkins, GRAPHICALNICETIES);
Cvar_Register (&mod_md3flags, GRAPHICALNICETIES); Cvar_Register (&mod_md3flags, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
Cvar_Register (&gl_brightness, GLRENDEREROPTIONS);
//renderer //renderer
@ -683,7 +690,6 @@ void Renderer_Init(void)
P_InitParticleSystem(); P_InitParticleSystem();
R_InitTextures(); R_InitTextures();
RQ_Init();
} }
qboolean Renderer_Started(void) qboolean Renderer_Started(void)
@ -976,6 +982,7 @@ void R_ShutdownRenderer(void)
if (host_basepal) if (host_basepal)
BZ_Free(host_basepal); BZ_Free(host_basepal);
host_basepal = NULL; host_basepal = NULL;
Surf_ClearLightmaps();
RQ_Shutdown(); RQ_Shutdown();
@ -1110,6 +1117,7 @@ TRACE(("dbg: R_ApplyRenderer: wad loaded\n"));
Draw_Init(); Draw_Init();
TRACE(("dbg: R_ApplyRenderer: draw inited\n")); TRACE(("dbg: R_ApplyRenderer: draw inited\n"));
R_Init(); R_Init();
RQ_Init();
R_InitParticleTexture (); R_InitParticleTexture ();
TRACE(("dbg: R_ApplyRenderer: renderer inited\n")); TRACE(("dbg: R_ApplyRenderer: renderer inited\n"));
SCR_Init(); SCR_Init();
@ -1445,7 +1453,10 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
if (!newr.renderer) if (!newr.renderer)
{ {
int i; int i;
Con_Printf("vid_renderer unset or unsupported. Using default.\n"); if (*vid_renderer.string)
Con_Printf("vid_renderer unsupported. Using default.\n");
else
Con_DPrintf("vid_renderer unset. Using default.\n");
//gotta do this after main hunk is saved off. //gotta do this after main hunk is saved off.
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)

View file

@ -125,6 +125,39 @@ void RQ_RenderBatchClear(void)
rqmingrad = NUMGRADUATIONS-1; rqmingrad = NUMGRADUATIONS-1;
} }
//render without clearing
void RQ_RenderBatch(void)
{
#define SLOTS 512
void *slot[SLOTS];
void *typeptr = NULL;
int maxslot = SLOTS;
void (*lr) (int count, void **objects, void *objtype) = NULL;
int i;
renderque_t *rq;
for (i = rqmaxgrad; i>=rqmingrad; i--)
// for (i = rqmingrad; i<=rqmaxgrad; i++)
{
for (rq = distrque[i]; rq; rq=rq->next)
{
if (!maxslot || rq->render != lr || typeptr != rq->data2)
{
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
maxslot = SLOTS;
}
slot[--maxslot] = rq->data1;
typeptr = rq->data2;
lr = rq->render;
}
}
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
}
void RQ_Shutdown(void) void RQ_Shutdown(void)
{ {
Z_Free(initialque); Z_Free(initialque);

View file

@ -5,6 +5,7 @@ void RQ_BeginFrame(void);
void RQ_AddDistReorder(void (*render) (int count, void **objects, void *objtype), void *object, void *objtype, float *pos); void RQ_AddDistReorder(void (*render) (int count, void **objects, void *objtype), void *object, void *objtype, float *pos);
void RQ_RenderBatchClear(void); void RQ_RenderBatchClear(void);
void RQ_RenderBatch(void);
typedef struct renderque_s typedef struct renderque_s
{ {

View file

@ -2554,6 +2554,19 @@ void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color, qboo
} }
} }
#define COL_TEAM_LOWAVGHIGH COLUMN("low/avg/high", 12*8, {sprintf (num, "%3i/%3i/%3i", plow, pavg, phigh); Draw_FunString ( x, y, num); })
#define COL_TEAM_TEAM COLUMN("team", 4*8, {Draw_FunStringWidth ( x, y, tm->team, 4*8); \
if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16))\
{\
Draw_FunString ( x - 1*8, y, "^Ue010");\
Draw_FunString ( x + 4*8, y, "^Ue011");\
}\
})
#define COL_TEAM_TOTAL COLUMN("total", 5*8, {Draw_FunString ( x, y, va("%5i", tm->frags)); })
#define COL_TEAM_PLAYERS COLUMN("players", 7*8, {Draw_FunString ( x, y, va("%5i", tm->players)); })
#define ALL_TEAM_COLUMNS COL_TEAM_LOWAVGHIGH COL_TEAM_TEAM COL_TEAM_TOTAL COL_TEAM_PLAYERS
/* /*
================== ==================
Sbar_TeamOverlay Sbar_TeamOverlay
@ -2565,10 +2578,9 @@ added by Zoid
void Sbar_TeamOverlay (void) void Sbar_TeamOverlay (void)
{ {
mpic_t *pic; mpic_t *pic;
int i, k, l; int i, k;
int x, y; int x, y, l;
char num[12]; char num[12];
char team[5];
team_t *tm; team_t *tm;
int plow, phigh, pavg; int plow, phigh, pavg;
@ -2592,19 +2604,31 @@ void Sbar_TeamOverlay (void)
y += 24; y += 24;
} }
x = (vid.width - 320)/2 + 36; x = l = (vid.width - 320)/2 + 36;
Draw_FunString(x, y, "low/avg/high team total players");
#define COLUMN(title, cwidth, code) Draw_FunString(x, y, title), x+=cwidth + 8;
ALL_TEAM_COLUMNS
// if (rank_width+(cwidth)+8 <= vid.width) {showcolumns |= (1<<COLUMN##title); rank_width += cwidth+8;}
// Draw_FunString(x, y, "low/avg/high");
// Draw_FunString(x+13*8, y, "team");
// Draw_FunString(x+18*8, y, "total");
// Draw_FunString(x+24*8, y, "players");
y += 8; y += 8;
// Draw_String(x, y, "------------ ---- ----- -------"); // Draw_String(x, y, "------------ ---- ----- -------");
Draw_FunString(x, y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1e\x1e\x1f"); x = l;
#undef COLUMN
#define COLUMN(title, cwidth, code) {char buf[64*6]; int t = (cwidth)/8; int c=0; while (t-->0) {buf[c++] = '^'; buf[c++] = 'U'; buf[c++] = 'e'; buf[c++] = '0'; buf[c++] = '1'; buf[c++] = (c==5?'d':(!t?'f':'e'));} buf[c] = 0; Draw_FunString(x, y, buf); x += cwidth + 8;}
ALL_TEAM_COLUMNS
// Draw_FunString(x, y, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f ^Ue01d^Ue01e^Ue01e^Ue01f ^Ue01d^Ue01e^Ue01e^Ue01e^Ue01f ^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f");
y += 8; y += 8;
#undef COLUMN
// sort the teams // sort the teams
Sbar_SortTeams(); Sbar_SortTeams();
// draw the text // draw the text
l = scoreboardlines;
for (i=0 ; i < scoreboardteams && y <= vid.height-10 ; i++) for (i=0 ; i < scoreboardteams && y <= vid.height-10 ; i++)
{ {
k = teamsort[i]; k = teamsort[i];
@ -2624,6 +2648,13 @@ void Sbar_TeamOverlay (void)
if (pavg < 0 || pavg > 999) if (pavg < 0 || pavg > 999)
pavg = 999; pavg = 999;
x = l;
#if 1
#define COLUMN(title, cwidth, code) code; x+=cwidth + 8;
ALL_TEAM_COLUMNS
#undef COLUMN
#else
sprintf (num, "%3i/%3i/%3i", plow, pavg, phigh); sprintf (num, "%3i/%3i/%3i", plow, pavg, phigh);
Draw_FunString ( x, y, num); Draw_FunString ( x, y, num);
@ -2641,10 +2672,10 @@ void Sbar_TeamOverlay (void)
if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16))
{ {
Draw_FunString ( x + 104 - 8, y, "^Ue016"); Draw_FunString ( x + 104 - 8, y, "^Ue010");
Draw_FunString ( x + 104 + 32, y, "^Ue017"); Draw_FunString ( x + 104 + 32, y, "^Ue011");
} }
#endif
y += 8; y += 8;
} }
y += 8; y += 8;

View file

@ -81,7 +81,7 @@ void SCR_ShowPic_Clear(void);
//a header is better than none... //a header is better than none...
void Draw_TextBox (int x, int y, int width, int lines); void Draw_TextBox (int x, int y, int width, int lines);
qboolean SCR_ScreenShot (char *filename); qboolean SCR_ScreenShot (char *filename, void *rgb_buffer, int width, int height);
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud); void SCR_DrawTwoDimensional(int uimenu, qboolean nohud);

View file

@ -122,41 +122,41 @@ static unsigned int ALSA_RW_GetDMAPos (soundcardinfo_t *sc)
static void ALSA_RW_Submit (soundcardinfo_t *sc, int start, int end) static void ALSA_RW_Submit (soundcardinfo_t *sc, int start, int end)
{ {
int state; int state;
unsigned int frames, offset, ringsize; unsigned int frames, offset, ringsize;
unsigned chunk; unsigned chunk;
int result; int result;
int stride = sc->sn.numchannels * (sc->sn.samplebits/8); int stride = sc->sn.numchannels * (sc->sn.samplebits/8);
/*we can't change the data that was already written*/ /*we can't change the data that was already written*/
frames = end - sc->snd_sent; frames = end - sc->snd_sent;
if (!frames) if (!frames)
return; return;
state = psnd_pcm_state (sc->handle); state = psnd_pcm_state (sc->handle);
ringsize = sc->sn.samples / sc->sn.numchannels; ringsize = sc->sn.samples / sc->sn.numchannels;
chunk = frames; chunk = frames;
offset = sc->snd_sent % ringsize; offset = sc->snd_sent % ringsize;
if (offset + chunk >= ringsize) if (offset + chunk >= ringsize)
chunk = ringsize - offset; chunk = ringsize - offset;
result = psnd_pcm_writei(sc->handle, sc->sn.buffer + offset*stride, chunk); result = psnd_pcm_writei(sc->handle, sc->sn.buffer + offset*stride, chunk);
if (result < chunk) if (result < chunk)
{ {
if (result >= 0) if (result >= 0)
sc->snd_sent += result; sc->snd_sent += result;
return; return;
} }
sc->snd_sent += chunk; sc->snd_sent += chunk;
chunk = frames - chunk; chunk = frames - chunk;
if (chunk) if (chunk)
{ {
result = psnd_pcm_writei(sc->handle, sc->sn.buffer, chunk); result = psnd_pcm_writei(sc->handle, sc->sn.buffer, chunk);
if (result > 0) if (result > 0)
sc->snd_sent += result; sc->snd_sent += result;
} }
if (state == SND_PCM_STATE_PREPARED) if (state == SND_PCM_STATE_PREPARED)
psnd_pcm_start (sc->handle); psnd_pcm_start (sc->handle);

View file

@ -50,7 +50,7 @@ vec3_t listener_up = {0, 0, 1};
vec3_t listener_velocity; vec3_t listener_velocity;
vec_t sound_nominal_clip_dist=1000.0; vec_t sound_nominal_clip_dist=1000.0;
#define MAX_SFX 512 #define MAX_SFX 2048
sfx_t *known_sfx; // hunk allocated [MAX_SFX] sfx_t *known_sfx; // hunk allocated [MAX_SFX]
int num_sfx; int num_sfx;
@ -901,7 +901,7 @@ void S_Startup (void)
break; break;
} }
sound_started = !!sndcardinfo; sound_started = true;//!!sndcardinfo;
S_ClearRaw(); S_ClearRaw();

View file

@ -6,10 +6,10 @@ java code has a function or two which just periodically calls us to ask us to du
#include <jni.h> #include <jni.h>
#include <pthread.h> #include <pthread.h>
//static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static soundcardinfo_t *sys_sc = NULL; static soundcardinfo_t *sys_sc = NULL;
extern int sys_soundflags; extern int sys_soundflags;
//called by the java code when it wants to know what sort of AudioTrack format to use.
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_audioinfo(JNIEnv *env, jclass this, jint arg) JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_audioinfo(JNIEnv *env, jclass this, jint arg)
{ {
soundcardinfo_t *sc = sys_sc; soundcardinfo_t *sc = sys_sc;
@ -33,55 +33,50 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_paintaudio(JNIEnv *env, jcl
int offset = 0; int offset = 0;
soundcardinfo_t *sc = sys_sc; soundcardinfo_t *sc = sys_sc;
int framesz; int framesz;
// if (!pthread_mutex_lock(&mutex))
if (sc)
{ {
if (sc) int buffersize = sc->sn.samples*sc->sn.samplebits/8;
int curtime = GetSoundtime(sc);
framesz = sc->sn.numchannels * sc->sn.samplebits/8;
S_PaintChannels (sc, curtime + (len / framesz));
if (len > buffersize)
{ {
int buffersize = sc->sn.samples*sc->sn.samplebits/8; len = buffersize; //whoa nellie!
int curtime = GetSoundtime(sc);
framesz = sc->sn.numchannels * sc->sn.samplebits/8;
S_PaintChannels (sc, curtime + (len / framesz));
if (len > buffersize)
{
len = buffersize; //whoa nellie!
}
if (len + sc->snd_sent%buffersize > buffersize)
{ //buffer will wrap, fill in the rest
(*env)->SetByteArrayRegion(env, stream, offset, buffersize - (sc->snd_sent%buffersize), (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
offset += buffersize - (sc->snd_sent%buffersize);
sc->snd_sent += buffersize - (sc->snd_sent%buffersize);
len -= buffersize - (sc->snd_sent%buffersize);
if (len < 0) /*this must be impossible, surely?*/
len = 0;
}
//and finish from the start
(*env)->SetByteArrayRegion(env, stream, offset, len, (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
offset += len;
sc->snd_sent += len;
} }
else
offset = len; /*so the playback thread ends up blocked properly*/ if (len + sc->snd_sent%buffersize > buffersize)
// pthread_mutex_unlock(&mutex); { //buffer will wrap, fill in the rest
(*env)->SetByteArrayRegion(env, stream, offset, buffersize - (sc->snd_sent%buffersize), (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
offset += buffersize - (sc->snd_sent%buffersize);
sc->snd_sent += buffersize - (sc->snd_sent%buffersize);
len -= buffersize - (sc->snd_sent%buffersize);
if (len < 0) /*this must be impossible, surely?*/
len = 0;
}
//and finish from the start
(*env)->SetByteArrayRegion(env, stream, offset, len, (char*)sc->sn.buffer + (sc->snd_sent%buffersize));
offset += len;
sc->snd_sent += len;
} }
else
offset = len; /*so the playback thread ends up blocked properly*/
return offset; return offset;
} }
static void Droid_Shutdown(soundcardinfo_t *sc) static void Droid_Shutdown(soundcardinfo_t *sc)
{ {
// pthread_mutex_lock(&mutex); //fixme: what if we're currently inside Java_com_fteqw_FTEDroidEngine_paintaudio?
sys_sc = NULL; sys_sc = NULL;
free(sc->sn.buffer); free(sc->sn.buffer);
sys_soundflags = 0; sys_soundflags = 0;
// pthread_mutex_unlock(&mutex);
} }
//return the number of samples that have already been submitted to the device.
static unsigned int Droid_GetDMAPos(soundcardinfo_t *sc) static unsigned int Droid_GetDMAPos(soundcardinfo_t *sc)
{ {
sc->sn.samplepos = sc->snd_sent / (sc->sn.samplebits/8); sc->sn.samplepos = sc->snd_sent / (sc->sn.samplebits/8);
@ -90,12 +85,10 @@ static unsigned int Droid_GetDMAPos(soundcardinfo_t *sc)
static void Droid_UnlockBuffer(soundcardinfo_t *sc, void *buffer) static void Droid_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
{ {
// pthread_mutex_unlock(&mutex);
} }
static void *Droid_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx) static void *Droid_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{ {
// pthread_mutex_lock(&mutex);
return sc->sn.buffer; return sc->sn.buffer;
} }
@ -116,34 +109,28 @@ static int Droid_InitCard (soundcardinfo_t *sc, int cardnum)
if (sys_sc) if (sys_sc)
return 2; return 2;
// if (!pthread_mutex_lock(&mutex)) sc->selfpainting = true;
{ // sc->sn.speed = 11025;
sc->selfpainting = true; // sc->sn.samplebits = 16;
// sc->sn.speed = 11025; // sc->sn.numchannels = 1;
// sc->sn.samplebits = 16;
// sc->sn.numchannels = 1;
/*internal buffer should have 1 sec audio*/ /*internal buffer should have 1 sec audio*/
sc->sn.samples = sc->sn.speed*sc->sn.numchannels; sc->sn.samples = sc->sn.speed*sc->sn.numchannels;
sc->Lock = Droid_LockBuffer; sc->Lock = Droid_LockBuffer;
sc->Unlock = Droid_UnlockBuffer; sc->Unlock = Droid_UnlockBuffer;
sc->SetWaterDistortion = Droid_SetUnderWater; sc->SetWaterDistortion = Droid_SetUnderWater;
sc->Submit = Droid_Submit; sc->Submit = Droid_Submit;
sc->Shutdown = Droid_Shutdown; sc->Shutdown = Droid_Shutdown;
sc->GetDMAPos = Droid_GetDMAPos; sc->GetDMAPos = Droid_GetDMAPos;
sc->sn.buffer = malloc(sc->sn.samples*sc->sn.samplebits/8); sc->sn.buffer = malloc(sc->sn.samples*sc->sn.samplebits/8);
sys_sc = sc; sys_sc = sc;
sys_soundflags = 3; sys_soundflags = 3;
// pthread_mutex_unlock(&mutex);
return 1; return 1;
}
return 0;
} }
int (*pDroid_InitCard) (soundcardinfo_t *sc, int cardnum) = &Droid_InitCard; int (*pDroid_InitCard) (soundcardinfo_t *sc, int cardnum) = &Droid_InitCard;

View file

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h" #include "quakedef.h"
#include "winquake.h" #include "winquake.h"
#include "fs.h"
int cache_full_cycle; int cache_full_cycle;
@ -779,7 +780,8 @@ qboolean S_LoadSound (sfx_t *s)
if (name[1] == ':' && name[2] == '\\') if (name[1] == ':' && name[2] == '\\')
{ {
FILE *f; vfsfile_t *f;
int fsize;
#ifndef _WIN32 //convert from windows to a suitable alternative. #ifndef _WIN32 //convert from windows to a suitable alternative.
char unixname[128]; char unixname[128];
Q_snprintfz(unixname, sizeof(unixname), "/mnt/%c/%s", name[0]-'A'+'a', name+3); Q_snprintfz(unixname, sizeof(unixname), "/mnt/%c/%s", name[0]-'A'+'a', name+3);
@ -794,16 +796,16 @@ qboolean S_LoadSound (sfx_t *s)
#endif #endif
if ((f = fopen(name, "rb"))) if ((f = VFSOS_Open(name, "rb")))
{ {
com_filesize = COM_filelength(f); fsize = VFS_GETLEN(f);
data = Hunk_TempAlloc (com_filesize); data = Hunk_TempAlloc (fsize);
result = fread(data, 1, com_filesize, f); //do something with result result = VFS_READ(f, data, fsize);
if (result != com_filesize) if (result != fsize)
Con_SafePrintf("S_LoadSound() fread: Filename: %s, expected %i, result was %u\n",name,com_filesize,(unsigned int)result); Con_SafePrintf("S_LoadSound() fread: Filename: %s, expected %i, result was %u\n", name, fsize, (unsigned int)result);
fclose(f); VFS_CLOSE(f);
} }
else else
{ {

View file

@ -64,6 +64,7 @@ public:
} }
static void statuschanged(void *arg) static void statuschanged(void *arg)
{ {
//potentially comes from another thread
//axfte *fte = (axfte*)arg; //axfte *fte = (axfte*)arg;
InvalidateRect(NULL, NULL, FALSE); InvalidateRect(NULL, NULL, FALSE);
} }
@ -602,6 +603,7 @@ public:
ULONG_PTR dwContinue), ULONG_PTR dwContinue),
/* [in] */ ULONG_PTR dwContinue) /* [in] */ ULONG_PTR dwContinue)
{ {
struct contextpublic *pub = (struct contextpublic*)plug;
int width, height; int width, height;
HBITMAP bmp = (HBITMAP)funcs->GetSplashBack(plug, hdcDraw, &width, &height); HBITMAP bmp = (HBITMAP)funcs->GetSplashBack(plug, hdcDraw, &width, &height);
if (bmp) if (bmp)
@ -620,6 +622,11 @@ public:
DeleteDC(memDC); DeleteDC(memDC);
funcs->ReleaseSplashBack(plug, bmp); funcs->ReleaseSplashBack(plug, bmp);
} }
if (*pub->statusmessage)
{
SetBkMode(hdcDraw, TRANSPARENT);
TextOutA(hdcDraw, 0, 0, pub->statusmessage, strlen(pub->statusmessage));
}
return S_OK; return S_OK;
} }
@ -785,10 +792,6 @@ struct
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\VersionIndependentProgID\\", "FTE.FTEPlug"}, {"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\VersionIndependentProgID\\", "FTE.FTEPlug"},
{"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\ProgID\\", "FTE.FTEPlug.1.0"}, {"Software\\Classes\\CLSID\\{"axfte_iid_str"}\\ProgID\\", "FTE.FTEPlug.1.0"},
#ifdef warningmsg
#pragma warningmsg("Hey, moodles, do you want the plugin to register itself as a firefox plugin at the same time as it registers itself for support in IE?")
#endif
/*
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Description", ENGINEWEBSITE}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\Description", ENGINEWEBSITE},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\GeckoVersion", "1.00"}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\GeckoVersion", "1.00"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Path", "***DLLNAME***"}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\Path", "***DLLNAME***"},
@ -800,7 +803,6 @@ struct
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\MimeTypes\\application/x-qtv\\Suffixes", "qtv"}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\MimeTypes\\application/x-qtv\\Suffixes", "qtv"},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\qtv", ""}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\qtv", ""},
{"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\mvd", ""}, {"Software\\MozillaPlugins\\@fteqw.com/FTE\\Suffixes\\mvd", ""},
*/
{NULL} {NULL}
}; };
HRESULT WINAPI DllRegisterServer(void) HRESULT WINAPI DllRegisterServer(void)
@ -826,8 +828,15 @@ HRESULT WINAPI DllRegisterServer(void)
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)binaryname, strlen(binaryname)); RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)binaryname, strlen(binaryname));
else if (!strcmp(regkeys[i].value, "***VERSION***")) else if (!strcmp(regkeys[i].value, "***VERSION***"))
{ {
char *ver = version_string(); char s[128];
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)ver, strlen(ver)); #ifdef OFFICIAL_RELEASE
Q_snprintfz(s, sizeof(s), "%s v%i.%02i", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR);
#elif defined(SVNREVISION)
Q_snprintfz(s, sizeof(s), "%s SVN %s", DISTRIBUTION, STRINGIFY(SVNREVISION));
#else
Q_snprintfz(s, sizeof(s), "%s build %s", DISTRIBUTION, __DATE__);
#endif
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)s, strlen(s));
} }
else else
RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)regkeys[i].value, strlen(regkeys[i].value)); RegSetValueExA(h, ls, 0, REG_SZ, (BYTE*)regkeys[i].value, strlen(regkeys[i].value));

View file

@ -27,10 +27,11 @@ static unsigned int vibrateduration;
static char errormessage[256]; static char errormessage[256];
extern jmp_buf host_abort; extern jmp_buf host_abort;
cvar_t sys_vibrate = CVAR("sys_vibrate", "1"); cvar_t sys_vibrate = CVARD("sys_vibrate", "1", "Enables the system vibrator for damage events and such things. The value provided is a duration scaler.");
cvar_t sys_osk = CVAR("sys_osk", "0"); //to be toggled cvar_t sys_osk = CVAR("sys_osk", "0"); //to be toggled
cvar_t sys_keepscreenon = CVAR("sys_keepscreenon", "1"); //to be toggled cvar_t sys_keepscreenon = CVARD("sys_keepscreenon", "1", "If set, the screen will never darken. This might cost some extra battery power, but then so will running a 3d engine."); //to be toggled
cvar_t sys_orientation = CVAR("sys_orientation", "sensor"); cvar_t sys_orientation = CVARD("sys_orientation", "landscape", "Specifies what angle to render quake at.\nValid values are: sensor (autodetect), landscape, portrait, reverselandscape, reverseportrait");
cvar_t sys_glesversion_cvar = CVARD("sys_glesversion", "1", "Specifies which version of gles to use. 1 or 2 are valid values.");
extern cvar_t vid_conautoscale; extern cvar_t vid_conautoscale;
@ -56,9 +57,15 @@ JNIEXPORT jstring JNICALL Java_com_fteqw_FTEDroidEngine_geterrormessage(JNIEnv *
JNIEXPORT jstring JNICALL Java_com_fteqw_FTEDroidEngine_getpreferedorientation(JNIEnv *env, jobject obj) JNIEXPORT jstring JNICALL Java_com_fteqw_FTEDroidEngine_getpreferedorientation(JNIEnv *env, jobject obj)
{ {
sys_orientation.modified = false; sys_orientation.modified = false;
sys_glesversion_cvar.modified = false;
return (*env)->NewStringUTF(env, sys_orientation.string); return (*env)->NewStringUTF(env, sys_orientation.string);
} }
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_getpreferedglesversion(JNIEnv *env, jobject obj)
{
return sys_glesversion_cvar.ival;
}
/*the java passes in all input directly via a 'UI' thread. we don't need to poll it at all*/ /*the java passes in all input directly via a 'UI' thread. we don't need to poll it at all*/
void INS_Move(float *movements, int pnum) void INS_Move(float *movements, int pnum)
{ {
@ -96,8 +103,11 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
static vec3_t oac; static vec3_t oac;
//if we had an error, don't even run a frame any more. //if we had an error, don't even run a frame any more.
if (*errormessage) if (*errormessage || !sys_running)
{
Sys_Printf("Crashed or quit\n");
return 8; return 8;
}
#ifdef SERVERONLY #ifdef SERVERONLY
SV_Frame(); SV_Frame();
@ -127,7 +137,7 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
ret |= 4; ret |= 4;
if (*errormessage) if (*errormessage)
ret |= 8; ret |= 8;
if (sys_orientation.modified) if (sys_orientation.modified || sys_glesversion_cvar.modified)
ret |= 16; ret |= 16;
if (sys_soundflags) if (sys_soundflags)
{ {
@ -190,6 +200,7 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
Sys_Printf("reinit\n"); Sys_Printf("reinit\n");
if (sys_memheap) if (sys_memheap)
free(sys_memheap); free(sys_memheap);
memset(&parms, 0, sizeof(parms));
parms.basedir = NULL; /*filled in later*/ parms.basedir = NULL; /*filled in later*/
parms.argc = 3; parms.argc = 3;
parms.argv = args; parms.argv = args;
@ -239,6 +250,7 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
#endif #endif
sys_running = true; sys_running = true;
sys_lastframe = Sys_Milliseconds(); sys_lastframe = Sys_Milliseconds();
sys_orientation.modified = true;
} }
} }
@ -407,6 +419,7 @@ void Sys_Init(void)
Cvar_Register(&sys_osk, "android stuff"); Cvar_Register(&sys_osk, "android stuff");
Cvar_Register(&sys_keepscreenon, "android stuff"); Cvar_Register(&sys_keepscreenon, "android stuff");
Cvar_Register(&sys_orientation, "android stuff"); Cvar_Register(&sys_orientation, "android stuff");
Cvar_Register(&sys_glesversion_cvar, "android stuff");
} }
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)

View file

@ -398,6 +398,8 @@ int main(int argc, char **argv)
quakeparms_t parms; quakeparms_t parms;
int i; int i;
memset(&parms, 0, sizeof(parms));
COM_InitArgv(argc, argv); COM_InitArgv(argc, argv);
TL_InitLanguages(); TL_InitLanguages();

View file

@ -67,7 +67,7 @@ qboolean NPFTE_BeginDownload(void *ctx, struct pipetype *ftype, char *url)
} }
void NPFTE_StatusChanged(void *sysctx) void NPFTE_StatusChanged(void *sysctx)
{ { //potentially called from another thread
NPP instance = sysctx; NPP instance = sysctx;
struct contextpublic *pub = instance->pdata; struct contextpublic *pub = instance->pdata;
InvalidateRgn(pub->oldwnd, NULL, FALSE); InvalidateRgn(pub->oldwnd, NULL, FALSE);
@ -128,11 +128,28 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
case WM_ERASEBKGND: case WM_ERASEBKGND:
return FALSE; return FALSE;
case WM_PAINT: case WM_PAINT:
if (pub->downloading) if (*pub->statusmessage)
{ {
HDC hdc; HDC hdc;
PAINTSTRUCT paint; PAINTSTRUCT paint;
char *s; unsigned int progress;
unsigned int total;
progress = pub->dldone;
total = pub->dlsize;
hdc = BeginPaint(hWnd, &paint);
DrawWndBack(ctx, hWnd, hdc, &paint);
SetBkMode(hdc, TRANSPARENT);
TextOutA(hdc, 0, 0, pub->statusmessage, strlen(pub->statusmessage));
EndPaint(hWnd, &paint);
return TRUE;
}
else if (pub->downloading)
{
HDC hdc;
PAINTSTRUCT paint;
char s[32];
unsigned int progress; unsigned int progress;
unsigned int total; unsigned int total;
@ -144,11 +161,11 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
SetBkMode(hdc, TRANSPARENT); SetBkMode(hdc, TRANSPARENT);
TextOutA(hdc, 0, 0, "Downloading Data, please wait", 16); TextOutA(hdc, 0, 0, "Downloading Data, please wait", 16);
if (!progress && !total) if (!progress && !total)
s = "connecting"; sprintf(s, "connecting");
else if (total) else if (total)
s = va("%i bytes (%i%%)", progress, (int)((100.0f*progress)/total)); sprintf(s, "%i bytes (%i%%)", progress, (int)((100.0f*progress)/total));
else else
s = va("%i bytes", progress); sprintf(s, "%i bytes", progress);
TextOutA(hdc, 0, 32, s, strlen(s)); TextOutA(hdc, 0, 32, s, strlen(s));
EndPaint(hWnd, &paint); EndPaint(hWnd, &paint);
return TRUE; return TRUE;
@ -169,9 +186,9 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
if (pub->availver) if (pub->availver)
{ {
s = va("Your plugin may be incompatible"); s = "Your plugin may be incompatible";
TextOutA(hdc, 0, 32, s, strlen(s)); TextOutA(hdc, 0, 32, s, strlen(s));
s = va("Version %3.2f was requested, you are using version %3.2f", pub->availver, (float)version_number()); s = "A newer version is available. Your version is dated " __DATE__ ".";
TextOutA(hdc, 0, 48, s, strlen(s)); TextOutA(hdc, 0, 48, s, strlen(s));
} }
} }
@ -183,7 +200,7 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
SetActiveWindow(hWnd); SetActiveWindow(hWnd);
if (!Plug_StartContext(ctx)) if (!Plug_StartContext(ctx))
Plug_StopContext(NULL); Plug_StopContext(NULL, false);
break; break;
default: default:
break; break;

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,7 @@ struct contextpublic
unsigned int dlsize; unsigned int dlsize;
unsigned int dldone; unsigned int dldone;
float availver; /*this is the version of the plugin that is available, if current is better, use 0*/ float availver; /*this is the version of the plugin that is available, if current is better, use 0*/
char statusmessage[256];
#if defined(_WIN32) && defined(__QUAKEDEF_H__) #if defined(_WIN32) && defined(__QUAKEDEF_H__)
/*the npapi stuff is lazy and uses this*/ /*the npapi stuff is lazy and uses this*/
@ -58,7 +59,7 @@ struct context *Plug_CreateContext(void *sysctx, const struct browserfuncs *func
void Plug_DestroyContext(struct context *ctx); void Plug_DestroyContext(struct context *ctx);
void Plug_LockPlugin(struct context *ctx, qboolean lockstate); void Plug_LockPlugin(struct context *ctx, qboolean lockstate);
qboolean Plug_StartContext(struct context *ctx); qboolean Plug_StartContext(struct context *ctx);
void Plug_StopContext(struct context *ctx); void Plug_StopContext(struct context *ctx, qboolean wait);
qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int left, int top, int width, int height); qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int left, int top, int width, int height);
int Plug_FindProp(struct context *ctx, const char *field); int Plug_FindProp(struct context *ctx, const char *field);
@ -81,7 +82,7 @@ struct plugfuncs
void (*DestroyContext)(struct context *ctx); void (*DestroyContext)(struct context *ctx);
void (*LockPlugin)(struct context *ctx, qboolean lockstate); void (*LockPlugin)(struct context *ctx, qboolean lockstate);
qboolean (*StartContext)(struct context *ctx); qboolean (*StartContext)(struct context *ctx);
void (*StopContext)(struct context *ctx); void (*StopContext)(struct context *ctx, qboolean wait);
qboolean (*ChangeWindow)(struct context *ctx, void *whnd, int left, int top, int width, int height); qboolean (*ChangeWindow)(struct context *ctx, void *whnd, int left, int top, int width, int height);
int (*FindProp)(struct context *ctx, const char *field); int (*FindProp)(struct context *ctx, const char *field);

View file

@ -483,6 +483,8 @@ int QDECL main(int argc, char **argv)
int t; int t;
int delay = 1; int delay = 1;
memset(&parms, 0, sizeof(parms));
parms.argv = argv; parms.argv = argv;
parms.basedir = "."; parms.basedir = ".";

View file

@ -49,6 +49,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if !defined(CLIENTONLY) && !defined(SERVERONLY) #if !defined(CLIENTONLY) && !defined(SERVERONLY)
qboolean isDedicated = false; qboolean isDedicated = false;
#endif #endif
qboolean isPlugin;
qboolean debugout; qboolean debugout;
HWND sys_parentwindow; HWND sys_parentwindow;
@ -87,7 +88,11 @@ qboolean Sys_RandomBytes(qbyte *string, int len)
return true; return true;
} }
/*
=================
Library loading
=================
*/
void Sys_CloseLibrary(dllhandle_t *lib) void Sys_CloseLibrary(dllhandle_t *lib)
{ {
FreeLibrary((HMODULE)lib); FreeLibrary((HMODULE)lib);
@ -371,19 +376,183 @@ typedef BOOL (WINAPI *MINIDUMPWRITEDUMP) (
#ifdef PRINTGLARRAYS #ifdef PRINTGLARRAYS
#include "glquake.h" #include "glquake.h"
#define GL_ARRAY_BUFFER 0x8892 #define GL_VERTEX_ARRAY_BINDING 0x85B5
#define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_ARRAY_BUFFER 0x8892
#define GL_ARRAY_BUFFER_BINDING 0x8894 #define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
#define GL_CURRENT_PROGRAM 0x8B8D
char *DecodeGLEnum(GLenum num)
{
switch(num)
{
case GL_CW: return "GL_CW";
case GL_CCW: return "GL_CCW";
case GL_NEVER: return "GL_NEVER";
case GL_LESS: return "GL_LESS";
case GL_EQUAL: return "GL_EQUAL";
case GL_LEQUAL: return "GL_LEQUAL";
case GL_GREATER: return "GL_GREATER";
case GL_NOTEQUAL: return "GL_NOTEQUAL";
case GL_GEQUAL: return "GL_GEQUAL";
case GL_ALWAYS: return "GL_ALWAYS";
case GL_FRONT: return "GL_FRONT";
case GL_BACK: return "GL_BACK";
case GL_FRONT_AND_BACK: return "GL_FRONT_AND_BACK";
case GL_COMBINE_ARB: return "GL_COMBINE";
case GL_MODULATE: return "GL_MODULATE";
case GL_REPLACE: return "GL_REPLACE";
case GL_ZERO: return "GL_ZERO";
case GL_ONE: return "GL_ONE";
case GL_SRC_COLOR: return "GL_SRC_COLOR";
case GL_ONE_MINUS_SRC_COLOR: return "GL_ONE_MINUS_SRC_COLOR";
case GL_SRC_ALPHA: return "GL_SRC_ALPHA";
case GL_ONE_MINUS_SRC_ALPHA: return "GL_ONE_MINUS_SRC_ALPHA";
case GL_DST_ALPHA: return "GL_DST_ALPHA";
case GL_ONE_MINUS_DST_ALPHA: return "GL_ONE_MINUS_DST_ALPHA";
case GL_DST_COLOR: return "GL_DST_COLOR";
case GL_ONE_MINUS_DST_COLOR: return "GL_ONE_MINUS_DST_COLOR";
case GL_SRC_ALPHA_SATURATE: return "GL_SRC_ALPHA_SATURATE";
default: return va("0x%x", num);
}
}
void DumpGLState(void)
{
int rval;
void *ptr;
int i;
GLint glint;
GLint glint4[4];
void (APIENTRY *qglGetVertexAttribiv) (GLuint index, GLenum pname, GLint* params);
void (APIENTRY *qglGetVertexAttribPointerv) (GLuint index, GLenum pname, GLvoid** pointer);
qglGetVertexAttribiv = (void*)wglGetProcAddress("glGetVertexAttribiv");
qglGetVertexAttribPointerv = (void*)wglGetProcAddress("glGetVertexAttribPointerv");
#pragma comment(lib,"opengl32.lib")
if (qglGetVertexAttribiv)
{
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &rval);
Sys_Printf("VERTEX_ARRAY_BINDING: %i\n", rval);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &rval);
Sys_Printf("GL_ARRAY_BUFFER_BINDING: %i\n", rval);
if (glIsEnabled(GL_COLOR_ARRAY))
{
glGetIntegerv(GL_COLOR_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_COLOR_ARRAY_POINTER, &ptr);
Sys_Printf("GL_COLOR_ARRAY: %s %i:%p\n", glIsEnabled(GL_COLOR_ARRAY)?"en":"dis", rval, ptr);
}
// if (glIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT))
// {
// glGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_FOG_COORDINATE_ARRAY_EXT: %i (%lx)\n", (int) glIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT), (int) ptr);
// }
// if (glIsEnabled(GL_INDEX_ARRAY))
{
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_INDEX_ARRAY_POINTER, &ptr);
Sys_Printf("GL_INDEX_ARRAY: %s %i:%p\n", glIsEnabled(GL_INDEX_ARRAY)?"en":"dis", rval, ptr);
}
if (glIsEnabled(GL_NORMAL_ARRAY))
{
glGetIntegerv(GL_NORMAL_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_NORMAL_ARRAY_POINTER, &ptr);
Sys_Printf("GL_NORMAL_ARRAY: %s %i:%p\n", glIsEnabled(GL_NORMAL_ARRAY)?"en":"dis", rval, ptr);
}
// glGetPointerv(GL_SECONDARY_COLOR_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_SECONDARY_COLOR_ARRAY: %i (%lx)\n", (int) glIsEnabled(GL_SECONDARY_COLOR_ARRAY), (int) ptr);
for (i = 0; i < 4; i++)
{
qglClientActiveTextureARB(mtexid0 + i);
if (glIsEnabled(GL_TEXTURE_COORD_ARRAY))
{
glGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &ptr);
Sys_Printf("GL_TEXTURE_COORD_ARRAY %i: %s %i:%p\n", i, glIsEnabled(GL_TEXTURE_COORD_ARRAY)?"en":"dis", rval, ptr);
}
}
if (glIsEnabled(GL_VERTEX_ARRAY))
{
glGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_VERTEX_ARRAY_POINTER, &ptr);
Sys_Printf("GL_VERTEX_ARRAY: %s %i:%p\n", glIsEnabled(GL_VERTEX_ARRAY)?"en":"dis", rval, ptr);
}
for (i = 0; i < 16; i++)
{
int en, bo, as, st, ty, no;
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &en);
if (!en)
continue;
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &bo);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &as);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &st);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &ty);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &no);
qglGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
Sys_Printf("attrib%i: %s as:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr);
}
glGetIntegerv(GL_CURRENT_PROGRAM, &glint);
Sys_Printf("GL_CURRENT_PROGRAM: %i\n", glint);
glGetIntegerv(GL_BLEND, &glint);
Sys_Printf("GL_BLEND: %i\n", glint);
glGetIntegerv(GL_BLEND_SRC, &glint);
Sys_Printf("GL_BLEND_SRC: %i\n", DecodeGLEnum(glint));
glGetIntegerv(GL_BLEND_DST, &glint);
Sys_Printf("GL_BLEND_DST: %i\n", DecodeGLEnum(glint));
glGetIntegerv(GL_DEPTH_WRITEMASK, &glint);
Sys_Printf("GL_DEPTH_WRITEMASK: %i\n", glint);
glGetIntegerv(GL_DEPTH_TEST, &glint);
Sys_Printf("GL_DEPTH_TEST: %i\n", glint);
glGetIntegerv(GL_DEPTH_FUNC, &glint);
Sys_Printf("GL_DEPTH_FUNC: %s\n", DecodeGLEnum(glint));
glGetIntegerv(GL_CULL_FACE, &glint);
Sys_Printf("GL_CULL_FACE: %i\n", glint);
glGetIntegerv(GL_CULL_FACE_MODE, &glint);
Sys_Printf("GL_CULL_FACE_MODE: %s\n", DecodeGLEnum(glint));
glGetIntegerv(GL_FRONT_FACE, &glint);
Sys_Printf("GL_FRONT_FACE: %s\n", DecodeGLEnum(glint));
glGetIntegerv(GL_SCISSOR_TEST, &glint);
Sys_Printf("GL_SCISSOR_TEST: %i\n", glint);
glGetIntegerv(GL_STENCIL_TEST, &glint);
Sys_Printf("GL_STENCIL_TEST: %i\n", glint);
glGetIntegerv(GL_COLOR_WRITEMASK, glint4);
Sys_Printf("GL_COLOR_WRITEMASK: %i %i %i %i\n", glint4[0], glint4[1], glint4[2], glint4[3]);
GL_SelectTexture(0);
glGetIntegerv(GL_TEXTURE_2D, &glint);
Sys_Printf("GL_TEXTURE_2D: %i\n", glint);
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint);
Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint));
GL_SelectTexture(1);
glGetIntegerv(GL_TEXTURE_2D, &glint);
Sys_Printf("GL_TEXTURE_2D: %i\n", glint);
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint);
Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint));
GL_SelectTexture(2);
glGetIntegerv(GL_TEXTURE_2D, &glint);
Sys_Printf("GL_TEXTURE_2D: %i\n", glint);
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &glint);
Sys_Printf("GL_TEXTURE_ENV_MODE: %s\n", DecodeGLEnum(glint));
}
}
#endif #endif
DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo) DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo)
@ -398,56 +567,7 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception
BOOL (WINAPI *pIsDebuggerPresent)(void); BOOL (WINAPI *pIsDebuggerPresent)(void);
#ifdef PRINTGLARRAYS #ifdef PRINTGLARRAYS
int rval; DumpGLState();
void *ptr;
int i;
void (APIENTRY *qglGetVertexAttribiv) (GLuint index, GLenum pname, GLint* params);
void (APIENTRY *qglGetVertexAttribPointerv) (GLuint index, GLenum pname, GLvoid** pointer);
qglGetVertexAttribiv = (void*)wglGetProcAddress("glGetVertexAttribiv");
qglGetVertexAttribPointerv = (void*)wglGetProcAddress("glGetVertexAttribPointerv");
#pragma comment(lib,"opengl32.lib")
if (qglGetVertexAttribiv)
{
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &rval);
Sys_Printf("GL_ARRAY_BUFFER_BINDING: %i\n", rval);
glGetPointerv(GL_COLOR_ARRAY_POINTER, &ptr);
Sys_Printf("GL_COLOR_ARRAY: %s (%lx)\n", glIsEnabled(GL_COLOR_ARRAY)?"en":"dis", (int) ptr);
// glGetPointerv(GL_FOG_COORD_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_FOG_COORDINATE_ARRAY_EXT: %i (%lx)\n", (int) glIsEnabled(GL_FOG_COORDINATE_ARRAY_EXT), (int) ptr);
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_INDEX_ARRAY_POINTER, &ptr);
Sys_Printf("GL_INDEX_ARRAY: %s %i:%p\n", glIsEnabled(GL_INDEX_ARRAY)?"en":"dis", rval, ptr);
glGetPointerv(GL_NORMAL_ARRAY_POINTER, &ptr);
Sys_Printf("GL_NORMAL_ARRAY: %s (%lx)\n", glIsEnabled(GL_NORMAL_ARRAY)?"en":"dis", (int) ptr);
// glGetPointerv(GL_SECONDARY_COLOR_ARRAY_POINTER, &ptr);
// Sys_Printf("GL_SECONDARY_COLOR_ARRAY: %i (%lx)\n", (int) glIsEnabled(GL_SECONDARY_COLOR_ARRAY), (int) ptr);
for (i = 0; i < 4; i++)
{
qglClientActiveTextureARB(mtexid0 + i);
glGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &ptr);
Sys_Printf("GL_TEXTURE_COORD_ARRAY %i: %s %i:%p\n", i, glIsEnabled(GL_TEXTURE_COORD_ARRAY)?"en":"dis", rval, ptr);
}
glGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &rval);
glGetPointerv(GL_VERTEX_ARRAY_POINTER, &ptr);
Sys_Printf("GL_VERTEX_ARRAY: %s %i:%p\n", glIsEnabled(GL_VERTEX_ARRAY)?"en":"dis", rval, ptr);
for (i = 0; i < 16; i++)
{
int en, bo, as, st, ty, no;
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &en);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &bo);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &as);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &st);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &ty);
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &no);
qglGetVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr);
Sys_Printf("attrib%i: %s as:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr);
}
}
#endif #endif
hKernel = LoadLibrary ("kernel32"); hKernel = LoadLibrary ("kernel32");
@ -851,15 +971,7 @@ void VARGS Sys_Error (const char *error, ...)
SetHookState(false); SetHookState(false);
#endif #endif
#ifdef NPFTE
{
extern jmp_buf host_abort;
/*jump to start of main loop (which exits the main loop)*/
longjmp (host_abort, 1);
}
#else
exit (1); exit (1);
#endif
} }
static wchar_t dequake(conchar_t chr) static wchar_t dequake(conchar_t chr)
@ -912,15 +1024,17 @@ void VARGS Sys_Printf (char *fmt, ...)
if (debugout) if (debugout)
{ {
//msvc debug output //msvc debug output
conchar_t msg[1024], *end; conchar_t msg[1024], *end, *in;
wchar_t wide[1024]; wchar_t wide[1024], *out;
int i;
end = COM_ParseFunString(CON_WHITEMASK, text, msg, sizeof(msg), false); end = COM_ParseFunString(CON_WHITEMASK, text, msg, sizeof(msg), false);
for (i = 0; msg+i < end; i++) out = wide;
in = msg;
for (in = msg; in < end; in++)
{ {
wide[i] = dequake(msg[i] & CON_CHARMASK); if (!(*in & CON_HIDDEN))
*out++ = dequake(*in & CON_CHARMASK);
} }
wide[i] = 0; *out = 0;
OutputDebugStringW(wide); OutputDebugStringW(wide);
} }
#endif #endif
@ -946,21 +1060,12 @@ void Sys_Quit (void)
longjmp(restart_jmpbuf, 1); longjmp(restart_jmpbuf, 1);
#endif #endif
#ifdef NPFTE
{
extern jmp_buf host_abort;
/*jump to start of main loop (which exits the main loop)*/
longjmp (host_abort, 1);
}
#else
#ifdef USE_MSVCRT_DEBUG #ifdef USE_MSVCRT_DEBUG
if (_CrtDumpMemoryLeaks()) if (_CrtDumpMemoryLeaks())
OutputDebugStringA("Leaks detected\n"); OutputDebugStringA("Leaks detected\n");
#endif #endif
exit(1); exit(1);
#endif
} }
@ -1262,7 +1367,52 @@ void Sys_SendKeyEvents (void)
{ {
MSG msg; MSG msg;
if (isDedicated) if (isPlugin)
{
DWORD avail;
static char text[256], *nl;
static int textpos = 0;
HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
if (!PeekNamedPipe(input, NULL, 0, NULL, &avail, NULL))
{
Cmd_ExecuteString("quit force", RESTRICT_LOCAL);
}
else if (avail)
{
if (avail > sizeof(text)-1-avail)
avail = sizeof(text)-1-avail;
if (ReadFile(input, text+textpos, avail, &avail, NULL))
{
textpos += avail;
while(1)
{
text[textpos] = 0;
nl = strchr(text, '\n');
if (nl)
{
*nl++ = 0;
if (!qrenderer && !strncmp(text, "vid_recenter ", 13))
{
Cmd_TokenizeString(text, false, false);
sys_parentleft = strtoul(Cmd_Argv(1), NULL, 0);
sys_parenttop = strtoul(Cmd_Argv(2), NULL, 0);
sys_parentwidth = strtoul(Cmd_Argv(3), NULL, 0);
sys_parentheight = strtoul(Cmd_Argv(4), NULL, 0);
sys_parentwindow = (HWND)strtoul(Cmd_Argv(5), NULL, 16);
}
Cmd_ExecuteString(text, RESTRICT_LOCAL);
memmove(text, nl, textpos - (nl - text));
textpos -= (nl - text);
}
else
break;
}
}
}
}
else if (isDedicated)
{ {
#ifndef CLIENTONLY #ifndef CLIENTONLY
SV_GetConsoleCommands (); SV_GetConsoleCommands ();
@ -1363,76 +1513,6 @@ qboolean Sys_Startup_CheckMem(quakeparms_t *parms)
return true; return true;
} }
#ifdef NPFTE
static quakeparms_t parms;
double lastlooptime;
qboolean NPQTV_Sys_Startup(int argc, char *argv[])
{
if (!host_initialized)
{
TL_InitLanguages();
parms.argc = argc;
parms.argv = argv;
parms.basedir = argv[0];
COM_InitArgv (parms.argc, parms.argv);
if (!Sys_Startup_CheckMem(&parms))
return false;
Host_Init (&parms);
}
lastlooptime = Sys_DoubleTime ();
return true;
}
void NPQTV_Sys_MainLoop(void)
{
double duratrion, newtime;
if (isDedicated)
{
#ifndef CLIENTONLY
NET_Sleep(50, false);
// find time passed since last cycle
newtime = Sys_DoubleTime ();
duratrion = newtime - lastlooptime;
lastlooptime = newtime;
SV_Frame ();
#else
Sys_Error("wut?");
#endif
}
else
{
#ifndef SERVERONLY
double sleeptime;
newtime = Sys_DoubleTime ();
duratrion = newtime - lastlooptime;
sleeptime = Host_Frame (duratrion);
lastlooptime = newtime;
SetHookState(sys_disableWinKeys.ival);
Sys_Sleep(sleeptime);
// Sleep(0);
#else
Sys_Error("wut?");
#endif
}
}
void Sys_RecentServer(char *command, char *target, char *title, char *desc)
{
}
#else
/* /*
================== ==================
WinMain WinMain
@ -1833,7 +1913,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
// MSG msg; // MSG msg;
quakeparms_t parms; quakeparms_t parms;
double time, oldtime, newtime; double time, oldtime, newtime;
char cwd[1024]; char cwd[1024], bindir[1024], *s;
const char *qtvfile = NULL; const char *qtvfile = NULL;
int delay = 0; int delay = 0;
@ -1841,6 +1921,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (hPrevInstance) if (hPrevInstance)
return 0; return 0;
memset(&parms, 0, sizeof(parms));
#ifndef MINGW #ifndef MINGW
#if _MSC_VER > 1200 #if _MSC_VER > 1200
Win7_Init(); Win7_Init();
@ -1937,12 +2019,21 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
setjmp (restart_jmpbuf); setjmp (restart_jmpbuf);
#endif #endif
GetModuleFileName(NULL, cwd, sizeof(cwd)-1); GetModuleFileName(NULL, bindir, sizeof(bindir)-1);
strcpy(exename, COM_SkipPath(cwd)); s = COM_SkipPath(exename);
strcpy(exename, s);
*s = 0;
parms.argv = (const char **)argv; parms.argv = (const char **)argv;
COM_InitArgv (parms.argc, parms.argv); COM_InitArgv (parms.argc, parms.argv);
isPlugin = !!COM_CheckParm("-plugin");
if (isPlugin)
{
printf("status Starting up!\n");
fflush(stdout);
}
if (COM_CheckParm("--version") || COM_CheckParm("-v")) if (COM_CheckParm("--version") || COM_CheckParm("-v"))
{ {
printf("version " DISTRIBUTION " " __TIME__ " " __DATE__ "\n"); printf("version " DISTRIBUTION " " __TIME__ " " __DATE__ "\n");
@ -1978,6 +2069,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
//tprints are now allowed //tprints are now allowed
parms.basedir = cwd; parms.basedir = cwd;
parms.binarydir = bindir;
parms.argc = com_argc; parms.argc = com_argc;
parms.argv = com_argv; parms.argv = com_argv;
@ -2050,6 +2142,12 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
#endif #endif
#endif #endif
if (isPlugin)
{
printf("status Running!\n");
fflush(stdout);
}
/* main window message loop */ /* main window message loop */
while (1) while (1)
{ {
@ -2134,7 +2232,6 @@ int __cdecl main(void)
} }
return WinMain(GetModuleHandle(NULL), NULL, cmdline, SW_NORMAL); return WinMain(GetModuleHandle(NULL), NULL, cmdline, SW_NORMAL);
} }
#endif
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{ {

View file

@ -16,11 +16,22 @@ F11 will step through.
#include "quakedef.h" #include "quakedef.h"
#ifdef TEXTEDITOR #ifdef TEXTEDITOR
static cvar_t alloweditor = SCVAR("alloweditor", "1"); //disallow loading editor for stepbystep debugging.
static cvar_t editstripcr = SCVAR("edit_stripcr", "1"); //remove \r from eols (on load). #ifdef _WIN32
static cvar_t editaddcr = SCVAR("edit_addcr", "1"); //make sure that each line ends with a \r (on save). #define editaddcr_default "1"
static cvar_t edittabspacing = SCVAR("edit_tabsize", "4"); #else
cvar_t debugger = SCVAR("debugger", "1"); #define editaddcr_default "0"
#endif
#ifdef ANDROID
#define debugger_default "0"
#else
#define debugger_default "1"
#endif
static cvar_t editstripcr = CVARD("edit_stripcr", "1", "remove \\r from eols (on load)");
static cvar_t editaddcr = CVARD("edit_addcr", editaddcr_default, "make sure that each line ends with a \\r (on save)");
static cvar_t edittabspacing = CVARD("edit_tabsize", "4", "How wide tab alignment is");
cvar_t debugger = CVARD("debugger", debugger_default, "When enabled, QC errors and debug events will enable step-by-step tracing.");
#undef pr_trace #undef pr_trace
@ -53,6 +64,21 @@ static void E_Free(void *mem)
#define GETBLOCK(s, ret) ret = (void *)E_Malloc(sizeof(fileblock_t) + s);ret->allocatedlength = s;ret->data = (char *)ret + sizeof(fileblock_t) #define GETBLOCK(s, ret) ret = (void *)E_Malloc(sizeof(fileblock_t) + s);ret->allocatedlength = s;ret->data = (char *)ret + sizeof(fileblock_t)
void PR_GenerateStatementString (progfuncs_t *progfuncs, int statementnum, char *out, int outlen);
fileblock_t *GenAsm(int statement)
{
char linebuf[256];
fileblock_t *b;
int l;
PR_GenerateStatementString(editprogfuncs, statement, linebuf, sizeof(linebuf));
l = strlen(linebuf);
b = E_Malloc(sizeof(fileblock_t) + l);
b->allocatedlength = l;
b->datalength = l;
b->data = (char *)b + sizeof(fileblock_t);
memcpy(b->data, linebuf, l);
return b;
}
static char OpenEditorFile[256]; static char OpenEditorFile[256];
@ -61,8 +87,10 @@ qboolean editoractive; //(export)
qboolean editormodal; //doesn't return. (export) qboolean editormodal; //doesn't return. (export)
static qboolean editorblocking; static qboolean editorblocking;
static qboolean madechanges; static qboolean madechanges;
static qboolean editenabled;
static qboolean insertkeyhit=true; static qboolean insertkeyhit=true;
static qboolean useeval; static qboolean useeval;
static qboolean stepasm;
static char evalstring[256]; static char evalstring[256];
@ -161,7 +189,7 @@ static void CloseEditor(void)
{ {
fileblock_t *b; fileblock_t *b;
key_dest = key_console; key_dest = key_game;
editoractive = false; editoractive = false;
editprogfuncs = NULL; editprogfuncs = NULL;
@ -169,11 +197,11 @@ static void CloseEditor(void)
return; return;
OpenEditorFile[0] = '\0'; OpenEditorFile[0] = '\0';
for (b = firstblock; b;) while(firstblock)
{ {
firstblock = b; b = firstblock;
b=b->next; firstblock=firstblock->next;
E_Free(firstblock); E_Free(b);
} }
madechanges = false; madechanges = false;
@ -227,6 +255,7 @@ static qboolean EditorSaveFile(char *s) //returns true if succesful
fclose(F); fclose(F);
*/ */
madechanges = false; madechanges = false;
editenabled = true;
executionlinenum = -1; executionlinenum = -1;
return true; return true;
@ -236,6 +265,14 @@ static qboolean EditorSaveFile(char *s) //returns true if succesful
static void EditorNewFile(void) static void EditorNewFile(void)
{ {
fileblock_t *b;
while(firstblock)
{
b = firstblock;
firstblock=firstblock->next;
E_Free(b);
}
GETBLOCK(64, firstblock); GETBLOCK(64, firstblock);
GETBLOCK(64, firstblock->next); GETBLOCK(64, firstblock->next);
firstblock->next->prev = firstblock; firstblock->next->prev = firstblock;
@ -250,9 +287,10 @@ static void EditorNewFile(void)
key_dest = key_editor; key_dest = key_editor;
editoractive = true; editoractive = true;
editenabled = true;
} }
static void EditorOpenFile(char *name) static void EditorOpenFile(char *name, qboolean readonly)
{ {
int i; int i;
char line[8192]; char line[8192];
@ -347,14 +385,17 @@ static void EditorOpenFile(char *name)
madechanges = false; madechanges = false;
executionlinenum = -1; executionlinenum = -1;
editenabled = !readonly;
key_dest = key_editor; key_dest = key_editor;
editoractive = true; editoractive = true;
} }
extern qboolean keydown[K_MAX];
void Editor_Key(int key, int unicode) void Editor_Key(int key, int unicode)
{ {
int i; int i;
fileblock_t *nb;
if (keybindings[key][0]) if (keybindings[key][0])
if (!strcmp(keybindings[key][0], "toggleconsole")) if (!strcmp(keybindings[key][0], "toggleconsole"))
{ {
@ -400,7 +441,7 @@ void Editor_Key(int key, int unicode)
if (key == K_SHIFT) if (key == K_SHIFT)
return; return;
if (useeval && key != K_F11 && key != K_F5) if (useeval)
{ {
switch(key) switch(key)
{ {
@ -408,19 +449,19 @@ void Editor_Key(int key, int unicode)
if (editprogfuncs) if (editprogfuncs)
*editprogfuncs->pr_trace = 0; *editprogfuncs->pr_trace = 0;
useeval = false; useeval = false;
break; return;
case K_F3: case K_F3:
useeval = false; useeval = false;
break; return;
case K_DEL: case K_DEL:
evalstring[0] = '\0'; evalstring[0] = '\0';
break; return;
case K_BACKSPACE: case K_BACKSPACE:
i = strlen(evalstring); i = strlen(evalstring);
if (i < 1) if (i < 1)
break; return;
evalstring[i-1] = '\0'; evalstring[i-1] = '\0';
break; return;
default: default:
if (unicode) if (unicode)
{ {
@ -428,9 +469,20 @@ void Editor_Key(int key, int unicode)
evalstring[i] = unicode; evalstring[i] = unicode;
evalstring[i+1] = '\0'; evalstring[i+1] = '\0';
} }
return;
case K_F5:
case K_F9:
case K_F11:
case K_MWHEELUP:
case K_UPARROW:
case K_PGUP:
case K_MWHEELDOWN:
case K_DOWNARROW:
case K_PGDN:
case K_LEFTARROW:
case K_RIGHTARROW:
break; break;
} }
return;
} }
/* if (ctrl_down && (key == 'c' || key == K_INS)) /* if (ctrl_down && (key == 'c' || key == K_INS))
@ -466,6 +518,14 @@ void Editor_Key(int key, int unicode)
cursorblock = cursorblock->prev; cursorblock = cursorblock->prev;
cursorlinenum--; cursorlinenum--;
} }
else if (cursorlinenum>1)
{
cursorlinenum--;
nb = GenAsm(cursorlinenum);
nb->next = cursorblock;
cursorblock->prev = nb;
firstblock = cursorblock = nb;
}
} }
} }
SetCursorpos(); SetCursorpos();
@ -490,6 +550,14 @@ void Editor_Key(int key, int unicode)
cursorblock = cursorblock->next; cursorblock = cursorblock->next;
cursorlinenum++; cursorlinenum++;
} }
else
{
cursorlinenum++;
nb = GenAsm(cursorlinenum);
nb->prev = cursorblock;
cursorblock->next = nb;
cursorblock = nb;
}
} }
} }
SetCursorpos(); SetCursorpos();
@ -516,7 +584,7 @@ void Editor_Key(int key, int unicode)
s++; s++;
} }
if (*file) if (*file)
EditorOpenFile(file); EditorOpenFile(file, false);
} }
break; break;
case K_F3: case K_F3:
@ -593,14 +661,39 @@ void Editor_Key(int key, int unicode)
case K_LEFTARROW: case K_LEFTARROW:
cursorx--; cursorx--;
if (keydown[K_CTRL])
{
//skip additional whitespace
while(cursorx > 0 && (cursorblock->data[cursorx-1] == ' ' || cursorblock->data[cursorx-1] <= '\t'))
cursorx--;
//skip over the word, to the start of it
while(cursorx > 0 && ((cursorblock->data[cursorx-1] >= 'a' && cursorblock->data[cursorx-1] <= 'z') ||
(cursorblock->data[cursorx-1] >= 'A' && cursorblock->data[cursorx-1] <= 'Z') ||
(cursorblock->data[cursorx-1] >= '0' && cursorblock->data[cursorx-1] <= '9')))
cursorx--;
}
if (cursorx < 0) if (cursorx < 0)
cursorx = 0; cursorx = 0;
break; break;
case K_RIGHTARROW: case K_RIGHTARROW:
cursorx++; if (keydown[K_CTRL])
if (cursorx > cursorblock->datalength) {
cursorx = cursorblock->datalength; while(cursorx+1 < cursorblock->datalength && ((cursorblock->data[cursorx] >= 'a' && cursorblock->data[cursorx] <= 'z') ||
(cursorblock->data[cursorx] >= 'A' && cursorblock->data[cursorx] <= 'Z') ||
(cursorblock->data[cursorx] >= '0' && cursorblock->data[cursorx] <= '9')))
cursorx++;
cursorx++;
while(cursorx+1 < cursorblock->datalength && (cursorblock->data[cursorx] == ' ' || cursorblock->data[cursorx] <= '\t'))
cursorx++;
}
else
{
cursorx++;
if (cursorx > cursorblock->datalength)
cursorx = cursorblock->datalength;
}
break; break;
case K_BACKSPACE: case K_BACKSPACE:
@ -615,29 +708,38 @@ void Editor_Key(int key, int unicode)
break; break;
} }
cursorlinenum-=1; if (editenabled)
madechanges = true; {
cursorlinenum-=1;
madechanges = true;
cursorblock = b->prev; cursorblock = b->prev;
MakeNewSize(cursorblock, b->datalength + cursorblock->datalength+5); MakeNewSize(cursorblock, b->datalength + cursorblock->datalength+5);
cursorx = cursorblock->datalength; cursorx = cursorblock->datalength;
memcpy(cursorblock->data + cursorblock->datalength, b->data, b->datalength); memcpy(cursorblock->data + cursorblock->datalength, b->data, b->datalength);
cursorblock->datalength += b->datalength; cursorblock->datalength += b->datalength;
cursorblock->next = b->next; cursorblock->next = b->next;
if (b->next) if (b->next)
b->next->prev = cursorblock; b->next->prev = cursorblock;
// cursorblock->prev->next = cursorblock->next; // cursorblock->prev->next = cursorblock->next;
// cursorblock->next->prev = cursorblock->prev; // cursorblock->next->prev = cursorblock->prev;
E_Free(b); E_Free(b);
// cursorblock = b; // cursorblock = b;
}
else
{
cursorblock = cursorblock->prev;
cursorx = cursorblock->datalength;
}
break; break;
} }
case K_DEL: //bksp falls through. case K_DEL: //bksp falls through.
if (editenabled)
{ {
int a; int a;
fileblock_t *b; fileblock_t *b;
@ -673,6 +775,7 @@ void Editor_Key(int key, int unicode)
break; break;
case K_ENTER: case K_ENTER:
if (editenabled)
{ {
fileblock_t *b = cursorblock; fileblock_t *b = cursorblock;
@ -695,14 +798,22 @@ void Editor_Key(int key, int unicode)
cursorx = 0; cursorx = 0;
} }
else if (cursorblock->next)
{
cursorblock = cursorblock->next;
cursorlinenum++;
cursorx = 0;
}
break; break;
case K_INS: case K_INS:
insertkeyhit = insertkeyhit?false:true; insertkeyhit = insertkeyhit?false:true;
break; break;
default: default:
if (!editenabled)
break;
if (unicode < ' ' && unicode != '\t') //we deem these as unprintable if (unicode < ' ' && unicode != '\t') //we deem these as unprintable
break; break;
if (insertkeyhit) //insert a char if (insertkeyhit) //insert a char
{ {
@ -735,58 +846,138 @@ void Editor_Key(int key, int unicode)
} }
} }
static void Draw_Line(int x, int y, fileblock_t *b, int cursorx) static void Draw_Line(int vy, fileblock_t *b, int cursorx)
{ {
int nx = 0, nnx; int nx = 0;
int y;
char *tooltip = NULL;
int nnx;
qbyte *d = b->data; qbyte *d = b->data;
qbyte *c; qbyte *c;
int i; int i;
extern int mousecursor_x, mousecursor_y;
int colour=COLOR_WHITE; int smx = (mousecursor_x * vid.pixelwidth) / vid.width, smy = (mousecursor_y * vid.pixelheight) / vid.height;
unsigned int colour;
int ts = edittabspacing.value; int ts = edittabspacing.value;
char linebuf[128];
if (cursorx >= 0) if (cursorx >= 0)
c = d + cursorx; c = d + cursorx;
else else
c = NULL; c = NULL;
Font_BeginString(font_conchar, x, y, &x, &y); Font_BeginString(font_conchar, nx, vy, &nx, &y);
if (ts < 1) if (ts < 1)
ts = 4; ts = 4;
ts*=8; ts*=8;
//figure out the colour
if (b->flags & (FB_BREAK)) if (b->flags & (FB_BREAK))
colour = COLOR_RED; //red
if (executionblock == b)
{ {
if (colour) //break point too if (executionblock == b)
colour = COLOR_GREEN; //green colour = COLOR_MAGENTA<<CON_FGSHIFT;
else else
colour = COLOR_YELLOW; //yellow colour = COLOR_RED<<CON_FGSHIFT;
}
else
{
if (executionblock == b)
colour = COLOR_YELLOW<<CON_FGSHIFT; //yellow
else
colour = COLOR_WHITE<<CON_FGSHIFT;
} }
nx = x; //if this line currently holds the mouse cursor, figure out the word that is highighted, and evaluate that word for debugging.
//self.ammo_shells is just 'self' if you highlight 'self', but if you highlight ammo_shells, it'll include the self, for easy debugging.
//use the f3 evaulator for more explicit debugging.
if (editprogfuncs && smy >= y && smy < y + Font_CharHeight())
{
int e, s;
nx = -viewportx;
for (i = 0; i < b->datalength; i++)
{
if (d[i] == '\t')
{
nnx=nx+ts;
nnx-=(nnx - -viewportx)%ts;
}
else
nnx = Font_CharEndCoord(font_conchar, nx, (int)d[i] | (colour));
if (smx >= nx && smx <= nnx)
{
for(s = i; s > 0; )
{
if ((d[s-1] >= 'a' && d[s-1] <= 'z') ||
(d[s-1] >= 'A' && d[s-1] <= 'Z') ||
(d[s-1] >= '0' && d[s-1] <= '9') ||
d[s-1] == '.' || d[s-1] == '_')
s--;
else
break;
}
for (e = i; e < b->datalength; )
{
if ((d[e] >= 'a' && d[e] <= 'z') ||
(d[e] >= 'A' && d[e] <= 'Z') ||
(d[e] >= '0' && d[e] <= '9') ||
/*d[e] == '.' ||*/ d[e] == '_')
e++;
else
break;
}
if (e >= s+sizeof(linebuf))
e = s+sizeof(linebuf) - 1;
memcpy(linebuf, d+s, e - s);
linebuf[e-s] = 0;
if (*linebuf)
tooltip = editprogfuncs->EvaluateDebugString(editprogfuncs, linebuf);
break;
}
nx = nnx;
}
}
nx = -viewportx;
for (i = 0; i < b->datalength; i++) for (i = 0; i < b->datalength; i++)
{ {
if (*d == '\t') if (*d == '\t')
{ {
if (d == c) if (d == c)
Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK)); {
int e = Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK|CON_BLINKTEXT));
if (e >= vid.pixelwidth)
viewportx += e - vid.pixelwidth;
if (nx < 0)
{
viewportx -= -nx;
if (viewportx < 0)
viewportx = 0;
}
}
nx+=ts; nx+=ts;
nx-=(nx - x)%ts; nx-=(nx - -viewportx)%ts;
d++; d++;
continue; continue;
} }
if (nx < (int)vid.pixelwidth) if (nx <= (int)vid.pixelwidth || cursorx>=0)
nnx = Font_DrawChar(nx, y, (int)*d | (colour<<CON_FGSHIFT)); nnx = Font_DrawChar(nx, y, (int)*d | (colour));
else nnx = vid.pixelwidth; else nnx = vid.pixelwidth;
if (d == c) if (d == c)
Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK)); {
int e = Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK|CON_BLINKTEXT));
if (e >= vid.pixelwidth)
viewportx += e - vid.pixelwidth;
if (nx < 0)
{
viewportx -= -nx;
if (viewportx < 0)
viewportx = 0;
}
}
nx = nnx; nx = nnx;
d++; d++;
@ -794,8 +985,32 @@ static void Draw_Line(int x, int y, fileblock_t *b, int cursorx)
/*we didn't do the cursor! stick it at the end*/ /*we didn't do the cursor! stick it at the end*/
if (c && c >= d) if (c && c >= d)
Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK)); {
int e = Font_DrawChar(nx, y, (int)11 | (CON_WHITEMASK|CON_BLINKTEXT));
if (e >= vid.pixelwidth)
viewportx += e - vid.pixelwidth;
if (nx < 0)
{
viewportx -= -nx;
if (viewportx < 0)
viewportx = 0;
}
}
if (tooltip)
{
while(*tooltip)
{
if (*tooltip == '\n')
{
smy += Font_CharHeight();
smx = (mousecursor_x * vid.pixelwidth) / vid.width;
tooltip++;
}
else
smx = Font_DrawChar(smx, smy, (COLOR_CYAN<<CON_FGSHIFT) | (COLOR_BLACK<<CON_BGSHIFT) | CON_NONCLEARBG | *tooltip++);
}
}
Font_EndString(font_conchar); Font_EndString(font_conchar);
} }
@ -821,7 +1036,6 @@ static fileblock_t *firstline(void)
void Editor_Draw(void) void Editor_Draw(void)
{ {
int x;
int y; int y;
int c; int c;
fileblock_t *b; fileblock_t *b;
@ -854,27 +1068,12 @@ void Editor_Draw(void)
} }
} }
x=0;
for (y = 0; y < cursorx; y++)
{
if (cursorblock->data[y] == '\0')
break;
else if (cursorblock->data[y] == '\t')
{
x+=32;
x&=~31;
}
else
x+=8;
}
x=-x + vid.width/2;
if (x > 0)
x = 0;
if (madechanges) if (madechanges)
Draw_FunString (vid.width - 8, 0, "!"); Draw_FunString (vid.width - 8, 0, "!");
if (!insertkeyhit) if (!insertkeyhit)
Draw_FunString (vid.width - 16, 0, "O"); Draw_FunString (vid.width - 16, 0, "O");
if (!editenabled)
Draw_FunString (vid.width - 24, 0, "R");
Draw_FunString(0, 0, va("%6i:%4i:%s", cursorlinenum, cursorx+1, OpenEditorFile)); Draw_FunString(0, 0, va("%6i:%4i:%s", cursorlinenum, cursorx+1, OpenEditorFile));
if (useeval) if (useeval)
@ -915,9 +1114,8 @@ void Editor_Draw(void)
{ {
c = -1; c = -1;
if (b == cursorblock) if (b == cursorblock)
if ((int)(Sys_DoubleTime()*4.0) & 1) c = cursorx;
c = cursorx; Draw_Line(y, b, c);
Draw_Line(x, y, b, c);
y+=8; y+=8;
if (y > vid.height) if (y > vid.height)
@ -947,10 +1145,10 @@ void Editor_Draw(void)
*/ */
} }
int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int nump, char **parms) int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int statement, int nump, char **parms)
{ {
char *f1, *f2; char *f1, *f2;
if (editormodal || line < 0 || !debugger.ival) if (editormodal || (line < 0 && !statement) || !debugger.ival)
return line; //whoops return line; //whoops
if (qrenderer == QR_NONE) if (qrenderer == QR_NONE)
@ -988,38 +1186,82 @@ int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int nump, char **
f1 += 4; f1 += 4;
if (!strncmp(f2, "src/", 4)) if (!strncmp(f2, "src/", 4))
f2 += 4; f2 += 4;
if (!editoractive || strcmp(f1, f2))
{
if (editoractive)
EditorSaveFile(OpenEditorFile);
EditorOpenFile(filename); stepasm = line < 0;
if (stepasm)
{
fileblock_t *nb, *lb;
int i;
EditorNewFile();
E_Free(firstblock->next);
E_Free(firstblock);
cursorlinenum = statement;
firstblock = GenAsm(cursorlinenum);
cursorblock = firstblock;
for (i = cursorlinenum; i > 0 && i > cursorlinenum - 20; i)
{
i--;
firstblock->prev = GenAsm(i);
firstblock->prev->next = firstblock;
firstblock = firstblock->prev;
}
lb = cursorblock;
for (i = cursorlinenum; i < cursorlinenum+20; )
{
i++;
nb = GenAsm(i);
lb->next = nb;
nb->prev = lb;
lb = nb;
}
}
else
{
if (!editoractive || strcmp(f1, f2))
{
if (editoractive && madechanges)
EditorSaveFile(OpenEditorFile);
EditorOpenFile(filename, true);
}
for (cursorlinenum = 1, cursorblock = firstblock; cursorlinenum < line && cursorblock->next; cursorlinenum++)
cursorblock=cursorblock->next;
} }
for (cursorlinenum = 1, cursorblock = firstblock; cursorlinenum < line && cursorblock->next; cursorlinenum++) executionlinenum = cursorlinenum;
cursorblock=cursorblock->next;
executionblock = cursorblock; executionblock = cursorblock;
if (!parms) if (!parms)
{ {
double oldrealtime = realtime;
editormodal = true; editormodal = true;
while(editormodal && editoractive && editprogfuncs) while(editormodal && editoractive && editprogfuncs)
{ {
realtime = Sys_DoubleTime();
// key_dest = key_editor; // key_dest = key_editor;
scr_disabled_for_loading=false; scr_disabled_for_loading=false;
SCR_UpdateScreen(); SCR_UpdateScreen();
Sys_SendKeyEvents(); Sys_SendKeyEvents();
IN_Commands ();
S_ExtraUpdate(); S_ExtraUpdate();
NET_Sleep(100, false); //any os. NET_Sleep(20, false); //any os.
} }
realtime = oldrealtime;
editormodal = false; editormodal = false;
} }
return line; if (stepasm)
return -executionlinenum;
else
return executionlinenum;
} }
void Editor_ProgsKilled(progfuncs_t *dead) void Editor_ProgsKilled(progfuncs_t *dead)
@ -1042,9 +1284,9 @@ static void Editor_f(void)
editprogfuncs = NULL; editprogfuncs = NULL;
useeval = false; useeval = false;
if (editoractive) if (editoractive && madechanges)
EditorSaveFile(OpenEditorFile); EditorSaveFile(OpenEditorFile);
EditorOpenFile(Cmd_Argv(1)); EditorOpenFile(Cmd_Argv(1), false);
// EditorNewFile(); // EditorNewFile();
} }
@ -1052,7 +1294,6 @@ void Editor_Init(void)
{ {
Cmd_AddCommand("edit", Editor_f); Cmd_AddCommand("edit", Editor_f);
Cvar_Register(&alloweditor, "Text editor");
Cvar_Register(&editstripcr, "Text editor"); Cvar_Register(&editstripcr, "Text editor");
Cvar_Register(&editaddcr, "Text editor"); Cvar_Register(&editaddcr, "Text editor");
Cvar_Register(&edittabspacing, "Text editor"); Cvar_Register(&edittabspacing, "Text editor");

View file

@ -142,19 +142,21 @@ V_CalcBob
float V_CalcBob (int pnum, qboolean queryold) float V_CalcBob (int pnum, qboolean queryold)
{ {
static double bobtime[MAX_SPLITS]; static double bobtime[MAX_SPLITS];
static double cltime[MAX_SPLITS];
static float bob[MAX_SPLITS]; static float bob[MAX_SPLITS];
float cycle; float cycle;
if (cl.spectator) if (cl.spectator)
return 0; return 0;
if (!cl.onground[pnum] || cl.paused || queryold) if (!cl.onground[pnum] || cl.paused)
return bob[pnum]; // just use old value return bob[pnum]; // just use old value
if (cl_bobcycle.value <= 0) if (cl_bobcycle.value <= 0)
return 0; return 0;
bobtime[pnum] += host_frametime; bobtime[pnum] += cl.time - cltime[pnum];
cltime[pnum] = cl.time;
cycle = bobtime[pnum] - (int)(bobtime[pnum]/cl_bobcycle.value)*cl_bobcycle.value; cycle = bobtime[pnum] - (int)(bobtime[pnum]/cl_bobcycle.value)*cl_bobcycle.value;
cycle /= cl_bobcycle.value; cycle /= cl_bobcycle.value;
if (cycle < cl_bobup.value) if (cycle < cl_bobup.value)
@ -568,7 +570,7 @@ void V_SetContentsColor (int contents)
cl.cshifts[CSHIFT_CONTENTS].percent *= v_contentblend.value; cl.cshifts[CSHIFT_CONTENTS].percent *= v_contentblend.value;
if (cl.cshifts[CSHIFT_SERVER].percent) if (cl.cshifts[CSHIFT_CONTENTS].percent)
{ //bound contents so it can't go negative { //bound contents so it can't go negative
if (cl.cshifts[CSHIFT_CONTENTS].percent < 0) if (cl.cshifts[CSHIFT_CONTENTS].percent < 0)
cl.cshifts[CSHIFT_CONTENTS].percent = 0; cl.cshifts[CSHIFT_CONTENTS].percent = 0;
@ -1292,13 +1294,16 @@ void R_DrawNameTags(void)
continue; continue;
if (i == cl.playernum[r_refdef.currentplayernum]) if (i == cl.playernum[r_refdef.currentplayernum])
continue; // Don't draw tag for the local player continue; // Don't draw tag for the local player
if (cl.players[i].spectator)
continue;
if (i == Cam_TrackNum(r_refdef.currentplayernum))
continue;
if (TP_IsPlayerVisible(nametagorg[i])) if (TP_IsPlayerVisible(nametagorg[i]))
{ {
VectorCopy(nametagorg[i], tagcenter); VectorCopy(nametagorg[i], tagcenter);
tagcenter[2] += 32; tagcenter[2] += 32;
Matrix4x4_CM_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y); if (!Matrix4x4_CM_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y))
if (center[2] > 1)
continue; continue;
len = COM_ParseFunString(CON_WHITEMASK, cl.players[i].name, buffer, sizeof(buffer), false) - buffer; len = COM_ParseFunString(CON_WHITEMASK, cl.players[i].name, buffer, sizeof(buffer), false) - buffer;
@ -1307,6 +1312,7 @@ void R_DrawNameTags(void)
} }
} }
void R2D_PolyBlend (void);
void V_RenderPlayerViews(int plnum) void V_RenderPlayerViews(int plnum)
{ {
int oldnuments; int oldnuments;
@ -1333,6 +1339,7 @@ void V_RenderPlayerViews(int plnum)
Cam_SelfTrack(plnum); Cam_SelfTrack(plnum);
R_RenderView (); R_RenderView ();
R2D_PolyBlend ();
R_DrawNameTags(); R_DrawNameTags();
cl_numvisedicts = oldnuments; cl_numvisedicts = oldnuments;

View file

@ -175,6 +175,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif #endif
#endif #endif
#else #else
#define USE_SQLITE
// #define USE_MYSQL
#define SIDEVIEWS 4 //enable secondary/reverse views. #define SIDEVIEWS 4 //enable secondary/reverse views.
#define SP2MODELS //quake2 sprite models #define SP2MODELS //quake2 sprite models
@ -260,6 +263,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef IRCCONNECT #undef IRCCONNECT
#endif #endif
#ifndef MULTITHREAD
#undef USE_SQLITE
#undef USE_MYSQL
#endif
#if defined(USE_SQLITE) || defined(USE_MYSQL)
#define SQL
#endif
//fix things a little... //fix things a little...
#ifdef NPQTV #ifdef NPQTV

View file

@ -1336,10 +1336,10 @@ char *Cmd_ExpandStringArguments (char *data, char *dest, int destlen)
============ ============
Cmd_TokenizeString Cmd_TokenizeString
Parses the given string into command line tokens. Parses the given string into command line tokens, stopping at the \n
============ ============
*/ */
void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize) char *Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
{ {
int i; int i;
@ -1365,7 +1365,7 @@ void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
} }
if (!*text) if (!*text)
return; return text;
if (cmd_argc == 1) if (cmd_argc == 1)
{ {
@ -1374,7 +1374,9 @@ void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
text = COM_StringParse (text, com_token, sizeof(com_token), expandmacros, qctokenize); text = COM_StringParse (text, com_token, sizeof(com_token), expandmacros, qctokenize);
if (!text) if (!text)
return; return text;
if (!strcmp(com_token, "\n"))
return text;
if (cmd_argc < MAX_ARGS) if (cmd_argc < MAX_ARGS)
{ {
@ -1383,6 +1385,7 @@ void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
cmd_argc++; cmd_argc++;
} }
} }
return text;
} }
void Cmd_TokenizePunctation (char *text, char *punctuation) void Cmd_TokenizePunctation (char *text, char *punctuation)
@ -1438,7 +1441,7 @@ Cmd_AddCommand
============ ============
*/ */
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function) qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *desc)
{ {
cmd_function_t *cmd; cmd_function_t *cmd;
@ -1467,6 +1470,7 @@ qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function)
cmd = (cmd_function_t*)Z_Malloc (sizeof(cmd_function_t)+strlen(cmd_name)+1); cmd = (cmd_function_t*)Z_Malloc (sizeof(cmd_function_t)+strlen(cmd_name)+1);
cmd->name = (char*)(cmd+1); cmd->name = (char*)(cmd+1);
cmd->description = desc;
strcpy(cmd->name, cmd_name); strcpy(cmd->name, cmd_name);
cmd->function = function; cmd->function = function;
cmd->next = cmd_functions; cmd->next = cmd_functions;
@ -1476,6 +1480,11 @@ qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function)
return true; return true;
} }
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function)
{
return Cmd_AddCommandD(cmd_name, function, NULL);
}
void Cmd_RemoveCommand (char *cmd_name) void Cmd_RemoveCommand (char *cmd_name)
{ {
cmd_function_t *cmd, **back; cmd_function_t *cmd, **back;
@ -1660,8 +1669,9 @@ typedef struct {
qboolean allowcutdown; qboolean allowcutdown;
qboolean cutdown; qboolean cutdown;
char result[256]; char result[256];
char *desc;
} match_t; } match_t;
void Cmd_CompleteCheck(char *check, match_t *match) //compare cumulative strings and join the result void Cmd_CompleteCheck(char *check, match_t *match, char *desc) //compare cumulative strings and join the result
{ {
if (*match->result) if (*match->result)
{ {
@ -1678,21 +1688,19 @@ void Cmd_CompleteCheck(char *check, match_t *match) //compare cumulative strings
else if (match->matchnum > 0) else if (match->matchnum > 0)
{ {
strcpy(match->result, check); strcpy(match->result, check);
match->desc = desc;
match->matchnum--; match->matchnum--;
} }
} }
else else
{ {
if (match->matchnum > 0) if (match->matchnum > 0)
{
strcpy(match->result, check);
match->matchnum--; match->matchnum--;
} strcpy(match->result, check);
else match->desc = desc;
strcpy(match->result, check);
} }
} }
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum) char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, char **descptr)
{ {
extern cvar_group_t *cvar_groups; extern cvar_group_t *cvar_groups;
cmd_function_t *cmd; cmd_function_t *cmd;
@ -1711,6 +1719,9 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
else else
len = Q_strlen(partial); len = Q_strlen(partial);
if (descptr)
*descptr = NULL;
if (!len) if (!len)
return NULL; return NULL;
@ -1719,6 +1730,7 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
match.allowcutdown = !fullonly?true:false; match.allowcutdown = !fullonly?true:false;
match.cutdown = false; match.cutdown = false;
match.desc = NULL;
if (matchnum) if (matchnum)
match.matchnum = matchnum; match.matchnum = matchnum;
else else
@ -1731,17 +1743,17 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
{ {
for (cmd=cmd_functions ; cmd ; cmd=cmd->next) for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncasecmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len)) if (!Q_strncasecmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
Cmd_CompleteCheck(cmd->name, &match); Cmd_CompleteCheck(cmd->name, &match, cmd->description);
for (a=cmd_alias ; a ; a=a->next) for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncasecmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len)) if (!Q_strncasecmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
Cmd_CompleteCheck(a->name, &match); Cmd_CompleteCheck(a->name, &match, "");
for (grp=cvar_groups ; grp ; grp=grp->next) for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next) for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
{ {
if (!Q_strncasecmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len)) if (!Q_strncasecmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
Cmd_CompleteCheck(cvar->name, &match); Cmd_CompleteCheck(cvar->name, &match, cvar->description);
if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len)) if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
Cmd_CompleteCheck(cvar->name2, &match); Cmd_CompleteCheck(cvar->name2, &match, cvar->description);
} }
} }
@ -1749,23 +1761,26 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens
{ {
for (cmd=cmd_functions ; cmd ; cmd=cmd->next) for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len)) if (!Q_strncmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
Cmd_CompleteCheck(cmd->name, &match); Cmd_CompleteCheck(cmd->name, &match, cmd->description);
for (a=cmd_alias ; a ; a=a->next) for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len)) if (!Q_strncmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
Cmd_CompleteCheck(a->name, &match); Cmd_CompleteCheck(a->name, &match, "");
for (grp=cvar_groups ; grp ; grp=grp->next) for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next) for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
{ {
if (!Q_strncmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len)) if (!Q_strncmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
Cmd_CompleteCheck(cvar->name, &match); Cmd_CompleteCheck(cvar->name, &match, cvar->description);
if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len)) if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
Cmd_CompleteCheck(cvar->name2, &match); Cmd_CompleteCheck(cvar->name2, &match, cvar->description);
} }
} }
if (match.matchnum>0) if (match.matchnum>0)
return NULL; return NULL;
if (!*match.result) if (!*match.result)
return NULL; return NULL;
if (descptr)
*descptr = match.desc;
return match.result; return match.result;
} }
@ -2735,6 +2750,7 @@ void Cmd_WriteConfig_f(void)
vfsfile_t *f; vfsfile_t *f;
char *filename; char *filename;
char fname[MAX_OSPATH]; char fname[MAX_OSPATH];
char sysname[MAX_OSPATH];
filename = Cmd_Argv(1); filename = Cmd_Argv(1);
if (!*filename) if (!*filename)
@ -2779,6 +2795,9 @@ void Cmd_WriteConfig_f(void)
VFS_CLOSE(f); VFS_CLOSE(f);
Cvar_Saved(); Cvar_Saved();
FS_NativePath(fname, FS_GAMEONLY, sysname, sizeof(sysname));
Con_Printf ("Wrote %s\n",sysname);
} }
void Cmd_Reset_f(void) void Cmd_Reset_f(void)

View file

@ -78,6 +78,7 @@ void Cmd_StuffCmds (void);
void Cmd_RemoveCommand (char *cmd_name); void Cmd_RemoveCommand (char *cmd_name);
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function); qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function);
qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *description);
// called by the init functions of other parts of the program to // called by the init functions of other parts of the program to
// register commands and functions to call for them. // register commands and functions to call for them.
// The cmd_name is referenced later, so it should not be in temp memory // The cmd_name is referenced later, so it should not be in temp memory
@ -89,7 +90,7 @@ qboolean Cmd_Exists (char *cmd_name);
char *Cmd_Describe (char *cmd_name); char *Cmd_Describe (char *cmd_name);
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum); char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, char **descptr);
qboolean Cmd_IsCommand (char *line); qboolean Cmd_IsCommand (char *line);
// attempts to match a partial command for automatic command line completion // attempts to match a partial command for automatic command line completion
// returns NULL if nothing fits // returns NULL if nothing fits
@ -114,7 +115,7 @@ void Alias_WipeStuffedAliaes(void);
void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions); void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions);
void Cmd_TokenizePunctation (char *text, char *punctuation); void Cmd_TokenizePunctation (char *text, char *punctuation);
void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize); char *Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize);
// Takes a null terminated string. Does not need to be /n terminated. // Takes a null terminated string. Does not need to be /n terminated.
// breaks the string up into arg tokens. // breaks the string up into arg tokens.

View file

@ -1534,8 +1534,9 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
#ifdef SKELETALMODELS #ifdef SKELETALMODELS
meshcache.usebonepose = NULL; meshcache.usebonepose = NULL;
if (inf->ofs_skel_xyz && 1)//!inf->ofs_skel_weight) if (inf->ofs_skel_xyz && !inf->ofs_skel_weight)
{ {
//if we have skeletal xyz info, but no skeletal weights, then its a partial model that cannot possibly be animated.
meshcache.usebonepose = NULL; meshcache.usebonepose = NULL;
mesh->xyz_array = (vecV_t*)((char*)inf + inf->ofs_skel_xyz); mesh->xyz_array = (vecV_t*)((char*)inf + inf->ofs_skel_xyz);
mesh->xyz2_array = NULL; mesh->xyz2_array = NULL;
@ -1548,8 +1549,10 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
mesh->xyz2_array = NULL; mesh->xyz2_array = NULL;
meshcache.usebonepose = Alias_GetBonePositions(inf, &e->framestate, meshcache.bonepose, MAX_BONES, true); meshcache.usebonepose = Alias_GetBonePositions(inf, &e->framestate, meshcache.bonepose, MAX_BONES, true);
if (e->fatness || !inf->ofs_skel_idx || !usebones) if (e->fatness || !inf->ofs_skel_idx || !usebones || inf->numswtransforms)
{ {
//software bone animation
//there are two ways to animate a skeleton, one is to transform
Alias_BuildSkeletalMesh(mesh, meshcache.usebonepose, inf); Alias_BuildSkeletalMesh(mesh, meshcache.usebonepose, inf);
#ifdef PEXT_FATNESS #ifdef PEXT_FATNESS
@ -1575,6 +1578,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
} }
else else
{ {
//hardware bone animation
mesh->xyz_array = (vecV_t*)((char*)inf + inf->ofs_skel_xyz); mesh->xyz_array = (vecV_t*)((char*)inf + inf->ofs_skel_xyz);
mesh->normals_array = (vec3_t*)((char*)inf + inf->ofs_skel_norm); mesh->normals_array = (vec3_t*)((char*)inf + inf->ofs_skel_norm);
mesh->snormals_array = (vec3_t*)((char*)inf + inf->ofs_skel_svect); mesh->snormals_array = (vec3_t*)((char*)inf + inf->ofs_skel_svect);
@ -5842,7 +5846,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(bones[i].name)); Q_strncpyz(bones[i].name, strings+ijoint[i].name, sizeof(bones[i].name));
bones[i].parent = ijoint[i].parent; bones[i].parent = ijoint[i].parent;
GenMatrixPosQuat3Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]); GenMatrixPosQuat3Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, mat);
if (ijoint[i].parent >= 0) if (ijoint[i].parent >= 0)
Matrix3x4_Multiply(mat, &basepose[ijoint[i].parent*12], &basepose[i*12]); Matrix3x4_Multiply(mat, &basepose[ijoint[i].parent*12], &basepose[i*12]);
@ -5932,7 +5936,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
for (i = 0; i < h->num_anims; i++) for (i = 0; i < h->num_anims; i++)
{ {
fgroup[i].isheirachical = true; fgroup[i].isheirachical = true;
fgroup[i].loop = LittleLong(anim[i].flags) & IQM_LOOP; fgroup[i].loop = !!(LittleLong(anim[i].flags) & IQM_LOOP);
Q_strncpyz(fgroup[i].name, strings+anim[i].name, sizeof(fgroup[i].name)); Q_strncpyz(fgroup[i].name, strings+anim[i].name, sizeof(fgroup[i].name));
fgroup[i].numposes = LittleLong(anim[i].num_frames); fgroup[i].numposes = LittleLong(anim[i].num_frames);
fgroup[i].poseofs = (char*)(opose+LittleLong(anim[i].first_frame)*12*h->num_poses) - (char*)&fgroup[i]; fgroup[i].poseofs = (char*)(opose+LittleLong(anim[i].first_frame)*12*h->num_poses) - (char*)&fgroup[i];

View file

@ -482,7 +482,7 @@ void (ODE_API *dJointSetUniversalParam)(dJointID, int parameter, dRea
//void (ODE_API *dJointSetPistonAnchorOffset)(dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz); //void (ODE_API *dJointSetPistonAnchorOffset)(dJointID j, dReal x, dReal y, dReal z, dReal dx, dReal dy, dReal dz);
//void (ODE_API *dJointSetPistonParam)(dJointID, int parameter, dReal value); //void (ODE_API *dJointSetPistonParam)(dJointID, int parameter, dReal value);
//void (ODE_API *dJointAddPistonForce)(dJointID joint, dReal force); //void (ODE_API *dJointAddPistonForce)(dJointID joint, dReal force);
//void (ODE_API *dJointSetFixed)(dJointID); void (ODE_API *dJointSetFixed)(dJointID);
//void (ODE_API *dJointSetFixedParam)(dJointID, int parameter, dReal value); //void (ODE_API *dJointSetFixedParam)(dJointID, int parameter, dReal value);
//void (ODE_API *dJointSetAMotorNumAxes)(dJointID, int num); //void (ODE_API *dJointSetAMotorNumAxes)(dJointID, int num);
//void (ODE_API *dJointSetAMotorAxis)(dJointID, int anum, int rel, dReal x, dReal y, dReal z); //void (ODE_API *dJointSetAMotorAxis)(dJointID, int anum, int rel, dReal x, dReal y, dReal z);
@ -947,7 +947,7 @@ static dllfunction_t odefuncs[] =
// {"dJointSetPistonAnchorOffset", (void **) &dJointSetPistonAnchorOffset}, // {"dJointSetPistonAnchorOffset", (void **) &dJointSetPistonAnchorOffset},
// {"dJointSetPistonParam", (void **) &dJointSetPistonParam}, // {"dJointSetPistonParam", (void **) &dJointSetPistonParam},
// {"dJointAddPistonForce", (void **) &dJointAddPistonForce}, // {"dJointAddPistonForce", (void **) &dJointAddPistonForce},
// {"dJointSetFixed", (void **) &dJointSetFixed}, {(void **) &dJointSetFixed, "dJointSetFixed"},
// {"dJointSetFixedParam", (void **) &dJointSetFixedParam}, // {"dJointSetFixedParam", (void **) &dJointSetFixedParam},
// {"dJointSetAMotorNumAxes", (void **) &dJointSetAMotorNumAxes}, // {"dJointSetAMotorNumAxes", (void **) &dJointSetAMotorNumAxes},
// {"dJointSetAMotorAxis", (void **) &dJointSetAMotorAxis}, // {"dJointSetAMotorAxis", (void **) &dJointSetAMotorAxis},
@ -1177,7 +1177,7 @@ void World_ODE_Init(void)
const char* dllname = const char* dllname =
{ {
# if defined(WIN64) # if defined(WIN64)
"libode1_64.dll" "libode1_64"
# elif defined(WIN32) # elif defined(WIN32)
"ode_double" "ode_double"
# elif defined(MACOSX) # elif defined(MACOSX)
@ -1664,7 +1664,6 @@ static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
break; break;
case 0: case 0:
default: default:
Sys_Error("what? but above the joint was valid...\n");
break; break;
} }
#undef SETPARAMS #undef SETPARAMS
@ -1771,11 +1770,169 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed
ed->ode.ode_numtriangles = numindexes/3; ed->ode.ode_numtriangles = numindexes/3;
return true; return true;
} }
/*
static void World_ODE_BodyFromSkel(world_t *world) qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, float *mat, wedict_t *ent)
{ {
dVector3 r[3];
if (!world->ode.ode_space)
return false;
bodyptr->ode_geom = dCreateBox(world->ode.ode_space, 3, 3, 3);
bodyptr->ode_body = dBodyCreate(world->ode.ode_world);
dGeomSetBody(bodyptr->ode_geom, bodyptr->ode_body);
dGeomSetData(bodyptr->ode_geom, (void*)ent);
r[0][0] = mat[0];
r[0][1] = mat[1];
r[0][2] = mat[2];
r[1][0] = mat[4];
r[1][1] = mat[5];
r[1][2] = mat[6];
r[2][0] = mat[8];
r[2][1] = mat[9];
r[2][2] = mat[10];
dBodySetPosition(bodyptr->ode_body, mat[3], mat[7], mat[11]);
dBodySetRotation(bodyptr->ode_body, r[0]);
dBodySetLinearVel(bodyptr->ode_body, 0, 0, 0);
dBodySetAngularVel(bodyptr->ode_body, 0, 0, 0);
return true;
} }
*/
void World_ODE_RagMatrixFromBody(world_t *world, odebody_t *bodyptr, float *mat)
{
const dReal *o = dBodyGetPosition(bodyptr->ode_body);
const dReal *r = dBodyGetRotation(bodyptr->ode_body);
mat[0] = r[0];
mat[1] = r[1];
mat[2] = r[2];
mat[3] = o[0];
mat[4] = r[4];
mat[5] = r[5];
mat[6] = r[6];
mat[7] = o[1];
mat[8] = r[8];
mat[9] = r[9];
mat[10] = r[10];
mat[11] = o[2];
}
void World_ODE_RagCreateJoint(world_t *world, odejoint_t *joint, odejointinfo_t *info, odebody_t *body1, odebody_t *body2, vec3_t aaa2[3])
{
switch(info->type)
{
case JOINTTYPE_POINT:
joint->ode_joint = dJointCreateBall(world->ode.ode_world, 0);
break;
case JOINTTYPE_HINGE:
joint->ode_joint = dJointCreateHinge(world->ode.ode_world, 0);
break;
case JOINTTYPE_SLIDER:
joint->ode_joint = dJointCreateSlider(world->ode.ode_world, 0);
break;
case JOINTTYPE_UNIVERSAL:
joint->ode_joint = dJointCreateUniversal(world->ode.ode_world, 0);
break;
case JOINTTYPE_HINGE2:
joint->ode_joint = dJointCreateHinge2(world->ode.ode_world, 0);
break;
case JOINTTYPE_FIXED:
joint->ode_joint = dJointCreateFixed(world->ode.ode_world, 0);
break;
default:
joint->ode_joint = NULL;
break;
}
if (joint->ode_joint)
{
//Con_Printf("made new joint %i\n", (int) (ed - prog->edicts));
// dJointSetData(joint->ode_joint, NULL);
dJointAttach(joint->ode_joint, body1?body1->ode_body:NULL, body2?body2->ode_body:NULL);
switch(info->type)
{
case JOINTTYPE_POINT:
dJointSetBallAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]);
break;
case JOINTTYPE_HINGE:
dJointSetHingeAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]);
dJointSetHingeAxis(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]);
dJointSetHingeParam(joint->ode_joint, dParamFMax, info->FMax);
dJointSetHingeParam(joint->ode_joint, dParamHiStop, info->HiStop);
dJointSetHingeParam(joint->ode_joint, dParamLoStop, info->LoStop);
dJointSetHingeParam(joint->ode_joint, dParamStopCFM, info->CFM);
dJointSetHingeParam(joint->ode_joint, dParamStopERP, info->ERP);
dJointSetHingeParam(joint->ode_joint, dParamVel, info->Vel);
break;
case JOINTTYPE_SLIDER:
dJointSetSliderAxis(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]);
dJointSetSliderParam(joint->ode_joint, dParamFMax, info->FMax);
dJointSetSliderParam(joint->ode_joint, dParamHiStop, info->HiStop);
dJointSetSliderParam(joint->ode_joint, dParamLoStop, info->LoStop);
dJointSetSliderParam(joint->ode_joint, dParamStopCFM, info->CFM);
dJointSetSliderParam(joint->ode_joint, dParamStopERP, info->ERP);
dJointSetSliderParam(joint->ode_joint, dParamVel, info->Vel);
break;
case JOINTTYPE_UNIVERSAL:
dJointSetUniversalAnchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]);
dJointSetUniversalAxis1(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]);
dJointSetUniversalAxis2(joint->ode_joint, aaa2[2][0], aaa2[2][1], aaa2[2][2]);
dJointSetUniversalParam(joint->ode_joint, dParamFMax, info->FMax);
dJointSetUniversalParam(joint->ode_joint, dParamHiStop, info->HiStop);
dJointSetUniversalParam(joint->ode_joint, dParamLoStop, info->LoStop);
dJointSetUniversalParam(joint->ode_joint, dParamStopCFM, info->CFM);
dJointSetUniversalParam(joint->ode_joint, dParamStopERP, info->ERP);
dJointSetUniversalParam(joint->ode_joint, dParamVel, info->Vel);
dJointSetUniversalParam(joint->ode_joint, dParamFMax2, info->FMax2);
dJointSetUniversalParam(joint->ode_joint, dParamHiStop2, info->HiStop2);
dJointSetUniversalParam(joint->ode_joint, dParamLoStop2, info->LoStop2);
dJointSetUniversalParam(joint->ode_joint, dParamStopCFM2, info->CFM2);
dJointSetUniversalParam(joint->ode_joint, dParamStopERP2, info->ERP2);
dJointSetUniversalParam(joint->ode_joint, dParamVel2, info->Vel2);
break;
case JOINTTYPE_HINGE2:
dJointSetHinge2Anchor(joint->ode_joint, aaa2[0][0], aaa2[0][1], aaa2[0][2]);
dJointSetHinge2Axis1(joint->ode_joint, aaa2[1][0], aaa2[1][1], aaa2[1][2]);
dJointSetHinge2Axis2(joint->ode_joint, aaa2[2][0], aaa2[2][1], aaa2[2][2]);
dJointSetHinge2Param(joint->ode_joint, dParamFMax, info->FMax);
dJointSetHinge2Param(joint->ode_joint, dParamHiStop, info->HiStop);
dJointSetHinge2Param(joint->ode_joint, dParamLoStop, info->LoStop);
dJointSetHinge2Param(joint->ode_joint, dParamStopCFM, info->CFM);
dJointSetHinge2Param(joint->ode_joint, dParamStopERP, info->ERP);
dJointSetHinge2Param(joint->ode_joint, dParamVel, info->Vel);
dJointSetHinge2Param(joint->ode_joint, dParamFMax2, info->FMax2);
dJointSetHinge2Param(joint->ode_joint, dParamHiStop2, info->HiStop2);
dJointSetHinge2Param(joint->ode_joint, dParamLoStop2, info->LoStop2);
dJointSetHinge2Param(joint->ode_joint, dParamStopCFM2, info->CFM2);
dJointSetHinge2Param(joint->ode_joint, dParamStopERP2, info->ERP2);
dJointSetHinge2Param(joint->ode_joint, dParamVel2, info->Vel2);
break;
case JOINTTYPE_FIXED:
dJointSetFixed(joint->ode_joint);
break;
}
}
}
void World_ODE_RagDestroyBody(world_t *world, odebody_t *bodyptr)
{
if (bodyptr->ode_geom)
dGeomDestroy(bodyptr->ode_geom);
bodyptr->ode_geom = NULL;
if (bodyptr->ode_body)
dBodyDestroy(bodyptr->ode_body);
bodyptr->ode_body = NULL;
}
void World_ODE_RagDestroyJoint(world_t *world, odejoint_t *joint)
{
if (joint->ode_joint)
dJointDestroy(joint->ode_joint);
joint->ode_joint = NULL;
}
static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed) static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{ {
dBodyID body = (dBodyID)ed->ode.ode_body; dBodyID body = (dBodyID)ed->ode.ode_body;
@ -1995,21 +2152,13 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
} }
// get current data from entity // get current data from entity
VectorClear(origin);
VectorClear(velocity);
//VectorClear(forward);
//VectorClear(left);
//VectorClear(up);
//VectorClear(spinvelocity);
VectorClear(angles);
VectorClear(avelocity);
gravity = true; gravity = true;
VectorCopy(ed->v->origin, origin); VectorCopy(ed->v->origin, origin);
VectorCopy(ed->v->velocity, velocity); VectorCopy(ed->v->velocity, velocity);
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_forward);if (val) VectorCopy(val->vector, forward); //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_forward);if (val) VectorCopy(val->vector, forward); else VectorClear(forward);
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_left);if (val) VectorCopy(val->vector, left); //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_left);if (val) VectorCopy(val->vector, left); else VectorClear(left);
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_up);if (val) VectorCopy(val->vector, up); //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_up);if (val) VectorCopy(val->vector, up); else VectorClear(up);
//val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.spinvelocity);if (val) VectorCopy(val->vector, spinvelocity); //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.spinvelocity);if (val) VectorCopy(val->vector, spinvelocity); else VectorClear(spinvelocity);
VectorCopy(ed->v->angles, angles); VectorCopy(ed->v->angles, angles);
VectorCopy(ed->v->avelocity, avelocity); VectorCopy(ed->v->avelocity, avelocity);
if (ed == world->edicts || (ed->xv->gravity && ed->xv->gravity <= 0.01)) if (ed == world->edicts || (ed->xv->gravity && ed->xv->gravity <= 0.01))
@ -2231,11 +2380,11 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
return; return;
ed1 = (wedict_t *) dGeomGetData(o1); ed1 = (wedict_t *) dGeomGetData(o1);
if(ed1 && ed1->isfree) if(!ed1 || ed1->isfree)
ed1 = NULL; ed1 = world->edicts;
ed2 = (wedict_t *) dGeomGetData(o2); ed2 = (wedict_t *) dGeomGetData(o2);
if(ed2 && ed2->isfree) if(!ed2 || ed2->isfree)
ed2 = NULL; ed2 = world->edicts;
// generate contact points between the two non-space geoms // generate contact points between the two non-space geoms
numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0])); numcontacts = dCollide(o1, o2, MAX_CONTACTS, &(contact[0].geom), sizeof(contact[0]));
@ -2317,7 +2466,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
void World_ODE_Frame(world_t *world, double frametime, double gravity) void World_ODE_Frame(world_t *world, double frametime, double gravity)
{ {
if (world->ode.ode && (world->ode.hasodeents))// || world->ode.hasragdoll)) if (world->ode.ode && (world->ode.hasodeents || world->ode.hasextraobjs))
{ {
int i; int i;
wedict_t *ed; wedict_t *ed;

View file

@ -93,6 +93,7 @@ cvar_t gameversion = CVARFD("gameversion","", CVAR_SERVERINFO, "gamecode version
cvar_t gameversion_min = CVARD("gameversion_min","", "gamecode version for server browsers"); cvar_t gameversion_min = CVARD("gameversion_min","", "gamecode version for server browsers");
cvar_t gameversion_max = CVARD("gameversion_max","", "gamecode version for server browsers"); cvar_t gameversion_max = CVARD("gameversion_max","", "gamecode version for server browsers");
cvar_t fs_gamename = CVARFD("fs_gamename", "", CVAR_NOSET, "The filesystem is trying to run this game"); cvar_t fs_gamename = CVARFD("fs_gamename", "", CVAR_NOSET, "The filesystem is trying to run this game");
cvar_t fs_gamedownload = CVARFD("fs_gamedownload", "", CVAR_NOSET, "The place that the game can be downloaded from.");
cvar_t com_protocolname = CVARD("com_gamename", "", "The game name used for dpmaster queries"); cvar_t com_protocolname = CVARD("com_gamename", "", "The game name used for dpmaster queries");
cvar_t com_modname = CVARD("com_modname", "", "dpmaster information"); cvar_t com_modname = CVARD("com_modname", "", "dpmaster information");
cvar_t com_parseutf8 = CVARD("com_parseutf8", "0", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed. cvar_t com_parseutf8 = CVARD("com_parseutf8", "0", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
@ -188,7 +189,7 @@ void QDECL Q_strncpyz(char *d, const char *s, int n)
//windows/linux have inconsistant snprintf //windows/linux have inconsistant snprintf
//this is an attempt to get them consistant and safe //this is an attempt to get them consistant and safe
//size is the total size of the buffer //size is the total size of the buffer
void VARGS Q_vsnprintfz (char *dest, size_t size, char *fmt, va_list argptr) void VARGS Q_vsnprintfz (char *dest, size_t size, const char *fmt, va_list argptr)
{ {
vsnprintf (dest, size, fmt, argptr); vsnprintf (dest, size, fmt, argptr);
dest[size-1] = 0; dest[size-1] = 0;
@ -197,7 +198,7 @@ void VARGS Q_vsnprintfz (char *dest, size_t size, char *fmt, va_list argptr)
//windows/linux have inconsistant snprintf //windows/linux have inconsistant snprintf
//this is an attempt to get them consistant and safe //this is an attempt to get them consistant and safe
//size is the total size of the buffer //size is the total size of the buffer
void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) void VARGS Q_snprintfz (char *dest, size_t size, const char *fmt, ...)
{ {
va_list argptr; va_list argptr;
@ -405,7 +406,7 @@ char *Q_strlwr(char *s)
int wildcmp(const char *wild, const char *string) int wildcmp(const char *wild, const char *string)
{ {
const char *cp=NULL, *mp=NULL; const char *cp=NULL, *mp=NULL;
/*
while ((*string) && (*wild != '*')) while ((*string) && (*wild != '*'))
{ {
if ((*wild != *string) && (*wild != '?')) if ((*wild != *string) && (*wild != '?'))
@ -415,30 +416,29 @@ int wildcmp(const char *wild, const char *string)
wild++; wild++;
string++; string++;
} }
*/
while (*string) while (*string)
{ {
if (*wild == '*') if (*wild == '*')
{ {
if (!*++wild) //a * at the end of the wild string matches anything the checked string has if (wild[1] == *string || *string == '/' || *string == '\\')
{ {
string = strchr(string, '/'); //* terminates if we get a match on the char following it, or if its a \ or / char
if (string && string[1]) /*don't match it if there's a / with something after it*/ wild++;
return 0; continue;
return 1;
} }
mp = wild; string++;
cp = string+1;
} }
else if ((*wild == *string) || (*wild == '?')) else if ((*wild == *string) || (*wild == '?'))
{ {
//this char matches
wild++; wild++;
string++; string++;
} }
else else
{ {
wild = mp; //failure
string = cp++; return false;
} }
} }
@ -1629,7 +1629,7 @@ char *COM_SkipPath (const char *pathname)
last = pathname; last = pathname;
while (*pathname) while (*pathname)
{ {
if (*pathname=='/') if (*pathname=='/' || *pathname == '\\')
last = pathname+1; last = pathname+1;
pathname++; pathname++;
} }
@ -2455,77 +2455,25 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
messedup: messedup:
if (!--outsize) if (!--outsize)
break; break;
uc = (unsigned char)(*str++);
if (utf8) if (utf8)
*out++ = (unsigned char)(*str++) | ext; *out++ = uc | ext;
else else
{ {
if (strchr("\n\r\t ", *str)) if (uc == '\n' || uc == '\r' || uc == '\t' || uc == ' ')
*out++ = (unsigned char)(*str++) | (ext&~CON_HIGHCHARSMASK); *out++ = uc | (ext&~CON_HIGHCHARSMASK);
else if (*str >= 32 && *str < 127 && !(ext&CON_HIGHCHARSMASK)) else if (uc >= 32 && uc < 127 && !(ext&CON_HIGHCHARSMASK))
*out++ = (unsigned char)(*str++) | ext; *out++ = uc | ext;
else if (uc >= 0x80+32 && uc < 0x80+127)
*out++ = (uc&127) | ext ^ CON_2NDCHARSETTEXT;
else else
*out++ = (unsigned char)(*str++) | ext | 0xe000; *out++ = uc | ext | 0xe000;
} }
} }
*out = 0; *out = 0;
return out; return out;
} }
int COM_FunStringLength(unsigned char *str)
{
//FIXME:
int len = 0;
while(*str)
{
//fixme: utf8
if (*str == '^')
{
str++;
if (*str >= '0' && *str <= '9')
str++; //invisible
else if (*str == '&') // extended code
{
if (isextendedcode(str[1]) && isextendedcode(str[2]))
{
str++;// foreground char
str++; // background char
str++;
continue;
}
// else invalid code
goto messedup;
}
else if (*str == 'a' || *str == 'b' || *str == 'h' || *str == 's' || *str == 'r')
str++; //invisible
else if (*str == '^')
{
len++; //double-code single-output
str++;
}
else
{
len++; //not recognised
len++;
str++;
}
continue;
}
if (*str == '&' && str[1] == 'c' && ishexcode(str[2]) && ishexcode(str[3]) && ishexcode(str[4]))
{
//ezquake colour codes
str += 5;
continue;
}
messedup:
len++;
str++;
}
return len;
}
//============================================================================ //============================================================================
#define TOKENSIZE sizeof(com_token) #define TOKENSIZE sizeof(com_token)
@ -3472,6 +3420,12 @@ void COM_Version_f (void)
} }
#endif #endif
#ifdef MULTITHREAD
Con_Printf("multithreading: enabled\n");
#else
Con_Printf("multithreading: disabled\n");
#endif
//print out which libraries are disabled //print out which libraries are disabled
#ifndef AVAIL_ZLIB #ifndef AVAIL_ZLIB
Con_Printf("zlib disabled\n"); Con_Printf("zlib disabled\n");
@ -3493,6 +3447,37 @@ void COM_Version_f (void)
#else #else
Con_Printf("libjpeg: %i (%d series)\n", JPEG_LIB_VERSION, ( JPEG_LIB_VERSION / 10 ) ); Con_Printf("libjpeg: %i (%d series)\n", JPEG_LIB_VERSION, ( JPEG_LIB_VERSION / 10 ) );
#endif #endif
#ifdef SPEEX_STATIC
Con_Printf("speex: static\n");
#elif defined(VOICECHAT)
Con_Printf("speex: dynamic\n");
#else
Con_Printf("speex: disabled\n");
#endif
#ifdef ODE_STATIC
Con_Printf("ODE: static\n");
#elif defined(USEODE)
Con_Printf("ODE: dynamic\n");
#else
Con_Printf("ODE: disabled\n");
#endif
#ifndef AVAIL_OGGVORBIS
Con_Printf("Ogg Vorbis: disabled\n");
#elif defined(LIBVORBISFILE_STATIC)
Con_Printf("Ogg Vorbis: static\n");
#else
Con_Printf("Ogg Vorbis: dynamic\n");
#endif
#ifdef USE_MYSQL
Con_Printf("mySQL: dynamic\n");
#else
Con_Printf("mySQL: disabled\n");
#endif
#ifdef USE_SQLITE
Con_Printf("sqlite: dynamic\n");
#else
Con_Printf("sqlite: disabled\n");
#endif
#ifndef AVAIL_OGGVORBIS #ifndef AVAIL_OGGVORBIS
Con_Printf("libvorbis disabled\n"); Con_Printf("libvorbis disabled\n");
#endif #endif
@ -3734,7 +3719,7 @@ void COM_Effectinfo_Reload(void)
if (!f) if (!f)
return; return;
buf = f; buf = f;
while (*f) while (f && *f)
{ {
f = COM_ParseToken(f, NULL); f = COM_ParseToken(f, NULL);
if (strcmp(com_token, "\n")) if (strcmp(com_token, "\n"))
@ -3749,7 +3734,7 @@ void COM_Effectinfo_Reload(void)
do do
{ {
f = COM_ParseToken(f, NULL); f = COM_ParseToken(f, NULL);
} while(*f && strcmp(com_token, "\n")); } while(f && *f && strcmp(com_token, "\n"));
} }
} }
FS_FreeFile(buf); FS_FreeFile(buf);

View file

@ -211,8 +211,8 @@ int wildcmp(const char *wild, const char *string); //1 if match
#define Q_strcmp(s1, s2) strcmp((s1), (s2)) #define Q_strcmp(s1, s2) strcmp((s1), (s2))
#define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) #define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) LIKEPRINTF(3); void VARGS Q_snprintfz (char *dest, size_t size, const char *fmt, ...) LIKEPRINTF(3);
void VARGS Q_vsnprintfz (char *dest, size_t size, char *fmt, va_list args); void VARGS Q_vsnprintfz (char *dest, size_t size, const char *fmt, va_list args);
int VARGS Com_sprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); int VARGS Com_sprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
#define Q_strncpyS(d, s, n) do{const char *____in=(s);char *____out=(d);int ____i; for (____i=0;*(____in); ____i++){if (____i == (n))break;*____out++ = *____in++;}if (____i < (n))*____out='\0';}while(0) //only use this when it should be used. If undiciided, use N #define Q_strncpyS(d, s, n) do{const char *____in=(s);char *____out=(d);int ____i; for (____i=0;*(____in); ____i++){if (____i == (n))break;*____out++ = *____in++;}if (____i < (n))*____out='\0';}while(0) //only use this when it should be used. If undiciided, use N
@ -277,7 +277,6 @@ void COM_ParsePlusSets (void);
typedef unsigned int conchar_t; typedef unsigned int conchar_t;
char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags); char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags);
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
int COM_FunStringLength(unsigned char *str);
char *COM_SkipPath (const char *pathname); char *COM_SkipPath (const char *pathname);
void COM_StripExtension (const char *in, char *out, int outlen); void COM_StripExtension (const char *in, char *out, int outlen);
@ -391,7 +390,6 @@ void FS_ReloadPackFiles(void);
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum); char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
FTE_DEPRECATED int COM_filelength (FILE *f);
qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize); qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize);
qbyte *COM_LoadTempFile (const char *path); qbyte *COM_LoadTempFile (const char *path);
qbyte *COM_LoadTempMoreFile (const char *path); //allocates a little bit more without freeing old temp qbyte *COM_LoadTempMoreFile (const char *path); //allocates a little bit more without freeing old temp

View file

@ -117,7 +117,6 @@ typedef struct console_s
int x; // offset in current line for next print int x; // offset in current line for next print
int cr; int cr;
conline_t *display; // bottom of console displays this line conline_t *display; // bottom of console displays this line
int subline;
int vislines; // pixel lines int vislines; // pixel lines
int linesprinted; // for notify times int linesprinted; // for notify times
qboolean unseentext; qboolean unseentext;
@ -132,6 +131,15 @@ extern console_t con_main;
extern console_t *con_current; // point to either con_main or con_chat extern console_t *con_current; // point to either con_main or con_chat
extern console_t *con_chat; extern console_t *con_chat;
//shared between console and keys.
//really the console input should be in console.c instead of keys.c I suppose.
#define MAXCMDLINE 256
#define CON_EDIT_LINES_MASK ((1<<6)-1)
extern unsigned char key_lines[CON_EDIT_LINES_MASK+1][MAXCMDLINE];
extern int edit_line;
extern int key_linepos;
extern int history_line;
extern int scr_chatmode; extern int scr_chatmode;
//extern int con_totallines; //extern int con_totallines;
@ -144,6 +152,7 @@ void Con_CheckResize (void);
void Con_ForceActiveNow(void); void Con_ForceActiveNow(void);
void Con_Init (void); void Con_Init (void);
void Con_Shutdown (void); void Con_Shutdown (void);
void Con_History_Load(void);
void Con_DrawConsole (int lines, qboolean noback); void Con_DrawConsole (int lines, qboolean noback);
char *Con_CopyConsole(qboolean nomarkup); char *Con_CopyConsole(qboolean nomarkup);
void Con_Print (char *txt); void Con_Print (char *txt);
@ -151,6 +160,7 @@ void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
void VARGS Con_TPrintf (translation_t text, ...); void VARGS Con_TPrintf (translation_t text, ...);
void VARGS Con_DPrintf (char *fmt, ...) LIKEPRINTF(1); void VARGS Con_DPrintf (char *fmt, ...) LIKEPRINTF(1);
void VARGS Con_SafePrintf (char *fmt, ...) LIKEPRINTF(1); void VARGS Con_SafePrintf (char *fmt, ...) LIKEPRINTF(1);
void Con_Footerf(qboolean append, char *fmt, ...) LIKEPRINTF(2);
void Con_Clear_f (void); void Con_Clear_f (void);
void Con_DrawNotify (void); void Con_DrawNotify (void);
void Con_ClearNotify (void); void Con_ClearNotify (void);

View file

@ -176,40 +176,6 @@ searchpath_t *com_searchpaths;
searchpath_t *com_purepaths; searchpath_t *com_purepaths;
searchpath_t *com_base_searchpaths; // without gamedirs searchpath_t *com_base_searchpaths; // without gamedirs
/*
================
COM_filelength
================
*/
int COM_filelength (FILE *f)
{
int pos;
int end;
pos = ftell (f);
fseek (f, 0, SEEK_END);
end = ftell (f);
fseek (f, pos, SEEK_SET);
return end;
}
/*
static int COM_FileOpenRead (char *path, FILE **hndl)
{
FILE *f;
f = fopen(path, "rb");
if (!f)
{
*hndl = NULL;
return -1;
}
*hndl = f;
return COM_filelength(f);
}
*/
int COM_FileSize(const char *path) int COM_FileSize(const char *path)
{ {
int len; int len;
@ -1810,8 +1776,8 @@ void COM_Gamedir (const char *dir)
/*stuff that makes dp-only mods work a bit better*/ /*stuff that makes dp-only mods work a bit better*/
#define DPCOMPAT "set _cl_playermodel \"\"\n set dpcompat_set 1\n set dpcompat_trailparticles 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n" #define DPCOMPAT "set _cl_playermodel \"\"\n set dpcompat_set 1\n set dpcompat_trailparticles 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
/*nexuiz/xonotic has a few quirks...*/ /*nexuiz/xonotic has a few quirks/annoyances...*/
#define NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\n" #define NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\npr_enable_uriget 0\n"
/*some modern non-compat settings*/ /*some modern non-compat settings*/
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n" #define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n"
/*set some stuff so our regular qw client appears more like hexen2*/ /*set some stuff so our regular qw client appears more like hexen2*/
@ -1830,6 +1796,7 @@ typedef struct {
const char *dir[4]; const char *dir[4];
const char *poshname; //Full name for the game. const char *poshname; //Full name for the game.
const char *downloadaddr;
} gamemode_info_t; } gamemode_info_t;
const gamemode_info_t gamemode_info[] = { const gamemode_info_t gamemode_info[] = {
//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get. //note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get.
@ -1837,12 +1804,12 @@ const gamemode_info_t gamemode_info[] = {
//rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake //rogue/hipnotic have no special files - the detection conflicts and stops us from running regular quake
//cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name
{"-quake", "q1", "DarkPlaces-Quake", {"id1/pak0.pak" {"-quake", "q1", "DarkPlaces-Quake", {"id1/pak0.pak",
"id1/quake.rc"}, NULL, {"id1", "qw", "fte"}, "Quake"}, "id1/quake.rc"}, NULL, {"id1", "qw", "fte"}, "Quake"/*, "id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
{"-hipnotic", "hipnotic", "Darkplaces-Hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"}, {"-hipnotic", "hipnotic", "Darkplaces-Hipnotic", {NULL}, NULL, {"id1", "qw", "hipnotic", "fte"}, "Quake: Scourge of Armagon"},
{"-rogue", "rogue", "Darkplaces-Rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"}, {"-rogue", "rogue", "Darkplaces-Rogue", {NULL}, NULL, {"id1", "qw", "rogue", "fte"}, "Quake: Dissolution of Eternity"},
{"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"}, {"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "ftedata"}, "Nexuiz"},
{"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, NEXCFG, {"data", "ftedata"}, "Xonotic"}, {"-xonotic", "xonotic", "Xonotic", {"xonotic.exe"}, NEXCFG, {"data", "ftedata"}, "Xonotic", "data/xonotic-20120308-data.pk3|http://localhost/xonotic-0.6.0.zip"},
{"-spark", "spark", "Spark", {"base/src/progs.src", {"-spark", "spark", "Spark", {"base/src/progs.src",
"base/qwprogs.dat", "base/qwprogs.dat",
"base/pak0.pak"}, DMFCFG, {"base", }, "Spark"}, "base/pak0.pak"}, DMFCFG, {"base", }, "Spark"},
@ -2215,7 +2182,8 @@ static qboolean Sys_SteamHasFile(char *basepath, int basepathlen, char *steamdir
FILE *f; FILE *f;
DWORD resultlen; DWORD resultlen;
HKEY key = NULL; HKEY key = NULL;
if (!FAILED(RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key)))
if (RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Valve\\Steam", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "SteamPath", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "SteamPath", NULL, NULL, basepath, &resultlen);
@ -2239,7 +2207,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
#endif #endif
//first, try and find it in our game paths location //first, try and find it in our game paths location
if (!FAILED(RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
if (!RegQueryValueEx(key, gamename, NULL, NULL, basepath, &resultlen)) if (!RegQueryValueEx(key, gamename, NULL, NULL, basepath, &resultlen))
@ -2284,7 +2252,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
HKEY key = NULL; HKEY key = NULL;
//look for HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Quake2_exe\Path //look for HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Quake2_exe\Path
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Quake2_exe", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Quake2_exe", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "Path", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "Path", NULL, NULL, basepath, &resultlen);
@ -2306,7 +2274,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
DWORD resultlen; DWORD resultlen;
HKEY key = NULL; HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\Activision\Wolfenstein - Enemy Territory //reads HKEY_LOCAL_MACHINE\SOFTWARE\Activision\Wolfenstein - Enemy Territory
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Activision\\Wolfenstein - Enemy Territory", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Activision\\Wolfenstein - Enemy Territory", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
@ -2328,7 +2296,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
HKEY key = NULL; HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Quake III Arena\InstallPath //reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Quake III Arena\InstallPath
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Quake III Arena", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Quake III Arena", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
@ -2350,7 +2318,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
DWORD resultlen; DWORD resultlen;
HKEY key = NULL; HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\World Of Padman\Path //reads HKEY_LOCAL_MACHINE\SOFTWARE\World Of Padman\Path
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\World Of Padman", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\World Of Padman", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "Path", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "Path", NULL, NULL, basepath, &resultlen);
@ -2365,7 +2333,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
DWORD resultlen; DWORD resultlen;
HKEY key = NULL; HKEY key = NULL;
//reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Doom 3\InstallPath //reads HKEY_LOCAL_MACHINE\SOFTWARE\id\Doom 3\InstallPath
if (!FAILED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Doom 3", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key))) if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\id\\Doom 3", 0, STANDARD_RIGHTS_READ|KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
{ {
resultlen = basepathlen; resultlen = basepathlen;
RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen); RegQueryValueEx(key, "InstallPath", NULL, NULL, basepath, &resultlen);
@ -2416,13 +2384,13 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
Q_strncpyz(basepath, resultpath, basepathlen-1); Q_strncpyz(basepath, resultpath, basepathlen-1);
//and save it into the windows registry //and save it into the windows registry
if (!FAILED(RegCreateKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths", if (RegCreateKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\" FULLENGINENAME "\\GamePaths",
0, NULL, 0, NULL,
REG_OPTION_NON_VOLATILE, REG_OPTION_NON_VOLATILE,
KEY_WRITE, KEY_WRITE,
NULL, NULL,
&key, &key,
NULL))) NULL) == ERROR_SUCCESS)
{ {
RegSetValueEx(key, gamename, 0, REG_SZ, basepath, strlen(basepath)); RegSetValueEx(key, gamename, 0, REG_SZ, basepath, strlen(basepath));
@ -2439,6 +2407,9 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
#else #else
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen) qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen)
{ {
#ifdef __linux__
// /usr/share/quake
#endif
return false; return false;
} }
#endif #endif
@ -2518,6 +2489,7 @@ void FS_StartupWithGame(int gamenum)
Cvar_Set(&com_protocolname, gamemode_info[gamenum].protocolname); Cvar_Set(&com_protocolname, gamemode_info[gamenum].protocolname);
Cvar_ForceSet(&fs_gamename, gamemode_info[gamenum].poshname); Cvar_ForceSet(&fs_gamename, gamemode_info[gamenum].poshname);
Cvar_ForceSet(&fs_gamedownload, gamemode_info[gamenum].downloadaddr?gamemode_info[gamenum].downloadaddr:"");
i = COM_CheckParm ("-basepack"); i = COM_CheckParm ("-basepack");
while (i && i < com_argc-1) while (i && i < com_argc-1)
@ -2596,7 +2568,7 @@ void FS_StartupWithGame(int gamenum)
COM_Gamedir(com_argv[i+1]); COM_Gamedir(com_argv[i+1]);
} }
#if 1//def ANDROID #ifdef ANDROID
{ {
vfsfile_t *f; vfsfile_t *f;
//write a .nomedia file to avoid people from getting random explosion sounds etc intersperced with their music //write a .nomedia file to avoid people from getting random explosion sounds etc intersperced with their music
@ -2679,6 +2651,7 @@ void COM_InitFilesystem (void)
Cvar_Register(&fs_gamename, "FS"); Cvar_Register(&fs_gamename, "FS");
Cvar_Register(&fs_gamedownload, "FS");
Cvar_Register(&com_protocolname, "Server Info"); Cvar_Register(&com_protocolname, "Server Info");
Cvar_Register(&com_modname, "Server Info"); Cvar_Register(&com_modname, "Server Info");
//identify the game from a telling file //identify the game from a telling file
@ -2697,6 +2670,29 @@ void COM_InitFilesystem (void)
} }
} }
} }
if (gamenum == -1 && host_parms.binarydir && *host_parms.binarydir && autobasedir)
{
for (i = 0; gamemode_info[i].argname && gamenum==-1; i++)
{
//look in the directory the exe exists in if we failed to find a valid installation in the working dir
for (j = 0; j < 4; j++)
{
if (gamemode_info[i].auniquefile[j])
{
f = VFSOS_Open(va("%s%s", host_parms.binarydir, gamemode_info[i].auniquefile[j]), "rb");
if (f)
{
//apply this as the new -basedir
Q_strncpyz(com_quakedir, host_parms.binarydir, sizeof(com_quakedir));
gamenum = i;
//we found it, its all okay
VFS_CLOSE(f);
break;
}
}
}
}
}
//use the game based on an exe name over the filesystem one (could easily have multiple fs path matches). //use the game based on an exe name over the filesystem one (could easily have multiple fs path matches).
for (i = 0; gamemode_info[i].argname; i++) for (i = 0; gamemode_info[i].argname; i++)
{ {
@ -2711,37 +2707,59 @@ void COM_InitFilesystem (void)
{ {
gamenum = i; gamenum = i;
for (j = 0; j < 4; j++) if (autobasedir)
{ {
if (gamemode_info[gamenum].auniquefile[j]) //try the working directory first
for (j = 0; j < 4; j++)
{ {
f = VFSOS_Open(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb"); if (gamemode_info[gamenum].auniquefile[j])
if (f)
{ {
//we found it, its all okay f = VFSOS_Open(va("%s%s", com_quakedir, gamemode_info[i].auniquefile[j]), "rb");
VFS_CLOSE(f); if (f)
break;
}
if (autobasedir)
{
#ifdef _WIN32
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
{ {
if (com_quakedir[strlen(com_quakedir)-1] == '\\') //we found it, its all okay
com_quakedir[strlen(com_quakedir)-1] = '/'; VFS_CLOSE(f);
else if (com_quakedir[strlen(com_quakedir)-1] != '/') break;
}
}
}
//try looking where the exe is
if (j == 4 && host_parms.binarydir && *host_parms.binarydir)
{
for (j = 0; j < 4; j++)
{
if (gamemode_info[gamenum].auniquefile[j])
{
f = VFSOS_Open(va("%s%s", host_parms.binarydir, gamemode_info[i].auniquefile[j]), "rb");
if (f)
{ {
com_quakedir[strlen(com_quakedir)+1] = '\0'; Q_strncpyz(com_quakedir, host_parms.binarydir, sizeof(com_quakedir));
com_quakedir[strlen(com_quakedir)] = '/'; //we found it, its all okay
VFS_CLOSE(f);
break;
} }
} }
else }
#endif }
//scan known locations/windows registry/etc to see if we can find an existing install
if (j == 4)
{
char realpath[MAX_OSPATH-1];
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, realpath, sizeof(realpath)))
{
Q_strncpyz(com_quakedir, realpath, sizeof(com_quakedir));
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
com_quakedir[strlen(com_quakedir)-1] = '/';
else if (com_quakedir[strlen(com_quakedir)-1] != '/')
{ {
Con_Printf("Couldn't find the gamedata for this game mode!\n"); com_quakedir[strlen(com_quakedir)+1] = '\0';
com_quakedir[strlen(com_quakedir)] = '/';
} }
} }
break; else
{
Con_Printf("Couldn't find the gamedata for this game mode!\n");
}
} }
} }
break; break;
@ -2760,8 +2778,10 @@ void COM_InitFilesystem (void)
if (autobasedir) if (autobasedir)
{ {
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir))) char realpath[MAX_OSPATH-1];
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, realpath, sizeof(realpath)))
{ {
Q_strncpyz(com_quakedir, realpath, sizeof(com_quakedir));
if (com_quakedir[strlen(com_quakedir)-1] == '\\') if (com_quakedir[strlen(com_quakedir)-1] == '\\')
com_quakedir[strlen(com_quakedir)-1] = '/'; com_quakedir[strlen(com_quakedir)-1] = '/';
else if (com_quakedir[strlen(com_quakedir)-1] != '/') else if (com_quakedir[strlen(com_quakedir)-1] != '/')

View file

@ -121,7 +121,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
vfsfile_t *Sys_OpenAsset(const char *fname); vfsfile_t *Sys_OpenAsset(const char *fname);
#endif #endif
static vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush) vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush)
{ {
FILE *f; FILE *f;
vfsstdiofile_t *file; vfsstdiofile_t *file;

View file

@ -524,6 +524,8 @@ int VFSZIP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
VFS_SEEK(vfsz->parent->raw, vfsz->pos+vfsz->startpos); VFS_SEEK(vfsz->parent->raw, vfsz->pos+vfsz->startpos);
vfsz->parent->currentfile = file; vfsz->parent->currentfile = file;
} }
if (vfsz->pos + bytestoread > vfsz->length)
bytestoread = max(0, vfsz->length - vfsz->pos);
read = VFS_READ(vfsz->parent->raw, buffer, bytestoread); read = VFS_READ(vfsz->parent->raw, buffer, bytestoread);
} }

View file

@ -1969,7 +1969,8 @@ qboolean CModQ3_LoadSubmodels (lump_t *l)
bleaf->contents = 0; bleaf->contents = 0;
leafbrush = &map_leafbrushes[numleafbrushes]; leafbrush = &map_leafbrushes[numleafbrushes];
for ( j = 0; j < bleaf->numleafbrushes; j++, leafbrush++ ) { for ( j = 0; j < bleaf->numleafbrushes; j++, leafbrush++ )
{
*leafbrush = LittleLong ( in->firstbrush ) + j; *leafbrush = LittleLong ( in->firstbrush ) + j;
bleaf->contents |= map_brushes[*leafbrush].contents; bleaf->contents |= map_brushes[*leafbrush].contents;
} }

View file

@ -1685,8 +1685,10 @@ void Matrix4x4_CM_UnProject(const vec3_t in, vec3_t out, const vec3_t viewangles
//returns fractions of screen. //returns fractions of screen.
//uses GL style rotations and translations and stuff. //uses GL style rotations and translations and stuff.
//3d -> screen (fixme: offscreen return values needed) //3d -> screen (fixme: offscreen return values needed)
void Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy) //returns false if the 2d point is offscreen.
qboolean Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy)
{ {
qboolean result = true;
float modelview[16]; float modelview[16];
float proj[16]; float proj[16];
@ -1705,12 +1707,17 @@ void Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles,
v[0] /= v[3]; v[0] /= v[3];
v[1] /= v[3]; v[1] /= v[3];
if (v[2] < 0)
result = false; //too close to the view
v[2] /= v[3]; v[2] /= v[3];
out[0] = (1+v[0])/2; out[0] = (1+v[0])/2;
out[1] = (1+v[1])/2; out[1] = (1+v[1])/2;
out[2] = (1+v[2])/2; out[2] = (1+v[2])/2;
if (out[2] > 1)
result = false; //beyond far clip plane
} }
return result;
} }

View file

@ -155,7 +155,7 @@ void Matrix4x4_CM_ModelViewMatrixFromAxis (float *modelview, const vec3_t pn, c
void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale); void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale);
void Matrix4_Multiply (const float *a, const float *b, float *out); void Matrix4_Multiply (const float *a, const float *b, float *out);
void Matrix3x4_Multiply(const float *a, const float *b, float *out); void Matrix3x4_Multiply(const float *a, const float *b, float *out);
void Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy); qboolean Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix4x4_CM_Transform3 (const float *matrix, const float *vector, float *product); void Matrix4x4_CM_Transform3 (const float *matrix, const float *vector, float *product);
void Matrix4x4_CM_Transform4 (const float *matrix, const float *vector, float *product); void Matrix4x4_CM_Transform4 (const float *matrix, const float *vector, float *product);
void Matrix4x4_CM_Transform34(const float *matrix, const vec3_t vector, vec4_t product); void Matrix4x4_CM_Transform34(const float *matrix, const vec3_t vector, vec4_t product);

View file

@ -96,7 +96,7 @@ qboolean NET_CompareAdr (netadr_t a, netadr_t b);
qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b); qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b);
char *NET_AdrToString (char *s, int len, netadr_t a); char *NET_AdrToString (char *s, int len, netadr_t a);
char *NET_BaseAdrToString (char *s, int len, netadr_t a); char *NET_BaseAdrToString (char *s, int len, netadr_t a);
qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr); qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize);
qboolean NET_StringToAdr (const char *s, netadr_t *a); qboolean NET_StringToAdr (const char *s, netadr_t *a);
qboolean NET_IsClientLegal(netadr_t *adr); qboolean NET_IsClientLegal(netadr_t *adr);

View file

@ -88,7 +88,7 @@ cvar_t net_mtu = CVARD("net_mtu", "1450", "Specifies a maximum udp payload size,
cvar_t pext_replacementdeltas = CVAR("debug_pext_replacementdeltas", "0"); /*rename once the extension is finalized*/ cvar_t pext_replacementdeltas = CVAR("debug_pext_replacementdeltas", "0"); /*rename once the extension is finalized*/
/*returns the bitmask of supported+enabled extensions*/ /*returns the entire bitmask of supported+enabled extensions*/
unsigned int Net_PextMask(int maskset) unsigned int Net_PextMask(int maskset)
{ {
unsigned int mask = 0; unsigned int mask = 0;

View file

@ -662,13 +662,7 @@ idnewt:28000
any form of ipv6, including port number. any form of ipv6, including port number.
============= =============
*/ */
#define DO(src,dest) \ qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize)
copy[0] = s[src]; \
copy[1] = s[src + 1]; \
sscanf (copy, "%x", &val); \
((struct sockaddr_ipx *)sadr)->dest = val
qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
{ {
struct hostent *h; struct hostent *h;
char *colon; char *colon;
@ -685,6 +679,13 @@ qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
unsigned int val; unsigned int val;
((struct sockaddr_ipx *)sadr)->sa_family = AF_IPX; ((struct sockaddr_ipx *)sadr)->sa_family = AF_IPX;
#define DO(src,dest) \
copy[0] = s[src]; \
copy[1] = s[src + 1]; \
sscanf (copy, "%x", &val); \
((struct sockaddr_ipx *)sadr)->dest = val
copy[2] = 0; copy[2] = 0;
DO(0, sa_netnum[0]); DO(0, sa_netnum[0]);
DO(2, sa_netnum[1]); DO(2, sa_netnum[1]);
@ -697,7 +698,14 @@ qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
DO(17, sa_nodenum[4]); DO(17, sa_nodenum[4]);
DO(19, sa_nodenum[5]); DO(19, sa_nodenum[5]);
sscanf (&s[22], "%u", &val); sscanf (&s[22], "%u", &val);
#undef DO
((struct sockaddr_ipx *)sadr)->sa_socket = htons((unsigned short)val); ((struct sockaddr_ipx *)sadr)->sa_socket = htons((unsigned short)val);
if (addrfamily)
*addrfamily = AF_IPX;
if (addrsize)
*addrsize = sizeof(struct sockaddr_ipx);
} }
else else
#endif #endif
@ -719,7 +727,7 @@ qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
if (*s == '[') if (*s == '[')
{ {
port = strstr(s, "]:"); port = strstr(s, "]");
if (!port) if (!port)
error = EAI_NONAME; error = EAI_NONAME;
else else
@ -729,7 +737,7 @@ qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
len = sizeof(dupbase)-1; len = sizeof(dupbase)-1;
strncpy(dupbase, s+1, len); strncpy(dupbase, s+1, len);
dupbase[len] = '\0'; dupbase[len] = '\0';
error = pgetaddrinfo(dupbase, port+2, &udp6hint, &addrinfo); error = pgetaddrinfo(dupbase, (port[1] == ':')?port+2:NULL, &udp6hint, &addrinfo);
} }
} }
else else
@ -748,7 +756,7 @@ qboolean NET_StringToSockaddr (const char *s, struct sockaddr_qstorage *sadr)
else else
error = EAI_NONAME; error = EAI_NONAME;
if (error) //failed, try string with no port. if (error) //failed, try string with no port.
error = pgetaddrinfo(s, NULL, &udp6hint, &addrinfo); //remember, this func will return any address family that could be using the udp protocol... (ip4 or ip6) error = pgetaddrinfo(s, NULL, &udp6hint, &addrinfo); //remember, this func will return any address family that could be using the udp protocol... (ip4 or ip6)
} }
if (error) if (error)
{ {
@ -779,6 +787,24 @@ dblbreak:
pfreeaddrinfo (addrinfo); pfreeaddrinfo (addrinfo);
if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound
return false; return false;
if (addrfamily)
*addrfamily = ((struct sockaddr*)sadr)->sa_family;
if (((struct sockaddr*)sadr)->sa_family == AF_INET)
{
if (!((struct sockaddr_in *)sadr)->sin_port)
((struct sockaddr_in *)sadr)->sin_port = htons(defaultport);
if (addrsize)
*addrsize = sizeof(struct sockaddr_in);
}
else
{
if (!((struct sockaddr_in6 *)sadr)->sin6_port)
((struct sockaddr_in6 *)sadr)->sin6_port = htons(defaultport);
if (addrsize)
*addrsize = sizeof(struct sockaddr_in6);
}
} }
else else
#endif #endif
@ -791,6 +817,8 @@ dblbreak:
if (strlen(s) >= sizeof(copy)-1) if (strlen(s) >= sizeof(copy)-1)
return false; return false;
((struct sockaddr_in *)sadr)->sin_port = htons(defaultport);
strcpy (copy, s); strcpy (copy, s);
// strip off a trailing :port if present // strip off a trailing :port if present
for (colon = copy ; *colon ; colon++) for (colon = copy ; *colon ; colon++)
@ -812,6 +840,10 @@ dblbreak:
return false; return false;
*(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
} }
if (addrfamily)
*addrfamily = AF_INET;
if (addrsize)
*addrsize = sizeof(struct sockaddr_in);
#else #else
return false; return false;
#endif #endif
@ -820,8 +852,6 @@ dblbreak:
return true; return true;
} }
#undef DO
/* /*
accepts anything that NET_StringToSockaddr accepts plus certain url schemes accepts anything that NET_StringToSockaddr accepts plus certain url schemes
including: tcp, irc including: tcp, irc
@ -868,7 +898,7 @@ qboolean NET_StringToAdr (const char *s, netadr_t *a)
{ {
//make sure that the rest of the address is a valid ip address (4 or 6) //make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, &sadr)) if (!NET_StringToSockaddr (s+6, 0, &sadr, NULL, NULL))
{ {
a->type = NA_INVALID; a->type = NA_INVALID;
return false; return false;
@ -914,7 +944,7 @@ qboolean NET_StringToAdr (const char *s, netadr_t *a)
} }
#endif #endif
if (!NET_StringToSockaddr (s, &sadr)) if (!NET_StringToSockaddr (s, 0, &sadr, NULL, NULL))
{ {
a->type = NA_INVALID; a->type = NA_INVALID;
return false; return false;
@ -4269,7 +4299,7 @@ void NET_GetLocalAddress (int socket, netadr_t *out)
if (getsockname (socket, (struct sockaddr *)&address, &namelen) == -1) if (getsockname (socket, (struct sockaddr *)&address, &namelen) == -1)
{ {
notvalid = true; notvalid = true;
NET_StringToSockaddr("0.0.0.0", (struct sockaddr_qstorage *)&address); NET_StringToSockaddr("0.0.0.0", 0, (struct sockaddr_qstorage *)&address, NULL, NULL);
// Sys_Error ("NET_Init: getsockname:", strerror(qerrno)); // Sys_Error ("NET_Init: getsockname:", strerror(qerrno));
} }

View file

@ -477,6 +477,11 @@ static qintptr_t VARGS Plug_ExportNative(void *offset, quintptr_t mask, const qi
else if (!strcmp(name, "Media_VideoDecoder")) else if (!strcmp(name, "Media_VideoDecoder"))
{ {
Media_RegisterDecoder(currentplug, func); Media_RegisterDecoder(currentplug, func);
// currentplug->blockcloses++;
}
else if (!strcmp(name, "Media_VideoEncoder"))
{
Media_RegisterEncoder(currentplug, func);
// currentplug->blockcloses++; // currentplug->blockcloses++;
} }
#endif #endif
@ -1812,6 +1817,7 @@ void Plug_Close(plugin_t *plug)
Con_Printf("Closing plugin %s\n", plug->name); Con_Printf("Closing plugin %s\n", plug->name);
#if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY) #if defined(PLUGINS) && !defined(NOMEDIA) && !defined(SERVERONLY)
Media_UnregisterDecoder(plug, NULL); Media_UnregisterDecoder(plug, NULL);
Media_UnregisterEncoder(plug, NULL);
#endif #endif
if (plug->shutdown) if (plug->shutdown)
VM_Call(plug->vm, plug->shutdown); VM_Call(plug->vm, plug->shutdown);
@ -1900,6 +1906,10 @@ void Plug_Shutdown(void)
BZ_Free(plugbuiltins); BZ_Free(plugbuiltins);
plugbuiltins = NULL; plugbuiltins = NULL;
plugincvararraylen = 0;
BZ_Free(plugincvararray);
plugincvararray = NULL;
plugincommandarraylen = 0; plugincommandarraylen = 0;
BZ_Free(plugincommandarray); BZ_Free(plugincommandarray);
plugincommandarray = NULL; plugincommandarray = NULL;

View file

@ -6,16 +6,13 @@
#include <ctype.h> #include <ctype.h>
//fixme
#define Z_QC_TAG 2
#define PRSTR 0xa6ffb3d7
static char *cvargroup_progs = "Progs variables"; static char *cvargroup_progs = "Progs variables";
cvar_t pr_brokenfloatconvert = SCVAR("pr_brokenfloatconvert", "0"); cvar_t pr_brokenfloatconvert = SCVAR("pr_brokenfloatconvert", "0");
cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "");//"16"); cvar_t pr_tempstringcount = SCVAR("pr_tempstringcount", "");//"16");
cvar_t pr_tempstringsize = SCVAR("pr_tempstringsize", "4096"); cvar_t pr_tempstringsize = SCVAR("pr_tempstringsize", "4096");
cvar_t dpcompat_stats = CVAR("dpcompat_stats", "0"); cvar_t pr_enable_uriget = SCVAR("pr_enable_uriget", "1");
int tokenizeqc(char *str, qboolean dpfuckage);
static char *strtoupper(char *s) static char *strtoupper(char *s)
{ {
@ -50,7 +47,7 @@ void PF_Common_RegisterCvars(void)
Cvar_Register (&pr_brokenfloatconvert, cvargroup_progs); Cvar_Register (&pr_brokenfloatconvert, cvargroup_progs);
Cvar_Register (&pr_tempstringcount, cvargroup_progs); Cvar_Register (&pr_tempstringcount, cvargroup_progs);
Cvar_Register (&pr_tempstringsize, cvargroup_progs); Cvar_Register (&pr_tempstringsize, cvargroup_progs);
Cvar_Register (&dpcompat_stats, cvargroup_progs); Cvar_Register (&pr_enable_uriget, cvargroup_progs);
WPhys_Init(); WPhys_Init();
} }
@ -823,9 +820,8 @@ void QCBUILTIN PF_cvar_type (progfuncs_t *prinst, struct globalvars_s *pr_global
ret |= 4; // CVAR_TYPE_PRIVATE ret |= 4; // CVAR_TYPE_PRIVATE
if(!(v->flags & CVAR_USERCREATED)) if(!(v->flags & CVAR_USERCREATED))
ret |= 8; // CVAR_TYPE_ENGINE ret |= 8; // CVAR_TYPE_ENGINE
if (v->description)
//fte cvars don't support this ret |= 16; // CVAR_TYPE_HASDESCRIPTION
// ret |= 16; // CVAR_TYPE_HASDESCRIPTION
} }
G_FLOAT(OFS_RETURN) = ret; G_FLOAT(OFS_RETURN) = ret;
} }
@ -1204,19 +1200,19 @@ static void PF_fwrite (progfuncs_t *prinst, int fnum, char *msg, int len)
{ {
if (fnum < 0 || fnum >= MAX_QC_FILES) if (fnum < 0 || fnum >= MAX_QC_FILES)
{ {
Con_Printf("PF_fgets: File out of range\n"); Con_Printf("PF_fwrite: File out of range\n");
return; //out of range return; //out of range
} }
if (!pf_fopen_files[fnum].data) if (!pf_fopen_files[fnum].data)
{ {
Con_Printf("PF_fgets: File is not open\n"); Con_Printf("PF_fwrite: File is not open\n");
return; //not open return; //not open
} }
if (pf_fopen_files[fnum].prinst != prinst) if (pf_fopen_files[fnum].prinst != prinst)
{ {
Con_Printf("PF_fgets: File is from wrong instance\n"); Con_Printf("PF_fwrite: File is from wrong instance\n");
return; //this just isn't ours. return; //this just isn't ours.
} }
@ -1263,6 +1259,7 @@ void PF_fcloseall (progfuncs_t *prinst)
Con_Printf("qc file %s was still open\n", pf_fopen_files[i].name); Con_Printf("qc file %s was still open\n", pf_fopen_files[i].name);
PF_fclose_i(i); PF_fclose_i(i);
} }
tokenizeqc("", false);
} }
@ -2151,7 +2148,7 @@ void QCBUILTIN PF_substring (progfuncs_t *prinst, struct globalvars_s *pr_global
slen = strlen(s); slen = strlen(s);
if (start < 0) if (start < 0)
start = slen-start; start = slen+start;
if (length < 0) if (length < 0)
length = slen-start+(length+1); length = slen-start+(length+1);
if (start < 0) if (start < 0)
@ -2279,7 +2276,15 @@ void QCBUILTIN PF_etos (progfuncs_t *prinst, struct globalvars_s *pr_globals)
void QCBUILTIN PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_strlennocol (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
char *in = PR_GetStringOfs(prinst, OFS_PARM0); char *in = PR_GetStringOfs(prinst, OFS_PARM0);
G_FLOAT(OFS_RETURN) = COM_FunStringLength(in); char result[8192];
unsigned int flagged[8192];
unsigned int len = 0;
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged), false);
COM_DeFunString(flagged, NULL, result, sizeof(result), true);
for (len = 0; result[len]; len++)
;
G_FLOAT(OFS_RETURN) = len;
} }
//DP_QC_STRINGCOLORFUNCTIONS //DP_QC_STRINGCOLORFUNCTIONS
@ -2351,7 +2356,7 @@ struct strbuf {
int allocated; int allocated;
}; };
#define NUMSTRINGBUFS 16 #define NUMSTRINGBUFS 64
struct strbuf strbuflist[NUMSTRINGBUFS]; struct strbuf strbuflist[NUMSTRINGBUFS];
void PF_buf_shutdown(progfuncs_t *prinst) void PF_buf_shutdown(progfuncs_t *prinst)
@ -2531,30 +2536,67 @@ void QCBUILTIN PF_bufstr_set (progfuncs_t *prinst, struct globalvars_s *pr_glob
void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_bufstr_add (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int bufno = G_FLOAT(OFS_PARM0)-1; int bufno = G_FLOAT(OFS_PARM0)-1;
//char *string = PR_GetStringOfs(prinst, OFS_PARM1); char *string = PR_GetStringOfs(prinst, OFS_PARM1);
//int order = G_FLOAT(OFS_PARM2); int order = G_FLOAT(OFS_PARM2);
int index;
if ((unsigned int)bufno >= NUMSTRINGBUFS) if ((unsigned int)bufno >= NUMSTRINGBUFS)
return; return;
if (strbuflist[bufno].prinst != prinst) if (strbuflist[bufno].prinst != prinst)
return; return;
Con_Printf("PF_bufstr_add: stub\n"); if (order)
{
//add on end
index = strbuflist[bufno].used;
}
else
{
//find a hole
for (index = 0; index < strbuflist[bufno].used; index++)
if (!strbuflist[bufno].strings[index])
break;
}
G_FLOAT(OFS_RETURN) = 0; //expand it if needed
if (index >= strbuflist[bufno].allocated)
{
int oldcount;
oldcount = strbuflist[bufno].allocated;
strbuflist[bufno].allocated = (index + 256);
strbuflist[bufno].strings = BZ_Realloc(strbuflist[bufno].strings, strbuflist[bufno].allocated*sizeof(char*));
memset(strbuflist[bufno].strings+oldcount, 0, (strbuflist[bufno].allocated - oldcount) * sizeof(char*));
}
//add in the new string.
if (strbuflist[bufno].strings[index])
Z_Free(strbuflist[bufno].strings[index]);
strbuflist[bufno].strings[index] = Z_Malloc(strlen(string)+1);
strcpy(strbuflist[bufno].strings[index], string);
if (index >= strbuflist[bufno].used)
strbuflist[bufno].used = index+1;
G_FLOAT(OFS_RETURN) = index;
} }
// #449 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS) // #449 void(float bufhandle, float string_index) bufstr_free (DP_QC_STRINGBUFFERS)
void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_bufstr_free (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
int bufno = G_FLOAT(OFS_PARM0)-1; int bufno = G_FLOAT(OFS_PARM0)-1;
//int index = G_FLOAT(OFS_PARM1); int index = G_FLOAT(OFS_PARM1);
if ((unsigned int)bufno >= NUMSTRINGBUFS) if ((unsigned int)bufno >= NUMSTRINGBUFS)
return; return;
if (strbuflist[bufno].prinst != prinst) if (strbuflist[bufno].prinst != prinst)
return; return;
Con_Printf("PF_bufstr_free: stub\n"); if (index >= strbuflist[bufno].used)
return; //not valid anyway.
if (strbuflist[bufno].strings[index])
Z_Free(strbuflist[bufno].strings[index]);
strbuflist[bufno].strings[index] = NULL;
} }
void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_buf_cvarlist (progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -2659,14 +2701,74 @@ void QCBUILTIN PF_uri_unescape (progfuncs_t *prinst, struct globalvars_s *pr_gl
RETURN_TSTRING(resultbuf); RETURN_TSTRING(resultbuf);
} }
#ifdef WEBCLIENT
static void PR_uri_get_callback(struct dl_download *dl)
{
extern progfuncs_t *menuprogs;
world_t *w = dl->user_ctx;
progfuncs_t *prinst = w?w->progs:menuprogs;
float id = dl->user_num;
func_t func;
if (!prinst)
return;
func = PR_FindFunction(prinst, "URI_Get_Callback", PR_ANY);
if (func)
{
int len;
char *buffer;
struct globalvars_s *pr_globals = PR_globals(prinst, PR_CURRENT);
G_FLOAT(OFS_PARM0) = id;
G_FLOAT(OFS_PARM1) = (dl->replycode!=200)?dl->replycode:0; //for compat with DP, we change any 200s to 0.
G_INT(OFS_PARM2) = 0;
if (dl->file)
{
len = VFS_GETLEN(dl->file);
buffer = malloc(len+1);
buffer[len] = 0;
VFS_READ(dl->file, buffer, len);
G_INT(OFS_PARM2) = PR_TempString(prinst, buffer);
free(buffer);
}
PR_ExecuteProgram(prinst, func);
}
}
#endif
// uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned // uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned
// returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string // returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string
//float(string uril, float id) uri_get = #513; //float(string uril, float id) uri_get = #513;
void QCBUILTIN PF_uri_get (progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_uri_get (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
Con_Printf("PF_uri_get: stub\n"); #ifdef WEBCLIENT
world_t *w = prinst->parms->user;
unsigned char *url = PR_GetStringOfs(prinst, OFS_PARM0);
float id = G_FLOAT(OFS_PARM1);
struct dl_download *dl;
G_FLOAT(OFS_RETURN) = 0; if (!pr_enable_uriget.ival)
{
Con_Printf("PF_uri_get(\"%s\",%g): %s disabled\n", url, id, pr_enable_uriget.name);
G_FLOAT(OFS_RETURN) = 0;
return;
}
Con_DPrintf("PF_uri_get(%s,%g)\n", url, id);
dl = HTTP_CL_Get(url, NULL, PR_uri_get_callback);
if (dl)
{
dl->user_ctx = w;
dl->user_num = id;
G_FLOAT(OFS_RETURN) = 1;
}
else
#endif
G_FLOAT(OFS_RETURN) = 0;
} }
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
@ -3170,18 +3272,30 @@ void QCBUILTIN PF_externvalue (progfuncs_t *prinst, struct globalvars_s *pr_glob
char *varname = PF_VarString(prinst, 1, pr_globals); char *varname = PF_VarString(prinst, 1, pr_globals);
eval_t *var; eval_t *var;
var = prinst->FindGlobal(prinst, varname, n, NULL); if (*varname == '&')
if (var)
{ {
G_INT(OFS_RETURN+0) = ((int*)&var->_int)[0]; //return its address instead of its value, for pointer use.
G_INT(OFS_RETURN+1) = ((int*)&var->_int)[1]; var = prinst->FindGlobal(prinst, varname+1, n, NULL);
G_INT(OFS_RETURN+2) = ((int*)&var->_int)[2]; if (var)
G_INT(OFS_RETURN) = (char*)var - prinst->stringtable;
else
G_INT(OFS_RETURN) = 0;
} }
else else
{ {
n = prinst->FindFunction(prinst, varname, n); var = prinst->FindGlobal(prinst, varname, n, NULL);
G_INT(OFS_RETURN) = n;
if (var)
{
G_INT(OFS_RETURN+0) = ((int*)&var->_int)[0];
G_INT(OFS_RETURN+1) = ((int*)&var->_int)[1];
G_INT(OFS_RETURN+2) = ((int*)&var->_int)[2];
}
else
{
n = prinst->FindFunction(prinst, varname, n);
G_INT(OFS_RETURN) = n;
}
} }
} }
@ -3657,7 +3771,8 @@ nolength:
default: default:
verbatim: verbatim:
if(o < end - 1) if(o < end - 1)
*o++ = *s++; *o++ = *s;
s++;
break; break;
} }
} }
@ -3667,6 +3782,77 @@ finished:
RETURN_TSTRING(outbuf); RETURN_TSTRING(outbuf);
} }
fdef_t *ED_FieldInfo (progfuncs_t *progfuncs, unsigned int *count);
char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val);
pbool ED_ParseEval (progfuncs_t *progfuncs, eval_t *eval, int type, char *s);
//float()
void QCBUILTIN PF_numentityfields (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int count = 0;
ED_FieldInfo(prinst, &count);
G_FLOAT(OFS_RETURN) = count;
}
//string(float fieldnum)
void QCBUILTIN PF_entityfieldname (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int fidx = G_FLOAT(OFS_PARM0);
unsigned int count = 0;
fdef_t *fdef;
fdef = ED_FieldInfo(prinst, &count);
if (fidx < count)
{
RETURN_TSTRING(fdef[fidx].name);
}
else
G_INT(OFS_RETURN) = 0;
}
//float(float fieldnum)
void QCBUILTIN PF_entityfieldtype (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int fidx = G_FLOAT(OFS_PARM0);
unsigned int count = 0;
fdef_t *fdef = ED_FieldInfo(prinst, &count);
if (fidx < count)
{
G_FLOAT(OFS_RETURN) = fdef[fidx].type;
}
else
G_FLOAT(OFS_RETURN) = 0;
}
//string(float fieldnum, entity ent)
void QCBUILTIN PF_getentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int fidx = G_FLOAT(OFS_PARM0);
wedict_t *ent = (wedict_t *)G_EDICT(prinst, OFS_PARM1);
eval_t *eval;
unsigned int count = 0;
fdef_t *fdef = ED_FieldInfo(prinst, &count);
if (fidx < count)
{
eval = (eval_t *)&((float *)ent->v)[fdef[fidx].ofs];
RETURN_TSTRING(PR_UglyValueString(prinst, fdef[fidx].type, eval));
}
else
G_INT(OFS_RETURN) = 0;
}
//float(float fieldnum, entity ent, string s)
void QCBUILTIN PF_putentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
unsigned int fidx = G_FLOAT(OFS_PARM0);
wedict_t *ent = (wedict_t *)G_EDICT(prinst, OFS_PARM1);
char *str = PR_GetStringOfs(prinst, OFS_PARM2);
eval_t *eval;
unsigned int count = 0;
fdef_t *fdef = ED_FieldInfo(prinst, &count);
if (fidx < count)
{
eval = (eval_t *)&((float *)ent->v)[fdef[fidx].ofs];
G_FLOAT(OFS_RETURN) = ED_ParseEval(prinst, eval, fdef[fidx].type, str);
}
else
G_FLOAT(OFS_RETURN) = 0;
}
#define DEF_SAVEGLOBAL (1u<<15) #define DEF_SAVEGLOBAL (1u<<15)
static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cvar_t *var) static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cvar_t *var)
{ {
@ -3690,11 +3876,11 @@ static void PR_AutoCvarApply(progfuncs_t *prinst, eval_t *val, etype_t type, cva
char res[128]; char res[128];
char *vs = var->string; char *vs = var->string;
vs = COM_ParseOut(vs, res, sizeof(res)); vs = COM_ParseOut(vs, res, sizeof(res));
val->_vector[0] = atof(com_token); val->_vector[0] = atof(res);
vs = COM_ParseOut(vs, res, sizeof(res)); vs = COM_ParseOut(vs, res, sizeof(res));
val->_vector[1] = atof(com_token); val->_vector[1] = atof(res);
vs = COM_ParseOut(vs, res, sizeof(res)); vs = COM_ParseOut(vs, res, sizeof(res));
val->_vector[2] = atof(com_token); val->_vector[2] = atof(res);
} }
break; break;
} }
@ -3726,11 +3912,17 @@ void PR_FoundPrefixedGlobals(progfuncs_t *progfuncs, char *name, eval_t *val, et
{ {
cvar_t *var; cvar_t *var;
char *vals; char *vals;
int nlen;
name += 9; //autocvar_ name += 9; //autocvar_
switch(type & ~DEF_SAVEGLOBAL) switch(type & ~DEF_SAVEGLOBAL)
{ {
case ev_float: case ev_float:
//ignore individual vector componants. let the vector itself do all the work.
nlen = strlen(name);
if(nlen >= 2 && name[nlen-2] == '_' && (name[nlen-1] == 'x' || name[nlen-1] == 'y' || name[nlen-1] == 'z'))
return;
vals = va("%f", val->_float); vals = va("%f", val->_float);
break; break;
case ev_integer: case ev_integer:
@ -3786,7 +3978,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_PEXT_Q3BSP"}, //quake3 bsp support. dp probably has an equivelent, but this is queryable per client. {"FTE_PEXT_Q3BSP"}, //quake3 bsp support. dp probably has an equivelent, but this is queryable per client.
{"DP_ENT_COLORMOD"}, {"DP_ENT_COLORMOD"},
{NULL}, //splitscreen - not queryable. {NULL}, //splitscreen - not queryable.
{"FTE_HEXEN2"}, //client can use hexen2 maps. server can use hexen2 progs {"FTE_HEXEN2", 3, NULL, {"particle2", "particle3", "particle4"}}, //client can use hexen2 maps. server can use hexen2 progs
{"FTE_PEXT_SPAWNSTATIC"}, //means that static entities can have alpha/scale and anything else the engine supports on normal ents. (Added for >256 models, while still being compatible - previous system failed with -1 skins) {"FTE_PEXT_SPAWNSTATIC"}, //means that static entities can have alpha/scale and anything else the engine supports on normal ents. (Added for >256 models, while still being compatible - previous system failed with -1 skins)
{"FTE_PEXT_CUSTOMTENTS", 2, NULL, {"RegisterTempEnt", "CustomTempEnt"}}, {"FTE_PEXT_CUSTOMTENTS", 2, NULL, {"RegisterTempEnt", "CustomTempEnt"}},
{"FTE_PEXT_256PACKETENTITIES"}, //client is able to receive unlimited packet entities (server caps itself to 256 to prevent insanity). {"FTE_PEXT_256PACKETENTITIES"}, //client is able to receive unlimited packet entities (server caps itself to 256 to prevent insanity).
@ -3835,6 +4027,7 @@ lh_extension_t QSG_Extensions[] = {
//to an extend {"DP_HALFLIFE_SPRITE"}, //to an extend {"DP_HALFLIFE_SPRITE"},
{"DP_INPUTBUTTONS"}, {"DP_INPUTBUTTONS"},
{"DP_LITSUPPORT"}, {"DP_LITSUPPORT"},
{"DP_MD3_TAGSINFO", 2, NULL, {"gettagindex", "gettaginfo"}},
{"DP_MONSTERWALK"}, {"DP_MONSTERWALK"},
{"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code for hexen2 support. {"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code for hexen2 support.
{"DP_MOVETYPEFOLLOW"}, {"DP_MOVETYPEFOLLOW"},
@ -3854,6 +4047,7 @@ lh_extension_t QSG_Extensions[] = {
{"DP_QC_FINDCHAINFLAGS", 1, NULL, {"findchainflags"}}, {"DP_QC_FINDCHAINFLAGS", 1, NULL, {"findchainflags"}},
{"DP_QC_FINDFLOAT", 1, NULL, {"findfloat"}}, {"DP_QC_FINDFLOAT", 1, NULL, {"findfloat"}},
{"DP_QC_FS_SEARCH", 4, NULL, {"search_begin", "search_end", "search_getsize", "search_getfilename"}}, {"DP_QC_FS_SEARCH", 4, NULL, {"search_begin", "search_end", "search_getsize", "search_getfilename"}},
{"DP_QC_GETSURFACE", 6, NULL, {"getsurfacenumpoints", "getsurfacepoint", "getsurfacenormal", "getsurfacetexture", "getsurfacenearpoint", "getsurfaceclippedpoint"}},
{"DP_QC_GETSURFACEPOINTATTRIBUTE", 1, NULL, {"getsurfacepointattribute"}}, {"DP_QC_GETSURFACEPOINTATTRIBUTE", 1, NULL, {"getsurfacepointattribute"}},
{"DP_QC_MINMAXBOUND", 3, NULL, {"min", "max", "bound"}}, {"DP_QC_MINMAXBOUND", 3, NULL, {"min", "max", "bound"}},
{"DP_QC_MULTIPLETEMPSTRINGS"}, {"DP_QC_MULTIPLETEMPSTRINGS"},
@ -3901,14 +4095,14 @@ lh_extension_t QSG_Extensions[] = {
{"DP_SV_WRITEUNTERMINATEDSTRING", 1, NULL, {"WriteUnterminatedString"}}, {"DP_SV_WRITEUNTERMINATEDSTRING", 1, NULL, {"WriteUnterminatedString"}},
{"DP_TE_BLOOD", 1, NULL, {"te_blood"}}, {"DP_TE_BLOOD", 1, NULL, {"te_blood"}},
{"DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}}, {"DP_TE_BLOODSHOWER", 1, NULL, {"te_bloodshower"}},
{"DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}}, {"_DP_TE_CUSTOMFLASH", 1, NULL, {"te_customflash"}},
{"DP_TE_EXPLOSIONRGB"}, {"DP_TE_EXPLOSIONRGB", 1, NULL, {"te_explosionrgb"}},
{"DP_TE_FLAMEJET", 1, NULL, {"te_flamejet"}}, {"_DP_TE_FLAMEJET", 1, NULL, {"te_flamejet"}},
{"DP_TE_PARTICLECUBE", 1, NULL, {"te_particlecube"}}, {"DP_TE_PARTICLECUBE", 1, NULL, {"te_particlecube"}},
//particlerain {"_DP_TE_PARTICLERAIN", 1, NULL, {"te_particlerain"}},
//particlesnow {"_DP_TE_PARTICLESNOW", 1, NULL, {"te_particlesnow"}},
{"DP_TE_PLASMABURN", 1, NULL, {"te_plasmaburn"}}, {"_DP_TE_PLASMABURN", 1, NULL, {"te_plasmaburn"}},
{"DP_TE_QUADEFFECTS1"}, {"_DP_TE_QUADEFFECTS1", 4, NULL, {"te_gunshotquad", "te_spikequad", "te_superspikequad", "te_explosionquad"}},
{"DP_TE_SMALLFLASH", 1, NULL, {"te_smallflash"}}, {"DP_TE_SMALLFLASH", 1, NULL, {"te_smallflash"}},
{"DP_TE_SPARK", 1, NULL, {"te_spark"}}, {"DP_TE_SPARK", 1, NULL, {"te_spark"}},
{"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}}, {"DP_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", "te_teleport", "te_explosion2", "te_lightning1", "te_lightning2", "te_lightning3", "te_beam"}},
@ -3933,7 +4127,7 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files. {"FTE_MEDIA_CIN"}, //playfilm command supports q2 cin files.
{"FTE_MEDIA_ROQ"}, //playfilm command supports q3 roq files {"FTE_MEDIA_ROQ"}, //playfilm command supports q3 roq files
#endif #endif
{"FTE_MULTIPROGS"}, //multiprogs functions are available. {"FTE_MULTIPROGS", 5, NULL, {"externcall", "addprogs", "externvalue", "externset", "instr"}}, //multiprogs functions are available.
{"FTE_MULTITHREADED", 3, NULL, {"sleep", "fork", "abort"}}, {"FTE_MULTITHREADED", 3, NULL, {"sleep", "fork", "abort"}},
#ifdef SERVER_DEMO_PLAYBACK #ifdef SERVER_DEMO_PLAYBACK
{"FTE_MVD_PLAYBACK"}, {"FTE_MVD_PLAYBACK"},
@ -3944,19 +4138,19 @@ lh_extension_t QSG_Extensions[] = {
{"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}}, {"FTE_QC_CHECKPVS", 1, NULL, {"checkpvs"}},
{"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclientname"}}, {"FTE_QC_MATCHCLIENTNAME", 1, NULL, {"matchclientname"}},
{"FTE_QC_PAUSED"}, {"FTE_QC_PAUSED"},
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}}, {"FTE_QC_INTCONV", 4, NULL, {"stoi", "itos", "stoh", "htos"}},
{"FTE_QC_SENDPACKET", 1, NULL, {"sendpacket"}}, //includes the SV_ParseConnectionlessPacket event.
{"FTE_QC_TRACETRIGGER"}, {"FTE_QC_TRACETRIGGER"},
{"FTE_SOLID_LADDER"}, //Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS {"FTE_SOLID_LADDER"}, //Allows a simple trigger to remove effects of gravity (solid 20). obsolete. will prolly be removed at some point as it is not networked properly. Use FTE_ENT_SKIN_CONTENTS
#ifdef SQL
// serverside SQL functions for managing an SQL database connection // serverside SQL functions for managing an SQL database connection
{"FTE_SQL", 9, NULL, {"sqlconnect","sqldisconnect","sqlopenquery","sqlclosequery","sqlreadfield","sqlerror","sqlescape","sqlversion", {"FTE_SQL", 9, NULL, {"sqlconnect","sqldisconnect","sqlopenquery","sqlclosequery","sqlreadfield","sqlerror","sqlescape","sqlversion",
"sqlreadfloat"}}, "sqlreadfloat"}},
#endif
//eperimental advanced strings functions. //eperimental advanced strings functions.
//reuses the FRIK_FILE builtins (with substring extension) //reuses the FRIK_FILE builtins (with substring extension)
{"FTE_STRINGS", 16, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone", {"FTE_STRINGS", 17, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone",
"strstrofs", "str2chr", "chr2str", "strconv", "infoadd", "infoget", "strncmp", "strcasecmp", "strncasecmp"}}, "strstrofs", "str2chr", "chr2str", "strconv", "infoadd", "infoget", "strncmp", "strcasecmp", "strncasecmp", "strpad"}},
{"FTE_SV_REENTER"}, {"FTE_SV_REENTER"},
{"FTE_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash", {"FTE_TE_STANDARDEFFECTBUILTINS", 14, NULL, {"te_gunshot", "te_spike", "te_superspike", "te_explosion", "te_tarexplosion", "te_wizspike", "te_knightspike", "te_lavasplash",
"te_teleport", "te_lightning1", "te_lightning2", "te_lightning3", "te_lightningblood", "te_bloodqw"}}, "te_teleport", "te_lightning1", "te_lightning2", "te_lightning3", "te_lightningblood", "te_bloodqw"}},

View file

@ -53,11 +53,6 @@ struct wedict_s
#define PF_pointsound PF_Fixme #define PF_pointsound PF_Fixme
#define PF_gecko_mousemove PF_Fixme #define PF_gecko_mousemove PF_Fixme
#define PF_numentityfields PF_Fixme
#define PF_entityfieldname PF_Fixme
#define PF_entityfieldtype PF_Fixme
#define PF_getentityfieldstring PF_Fixme
#define PF_putentityfieldstring PF_Fixme
#define PF_WritePicture PF_Fixme #define PF_WritePicture PF_Fixme
#define PF_ReadPicture PF_Fixme #define PF_ReadPicture PF_Fixme
@ -179,6 +174,11 @@ void PR_fclose_progs (progfuncs_t *prinst);
char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_globals); char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_globals);
void PR_AutoCvarSetup(progfuncs_t *prinst); void PR_AutoCvarSetup(progfuncs_t *prinst);
void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var); void PR_AutoCvar(progfuncs_t *prinst, cvar_t *var);
void QCBUILTIN PF_numentityfields (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_entityfieldname (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_entityfieldtype (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_putentityfieldstring (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -315,7 +315,7 @@ void QCBUILTIN PF_calltimeofday (progfuncs_t *prinst, struct globalvars_s *pr_gl
void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals);
void PF_fclose_progs (progfuncs_t *prinst); void PF_fclose_progs (progfuncs_t *prinst);
int QCEditor (progfuncs_t *prinst, char *filename, int line, int nump, char **parms); int QCEditor (progfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms);
@ -489,6 +489,34 @@ enum csqc_input_event
CSIE_ACCELEROMETER = 4 /*x, y, z*/ CSIE_ACCELEROMETER = 4 /*x, y, z*/
}; };
enum terrainedit_e
{
ter_reload, //
ter_save, //
ter_sethole, //vector pos, float radius, floatbool hole
ter_height_set, //vector pos, float radius, float newheight
ter_height_smooth, //vector pos, float radius, float percent
ter_height_spread, //vector pos, float radius, float percent
ter_raise, //vector pos, float radius, float heightchange
ter_lower, //vector pos, float radius, float heightchange
ter_tex_kill, //vector pos, void junk, void junk, string texname
ter_tex_get, //vector pos, void junk, float imagenum
ter_mix_paint, //vector pos, float radius, float percent, string texname
ter_mix_concentrate, //vector pos, float radius, float percent
ter_mix_noise, //vector pos, float radius, float percent
ter_mix_blur, //vector pos, float radius, float percent
ter_water_set, //vector pos, float radius, float newwaterheight
ter_mesh_add, //entity ent
ter_mesh_kill, //vector pos, float radius
ter_tint, //vector pos, float radius, float percent, vector newcol, float newalph
ter_height_flatten, //vector pos, float radius, float percent
// ter_poly_add, //add a poly, woo
// ter_poly_remove, //remove polys
// ter_autopaint_h, //vector pos, float radius, float percent, string tex1, string tex2 (paint tex1/tex2
// ter_autopaint_n //vector pos, float radius, float percent, string tex1, string tex2
};
enum enum
{ {
GE_MAXENTS = -1, GE_MAXENTS = -1,

View file

@ -52,10 +52,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PEXT_SPAWNSTATIC2 0x00400000 //Sends an entity delta instead of a baseline. #define PEXT_SPAWNSTATIC2 0x00400000 //Sends an entity delta instead of a baseline.
#define PEXT_CUSTOMTEMPEFFECTS 0x00800000 //supports custom temp ents. #define PEXT_CUSTOMTEMPEFFECTS 0x00800000 //supports custom temp ents.
#define PEXT_256PACKETENTITIES 0x01000000 //Client can recieve 256 packet entities. #define PEXT_256PACKETENTITIES 0x01000000 //Client can recieve 256 packet entities.
//#define PEXT_NEVERUSED 0x02000000 //#define PEXT_NEVERUSED 0x02000000 //reserved for a future multicastmask
#define PEXT_SHOWPIC 0x04000000 #define PEXT_SHOWPIC 0x04000000
#define PEXT_SETATTACHMENT 0x08000000 //md3 tags (needs networking, they need to lerp). #define PEXT_SETATTACHMENT 0x08000000 //md3 tags (needs networking, they need to lerp).
//#define PEXT_NEVERUSED 0x10000000 //#define PEXT_NEVERUSED 0x10000000 //reserved for a future multicastmask
#define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings. #define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings.
#ifdef CSQC_DAT #ifdef CSQC_DAT
@ -773,8 +773,9 @@ enum {
========================================================== ==========================================================
*/ */
#define MAX_CLIENTS 32 /*max 255, min 32*/ #define MAX_CLIENTS 32//255 /*max 255, min 32*/
#define QWMAX_CLIENTS 32 /*QW's standard max*/ #define QWMAX_CLIENTS 32 /*QW's standard max. clients might have issues above this value*/
#define NQMAX_CLIENTS 16 /*NQ's standard max. clients might have issues above this value*/
#define UPDATE_BACKUP 64 // copies of entity_state_t to keep buffered #define UPDATE_BACKUP 64 // copies of entity_state_t to keep buffered
// must be power of two // must be power of two

View file

@ -33,10 +33,6 @@ Also, can efficiency be improved much?
*/ */
#ifdef __MORPHOS__
#include <proto/dynload.h>
#endif
#include "quakedef.h" #include "quakedef.h"
#ifdef VM_ANY #ifdef VM_ANY
@ -70,10 +66,6 @@ struct vm_s {
qintptr_t (EXPORT_FN *vmMain)(qintptr_t command, qintptr_t arg0, qintptr_t arg1, qintptr_t arg2, qintptr_t arg3, qintptr_t arg4, qintptr_t arg5, qintptr_t arg6); qintptr_t (EXPORT_FN *vmMain)(qintptr_t command, qintptr_t arg0, qintptr_t arg1, qintptr_t arg2, qintptr_t arg3, qintptr_t arg4, qintptr_t arg5, qintptr_t arg6);
}; };
#if defined(__MORPHOS__) && I_AM_BIGFOOT
#include <proto/dynload.h>
#endif
dllhandle_t *QVM_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall) dllhandle_t *QVM_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall)
{ {
void (EXPORT_FN *dllEntry)(sys_calldll_t syscall); void (EXPORT_FN *dllEntry)(sys_calldll_t syscall);
@ -88,11 +80,6 @@ dllhandle_t *QVM_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall)
{NULL, NULL}, {NULL, NULL},
}; };
#ifdef __MORPHOS__
if (DynLoadBase == 0)
return 0;
#endif
#ifdef _WIN32 #ifdef _WIN32
snprintf(dllname_arch, sizeof(dllname_arch), "%sx86.dll", name); snprintf(dllname_arch, sizeof(dllname_arch), "%sx86.dll", name);
snprintf(dllname_anycpu, sizeof(dllname_anycpu), "%s.dll", name); snprintf(dllname_anycpu, sizeof(dllname_anycpu), "%s.dll", name);

View file

@ -92,6 +92,7 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres
#ifdef MULTITHREAD #ifdef MULTITHREAD
void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize); void *Sys_CreateThread(int (*func)(void *), void *args, int priority, int stacksize);
void Sys_WaitOnThread(void *thread); void Sys_WaitOnThread(void *thread);
void Sys_DetachThread(void *thread);
#define THREADP_IDLE -5 #define THREADP_IDLE -5
#define THREADP_NORMAL 0 #define THREADP_NORMAL 0

View file

@ -207,6 +207,12 @@ void World_ODE_Init(void);
void World_ODE_Start(world_t *world); void World_ODE_Start(world_t *world);
void World_ODE_End(world_t *world); void World_ODE_End(world_t *world);
void World_ODE_Shutdown(void); void World_ODE_Shutdown(void);
qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, float *mat, wedict_t *ed);
void World_ODE_RagDestroyBody(world_t *world, odebody_t *bodyptr);
void World_ODE_RagMatrixFromBody(world_t *world, odebody_t *bodyptr, float *mat);
void World_ODE_RagCreateJoint(world_t *world, odejoint_t *joint, odejointinfo_t *info, odebody_t *body1, odebody_t *body2, vec3_t aaa2[3]);
void World_ODE_RagDestroyJoint(world_t *world, odejoint_t *joint);
#endif #endif
void World_ClearWorld (world_t *w); void World_ClearWorld (world_t *w);

View file

@ -13,7 +13,7 @@ extern ID3D11DeviceContext *d3ddevctx;
//#define d3dcheck(foo) foo //#define d3dcheck(foo) foo
#define d3dcheck(foo) do{HRESULT err = foo; if (FAILED(err)) Sys_Error("D3D reported error on backend line %i - error 0x%x\n", __LINE__, (unsigned int)err);} while(0) #define d3dcheck(foo) do{HRESULT err = foo; if (FAILED(err)) Sys_Error("D3D reported error on backend line %i - error 0x%x\n", __LINE__, (unsigned int)err);} while(0)
#define MAX_TMUS 8 #define MAX_TMUS 16
extern float d3d_trueprojection[16]; extern float d3d_trueprojection[16];
@ -1542,9 +1542,9 @@ static void BE_SubmitMeshChain(int idxfirst)
static void BE_ApplyUniforms(program_t *prog, int permu) static void BE_ApplyUniforms(program_t *prog, int permu)
{ {
//FIXME: how many of these calls can we avoid? //FIXME: how many of these calls can we avoid?
ID3D11DeviceContext_IASetInputLayout(d3ddevctx, prog->handle[permu].hlsl.layout); ID3D11DeviceContext_IASetInputLayout(d3ddevctx, prog->permu[permu].handle.hlsl.layout);
ID3D11DeviceContext_VSSetShader(d3ddevctx, prog->handle[permu].hlsl.vert, NULL, 0); ID3D11DeviceContext_VSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.vert, NULL, 0);
ID3D11DeviceContext_PSSetShader(d3ddevctx, prog->handle[permu].hlsl.frag, NULL, 0); ID3D11DeviceContext_PSSetShader(d3ddevctx, prog->permu[permu].handle.hlsl.frag, NULL, 0);
ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ID3D11DeviceContext_IASetPrimitiveTopology(d3ddevctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ID3D11DeviceContext_VSSetConstantBuffers(d3ddevctx, 0, sizeof(shaderstate.cbuffers)/sizeof(shaderstate.cbuffers[0]), shaderstate.cbuffers); ID3D11DeviceContext_VSSetConstantBuffers(d3ddevctx, 0, sizeof(shaderstate.cbuffers)/sizeof(shaderstate.cbuffers[0]), shaderstate.cbuffers);
@ -1558,15 +1558,15 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
program_t *p = s->prog; program_t *p = s->prog;
if (TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_BUMPMAP].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.hlsl.vert)
perm |= PERMUTATION_BUMPMAP; perm |= PERMUTATION_BUMPMAP;
if (TEXVALID(shaderstate.curtexnums->specular) && p->handle[perm|PERMUTATION_SPECULAR].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->specular) && p->permu[perm|PERMUTATION_SPECULAR].handle.hlsl.vert)
perm |= PERMUTATION_SPECULAR; perm |= PERMUTATION_SPECULAR;
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->handle[perm|PERMUTATION_FULLBRIGHT].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.hlsl.vert)
perm |= PERMUTATION_FULLBRIGHT; perm |= PERMUTATION_FULLBRIGHT;
if (p->handle[perm|PERMUTATION_UPPERLOWER].hlsl.vert && (TEXVALID(shaderstate.curtexnums->upperoverlay) || TEXVALID(shaderstate.curtexnums->loweroverlay))) if (p->permu[perm|PERMUTATION_UPPERLOWER].handle.hlsl.vert && (TEXVALID(shaderstate.curtexnums->upperoverlay) || TEXVALID(shaderstate.curtexnums->loweroverlay)))
perm |= PERMUTATION_UPPERLOWER; perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.gfog_rgbd[3] && p->handle[perm|PERMUTATION_FOG].hlsl.vert) if (r_refdef.gfog_rgbd[3] && p->permu[perm|PERMUTATION_FOG].handle.hlsl.vert)
perm |= PERMUTATION_FOG; perm |= PERMUTATION_FOG;
// if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert) // if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert)
// perm |= PERMUTATION_OFFSET; // perm |= PERMUTATION_OFFSET;
@ -2449,6 +2449,7 @@ static entity_t *R_NearestPortal(plane_t *plane)
int i; int i;
entity_t *best = NULL; entity_t *best = NULL;
float dist, bestd = 0; float dist, bestd = 0;
//for q3-compat, portals on world scan for a visedict to use for their view.
for (i = 0; i < cl_numvisedicts; i++) for (i = 0; i < cl_numvisedicts; i++)
{ {
if (cl_visedicts[i].rtype == RT_PORTALSURFACE) if (cl_visedicts[i].rtype == RT_PORTALSURFACE)

View file

@ -125,8 +125,11 @@ static void *D3D11_AllocNewTextureData(void *datargba, int width, int height, un
} }
texid_t D3D11_AllocNewTexture(char *ident, int width, int height, unsigned int flags) texid_t D3D11_AllocNewTexture(char *ident, int width, int height, unsigned int flags)
{ {
d3d11texture_t *t;
void *img = D3D11_AllocNewTextureData(NULL, width, height, flags); void *img = D3D11_AllocNewTextureData(NULL, width, height, flags);
d3d11texture_t *t = d3d_lookup_texture(""); if (!img)
return r_nulltex;
t = d3d_lookup_texture("");
t->tex2d = img; t->tex2d = img;
return ToTexID(t); return ToTexID(t);
@ -207,6 +210,8 @@ static void Upload_Texture_32(ID3D11Texture2D *tex, unsigned int *data, int widt
// D3D11_MAPPED_SUBRESOURCE lock; // D3D11_MAPPED_SUBRESOURCE lock;
D3D11_TEXTURE2D_DESC desc; D3D11_TEXTURE2D_DESC desc;
if (!tex)
return;
ID3D11Texture2D_GetDesc(tex, &desc); ID3D11Texture2D_GetDesc(tex, &desc);
if (width == desc.Width && height == desc.Height) if (width == desc.Width && height == desc.Height)

View file

@ -138,9 +138,9 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, int permu
ID3DBlob *vcode = NULL, *fcode = NULL, *errors = NULL; ID3DBlob *vcode = NULL, *fcode = NULL, *errors = NULL;
qboolean success = false; qboolean success = false;
prog->handle[permu].hlsl.vert = NULL; prog->permu[permu].handle.hlsl.vert = NULL;
prog->handle[permu].hlsl.frag = NULL; prog->permu[permu].handle.hlsl.frag = NULL;
prog->handle[permu].hlsl.layout = NULL; prog->permu[permu].handle.hlsl.layout = NULL;
if (pD3DCompile) if (pD3DCompile)
{ {
@ -176,7 +176,7 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, int permu
success = false; success = false;
else else
{ {
if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), NULL, (ID3D11VertexShader**)&prog->handle[permu].hlsl.vert))) if (FAILED(ID3D11Device_CreateVertexShader(pD3DDev11, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), NULL, (ID3D11VertexShader**)&prog->permu[permu].handle.hlsl.vert)))
success = false; success = false;
} }
if (errors) if (errors)
@ -191,7 +191,7 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, int permu
success = false; success = false;
else else
{ {
if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fcode->lpVtbl->GetBufferPointer(fcode), fcode->lpVtbl->GetBufferSize(fcode), NULL, (ID3D11PixelShader**)&prog->handle[permu].hlsl.frag))) if (FAILED(ID3D11Device_CreatePixelShader(pD3DDev11, fcode->lpVtbl->GetBufferPointer(fcode), fcode->lpVtbl->GetBufferSize(fcode), NULL, (ID3D11PixelShader**)&prog->permu[permu].handle.hlsl.frag)))
success = false; success = false;
} }
if (errors) if (errors)
@ -291,7 +291,7 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, int permu
decl[elements].InstanceDataStepRate = 0; decl[elements].InstanceDataStepRate = 0;
elements++; elements++;
*/ */
if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), (ID3D11InputLayout**)&prog->handle[permu].hlsl.layout))) if (FAILED(ID3D11Device_CreateInputLayout(pD3DDev11, decl, elements, vcode->lpVtbl->GetBufferPointer(vcode), vcode->lpVtbl->GetBufferSize(vcode), (ID3D11InputLayout**)&prog->permu[permu].handle.hlsl.layout)))
{ {
Con_Printf("HLSL Shader %s requires unsupported inputs\n", name); Con_Printf("HLSL Shader %s requires unsupported inputs\n", name);
success = false; success = false;

View file

@ -33,7 +33,11 @@ Things to improve:
#define FORCESTATE
#ifdef FORCESTATE
#pragma warningmsg("D3D9 FORCESTATE is active")
#endif
extern LPDIRECT3DDEVICE9 pD3DDev9; extern LPDIRECT3DDEVICE9 pD3DDev9;
@ -41,7 +45,9 @@ extern LPDIRECT3DDEVICE9 pD3DDev9;
//#define d3dcheck(foo) foo //#define d3dcheck(foo) foo
#define d3dcheck(foo) do{HRESULT err = foo; if (FAILED(err)) Sys_Error("D3D reported error on backend line %i - error 0x%x\n", __LINE__, (unsigned int)err);} while(0) #define d3dcheck(foo) do{HRESULT err = foo; if (FAILED(err)) Sys_Error("D3D reported error on backend line %i - error 0x%x\n", __LINE__, (unsigned int)err);} while(0)
#define MAX_TMUS 4 #define MAX_TMUS 16
#define MAX_TC_TMUS 4
extern float d3d_trueprojection[16]; extern float d3d_trueprojection[16];
@ -179,8 +185,8 @@ typedef struct
unsigned int dynxyz_offs; unsigned int dynxyz_offs;
unsigned int dynxyz_size; unsigned int dynxyz_size;
IDirect3DVertexBuffer9 *dynst_buff[MAX_TMUS]; IDirect3DVertexBuffer9 *dynst_buff[MAX_TC_TMUS];
unsigned int dynst_offs[MAX_TMUS]; unsigned int dynst_offs[MAX_TC_TMUS];
unsigned int dynst_size; unsigned int dynst_size;
IDirect3DVertexBuffer9 *dyncol_buff; IDirect3DVertexBuffer9 *dyncol_buff;
@ -304,7 +310,11 @@ static void BE_ApplyShaderBits(unsigned int bits)
} }
} }
#ifdef FORCESTATE
delta = ~0;
#else
delta = bits ^ shaderstate.shaderbits; delta = bits ^ shaderstate.shaderbits;
#endif
if (!delta) if (!delta)
return; return;
shaderstate.shaderbits = bits; shaderstate.shaderbits = bits;
@ -433,7 +443,7 @@ void D3D9BE_Reset(qboolean before)
if (shaderstate.dynxyz_buff) if (shaderstate.dynxyz_buff)
IDirect3DVertexBuffer9_Release(shaderstate.dynxyz_buff); IDirect3DVertexBuffer9_Release(shaderstate.dynxyz_buff);
shaderstate.dynxyz_buff = NULL; shaderstate.dynxyz_buff = NULL;
for (tmu = 0; tmu < MAX_TMUS; tmu++) for (tmu = 0; tmu < MAX_TC_TMUS; tmu++)
{ {
if (shaderstate.dynst_buff[tmu]) if (shaderstate.dynst_buff[tmu])
IDirect3DVertexBuffer9_Release(shaderstate.dynst_buff[tmu]); IDirect3DVertexBuffer9_Release(shaderstate.dynst_buff[tmu]);
@ -507,7 +517,7 @@ void D3D9BE_Reset(qboolean before)
elements++; elements++;
} }
for (tmu = 0; tmu < MAX_TMUS; tmu++) for (tmu = 0; tmu < MAX_TC_TMUS; tmu++)
{ {
if (i & (D3D_VDEC_ST0<<tmu)) if (i & (D3D_VDEC_ST0<<tmu))
{ {
@ -547,7 +557,7 @@ void D3D9BE_Reset(qboolean before)
} }
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynxyz_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynxyz_buff, NULL); IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynxyz_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynxyz_buff, NULL);
for (tmu = 0; tmu < MAX_TMUS; tmu++) for (tmu = 0; tmu < D3D_VDEC_ST0; tmu++)
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynst_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynst_buff[tmu], NULL); IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dynst_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dynst_buff[tmu], NULL);
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dyncol_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dyncol_buff, NULL); IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, shaderstate.dyncol_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &shaderstate.dyncol_buff, NULL);
IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, shaderstate.dynidx_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFMT_QINDEX, D3DPOOL_DEFAULT, &shaderstate.dynidx_buff, NULL); IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, shaderstate.dynidx_size, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFMT_QINDEX, D3DPOOL_DEFAULT, &shaderstate.dynidx_buff, NULL);
@ -1655,25 +1665,27 @@ static void BE_SubmitMeshChain(int idxfirst)
static void BE_ApplyUniforms(program_t *prog, int permu) static void BE_ApplyUniforms(program_t *prog, int permu)
{ {
int h;
int i; int i;
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->handle[permu].hlsl.vert); IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->permu[permu].handle.hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[permu].hlsl.frag); IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[permu].handle.hlsl.frag);
for (i = 0; i < prog->numparams; i++) for (i = 0; i < prog->numparams; i++)
{ {
h = prog->permu[permu].parm[i];
switch (prog->parm[i].type) switch (prog->parm[i].type)
{ {
case SP_M_PROJECTION: case SP_M_PROJECTION:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], d3d_trueprojection, 4); IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, d3d_trueprojection, 4);
break; break;
case SP_M_VIEW: case SP_M_VIEW:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_refdef.m_view, 4); IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, r_refdef.m_view, 4);
break; break;
// case SP_M_MODEL: // case SP_M_MODEL:
// IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_refdef.m_view, 4); // IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, r_refdef.m_view, 4);
// break; // break;
case SP_V_EYEPOS: case SP_V_EYEPOS:
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_origin, 1); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, r_origin, 1);
break; break;
case SP_E_EYEPOS: case SP_E_EYEPOS:
{ {
@ -1681,13 +1693,13 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
float m16[16]; float m16[16];
Matrix4x4_CM_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin); Matrix4x4_CM_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin);
Matrix4x4_CM_Transform3(m16, r_origin, t2); Matrix4x4_CM_Transform3(m16, r_origin, t2);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t2, 1); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, t2, 1);
} }
break; break;
case SP_E_TIME: case SP_E_TIME:
{ {
vec4_t t1 = {shaderstate.curtime}; vec4_t t1 = {shaderstate.curtime};
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t1, 1); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, t1, 1);
} }
break; break;
case SP_M_MODELVIEWPROJECTION: case SP_M_MODELVIEWPROJECTION:
@ -1695,7 +1707,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
float mv[16], mvp[16]; float mv[16], mvp[16];
Matrix4_Multiply(r_refdef.m_view, shaderstate.m_model, mv); Matrix4_Multiply(r_refdef.m_view, shaderstate.m_model, mv);
Matrix4_Multiply(d3d_trueprojection, mv, mvp); Matrix4_Multiply(d3d_trueprojection, mv, mvp);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], mvp, 4); IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, mvp, 4);
} }
break; break;
@ -1708,15 +1720,15 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
Matrix4_Invert(shaderstate.m_model, inv); Matrix4_Invert(shaderstate.m_model, inv);
Matrix4x4_CM_Transform3(inv, shaderstate.curdlight->origin, t2); Matrix4x4_CM_Transform3(inv, shaderstate.curdlight->origin, t2);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t2, 3); IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, t2, 3);
break; break;
} }
case SP_LIGHTRADIUS: case SP_LIGHTRADIUS:
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], &shaderstate.curdlight->radius, 1); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, &shaderstate.curdlight->radius, 1);
break; break;
case SP_LIGHTCOLOUR: case SP_LIGHTCOLOUR:
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], shaderstate.curdlight_colours, 3); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, h, shaderstate.curdlight_colours, 3);
break; break;
case SP_E_COLOURS: case SP_E_COLOURS:
@ -1754,15 +1766,15 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned i
program_t *p = s->prog; program_t *p = s->prog;
if (TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_BUMPMAP].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].handle.hlsl.vert)
perm |= PERMUTATION_BUMPMAP; perm |= PERMUTATION_BUMPMAP;
if (TEXVALID(shaderstate.curtexnums->specular) && p->handle[perm|PERMUTATION_SPECULAR].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->specular) && p->permu[perm|PERMUTATION_SPECULAR].handle.hlsl.vert)
perm |= PERMUTATION_SPECULAR; perm |= PERMUTATION_SPECULAR;
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->handle[perm|PERMUTATION_FULLBRIGHT].hlsl.vert) if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].handle.hlsl.vert)
perm |= PERMUTATION_FULLBRIGHT; perm |= PERMUTATION_FULLBRIGHT;
if (p->handle[perm|PERMUTATION_UPPERLOWER].hlsl.vert && (TEXVALID(shaderstate.curtexnums->upperoverlay) || TEXVALID(shaderstate.curtexnums->loweroverlay))) if (p->permu[perm|PERMUTATION_UPPERLOWER].handle.hlsl.vert && (TEXVALID(shaderstate.curtexnums->upperoverlay) || TEXVALID(shaderstate.curtexnums->loweroverlay)))
perm |= PERMUTATION_UPPERLOWER; perm |= PERMUTATION_UPPERLOWER;
if (r_refdef.gfog_rgbd[3] && p->handle[perm|PERMUTATION_FOG].hlsl.vert) if (r_refdef.gfog_rgbd[3] && p->permu[perm|PERMUTATION_FOG].handle.hlsl.vert)
perm |= PERMUTATION_FOG; perm |= PERMUTATION_FOG;
// if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert) // if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert)
// perm |= PERMUTATION_OFFSET; // perm |= PERMUTATION_OFFSET;

View file

@ -155,14 +155,14 @@ void D3D9Shader_Init(void)
return; return;
} }
qboolean D3D9Shader_CreateProgram (program_t *prog, int permu, char **precompilerconstants, char *vert, char *frag) qboolean D3D9Shader_CreateProgram (program_t *prog, char *sname, int permu, char **precompilerconstants, char *vert, char *frag)
{ {
D3DXMACRO defines[64]; D3DXMACRO defines[64];
LPD3DXBUFFER code = NULL, errors = NULL; LPD3DXBUFFER code = NULL, errors = NULL;
qboolean success = false; qboolean success = false;
prog->handle[permu].hlsl.vert = NULL; prog->permu[permu].handle.hlsl.vert = NULL;
prog->handle[permu].hlsl.frag = NULL; prog->permu[permu].handle.hlsl.frag = NULL;
if (pD3DXCompileShader) if (pD3DXCompileShader)
{ {
@ -194,32 +194,32 @@ qboolean D3D9Shader_CreateProgram (program_t *prog, int permu, char **precompile
success = true; success = true;
defines[0].Name = "VERTEX_SHADER"; defines[0].Name = "VERTEX_SHADER";
if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->handle[permu].hlsl.ctabv))) if (FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].handle.hlsl.ctabv)))
success = false; success = false;
else else
{ {
IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&prog->handle[permu].hlsl.vert); IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&prog->permu[permu].handle.hlsl.vert);
code->lpVtbl->Release(code); code->lpVtbl->Release(code);
} }
if (errors) if (errors)
{ {
char *messages = errors->lpVtbl->GetBufferPointer(errors); char *messages = errors->lpVtbl->GetBufferPointer(errors);
Con_Printf("%s", messages); Con_Printf("Error compiling vertex shader %s:\n%s", sname, messages);
errors->lpVtbl->Release(errors); errors->lpVtbl->Release(errors);
} }
defines[0].Name = "FRAGMENT_SHADER"; defines[0].Name = "FRAGMENT_SHADER";
if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->handle[permu].hlsl.ctabf))) if (FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->permu[permu].handle.hlsl.ctabf)))
success = false; success = false;
else else
{ {
IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&prog->handle[permu].hlsl.frag); IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&prog->permu[permu].handle.hlsl.frag);
code->lpVtbl->Release(code); code->lpVtbl->Release(code);
} }
if (errors) if (errors)
{ {
char *messages = errors->lpVtbl->GetBufferPointer(errors); char *messages = errors->lpVtbl->GetBufferPointer(errors);
Con_Printf("%s", messages); Con_Printf("Error compiling pixel shader %s:\n%s", sname, messages);
errors->lpVtbl->Release(errors); errors->lpVtbl->Release(errors);
} }
} }

View file

@ -2,6 +2,7 @@ Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005 # Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftequake", "ftequake.vcproj", "{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftequake", "ftequake.vcproj", "{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{32B12987-DF8C-4E40-B07C-B18586A4CA65} = {32B12987-DF8C-4E40-B07C-B18586A4CA65}
{0018E098-B12A-4E4D-9B22-6772DA287080} = {0018E098-B12A-4E4D-9B22-6772DA287080} {0018E098-B12A-4E4D-9B22-6772DA287080} = {0018E098-B12A-4E4D-9B22-6772DA287080}
EndProjectSection EndProjectSection
EndProject EndProject
@ -26,7 +27,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "berkelium", "..\..\plugins\berkelium\berkelium.vcproj", "{4877586B-E85B-4DF8-BCCE-59D31514D240}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "berkplug", "..\..\plugins\berkelium\berkelium.vcproj", "{4877586B-E85B-4DF8-BCCE-59D31514D240}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "avplug", "..\..\plugins\avplug\avplug.vcproj", "{32B12987-DF8C-4E40-B07C-B18586A4CA65}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -56,8 +59,8 @@ Global
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.ActiveCfg = D3DRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.ActiveCfg = D3DDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.Build.0 = D3DRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.Build.0 = D3DDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.ActiveCfg = D3DDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.ActiveCfg = D3DDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.Build.0 = D3DDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.Build.0 = D3DDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DRelease|Win32.ActiveCfg = D3DRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DRelease|Win32.ActiveCfg = D3DRelease|Win32
@ -76,6 +79,7 @@ Global
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.ActiveCfg = GLDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.Build.0 = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.Build.0 = GLDebug|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|Win32.Build.0 = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|x64.ActiveCfg = GLRelease|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLRelease|x64.Build.0 = GLRelease|x64
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MDebug|Win32.ActiveCfg = MDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.MDebug|Win32.ActiveCfg = MDebug|Win32
@ -144,6 +148,7 @@ Global
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.Build.0 = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.ActiveCfg = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|x64.ActiveCfg = GLRelease|Win32
@ -349,7 +354,6 @@ Global
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.Build.0 = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.Build.0 = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|x64.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|Win32.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|Win32.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|Win32.Build.0 = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLDebug|x64.ActiveCfg = Debug|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|Win32.ActiveCfg = Release|Win32
{873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.GLRelease|x64.ActiveCfg = Release|Win32
@ -383,7 +387,6 @@ Global
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.Build.0 = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|Win32.Build.0 = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLDebug|x64.ActiveCfg = Debug|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.GLRelease|x64.ActiveCfg = Release|Win32
@ -405,6 +408,41 @@ Global
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.ActiveCfg = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.Build.0 = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|Win32.Build.0 = Release|Win32
{4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Release|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|Win32.Build.0 = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DDebug|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.Build.0 = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLDebug|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLDebug|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.GLRelease|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|Win32.Build.0 = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MDebug|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|Win32.Build.0 = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLDebug|x64.ActiveCfg = Debug|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MinGLRelease|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.MRelease|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release|Win32.ActiveCfg = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release|Win32.Build.0 = Release|Win32
{32B12987-DF8C-4E40-B07C-B18586A4CA65}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View file

@ -249,7 +249,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../d3d9;../libs/dxsdk9/include;../libs/dxsdk7/include" AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../d3d9;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;D3D9QUAKE;WIN32;_WINDOWS" PreprocessorDefinitions="_DEBUG;D3D9QUAKE;D3D11QUAKE;WIN32;_WINDOWS"
RuntimeLibrary="1" RuntimeLibrary="1"
FloatingPointModel="2" FloatingPointModel="2"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
@ -4944,6 +4944,169 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="..\server\sv_sql.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\server\sv_user.c" RelativePath="..\server\sv_user.c"
> >
@ -9659,6 +9822,14 @@
<File <File
RelativePath="..\client\in_generic.c" RelativePath="..\client\in_generic.c"
> >
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\client\in_win.c" RelativePath="..\client\in_win.c"
@ -20680,6 +20851,170 @@
/> />
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath="..\gl\gl_vidmacos.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File <File
RelativePath="..\client\in_macos.c" RelativePath="..\client\in_macos.c"
> >

File diff suppressed because it is too large Load diff

View file

@ -40,39 +40,149 @@ public class FTEDroidActivity extends Activity
private Sensor sensoracc; private Sensor sensoracc;
private FTEView view; private FTEView view;
float acc_x, acc_y, acc_z; /*might be some minor race condition on these*/ float acc_x, acc_y, acc_z; /*might be some minor race condition on these*/
private String basedir, userdir;
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
{
int version;
public void setversion(FTEView view, int version)
{
this.version = version;
view.setEGLContextClientVersion(version);
}
public boolean CheckGLES2Support()
{
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
EGLConfig cfg;
int oldver = this.version;
int[] version = new int[2];
egl.eglInitialize(display, version);
this.version = 2;
cfg = chooseConfig(egl, display);
this.version = oldver;
int[] value = {0};
egl.eglGetConfigAttrib(display, cfg, EGL10.EGL_RENDERABLE_TYPE, value);
egl.eglTerminate(display);
return ((value[0] & 4) == 4);
}
@Override
public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display)
{
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
EGLConfig[] cfg = new EGLConfig[64];
int[] num_configs = {0};
int[] value = {0};
int i;
int[] attribs =
{
egl.EGL_RENDERABLE_TYPE, (version>=2?4:1)/*egl.EGL_OPENGL_ES2_BIT*/,
// egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_BLUE_SIZE, 5,
egl.EGL_GREEN_SIZE, 6,
egl.EGL_RED_SIZE, 5,
egl.EGL_DEPTH_SIZE, 16,
// egl.EGL_STENCIL_SIZE, 8,
egl.EGL_NONE, egl.EGL_NONE
};
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
attribs[1] = 1; //egl.EGL_RENDERABLE_TYPE, 1/*egl.EGL_OPENGL_ES_BIT*/,
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
throw new IllegalArgumentException("eglChooseConfig didn't report any valid configs");
}
}
android.util.Log.i("FTEDroid", "Found " + num_configs[0] + " EGL configs.");
//try to find a gles2 context instead.
for (i = 0; i < num_configs[0]; i++)
{
android.util.Log.i("FTEDroid", "Config " + i + ":");
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RED_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_RED_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_GREEN_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_GREEN_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_BLUE_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_BLUE_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_DEPTH_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_DEPTH_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_STENCIL_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_STENCIL_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RENDERABLE_TYPE, value);
android.util.Log.i("FTEDroid", "EGL_RENDERABLE_TYPE " + value[0]);
if ((value[0] & 4) == 4)
{
android.util.Log.i("FTEDroid", "Found a GLES2 context!");
return cfg[i];
}
}
return cfg[0];
}
}
private class FTERenderer implements GLSurfaceView.Renderer private class FTERenderer implements GLSurfaceView.Renderer
{ {
private boolean inited; private boolean inited;
public int glesversion; public int glesversion;
private String basedir, userdir;
FTEDroidActivity act; FTEDroidActivity act;
FTEView theview; FTEView theview;
FTEEGLConfig cfgchooser;
int notifiedflags; int notifiedflags;
void updateGLESVersion()
{
if (FTEDroidEngine.getpreferedglesversion() < 2)
{
android.util.Log.i("FTEDroid", "Using GLES1");
this.glesversion = 1;
}
else if (android.os.Build.VERSION.SDK_INT >= 8) //could be 5 with setEGLContextFactory instead of setEGLContextClientVersion
{
if (cfgchooser.CheckGLES2Support())
{
android.util.Log.i("FTEDroid", "Support for GLES2 detected");
this.glesversion = 2;
cfgchooser.setversion(theview, this.glesversion);
}
else
{
android.util.Log.i("FTEDroid", "GLES2 not supported. Using GLES1.");
this.glesversion = 1;
}
}
else
{
android.util.Log.i("FTEDroid", "GLES2 requires android 2.2+");
this.glesversion = 1;
}
}
FTERenderer(FTEView view, FTEDroidActivity parent) FTERenderer(FTEView view, FTEDroidActivity parent)
{ {
act = parent; act = parent;
theview = view; theview = view;
try
{
android.content.pm.PackageInfo info = parent.getPackageManager().getPackageInfo("com.fteqw", 0);
basedir = info.applicationInfo.sourceDir;
}
catch(android.content.pm.PackageManager.NameNotFoundException e)
{
/*oh well, can just use the homedir instead*/
}
// try
// {
userdir = Environment.getExternalStorageDirectory().getPath() + "/fte";
// }
// catch(foo)
// {
// }
android.util.Log.i("FTEDroid", "Base dir is \"" + basedir + "\"."); FTEDroidEngine.init(0, 0, 0, basedir, userdir);
android.util.Log.i("FTEDroid", "User dir is \"" + userdir + "\"."); inited = true;
cfgchooser = new FTEEGLConfig();
// theview.setEGLConfigChooser(cfgchooser);
updateGLESVersion();
} }
@Override @Override
@ -140,7 +250,17 @@ public class FTEDroidActivity extends Activity
act.runOnUiThread(r); act.runOnUiThread(r);
} }
if (((flags ^ notifiedflags) & 8) != 0) if (((flags ^ notifiedflags) & 8) != 0)
{ {
final String errormsg = FTEDroidEngine.geterrormessage();
inited = false;
if (errormsg == "")
{
finish();
System.exit(0);
}
//8 means sys error //8 means sys error
Runnable r = new Runnable() Runnable r = new Runnable()
{ {
@ -149,7 +269,7 @@ public class FTEDroidActivity extends Activity
theview.setVisibility(theview.GONE); theview.setVisibility(theview.GONE);
AlertDialog ad = new AlertDialog.Builder(act).create(); AlertDialog ad = new AlertDialog.Builder(act).create();
ad.setTitle("FTE ERROR"); ad.setTitle("FTE ERROR");
ad.setMessage(FTEDroidEngine.geterrormessage()); ad.setMessage(errormsg);
ad.setCancelable(false); ad.setCancelable(false);
ad.setButton("Ok", new DialogInterface.OnClickListener() ad.setButton("Ok", new DialogInterface.OnClickListener()
{ {
@ -166,7 +286,8 @@ public class FTEDroidActivity extends Activity
act.runOnUiThread(r); act.runOnUiThread(r);
} }
if (((flags ^ notifiedflags) & 16) != 0) if (((flags ^ notifiedflags) & 16) != 0)
{ {
//16 means orientation cvar change
Runnable r = new Runnable() Runnable r = new Runnable()
{ {
public void run() public void run()
@ -231,93 +352,6 @@ public class FTEDroidActivity extends Activity
} }
} }
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
{
public void setversion(FTEView view, int version)
{
view.setEGLContextClientVersion(version);
}
public boolean CheckGLES2Support()
{
EGL10 egl = (EGL10) EGLContext.getEGL();
EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
EGLConfig cfg;
int[] version = new int[2];
egl.eglInitialize(display, version);
cfg = chooseConfig(egl, display);
int[] value = {0};
egl.eglGetConfigAttrib(display, cfg, EGL10.EGL_RENDERABLE_TYPE, value);
egl.eglTerminate(display);
return ((value[0] & 4) == 4);
}
@Override
public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display)
{
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
EGLConfig[] cfg = new EGLConfig[64];
int[] num_configs = {0};
int[] value = {0};
int i;
int[] attribs =
{
egl.EGL_RENDERABLE_TYPE, 4/*egl.EGL_OPENGL_ES2_BIT*/,
// egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
egl.EGL_BLUE_SIZE, 5,
egl.EGL_GREEN_SIZE, 6,
egl.EGL_RED_SIZE, 5,
egl.EGL_DEPTH_SIZE, 16,
// egl.EGL_STENCIL_SIZE, 8,
egl.EGL_NONE, egl.EGL_NONE
};
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
attribs[1] = 1; //egl.EGL_RENDERABLE_TYPE, 1/*egl.EGL_OPENGL_ES_BIT*/,
if (!egl.eglChooseConfig(display, attribs, cfg, 64, num_configs))
throw new IllegalArgumentException("eglChooseConfig failed");
if (num_configs[0] == 0)
{
throw new IllegalArgumentException("eglChooseConfig didn't report any valid configs");
}
}
android.util.Log.i("FTEDroid", "Found " + num_configs[0] + " EGL configs.");
for (i = 0; i < num_configs[0]; i++)
{
android.util.Log.i("FTEDroid", "Config " + i + ":");
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RED_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_RED_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_GREEN_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_GREEN_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_BLUE_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_BLUE_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_DEPTH_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_DEPTH_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_STENCIL_SIZE, value);
android.util.Log.i("FTEDroid", "EGL_STENCIL_SIZE " + value[0]);
egl.eglGetConfigAttrib(display, cfg[i], egl.EGL_RENDERABLE_TYPE, value);
android.util.Log.i("FTEDroid", "EGL_RENDERABLE_TYPE " + value[0]);
if ((value[0] & 4) == 4)
{
android.util.Log.i("FTEDroid", "Found a GLES2 context!");
return cfg[i];
}
}
return cfg[0];
}
}
private class FTEView extends GLSurfaceView implements SensorEventListener private class FTEView extends GLSurfaceView implements SensorEventListener
{ {
private final FTERenderer rndr; private final FTERenderer rndr;
@ -334,26 +368,35 @@ public class FTEDroidActivity extends Activity
{ {
byte[] audbuf = new byte[2048]; byte[] audbuf = new byte[2048];
int avail; int avail;
AudioTrack at;
int chans; int chans;
if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+ try
chans = AudioFormat.CHANNEL_OUT_7POINT1; {
else if (schannels >= 6) if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+
chans = AudioFormat.CHANNEL_OUT_5POINT1; chans = AudioFormat.CHANNEL_OUT_7POINT1;
else if (schannels >= 4) else if (schannels >= 6)
chans = AudioFormat.CHANNEL_OUT_QUAD; chans = AudioFormat.CHANNEL_OUT_5POINT1;
else if (schannels >= 2) else if (schannels >= 4)
chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO; chans = AudioFormat.CHANNEL_OUT_QUAD;
else else if (schannels >= 2)
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO; chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
int enc = (sbits == 8)?AudioFormat.ENCODING_PCM_8BIT:AudioFormat.ENCODING_PCM_16BIT; else
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int sz = 2*AudioTrack.getMinBufferSize(sspeed, chans, enc); int enc = (sbits == 8)?AudioFormat.ENCODING_PCM_8BIT:AudioFormat.ENCODING_PCM_16BIT;
int sz = 2*AudioTrack.getMinBufferSize(sspeed, chans, enc);
// if (sz < sspeed * 0.05) // if (sz < sspeed * 0.05)
// sz = sspeed * 0.05; // sz = sspeed * 0.05;
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, chans, enc, sz, AudioTrack.MODE_STREAM); at = new AudioTrack(AudioManager.STREAM_MUSIC, sspeed, chans, enc, sz, AudioTrack.MODE_STREAM);
}
catch(IllegalArgumentException e)
{
//fixme: tell the engine that its bad and that it should configure some different audio attributes, instead of simply muting.
return;
}
at.setStereoVolume(1, 1); at.setStereoVolume(1, 1);
at.play(); at.play();
@ -494,35 +537,6 @@ public class FTEDroidActivity extends Activity
inputevent = new FTELegacyInputEvent(); inputevent = new FTELegacyInputEvent();
rndr = new FTERenderer(this, context); rndr = new FTERenderer(this, context);
if (USE_GLES_VERSION < 2)
{
android.util.Log.i("FTEDroid", "GLES2 disabled at game compile time");
rndr.glesversion = 1;
}
else if (android.os.Build.VERSION.SDK_INT >= 8) //could be 5 with setEGLContextFactory instead of setEGLContextClientVersion
{
FTEEGLConfig cfgchooser = new FTEEGLConfig();
setEGLConfigChooser(cfgchooser);
if (cfgchooser.CheckGLES2Support())
{
android.util.Log.i("FTEDroid", "Support for GLES2 detected");
rndr.glesversion = 2;
cfgchooser.setversion(this, rndr.glesversion);
}
else
{
android.util.Log.i("FTEDroid", "GLES2 not supported. Using GLES1.");
rndr.glesversion = 1;
}
}
else
{
android.util.Log.i("FTEDroid", "GLES2 requires android 2.2+");
rndr.glesversion = 1;
}
setRenderer(rndr); setRenderer(rndr);
setFocusable(true); setFocusable(true);
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
@ -632,6 +646,28 @@ public class FTEDroidActivity extends Activity
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
android.util.Log.i("FTEDroid", "onCreate"); android.util.Log.i("FTEDroid", "onCreate");
try
{
String packagename = this.getComponentName().getPackageName(); //"com.fteqw", but not hardcoded.
android.util.Log.i("FTEDroid", "Installed in package \"" + packagename + "\".");
android.content.pm.PackageInfo info = this.getPackageManager().getPackageInfo(packagename, 0);
basedir = info.applicationInfo.sourceDir;
}
catch(android.content.pm.PackageManager.NameNotFoundException e)
{
/*oh well, can just use the homedir instead*/
}
// try
// {
userdir = Environment.getExternalStorageDirectory().getPath() + "/fte";
// }
// catch(foo)
// {
// }
android.util.Log.i("FTEDroid", "Base dir is \"" + basedir + "\".");
android.util.Log.i("FTEDroid", "User dir is \"" + userdir + "\".");
//go full-screen //go full-screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);

View file

@ -11,6 +11,7 @@ public class FTEDroidEngine
public static native int audioinfo(int arg); public static native int audioinfo(int arg);
public static native String geterrormessage(); public static native String geterrormessage();
public static native String getpreferedorientation(); public static native String getpreferedorientation();
public static native int getpreferedglesversion();
public static native void newglcontext(); public static native void newglcontext();
static static

View file

@ -938,7 +938,7 @@ void R_GAlias_DrawBatch(batch_t *batch)
{ {
if (batch->surf_first == surfnum) if (batch->surf_first == surfnum)
{ {
needrecolour = Alias_GAliasBuildMesh(&mesh, inf, surfnum, e, true); needrecolour = Alias_GAliasBuildMesh(&mesh, inf, surfnum, e, batch->shader->prog && batch->shader->prog->permu[PERMUTATION_SKELETAL].handle.glsl);
batch->mesh = &meshl; batch->mesh = &meshl;
return; return;
} }
@ -976,7 +976,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
clmodel = e->model; clmodel = e->model;
if (!(e->flags & Q2RF_WEAPONMODEL)) if (!(e->flags & Q2RF_WEAPONMODEL) && !e->framestate.bonestate)
{ {
if (R_CullEntityBox (e, clmodel->mins, clmodel->maxs)) if (R_CullEntityBox (e, clmodel->mins, clmodel->maxs))
return; return;

File diff suppressed because it is too large Load diff

View file

@ -186,8 +186,6 @@ void R_BloomBlend (void)
if (!r_refdef.pxrect.width || !r_refdef.pxrect.height) if (!r_refdef.pxrect.width || !r_refdef.pxrect.height)
return; return;
GL_Set2D(false);
/*update textures if we need to resize them*/ /*update textures if we need to resize them*/
R_SetupBloomTextures(r_refdef.pxrect.width, r_refdef.pxrect.height); R_SetupBloomTextures(r_refdef.pxrect.width, r_refdef.pxrect.height);

View file

@ -380,13 +380,15 @@ void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue)
void GLDraw_ImageList_f(void) void GLDraw_ImageList_f(void)
{ {
int count = 0; int count = 0;
unsigned int mem = 0;
gltexture_t *glt; gltexture_t *glt;
for (glt=gltextures ; glt ; glt=glt->next) for (glt=gltextures ; glt ; glt=glt->next)
{ {
count++; count++;
mem += glt->width * glt->height * 4;
Con_Printf("%s (%i*%i, seq=%i)\n", glt->identifier, glt->width, glt->height, glt->com.regsequence); Con_Printf("%s (%i*%i, seq=%i)\n", glt->identifier, glt->width, glt->height, glt->com.regsequence);
} }
Con_Printf("%i images\n", count); Con_Printf("%i images, %i bytes\n", count, mem);
} }
void GLDraw_FlushOldTextures(void) void GLDraw_FlushOldTextures(void)
@ -493,7 +495,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n")); TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n"));
GL_InitSceneProcessingShaders(); GL_InitSceneProcessingShaders();
Cmd_AddCommand ("r_imagelist", GLDraw_ImageList_f); Cmd_AddCommandD ("r_imagelist", GLDraw_ImageList_f, "Debug command. Reveals current list of loaded images.");
} }
void GLDraw_DeInit (void) void GLDraw_DeInit (void)
@ -1393,15 +1395,9 @@ void GL_Upload24BGR (char *name, qbyte *framedata, int inwidth, int inheight, un
dest = uploadmemorybufferintermediate; dest = uploadmemorybufferintermediate;
//change from bgr bottomup to rgba topdown //change from bgr bottomup to rgba topdown
for (outwidth = 1; outwidth < inwidth; outwidth*=2) outwidth = inwidth;
; outheight = inheight;
for (outheight = 1; outheight < inheight; outheight*=2) GL_RoundDimensions(&outwidth, &outheight, !(flags&IF_NOMIPMAP));
;
if (outwidth > 512)
outwidth = 512;
if (outheight > 512)
outheight = 512;
if (outwidth*outheight > sizeofuploadmemorybufferintermediate/4) if (outwidth*outheight > sizeofuploadmemorybufferintermediate/4)
Sys_Error("GL_Upload24BGR: image too big (%i*%i)", inwidth, inheight); Sys_Error("GL_Upload24BGR: image too big (%i*%i)", inwidth, inheight);
@ -1466,15 +1462,9 @@ void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheigh
dest = uploadmemorybufferintermediate; dest = uploadmemorybufferintermediate;
//change from bgr bottomup to rgba topdown //change from bgr bottomup to rgba topdown
for (outwidth = 1; outwidth < inwidth; outwidth*=2) outwidth = inwidth;
; outheight = inheight;
for (outheight = 1; outheight < inheight; outheight*=2) GL_RoundDimensions(&outwidth, &outheight, !(flags&IF_NOMIPMAP));
;
if (outwidth > 512)
outwidth = 512;
if (outheight > 512)
outheight = 512;
if (outwidth*outheight > sizeofuploadmemorybufferintermediate/4) if (outwidth*outheight > sizeofuploadmemorybufferintermediate/4)
Sys_Error("GL_Upload24BGR_Flip: image too big (%i*%i)", inwidth, inheight); Sys_Error("GL_Upload24BGR_Flip: image too big (%i*%i)", inwidth, inheight);

View file

@ -950,7 +950,7 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
for (i = '!'; i <= '_'; i++) for (i = '!'; i <= '_'; i++)
{ {
dp = NULL; dp = NULL;
FS_LoadFile(va("wad/stcfn%.3d", i), &dp); FS_LoadFile(va("wad/stcfn%.3d", i), (void**)&dp);
if (!dp) if (!dp)
break; break;
@ -1128,6 +1128,12 @@ struct font_s *Font_LoadFont(int height, char *fontfilename)
void Font_Free(struct font_s *f) void Font_Free(struct font_s *f)
{ {
struct charcache_s **link; struct charcache_s **link;
if (f->alt)
{
Font_Free(f->alt);
f->alt = NULL;
}
for (link = &fontplanes.oldestchar; *link; ) for (link = &fontplanes.oldestchar; *link; )
{ {
if (*link >= f->chars && *link <= f->chars + FONTCHARS) if (*link >= f->chars && *link <= f->chars + FONTCHARS)
@ -1195,8 +1201,13 @@ int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode)
if ((charcode&CON_CHARMASK) == '\t') if ((charcode&CON_CHARMASK) == '\t')
return x + ((TABWIDTH - (x % TABWIDTH)) % TABWIDTH); return x + ((TABWIDTH - (x % TABWIDTH)) % TABWIDTH);
if ((charcode & CON_2NDCHARSETTEXT) && font->alt) if (charcode & CON_2NDCHARSETTEXT)
font = font->alt; {
if (font->alt)
font = font->alt;
else if ((charcode & CON_CHARMASK) >= 0x20 && (charcode&CON_CHARMASK) < 0x80)
charcode |= 0xe000;
}
c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
if (!c) if (!c)
@ -1216,8 +1227,13 @@ int Font_CharWidth(unsigned int charcode)
struct font_s *font = curfont; struct font_s *font = curfont;
if (charcode&CON_HIDDEN) if (charcode&CON_HIDDEN)
return 0; return 0;
if ((charcode & CON_2NDCHARSETTEXT) && font->alt) if (charcode & CON_2NDCHARSETTEXT)
font = font->alt; {
if (font->alt)
font = font->alt;
else if ((charcode & CON_CHARMASK) >= 0x20 && (charcode&CON_CHARMASK) < 0x80)
charcode |= 0xe000;
}
c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK));
if (!c) if (!c)
@ -1340,8 +1356,13 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
if (charcode & CON_HIDDEN) if (charcode & CON_HIDDEN)
return px; return px;
if ((charcode & CON_2NDCHARSETTEXT) && font->alt) if (charcode & CON_2NDCHARSETTEXT)
font = font->alt; {
if (font->alt)
font = font->alt;
else if ((charcode & CON_CHARMASK) >= 0x20 && (charcode&CON_CHARMASK) < 0x80)
charcode |= 0xe000;
}
//crash if there is no current font. //crash if there is no current font.
c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK));
@ -1464,8 +1485,13 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
int col; int col;
int v; int v;
struct font_s *font = curfont; struct font_s *font = curfont;
if ((charcode & CON_2NDCHARSETTEXT) && font->alt) if (charcode & CON_2NDCHARSETTEXT)
font = font->alt; {
if (font->alt)
font = font->alt;
else if ((charcode & CON_CHARMASK) >= 0x20 && (charcode&CON_CHARMASK) < 0x80)
charcode |= 0xe000;
}
cw /= font->charheight; cw /= font->charheight;
ch /= font->charheight; ch /= font->charheight;

View file

@ -10,6 +10,17 @@
#define TERRAINTHICKNESS 16 #define TERRAINTHICKNESS 16
#define TERRAINACTIVESECTIONS 1000 #define TERRAINACTIVESECTIONS 1000
/*
a note on networking:
By default terrain is NOT networked. This means content is loaded without networking delays.
If you wish to edit the terrain collaboratively, you can enable the mod_terrain_networked cvar.
When set, changes on the server will notify clients that a section has changed, and the client will reload it as needed.
Changes on the client WILL NOT notify the server, and will get clobbered if the change is also made on the server.
This means for editing purposes, you MUST funnel it via ssqc with your own permission checks.
It also means for explosions and local stuff, the server will merely restate changes from impacts if you do them early. BUT DO NOT CALL THE EDIT FUNCTION IF THE SERVER HAS ALREADY APPLIED THE CHANGE.
*/
cvar_t mod_terrain_networked = CVARD("mod_terrain_networked", "0", "Terrain edits are networked. Clients will download sections on demand, and servers will notify clients of changes.");
//heightmaps work thusly: //heightmaps work thusly:
//there is one raw heightmap file //there is one raw heightmap file
//the file is split to 4*4 sections. //the file is split to 4*4 sections.
@ -258,6 +269,15 @@ static char *Terr_DiskSectionName(heightmap_t *hm, int sx, int sy)
sy &= CHUNKLIMIT-1; sy &= CHUNKLIMIT-1;
return va("maps/%s/sect_%03x_%03x.hms", hm->path, sx, sy); return va("maps/%s/sect_%03x_%03x.hms", hm->path, sx, sy);
} }
static char *Terr_TempDiskSectionName(heightmap_t *hm, int sx, int sy)
{
sx -= CHUNKBIAS;
sy -= CHUNKBIAS;
//wrap cleanly
sx &= CHUNKLIMIT-1;
sy &= CHUNKLIMIT-1;
return va("temp/%s/sect_%03x_%03x.hms", hm->path, sx, sy);
}
static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy) static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy)
{ {
dsection_t *ds = NULL; dsection_t *ds = NULL;
@ -269,6 +289,14 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in
#endif #endif
void *ptr; void *ptr;
if (mod_terrain_networked.ival)
{
#ifndef CLIENTONLY
if (hm != sv.world.worldmodel->terrain)
#endif
return NULL;
}
/*queue the file for download if we don't have it yet*/ /*queue the file for download if we don't have it yet*/
if (FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&ds) < 0 if (FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&ds) < 0
#ifndef CLIENTONLY #ifndef CLIENTONLY
@ -544,12 +572,12 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in
return s; return s;
} }
static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy) //doesn't clear edited/dirty flags or anything
static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, char *fname)
{ {
#ifndef SERVERONLY #ifndef SERVERONLY
dsection_t ds; dsection_t ds;
dsmesh_t dm; dsmesh_t dm;
char *fname;
unsigned char *lm; unsigned char *lm;
vfsfile_t *f; vfsfile_t *f;
int nothing = 0; int nothing = 0;
@ -608,7 +636,6 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy
ds.maxh = s->maxh; ds.maxh = s->maxh;
ds.ents_num = s->numents; ds.ents_num = s->numents;
fname = Terr_DiskSectionName(hm, sx, sy);
FS_CreatePath(fname, FS_GAMEONLY); FS_CreatePath(fname, FS_GAMEONLY);
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY); f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
@ -683,7 +710,7 @@ static hmsection_t *Terr_GetSection(heightmap_t *hm, int x, int y, qboolean dolo
} }
/*save all currently loaded sections*/ /*save all currently loaded sections*/
int HeightMap_Save(heightmap_t *hm) int Heightmap_Save(heightmap_t *hm)
{ {
hmsection_t *s; hmsection_t *s;
int x, y; int x, y;
@ -697,7 +724,7 @@ int HeightMap_Save(heightmap_t *hm)
continue; continue;
if (s->flags & TSF_EDITED) if (s->flags & TSF_EDITED)
{ {
if (Terr_SaveSection(hm, s, x, y)) if (Terr_SaveSection(hm, s, x, y, Terr_DiskSectionName(hm, x, y)))
{ {
s->flags &= ~TSF_EDITED; s->flags &= ~TSF_EDITED;
sectionssaved++; sectionssaved++;
@ -709,6 +736,68 @@ int HeightMap_Save(heightmap_t *hm)
return sectionssaved; return sectionssaved;
} }
#ifndef CLIENTONLY
static int dehex(int i)
{
if (i >= '0' && i <= '9')
return (i-'0');
else if (i >= 'A' && i <= 'F')
return (i-'A'+10);
else
return (i-'a'+10);
}
//on servers, we can get requests to download current map sections. if so, give them it.
qboolean Terrain_LocateSection(char *name, flocation_t *loc)
{
heightmap_t *hm;
hmsection_t *s;
int x, y;
int nlen = strlen(name);
//reject if its not in maps
if (strncmp(name, "maps/", 5))
return false;
//or too short
if (nlen < 17+5)
return false;
//reject if its not a section...
if (strncmp(name+nlen - 17, "/sect_", 6) || strcmp(name+nlen - 4, ".hms"))
return false;
//FIXME: find the right map instead
hm = sv.world.worldmodel->terrain;
if (!hm) //its not terrain.
return false;
x = dehex(name[nlen-17+ 6])<<8;
x|= dehex(name[nlen-17+ 7])<<4;
x|= dehex(name[nlen-17+ 8])<<0;
y = dehex(name[nlen-17+10])<<8;
y|= dehex(name[nlen-17+11])<<4;
y|= dehex(name[nlen-17+12])<<0;
x += CHUNKBIAS;
y += CHUNKBIAS;
//verify that its valid
if (strcmp(name, Terr_DiskSectionName(hm, x, y)))
return false;
s = Terr_GetSection(hm, x, y, false);
if (!s || !(s->flags & TSF_EDITED))
return false; //its not been edited, might as well just use the regular file
name = Terr_TempDiskSectionName(hm, x, y);
if (!Terr_SaveSection(hm, s, x, y, name))
return false;
return FS_FLocateFile(name, FSLFRT_IFFOUND, loc);
}
#endif
void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusable) void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusable)
{ {
RemoveLink(&s->recycle); RemoveLink(&s->recycle);
@ -729,7 +818,7 @@ void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusa
hm->relight = NULL; hm->relight = NULL;
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL && qglDeleteBuffersARB)
{ {
qglDeleteBuffersARB(1, &s->vbo.coord.gl.vbo); qglDeleteBuffersARB(1, &s->vbo.coord.gl.vbo);
qglDeleteBuffersARB(1, &s->vbo.indicies.gl.vbo); qglDeleteBuffersARB(1, &s->vbo.indicies.gl.vbo);
@ -2491,35 +2580,6 @@ static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float ra
} }
} }
//Heightmap_NativeBoxContents
enum
{
ter_reload, //
ter_save, //
ter_sethole, //vector pos, float radius, floatbool hole
ter_height_set, //vector pos, float radius, float newheight
ter_height_smooth, //vector pos, float radius, float percent
ter_height_spread, //vector pos, float radius, float percent
ter_raise, //vector pos, float radius, float heightchange
ter_lower, //vector pos, float radius, float heightchange
ter_tex_kill, //vector pos, void junk, void junk, string texname
ter_tex_get, //vector pos, void junk, float imagenum
ter_mixpaint, //vector pos, float radius, float percent, string texname
ter_mixconcentrate, //vector pos, float radius, float percent
ter_mixnoise, //vector pos, float radius, float percent
ter_mixblur, //vector pos, float radius, float percent
ter_water_set, //vector pos, float radius, float newwaterheight
ter_mesh_add, //entity ent
ter_mesh_kill, //vector pos, float radius
ter_tint, //vector pos, float radius, float percent, vector newcol, float newalph
ter_height_flatten, //vector pos, float radius, float percent
// ter_poly_add, //add a poly, woo
// ter_poly_remove, //remove polys
// ter_autopaint_h, //vector pos, float radius, float percent, string tex1, string tex2 (paint tex1/tex2
// ter_autopaint_n //vector pos, float radius, float percent, string tex1, string tex2
};
void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
world_t *vmw = prinst->parms->user; world_t *vmw = prinst->parms->user;
@ -2548,7 +2608,7 @@ void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_glob
Terr_PurgeTerrainModel(mod, false, true); Terr_PurgeTerrainModel(mod, false, true);
break; break;
case ter_save: case ter_save:
Con_Printf("%i sections saved\n", HeightMap_Save(hm)); Con_Printf("%i sections saved\n", Heightmap_Save(hm));
break; break;
case ter_sethole: case ter_sethole:
/* { /* {
@ -2623,16 +2683,16 @@ void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_glob
// case ter_mixset: // case ter_mixset:
// ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixset, G_VECTOR(OFS_PARM4)); // ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixset, G_VECTOR(OFS_PARM4));
// break; // break;
case ter_mixpaint: case ter_mix_paint:
ted_itterate(hm, tid_exponential, pos, radius, quant/10, SECTTEXSIZE, ted_mixpaint, PR_GetStringOfs(prinst, OFS_PARM4)); ted_itterate(hm, tid_exponential, pos, radius, quant/10, SECTTEXSIZE, ted_mixpaint, PR_GetStringOfs(prinst, OFS_PARM4));
break; break;
case ter_mixconcentrate: case ter_mix_concentrate:
ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixconcentrate, NULL); ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixconcentrate, NULL);
break; break;
case ter_mixnoise: case ter_mix_noise:
ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixnoise, NULL); ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixnoise, NULL);
break; break;
case ter_mixblur: case ter_mix_blur:
Vector4Set(tally, 0, 0, 0, 0); Vector4Set(tally, 0, 0, 0, 0);
ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixtally, &tally); ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixtally, &tally);
VectorScale(tally, 1/(tally[3]*255), tally); VectorScale(tally, 1/(tally[3]*255), tally);
@ -3007,4 +3067,9 @@ void *Mod_LoadTerrainInfo(model_t *mod, char *loadname)
return hm; return hm;
} }
void Terr_Init(void)
{
Cvar_Register(&mod_terrain_networked, "Terrain");
}
#endif #endif

View file

@ -556,176 +556,6 @@ void HL_SetupBones(hlmodel_t *model, int seqnum, int firstbone, int lastbone, fl
} }
} }
#if 0
/*
=======================================================================================================================
R_Draw_HL_AliasModel - main drawing function
=======================================================================================================================
*/
void R_DrawHLModel(entity_t *curent)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmodelcache_t *modelc = Mod_Extradata(curent->model);
hlmodel_t model;
int b, m, v;
short *skins;
int bgroup, cbone, lastbone;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//general model
model.header = (hlmdl_header_t *) ((char *)modelc + modelc->header);
model.texheader = (hlmdl_header_t *) ((char *)modelc + modelc->texheader);
model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures);
model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones);
model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls);
model.shaders = (shader_t **) ((char *)modelc + modelc->shaders);
skins = (short *) ((qbyte *) model.texheader + model.texheader->skins);
if (!model.texheader->numtextures)
{
Con_DPrintf("model with no textures: %s\n", curent->model->name);
return;
}
for (b = 0; b < MAX_BONE_CONTROLLERS; b++)
model.controller[b] = curent->framestate.bonecontrols[b];
// Con_Printf("%s %i\n", sequence->name, sequence->unknown1[0]);
cbone = 0;
for (bgroup = 0; bgroup < FS_COUNT; bgroup++)
{
lastbone = curent->framestate.g[bgroup].endbone;
if (bgroup == FS_COUNT-1)
lastbone = model.header->numbones;
if (cbone >= lastbone)
continue;
HL_SetupBones(&model, curent->framestate.g[bgroup].frame[0], cbone, lastbone, (curent->framestate.g[bgroup].subblendfrac+1)*0.5, curent->framestate.g[bgroup].frametime[0]); /* Setup the bones */
cbone = lastbone;
}
/* Manipulate each mesh directly */
for(b = 0; b < model.header->numbodyparts; b++)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmdl_bodypart_t *bodypart = (hlmdl_bodypart_t *) ((qbyte *) model.header + model.header->bodypartindex) +
b;
int bodyindex = (0 / bodypart->base) % bodypart->nummodels;
hlmdl_model_t *amodel = (hlmdl_model_t *) ((qbyte *) model.header + bodypart->modelindex) + bodyindex;
qbyte *bone = ((qbyte *) model.header + amodel->vertinfoindex);
vec3_t *verts = (vec3_t *) ((qbyte *) model.header + amodel->vertindex);
vec3_t transformed[2048];
// vec3_t *norms = (vec3_t *) ((qbyte *) model.header + amodel->unknown3[2]);
// vec3_t transformednorms[2048];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
for(v = 0; v < amodel->numverts; v++) // Transform per the matrix
{
VectorTransform(verts[v], (void *)transform_matrix[bone[v]], transformed[v]);
// glVertex3fv(verts[v]);
// glVertex3f( verts[v][0]+10*verts[v][0],
// verts[v][1]+10*verts[v][1],
// verts[v][2]+10*verts[v][2]);
}
//Need to work out what we have!
//raw data appears to be unit vectors
//transformed gives some points on the skeleton.
//what's also weird is that the meshes use these up!
/* glDisable(GL_TEXTURE_2D);
glBegin(GL_LINES);
for(v = 0; v < amodel->unknown3[0]; v++) // Transform per the matrix
{
VectorTransform(norms[v], transform_matrix[bone[v]], transformednorms[v]);
glVertex3fv(transformednorms[v]);
glVertex3f( transformednorms[v][0]+10*transformednorms[v][0],
transformednorms[v][1]+10*transformednorms[v][1],
transformednorms[v][2]+10*transformednorms[v][2]);
}
glEnd();
glEnable(GL_TEXTURE_2D);
*/
/* Draw each mesh */
for(m = 0; m < amodel->nummesh; m++)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
hlmdl_mesh_t *mesh = (hlmdl_mesh_t *) ((qbyte *) model.header + amodel->meshindex) + m;
float tex_w;
float tex_h;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
{
tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
// GL_LazyBind(0, GL_TEXTURE_2D, model.shaders[skins[mesh->skinindex]]->defaulttextures.base);
}
GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h);
}
}
}
/*
=======================================================================================================================
GL_Draw_HL_AliasFrame - clip and draw all triangles
=======================================================================================================================
*/
void GL_Draw_HL_AliasFrame(short *order, vec3_t *transformed, float tex_w, float tex_h)
{
/*~~~~~~~~~~*/
int count = 0;
/*~~~~~~~~~~*/
// int c_tris=0;
// int c_verts=0;
// int c_chains=0;
for(;;)
{
count = *order++; /* get the vertex count and primitive type */
if(!count) break; /* done */
if(count < 0)
{
count = -count;
qglBegin(GL_TRIANGLE_FAN);
}
else
{
qglBegin(GL_TRIANGLE_STRIP);
}
// c_tris += count-2;
// c_chains++;
do
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
float *verts = transformed[order[0]];
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//FIXME: what's order[1]?
/* texture coordinates come from the draw list */
qglTexCoord2f(order[2] * tex_w, order[3] * tex_h);
order += 4;
qglVertex3fv(verts);
// c_verts++;
} while(--count);
qglEnd();
}
}
#endif
void R_HL_BuildFrame(hlmodel_t *model, hlmdl_model_t *amodel, entity_t *curent, short *order, float tex_s, float tex_t, mesh_t *mesh) void R_HL_BuildFrame(hlmodel_t *model, hlmdl_model_t *amodel, entity_t *curent, short *order, float tex_s, float tex_t, mesh_t *mesh)
{ {
static vecV_t xyz[2048]; static vecV_t xyz[2048];

View file

@ -314,7 +314,7 @@ void RMod_Think (void)
{ {
COM_StripExtension(lightmodel->name, filename, sizeof(filename)); COM_StripExtension(lightmodel->name, filename, sizeof(filename));
COM_DefaultExtension(filename, ".lux", sizeof(filename)); COM_DefaultExtension(filename, ".lux", sizeof(filename));
f = FS_OpenVFS(filename, "wb", FS_GAMEONLY); f = FS_OpenVFS(filename, "wb", FS_GAME);
if (f) if (f)
{ {
VFS_WRITE(f, "QLIT\1\0\0\0", 8); VFS_WRITE(f, "QLIT\1\0\0\0", 8);
@ -329,7 +329,8 @@ void RMod_Think (void)
{ {
COM_StripExtension(lightmodel->name, filename, sizeof(filename)); COM_StripExtension(lightmodel->name, filename, sizeof(filename));
COM_DefaultExtension(filename, ".lit", sizeof(filename)); COM_DefaultExtension(filename, ".lit", sizeof(filename));
f = FS_OpenVFS(filename, "wb", FS_GAMEONLY);
f = FS_OpenVFS(filename, "wb", FS_GAME);
if (f) if (f)
{ {
VFS_WRITE(f, "QLIT\1\0\0\0", 8); VFS_WRITE(f, "QLIT\1\0\0\0", 8);
@ -429,6 +430,10 @@ void RMod_Init (void)
Cmd_AddCommand("mod_batchlist", RMod_BatchList_f); Cmd_AddCommand("mod_batchlist", RMod_BatchList_f);
Cmd_AddCommand("mod_texturelist", RMod_TextureList_f); Cmd_AddCommand("mod_texturelist", RMod_TextureList_f);
Cmd_AddCommand("mod_usetexture", RMod_BlockTextureColour_f); Cmd_AddCommand("mod_usetexture", RMod_BlockTextureColour_f);
#ifdef TERRAIN
Terr_Init();
#endif
} }
void RMod_Shutdown (void) void RMod_Shutdown (void)
@ -734,6 +739,7 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
TRACE(("RMod_LoadModel: md3\n")); TRACE(("RMod_LoadModel: md3\n"));
if (!Mod_LoadQ3Model (mod, buf)) if (!Mod_LoadQ3Model (mod, buf))
continue; continue;
Surf_BuildModelLightmaps(mod);
break; break;
#endif #endif
@ -801,6 +807,7 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
TRACE(("RMod_LoadModel: q2/q3/raven/fusion bsp\n")); TRACE(("RMod_LoadModel: q2/q3/raven/fusion bsp\n"));
if (!Mod_LoadQ2BrushModel (mod, buf)) if (!Mod_LoadQ2BrushModel (mod, buf))
continue; continue;
Surf_BuildModelLightmaps(mod);
break; break;
#endif #endif
#ifdef MAP_DOOM #ifdef MAP_DOOM
@ -820,6 +827,7 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
TRACE(("RMod_LoadModel: hl/q1 bsp\n")); TRACE(("RMod_LoadModel: hl/q1 bsp\n"));
if (!RMod_LoadBrushModel (mod, buf)) if (!RMod_LoadBrushModel (mod, buf))
continue; continue;
Surf_BuildModelLightmaps(mod);
break; break;
//Text based misc types. //Text based misc types.
@ -861,7 +869,7 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
} }
#endif #endif
Con_Printf(CON_WARNING "Unrecognised model format %i\n", LittleLong(*(unsigned *)buf)); Con_Printf(CON_WARNING "Unrecognised model format 0x%x (%c%c%c%c)\n", LittleLong(*(unsigned *)buf), ((char*)buf)[0], ((char*)buf)[1], ((char*)buf)[2], ((char*)buf)[3]);
continue; continue;
} }
@ -1236,7 +1244,7 @@ void RMod_LoadMiptex(texture_t *tx, miptex_t *mt, texnums_t *tn, int maps)
snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name);
} }
if (!TEXVALID(tn->bump) && loadmodel->fromgame != fg_halflife)// && gl_bump_fallbacks.ival) if (!TEXVALID(tn->bump) && loadmodel->fromgame != fg_halflife && r_loadbumpmapping)// && gl_bump_fallbacks.ival)
{ {
//no mip levels here, would be absurd. //no mip levels here, would be absurd.
base = (qbyte *)(mt+1); //convert to greyscale. base = (qbyte *)(mt+1); //convert to greyscale.
@ -1794,9 +1802,9 @@ void RMod_LoadLighting (lump_t *l)
luxdata = Hunk_AllocName(samples*3, "lux data"); luxdata = Hunk_AllocName(samples*3, "lux data");
for (i = 0; i < samples; i++) for (i = 0; i < samples; i++)
{ {
litdata[i*3+0] = 0.5f*255; luxdata[i*3+0] = 0.5f*255;
litdata[i*3+0] = 0.5f*255; luxdata[i*3+1] = 0.5f*255;
litdata[i*3+0] = 255; luxdata[i*3+2] = 255;
} }
} }
#endif #endif

View file

@ -305,6 +305,7 @@ typedef struct vbo_s
} vbo_t; } vbo_t;
void GL_SelectVBO(int vbo); void GL_SelectVBO(int vbo);
void GL_SelectEBO(int vbo); void GL_SelectEBO(int vbo);
void GL_DeselectVAO(void);
typedef struct texture_s typedef struct texture_s
{ {
@ -1019,10 +1020,12 @@ qbyte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
// gl_heightmap.c // gl_heightmap.c
// //
#ifdef TERRAIN #ifdef TERRAIN
void Terr_Init(void);
void Terr_DrawTerrainModel (batch_t **batch, entity_t *e); void Terr_DrawTerrainModel (batch_t **batch, entity_t *e);
qboolean Terr_LoadTerrainModel (model_t *mod, void *buffer); qboolean Terr_LoadTerrainModel (model_t *mod, void *buffer);
void Terr_PurgeTerrainModel(model_t *mod, qboolean lightmapsonly, qboolean lightmapreusable); void Terr_PurgeTerrainModel(model_t *mod, qboolean lightmapsonly, qboolean lightmapreusable);
void *Mod_LoadTerrainInfo(model_t *mod, char *loadname); //call this after loading a bsp void *Mod_LoadTerrainInfo(model_t *mod, char *loadname); //call this after loading a bsp
qboolean Terrain_LocateSection(char *name, flocation_t *loc); //used on servers to generate sections for download.
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, struct trace_s *trace); qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, struct trace_s *trace);
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org); unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org);
struct fragmentdecal_s; struct fragmentdecal_s;

View file

@ -102,6 +102,7 @@ texid_t scenepp_texture_warp;
texid_t scenepp_texture_edge; texid_t scenepp_texture_edge;
texid_t scenepp_postproc_cube; texid_t scenepp_postproc_cube;
int scenepp_postproc_cube_size;
// KrimZon - init post processing - called in GL_CheckExtensions, when they're called // KrimZon - init post processing - called in GL_CheckExtensions, when they're called
// I put it here so that only this file need be changed when messing with the post // I put it here so that only this file need be changed when messing with the post
@ -581,7 +582,10 @@ void R_RenderScene (void)
TRACE(("dbg: calling R_RenderDlights\n")); TRACE(("dbg: calling R_RenderDlights\n"));
R_RenderDlights (); R_RenderDlights ();
RQ_RenderBatchClear(); if (r_refdef.recurse)
RQ_RenderBatch();
else
RQ_RenderBatchClear();
cl_numvisedicts = tmpvisents; cl_numvisedicts = tmpvisents;
} }
@ -677,6 +681,7 @@ static entity_t *R_NearestPortal(plane_t *plane)
int i; int i;
entity_t *best = NULL; entity_t *best = NULL;
float dist, bestd = 0; float dist, bestd = 0;
//for q3-compat, portals on world scan for a visedict to use for their view.
for (i = 0; i < cl_numvisedicts; i++) for (i = 0; i < cl_numvisedicts; i++)
{ {
if (cl_visedicts[i].rtype == RT_PORTALSURFACE) if (cl_visedicts[i].rtype == RT_PORTALSURFACE)
@ -826,6 +831,15 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype)
// memset(newvis, 0xff, pvsbytes); // memset(newvis, 0xff, pvsbytes);
} }
} }
else if (batch->ent != &r_worldentity)
{
float d;
view = batch->ent;
d = DotProduct(r_refdef.vieworg, plane.normal) - plane.dist;
d-= 0.1; //nudge it past.
VectorAdd(r_refdef.vieworg, view->oldorigin, r_refdef.vieworg); //trivial offset for the warpzone.
VectorMA(r_refdef.vieworg, -d, plane.normal, r_refdef.pvsorigin); //clip the pvs origin to the plane.
}
else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin)) else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin))
{ {
r_refdef.flipcull ^= true; r_refdef.flipcull ^= true;
@ -1011,14 +1025,15 @@ void GLR_SetupFog (void)
} }
#endif #endif
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
static void R_RenderMotionBlur(void) static void R_RenderMotionBlur(void)
{ {
int vwidth = 1, vheight = 1; int vwidth = 1, vheight = 1;
float vs, vt, cs, ct; float vs, vt, cs, ct;
#ifdef warningmsg shader_t *shader;
#pragma warningmsg("backend fixme")
#endif
#if !defined(ANDROID) && !defined(NACL) #if !defined(ANDROID) && !defined(NACL)
//figure out the size of our texture.
if (gl_config.arb_texture_non_power_of_two) if (gl_config.arb_texture_non_power_of_two)
{ //we can use any size, supposedly { //we can use any size, supposedly
vwidth = vid.pixelwidth; vwidth = vid.pixelwidth;
@ -1032,21 +1047,6 @@ static void R_RenderMotionBlur(void)
vheight *= 2; vheight *= 2;
} }
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
PPL_RevertToKnownState();
GL_LazyBind(0, GL_TEXTURE_2D, sceneblur_texture);
// go 2d
qglMatrixMode(GL_PROJECTION);
qglPushMatrix();
qglLoadIdentity ();
qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999);
qglMatrixMode(GL_MODELVIEW);
qglPushMatrix();
qglLoadIdentity ();
//blend the last frame onto the scene //blend the last frame onto the scene
//the maths is because our texture is over-sized (must be power of two) //the maths is because our texture is over-sized (must be power of two)
cs = vs = (float)vid.pixelwidth / vwidth * 0.5; cs = vs = (float)vid.pixelwidth / vwidth * 0.5;
@ -1054,34 +1054,28 @@ static void R_RenderMotionBlur(void)
vs *= gl_motionblurscale.value; vs *= gl_motionblurscale.value;
vt *= gl_motionblurscale.value; vt *= gl_motionblurscale.value;
qglDisable (GL_DEPTH_TEST); //render using our texture
GL_CullFace(0); shader = R_RegisterShader("postproc_motionblur",
qglDisable (GL_ALPHA_TEST); "{\n"
qglEnable(GL_BLEND); "program default2d\n"
qglColor4f(1, 1, 1, gl_motionblur.value); "{\n"
qglBegin(GL_QUADS); "map $sourcecolour\n"
qglTexCoord2f(cs-vs, ct-vt); "blendfunc blend\n"
qglVertex2f(0, 0); "}\n"
qglTexCoord2f(cs+vs, ct-vt); "}\n"
qglVertex2f(vid.pixelwidth, 0); );
qglTexCoord2f(cs+vs, ct+vt); GLBE_RenderToTexture(sceneblur_texture, r_nulltex, r_nulltex, false);
qglVertex2f(vid.pixelwidth, vid.pixelheight); R2D_ImageColours(1, 1, 1, gl_motionblur.value);
qglTexCoord2f(cs-vs, ct+vt); R2D_Image(0, 0, vid.width, vid.height, cs-vs, ct+vt, cs+vs, ct-vt, shader);
qglVertex2f(0, vid.pixelheight); GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
qglEnd();
qglMatrixMode(GL_PROJECTION);
qglPopMatrix();
qglMatrixMode(GL_MODELVIEW);
qglPopMatrix();
//grab the current image so we can feed that back into the next frame.
GL_MTBind(0, GL_TEXTURE_2D, sceneblur_texture);
//copy the image into the texture so that we can play with it next frame too! //copy the image into the texture so that we can play with it next frame too!
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0); qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#endif #endif
PPL_RevertToKnownState();
} }
/*FIXME: we could use geometry shaders to draw to all 6 faces at once*/ /*FIXME: we could use geometry shaders to draw to all 6 faces at once*/
@ -1174,8 +1168,10 @@ qboolean R_RenderScene_Cubemap(void)
VectorCopy(r_refdef.viewangles, saveang); VectorCopy(r_refdef.viewangles, saveang);
saveang[2] = 0; saveang[2] = 0;
if (!TEXVALID(scenepp_postproc_cube)) if (!TEXVALID(scenepp_postproc_cube) || cmapsize != scenepp_postproc_cube_size)
{ {
if (TEXVALID(scenepp_postproc_cube))
GL_DestroyTexture(scenepp_postproc_cube);
scenepp_postproc_cube = GL_AllocNewTexture("***fish***", cmapsize, cmapsize, 0); scenepp_postproc_cube = GL_AllocNewTexture("***fish***", cmapsize, cmapsize, 0);
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_postproc_cube); GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_postproc_cube);
@ -1185,10 +1181,14 @@ qboolean R_RenderScene_Cubemap(void)
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
scenepp_postproc_cube_size = cmapsize;
} }
r_refdef.vrect.width = cmapsize; vrect = r_refdef.vrect; //save off the old vrect
r_refdef.vrect.height = cmapsize;
r_refdef.vrect.width = (cmapsize * vid.width) / vid.pixelwidth;
r_refdef.vrect.height = (cmapsize * vid.height) / vid.pixelheight;
r_refdef.vrect.x = 0; r_refdef.vrect.x = 0;
r_refdef.vrect.y = prect.y; r_refdef.vrect.y = prect.y;
@ -1223,6 +1223,8 @@ qboolean R_RenderScene_Cubemap(void)
qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, 0, 0, 0, vid.pixelheight - (prect.y + cmapsize), cmapsize, cmapsize); qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, 0, 0, 0, vid.pixelheight - (prect.y + cmapsize), cmapsize, cmapsize);
} }
r_refdef.vrect = vrect;
qglViewport (prect.x, vid.pixelheight - (prect.y+prect.height), prect.width, prect.height); qglViewport (prect.x, vid.pixelheight - (prect.y+prect.height), prect.width, prect.height);
// go 2d // go 2d
@ -1339,6 +1341,8 @@ void GLR_RenderView (void)
if (r_refdef.flags & Q2RDF_NOWORLDMODEL) if (r_refdef.flags & Q2RDF_NOWORLDMODEL)
return; return;
GL_Set2D (false);
if (r_bloom.value) if (r_bloom.value)
R_BloomBlend(); R_BloomBlend();
@ -1348,7 +1352,6 @@ void GLR_RenderView (void)
{ {
if (scenepp_waterwarp) if (scenepp_waterwarp)
{ {
GL_Set2D(false);
R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp); R2D_ScalePic(0, 0, vid.width, vid.height, scenepp_waterwarp);
} }
} }
@ -1363,7 +1366,6 @@ void GLR_RenderView (void)
shader_t *postproc = R_RegisterCustom(r_postprocshader.string, NULL, NULL); shader_t *postproc = R_RegisterCustom(r_postprocshader.string, NULL, NULL);
if (postproc) if (postproc)
{ {
GL_Set2D(false);
R2D_ScalePic(0, 0, vid.width, vid.height, postproc); R2D_ScalePic(0, 0, vid.width, vid.height, postproc);
} }
} }

View file

@ -178,12 +178,6 @@ void GLSCR_UpdateScreen (void)
GL_Set2D (false); GL_Set2D (false);
if (!noworld)
{
R2D_PolyBlend ();
R2D_BrightenScreen();
}
scr_con_forcedraw = false; scr_con_forcedraw = false;
if (noworld) if (noworld)
{ {
@ -208,6 +202,8 @@ void GLSCR_UpdateScreen (void)
SCR_DrawCursor(0); SCR_DrawCursor(0);
V_UpdatePalette (false); V_UpdatePalette (false);
R2D_BrightenScreen();
#if defined(_WIN32) && defined(GLQUAKE) #if defined(_WIN32) && defined(GLQUAKE)
Media_RecordFrame(); Media_RecordFrame();
#endif #endif

View file

@ -936,8 +936,6 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
break; break;
}; };
memset(prog->handle, 0, sizeof(*prog->handle)*PERMUTATIONS);
nummodifiers = 0; nummodifiers = 0;
for (end = strchr(name, '#'); end && *end; ) for (end = strchr(name, '#'); end && *end; )
{ {
@ -965,6 +963,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
memset(&prog->permu[p].handle, 0, sizeof(prog->permu[p].handle));
if (nopermutation & p) if (nopermutation & p)
{ {
continue; continue;
@ -992,19 +991,19 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
#ifdef GLQUAKE #ifdef GLQUAKE
else if (qrenderer == QR_OPENGL) else if (qrenderer == QR_OPENGL)
{ {
if (prog->handle[p].glsl) if (prog->permu[p].handle.glsl)
qglDeleteProgramObject_(prog->handle[p].glsl); qglDeleteProgramObject_(prog->permu[p].handle.glsl);
prog->handle[p].glsl = GLSlang_CreateProgram(name, (((p & PERMUTATION_SKELETAL) && ver < 120)?120:ver), permutationdefines, script, script, onefailed); prog->permu[p].handle.glsl = GLSlang_CreateProgram(name, (((p & PERMUTATION_SKELETAL) && ver < 120)?120:ver), permutationdefines, script, script, onefailed);
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
onefailed = true; onefailed = true;
if (!p && !prog->handle[p].glsl) if (!p && !prog->permu[p].handle.glsl)
break; break;
} }
#endif #endif
#ifdef D3D9QUAKE #ifdef D3D9QUAKE
else if (qrenderer == QR_DIRECT3D9) else if (qrenderer == QR_DIRECT3D9)
{ {
if (!D3D9Shader_CreateProgram(prog, p, permutationdefines, script, script)) if (!D3D9Shader_CreateProgram(prog, name, p, permutationdefines, script, script))
break; break;
} }
#endif #endif
@ -1041,7 +1040,7 @@ struct sbuiltin_s
char *body; char *body;
} sbuiltins[] = } sbuiltins[] =
{ {
#ifdef GLQUAKE #if 0//def GLQUAKE
/*a quick note on glsl versions: /*a quick note on glsl versions:
gl versioning started with 110 gl versioning started with 110
gles versioning started at 100 and only had a single one defined gles versioning started at 100 and only had a single one defined
@ -1293,162 +1292,6 @@ struct sbuiltin_s
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "rtlight",
/*
texture units:
s0=diffuse, s1=normal, s2=specular, s3=shadowmap
custom modifiers:
PCF(shadowmap)
CUBE(projected cubemap)
*/
"!!permu BUMP\n"
"!!permu SPECULAR\n"
"!!permu OFFSETMAPPING\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"struct a2v {\n"
"float4 pos: POSITION;\n"
"float3 tc: TEXCOORD0;\n"
"float3 n: NORMAL0;\n"
"float3 s: TANGENT0;\n"
"float3 t: BINORMAL0;\n"
"};\n"
"struct v2f {\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float3 tc: TEXCOORD0;\n"
"float3 lpos: TEXCOORD1;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"float3 l_lightposition;\n"
"v2f main (a2v inp)\n"
"{\n"
" v2f outp;\n"
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
" outp.tc = inp.tc;\n"
"float3 lightminusvertex = l_lightposition - inp.pos.xyz;\n"
"outp.lpos.x = dot(lightminusvertex, inp.s.xyz);\n"
"outp.lpos.y = dot(lightminusvertex, inp.t.xyz);\n"
"outp.lpos.z = dot(lightminusvertex, inp.n.xyz);\n"
" return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"sampler s_t0;\n"
"sampler s_t1;\n"
"float l_lightradius;\n"
"float3 l_lightcolour;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
" float3 col = l_lightcolour;\n"
" col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\n"
" float3 diff = tex2D(s_t0, inp.tc);\n"
" return float4(diff * col, 1);"
"}\n"
"#endif\n"
},
{QR_DIRECT3D9, 9, "defaultsky",
"struct a2v {\n"
"float4 pos: POSITION;\n"
"};\n"
"struct v2f {\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float3 vpos: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
" v2f outp;\n"
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
" outp.vpos = inp.pos;\n"
" return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"float e_time;\n"
"float3 e_eyepos;\n"
"float l_lightradius;\n"
"float3 l_lightcolour;\n"
"float3 l_lightposition;\n"
"sampler s_t0;\n" /*diffuse*/
"sampler s_t1;\n" /*normal*/
"sampler s_t2;\n" /*specular*/
"float4 main (v2f inp) : COLOR0\n"
"{\n"
" float2 tccoord;\n"
" float3 dir = inp.vpos - e_eyepos;\n"
" dir.z *= 3.0;\n"
" dir.xy /= 0.5*length(dir);\n"
" tccoord = (dir.xy + e_time*0.03125);\n"
" float4 solid = tex2D(s_t0, tccoord);\n"
" tccoord = (dir.xy + e_time*0.0625);\n"
" float4 clouds = tex2D(s_t1, tccoord);\n"
" return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
"}\n"
"#endif\n"
},
{QR_DIRECT3D9, 9, "defaultwarp",
"!!cvarf r_wateralpha\n"
"struct a2v {\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"struct v2f {\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
" v2f outp;\n"
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
" outp.tc = inp.tc;\n"
" return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"float cvar_r_wateralpha;\n"
"float e_time;\n"
"sampler s_t0;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
" float2 ntc;\n"
" ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;\n"
" ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125;\n"
" float3 ts = tex2D(s_t0, ntc).xyz;\n"
" return float4(ts, cvar_r_wateralpha);\n"
"}\n"
"#endif\n"
},
#endif
#include "r_bishaders.h" #include "r_bishaders.h"
{QR_NONE} {QR_NONE}
}; };
@ -1460,8 +1303,8 @@ void Shader_UnloadProg(program_t *prog)
int p; int p;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (prog->handle[p].glsl) if (prog->permu[p].handle.glsl)
qglDeleteProgramObject_(prog->handle[p].glsl); qglDeleteProgramObject_(prog->permu[p].handle.glsl);
} }
} }
#endif #endif
@ -1728,18 +1571,18 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
//figure out visible attributes //figure out visible attributes
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
continue; continue;
GLSlang_UseProgram(prog->handle[p].glsl); GLSlang_UseProgram(prog->permu[p].handle.glsl);
for (i = 0; shader_attr_names[i].name; i++) for (i = 0; shader_attr_names[i].name; i++)
{ {
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, shader_attr_names[i].name); uniformloc = qglGetAttribLocationARB(prog->permu[p].handle.glsl, shader_attr_names[i].name);
if (uniformloc != -1) if (uniformloc != -1)
{ {
if (shader_attr_names[i].ptype != uniformloc) if (shader_attr_names[i].ptype != uniformloc)
Con_Printf("Bad attribute\n"); Con_Printf("Bad attribute\n");
else else
prog->attrmask[p] |= 1u<<uniformloc; prog->permu[p].attrmask |= 1u<<uniformloc;
} }
} }
} }
@ -1750,11 +1593,11 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
found = false; found = false;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
continue; continue;
GLSlang_UseProgram(prog->handle[p].glsl); GLSlang_UseProgram(prog->permu[p].handle.glsl);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, shader_unif_names[i].name); uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, shader_unif_names[i].name);
if (uniformloc != -1) if (uniformloc != -1)
found = true; found = true;
@ -1764,7 +1607,7 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
break; break;
} }
else else
prog->parm[prog->numparams].handle[p] = uniformloc; prog->permu[p].parm[prog->numparams] = uniformloc;
} }
if (found) if (found)
{ {
@ -1797,16 +1640,16 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
found = false; found = false;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
continue; continue;
GL_SelectProgram(prog->handle[p].glsl); GL_SelectProgram(prog->permu[p].handle.glsl);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("cvar_%s", tmpname)); uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, va("cvar_%s", tmpname));
if (uniformloc != -1) if (uniformloc != -1)
{ {
qglUniform1fARB(uniformloc, cvar->value); qglUniform1fARB(uniformloc, cvar->value);
found = true; found = true;
} }
prog->parm[prog->numparams].handle[p] = uniformloc; prog->permu[p].parm[prog->numparams] = uniformloc;
} }
if (found) if (found)
prog->numparams++; prog->numparams++;
@ -1814,14 +1657,14 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
/*set texture uniforms*/ /*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
continue; continue;
if (!(prog->attrmask[p] & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these... if (!(prog->permu[p].attrmask & (1u<<VATTR_VERTEX1))) //a shader kinda has to use one of these...
prog->attrmask[p] |= (1u<<VATTR_LEG_VERTEX); prog->permu[p].attrmask |= (1u<<VATTR_LEG_VERTEX);
GLSlang_UseProgram(prog->handle[p].glsl); GLSlang_UseProgram(prog->permu[p].handle.glsl);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("s_t%i", i)); uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, va("s_t%i", i));
if (uniformloc != -1) if (uniformloc != -1)
qglUniform1iARB(uniformloc, i); qglUniform1iARB(uniformloc, i);
} }
@ -1846,20 +1689,20 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
cvar->flags |= CVAR_SHADERSYSTEM; cvar->flags |= CVAR_SHADERSYSTEM;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.hlsl.vert || !prog->permu[p].handle.hlsl.frag)
continue; continue;
uniformloc = D3D9Shader_FindUniform(&prog->handle[p], 1, va("cvar_%s", tmpname)); uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 1, va("cvar_%s", tmpname));
if (uniformloc != -1) if (uniformloc != -1)
{ {
vec4_t v = {cvar->value, 0, 0, 0}; vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->handle[0].hlsl.vert); IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->permu[p].handle.hlsl.vert);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, 0, v, 1); IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, 0, v, 1);
} }
uniformloc = D3D9Shader_FindUniform(&prog->handle[p], 2, va("cvar_%s", tmpname)); uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, va("cvar_%s", tmpname));
if (uniformloc != -1) if (uniformloc != -1)
{ {
vec4_t v = {cvar->value, 0, 0, 0}; vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[0].hlsl.vert); IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, 0, v, 1); IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, 0, v, 1);
} }
} }
@ -1869,10 +1712,10 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
found = false; found = false;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
uniformloc = D3D9Shader_FindUniform(&prog->handle[p], 0, shader_unif_names[i].name); uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 0, shader_unif_names[i].name);
if (uniformloc != -1) if (uniformloc != -1)
found = true; found = true;
prog->parm[prog->numparams].handle[p] = uniformloc; prog->permu[p].parm[prog->numparams] = uniformloc;
} }
if (found) if (found)
{ {
@ -1885,11 +1728,11 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
{ {
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
uniformloc = D3D9Shader_FindUniform(&prog->handle[p], 2, va("s_t%i", i)); uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, va("s_t%i", i));
if (uniformloc != -1) if (uniformloc != -1)
{ {
int v[4] = {i}; int v[4] = {i};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[0].hlsl.vert); IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1); IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
} }
} }
@ -2087,12 +1930,12 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
prog->parm[prog->numparams].type = parmtype; prog->parm[prog->numparams].type = parmtype;
for (p = 0; p < PERMUTATIONS; p++) for (p = 0; p < PERMUTATIONS; p++)
{ {
if (!prog->handle[p].glsl) if (!prog->permu[p].handle.glsl)
continue; continue;
GLSlang_UseProgram(prog->handle[p].glsl); GLSlang_UseProgram(prog->permu[p].handle.glsl);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, token); uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl, token);
prog->parm[prog->numparams].handle[p] = uniformloc; prog->permu[p].parm[prog->numparams] = uniformloc;
if (uniformloc != -1) if (uniformloc != -1)
{ {
@ -2223,6 +2066,7 @@ static qboolean Shaderpass_MapGen (shader_t *shader, shaderpass_t *pass, char *t
{ {
pass->texgen = T_GEN_SPECULAR; pass->texgen = T_GEN_SPECULAR;
pass->tcgen = TC_GEN_BASE; pass->tcgen = TC_GEN_BASE;
shader->flags |= SHADER_HASGLOSS;
} }
else if (!Q_stricmp (tname, "$fullbright")) else if (!Q_stricmp (tname, "$fullbright"))
{ {
@ -4010,7 +3854,15 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
} }
if (!TEXVALID(shader->defaulttextures.specular)) if (!TEXVALID(shader->defaulttextures.specular))
{
extern cvar_t gl_specular;
if ((shader->flags & SHADER_HASGLOSS) && gl_specular.value && gl_load24bit.value)
{
if (!TEXVALID(tn->specular))
tn->specular = R_LoadHiResTexture(va("%s_gloss", shader->name), NULL, 0);
}
TEXASSIGN(shader->defaulttextures.specular, tn->specular); TEXASSIGN(shader->defaulttextures.specular, tn->specular);
}
if (!TEXVALID(shader->defaulttextures.fullbright)) if (!TEXVALID(shader->defaulttextures.fullbright))
TEXASSIGN(shader->defaulttextures.fullbright, tn->fullbright); TEXASSIGN(shader->defaulttextures.fullbright, tn->fullbright);
} }
@ -4070,10 +3922,49 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"map $fullbright\n" "map $fullbright\n"
"}\n" "}\n"
"{\n"
"map $specular\n"
"}\n"
"}\n" "}\n"
); );
} }
#endif #endif
#if 0//def D3D9QUAKE
if (qrenderer == QR_DIRECT3D9)
{
if (!builtin)
builtin = (
"{\n"
"program defaultwall\n"
/*"param texture 0 tex_diffuse\n"
"param texture 1 tex_lightmap\n"
"param texture 2 tex_normalmap\n"
"param texture 3 tex_deluxmap\n"
"param texture 4 tex_fullbright\n"*/
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"{\n"
"map $specular\n"
"}\n"
"}\n"
);
}
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
{ {
@ -4128,6 +4019,9 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"map $fullbright\n" "map $fullbright\n"
"}\n" "}\n"
"{\n"
"map $specular\n"
"}\n"
"}\n" "}\n"
); );
} }
@ -4214,8 +4108,10 @@ char *Shader_DefaultBSPWater(char *shortname)
else if (r_fastturb.ival) else if (r_fastturb.ival)
wstyle = 0; wstyle = 0;
#ifdef GLQUAKE #ifdef GLQUAKE
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && r_waterstyle.ival>0 && !r_fastturb.ival && strncmp(shortname, "*lava", 5)) else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && !strncmp(shortname, "*lava", 5))
wstyle = r_waterstyle.ival; //r_waterstyle does not apply to lava, and requires glsl and stuff wstyle = r_lavastyle.ival;
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && strncmp(shortname, "*lava", 5))
wstyle = r_waterstyle.ival<1?1:r_waterstyle.ival;
#endif #endif
else else
wstyle = 1; wstyle = 1;
@ -4263,6 +4159,7 @@ char *Shader_DefaultBSPWater(char *shortname)
case 2: //refraction of the underwater surface, with a fresnel case 2: //refraction of the underwater surface, with a fresnel
return ( return (
"{\n" "{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"
@ -4279,6 +4176,7 @@ char *Shader_DefaultBSPWater(char *shortname)
case 3: //reflections case 3: //reflections
return ( return (
"{\n" "{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"
@ -4295,6 +4193,7 @@ char *Shader_DefaultBSPWater(char *shortname)
case 4: //ripples case 4: //ripples
return ( return (
"{\n" "{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"
@ -4314,6 +4213,7 @@ char *Shader_DefaultBSPWater(char *shortname)
case 5: //ripples+reflections case 5: //ripples+reflections
return ( return (
"{\n" "{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"

View file

@ -429,6 +429,7 @@ static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl)
case QR_OPENGL: case QR_OPENGL:
qglGenBuffersARB(2, sh_shmesh->vebo); qglGenBuffersARB(2, sh_shmesh->vebo);
GL_DeselectVAO();
GL_SelectVBO(sh_shmesh->vebo[0]); GL_SelectVBO(sh_shmesh->vebo[0]);
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB); qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB);
@ -1382,6 +1383,9 @@ static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2)
return false; return false;
} }
#if 1
#define Sh_LeafInView Sh_VisOverlaps
#else
static qboolean Sh_LeafInView(qbyte *lightvis, qbyte *vvis) static qboolean Sh_LeafInView(qbyte *lightvis, qbyte *vvis)
{ {
int i; int i;
@ -1409,6 +1413,7 @@ static qboolean Sh_LeafInView(qbyte *lightvis, qbyte *vvis)
return false; return false;
} }
#endif
typedef struct typedef struct
{ {
@ -2181,7 +2186,7 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
else else
lvis = NULL; lvis = NULL;
qglDisable(GL_SCISSOR_TEST); Sh_ScissorOff();
Sh_GenShadowMap(l, lvis); Sh_GenShadowMap(l, lvis);
@ -2297,6 +2302,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
BE_SelectEntity(e); BE_SelectEntity(e);
GL_DeselectVAO();
GL_SelectVBO(0); GL_SelectVBO(0);
GL_SelectEBO(0); GL_SelectEBO(0);
qglEnableClientState(GL_VERTEX_ARRAY); qglEnableClientState(GL_VERTEX_ARRAY);
@ -2534,7 +2540,6 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
{ {
int sfrontfail; int sfrontfail;
int sbackfail; int sbackfail;
qglEnable(GL_SCISSOR_TEST);
qglEnable(GL_STENCIL_TEST); qglEnable(GL_STENCIL_TEST);
//FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer? //FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer?
@ -2650,7 +2655,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
//end stencil writing. //end stencil writing.
/*stencil writing probably changed the vertex pointer, and our backend caches it*/ /*stencil writing probably changed the vertex pointer, and our backend caches it*/
PPL_RevertToKnownState(); // PPL_RevertToKnownState();
#if 0 //draw the stencil stuff to the red channel #if 0 //draw the stencil stuff to the red channel
qglMatrixMode(GL_PROJECTION); qglMatrixMode(GL_PROJECTION);

View file

@ -319,6 +319,8 @@ extern cvar_t gl_workaround_ati_shadersource;
qboolean GL_CheckExtension(char *extname) qboolean GL_CheckExtension(char *extname)
{ {
int i; int i;
int len;
const char *foo;
cvar_t *v = Cvar_Get(va("gl_ext_%s", extname), "1", 0, "GL Extensions"); cvar_t *v = Cvar_Get(va("gl_ext_%s", extname), "1", 0, "GL Extensions");
if (v && !v->ival) if (v && !v->ival)
{ {
@ -339,8 +341,18 @@ qboolean GL_CheckExtension(char *extname)
if (!gl_extensions) if (!gl_extensions)
return false; return false;
//note that this is not actually correct... //the list is space delimited. we cannot just strstr lest we find leading/trailing _FOO_.
return !!strstr(gl_extensions, extname); len = strlen(extname);
for (foo = gl_extensions; *foo; )
{
if (!strncmp(foo, extname, len) && (foo[len] == ' ' || !foo[len]))
return true;
while(*foo && *foo != ' ')
foo++;
if (*foo == ' ')
foo++;
}
return false;
} }
void APIENTRY GL_DrawRangeElementsEmul(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) void APIENTRY GL_DrawRangeElementsEmul(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
@ -355,6 +367,10 @@ void APIENTRY GL_ClientStateStub(GLenum array)
{ {
} }
void APIENTRY GL_ClientActiveTextureStub(GLenum texid)
{
}
#define getglcore getglfunction #define getglcore getglfunction
#define getglext(name) getglfunction(name) #define getglext(name) getglfunction(name)
void GL_CheckExtensions (void *(*getglfunction) (char *name)) void GL_CheckExtensions (void *(*getglfunction) (char *name))
@ -388,7 +404,8 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
s++; s++;
gl_minor_version = atoi(s); gl_minor_version = atoi(s);
} }
gl_config.glversion = gl_major_version + (gl_minor_version/10.f); //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);
/*gl3 adds glGetStringi instead, as core, with the old form require GL_ARB_compatibility*/ /*gl3 adds glGetStringi instead, as core, with the old form require GL_ARB_compatibility*/
if (gl_major_version >= 3 && qglGetStringi) /*warning: wine fails to export qglGetStringi*/ if (gl_major_version >= 3 && qglGetStringi) /*warning: wine fails to export qglGetStringi*/
@ -578,6 +595,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
} }
} }
/*
else if (GL_CheckExtension("GL_SGIS_multitexture") && !COM_CheckParm("-nomtex")) else if (GL_CheckExtension("GL_SGIS_multitexture") && !COM_CheckParm("-nomtex"))
{ //SGIS multitexture, limited in many ways but basic functionality is identical to ARB { //SGIS multitexture, limited in many ways but basic functionality is identical to ARB
Con_SafePrintf("Multitexture extensions found.\n"); Con_SafePrintf("Multitexture extensions found.\n");
@ -587,10 +605,17 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
mtexid0 = GL_TEXTURE0_SGIS; mtexid0 = GL_TEXTURE0_SGIS;
} }
*/
if (!qglClientActiveTextureARB)
{
qglClientActiveTextureARB = GL_ClientActiveTextureStub;
}
if ((gl_config.gles && gl_config.glversion >= 2) || GL_CheckExtension("GL_EXT_stencil_wrap")) if ((gl_config.gles && gl_config.glversion >= 2) || GL_CheckExtension("GL_EXT_stencil_wrap"))
gl_config.ext_stencil_wrap = true; gl_config.ext_stencil_wrap = true;
qglStencilOpSeparateATI = NULL;
qglActiveStencilFaceEXT = NULL;
if (gl_config.gles && gl_config.glversion >= 2) if (gl_config.gles && gl_config.glversion >= 2)
qglStencilOpSeparateATI = (void *) getglext("glStencilOpSeparate"); qglStencilOpSeparateATI = (void *) getglext("glStencilOpSeparate");
else if (GL_CheckExtension("GL_ATI_separate_stencil")) else if (GL_CheckExtension("GL_ATI_separate_stencil"))

View file

@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h" #include "quakedef.h"
#include "glquake.h" #include "glquake.h"
extern qboolean sys_glesversion; extern int sys_glesversion;
static dllhandle_t *sys_gl_module = NULL; static dllhandle_t *sys_gl_module = NULL;
@ -85,6 +85,9 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
Cons: GL_EndRendering call will not swap buffers. Buffers will be swapped on return to java. Cons: GL_EndRendering call will not swap buffers. Buffers will be swapped on return to java.
*/ */
if (!sys_glesversion)
return false;
if (sys_glesversion >= 2) if (sys_glesversion >= 2)
Sys_Printf("Loading GLES2 driver\n"); Sys_Printf("Loading GLES2 driver\n");
else else
@ -114,12 +117,12 @@ void GLVID_DeInit(void)
{ {
if (sys_display != EGL_NO_DISPLAY) if (sys_display != EGL_NO_DISPLAY)
{ {
eglMakeCurrent(sys_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(sys_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (sys_context != EGL_NO_CONTEXT) if (sys_context != EGL_NO_CONTEXT)
eglDestroyContext(sys_display, sys_context); eglDestroyContext(sys_display, sys_context);
if (sys_surface != EGL_NO_SURFACE) if (sys_surface != EGL_NO_SURFACE)
eglDestroySurface(sys_display, sys_surface); eglDestroySurface(sys_display, sys_surface);
eglTerminate(sys_display); eglTerminate(sys_display);
sys_context = EGL_NO_CONTEXT; sys_context = EGL_NO_CONTEXT;
sys_surface = EGL_NO_SURFACE; sys_surface = EGL_NO_SURFACE;
sys_display = EGL_NO_DISPLAY; sys_display = EGL_NO_DISPLAY;
@ -189,7 +192,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
vid.pixelwidth = w; vid.pixelwidth = w;
vid.pixelheight = h; vid.pixelheight = h;
GLVID_SetPalette (palette); GLVID_SetPalette (palette);
GL_Init(GLES_GetSymbol); GL_Init(GLES_GetSymbol);
vid.recalc_refdef = 1; vid.recalc_refdef = 1;
return true; return true;

View file

@ -1303,6 +1303,26 @@ void GLVID_Recenter_f(void)
//int nx = 0; //int nx = 0;
//int ny = 0; //int ny = 0;
#ifdef _MSC_VER
#define strtoull _strtoui64
#endif
if (Cmd_Argc() > 1)
sys_parentleft = atoi(Cmd_Argv(1));
if (Cmd_Argc() > 2)
sys_parenttop = atoi(Cmd_Argv(2));
if (Cmd_Argc() > 3)
sys_parentwidth = atoi(Cmd_Argv(3));
if (Cmd_Argc() > 4)
sys_parentheight = atoi(Cmd_Argv(4));
if (Cmd_Argc() > 5)
{
HWND newparent = (HWND)strtoull(Cmd_Argv(5), NULL, 16);
if (newparent != sys_parentwindow && mainwindow && modestate==MS_WINDOWED)
SetParent(mainwindow, sys_parentwindow);
sys_parentwindow = newparent;
}
if (sys_parentwindow && modestate==MS_WINDOWED) if (sys_parentwindow && modestate==MS_WINDOWED)
{ {
WindowRect = centerrect(sys_parentleft, sys_parenttop, sys_parentwidth, sys_parentheight, vid_width.value, vid_height.value); WindowRect = centerrect(sys_parentleft, sys_parenttop, sys_parentwidth, sys_parentheight, vid_width.value, vid_height.value);
@ -1673,6 +1693,11 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd); qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd);
FixPaletteInDescriptor(hDC, &pfd); FixPaletteInDescriptor(hDC, &pfd);
gl_stencilbits = pfd.cStencilBits; gl_stencilbits = pfd.cStencilBits;
if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
{
Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n");
}
return TRUE; return TRUE;
} }
} }
@ -1694,6 +1719,11 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
return FALSE; return FALSE;
} }
if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
{
Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n");
}
FixPaletteInDescriptor(hDC, &pfd); FixPaletteInDescriptor(hDC, &pfd);
return TRUE; return TRUE;
} }
@ -1883,9 +1913,8 @@ LONG WINAPI GLMainWndProc (
if (wParam & MK_LBUTTON) if (wParam & MK_LBUTTON)
{ {
temp |= 1; temp |= 1;
#ifdef NPFTE if (sys_parentwindow && modestate == MS_WINDOWED)
SetFocus(hWnd); SetFocus(hWnd);
#endif
} }
if (wParam & MK_RBUTTON) if (wParam & MK_RBUTTON)

View file

@ -939,9 +939,11 @@ void LightFace (int surfnum)
temp[1] = DotProduct(wnorm, tvector); temp[1] = DotProduct(wnorm, tvector);
temp[2] = DotProduct(wnorm, l.facenormal); temp[2] = DotProduct(wnorm, l.facenormal);
VectorNormalize(temp); VectorNormalize(temp);
*dulout++ = -(temp[0]+1)*128 + 128; temp[2] += 0.5;
*dulout++ = (temp[1]+1)*128 + 128; VectorNormalize(temp);
*dulout++ = (temp[2]+1)*128 + 128; *dulout++ = (-temp[0]+1)*128;
*dulout++ = (-temp[1]+1)*128;
*dulout++ = (-temp[2]+1)*128;
} }
} }
} }

View file

@ -5,6 +5,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "altwater", {QR_OPENGL, 110, "altwater",
"!!cvarf r_glsl_turbscale\n"
//modifier: REFLECT (s_t2 is a reflection instead of diffusemap) //modifier: REFLECT (s_t2 is a reflection instead of diffusemap)
//modifier: STRENGTH (0.1 = fairly gentle, 0.2 = big waves) //modifier: STRENGTH (0.1 = fairly gentle, 0.2 = big waves)
//modifier: FRESNEL (5=water) //modifier: FRESNEL (5=water)
@ -12,6 +13,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//modifier: RIPPLEMAP (s_t3 contains a ripplemap //modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT (some colour value) //modifier: TINT (some colour value)
"uniform float cvar_r_glsl_turbscale;\n"
"#ifndef FRESNEL\n" "#ifndef FRESNEL\n"
"#define FRESNEL 5.0\n" "#define FRESNEL 5.0\n"
"#endif\n" "#endif\n"
@ -74,9 +77,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//the fresnel term decides how transparent the water should be //the fresnel term decides how transparent the water should be
"f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n" "f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n"
"refr = texture2D(s_t0, stc + n.st*STRENGTH).rgb * TINT;\n" "refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;\n"
"#ifdef REFLECT\n" "#ifdef REFLECT\n"
"refl = texture2D(s_t2, stc - n.st*STRENGTH).rgb;\n" "refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;\n"
"#else\n" "#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n" "refl = texture2D(s_t2, ntc).xyz;\n"
"#endif\n" "#endif\n"
@ -334,6 +337,44 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "default2d",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_projection, inp.pos);\n"
"outp.tc = inp.tc;\n"
"outp.vcol = inp.vcol;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture;\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return shaderTexture.Sample(SampleType, inp.tc) * inp.vcol;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultadditivesprite", {QR_OPENGL, 110, "defaultadditivesprite",
"!!permu FOG\n" "!!permu FOG\n"
@ -431,6 +472,67 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultskin",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float4 tc: TEXCOORD0;\n"
"float3 normal: NORMAL;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float3 light: TEXCOORD1;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
//attribute vec2 v_texcoord;
//uniform vec3 e_light_dir;
//uniform vec3 e_light_mul;
//uniform vec3 e_light_ambient;
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.light = e_light_ambient + (dot(inp.normal,e_light_dir)*e_light_mul);\n"
"outp.tc = inp.tc.xy;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture[4]; //diffuse, lower, upper, fullbright\n"
"SamplerState SampleType;\n"
//uniform vec4 e_colourident;
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"float4 col;\n"
"col = shaderTexture[0].Sample(SampleType, inp.tc);\n"
"#ifdef UPPER\n"
"float4 uc = shaderTexture[2].Sample(SampleType, inp.tc);\n"
"col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);\n"
"#endif\n"
"#ifdef LOWER\n"
"float4 lc = shaderTexture[1].Sample(SampleType, inp.tc);\n"
"col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);\n"
"#endif\n"
"col.rgb *= inp.light;\n"
"#ifdef FULLBRIGHT\n"
"float4 fb = shaderTexture[3].Sample(SampleType, inp.tc);\n"
"col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
"#endif\n"
"return col;\n"
// return fog4(col * e_colourident);
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultsky", {QR_OPENGL, 110, "defaultsky",
//regular sky shader for scrolling q1 skies //regular sky shader for scrolling q1 skies
@ -465,6 +567,113 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "defaultsky",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"};\n"
"struct v2f\n"
"{\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float3 vpos: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_modelviewprojection, inp.pos);\n"
"outp.vpos = inp.pos;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"float e_time;\n"
"float3 e_eyepos;\n"
"float l_lightradius;\n"
"float3 l_lightcolour;\n"
"float3 l_lightposition;\n"
"sampler s_t0; /*diffuse*/\n"
"sampler s_t1; /*normal*/\n"
"sampler s_t2; /*specular*/\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float2 tccoord;\n"
"float3 dir = inp.vpos - e_eyepos;\n"
"dir.z *= 3.0;\n"
"dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\n"
"float4 solid = tex2D(s_t0, tccoord);\n"
"tccoord = (dir.xy + e_time*0.0625);\n"
"float4 clouds = tex2D(s_t1, tccoord);\n"
"return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultsky",
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float3 mpos: TEXCOORD1;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.mpos = outp.pos.xyz;\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture[2];\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"float2 tccoord;\n"
"float3 dir = inp.mpos - v_eyepos;\n"
"dir.z *= 3.0;\n"
"dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\n"
"float4 solid = shaderTexture[0].Sample(SampleType, tccoord);\n"
"tccoord = (dir.xy + e_time*0.0625);\n"
"float4 clouds = shaderTexture[1].Sample(SampleType, tccoord);\n"
"return (solid*(1.0-clouds.a)) + (clouds.a*clouds);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultsprite", {QR_OPENGL, 110, "defaultsprite",
"!!permu FOG\n" "!!permu FOG\n"
@ -496,6 +705,46 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultsprite",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float4 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc.xy;\n"
"outp.vcol = inp.vcol;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture;\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return shaderTexture.Sample(SampleType, inp.tc) * inp.vcol;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall", {QR_OPENGL, 110, "defaultwall",
"!!permu DELUXE\n" "!!permu DELUXE\n"
@ -503,13 +752,15 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!permu FOG\n" "!!permu FOG\n"
"!!permu LIGHTSTYLED\n" "!!permu LIGHTSTYLED\n"
"!!permu BUMP\n" "!!permu BUMP\n"
"!!permu SPECULAR\n"
"!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n"
//this is what normally draws all of your walls, even with rtlights disabled //this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead. //note that the '286' preset uses drawflat_walls instead.
"#include \"sys/fog.h\"\n" "#include \"sys/fog.h\"\n"
"#if defined(OFFSETMAPPING)\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
"varying vec3 eyevector;\n" "varying vec3 eyevector;\n"
"#endif\n" "#endif\n"
@ -530,7 +781,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"attribute vec2 v_lmcoord3;\n" "attribute vec2 v_lmcoord3;\n"
"attribute vec2 v_lmcoord4;\n" "attribute vec2 v_lmcoord4;\n"
"#endif\n" "#endif\n"
"#if defined(OFFSETMAPPING)\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
"uniform vec3 e_eyepos;\n" "uniform vec3 e_eyepos;\n"
"attribute vec3 v_normal;\n" "attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n" "attribute vec3 v_svector;\n"
@ -538,7 +789,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"void main ()\n" "void main ()\n"
"{\n" "{\n"
"#if defined(OFFSETMAPPING)\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n" "vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
"eyevector.x = -dot(eyeminusvertex, v_svector.xyz);\n" "eyevector.x = -dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n" "eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n"
@ -560,20 +811,23 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//samplers //samplers
"uniform sampler2D s_t0; //diffuse\n" "uniform sampler2D s_t0; //diffuse\n"
"uniform sampler2D s_t1; //lightmap0\n" "uniform sampler2D s_t1; //lightmap0\n"
"#if defined(OFFSETMAPPING) || defined(DELUXE)\n" "#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))\n"
"uniform sampler2D s_t2; //normal\n" "uniform sampler2D s_t2; //normal.rgb+height.a\n"
"#endif\n" "#endif\n"
"uniform sampler2D s_t3; //deluxe0\n" "uniform sampler2D s_t3; //deluxe0\n"
"#ifdef FULLBRIGHT\n" "#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4; //fullbright\n" "uniform sampler2D s_t4; //fullbright\n"
"#endif\n" "#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_t5; //specular\n"
"#endif\n"
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
"uniform sampler2D s_t5; //lightmap1\n" "uniform sampler2D s_t6; //lightmap1\n"
"uniform sampler2D s_t6; //lightmap2\n" "uniform sampler2D s_t7; //lightmap2\n"
"uniform sampler2D s_t7; //lightmap3\n" "uniform sampler2D s_t8; //lightmap3\n"
"uniform sampler2D s_t8; //deluxe1\n" "uniform sampler2D s_t9; //deluxe1\n"
"uniform sampler2D s_t9; //deluxe2\n" "uniform sampler2D s_t10; //deluxe2\n"
"uniform sampler2D s_t10; //deluxe3\n" "uniform sampler2D s_t11; //deluxe3\n"
"#endif\n" "#endif\n"
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
@ -582,6 +836,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform vec4 e_lmscale;\n" "uniform vec4 e_lmscale;\n"
"#endif\n" "#endif\n"
"uniform vec4 e_colourident;\n" "uniform vec4 e_colourident;\n"
"#ifdef SPECULAR\n"
"uniform float cvar_gl_specular;\n"
"#endif\n"
"#ifdef OFFSETMAPPING\n" "#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n" "#include \"sys/offsetmapping.h\"\n"
"#endif\n" "#endif\n"
@ -596,31 +853,53 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//yay, regular texture! //yay, regular texture!
"gl_FragColor = texture2D(s_t0, tc);\n" "gl_FragColor = texture2D(s_t0, tc);\n"
"#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR))\n"
"vec3 norm = normalize(texture2D(s_t2, tc).rgb - 0.5);\n"
"#elif defined(SPECULAR) || defined(DELUXE)\n"
"vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist.\n"
"#endif\n"
//modulate that by the lightmap(s) including deluxemap(s) //modulate that by the lightmap(s) including deluxemap(s)
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
"vec4 lightmaps;\n" "vec3 lightmaps;\n"
"#ifdef DELUXE\n" "#ifdef DELUXE\n"
"vec3 norm = texture2D(s_t2, tc).rgb;\n" "lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb * dot(norm, texture2D(s_t3, lm ).rgb);\n"
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0] * dot(norm, texture2D(s_t3, lm ).rgb);\n" "lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb * dot(norm, texture2D(s_t9, lm2).rgb);\n"
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1] * dot(norm, texture2D(s_t8, lm2).rgb);\n" "lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb * dot(norm, texture2D(s_t10, lm3).rgb);\n"
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2] * dot(norm, texture2D(s_t9, lm3).rgb);\n" "lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb * dot(norm, texture2D(s_t11,lm4).rgb);\n"
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3] * dot(norm, texture2D(s_t10,lm4).rgb);\n"
"#else\n" "#else\n"
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0];\n" "lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb;\n"
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1];\n" "lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb;\n"
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2];\n" "lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb;\n"
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3];\n" "lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb;\n"
"#endif\n" "#endif\n"
"#else\n"
"vec3 lightmaps = (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
//modulate by the bumpmap dot light
"#ifdef DELUXE\n"
"lightmaps *= dot(norm, 2.0*(texture2D(s_t3, lm).rgb-0.5));\n"
"#endif\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_t5, tc);\n"
"#ifdef DELUXE\n"
//not lightstyled...
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_t3, lm).rgb-0.5)); //this norm should be the deluxemap info instead\n"
"#else\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n"
"#endif\n"
"float spec = pow(max(dot(halfdir, norm), 0.0), 32.0 * specs.a);\n"
"spec *= cvar_gl_specular;\n"
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
//we default to something that is not garish when the light value is directly infront of every single pixel.
//we can justify this difference due to the rtlight editor etc showing the *4.
"gl_FragColor.rgb += spec * specs.rgb;\n"
"#endif\n"
//now we have our diffuse+specular terms, modulate by lightmap values.
"gl_FragColor.rgb *= lightmaps.rgb;\n" "gl_FragColor.rgb *= lightmaps.rgb;\n"
"#else\n"
"#ifdef DELUXE\n"
//gl_FragColor.rgb = dot(normalize(texture2D(s_t2, tc).rgb - 0.5), normalize(texture2D(s_t3, lm).rgb - 0.5));
//gl_FragColor.rgb = texture2D(s_t3, lm).rgb;
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb * dot(normalize(texture2D(s_t2, tc).rgb-0.5), 2.0*(texture2D(s_t3, lm).rgb-0.5));\n"
"#else\n"
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
"#endif\n"
"#endif\n"
//add on the fullbright //add on the fullbright
"#ifdef FULLBRIGHT\n" "#ifdef FULLBRIGHT\n"
@ -638,6 +917,46 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultwall",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float4 tc: TEXCOORD0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float2 lmtc: TEXCOORD1;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc.xy;\n"
"outp.lmtc = inp.tc.zw;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture[2];\n"
"SamplerState SampleType[2];\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return shaderTexture[0].Sample(SampleType[0], inp.tc) * shaderTexture[1].Sample(SampleType[1], inp.lmtc).bgra;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwarp", {QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n" "!!cvarf r_wateralpha\n"
@ -671,6 +990,91 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "defaultwarp",
"!!cvarf r_wateralpha\n"
"struct a2v {\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"struct v2f {\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_modelviewprojection, inp.pos);\n"
"outp.tc = inp.tc;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"float cvar_r_wateralpha;\n"
"float e_time;\n"
"sampler s_t0;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float2 ntc;\n"
"ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;\n"
"ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125;\n"
"float3 ts = tex2D(s_t0, ntc).xyz;\n"
"return float4(ts, cvar_r_wateralpha);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultwarp",
"!!cvarf r_wateralpha\n"
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
// float cvar_r_wateralpha;
// float e_time;
// sampler s_t0;
"Texture2D shaderTexture;\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"float2 ntc;\n"
"ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;\n"
"ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125;\n"
"return shaderTexture.Sample(SampleType, ntc);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "drawflat_wall", {QR_OPENGL, 110, "drawflat_wall",
"!!cvarv r_floorcolor\n" "!!cvarv r_floorcolor\n"
@ -705,6 +1109,49 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "drawflat_wall",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float4 tc: TEXCOORD0;\n"
"float3 norm: NORMAL;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float2 lmtc: TEXCOORD1;\n"
"float4 col: TEXCOORD2;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc.xy;\n"
"outp.lmtc = inp.tc.zw;\n"
"outp.col = ((inp.norm.z<0.73)?float4(0.5, 0.5, 0.5, 1):float4(0.25, 0.25, 0.5, 1));\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture;\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return inp.col * shaderTexture.Sample(SampleType, inp.lmtc);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "lpp_depthnorm", {QR_OPENGL, 110, "lpp_depthnorm",
"!!permu BUMP\n" "!!permu BUMP\n"
@ -1174,6 +1621,72 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "rtlight",
"!!permu BUMP\n"
"!!permu SPECULAR\n"
"!!permu OFFSETMAPPING\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
// texture units:
// s0=diffuse, s1=normal, s2=specular, s3=shadowmap
// custom modifiers:
// PCF(shadowmap)
// CUBE(projected cubemap)
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float3 tc: TEXCOORD0;\n"
"float3 n: NORMAL0;\n"
"float3 s: TANGENT0;\n"
"float3 t: BINORMAL0;\n"
"};\n"
"struct v2f\n"
"{\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float3 tc: TEXCOORD0;\n"
"float3 lpos: TEXCOORD1;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"float3 l_lightposition;\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_modelviewprojection, inp.pos);\n"
"outp.tc = inp.tc;\n"
"float3 lightminusvertex = l_lightposition - inp.pos.xyz;\n"
"outp.lpos.x = dot(lightminusvertex, inp.s.xyz);\n"
"outp.lpos.y = dot(lightminusvertex, inp.t.xyz);\n"
"outp.lpos.z = dot(lightminusvertex, inp.n.xyz);\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"sampler s_t0;\n"
"sampler s_t1;\n"
"float l_lightradius;\n"
"float3 l_lightcolour;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float3 col = l_lightcolour;\n"
"col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\n"
"float3 diff = tex2D(s_t0, inp.tc);\n"
"return float4(diff * col, 1);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "underwaterwarp", {QR_OPENGL, 110, "underwaterwarp",
"!!cvarf r_waterwarp\n" "!!cvarf r_waterwarp\n"
@ -1272,3 +1785,56 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
}, },
#endif #endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "terrain",
"struct a2v\n"
"{\n"
"float4 pos: POSITION;\n"
"float4 tc: TEXCOORD0;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"struct v2f\n"
"{\n"
"float4 pos: SV_POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"float2 lmtc: TEXCOORD1;\n"
"float4 vcol: COLOR0;\n"
"};\n"
"#include <ftedefs.h>\n"
"#ifdef VERTEX_SHADER\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"outp.pos = mul(m_model, inp.pos);\n"
"outp.pos = mul(m_view, outp.pos);\n"
"outp.pos = mul(m_projection, outp.pos);\n"
"outp.tc = inp.tc.xy;\n"
"outp.lmtc = inp.tc.zw;\n"
"outp.vcol = inp.vcol;\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"Texture2D shaderTexture[5];\n"
"SamplerState SampleType;\n"
"float4 main (v2f inp) : SV_TARGET\n"
"{\n"
"return float4(1,1,1,1);\n"
// float4 m = shaderTexture[4].Sample(SampleType, inp.tc) ;
// return inp.vcol*float4(m.aaa,1.0)*(
// shaderTexture[0].Sample(SampleType, inp.tc)*m.r
// + shaderTexture[1].Sample(SampleType, inp.tc)*m.g
// + shaderTexture[2].Sample(SampleType, inp.tc)*m.b
// + shaderTexture[3].Sample(SampleType, inp.tc)*1.0 - (m.r + m.g + m.b))
// ;
"}\n"
"#endif\n"
},
#endif

Some files were not shown because too many files have changed in this diff Show more