updated graphics.nim

This commit is contained in:
Araq 2014-09-18 23:35:08 +02:00
commit 4367fb26ad
2 changed files with 131 additions and 131 deletions

View file

@ -14,7 +14,7 @@
import colors, math import colors, math
from sdl import PSurface # Bug from sdl import PSurface # Bug
from sdl_ttf import OpenFont, closeFont from sdl_ttf import openFont, closeFont
type type
TRect* = tuple[x, y, width, height: int] TRect* = tuple[x, y, width, height: int]
@ -25,24 +25,24 @@ type
w*, h*: Natural w*, h*: Natural
s*: sdl.PSurface s*: sdl.PSurface
EGraphics* = object of EIO EGraphics* = object of IOError
TFont {.pure, final.} = object TFont {.pure, final.} = object
f: sdl_ttf.PFont f: sdl_ttf.PFont
color: SDL.TColor color: sdl.TColor
PFont* = ref TFont ## represents a font PFont* = ref TFont ## represents a font
proc toSdlColor*(c: TColor): Sdl.TColor = proc toSdlColor*(c: Color): sdl.TColor =
## Convert colors.TColor to SDL.TColor ## Convert colors.TColor to sdl.TColor
var x = c.extractRGB var x = c.extractRGB
result.r = x.r and 0xff result.r = x.r and 0xff
result.g = x.g and 0xff result.g = x.g and 0xff
result.b = x.b and 0xff result.b = x.b and 0xff
proc createSdlColor*(sur: PSurface, c: TColor, alpha: int = 0): int32 = proc createSdlColor*(sur: PSurface, c: Color, alpha: int = 0): int32 =
## Creates a color using ``sdl.MapRGBA``. ## Creates a color using ``sdl.MapRGBA``.
var x = c.extractRGB var x = c.extractRGB
return sdl.MapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff, return sdl.mapRGBA(sur.s.format, x.r and 0xff, x.g and 0xff,
x.b and 0xff, alpha and 0xff) x.b and 0xff, alpha and 0xff)
proc toSdlRect*(r: TRect): sdl.TRect = proc toSdlRect*(r: TRect): sdl.TRect =
@ -53,7 +53,7 @@ proc toSdlRect*(r: TRect): sdl.TRect =
result.h = uint16(r.height) result.h = uint16(r.height)
proc raiseEGraphics = proc raiseEGraphics =
raise newException(EGraphics, $SDL.GetError()) raise newException(EGraphics, $sdl.getError())
proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s) proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s)
@ -62,21 +62,21 @@ proc newSurface*(width, height: int): PSurface =
new(result, surfaceFinalizer) new(result, surfaceFinalizer)
result.w = width result.w = width
result.h = height result.h = height
result.s = SDL.CreateRGBSurface(SDL.SWSURFACE, width, height, result.s = sdl.createRGBSurface(sdl.SWSURFACE, width, height,
32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0) 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0)
if result.s == nil: if result.s == nil:
raiseEGraphics() raiseEGraphics()
assert(not sdl.MustLock(result.s)) assert(not sdl.mustLock(result.s))
proc fontFinalizer(f: PFont) = closeFont(f.f) proc fontFinalizer(f: PFont) = closeFont(f.f)
proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont = proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont =
## Creates a new font object. Raises ``EIO`` if the font cannot be loaded. ## Creates a new font object. Raises ``EIO`` if the font cannot be loaded.
new(result, fontFinalizer) new(result, fontFinalizer)
result.f = OpenFont(name, size.cint) result.f = openFont(name, size.cint)
if result.f == nil: if result.f == nil:
raise newException(EIO, "Could not open font file: " & name) raise newException(IOError, "Could not open font file: " & name)
result.color = toSdlColor(color) result.color = toSdlColor(color)
var var
@ -92,7 +92,7 @@ proc newScreenSurface*(width, height: int): PSurface =
new(result, surfaceFinalizer) new(result, surfaceFinalizer)
result.w = width result.w = width
result.h = height result.h = height
result.s = SDL.SetVideoMode(width, height, 0, 0) result.s = sdl.setVideoMode(width, height, 0, 0)
if result.s == nil: if result.s == nil:
raiseEGraphics() raiseEGraphics()
@ -100,7 +100,7 @@ proc writeToBMP*(sur: PSurface, filename: string) =
## Saves the contents of the surface `sur` to the file `filename` as a ## Saves the contents of the surface `sur` to the file `filename` as a
## BMP file. ## BMP file.
if sdl.saveBMP(sur.s, filename) != 0: if sdl.saveBMP(sur.s, filename) != 0:
raise newException(EIO, "cannot write: " & filename) raise newException(IOError, "cannot write: " & filename)
type type
TPixels = array[0..1000_000-1, int32] TPixels = array[0..1000_000-1, int32]
@ -110,44 +110,44 @@ template setPix(video, pitch, x, y, col: expr): stmt =
video[y * pitch + x] = int32(col) video[y * pitch + x] = int32(col)
template getPix(video, pitch, x, y: expr): expr = template getPix(video, pitch, x, y: expr): expr =
colors.TColor(video[y * pitch + x]) colors.Color(video[y * pitch + x])
const const
ColSize = 4 ColSize = 4
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} = proc getPixel(sur: PSurface, x, y: Natural): colors.Color {.inline.} =
assert x <% sur.w assert x <% sur.w
assert y <% sur.h assert y <% sur.h
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch.int div ColSize, result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch.int div ColSize,
x, y) x, y)
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} = proc setPixel(sur: PSurface, x, y: Natural, col: colors.Color) {.inline.} =
assert x <% sur.w assert x <% sur.w
assert y <% sur.h assert y <% sur.h
var pixs = cast[PPixels](sur.s.pixels) var pixs = cast[PPixels](sur.s.pixels)
#pixs[y * (sur.s.pitch div colSize) + x] = int(col) #pixs[y * (sur.s.pitch div colSize) + x] = int(col)
setPix(pixs, sur.s.pitch.int div ColSize, x, y, col) setPix(pixs, sur.s.pitch.int div ColSize, x, y, col)
proc `[]`*(sur: PSurface, p: TPoint): TColor = proc `[]`*(sur: PSurface, p: TPoint): Color =
## get pixel at position `p`. No range checking is done! ## get pixel at position `p`. No range checking is done!
result = getPixel(sur, p.x, p.y) result = getPixel(sur, p.x, p.y)
proc `[]`*(sur: PSurface, x, y: int): TColor = proc `[]`*(sur: PSurface, x, y: int): Color =
## get pixel at position ``(x, y)``. No range checking is done! ## get pixel at position ``(x, y)``. No range checking is done!
result = getPixel(sur, x, y) result = getPixel(sur, x, y)
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) = proc `[]=`*(sur: PSurface, p: TPoint, col: Color) =
## set the pixel at position `p`. No range checking is done! ## set the pixel at position `p`. No range checking is done!
setPixel(sur, p.x, p.y, col) setPixel(sur, p.x, p.y, col)
proc `[]=`*(sur: PSurface, x, y: int, col: TColor) = proc `[]=`*(sur: PSurface, x, y: int, col: Color) =
## set the pixel at position ``(x, y)``. No range checking is done! ## set the pixel at position ``(x, y)``. No range checking is done!
setPixel(sur, x, y, col) setPixel(sur, x, y, col)
proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface,
srcRect: TRect) = srcRect: TRect) =
## Copies ``srcSurf`` into ``destSurf`` ## Copies ``srcSurf`` into ``destSurf``
var destTRect, srcTRect: SDL.TRect var destTRect, srcTRect: sdl.TRect
destTRect.x = int16(destRect.x) destTRect.x = int16(destRect.x)
destTRect.y = int16(destRect.y) destTRect.y = int16(destRect.y)
@ -159,12 +159,12 @@ proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface,
srcTRect.w = uint16(srcRect.width) srcTRect.w = uint16(srcRect.width)
srcTRect.h = uint16(srcRect.height) srcTRect.h = uint16(srcRect.height)
if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0: if sdl.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0:
raiseEGraphics() raiseEGraphics()
proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] = proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] =
var w, h: cint var w, h: cint
if sdl_ttf.SizeUTF8(font.f, text, w, h) < 0: raiseEGraphics() if sdl_ttf.sizeUTF8(font.f, text, w, h) < 0: raiseEGraphics()
result.width = int(w) result.width = int(w)
result.height = int(h) result.height = int(h)
@ -175,21 +175,21 @@ proc drawText*(sur: PSurface, p: TPoint, text: string, font = defaultFont) =
new(textSur, surfaceFinalizer) new(textSur, surfaceFinalizer)
# Render the text # Render the text
textSur.s = sdl_ttf.RenderTextBlended(font.f, text, font.color) textSur.s = sdl_ttf.renderTextBlended(font.f, text, font.color)
# Merge the text surface with sur # Merge the text surface with sur
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
proc drawText*(sur: PSurface, p: TPoint, text: string, proc drawText*(sur: PSurface, p: TPoint, text: string,
bg: TColor, font = defaultFont) = bg: Color, font = defaultFont) =
## Draws text, at location ``p`` with font ``font``. ``bg`` ## Draws text, at location ``p`` with font ``font``. ``bg``
## is the background color. ## is the background color.
var textSur: PSurface # This surface will have the text drawn on it var textSur: PSurface # This surface will have the text drawn on it
new(textSur, surfaceFinalizer) new(textSur, surfaceFinalizer)
textSur.s = sdl_ttf.RenderTextShaded(font.f, text, font.color, toSdlColor(bg)) textSur.s = sdl_ttf.renderTextShaded(font.f, text, font.color, toSdlColor(bg))
# Merge the text surface with sur # Merge the text surface with sur
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h)) sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) = proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: Color) =
## draws a circle with center `p` and radius `r` with the given color ## draws a circle with center `p` and radius `r` with the given color
## onto the surface `sur`. ## onto the surface `sur`.
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
@ -229,7 +229,7 @@ proc `>-<`(val: int, s: PSurface): int {.inline.} =
proc `>|<`(val: int, s: PSurface): int {.inline.} = proc `>|<`(val: int, s: PSurface): int {.inline.} =
return if val < 0: 0 elif val >= s.h: s.h-1 else: val return if val < 0: 0 elif val >= s.h: s.h-1 else: val
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) = proc drawLine*(sur: PSurface, p1, p2: TPoint, color: Color) =
## draws a line between the two points `p1` and `p2` with the given color ## draws a line between the two points `p1` and `p2` with the given color
## onto the surface `sur`. ## onto the surface `sur`.
var stepx, stepy: int = 0 var stepx, stepy: int = 0
@ -273,7 +273,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
fraction = fraction + dx fraction = fraction + dx
setPix(video, pitch, x0, y0, color) setPix(video, pitch, x0, y0, color)
proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) = proc drawHorLine*(sur: PSurface, x, y, w: Natural, color: Color) =
## draws a horizontal line from (x,y) to (x+w-1, y). ## draws a horizontal line from (x,y) to (x+w-1, y).
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch.int div ColSize var pitch = sur.s.pitch.int div ColSize
@ -282,7 +282,7 @@ proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
for i in 0 .. min(sur.s.w-x, w)-1: for i in 0 .. min(sur.s.w-x, w)-1:
setPix(video, pitch, x + i, y, color) setPix(video, pitch, x + i, y, color)
proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) = proc drawVerLine*(sur: PSurface, x, y, h: Natural, color: Color) =
## draws a vertical line from (x,y) to (x, y+h-1). ## draws a vertical line from (x,y) to (x, y+h-1).
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch.int div ColSize var pitch = sur.s.pitch.int div ColSize
@ -291,7 +291,7 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) =
for i in 0 .. min(sur.s.h-y, h)-1: for i in 0 .. min(sur.s.h-y, h)-1:
setPix(video, pitch, x, y + i, color) setPix(video, pitch, x, y + i, color)
proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) = proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: Color) =
## draws a circle with center `p` and radius `r` with the given color ## draws a circle with center `p` and radius `r` with the given color
## onto the surface `sur` and fills it. ## onto the surface `sur` and fills it.
var a = 1 - r var a = 1 - r
@ -301,11 +301,11 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
var y = p.y var y = p.y
while px <= py: while px <= py:
# Fill up the middle half of the circle # Fill up the middle half of the circle
DrawVerLine(s, x + px, y, py + 1, color) drawVerLine(s, x + px, y, py + 1, color)
DrawVerLine(s, x + px, y - py, py, color) drawVerLine(s, x + px, y - py, py, color)
if px != 0: if px != 0:
DrawVerLine(s, x - px, y, py + 1, color) drawVerLine(s, x - px, y, py + 1, color)
DrawVerLine(s, x - px, y - py, py, color) drawVerLine(s, x - px, y - py, py, color)
if a < 0: if a < 0:
a = a + (2 * px + 3) a = a + (2 * px + 3)
else: else:
@ -313,13 +313,13 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
py = py - 1 py = py - 1
# Fill up the left/right half of the circle # Fill up the left/right half of the circle
if py >= px: if py >= px:
DrawVerLine(s, x + py + 1, y, px + 1, color) drawVerLine(s, x + py + 1, y, px + 1, color)
DrawVerLine(s, x + py + 1, y - px, px, color) drawVerLine(s, x + py + 1, y - px, px, color)
DrawVerLine(s, x - py - 1, y, px + 1, color) drawVerLine(s, x - py - 1, y, px + 1, color)
DrawVerLine(s, x - py - 1, y - px, px, color) drawVerLine(s, x - py - 1, y - px, px, color)
px = px + 1 px = px + 1
proc drawRect*(sur: PSurface, r: TRect, color: TColor) = proc drawRect*(sur: PSurface, r: TRect, color: Color) =
## draws a rectangle. ## draws a rectangle.
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch.int div ColSize var pitch = sur.s.pitch.int div ColSize
@ -337,78 +337,78 @@ proc drawRect*(sur: PSurface, r: TRect, color: TColor) =
setPix(video, pitch, r.x, r.y + i, color) setPix(video, pitch, r.x, r.y + i, color)
setPix(video, pitch, r.x + minW - 1, r.y + i, color) # Draw right side setPix(video, pitch, r.x + minW - 1, r.y + i, color) # Draw right side
proc fillRect*(sur: PSurface, r: TRect, col: TColor) = proc fillRect*(sur: PSurface, r: TRect, col: Color) =
## Fills a rectangle using sdl's ``FillRect`` function. ## Fills a rectangle using sdl's ``FillRect`` function.
var rect = toSdlRect(r) var rect = toSdlRect(r)
if sdl.FillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1: if sdl.fillRect(sur.s, addr(rect), sur.createSdlColor(col)) == -1:
raiseEGraphics() raiseEGraphics()
proc plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) = proc plot4EllipsePoints(sur: PSurface, cx, cy, x, y: Natural, col: Color) =
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch.int div ColSize var pitch = sur.s.pitch.int div ColSize
if CX+X <= sur.s.w-1: if cx+x <= sur.s.w-1:
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col) if cy+y <= sur.s.h-1: setPix(video, pitch, cx+x, cy+y, col)
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col) if cy-y <= sur.s.h-1: setPix(video, pitch, cx+x, cy-y, col)
if CX-X <= sur.s.w-1: if cx-x <= sur.s.w-1:
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY+Y, col) if cy+y <= sur.s.h-1: setPix(video, pitch, cx-x, cy+y, col)
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY-Y, col) if cy-y <= sur.s.h-1: setPix(video, pitch, cx-x, cy-y, col)
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, proc drawEllipse*(sur: PSurface, cx, cy, xRadius, yRadius: Natural,
col: TColor) = col: Color) =
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the
## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height ## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height
## of the ellipse. ## of the ellipse.
var var
X, Y: Natural x, y: Natural
XChange, YChange: Int xChange, yChange: int
EllipseError: Natural ellipseError: Natural
TwoASquare, TwoBSquare: Natural twoASquare, twoBSquare: Natural
StoppingX, StoppingY: Natural stoppingX, stoppingY: Natural
TwoASquare = 2 * XRadius * XRadius twoASquare = 2 * xRadius * xRadius
TwoBSquare = 2 * YRadius * YRadius twoBSquare = 2 * yRadius * yRadius
X = XRadius x = xRadius
Y = 0 y = 0
XChange = YRadius * YRadius * (1 - 2 * XRadius) xChange = yRadius * yRadius * (1 - 2 * xRadius)
YChange = XRadius * XRadius yChange = xRadius * xRadius
EllipseError = 0 ellipseError = 0
StoppingX = TwoBSquare * XRadius stoppingX = twoBSquare * xRadius
StoppingY = 0 stoppingY = 0
while StoppingX >= StoppingY: # 1st set of points, y` > - 1 while stoppingX >= stoppingY: # 1st set of points, y` > - 1
sur.Plot4EllipsePoints(CX, CY, X, Y, col) sur.plot4EllipsePoints(cx, cy, x, y, col)
inc(Y) inc(y)
inc(StoppingY, TwoASquare) inc(stoppingY, twoASquare)
inc(EllipseError, YChange) inc(ellipseError, yChange)
inc(YChange, TwoASquare) inc(yChange, twoASquare)
if (2 * EllipseError + XChange) > 0 : if (2 * ellipseError + xChange) > 0 :
dec(x) dec(x)
dec(StoppingX, TwoBSquare) dec(stoppingX, twoBSquare)
inc(EllipseError, XChange) inc(ellipseError, xChange)
inc(XChange, TwoBSquare) inc(xChange, twoBSquare)
# 1st point set is done; start the 2nd set of points # 1st point set is done; start the 2nd set of points
X = 0 x = 0
Y = YRadius y = yRadius
XChange = YRadius * YRadius xChange = yRadius * yRadius
YChange = XRadius * XRadius * (1 - 2 * YRadius) yChange = xRadius * xRadius * (1 - 2 * yRadius)
EllipseError = 0 ellipseError = 0
StoppingX = 0 stoppingX = 0
StoppingY = TwoASquare * YRadius stoppingY = twoASquare * yRadius
while StoppingX <= StoppingY: while stoppingX <= stoppingY:
sur.Plot4EllipsePoints(CX, CY, X, Y, col) sur.plot4EllipsePoints(cx, cy, x, y, col)
inc(X) inc(x)
inc(StoppingX, TwoBSquare) inc(stoppingX, twoBSquare)
inc(EllipseError, XChange) inc(ellipseError, xChange)
inc(XChange,TwoBSquare) inc(xChange,twoBSquare)
if (2 * EllipseError + YChange) > 0: if (2 * ellipseError + yChange) > 0:
dec(Y) dec(y)
dec(StoppingY, TwoASquare) dec(stoppingY, twoASquare)
inc(EllipseError, YChange) inc(ellipseError, yChange)
inc(YChange,TwoASquare) inc(yChange,twoASquare)
proc plotAA(sur: PSurface, x, y: int, c: float, color: TColor) = proc plotAA(sur: PSurface, x, y: int, c: float, color: Color) =
if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h): if (x > 0 and x < sur.s.w) and (y > 0 and y < sur.s.h):
var video = cast[PPixels](sur.s.pixels) var video = cast[PPixels](sur.s.pixels)
var pitch = sur.s.pitch.int div ColSize var pitch = sur.s.pitch.int div ColSize
@ -424,7 +424,7 @@ template cround(x: expr): expr = ipart(x + 0.5)
template fpart(x: expr): expr = x - ipart(x) template fpart(x: expr): expr = x - ipart(x)
template rfpart(x: expr): expr = 1.0 - fpart(x) template rfpart(x: expr): expr = 1.0 - fpart(x)
proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) = proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: Color) =
## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's ## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's
## line algorithm ## line algorithm
var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(), var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(),
@ -444,11 +444,11 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) =
swap(x2, y2) swap(x2, y2)
swap(dx, dy) swap(dx, dy)
template doPlot(x, y: int, c: float, color: TColor): stmt = template doPlot(x, y: int, c: float, color: Color): stmt =
if ax < ay: if ax < ay:
sur.PlotAA(y, x, c, color) sur.plotAA(y, x, c, color)
else: else:
sur.PlotAA(x, y, c, color) sur.plotAA(x, y, c, color)
if x2 < x1: if x2 < x1:
swap(x1, x2) swap(x1, x2)
@ -482,22 +482,22 @@ proc drawLineAA*(sur: PSurface, p1, p2: TPoint, color: TColor) =
intery = intery + gradient intery = intery + gradient
inc(x) inc(x)
proc fillSurface*(sur: PSurface, color: TColor) = proc fillSurface*(sur: PSurface, color: Color) =
## Fills the entire surface with ``color``. ## Fills the entire surface with ``color``.
if sdl.FillRect(sur.s, nil, sur.createSdlColor(color)) == -1: if sdl.fillRect(sur.s, nil, sur.createSdlColor(color)) == -1:
raiseEGraphics() raiseEGraphics()
template withEvents*(surf: PSurface, event: expr, actions: stmt): stmt {. template withEvents*(surf: PSurface, event: expr, actions: stmt): stmt {.
immediate.} = immediate.} =
## Simple template which creates an event loop. ``Event`` is the name of the ## Simple template which creates an event loop. ``Event`` is the name of the
## variable containing the TEvent object. ## variable containing the TEvent object.
while True: while true:
var event: SDL.TEvent var event: sdl.TEvent
if SDL.WaitEvent(addr(event)) == 1: if sdl.waitEvent(addr(event)) == 1:
actions actions
if sdl.Init(sdl.INIT_VIDEO) < 0: raiseEGraphics() if sdl.init(sdl.INIT_VIDEO) < 0: raiseEGraphics()
if sdl_ttf.Init() < 0: raiseEGraphics() if sdl_ttf.init() < 0: raiseEGraphics()
when isMainModule: when isMainModule:
var surf = newScreenSurface(800, 600) var surf = newScreenSurface(800, 600)
@ -539,19 +539,19 @@ when isMainModule:
withEvents(surf, event): withEvents(surf, event):
var eventp = addr(event) var eventp = addr(event)
case event.kind: case event.kind:
of SDL.QUITEV: of sdl.QUITEV:
break break
of SDL.KEYDOWN: of sdl.KEYDOWN:
var evk = sdl.EvKeyboard(eventp) var evk = sdl.evKeyboard(eventp)
if evk.keysym.sym == SDL.K_LEFT: if evk.keysym.sym == sdl.K_LEFT:
surf.drawHorLine(395, 300, 50, colBlack) surf.drawHorLine(395, 300, 50, colBlack)
echo("Drawing") echo("Drawing")
elif evk.keysym.sym == SDL.K_ESCAPE: elif evk.keysym.sym == sdl.K_ESCAPE:
break break
else: else:
echo(evk.keysym.sym) echo(evk.keysym.sym)
of SDL.MOUSEBUTTONDOWN: of sdl.MOUSEBUTTONDOWN:
var mbd = sdl.EvMouseButton(eventp) var mbd = sdl.evMouseButton(eventp)
if mouseStartX == -1 or mouseStartY == -1: if mouseStartX == -1 or mouseStartY == -1:
mouseStartX = int(mbd.x) mouseStartX = int(mbd.x)
mouseStartY = int(mbd.y) mouseStartY = int(mbd.y)
@ -560,16 +560,16 @@ when isMainModule:
mouseStartX = -1 mouseStartX = -1
mouseStartY = -1 mouseStartY = -1
of SDL.MouseMotion: of sdl.MOUSEMOTION:
var mm = sdl.EvMouseMotion(eventp) var mm = sdl.evMouseMotion(eventp)
if mouseStartX != -1 and mouseStartY != -1: if mouseStartX != -1 and mouseStartY != -1:
surf.drawLineAA((mouseStartX, mouseStartY), (int(mm.x), int(mm.y)), colPurple) surf.drawLineAA((mouseStartX, mouseStartY), (int(mm.x), int(mm.y)), colPurple)
#echo(mm.x, " ", mm.y, " ", mm.yrel) #echo(mm.x, " ", mm.y, " ", mm.yrel)
else: else:
#echo(event.kind) discard "echo(event.kind)"
SDL.UpdateRect(surf.s, 0, 0, 800, 600) sdl.updateRect(surf.s, 0, 0, 800, 600)
surf.writeToBMP("test.bmp") surf.writeToBMP("test.bmp")
SDL.Quit() sdl.quit()

