### Setup commands for OpenJoystickDriver Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/CONTRIBUTING.md Clones the repository, runs the setup script, and runs the check recipe. The dispatcher creates repository-local Python environments and may prompt to install missing Homebrew formulas in interactive terminals. ```bash git clone https://github.com/xsyetopz/OpenJoystickDriver.git cd OpenJoystickDriver ./Scripts/ojd setup just check ``` -------------------------------- ### Build and Install Development Operation Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/development/signing.md Command to initiate the build and installation process for development signing. ```bash ./Scripts/ojd build install dev ``` -------------------------------- ### Version conversion examples Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/pull-26.md Examples of how bundle_version_from_semver() encodes version tags into a single integer, which is invalid for kext versions. ```text 0.5.0-beta.1 -> 500001 0.5.0-beta.2 -> 500002 ``` -------------------------------- ### Install Xcode tools and clone OJD Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/controller-record.md Install the Xcode command-line tools and clone the OJD repository before probing. Run these commands in a terminal. ```bash xcode-select --install git clone https://github.com/xsyetopz/OpenJoystickDriver.git cd OpenJoystickDriver ``` -------------------------------- ### Prepare Signing Environment Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/development/tester-builds.md Install profiles and configure the local environment for signing. These scripts generate .env.dev and .env.release files which must not be committed. ```bash just signing-install-profiles just signing-configure ``` -------------------------------- ### Check Physical Output With Installed App Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/razer/wolverine-v2.md Generates a physical-output plan for the controller. Run each generated step individually and record the player indicator and rumble results. ```bash /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller output list ``` ```bash /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller output plan 5426 2601 ``` -------------------------------- ### Shell script: Inspect startup policy and probe runner Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/pull-27.md Executes commands to display startup policy implementation, probe runner setup, canonical target record, and resolver tests. ```shell printf '%s\n' '--- startup policy implementation ---' sed -n '1,70p' Sources/OpenJoystickDriverKit/Device/Pipeline/USBPipeline.swift printf '%s\n' '--- probe runner setup and transport use ---' sed -n '1,92p' Sources/OpenJoystickDriverHIDTool/ControllerRecordProbeRunner.swift printf '%s\n' '--- canonical target record ---' cat -n Sources/OpenJoystickDriverKit/Resources/Controllers/0e6f/0e6f-0401.json printf '%s\n' '--- resolver tests for missing output ---' rg -n -C 10 'discover\(|DiscoveredUSBTransport|missing|output|requirePreferredInterface' Tests/OpenJoystickDriverKitTests/Device Sources/OpenJoystickDriverKit/Device --glob '*.swift' ``` -------------------------------- ### USB pipe setup and handshake with input report loop (Objective-C) Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/issue-18.md Sets up USB pipes with fallback addresses, sends handshake packets (powerOn, ledOn, authDone), then loops reading input reports with deduplication and rumble control. Requires an existing IOUSBHostInterface and sendPacket helper. ```objective-c uint8_t inAddr = 0x82, outAddr = 0x02; IOUSBHostPipe *inPipe = [intf copyPipeWithAddress:inAddr error:&err]; IOUSBHostPipe *outPipe = [intf copyPipeWithAddress:outAddr error:&err]; if (!inPipe || !outPipe) { inAddr = 0x81; outAddr = 0x01; inPipe = [intf copyPipeWithAddress:inAddr error:&err]; outPipe = [intf copyPipeWithAddress:outAddr error:&err]; } if (!inPipe || !outPipe) { fprintf(stderr, "PIPES failed: %s\n", err.description.UTF8String); return 6; } printf("PIPES in=0x%02x out=0x%02x ok\n", inAddr, outAddr); // Startup sequence, sequence numbers as OJD sends them (1-based). uint8_t powerOn[] = {0x05, 0x20, 0x01, 0x01, 0x00}; uint8_t ledOn[] = {0x0a, 0x20, 0x02, 0x03, 0x00, 0x01, 0x14}; uint8_t authDone[] = {0x06, 0x20, 0x03, 0x02, 0x01, 0x00}; sendPacket(outPipe, powerOn, sizeof powerOn, "powerOn"); sendPacket(outPipe, ledOn, sizeof ledOn, "ledOn"); sendPacket(outPipe, authDone, sizeof authDone, "authDone"); printf("HANDSHAKE complete — press buttons now\n"); fflush(stdout); NSTimeInterval deadline = [NSDate timeIntervalSinceReferenceDate] + seconds; int rumbled = 0; uint64_t total = 0, inputReports = 0; uint8_t prev[64] = {0}; NSUInteger prevLen = 0; while ([NSDate timeIntervalSinceReferenceDate] < deadline) { NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate]; if (rumbled == 0 && now - t0 > seconds / 2) { uint8_t rb[] = {0x09, 0x00, 0x10, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x1d, 0x1d, 0xff, 0x00, 0x00}; sendPacket(outPipe, rb, sizeof rb, "rumbleBegin"); rumbled = 1; } if (rumbled == 1 && now - t0 > seconds / 2 + 2.0 && rumbled != 2) { uint8_t re[] = {0x09, 0x00, 0x11, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; sendPacket(outPipe, re, sizeof re, "rumbleEnd"); rumbled = 2; } NSMutableData *buf = [intf ioDataWithCapacity:64 error:nil]; NSUInteger got = 0; NSError *rerr = nil; BOOL ok = [inPipe sendIORequestWithData:buf bytesTransferred:&got completionTimeout:0 error:&rerr]; if (!ok || got == 0) continue; total++; const uint8_t *b = buf.bytes; if (b[0] == 0x20) inputReports++; // Dedupe: skip if identical to previous ignoring the sequence byte [2]. uint8_t cur[64]; memcpy(cur, b, got); if (got > 2) cur[2] = 0; if (got == prevLen && memcmp(cur, prev, got) == 0) continue; memcpy(prev, cur, got); prevLen = got; const char *tag = b[0] == 0x20 ? "RX input " : b[0] == 0x07 ? "RX xbox-btn" : b[0] == 0x02 ? "RX announce" : b[0] == 0x03 ? "RX keepalive" : "RX other"; hexdump(tag, b, got); } printf("SUMMARY packets=%llu input_reports=%llu\n", total, inputReports); return inputReports > 0 ? 0 : 7; } } ``` -------------------------------- ### Sample captured GIP packets from Nacon Revolution X Pro Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/issue-21.md Example packets captured from the controller after the startup sequence, showing the format of incoming data. The capture produced 56 packets and four normalized input events with zero parse errors. ```text 20 00 02 20 00 00 00 00 00 00 00 00 00 00 00 00 ... 02 20 55 1c d2 0f 89 66 ba 2a 00 00 85 32 34 06 ... 03 20 77 04 80 00 00 00 ``` -------------------------------- ### Run USBDriverKit Probe with --seconds 45 Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/xbox/1537.md Starts the USBDriverKit probe for 45 seconds with the controller connected directly by USB. After running, confirm that the controller stays poweredaaaa and that RECORD_HANDSHAKE and USB_RX packets succeed without failures. Requires quitting Steam, games, and controller utilities beforehand. ```bash ./Scripts/ojd diagnose record \ Sources/OpenJoystickDriverKit/Resources/Controllers/045e/045e-02d1.json \ --seconds 45 ``` -------------------------------- ### Startup-Output Ignore Helper Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/issue-22.md The existing logic in the beta.2 startup-output helper that fails to catch the .notFound error. ```swift case .inputOutput, .notSupported: return true ``` -------------------------------- ### Guide button virtual-key frames Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/issue-18.md Two frames representing the physical press and release of the guide button (0x07 virtual-key frames). ```text 07 20 01 02 01 5b ``` ```text 07 20 02 02 00 5b ``` -------------------------------- ### Generate a test plan with OpenJoystickDriver CLI Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/physical-output.md Lists connected devices and requests a test plan using decimal VID and PID. Replace the example GameSir G7 SE values with the decimal identifiers printed by `controller output list`. Append `--device ` to `plan` and output commands when identical models are connected, as ambiguous commands are rejected. ```bash vid=13623 pid=4112 /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller output list /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller output plan "$vid" "$pid" ``` -------------------------------- ### OpenJoystickDriver CLI command families Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/development/cli-and-runtime.md CLI command families for the headless expert interface. Use with the installed signed executable or `swift run OpenJoystickDriver` / `.build/debug/OpenJoystickDriver`. The server checks user, signing identifier, and team identifier; if repository sources are newer than the installed executable, the command stops and asks for a new install. ```text status [--json] controller list|state|packets|watch|output|disconnect|disconnect-wireless|resume ... map ... app status|login enable|disable|logs ... extension status|enable|disable permissions ... compat show|set |reset test [positive-seconds] diagnose [runtime|catalog|report] update check ... ``` -------------------------------- ### Generate Support Report Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/development/tester-builds.md Command for testers to generate a support report after installing and running the application. ```bash /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver \ --headless diagnose report ``` -------------------------------- ### List HID devices with OpenJoystickDriverHIDTool Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/steam-controller.md Run from the repository root to list HID devices. Paste every VID:0x28de line; if none appear, report that and paste nearby keyboard, mouse, or game controller lines present only while connected. ```bash swift run OpenJoystickDriverHIDTool --list ``` -------------------------------- ### Sample raw USB report Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/external/OpenJoystickDriver/issue-22.md A single 20-byte report captured from endpoint 0x81, shown as an example of the received data. ```text 00 14 00 00 00 00 35 77 e9 c2 77 eb 22 dc 00 00 00 00 00 00 ``` -------------------------------- ### Create Tester DMG Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/development/tester-builds.md Build, sign, notarize, and package the application into a DMG for testing. ```bash just package-tester ``` -------------------------------- ### Query controller state headlessly Source: https://github.com/xsyetopz/openjoystickdriver/blob/main/docs/testing/catalina-testkit.md Start the headless CLI to query controller state when the GUI window is unavailable. Note that automatic launch at login is not supported on Catalina. ```bash /Applications/OpenJoystickDriver.app/Contents/MacOS/OpenJoystickDriver --headless controller state ```