Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- billy = {}
- billy.time = 0
- billy.keys = {}
- billy.keys.used = {}
- billy.keys.used[29] = true
- billy.keys.quit = 29
- --[[
- miscellaneous functions and values.
- ]]
- local misc = {}
- misc.flipTable = function(table)
- local ntable = {}
- for i=1,#table do
- ntable[i] = table[#table - i + 1]
- end
- return ntable
- end
- misc.split = function(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- if str ~= nil then
- local fpat = "(.-)" .. pat
- local last_end = 1
- local s, e, cap = str:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = str:find(fpat, last_end)
- end
- if last_end <= #str then
- cap = str:sub(last_end)
- table.insert(t, cap)
- end
- else
- print("##ERROR failed to split ["..str.."] by:"..pat)
- end
- return t
- end
- billy.misc = misc
- --[[
- Dump table;
- not used inside billy - basically just an alternative to using the _G table if you don't want
- to clutter in it, as cluttering the _G table is more of a problem in CC than it is in LOVE
- ]]
- billy.dump = {}
- --[[
- All the standard override functions,
- override these and they get called at the appropriate time.
- ]]
- billy.load = function() end --called when the program starts
- billy.update = function() end --called every 0.05 seconds
- billy.draw = function() return false end --called every time the game is drawn, after update, every 0.05 seconds, return true/false depending on if changes have/haven't been made
- billy.event = function() end --called every time an event is called
- billy.quit = function() end --called when the game is quit using the quit button
- --[[
- graphics table for billy;
- contains all the graphics functions
- ]]
- local graphics = {}
- --[[
- data to be set in graphics functions for the graphics functions,
- It's safer to ignore this table, but you don't have to.
- ]]
- graphics.LOCAL_DATA = {}
- graphics.LOCAL_DATA.background = colors.black
- graphics.LOCAL_DATA.text = colors.white
- graphics.LOCAL_DATA.size = 1
- graphics.LOCAL_DATA.char = " "
- --[[
- Function to set the background colour in LOCAL_DATA, can be called by both:
- setBackgroundColor(colour)
- setBackgroundColour(colour)
- returns:
- old, colour
- where:
- old is the old background colour that was used
- colour is the new background colour being used
- ]]
- graphics.setBackgroundColor = function(color)
- local old = graphics.LOCAL_DATA.background
- graphics.LOCAL_DATA.background = color
- return old, color
- end
- graphics.setBackgroundColour = function(color) return graphics.setBackgroundColor(color) end
- --[[
- Function to set the text colour in LOCAL_DATA, can be called by both:
- setTextColor(colour)
- setTextColour(colour)
- returns:
- old, colour
- where:
- old is the old text colour that was used
- colour is the new text colour being used
- ]]
- graphics.setTextColor = function(color)
- local old = graphics.LOCAL_DATA.background
- graphics.LOCAL_DATA.text = color
- return old, color
- end
- graphics.setTextColour = function(color) return graphics.setTextColor(color) end
- --[[
- Function to set the size value in LOCAL_DATA,
- returns:
- old, size
- where:
- old is the old size value that was used
- size is the new size value being used
- ]]
- graphics.setSize = function(size)
- local old = graphics.LOCAL_DATA.size
- graphics.LOCAL_DATA.size = size
- return old, size
- end
- --[[
- Function to set the char value in LOCAL_DATA,
- returns:
- old, char
- where:
- old is the old char value that was used
- char is the new char value being used
- ]]
- graphics.setChar = function(char)
- local old = graphics.LOCAL_DATA.char
- graphics.LOCAL_DATA.char = char
- return old, char
- end
- --[[
- Function to draw a line between to points;
- x1,y1 are the x,y co-ordinates of the first point on the line
- x2,y2 are the x,y co-ordinates of the last point on the line
- returns:
- a table containing all positions of the line in the format:
- table[i] = {x, y}
- where:
- i = index of table, a number
- x,y are the x,y positions of the point on the line
- note:
- the table returned always has the first point as x1,y2 and the last point as x2,y2;
- so it keeps it's order.
- ]]
- graphics.drawLine = function(x1, y1, x2, y2)
- local pixs = {}
- x1 = math.floor(x1)
- y1 = math.floor(y1)
- x2 = math.floor(x2)
- y2 = math.floor(y2)
- if x1 == x2 and y1 == y2 then
- pixs[#pixs + 1] = {x1, y1}
- return pixs
- end
- local minX = math.min( x1, x2 )
- if minX == x1 then
- minY = y1
- maxX = x2
- maxY = y2
- else
- minY = y2
- maxX = x1
- maxY = y1
- end
- local xDiff = maxX - minX
- local yDiff = maxY - minY
- if xDiff > math.abs(yDiff) then
- local y = minY
- local dy = yDiff / xDiff
- for x=minX,maxX do
- if #pixs > 0 then
- if pixs[#pixs][1] == x and pixs[#pixs][2] == math.floor(y + 0.5) then else
- pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
- end
- else
- pixs[#pixs + 1] = {x, math.floor(y + 0.5)}
- end
- y = y + dy
- end
- else
- local x = minX
- local dx = xDiff / yDiff
- if maxY >= minY then
- for y=minY,maxY do
- if #pixs > 0 then
- if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- x = x + dx
- end
- else
- for y=minY,maxY,-1 do
- if #pixs > 0 then
- if pixs[#pixs][1] == math.floor(x+0.5) and pixs[#pixs][2] == y then else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- else
- pixs[#pixs + 1] = {math.floor(x+0.5), y}
- end
- x = x - dx
- end
- end
- end
- if pixs[1][1] == x2 and pixs[1][2] == y2 then pixs = billy.misc.flipTable(pixs) end
- return pixs
- end
- --[[
- Creates a polygon,
- poly is a table in the format:
- table[i] = {x,y}
- where:
- i = index of table, a number
- x,y = x,y co-ordinates of one of the corners of the polygon
- returns:
- shape
- where:
- shape is a table containing the following values and functions:
- shape.det = a string containing all the points of the corners of the polygon on it
- shape.poly = the table you used to create the shape
- shape.back = background colour of the shape
- shape.text = text colour of the shape
- shape.char = character used to draw the shape
- shape:draw = function that draws the polygon, no parameters or returns.
- ]]
- graphics.createShape = function(poly)
- local shape = {}
- local l = ""
- for i=1,#poly do
- local p1 = poly[i]
- local p2 = poly[i+1]
- if i == #poly then p2 = poly[1] end
- local line = drawLine(p1[1], p1[2], p2[1], p2[2])
- for j=1,#line do
- shape[#shape + 1] = line[j]
- end
- l = l..p1[1]..","..p1[2].." "
- end
- shape.det = l
- shape.poly = poly
- shape.back = billy.graphics.LOCAL_DATA.background
- shape.text = billy.graphics.LOCAL_DATA.text
- shape.char = billy.graphics.LOCAL_DATA.char
- shape.draw = function(self)
- for i=1,#self do
- local p = self[i]
- billy.buffer.setCursorPos(p[1], p[2])
- billy.buffer.setBackgroundColor(self.back)
- billy.buffer.setTextColor(self.text)
- billy.buffer.write(self.char)
- end
- --[[
- for i=1,#self.poly do
- local p = self.poly[i]
- billy.buffer.setCursorPos(p[1], p[2])
- billy.buffer.setBackgroundColor(self.back)
- billy.buffer.setTextColor(self.text)
- billy.buffer.write(tostring(i))
- end
- ]]
- --billy.buffer.setCursorPos(1, sh-1)
- --billy.buffer.write(self.det)
- end
- return shape
- end
- --[[
- Function that draws a shape with the current LOCAL_DATA,
- exactly the same as shape:draw but uses LOCAL_DATA for colours instead of the shape's colours.
- can be used to draw Triangles and Squares (Filled in ones)
- ]]
- graphics.drawShape = function(shape)
- for i=1,#shape do
- local p = shape[i]
- billy.buffer.setCursorPos(p[1], p[2])
- billy.buffer.setBackgroundColor(graphics.LOCAL_DATA.background)
- billy.buffer.setTextColor(graphics.LOCAL_DATA.text)
- billy.buffer.write(graphics.LOCAL_DATA.char)
- end
- end
- --[[
- Creates a Triangle, for use with fillTriangle
- p1,p2,p3 - the 3 co-ordinates of the triangle
- returns:
- table in format:
- table[x][y] = true
- ]]
- graphics.createTriangle = function(p1, p2, p3)
- local tab1 = billy.graphics.drawLine(p1[1], p1[2], p2[1], p2[2])
- local tab2 = billy.graphics.drawLine(p1[1], p1[2], p3[1], p3[2])
- local tab3 = billy.graphics.drawLine(p2[1], p2[2], p3[1], p3[2])
- local tabs = {tab1, tab2, tab3}
- local triangle = {}
- for i=1,#tabs do
- local tab = tabs[i]
- for i=1,#tab do
- local pos = tab[i]
- if triangle[x] == nil then triangle[x] = {} end
- triangle[pos[1]][pos[2]] = true
- end
- end
- return triangle
- end
- --[[
- Fills in a triangle, must be a triangle returned from createTriangle, NOT createShape
- tri - a triangle returned from createTriangle
- returns:
- table containing all the points in the triangle in format:
- table[i] = {x,y}
- where:
- i = index of table, a number
- x,y = the x,y coordinates of the point on the triangle
- ]]
- graphics.fillTriangle = function(tri)
- local minX, maxX = nil
- local minys = {}
- for x,v in pairs(tri) do
- if minX == nil then
- minX = x
- elseif x < minX then
- minX = x
- end
- if maxX == nil then
- maxX = x
- elseif x > maxX then
- maxX = x
- end
- if v ~= nil then
- local minY = nil
- for y,r in pairs(v) do
- if minY == nil then
- minY = y
- elseif y < minY then
- minY = y
- end
- end
- if minY ~= nil then
- if minys[x] == nil then minys[x] = {} end
- minys[x] = minY
- end
- end
- end
- local ntri = {}
- for x,v in pairs(tri) do
- if v ~= nil then
- for y,r in pairs(v) do
- ntri[#ntri + 1] = {x,y}
- end
- end
- end
- if minX ~= nil and maxX ~= nil then
- for x=minX, maxX do
- if minys[x] ~= nil then
- local y = minys[x]
- if tri[x] ~= nil then
- if getSize(tri[x]) > 1 then
- local check = false
- while check == false do
- y = y + 1
- if tri[x] ~= nil then
- if tri[x][y] ~= nil then check = true end
- end
- if y >= h then check = true end
- --term.setCursorPos(1, h-2)
- --print("y = "..y.."; x = "..x)
- --if check then
- ntri[#ntri + 1] = {x,y}
- --end
- end
- end
- end
- end
- end
- end
- return ntri
- end
- --[[
- function that creates a quadrilateral,
- p1,p2,p3,p4 = the 4 points of the quadrilateral
- returns:
- table containing all the points of the square in format:
- table[i] = {x,y}
- where:
- i = index of table, a number
- x,y = the x,y coordinates of the point on the square
- ]]
- graphics.fillQuad = function(p1, p2, p3, p4)
- local tri1 = billy.graphics.fillTriangle(getTriangle(p1, p2, p3))
- local tri2 = billy.graphics.fillTriangle(getTriangle(p1, p4, p3))
- local tris = {tri1, tri2}
- local square = {}
- for i=1,#tris do
- local tri = tris[i]
- for i=1,#tri do
- local pos = tri[i]
- local x = pos[1]
- local y = pos[2]
- square[#square + 1] = {x,y}
- end
- end
- return square
- end
- --[[
- Creates a circle;
- center = table containing {x,y} coordinates of the centre point
- radius = the radius of the circle
- fill = boolean as to whether or not the circle is filled in
- returns:
- table containing all the points in the circle on it, format:
- table[i] = {x,y}
- where:
- i = index of table, a number
- x,y = the x,y coordinates of the point
- ]]
- graphics.createCircle = function(center, radius, fill)
- -- (x-a)^2 + (y-B)^2 = r^2 (formula, where r is radius, x and y are coordinates and a and b is center)
- local pixs = {}
- local rads = radius^2
- local topright = {center[1]-radius, center[2]-radius}
- local bottomleft = {center[1]+radius, center[2]+radius}
- for cx=topright[1],bottomleft[1],1 do
- for cy=topright[2],bottomleft[2],1 do
- local xb = (cx-center[1])^2
- local yb = (cy-center[2])^2
- if (xb+yb) == rads then
- pixs[#pixs + 1] = {cx, cy}
- elseif fill and (xb+yb) <= rads then
- pixs[#pixs + 1] = {cx, cy}
- end
- end
- end
- return pixs
- end
- billy.graphics = graphics
- local IO = {}
- --[[
- gets all of the lines out of a file
- dir - the directory of the file
- returns:
- a table containing all the lines, in format:
- table[i] = line
- where:
- i = index of the table, a number
- line = the line of the file
- ]]
- IO.getLines = function(dir)
- local lines = {}
- if fs.exists(dir) then
- local file = fs.open(dir, "r")
- local line = file.readLine()
- while line ~= nil do
- lines[#lines + 1] = line
- line = file.readLine()
- end
- file.close()
- end
- return lines
- end
- --[[
- re-writes a file (or creates a new one) with the lines in it
- dir - the directory of the file
- lines - a table containing all the lines to write in the format:
- table[i] = line
- where:
- i = index of the table, a number
- line = the line of the file
- no returns.
- ]]
- IO.writeLines = function(dir, lines)
- local file = fs.open("w")
- for i=1,#lines do
- local line = lines[i]
- file.writeLine(line)
- end
- file.close()
- end
- --[[
- adds lines to a file at certain index, adds them before the line at that index
- dir - the directory of the file
- lines - a table containing all of the lines and their indexes, in the format:
- table[i] = {index, line}
- where:
- i = index of the table, a number
- index = index of the file to put the line in
- line = line to add to the file
- no returns.
- ]]
- IO.addLines = function(dir, lines)
- local lns = billy.IO.getLines(dir)
- local nlines = {}
- for i=1,#lns do
- local line = lines[i]
- for i=1,#lines do
- if lines[i][1] == i then nlines[#nlines + 1] = lines[i][2] end
- end
- nlines[#nlines + 1] = line
- end
- billy.IO.writeLines(nlines)
- end
- billy.IO = IO
- local image = {}
- --[[
- creates a table in image-table format from a file
- dir - the directory of the file
- returns:
- a table containing all of the characters in the file in the following format:
- table[x][y] = character
- where:
- x = the x position of the character
- y = the y position of the character
- character = the character
- the table also contains another table called "data", this contains significant data
- about the images and formating of the image-table.
- ]]
- image.createImageTable = function(dir)
- local lines = billy.IO.getLines(file)
- local imgtab = {}
- for y=1,#lines do
- local line = lines[y]
- if line:sub(1, 5) ~= "DAT::" then
- for x=1,string.len(line) do
- local char = line:sub(x, y)
- if imgtab[x] == nil then imgtab[x] = {} end
- imgtab[x][y] = char
- end
- else
- imgtab.data[#imgtab.data] = billy.misc.split(string.lower(line:sub(6, -1)), "::")
- end
- end
- return imgtab
- end
- --[[
- creates an image table out of a imgtab table using the appropriate name
- imgtab - the image-table
- name - the name of the image in the image-table
- returns:
- a table containing all of the characters in the image in the following format:
- table[x][y] = character
- where:
- x = the x position of the character
- y = the y position of the character
- character = the character
- the table also contains the following values:
- table.x = the x coordinate of the image
- table.y = the y coordinate of the image
- table.width = the width of the image
- table.height = the height of the image
- NOTE:
- if you want to get the true coordinate of one of the image coordinates it can be done via:
- c+image.c-1
- where:
- c = the x or y coordinate inside the image from 1 to width
- image = the image table
- image.c = image.x/y depending on what c is
- the -1 must be there as the inner-image co-ords start at 1, not 0.
- ]]
- image.getImage = function(imgtab, name)
- local data = imgtab.data
- for i=1,#data do
- local tab = data[i]
- if tab[1] == "image" then
- if tab[2] == name then
- local x1 = tonumber(tab[3])
- local y1 = tonumber(tab[4])
- local x2 = tonumber(tab[5])
- local y2 = tonumber(tab[6])
- local img = {}
- img.x = x1
- img.y = y1
- img.width = x2-x1+1
- img.height = y2-y1+1
- for x=x1,x2 do
- for y=y1,y2 do
- if imgtab[x] ~= nil then
- local char = imgtab[x][y]
- if char ~= nil then
- img[x-x1+1][y-y1+1] = char
- end
- end
- end
- end
- return img
- end
- end
- end
- return nil
- end
- billy.image = image
- local bufferAPI = {}
- bufferAPI.curCols = {} --almost useless, saves presents of "colour" combinations when they are used - character, background and text colour.
- bufferAPI.buffer_details = {1, 1, colors.black, colors.white, nil}
- local sw,sh = term.getSize()
- bufferAPI.getColorTab = function(char, background, text)
- if billy.bufferAPI.curCols[char] ~= nil then
- if billy.bufferAPI.curCols[char][background] ~= nil then
- if billy.bufferAPI.curCols[char][background][text] ~= nil then
- return billy.bufferAPI.curCols[char][background][text]
- end
- end
- end
- return nil
- end
- bufferAPI.addColorTab = function(col)
- local char = col.char
- local background = col.background
- local text = col.text
- if billy.bufferAPI.getColorTab(char, background, text) == nil then
- if billy.bufferAPI.curCols[char] == nil then billy.bufferAPI.curCols[char] = {} end
- if billy.bufferAPI.curCols[char][background] == nil then billy.bufferAPI.curCols[char][background] = {} end
- billy.bufferAPI.curCols[char][background][text] = col
- return true
- end
- return false
- end
- bufferAPI.createColor = function(char, background, text)
- --sleep(0)
- local col = billy.bufferAPI.getColorTab(char, background, text)
- if col == nil then
- col = {}
- col.char = char
- col.background = background
- col.text = text
- billy.bufferAPI.addColorTab(col)
- end
- return col
- end
- bufferAPI.createPixel = function(x, y, col)
- local pixel = {}
- pixel.x = x
- pixel.y = y
- pixel.col = col
- pixel.compare = function(self, col)
- return self.col == col
- end
- return pixel
- end
- bufferAPI.createBuffer = function()
- local buffer = {}
- buffer.width = sw
- buffer.height = sh
- buffer.changes = {}
- buffer.changed = {}
- buffer.term = term
- buffer.ps = 0
- billy.bufferAPI.buffer_details[5] = buffer
- for x=1,sw do
- buffer[x] = {}
- buffer.changes[x] = {}
- for y=1,sh do
- --print("x="..x..", y="..y)
- buffer[x][y] = billy.bufferAPI.createPixel(x, y, billy.bufferAPI.createColor(" ", colors.black, colors.white))
- buffer.changes[x][y] = false
- end
- end
- buffer.get = function(self, x, y)
- if self[x] ~= nil then
- if self[x][y] ~= nil then
- return self[x][y]
- end
- end
- return nil
- end
- buffer.check = function(self, x, y)
- if self.changes[x] ~= nil then
- if self.changes[x][y] ~= nil then
- return self.changes[x][y]
- end
- end
- return false
- end
- buffer.set = function(self, x, y, col)
- local pixel = self:get(x,y)
- if pixel ~= nil then
- if not pixel:compare(col) then
- pixel.col = col
- if not self:check(x,y) then
- self.changed[#self.changed + 1] = {x,y}
- if self.changes[x] == nil then self.changes[x] = {} end
- self.changes[x][y] = true
- end
- end
- end
- end
- buffer.render = function(self)
- for i=1,#self.changed do
- local pos = self.changed[i]
- self.changes[pos[1]][pos[2]] = false
- local pixel = self[pos[1]][pos[2]]
- self.term.setCursorPos(pixel.x, pixel.y)
- self.term.setBackgroundColor(pixel.col.background)
- self.term.setTextColor(pixel.col.text)
- self.term.write(pixel.col.char)
- end
- --term.setCursorPos(1, 13)
- --term.setBackgroundColor(colors.black)
- --term.setTextColor(colors.white)
- --print(#self.changed.." pixels changed")
- self.ps = #self.changed
- self.changed = {}
- end
- buffer.setBuffer = function(self)
- buffer_detials[5] = self
- end
- buffer.setCursorPos = function(x, y)
- billy.bufferAPI.buffer_details[1] = x
- billy.bufferAPI.buffer_details[2] = y
- end
- buffer.setBackgroundColor = function(col)
- billy.bufferAPI.buffer_details[3] = col
- end
- buffer.setTextColor = function(col)
- billy.bufferAPI.buffer_details[4] = col
- end
- buffer.getSize = function()
- local buffer = billy.bufferAPI.buffer_details[5]
- if buffer == nil then print("NIL_BUFFER") return 1,1 else
- return billy.bufferAPI.buffer_details[5].width, billy.bufferAPI.buffer_details[5].height
- end
- end
- buffer.writeChar = function(char, ox, oy)
- if ox == nil then ox = 0 end
- if oy == nil then oy = 0 end
- char = char:sub(1,1)
- local col = billy.bufferAPI.createColor(char, billy.bufferAPI.buffer_details[3], billy.bufferAPI.buffer_details[4])
- local buffer = billy.bufferAPI.buffer_details[5]
- if buffer ~= nil then
- buffer:set(billy.bufferAPI.buffer_details[1]+ox, billy.bufferAPI.buffer_details[2]+oy, col)
- end
- end
- buffer.write = function(str)
- for i=1,string.len(str) do
- billy.buffer.writeChar(str:sub(i,i), i-1, 0)
- end
- end
- buffer.clear = function()
- billy.bufferAPI.buffer_details[5]:reset()
- end
- buffer.reset = function(self)
- local buffer = self
- for x=1,self.width do
- buffer[x] = {}
- buffer.changes[x] = {}
- for y=1,sh do
- --print("x="..x..", y="..y)
- local pixel = billy.bufferAPI.createPixel(x, y, billy.bufferAPI.createColor(" ", billy.bufferAPI.buffer_details[3], colors.white))
- self.term.setCursorPos(x, y)
- self.term.setBackgroundColor(pixel.col.background)
- self.term.setTextColor(pixel.col.text)
- self.term.write(pixel.col.char)
- buffer[x][y] = pixel
- buffer.changes[x][y] = false
- end
- end
- buffer.changes = {}
- buffer.changed = {}
- end
- return buffer
- end
- billy.bufferAPI = bufferAPI
- billy.buffer = billy.bufferAPI.createBuffer()
- local args = {...}
- if #args > 0 then
- shell.run(unpack(args))
- print(billy.load())
- local pause = 0.05
- local on = true
- local timer = os.startTimer(pause)
- while on do
- local event,p1,p2,p3 = os.pullEvent()
- if event == "timer" and p1 == timer then
- billy.time = billy.time + 1
- billy.update()
- if billy.draw() then
- billy.buffer:render()
- end
- elseif event == "key" and billy.keys.used[p1] == true then
- if billy.keys.quit == p1 then
- billy.quit()
- on = false
- end
- else
- billy.event(event, p1, p2, p3)
- end
- if on then
- timer = os.startTimer(pause)
- end
- end
- else
- print("Error: No program entered")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement