Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": "Run DesktopGL platform",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "buildDesktopGL",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Platforms/ZXBox.Monogame/bin/Debug/net8.0/ZXBox.Monogame.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
"console": "internalConsole",
"stopAtEntry": false
}
]
}
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"files.exclude": {
"**/bin": true,
"**/obj": true
}
}
15 changes: 15 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "buildDesktopGL",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Platforms/ZXBox.Monogame/ZXBox.Monogame.csproj"
],
"problemMatcher": "$msCompile"
}
]
}
144 changes: 72 additions & 72 deletions Platforms/ZXBox.Blazor/Components/EmulatorComponent.razor.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using Microsoft.JSInterop.WebAssembly;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
using ZXBox.Core.Hardware.Input;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using Microsoft.JSInterop.WebAssembly;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Timers;
using ZXBox.Core.Hardware.Input;
using ZXBox.Hardware.Input;
using ZXBox.Hardware.Input.Joystick;
using ZXBox.Hardware.Output;
using ZXBox.Snapshot;
using ZXBox.Hardware.Output;
using ZXBox.Snapshot;

namespace ZXBox.Blazor.Pages
{
public partial class EmulatorComponentModel : ComponentBase, IAsyncDisposable
Expand Down Expand Up @@ -50,8 +50,8 @@ public ZXSpectrum GetZXSpectrum(RomEnum rom)
public void StartZXSpectrum(RomEnum rom)
{
speccy = GetZXSpectrum(rom);
speccy.InputHardware.Add(Keyboard);
speccy.InputHardware.Add(Keyboard);

kempston = new Kempston();
speccy.InputHardware.Add(kempston);
//48000 samples per second, 50 frames per second (20ms per frame) Mono
Expand All @@ -67,26 +67,26 @@ public void StartZXSpectrum(RomEnum rom)
public string TapeName { get; set; }
public async Task HandleFileSelected(InputFileChangeEventArgs args)
{
if (args.File.Name.ToLower().EndsWith(".tap"))
{
//Load the tape
var file = args.File;
var ms = new MemoryStream();
if (args.File.Name.ToLower().EndsWith(".tap"))
{
//Load the tape
var file = args.File;
var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
tapePlayer.LoadTape(ms.ToArray());
TapeName = Path.GetFileNameWithoutExtension(args.File.Name);
}
else
{
var file = args.File;
var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
var handler = FileFormatFactory.GetSnapShotHandler(file.Name);
var bytes = ms.ToArray();
handler.LoadSnapshot(bytes, speccy);
}
else
{
var file = args.File;
var ms = new MemoryStream();

await file.OpenReadStream().CopyToAsync(ms);

var handler = FileFormatFactory.GetSnapShotHandler(file.Name);
var bytes = ms.ToArray();
handler.LoadSnapshot(bytes, speccy);
}
}
[Inject]
HttpClient httpClient { get; set; }
Expand All @@ -104,37 +104,37 @@ public async Task LoadGame(string filename, string instructions)

private async void GameLoop_Elapsed(object sender, ElapsedEventArgs e)
{
Stopwatch sw = new Stopwatch();
//Get gamepads
kempston.Gamepads = await GamePadList.GetGamepadsAsync();
//Run JavaScriptInterop to find the currently pressed buttons
Stopwatch sw = new Stopwatch();

//Get gamepads
kempston.Gamepads = await GamePadList.GetGamepadsAsync();
//Run JavaScriptInterop to find the currently pressed buttons
Keyboard.KeyBuffer = await JSRuntime.InvokeAsync<List<string>>("getKeyStatus");
sw.Start();
speccy.DoIntructions(69888);
speccy.DoInstructions(69888);

beeper.GenerateSound();
await BufferSound();
Paint();
sw.Stop();
if (tapePlayer != null && tapePlayer.IsPlaying)
{
TapeStopped = false;
PercentLoaded = ((Convert.ToDouble(tapePlayer.CurrentTstate) / Convert.ToDouble(tapePlayer.TotalTstates)) * 100);
await InvokeAsync(() => StateHasChanged());
await BufferSound();

Paint();
sw.Stop();
if (tapePlayer != null && tapePlayer.IsPlaying)
{
TapeStopped = false;
PercentLoaded = ((Convert.ToDouble(tapePlayer.CurrentTstate) / Convert.ToDouble(tapePlayer.TotalTstates)) * 100);
await InvokeAsync(() => StateHasChanged());
}
if (!TapeStopped && !tapePlayer.IsPlaying)
{
TapeStopped = true;
await InvokeAsync(() => StateHasChanged());
if (!TapeStopped && !tapePlayer.IsPlaying)
{
TapeStopped = true;
await InvokeAsync(() => StateHasChanged());
}
}
bool TapeStopped = false;
GCHandle gchsound;
IntPtr pinnedsound;
WebAssemblyJSRuntime mono;
byte[] soundbytes;
}
bool TapeStopped = false;
GCHandle gchsound;
IntPtr pinnedsound;
WebAssemblyJSRuntime mono;
byte[] soundbytes;
protected async Task BufferSound()
{
soundbytes = beeper.GetSoundBuffer();
Expand All @@ -154,7 +154,7 @@ protected async override void OnAfterRender(bool firstRender)
base.OnAfterRender(firstRender);
}

GCHandle gchscreen;
GCHandle gchscreen;
IntPtr pinnedscreen;
//uint[] screen = new uint[68672]; //Height * width (256+20+20)*(192+20+20)
public async void Paint()
Expand All @@ -169,20 +169,20 @@ public async void Paint()
flashcounter--;
}

var screen = speccy.GetScreenInUint(flash);
//Allocate memory
var screen = speccy.GetScreenInUint(flash);

//Allocate memory
gchscreen = GCHandle.Alloc(screen, GCHandleType.Pinned);
pinnedscreen = gchscreen.AddrOfPinnedObject();
mono.InvokeUnmarshalled<IntPtr, string>("PaintCanvas", pinnedscreen);
gchscreen.Free();
}
public ValueTask DisposeAsync()
{
gameLoop.Stop();
gameLoop.Dispose();
return ValueTask.CompletedTask;
}
}

public ValueTask DisposeAsync()
{
gameLoop.Stop();
gameLoop.Dispose();
return ValueTask.CompletedTask;
}
}
}
8 changes: 5 additions & 3 deletions Platforms/ZXBox.Blazor/Hardware/Kempston.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ZXBox.Hardware.Input.Joystick
/// <summary>
/// The Kempston joystick interface differs from the other common types in that it does not map to the ZX Spectrum keyboard directly. Rather, it maps to a particular hardware port (0x1f) and support must therefore be 'built-in' to the software. Fortunately, the Kempston joystick interface was enormously popular, and support was very easy to provide, making Kempston control a common, almost standard, feature of most games.
/// Assuming an appropriate interface is attached, reading from port 0x1f returns the current state of the Kempston joystick in the form 000FUDLR, with active bits high.
/// � www.worldofspectrum.com
/// � www.worldofspectrum.com
/// </summary>

