跳转到内容

Aros/开发者/文档/库/底层

来自维基教科书,开放的世界,开放的书籍
Aros 维基教科书的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从 AmigaOS/SDL 移植软件
为 Zune 初学者
Zune .MUI 类
为 SDL 初学者
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm 覆盆子派支持
PPC Power Architecture
杂项
Aros 公共许可证

lowlevel.library,在 Workbench/Kickstart 3.1 中引入,为游戏和演示程序员提供计时器和键盘/操纵杆支持功能。

原始库由康懋达设计,存在以下问题...

  • 输入函数是轮询式的,而 AmigaOS 是事件驱动的。
  • 输入函数是系统范围的,而不是应用程序范围的。如果按下左键,只希望活动应用程序检测到它。使用低级库,其他应用程序也会检测到它。
  • 某些功能一次只能由一个应用程序使用。在多任务环境中,这是一个非常糟糕的想法。
  • 某些其他计时器函数只对 16 小时有效。然后它会返回错误的结果。
  • 鼓励程序员使用软件中断而不是高优先级线程。

lowlevel.library 不维护中断处理程序列表,它只维护一个中断处理程序,该处理程序会额外添加到标准键盘处理中。

ReadJoyPort() 已针对 USB 使用进行修补。

在原始的 AmigaOS 中,lowlevel.library 和 keyboard.device 密切相关,实际上只是一个模块的两个接口,不能分开。无论如何,现在有两个新的 HIDD,它们管理键盘和鼠标驱动程序。现在可以同时插入多个低级驱动程序,它们的输入流将被合并。请参阅 rom/hidd/keyboard 和 rom/hidd/mouse。

模拟编程

[编辑 | 编辑源代码]

ReadJoyPort(unit) 获取通常的数字位置 ReadJoyPort(unit + JP_TYPE_ANALOGUE) 获取新的模拟位置,其中包含两个八位计数器,用于保存两个操纵杆轴的绝对位置。

模拟轴信息是 0 到 255 之间的无符号整数,不一定经过校准使其以 128 为中心。

应用程序也可以控制,并可以通过将 JP_ANALOGUE_PORT_MAGIC 添加到 portNumber 或在 SetJoyPortAttrs() 中将 SJA_TYPE 设置为 SJA_TYPE_ANALOGUE 来明确要求 JP_TYPE_ANALOGUE 数据。

  • 要使用第二个模拟操纵杆,必须将其分配为第二个操纵杆(例如,将左操纵杆作为端口 0 中的操纵杆,另一个作为端口 1 中的操纵杆),并在该“第二个”操纵杆上启用模拟黑客。
  • 对两个低级单元使用 JP_ANALOGUE_PORT_MAGIC。然后将操纵杆的第二个模拟摇杆映射到低级单元 0 的轴。
  • 你的游戏现在可以读取一个操纵杆的两个模拟摇杆 :-)

震动编程

[编辑 | 编辑源代码]

SetJoyPortAttrsA() 为力反馈和震动包支持添加了三个选项。这些目前是对操纵杆中找到的两个马达的非常基本的控制。

  • portNumber - 相关的操纵杆端口 (0-3)。
  • SJA_Type (ULONG) - 将当前控制器类型设置为鼠标、操纵杆或游戏控制器。提供以下之一:SJA_TYPE_GAMECTLR、SJA_TYPE_MOUSE、SJA_TYPE_JOYSTK 或 SJA_TYPE_AUTOSENSE。如果使用 SJA_TYPE_AUTOSENSE,则 SJA_TYPE_ANALOGUE 或 SJA_TYPE_AUTOSENSE。

如果使用 SJA_TYPE_AUTOSENSE,ReadJoyPort() 将尝试自动确定插入给定端口的控制器类型。如果使用其他类型之一,ReadJoyPort() 将强制端口释放任何已分配的资源;将隐含类型返回到 SJA_TYPE_AUTOSENSE。

  • SJA_RumbleSetSlowMotor (UBYTE) - 如果有震动包,使用此标记将设置慢速马达的速度为给定值 (0 - 255)。
  • SJA_RumbleSetFastMotor (UBYTE) - 如果有震动包,使用此标记将设置快速马达的速度为给定值 (0 - 255)。
  • SJA_RumbleOff (BOOL) - 如果设置,这将关闭震动包马达。

RESULT success - 如果一切按计划进行,则为 TRUE,否则为 FALSE。

打开震动的调用是

SetJoyPortAttrsA(joy, SJA_RumbleSetFastMotor, 255, TAG_DONE);

其中 joy 是相应的单元

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


#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;
}


value other than JP_TYPE_NOTAVAIL) this function may be used in interrupts.

As an extension to the former available data, analogue joystick data may be returned. This is currently only supported by the Poseidon USB HID class, however, in future other devices may also add support for it.

The user may specify the analogue data override option in the HID class and the data returned by ReadJoyPort() will be of type 
JP_TYPE_ANALOGUE, which contains two eight bit counters holding the absolute position of two joystick axis. 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().

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


