diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index a93abaefc7..0c1bdf73a3 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -415,7 +415,7 @@ namespace BizHawk.Client.Common nextEmulator = new N64(nextComm, game, rom.RomData, GetCoreSyncSettings()); break; case "WSWAN": - nextEmulator = new WonderSwan(nextComm, rom.RomData); + nextEmulator = new WonderSwan(nextComm, rom.RomData, Deterministic); break; case "DEBUG": if (VersionInfo.INTERIM) diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs index 6abb0973ae..fcf0a4662e 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/BizSwan.cs @@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan /// /// [DllImport(dd, CallingConvention = cc)] - public static extern bool bizswan_load(IntPtr core, byte[] data, int length, [In] ref Settings settings); + public static extern bool bizswan_load(IntPtr core, byte[] data, int length, [In] ref SyncSettings settings); /// /// get size of saveram @@ -120,7 +120,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan } [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct Settings + public struct SyncSettings { public ushort byear; public byte bmonth; @@ -132,6 +132,11 @@ namespace BizHawk.Emulation.Cores.WonderSwan public Bloodtype blood; [MarshalAs(UnmanagedType.U1)] public bool rotateinput; + [MarshalAs(UnmanagedType.U1)] + public bool color; // true for color system + [MarshalAs(UnmanagedType.U1)] + public bool userealtime; // true for use real real RTC instead of emulation pegged time + public ulong initialtime; // inital time in unix format; only used when userealtime = false public void SetName(string newname) { diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs index ae09f88f59..ed2fdcccf8 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs @@ -40,15 +40,16 @@ namespace BizHawk.Emulation.Cores.WonderSwan #endregion - public WonderSwan(CoreComm comm, byte[] rom) + public WonderSwan(CoreComm comm, byte[] rom, bool deterministicEmulation) { this.CoreComm = comm; + DeterministicEmulation = deterministicEmulation; // when true, remember to force the RTC flag! Core = BizSwan.bizswan_new(); if (Core == IntPtr.Zero) throw new InvalidOperationException("bizswan_new() returned NULL!"); try { - var ss = new BizSwan.Settings + var ss = new BizSwan.SyncSettings { sex = BizSwan.Gender.Male, blood = BizSwan.Bloodtype.A, @@ -120,7 +121,7 @@ namespace BizHawk.Emulation.Cores.WonderSwan public string SystemId { get { return "WSWAN"; } } - public bool DeterministicEmulation { get { return true; } } + public bool DeterministicEmulation { get; private set; } public string BoardName { get { return null; } } #region SaveRam diff --git a/output/dll/bizswan.dll b/output/dll/bizswan.dll index 76a33992fc..2203c861ef 100644 Binary files a/output/dll/bizswan.dll and b/output/dll/bizswan.dll differ diff --git a/wonderswan/gfx.cpp b/wonderswan/gfx.cpp index f16519b392..a56cb27c45 100644 --- a/wonderswan/gfx.cpp +++ b/wonderswan/gfx.cpp @@ -240,7 +240,7 @@ namespace MDFN_IEN_WSWAN return(ret); } - void GFX::SetLayerEnableMask(uint64 mask) + void GFX::SetLayerEnableMask(uint32 mask) { LayerEnabled = mask; } diff --git a/wonderswan/gfx.h b/wonderswan/gfx.h index f30709239b..e6a1a9a09a 100644 --- a/wonderswan/gfx.h +++ b/wonderswan/gfx.h @@ -27,7 +27,7 @@ public: bool ExecuteLine(uint32 *surface, bool skip); - void SetLayerEnableMask(uint64 mask); + void SetLayerEnableMask(uint32 mask); private: // TCACHE ==================================== diff --git a/wonderswan/mednafen/types.h b/wonderswan/mednafen/types.h index 320aab5069..4e2b24f631 100644 --- a/wonderswan/mednafen/types.h +++ b/wonderswan/mednafen/types.h @@ -76,7 +76,6 @@ typedef uint64_t uint64; #undef MDFN_GCC_VERSION #elif defined(_MSC_VER) - #pragma message("Compiling with MSVC, untested") #define INLINE __forceinline #define NO_INLINE __declspec(noinline) diff --git a/wonderswan/memory.cpp b/wonderswan/memory.cpp index 8ccef25115..434fa49d5f 100644 --- a/wonderswan/memory.cpp +++ b/wonderswan/memory.cpp @@ -289,13 +289,14 @@ namespace MDFN_IEN_WSWAN } } - void Memory::Init(const Settings &settings) + void Memory::Init(const SyncSettings &settings) { char tmpname[17]; std::memcpy(tmpname, settings.name, 16); tmpname[16] = 0; language = settings.language; + wsc = settings.color; // WSwan_EEPROMInit() will also clear wsEEPROM sys->eeprom.Init(tmpname, settings.byear, settings.bmonth, settings.bday, settings.sex, settings.blood); diff --git a/wonderswan/memory.h b/wonderswan/memory.h index fc19116774..3dce1ced7b 100644 --- a/wonderswan/memory.h +++ b/wonderswan/memory.h @@ -13,7 +13,7 @@ public: uint8 Read20(uint32); void Write20(uint32 address,uint8 data); - void Init(const Settings &settings); + void Init(const SyncSettings &settings); void CheckSoundDMA(); void Reset(); @@ -50,6 +50,7 @@ private: bool language; + bool wsc; // mono / color public: System *sys; diff --git a/wonderswan/rtc.cpp b/wonderswan/rtc.cpp index 9ee167b0b9..b621ba0a93 100644 --- a/wonderswan/rtc.cpp +++ b/wonderswan/rtc.cpp @@ -19,10 +19,20 @@ */ #include "system.h" -#include +#include namespace MDFN_IEN_WSWAN { + static void GMTime(uint64 ticks, tm &time) + { + time_t t = ticks; + #ifdef __GNUC__ + gmtime_r(&t, &time); + #elif defined _MSC_VER + gmtime_s(&time, &t); + #endif + } + void RTC::Write(uint32 A, uint8 V) { switch(A) @@ -46,18 +56,19 @@ namespace MDFN_IEN_WSWAN case 0xcb : if(Command == 0x15) { - time_t long_time = CurrentTime; - struct tm *newtime = gmtime( &long_time ); + tm newtime; + uint64 now = userealtime ? time(0) : CurrentTime; + GMTime(CurrentTime, newtime); switch(wsCA15) { - case 0: wsCA15++;return mBCD(newtime->tm_year-100); - case 1: wsCA15++;return mBCD(newtime->tm_mon); - case 2: wsCA15++;return mBCD(newtime->tm_mday); - case 3: wsCA15++;return mBCD(newtime->tm_wday); - case 4: wsCA15++;return mBCD(newtime->tm_hour); - case 5: wsCA15++;return mBCD(newtime->tm_min); - case 6: wsCA15=0;return mBCD(newtime->tm_sec); + case 0: wsCA15++;return mBCD(newtime.tm_year-100); + case 1: wsCA15++;return mBCD(newtime.tm_mon); + case 2: wsCA15++;return mBCD(newtime.tm_mday); + case 3: wsCA15++;return mBCD(newtime.tm_wday); + case 4: wsCA15++;return mBCD(newtime.tm_hour); + case 5: wsCA15++;return mBCD(newtime.tm_min); + case 6: wsCA15=0;return mBCD(newtime.tm_sec); } return 0; } @@ -68,22 +79,33 @@ namespace MDFN_IEN_WSWAN return(0); } - void RTC::Reset() + void RTC::Init(uint64 initialtime, bool realtime) { - time_t happy_time = time(NULL); + if (realtime) + { + userealtime = true; + CurrentTime = time(0); + } + else + { + userealtime = false; + CurrentTime = initialtime; + } - CurrentTime = mktime(localtime(&happy_time)); ClockCycleCounter = 0; - wsCA15 = 0; + wsCA15 = 0; // is this also possibly set to 0 on reset? } void RTC::Clock(uint32 cycles) { - ClockCycleCounter += cycles; - while(ClockCycleCounter >= 3072000) + if (!userealtime) { - ClockCycleCounter -= 3072000; - CurrentTime++; + ClockCycleCounter += cycles; + while(ClockCycleCounter >= 3072000) + { + ClockCycleCounter -= 3072000; + CurrentTime++; + } } } diff --git a/wonderswan/rtc.h b/wonderswan/rtc.h index d4319e2c43..cdead60466 100644 --- a/wonderswan/rtc.h +++ b/wonderswan/rtc.h @@ -10,11 +10,13 @@ class RTC public: void Write(uint32 A, uint8 V); uint8 Read(uint32 A); - void Reset(); + void Init(uint64 initialtime, bool realtime); void Clock(uint32 cycles); private: uint64 CurrentTime; + bool userealtime; + uint32 ClockCycleCounter; uint8 wsCA15; uint8 Command, Data; diff --git a/wonderswan/system.cpp b/wonderswan/system.cpp index 62b4ba7ea5..a4baa2cafc 100644 --- a/wonderswan/system.cpp +++ b/wonderswan/system.cpp @@ -52,7 +52,7 @@ namespace MDFN_IEN_WSWAN gfx.Reset(); sound.Reset(); interrupt.Reset(); - rtc.Reset(); + //rtc.Reset(); // at the moment, RTC changes no state on hard reset eeprom.Reset(); for(int u0=0;u0<0xc9;u0++) @@ -101,7 +101,7 @@ namespace MDFN_IEN_WSWAN return(v); } - bool System::Load(const uint8 *data, int length, const Settings &settings) + bool System::Load(const uint8 *data, int length, const SyncSettings &settings) { uint32 real_rom_size; @@ -201,6 +201,7 @@ namespace MDFN_IEN_WSWAN // TODO: control WSC setting memory.Init(settings); + rtc.Init(settings.initialtime, settings.userealtime); //MDFNGameInfo->fps = (uint32)((uint64)3072000 * 65536 * 256 / (159*256)); @@ -219,7 +220,6 @@ namespace MDFN_IEN_WSWAN } System::System() - :wsc(1) { gfx.sys = this; memory.sys = this; @@ -294,7 +294,7 @@ namespace MDFN_IEN_WSWAN s->Advance(buttons, novideo, surface, soundbuff, *soundbuffsize); } - EXPORT int bizswan_load(System *s, const uint8 *data, int length, const Settings *settings) + EXPORT int bizswan_load(System *s, const uint8 *data, int length, const SyncSettings *settings) { return s->Load(data, length, *settings); } diff --git a/wonderswan/system.h b/wonderswan/system.h index 81c6514f5d..fad4f6cb40 100644 --- a/wonderswan/system.h +++ b/wonderswan/system.h @@ -4,6 +4,7 @@ namespace MDFN_IEN_WSWAN { class System; +struct SyncSettings; struct Settings; } @@ -30,7 +31,7 @@ public: void Reset(); void Advance(uint16 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize); - bool Load(const uint8 *data, int length, const Settings &s); + bool Load(const uint8 *data, int length, const SyncSettings &s); int SaveRamSize(); bool SaveRamLoad(const uint8 *data, int size); @@ -44,12 +45,9 @@ public: Sound sound; V30MZ cpu; Interrupt interrupt; -public: - int wsc; // 1 = 1; /*color/mono*/ - }; -struct Settings +struct SyncSettings { uint16 byear; // birth year, 0000-9999 uint8 bmonth; // birth month, 1-12 @@ -59,6 +57,14 @@ struct Settings uint8 sex; // sex, 1 = male, 2 = female uint8 blood; // 1 = a, 2 = b, 3 = o, 4 = ab bool rotateinput; // true to rotate input and dpads, sync setting because of this + bool color; // true if wonderswan is in color mode + bool userealtime; // true to use the system's actual clock; false to use an emulation pegged clock + uint64 initialtime; // when userealtime is false, the initial time in unix format +}; + +struct Settings +{ + uint32 LayerMask; // 1 = enable bg, 2 = enable fg, 4 = enable sprites }; namespace Debug