Skip to content

Instantly share code, notes, and snippets.

@EliTheCoder
Last active December 14, 2020 22:34
Show Gist options
  • Save EliTheCoder/86ac1b4b988ef642be18a3e0ed199abb to your computer and use it in GitHub Desktop.
Save EliTheCoder/86ac1b4b988ef642be18a3e0ed199abb to your computer and use it in GitHub Desktop.
-- Video Player version 1.0.0 by CrazedProgrammer
-- You can find info and documentation on these pages:
--
-- You may use this in your ComputerCraft OSes and modify it without asking.
-- However, you may not publish this program under your name without asking me.
-- If you have any suggestions, bug reports or questions then please send an email to:
-- [email protected]
local function loadAPIString(name, str)
local env = {}
setmetatable(env, {__index = _G})
local fn, err = loadstring(str, name)
if fn then
setfenv(fn, env)
local ok, err = pcall(fn)
if not ok then
error(err)
end
else
error(err)
end
local api = {}
for k,v in pairs(env) do
if k ~= "_ENV" then
api[k] = v
end
end
return api
end
local surface = loadAPIString("surface", "version=\"1.6.2\"local a,b,c,d,e=math.floor,math.cos,math.sin,table.concat,{\[1\]=\"0\",\[2\]=\"1\",\[4\]=\"2\",\[8\]=\"3\",\[16\]=\"4\",\[32\]=\"5\",\[64\]=\"6\",\[128\]=\"7\",\[256\]=\"8\",\[512\]=\"9\",\[1024\]=\"a\",\[2048\]=\"b\",\[4096\]=\"c\",\[8192\]=\"d\",\[16384\]=\"e\",\[32768\]=\"f\"}local f={render=function(g,h,i,j,k,l,m,n)h,i,j,k,l,m,n=h or term,i or 1,j or 1,k or 1,l or 1,m or g.width,n or g.height;if k>m then local o=k;k,m=m,o end;if l>n then local o=l;l,n=n,o end;if m<1 or k>g.width or n<1 or l>g.height then return end;if k<1 then k=1 end;if m>g.width then m=g.width end;if l<1 then l=1 end;if n>g.height then n=g.height end;local p={}if h.blit then local q,r,s={},{},{}for t=l,n do for u=k,m do q\[u-k+1\]=g.buffer\[((t-1)*g.width+u)*3-2\]or\" \"r\[u-k+1\]=e\[g.buffer\[((t-1)*g.width+u)*3-1\]or 32768\]s\[u-k+1\]=e\[g.buffer\[((t-1)*g.width+u)*3\]or 1\]end;p\[#p+1\]=j+t-l;p\[#p+1\]=d(q)p\[#p+1\]=d(s)p\[#p+1\]=d(r)end;for u=1,#p,4 do h.setCursorPos(i,p\[u\])h.blit(p\[u+1\],p\[u+2\],p\[u+3\])end else local q,v,w,x,y=\"\",0,0;for t=l,n do p\[#p+1\]=1;p\[#p+1\]=j+t-l;for u=k,m do x,y=g.buffer\[((t-1)*g.width+u)*3-1\]or 32768,g.buffer\[((t-1)*g.width+u)*3\]or 1;if x~=v then v=x;if q~=\"\"then p\[#p+1\]=4;p\[#p+1\]=q;q=\"\"end;p\[#p+1\]=2;p\[#p+1\]=v end;if y~=w then w=y;if q~=\"\"then p\[#p+1\]=4;p\[#p+1\]=q;q=\"\"end;p\[#p+1\]=3;p\[#p+1\]=w end;q=q..g.buffer\[((t-1)*g.width+u)*3-2\]or\" \"end;p\[#p+1\]=4;p\[#p+1\]=q;q=\"\"end;local z,A=nil;for u=1,#p,2 do z,A=p\[u\],p\[u+1\]if z==1 then h.setCursorPos(i,A)elseif z==2 then h.setBackgroundColor(A)elseif z==3 then h.setTextColor(A)else h.write(A)end end end;if g.blink and g.curX>=1 and g.curY>=1 and g.curX<=g.width and g.curY<=g.height then h.setCursorPos(i+g.curX-k,j+g.curY-l)h.setCursorBlink(true)elseif g.blink==false then h.setCursorBlink(false)g.blink=nil end;return#p/2 end,clear=function(g,B,v,w)local C=g.overwrite;g.overwrite=true;g:fillRect(g.x1,g.y1,g.x2,g.y2,B,v,w)g.overwrite=C end,drawText=function(g,i,j,s,v,w)local D=i;for u=1,#s do if s:sub(u,u)~=\"\\n\"then if i>=g.x1 and j>=g.y1 and i<=g.x2 and j<=g.y2 then g.buffer\[((j-1)*g.width+i)*3-2\]=s:sub(u,u)if v or g.overwrite then g.buffer\[((j-1)*g.width+i)*3-1\]=v end;if w or g.overwrite then g.buffer\[((j-1)*g.width+i)*3\]=w end end else i=D-1;j=j+1 end;i=i+1 end end,drawHLine=function(g,E,F,j,B,v,w)if E>F then local o=E;E,F=F,o end;if j<g.y1 or j>g.y2 or F<g.x1 or E>g.x2 then return end;if E<g.x1 then E=g.x1 end;if F>g.x2 then F=g.x2 end;if B or g.overwrite then for i=E,F do g.buffer\[((j-1)*g.width+i)*3-2\]=B end end;if v or g.overwrite then for i=E,F do g.buffer\[((j-1)*g.width+i)*3-1\]=v end end;if w or g.overwrite then for i=E,F do g.buffer\[((j-1)*g.width+i)*3\]=w end end end,fillRect=function(g,E,G,F,H,B,v,w)if E>F then local o=E;E,F=F,o end;if G>H then local o=G;G,H=H,o end;if F<g.x1 or E>g.x2 or H<g.y1 or G>g.y2 then return end;if E<g.x1 then E=g.x1 end;if F>g.x2 then F=g.x2 end;if G<g.y1 then G=g.y1 end;if H>g.y2 then H=g.y2 end;if B or g.overwrite then for j=G,H do for i=E,F do g.buffer\[((j-1)*g.width+i)*3-2\]=B end end end;if v or g.overwrite then for j=G,H do for i=E,F do g.buffer\[((j-1)*g.width+i)*3-1\]=v end end end;if w or g.overwrite then for j=G,H do for i=E,F do g.buffer\[((j-1)*g.width+i)*3\]=w end end end end}function create(I,J,B,v,w)local g={}for K,L in pairs(f)do g\[K\]=L end;g.width,g.height,g.x1,g.y1,g.x2,g.y2,g.curX,g.curY,g.overwrite,g.buffer=I,J,1,1,I,J,1,1,false,{}if B then for u=1,I*J do g.buffer\[u*3-2\]=B end end;if v then for u=1,I*J do g.buffer\[u*3-1\]=v end end;if w then for u=1,I*J do g.buffer\[u*3\]=w end end;return g end")
local fdialog = loadAPIString("fdialog", "local function list(a)local b=fs.list(a)table.sort(b,function(c,d)return string.lower(c)<string.lower(d)end)local e={}for f=1,#b do if fs.isDir(a..\"/\"..b\[f\])then e\[#e+1\]=b\[f\]end end;for f=1,#b do if not fs.isDir(a..\"/\"..b\[f\])then e\[#e+1\]=b\[f\]end end;return e end;local function g(a,h)local i,j=term.getSize()term.setBackgroundColor(colors.white)term.clear()term.setCursorPos(1,2-h)term.setBackgroundColor(colors.yellow)term.setTextColor(colors.black)term.write(\"..\"..string.rep(\" \",i-2))for k,l in pairs(list(a))do term.setCursorPos(1,k+2-h)if fs.isDir(a..\"/\"..l)then term.setBackgroundColor(colors.yellow)term.write(l..string.rep(\" \",i-#l))else term.setBackgroundColor(colors.white)term.write(l)end end;term.setCursorPos(1,1)term.setBackgroundColor(colors.gray)term.setTextColor(colors.white)if a~=\"\"then term.write(\"/\"..a..string.rep(\" \",i-#a-2))else term.write(\"/\"..string.rep(\" \",i-2))end;term.setBackgroundColor(colors.red)term.write(\"X\")term.setBackgroundColor(colors.gray)term.setCursorPos(i,2)term.write(\"^\")term.setCursorPos(i,j-1)term.write(\"v\")term.setCursorPos(1,j)term.setBackgroundColor(colors.lightGray)term.setTextColor(colors.black)term.write(string.rep(\" \",i))end;local function m()term.setCursorPos(1,1)term.setBackgroundColor(colors.black)term.setTextColor(colors.white)term.clear()end;function open(a)a=a or\"\"local h,i,j=0,term.getSize()g(a,h)while true do local n={os.pullEvent()}if n\[1\]==\"mouse_click\"then local o,p=n\[3\],n\[4\]if o==i and p==1 then m()return elseif o==i and p==2 then h=h-math.floor(j/3)+1;if h<0 then h=0 end elseif o==i and p==j-1 then h=h+math.floor(j/3)-1 elseif p>1 and p<j then if p+h==2 and a~=\"\"then a=fs.getDir(a)else for k,l in pairs(list(a))do if k==p+h-2 then if fs.isDir(a..\"/\"..l)then a=fs.getDir(a..\"/\"..l..\"/_\")else m()return fs.getDir(a..\"/\"..l..\"/_\")end end end end elseif p==j then term.setCursorPos(1,j)local q=read()if q==\"\"then elseif q==\"..\"and a~=\"\"then a=fs.getDir(a)elseif q:sub(1,1)==\"/\"then if fs.isDir(q)then a=q:sub(2,#q)else m()return q:sub(2,#q)end elseif fs.isDir(a..\"/\"..q)then a=fs.getDir(a..\"/\"..q..\"/_\")else m()return fs.getDir(a..\"/\"..q..\"/_\")end end elseif n\[1\]==\"mouse_scroll\"then h=h+n\[2\]*math.floor(j/3)-1;if h<0 then h=0 end elseif n\[1\]==\"term_resize\"then i,j=term.getSize()end;g(a,h)end end")
local width, height, surf = nil
local filename, file, mwidth, mheight, mfps, mlength, msurf = nil
local frame, playing = nil, false
local x1, y1, x2, y2, scale = nil
local timer, clock = os.startTimer(0), os.clock()
rednet.open("top")
local function resize()
width, height = term.getSize()
surf = surface.create(width, height, "#", colors.black, colors.black)
end
local function load()
file = fs.open(filename, "rb")
mwidth, mheight, mfps, mlength = file.read(), file.read(), file.read(), file.read() * 256 + file.read() + 1
msurf = surface.create(mwidth, mheight, nil, 1, 1)
frame = 1
end
local function nextFrame()
local changes, x, y, color = nil
changes = file.read() * 256 + file.read()
for j=1,changes do
x, y, color = file.read(), file.read(), file.read()
msurf.buffer[(y * mwidth + x) * 3 + 2] = 2 ^ math.floor(color / 16)
msurf.buffer[(y * mwidth + x) * 3 + 3] = 2 ^ (color % 16)
end
end
local function calculateBounds()
local w, h = width, height - 1
local aspect = w / h
if aspect < mwidth / mheight * 3 / 2 then
h = width / (mwidth / mheight * 3 / 2)
elseif aspect > mwidth / mheight * 3 / 2 then
w = height * (mwidth / mheight * 3 / 2)
end
x1, y1 = math.floor((width - w) / 2 + 1), math.floor((height - 1 - h) / 2 + 1)
x2, y2 = math.floor(x1 + w - 1), math.floor(y1 + h - 1)
scale = { }
local xscale, yscale = (x2 - x1 + 1) / mwidth, (y2 - y1 + 1) / mheight
for j=y1,y2 do
for i=x1,x2 do
scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 1] = math.floor((i - x1 + 0.5) / xscale) + 1
scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 2] = math.floor((j - y1 + 0.5) / yscale)
end
end
end
resize()
while true do
local e = {os.pullEventRaw()}
if e[1] == "terminate" then
if file then
file.close()
file = nil
end
term.clear()
break
elseif e[1] == "term_resize" then
resize()
if file then
calculateBounds()
end
elseif e[1] == "timer" and e[2] == timer then
timer = os.startTimer(0)
local c = os.clock()
local dt = c - clock
clock = c
if file then
if playing then
local nextframe = frame + dt * mfps
if nextframe > mlength then
nextframe = mlength
end
for i=math.floor(frame),math.floor(nextframe) - 1 do
nextFrame()
end
frame = nextframe
end
for j=y1,y2 do
for i=x1,x2 do
surf.buffer[((j - 1) * width + i) * 3 - 1] = msurf.buffer[(scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 2] * mwidth + scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 1]) * 3 - 1]
surf.buffer[((j - 1) * width + i) * 3] = msurf.buffer[(scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 2] * mwidth + scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 1]) * 3]
end
end
end
surf:render()
elseif e[1] == "rednet_message" and e[4] == "remote-player" then
if e[3] == "exit" then
if file then
file.close()
file = nil
end
term.clear()
break
elseif e[3] == "list" then
local fname = fdialog.open()
if fname then
if file then
file.close()
end
filename = fname
load()
nextFrame()
calculateBounds()
playing = false
surf:clear("#", colors.black, colors.black)
end
clock = os.clock()
timer = os.startTimer(0)
elseif e[3] == "play" then
playing = not playing
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment