fix colormod
added frag message filter, and dedicated frag tracker. added 'windowed consoles' for social-type stuff without depending upon csqc mods for it. added in_deviceids command which allows listing/renumbering device ids. slider widgets now support inverted ranges, so gamma selection isn't so weird. fix top/bottom colour selection bug. software banding feature is now part of the 'software' preset (now that it supports mipmaps). support for loading .maps, and editing their brushes etc (with appropriate qc mod). 'map mymap.map' to use. expect problems with missing wads and replacement textures overriding them and messing up texture scales. snd_inactive is now default. fix threading issue with wavs, no more error from 0-sample-but-otherwise-valid wavs. added -makeinstaller option to embed a manifest inside the exe (and icon). the resulting program will insist on installing the game if its run from outside a valid basedir. framegroup support for q1mdl. textures are now loaded on multiple worker threads, for reduced load times. moo har har. netgraph shows packet+byte rates too. added r_lightstylescale, pretty similar to contrast, but doesn't impose any framerate cost, but may have overbrighting issues. r_softwarebanding now works on q2bsp too. fixed crepuscular lights. gzip transfer encoding is performed while downloading, instead of inducing stalls. FINALLY fix ezquake download compat issue (dimman found the issue). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4851 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
18de6445ba
commit
2201b920c8
107 changed files with 6483 additions and 1851 deletions
|
@ -46,6 +46,7 @@ cvar_t cl_selfcam = SCVAR("cl_selfcam", "1");
|
|||
//cvar_t cl_camera_maxpitch = {"cl_camera_maxpitch", "10" };
|
||||
//cvar_t cl_camera_maxyaw = {"cl_camera_maxyaw", "30" };
|
||||
|
||||
static int Cam_FindSortedPlayer(int number);
|
||||
|
||||
int selfcam=1;
|
||||
|
||||
|
@ -524,6 +525,15 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
if (cmd->impulse)
|
||||
{
|
||||
int pl = cmd->impulse;
|
||||
|
||||
#if 1
|
||||
do
|
||||
{
|
||||
Cam_Lock(pv, Cam_FindSortedPlayer(pl));
|
||||
pv++;
|
||||
pl++;
|
||||
} while (pv >= &cl.playerview[0] && pv < &cl.playerview[cl.splitclients]);
|
||||
#else
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
if (i == MAX_CLIENTS)
|
||||
|
@ -550,6 +560,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -612,7 +623,9 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
do
|
||||
{
|
||||
s = &cl.players[i];
|
||||
if (s->name[0] && !s->spectator)
|
||||
//players with userid 0 are typically bots.
|
||||
//trying to spectate such bots just does not work (we have no idea which entity slot the bot is actually using, so don't try to track them).
|
||||
if (s->name[0] && !s->spectator && s->userid)
|
||||
{
|
||||
Cam_Lock(pv, i);
|
||||
return;
|
||||
|
@ -622,7 +635,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
// stay on same guy?
|
||||
i = pv->cam_spec_track;
|
||||
s = &cl.players[i];
|
||||
if (s->name[0] && !s->spectator)
|
||||
if (s->name[0] && !s->spectator && s->userid)
|
||||
{
|
||||
Cam_Lock(pv, i);
|
||||
return;
|
||||
|
@ -642,11 +655,46 @@ void Cam_Reset(void)
|
|||
}
|
||||
}
|
||||
|
||||
static int QDECL Cam_SortPlayers(const void *p1,const void *p2)
|
||||
{
|
||||
const player_info_t *a = *(player_info_t**)p1;
|
||||
const player_info_t *b = *(player_info_t**)p2;
|
||||
|
||||
if (!*a->team)
|
||||
return *b->team;
|
||||
if (!*b->team)
|
||||
return -*a->team;
|
||||
// if (a->spectator || b->spectator)
|
||||
// return a->spectator - b->spectator;
|
||||
return Q_strcasecmp(a->team, b->team);
|
||||
}
|
||||
static int Cam_FindSortedPlayer(int number)
|
||||
{
|
||||
player_info_t *playerlist[MAX_CLIENTS], *s;
|
||||
int i;
|
||||
int slots;
|
||||
number--;
|
||||
for (slots = 0, i = 0; i < cl.allocated_client_slots; i++)
|
||||
{
|
||||
s = &cl.players[i];
|
||||
if (s->name[0] && !s->spectator)
|
||||
playerlist[slots++] = s;
|
||||
}
|
||||
if (!slots)
|
||||
return 0;
|
||||
// if (number > slot)
|
||||
// return cl.allocated_client_slots; //error
|
||||
|
||||
qsort(playerlist, slots, sizeof(playerlist[0]), Cam_SortPlayers);
|
||||
return playerlist[number % slots] - cl.players;
|
||||
}
|
||||
|
||||
void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[seat];
|
||||
int slot;
|
||||
int slot, sortednum;
|
||||
player_info_t *s;
|
||||
char *e;
|
||||
|
||||
if (seat >= MAX_SPLITS)
|
||||
return;
|
||||
|
@ -669,12 +717,17 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg)
|
|||
return;
|
||||
}
|
||||
|
||||
// search nicks first
|
||||
for (slot = 0; slot < cl.allocated_client_slots; slot++)
|
||||
if (*plrarg == '#' && (slot=strtoul(plrarg+1, &e, 10)) && !*e)
|
||||
slot = Cam_FindSortedPlayer(slot);
|
||||
else
|
||||
{
|
||||
s = &cl.players[slot];
|
||||
if (s->name[0] && !s->spectator && !Q_strcasecmp(s->name, plrarg))
|
||||
break;
|
||||
// search nicks first
|
||||
for (slot = 0; slot < cl.allocated_client_slots; slot++)
|
||||
{
|
||||
s = &cl.players[slot];
|
||||
if (s->name[0] && !s->spectator && !Q_strcasecmp(s->name, plrarg))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slot == cl.allocated_client_slots)
|
||||
|
|
|
@ -3522,9 +3522,15 @@ void CL_LinkPacketEntities (void)
|
|||
//set scale
|
||||
ent->scale = state->scale/16.0;
|
||||
#endif
|
||||
ent->shaderRGBAf[0] = (state->colormod[0]*8.0f)/256;
|
||||
ent->shaderRGBAf[1] = (state->colormod[1]*8.0f)/256;
|
||||
ent->shaderRGBAf[2] = (state->colormod[2]*8.0f)/256;
|
||||
if (state->colormod[0] == 32 && state->colormod[1] == 32 && state->colormod[2] == 32)
|
||||
ent->shaderRGBAf[0] = ent->shaderRGBAf[1] = ent->shaderRGBAf[2] = 1;
|
||||
else
|
||||
{
|
||||
ent->flags |= RF_FORCECOLOURMOD;
|
||||
ent->shaderRGBAf[0] = (state->colormod[0]*8.0f)/256;
|
||||
ent->shaderRGBAf[1] = (state->colormod[1]*8.0f)/256;
|
||||
ent->shaderRGBAf[2] = (state->colormod[2]*8.0f)/256;
|
||||
}
|
||||
ent->shaderRGBAf[3] = state->trans/255.0f;
|
||||
|
||||
#ifdef PEXT_FATNESS
|
||||
|
|
|
@ -148,7 +148,7 @@ kbutton_t in_rollleft, in_rollright, in_up, in_down;
|
|||
|
||||
kbutton_t in_button3, in_button4, in_button5, in_button6, in_button7, in_button8;
|
||||
|
||||
#define IN_IMPULSECACHE 256
|
||||
#define IN_IMPULSECACHE 32
|
||||
int in_impulse[MAX_SPLITS][IN_IMPULSECACHE];
|
||||
int in_nextimpulse[MAX_SPLITS];
|
||||
int in_impulsespending[MAX_SPLITS];
|
||||
|
@ -837,7 +837,6 @@ CL_FinishMove
|
|||
void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum)
|
||||
{
|
||||
int i;
|
||||
int bits;
|
||||
|
||||
CL_ClampPitch(pnum);
|
||||
|
||||
|
@ -1463,7 +1462,7 @@ qboolean CLQW_SendCmd (sizebuf_t *buf)
|
|||
cmd->cursor_start[0] || cmd->cursor_start[1] || cmd->cursor_start[2] ||
|
||||
cmd->cursor_impact[0] || cmd->cursor_impact[1] || cmd->cursor_impact[2])
|
||||
{
|
||||
MSG_WriteByte (buf, clc_prydoncursor);
|
||||
MSG_WriteByte (buf, clcfte_prydoncursor);
|
||||
MSG_WriteShort(buf, cmd->cursor_screen[0] * 32767.0f);
|
||||
MSG_WriteShort(buf, cmd->cursor_screen[1] * 32767.0f);
|
||||
MSG_WriteFloat(buf, cmd->cursor_start[0]);
|
||||
|
@ -1895,7 +1894,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
if (cls.protocol == CP_QUAKE2)
|
||||
S_Voip_Transmit(clcq2_voicechat, &buf);
|
||||
else
|
||||
S_Voip_Transmit(clc_voicechat, &buf);
|
||||
S_Voip_Transmit(clcfte_voicechat, &buf);
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
|
@ -160,6 +160,7 @@ cvar_t cl_countpendingpl = CVARD("cl_countpendingpl", "0", "If set to 1, packet
|
|||
|
||||
cvar_t cl_standardchat = CVARFD("cl_standardchat", "0", CVAR_ARCHIVE, "Disables auto colour coding in chat messages.");
|
||||
cvar_t msg_filter = CVARD("msg_filter", "0", "Filter out chat messages: 0=neither. 1=broadcast chat. 2=team chat. 3=all chat.");
|
||||
cvar_t msg_filter_frags = CVARD("msg_filter_frags", "0", "Prevents frag messages from appearing on the console.");
|
||||
cvar_t cl_standardmsg = CVARFD("cl_standardmsg", "0", CVAR_ARCHIVE, "Disables auto colour coding in console prints.");
|
||||
cvar_t cl_parsewhitetext = CVARD("cl_parsewhitetext", "1", "When parsing chat messages, enable support for messages like: red{white}red");
|
||||
|
||||
|
@ -362,7 +363,7 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t *adr)
|
|||
|
||||
connectinfo.time = realtime; // for retransmit requests
|
||||
|
||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cconnect\\protocol\\darkplaces 3\\challenge\\%s", 255, 255, 255, 255, challenge);
|
||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cconnect\\protocol\\darkplaces 3\\protocols\\DP7 DP6 DP5\\challenge\\%s", 255, 255, 255, 255, challenge);
|
||||
|
||||
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
|
||||
|
||||
|
@ -718,12 +719,12 @@ void CL_CheckForResend (void)
|
|||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "q3"))
|
||||
cls.protocol = CP_QUAKE3;
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp6"))
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp6") || !strcmp(cl_loopbackprotocol.string, "dpp6"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_DP7;
|
||||
cls.protocol_nq = CPNQ_DP6;
|
||||
}
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp7"))
|
||||
else if (!strcmp(cl_loopbackprotocol.string, "dp7") || !strcmp(cl_loopbackprotocol.string, "dpp7"))
|
||||
{
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_DP7;
|
||||
|
@ -1817,6 +1818,8 @@ void CL_CheckServerInfo(void)
|
|||
cls.allow_fbskins = atof(s);
|
||||
else if (cl.teamfortress)
|
||||
cls.allow_fbskins = 0;
|
||||
else
|
||||
cls.allow_fbskins = 1;
|
||||
|
||||
s = Info_ValueForKey(cl.serverinfo, "*cheats");
|
||||
if (cl.spectator || cls.demoplayback || !stricmp(s, "on"))
|
||||
|
@ -2335,7 +2338,7 @@ drop to full console
|
|||
void CL_Changing_f (void)
|
||||
{
|
||||
char *mapname = Cmd_Argv(1);
|
||||
if (cls.download) // don't change when downloading
|
||||
if (cls.download && cls.download->method <= DL_QWPENDING) // don't change when downloading
|
||||
return;
|
||||
|
||||
cls.demoseeking = false; //don't seek over it
|
||||
|
@ -2370,7 +2373,7 @@ The server is changing levels
|
|||
*/
|
||||
void CL_Reconnect_f (void)
|
||||
{
|
||||
if (cls.download) // don't change when downloading
|
||||
if (cls.download && cls.download->method <= DL_QWPENDING) // don't change when downloading
|
||||
return;
|
||||
#ifdef NQPROT
|
||||
if (cls.protocol == CP_NETQUAKE && Cmd_FromGamecode())
|
||||
|
@ -2528,7 +2531,7 @@ void CL_ConnectionlessPacket (void)
|
|||
if (c == S2C_CHALLENGE)
|
||||
{
|
||||
static unsigned int lasttime = 0xdeadbeef;
|
||||
netadr_t lastadr;
|
||||
static netadr_t lastadr;
|
||||
unsigned int curtime = Sys_Milliseconds();
|
||||
unsigned long pext = 0, pext2 = 0, huffcrc=0, mtu=0;
|
||||
Con_TPrintf ("challenge\n");
|
||||
|
@ -2831,6 +2834,8 @@ client_connect: //fixme: make function
|
|||
cls.challenge = connectinfo.challenge;
|
||||
Netchan_Setup (NS_CLIENT, &cls.netchan, &net_from, cls.qport);
|
||||
cls.netchan.fragmentsize = connectinfo.mtu;
|
||||
if (connectinfo.mtu >= 64)
|
||||
cls.netchan.message.maxsize = sizeof(cls.netchan.message_buf);
|
||||
#ifdef HUFFNETWORK
|
||||
cls.netchan.compresstable = Huff_CompressionCRC(connectinfo.compresscrc);
|
||||
#else
|
||||
|
@ -3635,10 +3640,11 @@ void CL_Init (void)
|
|||
|
||||
Cvar_Register (&requiredownloads, cl_controlgroup);
|
||||
Cvar_Register (&cl_standardchat, cl_controlgroup);
|
||||
Cvar_Register (&msg_filter, cl_controlgroup);
|
||||
Cvar_Register (&msg_filter, cl_controlgroup);
|
||||
Cvar_Register (&msg_filter_frags, cl_controlgroup);
|
||||
Cvar_Register (&cl_standardmsg, cl_controlgroup);
|
||||
Cvar_Register (&cl_parsewhitetext, cl_controlgroup);
|
||||
Cvar_Register (&cl_nopext, cl_controlgroup);
|
||||
Cvar_Register (&cl_nopext, cl_controlgroup);
|
||||
Cvar_Register (&cl_pext_mask, cl_controlgroup);
|
||||
|
||||
Cvar_Register (&cl_splitscreen, cl_controlgroup);
|
||||
|
@ -4258,7 +4264,7 @@ void Host_DoRunFile(hrf_t *f)
|
|||
// if (f->flags & HRF_DOWNLOADED)
|
||||
man->blockupdate = true;
|
||||
BZ_Free(fdata);
|
||||
FS_ChangeGame(man, true);
|
||||
FS_ChangeGame(man, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4457,7 +4463,7 @@ Runs all active servers
|
|||
extern cvar_t cl_netfps;
|
||||
extern cvar_t cl_sparemsec;
|
||||
|
||||
qboolean startuppending;
|
||||
int startuppending;
|
||||
void CL_StartCinematicOrMenu(void);
|
||||
int nopacketcount;
|
||||
void SNDDMA_SetUnderWater(qboolean underwater);
|
||||
|
@ -4815,6 +4821,11 @@ void CL_StartCinematicOrMenu(void)
|
|||
{
|
||||
COM_MainThreadWork();
|
||||
|
||||
if (FS_DownloadingPackage())
|
||||
{
|
||||
startuppending = true;
|
||||
return;
|
||||
}
|
||||
if (cls.download)
|
||||
{
|
||||
startuppending = true;
|
||||
|
@ -4822,6 +4833,8 @@ void CL_StartCinematicOrMenu(void)
|
|||
}
|
||||
if (startuppending)
|
||||
{
|
||||
if (startuppending == 2)
|
||||
Cbuf_AddText("\nfs_restart\nvid_restart\n", RESTRICT_LOCAL);
|
||||
startuppending = false;
|
||||
Key_Dest_Remove(kdm_console); //make sure console doesn't stay up weirdly.
|
||||
}
|
||||
|
@ -4831,7 +4844,9 @@ void CL_StartCinematicOrMenu(void)
|
|||
UI_Start();
|
||||
#endif
|
||||
|
||||
Con_TPrintf ("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081 %s Initialized ^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082\n", *fs_gamename.string?fs_gamename.string:"Nothing");
|
||||
Cbuf_AddText("menu_restart\n", RESTRICT_LOCAL);
|
||||
|
||||
Con_TPrintf ("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081 %s %sInitialized ^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082\n", *fs_gamename.string?fs_gamename.string:"Nothing", com_installer?"Installer ":"");
|
||||
|
||||
//there might be some console command or somesuch waiting for the renderer to begin (demos or map command or whatever all need model support).
|
||||
realtime+=1;
|
||||
|
@ -4839,6 +4854,19 @@ void CL_StartCinematicOrMenu(void)
|
|||
|
||||
Con_ClearNotify();
|
||||
|
||||
TP_ExecTrigger("f_startup");
|
||||
Cbuf_Execute ();
|
||||
|
||||
if (com_installer)
|
||||
{
|
||||
com_installer = false;
|
||||
#if 0
|
||||
Key_Dest_Remove(kdm_console); //make sure console doesn't stay up weirdly.
|
||||
M_Menu_Installer();
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
//and any startup cinematics
|
||||
#ifndef NOMEDIA
|
||||
#ifndef CLIENTONLY
|
||||
|
@ -5006,7 +5034,10 @@ void Host_FinishLoading(void)
|
|||
//the filesystem has retrieved its manifest, but might still be waiting for paks to finish downloading.
|
||||
|
||||
//make sure the filesystem has some default if no manifest was loaded.
|
||||
FS_ChangeGame(NULL, true);
|
||||
FS_ChangeGame(NULL, true, true);
|
||||
|
||||
if (waitingformanifest)
|
||||
return;
|
||||
|
||||
Con_History_Load();
|
||||
|
||||
|
@ -5028,6 +5059,11 @@ void Host_FinishLoading(void)
|
|||
"\n"
|
||||
"See the GNU General Public License for more details.\n");
|
||||
|
||||
#ifdef _WIN32
|
||||
if (Sys_RunInstaller())
|
||||
Sys_Quit();
|
||||
#endif
|
||||
|
||||
Renderer_Start();
|
||||
|
||||
CL_StartCinematicOrMenu();
|
||||
|
@ -5176,6 +5212,7 @@ void Host_Shutdown(void)
|
|||
CL_FreeVisEdicts();
|
||||
M_Shutdown(true);
|
||||
Mod_Shutdown(true);
|
||||
Wads_Flush();
|
||||
#ifndef CLIENTONLY
|
||||
SV_Shutdown();
|
||||
#else
|
||||
|
|
|
@ -27,8 +27,6 @@ void CLDP_ParseDarkPlaces5Entities(void);
|
|||
void CL_SetStatInt (int pnum, int stat, int value);
|
||||
static qboolean CL_CheckModelResources (char *name);
|
||||
|
||||
int msgflags;
|
||||
|
||||
char cl_dp_csqc_progsname[128];
|
||||
int cl_dp_csqc_progssize;
|
||||
int cl_dp_csqc_progscrc;
|
||||
|
@ -266,7 +264,7 @@ char *svc_nqstrings[] =
|
|||
"NEW PROTOCOL(88)" //88
|
||||
};
|
||||
|
||||
extern cvar_t requiredownloads, cl_standardchat, msg_filter, cl_countpendingpl, cl_download_mapsrc;
|
||||
extern cvar_t requiredownloads, cl_standardchat, msg_filter, msg_filter_frags, cl_countpendingpl, cl_download_mapsrc;
|
||||
int oldparsecountmod;
|
||||
int parsecountmod;
|
||||
double parsecounttime;
|
||||
|
@ -5082,7 +5080,7 @@ void CLQ2_ParseInventory (void)
|
|||
#endif
|
||||
|
||||
//return if we want to print the message.
|
||||
char *CL_ParseChat(char *text, player_info_t **player)
|
||||
char *CL_ParseChat(char *text, player_info_t **player, int *msgflags)
|
||||
{
|
||||
extern cvar_t cl_chatsound, cl_nofake, cl_teamchatsound, cl_enemychatsound;
|
||||
int flags;
|
||||
|
@ -5167,35 +5165,11 @@ char *CL_ParseChat(char *text, player_info_t **player)
|
|||
}
|
||||
}
|
||||
|
||||
msgflags = flags;
|
||||
*msgflags = flags;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
char printtext[4096];
|
||||
void CL_ParsePrint(char *msg, int level)
|
||||
{
|
||||
if (strlen(printtext) + strlen(msg) >= sizeof(printtext))
|
||||
{
|
||||
Con_Printf("%s", printtext);
|
||||
Q_strncpyz(printtext, msg, sizeof(printtext));
|
||||
}
|
||||
else
|
||||
strcat(printtext, msg); //safe due to size on if.
|
||||
while((msg = strchr(printtext, '\n')))
|
||||
{
|
||||
*msg = '\0';
|
||||
if (level != PRINT_CHAT)
|
||||
Stats_ParsePrintLine(printtext);
|
||||
|
||||
TP_SearchForMsgTriggers(printtext, level);
|
||||
*msg = '\n';
|
||||
msg++;
|
||||
|
||||
memmove(printtext, msg, strlen(msg)+1);
|
||||
}
|
||||
}
|
||||
|
||||
// CL_PlayerColor: returns color and mask for player_info_t
|
||||
int CL_PlayerColor(player_info_t *plr, qboolean *name_coloured)
|
||||
{
|
||||
|
@ -5206,6 +5180,12 @@ int CL_PlayerColor(player_info_t *plr, qboolean *name_coloured)
|
|||
|
||||
if (cl.teamfortress) //override based on team
|
||||
{
|
||||
//damn spies
|
||||
if (!Q_strcasecmp(plr->team, "red"))
|
||||
c = 1;
|
||||
else if (!Q_strcasecmp(plr->team, "blue"))
|
||||
c = 5;
|
||||
else
|
||||
// TODO: needs some work
|
||||
switch (plr->rbottomcolor)
|
||||
{ //translate q1 skin colours to console colours
|
||||
|
@ -5296,7 +5276,7 @@ void TTS_SayChatString(char **stringtosay);
|
|||
|
||||
// CL_PrintChat: takes chat strings and performs name coloring and cl_parsewhitetext parsing
|
||||
// NOTE: text in rawmsg/msg is assumed destroyable and should not be used afterwards
|
||||
void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
|
||||
void CL_PrintChat(player_info_t *plr, char *msg, int plrflags)
|
||||
{
|
||||
extern cvar_t con_separatechat;
|
||||
char *name = NULL;
|
||||
|
@ -5307,12 +5287,12 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
|
|||
char fullchatmessage[2048];
|
||||
|
||||
fullchatmessage[0] = 0;
|
||||
if (plrflags & TPM_FAKED)
|
||||
/*if (plrflags & TPM_FAKED)
|
||||
{
|
||||
name = rawmsg; // use rawmsg pointer and msg modification to generate null-terminated string
|
||||
if (msg)
|
||||
*(msg - 2) = 0; // it's assumed that msg has 2 chars before it due to strstr
|
||||
}
|
||||
}*/
|
||||
|
||||
if (msg[0] == '/' && msg[1] == 'm' && msg[2] == 'e' && msg[3] == ' ')
|
||||
{
|
||||
|
@ -5540,13 +5520,63 @@ void CL_PrintStandardMessage(char *msg, int printlevel)
|
|||
|
||||
// print final chunk
|
||||
Q_strncatz(fullmessage, msg, sizeof(fullmessage));
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_ParsePrint(fullmessage, printlevel))
|
||||
return;
|
||||
#endif
|
||||
Con_Printf("%s", fullmessage);
|
||||
}
|
||||
|
||||
char printtext[4096];
|
||||
void CL_ParsePrint(char *msg, int level)
|
||||
{
|
||||
char n;
|
||||
if (strlen(printtext) + strlen(msg) >= sizeof(printtext))
|
||||
{
|
||||
Con_Printf("%s", printtext);
|
||||
Q_strncpyz(printtext, msg, sizeof(printtext));
|
||||
}
|
||||
else
|
||||
strcat(printtext, msg); //safe due to size on if.
|
||||
while((msg = strchr(printtext, '\n')))
|
||||
{
|
||||
n = msg[1];
|
||||
msg[1] = 0;
|
||||
|
||||
if (!cls.demoseeking)
|
||||
{
|
||||
if (level == PRINT_CHAT)
|
||||
{
|
||||
char *body;
|
||||
int msgflags;
|
||||
player_info_t *plr = NULL;
|
||||
|
||||
if (!TP_SuppressMessage(printtext))
|
||||
{
|
||||
body = CL_ParseChat(printtext, &plr, &msgflags);
|
||||
if (body)
|
||||
CL_PrintChat(plr, body, msgflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLUGINS
|
||||
if (Plug_ServerMessage(printtext, level))
|
||||
#endif
|
||||
#ifdef CSQC_DAT
|
||||
if (!CSQC_ParsePrint(printtext, level))
|
||||
#endif
|
||||
if (!Stats_ParsePrintLine(printtext) || !msg_filter_frags.ival)
|
||||
CL_PrintStandardMessage(printtext, level);
|
||||
}
|
||||
}
|
||||
|
||||
TP_SearchForMsgTriggers(printtext, level);
|
||||
msg[1] = n;
|
||||
msg++;
|
||||
|
||||
memmove(printtext, msg, strlen(msg)+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
char stufftext[4096];
|
||||
void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from network segregation.
|
||||
{
|
||||
|
@ -5625,7 +5655,7 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
|
|||
flocation_t loc;
|
||||
Cmd_TokenizeString(stufftext+2, false, false);
|
||||
if (FS_FLocateFile(Cmd_Argv(1), FSLFRT_IFFOUND, &loc))
|
||||
Con_Printf("You have been kicked due to a modified file located at %s.\n", Cmd_Argv(0));
|
||||
Con_Printf("You have been kicked due to the file \"%s\" being modified.\n", Cmd_Argv(1));
|
||||
}
|
||||
#ifdef PLUGINS
|
||||
else if (!strncmp(stufftext, "//tinfo ", 8))
|
||||
|
@ -5916,33 +5946,7 @@ void CLQW_ParseServerMessage (void)
|
|||
case svc_print:
|
||||
i = MSG_ReadByte ();
|
||||
s = MSG_ReadString ();
|
||||
|
||||
if (i == PRINT_CHAT)
|
||||
{
|
||||
char *msg;
|
||||
player_info_t *plr = NULL;
|
||||
|
||||
if (TP_SuppressMessage(s))
|
||||
break; //if this was unseen-sent from us, ignore it.
|
||||
|
||||
if ((msg = CL_ParseChat(s, &plr)))
|
||||
{
|
||||
CL_ParsePrint(s, i);
|
||||
if (!cls.demoseeking)
|
||||
CL_PrintChat(plr, s, msg, msgflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLUGINS
|
||||
if (Plug_ServerMessage(s, i))
|
||||
#endif
|
||||
{
|
||||
CL_ParsePrint(s, i);
|
||||
if (!cls.demoseeking)
|
||||
CL_PrintStandardMessage(s, i);
|
||||
}
|
||||
}
|
||||
CL_ParsePrint(s, i);
|
||||
break;
|
||||
|
||||
case svc_centerprint:
|
||||
|
@ -6060,6 +6064,12 @@ void CLQW_ParseServerMessage (void)
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef TERRAIN
|
||||
case svcfte_brushedit:
|
||||
CL_Parse_BrushEdit();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case svc_updatefrags:
|
||||
Sbar_Changed ();
|
||||
i = MSG_ReadByte ();
|
||||
|
@ -6448,27 +6458,7 @@ void CLQ2_ParseServerMessage (void)
|
|||
i = MSG_ReadByte ();
|
||||
s = MSG_ReadString ();
|
||||
|
||||
if (i == PRINT_CHAT)
|
||||
{
|
||||
char *msg;
|
||||
player_info_t *plr = NULL;
|
||||
|
||||
if ((msg = CL_ParseChat(s, &plr)))
|
||||
{
|
||||
CL_ParsePrint(s, i);
|
||||
CL_PrintChat(plr, s, msg, msgflags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef PLUGINS
|
||||
if (Plug_ServerMessage(s, i))
|
||||
#endif
|
||||
{
|
||||
CL_ParsePrint(s, i);
|
||||
CL_PrintStandardMessage(s, i);
|
||||
}
|
||||
}
|
||||
CL_ParsePrint(s, i);
|
||||
break;
|
||||
case svcq2_stufftext: //11 // [string] stuffed into client's console buffer, should be \n terminated
|
||||
s = MSG_ReadString ();
|
||||
|
@ -6721,28 +6711,11 @@ void CLNQ_ParseServerMessage (void)
|
|||
s = MSG_ReadString ();
|
||||
|
||||
if (*s == 1 || *s == 2)
|
||||
{
|
||||
char *msg;
|
||||
player_info_t *plr = NULL;
|
||||
|
||||
if ((msg = CL_ParseChat(s+1, &plr)))
|
||||
{
|
||||
CL_ParsePrint(s+1, PRINT_CHAT);
|
||||
CL_PrintChat(plr, s+1, msg, msgflags);
|
||||
}
|
||||
}
|
||||
CL_ParsePrint(s+1, PRINT_CHAT);
|
||||
else if (CLNQ_ParseNQPrints(s))
|
||||
break;
|
||||
else
|
||||
{
|
||||
if (CLNQ_ParseNQPrints(s))
|
||||
break;
|
||||
#ifdef PLUGINS
|
||||
if (Plug_ServerMessage(s, PRINT_HIGH))
|
||||
#endif
|
||||
{
|
||||
CL_ParsePrint(s, PRINT_HIGH);
|
||||
CL_PrintStandardMessage(s, PRINT_HIGH);
|
||||
}
|
||||
}
|
||||
CL_ParsePrint(s, PRINT_HIGH);
|
||||
break;
|
||||
|
||||
case svc_disconnect:
|
||||
|
@ -7117,7 +7090,7 @@ void CLNQ_ParseServerMessage (void)
|
|||
CL_ParseStatic (3);
|
||||
break;
|
||||
case svcfitz_spawnstaticsound2:
|
||||
Host_EndGame("svcfitz_spawnstaticsound2: not implemented");
|
||||
CL_ParseStaticSound(true);
|
||||
break;
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ static plugin_t *protocolclientplugin;
|
|||
|
||||
|
||||
|
||||
qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
if (qrenderer == QR_NONE)
|
||||
return 0;
|
||||
|
@ -45,7 +45,7 @@ qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t
|
|||
}
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_Key_GetKeyCode(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Key_GetKeyCode(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int modifier;
|
||||
return Key_StringToKeynum(VM_POINTER(arg[0]), &modifier);
|
||||
|
@ -54,7 +54,7 @@ qintptr_t VARGS Plug_Key_GetKeyCode(void *offset, quintptr_t mask, const qintptr
|
|||
|
||||
|
||||
|
||||
qintptr_t VARGS Plug_SCR_CenterPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_SCR_CenterPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
if (qrenderer == QR_NONE)
|
||||
return 0;
|
||||
|
@ -79,7 +79,7 @@ pluginimagearray_t *pluginimagearray;
|
|||
|
||||
#include "shader.h"
|
||||
|
||||
qintptr_t VARGS Plug_Draw_LoadImage(char *name, int type, char *script)
|
||||
static qintptr_t VARGS Plug_Draw_LoadImage(char *name, int type, char *script)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -131,7 +131,7 @@ qintptr_t VARGS Plug_Draw_LoadImage(char *name, int type, char *script)
|
|||
}
|
||||
|
||||
qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean *hasalpha, char *fname);
|
||||
qintptr_t VARGS Plug_Draw_LoadImageData(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_LoadImageData(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
qintptr_t ret = 0;
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
|
@ -147,7 +147,7 @@ qintptr_t VARGS Plug_Draw_LoadImageData(void *offset, quintptr_t mask, const qin
|
|||
|
||||
if ((rgbdata = Read32BitImageFile(codeddata, datalength, &width, &height, NULL, name)))
|
||||
{
|
||||
name = va("%s/", name);
|
||||
// name = va("%s", name);
|
||||
|
||||
t = Image_FindTexture(name, NULL, IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
|
||||
if (!TEXVALID(t))
|
||||
|
@ -162,13 +162,13 @@ qintptr_t VARGS Plug_Draw_LoadImageData(void *offset, quintptr_t mask, const qin
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_LoadImageShader(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_LoadImageShader(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
char *script = VM_POINTER(arg[1]);
|
||||
return Plug_Draw_LoadImage(name, 2, script);
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_LoadImagePic(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_LoadImagePic(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
int type = arg[1];
|
||||
|
@ -209,7 +209,7 @@ static void Plug_FreePlugImages(plugin_t *plug)
|
|||
}
|
||||
|
||||
//int R2D_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image)
|
||||
qintptr_t VARGS Plug_Draw_Image(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Image(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
mpic_t *pic;
|
||||
int i;
|
||||
|
@ -238,7 +238,7 @@ qintptr_t VARGS Plug_Draw_Image(void *offset, quintptr_t mask, const qintptr_t *
|
|||
return 1;
|
||||
}
|
||||
//x1,y1,x2,y2
|
||||
qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
switch(qrenderer) //FIXME: I don't want qrenderer seen outside the refresh
|
||||
{
|
||||
|
@ -257,7 +257,7 @@ qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *a
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int x, y;
|
||||
if (qrenderer == QR_NONE)
|
||||
|
@ -267,7 +267,7 @@ qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr
|
|||
Font_EndString(font_default);
|
||||
return 0;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_String(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_String(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int ipx, px, py;
|
||||
conchar_t buffer[2048], *str;
|
||||
|
@ -291,7 +291,7 @@ qintptr_t VARGS Plug_Draw_String(void *offset, quintptr_t mask, const qintptr_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
float x, y, width, height;
|
||||
if (qrenderer == QR_NONE)
|
||||
|
@ -304,7 +304,7 @@ qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *a
|
|||
R2D_FillBlock(x, y, width, height);
|
||||
return 0;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_ColourP(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_ColourP(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
if (arg[0]<0 || arg[0]>255)
|
||||
return false;
|
||||
|
@ -312,12 +312,12 @@ qintptr_t VARGS Plug_Draw_ColourP(void *offset, quintptr_t mask, const qintptr_t
|
|||
R2D_ImagePaletteColour(arg[0], 1);
|
||||
return 1;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_Colour3f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Colour3f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
R2D_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), 1);
|
||||
return 1;
|
||||
}
|
||||
qintptr_t VARGS Plug_Draw_Colour4f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Draw_Colour4f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
R2D_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
|
||||
return 1;
|
||||
|
@ -331,7 +331,7 @@ qintptr_t VARGS Plug_Draw_Colour4f(void *offset, quintptr_t mask, const qintptr_
|
|||
|
||||
|
||||
|
||||
qintptr_t VARGS Plug_LocalSound(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_LocalSound(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
if (qrenderer == QR_NONE)
|
||||
return false;
|
||||
|
@ -342,7 +342,7 @@ qintptr_t VARGS Plug_LocalSound(void *offset, quintptr_t mask, const qintptr_t *
|
|||
|
||||
|
||||
|
||||
qintptr_t VARGS Plug_CL_GetStats(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_CL_GetStats(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int i;
|
||||
int pnum = VM_LONG(arg[0]);
|
||||
|
@ -383,7 +383,7 @@ typedef struct {
|
|||
char team[8];
|
||||
} vmplugclientinfo_t;
|
||||
|
||||
qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int i, pt;
|
||||
vmplugclientinfo_t *out;
|
||||
|
@ -427,12 +427,12 @@ qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const qintptr_
|
|||
return pt == i;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_LocalPlayerNumber(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_LocalPlayerNumber(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
return cl.playerview[0].playernum;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_GetServerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_GetServerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *outptr = VM_POINTER(arg[0]);
|
||||
unsigned int outlen = VM_LONG(arg[1]);
|
||||
|
@ -445,7 +445,7 @@ qintptr_t VARGS Plug_GetServerInfo(void *offset, quintptr_t mask, const qintptr_
|
|||
return true;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_SetUserInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_SetUserInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *key = VM_POINTER(arg[0]);
|
||||
char *value = VM_POINTER(arg[1]);
|
||||
|
@ -455,7 +455,7 @@ qintptr_t VARGS Plug_SetUserInfo(void *offset, quintptr_t mask, const qintptr_t
|
|||
return true;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_GetLocationName(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_GetLocationName(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
float *locpoint = VM_POINTER(arg[0]);
|
||||
char *locname = VM_POINTER(arg[1]);
|
||||
|
@ -470,7 +470,7 @@ qintptr_t VARGS Plug_GetLocationName(void *offset, quintptr_t mask, const qintpt
|
|||
return VM_LONG(arg[1]);
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
char *text = VM_POINTER(arg[1]);
|
||||
|
@ -511,7 +511,7 @@ qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t
|
|||
|
||||
return 1;
|
||||
}
|
||||
qintptr_t VARGS Plug_Con_RenameSub(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_RenameSub(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
console_t *con;
|
||||
|
@ -525,7 +525,7 @@ qintptr_t VARGS Plug_Con_RenameSub(void *offset, quintptr_t mask, const qintptr_
|
|||
|
||||
return 1;
|
||||
}
|
||||
qintptr_t VARGS Plug_Con_IsActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_IsActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
console_t *con;
|
||||
|
@ -537,7 +537,7 @@ qintptr_t VARGS Plug_Con_IsActive(void *offset, quintptr_t mask, const qintptr_t
|
|||
|
||||
return Con_IsActive(con);
|
||||
}
|
||||
qintptr_t VARGS Plug_Con_SetActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_SetActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
console_t *con;
|
||||
|
@ -550,7 +550,7 @@ qintptr_t VARGS Plug_Con_SetActive(void *offset, quintptr_t mask, const qintptr_
|
|||
Con_SetActive(con);
|
||||
return true;
|
||||
}
|
||||
qintptr_t VARGS Plug_Con_Destroy(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_Destroy(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
console_t *con;
|
||||
|
@ -563,7 +563,7 @@ qintptr_t VARGS Plug_Con_Destroy(void *offset, quintptr_t mask, const qintptr_t
|
|||
Con_Destroy(con);
|
||||
return true;
|
||||
}
|
||||
qintptr_t VARGS Plug_Con_NameForNum(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_NameForNum(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char num = VM_LONG(arg[0]);
|
||||
char *buffer = VM_POINTER(arg[1]);
|
||||
|
@ -576,7 +576,157 @@ qintptr_t VARGS Plug_Con_NameForNum(void *offset, quintptr_t mask, const qintptr
|
|||
return Con_NameForNum(num, buffer, buffersize);
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
static qintptr_t VARGS Plug_Con_GetConsoleFloat(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *conname = VM_POINTER(arg[0]);
|
||||
char *attrib = VM_POINTER(arg[1]);
|
||||
int retbuf;
|
||||
float ret;
|
||||
console_t *con = Con_FindConsole(conname);
|
||||
ret = -1;
|
||||
|
||||
if (!con)
|
||||
ret = -1;
|
||||
else if (!strcmp(attrib, "unseen"))
|
||||
ret = con->unseentext;
|
||||
else if (!strcmp(attrib, "markup"))
|
||||
{
|
||||
if (con->parseflags & PFS_NOMARKUP)
|
||||
ret = 0;
|
||||
else if (con->parseflags & PFS_KEEPMARKUP)
|
||||
ret = 2;
|
||||
else
|
||||
ret = 1;
|
||||
}
|
||||
else if (!strcmp(attrib, "forceutf8"))
|
||||
ret = (con->parseflags&PFS_FORCEUTF8)?true:false;
|
||||
else if (!strcmp(attrib, "hidden"))
|
||||
ret = (con->flags & CONF_HIDDEN)?true:false;
|
||||
else if (!strcmp(attrib, "iswindow"))
|
||||
ret = (con->flags & CONF_ISWINDOW)?true:false;
|
||||
else if (!strcmp(attrib, "wnd_x"))
|
||||
ret = con->wnd_x;
|
||||
else if (!strcmp(attrib, "wnd_y"))
|
||||
ret = con->wnd_y;
|
||||
else if (!strcmp(attrib, "wnd_w"))
|
||||
ret = con->wnd_w;
|
||||
else if (!strcmp(attrib, "wnd_h"))
|
||||
ret = con->wnd_h;
|
||||
else if (!strcmp(attrib, "linecount"))
|
||||
ret = con->linecount;
|
||||
|
||||
VM_FLOAT(retbuf) = ret;
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
static qintptr_t VARGS Plug_Con_SetConsoleFloat(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *conname = VM_POINTER(arg[0]);
|
||||
char *attrib = VM_POINTER(arg[1]);
|
||||
float val = VM_FLOAT(arg[2]);
|
||||
console_t *con = Con_FindConsole(conname);
|
||||
|
||||
if (!con)
|
||||
{
|
||||
con = Con_Create(conname, 0);
|
||||
if (!con)
|
||||
return -1;
|
||||
con->userdata = currentplug;
|
||||
con->linebuffered = Plug_SubConsoleCommand;
|
||||
}
|
||||
|
||||
if (!strcmp(attrib, "unseen"))
|
||||
con->unseentext = !!val;
|
||||
else if (!strcmp(attrib, "markup"))
|
||||
{
|
||||
int cur = val;
|
||||
con->parseflags &= ~(PFS_NOMARKUP|PFS_KEEPMARKUP);
|
||||
if (cur == 0)
|
||||
con->parseflags |= PFS_NOMARKUP;
|
||||
else if (cur == 2)
|
||||
con->parseflags |= PFS_KEEPMARKUP;
|
||||
}
|
||||
else if (!strcmp(attrib, "forceutf8"))
|
||||
con->parseflags = (con->parseflags & ~PFS_FORCEUTF8) | (val?PFS_FORCEUTF8:0);
|
||||
else if (!strcmp(attrib, "hidden"))
|
||||
con->flags = (con->flags & ~CONF_HIDDEN) | (val?CONF_HIDDEN:0);
|
||||
else if (!strcmp(attrib, "iswindow"))
|
||||
{
|
||||
con->flags = (con->flags & ~CONF_ISWINDOW) | (val?CONF_ISWINDOW:0);
|
||||
if (con_curwindow == con && !(con->flags & CONF_ISWINDOW))
|
||||
con_curwindow = NULL;
|
||||
else if (!con_curwindow && (con->flags & CONF_ISWINDOW))
|
||||
con_curwindow = con;
|
||||
}
|
||||
else if (!strcmp(attrib, "wnd_x"))
|
||||
con->wnd_x = val;
|
||||
else if (!strcmp(attrib, "wnd_y"))
|
||||
con->wnd_y = val;
|
||||
else if (!strcmp(attrib, "wnd_w"))
|
||||
con->wnd_w = val;
|
||||
else if (!strcmp(attrib, "wnd_h"))
|
||||
con->wnd_h = val;
|
||||
else if (!strcmp(attrib, "linebuffered"))
|
||||
{
|
||||
con->userdata = currentplug;
|
||||
con->linebuffered = val?Plug_SubConsoleCommand:0;
|
||||
}
|
||||
else if (!strcmp(attrib, "linecount"))
|
||||
{
|
||||
if (val == 0)
|
||||
Con_ClearCon(con);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static qintptr_t VARGS Plug_Con_GetConsoleString(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
const char *conname = VM_POINTER(arg[0]);
|
||||
const char *attrib = VM_POINTER(arg[1]);
|
||||
const char *value = VM_POINTER(arg[2]);
|
||||
size_t size = VM_LONG(arg[3]);
|
||||
console_t *con = Con_FindConsole(conname);
|
||||
|
||||
if (VM_OOB(arg[2], arg[3]))
|
||||
return 0;
|
||||
|
||||
if (!con)
|
||||
return 0;
|
||||
else if (!strcmp(attrib, "footer"))
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
static qintptr_t VARGS Plug_Con_SetConsoleString(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
const char *conname = VM_POINTER(arg[0]);
|
||||
const char *attrib = VM_POINTER(arg[1]);
|
||||
const char *value = VM_POINTER(arg[2]);
|
||||
console_t *con = Con_FindConsole(conname);
|
||||
|
||||
if (!con)
|
||||
{
|
||||
con = Con_Create(conname, 0);
|
||||
if (!con)
|
||||
return -1;
|
||||
con->userdata = currentplug;
|
||||
con->linebuffered = Plug_SubConsoleCommand;
|
||||
}
|
||||
if (!con)
|
||||
return 0;
|
||||
else if (!strcmp(attrib, "footer"))
|
||||
Con_Footerf(con, false, "%s", value);
|
||||
else if (!strcmp(attrib, "title"))
|
||||
Q_strncpyz(con->title, value, sizeof(con->title));
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
int sourceid = VM_LONG(arg[0]);
|
||||
qbyte *data = VM_POINTER(arg[1]);
|
||||
|
@ -598,22 +748,22 @@ qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *
|
|||
#include "com_mesh.h"
|
||||
|
||||
#ifdef SKELETALMODELS
|
||||
int QDECL Plug_RegisterModelFormatText(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
||||
static int QDECL Plug_RegisterModelFormatText(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
||||
{
|
||||
void *module = currentplug;
|
||||
return Mod_RegisterModelFormatText(module, formatname, magictext, load);
|
||||
}
|
||||
int QDECL Plug_RegisterModelFormatMagic(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
||||
static int QDECL Plug_RegisterModelFormatMagic(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
||||
{
|
||||
void *module = currentplug;
|
||||
return Mod_RegisterModelFormatMagic(module, formatname, magic, load);
|
||||
}
|
||||
void QDECL Plug_UnRegisterModelFormat(int idx)
|
||||
static void QDECL Plug_UnRegisterModelFormat(int idx)
|
||||
{
|
||||
void *module = currentplug;
|
||||
Mod_UnRegisterModelFormat(module, idx);
|
||||
}
|
||||
void QDECL Plug_UnRegisterAllModelFormats(void)
|
||||
static void QDECL Plug_UnRegisterAllModelFormats(void)
|
||||
{
|
||||
void *module = currentplug;
|
||||
Mod_UnRegisterAllModelFormats(module);
|
||||
|
@ -671,6 +821,10 @@ void Plug_Client_Init(void)
|
|||
Plug_RegisterBuiltin("Con_SetActive", Plug_Con_SetActive, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_Destroy", Plug_Con_Destroy, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_NameForNum", Plug_Con_NameForNum, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_GetConsoleFloat", Plug_Con_GetConsoleFloat, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_SetConsoleFloat", Plug_Con_SetConsoleFloat, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_GetConsoleString", Plug_Con_GetConsoleString, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("Con_SetConsoleString", Plug_Con_SetConsoleString, PLUG_BIF_NEEDSRENDERER);
|
||||
|
||||
Plug_RegisterBuiltin("LocalSound", Plug_LocalSound, PLUG_BIF_NEEDSRENDERER);
|
||||
Plug_RegisterBuiltin("SCR_CenterPrint", Plug_SCR_CenterPrint, PLUG_BIF_NEEDSRENDERER);
|
||||
|
|
|
@ -560,15 +560,7 @@ void CL_CalcClientTime(void)
|
|||
extern float olddemotime;
|
||||
cl.servertime = olddemotime;
|
||||
}
|
||||
if (cls.protocol == CP_QUAKEWORLD && cls.demoplayback == DPB_MVD && !(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
|
||||
{
|
||||
extern float nextdemotime, olddemotime, demtime;
|
||||
float f;
|
||||
f = (demtime - olddemotime) / (nextdemotime - olddemotime);
|
||||
f = bound(0, f, 1);
|
||||
cl.servertime = cl.gametime*f + cl.oldgametime*(1-f);
|
||||
}
|
||||
else if (cls.protocol != CP_QUAKE3 && (!cl_predict_smooth.ival || (cl_predict_smooth.ival == 2 && !cls.demoplayback)))
|
||||
if (cls.protocol != CP_QUAKE3 && (!cl_predict_smooth.ival || (cl_predict_smooth.ival == 2 && !cls.demoplayback)) && cls.demoplayback != DPB_MVD)
|
||||
{
|
||||
float f;
|
||||
f = cl.gametime - cl.oldgametime;
|
||||
|
|
|
@ -93,7 +93,7 @@ void RSpeedShow(void)
|
|||
}
|
||||
for (i = 0; i < RQUANT_MAX; i++)
|
||||
{
|
||||
s = va("%g %-20s", samplerquant[i]/100.0, RQntNames[i]);
|
||||
s = va("%u.%.3u %-20s", samplerquant[i]/100, (samplerquant[i]%100), RQntNames[i]);
|
||||
Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
|
||||
}
|
||||
if (r_speeds.ival > 1)
|
||||
|
@ -245,6 +245,7 @@ void *scr_curcursor;
|
|||
extern char cl_screengroup[];
|
||||
void CLSCR_Init(void)
|
||||
{
|
||||
int i;
|
||||
Cmd_AddCommand("cprint", SCR_CPrint_f);
|
||||
|
||||
Cvar_Register(&con_stayhidden, cl_screengroup);
|
||||
|
@ -265,6 +266,8 @@ void CLSCR_Init(void)
|
|||
|
||||
|
||||
memset(&key_customcursor, 0, sizeof(key_customcursor));
|
||||
for (i = 0; i < kc_max; i++)
|
||||
key_customcursor[i].dirty = true;
|
||||
scr_curcursor = NULL;
|
||||
if (rf && rf->VID_SetCursor)
|
||||
rf->VID_SetCursor(scr_curcursor);
|
||||
|
@ -417,6 +420,25 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
|
|||
p->time_start = cl.time;
|
||||
}
|
||||
|
||||
void VARGS Stats_Message(char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char str[2048];
|
||||
cprint_t *p = &scr_centerprint[0];
|
||||
if (p->time_off >= 0)
|
||||
return;
|
||||
|
||||
va_start (argptr, msg);
|
||||
vsnprintf (str,sizeof(str)-1, msg, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
p->flags = CPRINT_OBITUARTY;
|
||||
p->titleimage[0] = 0;
|
||||
p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, sizeof(p->string), false) - p->string;
|
||||
p->time_off = scr_centertime.value;
|
||||
p->time_start = cl.time;
|
||||
}
|
||||
|
||||
void SCR_CPrint_f(void)
|
||||
{
|
||||
if (Cmd_Argc() == 2)
|
||||
|
@ -650,7 +672,7 @@ void SCR_DrawCursor(void)
|
|||
return;
|
||||
|
||||
//choose the cursor based upon the module that has primary focus
|
||||
if (key_dest_mask & key_dest_absolutemouse & (kdm_console|kdm_editor))
|
||||
if (key_dest_mask & key_dest_absolutemouse & (kdm_console|kdm_cwindows|kdm_editor))
|
||||
cmod = kc_console;
|
||||
else if ((key_dest_mask & key_dest_absolutemouse & kdm_menu))
|
||||
{
|
||||
|
@ -680,6 +702,13 @@ void SCR_DrawCursor(void)
|
|||
|
||||
if (key_customcursor[cmod].dirty)
|
||||
{
|
||||
if (key_customcursor[cmod].scale <= 0)
|
||||
{
|
||||
key_customcursor[cmod].hotspot[0] = cl_cursorbiasx.value;
|
||||
key_customcursor[cmod].hotspot[1] = cl_cursorbiasy.value;
|
||||
key_customcursor[cmod].scale = cl_cursorscale.value;
|
||||
}
|
||||
|
||||
key_customcursor[cmod].dirty = false;
|
||||
oldcurs = key_customcursor[cmod].handle;
|
||||
if (rf->VID_CreateCursor)
|
||||
|
@ -1173,7 +1202,7 @@ void SCR_Init (void)
|
|||
//
|
||||
// register our commands
|
||||
//
|
||||
Cmd_AddCommand ("screenshot_mega",SCR_ScreenShot_Mega_f);
|
||||
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);
|
||||
|
@ -1794,7 +1823,7 @@ SCR_SetUpToDrawConsole
|
|||
*/
|
||||
void SCR_SetUpToDrawConsole (void)
|
||||
{
|
||||
extern qboolean startuppending; //true if we're downloading media or something and have not yet triggered the startup action (read: main menu or cinematic)
|
||||
extern int startuppending; //true if we're downloading media or something and have not yet triggered the startup action (read: main menu or cinematic)
|
||||
#ifdef TEXTEDITOR
|
||||
//extern qboolean editoractive; //unused variable
|
||||
#endif
|
||||
|
@ -1818,17 +1847,22 @@ void SCR_SetUpToDrawConsole (void)
|
|||
else if (!startuppending && !Key_Dest_Has(kdm_menu) && (!Key_Dest_Has(~((!con_stayhidden.ival?kdm_console:0)|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
|
||||
{
|
||||
//go fullscreen if we're not doing anything
|
||||
if (con_curwindow && !cls.state)
|
||||
{
|
||||
Key_Dest_Add(kdm_cwindows);
|
||||
scr_conlines = 0;
|
||||
}
|
||||
#ifdef VM_UI
|
||||
if (UI_MenuState() || UI_OpenMenu())
|
||||
else if (UI_MenuState() || UI_OpenMenu())
|
||||
scr_con_current = scr_conlines = 0;
|
||||
else
|
||||
#endif
|
||||
else
|
||||
{
|
||||
if (cls.state < ca_demostart)
|
||||
{
|
||||
if (con_stayhidden.ival)
|
||||
{
|
||||
extern qboolean startuppending;
|
||||
extern int startuppending;
|
||||
scr_conlines = 0;
|
||||
if (SCR_GetLoadingStage() == LS_NONE)
|
||||
{
|
||||
|
@ -1845,7 +1879,7 @@ void SCR_SetUpToDrawConsole (void)
|
|||
if (!con_stayhidden.ival && !startuppending && Key_Dest_Has(kdm_console))
|
||||
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
|
||||
}
|
||||
else if (Key_Dest_Has(kdm_console) || scr_chatmode)
|
||||
else if ((Key_Dest_Has(kdm_console) || scr_chatmode))
|
||||
{
|
||||
//go half-screen if we're meant to have the console visible
|
||||
scr_conlines = vid.height*scr_consize.value; // half screen
|
||||
|
@ -1891,16 +1925,16 @@ SCR_DrawConsole
|
|||
*/
|
||||
void SCR_DrawConsole (qboolean noback)
|
||||
{
|
||||
if (scr_con_current)
|
||||
{
|
||||
Con_DrawConsole (scr_con_current, noback);
|
||||
clearconsole = 0;
|
||||
}
|
||||
else
|
||||
if (!scr_con_current)
|
||||
{
|
||||
if (!Key_Dest_Has(kdm_console|kdm_menu))
|
||||
Con_DrawNotify (); // only draw notify in game
|
||||
}
|
||||
if (scr_con_current || Key_Dest_Has(kdm_cwindows))
|
||||
{
|
||||
Con_DrawConsole (scr_con_current, noback);
|
||||
clearconsole = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2133,6 +2167,9 @@ void SCR_ScreenShot_Mega_f(void)
|
|||
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");
|
||||
|
@ -2177,7 +2214,12 @@ void SCR_ScreenShot_Mega_f(void)
|
|||
rgbbuffer = VID_GetRGBInfo(0, &width, &height);
|
||||
if (rgbbuffer)
|
||||
{
|
||||
SCR_ScreenShot(filename, rgbbuffer, width, height);
|
||||
if (SCR_ScreenShot(filename, rgbbuffer, width, height))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
BZ_Free(rgbbuffer);
|
||||
}
|
||||
}
|
||||
|
@ -2452,6 +2494,8 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
{
|
||||
SCR_DrawFPS ();
|
||||
SCR_DrawUPS ();
|
||||
SCR_DrawClock();
|
||||
SCR_DrawGameClock();
|
||||
}
|
||||
SCR_CheckDrawCenterString ();
|
||||
}
|
||||
|
|
|
@ -1475,7 +1475,7 @@ qboolean Stats_HaveKills(void);
|
|||
void VARGS Stats_Message(char *msg, ...) LIKEPRINTF(1);
|
||||
int qm_strcmp(char *s1, char *s2);
|
||||
int qm_stricmp(char *s1, char *s2);
|
||||
void Stats_ParsePrintLine(char *line);
|
||||
qboolean Stats_ParsePrintLine(char *line);
|
||||
void Stats_NewMap(void);
|
||||
void Stats_Clear(void);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "quakedef.h"
|
||||
|
||||
console_t con_main;
|
||||
console_t *con_curwindow;
|
||||
console_t *con_current; // points to whatever is the visible console
|
||||
console_t *con_mouseover; // points to whichever console's title is currently mouseovered, or null
|
||||
console_t *con_chat; // points to a chat console
|
||||
|
@ -128,8 +129,6 @@ void Con_Destroy (console_t *con)
|
|||
return;
|
||||
}
|
||||
|
||||
con_mouseover = NULL;
|
||||
|
||||
for (prev = &con_main; prev->next; prev = prev->next)
|
||||
{
|
||||
if (prev->next == con)
|
||||
|
@ -143,6 +142,18 @@ void Con_Destroy (console_t *con)
|
|||
|
||||
if (con_current == con)
|
||||
con_current = &con_main;
|
||||
|
||||
if (con_curwindow == con)
|
||||
{
|
||||
for (con_curwindow = &con_main; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
{
|
||||
if (con_curwindow->flags & CONF_ISWINDOW)
|
||||
break;
|
||||
}
|
||||
if (!con_curwindow)
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
}
|
||||
con_mouseover = NULL;
|
||||
}
|
||||
/*obtains a console_t without creating*/
|
||||
console_t *Con_FindConsole(const char *name)
|
||||
|
@ -177,7 +188,14 @@ console_t *Con_Create(const char *name, unsigned int flags)
|
|||
/*sets a console as the active one*/
|
||||
void Con_SetActive (console_t *con)
|
||||
{
|
||||
con_current = con;
|
||||
if (con->flags & CONF_ISWINDOW)
|
||||
{
|
||||
con_curwindow = con;
|
||||
Key_Dest_Add(kdm_cwindows);
|
||||
Key_Dest_Remove(kdm_console);
|
||||
}
|
||||
else
|
||||
con_current = con;
|
||||
|
||||
if (con->footerline)
|
||||
{
|
||||
|
@ -186,6 +204,7 @@ void Con_SetActive (console_t *con)
|
|||
Z_Free(con->footerline);
|
||||
con->footerline = NULL;
|
||||
}
|
||||
con->buttonsdown = CB_NONE;
|
||||
}
|
||||
/*for enumerating consoles*/
|
||||
qboolean Con_NameForNum(int num, char *buffer, int buffersize)
|
||||
|
@ -448,6 +467,20 @@ void Con_ToggleConsole_Force(void)
|
|||
void Con_ToggleConsole_f (void)
|
||||
{
|
||||
extern cvar_t con_stayhidden;
|
||||
|
||||
if (!con_curwindow)
|
||||
{
|
||||
for (con_curwindow = &con_main; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
if (con_curwindow->flags & CONF_ISWINDOW)
|
||||
break;
|
||||
}
|
||||
|
||||
if (con_curwindow && !Key_Dest_Has(kdm_cwindows|kdm_console))
|
||||
{
|
||||
Key_Dest_Add(kdm_cwindows);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
if (!(key_dest_mask & kdm_editor) && CSQC_ConsoleCommand("toggleconsole"))
|
||||
{
|
||||
|
@ -457,7 +490,10 @@ void Con_ToggleConsole_f (void)
|
|||
#endif
|
||||
|
||||
if (con_stayhidden.ival >= 3)
|
||||
{
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
return; //its hiding!
|
||||
}
|
||||
|
||||
Con_ToggleConsole_Force();
|
||||
}
|
||||
|
@ -672,6 +708,12 @@ void Con_PrintCon (console_t *con, char *txt, unsigned int parseflags)
|
|||
conchar_t *c;
|
||||
conline_t *oc;
|
||||
conline_t *reuse;
|
||||
int maxlines;
|
||||
|
||||
if (con->maxlines)
|
||||
maxlines = con->maxlines;
|
||||
else
|
||||
maxlines = con_maxlines.ival;
|
||||
|
||||
COM_ParseFunString(con->defaultcharbits, txt, expanded, sizeof(expanded), parseflags);
|
||||
|
||||
|
@ -690,7 +732,7 @@ void Con_PrintCon (console_t *con, char *txt, unsigned int parseflags)
|
|||
case '\n':
|
||||
con->cr = false;
|
||||
reuse = NULL;
|
||||
while (con->linecount >= con_maxlines.ival)
|
||||
while (con->linecount >= maxlines)
|
||||
{
|
||||
if (con->oldest == con->current)
|
||||
break;
|
||||
|
@ -714,7 +756,7 @@ void Con_PrintCon (console_t *con, char *txt, unsigned int parseflags)
|
|||
if (con->flags & CONF_NOTIMES)
|
||||
con->current->time = 0;
|
||||
else
|
||||
con->current->time = realtime;
|
||||
con->current->time = realtime + con->notif_t;
|
||||
|
||||
#if defined(_WIN32) && !defined(NOMEDIA) && !defined(WINRT)
|
||||
if (con->current)
|
||||
|
@ -789,7 +831,7 @@ void Con_PrintCon (console_t *con, char *txt, unsigned int parseflags)
|
|||
if (con->flags & CONF_NOTIMES)
|
||||
con->current->time = 0;
|
||||
else
|
||||
con->current->time = realtime;
|
||||
con->current->time = realtime + con->notif_t;
|
||||
}
|
||||
|
||||
void Con_Print (char *txt)
|
||||
|
@ -811,7 +853,7 @@ void Con_CycleConsole(void)
|
|||
if (!con_current)
|
||||
con_current = &con_main;
|
||||
|
||||
if (con_current->flags & CONF_HIDDEN)
|
||||
if (con_current->flags & (CONF_HIDDEN|CONF_ISWINDOW))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
@ -960,14 +1002,15 @@ void VARGS Con_DPrintf (const char *fmt, ...)
|
|||
}
|
||||
|
||||
/*description text at the bottom of the console*/
|
||||
void Con_Footerf(qboolean append, char *fmt, ...)
|
||||
void Con_Footerf(console_t *con, qboolean append, char *fmt, ...)
|
||||
{
|
||||
console_t *con = con_current;
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
conchar_t marked[MAXPRINTMSG], *markedend;
|
||||
int oldlen, newlen;
|
||||
conline_t *newf;
|
||||
if (!con)
|
||||
con = con_current;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
vsnprintf (msg,sizeof(msg)-1, fmt,argptr);
|
||||
|
@ -1038,7 +1081,13 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
|
|||
int x;
|
||||
|
||||
if (!con->linebuffered)
|
||||
{
|
||||
if (con->footerline)
|
||||
{
|
||||
y = Con_DrawConsoleLines(con, con->footerline, left, right, y, 0, selactive, selsx, selex, selsy, seley);
|
||||
}
|
||||
return y; //fixme: draw any unfinished lines of the current console instead.
|
||||
}
|
||||
|
||||
y -= Font_CharHeight();
|
||||
|
||||
|
@ -1203,18 +1252,20 @@ Draws the last few lines of output transparently over the game top
|
|||
void Con_DrawNotifyOne (console_t *con)
|
||||
{
|
||||
conchar_t *starts[NUM_CON_TIMES], *ends[NUM_CON_TIMES];
|
||||
float alphas[NUM_CON_TIMES], a;
|
||||
conchar_t *c;
|
||||
conline_t *l;
|
||||
int lines=con->notif_l;
|
||||
int line;
|
||||
int x = con->notif_x, y = con->notif_y;
|
||||
int w = con->notif_w;
|
||||
int nx, y;
|
||||
int nw;
|
||||
int x;
|
||||
|
||||
int maxlines;
|
||||
float t;
|
||||
|
||||
Font_BeginString(font_console, x, y, &x, &y);
|
||||
Font_Transform(con->notif_w, 0, &w, NULL);
|
||||
Font_BeginString(font_console, con->notif_x * vid.width, con->notif_y * vid.height, &nx, &y);
|
||||
Font_Transform(con->notif_w * vid.width, 0, &nw, NULL);
|
||||
|
||||
if (con->notif_l < 0)
|
||||
con->notif_l = 0;
|
||||
|
@ -1222,8 +1273,8 @@ void Con_DrawNotifyOne (console_t *con)
|
|||
con->notif_l = NUM_CON_TIMES;
|
||||
lines = maxlines = con->notif_l;
|
||||
|
||||
if (x == 0 && y == 0 && con->notif_w == vid.width)
|
||||
y = Con_DrawProgress(0, w, 0);
|
||||
if (!con->notif_x && !con->notif_y && con->notif_w == 1)
|
||||
y = Con_DrawProgress(0, nw, 0);
|
||||
|
||||
l = con->current;
|
||||
if (!l->length)
|
||||
|
@ -1234,21 +1285,31 @@ void Con_DrawNotifyOne (console_t *con)
|
|||
if (!t)
|
||||
continue; //hidden from notify
|
||||
t = realtime - t;
|
||||
if (t > con->notif_t)
|
||||
break;
|
||||
if (t > 0)
|
||||
{
|
||||
if (t > con->notif_fade)
|
||||
{
|
||||
l->time = 0;
|
||||
break;
|
||||
}
|
||||
a = 1 - (t/con->notif_fade);
|
||||
}
|
||||
else a = 1;
|
||||
|
||||
line = Font_LineBreaks((conchar_t*)(l+1), (conchar_t*)(l+1)+l->length, w, lines, starts, ends);
|
||||
line = Font_LineBreaks((conchar_t*)(l+1), (conchar_t*)(l+1)+l->length, nw, lines, starts, ends);
|
||||
if (!line && lines > 0)
|
||||
{
|
||||
lines--;
|
||||
starts[lines] = NULL;
|
||||
ends[lines] = NULL;
|
||||
alphas[lines] = a;
|
||||
}
|
||||
while(line --> 0 && lines > 0)
|
||||
{
|
||||
lines--;
|
||||
starts[lines] = starts[line];
|
||||
ends[lines] = ends[line];
|
||||
alphas[lines] = a;
|
||||
}
|
||||
if (lines == 0)
|
||||
break;
|
||||
|
@ -1265,15 +1326,24 @@ void Con_DrawNotifyOne (console_t *con)
|
|||
while (lines < con->notif_l)
|
||||
{
|
||||
x = 0;
|
||||
if (con_centernotify.value)
|
||||
Font_ForceColour(1, 1, 1, alphas[lines]);
|
||||
if (con->flags & CONF_NOTIFY_RIGHT)
|
||||
{
|
||||
for (c = starts[lines]; c < ends[lines]; c++)
|
||||
{
|
||||
x += Font_CharWidth(*c);
|
||||
}
|
||||
x = (w - x) / 2;
|
||||
x = (nw - x);
|
||||
}
|
||||
Font_LineDraw(x, y, starts[lines], ends[lines]);
|
||||
else if (con_centernotify.value)
|
||||
{
|
||||
for (c = starts[lines]; c < ends[lines]; c++)
|
||||
{
|
||||
x += Font_CharWidth(*c);
|
||||
}
|
||||
x = (nw - x) / 2;
|
||||
}
|
||||
Font_LineDraw(nx+x, y, starts[lines], ends[lines]);
|
||||
|
||||
y += Font_CharHeight();
|
||||
|
||||
|
@ -1281,6 +1351,8 @@ void Con_DrawNotifyOne (console_t *con)
|
|||
}
|
||||
|
||||
Font_EndString(font_console);
|
||||
|
||||
Font_InvalidateColour();
|
||||
}
|
||||
|
||||
void Con_ClearNotify(void)
|
||||
|
@ -1295,20 +1367,20 @@ void Con_ClearNotify(void)
|
|||
}
|
||||
void Con_DrawNotify (void)
|
||||
{
|
||||
extern qboolean startuppending;
|
||||
extern int startuppending;
|
||||
console_t *con;
|
||||
|
||||
con_main.flags |= CONF_NOTIFY;
|
||||
/*keep the main console up to date*/
|
||||
con_main.notif_l = con_numnotifylines.ival;
|
||||
con_main.notif_w = vid.width;
|
||||
con_main.notif_w = 1;
|
||||
con_main.notif_t = con_notifytime.value;
|
||||
|
||||
if (con_chat)
|
||||
{
|
||||
con_chat->notif_l = con_numnotifylines_chat.ival;
|
||||
con_chat->notif_w = vid.width - 64;
|
||||
con_chat->notif_y = vid.height - sb_lines - 8*4;
|
||||
con_chat->notif_w = 1;
|
||||
con_chat->notif_y = (vid.height - sb_lines - 8*4) / vid.width;
|
||||
con_chat->notif_t = con_notifytime_chat.value;
|
||||
}
|
||||
|
||||
|
@ -1447,6 +1519,12 @@ static int Con_DrawProgress(int left, int right, int y)
|
|||
{
|
||||
sprintf(progresspercenttext, " (%u%skb)", (int)(total/1024), extra?"+":"");
|
||||
}
|
||||
|
||||
//do some marquee thing, so the user gets the impression that SOMETHING is happening.
|
||||
progresspercent = realtime - (int)realtime;
|
||||
if ((int)realtime & 1)
|
||||
progresspercent = 1 - progresspercent;
|
||||
progresspercent *= 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1568,11 +1646,9 @@ int Con_DrawAlternateConsoles(int lines)
|
|||
console_t *con = &con_main, *om = con_mouseover;
|
||||
conchar_t buffer[512], *end, *start;
|
||||
|
||||
con_mouseover = NULL;
|
||||
|
||||
for (con = &con_main; con; con = con->next)
|
||||
{
|
||||
if (!(con->flags & CONF_HIDDEN))
|
||||
if (!(con->flags & (CONF_HIDDEN|CONF_ISWINDOW)))
|
||||
consshown++;
|
||||
}
|
||||
|
||||
|
@ -1584,7 +1660,7 @@ int Con_DrawAlternateConsoles(int lines)
|
|||
h = Font_CharHeight();
|
||||
for (x = 0, con = &con_main; con; con = con->next)
|
||||
{
|
||||
if (con->flags & CONF_HIDDEN)
|
||||
if (con->flags & (CONF_HIDDEN|CONF_ISWINDOW))
|
||||
continue;
|
||||
txt = con->title;
|
||||
|
||||
|
@ -1629,6 +1705,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
conchar_t *s;
|
||||
int i;
|
||||
int x;
|
||||
int charh = Font_CharHeight();
|
||||
|
||||
if (l != con->completionline)
|
||||
if (l != con->footerline)
|
||||
|
@ -1668,13 +1745,11 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
//scale the y coord to be in lines instead of pixels
|
||||
selsy -= y;
|
||||
seley -= y;
|
||||
selsy /= Font_CharHeight();
|
||||
seley /= Font_CharHeight();
|
||||
selsy--;
|
||||
seley--;
|
||||
// selsy -= charh;
|
||||
// seley -= charh;
|
||||
|
||||
//invert the selections to make sense, text-wise
|
||||
if (selsy == seley)
|
||||
/*if (selsy == seley)
|
||||
{
|
||||
//single line selected backwards
|
||||
if (selex < selsx)
|
||||
|
@ -1684,6 +1759,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
selsx = x;
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (seley < selsy)
|
||||
{ //selection goes upwards
|
||||
x = selsy;
|
||||
|
@ -1694,8 +1770,8 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
selex = selsx;
|
||||
selsx = x;
|
||||
}
|
||||
selsy *= Font_CharHeight();
|
||||
seley *= Font_CharHeight();
|
||||
// selsy *= Font_CharHeight();
|
||||
// seley *= Font_CharHeight();
|
||||
selsy += y;
|
||||
seley += y;
|
||||
}
|
||||
|
@ -1727,14 +1803,14 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
{
|
||||
imgname = Info_ValueForKey(linkinfo, "w");
|
||||
if (*imgname)
|
||||
picw = atoi(imgname);
|
||||
picw = (atoi(imgname) * charh) / 8.0;
|
||||
else if (pic->width)
|
||||
picw = (pic->width * vid.pixelwidth) / vid.width;
|
||||
else
|
||||
picw = 64;
|
||||
imgname = Info_ValueForKey(linkinfo, "h");
|
||||
if (*imgname)
|
||||
pich = atoi(imgname);
|
||||
pich = (atoi(imgname) * charh) / 8.0;
|
||||
else if (pic->height)
|
||||
pich = (pic->height * vid.pixelheight) / vid.height;
|
||||
else
|
||||
|
@ -1773,6 +1849,9 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
pich -= texth;
|
||||
y-= pich/2; //skip some space above and below the text block, to keep the text and image aligned.
|
||||
}
|
||||
|
||||
// if (selsx < picw && selex < picw)
|
||||
|
||||
}
|
||||
|
||||
l->lines = linecount;
|
||||
|
@ -1789,9 +1868,9 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
|
||||
if (selactive)
|
||||
{
|
||||
if (y >= selsy)
|
||||
if (y+charh >= selsy)
|
||||
{
|
||||
if (y <= seley)
|
||||
if (y < seley)
|
||||
{
|
||||
int sstart;
|
||||
int send;
|
||||
|
@ -1804,7 +1883,17 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
if (send == sstart)
|
||||
send = Font_CharEndCoord(font_console, send, ' ');
|
||||
|
||||
if (y >= seley)
|
||||
if (y+charh >= seley && y < selsy)
|
||||
{ //if they're both on the same line, make sure sx is to the left of ex, so our stuff makes sense
|
||||
if (selex < selsx)
|
||||
{
|
||||
x = selex;
|
||||
selex = selsx;
|
||||
selsx = x;
|
||||
}
|
||||
}
|
||||
|
||||
if (y+charh >= seley)
|
||||
{
|
||||
send = sstart;
|
||||
for (i = 0; i < linelength; )
|
||||
|
@ -1821,7 +1910,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
else
|
||||
con->selendoffset = 0;
|
||||
}
|
||||
if (y <= selsy)
|
||||
if (y < selsy)
|
||||
{
|
||||
for (i = 0; i < linelength; i++)
|
||||
{
|
||||
|
@ -1837,10 +1926,14 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
|
|||
else
|
||||
con->selstartoffset = 0;
|
||||
}
|
||||
|
||||
if (selactive == 1)
|
||||
{
|
||||
R2D_ImagePaletteColour(0, 1.0);
|
||||
R2D_FillBlock((sstart*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((send - sstart)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight);
|
||||
if (send < sstart)
|
||||
R2D_FillBlock((send*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((sstart - send)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight);
|
||||
else
|
||||
R2D_FillBlock((sstart*vid.width)/(float)vid.rotpixelwidth, (y*vid.height)/(float)vid.rotpixelheight, ((send - sstart)*vid.width)/(float)vid.rotpixelwidth, (Font_CharHeight()*vid.height)/(float)vid.rotpixelheight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1877,69 +1970,142 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
int selsx, selsy, selex, seley, selactive;
|
||||
int top;
|
||||
qboolean haveprogress;
|
||||
console_t *w, *mouseconsole;
|
||||
|
||||
if (lines <= 0)
|
||||
return;
|
||||
con_mouseover = NULL;
|
||||
|
||||
//draw any windowed consoles (under main console)
|
||||
if (Key_Dest_Has(kdm_cwindows))
|
||||
for (w = &con_main; w; w = w->next)
|
||||
{
|
||||
srect_t srect;
|
||||
if ((w->flags & (CONF_HIDDEN|CONF_ISWINDOW)) != CONF_ISWINDOW)
|
||||
continue;
|
||||
|
||||
if (w->wnd_w > vid.width)
|
||||
w->wnd_w = vid.width;
|
||||
if (w->wnd_h > vid.height)
|
||||
w->wnd_h = vid.height;
|
||||
if (w->wnd_w < 64)
|
||||
w->wnd_w = 64;
|
||||
if (w->wnd_h < 16)
|
||||
w->wnd_h = 16;
|
||||
//windows that move off the top of the screen somehow are bad.
|
||||
if (w->wnd_y > vid.height - 8)
|
||||
w->wnd_y = vid.height - 8;
|
||||
if (w->wnd_y < 0)
|
||||
w->wnd_y = 0;
|
||||
if (w->wnd_x > vid.width-32)
|
||||
w->wnd_x = vid.width-32;
|
||||
if (w->wnd_x < -w->wnd_w+32)
|
||||
w->wnd_x = -w->wnd_w+32;
|
||||
|
||||
if (w->wnd_h < 8)
|
||||
w->wnd_h = 8;
|
||||
|
||||
if (mousecursor_x >= w->wnd_x && mousecursor_x < w->wnd_x+w->wnd_w && mousecursor_y >= w->wnd_y && mousecursor_y < w->wnd_y+w->wnd_h && mousecursor_y > lines)
|
||||
con_mouseover = w;
|
||||
|
||||
w->mousecursor[0] = mousecursor_x - w->wnd_x;
|
||||
w->mousecursor[1] = mousecursor_y - w->wnd_y;
|
||||
|
||||
R2D_ImageColours(0.0, 0.05, 0.1, 0.5);
|
||||
R2D_FillBlock(w->wnd_x, w->wnd_y, w->wnd_w, w->wnd_h);
|
||||
Draw_FunStringWidth(w->wnd_x, w->wnd_y, w->title, w->wnd_w-16, 2, (con_curwindow==w)?true:false);
|
||||
Draw_FunStringWidth(w->wnd_x+w->wnd_w-8, w->wnd_y, "X", 8, 2, (w->buttonsdown == CB_CLOSE&& w->mousecursor[0] > w->wnd_w-8 && w->mousecursor[1] < 8)?true:false);
|
||||
|
||||
srect.x = w->wnd_x / vid.width;
|
||||
srect.y = (w->wnd_y+8) / vid.height;
|
||||
srect.width = w->wnd_w / vid.width;
|
||||
srect.height = (w->wnd_h-8) / vid.height;
|
||||
srect.dmin = -99999;
|
||||
srect.dmax = 99999;
|
||||
srect.y = (1-srect.y) - srect.height;
|
||||
if (srect.width && srect.height)
|
||||
{
|
||||
BE_Scissor(&srect);
|
||||
R2D_ImageColours(0, 0.1, 0.2, 1.0);
|
||||
if (w->buttonsdown & CB_SIZELEFT)
|
||||
R2D_FillBlock(w->wnd_x, w->wnd_y+8, 8, w->wnd_h-8);
|
||||
if (w->buttonsdown & CB_SIZERIGHT)
|
||||
R2D_FillBlock(w->wnd_x+w->wnd_w-8, w->wnd_y+8, 8, w->wnd_h-8);
|
||||
if (w->buttonsdown & CB_SIZEBOTTOM)
|
||||
R2D_FillBlock(w->wnd_x, w->wnd_y+w->wnd_h-8, w->wnd_w, 8);
|
||||
Con_DrawOneConsole(w, con_curwindow == w && !Key_Dest_Has(kdm_console), font_console, w->wnd_x+8, w->wnd_y, w->wnd_w-16, w->wnd_h-8);
|
||||
BE_Scissor(NULL);
|
||||
}
|
||||
|
||||
if (w->selstartline)
|
||||
mouseconsole = w;
|
||||
if (!con_curwindow)
|
||||
con_curwindow = w;
|
||||
}
|
||||
|
||||
if (lines > 0)
|
||||
{
|
||||
#ifdef QTERM
|
||||
if (qterms)
|
||||
QT_Update();
|
||||
if (qterms)
|
||||
QT_Update();
|
||||
#endif
|
||||
|
||||
// draw the background
|
||||
if (!noback)
|
||||
R2D_ConsoleBackground (0, lines, scr_con_forcedraw);
|
||||
if (!noback)
|
||||
R2D_ConsoleBackground (0, lines, scr_con_forcedraw);
|
||||
|
||||
con_current->unseentext = false;
|
||||
con_current->unseentext = false;
|
||||
|
||||
con_current->vislines = lines;
|
||||
con_current->vislines = lines;
|
||||
|
||||
top = Con_DrawAlternateConsoles(lines);
|
||||
top = Con_DrawAlternateConsoles(lines);
|
||||
|
||||
if (!con_current->display)
|
||||
con_current->display = con_current->current;
|
||||
if (!con_current->display)
|
||||
con_current->display = con_current->current;
|
||||
|
||||
x = 8;
|
||||
y = lines;
|
||||
x = 8;
|
||||
y = lines;
|
||||
|
||||
con_current->mousecursor[0] = mousecursor_x;
|
||||
con_current->mousecursor[1] = mousecursor_y;
|
||||
con_current->selstartline = NULL;
|
||||
con_current->selendline = NULL;
|
||||
selactive = Key_GetConsoleSelectionBox(con_current, &selsx, &selsy, &selex, &seley);
|
||||
con_current->mousecursor[0] = mousecursor_x;
|
||||
con_current->mousecursor[1] = mousecursor_y;
|
||||
con_current->selstartline = NULL;
|
||||
con_current->selendline = NULL;
|
||||
selactive = Key_GetConsoleSelectionBox(con_current, &selsx, &selsy, &selex, &seley);
|
||||
|
||||
Font_BeginString(font_console, x, y, &x, &y);
|
||||
Font_BeginString(font_console, selsx, selsy, &selsx, &selsy);
|
||||
Font_BeginString(font_console, selex, seley, &selex, &seley);
|
||||
ex = Font_ScreenWidth();
|
||||
sx = x;
|
||||
ex -= sx;
|
||||
Font_BeginString(font_console, x, y, &x, &y);
|
||||
Font_BeginString(font_console, selsx, selsy, &selsx, &selsy);
|
||||
Font_BeginString(font_console, selex, seley, &selex, &seley);
|
||||
ex = Font_ScreenWidth();
|
||||
sx = x;
|
||||
ex -= sx;
|
||||
|
||||
y -= Font_CharHeight();
|
||||
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
|
||||
y = Con_DrawInput (con_current, Key_Dest_Has(kdm_console), x, ex - x, y, selactive, selsx, selex, selsy, seley);
|
||||
|
||||
l = con_current->display;
|
||||
|
||||
y = Con_DrawConsoleLines(con_current, l, sx, ex, y, top, selactive, selsx, selex, selsy, seley);
|
||||
|
||||
if (!haveprogress && lines == vid.height)
|
||||
{
|
||||
char *version = version_string();
|
||||
int i;
|
||||
Font_BeginString(font_console, vid.width, lines, &x, &y);
|
||||
y -= Font_CharHeight();
|
||||
for (i = 0; version[i]; i++)
|
||||
x -= Font_CharWidth(version[i] | CON_WHITEMASK|CON_HALFALPHA);
|
||||
for (i = 0; version[i]; i++)
|
||||
x = Font_DrawChar(x, y, version[i] | CON_WHITEMASK|CON_HALFALPHA);
|
||||
haveprogress = Con_DrawProgress(x, ex - x, y) != y;
|
||||
y = Con_DrawInput (con_current, Key_Dest_Has(kdm_console), x, ex - x, y, selactive, selsx, selex, selsy, seley);
|
||||
|
||||
l = con_current->display;
|
||||
|
||||
y = Con_DrawConsoleLines(con_current, l, sx, ex, y, top, selactive, selsx, selex, selsy, seley);
|
||||
|
||||
if (!haveprogress && lines == vid.height)
|
||||
{
|
||||
char *version = version_string();
|
||||
int i;
|
||||
Font_BeginString(font_console, vid.width, lines, &x, &y);
|
||||
y -= Font_CharHeight();
|
||||
for (i = 0; version[i]; i++)
|
||||
x -= Font_CharWidth(version[i] | CON_WHITEMASK|CON_HALFALPHA);
|
||||
for (i = 0; version[i]; i++)
|
||||
x = Font_DrawChar(x, y, version[i] | CON_WHITEMASK|CON_HALFALPHA);
|
||||
}
|
||||
|
||||
Font_EndString(font_console);
|
||||
mouseconsole = con_mouseover?con_mouseover:con_current;
|
||||
}
|
||||
else
|
||||
mouseconsole = con_mouseover?con_mouseover:NULL;
|
||||
|
||||
Font_EndString(font_console);
|
||||
|
||||
if (con_current->selstartline)
|
||||
if (mouseconsole && mouseconsole->selstartline)
|
||||
{
|
||||
char *mouseover = Con_CopyConsole(false, true);
|
||||
char *mouseover = Con_CopyConsole(mouseconsole, false, true);
|
||||
if (mouseover)
|
||||
{
|
||||
char *end = strstr(mouseover, "^]");
|
||||
|
@ -1992,7 +2158,7 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
}
|
||||
}
|
||||
|
||||
void Con_DrawOneConsole(console_t *con, struct font_s *font, float fx, float fy, float fsx, float fsy)
|
||||
void Con_DrawOneConsole(console_t *con, qboolean focused, struct font_s *font, float fx, float fy, float fsx, float fsy)
|
||||
{
|
||||
int selactive, selsx, selsy, selex, seley;
|
||||
int x, y, sx, sy;
|
||||
|
@ -2018,7 +2184,7 @@ void Con_DrawOneConsole(console_t *con, struct font_s *font, float fx, float fy,
|
|||
seley += y;
|
||||
}
|
||||
|
||||
sy = Con_DrawInput (con, con->flags & CONF_KEYFOCUSED, x, sx, sy, selactive, selsx, selex, selsy, seley);
|
||||
sy = Con_DrawInput (con, focused, x, sx, sy, selactive, selsx, selex, selsy, seley);
|
||||
|
||||
if (!con->display)
|
||||
con->display = con->current;
|
||||
|
@ -2028,9 +2194,8 @@ void Con_DrawOneConsole(console_t *con, struct font_s *font, float fx, float fy,
|
|||
}
|
||||
|
||||
|
||||
char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink)
|
||||
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink)
|
||||
{
|
||||
console_t *con = con_current;
|
||||
conchar_t *cur;
|
||||
conline_t *l;
|
||||
conchar_t *lend;
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct {
|
|||
stat ownsuicides;
|
||||
char *fullname;
|
||||
char *abrev;
|
||||
char *image;
|
||||
char *codename;
|
||||
} weapontotals[MAX_WEAPONS];
|
||||
|
||||
|
@ -75,6 +76,7 @@ typedef struct {
|
|||
statmessage_t *message;
|
||||
} fragstats_t;
|
||||
|
||||
cvar_t r_tracker_frags = CVARD("r_tracker_frags", "0", "0: like vanilla quake\n1: shows only your kills/deaths\n2: shows all kills\n");
|
||||
static fragstats_t fragstats;
|
||||
|
||||
int Stats_GetKills(int playernum)
|
||||
|
@ -107,8 +109,149 @@ qboolean Stats_HaveKills(void)
|
|||
return fragstats.readkills;
|
||||
}
|
||||
|
||||
void VARGS Stats_Message(char *msg, ...)
|
||||
void VARGS Stats_Message(char *msg, ...);
|
||||
|
||||
static char *Stats_GenTrackerImageString(char *in)
|
||||
{ //images are of the form "foo \sg\ bar \q\"
|
||||
//which should eg be remapped to: "foo ^Ue200 bar foo ^Ue201"
|
||||
char res[256];
|
||||
char image[MAX_QPATH];
|
||||
char *outi;
|
||||
char *out;
|
||||
int i;
|
||||
if (!in || !*in)
|
||||
return NULL;
|
||||
|
||||
for (out = res; *in && out < res+sizeof(res)-10; )
|
||||
{
|
||||
if (*in == '\\')
|
||||
{
|
||||
in++;
|
||||
for (outi = image; *in && outi < image+sizeof(image)-10; )
|
||||
{
|
||||
if (*in == '\\')
|
||||
break;
|
||||
*outi++ = *in++;
|
||||
}
|
||||
*outi = 0;
|
||||
in++;
|
||||
|
||||
i = Font_RegisterTrackerImage(va("tracker/%s", image));
|
||||
if (i)
|
||||
{
|
||||
char hexchars[16] = "0123456789abcdef";
|
||||
*out++ = '^';
|
||||
*out++ = 'U';
|
||||
*out++ = hexchars[(i>>12)&15];
|
||||
*out++ = hexchars[(i>>8)&15];
|
||||
*out++ = hexchars[(i>>4)&15];
|
||||
*out++ = hexchars[(i>>0)&15];
|
||||
}
|
||||
else
|
||||
{
|
||||
//just copy the short name over, not much else we can do.
|
||||
for(outi = image; out < res+sizeof(res)-10 && *outi; )
|
||||
*out++ = *outi++;
|
||||
}
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
}
|
||||
*out = 0;
|
||||
return Z_StrDup(res);
|
||||
}
|
||||
|
||||
void Stats_FragMessage(int p1, int wid, int p2, qboolean teamkill)
|
||||
{
|
||||
static const char *nonplayers[] = {
|
||||
"BUG",
|
||||
"(teamkill)",
|
||||
"(suicide)",
|
||||
"(death)",
|
||||
"(unknown)",
|
||||
"(fixme)",
|
||||
"(fixme)"
|
||||
};
|
||||
char message[512];
|
||||
console_t *tracker;
|
||||
struct wt_s *w = &fragstats.weapontotals[wid];
|
||||
const char *p1n = (p1 < 0)?nonplayers[-p1]:cl.players[p1].name;
|
||||
const char *p2n = (p2 < 0)?nonplayers[-p2]:cl.players[p2].name;
|
||||
int localplayer = (cl.spectator && cl.playerview[0].cam_locked)?cl.playerview[0].cam_spec_track:cl.playerview[0].playernum;
|
||||
|
||||
#define YOU_GOOD S_COLOR_GREEN
|
||||
#define YOU_BAD S_COLOR_BLUE
|
||||
#define TEAM_GOOD S_COLOR_GREEN
|
||||
#define TEAM_BAD S_COLOR_RED
|
||||
#define TEAM_VBAD S_COLOR_BLUE
|
||||
#define TEAM_NEUTRAL S_COLOR_WHITE //enemy team thing that does not directly affect us
|
||||
#define ENEMY_GOOD S_COLOR_RED
|
||||
#define ENEMY_BAD S_COLOR_GREEN
|
||||
#define ENEMY_NEUTRAL S_COLOR_WHITE
|
||||
|
||||
|
||||
char *p1c = S_COLOR_WHITE;
|
||||
char *p2c = S_COLOR_WHITE;
|
||||
|
||||
if (!r_tracker_frags.ival)
|
||||
return;
|
||||
if (r_tracker_frags.ival < 2)
|
||||
if (p1 != localplayer && p2 != localplayer)
|
||||
return;
|
||||
|
||||
if (teamkill)
|
||||
{//team kills/suicides are always considered bad.
|
||||
if (p1 == localplayer)
|
||||
p1c = YOU_BAD;
|
||||
else if (cl.teamplay && !strcmp(cl.players[p1].team, cl.players[localplayer].team))
|
||||
p1c = TEAM_VBAD;
|
||||
else
|
||||
p1c = TEAM_NEUTRAL;
|
||||
p2c = p1c;
|
||||
}
|
||||
else if (p1 == p2)
|
||||
p1c = p2c = YOU_BAD;
|
||||
else if (cl.teamplay && p1 >= 0 && p2 >= 0 && !strcmp(cl.players[p1].team, cl.players[p2].team))
|
||||
p1c = p2c = TEAM_VBAD;
|
||||
else
|
||||
{
|
||||
if (p2 >= 0)
|
||||
{
|
||||
//us/teammate killing is good - unless it was a teammate.
|
||||
if (p2 == localplayer)
|
||||
p2c = YOU_GOOD;
|
||||
else if (cl.teamplay && !strcmp(cl.players[p2].team, cl.players[localplayer].team))
|
||||
p2c = TEAM_GOOD;
|
||||
else
|
||||
p2c = ENEMY_GOOD;
|
||||
}
|
||||
if (p1 >= 0)
|
||||
{
|
||||
//us/teammate dying is bad.
|
||||
if (p1 == localplayer)
|
||||
p1c = YOU_BAD;
|
||||
else if (cl.teamplay && !strcmp(cl.players[p1].team, cl.players[localplayer].team))
|
||||
p1c = TEAM_BAD;
|
||||
else
|
||||
p1c = p2c;
|
||||
}
|
||||
}
|
||||
|
||||
Q_snprintfz(message, sizeof(message), "%s%s ^7%s %s%s\n", p1c, p1n, w->image?w->image:w->abrev, p2c, p2n);
|
||||
|
||||
tracker = Con_FindConsole("tracker");
|
||||
if (!tracker)
|
||||
{
|
||||
tracker = Con_Create("tracker", CONF_HIDDEN|CONF_NOTIFY|CONF_NOTIFY_RIGHT|CONF_NOTIFY_BOTTOM);
|
||||
//this stuff should be configurable
|
||||
tracker->notif_l = tracker->maxlines = 8;
|
||||
tracker->notif_x = 0.5;
|
||||
tracker->notif_y = 0.333;
|
||||
tracker->notif_w = 1-tracker->notif_x;
|
||||
tracker->notif_t = 4;
|
||||
tracker->notif_fade = 1;
|
||||
}
|
||||
Con_PrintCon(tracker, message, tracker->parseflags);
|
||||
}
|
||||
|
||||
void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
||||
|
@ -126,6 +269,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
u1 = (p1 == (cl.playerview[0].playernum));
|
||||
u2 = (p2 == (cl.playerview[0].playernum));
|
||||
|
||||
//messages are killed weapon killer
|
||||
switch(mt)
|
||||
{
|
||||
case ff_death:
|
||||
|
@ -134,9 +278,15 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].owndeaths++;
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
}
|
||||
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
Stats_FragMessage(p1, wid, -3, true);
|
||||
|
||||
if (u1)
|
||||
Stats_Message("You died\n%s deaths: %i\n", fragstats.weapontotals[wid].fullname, fragstats.weapontotals[wid].owndeaths);
|
||||
break;
|
||||
case ff_suicide:
|
||||
if (u1)
|
||||
|
@ -144,15 +294,18 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].ownsuicides++;
|
||||
fragstats.weapontotals[wid].owndeaths++;
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
|
||||
Stats_Message("You are a fool\n");
|
||||
}
|
||||
|
||||
fragstats.weapontotals[wid].suicides++;
|
||||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].suisides++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
fragstats.totalsuicides++;
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
Stats_FragMessage(p1, wid, -2, true);
|
||||
if (u1)
|
||||
Stats_Message("You killed your own dumb self\n%s suicides: %i (%i)\n", fragstats.weapontotals[wid].fullname, fragstats.weapontotals[wid].ownsuicides, fragstats.weapontotals[wid].suicides);
|
||||
break;
|
||||
case ff_bonusfrag:
|
||||
if (u1)
|
||||
|
@ -160,6 +313,10 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].kills++;
|
||||
fragstats.clienttotals[p1].kills++;
|
||||
fragstats.totalkills++;
|
||||
|
||||
Stats_FragMessage(-4, wid, p1, false);
|
||||
if (u1)
|
||||
Stats_Message("You killed someone\n%s kills: %i\n", fragstats.weapontotals[wid].fullname, fragstats.weapontotals[wid].ownkills);
|
||||
break;
|
||||
case ff_tkbonus:
|
||||
if (u1)
|
||||
|
@ -173,6 +330,11 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.weapontotals[wid].teamkills++;
|
||||
fragstats.clienttotals[p1].teamkills++;
|
||||
fragstats.totalteamkills++;
|
||||
|
||||
Stats_FragMessage(-1, wid, p1, true);
|
||||
|
||||
if (u1)
|
||||
Stats_Message("You killed your teammate\n%s teamkills: %i\n", fragstats.weapontotals[wid].fullname, fragstats.weapontotals[wid].ownteamkills);
|
||||
break;
|
||||
case ff_flagtouch:
|
||||
fragstats.clienttotals[p1].grabs++;
|
||||
|
@ -180,8 +342,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
|
||||
if (u1)
|
||||
{
|
||||
Stats_Message("You grabbed the flag\n");
|
||||
Stats_Message("flag grabs: %i (%i)\n", fragstats.clienttotals[p1].grabs, fragstats.totaltouches);
|
||||
Stats_Message("You grabbed the flag\nflag grabs: %i (%i)\n", fragstats.clienttotals[p1].grabs, fragstats.totaltouches);
|
||||
}
|
||||
break;
|
||||
case ff_flagcaps:
|
||||
|
@ -190,8 +351,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
|
||||
if (u1)
|
||||
{
|
||||
Stats_Message("You captured the flag\n");
|
||||
Stats_Message("flag captures: %i (%i)\n", fragstats.clienttotals[p1].caps, fragstats.totalcaps);
|
||||
Stats_Message("You captured the flag\nflag captures: %i (%i)\n", fragstats.clienttotals[p1].caps, fragstats.totalcaps);
|
||||
}
|
||||
break;
|
||||
case ff_flagdrops:
|
||||
|
@ -200,8 +360,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
|
||||
if (u1)
|
||||
{
|
||||
Stats_Message("You dropped the flag\n");
|
||||
Stats_Message("flag drops: %i (%i)\n", fragstats.clienttotals[p1].drops, fragstats.totaldrops);
|
||||
Stats_Message("You dropped the flag\nflag drops: %i (%i)\n", fragstats.clienttotals[p1].drops, fragstats.totaldrops);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -215,8 +374,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
if (u1)
|
||||
{
|
||||
fragstats.weapontotals[wid].owndeaths++;
|
||||
Stats_Message("%s killed you\n", cl.players[p2].name);
|
||||
Stats_Message("%s deaths: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].owndeaths, fragstats.weapontotals[wid].owndeaths, fragstats.totaldeaths);
|
||||
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++;
|
||||
|
@ -224,9 +382,10 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
if (u2)
|
||||
{
|
||||
fragstats.weapontotals[wid].ownkills++;
|
||||
Stats_Message("You killed %s\n", cl.players[p1].name);
|
||||
Stats_Message("%s kills: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills, fragstats.totalkills);
|
||||
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);
|
||||
break;
|
||||
case ff_tkdeath:
|
||||
//killed by a teammate, but we don't know who
|
||||
|
@ -236,9 +395,16 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.totalkills++; //its a kill, but we don't know who from
|
||||
fragstats.totalteamkills++;
|
||||
|
||||
if (u1)
|
||||
fragstats.weapontotals[wid].owndeaths++;
|
||||
fragstats.clienttotals[p1].teamdeaths++;
|
||||
fragstats.clienttotals[p1].deaths++;
|
||||
fragstats.totaldeaths++;
|
||||
|
||||
Stats_FragMessage(p1, wid, -1, true);
|
||||
|
||||
if (u1)
|
||||
Stats_Message("Your teammate killed you\n%s deaths: %i\n", fragstats.weapontotals[wid].fullname, fragstats.weapontotals[wid].owndeaths);
|
||||
break;
|
||||
|
||||
case ff_tkills:
|
||||
|
@ -266,6 +432,12 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2)
|
|||
fragstats.totalkills++;
|
||||
|
||||
fragstats.totalteamkills++;
|
||||
|
||||
Stats_FragMessage(p1, wid, p2, false);
|
||||
if (u1)
|
||||
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)
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -344,6 +516,7 @@ void Stats_Clear(void)
|
|||
if (fragstats.weapontotals[i].codename) Z_Free(fragstats.weapontotals[i].codename);
|
||||
if (fragstats.weapontotals[i].fullname) Z_Free(fragstats.weapontotals[i].fullname);
|
||||
if (fragstats.weapontotals[i].abrev) Z_Free(fragstats.weapontotals[i].abrev);
|
||||
if (fragstats.weapontotals[i].image) Z_Free(fragstats.weapontotals[i].image);
|
||||
}
|
||||
|
||||
memset(&fragstats, 0, sizeof(fragstats));
|
||||
|
@ -424,6 +597,7 @@ static void Stats_LoadFragFile(char *name)
|
|||
{
|
||||
fragstats.weapontotals[wid].fullname = Z_Copy(Cmd_Argv(3));
|
||||
fragstats.weapontotals[wid].abrev = Z_Copy(Cmd_Argv(4));
|
||||
fragstats.weapontotals[wid].image = Stats_GenTrackerImageString(Cmd_Argv(5));
|
||||
}
|
||||
}
|
||||
else if (!stricmp(tk, "obituary") ||
|
||||
|
@ -526,7 +700,7 @@ static int Stats_ExtractName(char **line)
|
|||
return bm;
|
||||
}
|
||||
|
||||
void Stats_ParsePrintLine(char *line)
|
||||
qboolean Stats_ParsePrintLine(char *line)
|
||||
{
|
||||
statmessage_t *ms;
|
||||
int p1;
|
||||
|
@ -536,7 +710,7 @@ void Stats_ParsePrintLine(char *line)
|
|||
p1 = Stats_ExtractName(&line);
|
||||
if (p1<0) //reject it.
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ms = fragstats.message; ms; ms = ms->next)
|
||||
|
@ -552,16 +726,17 @@ void Stats_ParsePrintLine(char *line)
|
|||
if (!qm_stricmp(ms->msgpart2, m2))
|
||||
{
|
||||
Stats_Evaluate(ms->type, ms->wid, p1, p2);
|
||||
return; //done.
|
||||
return true; //done.
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //one player
|
||||
Stats_Evaluate(ms->type, ms->wid, p1, p1);
|
||||
return; //done.
|
||||
return true; //done.
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Stats_NewMap(void)
|
||||
|
|
|
@ -846,7 +846,7 @@ struct pngerr
|
|||
static void VARGS png_onerror(png_structp png_ptr, png_const_charp error_msg)
|
||||
{
|
||||
struct pngerr *err = qpng_get_error_ptr(png_ptr);
|
||||
Con_Printf("libpng %s: %s", err->fname, error_msg);
|
||||
Con_Printf("libpng %s: %s\n", err->fname, error_msg);
|
||||
longjmp(err->jbuf, 1);
|
||||
abort();
|
||||
}
|
||||
|
@ -854,7 +854,7 @@ static void VARGS png_onerror(png_structp png_ptr, png_const_charp error_msg)
|
|||
static void VARGS png_onwarning(png_structp png_ptr, png_const_charp warning_msg)
|
||||
{
|
||||
struct pngerr *err = qpng_get_error_ptr(png_ptr);
|
||||
Con_Printf("libpng %s: %s\n", err->fname, warning_msg);
|
||||
Con_DPrintf("libpng %s: %s\n", err->fname, warning_msg);
|
||||
}
|
||||
|
||||
qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *fname)
|
||||
|
@ -2820,7 +2820,7 @@ static void Image_GenerateMips(struct pendingtextureinfo *mips, unsigned int fla
|
|||
case PTI_RGBX8:
|
||||
case PTI_BGRA8:
|
||||
case PTI_BGRX8:
|
||||
for (mip = 1; mip < 32; mip++)
|
||||
for (mip = mips->mipcount; mip < 32; mip++)
|
||||
{
|
||||
mips->mip[mip].width = mips->mip[mip-1].width >> 1;
|
||||
mips->mip[mip].height = mips->mip[mip-1].height >> 1;
|
||||
|
@ -3418,7 +3418,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
case TF_RGBA32F:
|
||||
if (rawdata)
|
||||
{
|
||||
Con_Printf("R_LoadRawTexture: bad format");
|
||||
Con_Printf("R_LoadRawTexture: bad format\n");
|
||||
if (freedata)
|
||||
BZ_Free(rawdata);
|
||||
return false;
|
||||
|
@ -3428,7 +3428,7 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
|
||||
default:
|
||||
case TF_INVALID:
|
||||
Con_Printf("R_LoadRawTexture: bad format");
|
||||
Con_Printf("R_LoadRawTexture: bad format\n");
|
||||
if (freedata)
|
||||
BZ_Free(rawdata);
|
||||
return false;
|
||||
|
@ -3444,9 +3444,78 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag
|
|||
case TF_BGRA32:
|
||||
mips->encoding = PTI_BGRA8;
|
||||
break;
|
||||
case TF_MIP4_LUM8:
|
||||
//8bit opaque data
|
||||
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
|
||||
if (mips->mip[0].width == imgwidth && mips->mip[0].height == imgheight)
|
||||
{
|
||||
unsigned int pixels =
|
||||
(imgwidth>>0) * (imgheight>>0) +
|
||||
(imgwidth>>1) * (imgheight>>1) +
|
||||
(imgwidth>>2) * (imgheight>>2) +
|
||||
(imgwidth>>3) * (imgheight>>3);
|
||||
|
||||
mips->encoding = PTI_R8;
|
||||
rgbadata = BZ_Malloc(pixels);
|
||||
memcpy(rgbadata, rawdata, pixels);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
mips->mip[i].width = imgwidth>>i;
|
||||
mips->mip[i].height = imgheight>>i;
|
||||
mips->mip[i].datasize = mips->mip[i].width * mips->mip[i].height;
|
||||
mips->mip[i].needfree = false;
|
||||
}
|
||||
mips->mipcount = i;
|
||||
mips->mip[0].data = rgbadata;
|
||||
mips->mip[1].data = (qbyte*)mips->mip[0].data + mips->mip[0].datasize;
|
||||
mips->mip[2].data = (qbyte*)mips->mip[1].data + mips->mip[1].datasize;
|
||||
mips->mip[3].data = (qbyte*)mips->mip[2].data + mips->mip[2].datasize;
|
||||
|
||||
mips->extrafree = rgbadata;
|
||||
if (freedata)
|
||||
BZ_Free(rawdata);
|
||||
return true;
|
||||
}
|
||||
//fall through
|
||||
case TF_LUM8:
|
||||
mips->encoding = PTI_R8;
|
||||
break;
|
||||
case TF_MIP4_SOLID8:
|
||||
//8bit opaque data
|
||||
Image_RoundDimensions(&mips->mip[0].width, &mips->mip[0].height, flags);
|
||||
if (mips->mip[0].width == imgwidth && mips->mip[0].height == imgheight && sh_config.texfmt[PTI_RGBX8])
|
||||
{
|
||||
unsigned int pixels =
|
||||
(imgwidth>>0) * (imgheight>>0) +
|
||||
(imgwidth>>1) * (imgheight>>1) +
|
||||
(imgwidth>>2) * (imgheight>>2) +
|
||||
(imgwidth>>3) * (imgheight>>3);
|
||||
|
||||
mips->encoding = PTI_RGBX8;
|
||||
rgbadata = BZ_Malloc(pixels*4);
|
||||
for (i = 0; i < pixels; i++)
|
||||
rgbadata[i] = d_8to24rgbtable[((qbyte*)rawdata)[i]];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
mips->mip[i].width = imgwidth>>i;
|
||||
mips->mip[i].height = imgheight>>i;
|
||||
mips->mip[i].datasize = mips->mip[i].width * mips->mip[i].height * 4;
|
||||
mips->mip[i].needfree = false;
|
||||
}
|
||||
mips->mipcount = i;
|
||||
mips->mip[0].data = rgbadata;
|
||||
mips->mip[1].data = (qbyte*)mips->mip[0].data + mips->mip[0].datasize;
|
||||
mips->mip[2].data = (qbyte*)mips->mip[1].data + mips->mip[1].datasize;
|
||||
mips->mip[3].data = (qbyte*)mips->mip[2].data + mips->mip[2].datasize;
|
||||
|
||||
mips->extrafree = rgbadata;
|
||||
if (freedata)
|
||||
BZ_Free(rawdata);
|
||||
return true;
|
||||
}
|
||||
//fall through
|
||||
case TF_SOLID8:
|
||||
rgbadata = BZ_Malloc(imgwidth * imgheight*4);
|
||||
if (sh_config.texfmt[PTI_BGRX8])
|
||||
|
@ -4185,9 +4254,12 @@ image_t *Image_CreateTexture (const char *identifier, const char *subdir, unsign
|
|||
image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt)
|
||||
{
|
||||
image_t *tex;
|
||||
static int seq;
|
||||
|
||||
qboolean dontposttoworker = (flags & (IF_NOWORKER | IF_LOADNOW));
|
||||
flags &= ~IF_LOADNOW;
|
||||
qboolean lowpri = (flags & IF_LOWPRIORITY);
|
||||
qboolean highpri = (flags & IF_HIGHPRIORITY);
|
||||
flags &= ~(IF_LOADNOW | IF_LOWPRIORITY | IF_HIGHPRIORITY);
|
||||
|
||||
#ifdef LOADERTHREAD
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
|
@ -4214,16 +4286,16 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
|
|||
tex->status = TEX_LOADING;
|
||||
if (fallbackdata)
|
||||
{
|
||||
int b, pb = 0;
|
||||
int b = fallbackwidth*fallbackheight, pb = 0;
|
||||
switch(fallbackfmt)
|
||||
{
|
||||
case TF_8PAL24:
|
||||
pb = 3*256;
|
||||
b = 1;
|
||||
b *= 1;
|
||||
break;
|
||||
case TF_8PAL32:
|
||||
pb = 4*256;
|
||||
b = 1;
|
||||
b *= 1;
|
||||
break;
|
||||
case TF_LUM8:
|
||||
case TF_SOLID8:
|
||||
|
@ -4234,21 +4306,28 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
|
|||
case TF_H2_T4A4:
|
||||
case TF_HEIGHT8:
|
||||
case TF_HEIGHT8PAL: //we don't care about the actual palette.
|
||||
b = 1;
|
||||
b *= 1;
|
||||
break;
|
||||
case TF_RGBX32:
|
||||
case TF_RGBA32:
|
||||
case TF_BGRX32:
|
||||
case TF_BGRA32:
|
||||
b = 4;
|
||||
b *= 4;
|
||||
break;
|
||||
case TF_MIP4_LUM8:
|
||||
case TF_MIP4_SOLID8:
|
||||
b = (fallbackwidth>>0)*(fallbackheight>>0) +
|
||||
(fallbackwidth>>1)*(fallbackheight>>1) +
|
||||
(fallbackwidth>>2)*(fallbackheight>>2) +
|
||||
(fallbackwidth>>3)*(fallbackheight>>3);
|
||||
break;
|
||||
default:
|
||||
Sys_Error("Image_GetTexture: bad format");
|
||||
}
|
||||
tex->fallbackdata = BZ_Malloc(fallbackwidth*fallbackheight*b + pb);
|
||||
memcpy(tex->fallbackdata, fallbackdata, fallbackwidth*fallbackheight*b);
|
||||
tex->fallbackdata = BZ_Malloc(b + pb);
|
||||
memcpy(tex->fallbackdata, fallbackdata, b);
|
||||
if (pb)
|
||||
memcpy((qbyte*)tex->fallbackdata + fallbackwidth*fallbackheight*b, fallbackpalette, pb);
|
||||
memcpy((qbyte*)tex->fallbackdata + b, fallbackpalette, pb);
|
||||
tex->fallbackwidth = fallbackwidth;
|
||||
tex->fallbackheight = fallbackheight;
|
||||
tex->fallbackfmt = fallbackfmt;
|
||||
|
@ -4268,7 +4347,12 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
|
|||
if (dontposttoworker)
|
||||
Image_LoadHiResTextureWorker(tex, NULL, 0, 0);
|
||||
else
|
||||
COM_AddWork(1, Image_LoadHiResTextureWorker, tex, NULL, 0, 0);
|
||||
{
|
||||
if (lowpri)
|
||||
COM_AddWork(5, Image_LoadHiResTextureWorker, tex, NULL, 0, 0);
|
||||
else
|
||||
COM_AddWork(2+(seq++%3), Image_LoadHiResTextureWorker, tex, NULL, 0, 0);
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags)
|
||||
|
|
|
@ -114,6 +114,44 @@ void IN_ReInit(void)
|
|||
INS_ReInit();
|
||||
}
|
||||
|
||||
struct remapctx
|
||||
{
|
||||
char *type;
|
||||
char *devicename;
|
||||
int newdevid;
|
||||
};
|
||||
static void IN_DeviceIDs_DoRemap(void *vctx, char *type, char *devicename, int *qdevid)
|
||||
{
|
||||
struct remapctx *ctx = vctx;
|
||||
if (!strcmp(ctx->type, type))
|
||||
if (!strcmp(ctx->devicename, devicename))
|
||||
*qdevid = ctx->newdevid;
|
||||
}
|
||||
void IN_DeviceIDs_Enumerate(void *ctx, char *type, char *devicename, int *qdevid)
|
||||
{
|
||||
if (!qdevid)
|
||||
Con_Printf("%s (%s): %s\n", type, devicename, "device cannot be remapped");
|
||||
else
|
||||
Con_Printf("%s (%s): %i\n", type, devicename, *qdevid);
|
||||
}
|
||||
|
||||
void IN_DeviceIDs_f(void)
|
||||
{
|
||||
int i;
|
||||
char *s;
|
||||
struct remapctx ctx;
|
||||
|
||||
if (Cmd_Argc() > 3)
|
||||
{
|
||||
ctx.type = Cmd_Argv(1);
|
||||
ctx.devicename = Cmd_Argv(2);
|
||||
ctx.newdevid = atoi(Cmd_Argv(3));
|
||||
INS_EnumerateDevices(&ctx, IN_DeviceIDs_DoRemap);
|
||||
}
|
||||
else
|
||||
INS_EnumerateDevices(NULL, IN_DeviceIDs_Enumerate);
|
||||
}
|
||||
|
||||
void IN_Init(void)
|
||||
{
|
||||
events_avail = 0;
|
||||
|
@ -128,6 +166,8 @@ void IN_Init(void)
|
|||
Cvar_Register (&m_slidethreshold, "input controls");
|
||||
Cvar_Register (&m_touchmajoraxis, "input controls");
|
||||
|
||||
Cmd_AddCommand ("in_deviceids", IN_DeviceIDs_f);
|
||||
|
||||
INS_Init();
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,9 @@ void INS_ProcessInputMessage(struct InputEvent *msg, qboolean consumemotion)
|
|||
void INS_Commands(void)
|
||||
{
|
||||
}
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
}
|
||||
void INS_Move (float *movements, int pnum)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -913,6 +913,8 @@ void INS_Accumulate(void) //input polling
|
|||
void INS_Commands (void) //used to Cbuf_AddText joystick button events in windows.
|
||||
{
|
||||
}
|
||||
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ static cvar_t cl_keypad = CVAR("cl_keypad", "1");
|
|||
extern float multicursor_x[8], multicursor_y[8];
|
||||
extern qboolean multicursor_active[8];
|
||||
|
||||
POINT current_mouse_pos;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
HANDLE rawinputhandle;
|
||||
|
@ -534,9 +536,18 @@ void INS_UpdateGrabs(int fullscreen, int activeapp)
|
|||
else
|
||||
grabmouse = false;
|
||||
|
||||
//visiblity
|
||||
if (!SCR_HardwareCursorIsActive() && (fullscreen || in_simulatemultitouch.ival || grabmouse || (activeapp && mousecursor_x > 0 && mousecursor_y > 0 && mousecursor_x < vid.pixelwidth-1 && mousecursor_y < vid.pixelheight-1)))
|
||||
INS_HideMouse();
|
||||
if (activeapp)
|
||||
{
|
||||
if (!SCR_HardwareCursorIsActive() && (fullscreen || in_simulatemultitouch.ival || _windowed_mouse.value) && (current_mouse_pos.x >= window_rect.left && current_mouse_pos.y >= window_rect.top && current_mouse_pos.x <= window_rect.right && current_mouse_pos.y <= window_rect.bottom))
|
||||
{
|
||||
INS_HideMouse();
|
||||
}
|
||||
else
|
||||
{
|
||||
INS_ShowMouse();
|
||||
grabmouse = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INS_ShowMouse();
|
||||
|
@ -573,7 +584,7 @@ void INS_UpdateGrabs(int fullscreen, int activeapp)
|
|||
|
||||
|
||||
#ifdef AVAIL_DINPUT
|
||||
BOOL CALLBACK INS_EnumerateDevices(LPCDIDEVICEINSTANCE inst, LPVOID parm)
|
||||
BOOL CALLBACK INS_EnumerateDI7Devices(LPCDIDEVICEINSTANCE inst, LPVOID parm)
|
||||
{
|
||||
Con_DPrintf("EnumerateDevices found: %s\n", inst->tszProductName);
|
||||
|
||||
|
@ -620,7 +631,7 @@ int INS_InitDInput (void)
|
|||
if (FAILED(hr))
|
||||
return 0;
|
||||
|
||||
IDirectInput7_EnumDevices(g_pdi7, 0, &INS_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY);
|
||||
IDirectInput7_EnumDevices(g_pdi7, 0, &INS_EnumerateDI7Devices, NULL, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
// obtain an interface to the system mouse device.
|
||||
hr = IDirectInput7_CreateDeviceEx(g_pdi7, &fGUID_SysMouse, &fIID_IDirectInputDevice7A, &g_pMouse7, NULL);
|
||||
|
@ -678,7 +689,7 @@ int INS_InitDInput (void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
IDirectInput_EnumDevices(g_pdi, 0, &INS_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY);
|
||||
IDirectInput_EnumDevices(g_pdi, 0, &INS_EnumerateDI7Devices, NULL, DIEDFL_ATTACHEDONLY);
|
||||
|
||||
// obtain an interface to the system mouse device.
|
||||
hr = IDirectInput_CreateDevice(g_pdi, &fGUID_SysMouse, &g_pMouse, NULL);
|
||||
|
@ -1330,6 +1341,8 @@ void INS_Move (float *movements, int pnum)
|
|||
INS_MouseMove (movements, pnum);
|
||||
INS_JoyMove (movements, pnum);
|
||||
}
|
||||
else
|
||||
INS_Accumulate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1341,8 +1354,6 @@ potentially called multiple times per frame.
|
|||
*/
|
||||
void INS_Accumulate (void)
|
||||
{
|
||||
static POINT current_pos; //static to avoid bugs in vista(32) with largeaddressaware (this is fixed in win7). fixed exe base address prevents this from going above 2gb.
|
||||
|
||||
if (mouseactive && !dinput)
|
||||
{
|
||||
#ifdef USINGRAWINPUT
|
||||
|
@ -1350,9 +1361,9 @@ void INS_Accumulate (void)
|
|||
if (!rawmicecount)
|
||||
#endif
|
||||
{
|
||||
GetCursorPos (¤t_pos);
|
||||
GetCursorPos (¤t_mouse_pos);
|
||||
|
||||
IN_MouseMove(sysmouse.qdeviceid, false, current_pos.x - window_center_x, current_pos.y - window_center_y, 0, 0);
|
||||
IN_MouseMove(sysmouse.qdeviceid, false, current_mouse_pos.x - window_center_x, current_mouse_pos.y - window_center_y, 0, 0);
|
||||
}
|
||||
|
||||
// force the mouse to the center, so there's room to move (rawinput ignore this apparently)
|
||||
|
@ -1362,9 +1373,9 @@ void INS_Accumulate (void)
|
|||
if (!mouseactive)
|
||||
{
|
||||
extern int window_x, window_y;
|
||||
GetCursorPos (¤t_pos);
|
||||
GetCursorPos (¤t_mouse_pos);
|
||||
|
||||
IN_MouseMove(sysmouse.qdeviceid, true, current_pos.x-window_x, current_pos.y-window_y, 0, 0);
|
||||
IN_MouseMove(sysmouse.qdeviceid, true, current_mouse_pos.x-window_x, current_mouse_pos.y-window_y, 0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1790,6 +1801,15 @@ qboolean INS_ReadJoystick (struct wjoy_s *joy)
|
|||
}
|
||||
else
|
||||
{
|
||||
joy->povstate = 0;
|
||||
joy->buttonstate = 0;
|
||||
joy->axis[JOY_AXIS_X] = 32768;
|
||||
joy->axis[JOY_AXIS_Y] = 32768;
|
||||
joy->axis[JOY_AXIS_Z] = 32768;
|
||||
joy->axis[JOY_AXIS_R] = 32768;
|
||||
joy->axis[JOY_AXIS_U] = 32768;
|
||||
joy->axis[JOY_AXIS_V] = 32768;
|
||||
|
||||
// read error occurred
|
||||
// turning off the joystick seems too harsh for 1 read error,
|
||||
// but what should be done?
|
||||
|
@ -1994,10 +2014,29 @@ void INS_JoyMove (float *movements, int pnum)
|
|||
|
||||
for (idx = 0; idx < joy_count; idx++)
|
||||
{
|
||||
INS_JoyMovePtr(&wjoy[idx], movements, idx);
|
||||
INS_JoyMovePtr(&wjoy[idx], movements, pnum);
|
||||
}
|
||||
}
|
||||
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
int idx;
|
||||
|
||||
for (idx = 0; idx < rawmicecount; idx++)
|
||||
callback(ctx, "mouse", va("raw%i", idx), &rawmice[idx].qdeviceid);
|
||||
for (idx = 0; idx < rawkbdcount; idx++)
|
||||
callback(ctx, "keyboard", va("rawi", idx), &rawkbd[idx].qdeviceid);
|
||||
|
||||
if (dinput >= DINPUT_VERSION_DX7 && g_pMouse7)
|
||||
callback(ctx, "mouse", "di7", NULL);
|
||||
else if (dinput && g_pMouse7)
|
||||
callback(ctx, "mouse", "di", NULL);
|
||||
callback(ctx, "mouse", "system", NULL);
|
||||
|
||||
for (idx = 0; idx < joy_count; idx++)
|
||||
callback(ctx, "joy", va("mmj%i", idx), &wjoy[idx].devid);
|
||||
}
|
||||
|
||||
static qbyte scantokey[] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7
|
||||
|
|
|
@ -57,6 +57,7 @@ void INS_ReInit (void);
|
|||
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));
|
||||
|
||||
extern cvar_t cl_nodelta;
|
||||
extern cvar_t cl_c2spps;
|
||||
|
|
|
@ -338,9 +338,9 @@ void CompleteCommand (qboolean force)
|
|||
con_commandmatch = 1;
|
||||
|
||||
if (desc)
|
||||
Con_Footerf(false, "%s: %s", cmd, desc);
|
||||
Con_Footerf(NULL, false, "%s: %s", cmd, desc);
|
||||
else
|
||||
Con_Footerf(false, "");
|
||||
Con_Footerf(NULL, false, "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -374,27 +374,27 @@ void CompleteCommand (qboolean force)
|
|||
if (var)
|
||||
{
|
||||
if (desc)
|
||||
Con_Footerf(false, "%s %s\n%s", cmd, var->string, desc);
|
||||
Con_Footerf(NULL, false, "%s %s\n%s", cmd, var->string, desc);
|
||||
else
|
||||
Con_Footerf(false, "%s %s", cmd, var->string);
|
||||
Con_Footerf(NULL, false, "%s %s", cmd, var->string);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (desc)
|
||||
Con_Footerf(false, "%s: %s", cmd, desc);
|
||||
Con_Footerf(NULL, false, "%s: %s", cmd, desc);
|
||||
else
|
||||
Con_Footerf(false, "");
|
||||
Con_Footerf(NULL, false, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Footerf(false, "");
|
||||
Con_Footerf(NULL, false, "");
|
||||
con_commandmatch = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//lines typed at the main console enter here
|
||||
void Con_ExecuteLine(console_t *con, char *line)
|
||||
int Con_ExecuteLine(console_t *con, char *line)
|
||||
{
|
||||
qboolean waschat = false;
|
||||
char deutf8[8192];
|
||||
|
@ -413,7 +413,7 @@ void Con_ExecuteLine(console_t *con, char *line)
|
|||
}
|
||||
|
||||
con_commandmatch=1;
|
||||
Con_Footerf(false, "");
|
||||
Con_Footerf(con, false, "");
|
||||
|
||||
if (cls.state >= ca_connected && cl_chatmode.value == 2)
|
||||
{
|
||||
|
@ -465,10 +465,10 @@ void Con_ExecuteLine(console_t *con, char *line)
|
|||
{
|
||||
Con_Printf ("]%s\n",line);
|
||||
Cmd_ExecuteString(exec, RESTRICT_SERVER);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
Con_Footerf(false, "Commands cannot be execed while debugging QC");
|
||||
Con_Footerf(con, false, "Commands cannot be execed while debugging QC");
|
||||
}
|
||||
#endif
|
||||
Cbuf_AddText (exec, RESTRICT_LOCAL);
|
||||
|
@ -482,6 +482,8 @@ void Con_ExecuteLine(console_t *con, char *line)
|
|||
if (cls.state == ca_disconnected)
|
||||
SCR_UpdateScreen (); // force an update, because the command
|
||||
// may take some time
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vec3_t sccolor;
|
||||
|
@ -496,7 +498,7 @@ qboolean Key_GetConsoleSelectionBox(console_t *con, int *sx, int *sy, int *ex, i
|
|||
{
|
||||
*sx = *sy = *ex = *ey = 0;
|
||||
|
||||
if (con->mousedown[2] == 1)
|
||||
if (con->buttonsdown == CB_SCROLL)
|
||||
{
|
||||
//left-mouse.
|
||||
//scroll the console with the mouse. trigger links on release.
|
||||
|
@ -517,7 +519,7 @@ qboolean Key_GetConsoleSelectionBox(console_t *con, int *sx, int *sy, int *ex, i
|
|||
*ey = con->mousecursor[1];
|
||||
return true;
|
||||
}
|
||||
else if (con->mousedown[2] == 2)
|
||||
else if (con->buttonsdown == CB_COPY)
|
||||
{
|
||||
//right-mouse
|
||||
//select. copy-to-clipboard on release.
|
||||
|
@ -529,6 +531,43 @@ qboolean Key_GetConsoleSelectionBox(console_t *con, int *sx, int *sy, int *ex, i
|
|||
}
|
||||
else
|
||||
{
|
||||
if (con_curwindow == con && con->buttonsdown)
|
||||
{
|
||||
if (con->buttonsdown == CB_MOVE)
|
||||
{ //move window to track the cursor
|
||||
con->wnd_x += con->mousecursor[0] - con->mousedown[0];
|
||||
// con->mousedown[0] = con->mousecursor[0];
|
||||
con->wnd_y += con->mousecursor[1] - con->mousedown[1];
|
||||
// con->mousedown[1] = con->mousecursor[1];
|
||||
}
|
||||
if (con->buttonsdown & CB_SIZELEFT)
|
||||
{
|
||||
if (con->wnd_w - (con->mousecursor[0] - con->mousedown[0]) >= 64)
|
||||
{
|
||||
con->wnd_w -= con->mousecursor[0] - con->mousedown[0];
|
||||
con->wnd_x += con->mousecursor[0] - con->mousedown[0];
|
||||
}
|
||||
}
|
||||
if (con->buttonsdown & CB_SIZERIGHT)
|
||||
{
|
||||
if (con->wnd_w + (con->mousecursor[0] - con->mousedown[0]) >= 64)
|
||||
{
|
||||
con->wnd_w += con->mousecursor[0] - con->mousedown[0];
|
||||
con->mousedown[0] = con->mousecursor[0];
|
||||
}
|
||||
}
|
||||
if (con->buttonsdown & CB_SIZEBOTTOM)
|
||||
{
|
||||
if (con->wnd_h + (con->mousecursor[1] - con->mousedown[1]) >= 64)
|
||||
{
|
||||
con->wnd_h += con->mousecursor[1] - con->mousedown[1];
|
||||
con->mousedown[1] = con->mousecursor[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
con->buttonsdown = CB_NONE;
|
||||
|
||||
*sx = con->mousecursor[0];
|
||||
*sy = con->mousecursor[1];
|
||||
*ex = con->mousecursor[0];
|
||||
|
@ -564,7 +603,7 @@ void Key_ConsoleInsert(char *instext)
|
|||
key_linepos += len;
|
||||
}
|
||||
|
||||
void Key_DefaultLinkClicked(char *text, char *info)
|
||||
void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
||||
{
|
||||
char *c;
|
||||
/*the engine supports specific default links*/
|
||||
|
@ -639,7 +678,7 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
return;
|
||||
}
|
||||
|
||||
Con_Footerf(false, "^m#^m ^[%s\\player\\%i^]: %if %ims", cl.players[player].name, player, cl.players[player].frags, cl.players[player].ping);
|
||||
Con_Footerf(con, false, "^m#^m ^[%s\\player\\%i^]: %if %ims", cl.players[player].name, player, cl.players[player].frags, cl.players[player].ping);
|
||||
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
{
|
||||
|
@ -652,17 +691,17 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
if (cl.spectator || cls.demoplayback)
|
||||
{
|
||||
//we're spectating, or an mvd
|
||||
Con_Footerf(true, " ^[Spectate\\player\\%i\\action\\spec^]", player);
|
||||
Con_Footerf(con, true, " ^[Spectate\\player\\%i\\action\\spec^]", player);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we're playing.
|
||||
if (cls.protocol == CP_QUAKEWORLD && strcmp(cl.players[cl.playerview[0].playernum].team, cl.players[player].team))
|
||||
Con_Footerf(true, " ^[[Join Team %s]\\cmd\\setinfo team %s^]", cl.players[player].team, cl.players[player].team);
|
||||
Con_Footerf(con, true, " ^[[Join Team %s]\\cmd\\setinfo team %s^]", cl.players[player].team, cl.players[player].team);
|
||||
}
|
||||
Con_Footerf(true, " ^[%sgnore\\player\\%i\\action\\ignore^]", cl.players[player].ignored?"Uni":"I", player);
|
||||
Con_Footerf(con, true, " ^[%sgnore\\player\\%i\\action\\ignore^]", cl.players[player].ignored?"Uni":"I", player);
|
||||
// if (cl_voip_play.ival)
|
||||
Con_Footerf(true, " ^[%sute\\player\\%i\\action\\mute^]", cl.players[player].vignored?"Unm":"M", player);
|
||||
Con_Footerf(con, true, " ^[%sute\\player\\%i\\action\\mute^]", cl.players[player].vignored?"Unm":"M", player);
|
||||
|
||||
if (!cls.demoplayback && (*rcon_password.string
|
||||
#ifndef CLIENTONLY
|
||||
|
@ -670,8 +709,8 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
#endif
|
||||
))
|
||||
{
|
||||
Con_Footerf(true, " ^[Kick\\player\\%i\\action\\kick^]", player);
|
||||
Con_Footerf(true, " ^[Ban\\player\\%i\\action\\ban^]", player);
|
||||
Con_Footerf(con, true, " ^[Kick\\player\\%i\\action\\kick^]", player);
|
||||
Con_Footerf(con, true, " ^[Ban\\player\\%i\\action\\ban^]", player);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -687,20 +726,20 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
}
|
||||
else
|
||||
{
|
||||
Con_Footerf(true, " ^[Suicide\\cmd\\kill^]");
|
||||
Con_Footerf(con, true, " ^[Suicide\\cmd\\kill^]");
|
||||
#ifndef CLIENTONLY
|
||||
if (!sv.state)
|
||||
Con_Footerf(true, " ^[Disconnect\\cmd\\disconnect^]");
|
||||
Con_Footerf(con, true, " ^[Disconnect\\cmd\\disconnect^]");
|
||||
if (cls.allow_cheats || (sv.state && sv.allocated_client_slots == 1))
|
||||
#else
|
||||
Con_Footerf(true, " ^[Disconnect\\cmd\\disconnect^]");
|
||||
Con_Footerf(con, true, " ^[Disconnect\\cmd\\disconnect^]");
|
||||
if (cls.allow_cheats)
|
||||
#endif
|
||||
{
|
||||
Con_Footerf(true, " ^[Noclip\\cmd\\noclip^]");
|
||||
Con_Footerf(true, " ^[Fly\\cmd\\fly^]");
|
||||
Con_Footerf(true, " ^[God\\cmd\\god^]");
|
||||
Con_Footerf(true, " ^[Give\\impulse\\9^]");
|
||||
Con_Footerf(con, true, " ^[Noclip\\cmd\\noclip^]");
|
||||
Con_Footerf(con, true, " ^[Fly\\cmd\\fly^]");
|
||||
Con_Footerf(con, true, " ^[God\\cmd\\god^]");
|
||||
Con_Footerf(con, true, " ^[Give\\impulse\\9^]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,7 +820,7 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
c = Info_ValueForKey(info, "desc");
|
||||
if (*c)
|
||||
{
|
||||
Con_Footerf(false, "%s", c);
|
||||
Con_Footerf(con, false, "%s", c);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -805,13 +844,14 @@ void Key_DefaultLinkClicked(char *text, char *info)
|
|||
void Key_ConsoleRelease(console_t *con, int key, int unicode)
|
||||
{
|
||||
char *buffer;
|
||||
if (key == K_MOUSE1 && con->mousedown[2] == 1)
|
||||
|
||||
if (key == K_MOUSE1 && con->buttonsdown == CB_SCROLL)
|
||||
{
|
||||
con->mousedown[2] = 0;
|
||||
con->buttonsdown = CB_NONE;
|
||||
if (abs(con->mousedown[0] - con->mousecursor[0]) < 5 && abs(con->mousedown[1] - con->mousecursor[1]) < 5)
|
||||
{
|
||||
buffer = Con_CopyConsole(false, false);
|
||||
Con_Footerf(false, "");
|
||||
buffer = Con_CopyConsole(con, false, false);
|
||||
Con_Footerf(con, false, "");
|
||||
if (!buffer)
|
||||
return;
|
||||
if (keydown[K_SHIFT])
|
||||
|
@ -866,7 +906,7 @@ void Key_ConsoleRelease(console_t *con, int key, int unicode)
|
|||
if (!CSQC_ConsoleLink(buffer+2, info))
|
||||
#endif
|
||||
{
|
||||
Key_DefaultLinkClicked(buffer+2, info);
|
||||
Key_DefaultLinkClicked(con, buffer+2, info);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -881,18 +921,27 @@ void Key_ConsoleRelease(console_t *con, int key, int unicode)
|
|||
Z_Free(buffer);
|
||||
}
|
||||
else
|
||||
Con_Footerf(false, "");
|
||||
Con_Footerf(con, false, "");
|
||||
}
|
||||
if (key == K_MOUSE2 && con->mousedown[2] == 2)
|
||||
if (key == K_MOUSE2 && con->buttonsdown == CB_COPY)
|
||||
{
|
||||
con->mousedown[2] = 0;
|
||||
buffer = Con_CopyConsole(true, false); //don't keep markup if we're copying to the clipboard
|
||||
con->buttonsdown = CB_NONE;
|
||||
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
|
||||
if (!buffer)
|
||||
return;
|
||||
Sys_SaveClipboard(buffer);
|
||||
Z_Free(buffer);
|
||||
|
||||
}
|
||||
if (con->buttonsdown == CB_CLOSE)
|
||||
{ //window X (close)
|
||||
if (con->mousecursor[0] > con->wnd_w-8 && con->mousecursor[1] < 8)
|
||||
{
|
||||
Con_Destroy (con);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if (con->buttonsdown == CB_MOVE) //window title(move)
|
||||
con->buttonsdown = CB_NONE;
|
||||
}
|
||||
//if the referenced (trailing) chevron is doubled up, then it doesn't act as part of any markup and should be ignored for such things.
|
||||
static qboolean utf_specialchevron(unsigned char *start, unsigned char *chev)
|
||||
|
@ -1226,40 +1275,71 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key)
|
|||
|
||||
if ((key == K_MOUSE1 || key == K_MOUSE2))
|
||||
{
|
||||
// int xpos = (int)((con->mousecursor[0]*vid.width)/(vid.pixelwidth*8));
|
||||
int ypos = (int)((con->mousecursor[1]*vid.height)/(vid.pixelheight*8));
|
||||
if (con->flags & CONF_ISWINDOW)
|
||||
if (con->mousecursor[0] < 0 || con->mousecursor[1] < 0 || con->mousecursor[0] > con->wnd_w || con->mousecursor[1] > con->wnd_h)
|
||||
return true;
|
||||
if (con == con_mouseover)
|
||||
{
|
||||
con->buttonsdown = CB_NONE;
|
||||
|
||||
if ((con->flags & CONF_ISWINDOW) && !keydown[K_SHIFT])
|
||||
Con_SetActive(con);
|
||||
}
|
||||
con->mousedown[0] = con->mousecursor[0];
|
||||
con->mousedown[1] = con->mousecursor[1];
|
||||
if (ypos == 0 && con_mouseover)
|
||||
if (con_mouseover && con->mousedown[1] < 8)//(8.0*vid.height)/vid.pixelheight)
|
||||
{
|
||||
if (key == K_MOUSE2)
|
||||
Con_Destroy (con_mouseover);
|
||||
if (key == K_MOUSE2 && !(con->flags & CONF_ISWINDOW))
|
||||
Con_Destroy (con);
|
||||
else
|
||||
con_current = con_mouseover;
|
||||
{
|
||||
Con_SetActive(con);
|
||||
if ((con->flags & CONF_ISWINDOW))
|
||||
con->buttonsdown = (con->mousedown[0] > con->wnd_w-8)?CB_CLOSE:CB_MOVE;
|
||||
}
|
||||
}
|
||||
else if (key == K_MOUSE2)
|
||||
con->mousedown[2] = 2;
|
||||
else
|
||||
con->mousedown[2] = 1;
|
||||
con->buttonsdown = CB_COPY;
|
||||
else
|
||||
{
|
||||
con->buttonsdown = CB_NONE;
|
||||
if ((con->flags & CONF_ISWINDOW) && con->mousedown[0] < 8)
|
||||
con->buttonsdown |= CB_SIZELEFT;
|
||||
if ((con->flags & CONF_ISWINDOW) && con->mousedown[0] > con->wnd_w-8)
|
||||
con->buttonsdown |= CB_SIZERIGHT;
|
||||
if ((con->flags & CONF_ISWINDOW) && con->mousedown[1] > con->wnd_h-8)
|
||||
con->buttonsdown |= CB_SIZEBOTTOM;
|
||||
if (con->buttonsdown == CB_NONE)
|
||||
con->buttonsdown = CB_SCROLL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//console does not have any way to accept input, so don't try giving it any.
|
||||
if (!con->linebuffered)
|
||||
return false;
|
||||
|
||||
if (key == K_ENTER || key == K_KP_ENTER)
|
||||
{ // backslash text are commands, else chat
|
||||
int oldl = edit_line;
|
||||
edit_line = (edit_line + 1) & (CON_EDIT_LINES_MASK);
|
||||
history_line = edit_line;
|
||||
|
||||
if (con->linebuffered)
|
||||
{
|
||||
if (con->linebuffered(con, key_lines[oldl]+1) != 2)
|
||||
{
|
||||
edit_line = (edit_line + 1) & (CON_EDIT_LINES_MASK);
|
||||
history_line = edit_line;
|
||||
}
|
||||
}
|
||||
con_commandmatch = 0;
|
||||
|
||||
Z_Free(key_lines[edit_line]);
|
||||
key_lines[edit_line] = BZ_Malloc(2);
|
||||
key_lines[edit_line][0] = ']';
|
||||
key_lines[edit_line][1] = '\0';
|
||||
key_linepos = 1;
|
||||
|
||||
if (con->linebuffered)
|
||||
con->linebuffered(con, key_lines[oldl]+1);
|
||||
con_commandmatch = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1387,7 +1467,8 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key)
|
|||
return true;
|
||||
}
|
||||
|
||||
return Key_EntryLine(&key_lines[edit_line], 1, &key_linepos, key, unicode);
|
||||
Key_EntryLine(&key_lines[edit_line], 1, &key_linepos, key, unicode);
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -1699,9 +1780,9 @@ void Key_BindLevel_f (void)
|
|||
|
||||
c = Cmd_Argc();
|
||||
|
||||
if (c != 2 && c != 3)
|
||||
if (c != 2 && c != 4)
|
||||
{
|
||||
Con_Printf ("bindat <key> [<level> <command>] : attach a command to a key for a specific level of access\n");
|
||||
Con_Printf ("%s <key> [<level> <command>] : attach a command to a key for a specific level of access\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
b = Key_StringToKeynum (Cmd_Argv(1), &modifier);
|
||||
|
@ -1726,7 +1807,7 @@ void Key_BindLevel_f (void)
|
|||
|
||||
if (Cmd_IsInsecure())
|
||||
{
|
||||
Con_Printf("Server attempted usage of bindat\n");
|
||||
Con_Printf("Server attempted usage of %s\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1812,7 +1893,7 @@ void Key_Init (void)
|
|||
key_linepos = 1;
|
||||
|
||||
key_dest_mask = kdm_game;
|
||||
key_dest_absolutemouse = kdm_console | kdm_editor;
|
||||
key_dest_absolutemouse = kdm_console | kdm_editor | kdm_cwindows;
|
||||
|
||||
//
|
||||
// init ascii characters in console mode
|
||||
|
@ -2044,6 +2125,13 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
if (Key_Dest_Has(kdm_console))
|
||||
{
|
||||
Key_Dest_Remove(kdm_console);
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
if (!cls.state && !Key_Dest_Has(~kdm_game))
|
||||
M_ToggleMenu_f ();
|
||||
}
|
||||
else if (Key_Dest_Has(kdm_cwindows))
|
||||
{
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
if (!cls.state && !Key_Dest_Has(~kdm_game))
|
||||
M_ToggleMenu_f ();
|
||||
}
|
||||
|
@ -2078,11 +2166,19 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
//
|
||||
if (!down)
|
||||
{
|
||||
if (Key_Dest_Has(kdm_console))
|
||||
if (Key_Dest_Has(kdm_console|kdm_cwindows))
|
||||
{
|
||||
con_current->mousecursor[0] = mousecursor_x;
|
||||
con_current->mousecursor[1] = mousecursor_y;
|
||||
Key_ConsoleRelease(con_current, key, unicode);
|
||||
console_t *con = Key_Dest_Has(kdm_console)?con_current:con_curwindow;
|
||||
if (con_mouseover && key >= K_MOUSE1 && key <= K_MWHEELDOWN)
|
||||
con = con_mouseover;
|
||||
if (con_curwindow && con_curwindow != con)
|
||||
con_curwindow->buttonsdown = CB_NONE;
|
||||
if (con)
|
||||
{
|
||||
con->mousecursor[0] = mousecursor_x - ((con->flags & CONF_ISWINDOW)?con->wnd_x:0);
|
||||
con->mousecursor[1] = mousecursor_y - ((con->flags & CONF_ISWINDOW)?con->wnd_y:0);
|
||||
Key_ConsoleRelease(con, key, unicode);
|
||||
}
|
||||
}
|
||||
if (Key_Dest_Has(kdm_menu))
|
||||
M_Keyup (key, unicode);
|
||||
|
@ -2139,12 +2235,21 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
|
|||
#endif
|
||||
|
||||
|
||||
if (conkey && Key_Dest_Has(kdm_console))
|
||||
if (conkey && Key_Dest_Has(kdm_console|kdm_cwindows))
|
||||
{
|
||||
con_current->mousecursor[0] = mousecursor_x;
|
||||
con_current->mousecursor[1] = mousecursor_y;
|
||||
Key_Console (con_current, unicode, key);
|
||||
return;
|
||||
console_t *con = Key_Dest_Has(kdm_console)?con_current:con_curwindow;
|
||||
if ((con_mouseover||!Key_Dest_Has(kdm_console)) && key >= K_MOUSE1 && key <= K_MWHEELDOWN)
|
||||
con = con_mouseover;
|
||||
if (con)
|
||||
{
|
||||
con->mousecursor[0] = mousecursor_x - ((con->flags & CONF_ISWINDOW)?con->wnd_x:0);
|
||||
con->mousecursor[1] = mousecursor_y - ((con->flags & CONF_ISWINDOW)?con->wnd_y:0);
|
||||
if (Key_Console (con, unicode, key))
|
||||
return;
|
||||
}
|
||||
else
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
|
||||
}
|
||||
#ifdef TEXTEDITOR
|
||||
if (Key_Dest_Has(kdm_editor))
|
||||
|
|
|
@ -172,11 +172,12 @@ K_MAX = 256
|
|||
|
||||
typedef enum //highest has priority
|
||||
{
|
||||
kdm_game = 1u<<0, //should always be set
|
||||
kdm_message = 1u<<1,
|
||||
kdm_menu = 1u<<2,
|
||||
kdm_editor = 1u<<3,
|
||||
kdm_console = 1u<<4,
|
||||
kdm_game = 1u<<0, //should always be set
|
||||
kdm_message = 1u<<1,
|
||||
kdm_menu = 1u<<2,
|
||||
kdm_editor = 1u<<3,
|
||||
kdm_console = 1u<<4,
|
||||
kdm_cwindows = 1u<<5,
|
||||
} keydestmask_t;
|
||||
|
||||
//unsigned int Key_Dest_Get(void); //returns highest priority destination
|
||||
|
|
|
@ -1414,31 +1414,47 @@ void MC_Slider_Key(menuslider_t *option, int key)
|
|||
if (key == K_LEFTARROW || key == K_MWHEELDOWN)
|
||||
{
|
||||
range -= delta;
|
||||
if (range < option->min)
|
||||
range = option->min;
|
||||
if (option->min > option->max)
|
||||
range = bound(option->max, range, option->min);
|
||||
else
|
||||
range = bound(option->min, range, option->max);
|
||||
option->current = range;
|
||||
}
|
||||
else if (key == K_RIGHTARROW || key == K_MWHEELUP)
|
||||
{
|
||||
range += delta;
|
||||
if (range > option->max)
|
||||
range = option->max;
|
||||
if (option->min > option->max)
|
||||
range = bound(option->max, range, option->min);
|
||||
else
|
||||
range = bound(option->min, range, option->max);
|
||||
option->current = range;
|
||||
}
|
||||
else if (key == K_MOUSE1 && mousecursor_x >= ix-8 && mousecursor_x < ex+8)
|
||||
{
|
||||
range = (mousecursor_x - ix) / (ex - ix);
|
||||
range = option->min + range*(option->max-option->min);
|
||||
if (option->min > option->max)
|
||||
range = bound(option->max, range, option->min);
|
||||
else
|
||||
range = bound(option->min, range, option->max);
|
||||
option->current = range;
|
||||
}
|
||||
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1)
|
||||
{
|
||||
range += delta;
|
||||
|
||||
if (range >= option->max + delta/2)
|
||||
if (range == option->max)
|
||||
range = option->min;
|
||||
if (range > option->max)
|
||||
range = option->max;
|
||||
else
|
||||
{
|
||||
range += delta;
|
||||
if (option->min > option->max)
|
||||
{
|
||||
if (range < option->max-delta/2)
|
||||
range = option->max;
|
||||
}
|
||||
else
|
||||
if (range > option->max-delta/2)
|
||||
range = option->max;
|
||||
}
|
||||
option->current = range;
|
||||
}
|
||||
else
|
||||
|
@ -2183,6 +2199,7 @@ void M_Menu_Main_f (void)
|
|||
#endif
|
||||
if (QBigFontWorks())
|
||||
{
|
||||
int y;
|
||||
m_state = m_complex;
|
||||
Key_Dest_Add(kdm_menu);
|
||||
mainm = M_CreateMenu(0);
|
||||
|
@ -2203,18 +2220,35 @@ void M_Menu_Main_f (void)
|
|||
|
||||
MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp");
|
||||
|
||||
y = 32;
|
||||
mainm->selecteditem = (menuoption_t *)
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, 32, "Single ", "menu_single\n");
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, 52, "Multiplayer ", "menu_multi\n");
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, 72, "Options ", "menu_options\n");
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Single ", "menu_single\n"); y += 20;
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20;
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20;
|
||||
if (m_helpismedia.value)
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, 92, "Media ", "menu_media\n");
|
||||
{
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;
|
||||
}
|
||||
else
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, 92, "Help ", "help\n");
|
||||
{
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;
|
||||
}
|
||||
if (Cmd_AliasExist("mod_menu", RESTRICT_LOCAL))
|
||||
{
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, va("%-13s", Cvar_Get("mod_menu", "Mod Menu", 0, NULL)->string), "mod_menu\n"); y += 20;
|
||||
}
|
||||
if (Cmd_Exists("xmpp"))
|
||||
{
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Social ", "xmpp\n"); y += 20;
|
||||
}
|
||||
if (Cmd_Exists("irc"))
|
||||
{
|
||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;
|
||||
}
|
||||
#ifdef FTE_TARGET_WEB
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, 112,"Save Settings", "menu_quit\n");
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings", "menu_quit\n"); y += 20;
|
||||
#else
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, 112,"Quit ", "menu_quit\n");
|
||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit ", "menu_quit\n"); y += 20;
|
||||
#endif
|
||||
|
||||
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
|
||||
|
|
|
@ -151,7 +151,7 @@ qboolean ApplySetupMenu (union menuoption_s *option,struct menu_s *menu, int key
|
|||
Q_snprintfz(top, sizeof(top), "0x%x", info->topcolour&0xffffff);
|
||||
else
|
||||
Q_snprintfz(top, sizeof(top), "%i", info->topcolour);
|
||||
Cbuf_AddText(va("color %s %s\n", bot, top), RESTRICT_LOCAL);
|
||||
Cbuf_AddText(va("color %s %s\n", top, bot), RESTRICT_LOCAL);
|
||||
S_LocalSound ("misc/menu2.wav");
|
||||
M_RemoveMenu(menu);
|
||||
return true;
|
||||
|
|
|
@ -675,6 +675,8 @@ const char *presetexec[] =
|
|||
"seta r_nolerp 1;"
|
||||
"seta r_nolightdir 1;"
|
||||
"seta r_dynamic 0;"
|
||||
"seta r_bloom 0;"
|
||||
"seta r_softwarebanding 0;"
|
||||
"seta gl_polyblend 0;"
|
||||
"seta gl_flashblend 0;"
|
||||
"seta gl_specular 0;"
|
||||
|
@ -730,6 +732,7 @@ const char *presetexec[] =
|
|||
"cl_bob 0.02;"
|
||||
//these things are perhaps a little extreme
|
||||
"r_loadlit 0;"
|
||||
"r_softwarebanding 1;" //ugly software banding.
|
||||
"gl_texturemode nnl;" //yup, we went there.
|
||||
"gl_texturemode2d n.l;" //yeah, 2d too.
|
||||
"r_part_classic_square 1;" //blocky baby!
|
||||
|
@ -752,6 +755,7 @@ const char *presetexec[] =
|
|||
"gl_load24bit 1;"
|
||||
"r_replacemodels \"md3 md2\";"
|
||||
"r_coronas 1;"
|
||||
"r_softwarebanding 0;"
|
||||
"r_lerpmuzzlehack 1;"
|
||||
"gl_texturemode ln;"
|
||||
"gl_texturemode2d l;"
|
||||
|
@ -778,8 +782,8 @@ const char *presetexec[] =
|
|||
"gl_texture_anisotropic_filtering 4;"
|
||||
|
||||
, // realtime options
|
||||
// "r_bloom 1;"
|
||||
"r_particledesc \"spikeset high tsshaft\";"
|
||||
"r_bloom 1;"
|
||||
"r_particledesc \"high tsshaft\";"
|
||||
"r_waterstyle 3;"
|
||||
"r_glsl_offsetmapping 1;"
|
||||
"r_shadow_realtime_world 1;"
|
||||
|
@ -801,6 +805,7 @@ static void ApplyPreset (int presetnum)
|
|||
{
|
||||
Cbuf_InsertText(presetexec[i], RESTRICT_LOCAL, true);
|
||||
}
|
||||
Cbuf_InsertText("vid_reload\n", RESTRICT_LOCAL, true);
|
||||
forcesaveprompt = true;
|
||||
}
|
||||
|
||||
|
@ -2518,7 +2523,7 @@ void M_Menu_Video_f (void)
|
|||
MB_CMD("Apply Settings", M_VideoApply, "Restart video and apply renderer, display, and 2D resolution options."),
|
||||
MB_SPACING(4),
|
||||
MB_SLIDER("View Size", scr_viewsize, 30, 120, 10, NULL),
|
||||
MB_SLIDER("Gamma", v_gamma, 0.25, 1.5, 0.05, NULL),
|
||||
MB_SLIDER("Gamma", v_gamma, 1.5, 0.25, -0.05, NULL),
|
||||
MB_SLIDER("Contrast", v_contrast, 0.8, 3, 0.05, NULL),
|
||||
MB_END()
|
||||
};
|
||||
|
@ -2887,7 +2892,7 @@ static qboolean Mods_Key(struct menucustom_s *c, struct menu_s *m, int key)
|
|||
man = mods->manifests[i];
|
||||
mods->manifests[i] = NULL;
|
||||
M_RemoveMenu(m);
|
||||
FS_ChangeGame(man, true);
|
||||
FS_ChangeGame(man, true, true);
|
||||
|
||||
//starting to a blank state generally means that the current config settings are utterly useless and windowed by default.
|
||||
//so generally when switching to a *real* game, we want to restart video just so things like fullscreen etc are saved+used properly.
|
||||
|
@ -2935,7 +2940,7 @@ void M_Menu_Mods_f (void)
|
|||
|
||||
if (mods.nummanifests == 1)
|
||||
{
|
||||
FS_ChangeGame(mods.manifests[0], true);
|
||||
FS_ChangeGame(mods.manifests[0], true, true);
|
||||
Z_Free(mods.manifests);
|
||||
}
|
||||
else
|
||||
|
@ -2957,4 +2962,96 @@ void M_Menu_Mods_f (void)
|
|||
menu->remove = Mods_Remove;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
extern ftemanifest_t *fs_manifest; //currently active manifest.
|
||||
struct installermenudata
|
||||
{
|
||||
menuedit_t *syspath;
|
||||
};
|
||||
static void Installer_Remove (struct menu_s *m)
|
||||
{
|
||||
Cbuf_AddText("quit force\n", RESTRICT_LOCAL);
|
||||
}
|
||||
|
||||
|
||||
void FS_CreateBasedir(const char *path);
|
||||
#include <process.h>
|
||||
static qboolean Installer_Go(menuoption_t *opt, menu_t *menu, int key)
|
||||
{
|
||||
struct installermenudata *md = menu->data;
|
||||
|
||||
if (key == K_MOUSE1 || key == K_ENTER)
|
||||
{
|
||||
extern int startuppending;
|
||||
vfsfile_t *f;
|
||||
char path[MAX_OSPATH];
|
||||
char exepath[MAX_OSPATH];
|
||||
char newexepath[MAX_OSPATH];
|
||||
|
||||
Q_snprintfz(path, sizeof(path), "%s/", md->syspath->text);
|
||||
|
||||
Con_Printf("path %s\n", path);
|
||||
|
||||
menu->remove = NULL;
|
||||
M_RemoveMenu(menu);
|
||||
|
||||
FS_CreateBasedir(path);
|
||||
|
||||
#ifdef _WIN32
|
||||
GetModuleFileName(NULL, exepath, sizeof(exepath));
|
||||
FS_NativePath(va("%s.exe", fs_manifest->installation), FS_ROOT, newexepath, sizeof(newexepath));
|
||||
CopyFile(exepath, newexepath, FALSE);
|
||||
|
||||
// SetHookState(false);
|
||||
Host_Shutdown ();
|
||||
// CloseHandle (qwclsemaphore);
|
||||
// SetHookState(false);
|
||||
// _execv(newexepath, host_parms.argv);
|
||||
{
|
||||
PROCESS_INFORMATION childinfo;
|
||||
STARTUPINFO startinfo = {sizeof(startinfo)};
|
||||
CreateProcess(newexepath, va("\"%s\" +sys_register_file_associations %s", newexepath, COM_Parse(GetCommandLineA())), NULL, NULL, FALSE, 0, NULL, path, &startinfo, &childinfo);
|
||||
}
|
||||
exit(1);
|
||||
#elif 0
|
||||
#ifdef __linux__
|
||||
if (readlink("/proc/self/exe", exepath, sizeof(exepath)-1) <= 0)
|
||||
#endif
|
||||
Q_strncpyz(exepath, host_parms.argv[0], sizeof(exepath));
|
||||
|
||||
int fd = creat(newexepath, S_IRWXU | S_IRGRP|S_IXGRP);
|
||||
write(fd);
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
startuppending = 2;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void M_Menu_Installer(void)
|
||||
{
|
||||
menu_t *menu;
|
||||
struct installermenudata *md;
|
||||
|
||||
Key_Dest_Add(kdm_menu);
|
||||
|
||||
menu = M_CreateMenu(sizeof(*md));
|
||||
md = menu->data = (menu+1);
|
||||
|
||||
md->syspath = MC_AddEdit(menu, 0, 160, 64, "Path", "C:/Games/AfterQuake/testinstall/base");//va("c:/%s", fs_manifest->installation));
|
||||
|
||||
//FIXME: add path check display
|
||||
|
||||
MC_AddCommand (menu, 0, 160, 128, "Install", Installer_Go);
|
||||
MC_AddConsoleCommand(menu, 0, 160, 136, "Cancel", "menu_quit\n");
|
||||
|
||||
menu->selecteditem = (menuoption_t*)md->syspath;
|
||||
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 250, 0, menu->selecteditem->common.posy, NULL, false);
|
||||
menu->remove = Installer_Remove;
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -115,6 +115,7 @@ void M_Keyup (int key, int unicode);
|
|||
void M_Draw (int uimenu);
|
||||
void M_ToggleMenu_f (void);
|
||||
void M_Menu_Mods_f (void); //used at startup if the current gamedirs look dodgy.
|
||||
void M_Menu_Installer (void); //given an embedded manifest, this displays an install menu for said game.
|
||||
mpic_t *M_CachePic (char *path);
|
||||
void M_Menu_Quit_f (void);
|
||||
void M_Menu_Prompt (void (*callback)(void *, int), void *ctx, char *m1, char *m2, char *m3, char *optionyes, char *optionno, char *optioncancel);
|
||||
|
|
|
@ -182,6 +182,8 @@ typedef enum uploadfmt
|
|||
TF_BGR24, /*bgr byte order, no alpha channel nor pad, and regular top down*/
|
||||
TF_BGR24_FLIP, /*bgr byte order, no alpha channel nor pad, and bottom up*/
|
||||
TF_LUM8, /*8bit greyscale image*/
|
||||
TF_MIP4_LUM8, /*8bit 4-mip greyscale image*/
|
||||
TF_MIP4_SOLID8, /*8bit 4-mip image*/
|
||||
TF_SOLID8, /*8bit quake-palette image*/
|
||||
TF_TRANS8, /*8bit quake-palette image, index 255=transparent*/
|
||||
TF_TRANS8_FULLBRIGHT, /*fullbright 8 - fullbright texels have alpha 255, everything else 0*/
|
||||
|
|
|
@ -1495,8 +1495,10 @@ static void P_ParticleEffect_f(void)
|
|||
ptype->looks.blendmode = BM_INVMODC;
|
||||
else if (!strcmp(value, "blendcolour") || !strcmp(value, "blendcolor"))
|
||||
ptype->looks.blendmode = BM_BLENDCOLOUR;
|
||||
else
|
||||
else if (!strcmp(value, "blendalpha"))
|
||||
ptype->looks.blendmode = BM_BLEND;
|
||||
else
|
||||
ptype->looks.blendmode = BM_BLEND; //fallback
|
||||
}
|
||||
else if (!strcmp(var, "spawnmode"))
|
||||
{
|
||||
|
@ -5321,7 +5323,22 @@ static void R_AddTSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type)
|
|||
|
||||
|
||||
|
||||
if (type->stretch)
|
||||
if (type->stretch < 0)
|
||||
{
|
||||
vec3_t movedir;
|
||||
VectorNormalize2(p->vel, movedir);
|
||||
VectorMA(p->org, type->stretch, movedir, o2);
|
||||
VectorSubtract(r_refdef.vieworg, o2, v);
|
||||
|
||||
CrossProduct(v, p->vel, cr);
|
||||
VectorNormalize(cr);
|
||||
|
||||
VectorMA(o2, -p->scale/2, cr, cl_strisvertv[cl_numstrisvert+0]);
|
||||
VectorMA(o2, p->scale/2, cr, cl_strisvertv[cl_numstrisvert+1]);
|
||||
|
||||
VectorMA(p->org, -type->stretch, movedir, o2);
|
||||
}
|
||||
else if (type->stretch)
|
||||
{
|
||||
VectorMA(p->org, -type->stretch, p->vel, o2);
|
||||
VectorSubtract(r_refdef.vieworg, o2, v);
|
||||
|
|
|
@ -152,6 +152,8 @@ extern sfx_t *cl_sfx_r_exp3;
|
|||
globalentity(trace_ent, "trace_ent"); /*entity written by traceline*/ \
|
||||
globalfloat(trace_surfaceflags, "trace_surfaceflags"); /*float written by traceline*/ \
|
||||
globalfloat(trace_endcontents, "trace_endcontents"); /*float written by traceline EXT_CSQC_1*/ \
|
||||
globalint(trace_brush_id, "trace_brush_id"); /*int written by traceline*/ \
|
||||
globalint(trace_brush_faceid, "trace_brush_faceid"); /*int written by traceline*/ \
|
||||
\
|
||||
globalfloat(clientcommandframe, "clientcommandframe"); /*float the next frame that will be sent*/ \
|
||||
globalfloat(servercommandframe, "servercommandframe"); /*float the most recent frame received from the server*/ \
|
||||
|
@ -188,6 +190,7 @@ extern sfx_t *cl_sfx_r_exp3;
|
|||
|
||||
typedef struct {
|
||||
#define globalfloat(name,qcname) float *name
|
||||
#define globalint(name,qcname) int *name
|
||||
#define globalvector(name,qcname) float *name
|
||||
#define globalentity(name,qcname) int *name
|
||||
#define globalstring(name,qcname) string_t *name
|
||||
|
@ -197,6 +200,7 @@ typedef struct {
|
|||
csqcglobals
|
||||
|
||||
#undef globalfloat
|
||||
#undef globalint
|
||||
#undef globalvector
|
||||
#undef globalentity
|
||||
#undef globalstring
|
||||
|
@ -273,6 +277,7 @@ static void CSQC_FindGlobals(void)
|
|||
{
|
||||
static float csphysicsmode = 0;
|
||||
#define globalfloat(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
|
||||
#define globalint(name,qcname) csqcg.name = (int*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
|
||||
#define globalvector(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
|
||||
#define globalentity(name,qcname) csqcg.name = (int*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
|
||||
#define globalstring(name,qcname) csqcg.name = (string_t*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
|
||||
|
@ -281,6 +286,7 @@ static void CSQC_FindGlobals(void)
|
|||
csqcglobals
|
||||
|
||||
#undef globalfloat
|
||||
#undef globalint
|
||||
#undef globalvector
|
||||
#undef globalentity
|
||||
#undef globalstring
|
||||
|
@ -1200,6 +1206,10 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
if (!csqc_poly_shader)
|
||||
return;
|
||||
|
||||
nv = cl_numstrisvert-csqc_poly_startvert;
|
||||
if (nv == 2)
|
||||
flags |= BEF_LINES;
|
||||
|
||||
/*if the shader didn't change, continue with the old poly*/
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_poly_shader && cl_stris[cl_numstris-1].flags == flags)
|
||||
t = &cl_stris[cl_numstris-1];
|
||||
|
@ -1219,19 +1229,38 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
t->numidx = 0;
|
||||
}
|
||||
|
||||
nv = cl_numstrisvert-csqc_poly_startvert;
|
||||
if (cl_numstrisidx+(nv-2)*3 > cl_maxstrisidx)
|
||||
if (flags & BEF_LINES)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+(nv-2)*3 + 64;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
nv = cl_numstrisvert-csqc_poly_startvert;
|
||||
if (cl_numstrisidx+nv > cl_maxstrisidx)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+nv + 64;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
|
||||
/*build the triangle fan out of triangles*/
|
||||
for (i = 2; i < nv; i++)
|
||||
/*build the line list fan out of triangles*/
|
||||
for (i = 1; i < nv; i++)
|
||||
{
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i-1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i-1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i;
|
||||
nv = cl_numstrisvert-csqc_poly_startvert;
|
||||
if (cl_numstrisidx+(nv-2)*3 > cl_maxstrisidx)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+(nv-2)*3 + 64;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
|
||||
/*build the triangle fan out of triangles*/
|
||||
for (i = 2; i < nv; i++)
|
||||
{
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i-1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + i;
|
||||
}
|
||||
}
|
||||
|
||||
if (csqc_poly_flags & 4)
|
||||
|
@ -1389,7 +1418,7 @@ void QCBUILTIN PF_R_GetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
|
||||
switch(parametertype)
|
||||
{
|
||||
case VF_LPLAYER:
|
||||
case VF_ACTIVESEAT:
|
||||
if (prinst == csqc_world.progs)
|
||||
*r = csqc_playerseat;
|
||||
break;
|
||||
|
@ -1538,7 +1567,7 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
G_FLOAT(OFS_RETURN) = 1;
|
||||
switch(parametertype)
|
||||
{
|
||||
case VF_LPLAYER:
|
||||
case VF_ACTIVESEAT:
|
||||
if (prinst == csqc_world.progs)
|
||||
{
|
||||
CSQC_ChangeLocalPlayer(*p);
|
||||
|
@ -1895,6 +1924,10 @@ static void cs_settracevars(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
*csqcg.trace_surfaceflags = tr->surface?tr->surface->flags:0;
|
||||
if (csqcg.trace_endcontents)
|
||||
*csqcg.trace_endcontents = tr->contents;
|
||||
if (csqcg.trace_brush_id)
|
||||
*csqcg.trace_brush_id = tr->brush_id;
|
||||
if (csqcg.trace_brush_faceid)
|
||||
*csqcg.trace_brush_faceid = tr->brush_face;
|
||||
if (tr->ent)
|
||||
*csqcg.trace_ent = EDICT_TO_PROG(csqcprogs, (void*)tr->ent);
|
||||
else
|
||||
|
@ -2526,7 +2559,7 @@ static void QCBUILTIN PF_cs_sendevent (pubprogfuncs_t *prinst, struct globalvars
|
|||
if (!cls.state)
|
||||
return;
|
||||
|
||||
MSG_WriteByte(&cls.netchan.message, clc_qcrequest);
|
||||
MSG_WriteByte(&cls.netchan.message, clcfte_qcrequest);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (argtypes[i] == 's')
|
||||
|
@ -4965,6 +4998,13 @@ static struct {
|
|||
{"frameduration", PF_frameduration, 277},//void(float modidx, float framenum) frameduration = #277 (FTE_CSQC_SKELETONOBJECTS)
|
||||
|
||||
{"terrain_edit", PF_terrain_edit, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??)
|
||||
{"brush_get", PF_brush_get, 0},
|
||||
{"brush_create", PF_brush_create, 0},
|
||||
{"brush_delete", PF_brush_delete, 0},
|
||||
{"brush_selected", PF_brush_selected, 0},
|
||||
{"brush_getfacepoints", PF_brush_getfacepoints, 0},
|
||||
{"brush_findinvolume", PF_brush_findinvolume, 0},
|
||||
|
||||
{"touchtriggers", PF_touchtriggers, 279},//void() touchtriggers = #279;
|
||||
{"skel_ragupdate", PF_skel_ragedit, 281},// (FTE_QC_RAGDOLL)
|
||||
{"skel_mmap", PF_skel_mmap, 282},// (FTE_QC_RAGDOLL)
|
||||
|
@ -5108,6 +5148,8 @@ static struct {
|
|||
{"con_draw", PF_SubConDraw, 393},
|
||||
{"con_input", PF_SubConInput, 394},
|
||||
|
||||
{"cvars_haveunsaved", PF_cvars_haveunsaved, 0},
|
||||
|
||||
//400
|
||||
{"copyentity", PF_cs_copyentity, 400}, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
|
||||
{"setcolors", PF_NoCSQC, 401}, // #401 void(entity cl, float colours) setcolors (DP_SV_SETCOLOR) (don't implement)
|
||||
|
@ -6834,9 +6876,9 @@ void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd)
|
|||
|
||||
//this protocol allows up to 32767 edicts.
|
||||
#ifdef PEXT_CSQC
|
||||
static void CSQC_EntityCheck(int entnum)
|
||||
static void CSQC_EntityCheck(unsigned int entnum)
|
||||
{
|
||||
int newmax;
|
||||
unsigned int newmax;
|
||||
|
||||
if (entnum >= maxcsqcentities)
|
||||
{
|
||||
|
@ -6905,7 +6947,7 @@ void CSQC_GetEntityOrigin(unsigned int csqcent, float *out)
|
|||
void CSQC_ParseEntities(void)
|
||||
{
|
||||
csqcedict_t *ent;
|
||||
unsigned short entnum;
|
||||
unsigned int entnum;
|
||||
void *pr_globals;
|
||||
int packetsize;
|
||||
int packetstart;
|
||||
|
@ -6944,7 +6986,7 @@ void CSQC_ParseEntities(void)
|
|||
//replacement deltas now also includes 22bit entity num indicies.
|
||||
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||
{
|
||||
entnum = MSG_ReadShort();
|
||||
entnum = (unsigned short)MSG_ReadShort();
|
||||
removeflag = !!(entnum & 0x8000);
|
||||
if (entnum & 0x4000)
|
||||
entnum = (entnum & 0x3fff) | (MSG_ReadByte()<<14);
|
||||
|
@ -6953,7 +6995,7 @@ void CSQC_ParseEntities(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
entnum = MSG_ReadShort();
|
||||
entnum = (unsigned short)MSG_ReadShort();
|
||||
removeflag = !!(entnum & 0x8000);
|
||||
entnum &= ~0x8000;
|
||||
}
|
||||
|
|
|
@ -904,9 +904,9 @@ void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
}
|
||||
else if (!strcmp(field, "hidden"))
|
||||
{
|
||||
RETURN_TSTRING((con->flags & CON_HIDDEN)?"1":"0");
|
||||
RETURN_TSTRING((con->flags & CONF_HIDDEN)?"1":"0");
|
||||
if (value)
|
||||
con->flags = (con->flags & ~CON_HIDDEN) | (atoi(value)?CON_HIDDEN:0);
|
||||
con->flags = (con->flags & ~CONF_HIDDEN) | (atoi(value)?CONF_HIDDEN:0);
|
||||
}
|
||||
else if (!strcmp(field, "linecount"))
|
||||
{
|
||||
|
@ -943,7 +943,7 @@ void QCBUILTIN PF_SubConDraw (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
fontsize *= world->g.drawfontscale[1];
|
||||
}
|
||||
|
||||
Con_DrawOneConsole(con, PR_CL_ChooseFont(world->g.drawfont, fontsize, fontsize), pos[0], pos[1], size[0], size[1]);
|
||||
Con_DrawOneConsole(con, con->flags & CONF_KEYFOCUSED, PR_CL_ChooseFont(world->g.drawfont, fontsize, fontsize), pos[0], pos[1], size[0], size[1]);
|
||||
}
|
||||
qboolean Key_Console (console_t *con, unsigned int unicode, int key);
|
||||
void Key_ConsoleRelease (console_t *con, unsigned int unicode, int key);
|
||||
|
@ -1184,7 +1184,10 @@ void QCBUILTIN PF_isdemo (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
|
|||
//float clientstate(void) = #62;
|
||||
void QCBUILTIN PF_clientstate (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = cls.state >= ca_connected ? 2 : 1; //fit in with netquake (we never run a menu.dat dedicated)
|
||||
if (isDedicated)
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
else
|
||||
G_FLOAT(OFS_RETURN) = cls.state >= ca_connected ? 2 : 1; //fit in with netquake (we never run a menu.dat dedicated)
|
||||
}
|
||||
|
||||
//too specific to the prinst's builtins.
|
||||
|
@ -1646,6 +1649,11 @@ static void QCBUILTIN PF_m_setmodel(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
model_t *mod = Mod_ForName(modelname, MLV_WARN);
|
||||
if (modelval)
|
||||
modelval->string = G_INT(OFS_PARM1); //lets hope garbage collection is enough.
|
||||
|
||||
if (mod)
|
||||
while(mod->loadstate == MLS_LOADING)
|
||||
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
|
||||
|
||||
if (mod && minsval)
|
||||
VectorCopy(mod->mins, minsval->_vector);
|
||||
if (mod && maxsval)
|
||||
|
@ -1960,6 +1968,7 @@ static struct {
|
|||
{"con_printf", PF_SubConPrintf, 392},
|
||||
{"con_draw", PF_SubConDraw, 393},
|
||||
{"con_input", PF_SubConInput, 394},
|
||||
{"cvars_haveunsaved", PF_cvars_haveunsaved, 0},
|
||||
//gap
|
||||
{"buf_create", PF_buf_create, 440},
|
||||
{"buf_del", PF_buf_del, 441},
|
||||
|
|
|
@ -230,9 +230,10 @@ int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_lis
|
|||
|
||||
typedef struct quakeparms_s
|
||||
{
|
||||
char *basedir; //working directory
|
||||
char *binarydir; //exe directory
|
||||
int argc;
|
||||
char *basedir; //working directory
|
||||
char *binarydir; //exe directory
|
||||
const char *manifest; //linked manifest data (for installer functionality etc)
|
||||
int argc;
|
||||
const char **argv;
|
||||
} quakeparms_t;
|
||||
|
||||
|
|
|
@ -725,10 +725,18 @@ void R2D_Font_AddFontLink(char *buffer, int buffersize, char *fontname)
|
|||
#endif
|
||||
void R2D_Font_Changed(void)
|
||||
{
|
||||
float tsize;
|
||||
if (!con_textsize.modified)
|
||||
return;
|
||||
con_textsize.modified = false;
|
||||
|
||||
if (con_textsize.value < 0)
|
||||
tsize = (-con_textsize.value * vid.height) / vid.pixelheight;
|
||||
else
|
||||
tsize = con_textsize.value;
|
||||
if (!tsize)
|
||||
tsize = 8;
|
||||
|
||||
if (font_console == font_default)
|
||||
font_console = NULL;
|
||||
if (font_console)
|
||||
|
@ -763,8 +771,8 @@ void R2D_Font_Changed(void)
|
|||
CHOOSEFONTA cf = {sizeof(cf)};
|
||||
extern HWND mainwindow;
|
||||
font_default = Font_LoadFont(8, "");
|
||||
if (con_textsize.ival != 8 && con_textsize.ival >= 1)
|
||||
font_console = Font_LoadFont(con_textsize.ival, "");
|
||||
if (tsize != 8)
|
||||
font_console = Font_LoadFont(tsize, "");
|
||||
if (!font_console)
|
||||
font_console = font_default;
|
||||
|
||||
|
@ -805,11 +813,11 @@ void R2D_Font_Changed(void)
|
|||
if (!font_default && *gl_font.string)
|
||||
font_default = Font_LoadFont(8, "");
|
||||
|
||||
if (con_textsize.ival != 8 && con_textsize.ival >= 1)
|
||||
if (tsize != 8)
|
||||
{
|
||||
font_console = Font_LoadFont(con_textsize.ival, gl_font.string);
|
||||
font_console = Font_LoadFont(tsize, gl_font.string);
|
||||
if (!font_console)
|
||||
font_console = Font_LoadFont(con_textsize.ival, "");
|
||||
font_console = Font_LoadFont(tsize, "");
|
||||
}
|
||||
if (!font_console)
|
||||
font_console = font_default;
|
||||
|
@ -977,6 +985,8 @@ void R2D_BrightenScreen (void)
|
|||
//don't go crazy with brightness. that makes it unusable and is thus unsafe - and worse, lots of people assume its based around 1 (like gamma and contrast are). cap to 0.5
|
||||
if (v_brightness.value > 0.5)
|
||||
v_brightness.value = 0.5;
|
||||
if (v_contrast.value < 0.5)
|
||||
v_contrast.value = 0.5;
|
||||
|
||||
if (r2d_canhwgamma)
|
||||
return;
|
||||
|
|
|
@ -1582,7 +1582,7 @@ char *particle_set_high =
|
|||
"randomvel 1000\n"
|
||||
"friction 0.01\n"
|
||||
"gravity 100\n"
|
||||
"stretchfactor 5\n"
|
||||
"stretchfactor -80\n"
|
||||
"}\n"
|
||||
|
||||
//hide lights in explosions.
|
||||
|
@ -1633,6 +1633,8 @@ char *particle_set_high =
|
|||
|
||||
"shader\n"
|
||||
"{\n"
|
||||
"surfaceparm noshadows\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"glslprogram\n"
|
||||
"{\n"
|
||||
"varying vec2 tcoord;\n"
|
||||
|
|
|
@ -1,30 +1,9 @@
|
|||
/*
|
||||
WARNING: THIS FILE IS GENERATED BY 'generatebuiltin.c'.
|
||||
YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||
*/
|
||||
|
||||
extern char *particle_set_spikeset;
|
||||
#define R_PARTSET_BUILTINS_spikeset {"spikeset", &particle_set_spikeset},
|
||||
extern char *particle_set_faithful;
|
||||
#define R_PARTSET_BUILTINS_faithful {"faithful", &particle_set_faithful},
|
||||
extern char *particle_set_highfps;
|
||||
#define R_PARTSET_BUILTINS_highfps {"highfps", &particle_set_highfps},
|
||||
extern char *particle_set_high;
|
||||
#define R_PARTSET_BUILTINS_high {"high", &particle_set_high},
|
||||
extern char *particle_set_minimal;
|
||||
#define R_PARTSET_BUILTINS_minimal {"minimal", &particle_set_minimal},
|
||||
#ifdef HEXEN2
|
||||
extern char *particle_set_h2part;
|
||||
#define R_PARTSET_BUILTINS_h2part {"h2part", &particle_set_h2part},
|
||||
#else
|
||||
#define R_PARTSET_BUILTINS_h2part
|
||||
#endif
|
||||
#ifdef Q2CLIENT
|
||||
extern char *particle_set_q2part;
|
||||
#define R_PARTSET_BUILTINS_q2part {"q2part", &particle_set_q2part},
|
||||
#else
|
||||
#define R_PARTSET_BUILTINS_q2part
|
||||
#endif
|
||||
extern char *particle_set_tsshaft;
|
||||
#define R_PARTSET_BUILTINS_tsshaft {"tsshaft", &particle_set_tsshaft},
|
||||
#define R_PARTSET_BUILTINS R_PARTSET_BUILTINS_spikeset R_PARTSET_BUILTINS_faithful R_PARTSET_BUILTINS_highfps R_PARTSET_BUILTINS_high R_PARTSET_BUILTINS_minimal R_PARTSET_BUILTINS_h2part R_PARTSET_BUILTINS_q2part R_PARTSET_BUILTINS_tsshaft
|
||||
#define R_PARTSET_BUILTINS {"spikeset", &particle_set_spikeset},{"faithful", &particle_set_faithful},{"highfps", &particle_set_highfps},{"high", &particle_set_high},{"minimal", &particle_set_minimal},{"h2part", &particle_set_h2part},{"q2part", &particle_set_q2part},{"tsshaft", &particle_set_tsshaft},
|
||||
|
|
|
@ -280,7 +280,7 @@ void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *
|
|||
void R_LightArrays(const entity_t *entity, vecV_t *coords, vec4_t *colours, int vertcount, vec3_t *normals, float scale);
|
||||
|
||||
void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/
|
||||
void R_InitSky (struct texnums_s *ret, struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/
|
||||
void R_InitSky (struct texnums_s *tn, const char *skyname, qbyte *src, unsigned int width, unsigned int height); /*generate q1 sky texnums*/
|
||||
|
||||
void R_Clutter_Emit(struct batch_s **batches);
|
||||
void R_Clutter_Purge(void);
|
||||
|
@ -303,7 +303,7 @@ void Surf_BuildModelLightmaps (struct model_s *m); //rebuild lightmaps for a sin
|
|||
void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
|
||||
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
|
||||
int Surf_LightmapShift (struct model_s *model);
|
||||
#define LMBLOCK_SIZE_MAX 1024 //single axis
|
||||
#define LMBLOCK_SIZE_MAX 2048 //single axis
|
||||
typedef struct glRect_s {
|
||||
unsigned short l,t,w,h;
|
||||
} glRect_t;
|
||||
|
@ -371,13 +371,15 @@ enum imageflags
|
|||
IF_TEXTYPESHIFT = 8, /*0=2d, 1=3d, 2-7=cubeface*/
|
||||
IF_MIPCAP = 1<<10,
|
||||
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
|
||||
IF_LOADNOW = 1<<25,
|
||||
IF_HIGHPRIORITY = 1<<23,
|
||||
IF_LOWPRIORITY = 1<<24,
|
||||
IF_LOADNOW = 1<<25, /*hit the disk now, and delay the gl load until its actually needed. this is used only so that the width+height are known in advance*/
|
||||
IF_NOPCX = 1<<26, /*block pcx format. meaning qw skins can use team colours and cropping*/
|
||||
IF_TRYBUMP = 1<<27, /*attempt to load _bump if the specified _norm texture wasn't found*/
|
||||
IF_RENDERTARGET = 1<<28, /*never loaded from disk, loading can't fail*/
|
||||
IF_EXACTEXTENSION = 1<<29, /*don't mangle extensions, use what is specified and ONLY that*/
|
||||
IF_NOREPLACE = 1<<30, /*don't load a replacement, for some reason*/
|
||||
IF_NOWORKER = 1u<<31 /*don't pass the work to a loader thread. this gives synchronous loading.*/
|
||||
IF_NOWORKER = 1u<<31 /*don't pass the work to a loader thread. this gives fully synchronous loading. only valid from the main thread.*/
|
||||
};
|
||||
|
||||
#define R_LoadTexture8(id,w,h,d,f,t) Image_GetTexture(id, NULL, f, d, NULL, w, h, t?TF_TRANS8:TF_SOLID8)
|
||||
|
@ -455,8 +457,14 @@ void Mod_UnRegisterAllModelFormats(void *module);
|
|||
void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b);
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
void LightFace (int surfnum);
|
||||
void LightLoadEntities(char *entstring);
|
||||
struct relight_ctx_s;
|
||||
struct llightinfo_s;
|
||||
void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int surfnum); //version that is aware of bsp trees
|
||||
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, qbyte surf_styles[4], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale); //special version that doesn't know what a face is or anything.
|
||||
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, struct model_s *model, qboolean shadows);
|
||||
void LightReloadEntities(struct relight_ctx_s *ctx, char *entstring);
|
||||
void LightShutdown(struct relight_ctx_s *ctx, struct model_s *mod);
|
||||
extern const size_t lightthreadctxsize;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -505,6 +513,7 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *
|
|||
qbyte *ReadJPEGFile(qbyte *infile, int length, int *width, int *height);
|
||||
qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *name);
|
||||
qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out);
|
||||
void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight);
|
||||
|
||||
void BoostGamma(qbyte *rgba, int width, int height);
|
||||
void SaturateR8G8B8(qbyte *data, int size, float sat);
|
||||
|
@ -566,6 +575,7 @@ extern cvar_t r_coronas, r_flashblend, r_flashblendscale;
|
|||
extern cvar_t r_lightstylesmooth;
|
||||
extern cvar_t r_lightstylesmooth_limit;
|
||||
extern cvar_t r_lightstylespeed;
|
||||
extern cvar_t r_lightstylescale;
|
||||
extern cvar_t gl_nocolors;
|
||||
extern cvar_t gl_load24bit;
|
||||
extern cvar_t gl_finish;
|
||||
|
@ -626,13 +636,13 @@ extern int rquant[RQUANT_MAX];
|
|||
#define RSpeedRemark()
|
||||
#define RSpeedEnd(spt)
|
||||
#else
|
||||
#define RSpeedLocals() int rsp
|
||||
#define RSpeedMark() int rsp = (r_speeds.ival>1)?Sys_DoubleTime()*1000000:0
|
||||
#define RSpeedLocals() double rsp
|
||||
#define RSpeedMark() double rsp = (r_speeds.ival>1)?Sys_DoubleTime()*1000000:0
|
||||
#define RSpeedRemark() rsp = (r_speeds.ival>1)?Sys_DoubleTime()*1000000:0
|
||||
|
||||
#if defined(_WIN32) && defined(GLQUAKE)
|
||||
extern void (_stdcall *qglFinish) (void);
|
||||
#define RSpeedEnd(spt) do {if(r_speeds.ival > 1){if(r_speeds.ival > 2 && qglFinish)qglFinish(); rspeeds[spt] += (int)(Sys_DoubleTime()*1000000) - rsp;}}while (0)
|
||||
#define RSpeedEnd(spt) do {if(r_speeds.ival > 1){if(r_speeds.ival > 2 && qglFinish)qglFinish(); rspeeds[spt] += (double)(Sys_DoubleTime()*1000000) - rsp;}}while (0)
|
||||
#else
|
||||
#define RSpeedEnd(spt) rspeeds[spt] += (r_speeds.ival>1)?Sys_DoubleTime()*1000000 - rsp:0
|
||||
#endif
|
||||
|
|
|
@ -103,8 +103,8 @@ cvar_t r_flashblendscale = SCVARF ("gl_flashblendscale", "0.35",
|
|||
CVAR_ARCHIVE);
|
||||
cvar_t r_floorcolour = CVARAF ("r_floorcolour", "64 64 128",
|
||||
"r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
||||
cvar_t r_floortexture = SCVARF ("r_floortexture", "",
|
||||
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
||||
//cvar_t r_floortexture = SCVARF ("r_floortexture", "",
|
||||
// CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
|
||||
cvar_t r_fullbright = CVARFD ("r_fullbright", "0",
|
||||
CVAR_CHEAT|CVAR_SHADERSYSTEM, "Ignore world lightmaps, drawing everything fully lit.");
|
||||
cvar_t r_fullbrightSkins = SCVARF ("r_fullbrightSkins", "0.8", /*don't default to 1, as it looks a little ugly (too bright), but don't default to 0 either because then you're handicapped in the dark*/
|
||||
|
@ -113,6 +113,7 @@ cvar_t r_lightmap_saturation = SCVAR ("r_lightmap_saturation", "1");
|
|||
cvar_t r_lightstylesmooth = CVARF ("r_lightstylesmooth", "0", CVAR_ARCHIVE);
|
||||
cvar_t r_lightstylesmooth_limit = SCVAR ("r_lightstylesmooth_limit", "2");
|
||||
cvar_t r_lightstylespeed = SCVAR ("r_lightstylespeed", "10");
|
||||
cvar_t r_lightstylescale = SCVAR ("r_lightstylescale", "1");
|
||||
cvar_t r_loadlits = CVARF ("r_loadlit", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_menutint = SCVARF ("r_menutint", "0.68 0.4 0.13",
|
||||
CVAR_RENDERERCALLBACK);
|
||||
|
@ -127,7 +128,7 @@ cvar_t r_part_rain = CVARFD ("r_part_rain", "0",
|
|||
"Enable particle effects to emit off of surfaces. Mainly used for weather or lava/slime effects.");
|
||||
cvar_t r_skyboxname = SCVARF ("r_skybox", "",
|
||||
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||
cvar_t r_softwarebanding = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM | CVAR_RENDERERLATCH, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
|
||||
cvar_t r_softwarebanding = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
|
||||
cvar_t r_speeds = SCVAR ("r_speeds", "0");
|
||||
cvar_t r_stainfadeammount = SCVAR ("r_stainfadeammount", "1");
|
||||
cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
|
||||
|
@ -137,8 +138,8 @@ cvar_t r_stains = CVARFC("r_stains", IFMINIMAL("0","0.75"),
|
|||
cvar_t r_postprocshader = CVARD("r_postprocshader", "", "Specifies a shader to use as a post-processing shader");
|
||||
cvar_t r_wallcolour = CVARAF ("r_wallcolour", "128 128 128",
|
||||
"r_wallcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);//FIXME: broken
|
||||
cvar_t r_walltexture = CVARF ("r_walltexture", "",
|
||||
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); //FIXME: broken
|
||||
//cvar_t r_walltexture = CVARF ("r_walltexture", "",
|
||||
// CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); //FIXME: broken
|
||||
cvar_t r_wateralpha = CVARF ("r_wateralpha", "1",
|
||||
CVAR_ARCHIVE | CVAR_SHADERSYSTEM);
|
||||
cvar_t r_lavaalpha = CVARF ("r_lavaalpha", "",
|
||||
|
@ -170,7 +171,7 @@ cvar_t scr_conspeed = CVAR ("scr_conspeed", "2000");
|
|||
cvar_t scr_fov = CVARFDC("fov", "90",
|
||||
CVAR_ARCHIVE, "field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.",
|
||||
SCR_Fov_Callback);
|
||||
cvar_t scr_printspeed = SCVAR ("scr_printspeed", "8");
|
||||
cvar_t scr_printspeed = SCVAR ("scr_printspeed", "16");
|
||||
cvar_t scr_showpause = SCVAR ("showpause", "1");
|
||||
cvar_t scr_showturtle = SCVAR ("showturtle", "0");
|
||||
cvar_t scr_turtlefps = SCVAR ("scr_turtlefps", "10");
|
||||
|
@ -298,8 +299,6 @@ cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
|
|||
cvar_t r_clear = CVARAF("r_clear","0",
|
||||
"gl_clear", 0);
|
||||
cvar_t gl_max_size = CVARFD ("gl_max_size", "8192", CVAR_RENDERERLATCH, "Specifies the maximum texture size that the engine may use. Textures larger than this will be downsized. Clamped by the value the driver supports.");
|
||||
cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2",
|
||||
CVAR_ARCHIVE);
|
||||
cvar_t gl_menutint_shader = CVARD ("gl_menutint_shader", "1", "Controls the use of GLSL to desaturate the background when drawing the menu, like quake's dos software renderer used to do before the ugly dithering of winquake.");
|
||||
|
||||
//by setting to 64 or something, you can use this as a wallhack
|
||||
|
@ -333,10 +332,10 @@ cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR
|
|||
cvar_t gl_texture_anisotropic_filtering = CVARFC("gl_texture_anisotropic_filtering", "0",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
|
||||
Image_TextureMode_Callback);
|
||||
cvar_t gl_texturemode = CVARFDC("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST",
|
||||
cvar_t gl_texturemode = CVARFDC("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK | CVAR_SAVE,
|
||||
"Specifies how world/model textures appear. Typically 3 letters eg lln.\nFirst letter can be l(inear) or n(earest) and says how to sample from the mip (when downsampling).\nThe middle letter can . to disable mipmaps, or l or n to describe whether to blend between mipmaps.\nThe third letter says what to do when the texture is too low resolution and is thus the most noticable with low resolution textures, a n will make it look like lego, while an l will keep it smooth.", Image_TextureMode_Callback);
|
||||
cvar_t gl_mipcap = CVARFC("d_mipcap", "0 1000",
|
||||
cvar_t gl_mipcap = CVARAFC("d_mipcap", "0 1000", "gl_miptexLevel",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
|
||||
Image_TextureMode_Callback);
|
||||
cvar_t gl_texturemode2d = CVARFDC("gl_texturemode2d", "GL_LINEAR",
|
||||
|
@ -362,7 +361,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", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes the paralax sampling mode to be a bit nicer. 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");
|
||||
|
@ -431,7 +430,6 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&r_portaldrawplanes, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_portalonly, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_noaliasshadows, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_bumpscale_basetexture, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_bumpscale_bumpmap, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_heightscale_basetexture, GLRENDEREROPTIONS);
|
||||
|
@ -478,8 +476,8 @@ void GLRenderer_Init(void)
|
|||
|
||||
Cvar_Register (&r_wallcolour, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_floorcolour, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_walltexture, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_floortexture, GLRENDEREROPTIONS);
|
||||
// Cvar_Register (&r_walltexture, GLRENDEREROPTIONS);
|
||||
// Cvar_Register (&r_floortexture, GLRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&r_vertexdlights, GLRENDEREROPTIONS);
|
||||
|
||||
|
@ -630,6 +628,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register(&r_lightstylesmooth, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_lightstylesmooth_limit, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_lightstylespeed, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_lightstylescale, GRAPHICALNICETIES);
|
||||
|
||||
Cvar_Register(&r_stains, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES);
|
||||
|
@ -1430,6 +1429,13 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
newr->stereo = (r_stereo_method.ival == 1);
|
||||
newr->srgb = vid_srgb.ival;
|
||||
|
||||
if (com_installer)
|
||||
{
|
||||
newr->fullscreen = false;
|
||||
newr->width = 640;
|
||||
newr->height = 480;
|
||||
}
|
||||
|
||||
if (!*vid_vsync.string || vid_vsync.value < 0)
|
||||
newr->wait = -1;
|
||||
else
|
||||
|
|
|
@ -141,6 +141,13 @@ int Sbar_PlayerNum(playerview_t *pv)
|
|||
|
||||
int Sbar_TopColour(player_info_t *p)
|
||||
{
|
||||
if (cl.teamfortress)
|
||||
{
|
||||
if (!Q_strcasecmp(p->team, "red"))
|
||||
return 4;
|
||||
if (!Q_strcasecmp(p->team, "blue"))
|
||||
return 13;
|
||||
}
|
||||
if (scr_scoreboard_forcecolors.ival)
|
||||
return p->ttopcolor;
|
||||
else
|
||||
|
@ -149,6 +156,13 @@ int Sbar_TopColour(player_info_t *p)
|
|||
|
||||
int Sbar_BottomColour(player_info_t *p)
|
||||
{
|
||||
if (cl.teamfortress)
|
||||
{
|
||||
if (!Q_strcasecmp(p->team, "red"))
|
||||
return 4;
|
||||
if (!Q_strcasecmp(p->team, "blue"))
|
||||
return 13;
|
||||
}
|
||||
if (scr_scoreboard_forcecolors.ival)
|
||||
return p->tbottomcolor;
|
||||
else
|
||||
|
@ -1205,9 +1219,10 @@ int Sbar_itoa (int num, char *buf)
|
|||
num = -num;
|
||||
}
|
||||
|
||||
for (pow10 = 10 ; num >= pow10 ; pow10 *= 10)
|
||||
for (pow10 = 10 ; num >= pow10 && pow10>=10; pow10 *= 10)
|
||||
;
|
||||
|
||||
if (pow10 > 0)
|
||||
do
|
||||
{
|
||||
pow10 /= 10;
|
||||
|
@ -1229,7 +1244,7 @@ Sbar_DrawNum
|
|||
*/
|
||||
void Sbar_DrawNum (float x, float y, int num, int digits, int color)
|
||||
{
|
||||
char str[12];
|
||||
char str[16];
|
||||
char *ptr;
|
||||
int l, frame;
|
||||
#undef small
|
||||
|
|
|
@ -97,7 +97,8 @@ void SCR_SetLoadingFile(char *str);
|
|||
/*fonts*/
|
||||
void Font_Init(void);
|
||||
void Font_Shutdown(void);
|
||||
struct font_s *Font_LoadFont(int height, const char *fontfilename);
|
||||
int Font_RegisterTrackerImage(const char *image); //returns a unicode char value that can be used to embed the char within a line of text.
|
||||
struct font_s *Font_LoadFont(float height, const char *fontfilename);
|
||||
void Font_Free(struct font_s *f);
|
||||
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
|
||||
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
|
||||
|
|
|
@ -83,7 +83,7 @@ cvar_t snd_show = CVARAF( "s_show", "0",
|
|||
"snd_show", 0);
|
||||
cvar_t snd_khz = CVARAFD( "s_khz", "48",
|
||||
"snd_khz", CVAR_ARCHIVE, "Sound speed, in kilohertz. Common values are 11, 22, 44, 48. Values above 1000 are explicitly in hertz.");
|
||||
cvar_t snd_inactive = CVARAFD( "s_inactive", "0",
|
||||
cvar_t snd_inactive = CVARAFD( "s_inactive", "1",
|
||||
"snd_inactive", 0,
|
||||
"Play sound while application is inactive (ex. tabbed out). Needs a snd_restart if changed."
|
||||
); //set if you want sound even when tabbed out.
|
||||
|
@ -754,7 +754,7 @@ void S_Voip_RTP_Parse(unsigned short sequence, char *codec, unsigned char *data,
|
|||
if (!strcmp(codec, "speex@11025"))
|
||||
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_OLD, 0, sequence, datalen, data); //very much non-standard rtp
|
||||
if (!strcmp(codec, "speex@16000"))
|
||||
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_WIDE, 0, sequence, datalen, data);
|
||||
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_WIDE, 0, sequence&0xff, datalen, data);
|
||||
if (!strcmp(codec, "speex@32000"))
|
||||
S_Voip_Decode(MAX_CLIENTS-1, VOIP_SPEEX_ULTRAWIDE, 0, sequence, datalen, data);
|
||||
if (!strcmp(codec, "opus"))
|
||||
|
@ -2450,6 +2450,8 @@ void S_StopAllSounds(qboolean clear)
|
|||
{
|
||||
s = sc->channel[i].sfx;
|
||||
sc->channel[i].sfx = NULL;
|
||||
if (s->loadstate == SLS_LOADING)
|
||||
COM_WorkerPartialSync(s, &s->loadstate, SLS_LOADING);
|
||||
if (s->decoder.ended)
|
||||
if (!S_IsPlayingSomewhere(s)) //if we aint playing it elsewhere, free it compleatly.
|
||||
{
|
||||
|
|
|
@ -756,6 +756,9 @@ qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc)
|
|||
return false;
|
||||
}
|
||||
|
||||
void S_Wakeup (void *ctx, void *ctxdata, size_t a, size_t b)
|
||||
{
|
||||
}
|
||||
/*
|
||||
==============
|
||||
S_LoadSound
|
||||
|
@ -765,7 +768,7 @@ S_LoadSound
|
|||
qboolean S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b)
|
||||
{
|
||||
sfx_t *s = ctx;
|
||||
char namebuffer[256];
|
||||
char namebuffer[256];
|
||||
qbyte *data;
|
||||
int i;
|
||||
size_t result;
|
||||
|
@ -863,6 +866,8 @@ qboolean S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b)
|
|||
if (AudioInputPlugins[i](s, data, filesize, snd_speed))
|
||||
{
|
||||
s->loadstate = SLS_LOADED;
|
||||
//wake up the main thread in case it decided to wait for us.
|
||||
COM_AddWork(0, S_Wakeup, s, NULL, 0, 0);
|
||||
BZ_Free(data);
|
||||
return true;
|
||||
}
|
||||
|
@ -898,83 +903,85 @@ WAV loading
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
char *wavname;
|
||||
qbyte *data_p;
|
||||
qbyte *iff_end;
|
||||
qbyte *last_chunk;
|
||||
qbyte *iff_data;
|
||||
int iff_chunk_len;
|
||||
typedef struct
|
||||
{
|
||||
char *wavname;
|
||||
qbyte *data_p;
|
||||
qbyte *iff_end;
|
||||
qbyte *last_chunk;
|
||||
qbyte *iff_data;
|
||||
int iff_chunk_len;
|
||||
} wavctx_t;
|
||||
|
||||
|
||||
short GetLittleShort(void)
|
||||
short GetLittleShort(wavctx_t *ctx)
|
||||
{
|
||||
short val = 0;
|
||||
val = *data_p;
|
||||
val = val + (*(data_p+1)<<8);
|
||||
data_p += 2;
|
||||
val = *ctx->data_p;
|
||||
val = val + (*(ctx->data_p+1)<<8);
|
||||
ctx->data_p += 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
int GetLittleLong(void)
|
||||
int GetLittleLong(wavctx_t *ctx)
|
||||
{
|
||||
int val = 0;
|
||||
val = *data_p;
|
||||
val = val + (*(data_p+1)<<8);
|
||||
val = val + (*(data_p+2)<<16);
|
||||
val = val + (*(data_p+3)<<24);
|
||||
data_p += 4;
|
||||
val = *ctx->data_p;
|
||||
val = val + (*(ctx->data_p+1)<<8);
|
||||
val = val + (*(ctx->data_p+2)<<16);
|
||||
val = val + (*(ctx->data_p+3)<<24);
|
||||
ctx->data_p += 4;
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned int FindNextChunk(char *name)
|
||||
unsigned int FindNextChunk(wavctx_t *ctx, char *name)
|
||||
{
|
||||
unsigned int dataleft;
|
||||
|
||||
while (1)
|
||||
{
|
||||
dataleft = iff_end - last_chunk;
|
||||
dataleft = ctx->iff_end - ctx->last_chunk;
|
||||
if (dataleft < 8)
|
||||
{ // didn't find the chunk
|
||||
data_p = NULL;
|
||||
ctx->data_p = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
data_p=last_chunk;
|
||||
data_p += 4;
|
||||
ctx->data_p=ctx->last_chunk;
|
||||
ctx->data_p += 4;
|
||||
dataleft-= 8;
|
||||
iff_chunk_len = GetLittleLong();
|
||||
if (iff_chunk_len < 0)
|
||||
ctx->iff_chunk_len = GetLittleLong(ctx);
|
||||
if (ctx->iff_chunk_len < 0)
|
||||
{
|
||||
data_p = NULL;
|
||||
ctx->data_p = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (iff_chunk_len > dataleft)
|
||||
if (ctx->iff_chunk_len > dataleft)
|
||||
{
|
||||
Con_DPrintf ("\"%s\" seems truncated by %i bytes\n", wavname, iff_chunk_len-dataleft);
|
||||
Con_DPrintf ("\"%s\" seems truncated by %i bytes\n", ctx->wavname, ctx->iff_chunk_len-dataleft);
|
||||
#if 1
|
||||
iff_chunk_len = dataleft;
|
||||
ctx->iff_chunk_len = dataleft;
|
||||
#else
|
||||
data_p = NULL;
|
||||
ctx->data_p = NULL;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
dataleft-= iff_chunk_len;
|
||||
dataleft-= ctx->iff_chunk_len;
|
||||
// if (iff_chunk_len > 1024*1024)
|
||||
// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
|
||||
data_p -= 8;
|
||||
last_chunk = data_p + 8 + iff_chunk_len;
|
||||
if ((iff_chunk_len&1) && dataleft)
|
||||
last_chunk++;
|
||||
if (!Q_strncmp(data_p, name, 4))
|
||||
return iff_chunk_len;
|
||||
ctx->data_p -= 8;
|
||||
ctx->last_chunk = ctx->data_p + 8 + ctx->iff_chunk_len;
|
||||
if ((ctx->iff_chunk_len&1) && dataleft)
|
||||
ctx->last_chunk++;
|
||||
if (!Q_strncmp(ctx->data_p, name, 4))
|
||||
return ctx->iff_chunk_len;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int FindChunk(char *name)
|
||||
unsigned int FindChunk(wavctx_t *ctx, char *name)
|
||||
{
|
||||
last_chunk = iff_data;
|
||||
return FindNextChunk (name);
|
||||
ctx->last_chunk = ctx->iff_data;
|
||||
return FindNextChunk (ctx, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1004,67 +1011,72 @@ GetWavinfo
|
|||
wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
|
||||
{
|
||||
wavinfo_t info;
|
||||
int i;
|
||||
int format;
|
||||
int i;
|
||||
int format;
|
||||
int samples;
|
||||
int chunklen;
|
||||
wavctx_t ctx;
|
||||
|
||||
memset (&info, 0, sizeof(info));
|
||||
|
||||
if (!wav)
|
||||
return info;
|
||||
|
||||
iff_data = wav;
|
||||
iff_end = wav + wavlength;
|
||||
wavname = name;
|
||||
ctx.data_p = NULL;
|
||||
ctx.last_chunk = NULL;
|
||||
ctx.iff_chunk_len = 0;
|
||||
|
||||
ctx.iff_data = wav;
|
||||
ctx.iff_end = wav + wavlength;
|
||||
ctx.wavname = name;
|
||||
|
||||
// find "RIFF" chunk
|
||||
chunklen = FindChunk("RIFF");
|
||||
if (chunklen < 4 || Q_strncmp(data_p+8, "WAVE", 4))
|
||||
chunklen = FindChunk(&ctx, "RIFF");
|
||||
if (chunklen < 4 || Q_strncmp(ctx.data_p+8, "WAVE", 4))
|
||||
{
|
||||
Con_Printf("Missing RIFF/WAVE chunks in %s\n", name);
|
||||
return info;
|
||||
}
|
||||
|
||||
// get "fmt " chunk
|
||||
iff_data = data_p + 12;
|
||||
ctx.iff_data = ctx.data_p + 12;
|
||||
// DumpChunks ();
|
||||
|
||||
chunklen = FindChunk("fmt ");
|
||||
chunklen = FindChunk(&ctx, "fmt ");
|
||||
if (chunklen < 24-8)
|
||||
{
|
||||
Con_Printf("Missing/truncated fmt chunk\n");
|
||||
return info;
|
||||
}
|
||||
data_p += 8;
|
||||
format = GetLittleShort();
|
||||
ctx.data_p += 8;
|
||||
format = GetLittleShort(&ctx);
|
||||
if (format != 1)
|
||||
{
|
||||
Con_Printf("Microsoft PCM format only\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
info.numchannels = GetLittleShort();
|
||||
info.rate = GetLittleLong();
|
||||
data_p += 4+2;
|
||||
info.width = GetLittleShort() / 8;
|
||||
info.numchannels = GetLittleShort(&ctx);
|
||||
info.rate = GetLittleLong(&ctx);
|
||||
ctx.data_p += 4+2;
|
||||
info.width = GetLittleShort(&ctx) / 8;
|
||||
|
||||
// get cue chunk
|
||||
chunklen = FindChunk("cue ");
|
||||
chunklen = FindChunk(&ctx, "cue ");
|
||||
if (chunklen >= 36-8)
|
||||
{
|
||||
data_p += 32;
|
||||
info.loopstart = GetLittleLong();
|
||||
ctx.data_p += 32;
|
||||
info.loopstart = GetLittleLong(&ctx);
|
||||
// Con_Printf("loopstart=%d\n", sfx->loopstart);
|
||||
|
||||
// if the next chunk is a LIST chunk, look for a cue length marker
|
||||
chunklen = FindNextChunk ("LIST");
|
||||
chunklen = FindNextChunk (&ctx, "LIST");
|
||||
if (chunklen >= 32-8)
|
||||
{
|
||||
if (!strncmp (data_p + 28, "mark", 4))
|
||||
if (!strncmp (ctx.data_p + 28, "mark", 4))
|
||||
{ // this is not a proper parse, but it works with cooledit...
|
||||
data_p += 24;
|
||||
i = GetLittleLong (); // samples in loop
|
||||
ctx.data_p += 24;
|
||||
i = GetLittleLong (&ctx); // samples in loop
|
||||
info.samples = info.loopstart + i;
|
||||
// Con_Printf("looped length: %i\n", i);
|
||||
}
|
||||
|
@ -1074,14 +1086,14 @@ wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
|
|||
info.loopstart = -1;
|
||||
|
||||
// find data chunk
|
||||
chunklen = FindChunk("data");
|
||||
if (!chunklen)
|
||||
chunklen = FindChunk(&ctx, "data");
|
||||
if (!ctx.data_p)
|
||||
{
|
||||
Con_Printf("Missing data chunk in %s\n", name);
|
||||
return info;
|
||||
}
|
||||
|
||||
data_p += 8;
|
||||
ctx.data_p += 8;
|
||||
samples = chunklen / info.width /info.numchannels;
|
||||
|
||||
if (info.samples)
|
||||
|
@ -1101,7 +1113,7 @@ wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength)
|
|||
info.loopstart = info.samples;
|
||||
}
|
||||
|
||||
info.dataofs = data_p - wav;
|
||||
info.dataofs = ctx.data_p - wav;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -45,17 +45,19 @@ typedef struct {
|
|||
void *buf;
|
||||
} sfxdecode_t;
|
||||
|
||||
enum
|
||||
{
|
||||
SLS_NOTLOADED, //not tried to load it
|
||||
SLS_LOADING, //loading it on a worker thread.
|
||||
SLS_LOADED, //currently in memory and usable.
|
||||
SLS_FAILED //already tried to load it. it won't work. not found, invalid format, etc
|
||||
};
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_OSPATH];
|
||||
sfxdecode_t decoder;
|
||||
|
||||
enum {
|
||||
SLS_NOTLOADED, //not tried to load it
|
||||
SLS_LOADING, //loading it on a worker thread.
|
||||
SLS_LOADED, //currently in memory and usable.
|
||||
SLS_FAILED //already tried to load it. it won't work. not found, invalid format, etc
|
||||
} loadstate; //no more super-spammy
|
||||
int loadstate; //no more super-spammy
|
||||
qboolean touched:1; //if the sound is still relevent
|
||||
|
||||
#ifdef AVAIL_OPENAL
|
||||
|
|
|
@ -82,6 +82,9 @@ void INS_Move(float *movements, int pnum)
|
|||
void INS_Commands(void)
|
||||
{
|
||||
}
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
}
|
||||
void INS_Init(void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -252,7 +252,8 @@ void Sys_Printf (char *fmt, ...)
|
|||
void Sys_Quit (void)
|
||||
{
|
||||
Host_Shutdown();
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
if (!noconinput)
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
|
||||
#ifdef USE_LIBTOOL
|
||||
lt_dlexit();
|
||||
|
@ -273,7 +274,8 @@ void Sys_Error (const char *error, ...)
|
|||
char string[1024];
|
||||
|
||||
// change stdin to non blocking
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
if (!noconinput)
|
||||
fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
|
||||
|
||||
va_start (argptr,error);
|
||||
vsnprintf (string,sizeof(string)-1, error,argptr);
|
||||
|
@ -703,6 +705,9 @@ char *Sys_ConsoleInput(void)
|
|||
static char text[256];
|
||||
int len;
|
||||
|
||||
if (noconinput)
|
||||
return NULL;
|
||||
|
||||
// if (!qrenderer)
|
||||
{
|
||||
len = read (0, text, sizeof(text));
|
||||
|
|
|
@ -123,7 +123,7 @@ double Sys_DoubleTime (void)
|
|||
void Sys_Quit (void)
|
||||
{
|
||||
Host_Shutdown ();
|
||||
exit(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Sys_mkdir (char *path)
|
||||
|
@ -291,7 +291,7 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(
|
|||
#else
|
||||
|
||||
#if defined(GLQUAKE)
|
||||
//#define PRINTGLARRAYS
|
||||
#define PRINTGLARRAYS
|
||||
#endif
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUG)
|
||||
|
@ -606,7 +606,7 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
|
|||
}
|
||||
|
||||
#ifdef PRINTGLARRAYS
|
||||
if (!iswatchdog && qrenderer == QR_OPENGL)
|
||||
if (!iswatchdog && qrenderer == QR_OPENGL && Sys_IsMainThread())
|
||||
DumpGLState();
|
||||
#endif
|
||||
|
||||
|
@ -2841,7 +2841,7 @@ void Sys_SetAutoUpdateSetting(int newval)
|
|||
Update_Check();
|
||||
}
|
||||
|
||||
qboolean Sys_CheckUpdated(void)
|
||||
qboolean Sys_CheckUpdated(char *bindir, size_t bindirsize)
|
||||
{
|
||||
int ffe = COM_CheckParm("--fromfrontend");
|
||||
PROCESS_INFORMATION childinfo;
|
||||
|
@ -2924,7 +2924,12 @@ qboolean Sys_CheckUpdated(void)
|
|||
return true;
|
||||
}
|
||||
if (com_argv[ffe+2])
|
||||
{
|
||||
com_argv[0] = com_argv[ffe+2];
|
||||
Q_strncpyz(bindir, com_argv[0], bindirsize);
|
||||
*COM_SkipPath(bindir) = 0;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2936,7 +2941,7 @@ int Sys_GetAutoUpdateSetting(void)
|
|||
void Sys_SetAutoUpdateSetting(int newval)
|
||||
{
|
||||
}
|
||||
qboolean Sys_CheckUpdated(void)
|
||||
qboolean Sys_CheckUpdated(char *bindir, size_t bindirsize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -3024,6 +3029,7 @@ void Sys_DoFileAssociations(qboolean elevated)
|
|||
|
||||
Q_snprintfz(command, sizeof(command), DISTRIBUTION"_BSPFile.1");
|
||||
ok = ok & MyRegSetValue(root, "Software\\"FULLENGINENAME"\\Capabilities\\FileAssociations", ".bsp", REG_SZ, command, strlen(command));
|
||||
ok = ok & MyRegSetValue(root, "Software\\"FULLENGINENAME"\\Capabilities\\FileAssociations", ".map", REG_SZ, command, strlen(command));
|
||||
|
||||
// ok = ok & MyRegSetValue(root, "Software\\"FULLENGINENAME"\\Capabilities\\FileAssociations", ".fmf", REG_SZ, DISTRIBUTION"_ManifestFile", strlen(DISTRIBUTION"_ManifestFile"));
|
||||
// ok = ok & MyRegSetValue(root, "Software\\"FULLENGINENAME"\\Capabilities\\MIMEAssociations", "application/x-ftemanifest", REG_SZ, DISTRIBUTION"_ManifestFile", strlen(DISTRIBUTION"_ManifestFile"));
|
||||
|
@ -3172,6 +3178,593 @@ static int Sys_ProcessCommandline(char **argv, int maxargc, char *argv0)
|
|||
return i;
|
||||
}
|
||||
|
||||
//using this like posix' access function, but with much more code, microsoftisms, and no errno codes/info
|
||||
//no, I don't really have a clue why it needs to be so long.
|
||||
#include <svrapi.h>
|
||||
BOOL microsoft_access(LPCSTR pszFolder, DWORD dwAccessDesired)
|
||||
{
|
||||
HANDLE hToken;
|
||||
PRIVILEGE_SET PrivilegeSet;
|
||||
DWORD dwPrivSetSize;
|
||||
DWORD dwAccessGranted;
|
||||
BOOL fAccessGranted = FALSE;
|
||||
GENERIC_MAPPING GenericMapping;
|
||||
SECURITY_INFORMATION si = (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION);
|
||||
PSECURITY_DESCRIPTOR psdSD = NULL;
|
||||
DWORD dwNeeded;
|
||||
wchar_t wpath[MAX_OSPATH];
|
||||
widen(wpath, sizeof(wpath), pszFolder);
|
||||
GetFileSecurity(pszFolder,si,NULL,0,&dwNeeded);
|
||||
psdSD = malloc(dwNeeded);
|
||||
GetFileSecurity(pszFolder,si,psdSD,dwNeeded,&dwNeeded);
|
||||
ImpersonateSelf(SecurityImpersonation);
|
||||
OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hToken);
|
||||
memset(&GenericMapping, 0xff, sizeof(GENERIC_MAPPING));
|
||||
GenericMapping.GenericRead = ACCESS_READ;
|
||||
GenericMapping.GenericWrite = ACCESS_WRITE;
|
||||
GenericMapping.GenericExecute = 0;
|
||||
GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
|
||||
MapGenericMask(&dwAccessDesired, &GenericMapping);
|
||||
dwPrivSetSize = sizeof(PRIVILEGE_SET);
|
||||
AccessCheck(psdSD, hToken, dwAccessDesired, &GenericMapping, &PrivilegeSet, &dwPrivSetSize, &dwAccessGranted, &fAccessGranted);
|
||||
free(psdSD);
|
||||
return fAccessGranted;
|
||||
}
|
||||
|
||||
int MessageBoxU(HWND hWnd, char *lpText, char *lpCaption, UINT uType)
|
||||
{
|
||||
wchar_t widecaption[256];
|
||||
wchar_t widetext[2048];
|
||||
widen(widetext, sizeof(widetext), lpText);
|
||||
widen(widecaption, sizeof(widecaption), lpCaption);
|
||||
return MessageBoxW(hWnd, widetext, widecaption, uType);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static WNDPROC omgwtfwhyohwhy;
|
||||
LRESULT CALLBACK stoopidstoopidstoopid(HWND w, UINT m, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
switch (m)
|
||||
{
|
||||
case WM_NOTIFY:
|
||||
switch (((LPNMHDR)lp)->code)
|
||||
{
|
||||
case TVN_ENDLABELEDITW:
|
||||
{
|
||||
LRESULT r;
|
||||
NMTVDISPINFOW *fu = (NMTVDISPINFOW*)lp;
|
||||
NMTREEVIEWW gah;
|
||||
gah.action = TVC_UNKNOWN;
|
||||
gah.itemOld = fu->item;
|
||||
gah.itemNew = fu->item;
|
||||
gah.ptDrag.x = gah.ptDrag.y = 0;
|
||||
gah.hdr = fu->hdr;
|
||||
gah.hdr.code = TVN_SELCHANGEDW;
|
||||
r = CallWindowProc(omgwtfwhyohwhy,w,m,wp,lp);
|
||||
CallWindowProc(omgwtfwhyohwhy,w,WM_NOTIFY,wp,(LPARAM)&gah);
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case TVN_ENDLABELEDITA:
|
||||
{
|
||||
LRESULT r;
|
||||
NMTVDISPINFOA *fu = (NMTVDISPINFOA*)lp;
|
||||
NMTREEVIEWA gah;
|
||||
gah.action = TVC_UNKNOWN;
|
||||
gah.itemOld = fu->item;
|
||||
gah.itemNew = fu->item;
|
||||
gah.ptDrag.x = gah.ptDrag.y = 0;
|
||||
gah.hdr = fu->hdr;
|
||||
gah.hdr.code = TVN_SELCHANGEDA;
|
||||
r = CallWindowProc(omgwtfwhyohwhy,w,m,wp,lp);
|
||||
CallWindowProc(omgwtfwhyohwhy,w,WM_NOTIFY,wp,(LPARAM)&gah);
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case TVN_SELCHANGEDA:
|
||||
case TVN_SELCHANGEDW:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CallWindowProc(omgwtfwhyohwhy,w,m,wp,lp);
|
||||
}
|
||||
|
||||
struct egadsthisisretarded
|
||||
{
|
||||
char title[MAX_OSPATH];
|
||||
char subdir[MAX_OSPATH];
|
||||
char parentdir[MAX_OSPATH];
|
||||
char statustext[MAX_OSPATH];
|
||||
};
|
||||
|
||||
static INT CALLBACK StupidBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pDatafoo)
|
||||
{ //'stolen' from microsoft's knowledge base.
|
||||
//required to work around microsoft being annoying.
|
||||
struct egadsthisisretarded *pData = (struct egadsthisisretarded*)pDatafoo;
|
||||
TCHAR szDir[MAX_PATH];
|
||||
// char *foo;
|
||||
HWND edit = FindWindowEx(hwnd, NULL, "EDIT", NULL);
|
||||
HWND list;
|
||||
extern qboolean com_homepathenabled;
|
||||
// OutputDebugString(va("got %u (%u)\n", uMsg, lp));
|
||||
switch(uMsg)
|
||||
{
|
||||
case BFFM_INITIALIZED:
|
||||
OutputDebugString("initialised\n");
|
||||
|
||||
//combat windows putting new windows behind everything else if it takes a while for UAC prompts to go away
|
||||
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
||||
|
||||
//combat windows bug where renaming something doesn't update the dialog's path
|
||||
list = FindWindowEx(hwnd, NULL, "SHBROWSEFORFOLDER SHELLNAMESPACE CONTROL", NULL);
|
||||
if (list)
|
||||
omgwtfwhyohwhy = (WNDPROC)SetWindowLongPtr(list, GWLP_WNDPROC, (LONG_PTR)stoopidstoopidstoopid);
|
||||
|
||||
#ifndef _DEBUG
|
||||
//the standard location iiuc
|
||||
if (com_homepathenabled && SHGetSpecialFolderPath(NULL, szDir, CSIDL_PROGRAM_FILES, TRUE) && microsoft_access(szDir, ACCESS_READ | ACCESS_WRITE))
|
||||
;
|
||||
else if (microsoft_access("C:\\Games\\", ACCESS_READ | ACCESS_WRITE))
|
||||
Q_strncpyz(szDir, "C:\\Games\\", sizeof(szDir));
|
||||
else if (microsoft_access("C:\\", ACCESS_READ | ACCESS_WRITE))
|
||||
Q_strncpyz(szDir, "C:\\", sizeof(szDir));
|
||||
//if we're not an admin, install it somewhere else.
|
||||
else if (SHGetSpecialFolderPath(NULL, szDir, CSIDL_LOCAL_APPDATA, TRUE) && microsoft_access(szDir, ACCESS_READ | ACCESS_WRITE))
|
||||
;
|
||||
else
|
||||
#endif
|
||||
if (GetCurrentDirectory(sizeof(szDir)/sizeof(TCHAR), szDir) && microsoft_access(szDir, ACCESS_READ | ACCESS_WRITE))
|
||||
;
|
||||
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)szDir);
|
||||
// SendMessage(hwnd, BFFM_SETEXPANDED, TRUE, (LPARAM)szDir);
|
||||
SendMessageW(hwnd, BFFM_SETOKTEXT, TRUE, (LPARAM)L"Install");
|
||||
break;
|
||||
case BFFM_VALIDATEFAILEDA:
|
||||
if (!microsoft_access(pData->parentdir, ACCESS_READ | ACCESS_WRITE))
|
||||
return 1;
|
||||
if (edit)
|
||||
GetWindowText(edit, pData->subdir, sizeof(pData->subdir));
|
||||
|
||||
if (microsoft_access(va("%s\\%s", pData->parentdir, pData->subdir), ACCESS_READ))
|
||||
return MessageBoxU(hwnd, va("%s\\%s already exists!\nThis installer will (generally) not overwrite.\nIf you want to re-install, you must manually uninstall it first.\n\nContinue?", pData->parentdir, pData->subdir), fs_gamename.string, MB_ICONWARNING|MB_OKCANCEL|MB_TOPMOST) == IDCANCEL;
|
||||
else
|
||||
return MessageBoxU(hwnd, va("Install to %s\\%s ?", pData->parentdir, pData->subdir), fs_gamename.string, MB_OKCANCEL) == IDCANCEL;
|
||||
case BFFM_VALIDATEFAILEDW:
|
||||
return 1;//!microsoft_access("C:\\Games\\", ACCESS_READ | ACCESS_WRITE))
|
||||
case BFFM_SELCHANGED:
|
||||
OutputDebugString("selchanged\n");
|
||||
if (SHGetPathFromIDList((LPITEMIDLIST)lp, pData->parentdir))
|
||||
{
|
||||
// OutputDebugString(va("selchanged: %s\n", szDir));
|
||||
// while(foo = strchr(pData->parentdir, '\\'))
|
||||
// *foo = '/';
|
||||
//fixme: verify that id1 is a subdir perhaps?
|
||||
if (edit)
|
||||
{
|
||||
SetWindowText(edit, fs_gamename.string);
|
||||
SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)va("%s", pData->parentdir));
|
||||
}
|
||||
else
|
||||
SendMessageA(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)va("%s/%s", pData->parentdir, fs_gamename.string));
|
||||
}
|
||||
break;
|
||||
case BFFM_IUNKNOWN:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK NoCloseWindowProc(HWND w, UINT m, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
if (m == WM_CLOSE)
|
||||
return 0;
|
||||
return DefWindowProc(w, m, wp, lp);
|
||||
}
|
||||
|
||||
void FS_CreateBasedir(const char *path);
|
||||
qboolean Sys_DoInstall(void)
|
||||
{
|
||||
extern ftemanifest_t *fs_manifest;
|
||||
char exepath[MAX_OSPATH];
|
||||
char newexepath[MAX_OSPATH];
|
||||
char resultpath[MAX_PATH];
|
||||
BROWSEINFO bi;
|
||||
LPITEMIDLIST il;
|
||||
struct egadsthisisretarded diediedie;
|
||||
|
||||
if (fs_manifest && fs_manifest->eula)
|
||||
{
|
||||
if (MessageBoxU(NULL, fs_manifest->eula, fs_gamename.string, MB_OKCANCEL|MB_TOPMOST|MB_DEFBUTTON2) != IDOK)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
memset(&bi, 0, sizeof(bi));
|
||||
bi.hwndOwner = mainwindow; //note that this is usually still null
|
||||
bi.pidlRoot = NULL;
|
||||
GetCurrentDirectory(sizeof(resultpath)-1, resultpath);
|
||||
bi.pszDisplayName = resultpath;
|
||||
Q_snprintfz(diediedie.title, sizeof(diediedie.title), "Where would you like to install %s to?", fs_gamename.string);
|
||||
bi.lpszTitle = diediedie.title;
|
||||
bi.ulFlags = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT | BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_VALIDATE;
|
||||
bi.lpfn = StupidBrowseCallbackProc;
|
||||
bi.lParam = (LPARAM)&diediedie;
|
||||
bi.iImage = 0;
|
||||
|
||||
Q_strncpyz(diediedie.subdir, fs_gamename.string, sizeof(diediedie.subdir));
|
||||
|
||||
il = SHBrowseForFolder(&bi);
|
||||
if (il)
|
||||
{
|
||||
SHGetPathFromIDList(il, resultpath);
|
||||
CoTaskMemFree(il);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
Q_strncatz(resultpath, "/", sizeof(resultpath));
|
||||
if (*diediedie.subdir)
|
||||
{
|
||||
Q_strncatz(resultpath, diediedie.subdir, sizeof(resultpath));
|
||||
Q_strncatz(resultpath, "/", sizeof(resultpath));
|
||||
}
|
||||
|
||||
FS_CreateBasedir(resultpath);
|
||||
|
||||
GetModuleFileName(NULL, exepath, sizeof(exepath));
|
||||
FS_NativePath(va("%s.exe", fs_gamename.string), FS_ROOT, newexepath, sizeof(newexepath));
|
||||
CopyFile(exepath, newexepath, FALSE);
|
||||
|
||||
/*the game can now be run (using regular autoupdate stuff), but most installers are expected to install the data instead of just more downloaders, so lets do that with a 'nice' progress box*/
|
||||
{
|
||||
HINSTANCE hInstance = NULL;
|
||||
HWND progress, label, wnd;
|
||||
WNDCLASS wc;
|
||||
RECT ca;
|
||||
int sh;
|
||||
int pct = -100;
|
||||
char fname[MAX_OSPATH];
|
||||
memset(&wc, 0, sizeof(wc));
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = NoCloseWindowProc;//Progress_Wnd;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wc.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wc.lpszClassName = "FTEPROG";
|
||||
RegisterClass(&wc);
|
||||
|
||||
ca.right = GetSystemMetrics(SM_CXSCREEN);
|
||||
ca.bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
mainwindow = wnd = CreateWindowEx(0, wc.lpszClassName, va("%s Installer", fs_gamename.string), 0, (ca.right-320)/2, (ca.bottom-100)/2, 320, 100, NULL, NULL, hInstance, NULL);
|
||||
|
||||
GetClientRect(wnd, &ca);
|
||||
sh = GetSystemMetrics(SM_CYVSCROLL);
|
||||
|
||||
InitCommonControls();
|
||||
label = CreateWindow("STATIC","", WS_CHILD | WS_VISIBLE | SS_PATHELLIPSIS, sh, ((ca.bottom-ca.top-sh)/3), ca.right-ca.left-2*sh, sh, wnd, NULL, hInstance, NULL);
|
||||
progress = CreateWindowEx(0, PROGRESS_CLASS, NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, sh, ((ca.bottom-ca.top-sh)/3)*2, ca.right-ca.left-2*sh, sh, wnd, NULL, hInstance, NULL);
|
||||
|
||||
ShowWindow(wnd, SW_NORMAL);
|
||||
SetWindowPos(wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
|
||||
|
||||
SendMessage(progress, PBM_SETRANGE32, 0, 10000);
|
||||
*fname = 0;
|
||||
HTTP_CL_Think();
|
||||
while(FS_DownloadingPackage())
|
||||
{
|
||||
MSG msg;
|
||||
char *cur = cls.download?COM_SkipPath(cls.download->localname):"Please Wait";
|
||||
int newpct = cls.download?cls.download->percent*100:0;
|
||||
|
||||
if (cls.download && cls.download->sizeunknown)
|
||||
{
|
||||
//marquee needs manifest bollocks in order to work. so lets just not bother.
|
||||
float time = Sys_DoubleTime();
|
||||
newpct = 10000 * (time - (int)time);
|
||||
if ((int)time & 1)
|
||||
newpct = 10000 - newpct;
|
||||
}
|
||||
|
||||
if (Q_strcmp(fname, cur))
|
||||
{
|
||||
Q_strncpyz(fname, cur, sizeof(fname));
|
||||
SetWindowText(label, fname);
|
||||
}
|
||||
if (pct != newpct)
|
||||
{
|
||||
SendMessage(progress, PBM_SETPOS, pct, 0);
|
||||
pct = newpct;
|
||||
}
|
||||
|
||||
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
|
||||
DispatchMessage (&msg);
|
||||
|
||||
Sleep(10);
|
||||
HTTP_CL_Think();
|
||||
}
|
||||
DestroyWindow(progress);
|
||||
DestroyWindow(wnd);
|
||||
UnregisterClass("FTEPROG", hInstance);
|
||||
mainwindow = NULL;
|
||||
}
|
||||
|
||||
/*create startmenu icon*/
|
||||
if (MessageBoxU(NULL, va("Create Startmenu icon for %s?", fs_gamename.string), fs_gamename.string, MB_YESNO|MB_ICONQUESTION|MB_TOPMOST) == IDYES)
|
||||
{
|
||||
HRESULT hres;
|
||||
IShellLinkW *psl;
|
||||
hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (LPVOID*)&psl);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
char startmenu[MAX_OSPATH];
|
||||
WCHAR wsz[MAX_PATH];
|
||||
IPersistFile *ppf;
|
||||
widen(wsz, sizeof(wsz), newexepath);
|
||||
psl->lpVtbl->SetPath(psl, wsz);
|
||||
widen(wsz, sizeof(wsz), resultpath);
|
||||
psl->lpVtbl->SetWorkingDirectory(psl, wsz);
|
||||
hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
|
||||
if (SUCCEEDED(hres) && SHGetSpecialFolderPath(NULL, startmenu, CSIDL_COMMON_PROGRAMS, TRUE))
|
||||
{
|
||||
WCHAR wsz[MAX_PATH];
|
||||
widen(wsz, sizeof(wsz), va("%s/%s.lnk", startmenu, fs_gamename.string));
|
||||
hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
|
||||
if (hres == E_ACCESSDENIED && SHGetSpecialFolderPath(NULL, startmenu, CSIDL_PROGRAMS, TRUE))
|
||||
{
|
||||
widen(wsz, sizeof(wsz), va("%s/%s.lnk", startmenu, fs_gamename.string));
|
||||
hres = ppf->lpVtbl->Save(ppf, wsz, TRUE);
|
||||
}
|
||||
ppf->lpVtbl->Release(ppf);
|
||||
}
|
||||
psl->lpVtbl->Release(psl);
|
||||
}
|
||||
}
|
||||
|
||||
//now start it up properly.
|
||||
ShellExecute(mainwindow, "open", newexepath, Q_strcasecmp(fs_manifest->installation, "quake")?"":"+sys_register_file_associations", resultpath, SW_SHOWNORMAL);
|
||||
return true;
|
||||
}
|
||||
qboolean Sys_RunInstaller(void)
|
||||
{
|
||||
HINSTANCE ch;
|
||||
char exepath[MAX_OSPATH];
|
||||
if (COM_CheckParm("-doinstall"))
|
||||
return Sys_DoInstall();
|
||||
if (!com_installer)
|
||||
return false;
|
||||
if (MessageBoxU(NULL, va("%s is not installed. Install now?", fs_gamename.string), fs_gamename.string, MB_OKCANCEL|MB_ICONQUESTION|MB_TOPMOST) == IDOK)
|
||||
{
|
||||
GetModuleFileName(NULL, exepath, sizeof(exepath));
|
||||
ch = ShellExecute(mainwindow, "runas", com_argv[0], va("%s -doinstall", COM_Parse(GetCommandLine())), NULL, SW_SHOWNORMAL);
|
||||
if ((intptr_t)ch > 32)
|
||||
return true; //succeeded. should quit out.
|
||||
return Sys_DoInstall(); //if it failed, try doing it with the current privileges
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "fs.h"
|
||||
#define RESLANG MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK)
|
||||
static const char *Sys_FindManifest(void)
|
||||
{
|
||||
HRSRC hdl = FindResource(NULL, MAKEINTRESOURCE(1), RT_RCDATA);
|
||||
HGLOBAL hgl = LoadResource(NULL, hdl);
|
||||
return LockResource(hgl);
|
||||
}
|
||||
|
||||
//size info that microsoft recommends
|
||||
static const struct
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int bpp;
|
||||
} icosizes[] = {
|
||||
// {96, 96, 32},
|
||||
{48, 48, 32},
|
||||
{32, 32, 32},
|
||||
{16, 16, 32},
|
||||
// {16, 16, 4},
|
||||
// {48, 48, 4},
|
||||
// {32, 32, 4},
|
||||
// {16, 16, 1},
|
||||
// {48, 48, 1},
|
||||
// {32, 32, 1},
|
||||
{256, 256, 32} //vista!
|
||||
};
|
||||
//dates back to 16bit windows. bah.
|
||||
#pragma pack(push)
|
||||
#pragma pack(2)
|
||||
typedef struct
|
||||
{
|
||||
WORD idReserved;
|
||||
WORD idType;
|
||||
WORD idCount;
|
||||
struct
|
||||
{
|
||||
BYTE bWidth;
|
||||
BYTE bHeight;
|
||||
BYTE bColorCount;
|
||||
BYTE bReserved;
|
||||
WORD wPlanes;
|
||||
WORD wBitCount;
|
||||
DWORD dwBytesInRes;
|
||||
WORD nId;
|
||||
} idEntries[sizeof(icosizes)/sizeof(icosizes[0])];
|
||||
} icon_group_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static void Sys_MakeInstaller(const char *name)
|
||||
{
|
||||
vfsfile_t *filehandle;
|
||||
qbyte *filedata;
|
||||
unsigned int filelen;
|
||||
char *error = NULL;
|
||||
HANDLE bin;
|
||||
char ourname[MAX_OSPATH];
|
||||
char newname[MAX_OSPATH];
|
||||
char tmpname[MAX_OSPATH];
|
||||
|
||||
Q_snprintfz(newname, sizeof(newname), "%s.exe", name);
|
||||
Q_snprintfz(tmpname, sizeof(tmpname), "tmp.exe");
|
||||
|
||||
GetModuleFileName(NULL, ourname, sizeof(ourname));
|
||||
|
||||
if (!CopyFile(ourname, tmpname, FALSE))
|
||||
error = va("\"%s\" already exists or cannot be written", tmpname);
|
||||
|
||||
if (!(bin = BeginUpdateResource(tmpname, FALSE)))
|
||||
error = "BeginUpdateResource failed";
|
||||
else
|
||||
{
|
||||
//nuke existing icons.
|
||||
UpdateResource(bin, RT_GROUP_ICON, MAKEINTRESOURCE(1), RESLANG, NULL, 0);
|
||||
UpdateResource(bin, RT_GROUP_ICON, MAKEINTRESOURCE(2), RESLANG, NULL, 0);
|
||||
// UpdateResource(bin, RT_GROUP_ICON, MAKEINTRESOURCE(3), RESLANG, NULL, 0);
|
||||
|
||||
filehandle = VFSOS_Open(va("%s.png", name), "rb");
|
||||
if (filehandle)
|
||||
{
|
||||
icon_group_t icondata;
|
||||
qbyte *rgbadata;
|
||||
int imgwidth, imgheight;
|
||||
int iconid = 1;
|
||||
qboolean hasalpha;
|
||||
memset(&icondata, 0, sizeof(icondata));
|
||||
icondata.idType = 1;
|
||||
filelen = VFS_GETLEN(filehandle);
|
||||
filedata = BZ_Malloc(filelen);
|
||||
VFS_READ(filehandle, filedata, filelen);
|
||||
VFS_CLOSE(filehandle);
|
||||
|
||||
rgbadata = Read32BitImageFile(filedata, filelen, &imgwidth, &imgheight, &hasalpha, va("%s.png", name));
|
||||
if (!rgbadata)
|
||||
error = "unable to read icon image";
|
||||
else
|
||||
{
|
||||
void *data = NULL;
|
||||
unsigned int datalen = 0;
|
||||
unsigned int i;
|
||||
extern cvar_t gl_lerpimages;
|
||||
gl_lerpimages.ival = 1;
|
||||
for (i = 0; i < sizeof(icosizes)/sizeof(icosizes[0]); i++)
|
||||
{
|
||||
unsigned int x,y;
|
||||
unsigned int pixels;
|
||||
if (icosizes[i].width > imgwidth || icosizes[i].height > imgheight)
|
||||
continue; //ignore icons if they're bigger than the original icon.
|
||||
|
||||
if (icosizes[i].bpp == 32 && icosizes[i].width >= 128 && icosizes[i].height >= 128 && icosizes[i].width == imgwidth && icosizes[i].height == imgheight)
|
||||
{ //png compression. oh look. we originally loaded a png!
|
||||
data = filedata;
|
||||
datalen = filelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
//generate the bitmap info
|
||||
BITMAPV4HEADER *bi;
|
||||
qbyte *out, *outmask;
|
||||
qbyte *in, *inrow;
|
||||
unsigned int outidx;
|
||||
|
||||
pixels = icosizes[i].width * icosizes[i].height;
|
||||
|
||||
bi = data = Z_Malloc(sizeof(*bi) + icosizes[i].width * icosizes[i].height * 5 + icosizes[i].height*4);
|
||||
memset(bi,0, sizeof(BITMAPINFOHEADER));
|
||||
bi->bV4Size = sizeof(BITMAPINFOHEADER);
|
||||
bi->bV4Width = icosizes[i].width;
|
||||
bi->bV4Height = icosizes[i].height * 2;
|
||||
bi->bV4Planes = 1;
|
||||
bi->bV4BitCount = icosizes[i].bpp;
|
||||
bi->bV4V4Compression = BI_RGB;
|
||||
bi->bV4ClrUsed = (icosizes[i].bpp>=32?0:(1u<<icosizes[i].bpp));
|
||||
|
||||
datalen = bi->bV4Size;
|
||||
out = (qbyte*)data + datalen;
|
||||
datalen += ((icosizes[i].width*icosizes[i].bpp/8+3)&~3) * icosizes[i].height;
|
||||
outmask = (qbyte*)data + datalen;
|
||||
datalen += ((icosizes[i].width+31)&~31)/8 * icosizes[i].height;
|
||||
|
||||
in = malloc(pixels*4);
|
||||
Image_ResampleTexture((unsigned int*)rgbadata, imgwidth, imgheight, (unsigned int*)in, icosizes[i].width, icosizes[i].height);
|
||||
|
||||
inrow = in;
|
||||
outidx = 0;
|
||||
if (icosizes[i].bpp == 32)
|
||||
{
|
||||
for (y = 0; y < icosizes[i].height; y++)
|
||||
{
|
||||
inrow = in + 4*icosizes[i].width*(icosizes[i].height-1-y);
|
||||
for (x = 0; x < icosizes[i].width; x++)
|
||||
{
|
||||
if (inrow[3] == 0) //transparent
|
||||
outmask[outidx>>3] |= 1u<<(outidx&7);
|
||||
else
|
||||
{
|
||||
out[0] = inrow[2];
|
||||
out[1] = inrow[1];
|
||||
out[2] = inrow[0];
|
||||
}
|
||||
out += 4;
|
||||
outidx++;
|
||||
inrow += 4;
|
||||
}
|
||||
if (x & 3)
|
||||
out += 4 - (x&3);
|
||||
outidx = (outidx + 31)&~31;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!error && !UpdateResource(bin, RT_ICON, MAKEINTRESOURCE(iconid), 0, data, datalen))
|
||||
error = "UpdateResource failed (icon data)";
|
||||
|
||||
//and make a copy of it in the icon list
|
||||
icondata.idEntries[icondata.idCount].bWidth = (icosizes[i].width<256)?icosizes[i].width:0;
|
||||
icondata.idEntries[icondata.idCount].bHeight = (icosizes[i].height<256)?icosizes[i].height:0;
|
||||
icondata.idEntries[icondata.idCount].wBitCount = icosizes[i].bpp;
|
||||
icondata.idEntries[icondata.idCount].wPlanes = 1;
|
||||
icondata.idEntries[icondata.idCount].bColorCount = (icosizes[i].bpp>=8)?0:(1u<<icosizes[i].bpp);
|
||||
icondata.idEntries[icondata.idCount].dwBytesInRes = datalen;
|
||||
icondata.idEntries[icondata.idCount].nId = iconid++;
|
||||
icondata.idCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error && !UpdateResource(bin, RT_GROUP_ICON, MAKEINTRESOURCE(IDI_ICON1), RESLANG, &icondata, (qbyte*)&icondata.idEntries[icondata.idCount] - (qbyte*)&icondata))
|
||||
error = "UpdateResource failed (icon group)";
|
||||
BZ_Free(filedata);
|
||||
}
|
||||
else
|
||||
error = va("%s.ico not found", name);
|
||||
|
||||
filehandle = VFSOS_Open(va("%s.fmf", name), "rb");
|
||||
if (filehandle)
|
||||
{
|
||||
filelen = VFS_GETLEN(filehandle);
|
||||
filedata = BZ_Malloc(filelen+1);
|
||||
filedata[filelen] = 0;
|
||||
VFS_READ(filehandle, filedata, filelen);
|
||||
VFS_CLOSE(filehandle);
|
||||
if (!error && !UpdateResource(bin, RT_RCDATA, MAKEINTRESOURCE(1), 0, filedata, filelen+1))
|
||||
error = "UpdateResource failed (manicfest)";
|
||||
BZ_Free(filedata);
|
||||
}
|
||||
else
|
||||
error = va("%s.fmf not found in working directory", name);
|
||||
|
||||
if (!EndUpdateResource(bin, !!error) && !error)
|
||||
error = "EndUpdateResource failed. Check access permissions.";
|
||||
|
||||
DeleteFile(newname);
|
||||
MoveFile(tmpname, newname);
|
||||
}
|
||||
|
||||
if (error)
|
||||
Sys_Error("%s", error);
|
||||
}
|
||||
|
||||
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
// MSG msg;
|
||||
|
@ -3234,8 +3827,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
MessageBox(NULL, "This is an SSE2 optimised build, and your cpu doesn't seem to support it", DISTRIBUTION, 0);
|
||||
else
|
||||
#endif
|
||||
if (!(idedx&(1<<25)))
|
||||
MessageBox(NULL, "This is an SSE optimised build, and your cpu doesn't seem to support it", DISTRIBUTION, 0);
|
||||
if (!(idedx&(1<<25)))
|
||||
MessageBox(NULL, "This is an SSE optimised build, and your cpu doesn't seem to support it", DISTRIBUTION, 0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -3297,7 +3890,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
isPlugin = 0;
|
||||
}
|
||||
|
||||
if (Sys_CheckUpdated())
|
||||
if (Sys_CheckUpdated(bindir, sizeof(bindir)))
|
||||
return true;
|
||||
|
||||
if (COM_CheckParm("-register_types"))
|
||||
|
@ -3349,6 +3942,15 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
if (!GetCurrentDirectoryA (sizeof(cwd), cwd))
|
||||
Sys_Error ("Couldn't determine current directory");
|
||||
}
|
||||
|
||||
c = COM_CheckParm("-makeinstaller");
|
||||
if (c)
|
||||
{
|
||||
Sys_MakeInstaller(parms.argv[c+1]);
|
||||
return true;
|
||||
}
|
||||
parms.manifest = Sys_FindManifest();
|
||||
|
||||
if (parms.argc >= 2)
|
||||
{
|
||||
if (*parms.argv[1] != '-' && *parms.argv[1] != '+')
|
||||
|
@ -3380,7 +3982,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
}
|
||||
else
|
||||
{
|
||||
MessageBox(NULL, "Expected one argument, got multiple", "Blocking potential remote exploit", 0);
|
||||
MessageBox(NULL, va("Invalid commandline:\n%s", lpCmdLine), FULLENGINENAME, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3408,8 +4010,10 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
TL_InitLanguages();
|
||||
//tprints are now allowed
|
||||
|
||||
if (*cwd && cwd[strlen(cwd)-1] != '\\' && cwd[strlen(cwd)-1] != '/')
|
||||
Q_strncatz(cwd, "/", sizeof(cwd));
|
||||
|
||||
parms.basedir = cwd;
|
||||
parms.binarydir = bindir;
|
||||
|
||||
parms.argc = com_argc;
|
||||
parms.argv = com_argv;
|
||||
|
@ -3545,8 +4149,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* return success of application */
|
||||
return TRUE;
|
||||
/* return success of application */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int __cdecl main(void)
|
||||
|
|
|
@ -532,7 +532,7 @@ void Validation_Apply_Ruleset(void)
|
|||
#endif
|
||||
Validation_DelatchRulesets(); //make sure there's no old one
|
||||
|
||||
if (!*ruleset.string || !strcmp(ruleset.string, "none"))
|
||||
if (!*ruleset.string || !strcmp(ruleset.string, "none") || !strcmp(ruleset.string, "default"))
|
||||
return; //no ruleset is set
|
||||
|
||||
for (rs = rulesets; rs->rulesetname; rs++)
|
||||
|
|
|
@ -51,6 +51,8 @@ void W_CleanupName (const char *in, char *out)
|
|||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
c += ('a' - 'A');
|
||||
if (c == '*') //not a valid filesystem char
|
||||
c = '#';
|
||||
out[i] = c;
|
||||
}
|
||||
|
||||
|
@ -253,9 +255,9 @@ int numwadtextures;
|
|||
static texwadlump_t texwadlump[TEXWAD_MAXIMAGES];
|
||||
|
||||
typedef struct wadfile_s {
|
||||
char name[64];
|
||||
vfsfile_t *file;
|
||||
struct wadfile_s *next;
|
||||
char name[1];
|
||||
} wadfile_t;
|
||||
|
||||
wadfile_t *openwadfiles;
|
||||
|
@ -345,6 +347,12 @@ void W_LoadTextureWadFile (char *filename, int complain)
|
|||
}
|
||||
}
|
||||
// leaves the file open
|
||||
|
||||
wf = BZ_Malloc(sizeof(*wf) + strlen(filename));
|
||||
strcpy(wf->name, filename);
|
||||
wf->file = file;
|
||||
wf->next = openwadfiles;
|
||||
openwadfiles = wf;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -384,6 +392,9 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, size_t lumpsize, int *width, int *hei
|
|||
else if (!strncmp(tex->name, "window", 6) || !strncmp(tex->name, "glass", 5))
|
||||
alpha = 2;
|
||||
|
||||
if (tex->width > 0x10000 || tex->height > 0x10000)
|
||||
return NULL;
|
||||
|
||||
//use malloc here if you want, but you'll have to free it again... NUR!
|
||||
data = out = BZ_Malloc(tex->width * tex->height * 4);
|
||||
|
||||
|
@ -394,10 +405,17 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, size_t lumpsize, int *width, int *hei
|
|||
|
||||
*width = tex->width;
|
||||
*height = tex->height;
|
||||
pal = in + (((tex->width * tex->height) * 85) >> 6);
|
||||
pal += 2;
|
||||
if (pal+768 - (qbyte*)tex > lumpsize)
|
||||
|
||||
//halflife wads have palettes embedded in them. but make sure everything else is packed because some quake wads are weird.
|
||||
if (tex->offsets[0] == sizeof(*tex) &&
|
||||
tex->offsets[1] == tex->offsets[0] + (tex->width)*(tex->height) &&
|
||||
tex->offsets[2] == tex->offsets[1] + (tex->width>>1)*(tex->height>>1) &&
|
||||
tex->offsets[3] == tex->offsets[2] + (tex->width>>2)*(tex->height>>2) &&
|
||||
lumpsize == tex->offsets[3] + (tex->width>>3)*(tex->height>>3) + 2 + 768)
|
||||
pal = (qbyte *)tex + tex->offsets[3] + (tex->width>>3)*(tex->height>>3) + 2;
|
||||
else
|
||||
pal = host_basepal;
|
||||
|
||||
for (d = 0;d < tex->width * tex->height;d++)
|
||||
{
|
||||
p = *in++;
|
||||
|
@ -482,6 +500,39 @@ qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalp
|
|||
return NULL;
|
||||
}
|
||||
|
||||
miptex_t *W_GetMipTex(const char *name)
|
||||
{
|
||||
char texname[17];
|
||||
int i, j;
|
||||
vfsfile_t *file;
|
||||
miptex_t *tex;
|
||||
|
||||
texname[16] = 0;
|
||||
W_CleanupName (name, texname);
|
||||
for (i = 0;i < numwadtextures;i++)
|
||||
{
|
||||
if (!strcmp(texname, texwadlump[i].name)) // found it
|
||||
{
|
||||
file = texwadlump[i].file;
|
||||
if (!VFS_SEEK(file, texwadlump[i].position))
|
||||
{Con_Printf("W_GetTexture: corrupt WAD3 file");return NULL;}
|
||||
|
||||
tex = BZ_Malloc(texwadlump[i].size); //temp buffer for disk info (was hunk_tempalloc, but that wiped loading maps and the like
|
||||
if (!tex)
|
||||
return NULL;
|
||||
if (VFS_READ(file, tex, texwadlump[i].size) < texwadlump[i].size)
|
||||
{Con_Printf("W_GetTexture: corrupt WAD3 file");return NULL;}
|
||||
|
||||
tex->width = LittleLong(tex->width);
|
||||
tex->height = LittleLong(tex->height);
|
||||
for (j = 0;j < MIPLEVELS;j++)
|
||||
tex->offsets[j] = LittleLong(tex->offsets[j]);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct mapgroup_s {
|
||||
char *mapname;
|
||||
char *skyname;
|
||||
|
|
|
@ -116,3 +116,4 @@ qbyte *W_ConvertWAD3Texture(miptex_t *tex, size_t lumpsize, int *width, int *hei
|
|||
void Mod_ParseInfoFromEntityLump(struct model_s *wmodel);
|
||||
qboolean Wad_NextDownload (void);
|
||||
qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalpha);
|
||||
miptex_t *W_GetMipTex(const char *name);
|
||||
|
|
|
@ -79,8 +79,8 @@ void TP_SkinCvar_Callback(struct cvar_s *var, char *oldvalue);
|
|||
TP_CVAR(tp_autostatus, ""); /* things which will not always change, but are useful */ \
|
||||
TP_CVAR(tp_forceTriggers, "0"); \
|
||||
TP_CVAR(tp_loadlocs, "1"); \
|
||||
TP_CVARC(cl_teamskin, "", TP_SkinCvar_Callback); \
|
||||
TP_CVARC(cl_enemyskin, "", TP_SkinCvar_Callback); \
|
||||
TP_CVARAC(cl_teamskin, "", teamskin, TP_SkinCvar_Callback); \
|
||||
TP_CVARAC(cl_enemyskin, "", enemyskin, TP_SkinCvar_Callback); \
|
||||
TP_CVAR(tp_soundtrigger, "~"); \
|
||||
\
|
||||
TP_CVAR(tp_name_none, ""); \
|
||||
|
@ -165,9 +165,11 @@ void TP_SkinCvar_Callback(struct cvar_s *var, char *oldvalue);
|
|||
//create the globals for all the TP cvars.
|
||||
#define TP_CVAR(name,def) cvar_t name = CVAR(#name, def)
|
||||
#define TP_CVARC(name,def,call) cvar_t name = CVARC(#name, def, call)
|
||||
#define TP_CVARAC(name,def,name2,call) cvar_t name = CVARAFC(#name, def, #name2, 0, call)
|
||||
TP_CVARS;
|
||||
#undef TP_CVAR
|
||||
#undef TP_CVARC
|
||||
#undef TP_CVARAC
|
||||
|
||||
extern cvar_t host_mapname;
|
||||
|
||||
|
@ -2092,57 +2094,118 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
|
|||
player_info_t *player;
|
||||
char *name;
|
||||
|
||||
*offset = 0;
|
||||
*plr = NULL;
|
||||
|
||||
flags = TPM_UNKNOWN;
|
||||
msglen = strlen(s);
|
||||
if (!msglen)
|
||||
return TPM_UNKNOWN;
|
||||
|
||||
*offset = 0;
|
||||
*plr = NULL;
|
||||
|
||||
for (i=0, player=cl.players ; i < cl.allocated_client_slots ; i++, player++)
|
||||
if ((s[0] == '^' && s[1] == '[') || (s[0] == '(' && s[1] == '^' && s[2] == '['))
|
||||
{
|
||||
name = player->name;
|
||||
if (!(*name))
|
||||
continue;
|
||||
len = strlen(name);
|
||||
// check messagemode1
|
||||
if (len+2 <= msglen && s[len] == ':' && s[len+1] == ' ' &&
|
||||
!strncmp(name, s, len))
|
||||
char *end, *info;
|
||||
i = 0;
|
||||
for(info = s; *info; )
|
||||
{
|
||||
if (info[0] == '^' && info[1] == ']')
|
||||
break;
|
||||
if (*info == '\\')
|
||||
break;
|
||||
if (info[0] == '^' && info[1] == '^')
|
||||
info+=2;
|
||||
else
|
||||
info++;
|
||||
}
|
||||
for(end = info; *end; )
|
||||
{
|
||||
if (end[0] == '^' && end[1] == ']')
|
||||
{
|
||||
*end = 0;
|
||||
info = Info_ValueForKey(info, "player");
|
||||
if (*info)
|
||||
i = atoi(info)+1;
|
||||
*end = '^';
|
||||
break;
|
||||
}
|
||||
if (end[0] == '^' && end[1] == '^')
|
||||
end+=2;
|
||||
else
|
||||
end++;
|
||||
}
|
||||
if (!*end || i < 1 || i > cl.allocated_client_slots)
|
||||
return TPM_UNKNOWN;
|
||||
if (*s == '(')
|
||||
{
|
||||
if (end[2] != ')')
|
||||
return TPM_UNKNOWN;
|
||||
end+=3;
|
||||
}
|
||||
else
|
||||
end+=2;
|
||||
if (*end++ != ':')
|
||||
return TPM_UNKNOWN;
|
||||
if (*end++ != ' ')
|
||||
return TPM_UNKNOWN;
|
||||
*plr = player = &cl.players[i-1];
|
||||
*offset = end - s;
|
||||
|
||||
if (*s == '(')
|
||||
flags = TPM_TEAM;
|
||||
else
|
||||
{
|
||||
if (player->spectator)
|
||||
flags |= TPM_SPECTATOR;
|
||||
else
|
||||
flags |= TPM_NORMAL;
|
||||
*offset = len + 2;
|
||||
*plr = player;
|
||||
}
|
||||
// check messagemode2
|
||||
else if (s[0] == '(' && len+4 <= msglen &&
|
||||
!strncmp(s+len+1, "): ", 3) &&
|
||||
!strncmp(name, s+1, len))
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0, player=cl.players ; i < cl.allocated_client_slots ; i++, player++)
|
||||
{
|
||||
// no team messages in teamplay 0, except for our own
|
||||
if (cl.spectator)
|
||||
name = player->name;
|
||||
if (!(*name))
|
||||
continue;
|
||||
len = strlen(name);
|
||||
// check messagemode1
|
||||
if (len+2 <= msglen && s[len] == ':' && s[len+1] == ' ' &&
|
||||
!strncmp(name, s, len))
|
||||
{
|
||||
unsigned int track = Cam_TrackNum(&cl.playerview[SP]);
|
||||
if (i == track || ( cl.teamplay &&
|
||||
!strcmp(cl.players[track].team, player->team)) )
|
||||
{
|
||||
flags |= TPM_OBSERVEDTEAM;
|
||||
}
|
||||
if (player->spectator)
|
||||
flags |= TPM_SPECTATOR;
|
||||
else
|
||||
flags |= TPM_NORMAL;
|
||||
*offset = len + 2;
|
||||
*plr = player;
|
||||
}
|
||||
else
|
||||
// check messagemode2
|
||||
else if (s[0] == '(' && len+4 <= msglen &&
|
||||
!strncmp(s+len+1, "): ", 3) &&
|
||||
!strncmp(name, s+1, len))
|
||||
{
|
||||
if (i == cl.playerview[SP].playernum || ( cl.teamplay &&
|
||||
!strcmp(cl.players[cl.playerview[SP].playernum].team, player->team)) )
|
||||
// no team messages in teamplay 0, except for our own
|
||||
if (cl.spectator)
|
||||
{
|
||||
flags |= TPM_TEAM;
|
||||
unsigned int track = Cam_TrackNum(&cl.playerview[SP]);
|
||||
if (i == track || ( cl.teamplay &&
|
||||
!strcmp(cl.players[track].team, player->team)) )
|
||||
{
|
||||
flags |= TPM_OBSERVEDTEAM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == cl.playerview[SP].playernum || ( cl.teamplay &&
|
||||
!strcmp(cl.players[cl.playerview[SP].playernum].team, player->team)) )
|
||||
{
|
||||
flags |= TPM_TEAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*offset = len + 4;
|
||||
*plr = player;
|
||||
*offset = len + 4;
|
||||
*plr = player;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3390,9 +3453,11 @@ void TP_Init (void)
|
|||
//register all the TeamPlay cvars.
|
||||
#define TP_CVAR(name,def) Cvar_Register (&name, TEAMPLAYVARS);
|
||||
#define TP_CVARC(name,def,callback) Cvar_Register (&name, TEAMPLAYVARS);
|
||||
#define TP_CVARAC(name,def,name2,callback) Cvar_Register (&name, TEAMPLAYVARS);
|
||||
TP_CVARS;
|
||||
#undef TP_CVAR
|
||||
#undef TP_CVARC
|
||||
#undef TP_CVARAC
|
||||
|
||||
Cmd_AddCommand ("loadloc", TP_LoadLocFile_f);
|
||||
Cmd_AddCommand ("filter", TP_MsgFilter_f);
|
||||
|
@ -3429,7 +3494,7 @@ qboolean TP_SuppressMessage(char *buf) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags);
|
||||
void CL_PrintChat(player_info_t *plr, char *msg, int plrflags);
|
||||
|
||||
void CL_Say (qboolean team, char *extra)
|
||||
{
|
||||
|
@ -3509,7 +3574,7 @@ void CL_Say (qboolean team, char *extra)
|
|||
if (team)
|
||||
plrflags |= 2;
|
||||
|
||||
CL_PrintChat(&cl.players[cl.playerview[SP].playernum], NULL, text, plrflags);
|
||||
CL_PrintChat(&cl.players[cl.playerview[SP].playernum], text, plrflags);
|
||||
}
|
||||
|
||||
//strip out the extra markup
|
||||
|
|
|
@ -149,7 +149,7 @@ struct {
|
|||
sizebuf_t buf;
|
||||
int noclear;
|
||||
double waitattime;
|
||||
} cmd_text[RESTRICT_MAX+1+MAX_SPLITS]; //max is local.
|
||||
} cmd_text[RESTRICT_MAX+3+MAX_SPLITS]; //max is local.
|
||||
//RESTRICT_MAX+1 is the from sever buffer (max+2 is for second player...)
|
||||
|
||||
/*
|
||||
|
|
|
@ -88,6 +88,7 @@ qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *description
|
|||
// as a clc_stringcmd instead of executed locally
|
||||
|
||||
qboolean Cmd_Exists (const char *cmd_name);
|
||||
char *Cmd_AliasExist(const char *name, int restrictionlevel);
|
||||
// used by the cvar code to check for cvar / command name overlap
|
||||
|
||||
char *Cmd_Describe (char *cmd_name);
|
||||
|
|
|
@ -2336,7 +2336,10 @@ static frameinfo_t *ParseFrameInfo(char *modelname, int *numgroups)
|
|||
line = COM_ParseOut(line, tok, sizeof(tok));
|
||||
frames[count].fps = atof(tok);
|
||||
line = COM_ParseOut(line, tok, sizeof(tok));
|
||||
frames[count].loop = !!atoi(tok);
|
||||
if (!strcmp(tok, "true") || !strcmp(tok, "yes") || !strcmp(tok, "on"))
|
||||
frames[count].loop = true;
|
||||
else
|
||||
frames[count].loop = !!atoi(tok);
|
||||
line = COM_ParseOut(line, frames[count].name, sizeof(frames[count].name));
|
||||
if (frames[count].posecount>0 && frames[count].fps)
|
||||
count++;
|
||||
|
@ -3150,6 +3153,40 @@ static void *Q1_LoadSkins_GL (model_t *loadmodel, daliasskintype_t *pskintype, u
|
|||
}
|
||||
#endif
|
||||
|
||||
void Mesh_HandleFramegroupsFile(model_t *mod, galiasinfo_t *galias)
|
||||
{
|
||||
unsigned int numanims, a, p, n, g, oldnumanims = galias->numanimations, targpose;
|
||||
galiasanimation_t *o, *oldanims = galias->ofsanimations, *frame;
|
||||
frameinfo_t *framegroups = ParseFrameInfo(mod->name, &numanims);
|
||||
if (framegroups)
|
||||
{
|
||||
galias->ofsanimations = o = ZG_Malloc(&mod->memgroup, sizeof(*galias->ofsanimations) * numanims);
|
||||
for (a = 0; a < numanims; a++, o++)
|
||||
{
|
||||
o->poseofs = ZG_Malloc(&mod->memgroup, sizeof(*o->poseofs) * framegroups[a].posecount);
|
||||
for (p = 0; p < framegroups[a].posecount; p++)
|
||||
{
|
||||
targpose = framegroups[a].firstpose + p;
|
||||
for (n = 0, g = 0, frame = oldanims; g < oldnumanims; g++, frame++)
|
||||
{
|
||||
if (targpose < frame->numposes)
|
||||
break;
|
||||
targpose -= frame->numposes;
|
||||
}
|
||||
if (g == oldnumanims)
|
||||
break;
|
||||
o->poseofs[p] = frame->poseofs[targpose];
|
||||
}
|
||||
o->numposes = p;
|
||||
o->rate = framegroups[a].fps;
|
||||
o->loop = framegroups[a].loop;
|
||||
Q_strncpyz(o->name, framegroups[a].name, sizeof(o->name));
|
||||
}
|
||||
galias->numanimations = numanims;
|
||||
free(framegroups);
|
||||
}
|
||||
}
|
||||
|
||||
qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
|
@ -3440,6 +3477,8 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
|
|||
mod->type = mod_alias;
|
||||
Mod_ClampModelSize(mod);
|
||||
|
||||
Mesh_HandleFramegroupsFile(mod, galias);
|
||||
|
||||
mod->meshinfo = galias;
|
||||
|
||||
mod->funcs.NativeTrace = Mod_Trace;
|
||||
|
|
|
@ -350,7 +350,11 @@ int Q_strncasecmp (const char *s1, const char *s2, int n)
|
|||
if (c2 >= 'a' && c2 <= 'z')
|
||||
c2 -= ('a' - 'A');
|
||||
if (c1 != c2)
|
||||
return -1; // strings not equal
|
||||
{ // strings not equal
|
||||
if (c1 > c2)
|
||||
return 1; // strings not equal
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!c1)
|
||||
return 0; // strings are equal
|
||||
|
@ -1174,7 +1178,7 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
|
|||
MSG_WriteByte (buf, cmd->buttons);
|
||||
if (bits & CM_IMPULSE)
|
||||
MSG_WriteByte (buf, cmd->impulse);
|
||||
MSG_WriteByte (buf, cmd->msec);
|
||||
MSG_WriteByte (buf, cmd->msec&0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2993,7 +2997,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
|||
else if (*str == '^' && !(flags & PFS_NOMARKUP))
|
||||
{
|
||||
if (str[1] >= '0' && str[1] <= '9')
|
||||
{
|
||||
{ //q3 colour codes
|
||||
if (ext & CON_RICHFORECOLOUR)
|
||||
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR));
|
||||
ext = q3codemasks[str[1]-'0'] | (ext&~CON_Q3MASK); //change colour only.
|
||||
|
@ -3344,7 +3348,7 @@ messedup:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (uc == '\n' || uc == '\r' || uc == '\t' || uc == ' ')
|
||||
if (uc == '\n' || uc == '\r' || uc == '\t' || uc == '\v' || uc == ' ')
|
||||
*out++ = uc | ext;
|
||||
else if (uc >= 32 && uc < 127)
|
||||
*out++ = uc | ext;
|
||||
|
@ -4693,10 +4697,11 @@ void COM_ErrorMe_f(void)
|
|||
|
||||
|
||||
#ifdef LOADERTHREAD
|
||||
#define WORKERTHREADS (1+1+4)
|
||||
/*multithreading worker thread stuff*/
|
||||
static void *com_workercondition[2];
|
||||
static qboolean com_workerdone[2];
|
||||
static void *com_workerthread;
|
||||
static void *com_workercondition[WORKERTHREADS];
|
||||
static qboolean com_workerdone[WORKERTHREADS];
|
||||
static void *com_workerthread[WORKERTHREADS];
|
||||
static unsigned int mainthreadid;
|
||||
qboolean com_fatalerror;
|
||||
static struct com_work_s
|
||||
|
@ -4707,7 +4712,7 @@ static struct com_work_s
|
|||
void *data;
|
||||
size_t a;
|
||||
size_t b;
|
||||
} *com_work_head[2], *com_work_tail[2];
|
||||
} *com_work_head[WORKERTHREADS], *com_work_tail[WORKERTHREADS];
|
||||
static void Sys_ErrorThread(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
Sys_Error(data);
|
||||
|
@ -4719,6 +4724,9 @@ void COM_WorkerAbort(char *message)
|
|||
if (Sys_IsMainThread())
|
||||
return;
|
||||
|
||||
if (!com_workercondition[0])
|
||||
return; //Sys_IsMainThread was probably called too early...
|
||||
|
||||
work.func = Sys_ErrorThread;
|
||||
work.ctx = NULL;
|
||||
work.data = message;
|
||||
|
@ -4743,22 +4751,34 @@ void COM_WorkerAbort(char *message)
|
|||
//return if there's *any* loading that needs to be done anywhere.
|
||||
qboolean COM_HasWork(void)
|
||||
{
|
||||
return com_work_head[0] || com_work_head[1];
|
||||
unsigned int i;
|
||||
for (i = 0; i < WORKERTHREADS-1; i++)
|
||||
{
|
||||
if (com_work_head[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//thread==0 is main thread, thread==1 is a worker thread
|
||||
void COM_AddWork(int thread, void(*func)(void *ctx, void *data, size_t a, size_t b), void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
struct com_work_s *work;
|
||||
|
||||
//no worker there, just do it immediately on this thread instead of pushing it to the worker.
|
||||
if (thread && (!com_workerthread[thread] || com_fatalerror))
|
||||
{
|
||||
func(ctx, data, a, b);
|
||||
return;
|
||||
}
|
||||
|
||||
//build the work
|
||||
struct com_work_s *work = Z_Malloc(sizeof(*work));
|
||||
work = Z_Malloc(sizeof(*work));
|
||||
work->func = func;
|
||||
work->ctx = ctx;
|
||||
work->data = data;
|
||||
work->a = a;
|
||||
work->b = b;
|
||||
|
||||
if (!com_workerthread || com_fatalerror)
|
||||
thread = 0;
|
||||
|
||||
//queue it (fifo)
|
||||
Sys_LockConditional(com_workercondition[thread]);
|
||||
if (com_work_tail[thread])
|
||||
|
@ -4774,9 +4794,9 @@ void COM_AddWork(int thread, void(*func)(void *ctx, void *data, size_t a, size_t
|
|||
Sys_ConditionSignal(com_workercondition[thread]);
|
||||
Sys_UnlockConditional(com_workercondition[thread]);
|
||||
|
||||
if (!com_workerthread)
|
||||
while(COM_DoWork(0, false))
|
||||
;
|
||||
// if (!com_workerthread[thread])
|
||||
// while(COM_DoWork(thread, false))
|
||||
// ;
|
||||
}
|
||||
//leavelocked = false == poll mode.
|
||||
//leavelocked = true == safe sleeping
|
||||
|
@ -4816,9 +4836,20 @@ qboolean COM_DoWork(int thread, qboolean leavelocked)
|
|||
//nothing going on, if leavelocked then noone can add anything until we sleep.
|
||||
return false;
|
||||
}
|
||||
static void COM_WorkerSync_StopWorker(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
com_workerdone[a] = true;
|
||||
}
|
||||
static void COM_WorkerSync_SignalMain(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
Sys_LockConditional(com_workercondition[a]);
|
||||
com_workerdone[a] = true;
|
||||
Sys_ConditionSignal(com_workercondition[a]);
|
||||
Sys_UnlockConditional(com_workercondition[a]);
|
||||
}
|
||||
static int COM_WorkerThread(void *arg)
|
||||
{
|
||||
int thread = *(int*)arg;
|
||||
int thread = (void**)arg - com_workerthread;
|
||||
Sys_LockConditional(com_workercondition[thread]);
|
||||
do
|
||||
{
|
||||
|
@ -4828,15 +4859,14 @@ static int COM_WorkerThread(void *arg)
|
|||
break;
|
||||
} while (Sys_ConditionWait(com_workercondition[thread]));
|
||||
Sys_UnlockConditional(com_workercondition[thread]);
|
||||
|
||||
//no more work please...
|
||||
*(void**)arg = NULL;
|
||||
//and wake up main thread
|
||||
COM_WorkerSync_SignalMain(NULL, NULL, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
static void COM_WorkerSync_Stop(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
Sys_LockConditional(com_workercondition[a]);
|
||||
com_workerdone[a] = true;
|
||||
Sys_ConditionSignal(com_workercondition[a]);
|
||||
Sys_UnlockConditional(com_workercondition[a]);
|
||||
}
|
||||
|
||||
#ifndef COM_AssertMainThread
|
||||
void COM_AssertMainThread(const char *msg)
|
||||
{
|
||||
|
@ -4848,22 +4878,45 @@ void COM_AssertMainThread(const char *msg)
|
|||
#endif
|
||||
void COM_DestroyWorkerThread(void)
|
||||
{
|
||||
int i;
|
||||
com_fatalerror = false;
|
||||
if (com_workerthread)
|
||||
for (i = 0; i < WORKERTHREADS; i++)
|
||||
{
|
||||
//send it the terminate message
|
||||
COM_AddWork(1, COM_WorkerSync_Stop, NULL, NULL, 1, 0);
|
||||
Sys_WaitOnThread(com_workerthread);
|
||||
com_workerthread = NULL;
|
||||
if (com_workerthread[i])
|
||||
{
|
||||
void *thread = com_workerthread[i];
|
||||
com_workerdone[0] = false;
|
||||
//send it the terminate message
|
||||
COM_AddWork(i, COM_WorkerSync_StopWorker, NULL, NULL, i, 0);
|
||||
|
||||
//wait for the response while servicing anything that it might be waiting for.
|
||||
Sys_LockConditional(com_workercondition[0]);
|
||||
do
|
||||
{
|
||||
if (com_fatalerror)
|
||||
break;
|
||||
while(COM_DoWork(0, true))
|
||||
;
|
||||
if (com_workerdone[0])
|
||||
break;
|
||||
} while (Sys_ConditionWait(com_workercondition[0]));
|
||||
Sys_UnlockConditional(com_workercondition[0]);
|
||||
|
||||
//and now that we know its going down and will not wait any more, we can block for its final moments
|
||||
Sys_WaitOnThread(thread);
|
||||
|
||||
//finish any work that got posted to it that it neglected to finish.
|
||||
while(COM_DoWork(i, true))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (com_workercondition[0])
|
||||
Sys_DestroyConditional(com_workercondition[0]);
|
||||
com_workercondition[0] = NULL;
|
||||
|
||||
if (com_workercondition[1])
|
||||
Sys_DestroyConditional(com_workercondition[1]);
|
||||
com_workercondition[1] = NULL;
|
||||
for (i = 0; i < WORKERTHREADS; i++)
|
||||
{
|
||||
if (com_workercondition[i])
|
||||
Sys_DestroyConditional(com_workercondition[i]);
|
||||
com_workercondition[i] = NULL;
|
||||
}
|
||||
|
||||
if (com_resourcemutex)
|
||||
Sys_DestroyMutex(com_resourcemutex);
|
||||
|
@ -4874,33 +4927,38 @@ void COM_DestroyWorkerThread(void)
|
|||
void COM_WorkerFullSync(void)
|
||||
{
|
||||
qboolean repeat;
|
||||
if (!com_workerthread)
|
||||
return;
|
||||
int i;
|
||||
|
||||
//main thread asks worker thread to set main thread's 'done' flag.
|
||||
//the worker might be posting work to the main thread and back (shaders with texures) so make sure that the only work we do before the reply is the reply itself.
|
||||
do
|
||||
for (i = 1; i < WORKERTHREADS; i++)
|
||||
{
|
||||
int cmds = 0;
|
||||
com_workerdone[0] = false;
|
||||
repeat = COM_HasWork();
|
||||
COM_AddWork(1, COM_WorkerSync_Stop, NULL, NULL, 0, 0);
|
||||
Sys_LockConditional(com_workercondition[0]);
|
||||
if (!com_workerthread[i])
|
||||
continue;
|
||||
|
||||
//main thread asks worker thread to set main thread's 'done' flag.
|
||||
//the worker might be posting work to the main thread and back (shaders with texures) so make sure that the only work we do before the reply is the reply itself.
|
||||
do
|
||||
{
|
||||
int cmds = 0;
|
||||
com_workerdone[0] = false;
|
||||
repeat = COM_HasWork();
|
||||
COM_AddWork(i, COM_WorkerSync_SignalMain, NULL, NULL, 0, 0);
|
||||
Sys_LockConditional(com_workercondition[0]);
|
||||
do
|
||||
{
|
||||
if (com_fatalerror)
|
||||
break;
|
||||
while(COM_DoWork(0, true))
|
||||
cmds++;
|
||||
if (com_workerdone[0])
|
||||
break;
|
||||
} while (Sys_ConditionWait(com_workercondition[0]));
|
||||
Sys_UnlockConditional(com_workercondition[0]);
|
||||
if (com_fatalerror)
|
||||
break;
|
||||
while(COM_DoWork(0, true))
|
||||
cmds++;
|
||||
if (com_workerdone[0])
|
||||
break;
|
||||
} while (Sys_ConditionWait(com_workercondition[0]));
|
||||
Sys_UnlockConditional(com_workercondition[0]);
|
||||
if (com_fatalerror)
|
||||
break;
|
||||
if (cmds > 1)
|
||||
repeat = true;
|
||||
} while (COM_DoWork(0, false) || repeat); //outer loop ensures there isn't anything pingponging between
|
||||
if (cmds > 1)
|
||||
repeat = true;
|
||||
} while (COM_DoWork(0, false) || repeat); //outer loop ensures there isn't anything pingponging between
|
||||
}
|
||||
}
|
||||
|
||||
//main thread wants a specific object to be prioritised.
|
||||
|
@ -4912,7 +4970,6 @@ void COM_WorkerPartialSync(void *priorityctx, int *address, int value)
|
|||
{
|
||||
struct com_work_s **link, *work, *prev;
|
||||
double time1 = Sys_DoubleTime();
|
||||
int thread = 1;
|
||||
|
||||
// Con_Printf("waiting for %p %s\n", priorityctx, priorityctx);
|
||||
|
||||
|
@ -4922,32 +4979,36 @@ void COM_WorkerPartialSync(void *priorityctx, int *address, int value)
|
|||
//main thread is meant to do all loadstate value changes anyway, ensuring that we're woken up properly in this case.
|
||||
if (priorityctx)
|
||||
{
|
||||
unsigned int thread;
|
||||
qboolean found = false;
|
||||
Sys_LockConditional(com_workercondition[thread]);
|
||||
for (link = &com_work_head[thread], work = NULL; *link; link = &(*link)->next)
|
||||
for (thread = 1; thread < WORKERTHREADS && !found; thread++)
|
||||
{
|
||||
prev = work;
|
||||
work = *link;
|
||||
if (work->ctx == priorityctx)
|
||||
{ //unlink it
|
||||
Sys_LockConditional(com_workercondition[thread]);
|
||||
for (link = &com_work_head[thread], work = NULL; *link; link = &(*link)->next)
|
||||
{
|
||||
prev = work;
|
||||
work = *link;
|
||||
if (work->ctx == priorityctx)
|
||||
{ //unlink it
|
||||
|
||||
*link = work->next;
|
||||
if (!work->next)
|
||||
com_work_tail[thread] = prev;
|
||||
//link it in at the head, so its the next thing seen.
|
||||
work->next = com_work_head[thread];
|
||||
com_work_head[thread] = work;
|
||||
if (!work->next)
|
||||
com_work_tail[thread] = work;
|
||||
found = true;
|
||||
*link = work->next;
|
||||
if (!work->next)
|
||||
com_work_tail[thread] = prev;
|
||||
//link it in at the head, so its the next thing seen.
|
||||
work->next = com_work_head[thread];
|
||||
com_work_head[thread] = work;
|
||||
if (!work->next)
|
||||
com_work_tail[thread] = work;
|
||||
found = true;
|
||||
|
||||
break; //found it, nothing else to do.
|
||||
break; //found it, nothing else to do.
|
||||
}
|
||||
}
|
||||
//we've not actually added any work, so no need to signal
|
||||
Sys_UnlockConditional(com_workercondition[thread]);
|
||||
}
|
||||
if (!found)
|
||||
Con_DPrintf("Might be in for a long wait for %s\n", priorityctx);
|
||||
//we've not actually added any work, so no need to signal
|
||||
Sys_UnlockConditional(com_workercondition[thread]);
|
||||
}
|
||||
|
||||
Sys_LockConditional(com_workercondition[0]);
|
||||
|
@ -4974,7 +5035,7 @@ static void COM_WorkerPing(void *ctx, void *data, size_t a, size_t b)
|
|||
{
|
||||
double *timestamp = data;
|
||||
if (!b)
|
||||
COM_AddWork(0, COM_WorkerPing, ctx, data , 0, 1);
|
||||
COM_AddWork(0, COM_WorkerPing, ctx, data, 0, 1);
|
||||
else
|
||||
{
|
||||
Con_Printf("Ping: %g\n", Sys_DoubleTime() - *timestamp);
|
||||
|
@ -4996,14 +5057,21 @@ static void COM_WorkerTest_f(void)
|
|||
cvar_t worker_flush = CVARD("worker_flush", "1", "Is set, process the entire load queue, loading stuff faster but at the risk of stalling.");
|
||||
static void COM_InitWorkerThread(void)
|
||||
{
|
||||
static int tid = 1;
|
||||
int i;
|
||||
|
||||
//in theory, we could run multiple workers, signalling a different one in turn for each bit of work.
|
||||
com_resourcemutex = Sys_CreateMutex();
|
||||
com_workercondition[0] = Sys_CreateConditional();
|
||||
com_workercondition[1] = Sys_CreateConditional();
|
||||
for (i = 0; i < WORKERTHREADS; i++)
|
||||
{
|
||||
com_workercondition[i] = Sys_CreateConditional();
|
||||
}
|
||||
if (!COM_CheckParm("-noworker"))
|
||||
com_workerthread = Sys_CreateThread("loadworker", COM_WorkerThread, &tid, 0, 256*1024);
|
||||
{
|
||||
for (i = 1; i < WORKERTHREADS; i++)
|
||||
{
|
||||
com_workerthread[i] = Sys_CreateThread(va("loadworker_%i", i), COM_WorkerThread, &com_workerthread[i], 0, 256*1024);
|
||||
}
|
||||
}
|
||||
|
||||
Cmd_AddCommand ("worker_test", COM_WorkerTest_f);
|
||||
Cvar_Register(&worker_flush, NULL);
|
||||
|
@ -5753,8 +5821,10 @@ void Info_Print (char *s, char *lineprefix)
|
|||
|
||||
void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags)
|
||||
{
|
||||
const char *quotedvalue;
|
||||
char buffer[1024];
|
||||
char *command;
|
||||
char *value;
|
||||
char *value, t;
|
||||
cvar_t *var;
|
||||
|
||||
while(*info == '\\')
|
||||
|
@ -5779,7 +5849,11 @@ void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags
|
|||
VFS_WRITE(f, " ", 1);
|
||||
VFS_WRITE(f, command, value-command);
|
||||
VFS_WRITE(f, " ", 1);
|
||||
VFS_WRITE(f, value+1, info-(value+1));
|
||||
t = *info;
|
||||
*info = 0;
|
||||
quotedvalue = COM_QuotedString(value+1, buffer, sizeof(buffer), false);
|
||||
VFS_WRITE(f, quotedvalue, strlen(quotedvalue));
|
||||
*info = t;
|
||||
VFS_WRITE(f, "\n", 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,10 +477,18 @@ void COM_FlushFSCache(qboolean purge, qboolean domutex); //a file was written us
|
|||
void COM_RefreshFSCache_f(void);
|
||||
qboolean FS_Restarted(unsigned int *since);
|
||||
|
||||
enum manifestdeptype_e
|
||||
{
|
||||
mdt_invalid,
|
||||
mdt_singlepackage, //regular package, versioned.
|
||||
mdt_installation //allowed to install to the root.
|
||||
};
|
||||
typedef struct
|
||||
{
|
||||
qboolean blockupdate; //set to block the updateurl from being used this session. this avoids recursive updates when manifests contain the same update url.
|
||||
qboolean doinstall; //manifest was embedded in the engine. don't assume its already installed, but ask to install it (also, enable some extra permissions for writing dlls)
|
||||
|
||||
int parsever;
|
||||
int minver; //if the engine svn revision is lower than this, the manifest will not be used as an 'upgrade'.
|
||||
int maxver; //if not 0, the manifest will not be used
|
||||
qboolean disablehomedir;
|
||||
|
@ -490,13 +498,15 @@ typedef struct
|
|||
char *formalname; //the commercial name of the game. you'll get FULLENGINENAME otherwise.
|
||||
char *protocolname; //the name used for purposes of dpmaster
|
||||
char *defaultexec; //execed after cvars are reset, to give game-specific defaults.
|
||||
char *eula; //when running as an installer, the user will be presented with this as a prompt
|
||||
struct
|
||||
{
|
||||
qboolean base;
|
||||
char *path;
|
||||
} gamepath[8];
|
||||
struct
|
||||
struct manpack_s
|
||||
{
|
||||
int type;
|
||||
char *path; //the 'pure' name
|
||||
qboolean crcknown; //if the crc was specified
|
||||
unsigned int crc; //the public crc
|
||||
|
@ -509,7 +519,8 @@ void FS_Manifest_Free(ftemanifest_t *man);
|
|||
ftemanifest_t *FS_Manifest_Parse(const char *fname, const char *data);
|
||||
|
||||
void COM_InitFilesystem (void); //does not set up any gamedirs.
|
||||
qboolean FS_ChangeGame(ftemanifest_t *newgame, qboolean allowreloadconfigs);
|
||||
qboolean FS_DownloadingPackage(void);
|
||||
qboolean FS_ChangeGame(ftemanifest_t *newgame, qboolean allowreloadconfigs, qboolean allowbasedirchange);
|
||||
void FS_Shutdown(void);
|
||||
void COM_Gamedir (const char *dir);
|
||||
char *FS_GetGamedir(qboolean publicpathonly);
|
||||
|
@ -529,6 +540,7 @@ void COM_FlushTempoaryPacks(void);
|
|||
|
||||
void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm);
|
||||
|
||||
extern qboolean com_installer; //says that the engine is running in an 'installer' mode, and that the correct basedir is not yet known.
|
||||
extern struct cvar_s registered;
|
||||
extern qboolean standard_quake; //fixme: remove
|
||||
|
||||
|
|
|
@ -106,23 +106,40 @@ typedef struct conline_s {
|
|||
float time;
|
||||
} conline_t;
|
||||
|
||||
//majority of these are mututally exclusive. the bits allow multiple.
|
||||
#define CB_NONE 0
|
||||
#define CB_SCROLL 1
|
||||
#define CB_COPY 2
|
||||
#define CB_CLOSE 3
|
||||
#define CB_MOVE 4
|
||||
#define CB_SIZELEFT (1u<<29)
|
||||
#define CB_SIZERIGHT (1u<<30)
|
||||
#define CB_SIZEBOTTOM (1u<<31)
|
||||
#define CONF_HIDDEN 1 /*do not show in the console list (unless active)*/
|
||||
#define CONF_NOTIFY 2 /*text printed to console also appears as notify lines*/
|
||||
#define CONF_NOTIFY_BOTTOM 4 /*align the bottom*/
|
||||
#define CONF_NOTIMES 8
|
||||
#define CONF_KEYFOCUSED 16
|
||||
#define CONF_NOTIFY_RIGHT 8
|
||||
#define CONF_NOTIMES 16
|
||||
#define CONF_KEYFOCUSED 32
|
||||
#define CONF_ISWINDOW 64
|
||||
typedef struct console_s
|
||||
{
|
||||
int id;
|
||||
int nextlineid; //the current line being written to. so we can rewrite links etc.
|
||||
char name[64];
|
||||
char title[64];
|
||||
char name[128];
|
||||
char title[128];
|
||||
float wnd_x;
|
||||
float wnd_y;
|
||||
float wnd_w;
|
||||
float wnd_h;
|
||||
int linecount;
|
||||
unsigned int flags;
|
||||
int notif_x;
|
||||
int notif_y;
|
||||
int notif_w;
|
||||
float notif_x;
|
||||
float notif_y;
|
||||
float notif_w;
|
||||
int notif_l;
|
||||
float notif_fade; // will be transparent for this long when fading
|
||||
int maxlines;
|
||||
float notif_t;
|
||||
conline_t *oldest;
|
||||
conline_t *current; // line where next message will be printed
|
||||
|
@ -135,7 +152,7 @@ typedef struct console_s
|
|||
unsigned parseflags;
|
||||
conchar_t defaultcharbits;
|
||||
int commandcompletion; //allows tab completion of quake console commands
|
||||
void (*linebuffered) (struct console_s *con, char *line); //if present, called on enter, causes the standard console input to appear.
|
||||
int (*linebuffered) (struct console_s *con, char *line); //if present, called on enter, causes the standard console input to appear. return 2 to not save the line in history.
|
||||
void (*redirect) (struct console_s *con, int key); //if present, called every character.
|
||||
void *userdata;
|
||||
|
||||
|
@ -143,14 +160,16 @@ typedef struct console_s
|
|||
conline_t *footerline; //temp text at the bottom of the console
|
||||
conline_t *selstartline, *selendline;
|
||||
unsigned int selstartoffset, selendoffset;
|
||||
int mousedown[3]; //x,y,buttons
|
||||
int mousedown[2]; //x,y position that the current buttons were clicked.
|
||||
unsigned int buttonsdown;
|
||||
int mousecursor[2]; //x,y
|
||||
|
||||
struct console_s *next;
|
||||
} console_t;
|
||||
|
||||
extern console_t con_main;
|
||||
extern console_t *con_current; // point to either con_main or con_chat
|
||||
extern console_t *con_curwindow; // refers to a windowed console
|
||||
extern console_t *con_current; // point to either con_main or con_chat
|
||||
extern console_t *con_mouseover;
|
||||
extern console_t *con_chat;
|
||||
|
||||
|
@ -178,23 +197,23 @@ void Con_Shutdown (void);
|
|||
void Con_History_Save(void);
|
||||
void Con_History_Load(void);
|
||||
struct font_s;
|
||||
void Con_DrawOneConsole(console_t *con, struct font_s *font, float fx, float fy, float fsx, float fsy);
|
||||
void Con_DrawOneConsole(console_t *con, qboolean focused, struct font_s *font, float fx, float fy, float fsx, float fsy);
|
||||
void Con_DrawConsole (int lines, qboolean noback);
|
||||
char *Con_CopyConsole(qboolean nomarkup, qboolean onlyiflink);
|
||||
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink);
|
||||
void Con_Print (char *txt);
|
||||
void Con_PrintFlags(char *text, unsigned int setflags, unsigned int clearflags);
|
||||
void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
|
||||
void VARGS Con_TPrintf (translation_t text, ...);
|
||||
void VARGS Con_DPrintf (const char *fmt, ...) LIKEPRINTF(1);
|
||||
void VARGS Con_SafePrintf (char *fmt, ...) LIKEPRINTF(1);
|
||||
void Con_Footerf(qboolean append, char *fmt, ...) LIKEPRINTF(2);
|
||||
void Con_Footerf(console_t *con, qboolean append, char *fmt, ...) LIKEPRINTF(3);
|
||||
void Con_Clear_f (void);
|
||||
void Con_DrawNotify (void);
|
||||
void Con_ClearNotify (void);
|
||||
void Con_ToggleConsole_f (void);//note: allows csqc to intercept the toggleconsole
|
||||
void Con_ToggleConsole_Force(void);
|
||||
|
||||
void Con_ExecuteLine(console_t *con, char *line); //takes normal console commands
|
||||
int Con_ExecuteLine(console_t *con, char *line); //takes normal console commands
|
||||
|
||||
|
||||
void Con_CycleConsole (void);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,15 +3,16 @@
|
|||
#include "winquake.h"
|
||||
|
||||
//outlen is the size of out in _BYTES_.
|
||||
wchar_t *widen(wchar_t *out, size_t outlen, const char *utf8)
|
||||
wchar_t *widen(wchar_t *out, size_t outbytes, const char *utf8)
|
||||
{
|
||||
size_t outlen;
|
||||
wchar_t *ret = out;
|
||||
//utf-8 to utf-16, not ucs-2.
|
||||
unsigned int codepoint;
|
||||
int error;
|
||||
outlen = outbytes/sizeof(wchar_t);
|
||||
if (!outlen)
|
||||
return L"";
|
||||
outlen /= sizeof(wchar_t);
|
||||
outlen--;
|
||||
while (*utf8)
|
||||
{
|
||||
|
@ -304,7 +305,7 @@ static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *qu
|
|||
file->offset = 0;
|
||||
file->length = fsize;
|
||||
|
||||
return (vfsfile_t*)file;
|
||||
return &file->funcs;
|
||||
}
|
||||
|
||||
vfsfile_t *QDECL VFSW32_Open(const char *osname, const char *mode)
|
||||
|
|
|
@ -232,6 +232,228 @@ vfsfile_t *FS_DecompressGZip(vfsfile_t *infile, vfsfile_t *outfile)
|
|||
return temp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//returns an unseekable write-only file that will decompress any data that is written to it.
|
||||
//decompressed data will be written to the output
|
||||
typedef struct
|
||||
{
|
||||
vfsfile_t vf;
|
||||
vfsfile_t *outfile;
|
||||
qboolean autoclosefile;
|
||||
|
||||
//gzip header handling
|
||||
qboolean headerparsed;
|
||||
qbyte in[65536];
|
||||
int inlen;
|
||||
|
||||
qbyte out[65536];
|
||||
z_stream strm;
|
||||
} vf_gz_dec_t;
|
||||
|
||||
static qboolean QDECL FS_GZ_Dec_Close(vfsfile_t *f)
|
||||
{
|
||||
vf_gz_dec_t *n = (vf_gz_dec_t*)f;
|
||||
if (n->autoclosefile)
|
||||
VFS_CLOSE(n->outfile);
|
||||
qinflateEnd(&n->strm);
|
||||
Z_Free(n);
|
||||
return true;
|
||||
}
|
||||
static int QDECL FS_GZ_Dec_Write(vfsfile_t *f, const void *buffer, int len)
|
||||
{
|
||||
int ret;
|
||||
vf_gz_dec_t *n = (vf_gz_dec_t*)f;
|
||||
|
||||
if (n->headerparsed != 1)
|
||||
{
|
||||
qofs_t ofs = 0;
|
||||
gzheader_t *header;
|
||||
int chunk;
|
||||
if (len > sizeof(n->in) - n->inlen)
|
||||
chunk = sizeof(n->in) - n->inlen;
|
||||
else
|
||||
chunk = len;
|
||||
memmove(n->in, buffer, chunk);
|
||||
n->inlen += chunk;
|
||||
|
||||
if (n->headerparsed == 2)
|
||||
{
|
||||
if (n->inlen >= 8)
|
||||
{
|
||||
unsigned int crc = (n->in[0]<<0) | (n->in[1]<<8) | (n->in[2]<<16) | (n->in[3]<<24);
|
||||
unsigned int isize = (n->in[4]<<0) | (n->in[5]<<8) | (n->in[6]<<16) | (n->in[7]<<24);
|
||||
if (n->strm.total_out != isize)
|
||||
return -1; //the file we just received decoded to a different length (yay, concat...).
|
||||
//FIXME: validate the decoded crc
|
||||
n->headerparsed = false;
|
||||
n->strm.total_in = 0;
|
||||
n->strm.total_out = 0;
|
||||
len = n->inlen - 8;
|
||||
n->inlen = 0;
|
||||
if (FS_GZ_Dec_Write(f, n->in + 8, len) != len)
|
||||
return -1; //FIXME: make non-fatal somehow
|
||||
return chunk;
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
header = (gzheader_t*)n->in;
|
||||
ofs += sizeofgzheader_t; if (ofs > n->inlen) goto noheader;
|
||||
|
||||
if (header->ident1 != 0x1f || header->ident2 != 0x8b || header->cm != 8 || header->flags & GZ_RESERVED)
|
||||
return -1; //ERROR
|
||||
|
||||
if (header->flags & GZ_FEXTRA)
|
||||
{
|
||||
unsigned short ex;
|
||||
if (ofs+2 > n->inlen) goto noheader;
|
||||
ex = (n->in[ofs]<<0) | (n->in[ofs+1]<<8); //read little endian
|
||||
ofs += 2+ex; if (ofs > n->inlen) goto noheader;
|
||||
}
|
||||
|
||||
if (header->flags & GZ_FNAME)
|
||||
{
|
||||
char ch;
|
||||
// Con_Printf("gzipped file name: ");
|
||||
do {
|
||||
if (ofs+1 > n->inlen) goto noheader;
|
||||
ch = n->in[ofs++];
|
||||
// Con_Printf("%c", ch);
|
||||
} while(ch);
|
||||
// Con_Printf("\n");
|
||||
}
|
||||
|
||||
if (header->flags & GZ_FCOMMENT)
|
||||
{
|
||||
char ch;
|
||||
// Con_Printf("gzipped file comment: ");
|
||||
do {
|
||||
if (ofs+1 > n->inlen) goto noheader;
|
||||
ch = n->in[ofs++];
|
||||
// Con_Printf("%c", ch);
|
||||
} while(ch);
|
||||
// Con_Printf("\n");
|
||||
}
|
||||
|
||||
if (header->flags & GZ_FHCRC)
|
||||
{
|
||||
ofs += 2; if (ofs > n->inlen) goto noheader;
|
||||
}
|
||||
|
||||
//if we got here then the header is now complete.
|
||||
//tail-recurse it.
|
||||
n->headerparsed = true;
|
||||
chunk = n->inlen - ofs;
|
||||
if (FS_GZ_Dec_Write(f, n->in + ofs, chunk) != chunk)
|
||||
return -1; //FIXME: make non-fatal somehow
|
||||
return len;
|
||||
|
||||
noheader:
|
||||
if (n->inlen == sizeof(n->in))
|
||||
return -1; //we filled our buffer. if we didn't get past the header yet then someone fucked up.
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
n->strm.next_in = buffer;
|
||||
n->strm.avail_in = len;
|
||||
|
||||
while(n->strm.avail_in)
|
||||
{
|
||||
ret = qinflate(&n->strm, Z_SYNC_FLUSH);
|
||||
|
||||
if (!n->strm.avail_out)
|
||||
{
|
||||
if (VFS_WRITE(n->outfile, n->out, n->strm.next_out-n->out) != n->strm.next_out-n->out)
|
||||
return -1;
|
||||
|
||||
n->strm.next_out = n->out;
|
||||
n->strm.avail_out = sizeof(n->out);
|
||||
}
|
||||
|
||||
if (ret == Z_OK)
|
||||
continue;
|
||||
|
||||
//flush it
|
||||
if (VFS_WRITE(n->outfile, n->out, n->strm.next_out-n->out) != n->strm.next_out-n->out)
|
||||
return -1;
|
||||
n->strm.next_out = n->out;
|
||||
n->strm.avail_out = sizeof(n->out);
|
||||
|
||||
if (ret == Z_STREAM_END) //allow concat
|
||||
{
|
||||
int l = n->strm.avail_in;
|
||||
n->headerparsed = 2;
|
||||
n->inlen = 0;
|
||||
if (l != FS_GZ_Dec_Write(f, n->strm.next_in, n->strm.avail_in))
|
||||
return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
Con_Printf("Z_NEED_DICT\n");
|
||||
break;
|
||||
|
||||
case Z_ERRNO:
|
||||
Con_Printf("Z_ERRNO\n");
|
||||
break;
|
||||
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
case Z_BUF_ERROR:
|
||||
case Z_VERSION_ERROR:
|
||||
Con_Printf("File is corrupt\n");
|
||||
break;
|
||||
default:
|
||||
Con_Printf("Bug!\n");
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefile)
|
||||
{
|
||||
vf_gz_dec_t *n = Z_Malloc(sizeof(*n));
|
||||
|
||||
n->outfile = outfile;
|
||||
n->autoclosefile = autoclosefile;
|
||||
|
||||
n->strm.next_in = NULL;
|
||||
n->strm.avail_in = 0;
|
||||
n->strm.total_in = 0;
|
||||
n->strm.next_out = n->out;
|
||||
n->strm.avail_out = sizeof(n->out);
|
||||
n->strm.total_out = 0;
|
||||
|
||||
n->vf.Flush = NULL;
|
||||
n->vf.GetLen = NULL;
|
||||
n->vf.ReadBytes = NULL;
|
||||
n->vf.Seek = NULL;
|
||||
n->vf.Tell = NULL;
|
||||
n->vf.Close = FS_GZ_Dec_Close;
|
||||
n->vf.WriteBytes = FS_GZ_Dec_Write;
|
||||
n->vf.seekingisabadplan = true;
|
||||
|
||||
qinflateInit2(&n->strm, -MAX_WBITS);
|
||||
|
||||
return &n->vf;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -141,8 +141,8 @@ void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs)
|
|||
|
||||
void ClearBounds (vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
mins[0] = mins[1] = mins[2] = 999999999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -999999999;
|
||||
mins[0] = mins[1] = mins[2] = FLT_MAX;
|
||||
maxs[0] = maxs[1] = maxs[2] = -FLT_MAX;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1215,7 +1215,7 @@ texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char *
|
|||
image_t *base;
|
||||
|
||||
Q_snprintfz (name, sizeof(name), "textures/%s.wal", texname);
|
||||
wal = (void *)FS_LoadMallocFile (texname, NULL);
|
||||
wal = (void *)FS_LoadMallocFile (name, NULL);
|
||||
if (!wal)
|
||||
{
|
||||
wal = &replacementwal;
|
||||
|
@ -1263,11 +1263,31 @@ texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char *
|
|||
tex->width = base->width;
|
||||
tex->height = base->height;
|
||||
}
|
||||
else
|
||||
Con_Printf("Unable to load textures/%s.wal\n", wal->name);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int size =
|
||||
(wal->width>>0)*(wal->height>>0) +
|
||||
(wal->width>>1)*(wal->height>>1) +
|
||||
(wal->width>>2)*(wal->height>>2) +
|
||||
(wal->width>>3)*(wal->height>>3);
|
||||
|
||||
tex->mips[0] = BZ_Malloc(size);
|
||||
tex->palette = host_basepal;
|
||||
tex->mips[1] = tex->mips[0] + (wal->width>>0)*(wal->height>>0);
|
||||
tex->mips[2] = tex->mips[1] + (wal->width>>1)*(wal->height>>1);
|
||||
tex->mips[3] = tex->mips[2] + (wal->width>>2)*(wal->height>>2);
|
||||
memcpy(tex->mips[0], (qbyte *)wal + wal->offsets[0], (wal->width>>0)*(wal->height>>0));
|
||||
memcpy(tex->mips[1], (qbyte *)wal + wal->offsets[1], (wal->width>>1)*(wal->height>>1));
|
||||
memcpy(tex->mips[2], (qbyte *)wal + wal->offsets[2], (wal->width>>2)*(wal->height>>2));
|
||||
memcpy(tex->mips[3], (qbyte *)wal + wal->offsets[3], (wal->width>>3)*(wal->height>>3));
|
||||
|
||||
BZ_Free(wal);
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
@ -3933,7 +3953,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
|||
|
||||
if (header.lumps[i].filelen && header.lumps[i].fileofs + header.lumps[i].filelen > filelen)
|
||||
{
|
||||
Con_Printf (CON_ERROR "WARNING: q3bsp %s truncated (lump %i, %i+%i > %i)\n", mod->name, i, header.lumps[i].fileofs, header.lumps[i].filelen, filelen);
|
||||
Con_Printf (CON_ERROR "WARNING: q3bsp %s truncated (lump %i, %i+%i > %u)\n", mod->name, i, header.lumps[i].fileofs, header.lumps[i].filelen, (unsigned int)filelen);
|
||||
header.lumps[i].filelen = filelen - header.lumps[i].fileofs;
|
||||
if (header.lumps[i].filelen < 0)
|
||||
header.lumps[i].filelen = 0;
|
||||
|
@ -5128,6 +5148,7 @@ static void Mod_Trace_Trisoup_(vecV_t *posedata, index_t *indexes, size_t numind
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static void CM_ClipBoxToMesh (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace_t *trace, mesh_t *mesh)
|
||||
{
|
||||
trace_truefraction = trace->truefraction;
|
||||
|
@ -5136,6 +5157,7 @@ static void CM_ClipBoxToMesh (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, tr
|
|||
trace->truefraction = trace_truefraction;
|
||||
trace->fraction = trace_nearfraction;
|
||||
}
|
||||
*/
|
||||
|
||||
static void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
|
||||
trace_t *trace, q2cbrush_t *brush)
|
||||
|
|
|
@ -184,7 +184,7 @@ qboolean NET_RTP_Transmit(unsigned int sequence, unsigned int timestamp, const c
|
|||
built = true;
|
||||
MSG_WriteByte(&buf, (2u<<6) | (0u<<5) | (0u<<4) | (0<<0)); //v2_p1_x1_cc4
|
||||
MSG_WriteByte(&buf, (0u<<7) | ((i+96)<<0)); //m1_pt7
|
||||
MSG_WriteShort(&buf, BigShort(sequence)); //seq
|
||||
MSG_WriteShort(&buf, BigShort(sequence)&0xffff); //seq
|
||||
MSG_WriteLong(&buf, BigLong(timestamp)); //timestamp
|
||||
MSG_WriteLong(&buf, BigLong(0)); //ssrc
|
||||
SZ_Write(&buf, cdata, clength);
|
||||
|
|
|
@ -76,9 +76,10 @@ qboolean SSL_Inited(void)
|
|||
|
||||
struct sslbuf
|
||||
{
|
||||
char data[8192];
|
||||
int avail;
|
||||
int newd;
|
||||
size_t datasize;
|
||||
char *data;
|
||||
size_t avail;
|
||||
size_t newd;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -113,13 +114,20 @@ typedef struct {
|
|||
|
||||
static int SSPI_CopyIntoBuffer(struct sslbuf *buf, const void *data, unsigned int bytes)
|
||||
{
|
||||
if (bytes > sizeof(buf->data) - buf->avail)
|
||||
bytes = sizeof(buf->data) - buf->avail;
|
||||
if (bytes > buf->datasize - buf->avail)
|
||||
bytes = buf->datasize - buf->avail;
|
||||
memcpy(buf->data + buf->avail, data, bytes);
|
||||
buf->avail += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
static int SSPI_ExpandBuffer(struct sslbuf *buf, size_t bytes)
|
||||
{
|
||||
if (bytes < buf->datasize)
|
||||
return buf->datasize;
|
||||
Z_ReallocElements(&buf->data, &buf->datasize, bytes, 1);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void SSPI_Error(sslfile_t *f, char *error)
|
||||
{
|
||||
|
@ -153,7 +161,7 @@ static int SSPI_CheckNewInCrypt(sslfile_t *f)
|
|||
int newd;
|
||||
if (!f->stream)
|
||||
return -1;
|
||||
newd = VFS_READ(f->stream, f->incrypt.data+f->incrypt.avail, sizeof(f->incrypt.data) - f->incrypt.avail);
|
||||
newd = VFS_READ(f->stream, f->incrypt.data+f->incrypt.avail, f->incrypt.datasize - f->incrypt.avail);
|
||||
if (newd < 0)
|
||||
return newd;
|
||||
else
|
||||
|
@ -193,7 +201,11 @@ static void SSPI_Decode(sslfile_t *f)
|
|||
if (ss < 0)
|
||||
{
|
||||
if (ss == SEC_E_INCOMPLETE_MESSAGE)
|
||||
{
|
||||
if (f->incrypt.avail == f->incrypt.datasize)
|
||||
SSPI_ExpandBuffer(&f->incrypt, f->incrypt.datasize+1024);
|
||||
return; //no error if its incomplete, we can just get more data later on.
|
||||
}
|
||||
switch(ss)
|
||||
{
|
||||
case SEC_E_INVALID_HANDLE: SSPI_Error(f, "DecryptMessage failed: SEC_E_INVALID_HANDLE\n"); break;
|
||||
|
@ -296,15 +308,17 @@ static void SSPI_Encode(sslfile_t *f)
|
|||
}
|
||||
|
||||
//these are known sites that use self-signed certificates, or are special enough that we don't trust corporate networks to hack in their own certificate authority for a proxy/mitm
|
||||
static const qbyte triptohell_certdata[] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\x8b\xd0\x05\x63\x62\xd1\x6a\xe3\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x34\x32\x32\x34\x32\x34\x37\x5a\x17\x0d\x32\x34\x31\x32\x32\x31\x32\x32\x34\x32\x34\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaf\x10\x33\xfa\x39\xf5\xae\x2c\x91\x0e\x20\xe6\x3c\x5c\x7c\x1e\xeb\x16\x50\x2f\x05\x30\xfe\x67\xee\xa9\x00\x54\xd9\x4a\x86\xe6\xba\x80\xfb\x1a\x80\x08\x7e\x7b\x13\xe5\x1a\x18\xc9\xd4\x70\xbd\x5d\xc4\x38\xef\x64\xf1\x90\x2c\x53\x49\x93\x24\x36\x3e\x11\x59\x69\xa6\xdf\x37\xb2\x54\x82\x28\x3e\xdd\x30\x75\xa0\x18\xd8\xe1\xf5\x52\x73\x12\x5b\x37\x68\x1c\x59\xbd\x8c\x73\x66\x47\xbc\xcb\x9c\xfe\x38\x92\x8f\x74\xe9\xd1\x2f\x96\xd2\x5d\x6d\x11\x59\xb2\xdc\xbd\x8c\x37\x5b\x22\x76\x98\xe7\xbe\x08\xef\x1e\x99\xc4\xa9\x77\x2c\x9c\x0e\x08\x3c\x8e\xab\x97\x0c\x6a\xd7\x03\xab\xfd\x4a\x1e\x95\xb2\xc2\x9c\x3a\x16\x65\xd7\xaf\x45\x5f\x6e\xe7\xce\x51\xba\xa0\x60\x43\x0e\x07\xc5\x0b\x0a\x82\x05\x26\xc4\x92\x0a\x27\x5b\xfc\x57\x6c\xdf\xe2\x54\x8a\xef\x38\xf1\xf8\xc4\xf8\x51\x16\x27\x1f\x78\x89\x7c\x5b\xd7\x53\xcd\x9b\x54\x2a\xe6\x71\xee\xe4\x56\x2e\xa4\x09\x1a\x61\xf7\x0f\x97\x22\x94\xd7\xef\x21\x6c\xe6\x81\xfb\x54\x5f\x09\x92\xac\xd2\x7c\xab\xd5\xa9\x81\xf4\xc9\xb7\xd6\xbf\x68\xf8\x4f\xdc\xf3\x60\xa3\x3b\x29\x92\x9e\xdd\xa2\xa3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x62\xa7\x26\xeb\xd4\x03\x29\x9c\x09\x33\x69\x7a\x9c\x65\x68\xec\x4c\xb9\x06\xeb\x1e\x51\x6f\x78\x20\xdc\xf6\x44\x5e\x06\x6e\x53\x87\x73\xe6\x14\x15\xb9\x17\x74\x67\xe0\x4e\x48\x38\xbc\x1c\xbd\xd0\xad\xd6\xbd\x8c\xf0\x3a\xe0\x13\x73\x19\xad\x8b\x79\x68\x67\x65\x9b\x7a\x4c\x81\xfb\xd9\x92\x77\x89\xb5\xb0\x53\xb0\xa5\xf7\x2d\x8e\x29\x60\x31\xd1\x9b\x2f\x63\x8a\x5f\x64\xc1\x61\xd5\xb7\xdf\x70\x3b\x2b\xf6\x1a\x96\xb9\xa7\x08\xca\x87\xa6\x8c\x60\xca\x6e\xd7\xee\xba\xef\x89\x0b\x93\xd5\xfd\xfc\x14\xba\xef\x27\xba\x90\x11\x90\xf7\x25\x70\xe7\x4e\xf4\x9c\x13\x27\xc1\xa7\x8e\xd9\x66\x43\x72\x20\x5b\xe1\x5c\x73\x74\xf5\x33\xf2\xa5\xf6\xe1\xd5\xac\xf3\x67\x5c\xe7\xd4\x0a\x8d\x91\x73\x03\x3e\x9d\xbc\x96\xc3\x0c\xdb\xd5\x77\x6e\x76\x44\x69\xaf\x24\x0f\x4f\x8b\x47\x36\x8b\xc3\xd6\x36\xdd\x26\x5a\x9c\xdd\x9c\x43\xee\x29\x43\xdd\x75\x2f\x19\x52\xfc\x1d\x24\x9c\x13\x29\x99\xa0\x6d\x7a\x95\xcc\xa0\x58\x86\xd8\xc5\xb9\xa3\xc2\x3d\x64\x1d\x85\x8a\xca\x53\x55\x8e\x9a\x6d\xc9\x91\x73\xf4\xe1\xe1\xa4\x9b\x76\xfc\x7f\x63\xc2\xb9\x23";
|
||||
static struct
|
||||
{
|
||||
wchar_t *hostname;
|
||||
unsigned int datasize;
|
||||
qbyte *data;
|
||||
const qbyte *data;
|
||||
//FIXME: include expiry information
|
||||
//FIXME: add alternative when one is about to expire
|
||||
} knowncerts[] = {
|
||||
{L"triptohell.info", 933, "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\x8b\xd0\x05\x63\x62\xd1\x6a\xe3\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x34\x32\x32\x34\x32\x34\x37\x5a\x17\x0d\x32\x34\x31\x32\x32\x31\x32\x32\x34\x32\x34\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaf\x10\x33\xfa\x39\xf5\xae\x2c\x91\x0e\x20\xe6\x3c\x5c\x7c\x1e\xeb\x16\x50\x2f\x05\x30\xfe\x67\xee\xa9\x00\x54\xd9\x4a\x86\xe6\xba\x80\xfb\x1a\x80\x08\x7e\x7b\x13\xe5\x1a\x18\xc9\xd4\x70\xbd\x5d\xc4\x38\xef\x64\xf1\x90\x2c\x53\x49\x93\x24\x36\x3e\x11\x59\x69\xa6\xdf\x37\xb2\x54\x82\x28\x3e\xdd\x30\x75\xa0\x18\xd8\xe1\xf5\x52\x73\x12\x5b\x37\x68\x1c\x59\xbd\x8c\x73\x66\x47\xbc\xcb\x9c\xfe\x38\x92\x8f\x74\xe9\xd1\x2f\x96\xd2\x5d\x6d\x11\x59\xb2\xdc\xbd\x8c\x37\x5b\x22\x76\x98\xe7\xbe\x08\xef\x1e\x99\xc4\xa9\x77\x2c\x9c\x0e\x08\x3c\x8e\xab\x97\x0c\x6a\xd7\x03\xab\xfd\x4a\x1e\x95\xb2\xc2\x9c\x3a\x16\x65\xd7\xaf\x45\x5f\x6e\xe7\xce\x51\xba\xa0\x60\x43\x0e\x07\xc5\x0b\x0a\x82\x05\x26\xc4\x92\x0a\x27\x5b\xfc\x57\x6c\xdf\xe2\x54\x8a\xef\x38\xf1\xf8\xc4\xf8\x51\x16\x27\x1f\x78\x89\x7c\x5b\xd7\x53\xcd\x9b\x54\x2a\xe6\x71\xee\xe4\x56\x2e\xa4\x09\x1a\x61\xf7\x0f\x97\x22\x94\xd7\xef\x21\x6c\xe6\x81\xfb\x54\x5f\x09\x92\xac\xd2\x7c\xab\xd5\xa9\x81\xf4\xc9\xb7\xd6\xbf\x68\xf8\x4f\xdc\xf3\x60\xa3\x3b\x29\x92\x9e\xdd\xa2\xa3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x62\xa7\x26\xeb\xd4\x03\x29\x9c\x09\x33\x69\x7a\x9c\x65\x68\xec\x4c\xb9\x06\xeb\x1e\x51\x6f\x78\x20\xdc\xf6\x44\x5e\x06\x6e\x53\x87\x73\xe6\x14\x15\xb9\x17\x74\x67\xe0\x4e\x48\x38\xbc\x1c\xbd\xd0\xad\xd6\xbd\x8c\xf0\x3a\xe0\x13\x73\x19\xad\x8b\x79\x68\x67\x65\x9b\x7a\x4c\x81\xfb\xd9\x92\x77\x89\xb5\xb0\x53\xb0\xa5\xf7\x2d\x8e\x29\x60\x31\xd1\x9b\x2f\x63\x8a\x5f\x64\xc1\x61\xd5\xb7\xdf\x70\x3b\x2b\xf6\x1a\x96\xb9\xa7\x08\xca\x87\xa6\x8c\x60\xca\x6e\xd7\xee\xba\xef\x89\x0b\x93\xd5\xfd\xfc\x14\xba\xef\x27\xba\x90\x11\x90\xf7\x25\x70\xe7\x4e\xf4\x9c\x13\x27\xc1\xa7\x8e\xd9\x66\x43\x72\x20\x5b\xe1\x5c\x73\x74\xf5\x33\xf2\xa5\xf6\xe1\xd5\xac\xf3\x67\x5c\xe7\xd4\x0a\x8d\x91\x73\x03\x3e\x9d\xbc\x96\xc3\x0c\xdb\xd5\x77\x6e\x76\x44\x69\xaf\x24\x0f\x4f\x8b\x47\x36\x8b\xc3\xd6\x36\xdd\x26\x5a\x9c\xdd\x9c\x43\xee\x29\x43\xdd\x75\x2f\x19\x52\xfc\x1d\x24\x9c\x13\x29\x99\xa0\x6d\x7a\x95\xcc\xa0\x58\x86\xd8\xc5\xb9\xa3\xc2\x3d\x64\x1d\x85\x8a\xca\x53\x55\x8e\x9a\x6d\xc9\x91\x73\xf4\xe1\xe1\xa4\x9b\x76\xfc\x7f\x63\xc2\xb9\x23"},
|
||||
{L"triptohell.info", 933, triptohell_certdata},
|
||||
{L"fte.triptohell.info", 933, triptohell_certdata},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -543,7 +557,7 @@ static void SSPI_Handshake (sslfile_t *f)
|
|||
OutBuffDesc.cBuffers = 1;
|
||||
OutBuffDesc.pBuffers = &OutSecBuff;
|
||||
|
||||
OutSecBuff.cbBuffer = sizeof(f->outcrypt.data) - f->outcrypt.avail;
|
||||
OutSecBuff.cbBuffer = f->outcrypt.datasize - f->outcrypt.avail;
|
||||
OutSecBuff.BufferType = SECBUFFER_TOKEN;
|
||||
OutSecBuff.pvBuffer = f->outcrypt.data + f->outcrypt.avail;
|
||||
|
||||
|
@ -589,7 +603,11 @@ static void SSPI_Handshake (sslfile_t *f)
|
|||
ss = secur.pInitializeSecurityContextA (&f->cred, &f->sechnd, NULL, MessageAttribute, 0, SECURITY_NATIVE_DREP, &InBuffDesc, 0, &f->sechnd, &OutBuffDesc, &ContextAttributes, &Lifetime);
|
||||
|
||||
if (ss == SEC_E_INCOMPLETE_MESSAGE)
|
||||
{
|
||||
if (f->incrypt.avail == f->incrypt.datasize)
|
||||
SSPI_ExpandBuffer(&f->incrypt, f->incrypt.datasize+1024);
|
||||
return;
|
||||
}
|
||||
|
||||
//any extra data should still remain for the next time around. this might be more handshake data or payload data.
|
||||
if (InSecBuff[1].BufferType == SECBUFFER_EXTRA)
|
||||
|
@ -620,7 +638,11 @@ static void SSPI_Handshake (sslfile_t *f)
|
|||
ss = secur.pAcceptSecurityContext(&f->cred, (f->handshaking==HS_SERVER)?&f->sechnd:NULL, &InBuffDesc, ASC_REQ_ALLOCATE_MEMORY|ASC_REQ_STREAM|ASC_REQ_CONFIDENTIALITY, SECURITY_NATIVE_DREP, &f->sechnd, &OutBuffDesc, &ContextAttributes, &Lifetime);
|
||||
|
||||
if (ss == SEC_E_INCOMPLETE_MESSAGE)
|
||||
{
|
||||
if (f->incrypt.avail == f->incrypt.datasize)
|
||||
SSPI_ExpandBuffer(&f->incrypt, f->incrypt.datasize+1024);
|
||||
return;
|
||||
}
|
||||
f->handshaking = HS_SERVER;
|
||||
|
||||
//any extra data should still remain for the next time around. this might be more handshake data or payload data.
|
||||
|
@ -776,6 +798,12 @@ static qboolean QDECL SSPI_Close (struct vfsfile_s *file)
|
|||
sslfile_t *f = (sslfile_t *)file;
|
||||
qboolean success = f->stream != NULL;
|
||||
SSPI_Error(f, "");
|
||||
|
||||
Z_Free(f->outraw.data);
|
||||
Z_Free(f->outcrypt.data);
|
||||
Z_Free(f->inraw.data);
|
||||
Z_Free(f->incrypt.data);
|
||||
|
||||
Z_Free(f);
|
||||
return success;
|
||||
}
|
||||
|
@ -834,6 +862,11 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server)
|
|||
newf->funcs.WriteBytes = SSPI_WriteBytes;
|
||||
newf->funcs.seekingisabadplan = true;
|
||||
|
||||
SSPI_ExpandBuffer(&newf->outraw, 8192);
|
||||
SSPI_ExpandBuffer(&newf->outcrypt, 8192);
|
||||
SSPI_ExpandBuffer(&newf->inraw, 8192);
|
||||
SSPI_ExpandBuffer(&newf->incrypt, 8192);
|
||||
|
||||
if (server)
|
||||
SSPI_GenServerCredentials(newf);
|
||||
|
||||
|
|
|
@ -2544,7 +2544,11 @@ qboolean FTENET_Generic_SendPacket(ftenet_generic_connection_t *con, int length,
|
|||
Con_DPrintf("NET_SendPacket Warning: %i\n", ecode);
|
||||
else
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
Con_TPrintf ("NET_SendPacket ERROR: %i\n", ecode);
|
||||
#else
|
||||
Con_TPrintf ("NET_SendPacket ERROR: %s\n", strerror(ecode));
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
|
@ -2807,6 +2811,82 @@ void tobase64(unsigned char *out, int outlen, unsigned char *in, int inlen)
|
|||
*out = 0;
|
||||
}
|
||||
|
||||
qboolean FTENET_TCPConnect_WebSocket_Splurge(ftenet_tcpconnect_stream_t *st, qbyte packettype, const qbyte *data, unsigned int length)
|
||||
{
|
||||
/*as a server, we don't need the mask stuff*/
|
||||
unsigned short ctrl = 0x8000 | (packettype<<8);
|
||||
unsigned int paylen = 0;
|
||||
unsigned int payoffs = st->outlen;
|
||||
int i;
|
||||
switch((ctrl>>8) & 0xf)
|
||||
{
|
||||
case 1:
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
paylen += (((char*)data)[i] == 0 || ((unsigned char*)data)[i] >= 0x80)?2:1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
paylen = length;
|
||||
break;
|
||||
}
|
||||
if (paylen >= 126)
|
||||
ctrl |= 126;
|
||||
else
|
||||
ctrl |= paylen;
|
||||
|
||||
if (payoffs + 4 + paylen > sizeof(st->outbuffer))
|
||||
return false;
|
||||
|
||||
st->outbuffer[payoffs++] = ctrl>>8;
|
||||
st->outbuffer[payoffs++] = ctrl&0xff;
|
||||
if ((ctrl&0x7f) == 126)
|
||||
{
|
||||
st->outbuffer[payoffs++] = paylen>>8;
|
||||
st->outbuffer[payoffs++] = paylen&0xff;
|
||||
}
|
||||
switch((ctrl>>8) & 0xf)
|
||||
{
|
||||
case 1:/*utf8ify the data*/
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (!((unsigned char*)data)[i])
|
||||
{ /*0 is encoded as 0x100 to avoid safety checks*/
|
||||
st->outbuffer[payoffs++] = 0xc0 | (0x100>>6);
|
||||
st->outbuffer[payoffs++] = 0x80 | (0x100&0x3f);
|
||||
}
|
||||
else if (((unsigned char*)data)[i] >= 0x80)
|
||||
{ /*larger bytes require markup*/
|
||||
st->outbuffer[payoffs++] = 0xc0 | (((unsigned char*)data)[i]>>6);
|
||||
st->outbuffer[payoffs++] = 0x80 | (((unsigned char*)data)[i]&0x3f);
|
||||
}
|
||||
else
|
||||
{ /*lower 7 bits are as-is*/
|
||||
st->outbuffer[payoffs++] = ((char*)data)[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: //raw data
|
||||
memcpy(st->outbuffer+payoffs, data, length);
|
||||
payoffs += length;
|
||||
break;
|
||||
}
|
||||
st->outlen = payoffs;
|
||||
|
||||
|
||||
if (st->outlen)
|
||||
{ /*try and flush the old data*/
|
||||
int done;
|
||||
done = VFS_WRITE(st->clientstream, st->outbuffer, st->outlen);
|
||||
if (done > 0)
|
||||
{
|
||||
memmove(st->outbuffer, st->outbuffer + done, st->outlen - done);
|
||||
st->outlen -= done;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "fs.h"
|
||||
qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
|
||||
{
|
||||
|
@ -3218,35 +3298,47 @@ handshakeerror:
|
|||
unsigned int payoffs = 2;
|
||||
unsigned int mask = 0;
|
||||
st->inbuffer[st->inlen]=0;
|
||||
if (ctrl & 0x7000)
|
||||
{
|
||||
Con_Printf ("%s: reserved bits set\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
}
|
||||
if ((ctrl & 0x7f) == 127)
|
||||
{
|
||||
unsigned long long ullpaylen;
|
||||
//as a payload is not allowed to be encoded as too large a type, and quakeworld never used packets larger than 1450 bytes anyway, this code isn't needed (65k is the max even without this)
|
||||
// if (sizeof(paylen) < 8)
|
||||
if (sizeof(ullpaylen) < 8)
|
||||
{
|
||||
Con_Printf ("%s: payload frame too large\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
}
|
||||
/* else
|
||||
else
|
||||
{
|
||||
if (payoffs + 8 > st->inlen)
|
||||
break;
|
||||
paylen =
|
||||
((unsigned char*)st->inbuffer)[payoffs+0]<<56 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+1]<<48 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+2]<<40 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+3]<<32 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+4]<<24 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+5]<<16 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+6]<<8 |
|
||||
((unsigned char*)st->inbuffer)[payoffs+7]<<0;
|
||||
if (paylen < 0x10000)
|
||||
ullpaylen =
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+0]<<56ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+1]<<48ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+2]<<40ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+3]<<32ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+4]<<24ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+5]<<16ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+6]<< 8ull |
|
||||
(unsigned long long)((unsigned char*)st->inbuffer)[payoffs+7]<< 0ull;
|
||||
if (ullpaylen < 0x10000)
|
||||
{
|
||||
Con_Printf ("%s: payload size encoded badly\n", NET_AdrToString (st->remoteaddr, sizeof(st->remoteaddr), net_from));
|
||||
Con_Printf ("%s: payload size (%llu) encoded badly\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), ullpaylen);
|
||||
goto closesvstream;
|
||||
}
|
||||
if (ullpaylen > 0x10000)
|
||||
{
|
||||
Con_Printf ("%s: payload size (%llu) is abusive\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr), st->inbuffer, ullpaylen);
|
||||
goto closesvstream;
|
||||
}
|
||||
paylen = ullpaylen;
|
||||
payoffs += 8;
|
||||
}
|
||||
*/ }
|
||||
}
|
||||
else if ((ctrl & 0x7f) == 126)
|
||||
{
|
||||
if (payoffs + 2 > st->inlen)
|
||||
|
@ -3293,10 +3385,10 @@ handshakeerror:
|
|||
|
||||
switch((ctrl>>8) & 0xf)
|
||||
{
|
||||
case 0: /*continuation*/
|
||||
case 0x0: /*continuation*/
|
||||
Con_Printf ("websocket continuation frame from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
case 1: /*text frame*/
|
||||
case 0x1: /*text frame*/
|
||||
// Con_Printf ("websocket text frame from %s\n", NET_AdrToString (adr, sizeof(adr), st->remoteaddr));
|
||||
{
|
||||
/*text frames are pure utf-8 chars, no dodgy encodings or anything, all pre-checked...
|
||||
|
@ -3330,8 +3422,8 @@ handshakeerror:
|
|||
net_message.cursize = out - net_message_buffer;
|
||||
}
|
||||
break;
|
||||
case 2: /*binary frame*/
|
||||
// Con_Printf ("websocket binary frame from %s\n", NET_AdrToString (adr, sizeof(adr), st->remoteaddr));
|
||||
case 0x2: /*binary frame*/
|
||||
Con_Printf ("websocket binary frame from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
net_message.cursize = paylen;
|
||||
if (net_message.cursize+8 >= sizeof(net_message_buffer) )
|
||||
{
|
||||
|
@ -3350,13 +3442,15 @@ handshakeerror:
|
|||
else
|
||||
memcpy(net_message_buffer, st->inbuffer+payoffs, paylen);
|
||||
break;
|
||||
case 8: /*connection close*/
|
||||
case 0x8: /*connection close*/
|
||||
Con_Printf ("websocket closure %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
case 9: /*ping*/
|
||||
case 0x9: /*ping*/
|
||||
Con_Printf ("websocket ping from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
case 10: /*pong*/
|
||||
if (!FTENET_TCPConnect_WebSocket_Splurge(st, 0xa, st->inbuffer+payoffs, paylen))
|
||||
goto closesvstream;
|
||||
break;
|
||||
case 0xa: /*pong*/
|
||||
Con_Printf ("websocket pong from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||
goto closesvstream;
|
||||
default:
|
||||
|
@ -3479,67 +3573,7 @@ qboolean FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
|
|||
//fallthrough
|
||||
case TCPC_WEBSOCKETU:
|
||||
case TCPC_WEBSOCKETB:
|
||||
{
|
||||
/*as a server, we don't need the mask stuff*/
|
||||
unsigned short ctrl = (st->clienttype==TCPC_WEBSOCKETU)?0x8100:0x8200;
|
||||
unsigned int paylen = 0;
|
||||
unsigned int payoffs = 2;
|
||||
int i;
|
||||
switch((ctrl>>8) & 0xf)
|
||||
{
|
||||
case 1:
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
paylen += (((char*)data)[i] == 0 || ((unsigned char*)data)[i] >= 0x80)?2:1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
paylen = length;
|
||||
break;
|
||||
}
|
||||
if (paylen >= 126)
|
||||
{
|
||||
ctrl |= 126;
|
||||
payoffs += 2;
|
||||
}
|
||||
else
|
||||
ctrl |= paylen;
|
||||
|
||||
st->outbuffer[0] = ctrl>>8;
|
||||
st->outbuffer[1] = ctrl&0xff;
|
||||
if (paylen >= 126)
|
||||
{
|
||||
st->outbuffer[2] = paylen>>8;
|
||||
st->outbuffer[3] = paylen&0xff;
|
||||
}
|
||||
switch((ctrl>>8) & 0xf)
|
||||
{
|
||||
case 1:/*utf8ify the data*/
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (!((unsigned char*)data)[i])
|
||||
{ /*0 is encoded as 0x100 to avoid safety checks*/
|
||||
st->outbuffer[payoffs++] = 0xc0 | (0x100>>6);
|
||||
st->outbuffer[payoffs++] = 0x80 | (0x100&0x3f);
|
||||
}
|
||||
else if (((unsigned char*)data)[i] >= 0x80)
|
||||
{ /*larger bytes require markup*/
|
||||
st->outbuffer[payoffs++] = 0xc0 | (((unsigned char*)data)[i]>>6);
|
||||
st->outbuffer[payoffs++] = 0x80 | (((unsigned char*)data)[i]&0x3f);
|
||||
}
|
||||
else
|
||||
{ /*lower 7 bits are as-is*/
|
||||
st->outbuffer[payoffs++] = ((char*)data)[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: //raw data
|
||||
memcpy(st->outbuffer+payoffs, data, length);
|
||||
payoffs += length;
|
||||
break;
|
||||
}
|
||||
st->outlen = payoffs;
|
||||
}
|
||||
FTENET_TCPConnect_WebSocket_Splurge(st, (st->clienttype==TCPC_WEBSOCKETU)?1:2, data, length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -4395,7 +4429,8 @@ static qboolean FTENET_WebSocket_SendPacket(ftenet_generic_connection_t *gcon, i
|
|||
ftenet_websocket_connection_t *wsc = (void*)gcon;
|
||||
if (NET_CompareAdr(to, &wsc->remoteadr))
|
||||
{
|
||||
emscriptenfte_ws_send(wsc->sock, data, length);
|
||||
if (emscriptenfte_ws_send(wsc->sock, data, length) < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -5846,8 +5881,16 @@ int QDECL VFSTCP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestorea
|
|||
if (tf->sock != INVALID_SOCKET)
|
||||
{
|
||||
trying = sizeof(tf->readbuffer) - tf->readbuffered;
|
||||
if (trying > 1500)
|
||||
trying = 1500;
|
||||
if (bytestoread > 1500)
|
||||
{
|
||||
if (trying > bytestoread)
|
||||
trying = bytestoread;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (trying > 1500)
|
||||
trying = 1500;
|
||||
}
|
||||
len = recv(tf->sock, tf->readbuffer + tf->readbuffered, trying, 0);
|
||||
if (len == -1)
|
||||
{
|
||||
|
@ -5924,7 +5967,7 @@ int QDECL VFSTCP_WriteBytes (struct vfsfile_s *file, const void *buffer, int byt
|
|||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&fd);
|
||||
FD_SET(tf->sock, &fd);
|
||||
if (!select((int)tf->sock+1, NULL, &fd, NULL, &timeout))
|
||||
if (!select((int)tf->sock+1, NULL, &fd, &fd, &timeout))
|
||||
return 0;
|
||||
tf->conpending = false;
|
||||
}
|
||||
|
@ -5939,7 +5982,7 @@ int QDECL VFSTCP_WriteBytes (struct vfsfile_s *file, const void *buffer, int byt
|
|||
return 0; //nothing available yet.
|
||||
case NET_ENOTCONN:
|
||||
Con_Printf("connection to \"%s\" failed\n", tf->peer);
|
||||
break;
|
||||
return -1; //don't bother trying to read if we never connected.
|
||||
default:
|
||||
Sys_Printf("tcp socket error %i (%s)\n", e, tf->peer);
|
||||
break;
|
||||
|
|
|
@ -77,7 +77,7 @@ typedef struct plugin_s {
|
|||
struct plugin_s *next;
|
||||
} plugin_t;
|
||||
|
||||
void Plug_SubConsoleCommand(console_t *con, char *line);
|
||||
int Plug_SubConsoleCommand(console_t *con, char *line);
|
||||
|
||||
plugin_t *currentplug;
|
||||
|
||||
|
@ -262,6 +262,8 @@ plugin_t *Plug_Load(const char *file, int type)
|
|||
newplug->name = (char*)(newplug+1);
|
||||
strcpy(newplug->name, file);
|
||||
|
||||
if (!newplug->vm && (type & PLUG_NATIVE))
|
||||
newplug->vm = VM_Create(va("fteplug_%s_", file), Plug_SystemCallsNative, NULL);
|
||||
if (!newplug->vm && (type & PLUG_NATIVE))
|
||||
newplug->vm = VM_Create(va("fteplug_%s", file), Plug_SystemCallsNative, NULL);
|
||||
if (!newplug->vm && (type & PLUG_QVM))
|
||||
|
@ -334,6 +336,9 @@ static int QDECL Plug_EnumeratedRoot (const char *name, qofs_t size, time_t mtim
|
|||
if (dot)
|
||||
*dot = 0;
|
||||
}
|
||||
len = strlen(vmname);
|
||||
if (len > 0 && vmname[len-1] == '_')
|
||||
vmname[len-1] = 0;
|
||||
if (!Plug_Load(vmname, PLUG_NATIVE))
|
||||
Con_Printf("Couldn't load plugin %s\n", vmname);
|
||||
|
||||
|
@ -1538,16 +1543,18 @@ qboolean Plug_ConsoleLink(char *text, char *info)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Plug_SubConsoleCommand(console_t *con, char *line)
|
||||
int Plug_SubConsoleCommand(console_t *con, char *line)
|
||||
{
|
||||
int ret;
|
||||
char buffer[2048];
|
||||
plugin_t *oldplug = currentplug; //shouldn't really be needed, but oh well
|
||||
currentplug = con->userdata;
|
||||
|
||||
Q_strncpyz(buffer, va("\"%s\" %s", con->name, line), sizeof(buffer));
|
||||
Cmd_TokenizeString(buffer, false, false);
|
||||
VM_Call(currentplug->vm, currentplug->conexecutecommand, 0);
|
||||
ret = VM_Call(currentplug->vm, currentplug->conexecutecommand, 0);
|
||||
currentplug = oldplug;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Plug_SpellCheckMaskedText(unsigned int *maskedstring, int maskedchars, int x, int y, int cs, int firstc, int charlimit)
|
||||
|
|
|
@ -295,9 +295,9 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
debuggerinstance = prinst;
|
||||
debuggerfile = filename;
|
||||
if (reason)
|
||||
Con_Footerf(false, "^bDebugging: %s", reason);
|
||||
Con_Footerf(NULL, false, "^bDebugging: %s", reason);
|
||||
else
|
||||
Con_Footerf(false, "^bDebugging");
|
||||
Con_Footerf(NULL, false, "^bDebugging");
|
||||
while(debuggerresume == -1 && !wantquit)
|
||||
{
|
||||
Sleep(10);
|
||||
|
@ -1015,7 +1015,16 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
world_t *w = prinst->parms->user;
|
||||
wedict_t *ent = (wedict_t*)PROG_TO_EDICT(prinst, *w->g.self);
|
||||
wedict_t *ent = ((prinst->callargc>0)?G_WEDICT(prinst, OFS_PARM0):PROG_TO_WEDICT(prinst, *w->g.self));
|
||||
if (prinst->callargc > 1)
|
||||
{
|
||||
if (ent->readonly)
|
||||
{
|
||||
Con_Printf("setorigin on readonly entity %i\n", ent->entnum);
|
||||
return;
|
||||
}
|
||||
VectorCopy(G_VECTOR(OFS_PARM1), ent->v->origin);
|
||||
}
|
||||
World_LinkEdict (w, ent, true);
|
||||
}
|
||||
|
||||
|
@ -1231,6 +1240,11 @@ void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
G_INT(OFS_RETURN) = 0;
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_cvars_haveunsaved (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = Cvar_UnsavedArchive();
|
||||
}
|
||||
|
||||
//string(string cvarname) cvar_defstring
|
||||
void QCBUILTIN PF_cvar_defstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -1438,8 +1452,6 @@ void QCBUILTIN PF_memptradd (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
//memory stuff
|
||||
////////////////////////////////////////////////////
|
||||
//hash table stuff
|
||||
#define MAX_QC_HASHTABLES 256
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pubprogfuncs_t *prinst;
|
||||
|
@ -1458,12 +1470,16 @@ typedef struct
|
|||
char *stringdata;
|
||||
};
|
||||
} pf_hashentry_t;
|
||||
pf_hashtab_t pf_hashtab[MAX_QC_HASHTABLES];
|
||||
pf_hashtab_t *pf_hashtab;
|
||||
size_t pf_hash_maxtables;
|
||||
pf_hashtab_t pf_peristanthashtab; //persists over map changes.
|
||||
pf_hashtab_t pf_reverthashtab; //pf_peristanthashtab as it was at map start, for map restarts.
|
||||
static pf_hashtab_t *PF_hash_findtab(pubprogfuncs_t *prinst, int idx)
|
||||
{
|
||||
if (!idx)
|
||||
idx -= 1;
|
||||
if (idx >= 0 && (unsigned)idx < pf_hash_maxtables && pf_hashtab[idx].prinst)
|
||||
return &pf_hashtab[idx];
|
||||
else if (idx == -1)
|
||||
{
|
||||
if (!pf_peristanthashtab.tab.numbuckets)
|
||||
{
|
||||
|
@ -1475,9 +1491,6 @@ static pf_hashtab_t *PF_hash_findtab(pubprogfuncs_t *prinst, int idx)
|
|||
}
|
||||
return &pf_peristanthashtab;
|
||||
}
|
||||
idx -= 1;
|
||||
if (idx >= 0 && idx < MAX_QC_HASHTABLES && pf_hashtab[idx].prinst)
|
||||
return &pf_hashtab[idx];
|
||||
else
|
||||
PR_BIError(prinst, "PF_hash_findtab: invalid hash table\n");
|
||||
return NULL;
|
||||
|
@ -1585,7 +1598,7 @@ void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
{
|
||||
if (!type)
|
||||
type = tab->defaulttype;
|
||||
if (flags & 256)
|
||||
if (!(flags & 512) || (flags & 256))
|
||||
{
|
||||
ent = Hash_Get(&tab->tab, name);
|
||||
if (ent)
|
||||
|
@ -1635,6 +1648,7 @@ void QCBUILTIN PF_hash_destroytab (pubprogfuncs_t *prinst, struct globalvars_s *
|
|||
}
|
||||
void QCBUILTIN PF_hash_createtab (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
//FIXME: these need to be managed by the qcvm for garbage collection
|
||||
int i;
|
||||
int numbuckets = G_FLOAT(OFS_PARM0);
|
||||
// qboolean dupestrings = (prinst->callargc>1)?G_FLOAT(OFS_PARM1):false;
|
||||
|
@ -1643,20 +1657,27 @@ void QCBUILTIN PF_hash_createtab (pubprogfuncs_t *prinst, struct globalvars_s *p
|
|||
type = ev_vector;
|
||||
if (numbuckets < 4)
|
||||
numbuckets = 64;
|
||||
for (i = 0; i < MAX_QC_HASHTABLES; i++)
|
||||
{
|
||||
|
||||
for (i = 0; i < pf_hash_maxtables; i++)
|
||||
{ //look for an empty slot
|
||||
if (!pf_hashtab[i].prinst)
|
||||
break;
|
||||
}
|
||||
if (i == pf_hash_maxtables)
|
||||
{ //all slots taken, expand list
|
||||
if (!ZF_ReallocElements(&pf_hashtab, &pf_hash_maxtables, pf_hash_maxtables+64, sizeof(*pf_hashtab)))
|
||||
{
|
||||
pf_hashtab[i].defaulttype = type;
|
||||
pf_hashtab[i].prinst = prinst;
|
||||
pf_hashtab[i].bucketmem = Z_Malloc(Hash_BytesForBuckets(numbuckets));
|
||||
Hash_InitTable(&pf_hashtab[i].tab, numbuckets, pf_hashtab[i].bucketmem);
|
||||
G_FLOAT(OFS_RETURN) = i + 1;
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
return;
|
||||
|
||||
//fill it in
|
||||
pf_hashtab[i].defaulttype = type;
|
||||
pf_hashtab[i].prinst = prinst;
|
||||
pf_hashtab[i].bucketmem = Z_Malloc(Hash_BytesForBuckets(numbuckets));
|
||||
Hash_InitTable(&pf_hashtab[i].tab, numbuckets, pf_hashtab[i].bucketmem);
|
||||
G_FLOAT(OFS_RETURN) = i + 1;
|
||||
}
|
||||
|
||||
void pf_hash_savegame(void) //write the persistant table to a saved game.
|
||||
|
@ -4847,6 +4868,11 @@ void QCBUILTIN PF_localcmd (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
char *str;
|
||||
|
||||
str = PF_VarString(prinst, 0, pr_globals);
|
||||
if (developer.ival)
|
||||
{
|
||||
PR_StackTrace(prinst, false);
|
||||
Con_Printf("localcmd: %s\n", str);
|
||||
}
|
||||
if (!strcmp(str, "host_framerate 0\n"))
|
||||
Cbuf_AddText ("sv_mintic 0\n", RESTRICT_INSECURE); //hmm... do this better...
|
||||
else
|
||||
|
|
|
@ -269,11 +269,19 @@ void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr
|
|||
void QCBUILTIN PF_physics_addforce(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_physics_addtorque(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_create(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_delete(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_selected(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_getfacepoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_brush_findinvolume(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
||||
//pr_cmds.c builtins that need to be moved to a common.
|
||||
void VARGS PR_BIError(pubprogfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2);
|
||||
void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_cvars_haveunsaved (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_cvar_set (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_cvar_setf (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
void QCBUILTIN PF_ArgC (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
|
||||
|
@ -621,7 +629,7 @@ typedef enum
|
|||
//33-36 used by DP...
|
||||
VF_PERSPECTIVE = 200,
|
||||
//201 used by DP... WTF? CLEARSCREEN
|
||||
VF_LPLAYER = 202,
|
||||
VF_ACTIVESEAT = 202,
|
||||
VF_AFOV = 203, //aproximate fov (match what the engine would normally use for the fov cvar). p0=fov, p1=zoom
|
||||
VF_SCREENVSIZE = 204,
|
||||
VF_SCREENPSIZE = 205,
|
||||
|
|
|
@ -282,6 +282,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define svcfte_voicechat 84
|
||||
#define svcfte_setangledelta 85 // [angle3] add this to the current viewangles
|
||||
#define svcfte_updateentities 86
|
||||
#define svcfte_brushedit 87 // networked brush editing, paired with clcfte_brushedit.
|
||||
|
||||
|
||||
//fitz svcs
|
||||
|
@ -413,14 +414,15 @@ enum clcq2_ops_e
|
|||
#define clc_stringcmd 4 // [string] message
|
||||
#define clc_delta 5 // [qbyte] sequence number, requests delta compression of message
|
||||
#define clc_tmove 6 // teleport request, spectator only
|
||||
#define clc_upload 7 // teleport request, spectator only
|
||||
#define clc_upload 7 //
|
||||
|
||||
#define clcdp_ackframe 50
|
||||
#define clcdp_ackdownloaddata 51
|
||||
|
||||
#define clc_qcrequest 81
|
||||
#define clc_prydoncursor 82
|
||||
#define clc_voicechat 83
|
||||
#define clcfte_qcrequest 81
|
||||
#define clcfte_prydoncursor 82
|
||||
#define clcfte_voicechat 83
|
||||
#define clcfte_brushedit 84
|
||||
|
||||
//==============================================
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
void Sys_mkdir (char *path); //not all pre-unix systems have directories (including dos 1)
|
||||
qboolean Sys_remove (char *path);
|
||||
qboolean Sys_Rename (char *oldfname, char *newfname);
|
||||
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen);
|
||||
qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *basepath, int basepathlen, qboolean allowprompts);
|
||||
|
||||
//
|
||||
// memory protection
|
||||
|
@ -49,6 +49,7 @@ void Sys_Warn (char *fmt, ...) LIKEPRINTF(1);
|
|||
|
||||
void Sys_Quit (void);
|
||||
void Sys_RecentServer(char *command, char *target, char *title, char *desc);
|
||||
qboolean Sys_RunInstaller(void);
|
||||
|
||||
typedef struct {
|
||||
void **funcptr;
|
||||
|
|
|
@ -72,6 +72,8 @@ typedef struct trace_s
|
|||
|
||||
qboolean inopen, inwater;
|
||||
float truefraction; //can be negative, also has floating point precision issues, etc.
|
||||
int brush_id;
|
||||
int brush_face;
|
||||
} trace_t;
|
||||
|
||||
typedef struct q2trace_s
|
||||
|
|
|
@ -322,6 +322,34 @@ void VARGS Z_FreeTags(int tag)
|
|||
}
|
||||
}
|
||||
|
||||
//close enough
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
qboolean ZF_ReallocElements(void **ptr, size_t *elements, size_t newelements, size_t elementsize)
|
||||
{
|
||||
void *n;
|
||||
size_t oldsize;
|
||||
size_t newsize;
|
||||
|
||||
//protect against malicious overflows
|
||||
if (newelements > SIZE_MAX / elementsize)
|
||||
return false;
|
||||
|
||||
oldsize = *elements * elementsize;
|
||||
newsize = newelements * elementsize;
|
||||
|
||||
n = BZ_Realloc(*ptr, newsize);
|
||||
if (!n)
|
||||
return false;
|
||||
if (newsize > oldsize)
|
||||
memset((char*)n+oldsize, 0, newsize - oldsize);
|
||||
*elements = newelements;
|
||||
*ptr = n;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void *Z_Realloc(void *data, int newsize)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,8 @@ void *ZF_MallocNamed (int size, char *file, int line); // allowed to fail
|
|||
void *VARGS Z_TagMalloc (int size, int tag);
|
||||
void VARGS Z_TagFree(void *ptr);
|
||||
void VARGS Z_FreeTags(int tag);
|
||||
//void *Z_Realloc (void *ptr, int size);
|
||||
qboolean ZF_ReallocElements(void **ptr, size_t *elements, size_t newelements, size_t elementsize); //returns false on error
|
||||
#define Z_ReallocElements(ptr,elements,newelements,elementsize) do{if (!ZF_ReallocElements(ptr,elements,newelements,elementsize))Sys_Error("Z_ReallocElements failed (%s %i)\n", __FILE__, __LINE__);}while(0) //returns false on error
|
||||
|
||||
//Big Zone: allowed to fail, doesn't clear. The expectation is a large file, rather than sensitive data structures.
|
||||
//(this is a nicer name for malloc)
|
||||
|
|
|
@ -759,9 +759,9 @@ static void (D3D9_VID_DeInit) (void)
|
|||
mainwindow = NULL;
|
||||
}
|
||||
|
||||
Cvar_Unhook(&v_gamma);
|
||||
Cvar_Unhook(&v_contrast);
|
||||
Cvar_Unhook(&v_brightness);
|
||||
// Cvar_Unhook(&v_gamma);
|
||||
// Cvar_Unhook(&v_contrast);
|
||||
// Cvar_Unhook(&v_brightness);
|
||||
}
|
||||
|
||||
qboolean D3D9_VID_ApplyGammaRamps (unsigned short *ramps)
|
||||
|
|
|
@ -2,9 +2,9 @@ Microsoft Visual Studio Solution File, Format Version 9.00
|
|||
# Visual Studio 2005
|
||||
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "FTEQuake", "..\setup\setup.vdproj", "{E0EE8B50-3A75-42A9-B80A-787675979B0C}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{82285268-9C3B-44AD-BBE7-40670F9D2628} = {82285268-9C3B-44AD-BBE7-40670F9D2628}
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA} = {9767E236-8454-44E9-8999-CD5BDAFBE9BA}
|
||||
{72269FEE-293D-40BC-A7AE-E429F4496869} = {72269FEE-293D-40BC-A7AE-E429F4496869}
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA} = {9767E236-8454-44E9-8999-CD5BDAFBE9BA}
|
||||
{82285268-9C3B-44AD-BBE7-40670F9D2628} = {82285268-9C3B-44AD-BBE7-40670F9D2628}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "botlib", "botlib.vcproj", "{0018E098-B12A-4E4D-9B22-6772DA287080}"
|
||||
|
@ -33,6 +33,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "httpserver", "..\http\https
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftequake", "ftequake.vcproj", "{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA} = {9767E236-8454-44E9-8999-CD5BDAFBE9BA}
|
||||
{0018E098-B12A-4E4D-9B22-6772DA287080} = {0018E098-B12A-4E4D-9B22-6772DA287080}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
@ -351,6 +352,7 @@ Global
|
|||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.GLDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.GLDebug|Win32.Build.0 = Debug|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.GLDebug|x64.ActiveCfg = Debug|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.GLRelease|Win32.ActiveCfg = Release|Win32
|
||||
{9767E236-8454-44E9-8999-CD5BDAFBE9BA}.GLRelease|x64.ActiveCfg = Release|Win32
|
||||
|
|
|
@ -26099,6 +26099,10 @@
|
|||
RelativePath="..\common\fs_win32.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\fs_xz.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\fs_zip.c"
|
||||
>
|
||||
|
|
|
@ -742,6 +742,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
cm->texnum.specular = r_nulltex;
|
||||
cm->texnum.loweroverlay = r_nulltex;
|
||||
cm->texnum.upperoverlay = r_nulltex;
|
||||
cm->texnum.paletted = r_nulltex;
|
||||
|
||||
//q2 has no surfaces in its player models, so don't crash from that
|
||||
//note that q2 should also always have a custom skin set. its not our problem (here) if it doesn't.
|
||||
|
|
|
@ -3531,6 +3531,12 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
shaderstate.crepskyshader = R_RegisterShader("crepuscular_sky", SUF_NONE,
|
||||
"{\n"
|
||||
"program crepuscular_sky\n"
|
||||
"{\n"
|
||||
"map $diffuse\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $fullbright\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
@ -3988,7 +3994,7 @@ static void DrawMeshes(void)
|
|||
{
|
||||
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
|
||||
}
|
||||
BE_SendPassBlendDepthMask((shaderstate.curshader->passes[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_NODEPTHTEST);
|
||||
BE_SendPassBlendDepthMask((shaderstate.curshader->passes[0].shaderbits & ~SBITS_BLEND_BITS) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | ((r_wireframe.ival == 1)?SBITS_MISC_NODEPTHTEST:0));
|
||||
|
||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR), 0);
|
||||
BE_SubmitMeshChain(false);
|
||||
|
@ -4629,6 +4635,7 @@ static void BE_UpdateLightmaps(void)
|
|||
lightmapinfo_t *lm;
|
||||
int lmidx;
|
||||
int glformat, gltype;
|
||||
int internalformat = GL_RGBA;
|
||||
switch (lightmap_bytes)
|
||||
{
|
||||
case 4:
|
||||
|
@ -4644,6 +4651,9 @@ static void BE_UpdateLightmaps(void)
|
|||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
}
|
||||
if (gl_config.gles)
|
||||
internalformat = glformat;
|
||||
|
||||
for (lmidx = 0; lmidx < numlightmaps; lmidx++)
|
||||
{
|
||||
lm = lightmap[lmidx];
|
||||
|
@ -4660,7 +4670,7 @@ static void BE_UpdateLightmaps(void)
|
|||
GL_MTBind(0, GL_TEXTURE_2D, lm->lightmap_texture);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, internalformat,
|
||||
lm->width, lm->height, 0, glformat, gltype,
|
||||
lm->lightmaps);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ http://prideout.net/archive/bloom/ contains some sample code
|
|||
#include "shader.h"
|
||||
#include "glquake.h"
|
||||
cvar_t r_bloom = CVARAFD("r_bloom", "0", "gl_bloom", CVAR_ARCHIVE, "Enables bloom (light bleeding from bright objects). Fractional values reduce the amount shown.");
|
||||
cvar_t r_bloom_filter = CVARD("r_bloom_filter", "0.5 0.5 0.5", "Controls how bright the image must get before it will bloom (3 separate values, in RGB order).");
|
||||
cvar_t r_bloom_filter = CVARD("r_bloom_filter", "0.7 0.7 0.7", "Controls how bright the image must get before it will bloom (3 separate values, in RGB order).");
|
||||
cvar_t r_bloom_scale = CVARD("r_bloom_scale", "0.5", "Controls the initial downscale size. Smaller values will bloom further but be more random.");
|
||||
static shader_t *bloomfilter;
|
||||
static shader_t *bloomrescale;
|
||||
|
|
|
@ -233,7 +233,7 @@ static void GL_Texturemode_Apply(GLenum targ, unsigned int flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((filter[1]))// && !(flags & IF_NEAREST)) || (flags & IF_LINEAR))
|
||||
if ((filter[1] && !(flags & IF_NEAREST)) || (flags & IF_LINEAR))
|
||||
{
|
||||
if (filter[0] && !(flags & IF_NEAREST) || (flags & IF_LINEAR))
|
||||
min = GL_LINEAR_MIPMAP_LINEAR;
|
||||
|
@ -242,7 +242,7 @@ static void GL_Texturemode_Apply(GLenum targ, unsigned int flags)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (filter[0] && !(flags & IF_NEAREST) || (flags & IF_LINEAR))
|
||||
if ((filter[0] && !(flags & IF_NEAREST)) || (flags & IF_LINEAR))
|
||||
min = GL_LINEAR_MIPMAP_NEAREST;
|
||||
else
|
||||
min = GL_NEAREST_MIPMAP_NEAREST;
|
||||
|
@ -324,6 +324,7 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
|
|||
//make sure the texture is complete even if the mips are not.
|
||||
//note that some drivers will just ignore levels that are not valid.
|
||||
//this means that we can't make this setting dynamic, so we might as well let the drivers know BEFORE we do the uploads, to be kind to those that are buggy..
|
||||
//this is available in gles3
|
||||
if (!gl_config.gles)
|
||||
{
|
||||
if (targ != GL_TEXTURE_CUBE_MAP_ARB && (tex->flags & IF_MIPCAP))
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
void Font_Init(void);
|
||||
void Font_Shutdown(void);
|
||||
struct font_s *Font_LoadFont(int height, const char *fontfilename);
|
||||
struct font_s *Font_LoadFont(float height, const char *fontfilename);
|
||||
void Font_Free(struct font_s *f);
|
||||
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
|
||||
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
|
||||
|
@ -161,6 +161,7 @@ static const char *imgs[] =
|
|||
#define BITMAPPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-2)
|
||||
#define DEFAULTPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-3)
|
||||
#define SINGLEPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-4)
|
||||
#define TRACKERIMAGE ((1<<(8*sizeof(PLANEIDXTYPE)))-5)
|
||||
#define PLANEWIDTH (1<<8)
|
||||
#define PLANEHEIGHT PLANEWIDTH
|
||||
|
||||
|
@ -226,6 +227,7 @@ typedef struct font_s
|
|||
typedef struct {
|
||||
texid_t texnum[FONTPLANES];
|
||||
texid_t defaultfont;
|
||||
texid_t trackerimage;
|
||||
|
||||
unsigned char plane[PLANEWIDTH*PLANEHEIGHT][4]; //tracks the current plane
|
||||
PLANEIDXTYPE activeplane;
|
||||
|
@ -259,12 +261,56 @@ static struct font_s *curfont;
|
|||
static float curfont_scale[2];
|
||||
static qboolean curfont_scaled;
|
||||
|
||||
|
||||
//^Ue2XX
|
||||
static struct
|
||||
{
|
||||
image_t *image;
|
||||
char name[64];
|
||||
} trackerimages[256];
|
||||
static int numtrackerimages;
|
||||
#define TRACKERFIRST 0xe200
|
||||
int Font_RegisterTrackerImage(const char *image)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < numtrackerimages; i++)
|
||||
{
|
||||
if (!strcmp(trackerimages[i].name, image))
|
||||
return TRACKERFIRST + i;
|
||||
}
|
||||
if (numtrackerimages == 256)
|
||||
return 0;
|
||||
trackerimages[i].image = NULL; //actually load it elsewhere, because we're lazy.
|
||||
Q_strncpyz(trackerimages[i].name, image, sizeof(trackerimages[i].name));
|
||||
numtrackerimages++;
|
||||
return TRACKERFIRST + i;
|
||||
}
|
||||
//called from the font display code for tracker images
|
||||
static image_t *Font_GetTrackerImage(unsigned int imid)
|
||||
{
|
||||
if (!trackerimages[imid].image)
|
||||
{
|
||||
if (!*trackerimages[imid].name)
|
||||
return NULL;
|
||||
trackerimages[imid].image = Image_GetTexture(trackerimages[imid].name, NULL, 0, NULL, NULL, 0, 0, TF_INVALID);
|
||||
}
|
||||
if (!trackerimages[imid].image)
|
||||
return NULL;
|
||||
if (trackerimages[imid].image->status != TEX_LOADED)
|
||||
return NULL;
|
||||
return trackerimages[imid].image;
|
||||
}
|
||||
|
||||
//called at load time - initalises font buffers
|
||||
void Font_Init(void)
|
||||
{
|
||||
int i;
|
||||
TEXASSIGN(fontplanes.defaultfont, r_nulltex);
|
||||
|
||||
//clear tracker images, just in case they were still set for the previous renderer context
|
||||
for (i = 0; i < sizeof(trackerimages)/sizeof(trackerimages[0]); i++)
|
||||
trackerimages[i].image = NULL;
|
||||
|
||||
font_foremesh.indexes = font_indicies;
|
||||
font_foremesh.xyz_array = font_coord;
|
||||
font_foremesh.st_array = font_texcoord;
|
||||
|
@ -658,6 +704,17 @@ static struct charcache_s *Font_GetChar(font_t *f, CHARIDXTYPE charidx)
|
|||
struct charcache_s *c = &f->chars[charidx];
|
||||
if (c->texplane == INVALIDPLANE)
|
||||
{
|
||||
if (charidx >= TRACKERFIRST && charidx < TRACKERFIRST+100)
|
||||
{
|
||||
static struct charcache_s tc;
|
||||
tc.texplane = TRACKERIMAGE;
|
||||
fontplanes.trackerimage = Font_GetTrackerImage(charidx-TRACKERFIRST);
|
||||
if (!fontplanes.trackerimage)
|
||||
return Font_GetChar(f, '?');
|
||||
tc.advance = fontplanes.trackerimage->width * ((float)f->charheight / fontplanes.trackerimage->height);
|
||||
return &tc;
|
||||
}
|
||||
|
||||
//not cached, can't get.
|
||||
c = Font_TryLoadGlyph(f, charidx);
|
||||
|
||||
|
@ -1079,14 +1136,14 @@ void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
|
|||
|
||||
//creates a new font object from the given file, with each text row with the given height.
|
||||
//width is implicit and scales with height and choice of font.
|
||||
struct font_s *Font_LoadFont(int vheight, const char *fontfilename)
|
||||
struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
|
||||
{
|
||||
struct font_s *f;
|
||||
int i = 0;
|
||||
int defaultplane;
|
||||
char *aname;
|
||||
char *parms;
|
||||
int height = (vheight * vid.rotpixelheight)/vid.height;
|
||||
int height = ((vheight * vid.rotpixelheight)/vid.height) + 0.5;
|
||||
char facename[MAX_QPATH];
|
||||
|
||||
Q_strncpy(facename, fontfilename, sizeof(facename));
|
||||
|
@ -1572,7 +1629,7 @@ int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int max
|
|||
// scan the width of the line
|
||||
for (px=0, l=0 ; px <= maxpixelwidth; )
|
||||
{
|
||||
if (start+l >= end || (start[l]&(CON_CHARMASK|CON_HIDDEN)) == '\n')
|
||||
if (start+l >= end || (start[l]&(CON_CHARMASK|CON_HIDDEN)) == '\n' || (start[l]&(CON_CHARMASK|CON_HIDDEN)) == '\v')
|
||||
break;
|
||||
px = Font_CharEndCoord(font, px, start[l]);
|
||||
l++;
|
||||
|
@ -1600,7 +1657,7 @@ int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int max
|
|||
if (start == end)
|
||||
break;
|
||||
|
||||
if ((*start&(CON_CHARMASK|CON_HIDDEN)) == '\n')
|
||||
if ((*start&(CON_CHARMASK|CON_HIDDEN)) == '\n' || (*start&(CON_CHARMASK|CON_HIDDEN)) == '\v')
|
||||
start++; // skip the \n
|
||||
}
|
||||
|
||||
|
@ -1707,16 +1764,16 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
if ((charcode & CON_CHARMASK) == ' ')
|
||||
return nextx;
|
||||
|
||||
if (charcode & CON_BLINKTEXT)
|
||||
/* if (charcode & CON_BLINKTEXT)
|
||||
{
|
||||
if (!cl_noblink.ival)
|
||||
if ((int)(realtime*3) & 1)
|
||||
return nextx;
|
||||
}
|
||||
|
||||
*/
|
||||
if (charcode & CON_RICHFORECOLOUR)
|
||||
{
|
||||
col = charcode & (CON_2NDCHARSETTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
|
||||
col = charcode & (CON_2NDCHARSETTEXT|CON_BLINKTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
|
@ -1749,6 +1806,11 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
if (charcode & CON_BLINKTEXT)
|
||||
{
|
||||
float a = (sin(realtime*3)+1)*0.4 + 0.2;
|
||||
rgba[3] *= a;
|
||||
}
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
|
@ -1757,7 +1819,7 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
}
|
||||
else
|
||||
{
|
||||
col = charcode & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
|
||||
col = charcode & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA|CON_BLINKTEXT);
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
|
@ -1793,6 +1855,11 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
if (charcode & CON_BLINKTEXT)
|
||||
{
|
||||
float a = (sin(realtime*3)+1)*0.4 + 0.2;
|
||||
rgba[3] *= a;
|
||||
}
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
|
@ -1807,6 +1874,15 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
|
||||
switch(c->texplane)
|
||||
{
|
||||
case TRACKERIMAGE:
|
||||
s0 = t0 = 0;
|
||||
s1 = t1 = 1;
|
||||
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
|
||||
sw = (c->advance*vid.width) / (float)vid.rotpixelwidth;
|
||||
sh = (font->charheight*vid.height) / (float)vid.rotpixelheight;
|
||||
v = Font_BeginChar(fontplanes.trackerimage);
|
||||
break;
|
||||
case DEFAULTPLANE:
|
||||
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
|
||||
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,6 +83,7 @@ void Mod_LoadAliasShaders(model_t *mod);
|
|||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
model_t *lightmodel;
|
||||
struct relight_ctx_s *lightcontext;
|
||||
int numlightdata;
|
||||
qboolean writelitfile;
|
||||
|
||||
|
@ -254,6 +255,7 @@ volatile qboolean wantrelight;
|
|||
int RelightThread(void *arg)
|
||||
{
|
||||
int surf;
|
||||
void *threadctx = malloc(lightthreadctxsize);
|
||||
while (wantrelight)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -265,9 +267,10 @@ int RelightThread(void *arg)
|
|||
#endif
|
||||
if (surf >= lightmodel->numsurfaces)
|
||||
break;
|
||||
LightFace(surf);
|
||||
LightFace(lightcontext, threadctx, surf);
|
||||
lightmodel->surfaces[surf].cached_dlight = -1;
|
||||
}
|
||||
free(threadctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -312,7 +315,7 @@ void Mod_Think (void)
|
|||
return;
|
||||
}
|
||||
#else
|
||||
LightFace(relitsurface);
|
||||
LightFace(lightcontext, relitsurface);
|
||||
Mod_UpdateLightmap(relitsurface);
|
||||
|
||||
relitsurface++;
|
||||
|
@ -337,6 +340,9 @@ void Mod_Think (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
LightShutdown(lightcontext, lightmodel);
|
||||
lightcontext = NULL;
|
||||
|
||||
if (lightmodel->deluxdata)
|
||||
{
|
||||
COM_StripExtension(lightmodel->name, filename, sizeof(filename));
|
||||
|
@ -1180,31 +1186,94 @@ model_t *Mod_ForName (const char *name, enum mlverbosity_e verbosity)
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
static const struct
|
||||
{
|
||||
const char *oldname;
|
||||
unsigned int chksum; //xor-compacted md4
|
||||
const char *newname;
|
||||
} buggytextures[] =
|
||||
{
|
||||
//FIXME: we should load this table from disk or something.
|
||||
//old sum new
|
||||
{"metal5_2", 0x45d110ec, "metal5_2_arc"},
|
||||
{"metal5_2", 0x0d275f87, "metal5_2_x"},
|
||||
{"metal5_4", 0xf8e27da8, "metal5_4_arc"},
|
||||
{"metal5_4", 0xa301c52e, "metal5_4_double"},
|
||||
{"metal5_8", 0xfaa8bf77, "metal5_8_back"},
|
||||
{"metal5_8", 0x88792923, "metal5_8_rune"},
|
||||
{"plat_top1", 0xfe4f9f5a, "plat_top1_bolt"},
|
||||
{"plat_top1", 0x9ac3fccf, "plat_top1_cable"},
|
||||
{"sky4", 0xde688b77, "sky1"},
|
||||
// {"sky4", 0x8a010dc0, "sky4"},
|
||||
// {"window03", ?, "window03_?"},
|
||||
// {"window03", ?, "window03_?"},
|
||||
|
||||
|
||||
//FIXME: hexen2 has the same issue.
|
||||
};
|
||||
static const char *Mod_RemapBuggyTexture(const char *name, const qbyte *data, unsigned int datalen)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(buggytextures)/sizeof(buggytextures[0]); i++)
|
||||
{
|
||||
if (!strcmp(name, buggytextures[i].oldname))
|
||||
{
|
||||
unsigned int sum = Com_BlockChecksum(data, datalen);
|
||||
for (; i < sizeof(buggytextures)/sizeof(buggytextures[0]); i++)
|
||||
{
|
||||
if (strcmp(name, buggytextures[i].oldname))
|
||||
break;
|
||||
if (sum == buggytextures[i].chksum)
|
||||
return buggytextures[i].newname;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void Mod_FinishTexture(texture_t *tx, const char *loadname)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
extern cvar_t gl_shadeq1_name;
|
||||
char altname[MAX_QPATH];
|
||||
char *star;
|
||||
const char *origname = NULL;
|
||||
const char *shadername = tx->name;
|
||||
|
||||
|
||||
/*skies? just replace with the override sky*/
|
||||
if (!strncmp(tx->name, "sky", 3) && *cl.skyname)
|
||||
tx->shader = R_RegisterCustom (va("skybox_%s", cl.skyname), SUF_NONE, Shader_DefaultSkybox, NULL); //just load the regular name.
|
||||
//find the *
|
||||
else if (!*gl_shadeq1_name.string || !strcmp(gl_shadeq1_name.string, "*"))
|
||||
tx->shader = R_RegisterCustom (tx->name, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL); //just load the regular name.
|
||||
else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit.
|
||||
tx->shader = R_RegisterCustom (gl_shadeq1_name.string, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL);
|
||||
else
|
||||
{
|
||||
strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left
|
||||
altname[star-gl_shadeq1_name.string] = '\0';
|
||||
strcat(altname, tx->name); //insert the *
|
||||
strcat(altname, star+1); //add any final text.
|
||||
tx->shader = R_RegisterCustom (altname, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL);
|
||||
//remap to avoid bugging out on textures with the same name and different images (vanilla content sucks)
|
||||
shadername = Mod_RemapBuggyTexture(shadername, tx->mips[0], tx->width*tx->height);
|
||||
if (shadername)
|
||||
origname = tx->name;
|
||||
else
|
||||
shadername = tx->name;
|
||||
|
||||
//find the *
|
||||
if (!*gl_shadeq1_name.string || !strcmp(gl_shadeq1_name.string, "*"))
|
||||
;
|
||||
else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit.
|
||||
shadername = gl_shadeq1_name.string;
|
||||
else
|
||||
{
|
||||
strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left
|
||||
altname[star-gl_shadeq1_name.string] = '\0';
|
||||
strcat(altname, shadername); //insert the *
|
||||
strcat(altname, star+1); //add any final text.
|
||||
shadername = altname;
|
||||
}
|
||||
|
||||
tx->shader = R_RegisterCustom (shadername, SUF_LIGHTMAP, Shader_DefaultBSPQ1, NULL);
|
||||
}
|
||||
|
||||
if (!strncmp(tx->name, "sky", 3))
|
||||
R_InitSky (&tx->shader->defaulttextures, tx, tx->mips[0]);
|
||||
R_InitSky (&tx->shader->defaulttextures, shadername, tx->mips[0], tx->width, tx->height);
|
||||
else
|
||||
{
|
||||
unsigned int maps = 0;
|
||||
|
@ -1216,53 +1285,42 @@ void Mod_FinishTexture(texture_t *tx, const char *loadname)
|
|||
maps |= SHADER_HASNORMALMAP;
|
||||
if (gl_specular.ival)
|
||||
maps |= SHADER_HASGLOSS;
|
||||
R_BuildLegacyTexnums(tx->shader, loadname, maps, ((*tx->name=='{')?TF_TRANS8:TF_SOLID8), tx->width, tx->height, tx->mips, host_basepal);
|
||||
R_BuildLegacyTexnums(tx->shader, origname, loadname, maps, ((*tx->name=='{')?TF_TRANS8:TF_MIP4_SOLID8), tx->width, tx->height, tx->mips, tx->palette);
|
||||
}
|
||||
BZ_Free(tx->mips[0]);
|
||||
#endif
|
||||
}
|
||||
#ifndef SERVERONLY
|
||||
static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
qbyte *base;
|
||||
qboolean alphaed;
|
||||
int pixels = mt->width*mt->height/64*85;
|
||||
|
||||
|
||||
base = (qbyte *)(mt+1);
|
||||
unsigned int size =
|
||||
(mt->width>>0)*(mt->height>>0) +
|
||||
(mt->width>>1)*(mt->height>>1) +
|
||||
(mt->width>>2)*(mt->height>>2) +
|
||||
(mt->width>>3)*(mt->height>>3);
|
||||
|
||||
if (loadmodel->fromgame == fg_halflife)
|
||||
{//external textures have already been filtered.
|
||||
|
||||
//size is not directly known.
|
||||
//we might be able to infer based upon neighbours, but that seems like too much hassle
|
||||
base = W_ConvertWAD3Texture(mt, 0xffffffff, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit.
|
||||
// tx->texnums.base = R_LoadReplacementTexture(mt->name, loadname, alphaed?0:IF_NOALPHA, base, tx->width, tx->height, alphaed?TF_RGBA32:TF_RGBX32);
|
||||
BZ_Free(base);
|
||||
{ //mostly identical, just a specific palette hidden at the end. handle fences elsewhere.
|
||||
tx->mips[0] = BZ_Malloc(size + 768);
|
||||
tx->palette = tx->mips[0] + size;
|
||||
memcpy(tx->palette, (qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3) + 2, 768);
|
||||
}
|
||||
else
|
||||
{
|
||||
qbyte *mipbase;
|
||||
unsigned int mipwidth, mipheight;
|
||||
extern cvar_t gl_miptexLevel;
|
||||
if ((unsigned int)gl_miptexLevel.ival < 4 && mt->offsets[gl_miptexLevel.ival])
|
||||
{
|
||||
mipbase = (qbyte*)mt + mt->offsets[gl_miptexLevel.ival];
|
||||
mipwidth = tx->width>>gl_miptexLevel.ival;
|
||||
mipheight = tx->height>>gl_miptexLevel.ival;
|
||||
}
|
||||
else
|
||||
{
|
||||
mipbase = base;
|
||||
mipwidth = tx->width;
|
||||
mipheight = tx->height;
|
||||
}
|
||||
|
||||
tx->mips[0] = BZ_Malloc(mipwidth*mipheight);
|
||||
memcpy(tx->mips[0], mipbase, mipwidth*mipheight);
|
||||
tx->mips[0] = BZ_Malloc(size);
|
||||
tx->palette = host_basepal;
|
||||
}
|
||||
#endif
|
||||
|
||||
tx->mips[1] = tx->mips[0] + (mt->width>>0)*(mt->height>>0);
|
||||
tx->mips[2] = tx->mips[1] + (mt->width>>1)*(mt->height>>1);
|
||||
tx->mips[3] = tx->mips[2] + (mt->width>>2)*(mt->height>>2);
|
||||
memcpy(tx->mips[0], (qbyte *)mt + mt->offsets[0], (mt->width>>0)*(mt->height>>0));
|
||||
memcpy(tx->mips[1], (qbyte *)mt + mt->offsets[1], (mt->width>>1)*(mt->height>>1));
|
||||
memcpy(tx->mips[2], (qbyte *)mt + mt->offsets[2], (mt->width>>2)*(mt->height>>2));
|
||||
memcpy(tx->mips[3], (qbyte *)mt + mt->offsets[3], (mt->width>>3)*(mt->height>>3));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -1346,7 +1404,9 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
Mod_LoadMiptex(loadmodel, tx, mt);
|
||||
#endif
|
||||
}
|
||||
//
|
||||
// sequence the animations
|
||||
|
@ -1562,6 +1622,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
{ //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous.
|
||||
char luxname[MAX_QPATH];
|
||||
size_t luxsz = 0;
|
||||
*luxname = 0;
|
||||
if (!luxdata)
|
||||
{
|
||||
Q_strncpyz(luxname, loadmodel->name, sizeof(luxname));
|
||||
|
@ -1586,6 +1647,12 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
luxdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, luxname, &luxsz);
|
||||
luxtmp = false;
|
||||
}
|
||||
//make sure the .lux has the correct size
|
||||
if (luxdata && l->filelen && l->filelen != (luxsz-8)/3)
|
||||
{
|
||||
Con_Printf("deluxmap \"%s\" doesn't match level. Ignored.\n", luxname);
|
||||
luxdata=NULL;
|
||||
}
|
||||
if (!luxdata)
|
||||
{
|
||||
int size;
|
||||
|
@ -1594,20 +1661,12 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
luxdata = NULL;
|
||||
luxtmp = true;
|
||||
}
|
||||
else if (luxdata)
|
||||
else
|
||||
{
|
||||
if (l->filelen && l->filelen != (luxsz-8)/3)
|
||||
{
|
||||
Con_Printf("deluxmap \"%s\" doesn't match level. Ignored.\n", luxname);
|
||||
luxdata=NULL;
|
||||
}
|
||||
else if (luxdata[0] == 'Q' && luxdata[1] == 'L' && luxdata[2] == 'I' && luxdata[3] == 'T')
|
||||
if (luxdata[0] == 'Q' && luxdata[1] == 'L' && luxdata[2] == 'I' && luxdata[3] == 'T')
|
||||
{
|
||||
if (LittleLong(*(int *)&luxdata[4]) == 1)
|
||||
{
|
||||
luxdata+=8;
|
||||
loadmodel->deluxdata = luxdata;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("\"%s\" isn't a version 1 deluxmap\n", luxname);
|
||||
|
@ -1647,23 +1706,17 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
if (depthmaps <= depthlits)
|
||||
litname = litnamemaps; //maps has priority over lits
|
||||
else
|
||||
{
|
||||
litname = litnamelits;
|
||||
}
|
||||
|
||||
litdata = FS_LoadMallocGroupFile(&loadmodel->memgroup, litname, &litsize);
|
||||
littmp = false;
|
||||
if (!litdata)
|
||||
{
|
||||
int size;
|
||||
litdata = Q1BSPX_FindLump("RGBLIGHTING", &size);
|
||||
if (size != samples*3)
|
||||
if (litdata)
|
||||
{ //validate it, if we loaded one.
|
||||
if (litdata[0] != 'Q' || litdata[1] != 'L' || litdata[2] != 'I' || litdata[3] != 'T')
|
||||
{
|
||||
litdata = NULL;
|
||||
littmp = true;
|
||||
}
|
||||
else if (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T')
|
||||
{
|
||||
if (LittleLong(*(int *)&litdata[4]) == 1 && l->filelen && samples*3 != (litsize-8))
|
||||
Con_Printf("lit \"%s\" isn't a lit\n", litname);
|
||||
}
|
||||
else if (LittleLong(*(int *)&litdata[4]) == 1 && l->filelen && samples*3 != (litsize-8))
|
||||
{
|
||||
litdata = NULL;
|
||||
Con_Printf("lit \"%s\" doesn't match level. Ignored.\n", litname);
|
||||
|
@ -1673,7 +1726,20 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
Con_Printf("lit \"%s\" isn't version 1.\n", litname);
|
||||
litdata = NULL;
|
||||
}
|
||||
else if (lumdata)
|
||||
}
|
||||
|
||||
littmp = false;
|
||||
if (!litdata)
|
||||
{
|
||||
int size;
|
||||
litdata = Q1BSPX_FindLump("RGBLIGHTING", &size);
|
||||
if (size != samples*3)
|
||||
litdata = NULL;
|
||||
littmp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lumdata)
|
||||
{
|
||||
float prop;
|
||||
int i;
|
||||
|
@ -1711,13 +1777,6 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
|||
//end anti-cheat
|
||||
}
|
||||
}
|
||||
else if (litdata)
|
||||
{
|
||||
Con_Printf("lit \"%s\" isn't a lit\n", litname);
|
||||
litdata = NULL;
|
||||
}
|
||||
// else
|
||||
//failed to find
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1850,7 +1909,7 @@ char *Mod_ParseWorldspawnKey(const char *ents, const char *key, char *buffer, si
|
|||
{
|
||||
char keyname[64];
|
||||
char value[1024];
|
||||
while(*ents)
|
||||
while(ents && *ents)
|
||||
{
|
||||
ents = COM_ParseOut(ents, keyname, sizeof(keyname));
|
||||
if (*keyname == '{') //an entity
|
||||
|
@ -2731,28 +2790,20 @@ static void Mod_Batches_Generate(model_t *mod)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int allocated[LMBLOCK_SIZE_MAX];
|
||||
int lmnum;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
qboolean deluxe;
|
||||
} lmalloc_t;
|
||||
#define LM_FIRST 0x50
|
||||
static void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height)
|
||||
void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm)
|
||||
{
|
||||
memset(lmallocator, 0, sizeof(*lmallocator));
|
||||
lmallocator->deluxe = hasdeluxe;
|
||||
lmallocator->lmnum = LM_FIRST;
|
||||
lmallocator->lmnum = firstlm;
|
||||
lmallocator->firstlm = firstlm;
|
||||
|
||||
lmallocator->width = width;
|
||||
lmallocator->height = height;
|
||||
}
|
||||
static void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod)
|
||||
void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod)
|
||||
{
|
||||
mod->lightmaps.first = LM_FIRST;
|
||||
mod->lightmaps.count = (lmallocator->lmnum - LM_FIRST);
|
||||
mod->lightmaps.first = lmallocator->firstlm;
|
||||
mod->lightmaps.count = (lmallocator->lmnum - lmallocator->firstlm);
|
||||
if (lmallocator->allocated[0])
|
||||
mod->lightmaps.count++;
|
||||
|
||||
|
@ -2765,7 +2816,7 @@ static void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod)
|
|||
else
|
||||
mod->lightmaps.deluxemapping = false;
|
||||
}
|
||||
static void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum)
|
||||
void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum)
|
||||
{
|
||||
int best, best2;
|
||||
int i, j;
|
||||
|
@ -2920,6 +2971,8 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
|
|||
}
|
||||
samps /= 4;
|
||||
samps = sqrt(samps);
|
||||
if (j > 128)
|
||||
samps *= 2;
|
||||
mod->lightmaps.width = bound(j, samps, LMBLOCK_SIZE_MAX);
|
||||
mod->lightmaps.height = bound(j, samps, LMBLOCK_SIZE_MAX);
|
||||
for (i = 0; (1<<i) < mod->lightmaps.width; i++);
|
||||
|
@ -2929,7 +2982,7 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
|
|||
mod->lightmaps.width = bound(64, mod->lightmaps.width, sh_config.texture_maxsize);
|
||||
mod->lightmaps.height = bound(64, mod->lightmaps.height, sh_config.texture_maxsize);
|
||||
|
||||
Mod_LightmapAllocInit(&lmallocator, mod->deluxdata != NULL, mod->lightmaps.width, mod->lightmaps.height);
|
||||
Mod_LightmapAllocInit(&lmallocator, mod->deluxdata != NULL, mod->lightmaps.width, mod->lightmaps.height, 0x50);
|
||||
|
||||
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
|
||||
for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
|
||||
|
@ -2982,7 +3035,7 @@ static void Mod_Batches_AllocLightmaps(model_t *mod)
|
|||
|
||||
extern void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift);
|
||||
//if build is NULL, uses q1/q2 surf generation, and allocates lightmaps
|
||||
void Mod_Batches_Build(model_t *mod, builddata_t *bd)
|
||||
static void Mod_Batches_Build(model_t *mod, builddata_t *bd)
|
||||
{
|
||||
int i;
|
||||
int numverts = 0, numindicies=0;
|
||||
|
@ -4099,6 +4152,7 @@ void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b)
|
|||
{
|
||||
#ifndef SERVERONLY
|
||||
model_t *mod = ctx;
|
||||
char loadname[MAX_QPATH];
|
||||
|
||||
if (!a)
|
||||
{ //submodels share textures, so only do this if 'a' is 0 (inline index, 0 = world).
|
||||
|
@ -4128,15 +4182,26 @@ void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b)
|
|||
}
|
||||
else if (mod->fromgame == fg_quake2)
|
||||
{
|
||||
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
||||
for(a = 0; a < mod->numtextures; a++)
|
||||
{
|
||||
unsigned int maps = 0;
|
||||
mod->textures[a]->shader = R_RegisterCustom (mod->textures[a]->name, SUF_LIGHTMAP, Shader_DefaultBSPQ2, NULL);
|
||||
R_BuildDefaultTexnums(NULL, mod->textures[a]->shader);
|
||||
|
||||
maps |= SHADER_HASPALETTED;
|
||||
maps |= SHADER_HASDIFFUSE;
|
||||
if (r_fb_bmodels.ival)
|
||||
maps |= SHADER_HASFULLBRIGHT;
|
||||
// if (r_loadbumpmapping || (r_waterstyle.ival > 1 && *tx->name == '*'))
|
||||
// maps |= SHADER_HASNORMALMAP;
|
||||
if (gl_specular.ival)
|
||||
maps |= SHADER_HASGLOSS;
|
||||
R_BuildLegacyTexnums(mod->textures[a]->shader, mod->textures[a]->name, loadname, maps, TF_MIP4_SOLID8, mod->textures[a]->width, mod->textures[a]->height, mod->textures[a]->mips, mod->textures[a]->palette);
|
||||
BZ_Free(mod->textures[a]->mips[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char loadname[MAX_QPATH];
|
||||
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
||||
if (!strncmp(loadname, "b_", 2))
|
||||
Q_strncpyz(loadname, "bmodels", sizeof(loadname));
|
||||
|
@ -4168,11 +4233,14 @@ static void Mod_FindVisPatch(struct vispatch_s *patch, model_t *mod, size_t leaf
|
|||
int *lenptr, len;
|
||||
int ofs;
|
||||
qbyte *file;
|
||||
char *mapname;
|
||||
memset(patch, 0, sizeof(*patch));
|
||||
|
||||
if (!mod_external_vis.ival)
|
||||
return;
|
||||
|
||||
mapname = COM_SkipPath(mod->name);
|
||||
|
||||
COM_StripExtension(mod->name, patchname, sizeof(patchname));
|
||||
Q_strncatz(patchname, ".vis", sizeof(patchname));
|
||||
|
||||
|
@ -4184,6 +4252,7 @@ static void Mod_FindVisPatch(struct vispatch_s *patch, model_t *mod, size_t leaf
|
|||
patch->filelen = FS_LoadFile(patchname, &patch->fileptr);
|
||||
if (!patch->fileptr)
|
||||
return;
|
||||
|
||||
ofs = 0;
|
||||
while (ofs+36 <= patch->filelen)
|
||||
{
|
||||
|
@ -4198,7 +4267,7 @@ static void Mod_FindVisPatch(struct vispatch_s *patch, model_t *mod, size_t leaf
|
|||
if (ofs+36+len > patch->filelen)
|
||||
break;
|
||||
|
||||
// if (!Q_strcasecmp(patchname, "foo"))
|
||||
if (!Q_strcasecmp(patchname, mapname))
|
||||
{
|
||||
lenptr = (int*)file;
|
||||
patch->vislen = LittleLong(*lenptr);
|
||||
|
@ -4214,10 +4283,11 @@ static void Mod_FindVisPatch(struct vispatch_s *patch, model_t *mod, size_t leaf
|
|||
|
||||
if (sizeof(int)*2 + patch->vislen + patch->leaflen != len || patch->leaflen != leaflumpsize)
|
||||
{
|
||||
Con_Printf("Vis patch is unsuitable\n");
|
||||
patch->visptr = NULL;
|
||||
patch->leafptr = NULL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
ofs += 36+len;
|
||||
}
|
||||
|
@ -4494,7 +4564,10 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
|
|||
#ifdef RUNTIMELIGHTING
|
||||
TRACE(("LoadBrushModel %i\n", __LINE__));
|
||||
if (lightmodel == mod)
|
||||
LightLoadEntities(lightmodel->entities);
|
||||
{
|
||||
lightcontext = LightStartup(NULL, lightmodel, true);
|
||||
LightReloadEntities(lightcontext, lightmodel->entities);
|
||||
}
|
||||
#endif
|
||||
TRACE(("LoadBrushModel %i\n", __LINE__));
|
||||
if (!isDedicated)
|
||||
|
|
|
@ -51,7 +51,11 @@ typedef enum {
|
|||
} shadersort_t;
|
||||
|
||||
#define MAX_BONES 256
|
||||
#ifdef FTE_TARGET_WEB
|
||||
#define MAX_GPU_BONES 32 //ATI drivers bug out and start to crash if you put this at 128. FIXME: make dynamic.
|
||||
#else
|
||||
#define MAX_GPU_BONES 64 //ATI drivers bug out and start to crash if you put this at 128. FIXME: make dynamic.
|
||||
#endif
|
||||
struct doll_s;
|
||||
void rag_flushdolls(qboolean force);
|
||||
void rag_freedoll(struct doll_s *doll);
|
||||
|
@ -292,6 +296,7 @@ typedef struct texture_s
|
|||
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
|
||||
|
||||
qbyte *mips[4]; //the different mipmap levels.
|
||||
qbyte *palette; //host_basepal or halflife per-texture palette
|
||||
} texture_t;
|
||||
/*
|
||||
typedef struct
|
||||
|
@ -999,6 +1004,9 @@ unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org)
|
|||
struct fragmentdecal_s;
|
||||
void Terrain_ClipDecal(struct fragmentdecal_s *dec, float *center, float radius, model_t *model);
|
||||
qboolean Terr_DownloadedSection(char *fname);
|
||||
|
||||
void CL_Parse_BrushEdit(void);
|
||||
qboolean SV_Parse_BrushEdit(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ void R_NetGraph (void)
|
|||
int lost;
|
||||
char st[80];
|
||||
unsigned ngraph_pixels[NET_GRAPHHEIGHT][NET_TIMINGS];
|
||||
float pi, po, bi, bo;
|
||||
|
||||
x = 0;
|
||||
if (r_netgraph.value < 0)
|
||||
|
@ -130,15 +131,22 @@ void R_NetGraph (void)
|
|||
|
||||
x = ((vid.width - 320)>>1);
|
||||
x=-x;
|
||||
y = vid.height - sb_lines - 24 - NET_GRAPHHEIGHT - 1;
|
||||
y = vid.height - sb_lines - 24 - NET_GRAPHHEIGHT - 2*8;
|
||||
|
||||
M_DrawTextBox (x, y, NET_TIMINGS/8, NET_GRAPHHEIGHT/8 + 1);
|
||||
M_DrawTextBox (x, y, NET_TIMINGS/8, NET_GRAPHHEIGHT/8 + 3);
|
||||
y += 8;
|
||||
|
||||
sprintf(st, "%3i%% packet loss", lost);
|
||||
Draw_FunString(8, y, st);
|
||||
y += 8;
|
||||
|
||||
if (NET_GetRates(cls.sockets, &pi, &po, &bi, &bo))
|
||||
{
|
||||
Draw_FunString(8, y+0, va("in: %g %g\n", pi, bi)); //not relevent as a limit.
|
||||
Draw_FunString(8, y+8, va("out: %g %g\n", po, bo)); //not relevent as a limit.
|
||||
}
|
||||
y += 16;
|
||||
|
||||
Image_Upload(netgraphtexture, TF_RGBA32, ngraph_pixels, NULL, NET_TIMINGS, NET_GRAPHHEIGHT, IF_UIPIC|IF_NOMIPMAP|IF_NOPICMIP);
|
||||
x=8;
|
||||
R2D_Image(x, y, NET_TIMINGS, NET_GRAPHHEIGHT, 0, 0, 1, 1, netgraphshader);
|
||||
|
|
|
@ -59,6 +59,9 @@ void R_AnimateLight (void)
|
|||
{
|
||||
int i,j;
|
||||
float f;
|
||||
|
||||
//if (r_lightstylescale.value > 2)
|
||||
//r_lightstylescale.value = 2;
|
||||
|
||||
//
|
||||
// light animations
|
||||
|
@ -74,13 +77,13 @@ void R_AnimateLight (void)
|
|||
int v1, v2, vd;
|
||||
if (!cl_lightstyle[j].length)
|
||||
{
|
||||
d_lightstylevalue[j] = ('m'-'a')*22;
|
||||
d_lightstylevalue[j] = ('m'-'a')*22 * r_lightstylescale.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cl_lightstyle[j].map[0] == '=')
|
||||
{
|
||||
d_lightstylevalue[j] = atof(cl_lightstyle[j].map+1)*256;
|
||||
d_lightstylevalue[j] = atof(cl_lightstyle[j].map+1)*256*r_lightstylescale.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -92,9 +95,9 @@ void R_AnimateLight (void)
|
|||
|
||||
vd = v1 - v2;
|
||||
if (!r_lightstylesmooth.ival || vd < -r_lightstylesmooth_limit.ival || vd > r_lightstylesmooth_limit.ival)
|
||||
d_lightstylevalue[j] = v1*22;
|
||||
d_lightstylevalue[j] = v1*22*r_lightstylescale.value;
|
||||
else
|
||||
d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22;
|
||||
d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22*r_lightstylescale.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -870,6 +870,9 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
|
|||
if (r_refdef.recurse >= R_MAX_RECURSE-1)
|
||||
return;
|
||||
|
||||
if (!mesh->xyz_array)
|
||||
return;
|
||||
|
||||
if (!mesh->normals_array)
|
||||
{
|
||||
VectorSet(plane.normal, 0, 0, 1);
|
||||
|
|
|
@ -446,7 +446,6 @@ extern cvar_t r_stains, r_stainfadetime, r_stainfadeammount;
|
|||
extern cvar_t gl_font;
|
||||
extern cvar_t vid_conautoscale, vid_conheight, vid_conwidth;
|
||||
extern cvar_t crosshair, crosshairimage, crosshaircolor, r_skyboxname;
|
||||
extern cvar_t r_floorcolour, r_wallcolour, r_floortexture, r_walltexture;
|
||||
extern cvar_t r_fastskycolour;
|
||||
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue);
|
||||
|
||||
|
@ -460,12 +459,9 @@ void GLR_DeInit (void)
|
|||
Cvar_Unhook(&vid_conautoscale);
|
||||
Cvar_Unhook(&vid_conheight);
|
||||
Cvar_Unhook(&vid_conwidth);
|
||||
Cvar_Unhook(&r_walltexture);
|
||||
Cvar_Unhook(&r_floortexture);
|
||||
Cvar_Unhook(&r_drawflat);
|
||||
Cvar_Unhook(&v_gamma);
|
||||
Cvar_Unhook(&v_contrast);
|
||||
Cvar_Unhook(&v_brightness);
|
||||
// Cvar_Unhook(&v_gamma);
|
||||
// Cvar_Unhook(&v_contrast);
|
||||
// Cvar_Unhook(&v_brightness);
|
||||
|
||||
Surf_DeInit();
|
||||
|
||||
|
@ -478,10 +474,6 @@ void GLR_Init (void)
|
|||
|
||||
// Cmd_AddCommand ("makewad", R_MakeTexWad_f);
|
||||
|
||||
// Cvar_Hook(&r_floortexture, GLR_Floortexture_Callback);
|
||||
// Cvar_Hook(&r_walltexture, GLR_Walltexture_Callback);
|
||||
// Cvar_Hook(&r_drawflat, GLR_Drawflat_Callback);
|
||||
|
||||
GLR_ReInit();
|
||||
}
|
||||
|
||||
|
|
|
@ -657,10 +657,18 @@ static int Shader_SetImageFlags(shader_t *shader, shaderpass_t *pass, char **nam
|
|||
|
||||
texid_t R_LoadColourmapImage(void)
|
||||
{
|
||||
unsigned int w = 256, h = VID_GRADES-1;
|
||||
unsigned int w = 256, h = VID_GRADES;
|
||||
unsigned int x;
|
||||
unsigned int data[256*(VID_GRADES-1)];
|
||||
unsigned int data[256*(VID_GRADES)];
|
||||
qbyte *colourmappal = (qbyte *)FS_LoadMallocFile ("gfx/colormap.lmp", NULL);
|
||||
if (!colourmappal)
|
||||
{
|
||||
size_t sz;
|
||||
qbyte *pcx = FS_LoadMallocFile("pics/colormap.pcx", &sz);
|
||||
colourmappal = Z_Malloc(256*VID_GRADES);
|
||||
ReadPCXData(pcx, sz, 256, VID_GRADES, colourmappal);
|
||||
BZ_Free(pcx);
|
||||
}
|
||||
if (colourmappal)
|
||||
{
|
||||
for (x = 0; x < sizeof(data)/sizeof(data[0]); x++)
|
||||
|
@ -726,6 +734,12 @@ static void Shader_NoMipMaps ( shader_t *shader, shaderpass_t *pass, char **ptr
|
|||
shader->flags |= (SHADER_NOMIPMAPS|SHADER_NOPICMIP);
|
||||
}
|
||||
|
||||
static void Shader_Affine ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
||||
{
|
||||
shader->flags |= SBITS_AFFINE;
|
||||
}
|
||||
|
||||
|
||||
static void Shader_NoPicMip ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
||||
{
|
||||
shader->flags |= SHADER_NOPICMIP;
|
||||
|
@ -2056,6 +2070,7 @@ static shaderkey_t shaderkeys[] =
|
|||
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d
|
||||
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d
|
||||
{"param", Shader_ProgramParam, "fte"}, //legacy
|
||||
{"affine", Shader_Affine, "fte"}, //some hardware is horribly slow, and can benefit from certain hints.
|
||||
|
||||
{"bemode", Shader_BEMode, "fte"},
|
||||
|
||||
|
@ -4134,6 +4149,7 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
char *h;
|
||||
char imagename[MAX_QPATH];
|
||||
char *subpath = NULL;
|
||||
unsigned int imageflags = 0;
|
||||
strcpy(imagename, shader->name);
|
||||
h = strchr(imagename, '#');
|
||||
if (h)
|
||||
|
@ -4172,6 +4188,8 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
TEXASSIGN(shader->defaulttextures.paletted, tn->paletted);
|
||||
}
|
||||
|
||||
imageflags |= IF_LOWPRIORITY;
|
||||
|
||||
COM_StripExtension(imagename, imagename, sizeof(imagename));
|
||||
|
||||
if (!TEXVALID(shader->defaulttextures.bump))
|
||||
|
@ -4179,9 +4197,9 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
if (r_loadbumpmapping || (shader->flags & SHADER_HASNORMALMAP))
|
||||
{
|
||||
if (!TEXVALID(tn->bump) && *shader->mapname && (shader->flags & SHADER_HASNORMALMAP))
|
||||
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->mapname), NULL, IF_TRYBUMP);
|
||||
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->mapname), NULL, imageflags|IF_TRYBUMP);
|
||||
if (!TEXVALID(tn->bump))
|
||||
tn->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, IF_TRYBUMP);
|
||||
tn->bump = R_LoadHiResTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP);
|
||||
}
|
||||
TEXASSIGN(shader->defaulttextures.bump, tn->bump);
|
||||
}
|
||||
|
@ -4191,9 +4209,9 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
if (shader->flags & SHADER_HASTOPBOTTOM)
|
||||
{
|
||||
if (!TEXVALID(tn->loweroverlay) && *shader->mapname)
|
||||
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->mapname), NULL, 0);
|
||||
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->mapname), NULL, imageflags);
|
||||
if (!TEXVALID(tn->loweroverlay))
|
||||
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", imagename), subpath, 0); /*how rude*/
|
||||
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", imagename), subpath, imageflags); /*how rude*/
|
||||
}
|
||||
TEXASSIGN(shader->defaulttextures.loweroverlay, tn->loweroverlay);
|
||||
}
|
||||
|
@ -4203,9 +4221,9 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
if (shader->flags & SHADER_HASTOPBOTTOM)
|
||||
{
|
||||
if (!TEXVALID(tn->upperoverlay) && *shader->mapname)
|
||||
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->mapname), NULL, 0);
|
||||
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->mapname), NULL, imageflags);
|
||||
if (!TEXVALID(tn->upperoverlay))
|
||||
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", imagename), subpath, 0);
|
||||
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", imagename), subpath, imageflags);
|
||||
}
|
||||
TEXASSIGN(shader->defaulttextures.upperoverlay, tn->upperoverlay);
|
||||
}
|
||||
|
@ -4216,9 +4234,9 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
if ((shader->flags & SHADER_HASGLOSS) && gl_specular.value && gl_load24bit.value)
|
||||
{
|
||||
if (!TEXVALID(tn->specular) && *shader->mapname)
|
||||
tn->specular = R_LoadHiResTexture(va("%s_gloss", shader->mapname), NULL, 0);
|
||||
tn->specular = R_LoadHiResTexture(va("%s_gloss", shader->mapname), NULL, imageflags);
|
||||
if (!TEXVALID(tn->specular))
|
||||
tn->specular = R_LoadHiResTexture(va("%s_gloss", imagename), subpath, 0);
|
||||
tn->specular = R_LoadHiResTexture(va("%s_gloss", imagename), subpath, imageflags);
|
||||
}
|
||||
TEXASSIGN(shader->defaulttextures.specular, tn->specular);
|
||||
}
|
||||
|
@ -4229,24 +4247,37 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
|||
if ((shader->flags & SHADER_HASFULLBRIGHT) && r_fb_bmodels.value && gl_load24bit.value)
|
||||
{
|
||||
if (!TEXVALID(tn->fullbright) && *shader->mapname)
|
||||
tn->fullbright = R_LoadHiResTexture(va("%s_luma", shader->mapname), NULL, 0);
|
||||
tn->fullbright = R_LoadHiResTexture(va("%s_luma", shader->mapname), NULL, imageflags);
|
||||
if (!TEXVALID(tn->fullbright))
|
||||
tn->fullbright = R_LoadHiResTexture(va("%s_luma", imagename), subpath, 0);
|
||||
tn->fullbright = R_LoadHiResTexture(va("%s_luma", imagename), subpath, imageflags);
|
||||
}
|
||||
TEXASSIGN(shader->defaulttextures.fullbright, tn->fullbright);
|
||||
}
|
||||
}
|
||||
|
||||
//call this with some fallback textures to directly load some textures
|
||||
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette)
|
||||
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette)
|
||||
{
|
||||
char *h;
|
||||
char imagename[MAX_QPATH];
|
||||
//extern cvar_t gl_miptexLevel;
|
||||
texnums_t *tex = &shader->defaulttextures;
|
||||
unsigned int imageflags;
|
||||
qbyte *dontcrashme[4] = {NULL};
|
||||
if (!mipdata)
|
||||
mipdata = dontcrashme;
|
||||
/*else if (gl_miptexLevel.ival)
|
||||
{
|
||||
unsigned int miplevel = 0, i;
|
||||
for (i = 0; i < 3 && i < gl_miptexLevel.ival && mipdata[i]; i++)
|
||||
miplevel = i;
|
||||
for (i = 0; i < 3; i++)
|
||||
dontcrashme[i] = (miplevel+i)>3?NULL:mipdata[miplevel+i];
|
||||
width >>= miplevel;
|
||||
height >>= miplevel;
|
||||
mipdata = dontcrashme;
|
||||
}
|
||||
*/
|
||||
strcpy(imagename, shader->name);
|
||||
h = strchr(imagename, '#');
|
||||
if (h)
|
||||
|
@ -4263,8 +4294,11 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned
|
|||
if (shader->generator == Shader_DefaultSkin)
|
||||
subpath = shader->genargs;
|
||||
|
||||
if (basefmt == TF_MIP4_SOLID8 && (!mipdata[0] || !mipdata[1] || !mipdata[2] || !mipdata[3]))
|
||||
basefmt = TF_SOLID8;
|
||||
|
||||
//make sure the noalpha thing is set properly.
|
||||
imageflags = (basefmt==TF_SOLID8)?IF_NOALPHA:0;
|
||||
imageflags = (basefmt==TF_SOLID8 || basefmt == TF_MIP4_SOLID8)?IF_NOALPHA:0;
|
||||
imageflags |= IF_MIPCAP;
|
||||
|
||||
COM_StripExtension(imagename, imagename, sizeof(imagename));
|
||||
|
@ -4274,7 +4308,22 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned
|
|||
{
|
||||
if (!TEXVALID(tex->base) && *shader->mapname)
|
||||
tex->base = R_LoadHiResTexture(shader->mapname, NULL, imageflags);
|
||||
if (!TEXVALID(tex->base))
|
||||
if (!TEXVALID(tex->base) && fallbackname)
|
||||
{
|
||||
if (gl_load24bit.ival)
|
||||
{
|
||||
tex->base = Image_GetTexture(imagename, subpath, imageflags|IF_NOWORKER, NULL, NULL, width, height, basefmt);
|
||||
if (!TEXLOADED(tex->base))
|
||||
{
|
||||
tex->base = Image_GetTexture(fallbackname, subpath, imageflags|IF_NOWORKER, NULL, NULL, width, height, basefmt);
|
||||
if (TEXLOADED(tex->base))
|
||||
Q_strncpyz(imagename, fallbackname, sizeof(imagename));
|
||||
}
|
||||
}
|
||||
if (!TEXLOADED(tex->base))
|
||||
tex->base = Image_GetTexture(imagename, subpath, imageflags, mipdata[0], palette, width, height, basefmt);
|
||||
}
|
||||
else if (!TEXVALID(tex->base))
|
||||
tex->base = Image_GetTexture(imagename, subpath, imageflags, mipdata[0], palette, width, height, basefmt);
|
||||
}
|
||||
|
||||
|
@ -4283,9 +4332,10 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned
|
|||
if (!TEXVALID(tex->paletted) && *shader->mapname)
|
||||
tex->paletted = R_LoadHiResTexture(va("%s_pal", shader->mapname), NULL, imageflags|IF_NEAREST);
|
||||
if (!TEXVALID(tex->paletted))
|
||||
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST, mipdata[0], palette, width, height, TF_LUM8);
|
||||
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST, mipdata[0], palette, width, height, (basefmt==TF_MIP4_SOLID8)?TF_MIP4_LUM8:TF_LUM8);
|
||||
}
|
||||
|
||||
imageflags |= IF_LOWPRIORITY;
|
||||
//all the rest need/want an alpha channel in some form.
|
||||
imageflags &= ~IF_NOALPHA;
|
||||
imageflags |= IF_NOGAMMA;
|
||||
|
@ -4667,6 +4717,7 @@ void Shader_DefaultBSPQ2(const char *shortname, shader_t *s, const void *args)
|
|||
Shader_DefaultScript(shortname, s, Shader_DefaultBSPWater(s, shortname));
|
||||
}
|
||||
else if (!strncmp(shortname, "trans/", 6))
|
||||
{
|
||||
Shader_DefaultScript(shortname, s,
|
||||
"{\n"
|
||||
"{\n"
|
||||
|
@ -4676,6 +4727,19 @@ void Shader_DefaultBSPQ2(const char *shortname, shader_t *s, const void *args)
|
|||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
else if (r_softwarebanding.ival)
|
||||
{
|
||||
/*alpha bended*/
|
||||
Shader_DefaultScript(shortname, s,
|
||||
"{\n"
|
||||
"program defaultwall#EIGHTBIT\n"
|
||||
"{\n"
|
||||
"map $colourmap\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
else
|
||||
Shader_DefaultBSPLM(shortname, s, args);
|
||||
}
|
||||
|
|
|
@ -3201,13 +3201,17 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
|
|||
"}\n"
|
||||
);
|
||||
|
||||
crepuscular_texture_id = Image_CreateTexture("***crepusculartexture***", NULL, 0);
|
||||
crepuscular_texture_id = Image_CreateTexture("***crepusculartexture***", NULL, IF_LINEAR|IF_NOMIPMAP|IF_CLAMP|IF_NOGAMMA);
|
||||
Image_Upload(crepuscular_texture_id, TF_RGBA32, NULL, NULL, vid.pixelwidth, vid.pixelheight, IF_LINEAR|IF_NOMIPMAP|IF_CLAMP|IF_NOGAMMA);
|
||||
}
|
||||
|
||||
BE_Scissor(NULL);
|
||||
|
||||
oldfbo = GLBE_FBO_Update(&crepuscular_fbo, 0, &crepuscular_texture_id, 1, r_nulltex, vid.pixelwidth, vid.pixelheight);
|
||||
oldfbo = GLBE_FBO_Update(&crepuscular_fbo, FBO_RB_DEPTH, &crepuscular_texture_id, 1, r_nulltex, vid.pixelwidth, vid.pixelheight);
|
||||
|
||||
GL_ForceDepthWritable();
|
||||
// qglClearColor(0, 0, 0, 1);
|
||||
qglClear(GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
BE_SelectMode(BEM_CREPUSCULAR);
|
||||
BE_SelectDLight(dl, colours, dl->axis, LSHADER_STANDARD);
|
||||
|
@ -3217,6 +3221,7 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
|
|||
|
||||
oldsrccol = NULL;//shaderstate.tex_sourcecol;
|
||||
GLBE_FBO_Sources(crepuscular_texture_id, NULL);
|
||||
// crepuscular_shader->defaulttextures.base = crepuscular_texture_id;
|
||||
//shaderstate.tex_sourcecol = oldsrccol;
|
||||
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
|
@ -3448,6 +3453,12 @@ void Sh_DrawLights(qbyte *vis)
|
|||
colour[1] *= cl_lightstyle[dl->style-1].colours[1] * d_lightstylevalue[dl->style-1]/255.0f;
|
||||
colour[2] *= cl_lightstyle[dl->style-1].colours[2] * d_lightstylevalue[dl->style-1]/255.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
colour[0] *= r_lightstylescale.value;
|
||||
colour[1] *= r_lightstylescale.value;
|
||||
colour[2] *= r_lightstylescale.value;
|
||||
}
|
||||
|
||||
if (colour[0] < 0.001 && colour[1] < 0.001 && colour[2] < 0.001)
|
||||
continue; //just switch these off.
|
||||
|
|
|
@ -1062,6 +1062,23 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
qglDebugMessageCallbackARB = (void *)getglext("glDebugMessageCallbackARB");
|
||||
qglGetDebugMessageLogARB = (void *)getglext("glGetDebugMessageLogARB");
|
||||
}
|
||||
else if (GL_CheckExtension("GL_KHR_debug"))
|
||||
{
|
||||
if (gl_config_gles)
|
||||
{
|
||||
qglDebugMessageControlARB = (void *)getglext("glDebugMessageControlKHR");
|
||||
qglDebugMessageInsertARB = (void *)getglext("glDebugMessageInsertKHR");
|
||||
qglDebugMessageCallbackARB = (void *)getglext("glDebugMessageCallbackKHR");
|
||||
qglGetDebugMessageLogARB = (void *)getglext("glGetDebugMessageLogKHR");
|
||||
}
|
||||
else
|
||||
{
|
||||
qglDebugMessageControlARB = (void *)getglext("glDebugMessageControl");
|
||||
qglDebugMessageInsertARB = (void *)getglext("glDebugMessageInsert");
|
||||
qglDebugMessageCallbackARB = (void *)getglext("glDebugMessageCallback");
|
||||
qglGetDebugMessageLogARB = (void *)getglext("glGetDebugMessageLog");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qglDebugMessageControlARB = NULL;
|
||||
|
@ -1640,7 +1657,13 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
|
|||
strings++;
|
||||
if (gl_config.gles)
|
||||
{
|
||||
prstrings[strings] = "precision mediump float;\n";
|
||||
prstrings[strings] =
|
||||
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"precision highp float;\n"
|
||||
"#else\n"
|
||||
"precision mediump float;\n"
|
||||
"#endif\n"
|
||||
;
|
||||
length[strings] = strlen(prstrings[strings]);
|
||||
strings++;
|
||||
}
|
||||
|
@ -2612,13 +2635,22 @@ void DumpGLState(void)
|
|||
|
||||
// if (qglGetVertexAttribiv)
|
||||
{
|
||||
qglGetIntegerv(GL_VERTEX_ARRAY_BINDING, &rval);
|
||||
Sys_Printf("VERTEX_ARRAY_BINDING: %i\n", rval);
|
||||
qglGetIntegerv(GL_ARRAY_BUFFER_BINDING, &rval);
|
||||
Sys_Printf("GL_ARRAY_BUFFER_BINDING: %i\n", rval);
|
||||
if (qglBindVertexArray)
|
||||
{
|
||||
qglGetIntegerv(GL_VERTEX_ARRAY_BINDING, &rval);
|
||||
Sys_Printf("VERTEX_ARRAY_BINDING: %i\n", rval);
|
||||
}
|
||||
if (qglBindBufferARB)
|
||||
{
|
||||
qglGetIntegerv(GL_ARRAY_BUFFER_BINDING, &rval);
|
||||
Sys_Printf("GL_ARRAY_BUFFER_BINDING: %i\n", rval);
|
||||
}
|
||||
if (qglIsEnabled(GL_COLOR_ARRAY))
|
||||
{
|
||||
qglGetIntegerv(GL_COLOR_ARRAY_BUFFER_BINDING, &rval);
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_COLOR_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
qglGetPointerv(GL_COLOR_ARRAY_POINTER, &ptr);
|
||||
Sys_Printf("GL_COLOR_ARRAY: %s %i:%p\n", qglIsEnabled(GL_COLOR_ARRAY)?"en":"dis", rval, ptr);
|
||||
}
|
||||
|
@ -2629,7 +2661,10 @@ void DumpGLState(void)
|
|||
// }
|
||||
// if (qglIsEnabled(GL_INDEX_ARRAY))
|
||||
{
|
||||
qglGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval);
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
#ifndef GL_INDEX_ARRAY_POINTER
|
||||
Sys_Printf("GL_ELEMENT_ARRAY_BUFFER_BINDING: %i:%p\n", rval, (void*)0);
|
||||
#else
|
||||
|
@ -2639,7 +2674,10 @@ void DumpGLState(void)
|
|||
}
|
||||
if (qglIsEnabled(GL_NORMAL_ARRAY))
|
||||
{
|
||||
qglGetIntegerv(GL_NORMAL_ARRAY_BUFFER_BINDING, &rval);
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_NORMAL_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
qglGetPointerv(GL_NORMAL_ARRAY_POINTER, &ptr);
|
||||
Sys_Printf("GL_NORMAL_ARRAY: %s %i:%p\n", qglIsEnabled(GL_NORMAL_ARRAY)?"en":"dis", rval, ptr);
|
||||
}
|
||||
|
@ -2650,14 +2688,20 @@ void DumpGLState(void)
|
|||
qglClientActiveTextureARB(mtexid0 + i);
|
||||
if (qglIsEnabled(GL_TEXTURE_COORD_ARRAY))
|
||||
{
|
||||
qglGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &rval);
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
qglGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &ptr);
|
||||
Sys_Printf("GL_TEXTURE_COORD_ARRAY %i: %s %i:%p\n", i, qglIsEnabled(GL_TEXTURE_COORD_ARRAY)?"en":"dis", rval, ptr);
|
||||
}
|
||||
}
|
||||
if (qglIsEnabled(GL_VERTEX_ARRAY))
|
||||
{
|
||||
qglGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &rval);
|
||||
if (qglBindBufferARB)
|
||||
qglGetIntegerv(GL_VERTEX_ARRAY_BUFFER_BINDING, &rval);
|
||||
else
|
||||
rval = 0;
|
||||
qglGetPointerv(GL_VERTEX_ARRAY_POINTER, &ptr);
|
||||
Sys_Printf("GL_VERTEX_ARRAY: %s %i:%p\n", qglIsEnabled(GL_VERTEX_ARRAY)?"en":"dis", rval, ptr);
|
||||
}
|
||||
|
@ -2670,7 +2714,10 @@ void DumpGLState(void)
|
|||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &en);
|
||||
if (!en)
|
||||
continue;
|
||||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &bo);
|
||||
if (qglBindBufferARB)
|
||||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &bo);
|
||||
else
|
||||
bo = 0;
|
||||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &as);
|
||||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &st);
|
||||
qglGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &ty);
|
||||
|
@ -2680,8 +2727,11 @@ void DumpGLState(void)
|
|||
Sys_Printf("attrib%i: %s sz:%i st:%i ty:%0x %s%i:%p\n", i, en?"en":"dis", as, st,ty,no?"norm ":"", bo, ptr);
|
||||
}
|
||||
|
||||
qglGetIntegerv(GL_CURRENT_PROGRAM, &glint);
|
||||
Sys_Printf("GL_CURRENT_PROGRAM: %i\n", glint);
|
||||
if (qglUseProgramObjectARB)
|
||||
{
|
||||
qglGetIntegerv(GL_CURRENT_PROGRAM, &glint);
|
||||
Sys_Printf("GL_CURRENT_PROGRAM: %i\n", glint);
|
||||
}
|
||||
|
||||
qglGetIntegerv(GL_BLEND, &glint);
|
||||
Sys_Printf("GL_BLEND: %i\n", glint);
|
||||
|
|
|
@ -2009,6 +2009,9 @@ void INS_ReInit(void)
|
|||
void INS_Shutdown(void)
|
||||
{
|
||||
}
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
}
|
||||
|
||||
void GLVID_SetCaption(char *text)
|
||||
{
|
||||
|
|
|
@ -205,6 +205,9 @@ void INS_Shutdown (void)
|
|||
void INS_Commands (void)
|
||||
{
|
||||
}
|
||||
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, char *type, char *devicename, int *qdevid))
|
||||
{
|
||||
}
|
||||
void INS_Move (float *movements, int pnum)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -578,7 +578,6 @@ RECT centerrect(unsigned int parentleft, unsigned int parenttop, unsigned int pa
|
|||
return r;
|
||||
}
|
||||
|
||||
void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight);
|
||||
void *WIN_CreateCursor(char *filename, float hotx, float hoty, float scale)
|
||||
{
|
||||
int width, height;
|
||||
|
@ -2157,6 +2156,10 @@ LONG WINAPI GLMainWndProc (
|
|||
INS_TranslateKeyEvent(wParam, lParam, false, 0, false);
|
||||
break;
|
||||
|
||||
case WM_MOUSEACTIVATE:
|
||||
lRet = MA_ACTIVATEANDEAT;
|
||||
break;
|
||||
|
||||
// this is complicated because Win32 seems to pack multiple mouse events into
|
||||
// one update sometimes, so we always check all states and look for events
|
||||
case WM_LBUTTONDOWN:
|
||||
|
|
|
@ -352,6 +352,8 @@ static void R_CalcSkyChainBounds (batch_t *batch)
|
|||
for (m = batch->firstmesh; m < batch->meshes; m++)
|
||||
{
|
||||
mesh = batch->mesh[m];
|
||||
if (!mesh->xyz_array)
|
||||
continue;
|
||||
//triangulate
|
||||
for (i=2 ; i<mesh->numvertexes ; i++)
|
||||
{
|
||||
|
@ -742,7 +744,7 @@ R_InitSky
|
|||
A sky texture is 256*128, with the right side being a masked overlay
|
||||
==============
|
||||
*/
|
||||
void R_InitSky (struct texnums_s *tn, texture_t *mt, qbyte *src)
|
||||
void R_InitSky (struct texnums_s *tn, const char *skyname, qbyte *src, unsigned int width, unsigned int height)
|
||||
{
|
||||
int i, j, p;
|
||||
unsigned trans[128*128];
|
||||
|
@ -751,45 +753,51 @@ void R_InitSky (struct texnums_s *tn, texture_t *mt, qbyte *src)
|
|||
unsigned *rgba;
|
||||
char name[MAX_QPATH];
|
||||
|
||||
unsigned int stride = width;
|
||||
width /= 2;
|
||||
|
||||
memset(tn, 0, sizeof(*tn));
|
||||
|
||||
if (width < 1 || height < 1 || stride != width*2)
|
||||
return;
|
||||
|
||||
// make an average value for the back to avoid
|
||||
// a fringe on the top level
|
||||
|
||||
r = g = b = 0;
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
for (i=0 ; i<height ; i++)
|
||||
for (j=0 ; j<width ; j++)
|
||||
{
|
||||
p = src[i*256 + j + 128];
|
||||
p = src[i*stride + j + width];
|
||||
rgba = &d_8to24rgbtable[p];
|
||||
trans[(i*128) + j] = *rgba;
|
||||
trans[(i*width) + j] = *rgba;
|
||||
r += ((qbyte *)rgba)[0];
|
||||
g += ((qbyte *)rgba)[1];
|
||||
b += ((qbyte *)rgba)[2];
|
||||
}
|
||||
|
||||
Q_snprintfz(name, sizeof(name), "%s_solid", mt->name);
|
||||
Q_snprintfz(name, sizeof(name), "%s_solid", skyname);
|
||||
Q_strlwr(name);
|
||||
tn->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, trans, 128, 128, TF_RGBX32);
|
||||
tn->base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA, trans, width, height, TF_RGBX32);
|
||||
|
||||
((qbyte *)&transpix)[0] = r/(128*128);
|
||||
((qbyte *)&transpix)[1] = g/(128*128);
|
||||
((qbyte *)&transpix)[2] = b/(128*128);
|
||||
((qbyte *)&transpix)[0] = r/(width*height);
|
||||
((qbyte *)&transpix)[1] = g/(width*height);
|
||||
((qbyte *)&transpix)[2] = b/(width*height);
|
||||
((qbyte *)&transpix)[3] = 0;
|
||||
alphamask = LittleLong(0x7fffffff);
|
||||
for (i=0 ; i<128 ; i++)
|
||||
for (j=0 ; j<128 ; j++)
|
||||
for (i=0 ; i<height ; i++)
|
||||
for (j=0 ; j<width ; j++)
|
||||
{
|
||||
p = src[i*256 + j];
|
||||
p = src[i*stride + j];
|
||||
if (p == 0)
|
||||
trans[(i*128) + j] = transpix;
|
||||
trans[(i*width) + j] = transpix;
|
||||
else
|
||||
trans[(i*128) + j] = d_8to24rgbtable[p] & alphamask;
|
||||
trans[(i*width) + j] = d_8to24rgbtable[p] & alphamask;
|
||||
}
|
||||
|
||||
//FIXME: support _trans
|
||||
Q_snprintfz(name, sizeof(name), "%s_alpha", mt->name);
|
||||
Q_snprintfz(name, sizeof(name), "%s_alpha", skyname);
|
||||
Q_strlwr(name);
|
||||
tn->fullbright = R_LoadReplacementTexture(name, NULL, 0, trans, 128, 128, TF_RGBA32);
|
||||
tn->fullbright = R_LoadReplacementTexture(name, NULL, 0, trans, width, height, TF_RGBA32);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -60,6 +60,21 @@ typedef struct builddata_s
|
|||
void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b); //data === builddata_t
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int allocated[LMBLOCK_SIZE_MAX];
|
||||
int firstlm;
|
||||
int lmnum;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
qboolean deluxe;
|
||||
} lmalloc_t;
|
||||
void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm); //firstlm is for debugging stray lightmap indexes
|
||||
void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod);
|
||||
void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum);
|
||||
|
||||
|
||||
|
||||
#ifdef GLQUAKE
|
||||
#if defined(ANDROID) /*FIXME: actually just to use standard GLES headers instead of full GL*/
|
||||
#if 1
|
||||
|
|
|
@ -1,34 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
#ifndef UTILITY
|
||||
|
||||
|
||||
extern model_t *lightmodel;
|
||||
#define bsptexinfo(i) (*i)
|
||||
#define dsurfedges lightmodel->surfedges
|
||||
#define dvertexes lightmodel->vertexes
|
||||
#define dedges lightmodel->edges
|
||||
#define texinfo_t mtexinfo_t
|
||||
#define Q_PI M_PI
|
||||
#define Error Host_Error
|
||||
#define byte qbyte
|
||||
|
||||
#define dfaces lightmodel->surfaces
|
||||
#define dplanes lightmodel->planes
|
||||
#define dface_t msurface_t
|
||||
#define dvertex_t mvertex_t
|
||||
#define point position
|
||||
|
||||
#define side flags & SURF_PLANEBACK
|
||||
|
||||
#define scaledist 1
|
||||
#define rangescale 0.5
|
||||
#define extrasamples 1
|
||||
#define scalecos 0.5
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct mentity_s {
|
||||
vec3_t origin;
|
||||
|
@ -41,11 +13,40 @@ typedef struct mentity_s {
|
|||
char target[64];
|
||||
char targetname[64];
|
||||
|
||||
struct mentity_s *targetent;
|
||||
int targetentnum;
|
||||
} mentity_t;
|
||||
|
||||
static mentity_t entities[8192];
|
||||
static int num_entities;
|
||||
struct relight_ctx_s
|
||||
{
|
||||
unsigned int nummodels;
|
||||
model_t *models[2048];
|
||||
|
||||
qboolean shadows;
|
||||
mentity_t *entities;
|
||||
unsigned int num_entities;
|
||||
unsigned int max_entities;
|
||||
};
|
||||
|
||||
|
||||
#define bsptexinfo(i) (*i)
|
||||
#define dsurfedges lightmodel->surfedges
|
||||
#define dvertexes lightmodel->vertexes
|
||||
#define dedges lightmodel->edges
|
||||
#define texinfo_t mtexinfo_t
|
||||
#define Q_PI M_PI
|
||||
|
||||
#define dfaces lightmodel->surfaces
|
||||
#define dplanes lightmodel->planes
|
||||
#define dface_t msurface_t
|
||||
#define dvertex_t mvertex_t
|
||||
|
||||
#define side flags & SURF_PLANEBACK
|
||||
|
||||
#define scaledist 1
|
||||
#define rangescale 0.5
|
||||
#define extrasamples 0
|
||||
#define scalecos 0.5
|
||||
|
||||
|
||||
#define bsp_origin vec3_origin
|
||||
|
||||
|
@ -56,14 +57,17 @@ CastRay
|
|||
Returns the distance between the points, or -1 if blocked
|
||||
=============
|
||||
*/
|
||||
vec_t CastRay (vec3_t p1, vec3_t p2)
|
||||
static vec_t CastRay (struct relight_ctx_s *ctx, vec3_t p1, vec3_t p2)
|
||||
{
|
||||
trace_t trace;
|
||||
vec3_t move;
|
||||
|
||||
lightmodel->funcs.NativeTrace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &trace);
|
||||
if (trace.fraction < 1)
|
||||
return -1;
|
||||
if (ctx->shadows)
|
||||
{
|
||||
ctx->models[0]->funcs.NativeTrace (ctx->models[0], 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID, &trace);
|
||||
if (trace.fraction < 1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
VectorSubtract(p1, p2, move);
|
||||
return VectorLength(move);
|
||||
|
@ -114,7 +118,33 @@ static void ParseEpair (mentity_t *mapent, char *key, char *value)
|
|||
}
|
||||
}
|
||||
|
||||
void LightLoadEntities(char *entstring)
|
||||
void LightShutdown(struct relight_ctx_s *ctx, model_t *mod)
|
||||
{
|
||||
qboolean stillheld = false;
|
||||
unsigned int i;
|
||||
for (i = 0; i < ctx->nummodels; i++)
|
||||
{
|
||||
if (ctx->models[i] == mod)
|
||||
ctx->models[i] = NULL;
|
||||
if (ctx->models[i])
|
||||
stillheld = true;
|
||||
}
|
||||
if (stillheld)
|
||||
return;
|
||||
Z_Free(ctx->entities);
|
||||
Z_Free(ctx);
|
||||
}
|
||||
struct relight_ctx_s *LightStartup(struct relight_ctx_s *ctx, model_t *model, qboolean shadows)
|
||||
{
|
||||
if (!ctx)
|
||||
{
|
||||
ctx = Z_Malloc(sizeof(*ctx));
|
||||
ctx->shadows = shadows;
|
||||
}
|
||||
ctx->models[ctx->nummodels++] = model;
|
||||
return ctx;
|
||||
}
|
||||
void LightReloadEntities(struct relight_ctx_s *ctx, char *entstring)
|
||||
{
|
||||
#define DEFAULTLIGHTLEVEL 300
|
||||
mentity_t *mapent;
|
||||
|
@ -122,7 +152,7 @@ void LightLoadEntities(char *entstring)
|
|||
char value[1024];
|
||||
int i;
|
||||
int switchedstyle=32;
|
||||
num_entities = 0;
|
||||
ctx->num_entities = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -135,11 +165,18 @@ void LightLoadEntities(char *entstring)
|
|||
break;
|
||||
}
|
||||
|
||||
mapent = &entities[num_entities];
|
||||
if (ctx->num_entities == ctx->max_entities)
|
||||
{
|
||||
ctx->max_entities = ctx->max_entities + 128;
|
||||
ctx->entities = BZ_Realloc(ctx->entities, sizeof(*ctx->entities) * ctx->max_entities);
|
||||
}
|
||||
|
||||
mapent = &ctx->entities[ctx->num_entities];
|
||||
memset(mapent, 0, sizeof(*mapent));
|
||||
mapent->colour[0] = 0;
|
||||
mapent->colour[1] = 0;
|
||||
mapent->colour[2] = 0;
|
||||
mapent->targetentnum = -1;
|
||||
while(1)
|
||||
{
|
||||
entstring = COM_ParseOut(entstring, key, sizeof(key));
|
||||
|
@ -158,7 +195,7 @@ void LightLoadEntities(char *entstring)
|
|||
for (i = 0; i < 256; i+=16)
|
||||
{
|
||||
v[2] = mapent->origin[2]-i;
|
||||
cont = lightmodel->funcs.PointContents (lightmodel, NULL, v);
|
||||
cont = ctx->models[0]->funcs.PointContents (ctx->models[0], NULL, v);
|
||||
if (cont & (FTECONTENTS_LAVA | FTECONTENTS_SLIME | FTECONTENTS_SOLID))
|
||||
break;
|
||||
}
|
||||
|
@ -204,35 +241,35 @@ void LightLoadEntities(char *entstring)
|
|||
|
||||
if (*mapent->targetname && !mapent->style && !strcmp(mapent->classname, "light"))
|
||||
{
|
||||
for (i = 0; i <= num_entities; i++)
|
||||
for (i = 0; i <= ctx->num_entities; i++)
|
||||
{
|
||||
if (entities[i].style >= 32 && !strcmp(entities[i].targetname, mapent->targetname))
|
||||
if (ctx->entities[i].style >= 32 && !strcmp(ctx->entities[i].targetname, mapent->targetname))
|
||||
{
|
||||
mapent->style = entities[i].style;
|
||||
mapent->style = ctx->entities[i].style;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == num_entities)
|
||||
if (i == ctx->num_entities)
|
||||
mapent->style = switchedstyle++;
|
||||
}
|
||||
|
||||
|
||||
num_entities++;
|
||||
ctx->num_entities++;
|
||||
}
|
||||
|
||||
for (mapent = entities; mapent < &entities[num_entities]; mapent++)
|
||||
for (mapent = ctx->entities; mapent < &ctx->entities[ctx->num_entities]; mapent++)
|
||||
{
|
||||
if (*mapent->target)
|
||||
{
|
||||
for (i = 0; i < num_entities; i++)
|
||||
for (i = 0; i < ctx->num_entities; i++)
|
||||
{
|
||||
if (mapent == &entities[i])
|
||||
if (mapent == &ctx->entities[i])
|
||||
continue;
|
||||
|
||||
if (!strcmp(mapent->target, entities[i].targetname))
|
||||
if (!strcmp(mapent->target, ctx->entities[i].targetname))
|
||||
{
|
||||
mapent->targetent = &entities[i];
|
||||
mapent->targetentnum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -240,43 +277,6 @@ void LightLoadEntities(char *entstring)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define mentity_t entity_t
|
||||
#define UTILITY
|
||||
#include "light.h"
|
||||
|
||||
#define bsptexinfo(i) texinfo[i]
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
CastRay
|
||||
|
||||
Returns the distance between the points, or -1 if blocked
|
||||
=============
|
||||
*/
|
||||
vec_t CastRay (vec3_t p1, vec3_t p2)
|
||||
{
|
||||
int i;
|
||||
vec_t t;
|
||||
qboolean trace;
|
||||
|
||||
trace = TestLine (p1, p2);
|
||||
|
||||
if (!trace)
|
||||
return -1; // ray was blocked
|
||||
|
||||
t = 0;
|
||||
for (i=0 ; i< 3 ; i++)
|
||||
t += (p2[i]-p1[i]) * (p2[i]-p1[i]);
|
||||
|
||||
if (t < 1)
|
||||
t = 1; // don't blow up...
|
||||
return sqrt(t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
@ -298,10 +298,13 @@ towards the center until it is valid.
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
#define SINGLEMAP (18*18*4)
|
||||
#define MAXIMUMEXTENT 128
|
||||
#define SINGLEMAP (MAXIMUMEXTENT*MAXIMUMEXTENT*4)
|
||||
|
||||
typedef struct
|
||||
typedef struct llightinfo_s
|
||||
{
|
||||
struct relight_ctx_s *ctx; //relight context, shared between threads.
|
||||
|
||||
vec3_t lightmaps[MAXQ1LIGHTMAPS][SINGLEMAP];
|
||||
vec3_t lightnorm[MAXQ1LIGHTMAPS][SINGLEMAP];
|
||||
int numlightstyles;
|
||||
|
@ -319,11 +322,11 @@ typedef struct
|
|||
vec_t exactmins[2], exactmaxs[2];
|
||||
|
||||
int texmins[2], texsize[2];
|
||||
int lightstyles[256];
|
||||
int surfnum;
|
||||
dface_t *face;
|
||||
int lightstyles[MAXQ1LIGHTMAPS];
|
||||
} llightinfo_t;
|
||||
|
||||
const size_t lightthreadctxsize = sizeof(llightinfo_t);
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -332,35 +335,36 @@ CalcFaceVectors
|
|||
Fills in texorg, worldtotex. and textoworld
|
||||
================
|
||||
*/
|
||||
static void LightCalcFaceVectors (llightinfo_t *l)
|
||||
static void LightCalcFaceVectors (llightinfo_t *l, vec4_t surf_texplanes[2])
|
||||
{
|
||||
texinfo_t *tex;
|
||||
int i, j;
|
||||
vec3_t texnormal;
|
||||
float distscale;
|
||||
vec_t dist, len;
|
||||
|
||||
tex = &bsptexinfo(l->face->texinfo);
|
||||
|
||||
// convert from float to vec_t
|
||||
for (i=0 ; i<2 ; i++)
|
||||
for (j=0 ; j<3 ; j++)
|
||||
l->worldtotex[i][j] = tex->vecs[i][j];
|
||||
l->worldtotex[i][j] = surf_texplanes[i][j];
|
||||
|
||||
// calculate a normal to the texture axis. points can be moved along this
|
||||
// without changing their S/T
|
||||
texnormal[0] = tex->vecs[1][1]*tex->vecs[0][2]
|
||||
- tex->vecs[1][2]*tex->vecs[0][1];
|
||||
texnormal[1] = tex->vecs[1][2]*tex->vecs[0][0]
|
||||
- tex->vecs[1][0]*tex->vecs[0][2];
|
||||
texnormal[2] = tex->vecs[1][0]*tex->vecs[0][1]
|
||||
- tex->vecs[1][1]*tex->vecs[0][0];
|
||||
texnormal[0] = surf_texplanes[1][1]*surf_texplanes[0][2]
|
||||
- surf_texplanes[1][2]*surf_texplanes[0][1];
|
||||
texnormal[1] = surf_texplanes[1][2]*surf_texplanes[0][0]
|
||||
- surf_texplanes[1][0]*surf_texplanes[0][2];
|
||||
texnormal[2] = surf_texplanes[1][0]*surf_texplanes[0][1]
|
||||
- surf_texplanes[1][1]*surf_texplanes[0][0];
|
||||
VectorNormalize (texnormal);
|
||||
|
||||
// flip it towards plane normal
|
||||
distscale = DotProduct (texnormal, l->facenormal);
|
||||
if (!distscale)
|
||||
Error ("Texture axis perpendicular to face");
|
||||
{
|
||||
VectorCopy(l->facenormal, texnormal);
|
||||
distscale = 1;
|
||||
Con_Printf ("Texture axis perpendicular to face\n");
|
||||
}
|
||||
if (distscale < 0)
|
||||
{
|
||||
distscale = -distscale;
|
||||
|
@ -383,7 +387,7 @@ static void LightCalcFaceVectors (llightinfo_t *l)
|
|||
|
||||
// calculate texorg on the texture plane
|
||||
for (i=0 ; i<3 ; i++)
|
||||
l->texorg[i] = -tex->vecs[0][3]* l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];
|
||||
l->texorg[i] = -surf_texplanes[0][3]* l->textoworld[0][i] - surf_texplanes[1][3] * l->textoworld[1][i];
|
||||
|
||||
// project back to the face plane
|
||||
dist = DotProduct (l->texorg, l->facenormal) - l->facedist - 1;
|
||||
|
@ -400,18 +404,15 @@ Fills in s->texmins[] and s->texsize[]
|
|||
also sets exactmins[] and exactmaxs[]
|
||||
================
|
||||
*/
|
||||
static void LightCalcFaceExtents (llightinfo_t *l)
|
||||
static void LightCalcFaceExtents (model_t *lightmodel, dface_t *s, vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2])
|
||||
{
|
||||
dface_t *s;
|
||||
vec_t mins[2], maxs[2], val;
|
||||
int i,j, e;
|
||||
dvertex_t *v;
|
||||
texinfo_t *tex;
|
||||
|
||||
s = l->face;
|
||||
|
||||
mins[0] = mins[1] = 999999;
|
||||
maxs[0] = maxs[1] = -99999;
|
||||
maxs[0] = maxs[1] = -999999;
|
||||
|
||||
tex = &bsptexinfo(s->texinfo);
|
||||
|
||||
|
@ -425,9 +426,9 @@ static void LightCalcFaceExtents (llightinfo_t *l)
|
|||
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
val = v->point[0] * tex->vecs[j][0] +
|
||||
v->point[1] * tex->vecs[j][1] +
|
||||
v->point[2] * tex->vecs[j][2] +
|
||||
val = v->position[0] * tex->vecs[j][0] +
|
||||
v->position[1] * tex->vecs[j][1] +
|
||||
v->position[2] * tex->vecs[j][2] +
|
||||
tex->vecs[j][3];
|
||||
if (val < mins[j])
|
||||
mins[j] = val;
|
||||
|
@ -438,17 +439,17 @@ static void LightCalcFaceExtents (llightinfo_t *l)
|
|||
|
||||
for (i=0 ; i<2 ; i++)
|
||||
{
|
||||
l->exactmins[i] = mins[i];
|
||||
l->exactmaxs[i] = maxs[i];
|
||||
exactmins[i] = mins[i];
|
||||
exactmaxs[i] = maxs[i];
|
||||
|
||||
mins[i] = floor(mins[i]/(1<<s->lmshift));
|
||||
maxs[i] = ceil(maxs[i]/(1<<s->lmshift));
|
||||
|
||||
l->texmins[i] = mins[i];
|
||||
l->texsize[i] = maxs[i] - mins[i];
|
||||
if (l->texsize[i] > 17)
|
||||
texmins[i] = mins[i];
|
||||
texsize[i] = maxs[i] - mins[i];
|
||||
if (texsize[i] > MAXIMUMEXTENT-1)
|
||||
{
|
||||
l->texsize[i] = 17;
|
||||
texsize[i] = MAXIMUMEXTENT-1;
|
||||
Con_Printf("Bad surface extents");
|
||||
}
|
||||
}
|
||||
|
@ -462,12 +463,12 @@ For each texture aligned grid point, back project onto the plane
|
|||
to get the world xyz value of the sample point
|
||||
=================
|
||||
*/
|
||||
static int c_bad;
|
||||
static void LightCalcPoints (llightinfo_t *l)
|
||||
static void LightCalcPoints (llightinfo_t *l, float lmscale)
|
||||
{
|
||||
int i;
|
||||
int s, t, j;
|
||||
int w, h, step;
|
||||
int w, h;
|
||||
vec_t step;
|
||||
vec_t starts, startt, us, ut;
|
||||
vec_t *surf;
|
||||
vec_t mids, midt;
|
||||
|
@ -489,17 +490,17 @@ static void LightCalcPoints (llightinfo_t *l)
|
|||
{ // extra filtering
|
||||
h = (l->texsize[1]+1)*2;
|
||||
w = (l->texsize[0]+1)*2;
|
||||
starts = (l->texmins[0]-0.5)*16;
|
||||
startt = (l->texmins[1]-0.5)*16;
|
||||
step = 8;
|
||||
starts = (l->texmins[0]-0.5)*lmscale;
|
||||
startt = (l->texmins[1]-0.5)*lmscale;
|
||||
step = 0.5 * lmscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = l->texsize[1]+1;
|
||||
w = l->texsize[0]+1;
|
||||
starts = l->texmins[0]*16;
|
||||
startt = l->texmins[1]*16;
|
||||
step = 16;
|
||||
starts = l->texmins[0]*lmscale;
|
||||
startt = l->texmins[1]*lmscale;
|
||||
step = lmscale;
|
||||
}
|
||||
|
||||
l->numsurfpt = w * h;
|
||||
|
@ -518,19 +519,19 @@ static void LightCalcPoints (llightinfo_t *l)
|
|||
surf[j] = l->texorg[j] + l->textoworld[0][j]*us
|
||||
+ l->textoworld[1][j]*ut;
|
||||
|
||||
if (CastRay (facemid, surf) != -1)
|
||||
if (CastRay (l->ctx, facemid, surf) != -1)
|
||||
break; // got it
|
||||
if (i & 1)
|
||||
{
|
||||
if (us > mids)
|
||||
{
|
||||
us -= 8;
|
||||
us -= lmscale*0.5;
|
||||
if (us < mids)
|
||||
us = mids;
|
||||
}
|
||||
else
|
||||
{
|
||||
us += 8;
|
||||
us += lmscale*0.5;
|
||||
if (us > mids)
|
||||
us = mids;
|
||||
}
|
||||
|
@ -539,13 +540,13 @@ static void LightCalcPoints (llightinfo_t *l)
|
|||
{
|
||||
if (ut > midt)
|
||||
{
|
||||
ut -= 8;
|
||||
ut -= lmscale*0.5;
|
||||
if (ut < midt)
|
||||
ut = midt;
|
||||
}
|
||||
else
|
||||
{
|
||||
ut += 8;
|
||||
ut += lmscale*0.5;
|
||||
if (ut > midt)
|
||||
ut = midt;
|
||||
}
|
||||
|
@ -555,9 +556,9 @@ static void LightCalcPoints (llightinfo_t *l)
|
|||
VectorSubtract (facemid, surf, move);
|
||||
VectorNormalize (move);
|
||||
VectorMA (surf, 8, move, surf);
|
||||
|
||||
P_RunParticleEffectType(surf, NULL, 1, pt_wizspike);
|
||||
}
|
||||
if (i == 2)
|
||||
c_bad++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,8 +573,6 @@ FACE LIGHTING
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
int c_culldistplane, c_proper;
|
||||
|
||||
/*
|
||||
================
|
||||
SingleLightFace
|
||||
|
@ -588,8 +587,7 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
vec_t *surf;
|
||||
qboolean hit;
|
||||
int mapnum;
|
||||
int size;
|
||||
int c, i;
|
||||
int c;
|
||||
vec3_t rel;
|
||||
vec3_t spotvec;
|
||||
vec_t falloff;
|
||||
|
@ -605,14 +603,11 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
|
||||
// don't bother with light too far away
|
||||
if (dist > light->light)
|
||||
{
|
||||
c_culldistplane++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (light->targetent)
|
||||
if (light->targetentnum>=0)
|
||||
{
|
||||
VectorSubtract (light->targetent->origin, light->origin, spotvec);
|
||||
VectorSubtract (l->ctx->entities[light->targetentnum].origin, light->origin, spotvec);
|
||||
VectorNormalize (spotvec);
|
||||
if (!light->angle)
|
||||
falloff = -cos(20*Q_PI/180);
|
||||
|
@ -631,6 +626,7 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
norms = l->lightnorm[mapnum];
|
||||
if (mapnum == l->numlightstyles)
|
||||
{ // init a new light map
|
||||
#ifdef UTILITY
|
||||
if (mapnum == MAXQ1LIGHTMAPS)
|
||||
{
|
||||
printf ("WARNING: Too many light styles on a face\n");
|
||||
|
@ -646,24 +642,26 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
norms[i][1] = 0;
|
||||
norms[i][2] = 0;
|
||||
}
|
||||
#else
|
||||
return; //can't light a surface with a lightstyle that did not previously exist, due to lightmap space limits.
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// check it for real
|
||||
//
|
||||
hit = false;
|
||||
c_proper++;
|
||||
|
||||
surf = l->surfpt[0];
|
||||
for (c=0 ; c<l->numsurfpt ; c++, surf+=3)
|
||||
{
|
||||
dist = CastRay(light->origin, surf)*scaledist;
|
||||
dist = CastRay(l->ctx, light->origin, surf)*scaledist;
|
||||
if (dist < 0)
|
||||
continue; // light doesn't reach
|
||||
|
||||
VectorSubtract (light->origin, surf, incoming);
|
||||
VectorNormalize (incoming);
|
||||
if (light->targetent)
|
||||
if (light->targetentnum >= 0)
|
||||
{ // spotlight cutoff
|
||||
if (DotProduct (spotvec, incoming) > falloff)
|
||||
continue;
|
||||
|
@ -680,14 +678,14 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
|
|||
lightsamp[c][1] += add*light->colour[1];
|
||||
lightsamp[c][2] += add*light->colour[2];
|
||||
|
||||
norms[c][0] += add * incoming[0]; //Quake doesn't make sence some times.
|
||||
norms[c][0] += add * incoming[0];
|
||||
norms[c][1] += add * incoming[1];
|
||||
norms[c][2] += add * incoming[2];
|
||||
|
||||
if (add > 1) // ignore real tiny lights
|
||||
hit = true;
|
||||
}
|
||||
|
||||
|
||||
if (mapnum == l->numlightstyles && hit)
|
||||
{
|
||||
l->lightstyles[mapnum] = light->style;
|
||||
|
@ -749,12 +747,10 @@ static void FixMinlight (llightinfo_t *l)
|
|||
LightFace
|
||||
============
|
||||
*/
|
||||
void LightFace (int surfnum)
|
||||
void LightPlane (struct relight_ctx_s *ctx, struct llightinfo_s *l, qbyte surf_styles[4], qbyte *surf_rgbsamples, qbyte *surf_deluxesamples, vec4_t surf_plane, vec4_t surf_texplanes[2], vec2_t exactmins, vec2_t exactmaxs, int texmins[2], int texsize[2], float lmscale)
|
||||
{
|
||||
dface_t *f;
|
||||
llightinfo_t l;
|
||||
int s, t;
|
||||
int i,j,c,ch;
|
||||
int i,c,ch;
|
||||
vec_t total, mean;
|
||||
int size;
|
||||
int lightmapwidth;
|
||||
|
@ -762,82 +758,62 @@ void LightFace (int surfnum)
|
|||
int lightmapsize;
|
||||
byte *out;
|
||||
#endif
|
||||
byte *rgbout;
|
||||
byte *dulout;
|
||||
qbyte *rgbout;
|
||||
qbyte *dulout;
|
||||
vec3_t *light, *norm;
|
||||
vec3_t wnorm, temp, svector, tvector;
|
||||
int w;
|
||||
|
||||
f = dfaces + surfnum;
|
||||
|
||||
//
|
||||
// some surfaces don't need lightmaps
|
||||
//
|
||||
#ifdef UTILITY
|
||||
for (j=0 ; j<MAXLIGHTMAPS ; j++)
|
||||
f->styles[j] = 255;
|
||||
#endif
|
||||
if ( bsptexinfo(f->texinfo).flags & TEX_SPECIAL)
|
||||
{ // non-lit texture
|
||||
#ifdef UTILITY
|
||||
f->lightofs = -1;
|
||||
#endif
|
||||
if (!surf_rgbsamples)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef UTILITY
|
||||
if (!f->samples)
|
||||
return;
|
||||
#endif
|
||||
|
||||
memset (&l, 0, sizeof(l));
|
||||
l.surfnum = surfnum;
|
||||
l.face = f;
|
||||
memset (l, 0, sizeof(*l));
|
||||
l->ctx = ctx;
|
||||
|
||||
//
|
||||
// rotate plane
|
||||
//
|
||||
#ifndef UTILITY
|
||||
VectorCopy (f->plane->normal, l.facenormal);
|
||||
l.facedist = f->plane->dist;
|
||||
#else
|
||||
VectorCopy (dplanes[f->planenum].normal, l.facenormal);
|
||||
l.facedist = dplanes[f->planenum].dist;
|
||||
#endif
|
||||
if (f->side)
|
||||
{
|
||||
VectorNegate (l.facenormal, l.facenormal);
|
||||
l.facedist = -l.facedist;
|
||||
}
|
||||
|
||||
VectorCopy (surf_plane, l->facenormal);
|
||||
l->facedist = surf_plane[3];
|
||||
|
||||
|
||||
LightCalcFaceVectors (&l);
|
||||
LightCalcFaceExtents (&l);
|
||||
LightCalcPoints (&l);
|
||||
LightCalcFaceVectors (l, surf_texplanes);
|
||||
Vector2Copy(exactmins, l->exactmins);
|
||||
Vector2Copy(exactmaxs, l->exactmaxs);
|
||||
Vector2Copy(texmins, l->texmins);
|
||||
Vector2Copy(texsize, l->texsize);
|
||||
LightCalcPoints (l, lmscale);
|
||||
|
||||
lightmapwidth = l.texsize[0]+1;
|
||||
lightmapwidth = l->texsize[0]+1;
|
||||
|
||||
size = lightmapwidth*(l.texsize[1]+1);
|
||||
size = lightmapwidth*(l->texsize[1]+1);
|
||||
if (size > SINGLEMAP)
|
||||
Error ("Bad lightmap size");
|
||||
Host_Error ("Bad lightmap size");
|
||||
|
||||
for (i=0 ; i<MAXQ1LIGHTMAPS ; i++)
|
||||
l.lightstyles[i] = 255;
|
||||
i = 0;
|
||||
#ifndef UTILITY
|
||||
for (; surf_styles[i] != 255 && i < 4; i++)
|
||||
l->lightstyles[i] = surf_styles[i];
|
||||
#endif
|
||||
l->numlightstyles = i;
|
||||
for ( ; i<MAXQ1LIGHTMAPS ; i++)
|
||||
l->lightstyles[i] = 255;
|
||||
|
||||
//
|
||||
// cast all lights
|
||||
//
|
||||
l.numlightstyles = 0;
|
||||
for (i=0 ; i<num_entities ; i++)
|
||||
for (i=0 ; i<ctx->num_entities ; i++)
|
||||
{
|
||||
if (entities[i].light)
|
||||
SingleLightFace (&entities[i], &l);
|
||||
if (ctx->entities[i].light)
|
||||
SingleLightFace (&ctx->entities[i], l);
|
||||
}
|
||||
|
||||
FixMinlight (&l);
|
||||
FixMinlight (l);
|
||||
|
||||
if (!l.numlightstyles)
|
||||
if (!l->numlightstyles)
|
||||
{ // no light hitting it
|
||||
#ifdef UTILITY
|
||||
f->lightofs = -1;
|
||||
|
@ -845,20 +821,15 @@ void LightFace (int surfnum)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef UTILITY
|
||||
for (j=0 ; j<MAXQ1LIGHTMAPS ; j++)
|
||||
f->styles[j] = 255;
|
||||
#endif
|
||||
|
||||
//
|
||||
// save out the values
|
||||
//
|
||||
for (i=0 ; i <MAXQ1LIGHTMAPS ; i++)
|
||||
f->styles[i] = l.lightstyles[i];
|
||||
surf_styles[i] = l->lightstyles[i];
|
||||
|
||||
|
||||
#ifdef UTILITY
|
||||
lightmapsize = size*l.numlightstyles;
|
||||
lightmapsize = size*l->numlightstyles;
|
||||
if (runningrgblightdatabase)
|
||||
{
|
||||
out = GetFakeFileSpace(&f->lightofs, lightmapsize);
|
||||
|
@ -873,13 +844,13 @@ void LightFace (int surfnum)
|
|||
dulout = GetNormFileSpace (f->lightofs, lightmapsize);
|
||||
}
|
||||
#else
|
||||
rgbout = f->samples;
|
||||
if (lightmodel->deluxdata)
|
||||
rgbout = surf_rgbsamples;
|
||||
if (l->ctx->models[0]->deluxdata)
|
||||
{
|
||||
dulout = f->samples - lightmodel->lightdata + lightmodel->deluxdata;
|
||||
dulout = surf_deluxesamples;
|
||||
|
||||
VectorCopy(bsptexinfo(f->texinfo).vecs[0], svector);
|
||||
VectorNegate(bsptexinfo(f->texinfo).vecs[1], tvector);
|
||||
VectorCopy(surf_texplanes[0], svector);
|
||||
VectorNegate(surf_texplanes[1], tvector);
|
||||
VectorNormalize(svector);
|
||||
VectorNormalize(tvector);
|
||||
}
|
||||
|
@ -891,18 +862,20 @@ void LightFace (int surfnum)
|
|||
|
||||
// extra filtering
|
||||
// h = (l.texsize[1]+1)*2;
|
||||
w = (l.texsize[0]+1)*2;
|
||||
w = l->texsize[0]+1;
|
||||
if (extrasamples)
|
||||
w *= 2;
|
||||
|
||||
for (i=0 ; i< l.numlightstyles ; i++)
|
||||
for (i=0 ; i< l->numlightstyles ; i++)
|
||||
{
|
||||
if (l.lightstyles[i] == 0xff)
|
||||
Error ("Wrote empty lightmap");
|
||||
light = l.lightmaps[i];
|
||||
norm = l.lightnorm[i];
|
||||
if (l->lightstyles[i] == 0xff)
|
||||
Host_Error ("Wrote empty lightmap");
|
||||
light = l->lightmaps[i];
|
||||
norm = l->lightnorm[i];
|
||||
c = 0;
|
||||
for (t=0 ; t<=l.texsize[1] ; t++)
|
||||
for (t=0 ; t<=l->texsize[1] ; t++)
|
||||
{
|
||||
for (s=0 ; s<=l.texsize[0] ; s++, c++)
|
||||
for (s=0 ; s<=l->texsize[0] ; s++, c++)
|
||||
{
|
||||
mean = 0;
|
||||
|
||||
|
@ -924,11 +897,13 @@ void LightFace (int surfnum)
|
|||
}
|
||||
total *= rangescale; // scale before clamping
|
||||
#ifndef UTILITY
|
||||
if (total > *rgbout) //sorry - for qw
|
||||
total = *rgbout;
|
||||
// if (total > *rgbout) //sorry - for qw
|
||||
// total = *rgbout;
|
||||
#endif
|
||||
if (total < 0)
|
||||
Error ("light < 0");
|
||||
total = 0;
|
||||
if (total > 0xff)
|
||||
total = 0xff;
|
||||
|
||||
*rgbout++ = total;
|
||||
mean += total;
|
||||
|
@ -941,15 +916,11 @@ void LightFace (int surfnum)
|
|||
{
|
||||
temp[0] = DotProduct(wnorm, svector);
|
||||
temp[1] = DotProduct(wnorm, tvector);
|
||||
temp[2] = DotProduct(wnorm, l.facenormal);
|
||||
temp[2] = DotProduct(wnorm, l->facenormal);
|
||||
if (!temp[0] && !temp[1] && !temp[2])
|
||||
VectorSet(temp, 0, 0, 1);
|
||||
else
|
||||
{
|
||||
VectorNormalize(temp);
|
||||
// temp[2] += 0.5;
|
||||
VectorNormalize(temp);
|
||||
}
|
||||
*dulout++ = (temp[0]+1)*128;
|
||||
*dulout++ = (temp[1]+1)*128;
|
||||
*dulout++ = (temp[2]+1)*128;
|
||||
|
@ -958,5 +929,27 @@ void LightFace (int surfnum)
|
|||
}
|
||||
}
|
||||
}
|
||||
void LightFace (struct relight_ctx_s *ctx, struct llightinfo_s *threadctx, int facenum)
|
||||
{
|
||||
dface_t *f = ctx->models[0]->surfaces + facenum;
|
||||
vec4_t plane;
|
||||
vec2_t exactmins;
|
||||
vec2_t exactmaxs;
|
||||
int texmins[2], texsize[2];
|
||||
|
||||
VectorCopy (f->plane->normal, plane);
|
||||
plane[3] = f->plane->dist;
|
||||
if (f->flags & SURF_PLANEBACK)
|
||||
{
|
||||
VectorNegate (plane, plane);
|
||||
plane[3] = -plane[3];
|
||||
}
|
||||
|
||||
//no lighting on these.
|
||||
if (f->texinfo->flags & TEX_SPECIAL)
|
||||
return;
|
||||
|
||||
LightCalcFaceExtents(ctx->models[0], f, exactmins, exactmaxs, texmins, texsize);
|
||||
LightPlane(ctx, threadctx, f->styles, f->samples, f->samples - ctx->models[0]->lightdata + ctx->models[0]->deluxdata, plane, f->texinfo->vecs, exactmins, exactmaxs, texmins, texsize, 1<<f->lmshift);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1691,8 +1691,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#define r_glsl_pcf 9\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
|
||||
|
||||
//texturegather is a gl4 feature, but these shaders are gl2.0 or something
|
||||
"#if #include \"cvar/texgather\" && defined(GL_ARB_texture_gather) && defined(PCF) \n"
|
||||
"#extension GL_ARB_texture_gather : enable\n"
|
||||
"#define DOTEXTUREGATHER\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef UPPERLOWER\n"
|
||||
|
@ -1851,7 +1854,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"{\n"
|
||||
"vec3 shadowcoord = ShadowmapCoord();\n"
|
||||
|
||||
"#if 0//def GL_ARB_texture_gather\n"
|
||||
"#ifdef DOTEXTUREGATHER\n"
|
||||
"vec2 ipart, fpart;\n"
|
||||
"#define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y)))\n"
|
||||
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
|
||||
|
|
|
@ -595,7 +595,7 @@ shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname);
|
|||
shader_t *R_RegisterCustom (const char *name, unsigned int usageflags, shader_gen_t *defaultgen, const void *args);
|
||||
//once loaded, most shaders should have one of the following two calls used upon it
|
||||
void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader);
|
||||
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette);
|
||||
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette);
|
||||
void R_RemapShader(const char *sourcename, const char *destname, float timeoffset);
|
||||
|
||||
cin_t *R_ShaderGetCinematic(shader_t *s);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "netinc.h"
|
||||
#include "fs.h"
|
||||
|
||||
vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefile);
|
||||
|
||||
#if defined(WEBCLIENT)
|
||||
|
||||
#if defined(FTE_TARGET_WEB)
|
||||
|
@ -287,20 +289,20 @@ struct http_dl_ctx_s {
|
|||
|
||||
char *buffer;
|
||||
|
||||
int bufferused;
|
||||
int bufferlen;
|
||||
size_t bufferused;
|
||||
size_t bufferlen;
|
||||
|
||||
int totalreceived; //useful when we're just dumping to a file.
|
||||
size_t totalreceived; //useful when we're just dumping to a file.
|
||||
|
||||
struct vfsfile_s *file; //if gzipping, this is a temporary file. we'll write to the real file from this after the transfer is complete.
|
||||
qboolean gzip;
|
||||
qboolean chunking;
|
||||
int chunksize;
|
||||
int chunked;
|
||||
size_t chunksize;
|
||||
size_t chunked;
|
||||
|
||||
enum {HC_REQUESTING, HC_GETTINGHEADER, HC_GETTING} state;
|
||||
|
||||
int contentlength;
|
||||
size_t contentlength;
|
||||
};
|
||||
|
||||
void HTTP_Cleanup(struct dl_download *dl)
|
||||
|
@ -400,7 +402,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
|
||||
msg = con->buffer;
|
||||
con->chunking = false;
|
||||
con->contentlength = 0;
|
||||
con->contentlength = -1;
|
||||
con->gzip = false;
|
||||
*mimetype = 0;
|
||||
*Location = 0;
|
||||
|
@ -567,7 +569,11 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
if (con->gzip)
|
||||
{
|
||||
#if !defined(NPFTE) && defined(AVAIL_ZLIB)
|
||||
#if 1
|
||||
con->file = FS_GZ_DecompressWriteFilter(dl->file, false);
|
||||
#else
|
||||
con->file = FS_OpenTemp();
|
||||
#endif
|
||||
#else
|
||||
Con_Printf("HTTP: no support for gzipped files \"%s\"\n", dl->localname);
|
||||
dl->status = DL_FAILED;
|
||||
|
@ -659,7 +665,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
}
|
||||
else
|
||||
{
|
||||
con->totalreceived+=ammount;
|
||||
con->totalreceived+=con->bufferused;
|
||||
if (con->file) //we've got a chunk in the buffer
|
||||
{ //write it
|
||||
if (VFS_WRITE(con->file, con->buffer, con->bufferused) != con->bufferused)
|
||||
|
@ -669,6 +675,8 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
}
|
||||
con->bufferused = 0;
|
||||
}
|
||||
if (con->totalreceived == con->contentlength)
|
||||
ammount = 0;
|
||||
}
|
||||
|
||||
if (!ammount)
|
||||
|
@ -678,6 +686,13 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
else
|
||||
{
|
||||
#if !defined(NPFTE) && defined(AVAIL_ZLIB)
|
||||
#if 1
|
||||
if (con->gzip && con->file)
|
||||
{
|
||||
VFS_CLOSE(con->file);
|
||||
con->file = NULL;
|
||||
}
|
||||
#else
|
||||
if (con->gzip && con->file)
|
||||
{
|
||||
VFS_SEEK(con->file, 0);
|
||||
|
@ -685,7 +700,11 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
|
|||
con->file = NULL;
|
||||
}
|
||||
#endif
|
||||
dl->status = (dl->replycode == 200)?DL_FINISHED:DL_FAILED;
|
||||
#endif
|
||||
if (con->contentlength != -1 && con->totalreceived != con->contentlength)
|
||||
dl->status = DL_FAILED; //file was truncated
|
||||
else
|
||||
dl->status = (dl->replycode == 200)?DL_FINISHED:DL_FAILED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -82,28 +82,41 @@ char *authedusername;
|
|||
char *autheduserpassword;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int httpport = 80;
|
||||
int arg = 1;
|
||||
WSADATA pointlesscrap;
|
||||
WSAStartup(2, &pointlesscrap);
|
||||
|
||||
if (argc == 3)
|
||||
{
|
||||
authedusername = argv[1];
|
||||
autheduserpassword = argv[2];
|
||||
if (arg < argc && atoi(argv[arg]))
|
||||
httpport = atoi(argv[arg++]);
|
||||
if (arg < argc)
|
||||
authedusername = argv[arg++];
|
||||
if (arg < argc)
|
||||
autheduserpassword = argv[arg++];
|
||||
|
||||
printf("http port %i\n", httpport);
|
||||
if (authedusername || autheduserpassword)
|
||||
printf("Username = \"%s\"\nPassword = \"%s\"\n", authedusername, autheduserpassword);
|
||||
}
|
||||
else
|
||||
printf("Server is read only\n");
|
||||
|
||||
while(1)
|
||||
{
|
||||
// FTP_ServerRun(1, 21);
|
||||
HTTP_ServerPoll(1, 80);
|
||||
if (httpport)
|
||||
HTTP_ServerPoll(1, httpport);
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void COM_EnumerateFiles (const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *f), void *parm)
|
||||
static time_t Sys_FileTimeToTime(FILETIME ft)
|
||||
{
|
||||
ULARGE_INTEGER ull;
|
||||
ull.LowPart = ft.dwLowDateTime;
|
||||
ull.HighPart = ft.dwHighDateTime;
|
||||
return ull.QuadPart / 10000000ULL - 11644473600ULL;
|
||||
}
|
||||
void COM_EnumerateFiles (const char *match, int (*func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t *f), void *parm)
|
||||
{
|
||||
HANDLE r;
|
||||
WIN32_FIND_DATA fd;
|
||||
|
@ -132,19 +145,19 @@ void COM_EnumerateFiles (const char *match, int (*func)(const char *, qofs_t, vo
|
|||
else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory
|
||||
{
|
||||
sprintf(file, "%s%s/", apath, fd.cFileName);
|
||||
go = func(file, fd.nFileSizeLow, parm, NULL);
|
||||
go = func(file, fd.nFileSizeLow, Sys_FileTimeToTime(fd.ftLastWriteTime), parm, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(file, "%s%s", apath, fd.cFileName);
|
||||
go = func(file, fd.nFileSizeLow, parm, NULL);
|
||||
go = func(file, fd.nFileSizeLow, Sys_FileTimeToTime(fd.ftLastWriteTime), parm, NULL);
|
||||
}
|
||||
}
|
||||
while(FindNextFile(r, &fd) && go);
|
||||
FindClose(r);
|
||||
}
|
||||
|
||||
char *COM_ParseOut (const char *data, char *out, int outlen)
|
||||
char *COM_ParseType (const char *data, char *out, int outlen, com_tokentype_t *toktype)
|
||||
{
|
||||
int c;
|
||||
int len;
|
||||
|
|
|
@ -284,7 +284,7 @@ r_part +te_explosion
|
|||
randomvel 1000
|
||||
friction 0.01
|
||||
gravity 100
|
||||
stretchfactor 5
|
||||
stretchfactor -80
|
||||
}
|
||||
|
||||
//hide lights in explosions.
|
||||
|
|
|
@ -1950,8 +1950,8 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
|
|||
protocollen = 6;
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
protocollen = 6;
|
||||
nullterms = 1;
|
||||
protocollen = 6+nullterms;
|
||||
break;
|
||||
case svcqw_updatestatlong:
|
||||
protocollen = 6;
|
||||
|
|
|
@ -87,6 +87,7 @@ cvar_t pr_ssqc_coreonerror = CVAR("pr_coreonerror", "1");
|
|||
cvar_t sv_gameplayfix_honest_tracelines = CVAR("sv_gameplayfix_honest_tracelines", "1");
|
||||
cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "0", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model.");
|
||||
cvar_t sv_gameplayfix_setmodelsize_qw = CVARD("sv_gameplayfix_setmodelsize_qw", "0", "The setmodel builtin will act as a setsize for QuakeWorld mods also.");
|
||||
cvar_t dpcompat_nopreparse = CVARD("dpcompat_nopreparse", "0", "Xonotic uses svc_tempentity with unknowable lengths mixed with other data that needs to be translated. This cvar disables any attempt to translate or pre-parse network messages, including disabling nq/qw cross compatibility. NOTE: because preparsing will be disabled, messages might not get backbuffered correctly if too much reliable data is written.");
|
||||
|
||||
cvar_t sv_addon[MAXADDONS];
|
||||
char cvargroup_progs[] = "Progs variables";
|
||||
|
@ -1295,6 +1296,7 @@ void PR_Init(void)
|
|||
Cvar_Register (&pr_ssqc_progs, cvargroup_progs);
|
||||
Cvar_Register (&pr_compatabilitytest, cvargroup_progs);
|
||||
|
||||
Cvar_Register (&dpcompat_nopreparse, cvargroup_progs);
|
||||
Cvar_Register (&pr_nonetaccess, cvargroup_progs);
|
||||
Cvar_Register (&pr_overridebuiltins, cvargroup_progs);
|
||||
|
||||
|
@ -2957,9 +2959,8 @@ PF_ambientsound
|
|||
*/
|
||||
void PF_ambientsound_Internal (float *pos, const char *samp, float vol, float attenuation)
|
||||
{
|
||||
int i, soundnum, j;
|
||||
sizebuf_t *buf[3] = {&sv.signon, &sv.nqmulticast, &sv.multicast};
|
||||
sizebuf_t *msg;
|
||||
staticsound_state_t *state;
|
||||
int soundnum;
|
||||
|
||||
// check to see if samp was properly precached
|
||||
for (soundnum=1 ; *sv.strings.sound_precache[soundnum] ; soundnum++)
|
||||
|
@ -2972,25 +2973,18 @@ void PF_ambientsound_Internal (float *pos, const char *samp, float vol, float at
|
|||
return;
|
||||
}
|
||||
|
||||
SV_FlushSignon();
|
||||
|
||||
if (soundnum > 255)
|
||||
return;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
if (sv.num_static_sounds == sv_max_staticsounds)
|
||||
{
|
||||
msg = buf[j];
|
||||
if (sv.state == ss_loading && j)
|
||||
break;
|
||||
// add an svc_spawnambient command to the level signon packet
|
||||
MSG_WriteByte (msg,svc_spawnstaticsound);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
MSG_WriteCoord(msg, pos[i]);
|
||||
MSG_WriteByte (msg, soundnum);
|
||||
MSG_WriteByte (msg, bound(0, (int)(vol*255), 255));
|
||||
MSG_WriteByte (msg, attenuation*64);
|
||||
sv_max_staticsounds += 16;
|
||||
sv_staticsounds = BZ_Realloc(sv_staticsounds, sizeof(*sv_staticsounds) * sv_max_staticsounds);
|
||||
}
|
||||
SV_Multicast(pos, MULTICAST_ALL_R);
|
||||
|
||||
state = &sv_staticsounds[sv.num_static_sounds++];
|
||||
memset(state, 0, sizeof(*state));
|
||||
VectorCopy(pos, state->position);
|
||||
state->soundnum = soundnum;
|
||||
state->volume = bound(0, (int)(vol*255), 255);
|
||||
state->attenuation = attenuation*64;
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_ambientsound (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4212,7 +4206,7 @@ static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
vec3_t start, dir, end, bestdir;
|
||||
int i, j;
|
||||
trace_t tr;
|
||||
float dist, bestdist;
|
||||
float dist, bestdist = sv_aim.value;
|
||||
char *noaim;
|
||||
|
||||
ent = G_EDICT(prinst, OFS_PARM0);
|
||||
|
@ -4231,6 +4225,14 @@ static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
VectorCopy (P_VEC(v_forward), G_VECTOR(OFS_RETURN));
|
||||
return;
|
||||
}
|
||||
|
||||
noaim = Info_ValueForKey (svs.clients[i-1].userinfo, "aim");
|
||||
if (noaim)
|
||||
{
|
||||
dist = atof(noaim);
|
||||
if (dist > 0)
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
// try sending a trace straight
|
||||
|
@ -4433,7 +4435,9 @@ void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteByte(dest, val);
|
||||
return;
|
||||
|
@ -4444,7 +4448,7 @@ void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
NPP_QWWriteByte(dest, val);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4454,8 +4458,12 @@ void QCBUILTIN PF_WriteByte (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
ClientReliableWrite_Byte(cl, val);
|
||||
}
|
||||
else
|
||||
MSG_WriteByte (QWWriteDest(dest), val);
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteByte (NQWriteDest(dest), val);
|
||||
else
|
||||
MSG_WriteByte (QWWriteDest(dest), val);
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4475,7 +4483,9 @@ void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteChar(dest, val);
|
||||
return;
|
||||
|
@ -4486,7 +4496,7 @@ void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
NPP_QWWriteChar(dest, val);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4496,8 +4506,12 @@ void QCBUILTIN PF_WriteChar (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
ClientReliableWrite_Char(cl, val);
|
||||
}
|
||||
else
|
||||
MSG_WriteChar (QWWriteDest(dest), val);
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteChar (NQWriteDest(dest), val);
|
||||
else
|
||||
MSG_WriteChar (QWWriteDest(dest), val);
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4517,7 +4531,9 @@ void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteShort(dest, val);
|
||||
return;
|
||||
|
@ -4528,8 +4544,8 @@ void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
NPP_QWWriteShort(dest, val);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (desf == MSG_ONE)
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
if (!cl)
|
||||
|
@ -4538,8 +4554,12 @@ void QCBUILTIN PF_WriteShort (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
ClientReliableWrite_Short(cl, val);
|
||||
}
|
||||
else
|
||||
MSG_WriteShort (QWWriteDest(dest), val);
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteShort (NQWriteDest(dest), val);
|
||||
else
|
||||
MSG_WriteShort (QWWriteDest(dest), val);
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4558,7 +4578,9 @@ void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteLong(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
|
@ -4569,7 +4591,7 @@ void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
NPP_QWWriteLong(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4579,8 +4601,12 @@ void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
ClientReliableWrite_Long(cl, G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
else
|
||||
MSG_WriteLong (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteLong (NQWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
else
|
||||
MSG_WriteLong (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4599,7 +4625,9 @@ void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteAngle(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
|
@ -4610,7 +4638,7 @@ void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
NPP_QWWriteAngle(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4620,8 +4648,12 @@ void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
ClientReliableWrite_Angle(cl, G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
else
|
||||
MSG_WriteAngle (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteAngle (NQWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
else
|
||||
MSG_WriteAngle (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4640,7 +4672,9 @@ void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteCoord(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
|
@ -4651,7 +4685,7 @@ void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
NPP_QWWriteCoord(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4661,8 +4695,12 @@ void QCBUILTIN PF_WriteCoord (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
ClientReliableWrite_Coord(cl, G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
else
|
||||
MSG_WriteCoord (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteCoord (NQWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
else
|
||||
MSG_WriteCoord (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4681,7 +4719,9 @@ void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteFloat(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
|
@ -4692,7 +4732,7 @@ void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
NPP_QWWriteFloat(dest, G_FLOAT(OFS_PARM1));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4702,8 +4742,12 @@ void QCBUILTIN PF_WriteFloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
ClientReliableWrite_Float(cl, G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
else
|
||||
MSG_WriteFloat (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteFloat (NQWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
else
|
||||
MSG_WriteFloat (QWWriteDest(dest), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
}
|
||||
|
||||
void PF_WriteString_Internal (int target, const char *str)
|
||||
|
@ -4721,7 +4765,9 @@ void PF_WriteString_Internal (int target, const char *str)
|
|||
)
|
||||
return;
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteString(target, str);
|
||||
return;
|
||||
|
@ -4732,7 +4778,7 @@ void PF_WriteString_Internal (int target, const char *str)
|
|||
NPP_QWWriteString(target, str);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (target == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4742,8 +4788,12 @@ void PF_WriteString_Internal (int target, const char *str)
|
|||
ClientReliableWrite_String(cl, str);
|
||||
}
|
||||
else
|
||||
MSG_WriteString (QWWriteDest(target), str);
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteString (NQWriteDest(target), str);
|
||||
else
|
||||
MSG_WriteString (QWWriteDest(target), str);
|
||||
}
|
||||
}
|
||||
|
||||
static void QCBUILTIN PF_WriteString (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -4769,7 +4819,9 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
)
|
||||
return;
|
||||
|
||||
if (progstype != PROG_QW)
|
||||
if (dpcompat_nopreparse.ival)
|
||||
;
|
||||
else if (progstype != PROG_QW)
|
||||
{
|
||||
NPP_NQWriteEntity(dest, G_EDICTNUM(prinst, OFS_PARM1));
|
||||
return;
|
||||
|
@ -4780,7 +4832,7 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
NPP_QWWriteEntity(dest, G_EDICTNUM(prinst, OFS_PARM1));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
if (dest == MSG_ONE)
|
||||
{
|
||||
client_t *cl = Write_GetClient();
|
||||
|
@ -4790,8 +4842,12 @@ void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
ClientReliableWrite_Entity(cl, G_EDICTNUM(prinst, OFS_PARM1));
|
||||
}
|
||||
else
|
||||
MSG_WriteEntity (QWWriteDest(dest), G_EDICTNUM(prinst, OFS_PARM1));
|
||||
#endif
|
||||
{
|
||||
if (progstype != PROG_QW)
|
||||
MSG_WriteEntity (NQWriteDest(dest), G_EDICTNUM(prinst, OFS_PARM1));
|
||||
else
|
||||
MSG_WriteEntity (QWWriteDest(dest), G_EDICTNUM(prinst, OFS_PARM1));
|
||||
}
|
||||
}
|
||||
|
||||
//small wrapper function.
|
||||
|
@ -5029,13 +5085,10 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
|
|||
void QCBUILTIN PF_makestatic (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
edict_t *ent;
|
||||
int mdlindex;
|
||||
entity_state_t *state;
|
||||
|
||||
ent = G_EDICT(prinst, OFS_PARM0);
|
||||
|
||||
mdlindex = SV_ModelIndex(PR_GetString(prinst, ent->v->model));
|
||||
|
||||
if (sv.num_static_entities == sv_max_staticentities)
|
||||
{
|
||||
sv_max_staticentities += 16;
|
||||
|
@ -9519,7 +9572,30 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"frameduration", PF_frameduration, 0, 0, 0, 277, D("float(float modidx, float framenum)", "Retrieves the duration (in seconds) of the specified framegroup.")},// (FTE_CSQC_SKELETONOBJECTS)
|
||||
|
||||
{"terrain_edit", PF_terrain_edit, 0, 0, 0, 278, D("void(float action, optional vector pos, optional float radius, optional float quant, ...)", "Realtime terrain editing. Actions are the TEREDIT_ constants.")},// (??FTE_TERRAIN_EDIT??
|
||||
{"touchtriggers", PF_touchtriggers, 0, 0, 0, 279, D("void()", "Triggers a touch events between self and every entity that it is in contact with. This should typically just be the triggers touch functions.")},//
|
||||
|
||||
#define qcbrushface \
|
||||
"typedef struct\n{\n" \
|
||||
"\tstring\tshadername;\n" \
|
||||
"\tvector\tplanenormal;\n" \
|
||||
"\tfloat\tplanedist;\n" \
|
||||
"\tvector\tsdir;\n" \
|
||||
"\tfloat\tsbias;\n" \
|
||||
"\tvector\ttdir;\n" \
|
||||
"\tfloat\ttbias;\n" \
|
||||
"} brushface_t;\n"
|
||||
{"brush_get", PF_brush_get, 0, 0, 0, 0, D(qcbrushface "int(float modelidx, int brushid, brushface_t *out_faces, int maxfaces, int *out_contents)", "Queries a brush's information. You must pre-allocate the face array for the builtin to write to. Return value is the number of faces retrieved, 0 on error.")},
|
||||
{"brush_create", PF_brush_create, 0, 0, 0, 0, D("int(float modelidx, brushface_t *in_faces, int numfaces, int contents)", "Inserts a new brush into the model. Return value is the new brush's id.")},
|
||||
{"brush_delete", PF_brush_delete, 0, 0, 0, 0, D("void(float modelidx, int brushid)", "Destroys the specified brush.")},
|
||||
{"brush_selected", PF_brush_selected, 0, 0, 0, 0, D("float(float modelid, int brushid, int faceid, float selectedstate)", "Allows you to easily set transient visual properties of a brush. returns old value. selectedstate=-1 changes nothing (called for its return value).")},
|
||||
{"brush_getfacepoints",PF_brush_getfacepoints,0,0, 0, 0, D("int(float modelid, int brushid, int faceid, vector *points, int maxpoints)", "Returns the list of verticies surrounding the given face. If face is 0, returns the center of the brush (if space for 1 point) or the mins+maxs (if space for 2 points).")},
|
||||
// {"brush_calcfacepoints",PF_brush_calcfacepoints,0,0, 0, 0, D("int(brushface_t *in_faces, int numfaces, int faceid, vector *points, int maxpoints)", "Returns the list of verticies surrounding the given face. If face is 0, returns the center of the brush (if space for 1 point) or the mins+maxs (if space for 2 points). Returns 0 if a face is degenerate.")},
|
||||
{"brush_findinvolume",PF_brush_findinvolume,0, 0, 0, 0, D("int(float modelid, vector *planes, float *dists, int numplanes, int *out_brushes, int *out_faces, int maxresults)", "Allows you to easily obtain a list of brushes+faces within the given bounding region. If out_faces is not null, the same brush might be listed twice.")},
|
||||
// {"brush_editplane", PF_brush_editplane, 0, 0, 0, 0, D("float(float modelid, int brushid, int faceid, in brushface *face)", "Changes a surface's texture info.")},
|
||||
// {"brush_transformselected",PF_brush_transformselected,0,0,0, 0, D("int(float modelid, int brushid, float *matrix)", "Transforms selected brushes by the given transform")},
|
||||
|
||||
|
||||
|
||||
{"touchtriggers", PF_touchtriggers, 0, 0, 0, 279, D("void(optional entity ent, optional vector neworigin)", "Triggers a touch events between self and every SOLID_TRIGGER entity that it is in contact with. This should typically just be the triggers touch functions. Also optionally updates the origin of the moved entity.")},//
|
||||
{"WriteFloat", PF_WriteFloat, 0, 0, 0, 280, "void(float buf, float fl)"},//
|
||||
{"skel_ragupdate", PF_skel_ragedit, 0, 0, 0, 281, D("float(entity skelent, string dollcmd, float animskel)", "Updates the skeletal object attached to the entity according to its origin and other properties.\nif animskel is non-zero, the ragdoll will animate towards the bone state in the animskel skeletal object, otherwise they will pick up the model's base pose which may not give nice results.\nIf dollcmd is not set, the ragdoll will update (this should be done each frame).\nIf the doll is updated without having a valid doll, the model's default .doll will be instanciated.\ncommands:\n doll foo.doll : sets up the entity to use the named doll file\n dollstring TEXT : uses the doll file directly embedded within qc, with that extra prefix.\n cleardoll : uninstanciates the doll without destroying the skeletal object.\n animate 0.5 : specifies the strength of the ragdoll as a whole \n animatebody somebody 0.5 : specifies the strength of the ragdoll on a specific body (0 will disable ragdoll animations on that body).\n enablejoint somejoint 1 : enables (or disables) a joint. Disabling joints will allow the doll to shatter.")}, // (FTE_CSQC_RAGDOLL)
|
||||
{"skel_mmap", PF_skel_mmap, 0, 0, 0, 282, D("float*(float skel)", "Map the bones in VM memory. They can then be accessed via pointers. Each bone is 12 floats, the four vectors interleaved (sadly).")},// (FTE_QC_RAGDOLL)
|
||||
|
@ -9662,6 +9738,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"con_printf", PF_Fixme, 0, 0, 0, 392, D("void(string conname, string messagefmt, ...)", "Prints onto a named console.")},
|
||||
{"con_draw", PF_Fixme, 0, 0, 0, 393, D("void(string conname, vector pos, vector size, float fontsize)", "Draws the named console.")},
|
||||
{"con_input", PF_Fixme, 0, 0, 0, 394, D("float(string conname, float inevtype, float parama, float paramb, float paramc)", "Forwards input events to the named console. Mouse updates should be absolute only.")},
|
||||
{"cvar_unsaved", PF_Fixme, 0, 0, 0, 0, D("float()", "Returns true if any archived cvar has an unsaved value.")},
|
||||
//end fte extras
|
||||
|
||||
//DP extras
|
||||
|
@ -9822,7 +9899,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"cvar_type", PF_cvar_type, 0, 0, 0, 495, "float(string name)"},//DP_QC_CVAR_TYPE
|
||||
{"numentityfields", PF_numentityfields, 0, 0, 0, 496, D("float()", "Gives the number of named entity fields. Note that this is not the size of an entity, but rather just the number of unique names (ie: vectors use 4 names rather than 3).")},//DP_QC_ENTITYDATA
|
||||
{"findentityfield", PF_findentityfield, 0, 0, 0, 0, D("float(string fieldname)", "Find a field index by name.")},
|
||||
{"entityfieldref", PF_entityfieldref, 0, 0, 0, 0, D(".__variant(float fieldnum)", "Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using.")},//DP_QC_ENTITYDATA
|
||||
{"entityfieldref", PF_entityfieldref, 0, 0, 0, 0, D("typedef .__variant field_t;\nfield_t(float fieldnum)", "Returns a field value that can be directly used to read entity fields. Be sure to validate the type with entityfieldtype before using.")},//DP_QC_ENTITYDATA
|
||||
{"entityfieldname", PF_entityfieldname, 0, 0, 0, 497, D("string(float fieldnum)", "Retrieves the name of the given entity field.")},//DP_QC_ENTITYDATA
|
||||
{"entityfieldtype", PF_entityfieldtype, 0, 0, 0, 498, D("float(float fieldnum)", "Provides information about the type of the field specified by the field num. Returns one of the EV_ values.")},//DP_QC_ENTITYDATA
|
||||
{"getentityfieldstring",PF_getentityfieldstring,0,0, 0, 499, "string(float fieldnum, entity ent)"},//DP_QC_ENTITYDATA
|
||||
|
@ -10534,6 +10611,9 @@ void PR_DumpPlatform_f(void)
|
|||
{"input_cursor_trace_endpos", "vector", CS/*|QW|NQ*/},
|
||||
{"input_cursor_trace_entnum", "float", CS/*|QW|NQ*/},
|
||||
|
||||
{"trace_brush_id", "float", QW|NQ|CS},
|
||||
{"trace_brush_faceid", "float", QW|NQ|CS},
|
||||
|
||||
#define comfieldfloat(name,desc) {#name, ".float", FL, desc},
|
||||
#define comfieldvector(name,desc) {#name, ".vector", FL, desc},
|
||||
#define comfieldentity(name,desc) {#name, ".entity", FL, desc},
|
||||
|
@ -10603,7 +10683,7 @@ void PR_DumpPlatform_f(void)
|
|||
|
||||
{"GameCommand", "noref void(string cmdtext)", CS|MENU},
|
||||
|
||||
{"init", "noref void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget)."},
|
||||
{"init", "noref void(float prevprogs)", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget)."},
|
||||
{"initents", "noref void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules."},
|
||||
|
||||
{"m_init", "void()", MENU},
|
||||
|
@ -10870,6 +10950,7 @@ void PR_DumpPlatform_f(void)
|
|||
|
||||
{"gamestate", "hashtable", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0},
|
||||
{"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 256},
|
||||
{"HASH_ADD", "const float", ALL, "Used with hash_add. The new entry will be inserted in addition to the existing entry.", 512},
|
||||
|
||||
{"STAT_HEALTH", "const float", CS, "Player's health.", STAT_HEALTH},
|
||||
{"STAT_WEAPONMODELI", "const float", CS, "This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions).", STAT_WEAPONMODELI},
|
||||
|
@ -10920,7 +11001,7 @@ void PR_DumpPlatform_f(void)
|
|||
{"VF_CL_VIEWANGLES_Z", "const float", CS, NULL, VF_CL_VIEWANGLES_Z},
|
||||
|
||||
{"VF_PERSPECTIVE", "const float", CS|MENU, "1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport.", VF_PERSPECTIVE},
|
||||
{"VF_LPLAYER", "const float", CS, "The 'seat' number, used when running splitscreen.", VF_LPLAYER},
|
||||
{"VF_ACTIVESEAT", "#define VF_LPLAYER VF_ACTIVESEAT\nconst float", CS, "The 'seat' number, used when running splitscreen.", VF_ACTIVESEAT},
|
||||
{"VF_AFOV", "const float", CS|MENU, "Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you.", VF_AFOV},
|
||||
{"VF_SCREENVSIZE", "const float", CS|MENU, "Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect).", VF_SCREENVSIZE},
|
||||
{"VF_SCREENPSIZE", "const float", CS|MENU, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE},
|
||||
|
@ -11561,19 +11642,19 @@ void PR_DumpPlatform_f(void)
|
|||
VFS_PRINTF(f,
|
||||
"accessor hashtable : float\n{\n"
|
||||
"\tinline get vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);};\n"
|
||||
"\tinline set vector v[string key] = {hash_add(this, key, value, 1, EV_VECTOR);};\n"
|
||||
"\tinline set vector v[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_VECTOR);};\n"
|
||||
"\tinline get string s[string key] = {return hash_get(this, key, \"\", EV_STRING);};\n"
|
||||
"\tinline set string s[string key] = {hash_add(this, key, value, 1, EV_STRING);};\n"
|
||||
"\tinline set string s[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_STRING);};\n"
|
||||
"\tinline get string f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);};\n"
|
||||
"\tinline set string f[string key] = {hash_add(this, key, value, 1, EV_FLOAT);};\n"
|
||||
"\tinline set string f[string key] = {hash_add(this, key, value, HASH_REPLACE|EV_FLOAT);};\n"
|
||||
"\tinline get __variant[string key] = {return hash_get(this, key, __NULL__);};\n"
|
||||
"\tinline set __variant[string key] = {hash_add(this, key, value, 1);};\n"
|
||||
"\tinline set __variant[string key] = {hash_add(this, key, value, HASH_REPLACE);};\n"
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
"accessor infostring : string\n{\n"
|
||||
"\tget string[string] = infoget;\n"
|
||||
#ifdef QCGC
|
||||
"\tinline set* string[string] = {(*this) = infoadd(*this, value);};\n"
|
||||
"\tinline set* string[string fld] = {(*this) = infoadd(*this, fld, value);};\n"
|
||||
#endif
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
|
|
|
@ -93,8 +93,18 @@ typedef struct
|
|||
char fatness;
|
||||
} mvdentity_state_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t position;
|
||||
unsigned short soundnum;
|
||||
qbyte volume;
|
||||
qbyte attenuation;
|
||||
} staticsound_state_t;
|
||||
|
||||
extern entity_state_t *sv_staticentities;
|
||||
extern int sv_max_staticentities;
|
||||
extern staticsound_state_t *sv_staticsounds;
|
||||
extern int sv_max_staticsounds;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -271,6 +281,7 @@ typedef struct
|
|||
//end this lot... (demo playback)
|
||||
|
||||
int num_static_entities;
|
||||
int num_static_sounds;
|
||||
|
||||
svcustomtents_t customtents[255];
|
||||
|
||||
|
@ -354,6 +365,7 @@ enum
|
|||
PRESPAWN_CUSTOMTENTS,
|
||||
PRESPAWN_SIGNON_BUF,
|
||||
PRESPAWN_SPAWNSTATIC,
|
||||
PRESPAWN_AMBIENTSOUND,
|
||||
PRESPAWN_BASELINES,
|
||||
PRESPAWN_DONE
|
||||
};
|
||||
|
@ -376,6 +388,8 @@ typedef struct client_s
|
|||
|
||||
unsigned int prespawn_stage;
|
||||
unsigned int prespawn_idx;
|
||||
qboolean prespawn_allow_modellist;
|
||||
qboolean prespawn_allow_soundlist;
|
||||
|
||||
int spectator; // non-interactive
|
||||
int redirect;
|
||||
|
|
|
@ -349,12 +349,20 @@ static int QDECL ShowMapList (const char *name, qofs_t flags, time_t mtime, void
|
|||
if (name[5] == 'b' && name[6] == '_') //skip box models
|
||||
return true;
|
||||
COM_StripExtension(name+5, stripped, sizeof(stripped));
|
||||
Con_Printf("^[%s\\map\\%s^]\n", stripped, stripped);
|
||||
Con_Printf("^[[%s]\\map\\%s^]\n", stripped, stripped);
|
||||
return true;
|
||||
}
|
||||
static int QDECL ShowMapListExt (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
if (name[5] == 'b' && name[6] == '_') //skip box models
|
||||
return true;
|
||||
Con_Printf("^[[%s]\\map\\%s^]\n", name+5, name+5);
|
||||
return true;
|
||||
}
|
||||
static void SV_MapList_f(void)
|
||||
{
|
||||
COM_EnumerateFiles("maps/*.bsp", ShowMapList, NULL);
|
||||
COM_EnumerateFiles("maps/*.map", ShowMapListExt, NULL);
|
||||
COM_EnumerateFiles("maps/*.cm", ShowMapList, NULL);
|
||||
COM_EnumerateFiles("maps/*.hmp", ShowMapList, NULL);
|
||||
}
|
||||
|
@ -413,7 +421,10 @@ void SV_Map_f (void)
|
|||
|
||||
if (Cmd_Argc() != 2 && Cmd_Argc() != 3)
|
||||
{
|
||||
Con_TPrintf ("%s <levelname> <startspot>: change the level\n", Cmd_Argv(0));
|
||||
if (Cmd_IsInsecure())
|
||||
return;
|
||||
Con_TPrintf ("Available maps:\n", Cmd_Argv(0));
|
||||
SV_MapList_f();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -458,7 +469,7 @@ void SV_Map_f (void)
|
|||
if (!strcmp(level, ".")) //restart current
|
||||
{
|
||||
//grab the current map name
|
||||
COM_StripExtension(COM_SkipPath(sv.modelname), level, sizeof(level));
|
||||
Q_strncpyz(level, sv.name, sizeof(level));
|
||||
isrestart = true;
|
||||
flushparms = false;
|
||||
newunit = false;
|
||||
|
@ -505,7 +516,7 @@ void SV_Map_f (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
char *exts[] = {"maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", "maps/%s.map", NULL};
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ NULL};
|
||||
int i, j;
|
||||
|
||||
for (i = 0; exts[i]; i++)
|
||||
|
|
|
@ -30,6 +30,8 @@ server_t sv; // local server
|
|||
|
||||
entity_state_t *sv_staticentities;
|
||||
int sv_max_staticentities;
|
||||
staticsound_state_t *sv_staticsounds;
|
||||
int sv_max_staticsounds;
|
||||
|
||||
char localinfo[MAX_LOCALINFO_STRING+1]; // local game info
|
||||
|
||||
|
@ -937,7 +939,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
else
|
||||
#endif
|
||||
{
|
||||
char *exts[] = {"maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", "maps/%s.map", NULL};
|
||||
//.map is commented out because quite frankly, they're a bit annoying when the engine loads the gpled start.map when really you wanted to just play the damn game intead of take it apart.
|
||||
//if you want to load a .map, just use 'map foo.map' instead.
|
||||
char *exts[] = {"maps/%s", "maps/%s.bsp", "maps/%s.cm", "maps/%s.hmp", /*"maps/%s.map",*/ NULL};
|
||||
int depth, bestdepth;
|
||||
Q_strncpyz (sv.name, server, sizeof(sv.name));
|
||||
Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[0], server);
|
||||
|
@ -1004,7 +1008,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
|||
sv.csqcchecksum = Com_BlockChecksum(file, fsz);
|
||||
sprintf(text, "0x%x", sv.csqcchecksum);
|
||||
Info_SetValueForStarKey(svs.info, "*csprogs", text, MAX_SERVERINFO_STRING);
|
||||
sprintf(text, "0x%x", fsz);
|
||||
sprintf(text, "0x%x", (unsigned int)fsz);
|
||||
Info_SetValueForStarKey(svs.info, "*csprogssize", text, MAX_SERVERINFO_STRING);
|
||||
if (strcmp(sv_csqc_progname.string, "csprogs.dat"))
|
||||
Info_SetValueForStarKey(svs.info, "*csprogsname", sv_csqc_progname.string, MAX_SERVERINFO_STRING);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue