11package main
22
33import (
4+ "flag"
45 "fmt"
6+ "log"
57 "os"
8+ "runtime/pprof"
69 "sort"
710 "strconv"
811 "time"
@@ -16,13 +19,14 @@ import (
1619
1720// SDL2 variables
1821var windowTitle string = "GoNES SDL2"
19- var fontPath string = "./ui/ assets/UbuntuMono-R.ttf" // Man, do not use a variable-width font! It looks too ugly with that!
22+ var fontPath string = "./assets/UbuntuMono-R.ttf" // Man, do not use a variable-width font! It looks too ugly with that!
2023var fontSize int = 15
2124var windowWidth , windowHeight int32 = 680 , 480
2225
2326// Timer.
2427var startTime time.Time = time .Now ()
2528var endTime time.Time = time .Now ()
29+ var elapsedTime int64 = 0
2630
2731type debugger struct {
2832 bus * nes.Bus
@@ -267,26 +271,66 @@ func (debug *debugger) Update(elapsedTime int64) bool {
267271 // Swap screen and buffer (present),
268272 // Clear buffer for next round.
269273
270- // Get user inputs.
274+ // Get NES controller inputs.
275+ keyState := sdl .GetKeyboardState ()
276+
277+ debug .bus .Controller [0 ] = 0x00
278+ if keyState [sdl .SCANCODE_X ] != 0 {
279+ debug .bus .Controller [0 ] |= 0x80
280+ } else {
281+ debug .bus .Controller [0 ] |= 0x00
282+ }
283+
284+ if keyState [sdl .SCANCODE_Z ] != 0 {
285+ debug .bus .Controller [0 ] |= 0x40
286+ } else {
287+ debug .bus .Controller [0 ] |= 0x00
288+ }
289+
290+ if keyState [sdl .SCANCODE_A ] != 0 {
291+ debug .bus .Controller [0 ] |= 0x20
292+ } else {
293+ debug .bus .Controller [0 ] |= 0x00
294+ }
295+
296+ if keyState [sdl .SCANCODE_S ] != 0 {
297+ debug .bus .Controller [0 ] |= 0x10
298+ } else {
299+ debug .bus .Controller [0 ] |= 0x00
300+ }
301+
302+ if keyState [sdl .SCANCODE_UP ] != 0 {
303+ debug .bus .Controller [0 ] |= 0x08
304+ } else {
305+ debug .bus .Controller [0 ] |= 0x00
306+ }
307+
308+ if keyState [sdl .SCANCODE_DOWN ] != 0 {
309+ debug .bus .Controller [0 ] |= 0x04
310+ } else {
311+ debug .bus .Controller [0 ] |= 0x00
312+ }
313+
314+ if keyState [sdl .SCANCODE_LEFT ] != 0 {
315+ debug .bus .Controller [0 ] |= 0x02
316+ } else {
317+ debug .bus .Controller [0 ] |= 0x00
318+ }
319+
320+ if keyState [sdl .SCANCODE_RIGHT ] != 0 {
321+ debug .bus .Controller [0 ] |= 0x01
322+ } else {
323+ debug .bus .Controller [0 ] |= 0x00
324+ }
325+
326+ // Get debugger inputs.
271327 for event := sdl .PollEvent (); event != nil ; event = sdl .PollEvent () {
272328 switch t := event .(type ) {
273329 case * sdl.QuitEvent :
274330 return false
275331 case * sdl.KeyboardEvent :
276332 if ! debug .inputLock {
277333 switch t .Keysym .Sym {
278- // NES controller
279- // Bugged...
280- case sdl .K_s :
281- debug .bus .Controller [0 ] |= 0x10
282- case sdl .K_UP :
283- debug .bus .Controller [0 ] |= 0x08
284- case sdl .K_DOWN :
285- debug .bus .Controller [0 ] |= 0x04
286- case sdl .K_LEFT :
287- debug .bus .Controller [0 ] |= 0x02
288- case sdl .K_RIGHT :
289- debug .bus .Controller [0 ] |= 0x01
290334 // Debug utility.
291335 case sdl .K_c :
292336 // Golang's do while.
@@ -321,8 +365,10 @@ func (debug *debugger) Update(elapsedTime int64) bool {
321365
322366 // Anti-jittering
323367 if t .Repeat > 0 {
368+ // Held.
324369 debug .inputLock = false
325370 } else {
371+ // Pressed once.
326372 if t .State == sdl .RELEASED {
327373 debug .inputLock = false
328374 } else if t .State == sdl .PRESSED {
@@ -337,7 +383,7 @@ func (debug *debugger) Update(elapsedTime int64) bool {
337383 if debug .residualTime > 0 {
338384 debug .residualTime -= elapsedTime
339385 } else {
340- debug .residualTime += 1000 / 60 - elapsedTime
386+ debug .residualTime += 1000000 / 60 - elapsedTime
341387 // Golang's do while.
342388 for done := true ; done ; done = debug .bus .PPU .FrameComplete != true {
343389 debug .bus .Clock ()
@@ -389,18 +435,23 @@ func (debug *debugger) Update(elapsedTime int64) bool {
389435 debug .drawDMA (416 , 72 , 25 )
390436
391437 // Draw key hints.
392- debug .drawString (0 , 362 , "SPACE - Run/stop" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
393- debug .drawString (0 , 372 , "R - Reset" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
394- debug .drawString (0 , 382 , "F - Step one frame" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
395- debug .drawString (0 , 392 , "C - Step one instruction" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
396- debug .drawString (0 , 402 , "D - Dump screen" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
397- debug .drawString (0 , 412 , "P - Change palette" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
398-
399- fps := 0
400- if elapsedTime != 0 {
401- fps = int (1000 / elapsedTime )
402- }
403- debug .drawString (612 , 2 , "FPS: " + strconv .Itoa (fps ), & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
438+ debug .drawString (2 , 306 , "NES" , & sdl.Color {R : 255 , G : 255 , B : 0 , A : 0 })
439+ debug .drawString (2 , 316 , "Z - A" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
440+ debug .drawString (2 , 326 , "X - B" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
441+ debug .drawString (2 , 336 , "A - Select" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
442+ debug .drawString (2 , 346 , "S - Start" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
443+ debug .drawString (2 , 356 , "UP - Up" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
444+ debug .drawString (2 , 366 , "DOWN - Down" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
445+ debug .drawString (2 , 376 , "LEFT - Left" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
446+ debug .drawString (2 , 386 , "RIGHT - Right" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
447+
448+ debug .drawString (2 , 406 , "Debugger" , & sdl.Color {R : 255 , G : 255 , B : 0 , A : 0 })
449+ debug .drawString (2 , 416 , "SPACE - Run/stop" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
450+ debug .drawString (2 , 426 , "R - Reset" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
451+ debug .drawString (2 , 436 , "F - Step one frame" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
452+ debug .drawString (2 , 446 , "C - Step one instruction" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
453+ debug .drawString (2 , 456 , "D - Dump screen" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
454+ debug .drawString (2 , 466 , "P - Change palette" , & sdl.Color {R : 0 , G : 255 , B : 0 , A : 0 })
404455
405456 // Swap buffer and present our rendered content.
406457 debug .window .UpdateSurface ()
@@ -414,28 +465,56 @@ func (debug *debugger) Update(elapsedTime int64) bool {
414465}
415466
416467func (debug * debugger ) Start () {
417- elapsedTime := startTime .Sub (endTime ).Milliseconds ()
468+ var passedTime int64 = 0
469+ var passedFrame int64 = 0
418470
419471 running := true
420472 for running {
421473 startTime = time .Now ()
422474 running = debug .Update (elapsedTime )
423475 endTime = time .Now ()
424- elapsedTime = endTime .Sub (startTime ).Milliseconds ()
476+ elapsedTime = endTime .Sub (startTime ).Microseconds ()
477+
478+ passedTime += elapsedTime
479+ passedFrame ++
480+ if passedTime >= 1000000 {
481+ debug .window .SetTitle (windowTitle + " FPS: " + strconv .Itoa (int (1000000 / (passedTime / passedFrame ))))
482+ passedTime = 0
483+ passedFrame = 0
484+ }
425485 }
426-
427486}
428487
429488func main () {
430489 fmt .Println (windowTitle )
431-
432490 // I really enjoy its graphics. I mean the anime movie.
433491 fmt .Println ("HELLO WORLD -ALLTALE-" )
434492 fmt .Println ("With programming we have god's hand." )
435493
494+ // Read flags
495+ var file = flag .String ("file" , "" , "NES ROM file" )
496+ var cpuprofile = flag .String ("cpuprofile" , "" , "Write cpu profile to file" )
497+
498+ flag .Parse ()
499+
500+ // Handle flags
501+ if * file == "" {
502+ fmt .Println ("Please specify a NES ROM file." )
503+ os .Exit (1 )
504+ }
505+
506+ if * cpuprofile != "" {
507+ f , err := os .Create (* cpuprofile )
508+ if err != nil {
509+ log .Fatal (err )
510+ }
511+ pprof .StartCPUProfile (f )
512+ defer pprof .StopCPUProfile ()
513+ }
514+
436515 // Construct a debugger instance.
437516 debug := debugger {}
438- err := debug .Construct ("./roms/smb.nes" , windowWidth , windowHeight )
517+ err := debug .Construct (* file , windowWidth , windowHeight )
439518 if err != nil {
440519 return
441520 }
0 commit comments