Cronus Controller AdapterRecently, I came across a pretty cool little device called the “Cronus controller adapter“. Basically, it’s a USB dongle that can be plugged into your Xbox 360 or Playstation 3, allowing you to use any controller you want no matter what console it was originally designed for as long as it works over USB. For example, using the Cronus adapter, you can use your Xbox 360 controller on your Playstation 3, your Playstation 3 controller on your Xbox 360, or your mouse and keyboard on both. Since I (used to) do a lot of computer vision programming (and have been looking for an excuse to get back into it), I felt like this little device would be a great way for me to create some new computer vision applications. Since I’ve already written several computer vision apps that can detect and track objects, I would like to test my skills at automating some video games by using OpenCV for the processing. Since the Cronus controller adapter allows you to feed commands to your Xbox 360 and Playstation 3 from basically any other device, I think that the Cronus adapter will be a great way for me to send commands to my Xbox 360 based on objects detected and tracked by OpenCV using my computer.

The Cronus controller adapter has a file that can be downloaded from the Cronus website (http://www.cronusdevice.com) called “gcdapi.dll” which is an API that you can use to communicate with the Cronus adapter using your programming language of choice. Since I am working with C#, I have to write a DLL wrapper so that I can invoke the API calls from my C# application. I have already started working on the wrapper and already have the basic commands supported (gcapi_IsConnected, gcapi_GetTimeVal, gcapi_CalcPressTime). As time permits, I will finish out all of the API’s commands. There are only about 6 commands, but I have only had about 5 minutes to work on the wrapper. Once I finish the wrapper and the example application, I will post both of them on this website for the rest of you to play with. I will also post the code I am working on that uses OpenCV for processing video input from the games and the Cronus device for sending commands to my Xbox 360. Currently, since it is probably the simplest game to automate using computer vision, I am creating a test app that can be used to automate Guitar Hero gameplay. Here’s a screenshot of the first test of the app where it identifies where the buttons are located on the screen and draws corresponding rectangles around them.

Guitar Hero Automation Test 1

If you do not want to wait on me to finish my code, you can and should checkout the Gamepad Proxy website at http://www.gamepadproxy.com. There you will find all kinds of other useful tools and tutorials that teach you how to work with the Cronus device and how to work with the API. They even include a tool that helps automate Guitar Hero gameplay as well. Gamepad Proxy also has a link to download the Cronus Software Suite which you will need to define your controller settings when using the Cronus device.

For those of you that have already automated some video games, please share with us your success stories. For those of you that have not already automated any video games, please share with us your ideas for games you would like to see automated. Also, be sure to pickup your Cronus controller adapter from Amazon by clicking here.

Here is the Cronus controller adapter in action where I use it to automate Guitar Hero on my Xbox 360.

 

Thank you for your interest in my site. If you find the information provided on this site useful, please consider making a donation to help continue development!

PayPal will open in a new tab.
$2.00
$5.00
Other

Related Posts

Tagged with:  

30 Responses to Video Game Automation with OpenCV and C#

  1. kodypeterson says:

    Just wondering if you have this code hosted somewhere. I am currently working with the cronus device and would love not to have to write the wrapper myself if you already have it. Thanks!

    • LuCuS says:

      Unfortunately, I do not have the code online anywhere at this time. Do to my “day job” getting in the way :-), I had to put this project on hold for a while and never had a chance to revisit it. I did however get the wrapper working. I just never put it online nor did I complete the computer vision code any further than the Guitar Hero automation app. I got pulled into a 5 month project at work shortly after posting this article and forgot all about this. If you’re looking at just automating Guitar Hero, you should search the GamePadProxy.com website for a plugin called “Guitar Master” as it’s already capable of automating Guitar Hero. If I can find some extra time (which is highly unlikely for the near future), I’d like to revisit this project and continue working on some of the projects I had originally intended to work on. I had a pretty good start on automating some racing games and planned to take a look at some FPS games as well.

    • LuCuS says:

      BTW, you can find the API mentioned in the article as well as a “.h” file at the Gamepad Proxy site: http://www.gamepadproxy.com/manual/. Just click on “Device API” on the left.

      • kodypeterson says:

        Yeah, I have been trying to get the dll into my project but it is saying that it is not valid. :/ Back to the drawing board??? By the way, I am working on creating a Street View map for GTA 5. That is where this all comes to play need something to turn the camera to take a perfect 360 capture for the Street View API. So I just need to tell cronus to press specific keys. That is all… Any advise or direction you have would be very helpful.

        • LuCuS says:

          You will need to use the gcapi_Write method. I can’t remember right off the top of my head how the code looked and I don’t have my computer nearby that has the code on it. But, I think the code looked something like this for the wrapper part of that method.

          [DllImport("gcdapi.dll")]
          private static extern int gcapi_Write(int[] output);
          public static int Write(int[] output)
          {
          return gcapi_Write(output);
          }

  2. kodypeterson says:

    Oh! So i don’t need to add the dll as a reference in the project?

    • LuCuS says:

      No. The DLL is an “unmanaged” C library. Had it been a “managed” library, you could import it right in and work with it directly. Since it’s “unmanaged”, you will have to write a wrapper that exposes its internal methods for your code to use. The “[DllImport(“gcdapi.dll”)]” part in the example I sent you last will take care of the loading part for you. The DLL will still need to be in the same directory as your EXE.

      • kodypeterson says:

        Perfect! So, got that working.. .Just need to figure out what the output states are. Any reference on that? You have been terrific help!

        • kodypeterson says:

          So, I found the states. And now am getting a return of 0. Here is what I have:

          [DllImport(“gcdapi.dll”)]
          private static extern int gcapi_Write(int[] output);

          public static int Write(int[] output)
          {
          return gcapi_Write(output);
          }

          private void button1_Click(object sender, EventArgs e)
          {
          int[] arr1 = new int[] { 19 };
          Console.WriteLine(WindowsFormsApplication3.Program.Write(arr1));
          }

          Now, 19 should be XB360_A

          It is writing a “0” to the console which means error, but idk what the error is.. 😛 Any help would be great!

          • LuCuS says:

            If I’m remembering correctly, you will need to call the “gcdapi_Load” method before you can pass data to it. So, in your wrapper class, you’ll need to add a Load wrapper such as:

            [DllImport("gcdapi.dll")]
            private static extern int gcdapi_Load();
            public static int Load()
            {
            return gcdapi_Load();
            }

            Then, to test that your device is connected, loaded, and ready to accept calls, you can test it with this:

            [DllImport("gcapi.dll")]
            private static extern int gcapi_IsConnected();
            public static bool IsConnected()
            {
            return gcapi_IsConnected() == 1 ? true : false;
            }

            You’ll also need to make sure you unload the device when closing your app. You can do that using the “gcdapi_Unload” method.

            [DllImport("gcdapi.dll")]
            private static extern int gcdapi_Unload();
            public static bool Unload()
            {
            return gcdapi_Unload();
            }

  3. kodypeterson says:

    Hmmm…. So added those in and Load() returns “1025” and isConnected returns “False” :/ I think I am doomed….. Although, I have verified through CronusCnfg it is connected and the monitor is seeing the controller input/output…

    • LuCuS says:

      Try giving your device a second to “wake up” and register. You can do that by putting the following code between where you call Load and where you call IsConnected.

      System.Threading.Thread.Sleep(1000);

    • LuCuS says:

      Also, I think the IsConnected logic is wrong. It should be this:

      return gcapi_IsConnected() > 0 ? true : false;

      • kodypeterson says:

        I will try that. gcaip_IsConnected() is returning a different int every application run… Here are 2 ex. “13850369” & “45897473” Also, when not connected I get a high number too “43144960” and it too is different

        • LuCuS says:

          Yeah. Forget my last comment. According to the API docs, you should be getting a 1 or 0 (true or false).

          • kodypeterson says:

            Yes, but it is not returning a 0 or a 1… Odd

          • LuCuS says:

            How do you have your Cronus connected to your computer? Is it connected directly to a USB port or is it connected to your console and then connected to your computer using a USB cable? Also, all of the code I have shared today is code from memory (which I have horrible memory). So, I would recommend comparing the code to the API docs to make sure everything is correct.

  4. kodypeterson says:

    🙁 Darn Still False I even had it wait 15 seconds “1500” and still was False… Although, on a plus note. My math is being exercised as a requirement to comment 😉

  5. kodypeterson says:

    I have it connected to the console then the PCPROG port it to my PC. It does seem like the docs are matching up to your code except for the type so idk what “uint8_t” converts to from C to C#

    • LuCuS says:

      “uint8_t” is the same as a “byte”. So, try changing your code from “private static extern int” to “private static extern byte”. Now your “IsConnected” should work.

      • kodypeterson says:

        That was the ticket. Working on seeing if the “write” works… Write is uint8_t _stdcall gcapi_Write(int8_t *output) do we need a change?

        • LuCuS says:

          Yes. It too will need to be changed.

          private static extern byte gcapi_Write(byte[] output);

          • kodypeterson says:

            So, that does not work. I was using int[] output and i was able to change the first 5 indexes but they did not match up to the indexes in the API docs. Also, to activate it would be 100 as the byte value for the index value? I am not sure how int 100 translates to byte type.

          • LuCuS says:

            You need to convert your int value to a byte[]. You can do that like this:

            int intValue;
            byte[] intBytes = BitConverter.GetBytes(intValue);
            Array.Reverse(intBytes);
            byte[] result = intBytes;

            You’ll then pass “intBytes” to the Write(byte[] output)” wrapper.

  6. kodypeterson says:

    Not sure that will work. intValue = an int array

    int8_t output[GCAPI_OUTPUT_TOTAL] = {0};

    output[PS3_CROSS] = 100;
    output[PS3_LX] = -45;

    if(!gcapi_Write(output)) {

    See what they do?

    • LuCuS says:

      They’re just setting up a new byte array and assigning values in that array at positions PS3_CROSS & PS3_LX (where PS3_CROSS = 19, PS_LX = 11, and GCAPI_OUTPUT_TOTAL = 36):

      byte[] output = new byte[GCAPI_OUTPUT_TOTAL];
      output[PS3_CROSS] = Convert.ToByte(100);
      output[PS3_LX] = Convert.ToByte(-45);
      Gcdapi.Write(output);

  7. Glashoop says:

    Dear LuCuS,

    I would love to start using your script on my Cronus for Guitar Hero, from this i would love to learn how this works. Is the download you tagged in your other post the one you are using on your youtube account in which you can see you auto playing Guitar Hero?

    Cheers
    Jeroen

    • LuCuS says:

      I created 2 videos of this. The video embedded above is using Gamepad Proxy. The other video used my app which is from the screenshot at the top of this article. Both apps allow you to watch the game being played in real-time.

Leave a Reply