From e8f26025860a6551718f0d337bb337c895a64e53 Mon Sep 17 00:00:00 2001 From: Newsdee Date: Sun, 19 Jun 2016 12:44:20 +0800 Subject: [PATCH] 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) --- menu.c | 79 +++++++++++----------- osd.c | 199 +++++++++++++++++++++++++++++++----------------------- osd.h | 61 +++++++++-------- usb/hid.c | 18 ++--- user_io.c | 40 ++++++----- 5 files changed, 210 insertions(+), 187 deletions(-) diff --git a/menu.c b/menu.c index 0fe63ee..d1fdf0e 100644 --- a/menu.c +++ b/menu.c @@ -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 diff --git a/osd.c b/osd.c index bbd21c4..02c8411 100644 --- a/osd.c +++ b/osd.c @@ -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; -} \ No newline at end of file +} diff --git a/osd.h b/osd.h index b1fbcf8..cb7c972 100644 --- a/osd.h +++ b/osd.h @@ -97,6 +97,22 @@ #include +//// 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); diff --git a/usb/hid.c b/usb/hid.c index a865aca..06a938d 100644 --- a/usb/hid.c +++ b/usb/hid.c @@ -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 diff --git a/user_io.c b/user_io.c index d66a456..4669e50 100644 --- a/user_io.c +++ b/user_io.c @@ -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)) {