Last active
December 14, 2020 22:34
-
-
Save EliTheCoder/86ac1b4b988ef642be18a3e0ed199abb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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