gzdoom/code/djgpp/I_input.c
1999-02-17 00:00:00 +00:00

507 lines
No EOL
10 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"
static void I_StartupKeyboard (void);
static void I_ShutdownKeyboard (void);
static void I_StartupJoystick (void);
static void I_JoystickEvents (void);
static void mouse_init (void);
static void mouse_uninit (void);
#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 SC_RSHIFT 0x36
#define SC_LSHIFT 0x2a
#define SC_UPARROW 0x48
#define SC_DOWNARROW 0x50
#define SC_LEFTARROW 0x4b
#define SC_RIGHTARROW 0x4d
#define KBDQUESIZE 32
static byte keyboardque[KBDQUESIZE];
static int kbdtail, kbdhead;
static BOOL shiftdown;
// Used by the console for making keys repeat
int KeyRepeatDelay;
int KeyRepeatRate;
extern constate_e ConsoleState;
cvar_t *i_remapkeypad;
cvar_t *usejoystick;
cvar_t *usemouse;
BOOL I_InitInput (void)
{
atexit (I_ShutdownInput);
Printf (PRINT_HIGH, "I_StartupMouse\n");
mouse_init ();
// 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)
{
mouse_uninit ();
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;
static int lastpress;
/*
================
=
= I_KeyboardISR
=
================
*/
void I_KeyboardISR (void)
{
asm volatile ("cli; pusha");
// Get the scan code
keyboardque[kbdhead&(KBDQUESIZE-1)] = lastpress = _inbyte(0x60);
kbdhead++;
// acknowledge the interrupt
_outbyte(0x20,0x20);
asm volatile ("popa; sti");
}
void __End_of_I_KeyboardISR (void) { }
static void I_StartupKeyboard (void)
{
#ifndef NOKBD
_go32_dpmi_lock_code (I_KeyboardISR, (long)__End_of_I_KeyboardISR - (long)I_KeyboardISR);
_go32_dpmi_lock_data ((void *)keyboardque, sizeof(keyboardque));
_go32_dpmi_lock_data ((void *)kbdhead, sizeof(kbdhead));
_go32_dpmi_lock_data ((void *)lastpress, sizeof(lastpress));
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++;
if (k == lastk)
continue; // ignore repeating keys
lastk = k;
// extended keyboard shift key bullshit
if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT )
{
if ( keyboardque[(kbdtail-2)&(KBDQUESIZE-1)]==0xe0 )
continue;
k &= 0x80;
k |= SC_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;
}
}
ev.data1 = k;
ev.data2 = 0;
switch (k)
{
case SC_LSHIFT:
shiftdown = ev.type == ev_keydown;
break;
default:
ev.data2 = Convert[k];
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 mouse_init (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 mouse_uninit (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
}