1
0
Fork 0
forked from fte/fteqw

Added console-links support.

Shift click IPs/words/links on the console to enter them as arguments.
Fixed some utf-8 issues.
Fixed issue with csaddon.dat not loading in release builds.
Fixed berkelium inputs, should have a full range of keys now, though there's still no 'back' support.
Bad name rejection made more paranoid.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4124 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-10-13 00:56:31 +00:00
parent fc2ab857f5
commit 5d9ba4b548
20 changed files with 866 additions and 179 deletions

View file

@ -1024,30 +1024,30 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
{
char *s;
qboolean anycsqc;
char *endptr;
unsigned int chksum;
#ifdef _DEBUG
anycsqc = true;
#else
anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc"));
#endif
if (cls.demoplayback)
anycsqc = true;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (anycsqc || *s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
chksum = strtoul(s, &endptr, 0);
if (*endptr)
{
char *endptr;
unsigned int chksum = strtoul(s, &endptr, 0);
if (*endptr)
{
Con_Printf("corrupt *csprogs key in serverinfo\n");
anycsqc = true;
chksum = 0;
}
SCR_SetLoadingFile("csprogs");
if (!CSQC_Init(anycsqc, chksum))
{
Sbar_Start(); //try and start this before we're actually on the server,
//this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load.
//hopefully this'll make it more robust.
//csqc is expected to use it's own huds, or to run on decent servers. :p
}
Con_Printf("corrupt *csprogs key in serverinfo\n");
anycsqc = true;
chksum = 0;
}
SCR_SetLoadingFile("csprogs");
if (!CSQC_Init(anycsqc, *s?true:false, chksum))
{
Sbar_Start(); //try and start this before we're actually on the server,
//this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load.
//hopefully this'll make it more robust.
//csqc is expected to use it's own huds, or to run on decent servers. :p
}
endstage();
}
@ -1285,7 +1285,6 @@ Sound_NextDownload
*/
void Sound_CheckDownloads (void)
{
char *s;
int i;
@ -1294,6 +1293,7 @@ void Sound_CheckDownloads (void)
#ifdef CSQC_DAT
// if (cls.fteprotocolextensions & PEXT_CSQC)
{
char *s;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s) //only allow csqc if the server says so, and the 'checksum' matches.
{
@ -2843,8 +2843,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
#ifdef PEXT_CSQC
CSQC_Shutdown();
if (cls.demoplayback)
CSQC_Init(true, 0);
CSQC_Init(cls.demoplayback, false, 0);
#endif
}
void CLNQ_SignonReply (void)
@ -2881,10 +2880,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
{
char *s;
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s)
CSQC_Init(false, atoi(s));
else
CSQC_Shutdown();
CSQC_Init(false, *s?true:false, atoi(s));
}
#endif
}
@ -4786,18 +4782,15 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags)
if (plrflags & (TPM_TEAM|TPM_OBSERVEDTEAM)) // for team chat don't highlight the name, just the brackets
{
// color is reset every printf so we're safe here
Q_strncatz(fullchatmessage, va("\1(%s^%c", name_coloured?"":"^m", c), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("%s%s^d", name_coloured?"^m":"", name), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("%s^%c)", name_coloured?"^m":"", c), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("\1(^[%s%s^d\\player\\%i^])", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
}
else if (cl_standardchat.ival)
{
Q_strncatz(fullchatmessage, va("\1%s", name), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("\1^[%s%s^d\\player\\%i^]", name_coloured?"^m":"", name, plr-cl.players), sizeof(fullchatmessage));
}
else
{
Q_strncatz(fullchatmessage, va("\1%s^%c%s^d", name_coloured?"":"^m", c, name), sizeof(fullchatmessage));
Q_strncatz(fullchatmessage, va("\1^[%s^%c%s^d\\player\\%i^]", name_coloured?"^m":"", c, name, plr-cl.players), sizeof(fullchatmessage));
}
if (!memessage)
@ -4935,7 +4928,7 @@ void CL_PrintStandardMessage(char *msg, int printlevel)
c = '0' + CL_PlayerColor(p, &coloured);
// print name
Q_strncatz(fullmessage, va("%s^%c%s^7%s", coloured?"^m":"", c, name, coloured?"^m":""), sizeof(fullmessage));
Q_strncatz(fullmessage, va("^[%s^%c%s^d\\player\\%i^]", coloured?"^m":"", c, name, p - cl.players), sizeof(fullmessage));
break;
}
}

View file

@ -1075,7 +1075,8 @@ char *CG_GetConfigString(int num);
#ifdef CSQC_DAT
qboolean CSQC_Inited(void);
void CSQC_RendererRestarted(void);
qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum);
qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checksum);
qboolean CSQC_ConsoleLink(char *text, char *info);
void CSQC_RegisterCvarsAndThings(void);
qboolean CSQC_DrawView(void);
void CSQC_Shutdown(void);

View file

