跳轉到內容

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 垂直位置的掩碼
華夏公益教科書