diff --git a/Parsons.Steamdeck/Parsons.Steamdeck.csproj b/Parsons.Steamdeck/Parsons.Steamdeck.csproj index cfa13ad..c47f124 100644 --- a/Parsons.Steamdeck/Parsons.Steamdeck.csproj +++ b/Parsons.Steamdeck/Parsons.Steamdeck.csproj @@ -7,10 +7,14 @@ enable true - true Size + + + + + diff --git a/Parsons.Steamdeck/Program.cs b/Parsons.Steamdeck/Program.cs index 20500f8..05554e9 100644 --- a/Parsons.Steamdeck/Program.cs +++ b/Parsons.Steamdeck/Program.cs @@ -10,61 +10,133 @@ namespace Parsons.SteamDeck { static void Main(string[] args) { - // 1. Initialize Cross-Platform OpenGL Window - // THE FIX: Use PascalCase C# enums Raylib.SetConfigFlags(ConfigFlags.ResizableWindow); - Raylib.InitWindow(1280, 800, "Parsons Master System"); // Native Steam Deck Resolution + Raylib.InitWindow(1280, 800, "Parsons Master System 2026"); Raylib.InitAudioDevice(); - // 2. Initialize Hardware-Agnostic Audio Stream (44.1kHz, 32-bit float, Mono) + //Raylib.SetAudioStreamBufferSizeDefault(1024); + AudioStream audioStream = Raylib.LoadAudioStream(44100, 32, 1); Raylib.PlayAudioStream(audioStream); - // 3. Boot the Core Emulator SmsMachine machine = new SmsMachine(); RaylibAudioPlayer audioPlayer = new RaylibAudioPlayer(); machine.AudioProcessor.AudioDevice = audioPlayer; - // Load a ROM (Passed via command line argument, e.g. ./Parsons.SteamDeck sonic.sms) - if (args.Length > 0 && File.Exists(args[0])) - { - machine.LoadCartridge(File.ReadAllBytes(args[0])); - bool isGG = args[0].EndsWith(".gg", StringComparison.OrdinalIgnoreCase); - machine.VideoProcessor.IsGameGear = isGG; - } - - // Lock the engine loop to 60 FPS natively Raylib.SetTargetFPS(60); - // 4. Prepare the Video Texture Pipeline - // THE FIX: Use Color.Black Image img = Raylib.GenImageColor(256, 192, Color.Black); Texture2D vdpTexture = Raylib.LoadTextureFromImage(img); - byte[] pixelBuffer = new byte[256 * 192 * 4]; // Fast RGBA translation array + byte[] pixelBuffer = new byte[256 * 192 * 4]; + + bool isMenuState = true; + string[] embeddedRoms = GetEmbeddedRoms(); + int selectedRomIndex = 0; + bool buttonLock = false; - // --- THE MAIN GAME LOOP --- while (!Raylib.WindowShouldClose()) { - // A. OS-Agnostic Input Polling (Works on Keyboard AND Steam Deck Controller) - // THE FIX: PascalCase KeyboardKey and GamepadButton enums - byte pad = 0xFF; - if (Raylib.IsKeyDown(KeyboardKey.Up) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceUp)) pad &= 0xFE; - if (Raylib.IsKeyDown(KeyboardKey.Down) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceDown)) pad &= 0xFD; - if (Raylib.IsKeyDown(KeyboardKey.Left) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft)) pad &= 0xFB; - if (Raylib.IsKeyDown(KeyboardKey.Right) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceRight)) pad &= 0xF7; - - // Steam Deck "A" Button is RightFaceDown. "B" Button is RightFaceRight. - if (Raylib.IsKeyDown(KeyboardKey.Z) || Raylib.IsGamepadButtonDown(0, GamepadButton.RightFaceDown)) pad &= 0xEF; // B1 / A Button - if (Raylib.IsKeyDown(KeyboardKey.X) || Raylib.IsGamepadButtonDown(0, GamepadButton.RightFaceRight)) pad &= 0xDF; // B2 / B Button - - machine.IoBus.Joypad1Keyboard = pad; - - // B. Execute exactly one frame of T-States - machine.RunFrame(); - - // C. Flush Audio Buffer to the Sound Card - if (Raylib.IsAudioStreamProcessed(audioStream)) + if (isMenuState) { + // --- MENU INPUT LOGIC --- + if (!buttonLock) + { + if (Raylib.IsKeyDown(KeyboardKey.S) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceDown)) + { + selectedRomIndex++; + if (selectedRomIndex >= embeddedRoms.Length) selectedRomIndex = 0; + buttonLock = true; + } + else if (Raylib.IsKeyDown(KeyboardKey.W) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceUp)) + { + selectedRomIndex--; + if (selectedRomIndex < 0) selectedRomIndex = embeddedRoms.Length - 1; + buttonLock = true; + } + else if (Raylib.IsKeyDown(KeyboardKey.O) || Raylib.IsGamepadButtonDown(0, GamepadButton.RightFaceDown)) + { + string targetRom = embeddedRoms[selectedRomIndex]; + machine.LoadCartridge(LoadEmbeddedRomBytes(targetRom)); + machine.VideoProcessor.IsGameGear = targetRom.EndsWith(".gg", StringComparison.OrdinalIgnoreCase); + isMenuState = false; + } + } + + if (Raylib.IsKeyUp(KeyboardKey.S) && Raylib.IsKeyUp(KeyboardKey.W) && + Raylib.IsGamepadButtonUp(0, GamepadButton.LeftFaceDown) && Raylib.IsGamepadButtonUp(0, GamepadButton.LeftFaceUp)) + { + buttonLock = false; + } + + // --- SCROLLING MENU DRAW LOGIC --- + Raylib.BeginDrawing(); + Raylib.ClearBackground(new Color(20, 20, 40, 255)); + + Raylib.DrawText("PARSONS MASTER SYSTEM", 50, 50, 40, Color.White); + Raylib.DrawText("Select: D-Pad Start: 'A' Button Return to Menu: Select + Start", 50, 100, 20, Color.LightGray); + + // THE FIX: Sliding Window Camera Math + int maxVisibleItems = 16; + int startIndex = selectedRomIndex - (maxVisibleItems / 2); + if (startIndex < 0) startIndex = 0; + if (startIndex > embeddedRoms.Length - maxVisibleItems) startIndex = Math.Max(0, embeddedRoms.Length - maxVisibleItems); + + for (int i = 0; i < maxVisibleItems && (startIndex + i) < embeddedRoms.Length; i++) + { + int actualIndex = startIndex + i; + string cleanName = embeddedRoms[actualIndex].Replace("Parsons.Steamdeck.ROMS.", ""); + + Color textColor = (actualIndex == selectedRomIndex) ? Color.Yellow : Color.White; + string prefix = (actualIndex == selectedRomIndex) ? ">> " : " "; + + Raylib.DrawText(prefix + cleanName, 80, 160 + (i * 35), 20, textColor); + } + + Raylib.EndDrawing(); + } + else + { + // --- EMULATOR HOTKEYS --- + + // If the user holds the "Select" button (or Shift on Keyboard) + if (Raylib.IsGamepadButtonDown(0, GamepadButton.MiddleLeft) || Raylib.IsKeyDown(KeyboardKey.LeftShift)) + { + // Select + Start = Return to Menu + if (Raylib.IsGamepadButtonPressed(0, GamepadButton.MiddleRight) || Raylib.IsKeyPressed(KeyboardKey.Enter)) + { + isMenuState = true; + machine.Reset(); + } + + // Select + R1 = Save State + if (Raylib.IsGamepadButtonPressed(0, GamepadButton.RightTrigger1) || Raylib.IsKeyPressed(KeyboardKey.F5)) + { + machine.SaveState("steamdeck.state"); + } + + // Select + L1 = Load State + if (Raylib.IsGamepadButtonPressed(0, GamepadButton.LeftTrigger1) || Raylib.IsKeyPressed(KeyboardKey.F8)) + { + machine.LoadState("steamdeck.state"); + } + } + + // --- EMULATOR LOGIC --- + byte pad = 0xFF; + if (Raylib.IsKeyDown(KeyboardKey.Up) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceUp)) pad &= 0xFE; + if (Raylib.IsKeyDown(KeyboardKey.Down) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceDown)) pad &= 0xFD; + if (Raylib.IsKeyDown(KeyboardKey.Left) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft)) pad &= 0xFB; + if (Raylib.IsKeyDown(KeyboardKey.Right) || Raylib.IsGamepadButtonDown(0, GamepadButton.LeftFaceRight)) pad &= 0xF7; + if (Raylib.IsKeyDown(KeyboardKey.O) || Raylib.IsGamepadButtonDown(0, GamepadButton.RightFaceDown)) pad &= 0xEF; + if (Raylib.IsKeyDown(KeyboardKey.P) || Raylib.IsGamepadButtonDown(0, GamepadButton.RightFaceRight)) pad &= 0xDF; + + machine.IoBus.Joypad1Keyboard = pad; + + machine.RunFrame(); + + // C. Flush Audio Buffer to the Sound Card + // THE FIX: Do not wait for Raylib to ask! Shove the exact number of + // samples we generated this frame directly into the ring buffer. float[] samples = audioPlayer.GetQueuedSamples(); if (samples.Length > 0) { @@ -76,50 +148,80 @@ namespace Parsons.SteamDeck } } } - } - // D. Fast Pixel Translation (ARGB int -> RGBA bytes) - int[] frameBuffer = machine.VideoProcessor.FrameBuffer; - for (int i = 0; i < frameBuffer.Length; i++) - { - int argb = frameBuffer[i]; - pixelBuffer[i * 4 + 0] = (byte)((argb >> 16) & 0xFF); // R - pixelBuffer[i * 4 + 1] = (byte)((argb >> 8) & 0xFF); // G - pixelBuffer[i * 4 + 2] = (byte)(argb & 0xFF); // B - pixelBuffer[i * 4 + 3] = 255; // A - } + //if (Raylib.IsAudioStreamProcessed(audioStream)) + //{ + // if (audioPlayer.AvailableSamples >= 1024) + // { + // float[] samples = audioPlayer.GetSamples(1024); + // unsafe + // { + // fixed (float* p = samples) + // { + // Raylib.UpdateAudioStream(audioStream, p, 1024); + // } + // } + // } + //} - // Push bytes directly to the GPU Texture - unsafe - { - fixed (byte* p = pixelBuffer) + int[] frameBuffer = machine.VideoProcessor.FrameBuffer; + for (int i = 0; i < frameBuffer.Length; i++) { - Raylib.UpdateTexture(vdpTexture, p); + int argb = frameBuffer[i]; + pixelBuffer[i * 4 + 0] = (byte)((argb >> 16) & 0xFF); + pixelBuffer[i * 4 + 1] = (byte)((argb >> 8) & 0xFF); + pixelBuffer[i * 4 + 2] = (byte)(argb & 0xFF); + pixelBuffer[i * 4 + 3] = 255; } + + unsafe + { + fixed (byte* p = pixelBuffer) + { + Raylib.UpdateTexture(vdpTexture, p); + } + } + + Raylib.BeginDrawing(); + Raylib.ClearBackground(Color.Black); + + float scale = Math.Min((float)Raylib.GetScreenWidth() / 256, (float)Raylib.GetScreenHeight() / 192); + Rectangle sourceRec = new Rectangle(0, 0, 256, 192); + Rectangle destRec = new Rectangle( + (Raylib.GetScreenWidth() - (256 * scale)) * 0.5f, + (Raylib.GetScreenHeight() - (192 * scale)) * 0.5f, + 256 * scale, 192 * scale); + + Raylib.DrawTexturePro(vdpTexture, sourceRec, destRec, new Vector2(0, 0), 0.0f, Color.White); + + Raylib.EndDrawing(); } - - // E. Render to Screen (Perfect Aspect Ratio Scaling) - Raylib.BeginDrawing(); - Raylib.ClearBackground(Color.Black); - - float scale = Math.Min((float)Raylib.GetScreenWidth() / 256, (float)Raylib.GetScreenHeight() / 192); - Rectangle sourceRec = new Rectangle(0, 0, 256, 192); - Rectangle destRec = new Rectangle( - (Raylib.GetScreenWidth() - (256 * scale)) * 0.5f, - (Raylib.GetScreenHeight() - (192 * scale)) * 0.5f, - 256 * scale, 192 * scale); - - // Draw the VDP Frame - Raylib.DrawTexturePro(vdpTexture, sourceRec, destRec, new Vector2(0, 0), 0.0f, Color.White); - - Raylib.EndDrawing(); } - // Clean up hardware resources on exit Raylib.UnloadTexture(vdpTexture); Raylib.UnloadAudioStream(audioStream); Raylib.CloseAudioDevice(); Raylib.CloseWindow(); } + + private static string[] GetEmbeddedRoms() + { + // Pulls all embedded files and filters for Master System and Game Gear + return System.Reflection.Assembly.GetExecutingAssembly() + .GetManifestResourceNames() + .Where(r => r.EndsWith(".sms", StringComparison.OrdinalIgnoreCase) || + r.EndsWith(".gg", StringComparison.OrdinalIgnoreCase)) + .ToArray(); + } + + private static byte[] LoadEmbeddedRomBytes(string resourceName) + { + using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) + using (MemoryStream ms = new MemoryStream()) + { + stream.CopyTo(ms); + return ms.ToArray(); + } + } } } \ No newline at end of file diff --git a/Parsons.Steamdeck/ROMS/After Burner (UE) [!].sms b/Parsons.Steamdeck/ROMS/After Burner (UE) [!].sms new file mode 100644 index 0000000..58c8219 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/After Burner (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Aladdin (USA, Europe, Brazil).gg b/Parsons.Steamdeck/ROMS/Aladdin (USA, Europe, Brazil).gg new file mode 100644 index 0000000..46301a8 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Aladdin (USA, Europe, Brazil).gg differ diff --git a/Parsons.Steamdeck/ROMS/Alex Kidd in High Tech World (UE) [!].sms b/Parsons.Steamdeck/ROMS/Alex Kidd in High Tech World (UE) [!].sms new file mode 100644 index 0000000..e0398f5 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Alex Kidd in High Tech World (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Alex Kidd in Miracle World (UE) [!].sms b/Parsons.Steamdeck/ROMS/Alex Kidd in Miracle World (UE) [!].sms new file mode 100644 index 0000000..bc13346 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Alex Kidd in Miracle World (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Back to the Future 2 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Back to the Future 2 (UE) [!].sms new file mode 100644 index 0000000..29fce34 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Back to the Future 2 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Back to the Future 3 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Back to the Future 3 (UE) [!].sms new file mode 100644 index 0000000..0e689a4 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Back to the Future 3 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Bart vs. the Space Mutants (UE) [!].sms b/Parsons.Steamdeck/ROMS/Bart vs. the Space Mutants (UE) [!].sms new file mode 100644 index 0000000..e980958 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Bart vs. the Space Mutants (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Bart vs. the World (UE) [!].sms b/Parsons.Steamdeck/ROMS/Bart vs. the World (UE) [!].sms new file mode 100644 index 0000000..5212d93 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Bart vs. the World (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Black Belt (UE) [!].sms b/Parsons.Steamdeck/ROMS/Black Belt (UE) [!].sms new file mode 100644 index 0000000..ed8c6b9 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Black Belt (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Bonanza Bros. (Europe).sms b/Parsons.Steamdeck/ROMS/Bonanza Bros. (Europe).sms new file mode 100644 index 0000000..966f041 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Bonanza Bros. (Europe).sms differ diff --git a/Parsons.Steamdeck/ROMS/California Games (UE) [!].sms b/Parsons.Steamdeck/ROMS/California Games (UE) [!].sms new file mode 100644 index 0000000..afd61f6 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/California Games (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/California Games 2 (UE) [!].sms b/Parsons.Steamdeck/ROMS/California Games 2 (UE) [!].sms new file mode 100644 index 0000000..e62c51a Binary files /dev/null and b/Parsons.Steamdeck/ROMS/California Games 2 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Casino Games (UE) [!].sms b/Parsons.Steamdeck/ROMS/Casino Games (UE) [!].sms new file mode 100644 index 0000000..9a56419 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Casino Games (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Choplifter (SG-1000) [!].sg b/Parsons.Steamdeck/ROMS/Choplifter (SG-1000) [!].sg new file mode 100644 index 0000000..f6d6ccb Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Choplifter (SG-1000) [!].sg differ diff --git a/Parsons.Steamdeck/ROMS/Cloud Master (JUE).sms b/Parsons.Steamdeck/ROMS/Cloud Master (JUE).sms new file mode 100644 index 0000000..a3ed922 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Cloud Master (JUE).sms differ diff --git a/Parsons.Steamdeck/ROMS/Cool Spot (UE) [!].sms b/Parsons.Steamdeck/ROMS/Cool Spot (UE) [!].sms new file mode 100644 index 0000000..eb7cb7c Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Cool Spot (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Desert Strike (UE) [!].sms b/Parsons.Steamdeck/ROMS/Desert Strike (UE) [!].sms new file mode 100644 index 0000000..6ff8d72 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Desert Strike (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Double Dragon (UE) [!].sms b/Parsons.Steamdeck/ROMS/Double Dragon (UE) [!].sms new file mode 100644 index 0000000..936287e Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Double Dragon (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Dynamite Dux (UE) [!].sms b/Parsons.Steamdeck/ROMS/Dynamite Dux (UE) [!].sms new file mode 100644 index 0000000..f0778eb Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Dynamite Dux (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Ecco the Dolphin (UE).sms b/Parsons.Steamdeck/ROMS/Ecco the Dolphin (UE).sms new file mode 100644 index 0000000..7c86562 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Ecco the Dolphin (UE).sms differ diff --git a/Parsons.Steamdeck/ROMS/Fantasy Zone (UE) [!].sms b/Parsons.Steamdeck/ROMS/Fantasy Zone (UE) [!].sms new file mode 100644 index 0000000..28f3b66 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Fantasy Zone (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Fantasy Zone 2 - The Tears of Opa-Opa (UE) [!].sms b/Parsons.Steamdeck/ROMS/Fantasy Zone 2 - The Tears of Opa-Opa (UE) [!].sms new file mode 100644 index 0000000..7ddce16 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Fantasy Zone 2 - The Tears of Opa-Opa (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Fantasy Zone 3 - The Maze (UE) [!].sms b/Parsons.Steamdeck/ROMS/Fantasy Zone 3 - The Maze (UE) [!].sms new file mode 100644 index 0000000..4bde5c1 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Fantasy Zone 3 - The Maze (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Gangster Town (UE) [!].sms b/Parsons.Steamdeck/ROMS/Gangster Town (UE) [!].sms new file mode 100644 index 0000000..14ba8da Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Gangster Town (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Gauntlet (UE) [!].sms b/Parsons.Steamdeck/ROMS/Gauntlet (UE) [!].sms new file mode 100644 index 0000000..e3f1520 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Gauntlet (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Ghost House (UE) [!].sms b/Parsons.Steamdeck/ROMS/Ghost House (UE) [!].sms new file mode 100644 index 0000000..e30daa6 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Ghost House (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Ghouls 'n Ghosts (USA).sms b/Parsons.Steamdeck/ROMS/Ghouls 'n Ghosts (USA).sms new file mode 100644 index 0000000..ab4f3ee Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Ghouls 'n Ghosts (USA).sms differ diff --git a/Parsons.Steamdeck/ROMS/Global Defense (UE) [!].sms b/Parsons.Steamdeck/ROMS/Global Defense (UE) [!].sms new file mode 100644 index 0000000..b798d41 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Global Defense (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Golden Axe (UE) [!].sms b/Parsons.Steamdeck/ROMS/Golden Axe (UE) [!].sms new file mode 100644 index 0000000..684d6be Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Golden Axe (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sav b/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sav new file mode 100644 index 0000000..724dc97 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sav differ diff --git a/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sms b/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sms new file mode 100644 index 0000000..0f253de Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Golden Axe Warrior.sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Baseball (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Baseball (UE) [!].sms new file mode 100644 index 0000000..12db16a Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Baseball (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Basketball (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Basketball (UE) [!].sms new file mode 100644 index 0000000..c32e53b Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Basketball (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Football (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Football (UE) [!].sms new file mode 100644 index 0000000..65b6974 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Football (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Golf (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Golf (UE) [!].sms new file mode 100644 index 0000000..ddb1eb3 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Golf (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Ice Hockey (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Ice Hockey (UE) [!].sms new file mode 100644 index 0000000..8b08f03 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Ice Hockey (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Great Volleyball (UE) [!].sms b/Parsons.Steamdeck/ROMS/Great Volleyball (UE) [!].sms new file mode 100644 index 0000000..fed4b15 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Great Volleyball (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Hang-On (UE) [!].sms b/Parsons.Steamdeck/ROMS/Hang-On (UE) [!].sms new file mode 100644 index 0000000..64079f5 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Hang-On (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Hang-On 2 (SG-1000).sg b/Parsons.Steamdeck/ROMS/Hang-On 2 (SG-1000).sg new file mode 100644 index 0000000..b03b494 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Hang-On 2 (SG-1000).sg differ diff --git a/Parsons.Steamdeck/ROMS/Heavyweight Champ (UE) [!].sms b/Parsons.Steamdeck/ROMS/Heavyweight Champ (UE) [!].sms new file mode 100644 index 0000000..79b1018 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Heavyweight Champ (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Home Alone (UE) [!].sms b/Parsons.Steamdeck/ROMS/Home Alone (UE) [!].sms new file mode 100644 index 0000000..d572ac7 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Home Alone (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Impossible Mission (UE) [!].sms b/Parsons.Steamdeck/ROMS/Impossible Mission (UE) [!].sms new file mode 100644 index 0000000..7c1168f Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Impossible Mission (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Japanese SMS BIOS v2.1 (J) [!].sms b/Parsons.Steamdeck/ROMS/Japanese SMS BIOS v2.1 (J) [!].sms new file mode 100644 index 0000000..77cf860 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Japanese SMS BIOS v2.1 (J) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Jurassic Park (UE) [!].sms b/Parsons.Steamdeck/ROMS/Jurassic Park (UE) [!].sms new file mode 100644 index 0000000..3f647b4 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Jurassic Park (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Lucky Dime Caper Starring Donald Duck, The (Europe, Brazil) (En).sms b/Parsons.Steamdeck/ROMS/Lucky Dime Caper Starring Donald Duck, The (Europe, Brazil) (En).sms new file mode 100644 index 0000000..e6f92ef Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Lucky Dime Caper Starring Donald Duck, The (Europe, Brazil) (En).sms differ diff --git a/Parsons.Steamdeck/ROMS/Mickey Mouse - Castle of Illusion (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mickey Mouse - Castle of Illusion (UE) [!].sms new file mode 100644 index 0000000..96c63e9 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mickey Mouse - Castle of Illusion (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Mickey Mouse - Land of Illusion (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mickey Mouse - Land of Illusion (UE) [!].sms new file mode 100644 index 0000000..ba79e40 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mickey Mouse - Land of Illusion (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Mickey Mouse - Legend of Illusion (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mickey Mouse - Legend of Illusion (UE) [!].sms new file mode 100644 index 0000000..9a62261 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mickey Mouse - Legend of Illusion (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Micro Machines (Europe).sms b/Parsons.Steamdeck/ROMS/Micro Machines (Europe).sms new file mode 100644 index 0000000..ff3ce6c Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Micro Machines (Europe).sms differ diff --git a/Parsons.Steamdeck/ROMS/Mortal Kombat (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mortal Kombat (UE) [!].sms new file mode 100644 index 0000000..581a4af Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mortal Kombat (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Mortal Kombat 2 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mortal Kombat 2 (UE) [!].sms new file mode 100644 index 0000000..b34cacb Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mortal Kombat 2 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Mortal Kombat 3 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Mortal Kombat 3 (UE) [!].sms new file mode 100644 index 0000000..3b1f405 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Mortal Kombat 3 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Olympic Gold - Barcelona '92 (Europe).sms b/Parsons.Steamdeck/ROMS/Olympic Gold - Barcelona '92 (Europe).sms new file mode 100644 index 0000000..41827e8 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Olympic Gold - Barcelona '92 (Europe).sms differ diff --git a/Parsons.Steamdeck/ROMS/OutRun (USA).sms b/Parsons.Steamdeck/ROMS/OutRun (USA).sms new file mode 100644 index 0000000..c877842 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/OutRun (USA).sms differ diff --git a/Parsons.Steamdeck/ROMS/Paperboy (UE) [!].sms b/Parsons.Steamdeck/ROMS/Paperboy (UE) [!].sms new file mode 100644 index 0000000..10e0768 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Paperboy (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Parlour Games (UE) [!].sms b/Parsons.Steamdeck/ROMS/Parlour Games (UE) [!].sms new file mode 100644 index 0000000..c6bf968 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Parlour Games (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Phantasy Star (UE) [!].sms b/Parsons.Steamdeck/ROMS/Phantasy Star (UE) [!].sms new file mode 100644 index 0000000..5d58846 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Phantasy Star (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Populous (UE) [!].sms b/Parsons.Steamdeck/ROMS/Populous (UE) [!].sms new file mode 100644 index 0000000..4de3d0b Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Populous (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Prince of Persia (Europe).sms b/Parsons.Steamdeck/ROMS/Prince of Persia (Europe).sms new file mode 100644 index 0000000..05c2670 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Prince of Persia (Europe).sms differ diff --git a/Parsons.Steamdeck/ROMS/Psychic World (UE) [!].sms b/Parsons.Steamdeck/ROMS/Psychic World (UE) [!].sms new file mode 100644 index 0000000..842f983 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Psychic World (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Psycho Fox (UE) [!].sms b/Parsons.Steamdeck/ROMS/Psycho Fox (UE) [!].sms new file mode 100644 index 0000000..0071def Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Psycho Fox (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/R-Type.sms b/Parsons.Steamdeck/ROMS/R-Type.sms new file mode 100644 index 0000000..a3dca4f Binary files /dev/null and b/Parsons.Steamdeck/ROMS/R-Type.sms differ diff --git a/Parsons.Steamdeck/ROMS/Road Rash (UE) [!].sms b/Parsons.Steamdeck/ROMS/Road Rash (UE) [!].sms new file mode 100644 index 0000000..da3cb7e Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Road Rash (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/SMSTestSuite.sms b/Parsons.Steamdeck/ROMS/SMSTestSuite.sms new file mode 100644 index 0000000..9105845 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/SMSTestSuite.sms differ diff --git a/Parsons.Steamdeck/ROMS/Shadow of the Beast (UE) [!].sms b/Parsons.Steamdeck/ROMS/Shadow of the Beast (UE) [!].sms new file mode 100644 index 0000000..0e36042 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Shadow of the Beast (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Smash TV (UE) [!].sms b/Parsons.Steamdeck/ROMS/Smash TV (UE) [!].sms new file mode 100644 index 0000000..cc44ef0 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Smash TV (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Sonic 1 GG.gg b/Parsons.Steamdeck/ROMS/Sonic 1 GG.gg new file mode 100644 index 0000000..e4c92e5 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic 1 GG.gg differ diff --git a/Parsons.Steamdeck/ROMS/Sonic 2.sms b/Parsons.Steamdeck/ROMS/Sonic 2.sms new file mode 100644 index 0000000..be84f50 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic 2.sms differ diff --git a/Parsons.Steamdeck/ROMS/Sonic Chaos (UE) [!].sms b/Parsons.Steamdeck/ROMS/Sonic Chaos (UE) [!].sms new file mode 100644 index 0000000..9fee921 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic Chaos (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Sonic The Hedgehog - Triple Trouble (USA, Europe, Brazil).gg b/Parsons.Steamdeck/ROMS/Sonic The Hedgehog - Triple Trouble (USA, Europe, Brazil).gg new file mode 100644 index 0000000..d7ee99d Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic The Hedgehog - Triple Trouble (USA, Europe, Brazil).gg differ diff --git a/Parsons.Steamdeck/ROMS/Sonic The Hedgehog 2 (World).gg b/Parsons.Steamdeck/ROMS/Sonic The Hedgehog 2 (World).gg new file mode 100644 index 0000000..6b60690 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic The Hedgehog 2 (World).gg differ diff --git a/Parsons.Steamdeck/ROMS/Sonic.sms b/Parsons.Steamdeck/ROMS/Sonic.sms new file mode 100644 index 0000000..db328b5 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Sonic.sms differ diff --git a/Parsons.Steamdeck/ROMS/Space Harrier (USA).sms b/Parsons.Steamdeck/ROMS/Space Harrier (USA).sms new file mode 100644 index 0000000..9b99225 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Space Harrier (USA).sms differ diff --git a/Parsons.Steamdeck/ROMS/Speedball (UE) (Virgin) [!].sms b/Parsons.Steamdeck/ROMS/Speedball (UE) (Virgin) [!].sms new file mode 100644 index 0000000..c7b97c4 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Speedball (UE) (Virgin) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Star Wars (UE) [!].sms b/Parsons.Steamdeck/ROMS/Star Wars (UE) [!].sms new file mode 100644 index 0000000..236645f Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Star Wars (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Street Fighter 2 (Brazil) [!].sms b/Parsons.Steamdeck/ROMS/Street Fighter 2 (Brazil) [!].sms new file mode 100644 index 0000000..7a93dcf Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Street Fighter 2 (Brazil) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Streets of Rage (UE) [!].sms b/Parsons.Steamdeck/ROMS/Streets of Rage (UE) [!].sms new file mode 100644 index 0000000..08428c8 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Streets of Rage (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Streets of Rage 2 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Streets of Rage 2 (UE) [!].sms new file mode 100644 index 0000000..55c4196 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Streets of Rage 2 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Summer Games (UE) [!].sms b/Parsons.Steamdeck/ROMS/Summer Games (UE) [!].sms new file mode 100644 index 0000000..1ddc457 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Summer Games (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Super Kick Off (UE) [!].sms b/Parsons.Steamdeck/ROMS/Super Kick Off (UE) [!].sms new file mode 100644 index 0000000..a7d680d Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Super Kick Off (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Super Monaco GP (UE) [!].sms b/Parsons.Steamdeck/ROMS/Super Monaco GP (UE) [!].sms new file mode 100644 index 0000000..74dfdec Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Super Monaco GP (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Super Monaco GP 2 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Super Monaco GP 2 (UE) [!].sms new file mode 100644 index 0000000..5539794 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Super Monaco GP 2 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Super Tennis (UE) [!].sms b/Parsons.Steamdeck/ROMS/Super Tennis (UE) [!].sms new file mode 100644 index 0000000..9545ce6 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Super Tennis (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Terminator 2 - Judgment Day (UE) [!].sms b/Parsons.Steamdeck/ROMS/Terminator 2 - Judgment Day (UE) [!].sms new file mode 100644 index 0000000..fb86ec9 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Terminator 2 - Judgment Day (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Terminator, The (UE) [!].sms b/Parsons.Steamdeck/ROMS/Terminator, The (UE) [!].sms new file mode 100644 index 0000000..a038126 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Terminator, The (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Trans-Bot (UE).sms b/Parsons.Steamdeck/ROMS/Trans-Bot (UE).sms new file mode 100644 index 0000000..389f91e Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Trans-Bot (UE).sms differ diff --git a/Parsons.Steamdeck/ROMS/Winter Olympics '94 (UE) [!].sms b/Parsons.Steamdeck/ROMS/Winter Olympics '94 (UE) [!].sms new file mode 100644 index 0000000..dfc3426 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Winter Olympics '94 (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Wonder Boy (UE) [!].sms b/Parsons.Steamdeck/ROMS/Wonder Boy (UE) [!].sms new file mode 100644 index 0000000..479f88a Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Wonder Boy (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Wonder Boy 2 - Wonderboy in Monsterland (UE) [!].sms b/Parsons.Steamdeck/ROMS/Wonder Boy 2 - Wonderboy in Monsterland (UE) [!].sms new file mode 100644 index 0000000..39c351b Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Wonder Boy 2 - Wonderboy in Monsterland (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/Wonder Boy 3 - The Dragon's Trap (UE) [!].sms b/Parsons.Steamdeck/ROMS/Wonder Boy 3 - The Dragon's Trap (UE) [!].sms new file mode 100644 index 0000000..ae03c6a Binary files /dev/null and b/Parsons.Steamdeck/ROMS/Wonder Boy 3 - The Dragon's Trap (UE) [!].sms differ diff --git a/Parsons.Steamdeck/ROMS/zexall.sms b/Parsons.Steamdeck/ROMS/zexall.sms new file mode 100644 index 0000000..906d615 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/zexall.sms differ diff --git a/Parsons.Steamdeck/ROMS/zexdoc.sav b/Parsons.Steamdeck/ROMS/zexdoc.sav new file mode 100644 index 0000000..8499111 --- /dev/null +++ b/Parsons.Steamdeck/ROMS/zexdoc.sav @@ -0,0 +1,10 @@ +Z80 Instruction Exerciser 0.21 +Documented flags version +Outputs: +* SDSC Debug Console +* Emulicious Debug Console +* TMS9918 Text Mode +* SRAM + +SCF/CCF tests: + \ No newline at end of file diff --git a/Parsons.Steamdeck/ROMS/zexdoc.sms b/Parsons.Steamdeck/ROMS/zexdoc.sms new file mode 100644 index 0000000..8440311 Binary files /dev/null and b/Parsons.Steamdeck/ROMS/zexdoc.sms differ diff --git a/Parsons.Steamdeck/RaylibAudioPlayer.cs b/Parsons.Steamdeck/RaylibAudioPlayer.cs index 9eea779..523bd7c 100644 --- a/Parsons.Steamdeck/RaylibAudioPlayer.cs +++ b/Parsons.Steamdeck/RaylibAudioPlayer.cs @@ -7,15 +7,24 @@ namespace Parsons.SteamDeck { private ConcurrentQueue _sampleQueue = new ConcurrentQueue(); + // 4096 samples provides a perfect ~90ms safety buffer + private const int MaxBufferSamples = 4096; + public void AddSample(float sample) { - // Queue the sample from the emulator core _sampleQueue.Enqueue(sample); + + // THE FIX: If the CPU outpaces the soundcard, drop the OLDEST sample! + // This guarantees we never fall behind and the audio stays perfectly synced. + if (_sampleQueue.Count > MaxBufferSamples) + { + _sampleQueue.TryDequeue(out _); + } } + // Grab absolutely everything we generated this frame public float[] GetQueuedSamples() { - // Pull all pending samples out of the queue to send to the sound card int count = _sampleQueue.Count; float[] buffer = new float[count]; for (int i = 0; i < count; i++)