diff options
| author | TakaRikka <38417346+TakaRikka@users.noreply.github.com> | 2025-12-16 06:55:07 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-16 16:55:07 +0200 |
| commit | 8185d87f855baff0d55d0e3ffc1a3cbdcfc4b5e2 (patch) | |
| tree | 2a3c01f1a2a8b81de5a0748a5bcb187a97e7a114 /src/revolution/homebuttonLib/HBMController.cpp | |
| parent | c8104b6d62cc424318c7e0c44c92d94234bfef15 (diff) | |
copy homebuttonLib from oot-vc (#2960)
* initial copy of hbm from sdk_2009-12-11
* some more nw4hbm cleanup
* nw4hbm db mostly done
* nw4hbm snd copied from oot-vc
* nw4hbm ut copied
* nw4hbm lyt copied
* nw4hbm copied, mostly matching usa 1.0
* setup nw4hbm debug define
* fix HBMDataInfo struct
* add rvl sdk card lib
Diffstat (limited to 'src/revolution/homebuttonLib/HBMController.cpp')
| -rw-r--r-- | src/revolution/homebuttonLib/HBMController.cpp | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/src/revolution/homebuttonLib/HBMController.cpp b/src/revolution/homebuttonLib/HBMController.cpp new file mode 100644 index 0000000000..207ee57130 --- /dev/null +++ b/src/revolution/homebuttonLib/HBMController.cpp @@ -0,0 +1,356 @@ +#include "HBMController.h" + +namespace homebutton { + + bool Controller::sBatteryFlag[WPAD_MAX_CONTROLLERS]; + OSAlarm Controller::sAlarm[WPAD_MAX_CONTROLLERS]; + OSAlarm Controller::sAlarmSoundOff[WPAD_MAX_CONTROLLERS]; + Controller* Controller::sThis[WPAD_MAX_CONTROLLERS]; + bool Controller::sSetInfoAsync[WPAD_MAX_CONTROLLERS]; + RemoteSpk* Controller::sPInstance; + s32 Controller::lbl_8025DBBC; + + void Controller::wpadConnectCallback(s32 chan, s32 result) { + switch (result) { + case WPAD_ESUCCESS: + if (!sThis[chan]->mCallbackFlag) { + sThis[chan]->mOldExtensionCallback = + WPADSetExtensionCallback(chan, wpadExtensionCallback); + sThis[chan]->mCallbackFlag = true; + } + + WPADControlSpeaker(chan, WPAD_SPEAKER_DISABLE, NULL); + break; + + case WPAD_ENODEV: + WPADSetExtensionCallback(chan, sThis[chan]->mOldExtensionCallback); + sThis[chan]->mOldExtensionCallback = NULL; + sThis[chan]->mCallbackFlag = false; + sThis[chan]->mCheckSoundTimeFlag = false; + sThis[chan]->mCheckSoundIntervalFlag = false; + break; + } + + if (sThis[chan]->mOldConnectCallback) { + (*sThis[chan]->mOldConnectCallback)(chan, result); + } + } + + void Controller::wpadExtensionCallback(s32 chan, s32 result) { + switch (result) { + case WPAD_DEV_INITIALIZING: + sThis[chan]->soundOff(1000); + break; + } + + if (sThis[chan]->mOldExtensionCallback) { + (*sThis[chan]->mOldExtensionCallback)(chan, result); + } + } + + void Controller::soundOnCallback(OSAlarm* alm, OSContext*) { + int chan = (int)OSGetAlarmUserData(alm); + sThis[chan]->soundOn(); + } + + Controller::Controller(int chan, RemoteSpk* spk) { + mHBController.chan = chan; + mHBController.rumble = false; + mHBController.spVol = 1.0f; + + remotespk = spk; + mOldConnectCallback = NULL; + mOldExtensionCallback = NULL; + mCallbackFlag = false; + mSoundOffFlag = false; + + if (chan < WPAD_MAX_CONTROLLERS) { + sBatteryFlag[chan] = false; + OSCreateAlarm(&sAlarm[chan]); + OSCreateAlarm(&sAlarmSoundOff[chan]); + sThis[chan] = this; + } + } + + Controller::~Controller() { + OSCancelAlarm(&sAlarm[mHBController.chan]); + OSCancelAlarm(&sAlarmSoundOff[mHBController.chan]); + } + + void Controller::initCallback() { + u32 type; + + mOldConnectCallback = WPADSetConnectCallback(mHBController.chan, &wpadConnectCallback); + + switch (WPADProbe(mHBController.chan, &type)) { + case WPAD_ESUCCESS: + mOldExtensionCallback = + WPADSetExtensionCallback(mHBController.chan, &wpadExtensionCallback); + mCallbackFlag = true; + break; + case WPAD_ENODEV: + mCallbackFlag = false; + break; + } + } + + void Controller::clearCallback() { + WPADSetConnectCallback(mHBController.chan, mOldConnectCallback); + mOldConnectCallback = NULL; + + WPADSetExtensionCallback(mHBController.chan, mOldExtensionCallback); + mOldExtensionCallback = NULL; + } + + void Controller::setKpad(const HBMKPadData* con, bool updatePos) { + if (!con->kpad) { + return; + } + + if (updatePos) { + if (con->kpad->dev_type == WPAD_DEV_CLASSIC && con->use_devtype == WPAD_DEV_CLASSIC) { + mHBController.x = con->pos.x; + mHBController.y = con->pos.y; + } else { + mHBController.x = con->kpad->pos.x; + mHBController.y = con->kpad->pos.y; + } + } + + mHBController.trig = con->kpad->trig; + mHBController.hold = con->kpad->hold; + mHBController.release = con->kpad->release; + + if (con->kpad->dev_type == WPAD_DEV_CLASSIC) { + u32 h = con->kpad->ex_status.cl.hold; + u32 t = con->kpad->ex_status.cl.trig; + u32 r = con->kpad->ex_status.cl.release; + + if (h & WPAD_BUTTON_CL_A) { + mHBController.hold |= WPAD_BUTTON_A; + } + if (t & WPAD_BUTTON_CL_A) { + mHBController.trig |= WPAD_BUTTON_A; + } + if (r & WPAD_BUTTON_CL_A) { + mHBController.release |= WPAD_BUTTON_A; + } + + if (h & WPAD_BUTTON_CL_PLUS) { + mHBController.hold |= WPAD_BUTTON_PLUS; + } + if (t & WPAD_BUTTON_CL_PLUS) { + mHBController.trig |= WPAD_BUTTON_PLUS; + } + if (r & WPAD_BUTTON_CL_PLUS) { + mHBController.release |= WPAD_BUTTON_PLUS; + } + + if (h & WPAD_BUTTON_CL_MINUS) { + mHBController.hold |= WPAD_BUTTON_MINUS; + } + if (t & WPAD_BUTTON_CL_MINUS) { + mHBController.trig |= WPAD_BUTTON_MINUS; + } + if (r & WPAD_BUTTON_CL_MINUS) { + mHBController.release |= WPAD_BUTTON_MINUS; + } + + if (h & WPAD_BUTTON_CL_HOME) { + mHBController.hold |= WPAD_BUTTON_HOME; + } + if (t & WPAD_BUTTON_CL_HOME) { + mHBController.trig |= WPAD_BUTTON_HOME; + } + if (r & WPAD_BUTTON_CL_HOME) { + mHBController.release |= WPAD_BUTTON_HOME; + } + } + } + + void Controller::clrKpadButton() { + mHBController.trig = 0; + mHBController.hold = 0; + mHBController.release = 0; + } + + void Controller::setInValidPos() { + mHBController.x = -10000.0f; + mHBController.y = -10000.0f; + } + + int Controller::getChan() const { + return mHBController.chan; + } + + void Controller::connect() { + getRemoteSpk()->Connect(getChan()); + } + + void Controller::disconnect() { /* ... */ } + + void Controller::setSpeakerVol(f32 vol) { + mHBController.spVol = vol; + } + + f32 Controller::getSpeakerVol() const { + return mHBController.spVol; + } + + void Controller::playSound(nw4hbm::snd::SoundArchivePlayer* pSoundArchivePlayer, int id) { + if (!mSoundOffFlag) { + getRemoteSpk()->Play(getChan(), id, getSpeakerVol() * 10.0f); + + if (WPADIsSpeakerEnabled(getChan())) { + if (!mCheckSoundTimeFlag) { + mPlaySoundTime = OSGetTime(); + } + + mCheckSoundTimeFlag = true; + mCheckSoundIntervalFlag = false; + } + } + } + + bool Controller::isPlayingSound() const { + return getRemoteSpk()->isPlaying(getChan()); + } + + bool Controller::isPlayingSoundId(int id) const { + if (!isPlayingSound()) { + return false; + } + + if (!getRemoteSpk()->isPlayingId(getChan(), id)) { + return false; + } + + return true; + } + + void Controller::initSound() { + mCheckSoundTimeFlag = false; + mCheckSoundIntervalFlag = false; + } + + void Controller::updateSound() { + int chan = getChan(); + + if (!isPlayingSound()) { + if (mCheckSoundTimeFlag) { + if (!mCheckSoundIntervalFlag) { + mStopSoundTime = OSGetTime(); + mCheckSoundIntervalFlag = true; + } else { + OSTime time = OSGetTime(); + if (OSTicksToMilliseconds(time - mStopSoundTime) >= 1000) { + mCheckSoundTimeFlag = false; + mCheckSoundIntervalFlag = false; + } + } + } + + return; + } else { + if (mCheckSoundTimeFlag) { + mCheckSoundIntervalFlag = false; + + OSTime time = OSGetTime(); + if (OSTicksToMilliseconds(time - mPlaySoundTime) >= 480000) { + mCheckSoundTimeFlag = false; + mCheckSoundIntervalFlag = false; + soundOff(1000); + return; + } + } + + // Average radio sensitivity is 80 (see __wpadCalcRadioQuality) + if (!mSoundOffFlag && WPADGetRadioSensitivity(chan) <= 85) { + soundOff(1000); + } + } + } + + void Controller::soundOff(int msec) { + int chan = getChan(); + + if (!WPADIsSpeakerEnabled(chan)) { + return; + } + + WPADControlSpeaker(chan, WPAD_SPEAKER_MUTE, NULL); + + OSSetAlarmUserData(&sAlarmSoundOff[chan], (void*)chan); + OSCancelAlarm(&sAlarmSoundOff[chan]); + OSSetAlarm(&sAlarmSoundOff[chan], OSMillisecondsToTicks(msec), &soundOnCallback); + + mSoundOffFlag = true; + } + + void Controller::soundOn() { + int chan = getChan(); + + if (WPADIsSpeakerEnabled(chan)) { + WPADControlSpeaker(chan, WPAD_SPEAKER_UNMUTE, NULL); + } + + mSoundOffFlag = false; + } + + bool Controller::isPlayReady() const { + return getRemoteSpk()->isPlayReady(getChan()); + } + + HBController* Controller::getController() { + return &mHBController; + } + + void Controller::startMotor() { + if (getChan() < WPAD_MAX_CONTROLLERS && !isPlayingSound()) { + setRumble(); + WPADControlMotor(getChan(), WPAD_MOTOR_RUMBLE); + } + } + + void Controller::stopMotor() { + if (getChan() < WPAD_MAX_CONTROLLERS && isRumbling()) { + clrRumble(); + WPADControlMotor(getChan(), WPAD_MOTOR_STOP); + } + } + + s32 Controller::getInfoAsync(WPADInfo* info) { + if (getChan() >= WPAD_MAX_CONTROLLERS) { + return -2; + } + + if (isPlayingSound() || isRumbling()) { + return -2; + } + + return WPADGetInfoAsync(getChan(), info, &ControllerCallback); + } + + void Controller::ControllerCallback(s32 chan, s32 result) { + if (result == WPAD_ESUCCESS && chan < WPAD_MAX_CONTROLLERS) { + sBatteryFlag[chan] = true; + } + } + + bool Controller::getBatteryFlag() const { + if (getChan() >= WPAD_MAX_CONTROLLERS) { + return false; + } + + return sBatteryFlag[getChan()]; + } + + void Controller::clrBatteryFlag() { + if (getChan() >= WPAD_MAX_CONTROLLERS) { + return; + } + + sBatteryFlag[getChan()] = false; + } + +} // namespace homebutton |
