-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
115 lines (94 loc) · 3.33 KB
/
Program.cs
File metadata and controls
115 lines (94 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using Raylib_cs;
using System.Numerics;
namespace SharpBoy;
public class Program
{
private static int physicalScreenWidth = 800;
private static int physicalScreenHeight = 600;
//NOTE(Simon): The Gameboy runs at 4MiHz (4 * 1024 * 1024)
private static int FPS = 60;
private static int hz = 1;
private static int khz = hz * 1024;
private static int mhz = khz * 1024;
private static bool[] input = new bool[8];
private static KeyboardKey[] inputMap = {
KeyboardKey.KEY_RIGHT, //Right
KeyboardKey.KEY_LEFT, //Left
KeyboardKey.KEY_UP, //Up
KeyboardKey.KEY_DOWN, //Down
KeyboardKey.KEY_A, //A
KeyboardKey.KEY_B, //B
KeyboardKey.KEY_BACKSPACE, //Select
KeyboardKey.KEY_ENTER, //Start
};
public static void Main(string[] args)
{
var emulator = new Emulator();
string path = @"C:\Users\Simon\Downloads\Tetris\Tetris.gb";
//string path = @"C:\Users\Simon\Downloads\DMGTestRoms\acceptance\instr\daa.gb";
emulator.LoadProgram(ReadProgramFromDisk(path));
Raylib.SetConfigFlags(ConfigFlags.FLAG_WINDOW_RESIZABLE);
Raylib.InitWindow(physicalScreenWidth, physicalScreenHeight, "SharpBoy");
Raylib.SetTargetFPS(FPS);
var target = Raylib.LoadRenderTexture(Emulator.screenWidth, Emulator.screenHeight);
target.texture.format = PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8;
Raylib.SetTextureWrap(target.texture, TextureWrap.TEXTURE_WRAP_CLAMP);
Raylib.SetTextureFilter(target.texture, TextureFilter.TEXTURE_FILTER_POINT);
float scale = CalculateTextureScale();
//NOTE(Simon): We lose some precision due to integer division. But at 60fps that works out to being 80ms slower per day of runtime
int cyclesPerFrame = 1 * mhz / 60;
while (!Raylib.WindowShouldClose())
{
UpdateInput();
emulator.Simulate(input, cyclesPerFrame);
if (Raylib.IsWindowResized())
{
scale = CalculateTextureScale();
}
Raylib.BeginTextureMode(target);
{
unsafe
{
fixed (void* p = emulator.screen)
{
Raylib.UpdateTexture(target.texture, p);
}
}
}
Raylib.EndTextureMode();
Raylib.BeginDrawing();
{
Raylib.ClearBackground(Color.BLACK);
var sourceRect = new Rectangle(0, 0, target.texture.width, -target.texture.height);
var destRect = new Rectangle(Raylib.GetScreenWidth() - (Emulator.screenWidth * scale) * .5f, Raylib.GetScreenHeight() - (Emulator.screenHeight * scale) * .5f, Emulator.screenWidth * scale, Emulator.screenHeight * scale);
Raylib.DrawTexturePro(target.texture, sourceRect, destRect, new Vector2(Raylib.GetScreenWidth() / 2f, Raylib.GetScreenHeight() / 2f), 0, Color.WHITE);
}
Raylib.EndDrawing();
}
Raylib.CloseWindow();
}
public static void UpdateInput()
{
for (int i = 0; i < inputMap.Length; i++)
{
var key = inputMap[i];
if (Raylib.IsKeyPressed(key))
{
input[i] = true;
//TODO(Simon): Handle interrupts???
}
}
for (int i = 0; i < inputMap.Length; i++)
{
if (Raylib.IsKeyReleased(inputMap[i]))
{
input[i] = false;
}
}
}
private static float CalculateTextureScale() => Math.Min(Raylib.GetScreenWidth() / (float)Emulator.screenWidth, Raylib.GetScreenHeight() / (float)Emulator.screenHeight);
public static byte[] ReadProgramFromDisk(string path)
{
return File.ReadAllBytes(path);
}
}