diff --git a/scripts/boot.lua b/scripts/boot.lua index 28878c9..309431b 100644 --- a/scripts/boot.lua +++ b/scripts/boot.lua @@ -60,16 +60,18 @@ local coreFont = font.new(data) gpu.font = coreFont function write(t, x, y, col, target) + local fnt = gpu.font.data + t = tostring(t) col = col or 16 local xoff = 0 for i=1, #t do local text = t:sub(i, i) local c = string.byte(text) - if gpu.font.data[c] then + if fnt[c] then for j=1, 7 do for k=1, 7 do - if gpu.font.data[c][j][k] then + if fnt[c][j][k] then local dx = x + xoff + k local dy = y + j if target then diff --git a/scripts/home/demos/circ.lua b/scripts/home/demos/circ.lua index cb3d327..fa3a856 100644 --- a/scripts/home/demos/circ.lua +++ b/scripts/home/demos/circ.lua @@ -3,7 +3,6 @@ Random fun little thing ... I don't even know - Inspired by @egordorichev ]] @@ -15,36 +14,65 @@ local w, h = gpu.width, gpu.height local gpp = dofile("/lib/gpp.lua") +local sin, cos = math.sin, math.cos + local timer = 0 +local vel = 0 +local off = 0 +local loff = 0 local function update(dt) - timer = timer + (2 * dt) + timer = timer + dt + vel = 10 * sin(2 * timer) + loff = off + off = off + vel * dt +end + +local function round(n) + if n % 1 >= 0.5 then + return n % 1 + 1 + else + return n % 1 + end end local gr = 50 +local function cfunc(i, j) + if round(i / (math.pi / 2)) % 2 == 0 then + return 16 + else + if j % 2 == 0 then + return 9 + else + return 8 + end + end +end + local function draw() for i = 1, 1499 do local x, y = math.random(1, w), math.random(1, h) - -- gpu.drawRectangle(x - 1, y, 3, 1, 1) - -- gpu.drawRectangle(x, y - 1, 1, 3, 1) gpu.drawPixel(x - 1, y, 1) gpu.drawPixel(x + 1, y, 1) gpu.drawPixel(x, y - 1, 1) gpu.drawPixel(x, y + 1, 1) end + -- gpu.clear() - for j = 0.5, 4, 0.5 do + for j = 1, 7 do for i = 0, 2 * math.pi, math.pi / 4 do - local r = (math.sin(4 * timer + i) * gr + gr) * j - gpp.fillEllipse(w / 2 + math.cos(timer + i + (10 * j)) * r, h / 2 + math.sin(timer + i + (10 * j)) * r, 10, 10, math.floor(i * 12 + timer) % 15 + 2) + local r = (sin((timer + j / 3) * 1.5) + 1.25) * (35 + j * 10) + -- local cloff = loff * (j % 2 == 0 and 1 or -1) + -- local coff = off * (j % 2 == 0 and 1 or -1) + + for k = math.min(off, loff), math.max(off, loff), 0.05 do + local coff = k * (j % 2 == 0 and 1 or -1) + gpp.fillEllipse(w / 2 + math.cos(coff + i) * r, h / 2 + math.sin(coff + i) * r, 10, 10, cfunc(i, j)) + --math.floor((i + j) * 12) % 15 + 2) + end end end - -- for i = 0, 2 * math.pi, math.pi / 2 do - -- local r = (4 * gr) - (math.sin(4 * timer + i) * (4 * gr) + (4 * gr)) - -- gpp.fillEllipse(w / 2 + math.cos(timer + i) * r, h / 2 + math.sin(timer + i) * r, 10, 10, math.floor(i * 12 + timer) % 15 + 2) - -- end - gpu.swap() end diff --git a/scripts/home/demos/dither/astc.bmp.rif b/scripts/home/demos/dither/astc.bmp.rif new file mode 100644 index 0000000..902f38a Binary files /dev/null and b/scripts/home/demos/dither/astc.bmp.rif differ diff --git a/scripts/home/demos/dither/dither.lua b/scripts/home/demos/dither/dither.lua index c0f9b98..57077ac 100644 --- a/scripts/home/demos/dither/dither.lua +++ b/scripts/home/demos/dither/dither.lua @@ -6,6 +6,7 @@ -- (1/32) local bitmap = dofile("/lib/bitmap.lua") +local rif = dofile("/lib/rif.lua") local file = ({...})[1] or "land.bmp" @@ -91,6 +92,10 @@ for i=1, ditherImage.height do end end +local handle = fs.open(file .. ".rif", "w") +handle:write(rif.encode(dithered, ditherImage.width, ditherImage.height)) +handle:close() + while true do gpu.clear() diff --git a/scripts/home/demos/dither/tucan.bmp.rif b/scripts/home/demos/dither/tucan.bmp.rif new file mode 100644 index 0000000..2924e8b Binary files /dev/null and b/scripts/home/demos/dither/tucan.bmp.rif differ diff --git a/scripts/home/demos/ghostmark.lua b/scripts/home/demos/ghost.lua similarity index 100% rename from scripts/home/demos/ghostmark.lua rename to scripts/home/demos/ghost.lua diff --git a/scripts/home/demos/ghost.rif b/scripts/home/demos/ghost.rif index 3cdd029..7a97060 100644 Binary files a/scripts/home/demos/ghost.rif and b/scripts/home/demos/ghost.rif differ diff --git a/scripts/home/demos/ltest.lua b/scripts/home/demos/ltest.lua index fdca756..2d0a204 100644 --- a/scripts/home/demos/ltest.lua +++ b/scripts/home/demos/ltest.lua @@ -2,12 +2,15 @@ local running = true local rif = dofile("/lib/rif.lua") -local handle = fs.open("logo.rif", "rb") +local file = ({...})[1] or "logo.rif" +local handle = fs.open(file, "rb") local data = handle:read("*a") handle:close() local rifData, w, h = rif.decode1D(data) +local rifImg = rif.createImage(rifData, w, h) + local track = {} local c = 1 @@ -15,7 +18,7 @@ for i = 1, h do for j = 1, w do local d = rifData[c] if d ~= -1 then - track[#track + 1] = {c = d, dx = j + (gpu.width / 2 - 15), dy = i + (gpu.height / 2 - 35)} + track[#track + 1] = {c = d, dx = j + (gpu.width - w) / 2, dy = i + (gpu.height - h) / 2} --x = j + 140 + math.random(-40, 40), y = i + 85 + math.random(-40, 40)} end c = c + 1 @@ -41,20 +44,49 @@ local round = function(x) end end +-- local lookup = {} +-- for i = 1, #track do +-- lookup[i] = i +-- end +-- local dorder = {} +-- for i = 1, #track do +-- dorder[i] = table.remove(lookup, math.random(1, #lookup)) +-- end + +local frms = 0 local function drawContent() - local brkpt = 5 - for i=1, #track do + frms = frms + 1 + local brkpt = w + gpu.clear() + -- local min = math.huge + for i=math.max(0, math.floor((frms - 90)/1.4) * w) + 1, #track do + -- local i = dorder[pt] if not track[i].x then track[i].x = track[i].dx + math.random(-40, 40) track[i].y = track[i].dy + math.random(-40, 40) brkpt = brkpt - 1 if brkpt == 0 then break end end - gpu.drawPixel(round(track[i].x), round(track[i].y), track[i].c) + + -- if min > i then min = i end + + if math.abs(track[i].x - track[i].dx) < 1 then + gpu.drawPixel(track[i].dx, track[i].dy, track[i].c) + else + gpu.drawPixel(round(track[i].x), round(track[i].y), track[i].c) + end track[i].x = (track[i].dx - track[i].x) * 0.04 + track[i].x track[i].y = (track[i].dy - track[i].y) * 0.04 + track[i].y end + + if math.max(0, math.floor((frms - 90)/1.4)) + 1 > 1 then + rifImg:render((gpu.width - w) / 2 + 1, (gpu.height - h) / 2 + 1, w, math.min(h, math.max(0, math.floor((frms - 90)/1.4)) + 1)) + end + + -- print(min) + + -- rifImg:render(1, 1) end local eventQueue = {} @@ -75,4 +107,4 @@ while running do drawContent() gpu.swap() -end +end \ No newline at end of file diff --git a/scripts/home/demos/part.lua b/scripts/home/demos/part.lua new file mode 100644 index 0000000..cd12579 --- /dev/null +++ b/scripts/home/demos/part.lua @@ -0,0 +1,575 @@ +local rif = dofile("/lib/rif.lua") +local gpp = dofile("/lib/gpp.lua") + +local sw, sh = gpu.width, gpu.height +local fl = math.floor + +local sqrt, atan2 = math.sqrt, math.atan2 +local sin, cos = math.sin, math.cos +local csc, sec = function(x) return 1 / sin(x) end, function(x) return 1 / cos(x) end + +-- I'm not sure where this function came from but I didn't write it +local function class(superclass, name) + local cls = {} + cls.__name = name or "" + cls.__super = superclass + cls.__index = cls + return setmetatable(cls, {__call = function (c, ...) + self = setmetatable({}, cls) + local super = cls.__super + while (super~=nil) do + if super.__init then + super.__init(self, ...) + end + super = super.__super + end + if cls.__init then + cls.__init(self, ...) + end + return self + end}) +end + +local running = true + +local clc = 0 + +local op = gpu.getPalette() +local pal = { + {13, 8, 13 }, + {79, 43, 36 }, + {109, 69, 52 }, + {4, 255, 255}, + {141, 4, 4 }, + {251, 0, 0 }, + {255, 137, 4 }, + {255, 255, 0 }, + {0, 153, 0 }, + {105, 137, 187}, + {48, 105, 160}, + {16, 32, 95 }, + {23, 0, 33 }, + {255, 0, 0 }, + {255, 0, 255}, + {255, 255, 255} +} + +gpu.blitPalette(pal) + +local circH = fs.open("part.rif", "rb") +local circData = circH:read("*all") +circH:close() + +local circ, w, h = rif.decode1D(circData) + +local circles = {} +for i = 0, (w + 1) / 7 - 1 do + circles[i + 1] = {} + + for j = 0, h - 1 do + for k = 1, h do + circles[i + 1][j * h + k] = circ[i * 7 + j * w + k] + end + end +end + +local curs, cw, ch = rif.createImage("target.rif") + +local mouse = {sw / 2, sh / 2} + +local pmap = { + [0] = 5, + [5] = 6, + [6] = 7, + [7] = 8, + [8] = 4, + [4] = 16, + [16] = 16 +} + +local bmap = { + [0] = 12, + [12] = 11, + [11] = 10, + [10] = 4, + [4] = 4 +} + +local partCyc = { + 8, 16, 0, 8, 16, 2 +} + +local ship = {0, 0, -3 * math.pi / 4, 0, 0} +local missiles = {} + +local fbo = {} +for i = 1, sw * sh do + fbo[i] = 1 +end + +local stars = {} + +for i = 1, 100 do + local zsp = math.random(1000, 2000) / 1000 + local vpx = (sw / 2) * zsp + local vpy = (sh / 2) * zsp + local star = {math.random(-vpx, vpx) - (sw / 2), + math.random(-vpy, vpy) - (sh / 2), zsp} + stars[#stars + 1] = star +end + +local parts = {} +local exparts = {} + +local asts = {} + +local Destructable = class(nil, "DeObj") + +function Destructable:__init(x, y, poly, vx, vy) + self.x = x + self.y = y + self.vx = vx or 0 + self.vy = vy or 0 + self.rotation = 0 + self.poly = poly + + local polyR = 0 + for i = 1, #poly do + polyR = polyR + math.sqrt(poly[i][1] * poly[i][1] + poly[i][2] * poly[i][2]) + end + + self.polyR = polyR / #poly +end + +function Destructable:update(dt) + self.rotation = self.rotation + dt + + self.x = self.x + self.vx * dt + self.y = self.y + self.vy * dt + + self.vx = self.vx + self.vx * -dt + self.vy = self.vy + self.vy * -dt + + self.vy = self.vy * 0.99 +end + +function Destructable:draw() + local offsetX = ship[1] - sw / 2 + local offsetY = ship[2] - sh / 2 + + local rot = self.rotation + local plist = self.poly + + local drawFigure = {} + for i = 1, #plist do + local ppos = plist[i] + local polyps = #plist + + local ang = math.atan2(plist[i][2], plist[i][1]) + local dst = math.sqrt(plist[i][1] * plist[i][1] + plist[i][2] * plist[i][2]) + + drawFigure[#drawFigure + 1] = {-offsetX + math.cos(rot + ang) * dst + self.x, -offsetY + math.sin(rot + ang) * dst + self.y} + end + + -- For debugging collision circles + -- gpp.fillCircle(-offsetX + self.x, -offsetY + self.y, self.polyR, 16) + + gpp.fillPolygon(drawFigure, 2) +end + +local function polyListToString(polyList) + local str = "" + for i = 1, #polyList do + str = str .. "(" .. table.concat(polyList[i], ", ") .. ") " + end + + return str +end + +function Destructable:destruct(maxSplit) + local newPolys = {} + + maxSplit = maxSplit or math.huge + + local splitSeg = math.min(maxSplit, #self.poly / 2) + local amount = math.floor(#self.poly / splitSeg) + + for i = 0, splitSeg - 1 do + if i == splitSeg - 1 then + amount = #self.poly + end + + if amount <= 2 then + break + end + + local myPoly = {{0, 0}} + for j = 1, amount do + local npp = table.remove(self.poly, 1) + myPoly[#myPoly + 1] = npp + end + + local ax, ay = 0, 0 + for i = 1, #myPoly do + ax = ax + myPoly[i][1] + ay = ay + myPoly[i][2] + end + + local cx, cy = ax / #myPoly, ay / #myPoly + + for i = 1, #myPoly do + myPoly[i] = {myPoly[i][1] - cx, myPoly[i][2] - cy} + end + + newPolys[#newPolys + 1] = Destructable(self.x, self.y, myPoly, cx * 8 + math.random(-30, 30), cy * 8 + math.random(-30, 30)) + end + + return newPolys +end + +local function genAst() + local lst = {} + for i = 1, 16 do + local dst = math.random(9, 12) + lst[i] = { + math.cos(math.pi * i / 8) * dst, + math.sin(math.pi * i / 8) * dst + } + end + + return lst +end + +asts[1] = Destructable(60, 60, genAst()) +asts[2] = Destructable(-40, -80, genAst()) + +local function switch(val) + return function(tbl) + if tbl[val] then + tbl[val]() + elseif tbl.default then + tbl.default() + end + end +end + +local shake = 0 + +local function draw() + local offsetX = ship[1] - sw / 2 + local offsetY = ship[2] - sh / 2 + + if shake > 0 then + offsetX = offsetX + math.random(-shake, shake) + offsetY = offsetY + math.random(-shake, shake) + shake = shake - 1 + end + + gpu.clear() + + for i = 1, #stars do + local star = stars[i] + local x = (star[1] - offsetX) / star[3] + (sw / 2) + local y = (star[2] - offsetY) / star[3] + (sh / 2) + + if x < 0 then + star[1] = (2 * offsetX + star[3] * sw) / 2 + x = sw + elseif x >= sw then + star[1] = (2 * offsetX - star[3] * sw) / 2 + x = 0 + end + + if y < 0 then + star[2] = (2 * offsetY + star[3] * sh) / 2 + y = sh + elseif y >= sh then + star[2] = (2 * offsetY - star[3] * sh) / 2 + y = 0 + end + + gpu.drawPixel(x, y, 16) + end + + for i = 1, sw * sh do + fbo[i] = 0 + end + + for i = 1, #parts do + local part = parts[i] + local stage = circles[part[3]] + + for j = 1, h do + for k = 1, h do + local xv = fl(part[1] - offsetX) + j - 1 + local yv = fl(part[2] - offsetY) + k - 1 + if xv <= sw and xv >= 1 and yv <= sh and yv >= 1 then + if stage[(k - 1) * h + j] == 1 then + local index = xv + (yv - 1) * sw + local prev = fbo[index] + if part[6] == 1 then + fbo[index] = pmap[prev] or pmap[0] + else + fbo[index] = bmap[prev] or bmap[0] + end + end + end + end + end + end + + gpu.blitPixels(0, 0, sw, sh, fbo) + + local verts = { + {0, -3}, + {0, 3}, + {-10, 0} + } + + local tverts = {} + + for i = 1, #verts do + local x, y = verts[i][1], verts[i][2] + + local mag = math.sqrt(x * x + y * y) + local ang = math.atan2(y, x) + x, y = math.cos(ship[3] + ang) * mag + ship[1], math.sin(ship[3] + ang) * mag + ship[2] + x, y = math.floor(x - offsetX), math.floor(y - offsetY) + + tverts[#tverts + 1] = {x, y} + + if i > 1 then + gpp.drawLine(tverts[i - 1][1], tverts[i - 1][2], x, y, 16) + + if i == #verts then + gpp.drawLine(x, y, tverts[1][1], tverts[1][2], 16) + end + end + end + + for i = 1, #asts do + asts[i]:draw() + end + + for i = #exparts, 1, -1 do + gpp.fillCircle(math.floor(-offsetX + exparts[i][1]), math.floor(-offsetY + exparts[i][2]), math.floor(exparts[i][3] - exparts[i][4]), partCyc[math.floor(exparts[i][4] / 0.4)] or 2) + exparts[i][4] = exparts[i][4] + 0.4 + if exparts[i][3] - exparts[i][4] <= 0 then + table.remove(exparts, i) + end + end + + curs:render(mouse[1] - cw / 2, mouse[2] - ch / 2, 0, 0, 16, 16, 1) + + gpu.swap() +end + +local kd = {} + +local acc = 0 +local function update(dt) + clc = clc + dt + acc = acc + dt + if acc > 0.1 then + acc = 0 + + for i = #parts, 1, -1 do + parts[i][3] = parts[i][3] + 1 + if parts[i][3] > #circles then + table.remove(parts, i) + end + end + end + + for i = 1, #asts do + asts[i]:update(dt) + end + + for i = #missiles, 1, -1 do + local missile = missiles[i] + + local sdx = missile[1] - ship[1] + local sdy = missile[2] - ship[2] + local dist = sdx * sdx + sdy * sdy + if dist > 100000000 then + table.remove(missiles, i) + else + missile[4] = missile[4] + math.cos(missile[3]) * dt * 80 + missile[5] = missile[5] + math.sin(missile[3]) * dt * 80 + + missile[1] = missile[1] + dt * missile[4] + missile[2] = missile[2] + dt * missile[5] + + local good = true + for fi = 1, #asts do + local ast = asts[fi] + local distX = missile[1] - ast.x + local distY = missile[2] - ast.y + if math.sqrt(distX * distX + distY * distY) <= ast.polyR then + local opr = ast.polyR + local dd = table.remove(asts, fi):destruct(math.random(3, 5)) + for xi = 1, #dd do + asts[#asts + 1] = dd[xi] + end + + local p1, p2 = missile[1], missile[2] + exparts[#exparts + 1] = {p1, p2, 12, 1} + p1, p2 = p1 + math.random(-6, 6), p2 + math.random(-6, 6) + exparts[#exparts + 1] = {p1, p2, 8, 0} + p1, p2 = p1 + math.random(-3, 3), p2 + math.random(-3, 3) + exparts[#exparts + 1] = {p1, p2, 4, -1} + + shake = math.sqrt(opr) * 3 + + speaker.stopAll() + speaker.play({channel = 5, frequency = 600, time = 0.5, shift = -550, volume = 0.28, attack = 0, release = 0.4}) + + table.remove(missiles, i) + good = false + + break + end + end + + if good then + parts[#parts + 1] = {missile[1] + math.random(-2, 2), missile[2] + math.random(-2, 2), 1, missile[4] / 2 * math.cos(missile[3]), missile[4] / 2 * math.sin(missile[3]), 2} + end + end + end + + for i = 1, #parts do + parts[i][1] = parts[i][1] + parts[i][4] * dt + parts[i][2] = parts[i][2] + parts[i][5] * dt + parts[i][4] = parts[i][4] * 0.99 + parts[i][5] = parts[i][5] * 0.99 + end + + if kd.left then + ship[3] = ship[3] - 4 * dt + elseif kd.right then + ship[3] = ship[3] + 4 * dt + end + + if kd.up then + ship[4] = ship[4] + math.cos(ship[3]) * dt * 80 + ship[5] = ship[5] + math.sin(ship[3]) * dt * 80 + if ship[4] > 100 then + ship[4] = 100 + end + end + + ship[1] = ship[1] - dt * ship[4] + ship[2] = ship[2] - dt * ship[5] + + ship[4] = ship[4] * 0.98 + ship[5] = ship[5] * 0.98 + + if kd.up then + parts[#parts + 1] = {ship[1] + math.random(-2, 2), ship[2] + math.random(-2, 2), 1, + 40 * math.cos(ship[3]), 40 * math.sin(ship[3]), 1} + end +end + +local function event(e, ...) + if e == "key" then + local k = ... + switch(k) { + escape = function() + running = false + end + } + + kd[k] = true + + if k == "up" then + speaker.play({channel = 5, frequency = 300, time = 50, shift = 0, volume = 0.1, attack = 0, release = 0}) + elseif k == "left" or k == "right" then + + speaker.play({channel = 3, frequency = 50, time = 0.1, shift = 0, volume = 0.08, attack = 0.1, release = 0}) + + for i = 1, 10 do + speaker.play({channel = 3, frequency = 50, time = 0.1, shift = -5, volume = 0.08, attack = 0, release = 0}) + speaker.play({channel = 3, frequency = 45, time = 0.1, shift = 5, volume = 0.08, attack = 0, release = 0}) + end + end + elseif e == "keyUp" then + local k = ... + kd[k] = false + + if k == "up" then + speaker.stopChannel(5) + elseif k == "left" or k == "right" then + speaker.stopChannel(3) + speaker.play({channel = 3, frequency = 50, time = 0.1, shift = 0, volume = 0.08, attack = 0, release = 0.1}) + end + elseif e == "mouseMoved" then + local x, y = ... + mouse = {x, y} + elseif e == "mousePressed" then + local mx, my, b = ... + + local theta = 0 + local dist = math.huge + + local x, y = mx - sw / 2, my - sh / 2 + local a = 80 + local vx0, vy0 = -ship[4], -ship[5] + + local v0 = sqrt(vx0 * vx0 + vy0 * vy0) + local i0 = atan2(vy0, vx0) + + local x0, y0 = 0, 0 + + for i = 0, math.pi * 2, 0.001 do + local tm = (((-v0)*cos(i0) + sqrt(2*a*(x-x0)*cos(i) + v0*v0*cos(i0)*cos(i0))) * sec(i))/a + local tm2 = -(((v0*cos(i0) + sqrt(2*a*(x-x0)*cos(i) + v0*v0*cos(i0)*cos(i0))) * sec(i))/a) + + local tch = tm == tm and tm or nil + local tch2 = tm2 == tm2 and tm2 or nil + + if tch then + local test = {tch, tch2} + for j = 1, 2 do + local tnum = test[j] + if tnum >= 0 then + local fx = ((a * cos(i) * tnum * tnum) / 2) + (v0 * cos(i0) * tnum) + x0 + local fy = ((a * sin(i) * tnum * tnum) / 2) + (v0 * sin(i0) * tnum) + y0 + + local dd = math.sqrt((x - fx) * (x - fx) + (y - fy) * (y - fy)) + if dd < dist then + theta = i + dist = dd + end + end + end + end + end + + local missile = {ship[1], ship[2], theta, -ship[4], -ship[5]} + missiles[#missiles + 1] = missile + + speaker.play({channel = 5, frequency = 7000, time = 1.2, shift = -500, volume = 0.1, attack = 0.1, release = 0.5}) + end +end + +local eq = {} +local last = os.clock() +while running do + while true do + local a = {coroutine.yield()} + if not a[1] then break end + table.insert(eq, a) + end + + while #eq > 0 do + event(unpack(table.remove(eq, 1))) + end + + update(os.clock() - last) + last = os.clock() + + draw() +end + +gpu.blitPalette(op) +speaker.stopAll() \ No newline at end of file diff --git a/scripts/home/demos/part.rif b/scripts/home/demos/part.rif new file mode 100644 index 0000000..7047eaf Binary files /dev/null and b/scripts/home/demos/part.rif differ diff --git a/scripts/home/demos/target.rif b/scripts/home/demos/target.rif new file mode 100644 index 0000000..e225292 Binary files /dev/null and b/scripts/home/demos/target.rif differ diff --git a/scripts/home/games/mine/flag.rif b/scripts/home/games/mine/flag.rif index 20dc915..ff52f48 100644 Binary files a/scripts/home/games/mine/flag.rif and b/scripts/home/games/mine/flag.rif differ diff --git a/scripts/home/map.rif b/scripts/home/map.rif new file mode 100644 index 0000000..75cfe22 Binary files /dev/null and b/scripts/home/map.rif differ diff --git a/scripts/home/melon.rif b/scripts/home/melon.rif new file mode 100644 index 0000000..298ea62 Binary files /dev/null and b/scripts/home/melon.rif differ diff --git a/scripts/home/pc.rif b/scripts/home/pc.rif new file mode 100644 index 0000000..8726834 Binary files /dev/null and b/scripts/home/pc.rif differ diff --git a/scripts/lib/gpp.lua b/scripts/lib/gpp.lua index 488f3ae..fb41d24 100644 --- a/scripts/lib/gpp.lua +++ b/scripts/lib/gpp.lua @@ -1,5 +1,19 @@ local gpp = {} +local gpuDrawPixel = gpu.drawPixel +local gpuDrawRectangle = gpu.drawRectangle + +local gpuWidth = gpu.width +local gpuHeight = gpu.height + +local function round(n) + if n % 1 >= 0.5 then + return math.ceil(n) + else + return math.floor(n) + end +end + function gpp.fillEllipse(x0, y0, rx, ry, c) local twoASquare = 2 * rx * rx local twoBSquare = 2 * ry * ry @@ -12,8 +26,8 @@ function gpp.fillEllipse(x0, y0, rx, ry, c) local stopY = 0 while stopX >= stopY do - gpu.drawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) - gpu.drawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) y = y + 1 stopY = stopY + twoASquare @@ -37,8 +51,8 @@ function gpp.fillEllipse(x0, y0, rx, ry, c) stopY = twoASquare * ry while stopX <= stopY do - gpu.drawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) - gpu.drawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) x = x + 1 stopX = stopX + twoBSquare @@ -66,10 +80,10 @@ function gpp.drawEllipse(x0, y0, rx, ry, c) local stopY = 0 while stopX >= stopY do - gpu.drawPixel(x0 + x, y0 + y, c) - gpu.drawPixel(x0 - x, y0 + y, c) - gpu.drawPixel(x0 - x, y0 - y, c) - gpu.drawPixel(x0 + x, y0 - y, c) + gpuDrawPixel(x0 + x, y0 + y, c) + gpuDrawPixel(x0 - x, y0 + y, c) + gpuDrawPixel(x0 - x, y0 - y, c) + gpuDrawPixel(x0 + x, y0 - y, c) y = y + 1 stopY = stopY + twoASquare @@ -93,10 +107,10 @@ function gpp.drawEllipse(x0, y0, rx, ry, c) stopY = twoASquare * ry while stopX <= stopY do - gpu.drawPixel(x0 + x, y0 + y, c) - gpu.drawPixel(x0 - x, y0 + y, c) - gpu.drawPixel(x0 - x, y0 - y, c) - gpu.drawPixel(x0 + x, y0 - y, c) + gpuDrawPixel(x0 + x, y0 + y, c) + gpuDrawPixel(x0 - x, y0 + y, c) + gpuDrawPixel(x0 - x, y0 - y, c) + gpuDrawPixel(x0 + x, y0 - y, c) x = x + 1 stopX = stopX + twoBSquare @@ -118,11 +132,11 @@ function gpp.fillCircle(x0, y0, r, c) local err = 0 while x >= y do - gpu.drawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) - gpu.drawRectangle(x0 - y, y0 + x, 2 * y + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 + y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - y, y0 + x, 2 * y + 1, 1, c) - gpu.drawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) - gpu.drawRectangle(x0 - y, y0 - x, 2 * y + 1, 1, c) + gpuDrawRectangle(x0 - x, y0 - y, 2 * x + 1, 1, c) + gpuDrawRectangle(x0 - y, y0 - x, 2 * y + 1, 1, c) y = y + 1 if err <= 0 then @@ -159,14 +173,14 @@ function gpp.drawLine(x1, y1, x2, y2, c) min = x < min and x or min if deltaErr > 0 then - gpu.drawRectangle(min, y, x - min + 1, 1, c) + gpuDrawRectangle(min, y, x - min + 1, 1, c) min = math.huge y = y + ddY deltaErr = deltaErr - deltaX end deltaErr = deltaErr + deltaY * ddY end - gpu.drawRectangle(min, y, x2 - min + 1, 1, c) + gpuDrawRectangle(min, y, x2 - min + 1, 1, c) else if y1 > y2 then local tx, ty = x1, y1 @@ -188,14 +202,71 @@ function gpp.drawLine(x1, y1, x2, y2, c) min = y < min and y or min if deltaErr > 0 then - gpu.drawRectangle(x, min, 1, y - min + 1, c) + gpuDrawRectangle(x, min, 1, y - min + 1, c) min = math.huge x = x + ddX deltaErr = deltaErr - deltaY end deltaErr = deltaErr + deltaX * ddX end - gpu.drawRectangle(x, min, 1, y2 - min + 1, c) + gpuDrawRectangle(x, min, 1, y2 - min + 1, c) + end +end + +function gpp.fillPolygon(poly, c) + local pixelX, pixelY, i, j, swap + local nodes, nodeX = 0, {} + + local imgTop, imgBot = gpuHeight, 0 + for i = 1, #poly do + local pp = poly[i] + if pp[2] < imgTop then + imgTop = pp[2] + end + + if pp[2] > imgBot then + imgBot = pp[2] + end + end + + for pixelY = imgTop, imgBot do + -- Build a list of nodes + nodes = 0; j = #poly + for i = 1, #poly do + local pp = poly[i] + local pn = poly[j] + + if (pp[2] < pixelY and pn[2] >= pixelY + or pn[2] < pixelY and pp[2] >= pixelY) then + nodes = nodes + 1 + nodeX[nodes] = round((pp[1] + (pixelY - pp[2]) / (pn[2] - pp[2]) * (pn[1] - pp[1]))) + end + + j = i + end + + -- Bubble Sort the nodes + i = 1; + while (i < nodes) do + if (nodeX[i] > nodeX[i+1]) then + swap = nodeX[i]; + nodeX[i] = nodeX[i+1]; + nodeX[i+1] = swap; + if i > 1 then i = i - 1 end + else + i = i + 1 + end + end + + -- Fill the pixels between node pairs. + for i = 1, nodes - 1, 2 do + if (nodeX[i ] >= gpuWidth) then break end + if (nodeX[i + 1] > 0 ) then + if (nodeX[i ] < 0 ) then nodeX[i] = 0 end + if (nodeX[i + 1] > gpuWidth) then nodeX[i + 1] = gpuWidth end + gpuDrawRectangle(nodeX[i], pixelY, round(nodeX[i + 1] - nodeX[i] + 1), 1, c) + end + end end end diff --git a/scripts/lib/rif.lua b/scripts/lib/rif.lua index b610cb1..b4de50c 100644 --- a/scripts/lib/rif.lua +++ b/scripts/lib/rif.lua @@ -37,10 +37,10 @@ function rif.encode(pixels, w, h) sp = 1 end - transmap[#transmap + 1] = fp < 0 - transmap[#transmap + 1] = sp < 0 - fp = fp < 0 and 0 or fp - 1 - sp = sp < 0 and 0 or sp - 1 + transmap[#transmap + 1] = fp <= 0 + transmap[#transmap + 1] = sp <= 0 + fp = fp <= 0 and 0 or fp - 1 + sp = sp <= 0 and 0 or sp - 1 local cstr = bit.bor(bit.lshift(fp, 4), sp) output = output .. string.char(cstr) @@ -63,7 +63,7 @@ function rif.encode(pixels, w, h) if not sp then -- We have enough pixels, but we've an odd number of pixels so -- add a padding buffer, doesn't really matter what color it is. - sp = 1 + sp = 6 if pad then error("More than one padding occurred!", 2) end @@ -91,6 +91,9 @@ function rif.encode(pixels, w, h) end bytes[#bytes + 1] = string.char(byte) + if not string.char(byte) then + error("SOMEOTHJISHEITHENF SEJFOISEJF") + end end return output .. table.concat(bytes, "") @@ -162,7 +165,7 @@ function rif.createImage(filenameOrRifData, wa, ha) image:blitPixels(0, 0, w, h, rifData) image:flush() - return image + return image, w, h end return rif \ No newline at end of file diff --git a/scripts/shell.lua b/scripts/shell.lua index 497244f..abf2642 100644 --- a/scripts/shell.lua +++ b/scripts/shell.lua @@ -33,6 +33,7 @@ local pureHistoryPoint = 1 shell = {} local shell = shell +shell.config = config local lineHistory = {{{"rikoOS 1.0"}, {13}}} @@ -77,19 +78,71 @@ function shell.writeOutputC(msg, c, rd) _ = rd and shell.redraw(true) or 1 end + +function shell.tabulate(...) + local tAll = {...} + + local w = (gpu.width - 4) / 7 + local nMaxLen = w / 7 + for n, t in ipairs(tAll) do + if type(t) == "table" then + for n, sItem in pairs(t) do + nMaxLen = math.max(string.len( sItem ) + 1, nMaxLen) + end + end + end + local nCols = math.floor(w / nMaxLen) + local nLines = 0 + + local cx = 0 + + local function newLine() + shell.writeOutputC("\n", nil, false) + cx = 0 + nLines = nLines + 1 + end + + local cc = nil + local function drawCols(_t) + local nCol = 1 + for n, s in ipairs(_t) do + if nCol > nCols then + nCol = 1 + newLine() + end + + shell.writeOutputC((" "):rep(((nCol - 1) * nMaxLen) - cx) .. s, cc, false) + cx = ((nCol - 1) * nMaxLen) + #s + + nCol = nCol + 1 + end + end + for n, t in ipairs(tAll) do + if type(t) == "table" then + if #t > 0 then + drawCols(t) + if n < #tAll then + shell.writeOutputC("\n", nil, false) + end + end + elseif type(t) == "number" then + cc = t + end + end +end + local prefix = "> " local str = "" --- local e, p1, p2 local lastP = 0 local lastf = 0 local fps = 60 -local mouseX, mouseY = 0, 0 +local mouseX, mouseY = -5, -5 function shell.redraw(swap) - swap = (swap == nil) and swap or true -- just to be explicit + swap = (swap == nil) and swap or true -- explicitness is necessary gpu.clear() @@ -109,7 +162,7 @@ function shell.redraw(swap) end gpu.drawRectangle(0, h - 10, w, 10, 6) - write("FPS: " .. tostring(round(fps, 0.01)), 2, 189) + write("FPS: " .. tostring(round(fps, 0.01)), 2, h - 9) gpu.drawRectangle(mouseX, mouseY, 2, 1, 7) gpu.drawRectangle(mouseX, mouseY, 1, 2, 7) @@ -124,6 +177,13 @@ function shell.getRunningProgram() return lastRun:match("(.+)%.lua") end +function shell.clear() + lineHistory = {} + + historyPoint = 1 + lineOffset = 0 +end + local function getprefix() local wd = fs.getCWD() wd = wd:gsub("\\", "/") @@ -149,6 +209,7 @@ local function update() shell.redraw() end +local fullscreen = false local function processEvent(e, ...) local args = {...} local p1, p2 = args[1], args[2] @@ -158,7 +219,10 @@ local function processEvent(e, ...) elseif e == "mouseMoved" then mouseX, mouseY = p1, p2 elseif e == "key" then - if p1 == "backspace" then + if p1 == "f11" then + fullscreen = not fullscreen + gpu.setFullscreen(fullscreen) + elseif p1 == "backspace" then str = str:sub(1, #str - 1) lastP = os.clock() * 2 elseif p1 == "up" then @@ -239,7 +303,7 @@ local function processEvent(e, ...) if got then c = 7 - shell.writeOutputC("Unknown program `" .. str:match("%S+") .. "'", 8) + shell.writeOutputC("Unknown program `" .. str:match("%S+") .. "'\n", 8) historyPoint = #lineHistory + 1 end diff --git a/scripts/usr/bin/cd.lua b/scripts/usr/bin/cd.lua index ae62aea..3a43129 100644 --- a/scripts/usr/bin/cd.lua +++ b/scripts/usr/bin/cd.lua @@ -1,3 +1,6 @@ +--HELP: \b6Usage: \b16cd \b7<\b16dir\b7> \n +-- \b6Description: \b7Change directory to \b16dir + local args = ({...})[1] local mask = tonumber("11111111", 2) diff --git a/scripts/usr/bin/cls.lua b/scripts/usr/bin/cls.lua new file mode 100644 index 0000000..68bebd3 --- /dev/null +++ b/scripts/usr/bin/cls.lua @@ -0,0 +1,4 @@ +--HELP: \b6Usage: \b16cls \n +-- \b6Description: \b7Clears the shell screen + +shell.clear() \ No newline at end of file diff --git a/scripts/usr/bin/edit.lua b/scripts/usr/bin/edit.lua index 5d57bf6..8bb28f8 100644 --- a/scripts/usr/bin/edit.lua +++ b/scripts/usr/bin/edit.lua @@ -15,6 +15,8 @@ local syntaxTheme = { catch = 16 -- everything else is white } +local rif = dofile("/lib/rif.lua") + local width, height = gpu.width, gpu.height local args = {...} @@ -27,6 +29,17 @@ if #args < 1 then end end +local mposx, mposy = -5, -5 + +local cur +do + local curRIF = "\82\73\86\2\0\6\0\7\1\0\0\0\0\0\0\0\0\0\0\1\0\0\31\16\0\31\241\0\31\255\16\31\255\241\31\241\16\1\31\16\61\14\131\0\24\2" + local rifout, cw, ch = rif.decode1D(curRIF) + cur = image.newImage(cw, ch) + cur:blitPixels(0, 0, cw, ch, rifout) + cur:flush() +end + local tabInsert = table.insert local tabRemove = table.remove @@ -344,6 +357,8 @@ local function drawContent() end drawCursor() + + cur:render(mposx, mposy) end local function checkDrawBounds() @@ -477,6 +492,8 @@ local function processEvent(e, p1, p2) end end end + elseif e == "mouseMoved" then + mposx, mposy = p1, p2 elseif e == "mousePressed" or (e == "mouseMoved" and mouseDown) then mouseDown = true local x, y = p1, p2 diff --git a/scripts/usr/bin/exit.lua b/scripts/usr/bin/exit.lua index f46b671..70a54bc 100644 --- a/scripts/usr/bin/exit.lua +++ b/scripts/usr/bin/exit.lua @@ -1 +1,4 @@ +--HELP: \b6Usage: \b16exit \n +-- \b6Description: \b7Close Riko4 + riko4.exit() diff --git a/scripts/usr/bin/gc.lua b/scripts/usr/bin/gc.lua deleted file mode 100644 index d708717..0000000 --- a/scripts/usr/bin/gc.lua +++ /dev/null @@ -1 +0,0 @@ -collectgarbage("collect") \ No newline at end of file diff --git a/scripts/usr/bin/help.lua b/scripts/usr/bin/help.lua new file mode 100644 index 0000000..7b21577 --- /dev/null +++ b/scripts/usr/bin/help.lua @@ -0,0 +1,148 @@ +--HELP: \b6Usage: \b16help \b7[\b16program\b7] \n +-- \b6Description: \b7When \b16program \b7is given, displays help for that program, otherwise displays general help + +local args = {...} + +local w, h = gpu.width, gpu.height + +local function writeICWrap(str, preserveWordsQ, strLitQ, start) + local color = 16 + start = start or 0 + + local pw = preserveWordsQ + if strLitQ then + str = str:gsub("\n", "") + str = str:gsub("\\b", "\b") + end + + str = "\b16" .. str + + for part in str:gmatch("\b?[^\b]+") do + if tonumber(part:sub(3, 3)) then + color = tonumber(part:sub(2, 3)) + part = part:sub(4) + else + color = tonumber(part:sub(2, 2)) + part = part:sub(3) + end + + local endP = function() return math.floor((w - start - 3) / 7) end + + if #part > endP() then + local max = math.floor(w / 7) + + if pw then + while #part > 0 do + local sec = part:sub(1, endP() + 1) .. (" "):rep(endP() - #part) + local wp = sec:sub(endP(), endP() + 1) + if wp:match("%S%S") then + local rev = sec:reverse() + local fpw = #sec - (rev:find("%s") or #rev) + local left = part:sub(fpw + 1):match("%s*(.+)") + part = part:sub(1, fpw) + + shell.writeOutputC(part .. "\n ", color) + start = 7 + + part = left + else + shell.writeOutputC(part:sub(1, endP()), color) + local ep = #part:sub(1, endP()) + part = part:sub(ep + 1) + start = start + ep * 7 + if start >= (max - 1) * 7 then + shell.writeOutputC("\n ") + part = part:match("%s*(.+)") or "" + start = 7 + end + end + end + else + shell.writeOutputC(part:sub(1, endP()), color) + + part = part:sub(endP() + 1) + start = 7 + + while #part > 0 do + shell.writeOutputC("\n " .. part:sub(1, endP()), color) + + part = part:sub(endP() + 1) + start = 7 + end + end + else + shell.writeOutputC(part, color) + start = start + #part * 8 + end + end +end + +if #args == 0 then + writeICWrap("\b8System: \b7Riko4\n") + writeICWrap("\b8Version: \b12v0.0.1\n\n") + + writeICWrap([[\b7For a list of readily accessible programs, type \b16programs\b7 into the shell.]], true, true) + + writeICWrap("\n\n") + writeICWrap([[\b7For help with a specific program, type \b16help <>\b7 into the shell.]], true, true) + writeICWrap("\n") +else + local handleName = "" + local DONE = false + for i = 1, #shell.config.path do + local dir = fs.list(shell.config.path[i]) or {} + for j = 1, #dir do + local name = dir[j] + if name ~= "." and name ~= ".." then + local ctp = name:find("%.") + local fnm = name + if ctp then fnm = name:sub(1, ctp - 1) end + if fnm == args[1] then + handleName = shell.config.path[i] .. "/" .. name + DONE = true + break + end + end + end + + if DONE then + break + end + end + + if handleName == "" then + writeICWrap("\b7No program called \b16" .. args[1] .. "\b7 was found\n", true) + return + end + + local handle = fs.open(handleName, "rb") + + if not handle then + writeICWrap("\b8An unexpected error occured\n", true) + return + end + local first = handle:read("*line") + + if first:sub(1, 7) == "--HELP:" then + first = "--" .. first:sub(8) + while true do + local bit = first:sub(4) + + if bit:sub(#bit - 1, #bit) == "\\n" then + writeICWrap(bit:sub(1, #bit - 3), true, true) + writeICWrap("\n") + + first = handle:read("*line") + else + writeICWrap(bit, true, true) + writeICWrap("\n") + + break + end + end + else + writeICWrap("\b7No help information was found for this program\n", true) + end + + handle:close() +end \ No newline at end of file diff --git a/scripts/usr/bin/ink.lua b/scripts/usr/bin/ink.lua index dd0a179..5b91b18 100644 --- a/scripts/usr/bin/ink.lua +++ b/scripts/usr/bin/ink.lua @@ -1,3 +1,6 @@ +--HELP: \b6Usage: \b16ink \n +-- \b6Description: \b7Image / Spritesheet editor + local RIF = dofile("/lib/rif.lua") local scrnWidth, scrnHeight = gpu.width, gpu.height @@ -41,7 +44,8 @@ local locale = { select = "Select", copied = "Copied", pasted = "Pasted", - noclip = "No clipboard data" + noclip = "No clipboard data", + resize = "Resize" } } @@ -68,15 +72,15 @@ do transMatte:blitPixels(0, 0, scrnWidth + 11, scrnHeight + 11, transBuffer) transMatte:flush() - checkMatte = image.newImage(scrnWidth + 1, scrnHeight + 1) - local checkBuffer = {} - for i = 1, scrnWidth + 1 do - for j = 1, scrnHeight + 1 do - checkBuffer[(j - 1)*(scrnWidth + 1) + i] = ((i + j) % 2 == 1) and 16 or 1 - end - end - checkMatte:blitPixels(0, 0, scrnWidth + 1, scrnHeight + 1, checkBuffer) - checkMatte:flush() + -- checkMatte = image.newImage(scrnWidth + 1, scrnHeight + 1) + -- local checkBuffer = {} + -- for i = 1, scrnWidth + 1 do + -- for j = 1, scrnHeight + 1 do + -- checkBuffer[(j - 1)*(scrnWidth + 1) + i] = ((i + j) % 2 == 1) and 16 or 1 + -- end + -- end + -- checkMatte:blitPixels(0, 0, scrnWidth + 1, scrnHeight + 1, checkBuffer) + -- checkMatte:flush() end local canvArea = image.newImage(scrnWidth, scrnHeight - 20) @@ -201,10 +205,10 @@ local clipboard = {w = 0, h = 0, full = false, prev = false, data = {}} local mouseDown = {false, false, false} -local toolPalette = window.new(locale[lang].tools, 60, 80, 340 - 65, 60) +local toolPalette = window.new(locale[lang].tools, 60, 80, scrnWidth - 65, 60) local colorPalette = window.new(locale[lang].colors, 6*4 + 20, 6*4, 4, 60) -local pathDialog = window.new(locale[lang].save, 100, 20, 6, 200 - 46) -local newDialog = window.new(locale[lang].new, 99, 24, 6, 200 - 50) +local pathDialog = window.new(locale[lang].save, 100, 20, 6, scrnHeight - 46) +local newDialog = window.new(locale[lang].new, 99, 24, 6, scrnHeight - 50) local pathVars = { str = "", @@ -220,6 +224,7 @@ local newVars = { hnum = "", cposw = 0, cposh = 0, + which = 1, visible = false, time = os.clock(), focus = false, @@ -245,14 +250,27 @@ local secColor = 9 local workingImage = {} local dispImage -local function constructImage() - workingImage = {} +local function constructImage(over) + -- workingImage = {} for i = 1, imgWidth do workingImage[i] = {} for j = 1, imgHeight do - workingImage[i][j] = 0 + if (over and not workingImage[i][j]) or (not over) then + workingImage[i][j] = 0 + end + end + end + + for i = imgWidth + 1, #workingImage do + if i > imgWidth then + workingImage[i] = nil + else + for j = 1, imgHeight do + workingImage[i][j] = nil + end end end + dispImage = image.newImage(imgWidth, imgHeight) end constructImage() @@ -281,7 +299,7 @@ local function saveImage(name) end local oData = RIF.encode(workingImage, imgWidth, imgHeight) - local handle = fs.open(name, "w") + local handle = fs.open(name, "wb") if not handle then status = locale[lang].failSave statusPos = statusRest @@ -443,6 +461,16 @@ local function propSel() toolVars.select.endy = math.max(toolVars.select.isy, toolVars.select.iey) end +local function count(t) + local n = 0 + + for _ in pairs(t) do + n = n + 1 + end + + return n +end + local toolList = { { name = locale[lang].pencil, @@ -452,7 +480,6 @@ local toolList = { end, mouseUp = function(x, y, b) toolVars.pencil.mouseDown[b] = false - drawQ(x, y, b) end, mouseMoved = function(x, y) toolVars.pencil.mposx = x @@ -480,13 +507,6 @@ local toolList = { end, mouseUp = function(x, y, b) toolVars.eraser.mouseDown[b] = false - local tx, ty = convertScrn2I(x, y) - if tx >= 0 and ty >= 0 and tx < imgWidth and ty < imgHeight and b == 1 then - workingImage[tx + 1][ty + 1] = 0 - dispImage:clear() - dispImage:blitPixels(0, 0, imgWidth, imgHeight, toBlitTable(workingImage)) - dispImage:flush() - end end, mouseMoved = function(x, y) toolVars.eraser.mposx = x @@ -566,6 +586,11 @@ local toolList = { propSel() toolVars.select.mouseDown = false + + if toolVars.select.isx == toolVars.select.iex and + toolVars.select.isy == toolVars.select.iey then + toolVars.select.exists = false + end end end, mouseMoved = function(x, y) @@ -590,7 +615,7 @@ local toolList = { gpu.drawRectangle((transX * zoomFactor) + drawOffX - 1, (transY * zoomFactor) + drawOffY + 10 + (zoomFactor / 2 - 0.5), 1, ((zoomFactor + 1) % 2) + 1, primColor) - gpu.drawRectangle(((transX + 1) * zoomFactor) + drawOffX - 1, (transY * zoomFactor) + drawOffY + 10 + (zoomFactor / 2 - 0.5), + gpu.drawRectangle(((transX + 1) * zoomFactor) + drawOffX, (transY * zoomFactor) + drawOffY + 10 + (zoomFactor / 2 - 0.5), 1, ((zoomFactor + 1) % 2) + 1, primColor) end } @@ -691,12 +716,14 @@ local function openPath(mode, str) newVars.focus = false end -local function openNew() +local function openNew(which, str) newVars.visible = true newVars.focus = true newVars.mode = 1 + newVars.which = which newVars.str = csaved or "" newVars.cpos = #newVars.str + newDialog.title = locale[lang][str] pathVars.visible = false pathVars.focus = false @@ -708,7 +735,7 @@ local toolbar = { { name = locale[lang].file, actions = { - {locale[lang].new, function() openNew() end}, + {locale[lang].new, function() openNew(1, "new") end}, {locale[lang].save, function() if csaved then saveImage(csaved) else openPath(1, "save") end end}, {locale[lang].saveas, function() openPath(1, "save") end}, {locale[lang].load, function() openPath(2, "load") end}, @@ -718,6 +745,7 @@ local toolbar = { { name = locale[lang].edit, actions = { + {locale[lang].resize, function() openNew(2, "resize") end}, {locale[lang].undo}, {locale[lang].redo}, {locale[lang].cut}, @@ -754,6 +782,28 @@ do end end +local rectT = 0 +local function outRect(x, y, w, h) + rectT = (rectT + 1) % 16 + if w > 0 and h > 0 then + gpu.drawRectangle(x, y, w, 1, 16) + gpu.drawRectangle(x, y + h - 1, w, 1, 16) + + for i = math.floor(rectT / 4), w - 1, 4 do + gpu.drawPixel(x + i, y, 1) + gpu.drawPixel(x + w - i, y + h - 1, 1) + end + + gpu.drawRectangle(x, y, 1, h, 16) + gpu.drawRectangle(x + w - 1, y, 1, h, 16) + + for i = math.floor(rectT / 4), h - 1, 4 do + gpu.drawPixel(x, y + h - i, 1) + gpu.drawPixel(x + w - 1, y + i, 1) + end + end +end + local function repaintCanv() canvArea:clear() @@ -787,30 +837,34 @@ local function drawContent() end TEMPFRIGGINI = TEMPFRIGGINI % 8 + 1 - if toolVars.select.exists then - checkMatte:render( - (toolVars.select.locx) * zoomFactor + drawOffX, - (toolVars.select.locy) * zoomFactor + drawOffY + 10, - TEMPFRIGGINI / 4, 0, - (toolVars.select.endx - toolVars.select.locx + 1) * zoomFactor, 1) - - checkMatte:render( - (toolVars.select.locx) * zoomFactor + drawOffX, - (toolVars.select.endy + 1) * zoomFactor + drawOffY + 9, - TEMPFRIGGINI / 4, 1, - (toolVars.select.endx - toolVars.select.locx + 1) * zoomFactor, 1) - - checkMatte:render( - (toolVars.select.locx) * zoomFactor + drawOffX, - (toolVars.select.locy) * zoomFactor + drawOffY + 10, - TEMPFRIGGINI / 4, 0, - 1, (toolVars.select.endy - toolVars.select.locy + 1) * zoomFactor) - - checkMatte:render( - (toolVars.select.endx + 1) * zoomFactor + drawOffX - 1, - (toolVars.select.locy) * zoomFactor + drawOffY + 10, - TEMPFRIGGINI / 4, 0, - 1, (toolVars.select.endy - toolVars.select.locy + 1) * zoomFactor) + if toolVars.select.exists and toolList[selectedTool].name == locale[lang].select then + -- checkMatte:render( + -- (toolVars.select.locx) * zoomFactor + drawOffX, + -- (toolVars.select.locy) * zoomFactor + drawOffY + 10, + -- TEMPFRIGGINI / 4, 0, + -- (toolVars.select.endx - toolVars.select.locx + 1) * zoomFactor, 1) + + -- checkMatte:render( + -- (toolVars.select.locx) * zoomFactor + drawOffX, + -- (toolVars.select.endy + 1) * zoomFactor + drawOffY + 9, + -- TEMPFRIGGINI / 4, 1, + -- (toolVars.select.endx - toolVars.select.locx + 1) * zoomFactor, 1) + + -- checkMatte:render( + -- (toolVars.select.locx) * zoomFactor + drawOffX, + -- (toolVars.select.locy) * zoomFactor + drawOffY + 10, + -- TEMPFRIGGINI / 4, 0, + -- 1, (toolVars.select.endy - toolVars.select.locy + 1) * zoomFactor) + + -- checkMatte:render( + -- (toolVars.select.endx + 1) * zoomFactor + drawOffX - 1, + -- (toolVars.select.locy) * zoomFactor + drawOffY + 10, + -- TEMPFRIGGINI / 4, 0, + -- 1, (toolVars.select.endy - toolVars.select.locy + 1) * zoomFactor) + outRect((toolVars.select.locx) * zoomFactor + drawOffX, + (toolVars.select.locy) * zoomFactor + drawOffY + 10, + (toolVars.select.endx - toolVars.select.locx + 1) * zoomFactor, + (toolVars.select.endy - toolVars.select.locy + 1) * zoomFactor) end if not toolList[selectedTool] then @@ -994,7 +1048,7 @@ local function processEvent(ev, p1, p2, p3, p4) end elseif p1 == "n" then if keyMods.ctrl then - openNew() + openNew(1, "new") end elseif p1 == "o" then if keyMods.ctrl then @@ -1024,7 +1078,7 @@ local function processEvent(ev, p1, p2, p3, p4) if tonumber(newVars.wnum) and tonumber(newVars.hnum) then imgWidth = tonumber(newVars.wnum) imgHeight = tonumber(newVars.hnum) - constructImage() + constructImage(newVars.which > 1) end newVars.visible = false newVars.focus = false @@ -1163,11 +1217,26 @@ local function processEvent(ev, p1, p2, p3, p4) mousePosX = p1 mousePosY = p2 elseif ev == "mouseWheel" then - local px, py = convertScrn2I(mousePosX, mousePosY) - zoomFactor = clamp(zoomFactor + p1, 1) - drawOffX = mousePosX - px * zoomFactor - drawOffY = (mousePosY - 10) - py * zoomFactor - repaintCanv() + if keyMods.ctrl then + local px, py = convertScrn2I(mousePosX, mousePosY) + zoomFactor = clamp(zoomFactor + p1, 1) + drawOffX = mousePosX - px * zoomFactor + drawOffY = (mousePosY - 10) - py * zoomFactor + repaintCanv() + else + toolList[selectedTool].mouseUp(mousePosX, mousePosY, 1) + toolList[selectedTool].mouseUp(mousePosX, mousePosY, 2) + toolList[selectedTool].mouseUp(mousePosX, mousePosY, 3) + + if p1 < 0 then + selectedTool = (selectedTool % count(toolList)) + 1 + else + selectedTool = ((selectedTool - 2) % count(toolList)) + 1 + end + toolList[selectedTool].mouseMoved(mousePosX, mousePosY, 0, 0) + + toolPalette.repaint() + end end end diff --git a/scripts/usr/bin/ls.lua b/scripts/usr/bin/ls.lua index e0126fa..00b47e0 100644 --- a/scripts/usr/bin/ls.lua +++ b/scripts/usr/bin/ls.lua @@ -1,56 +1,7 @@ -local args = {...} - -local function tabulateCommon(...) - local tAll = {...} - - local w = (gpu.width - 4) / 8 - local nMaxLen = w / 8 - for n, t in ipairs(tAll) do - if type(t) == "table" then - for n, sItem in pairs(t) do - nMaxLen = math.max(string.len( sItem ) + 1, nMaxLen) - end - end - end - local nCols = math.floor(w / nMaxLen) - local nLines = 0 +--HELP: \b6Usage: \b16ls \b7[\b16dir\b7]\b16\n +-- \b6Description: \b7List the contents of \b16dir\b7 or if not specified, the current directory - local cx = 0 - - local function newLine() - shell.writeOutputC("\n", nil, false) - cx = 0 - nLines = nLines + 1 - end - - local cc = nil - local function drawCols(_t) - local nCol = 1 - for n, s in ipairs(_t) do - if nCol > nCols then - nCol = 1 - newLine() - end - - shell.writeOutputC((" "):rep(((nCol - 1) * nMaxLen) - cx) .. s, cc, false) - cx = ((nCol - 1) * nMaxLen) + #s - - nCol = nCol + 1 - end - end - for n, t in ipairs(tAll) do - if type(t) == "table" then - if #t > 0 then - drawCols(t) - if n < #tAll then - shell.writeOutputC("\n", nil, false) - end - end - elseif type(t) == "number" then - cc = t - end - end -end +local args = {...} local dir = args[1] and args[1] or "./" @@ -73,8 +24,6 @@ end table.sort(outTbl[2]) table.sort(outTbl[4]) -tabulateCommon(unpack(outTbl)) +shell.tabulate(unpack(outTbl)) shell.writeOutputC("\n") - -shell.redraw() \ No newline at end of file diff --git a/scripts/usr/bin/map.lua b/scripts/usr/bin/map.lua index e2ad905..58ea933 100644 --- a/scripts/usr/bin/map.lua +++ b/scripts/usr/bin/map.lua @@ -1,19 +1,19 @@ local running = true -local rif = dofile("../lib/rif.lua") +local rif = dofile("/lib/rif.lua") local width, height = gpu.width, gpu.height --- local curRIF = "\82\73\86\2\0\5\0\5\1\0\0\0\0\0\0\0\0\0\0\0\0\0\240\0\0\240\0\0\240\0\0\0\24\130\48\0" --- local cur = image.newImage(5, 5) --- cur:blitPixels(0, 0, 5, 5, rif.decode1D(curRIF)) +local curRIF = "\82\73\86\2\0\6\0\7\1\0\0\0\0\0\0\0\0\0\0\1\0\0\31\16\0\31\241\0\31\255\16\31\255\241\31\241\16\1\31\16\61\14\131\0\24\2" +local rifout, cw, ch = rif.decode1D(curRIF) +local cur = image.newImage(cw, ch) +cur:blitPixels(0, 0, cw, ch, rifout) +cur:flush() -local cur = rif.createImage("curs.rif") - -local sheet = rif.createImage("pactex.rif") +local sheet = rif.createImage("/home/games/mine/flag.rif") local shw = 8 local shh = 5 -local pxs = 24 +local pxs = 8 local barW = 4 @@ -50,16 +50,16 @@ local function processEvent(e, ...) mstate = (mstate % 2) + 1 elseif x >= off then local transX = x - off - local indexX = math.ceil(transX / 24) - local indexY = math.ceil((y - winScroll) / 24) + local indexX = math.ceil(transX / pxs) + local indexY = math.ceil((y - winScroll) / pxs) sel = {indexX, indexY} else if b == 1 then local p, p2 = transformSSC() - board[#board + 1] = {x = math.floor(x / 24), y = math.floor(y / 24), spx = p, spy = p2} + board[#board + 1] = {x = math.floor(x / pxs), y = math.floor(y / pxs), spx = p, spy = p2} elseif b == 3 then for i = 1, #board do - if board[i].x == math.floor(x / 24) and board[i].y == math.floor(y / 24) then + if board[i].x == math.floor(x / pxs) and board[i].y == math.floor(y / pxs) then table.remove(board, i) break end @@ -85,11 +85,11 @@ end local function draw() for i = 1, #board do - sheet:render(board[i].x * 24, board[i].y * 24, board[i].spx, board[i].spy, pxs, pxs) + sheet:render(board[i].x * pxs, board[i].y * pxs, board[i].spx, board[i].spy, pxs, pxs) end local p, p2 = transformSSC() - sheet:render(math.floor(mouse[1] / 24) * 24, math.floor(mouse[2] / 24) * 24, p, p2, pxs, pxs) + sheet:render(math.floor(mouse[1] / pxs) * pxs, math.floor(mouse[2] / pxs) * pxs, p, p2, pxs, pxs) gpu.drawRectangle(off, 0, pxs * barW, height, 7) gpu.drawRectangle(off - 5, 0, 5, height, 6) diff --git a/scripts/usr/bin/mapper.lua b/scripts/usr/bin/mapper.lua new file mode 100644 index 0000000..6117a1e --- /dev/null +++ b/scripts/usr/bin/mapper.lua @@ -0,0 +1,283 @@ +--HELP: \b6Usage: \b16mapper \n +-- \b6Description: \b7Map creation tool + +local rif = dofile("/lib/rif.lua") + +local running = true +local w, h = gpu.width, gpu.height + +local sprsht = rif.createImage("/home/map.rif") + +local selSheet = rif.createImage("/home/melon.rif") +local sheetPS = 8 +local sheetPD = 0 + +local seling = false +local selSX = 0 +local selSY = 0 +local selEW = 0 +local selEH = 0 + +local move = false +local moffx = 0 +local moffy = 0 + +local selected = {img = image.newImage(0, 0)} + +local objCache = {} +local objects = {} + +local cur +do + local curRIF = "\82\73\86\2\0\6\0\7\1\0\0\0\0\0\0\0\0\0\0\1\0\0\31\16\0\31\241\0\31\255\16\31\255\241\31\241\16\1\31\16\61\14\131\0\24\2" + local rifout, cw, ch = rif.decode1D(curRIF) + cur = image.newImage(cw, ch) + cur:blitPixels(0, 0, cw, ch, rifout) + cur:flush() +end + +local mx, my = 0, 0 + +local selectMode = false +local currentPlaced = {} + +local rectT = 0 +local function outRect(x, y, w, h) + rectT = (rectT + 1) % 16 + if w > 0 and h > 0 then + gpu.drawRectangle(x, y, w, 1, 16) + gpu.drawRectangle(x, y + h - 1, w, 1, 16) + + for i = math.floor(rectT / 4), w, 4 do + gpu.drawPixel(x + i, y, 1) + gpu.drawPixel(x + w - i, y + h - 1, 1) + end + + gpu.drawRectangle(x, y, 1, h, 16) + gpu.drawRectangle(x + w - 1, y, 1, h, 16) + + for i = math.floor(rectT / 4), h, 4 do + gpu.drawPixel(x, y + h - i, 1) + gpu.drawPixel(x + w - 1, y + i, 1) + end + end +end + +local function getSStr() + return selSX .. "x" .. selSY .. "x" .. selEW .. "x" .. selEH +end + +local function activateSelection() + selected = {} + + if objCache[getSStr()] then + selected.img = objCache[getSStr()] + else + local outImg = image.newImage(sheetPS * selEW, sheetPS * selEH) + + for i = selSX, selSX + selEW - 1 do + for j = selSY, selSY + selEH - 1 do + selSheet:copy(outImg, (i - selSX) * sheetPS, + (j - selSY) * sheetPS, + sheetPS, sheetPS, + i * (sheetPS + sheetPD), + j * (sheetPS + sheetPD)) + end + end + + outImg:flush() + selected.img = outImg + objCache[getSStr()] = outImg + end +end + +local function checkIntersect(a, b, c, d, w, h) + if c >= a and c < a + w then + if d >= b and d < b + h then + return true + end + end + + if a >= c and a < c + w then + if b >= d and b < d + h then + return true + end + end + + return false +end + +local function draw() + gpu.clear() + + if selectMode then + if selSheet then + selSheet:render(0, 8) + end + + outRect(selSX * (sheetPS + sheetPD), selSY * (sheetPS + sheetPD) + 8, + selEW * (sheetPS + sheetPD), selEH * (sheetPS + sheetPD), 8) + else + for i = moffx % sheetPS, w, sheetPS do + gpu.drawRectangle(i, 8, 1, h - 8, 6) + end + + for i = moffy % sheetPS, h, sheetPS do + gpu.drawRectangle(0, i + 8, w, 1, 6) + end + + gpu.drawRectangle(0, (moffy + 8) % (h + 1), w, 1, 8) + gpu.drawRectangle(moffx % (w + 1), 8, 1, h - 8, 8) + + gpu.drawRectangle(0, moffy + 8, w, 1, 11) + gpu.drawRectangle(moffx, 8, 1, h - 8, 11) + + for i = 1, #objects do + local obj = objects[i] + + obj.obj:render(obj.x * sheetPS + moffx + 1, obj.y * sheetPS + 9 + moffy) + end + + selected.img:render(math.floor((mx - moffx) / sheetPS) * sheetPS + moffx + 1, + math.floor((my - 8 - moffy) / sheetPS) * sheetPS + 9 + moffy) + end + + gpu.drawRectangle(0, 0, w, 8, 7) + + sprsht:render(w - 8, 0, 0, 0, 8, 8) + + cur:render(mx, my) + + gpu.swap() +end + +local function update(dt) + +end + +local function event(e, ...) + if e == "key" then + local k = ... + if k == "escape" then + running = false + elseif k == "tab" then + selectMode = true + end + elseif e == "keyUp" then + local k = ... + if k == "tab" then + selectMode = false + end + elseif e == "mouseMoved" then + local x, y, dx, dy = ... + mx, my = x, y + + if move then + moffx = moffx + dx + moffy = moffy + dy + end + + if selectMode and seling then + y = y - 8 + + local cx = math.floor(x / (sheetPS + sheetPD)) + local cy = math.floor(y / (sheetPS + sheetPD)) + + selEW = cx - selSX + 1 + selEH = cy - selSY + 1 + elseif not selectMode then + if #currentPlaced > 0 then + x = x - moffx + y = y - 8 - moffy + + local x = math.floor(x / sheetPS) + local y = math.floor(y / sheetPS) + + local good = true + for i = 1, #currentPlaced do + if checkIntersect(x, y, currentPlaced[i].x, currentPlaced[i].y, selEW, selEH) then + good = false + end + end + + if good then + local obj = objCache[getSStr()] + + objects[#objects + 1] = { + obj = obj, + x = x, + y = y + } + + currentPlaced[#currentPlaced + 1] = { + x = x, + y = y + } + end + end + end + elseif e == "mousePressed" then + local x, y, b = ... + if b == 1 then + if selectMode then + seling = true + + y = y - 8 + + selSX = math.floor(x / (sheetPS + sheetPD)) + selSY = math.floor(y / (sheetPS + sheetPD)) + selEW = 1 + selEH = 1 + else + x = x - moffx + y = y - 8 - moffy + + local obj = objCache[getSStr()] + + objects[#objects + 1] = { + obj = obj, + x = math.floor(x / sheetPS), + y = math.floor(y / sheetPS) + } + + currentPlaced = { + { + x = math.floor(x / sheetPS), + y = math.floor(y / sheetPS) + } + } + end + elseif b == 2 then + move = true + end + elseif e == "mouseReleased" then + local x, y, b = ... + if b == 1 then + seling = false + currentPlaced = {} + + activateSelection() + elseif b == 2 then + move = false + end + end +end + +local eq = {} +local last = os.clock() +while running do + while true do + local a = {coroutine.yield()} + if not a[1] then break end + table.insert(eq, a) + end + + while #eq > 0 do + event(unpack(table.remove(eq, 1))) + end + + update(os.clock() - last) + last = os.clock() + + draw() +end diff --git a/scripts/usr/bin/mkdir.lua b/scripts/usr/bin/mkdir.lua index 95810df..aed7d1e 100644 --- a/scripts/usr/bin/mkdir.lua +++ b/scripts/usr/bin/mkdir.lua @@ -1,3 +1,6 @@ +--HELP: \b6Usage: \b16mkdir \b7[\b16dir\b7] \n +-- \b6Description: \b7Creates new directory \b16dir + local args = ({...})[1] local mask = tonumber("11111111", 2) diff --git a/scripts/usr/bin/mv.lua b/scripts/usr/bin/mv.lua index d632368..16bc338 100644 --- a/scripts/usr/bin/mv.lua +++ b/scripts/usr/bin/mv.lua @@ -1,3 +1,6 @@ +--HELP: \b6Usage: \b16mv \b7[\b16src\b7] [\b16dest\b7] \n +-- \b6Description: \b7Moves \b16src \b7to \b17dest + local args = {...} local from = args[1] local to = args[2] diff --git a/scripts/usr/bin/pal.lua b/scripts/usr/bin/pal.lua new file mode 100644 index 0000000..211715e --- /dev/null +++ b/scripts/usr/bin/pal.lua @@ -0,0 +1,9 @@ +gpu.clear() + +for i = 1, 16 do + gpu.drawRectangle(((i - 1) % 4) * 24 + 24, math.floor((i - 1) / 4) * 24 + 24, 24, 24, i) +end + +gpu.swap() + +while coroutine.yield() ~= "key" do end \ No newline at end of file diff --git a/scripts/usr/bin/pproc.lua b/scripts/usr/bin/pproc.lua index 93df595..adf0419 100644 --- a/scripts/usr/bin/pproc.lua +++ b/scripts/usr/bin/pproc.lua @@ -1,81 +1,21 @@ ---[[ - -USAGE: pproc [outputFile] - -If outputFile is not specified, pproc will write output to this path: inputFile .. ".lua" - -]] - +--HELP: \b6Usage: \b16pproc \b7<\b16input\b7> [\b16outfile\b7] \n +-- \b6Description: \b7Preprocesses \b16input\b7, writing \b7to \b17outfile \b7or \b16input \b7plus \b16.lua local args = {...} -local erf -if shell then - if shell.writeOutputC then - erf = function(t) - shell.writeOutputC(t, 8) - end - elseif printError then - erf = function(t) - printError(t) - end - else - erf = function(t) - error(t) - end - end -else - erf = function(t) - error(t) - end -end - -local outAPI = io or fs - if not args[1] then if shell then local prog = shell.getRunningProgram() - erf("Syntax: " .. (prog or "pproc") .. " [outfile]\n") + shell.writeOutputC("Syntax: " .. (prog or "pproc") .. " [outfile]\n", 8) return else - erf("Syntax: pproc [outfile]") + error("Syntax: pproc [outfile]") end end -local setfenv = setfenv -local ifEQ = true - -if not setfenv then - if debug then - setfenv = function(fn, env) - local i = 1 - while true do - local name = debug.getupvalue(fn, i) - if name == "_ENV" then - debug.upvaluejoin(fn, i, (function() - return env - end), 1) - break - elseif not name then - break - end - - i = i + 1 - end - - return fn - end - else - erf("No debug library, `if' ppc disabled") - ifEQ = false - end -end - -local loadStr = loadstring or load - local fn = args[1] -local handle = outAPI.open(fn, "r") +local handle = fs.open(fn, "r") local data = handle:read("*all") .. "\n" handle:close() @@ -83,373 +23,136 @@ local function trimS(s) return s:match("%s*(.+)") end -local function trimF(s) - local fp = s:match("%s*(.+)") - local sp = fp:reverse():match("%s*(.+)") - return sp:reverse() -end - local function sw(str, swr) return str:sub(1, #swr) == swr end -local function parenfind(str) - local first = str:find("%(") - if not first then - return - end - - local rest = str:sub(first + 1) - local last - - local embed = 0 - for i = 1, #rest do - local c = rest:sub(i, i) - if c == "(" then - embed = embed + 1 - elseif c == ")" then - embed = embed - 1 - if embed == -1 then - last = i - break - end - end - end - - if last then - return first, first + last, str:sub(first, first + last) - else - return - end -end - local final = "" local scope = {} -local multiline = false -local lineI = 0 - -local function attemptSub(line) - local lineP = "" - - while #line > 0 do - local c = line:sub(1, 1); line = line:sub(2) - local p = line:sub(1, 1) - - if c == "\"" or c == "'" then - lineP = lineP .. c - - local escaping = false - for char in line:gmatch(".") do - lineP = lineP .. char - line = line:sub(2) - if char == c and not escaping then - break - elseif char == "\\" then - escaping = true - else - escaping = false - end - end - elseif c == "[" and p == "[" then - multiline = true - local endS = line:find("]]") - if endS then - lineP = lineP .. line:sub(1, endS + 1) - line = line:sub(endS + 2) - multiline = false - else - lineP = lineP .. c .. line - line = "" - end +local multiline = false +local i = 0 +for line in data:gmatch("([^\n]*)\n") do + i = i + 1 + if multiline then + local endS = line:find("]]") + if endS then + final = final .. line:sub(1, endS + 1) + line = line:sub(endS + 2) + multiline = false else - local nextS = line:find("[\"']") - local nextM = line:find("%[%[") - local next = math.min(nextS or #line + 1, nextM or #line + 1) - - local safe = c .. line:sub(1, next - 1) - local safeOff = 0 - - while #safe > 0 do - local nextPKW, endPKW, Pstr = safe:find("([%a_][%w_]*)") - if nextPKW then - lineP = lineP .. safe:sub(1, nextPKW - 1) - safe = safe:sub(endPKW + 1) - safeOff = safeOff + endPKW - - local found = false - for i = 1, #scope do - if scope[i][1] == Pstr then - if scope[i][3] then - local s, e, tinner = parenfind(line:sub(safeOff)) - - if e then - next = safeOff + e - safe = line:sub(safeOff + e, next - 1) - safeOff = safeOff + e - end - - if s == 1 then - local paramsS = tinner:sub(2, #tinner - 1) - local params = {} - - for param in paramsS:gmatch("[^%,]+") do - params[#params + 1] = trimF(param) - end - - local modded = {} - local tempHold = {} - for k = 1, #scope[i][3] do - local v = scope[i][3][k] - - local indTA = #scope + 1 - for j = 1, #scope do - if v == scope[j][1] then - tempHold[j] = {scope[j][1], scope[j][2], scope[j][3]} - indTA = j - break - end - end - - scope[indTA] = {v, params[k]} - modded[#modded + 1] = indTA - end - - lineP = lineP .. attemptSub(scope[i][2]) - - for p = 1, #modded do - local indER = modded[p] - if tempHold[indER] then - scope[indER] = tempHold[indER] - else - scope[indER] = nil - end - end - - found = true - break - else - erf("PP WARN: (Line " .. lineI .. ")\n`" .. Pstr .. "' is a macro function, but is not called\n") - lineP = lineP .. attemptSub(scope[i][2]) - found = true - break - end - else - lineP = lineP .. attemptSub(scope[i][2]) - found = true - break - end - end - end - - if not found then - lineP = lineP .. Pstr - end - else - lineP = lineP .. safe - safe = "" - end - end - - line = line:sub(next) + final = final .. line .. "\n" + line = "" end - end - - return lineP -end - -local skipBlock = 0 -local openInner = 0 -local lines = {} -for line in data:gmatch("([^\n]*)\n") do - lines[#lines + 1] = line -end - -while #lines > 0 do - local line = table.remove(lines, 1) - - lineI = lineI + 1 - if lineI > 1000 then break end - - if skipBlock > 0 then + else local trim = trimS(line) or "" if trim:sub(1, 1) == "#" then -- Preprocessor instruction local inst = trimS(trim:sub(2)) - if sw(inst, "else") then - if openInner == 0 then - skipBlock = skipBlock - 1 - end - elseif sw(inst, "endif") then - if openInner == 0 then - skipBlock = skipBlock - 1 - else - openInner = openInner - 1 + if sw(inst, "define") then + local command = trimS(inst:sub(7)) + local name = command:match("%S+") + local rest = command:sub(#name + 2) + + scope[#scope + 1] = {name, rest} + elseif sw(inst, "undef") then + local command = trimS(inst:sub(6)) + local name = command:match("%S+") + + for i = 1, #scope do + if scope[i][1] == name then + table.remove(scope, i) + break + end end - elseif sw(inst, "ifndef") or sw(inst, "ifdef") then - openInner = openInner + 1 - end - end - else - if multiline then - local endS = line:find("]]") - if endS then - final = final .. line:sub(1, endS + 1) - line = line:sub(endS + 2) - multiline = false else - final = final .. line .. "\n" - line = "" + shell.writeOutputC("Preprocessor parse error: (Line " .. i .. ")\nUnknown instruction `" .. inst:match("%S+") .. "'\n", 8) end else - local trim = trimS(line) or "" - if trim:sub(1, 1) == "#" then - -- Preprocessor instruction - local inst = trimS(trim:sub(2)) - - if sw(inst, "include") then - local command = trimS(inst:sub(3)) - local inStr = command:match("%b\"\"") - if inStr then - local fn = inStr:sub(2, #inStr - 1) - local Ihandle = fs.open(fn, "rb") - if Ihandle then - local Idata = Ihandle:read("*all") .. "\n" - local Ilines = {} - - for Iline in Idata:gmatch("([^\n]*)\n") do - Ilines[#Ilines + 1] = Iline - end - - for r = 1, #lines do - Ilines[#Ilines + 1] = lines[r] - end - - lines = Ilines - else - erf("Preprocessor parse error: (Line " .. lineI .. ")\nCannot find `" .. fn .. "'\n") - end - else - erf("Preprocessor parse error: (Line " .. lineI .. ")\nUnknown include strategy\n") - end - elseif sw(inst, "define") then - local command = trimS(inst:sub(7)) - local name = command:match("%S+") - local nameCMD = command:match("%S+%b()") - if nameCMD then - name = nameCMD - end - local fnSt, fnEnd, inner = name:find("(%b())") + local lineP = "" - local rest = command:sub(#name + 2) + while #line > 0 do + local c = line:sub(1, 1); line = line:sub(2) + local p = line:sub(1, 1) - local params - if fnSt then - name = name:sub(1, fnSt - 1) - rest = command:sub(fnEnd + 2) + if c == "\"" or c == "'" then + lineP = lineP .. c - local paramsS = inner:sub(2, #inner - 1) - params = {} - - for param in paramsS:gmatch("[^%,%s]+") do - params[#params + 1] = param - end - end - - scope[#scope + 1] = {name, rest, params} - elseif sw(inst, "undef") then - local command = trimS(inst:sub(6)) - local name = command:match("%S+") - - for i = 1, #scope do - if scope[i][1] == name then - table.remove(scope, i) - break - end - end - elseif sw(inst, "ifdef") then - local command = trimS(inst:sub(6)) - local name = command:match("%S+") - - local found = false - for i = 1, #scope do - if scope[i][1] == name then - found = true - break - end - end - - if not found then - skipBlock = skipBlock + 1 - end - elseif sw(inst, "ifndef") then - local command = trimS(inst:sub(7)) - local name = command:match("%S+") - - local found = false - for i = 1, #scope do - if scope[i][1] == name then - found = true + local escaping = false + for char in line:gmatch(".") do + lineP = lineP .. char + line = line:sub(2) + if char == c and not escaping then break + elseif char == "\\" then + escaping = true + else + escaping = false end end - - if found then - skipBlock = skipBlock + 1 - end - elseif sw(inst, "if") then - if not ifEQ then - erf("Preprocessor parse error: (Line " .. lineI .. ")\n`if' ppc is disabled\n") + elseif c == "[" and p == "[" then + multiline = true + + local endS = line:find("]]") + if endS then + lineP = lineP .. line:sub(1, endS + 1) + line = line:sub(endS + 2) + multiline = false else - local command = trimS(inst:sub(3)) - local fn, er = loadStr("return (" .. command .. ")") - - if not fn then - er = er and er:sub(er:find(":") + 4) or "Invalid conditional" - erf("Preprocessor parse error: (Line " .. lineI .. ")\n" .. er .. "\n") - else - local fscope = {} + lineP = lineP .. c .. line + line = "" + end + else + local nextS = line:find("[\"']") + local nextM = line:find("%[%[") + local next = math.min(nextS or #line + 1, nextM or #line + 1) + + local safe = c .. line:sub(1, next - 1) + + while #safe > 0 do + local nextPKW, endPKW, Pstr = safe:find("([%a_][%w_]*)") + if nextPKW then + lineP = lineP .. safe:sub(1, nextPKW - 1) + safe = safe:sub(endPKW + 1) + + local found = false for i = 1, #scope do - local val = scope[i][2] - if tonumber(val) then val = tonumber(scope[i][2]) end - fscope[scope[i][1]] = val + if scope[i][1] == Pstr then + lineP = lineP .. scope[i][2] + found = true + break + end end - setfenv(fn, fscope) - local succ, sret = pcall(fn) - - if not succ then - sret = sret and sret:sub(sret:find(":") + 4) or "Invalid conditional" - erf("Preprocessor parse error: (Line " .. lineI .. ")\n" .. sret .. "\n") - skipBlock = skipBlock + 1 - elseif not sret then - skipBlock = skipBlock + 1 + if not found then + lineP = lineP .. Pstr end + else + lineP = lineP .. safe + safe = "" end end - elseif sw(inst, "else") then - skipBlock = skipBlock + 1 - elseif sw(inst, "endif") then - -- Doesn't affect flow, only applicable to helping blocks - else - erf("Preprocessor parse error: (Line " .. lineI .. ")\nUnknown instruction `" .. inst:match("%S+") .. "'\n") - end - else - local lineP = attemptSub(line) - final = final .. lineP .. "\n" + line = line:sub(next) + end end + + final = final .. lineP .. "\n" + + -- for i = 1, #scope do + -- if scope[i][1] == name then + -- table.remove(scope, i) + -- break + -- end + -- end end end - - end +-- print("BEGIN\n" .. final .. "\nEND") local outFN = args[2] or (args[1] .. ".lua") -local outHandle = outAPI.open(outFN, "w") -if outHandle then - outHandle:write(final) - outHandle:close() -end +local outHandle = fs.open(outFN, "w") +outHandle:write(final) +outHandle:close() diff --git a/scripts/usr/bin/programs.lua b/scripts/usr/bin/programs.lua new file mode 100644 index 0000000..062e565 --- /dev/null +++ b/scripts/usr/bin/programs.lua @@ -0,0 +1,24 @@ +--HELP: \b6Usage: \b16programs \n +-- \b6Description: \b7Lists readily acessible programs + +local tbl = {} + +for i = 1, #shell.config.path do + if shell.config.path[i] ~= "." then + local dir = fs.list(shell.config.path[i]) or "" + for j = 1, #dir do + local name = dir[j] + if name:sub(1, 1) ~= "." then + local ctp = name:find("%.") + if ctp then name = name:sub(1, ctp - 1) end + tbl[#tbl + 1] = name + end + end + end +end + +local tabular = {12, tbl} + +shell.tabulate(unpack(tabular)) + +shell.writeOutputC("\n") diff --git a/scripts/usr/bin/rm.lua b/scripts/usr/bin/rm.lua index 50a8a15..edf8fd8 100644 --- a/scripts/usr/bin/rm.lua +++ b/scripts/usr/bin/rm.lua @@ -1,3 +1,6 @@ +--HELP: \b6Usage: \b16rm \b7<\b16file\b7> \n +-- \b6Description: \b7Deletes \b16file + local arg = ({...})[1] fs.delete(arg) \ No newline at end of file diff --git a/src/riko.cpp b/src/riko.cpp index 99c013b..5a4c57b 100644 --- a/src/riko.cpp +++ b/src/riko.cpp @@ -608,6 +608,8 @@ int main(int argc, char * argv[]) { canRun = false; } else if (result != LUA_YIELD) { printLuaError(result); + puts(lua_tostring(mainThread, -1)); + canRun = false; exitCode = 1; } diff --git a/src/rikoConsts.h b/src/rikoConsts.h index 435de19..c46fa61 100644 --- a/src/rikoConsts.h +++ b/src/rikoConsts.h @@ -4,8 +4,8 @@ #define OPEN_FS_DESC 128 -#define SCRN_WIDTH 320 -#define SCRN_HEIGHT 180 +#define SCRN_WIDTH 280 +#define SCRN_HEIGHT 160 #define sane_NUM_SCANCODES 512