Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- LOGO Turtle graphics API v0.3.2
- code by GopherAtl.
- Do anything you want with this code except claim credit for it.
- If you distribute a program that uses it, please link users to the
- official thread on the cc forums here:
- http://www.computercraft.info/forums2/index.php?/topic/4006-logo-interpreter/
- If you distribute a modified version with fixes or enhancements, please link to
- it in the official thread as well.
- --]]
- --character aspect ratio - constant
- local charAspect=6.0/9.0
- --current turtle location info
- local curX,curY=0,0
- local curAngle=0
- --the view scale - how many units from center to the nearest edge (usually top/bottom)
- local curScale=100
- --pen state
- local isPenDown=true
- local curPenChar="X"
- --list of display objects being used
- local displays={}
- --unused at present, will remember line data so it can be redrawn
- local lineData={
- { pos={0, 0, 0}, angle=0 }
- }
- --Bresenham's line algo, adapted to lua by me
- function line(device,x1,y1,x2,y2,ch)
- local steep = math.abs(y2-y1)>math.abs(x2-x1)
- local setPos
- if steep then
- y1,x1=x1,y1
- y2,x2=x2,y2
- setPos=function(y,x) device.setCursorPos(x,y) end
- else
- setPos=function(x,y) device.setCursorPos(x,y) end
- end
- if x1>x2 then
- x1,x2=x2,x1
- y1,y2=y2,y1
- end
- local dx=x2-x1
- local dy=math.abs(y2-y1)
- local err=dx/2
- local ys= y1<y2 and 1 or -1
- local y=y1
- for x=x1,x2 do
- setPos(x,y)
- device.write(ch)
- err=err-dy
- if err<0 then
- y=y+ys
- err=err+dx
- end
- end
- end
- --reset the state of all api variables.
- function reset()
- home()
- curPenChar="x"
- isPenDown=true
- curScale=100
- displays={}
- lineData={
- { pos={0, 0, 0}, angle=0 }
- }
- end
- function penUp()
- isPenDown=false
- end
- function penDown()
- isPenDown=true
- end
- function penChar(ch)
- curPenChar=string.sub(ch,1,1)
- end
- function moveTo(x,y)
- if isPenDown then
- for k,v in pairs(displays) do
- local x1,y1=posToScreen(curX,curY,k)
- local x2,y2=posToScreen(x,y,k)
- line(displays[k].wrapper,x1,y1,x2,y2,curPenChar)
- end
- end
- curX=x
- curY=y
- end
- function turn(angle)
- curAngle=(curAngle+angle)%360
- end
- function turnTo(angle)
- curAngle=angle%360
- end
- function forward(dist)
- local angleRad=curAngle*math.pi/180.0
- local newX=curX+dist*math.sin(angleRad)
- local newY=curY+dist*math.cos(angleRad)
- moveTo(newX,newY)
- end
- --[[
- generates values needed for saling lines to a given display
- device based on it's dimensions and defined bounds and the
- current scale.
- --]]
- local function scaleDisplay(name)
- if displays[name].width*6>displays[name].height*9 then
- --height is smaller
- displays[name].scaleY=displays[name].centerY/curScale
- displays[name].scaleX=displays[name].scaleY/charAspect
- else
- displays[name].scaleX=displays[name].centerX/curScale
- displays[name].scaleY=displays[name].scaleX*charAspect
- end
- end
- --[[
- set the scale for all devices to render; the smaller of the
- two axes, width or height, as determined by both the dimensions
- in characters of the screen and the dimensions of a single
- character in the font, will range from -newScale to scale, the
- other axis will be larger proportional to trueAspect.
- --]]
- function scale(newScale)
- curScale=newScale
- --smaller dimension of monitor will be scale
- for k,v in pairs(displays) do
- scaleDisplay(k)
- end
- end
- --convert a coordinate to a position on a given display with
- --the current scale
- function posToScreen(x,y,display)
- return x*displays[display].scaleX+displays[display].centerX+1, y*displays[display].scaleY+displays[display].centerY+1
- end
- --erases the draw area and clears the draw history
- function clean()
- for k,v in pairs(displays) do
- for y=v.minY, v.maxY do
- v.wrapper.setCursorPos(v.minX,y)
- v.wrapper.write(string.rep(" ",v.width))
- end
- end
- lineData={
- { pos={0, 0, 0}, angle=0 }
- }
- end
- --restores the turtle to it's initial state
- function home()
- curX=0
- curY=0
- curAngle=0
- end
- --[[
- add a display to the devices it's drawing to.
- wrapper is the interface, term for terminal or result of
- peripheral.wrap() for monitors.
- min/max values specify a region of the screen to draw in;
- default to full screen
- --]]
- function addDisplay(name,wrapper,minX,minY,maxX,maxY)
- --set default params
- if minX==nil then
- minX=1
- end
- if minY==nil then
- minY=1
- end
- if maxX==nil then
- local t
- maxX, t=wrapper.getSize()
- end
- if maxY==nil then
- local t
- t, maxY=wrapper.getSize()
- end
- local width, height=maxX-minX+1, maxY-minY+1
- displays[name]={
- minX=minX,
- minY=minY,
- maxX=maxX,
- maxY=maxY,
- wrapper=wrapper,
- width=width,
- height=height,
- centerX=width/2,
- centerY=height/2,
- aspect=width/height,
- trueAspect=charAspect*width/height,
- }
- scaleDisplay(name)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement