Aros/Developer/Docs/Libraries/LowLevel

< Aros < Developer < Docs < Libraries
Navbar for the Aros wikibook
Aros User Docs
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
Aros Intel AMD x86 Installing
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros x86 Complete System HCL
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
Motorola 68k Amiga Support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Android Support
Arm Raspberry Pi Support
PPC Power Architecture
misc
Aros Public License


History

The lowlevel.library, introduced in Workbench/Kickstart 3.1, offers timer and keyboard/joystick support functions to game and demo programmers.

The original library was designed by Commodore and had the following issues...

lowlevel.library does not maintain a list of interrupt handlers, it maintains only a single interrupt handler, which is added additionally to standard keyboard processing.


Current

ReadJoyPort() is patched for USB usage.

In the original AmigaOS lowlevel.library and keyboard.device are tightly glued together and in fact just two interfaces of one module and can't be separated. Anyway, two new HIDDs which now manages the keyboard and mouse drivers. Now it is possible to plug in several lowlevel drivers at once, their input streams will be merged. See rom/hidd/keyboard and rom/hidd/mouse.


Analogue Programming

ReadJoyPort(unit) to get the usual digital positions ReadJoyPort(unit + JP_TYPE_ANALOGUE) to get the new analog positions which contains two eight bit counters holding the absolute position of two joystick axis.

The analogue axis information is an unsigned integer from 0 to 255 and has not necessarily been calibrated to be centered at 128.

An application can also take control and can explicitly demand JP_TYPE_ANALOGUE data by either adding JP_ANALOGUE_PORT_MAGIC to the portNumber or setting SJA_TYPE to SJA_TYPE_ANALOGUE in SetJoyPortAttrs().


Rumble Programming

SetJoyPortAttrsA() adds three options for force feedback and rumble pack support. These are currently very basic controls of two motors found in the joypad.

If SJA_TYPE_AUTOSENSE is used, ReadJoyPort() will attempt to determine the type of controller plugged into the given port automatically. If one of the other types is used, ReadJoyPort() will forcing a port to deallocate any allocated resources; return the implied type to SJA_TYPE_AUTOSENSE.

RESULT success - TRUE if everything went according to plan, or FALSE upon failure

The call to turn rumble on is

SetJoyPortAttrsA(joy, SJA_RumbleSetFastMotor, 255, TAG_DONE);

where joy is the appropriate unit

ReadJoyPort() ignores buttons 8-12 on the gamepad, even though they work fine in Preferences 

Sometimes they are not, as there is no real standard for that. It seems to be the norm but not always...



Examples

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/lowlevel.h>
#include <libraries/lowlevel_ext.h>

#include <stdio.h>
#include <stdlib.h>


struct Library *LowLevelBase;

static void printbuttons(ULONG val)
{
    if (val & JPF_BUTTON_PLAY)      printf("[PLAY/MMB]");
    if (val & JPF_BUTTON_REVERSE)   printf("[REVERSE]");
    if (val & JPF_BUTTON_FORWARD)   printf("[FORWARD]");
    if (val & JPF_BUTTON_GREEN)     printf("[SHUFFLE]");
    if (val & JPF_BUTTON_RED)       printf("[SELECT/LMB/FIRE]");
    if (val & JPF_BUTTON_BLUE)      printf("[STOP/RMB]");
}

static void printmousedirections(ULONG val)
{
    printf("[%d,%d]", (val & JP_MHORZ_MASK), (val & JP_MVERT_MASK) >> 8);
}

static void printajoydirections(ULONG val)
{
    printf("[%d, %d]", (val & JP_XAXIS_MASK), (val & JP_YAXIS_MASK) >> 8);
}
static void printjoydirections(ULONG val)
{
    if (val & JPF_JOY_UP)       printf("[UP]");
    if (val & JPF_JOY_DOWN)     printf("[DOWN]");
    if (val & JPF_JOY_LEFT)     printf("[LEFT]");
    if (val & JPF_JOY_RIGHT)    printf("[RIGHT]");
}

static void printjoyport(ULONG val)
{
    int i;
    
    for(i = 31; i >= 0; i--)
    {
    	printf("%d", (val & (1 << i)) ? 1 : 0);
    }
    
    printf(" - ");
    
    if ((val & JP_TYPE_MASK) == JP_TYPE_NOTAVAIL) printf("NOT AVAILABLE");
    if ((val & JP_TYPE_MASK) == JP_TYPE_UNKNOWN)  printf("UNKNOWN");
    
    if ((val & JP_TYPE_MASK) == JP_TYPE_JOYSTK)
    {
        printf("JOYSTICK - ");
        printjoydirections(val);
        printbuttons(val);
    }
    
    if ((val & JP_TYPE_MASK) == JP_TYPE_GAMECTLR)
    {
        printf("GAME CONTROLLER - ");
        printjoydirections(val);
        printbuttons(val);
    }

    if ((val & JP_TYPE_MASK) == JP_TYPE_MOUSE)
    {
        printf("MOUSE - ");
        printmousedirections(val);
        printbuttons(val);
    }
    
    if ((val & JP_TYPE_MASK) == JP_TYPE_ANALOGUE)
    {
        printf("JOYSTICK[ANALOGUE] - ");
        printajoydirections(val);
        printbuttons(val);
    }

    printf("\n");
}

int main(int argc, char **argv)
{
    int unit = 1;

    if (argc == 2) unit = atoi(argv[1]);

    LowLevelBase = OpenLibrary("lowlevel.library", 0);

    if (LowLevelBase)
    {
        ULONG old = 0;

        while(!CheckSignal(SIGBREAKF_CTRL_C))
        {
            ULONG new;

            new = ReadJoyPort(unit);
            if (new != old)
            {
	            old = new;
                printjoyport(new);
            }

            Delay(1);
        }
        CloseLibrary(LowLevelBase);
    }

    return 0;
}



Reference

implemented

ULONG ReadJoyPort(ULONG port)
UBYTE GetLanguageSelection()
ULONG GetKey()
VOID QueryKeys(struct KeyQuery * queryArray, UBYTE arraySize)
APTR AddKBInt(const APTR intRoutine, const APTR intData)
VOID RemKBInt(APTR intHandle)
ULONG SystemControlA(const struct TagItem * tagList)
ULONG SystemControl(Tag tagList, ...)
APTR AddTimerInt(const APTR intRoutine, const APTR intData)
VOID RemTimerInt(APTR intHandle)
ULONG ElapsedTime(struct EClockVal * context)
APTR AddVBlankInt(const APTR intRoutine, const APTR intData)
VOID RemVBlankInt(APTR intHandle)
BOOL SetJoyPortAttrsA(ULONG portNumber, const struct TagItem * tagList)


not implemented

BOOL SetJoyPortAttrs(ULONG portNumber, Tag tagList, ...)
VOID StopTimerInt(APTR intHandle)
VOID StartTimerInt(APTR intHandle, ULONG timeInterval, BOOL continuous)


The type of device can be determined by applying the mask JP_TYPE_MASK to the return value and comparing the resultant value with the following:

JP_TYPE_NOTAVAIL port data unavailable
JP_TYPE_GAMECTLR game controller
JP_TYPE_MOUSE mouse
JP_TYPE_JOYSTK joystick
JP_TYPE_ANALOGUE analog stick
JP_TYPE_UNKNOWN unknown device
If type = JP_TYPE_GAMECTL R the bit map of portState is:
JPF_BUTTON_BLUE Blue - Stop
JPF_BUTTON_RED Red - Select
JPF_BUTTON_YELLOW Yellow - Repeat
JPF_BUTTON_GREEN Green - Shuffle
JPF_BUTTON_FORWARD Charcoal - Forward
JPF_BUTTON_REVERSE Charcoal - Reverse
JPF_BUTTON_PLAY Grey - Play/Pause
JPF_JOY_UP Up
JPF_JOY_DOWN Down
JPF_JOY_LEFT Left
JPF_JOY_RIGHT Right
If type = JP_TYPE_JOYSTK the bit map of portState is:
JPF_BUTTON_BLUE Right
JPF_BUTTON_RED Fire
JPF_JOY_UP Up
JPF_JOY_DOWN Down
JPF_JOY_LEFT Left
JPF_JOY_RIGHT Right
If type = JP_TYPE_MOUSE the bit map of portState is:
JPF_BUTTON_BLUE Right mouse
JPF_BUTTON_RED Left mouse
JPF_BUTTON_PLAY Middle mouse
JP_MVERT_MASK Mask for vertical counter
JP_MHORZ_MASK Mask for horizontal counter
If type = JP_TYPE_ANALOGUE the bit map of portState is:
JPF_BUTTON_RED Button 1 (standard fire)
JPF_BUTTON_BLUE Button 2
JPF_BUTTON_GREEN Button 3
JPF_BUTTON_YELLOW Button 4
JPF_BUTTON_FORWARD Button 5
JPF_BUTTON_REVERSE Button 6
JPF_BUTTON_PLAY Button 7
JP_XAXIS_MASK Mask for horizontal position
JP_YAXIS_MASK Mask for vertical position
This article is issued from Wikibooks. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.