void Output(int chan, u8 rumble_command) { if (!UseAdapter() || !s_detected || !s_fd) return; // Skip over rumble commands if it has not changed or the controller is wireless if (rumble_command != s_controller_rumble[chan] && s_controller_type[chan] != ControllerTypes::CONTROLLER_WIRELESS) { s_controller_rumble[chan] = rumble_command; unsigned char rumble[5] = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3] }; { std::lock_guard<std::mutex> lk(s_write_mutex); memcpy(s_controller_write_payload, rumble, 5); s_controller_write_payload_size.store(5); } s_write_happened.Set(); } }
void Init() { if (s_fd) return; if (Core::GetState() != Core::State::Uninitialized) { if ((CoreTiming::GetTicks() - s_last_init) < SystemTimers::GetTicksPerSecond()) return; s_last_init = CoreTiming::GetTicks(); } JNIEnv* env; g_java_vm->AttachCurrentThread(&env, NULL); jclass adapter_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Java_GCAdapter"); s_adapter_class = reinterpret_cast<jclass>(env->NewGlobalRef(adapter_class)); if (UseAdapter()) StartScanThread(); }
GCPadStatus Input(int chan) { if (!UseAdapter() || !s_detected || !s_fd) return {}; int payload_size = 0; std::array<u8, 37> controller_payload_copy; { std::lock_guard<std::mutex> lk(s_read_mutex); controller_payload_copy = s_controller_payload; payload_size = s_controller_payload_size.load(); } GCPadStatus pad = {}; if (payload_size != controller_payload_copy.size()) { ERROR_LOG(SERIALINTERFACE, "error reading payload (size: %d, type: %02x)", payload_size, controller_payload_copy[0]); Reset(); } else { bool get_origin = false; u8 type = controller_payload_copy[1 + (9 * chan)] >> 4; if (type != ControllerTypes::CONTROLLER_NONE && s_controller_type[chan] == ControllerTypes::CONTROLLER_NONE) { ERROR_LOG(SERIALINTERFACE, "New device connected to Port %d of Type: %02x", chan + 1, controller_payload_copy[1 + (9 * chan)]); get_origin = true; } s_controller_type[chan] = type; if (s_controller_type[chan] != ControllerTypes::CONTROLLER_NONE) { u8 b1 = controller_payload_copy[1 + (9 * chan) + 1]; u8 b2 = controller_payload_copy[1 + (9 * chan) + 2]; if (b1 & (1 << 0)) pad.button |= PAD_BUTTON_A; if (b1 & (1 << 1)) pad.button |= PAD_BUTTON_B; if (b1 & (1 << 2)) pad.button |= PAD_BUTTON_X; if (b1 & (1 << 3)) pad.button |= PAD_BUTTON_Y; if (b1 & (1 << 4)) pad.button |= PAD_BUTTON_LEFT; if (b1 & (1 << 5)) pad.button |= PAD_BUTTON_RIGHT; if (b1 & (1 << 6)) pad.button |= PAD_BUTTON_DOWN; if (b1 & (1 << 7)) pad.button |= PAD_BUTTON_UP; if (b2 & (1 << 0)) pad.button |= PAD_BUTTON_START; if (b2 & (1 << 1)) pad.button |= PAD_TRIGGER_Z; if (b2 & (1 << 2)) pad.button |= PAD_TRIGGER_R; if (b2 & (1 << 3)) pad.button |= PAD_TRIGGER_L; if (get_origin) pad.button |= PAD_GET_ORIGIN; pad.stickX = controller_payload_copy[1 + (9 * chan) + 3]; pad.stickY = controller_payload_copy[1 + (9 * chan) + 4]; pad.substickX = controller_payload_copy[1 + (9 * chan) + 5]; pad.substickY = controller_payload_copy[1 + (9 * chan) + 6]; pad.triggerLeft = controller_payload_copy[1 + (9 * chan) + 7]; pad.triggerRight = controller_payload_copy[1 + (9 * chan) + 8]; } else { pad.button = PAD_ERR_STATUS; } } return pad; }