mirror of https://github.com/tsoding/boomer
commit
00aad4f1b9
@ -0,0 +1,36 @@
|
||||
import x11/xlib, x11/x, x11/xutil
|
||||
|
||||
type Image* = object
|
||||
width*, height*, bpp*: cint
|
||||
pixels*: cstring
|
||||
|
||||
proc saveToPPM*(image: Image, filePath: string) =
|
||||
var f = open(filePath, fmWrite)
|
||||
defer: f.close
|
||||
writeLine(f, "P6")
|
||||
writeLine(f, image.width, " ", image.height)
|
||||
writeLine(f, 255)
|
||||
for i in 0..<(image.width * image.height):
|
||||
f.write(image.pixels[i * 4 + 2])
|
||||
f.write(image.pixels[i * 4 + 1])
|
||||
f.write(image.pixels[i * 4 + 0])
|
||||
|
||||
# NOTE: it's not possible to deallocate the returned Image because the
|
||||
# reference to XImage is lost.
|
||||
proc takeScreenshot*(display: PDisplay, root: TWindow): Image =
|
||||
var attributes: TXWindowAttributes
|
||||
discard XGetWindowAttributes(display, root, addr attributes)
|
||||
|
||||
var screenshot = XGetImage(display, root,
|
||||
0, 0,
|
||||
attributes.width.cuint,
|
||||
attributes.height.cuint,
|
||||
AllPlanes,
|
||||
ZPixmap)
|
||||
if screenshot == nil:
|
||||
quit "Could not get a screenshot"
|
||||
|
||||
result.width = attributes.width
|
||||
result.height = attributes.height
|
||||
result.bpp = screenshot.bits_per_pixel
|
||||
result.pixels = screenshot.data
|
@ -0,0 +1,39 @@
|
||||
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
|
||||
|
||||
type Mouse* = object
|
||||
curr*: Vec2
|
||||
prev*: Vec2
|
||||
drag*: bool
|
||||
|
||||
type Camera* = object
|
||||
position*: Vec2
|
||||
velocity*: Vec2
|
||||
scale*: float
|
||||
delta_scale*: float
|
||||
|
||||
proc world*(camera: Camera, v: Vec2): Vec2 =
|
||||
(v - camera.position) / camera.scale
|
||||
|
||||
proc screen*(camera: Camera, v: Vec2): Vec2 =
|
||||
v * camera.scale + camera.position
|
||||
|
||||
proc update*(camera: var Camera, dt: float, mouse: Mouse) =
|
||||
echo camera.velocity.len
|
||||
|
||||
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
|
||||
|
||||
if not mouse.drag and (camera.velocity.len > 20.0):
|
||||
camera.position += camera.velocity * dt
|
||||
camera.velocity = camera.velocity - camera.velocity.norm * FRICTION * dt
|
@ -0,0 +1,24 @@
|
||||
import math
|
||||
|
||||
type Vec2* = tuple[x: float, y: float]
|
||||
|
||||
proc `-`*(v1: Vec2, v2: Vec2): Vec2 {.inline.} = (v1.x - v2.x, v1.y - v2.y)
|
||||
proc `+`*(v1: Vec2, v2: Vec2): Vec2 {.inline.} = (v1.x + v2.x, v1.y + v2.y)
|
||||
proc `*`*(v: Vec2, s: float): Vec2 {.inline.} = (v.x * s, v.y * s)
|
||||
proc `/`*(v: Vec2, s: float): Vec2 {.inline.} = (v.x / s, v.y / s)
|
||||
proc `+=`*(v1: var Vec2, v2: Vec2) {.inline.} =
|
||||
v1.x += v2.x
|
||||
v1.y += v2.y
|
||||
proc `*=`*(v: var Vec2, s: float) {.inline.} =
|
||||
v.x *= s
|
||||
v.y *= s
|
||||
|
||||
proc len*(v: Vec2): float {.inline.} =
|
||||
sqrt(v.x * v.x + v.y * v.y)
|
||||
|
||||
proc norm*(v: Vec2): Vec2 {.inline.} =
|
||||
let l = v.len
|
||||
if abs(l) < 1e-9:
|
||||
result = (0.0, 0.0)
|
||||
else:
|
||||
result = (v.x / l, v.y / l)
|
Loading…
Reference in New Issue