Attempt to improve touchscreen behaviours with onscreen buttons that appear upon touch events (and fade out). Long presses should close menus etc. Likely needs some more work.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6335 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2023-01-09 05:14:38 +00:00
parent d4d84aec9d
commit fb4531ea6c
24 changed files with 495 additions and 293 deletions

View file

@ -763,13 +763,16 @@ qboolean IN_WeaponWheelIsShown(void)
return false;
return true;
}
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y) //either mouse or controller
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y, float threshhold) //either mouse or controller
{
if (!(in_wwheel.state[pnum]&1) || !weaponinfo_count)
return false;
if (x*x+y*y > threshhold*threshhold) //protects against deadzones.
{
wwheeldir[pnum][0] += x;
wwheeldir[pnum][1] += y;
}
return true;
}
#include "shader.h"

View file

@ -96,8 +96,8 @@ cvar_t cfg_save_name = CVARFD("cfg_save_name", "fte", CVAR_ARCHIVE|CVAR_NOTFROMS
cvar_t cl_splitscreen = CVARD("cl_splitscreen", "0", "Enables splitscreen support. See also: allow_splitscreen, in_rawinput*, the \"p\" command.");
cvar_t lookspring = CVARF("lookspring","0", CVAR_ARCHIVE);
cvar_t lookstrafe = CVARF("lookstrafe","0", CVAR_ARCHIVE);
cvar_t lookspring = CVARFD("lookspring","0", CVAR_ARCHIVE, "Recentre the camera when the mouse-look is released.");
cvar_t lookstrafe = CVARFD("lookstrafe","0", CVAR_ARCHIVE, "Mouselook enables mouse strafing.");
cvar_t sensitivity = CVARF("sensitivity","10", CVAR_ARCHIVE);
cvar_t cl_staticsounds = CVARF("cl_staticsounds", "1", CVAR_ARCHIVE);

View file

@ -1253,12 +1253,14 @@ typedef struct showpic_s {
struct showpic_s *next;
qbyte zone;
qboolean persist;
float fadedelay;
short x, y, w, h;
char *name;
char *picname;
char *tcommand;
} showpic_t;
showpic_t *showpics;
double showpics_touchtime;
static void SP_RecalcXY ( float *xx, float *yy, int origin )
{
@ -1347,7 +1349,7 @@ static void SP_RecalcXY ( float *xx, float *yy, int origin )
void SCR_ShowPics_Draw(void)
{
downloadlist_t *failed;
float x, y;
float x, y, a = 1;
showpic_t *sp;
mpic_t *p;
for (sp = showpics; sp; sp = sp->next)
@ -1366,23 +1368,48 @@ void SCR_ShowPics_Draw(void)
if (failed)
continue;
p = R2D_SafeCachePic(sp->picname);
if (!p)
if (sp->fadedelay && showpics_touchtime+sp->fadedelay < realtime)
{
a = 1+(showpics_touchtime+sp->fadedelay-realtime);
if (a > 1)
a = 1; //shouldn't really happen, w/e.
else if (a <= 0)
continue;
R2D_ImageColours(1,1,1,a);
}
else if (a != 1)
R2D_ImageColours(1,1,1,a=1);
p = R2D_SafeCachePic(sp->picname);
if (!p || !R_GetShaderSizes(p, NULL, NULL, false))
{
if (sp->h > 8)
Draw_FunStringWidth(x-2, y + (sp->h-8)/2, sp->name, sp->w+4, 2, false); //slightly wider, to try to somewhat deal with 16:10 resolutions...
}
else
R2D_ScalePic(x, y, sp->w?sp->w:p->width, sp->h?sp->h:p->height, p);
}
if (a != 1)
R2D_ImageColours(1,1,1,1);
}
char *SCR_ShowPics_ClickCommand(int cx, int cy)
const char *SCR_ShowPics_ClickCommand(float cx, float cy, qboolean istouch)
{
downloadlist_t *failed;
float x, y, w, h;
showpic_t *sp;
mpic_t *p;
qboolean tryload = !showpics_touchtime;
float bestdist = istouch?16:1;
const char *best = NULL;
showpics_touchtime = realtime;
for (sp = showpics; sp; sp = sp->next)
{
if (!sp->tcommand || !*sp->tcommand)
continue;
tryload = false;
x = sp->x;
y = sp->y;
w = sp->w;
@ -1406,11 +1433,22 @@ char *SCR_ShowPics_ClickCommand(int cx, int cy)
w = w?w:sp->w;
h = h?h:sp->h;
}
if (cx >= x && cx < x+w)
if (cy >= y && cy < y+h)
return sp->tcommand; //if they overlap, that's your own damn fault.
x = bound(x, cx, x+w)-cx;
y = bound(y, cy, y+h)-cy;
x = max(fabs(x),fabs(y));
if (bestdist > x)
{ //looks like this one is closer to the cursor
bestdist = x;
best = sp->tcommand;
if (bestdist <= 0) //use the first that's inside.
break;
}
return NULL;
}
if (tryload)
Cbuf_AddText("exec touch.cfg\n", RESTRICT_LOCAL);
return best;
}
//all=false clears only server pics, not ones from configs.
@ -1425,6 +1463,8 @@ void SCR_ShowPic_ClearAll(qboolean persistflag)
scr_centerprint[pnum].charcount = 0;
}
if (!persistflag)
showpics_touchtime = 0; //map change. gamedir may have changed too.
for (link = &showpics; (sp=*link); )
{
if (sp->persist != persistflag)
@ -1599,6 +1639,7 @@ void SCR_ShowPic_Script_f(void)
int x, y, w, h;
int zone;
showpic_t *sp;
float fadedelay;
imgname = Cmd_Argv(1);
name = Cmd_Argv(2);
@ -1609,6 +1650,7 @@ void SCR_ShowPic_Script_f(void)
w = atoi(Cmd_Argv(6));
h = atoi(Cmd_Argv(7));
tcommand = Cmd_Argv(8);
fadedelay = atof(Cmd_Argv(9));
sp = SCR_ShowPic_Find(name);
@ -1623,6 +1665,7 @@ void SCR_ShowPic_Script_f(void)
sp->y = y;
sp->w = w;
sp->h = h;
sp->fadedelay = fadedelay;
if (!sp->persist)
sp->persist = !Cmd_FromGamecode();

View file

@ -1216,7 +1216,7 @@ void CL_UpdateWindowTitle(void);
#ifdef QUAKESTATS
const char *IN_GetPreselectedViewmodelName(unsigned int pnum);
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y);
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y, float threshhold);
qboolean IN_DrawWeaponWheel(int pnum);
qboolean IN_WeaponWheelIsShown(void); //to decide when the game should be auto-paused.
#endif

View file

@ -3294,7 +3294,7 @@ void Con_DrawConsole (int lines, qboolean noback)
}
selactive = Key_GetConsoleSelectionBox(con_current, &selsx, &selsy, &selex, &seley);
if ((con_current->flags & CONF_KEEPSELECTION) && con_current->selstartline && con_current->selendline)
if ((con_current->flags & CONF_KEEPSELECTION) && con_current->selstartline && con_current->selendline && con_current->buttonsdown != CB_SELECTED)
selactive = -1;
Font_BeginString(font_console, x, y, &x, &y);
@ -3327,6 +3327,54 @@ void Con_DrawConsole (int lines, qboolean noback)
Font_EndString(font_console);
mouseconsole = con_mouseover?con_mouseover:con_current;
if (con_current->buttonsdown == CB_SELECTED)
{ //select was released...
console_t *con = con_current;
char *buffer;
con->buttonsdown = CB_NONE;
if (con->selstartline)
{
con->flags |= CONF_KEEPSELECTION;
if (con->userline)
{
if (con->flags & CONF_BACKSELECTION)
{
con->userline = con->selendline;
con->useroffset = con->selendoffset;
}
else
{
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
}
if (con->selstartline == con->selendline && con->selendoffset <= con->selstartoffset+1)
{
if (keydown[K_LSHIFT] || keydown[K_RSHIFT])
;
else
{
buffer = Con_CopyConsole(con, false, true, false);
if (buffer)
{
Key_HandleConsoleLink(con, buffer);
Z_Free(buffer);
}
}
}
else
{
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
if (buffer)
{
Sys_SaveClipboard(CBT_SELECTION, buffer);
Z_Free(buffer);
}
}
}
}
}
else
mouseconsole = con_mouseover?con_mouseover:NULL;

