blob: 19291359d852c12f09997f64507227692882c8fc [file] [log] [blame] [raw]
/*
YAPE - Yet Another Plus/4 Emulator
The program emulates the Commodore 264 family of 8 bit microcomputers
This program is free software, you are welcome to distribute it,
and/or modify it under certain conditions. For more information,
read 'Copying'.
(c) 2000, 2001, 2004, 2015 Attila Grósz
*/
#include <memory.h>
#include <stdio.h>
#include "keyboard.h"
enum {
P4K_INS = 0, P4K_RETURN, P4K_POUND, P4K_HELP, P4K_F1, P4K_F2, P4K_F3, P4K_AT,
P4K_3, P4K_W, P4K_A, P4K_4, P4K_Z, P4K_S, P4K_E, P4K_SHIFT,
P4K_5, P4K_R, P4K_D, P4K_6, P4K_C, P4K_F, P4K_T, P4K_X,
P4K_7, P4K_Y, P4K_G, P4K_8, P4K_B, P4K_H, P4K_U, P4K_V,
P4K_9, P4K_I, P4K_J, P4K_0, P4K_M, P4K_K, P4K_O, P4K_N,
P4K_DOWN, P4K_P, P4K_L, P4K_UP, P4K_PERIOD, P4K_DPOINT, P4K_MINUS, P4K_COMMA,
P4K_LEFT, P4K_MULTIPLY, P4K_SEMICOLON, P4K_RIGHT, P4K_ESC, P4K_EQUAL, P4K_PLUS, P4K_SLASH,
P4K_1, P4K_HOME, P4K_CTRL, P4K_2, P4K_SPACE, P4K_COMMIE, P4K_Q, P4K_STOP
};
static const unsigned int joystick[5]={
SDL_SCANCODE_KP_8, SDL_SCANCODE_KP_6, SDL_SCANCODE_KP_2,
SDL_SCANCODE_KP_4, SDL_SCANCODE_KP_0 }; // PC keycodes up, right, down, left and fire
static const unsigned int joykeys[2][5]=
{ {P4K_5, P4K_6, P4K_R, P4K_D, P4K_T }, // keys for joystick 1 and 2 up, right, down, left and fire
{P4K_3, P4K_4, P4K_W, P4K_A, P4K_SHIFT } };
static const unsigned int origkeys[5]={
P4K_UP, P4K_RIGHT, P4K_DOWN, P4K_LEFT, 255};
//--------------------------------------------------------------
unsigned int KEYS::nrOfJoys;
SDL_Joystick *KEYS::sdlJoys[2];
KEYS::KEYS()
{
int i;
memset(joytrans,0xFF,sizeof(joytrans));
activejoy=0;
for (i=0;i<5;++i)
joytrans[joystick[i]]=joykeys[activejoy][i];
empty();
block(false);
}
void KEYS::initPcJoys()
{
nrOfJoys = SDL_NumJoysticks();
SDL_JoystickEventState(SDL_ENABLE);
sdlJoys[0] = sdlJoys[1] = 0;
unsigned int i = nrOfJoys + 1;
if (i > 2) i = 2;
while (i) {
i -= 1;
sdlJoys[i] = SDL_JoystickOpen(i);
}
fprintf(stderr, "Found %i joysticks.\n", nrOfJoys);
for( i=0; i < nrOfJoys; i++ ) {
printf(" %s\n", SDL_JoystickNameForIndex(i));
}
}
void KEYS::empty(void)
{
memset(joybuffer,0,256);
latched = 0xff;
}
void KEYS::latch(unsigned int keyrow, unsigned int joyrow)
{
latched = feedkey(keyrow) & feedjoy(joyrow);
//fprintf(stderr, "Key latch (%02X): %02X\n", keyrow, latched);
}
unsigned char KEYS::keyReadMatrixRow(unsigned int r)
{
const Uint8 *kbstate = SDL_GetKeyboardState(NULL);
unsigned char tmp;
//for(int i = 0; i < 256; i++)
// if (kbstate[i]) fprintf(stderr, "Key pressed (%02X)\n", i);
if (kbstate[SDL_SCANCODE_LALT])
return 0xFF;
switch (r) {
default:
case 0:
tmp = ~
((kbstate[SDL_SCANCODE_BACKSPACE]<<0)
|(kbstate[SDL_SCANCODE_RETURN]<<1)
|(kbstate[SDL_SCANCODE_KP_ENTER]<<1)
|(kbstate[SDL_SCANCODE_END]<<2)
|(kbstate[SDL_SCANCODE_F4]<<3)
|(kbstate[SDL_SCANCODE_F1]<<4)
|(kbstate[SDL_SCANCODE_F2]<<5)
|(kbstate[SDL_SCANCODE_F3]<<6)
|(kbstate[SDL_SCANCODE_MINUS]<<7));
break;
case 1:
tmp = ~
((kbstate[SDL_SCANCODE_3]<<0)
|(kbstate[SDL_SCANCODE_W]<<1)
|(kbstate[SDL_SCANCODE_A]<<2)
|(kbstate[SDL_SCANCODE_4]<<3)
|(kbstate[SDL_SCANCODE_Z]<<4)
|(kbstate[SDL_SCANCODE_S]<<5)
|(kbstate[SDL_SCANCODE_E]<<6)
|(kbstate[SDL_SCANCODE_RSHIFT]<<7)
|(kbstate[SDL_SCANCODE_LSHIFT]<<7));
break;
case 2:
tmp = ~
((kbstate[SDL_SCANCODE_5]<<0)
|(kbstate[SDL_SCANCODE_R]<<1)
|(kbstate[SDL_SCANCODE_D]<<2)
|(kbstate[SDL_SCANCODE_6]<<3)
|(kbstate[SDL_SCANCODE_C]<<4)
|(kbstate[SDL_SCANCODE_F]<<5)
|(kbstate[SDL_SCANCODE_T]<<6)
|(kbstate[SDL_SCANCODE_X]<<7));
break;
case 3:
tmp = ~
((kbstate[SDL_SCANCODE_7]<<0)
|(kbstate[SDL_SCANCODE_Y]<<1)
|(kbstate[SDL_SCANCODE_G]<<2)
|(kbstate[SDL_SCANCODE_8]<<3)
|(kbstate[SDL_SCANCODE_B]<<4)
|(kbstate[SDL_SCANCODE_H]<<5)
|(kbstate[SDL_SCANCODE_U]<<6)
|(kbstate[SDL_SCANCODE_V]<<7));
break;
case 4:
tmp = ~
((kbstate[SDL_SCANCODE_9]<<0)
|(kbstate[SDL_SCANCODE_I]<<1)
|(kbstate[SDL_SCANCODE_J]<<2)
|(kbstate[SDL_SCANCODE_0]<<3)
|(kbstate[SDL_SCANCODE_M]<<4)
|(kbstate[SDL_SCANCODE_K]<<5)
|(kbstate[SDL_SCANCODE_O]<<6)
|(kbstate[SDL_SCANCODE_N]<<7));
break;
case 5:
tmp = ~
//((kbstate[joyset_dinp[2 - (joy_setup_code[0] == 2)][2]]<<0)
((kbstate[SDL_SCANCODE_P]<<1)
|(kbstate[SDL_SCANCODE_L]<<2)
//|(kbstate[joyset_dinp[2 - (joy_setup_code[0] == 2)][0]]<<3)
|(kbstate[SDL_SCANCODE_PERIOD]<<4)
|(kbstate[SDL_SCANCODE_KP_PERIOD]<<4) /* numeric . */
|(kbstate[SDL_SCANCODE_SEMICOLON]<<5)
|(kbstate[SDL_SCANCODE_RIGHTBRACKET]<<6)
|(kbstate[SDL_SCANCODE_KP_MINUS]<<6) /* numeric - */
|(kbstate[SDL_SCANCODE_COMMA]<<7));
//if (!activejoy)
tmp &= ~((kbstate[SDL_SCANCODE_DOWN]<<0)|(kbstate[SDL_SCANCODE_UP]<<3));
//else
// tmp &= ~((kbstate[SDL_SCANCODE_KP_2]<<0)|(kbstate[SDL_SCANCODE_KP_8]<<3));
break;
case 6:
tmp = ~
((kbstate[SDL_SCANCODE_BACKSLASH]<<1)
|(kbstate[SDL_SCANCODE_KP_MULTIPLY]<<1)
|(kbstate[SDL_SCANCODE_APOSTROPHE]<<2)
|(kbstate[SDL_SCANCODE_GRAVE]<<4)
|(kbstate[SDL_SCANCODE_EQUALS]<<5)
|(kbstate[SDL_SCANCODE_LEFTBRACKET]<<6)
|(kbstate[SDL_SCANCODE_KP_PLUS]<<6) /* numeric + */
|(kbstate[SDL_SCANCODE_SLASH]<<7)
|(kbstate[SDL_SCANCODE_KP_DIVIDE]<<7)); /* numeric / */
//if (!activejoy)
tmp &= ~((kbstate[SDL_SCANCODE_LEFT]<<0)|(kbstate[SDL_SCANCODE_RIGHT]<<3));
//else
// tmp &= ~((kbstate[SDL_SCANCODE_KP_4]<<0)|(kbstate[SDL_SCANCODE_KP_6]<<3));
break;
case 7:
tmp = ~
((kbstate[SDL_SCANCODE_1]<<0)
|(kbstate[SDL_SCANCODE_HOME]<<1)
|(kbstate[SDL_SCANCODE_RCTRL]<<2)
|(kbstate[SDL_SCANCODE_PRIOR]<<2)
|(kbstate[SDL_SCANCODE_2]<<3)
|(kbstate[SDL_SCANCODE_SPACE]<<4)
|(kbstate[SDL_SCANCODE_LCTRL]<<5)
|(kbstate[SDL_SCANCODE_Q]<<6)
|(kbstate[SDL_SCANCODE_TAB]<<7));
break;
}
return tmp;
}
unsigned char KEYS::feedkey(unsigned char latch)
{
static unsigned char tmp;
tmp = 0xFF;
if ((latch&0x01)==0) tmp&=keyReadMatrixRow(0);
if ((latch&0x02)==0) tmp&=keyReadMatrixRow(1);
if ((latch&0x04)==0) tmp&=keyReadMatrixRow(2);
if ((latch&0x08)==0) tmp&=keyReadMatrixRow(3);
if ((latch&0x10)==0) tmp&=keyReadMatrixRow(4);
if ((latch&0x20)==0) tmp&=keyReadMatrixRow(5);
if ((latch&0x40)==0) tmp&=keyReadMatrixRow(6);
if ((latch&0x80)==0) tmp&=keyReadMatrixRow(7);
return tmp;
}
unsigned char KEYS::joy_trans(unsigned char r)
{
const Uint8 *kbstate = SDL_GetKeyboardState(NULL);
unsigned char tmp;
tmp = ~
((kbstate[joystick[0]]<<0)
|(kbstate[joystick[2]]<<1)
|(kbstate[joystick[3]]<<2)
|(kbstate[joystick[1]]<<3)
|(kbstate[joystick[4]]<<(6 + activejoy)));
return tmp;
}
unsigned char KEYS::getPcJoyState(unsigned int joyNr, unsigned int activeJoy)
{
const Sint16 deadZone = 32767 / 5;
unsigned char state;
Sint16 x_move, y_move;
state = SDL_JoystickGetButton(sdlJoys[joyNr], 0);
state |= SDL_JoystickGetButton(sdlJoys[joyNr], 10);
state <<= (6 + activeJoy);
// if (state)
// fprintf(stderr,"Joy(%i) state: %X ", joyNr, state);
x_move = SDL_JoystickGetAxis(sdlJoys[joyNr], 0);
y_move = SDL_JoystickGetAxis(sdlJoys[joyNr], 1);
if (x_move >= deadZone) {
state |= 8;
} else if (x_move <= -deadZone) {
state |= 4;
}
if (y_move >= deadZone) {
state |= 2;
} else if (y_move <= -deadZone) {
state |= 1;
}
return state ^ 0xFF;
}
unsigned char KEYS::feedjoy(unsigned char latch)
{
unsigned char tmp = 0xFF;
if ((latch&0x02)==0) {
if (activejoy)
tmp &= joy_trans(1);
if (sdlJoys[1^activejoy])
tmp&=getPcJoyState(1^activejoy, activejoy);
}
if ((latch&0x04)==0) {
if (!activejoy)
tmp &= joy_trans(2); // Joy2 is wired two times...
if (sdlJoys[0^activejoy])
tmp&=getPcJoyState(0^activejoy, activejoy);
}
return tmp;
}
void KEYS::joyinit(void)
{
register int i;
for (i=0;i<5;++i) {
joytrans[joystick[i]]=joykeys[activejoy][i];
// sdltrans[joystick[i]]=0xFF;
}
}
void KEYS::swapjoy()
{
// register int i;
activejoy=1-activejoy;
//for (i=0;i<5;++i)
// joytrans[joystick[i]]=joykeys[activejoy][i];
}
void KEYS::releasejoy()
{
//register int i;
//for (i=0;i<5;++i)
// sdltrans[joystick[i]]=origkeys[i];
}
KEYS::~KEYS()
{
int i = nrOfJoys;
while (i) {
i -= 1;
SDL_JoystickClose(sdlJoys[i]);
}
}