@ -848,7 +848,7 @@ int Con_DrawInput (int left, int right, int y)
text[key_linepos] = 0;
cursor = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext) - sizeof(maskedtext[0]), true);
text[key_linepos] = i;
endmtext = COM_ParseFunString(CON_WHITEMASK, text, maskedtext, sizeof(maskedtext) - sizeof(maskedtext[0]), true);
endmtext = COM_ParseFunString(CON_WHITEMASK, text+key_linepos, cursor, ((char*)maskedtext)+sizeof(maskedtext) - (char*)(cursor+1), true);
endmtext[1] = 0;
@ -890,11 +890,11 @@ int Con_DrawInput (int left, int right, int y)
#endif
cursorframe = ((int)(realtime*con_cursorspeed)&1);
for (lhs = 0, i = key_linepos-1; i >= 0; i--)
for (lhs = 0, i = cursor - maskedtext-1; i >= 0; i--)
{
lhs += Font_CharWidth(maskedtext[i]);
}
for (rhs = 0, i = key_linepos+1; maskedtext[i]; i++)
for (rhs = 0, i = cursor - maskedtext; maskedtext[i]; i++)
{
rhs += Font_CharWidth(maskedtext[i]);
}
@ -1575,11 +1575,12 @@ void Con_DrawConsole (int lines, qboolean noback)
char *Con_CopyConsole(void)
char *Con_CopyConsole(qboolean nomarkup)
{
conchar_t *cur;
conline_t *l;
conchar_t *lend;
conchar_t col = CON_WHITEMASK;
char *result;
int outlen, maxlen;
int finalendoffset;
@ -1590,6 +1591,9 @@ char *Con_CopyConsole(void)
maxlen = 1024*1024;
result = Z_Malloc(maxlen+1);
// for (cur = (conchar_t*)(selstartline+1), finalendoffset = 0; cur < (conchar_t*)(selstartline+1) + selstartline->length; cur++, finalendoffset++)
// result[finalendoffset] = *cur & 0xffff;
l = selstartline;
cur = (conchar_t*)(l+1) + selstartoffset;
finalendoffset = selendoffset;
@ -1603,21 +1607,48 @@ char *Con_CopyConsole(void)
while (cur > (conchar_t*)(l+1))
{
cur--;
if ((*cur & 0xff) == ' ')
if ((*cur & CON_CHARMASK) == ' ')
{
cur++;
break;
}
if (*cur == CON_LINKSTART)
break;
}
while (finalendoffset < selendline->length)
{
if ((((conchar_t*)(l+1))[finalendoffset] & 0xff) != ' ')
if ((((conchar_t*)(l+1))[finalendoffset] & CON_CHARMASK) != ' ')
finalendoffset++;
else
break;
}
}
}
//scan backwards to find any link enclosure
for(lend = cur; lend >= (conchar_t*)(l+1); lend--)
{
if (*lend == CON_LINKSTART)
{
//found one
cur = lend;
break;
}
if (*lend == CON_LINKEND)
{
//some other link ended here. don't use its start.
break;
}
}
//scan forwards to find the end of the selected link
for(lend = (conchar_t*)(selendline+1) + finalendoffset; lend < (conchar_t*)(selendline+1) + selendline->length; lend++)
{
if (*lend == CON_LINKEND)
{
finalendoffset = lend+1 - (conchar_t*)(selendline+1);
break;
}
}
outlen = 0;
for (;;)
@ -1626,12 +1657,8 @@ char *Con_CopyConsole(void)
lend = (conchar_t*)(l+1) + finalendoffset;
else
lend = (conchar_t*)(l+1) + l->length;
while (cur < lend)
{
if (outlen == maxlen)
break;
result[outlen++] = *cur++;
}
outlen = COM_DeFunString(cur, lend, result + outlen, maxlen - outlen, nomarkup) - result;
if (l == selendline)
break;
@ -1642,6 +1669,9 @@ char *Con_CopyConsole(void)
Con_Printf("Error: Bad console buffer\n");
break;
}
if (outlen+3 > maxlen)
break;
#ifdef _WIN32
result[outlen++] = '\r';
#endif

View file