View file

@ -1287,19 +1287,19 @@ template evconv(procName: expr, ptrName: typedesc, assertions: TEventSeq): stmt
assert(contains(assertions, event.kind)) assert(contains(assertions, event.kind))
result = cast[ptrName](event) result = cast[ptrName](event)
evconv(EvActive, PActiveEvent, {ACTIVEEVENT}) evconv(evActive, PActiveEvent, {ACTIVEEVENT})
evconv(EvKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP}) evconv(evKeyboard, PKeyboardEvent, {KEYDOWN, KEYUP})
evconv(EvMouseMotion, PMouseMotionEvent, {MOUSEMOTION}) evconv(evMouseMotion, PMouseMotionEvent, {MOUSEMOTION})
evconv(EvMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP}) evconv(evMouseButton, PMouseButtonEvent, {MOUSEBUTTONDOWN, MOUSEBUTTONUP})
evconv(EvJoyAxis, PJoyAxisEvent,{JOYAXISMOTION}) evconv(evJoyAxis, PJoyAxisEvent,{JOYAXISMOTION})
evconv(EvJoyBall, PJoyBallEvent, {JOYBALLMOTION}) evconv(evJoyBall, PJoyBallEvent, {JOYBALLMOTION})
evconv(EvJoyHat, PJoyHatEvent, {JOYHATMOTION}) evconv(evJoyHat, PJoyHatEvent, {JOYHATMOTION})
evconv(EvJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP}) evconv(evJoyButton, PJoyButtonEvent, {JOYBUTTONDOWN, JOYBUTTONUP})
evconv(EvResize, PResizeEvent, {VIDEORESIZE}) evconv(evResize, PResizeEvent, {VIDEORESIZE})
evconv(EvExpose, PExposeEvent, {VIDEOEXPOSE}) evconv(evExpose, PExposeEvent, {VIDEOEXPOSE})
evconv(EvQuit, PQuitEvent, {QUITEV}) evconv(evQuit, PQuitEvent, {QUITEV})
evconv(EvUser, PUserEvent, {USEREVENT}) evconv(evUser, PUserEvent, {USEREVENT})
evconv(EvSysWM, PSysWMEvent, {SYSWMEVENT}) evconv(evSysWM, PSysWMEvent, {SYSWMEVENT})
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# initialization # initialization