-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.go
187 lines (169 loc) · 3.95 KB
/
main.go
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package main
import (
"os"
"strconv"
sdl "github.com/veandco/go-sdl2/sdl"
beeper "github.com/skatiyar/go-chip8/beeper"
emu "github.com/skatiyar/go-chip8/emulator"
)
// Default Chip8 resolution
const CHIP_8_WIDTH int32 = 64
const CHIP_8_HEIGHT int32 = 32
func main() {
if len(os.Args) < 3 {
panic("Please provide modifier and a c8 file")
}
fileName := os.Args[2]
var modifier int32 = 10
if len(os.Args) == 3 {
if val, valErr := strconv.ParseInt(os.Args[1], 10, 32); valErr != nil {
panic(valErr)
} else {
if val > 0 {
modifier = int32(val)
}
}
}
// Initialize chip8 cpu
c8 := emu.Init()
if loadErr := c8.LoadProgram(fileName); loadErr != nil {
panic(loadErr)
}
// Initialize sdl2
if sdlErr := sdl.Init(sdl.INIT_EVERYTHING); sdlErr != nil {
panic(sdlErr)
}
defer sdl.Quit()
// Initialize beeper after sdl
beep, beepErr := beeper.Init()
if beepErr != nil {
panic(beepErr)
}
defer beep.Close()
// Function to be called for beep sound
c8.AddBeep(func() {
beep.Play()
})
// Create window, chip8 resolution with given modifier
window, windowErr := sdl.CreateWindow("Chip 8 - "+fileName, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, CHIP_8_WIDTH*modifier, CHIP_8_HEIGHT*modifier, sdl.WINDOW_SHOWN)
if windowErr != nil {
panic(windowErr)
}
defer window.Destroy()
// Create render surface
canvas, canvasErr := sdl.CreateRenderer(window, -1, 0)
if canvasErr != nil {
panic(canvasErr)
}
defer canvas.Destroy()
for {
// Compute the next opcode
c8.Cycle()
// Draw only if required
if c8.Draw() {
// Clear the screen
canvas.SetDrawColor(255, 0, 0, 255)
canvas.Clear()
// Get the display buffer and render
vector := c8.Buffer()
for j := 0; j < len(vector); j++ {
for i := 0; i < len(vector[j]); i++ {
// Values of pixel are stored in 1D array of size 64 * 32
if vector[j][i] != 0 {
canvas.SetDrawColor(255, 255, 0, 255)
} else {
canvas.SetDrawColor(255, 0, 0, 255)
}
canvas.FillRect(&sdl.Rect{
Y: int32(j) * modifier,
X: int32(i) * modifier,
W: modifier,
H: modifier,
})
}
}
canvas.Present()
}
// Poll for Quit and Keyboard events
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch et := event.(type) {
case *sdl.QuitEvent:
os.Exit(0)
case *sdl.KeyboardEvent:
if et.Type == sdl.KEYUP {
switch et.Keysym.Sym {
case sdl.K_1:
c8.Key(0x1, false)
case sdl.K_2:
c8.Key(0x2, false)
case sdl.K_3:
c8.Key(0x3, false)
case sdl.K_4:
c8.Key(0xC, false)
case sdl.K_q:
c8.Key(0x4, false)
case sdl.K_w:
c8.Key(0x5, false)
case sdl.K_e:
c8.Key(0x6, false)
case sdl.K_r:
c8.Key(0xD, false)
case sdl.K_a:
c8.Key(0x7, false)
case sdl.K_s:
c8.Key(0x8, false)
case sdl.K_d:
c8.Key(0x9, false)
case sdl.K_f:
c8.Key(0xE, false)
case sdl.K_z:
c8.Key(0xA, false)
case sdl.K_x:
c8.Key(0x0, false)
case sdl.K_c:
c8.Key(0xB, false)
case sdl.K_v:
c8.Key(0xF, false)
}
} else if et.Type == sdl.KEYDOWN {
switch et.Keysym.Sym {
case sdl.K_1:
c8.Key(0x1, true)
case sdl.K_2:
c8.Key(0x2, true)
case sdl.K_3:
c8.Key(0x3, true)
case sdl.K_4:
c8.Key(0xC, true)
case sdl.K_q:
c8.Key(0x4, true)
case sdl.K_w:
c8.Key(0x5, true)
case sdl.K_e:
c8.Key(0x6, true)
case sdl.K_r:
c8.Key(0xD, true)
case sdl.K_a:
c8.Key(0x7, true)
case sdl.K_s:
c8.Key(0x8, true)
case sdl.K_d:
c8.Key(0x9, true)
case sdl.K_f:
c8.Key(0xE, true)
case sdl.K_z:
c8.Key(0xA, true)
case sdl.K_x:
c8.Key(0x0, true)
case sdl.K_c:
c8.Key(0xB, true)
case sdl.K_v:
c8.Key(0xF, true)
}
}
}
}
// Chip8 cpu clock worked at frequency of 60Hz, so set delay to (1000/60)ms
sdl.Delay(1000 / 60)
}
}