Operating system for OpenComputers
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.3KB

  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 = 0 -- 0 normal, 1 escape, 2 command
  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 checkCursor()
  16. if cx > mx and lw then
  17. cx, cy = 1, cy+1
  18. end
  19. if cy > my then
  20. gpu.copy(1,2,mx,my-1,0,-1)
  21. gpu.fill(1,my,mx,1," ")
  22. cy=my
  23. end
  24. if cy < 1 then cy = 1 end
  25. if cx < 1 then cx = 1 end
  26. end
  27. local function termwrite(s)
  28. local wb = ""
  29. local lb, ec = nil, nil
  30. local function flushwb()
  31. while wb:len() > 0 do
  32. checkCursor()
  33. local wl = wb:sub(1,mx-cx+1)
  34. wb = wb:sub(wl:len()+1)
  35. gpu.set(cx, cy, wl)
  36. cx = cx + wl:len()
  37. end
  38. end
  39. local rs = ""
  40. s=s:gsub("\8","\27[D")
  41. pc = gpu.get(cx,cy)
  42. gpu.setForeground(fg)
  43. gpu.setBackground(bg)
  44. gpu.set(cx,cy,pc)
  45. for cc in s:gmatch(".") do
  46. if mode == 0 then
  47. if cc == "\n" then
  48. flushwb()
  49. cx,cy = 1, cy+1
  50. elseif cc == "\t" then
  51. wb=wb..(" "):rep(8*((cx+9)//8))
  52. elseif cc == "\27" then
  53. flushwb()
  54. mode = 1
  55. else
  56. wb = wb .. cc
  57. end
  58. elseif mode == 1 then
  59. if cc == "[" then
  60. mode = 2
  61. else
  62. mode = 0
  63. end
  64. elseif mode == 2 then
  65. if cc:match("[%d;]") then
  66. cs = cs .. cc
  67. else
  68. mode = 0
  69. local tA = {}
  70. for s in cs:gmatch("%d+") do
  71. tA[#tA+1] = tonumber(s)
  72. end
  73. if cc == "H" then
  74. cx, cy = tA[1] or 1, tA[2] or 1
  75. elseif cc == "A" then
  76. cy = cy - (tA[1] or 1)
  77. elseif cc == "B" then
  78. cy = cy + (tA[1] or 1)
  79. elseif cc == "C" then
  80. cx = cx + (tA[1] or 1)
  81. elseif cc == "D" then
  82. cx = cx - (tA[1] or 1)
  83. elseif cc == "s" then
  84. sx, sy = cx, cy
  85. elseif cc == "u" then
  86. cx, cy = sx, sy
  87. elseif cc == "n" and tA[1] == 6 then
  88. rs = string.format("%s\27[%d;%dR",rs,cx,cy)
  89. elseif cc == "K" and tA[1] == 1 then
  90. gpu.fill(1,cy,cx,1," ")
  91. elseif cc == "K" and tA[1] == 2 then
  92. gpu.fill(cx,cy,mx,1," ")
  93. elseif cc == "K" then
  94. gpu.fill(1,cy,mx,1," ")
  95. elseif cc == "J" and tA[1] == 1 then
  96. gpu.fill(1,1,mx,cy," ")
  97. elseif cc == "J" and tA[1] == 2 then
  98. gpu.fill(1,1,mx,my," ")
  99. cx, cy = 1, 1
  100. elseif cc == "J" then
  101. gpu.fill(1,cy,mx,my," ")
  102. elseif cc == "m" then
  103. for _,num in ipairs(tA) do
  104. if num == 0 then
  105. fg,bg,ec,lb = 0xFFFFFF,0,true,true
  106. elseif num == 7 then
  107. local nfg,nbg = bg, fg
  108. fg, bg = nfg, nbg
  109. elseif num > 29 and num < 38 then
  110. fg = colours[num-29]
  111. elseif num > 39 and num < 48 then
  112. bg = colours[num-39]
  113. elseif num == 100 then -- disable local echo
  114. ec = false
  115. elseif num == 101 then -- disable line mode
  116. lb = false
  117. end
  118. end
  119. gpu.setForeground(fg)
  120. gpu.setBackground(bg)
  121. end
  122. cs = ""
  123. checkCursor()
  124. end
  125. end
  126. end
  127. flushwb()
  128. checkCursor()
  129. pc = gpu.get(cx,cy)
  130. gpu.setForeground(bg)
  131. gpu.setBackground(fg)
  132. gpu.set(cx,cy,pc)
  133. gpu.setForeground(fg)
  134. gpu.setBackground(bg)
  135. return rs, lb, ec
  136. end
  137. return termwrite
  138. end