fixed graphics module
This commit is contained in:
parent
6c08ba8290
commit
048811b2be
6 changed files with 2742 additions and 134 deletions
|
|
@ -11,7 +11,8 @@
|
||||||
## implementation uses SDL but the interface is meant to support multiple
|
## implementation uses SDL but the interface is meant to support multiple
|
||||||
## backends some day.
|
## backends some day.
|
||||||
|
|
||||||
import sdl, colors
|
import colors
|
||||||
|
from sdl import PSurface # Bug
|
||||||
|
|
||||||
type
|
type
|
||||||
TRect* = tuple[x, y, width, height: int]
|
TRect* = tuple[x, y, width, height: int]
|
||||||
|
|
@ -30,174 +31,192 @@ proc newSurface*(width, height: int): PSurface =
|
||||||
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, 0xff000000)
|
32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0)
|
||||||
|
|
||||||
|
assert(not sdl.MustLock(result.s))
|
||||||
|
|
||||||
proc textBounds*(text: string): tuple[len, height: int]
|
#proc textBounds*(text: string): tuple[len, height: int]
|
||||||
proc drawText*(sur: PSurface, p: TPoint, text: string)
|
#proc drawText*(sur: PSurface, p: TPoint, text: string)
|
||||||
|
|
||||||
proc writeToPNG*(sur: PSurface, filename: string) =
|
proc writeToBMP*(sur: PSurface, filename: string) =
|
||||||
## writes the contents of the surface `sur` to the file `filename`.
|
## Saves the contents of the surface `sur` to the file `filename` as a
|
||||||
|
## BMP file.
|
||||||
|
if sdl.saveBMP(sur.s, filename) != 0:
|
||||||
|
raise newException(EIO, "cannot write: " & filename)
|
||||||
|
|
||||||
type
|
type
|
||||||
TPixels = array[0..1000_000-1, int32]
|
TPixels = array[0..1000_000-1, int32]
|
||||||
PPixels = ptr TPixels
|
PPixels = ptr TPixels
|
||||||
|
|
||||||
template setPix(video, pitch, x, y, col: expr): expr =
|
template setPix(video, pitch, x, y, col: expr): stmt =
|
||||||
video[y * pitch + x] = col
|
video[y * pitch + x] = int32(col)
|
||||||
|
|
||||||
template getPix(video, pitch, x, y: expr): expr =
|
template getPix(video, pitch, x, y: expr): expr =
|
||||||
video[y * pitch + x]
|
colors.TColor(video[y * pitch + x])
|
||||||
|
|
||||||
const
|
const
|
||||||
ColSize = 4
|
ColSize = 4
|
||||||
|
|
||||||
proc getPixel(sur: PSurface, x, y: Natural): TColor =
|
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor =
|
||||||
result = getPix(PPixels(sur.pixels), sur.pitch div ColSize, x, y)
|
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch div ColSize, x, y)
|
||||||
|
|
||||||
proc setPixel(sur: PSurface, x, y: Natural; col: TColor) =
|
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) =
|
||||||
setPix(PPixels(sur.pixels), sur.pitch div ColSize, x, y, col)
|
var pixs = cast[PPixels](sur.s.pixels)
|
||||||
|
#pixs[y * (sur.s.pitch div colSize) + x] = int(col)
|
||||||
|
setPix(pixs, sur.s.pitch div ColSize, x, y, col)
|
||||||
|
|
||||||
proc `[]`*(sur: PSurface, p: TPoint): TColor =
|
proc `[]`*(sur: PSurface, p: TPoint): TColor =
|
||||||
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): TColor =
|
||||||
result = setPixel(sur, x, y)
|
# result = setPixel(sur, x, y)
|
||||||
|
|
||||||
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) =
|
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) =
|
||||||
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: TColor) =
|
||||||
setPixel(sur, x, y, col)
|
# setPixel(sur, x, y, col)
|
||||||
|
|
||||||
proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||||
## 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 = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
var p = 1 - r
|
var a = 1 - r
|
||||||
var py = r
|
var py = r
|
||||||
var px = 0
|
var px = 0
|
||||||
var x = p.x
|
var x = p.x
|
||||||
var y = p.y
|
var y = p.y
|
||||||
while px <= py + 1:
|
while px <= py + 1:
|
||||||
setPix(video, pitch, x + px, y + py, color)
|
setPix(video, pitch, x + px, y + py, color)
|
||||||
setPix(video, pitch, x + px, y - py, color)
|
setPix(video, pitch, x + px, y - py, color)
|
||||||
setPix(video, pitch, x - px, y + py, color)
|
setPix(video, pitch, x - px, y + py, color)
|
||||||
setPix(video, pitch, x - px, y - py, color)
|
setPix(video, pitch, x - px, y - py, color)
|
||||||
|
|
||||||
setPix(video, pitch, x + py, y + px, color)
|
setPix(video, pitch, x + py, y + px, color)
|
||||||
setPix(video, pitch, x + py, y - px, color)
|
setPix(video, pitch, x + py, y - px, color)
|
||||||
setPix(video, pitch, x - py, y + px, color)
|
setPix(video, pitch, x - py, y + px, color)
|
||||||
setPix(video, pitch, x - py, y - px, color)
|
setPix(video, pitch, x - py, y - px, color)
|
||||||
|
|
||||||
if p < 0:
|
if a < 0:
|
||||||
p = p + (2 * px + 3)
|
a = a + (2 * px + 3)
|
||||||
else:
|
else:
|
||||||
p = p + (2 * (px - py) + 5)
|
a = a + (2 * (px - py) + 5)
|
||||||
py = py - 1
|
py = py - 1
|
||||||
px = px + 1
|
px = px + 1
|
||||||
|
|
||||||
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||||
## 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 x0: int = p1.x
|
var x0: int = p1.x
|
||||||
var x1: int = p2.x
|
var x1: int = p2.x
|
||||||
var y0: int = p1.y
|
var y0: int = p1.y
|
||||||
var y1: int = p2.y
|
var y1: int = p2.y
|
||||||
var dy: int = y1 - y0
|
var dy: int = y1 - y0
|
||||||
var dx: int = x1 - x0
|
var dx: int = x1 - x0
|
||||||
if dy < 0:
|
if dy < 0:
|
||||||
dy = -dy
|
dy = -dy
|
||||||
stepy = -1
|
stepy = -1
|
||||||
else:
|
else:
|
||||||
stepy = 1
|
stepy = 1
|
||||||
if dx < 0:
|
if dx < 0:
|
||||||
dx = -dx
|
dx = -dx
|
||||||
stepx = -1
|
stepx = -1
|
||||||
else:
|
else:
|
||||||
stepx = 1
|
stepx = 1
|
||||||
dy = dy * 2
|
dy = dy * 2
|
||||||
dx = dx * 2
|
dx = dx * 2
|
||||||
var video = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
setPix(video, pitch, x0, y0, color)
|
setPix(video, pitch, x0, y0, color)
|
||||||
if dx > dy:
|
if dx > dy:
|
||||||
var fraction = dy - (dx div 2)
|
var fraction = dy - (dx div 2)
|
||||||
while x0 != x1:
|
while x0 != x1:
|
||||||
if fraction >= 0:
|
if fraction >= 0:
|
||||||
y0 = y0 + stepy
|
y0 = y0 + stepy
|
||||||
fraction = fraction - dx
|
fraction = fraction - dx
|
||||||
x0 = x0 + stepx
|
x0 = x0 + stepx
|
||||||
fraction = fraction + dy
|
fraction = fraction + dy
|
||||||
setPix(video, pitch, x0, y0, color)
|
setPix(video, pitch, x0, y0, color)
|
||||||
else:
|
else:
|
||||||
var fraction = dx - (dy div 2)
|
var fraction = dx - (dy div 2)
|
||||||
while y0 != y1:
|
while y0 != y1:
|
||||||
if fraction >= 0:
|
if fraction >= 0:
|
||||||
x0 = x0 + stepx
|
x0 = x0 + stepx
|
||||||
fraction = fraction - dy
|
fraction = fraction - dy
|
||||||
y0 = y0 + stepy
|
y0 = y0 + stepy
|
||||||
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: TColor) =
|
||||||
## draws a horizontal line from (x,y) to (x+w-1, h).
|
## draws a horizontal line from (x,y) to (x+w-1, h).
|
||||||
var video = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
for i = 0 .. w-1: setPix(video, pitch, x + i, y, color)
|
for i in 0 .. w-1: 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: TColor) =
|
||||||
## 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 = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
for i in 0 .. h-1: setPix(video, pitch, x, y + i, color)
|
for i in 0 .. h-1: 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: TColor) =
|
||||||
## 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 p = 1 - r
|
var a = 1 - r
|
||||||
var py: int = r
|
var py: int = r
|
||||||
var px = 0
|
var px = 0
|
||||||
var x = p.x
|
var x = p.x
|
||||||
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 p < 0:
|
if a < 0:
|
||||||
p = p + (2 * px + 3)
|
a = a + (2 * px + 3)
|
||||||
else:
|
else:
|
||||||
p = p + (2 * (px - py) + 5)
|
a = a + (2 * (px - py) + 5)
|
||||||
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: TColor) =
|
||||||
## draws a rectangle.
|
## draws a rectangle.
|
||||||
var video = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
for i in 0 .. r.w-1:
|
for i in 0 .. r.width-1:
|
||||||
setPix(video, pitch, r.x + i, r.y, color)
|
setPix(video, pitch, r.x + i, r.y, color)
|
||||||
for i in 0 .. r.h-1:
|
for i in 0 .. r.height-1:
|
||||||
setPix(video, pitch, r.x, r.y + i, color)
|
setPix(video, pitch, r.x, r.y + i, color)
|
||||||
setPix(video, pitch, r.x + r.w - 1, r.y + i, color)
|
setPix(video, pitch, r.x + r.width - 1, r.y + i, color)
|
||||||
for i in 0 .. r.w-1:
|
for i in 0 .. r.width-1:
|
||||||
setPix(video, pitch, r.x + i, r.y + r.h - 1, color)
|
setPix(video, pitch, r.x + i, r.y + r.height - 1, color)
|
||||||
|
|
||||||
proc fillRect*(sur: PSurface, r: TRect, col: TColor) =
|
proc fillRect*(sur: PSurface, r: TRect, col: TColor) =
|
||||||
## draws and fills a rectancle.
|
## draws and fills a rectancle.
|
||||||
var video = sur.pixels
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.pitch div ColSize
|
assert video != nil
|
||||||
for i in r.y..y+r.h-1:
|
var pitch = sur.s.pitch div ColSize
|
||||||
for j in r.x..r.x+r.w-1:
|
for i in r.y..r.y+r.height-1:
|
||||||
setPix(video, pitch, j, i, color)
|
for j in r.x..r.x+r.width-1:
|
||||||
|
setPix(video, pitch, j, i, col)
|
||||||
|
|
||||||
|
if sdl.Init(sdl.INIT_VIDEO) < 0:
|
||||||
|
echo "init failed"
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
var surf = newSurface(800, 600)
|
||||||
|
var r: TRect = (0, 0, 200, 300)
|
||||||
|
surf.fillRect(r, colBlue)
|
||||||
|
surf.drawHorLine(5, 5, 60, colRed)
|
||||||
|
surf.setPixel(70, 100, colWhite)
|
||||||
|
surf.writeToBMP("test.bmp")
|
||||||
|
|
|
||||||
|
|
@ -162,11 +162,15 @@ iterator split*(s: string, seps: set[char] = Whitespace): string =
|
||||||
## produces the same output.
|
## produces the same output.
|
||||||
var last = 0
|
var last = 0
|
||||||
assert(not ('\0' in seps))
|
assert(not ('\0' in seps))
|
||||||
|
#echo "cam here 1", s
|
||||||
while last < len(s):
|
while last < len(s):
|
||||||
while s[last] in seps: inc(last)
|
while s[last] in seps: inc(last)
|
||||||
var first = last
|
var first = last
|
||||||
|
#echo "A first: ", first, " last: ", last
|
||||||
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
while last < len(s) and s[last] not_in seps: inc(last) # BUGFIX!
|
||||||
|
#echo "B first: ", first, " last: ", last
|
||||||
if first <= last-1:
|
if first <= last-1:
|
||||||
|
echo copy(s, first, last-1)
|
||||||
yield copy(s, first, last-1)
|
yield copy(s, first, last-1)
|
||||||
|
|
||||||
iterator split*(s: string, sep: char): string =
|
iterator split*(s: string, sep: char): string =
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ proc xmlCheckedTag*(e: PNimrodNode, tag: string,
|
||||||
# will be modified, so that each attribute is only given one value
|
# will be modified, so that each attribute is only given one value
|
||||||
var req = split(reqAttr)
|
var req = split(reqAttr)
|
||||||
var opt = split(optAttr)
|
var opt = split(optAttr)
|
||||||
|
echo "##", optAttr, "##", opt.len
|
||||||
result = newNimNode(nnkBracket, e)
|
result = newNimNode(nnkBracket, e)
|
||||||
result.add(newStrLitNode("<"))
|
result.add(newStrLitNode("<"))
|
||||||
result.add(newStrLitNode(tag))
|
result.add(newStrLitNode(tag))
|
||||||
|
|
|
||||||
2583
lib/wrappers/sdl/sdl.nim
Executable file
2583
lib/wrappers/sdl/sdl.nim
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
||||||
t99bott.nim;20;constant expression expected
|
t99bott.nim;20;constant expression expected
|
||||||
tadrdisc.nim;15;for a 'var' type a variable needs to be passed
|
tadrdisc.nim;15;for a 'var' type a variable needs to be passed
|
||||||
tambsym.nim;6;ambiguous identifier
|
tambsym.nim;6;ambiguous identifier
|
||||||
|
tambsym2.nim;4;undeclared identifier: 'CreateRGBSurface'
|
||||||
tambsym3.nim;6;ambiguous identifier
|
tambsym3.nim;6;ambiguous identifier
|
||||||
tbind2.nim;7;ambiguous call
|
tbind2.nim;7;ambiguous call
|
||||||
tbind4.nim;4;instantiation from here
|
tbind4.nim;4;instantiation from here
|
||||||
|
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ proc colorBool(b: bool): string =
|
||||||
else: result = "<span color:\"red\">no</span>"
|
else: result = "<span color:\"red\">no</span>"
|
||||||
|
|
||||||
proc `$`(r: TResults): string =
|
proc `$`(r: TResults): string =
|
||||||
result = "<table><tr><td>Test</td><td>Expected</td>" &
|
result = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
|
||||||
"<td>Given</td><td>Success</td></tr>\n"
|
"<td>Given</td><td>Success</td></tr>\n"
|
||||||
for test, expected, given, success in items(r.data):
|
for test, expected, given, success in items(r.data):
|
||||||
result.add("<tr><td>$#</td><td>$#</td><td>$#</td><td>$#</td></tr>\n" % [
|
result.add("<tr><td>$#</td><td>$#</td><td>$#</td><td>$#</td></tr>\n" % [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue