mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-27 14:12:25 +00:00
2cad75bc69
Removed the impulse2/+forward2 etc commands. Added +p2, -p2, p2 commands as a prefixed command instead. don't use + or - on them (so '+p2 forward' to move player 2 forward), this permits a simple generic way to send commands to a single player from an input device. rawinput mice will submit commands/movements based upon idx%maxsplits, they will correctly submit mouse clicks, which will be mapped through the +p2/+p3 commands as appropriate, so each mouse is purely for a single player. Fixed player model visibility in splitscreen mode. Ignoring allow_splitscreen for the local player, cl_splitscreen is technically now the only enabler (though you will need to configure rawinput or binds). Added support for { texturename prefixes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3582 fc73d0e0-1445-4013-8a0c-d673dee63da5
638 lines
9.7 KiB
C
638 lines
9.7 KiB
C
/*
|
|
Copyright (C) 2006-2007 Mark Olsen
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#include <exec/exec.h>
|
|
#include <intuition/intuition.h>
|
|
#include <intuition/extensions.h>
|
|
#include <intuition/intuitionbase.h>
|
|
#include <devices/input.h>
|
|
|
|
#include <proto/exec.h>
|
|
#include <proto/intuition.h>
|
|
|
|
#include <clib/alib_protos.h>
|
|
|
|
#include "quakedef.h"
|
|
#include "input.h"
|
|
|
|
#include "in_morphos.h"
|
|
|
|
cvar_t in_xflip = {"in_xflip", "0"};
|
|
|
|
struct InputEvent imsgs[MAXIMSGS];
|
|
extern struct IntuitionBase *IntuitionBase;
|
|
extern struct Window *window;
|
|
extern struct Screen *screen;
|
|
|
|
int imsglow = 0;
|
|
int imsghigh = 0;
|
|
|
|
extern qboolean mouse_active;
|
|
|
|
static struct Interrupt InputHandler;
|
|
|
|
static struct Interrupt InputHandler;
|
|
static struct MsgPort *inputport = 0;
|
|
static struct IOStdReq *inputreq = 0;
|
|
static BYTE inputret = -1;
|
|
|
|
cvar_t m_filter = {"m_filter", "1", CVAR_ARCHIVE};
|
|
|
|
extern cvar_t _windowed_mouse;
|
|
|
|
float mouse_x, mouse_y;
|
|
float old_mouse_x, old_mouse_y;
|
|
|
|
#define DEBUGRING(x)
|
|
|
|
void IN_Shutdown(void)
|
|
{
|
|
if (inputret == 0)
|
|
{
|
|
inputreq->io_Data = (void *)&InputHandler;
|
|
inputreq->io_Command = IND_REMHANDLER;
|
|
DoIO((struct IORequest *)inputreq);
|
|
|
|
CloseDevice((struct IORequest *)inputreq);
|
|
|
|
inputret = -1;
|
|
}
|
|
|
|
if (inputreq)
|
|
{
|
|
DeleteStdIO(inputreq);
|
|
|
|
inputreq = 0;
|
|
}
|
|
|
|
if (inputport)
|
|
{
|
|
DeletePort(inputport);
|
|
|
|
inputport = 0;
|
|
}
|
|
}
|
|
|
|
void IN_ReInit()
|
|
{
|
|
/* Cvar_Register (&m_filter, "input controls");*/
|
|
|
|
inputport = CreatePort(0, 0);
|
|
if (inputport == 0)
|
|
{
|
|
IN_Shutdown();
|
|
Sys_Error("Unable to create message port");
|
|
}
|
|
|
|
inputreq = CreateStdIO(inputport);
|
|
if (inputreq == 0)
|
|
{
|
|
IN_Shutdown();
|
|
Sys_Error("Unable to create IO request");
|
|
}
|
|
|
|
inputret = OpenDevice("input.device", 0, (struct IORequest *)inputreq, 0);
|
|
if (inputret != 0)
|
|
{
|
|
IN_Shutdown();
|
|
Sys_Error("Unable to open input.device");
|
|
}
|
|
|
|
InputHandler.is_Node.ln_Type = NT_INTERRUPT;
|
|
InputHandler.is_Node.ln_Pri = 100;
|
|
InputHandler.is_Node.ln_Name = "FTEQW input handler";
|
|
InputHandler.is_Data = 0;
|
|
InputHandler.is_Code = (void(*)())&myinputhandler;
|
|
inputreq->io_Data = (void *)&InputHandler;
|
|
inputreq->io_Command = IND_ADDHANDLER;
|
|
DoIO((struct IORequest *)inputreq);
|
|
}
|
|
|
|
void IN_Init(void)
|
|
{
|
|
Cvar_Register (&in_xflip, "input controls");
|
|
IN_ReInit();
|
|
}
|
|
|
|
static void ExpireRingBuffer()
|
|
{
|
|
int i = 0;
|
|
|
|
while(imsgs[imsglow].ie_Class == IECLASS_NULL && imsglow != imsghigh)
|
|
{
|
|
imsglow++;
|
|
i++;
|
|
imsglow%= MAXIMSGS;
|
|
}
|
|
|
|
DEBUGRING(dprintf("Expired %d messages\n", i));
|
|
}
|
|
|
|
void IN_Commands(void)
|
|
{
|
|
int a;
|
|
char key;
|
|
int i;
|
|
int down;
|
|
struct InputEvent ie;
|
|
|
|
for(i = imsglow;i != imsghigh;i++, i%= MAXIMSGS)
|
|
{
|
|
DEBUGRING(dprintf("%d %d\n", i, imsghigh));
|
|
if ((window->Flags & WFLG_WINDOWACTIVE))
|
|
{
|
|
if (imsgs[i].ie_Class == IECLASS_NEWMOUSE)
|
|
{
|
|
key = 0;
|
|
|
|
if (imsgs[i].ie_Code == NM_WHEEL_UP)
|
|
key = K_MWHEELUP;
|
|
else if (imsgs[i].ie_Code == NM_WHEEL_DOWN)
|
|
key = K_MWHEELDOWN;
|
|
|
|
if (imsgs[i].ie_Code == NM_BUTTON_FOURTH)
|
|
{
|
|
Key_Event(0, K_MOUSE4, 0, true);
|
|
}
|
|
else if (imsgs[i].ie_Code == (NM_BUTTON_FOURTH|IECODE_UP_PREFIX))
|
|
{
|
|
Key_Event(0, K_MOUSE4, 0, false);
|
|
}
|
|
|
|
if (key)
|
|
{
|
|
Key_Event(0, key, 0, 1);
|
|
Key_Event(0, key, 0, 0);
|
|
}
|
|
|
|
}
|
|
else if (imsgs[i].ie_Class == IECLASS_RAWKEY)
|
|
{
|
|
down = !(imsgs[i].ie_Code&IECODE_UP_PREFIX);
|
|
imsgs[i].ie_Code&=~IECODE_UP_PREFIX;
|
|
|
|
memcpy(&ie, &imsgs[i], sizeof(ie));
|
|
|
|
key = 0;
|
|
if (imsgs[i].ie_Code <= 255)
|
|
key = keyconv[imsgs[i].ie_Code];
|
|
|
|
if (key)
|
|
Key_Event(0, key, key, down);
|
|
else
|
|
{
|
|
if (developer.value)
|
|
Con_Printf("Unknown key %d\n", imsgs[i].ie_Code);
|
|
}
|
|
}
|
|
|
|
else if (imsgs[i].ie_Class == IECLASS_RAWMOUSE)
|
|
{
|
|
if (imsgs[i].ie_Code == IECODE_LBUTTON)
|
|
Key_Event(0, K_MOUSE1, 0, true);
|
|
else if (imsgs[i].ie_Code == (IECODE_LBUTTON|IECODE_UP_PREFIX))
|
|
Key_Event(0, K_MOUSE1, 0, false);
|
|
else if (imsgs[i].ie_Code == IECODE_RBUTTON)
|
|
Key_Event(0, K_MOUSE2, 0, true);
|
|
else if (imsgs[i].ie_Code == (IECODE_RBUTTON|IECODE_UP_PREFIX))
|
|
Key_Event(0, K_MOUSE2, 0, false);
|
|
else if (imsgs[i].ie_Code == IECODE_MBUTTON)
|
|
Key_Event(0, K_MOUSE3, 0, true);
|
|
else if (imsgs[i].ie_Code == (IECODE_MBUTTON|IECODE_UP_PREFIX))
|
|
Key_Event(0, K_MOUSE3, 0, false);
|
|
|
|
mouse_x+= imsgs[i].ie_position.ie_xy.ie_x;
|
|
mouse_y+= imsgs[i].ie_position.ie_xy.ie_y;
|
|
}
|
|
|
|
}
|
|
|
|
imsgs[i].ie_Class = IECLASS_NULL;
|
|
|
|
}
|
|
|
|
ExpireRingBuffer();
|
|
|
|
}
|
|
|
|
void IN_Move (float *movements, int pnum)
|
|
{
|
|
extern int mousecursor_x, mousecursor_y;
|
|
extern int mousemove_x, mousemove_y;
|
|
|
|
if (pnum != 0)
|
|
return; //we're lazy today.
|
|
|
|
if (m_filter.value) {
|
|
mouse_x = (mouse_x + old_mouse_x) * 0.5;
|
|
mouse_y = (mouse_y + old_mouse_y) * 0.5;
|
|
}
|
|
|
|
old_mouse_x = mouse_x;
|
|
old_mouse_y = mouse_y;
|
|
|
|
#ifdef IN_XFLIP
|
|
if(in_xflip.value) mouse_x *= -1;
|
|
#endif
|
|
|
|
if (Key_MouseShouldBeFree())
|
|
{
|
|
mousemove_x += mouse_x;
|
|
mousemove_y += mouse_y;
|
|
mousecursor_x += mouse_x;
|
|
mousecursor_y += mouse_y;
|
|
|
|
if (mousecursor_y<0)
|
|
mousecursor_y=0;
|
|
if (mousecursor_x<0)
|
|
mousecursor_x=0;
|
|
|
|
if (mousecursor_x >= vid.width)
|
|
mousecursor_x = vid.width - 1;
|
|
|
|
if (mousecursor_y >= vid.height)
|
|
mousecursor_y = vid.height - 1;
|
|
|
|
mouse_x = mouse_y = 0;
|
|
#ifdef VM_UI
|
|
UI_MousePosition(mousecursor_x, mousecursor_y);
|
|
#endif
|
|
}
|
|
|
|
|
|
mouse_x *= sensitivity.value;
|
|
mouse_y *= sensitivity.value;
|
|
|
|
if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) ))
|
|
{
|
|
if (movements)
|
|
movements[1] += m_side.value * mouse_x;
|
|
}
|
|
else
|
|
{
|
|
cl.viewangles[pnum][YAW] -= m_yaw.value * mouse_x;
|
|
}
|
|
if (in_mlook.state[pnum] & 1)
|
|
V_StopPitchDrift (pnum);
|
|
|
|
if ( (in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1)) {
|
|
cl.viewangles[pnum][PITCH] += m_pitch.value * mouse_y;
|
|
CL_ClampPitch(pnum);
|
|
} else {
|
|
if (movements)
|
|
{
|
|
if ((in_strafe.state[pnum] & 1) && noclip_anglehack)
|
|
movements[2] -= m_forward.value * mouse_y;
|
|
else
|
|
movements[0] -= m_forward.value * mouse_y;
|
|
}
|
|
}
|
|
mouse_x = mouse_y = 0.0;
|
|
}
|
|
|
|
char keyconv[] =
|
|
{
|
|
'`', /* 0 */
|
|
'1',
|
|
'2',
|
|
'3',
|
|
'4',
|
|
'5',
|
|
'6',
|
|
'7',
|
|
'8',
|
|
'9',
|
|
'0', /* 10 */
|
|
'-',
|
|
'=',
|
|
0,
|
|
0,
|
|
K_INS,
|
|
'q',
|
|
'w',
|
|
'e',
|
|
'r',
|
|
't', /* 20 */
|
|
'y',
|
|
'u',
|
|
'i',
|
|
'o',
|
|
'p',
|
|
'[',
|
|
']',
|
|
0,
|
|
K_KP_END,
|
|
K_KP_DOWNARROW, /* 30 */
|
|
K_KP_PGDN,
|
|
'a',
|
|
's',
|
|
'd',
|
|
'f',
|
|
'g',
|
|
'h',
|
|
'j',
|
|
'k',
|
|
'l', /* 40 */
|
|
';',
|
|
'\'',
|
|
'\\',
|
|
0,
|
|
K_KP_LEFTARROW,
|
|
K_KP_5,
|
|
K_KP_RIGHTARROW,
|
|
'<',
|
|
'z',
|
|
'x', /* 50 */
|
|
'c',
|
|
'v',
|
|
'b',
|
|
'n',
|
|
'm',
|
|
',',
|
|
'.',
|
|
'/',
|
|
0,
|
|
K_KP_DEL, /* 60 */
|
|
K_KP_HOME,
|
|
K_KP_UPARROW,
|
|
K_KP_PGUP,
|
|
' ',
|
|
K_BACKSPACE,
|
|
K_TAB,
|
|
K_KP_ENTER,
|
|
K_ENTER,
|
|
K_ESCAPE,
|
|
K_DEL, /* 70 */
|
|
K_INS,
|
|
K_PGUP,
|
|
K_PGDN,
|
|
K_KP_MINUS,
|
|
K_F11,
|
|
K_UPARROW,
|
|
K_DOWNARROW,
|
|
K_RIGHTARROW,
|
|
K_LEFTARROW,
|
|
K_F1, /* 80 */
|
|
K_F2,
|
|
K_F3,
|
|
K_F4,
|
|
K_F5,
|
|
K_F6,
|
|
K_F7,
|
|
K_F8,
|
|
K_F9,
|
|
K_F10,
|
|
0, /* 90 */
|
|
0,
|
|
K_KP_SLASH,
|
|
0,
|
|
K_KP_PLUS,
|
|
0,
|
|
K_SHIFT,
|
|
K_SHIFT,
|
|
K_CAPSLOCK,
|
|
K_CTRL,
|
|
K_ALT, /* 100 */
|
|
K_ALT,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
K_PAUSE, /* 110 */
|
|
K_F12,
|
|
K_HOME,
|
|
K_END,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 120 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 130 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 140 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 150 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 160 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 170 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 180 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 190 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 200 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 210 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 220 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 230 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 240 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0, /* 250 */
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
};
|
|
|
|
struct InputEvent *myinputhandler_real(void);
|
|
|
|
struct EmulLibEntry myinputhandler =
|
|
{
|
|
TRAP_LIB, 0, (void(*)(void))myinputhandler_real
|
|
};
|
|
|
|
struct InputEvent *myinputhandler_real()
|
|
{
|
|
struct InputEvent *moo = (struct InputEvent *)REG_A0;
|
|
|
|
struct InputEvent *coin;
|
|
|
|
int screeninfront;
|
|
|
|
coin = moo;
|
|
|
|
if (screen)
|
|
{
|
|
#if 0
|
|
if (IntuitionBase->LibNode.lib_Version > 50 || (IntuitionBase == 50 && IntuitionBase->LibNode.lib_Revision >= 56))
|
|
GetAttr(screen, SA_Displayed, &screeninfront);
|
|
else
|
|
#endif
|
|
screeninfront = screen==IntuitionBase->FirstScreen;
|
|
}
|
|
else
|
|
screeninfront = 1;
|
|
|
|
do
|
|
{
|
|
if (coin->ie_Class == IECLASS_RAWMOUSE || coin->ie_Class == IECLASS_RAWKEY || coin->ie_Class == IECLASS_NEWMOUSE)
|
|
{
|
|
/* kprintf("Mouse\n");*/
|
|
|
|
if ((imsghigh > imsglow && !(imsghigh == MAXIMSGS-1 && imsglow == 0)) || (imsghigh < imsglow && imsghigh != imsglow-1) || imsglow == imsghigh)
|
|
{
|
|
memcpy(&imsgs[imsghigh], coin, sizeof(imsgs[0]));
|
|
imsghigh++;
|
|
imsghigh%= MAXIMSGS;
|
|
}
|
|
else
|
|
{
|
|
DEBUGRING(kprintf("FTE: message dropped, imsglow = %d, imsghigh = %d\n", imsglow, imsghigh));
|
|
}
|
|
|
|
if (/*mouse_active && */(window->Flags & WFLG_WINDOWACTIVE) && coin->ie_Class == IECLASS_RAWMOUSE && screeninfront && window->MouseX > 0 && window->MouseY > 0)
|
|
{
|
|
if (_windowed_mouse.value)
|
|
{
|
|
#if 0
|
|
coin->ie_Class = IECLASS_NULL;
|
|
#else
|
|
coin->ie_position.ie_xy.ie_x = 0;
|
|
coin->ie_position.ie_xy.ie_y = 0;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
coin = coin->ie_NextEvent;
|
|
} while(coin);
|
|
|
|
return moo;
|
|
}
|
|
|