Advertisement
CrazedProgrammer

Video Player

May 27th, 2015
11,351
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.40 KB | None | 0 0
  1. -- Video Player version 1.0.0 by CrazedProgrammer
  2. -- You can find info and documentation on these pages:
  3. --
  4. -- You may use this in your ComputerCraft OSes and modify it without asking.
  5. -- However, you may not publish this program under your name without asking me.
  6. -- If you have any suggestions, bug reports or questions then please send an email to:
  7. -- crazedprogrammer@gmail.com
  8.  
  9. local function loadAPIString(name, str)
  10.     local env = {}
  11.     setmetatable(env, {__index = _G})
  12.     local fn, err = loadstring(str, name)
  13.     if fn then
  14.         setfenv(fn, env)
  15.         local ok, err = pcall(fn)
  16.         if not ok then
  17.             error(err)
  18.         end
  19.     else
  20.         error(err)
  21.     end
  22.     local api = {}
  23.     for k,v in pairs(env) do
  24.         if k ~= "_ENV" then
  25.             api[k] =  v
  26.         end
  27.     end
  28.     return api
  29. end
  30. 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")
  31. 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")
  32. local width, height, surf = nil
  33. local filename, file, mwidth, mheight, mfps, mlength, msurf = nil
  34. local frame, playing = nil, false
  35. local x1, y1, x2, y2, scale = nil
  36. local timer, clock = os.startTimer(0), os.clock()
  37. local function resize()
  38.     width, height = term.getSize()
  39.     surf = surface.create(width, height, "#", colors.black, colors.black)
  40. end
  41. local function load()
  42.     file = fs.open(filename, "rb")
  43.     mwidth, mheight, mfps, mlength = file.read(), file.read(), file.read(), file.read() * 256 + file.read() + 1
  44.     msurf = surface.create(mwidth, mheight, nil, 1, 1)
  45.     frame = 1
  46. end
  47. local function nextFrame()
  48.     local changes, x, y, color = nil
  49.     changes = file.read() * 256 + file.read()
  50.     for j=1,changes do
  51.         x, y, color = file.read(), file.read(), file.read()
  52.         msurf.buffer[(y * mwidth + x) * 3 + 2] = 2 ^ math.floor(color / 16)
  53.         msurf.buffer[(y * mwidth + x) * 3 + 3] = 2 ^ (color % 16)
  54.     end
  55. end
  56. local function calculateBounds()
  57.     local w, h = width, height - 1
  58.     local aspect = w / h
  59.     if aspect < mwidth / mheight * 3 / 2 then
  60.         h = width / (mwidth / mheight * 3 / 2)
  61.     elseif aspect > mwidth / mheight * 3 / 2 then
  62.         w = height * (mwidth / mheight * 3 / 2)
  63.     end
  64.     x1, y1 = math.floor((width - w) / 2 + 1), math.floor((height - 1 - h) / 2 + 1)
  65.     x2, y2 = math.floor(x1 + w - 1), math.floor(y1 + h - 1)
  66.     scale = { }
  67.     local xscale, yscale = (x2 - x1 + 1) / mwidth, (y2 - y1 + 1) / mheight
  68.     for j=y1,y2 do
  69.         for i=x1,x2 do
  70.             scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 1] = math.floor((i - x1 + 0.5) / xscale) + 1
  71.             scale[((j - y1) * (x2 - x1 + 1) + i - x1) * 2 + 2] = math.floor((j - y1 + 0.5) / yscale)
  72.         end
  73.     end
  74. end
  75. resize()
  76. while true do
  77.     local e = {os.pullEventRaw()}
  78.     if e[1] == "terminate" then
  79.         if file then
  80.             file.close()
  81.             file = nil
  82.         end
  83.         break
  84.     elseif e[1] == "term_resize" then
  85.         resize()
  86.         if file then
  87.             calculateBounds()
  88.         end
  89.     elseif e[1] == "timer" and e[2] == timer then
  90.         timer = os.startTimer(0)
  91.         local c = os.clock()
  92.         local dt = c - clock
  93.         clock = c
  94.         if file then
  95.             if playing then
  96.                 local nextframe = frame + dt * mfps
  97.                 if nextframe > mlength then
  98.                     nextframe = mlength
  99.                 end
  100.                 for i=math.floor(frame),math.floor(nextframe) - 1 do
  101.                     nextFrame()
  102.                 end
  103.                 frame = nextframe
  104.             end
  105.             for j=y1,y2 do
  106.                 for i=x1,x2 do
  107.                     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]
  108.                     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]
  109.                 end
  110.             end
  111.         end
  112.         surf:drawHLine(1, width, height, " ", colors.gray, colors.white)
  113.         if file then
  114.             surf:drawHLine(1, math.floor((width - 5) * frame / mlength + 0.5), height, nil, colors.lightGray)
  115.             surf:drawText(1, height, string.format("%02d:%02d", math.floor(frame / mfps / 60), math.floor(frame / mfps) - math.floor(frame / mfps / 60) * 60))
  116.             surf:drawText(width - 9, height, string.format("%02d:%02d", math.floor(mlength / mfps / 60), math.floor(mlength / mfps) - math.floor(mlength / mfps / 60) * 60))
  117.         else
  118.             surf:drawText(1, height, "00:00")
  119.             surf:drawText(width - 9, height, "00:00")
  120.         end
  121.         if playing then
  122.             surf:drawText(width - 3, height, "||")
  123.         else
  124.             surf:drawText(width - 3, height, "|>")
  125.         end
  126.         surf:drawText(width - 1, height, "LX")
  127.         surf:render()
  128.     elseif e[1] == "mouse_click" and e[4] == height then
  129.         if e[3] == width then
  130.             if file then
  131.                 file.close()
  132.                 file = nil
  133.             end
  134.             break
  135.         elseif e[3] == width - 1 then
  136.             local fname = fdialog.open()
  137.             if fname then
  138.                 if file then
  139.                     file.close()
  140.                 end
  141.                 filename = fname
  142.                 load()
  143.                 nextFrame()
  144.                 calculateBounds()
  145.                 playing = true
  146.                 surf:clear("#", colors.black, colors.black)
  147.             end
  148.             clock = os.clock()
  149.             timer = os.startTimer(0)
  150.         elseif e[3] == width - 3 or e[3] == width - 2 then
  151.             playing = not playing
  152.         elseif e[3] >= 1 and e[3] <= width - 5 then
  153.             if file then
  154.                 local newframe = e[3] / (width - 5) * mlength
  155.                 if e[3] == 1 then
  156.                     newframe = 1
  157.                 end
  158.                 local c = os.clock()
  159.                 if newframe >= frame then
  160.                     for i=math.floor(frame), math.floor(newframe) - 1 do
  161.                         nextFrame()
  162.                         local nc = os.clock()
  163.                         if nc - c > 1 then
  164.                             os.sleep(0)
  165.                             c = nc
  166.                         end
  167.                     end
  168.                 else
  169.                     file.close()
  170.                     load()
  171.                     for i=1, math.floor(newframe) do
  172.                         nextFrame()
  173.                         local nc = os.clock()
  174.                         if nc - c > 1 then
  175.                             os.sleep(0)
  176.                             c = nc
  177.                         end
  178.                     end
  179.                 end
  180.                 frame = newframe
  181.                 clock = os.clock()
  182.                 timer = os.startTimer(0)
  183.             end
  184.         end
  185.     end
  186. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement