RetroPie forum home
    • Recent
    • Tags
    • Popular
    • Home
    • Docs
    • Register
    • Login
    Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

    Food Fight - joystick troubles, solved

    Scheduled Pinned Locked Moved Help and Support
    ad stick
    125 Posts 5 Posters 10.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      mahoneyt944 @grant2258
      last edited by

      @grant2258 tested, can't move left or right and diagonals are stoping off target most times. Sometimes diagonals stop in linear directions too.

      1 Reply Last reply Reply Quote 0
      • G
        grant2258 Banned
        last edited by grant2258

        works fine here make sure your using cheat ports the re-calibrate your your joystick in the service menu. When you mess about with this code you change the calibration during my testing i had to repeatedly delete the nvram to undo teh games calibration.

        Thats why care needs to be done when testing. The horizontal could be reading too fast for you i explained this before its button debounce delay the read time.

        the code is here

        wget https://raw.githubusercontent.com/grant2258/Blaster-Barcade/3d1f20d2bcc51552672119cdded187633cdfe1d7/src/drivers/foodf.c

        ps this code works fine in default nvram when you spin the joystick round once and works every time if you calibrate

        M 1 Reply Last reply Reply Quote 0
        • M
          mahoneyt944 @grant2258
          last edited by

          @grant2258

          Had a compiling error that's why it was messed up.
          Fixed now ... Testing now

          1 Reply Last reply Reply Quote 0
          • G
            grant2258 Banned
            last edited by grant2258

            this code here https://github.com/grant2258/Blaster-Barcade/blob/3d1f20d2bcc51552672119cdded187633cdfe1d7/src/drivers/foodf.c#L199

            change it too

                if( counter == 8) {  direction = readinputport(6); counter =0; }
                else counter ++;
            

            and add somewhere at the top where the other variables are this should take care of the debounce works fine on a keyboard (horizontal centering )

            static INT16  counter = 0;
            
            M 1 Reply Last reply Reply Quote 0
            • M
              mahoneyt944 @grant2258
              last edited by mahoneyt944

              @grant2258

              if the counter isn't 8 direction wont be set to be used with temp. is that an issue? Or should this be a while loop

              1 Reply Last reply Reply Quote 0
              • G
                grant2258 Banned
                last edited by

                it intentional it uses the last read. The problem is it reads so fast you get button debounce you need to slow the reads down unti you get horizontals without issues.

                M 1 Reply Last reply Reply Quote 0
                • M
                  mahoneyt944 @grant2258
                  last edited by mahoneyt944

                  @grant2258 right but on first time run your direction wasn't set yet to have a last read position.

                  G 1 Reply Last reply Reply Quote 0
                  • G
                    grant2258 Banned @mahoneyt944
                    last edited by grant2258

                    @mahoneyt944 are you having any issues ? you shouldnt be. The analog reads far too fast for button debounce you need 10 - 20 ms for the debounce. Even when you dont press a button it will read zero as center it will happen so fast you wont notice it and teh buttons will be read in less time than you could press it.

                    M 1 Reply Last reply Reply Quote 0
                    • M
                      mahoneyt944 @grant2258
                      last edited by mahoneyt944

                      @grant2258 if I change the code to use the counter even after calibration I get issues. He moves diagonals slowly and looks choppy. Then when exiting and re-entering the emulator he doesn't stop moving. If I don't use the counter it's fine just sometimes stops linear instead of diagonal.

                      1 Reply Last reply Reply Quote 0
                      • G
                        grant2258 Banned
                        last edited by grant2258

                        Well i would suggest you delete your foodf nvram and cfg files since the input ports where added and it was save before that. Ive only tested on a windows machine will compile on pi and test it in my barcade. And be sure to have your cheat ports on.

                        M 1 Reply Last reply Reply Quote 0
                        • M
                          mahoneyt944 @grant2258
                          last edited by

                          @grant2258

                          it works for me like this instead

                          static READ16_HANDLER( analog_r )
                          {
                          
                            #define max  255
                            #define cent 128
                            #define bump 51;
                          
                            #define up   1
                            #define down 2
                            #define left 4
                            #define right 8
                          
                            static INT16  xvalue = 0x80;
                            static INT16  yvalue = 0x80;
                            static INT16  currentx  = 0x80;
                            static INT16  currenty  = 0x80;
                            static INT16  center = 0;
                            static INT16  counter = 0;
                            int temp;
                            UINT16 direction;
                          
                            if( options.cheat_input_ports) // use cheat ports
                            {
                          
                              if(whichport == 0 || whichport ==2)   direction = readinputport(6);
                              
                              if (counter == 8)
                              {
                                temp = direction & ~16;
                                if ( temp == 0 ) center =1;
                          
                                else if ( temp == up         ) { center=0; xvalue = cent; yvalue = max;  currentx=cent;      currenty= cent+bump; }
                                else if ( temp == down       ) { center=0; xvalue = cent; yvalue = 0;    currentx=cent;      currenty= cent-bump; }
                                else if ( temp == left       ) { center=0; xvalue = max;  yvalue = cent; currentx=cent+bump; currenty= cent;      }
                                else if ( temp == right      ) { center=0; xvalue = 0;    yvalue = cent; currentx=cent-bump; currenty= cent;      }
                          
                                else if ( temp == right+up   ) { center=0; xvalue = 0;    yvalue = max;  currentx=cent-bump; currenty= cent+bump; }
                                else if ( temp == right+down ) { center=0; xvalue = 0;    yvalue = 0;    currentx=cent-bump; currenty= cent-bump; }
                                else if ( temp == left+up    ) { center=0; xvalue = max;  yvalue = max;  currentx=cent+bump; currenty= cent+bump; }
                                else if ( temp == left+down  ) { center=0; xvalue = max;  yvalue = 0;    currentx=cent+bump; currenty= cent-bump; }
                                else log_cb(RETRO_LOG_INFO, LOGPRE "unhandled condition %d\n",temp);
                                counter = 0;
                              }
                              else counter++;
                          
                              if (whichport == 0)
                              {
                                if (center)
                                  return currentx;
                                return xvalue;
                              }
                          
                              else if (whichport == 2)
                              {
                                if (center)
                                  return currenty;
                                return yvalue;
                              }
                            }
                          
                          
                          
                          
                            else // use original inputs
                              return readinputport(whichport);
                          }
                          
                          1 Reply Last reply Reply Quote 0
                          • G
                            grant2258 Banned
                            last edited by grant2258

                            ok just put the counter in if your horizontals arent sticking havent tested it on the pie yet just on a windows box will let you know how i get on. I have a few other things in tinkering with havent spent a great deal of time on this

                            M 1 Reply Last reply Reply Quote 0
                            • M
                              mahoneyt944 @grant2258
                              last edited by mahoneyt944

                              @grant2258 the counter is in, I just moved where it is so direction is always defined on each read but the position is not updated unless it's on the right count.

                              We could probably initialize direction normally this way too instead of undefined and remove the if statement

                              Like this

                              static READ16_HANDLER( analog_r )
                              {
                              
                                #define max  255
                                #define cent 128
                                #define bump 51;
                              
                                #define up   1
                                #define down 2
                                #define left 4
                                #define right 8
                              
                                static INT16  xvalue = 0x80;
                                static INT16  yvalue = 0x80;
                                static INT16  currentx  = 0x80;
                                static INT16  currenty  = 0x80;
                                static INT16  center = 0;
                                static INT16  counter = 0;
                                static INT16  direction = readinputport(6);
                                int temp;
                              
                                if( options.cheat_input_ports) // use cheat ports
                                {
                                  if (counter == 8)
                                  {
                                    direction = readinputport(6);
                                    temp = direction & ~16;
                                    counter = 0;
                              
                                    if ( temp == 0 ) center =1;
                                    else if ( temp == up         ) { center=0; xvalue = cent; yvalue = max;  currentx=cent;      currenty= cent+bump; }
                                    else if ( temp == down       ) { center=0; xvalue = cent; yvalue = 0;    currentx=cent;      currenty= cent-bump; }
                                    else if ( temp == left       ) { center=0; xvalue = max;  yvalue = cent; currentx=cent+bump; currenty= cent;      }
                                    else if ( temp == right      ) { center=0; xvalue = 0;    yvalue = cent; currentx=cent-bump; currenty= cent;      }
                              
                                    else if ( temp == right+up   ) { center=0; xvalue = 0;    yvalue = max;  currentx=cent-bump; currenty= cent+bump; }
                                    else if ( temp == right+down ) { center=0; xvalue = 0;    yvalue = 0;    currentx=cent-bump; currenty= cent-bump; }
                                    else if ( temp == left+up    ) { center=0; xvalue = max;  yvalue = max;  currentx=cent+bump; currenty= cent+bump; }
                                    else if ( temp == left+down  ) { center=0; xvalue = max;  yvalue = 0;    currentx=cent+bump; currenty= cent-bump; }
                                  }
                                  else counter++;
                              
                                  if (whichport == 0)
                                  {
                                    if (center)
                                      return currentx;
                                    return xvalue;
                                  }
                              
                                  else if (whichport == 2)
                                  {
                                    if (center)
                                      return currenty;
                                    return yvalue;
                                  }
                                }
                              
                              
                                else // use original inputs
                                  return readinputport(whichport);
                              }
                              
                              1 Reply Last reply Reply Quote 0
                              • G
                                grant2258 Banned
                                last edited by

                                strange ill checkout it out on the pi. You need to understand something about this code. This function only reads one axis at a time x then y over and over at high speeds keep that in mind if you make changes.

                                M 1 Reply Last reply Reply Quote 0
                                • M
                                  mahoneyt944 @grant2258
                                  last edited by mahoneyt944

                                  @grant2258

                                  It's seems to work good, the only issue I had was on the first run of the code direction wasn't defined so temp was trying to use an undefined variable and it caused glitches.

                                  So I changed it slightly,

                                  This version should solve it:

                                  Outdated

                                  static READ16_HANDLER( analog_r )
                                  {
                                    #define max  255
                                    #define cent 128
                                    #define bump 51
                                  
                                    #define up    1
                                    #define down  2
                                    #define left  4
                                    #define right 8
                                  
                                    static INT16  xvalue = 0x80;
                                    static INT16  yvalue = 0x80;
                                    static INT16  currentx  = 0x80; // face left first round
                                    static INT16  currenty  = 0x7F;
                                    static INT16  center = 0;
                                    static INT16  delay = 0;
                                  
                                    if( options.cheat_input_ports) // use cheat ports
                                    {
                                      if (delay == 8) // debounce protection
                                      {
                                        int temp = readinputport(6) & ~16;
                                        delay = 0;
                                  
                                        if ( temp == 0 ) center =1;
                                        else if ( temp == up         ) { center=0; xvalue = cent; yvalue = max;  currentx=cent;      currenty= cent+bump; }
                                        else if ( temp == down       ) { center=0; xvalue = cent; yvalue = 0;    currentx=cent;      currenty= cent-bump; }
                                        else if ( temp == left       ) { center=0; xvalue = max;  yvalue = cent; currentx=cent+bump; currenty= cent;      }
                                        else if ( temp == right      ) { center=0; xvalue = 0;    yvalue = cent; currentx=cent-bump; currenty= cent;      }
                                  
                                        else if ( temp == right+up   ) { center=0; xvalue = 0;    yvalue = max;  currentx=cent-bump; currenty= cent+bump; }
                                        else if ( temp == right+down ) { center=0; xvalue = 0;    yvalue = 0;    currentx=cent-bump; currenty= cent-bump; }
                                        else if ( temp == left+up    ) { center=0; xvalue = max;  yvalue = max;  currentx=cent+bump; currenty= cent+bump; }
                                        else if ( temp == left+down  ) { center=0; xvalue = max;  yvalue = 0;    currentx=cent+bump; currenty= cent-bump; }
                                      }
                                      else delay++;
                                  
                                      if (whichport == 0)
                                      {
                                        if (center)
                                          return currentx;
                                        return xvalue;
                                      }
                                  
                                      else if (whichport == 2)
                                      {
                                        if (center)
                                          return currenty;
                                        return yvalue;
                                      }
                                    }
                                  
                                    else // use original inputs
                                      return readinputport(whichport);
                                  }
                                  
                                  1 Reply Last reply Reply Quote 0
                                  • M
                                    mahoneyt944
                                    last edited by mahoneyt944

                                    Temp should also be defined inside the "delay" debounce section so it's not repeatily initialized. So it's initialized when we actually go to use it. Updated it above . I'll test it later

                                    And great work. This is a very clever solution.

                                    1 Reply Last reply Reply Quote 0
                                    • G
                                      grant2258 Banned
                                      last edited by grant2258

                                      actually that code isint there at all i just told you can increase the loop.

                                      https://github.com/grant2258/Blaster-Barcade/commit/3d1f20d2bcc51552672119cdded187633cdfe1d7#diff-4b920d5f055f4340a0d6485c3bc5846eR199

                                      this code always ensures the last direction is set was sent regardless if your missed read direction or not. the last position pressed is returned always. you should only have the delay around the reading the input port.

                                      The only change you need to make is change
                                      UINT16 direction;

                                      to static UINT16 direction =0; so its initialized at center when adding the delay loop.

                                           if(whichport == 0 || whichport ==2)   direction = readinputport(6); 
                                      

                                      was only originally there incase somone set cocktail mode thats reads 1 and 3 for player 2

                                      M 1 Reply Last reply Reply Quote 0
                                      • M
                                        mahoneyt944 @grant2258
                                        last edited by mahoneyt944

                                        @grant2258
                                        Correct it has to be static, That was my thinking. That's what I meant by the first time read it wasn't set. That's what caused my issue before.

                                        With that fixed, coded your way it updates direction once every 8 count but writes to the xcurrent, ycurrent, xvalue, yvalue on every count, which it doesn't need to since it's using the same direction value every time it writes. So I changed your code to update direction once every 8 count and write to xcurrent, ycurrent, xvalue, yvalue on every 8 count too.

                                        They both do the same thing, my version of your code just uses more efficiency when setting the variables.

                                        Then I moved int temp into it's scope so it's not initialized on every count but only when being used.

                                        Im glad it's working now regardless, I can't help thinking if we did something similar we could fix true analog stops too. Obviously 8 way is the best we can do on digital. Making mame2003-plus the home of working food fight lol. 💪, Unofficially.

                                        It's easier with digital because it's 8-way on or off movements but analog has range so you'd need to know the range of each direction.

                                        1 Reply Last reply Reply Quote 0
                                        • G
                                          grant2258 Banned
                                          last edited by grant2258

                                          Well this game isint 49 way its two pots on a gambit. Ie really big ass thumb stick. The code is sending back like this for a reason.

                                          Say you read x pause and y doesnt get updated your centering will be off because your only sending one axis back (it only reads one at a time0) and the other one got missed the x and y being off can effect your positioning. You looking at the code like its digital and its not you need to mimic an analog stick it was reading at this rate in the first place. the original code always met this condition anyway so it wasnt an issue until a delay was added i just showed you some code how to easily implement it.

                                          It seems you know what your doing hopefully this we help you understand a iittle more if you wanna try fix something else. To be honest I never payed this game before I like it but the music sucks balls! doorooh doooroho doooooooooooooooo aaaaaaaaaaaaarg

                                          M 1 Reply Last reply Reply Quote 0
                                          • M
                                            mahoneyt944 @grant2258
                                            last edited by mahoneyt944

                                            @grant2258

                                            What I'm getting at is, I test games on my spare pi outside my arcade cab which uses a PS2 style controller so it has digital and analog to work with. If I set the new center digital feature off and the cheat input feature off my digital keeps running as expected and analog will stop but always facing right. While still moving, analog has crisp moving directions between that of a 8 way control as it should.

                                            If I turn centering on both digital and analog stop to the right. Analog still has it crisp movements though.

                                            Now turn on cheat input. Both digital and analog stop correctly but analog is cut to 8 way movements because of the returns in the cheat input feature (which I know it's not meant for analog).

                                            If we coded this part:

                                            else // use original inputs
                                                return readinputport(whichport);
                                            

                                            To instead look for current analog positions, and return stops positions, analog could also benefit from fixed stops without being reduced to 8 way. It just has a lot more positions to account for.

                                            You'd need a grid chart to define each direction range of both pots(x and y) to use as a lookup table then determine a stop from it based on your position.

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post

                                            Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.

                                            Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.