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: