You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
2.7 KiB

3 years ago
3 years ago
  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "go-chip8/chip8"
  6. "os"
  7. "github.com/veandco/go-sdl2/sdl"
  8. )
  9. // SdlEmulator represents the Chip8 emulator with Sdl frontend
  10. type SdlEmulator struct {
  11. w int
  12. h int
  13. renderer *sdl.Renderer
  14. zoom int32
  15. chip8 chip8.Chip8
  16. }
  17. // NewSdlEmulator creates a new SdlEmulator
  18. func NewSdlEmulator(w, h int, zoom int32) SdlEmulator {
  19. c := chip8.NewChip8()
  20. window, err := sdl.CreateWindow("go-chip8", sdl.WINDOWPOS_UNDEFINED,
  21. sdl.WINDOWPOS_UNDEFINED, int32(w)*zoom, int32(h)*zoom, sdl.WINDOW_SHOWN)
  22. if err != nil {
  23. panic(err)
  24. }
  25. renderer, err := sdl.CreateRenderer(window, -1, 0)
  26. if err != nil {
  27. panic(err)
  28. }
  29. return SdlEmulator{
  30. w: w,
  31. h: h,
  32. renderer: renderer,
  33. zoom: zoom,
  34. chip8: c,
  35. }
  36. }
  37. func (e *SdlEmulator) drawGraphics() {
  38. e.renderer.SetDrawColor(0, 0, 0, 1)
  39. e.renderer.Clear()
  40. e.renderer.SetDrawColor(255, 255, 255, 1)
  41. for y := 0; y < e.h; y++ {
  42. for x := 0; x < e.w; x++ {
  43. pixel := e.chip8.Gfx[y*e.w+x]
  44. if pixel != 0 {
  45. e.renderer.FillRect(&sdl.Rect{
  46. X: int32(x) * e.zoom,
  47. Y: int32(y) * e.zoom,
  48. W: e.zoom,
  49. H: e.zoom,
  50. })
  51. }
  52. }
  53. }
  54. e.renderer.Present()
  55. e.chip8.DrawFlag = false
  56. }
  57. func (e *SdlEmulator) setKeys() {
  58. for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
  59. switch t := event.(type) {
  60. case *sdl.QuitEvent:
  61. fmt.Println("Quit")
  62. os.Exit(0)
  63. case *sdl.KeyboardEvent:
  64. switch t.Type {
  65. case sdl.KEYDOWN:
  66. if keyHex, ok := validKeys[t.Keysym.Sym]; ok {
  67. fmt.Println("down", t.Keysym.Sym)
  68. e.chip8.Key[keyHex] = 1
  69. fmt.Println(keyHex, e.chip8.Key[keyHex])
  70. }
  71. case sdl.KEYUP:
  72. if keyHex, ok := validKeys[t.Keysym.Sym]; ok {
  73. fmt.Println("up", t.Keysym.Sym)
  74. e.chip8.Key[keyHex] = 0
  75. fmt.Println(keyHex, e.chip8.Key[keyHex])
  76. }
  77. if t.Keysym.Sym == sdl.K_ESCAPE {
  78. fmt.Println("EXIT")
  79. os.Exit(0)
  80. }
  81. }
  82. }
  83. }
  84. }
  85. /*
  86. Key pad: Keyboard keys:
  87. 1 2 3 c 1 2 3 4
  88. 4 5 6 d q w e r
  89. 7 8 9 e a s d f
  90. a 0 b f z x c v
  91. */
  92. var validKeys = map[sdl.Keycode]byte{
  93. sdl.K_1: 0x01,
  94. sdl.K_2: 0x02,
  95. sdl.K_3: 0x03,
  96. sdl.K_4: 0x0c,
  97. sdl.K_q: 0x04,
  98. sdl.K_w: 0x05,
  99. sdl.K_e: 0x06,
  100. sdl.K_r: 0x0d,
  101. sdl.K_a: 0x07,
  102. sdl.K_s: 0x08,
  103. sdl.K_d: 0x09,
  104. sdl.K_f: 0x0e,
  105. sdl.K_z: 0x0a,
  106. sdl.K_x: 0x00,
  107. sdl.K_c: 0x0b,
  108. sdl.K_v: 0x0f,
  109. }
  110. func main() {
  111. filepath := flag.String("file", "file-path", "file path of the input file")
  112. flag.Parse()
  113. emulator := NewSdlEmulator(chip8.W, chip8.H, 8)
  114. err := emulator.chip8.LoadGame(*filepath)
  115. if err != nil {
  116. panic(err)
  117. }
  118. for {
  119. emulator.chip8.EmulateCycle()
  120. if emulator.chip8.DrawFlag {
  121. emulator.drawGraphics()
  122. }
  123. emulator.setKeys()
  124. sdl.Delay(200 / 60)
  125. }
  126. }