nim-chip8/src/gfx.nim

127 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