mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-28 05:30:43 +00:00
629 lines
No EOL
13 KiB
C
629 lines
No EOL
13 KiB
C
#include <stdlib.h>
|
|
#include <dpmi.h>
|
|
#include <go32.h>
|
|
#include <pc.h>
|
|
|
|
#include "m_argv.h"
|
|
#include "i_input.h"
|
|
#include "i_system.h"
|
|
#include "v_video.h"
|
|
#include "d_main.h"
|
|
#include "c_consol.h"
|
|
#include "c_cvars.h"
|
|
#include "i_video.h"
|
|
|
|
// from allegro.h
|
|
#define END_OF_FUNCTION(x) void x##_end() { }
|
|
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void *)&x, sizeof(x))
|
|
#define LOCK_FUNCTION(x) _go32_dpmi_lock_code(x, (long)x##_end - (long)x)
|
|
|
|
static void I_StartupKeyboard (void);
|
|
static void I_ShutdownKeyboard (void);
|
|
static void I_StartupMouse (void);
|
|
static void I_ShutdownMouse (void);
|
|
#if 0
|
|
static void I_StartupJoystick (void);
|
|
static void I_JoystickEvents (void);
|
|
#endif
|
|
|
|
#define KEYBOARDINT 9
|
|
|
|
#define _outbyte(x,y) (outp(x,y))
|
|
#define _outhword(x,y) (outpw(x,y))
|
|
|
|
#define _inbyte(x) (inp(x))
|
|
#define _inhword(x) (inpw(x))
|
|
|
|
#define DIK_LSHIFT 0x2A
|
|
#define DIK_RSHIFT 0x36
|
|
#define DIK_MULTIPLY 0x37 /* * on numeric keypad */
|
|
#define DIK_1 0x02
|
|
#define DIK_2 0x03
|
|
#define DIK_3 0x04
|
|
#define DIK_4 0x05
|
|
#define DIK_5 0x06
|
|
#define DIK_6 0x07
|
|
#define DIK_7 0x08
|
|
#define DIK_8 0x09
|
|
#define DIK_9 0x0A
|
|
#define DIK_0 0x0B
|
|
#define DIK_NUMPAD7 0x47
|
|
#define DIK_NUMPAD8 0x48
|
|
#define DIK_NUMPAD9 0x49
|
|
#define DIK_SUBTRACT 0x4A /* - on numeric keypad */
|
|
#define DIK_NUMPAD4 0x4B
|
|
#define DIK_NUMPAD5 0x4C
|
|
#define DIK_NUMPAD6 0x4D
|
|
#define DIK_ADD 0x4E /* + on numeric keypad */
|
|
#define DIK_NUMPAD1 0x4F
|
|
#define DIK_NUMPAD2 0x50
|
|
#define DIK_NUMPAD3 0x51
|
|
#define DIK_NUMPAD0 0x52
|
|
#define DIK_DECIMAL 0x53 /* . on numeric keypad */
|
|
#define DIK_DIVIDE 0xB5 /* / on numeric keypad */
|
|
#define DIK_HOME 0xC7 /* Home on arrow keypad */
|
|
#define DIK_UP 0xC8 /* UpArrow on arrow keypad */
|
|
#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */
|
|
#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */
|
|
#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */
|
|
#define DIK_END 0xCF /* End on arrow keypad */
|
|
#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */
|
|
#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */
|
|
#define DIK_INSERT 0xD2 /* Insert on arrow keypad */
|
|
#define DIK_DELETE 0xD3 /* Delete on arrow keypad */
|
|
|
|
#define KBDQUESIZE 32
|
|
static byte keyboardque[KBDQUESIZE];
|
|
static unsigned int kbdtail, kbdhead;
|
|
static BOOL shiftdown;
|
|
|
|
// Used by the console for making keys repeat
|
|
int KeyRepeatDelay;
|
|
int KeyRepeatRate;
|
|
|
|
extern constate_e ConsoleState;
|
|
extern BOOL menuactive;
|
|
|
|
cvar_t *i_remapkeypad;
|
|
cvar_t *usejoystick;
|
|
cvar_t *usemouse;
|
|
|
|
BOOL I_InitInput (void)
|
|
{
|
|
atexit (I_ShutdownInput);
|
|
|
|
Printf (PRINT_HIGH, "I_StartupMouse\n");
|
|
I_StartupMouse ();
|
|
// Printf (PRINT_HIGH, "I_StartupJoystick\n");
|
|
// I_StartupJoystick ();
|
|
Printf (PRINT_HIGH, "I_StartupKeyboard\n");
|
|
I_StartupKeyboard ();
|
|
|
|
KeyRepeatDelay = (250 * TICRATE) / 1000;
|
|
KeyRepeatRate = TICRATE / 15;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Free all input resources
|
|
void I_ShutdownInput (void)
|
|
{
|
|
I_ShutdownMouse ();
|
|
I_ShutdownKeyboard ();
|
|
}
|
|
|
|
|
|
/****** Keyboard Routines ******/
|
|
|
|
static const byte Convert [256] =
|
|
{
|
|
// 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', '-', '=', 8, 9, // 0
|
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, 0, 'a', 's', // 1
|
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`', 0,'\\', 'z', 'x', 'c', 'v', // 2
|
|
'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, // 3
|
|
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', // 4
|
|
'2', '3', '0', '.', 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '=', 0, 0, // 8
|
|
0, '@', ':', '_', 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, // 9
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
|
|
0, 0, 0, ',', 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
|
|
};
|
|
|
|
static const byte Convert_Shift [256] =
|
|
{
|
|
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, 9, // 0
|
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13, 0, 'A', 'S', // 1
|
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', // 2
|
|
'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, // 3
|
|
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1', // 4
|
|
'2', '3', '0', '.', 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '=', 0, 0, // 8
|
|
0, '@', ':', '_', 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, // 9
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
|
|
0, 0, 0, ',', 0, '/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
|
|
};
|
|
|
|
static _go32_dpmi_seginfo oldkeyboardisr, newkeyboardisr;
|
|
static BOOL keyboardinited;
|
|
|
|
/*
|
|
================
|
|
=
|
|
= I_KeyboardISR
|
|
=
|
|
================
|
|
*/
|
|
|
|
void I_KeyboardISR (void)
|
|
{
|
|
asm volatile ("cli; pusha");
|
|
// Get the scan code
|
|
|
|
keyboardque[kbdhead&(KBDQUESIZE-1)] = _inbyte(0x60);
|
|
kbdhead++;
|
|
|
|
// acknowledge the interrupt
|
|
|
|
_outbyte(0x20,0x20);
|
|
asm volatile ("popa; sti");
|
|
}
|
|
|
|
END_OF_FUNCTION(I_KeyboardISR)
|
|
|
|
|
|
static void I_StartupKeyboard (void)
|
|
{
|
|
#ifndef NOKBD
|
|
LOCK_FUNCTION (I_KeyboardISR);
|
|
LOCK_VARIABLE (keyboardque);
|
|
LOCK_VARIABLE (kbdhead);
|
|
|
|
asm volatile ("cli");
|
|
newkeyboardisr.pm_offset = (int)I_KeyboardISR;
|
|
newkeyboardisr.pm_selector = _go32_my_cs();
|
|
_go32_dpmi_get_protected_mode_interrupt_vector (KEYBOARDINT, &oldkeyboardisr);
|
|
_go32_dpmi_allocate_iret_wrapper (&newkeyboardisr);
|
|
_go32_dpmi_set_protected_mode_interrupt_vector (KEYBOARDINT, &newkeyboardisr);
|
|
keyboardinited = true;
|
|
asm volatile ("sti");
|
|
#endif
|
|
|
|
//I_ReadKeys ();
|
|
}
|
|
|
|
void I_ShutdownKeyboard (void)
|
|
{
|
|
short temp;
|
|
|
|
if (keyboardinited) {
|
|
_go32_dpmi_set_protected_mode_interrupt_vector (KEYBOARDINT, &oldkeyboardisr);
|
|
_go32_dpmi_free_iret_wrapper (&newkeyboardisr);
|
|
}
|
|
// clear bios key buffer
|
|
_dosmemgetw (0x41a, 1, &temp);
|
|
_dosmemputw (&temp, 1, 0x41c);
|
|
}
|
|
|
|
static void I_ReadKeyboard (void)
|
|
{
|
|
static BOOL special = false;
|
|
static int lastk;
|
|
int k;
|
|
event_t ev;
|
|
|
|
while (kbdtail < kbdhead)
|
|
{
|
|
k = keyboardque[kbdtail&(KBDQUESIZE-1)];
|
|
kbdtail++;
|
|
|
|
// extended keyboard shift key bullshit
|
|
if ( (k&0x7f)==DIK_LSHIFT || (k&0x7f)==DIK_RSHIFT )
|
|
{
|
|
if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
|
|
continue;
|
|
k &= 0x80;
|
|
k |= DIK_LSHIFT;
|
|
}
|
|
|
|
if (k==0xe0)
|
|
{
|
|
special = true;
|
|
continue; // special / pause keys
|
|
}
|
|
if (keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0xe1)
|
|
continue; // pause key bullshit
|
|
|
|
if (k==0xc5 && keyboardque[(kbdtail-2)&(KBDQUESIZE-1)] == 0x9d)
|
|
{
|
|
ev.type = ev_keydown;
|
|
ev.data1 = KEY_PAUSE;
|
|
D_PostEvent (&ev);
|
|
continue;
|
|
}
|
|
|
|
if (k&0x80)
|
|
ev.type = ev_keyup;
|
|
else
|
|
ev.type = ev_keydown;
|
|
|
|
k &= 0x7f;
|
|
if (special)
|
|
{
|
|
special = false;
|
|
switch (k)
|
|
{
|
|
case 0x47:
|
|
case 0x48:
|
|
case 0x49:
|
|
case 0x4b:
|
|
case 0x4d:
|
|
case 0x4f:
|
|
case 0x50:
|
|
case 0x51:
|
|
case 0x52:
|
|
case 0x53:
|
|
k |= 0x80;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((k | (ev.type<<8)) == lastk)
|
|
continue; // ignore repeating keys
|
|
|
|
lastk = k | (ev.type<<8);
|
|
ev.data2 = 0;
|
|
switch (k)
|
|
{
|
|
case DIK_LSHIFT:
|
|
shiftdown = ev.type == ev_keydown;
|
|
break;
|
|
default:
|
|
if (!menuactive &&
|
|
(ConsoleState == c_falling || ConsoleState == c_down)) {
|
|
switch (k) {
|
|
case DIK_NUMPAD4:
|
|
k = DIK_4;
|
|
break;
|
|
case DIK_NUMPAD6:
|
|
k = DIK_6;
|
|
break;
|
|
case DIK_NUMPAD8:
|
|
k = DIK_8;
|
|
break;
|
|
case DIK_NUMPAD2:
|
|
k = DIK_2;
|
|
break;
|
|
case DIK_NUMPAD7:
|
|
k = DIK_7;
|
|
break;
|
|
case DIK_NUMPAD9:
|
|
k = DIK_9;
|
|
break;
|
|
case DIK_NUMPAD3:
|
|
k = DIK_3;
|
|
break;
|
|
case DIK_NUMPAD1:
|
|
k = DIK_1;
|
|
break;
|
|
case DIK_NUMPAD0:
|
|
k = DIK_0;
|
|
break;
|
|
case DIK_NUMPAD5:
|
|
k = DIK_5;
|
|
break;
|
|
}
|
|
} else if (i_remapkeypad->value) {
|
|
switch (k) {
|
|
case DIK_NUMPAD4:
|
|
k = DIK_LEFT;
|
|
break;
|
|
case DIK_NUMPAD6:
|
|
k = DIK_RIGHT;
|
|
break;
|
|
case DIK_NUMPAD8:
|
|
k = DIK_UP;
|
|
break;
|
|
case DIK_NUMPAD2:
|
|
k = DIK_DOWN;
|
|
break;
|
|
case DIK_NUMPAD7:
|
|
k = DIK_HOME;
|
|
break;
|
|
case DIK_NUMPAD9:
|
|
k = DIK_PRIOR;
|
|
break;
|
|
case DIK_NUMPAD3:
|
|
k = DIK_NEXT;
|
|
break;
|
|
case DIK_NUMPAD1:
|
|
k = DIK_END;
|
|
break;
|
|
case DIK_NUMPAD0:
|
|
k = DIK_INSERT;
|
|
break;
|
|
case DIK_DECIMAL:
|
|
k = DIK_DELETE;
|
|
break;
|
|
}
|
|
}
|
|
ev.data2 = Convert[k];
|
|
break;
|
|
}
|
|
ev.data1 = k;
|
|
if (ConsoleState == c_falling || ConsoleState == c_down) {
|
|
switch (k) {
|
|
case DIK_DIVIDE:
|
|
ev.data2 = '/';
|
|
break;
|
|
case DIK_MULTIPLY:
|
|
ev.data2 = '*';
|
|
break;
|
|
case DIK_ADD:
|
|
ev.data2 = '+';
|
|
break;
|
|
case DIK_SUBTRACT:
|
|
ev.data2 = '-';
|
|
break;
|
|
case DIK_DECIMAL:
|
|
ev.data2 = '.';
|
|
break;
|
|
}
|
|
}
|
|
if (shiftdown)
|
|
ev.data3 = Convert_Shift[k];
|
|
else
|
|
ev.data3 = ev.data2;
|
|
D_PostEvent (&ev);
|
|
}
|
|
}
|
|
|
|
|
|
/****** Mouse Functions ******/
|
|
|
|
static BOOL mouse_present;
|
|
static int num_buttons;
|
|
|
|
static void I_StartupMouse (void)
|
|
{
|
|
__dpmi_regs r;
|
|
|
|
r.x.ax = 0;
|
|
__dpmi_int (0x33, &r); // Initialize mouse driver
|
|
|
|
if (r.x.ax == 0) {
|
|
mouse_present = false;
|
|
return;
|
|
}
|
|
|
|
mouse_present = true;
|
|
num_buttons = r.x.bx;
|
|
if (num_buttons == 0xffff)
|
|
num_buttons = 2;
|
|
else if (num_buttons > 4)
|
|
num_buttons = 4;
|
|
}
|
|
|
|
static void I_ShutdownMouse (void)
|
|
{
|
|
// We don't need to do anything here.
|
|
}
|
|
|
|
static void ReadMouse (void)
|
|
{
|
|
static int last_buttons;
|
|
int mouse_buttons;
|
|
|
|
event_t ev;
|
|
__dpmi_regs r;
|
|
|
|
if (!mouse_present || !usemouse->value)
|
|
return;
|
|
|
|
r.x.ax = 11;
|
|
__dpmi_int (0x33, &r);
|
|
|
|
ev.data2 = ((signed short)r.x.cx) * 2;
|
|
ev.data3 = -(signed short)r.x.dx;
|
|
|
|
if (ev.data2 || ev.data3) {
|
|
ev.type = ev_mouse;
|
|
ev.data1 = 0;
|
|
D_PostEvent (&ev);
|
|
}
|
|
|
|
r.x.ax = 3;
|
|
__dpmi_int (0x33, &r);
|
|
|
|
mouse_buttons = r.x.bx;
|
|
|
|
if (mouse_buttons != last_buttons) {
|
|
int rollnow = mouse_buttons;
|
|
int rollthen = last_buttons;
|
|
int i;
|
|
|
|
last_buttons = mouse_buttons;
|
|
|
|
ev.data2 = ev.data3 = 0;
|
|
|
|
for (i = 0; i < num_buttons; i++, rollnow >>= 1, rollthen >>= 1) {
|
|
if ((rollnow & 1) != (rollthen & 1)) {
|
|
ev.type = (rollnow & 1) ? ev_keydown : ev_keyup;
|
|
ev.data1 = i + KEY_MOUSE1;
|
|
D_PostEvent (&ev);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/****** Joystick Functions ******/
|
|
|
|
//==================================================
|
|
//
|
|
// joystick vars
|
|
//
|
|
//==================================================
|
|
|
|
BOOL joystickpresent;
|
|
extern unsigned int joystickx, joysticky;
|
|
BOOL I_ReadJoystick (void); // returns false if not connected
|
|
|
|
int joyxl, joyxh, joyyl, joyyh;
|
|
|
|
#if 0
|
|
BOOL WaitJoyButton (void)
|
|
{
|
|
int oldbuttons, buttons;
|
|
|
|
oldbuttons = 0;
|
|
do
|
|
{
|
|
I_WaitVBL (1);
|
|
buttons = ((inp(0x201) >> 4)&1)^1;
|
|
if (buttons != oldbuttons)
|
|
{
|
|
oldbuttons = buttons;
|
|
continue;
|
|
}
|
|
|
|
if ((lastpress& 0x7f) == 1)
|
|
{
|
|
joystickpresent = false;
|
|
return false;
|
|
}
|
|
} while (!buttons);
|
|
|
|
do
|
|
{
|
|
I_WaitVBL (1);
|
|
buttons = ((inp(0x201) >> 4)&1)^1;
|
|
if (buttons != oldbuttons)
|
|
{
|
|
oldbuttons = buttons;
|
|
continue;
|
|
}
|
|
|
|
if ((lastpress & 0x7f) == 1)
|
|
{
|
|
joystickpresent = false;
|
|
return false;
|
|
}
|
|
} while ( buttons);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
===============
|
|
=
|
|
= I_StartupJoystick
|
|
=
|
|
===============
|
|
*/
|
|
|
|
int basejoyx, basejoyy;
|
|
|
|
static void I_StartupJoystick (void)
|
|
{
|
|
int centerx, centery;
|
|
|
|
joystickpresent = 0;
|
|
if (M_CheckParm ("-nojoy") || !usejoystick->value)
|
|
return;
|
|
|
|
if (!I_ReadJoystick ())
|
|
{
|
|
joystickpresent = false;
|
|
DPrintf ("joystick not found ",0);
|
|
return;
|
|
}
|
|
Printf (PRINT_HIGH, "joystick found\n");
|
|
joystickpresent = true;
|
|
|
|
Printf (PRINT_HIGH, "CENTER the joystick and press button 1:");
|
|
if (!WaitJoyButton ())
|
|
return;
|
|
I_ReadJoystick ();
|
|
centerx = joystickx;
|
|
centery = joysticky;
|
|
|
|
Printf (PRINT_HIGH, "\nPush the joystick to the UPPER LEFT corner and press button 1:");
|
|
if (!WaitJoyButton ())
|
|
return;
|
|
I_ReadJoystick ();
|
|
joyxl = (centerx + joystickx)/2;
|
|
joyyl = (centerx + joysticky)/2;
|
|
|
|
Printf (PRINT_HIGH, "\nPush the joystick to the LOWER RIGHT corner and press button 1:");
|
|
if (!WaitJoyButton ())
|
|
return;
|
|
I_ReadJoystick ();
|
|
joyxh = (centerx + joystickx)/2;
|
|
joyyh = (centery + joysticky)/2;
|
|
Printf (PRINT_HIGH, "\n");
|
|
}
|
|
|
|
/*
|
|
===============
|
|
=
|
|
= I_JoystickEvents
|
|
=
|
|
===============
|
|
*/
|
|
|
|
static void I_JoystickEvents (void)
|
|
{
|
|
event_t ev;
|
|
|
|
//
|
|
// joystick events
|
|
//
|
|
if (!joystickpresent)
|
|
return;
|
|
|
|
I_ReadJoystick ();
|
|
ev.type = ev_joystick;
|
|
ev.data1 = ((inp(0x201) >> 4)&15)^15;
|
|
|
|
if (joystickx < joyxl)
|
|
ev.data2 = -1;
|
|
else if (joystickx > joyxh)
|
|
ev.data2 = 1;
|
|
else
|
|
ev.data2 = 0;
|
|
if (joysticky < joyyl)
|
|
ev.data3 = -1;
|
|
else if (joysticky > joyyh)
|
|
ev.data3 = 1;
|
|
else
|
|
ev.data3 = 0;
|
|
|
|
D_PostEvent (&ev);
|
|
}
|
|
#endif //0
|
|
|
|
/****** Input Event Generation ******/
|
|
|
|
void I_StartTic (void)
|
|
{
|
|
ReadMouse ();
|
|
I_ReadKeyboard ();
|
|
}
|
|
|
|
void I_StartFrame (void)
|
|
{
|
|
#if 0
|
|
I_JoystickEvents ();
|
|
#endif
|
|
} |