fixed graphics module

This commit is contained in:
Andreas Rumpf 2010-03-03 16:58:33 +01:00
commit 048811b2be
6 changed files with 2742 additions and 134 deletions

View file

@ -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,52 +31,58 @@ 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)
proc textBounds*(text: string): tuple[len, height: int] assert(not sdl.MustLock(result.s))
proc drawText*(sur: PSurface, p: TPoint, text: string)
proc writeToPNG*(sur: PSurface, filename: string) = #proc textBounds*(text: string): tuple[len, height: int]
## writes the contents of the surface `sur` to the file `filename`. #proc drawText*(sur: PSurface, p: TPoint, text: string)
proc writeToBMP*(sur: PSurface, filename: string) =
## 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
@ -91,16 +98,17 @@ proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
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
@ -119,8 +127,8 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
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)
@ -143,20 +151,20 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
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
@ -168,10 +176,10 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
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:
@ -183,21 +191,32 @@ proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
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")

View file

@ -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 =

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

1 t99bott.nim 20 constant expression expected
2 tadrdisc.nim 15 for a 'var' type a variable needs to be passed
3 tambsym.nim 6 ambiguous identifier
4 tambsym2.nim 4 undeclared identifier: 'CreateRGBSurface'
5 tambsym3.nim 6 ambiguous identifier
6 tbind2.nim 7 ambiguous call
7 tbind4.nim 4 instantiation from here

View file

@ -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" % [