게임 컨트롤러 라이브러리 사용

게임 컨트롤러 라이브러리를 사용하여 게임에 게임 컨트롤러 지원을 추가하려면 다음 함수를 사용하세요.

게임 컨트롤러 라이브러리 초기화 및 삭제

Paddleboat_init 함수를 사용하여 게임 컨트롤러 라이브러리를 초기화합니다.

Paddleboat_ErrorCode Paddleboat_init(JNIEnv *env, jobject jcontext)

Paddleboat_init는 다음 두 가지 매개변수를 사용합니다.

  • 현재 스레드에 연결된 JNIEnv에 대한 포인터입니다.
  • Context 파생 클래스에 관한 jobject JNI 객체 참조입니다. Activity, NativeActivity, GameActivity를 포함하되 이에 국한되지 않는 모든 Context 파생 클래스 객체가 유효합니다.

Paddleboat_init는 초기화가 성공하면 PADDLEBOAT_NO_ERROR를 반환하고, 그렇지 않으면 해당하는 오류 코드가 반환됩니다.

Paddleboat_isInitialized를 사용하여 게임 컨트롤러 라이브러리가 성공적으로 초기화되었는지 확인할 수 있습니다. 부울 값을 반환합니다. true인 경우 API를 사용할 수 있습니다.

bool Paddleboat_isInitialized()

애플리케이션을 종료하기 전에 Paddleboat_destroy 함수를 사용하여 게임 컨트롤러 라이브러리를 종료합니다. 이 함수는 현재 스레드에 연결된 JNIEnv에 대한 포인터를 단일 매개변수로 사용합니다. Paddleboat_initPaddleboat_destroy 후에 다시 호출될 수 있습니다.

void Paddleboat_destroy(JNIEnv *env)

라이브러리에 수명 주기 이벤트 알림

게임 컨트롤러 라이브러리에 활동 수명 주기 onStoponStart 이벤트를 알려야 합니다. 이벤트 중지 및 시작 처리 코드에서 Paddleboat_onStopPaddleboat_onStart 함수를 호출합니다. 두 함수는 모두 현재 스레드에 연결된 JNIEnv를 가리키는 포인터 하나인 단일 매개변수를 사용합니다.

void Paddleboat_onStop(JNIEnv *env)
void Paddleboat_onStart(JNIEnv *env)

컨트롤러 상태 콜백 등록 또는 삭제

게임 컨트롤러 라이브러리는 컨트롤러 상태 콜백을 사용하여 컨트롤러의 연결 또는 연결 해제 시 이를 게임에 알립니다. 한 번에 하나의 컨트롤러 상태 콜백만 지원합니다.

  • 컨트롤러 상태 콜백을 등록하거나 이전에 등록된 콜백을 새 콜백 함수로 바꾸려면 Paddleboat_setControllerStatusCallback 함수를 호출합니다.
  • 현재 등록된 콜백을 삭제하려면 NULL 또는 nullptr를 전달합니다.
  • userData 매개변수는 사용자 정의 데이터를 위한 선택적 포인터입니다. userData 매개변수는 콜백 함수에 전달됩니다. 이 포인터는 이후 Paddleboat_setControllerStatusCallback을 호출할 때까지 내부적으로 유지됩니다.
void Paddleboat_setControllerStatusCallback(Paddleboat_ControllerStatusCallback
  statusCallback, void *userData)

콜백 함수의 함수 서명은 다음과 같습니다.

typedef void (*Paddleboat_ControllerStatusCallback)(
  const int32_t controllerIndex,
  const Paddleboat_ControllerStatus controllerStatus,
  void *userData)
매개변수 설명
controllerIndex 콜백을 시작한 컨트롤러의 색인으로, 0에서
PADDLEBOAT_MAX_CONTROLLERS - 1 사이의 값입니다.
controllerStatus PADDLEBOAT_CONTROLLER_JUST_CONNECTED 또는
PADDLEBOAT_CONTROLLER_JUST_DISCONNECTED의 열거형 값입니다.
userData Paddleboat_setControllerStatusCallback의 마지막 호출로 지정된 사용자 정의 데이터에 대한 선택적 포인터(NULL일 수 있음)입니다.