View file

@ -15,8 +15,9 @@ extern qboolean mouse_active;
static cvar_t m_filter = CVARF("m_filter", "0", CVAR_ARCHIVE);
static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice.");
static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas.");
static cvar_t m_touchstrafe = CVARAFD("m_touchstrafe", "1", "m_strafeonright", CVAR_ARCHIVE, "0: entire screen changes angles only.\n1: right hand side controls strafing.\n2:left hand side strafes.");
static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens).");
static cvar_t m_touchstrafe = CVARAFD("m_touchstrafe", "0", "m_strafeonright", CVAR_ARCHIVE, "0: entire screen changes angles only.\n1: right hand side controls strafing.\n2:left hand side strafes.");
//static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens).");
static cvar_t m_longpressthreshold = CVARFD("m_longpressthreshold", "1", CVAR_ARCHIVE, "How long to press for it to register as a long press (touchscreens).");
static cvar_t m_touchmajoraxis = CVARFD("m_touchmajoraxis", "1", CVAR_ARCHIVE, "When using a touchscreen, use only the major axis for strafing.");
static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "10", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens).");
@ -121,16 +122,27 @@ static cvar_t joy_movethreshold[3] =
CVAR("joyupthreshold", "0.118"), //30/255 (trigger)
};
static cvar_t joy_exponent = CVARD("joyexponent", "3", "Scales joystick/controller sensitivity non-linearly to increase precision in the center.\nA value of 1 is linear.");
static cvar_t joy_exponent = CVARD("joyexponent", "1", "Scales joystick/controller sensitivity non-linearly to increase precision in the center.\nA value of 1 is linear.");
#if defined(__linux__) && defined(FTE_SDL)
#include <SDL.h>
void joy_radialdeadzone_cb(cvar_t *var, char *oldvalue)
{
if (!*var->string)
{
#if defined(__linux__) && defined(FTE_SDL)
var->ival = 2; //sdl2 provides its own deadzones on linux, by default. FIXME: check SDL_GetHint(SDL_HINT_LINUX_JOYSTICK_DEADZONES), default is "1"
if (SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, true))
var->ival = 2; //sdl2 provides its own deadzones on linux, by default.
else
var->ival = 1;
}
}
#else
void joy_radialdeadzone_cb(cvar_t *var, char *oldvalue)
{
if (!*var->string)
var->ival = 1;
}
#endif
}
}
static cvar_t joy_radialdeadzone = CVARCD("joyradialdeadzone", "", joy_radialdeadzone_cb, "Treat controller dead zones as a pair, rather than per-axis.");
@ -207,7 +219,8 @@ static struct mouse_s
vec2_t delta; //how far its moved recently
vec2_t old_delta; //how far its moved previously, for mouse smoothing
float wheeldelta;
int held; //button is held (for touch stuff). 1=mouse movements permitted. 2=mouse1 was sent to the game
double touchtime; //0 when not touching, otherwise start time of touch.
unsigned int touchkey; //which other key we generated (so it gets released again.
unsigned int updates; //tracks updates per second
qboolean updated;
} ptr[MAXPOINTERS];
@ -336,7 +349,7 @@ void IN_Init(void)
Cvar_Register (&m_forcewheel, "Input Controls");
Cvar_Register (&m_forcewheel_threshold, "Input Controls");
Cvar_Register (&m_touchstrafe, "input controls");
Cvar_Register (&m_fatpressthreshold, "input controls");
Cvar_Register (&m_longpressthreshold, "input controls");
Cvar_Register (&m_slidethreshold, "input controls");
Cvar_Register (&m_touchmajoraxis, "input controls");
Cvar_Register (&m_accel, "input controls");
@ -367,35 +380,14 @@ void IN_Init(void)
INS_Init();
}
//tells the keys.c code whether the cursor is currently active, causing mouse clicks instead of binds.
qboolean IN_MouseDevIsTouch(unsigned int devid)
{
if (devid < MAXPOINTERS)
return ptr[devid].type == M_TOUCH;
return false;
}
//there was no ui to click on at least...
//translates MOUSE1 press events into begin-look-or-strafe events.
//translates to MOUSE2 accordingly
//returns 0 if it ate it completely.
int IN_TranslateMButtonPress(unsigned int devid)
//translates touch press events into ones that are actually bound, according to touchstrafe and position.
int IN_Touch_Fallback(unsigned int devid)
{
int ret;
if (!ptr[devid].held)
{
//set the cursor-pressed state, so we begin to look/strafe around
ptr[devid].held = 1;
ptr[devid].moveddist = 0;
ptr[devid].heldpos[0] = ptr[devid].oldpos[0];
ptr[devid].heldpos[1] = ptr[devid].oldpos[1];
ptr[devid].delta[0] = 0;
ptr[devid].delta[1] = 0;
ret = 0; //eat it
}
else
{
//translate touch to mouse2 if its on the strafing side of the screen.
switch(m_touchstrafe.ival)
if (devid >= countof(ptr))
ret = 0;
else switch(m_touchstrafe.ival) //translate touch to mouse2 if its on the strafing side of the screen.
{
case 2:
ret = ptr[devid].heldpos[0] < vid.pixelwidth/2;
@ -408,10 +400,20 @@ int IN_TranslateMButtonPress(unsigned int devid)
break;
}
ret = ret?K_MOUSE2:K_MOUSE1;
}
return ret;
}
void IN_Touch_BlockGestures(unsigned int devid)
{ //called via K_TOUCH, blocks K_TOUCHTAP etc gestures
if (devid < countof(ptr))
ptr[devid].touchkey = 0; //block it all.
}
qboolean IN_Touch_MouseIsAbs(unsigned int devid)
{ //lets the caller know if a mouse1 down event was abs
if (devid < countof(ptr))
return ptr[devid].type == M_TOUCH;
return false;
}
/*a 'pointer' is either a multitouch pointer, or a separate device
note that mice use the keyboard button api, but separate devices*/
@ -428,6 +430,7 @@ void IN_Commands(void)
switch(ev->type)
{
case IEV_KEYRELEASE:
//Con_Printf("IEV_KEYDOWN %i: %i '%c'\n", ev->devid, ev->keyboard.scancode, ev->keyboard.unicode?ev->keyboard.unicode:' ');
if (ev->keyboard.scancode == -1)
{
int i;
@ -435,43 +438,48 @@ void IN_Commands(void)
Key_Event(ev->devid, i, 0, false);
break;
}
case IEV_KEYDOWN:
//Con_Printf("IEV_KEY%s %i: %i '%c'\n", (ev->type==IEV_KEYDOWN)?"DOWN ":"RELEASE", ev->devid, ev->keyboard.scancode, ev->keyboard.unicode?ev->keyboard.unicode:' ');
//on touchscreens, mouse1 is used as up/down state. we have to emulate actual mouse clicks based upon distance moved, so we can get movement events.
if ((ev->keyboard.scancode == K_MOUSE1||ev->keyboard.scancode==K_TOUCH) && ev->devid < MAXPOINTERS && (ptr[ev->devid].type == M_TOUCH))
{
if (ev->type == IEV_KEYDOWN)
{
float fl;
touchcursor = ev->devid;
fl = ptr[ev->devid].oldpos[0] * vid.width / vid.pixelwidth;
mousecursor_x = bound(0, fl, vid.width-1);
fl = ptr[ev->devid].oldpos[1] * vid.height / vid.pixelheight;
mousecursor_y = bound(0, fl, vid.height-1);
}
else if (touchcursor == ev->devid)
{ //touch (or abs clicks)
struct mouse_s *m = &ptr[ev->devid];
if (touchcursor == ev->devid)
touchcursor = -1; //revert it to the mouse, or whatever device was 0.
if (Key_MouseShouldBeFree())
ptr[ev->devid].held = 0;
else if (ptr[ev->devid].held)
{
if (ev->type == IEV_KEYDOWN)
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
if (ev->keyboard.scancode==K_TOUCH && m->touchtime && m->touchkey==K_TOUCH)
{ //convert to tap/longpress if it wasn't already a gesture. don't ever convert mouse.
if (Sys_DoubleTime()-m->touchtime > m_longpressthreshold.value)
m->touchkey = K_TOUCHLONG;
else
{
if (ptr[ev->devid].held == 1 && ptr[ev->devid].moveddist < m_slidethreshold.value)
{
ptr[ev->devid].held = 2; //so we don't just flag it as held again
Key_Event(ev->devid, ev->keyboard.scancode, 0, true);
m->touchkey = K_TOUCHTAP;
Key_Event(ev->devid, m->touchkey, 0, true);
}
Key_Event(ev->devid, ev->keyboard.scancode, 0, false);
ptr[ev->devid].held = 0;
if (m->touchkey && m->touchkey!=ev->keyboard.scancode)
Key_Event(ev->devid, m->touchkey, 0, false); //and release...
//reset it.
m->touchkey = 0;
m->touchtime = 0;
m->moveddist = 0;
}
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, false);
break;
case IEV_KEYDOWN:
//Con_Printf("IEV_KEYDOWN %i: %i '%c'\n", ev->devid, ev->keyboard.scancode, ev->keyboard.unicode?ev->keyboard.unicode:' ');
if ((ev->keyboard.scancode == K_MOUSE1||ev->keyboard.scancode==K_TOUCH) && ev->devid < MAXPOINTERS && (ptr[ev->devid].type == M_TOUCH))
{ //touch (or abs clicks)
struct mouse_s *m = &ptr[ev->devid];
float fl;
touchcursor = ev->devid;
fl = m->oldpos[0] * vid.width / vid.pixelwidth; mousecursor_x = bound(0, fl, vid.width-1);
fl = m->oldpos[1] * vid.height / vid.pixelheight; mousecursor_y = bound(0, fl, vid.height-1);
m->touchtime = Sys_DoubleTime();
m->moveddist = 0;
if (ev->keyboard.scancode==K_TOUCH)
m->touchkey = K_TOUCH;
else
m->touchkey = 0;
}
}
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, ev->type == IEV_KEYDOWN);
Key_Event(ev->devid, ev->keyboard.scancode, ev->keyboard.unicode, true);
break;
case IEV_JOYAXIS:
if (ev->devid < MAXJOYSTICKS && ev->joy.axis < MAXJOYAXIS)
@ -541,44 +549,45 @@ void IN_Commands(void)
if (ev->devid < MAXPOINTERS)
{
if (ptr[ev->devid].type != M_TOUCH)
struct mouse_s *m = &ptr[ev->devid];
if (m->type != M_TOUCH)
{
//if its now become an absolute device, clear stuff so we don't get confused.
ptr[ev->devid].type = M_TOUCH;
ptr[ev->devid].held = 0;
ptr[ev->devid].moveddist = 0;
ptr[ev->devid].oldpos[0] = ev->mouse.x;
ptr[ev->devid].oldpos[1] = ev->mouse.y;
m->type = M_TOUCH;
m->touchtime = 0;
m->touchkey = 0;
m->moveddist = 0;
m->oldpos[0] = ev->mouse.x;
m->oldpos[1] = ev->mouse.y;
}
if (ptr[ev->devid].held)
{
ptr[ev->devid].delta[0] += ev->mouse.x - ptr[ev->devid].oldpos[0];
ptr[ev->devid].delta[1] += ev->mouse.y - ptr[ev->devid].oldpos[1];
if (m->touchtime)
{ //only do this when its actually held in some form...
m->delta[0] += ev->mouse.x - m->oldpos[0];
m->delta[1] += ev->mouse.y - m->oldpos[1];
ptr[ev->devid].moveddist += fabs(ev->mouse.x - ptr[ev->devid].oldpos[0]) + fabs(ev->mouse.y - ptr[ev->devid].oldpos[1]);
m->moveddist += fabs(ev->mouse.x - m->oldpos[0]) + fabs(ev->mouse.y - m->oldpos[1]);
}
if (ev->mouse.x != ptr[ev->devid].oldpos[0] ||
ev->mouse.y != ptr[ev->devid].oldpos[1])
if (ev->mouse.x != m->oldpos[0] ||
ev->mouse.y != m->oldpos[1])
{
ptr[ev->devid].updates++;
ptr[ev->devid].updated = true;
m->updates++;
m->updated = true;
}
ptr[ev->devid].oldpos[0] = ev->mouse.x;
ptr[ev->devid].oldpos[1] = ev->mouse.y;
m->oldpos[0] = ev->mouse.x;
m->oldpos[1] = ev->mouse.y;
if (ptr[ev->devid].held > 1 && ev->mouse.tsize < m_fatpressthreshold.value)
if (m->touchtime && m->touchkey == K_TOUCH)
{
ptr[ev->devid].held = 1;
Key_Event(ev->devid, K_MOUSE1, 0, false);
}
if (ptr[ev->devid].held == 1 && ev->mouse.tsize > m_fatpressthreshold.value)
{
ptr[ev->devid].held = 2;
Key_Event(ev->devid, K_MOUSE1, 0, true);
if (Sys_DoubleTime()-m->touchtime > 1)
m->touchkey = K_TOUCHLONG; //held for long enough...
else if (m->moveddist >= m_slidethreshold.value)
m->touchkey = K_TOUCHSLIDE; //moved far enough to consitute a slide
else
break;
Key_Event(ev->devid, m->touchkey, 0, true);
}
}
break;
@ -672,6 +681,17 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
if (mouse->type == M_TOUCH)
{
qboolean strafing = false;
if (mouse->touchtime && mouse->touchkey==K_TOUCH)
{ //convert to tap/longpress if it wasn't already a gesture. don't ever convert mouse.
if (Sys_DoubleTime()-mouse->touchtime > m_longpressthreshold.value)
{ //might as well trigger this here...
mouse->touchkey = K_TOUCHLONG;
Key_Event(mouse-ptr, mouse->touchkey, 0, true);
}
}
switch(m_touchstrafe.ival)
{
case 2:
@ -681,13 +701,13 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
strafing = mouse->heldpos[0] > vid.pixelwidth/2;
break;
case 0:
strafing = true;
strafing = false;
break;
}
if (strafing && movements != NULL && !Key_Dest_Has(~kdm_game))
{
//if they're strafing, calculate the speed to move at based upon their displacement
if (mouse->held)
if (mouse->touchtime)
{
if (m_touchstrafe.ival == 2) //left side
mx = mouse->oldpos[0] - (vid.pixelwidth*1)/4.0;
@ -724,6 +744,9 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
//boost sensitivity so that the default works okay.
mx *= 1.75;
my *= 1.75;
if (IN_WeaponWheelAccumulate(pnum, mx, my, 0))
mx = my = 0;
}
}
else
@ -778,7 +801,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
//if game is not focused, kill any mouse look
if (
#ifdef QUAKESTATS
IN_WeaponWheelAccumulate(pnum, mx, my) ||
IN_WeaponWheelAccumulate(pnum, mx, my, 0) ||
#endif
Key_Dest_Has(~kdm_game))
{
@ -879,12 +902,17 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
//rescales threshold-1 down 0-1
static float joydeadzone(float mag, float deadzone)
{
if (joy_radialdeadzone.ival == 2) //hacky overload to disable dead zones where the system provides it instead.
deadzone = 0;
if (mag > 1) //erg?
mag = 1;
if (mag > deadzone)
{
mag -= deadzone;
mag = mag / (1.f-deadzone);
mag = pow(mag, joy_exponent.value);
}
else
mag = 0;
@ -949,49 +977,51 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
}
}
if (IN_WeaponWheelAccumulate(joy->qdeviceid, jstrafe[1]*50, -jstrafe[0]*50))
jstrafe[0] = jstrafe[1] = 0;
if (joy_radialdeadzone.ival == 2)
{ //steam or SDL or something is doing deadzone and exponent stuff already. just use identity so we don't get double deadzones.
}
else if (joy_radialdeadzone.ival)
if (joy_radialdeadzone.ival)
{
//uses a radial deadzone for x+y axis, and separate out the z axis, just because most controllers are 2d affairs with any 3rd axis being a separate knob.
//deadzone values are stolen from microsoft's xinput documentation. they seem quite large to me - I guess that means that xbox controllers are just dodgy imprecise crap with excessive amounts of friction and finger grease.
mag = joydeadzone(sqrt(jlook[0]*jlook[0] + jlook[1]*jlook[1]), sqrt(joy_anglethreshold[0].value*joy_anglethreshold[0].value + joy_anglethreshold[1].value*joy_anglethreshold[1].value));
mag = pow(mag, joy_exponent.value);
jlook[0] *= mag;
jlook[1] *= mag;
float basemag = sqrt(jlook[0]*jlook[0] + jlook[1]*jlook[1]);
if (basemag)
{
mag = joydeadzone(basemag, sqrt(joy_anglethreshold[0].value*joy_anglethreshold[0].value + joy_anglethreshold[1].value*joy_anglethreshold[1].value));
jlook[0] = (jlook[0]/basemag) * mag;
jlook[1] = (jlook[1]/basemag) * mag;
}
else
jlook[0] = jlook[1] = 0;
mag = joydeadzone(fabs(jlook[2]), joy_anglethreshold[2].value);
mag = pow(mag, joy_exponent.value);
jlook[2] *= mag;
mag = joydeadzone(sqrt(jstrafe[0]*jstrafe[0] + jstrafe[1]*jstrafe[1]), sqrt(joy_movethreshold[0].value*joy_movethreshold[0].value + joy_movethreshold[1].value*joy_movethreshold[1].value));
mag = pow(mag, joy_exponent.value);
jstrafe[0] *= mag;
jstrafe[1] *= mag;
jlook[2] = mag;
basemag = sqrt(jstrafe[0]*jstrafe[0] + jstrafe[1]*jstrafe[1]);
if (basemag)
{
mag = joydeadzone(basemag, sqrt(joy_movethreshold[0].value*joy_movethreshold[0].value + joy_movethreshold[1].value*joy_movethreshold[1].value));
jstrafe[0] = (jstrafe[0]/basemag) * mag;
jstrafe[1] = (jstrafe[1]/basemag) * mag;
}
else
jstrafe[0] = jstrafe[1] = 0;
mag = joydeadzone(fabs(jstrafe[2]), joy_movethreshold[2].value);
mag = pow(mag, joy_exponent.value);
jstrafe[2] *= mag;
jstrafe[2] = mag;
}
else
{
for (i = 0; i < 3; i++)
{
mag = joydeadzone(fabs(jlook[i]), joy_anglethreshold[i].value);
mag = pow(mag, joy_exponent.value);
jlook[i] *= mag;
jlook[i] = ((jlook[i]<0)?-1:1)*mag;
mag = joydeadzone(fabs(jstrafe[i]), joy_movethreshold[i].value);
mag = pow(mag, joy_exponent.value);
jstrafe[i] *= mag;
jstrafe[i] = ((jstrafe[i]<0)?-1:1)*mag;
}
}
if (IN_WeaponWheelAccumulate(joy->qdeviceid, jstrafe[1]*50, -jstrafe[0]*50, 20))
jstrafe[0] = jstrafe[1] = 0;
if (IN_WeaponWheelAccumulate(joy->qdeviceid, jlook[1]*50, jlook[0]*50, 20))
jlook[0] = jlook[1] = 0;
if (Key_Dest_Has(~kdm_game))
{
VectorClear(jlook);

View file

@ -19,7 +19,7 @@ extern qboolean vid_isfullscreen;
#if SDL_MAJOR_VERSION > 1 || (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3)
#define HAVE_SDL_TEXTINPUT
cvar_t sys_osk = CVARD("sys_osk", "1", "Enables support for text input. This will be ignored when the console has focus, but gamecode may end up with composition boxes appearing.");
cvar_t sys_osk = CVARD("sys_osk", "0", "Enables support for text input. This will be ignored when the console has focus, but gamecode may end up with composition boxes appearing.");
#endif
void IN_ActivateMouse(void)
@ -1053,21 +1053,64 @@ static unsigned int tbl_sdltoquakemouse[] =
K_MOUSE10
};
#ifdef HAVE_SDL_TEXTINPUT
#ifdef __linux__
#include <SDL_misc.h>
static qboolean usesteamosk;
#endif
#endif
void Sys_SendKeyEvents(void)
{
SDL_Event event;
int axis, j;
#ifdef HAVE_SDL_TEXTINPUT
SDL_bool active = SDL_IsTextInputActive();
if (Key_Dest_Has(kdm_console|kdm_message) || (!Key_Dest_Has(~kdm_game) && cls.state == ca_disconnected) || sys_osk.ival)
static SDL_bool active = false;
SDL_bool osk = Key_Dest_Has(kdm_console|kdm_cwindows|kdm_message);
if (Key_Dest_Has(kdm_prompt|kdm_menu))
{
j = Menu_WantOSK();
if (j < 0)
osk |= sys_osk.ival;
else
osk |= j;
}
else if (Key_Dest_Has(kdm_game))
osk |= sys_osk.ival;
if (osk)
{
SDL_Rect rect;
rect.x = 0;
rect.y = vid.rotpixelheight/2;
rect.w = vid.rotpixelwidth;
rect.h = vid.rotpixelheight - rect.y;
SDL_SetTextInputRect(&rect);
if (!active)
{
#ifdef __linux__
if (usesteamosk)
SDL_OpenURL("steam://open/keyboard?Mode=1");
else
#endif
SDL_StartTextInput();
active = true;
// Con_Printf("OSK shown...\n");
}
}
else
{
if (active)
{
#ifdef __linux__
if (usesteamosk)
SDL_OpenURL("steam://close/keyboard?Mode=1");
else
#endif
SDL_StopTextInput();
active = false;
// Con_Printf("OSK shown... killed\n");
}
}
#endif
@ -1411,6 +1454,12 @@ void INS_Init (void)
#ifdef HAVE_SDL_TEXTINPUT
Cvar_Register(&sys_osk, "input controls");
#endif
#ifdef HAVE_SDL_TEXTINPUT
#ifdef __linux__
usesteamosk = SDL_GetHintBoolean("SteamDeck", false); //looks like there's a 'SteamDeck=1' environment setting on the deck (when started via steam itself, at least), so we don't get valve's buggy-as-poop osk on windows etc.
#endif
#endif
}
void INS_Accumulate(void) //input polling
{

View file

@ -29,8 +29,9 @@ void IN_Shutdown (void);
void IN_Commands (void);
// oportunity for devices to stick commands on the script buffer
qboolean IN_MouseDevIsTouch(unsigned int devid); //check if a mouse devid is a touch screen, and thus if we should check the cursor and simulate a ui event or not
int IN_TranslateMButtonPress(unsigned int devid); //allow the touchscreen code to swallow mouse1 as a begin-looking event
void IN_Touch_BlockGestures(unsigned int devid); //prevents any gestures from being generated from the same touch event.
int IN_Touch_Fallback(unsigned int devid); //decides whether a tap should be attack/jump according to m_touchstrafe
qboolean IN_Touch_MouseIsAbs(unsigned int devid);
void IN_Move (float *nudgemovements, float *absmovements, int pnum, float frametime);
// add additional movement on top of the keyboard move cmd

View file

@ -199,6 +199,9 @@ keyname_t keynames[] =
{"MWHEELLEFT", K_MWHEELLEFT},
{"MWHEELRIGHT", K_MWHEELRIGHT},
{"TOUCH", K_TOUCH},
{"TOUCHSLIDE", K_TOUCHSLIDE},
{"TOUCHTAP", K_TOUCHTAP},
{"TOUCHLONG", K_TOUCHLONG},
{"LWIN", K_LWIN}, //windows name
{"RWIN", K_RWIN}, //windows name
@ -758,7 +761,7 @@ qboolean Key_GetConsoleSelectionBox(console_t *con, int *sx, int *sy, int *ex, i
*ey = con->mousecursor[1];
return true;
}
else if (con->buttonsdown == CB_COPY || con->buttonsdown == CB_SELECT)
else if (con->buttonsdown == CB_SELECT || con->buttonsdown == CB_SELECTED)
{
//right-mouse
//select. copy-to-clipboard on release.
@ -1208,60 +1211,18 @@ void Key_HandleConsoleLink(console_t *con, char *buffer)
}
}
#define Key_IsTouchScreen() false
void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
{
char *buffer;
if (key < 0)
key = 0;
if (key == K_MOUSE1 && con->buttonsdown == CB_SELECT)
if ((key == K_TOUCHTAP || key == K_MOUSE1) && con->buttonsdown == CB_SELECT)
{
if (con->selstartline)
{
if (con->userline)
{
if (con->flags & CONF_BACKSELECTION)
{
con->userline = con->selendline;
con->useroffset = con->selendoffset;
con->buttonsdown = CB_SELECTED;
return;
}
else
{
con->userline = con->selstartline;
con->useroffset = con->selstartoffset;
}
}
if (con->selstartline == con->selendline && con->selendoffset <= con->selstartoffset+1)
{
con->flags &= ~CONF_KEEPSELECTION;
if (keydown[K_LSHIFT] || keydown[K_RSHIFT])
;
else
{
buffer = Con_CopyConsole(con, false, true, false);
if (buffer)
{
Key_HandleConsoleLink(con, buffer);
Z_Free(buffer);
}
}
}
else
{
con->flags |= CONF_KEEPSELECTION;
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
if (buffer)
{
Sys_SaveClipboard(CBT_SELECTION, buffer);
Z_Free(buffer);
}
}
}
con->buttonsdown = CB_NONE;
}
if ((key == K_TOUCH || key == K_MOUSE1) && con->buttonsdown == CB_SCROLL)// || (key == K_MOUSE2 && con->buttonsdown == CB_SCROLL_R))
if ((key == K_TOUCHSLIDE || key == K_MOUSE1) && con->buttonsdown == CB_SCROLL)// || (key == K_MOUSE2 && con->buttonsdown == CB_SCROLL_R))
{
con->buttonsdown = CB_NONE;
if (fabs(con->mousedown[0] - con->mousecursor[0]) < 5 && fabs(con->mousedown[1] - con->mousecursor[1]) < 5)
@ -1296,7 +1257,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
else
Con_Footerf(con, false, "");
}
if (key == K_MOUSE2 && con->buttonsdown == CB_COPY)
/*if ((key == K_TOUCHLONG || key == K_MOUSE2) && con->buttonsdown == CB_COPY)
{
con->buttonsdown = CB_NONE;
buffer = Con_CopyConsole(con, true, false, true); //don't keep markup if we're copying to the clipboard
@ -1304,7 +1265,7 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
return;
Sys_SaveClipboard(CBT_CLIPBOARD, buffer);
Z_Free(buffer);
}
}*/
if (con->buttonsdown == CB_CLOSE)
{ //window X (close)
if (con->mousecursor[0] > con->wnd_w-16 && con->mousecursor[1] < 8)
@ -1315,6 +1276,9 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
return;
}
}
if (con->buttonsdown == CB_SELECTED)
; //will time out in the drawing code.
else
// if (con->buttonsdown == CB_MOVE) //window title(move)
con->buttonsdown = CB_NONE;
@ -1878,7 +1842,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
}
if (con->redirect)
{
if (key == K_TOUCH || key == K_MOUSE1 || key == K_MOUSE2)
if (key == K_TOUCHTAP || key == K_TOUCHSLIDE || key == K_TOUCHLONG || key == K_MOUSE1 || key == K_MOUSE2)
;
else if (con->redirect(con, unicode, key))
return true;
@ -1893,7 +1857,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
return true;
}
if (key == K_TOUCH || key == K_MOUSE1 || key == K_MOUSE2)
if (key == K_TOUCHTAP || key == K_TOUCHSLIDE || key == K_TOUCHLONG || key == K_MOUSE1 || key == K_MOUSE2)
{
int olddown[2] = {con->mousedown[0],con->mousedown[1]};
if (con->flags & CONF_ISWINDOW)
@ -1910,7 +1874,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
con->mousedown[1] = con->mousecursor[1];
if (con_mouseover && con->mousedown[1] < 8)//(8.0*vid.height)/vid.pixelheight)
{
if (key == K_MOUSE2 && !(con->flags & CONF_ISWINDOW))
if ((key == K_MOUSE2||key==K_TOUCHLONG) && !(con->flags & CONF_ISWINDOW))
{
if (con->close && !con->close(con, false))
return true;
@ -1931,9 +1895,6 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
return true;
con->flags &= ~CONF_KEEPSELECTION;
if (key == K_TOUCH)
con->buttonsdown = CB_COPY;
else
con->buttonsdown = CB_SCROLL_R;
}
else
@ -1956,7 +1917,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
return true;
}
#endif
if (key == K_TOUCH || con->mousecursor[0] > ((con->flags & CONF_ISWINDOW)?con->wnd_w-16:vid.width)-8)
if (key == K_TOUCHSLIDE || con->mousecursor[0] > ((con->flags & CONF_ISWINDOW)?con->wnd_w-16:vid.width)-8)
{ //just scroll the console up/down
con->buttonsdown = CB_SCROLL;
}
@ -1982,6 +1943,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
con->mousedowntime = realtime;
con->buttonsdown = CB_SELECT;
con->flags &= ~CONF_KEEPSELECTION;
if (shift)
{
@ -1989,15 +1951,16 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
con->mousedown[1] = olddown[1];
}
}
con->flags &= ~CONF_KEEPSELECTION;
}
}
if ((con->buttonsdown == CB_COPY || con->buttonsdown == CB_SCROLL) && !con->linecount && (!con->linebuffered || con->linebuffered == Con_Navigate))
if (con->buttonsdown == CB_SCROLL && !con->linecount && (!con->linebuffered || con->linebuffered == Con_Navigate))
con->buttonsdown = CB_NONE;
else
return true;
}
if (key == K_TOUCH)
return true; //eat it, so we don't get any kind of mouse emu junk
if (key == K_PGUP || key == K_KP_PGUP || key==K_MWHEELUP || key == K_GP_LEFT_THUMB_UP)
{
@ -2289,7 +2252,7 @@ void Key_Message (int key, int unicode)
return;
}
if (key == K_ESCAPE || key == K_GP_DIAMOND_CANCEL)
if (key == K_ESCAPE || key == K_TOUCHLONG || key == K_GP_DIAMOND_CANCEL)
{
Key_Dest_Remove(kdm_message);
chat_bufferpos = 0;
@ -2950,7 +2913,8 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
{
unsigned int devbit = 1u<<devid;
int bl, bkey;
char *dc, *uc;
const char *dc;
char *uc;
char p[16];
int modifierstate;
int conkey = consolekeys[key] || ((unicode || key == '`') && (key != '`' || key_linepos>0)); //if the input line is empty, allow ` to toggle the console, otherwise enter it as actual text.
@ -2984,9 +2948,8 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
shift_down = keydown[K_LSHIFT]|keydown[K_RSHIFT];
}
if (key == K_ESCAPE)
{
if (shift_down)
if ((key == K_ESCAPE && (shift_down &devbit)) ||
(key == K_GP_MENU && (keydown[K_GP_VIEW]&devbit)))
{
extern cvar_t con_stayhidden;
if (down && con_stayhidden.ival < 2)
@ -2996,7 +2959,6 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
return;
}
}
}
//yes, csqc is allowed to steal the escape key.
if (key != '`' && (!down || key != K_ESCAPE || (!Key_Dest_Has(~kdm_game) && !shift_down)) &&
@ -3246,14 +3208,12 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
//gamepad buttons should get fallbacks out of the box, even if they're not initially listed on the binds menu.
//these may be redefined later...
// case K_GP_LEFT_SHOULDER: dc = "impulse 12"; goto defaultedbind; //matches QS's default.cfg
// case K_GP_RIGHT_SHOULDER: dc = "impulse 10"; goto defaultedbind; //matches QS's default.cfg
case K_GP_LEFT_SHOULDER: dc = "impulse 10"; goto defaultedbind;
case K_GP_RIGHT_SHOULDER: dc = "+weaponwheel"; goto defaultedbind;
case K_GP_LEFT_TRIGGER: dc = "+button3"; goto defaultedbind; //matches QS's default.cfg
case K_GP_RIGHT_TRIGGER: dc = "+attack"; goto defaultedbind; //matches QS's default.cfg
case K_GP_LEFT_SHOULDER: dc = "+jump"; goto defaultedbind; //qs: impulse 12 (should be 11 for qw...)
case K_GP_RIGHT_SHOULDER: dc = "+weaponwheel"; goto defaultedbind; //qs: impulse 10
case K_GP_LEFT_TRIGGER: dc = "+button3"; goto defaultedbind; //qs: jump
case K_GP_RIGHT_TRIGGER: dc = "+attack"; goto defaultedbind; //qs: +attack
case K_GP_START: dc = "togglemenu"; goto defaultedbind;
case K_GP_A: dc = "+jump"; goto defaultedbind;
case K_GP_A: dc = "impulse 10"; goto defaultedbind;
case K_GP_B: dc = "+button4"; goto defaultedbind;
case K_GP_X: dc = "+button5"; goto defaultedbind;
case K_GP_Y: dc = "+button6"; goto defaultedbind;
@ -3276,9 +3236,9 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
}
defaultedbind:
if (key == K_TOUCH || (key == K_MOUSE1 && IN_MouseDevIsTouch(devid)))
if (key == K_TOUCH || (key == K_MOUSE1 && IN_Touch_MouseIsAbs(devid)))
{
char *button = SCR_ShowPics_ClickCommand(mousecursor_x, mousecursor_y);
const char *button = SCR_ShowPics_ClickCommand(mousecursor_x, mousecursor_y, key == K_TOUCH);
if (button)
{
dc = button;
@ -3292,18 +3252,19 @@ defaultedbind:
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
else
{
bkey = IN_TranslateMButtonPress(devid);
else if (!Key_MouseShouldBeFree())
return;
}
IN_Touch_BlockGestures(devid);
}
if (key == K_TOUCHTAP && !dc)
{ //convert to mouse1 or mouse2 when touchstrafe is on and touchtap is unbound
bkey = IN_Touch_Fallback(devid);
if (bkey)
{
dc = keybindings[bkey][modifierstate];
bl = bindcmdlevel[bkey][modifierstate];
}
else if (!Key_MouseShouldBeFree())
return;
}
}
}
if (dc)

