diff --git a/Assets/dll/bsnes.wbx.zst b/Assets/dll/bsnes.wbx.zst index aba33e4676..0e531d2539 100644 Binary files a/Assets/dll/bsnes.wbx.zst and b/Assets/dll/bsnes.wbx.zst differ diff --git a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs index d145fc0161..af3efaf625 100644 --- a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs +++ b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.Designer.cs @@ -64,13 +64,16 @@ this.lblRegion = new BizHawk.WinForms.Controls.LocLabelEx(); this.lblEntropy = new BizHawk.WinForms.Controls.LocLabelEx(); this.lblDoubleSize = new BizHawk.WinForms.Controls.LocLabelEx(); + this.cbUseRealTime = new System.Windows.Forms.CheckBox(); + this.dtpInitialTime = new System.Windows.Forms.DateTimePicker(); + this.lblInitialTime = new BizHawk.WinForms.Controls.LocLabelEx(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // btnOk // this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnOk.Location = new System.Drawing.Point(136, 405); + this.btnOk.Location = new System.Drawing.Point(136, 439); this.btnOk.Name = "btnOk"; this.btnOk.Size = new System.Drawing.Size(75, 23); this.btnOk.TabIndex = 26; @@ -82,7 +85,7 @@ // this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(217, 405); + this.btnCancel.Location = new System.Drawing.Point(217, 439); this.btnCancel.Name = "btnCancel"; this.btnCancel.Size = new System.Drawing.Size(75, 23); this.btnCancel.TabIndex = 0; @@ -118,7 +121,7 @@ this.groupBox1.Controls.Add(this.Obj3Checkbox); this.groupBox1.Controls.Add(this.Obj2Checkbox); this.groupBox1.Controls.Add(this.Obj1Checkbox); - this.groupBox1.Location = new System.Drawing.Point(18, 282); + this.groupBox1.Location = new System.Drawing.Point(18, 316); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(274, 115); this.groupBox1.TabIndex = 13; @@ -264,7 +267,7 @@ // this.EntropyBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.EntropyBox.FormattingEnabled = true; - this.EntropyBox.Location = new System.Drawing.Point(16, 215); + this.EntropyBox.Location = new System.Drawing.Point(16, 249); this.EntropyBox.Name = "EntropyBox"; this.EntropyBox.Size = new System.Drawing.Size(128, 21); this.EntropyBox.TabIndex = 10; @@ -273,7 +276,7 @@ // this.RegionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.RegionBox.FormattingEnabled = true; - this.RegionBox.Location = new System.Drawing.Point(162, 255); + this.RegionBox.Location = new System.Drawing.Point(161, 289); this.RegionBox.Name = "RegionBox"; this.RegionBox.Size = new System.Drawing.Size(128, 21); this.RegionBox.TabIndex = 13; @@ -353,7 +356,7 @@ // this.AspectRatioCorrectionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.AspectRatioCorrectionBox.FormattingEnabled = true; - this.AspectRatioCorrectionBox.Location = new System.Drawing.Point(161, 215); + this.AspectRatioCorrectionBox.Location = new System.Drawing.Point(161, 249); this.AspectRatioCorrectionBox.Name = "AspectRatioCorrectionBox"; this.AspectRatioCorrectionBox.Size = new System.Drawing.Size(128, 21); this.AspectRatioCorrectionBox.TabIndex = 11; @@ -382,32 +385,32 @@ // this.SatellaviewCartridgeBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.SatellaviewCartridgeBox.FormattingEnabled = true; - this.SatellaviewCartridgeBox.Location = new System.Drawing.Point(16, 255); + this.SatellaviewCartridgeBox.Location = new System.Drawing.Point(16, 289); this.SatellaviewCartridgeBox.Name = "SatellaviewCartridgeBox"; this.SatellaviewCartridgeBox.Size = new System.Drawing.Size(128, 21); this.SatellaviewCartridgeBox.TabIndex = 12; // // lblSatellaviewCartridge // - this.lblSatellaviewCartridge.Location = new System.Drawing.Point(14, 239); + this.lblSatellaviewCartridge.Location = new System.Drawing.Point(16, 273); this.lblSatellaviewCartridge.Name = "lblSatellaviewCartridge"; this.lblSatellaviewCartridge.Text = "Satellaview cartridge"; // // lblAspectRatioCorrection // - this.lblAspectRatioCorrection.Location = new System.Drawing.Point(159, 198); + this.lblAspectRatioCorrection.Location = new System.Drawing.Point(159, 233); this.lblAspectRatioCorrection.Name = "lblAspectRatioCorrection"; this.lblAspectRatioCorrection.Text = "Aspect Ratio Correction"; // // lblRegion // - this.lblRegion.Location = new System.Drawing.Point(159, 239); + this.lblRegion.Location = new System.Drawing.Point(159, 273); this.lblRegion.Name = "lblRegion"; this.lblRegion.Text = "Region"; // // lblEntropy // - this.lblEntropy.Location = new System.Drawing.Point(13, 198); + this.lblEntropy.Location = new System.Drawing.Point(13, 233); this.lblEntropy.Name = "lblEntropy"; this.lblEntropy.Text = "Entropy"; // @@ -418,6 +421,34 @@ this.lblDoubleSize.Name = "lblDoubleSize"; this.lblDoubleSize.Text = "Some games are changing the resolution constantly (e.g. SD3) so this option can f" + "orce the SNES output to stay double-size always."; + // + // cbUseRealTime + // + this.cbUseRealTime.AutoSize = true; + this.cbUseRealTime.Location = new System.Drawing.Point(161, 176); + this.cbUseRealTime.Name = "cbUseRealTime"; + this.cbUseRealTime.Size = new System.Drawing.Size(96, 17); + this.cbUseRealTime.TabIndex = 27; + this.cbUseRealTime.Text = "Use Real Time"; + this.cbUseRealTime.UseVisualStyleBackColor = true; + // + // dtpInitialTime + // + this.dtpInitialTime.CustomFormat = "yyyy-MM-dd HH:mm:ss"; + this.dtpInitialTime.Format = System.Windows.Forms.DateTimePickerFormat.Custom; + this.dtpInitialTime.Location = new System.Drawing.Point(79, 203); + this.dtpInitialTime.MinDate = new System.DateTime(1970, 1, 1, 0, 0, 0, 0); + this.dtpInitialTime.Name = "dtpInitialTime"; + this.dtpInitialTime.Size = new System.Drawing.Size(206, 20); + this.dtpInitialTime.TabIndex = 27; + // + // lblInitialTime + // + this.lblInitialTime.Location = new System.Drawing.Point(15, 202); + this.lblInitialTime.MaximumSize = new System.Drawing.Size(260, 0); + this.lblInitialTime.Name = "lblInitialTime"; + this.lblInitialTime.Padding = new System.Windows.Forms.Padding(0, 4, 0, 4); + this.lblInitialTime.Text = "Initial Time"; // // BSNESOptions // @@ -425,7 +456,8 @@ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(304, 436); + this.ClientSize = new System.Drawing.Size(304, 470); + this.Controls.Add(this.lblInitialTime); this.Controls.Add(this.SatellaviewCartridgeBox); this.Controls.Add(this.lblSatellaviewCartridge); this.Controls.Add(this.cbShowCursor); @@ -446,6 +478,8 @@ this.Controls.Add(this.groupBox1); this.Controls.Add(this.lblDoubleSize); this.Controls.Add(this.cbDoubleSize); + this.Controls.Add(this.cbUseRealTime); + this.Controls.Add(this.dtpInitialTime); this.Controls.Add(this.btnCancel); this.Controls.Add(this.btnOk); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; @@ -501,5 +535,8 @@ private System.Windows.Forms.CheckBox cbShowCursor; private WinForms.Controls.LocLabelEx lblSatellaviewCartridge; private System.Windows.Forms.ComboBox SatellaviewCartridgeBox; + private System.Windows.Forms.CheckBox cbUseRealTime; + private System.Windows.Forms.DateTimePicker dtpInitialTime; + private WinForms.Controls.LocLabelEx lblInitialTime; } } diff --git a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs index acefbf90e7..b130ab9b94 100644 --- a/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs +++ b/src/BizHawk.Client.EmuHawk/config/SNES/BSNESOptions.cs @@ -43,6 +43,8 @@ namespace BizHawk.Client.EmuHawk FastDSP = ss.FastDSP, FastCoprocessors = ss.FastCoprocessors, UseSGB2 = ss.UseSGB2, + UseRealTime = ss.UseRealTime, + InitialTime = ss.InitialTime, ShowObj1 = s.ShowOBJ_0, ShowObj2 = s.ShowOBJ_1, ShowObj3 = s.ShowOBJ_2, @@ -74,6 +76,8 @@ namespace BizHawk.Client.EmuHawk ss.FastCoprocessors = dlg.FastCoprocessors; ss.UseSGB2 = dlg.UseSGB2; ss.SatellaviewCartridge = dlg.SatellaviewCartridge; + ss.UseRealTime = dlg.UseRealTime; + ss.InitialTime = dlg.InitialTime; s.ShowOBJ_0 = dlg.ShowObj1; s.ShowOBJ_1 = dlg.ShowObj2; s.ShowOBJ_2 = dlg.ShowObj3; @@ -113,8 +117,8 @@ namespace BizHawk.Client.EmuHawk { get => cbShowOverscan.Checked; init => cbShowOverscan.Checked = value; - } - + } + private bool ShowCursor { get => cbShowCursor.Checked; @@ -153,6 +157,18 @@ namespace BizHawk.Client.EmuHawk init => cbUseSGB2.Checked = value; } + private bool UseRealTime + { + get => cbUseRealTime.Checked; + init => cbUseRealTime.Checked = value; + } + + private DateTime InitialTime + { + get => dtpInitialTime.Value; + init => dtpInitialTime.Value = value; + } + private BsnesApi.ENTROPY Entropy => (BsnesApi.ENTROPY) EntropyBox.SelectedIndex; private BsnesApi.REGION_OVERRIDE RegionOverride => (BsnesApi.REGION_OVERRIDE)RegionBox.SelectedIndex; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs index cee43b3ce8..ca1a7e8730 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesApi.cs @@ -198,6 +198,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES public delegate void snes_read_hook_t(uint address); public delegate void snes_write_hook_t(uint address, byte value); public delegate void snes_exec_hook_t(uint address); + public delegate long snes_time_t(); public delegate void snes_msu_open_t(ushort track_id); public delegate void snes_msu_seek_t(long offset, bool relative); public delegate byte snes_msu_read_t(); @@ -248,6 +249,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES public snes_read_hook_t readHookCb; public snes_write_hook_t writeHookCb; public snes_exec_hook_t execHookCb; + public snes_time_t timeCb; public snes_msu_open_t msuOpenCb; public snes_msu_seek_t msuSeekCb; public snes_msu_read_t msuReadCb; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs index e4f546ddca..900ebe3067 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IEmulator.cs @@ -55,6 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES int numSamples = UpdateAudioBuffer(); _soundProvider.PutSamples(_audioBuffer, numSamples / 2); Frame++; + AdvanceRtc(); if (IsLagFrame) { @@ -77,7 +78,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES public string SystemId { get; } - public bool DeterministicEmulation => true; + public bool DeterministicEmulation { get; } public void ResetCounters() { diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs index 34078ec21d..c82aac4d19 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.ISettable.cs @@ -1,4 +1,5 @@ -using BizHawk.Emulation.Common; +using System; +using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Nintendo.BSNES { @@ -120,6 +121,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES public bool UseSGB2 { get; set; } = true; public SATELLAVIEW_CARTRIDGE SatellaviewCartridge { get; set; } = SATELLAVIEW_CARTRIDGE.Autodetect; + + public bool UseRealTime { get; set; } = true; + + public DateTime InitialTime { get; set; } = new(2010, 1, 1); } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IStatable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IStatable.cs index 2441ca0232..cc207e655e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IStatable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.IStatable.cs @@ -11,6 +11,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES writer.Write(IsLagFrame); writer.Write(LagCount); writer.Write(Frame); + writer.Write(_clockTime); + writer.Write(_clockRemainder); } public void LoadStateBinary(BinaryReader reader) @@ -19,6 +21,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES IsLagFrame = reader.ReadBoolean(); LagCount = reader.ReadInt32(); Frame = reader.ReadInt32(); + _clockTime = reader.ReadInt64(); + _clockRemainder = reader.ReadInt32(); } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs index 20b534f3a0..b4556b7542 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs @@ -56,6 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES readHookCb = ReadHook, writeHookCb = WriteHook, execHookCb = ExecHook, + timeCb = snes_time, msuOpenCb = msu_open, msuSeekCb = msu_seek, msuReadCb = msu_read, @@ -66,6 +67,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES _controllers = new BsnesControllers(_syncSettings, subframe); + DeterministicEmulation = !_syncSettings.UseRealTime || loadParameters.DeterministicEmulationRequested; + InitializeRtc(_syncSettings.InitialTime); + generate_palette(); BsnesApi.SnesInitData snesInitData = new() { @@ -340,6 +344,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES } } + private static readonly DateTime _epoch = new(1970, 1, 1, 0, 0, 0); + private long _clockTime; + private int _clockRemainder; + + protected void InitializeRtc(DateTime start) + => _clockTime = (long)(start - _epoch).TotalSeconds; + + private void AdvanceRtc() + { + _clockRemainder += VsyncDenominator; + if (_clockRemainder >= VsyncNumerator) + { + _clockRemainder -= VsyncNumerator; + _clockTime++; + } + } + + private long snes_time() + => DeterministicEmulation ? _clockTime : (long)(DateTime.Now - _epoch).TotalSeconds; + private FileStream _currentMsuTrack; private void msu_seek(long offset, bool relative) diff --git a/waterbox/bsnescore/bsnes/emulator/platform.hpp b/waterbox/bsnescore/bsnes/emulator/platform.hpp index 5be9bc46f6..2c4074e5e4 100644 --- a/waterbox/bsnescore/bsnes/emulator/platform.hpp +++ b/waterbox/bsnescore/bsnes/emulator/platform.hpp @@ -22,8 +22,8 @@ struct Platform { virtual auto inputRumble(uint port, uint device, uint input, bool enable) -> void {} virtual auto dipSettings(Markup::Node node) -> uint { return 0; } virtual auto notify(string text) -> void {} - // 03-may-2021 manual addition. unused currently but let's hope for the best - virtual auto getBackdropColor() -> uint16 { return 0; } + // 03-may-2021 manual addition. unused currently but let's hope for the best + virtual auto getBackdropColor() -> uint16 { return 0; } bool traceEnabled = false; bool readHookEnabled = false; @@ -33,6 +33,7 @@ struct Platform { virtual auto readHook(uint address) -> void {} virtual auto writeHook(uint address, uint8 value) -> void {} virtual auto execHook(uint address) -> void {} + virtual auto time() -> int64 { return ::time(0); } }; extern Platform* platform; diff --git a/waterbox/bsnescore/bsnes/sfc/coprocessor/epsonrtc/memory.cpp b/waterbox/bsnescore/bsnes/sfc/coprocessor/epsonrtc/memory.cpp index f3ab59ee80..290a33f334 100644 --- a/waterbox/bsnescore/bsnes/sfc/coprocessor/epsonrtc/memory.cpp +++ b/waterbox/bsnescore/bsnes/sfc/coprocessor/epsonrtc/memory.cpp @@ -155,7 +155,7 @@ auto EpsonRTC::load(const uint8* data) -> void { timestamp |= data[8 + byte] << (byte * 8); } - uint64 diff = (uint64)time(0) - timestamp; + uint64 diff = (uint64)platform->time() - timestamp; while(diff >= 60 * 60 * 24) { tickDay(); diff -= 60 * 60 * 24; } while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; } while(diff >= 60) { tickMinute(); diff -= 60; } @@ -172,7 +172,7 @@ auto EpsonRTC::save(uint8* data) -> void { data[6] = weekday << 0 | resync << 3 | hold << 4 | calendar << 5 | irqflag << 6 | roundseconds << 7; data[7] = irqmask << 0 | irqduty << 1 | irqperiod << 2 | pause << 4 | stop << 5 | atime << 6 | test << 7; - uint64 timestamp = (uint64)time(0); + uint64 timestamp = (uint64)platform->time(); for(auto byte : range(8)) { data[8 + byte] = timestamp; timestamp >>= 8; diff --git a/waterbox/bsnescore/bsnes/sfc/coprocessor/sharprtc/memory.cpp b/waterbox/bsnescore/bsnes/sfc/coprocessor/sharprtc/memory.cpp index 3803f1ec79..12405d06c0 100644 --- a/waterbox/bsnescore/bsnes/sfc/coprocessor/sharprtc/memory.cpp +++ b/waterbox/bsnescore/bsnes/sfc/coprocessor/sharprtc/memory.cpp @@ -46,7 +46,7 @@ auto SharpRTC::load(const uint8* data) -> void { timestamp |= data[8 + byte] << (byte * 8); } - uint64 diff = (uint64)time(0) - timestamp; + uint64 diff = (uint64)platform->time() - timestamp; while(diff >= 60 * 60 * 24) { tickDay(); diff -= 60 * 60 * 24; } while(diff >= 60 * 60) { tickHour(); diff -= 60 * 60; } while(diff >= 60) { tickMinute(); diff -= 60; } @@ -59,7 +59,7 @@ auto SharpRTC::save(uint8* data) -> void { data[byte] |= rtcRead(byte * 2 + 1) << 4; } - uint64 timestamp = (uint64)time(nullptr); + uint64 timestamp = (uint64)platform->time(); for(auto byte : range(8)) { data[8 + byte] = timestamp; timestamp >>= 8; diff --git a/waterbox/bsnescore/bsnes/sfc/expansion/satellaview/satellaview.cpp b/waterbox/bsnescore/bsnes/sfc/expansion/satellaview/satellaview.cpp index 146bac7686..e82faa5e44 100644 --- a/waterbox/bsnescore/bsnes/sfc/expansion/satellaview/satellaview.cpp +++ b/waterbox/bsnescore/bsnes/sfc/expansion/satellaview/satellaview.cpp @@ -26,8 +26,7 @@ auto Satellaview::read(uint addr, uint8 data) -> uint8 { if(regs.rtcCounter >= 18) regs.rtcCounter = 0; if(counter == 0) { - time_t rawtime; - time(&rawtime); + time_t rawtime = platform->time(); tm* t = localtime(&rawtime); regs.rtcHour = t->tm_hour; diff --git a/waterbox/bsnescore/bsnes/target-bsnescore/callbacks.h b/waterbox/bsnescore/bsnes/target-bsnescore/callbacks.h index abbd47cf06..d2490b8005 100644 --- a/waterbox/bsnescore/bsnes/target-bsnescore/callbacks.h +++ b/waterbox/bsnescore/bsnes/target-bsnescore/callbacks.h @@ -12,6 +12,7 @@ typedef void (*snes_trace_t)(const char* disassembly, const char* register_info) typedef void (*snes_read_hook_t)(uint32_t address); typedef void (*snes_write_hook_t)(uint32_t address, uint8_t value); typedef void (*snes_exec_hook_t)(uint32_t address); +typedef int64_t (*snes_time_t)(void); typedef void (*snes_msu_open_t)(uint16_t track_id); typedef void (*snes_msu_seek_t)(long offset, bool relative); typedef uint8_t (*snes_msu_read_t)(void); @@ -27,6 +28,7 @@ struct SnesCallbacks { snes_read_hook_t snes_read_hook; snes_write_hook_t snes_write_hook; snes_exec_hook_t snes_exec_hook; + snes_time_t snes_time; snes_msu_open_t snes_msu_open; snes_msu_seek_t snes_msu_seek; snes_msu_read_t snes_msu_read; diff --git a/waterbox/bsnescore/bsnes/target-bsnescore/program.cpp b/waterbox/bsnescore/bsnes/target-bsnescore/program.cpp index b268d94ea3..741ec9f9e0 100644 --- a/waterbox/bsnescore/bsnes/target-bsnescore/program.cpp +++ b/waterbox/bsnescore/bsnes/target-bsnescore/program.cpp @@ -29,6 +29,7 @@ struct Program : Emulator::Platform auto readHook(uint address) -> void override; auto writeHook(uint address, uint8 value) -> void override; auto execHook(uint address) -> void override; + auto time() -> int64 override; auto load() -> void; auto loadSuperFamicom() -> bool; @@ -494,6 +495,11 @@ auto Program::execHook(uint address) -> void snesCallbacks.snes_exec_hook(address); } +auto Program::time() -> int64 +{ + return snesCallbacks.snes_time(); +} + auto Program::getBackdropColor() -> uint16 { return backdropColor;