Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify SGB related UIs and make it possible to use SGB under Gambatte link #3635

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
dd14f8e
merge SGB into a mode option of Gambatte
Fortranm Jun 18, 2022
5f95a93
merge the core choices for SGB
Fortranm Jun 18, 2022
f8b294f
GBL compatibility
Fortranm Jun 19, 2022
eecee30
rename SGB mode to SGB2 for Gambatte and fix BSNES initialization
Fortranm Jun 19, 2022
dd6abbc
SGB border in GBL
Fortranm Jun 21, 2022
7dd40dd
adjust sgb core detection
Fortranm Jun 22, 2022
511f48d
reformat controller button naming
Fortranm Jun 30, 2022
2e6f59b
adjust for 2.9
Fortranm Apr 16, 2023
2e534a9
adjust for 2.9 again
Fortranm Apr 16, 2023
ff268f3
revert changes to BSNES CoreConstructor
Fortranm Jun 23, 2023
c183e6e
one Player tab per SNES controller for SGB
Fortranm Jun 23, 2023
0a3a727
idiomatic rephrase for showAnyBorder
Fortranm Jul 12, 2023
ef87a48
no dummy for CreateSGBVideoBuffer
Fortranm Jul 12, 2023
c0ff230
fix SGB conversion in LsmvImport
Fortranm Jul 13, 2023
b2a4720
add legacy BSNES option for (S)GB
Fortranm Jul 13, 2023
e8aa24a
minor cosmetic changes
Morilli May 29, 2024
3786258
Fix `.vbm` importer when Gambatte isn't the preferred GB core
YoshiRulz May 30, 2024
0f5cc8d
Fix button mapping spaghetti
YoshiRulz May 30, 2024
b910c38
Code style nitpicks
YoshiRulz May 30, 2024
864ee92
minor cleanups in Gambatte.cs
Morilli Jun 19, 2024
c68e9db
Remove special SGB handling and mark bsnes* as GB/GBC cores
Morilli Jun 19, 2024
c56f047
remove SGB from CorePickerUIData
Fortranm Jul 1, 2024
f148272
Un-revert submodule pull
YoshiRulz Jul 1, 2024
cddb113
Un-revert other submodule pulls
YoshiRulz Jul 1, 2024
02746ef
fix the crash from Toggle Link Connection
Fortranm Jul 2, 2024
06496c6
remove inaccurate description of how Auto works for console
Fortranm Jul 4, 2024
3e401db
Merge branch 'master' into SGB-link
Fortranm Jul 4, 2024
0e32693
Remove unused import
YoshiRulz Jul 5, 2024
b187651
Merge branch 'master' into SGB-link
Fortranm Jan 8, 2025
a43e047
do not change overall GUI
Fortranm Feb 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/BizHawk.Client.Common/RomLoader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
Expand Down
2 changes: 1 addition & 1 deletion src/BizHawk.Client.Common/config/Config.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

Expand Down
3 changes: 1 addition & 2 deletions src/BizHawk.Client.Common/movie/import/LsmvImport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ protected override void RunImport()
break;
case "sgb_ntsc":
case "sgb_pal":
platform = VSystemID.Raw.SNES;
Config.GbAsSgb = true;
platform = VSystemID.Raw.SGB;
break;
}

Expand Down
16 changes: 12 additions & 4 deletions src/BizHawk.Client.Common/movie/import/VbmImport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ recording time in Unix epoch format
Result.Movie.HeaderEntries.Add("IsCGBMode", "1");
}

var finalCoreName = Config.PreferredCores[VSystemID.Raw.GB];
if (isSGB)
{
Result.Errors.Add("SGB imports are not currently supported");
platform = VSystemID.Raw.SGB;
if (finalCoreName is not CoreNames.Gambatte)
{
Result.Warnings.Add($"{finalCoreName} doesn't support SGB; will use {CoreNames.Gambatte}");
finalCoreName = CoreNames.Gambatte;
}
}

Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
Expand Down Expand Up @@ -277,13 +283,15 @@ A stream of 2-byte bitvectors which indicate which buttons are pressed at each p
}
else
{
Result.Movie.HeaderEntries[HeaderKeys.Core] = Config.PreferredCores[VSystemID.Raw.GB];
switch (Config.PreferredCores[VSystemID.Raw.GB])
Result.Movie.HeaderEntries[HeaderKeys.Core] = finalCoreName;
switch (finalCoreName)
{
case CoreNames.Gambatte:
Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(new Gameboy.GambatteSyncSettings
{
ConsoleMode = is_GBC ? Gameboy.GambatteSyncSettings.ConsoleModeType.GBC : Gameboy.GambatteSyncSettings.ConsoleModeType.GB,
ConsoleMode = isSGB
? Gameboy.GambatteSyncSettings.ConsoleModeType.SGB2
: is_GBC ? Gameboy.GambatteSyncSettings.ConsoleModeType.GBC : Gameboy.GambatteSyncSettings.ConsoleModeType.GB,
});
break;
case CoreNames.GbHawk:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,12 @@ public enum ConsoleModeType
Auto,
GB,
GBC,
GBA
GBA,
SGB2,
}

[DisplayName("Console Mode")]
[Description("Pick which console to run, 'Auto' chooses from ROM header; 'GB', 'GBC', and 'GBA' chooses the respective system. Does nothing in SGB mode.")]
[Description("Picks which console to emulate. Forced to be 'SGB2' when 'GB in SGB' is checked.")]
[DefaultValue(ConsoleModeType.Auto)]
public ConsoleModeType ConsoleMode { get; set; }

Expand Down
18 changes: 10 additions & 8 deletions src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public Gameboy(CoreComm comm, IGameInfo game, byte[] file, GambatteSettings sett

var flags = LibGambatte.LoadFlags.READONLY_SAV;

if (game.System == VSystemID.Raw.SGB)
{
_syncSettings.ConsoleMode = GambatteSyncSettings.ConsoleModeType.SGB2;
}

switch (_syncSettings.ConsoleMode)
{
case GambatteSyncSettings.ConsoleModeType.GB:
Expand All @@ -57,6 +62,10 @@ public Gameboy(CoreComm comm, IGameInfo game, byte[] file, GambatteSettings sett
case GambatteSyncSettings.ConsoleModeType.GBA:
flags |= LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG;
break;
case GambatteSyncSettings.ConsoleModeType.SGB2:
flags |= LibGambatte.LoadFlags.SGB_MODE;
IsSgb = true;
break;
case GambatteSyncSettings.ConsoleModeType.Auto:
if (game.System == VSystemID.Raw.GBC)
flags |= LibGambatte.LoadFlags.CGB_MODE;
Expand All @@ -65,13 +74,6 @@ public Gameboy(CoreComm comm, IGameInfo game, byte[] file, GambatteSettings sett
throw new InvalidOperationException();
}

if (game.System == VSystemID.Raw.SGB)
{
flags &= ~(LibGambatte.LoadFlags.CGB_MODE | LibGambatte.LoadFlags.GBA_FLAG);
flags |= LibGambatte.LoadFlags.SGB_MODE;
IsSgb = true;
}

IsCgb = (flags & LibGambatte.LoadFlags.CGB_MODE) == LibGambatte.LoadFlags.CGB_MODE;

bool ForceBios()
Expand Down Expand Up @@ -647,7 +649,7 @@ public IGPUMemoryAreas LockGPU()
Vram = _vram,
Oam = _oam,
Sppal = _sppal,
Bgpal = _bgpal,
Bgpal = _bgpal,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common;

namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
Expand All @@ -17,16 +18,26 @@ public bool FrameAdvance(IController controller, bool render, bool rendersound =

foreach (var s in GBLinkController.BoolButtons)
{
if (controller.IsPressed(s))
if (!controller.IsPressed(s)) continue;
CasualPokePlayer marked this conversation as resolved.
Show resolved Hide resolved
if (s[0] is not 'P') continue;
var iSpace = s.IndexOf(' ');
var playerNum = int.Parse(s.Substring(startIndex: 1, length: iSpace - 1));
var consoleNum = 0;
var isSGB = false;
while (consoleNum < _numCores)
{
for (int i = 0; i < _numCores; i++)
{
if (s.Contains($"P{i + 1} "))
{
_linkedConts[i].Set(s.Replace($"P{i + 1} ", ""));
}
}
isSGB = IsSgb(consoleNum);
var playersForConsole = isSGB ? 4 : 1;
if (playerNum <= playersForConsole) break;
playerNum -= playersForConsole;
consoleNum++;
}
//TODO rather than this string manipulation, could construct a lookup ahead of time
_linkedConts[consoleNum].Set(s.EndsWithOrdinal("Power")
? "Power"
: isSGB
? $"P{playerNum} {s.Substring(startIndex: iSpace + 1)}"
: s.Substring(startIndex: iSpace + 1));
}

bool linkDiscoSignalNew = controller.IsPressed("Toggle Link Connection");
Expand Down Expand Up @@ -66,10 +77,11 @@ public bool FrameAdvance(IController controller, bool render, bool rendersound =

unsafe
{
fixed (int* fbuff = &FrameBuffer[0])
fixed (int* fbuff = &FrameBuffer[0], svbuff = SgbVideoBuffer)
{
// use pitch to have both cores write to the same frame buffer, interleaved
int Pitch = 160 * _numCores;
int sgbPitch = 256 * _numCores;

fixed (short* sbuff = &SoundBuffer[0])
{
Expand Down Expand Up @@ -102,6 +114,27 @@ public bool FrameAdvance(IController controller, bool render, bool rendersound =
{
Array.Copy(FrameBuffer, (i * 160) + (j * Pitch), VideoBuffer, (i * 160) + (j * Pitch), 160);
}
if (IsAnySgb)
{
// all SGB borders will be displayed when any of them has the option enabled
if (IsSgb(i))
{
if (LibGambatte.gambatte_updatescreenborder(
_linkedCores[i].GambatteState,
svbuff + (i * 256),
sgbPitch) is not 0)
{
throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_updatescreenborder)}() returned non-zero (border error???)");
}
}
else
{
for (int j = 0; j < 144; j++)
{
Array.Copy(FrameBuffer, (i * 160) + (j * Pitch), SgbVideoBuffer, (i * 256 + 48) + (40 + j) * sgbPitch, 160);
}
}
}
}

n[i] += (int)nsamp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
public partial class GambatteLink : IVideoProvider
{
public int VirtualWidth => 160 * _numCores;
public int VirtualHeight => 144;
public int BufferWidth => 160 * _numCores;
public int BufferHeight => 144;
public int VirtualWidth
=> (ShowAnyBorder() ? 256 : 160) * _numCores;

public int VirtualHeight
=> ShowAnyBorder() ? 224 : 144;

public int BufferWidth
=> VirtualWidth;

public int BufferHeight
=> VirtualHeight;

public int VsyncNumerator => _linkedCores[P1].VsyncNumerator;

Expand All @@ -17,19 +24,24 @@ public partial class GambatteLink : IVideoProvider

private readonly int[] FrameBuffer;

public int[] GetVideoBuffer() => VideoBuffer;
public int[] GetVideoBuffer()
=> ShowAnyBorder() ? SgbVideoBuffer : VideoBuffer;

private readonly int[] VideoBuffer;


private readonly int[] SgbVideoBuffer;

private int[] CreateVideoBuffer()
{
var b = new int[BufferWidth * BufferHeight];
var b = new int[160 * _numCores * 144];
for (int i = 0; i < b.Length; i++)
{
b[i] = -1; // GB/C screen is disabled on bootup, so it always starts as white, not black
}
return b;
}

private int[] CreateSGBVideoBuffer()
=> IsAnySgb ? new int[256 * _numCores * 224] : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public GambatteLink(CoreLoadParameters<GambatteLinkSettings, GambatteLinkSyncSet
_linkedCores[i] = new Gameboy(lp.Comm, lp.Roms[i].Game, lp.Roms[i].RomData, _settings._linkedSettings[i], _syncSettings._linkedSyncSettings[i], lp.DeterministicEmulationRequested);
_linkedCores[i].ConnectInputCallbackSystem(_inputCallbacks);
_linkedCores[i].ConnectMemoryCallbackSystem(_memoryCallbacks, i);
_linkedConts[i] = new SaveController(Gameboy.CreateControllerDefinition(sgb: false, sub: false, tilt: false, rumble: false, remote: false));
IsAnySgb |= IsSgb(i);
_linkedConts[i] = new SaveController(Gameboy.CreateControllerDefinition(sgb: IsSgb(i), sub: false, tilt: false, rumble: false, remote: false));
_linkedBlips[i] = new BlipBuffer(1024);
_linkedBlips[i].SetRates(2097152 * 2, 44100);
_linkedOverflow[i] = 0;
Expand All @@ -66,6 +67,7 @@ public GambatteLink(CoreLoadParameters<GambatteLinkSettings, GambatteLinkSyncSet

FrameBuffer = CreateVideoBuffer();
VideoBuffer = CreateVideoBuffer();
SgbVideoBuffer = CreateSGBVideoBuffer();

GBLinkController = CreateControllerDefinition();

Expand Down Expand Up @@ -142,12 +144,23 @@ public IGameboyCommon First

private ControllerDefinition CreateControllerDefinition()
{
static void AddGBButtonsForPlayer(int p, ControllerDefinition ret)
{
var pfx = $"P{p} ";
ret.BoolButtons.AddRange(new[] { "Up", "Down", "Left", "Right", "A", "B", "Select", "Start" }
.Select(s => pfx + s));
}
ControllerDefinition ret = new($"GB Link {_numCores}x Controller");
for (int i = 0; i < _numCores; i++)
for (int i = 0, p = 1; i < _numCores; i++)
{
ret.BoolButtons.AddRange(
new[] { "Up", "Down", "Left", "Right", "A", "B", "Select", "Start", "Power" }
.Select(s => $"P{i + 1} {s}"));
AddGBButtonsForPlayer(p, ret);
ret.BoolButtons.Add($"P{p} Power");
p++;
if (IsSgb(i))
{
// add 3 more gamepads without a Power button
for (int e = p + 3; p < e; p++) AddGBButtonsForPlayer(p, ret);
}
}
ret.BoolButtons.Add("Toggle Link Connection");
if (_numCores > 2)
Expand All @@ -158,6 +171,20 @@ private ControllerDefinition CreateControllerDefinition()
return ret.MakeImmutable();
}

private bool IsSgb(int i)
=> _linkedCores[i].IsSgb;

public bool IsAnySgb { get; private set; }

private bool ShowBorder(int i)
=> IsSgb(i) && _settings._linkedSettings[i].ShowBorder;

public bool ShowAnyBorder()
{
for (var i = 0; i < _numCores; i++) if (ShowBorder(i)) return true;
return false;
}

private const int P1 = 0;
private const int P2 = 1;
private const int P3 = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ public enum CDLog_Flags : int

[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_updatescreenborder(IntPtr core, int[] videobuf, int pitch);
[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern unsafe int gambatte_updatescreenborder(IntPtr core, int* videobuf, int pitch);

[DllImport("libgambatte", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_generatesgbsamples(IntPtr core, short[] soundbuf, out uint samples);
Expand Down