@ -409,6 +409,12 @@ qboolean Key_GetConsoleSelectionBox(int *sx, int *sy, int *ex, int *ey)
con_mousedown[1] -= 8;
con_current->display = con_current->display->newer;
}
*sx = mousecursor_x;
*sy = mousecursor_y;
*ex = mousecursor_x;
*ey = mousecursor_y;
return true;
}
else if (con_mousedown[2] == 2)
{
@ -421,16 +427,253 @@ qboolean Key_GetConsoleSelectionBox(int *sx, int *sy, int *ex, int *ey)
return false;
}
/*insert the given text at the console input line at the current cursor pos*/
void Key_ConsoleInsert(char *instext)
{
int i;
int len;
len = strlen(instext);
if (len + strlen(key_lines[edit_line]) > MAXCMDLINE - 1)
len = MAXCMDLINE - 1 - strlen(key_lines[edit_line]);
if (len > 0)
{ // insert the string
memmove (key_lines[edit_line] + key_linepos + len,
key_lines[edit_line] + key_linepos, strlen(key_lines[edit_line]) - key_linepos + 1);
memcpy (key_lines[edit_line] + key_linepos, instext, len);
for (i = 0; i < len; i++)
{
if (key_lines[edit_line][key_linepos+i] == '\r')
key_lines[edit_line][key_linepos+i] = ' ';
else if (key_lines[edit_line][key_linepos+i] == '\n')
key_lines[edit_line][key_linepos+i] = ';';
}
key_linepos += len;
}
}
void Key_ConsoleRelease(int key, int unicode)
{
extern int mousecursor_x, mousecursor_y;
char *buffer;
if (key == K_MOUSE1)
{
con_mousedown[2] = 0;
if (abs(con_mousedown[0] - mousecursor_x) < 5 && abs(con_mousedown[1] - mousecursor_y) < 5)
{
buffer = Con_CopyConsole(false);
if (!buffer)
return;
if (keydown[K_SHIFT])
{
int len;
len = strlen(buffer);
//strip any trailing dots/elipsis
while (len > 1 && !strcmp(buffer+len-1, "."))
{
len-=1;
buffer[len] = 0;
}
//strip any enclosing quotes
while (*buffer == '\"' && len > 2 && !strcmp(buffer+len-1, "\""))
{
len-=2;
memmove(buffer, buffer+1, len);
buffer[len] = 0;
}
Key_ConsoleInsert(buffer);
}
else
{
if (buffer[0] == '^' && buffer[1] == '[')
{
//looks like it might be a link!
char *end = NULL;
char *info;
for (info = buffer + 2; *info; )
{
if (info[0] == '^' && info[1] == ']')
{
break;
}
if (*info == '\\')
break;
else if (info[0] == '^' && info[1] == '^')
info+=2;
else
info++;
}
for(end = info; *end; )
{
if (end[0] == '^' && end[1] == ']')
{
char *c;
//okay, its a valid link that they clicked
*end = 0;
#ifdef CSQC_DAT
if (!CSQC_ConsoleLink(buffer+2, info))
#endif
{
/*the engine supports specific default links*/
/*we don't support everything. a: there's no point. b: unbindall links are evil.*/
c = Info_ValueForKey(info, "player");
if (*c)
{
unsigned int player = atoi(c);
int i;
if (player >= MAX_CLIENTS)
break;
c = Info_ValueForKey(info, "action");
if (*c)
{
if (!strcmp(c, "mute"))
{
if (!cl.players[player].vignored)
{
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] muted\n", cl.players[player].name, player);
}
else
{
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unmuted\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "ignore"))
{
if (!cl.players[player].ignored)
{
cl.players[player].ignored = true;
cl.players[player].vignored = true;
Con_Printf("^[%s\\player\\%i^] ignored\n", cl.players[player].name, player);
}
else
{
cl.players[player].ignored = false;
cl.players[player].vignored = false;
Con_Printf("^[%s\\player\\%i^] unignored\n", cl.players[player].name, player);
}
}
else if (!strcmp(c, "kick"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nclientkick %i\n", player), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon kick %s\n", cl.players[player].name), RESTRICT_LOCAL);
}
else if (!strcmp(c, "ban"))
{
#ifndef CLIENTONLY
if (sv.active)
{
//use the q3 command, because we can.
Cbuf_AddText(va("\nbanname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
else
#endif
Cbuf_AddText(va("\nrcon banname %s QuickBan\n", cl.players[player].name), RESTRICT_LOCAL);
}
break;
}
Con_Printf("^m#^m ^[%s\\player\\%i^]: %if %ims", cl.players[player].name, player, cl.players[player].frags, cl.players[player].ping);
for (i = 0; i < cl.splitclients; i++)
{
if (cl.playernum[i] == player)
break;
}
if (i == cl.splitclients)
{
extern cvar_t rcon_password;
if (cls.protocol == CP_QUAKEWORLD && strcmp(cl.players[cl.playernum[0]].team, cl.players[player].team))
Con_Printf(" ^[[Join Team %s]\\cmd\\setinfo team %s^]", cl.players[player].team, cl.players[player].team);
Con_Printf(" ^[%sgnore\\player\\%i\\action\\ignore^]", cl.players[player].ignored?"Uni":"I", player);
// if (cl_voip_play.ival)
Con_Printf(" ^[%sute\\player\\%i\\action\\mute^]", cl.players[player].vignored?"Unm":"M", player);
if (*rcon_password.string
#ifndef CLIENTONLY
|| (sv.state && svs.clients[player].netchan.remote_address.type != NA_LOOPBACK)
#endif
)
{
Con_Printf(" ^[Kick\\player\\%i\\action\\kick^]", player);
Con_Printf(" ^[Ban\\player\\%i\\action\\ban^]", player);
}
}
else
{
char cmdprefix[6];
snprintf(cmdprefix, sizeof(cmdprefix), "%i ", i);
//hey look! its you!
Con_Printf(" ^[Suicide\\cmd\\kill^]");
#ifndef CLIENTONLY
if (!sv.state)
Con_Printf(" ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats || (sv.state && sv.allocated_client_slots == 1))
#else
Con_Printf(" ^[Disconnect\\cmd\\disconnect^]");
if (cls.allow_cheats)
#endif
{
Con_Printf(" ^[Noclip\\cmd\\noclip^]");
Con_Printf(" ^[Fly\\cmd\\fly^]");
Con_Printf(" ^[God\\cmd\\god^]");
Con_Printf(" ^[Give\\impulse\\9^]");
}
}
Con_Printf("\r");
break;
}
c = Info_ValueForKey(info, "connect");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nconnect %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "qtv");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nqtvplay %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "cmd");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\ncmd %s\n", c), RESTRICT_LOCAL);
break;
}
c = Info_ValueForKey(info, "impulse");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nimpulse %s\n", c), RESTRICT_LOCAL);
break;
}
}
break;
}
if (end[0] == '^' && end[1] == '^')
end+=2;
else
end++;
}
}
}
Z_Free(buffer);
}
}
if (key == K_MOUSE2 && con_mousedown[2] == 2)
{
extern int mousecursor_x, mousecursor_y;
char *buffer;
con_mousedown[2] = 0;
buffer = Con_CopyConsole();
buffer = Con_CopyConsole(true); //don't keep markup if we're copying to the clipboard
if (!buffer)
return;
Sys_SaveClipboard(buffer);
@ -439,6 +682,91 @@ void Key_ConsoleRelease(int key, int unicode)
}
}
//move the cursor one char to the left. cursor must be within the 'start' string.
unsigned char *utf_left(unsigned char *start, unsigned char *cursor)
{
extern cvar_t com_parseutf8;
if (cursor == start)
return cursor;
if (com_parseutf8.ival>0)
{
cursor--;
while ((*cursor & 0xc0) == 0x80 && cursor > start)
cursor--;
}
else
cursor--;
if (*cursor == ']' && cursor > start && cursor[-1] == '^')
{
//just stepped onto a link
char *linkstart;
linkstart = cursor-1;
while(linkstart >= start)
{
if (linkstart[0] == '^' && linkstart[1] == '[')
return linkstart;
linkstart--;
}
}
return cursor;
}
//move the cursor one char to the right.
unsigned char *utf_right(unsigned char *cursor)
{
extern cvar_t com_parseutf8;
if (*cursor == '^' && cursor[1] == '[')
{
//just stepped over a link
char *linkend;
linkend = cursor+2;
while(*linkend)
{
if (linkend[0] == '^' && linkend[1] == '^')
linkend += 2;
else if (linkend[0] == '^' && linkend[1] == ']')
return linkend+2;
else
linkend++;
}
return linkend;
}
if (com_parseutf8.ival>0)
{
int skip = 1;
//figure out the length of the char
if ((*cursor & 0xc0) == 0x80)
skip = 1; //error
else if ((*cursor & 0xe0) == 0xc0)
skip = 2;
else if ((*cursor & 0xf0) == 0xe0)
skip = 3;
else if ((*cursor & 0xf1) == 0xf0)
skip = 4;
else if ((*cursor & 0xf3) == 0xf1)
skip = 5;
else if ((*cursor & 0xf7) == 0xf3)
skip = 6;
else if ((*cursor & 0xff) == 0xf7)
skip = 7;
else skip = 1;
while (*cursor && skip)
{
cursor++;
skip--;
}
}
else if (*cursor)
cursor++;
return cursor;
}
/*
====================
Key_Console
@ -544,15 +872,14 @@ void Key_Console (unsigned int unicode, int key)
if (key == K_LEFTARROW)
{
if (key_linepos > 1)
key_linepos--;
key_linepos = utf_left(key_lines[edit_line]+1, key_lines[edit_line] + key_linepos) - key_lines[edit_line];
return;
}
if (key == K_RIGHTARROW)
{
if (key_lines[edit_line][key_linepos])
{
key_linepos++;
key_linepos = utf_right(key_lines[edit_line] + key_linepos) - key_lines[edit_line];
return;
}
else
@ -563,15 +890,8 @@ void Key_Console (unsigned int unicode, int key)
{
if (key_lines[edit_line][key_linepos])
{
int charlen = 1;
if (com_parseutf8.ival>0 &&
(key_lines[edit_line][key_linepos] & 0xc0) != 0x80)
{
while((key_lines[edit_line][key_linepos+charlen] & 0xc0) == 0x80)
charlen++;
}
memmove(key_lines[edit_line]+key_linepos, key_lines[edit_line]+key_linepos+charlen, strlen(key_lines[edit_line]+key_linepos+charlen)+charlen);
int charlen = utf_right(key_lines[edit_line] + key_linepos) - (key_lines[edit_line] + key_linepos);
memmove(key_lines[edit_line]+key_linepos, key_lines[edit_line]+key_linepos+charlen, strlen(key_lines[edit_line]+key_linepos+charlen)+1);
return;
}
else
@ -582,13 +902,8 @@ void Key_Console (unsigned int unicode, int key)
{
if (key_linepos > 1)
{
int charlen = 1;
if (com_parseutf8.ival>0)
{
while (key_linepos > charlen && (key_lines[edit_line][key_linepos-charlen] & 0xc0) == 0x80)
charlen++;
}
memmove(key_lines[edit_line]+key_linepos-charlen, key_lines[edit_line]+key_linepos, strlen(key_lines[edit_line]+key_linepos)+charlen);
int charlen = (key_lines[edit_line]+key_linepos) - utf_left(key_lines[edit_line]+1, key_lines[edit_line] + key_linepos);
memmove(key_lines[edit_line]+key_linepos-charlen, key_lines[edit_line]+key_linepos, strlen(key_lines[edit_line]+key_linepos)+1);
key_linepos -= charlen;
}
return;
@ -692,36 +1007,19 @@ void Key_Console (unsigned int unicode, int key)
return;
}
if (((unicode=='C' || unicode=='c') && keydown[K_CTRL]) || (keydown[K_CTRL] && key == K_INS))
//beware that windows translates ctrl+c and ctrl+v to a control char
if (((unicode=='C' || unicode=='c' || unicode==3) && keydown[K_CTRL]) || (keydown[K_CTRL] && key == K_INS))
{
Sys_SaveClipboard(key_lines[edit_line]+1);
return;
}
if (((unicode=='V' || unicode=='v') && keydown[K_CTRL]) || (keydown[K_SHIFT] && key == K_INS))
if (((unicode=='V' || unicode=='v' || unicode==22) && keydown[K_CTRL]) || (keydown[K_SHIFT] && key == K_INS))
{
clipText = Sys_GetClipboard();
if (clipText)
{
int i;
int len;
len = strlen(clipText);
if (len + strlen(key_lines[edit_line]) > MAXCMDLINE - 1)
len = MAXCMDLINE - 1 - strlen(key_lines[edit_line]);
if (len > 0)
{ // insert the string
memmove (key_lines[edit_line] + key_linepos + len,
key_lines[edit_line] + key_linepos, strlen(key_lines[edit_line]) - key_linepos + 1);
memcpy (key_lines[edit_line] + key_linepos, clipText, len);
for (i = 0; i < len; i++)
{
if (key_lines[edit_line][key_linepos+i] == '\r')
key_lines[edit_line][key_linepos+i] = ' ';
else if (key_lines[edit_line][key_linepos+i] == '\n')
key_lines[edit_line][key_linepos+i] = ';';
}
key_linepos += len;
}
Key_ConsoleInsert(clipText);
Sys_CloseClipboard(clipText);
}
return;
@ -1466,7 +1764,7 @@ void Key_Event (int devid, int key, unsigned int unicode, qboolean down)
//yes, csqc is allowed to steal the escape key.
if (key != '`' && key != '~')
if (key_dest == key_game)
if (key_dest == key_game && !Media_PlayingFullScreen())
{
#ifdef CSQC_DAT
if (CSQC_KeyPress(key, unicode, down, devid)) //give csqc a chance to handle it.

View file

@ -2199,6 +2199,8 @@ qboolean Media_PlayFilm(char *name)
cin->ended = false;
if (cin->rewind)
cin->rewind(cin);
if (cin->changestream)
cin->changestream(cin, "cmd:focus");
}
else
{

View file

@ -107,6 +107,7 @@ extern sfx_t *cl_sfx_r_exp3;
globalfunction(input_event, "CSQC_InputEvent"); \
globalfunction(input_frame, "CSQC_Input_Frame");/*EXT_CSQC_1*/ \
globalfunction(console_command, "CSQC_ConsoleCommand"); \
globalfunction(console_link, "CSQC_ConsoleLink"); \
globalfunction(gamecommand, "GameCommand"); /*DP extension*/\
\
globalfunction(ent_update, "CSQC_Ent_Update"); \
@ -1251,6 +1252,15 @@ static void QCBUILTIN PF_R_GetViewFlag(progfuncs_t *prinst, struct globalvars_s
*r = r_refdef.useperspective;
break;
case VF_SCREENVSIZE:
r[0] = vid.width;
r[1] = vid.height;
break;
case VF_SCREENPSIZE:
r[0] = vid.rotpixelwidth;
r[1] = vid.rotpixelheight;
break;
default:
Con_DPrintf("GetViewFlag: %i not recognised\n", parametertype);
break;
@ -4947,7 +4957,7 @@ qboolean CSQC_Inited(void)
}
double csqctime;
qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum)
qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checksum)
{
int i;
string_t *str;
@ -5054,23 +5064,27 @@ qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum)
}
csqc_isdarkplaces = false;
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) >= 0)
loaded = true;
else
if (csdatenabled || csqc_singlecheats || anycsqc)
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) >= 0)
loaded = true;
else if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) >= 0)
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 22390, NULL, 0) >= 0)
loaded = true;
else
loaded = false;
{
if (PR_LoadProgs(csqcprogs, "csprogs.dat", 52195, NULL, 0) >= 0)
loaded = true;
else if (PR_LoadProgs(csqcprogs, "csprogs.dat", 0, NULL, 0) >= 0)
loaded = true;
else
loaded = false;
if (loaded)
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n");
if (loaded)
Con_Printf(CON_WARNING "Running outdated or unknown csprogs.dat version\n");
}
}
if (csqc_singlecheats)
if (csqc_singlecheats || anycsqc)
{
Con_DPrintf("loading csaddon.dat...\n");
if (PR_LoadProgs(csqcprogs, "csaddon.dat", 0, NULL, 0) >= 0)
loaded = true;
}
@ -5518,6 +5532,21 @@ qboolean CSQC_Accelerometer(float x, float y, float z)
return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_ConsoleLink(char *text, char *info)
{
void *pr_globals;
if (!csqcprogs || !csqcg.console_link)
return false;
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
(((string_t *)pr_globals)[OFS_PARM1] = PR_TempString(csqcprogs, info));
*info = 0;
(((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, text));
*info = '\\';
PR_ExecuteProgram (csqcprogs, csqcg.console_link);
return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_ConsoleCommand(char *cmd)
{
void *pr_globals;

View file

@ -1863,31 +1863,74 @@ conchar_t q3codemasks[MAXQ3COLOURS] = {
0x07000000 // 9, "half-intensity" (BX_COLOREDTEXT)
};
//Strips out the flags
void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflags)
//Converts a conchar_t string into a char string. returns the null terminator. pass NULL for stop to calc it
char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags)
{
if (ignoreflags)
if (!stop)
{
while(*str)
for (stop = str; *stop; stop++)
;
}
#ifdef _DEBUG
if (!outsize)
Sys_Error("COM_DeFunString given outsize=0");
#endif
/*if (ignoreflags)
{
while(str < stop)
{
if (!--outsize)
break;
*out++ = (unsigned char)(*str++&255);
}
*out++ = 0;
*out = 0;
}
else
else*/
{
int fl, d;
unsigned int c;
int prelinkflags = CON_WHITEMASK; //if used, its already an error.
//FIXME: TEST!
fl = CON_WHITEMASK;
while(*str)
while(str < stop)
{
if (!--outsize)
break;
if ((*str & CON_FLAGSMASK) != fl)
if ((*str & CON_HIDDEN) && ignoreflags)
{
str++;
continue;
}
if (*str == CON_LINKSTART)
{
if (!ignoreflags)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = '^';
*out++ = '[';
}
prelinkflags = fl;
fl = COLOR_RED << CON_FGSHIFT;
str++;
continue;
}
else if (*str == CON_LINKEND)
{
if (!ignoreflags)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = '^';
*out++ = ']';
}
fl = prelinkflags;
str++;
continue;
}
else if ((*str & CON_FLAGSMASK) != fl && !ignoreflags)
{
d = fl^(*str & CON_FLAGSMASK);
// if (fl & CON_NONCLEARBG) //not represented.
@ -1918,31 +1961,130 @@ void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflag
if (d & (CON_FGMASK | CON_BGMASK | CON_NONCLEARBG))
{
if (outsize<=4)
break;
outsize -= 4;
d = (*str & CON_FLAGSMASK);
*out++ = '^';
*out++ = '&';
if ((d & CON_FGMASK) == CON_WHITEMASK)
*out++ = '-';
else
sprintf(out, "%X", d>>24);
if (d & CON_NONCLEARBG)
static char q3[16] = { '0', 0, 0, 0,
0, 0, 0, 0,
0, '4', '2', '5',
'1', '6', '3', '7'};
if (!(d & (CON_BGMASK | CON_NONCLEARBG)) && q3[(*str & CON_FGMASK) >> CON_FGSHIFT] && !((d|fl) & CON_HALFALPHA))
{
sprintf(out, "%X", d>>28);
if (outsize<=2)
break;
outsize -= 2;
d = (*str & CON_FLAGSMASK);
*out++ = '^';
*out++ = q3[(*str & CON_FGMASK) >> CON_FGSHIFT];
}
else
*out++ = '-';
{
if (outsize<=4)
break;
outsize -= 4;
d = (*str & CON_FLAGSMASK);
*out++ = '^';
*out++ = '&';
if ((d & CON_FGMASK) == CON_WHITEMASK)
*out = '-';
else
sprintf(out, "%X", d>>24);
out++;
if (d & CON_NONCLEARBG)
sprintf(out, "%X", d>>28);
else
*out = '-';
out++;
}
}
fl = (*str & CON_FLAGSMASK);
}
*out++ = (unsigned char)(*str++&255);
//don't magically show hidden text
if (ignoreflags && (*str & CON_HIDDEN))
continue;
c = *str++ & 0xffff;
if (com_parseutf8.ival > 0)
{
//utf-8
if (c > 0x7ff)
{
if (outsize<=3)
break;
outsize -= 3;
*out++ = (unsigned char)((c>>12)&0x0f) | 0xe0;
*out++ = (unsigned char)((c>>6)&0x3f) | 0x80;
*out++ = (unsigned char)(c&0x3f) | 0x80;
}
else if (c > 0x7f)
{
if (outsize<=2)
break;
outsize -= 2;
*out++ = (unsigned char)((c>>6)&0x1f) | 0xc0;
*out++ = (unsigned char)(c&0x3f) | 0x80;
}
else
{
if (outsize<=1)
break;
outsize -= 1;
*out++ = (unsigned char)(c&0x7f);
}
}
else if (com_parseutf8.ival)
{
//iso8859-1
if ((c >= 0 && c < 255) || (c >= 0xe000+32 && c < 0xe000+127)) //quake chars between 32 and 127 are identical to iso8859-1
{
if (!--outsize)
break;
*out++ = (unsigned char)(c&255);
}
else //any other quake char is not iso8859-1
{
const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
if (outsize<=6)
break;
outsize -= 6;
*out++ = '^';
*out++ = 'U';
*out++ = hex[(c>>12)&15];
*out++ = hex[(c>>8)&15];
*out++ = hex[(c>>4)&15];
*out++ = hex[(c>>0)&15];
}
}
else
{
//quake chars
if (c == '\n' || c == '\r' || c == '\t' || (c >= 32 && c < 127) || (c >= 0xe000 && c < 0xe100)) //quake chars between 32 and 127 are identical to iso8859-1
{
if (!--outsize)
break;
*out++ = (unsigned char)(c&255);
}
else //any other char is not quake
{
const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
if (outsize<=6)
break;
outsize -= 6;
*out++ = '^';
*out++ = 'U';
*out++ = hex[(c>>12)&15];
*out++ = hex[(c>>8)&15];
*out++ = hex[(c>>4)&15];
*out++ = hex[(c>>0)&15];
}
}
}
*out++ = 0;
*out = 0;
}
return out;
}
static int dehex(int i)
@ -1963,6 +2105,9 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
int extstackdepth = 0;
unsigned int uc, l;
int utf8 = com_parseutf8.ival;
conchar_t linkinitflags = CON_WHITEMASK;/*doesn't need the init, but msvc is stupid*/
qboolean linkkeep = keepmarkup;
conchar_t *linkstart = NULL;
conchar_t ext;
@ -2120,6 +2265,40 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
// else invalid code
goto messedup;
}
else if (str[1] == '[' && !linkstart)
{
//preserved flags and reset to white. links must contain their own colours.
linkinitflags = ext;
ext = COLOR_RED << CON_FGSHIFT;
linkstart = out;
*out++ = '[';
//never keep the markup
linkkeep = keepmarkup;
keepmarkup = false;
str+=2;
continue;
}
else if (str[1] == ']' && linkstart)
{
*out++ = ']';
//its a valid link, so we can hide it all now
*linkstart++ |= CON_HIDDEN; //leading [ is hidden
while(linkstart < out-1 && (*linkstart&CON_CHARMASK) != '\\') //link text is NOT hidden
linkstart++;
while(linkstart < out) //but the infostring behind it is, as well as the terminator
*linkstart++ |= CON_HIDDEN;
//reset colours to how they used to be
ext = linkinitflags;
linkstart = NULL;
keepmarkup = linkkeep;
//never keep the markup
str+=2;
continue;
}
else if (str[1] == 'a')
{
ext ^= CON_2NDCHARSETTEXT;
@ -2130,7 +2309,10 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
}
else if (str[1] == 'd')
{
ext = defaultflags;
if (linkstart)
ext = COLOR_RED << CON_FGSHIFT;
else
ext = defaultflags;
}
else if (str[1] == 'm')
{

View file

@ -275,7 +275,7 @@ void COM_InitArgv (int argc, const char **argv);
void COM_ParsePlusSets (void);
typedef unsigned int conchar_t;
void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflags);
char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, qboolean ignoreflags);
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
int COM_FunStringLength(unsigned char *str);

