126 lines
3.2 KiB
Nim
126 lines
3.2 KiB
Nim
import def, cpu
|
|
import sdl2
|
|
|
|
const TIMER_TICK = 1 / 60
|
|
|
|
type SDLException = object of Defect
|
|
|
|
template sdlFailIf(condition: typed, reason: string) =
|
|
if condition: raise SDLException.newException(
|
|
reason & ", SDL error " & $getError()
|
|
)
|
|
|
|
proc setKey(c: var CPU, key: Scancode, pressed: bool) =
|
|
let keysym: uint8 =
|
|
case key:
|
|
of SDL_SCANCODE_0, SDL_SCANCODE_KP_0: 0
|
|
of SDL_SCANCODE_1, SDL_SCANCODE_KP_1: 1
|
|
of SDL_SCANCODE_2, SDL_SCANCODE_KP_2: 2
|
|
of SDL_SCANCODE_3, SDL_SCANCODE_KP_3: 3
|
|
of SDL_SCANCODE_4, SDL_SCANCODE_KP_4: 4
|
|
of SDL_SCANCODE_5, SDL_SCANCODE_KP_5: 5
|
|
of SDL_SCANCODE_6, SDL_SCANCODE_KP_6: 6
|
|
of SDL_SCANCODE_7, SDL_SCANCODE_KP_7: 7
|
|
of SDL_SCANCODE_8, SDL_SCANCODE_KP_8: 8
|
|
of SDL_SCANCODE_9, SDL_SCANCODE_KP_9: 9
|
|
of SDL_SCANCODE_A: 0xA
|
|
of SDL_SCANCODE_B: 0xB
|
|
of SDL_SCANCODE_C: 0xC
|
|
of SDL_SCANCODE_D: 0xD
|
|
of SDL_SCANCODE_E: 0xE
|
|
of SDL_SCANCODE_F: 0xF
|
|
else: return
|
|
|
|
c.keys[keysym] = pressed
|
|
|
|
if pressed and c.reading_key != NOT_READING:
|
|
c.reg[c.reading_key] = keysym
|
|
c.reading_key = NOT_READING
|
|
|
|
proc draw(c: var CPU, renderer: RendererPtr, texture: TexturePtr) =
|
|
texture.updateTexture(
|
|
rect = nil,
|
|
pixels = addr c.fb,
|
|
pitch = SCR_WIDTH * uint32.sizeof
|
|
)
|
|
|
|
renderer.copy(
|
|
texture = texture,
|
|
srcrect = nil,
|
|
dstrect = nil
|
|
)
|
|
|
|
renderer.present
|
|
c.needs_draw = false
|
|
|
|
|
|
proc spawn*(c: var CPU) =
|
|
sdlFailIf(not sdl2.init(INIT_VIDEO or INIT_TIMER or INIT_EVENTS)):
|
|
"SDL2 initialization failed"
|
|
defer: sdl2.quit()
|
|
|
|
let window = createWindow(
|
|
title = "nim-chip8",
|
|
x = SDL_WINDOWPOS_CENTERED,
|
|
y = SDL_WINDOWPOS_CENTERED,
|
|
w = SCR_WIDTH * 10,
|
|
h = SCR_HEIGHT * 10,
|
|
flags = SDL_WINDOW_SHOWN
|
|
)
|
|
|
|
sdlFailIf window.isNil: "window could not be created"
|
|
defer: window.destroy()
|
|
|
|
let renderer = createRenderer(
|
|
window = window,
|
|
index = -1,
|
|
flags = Renderer_Accelerated or Renderer_PresentVsync or Renderer_TargetTexture
|
|
)
|
|
|
|
sdlFailIf renderer.isNil: "renderer could not be created"
|
|
defer: renderer.destroy
|
|
|
|
let texture = createTexture(
|
|
renderer = renderer,
|
|
format = SDL_PIXELFORMAT_ARGB8888,
|
|
access = SDL_TEXTUREACCESS_STATIC,
|
|
w = SCR_WIDTH,
|
|
h = SCR_HEIGHT
|
|
)
|
|
|
|
sdlFailIf texture.isNil: "texture could not be created"
|
|
defer: texture.destroy
|
|
|
|
var
|
|
running = true
|
|
counter = getPerformanceCounter()
|
|
dt: float32
|
|
tt: float32
|
|
previousCounter: uint64
|
|
|
|
while running:
|
|
previousCounter = counter
|
|
counter = getPerformanceCounter()
|
|
|
|
dt = (counter - previousCounter).float / getPerformanceFrequency().float
|
|
tt += dt
|
|
|
|
if tt > TIMER_TICK:
|
|
if c.dt != 0: c.dt.dec
|
|
if c.st != 0: c.st.dec
|
|
tt = 0
|
|
|
|
var event = defaultEvent
|
|
|
|
while event.pollEvent:
|
|
case event.kind
|
|
of QuitEvent:
|
|
running = false
|
|
break
|
|
of KeyDown:
|
|
c.setKey event.key.keysym.scancode, true
|
|
of KeyUp:
|
|
c.setKey event.key.keysym.scancode, false
|
|
else: discard
|
|
if c.needs_draw: c.draw renderer, texture
|
|
if c.reading_key == NOT_READING: c.step
|