View file

@ -236,8 +236,6 @@ typedef enum {
K_RSHIFT,
K_PRINTSCREEN,
K_TOUCH,
/* multimedia keyboard */
K_MM_BROWSER_BACK,
K_MM_BROWSER_FAVORITES,
@ -250,6 +248,14 @@ typedef enum {
K_MM_TRACK_PREV,
K_MM_TRACK_STOP,
K_MM_TRACK_PLAYPAUSE,
//touchscreen stuff.
K_TOUCH, //initial touch
//will be paired with one of...
K_TOUCHSLIDE, //existing touch became a slide
K_TOUCHTAP, //touched briefly without sliding (treat like a left-click, though fired on final release)
K_TOUCHLONG, //touch lasted a while and without moving (treat like a right-click)
K_MAX,
//360 buttons
@ -337,6 +343,7 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid);
void Key_Unbindall_f (void); //aka: Key_Shutdown
void Key_ConsoleReplace(const char *instext);
void Key_DefaultLinkClicked(console_t *con, char *text, char *info);
void Key_HandleConsoleLink(console_t *con, char *buffer);
qboolean Key_Console (console_t *con, int key, unsigned int unicode);
void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode);

View file

@ -5685,7 +5685,7 @@ static void MD_Source_Draw (int x, int y, struct menucustom_s *c, struct emenu_s
}
static qboolean MD_Source_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
if (pm_source[c->dint].flags & SRCFL_DISABLED)
{
@ -5744,7 +5744,7 @@ static void MD_AutoUpdate_Draw (int x, int y, struct menucustom_s *c, struct eme
}
static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
char nv[8] = "0";
if (pkg_autoupdate.ival < UPD_TESTING && pkg_autoupdate.ival >= 0)
@ -5759,7 +5759,7 @@ static qboolean MD_AutoUpdate_Key (struct menucustom_s *c, struct emenu_s *m, in
static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
PM_MarkUpdates();
return true;
@ -5770,7 +5770,7 @@ static qboolean MD_MarkUpdatesButton (union menuoption_s *mo,struct emenu_s *m,i
qboolean MD_PopMenu (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
M_RemoveMenu(m);
return true;
@ -5780,7 +5780,7 @@ qboolean MD_PopMenu (union menuoption_s *mo,struct emenu_s *m,int key)
static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
PM_PromptApplyChanges();
return true;
@ -5790,7 +5790,7 @@ static qboolean MD_ApplyDownloads (union menuoption_s *mo,struct emenu_s *m,int
static qboolean MD_RevertUpdates (union menuoption_s *mo,struct emenu_s *m,int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
PM_RevertChanges();
return true;

View file

@ -660,7 +660,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
}
else
{
if (!keydown[K_MOUSE1] && !keydown[K_TOUCH])
if (!keydown[K_MOUSE1] && !keydown[K_TOUCHTAP])
option->frame.mousedown = false;
option->frame.frac = M_DrawScrollbar(xpos+option->frame.common.posx, ypos+option->common.posy, option->frame.common.width, option->frame.common.height, option->frame.frac, option->frame.mousedown);
@ -803,14 +803,14 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
if (bindingactive && menu->selecteditem == option)
Draw_FunString (x, y, "Press key");
else if (!keycount)
Draw_FunString (x, y, "???");
Draw_FunString (x, y, "^8??""?");
else
{
for (j = 0; j < keycount; j++)
{ /*these offsets are wrong*/
if (j)
{
Draw_FunString (x + 8, y, "or");
Draw_FunString (x + 8, y, "^8or");
x += 32;
}
keyname = Key_KeynumToLocalString (keys[j], keymods[j]);
@ -854,6 +854,10 @@ static void MenuDraw(emenu_t *menu)
menu->xpos = ((vid.width - 320)>>1);
if (menu->predraw)
menu->predraw(menu);
if (menu->selecteditem && menu->selecteditem->common.type == mt_text)
menu->menu.showosk = true;
else
menu->menu.showosk = false;
MenuDrawItems(menu->xpos, menu->ypos, menu->options, menu);
// draw tooltip
if (menu->mouseitem && menu->tooltip && realtime > menu->tooltiptime)
@ -1639,7 +1643,7 @@ void MC_Slider_Key(menuslider_t *option, int key)
range = bound(option->min, range, option->max);
option->current = range;
}
else if ((key == K_TOUCH || key == K_MOUSE1) && mousecursor_x >= ix-8 && mousecursor_x < ex+8)
else if ((key == K_TOUCHTAP || 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);
@ -1649,7 +1653,7 @@ void MC_Slider_Key(menuslider_t *option, int key)
range = bound(option->min, range, option->max);
option->current = range;
}
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1 || key == K_TOUCH)
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_MOUSE1 || key == K_TOUCHTAP)
{
if (range == option->max)
range = option->min;
@ -1684,7 +1688,7 @@ void MC_Slider_Key(menuslider_t *option, int key)
void MC_CheckBox_Key(menucheck_t *option, emenu_t *menu, int key)
{
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_START && key != K_GP_DIAMOND_CONFIRM && key != K_GP_DIAMOND_ALTCONFIRM && key != K_LEFTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_LEFT && key != K_GP_LEFT_THUMB_LEFT && key != K_RIGHTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_RIGHT && key != K_GP_LEFT_THUMB_RIGHT && key != K_MWHEELUP && key != K_MWHEELDOWN && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_START && key != K_GP_DIAMOND_CONFIRM && key != K_GP_DIAMOND_ALTCONFIRM && key != K_LEFTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_LEFT && key != K_GP_LEFT_THUMB_LEFT && key != K_RIGHTARROW && key != K_KP_LEFTARROW && key != K_GP_DPAD_RIGHT && key != K_GP_LEFT_THUMB_RIGHT && key != K_MWHEELUP && key != K_MWHEELDOWN && key != K_MOUSE1 && key != K_TOUCHTAP)
return;
if (option->func)
option->func(option, menu, CHK_TOGGLE);
@ -1750,7 +1754,7 @@ void MC_EditBox_Key(menuedit_t *edit, int key, unsigned int unicode)
void MC_Combo_Key(menucombo_t *combo, int key)
{
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_GP_DPAD_RIGHT || key == K_GP_LEFT_THUMB_RIGHT ||key == K_GP_DIAMOND_ALTCONFIRM || key == K_MWHEELDOWN || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_START || key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_GP_DPAD_RIGHT || key == K_GP_LEFT_THUMB_RIGHT ||key == K_GP_DIAMOND_ALTCONFIRM || key == K_MWHEELDOWN || key == K_MOUSE1 || key == K_TOUCHTAP)
{
combo->selectedoption++;
if (combo->selectedoption >= combo->numoptions)
@ -1810,7 +1814,7 @@ static qboolean M_KeyEvent(menu_t *m, qboolean isdown, unsigned int devid, int k
emenu_t *menu = (emenu_t*)m;
if (isdown)
{
if (key == K_MOUSE1 || key == K_TOUCH) //mouse clicks are deferred until the release event. this is for touch screens and aiming.
if (key == K_MOUSE1 || key == K_TOUCHTAP) //mouse clicks are deferred until the release event. this is for touch screens and aiming.
{
if (menu->mouseitem && menu->mouseitem->common.type == mt_frameend)
menu->mouseitem->frame.mousedown = true;
@ -1825,7 +1829,7 @@ static qboolean M_KeyEvent(menu_t *m, qboolean isdown, unsigned int devid, int k
}
else
{
if ((key == K_MOUSE1 || key == K_TOUCH) && menu_mousedown)
if ((key == K_MOUSE1 || key == K_TOUCHTAP) && menu_mousedown)
M_Complex_Key (menu, key, unicode);
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
M_Complex_Key (menu, key, unicode);
@ -2088,6 +2092,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
case K_MOUSE2: //right
case K_MOUSE4: //back
case K_ESCAPE:
case K_TOUCHLONG:
case K_GP_BACK:
case K_GP_START:
case K_GP_DIAMOND_CANCEL:
@ -2193,7 +2198,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
goto goup;
else goto godown;
}
case K_TOUCH:
case K_TOUCHTAP:
case K_MOUSE1:
case K_MOUSE3:
case K_MOUSE5:
@ -2239,7 +2244,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
case mt_qbuttonbigfont:
if (!currentmenu->selecteditem->button.command)
currentmenu->selecteditem->button.key(currentmenu->selecteditem, currentmenu, key);
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_GP_DIAMOND_ALTCONFIRM || key == K_MOUSE1 || key == K_TOUCH)
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_GP_DIAMOND_ALTCONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
Cbuf_AddText(currentmenu->selecteditem->button.command, RESTRICT_LOCAL);
#ifdef HEXEN2
@ -2261,7 +2266,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
MC_Combo_Key(&currentmenu->selecteditem->combo, key);
break;
case mt_bind:
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
bindingactive = true;
else if (key == K_BACKSPACE || key == K_DEL || key == K_GP_DIAMOND_ALTCONFIRM)
M_UnbindCommand (currentmenu->selecteditem->bind.command);

View file

@ -1266,7 +1266,7 @@ qboolean M_Media_Key (int key, emenu_t *menu)
}
}
}
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
else if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
if (key == K_MOUSE1)
{
@ -2549,7 +2549,7 @@ static void MediaView_DrawFilm(menu_t *m)
}
static qboolean MediaView_KeyEvent(menu_t *m, qboolean isdown, unsigned int devid, int key, int unicode)
{
if (isdown && key == K_ESCAPE)
if (isdown && (key == K_ESCAPE || key == K_GP_GUIDE || key == K_GP_DIAMOND_CANCEL || key == K_TOUCHLONG))
{
Media_StopFilm(false); //skip to the next.
return true;

View file

@ -234,7 +234,7 @@ qboolean SetupMenuColour (union menuoption_s *option,struct emenu_s *menu, int k
//but we give the top free reign.
//unless they hold shift, in which case it switches around
//this allows for whatever you want
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MOUSE1 || key == K_TOUCH || key == K_GP_DPAD_RIGHT)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MOUSE1 || key == K_TOUCHTAP || key == K_GP_DPAD_RIGHT)
{
if ((keydown[K_LSHIFT] || keydown[K_RSHIFT]) ^ (ptr == &info->topcolour))
{
@ -570,7 +570,7 @@ qboolean MultiBeginGame (union menuoption_s *option,struct emenu_s *menu, int ke
{
newmultimenu_t *info = menu->data;
char quoted[1024];
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
if (cls.state)

View file

@ -1510,7 +1510,7 @@ qboolean M_PresetApply (union menuoption_s *op, struct emenu_s *menu, int key)
{
fpsmenuinfo_t *info = (fpsmenuinfo_t*)menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
Cbuf_AddText("fps_preset ", RESTRICT_LOCAL);
@ -1771,7 +1771,7 @@ qboolean M_VideoApplyShadowLighting (union menuoption_s *op,struct emenu_s *menu
{
lightingmenuinfo_t *info = (lightingmenuinfo_t*)menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
#ifdef RTLIGHTS
@ -2230,7 +2230,7 @@ qboolean M_Apply_SP_Cheats (union menuoption_s *op,struct emenu_s *menu,int key)
{
singleplayerinfo_t *info = menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
switch(info->skillcombo->selectedoption)
@ -2348,7 +2348,7 @@ qboolean M_Apply_SP_Cheats_Q2 (union menuoption_s *op,struct emenu_s *menu,int k
{
singleplayerq2info_t *info = menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
switch(info->skillcombo->selectedoption)
@ -2554,7 +2554,7 @@ qboolean M_Apply_SP_Cheats_H2 (union menuoption_s *op,struct emenu_s *menu,int k
{
singleplayerh2info_t *info = menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
#ifdef HAVE_SERVER
@ -2810,7 +2810,7 @@ qboolean M_VideoApply (union menuoption_s *op, struct emenu_s *menu, int key)
extern cvar_t vid_desktopsettings;
videomenuinfo_t *info = (videomenuinfo_t*)menu->data;
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCH)
if (key != K_ENTER && key != K_KP_ENTER && key != K_GP_DIAMOND_CONFIRM && key != K_MOUSE1 && key != K_TOUCHTAP)
return false;
// force update display options
@ -4381,7 +4381,7 @@ static void Mods_Draw(int x, int y, struct menucustom_s *c, struct emenu_s *m)
static qboolean Mods_Key(struct menucustom_s *c, struct emenu_s *m, int key, unsigned int unicode)
{
int gameidx = c->dint;
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
qboolean wasgameless = !*FS_GetGamedir(false);
if (!Mods_GetMod(c->dint))
@ -4447,7 +4447,7 @@ static qboolean Installer_Go(menuoption_t *opt, menu_t *menu, int key)
{
struct installermenudata *md = menu->data;
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCH)
if (key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_MOUSE1 || key == K_TOUCHTAP)
{
extern int startuppending;
vfsfile_t *f;

View file

@ -739,7 +739,7 @@ static qboolean M_DemoKey(menucustom_t *control, emenu_t *menu, int key, unsigne
info->selected = info->selected->next;
}
break;
case K_TOUCH:
case K_TOUCHTAP:
case K_MOUSE1:
if (info->dragscroll == 2)
{

View file

@ -153,6 +153,15 @@ void Menu_PopAll(void)
Menu_Unlink(menus[i], true);
}
int Menu_WantOSK(void)
{
if (promptmenu)
return promptmenu->showosk;
if (topmenu)
return topmenu->showosk;
return -1;
}
void Menu_Draw(void)
{
#ifdef MENU_DAT
@ -443,7 +452,7 @@ static qboolean Prompt_MenuKeyEvent(struct menu_s *gm, qboolean isdown, unsigned
void (*callback)(void *, promptbutton_t) = m->callback;
void *ctx = m->ctx;
if (key == K_MOUSE1 || key == K_TOUCH)
if (key == K_MOUSE1 || key == K_TOUCHTAP)
{ //mouse events fire their action on release.
if (isdown)
{
@ -495,10 +504,10 @@ static qboolean Prompt_MenuKeyEvent(struct menu_s *gm, qboolean isdown, unsigned
}
else if (key == K_ESCAPE || key == K_GP_BACK || key == K_MOUSE2 || key == K_MOUSE4 || key == K_GP_DIAMOND_CANCEL)
action = PROMPT_CANCEL;
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1 || key == K_TOUCH || key == K_GP_DIAMOND_CONFIRM)
else if (key == K_ENTER || key == K_KP_ENTER || key == K_MOUSE1 || key == K_TOUCHTAP || key == K_GP_DIAMOND_CONFIRM)
{
int button;
if (key == K_MOUSE1 || key == K_TOUCH)
if (key == K_MOUSE1 || key == K_TOUCHTAP)
button = m->mbutton;
else
button = m->kbutton;
@ -1048,7 +1057,10 @@ void M_Help_Draw (emenu_t *m)
pic = NULL;
}
if (!pic)
{
m->postdraw = M_RemoveMenu;
M_Menu_Main_f ();
}
else
{
//define default aspect ratio

View file

@ -111,10 +111,12 @@ typedef struct menu_s {
qboolean lowpriority; //appears underneath other menus.
qboolean isopaque; //guarentees an opaque background
qboolean persist; //try really hard to not kill this.
qboolean showosk;
} menu_t;
extern menu_t *topmenu; //the currently visible menu.
extern menu_t *promptmenu; //the currently visible prompt (separate from menus, so they always appear over the top of consoles too, they also always show the menu underneath)
void Menu_KeyEvent(qboolean down, int qdeviceid, int key, int unicode);
int Menu_WantOSK(void);
void Menu_Draw(void);
void Prompts_Draw(void);
void Menu_PopAll(void); //attempts to pop all menus (this is for map starts, some might linger)

View file

@ -90,6 +90,9 @@ int MP_TranslateFTEtoQCCodes(keynum_t code)
// case K_MOUSE15: return 528;
// case K_MOUSE16: return 529;
case K_TOUCH: return 600;
case K_TOUCHSLIDE: return 601;
case K_TOUCHTAP: return 602;
case K_TOUCHLONG: return 603;
case K_JOY1: return 768;
case K_JOY2: return 769;
@ -288,6 +291,9 @@ keynum_t MP_TranslateQCtoFTECodes(int code)
// case 528: return K_MOUSE15;
// case 529: return K_MOUSE16;
case 600: return K_TOUCH;
case 601: return K_TOUCHSLIDE;
case 602: return K_TOUCHTAP;
case 603: return K_TOUCHLONG;
case 768: return K_JOY1;
case 769: return K_JOY2;

View file

@ -2893,7 +2893,7 @@ static qboolean MP_KeyEvent(menu_t *menu, qboolean isdown, unsigned int devid, i
PR_ExecuteProgram(menu_world.progs, mpfuncs.inputevent);
result = G_FLOAT(OFS_RETURN);
if (!result && key == K_TOUCH)
{
{ //convert touches to mouse, for compat. gestures are untranslated but expected to be ignored.
G_FLOAT(OFS_PARM0) = isdown?CSIE_KEYDOWN:CSIE_KEYUP;
G_FLOAT(OFS_PARM1) = MP_TranslateFTEtoQCCodes(K_MOUSE1);
G_FLOAT(OFS_PARM2) = unicode;
@ -2908,7 +2908,7 @@ static qboolean MP_KeyEvent(menu_t *menu, qboolean isdown, unsigned int devid, i
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
if (key == K_TOUCH)
key = K_MOUSE1;
key = K_MOUSE1; //old api doesn't expect touches nor provides feedback for emulation. make sure stuff works.
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keydown);
@ -2918,7 +2918,7 @@ static qboolean MP_KeyEvent(menu_t *menu, qboolean isdown, unsigned int devid, i
{
void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT);
if (key == K_TOUCH)
key = K_MOUSE1;
key = K_MOUSE1; //old api doesn't expect touches.
G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key);
G_FLOAT(OFS_PARM1) = unicode;
PR_ExecuteProgram(menu_world.progs, mpfuncs.keyup);

View file

@ -82,7 +82,7 @@ void SCR_ShowPic_Hide(void);
void SCR_ShowPic_Move(void);
void SCR_ShowPic_Update(void);
void SCR_ShowPic_ClearAll(qboolean persistflag);
char *SCR_ShowPics_ClickCommand(int cx, int cy);
const char *SCR_ShowPics_ClickCommand(float cx, float cy, qboolean loadtouch);
void SCR_ShowPic_Script_f(void);
void SCR_ShowPic_Remove_f(void);

View file

@ -969,7 +969,8 @@ int QDECL main(int argc, char **argv)
TL_InitLanguages(parms.basedir);
Sys_Printf ("Host_Init\n");
if (parms.binarydir)
Sys_Printf("Binary is located at \"%s\"\n", parms.binarydir);
Host_Init (&parms);
oldtime = Sys_DoubleTime ();
@ -1071,10 +1072,23 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres
#include <SDL_clipboard.h>
void Sys_Clipboard_PasteText(clipboardtype_t cbt, void (*callback)(void *cb, const char *utf8), void *ctx)
{
callback(ctx, SDL_GetClipboardText());
char *txt;
#if SDL_VERSION_ATLEAST(2,26,0)
if (cbt == CBT_SELECTION)
txt = SDL_GetPrimarySelectionText();
else
#endif
txt = SDL_GetClipboardText();
callback(ctx, txt);
SDL_free(txt);
}
void Sys_SaveClipboard(clipboardtype_t cbt, const char *text)
{
#if SDL_VERSION_ATLEAST(2,26,0)
if (cbt == CBT_SELECTION)
SDL_SetPrimarySelectionText(text);
else
#endif
SDL_SetClipboardText(text);
}
#else

View file

@ -700,6 +700,20 @@ static const char *replacementq1binds =
// "bind F11 +zoom\n"
"bind F12 screenshot\n"
;
static const char *defaulttouchcfg =
"showpic_removeall\n"
// "sv_aim 0.90\n" //quake style, avoid needing to pitch too much
"showpic touch_moveforward.tga fwd -128 -112 bm 32 32 +forward 5\n"
"showpic touch_moveback.tga back -128 -80 bm 32 32 +back 5\n"
"showpic touch_moveleft.tga left -160 -88 bm 32 32 +moveleft 5\n"
"showpic touch_moveright.tga rght -96 -88 bm 32 32 +moveright 5\n"
"showpic touch_attack.tga fire -160 -160 bm 32 32 +attack 5\n"
"showpic touch_jump.tga jump 128 -80 bm 32 32 +jump 5\n"
"showpic touch_weapons.tga weap 80 -80 bm 32 32 +weaponwheel 5\n"
"showpic touch_menu.tga menu -32 0 tr 32 32 togglemenu 10\n"
;
#endif
/*
@ -785,9 +799,9 @@ static void Cmd_Exec_f (void)
if (!strncmp(name, "../", 3) || !strncmp(name, "..\\", 3) || !strncmp(name, "./", 2) || !strncmp(name, ".\\", 2))
{ //filesystem will correctly block this (and more), but it does look dodgy when servers try doing this dodgy shit anyway.
if (Cmd_IsInsecure())
Con_TPrintf ("exec: %s is an invalid path (from server)\n", name);
Con_TPrintf ("%s: %s is an invalid path (from server)\n", Cmd_Argv(0), name);
else
Con_TPrintf ("exec: %s is an invalid path\n", name);
Con_TPrintf ("%s: %s is an invalid path\n", Cmd_Argv(0), name);
return;
}
@ -796,7 +810,7 @@ static void Cmd_Exec_f (void)
file = FS_OpenReadLocation(name, &loc);
if (!file)
{
Con_TPrintf ("couldn't exec %s. check permissions.\n", name);
Con_TPrintf ("couldn't %s %s. check permissions.\n", Cmd_Argv(0), name);
return;
}
@ -815,6 +829,12 @@ static void Cmd_Exec_f (void)
untrusted = false;
l = 0;
}
else if (!strcmp(name, "touch.cfg")) //auto-execed if they touch a touchscreen.
{
f = Z_StrDup(defaulttouchcfg);
untrusted = false;
l = 0;
}
#endif
else
{

View file

@ -119,14 +119,15 @@ enum
{
CB_NONE = 0,
CB_SCROLL = 1,
CB_COPY = 2,
CB_SCROLL_R = 2,
CB_CLOSE = 3,
CB_MOVE = 4,
CB_ACTIONBAR = 5,
CB_SELECT = 6,
CB_SCROLL_R = 7,
CB_SELECTED = 7,
//the flags part
CB_STALE = (1u<<28), //WAS held last frame - to make sure we still do stuff when released on the same frame.
CB_SIZELEFT = (1u<<29),
CB_SIZERIGHT = (1u<<30),
CB_SIZEBOTTOM = (1u<<31),