Gamoover

Vous êtes nostalgiques des jeux vidéos de votre enfance ? Vous désirez acquérir, ou construire une borne d'arcade ? Vous trouverez ici les réponses a vos questions et une communauté de joueurs passionnés.

PIC18F2550 et gamepad

Démarré par Iro, Mercredi 21 Janvier 2015, 16:12:11 PM

Iro

Hello,
J'ai trouvé sur le net , un schéma de pad USB à base de PIC18F2550 avec les sources (microchip)
Il fonctionne correctement à une chose prêt : Il est en autofire.
L'appui long d'un bouton répète l'action au lieu de ne le faire qu'une fois.

1ére chose qui m'étonne, c'est que ce ne soit pas gérer de base. A moins que le source que j'ai récupéré ai été modifié. Il est ici


Après quelques recherches sur le net et réflexions, il faudrait "bypasser" ou faire un "delay" pour ne pas prendre en compte le même appui précédent. Mais je suis totalement noob sur le sujet et finalement paumé  :-\

Savez vous comment faire pour résoudre ce problème ou connaissez vous un site qui explique le fonctionnement d'un pad USB ?

Merci <:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

sushy18

salut iro,
en regardant "USB HID Protocol" comme ici :

http://www.rennes.supelec.fr/ren/fi/elec/docs/usb/hid.html

tu aura les infos que tu veux ? ou tu recherche un truc spécifique aux pad 18f2550 et 18f4550 ?
Si tu ne sais pas demande, si tu sais partage !!
Faudrait pas perdre de vue qu'une borne d'arcade c'est pas une console, c'est rarement plug n play, plus souvent plug n pschitt... (Funkycochise 2008)
"Gratuit ? C'est déjà trop cher !!" ( Crying Freeman 2016)

Iro

Je jette un oeil et te dis <:)
Mais rapidos, c'est plutôt une info sur le fonctionnement d'un gamepad dont j'ai besoin.
Je pense sur la temporisation des validations de touches, dans la boucle principale (USB_POLL ?)
A mon avisu mon probléme n'est pas spécifique au PIC
<:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

sushy18

la rémanence des touches l'est pour toute les entrées ?
tu as le schéma ou le .hex ?
Si tu ne sais pas demande, si tu sais partage !!
Faudrait pas perdre de vue qu'une borne d'arcade c'est pas une console, c'est rarement plug n play, plus souvent plug n pschitt... (Funkycochise 2008)
"Gratuit ? C'est déjà trop cher !!" ( Crying Freeman 2016)

Iro

Il me semble .. Je vais vérifier.
Tout est disponible ici
http://cytron.com.my/p-pr26
<:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

f4brice

#5
Dans la partie "variable", tout en haut du source, ajouter :

BYTE waitRelease = 0xFF;

Juste avant la fonction "void Emulate_Joystick(void)", ajouter cette fonction :



static BYTE checkButtonPressed(BYTE buttons, BYTE maskButton, BYTE maskHid)
{
  if( buttons&maskButton )
  {
     /* button is not pressed */
     waitRelease |= maskButton;
  }
  else
  {
     /* button is pressed */
     if( waitRelease&maskButton )
     {
        waitRelease &= ~maskButton;
        return maskHid;
     }
  }

  return 0;
}




Et enfin replacer ça :



//button 1:up1 button 2:right1 button 3:down1 button 4:left1
//button //button 5:start button 6:select button 7:b_5 button 8:b_6
hid_report_in[5]=0x00; //initialized all button as 0

if (ConfBoutonNormal == TRUE)
     {if(!b_1)hid_report_in[5] |=0x01; //if b_1 is pressed, send report to button and set bit0 as 1
   else hid_report_in[5] &=0xFE; //if not, clear bit0 to 0
 if(!b_2)hid_report_in[5] |=0x02; //if b_1 is pressed, set bit1 as 1
  else hid_report_in[5] &=0xFD; //if not, clear bit1 to 0
 if(!b_3)hid_report_in[5] |=0x04; //if b_1 is pressed, set bit2 as 1
   else hid_report_in[5] &=0xFB; //if not, clear bit2 to 0
     if(!b_4)hid_report_in[5] |=0x08; //if b_1 is pressed, set bit3 as 1
else hid_report_in[5] &=0xF7;} //if not, clear bit3 to 0
   else
    {if(!b_1)hid_report_in[5] |=0x08; //if b_1 is pressed, send report to button and set bit0 as 1
   else hid_report_in[5] &=0xF7; //if not, clear bit0 to 0
 if(!b_2)hid_report_in[5] |=0x01; //if b_1 is pressed, set bit1 as 1
  else hid_report_in[5] &=0xFE; //if not, clear bit1 to 0
 if(!b_3)hid_report_in[5] |=0x02; //if b_1 is pressed, set bit2 as 1
   else hid_report_in[5] &=0xFD; //if not, clear bit2 to 0
     if(!b_4)hid_report_in[5] |=0x04; //if b_1 is pressed, set bit3 as 1
else hid_report_in[5] &=0xFB;} //if not, clear bit3 to 0


if(!b_8)hid_report_in[5] |=0x10; //if select is pressed, set bit4 as 1
else hid_report_in[5] &=0xEF; //if not, clear bit4 to 0
if(!b_7)hid_report_in[5] |=0x20; //if start is pressed, set bit5 as 1
else hid_report_in[5] &=0xDF; //if not, clear bit5 to 0
if(!b_6)hid_report_in[5] |=0x40; //if b_6 is pressed, set bit6 as 1
else hid_report_in[5] &=0xBF; //if not, clear bit6 to 0
if(!b_5)hid_report_in[5] |=0x80; //if b_5 is pressed, set bit7 as 1
else hid_report_in[5] &=0x7F;