Compatibility issues:
- If the HID class is not loaded, use of SJA_TYPE_ANALOGUE will have no effect and JP_TYPE_NOTAVAIL will be returned on ReadJoyPort(). 
- If the HID class is not loaded, and JP_ANALOGUE_PORT_MAGIC is used, JP_TYPE_NOTAVAIL will be returned on ReadJoyPort().
- If SetJoyPortAttrs() has been set to SJA_TYPE_JOYSTK or SJA_TYPE_GAMECTRL, using portNumbers from 0 to 3 still will return
digitally interpreted data, whereas using portNumbers from JP_ANALOGUE_PORT_MAGIC to JP_ANALOGUE_PORT_MAGIC+3 will return
the analogue data from the ports.

INPUTS
portNumber - port to read, in the range 0 to 3.

If the JP_ANALOGUE_PORT_MAGIC bit is set additionally, the returned bitmask will be of JP_TYPE_ANALOGUE, even
if the port was set to JP_TYPE_GAMECTRL or JP_TYPE_JOYSTK before.

RESULT
portState - bit map that identifies the device and the current

JP_TYPE_GAMECTLR        game controller
JP_TYPE_MOUSE           mouse
JP_TYPE_JOYSTK          joystick
JP_TYPE_ANALOGUE        analogue stick (EXT)
JP_TYPE_UNKNOWN         unknown device
 
If type = JP_TYPE_GAMECTLR the bit map of portState is:

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


SEE ALSO SetJoyPortAttrs()
 
time attempting to sense which type of controller is in use -- and, optionally, to force ReadJoyPort() into utilizing a certain 
controller type.

SetJoyPortAttrs() adds three options for force feedback and rumble pack support. These are currently very basic controls of two
motors found in the joypad. 
 
INPUTS
portNumber - the joyport in question (0-3).
SJA_Type (ULONG) - Sets the current controller type to the mouse, joystick, or game controller. Supply one of 		SJA_TYPE_GAMECTLR, SJA_TYPE_MOUSE, SJA_TYPE_JOYSTK, or SJA_TYPE_AUTOSENSE. If SJA_TYPE_AUTOSENSE is used,

SJA_TYPE_ANALOGUE, or SJA_TYPE_AUTOSENSE. 
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.

SJA_RumbleSetSlowMotor (UBYTE) - If a rumble pack is available, using this tag will set the speed of the slow motor
to the given value (0 - 255).

SJA_RumbleSetFastMotor (UBYTE) - If a rumble pack is available, using this tag will set the speed of the fast motor
to the given value (0 - 255).

SJA_RumbleOff (BOOL) - If set, this will turn the rumble pack motors off.

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


<libraries/lowlevel.h>


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)

可以通过将掩码 JP_TYPE_MASK 应用于返回值并将结果值与以下值进行比较来确定设备类型

JP_TYPE_NOTAVAIL 端口数据不可用
JP_TYPE_GAMECTLR 游戏控制器
JP_TYPE_MOUSE 鼠标
JP_TYPE_JOYSTK 操纵杆
JP_TYPE_ANALOGUE 模拟摇杆
JP_TYPE_UNKNOWN 未知设备
如果 type = JP_TYPE_GAMECTL R,则 portState 的位图是
JPF_BUTTON_BLUE 蓝色 - 停止
JPF_BUTTON_RED 红色 - 选择
JPF_BUTTON_YELLOW 黄色 - 重复
JPF_BUTTON_GREEN 绿色 - 随机播放
JPF_BUTTON_FORWARD 炭灰色 - 向前
JPF_BUTTON_REVERSE 炭灰色 - 向后
JPF_BUTTON_PLAY 灰色 - 播放/暂停
JPF_JOY_UP 向上
JPF_JOY_DOWN 向下
JPF_JOY_LEFT 向左
JPF_JOY_RIGHT 向右
如果 type = JP_TYPE_JOYSTK,则 portState 的位图是
JPF_BUTTON_BLUE 向右
JPF_BUTTON_RED 开火
JPF_JOY_UP 向上
JPF_JOY_DOWN 向下
JPF_JOY_LEFT 向左
JPF_JOY_RIGHT 向右
如果 type = JP_TYPE_MOUSE,则 portState 的位图是
JPF_BUTTON_BLUE 右键
JPF_BUTTON_RED 左键
JPF_BUTTON_PLAY 中键
JP_MVERT_MASK 垂直计数器的掩码
JP_MHORZ_MASK 水平计数器的掩码
如果 type = JP_TYPE_ANALOGUE,则 portState 的位图是
JPF_BUTTON_RED 按钮 1(标准开火)
JPF_BUTTON_BLUE 按钮 2
JPF_BUTTON_GREEN 按钮 3
JPF_BUTTON_YELLOW 按钮 4
JPF_BUTTON_FORWARD 按钮 5
JPF_BUTTON_REVERSE 按钮 6
JPF_BUTTON_PLAY 按钮 7
JP_XAXIS_MASK 水平位置的掩码
JP_YAXIS_MASK 垂直位置的掩码
华夏公益教科书