Added Solar Sensor support from VBA-Wii.

Requires EEPROM+Sensor save type and Real Time Clock enabled.  The solar sensor can be controlled by the left and right motion sensor controls.
This commit is contained in:
skidau 2015-03-26 09:08:30 +00:00
parent 8ac02202e9
commit e19d04c4fd
5 changed files with 146 additions and 6 deletions

View File

@ -62,6 +62,11 @@ extern void systemScreenMessage(const char *);
extern void systemUpdateMotionSensor();
extern int systemGetSensorX();
extern int systemGetSensorY();
extern int systemGetSensorZ();
extern u8 systemGetSensorDarkness();
extern void systemCartridgeRumble(bool);
extern void systemPossibleCartridgeRumble(bool);
extern void updateRumbleFrame();
extern bool systemCanChangeSoundQuality();
extern void systemShowSpeed(int);
extern void system10Frames(int);

View File

@ -56,7 +56,28 @@ u16 rtcRead(u32 address)
return rtcClockData.byte1;
break;
case 0x80000c4:
return rtcClockData.byte0;
// Boktai Solar Sensor
if (rtcClockData.byte1 == 7) {
if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) {
rtcClockData.reserved[10] = 0;
rtcClockData.reserved[11] = 0;
return 8;
}
else {
return 0;
}
}
// WarioWare Twisted Tilt Sensor
else if (rtcClockData.byte1 == 0x0b) {
//sprintf(DebugStr, "Reading Twisted Sensor bit %d", rtcClockData.reserved[11]);
u16 v = systemGetSensorZ();
return ((v >> rtcClockData.reserved[11]) & 1) << 2;
}
// Real Time Clock
else {
//sprintf(DebugStr, "Reading RTC %02x, %02x, %02x", rtcClockData.byte0, rtcClockData.byte1, rtcClockData.byte2);
return rtcClockData.byte0;
}
break;
}
}
@ -78,10 +99,46 @@ bool rtcWrite(u32 address, u16 value)
return false;
if(address == 0x80000c8) {
rtcClockData.byte2 = (u8)value; // enable ?
} else if(address == 0x80000c6) {
rtcClockData.byte1 = (u8)value; // read/write
} else if(address == 0x80000c4) {
rtcClockData.byte2 = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8
}
else if (address == 0x80000c6) {
rtcClockData.byte1 = (u8)value; // 0=read/1=write (for each of 4 low bits)
// rumble is off when not writing to that pin
if (/*rtcWarioRumbleEnabled &&*/ !(value & 8)) systemCartridgeRumble(false);
}
else if (address == 0x80000c4) { // 4 bits of I/O Port Data (upper bits not used)
// WarioWare Twisted rumble
if (/*rtcWarioRumbleEnabled &&*/ (rtcClockData.byte1 & 8)) {
systemCartridgeRumble(value & 8);
}
// Boktai solar sensor
if (rtcClockData.byte1 == 7) {
if (value & 2) {
// reset counter to 0
rtcClockData.reserved[11] = 0;
rtcClockData.reserved[10] = 0;
}
if ((value & 1) && (!(rtcClockData.reserved[10] & 1))) {
// increase counter, ready to do another read
if (rtcClockData.reserved[11]<255) rtcClockData.reserved[11]++;
}
rtcClockData.reserved[10] = value & rtcClockData.byte1;
}
// WarioWare Twisted rotation sensor
if (rtcClockData.byte1 == 0xb) {
if (value & 2) {
// clock goes high in preperation for reading a bit
rtcClockData.reserved[11]--;
}
if (value & 1) {
// start ADC conversion
rtcClockData.reserved[11] = 15;
}
rtcClockData.byte0 = value & rtcClockData.byte1;
// Real Time Clock
}
/**/
if(rtcClockData.byte2 & 1) {
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) {
rtcClockData.state = COMMAND;
@ -202,6 +259,7 @@ void rtcReset()
rtcClockData.dataLen = 0;
rtcClockData.bits = 0;
rtcClockData.state = IDLE;
rtcClockData.reserved[11] = 0;
}
#ifdef __LIBRETRO__

View File

@ -751,12 +751,20 @@ void DirectInput::checkKeys()
void DirectInput::checkMotionKeys()
{
if(checkKey(theApp.input->joypaddata[MOTION(KEY_LEFT)])) {
theApp.sunBars--;
if (theApp.sunBars < 1)
theApp.sunBars = 1;
theApp.sensorX += 3;
if(theApp.sensorX > 2197)
theApp.sensorX = 2197;
if(theApp.sensorX < 2047)
theApp.sensorX = 2057;
} else if(checkKey(theApp.input->joypaddata[MOTION(KEY_RIGHT)])) {
theApp.sunBars++;
if (theApp.sunBars > 100)
theApp.sunBars = 100;
theApp.sensorX -= 3;
if(theApp.sensorX < 1897)
theApp.sensorX = 1897;

View File

@ -316,6 +316,7 @@ VBA::VBA()
movieNextJoypad = 0;
sensorX = 2047;
sensorY = 2047;
sunBars = 500;
mouseCounter = 0;
wasPaused = false;
frameskipadjust = 0;
@ -942,12 +943,18 @@ u32 systemReadJoypad(int which)
return 0;
}
static u8 sensorDarkness = 0xE8; // total darkness (including daylight on rainy days)
// TODO: implement
void systemCartridgeRumble(bool) { }
void systemPossibleCartridgeRumble(bool) { }
void updateRumbleFrame() { }
int systemGetSensorZ() { return 0; }
u8 systemGetSensorDarkness() { return 0; }
u8 systemGetSensorDarkness()
{
return sensorDarkness;
}
void systemDrawScreen()
{
@ -1140,10 +1147,71 @@ void systemScreenMessage(const char *msg)
theApp.screenMessageBuffer = theApp.screenMessageBuffer.Left(40);
}
void systemUpdateSolarSensor()
{
u8 sun = 0x0; //sun = 0xE8 - 0xE8 (case 0 and default)
int level = theApp.sunBars / 10;
switch (level)
{
case 1:
sun = 0xE8 - 0xE0;
break;
case 2:
sun = 0xE8 - 0xDA;
break;
case 3:
sun = 0xE8 - 0xD0;
break;
case 4:
sun = 0xE8 - 0xC8;
break;
case 5:
sun = 0xE8 - 0xC0;
break;
case 6:
sun = 0xE8 - 0xB0;
break;
case 7:
sun = 0xE8 - 0xA0;
break;
case 8:
sun = 0xE8 - 0x88;
break;
case 9:
sun = 0xE8 - 0x70;
break;
case 10:
sun = 0xE8 - 0x50;
break;
default:
break;
}
struct tm *newtime;
time_t long_time;
// regardless of the weather, there should be no sun at night time!
time(&long_time); // Get time as long integer.
newtime = localtime(&long_time); // Convert to local time.
if (newtime->tm_hour > 21 || newtime->tm_hour < 5)
{
sun = 0; // total darkness, 9pm - 5am
}
else if (newtime->tm_hour > 20 || newtime->tm_hour < 6)
{
sun /= 9; // almost total darkness 8pm-9pm, 5am-6am
}
else if (newtime->tm_hour > 18 || newtime->tm_hour < 7)
{
sun >>= 1;
}
sensorDarkness = 0xE8 - sun;
}
void systemUpdateMotionSensor()
{
if(theApp.input)
theApp.input->checkMotionKeys();
systemUpdateSolarSensor();
}
int systemGetSensorX()

View File

@ -181,6 +181,7 @@ class VBA : public CWinApp
u32 movieNextJoypad;
int sensorX;
int sensorY;
int sunBars;
int mouseCounter;
bool wasPaused;
int frameskipadjust;