게임 컨트롤러 라이브러리 업데이트 함수 호출

게임 컨트롤러 라이브러리 업데이트 함수 Paddleboat_update는 게임 프레임당 한 번 호출되어야 하며, 프레임 시작 근처에 호출되는 것이 좋습니다. 이 함수는 단일 매개변수, 즉 현재 스레드에 연결된 JNIEnv를 가리키는 포인터를 사용합니다.

void Paddleboat_update(JNIEnv *env)

이벤트 처리

입력 이벤트를 수신할 때 게임은 검사를 위해 이를 게임 컨트롤러 라이브러리로 전달해야 합니다. 게임 컨트롤러 라이브러리는 입력 이벤트가 관리 기기 중 하나와 연결되어 있는지 평가합니다. 관리 기기의 이벤트는 처리 및 소비됩니다.

게임 컨트롤러 라이브러리는 두 가지 유형의 AInputEventsGameActivity 입력 이벤트를 지원합니다.

AInputEvent 처리

게임은 이벤트 처리 코드로부터 Paddleboat_processInputEvent를 호출하여 AInputEvents를 전달해야 합니다.

int32_t Paddleboat_processInputEvent(const AInputEvent *event)

이벤트가 무시되면 Paddleboat_processInputEvent에서 0을 반환하고, 게임 컨트롤러 라이브러리에서 이벤트를 처리 및 소비한 경우 1을 반환합니다.

GameActivity 이벤트 처리

게임에서 GameActivity를 사용하는 경우 이벤트 처리 코드에서 Paddleboat_processGameActivityKeyInputEvent 또는 Paddleboat_processGameActivityMotionInputEvent를 호출하여 GameActivityKeyEventGameActivityMotionEvent 이벤트를 전달합니다.

int32_t Paddleboat_processGameActivityKeyInputEvent(const void *event,
                                                    const size_t eventSize)
int32_t Paddleboat_processGameActivityMotionInputEvent(const void *event,
                                                       const size_t eventSize)
매개변수 설명
event 호출되는 함수에 따른 GameActivityKeyEvent 또는 GameActivityMotionEvent 구조에 대한 포인터.
eventSize event 매개변수에 전달된 이벤트 구조의 크기(바이트).

이벤트가 무시되면 두 함수 모두 0을 반환하고, 이벤트가 게임 컨트롤러 라이브러리에서 처리 및 소비되면 1을 반환합니다.

GameActivity를 사용하려면 GameActivityPointerAxes_enableAxis 함수를 사용하여 활성 모션 축을 지정해야 합니다. Paddleboat_getActiveAxisMask 호출은 연결된 컨트롤러에서 사용하는 현재 활성 모션 축의 비트마스크를 반환합니다.

uint64_t Paddleboat_getActiveAxisMask()

이를 처리하는 방법의 예는 GameActivity를 사용하는 게임 컨트롤러 라이브러리 샘플을 참조하세요. 샘플은 활성 축 마스크를 폴링하고 새 축이 사용되면 GameActivity에 알립니다. 이는 NativeEngine::CheckForNewAxis() 함수에서 구현됩니다.

void NativeEngine::CheckForNewAxis() {
    // Tell GameActivity about any new axis ids so it reports
    // their events
    const uint64_t activeAxisIds = Paddleboat_getActiveAxisMask();
    uint64_t newAxisIds = activeAxisIds ^ mActiveAxisIds;
    if (newAxisIds != 0) {
        mActiveAxisIds = activeAxisIds;
        int32_t currentAxisId = 0;
        while(newAxisIds != 0) {
            if ((newAxisIds & 1) != 0) {
                LOGD("Enable Axis: %d", currentAxisId);
                GameActivityPointerAxes_enableAxis(currentAxisId);
            }
            ++currentAxisId;
            newAxisIds >>= 1;
        }
    }
}

컨트롤러 읽기

게임 컨트롤러 라이브러리는 색인 값을 사용하여 특정 컨트롤러를 참조합니다. 유효한 색인 값의 범위는 0에서 PADDLEBOAT_MAX_CONTROLLERS - 1입니다. Paddleboat_getControllerStatus 함수는 지정된 컨트롤러 색인의 상태를 확인합니다.