View file

@ -38,7 +38,7 @@ extern conchar_t q3codemasks[MAXQ3COLOURS];
#define CON_HIGHCHARSMASK 0x00000080 // Quake's alternative mask
#define CON_FLAGSMASK 0xFFF00000
#define CON_UNUSEDMASK 0x000F0000
#define CON_HIDDEN 0x000F0000
#define CON_CHARMASK 0x0000FFFF
#define CON_FGMASK 0x0F000000
@ -51,6 +51,9 @@ extern conchar_t q3codemasks[MAXQ3COLOURS];
#define CON_DEFAULTCHAR (CON_WHITEMASK | 32)
#define CON_LINKSTART (CON_HIDDEN | '[')
#define CON_LINKEND (CON_HIDDEN | ']')
// RGBI standard colors
#define COLOR_BLACK 0
#define COLOR_DARKBLUE 1
@ -142,7 +145,7 @@ void Con_ForceActiveNow(void);
void Con_Init (void);
void Con_Shutdown (void);
void Con_DrawConsole (int lines, qboolean noback);
char *Con_CopyConsole(void);
char *Con_CopyConsole(qboolean nomarkup);
void Con_Print (char *txt);
void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
void VARGS Con_TPrintf (translation_t text, ...);

View file

@ -5846,7 +5846,7 @@ int CM_WriteAreaBits (model_t *mod, qbyte *buffer, int area)
return bytes;
}
#ifndef CLIENTONLY
void CM_InitPortalState(void)
{
int i;
@ -5857,6 +5857,7 @@ void CM_InitPortalState(void)
map_q2areas[i].floodnum = 0;
}
}
#endif
/*
===================

View file

@ -2290,7 +2290,7 @@ void QCBUILTIN PF_strdecolorize (progfuncs_t *prinst, struct globalvars_s *pr_gl
char result[8192];
unsigned int flagged[8192];
COM_ParseFunString(CON_WHITEMASK, in, flagged, sizeof(flagged), false);
COM_DeFunString(flagged, result, sizeof(result), true);
COM_DeFunString(flagged, NULL, result, sizeof(result), true);
RETURN_TSTRING(result);
}

View file

@ -435,6 +435,8 @@ typedef enum
//201 used by DP... WTF? CLEARSCREEN
VF_LPLAYER = 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,
} viewflags;
/*FIXME: this should be changed*/

