Controllers

From Amiga Development Wiki
Jump to: navigation, search

Lowlevel.library was added in Kickstart 3.1 to support new CD32 game controllers. Until then it was not a possible support joysticks without direct hardware access.

With lowlevel.library you can access game controllers (game pads), digital and analog joysticks or mice. USB joysticks and game pads are transparently mapped to lowlevel.library ports.

#include <libraries/lowlevel.h>
#include <proto/dos.h>
#include <proto/lowlevel.h>
 
#define MAX_JOYSTICKS 4 /* lowlevel.library is limited to 4 ports */
 
void find_controllers()
{
   int i, done = FALSE;
 
   for (i = 0; i < MAX_JOYSTICKS && done == FALSE; i++)
   {
      ULONG flags;
 
      switch (i)
      {
         case 0:
            flags = ReadJoyPort(1);
            break;
 
         case 1:
            flags = ReadJoyPort(0);
            break;
 
         default:
            flags = ReadJoyPort(i);
            break;
      }
 
      switch (flags & JP_TYPE_MASK)
      {
         case JP_TYPE_NOTAVAIL:
            done = TRUE;
            break;
 
         case JP_TYPE_GAMECTLR:
            PutStr("Game controller found\n");
            break;
 
         case JP_TYPE_MOUSE:
            PutStr("Mouse controller found\n");
            break;
 
         case JP_TYPE_JOYSTK:
            PutStr("Joystick found\n");
            break;
      }
   }
}

Reading controller states is very simple. Please note that analog support is not available if lowlevel.library version is too old.

#include <libraries/lowlevel.h>
#include <libraries/lowlevel_ext.h>
#include <proto/dos.h>
#include <proto/lowlevel.h>
 
void read_controller(int port)
{
   ULONG flags = ReadJoyPort(port);
 
   switch (flags & JP_TYPE_MASK)
   {
      case JP_TYPE_NOTAVAIL:
         return;
 
      case JP_TYPE_GAMECTLR:
      case JP_TYPE_MOUSE:
      case JP_TYPE_JOYSTICK:
         if (flags & JPF_JOY_DOWN)
            PutStr("Controller down\n");
         else if (flags & JPF_JOY_UP)
            PutStr("Controller up\n");
 
         if (flags & JPF_JOY_LEFT)
            PutStr("Controller left\n");
         else if (flags & JPF_JOY_RIGHT)
            PutStr("Controller right\n");
 
         break;
   }
 
   if (LowLevelBase->lib_Version > 50 || (LowLevelBase->lib_Version >= 50 && LowLevelBase->lib_Revision >= 17))
   {
      ULONG analog = ReadJoyPort(port + JP_ANALOGUE_PORT_MAGIC);
 
      if (analog & JP_TYPE_ANALOGUE)
      {
         LONG x_axis = analog & JP_XAXIS_MASK;
         LONG y_axis = analog & JP_YAXIS_MASK;
 
         Printf("Analog: %ld/%ld\n", x_axis, y_axis);
      }
   }
 
   switch (flags & JP_TYPE_MASK)
   {
      case JP_TYPE_GAMECTLR:
         if (data & (JPF_BUTTON_BLUE | JPF_BUTTON_RED | JPF_BUTTON_YELLOW | JPF_BUTTON_GREEN | JPF_BUTTON_FORWARD | JPF_BUTTON_REVERSE | JPF_BUTTON_PLAY))
            PutStr("Button pressed\n");
         break;
 
      case JP_TYPE_JOYSTK:
         if (data & (JPF_BUTTON_BLUE | JPF_BUTTON_RED))
            PutStr("Button pressed\n");
         break;
 
      case JP_TYPE_MOUSE: /* Play button is middle button */
         if (data & (JPF_BUTTON_BLUE | JPF_BUTTON_RED | JPF_BUTTON_PLAY))
            PutStr("Button pressed\n");
         break;
   }
}