Paddleboat_ControllerStatus Paddleboat_getControllerStatus(
  const int32_t controllerIndex)

연결된 컨트롤러에서 정보를 읽는 데 사용하는 세 가지 함수가 있습니다.

컨트롤러 이름

Paddleboat_getControllerName function은 컨트롤러 색인과 버퍼 사이즈라는 두 가지 입력 매개변수와 컨트롤러 이름 문자열을 저장할 버퍼에 대한 포인터를 사용합니다. 이름 문자열은 UTF-8 인코딩을 사용하여 C 문자열로 형식이 지정됩니다. 기기 이름은 InputDevice.getName()을 사용하여 내부적으로 가져옵니다.

Paddleboat_getControllerName에서 이름을 성공적으로 검색하면 PADDLEBOAT_NO_ERROR가 반환되고, 그렇지 않으면 해당하는 오류 코드가 반환됩니다.

Paddleboat_ErrorCode Paddleboat_getControllerName(const int32_t controllerIndex,
                                                  const size_t bufferSize,
                                                  char *controllerName);
매개변수 설명
controllerIndex 콜백을 시작한 컨트롤러의 색인으로, 0에서
PADDLEBOAT_MAX_CONTROLLERS - 1 사이의 값입니다.
bufferSize controllerName에서 전달한 버퍼의 크기(바이트 단위)로, 필요한 경우 이름 문자열이 버퍼에 맞춰 잘립니다.
controllerName 컨트롤러 이름을 저장할 bufferSize 바이트의 버퍼에 대한 포인터로, 이름은 UTF-8 인코딩을 사용하여 C 문자열로 저장됩니다.

컨트롤러 기기 정보

Paddleboat_getControllerInfo function은 두 가지 입력 매개변수인 컨트롤러 색인 및 Paddleboat_Controller_Info 구조를 가리키는 포인터를 사용합니다.

Paddleboat_Controller_Info에 데이터가 채워지면 Paddleboat_getControllerInfoPADDLEBOAT_NO_ERROR를 반환합니다. 그렇지 않으면 해당하는 오류 코드가 반환됩니다.

Paddleboat_ErrorCode Paddleboat_getControllerInfo(const int32_t controllerIndex,
  Paddleboat_Controller_Info *controllerInfo)

Paddleboat_Controller_Info 구조는 컨트롤러에 대한 기기별 정보를 포함합니다.

typedef struct Paddleboat_Controller_Info {
    uint32_t controllerFlags;
    int32_t controllerNumber;
    int32_t vendorId;
    int32_t productId;
    int32_t deviceId;
    Paddleboat_Controller_Thumbstick_Precision leftStickPrecision;
    Paddleboat_Controller_Thumbstick_Precision rightStickPrecision;
} Paddleboat_Controller_Info;

typedef struct Paddleboat_Controller_Thumbstick_Precision {
    float stickFlatX;
    float stickFlatY;
    float stickFuzzX;
    float stickFuzzY;
} Paddleboat_Controller_Thumbstick_Precision;

여러 구조 멤버가 컨트롤러와 연결된 InputDevice에서 가져온 값으로 채워집니다.

controllerNumber    -   InputDevice.getControllerNumber()
vendorId              - InputDevice.getVendorId()
productId             - InputDevice.getProductId()
deviceId              - InputDevice.getId()
  • stickFlat 값은 평평한 중앙 위치의 범위를 나타냅니다. 이 값은 자체 센터링 기기에서 주로 기본적인 중앙 '통신 사각지대'를 계산하는 데 유용합니다.
  • stickFuzz 값은 노이즈 및 기기 민감도 제한으로 인해 현재 값이 실제 값과 얼마나 차이가 나게 될지 나타내는 오류 허용 오차입니다.

두 값 모두 각 차원에서 최대 1.0의 축 값으로 정규화됩니다.

controllerFlags 멤버에는 개별 비트마스크된 플래그와 멀티 비트 조합 값의 조합이 포함되어 있습니다.

PADDLEBOAT_CONTROLLER_LAYOUT_MASKcontrollerFlags의 논리적 AND를 수행하면 Paddleboat_ControllerButtonLayout 열거형으로 캐스팅될 수 있는 값이 생성됩니다. 이 열거형은 컨트롤러에서 사용하는 버튼 아이콘과 레이아웃을 지정합니다.

enum Paddleboat_ControllerButtonLayout {
    //  Y
    // X B
    //  A
    PADDLEBOAT_CONTROLLER_LAYOUT_STANDARD = 0,
    //  △
    // □ ○
    //  x
    PADDLEBOAT_CONTROLLER_LAYOUT_SHAPES = 1,
    //  X
    // Y A
    //  B
    PADDLEBOAT_CONTROLLER_LAYOUT_REVERSE = 2,
    // X Y R1 L1
    // A B R2 L2
    PADDLEBOAT_CONTROLLER_LAYOUT_ARCADE_STICK = 3,
    PADDLEBOAT_CONTROLLER_LAYOUT_MASK = 3
};

다음 상수는 기능 비트를 정의합니다. 컨트롤러가 특정 기능을 지원하는지 확인하려면 controllerFlags에 상응하는 상수의 논리적 AND를 실행합니다. 0이 아닌 결과는 기능이 컨트롤러에서 지원함을 의미합니다.

PADDLEBOAT_CONTROLLER_FLAG_TOUCHPAD

이 플래그 비트가 설정되면 컨트롤러에 통합된 터치패드가 있습니다. 터치패드를 누르면 컨트롤러가 Paddleboat_Controller_Data.buttonsDown 필드에 PADDLEBOAT_BUTTON_TOUCHPAD 비트를 설정합니다.

PADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE

이 플래그 비트가 설정되면 컨트롤러가 포인터 기기를 에뮬레이션합니다. Paddleboat_Controller_Data 구조의 virtualPointer 멤버는 가상 포인터의 현재 좌표로 채워집니다.

컨트롤러 데이터

Paddleboat_getControllerData 함수에서는 컨트롤러 색인 및 Paddleboat_Controller_Data 구조에 대한 포인터라는 두 가지 입력 매개변수를 사용합니다. Paddleboat_Controller_Data에 데이터가 채워지면 Paddleboat_getControllerInfoPADDLEBOAT_NO_ERROR를 반환합니다. 그렇지 않으면 적절한 오류 코드가 반환됩니다.

Paddleboat_ErrorCode Paddleboat_getControllerData(const int32_t controllerIndex,
  Paddleboat_Controller_Data *controllerData)

Paddleboat_Controller_Data 구조에는 컨트롤러의 현재 컨트롤 입력 값이 포함됩니다.

typedef struct Paddleboat_Controller_Data {
    uint64_t timestamp;
    uint32_t buttonsDown;
    Paddleboat_Controller_Thumbstick leftStick;
    Paddleboat_Controller_Thumbstick rightStick;
    float triggerL1;
    float triggerL2;
    float triggerR1;
    float triggerR2;
    Paddleboat_Controller_Pointer virtualPointer;
} Paddleboat_Controller_Data;

typedef struct Paddleboat_Controller_Pointer {
    float pointerX;
    float pointerY;
} Paddleboat_Controller_Pointer;

typedef struct Paddleboat_Controller_Thumbstick {
    float stickX;
    float stickY;
} Paddleboat_Controller_Thumbstick;

값 범위

입력 유형 값 범위
섬스틱 축 -1.0에서 1.0
트리거 0.0에서 1.0까지
가상 포인터 0.0에서 창 너비/높이(픽셀)

구조 세부정보

구조 멤버 설명
buttonsDown 버튼당 비트 비트필드 배열으로, 버튼 비트마스크 상수는 paddleboat.h 헤더 파일에서 정의되며 PADDLEBOAT_BUTTON_으로 시작합니다.
timestamp. 가장 최근의 컨트롤러 입력 이벤트의 타임스탬프로, 타임스탬프는 시계 에포크 이후의 마이크로초입니다.
virtualPointer 가상 포인터 위치로, controllerFlagsPADDLEBOAT_CONTROLLER_FLAG_VIRTUAL_MOUSE 플래그가 설정된 경우에만 유효하고 그렇지 않으면 0.0, 0.0이 됩니다.