View file

@ -338,4 +338,5 @@ int D3D11Shader_FindUniform(union programhandle_u *h, int type, char *name)
#endif
return -1;
}
#endif
#endif

View file

@ -9,11 +9,6 @@
#define COBJMACROS
#include <d3d11.h>
//#include <d3d9.h>
//#pragma comment(lib, "../libs/dxsdk9/lib/d3d9.lib")
/*Fixup outdated windows headers*/
#ifndef WM_XBUTTONDOWN
#define WM_XBUTTONDOWN 0x020B

View file

@ -22538,6 +22538,18 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\sha1.c"
>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\translate.c"
>

View file

@ -3213,11 +3213,11 @@ void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
shaderstate.lastuniform = 0;
lmode = 0;
if (dl->fov && shaderstate.shader_light[lmode|LSHADER_SPOT]->prog)
if (dl->fov && shaderstate.shader_light[lmode|LSHADER_SPOT] && shaderstate.shader_light[lmode|LSHADER_SPOT]->prog)
lmode |= LSHADER_SPOT;
if ((dl->flags & LFLAG_SHADOWMAP) && shaderstate.shader_light[lmode|LSHADER_SMAP]->prog)
if ((dl->flags & LFLAG_SHADOWMAP) && shaderstate.shader_light[lmode|LSHADER_SMAP] && shaderstate.shader_light[lmode|LSHADER_SMAP]->prog)
lmode |= LSHADER_SMAP;
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_light[lmode|LSHADER_CUBE]->prog)
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_light[lmode|LSHADER_CUBE] && shaderstate.shader_light[lmode|LSHADER_CUBE]->prog)
lmode |= LSHADER_CUBE;
shaderstate.lightmode = lmode;
}

View file

@ -1190,6 +1190,8 @@ int Font_CharEndCoord(struct font_s *font, int x, unsigned int charcode)
{
struct charcache_s *c;
#define TABWIDTH (8*20)
if (charcode&CON_HIDDEN)
return x;
if ((charcode&CON_CHARMASK) == '\t')
return x + ((TABWIDTH - (x % TABWIDTH)) % TABWIDTH);
@ -1212,6 +1214,8 @@ int Font_CharWidth(unsigned int charcode)
{
struct charcache_s *c;
struct font_s *font = curfont;
if (charcode&CON_HIDDEN)
return 0;
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
font = font->alt;
@ -1333,6 +1337,9 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
int col;
int v;
struct font_s *font = curfont;
if (charcode & CON_HIDDEN)
return px;
if ((charcode & CON_2NDCHARSETTEXT) && font->alt)
font = font->alt;

View file

@ -9946,6 +9946,8 @@ void PR_DumpPlatform_f(void)
{"VF_PERSPECTIVE", "const float", CS, VF_PERSPECTIVE},
{"VF_LPLAYER", "const float", CS, VF_LPLAYER},
{"VF_AFOV", "const float", CS, VF_AFOV},
{"VF_SCREENVSIZE", "const float", CS, VF_SCREENVSIZE},
{"VF_SCREENPSIZE", "const float", CS, VF_SCREENPSIZE},
{"RF_VIEWMODEL", "const float", CS, CSQCRF_VIEWMODEL},
{"RF_EXTERNALMODEL", "const float", CS, CSQCRF_EXTERNALMODEL},

View file

@ -4523,6 +4523,7 @@ void SV_FixupName(char *in, char *out, unsigned int outlen)
{
char *s, *p;
unsigned int len;
conchar_t testbuf[1024], *t, *e;
if (outlen == 0)
return;
@ -4544,7 +4545,20 @@ void SV_FixupName(char *in, char *out, unsigned int outlen)
}
*s = '\0';
if (!*out)
/*note: clients are not guarenteed to parse things the same as the server. utf-8 surrogates may be awkward here*/
e = COM_ParseFunString(CON_WHITEMASK, out, testbuf, sizeof(testbuf), false);
for (t = testbuf; t < e; t++)
{
/*reject anything hidden in names*/
if (*t & CON_HIDDEN)
break;
/*reject pictograms*/
if ((*t & CON_CHARMASK) >= 0xe100 && (*t & CON_CHARMASK) < 0xe200)
break;
/*FIXME: should we try to ensure that the chars are in most fonts? that might annoy speakers of more exotic languages I suppose. cvar it?*/
}
if (!*out || (t < e) || e == testbuf)
{ //reached end and it was all whitespace
//white space only
strncpy(out, "unnamed", outlen);

View file

@ -23,40 +23,105 @@ class MyDelegate : public Berkelium::WindowDelegate
private:
decctx *ctx;
virtual void onCrashedWorker(Berkelium::Window *win)
{
int i;
Con_Printf("Berkelium worker crashed\n");
/*black it out*/
for (i = 0; i < ctx->width*ctx->height; i++)
{
ctx->buffer[i] = 0xff000000;
}
ctx->repainted = true;
}
virtual void onCrashed(Berkelium::Window *win)
{
int i;
Con_Printf("Berkelium window crashed\n");
/*black it out*/
for (i = 0; i < ctx->width*ctx->height; i++)
{
ctx->buffer[i] = 0xff000000;
}
ctx->repainted = true;
}
virtual void onUnresponsive(Berkelium::Window *win)
{
Con_Printf("Berkelium window unresponsive\n");
}
virtual void onResponsive(Berkelium::Window *win)
{
Con_Printf("Berkelium window responsive again, yay\n");
}
virtual void onPaint(Berkelium::Window *wini, const unsigned char *bitmap_in, const Berkelium::Rect &bitmap_rect, size_t num_copy_rects, const Berkelium::Rect *copy_rects, int dx, int dy, const Berkelium::Rect& scroll_rect)
{
int i;
// handle paint events...
if (dx || dy)
{
int y;
int t = scroll_rect.top();
int l = scroll_rect.left();
int y, m;
int dt = scroll_rect.top();
int dl = scroll_rect.left();
int w = scroll_rect.width();
int h = scroll_rect.height();
if (dy > 0)
{
//if we're moving downwards, we need to write the bottom before the top (so we don't overwrite the data before its copied)
for (y = t+h-1; y >= t; y--)
{
if (y < 0 || y >= ctx->height)
continue;
if (y+dy < 0 || y+dy >= ctx->height)
continue;
memmove(ctx->buffer + ((l+dx) + (y+dy)*ctx->width), ctx->buffer + (l + y*ctx->width), w*4);
}
}
else
{
//moving upwards requires we write the top row first
for (y = t; y < t+h; y++)
{
if (y < 0 || y >= ctx->height)
continue;
if (y+dy < 0 || y+dy >= ctx->height)
continue;
int st = dt - dy;
int sl = dl - dx;
memmove(ctx->buffer + ((l+dx) + (y+dy)*ctx->width), ctx->buffer + (l + y*ctx->width), w*4);
/*bound the output rect*/
if (dt < 0)
{
st -= dt;
h += dt;
dt = 0;
}
if (dl < 0)
{
sl -= dl;
w += dl;
dl = 0;
}
/*bound the source rect*/
if (st < 0)
{
dt -= st;
h += st;
st = 0;
}
if (sl < 0)
{
dl -= sl;
w += sl;
sl = 0;
}
/*bound the width*/
m = (dl>sl)?dl:sl;
if (m + w > ctx->width)
w = ctx->width - m;
m = (dt>st)?dt:st;
if (m + h > ctx->height)
h = ctx->height - m;
if (w > 0 && h > 0)
{
if (dy > 0)
{
//if we're moving downwards, we need to write the bottom before the top (so we don't overwrite the data before its copied)
for (y = h; y >= 0; y--)
{
memmove(ctx->buffer + (dl + (dt+y)*ctx->width), ctx->buffer + (sl + (st+y)*ctx->width), w*4);
}
}
else
{
//moving upwards requires we write the top row first
for (y = 0; y < h; y++)
{
memmove(ctx->buffer + (dl + (dt+y)*ctx->width), ctx->buffer + (sl + (st+y)*ctx->width), w*4);
}
}
}
}
@ -65,22 +130,37 @@ private:
unsigned int *out = ctx->buffer;
const unsigned int *in = (const unsigned int*)bitmap_in;
int x, y;
int t = copy_rects[i].top() - bitmap_rect.top();
int l = copy_rects[i].left() - bitmap_rect.left();
int t = copy_rects[i].top();
int l = copy_rects[i].left();
int r = copy_rects[i].width() + l;
int b = copy_rects[i].height() + t;
unsigned int instride = bitmap_rect.width() - (r - l);
unsigned int outstride = ctx->width - (r - l);
int w, h;
out += copy_rects[i].left();
out += copy_rects[i].top() * ctx->width;
//Clip the rect to the display. This should generally happen anyway, but resizes can be lagged a bit with the whole multi-process/thread thing.
//don't need to clip to the bitmap rect, that should be correct.
if (l < 0)
l = 0;
if (t < 0)
t = 0;
if (r > ctx->width)
r = ctx->width;
if (b > ctx->height)
b = ctx->height;
w = r - l;
h = b - t;
in += l;
in += t * bitmap_rect.width();
unsigned int instride = bitmap_rect.width() - (w);
unsigned int outstride = ctx->width - (w);
for (y = t; y < b; y++)
out += l;
out += t * ctx->width;
in += (l-bitmap_rect.left());
in += (t-bitmap_rect.top()) * bitmap_rect.width();
for (y = 0; y < h; y++)
{
for (x = l; x < r; x++)
for (x = 0; x < w; x++)
{
*out++ = *in++;
}
@ -182,16 +262,47 @@ static void Dec_Key (void *vctx, int code, int unicode, int isup)
wchar_t wchr = unicode;
if (code >= 178 && code < 178+6)
ctx->wnd->mouseButton(code - 178, !isup);
{
code = code - 178;
//swap mouse2+3
if (code == 1)
code = 2;
else if (code == 2)
code = 1;
ctx->wnd->mouseButton(code, !isup);
}
else if (code == 188 || code == 189)
ctx->wnd->mouseWheel(0, (code==189)?-30:30);
{
if (!isup)
ctx->wnd->mouseWheel(0, (code==189)?-30:30);
}
else
{
if (code)
{
int mods = 0;
if (code == 127)
code = 0x08;
else if (code == 140) //del
code = 0x2e;
else if (code == 143) //home
code = 0x24;
else if (code == 144) //end
code = 0x23;
else if (code == 141) //pgdn
code = 0x22;
else if (code == 142) //pgup
code = 0x21;
else if (code == 139) //ins
code = 0x2d;
else if (code == 132) //up
code = 0x26;
else if (code == 133) //down
code = 0x28;
else if (code == 134) //left
code = 0x25;
else if (code == 135) //right
code = 0x27;
ctx->wnd->keyEvent(!isup, mods, code, 0);
}
if (unicode && !isup)
@ -214,6 +325,10 @@ static void Dec_ChangeStream(void *vctx, char *newstream)
ctx->wnd->refresh();
else if (!strcmp(newstream+4, "transparent"))
ctx->wnd->setTransparent(true);
else if (!strcmp(newstream+4, "focus"))
ctx->wnd->focus();
else if (!strcmp(newstream+4, "unfocus"))
ctx->wnd->unfocus();
else if (!strcmp(newstream+4, "opaque"))
ctx->wnd->setTransparent(true);
else if (!strcmp(newstream+4, "stop"))