From 51af1d564a350b21babe62d9093f4d0b54dada74 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 Linux build fix git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@1266 a31d4220-a93d-0410-bf67-fe4944624d44 wx build fix git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@1268 a31d4220-a93d-0410-bf67-fe4944624d44 Note: Does not include link changes to wxbvam.cpp from 1268 intial fix for solarsensor that skid implemented. Will add functioning code after, for now it will allow users to compile at least the SDL interface. git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@1254 a31d4220-a93d-0410-bf67-fe4944624d44 Conflicts: src/sdl/SDL.cpp --- src/System.h | 5 ++ src/gba/RTC.cpp | 68 +++++++++++++-- src/gtk/system.cpp | 13 +++ src/libretro/libretro.cpp | 10 +++ src/sdl/SDL.cpp | 54 ++++++++---- src/sdl/inputSDL.cpp | 1 + src/win32/DirectInput.cpp | 8 ++ src/win32/VBA.cpp | 70 ++++++++++++++- src/win32/VBA.h | 1 + src/wx/sys.cpp | 175 ++++++++++++++++++++++++++++---------- 10 files changed, 335 insertions(+), 70 deletions(-) diff --git a/src/System.h b/src/System.h index 1895d6b9..62c5155c 100644 --- a/src/System.h +++ b/src/System.h @@ -64,6 +64,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/gtk/system.cpp b/src/gtk/system.cpp index 3a443b5f..6752f4d4 100644 --- a/src/gtk/system.cpp +++ b/src/gtk/system.cpp @@ -114,6 +114,10 @@ void systemUpdateMotionSensor() { } +u8 systemGetSensorDarkness() +{ +} + int systemGetSensorX() { return 0; @@ -124,6 +128,15 @@ int systemGetSensorY() return 0; } +int systemGetSensorZ() +{ + return 0; +} + +void systemCartridgeRumble(bool) +{ +} + void systemGbPrint(u8 * _puiData, int _iLen, int _iPages, diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index 4e8e03cb..822185a7 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -580,6 +580,11 @@ int systemGetSensorY(void) return 0; } +int systemGetSensorZ(void) +{ + return 0; +} + u32 systemReadJoypad(int which) { if (which == -1) @@ -596,6 +601,11 @@ u32 systemReadJoypad(int which) bool systemReadJoypads() { return true; } void systemUpdateMotionSensor() {} +u8 systemGetSensorDarkness() {} + +void systemCartridgeRumble(bool) +{ +} bool systemPauseOnFrame() { return false; } void systemGbPrint(u8 *data,int pages, int feed, int palette, int contrast) {} diff --git a/src/sdl/SDL.cpp b/src/sdl/SDL.cpp index 363d3e63..1959d808 100644 --- a/src/sdl/SDL.cpp +++ b/src/sdl/SDL.cpp @@ -2660,50 +2660,70 @@ bool systemCanChangeSoundQuality() bool systemPauseOnFrame() { - if(pauseNextFrame) { - paused = true; - pauseNextFrame = false; - return true; - } - return false; + if(pauseNextFrame) { + paused = true; + pauseNextFrame = false; + return true; + } + return false; } void systemGbBorderOn() { - srcWidth = 256; - srcHeight = 224; - gbBorderLineSkip = 256; - gbBorderColumnSkip = 48; - gbBorderRowSkip = 40; + srcWidth = 256; + srcHeight = 224; + gbBorderLineSkip = 256; + gbBorderColumnSkip = 48; + gbBorderRowSkip = 40; - sdlInitVideo(); + sdlInitVideo(); filterFunction = initFilter(filter, srcWidth); } bool systemReadJoypads() { - return true; + return true; } u32 systemReadJoypad(int which) { - return inputReadJoypad(which); + return inputReadJoypad(which); +} +//static u8 sensorDarkness = 0xE8; // total darkness (including daylight on rainy days) + +void systemUpdateSolarSensor() +{ +} + +void systemCartridgeRumble(bool) +{ } void systemUpdateMotionSensor() { - inputUpdateMotionSensor(); + inputUpdateMotionSensor(); + systemUpdateSolarSensor(); } int systemGetSensorX() { - return inputGetSensorX(); + return inputGetSensorX(); } int systemGetSensorY() { - return inputGetSensorY(); + return inputGetSensorY(); +} + +int systemGetSensorZ() +{ + return 0; +} + +u8 systemGetSensorDarkness() +{ + //return sensorDarkness; } SoundDriver * systemSoundInit() diff --git a/src/sdl/inputSDL.cpp b/src/sdl/inputSDL.cpp index e0ba0ca5..83c3326c 100644 --- a/src/sdl/inputSDL.cpp +++ b/src/sdl/inputSDL.cpp @@ -623,3 +623,4 @@ EPad inputGetDefaultJoypad() { return sdlDefaultJoypad; } + 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 329b4d5c..69411a00 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -312,6 +312,7 @@ VBA::VBA() movieNextJoypad = 0; sensorX = 2047; sensorY = 2047; + sunBars = 500; mouseCounter = 0; wasPaused = false; frameskipadjust = 0; @@ -925,12 +926,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() { @@ -1123,10 +1130,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 0f8c3a8e..86cc4166 100644 --- a/src/win32/VBA.h +++ b/src/win32/VBA.h @@ -177,6 +177,7 @@ class VBA : public CWinApp u32 movieNextJoypad; int sensorX; int sensorY; + int sunBars; int mouseCounter; bool wasPaused; int frameskipadjust; diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index 911e4c44..88c9964d 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -95,6 +95,7 @@ wxFFile game_file; bool game_recording, game_playback; u32 game_frame; u32 game_joypad; +int sunBars = 500; void systemStartGameRecording(const wxString &fname) { @@ -402,57 +403,132 @@ u32 systemGetClock() return wxGetApp().timer.Time(); } +void systemCartridgeRumble(bool) {} + +static u8 sensorDarkness = 0xE8; // total darkness (including daylight on rainy days) + +u8 systemGetSensorDarkness() +{ + return sensorDarkness; +} + +void systemUpdateSolarSensor() +{ + u8 sun = 0x0; //sun = 0xE8 - 0xE8 (case 0 and default) + int level = 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() { for(int i = 0; i < 4; i++) { - if(!sensorx[i]) - sensorx[i] = 2047; - if(!sensory[i]) - sensory[i] = 2047; - if(joypress[i] & KEYM_MOTION_LEFT) { - sensorx[i] += 3; - if(sensorx[i] > 2197) - sensorx[i] = 2197; - if(sensorx[i] < 2047) - sensorx[i] = 2057; - } else if(joypress[i] & KEYM_MOTION_RIGHT) { - sensorx[i] -= 3; - if(sensorx[i] < 1897) - sensorx[i] = 1897; - if(sensorx[i] > 2047) - sensorx[i] = 2037; - } else if(sensorx[i] > 2047) { - sensorx[i] -= 2; - if(sensorx[i] < 2047) - sensorx[i] = 2047; - } else { - sensorx[i] += 2; - if(sensorx[i] > 2047) - sensorx[i] = 2047; + if(!sensorx[i]) + sensorx[i] = 2047; + if(!sensory[i]) + sensory[i] = 2047; + if(joypress[i] & KEYM_MOTION_LEFT) { + sunBars--; + if (sunBars < 1) + sunBars = 1; + sensorx[i] += 3; + if(sensorx[i] > 2197) + sensorx[i] = 2197; + if(sensorx[i] < 2047) + sensorx[i] = 2057; + } else if(joypress[i] & KEYM_MOTION_RIGHT) { + sunBars++; + if (sunBars > 100) + sunBars = 100; + sensorx[i] -= 3; + if(sensorx[i] < 1897) + sensorx[i] = 1897; + if(sensorx[i] > 2047) + sensorx[i] = 2037; + } else if(sensorx[i] > 2047) { + sensorx[i] -= 2; + if(sensorx[i] < 2047) + sensorx[i] = 2047; + } else { + sensorx[i] += 2; + if(sensorx[i] > 2047) + sensorx[i] = 2047; + } + + if(joypress[i] & KEYM_MOTION_UP) { + sensory[i] += 3; + if(sensory[i] > 2197) + sensory[i] = 2197; + if(sensory[i] < 2047) + sensory[i] = 2057; + } else if(joypress[i] & KEYM_MOTION_DOWN) { + sensory[i] -= 3; + if(sensory[i] < 1897) + sensory[i] = 1897; + if(sensory[i] > 2047) + sensory[i] = 2037; + } else if(sensory[i] > 2047) { + sensory[i] -= 2; + if(sensory[i] < 2047) + sensory[i] = 2047; + } else { + sensory[i] += 2; + if(sensory[i] > 2047) + sensory[i] = 2047; + } } - - if(joypress[i] & KEYM_MOTION_UP) { - sensory[i] += 3; - if(sensory[i] > 2197) - sensory[i] = 2197; - if(sensory[i] < 2047) - sensory[i] = 2057; - } else if(joypress[i] & KEYM_MOTION_DOWN) { - sensory[i] -= 3; - if(sensory[i] < 1897) - sensory[i] = 1897; - if(sensory[i] > 2047) - sensory[i] = 2037; - } else if(sensory[i] > 2047) { - sensory[i] -= 2; - if(sensory[i] < 2047) - sensory[i] = 2047; - } else { - sensory[i] += 2; - if(sensory[i] > 2047) - sensory[i] = 2047; - } - } + systemUpdateSolarSensor(); } int systemGetSensorX() @@ -465,6 +541,11 @@ int systemGetSensorY() return sensory[gopts.default_stick - 1]; } +int systemGetSensorZ() +{ + return sensory[gopts.default_stick - 1]; +} + class PrintDialog : public wxEvtHandler, public wxPrintout { public: