mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-18 15:21:50 +01:00
189 lines
4.0 KiB
C
189 lines
4.0 KiB
C
|
/*
|
||
|
* Copyright (C) 2017 FIX94
|
||
|
*
|
||
|
* This software may be modified and distributed under the terms
|
||
|
* of the MIT license. See the LICENSE file for details.
|
||
|
*/
|
||
|
#include <gccore.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include "wiidrc.h"
|
||
|
|
||
|
struct WiiDRCStat {
|
||
|
s16 xAxisLmid;
|
||
|
s16 xAxisRmid;
|
||
|
s16 yAxisLmid;
|
||
|
s16 yAxisRmid;
|
||
|
};
|
||
|
|
||
|
struct WiiDRCButtons {
|
||
|
u32 up;
|
||
|
u32 down;
|
||
|
u32 state;
|
||
|
};
|
||
|
|
||
|
static struct WiiDRCStat __WiiDRC_Status;
|
||
|
static struct WiiDRCData __WiiDRC_PadData;
|
||
|
static struct WiiDRCButtons __WiiDRC_PadButtons;
|
||
|
static bool __WiiDRC_ShutdownRequested;
|
||
|
|
||
|
static u32 __WiiDRC_Inited = 0;
|
||
|
static u8 *__WiiDRC_I2CBuf = NULL;
|
||
|
static u8 *__WiiDRC_DRCStateBuf = NULL;
|
||
|
|
||
|
static bool __WiiDRC_SetI2CBuf()
|
||
|
{
|
||
|
DCInvalidateRange((void*)0x938B2964, 4);
|
||
|
if(*(vu32*)0x938B2964 == 0x138BB004) //r569
|
||
|
{
|
||
|
__WiiDRC_I2CBuf = (u8*)0x938BB004;
|
||
|
return true;
|
||
|
}
|
||
|
DCInvalidateRange((void*)0x938B2564, 4);
|
||
|
if(*(vu32*)0x938B2564 == 0x138BB004) //r570
|
||
|
{
|
||
|
__WiiDRC_I2CBuf = (u8*)0x938BB004;
|
||
|
return true;
|
||
|
}
|
||
|
else if(*(vu32*)0x938B2564 == 0x138BA004) //r590
|
||
|
{
|
||
|
__WiiDRC_I2CBuf = (u8*)0x938BA004;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
static bool __WiiDRC_SetDRCStateBuf()
|
||
|
{
|
||
|
//TODO r569
|
||
|
DCInvalidateRange((void*)0x938B563C, 4);
|
||
|
if(*(vu32*)0x938B563C == 0x138BE770) //r570
|
||
|
{
|
||
|
__WiiDRC_DRCStateBuf = (u8*)0x938BE770;
|
||
|
return true;
|
||
|
}
|
||
|
DCInvalidateRange((void*)0x938B5724, 4);
|
||
|
if(*(vu32*)0x938B5724 == 0x138BD770) //r590
|
||
|
{
|
||
|
__WiiDRC_DRCStateBuf = (u8*)0x938BD770;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_Init()
|
||
|
{
|
||
|
if(__WiiDRC_Inited == 1)
|
||
|
return false;
|
||
|
if(!__WiiDRC_SetI2CBuf())
|
||
|
return false;
|
||
|
//can fail on r569 for now
|
||
|
__WiiDRC_SetDRCStateBuf();
|
||
|
|
||
|
__WiiDRC_Inited = 1;
|
||
|
|
||
|
WiiDRC_Recalibrate(); //sets up __WiiDRC_Status
|
||
|
memset(&__WiiDRC_PadData,0,sizeof(struct WiiDRCData));
|
||
|
memset(&__WiiDRC_PadButtons,0,sizeof(struct WiiDRCButtons));
|
||
|
__WiiDRC_ShutdownRequested = false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_Inited()
|
||
|
{
|
||
|
return !!__WiiDRC_Inited;
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_Recalibrate()
|
||
|
{
|
||
|
if(__WiiDRC_Inited == 0)
|
||
|
return false;
|
||
|
|
||
|
DCInvalidateRange(__WiiDRC_I2CBuf,9);
|
||
|
__WiiDRC_Status.xAxisLmid = (s8)(__WiiDRC_I2CBuf[4]-0x80);
|
||
|
__WiiDRC_Status.yAxisLmid = (s8)(__WiiDRC_I2CBuf[5]-0x80);
|
||
|
__WiiDRC_Status.xAxisRmid = (s8)(__WiiDRC_I2CBuf[6]-0x80);
|
||
|
__WiiDRC_Status.yAxisRmid = (s8)(__WiiDRC_I2CBuf[7]-0x80);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_ScanPads()
|
||
|
{
|
||
|
if(__WiiDRC_Inited == 0)
|
||
|
return false;
|
||
|
|
||
|
DCInvalidateRange(__WiiDRC_I2CBuf,9);
|
||
|
__WiiDRC_ShutdownRequested = !!(__WiiDRC_I2CBuf[1]&0x80);
|
||
|
__WiiDRC_PadData.button = (__WiiDRC_I2CBuf[2]<<8) | (__WiiDRC_I2CBuf[3]);
|
||
|
__WiiDRC_PadData.xAxisL = ((s8)(__WiiDRC_I2CBuf[4]-0x80)) - __WiiDRC_Status.xAxisLmid;
|
||
|
__WiiDRC_PadData.yAxisL = ((s8)(__WiiDRC_I2CBuf[5]-0x80)) - __WiiDRC_Status.yAxisLmid;
|
||
|
__WiiDRC_PadData.xAxisR = ((s8)(__WiiDRC_I2CBuf[6]-0x80)) - __WiiDRC_Status.xAxisRmid;
|
||
|
__WiiDRC_PadData.yAxisR = ((s8)(__WiiDRC_I2CBuf[7]-0x80)) - __WiiDRC_Status.yAxisRmid;
|
||
|
__WiiDRC_PadData.extra = __WiiDRC_I2CBuf[8];
|
||
|
__WiiDRC_PadData.battery = (__WiiDRC_PadData.extra>>1)&7;
|
||
|
|
||
|
u16 newstate, oldstate;
|
||
|
|
||
|
newstate = __WiiDRC_PadData.button;
|
||
|
oldstate = __WiiDRC_PadButtons.state;
|
||
|
__WiiDRC_PadButtons.state = newstate;
|
||
|
__WiiDRC_PadButtons.up = oldstate & ~newstate;
|
||
|
__WiiDRC_PadButtons.down = newstate & (newstate ^ oldstate);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_Connected()
|
||
|
{
|
||
|
if(__WiiDRC_DRCStateBuf)
|
||
|
{
|
||
|
DCInvalidateRange(__WiiDRC_DRCStateBuf, 4);
|
||
|
return !!(*(vu32*)__WiiDRC_DRCStateBuf);
|
||
|
}
|
||
|
return true; //default connect
|
||
|
}
|
||
|
|
||
|
bool WiiDRC_ShutdownRequested()
|
||
|
{
|
||
|
return __WiiDRC_ShutdownRequested;
|
||
|
}
|
||
|
|
||
|
const u8 *WiiDRC_GetRawI2CAddr()
|
||
|
{
|
||
|
return __WiiDRC_I2CBuf;
|
||
|
}
|
||
|
const struct WiiDRCData *WiiDRC_Data()
|
||
|
{
|
||
|
return &__WiiDRC_PadData;
|
||
|
}
|
||
|
u32 WiiDRC_ButtonsUp()
|
||
|
{
|
||
|
return __WiiDRC_PadButtons.up;
|
||
|
}
|
||
|
u32 WiiDRC_ButtonsDown()
|
||
|
{
|
||
|
return __WiiDRC_PadButtons.down;
|
||
|
}
|
||
|
u32 WiiDRC_ButtonsHeld()
|
||
|
{
|
||
|
return __WiiDRC_PadButtons.state;
|
||
|
}
|
||
|
s16 WiiDRC_lStickX()
|
||
|
{
|
||
|
return __WiiDRC_PadData.xAxisL;
|
||
|
}
|
||
|
s16 WiiDRC_lStickY()
|
||
|
{
|
||
|
return __WiiDRC_PadData.yAxisL;
|
||
|
}
|
||
|
s16 WiiDRC_rStickX()
|
||
|
{
|
||
|
return __WiiDRC_PadData.xAxisR;
|
||
|
}
|
||
|
s16 WiiDRC_rStickY()
|
||
|
{
|
||
|
return __WiiDRC_PadData.yAxisR;
|
||
|
}
|