mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 23:22:01 +00:00
445e7f476b
mouse+kb+soundblaster devices should work. you can compile a dedicated server, but the lack of any networking support makes it a bit pointless. the software renderer will work, but its crap and gets absolutely dire framerates. there's no code to init mesa or anything, so its crappy-software rendering only. I doubt anything useful will ever result from this, but it was still interesting to do. possibly the only useful thing to come from this will be from limiting ram use. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5104 fc73d0e0-1445-4013-8a0c-d673dee63da5
185 lines
5.5 KiB
C
185 lines
5.5 KiB
C
#include <quakedef.h>
|
|
|
|
//because cake.
|
|
#include "sys_linux.c"
|
|
|
|
#include <dos.h>
|
|
#include <dpmi.h>
|
|
_go32_dpmi_registers regs;
|
|
int dos_int86(int vec)
|
|
{
|
|
int rc;
|
|
regs.x.ss = regs.x.sp = 0;
|
|
rc = _go32_dpmi_simulate_int(vec, ®s);
|
|
return rc || (regs.x.flags & 1);
|
|
}
|
|
|
|
|
|
static int mouse_buttons;
|
|
static int mouse_numbuttons;
|
|
static unsigned int dosmousedeviceid;
|
|
|
|
static unsigned int doskeyboarddeviceid;
|
|
|
|
#define KBRINGSIZE 256
|
|
static struct
|
|
{
|
|
unsigned char buf[KBRINGSIZE];
|
|
int write;
|
|
int read;
|
|
} kbring;
|
|
|
|
void TheKBHandler(void)
|
|
{ //this needs to be kept simple and small.
|
|
//we write to a really simple ringbuffer to avoid needing to lock various code/data pages.
|
|
kbring.buf[kbring.write++&(KBRINGSIZE-1)] = inportb(0x60);
|
|
outportb(0x20, 0x20);
|
|
}
|
|
|
|
unsigned char keymap[256] =
|
|
{
|
|
//this is a copy of the US keymap from vanilla quake.
|
|
//its so very tempting to switch it to a UK keymap...
|
|
|
|
// 0 1 2 3 4 5 6 7
|
|
// 8 9 A B C D E F
|
|
0 , 27, '1', '2', '3', '4', '5', '6',
|
|
'7', '8', '9', '0', '-', '=', K_BACKSPACE,K_TAB, // 0
|
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
|
'o', 'p', '[', ']', 13 , K_CTRL, 'a', 's', // 1
|
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
|
'\'' , '`', K_LSHIFT,'\\', 'z', 'x', 'c', 'v', // 2
|
|
'b', 'n', 'm', ',', '.', '/', K_RSHIFT, '*',
|
|
K_ALT, ' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
|
|
K_F6, K_F7, K_F8, K_F9, K_F10, 0 , 0 , K_HOME,
|
|
K_UPARROW, K_PGUP, '-', K_LEFTARROW,'5', K_RIGHTARROW,'+', K_END, // 4
|
|
K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0 , 0, K_F11,
|
|
K_F12, 0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 7
|
|
|
|
// 0 1 2 3 4 5 6 7
|
|
// 8 9 A B C D E F
|
|
0 , 27, '!', '@', '#', '$', '%', '^',
|
|
'&', '*', '(', ')', '_', '+', K_BACKSPACE,K_TAB, // 0
|
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
|
|
'O', 'P', '{', '}', 13 , K_CTRL, 'A', 'S', // 1
|
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
|
|
'\"', '~', K_LSHIFT,'|', 'Z', 'X', 'C', 'V', // 2
|
|
'B', 'N', 'M', '<', '>', '?', K_RSHIFT, '*',
|
|
K_ALT, ' ', 0 , K_F1, K_F2, K_F3, K_F4, K_F5, // 3
|
|
K_F6, K_F7, K_F8, K_F9, K_F10, 0 , 0 , K_HOME,
|
|
K_UPARROW, K_PGUP, '_', K_LEFTARROW,'%', K_RIGHTARROW,'+', K_END, // 4
|
|
K_DOWNARROW,K_PGDN, K_INS, K_DEL, 0, 0, 0, K_F11,
|
|
K_F12, 0 , 0 , 0 , 0 , 0 , 0 , 0, // 5
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, // 6
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,
|
|
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 // 7
|
|
};
|
|
|
|
void INS_Init(void)
|
|
{
|
|
//make sure the kb handler and its data won't get paged out.
|
|
_go32_dpmi_lock_code((void *) TheKBHandler, 512);
|
|
_go32_dpmi_lock_data((void *) &kbring, sizeof(kbring));
|
|
|
|
//set up our interrupt handler.
|
|
_go32_dpmi_seginfo info;
|
|
info.pm_offset = (int) TheKBHandler;
|
|
_go32_dpmi_allocate_iret_wrapper(&info);
|
|
_go32_dpmi_set_protected_mode_interrupt_vector(9, &info);
|
|
}
|
|
|
|
void Sys_SendKeyEvents(void)
|
|
{ //this is kinda silly, but the handler can't do it if we want to be correct with respect to virtual memory.
|
|
static int shift_down;
|
|
while (kbring.read != kbring.write)
|
|
{ //keyboard maps are complicated, annoyingly so. left/right/extended.... and don't get me started on sysreq. some keys don't even have release events!
|
|
unsigned char c = kbring.buf[kbring.read++&(KBRINGSIZE-1)];
|
|
unsigned int qkey, ukey;
|
|
|
|
qkey = keymap[c&0x7f];
|
|
ukey = (qkey >= 32 && qkey < 127)?keymap[(c&0x7f)|(shift_down?128:0)]:0;
|
|
if (c == 0xe0)
|
|
{ //extended keys...
|
|
if (kbring.buf[kbring.read&(KBRINGSIZE-1)] == 0x1d)
|
|
qkey = K_RSHIFT;
|
|
else
|
|
continue; //annoying extended keys.
|
|
ukey = 0;
|
|
kbring.read++;
|
|
}
|
|
if (qkey == K_LSHIFT)
|
|
shift_down = (shift_down&~1) | ((c&0x80)?0:1);
|
|
if (qkey == K_RSHIFT)
|
|
shift_down = (shift_down&~2) | ((c&0x80)?0:2);
|
|
// Con_Printf("Keyboard: %x\n", c);
|
|
IN_KeyEvent(doskeyboarddeviceid, !(c&0x80), qkey, ukey);
|
|
}
|
|
}
|
|
|
|
void INS_Move(float *movements, int pnum)
|
|
{
|
|
}
|
|
void INS_Commands(void)
|
|
{
|
|
if (!mouse_numbuttons)
|
|
return;
|
|
|
|
regs.x.ax = 11; // read move
|
|
dos_int86(0x33);
|
|
if (regs.x.cx || regs.x.dx)
|
|
{
|
|
IN_MouseMove(dosmousedeviceid, false, (short)regs.x.cx, (short)regs.x.dx, 0, 0);
|
|
|
|
Con_Printf("Mouse Move: %i %i\n", (short)regs.x.cx, (short)regs.x.dx);
|
|
}
|
|
|
|
regs.x.ax = 3; // read buttons
|
|
dos_int86(0x33);
|
|
int b = mouse_buttons ^ regs.x.bx;
|
|
mouse_buttons = regs.x.bx;
|
|
for (int i = 0; i < mouse_numbuttons; i++)
|
|
{
|
|
if (b&(1u<<i))
|
|
IN_KeyEvent(dosmousedeviceid, !!(mouse_buttons&(1u<<i)), K_MOUSE1+i, 0);
|
|
}
|
|
|
|
Sys_SendKeyEvents();
|
|
}
|
|
void INS_ReInit(void)
|
|
{
|
|
dosmousedeviceid = 0;
|
|
mouse_buttons = 0;
|
|
mouse_numbuttons = 0;
|
|
|
|
regs.x.ax = 0;
|
|
dos_int86(0x33);
|
|
if (!regs.x.ax)
|
|
{
|
|
Con_Printf ("No mouse found\n");
|
|
return;
|
|
}
|
|
mouse_numbuttons = regs.x.bx;
|
|
if (mouse_numbuttons >= 255)
|
|
mouse_numbuttons = 2;
|
|
if (mouse_numbuttons > 10)
|
|
mouse_numbuttons = 10;
|
|
Con_Printf("%d-button mouse available\n", mouse_numbuttons);
|
|
}
|
|
void INS_Shutdown(void)
|
|
{
|
|
}
|
|
void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type, const char *devicename, unsigned int *qdevid))
|
|
{
|
|
callback(ctx, "mouse", "dosmouse", &dosmousedeviceid);
|
|
callback(ctx, "keyboard", "doskeyboard", &doskeyboarddeviceid);
|
|
}
|
|
|
|
void Sys_Sleep (double seconds)
|
|
{
|
|
usleep(seconds * 1000000);
|
|
}
|