par ça :



  hid_report_in[5] = 0x00;
  if( ConfBoutonNormal )
  {
      /* Ordre 1234 */
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x01, 0x01);  //b1
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x02, 0x02);  //b2
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x04, 0x04);  //b3
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x08, 0x08);  //b4
  }
  else
  {
      /* Ordre 4123 (NeoGeo) */
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x01, 0x08);  //b1 reported as b4
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x02, 0x01);  //b2 reported as b1
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x04, 0x02);  //b3 reported as b2
      hid_report_in[5] |= checkButtonPressed(PORTB, 0x08, 0x04);  //b4 reported as b3
  }

  hid_report_in[5] |= checkButtonPressed(PORTB, 0x10, 0x80);  //b5
  hid_report_in[5] |= checkButtonPressed(PORTB, 0x20, 0x40);  //b6
  hid_report_in[5] |= checkButtonPressed(PORTB, 0x40, 0x20);  //b7
  hid_report_in[5] |= checkButtonPressed(PORTB, 0x80, 0x10);  //b8


On peut faire plus propre, mais là je dois aller au taf...  ;)

Iro

#6
Merci  :-)= :-)=
Je test dés que possible !!

EDIT : L'ordre qui te parait chelou est pour inverser logiciellement les boutons :D
Pour passer de 1234 à 4123 pour une disposition Neogeo
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

f4brice

Citation de: Iro le Vendredi 30 Janvier 2015, 08:28:09 AM
EDIT : L'ordre qui te parait chelou est pour inverser logiciellement les boutons :D
Pour passer de 1234 à 4123 pour une disposition Neogeo

Dans ce cas, c'est bon !
Je pensais que la notion d'inversion faisait passer de 1234 à 4321...

Iro

J'ai reprogrammé le PIC avec la modif mais les touches ne sont plus détectées
Voici la modif
http://www.gamoover.net/redacteur/Iro/Krayt-Pad/main.c

Merci <:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

BigPanik

pour moi y a juste à mettre en commentaire la ligne
Citationhid_report_in[5]=0x00;   

BP

Iro

"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

sushy18

BIG PANIC , F4brice. ... il manque liodel et de ce post il va en ressortir un .hex aux petits oignons  =:))
Si tu ne sais pas demande, si tu sais partage !!
Faudrait pas perdre de vue qu'une borne d'arcade c'est pas une console, c'est rarement plug n play, plus souvent plug n pschitt... (Funkycochise 2008)
"Gratuit ? C'est déjà trop cher !!" ( Crying Freeman 2016)

Iro

Bon maintenant, c'est tous les boutons qui sont appuyés :D
C'est impératif de mettre à blanc à ce niveau non ? Sinon le programme garde en mémoire les précédentes touches .
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

f4brice

Pour moi, le "hid_report_in[5]=0x00;" est important car sinon le PIC va envoyer n'importe quoi au PC...

Je viens de simuler mon bout de code en python :


waitRelease = 0xFF
def checkButtonPressed(button, maskButton, maskHid):
  global waitRelease
  if button&maskButton:
    waitRelease |= maskButton
  else:
    if waitRelease&maskButton:
      waitRelease &= ~maskButton
      return  maskHid
  return 0


print "cas 1=%s" % checkButtonPressed(0xFF, 0x01, 123)
print "cas 2=%s" % checkButtonPressed(0xFE, 0x01, 123)
print "cas 3=%s" % checkButtonPressed(0xFE, 0x01, 123)
print "cas 4=%s" % checkButtonPressed(0xFE, 0x01, 123)
print "cas 5=%s" % checkButtonPressed(0xFF, 0x01, 123)



Et voici le résultat :



  • cas 1 : le bouton n'est pas appuyé => il n'est pas présent dans les données envoyées en USB
  • cas 2 : le bouton est vu appuyé pour la 1ère fois => il est présent dans les données USB
  • cas 3 : le bouton est toujours appuyé => il n'est plus présent dans les données USB
  • cas 4 : idem cas 3
  • cas 5 : le bouton est relaché => toujours pas présent dans les données USB

Mon bout de code fait ce qui est prévu : signaler l'appui du bouton uniquement la première fois qu'il est détecté.
Le bouton doit être relaché puis à nouveau appuyé pour être signalé en USB.

Iro

Ok, je vais essayer de voir ce qui se passe avec la simulation de proteus
<:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO   

Iro

Bon, à force de creuser , on trouve (je suis dans ma période minecraft :D)

C'était bien un anti-rebond qu'il fallait appliquer. Et à force de lire des sources et des explications, j'ai trouvé la fonction. Qui d'ailleurs revenaient régulièrement.

C'est un délai (en milliseconde) qu'il faut appliquer avant chaque lecture des inputs, dans la boucle principale

while(1)
    {
          ........
          ........
          ........
          DelayMs(50) ;
          LectureInput(); 
          ........
          ........
    }
   
J'ai essayè avec 50ms car c'était la valeur qui revenait. Cela a l'air de fonctionner plutôt bien en règle générale mais j'ai l'impression que c'est un peu poussif avec les appuis répétitif comme l'Electric Thunder de Blanka par exemple. Je vais réduire le délais et voir si il sort plus facilement.

Le header et le C sont dispo ici pour ceux que cela intéresse

<:)
"Jet set 2, c'est avec Robert Garcia ?" Kaneda, Lapsus de sac Vol.1
Peter Shou Owner' Club

WIPs : Naomi - SEGA Rally - AB Cop - Lethal Enforcers - COMPUMI - Terminator 2 - Space Invaders - Artworks pour Boitiers K7 Naomi CF - Ma collec' de panels

LES TUTOS DE GAMO