mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 06:32:00 +00:00
curtesy molgrum: allow_download_loc permits locs/*.loc to be downloaded. also fixes an strncmp. oops.
device ids with rawinput and xinput are now assigned only on the first event. this means the ordering is easily controllable, thus helping splitscreen usability. fix compile errors with the nolegacy builds. client updates "chat" userinfo to match ezquake. does not display them still. server now forwards them correctly for ezquake. android can now switch gles version. a bit crashy with it though. android: gyroscope is now available to csqc. android: added vid_dpi_x/y cvars. will be 0 on other platforms, for now. added screenshot_vr command, for 360-degree stereoscopic screenshots. fix a potential crash from frag parsing. added m_accel_style and friends, for nicer mouse acceleration. fixed const-correctness in a few places. added friendly spectate button to the server browser display a warning if an mdl has dodgy seam values. this won't affect fte, but can crash winquake. qcc: fix struct fields to at least appear to work. qcc: -I is finally implemented. qccgui: options now has tooltips, so people might have a chance of actually figuring out what each option does. menusys: game configs menu now scans for files rather than listing specific ones. should probably be tested more. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4998 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
9360a016c2
commit
46c63cbedb
91 changed files with 2150 additions and 1213 deletions
|
@ -266,11 +266,14 @@ ifeq ($(FTE_TARGET),linux64)
|
|||
CC=gcc -m64
|
||||
BITS=64
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),cygwin)
|
||||
FTE_TARGET=cyg
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(FTE_TARGET),) #user didn't specify prefered target
|
||||
ifneq ($(shell uname 2>&1 | grep CYGWIN),)
|
||||
FTE_TARGET=cygwin
|
||||
FTE_TARGET=cyg
|
||||
ANDROID_SCRIPT=android.bat
|
||||
endif
|
||||
ifneq ($(shell $(CC) -v 2>&1 | grep mingw),)
|
||||
|
@ -341,7 +344,7 @@ DO_CC=$(DO_ECHO) $(CC) $(LTO_CC) $(ALL_CFLAGS) -o $@ -c $<
|
|||
ifeq ($(FTE_TARGET),vc)
|
||||
BASELDFLAGS=
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),cygwin)
|
||||
ifeq ($(FTE_TARGET),cyg)
|
||||
BASELDFLAGS=-lm
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),morphos)
|
||||
|
@ -618,7 +621,8 @@ SERVER_OBJS = \
|
|||
httpserver.o
|
||||
|
||||
SERVERONLY_OBJS = \
|
||||
sv_sys_unix.o
|
||||
sv_sys_unix.o \
|
||||
sys_linux_threads.o
|
||||
|
||||
WINDOWSSERVERONLY_OBJS = \
|
||||
net_ssl_winsspi.o \
|
||||
|
@ -1220,8 +1224,7 @@ ifeq ($(FTE_TARGET),morphos)
|
|||
endif
|
||||
|
||||
|
||||
ifeq ($(FTE_TARGET),cygwin)
|
||||
|
||||
ifeq ($(FTE_TARGET),cyg)
|
||||
SV_DIR=sv_cygwin
|
||||
SV_LDFLAGS=-lz
|
||||
|
||||
|
|
|
@ -1090,12 +1090,14 @@ void CL_RecordMap_f (void)
|
|||
CL_Disconnect_f();
|
||||
return;
|
||||
}
|
||||
#ifdef NQPROT
|
||||
if (!strcmp(demoext, "dem"))
|
||||
{
|
||||
cls.demorecording = DPB_NETQUAKE;
|
||||
VFS_PUTS(cls.demooutfile, "-1\n");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
cls.demorecording = DPB_QUAKEWORLD;
|
||||
CL_WriteSetDemoMessage();
|
||||
}
|
||||
|
@ -1343,19 +1345,25 @@ void CL_Record_f (void)
|
|||
{
|
||||
char buffer[1024];
|
||||
FS_GetPackNames(buffer, sizeof(buffer), 2, true); /*retain extensions, or we'd have to assume pk3*/
|
||||
MSG_WriteByte(&buf, svc_stufftext);
|
||||
SZ_Write(&buf, "//paknames ", 11);
|
||||
SZ_Write(&buf, buffer, strlen(buffer));
|
||||
MSG_WriteString(&buf, "\n");
|
||||
if (*buffer)
|
||||
{
|
||||
MSG_WriteByte(&buf, svc_stufftext);
|
||||
SZ_Write(&buf, "//paknames ", 11);
|
||||
SZ_Write(&buf, buffer, strlen(buffer));
|
||||
MSG_WriteString(&buf, "\n");
|
||||
}
|
||||
}
|
||||
//Paks
|
||||
{
|
||||
char buffer[1024];
|
||||
FS_GetPackHashes(buffer, sizeof(buffer), false);
|
||||
MSG_WriteByte(&buf, svc_stufftext);
|
||||
SZ_Write(&buf, "//paks ", 7);
|
||||
SZ_Write(&buf, buffer, strlen(buffer));
|
||||
MSG_WriteString(&buf, "\n");
|
||||
if (*buffer)
|
||||
{
|
||||
MSG_WriteByte(&buf, svc_stufftext);
|
||||
SZ_Write(&buf, "//paks ", 7);
|
||||
SZ_Write(&buf, buffer, strlen(buffer));
|
||||
MSG_WriteString(&buf, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME: //at
|
||||
|
|
|
@ -1564,6 +1564,7 @@ qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend)
|
|||
int clientcount, lost;
|
||||
int curframe;
|
||||
int st = buf->cursize;
|
||||
int chatstate;
|
||||
|
||||
cl.movesequence = cls.netchan.outgoing_sequence; //make sure its correct even over map changes.
|
||||
curframe = cl.movesequence & UPDATE_MASK;
|
||||
|
@ -1582,8 +1583,20 @@ qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend)
|
|||
clientcount = 1;
|
||||
|
||||
|
||||
chatstate = 0;
|
||||
chatstate |= Key_Dest_Has(~kdm_game)?1:0;
|
||||
chatstate |= vid.activeapp?0:2;
|
||||
for (plnum = 0; plnum<clientcount; plnum++)
|
||||
{
|
||||
if (cl.playerview[plnum].chatstate != chatstate)
|
||||
{
|
||||
if (chatstate)
|
||||
CL_SetInfo(plnum, "chat", va("%i", chatstate));
|
||||
else
|
||||
CL_SetInfo(plnum, "chat", "");
|
||||
cl.playerview[plnum].chatstate = chatstate;
|
||||
}
|
||||
|
||||
cmd = &cl.outframes[curframe].cmd[plnum];
|
||||
*cmd = independantphysics[plnum];
|
||||
|
||||
|
|
|
@ -860,19 +860,23 @@ void CL_CheckForResend (void)
|
|||
connectinfo.fteext1 = Net_PextMask(1, false);
|
||||
connectinfo.fteext2 = Net_PextMask(2, false);
|
||||
}
|
||||
#ifdef NQPROT
|
||||
else if (cls.demorecording == DPB_NETQUAKE && cls.protocol != CP_NETQUAKE)
|
||||
{
|
||||
connectinfo.protocol = CP_NETQUAKE;
|
||||
connectinfo.subprotocol = CPNQ_FITZ666;
|
||||
//FIXME: use pext.
|
||||
}
|
||||
else if (cls.demorecording == DPB_QUAKE2 && cls.protocol != CP_NETQUAKE)
|
||||
#endif
|
||||
#ifdef Q2CLIENT
|
||||
else if (cls.demorecording == DPB_QUAKE2 && cls.protocol != CP_QUAKE2)
|
||||
{
|
||||
connectinfo.protocol = CP_QUAKE2;
|
||||
connectinfo.subprotocol = PROTOCOL_VERSION_Q2;
|
||||
connectinfo.fteext1 = PEXT_MODELDBL|PEXT_SOUNDDBL|PEXT_SPLITSCREEN;
|
||||
//FIXME: use pext.
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1553,6 +1557,8 @@ void CL_ClearState (void)
|
|||
cl.playerview[i].viewheight = DEFAULT_VIEWHEIGHT;
|
||||
cl.playerview[i].maxspeed = 320;
|
||||
cl.playerview[i].entgravity = 1;
|
||||
|
||||
cl.playerview[i].chatstate = atoi(Info_ValueForKey(cls.userinfo[i], "chat"));
|
||||
}
|
||||
#ifdef QUAKESTATS
|
||||
for (i = 0; i < MAX_CLIENTS; i++) //in case some server doesn't support it
|
||||
|
@ -1672,6 +1678,8 @@ void CL_Disconnect (void)
|
|||
cl.intermissionmode = IM_NONE;
|
||||
cl.oldgametime = 0;
|
||||
|
||||
memset(&r_refdef, 0, sizeof(r_refdef));
|
||||
|
||||
#ifdef NQPROT
|
||||
cls.signon=0;
|
||||
#endif
|
||||
|
@ -3811,9 +3819,6 @@ void CL_Init (void)
|
|||
ver = va("%s v%i.%02i", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR);
|
||||
|
||||
Info_SetValueForStarKey (cls.userinfo[0], "*ver", ver, sizeof(cls.userinfo[0]));
|
||||
Info_SetValueForStarKey (cls.userinfo[1], "*ss", "1", sizeof(cls.userinfo[1]));
|
||||
Info_SetValueForStarKey (cls.userinfo[2], "*ss", "1", sizeof(cls.userinfo[2]));
|
||||
Info_SetValueForStarKey (cls.userinfo[3], "*ss", "1", sizeof(cls.userinfo[3]));
|
||||
|
||||
InitValidation();
|
||||
|
||||
|
@ -4821,6 +4826,54 @@ qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CL_UpdateHeadAngles(void)
|
||||
{
|
||||
/*FIXME: no idea what I'm doing with this. lets just not break anything for now
|
||||
//identity, for now
|
||||
vec3_t headchange[3] =
|
||||
{
|
||||
{1,0,0},
|
||||
{0,1,0},
|
||||
{0,0,1}
|
||||
};
|
||||
vec3_t tmp[3], tmp2[3];
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
|
||||
tmp2[0][0] = 0;
|
||||
tmp2[0][1] = host_frametime*90;
|
||||
tmp2[0][2] = 0;
|
||||
AngleVectorsFLU(tmp2[0], headchange[0], headchange[1], headchange[2]);
|
||||
|
||||
switch(cl_headmode.ival)
|
||||
{
|
||||
case 3: //head angles change both
|
||||
R_ConcatRotations(headchange, r_refdef.headaxis, tmp);
|
||||
break;
|
||||
case 2: //head changes are entirely relative to the 'view' angle
|
||||
R_ConcatRotations(headchange, r_refdef.headaxis, tmp);
|
||||
memcpy(r_refdef.headaxis, tmp, sizeof(r_refdef.headaxis));
|
||||
break;
|
||||
case 1: //head changes change the view angle directly.
|
||||
|
||||
AngleVectorsFLU(pv->viewangles, tmp[0], tmp[1], tmp[2]);
|
||||
R_ConcatRotations(headchange, tmp, tmp2);
|
||||
VectorAngles(tmp2[0], tmp2[2], pv->viewangles);
|
||||
pv->viewangles[0] *= -1;
|
||||
|
||||
//fall through
|
||||
default:
|
||||
case 0: //off
|
||||
VectorSet(r_refdef.headaxis[0], 1, 0, 0);
|
||||
VectorSet(r_refdef.headaxis[1], 0, 1, 0);
|
||||
VectorSet(r_refdef.headaxis[2], 0, 0, 1);
|
||||
break;
|
||||
}
|
||||
*/
|
||||
VectorSet(r_refdef.headaxis[0], 1, 0, 0);
|
||||
VectorSet(r_refdef.headaxis[1], 0, 1, 0);
|
||||
VectorSet(r_refdef.headaxis[2], 0, 0, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_Frame
|
||||
|
@ -4903,9 +4956,7 @@ double Host_Frame (double time)
|
|||
Key_Dest_Has(kdm_gmenu) ||
|
||||
Key_Dest_Has(kdm_emenu) ||
|
||||
Key_Dest_Has(kdm_editor) ||
|
||||
#ifdef _WIN32
|
||||
!ActiveApp ||
|
||||
#endif
|
||||
!vid.activeapp ||
|
||||
cl.paused
|
||||
;
|
||||
// TODO: check if minimized or unfocused
|
||||
|
@ -5124,13 +5175,16 @@ double Host_Frame (double time)
|
|||
|
||||
if (SCR_UpdateScreen && !vid.isminimized)
|
||||
{
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
extern cvar_t scr_chatmodecvar, r_stereo_method;
|
||||
|
||||
if (scr_chatmodecvar.ival && cl.intermissionmode == IM_NONE)
|
||||
scr_chatmode = (cl.spectator&&cl.splitclients<2&&cls.state == ca_active)?2:1;
|
||||
else
|
||||
scr_chatmode = 0;
|
||||
|
||||
r_refdef.stereomethod = r_stereo_method.ival;
|
||||
CL_UpdateHeadAngles();
|
||||
|
||||
SCR_UpdateScreen ();
|
||||
|
||||
if (R2D_Flush)
|
||||
|
@ -5239,7 +5293,7 @@ void CL_StartCinematicOrMenu(void)
|
|||
}
|
||||
if (startuppending)
|
||||
{
|
||||
if (startuppending == 2)
|
||||
if (startuppending == 2) //installer finished.
|
||||
Cbuf_AddText("\nfs_restart\nvid_restart\n", RESTRICT_LOCAL);
|
||||
startuppending = false;
|
||||
Key_Dest_Remove(kdm_console); //make sure console doesn't stay up weirdly.
|
||||
|
@ -5461,45 +5515,64 @@ void CL_ExecInitialConfigs(char *resetcommand)
|
|||
|
||||
void Host_FinishLoading(void)
|
||||
{
|
||||
//the filesystem has retrieved its manifest, but might still be waiting for paks to finish downloading.
|
||||
extern qboolean r_blockvidrestart;
|
||||
if (r_blockvidrestart == true)
|
||||
{
|
||||
//1 means we need to init the filesystem
|
||||
|
||||
//make sure the filesystem has some default if no manifest was loaded.
|
||||
FS_ChangeGame(NULL, true, true);
|
||||
//the filesystem has retrieved its manifest, but might still be waiting for paks to finish downloading.
|
||||
|
||||
if (waitingformanifest)
|
||||
//make sure the filesystem has some default if no manifest was loaded.
|
||||
FS_ChangeGame(NULL, true, true);
|
||||
|
||||
if (waitingformanifest)
|
||||
return;
|
||||
|
||||
Con_History_Load();
|
||||
|
||||
Cmd_StuffCmds();
|
||||
Cbuf_Execute ();
|
||||
|
||||
CL_ArgumentOverrides();
|
||||
#ifndef CLIENTONLY
|
||||
SV_ArgumentOverrides();
|
||||
#endif
|
||||
|
||||
Con_Printf ("\n%s\n", version_string());
|
||||
|
||||
Con_DPrintf("This program is free software; you can redistribute it and/or "
|
||||
"modify it under the terms of the GNU General Public License "
|
||||
"as published by the Free Software Foundation; either version 2 "
|
||||
"of the License, or (at your option) any later version."
|
||||
"\n"
|
||||
"This program is distributed in the hope that it will be useful, "
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of "
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
|
||||
"\n"
|
||||
"See the GNU General Public License for more details.\n");
|
||||
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && defined(WEBCLIENT)
|
||||
if (Sys_RunInstaller())
|
||||
Sys_Quit();
|
||||
#endif
|
||||
|
||||
r_blockvidrestart = 2;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
//android needs to wait a bit longer before it's allowed to init its video properly.
|
||||
extern int sys_glesversion;
|
||||
if (!sys_glesversion)
|
||||
return;
|
||||
|
||||
Con_History_Load();
|
||||
|
||||
Cmd_StuffCmds();
|
||||
Cbuf_Execute ();
|
||||
|
||||
CL_ArgumentOverrides();
|
||||
#ifndef CLIENTONLY
|
||||
SV_ArgumentOverrides();
|
||||
#endif
|
||||
|
||||
Con_Printf ("\n%s\n", version_string());
|
||||
|
||||
Con_DPrintf("This program is free software; you can redistribute it and/or "
|
||||
"modify it under the terms of the GNU General Public License "
|
||||
"as published by the Free Software Foundation; either version 2 "
|
||||
"of the License, or (at your option) any later version."
|
||||
"\n"
|
||||
"This program is distributed in the hope that it will be useful, "
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of "
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "
|
||||
"\n"
|
||||
"See the GNU General Public License for more details.\n");
|
||||
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && defined(WEBCLIENT)
|
||||
if (Sys_RunInstaller())
|
||||
Sys_Quit();
|
||||
#endif
|
||||
|
||||
Renderer_Start();
|
||||
|
||||
CL_StartCinematicOrMenu();
|
||||
if (r_blockvidrestart == 2)
|
||||
{ //2 is part of the initial startup
|
||||
Renderer_Start();
|
||||
CL_StartCinematicOrMenu();
|
||||
}
|
||||
else //3 flags for a renderer restart
|
||||
Renderer_Start();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2009,7 +2009,7 @@ void CL_ParseChunkedDownload(qdownload_t *dl)
|
|||
|
||||
if (flag < 0)
|
||||
{
|
||||
if (flag == -4)
|
||||
if (flag == DLERR_REDIRECTFILE)
|
||||
{
|
||||
if (CL_AllowArbitaryDownload(svname))
|
||||
{
|
||||
|
@ -2019,11 +2019,11 @@ void CL_ParseChunkedDownload(qdownload_t *dl)
|
|||
}
|
||||
svname = dl->remotename;
|
||||
}
|
||||
else if (flag == -3)
|
||||
else if (flag == DLERR_UNKNOWN)
|
||||
Con_Printf("Server reported an error when downloading file \"%s\"\n", svname);
|
||||
else if (flag == -2)
|
||||
else if (flag == DLERR_PERMISSIONS)
|
||||
Con_Printf("Server permissions deny downloading file \"%s\"\n", svname);
|
||||
else
|
||||
else //if (flag == DLERR_FILENOTFOUND)
|
||||
Con_Printf("Couldn't find file \"%s\" on the server\n", svname);
|
||||
|
||||
if (dl)
|
||||
|
@ -2292,7 +2292,7 @@ void DL_Abort(qdownload_t *dl, enum qdlabort aborttype)
|
|||
for (b = dl->dlblocks; b; b = n)
|
||||
{
|
||||
if (b->state == DLB_RECEIVED)
|
||||
VFS_PRINTF(parts, "c "fPRIllx" "fPRIllx"\n", (long long)b->start, (long long)b->end);
|
||||
VFS_PRINTF(parts, "c %"PRIx64" %"PRIx64"\n", (long long)b->start, (long long)b->end);
|
||||
else
|
||||
{
|
||||
for(;;)
|
||||
|
@ -2307,7 +2307,7 @@ void DL_Abort(qdownload_t *dl, enum qdlabort aborttype)
|
|||
}
|
||||
break;
|
||||
}
|
||||
VFS_PRINTF(parts, "m "fPRIllx" "fPRIllx"\n", (long long)b->start, (long long)b->end);
|
||||
VFS_PRINTF(parts, "m %"PRIx64" %"PRIx64"\n", (long long)b->start, (long long)b->end);
|
||||
}
|
||||
|
||||
n = b->next;
|
||||
|
@ -4774,6 +4774,8 @@ void CL_ProcessUserInfo (int slot, player_info_t *player)
|
|||
|
||||
Skin_FlushPlayers();
|
||||
}
|
||||
else if (cl.teamplay && cl.spectator && slot == Cam_TrackNum(&cl.playerview[0])) //skin forcing cares about the team of the guy we're tracking.
|
||||
Skin_FlushPlayers();
|
||||
else if (cls.state == ca_active)
|
||||
Skin_Find (player);
|
||||
|
||||
|
|
|
@ -219,11 +219,6 @@ float scr_disabled_time;
|
|||
|
||||
float oldsbar = 0;
|
||||
|
||||
void SCR_ScreenShot_f (void);
|
||||
void SCR_ScreenShot_Mega_f(void);
|
||||
void SCR_RSShot_f (void);
|
||||
void SCR_CPrint_f(void);
|
||||
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t show_fps = SCVARF("show_fps", "0", CVAR_ARCHIVE);
|
||||
cvar_t show_fps_x = SCVAR("show_fps_x", "-1");
|
||||
|
@ -243,6 +238,15 @@ cvar_t scr_showobituaries = CVAR("scr_showobituaries", "0");
|
|||
|
||||
void *scr_curcursor;
|
||||
|
||||
|
||||
static void SCR_CPrint_f(void)
|
||||
{
|
||||
if (Cmd_Argc() == 2)
|
||||
SCR_CenterPrint(0, Cmd_Argv(1), true);
|
||||
else
|
||||
SCR_CenterPrint(0, Cmd_Args(), true);
|
||||
}
|
||||
|
||||
extern char cl_screengroup[];
|
||||
void CLSCR_Init(void)
|
||||
{
|
||||
|
@ -508,14 +512,6 @@ void VARGS Stats_Message(char *msg, ...)
|
|||
p->time_start = cl.time;
|
||||
}
|
||||
|
||||
void SCR_CPrint_f(void)
|
||||
{
|
||||
if (Cmd_Argc() == 2)
|
||||
SCR_CenterPrint(0, Cmd_Argv(1), true);
|
||||
else
|
||||
SCR_CenterPrint(0, Cmd_Args(), true);
|
||||
}
|
||||
|
||||
#define MAX_CPRINT_LINES 128
|
||||
void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
||||
{
|
||||
|
@ -1319,56 +1315,6 @@ void SCR_SizeDown_f (void)
|
|||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_Init
|
||||
==================
|
||||
*/
|
||||
void SCR_Init (void)
|
||||
{
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommandD ("screenshot_mega",SCR_ScreenShot_Mega_f, "screenshot_mega <name> [width] [height]\nTakes a screenshot with explicit sizes that are not tied to the size of your monitor, allowing for true monstrosities.");
|
||||
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
|
||||
Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
|
||||
Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
|
||||
|
||||
scr_net = R2D_SafePicFromWad ("net");
|
||||
scr_turtle = R2D_SafePicFromWad ("turtle");
|
||||
|
||||
scr_initialized = true;
|
||||
}
|
||||
|
||||
void SCR_DeInit (void)
|
||||
{
|
||||
int i;
|
||||
if (scr_curcursor)
|
||||
{
|
||||
rf->VID_SetCursor(scr_curcursor);
|
||||
scr_curcursor = NULL;
|
||||
}
|
||||
for (i = 0; i < countof(key_customcursor); i++)
|
||||
{
|
||||
if (key_customcursor[i].handle)
|
||||
{
|
||||
rf->VID_DestroyCursor(key_customcursor[i].handle);
|
||||
key_customcursor[i].handle = NULL;
|
||||
}
|
||||
key_customcursor[i].dirty = true;
|
||||
}
|
||||
if (scr_initialized)
|
||||
{
|
||||
scr_initialized = false;
|
||||
|
||||
Cmd_RemoveCommand ("screenshot");
|
||||
Cmd_RemoveCommand ("screenshot_mega");
|
||||
Cmd_RemoveCommand ("sizeup");
|
||||
Cmd_RemoveCommand ("sizedown");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
SCR_DrawTurtle
|
||||
|
@ -2082,7 +2028,7 @@ typedef struct _TargaHeader {
|
|||
qboolean screenshotJPEG(char *filename, enum fs_relative fsroot, int compression, qbyte *screendata, int screenwidth, int screenheight, enum uploadfmt fmt);
|
||||
#endif
|
||||
#ifdef AVAIL_PNGLIB
|
||||
int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, qbyte *pixels, int width, int height, enum uploadfmt fmt);
|
||||
int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, void **buffers, int numbuffers, int width, int height, enum uploadfmt fmt);
|
||||
#endif
|
||||
void WriteBMPFile(char *filename, enum fs_relative fsroot, qbyte *in, int width, int height);
|
||||
|
||||
|
@ -2202,7 +2148,7 @@ int MipColor(int r, int g, int b)
|
|||
return best;
|
||||
}
|
||||
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void *rgb_buffer, int width, int height, enum uploadfmt fmt)
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int width, int height, enum uploadfmt fmt)
|
||||
{
|
||||
#if defined(AVAIL_PNGLIB) || defined(AVAIL_JPEGLIB)
|
||||
extern cvar_t scr_sshot_compression;
|
||||
|
@ -2212,35 +2158,33 @@ qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void *rgb_buff
|
|||
|
||||
COM_FileExtension(filename, ext, sizeof(ext));
|
||||
|
||||
if (!rgb_buffer)
|
||||
return false;
|
||||
|
||||
#ifdef AVAIL_PNGLIB
|
||||
if (!Q_strcasecmp(ext, "png"))
|
||||
if (!Q_strcasecmp(ext, "png") || !Q_strcasecmp(ext, "pns"))
|
||||
{
|
||||
//png can do bgr+rgb
|
||||
//rgba bgra will result in an extra alpha chan
|
||||
return Image_WritePNG(filename, fsroot, scr_sshot_compression.value, rgb_buffer, width, height, fmt);
|
||||
//actual stereo is also supported. huzzah.
|
||||
return Image_WritePNG(filename, fsroot, scr_sshot_compression.value, buffer, numbuffers, width, height, fmt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef AVAIL_JPEGLIB
|
||||
if (!Q_strcasecmp(ext, "jpeg") || !Q_strcasecmp(ext, "jpg"))
|
||||
{
|
||||
return screenshotJPEG(filename, fsroot, scr_sshot_compression.value, rgb_buffer, width, height, fmt);
|
||||
return screenshotJPEG(filename, fsroot, scr_sshot_compression.value, buffer[0], width, height, fmt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* if (!Q_strcasecmp(ext, "bmp"))
|
||||
{
|
||||
return WriteBMPFile(pcxname, rgb_buffer, width, height);
|
||||
return WriteBMPFile(pcxname, buffer[0], width, height);
|
||||
}
|
||||
else*/
|
||||
if (!Q_strcasecmp(ext, "pcx"))
|
||||
{
|
||||
int y, x, s;
|
||||
qbyte *src, *dest;
|
||||
qbyte *newbuf = rgb_buffer;
|
||||
qbyte *newbuf = buffer[0];
|
||||
if (fmt == TF_RGB24 || fmt == TF_RGBA32)
|
||||
{
|
||||
s = (fmt == TF_RGB24)?3:4;
|
||||
|
@ -2277,7 +2221,7 @@ qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void *rgb_buff
|
|||
WritePCXfile (filename, fsroot, newbuf, width, height, width, host_basepal, false);
|
||||
}
|
||||
else if (!Q_strcasecmp(ext, "tga")) //tga
|
||||
return WriteTGA(filename, fsroot, rgb_buffer, width, height, fmt);
|
||||
return WriteTGA(filename, fsroot, buffer[0], width, height, fmt);
|
||||
else //extension / type not recognised.
|
||||
return false;
|
||||
return true;
|
||||
|
@ -2288,7 +2232,7 @@ qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void *rgb_buff
|
|||
SCR_ScreenShot_f
|
||||
==================
|
||||
*/
|
||||
void SCR_ScreenShot_f (void)
|
||||
static void SCR_ScreenShot_f (void)
|
||||
{
|
||||
char sysname[1024];
|
||||
char pcxname[MAX_QPATH];
|
||||
|
@ -2325,7 +2269,7 @@ void SCR_ScreenShot_f (void)
|
|||
//
|
||||
for (i=0 ; i<stop ; i++)
|
||||
{
|
||||
Q_snprintfz(pcxname, sizeof(pcxname), "%s-%s-%i.%s", scr_sshot_prefix.string, date, i, scr_sshot_type.string);
|
||||
Q_snprintfz(pcxname, sizeof(pcxname), "%s%s-%i.%s", scr_sshot_prefix.string, date, i, scr_sshot_type.string);
|
||||
|
||||
if (!(vfs = FS_OpenVFS(pcxname, "rb", FS_GAMEONLY)))
|
||||
break; // file doesn't exist
|
||||
|
@ -2343,7 +2287,7 @@ void SCR_ScreenShot_f (void)
|
|||
rgbbuffer = VID_GetRGBInfo(&width, &height, &fmt);
|
||||
if (rgbbuffer)
|
||||
{
|
||||
if (SCR_ScreenShot(pcxname, FS_GAMEONLY, rgbbuffer, width, height, fmt))
|
||||
if (SCR_ScreenShot(pcxname, FS_GAMEONLY, &rgbbuffer, 1, width, height, fmt))
|
||||
{
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
BZ_Free(rgbbuffer);
|
||||
|
@ -2354,43 +2298,12 @@ void SCR_ScreenShot_f (void)
|
|||
Con_Printf ("Couldn't write %s\n", sysname);
|
||||
}
|
||||
|
||||
void SCR_ScreenShot_Mega_f(void)
|
||||
void *SCR_ScreenShot_FBO(int fbwidth, int fbheight, enum uploadfmt *fmt)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
qbyte *rgbbuffer;
|
||||
char filename[MAX_QPATH];
|
||||
enum uploadfmt fmt;
|
||||
|
||||
//poke the various modes into redrawing the screen (without huds), to avoid any menus or console drawn over the top of the current backbuffer.
|
||||
//FIXME: clear-to-black first
|
||||
int width, height;
|
||||
void *buf;
|
||||
qboolean okay = false;
|
||||
|
||||
char *screenyname = Cmd_Argv(1);
|
||||
unsigned int fbwidth = strtoul(Cmd_Argv(2), NULL, 0);
|
||||
unsigned int fbheight = strtoul(Cmd_Argv(3), NULL, 0);
|
||||
|
||||
if (Cmd_IsInsecure())
|
||||
return;
|
||||
|
||||
if (qrenderer <= QR_HEADLESS)
|
||||
{
|
||||
Con_Printf("No renderer active\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fbwidth)
|
||||
fbwidth = sh_config.texture_maxsize;
|
||||
fbwidth = bound(0, fbwidth, sh_config.texture_maxsize);
|
||||
if (!fbheight)
|
||||
fbheight = (fbwidth * 3)/4;
|
||||
fbheight = bound(0, fbheight, sh_config.texture_maxsize);
|
||||
if (!*screenyname)
|
||||
screenyname = "megascreeny";
|
||||
|
||||
Q_snprintfz(filename, sizeof(filename), "%s-%s", scr_sshot_prefix.string, screenyname);
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
Q_strncpyz(r_refdef.rt_destcolour[0].texname, "megascreeny", sizeof(r_refdef.rt_destcolour[0].texname));
|
||||
R2D_RT_Configure(r_refdef.rt_destcolour[0].texname, fbwidth, fbheight, 1);
|
||||
BE_RenderToTextureUpdate2d(true);
|
||||
|
@ -2415,33 +2328,254 @@ void SCR_ScreenShot_Mega_f(void)
|
|||
V_RenderView ();
|
||||
okay = true;
|
||||
}
|
||||
|
||||
//okay, we drew something, we're good to save a screeny.
|
||||
if (okay)
|
||||
//fixme: add a way to get+save the depth values too
|
||||
if (!okay)
|
||||
{
|
||||
rgbbuffer = VID_GetRGBInfo(&width, &height, &fmt);
|
||||
if (rgbbuffer)
|
||||
{
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, rgbbuffer, width, height, fmt))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
BZ_Free(rgbbuffer);
|
||||
}
|
||||
buf = NULL;
|
||||
width = height = 0;
|
||||
*fmt = TF_INVALID;
|
||||
}
|
||||
else
|
||||
buf = VID_GetRGBInfo(&width, &height, fmt);
|
||||
|
||||
R2D_RT_Configure(r_refdef.rt_destcolour[0].texname, 0, 0, 0);
|
||||
Q_strncpyz(r_refdef.rt_destcolour[0].texname, "", sizeof(r_refdef.rt_destcolour[0].texname));
|
||||
BE_RenderToTextureUpdate2d(true);
|
||||
|
||||
if (width != fbwidth || height != fbheight)
|
||||
{
|
||||
BZ_Free(buf);
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void SCR_ScreenShot_Mega_f(void)
|
||||
{
|
||||
int width[2];
|
||||
int height[2];
|
||||
void *buffers[2];
|
||||
enum uploadfmt fmt[2];
|
||||
int numbuffers = 0;
|
||||
int buf;
|
||||
char filename[MAX_QPATH];
|
||||
stereomethod_t osm = r_refdef.stereomethod;
|
||||
|
||||
//massage the rendering code to redraw the screen with an fbo forced.
|
||||
//this allows us to generate screenshots which are not otherwise possible to actually draw.
|
||||
//this includes larger resolutions (although the lack of stiching leaves us subject to gpu limits of about 16k)
|
||||
|
||||
char *screenyname = Cmd_Argv(1);
|
||||
unsigned int fbwidth = strtoul(Cmd_Argv(2), NULL, 0);
|
||||
unsigned int fbheight = strtoul(Cmd_Argv(3), NULL, 0);
|
||||
char ext[8];
|
||||
|
||||
if (Cmd_IsInsecure())
|
||||
return;
|
||||
|
||||
if (qrenderer <= QR_HEADLESS)
|
||||
{
|
||||
Con_Printf("No renderer active\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fbwidth)
|
||||
fbwidth = sh_config.texture_maxsize;
|
||||
fbwidth = bound(0, fbwidth, sh_config.texture_maxsize);
|
||||
if (!fbheight)
|
||||
fbheight = (fbwidth * 3)/4;
|
||||
fbheight = bound(0, fbheight, sh_config.texture_maxsize);
|
||||
|
||||
if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/')
|
||||
screenyname = "";
|
||||
if (!*screenyname)
|
||||
{
|
||||
screenyname = "megascreeny";
|
||||
Q_snprintfz(filename, sizeof(filename), "%s%s", scr_sshot_prefix.string, screenyname);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *mangle;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s", scr_sshot_prefix.string);
|
||||
mangle = COM_SkipPath(filename);
|
||||
Q_snprintfz(mangle, sizeof(filename) - (mangle-filename), "%s", screenyname);
|
||||
}
|
||||
if (!strcmp(Cmd_Argv(0), "screenshot_stereo"))
|
||||
COM_DefaultExtension (filename, "png", sizeof(filename));
|
||||
else
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
COM_FileExtension(filename, ext, sizeof(ext));
|
||||
if (!strcmp(Cmd_Argv(0), "screenshot_stereo") || !strcmp(ext, "pns") || osm == STEREO_QUAD)
|
||||
numbuffers = 2; //stereo png
|
||||
else
|
||||
numbuffers = 1;
|
||||
|
||||
if (numbuffers == 2 && Q_strcasecmp(ext, "png") && Q_strcasecmp(ext, "pns"))
|
||||
{
|
||||
Con_Printf("Only png format is supported for stereo screenshots\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(buf = 0; buf < numbuffers; buf++)
|
||||
{
|
||||
if (numbuffers == 2)
|
||||
{
|
||||
if (buf)
|
||||
r_refdef.stereomethod = STEREO_RIGHTONLY;
|
||||
else
|
||||
r_refdef.stereomethod = STEREO_LEFTONLY;
|
||||
}
|
||||
|
||||
buffers[buf] = SCR_ScreenShot_FBO(fbwidth, fbheight, &fmt[buf]);
|
||||
|
||||
if (width[buf] != width[0] || height[buf] != height[0] || fmt[buf] != fmt[0])
|
||||
{ //invalid is better than unmatched.
|
||||
BZ_Free(buffers[buf]);
|
||||
buffers[buf] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (numbuffers == 2 && !buffers[1])
|
||||
numbuffers = 1;
|
||||
|
||||
//okay, we drew something, we're good to save a screeny.
|
||||
if (buffers[0])
|
||||
{
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, buffers, numbuffers, width[0], height[0], fmt[0]))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to capture screenshot\n");
|
||||
|
||||
for(buf = 0; buf < numbuffers; buf++)
|
||||
BZ_Free(buffers[buf]);
|
||||
|
||||
r_refdef.stereomethod = osm;
|
||||
}
|
||||
|
||||
static void SCR_ScreenShot_VR_f(void)
|
||||
{
|
||||
char *screenyname = Cmd_Argv(1);
|
||||
int width = atoi(Cmd_Argv(2));
|
||||
//we spin the camera around, taking slices from equirectangular screenshots
|
||||
char filename[MAX_QPATH];
|
||||
int height; //equirectangular 360 * 180 gives a nice clean ratio
|
||||
int px = 4;
|
||||
int step = atof(Cmd_Argv(3));
|
||||
unsigned int *left_buffer;
|
||||
unsigned int *right_buffer;
|
||||
unsigned int *buf;
|
||||
enum uploadfmt fmt;
|
||||
int lx, rx, x, y;
|
||||
vec3_t baseang;
|
||||
float ang;
|
||||
extern cvar_t r_projection, r_stereo_separation;
|
||||
VectorCopy(r_refdef.viewangles, baseang);
|
||||
|
||||
if (width <= 2)
|
||||
width = 2048;
|
||||
height = width/2;
|
||||
if (step <= 0)
|
||||
step = 5;
|
||||
|
||||
left_buffer = BZF_Malloc (width*height*2*px);
|
||||
right_buffer = left_buffer + width*height;
|
||||
|
||||
if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/')
|
||||
screenyname = "";
|
||||
if (!*screenyname)
|
||||
{
|
||||
screenyname = "vr";
|
||||
Q_snprintfz(filename, sizeof(filename), "%s%s", scr_sshot_prefix.string, screenyname);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *mangle;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s", scr_sshot_prefix.string);
|
||||
mangle = COM_SkipPath(filename);
|
||||
Q_snprintfz(mangle, sizeof(filename) - (mangle-filename), "%s", screenyname);
|
||||
}
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
|
||||
|
||||
if (!left_buffer)
|
||||
{
|
||||
Con_Printf("out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
r_projection.ival = PROJ_EQUIRECTANGULAR;
|
||||
for (lx = 0; lx < width; lx = rx)
|
||||
{
|
||||
rx = lx + step;
|
||||
if (rx > width)
|
||||
rx = width;
|
||||
|
||||
r_refdef.stereomethod = STEREO_OFF;
|
||||
|
||||
cl.playerview->simangles[0] = 0; //pitch is BAD
|
||||
cl.playerview->simangles[1] = baseang[1];// - 360.0*(lx + 0.5*(rx-lx)) / width;
|
||||
cl.playerview->simangles[2] = 0; //roll is BAD
|
||||
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||
|
||||
//FIXME: it should be possible to do this more inteligently, and get both strips with a single render.
|
||||
|
||||
ang = M_PI*2*(baseang[1]/360.0 + (lx+0.5*(rx-lx))/width);
|
||||
r_refdef.eyeoffset[0] = sin(ang) * r_stereo_separation.value * 0.5;
|
||||
r_refdef.eyeoffset[1] = cos(ang) * r_stereo_separation.value * 0.5;
|
||||
r_refdef.eyeoffset[2] = 0;
|
||||
buf = SCR_ScreenShot_FBO(width, height, &fmt);
|
||||
if (buf && fmt == TF_BGRA32)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
left_buffer[y*width + x] = buf[y*width + /*(width-step)/2 +*/ x];
|
||||
}
|
||||
BZ_Free(buf);
|
||||
|
||||
r_refdef.eyeoffset[0] *= -1;
|
||||
r_refdef.eyeoffset[1] *= -1;
|
||||
r_refdef.eyeoffset[2] = 0;
|
||||
buf = SCR_ScreenShot_FBO(width, height, &fmt);
|
||||
if (buf && fmt == TF_BGRA32)
|
||||
{
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
right_buffer[y*width + x] = buf[y*width + /*(width-step)/2 +*/ x];
|
||||
}
|
||||
BZ_Free(buf);
|
||||
}
|
||||
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, &left_buffer, 1, width, height*2, TF_BGRA32))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
|
||||
BZ_Free(left_buffer);
|
||||
|
||||
r_projection.ival = r_projection.value;
|
||||
VectorCopy(baseang, r_refdef.viewangles);
|
||||
VectorClear(r_refdef.eyeoffset);
|
||||
}
|
||||
|
||||
void SCR_ScreenShot_EnvMap_f(void)
|
||||
{
|
||||
Con_Printf("Not implemented\n");
|
||||
}
|
||||
|
||||
|
||||
// from gl_draw.c
|
||||
qbyte *draw_chars; // 8*8 graphic characters
|
||||
|
||||
void SCR_DrawCharToSnap (int num, qbyte *dest, int width)
|
||||
static void SCR_DrawCharToSnap (int num, qbyte *dest, int width)
|
||||
{
|
||||
int row, col;
|
||||
qbyte *source;
|
||||
|
@ -2472,7 +2606,7 @@ void SCR_DrawCharToSnap (int num, qbyte *dest, int width)
|
|||
|
||||
}
|
||||
|
||||
void SCR_DrawStringToSnap (const char *s, qbyte *buf, int x, int y, int width)
|
||||
static void SCR_DrawStringToSnap (const char *s, qbyte *buf, int x, int y, int width)
|
||||
{
|
||||
qbyte *dest;
|
||||
const unsigned char *p;
|
||||
|
@ -2537,6 +2671,7 @@ qboolean SCR_RSShot (void)
|
|||
BZ_Free(newbuf);
|
||||
return false;
|
||||
}
|
||||
//FIXME: bgra
|
||||
|
||||
w = RSSHOT_WIDTH;
|
||||
h = RSSHOT_HEIGHT;
|
||||
|
@ -2620,7 +2755,6 @@ Brings the console down and fades the palettes back to normal
|
|||
*/
|
||||
void SCR_BringDownConsole (void)
|
||||
{
|
||||
int i;
|
||||
int pnum;
|
||||
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
|
@ -2628,9 +2762,6 @@ void SCR_BringDownConsole (void)
|
|||
scr_centerprint[pnum].charcount = 0;
|
||||
cl.playerview[pnum].cshifts[CSHIFT_CONTENTS].percent = 0; // no area contents palette on next frame
|
||||
}
|
||||
|
||||
// for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
|
||||
// SCR_UpdateScreen ();
|
||||
}
|
||||
|
||||
void SCR_TileClear (int skipbottom)
|
||||
|
@ -2738,3 +2869,63 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
|
||||
RSpeedEnd(RSPEED_2D);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_Init
|
||||
==================
|
||||
*/
|
||||
void SCR_Init (void)
|
||||
{
|
||||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommandD ("screenshot_mega",SCR_ScreenShot_Mega_f, "screenshot_mega <name> [width] [height]\nTakes a screenshot with explicit sizes that are not tied to the size of your monitor, allowing for true monstrosities.");
|
||||
Cmd_AddCommandD ("screenshot_stereo",SCR_ScreenShot_Mega_f, "screenshot_stereo <name> [width] [height]\nTakes a simple stereo screenshot.");
|
||||
Cmd_AddCommandD ("screenshot_vr",SCR_ScreenShot_VR_f, "screenshot_vr <name> [width]\nTakes a spherical stereoscopic panorama image, for viewing with VR displays.");
|
||||
Cmd_AddCommand ("envmap",SCR_ScreenShot_EnvMap_f);
|
||||
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
|
||||
Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
|
||||
Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
|
||||
|
||||
scr_net = R2D_SafePicFromWad ("net");
|
||||
scr_turtle = R2D_SafePicFromWad ("turtle");
|
||||
|
||||
scr_initialized = true;
|
||||
}
|
||||
|
||||
void SCR_DeInit (void)
|
||||
{
|
||||
int i;
|
||||
if (scr_curcursor)
|
||||
{
|
||||
rf->VID_SetCursor(scr_curcursor);
|
||||
scr_curcursor = NULL;
|
||||
}
|
||||
for (i = 0; i < countof(key_customcursor); i++)
|
||||
{
|
||||
if (key_customcursor[i].handle)
|
||||
{
|
||||
rf->VID_DestroyCursor(key_customcursor[i].handle);
|
||||
key_customcursor[i].handle = NULL;
|
||||
}
|
||||
key_customcursor[i].dirty = true;
|
||||
}
|
||||
if (scr_initialized)
|
||||
{
|
||||
scr_initialized = false;
|
||||
|
||||
Cmd_RemoveCommand ("screenshot");
|
||||
Cmd_RemoveCommand ("screenshot_mega");
|
||||
Cmd_RemoveCommand ("screenshot_stereo");
|
||||
Cmd_RemoveCommand ("screenshot_vr");
|
||||
Cmd_RemoveCommand ("envmap");
|
||||
Cmd_RemoveCommand ("sizeup");
|
||||
Cmd_RemoveCommand ("sizedown");
|
||||
}
|
||||
}
|
|
@ -632,6 +632,8 @@ struct playerview_s
|
|||
float rollangle;
|
||||
float hdr_last;
|
||||
|
||||
int chatstate; //1=talking, 2=afk
|
||||
|
||||
float crouch; // local amount for smoothing stepups
|
||||
vec3_t oldorigin; // to track step smoothing
|
||||
float oldz, extracrouch, crouchspeed; // to track step smoothing
|
||||
|
@ -1341,6 +1343,7 @@ qboolean CSQC_MouseMove(float xdelta, float ydelta, int devid);
|
|||
qboolean CSQC_MousePosition(float xabs, float yabs, int devid);
|
||||
qboolean CSQC_JoystickAxis(int axis, float value, int devid);
|
||||
qboolean CSQC_Accelerometer(float x, float y, float z);
|
||||
qboolean CSQC_Gyroscope(float x, float y, float z);
|
||||
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation, float pitchmod, float timeofs, unsigned int flags);
|
||||
void CSQC_ParseEntities(void);
|
||||
void CSQC_ResetTrails(void);
|
||||
|
|
|
@ -1121,9 +1121,6 @@ return value is the top of the region
|
|||
*/
|
||||
int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y, qboolean selactive, int selsx, int selex, int selsy, int seley)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
extern qboolean ActiveApp;
|
||||
#endif
|
||||
int i;
|
||||
int lhs, rhs;
|
||||
int p;
|
||||
|
@ -1203,11 +1200,9 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
|
|||
// else
|
||||
// Plug_SpellCheckMaskedText(maskedtext+1, i-1, x, y, 8, si, con_current->linewidth);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!ActiveApp)
|
||||
if (!vid.activeapp)
|
||||
cursorframe = 0;
|
||||
else
|
||||
#endif
|
||||
cursorframe = ((int)(realtime*con_cursorspeed)&1);
|
||||
|
||||
//FIXME: support tab somehow
|
||||
|
|
|
@ -309,6 +309,11 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
u1 = (p1 == (cl.playerview[0].playernum));
|
||||
u2 = (p2 == (cl.playerview[0].playernum));
|
||||
|
||||
if (p1 == -1)
|
||||
p1 = p2;
|
||||
if (p2 == -1)
|
||||
p2 = p1;
|
||||
|
||||
//messages are killed weapon killer
|
||||
switch(mt)
|
||||
{
|
||||
|
@ -320,7 +325,8 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
}
|
||||
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
Stats_FragMessage(p1, wid, -3, true);
|
||||
|
@ -338,8 +344,11 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
|
||||
fragstats.weapontotals[wid].suicides++;
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].suicides++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
if (p1 >= 0)
|
||||
{
|
||||
fragstats.clienttotals[p1].suicides++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
}
|
||||
fragstats.totalsuicides++;
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
|
@ -351,7 +360,8 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
if (u1)
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].kills++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].kills++;
|
||||
fragstats.totalkills++;
|
||||
|
||||
Stats_FragMessage(-4, wid, p1, false);
|
||||
|
@ -371,7 +381,8 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
if (u1)
|
||||
fragstats.weapontotals[wid].ownteamkills++;
|
||||
fragstats.weapontotals[wid].teamkills++;
|
||||
fragstats.clienttotals[p1].teamkills++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].teamkills++;
|
||||
fragstats.totalteamkills++;
|
||||
|
||||
Stats_FragMessage(-1, wid, p1, true);
|
||||
|
@ -385,25 +396,27 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.clienttotals[p1].grabs++;
|
||||
fragstats.totaltouches++;
|
||||
|
||||
if (u1)
|
||||
if (u1 && p1 >= 0)
|
||||
{
|
||||
Stats_Message("You grabbed the flag\nflag grabs: %i (%i)\n", fragstats.clienttotals[p1].grabs, fragstats.totaltouches);
|
||||
}
|
||||
break;
|
||||
case ff_flagcaps:
|
||||
fragstats.clienttotals[p1].caps++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].caps++;
|
||||
fragstats.totalcaps++;
|
||||
|
||||
if (u1)
|
||||
if (u1 && p1 >= 0)
|
||||
{
|
||||
Stats_Message("You captured the flag\nflag captures: %i (%i)\n", fragstats.clienttotals[p1].caps, fragstats.totalcaps);
|
||||
}
|
||||
break;
|
||||
case ff_flagdrops:
|
||||
fragstats.clienttotals[p1].drops++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].drops++;
|
||||
fragstats.totaldrops++;
|
||||
|
||||
if (u1)
|
||||
if (u1 && p1 >= 0)
|
||||
{
|
||||
Stats_Message("You dropped the flag\nflag drops: %i (%i)\n", fragstats.clienttotals[p1].drops, fragstats.totaldrops);
|
||||
}
|
||||
|
@ -414,21 +427,26 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
case ff_fragedby:
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
if (p1 >= 0)
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
fragstats.totaldeaths++;
|
||||
if (u1)
|
||||
{
|
||||
fragstats.weapontotals[wid].owndeaths++;
|
||||
Stats_Message("%s killed you\n%s deaths: %i (%i/%i)\n", cl.players[p2].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].owndeaths, fragstats.weapontotals[wid].owndeaths, fragstats.totaldeaths);
|
||||
if (p1 >= 0 && p2 >= 0)
|
||||
Stats_Message("%s killed you\n%s deaths: %i (%i/%i)\n", cl.players[p2].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].owndeaths, fragstats.weapontotals[wid].owndeaths, fragstats.totaldeaths);
|
||||
}
|
||||
|
||||
fragstats.clienttotals[p2].kills++;
|
||||
if (p2 >= 0)
|
||||
fragstats.clienttotals[p2].kills++;
|
||||
fragstats.totalkills++;
|
||||
if (u2)
|
||||
{
|
||||
Stats_OwnFrag(cl.players[p1].name);
|
||||
if (p1 >= 0)
|
||||
Stats_OwnFrag(cl.players[p1].name);
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
Stats_Message("You killed %s\n%s kills: %i (%i/%i)\n", cl.players[p1].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills, fragstats.totalkills);
|
||||
if (p1 >= 0 && p2 >= 0)
|
||||
Stats_Message("You killed %s\n%s kills: %i (%i/%i)\n", cl.players[p1].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills, fragstats.totalkills);
|
||||
}
|
||||
|
||||
Stats_FragMessage(p1, wid, p2, false);
|
||||
|
@ -464,8 +482,11 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].ownteamdeaths++;
|
||||
fragstats.weapontotals[wid].owndeaths++;
|
||||
}
|
||||
fragstats.clienttotals[p1].teamdeaths++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
if (p1 >= 0)
|
||||
{
|
||||
fragstats.clienttotals[p1].teamdeaths++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
}
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
if (u2)
|
||||
|
@ -473,16 +494,19 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].ownkills++;
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
}
|
||||
fragstats.clienttotals[p2].teamkills++;
|
||||
fragstats.clienttotals[p2].kills++;
|
||||
if (p2 >= 0)
|
||||
{
|
||||
fragstats.clienttotals[p2].teamkills++;
|
||||
fragstats.clienttotals[p2].kills++;
|
||||
}
|
||||
fragstats.totalkills++;
|
||||
|
||||
fragstats.totalteamkills++;
|
||||
|
||||
Stats_FragMessage(p1, wid, p2, false);
|
||||
if (u1)
|
||||
if (u1 && p2 >= 0)
|
||||
Stats_Message("%s killed you\n%s deaths: %i (%i/%i)\n", cl.players[p2].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].owndeaths, fragstats.weapontotals[wid].owndeaths, fragstats.totaldeaths);
|
||||
if (u2)
|
||||
if (u2 && p1 >= 0 && p2 >= 0)
|
||||
{
|
||||
Stats_OwnFrag(cl.players[p1].name);
|
||||
Stats_Message("You killed %s\n%s kills: %i (%i/%i)\n", cl.players[p1].name, fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills, fragstats.totalkills);
|
||||
|
|
|
@ -745,6 +745,7 @@ void (PNGAPI *qpng_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)) PSTATIC
|
|||
png_voidp (PNGAPI *qpng_get_io_ptr) PNGARG((png_structp png_ptr)) PSTATIC(png_get_io_ptr);
|
||||
void (PNGAPI *qpng_destroy_write_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)) PSTATIC(png_destroy_write_struct);
|
||||
png_structp (PNGAPI *qpng_create_write_struct) PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warn_fn)) PSTATIC(png_create_write_struct);
|
||||
void (PNGAPI *qpng_set_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)) PSTATIC(png_set_unknown_chunks);
|
||||
|
||||
png_voidp (PNGAPI *qpng_get_error_ptr) PNGARG((png_structp png_ptr)) PSTATIC(png_get_error_ptr);
|
||||
|
||||
|
@ -791,6 +792,7 @@ qboolean LibPNG_Init(void)
|
|||
{(void **) &qpng_get_io_ptr, "png_get_io_ptr"},
|
||||
{(void **) &qpng_destroy_write_struct, "png_destroy_write_struct"},
|
||||
{(void **) &qpng_create_write_struct, "png_create_write_struct"},
|
||||
{(void **) &qpng_set_unknown_chunks, "png_set_unknown_chunks"},
|
||||
|
||||
{(void **) &qpng_get_error_ptr, "png_get_error_ptr"},
|
||||
{NULL, NULL}
|
||||
|
@ -983,7 +985,7 @@ error:
|
|||
|
||||
|
||||
#ifndef NPFTE
|
||||
int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, qbyte *pixels, int width, int height, enum uploadfmt fmt)
|
||||
int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, void **buffers, int numbuffers, int width, int height, enum uploadfmt fmt)
|
||||
{
|
||||
char name[MAX_OSPATH];
|
||||
int i;
|
||||
|
@ -993,10 +995,24 @@ int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, qb
|
|||
png_byte **row_pointers;
|
||||
struct pngerr errctx;
|
||||
int pxsize;
|
||||
int stride = width;
|
||||
|
||||
qbyte stereochunk = 0; //cross-eyed
|
||||
png_unknown_chunk unknowns = {"sTER", &stereochunk, sizeof(stereochunk), PNG_HAVE_PLTE};
|
||||
|
||||
if (!FS_NativePath(filename, fsroot, name, sizeof(name)))
|
||||
return false;
|
||||
|
||||
if (numbuffers == 2)
|
||||
{
|
||||
stride = width;
|
||||
if (stride & 7) //standard stereo images must be padded to 8 pixels width padding between
|
||||
stride += 8-(stride & 7);
|
||||
stride += width;
|
||||
}
|
||||
else //arrange them all horizontally
|
||||
stride = width * numbuffers;
|
||||
|
||||
if (!LibPNG_Init())
|
||||
return false;
|
||||
|
||||
|
@ -1046,20 +1062,67 @@ err:
|
|||
if (fmt == TF_RGBA32 || fmt == TF_BGRA32)
|
||||
{
|
||||
pxsize = 4;
|
||||
qpng_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
qpng_set_IHDR(png_ptr, info_ptr, stride, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pxsize = 3;
|
||||
qpng_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
qpng_set_IHDR(png_ptr, info_ptr, stride, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
if (numbuffers == 2) //flag it as a standard stereographic image
|
||||
qpng_set_unknown_chunks(png_ptr, info_ptr, &unknowns, 1);
|
||||
|
||||
qpng_write_info(png_ptr, info_ptr);
|
||||
|
||||
row_pointers = BZ_Malloc (sizeof(png_byte *) * height);
|
||||
if (!row_pointers)
|
||||
goto err;
|
||||
for (i = 0; i < height; i++)
|
||||
row_pointers[height - i - 1] = pixels + i * width * pxsize;
|
||||
if (numbuffers == 2)
|
||||
{ //standard stereographic png image.
|
||||
qbyte *pixels, *left, *right;
|
||||
//we need to pack the data into a single image for libpng to use
|
||||
row_pointers = Z_Malloc (sizeof(png_byte *) * height + stride*height*pxsize); //must be zeroed, because I'm too lazy to specially deal with padding.
|
||||
if (!row_pointers)
|
||||
goto err;
|
||||
pixels = (qbyte*)row_pointers + height;
|
||||
//png requires right then left, which is a bit weird.
|
||||
right = pixels;
|
||||
left = right + (stride-width)*pxsize;
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
if ((qbyte*)buffers[1])
|
||||
memcpy(right + i*stride*pxsize, (qbyte*)buffers[1] + i*pxsize*width, pxsize * width);
|
||||
if ((qbyte*)buffers[0])
|
||||
memcpy(left + i*stride*pxsize, (qbyte*)buffers[0] + i*pxsize*width, pxsize * width);
|
||||
row_pointers[height - i - 1] = pixels + i * stride * pxsize;
|
||||
}
|
||||
}
|
||||
else if (numbuffers == 1)
|
||||
{
|
||||
row_pointers = BZ_Malloc (sizeof(png_byte *) * height);
|
||||
if (!row_pointers)
|
||||
goto err;
|
||||
for (i = 0; i < height; i++)
|
||||
row_pointers[height - i - 1] = (qbyte*)buffers[0] + i * width * pxsize;
|
||||
}
|
||||
else
|
||||
{ //pack all images horizontally, because preventing people from doing the whole cross-eyed thing is cool, or something.
|
||||
qbyte *pixels;
|
||||
int j;
|
||||
//we need to pack the data into a single image for libpng to use
|
||||
row_pointers = BZ_Malloc (sizeof(png_byte *) * height + stride*height*pxsize);
|
||||
if (!row_pointers)
|
||||
goto err;
|
||||
pixels = (qbyte*)row_pointers + height;
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
for (j = 0; j < numbuffers; j++)
|
||||
{
|
||||
if (buffers[j])
|
||||
memcpy(pixels+(width*j + i*stride)*pxsize, (qbyte*)buffers[j] + i*pxsize*width, pxsize * width);
|
||||
}
|
||||
row_pointers[height - i - 1] = pixels + i * stride * pxsize;
|
||||
}
|
||||
}
|
||||
qpng_write_image(png_ptr, row_pointers);
|
||||
qpng_write_end(png_ptr, info_ptr);
|
||||
BZ_Free(row_pointers);
|
||||
|
@ -1572,8 +1635,64 @@ qboolean screenshotJPEG(char *filename, enum fs_relative fsroot, int compression
|
|||
struct jpeg_compress_struct cinfo;
|
||||
JSAMPROW row_pointer[1];
|
||||
|
||||
if (fmt != TF_RGB24)
|
||||
//convert in-place if needed.
|
||||
//bgr->rgb may require copying out entirely for the first pixel to work properly.
|
||||
if (fmt == TF_BGRA32)
|
||||
{
|
||||
qbyte *in=screendata, *out=screendata;
|
||||
size_t sz = screenwidth*screenheight;
|
||||
while(sz --> 0)
|
||||
{
|
||||
int r = in[2];
|
||||
int g = in[1];
|
||||
int b = in[0];
|
||||
out[0] = r;
|
||||
out[1] = g;
|
||||
out[2] = b;
|
||||
in+=4;
|
||||
out+=3;
|
||||
}
|
||||
fmt = TF_RGB24;
|
||||
}
|
||||
else if (fmt == TF_RGBA32)
|
||||
{
|
||||
qbyte *in=screendata, *out=screendata;
|
||||
size_t sz = screenwidth*screenheight;
|
||||
while(sz --> 0)
|
||||
{
|
||||
int r = in[0];
|
||||
int g = in[1];
|
||||
int b = in[2];
|
||||
out[0] = r;
|
||||
out[1] = g;
|
||||
out[2] = b;
|
||||
in+=4;
|
||||
out+=3;
|
||||
}
|
||||
fmt = TF_RGB24;
|
||||
}
|
||||
else if (fmt == TF_BGR24)
|
||||
{
|
||||
qbyte *in=screendata, *out=screendata;
|
||||
size_t sz = screenwidth*screenheight;
|
||||
while(sz --> 0)
|
||||
{
|
||||
int r = in[0];
|
||||
int g = in[1];
|
||||
int b = in[2];
|
||||
out[0] = r;
|
||||
out[1] = g;
|
||||
out[2] = b;
|
||||
in+=3;
|
||||
out+=3;
|
||||
}
|
||||
fmt = TF_RGB24;
|
||||
}
|
||||
else if (fmt != TF_RGB24)
|
||||
{
|
||||
Con_Printf("screenshotJPEG: image format not supported\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LIBJPEG_LOADED())
|
||||
return false;
|
||||
|
@ -1640,7 +1759,7 @@ void WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, i
|
|||
pcx = Hunk_TempAlloc (width*height*2+1000);
|
||||
if (pcx == NULL)
|
||||
{
|
||||
Con_Printf("SCR_ScreenShot_f: not enough memory\n");
|
||||
Con_Printf("WritePCXfile: not enough memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3591,14 +3710,31 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
freedata = true;
|
||||
break;
|
||||
case TF_TRANS8:
|
||||
case TF_H2_TRANS8_0:
|
||||
{
|
||||
qbyte ref = (fmt==TF_H2_TRANS8_0)?0:0xff;
|
||||
mips->encoding = PTI_RGBX8;
|
||||
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
|
||||
for (i = 0; i < imgwidth * imgheight; i++)
|
||||
{
|
||||
if (((qbyte*)rawdata)[i] == ref)
|
||||
if (((qbyte*)rawdata)[i] == 0xff)
|
||||
{//fixme: blend non-0xff neighbours. no, just use premultiplied alpha instead, where it matters.
|
||||
rgbadata[i] = 0;
|
||||
mips->encoding = PTI_RGBA8;
|
||||
}
|
||||
else
|
||||
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
|
||||
}
|
||||
if (freedata)
|
||||
BZ_Free(rawdata);
|
||||
freedata = true;
|
||||
}
|
||||
break;
|
||||
case TF_H2_TRANS8_0:
|
||||
{
|
||||
mips->encoding = PTI_RGBX8;
|
||||
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
|
||||
for (i = 0; i < imgwidth * imgheight; i++)
|
||||
{
|
||||
if (((qbyte*)rawdata)[i] == 0xff || ((qbyte*)rawdata)[i] == 0)
|
||||
{//fixme: blend non-0xff neighbours. no, just use premultiplied alpha instead, where it matters.
|
||||
rgbadata[i] = 0;
|
||||
mips->encoding = PTI_RGBA8;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
extern qboolean mouse_active;
|
||||
|
||||
static cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE);
|
||||
static cvar_t m_accel = CVARF("m_accel", "0", CVAR_ARCHIVE);
|
||||
static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice.");
|
||||
static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas.");
|
||||
static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn.");
|
||||
|
@ -14,6 +13,12 @@ static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_AR
|
|||
static cvar_t m_touchmajoraxis = CVARFD("m_touchmajoraxis", "1", CVAR_ARCHIVE, "When using a touchscreen, use only the major axis for strafing.");
|
||||
static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "10", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens).");
|
||||
|
||||
static cvar_t m_accel = CVARAFD("m_accel", "0", "cl_mouseAccel", CVAR_ARCHIVE, "Values >0 will amplify mouse movement proportional to velocity. Small values have great effect. A lot of good Quake Live players use around the 0.1-0.2 mark, but this depends on your mouse CPI and polling rate.");
|
||||
static cvar_t m_accel_style = CVARAD("m_accel_style", "1", "cl_mouseAccelStyle", "1 = Quake Live mouse acceleration, 0 = Old style accelertion.");
|
||||
static cvar_t m_accel_power = CVARAD("m_accel_power", "2", "cl_mouseAccelPower", "Used when m_accel_style is 1.\nValues 1 or below are dumb. 2 is linear and the default. 99% of accel users use this. Above 2 begins to amplify exponentially and you will get more acceleration at higher velocities. Great if you want low accel for slow movements, and high accel for fast movements. Good in combination with a sensitivity cap.");
|
||||
static cvar_t m_accel_offset = CVARAD("m_accel_offset", "0", "cl_mouseAccelOffset", "Used when m_accel_style is 1.\nAcceleration will not be active until the mouse movement exceeds this speed (counts per millisecond). Negative values are supported, which has the effect of causing higher rates of acceleration to happen at lower velocities.");
|
||||
static cvar_t m_accel_senscap = CVARAD("m_accel_senscap", "0", "cl_mouseSensCap", "Used when m_accel_style is 1.\nSets an upper limit on the amplified mouse movement. Great for tuning acceleration around lower velocities while still remaining in control of fast motion such as flicking.");
|
||||
|
||||
void QDECL joyaxiscallback(cvar_t *var, char *oldvalue)
|
||||
{
|
||||
int sign;
|
||||
|
@ -63,12 +68,13 @@ void QDECL joyaxiscallback(cvar_t *var, char *oldvalue)
|
|||
|
||||
static cvar_t joy_advaxis[6] =
|
||||
{
|
||||
CVARCD("joyadvaxisx", "turnright", joyaxiscallback, "Provides a way to remap each joystick/controller axis.\n0:dead, 1:fwd, 2:pitch, 3:side, 4:yaw, 5:up, 6:roll"),
|
||||
CVARC("joyadvaxisy", "lookup", joyaxiscallback),
|
||||
CVARC("joyadvaxisz", "moveup", joyaxiscallback),
|
||||
CVARC("joyadvaxisr", "moveright", joyaxiscallback),
|
||||
CVARC("joyadvaxisu", "moveforward", joyaxiscallback),
|
||||
CVARC("joyadvaxisv", "rollright", joyaxiscallback)
|
||||
#define ADVAXISDESC (const char *)"Provides a way to remap each joystick/controller axis.\nShould be set to one of: moveforward, moveback, lookup, lookdown, turnleft, turnright, moveleft, moveright, moveup, movedown, rollleft, rollright"
|
||||
CVARCD("joyadvaxisx", "turnright", joyaxiscallback, ADVAXISDESC),
|
||||
CVARCD("joyadvaxisy", "lookup", joyaxiscallback, ADVAXISDESC),
|
||||
CVARCD("joyadvaxisz", "moveup", joyaxiscallback, ADVAXISDESC),
|
||||
CVARCD("joyadvaxisr", "moveright", joyaxiscallback, ADVAXISDESC),
|
||||
CVARCD("joyadvaxisu", "moveforward", joyaxiscallback, ADVAXISDESC),
|
||||
CVARCD("joyadvaxisv", "rollright", joyaxiscallback, ADVAXISDESC)
|
||||
};
|
||||
static cvar_t joy_advaxisscale[6] =
|
||||
{
|
||||
|
@ -240,6 +246,8 @@ void IN_DeviceIDs_Enumerate(void *ctx, const char *type, const char *devicename,
|
|||
devicename = COM_QuotedString(devicename, buf, sizeof(buf), false);
|
||||
if (!qdevid)
|
||||
Con_Printf("%s\t%s\t%s\n", type, "N/A", devicename);
|
||||
else if (*qdevid == DEVID_UNSET)
|
||||
Con_Printf("%s\t%s\t%s\n", type, "Unset", devicename);
|
||||
else
|
||||
Con_Printf("%s\t%i\t%s\n", type, *qdevid, devicename);
|
||||
}
|
||||
|
@ -291,13 +299,17 @@ void IN_Init(void)
|
|||
events_used = 0;
|
||||
|
||||
Cvar_Register (&m_filter, "input controls");
|
||||
Cvar_Register (&m_accel, "input controls");
|
||||
Cvar_Register (&m_forcewheel, "Input Controls");
|
||||
Cvar_Register (&m_forcewheel_threshold, "Input Controls");
|
||||
Cvar_Register (&m_strafeonright, "input controls");
|
||||
Cvar_Register (&m_fatpressthreshold, "input controls");
|
||||
Cvar_Register (&m_slidethreshold, "input controls");
|
||||
Cvar_Register (&m_touchmajoraxis, "input controls");
|
||||
Cvar_Register (&m_accel, "input controls");
|
||||
Cvar_Register (&m_accel_style, "input controls");
|
||||
Cvar_Register (&m_accel_power, "input controls");
|
||||
Cvar_Register (&m_accel_offset, "input controls");
|
||||
Cvar_Register (&m_accel_senscap, "input controls");
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
|
@ -498,7 +510,7 @@ void IN_Commands(void)
|
|||
}
|
||||
}
|
||||
|
||||
void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
|
||||
void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frametime)
|
||||
{
|
||||
int mx, my;
|
||||
double mouse_x, mouse_y, mouse_deltadist;
|
||||
|
@ -684,9 +696,30 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
|
|||
|
||||
if (m_accel.value)
|
||||
{
|
||||
mouse_deltadist = sqrt(mx*mx + my*my);
|
||||
mouse_x *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale);
|
||||
mouse_y *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale);
|
||||
if (m_accel_style.ival)
|
||||
{
|
||||
float accelsens = sensitivity.value*in_sensitivityscale;
|
||||
float mousespeed = (sqrt (mx * mx + my * my)) / (1000.0f * (float) frametime);
|
||||
mousespeed -= m_accel_offset.value;
|
||||
if (mousespeed > 0)
|
||||
{
|
||||
mousespeed *= m_accel.value;
|
||||
if (m_accel_power.value > 1)
|
||||
accelsens += exp((m_accel_power.value - 1) * log(mousespeed));
|
||||
else
|
||||
accelsens = 1;
|
||||
}
|
||||
if (m_accel_senscap.value > 0 && accelsens > m_accel_senscap.value)
|
||||
accelsens = m_accel_senscap.value;
|
||||
mouse_x *= accelsens;
|
||||
mouse_y *= accelsens;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse_deltadist = sqrt(mx*mx + my*my);
|
||||
mouse_x *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale);
|
||||
mouse_y *= (mouse_deltadist*m_accel.value + sensitivity.value*in_sensitivityscale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -873,7 +906,7 @@ void IN_Move (float *movements, int pnum, float frametime)
|
|||
int i;
|
||||
INS_Move(movements, pnum);
|
||||
for (i = 0; i < MAXPOINTERS; i++)
|
||||
IN_MoveMouse(&ptr[i], movements, pnum);
|
||||
IN_MoveMouse(&ptr[i], movements, pnum, frametime);
|
||||
|
||||
for (i = 0; i < MAXJOYSTICKS; i++)
|
||||
IN_MoveJoystick(&joy[i], movements, pnum, frametime);
|
||||
|
|
|
@ -8,7 +8,6 @@ SDL_Window *sdlwindow;
|
|||
extern SDL_Surface *sdlsurf;
|
||||
#endif
|
||||
|
||||
qboolean ActiveApp;
|
||||
qboolean mouseactive;
|
||||
extern qboolean mouseusedforgui;
|
||||
extern qboolean vid_isfullscreen;
|
||||
|
@ -705,10 +704,10 @@ void Sys_SendKeyEvents(void)
|
|||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
ActiveApp = true;
|
||||
vid.activeapp = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
Cbuf_AddText("quit prompt\n", RESTRICT_LOCAL);
|
||||
|
@ -720,7 +719,7 @@ void Sys_SendKeyEvents(void)
|
|||
case SDL_ACTIVEEVENT:
|
||||
if (event.active.state & SDL_APPINPUTFOCUS)
|
||||
{ //follow keyboard status
|
||||
ActiveApp = !!event.active.gain;
|
||||
vid.activeapp = !!event.active.gain;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct _XINPUT_VIBRATION {
|
|||
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
|
||||
DWORD (WINAPI *pXInputGetState)(DWORD dwUserIndex, XINPUT_STATE *pState);
|
||||
DWORD (WINAPI *pXInputSetState)(DWORD dwUserIndex, XINPUT_VIBRATION *pState);
|
||||
DWORD (WINAPI *pXInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid);
|
||||
enum
|
||||
{
|
||||
XINPUT_GAMEPAD_DPAD_UP = 0x0001,
|
||||
|
@ -72,6 +73,7 @@ enum
|
|||
XINPUT_GAMEPAD_X = 0x4000,
|
||||
XINPUT_GAMEPAD_Y = 0x8000
|
||||
};
|
||||
static qboolean xinput_useaudio;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -173,6 +175,7 @@ static struct wjoy_s {
|
|||
DWORD oldpovstate;
|
||||
DWORD buttonstate;
|
||||
DWORD oldbuttonstate;
|
||||
soundcardinfo_t *audiodev;
|
||||
} wjoy[MAX_JOYSTICKS];
|
||||
static int joy_count;
|
||||
|
||||
|
@ -351,6 +354,51 @@ static void INS_HideMouse (void)
|
|||
}
|
||||
}
|
||||
|
||||
//scan for an unused device id for joysticks (now that something was pressed).
|
||||
static int Joy_AllocateDevID(void)
|
||||
{
|
||||
int id = 0, j;
|
||||
for (id = 0; ; id++)
|
||||
{
|
||||
for (j = 0; j < joy_count; j++)
|
||||
{
|
||||
if (wjoy[j].devid == id)
|
||||
break;
|
||||
}
|
||||
if (j == joy_count)
|
||||
return id;
|
||||
}
|
||||
}
|
||||
#ifdef USINGRAWINPUT
|
||||
static int Mouse_AllocateDevID(void)
|
||||
{
|
||||
int id = 0, j;
|
||||
for (id = 0; ; id++)
|
||||
{
|
||||
for (j = 0; j < rawmicecount; j++)
|
||||
{
|
||||
if (rawmice[j].qdeviceid == id)
|
||||
break;
|
||||
}
|
||||
if (j == rawmicecount)
|
||||
return id;
|
||||
}
|
||||
}
|
||||
static int Keyboard_AllocateDevID(void)
|
||||
{
|
||||
int id = 0, j;
|
||||
for (id = 0; ; id++)
|
||||
{
|
||||
for (j = 0; j < rawkbdcount; j++)
|
||||
{
|
||||
if (rawkbd[j].qdeviceid == id)
|
||||
break;
|
||||
}
|
||||
if (j == rawkbdcount)
|
||||
return id;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===========
|
||||
|
@ -1008,7 +1056,7 @@ void INS_RawInput_Init(void)
|
|||
Q_strncpyz(rawmice[rawmicecount].sysname, dname, sizeof(rawmice[rawmicecount].sysname));
|
||||
rawmice[rawmicecount].numbuttons = 16;
|
||||
rawmice[rawmicecount].oldbuttons = 0;
|
||||
rawmice[rawmicecount].qdeviceid = rawmicecount;
|
||||
rawmice[rawmicecount].qdeviceid = DEVID_UNSET;
|
||||
rawmicecount++;
|
||||
break;
|
||||
case RIM_TYPEKEYBOARD:
|
||||
|
@ -1017,7 +1065,7 @@ void INS_RawInput_Init(void)
|
|||
|
||||
rawkbd[rawkbdcount].handles.rawinputhandle = pRawInputDeviceList[i].hDevice;
|
||||
Q_strncpyz(rawkbd[rawkbdcount].sysname, dname, sizeof(rawkbd[rawkbdcount].sysname));
|
||||
rawkbd[rawkbdcount].qdeviceid = rawkbdcount;
|
||||
rawkbd[rawkbdcount].qdeviceid = DEVID_UNSET;
|
||||
rawkbdcount++;
|
||||
break;
|
||||
default:
|
||||
|
@ -1229,13 +1277,13 @@ void INS_MouseEvent (int mstate)
|
|||
if ( (mstate & (1<<i)) &&
|
||||
!(sysmouse.oldbuttons & (1<<i)) )
|
||||
{
|
||||
IN_KeyEvent (0, true, K_MOUSE1 + i, 0);
|
||||
IN_KeyEvent (sysmouse.qdeviceid, true, K_MOUSE1 + i, 0);
|
||||
}
|
||||
|
||||
if ( !(mstate & (1<<i)) &&
|
||||
(sysmouse.oldbuttons & (1<<i)) )
|
||||
{
|
||||
IN_KeyEvent (0, false, K_MOUSE1 + i, 0);
|
||||
IN_KeyEvent (sysmouse.qdeviceid, false, K_MOUSE1 + i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1343,7 +1391,7 @@ INS_Move
|
|||
*/
|
||||
void INS_Move (float *movements, int pnum)
|
||||
{
|
||||
if (ActiveApp && !Minimized)
|
||||
if (vid.activeapp && !Minimized)
|
||||
{
|
||||
INS_MouseMove (movements, pnum);
|
||||
INS_JoyMove (movements, pnum);
|
||||
|
@ -1407,6 +1455,17 @@ void INS_RawInput_MouseRead(void)
|
|||
return;
|
||||
mouse = &rawmice[i];
|
||||
|
||||
if (mouse->qdeviceid == DEVID_UNSET)
|
||||
{
|
||||
if ((raw->data.mouse.usButtonFlags & (RI_MOUSE_BUTTON_1_DOWN|RI_MOUSE_BUTTON_2_DOWN|RI_MOUSE_BUTTON_3_DOWN|RI_MOUSE_BUTTON_4_DOWN|RI_MOUSE_BUTTON_5_DOWN|RI_MOUSE_WHEEL))
|
||||
|| (raw->data.mouse.ulRawButtons & RI_RAWBUTTON_MASK) || raw->data.mouse.lLastX || raw->data.mouse.lLastY)
|
||||
{
|
||||
mouse->qdeviceid = Mouse_AllocateDevID();
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
multicursor_active[mouse->qdeviceid&7] = 0;
|
||||
|
||||
// movement
|
||||
|
@ -1507,6 +1566,9 @@ void INS_RawInput_KeyboardRead(void)
|
|||
if (i == rawkbdcount) // not tracking this device
|
||||
return;
|
||||
|
||||
if (rawkbd[i].qdeviceid == DEVID_UNSET)
|
||||
rawkbd[i].qdeviceid = Keyboard_AllocateDevID();
|
||||
|
||||
down = !(raw->data.keyboard.Flags & RI_KEY_BREAK);
|
||||
wParam = raw->data.keyboard.VKey ;//(-down) & 0xC0000000;
|
||||
lParam = (MapVirtualKey(raw->data.keyboard.VKey, 0)<<16) | ((!!(raw->data.keyboard.Flags & RI_KEY_E0))<<24);
|
||||
|
@ -1575,7 +1637,7 @@ static void INS_StartupJoystickId(unsigned int id)
|
|||
joy = &wjoy[joy_count];
|
||||
memset(joy, 0, sizeof(*joy));
|
||||
joy->id = id;
|
||||
joy->devid = 1+joy_count; //FIXME: this is a hack. make joysticks 1-based. this means mouse0 controls 1st player, joy0 controls 2nd player (controls wrap so joy1 controls 1st player too.
|
||||
joy->devid = DEVID_UNSET;//1+joy_count; //FIXME: this is a hack. make joysticks 1-based. this means mouse0 controls 1st player, joy0 controls 2nd player (controls wrap so joy1 controls 1st player too.
|
||||
|
||||
// get the capabilities of the selected joystick
|
||||
// abort startup if command fails
|
||||
|
@ -1597,45 +1659,52 @@ static void INS_StartupJoystickId(unsigned int id)
|
|||
|
||||
joy_count++;
|
||||
}
|
||||
void INS_SetupControllerAudioDevices(void)
|
||||
static void IN_XInput_SetupAudio(struct wjoy_s *joy)
|
||||
{
|
||||
#ifdef AVAIL_XINPUT
|
||||
char audiodevicename[MAX_QPATH];
|
||||
wchar_t mssuck[MAX_QPATH];
|
||||
static GUID GUID_NULL;
|
||||
GUID gplayback = GUID_NULL;
|
||||
GUID gcapture = GUID_NULL;
|
||||
|
||||
if (joy->audiodev)
|
||||
{
|
||||
S_ShutdownCard(joy->audiodev);
|
||||
joy->audiodev = NULL;
|
||||
}
|
||||
|
||||
if (!xinput_useaudio)
|
||||
return;
|
||||
|
||||
if (!joy->isxinput)
|
||||
return;
|
||||
if (joy->devid == DEVID_UNSET)
|
||||
return;
|
||||
|
||||
if (pXInputGetDSoundAudioDeviceGuids(joy->id, &gplayback, &gcapture) != ERROR_SUCCESS)
|
||||
return; //probably not plugged in
|
||||
|
||||
if (!memcmp(&gplayback, &GUID_NULL, sizeof(gplayback)))
|
||||
return; //we have a controller, but no headset.
|
||||
|
||||
StringFromGUID2(&gplayback, mssuck, sizeof(mssuck)/sizeof(mssuck[0]));
|
||||
narrowen(audiodevicename, sizeof(audiodevicename), mssuck);
|
||||
Con_Printf("Controller %i uses audio device %s\n", joy->id, audiodevicename);
|
||||
joy->audiodev = S_SetupDeviceSeat("DirectSound", audiodevicename, joy->devid);
|
||||
#endif
|
||||
}
|
||||
void INS_SetupControllerAudioDevices(qboolean enabled)
|
||||
{
|
||||
#ifdef AVAIL_XINPUT
|
||||
int i;
|
||||
static DWORD (WINAPI *pXInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid);
|
||||
static dllhandle_t *xinput;
|
||||
if (!xinput)
|
||||
{
|
||||
dllfunction_t funcs[] =
|
||||
{
|
||||
{(void**)&pXInputGetDSoundAudioDeviceGuids, "XInputGetDSoundAudioDeviceGuids"},
|
||||
{NULL}
|
||||
};
|
||||
xinput = Sys_LoadLibrary(AVAIL_XINPUT_DLL, funcs);
|
||||
}
|
||||
|
||||
if (!pXInputGetDSoundAudioDeviceGuids)
|
||||
return;
|
||||
|
||||
xinput_useaudio = enabled;
|
||||
for (i = 0; i < joy_count; i++)
|
||||
{
|
||||
char audiodevicename[MAX_QPATH];
|
||||
wchar_t mssuck[MAX_QPATH];
|
||||
static GUID GUID_NULL;
|
||||
GUID gplayback = GUID_NULL;
|
||||
GUID gcapture = GUID_NULL;
|
||||
if (!wjoy[i].isxinput)
|
||||
continue;
|
||||
if (pXInputGetDSoundAudioDeviceGuids(wjoy[i].id, &gplayback, &gcapture) != ERROR_SUCCESS)
|
||||
continue; //probably not plugged in
|
||||
|
||||
if (!memcmp(&gplayback, &GUID_NULL, sizeof(gplayback)))
|
||||
continue; //we have a controller, but no headset.
|
||||
|
||||
StringFromGUID2(&gplayback, mssuck, sizeof(mssuck)/sizeof(mssuck[0]));
|
||||
narrowen(audiodevicename, sizeof(audiodevicename), mssuck);
|
||||
Con_Printf("Controller %i uses audio device %s\n", wjoy[i].id, audiodevicename);
|
||||
S_SetupDeviceSeat("DirectSound", audiodevicename, wjoy[i].devid);
|
||||
}
|
||||
IN_XInput_SetupAudio(&wjoy[i]);
|
||||
#endif
|
||||
}
|
||||
void INS_StartupJoystick (void)
|
||||
|
@ -1659,12 +1728,12 @@ void INS_StartupJoystick (void)
|
|||
{NULL}
|
||||
};
|
||||
xinput = Sys_LoadLibrary(AVAIL_XINPUT_DLL, funcs);
|
||||
|
||||
if (xinput)
|
||||
pXInputGetDSoundAudioDeviceGuids = Sys_GetAddressForName(xinput, "XInputGetDSoundAudioDeviceGuids");
|
||||
}
|
||||
if (pXInputGetState)
|
||||
{
|
||||
DWORD (WINAPI *pXInputGetDSoundAudioDeviceGuids)(DWORD dwUserIndex, GUID* pDSoundRenderGuid, GUID* pDSoundCaptureGuid);
|
||||
pXInputGetDSoundAudioDeviceGuids = Sys_GetAddressForName(xinput, "XInputGetDSoundAudioDeviceGuids");
|
||||
|
||||
for (id = 0; id < 4; id++)
|
||||
{
|
||||
if (joy_count == countof(wjoy))
|
||||
|
@ -1672,7 +1741,7 @@ void INS_StartupJoystick (void)
|
|||
memset(&wjoy[id], 0, sizeof(wjoy[id]));
|
||||
wjoy[joy_count].isxinput = true;
|
||||
wjoy[joy_count].id = id;
|
||||
wjoy[joy_count].devid = id;
|
||||
wjoy[joy_count].devid = DEVID_UNSET;//id;
|
||||
wjoy[joy_count].numbuttons = 16;
|
||||
joy_count++;
|
||||
}
|
||||
|
@ -1790,29 +1859,38 @@ void INS_Commands (void)
|
|||
// loop through the joystick buttons
|
||||
// key a joystick event or auxillary event for higher number buttons for each state change
|
||||
buttonstate = joy->buttonstate;
|
||||
if (joy->isxinput)
|
||||
if (buttonstate != joy->oldbuttonstate)
|
||||
{
|
||||
for (i=0 ; i < joy->numbuttons ; i++)
|
||||
if (joy->devid == DEVID_UNSET)
|
||||
{
|
||||
if ( (buttonstate & (1<<i)) && !(joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, xinputjbuttons[i], 0, true);
|
||||
|
||||
if ( !(buttonstate & (1<<i)) && (joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, xinputjbuttons[i], 0, false);
|
||||
joy->devid = Joy_AllocateDevID();
|
||||
IN_XInput_SetupAudio(joy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i < joy->numbuttons ; i++)
|
||||
|
||||
if (joy->isxinput)
|
||||
{
|
||||
if ( (buttonstate & (1<<i)) && !(joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, dinputjbuttons[i], 0, true);
|
||||
for (i=0 ; i < joy->numbuttons ; i++)
|
||||
{
|
||||
if ( (buttonstate & (1<<i)) && !(joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, xinputjbuttons[i], 0, true);
|
||||
|
||||
if ( !(buttonstate & (1<<i)) && (joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, dinputjbuttons[i], 0, false);
|
||||
if ( !(buttonstate & (1<<i)) && (joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, xinputjbuttons[i], 0, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i < joy->numbuttons ; i++)
|
||||
{
|
||||
if ( (buttonstate & (1<<i)) && !(joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, dinputjbuttons[i], 0, true);
|
||||
|
||||
if ( !(buttonstate & (1<<i)) && (joy->oldbuttonstate & (1<<i)) )
|
||||
Key_Event (joy->devid, dinputjbuttons[i], 0, false);
|
||||
}
|
||||
}
|
||||
joy->oldbuttonstate = buttonstate;
|
||||
}
|
||||
joy->oldbuttonstate = buttonstate;
|
||||
|
||||
if (joy->haspov)
|
||||
{
|
||||
|
@ -1831,20 +1909,26 @@ void INS_Commands (void)
|
|||
if (joy->povstate == JOY_POVLEFT)
|
||||
povstate |= 0x08;
|
||||
}
|
||||
// determine which bits have changed and key an auxillary event for each change
|
||||
for (i=0 ; i < 4 ; i++)
|
||||
if (joy->oldpovstate != povstate)
|
||||
{
|
||||
if ( (povstate & (1<<i)) && !(joy->oldpovstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (joy->devid, K_AUX29 + i, 0, true);
|
||||
}
|
||||
if (joy->devid == DEVID_UNSET)
|
||||
joy->devid = Joy_AllocateDevID();
|
||||
|
||||
if ( !(povstate & (1<<i)) && (joy->oldpovstate & (1<<i)) )
|
||||
// determine which bits have changed and key an auxillary event for each change
|
||||
for (i=0 ; i < 4 ; i++)
|
||||
{
|
||||
Key_Event (joy->devid, K_AUX29 + i, 0, false);
|
||||
if ( (povstate & (1<<i)) && !(joy->oldpovstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (joy->devid, K_AUX29 + i, 0, true);
|
||||
}
|
||||
|
||||
if ( !(povstate & (1<<i)) && (joy->oldpovstate & (1<<i)) )
|
||||
{
|
||||
Key_Event (joy->devid, K_AUX29 + i, 0, false);
|
||||
}
|
||||
}
|
||||
joy->oldpovstate = povstate;
|
||||
}
|
||||
joy->oldpovstate = povstate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1886,16 +1970,19 @@ qboolean INS_ReadJoystick (struct wjoy_s *joy)
|
|||
//do we care about the dwPacketNumber?
|
||||
joy->buttonstate = xistate.Gamepad.wButtons & 0xffff;
|
||||
|
||||
IN_JoystickAxisEvent(joy->devid, 0, xistate.Gamepad.sThumbRX / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, xistate.Gamepad.sThumbRY / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, xistate.Gamepad.bRightTrigger/255.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, xistate.Gamepad.sThumbLX / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, xistate.Gamepad.sThumbLY / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, xistate.Gamepad.bLeftTrigger/255.0);
|
||||
if (joy->devid != DEVID_UNSET)
|
||||
{
|
||||
IN_JoystickAxisEvent(joy->devid, 0, xistate.Gamepad.sThumbRX / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, xistate.Gamepad.sThumbRY / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, xistate.Gamepad.bRightTrigger/255.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, xistate.Gamepad.sThumbLX / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, xistate.Gamepad.sThumbLY / 32768.0);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, xistate.Gamepad.bLeftTrigger/255.0);
|
||||
|
||||
vibrator.wLeftMotorSpeed = xinput_leftvibrator.value * 0xffff;
|
||||
vibrator.wRightMotorSpeed = xinput_rightvibrator.value * 0xffff;
|
||||
pXInputSetState(joy->id, &vibrator);
|
||||
vibrator.wLeftMotorSpeed = xinput_leftvibrator.value * 0xffff;
|
||||
vibrator.wRightMotorSpeed = xinput_rightvibrator.value * 0xffff;
|
||||
pXInputSetState(joy->id, &vibrator);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1910,24 +1997,30 @@ qboolean INS_ReadJoystick (struct wjoy_s *joy)
|
|||
{
|
||||
joy->povstate = ji.dwPOV;
|
||||
joy->buttonstate = ji.dwButtons;
|
||||
IN_JoystickAxisEvent(joy->devid, 0, (ji.dwXpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, (ji.dwYpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, (ji.dwZpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, (ji.dwRpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, (ji.dwUpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, (ji.dwVpos - 32768.0) / 32768);
|
||||
if (joy->devid != DEVID_UNSET)
|
||||
{
|
||||
IN_JoystickAxisEvent(joy->devid, 0, (ji.dwXpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, (ji.dwYpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, (ji.dwZpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, (ji.dwRpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, (ji.dwUpos - 32768.0) / 32768);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, (ji.dwVpos - 32768.0) / 32768);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
joy->povstate = 0;
|
||||
joy->buttonstate = 0;
|
||||
IN_JoystickAxisEvent(joy->devid, 0, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, 0);
|
||||
if (joy->devid != DEVID_UNSET)
|
||||
{
|
||||
IN_JoystickAxisEvent(joy->devid, 0, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 1, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 2, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 3, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 4, 0);
|
||||
IN_JoystickAxisEvent(joy->devid, 5, 0);
|
||||
}
|
||||
|
||||
// read error occurred
|
||||
// turning off the joystick seems too harsh for 1 read error,
|
||||
|
@ -1977,10 +2070,12 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char
|
|||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < rawmicecount; idx++)
|
||||
callback(ctx, "mouse", rawmice[idx].sysname?rawmice[idx].sysname:va("raw%i", idx), &rawmice[idx].qdeviceid);
|
||||
for (idx = 0; idx < rawkbdcount; idx++)
|
||||
callback(ctx, "keyboard", rawkbd[idx].sysname?rawkbd[idx].sysname:va("rawk%i", idx), &rawkbd[idx].qdeviceid);
|
||||
callback(ctx, "keyboard", "system", NULL);
|
||||
|
||||
for (idx = 0; idx < rawmicecount; idx++)
|
||||
callback(ctx, "mouse", rawmice[idx].sysname?rawmice[idx].sysname:va("raw%i", idx), &rawmice[idx].qdeviceid);
|
||||
|
||||
#if (DIRECTINPUT_VERSION >= DINPUT_VERSION_DX7)
|
||||
if (dinput >= DINPUT_VERSION_DX7 && g_pMouse7)
|
||||
|
@ -1993,10 +2088,13 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char
|
|||
|
||||
for (idx = 0; idx < joy_count; idx++)
|
||||
{
|
||||
int odevid = wjoy[idx].devid;
|
||||
if (wjoy[idx].isxinput)
|
||||
callback(ctx, "joy", va("xi%i", wjoy[idx].id), &wjoy[idx].devid);
|
||||
else
|
||||
callback(ctx, "joy", va("mmj%i", wjoy[idx].id), &wjoy[idx].devid);
|
||||
if (odevid != wjoy[idx].devid)
|
||||
IN_XInput_SetupAudio(&wjoy[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@ void INS_Init (void);
|
|||
void INS_Shutdown (void);
|
||||
void INS_Commands (void); //final chance to call IN_MouseMove/IN_KeyEvent each frame
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid));
|
||||
void INS_SetupControllerAudioDevices(void); //creates audio devices for each controller (where controllers have their own audio devices)
|
||||
void INS_SetupControllerAudioDevices(qboolean enabled); //creates audio devices for each controller (where controllers have their own audio devices)
|
||||
|
||||
#define DEVID_UNSET -1
|
||||
|
||||
extern cvar_t cl_nodelta;
|
||||
extern cvar_t cl_c2spps;
|
||||
|
|
|
@ -323,7 +323,7 @@ int con_commandmatch;
|
|||
void CompleteCommand (qboolean force)
|
||||
{
|
||||
char *cmd, *s;
|
||||
char *desc;
|
||||
const char *desc;
|
||||
|
||||
s = key_lines[edit_line]+1;
|
||||
if (*s == '\\' || *s == '/')
|
||||
|
@ -2172,7 +2172,7 @@ qboolean Key_MouseShouldBeFree(void)
|
|||
if (Key_Dest_Has(kdm_editor))
|
||||
return true;
|
||||
|
||||
// if (!ActiveApp)
|
||||
// if (!vid.activeapp)
|
||||
// return true;
|
||||
|
||||
if (Key_Dest_Has(kdm_emenu))
|
||||
|
|
|
@ -805,8 +805,9 @@ menubind_t *MC_AddBind(menu_t *menu, int cx, int bx, int y, const char *caption,
|
|||
strcpy(n->command, command);
|
||||
if (tooltip)
|
||||
{
|
||||
n->common.tooltip = n->command+strlen(n->command)+1;
|
||||
strcpy(n->common.tooltip, tooltip);
|
||||
char *tip = n->command+strlen(n->command)+1;
|
||||
n->common.tooltip = tip;
|
||||
strcpy(tip, tooltip);
|
||||
}
|
||||
n->common.width = n->captionwidth + 64;
|
||||
n->common.height = 8;
|
||||
|
|
|
@ -25,7 +25,7 @@ static cvar_t sb_showtimelimit = CVARF("sb_showtimelimit", "0", CVAR_ARCHIVE);
|
|||
|
||||
static cvar_t sb_alpha = CVARF("sb_alpha", "0.7", CVAR_ARCHIVE);
|
||||
|
||||
vrect_t joinbutton;
|
||||
vrect_t joinbutton, specbutton;
|
||||
static float refreshedtime;
|
||||
static int isrefreshing;
|
||||
static int serverpreview;
|
||||
|
@ -62,6 +62,7 @@ void M_Serverlist_Init(void)
|
|||
}
|
||||
|
||||
typedef struct {
|
||||
int servers_top;
|
||||
int visibleslots;
|
||||
int scrollpos;
|
||||
int selectedpos;
|
||||
|
@ -278,7 +279,7 @@ static void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu)
|
|||
serverhighlight[(int)stype][2],
|
||||
1.0);
|
||||
}
|
||||
else if (thisone == info->scrollpos + (int)(mousecursor_y-16)/8 && mousecursor_x < x)
|
||||
else if (thisone == info->scrollpos + (int)(mousecursor_y-info->servers_top)/8 && mousecursor_x < x)
|
||||
R2D_ImageColours((sin(realtime*4.4)*0.25)+0.5, (sin(realtime*4.4)*0.25)+0.5, 0.08, sb_alpha.value);
|
||||
else if (selectedserver.inuse && NET_CompareAdr(&si->adr, &selectedserver.adr))
|
||||
R2D_ImageColours(((sin(realtime*4.4)*0.25)+0.5) * 0.5, ((sin(realtime*4.4)*0.25)+0.5)*0.5, 0.08*0.5, sb_alpha.value);
|
||||
|
@ -317,7 +318,7 @@ static qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key, unsigned
|
|||
if (key == K_MOUSE1)
|
||||
{
|
||||
oldselection = info->selectedpos;
|
||||
info->selectedpos = info->scrollpos + (mousecursor_y-16)/8;
|
||||
info->selectedpos = info->scrollpos + (mousecursor_y-info->servers_top)/8;
|
||||
server = Master_SortedServer(info->selectedpos);
|
||||
|
||||
selectedserver.inuse = true;
|
||||
|
@ -559,6 +560,7 @@ static void SL_PostDraw (menu_t *menu)
|
|||
R2D_FillBlock (x, y+1, 32, 3);
|
||||
R2D_ImagePaletteColour (Sbar_ColorForMap(server->moreinfo->players[i].botc), 1.0);
|
||||
R2D_FillBlock (x, y+4, 32, 4);
|
||||
R2D_ImageColours (1.0, 1.0, 1.0, 1.0);
|
||||
Draw_FunStringWidth (x, y, va("%3i", server->moreinfo->players[i].frags), 32-4, true, false);
|
||||
}
|
||||
x += 32+8;
|
||||
|
@ -586,24 +588,53 @@ static void SL_PostDraw (menu_t *menu)
|
|||
Draw_FunStringWidth(vid.width/2 - 100, vid.height/2 + 0, "Please wait", 200, 2, false);
|
||||
}
|
||||
|
||||
if ((server->special & SS_PROTOCOLMASK) == SS_QUAKEWORLD)
|
||||
{
|
||||
int lx = vid.width/2 - w/2;
|
||||
int y = vid.height/2 - h/2 - 4 + h;
|
||||
int sw;
|
||||
int bh, bw;
|
||||
qboolean active = false;
|
||||
w += 16;
|
||||
h = 24;
|
||||
bw = w+16+12;
|
||||
bh = 24;
|
||||
// lx += bw-12;
|
||||
bw = strlen("Observe")*8 + 24;
|
||||
bw = ((bw+15)/16) * 16; //width must be a multiple of 16
|
||||
// lx -= bw;
|
||||
|
||||
specbutton.x = lx;
|
||||
specbutton.y = y;
|
||||
specbutton.width = bw + 16;
|
||||
specbutton.height = bh + 16;
|
||||
R2D_ImageColours(1,1,1,1);
|
||||
Draw_TextBox(lx, y, bw/8, bh/8);
|
||||
y += 8;
|
||||
lx += 8;
|
||||
|
||||
if (mousecursor_x >= specbutton.x && mousecursor_x < specbutton.x+specbutton.width)
|
||||
if (mousecursor_y >= specbutton.y && mousecursor_y < specbutton.y+specbutton.height)
|
||||
active = true;
|
||||
|
||||
Draw_FunStringWidth(lx, y + (bh-8)/2, "Observe", bw, 2, active);y+=8;
|
||||
}
|
||||
|
||||
{
|
||||
int lx = vid.width/2 - w/2;
|
||||
int y = vid.height/2 - h/2 - 4 + h;
|
||||
int bw, bh;
|
||||
qboolean active = false;
|
||||
bw = w+16;
|
||||
bh = 24;
|
||||
lx += w-12;
|
||||
w = strlen("join")*8 + 24;
|
||||
w = ((w+15)/16) * 16; //width must be a multiple of 16
|
||||
lx -= w;
|
||||
bw = strlen("Join")*8 + 24;
|
||||
bw = ((bw+15)/16) * 16; //width must be a multiple of 16
|
||||
lx -= bw;
|
||||
|
||||
joinbutton.x = lx;
|
||||
joinbutton.y = y;
|
||||
joinbutton.width = w + 16;
|
||||
joinbutton.height = h + 16;
|
||||
joinbutton.width = bw + 16;
|
||||
joinbutton.height = bh + 16;
|
||||
R2D_ImageColours(1,1,1,1);
|
||||
Draw_TextBox(lx, y, w/8, h/8);
|
||||
Draw_TextBox(lx, y, bw/8, bh/8);
|
||||
y += 8;
|
||||
lx += 8;
|
||||
|
||||
|
@ -611,7 +642,7 @@ static void SL_PostDraw (menu_t *menu)
|
|||
if (mousecursor_y >= joinbutton.y && mousecursor_y < joinbutton.y+joinbutton.height)
|
||||
active = true;
|
||||
|
||||
Draw_FunStringWidth(lx, y + (h-8)/2, "Join", w, 2, active);y+=8;
|
||||
Draw_FunStringWidth(lx, y + (bh-8)/2, "Join", bw, 2, active);y+=8;
|
||||
}
|
||||
}
|
||||
else if (isrefreshing)
|
||||
|
@ -658,7 +689,13 @@ static qboolean SL_Key (int key, menu_t *menu)
|
|||
if (mousecursor_y >= joinbutton.y && mousecursor_y < joinbutton.y+joinbutton.height)
|
||||
{
|
||||
serverpreview = false;
|
||||
goto doconnect;
|
||||
goto dojoin;
|
||||
}
|
||||
if (mousecursor_x >= specbutton.x && mousecursor_x < specbutton.x+joinbutton.width)
|
||||
if (mousecursor_y >= specbutton.y && mousecursor_y < specbutton.y+joinbutton.height)
|
||||
{
|
||||
serverpreview = false;
|
||||
goto dospec;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -698,10 +735,13 @@ static qboolean SL_Key (int key, menu_t *menu)
|
|||
else if (key == 'b' || key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER) //join
|
||||
{
|
||||
if (key == 's' || key == 'o')
|
||||
{
|
||||
dospec:
|
||||
Cbuf_AddText("spectator 1\n", RESTRICT_LOCAL);
|
||||
}
|
||||
else if (key == 'j')
|
||||
{
|
||||
doconnect:
|
||||
dojoin:
|
||||
Cbuf_AddText("spectator 0\n", RESTRICT_LOCAL);
|
||||
}
|
||||
|
||||
|
@ -834,7 +874,7 @@ static void SL_ServerPlayer (int x, int y, menucustom_t *ths, menu_t *menu)
|
|||
R2D_FillBlock (x, y, 32, 4);
|
||||
R2D_ImagePaletteColour (Sbar_ColorForMap(selectedserver.detail->players[i].botc), 1.0);
|
||||
R2D_FillBlock (x, y+4, 32, 4);
|
||||
|
||||
R2D_ImageColours (1.0, 1.0, 1.0, 1.0);
|
||||
Draw_FunStringWidth (x, y, va("%3i", selectedserver.detail->players[i].frags), 32-4, true, false);
|
||||
}
|
||||
|
||||
|
@ -1047,14 +1087,16 @@ void M_Menu_ServerList2_f(void)
|
|||
|
||||
info = (serverlist_t*)(menu + 1);
|
||||
|
||||
y = 8;
|
||||
y = 16;
|
||||
cust = MC_AddCustom(menu, 0, y, NULL, 0);
|
||||
cust->draw = SL_TitlesDraw;
|
||||
cust->key = SL_TitlesKey;
|
||||
cust->common.height = 8;
|
||||
cust->common.width = vid.width-8;
|
||||
y+=8;
|
||||
|
||||
info->visibleslots = (vid.height-16 - 64);
|
||||
info->servers_top = y;
|
||||
info->visibleslots = (vid.height-info->servers_top - 64);
|
||||
|
||||
cust = MC_AddCustom(menu, vid.width-8, 16, NULL, 0);
|
||||
cust->draw = SL_SliderDraw;
|
||||
|
@ -1063,7 +1105,7 @@ void M_Menu_ServerList2_f(void)
|
|||
cust->common.width = 8;
|
||||
|
||||
info->visibleslots = (info->visibleslots-8)/8;
|
||||
for (i = 0, y = 16; i <= info->visibleslots; y +=8, i++)
|
||||
for (i = 0, y = info->servers_top; i <= info->visibleslots; y +=8, i++)
|
||||
{
|
||||
cust = MC_AddCustom(menu, 0, y, NULL, i);
|
||||
if (i==0)
|
||||
|
|
|
@ -2770,7 +2770,7 @@ static void QDECL capture_raw_video (void *vctx, void *data, int frame, int widt
|
|||
char filename[MAX_OSPATH];
|
||||
ctx->frames = frame+1;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s%8.8i.%s", ctx->videonameprefix, frame, ctx->videonameextension);
|
||||
SCR_ScreenShot(filename, ctx->fsroot, data, width, height, fmt);
|
||||
SCR_ScreenShot(filename, ctx->fsroot, &data, 1, width, height, fmt);
|
||||
}
|
||||
static void QDECL capture_raw_audio (void *vctx, void *data, int bytes)
|
||||
{
|
||||
|
|
|
@ -200,6 +200,7 @@ void M_Menu_Options_f (void)
|
|||
"Fisheye",
|
||||
"Panoramic",
|
||||
"Lambert Azimuthal Equal-Area",
|
||||
"Equirectangular",
|
||||
NULL
|
||||
};
|
||||
static const char *projectionvalues[] = {
|
||||
|
|
|
@ -486,7 +486,7 @@ void M_Menu_SinglePlayer_f (void)
|
|||
{
|
||||
menu = M_CreateMenu(0);
|
||||
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
||||
MC_AddCenterPicture(menu, 0, 24, "gfx/p_option.lmp");
|
||||
MC_AddCenterPicture(menu, 0, 24, "gfx/ttl_sgl.lmp");
|
||||
|
||||
menu->selecteditem = (menuoption_t*)
|
||||
MC_AddConsoleCommandQBigFont (menu, 72, 32, "New Game", "closemenu;disconnect;maxclients 1;deathmatch 0;coop 0;startmap_sp\n");
|
||||
|
@ -500,7 +500,7 @@ void M_Menu_SinglePlayer_f (void)
|
|||
{ //q1
|
||||
menu = M_CreateMenu(0);
|
||||
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
||||
MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp");
|
||||
MC_AddCenterPicture(menu, 4, 24, "gfx/ttl_sgl.lmp");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ typedef struct { //must be first of each structure type.
|
|||
int width; //total width
|
||||
int height; //total height
|
||||
int extracollide; // dirty hack to stretch collide box left (the real fix is to have separate collide/render rects)
|
||||
char *tooltip;
|
||||
const char *tooltip;
|
||||
qboolean noselectionsound:1;
|
||||
qboolean iszone:1;
|
||||
qboolean ishidden:1;
|
||||
|
@ -325,7 +325,7 @@ typedef struct menubulk_s {
|
|||
menutype_t type;
|
||||
int variant;
|
||||
char *text;
|
||||
char *tooltip;
|
||||
const char *tooltip;
|
||||
char *consolecmd; // console command
|
||||
cvar_t *cvar; // check box, slider
|
||||
int flags; // check box
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef struct {
|
|||
int numframes;
|
||||
synctype_t synctype;
|
||||
//qtest stops here
|
||||
int flags;
|
||||
int flags; //offset 0x4c
|
||||
float size;
|
||||
//quake stops here
|
||||
int num_st;
|
||||
|
|
|
@ -6921,7 +6921,7 @@ qboolean CSQC_DrawView(void)
|
|||
void *pr_globals = PR_globals(csqcprogs, PR_CURRENT);
|
||||
G_FLOAT(OFS_PARM0) = vid.width;
|
||||
G_FLOAT(OFS_PARM1) = vid.height;
|
||||
G_FLOAT(OFS_PARM2) = !m_state;
|
||||
G_FLOAT(OFS_PARM2) = !m_state && !r_refdef.eyeoffset[0] && !r_refdef.eyeoffset[1];
|
||||
}
|
||||
//end EXT_CSQC_1
|
||||
if (csqcg.f_updateviewloading && cls.state && cls.state < ca_active)
|
||||
|
@ -6943,7 +6943,7 @@ qboolean CSQC_DrawView(void)
|
|||
|
||||
qboolean CSQC_KeyPress(int key, int unicode, qboolean down, int devid)
|
||||
{
|
||||
static qbyte csqckeysdown[K_MAX/8];
|
||||
static qbyte csqckeysdown[K_MAX];
|
||||
void *pr_globals;
|
||||
#ifdef TEXTEDITOR
|
||||
extern qboolean editormodal;
|
||||
|
@ -6962,18 +6962,24 @@ qboolean CSQC_KeyPress(int key, int unicode, qboolean down, int devid)
|
|||
G_FLOAT(OFS_PARM2) = unicode;
|
||||
G_FLOAT(OFS_PARM3) = devid;
|
||||
|
||||
//small sanity check, so things don't break too much if things get big.
|
||||
if (devid < 0 || (unsigned)devid >= sizeof(csqckeysdown[0])*8)
|
||||
devid = sizeof(csqckeysdown[0])*8-1;
|
||||
if (key < 0 || key >= K_MAX)
|
||||
key = 0; //panic. everyone panic.
|
||||
|
||||
if (down)
|
||||
{
|
||||
qcinput_scan = G_FLOAT(OFS_PARM1);
|
||||
qcinput_unicode = G_FLOAT(OFS_PARM2);
|
||||
|
||||
csqckeysdown[key>>3] |= (1<<(key&7));
|
||||
csqckeysdown[key] |= (1u<<devid);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (key && !(csqckeysdown[key>>3] & (1<<(key&7))))
|
||||
return false;
|
||||
csqckeysdown[key>>3] &= ~(1<<(key&7));
|
||||
if (key && !(csqckeysdown[key] & (1u<<devid)))
|
||||
return false; //prevent up events being able to leak
|
||||
csqckeysdown[key] &= ~(1u<<devid);
|
||||
}
|
||||
PR_ExecuteProgram (csqcprogs, csqcg.input_event);
|
||||
qcinput_scan = 0; //and stop replay attacks
|
||||
|
@ -7045,6 +7051,20 @@ qboolean CSQC_Accelerometer(float x, float y, float z)
|
|||
PR_ExecuteProgram (csqcprogs, csqcg.input_event);
|
||||
return G_FLOAT(OFS_RETURN);
|
||||
}
|
||||
qboolean CSQC_Gyroscope(float x, float y, float z)
|
||||
{
|
||||
void *pr_globals;
|
||||
if (!csqcprogs || !csqcg.input_event)
|
||||
return false;
|
||||
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
|
||||
|
||||
G_FLOAT(OFS_PARM0) = CSIE_GYROSCOPE;
|
||||
G_FLOAT(OFS_PARM1) = x;
|
||||
G_FLOAT(OFS_PARM2) = y;
|
||||
G_FLOAT(OFS_PARM3) = z;
|
||||
PR_ExecuteProgram (csqcprogs, csqcg.input_event);
|
||||
return G_FLOAT(OFS_RETURN);
|
||||
}
|
||||
|
||||
qboolean CSQC_ConsoleLink(char *text, char *info)
|
||||
{
|
||||
|
|
|
@ -230,9 +230,9 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
const char *slotname = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
const char *facename = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
const char *sizestr = PR_GetStringOfs(prinst, OFS_PARM2);
|
||||
int slotnum = G_FLOAT(OFS_PARM3);
|
||||
//float fix_scale = G_FLOAT(OFS_PARM4);
|
||||
//float fix_voffset = G_FLOAT(OFS_PARM5);
|
||||
int slotnum = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):-1;
|
||||
//float fix_scale = (prinst->callargc>4)?G_FLOAT(OFS_PARM4):0;
|
||||
//float fix_voffset = (prinst->callargc>5)G_FLOAT(OFS_PARM5):0;
|
||||
int i, sz;
|
||||
world_t *world = prinst->parms->user;
|
||||
|
||||
|
|
|
@ -200,48 +200,37 @@ extern "C" {
|
|||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
|
||||
//msvcrt lacks any and all c99 support.
|
||||
#ifdef _WIN32
|
||||
#define fPRIp "%p"
|
||||
#define PRIxPTR "p"
|
||||
//totally different from any other system
|
||||
#define fPRIllx "%I64x"
|
||||
#define fPRIllu "%I64u"
|
||||
#define fPRIlli "%I64i"
|
||||
#else
|
||||
//make SURE we get 0xdeadbeef for this
|
||||
#if FTE_WORDSIZE != 32
|
||||
#define fPRIp "%#zx"
|
||||
#else
|
||||
#define fPRIp "%#x"
|
||||
#endif
|
||||
#define PRIx64 "I64x"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRIi64 "I64i"
|
||||
|
||||
//assume some c99 support where we print long long int types.
|
||||
#define fPRIllx "%llx"
|
||||
#define fPRIllu "%llu"
|
||||
#define fPRIlli "%lli"
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
//windows does not follow c99 at all
|
||||
#ifdef _WIN64
|
||||
#define fPRIzx "%Ix"
|
||||
#define fPRIzu "%Iu"
|
||||
#define fPRIzi "%Ii"
|
||||
#define PRIxSIZE "Ix"
|
||||
#define PRIuSIZE "Iu"
|
||||
#define PRIiSIZE "Ii"
|
||||
#else
|
||||
#define fPRIzx "%x"
|
||||
#define fPRIzu "%u"
|
||||
#define fPRIzi "%i"
|
||||
#define PRIxSIZE "x"
|
||||
#define PRIuSIZE "u"
|
||||
#define PRIiSIZE "i"
|
||||
#endif
|
||||
#elif FTE_WORDSIZE != 32
|
||||
//64bit systems are expected to have an awareness of c99
|
||||
#define fPRIzx "%zx"
|
||||
#define fPRIzu "%zu"
|
||||
#define fPRIzi "%zi"
|
||||
#else
|
||||
//regular old c89 for 32bit platforms.
|
||||
#define fPRIzx "%x"
|
||||
#define fPRIzu "%u"
|
||||
#define fPRIzi "%i"
|
||||
#include <inttypes.h>
|
||||
//these are non-standard. c99 would expect people to just use %zx etc
|
||||
#if FTE_WORDSIZE != 32
|
||||
//64bit systems are expected to have an awareness of c99
|
||||
#define PRIxSIZE "zx"
|
||||
#define PRIuSIZE "zu"
|
||||
#define PRIiSIZE "zi"
|
||||
#else
|
||||
//regular old c89 for 32bit platforms.
|
||||
#define PRIxSIZE "x"
|
||||
#define PRIuSIZE "u"
|
||||
#define PRIiSIZE "i"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#endif
|
||||
|
||||
void Mod_SetParent (mnode_t *node, mnode_t *parent);
|
||||
static int D3_LeafnumForPoint (struct model_s *model, vec3_t point);
|
||||
static int D3_ClusterForPoint (struct model_s *model, vec3_t point);
|
||||
|
||||
#ifndef SERVERONLY
|
||||
static qboolean Mod_LoadMap_Proc(model_t *model, char *data)
|
||||
|
@ -118,7 +118,7 @@ static qboolean Mod_LoadMap_Proc(model_t *model, char *data)
|
|||
m[surf].numindexes = numindicies;
|
||||
vdata = ZG_Malloc(&model->memgroup, numverts * (sizeof(vecV_t) + sizeof(vec2_t) + sizeof(vec3_t) + sizeof(vec4_t)) + numindicies * sizeof(index_t));
|
||||
|
||||
m[surf].colors4f_array = (vec4_t*)vdata;vdata += sizeof(vec4_t)*numverts;
|
||||
m[surf].colors4f_array[0] = (vec4_t*)vdata;vdata += sizeof(vec4_t)*numverts;
|
||||
m[surf].xyz_array = (vecV_t*)vdata;vdata += sizeof(vecV_t)*numverts;
|
||||
m[surf].st_array = (vec2_t*)vdata;vdata += sizeof(vec2_t)*numverts;
|
||||
m[surf].normals_array = (vec3_t*)vdata;vdata += sizeof(vec3_t)*numverts;
|
||||
|
@ -156,22 +156,22 @@ static qboolean Mod_LoadMap_Proc(model_t *model, char *data)
|
|||
sub->mins[j] = f;
|
||||
}
|
||||
|
||||
m[surf].colors4f_array[v][0] = 255;
|
||||
m[surf].colors4f_array[v][1] = 255;
|
||||
m[surf].colors4f_array[v][2] = 255;
|
||||
m[surf].colors4f_array[v][3] = 255;
|
||||
m[surf].colors4f_array[0][v][0] = 255;
|
||||
m[surf].colors4f_array[0][v][1] = 255;
|
||||
m[surf].colors4f_array[0][v][2] = 255;
|
||||
m[surf].colors4f_array[0][v][3] = 255;
|
||||
|
||||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
/*if its not closed yet, there's an optional colour value*/
|
||||
if (strcmp(token, ")"))
|
||||
{
|
||||
m[surf].colors4f_array[v][0] = atof(token)/255;
|
||||
m[surf].colors4f_array[0][v][0] = atof(token)/255;
|
||||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
m[surf].colors4f_array[v][1] = atof(token)/255;
|
||||
m[surf].colors4f_array[0][v][1] = atof(token)/255;
|
||||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
m[surf].colors4f_array[v][2] = atof(token)/255;
|
||||
m[surf].colors4f_array[0][v][2] = atof(token)/255;
|
||||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
m[surf].colors4f_array[v][3] = atof(token)/255;
|
||||
m[surf].colors4f_array[0][v][3] = atof(token)/255;
|
||||
|
||||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
if (strcmp(token, ")"))
|
||||
|
@ -190,7 +190,7 @@ static qboolean Mod_LoadMap_Proc(model_t *model, char *data)
|
|||
data = COM_ParseOut(data, token, sizeof(token));
|
||||
if (strcmp(token, "}"))
|
||||
return false;
|
||||
sub->needload = false;
|
||||
// sub->loadstate = MLS_LOADED;
|
||||
sub->fromgame = fg_doom3;
|
||||
sub->type = mod_brush;
|
||||
|
||||
|
@ -396,7 +396,7 @@ unsigned char *D3_CalcVis(model_t *mod, vec3_t org)
|
|||
static unsigned char vis[256];
|
||||
vec_t newbounds[4];
|
||||
|
||||
start = D3_LeafnumForPoint(mod, org);
|
||||
start = D3_ClusterForPoint(mod, org);
|
||||
/*figure out which area we're in*/
|
||||
if (start < 0)
|
||||
{
|
||||
|
@ -452,7 +452,7 @@ void D3_GenerateAreas(model_t *mod)
|
|||
cl_static_entities[cl.num_statics].pvscache.num_leafs = 1;
|
||||
cl_static_entities[cl.num_statics].pvscache.leafnums[0] = area;
|
||||
|
||||
if (ent->model && !ent->model->needload)
|
||||
if (ent->model && ent->model->loadstate != MLS_NOTLOADED)
|
||||
cl.num_statics++;
|
||||
else
|
||||
break;
|
||||
|
@ -465,12 +465,12 @@ void D3_GenerateAreas(model_t *mod)
|
|||
static void D3_FindTouchedLeafs (struct model_s *model, struct pvscache_s *ent, vec3_t cullmins, vec3_t cullmaxs)
|
||||
{
|
||||
}
|
||||
static qbyte *D3_LeafPVS (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize)
|
||||
static qbyte *D3_ClusterPVS (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize)
|
||||
{
|
||||
memset(buffer, 0xff, buffersize);
|
||||
return buffer;
|
||||
}
|
||||
static int D3_LeafnumForPoint (struct model_s *model, vec3_t point)
|
||||
static int D3_ClusterForPoint (struct model_s *model, vec3_t point)
|
||||
{
|
||||
float p;
|
||||
int c;
|
||||
|
@ -841,7 +841,7 @@ return;
|
|||
D3_RecursiveSurfCheck (node->child[side^1], midf, p2f, mid, p2);
|
||||
}
|
||||
|
||||
static qboolean D3_Trace (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int hitcontentsmask, struct trace_s *trace)
|
||||
static qboolean D3_Trace (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int hitcontentsmask, struct trace_s *trace)
|
||||
{
|
||||
int i;
|
||||
float e1,e2;
|
||||
|
@ -1008,7 +1008,7 @@ typedef struct
|
|||
int v[2];
|
||||
int fl[2];
|
||||
} d3edge_t;
|
||||
qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf)
|
||||
qboolean QDECL D3_LoadMap_CollisionMap(model_t *mod, void *buf, size_t bufsize)
|
||||
{
|
||||
int pedges[64];
|
||||
cm_surface_t *surf;
|
||||
|
@ -1296,17 +1296,17 @@ qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf)
|
|||
|
||||
/*load up the .map so we can get some entities (anyone going to bother making a qc mod compatible with this?)*/
|
||||
COM_StripExtension(mod->name, token, sizeof(token));
|
||||
mod->entities = FS_LoadMallocFile(va("%s.map", token));
|
||||
mod->entities = FS_LoadMallocFile(va("%s.map", token), NULL);
|
||||
|
||||
mod->funcs.FindTouchedLeafs = D3_FindTouchedLeafs;
|
||||
mod->funcs.NativeTrace = D3_Trace;
|
||||
mod->funcs.PointContents = D3_PointContents;
|
||||
mod->funcs.FatPVS = D3_FatPVS;
|
||||
mod->funcs.LeafnumForPoint = D3_LeafnumForPoint;
|
||||
mod->funcs.ClusterForPoint = D3_ClusterForPoint;
|
||||
mod->funcs.StainNode = D3_StainNode;
|
||||
mod->funcs.LightPointValues = D3_LightPointValues;
|
||||
mod->funcs.EdictInFatPVS = D3_EdictInFatPVS;
|
||||
mod->funcs.LeafPVS = D3_LeafPVS;
|
||||
mod->funcs.ClusterPVS = D3_ClusterPVS;
|
||||
|
||||
mod->fromgame = fg_doom3;
|
||||
|
||||
|
@ -1315,7 +1315,7 @@ qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf)
|
|||
if (!isDedicated)
|
||||
{
|
||||
COM_StripExtension(mod->name, token, sizeof(token));
|
||||
buf = FS_LoadMallocFile(va("%s.proc", token));
|
||||
buf = FS_LoadMallocFile(va("%s.proc", token), NULL);
|
||||
Mod_LoadMap_Proc(mod, buf);
|
||||
BZ_Free(buf);
|
||||
}
|
||||
|
|
|
@ -202,6 +202,29 @@ typedef struct
|
|||
void CL_BlendFog(fogstate_t *result, fogstate_t *oldf, float time, fogstate_t *newf);
|
||||
void CL_ResetFog(int fogtype);
|
||||
|
||||
typedef enum {
|
||||
STEREO_OFF,
|
||||
STEREO_QUAD,
|
||||
STEREO_RED_CYAN,
|
||||
STEREO_RED_BLUE,
|
||||
STEREO_RED_GREEN,
|
||||
STEREO_CROSSEYED,
|
||||
|
||||
//these are internal methods and do not form part of any public API
|
||||
STEREO_LEFTONLY,
|
||||
STEREO_RIGHTONLY
|
||||
} stereomethod_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROJ_STANDARD = 0,
|
||||
PROJ_STEREOGRAPHIC = 1, //aka panini
|
||||
PROJ_FISHEYE = 2, //standard fisheye
|
||||
PROJ_PANORAMA = 3, //for nice panoramas
|
||||
PROJ_LAEA = 4, //lambert azimuthal equal-area
|
||||
PROJ_EQUIRECTANGULAR = 5 //projects a sphere into 2d. used by vr screenshots.
|
||||
} qprojection_t;
|
||||
|
||||
typedef struct {
|
||||
char texname[MAX_QPATH];
|
||||
} rtname_t;
|
||||
|
@ -220,6 +243,8 @@ typedef struct
|
|||
vec3_t vieworg; /*logical view center*/
|
||||
vec3_t viewangles;
|
||||
vec3_t viewaxis[3]; /*forward, left, up (NOT RIGHT)*/
|
||||
vec3_t headaxis[3]; /*this is for head mounted displays. this is relative to the view*/
|
||||
vec3_t eyeoffset; /*world space, for vr screenies*/
|
||||
|
||||
float fov_x, fov_y, afov;
|
||||
|
||||
|
@ -251,6 +276,7 @@ typedef struct
|
|||
unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/
|
||||
qboolean useperspective; /*not orthographic*/
|
||||
|
||||
stereomethod_t stereomethod;
|
||||
rtname_t rt_destcolour[R_MAX_RENDERTARGETS]; /*used for 2d. written by 3d*/
|
||||
rtname_t rt_sourcecolour; /*read by 2d. not used for 3d. */
|
||||
rtname_t rt_depth; /*read by 2d. used by 3d (renderbuffer used if not set)*/
|
||||
|
|
|
@ -202,7 +202,7 @@ cvar_t scr_showturtle = SCVAR ("showturtle", "0");
|
|||
cvar_t scr_turtlefps = SCVAR ("scr_turtlefps", "10");
|
||||
cvar_t scr_sshot_compression = SCVAR ("scr_sshot_compression", "75");
|
||||
cvar_t scr_sshot_type = SCVAR ("scr_sshot_type", "png");
|
||||
cvar_t scr_sshot_prefix = SCVAR ("scr_sshot_prefix", "screenshots/fte");
|
||||
cvar_t scr_sshot_prefix = SCVAR ("scr_sshot_prefix", "screenshots/fte-");
|
||||
cvar_t scr_viewsize = CVARFC("viewsize", "100",
|
||||
CVAR_ARCHIVE,
|
||||
SCR_Viewsize_Callback);
|
||||
|
@ -248,8 +248,10 @@ cvar_t vid_wndalpha = CVARD ("vid_wndalpha", "1", "When running windowed,
|
|||
//more readable defaults to match conwidth/conheight.
|
||||
cvar_t vid_width = CVARFD ("vid_width", "0",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "The screen width to attempt to use, in physical pixels. 0 means use desktop resolution.");
|
||||
cvar_t vid_dpi_x = CVARFD ("vid_dpi_x", "0", CVAR_NOSET, "For mods that need to determine the physical screen size (like with touchscreens). 0 means unknown");
|
||||
cvar_t vid_dpi_y = CVARFD ("vid_dpi_y", "0", CVAR_NOSET, "For mods that need to determine the physical screen size (like with touchscreens). 0 means unknown");
|
||||
|
||||
cvar_t r_stereo_separation = CVARD("r_stereo_separation", "4", "How far your eyes are apart, in quake units. A non-zero value will enable stereoscoping rendering. You might need some of them retro 3d glasses. Hardware support is recommended, see r_stereo_context.");
|
||||
cvar_t r_stereo_separation = CVARD("r_stereo_separation", "4", "How far apart your eyes are, in quake units. A non-zero value will enable stereoscoping rendering. You might need some of them retro 3d glasses. Hardware support is recommended, see r_stereo_context.");
|
||||
cvar_t r_stereo_method = CVARFD("r_stereo_method", "0", CVAR_ARCHIVE, "Value 0 = Off.\nValue 1 = Attempt hardware acceleration. Requires vid_restart.\nValue 2 = red/cyan.\nValue 3 = red/blue.\nValue 4=red/green.\nValue 5=eye strain.");
|
||||
|
||||
extern cvar_t r_dodgytgafiles;
|
||||
|
@ -392,7 +394,7 @@ cvar_t r_shadow_heightscale_bumpmap = CVARD ("r_shadow_heightscale_bumpmap",
|
|||
|
||||
cvar_t r_glsl_offsetmapping = CVARFD ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Enables the use of paralax mapping, adding fake depth to textures.");
|
||||
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
|
||||
cvar_t r_glsl_offsetmapping_reliefmapping = CVARFD("r_glsl_offsetmapping_reliefmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes the paralax sampling mode to be a bit nicer, but noticably more expensive at high resolutions. r_glsl_offsetmapping must be set.");
|
||||
cvar_t r_glsl_offsetmapping_reliefmapping = CVARFD("r_glsl_offsetmapping_reliefmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes the paralax sampling mode to be a bit nicer, but noticably more expensive at high resolutions. r_glsl_offsetmapping must be set.");
|
||||
cvar_t r_glsl_turbscale = CVARFD ("r_glsl_turbscale", "1", CVAR_ARCHIVE, "Controls the strength of water ripples (used by the altwater glsl code).");
|
||||
|
||||
cvar_t r_fastturbcolour = CVARFD ("r_fastturbcolour", "0.1 0.2 0.3", CVAR_ARCHIVE, "The colour to use for water surfaces draw with r_waterstyle 0.\n");
|
||||
|
@ -684,6 +686,8 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&vid_refreshrate, VIDCOMMANDGROUP);
|
||||
Cvar_Register (&vid_multisample, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&vid_srgb, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&vid_dpi_x, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&vid_dpi_y, GLRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&vid_desktopsettings, VIDCOMMANDGROUP);
|
||||
|
||||
|
@ -837,7 +841,7 @@ void Renderer_Init(void)
|
|||
|
||||
qboolean Renderer_Started(void)
|
||||
{
|
||||
return !!currentrendererstate.renderer;
|
||||
return !r_blockvidrestart && !!currentrendererstate.renderer;
|
||||
}
|
||||
|
||||
void Renderer_Start(void)
|
||||
|
@ -1046,14 +1050,17 @@ void R_ShutdownRenderer(qboolean devicetoo)
|
|||
TRACE(("dbg: R_ApplyRenderer: R_DeInit\n"));
|
||||
R_DeInit();
|
||||
}
|
||||
R_DeInit = NULL;
|
||||
|
||||
if (Draw_Shutdown)
|
||||
Draw_Shutdown();
|
||||
Draw_Shutdown = NULL;
|
||||
|
||||
if (VID_DeInit && devicetoo)
|
||||
{
|
||||
TRACE(("dbg: R_ApplyRenderer: VID_DeInit\n"));
|
||||
VID_DeInit();
|
||||
VID_DeInit = NULL;
|
||||
}
|
||||
|
||||
TRACE(("dbg: R_ApplyRenderer: SCR_DeInit\n"));
|
||||
|
@ -1143,6 +1150,9 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
|
|||
r_softwarebanding = r_softwarebanding_cvar.ival;
|
||||
r_deluxemapping = r_deluxemapping_cvar.ival;
|
||||
|
||||
vid.dpi_x = 0;
|
||||
vid.dpi_y = 0;
|
||||
|
||||
if (qrenderer != QR_NONE) //graphics stuff only when not dedicated
|
||||
{
|
||||
size_t sz;
|
||||
|
@ -1260,6 +1270,9 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
|
|||
|
||||
// host_hunklevel = Hunk_LowMark();
|
||||
|
||||
Cvar_ForceSetValue(&vid_dpi_x, vid.dpi_x);
|
||||
Cvar_ForceSetValue(&vid_dpi_y, vid.dpi_y);
|
||||
|
||||
|
||||
TRACE(("dbg: R_ApplyRenderer: R_PreNewMap (how handy)\n"));
|
||||
Surf_PreNewMap();
|
||||
|
|
|
@ -81,7 +81,7 @@ void SCR_ShowPic_Remove_f(void);
|
|||
void Draw_TextBox (int x, int y, int width, int lines);
|
||||
enum fs_relative;
|
||||
enum uploadfmt;
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void *rgb_buffer, int width, int height, enum uploadfmt fmt);
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int width, int height, enum uploadfmt fmt);
|
||||
|
||||
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud);
|
||||
|
||||
|
|
|
@ -1577,6 +1577,9 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
memset(sc, 0, sizeof(*sc));
|
||||
sc->seat = seat;
|
||||
|
||||
sc->next = sndcardinfo;
|
||||
sndcardinfo = sc;
|
||||
|
||||
// set requested rate
|
||||
if (snd_khz.ival >= 1000)
|
||||
sc->sn.speed = snd_khz.ival;
|
||||
|
@ -1632,7 +1635,7 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
if (st)
|
||||
{
|
||||
S_DefaultSpeakerConfiguration(sc);
|
||||
if (sndcardinfo)
|
||||
if (snd_speed)
|
||||
{ //if the sample speeds of multiple soundcards do not match, it'll fail.
|
||||
if (snd_speed != sc->sn.speed)
|
||||
{
|
||||
|
@ -1644,8 +1647,8 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
else
|
||||
snd_speed = sc->sn.speed;
|
||||
|
||||
sc->next = sndcardinfo;
|
||||
sndcardinfo = sc;
|
||||
if (sc->seat == -1 && sc->ListenerUpdate)
|
||||
sc->seat = 0; //hardware rendering won't cope with seat=-1
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
@ -1664,7 +1667,8 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
if (st == 1)
|
||||
{
|
||||
S_DefaultSpeakerConfiguration(sc);
|
||||
if (sndcardinfo)
|
||||
|
||||
if (snd_speed)
|
||||
{ //if the sample speeds of multiple soundcards do not match, it'll fail.
|
||||
if (snd_speed != sc->sn.speed)
|
||||
{
|
||||
|
@ -1678,14 +1682,13 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
|
||||
if (sc->seat == -1 && sc->ListenerUpdate)
|
||||
sc->seat = 0; //hardware rendering won't cope with seat=-1
|
||||
sc->next = sndcardinfo;
|
||||
sndcardinfo = sc;
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Z_Free(sc);
|
||||
S_ShutdownCard(sc);
|
||||
|
||||
if (!driver)
|
||||
Con_TPrintf("Could not start audio device \"%s\"\n", device?device:"default");
|
||||
else
|
||||
|
@ -1693,9 +1696,9 @@ static soundcardinfo_t *SNDDMA_Init(char *driver, char *device, int seat)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void S_SetupDeviceSeat(char *driver, char *device, int seat)
|
||||
soundcardinfo_t *S_SetupDeviceSeat(char *driver, char *device, int seat)
|
||||
{
|
||||
SNDDMA_Init(driver, device, seat);
|
||||
return SNDDMA_Init(driver, device, seat);
|
||||
/*
|
||||
soundcardinfo_t *sc;
|
||||
for (sc = sndcardinfo; sc; sc = sc->next)
|
||||
|
@ -1781,7 +1784,7 @@ void S_Startup (void)
|
|||
if (!sndcardinfo && !nodefault)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(FTE_SDL)
|
||||
INS_SetupControllerAudioDevices();
|
||||
INS_SetupControllerAudioDevices(true);
|
||||
#endif
|
||||
if (!sndcardinfo)
|
||||
SNDDMA_Init(NULL, NULL, -1);
|
||||
|
@ -2021,26 +2024,28 @@ void S_Init (void)
|
|||
|
||||
void S_ShutdownCard(soundcardinfo_t *sc)
|
||||
{
|
||||
soundcardinfo_t *prev;
|
||||
soundcardinfo_t **link;
|
||||
|
||||
if (sndcardinfo == sc)
|
||||
sndcardinfo = sc->next;
|
||||
else
|
||||
for (link = &sndcardinfo; *link; link = &(*link)->next)
|
||||
{
|
||||
for (prev = sndcardinfo; prev->next; prev = prev->next)
|
||||
if (*link == sc)
|
||||
{
|
||||
if (prev->next == sc)
|
||||
prev->next = sc->next;
|
||||
*link = sc->next;
|
||||
if (sc->Shutdown)
|
||||
sc->Shutdown(sc);
|
||||
Z_Free(sc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sc->Shutdown(sc);
|
||||
Z_Free(sc);
|
||||
}
|
||||
void S_Shutdown(qboolean final)
|
||||
{
|
||||
soundcardinfo_t *sc, *next;
|
||||
|
||||
#if defined(_WIN32) && !defined(FTE_SDL)
|
||||
INS_SetupControllerAudioDevices(false);
|
||||
#endif
|
||||
|
||||
for (sc = sndcardinfo; sc; sc=next)
|
||||
{
|
||||
next = sc->next;
|
||||
|
|
|
@ -824,7 +824,7 @@ void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b)
|
|||
result = VFS_READ(f, data, filesize);
|
||||
|
||||
if (result != filesize)
|
||||
Con_SafePrintf("S_LoadSound() fread: Filename: %s, expected "fPRIzu", result was "fPRIzu"\n", name, filesize, result);
|
||||
Con_SafePrintf("S_LoadSound() fread: Filename: %s, expected %"PRIuSIZE", result was %"PRIuSIZE"\n", name, filesize, result);
|
||||
|
||||
VFS_CLOSE(f);
|
||||
}
|
||||
|
|
|
@ -164,6 +164,7 @@ void S_EndPrecaching (void);
|
|||
void S_PaintChannels(soundcardinfo_t *sc, int endtime);
|
||||
void S_InitPaintChannels (soundcardinfo_t *sc);
|
||||
|
||||
soundcardinfo_t *S_SetupDeviceSeat(char *driver, char *device, int seat);
|
||||
void S_ShutdownCard (soundcardinfo_t *sc);
|
||||
|
||||
void S_DefaultSpeakerConfiguration(soundcardinfo_t *sc);
|
||||
|
@ -341,6 +342,4 @@ typedef struct
|
|||
void (QDECL *Shutdown) (void *ctx); /*destroy everything*/
|
||||
} snd_capture_driver_t;
|
||||
|
||||
void S_SetupDeviceSeat(char *driver, char *device, int seat);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@ qboolean isDedicated = false;
|
|||
void *sys_window; /*public so the renderer can attach to the correct place*/
|
||||
static int sys_running = false;
|
||||
int sys_glesversion;
|
||||
extern qboolean r_blockvidrestart;
|
||||
float sys_dpi_x, sys_dpi_y;
|
||||
int sys_soundflags; /*1 means active. 2 means reset (so claim that its not active for one frame to force a reset)*/
|
||||
static void *sys_memheap;
|
||||
static unsigned int sys_lastframe;
|
||||
|
@ -110,10 +112,12 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_motion(JNIEnv *env, jobject
|
|||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject obj,
|
||||
jfloat ax, jfloat ay, jfloat az)
|
||||
jfloat ax, jfloat ay, jfloat az,
|
||||
jfloat gx, jfloat gy, jfloat gz)
|
||||
{
|
||||
int ret;
|
||||
static vec3_t oac;
|
||||
static vec3_t oacc;
|
||||
static vec3_t ogyro;
|
||||
|
||||
//if we had an error, don't even run a frame any more.
|
||||
if (*errormessage || !sys_running)
|
||||
|
@ -122,20 +126,29 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
|
|||
return 8;
|
||||
}
|
||||
|
||||
// Sys_Printf("starting frame\n");
|
||||
|
||||
#ifdef SERVERONLY
|
||||
SV_Frame();
|
||||
#else
|
||||
unsigned int now = Sys_Milliseconds();
|
||||
double tdelta = (now - sys_lastframe) * 0.001;
|
||||
if (oac[0] != ax || oac[1] != ay || oac[2] != az)
|
||||
if (oacc[0] != ax || oacc[1] != ay || oacc[2] != az)
|
||||
{
|
||||
//down: x= +9.8
|
||||
//left: y= -9.8
|
||||
//up: z= +9.8
|
||||
CSQC_Accelerometer(ax, ay, az);
|
||||
oac[0] = ax;
|
||||
oac[1] = ay;
|
||||
oac[2] = az;
|
||||
oacc[0] = ax;
|
||||
oacc[1] = ay;
|
||||
oacc[2] = az;
|
||||
}
|
||||
if (ogyro[0] != gx || ogyro[1] != gy || ogyro[2] != gz)
|
||||
{
|
||||
CSQC_Gyroscope(gx * 180.0/M_PI, gy * 180.0/M_PI, gz * 180.0/M_PI);
|
||||
ogyro[0] = gx;
|
||||
ogyro[1] = gy;
|
||||
ogyro[2] = gz;
|
||||
}
|
||||
Host_Frame(tdelta);
|
||||
sys_lastframe = now;
|
||||
|
@ -148,7 +161,7 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
|
|||
ret |= 2;
|
||||
if (sys_keepscreenon.ival)
|
||||
ret |= 4;
|
||||
if (*errormessage)
|
||||
if (*errormessage || !sys_running)
|
||||
ret |= 8;
|
||||
if (sys_orientation.modified || sys_glesversion_cvar.modified)
|
||||
ret |= 16;
|
||||
|
@ -159,9 +172,25 @@ JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_frame(JNIEnv *env, jobject
|
|||
else
|
||||
ret |= 32;
|
||||
}
|
||||
// Sys_Printf("frame ended\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
//tells us that our old gl context is about to be nuked.
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_killglcontext(JNIEnv *env, jobject obj)
|
||||
{
|
||||
if (!sys_running)
|
||||
return;
|
||||
if (qrenderer == QR_NONE)
|
||||
return; //not initialised yet...
|
||||
Sys_Printf("Killing resources\n");
|
||||
R_ShutdownRenderer(true);
|
||||
qrenderer = QR_NONE;
|
||||
sys_glesversion = 0;
|
||||
if (!r_blockvidrestart)
|
||||
r_blockvidrestart = 3; //so video is restarted properly for the next frame
|
||||
}
|
||||
|
||||
//tells us that our old gl context got completely obliterated
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_newglcontext(JNIEnv *env, jobject obj)
|
||||
{
|
||||
|
@ -176,13 +205,14 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_openfile(JNIEnv *env, jobje
|
|||
jstring openfile)
|
||||
{
|
||||
const char *fname = (*env)->GetStringUTFChars(env, openfile, NULL);
|
||||
Host_RunFile(fname, strlen(fname), NULL);
|
||||
if (sys_running)
|
||||
Host_RunFile(fname, strlen(fname), NULL);
|
||||
(*env)->ReleaseStringUTFChars(env, openfile, fname);
|
||||
}
|
||||
|
||||
//called for init or resizes
|
||||
JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject obj,
|
||||
jint width, jint height, jint glesversion, jstring japkpath, jstring jusrpath)
|
||||
jint width, jint height, jfloat dpix, jfloat dpiy, jint glesversion, jstring japkpath, jstring jusrpath)
|
||||
{
|
||||
const char *tmp;
|
||||
|
||||
|
@ -192,13 +222,17 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
|
|||
vid.pixelwidth = width;
|
||||
vid.pixelheight = height;
|
||||
sys_glesversion = glesversion;
|
||||
sys_dpi_x = dpix;
|
||||
sys_dpi_y = dpiy;
|
||||
if (sys_running)
|
||||
{
|
||||
Sys_Printf("vid size changed\n");
|
||||
if (1)//FFS sys_running == 2)
|
||||
if (!glesversion)
|
||||
return; //gah!
|
||||
Sys_Printf("vid size changed (%i %i gles%i)\n", width, height, glesversion);
|
||||
if (!r_blockvidrestart)
|
||||
{
|
||||
//if our textures got destroyed, we need to reload them all
|
||||
Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL);
|
||||
Cmd_ExecuteString("vid_reload\n", RESTRICT_LOCAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -246,6 +280,11 @@ JNIEXPORT void JNICALL Java_com_fteqw_FTEDroidEngine_init(JNIEnv *env, jobject o
|
|||
sys_running = true;
|
||||
sys_lastframe = Sys_Milliseconds();
|
||||
sys_orientation.modified = true;
|
||||
|
||||
while(r_blockvidrestart == 1)
|
||||
Java_com_fteqw_FTEDroidEngine_frame(env, obj, 0,0,0, 0,0,0);
|
||||
|
||||
Sys_Printf("Engine started\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,6 +360,7 @@ void Sys_Quit(void)
|
|||
SV_Shutdown();
|
||||
#endif
|
||||
|
||||
sys_running = false;
|
||||
LOGI("%s", "quitting");
|
||||
|
||||
longjmp(host_abort, 1);
|
||||
|
|
|
@ -26,7 +26,6 @@ SDL_Window *sdlwindow;
|
|||
#ifndef isDedicated
|
||||
qboolean isDedicated;
|
||||
#endif
|
||||
extern qboolean ActiveApp;
|
||||
|
||||
void Sys_Error (const char *error, ...)
|
||||
{
|
||||
|
@ -502,7 +501,7 @@ int QDECL main(int argc, char **argv)
|
|||
|
||||
// yield the CPU for a little while when paused, minimized, or not the focus
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
if (!ActiveApp)
|
||||
if (!vid.activeapp)
|
||||
SDL_Delay(1);
|
||||
#else
|
||||
if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS))
|
||||
|
|
|
@ -49,7 +49,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; //13.35+
|
|||
|
||||
#ifdef WINRT //you're going to need a different sys_ port.
|
||||
qboolean isDedicated = false;
|
||||
qboolean ActiveApp;
|
||||
void VARGS Sys_Error (const char *error, ...){} //eep
|
||||
void VARGS Sys_Printf (char *fmt, ...){} //safe, but not ideal (esp for debugging)
|
||||
void Sys_SendKeyEvents (void){} //safe, but not ideal
|
||||
|
@ -483,7 +482,7 @@ char *Sys_GetNameForAddress(dllhandle_t *module, void *address)
|
|||
#endif
|
||||
|
||||
int starttime;
|
||||
qboolean ActiveApp, Minimized;
|
||||
qboolean Minimized;
|
||||
qboolean WinNT; //NT has a) proper unicode support that does not unconditionally result in errors. b) a few different registry paths.
|
||||
|
||||
static HANDLE hinput, houtput;
|
||||
|
@ -928,7 +927,7 @@ cvar_t sys_disableTaskSwitch = SCVARF("sys_disableTaskSwitch", "0", CVAR_NOTFROM
|
|||
LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
|
||||
if (ActiveApp)
|
||||
if (vid.activeapp)
|
||||
switch (nCode)
|
||||
{
|
||||
case HC_ACTION:
|
||||
|
@ -4246,7 +4245,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
sleeptime = Host_Frame (time);
|
||||
oldtime = newtime;
|
||||
|
||||
SetHookState(ActiveApp);
|
||||
SetHookState(vid.activeapp);
|
||||
|
||||
/*sleep if its not yet time for a frame*/
|
||||
if (sleeptime)
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
qboolean activeapp;
|
||||
qboolean isminimized; //can omit rendering as it won't be seen anyway.
|
||||
int fullbright; // index of first fullbright color
|
||||
|
||||
|
@ -79,6 +80,9 @@ typedef struct
|
|||
unsigned rotpixelheight; /*pixel after rotation in pixels*/
|
||||
unsigned pixelwidth; /*true height in pixels*/
|
||||
unsigned pixelheight; /*true width in pixels*/
|
||||
|
||||
float dpi_x;
|
||||
float dpi_y;
|
||||
} viddef_t;
|
||||
|
||||
extern viddef_t vid; // global video state
|
||||
|
|
|
@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include <ctype.h> // for isdigit();
|
||||
|
||||
cvar_t r_projection = CVARD("r_projection", "0", "0: regular perspective.\n1: stereographic (aka: pannini).\n2: fisheye.\n3: panoramic.\n4: lambert azimuthal equal-area.");
|
||||
cvar_t r_projection = CVARD("r_projection", "0", "0: regular perspective.\n1: stereographic (aka: pannini).\n2: fisheye.\n3: panoramic.\n4: lambert azimuthal equal-area.\n5: Equirectangular");
|
||||
cvar_t ffov = CVARFD("ffov", "", 0, "Allows you to set a specific field of view for when a custom projection is specified. If empty, will use regular fov cvar, which might get messy.");
|
||||
#if defined(_WIN32) && !defined(MINIMAL)
|
||||
//amusing gimmick / easteregg.
|
||||
|
@ -1156,7 +1156,7 @@ void V_ApplyAFov(playerview_t *pv)
|
|||
//aproximate fov is our regular fov value. explicit is settable by gamecode for weird aspect ratios
|
||||
if (!r_refdef.fov_x || !r_refdef.fov_y)
|
||||
{
|
||||
extern cvar_t r_stereo_method, r_stereo_separation;
|
||||
extern cvar_t r_stereo_separation;
|
||||
float ws;
|
||||
|
||||
float afov = r_refdef.afov;
|
||||
|
@ -1169,13 +1169,13 @@ void V_ApplyAFov(playerview_t *pv)
|
|||
afov = min(afov, 170);
|
||||
|
||||
ws = 1;
|
||||
if (r_stereo_method.ival == 5 && r_stereo_separation.value)
|
||||
if (r_refdef.stereomethod == STEREO_CROSSEYED && r_stereo_separation.value)
|
||||
ws = 0.5;
|
||||
|
||||
//attempt to retain a classic fov
|
||||
if (ws*r_refdef.vrect.width < (r_refdef.vrect.height*640)/432)
|
||||
{
|
||||
r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*r_refdef.pxrect.width)/vid.width, (r_refdef.vrect.height*r_refdef.pxrect.height)/vid.height);
|
||||
r_refdef.fov_y = CalcFov(afov, (ws*r_refdef.vrect.width*r_refdef.pxrect.width)/vid.fbvwidth, (r_refdef.vrect.height*r_refdef.pxrect.height)/vid.fbvheight);
|
||||
r_refdef.fov_x = afov;//CalcFov(r_refdef.fov_y, 432, 640);
|
||||
}
|
||||
else
|
||||
|
@ -1552,7 +1552,7 @@ static void SCR_VRectForPlayer(vrect_t *vrect, int pnum, unsigned maxseats)
|
|||
case 3:
|
||||
#ifdef GLQUAKE
|
||||
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
|
||||
&& r_projection.ival == 2 /*panoramic view always stacks player views*/
|
||||
&& r_projection.ival == PROJ_PANORAMA /*panoramic view always stacks player views*/
|
||||
)
|
||||
{ //over twice as wide as high, assume dual moniter, horizontal.
|
||||
vrect->width = vid.fbvwidth/cl.splitclients;
|
||||
|
@ -1888,7 +1888,7 @@ void R_DrawNameTags(void)
|
|||
{
|
||||
char asciibuffer[8192];
|
||||
char *entstr;
|
||||
int buflen;
|
||||
size_t buflen;
|
||||
int x, y;
|
||||
|
||||
sprintf(asciibuffer, "entity %i ", e->entnum);
|
||||
|
|
|
@ -90,7 +90,7 @@ extern BOOL (STDAPICALLTYPE *pShell_NotifyIconW)(DWORD dwMessage, PNOTIFYICONDAT
|
|||
#endif
|
||||
|
||||
extern HWND mainwindow;
|
||||
extern qboolean ActiveApp, Minimized;
|
||||
extern qboolean Minimized;
|
||||
|
||||
extern qboolean WinNT;
|
||||
|
||||
|
|
|
@ -1876,9 +1876,9 @@ typedef struct {
|
|||
qboolean allowcutdown;
|
||||
qboolean cutdown;
|
||||
char result[256];
|
||||
char *desc;
|
||||
const char *desc;
|
||||
} match_t;
|
||||
void Cmd_CompleteCheck(char *check, match_t *match, char *desc) //compare cumulative strings and join the result
|
||||
void Cmd_CompleteCheck(char *check, match_t *match, const char *desc) //compare cumulative strings and join the result
|
||||
{
|
||||
if (*match->result)
|
||||
{
|
||||
|
@ -1907,7 +1907,7 @@ void Cmd_CompleteCheck(char *check, match_t *match, char *desc) //compare cumula
|
|||
match->desc = desc;
|
||||
}
|
||||
}
|
||||
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, char **descptr)
|
||||
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr)
|
||||
{
|
||||
extern cvar_group_t *cvar_groups;
|
||||
cmd_function_t *cmd;
|
||||
|
|
|
@ -95,7 +95,7 @@ char *Cmd_AliasExist(const char *name, int restrictionlevel);
|
|||
|
||||
char *Cmd_Describe (char *cmd_name);
|
||||
|
||||
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, char **descptr);
|
||||
char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr);
|
||||
qboolean Cmd_IsCommand (char *line);
|
||||
// attempts to match a partial command for automatic command line completion
|
||||
// returns NULL if nothing fits
|
||||
|
|
|
@ -521,7 +521,7 @@ const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *sourcedat
|
|||
//a->ia->ir
|
||||
|
||||
if (bonecount > destbonecount || bonecount > MAX_BONES)
|
||||
Sys_Error("Alias_ConvertBoneData: too many bones "fPRIzu">"fPRIzu"\n", bonecount, destbonecount);
|
||||
Sys_Error("Alias_ConvertBoneData: too many bones %"PRIuSIZE">%"PRIuSIZE"\n", bonecount, destbonecount);
|
||||
|
||||
//r(->a)->ia(->ir)
|
||||
if (desttype == SKEL_INVERSE_RELATIVE && sourcetype == SKEL_RELATIVE)
|
||||
|
@ -3611,6 +3611,12 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
|
||||
if (pinstverts[i].onseam)
|
||||
{
|
||||
if (pinstverts[i].onseam != 0x20 && !galias->warned)
|
||||
{
|
||||
Con_Printf(CON_WARNING "Model %s has an invalid seam flag, which may crash software-rendered engines\n", mod->name);
|
||||
//1 == ALIAS_LEFT_CLIP
|
||||
galias->warned = true;
|
||||
}
|
||||
st_array[j][0] = st_array[i][0]+0.5;
|
||||
st_array[j][1] = st_array[i][1];
|
||||
seamremap[i] = j;
|
||||
|
@ -6613,7 +6619,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
|
|||
}
|
||||
if (h->filesize != fsize)
|
||||
{
|
||||
Con_Printf("%s: size (%u != "fPRIzu")\n", mod->name, h->filesize, fsize);
|
||||
Con_Printf("%s: size (%u != %"PRIuSIZE")\n", mod->name, h->filesize, fsize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1855,7 +1855,7 @@ void QDECL COM_StripExtension (const char *in, char *out, int outlen)
|
|||
}
|
||||
}
|
||||
|
||||
void COM_StripAllExtensions (char *in, char *out, int outlen)
|
||||
void COM_StripAllExtensions (const char *in, char *out, int outlen)
|
||||
{
|
||||
char *s;
|
||||
|
||||
|
@ -1998,7 +1998,7 @@ void COM_FileBase (const char *in, char *out, int outlen)
|
|||
COM_DefaultExtension
|
||||
==================
|
||||
*/
|
||||
void COM_DefaultExtension (char *path, char *extension, int maxlen)
|
||||
void COM_DefaultExtension (char *path, const char *extension, int maxlen)
|
||||
{
|
||||
char *src;
|
||||
//
|
||||
|
@ -2022,7 +2022,7 @@ void COM_DefaultExtension (char *path, char *extension, int maxlen)
|
|||
//adds .ext only if it isn't already present (either case).
|
||||
//extension *must* contain a leading . as this is really a requiresuffix rather than an actual extension
|
||||
//returns false if truncated. will otherwise still succeed.
|
||||
qboolean COM_RequireExtension(char *path, char *extension, int maxlen)
|
||||
qboolean COM_RequireExtension(char *path, const char *extension, int maxlen)
|
||||
{
|
||||
qboolean okay = true;
|
||||
int plen = strlen(path);
|
||||
|
|
|
@ -372,11 +372,11 @@ unsigned int unicode_charcount(const char *in, size_t buffersize, qboolean marku
|
|||
|
||||
char *COM_SkipPath (const char *pathname);
|
||||
void QDECL COM_StripExtension (const char *in, char *out, int outlen);
|
||||
void COM_StripAllExtensions (char *in, char *out, int outlen);
|
||||
void COM_StripAllExtensions (const char *in, char *out, int outlen);
|
||||
void COM_FileBase (const char *in, char *out, int outlen);
|
||||
int QDECL COM_FileSize(const char *path);
|
||||
void COM_DefaultExtension (char *path, char *extension, int maxlen);
|
||||
qboolean COM_RequireExtension(char *path, char *extension, int maxlen);
|
||||
void COM_DefaultExtension (char *path, const char *extension, int maxlen);
|
||||
qboolean COM_RequireExtension(char *path, const char *extension, int maxlen);
|
||||
char *COM_FileExtension (const char *in, char *result, size_t sizeofresult);
|
||||
void COM_CleanUpPath(char *str);
|
||||
|
||||
|
|
|
@ -1024,6 +1024,16 @@ void Cvar_SetValue (cvar_t *var, float value)
|
|||
sprintf (val, "%g",value);
|
||||
Cvar_Set (var, val);
|
||||
}
|
||||
void Cvar_ForceSetValue (cvar_t *var, float value)
|
||||
{
|
||||
char val[32];
|
||||
|
||||
// if (value == (int)value)
|
||||
// sprintf (val, "%i",(int)value); //make it look nicer.
|
||||
// else
|
||||
sprintf (val, "%g",value);
|
||||
Cvar_ForceSet (var, val);
|
||||
}
|
||||
|
||||
void Cvar_Free(cvar_t *tbf)
|
||||
{
|
||||
|
@ -1190,8 +1200,9 @@ cvar_t *Cvar_Get2(const char *name, const char *defaultvalue, int flags, const c
|
|||
var->flags = flags|CVAR_POINTER|CVAR_USERCREATED;
|
||||
if (description)
|
||||
{
|
||||
var->description = var->name+strlen(var->name)+1;
|
||||
strcpy(var->description, description);
|
||||
char *desc = var->name+strlen(var->name)+1;
|
||||
strcpy(desc, description);
|
||||
var->description = desc;
|
||||
}
|
||||
|
||||
if (!Cvar_Register(var, group))
|
||||
|
|
|
@ -70,7 +70,7 @@ typedef struct cvar_s
|
|||
char *name2;
|
||||
|
||||
void (QDECL *callback) (struct cvar_s *var, char *oldvalue);
|
||||
char *description;
|
||||
const char *description;
|
||||
char *enginevalue; //when changing manifest dir, the cvar will be reset to this value. never freed.
|
||||
char *defaultstr; //this is the current mod's default value. set on first update.
|
||||
|
||||
|
@ -164,6 +164,7 @@ cvar_t *Cvar_ForceSet (cvar_t *var, const char *value);
|
|||
cvar_t *Cvar_Set (cvar_t *var, const char *value);
|
||||
// equivelant to "<name> <variable>" typed at the console
|
||||
|
||||
void Cvar_ForceSetValue (cvar_t *var, float value);
|
||||
void Cvar_SetValue (cvar_t *var, float value);
|
||||
// expands value to a string and calls Cvar_Set
|
||||
|
||||
|
|
|
@ -4672,13 +4672,24 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
|
|||
|
||||
#ifdef ANDROID
|
||||
{
|
||||
//write a .nomedia file to avoid people from getting random explosion sounds etc interspersed with their music
|
||||
vfsfile_t *f;
|
||||
//write a .nomedia file to avoid people from getting random explosion sounds etc intersperced with their music
|
||||
f = FS_OpenVFS(".nomedia", "rb", FS_ROOT);
|
||||
char nomedia[MAX_OSPATH];
|
||||
//figure out the path we're going to end up writing to
|
||||
if (com_homepathenabled)
|
||||
snprintf(nomedia, sizeof(nomedia), "%s%s", com_homepath, ".nomedia");
|
||||
else
|
||||
snprintf(nomedia, sizeof(nomedia), "%s%s", com_gamepath, ".nomedia");
|
||||
|
||||
//make sure it exists.
|
||||
f = VFSOS_Open(nomedia, "rb");
|
||||
if (!f) //don't truncate
|
||||
{
|
||||
COM_CreatePath(nomedia);
|
||||
f = VFSOS_Open(nomedia, "wb");
|
||||
}
|
||||
if (f)
|
||||
VFS_CLOSE(f);
|
||||
else
|
||||
FS_WriteFile(".nomedia", NULL, 0, FS_ROOT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3399,12 +3399,12 @@ handshakeerror:
|
|||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+7]<< 0ull;
|
||||
if (ullpaylen < 0x10000)
|
||||
{
|
||||
Con_Printf ("%s: payload size ("fPRIllu") encoded badly\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), ullpaylen);
|
||||
Con_Printf ("%s: payload size (%"PRIu64") encoded badly\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), ullpaylen);
|
||||
goto closesvstream;
|
||||
}
|
||||
if (ullpaylen > 0x10000)
|
||||
{
|
||||
Con_Printf ("%s: payload size ("fPRIllu") is abusive\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), ullpaylen);
|
||||
Con_Printf ("%s: payload size (%"PRIu64") is abusive\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), ullpaylen);
|
||||
goto closesvstream;
|
||||
}
|
||||
paylen = ullpaylen;
|
||||
|
|
|
@ -722,6 +722,7 @@ enum csqc_input_event
|
|||
CSIE_ACCELEROMETER = 4, /*x, y, z*/
|
||||
CSIE_FOCUS = 5, /*mouse, key, devid. if has, the game window has focus. (true/false/-1)*/
|
||||
CSIE_JOYAXIS = 6, /*axis, value, devid*/
|
||||
CSIE_GYROSCOPE = 7, /*x, y, z rotational acceleration*/
|
||||
};
|
||||
|
||||
#ifdef TERRAIN
|
||||
|
|
|
@ -441,6 +441,13 @@ enum clcq2_ops_e
|
|||
|
||||
//==============================================
|
||||
|
||||
#define DLERR_FILENOTFOUND -1 //server cannot serve the file
|
||||
#define DLERR_PERMISSIONS -2 //server refuses to serve the file
|
||||
#define DLERR_UNKNOWN -3 //server bugged out while trying to serve the request
|
||||
#define DLERR_REDIRECTFILE -4 //client should download the specified file instead.
|
||||
#define DLERR_REDIRECTPACK -5 //client should download the specified package instead.
|
||||
#define DLERR_PACKAGE -6 //not networked. packages require special file access.
|
||||
|
||||
//these flags are sent as part of the svc_precache index, for any-time precaches. using the upper two bits means we still have 16k available models/sounds/etc
|
||||
#define PC_TYPE 0xc000
|
||||
#define PC_MODEL 0x0000
|
||||
|
|
|
@ -127,12 +127,12 @@ qboolean Sys_ConditionSignal(void *condv); //lock first
|
|||
qboolean Sys_ConditionBroadcast(void *condv); //lock first
|
||||
void Sys_DestroyConditional(void *condv);
|
||||
#else
|
||||
#define Sys_IsMainThread() true
|
||||
#define Sys_CreateMutex() NULL
|
||||
#define Sys_LockMutex(m) true
|
||||
#define Sys_UnlockMutex(m) true
|
||||
#define Sys_IsMainThread() (true)
|
||||
#define Sys_CreateMutex() (NULL)
|
||||
#define Sys_LockMutex(m) (true)
|
||||
#define Sys_UnlockMutex(m) (true)
|
||||
#define Sys_DestroyMutex(m)
|
||||
#define Sys_IsThread(t) !t
|
||||
#define Sys_IsThread(t) (!t)
|
||||
#endif
|
||||
|
||||
void Sys_Sleep(double seconds);
|
||||
|
|
|
@ -94,6 +94,9 @@ void TL_InitLanguages(char *newlangpath)
|
|||
int i;
|
||||
char *lang;
|
||||
|
||||
if (!newlangpath)
|
||||
newlangpath = "";
|
||||
|
||||
Q_strncpyz(langpath, newlangpath, sizeof(langpath));
|
||||
|
||||
//lang can override any environment or system settings.
|
||||
|
|
|
@ -198,25 +198,25 @@ static qboolean D3D9AppActivate(BOOL fActive, BOOL minimize)
|
|||
{
|
||||
static BOOL sound_active;
|
||||
|
||||
if (ActiveApp == fActive && Minimized == minimize)
|
||||
if (vid.activeapp == fActive && Minimized == minimize)
|
||||
return false; //so windows doesn't crash us over and over again.
|
||||
|
||||
ActiveApp = fActive;
|
||||
vid.activeapp = fActive;
|
||||
Minimized = minimize;
|
||||
|
||||
// enable/disable sound on focus gain/loss
|
||||
if (!ActiveApp && sound_active)
|
||||
if (!vid.activeapp && sound_active)
|
||||
{
|
||||
S_BlockSound ();
|
||||
sound_active = false;
|
||||
}
|
||||
else if (ActiveApp && !sound_active)
|
||||
else if (vid.activeapp && !sound_active)
|
||||
{
|
||||
S_UnblockSound ();
|
||||
sound_active = true;
|
||||
}
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
|
||||
if (fActive)
|
||||
{
|
||||
|
@ -1094,7 +1094,7 @@ static void (D3D9_SCR_UpdateScreen) (void)
|
|||
window_center_y = (window_rect.top + window_rect.bottom)/2;
|
||||
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -261,25 +261,25 @@ static qboolean D3D11AppActivate(BOOL fActive, BOOL minimize)
|
|||
{
|
||||
static BOOL sound_active;
|
||||
|
||||
if (ActiveApp == fActive && Minimized == minimize)
|
||||
if (vid.activeapp == fActive && Minimized == minimize)
|
||||
return false; //so windows doesn't crash us over and over again.
|
||||
|
||||
ActiveApp = fActive;
|
||||
vid.activeapp = fActive;
|
||||
Minimized = minimize;
|
||||
|
||||
// enable/disable sound on focus gain/loss
|
||||
if (!ActiveApp && sound_active)
|
||||
if (!vid.activeapp && sound_active)
|
||||
{
|
||||
S_BlockSound ();
|
||||
sound_active = false;
|
||||
}
|
||||
else if (ActiveApp && !sound_active)
|
||||
else if (vid.activeapp && !sound_active)
|
||||
{
|
||||
S_UnblockSound ();
|
||||
sound_active = true;
|
||||
}
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ static LRESULT WINAPI D3D11_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
|
|||
|
||||
if (modestate == MS_FULLSCREEN)
|
||||
{
|
||||
IDXGISwapChain_SetFullscreenState(d3dswapchain, ActiveApp, d3dscreen);
|
||||
IDXGISwapChain_SetFullscreenState(d3dswapchain, vid.activeapp, d3dscreen);
|
||||
D3D11_DoResize();
|
||||
}
|
||||
Cvar_ForceCallback(&v_gamma);
|
||||
|
@ -1356,7 +1356,7 @@ static void (D3D11_SCR_UpdateScreen) (void)
|
|||
window_center_y = (window_rect.top + window_rect.bottom)/2;
|
||||
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -348,7 +348,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include,../d3d,../d3d9,../libs/dxsdk9/include"
|
||||
PreprocessorDefinitions="_DEBUG;D3DQUAKE;WIN32;_WINDOWS;MULTITHREAD"
|
||||
PreprocessorDefinitions="_DEBUG;D3D9QUAKE;D3D11QUAKE;WIN32;_WINDOWS;MULTITHREAD"
|
||||
RuntimeLibrary="1"
|
||||
EnableFunctionLevelLinking="true"
|
||||
FloatingPointModel="2"
|
||||
|
@ -663,7 +663,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include"
|
||||
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;MULTITHREAD;BOTLIB_STATIC;USE_MSVCRT_DEBUG"
|
||||
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;BOTLIB_STATIC;USE_MSVCRT_DEBUG"
|
||||
BasicRuntimeChecks="3"
|
||||
SmallerTypeCheck="true"
|
||||
RuntimeLibrary="1"
|
||||
|
@ -1179,7 +1179,7 @@
|
|||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include,../d3d,../d3d9,../libs/dxsdk9/include"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE;MULTITHREAD"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;GLQUAKE;D3D9QUAKE;D3D11QUAKE;MULTITHREAD"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
|
@ -1586,7 +1586,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include,../d3d,../d3d9,../libs/dxsdk9/include"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE;SWQUAKE;MULTITHREAD"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;D3D9QUAKE;D3D11QUAKE;SWQUAKE;MULTITHREAD"
|
||||
RuntimeLibrary="1"
|
||||
FloatingPointModel="2"
|
||||
UsePrecompiledHeader="2"
|
||||
|
|
|
@ -37,10 +37,184 @@ public class FTEDroidActivity extends Activity
|
|||
{
|
||||
private SensorManager sensorman;
|
||||
private Sensor sensoracc;
|
||||
private Sensor sensorgyro;
|
||||
private FTEView view;
|
||||
float acc_x, acc_y, acc_z; /*might be some minor race condition on these*/
|
||||
float gyro_x, gyro_y, gyro_z; /*might be some minor race condition on these*/
|
||||
private String basedir, userdir;
|
||||
|
||||
|
||||
private audiothreadclass audiothread;
|
||||
private class audiothreadclass extends Thread
|
||||
{
|
||||
boolean timetodie;
|
||||
int schannels;
|
||||
int sspeed;
|
||||
int sbits;
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
byte[] audbuf = new byte[2048];
|
||||
int avail;
|
||||
AudioTrack at;
|
||||
|
||||
int chans;
|
||||
try
|
||||
{
|
||||
if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+
|
||||
chans = AudioFormat.CHANNEL_OUT_7POINT1;
|
||||
else if (schannels >= 6)
|
||||
chans = AudioFormat.CHANNEL_OUT_5POINT1;
|
||||
else if (schannels >= 4)
|
||||
chans = AudioFormat.CHANNEL_OUT_QUAD;
|
||||
else if (schannels >= 2)
|
||||
chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
|
||||
else
|
||||
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||
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)
|
||||
// sz = sspeed * 0.05;
|
||||
|
||||
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.play();
|
||||
|
||||
while(!timetodie)
|
||||
{
|
||||
avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
|
||||
at.write(audbuf, 0, avail);
|
||||
}
|
||||
|
||||
at.stop();
|
||||
}
|
||||
public void killoff()
|
||||
{
|
||||
timetodie = true;
|
||||
try
|
||||
{
|
||||
join();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
}
|
||||
timetodie = false;
|
||||
}
|
||||
};
|
||||
private void audioInit(int sspeed, int schannels, int sbits)
|
||||
{
|
||||
if (audiothread == null)
|
||||
{
|
||||
audiothread = new audiothreadclass();
|
||||
audiothread.schannels = schannels;
|
||||
audiothread.sspeed = sspeed;
|
||||
audiothread.sbits = sbits;
|
||||
audiothread.start();
|
||||
}
|
||||
}
|
||||
public void audioStop()
|
||||
{
|
||||
if (audiothread != null)
|
||||
{
|
||||
audiothread.killoff();
|
||||
audiothread = null;
|
||||
}
|
||||
}
|
||||
public void audioResume()
|
||||
{
|
||||
if (audiothread != null)
|
||||
{
|
||||
audiothread.killoff();
|
||||
audiothread.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class FTEMultiTouchInputEvent extends FTELegacyInputEvent
|
||||
{
|
||||
/*Requires API level 5+ (android 2.0+)*/
|
||||
private void domove(MotionEvent event)
|
||||
{
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int i;
|
||||
for (i = 0; i < pointerCount; i++)
|
||||
FTEDroidEngine.motion(0, event.getPointerId(i), event.getX(i), event.getY(i), event.getSize(i));
|
||||
}
|
||||
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
int id;
|
||||
float x, y, size;
|
||||
final int act = event.getAction();
|
||||
|
||||
domove(event);
|
||||
|
||||
switch(act & event.ACTION_MASK)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
size = event.getSize(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(1, id, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
size = event.getSize(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(2, id, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class FTELegacyInputEvent
|
||||
{
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
final int act = event.getAction();
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final float size = event.getSize();
|
||||
|
||||
FTEDroidEngine.motion(0, 0, x, y, size);
|
||||
|
||||
switch(act)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
FTEDroidEngine.motion(1, 0, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
FTEDroidEngine.motion(2, 0, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FTEEGLConfig implements GLSurfaceView.EGLConfigChooser
|
||||
{
|
||||
int version;
|
||||
|
@ -176,8 +350,11 @@ public class FTEDroidActivity extends Activity
|
|||
act = parent;
|
||||
theview = view;
|
||||
|
||||
FTEDroidEngine.init(0, 0, 0, basedir, userdir);
|
||||
inited = true;
|
||||
if (!inited)
|
||||
{
|
||||
FTEDroidEngine.init(0, 0, 0, 0, 0, basedir, userdir);
|
||||
inited = true;
|
||||
}
|
||||
|
||||
cfgchooser = new FTEEGLConfig();
|
||||
// theview.setEGLConfigChooser(cfgchooser);
|
||||
|
@ -190,7 +367,7 @@ public class FTEDroidActivity extends Activity
|
|||
if (inited == true)
|
||||
{
|
||||
int flags;
|
||||
flags = FTEDroidEngine.frame(act.acc_x, act.acc_y, act.acc_z);
|
||||
flags = FTEDroidEngine.frame(act.acc_x, act.acc_y, act.acc_z, act.gyro_x, act.gyro_y, act.gyro_z);
|
||||
if (flags != notifiedflags)
|
||||
{
|
||||
if (((flags ^ notifiedflags) & 1) != 0)
|
||||
|
@ -254,7 +431,7 @@ public class FTEDroidActivity extends Activity
|
|||
|
||||
inited = false;
|
||||
|
||||
if (errormsg == "")
|
||||
if (errormsg.equals(""))
|
||||
{
|
||||
finish();
|
||||
System.exit(0);
|
||||
|
@ -287,7 +464,7 @@ public class FTEDroidActivity extends Activity
|
|||
if (((flags ^ notifiedflags) & 16) != 0)
|
||||
{
|
||||
//16 means orientation cvar change
|
||||
Runnable r = new Runnable()
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
|
@ -323,13 +500,44 @@ public class FTEDroidActivity extends Activity
|
|||
}
|
||||
};
|
||||
act.runOnUiThread(r);
|
||||
|
||||
//fixme: move to proper vid_restart thing.
|
||||
int wantver = FTEDroidEngine.getpreferedglesversion();
|
||||
if (wantver != 0 && this.glesversion != 0 && wantver != this.glesversion)
|
||||
{
|
||||
inited = false;
|
||||
wantver = FTEDroidEngine.getpreferedglesversion();
|
||||
android.util.Log.i("FTEDroid", "Killing old gl state");
|
||||
FTEDroidEngine.killglcontext();
|
||||
android.util.Log.i("FTEDroid", "old gl state killed, queueing context kill");
|
||||
r = new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "Attempting to restart view");
|
||||
//create a new view and use that, because the desired gl context version might have changed
|
||||
view = new FTEView(act);
|
||||
setContentView(view);
|
||||
}
|
||||
};
|
||||
act.runOnUiThread(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (((flags ^ notifiedflags) & 32) != 0)
|
||||
{
|
||||
if ((flags & 32) != 0)
|
||||
view.audioInit(FTEDroidEngine.audioinfo(0), FTEDroidEngine.audioinfo(1), FTEDroidEngine.audioinfo(2));
|
||||
else
|
||||
view.audioStop();
|
||||
final int fl = flags;
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if ((fl & 32) != 0)
|
||||
act.audioInit(FTEDroidEngine.audioinfo(0), FTEDroidEngine.audioinfo(1), FTEDroidEngine.audioinfo(2));
|
||||
else
|
||||
act.audioStop();
|
||||
}
|
||||
};
|
||||
act.runOnUiThread(r);
|
||||
}
|
||||
|
||||
//clear anything which is an impulse
|
||||
|
@ -341,10 +549,12 @@ public class FTEDroidActivity extends Activity
|
|||
public void onSurfaceChanged(GL10 gl, int width, int height)
|
||||
{
|
||||
android.util.Log.i("FTEDroid", "Surface changed, now " + width + " by " + height + ".");
|
||||
if (glesversion != 0)
|
||||
if (glesversion != 0 && inited)
|
||||
{
|
||||
FTEDroidEngine.init(width, height, glesversion, basedir, userdir);
|
||||
inited = true;
|
||||
android.util.DisplayMetrics metrics = new android.util.DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
FTEDroidEngine.init(width, height, metrics.xdpi, metrics.ydpi, glesversion, basedir, userdir);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
|
@ -357,101 +567,6 @@ public class FTEDroidActivity extends Activity
|
|||
private class FTEView extends GLSurfaceView implements SensorEventListener
|
||||
{
|
||||
private final FTERenderer rndr;
|
||||
|
||||
private audiothreadclass audiothread;
|
||||
private class audiothreadclass extends Thread
|
||||
{
|
||||
boolean timetodie;
|
||||
int schannels;
|
||||
int sspeed;
|
||||
int sbits;
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
byte[] audbuf = new byte[2048];
|
||||
int avail;
|
||||
AudioTrack at;
|
||||
|
||||
int chans;
|
||||
try
|
||||
{
|
||||
if (schannels >= 8) //the OUT enumeration allows specific speaker control. but also api level 5+
|
||||
chans = AudioFormat.CHANNEL_OUT_7POINT1;
|
||||
else if (schannels >= 6)
|
||||
chans = AudioFormat.CHANNEL_OUT_5POINT1;
|
||||
else if (schannels >= 4)
|
||||
chans = AudioFormat.CHANNEL_OUT_QUAD;
|
||||
else if (schannels >= 2)
|
||||
chans = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
|
||||
else
|
||||
chans = AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||
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)
|
||||
// sz = sspeed * 0.05;
|
||||
|
||||
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.play();
|
||||
|
||||
while(!timetodie)
|
||||
{
|
||||
avail = FTEDroidEngine.paintaudio(audbuf, audbuf.length);
|
||||
at.write(audbuf, 0, avail);
|
||||
}
|
||||
|
||||
at.stop();
|
||||
}
|
||||
public void killoff()
|
||||
{
|
||||
timetodie = true;
|
||||
try
|
||||
{
|
||||
join();
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
}
|
||||
timetodie = false;
|
||||
}
|
||||
};
|
||||
|
||||
private void audioInit(int sspeed, int schannels, int sbits)
|
||||
{
|
||||
if (audiothread == null)
|
||||
{
|
||||
audiothread = new audiothreadclass();
|
||||
audiothread.schannels = schannels;
|
||||
audiothread.sspeed = sspeed;
|
||||
audiothread.sbits = sbits;
|
||||
audiothread.start();
|
||||
}
|
||||
}
|
||||
public void audioStop()
|
||||
{
|
||||
if (audiothread != null)
|
||||
{
|
||||
audiothread.killoff();
|
||||
audiothread = null;
|
||||
}
|
||||
}
|
||||
public void audioResume()
|
||||
{
|
||||
if (audiothread != null)
|
||||
{
|
||||
audiothread.killoff();
|
||||
audiothread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/* private FTEJoystickInputEvent joystickevent;
|
||||
class FTEJoystickInputEvent
|
||||
|
@ -479,80 +594,6 @@ public class FTEDroidActivity extends Activity
|
|||
}
|
||||
*/
|
||||
private FTELegacyInputEvent inputevent;
|
||||
class FTEMultiTouchInputEvent extends FTELegacyInputEvent
|
||||
{
|
||||
/*Requires API level 5+ (android 2.0+)*/
|
||||
private void domove(MotionEvent event)
|
||||
{
|
||||
final int pointerCount = event.getPointerCount();
|
||||
int i;
|
||||
for (i = 0; i < pointerCount; i++)
|
||||
FTEDroidEngine.motion(0, event.getPointerId(i), event.getX(i), event.getY(i), event.getSize(i));
|
||||
}
|
||||
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
int id;
|
||||
float x, y, size;
|
||||
final int act = event.getAction();
|
||||
|
||||
domove(event);
|
||||
|
||||
switch(act & event.ACTION_MASK)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
size = event.getSize(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(1, id, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
id = ((act&event.ACTION_POINTER_ID_MASK) >> event.ACTION_POINTER_ID_SHIFT);
|
||||
x = event.getX(id);
|
||||
y = event.getY(id);
|
||||
size = event.getSize(id);
|
||||
id = event.getPointerId(id);
|
||||
FTEDroidEngine.motion(2, id, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class FTELegacyInputEvent
|
||||
{
|
||||
public boolean go(MotionEvent event)
|
||||
{
|
||||
final int act = event.getAction();
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
final float size = event.getSize();
|
||||
|
||||
FTEDroidEngine.motion(0, 0, x, y, size);
|
||||
|
||||
switch(act)
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
FTEDroidEngine.motion(1, 0, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
FTEDroidEngine.motion(2, 0, x, y, size);
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public FTEView(FTEDroidActivity context)
|
||||
{
|
||||
|
@ -713,9 +754,18 @@ public class FTEDroidActivity extends Activity
|
|||
|
||||
public void onSensorChanged(final SensorEvent event)
|
||||
{
|
||||
acc_x = event.values[0];
|
||||
acc_y = event.values[1];
|
||||
acc_z = event.values[2];
|
||||
if (event.sensor == sensoracc)
|
||||
{
|
||||
acc_x = event.values[0];
|
||||
acc_y = event.values[1];
|
||||
acc_z = event.values[2];
|
||||
}
|
||||
else if (event.sensor == sensorgyro)
|
||||
{
|
||||
gyro_x = event.values[0];
|
||||
gyro_y = event.values[1];
|
||||
gyro_z = event.values[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -776,6 +826,8 @@ public class FTEDroidActivity extends Activity
|
|||
{
|
||||
android.util.Log.i("FTEDroid", "init accelerometer");
|
||||
sensoracc = sensorman.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
android.util.Log.i("FTEDroid", "init gyro");
|
||||
sensorgyro = sensorman.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
||||
}
|
||||
android.util.Log.i("FTEDroid", "done");
|
||||
}
|
||||
|
@ -786,8 +838,10 @@ public class FTEDroidActivity extends Activity
|
|||
super.onResume();
|
||||
if (sensorman != null && sensoracc != null)
|
||||
sensorman.registerListener((SensorEventListener)view, sensoracc, SensorManager.SENSOR_DELAY_GAME);
|
||||
if (sensorman != null && sensorgyro != null)
|
||||
sensorman.registerListener((SensorEventListener)view, sensorgyro, SensorManager.SENSOR_DELAY_GAME);
|
||||
|
||||
view.audioResume();
|
||||
audioResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -822,18 +876,18 @@ public class FTEDroidActivity extends Activity
|
|||
@Override
|
||||
protected void onStop()
|
||||
{
|
||||
if (sensorman != null && sensoracc != null)
|
||||
if (sensorman != null && (sensoracc != null || sensorgyro != null))
|
||||
sensorman.unregisterListener(view);
|
||||
view.audioStop();
|
||||
audioStop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
if (sensorman != null && sensoracc != null)
|
||||
if (sensorman != null && (sensoracc != null || sensorgyro != null))
|
||||
sensorman.unregisterListener(view);
|
||||
view.audioStop();
|
||||
audioStop();
|
||||
super.onPause();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.fteqw;
|
|||
|
||||
public class FTEDroidEngine
|
||||
{
|
||||
public static native void init(int w, int h, int gles2, String apkpath, String usrpath); /* init/reinit */
|
||||
public static native int frame(float ax, float ay, float az);
|
||||
public static native void init(int w, int h, float dpix, float dpiy, int gles2, String apkpath, String usrpath); /* init/reinit */
|
||||
public static native int frame(float ax, float ay, float az, float gx, float gy, float gz);
|
||||
public static native int openfile(String filename);
|
||||
public static native int getvibrateduration(); //in ms
|
||||
public static native int keypress(int down, int qkey, int unicode);
|
||||
|
@ -13,6 +13,7 @@ public class FTEDroidEngine
|
|||
public static native String geterrormessage();
|
||||
public static native String getpreferedorientation();
|
||||
public static native int getpreferedglesversion();
|
||||
public static native void killglcontext();
|
||||
public static native void newglcontext();
|
||||
|
||||
static
|
||||
|
|
|
@ -402,10 +402,33 @@ void R_SetupGL (float stereooffset)
|
|||
|
||||
if (!r_refdef.recurse)
|
||||
{
|
||||
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
|
||||
VectorCopy (r_refdef.vieworg, r_origin);
|
||||
newa[0] = r_refdef.viewangles[0];
|
||||
newa[1] = r_refdef.viewangles[1];
|
||||
newa[2] = r_refdef.viewangles[2] + gl_screenangle.value;
|
||||
if (1)
|
||||
{
|
||||
vec3_t paxis[3];
|
||||
AngleVectors (newa, paxis[0], paxis[1], paxis[2]);
|
||||
|
||||
VectorMA(r_origin, stereooffset, vright, r_origin);
|
||||
//R_ConcatRotations(r_refdef.headaxis, paxis, vpn);
|
||||
|
||||
VectorMA(vec3_origin, r_refdef.headaxis[0][0], paxis[0], vpn);
|
||||
VectorMA(vpn, r_refdef.headaxis[0][1], paxis[1], vpn);
|
||||
VectorMA(vpn, r_refdef.headaxis[0][2], paxis[2], vpn);
|
||||
|
||||
VectorMA(vec3_origin, r_refdef.headaxis[1][0], paxis[0], vright);
|
||||
VectorMA(vright, r_refdef.headaxis[1][1], paxis[1], vright);
|
||||
VectorMA(vright, r_refdef.headaxis[1][2], paxis[2], vright);
|
||||
|
||||
VectorMA(vec3_origin, r_refdef.headaxis[2][0], paxis[0], vup);
|
||||
VectorMA(vup, r_refdef.headaxis[2][1], paxis[1], vup);
|
||||
VectorMA(vup, r_refdef.headaxis[2][2], paxis[2], vup);
|
||||
}
|
||||
else
|
||||
AngleVectors (newa, vpn, vright, vup);
|
||||
|
||||
VectorMA(r_refdef.vieworg, stereooffset, vright, r_origin);
|
||||
VectorAdd(r_origin, r_refdef.eyeoffset, r_origin);
|
||||
|
||||
//
|
||||
// set up viewpoint
|
||||
|
@ -457,10 +480,10 @@ void R_SetupGL (float stereooffset)
|
|||
w = x2 - x;
|
||||
h = y2 - y;
|
||||
|
||||
if (stereooffset && r_stereo_method.ival == 5)
|
||||
if (stereooffset && r_refdef.stereomethod == STEREO_CROSSEYED)
|
||||
{
|
||||
w /= 2;
|
||||
if (stereooffset > 0)
|
||||
if (stereooffset < 0)
|
||||
x += vid.fbpwidth/2;
|
||||
}
|
||||
|
||||
|
@ -511,10 +534,7 @@ void R_SetupGL (float stereooffset)
|
|||
Matrix4x4_CM_Orthographic(r_refdef.m_projection, -fov_x/2, fov_x/2, -fov_y/2, fov_y/2, gl_mindist.value, gl_maxdist.value>=1?gl_maxdist.value:9999);
|
||||
}
|
||||
|
||||
newa[0] = r_refdef.viewangles[0];
|
||||
newa[1] = r_refdef.viewangles[1];
|
||||
newa[2] = r_refdef.viewangles[2] + gl_screenangle.value;
|
||||
Matrix4x4_CM_ModelViewMatrix(r_refdef.m_view, newa, r_origin);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_origin);
|
||||
}
|
||||
|
||||
if (qglLoadMatrixf)
|
||||
|
@ -584,15 +604,15 @@ void R_RenderScene (void)
|
|||
int tmpvisents = cl_numvisedicts; /*world rendering is allowed to add additional ents, but we don't want to keep them for recursive views*/
|
||||
int cull = r_refdef.flipcull;
|
||||
|
||||
stereomode = r_stereo_method.ival;
|
||||
if (stereomode == 1)
|
||||
stereomode = r_refdef.stereomethod;
|
||||
if (stereomode == STEREO_QUAD)
|
||||
{
|
||||
#ifdef GL_STEREO
|
||||
GLint glb;
|
||||
qglGetIntegerv(GL_STEREO, &glb);
|
||||
if (!glb || !qglDrawBuffer)
|
||||
#endif
|
||||
stereomode = 0; //we are not a stereo context, so no stereoscopic rendering (this encourages it to otherwise be left enabled, which means the user is more likely to spot that they asked it to give a slower context.
|
||||
stereomode = STEREO_OFF; //we are not a stereo context, so no stereoscopic rendering (this encourages it to otherwise be left enabled, which means the user is more likely to spot that they asked it to give a slower context.
|
||||
}
|
||||
|
||||
|
||||
|
@ -600,12 +620,12 @@ void R_RenderScene (void)
|
|||
{
|
||||
stereooffset[0] = 0;
|
||||
stereoframes = 1;
|
||||
stereomode = 0;
|
||||
stereomode = STEREO_OFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
stereooffset[0] = -r_stereo_separation.value;
|
||||
stereooffset[1] = r_stereo_separation.value;
|
||||
stereooffset[0] = -0.5*r_stereo_separation.value;
|
||||
stereooffset[1] = +0.5*r_stereo_separation.value;
|
||||
stereoframes = 2;
|
||||
}
|
||||
|
||||
|
@ -614,37 +634,46 @@ void R_RenderScene (void)
|
|||
switch (stereomode)
|
||||
{
|
||||
default:
|
||||
case 0: //off
|
||||
case STEREO_OFF: //off
|
||||
if (i)
|
||||
return;
|
||||
break;
|
||||
#ifdef GL_STEREO
|
||||
case 1: //proper gl stereo rendering
|
||||
case STEREO_QUAD: //proper gl stereo rendering
|
||||
if (stereooffset[i] < 0)
|
||||
qglDrawBuffer(GL_BACK_LEFT);
|
||||
else
|
||||
qglDrawBuffer(GL_BACK_RIGHT);
|
||||
break;
|
||||
#endif
|
||||
case 2: //red/cyan(green+blue)
|
||||
case STEREO_RED_CYAN: //red/cyan(green+blue)
|
||||
if (stereooffset[i] < 0)
|
||||
qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
else
|
||||
qglColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
break;
|
||||
case 3: //red/blue
|
||||
case STEREO_RED_BLUE: //red/blue
|
||||
if (stereooffset[i] < 0)
|
||||
qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
else
|
||||
qglColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
|
||||
break;
|
||||
case 4: //red/green
|
||||
case STEREO_RED_GREEN: //red/green
|
||||
if (stereooffset[i] < 0)
|
||||
qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
else
|
||||
qglColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
|
||||
break;
|
||||
case 5: //eyestrain
|
||||
case STEREO_CROSSEYED: //eyestrain
|
||||
break;
|
||||
case STEREO_LEFTONLY:
|
||||
if (i != 0)
|
||||
continue;
|
||||
break;
|
||||
case STEREO_RIGHTONLY:
|
||||
if (i != 1)
|
||||
continue;
|
||||
//fixme: depth buffer doesn't need clearing
|
||||
break;
|
||||
}
|
||||
if (i)
|
||||
|
@ -683,21 +712,16 @@ void R_RenderScene (void)
|
|||
switch (stereomode)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
case STEREO_OFF:
|
||||
case STEREO_LEFTONLY:
|
||||
case STEREO_RIGHTONLY:
|
||||
break;
|
||||
case 1:
|
||||
case STEREO_QUAD:
|
||||
qglDrawBuffer(GL_BACK);
|
||||
break;
|
||||
case 3:
|
||||
qglColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
qglClear(GL_COLOR_BUFFER_BIT);
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
break;
|
||||
case 4:
|
||||
qglColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
|
||||
qglClear(GL_COLOR_BUFFER_BIT);
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
case 2:
|
||||
case STEREO_RED_BLUE: //green should have already been cleared.
|
||||
case STEREO_RED_GREEN: //blue should have already been cleared.
|
||||
case STEREO_RED_CYAN:
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
break;
|
||||
case 5:
|
||||
|
@ -1397,6 +1421,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
{90, 0, 0}, {-90, 0, 0},
|
||||
{0, 0, 0}, {0, -180, 0} };
|
||||
vec3_t saveang;
|
||||
vec3_t saveorg;
|
||||
|
||||
vrect_t vrect;
|
||||
pxrect_t prect;
|
||||
|
@ -1408,6 +1433,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
qboolean usefbo = true; //this appears to be a 20% speedup in my tests.
|
||||
static fbostate_t fbostate; //FIXME
|
||||
qboolean fboreset = false;
|
||||
int osm = r_refdef.stereomethod;
|
||||
|
||||
/*needs glsl*/
|
||||
if (!gl_config.arb_shader_objects)
|
||||
|
@ -1423,7 +1449,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
{
|
||||
default: //invalid.
|
||||
return false;
|
||||
case 1:
|
||||
case PROJ_STEREOGRAPHIC:
|
||||
shader = R_RegisterShader("postproc_stereographic", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_stereographic\n"
|
||||
|
@ -1443,7 +1469,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case PROJ_FISHEYE:
|
||||
shader = R_RegisterShader("postproc_fisheye", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_fisheye\n"
|
||||
|
@ -1460,7 +1486,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
if (ffov.value > 270)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
break;
|
||||
case 3:
|
||||
case PROJ_PANORAMA:
|
||||
shader = R_RegisterShader("postproc_panorama", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_panorama\n"
|
||||
|
@ -1480,7 +1506,7 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
}
|
||||
facemask = 0x3f;
|
||||
break;
|
||||
case 4:
|
||||
case PROJ_LAEA:
|
||||
shader = R_RegisterShader("postproc_laea", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_laea\n"
|
||||
|
@ -1498,6 +1524,28 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
break;
|
||||
|
||||
case PROJ_EQUIRECTANGULAR:
|
||||
shader = R_RegisterShader("postproc_equirectangular", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_equirectangular\n"
|
||||
"{\n"
|
||||
"map $sourcecube\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
facemask = 0x3f;
|
||||
#if 0
|
||||
facemask |= 1<<4; /*front view*/
|
||||
if (ffov.value > 90)
|
||||
{
|
||||
facemask |= (1<<0) | (1<<1) | (1<<2) | (1<<3); /*side/top/bottom views*/
|
||||
if (ffov.value > 270)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
//FIXME: we should be able to rotate the view
|
||||
|
@ -1536,9 +1584,12 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
|
||||
//FIXME: gl_max_size
|
||||
|
||||
VectorCopy(r_refdef.vieworg, saveorg);
|
||||
VectorCopy(r_refdef.viewangles, saveang);
|
||||
saveang[2] = 0;
|
||||
|
||||
r_refdef.stereomethod = STEREO_OFF;
|
||||
|
||||
if (!TEXVALID(scenepp_postproc_cube) || cmapsize != scenepp_postproc_cube_size)
|
||||
{
|
||||
if (!TEXVALID(scenepp_postproc_cube))
|
||||
|
@ -1626,6 +1677,8 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
|
||||
r_refdef.vrect = vrect;
|
||||
r_refdef.pxrect = prect;
|
||||
VectorCopy(saveorg, r_refdef.vieworg);
|
||||
r_refdef.stereomethod = osm;
|
||||
|
||||
//GL_ViewportUpdate();
|
||||
GL_Set2D(false);
|
||||
|
@ -1639,7 +1692,12 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
qglLoadIdentity ();
|
||||
*/
|
||||
// draw it through the shader
|
||||
if (r_projection.ival == 3)
|
||||
if (r_projection.ival == PROJ_EQUIRECTANGULAR)
|
||||
{
|
||||
//note vr screenshots have requirements here
|
||||
R2D_Image(vrect.x, vrect.y, vrect.width, vrect.height, 0, 1, 1, 0, shader);
|
||||
}
|
||||
else if (r_projection.ival == PROJ_PANORAMA)
|
||||
{
|
||||
float saspect = .5;
|
||||
float taspect = vrect.height / vrect.width * ffov.value / 90;//(0.5 * vrect.width) / vrect.height;
|
||||
|
|
|
@ -21,6 +21,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "glquake.h"
|
||||
|
||||
extern int sys_glesversion;
|
||||
extern float sys_dpi_x;
|
||||
extern float sys_dpi_y;
|
||||
|
||||
static dllhandle_t *sys_gl_module = NULL;
|
||||
|
||||
|
@ -77,6 +79,11 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
return false;
|
||||
}
|
||||
|
||||
vid.dpi_x = sys_dpi_x;
|
||||
vid.dpi_y = sys_dpi_y;
|
||||
|
||||
vid.activeapp = true;
|
||||
|
||||
GL_Init(GLES_GetSymbol);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -513,7 +513,6 @@ static qboolean XI2_Init(void)
|
|||
|
||||
//qboolean is8bit = false;
|
||||
//qboolean isPermedia = false;
|
||||
qboolean ActiveApp = false;
|
||||
extern qboolean sys_gracefulexit;
|
||||
|
||||
#define SYS_CLIPBOARD_SIZE 512
|
||||
|
@ -1099,7 +1098,7 @@ static void GetEvent(void)
|
|||
/*
|
||||
if (fullscreenflags & FULLSCREEN_LEGACY)
|
||||
if (fullscreenflags & FULLSCREEN_VMODE)
|
||||
if (!ActiveApp)
|
||||
if (!vid.activeapp)
|
||||
{ //KDE doesn't seem to like us, in that you can't alt-tab back or click to activate.
|
||||
//This allows us to steal input focus back from the window manager
|
||||
x11.pXSetInputFocus(vid_dpy, vid_window, RevertToParent, CurrentTime);
|
||||
|
@ -1144,7 +1143,7 @@ static void GetEvent(void)
|
|||
|
||||
case FocusIn:
|
||||
//activeapp is if the game window is focused
|
||||
ActiveApp = true;
|
||||
vid.activeapp = true;
|
||||
|
||||
//but change modes to track the desktop window
|
||||
// if (!(fullscreenflags & FULLSCREEN_ACTIVE) || event.xfocus.window != vid_decoywindow)
|
||||
|
@ -1173,7 +1172,7 @@ static void GetEvent(void)
|
|||
|
||||
if (event.xfocus.window == mw || event.xfocus.window == vid_window)
|
||||
{
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
if (old_windowed_mouse)
|
||||
{
|
||||
Con_DPrintf("uninstall grabs\n");
|
||||
|
@ -1336,9 +1335,9 @@ qboolean GLVID_ApplyGammaRamps(unsigned short *ramps)
|
|||
if (ramps)
|
||||
{
|
||||
//hardwaregamma==1 skips hardware gamma when we're not fullscreen, in favour of software glsl based gamma.
|
||||
// if (vid_hardwaregamma.value == 1 && !ActiveApp && !(fullscreenflags & FULLSCREEN_ACTIVE))
|
||||
// if (vid_hardwaregamma.value == 1 && !vid.activeapp && !(fullscreenflags & FULLSCREEN_ACTIVE))
|
||||
// return false;
|
||||
// if (!ActiveApp)
|
||||
// if (!vid.activeapp)
|
||||
// return false;
|
||||
// if (!vid_hardwaregamma.value)
|
||||
// return false;
|
||||
|
@ -1751,7 +1750,7 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl)
|
|||
break; //erm
|
||||
}
|
||||
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
if (fullscreenflags & FULLSCREEN_LEGACY)
|
||||
{
|
||||
vid_decoywindow = X_CreateWindow(false, visinfo, 640, 480, false);
|
||||
|
@ -1977,7 +1976,7 @@ void Sys_SendKeyEvents(void)
|
|||
return;
|
||||
|
||||
wantwindowed = !!_windowed_mouse.value;
|
||||
if (!ActiveApp)
|
||||
if (!vid.activeapp)
|
||||
wantwindowed = false;
|
||||
if (Key_MouseShouldBeFree() && !fullscreenflags)
|
||||
wantwindowed = false;
|
||||
|
|
|
@ -1168,7 +1168,7 @@ static qboolean CreateMainWindow(rendererstate_t *info)
|
|||
|
||||
Win_Touch_Init(mainwindow);
|
||||
|
||||
INS_UpdateGrabs(info->fullscreen, ActiveApp);
|
||||
INS_UpdateGrabs(info->fullscreen, vid.activeapp);
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
@ -1816,7 +1816,7 @@ void GLVID_SwapBuffers (void)
|
|||
|
||||
// handle the mouse state when windowed if that's changed
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
}
|
||||
|
||||
void OblitterateOldGamma(void)
|
||||
|
@ -1843,7 +1843,7 @@ qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
|
|||
if (vid_hardwaregamma.value == 1 && modestate == MS_WINDOWED)
|
||||
return false; //don't do hardware gamma in windowed mode
|
||||
|
||||
if (ActiveApp && vid_hardwaregamma.value) //this is needed because ATI drivers don't work properly (or when task-switched out).
|
||||
if (vid.activeapp && vid_hardwaregamma.value) //this is needed because ATI drivers don't work properly (or when task-switched out).
|
||||
{
|
||||
if (gammaworks)
|
||||
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
|
||||
|
@ -2174,25 +2174,25 @@ qboolean GLAppActivate(BOOL fActive, BOOL minimize)
|
|||
{
|
||||
static BOOL sound_active;
|
||||
|
||||
if (ActiveApp == fActive && Minimized == minimize)
|
||||
if (vid.activeapp == fActive && Minimized == minimize)
|
||||
return false; //so windows doesn't crash us over and over again.
|
||||
|
||||
ActiveApp = fActive;// && (foregroundwindow==mainwindow);
|
||||
vid.activeapp = fActive;// && (foregroundwindow==mainwindow);
|
||||
Minimized = minimize;
|
||||
|
||||
// enable/disable sound on focus gain/loss
|
||||
if (!ActiveApp && sound_active)
|
||||
if (!vid.activeapp && sound_active)
|
||||
{
|
||||
S_BlockSound ();
|
||||
sound_active = false;
|
||||
}
|
||||
else if (ActiveApp && !sound_active)
|
||||
else if (vid.activeapp && !sound_active)
|
||||
{
|
||||
S_UnblockSound ();
|
||||
sound_active = true;
|
||||
}
|
||||
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, ActiveApp);
|
||||
INS_UpdateGrabs(modestate != MS_WINDOWED, vid.activeapp);
|
||||
|
||||
if (fActive)
|
||||
{
|
||||
|
@ -2657,7 +2657,7 @@ void VID_Init8bitPalette(void)
|
|||
void GLVID_DeInit (void)
|
||||
{
|
||||
GLVID_Shutdown();
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
|
||||
Cvar_Unhook(&vid_vsync);
|
||||
Cvar_Unhook(&vid_wndalpha);
|
||||
|
@ -2710,7 +2710,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
|
||||
if (isPlugin >= 2)
|
||||
{
|
||||
fprintf(stdout, "refocuswindow "fPRIp"\n", mainwindow);
|
||||
fprintf(stdout, "refocuswindow %"PRIxPTR"\n", mainwindow);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ extern qboolean vid_isfullscreen;
|
|||
unsigned short intitialgammaramps[3][256];
|
||||
#endif
|
||||
|
||||
qboolean ActiveApp;
|
||||
qboolean mouseactive;
|
||||
extern qboolean mouseusedforgui;
|
||||
|
||||
|
@ -229,7 +228,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
ActiveApp = true;
|
||||
vid.activeapp = true;
|
||||
|
||||
GL_Init(GLVID_getsdlglfunction);
|
||||
|
||||
|
@ -275,7 +274,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
|
||||
void GLVID_DeInit (void)
|
||||
{
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
|
||||
IN_DeactivateMouse();
|
||||
|
||||
|
@ -321,7 +320,7 @@ void GLVID_SwapBuffers (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!Key_MouseShouldBeFree() && ActiveApp)
|
||||
if (!Key_MouseShouldBeFree() && vid.activeapp)
|
||||
IN_ActivateMouse ();
|
||||
else
|
||||
IN_DeactivateMouse ();
|
||||
|
|
|
@ -417,7 +417,7 @@ void R_SaveRTLights_f(void);
|
|||
void GLR_DoomWorld();
|
||||
#endif
|
||||
#ifdef MAP_PROC
|
||||
qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf);
|
||||
qboolean QDECL D3_LoadMap_CollisionMap(model_t *mod, char *buf, size_t bufsize);
|
||||
unsigned char *D3_CalcVis(model_t *mod, vec3_t org);
|
||||
void D3_GenerateAreas(model_t *mod);
|
||||
#endif
|
||||
|
|
|
@ -1831,6 +1831,41 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"tc.y = -2.0*d.y/div;\n"
|
||||
"tc.z = -(-1.0 + d.x*d.x + d.y*d.y)/div;\n"
|
||||
|
||||
"gl_FragColor = textureCube(s_t0, tc);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
{QR_OPENGL, 110, "postproc_equirectangular",
|
||||
"!!cvarf ffov\n"
|
||||
|
||||
//equirectangular view rendering, commonly used for sphere->2d map projections.
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"attribute vec2 v_texcoord;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"texcoord = v_texcoord.xy;\n"
|
||||
"gl_Position = ftetransform();\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"uniform samplerCube s_t0;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"uniform float cvar_ffov;\n"
|
||||
|
||||
"#define PI 3.1415926535897932384626433832795\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"vec3 tc;\n"
|
||||
"float lng = (texcoord.x - 0.5) * PI * 2.0;\n"
|
||||
"float lat = (texcoord.y) * PI * 1.0;\n"
|
||||
|
||||
"tc.z = cos(lng) * sin(lat); \n"
|
||||
"tc.x = sin(lng) * sin(lat);\n"
|
||||
"tc.y = cos(lat);\n"
|
||||
"gl_FragColor = textureCube(s_t0, tc);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
|
|
@ -279,6 +279,7 @@ It doesn't use persistant connections.
|
|||
*/
|
||||
|
||||
#define COOKIECOOKIECOOKIE
|
||||
#ifdef COOKIECOOKIECOOKIE
|
||||
typedef struct cookie_s
|
||||
{
|
||||
struct cookie_s *next;
|
||||
|
@ -293,6 +294,7 @@ cookie_t *cookies;
|
|||
void Cookie_Feed(char *domain, int secure, char *name, char *value)
|
||||
{
|
||||
cookie_t **link, *c;
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
for(link = &cookies; c = *link; link = &(*link)->next)
|
||||
{
|
||||
if (!strcmp(c->domain, domain) && c->secure == secure && !strcmp(c->name, name))
|
||||
|
@ -304,23 +306,25 @@ void Cookie_Feed(char *domain, int secure, char *name, char *value)
|
|||
*link = c->next;
|
||||
Z_Free(c);
|
||||
}
|
||||
if (!value || !*value)
|
||||
if (value && *value)
|
||||
{
|
||||
// Con_Printf("Deleting cookie http%s://%s/ %s\n", secure?"s":"", domain, name);
|
||||
//no new value, hurrah.
|
||||
return;
|
||||
// Con_Printf("Setting cookie http%s://%s/ %s=%s\n", secure?"s":"", domain, name, value);
|
||||
c = Z_Malloc(sizeof(*c) + strlen(domain) + strlen(name) + strlen(value) + 3);
|
||||
c->domain = (char*)(c+1);
|
||||
strcpy(c->domain, domain);
|
||||
c->secure = secure;
|
||||
c->name = c->domain+strlen(c->domain)+1;
|
||||
strcpy(c->name, name);
|
||||
c->value = c->name+strlen(c->name)+1;
|
||||
strcpy(c->value, value);
|
||||
c->next = cookies;
|
||||
cookies = c;
|
||||
}
|
||||
// Con_Printf("Setting cookie http%s://%s/ %s=%s\n", secure?"s":"", domain, name, value);
|
||||
c = Z_Malloc(sizeof(*c) + strlen(domain) + strlen(name) + strlen(value) + 3);
|
||||
c->domain = (char*)(c+1);
|
||||
strcpy(c->domain, domain);
|
||||
c->secure = secure;
|
||||
c->name = c->domain+strlen(c->domain)+1;
|
||||
strcpy(c->name, name);
|
||||
c->value = c->name+strlen(c->name)+1;
|
||||
strcpy(c->value, value);
|
||||
c->next = cookies;
|
||||
cookies = c;
|
||||
else
|
||||
{
|
||||
// Con_Printf("Deleted cookie http%s://%s/ %s\n", secure?"s":"", domain, name);
|
||||
}
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
}
|
||||
|
||||
//just removes all the cookies it can.
|
||||
|
@ -359,7 +363,7 @@ void Cookie_Parse(char *domain, int secure, char *line, char *end)
|
|||
*end = 0;
|
||||
Cookie_Feed(domain, secure, line, e+1);
|
||||
}
|
||||
//outputs a complete http line: Cookie a=v1; b=v2\r\n
|
||||
//outputs a complete http line: Cookie: a=v1; b=v2\r\n
|
||||
void Cookie_Regurgitate(char *domain, int secure, char *buffer, size_t buffersize)
|
||||
{
|
||||
qboolean hascookies = false;
|
||||
|
@ -367,6 +371,7 @@ void Cookie_Regurgitate(char *domain, int secure, char *buffer, size_t buffersiz
|
|||
char *l = buffer;
|
||||
buffersize -= 3; //\r\n\0
|
||||
*buffer = 0;
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
for (c = cookies; c; c = c->next)
|
||||
{
|
||||
if (!strcmp(c->domain, domain) && c->secure == secure)
|
||||
|
@ -401,6 +406,7 @@ void Cookie_Regurgitate(char *domain, int secure, char *buffer, size_t buffersiz
|
|||
buffer += vlen;
|
||||
}
|
||||
}
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
|
||||
if (hascookies)
|
||||
strcpy(buffer, "\r\n");
|
||||
|
@ -410,6 +416,7 @@ void Cookie_Regurgitate(char *domain, int secure, char *buffer, size_t buffersiz
|
|||
// if (*l)
|
||||
// Con_Printf("Sending cookie(s) to http%s://%s/ %s\n", secure?"s":"", domain, l);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct http_dl_ctx_s {
|
||||
// struct dl_download *dlctx;
|
||||
|
|
|
@ -1398,7 +1398,7 @@ static pbool PR_ExecRunWarning (pubprogfuncs_t *ppf, int xstatement, char *error
|
|||
|
||||
if (progfuncs->funcs.debug_trace == 0)
|
||||
{
|
||||
pr_xstatement = ShowStep(progfuncs, xstatement, error, false);
|
||||
pr_xstatement = ShowStep(progfuncs, xstatement, string, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -6465,10 +6465,11 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
QCC_FreeTemp(idx);
|
||||
return QCC_PR_BuildRef(retbuf, REF_GLOBAL, QCC_MakeIntConst(arraysize), nullsref, type_integer, true);
|
||||
}
|
||||
else if (((t->type == ev_pointer && !arraysize) || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
|
||||
else if (((t->type == ev_pointer && !arraysize) || (t->type == ev_field && (t->aux_type->type == ev_struct || t->aux_type->type == ev_union)) || t->type == ev_struct || t->type == ev_union) && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
|
||||
{
|
||||
char *tname;
|
||||
unsigned int i;
|
||||
pbool fld = t->type == ev_field;
|
||||
if (!idx.cast && t->type == ev_pointer && !arraysize)
|
||||
{
|
||||
t = t->aux_type;
|
||||
|
@ -6481,6 +6482,12 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
if (!t->size)
|
||||
QCC_PR_ParseError(0, "%s was not defined yet", tname);
|
||||
}
|
||||
else if (fld)
|
||||
{
|
||||
t = t->aux_type;
|
||||
if (!t->size)
|
||||
QCC_PR_ParseError(0, "%s was not defined yet", tname);
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseError(0, "indirection in something that is not a struct or union", tname);
|
||||
|
||||
|
@ -6511,6 +6518,9 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
|
|||
}
|
||||
arraysize = t->params[i].arraysize;
|
||||
t = t->params[i].type;
|
||||
|
||||
if (fld)
|
||||
t = QCC_PR_FieldType(t);
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
@ -7841,6 +7851,7 @@ QCC_sref_t QCC_RefToDef(QCC_ref_t *ref, pbool freetemps)
|
|||
case REF_ARRAY:
|
||||
if (ref->index.cast)
|
||||
{
|
||||
//FIXME: array reads of array[immediate+offset] should generate (array+immediate)[offset] instead.
|
||||
//FIXME: this needs to be deprecated
|
||||
const QCC_eval_t *idxeval = QCC_SRef_EvalConst(ref->index);
|
||||
if (idxeval && (ref->index.cast->type == ev_float || ref->index.cast->type == ev_integer))
|
||||
|
|
|
@ -18,6 +18,9 @@ int QCC_PR_CheckCompConst(void);
|
|||
pbool QCC_Include(char *filename);
|
||||
void QCC_FreeDef(QCC_def_t *def);
|
||||
|
||||
#define MAXINCLUDEDIRS 8
|
||||
char qccincludedir[MAXINCLUDEDIRS][256]; //the -src path, for #includes
|
||||
|
||||
char *compilingfile;
|
||||
|
||||
int pr_source_line;
|
||||
|
@ -104,8 +107,33 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor);
|
|||
qcc_includechunk_t *currentchunk;
|
||||
void QCC_PR_CloseProcessor(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAXINCLUDEDIRS; i++)
|
||||
*qccincludedir[i] = 0;
|
||||
currentchunk = NULL;
|
||||
}
|
||||
void QCC_PR_AddIncludePath(char *newinc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXINCLUDEDIRS; i++)
|
||||
{
|
||||
if (!*qccincludedir[i])
|
||||
{
|
||||
QC_strlcpy(qccincludedir[i], newinc, sizeof(qccincludedir));
|
||||
break;
|
||||
}
|
||||
if (!strcmp(qccincludedir[i], newinc))
|
||||
break;
|
||||
}
|
||||
if (i == MAXINCLUDEDIRS)
|
||||
{
|
||||
if (!s_file)
|
||||
QCC_PR_Warning(WARN_STRINGTOOLONG, "cmdline", 0, "Too many include dirs. Ignoring and hoping the stars align.");
|
||||
else
|
||||
QCC_PR_ParseWarning(WARN_STRINGTOOLONG, "Too many include dirs. Ignoring and hoping the stars align.");
|
||||
}
|
||||
}
|
||||
void QCC_PR_IncludeChunkEx (char *data, pbool duplicate, char *filename, CompilerConstant_t *cnst)
|
||||
{
|
||||
qcc_includechunk_t *chunk = qccHunkAlloc(sizeof(qcc_includechunk_t));
|
||||
|
@ -165,18 +193,11 @@ void QCC_PR_PrintNextLine (void)
|
|||
printf ("\n");
|
||||
}
|
||||
|
||||
extern char qccmsourcedir[];
|
||||
//also meant to include it.
|
||||
void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath, pbool verbose)
|
||||
void QCC_Canonicalize(char *fullname, size_t fullnamesize, char *newfile, char *base)
|
||||
{
|
||||
char fullname[1024];
|
||||
int doubledots;
|
||||
|
||||
char *end = fullname;
|
||||
|
||||
if (!*newfile)
|
||||
return;
|
||||
|
||||
|
||||
doubledots = 0;
|
||||
/*count how far up we need to go*/
|
||||
while(!strncmp(newfile, "../", 3) || !strncmp(newfile, "..\\", 3))
|
||||
|
@ -185,25 +206,11 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath, pbool
|
|||
doubledots++;
|
||||
}
|
||||
|
||||
#if 0
|
||||
currentfile += strlen(rootpath); //could this be bad?
|
||||
strcpy(fullname, rootpath);
|
||||
|
||||
end = fullname+strlen(end);
|
||||
if (*fullname && end[-1] != '/')
|
||||
{
|
||||
strcpy(end, "/");
|
||||
end = end+strlen(end);
|
||||
}
|
||||
strcpy(end, currentfile);
|
||||
end = end+strlen(end);
|
||||
#else
|
||||
if (currentfile)
|
||||
strcpy(fullname, currentfile);
|
||||
if (base)
|
||||
strcpy(fullname, base);
|
||||
else
|
||||
*fullname = 0;
|
||||
end = fullname+strlen(fullname);
|
||||
#endif
|
||||
|
||||
while (end > fullname)
|
||||
{
|
||||
|
@ -227,6 +234,40 @@ void QCC_FindBestInclude(char *newfile, char *currentfile, char *rootpath, pbool
|
|||
}
|
||||
|
||||
strcpy(end, newfile);
|
||||
}
|
||||
|
||||
extern char qccmsourcedir[];
|
||||
//also meant to include it.
|
||||
void QCC_FindBestInclude(char *newfile, char *currentfile, pbool verbose)
|
||||
{
|
||||
int includepath = 0;
|
||||
char fullname[1024];
|
||||
|
||||
if (!*newfile)
|
||||
return;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (includepath)
|
||||
{
|
||||
if (includepath > MAXINCLUDEDIRS || !*qccincludedir[includepath-1])
|
||||
QCC_Error(ERR_COULDNTOPENFILE, "Couldn't open file %s", newfile);
|
||||
|
||||
currentfile = qccincludedir[includepath-1];
|
||||
}
|
||||
|
||||
QCC_Canonicalize(fullname, sizeof(fullname), newfile, currentfile);
|
||||
|
||||
{
|
||||
extern progfuncs_t *qccprogfuncs;
|
||||
if (qccprogfuncs->funcs.parms->FileSize(fullname) == -1)
|
||||
{
|
||||
includepath++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
|
@ -794,7 +835,7 @@ pbool QCC_PR_Precompiler(void)
|
|||
break;
|
||||
}
|
||||
|
||||
QCC_FindBestInclude(pr_token, compilingfile, qccmsourcedir, true);
|
||||
QCC_FindBestInclude(pr_token, compilingfile, true);
|
||||
|
||||
if (*pr_file_p == '\r')
|
||||
pr_file_p++;
|
||||
|
@ -835,7 +876,7 @@ pbool QCC_PR_Precompiler(void)
|
|||
}
|
||||
msg[a] = 0;
|
||||
|
||||
QCC_FindBestInclude(msg, compilingfile, qccmsourcedir, false);
|
||||
QCC_FindBestInclude(msg, compilingfile, false);
|
||||
|
||||
pr_file_p++;
|
||||
|
||||
|
@ -955,6 +996,22 @@ pbool QCC_PR_Precompiler(void)
|
|||
{
|
||||
ForcedCRC = atoi(msg);
|
||||
}
|
||||
else if (!QC_strcasecmp(qcc_token, "includedir"))
|
||||
{
|
||||
char newinc[1024];
|
||||
int i;
|
||||
QCC_COM_Parse(msg);
|
||||
|
||||
if (*qcc_token)
|
||||
{
|
||||
i = qcc_token[strlen(qcc_token)-1];
|
||||
if (i != '/' && i != '\\')
|
||||
QC_strlcat(qcc_token, "/", sizeof(qcc_token));
|
||||
}
|
||||
|
||||
QCC_Canonicalize(newinc, sizeof(newinc), qcc_token, compilingfile);
|
||||
QCC_PR_AddIncludePath(newinc);
|
||||
}
|
||||
else if (!QC_strcasecmp(qcc_token, "noref"))
|
||||
defaultnoref = !!atoi(msg);
|
||||
else if (!QC_strcasecmp(qcc_token, "nosave"))
|
||||
|
@ -1110,50 +1167,11 @@ pbool QCC_PR_Precompiler(void)
|
|||
{ //doesn't make sence, but silenced if you are switching between using a certain precompiler app used with CuTF.
|
||||
extern char destfile[1024];
|
||||
char olddest[1024];
|
||||
#ifndef QCCONLY
|
||||
extern char qccmfilename[1024];
|
||||
int p;
|
||||
char *s, *s2;
|
||||
#endif
|
||||
Q_strlcpy(olddest, destfile, sizeof(olddest));
|
||||
QCC_COM_Parse(msg);
|
||||
|
||||
#ifndef QCCONLY
|
||||
p=0;
|
||||
s2 = qcc_token;
|
||||
if (!strncmp(s2, "./", 2))
|
||||
s2+=2;
|
||||
else
|
||||
{
|
||||
while(!strncmp(s2, "../", 3))
|
||||
{
|
||||
s2+=3;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
strcpy(qccmfilename, qccmsourcedir);
|
||||
for (s=qccmfilename+strlen(qccmfilename);p && s>=qccmfilename; s--)
|
||||
{
|
||||
if (*s == '/' || *s == '\\')
|
||||
{
|
||||
*(s+1) = '\0';
|
||||
p--;
|
||||
}
|
||||
}
|
||||
QC_snprintfz(destfile, sizeof(destfile), "%s", s2);
|
||||
QCC_Canonicalize(destfile, sizeof(destfile), qcc_token, compilingfile);
|
||||
|
||||
while (p>0)
|
||||
{
|
||||
memmove(destfile+3, destfile, strlen(destfile)+1);
|
||||
destfile[0] = '.';
|
||||
destfile[1] = '.';
|
||||
destfile[2] = '/';
|
||||
p--;
|
||||
}
|
||||
#else
|
||||
|
||||
strcpy(destfile, qcc_token);
|
||||
#endif
|
||||
if (strcmp(destfile, olddest))
|
||||
printf("Outputfile: %s\n", destfile);
|
||||
}
|
||||
|
|
|
@ -3401,13 +3401,23 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
static void AddTip(HWND tipwnd, HWND tool, char *message)
|
||||
{
|
||||
TOOLINFO toolInfo = { 0 };
|
||||
toolInfo.cbSize = sizeof(toolInfo);
|
||||
toolInfo.hwnd = tool;
|
||||
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
|
||||
toolInfo.uId = (UINT_PTR)tool;
|
||||
toolInfo.lpszText = message;
|
||||
SendMessage(tipwnd, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
|
||||
}
|
||||
void OptionsDialog(void)
|
||||
{
|
||||
char nicername[256], *us;
|
||||
HWND subsection;
|
||||
RECT r;
|
||||
WNDCLASS wndclass;
|
||||
HWND wnd;
|
||||
HWND wnd, tipwnd;
|
||||
int i;
|
||||
int flagcolums=1;
|
||||
|
||||
|
@ -3486,6 +3496,10 @@ void OptionsDialog(void)
|
|||
optionsmenu=CreateWindowEx(WS_EX_CONTEXTHELP, OPTIONS_WINDOW_CLASS_NAME, "Options - FTE QuakeC compiler", WS_CAPTION|WS_SYSMENU,
|
||||
r.left, r.top, r.right-r.left, r.bottom-r.top, NULL, NULL, ghInstance, NULL);
|
||||
|
||||
tipwnd = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, optionsmenu, NULL, ghInstance, NULL);
|
||||
SetWindowPos(tipwnd, HWND_TOPMOST,0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
subsection = CreateWindow("BUTTON", "Optimisations", WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
|
||||
0, 0, 400, height-40*4+24, optionsmenu, NULL, ghInstance, NULL);
|
||||
|
||||
|
@ -3518,51 +3532,59 @@ void OptionsDialog(void)
|
|||
if (!fl_nondfltopts)
|
||||
EnableWindow(wnd, FALSE);
|
||||
|
||||
AddTip(tipwnd, wnd, optimisations[i].description);
|
||||
|
||||
num++;
|
||||
}
|
||||
|
||||
CreateWindow("BUTTON","O0",
|
||||
wnd = CreateWindow("BUTTON","O0",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_LEVEL0,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","O1",
|
||||
AddTip(tipwnd, wnd, "Disable optimisations completely, giving code more similar to vanilla.");
|
||||
wnd = CreateWindow("BUTTON","O1",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_LEVEL1,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","O2",
|
||||
AddTip(tipwnd, wnd, "Enable simple optimisations (primarily size). Probably still breaks decompilers.");
|
||||
wnd = CreateWindow("BUTTON","O2",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64*2,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_LEVEL2,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","O3",
|
||||
AddTip(tipwnd, wnd, "Enable most optimisations. Does not optimise anything that is likely to break any engines.");
|
||||
wnd = CreateWindow("BUTTON","O3",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64*3,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_LEVEL3,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","Debug",
|
||||
AddTip(tipwnd, wnd, "Enable unsafe optimisations. The extra optimisations may cause the progs to fail in certain cases, especially if used to compile addon modules.");
|
||||
wnd = CreateWindow("BUTTON","Debug",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64*4,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_DEBUG,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","Default",
|
||||
AddTip(tipwnd, wnd, "Disable any optimisations that might interfere with debugging somehow.");
|
||||
wnd = CreateWindow("BUTTON","Default",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64*5,height-40*5+24,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_DEFAULT,
|
||||
ghInstance,
|
||||
NULL);
|
||||
AddTip(tipwnd, wnd, "Default optimsations are aimed at increasing capacity without breaking debuggers or common decompilers (although gotos, switches, arrays, etc, will still result in issues).");
|
||||
|
||||
#ifdef EMBEDDEBUG
|
||||
w_enginebinary = CreateWindowEx(WS_EX_CLIENTEDGE,
|
||||
|
@ -3592,29 +3614,36 @@ void OptionsDialog(void)
|
|||
(HMENU)IDI_O_ENGINECOMMANDLINE,
|
||||
ghInstance,
|
||||
NULL);
|
||||
|
||||
AddTip(tipwnd, w_enginebinary, "This is the engine that you wish to debug with.\nCurrently only FTEQW supports actual debugging, while specifying other engines here merely provides you with a quick way to start them up");
|
||||
AddTip(tipwnd, w_enginebasedir, "This is your base directory (typically the directory your engine executable is in)");
|
||||
AddTip(tipwnd, w_enginecommandline, "This is the commandline to use to invoke your mod.\nYou'll likely want -game here.\n-window is also handy.\n-nohome can be used to inhibit the use of home directories.\nYou may also want to add '+map start' or some such.");
|
||||
#endif
|
||||
|
||||
CreateWindow("BUTTON","Apply",
|
||||
wnd = CreateWindow("BUTTON","Apply",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8,height-40,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_APPLY,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","Save",
|
||||
AddTip(tipwnd, wnd, "Use selected settings without saving them to disk.");
|
||||
wnd = CreateWindow("BUTTON","Save",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64,height-40,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_APPLYSAVE,
|
||||
ghInstance,
|
||||
NULL);
|
||||
CreateWindow("BUTTON","progs.src",
|
||||
AddTip(tipwnd, wnd, "Use selected settings and save them to disk so that they're also used the next time you start fteqccgui.");
|
||||
wnd = CreateWindow("BUTTON","progs.src",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
8+64*2,height-40,64,32,
|
||||
optionsmenu,
|
||||
(HMENU)IDI_O_CHANGE_PROGS_SRC,
|
||||
ghInstance,
|
||||
NULL);
|
||||
AddTip(tipwnd, wnd, "Change the initial src file.");
|
||||
|
||||
|
||||
|
||||
|
@ -3631,6 +3660,7 @@ void OptionsDialog(void)
|
|||
Button_SetCheck(wnd, 1);
|
||||
else
|
||||
Button_SetCheck(wnd, 0);
|
||||
AddTip(tipwnd, wnd, "Compile for hexen2.\nThis changes the opcodes slightly, the progs crc, and enables some additional keywords.");
|
||||
|
||||
targitem_fte = wnd = CreateWindow("BUTTON","Extended Instructions",
|
||||
WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
|
||||
|
@ -3644,6 +3674,7 @@ void OptionsDialog(void)
|
|||
Button_SetCheck(wnd, 1);
|
||||
else
|
||||
Button_SetCheck(wnd, 0);
|
||||
AddTip(tipwnd, wnd, "Enables the use of additional opcodes, which only FTE supports at this time.\nThis gives both smaller and faster code, as well as allowing pointers, ints, and other extensions not possible with the vanilla QCVM.");
|
||||
|
||||
/* autohighlight_item = wnd = CreateWindow("BUTTON","Syntax Highlighting",
|
||||
WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
|
||||
|
@ -3690,6 +3721,7 @@ void OptionsDialog(void)
|
|||
Button_SetCheck(wnd, 1);
|
||||
else
|
||||
Button_SetCheck(wnd, 0);
|
||||
AddTip(tipwnd, wnd, compiler_flag[i].description);
|
||||
}
|
||||
|
||||
CreateWindow("STATIC","Extra Parameters:",
|
||||
|
@ -3708,6 +3740,7 @@ void OptionsDialog(void)
|
|||
(HMENU)IDI_O_ADDITIONALPARAMETERS,
|
||||
ghInstance,
|
||||
NULL);
|
||||
AddTip(tipwnd, extraparmsitem, "You can specify any additional commandline arguments here.\nAdd -DFOO=bar to define the FOO preprocessor constant as bar.");
|
||||
|
||||
ShowWindow(optionsmenu, SW_SHOWDEFAULT);
|
||||
}
|
||||
|
@ -4882,6 +4915,7 @@ void AddSourceFile(const char *parentpath, const char *filename)
|
|||
{ //add a directory.
|
||||
item.hParent = pi;
|
||||
item.item.lParam = !slash; //lparam = false if we're only adding this node to get at a child.
|
||||
item.item.state = ((*item.item.pszText!='.')?TVIS_EXPANDED:0); //directories with a leading . should not be expanded by default
|
||||
pi = (HANDLE)SendMessage(projecttree,TVM_INSERTITEM,0,(LPARAM)&item);
|
||||
item.hParent = pi;
|
||||
}
|
||||
|
@ -5142,11 +5176,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
}
|
||||
else
|
||||
{
|
||||
if (mdibox)
|
||||
{
|
||||
buttons[ID_EDIT].washit = true;
|
||||
}
|
||||
else
|
||||
if (!mdibox)
|
||||
{
|
||||
GUIprintf("Welcome to FTE QCC\n");
|
||||
GUIprintf("Source file: ");
|
||||
|
|
|
@ -934,7 +934,52 @@ void QCC_UnmarshalLocals(void)
|
|||
if (verbose)
|
||||
printf("%i shared locals, %i private, %i total\n", biggest - onum, onum - eog, numpr_globals-eog);
|
||||
}
|
||||
static void QCC_GenerateFieldDefs(QCC_def_t *def, char *fieldname, int ofs, QCC_type_t *type)
|
||||
{
|
||||
string_t sname;
|
||||
QCC_ddef32_t *dd;
|
||||
if (type->type == ev_struct || type->type == ev_union)
|
||||
{ //the qcvm cannot cope with struct fields. so we need to generate lots of fake ones.
|
||||
char sub[256];
|
||||
unsigned int p, a;
|
||||
int parms = type->num_parms;
|
||||
if (type->type == ev_union)
|
||||
parms = 1; //unions only generate the first element. it simplifies things (should really just be the biggest).
|
||||
for (p = 0; p < parms; p++)
|
||||
{
|
||||
if (type->params[p].arraysize)
|
||||
{
|
||||
for (a = 0; a < type->params[p].arraysize; a++)
|
||||
{
|
||||
QC_snprintfz(sub, sizeof(sub), "%s.%s[%u]", fieldname, type->params[p].paramname, a);
|
||||
QCC_GenerateFieldDefs(def, sub, ofs + type->params[p].ofs + a * type->params[p].type->size, type->params[p].type);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QC_snprintfz(sub, sizeof(sub), "%s.%s", fieldname, type->params[p].paramname);
|
||||
QCC_GenerateFieldDefs(def, sub, ofs + type->params[p].ofs, type->params[p].type);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (numfielddefs >= MAX_FIELDS)
|
||||
QCC_PR_ParseError(0, "Too many fields. Limit is %u\n", MAX_FIELDS);
|
||||
dd = &fields[numfielddefs];
|
||||
numfielddefs++;
|
||||
dd->type = type->type;
|
||||
dd->s_name = sname = QCC_CopyString (fieldname);
|
||||
dd->ofs = def->symboldata[ofs]._int;
|
||||
|
||||
if (numglobaldefs >= MAX_GLOBALS)
|
||||
QCC_PR_ParseError(0, "Too many globals. Limit is %u\n", MAX_GLOBALS);
|
||||
//and make sure that there's a global defined too, so field remapping isn't screwed.
|
||||
dd = &qcc_globals[numglobaldefs];
|
||||
numglobaldefs++;
|
||||
dd->type = ev_field;
|
||||
dd->ofs = ofs;
|
||||
dd->s_name = sname;
|
||||
}
|
||||
|
||||
|
||||
CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def);
|
||||
|
@ -1300,13 +1345,8 @@ pbool QCC_WriteData (int crc)
|
|||
}
|
||||
else if (def->type->type == ev_field && def->constant && (!def->scope || def->isstatic || def->initialized))
|
||||
{
|
||||
if (numfielddefs >= MAX_FIELDS)
|
||||
QCC_PR_ParseError(0, "Too many fields. Limit is %u\n", MAX_FIELDS);
|
||||
dd = &fields[numfielddefs];
|
||||
numfielddefs++;
|
||||
dd->type = def->type->aux_type->type;
|
||||
dd->s_name = QCC_CopyString (def->name);
|
||||
dd->ofs = def->symboldata[def->ofs]._int;
|
||||
QCC_GenerateFieldDefs(def, def->name, def->ofs, def->type->aux_type);
|
||||
continue;
|
||||
}
|
||||
else if ((def->scope||def->constant) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
|
||||
{
|
||||
|
@ -3167,6 +3207,14 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
|||
memcpy(cnst->value, val, strlen(val)+1);
|
||||
}
|
||||
}
|
||||
else if ( !strncmp(myargv[i], "-I", 2) )
|
||||
{
|
||||
name = myargv[i] + 2;
|
||||
if (!*name && i+1<myargc)
|
||||
name = myargv[++i];
|
||||
|
||||
QCC_PR_AddIncludePath(name);
|
||||
}
|
||||
|
||||
//optimisations.
|
||||
else if ( !strnicmp(myargv[i], "-O", 2) || !strnicmp(myargv[i], "/O", 2) )
|
||||
|
|
|
@ -1512,7 +1512,10 @@ void Q_InitProgs(void)
|
|||
|
||||
if (a)
|
||||
{
|
||||
as = strstr(a, "extraqwprogs=");
|
||||
if (progstype == PROG_QW)
|
||||
as = strstr(a, "extraqwprogs=");
|
||||
else
|
||||
as = strstr(a, "extraprogs=");
|
||||
if (as)
|
||||
{
|
||||
for (a = as+13; *a; a++)
|
||||
|
@ -1630,7 +1633,10 @@ void Q_InitProgs(void)
|
|||
a = as = COM_LoadStackFile(va("maps/%s.inf", svs.name), addons, sizeof(addons), NULL);
|
||||
if (a)
|
||||
{
|
||||
as = strstr(a, "qwprogs=");
|
||||
if (progstype == PROG_QW)
|
||||
as = strstr(a, "qwprogs=");
|
||||
else
|
||||
as = strstr(a, "progs=");
|
||||
if (as)
|
||||
{
|
||||
for (a = as+11; *a; a++)
|
||||
|
@ -10038,7 +10044,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"serverkey", PF_Fixme, 0, 0, 0, 354, D("string(string key)", "Look up a key in the server's public serverinfo string")},//
|
||||
{"getentitytoken", PF_Fixme, 0, 0, 0, 355, D("string(optional string resetstring)", "Grab the next token in the map's entity lump.\nIf resetstring is not specified, the next token will be returned with no other sideeffects.\nIf empty, will reset from the map before returning the first token, probably {.\nIf not empty, will tokenize from that string instead.\nAlways returns tempstrings.")},//;
|
||||
{"findfont", PF_Fixme, 0, 0, 0, 356, D("float(string s)", "Looks up a named font slot. Matches the actual font name as a last resort.")},//;
|
||||
{"loadfont", PF_Fixme, 0, 0, 0, 357, D("float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)", "too convoluted for me to even try to explain correct usage. Try drawfont = loadfont(\"foo\", \"cour\", \"16\", 0, 0, 0); to switch to the courier font, if you have the freetype2 library in windows..")},
|
||||
{"loadfont", PF_Fixme, 0, 0, 0, 357, D("float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)", "too convoluted for me to even try to explain correct usage. Try drawfont = loadfont(\"\", \"cour\", \"16\", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high), if you have the freetype2 library in windows..")},
|
||||
{"sendevent", PF_Fixme, 0, 0, 0, 359, D("void(string evname, string evargs, ...)", "Invoke Cmd_evname_evargs in ssqc. evargs must be a string of initials refering to the types of the arguments to pass. v=vector, e=entity(.entnum field is sent), f=float, i=int. 6 arguments max - you can get more if you pack your floats into vectors.")},// (EXT_CSQC_1)
|
||||
|
||||
{"readbyte", PF_Fixme, 0, 0, 0, 360, "float()"},// (EXT_CSQC)
|
||||
|
@ -11328,27 +11334,28 @@ void PR_DumpPlatform_f(void)
|
|||
{"EF_DIMLIGHT", "const float", QW|NQ|CS, NULL, EF_DIMLIGHT},
|
||||
{"EF_FLAG1", "const float", QW , NULL, QWEF_FLAG1},
|
||||
{"EF_FLAG2", "const float", QW , NULL, QWEF_FLAG2},
|
||||
{"EF_ADDITIVE", "const float", NQ|CS, NULL, NQEF_ADDITIVE},
|
||||
{"EF_BLUE", "const float", QW|NQ|CS, NULL, EF_BLUE},
|
||||
{"EF_RED", "const float", QW|NQ|CS, NULL, EF_RED},
|
||||
{"EF_GREEN", "const float", QW|NQ|CS, NULL, EF_GREEN},
|
||||
{"EF_FULLBRIGHT", "const float", QW|NQ|CS, NULL, EF_FULLBRIGHT},
|
||||
{"EF_NOSHADOW", "const float", QW|NQ|CS, NULL, EF_NOSHADOW},
|
||||
{"EF_NODEPTHTEST", "const float", QW|NQ|CS, NULL, EF_NODEPTHTEST},
|
||||
{"EF_NODRAW", "const float", NQ|CS, NULL, NQEF_NODRAW},
|
||||
{"EF_ADDITIVE", "const float", NQ|CS, "The entity will be drawn with an additive blend.", NQEF_ADDITIVE},
|
||||
{"EF_BLUE", "const float", QW|NQ|CS, "A blue glow", EF_BLUE},
|
||||
{"EF_RED", "const float", QW|NQ|CS, "A red glow", EF_RED},
|
||||
{"EF_GREEN", "const float", QW|NQ|CS, "A green glow", EF_GREEN},
|
||||
{"EF_FULLBRIGHT", "const float", QW|NQ|CS, "This entity will ignore lighting", EF_FULLBRIGHT},
|
||||
{"EF_NOSHADOW", "const float", QW|NQ|CS, "This entity will not cast shadows", EF_NOSHADOW},
|
||||
{"EF_NODEPTHTEST", "const float", QW|NQ|CS, "This entity will be drawn over the top of other things that are closer.", EF_NODEPTHTEST},
|
||||
|
||||
{"EF_NOMODELFLAGS", "const float", QW|NQ, "Surpresses the normal flags specified in the model.", EF_NOMODELFLAGS},
|
||||
|
||||
{"MF_ROCKET", "const float", QW|NQ|CS, NULL, EF_MF_ROCKET>>24},
|
||||
{"MF_GRENADE", "const float", QW|NQ|CS, NULL, EF_MF_GRENADE>>24},
|
||||
{"MF_GIB", "const float", QW|NQ|CS, NULL, EF_MF_GIB>>24},
|
||||
{"MF_GIB", "const float", QW|NQ|CS, "Regular blood trail", EF_MF_GIB>>24},
|
||||
{"MF_ROTATE", "const float", QW|NQ|CS, NULL, EF_MF_ROTATE>>24},
|
||||
{"MF_TRACER", "const float", QW|NQ|CS, NULL, EF_MF_TRACER>>24},
|
||||
{"MF_ZOMGIB", "const float", QW|NQ|CS, NULL, EF_MF_ZOMGIB>>24},
|
||||
{"MF_TRACER2", "const float", QW|NQ|CS, NULL, EF_MF_TRACER2>>24},
|
||||
{"MF_TRACER3", "const float", QW|NQ|CS, NULL, EF_MF_TRACER3>>24},
|
||||
{"MF_TRACER", "const float", QW|NQ|CS, "AKA: green scrag trail", EF_MF_TRACER>>24},
|
||||
{"MF_ZOMGIB", "const float", QW|NQ|CS, "Dark blood trail", EF_MF_ZOMGIB>>24},
|
||||
{"MF_TRACER2", "const float", QW|NQ|CS, "AKA: hellknight projectile trail", EF_MF_TRACER2>>24},
|
||||
{"MF_TRACER3", "const float", QW|NQ|CS, "AKA: purple vore trail", EF_MF_TRACER3>>24},
|
||||
|
||||
|
||||
{"SL_ORG_TL", "const float", QW|NQ, NULL, SL_ORG_TL},
|
||||
{"SL_ORG_TL", "const float", QW|NQ, "Used with showpic etc, specifies that the x+y values are relative to the top-left of the screen", SL_ORG_TL},
|
||||
{"SL_ORG_TR", "const float", QW|NQ, NULL, SL_ORG_TR},
|
||||
{"SL_ORG_BL", "const float", QW|NQ, NULL, SL_ORG_BL},
|
||||
{"SL_ORG_BR", "const float", QW|NQ, NULL, SL_ORG_BR},
|
||||
|
@ -11464,6 +11471,7 @@ void PR_DumpPlatform_f(void)
|
|||
{"IE_ACCELEROMETER", "const float", CS, NULL, CSIE_ACCELEROMETER},
|
||||
{"IE_FOCUS", "const float", CS, "Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged.", CSIE_FOCUS},
|
||||
{"IE_JOYAXIS", "const float", CS, "Specifies that what value a joystick/controller axis currently specifies. x=axis, y=value. Will be called multiple times, once for each axis of each active controller.", CSIE_JOYAXIS},
|
||||
{"IE_GYROSCOPE", "const float", CS, NULL, CSIE_GYROSCOPE},
|
||||
|
||||
{"CLIENTTYPE_DISCONNECTED","const float", QW|NQ, "Return value from clienttype() builtin. This entity is a player slot that is currently empty.", CLIENTTYPE_DISCONNECTED},
|
||||
{"CLIENTTYPE_REAL", "const float", QW|NQ, "This is a real player, and not a bot.", CLIENTTYPE_REAL},
|
||||
|
|
|
@ -1527,19 +1527,19 @@ static qintptr_t QVM_uri_query (void *offset, quintptr_t mask, const qintptr_t *
|
|||
|
||||
if (!pr_enable_uriget.ival)
|
||||
{
|
||||
Con_Printf("QVM_uri_query(\"%s\","fPRIp"): %s disabled\n", url, cb_context, pr_enable_uriget.name);
|
||||
Con_Printf("QVM_uri_query(\"%s\",%"PRIxPTR"): %s disabled\n", url, (qintptr_t)cb_context, pr_enable_uriget.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mimetype && *mimetype)
|
||||
{
|
||||
VALIDATEPOINTER(arg[4],datasize);
|
||||
Con_DPrintf("QVM_uri_query(%s,"fPRIp")\n", url, cb_context);
|
||||
Con_DPrintf("QVM_uri_query(%s,%"PRIxPTR")\n", url, (qintptr_t)cb_context);
|
||||
dl = HTTP_CL_Put(url, mimetype, data, datasize, QVM_uri_query_callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf("QVM_uri_query(%s,"fPRIp")\n", url, cb_context);
|
||||
Con_DPrintf("QVM_uri_query(%s,%"PRIxPTR")\n", url, (qintptr_t)cb_context);
|
||||
dl = HTTP_CL_Get(url, NULL, QVM_uri_query_callback);
|
||||
}
|
||||
if (dl)
|
||||
|
@ -1751,26 +1751,25 @@ static qintptr_t QVM_Map_Extension (void *offset, quintptr_t mask, const qintptr
|
|||
}
|
||||
|
||||
//============== general Quake services ==================
|
||||
|
||||
#if FTE_WORDSIZE == 32 && !defined(NACL)
|
||||
static int syscallqvm (void *offset, quintptr_t mask, int fn, const int *arg)
|
||||
{
|
||||
if (fn >= countof(traps))
|
||||
return QVM_NotYetImplemented(offset, mask, arg);
|
||||
return traps[fn](offset, mask, arg);
|
||||
if (sizeof(int) == sizeof(qintptr_t))
|
||||
{ //should allow the slow copy below to be optimised out
|
||||
if (fn >= countof(traps))
|
||||
return QVM_NotYetImplemented(offset, mask, (qintptr_t*)arg);
|
||||
return traps[fn](offset, mask, (qintptr_t*)arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
qintptr_t args[13];
|
||||
int i;
|
||||
for (i = 0; i < 13; i++)
|
||||
args[i] = arg[i];
|
||||
if (fn >= countof(traps))
|
||||
return QVM_NotYetImplemented(offset, mask, args);
|
||||
return traps[fn](offset, mask, args);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static int syscallqvm (void *offset, quintptr_t mask, int fn, const int *arg)
|
||||
{
|
||||
qintptr_t args[13];
|
||||
int i;
|
||||
for (i = 0; i < 13; i++)
|
||||
args[i] = arg[i];
|
||||
if (fn >= countof(traps))
|
||||
return QVM_NotYetImplemented(offset, mask, args);
|
||||
return traps[fn](offset, mask, args);
|
||||
}
|
||||
#endif
|
||||
|
||||
static qintptr_t EXPORT_FN syscallnative (qintptr_t arg, ...)
|
||||
{
|
||||
|
|
|
@ -1257,7 +1257,7 @@ void SV_Savegame (const char *savename, qboolean mapchange)
|
|||
rgbbuffer = VID_GetRGBInfo(&width, &height, &fmt);
|
||||
if (rgbbuffer)
|
||||
{
|
||||
SCR_ScreenShot(savefilename, FS_GAMEONLY, rgbbuffer, width, height, fmt);
|
||||
SCR_ScreenShot(savefilename, FS_GAMEONLY, &rgbbuffer, 1, width, height, fmt);
|
||||
BZ_Free(rgbbuffer);
|
||||
|
||||
|
||||
|
@ -1307,6 +1307,7 @@ void SV_Savegame_f (void)
|
|||
cvar_t sv_autosave = CVARD("sv_autosave", "1", "Interval for autosaves, in minutes.");
|
||||
void SV_AutoSave(void)
|
||||
{
|
||||
#ifndef NOBUILTINMENUS
|
||||
#ifndef SERVERONLY
|
||||
const char *autosavename;
|
||||
int i;
|
||||
|
@ -1342,11 +1343,12 @@ void SV_AutoSave(void)
|
|||
}
|
||||
|
||||
autosavename = M_ChooseAutoSave();
|
||||
Con_Printf("Autosaving to %s\n", autosavename);
|
||||
Con_DPrintf("Autosaving to %s\n", autosavename);
|
||||
SV_Savegame(autosavename, false);
|
||||
|
||||
sv.autosave_time = sv.time + sv_autosave.value * 60;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void SV_Loadgame_f (void)
|
||||
|
|
|
@ -291,12 +291,18 @@ SV_Give_f
|
|||
*/
|
||||
static void SV_Give_f (void)
|
||||
{
|
||||
char *t;
|
||||
char *t = Cmd_Argv(2);
|
||||
int v;
|
||||
|
||||
if (!svprogfuncs)
|
||||
return;
|
||||
|
||||
if (!strcmp(t, "damn"))
|
||||
{
|
||||
Con_TPrintf ("%s not given.\n", t);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SV_MayCheat())
|
||||
{
|
||||
Con_TPrintf ("Please set sv_cheats 1 and restart the map first.\n");
|
||||
|
@ -319,7 +325,6 @@ static void SV_Give_f (void)
|
|||
|
||||
SV_LogPlayer(host_client, "give cheat");
|
||||
|
||||
t = Cmd_Argv(2);
|
||||
v = atoi (Cmd_Argv(3));
|
||||
|
||||
switch ((t[1]==0)?t[0]:0)
|
||||
|
@ -1259,7 +1264,7 @@ static void SV_BanList_f (void)
|
|||
{
|
||||
*middlebit = 0;
|
||||
if (nb->expiretime)
|
||||
Q_strncatz(middlebit, va(",\t+"fPRIllu, (unsigned long long)nb->expiretime - bantime), sizeof(middlebit));
|
||||
Q_strncatz(middlebit, va(",\t+%"PRIu64, (unsigned long long)nb->expiretime - bantime), sizeof(middlebit));
|
||||
if (nb->reason[0])
|
||||
Q_strncatz(middlebit, ",\t", sizeof(middlebit));
|
||||
Con_Printf("%s%s%s\n", NET_AdrToStringMasked(adr, sizeof(adr), &nb->adr, &nb->adrmask), middlebit, nb->reason);
|
||||
|
@ -1297,7 +1302,7 @@ static void SV_FilterList_f (void)
|
|||
if (nb->expiretime)
|
||||
{
|
||||
time_t secs = nb->expiretime - curtime;
|
||||
Con_Printf("%s %s +"fPRIllu":%02u\n", NET_AdrToStringMasked(adr, sizeof(adr), &nb->adr, &nb->adrmask), banflagtext, (unsigned long long)(secs/60), (unsigned int)(secs%60));
|
||||
Con_Printf("%s %s +%"PRIu64":%02u\n", NET_AdrToStringMasked(adr, sizeof(adr), &nb->adr, &nb->adrmask), banflagtext, (unsigned long long)(secs/60), (unsigned int)(secs%60));
|
||||
}
|
||||
else
|
||||
Con_Printf("%s %s\n", NET_AdrToStringMasked(adr, sizeof(adr), &nb->adr, &nb->adrmask), banflagtext);
|
||||
|
@ -1482,9 +1487,9 @@ static void SV_WriteIP_f (void)
|
|||
}
|
||||
}
|
||||
if (bi->reason[0])
|
||||
s = va("addip %s %s "fPRIllu" \"%s\"\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflagtext, (unsigned long long) bi->expiretime, bi->reason);
|
||||
s = va("addip %s %s %"PRIu64" \"%s\"\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflagtext, (unsigned long long) bi->expiretime, bi->reason);
|
||||
else if (bi->expiretime)
|
||||
s = va("addip %s %s "fPRIllu"\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflagtext, (unsigned long long) bi->expiretime);
|
||||
s = va("addip %s %s %"PRIu64"\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflagtext, (unsigned long long) bi->expiretime);
|
||||
else
|
||||
s = va("addip %s %s\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflagtext);
|
||||
VFS_WRITE(f, s, strlen(s));
|
||||
|
@ -2713,7 +2718,7 @@ void SV_MemInfo_f(void)
|
|||
|
||||
csfr = sizeof(*cl->csqcentversions) * cl->max_net_ents;
|
||||
|
||||
Con_Printf(fPRIzu" minping=%i frame=%i, csqc=%i\n", sizeof(svs.clients[i]), sz, fr, csfr);
|
||||
Con_Printf("%"PRIuSIZE" minping=%i frame=%i, csqc=%i\n", sizeof(svs.clients[i]), sz, fr, csfr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,9 +226,11 @@ void MSV_MapCluster_f(void)
|
|||
Q_strncpyz(sv.modelname, "start", sizeof(sv.modelname));
|
||||
if (atoi(Cmd_Argv(2)))
|
||||
{
|
||||
#ifdef SQL
|
||||
Con_Printf("Opening database \"%s\"\n", sqlparams[3]);
|
||||
sv.logindatabase = SQL_NewServer("sqlite", sqlparams);
|
||||
if (sv.logindatabase == -1)
|
||||
#endif
|
||||
{
|
||||
SV_UnspawnServer();
|
||||
Con_Printf("Unable to open account database\n");
|
||||
|
@ -934,13 +936,14 @@ struct logininfo_s
|
|||
char guid[64];
|
||||
char name[64];
|
||||
};
|
||||
#endif
|
||||
qboolean SV_IgnoreSQLResult(queryrequest_t *req, int firstrow, int numrows, int numcols, qboolean eof)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int numstats, float *stats)
|
||||
{
|
||||
#ifdef SQL
|
||||
queryrequest_t *req;
|
||||
sqlserver_t *srv;
|
||||
static char hex[16] = "0123456789abcdef";
|
||||
|
@ -961,6 +964,7 @@ void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int num
|
|||
if (srv)
|
||||
SQL_NewQuery(srv, SV_IgnoreSQLResult, sql, &req);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
qboolean MSV_ClusterLoginReply(netadr_t *legacyclientredirect, unsigned int serverid, unsigned int playerid, char *playername, char *clientguid, netadr_t *clientaddr, void *statsblob, size_t statsblobsize)
|
||||
|
@ -1023,6 +1027,7 @@ qboolean MSV_ClusterLoginReply(netadr_t *legacyclientredirect, unsigned int serv
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef SQL
|
||||
qboolean MSV_ClusterLoginSQLResult(queryrequest_t *req, int firstrow, int numrows, int numcols, qboolean eof)
|
||||
{
|
||||
sqlserver_t *sql = SQL_GetServer(req->srvid, true);
|
||||
|
@ -1061,16 +1066,12 @@ qboolean MSV_ClusterLoginSQLResult(queryrequest_t *req, int firstrow, int numrow
|
|||
pendinglookups--;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//returns true to block entry to this server.
|
||||
extern int nextuserid;
|
||||
qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
|
||||
{
|
||||
char escname[64], escpasswd[64];
|
||||
sqlserver_t *sql;
|
||||
queryrequest_t *req;
|
||||
struct logininfo_s *info;
|
||||
|
||||
if (sv.state != ss_clustermode)
|
||||
return false;
|
||||
|
||||
|
@ -1080,8 +1081,13 @@ qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
|
|||
return false;
|
||||
}*/
|
||||
|
||||
#ifdef SQL
|
||||
if (sv.logindatabase != -1)
|
||||
{
|
||||
char escname[64], escpasswd[64];
|
||||
struct logininfo_s *info;
|
||||
sqlserver_t *sql;
|
||||
queryrequest_t *req;
|
||||
if (pendinglookups > 10)
|
||||
return true;
|
||||
sql = SQL_GetServer(sv.logindatabase, false);
|
||||
|
@ -1097,7 +1103,9 @@ qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
|
|||
info->clientaddr = net_from;
|
||||
}
|
||||
}
|
||||
/* else if (0)
|
||||
else
|
||||
#endif
|
||||
/* if (0)
|
||||
{
|
||||
char tmpbuf[256];
|
||||
netadr_t redir;
|
||||
|
@ -1107,8 +1115,8 @@ qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
|
|||
return false;
|
||||
}
|
||||
return true;
|
||||
}*/
|
||||
else
|
||||
}
|
||||
else*/
|
||||
MSV_ClusterLoginReply(NULL, 0, ++nextuserid, Info_ValueForKey(userinfo, "name"), guid, &net_from, NULL, 0);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ cvar_t allow_download_packages = CVARD("allow_download_packages", "1", "if 1, p
|
|||
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
|
||||
cvar_t allow_download_wads = CVARD("allow_download_wads", "1", "0 blocks downloading of any file in the wads/ directory, or is in the root directory with the extension .wad");
|
||||
cvar_t allow_download_configs = CVARD("allow_download_configs", "0", "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD.");
|
||||
cvar_t allow_download_locs = CVARD("allow_download_locs", "1", "0 blocks downloading of any file in the locs/ directory");
|
||||
cvar_t allow_download_copyrighted = CVARD("allow_download_copyrighted", "0", "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
|
||||
cvar_t allow_download_other = CVARD("allow_download_other", "0", "0 blocks downloading of any file that was not covered by any of the directory download blocks.");
|
||||
|
||||
|
@ -4777,6 +4778,7 @@ void SV_InitLocal (void)
|
|||
Cvar_Register (&allow_download_pakcontents, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_textures,cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_configs, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_locs, cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_packages,cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_refpackages,cvargroup_serverpermissions);
|
||||
Cvar_Register (&allow_download_wads, cvargroup_serverpermissions);
|
||||
|
@ -4819,8 +4821,10 @@ void SV_InitLocal (void)
|
|||
|
||||
Cmd_AddCommand ("openroute", SV_OpenRoute_f);
|
||||
|
||||
#ifndef NOBUILTINMENUS
|
||||
#ifndef SERVERONLY
|
||||
Cvar_Register(&sv_autosave, cvargroup_servercontrol);
|
||||
#endif
|
||||
#endif
|
||||
Cmd_AddCommand ("savegame_legacy", SV_LegacySavegame_f);
|
||||
Cmd_AddCommand ("savegame", SV_Savegame_f);
|
||||
|
|
|
@ -868,164 +868,6 @@ void Sys_ServerActivity(void)
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef MULTITHREAD
|
||||
/* Thread creation calls */
|
||||
typedef void *(*pfunction_t)(void *);
|
||||
|
||||
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize)
|
||||
{
|
||||
pthread_t *thread;
|
||||
pthread_attr_t attr;
|
||||
|
||||
thread = (pthread_t *)malloc(sizeof(pthread_t));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
if (stacksize < PTHREAD_STACK_MIN)
|
||||
stacksize = PTHREAD_STACK_MIN;
|
||||
pthread_attr_setstacksize(&attr, stacksize);
|
||||
if (pthread_create(thread, &attr, (pfunction_t)func, args))
|
||||
{
|
||||
free(thread);
|
||||
thread = NULL;
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return (void *)thread;
|
||||
}
|
||||
|
||||
void Sys_WaitOnThread(void *thread)
|
||||
{
|
||||
pthread_join((pthread_t *)thread, NULL);
|
||||
free(thread);
|
||||
}
|
||||
|
||||
/* Mutex calls */
|
||||
void *Sys_CreateMutex(void)
|
||||
{
|
||||
pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
|
||||
if (mutex && !pthread_mutex_init(mutex, NULL))
|
||||
return mutex;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qboolean Sys_TryLockMutex(void *mutex)
|
||||
{
|
||||
return !pthread_mutex_trylock(mutex);
|
||||
}
|
||||
|
||||
qboolean Sys_LockMutex(void *mutex)
|
||||
{
|
||||
return !pthread_mutex_lock(mutex);
|
||||
}
|
||||
|
||||
qboolean Sys_UnlockMutex(void *mutex)
|
||||
{
|
||||
return !pthread_mutex_unlock(mutex);
|
||||
}
|
||||
|
||||
void Sys_DestroyMutex(void *mutex)
|
||||
{
|
||||
pthread_mutex_destroy(mutex);
|
||||
free(mutex);
|
||||
}
|
||||
|
||||
/* Conditional wait calls */
|
||||
typedef struct condvar_s
|
||||
{
|
||||
//FIXME: these should not be pointers.
|
||||
pthread_mutex_t *mutex;
|
||||
pthread_cond_t *cond;
|
||||
} condvar_t;
|
||||
|
||||
void *Sys_CreateConditional(void)
|
||||
{
|
||||
condvar_t *condv;
|
||||
pthread_mutex_t *mutex;
|
||||
pthread_cond_t *cond;
|
||||
|
||||
condv = (condvar_t *)malloc(sizeof(condvar_t));
|
||||
if (!condv)
|
||||
return NULL;
|
||||
|
||||
mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if (!mutex)
|
||||
return NULL;
|
||||
|
||||
cond = (pthread_cond_t *)malloc(sizeof(pthread_cond_t));
|
||||
if (!cond)
|
||||
return NULL;
|
||||
|
||||
if (!pthread_mutex_init(mutex, NULL))
|
||||
{
|
||||
if (!pthread_cond_init(cond, NULL))
|
||||
{
|
||||
condv->cond = cond;
|
||||
condv->mutex = mutex;
|
||||
|
||||
return (void *)condv;
|
||||
}
|
||||
else
|
||||
pthread_mutex_destroy(mutex);
|
||||
}
|
||||
|
||||
free(cond);
|
||||
free(mutex);
|
||||
free(condv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qboolean Sys_LockConditional(void *condv)
|
||||
{
|
||||
return !pthread_mutex_lock(((condvar_t *)condv)->mutex);
|
||||
}
|
||||
|
||||
qboolean Sys_UnlockConditional(void *condv)
|
||||
{
|
||||
return !pthread_mutex_unlock(((condvar_t *)condv)->mutex);
|
||||
}
|
||||
|
||||
qboolean Sys_ConditionWait(void *condv)
|
||||
{
|
||||
return !pthread_cond_wait(((condvar_t *)condv)->cond, ((condvar_t *)condv)->mutex);
|
||||
}
|
||||
|
||||
qboolean Sys_ConditionSignal(void *condv)
|
||||
{
|
||||
return !pthread_cond_signal(((condvar_t *)condv)->cond);
|
||||
}
|
||||
|
||||
qboolean Sys_ConditionBroadcast(void *condv)
|
||||
{
|
||||
return !pthread_cond_broadcast(((condvar_t *)condv)->cond);
|
||||
}
|
||||
|
||||
void Sys_DestroyConditional(void *condv)
|
||||
{
|
||||
condvar_t *cv = (condvar_t *)condv;
|
||||
|
||||
pthread_cond_destroy(cv->cond);
|
||||
pthread_mutex_destroy(cv->mutex);
|
||||
free(cv->cond);
|
||||
free(cv->mutex);
|
||||
free(cv);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Sys_Sleep (double seconds)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ts.tv_sec = (time_t)seconds;
|
||||
seconds -= ts.tv_sec;
|
||||
ts.tv_nsec = seconds * 1000000000.0;
|
||||
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
qboolean Sys_RandomBytes(qbyte *string, int len)
|
||||
{
|
||||
qboolean res;
|
||||
|
|
|
@ -2629,6 +2629,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
extern cvar_t allow_download_root;
|
||||
extern cvar_t allow_download_logs;
|
||||
extern cvar_t allow_download_configs;
|
||||
extern cvar_t allow_download_locs;
|
||||
extern cvar_t allow_download_copyrighted;
|
||||
extern cvar_t allow_download_other;
|
||||
char cleanname[MAX_QPATH];
|
||||
|
@ -2700,9 +2701,12 @@ qboolean SV_AllowDownload (const char *name)
|
|||
if (strncmp(name, "textures/", 9) == 0)
|
||||
return !!allow_download_textures.value;
|
||||
|
||||
if (strncmp(name, "config/", 9) == 0)
|
||||
if (strncmp(name, "config/", 7) == 0)
|
||||
return !!allow_download_configs.value;
|
||||
|
||||
if (strncmp(name, "locs/", 5) == 0)
|
||||
return !!allow_download_locs.value;
|
||||
|
||||
//wads
|
||||
if (strncmp(name, "wads/", 5) == 0)
|
||||
return !!allow_download_wads.value;
|
||||
|
@ -2739,6 +2743,7 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
extern cvar_t sv_demoDir;
|
||||
qboolean protectedpak;
|
||||
qboolean found;
|
||||
static char tmpname[MAX_QPATH];
|
||||
|
||||
if (replacementname)
|
||||
*replacementname = NULL;
|
||||
|
@ -2765,19 +2770,22 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
return -1; //not found
|
||||
}
|
||||
name = *replacementname = va("demos/%s", mvdname);
|
||||
return -4;
|
||||
return DLERR_REDIRECTFILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SV_AllowDownload(name))
|
||||
{
|
||||
Sys_Printf ("%s denied download of %s due to path/name rules\n", host_client->name, name);
|
||||
return -2; //not permitted (even if it exists).
|
||||
return DLERR_PERMISSIONS; //not permitted (even if it exists).
|
||||
}
|
||||
|
||||
//mvdsv demo downloading support. demos/ -> demodir (sets up the server paths)
|
||||
if (!strncmp(name, "demos/", 6))
|
||||
name = va("%s/%s", sv_demoDir.string, name+6);
|
||||
{
|
||||
Q_snprintfz(tmpname, sizeof(tmpname), "%s/%s", sv_demoDir.string, name+6);
|
||||
name = tmpname;
|
||||
}
|
||||
|
||||
if (!strncmp(name, "package/", 8))
|
||||
{
|
||||
|
@ -2786,10 +2794,10 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
{
|
||||
loc->len = VFS_GETLEN(f);
|
||||
VFS_CLOSE(f);
|
||||
return -5; //found package
|
||||
return DLERR_PACKAGE; //found package
|
||||
}
|
||||
else
|
||||
return -1; //not found/unable to open
|
||||
return DLERR_FILENOTFOUND; //not found/unable to open
|
||||
}
|
||||
#ifdef TERRAIN
|
||||
else if (Terrain_LocateSection(name, loc))
|
||||
|
@ -2800,37 +2808,44 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
else
|
||||
found = FS_FLocateFile(name, FSLF_IFFOUND, loc);
|
||||
|
||||
//nexuiz names certain files as .wav but they're really .ogg on disk.
|
||||
if (!found && replacementname)
|
||||
{
|
||||
char ext[8];
|
||||
if (!strcmp(COM_FileExtension(name, ext, sizeof(ext)), "wav"))
|
||||
{
|
||||
char tryogg[MAX_QPATH];
|
||||
COM_StripExtension(name, tryogg, sizeof(tryogg));
|
||||
COM_DefaultExtension(tryogg, ".ogg", sizeof(tryogg));
|
||||
size_t alt;
|
||||
static const char *alternatives[][4] = {
|
||||
//orig-path, orig-ext, new-path, new-ext
|
||||
//nexuiz qc names [sound/]sound/foo.wav but expects sound/foo.ogg and variations of that (the [sound/] is implied, but ignored)
|
||||
{"", "", ".wav", ".ogg"},//nexuiz qc names .wav, but the paks use .ogg
|
||||
{"sound/", "", ".wav", ".wav"}, //nexuiz qc names sound/ but that's normally implied, resulting in doubles that don't exist in the filesystem
|
||||
{"sound/", "", ".wav", ".ogg"} //both of nexuiz's issues
|
||||
};
|
||||
|
||||
found = FS_FLocateFile(tryogg, FSLF_IFFOUND, loc);
|
||||
if (found)
|
||||
{
|
||||
name = *replacementname = va("%s", tryogg);
|
||||
}
|
||||
}
|
||||
}
|
||||
//nexuiz also names files with absolute paths (yet sounds are meant to have an extra prefix)
|
||||
//this results in clients asking for sound/sound/blah.wav (or sound/sound/blah.ogg for nexuiz)
|
||||
if (!found && replacementname)
|
||||
{
|
||||
if (!strncmp(name, "sound/", 6))
|
||||
for (alt = 0; alt < countof(alternatives); alt++)
|
||||
{
|
||||
int result;
|
||||
result = SV_LocateDownload(name+6, loc, replacementname, redirectpaks);
|
||||
if (!result)
|
||||
{ //if that was successful... redirect to it.
|
||||
result = -4;
|
||||
*replacementname = name+6;
|
||||
char tryalt[MAX_QPATH];
|
||||
char ext[8];
|
||||
if (strncmp(name, alternatives[alt][0], strlen(alternatives[alt][0])))
|
||||
{
|
||||
if (*alternatives[alt][2])
|
||||
{
|
||||
if (strcmp(COM_FileExtension(name, ext, sizeof(ext)), alternatives[alt][2]+1))
|
||||
continue;
|
||||
memcpy(tryalt, alternatives[alt][1], strlen(alternatives[alt][1]));
|
||||
COM_StripExtension(name+strlen(alternatives[alt][0]), tryalt+strlen(alternatives[alt][1]), sizeof(tryalt)-strlen(alternatives[alt][1]));
|
||||
COM_DefaultExtension(tryalt, alternatives[alt][3], sizeof(tryalt));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(tryalt, alternatives[alt][1], strlen(alternatives[alt][1]));
|
||||
Q_strncpyz(tryalt+strlen(alternatives[alt][1]), name+strlen(alternatives[alt][0]), sizeof(tryalt)-strlen(alternatives[alt][1]));
|
||||
}
|
||||
found = FS_FLocateFile(tryalt, FSLF_IFFOUND, loc);
|
||||
if (found)
|
||||
{
|
||||
Q_snprintfz(tmpname, sizeof(tmpname), "%s", tryalt);
|
||||
name = *replacementname = tmpname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2844,7 +2859,7 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
if (!allow_download_anymap.value && !strncmp(name, "maps/", 5))
|
||||
{
|
||||
Sys_Printf ("%s denied download of %s - it is in a pak\n", host_client->name, name+8);
|
||||
return -2;
|
||||
return DLERR_PERMISSIONS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2858,7 +2873,7 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
{
|
||||
//its inside a pak file, return the name of this file instead
|
||||
*replacementname = pakname;
|
||||
return -4; //redirect
|
||||
return DLERR_REDIRECTPACK; //redirect
|
||||
}
|
||||
else
|
||||
Con_Printf("Failed to read %s\n", pakname);
|
||||
|
@ -2870,12 +2885,12 @@ static int SV_LocateDownload(char *name, flocation_t *loc, char **replacementnam
|
|||
if (!allow_download_pakcontents.value)
|
||||
{
|
||||
Sys_Printf ("%s denied download of %s - it is in a pak\n", host_client->name, name+8);
|
||||
return -2;
|
||||
return DLERR_PERMISSIONS;
|
||||
}
|
||||
}
|
||||
|
||||
if (replacementname && *replacementname)
|
||||
return -4;
|
||||
return DLERR_REDIRECTPACK;
|
||||
return 0;
|
||||
}
|
||||
return -1; //not found
|
||||
|
@ -2980,7 +2995,7 @@ void SV_BeginDownload_f(void)
|
|||
|
||||
result = SV_LocateDownload(name, &loc, &redirection, false);
|
||||
|
||||
if (result == -5)
|
||||
if (result == DLERR_PACKAGE)
|
||||
{
|
||||
//package download
|
||||
result = 0;
|
||||
|
@ -2989,11 +3004,11 @@ void SV_BeginDownload_f(void)
|
|||
else
|
||||
{
|
||||
//redirection protocol-specific code goes here.
|
||||
if (result == -4)
|
||||
if (result == DLERR_REDIRECTPACK || result == DLERR_REDIRECTFILE)
|
||||
{
|
||||
#ifdef PEXT_CHUNKEDDOWNLOADS
|
||||
qboolean isezquake = !strncmp(Info_ValueForKey(host_client->userinfo, "*client"), "ezQuake", 7);
|
||||
if ((host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) && !isezquake)
|
||||
//ezquake etc cannot cope with proper redirects
|
||||
if ((host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) && (host_client->fteprotocolextensions & PEXT_CSQC))
|
||||
{
|
||||
//redirect the client (before the message saying download failed)
|
||||
// char *s = va("dlsize \"%s\" r \"%s\"\n", name, redirection);
|
||||
|
@ -3002,13 +3017,14 @@ void SV_BeginDownload_f(void)
|
|||
|
||||
ClientReliableWrite_Begin (host_client, svc_download, 10+strlen(name));
|
||||
ClientReliableWrite_Long (host_client, -1);
|
||||
ClientReliableWrite_Long (host_client, result);
|
||||
ClientReliableWrite_Long (host_client, DLERR_REDIRECTFILE);
|
||||
ClientReliableWrite_String (host_client, redirection);
|
||||
return;
|
||||
}
|
||||
else
|
||||
else if (result == DLERR_REDIRECTFILE && host_client->protocol == SCP_QUAKEWORLD)
|
||||
{ //crappy hack for crappy clients. tell them to download the new file instead without telling them about any failure.
|
||||
//this will seriously mess with any download queues or anything like that
|
||||
//this doesn't apply to packages, because these shitty clients won't know to actually load said packages before attempting to request more files, meaning the same package gets downloaded 80 times and then only actually used AFTER they restart the client.
|
||||
char *s = va("download \"%s\"\n", redirection);
|
||||
ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(s));
|
||||
ClientReliableWrite_String (host_client, s);
|
||||
|
@ -3032,14 +3048,23 @@ void SV_BeginDownload_f(void)
|
|||
char *error;
|
||||
switch(result)
|
||||
{
|
||||
case DLERR_FILENOTFOUND:
|
||||
default:
|
||||
result = DLERR_FILENOTFOUND;
|
||||
error = "Download could not be found\n";
|
||||
break;
|
||||
case -2:
|
||||
case DLERR_UNKNOWN:
|
||||
error = "Filesystem error\n";
|
||||
break;
|
||||
case DLERR_PERMISSIONS:
|
||||
error = "Download permission denied\n";
|
||||
break;
|
||||
case -4:
|
||||
result = -1;
|
||||
case DLERR_REDIRECTFILE:
|
||||
result = DLERR_PERMISSIONS;
|
||||
error = "Client doesn't support file redirection\n";
|
||||
break;
|
||||
case DLERR_REDIRECTPACK:
|
||||
result = DLERR_PERMISSIONS;
|
||||
error = "Package contents not available individually\n";
|
||||
break;
|
||||
}
|
||||
|
@ -3849,6 +3874,7 @@ qboolean SV_UserInfoIsBasic(char *infoname)
|
|||
"skin",
|
||||
"topcolor",
|
||||
"bottomcolor",
|
||||
"chat", //ezquake's afk indicators
|
||||
|
||||
NULL};
|
||||
|
||||
|
@ -3914,12 +3940,14 @@ void SV_SetInfo_f (void)
|
|||
if (!strcmp(Info_ValueForKey(host_client->userinfo, key), oldval))
|
||||
return; // key hasn't changed
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (svs.gametype == GT_QUAKE2)
|
||||
{
|
||||
ge->ClientUserinfoChanged (host_client->q2edict, host_client->userinfo); //tell the gamecode
|
||||
SV_ExtractFromUserinfo(host_client, true); //let the server routines know
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// process any changed values
|
||||
SV_ExtractFromUserinfo (host_client, true);
|
||||
|
@ -6864,7 +6892,7 @@ void SV_ReadQCRequest(void)
|
|||
{
|
||||
int e;
|
||||
char args[8];
|
||||
char *rname;
|
||||
char *rname, *fname;
|
||||
func_t f;
|
||||
int i;
|
||||
globalvars_t *pr_globals;
|
||||
|
@ -6924,10 +6952,10 @@ done:
|
|||
args[i] = 0;
|
||||
rname = MSG_ReadString();
|
||||
if (i)
|
||||
rname = va("CSEv_%s_%s", rname, args);
|
||||
fname = va("CSEv_%s_%s", rname, args);
|
||||
else
|
||||
rname = va("CSEv_%s", rname);
|
||||
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
||||
fname = va("CSEv_%s", rname);
|
||||
f = PR_FindFunction(svprogfuncs, fname, PR_ANY);
|
||||
if (!f)
|
||||
{
|
||||
if (i)
|
||||
|
@ -6942,7 +6970,7 @@ done:
|
|||
PR_ExecuteProgram(svprogfuncs, f);
|
||||
}
|
||||
else
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "qcrequest \"%s\" not supported\n", rname);
|
||||
SV_ClientPrintf(host_client, PRINT_HIGH, "qcrequest \"%s\" not supported\n", fname);
|
||||
}
|
||||
|
||||
void SV_AckEntityFrame(client_t *cl, int framenum)
|
||||
|
|
|
@ -29,6 +29,7 @@ char shaders[][64] =
|
|||
"postproc_panorama",
|
||||
"postproc_laea",
|
||||
"postproc_stereographic",
|
||||
"postproc_equirectangular",
|
||||
"fxaa",
|
||||
"rtlight",
|
||||
"underwaterwarp",
|
||||
|
|
|
@ -996,13 +996,13 @@ void SW_SCR_UpdateScreen(void)
|
|||
V_UpdatePalette (false);
|
||||
}
|
||||
|
||||
void SW_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
|
||||
void SW_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
|
||||
{
|
||||
}
|
||||
void SW_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray)
|
||||
void SW_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
|
||||
{
|
||||
}
|
||||
void SW_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray)
|
||||
void SW_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray)
|
||||
{
|
||||
}
|
||||
void SW_VBO_Destroy(vboarray_t *vearray)
|
||||
|
|
|
@ -258,25 +258,25 @@ qboolean SWAppActivate(BOOL fActive, BOOL minimize)
|
|||
{
|
||||
static BOOL sound_active;
|
||||
|
||||
if (ActiveApp == fActive && Minimized == minimize)
|
||||
if (vid.activeapp == fActive && Minimized == minimize)
|
||||
return false; //so windows doesn't crash us over and over again.
|
||||
|
||||
ActiveApp = fActive;
|
||||
vid.activeapp = fActive;
|
||||
Minimized = minimize;
|
||||
|
||||
// enable/disable sound on focus gain/loss
|
||||
if (!ActiveApp && sound_active)
|
||||
if (!vid.activeapp && sound_active)
|
||||
{
|
||||
S_BlockSound ();
|
||||
sound_active = false;
|
||||
}
|
||||
else if (ActiveApp && !sound_active)
|
||||
else if (vid.activeapp && !sound_active)
|
||||
{
|
||||
S_UnblockSound ();
|
||||
sound_active = true;
|
||||
}
|
||||
|
||||
INS_UpdateGrabs(false, ActiveApp);
|
||||
INS_UpdateGrabs(false, vid.activeapp);
|
||||
|
||||
/*
|
||||
if (fActive)
|
||||
|
@ -704,7 +704,7 @@ void SW_VID_SwapBuffers(void)
|
|||
DIB_SwapBuffers();
|
||||
framenumber++;
|
||||
|
||||
INS_UpdateGrabs(false, ActiveApp);
|
||||
INS_UpdateGrabs(false, vid.activeapp);
|
||||
|
||||
// memset( pDIBBase, 0, vid.pixelwidth * vid.pixelheight * 4);
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ extern int gammaworks;
|
|||
|
||||
extern qboolean vid_isfullscreen;
|
||||
|
||||
qboolean ActiveApp;
|
||||
qboolean mouseactive;
|
||||
extern qboolean mouseusedforgui;
|
||||
|
||||
|
@ -221,7 +220,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
return false;
|
||||
}
|
||||
|
||||
ActiveApp = true;
|
||||
vid.activeapp = true;
|
||||
|
||||
GL_Init(GLVID_getsdlglfunction);
|
||||
|
||||
|
@ -236,7 +235,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
|
||||
void GLVID_DeInit (void)
|
||||
{
|
||||
ActiveApp = false;
|
||||
vid.activeapp = false;
|
||||
|
||||
emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -261,9 +260,9 @@ void GLVID_SwapBuffers (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((key_dest == key_game||mouseusedforgui) && ActiveApp)
|
||||
if ((key_dest == key_game||mouseusedforgui) && vid.activeapp)
|
||||
IN_ActivateMouse ();
|
||||
else if (!(key_dest == key_game || mouseusedforgui) || !ActiveApp)
|
||||
else if (!(key_dest == key_game || mouseusedforgui) || !vid.activeapp)
|
||||
IN_DeactivateMouse ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ nonstatic void(mitem_desktop desktop) M_Main =
|
|||
local mitem_exmenu m;
|
||||
|
||||
//no dupes please.
|
||||
m = (mitem_exmenu)desktop.findchild(_("Main Menu"));
|
||||
m = (mitem_exmenu)desktop.findchildtext(_("Main Menu"));
|
||||
if (m)
|
||||
{
|
||||
m.totop();
|
||||
|
|
|
@ -23,7 +23,7 @@ nonstatic void(mitem_desktop desktop) M_NewGame =
|
|||
if (gametype == "sp")
|
||||
{
|
||||
//single player has no options. the start map itself gives skill+episode options.
|
||||
localcmd("\ndeathmatch 0; coop 0; maxplayers 0; timelimit 0; fraglimit 0; teamplay 0; map start\n");
|
||||
localcmd("\ndeathmatch 0; coop 0; maxplayers 0; timelimit 0; fraglimit 0; teamplay 0; samelevel 0; map start\n");
|
||||
return;
|
||||
}
|
||||
if (gametype == "begin")
|
||||
|
|
|
@ -35,7 +35,7 @@ nonstatic void(mitem_desktop desktop) M_Options =
|
|||
|
||||
//and show the options.
|
||||
fr.add(spawn(mitem_text, item_text:"Graphical Presets", item_command:"m_pop;m_preset", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
fr.add(spawn(mitem_text, item_text:"Game Presets", item_command:"m_pop;m_configs", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
fr.add(spawn(mitem_text, item_text:"Game Configs", item_command:"m_pop;m_configs", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
fr.add(spawn(mitem_text, item_text:"Basic Setup", item_command:"m_pop;m_basicopts", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
fr.add(spawn(mitem_text, item_text:"Audio", item_command:"m_pop;m_audio", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
fr.add(spawn(mitem_text, item_text:"Video", item_command:"m_pop;m_video", item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [0, 16]); pos += 16;
|
||||
|
|
|
@ -3,24 +3,8 @@ Uses the engine command to apply the preset, and tries an exec instead if a conf
|
|||
Doesn't track the current one or anything.
|
||||
Really simple and stupid menu.
|
||||
no background tint, so the game is still visible so you can preview it.
|
||||
|
||||
you should probably remove the fps_preset part. I left it in so that I don't have to bother with providing cfg files. note that this isn't a valid solution for dp, but whatever.
|
||||
the great thing about providing source is that you can change it.
|
||||
you can instead just shove your preset settings directly into the quotes instead of exec.
|
||||
*/
|
||||
|
||||
struct
|
||||
{
|
||||
string name;
|
||||
string preset;
|
||||
string config;
|
||||
} configs[] =
|
||||
{
|
||||
// {"Simple Deathmatch", "simple", "configs/game_simple.cfg"},
|
||||
{"Deathmatch", "deathmatch", "configs/game_deathmatch.cfg"},
|
||||
{"Mod Compatibility", "compat", "configs/game_compat.cfg"},
|
||||
{"Standard", "normal", "configs/game_normal.cfg"}
|
||||
};
|
||||
|
||||
nonstatic void(mitem_desktop desktop) M_Configs =
|
||||
{
|
||||
|
@ -41,13 +25,24 @@ nonstatic void(mitem_desktop desktop) M_Configs =
|
|||
mitem_frame fr = spawn(mitem_frame, item_flags: IF_SELECTABLE, frame_hasscroll:TRUE);
|
||||
m.add(fr, RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MID | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, -h], [0, h*2]);
|
||||
|
||||
float fl = RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN;
|
||||
|
||||
//add the options
|
||||
for (i = 0; i < configs.length; i++)
|
||||
|
||||
|
||||
float fs, y=0;
|
||||
fs = search_begin("configs/game_*.cfg", TRUE, TRUE);
|
||||
float c = search_getsize(fs);
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
fr.add(spawn(mitem_text, item_text:configs[i].name, item_command:sprintf("exec \"%s\"", configs[i].config), item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, i*16], [100, 16]);
|
||||
string fname = search_getfilename(fs, i);
|
||||
string iname = substring(fname, 10, -5);
|
||||
string dname = GetFirstLineComment(fname, iname);
|
||||
iname = sprintf("exec \"%s\"", iname);
|
||||
if (dname && !fr.findchildcmd(iname))
|
||||
fr.add(spawn(mitem_text, item_text:dname, item_command:iname, item_scale:16, item_flags:IF_CENTERALIGN), RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, y+=16], '100 16');
|
||||
}
|
||||
search_end(fs);
|
||||
if (c <= 0)
|
||||
fr.add(spawn(mitem_text, item_text:"No configs found", item_scale:16, item_flags:IF_CENTERALIGN), RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, y], '100 16');
|
||||
|
||||
//random art for style
|
||||
#if 1//def CSQC
|
||||
|
|
|
@ -19,9 +19,9 @@ nonstatic void(mitem_desktop desktop) M_Options_Hud =
|
|||
mitem_frame fr = spawn(mitem_frame, item_flags: IF_SELECTABLE, frame_hasscroll:TRUE);
|
||||
m.add(fr, RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MID | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, -h], [0, h*2]);
|
||||
|
||||
float fs = search_begin("configs/hud_*.cfg", TRUE, TRUE);
|
||||
float fs = search_begin("hud/*.cfg", TRUE, TRUE);
|
||||
float fc = search_getsize(fs);
|
||||
|
||||
|
||||
//add the options
|
||||
for (i = 0, float y = 0; i < fc; i++)
|
||||
{
|
||||
|
|
|
@ -48,16 +48,6 @@ class particlesmenu : mitem_frame
|
|||
thelist = strtrim(strcat(thelist, " ", cmd));
|
||||
UpdateSelections();
|
||||
};
|
||||
//to avoid dupes
|
||||
nonvirtual float(string n) HasChild =
|
||||
{
|
||||
for (mitem ch = item_children; ch; ch = ch.item_next)
|
||||
{
|
||||
if (!strcasecmp(n, ch.item_command))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
};
|
||||
};
|
||||
|
||||
string(string fname, string dflt) GetFirstLineComment =
|
||||
|
@ -124,7 +114,7 @@ nonstatic void(mitem_desktop desktop) M_Options_Particles =
|
|||
string fname = search_getfilename(fs, i);
|
||||
string iname = substring(fname, 10, -5);
|
||||
string dname = GetFirstLineComment(fname, iname);
|
||||
if (dname && !fr.HasChild(iname))
|
||||
if (dname && !fr.findchildcmd(iname))
|
||||
fr.add(spawn(mitem_text, item_text:dname, item_command:iname, item_scale:8, item_flags:IF_CENTERALIGN), RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, y+=8], '0 8');
|
||||
}
|
||||
search_end(fs);
|
||||
|
@ -134,7 +124,7 @@ nonstatic void(mitem_desktop desktop) M_Options_Particles =
|
|||
string fname = search_getfilename(fs, i);
|
||||
string iname = substring(fname, 10, -5);
|
||||
string dname = GetFirstLineComment(fname, iname);
|
||||
if (dname && !fr.HasChild(iname))
|
||||
if (dname && !fr.findchildcmd(iname))
|
||||
fr.add(spawn(mitem_text, item_text:dname, item_command:iname, item_scale:8, item_flags:IF_CENTERALIGN), RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, y+=8], '0 8');
|
||||
}
|
||||
search_end(fs);
|
||||
|
|
|
@ -63,14 +63,30 @@ nonstatic void(mitem_desktop desktop) M_Preset =
|
|||
m.add(fr, RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MID | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN, [0, -h], [0, h*2]);
|
||||
float fl = RS_X_MIN_PARENT_MIN|RS_Y_MIN_PARENT_MIN | RS_X_MAX_PARENT_MAX|RS_Y_MAX_OWN_MIN;
|
||||
|
||||
//add the options
|
||||
for (i = 0, float pos = 0; i < presets.length; i++)
|
||||
float fs, y=0;
|
||||
fs = search_begin("configs/preset_*.cfg", TRUE, TRUE);
|
||||
float c = search_getsize(fs);
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
if (checkfileexists(presets[i].config)) //file exists, try to exec it
|
||||
fr.add(spawn(mitem_text, item_text:presets[i].name, item_command:sprintf("exec \"%s\";vid_reload", presets[i].config), item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [100, 16]);
|
||||
else //okay, no file exists, depend upon the engine for it.
|
||||
string fname = search_getfilename(fs, i);
|
||||
string iname = substring(fname, 10, -5);
|
||||
string dname = GetFirstLineComment(fname, iname);
|
||||
iname = sprintf("exec \"%s\";vid_reload", iname);
|
||||
if (dname && !fr.findchildcmd(iname))
|
||||
{
|
||||
fr.add(spawn(mitem_text, item_text:dname, item_command:iname, item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, y], '100 16');
|
||||
y+=16;
|
||||
}
|
||||
}
|
||||
search_end(fs);
|
||||
if (c <= 0)
|
||||
{
|
||||
//add the default options
|
||||
for (i = 0, float pos = 0; i < presets.length; i++)
|
||||
{
|
||||
fr.add(spawn(mitem_text, item_text:presets[i].name, item_command:sprintf("fps_preset %s", presets[i].preset), item_scale:16, item_flags:IF_CENTERALIGN), fl, [0, pos], [100, 16]);
|
||||
pos += 16;
|
||||
pos += 16;
|
||||
}
|
||||
}
|
||||
|
||||
//random art for style
|
||||
|
|
|
@ -372,7 +372,7 @@ nonstatic void(mitem_desktop desktop) M_Servers =
|
|||
}
|
||||
#endif
|
||||
|
||||
o = (mitem_menu)desktop.findchild(_("Servers List"));
|
||||
o = (mitem_menu)desktop.findchildtext(_("Servers List"));
|
||||
if (o)
|
||||
o.totop();
|
||||
else
|
||||
|
|
|
@ -25,15 +25,18 @@ float sb_showscores;
|
|||
|
||||
void() mitem_desktop::mitem_desktop =
|
||||
{
|
||||
#define menu_font_win autocvar(menu_font_win, "cour")
|
||||
#define menu_font_win autocvar(menu_font_win, "")
|
||||
#define menu_font autocvar(menu_font, "")
|
||||
queryscreensize();
|
||||
|
||||
//make sure we have a font that can cope with slightly up-scaled stuff.
|
||||
//windows is special because we can load from the system fonts
|
||||
if (menu_font_win != "" && !strncmp(cvar_string("sys_platform"), "Win", 3))
|
||||
drawfont = loadfont("", menu_font_win, "8 12 16", 0);
|
||||
drawfont = loadfont("", menu_font_win, "8 12 16", -1);
|
||||
else if (menu_font != "")
|
||||
drawfont = loadfont("", menu_font, "8 12 16", -1);
|
||||
else
|
||||
drawfont = loadfont("", menu_font, "8 12 16", 0);
|
||||
drawfont = 0;
|
||||
|
||||
item_text = "desktop";
|
||||
if (!item_flags)
|
||||
|
|
|
@ -35,7 +35,8 @@ class mitem_frame : mitem
|
|||
vector item_framesize; //x=sides, y=top, z=bottom
|
||||
float frame_hasscroll;
|
||||
|
||||
static mitem(string title) findchild;
|
||||
static mitem(string title) findchildtext;
|
||||
static mitem(string title) findchildcmd;
|
||||
static void(mitem newitem, float originflags, vector originmin, vector originmax) add;
|
||||
static void(mitem newitem, vector pos) adda;
|
||||
static void(mitem newitem, vector originmin, vector originmax) addm;
|
||||
|
@ -56,7 +57,7 @@ void(mitem fromitem, string cmd) mitem_frame::item_execcommand =
|
|||
localcmd(strcat(cmd, "\n"));
|
||||
};
|
||||
|
||||
mitem(string title) mitem_frame::findchild =
|
||||
mitem(string title) mitem_frame::findchildtext =
|
||||
{
|
||||
mitem ch;
|
||||
for (ch = item_children; ch; ch = ch.item_next)
|
||||
|
@ -66,6 +67,17 @@ mitem(string title) mitem_frame::findchild =
|
|||
}
|
||||
return __NULL__;
|
||||
};
|
||||
mitem(string title) mitem_frame::findchildcmd =
|
||||
{
|
||||
mitem ch;
|
||||
for (ch = item_children; ch; ch = ch.item_next)
|
||||
{
|
||||
if (ch.item_command == title)
|
||||
return ch;
|
||||
}
|
||||
return __NULL__;
|
||||
};
|
||||
|
||||
|
||||
//adds an item with the desired origin settings
|
||||
void(mitem newitem, float originflags, vector originmin, vector originmax) mitem_frame::add =
|
||||
|
|
Loading…
Reference in a new issue