David Rimer
/
Gigatron_Emulator
A small emulator for the gigatron created for the STM32F746G-DISCO and an NES wii controller
WiiClassicControllerReader/WiiClassicControllerReader.cpp
- Committer:
- davidr99
- Date:
- 2020-03-05
- Revision:
- 1:4c1f3d32fceb
File content as of revision 1:4c1f3d32fceb:
/* * WiiClassicControllerReader. A program allowing the output of one or two * Wii Classic Controllers to be read via I2C and decoded for use, using the mbed * microcontroller and its associated libraries. * * Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source * game console <http://www.mbedgc.com>. Based on the original code for * the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. * * This file is part of WiiClassicControllerReader. * * WiiClassicControllerReader is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * WiiClassicControllerReader is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. */ #include "WiiClassicControllerReader.h" // constructor WiiClassicControllerReader::WiiClassicControllerReader(PinName sda, PinName scl) : controllerPort(sda, scl), ljoyX(0), ljoyY(0), rjoyX(0), rjoyY(0), buttonX(0), buttonY(0), buttonA(0), buttonB(0), buttonZL(0), buttonZR(0), buttonLT(0), buttonRT(0), buttonLC(0), buttonRC(0), buttonHOME(0), buttonSELECT(0), buttonSTART(0), buttonDU(0), buttonDD(0), buttonDL(0), buttonDR(0), controllerInit(false) { } void WiiClassicControllerReader::RequestRead() { // don't expect client to remember to send an init to the nunchuck // so do it for them here if (!controllerInit) { controllerInit = ControllerInit(); } if (controllerInit) // don't start reading if init failed { if (ControllerRead()) { // only decode successful reads ControllerDecode(); } } } bool WiiClassicControllerReader::ControllerInit() { bool success = false; const BYTE cmd[] = {CONTROLLER_REGADDR, 0x00}; if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) success = true; return success; } bool WiiClassicControllerReader::ControllerRead() { bool success = false; // write the address we want to read from const BYTE cmd[] = {0x00}; if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) { // the Wii Classic Controller is non-standard I2C // and can't manage setting the read address and immediately supplying the data // so wait a bit wait(I2C_READ_DELAY); if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf))) success = true; } return success; } bool WiiClassicControllerReader::ControllerWriteCmd() { bool success = false; // write the address we want to read from const BYTE cmd[] = {0x00}; if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) { success = true; } return success; } bool WiiClassicControllerReader::ControllerReadCmd() { bool success = false; if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf))) { success = true; } return success; } void WiiClassicControllerReader::ControllerDecode() { ljoyX = (int)readBuf[0] & MASK_LX; ljoyY = (int)readBuf[1] & MASK_LY; rjoyY = (int)readBuf[2] & MASK_RY; buttonRT = (int)readBuf[3] & MASK_RT; buttonRC = (int)readBuf[4] & MASK_RC_DL; buttonSTART = (int)readBuf[4] & MASK_BSTART_ZR; buttonHOME = (int)readBuf[4] & MASK_BHOME_X; buttonSELECT = (int)readBuf[4] & MASK_BSELECT_A; buttonLC = (int)readBuf[4] & MASK_LC_Y; buttonDD = (int)readBuf[4] & MASK_BDD_B; buttonDR = (int)readBuf[4] & MASK_BDR_ZL; buttonDU = (int)readBuf[5] & MASK_BDU; buttonDL = (int)readBuf[5] & MASK_RC_DL; buttonZR = (int)readBuf[5] & MASK_BSTART_ZR; buttonX = (int)readBuf[5] & MASK_BHOME_X; buttonA = (int)readBuf[5] & MASK_BSELECT_A; buttonY = (int)readBuf[5] & MASK_LC_Y; buttonB = (int)readBuf[5] & MASK_BDD_B; buttonZL = (int)readBuf[5] & MASK_BDR_ZL; // the RjoyX axis and LT values are really 5 bit values // so shift the 2 bit values read from the controller // 3 bits to the right rjoyX = ( (int)readBuf[0] & MASK_RX34 ) << 3; buttonLT = ( (int)readBuf[2] & MASK_LT34 ) << 3; // and for each value add bit 2, bit 1, and bit 0 // as required if (readBuf[2] & MASK_BDR_ZL) rjoyX += 1; if (readBuf[1] & MASK_BDD_B) rjoyX += 2; if (readBuf[1] & MASK_BDR_ZL) rjoyX += 4; if (readBuf[3] & MASK_LC_Y) buttonLT += 1; if (readBuf[3] & MASK_BDD_B) buttonLT += 2; if (readBuf[3] & MASK_BDR_ZL) buttonLT += 4; }