From e55cbb43cc9ad2662f7fc5058cd7b0e3ea64ff13 Mon Sep 17 00:00:00 2001 From: skidau Date: Thu, 26 Mar 2015 09:08:30 +0000 Subject: [PATCH] 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. git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@1246 a31d4220-a93d-0410-bf67-fe4944624d44 --- src/System.h | 5 +++ src/gba/RTC.cpp | 68 ++++++++++++++++++++++++++++++++++--- src/win32/DirectInput.cpp | 8 +++++ src/win32/VBA.cpp | 70 ++++++++++++++++++++++++++++++++++++++- src/win32/VBA.h | 1 + 5 files changed, 146 insertions(+), 6 deletions(-) diff --git a/src/System.h b/src/System.h index 30c74e84..f9ba3ee0 100644 --- a/src/System.h +++ b/src/System.h @@ -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); diff --git a/src/gba/RTC.cpp b/src/gba/RTC.cpp index bc060ac7..5249b7ec 100644 --- a/src/gba/RTC.cpp +++ b/src/gba/RTC.cpp @@ -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__ diff --git a/src/win32/DirectInput.cpp b/src/win32/DirectInput.cpp index 821ed591..afc87133 100644 --- a/src/win32/DirectInput.cpp +++ b/src/win32/DirectInput.cpp @@ -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; diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp index 26753b0c..4912c621 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -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() diff --git a/src/win32/VBA.h b/src/win32/VBA.h index 0fd19cc5..00537d6e 100644 --- a/src/win32/VBA.h +++ b/src/win32/VBA.h @@ -181,6 +181,7 @@ class VBA : public CWinApp u32 movieNextJoypad; int sensorX; int sensorY; + int sunBars; int mouseCounter; bool wasPaused; int frameskipadjust;