From 5cb474d41a2049337ca9bee6ab3388bfcd2c7ab3 Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Thu, 16 Oct 2025 15:00:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E4=BA=9BEssgee=E6=A0=B8=E5=BF=83?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Emulation/Audio/DMGAudio.Square.cs | 40 +++++++++++++++---- .../Emulation/Machines/GameBoy.cs | 11 +++-- .../Emulation/Video/Nintendo/DMGVideo.cs | 35 +++++++++++----- 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.Square.cs b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.Square.cs index b20478ea..fe255c89 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.Square.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Audio/DMGAudio.Square.cs @@ -6,13 +6,36 @@ namespace Essgee.Emulation.Audio { public class Square : IDMGAudioChannel { - static readonly bool[,] dutyCycleTable = new bool[,] + //static readonly bool[,] dutyCycleTable = new bool[,] + // { + // { false, false, false, false, false, false, false, true, }, // 00000001 12.5% + // { true, false, false, false, false, false, false, true, }, // 10000001 25% + // { true, false, false, false, false, true, true, true, }, // 10000111 50% + // { false, true, true, true, true, true, true, false, } // 01111110 75% + //}; + + // 1. 初始化 - 假设原始数组是 4行 x 8列 + private const int Rows = 4; + private const int Cols = 8; + private readonly bool[] _dutyCycleTable1D = new bool[Rows * Cols] { - { false, false, false, false, false, false, false, true, }, // 00000001 12.5% - { true, false, false, false, false, false, false, true, }, // 10000001 25% - { true, false, false, false, false, true, true, true, }, // 10000111 50% - { false, true, true, true, true, true, true, false, } // 01111110 75% - }; + // 第一行 (索引 0-7) + false, false, false, false, false, false, false, true, + // 第二行 (索引 8-15) + true, false, false, false, false, false, false, true, + // 第三行 (索引 16-23) + true, false, false, false, false, true, true, true, + // 第四行 (索引 24-31) + false, true, true, true, true, true, true, false + }; + + // 2. 访问方法 - 替代原来的 dutyCycleTable[row, col] + public bool GetValue(int row, int col) + { + // 重要的边界检查(在稳定后可通过条件编译移除以极致优化) + // if (row < 0 || row >= Rows || col < 0 || col >= Cols) return false; + return _dutyCycleTable1D[row * Cols + col]; + } // NR10/20 byte sweepPeriodReload, sweepShift; @@ -143,7 +166,10 @@ namespace Essgee.Emulation.Audio dutyCounter %= 8; } - OutputVolume = isDacEnabled && dutyCycleTable[dutyCycle, dutyCounter] ? volume : 0; + //OutputVolume = isDacEnabled && dutyCycleTable[dutyCycle, dutyCounter] ? volume : 0; + + //改为一维数组访问 + OutputVolume = isDacEnabled && _dutyCycleTable1D[dutyCycle * Cols + dutyCounter] ? volume : 0; } private void Trigger() diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs index cefb4099..d772d4b4 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Machines/GameBoy.cs @@ -445,9 +445,11 @@ namespace Essgee.Emulation.Machines public void RunStep() { - var clockCyclesInStep = cpu.Step(); - - for (var s = 0; s < clockCyclesInStep / 4; s++) + int clockCyclesInStep = cpu.Step(); + int loopCount = clockCyclesInStep / 4; // 除法计算移出循环 + // 在循环外检查 cartridge 是否为空,避免每次循环都检查 + bool hasCartridge = cartridge != null; + for (var s = 0; s < loopCount; s++) { HandleTimerOverflow(); UpdateCycleCounter((ushort)(clockCycleCount + 4)); @@ -456,7 +458,8 @@ namespace Essgee.Emulation.Machines video.Step(4); audio.Step(4); - cartridge?.Step(4); + if(hasCartridge) + cartridge.Step(4); currentMasterClockCyclesInFrame += 4; } diff --git a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Video/Nintendo/DMGVideo.cs b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Video/Nintendo/DMGVideo.cs index 6e307eb2..bf6b7ee0 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Video/Nintendo/DMGVideo.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/Essgee.Unity/Emulation/Video/Nintendo/DMGVideo.cs @@ -93,14 +93,26 @@ namespace Essgee.Emulation.Video.Nintendo protected bool statIrqSignal, vBlankReady; protected int[] spritesOnLine; - readonly byte[][] colorValuesBgr = new byte[][] + // readonly byte[][] colorValuesBgr = new byte[][] + // { + // /* B G R */ + // new byte[] { 0xF8, 0xF8, 0xF8 }, /* White */ + // new byte[] { 0x9B, 0x9B, 0x9B }, /* Light gray */ + // new byte[] { 0x3E, 0x3E, 0x3E }, /* Dark gray */ + // new byte[] { 0x1F, 0x1F, 0x1F }, /* Black */ + //}; + + + //取值范例 colorValuesBgr[colorIndex * 3 + channelIndex]; + const byte colorValuesBgr_singleLen = 3; + // 转换后的一维数组 + readonly byte[] colorValuesBgr = new byte[] { - /* B G R */ - new byte[] { 0xF8, 0xF8, 0xF8 }, /* White */ - new byte[] { 0x9B, 0x9B, 0x9B }, /* Light gray */ - new byte[] { 0x3E, 0x3E, 0x3E }, /* Dark gray */ - new byte[] { 0x1F, 0x1F, 0x1F }, /* Black */ - }; + /* White */ 0xF8, 0xF8, 0xF8, + /* Light gray */0x9B, 0x9B, 0x9B, + /* Dark gray */ 0x3E, 0x3E, 0x3E, + /* Black */ 0x1F, 0x1F, 0x1F + }; protected const byte screenUsageEmpty = 0; protected const byte screenUsageBackground = 1 << 0; @@ -719,9 +731,12 @@ namespace Essgee.Emulation.Video.Nintendo protected virtual void WriteColorToFramebuffer(byte c, int address) { - outputFramebuffer[address + 0] = colorValuesBgr[c & 0x03][0]; - outputFramebuffer[address + 1] = colorValuesBgr[c & 0x03][1]; - outputFramebuffer[address + 2] = colorValuesBgr[c & 0x03][2]; + //outputFramebuffer[address + 0] = colorValuesBgr[c & 0x03][0]; + //outputFramebuffer[address + 1] = colorValuesBgr[c & 0x03][1]; + //outputFramebuffer[address + 2] = colorValuesBgr[c & 0x03][2]; + outputFramebuffer[address + 0] = colorValuesBgr[(c & 0x03) * 3 + 0]; + outputFramebuffer[address + 1] = colorValuesBgr[(c & 0x03) * 3 + 1]; + outputFramebuffer[address + 2] = colorValuesBgr[(c & 0x03) * 3 + 2]; outputFramebuffer[address + 3] = 0xFF; }