Operating system for OpenComputers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.6KB

  1. function vt100emu(gpu) -- takes GPU component proxy *gpu* and returns a function to write to it in a manner like an ANSI terminal
  2. local colours = {0x0,0xFF0000,0x00FF00,0xFFFF00,0x0000FF,0xFF00FF,0x00B6FF,0xFFFFFF}
  3. local mx, my = gpu.maxResolution()
  4. local cx, cy = 1, 1
  5. local pc = " "
  6. local lc = ""
  7. local mode = "n"
  8. local lw = true
  9. local sx, sy = 1,1
  10. local cs = ""
  11. local bg, fg = 0, 0xFFFFFF
  12. -- setup
  13. gpu.setResolution(mx,my)
  14. gpu.fill(1,1,mx,my," ")
  15. local function termwrite(s)
  16. local rs = ""
  17. s=s:gsub("\8","\27[D")
  18. pc = gpu.get(cx,cy)
  19. gpu.setForeground(fg)
  20. gpu.setBackground(bg)
  21. gpu.set(cx,cy,pc)
  22. for i = 1, s:len() do
  23. local cc = s:sub(i,i)
  24. if mode == "n" then
  25. if cc == "\n" then -- line feed
  26. cx, cy = 1, cy+1
  27. elseif cc == "\r" then -- cursor home
  28. cx = 1
  29. elseif cc == "\27" then -- escape
  30. mode = "e"
  31. elseif cc == "\t" then
  32. cx = 8*((cx+9)//8)
  33. elseif string.byte(cc) > 31 and string.byte(cc) < 127 then -- printable, I guess
  34. gpu.set(cx, cy, cc)
  35. cx = cx + 1
  36. end
  37. elseif mode == "e" then
  38. if cc == "[" then
  39. mode = "v"
  40. cs = ""
  41. elseif cc == "D" then -- scroll down
  42. gpu.copy(1,2,mx,my-1,0,-1)
  43. gpu.fill(1,my,mx,1," ")
  44. cy=cy+1
  45. mode = "n"
  46. elseif cc == "M" then -- scroll up
  47. gpu.copy(1,1,mx,my-1,0,1)
  48. gpu.fill(1,1,mx,1," ")
  49. mode = "n"
  50. else
  51. mode = "n"
  52. end
  53. elseif mode == "v" then
  54. mode = "n"
  55. if cc == "s" then -- save cursor
  56. sx, sy = cx, cy
  57. elseif cc == "u" then -- restore cursor
  58. cx, cy = sx, sy
  59. elseif cc == "H" then -- cursor home or to
  60. local tx, ty = cs:match("(%d+);(%d+)")
  61. tx, ty = tx or "1", ty or "1"
  62. cx, cy = tonumber(tx), tonumber(ty)
  63. elseif cc == "A" then -- cursor up
  64. cy = cy - (tonumber(cs) or 1)
  65. elseif cc == "B" then -- cursor down
  66. cy = cy + (tonumber(cs) or 1)
  67. elseif cc == "C" then -- cursor right
  68. cx = cx + (tonumber(cs) or 1)
  69. elseif cc == "D" then -- cursor left
  70. cx = cx - (tonumber(cs) or 1)
  71. elseif cc == "h" and lc == "7" then -- enable line wrap
  72. lw = true
  73. elseif cc == "l" and lc == "7" then -- disable line wrap
  74. lw = false
  75. elseif cc == "c" then
  76. rs = string.format("%s\27[%d;%d0c",rs,mx,my)
  77. elseif cc == "n" and lc == "6" then
  78. rs = string.format("%s\27[%d;%dR",rs,cx,cy)
  79. elseif cc == "K" then
  80. if lc == "1" then
  81. gpu.fill(1,cy,cx,1," ")
  82. elseif lc == "2" then
  83. gpu.fill(cx,cy,mx,1," ")
  84. else
  85. gpu.fill(1,cy,mx,1," ")
  86. end
  87. elseif cc == "J" then
  88. if lc == "1" then
  89. gpu.fill(1,1,mx,cy," ")
  90. elseif lc == "2" then
  91. gpu.full(1,1,mx,my," ")
  92. cx,cy = 1, 1
  93. else
  94. gpu.fill(1,cy,mx,my," ")
  95. end
  96. elseif cc == "m" then
  97. for num in cs:gmatch("%d+") do
  98. num=tonumber(num)
  99. if num == 0 then
  100. fg,bg = 0xFFFFFF,0
  101. elseif num == 7 then
  102. local nfg,nbg = bg, fg
  103. fg, bg = nfg, nbg
  104. elseif num > 29 and num < 38 then
  105. fg = colours[num-29]
  106. elseif num > 39 and num < 48 then
  107. bg = colours[num-39]
  108. end
  109. end
  110. gpu.setForeground(fg)
  111. gpu.setBackground(bg)
  112. else
  113. cs = cs .. cc
  114. if cc:match("[%d;]") then
  115. mode = "v"
  116. end
  117. end
  118. end
  119. if cx > mx and lw then
  120. cx, cy = 1, cy+1
  121. end
  122. if cy > my then
  123. gpu.copy(1,2,mx,my-1,0,-1)
  124. gpu.fill(1,my,mx,1," ")
  125. cy=my
  126. end
  127. if cy < 1 then cy = 1 end
  128. if cx < 1 then cx = 1 end
  129. lc = cc
  130. end
  131. pc = gpu.get(cx,cy)
  132. gpu.setForeground(bg)
  133. gpu.setBackground(fg)
  134. gpu.set(cx,cy,pc)
  135. gpu.setForeground(fg)
  136. gpu.setBackground(bg)
  137. return rs
  138. end
  139. return termwrite
  140. end