1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-02-14 03:24:07 +00:00

Refactored joystick code with new mist_joystick_t data strucutre.

Preparatory work to support turbo/autofire on joystick buttons.
(doesn't yet work with cores)
This commit is contained in:
Newsdee
2016-06-19 12:44:20 +08:00
parent d37127485a
commit e8f2602586
5 changed files with 210 additions and 187 deletions

79
menu.c
View File

@@ -249,14 +249,14 @@ void siprintbinary(char* buffer, size_t const size, void const * const ptr)
unsigned char *b = (unsigned char*) ptr;
unsigned char byte;
int i, j;
memset(buffer, '\0', size);
memset(buffer, '\0', sizeof(buffer));
for (i=size-1;i>=0;i--)
{
for (j=0;j<8;j++)
{
byte = (b[i] >> j) & 1;
buffer[j]=byte?'\x1a':'\x19';
}
for (j=0;j<8;j++)
{
byte = (b[i] >> j) & 1;
buffer[j]=byte?'\x1a':'\x19';
}
}
return;
}
@@ -266,13 +266,9 @@ void get_joystick_state( char *joy_string, char *joy_string2, unsigned int joy_n
uint16_t vjoy;
memset(joy_string, '\0', sizeof(joy_string));
memset(joy_string2, '\0', sizeof(joy_string2));
if (joy_num==0) {
vjoy = (uint16_t)OsdJoyGet();
vjoy |= OsdJoyGetExtra() << 8;
} else {
vjoy = (uint16_t)OsdJoyGet2();
vjoy |= OsdJoyGetExtra2() << 8;
}
mist_joystick_t joystick = OsdJoyGet(joy_num);
vjoy = OsdJoyState(joy_num);;
vjoy |= joystick.state_extra << 8;
if (vjoy==0) {
memset(joy_string2, ' ', 8);
memset(joy_string2+8, '\x14', 1);
@@ -309,19 +305,15 @@ void get_joystick_state_usb( char *s, unsigned char joy_num ) {
char binary_string[9]="00000000";
unsigned char joy = 0;
unsigned int max_btn = 1;
if (OsdNumJoysticks()==0 || (joy_num==1 && OsdNumJoysticks()<2))
{
strcpy( s, " ");
return;
}
if(joy_num==0) {
joy = OsdUsbJoyGet();
max_btn = OsdUsbGetNumButtons();
}
else {
joy = OsdUsbJoyGetB();
max_btn = OsdUsbGetNumButtonsB();
}
mist_joystick_t joystick = OsdJoyGet(joy_num);
joy = joystick.usb_state;
max_btn = joystick.num_buttons;
siprintf(s, " USB: ---- 0000 0000 0000");
siprintbinary(binary_string, sizeof(joy), &joy);
s[7] = binary_string[0]=='\x1a'?'>':'\x1b';
@@ -332,10 +324,7 @@ void get_joystick_state_usb( char *s, unsigned char joy_num ) {
s[13] = max_btn>1 ? binary_string[5] : ' ';
s[14] = max_btn>2 ? binary_string[6] : ' ';
s[15] = max_btn>3 ? binary_string[7] : ' ';
if(joy_num==0)
joy = OsdUsbJoyGetExtra();
else
joy = OsdUsbJoyGetExtraB();
joy = joystick.usb_state_extra;
siprintbinary(binary_string, sizeof(joy), &joy);
s[17] = max_btn>4 ? binary_string[0] : ' ';
s[18] = max_btn>5 ? binary_string[1] : ' ';
@@ -382,8 +371,6 @@ void get_joystick_id ( char *usb_id, unsigned char joy_num, short raw_id ) {
/*
Builds a string containing the USB VID/PID information of a joystick
*/
unsigned int usb_vid;
unsigned int usb_pid;
char buffer[32]="";
if (raw_id==0) {
if (OsdNumJoysticks()==0 || (joy_num==1 && OsdNumJoysticks()<2))
@@ -393,20 +380,14 @@ void get_joystick_id ( char *usb_id, unsigned char joy_num, short raw_id ) {
return;
}
}
if (joy_num==1) {
usb_vid = OsdUsbVidGetB();
usb_pid = OsdUsbPidGetB();
} else {
usb_vid = OsdUsbVidGet();
usb_pid = OsdUsbPidGet();
}
mist_joystick_t joystick = OsdJoyGet( joy_num );
memset(usb_id, '\0', sizeof(usb_id));
if (usb_vid>0) {
if (joystick.vid>0) {
if (raw_id == 0) {
strcpy(buffer, get_joystick_alias( usb_vid, usb_pid ));
strcpy(buffer, get_joystick_alias( joystick.vid, joystick.pid ));
}
if(strlen(buffer)==0) {
append_joystick_usbid( buffer, usb_vid, usb_pid );
append_joystick_usbid( buffer, joystick.vid, joystick.pid );
}
} else {
strcpy(buffer, "Atari DB9 Joystick");
@@ -437,6 +418,7 @@ void HandleUI(void)
{
char *p;
unsigned char i, c, m, up, down, select, menu, right, left, plus, minus;
uint8_t mod;
unsigned long len;
static hardfileTYPE t_hardfile[2]; // temporary copy of former hardfile configuration
static unsigned char ctrl = false;
@@ -453,6 +435,10 @@ void HandleUI(void)
char joy_string2[32];
char usb_id[64];
// update turbo status for joysticks
OsdTurboUpdate(0);
OsdTurboUpdate(1);
// get user control codes
c = OsdGetCtrl();
@@ -582,6 +568,7 @@ void HandleUI(void)
}
}
// Switch to current menu screen
switch (menustate)
{
@@ -1058,8 +1045,10 @@ void HandleUI(void)
case MENU_8BIT_CONTROLLERS2:
// menu key goes back to previous menu
if (menu)
if (menu) {
menusub = 1;
menustate = MENU_8BIT_SYSTEM1;
}
if(select) {
switch (menusub) {
case 0:
@@ -1106,6 +1095,12 @@ void HandleUI(void)
OsdKeyboardPressed(keys);
OsdWrite(0, " USB scancodes", 0,0);
siprintf(s, " %2x %2x %2x %2x", keys[0], keys[1], keys[2], keys[3]); // keys[4], keys[5]); - no need to show all, save some space...
OsdWrite(1, s, 0,0);
mod = OsdKeyboardModifiers();
siprintbinary(usb_id, sizeof(mod), &mod);
siprintf(s, " mod keys - 00000000");
for(i=0; i<8; i++)
s[15+i] = usb_id[i];
OsdWrite(2, s, 0,0);
OsdWrite(3, "", 0, 0);
OsdWrite(4, " PS/2 scancodes", 0, 0);
@@ -1121,9 +1116,11 @@ void HandleUI(void)
OsdWrite(0, " USB scancodes", 0,0);
siprintf(s, " %2x %2x %2x %2x", keys[0], keys[1], keys[2], keys[3]); // keys[4], keys[5]);
OsdWrite(1, s, 0,0);
m = OsdKeyboardModifiers();
siprintbinary(usb_id, sizeof(m), &m);
siprintf(s, " mod keys - %s", usb_id);
mod = OsdKeyboardModifiers();
siprintbinary(usb_id, sizeof(mod), &mod);
siprintf(s, " mod keys - 00000000");
for(i=0; i<8; i++)
s[15+i] = usb_id[i];
OsdWrite(2, s, 0,0);
OsdKeyboardPressedPS2(keys_ps2);
assign_ps2_modifier( m, keys_ps2, 0x1, 0x14); // LCTRL

199
osd.c
View File

@@ -728,109 +728,136 @@ static unsigned char joysticks;
unsigned char OsdNumJoysticks() {
return joysticks;
}
unsigned char OsdNumJoysticksSet(unsigned char num) {
/* latest joystick state */
static mist_joystick_t mist_joy[3] = { // 3rd one is dummy, used to store defaults
{
.vid = 0,
.pid = 0,
.num_buttons=1, // DB9 has 1 button
.state=0,
.state_extra=0,
.usb_state=0,
.usb_state_extra=0,
.turbo=50,
.turbo_counter=0,
.turbo_mask=0x30, // A and B buttons
.turbo_state=0xFF // flip state (0 or 1)
},
{
.vid = 0,
.pid = 0,
.num_buttons=1, // DB9 has 1 button
.state=0,
.state_extra=0,
.usb_state=0,
.usb_state_extra=0,
.turbo=0,
.turbo_counter=0,
.turbo_mask=0x30, // A and B buttons
.turbo_state=0xFF // flip state (0 or 1)
},
{
.vid = 0,
.pid = 0,
.num_buttons=1, // DB9 has 1 button
.state=0,
.state_extra=0,
.usb_state=0,
.usb_state_extra=0,
.turbo=0,
.turbo_counter=0,
.turbo_mask=0x30, // A and B buttons
.turbo_state=0xFF // flip state (0 or 1)
}
};
void OsdNumJoysticksSet(unsigned char num) {
mist_joystick_t joy;
joysticks = num;
if(joysticks<3) {
//clear USB joysticks
if(joysticks<2)
joy = mist_joy[0];
else
joy = mist_joy[1];
joy.vid=0;
joy.vid=0;
joy.num_buttons=1;
joy.state=0;
joy.state_extra=0;
joy.usb_state=0;
joy.usb_state_extra=0;
}
}
/* latest joystick state */
static unsigned char osd_joy;
static unsigned char osd_joy_extra;
void OsdJoySet(unsigned char c) {
//iprintf("OSD joy: %x\n", c);
osd_joy = c;
}
void OsdJoySetExtra(unsigned char c) {
osd_joy_extra = c;
}
unsigned char OsdJoyGet() {
return osd_joy;
}
unsigned char OsdJoyGetExtra() {
return osd_joy_extra;
}
/* latest joystick state */
static unsigned char osd_joy2;
static unsigned char osd_joy_extra2;
void OsdJoySet2(unsigned char c) {
//iprintf("OSD joy 2: %x\n", c);
osd_joy2 = c;
}
void OsdJoySetExtra2(unsigned char c) {
osd_joy_extra2 = c;
}
unsigned char OsdJoyGet2() {
return osd_joy2;
}
unsigned char OsdJoyGetExtra2() {
return osd_joy_extra2;
// state of MIST virtual joystick
mist_joystick_t OsdJoyGet(uint8_t joy_num) {
if(joy_num>1) return mist_joy[2];
return mist_joy[joy_num];
}
static uint8_t raw_usb_joy; // four directions and 4 buttons
static uint8_t raw_usb_joy_extra; // eight extra buttons
void OsdUsbJoySet(uint8_t usbjoy, uint8_t usbextra) {
raw_usb_joy = usbjoy;
raw_usb_joy_extra = usbextra;
void OsdJoySet(unsigned char c, uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].state = c;
if(c==0) OsdTurboReset(joy_num); //clear turbo if no button pressed
}
uint8_t OsdUsbJoyGet() {
return raw_usb_joy;
}
uint8_t OsdUsbJoyGetExtra() {
return raw_usb_joy_extra;
void OsdJoySetExtra(unsigned char c, uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].state_extra = c;
}
static uint8_t raw_usb_joy_b; // four directions and 4 buttons
static uint8_t raw_usb_joy_extra_b; // eight extra buttons
void OsdUsbJoySetB(uint8_t usbjoy, uint8_t usbextra) {
raw_usb_joy_b = usbjoy;
raw_usb_joy_extra_b = usbextra;
}
uint8_t OsdUsbJoyGetB() {
return raw_usb_joy_b;
}
uint8_t OsdUsbJoyGetExtraB() {
return raw_usb_joy_extra_b;
// raw state of USB controller
void OsdUsbJoySet(uint8_t usbjoy, uint8_t usbextra, uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].usb_state = usbjoy;
mist_joy[joy_num].usb_state_extra = usbextra;
}
/* connected HID information */
static unsigned int usb_vid;
static unsigned int usb_pid;
static unsigned int num_buttons;
void OsdUsbIdSet(unsigned int vid, unsigned int pid, unsigned int num) {
usb_vid=vid;
usb_pid=pid;
num_buttons = num;
}
unsigned int OsdUsbVidGet() {
return usb_vid;
}
unsigned int OsdUsbPidGet() {
return usb_pid;
}
unsigned int OsdUsbGetNumButtons() {
return num_buttons;
void OsdUsbIdSet(unsigned int vid, unsigned int pid, unsigned int btn_count, uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].vid = vid;
mist_joy[joy_num].pid = pid;
mist_joy[joy_num].num_buttons = btn_count;
}
/* connected HID information - joy 2*/
static unsigned int usb_vid_b;
static unsigned int usb_pid_b;
static unsigned int num_buttons_b;
void OsdUsbIdSetB(unsigned int vid, unsigned int pid, unsigned int num) {
usb_vid_b=vid;
usb_pid_b=pid;
num_buttons_b = num;
/* handle button's turbo timers */
void OsdTurboUpdate(uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].turbo_counter += 1;
if(mist_joy[joy_num].turbo_counter > mist_joy[joy_num].turbo) {
mist_joy[joy_num].turbo_counter = 0;
mist_joy[joy_num].turbo_state ^= mist_joy[joy_num].turbo_mask;
}
}
unsigned int OsdUsbVidGetB() {
return usb_vid_b;
/* reset all turbo timers and state */
void OsdTurboReset(uint8_t joy_num) {
if(joy_num>1) return;
mist_joy[joy_num].turbo_counter = 0;
mist_joy[joy_num].turbo_state = 0xFF;
}
unsigned int OsdUsbPidGetB() {
return usb_pid_b;
/* set a specific turbo mask and timeout */
void OsdTurboSet ( uint16_t turbo, uint16_t mask, uint8_t joy_num ) {
if(joy_num>1) return;
OsdTurboReset(joy_num);
mist_joy[joy_num].turbo = turbo;
mist_joy[joy_num].turbo_mask = mask;
}
unsigned int OsdUsbGetNumButtonsB() {
return num_buttons_b;
/* return Joy state including turbo settings */
uint8_t OsdJoyState ( uint8_t joy_num ) {
if(joy_num>1) return 0;
uint8_t result = mist_joy[joy_num].state;
result &= mist_joy[joy_num].turbo_state;
return result;
}
/* keyboard data */
static unsigned char key_modifier = 0;
static uint8_t key_modifier = 0;
static unsigned char key_pressed[6] = { 0,0,0,0,0,0 };
static unsigned int key_ps2[6] = { 0,0,0,0,0,0 };
void OsdKeyboardSet( unsigned char modifier, char* keycodes, int* keycodes_ps2) {
@@ -857,7 +884,7 @@ void OsdKeyboardSet( unsigned char modifier, char* keycodes, int* keycodes_ps2)
}
}
}
unsigned char OsdKeyboardModifiers() {
uint8_t OsdKeyboardModifiers() {
return key_modifier;
}
void OsdKeyboardPressed(char *keycodes) {
@@ -879,4 +906,4 @@ void OsdCoreNameSet(const char* str) {
}
char* OsdCoreName() {
return lastcorename;
}
}

61
osd.h
View File

@@ -97,6 +97,22 @@
#include <inttypes.h>
//// type definitions ////
typedef struct {
uint16_t vid; // USB vendor ID
uint16_t pid; // USB product ID
uint8_t num_buttons; // number of physical buttons reported by HID parsing
uint8_t state; // virtual joystick: current state of 4 direction + 4 first buttons
uint8_t state_extra; // current state of 8 more buttons
uint8_t usb_state; // raw USB state of direction and buttons
uint8_t usb_state_extra; // raw USB state of 8 more buttons
uint16_t turbo; // 0 if disabled, otherwise max number to flip state
uint16_t turbo_counter; // increased when using turbo, flips state when passing turbo
uint8_t turbo_mask; // buttons subject to turbo
uint8_t turbo_state; // current mask to apply
} mist_joystick_t;
/*functions*/
void OsdSetTitle(char *s,int arrow); // arrow > 0 = display right arrow in bottom right, < 0 = display left arrow
void OsdWrite(unsigned char n, char *s, unsigned char inver, unsigned char stipple);
@@ -136,44 +152,29 @@ unsigned char OsdKeyGet();
* Various functions to retrieve hardware state from the OSD
*/
// State of first (virtual) internal joystisk i.e. after mapping
void OsdJoySet(unsigned char);
unsigned char OsdJoyGet();
void OsdJoySetExtra(unsigned char);
unsigned char OsdJoyGetExtra();
mist_joystick_t OsdJoyGet(uint8_t joy_num); // all data
uint8_t OsdJoyState ( uint8_t joy_num ); // directions and 4 buttons, reflecting turbo settings
// State of second (virtual) joystisk
void OsdJoySet2(unsigned char);
unsigned char OsdJoyGet2();
void OsdJoySetExtra2(unsigned char);
unsigned char OsdJoyGetExtra2();
// State of first (virtual) internal joystisk i.e. after mapping
void OsdJoySet(unsigned char, uint8_t joy_num);
void OsdJoySetExtra(unsigned char, uint8_t joy_num);
// USB raw data for joystick 1
void OsdUsbJoySet(uint8_t usbjoy, uint8_t usbextra, uint8_t joy_num);
void OsdUsbIdSet(unsigned int vid, unsigned int pid, unsigned int num_buttons, uint8_t joy_num);
// Keep track of connected sticks
unsigned char OsdNumJoysticks();
unsigned char OsdNumJoysticksSet(unsigned char num);
void OsdNumJoysticksSet(unsigned char num);
// USB raw data for joystick 1
void OsdUsbJoySet(uint8_t usbjoy, uint8_t usbextra);
uint8_t OsdUsbJoyGet();
uint8_t OsdUsbJoyGetExtra();
void OsdUsbIdSet(unsigned int vid, unsigned int pid, unsigned int num_buttons);
unsigned int OsdUsbVidGet();
unsigned int OsdUsbPidGet();
unsigned int OsdUsbGetNumButtons();
// USB raw data for joystick 2
void OsdUsbJoySetB(uint8_t usbjoy, uint8_t usbextra);
uint8_t OsdUsbJoyGetB();
uint8_t OsdUsbJoyGetExtraB();
void OsdUsbIdSetB(unsigned int vid, unsigned int pid, unsigned int num_buttons);
unsigned int OsdUsbVidGetB();
unsigned int OsdUsbPidGetB();
unsigned int OsdUsbGetNumButtonsB();
// turbo function
void OsdTurboUpdate(uint8_t joy_num);
void OsdTurboReset(uint8_t joy_num);
void OsdTurboSet ( uint16_t turbo, uint16_t mask, uint8_t joy_num );
// keyboard status
void OsdKeyboardSet( unsigned char modifier, char* pressed, int* pressed_ps2); //get usb and ps2 codes
unsigned char OsdKeyboardModifiers();
uint8_t OsdKeyboardModifiers();
void OsdKeyboardPressed(char *pressed);
void OsdKeyboardPressedPS2(unsigned int *keycodes);

View File

@@ -736,13 +736,9 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
jmap |= btn << JOY_BTN_SHIFT; // add buttons
// report joystick 1 to OSD
if ( iface->jindex==0) {
OsdUsbIdSet( conf->joystick_mouse.vid, conf->joystick_mouse.pid, conf->joystick_mouse.button_count );
OsdUsbJoySet( jmap, btn_extra );
} else if (iface->jindex==1) {
OsdUsbIdSetB( conf->joystick_mouse.vid, conf->joystick_mouse.pid, conf->joystick_mouse.button_count );
OsdUsbJoySetB( jmap, btn_extra );
}
OsdUsbIdSet( conf->joystick_mouse.vid, conf->joystick_mouse.pid, conf->joystick_mouse.button_count, iface->jindex );
OsdUsbJoySet( jmap, btn_extra, iface->jindex );
// map virtual joypad
uint16_t vjoy = jmap;
vjoy |= btn_extra << 8;
@@ -757,12 +753,8 @@ static void usb_process_iface (usb_hid_iface_info_t *iface,
//if (jmap != 0) iprintf("JMAP post map:%d\n", jmap);
// report joystick 1 to OSD
if ( iface->jindex==0) {
OsdJoySetExtra( btn_extra );
} else if (iface->jindex==1) {
OsdJoySetExtra2( btn_extra );
}
// report joystick extra buttons to OSD
OsdJoySetExtra( btn_extra, iface->jindex );
// swap joystick 0 and 1 since 1 is the one
// used primarily on most systems

View File

@@ -313,25 +313,34 @@ void user_io_analog_joystick(unsigned char joystick, char valueX, char valueY) {
}
void user_io_digital_joystick(unsigned char joystick, unsigned char map) {
// "only" 6 joysticks are supported
if(joystick >= 6)
return;
// the physical joysticks (db9 ports at the right device side)
// as well as the joystick emulation are renumbered if usb joysticks
// are present in the system. The USB joystick(s) replace joystick 1
// and 0 and the physical joysticks are "shifted up".
// Since the primary joystick is in port 1 the first usb joystick
// becomes joystick 1 and only the second one becomes joystick 0
// (mouse port)
if (joystick==1) {
OsdJoySet(map, 0);
//map = (unsigned char)OsdJoyState(0); //apply turbo
}
else if (joystick==0) {// WARNING: 0 is the second joystick, either USB or DB9
OsdJoySet(map, 1);
//map = (unsigned char)OsdJoyState(1); //apply turbo
}
// if osd is open control it via joystick
if(osd_is_visible) {
static const uint8_t joy2kbd[] = {
OSDCTRLMENU, OSDCTRLMENU, OSDCTRLMENU, OSDCTRLSELECT,
OSDCTRLUP, OSDCTRLDOWN, OSDCTRLLEFT, OSDCTRLRIGHT };
// the physical joysticks (db9 ports at the right device side)
// as well as the joystick emulation are renumbered if usb joysticks
// are present in the system. The USB joystick(s) replace joystick 1
// and 0 and the physical joysticks are "shifted up".
// Since the primary joystick is in port 1 the first usb joystick
// becomes joystick 1 and only the second one becomes joystick 0
// (mouse port)
if (joystick==1)
OsdJoySet(map);
else if (joystick==0) // WARNING: 0 is the second joystick, either USB or DB9
OsdJoySet2(map);
// iprintf("joy to osd\n");
// OsdKeySet(0x80 | usb2ami[pressed[i]]);
@@ -341,10 +350,7 @@ void user_io_digital_joystick(unsigned char joystick, unsigned char map) {
// iprintf("j%d: %x\n", joystick, map);
// "only" 6 joysticks are supported
if(joystick >= 6)
return;
// atari ST handles joystick 0 and 1 through the ikbd emulated by the io controller
// but only for joystick 1 and 2
if((core_type == CORE_TYPE_MIST) && (joystick < 2)) {