public class Kempston:IInput
Expand All @@ -38,9 +38,11 @@ public bool Enabled

#region IInput Members

public int Input(int Port,int tact)
public void AddTStates(int tstates) { }

public byte Input(ushort Port,int tact)
{
int returnvalue = 0xFF;
byte returnvalue = 0xFF;
if ((Port &0xff) == 0x1f)
{
returnvalue = 0x0;
Expand Down
11 changes: 6 additions & 5 deletions Platforms/ZXBox.Blazor/Hardware/Keyboard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public bool GetKeyStatus(string key)
return KeyBuffer.Any(k => k.ToLower() == key.ToLower());
}

public int Input(int Port, int tstates)
public void AddTStates(int tstates) { }

public byte Input(ushort Port, int tstates)
{

if ((Port & 0xFF) == 0xFE)
Expand Down Expand Up @@ -57,16 +59,15 @@ public int Input(int Port, int tstates)
right = true;
}

bool symbol = false;
int returnvalue = 0xFF;
var returnvalue = 0xFF;

//Special cace for any key
if (((Port >> 8) & 0xFF) == 0x01 || ((Port >> 8) & 0xFF) == 0x00 || ((Port >> 8) & 0xFF) == 0x02)
{ //Check for any key including joy, we might need to add more joy buttons later on

if (KeyBuffer.Count() > 0)
{
return returnvalue &= ~1;
return (byte)(returnvalue &= ~1);
}

}
Expand Down Expand Up @@ -197,7 +198,7 @@ public int Input(int Port, int tstates)
break;
}

return returnvalue;
return (byte)returnvalue;
}
return 0xFF;
}
Expand Down
8 changes: 4 additions & 4 deletions Platforms/ZXBox.Blazor/ZXBox.Blazor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-preview.6.23329.11" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-preview.6.23329.11" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" PrivateAssets="all" />

<PackageReference Include="System.Net.Http.Json" Version="8.0.0-preview.6.23329.7" />
<PackageReference Include="Toolbelt.Blazor.Gamepad" Version="8.0.0.1" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
<PackageReference Include="Toolbelt.Blazor.Gamepad" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
20 changes: 20 additions & 0 deletions Platforms/ZXBox.Monogame/Hardware/JoystickFake.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using ZXBox.Hardware.Interfaces;

namespace ZXBox.Monogame.Hardware
{
public class JoystickFake : ZXBox.Hardware.Interfaces.IInput
{
public byte Input(ushort Port, int tact)
{
byte returnvalue = 0xFF;
if ((Port & 0xff) == 0x1f)
{
returnvalue = 0x0;
}
return returnvalue;
}

public void AddTStates(int tstates) { }
}
}
Loading