endlesstravel / Love2dCS

C# Wrapper for LÖVE, a 2d game engine
MIT License
165 stars 14 forks source link

Joystick.IsConnected crashes love when using Red Rockcandy Xbox 360 controller #45

Open Shadowblitz16 opened 5 years ago

Shadowblitz16 commented 5 years ago

hello I have this code here that when it reaches the second line of the method it crashes

    public override void Update()
    {
        InputPrev = InputCurr;
        InputCurr = Joy.IsConnected() && Joy.IsDown(Key);
    }

image

Shadowblitz16 commented 5 years ago

here is the demo project https://drive.google.com/open?id=1LJGx11KsRysF2watXqXTVnLmfm6E_HLE

endlesstravel commented 5 years ago

I can't figure out what happend.

I just test your project, it's work fine. (your code has bug that InputMap.cs on line 151, joyStick may be a null object.)

Here is may test code, it just work fine as well,

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Love;

namespace Project1
{
    class issues45 : Scene
    {
        public override void Update(float dt)
        {
            foreach (var joy in Joystick.GetJoysticks())
            {
                joy.IsConnected();
                for (int i = 0; i < joy.GetButtonCount(); i++)
                {
                    if (joy.IsDown(i))
                    {
                        Console.WriteLine($"joy {joy.GetName() + joy.GetGUID()} key {i} is down !");
                    }
                }

                GamepadButton[] gpbs = (GamepadButton[])System.Enum.GetValues(typeof(GamepadButton));
                foreach (var btn in gpbs)
                {
                    if (joy.IsGamepadDown(btn))
                    {
                        Console.WriteLine($"joy {joy.GetName() + joy.GetGUID()} gampad {btn} is down!");
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            Boot.Init(new BootConfig
            {
            });
            Boot.Run(new issues45());
        }
    }
}
Shadowblitz16 commented 5 years ago

idk its still happening.

System.AccessViolationException
    HResult=0x80004003
    Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    Source=<Cannot evaluate the exception source>
    StackTrace:
<Cannot evaluate the exception stack trace>

at Love.Love2dDll._wrap_love_dll_type_Joystick_isConnected(IntPtr p, Boolean& out_result)
at Love.Joystick.IsConnected()
at BattleStars.Engine.ButtonMapJoystick.Update() in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars.Engine\src\Btn\ButtonMap.cs:line 88
at BattleStars.Engine.BtnPlayer.Update() in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars.Engine\src\Btn.cs:line 124
at BattleStars.Engine.Btn.Update() in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars.Engine\src\Btn.cs:line 145
at BattleStars.Engine.GameManager.Update(Single dt) in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars.Engine\src\Game.cs:line 49
at Love.Boot.Loop(BootConfig bootConfig, Scene scene)
at Love.Boot.Run(Scene scene, BootConfig bootConfig)
at BattleStars.Engine.Game.Run(Game game, Int32 gameW, Int32 gameH, Int32 gameFps, Int32 gameScale) in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars.Engine\src\Game.cs:line 80
at BattleStars.Program.Program.Main(String[] args) in C:\Users\Shadowblitz16\source\repos\BattleStars\BattleStars\src\Program.cs:line 14
Shadowblitz16 commented 5 years ago

so here is a revamped version that tries to make sure sure that the joystick exists..

public          class ButtonMapJoystick : ButtonMap
{
  public Joystick      Joy;
  public int           Player;
  public int           Players;
  public override bool InputCurr { get; set; }
  public override bool InputPrev { get; set; }

  public ButtonMapJoystick(GamepadButton key, int player)
  {
    Key    = (int)key;
    Player = player;
  }
  public override void Update()
  {
    if (Joystick.GetJoystickCount() != Players)
    {
        Players = Joystick.GetJoystickCount();
        if (Player < Players) Joy = Joystick.GetJoysticks()[Player];
    }

    InputPrev = InputCurr;
    InputCurr = (Joy != null) ? Joy.IsConnected() && Joy.IsDown(Key) : false;
  }
}    

it still crashes though

Shadowblitz16 commented 5 years ago

@endlesstravel I figured out what it was. its the red rockcandy xbox 360 controller I am using it crashes love. here is a picture of it https://i5.walmartimages.com/asr/029a0f17-9f5a-4c14-815e-353897f6c00b_1.2947e88f4b93170e31e057d2c5a14f76.jpeg?odnHeight=180&odnWidth=180&odnBg=FFFFFF

endlesstravel commented 5 years ago

I can't figure out what happend. 😭

I tested all my controllers, it is no crashed.

It is that Love crashed only you use red rockcandy xbox 360 controller ?

Shadowblitz16 commented 5 years ago

its the only controller I have besides the cheap snes controller most engines don't support. but ya if the controller are unplugged love is fine, but if they are plugged in the it seems that it crashes on Joystick:IsSupported().

endlesstravel commented 5 years ago

That's strange. Original Love has no method IsSupported on Joystick.

image

did you mean is Joystick:isConnected ?

Can you test on original Original Love to figure it crashed as well ?

Shadowblitz16 commented 5 years ago

ok so in this code where it says putBreakPointHere it is never triggered even though I directly check if Keyboard is pressed

        public string MapInput(BtnType type)
        {
            BtnMapKeyboard keyboard =  Keyboards[(int)type];
            KeyConstant[ ] Keys1    = (KeyConstant[])Enum.GetValues(typeof(KeyConstant));
            foreach (var key in Keys1)
            {
                if (key == KeyConstant.V)
                {
                    var test = Keyboard.IsPressed(key);
                    if (test)
                    {
                        var putBreakPointHere = true;
                    }
                }
                if (Keyboard.IsPressed(key) && !KeyboardsHasKey(type, key))
                {
                    keyboard.MapInput((int)key);
                    keyboard.SetInput(BtnState.Held);
                    return key.ToString();
                }
            }

            BtnMapJoystick joystick = Joysticks[(int)type];
            GamepadButton[] Keys2 = (GamepadButton[])Enum.GetValues(typeof(GamepadButton));
            foreach (var key in Keys2)
            {
                if (joystick.Joy != null && joystick.Joy.IsPressed((int)key) && !JoysticksHasKey(type, key))
                {
                    joystick.MapInput((int)key);
                    joystick.SetInput(BtnState.Held);
                    return key.ToString();
                }
            }

            return "";
        }

I have no idea where i got the joystick.isSupported() maybe it was joystick.isConnected(). maybe it was a bad usb connection that was making it crash because it doesn't do it now

endlesstravel commented 5 years ago

en, Interesting things. I mean, can you test the code below? If there no output on window, and i thinks there is some code environment make it invalid. Can you email your sample project to me, so i can analysis what happend.

using System;
using Love;

namespace Project1
{
    class issues45 : Scene
    {
        string infoString = "";
        public override void Update(float dt)
        {
            foreach (var key in (KeyConstant[])Enum.GetValues(typeof(KeyConstant)))
            {
                if (Keyboard.IsPressed(key))
                {
                    infoString += key.ToString() + " is Pressed. \n";
                }
            }
        }

        public override void Draw()
        {
            Graphics.Print(infoString);
        }

        static void Main(string[] args)
        {
            Boot.Init(new BootConfig
            {
            });
            Boot.Run(new issues45());
        }
    }
}
Shadowblitz16 commented 5 years ago

this doesn't draw or print anything

using System;
using Love;

namespace LoveControllerTest
{
    class Program : Scene
    {
        string infoString = "";
        public override void Update(float dt)
        {
            foreach (var key in (KeyConstant[])Enum.GetValues(typeof(KeyConstant)))
            {
                if (Keyboard.IsPressed(key))
                {
                    infoString += key.ToString() + " is Pressed. \n";
                }
            }
        }

        public override void Draw()
        {
            Graphics.SetColor(Color.White);
            Graphics.Print(infoString);
        }

        static void Main(string[] args)
        {
            Boot.Init(new BootConfig
            {
            });
            Boot.Run(new Program());
        }
    }
}