diff --git a/src/boomer.nim b/src/boomer.nim index 3c92cd1..3e9b06b 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -1,12 +1,13 @@ +import os +import math + import x11/xlib, x11/x, x11/xutil import opengl, opengl/glx -import math import vec2 import navigation import image - -const FPS: int = 60 +import config template checkError(context: string) = let error = glGetError() @@ -49,6 +50,15 @@ const WHEEL_DOWN = 5 proc main() = + var config = defaultConfig + var configFile = "" + + if paramCount() > 0: + configFile = paramStr(1) + config = loadConfig(configFile) + + echo "Using config: ", config + var display = XOpenDisplay(nil) if display == nil: quit "Failed to open display" @@ -149,6 +159,7 @@ proc main() = var camera = Camera(scale: 1.0) var mouse: Mouse + while not quitting: var xev: TXEvent while XPending(display) > 0: @@ -163,7 +174,7 @@ proc main() = if mouse.drag: camera.position += camera.world(mouse.curr) - camera.world(mouse.prev) - camera.velocity = (mouse.curr - mouse.prev) * DRAG_VELOCITY_FACTOR + camera.velocity = (mouse.curr - mouse.prev) * config.drag_velocity_factor mouse.prev = mouse.curr of ClientMessage: @@ -177,6 +188,11 @@ proc main() = camera.delta_scale = 0.0 camera.position = (0.0, 0.0) camera.velocity = (0.0, 0.0) + of 24: + quitting = true + of 27: + if configFile.len > 0: + config = loadConfig(configFile) else: discard @@ -187,10 +203,10 @@ proc main() = mouse.drag = true of WHEEL_UP: - camera.delta_scale += SCROLL_SPEED + camera.delta_scale += config.scroll_speed of WHEEL_DOWN: - camera.delta_scale -= SCROLL_SPEED + camera.delta_scale -= config.scroll_speed else: discard @@ -204,7 +220,7 @@ proc main() = else: discard - camera.update(1.0 / FPS.float, mouse) + camera.update(config, 1.0 / config.fps.float, mouse) screenshot.display(camera) glXSwapBuffers(display, win) diff --git a/src/config.nim b/src/config.nim new file mode 100644 index 0000000..58046ab --- /dev/null +++ b/src/config.nim @@ -0,0 +1,37 @@ +import macros +import strutils + +type Config* = object + scrollSpeed*: float + dragVelocityFactor*: float + dragFriction*: float + scaleFriction*: float + fps*: int + +const defaultConfig* = Config( + scroll_speed: 1.0, + drag_velocity_factor: 20.0, + drag_friction: 2000.0, + scale_friction: 5.0, + fps: 60 +) + +proc loadConfig*(filePath: string): Config = + result = defaultConfig + for line in filePath.lines: + let pair = line.split('=') + let key = pair[0].strip + let value = pair[1].strip + case key + of "scroll_speed": + result.scroll_speed = value.parseFloat + of "drag_velocity_factor": + result.drag_velocity_factor = value.parseFloat + of "drag_friction": + result.drag_friction = value.parseFloat + of "scale_friction": + result.scale_friction = value.parseFloat + of "fps": + result.fps = value.parseInt + else: + raise newException(Exception, "Unknown config key " & key) diff --git a/src/navigation.nim b/src/navigation.nim index ae1f05a..60e284c 100644 --- a/src/navigation.nim +++ b/src/navigation.nim @@ -1,10 +1,6 @@ import vec2 import math - -const SCROLL_SPEED* = 1.0 -const DRAG_VELOCITY_FACTOR*: float = 20.0 -const FRICTION*: float = 2000.0 -const SCALE_FRICTION*: float = 5.0 +import config type Mouse* = object curr*: Vec2 @@ -23,15 +19,15 @@ proc world*(camera: Camera, v: Vec2): Vec2 = proc screen*(camera: Camera, v: Vec2): Vec2 = v * camera.scale + camera.position -proc update*(camera: var Camera, dt: float, mouse: Mouse) = +proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse) = if abs(camera.delta_scale) > 0.5: let wp0 = camera.world(mouse.curr) camera.scale = max(camera.scale + camera.delta_scale * dt, 1.0) let wp1 = camera.world(mouse.curr) let dwp = wp1 - wp0 camera.position += dwp - camera.delta_scale -= sgn(camera.delta_scale).float * SCALE_FRICTION * dt + camera.delta_scale -= sgn(camera.delta_scale).float * config.scale_friction * dt if not mouse.drag and (camera.velocity.len > 20.0): camera.position += camera.velocity * dt - camera.velocity = camera.velocity - camera.velocity.norm * FRICTION * dt + camera.velocity = camera.velocity - camera.velocity.norm * config.drag_friction * dt