Redxone

[WIP] (CC) HexIt (Multi-Resolution)

Jun 22nd, 2017
461
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.     Program: HexIt
  3.     Created by: Lewisk3/Redxone
  4.    
  5.     Terms of use ( 6/23/17 ):
  6.         Do not edit this program and re-distribute the edit on the forums.
  7.         Use on ROM hacking is soley the responibility of the user.
  8.         Do not copy the program and try to push it off as your own.
  9.    
  10.     Have fun!
  11. --]]
  12.  
  13.  
  14. -- Monochrome support (WIP)
  15. if(not term.isColor())then
  16.   colors.orange    = colors.black
  17.   colors.magenta   = colors.white
  18.   colors.lightBlue = colors.lightGray
  19.   colors.yellow    = colors.white
  20.   colors.lime      = colors.white
  21.   colors.pink      = colors.white
  22.   colors.cyan      = colors.white
  23.   colors.purple    = colors.white
  24.   colors.blue      = colors.gray
  25.   colors.brown     = colors.white
  26.   colors.green     = colors.gray
  27.   colors.red       = colors.gray
  28. end
  29.  
  30.  
  31. if(term.current == nil)then
  32.   term.current().setVisible = function(tf) return false end
  33. elseif(term.current().setVisible == nil)then
  34.   term.current().setVisible = function(tf) return false end
  35. end
  36.  
  37. local w, h = term.getSize()
  38. --local w,h = 26, 20
  39. if(w < 26 or h < 19)then
  40.     error("\nYour current resolutions is too low :> " .. w .. "x" .. h .. " \nMinimum supported resolution :> 26x20")
  41. end
  42. local validHex = "0123456789abcdef"
  43. local running = true
  44. local barsize = 4
  45. local baroffs = 3
  46. local writeMode = "hex"
  47. local funcKey = false
  48. _currentMemory = 0
  49. view_w = (math.floor(w/1.40)-barsize)+1
  50. local isEvenRes = ((w-view_w)%3) <= 0
  51. if( not isEvenRes )then
  52.     baroffs = 2
  53. end
  54. _isPocket = (w == 26)
  55. _hexLineSize = math.floor(view_w/3)
  56. _hexPageSize = view_w
  57. _hexData = ""
  58. _hexSelected = 1
  59. _hexFile = ""
  60. _hexSize = 1
  61. _hexEditMode = "return"
  62. _hexBuffer = ""
  63. _hexLastByte = 0
  64. _searches = {}
  65. _lastSearch = {
  66.     mode = "hex",
  67.     dir  = "down",
  68.     data = "00",
  69. }
  70. _hexAddress = ""
  71. local dropColors = {colors.black,colors.white,colors.blue,colors.black}
  72.  
  73. hexedit_buttons = {
  74.     {x=1,graphic='[*]',desc="New file.",call=function()
  75.         local file = showBox("New file","Enter file name","input",21,10)
  76.         refreshScreen()
  77.         if(#file <= 0 or file == "/")then
  78.             refreshScreen()
  79.             return
  80.         end  
  81.         if(fs.exists(file))then
  82.             showBox("File","File \"" .. file:sub(1,15) .. "\"\n already exists. \n\n  Press any key.","key",21,10)
  83.             refreshScreen()
  84.             return
  85.         end
  86.         local size = tonumber(showBox("New File","Enter file size\n(In bytes hex)","input",21,10),16)
  87.         if(size == nil)then
  88.             showBox("New File","Invalid file size.","key",21,9)
  89.             refreshScreen()
  90.             return
  91.         end
  92.         if (size <= 0 or size > tonumber("FFFFF",16)) then
  93.             showBox("New File","Invalid file size.","key",21,9)
  94.             refreshScreen()
  95.             return
  96.         end
  97.         local result = showBox("New File","Create file - \n" .. file .. "?","yesno",21,10)
  98.         refreshScreen()
  99.         if(result == "yes")then
  100.             newFile(file,size)
  101.             showBox("File"," File created - \n " .. file .. "\n Press any key.","key",21,8)
  102.         end
  103.         refreshScreen()
  104.     end},
  105.     {x=5,graphic= "[" .. string.char(24) .. "]",desc="Open file.",call=function()
  106.         local file = showBox("Open File","Enter file name or\n location.","input",21,10)
  107.         refreshScreen()
  108.         if(not fs.exists(file) or #file <= 0)then
  109.             showBox("File"," File doesnt exist - \n " .. file .. "\n Press any key.","key",21,8)
  110.             refreshScreen()
  111.             return
  112.         end
  113.         local result = showBox("File","Open file, " .. file .. "?","yesno",21,10)
  114.         refreshScreen()
  115.         if(result == "yes")then
  116.             showBox("File","Loading\n"..file,"nomode",21,3)
  117.             loadFile(file)
  118.             refreshScreen()
  119.             showBox("File"," File loaded - \n " .. _hexFile .. "\n Press any key.","key",21,8)
  120.         end
  121.         refreshScreen()
  122.     end},
  123.     {x=9,graphic="[" .. string.char(25) .. "]",desc="Save file.",call=function()
  124.         local result = showBox("File","Save file, \n" .. _hexFile .. "?","yesno",21,10)
  125.         refreshScreen()
  126.         if(result == "yes")then
  127.             f = fs.open(_hexFile,"wb")
  128.             for i = 1, #_hexData do
  129.                 local byte = string.byte(_hexData:sub(i,i))
  130.                 f.write(byte)
  131.             end
  132.             f.close()
  133.             showBox("File"," File saved - " .. _hexFile .. "\n Press any key.","key",21,6)
  134.             refreshScreen()
  135.         end
  136.     end},
  137.     {x=13,graphic="(" .. "?" .. ")",desc="Find Hex/Text.",call=function()
  138.             local str, result = showBox("Find Hex/Ascii","Find what?","inputmode",21,10,"Hex","Ascii",true)
  139.             if(str == nil or str == "")then refreshScreen() return false end
  140.             local dir = showBox("Find " .. string.upper(result:sub(1,1)) .. result:sub(2,-1),"Up or down?","yesno",21,10,"Up","Down")
  141.             searchFile((result),dir,str)
  142.             refreshScreen()
  143.     end},
  144.     {x=17,graphic='[R]',desc="Resize file.",call=function()
  145.         local size = tonumber(showBox("Resize File","Enter file size\n(In bytes hex)","input",21,10),16)
  146.         if(size == nil)then refreshScreen() return false end
  147.         if (size <= 0 or size > tonumber("FFFFF",16) or size == nil) then
  148.             showBox("Resize File","Invalid file size.","key",21,9)
  149.             refreshScreen()
  150.             return
  151.         end
  152.         local result = showBox("Resize File","Resize file from \n" .. _hexSize .. "\nto\n" .. size .. "?\n\nThis may result in\nloss of information.","yesno",25,15)
  153.         refreshScreen()
  154.         if(result == "yes")then
  155.             _hexSelected = 1
  156.             _currentMemory = 0
  157.             if(size < _hexSize)then
  158.                 _hexData = _hexData:sub(1,size)
  159.                 _hexSize = #_hexData
  160.             else
  161.                 _hexData = _hexData:sub(1,-1) .. string.rep(string.char(0),size-_hexSize)
  162.                 _hexSize = #_hexData
  163.             end
  164.             showBox("Resize File"," File resized!\n   Press any key.","key",21,8)
  165.         end
  166.         refreshScreen()
  167.     end},
  168. }
  169.  
  170. hexedit_dropdowns = {
  171.     ['file'] = {{txt="New (^+N)",call = function() hexedit_buttons[1].call()
  172.             refreshScreen()
  173.      end},
  174.         {txt="Open",call = function() hexedit_buttons[2].call() end},
  175.         {txt="Save (^+A)",call = function() hexedit_buttons[3].call() end},{txt=""},
  176.         {txt="Exit (^+X)",call = function() exitHexIt() end}},
  177.     ['edit'] = {{txt="Insert",call = function()
  178.         _hexBuffer = ""
  179.         local ins, itype = showBox("Insert At Cursor","Enter value to insert","inputmode",21,14,"Hex","Ascii")
  180.         if(ins ~= "" and itype == "hex")then
  181.             charStr = ""
  182.             ins = ins:gsub("%s","")
  183.             for i = 1, #ins, 2 do
  184.                 local charbyte = tonumber(ins:sub(i,i+1),16)
  185.                 if(charbyte == nil)then
  186.                     showBox("Hex Insert","Invalid data.","key",21,9)
  187.                     refreshScreen()
  188.                     return
  189.                 end
  190.                 charStr = charStr .. string.char(charbyte)
  191.             end
  192.             insertBytes(_hexSelected,charStr)
  193.         elseif(ins ~= "")then
  194.             insertBytes(_hexSelected,ins)
  195.         end
  196.         refreshScreen()
  197.     end},{txt="Resize",call = function() hexedit_buttons[5].call() end},
  198.     {txt="Mode (^+M)",call = function()
  199.         _hexEditMode = showBox("Editing Mode","Set edit mode \nReturn: Press enter for each edit. \nFill: When you fill the input.","yesno",35,12,"Return","Fill")
  200.     end},{txt="Bit Edit",call = function()
  201.         local edit, dtype = showBox("Edit Bits","Enter value to set: \n" .. getByte(_hexSelected) .. " to. ","inputmode",21,14,"Binary","Decimal",true)
  202.         if(edit ~= nil and edit ~= "")then
  203.             if(dtype == "binary")then
  204.                 edit = tonumber(edit,2)
  205.                 if(edit == nil)then showBox("Invalid Input","Invalid input for \nmode:\"" .. dtype .. "\"","key",21,12) return false end
  206.             end
  207.             if(not tonumber(edit))then showBox("Invalid Input","Invalid input: \n" .. edit .. "\nFor mode: \n\"" .. dtype .. "\"","key",21,12) return false end
  208.             if(string.char(edit) == nil)then return false end
  209.             setChar(_hexSelected, string.char(edit))
  210.         end
  211.     end},
  212.     {txt=" "},{txt="Delete at Cursor",call = function()
  213.          if(_hexSelected > 0)then
  214.             _hexData = _hexData:sub(1,_hexSelected-1) .. _hexData:sub(_hexSelected+1,-1)
  215.             _hexSize = #_hexData
  216.             if(_hexSelected > _hexSize)then _hexSelected = _hexSize end
  217.             refreshScreen()
  218.             -- Used to refresh string stream
  219.             jumpToByte(_hexSelected)
  220.          end
  221.     end}, {txt="Refresh Screen",call = function()
  222.             refreshScreen()
  223.             -- Used to refresh string stream
  224.             jumpToByte(_hexSelected)
  225.     end}},
  226.     ['search'] = {{txt="Search Hex (^+F)",call = function()
  227.             local hexStr, dir = showBox("Find Hex","Enter string of Hex \ncharacters to \nfind.","inputmode",21,14,"Up","Down",true)
  228.             if(hexStr == nil or hexStr == "")then refreshScreen() return false end
  229.             searchFile("hex",(dir),hexStr)
  230.             refreshScreen()
  231.     end},{txt="Search Chars (^+F)",call = function()
  232.         local charStr, dir = showBox("Find Ascii","Enter string of \ncharacters to find.","inputmode",21,14,"Up","Down",true)
  233.         if(charStr == nil or charStr == "")then refreshScreen() return false end
  234.         searchFile("ascii",(dir),charStr)
  235.         refreshScreen()
  236.     end},{txt=" "},{txt="Clear Searches",call = function()
  237.         local result = showBox("Clear Searches","This will delete all\nprevious searches.","yesno",21,10)
  238.         if(result == "yes")then _searches = {} showBox("Searches","Searches cleared. \n   Press any key. ","key",21,10) end
  239.         refreshScreen()
  240.     end}},
  241.     ['address'] = {{txt="Goto (^+J)",call = function()
  242.         _hexBuffer = ""
  243.         local addr = tonumber(showBox("Jump to Address","Enter the Address you\nwant to jump to below.","input",21,10),16)
  244.         if(addr == nil)then
  245.             showBox("Jump to Address","Invalid jump.","key",21,9)
  246.             refreshScreen()
  247.             return
  248.         end
  249.         jumpToByte(addr)
  250.     end},{txt=" "},
  251.     {txt="Save Address", call = function()
  252.         if(_hexSelected == 0)then
  253.             _hexAddress = _currentMemory
  254.         else
  255.             _hexAddress = _hexSelected
  256.         end
  257.         showBox("Address Saved","Saved address -\n" .. toHex(_hexAddress),"key",21,9)
  258.         refreshScreen()
  259.     end},{txt="Get Address",call = function()
  260.         if(_hexAddress ~= "")then
  261.             showBox("Address Saved","address -\n" .. toHex(_hexAddress),"key",21,9)
  262.         else
  263.             showBox("Address Jump","No address saved.","key",21,9)
  264.         end
  265.         refreshScreen()
  266.     end},{txt="Goto Saved",call = function()
  267.         if(_hexAddress ~= "")then
  268.             jumpToByte(_hexAddress)
  269.             showBox("Address Jump","Jumped to -\n" .. toHex(_hexAddress),"key",21,9)
  270.         else
  271.             showBox("Address Jump","No address saved.","key",21,9)
  272.         end
  273.         refreshScreen()
  274.     end}},
  275. }
  276. hexedit_menus = {
  277.     {x=1,text="File",call=function()
  278.         dropMenu(1,2,dropColors,hexedit_dropdowns['file'],1)
  279.         if(running)then refreshScreen() end
  280.     end},
  281.     {x=7,text="Edit",call=function()
  282.         dropMenu(7,2,dropColors,hexedit_dropdowns['edit'],1)
  283.         refreshScreen()
  284.     end},
  285.     {x=13,text="Search",call=function()
  286.         dropMenu(13,2,dropColors,hexedit_dropdowns['search'],1)
  287.         refreshScreen()
  288.     end},
  289.     {x=21,text="Address",call=function()
  290.         local mox = 21
  291.         if(_isPocket)then mox = 13 end
  292.         dropMenu(mox,2,dropColors,hexedit_dropdowns['address'],1)
  293.         refreshScreen()
  294.     end},
  295. }
  296.  
  297. if(_isPocket)then
  298.     table.remove(hexedit_menus,3)
  299.     hexedit_menus[3].x = 13
  300. end
  301.  
  302.  
  303.  
  304. function searchFile(mode,dir,bytes)
  305.     --error(mode .. ": " .. dir .. " :> " .. bytes)
  306.     if(bytes == nil)then return false end
  307.     if(mode == "hex")then
  308.     -- Convert hex string to Ascii, for ease of use using string.find.
  309.         local charStr = ""
  310.         hexStr = bytes:gsub("%s","")
  311.         for i = 1, #hexStr, 2 do
  312.             local charbyte = tonumber(hexStr:sub(i,i+1),16)
  313.             if(charbyte == nil)then
  314.                 showBox("Find Hex","Invalid search.","key",21,9)
  315.                 refreshScreen()
  316.                 return
  317.             end
  318.             charStr = charStr .. string.char(charbyte)
  319.         end
  320.         local findex
  321.         if(dir == "down")then
  322.             findex, _ = _hexData:find(charStr,_hexSelected)
  323.             if(checkJump(findex))then -- We are already here.
  324.                 findex, _ = _hexData:find(charStr,_hexSelected+#charStr+1)
  325.             end
  326.         elseif("up")then
  327.             findex, _ = (_hexData:sub(1,_hexSelected)):reverse():find(charStr:reverse())
  328.             if(findex ~= nil)then
  329.                 findex = (#(_hexData:sub(1,_hexSelected))+1-findex)-(#charStr-1)
  330.                 if(checkJump(findex))then -- We are already here.
  331.                     findex, _ = (_hexData:sub(1,_hexSelected-1)):reverse():find(charStr:reverse())
  332.                     findex = (#(_hexData:sub(1,_hexSelected-1))+1-findex)-(#charStr-1)
  333.                 end
  334.             end
  335.         else
  336.             showBox("Invalid search","Invalid mode: \n" .. dir .. "\n  Press any key. ","key",21,10)
  337.             return false
  338.         end
  339.         if(findex ~= nil)then
  340.             if(showBox("Jump to location?","Jump to hex \nfound at:" .. toHex(findex) .. "?","yesno",21,10) == "yes")then
  341.                 jumpToByte(findex)
  342.                 writeMode = "hex"
  343.             end
  344.         else
  345.             showBox("Find Hex","Not found: \n" .. hexStr:sub(1,20) .. "\n   Press any key. ","key",21,10)
  346.         end
  347.         refreshScreen()
  348.     elseif(mode == "ascii")then
  349.         local findex
  350.         if(dir == "down")then
  351.             findex, _ = _hexData:find(bytes,_hexSelected)
  352.             if(checkJump(findex))then -- We are already here.
  353.                 findex, _ = _hexData:find(bytes,_hexSelected+#bytes+1)
  354.             end
  355.         elseif("up")then
  356.             findex, _ = (_hexData:sub(1,_hexSelected)):reverse():find(bytes:reverse())
  357.             if(findex ~= nil)then
  358.                 findex = (#(_hexData:sub(1,_hexSelected))+1-findex)-(#bytes-1)
  359.                 if(checkJump(findex))then -- We are already here.
  360.                     findex, _ = (_hexData:sub(1,_hexSelected-1)):reverse():find(bytes:reverse())
  361.                     findex = (#(_hexData:sub(1,_hexSelected-1))+1-findex)-(#bytes-1)
  362.                 end
  363.             end
  364.         else
  365.             showBox("Invalid search","Invalid mode: \n" .. dir .. "\n   Press any key. ","key",21,10)
  366.             return false
  367.         end
  368.             if(findex ~= nil)then
  369.                 if(showBox("Jump to location?","Jump to string \nfound at:" .. toHex(findex) .. "?","yesno",21,10) == "yes")then
  370.                     jumpToByte(findex)
  371.                     writeMode = "char"
  372.                 end
  373.             else
  374.                 showBox("Find Ascii","Not found: \n" .. bytes:sub(1,20) .. "\n   Press any key. ","key",21,10)
  375.             end
  376.         refreshScreen()
  377.     else
  378.         showBox("Invalid search","Invalid mode: \n" .. mode .. "\n   Press any key. ","key",21,10)
  379.     end
  380.     _lastSearch.dir = dir
  381.     _lastSearch.mode = mode
  382.     _lastSearch.data = bytes
  383. end
  384.  
  385. function getScreenPage(val)
  386.     return math.ceil(val / (_hexLineSize * (h-3)))
  387. end
  388.  
  389. function exitHexIt()
  390.     running = false
  391.     term.setTextColor(colors.white)
  392.     term.setBackgroundColor(colors.black)
  393.     term.clear()
  394.     term.setCursorPos(1, 1)
  395.     print("Thanks for using HexIt!")
  396.     print("If you enjoyed the program be sure to give it an up vote on the forums!")
  397. end
  398.  
  399.  
  400. function flashButton(tc,bc,time,x,y,graphic,nt,nb)
  401.     term.setCursorPos(x,y)
  402.     term.setTextColor(tc)
  403.     term.setBackgroundColor(bc)
  404.     write(graphic)
  405.     sleep(time)
  406.     term.setCursorPos(x,y)
  407.     term.setTextColor(nt)
  408.     term.setBackgroundColor(nb)
  409.     write(graphic)
  410. end
  411.  
  412. function seekPage(pg)
  413.     if(#_hexBuffer > 0)then _hexBuffer = "" end
  414.     _currentMemory = _currentMemory + (pg*_hexLineSize * (h-3))
  415.     if(_currentMemory < 0)then _currentMemory = 0 end
  416.     if(getScreenPage(_currentMemory) >= getScreenPage(_hexSize))then
  417.     _currentMemory = (getScreenPage(_hexSize)-1)*_hexLineSize * (h-3)
  418.     end
  419.     redrawData()
  420. end
  421. function seek(mem)
  422.     if(_currentMemory + mem*_hexLineSize < 0)then return false end
  423.     if(_currentMemory + mem*_hexLineSize > _hexSize)then return false end
  424.     if(#_hexBuffer > 0)then _hexBuffer = "" end
  425.     _currentMemory = _currentMemory + (mem*_hexLineSize)
  426.     if(_currentMemory < 0)then _currentMemory = 0 end
  427.     if(getScreenPage(_currentMemory) >= getScreenPage(_hexSize))then
  428.         _currentMemory = (getScreenPage(_hexSize)-1)*_hexLineSize * (h-3)
  429.     end
  430.     redrawData()
  431. end
  432.  
  433. function toHex(dec)
  434.     local hex = ""
  435.     local hexkey = "0123456789ABCDEF"
  436.     local rim
  437.     if(dec == nil)then
  438.         error("Failed to load file: " .. _hexFile .. " at " .. _hexLastByte)
  439.     end
  440.     if(dec == 0)then hex = "0" end
  441.     while dec > 0 do
  442.        rim = math.floor(dec%16)
  443.        hex = hexkey:sub(rim+1,rim+1) .. hex
  444.        dec = math.floor(dec/16)
  445.     end
  446.     if(#hex == 1)then
  447.       hex = "0" .. hex
  448.     end
  449.     if(dec < 0)then
  450.       local num = 256 + dec
  451.       return toHex(num)
  452.     end
  453.     return hex
  454. end
  455.  
  456. function toBin (dec)
  457.     -- Convert to base 10 soooo easy
  458.     local bin = ""
  459.     local binkey = "01"
  460.     local rim
  461.     if(type(dec) == "string")then error("toBin -> Invalid type: " .. dec) end
  462.     while dec > 0 do
  463.        rim = math.floor(dec%2)
  464.        bin = binkey:sub(rim+1,rim+1) .. bin
  465.        dec = math.floor(dec/2)
  466.     end
  467.     if(#bin < 8)then
  468.       bin = string.rep("0",8-#bin) .. bin
  469.     end
  470.     return bin
  471.   end
  472.  
  473.  
  474. function drawGUI()
  475.     term.setBackgroundColor(colors.white)
  476.     term.clear()
  477.     paintutils.drawLine(1,1,w,1,colors.gray)
  478.     paintutils.drawLine(1,2,w,2,colors.lightGray)
  479.     term.setTextColor(colors.white)
  480.     term.setCursorPos(w,1)
  481.     term.blit("X","0","e")
  482.     term.setCursorPos(1,2)
  483.     for i = 1, #hexedit_buttons do
  484.         write(hexedit_buttons[i].graphic .. " ")
  485.     end
  486.     if(not _isPocket)then
  487.         term.setCursorPos(math.max(w-(9+#_hexFile),hexedit_buttons[#hexedit_buttons].x+#hexedit_buttons[#hexedit_buttons].graphic+1), 2)
  488.         write("Editing: ")
  489.         term.setBackgroundColor(colors.green)
  490.         term.setTextColor(colors.white)
  491.         if( (w-(9+#_hexFile)) < hexedit_buttons[#hexedit_buttons].x+4)then
  492.             write(_hexFile:sub(1,hexedit_buttons[#hexedit_buttons].x-2) .. "...")
  493.         else
  494.             write(_hexFile)
  495.         end
  496.     end
  497.     term.setTextColor(colors.lightGray)
  498.     term.setBackgroundColor(colors.gray)
  499.     term.setCursorPos(1,1)
  500.     for i = 1, #hexedit_menus do
  501.         write(hexedit_menus[i].text .. "  ")
  502.     end
  503.  
  504.     paintutils.drawLine(1+barsize,3,1+barsize,h,colors.lightGray)
  505.     paintutils.drawLine(2+barsize,3,2+barsize,h,colors.black)
  506.     -- 3 / 2 = 1.5 "#(LL ) = 3" div 2 because of string.reps
  507.     paintutils.drawLine(barsize+(view_w)+baroffs,3,barsize+(view_w)+baroffs,h,colors.lightGray)
  508. end
  509.  
  510. function loadFile(file)
  511.     if(not fs.exists(file))then error("HexEditCC: error -> File doesn't exist (" .. file .. ")." ) end
  512.     -- Load data into vars
  513.     _currentMemory = 0
  514.     _hexData = ""
  515.     _hexSelected = 1
  516.     _hexFile = ""
  517.     _hexSize = 1
  518.     _hexBuffer = ""
  519.     _hexLastByte = 0
  520.     f = fs.open(file,"rb")
  521.     _hexFile = file
  522.     for byte in f.read do
  523.         _hexData = _hexData .. string.char(byte)
  524.     end
  525.     f.close()
  526.     if(#_hexData == 0)then _hexData = string.char(0) end
  527.     _hexSize = #_hexData
  528. end
  529.  
  530. function newFile(file,size)
  531.     if(fs.exists(file))then error("HexEditCC: error -> File already exists (" .. file .. ")." ) end
  532.     -- Load data into vars
  533.     _currentMemory = 0
  534.     _hexData = ""
  535.     _hexSelected = 1
  536.     _hexFile = ""
  537.     _hexSize = 1
  538.     _hexBuffer = ""
  539.     _hexLastByte = 0
  540.     _hexFile = file
  541.     _hexData = _hexData .. string.rep(string.char(0),size)
  542.     if(#_hexData == 0)then _hexData = string.char(0) end
  543.     _hexSize = #_hexData
  544. end
  545.  
  546. function moveSelectedByte(dir)
  547.     drawSelectedByte(1)
  548.     _hexSelected = _hexSelected + dir
  549.     if(_hexSelected > _hexSize)then _hexSelected = _hexSize end
  550.     if(_hexSelected < 1)then _hexSelected = 1 end
  551.     if( math.ceil((_hexSelected-_currentMemory)/_hexLineSize) > h-2)then
  552.         seek(1)
  553.     end
  554.     if( math.ceil((_hexSelected-_currentMemory)/_hexLineSize) <= 0)then
  555.         seek(-1)
  556.     end
  557.     drawSelectedByte()
  558. end
  559.  
  560. function getByte(byte)
  561.     if(_hexData == "")then return "00" end
  562.     _hexLastByte = byte
  563.     if(byte > #_hexData)then return nil end
  564.     return toHex(string.byte(_hexData:sub(byte,byte)))
  565. end
  566.  
  567. function getChar(byte)
  568.     if(_hexData == "")then return "00" end
  569.     _hexLastByte = byte
  570.     if(byte > #_hexData)then return nil end
  571.     return _hexData:sub(byte,byte):gsub("\n"," ")
  572. end
  573.  
  574. function setByte(addr,byte)
  575.     local byte = string.char(tonumber(byte,16))
  576.     _hexData = _hexData:sub(1,addr-1) .. byte .. _hexData:sub(addr+1,-1)
  577.     _hexBuffer = ""
  578.     moveSelectedByte(1)
  579. end
  580.  
  581. function setChar(addr,byte)
  582.     _hexData = _hexData:sub(1,addr-1) .. byte .. _hexData:sub(addr+1,-1)
  583.     _hexBuffer = ""
  584.     moveSelectedByte(1)
  585. end
  586.  
  587. function insertBytes(addr,bytes)
  588.     local ovrhex = _hexData:sub(1,addr) .. bytes .. _hexData:sub(addr,-1)
  589.     _hexData = ovrhex
  590.     _hexSize = #_hexData
  591.     moveSelectedByte(#bytes)
  592. end
  593.  
  594. function checkJump(addr)
  595.     if(addr == nil)then
  596.         return false
  597.     end
  598.     local offs = 1
  599.  
  600.     if(addr > _hexLineSize)then
  601.         offs = math.floor(addr%_hexLineSize)
  602.         addr = math.floor(addr/_hexLineSize)
  603.         return (_hexSelected == ((addr)*_hexLineSize) + offs)
  604.     else
  605.         return (_hexSelected == offs)
  606.     end
  607. end
  608.  
  609. function jumpToByte(addr)
  610.     if(addr == nil)then
  611.         refreshScreen()
  612.         return false
  613.     end
  614.     local offs = 1
  615.     drawSelectedByte(1)
  616.     drawGUI()
  617.  
  618.     if(addr > _hexLineSize)then
  619.         offs = math.floor(addr%_hexLineSize)
  620.         addr = math.floor(addr/_hexLineSize)
  621.         _hexSelected = ((addr)*_hexLineSize) + offs
  622.         if(_hexSelected > _hexSize)then
  623.             _hexSelected = 0
  624.             redrawData()
  625.             showBox("Notice","End of file reached.","key",21,3)
  626.             drawGUI()
  627.             return false
  628.         else
  629.             _currentMemory = ((addr)*_hexLineSize)
  630.         end
  631.     else
  632.         offs = addr
  633.         _currentMemory = 0
  634.         _hexSelected = offs
  635.     end
  636.    
  637.     drawSelectedByte()
  638.     redrawData()
  639.     -- Re-align memory
  640.     seek(1)
  641.     seek(-1)
  642.     return true
  643. end
  644.  
  645. function printLn(txt)
  646.     local lines={}
  647.     local i=1
  648.     for str in string.gmatch(txt, "([^\n]+)") do
  649.         lines[i] = str
  650.         i = i + 1
  651.     end
  652.     for i = 1, #lines do
  653.         local _x, _y = term.getCursorPos()
  654.         write(lines[i])
  655.         term.setCursorPos(_x, _y+1)
  656.     end
  657. end
  658.  
  659. function dropMenu(sx,sy,mcolors,buttons,textoffs)
  660.     local inmenu = true
  661.     if(textoffs == nil)then textoffs = 0 end
  662.     menuDrop = {
  663.         mx = sx,
  664.         my = sy,
  665.         mw = 1,
  666.         txtoff = textoffs,
  667.         tcol = mcolors[1],
  668.         bcol = mcolors[2],
  669.         ftcol = mcolors[3],
  670.         fbcol = mcolors[4],
  671.         menu = buttons, -- Menu structure: {txt="Test",call=function() do stuff! end}
  672.         mh = #buttons,
  673.         draw = function(self)
  674.                 term.setTextColor(self.tcol)
  675.                 term.setBackgroundColor(self.bcol)
  676.                 term.setCursorPos(self.mx,self.my)
  677.                 -- Get longest length of menu for size
  678.                 for i = 1, #self.menu do
  679.                     if(self.mw < (#self.menu[i].txt)+self.txtoff)then
  680.                        self.mw = (#self.menu[i].txt)+self.txtoff
  681.                     end
  682.                 end
  683.                 paintutils.drawFilledBox(self.mx-1,self.my+1,self.mw+self.mx,self.mh+self.my+2,colors.black)
  684.                 paintutils.drawFilledBox(self.mx,self.my,self.mw+self.mx+1,self.mh+self.my+1,self.bcol)
  685.                 -- Commence drawing!
  686.                 for i = 1, #self.menu do
  687.                     term.setCursorPos(self.mx+self.txtoff,self.my+i)
  688.                     write(self.menu[i].txt)
  689.                 end
  690.         end,
  691.         clickbutton = function(self,time,buttonindex)
  692.             if(self.menu[buttonindex].call ~= nil)then
  693.                 term.setTextColor(self.ftcol)
  694.                 term.setBackgroundColor(self.fbcol)
  695.                 term.setCursorPos(self.mx+self.txtoff,self.my+buttonindex)
  696.                 write(self.menu[buttonindex].txt)
  697.                 sleep(time)
  698.                 term.setTextColor(self.tcol)
  699.                 term.setBackgroundColor(self.bcol)
  700.                 term.setCursorPos(self.mx+self.txtoff,self.my+buttonindex)
  701.                 write(self.menu[buttonindex].txt)  
  702.                 self.menu[buttonindex].call()
  703.                 inmenu = false
  704.                 return
  705.             end
  706.         end,
  707.         update = function(self,ev)
  708.             if(inmenu == false)then
  709.                 return false
  710.             end
  711.             if(ev[1] == "mouse_click")then
  712.                 local mb, mx, my = ev[2], ev[3], ev[4]
  713.                 if(mb == 1)then
  714.                     if(mx >= self.mx and mx < self.mx+self.mw and my >= self.my and my <= self.my+self.mh+1)then
  715.                         if(mx >= self.mx+self.txtoff)then
  716.                             if(self.menu[(my-self.my)])then
  717.                                 self:clickbutton(0.1,(my-self.my))
  718.                             end
  719.                         end
  720.                     else
  721.                         inmenu = false
  722.                         return false
  723.                     end
  724.                 end
  725.             end
  726.             return true
  727.         end,
  728.     }
  729.     menuDrop:draw()
  730.     while inmenu do
  731.         if(not menuDrop:update({os.pullEvent()}))then
  732.             return
  733.         end
  734.     end
  735. end
  736.  
  737. function showBox(title,text,btype,bw,bh,ym,nm,hist)
  738.     local prevsearches = _searches
  739.     if(hist == nil)then
  740.         hist = false   
  741.     end
  742.     local midw, midh = math.floor(w/2), math.floor(h/2)
  743.     paintutils.drawFilledBox((midw-(bw/2))-1,(midh-(bh/2))+1,(midw+(bw/2))-1,midh+1, colors.black)
  744.     paintutils.drawFilledBox(midw-(bw/2),midh-(bh/2),(midw+(bw/2)),midh, colors.lightGray)
  745.     paintutils.drawLine(midw-(bw/2),midh-(bh/2),(midw+(bw/2)),midh-(bh/2), colors.blue)
  746.     term.setTextColor(colors.white)
  747.     term.setBackgroundColor(colors.blue)
  748.     term.setCursorPos(midw-(bw/2)+1,(midh-(bh/2)))
  749.     write(title)
  750.     term.setTextColor(colors.white)
  751.     term.setBackgroundColor(colors.lightGray)
  752.     term.setCursorPos(midw-(bw/2),midh-(bh/2)+1)
  753.     printLn(text)
  754.     if(btype == "input")then
  755.         sleep(0.01) -- Cancel already pressed keys.
  756.         local readwin = window.create(term.current(),(midw-(bw/2))+1,midh-1,bw-1,1)
  757.         paintutils.drawLine((midw-(bw/2))+1,midh-1,(midw+(bw/2))-1,midh-1, colors.black)
  758.         term.setCursorPos((midw-(bw/2))+1,midh-1)
  759.         local _oldTerm = term.current()
  760.         term.redirect(readwin)
  761.         local res
  762.         if(hist == true)then
  763.              res = read(nil,_searches)
  764.             if((res ~= "" or res ~= nil))then
  765.                 table.insert(_searches, res)
  766.             end
  767.         else
  768.              res = read()
  769.         end
  770.         term.redirect(_oldTerm)
  771.         term.setCursorPos((midw-(bw/2))+1,midh-1)
  772.         write(res:sub(1,bw-2))
  773.         return res
  774.     end
  775.     if(btype == "key")then os.pullEvent("key") end
  776.     if(btype == "inputmode")then
  777.         sleep(0.01) -- Cancel already pressed keys.
  778.         paintutils.drawLine((midw-(bw/2))+1,midh-3,(midw+(bw/2))-1,midh-3, colors.black)
  779.         if(ym == nil)then ym = "Yes" end
  780.         if(nm == nil)then nm = "No" end
  781.         paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.green)
  782.         term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  783.         write("1. " .. ym)
  784.         paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.red)
  785.         term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  786.         write("2. " .. nm)
  787.         term.setBackgroundColor(colors.black)
  788.         term.setCursorPos((midw-(bw/2))+1,midh-3)
  789.         local readwin = window.create(term.current(),(midw-(bw/2))+1,midh-3,bw-1,1)
  790.         local _oldTerm = term.current()
  791.         term.redirect(readwin)
  792.         local res
  793.         if(hist == true)then
  794.             res = read(nil,_searches)
  795.             if((res ~= "" or res ~= nil))then
  796.                 table.insert(_searches, res)
  797.             end
  798.         else
  799.             res = read()
  800.         end
  801.         term.redirect(_oldTerm)
  802.         term.setCursorPos((midw-(bw/2))+1,midh-3)
  803.         write(res:sub(1,bw-2))
  804.        
  805.         if(res == nil or res == "")then return "" end
  806.         local rett = ""
  807.         local waiting = true
  808.         while waiting do
  809.             local e,b,mx,my = os.pullEvent()
  810.             if(e == "mouse_click")then
  811.                 if(mx >= (midw-(bw/2))+1 and mx <= midw-2 and my == midh-1)then -- Yes
  812.                     paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.black)
  813.                     term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  814.                     write("1. " .. ym)
  815.                     sleep(0.1)
  816.                     waiting = false
  817.                     rett = ym
  818.                 elseif(mx >= midw+1 and mx <= (midw+(bw/2))-1 and my == midh-1)then -- No
  819.                     paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.black)
  820.                     term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  821.                     write("2. " .. nm)
  822.                     sleep(0.1)
  823.                     waiting = false
  824.                     rett = nm
  825.                 end
  826.             elseif(e == "key")then
  827.                 if(b == keys.one or b == keys.numPad1 or b == keys.enter)then
  828.                     paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.black)
  829.                     term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  830.                     write("1. " .. ym)
  831.                     sleep(0.1)
  832.                     waiting = false
  833.                     rett = ym
  834.                 elseif(b == keys.two or b == keys.numPad2 or b == keys.backspace)then
  835.                     paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.black)
  836.                     term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  837.                     write("2. " .. nm)
  838.                     sleep(0.1)
  839.                     waiting = false
  840.                     rett = nm
  841.                 end
  842.             end
  843.         end
  844.         return res, string.lower(rett)
  845.     end
  846.     if(btype == "yesno")then
  847.         if(ym == nil)then ym = "Yes" end
  848.         if(nm == nil)then nm = "No" end
  849.         paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.green)
  850.         term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  851.         write("1. " .. ym)
  852.         paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.red)
  853.         term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  854.         write("2. " .. nm)
  855.         term.setBackgroundColor(colors.black)
  856.         term.setCursorPos((midw-(bw/2))+1,midh-3)
  857.         local waiting = true
  858.         while waiting do
  859.             local e,b,mx,my = os.pullEvent()
  860.             if(e == "mouse_click")then
  861.                 if(mx >= (midw-(bw/2))+1 and mx <= midw-2 and my == midh-1)then -- Yes
  862.                     paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.black)
  863.                     term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  864.                     write("1. " .. ym)
  865.                     sleep(0.1)
  866.                     waiting = false
  867.                     return string.lower(ym)
  868.                 elseif(mx >= midw+1 and mx <= (midw+(bw/2))-1 and my == midh-1)then -- No
  869.                     paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.black)
  870.                     term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  871.                     write("2. " .. nm)
  872.                     sleep(0.1)
  873.                     waiting = false
  874.                     return string.lower(nm)
  875.                 end
  876.             elseif(e == "key")then
  877.                 if(b == keys.one or b == keys.numPad1 or b == keys.enter)then
  878.                     paintutils.drawLine((midw-(bw/2))+1,midh-1,midw-2,midh-1, colors.black)
  879.                     term.setCursorPos((((midw-(bw/2))+1+(midw-2))/2)-math.floor( (#ym+3)/2),midh-1)
  880.                     write("1. " .. ym)
  881.                     sleep(0.1)
  882.                     waiting = false
  883.                     return string.lower(ym)
  884.                 elseif(b == keys.two or b == keys.numPad2 or b == keys.backspace)then
  885.                     paintutils.drawLine(midw+1,midh-1,(midw+(bw/2))-1,midh-1, colors.black)
  886.                     term.setCursorPos(((midw+1+(midw+(bw/2))-1)/2)-math.floor( (#nm+3)/2),midh-1,midh-1)
  887.                     write("2. " .. nm)
  888.                     sleep(0.1)
  889.                     waiting = false
  890.                     return string.lower(nm)
  891.                 end
  892.             end
  893.         end
  894.     end
  895.     sleep(0.1)
  896. end
  897.  
  898.  
  899. function drawHexBuffer()
  900.     if( ((_hexSelected-_currentMemory)/view_w) <= h and math.ceil((_hexSelected-_currentMemory)/_hexLineSize) >= 1)then
  901.         if( math.ceil((_hexSelected-_currentMemory)/_hexLineSize) <= 1)then
  902.             hy = 1
  903.             hx = (_hexSelected-_currentMemory)*3
  904.         else
  905.             hy = math.ceil((_hexSelected-_currentMemory)/_hexLineSize)
  906.             hx = math.ceil((_hexSelected-_currentMemory)%_hexLineSize)*3
  907.             if(math.ceil((_hexSelected-_currentMemory)%_hexLineSize) == 0)then
  908.                 hx = _hexLineSize*3
  909.             end
  910.         end
  911.         if(writeMode == "hex")then
  912.             if(not un)then
  913.                 term.setTextColor(colors.white)
  914.                 term.setBackgroundColor(colors.blue)
  915.             else
  916.                 term.setTextColor(colors.lightGray)
  917.                 term.setBackgroundColor(colors.black)
  918.             end
  919.             term.setCursorPos(hx+barsize,hy+2)
  920.             write("  ")
  921.             term.setCursorPos(hx+barsize,hy+2)
  922.             write(_hexBuffer)
  923.         elseif(writeMode == "char")then
  924.             if(not un)then
  925.                 term.setTextColor(colors.lightGray)
  926.                 term.setBackgroundColor(colors.orange)
  927.             else
  928.                 term.setTextColor(colors.black)
  929.                 term.setBackgroundColor(colors.white)
  930.             end
  931.             term.setCursorPos( (view_w+barsize+baroffs) + math.ceil(hx/3), hy+2)
  932.             write(_hexBuffer)
  933.         end
  934.     end
  935. end
  936.  
  937. function drawSelectedByte(un)
  938.     if(#_hexBuffer > 0)then _hexBuffer = "" end
  939.     if(un == nil)then un = false end
  940.     local hx, hy = 1, 1
  941.     if( ((_hexSelected-_currentMemory)/view_w) <= h and math.ceil((_hexSelected-_currentMemory)/_hexLineSize) >= 1)then
  942.         if( math.ceil((_hexSelected-_currentMemory)/_hexLineSize) <= 1)then
  943.             hy = 1
  944.             hx = (_hexSelected-_currentMemory)*3
  945.         else
  946.             hy = math.ceil((_hexSelected-_currentMemory)/_hexLineSize)
  947.             hx = math.ceil((_hexSelected-_currentMemory)%_hexLineSize)*3
  948.             if(math.ceil((_hexSelected-_currentMemory)%_hexLineSize) == 0)then
  949.                 hx = _hexLineSize*3
  950.             end
  951.         end
  952.         if(not un)then
  953.             term.setTextColor(colors.lightGray)
  954.             term.setBackgroundColor(colors.black)
  955.         else
  956.             term.setTextColor(colors.white)
  957.             term.setBackgroundColor(colors.lightGray)
  958.         end
  959.         local sideY = math.ceil((_hexSelected-_currentMemory)/_hexLineSize)
  960.         term.setCursorPos(1,sideY+2)
  961.         local onmem = _currentMemory+(_hexLineSize*(sideY-1))
  962.         write(string.rep(" ", 5-#toHex(onmem)) .. toHex(onmem))
  963.         if(not un)then
  964.             term.setTextColor(colors.lightGray)
  965.             term.setBackgroundColor(colors.blue)
  966.             if(writeMode == "char")then term.setBackgroundColor(colors.orange) end
  967.         else
  968.             term.setTextColor(colors.black)
  969.             term.setBackgroundColor(colors.white)
  970.         end
  971.         term.setCursorPos( (view_w+barsize+baroffs) + math.ceil(hx/3), hy+2)
  972.         write(getChar(_hexSelected))
  973.  
  974.         if(not _isPocket)then
  975.             term.setBackgroundColor(colors.gray)
  976.             term.setTextColor(colors.lime)
  977.             term.setCursorPos(w-22,1)
  978.             local decByte = string.byte(_hexData:sub(_hexSelected,_hexSelected))
  979.             if(decByte == nil)then decByte = 0 end
  980.             write(toHex(math.min(_hexSelected,1048575)) .. "M|" .. toBin(decByte) .. "B|" .. string.rep("0",3-#tostring(decByte)) .. decByte .. "D ")
  981.         end
  982.  
  983.         -- This must happen last needed due to the space after each hex
  984.         if(not un)then
  985.             term.setTextColor(colors.white)
  986.             term.setBackgroundColor(colors.blue)
  987.         else
  988.             term.setTextColor(colors.lightGray)
  989.             term.setBackgroundColor(colors.black)
  990.         end
  991.         term.setCursorPos(hx+barsize,hy+2)
  992.         write(getByte(_hexSelected))
  993.     end
  994. end
  995.  
  996. function redrawData()
  997.     term.setTextColor(colors.black)
  998.     term.setBackgroundColor(colors.white)
  999.     term.setCursorPos(1,1)
  1000.     if(#_hexData == 0)then
  1001.         if(term.current)then term.current().setVisible(true) end
  1002.         showBox("Error"," File too small. \n Inflating 1 byte. \n \n Press any key.","none",21,10)
  1003.         sleep(0.1)
  1004.         _hexData = string.char(0)
  1005.         _hexSize = 1
  1006.         os.pullEvent("key")
  1007.     end
  1008.     -- Draw mem bar
  1009.     local onmem = _currentMemory
  1010.     --local drawSize
  1011.     if( _hexSize-(onmem) > h*(_hexLineSize))then drawSize = h*(_hexLineSize) else drawSize = (_hexSize-(onmem)) end
  1012.     _hexPageSize = drawSize
  1013.     if(getScreenPage(_currentMemory) == getScreenPage(_hexSize)-1)then
  1014.         if(term.current)then term.current().setVisible(false) end
  1015.         paintutils.drawFilledBox(1,3,barsize+1,h,colors.gray)
  1016.         if(term.current)then term.current().setVisible(true) end
  1017.     end
  1018.     for i = 1, math.ceil(drawSize/_hexLineSize) do
  1019.             term.setCursorPos(1,i+2)
  1020.             if(math.ceil((_hexSelected-_currentMemory)/_hexLineSize) == i)then
  1021.                 term.setTextColor(colors.lightGray)
  1022.                 term.setBackgroundColor(colors.black)
  1023.             else
  1024.                 term.setTextColor(colors.white)
  1025.                 term.setBackgroundColor(colors.lightGray)
  1026.             end
  1027.             write(string.rep(" ", 5-#toHex(onmem)) .. toHex(onmem))
  1028.             onmem = onmem + _hexLineSize
  1029.     end
  1030.     if(getScreenPage(_currentMemory) == getScreenPage(_hexSize)-1)then
  1031.         if(term.current)then term.current().setVisible(false) end
  1032.         paintutils.drawFilledBox(barsize+2,3,(barsize+1)+view_w,h,colors.white)
  1033.         if(term.current)then term.current().setVisible(true) end
  1034.     end
  1035.     --paintutils.drawLine(1+barsize,3,1+barsize,h,colors.lightGray)
  1036.     paintutils.drawLine(2+barsize,3,2+barsize,h,colors.black)
  1037.     local ind = 1
  1038.     term.setCursorPos(barsize+3,3)
  1039.     for px = 1, drawSize do
  1040.         if(ind > _hexLineSize)then
  1041.             local _, _y = term.getCursorPos()
  1042.             term.setCursorPos(barsize+3,_y+1)
  1043.             ind = 1
  1044.         end
  1045.         local byte = getByte(px+_currentMemory)
  1046.         if(byte ~= nil)then
  1047.             if((px+_currentMemory) == _hexSelected)then
  1048.                 drawSelectedByte()
  1049.                 term.setTextColor(colors.lightGray)
  1050.                 term.setBackgroundColor(colors.black)
  1051.             else
  1052.                 term.setTextColor(colors.lightGray)
  1053.                 term.setBackgroundColor(colors.black)
  1054.                 write(byte)
  1055.             end
  1056.             if( ((ind) < _hexLineSize) or isEvenRes)then
  1057.                 write(" ")
  1058.             end
  1059.         end
  1060.         ind = ind + 1
  1061.     end
  1062.     if(getScreenPage(_currentMemory) == getScreenPage(_hexSize)-1)then
  1063.         if(term.current)then term.current().setVisible(false) end
  1064.         paintutils.drawFilledBox(view_w+barsize+4,3,w,h,colors.white)
  1065.         if(term.current)then term.current().setVisible(true) end
  1066.     end
  1067.     ind = 1
  1068.     term.setCursorPos(view_w+barsize+1+baroffs,3)
  1069.     for px = 1, drawSize do
  1070.         local _x, _y = term.getCursorPos()
  1071.         if(_x > w)then
  1072.             term.setCursorPos(view_w+barsize+1+baroffs,_y+1)
  1073.             ind = 1
  1074.         end
  1075.         local byte = getChar(px+_currentMemory)
  1076.         if(byte ~= nil)then
  1077.             if((px+_currentMemory) == _hexSelected)then
  1078.                 _x, _y = term.getCursorPos()
  1079.                 drawSelectedByte()
  1080.                 term.setCursorPos(_x+1,_y)
  1081.             else
  1082.                 term.setTextColor(colors.black)
  1083.                 term.setBackgroundColor(colors.white)
  1084.                 write(byte)
  1085.             end
  1086.         end
  1087.         ind = ind + 1
  1088.     end
  1089.     -- 3 / 2 = 1.5 "#(LL ) = 3" div 2 because of string.reps
  1090.     paintutils.drawLine(barsize+(view_w)+baroffs,3,barsize+(view_w)+baroffs,h,colors.lightGray)
  1091. end
  1092.  
  1093. function refreshScreen()
  1094.     if(term.current)then term.current().setVisible(false) end
  1095.     drawGUI()
  1096.     redrawData()
  1097.     drawSelectedByte()
  1098.     if(term.current)then term.current().setVisible(true) end
  1099. end
  1100.  
  1101. function update(ev)
  1102.     if(ev[1] == "mouse_scroll")then
  1103.         if(ev[2] == -1)then -- UP
  1104.             seek(-1)
  1105.         elseif(ev[2] == 1)then -- DOWN
  1106.             seek(1)
  1107.         end
  1108.     elseif(ev[1] == "key_up")then
  1109.         if(ev[2] == keys.leftCtrl)then funcKey = false end
  1110.     elseif(ev[1] == "key")then
  1111.         local key = ev[2]
  1112.         if(funcKey)then
  1113.             if(key == keys.a)then
  1114.                 hexedit_buttons[3].call()
  1115.                 funcKey = false
  1116.             elseif(key == keys.j)then
  1117.                 hexedit_dropdowns["address"][1].call()
  1118.                 funcKey = false
  1119.             elseif(key == keys.f)then
  1120.                 hexedit_buttons[4].call()
  1121.                 funcKey = false
  1122.             elseif(key == keys.x)then
  1123.                 local res = showBox("Exit HexIt?","Exit HexIt? \nThis will end your\nHexIt session.","yesno",21,10)
  1124.                 refreshScreen()
  1125.                 if(res == "yes")then
  1126.                     exitHexIt()
  1127.                 end
  1128.                 funcKey = false
  1129.             elseif(key == keys.n)then
  1130.                 hexedit_buttons[1].call()
  1131.                 funcKey = false
  1132.             elseif(key == keys.m)then
  1133.                 hexedit_dropdowns["edit"][3].call()
  1134.                 refreshScreen()
  1135.                 funcKey = false
  1136.             else
  1137.                 funcKey = false
  1138.             end
  1139.         elseif(key == keys.leftCtrl)then
  1140.             funcKey = true
  1141.         end
  1142.         if(key == keys.left)then
  1143.             moveSelectedByte(-1)   
  1144.         elseif(key == keys.right)then
  1145.             moveSelectedByte(1)
  1146.         elseif(key == keys.up)then
  1147.             moveSelectedByte(-_hexLineSize)
  1148.         elseif(key == keys.down)then
  1149.             moveSelectedByte(_hexLineSize)
  1150.         elseif(key == keys.pageUp)then
  1151.             seekPage(-1)
  1152.         elseif(key == keys.pageDown)then
  1153.             seekPage(1)
  1154.         elseif(key == keys.tab)then
  1155.             if(writeMode == "hex")then writeMode = "char" else writeMode = "hex" end
  1156.             refreshScreen()
  1157.             -- No hold.
  1158.             sleep(0.01)
  1159.         elseif(key == keys.delete)then
  1160.             if(_hexSelected > 0)then
  1161.                 _hexData = _hexData:sub(1,_hexSelected-1) .. _hexData:sub(_hexSelected+1,-1)
  1162.                 _hexSize = #_hexData
  1163.                 if(_hexSelected > _hexSize)then _hexSelected = _hexSize end
  1164.                 refreshScreen()
  1165.             end
  1166.         elseif(key == keys.backspace and writeMode == "char")then
  1167.             moveSelectedByte(-1)
  1168.         elseif(key == keys.enter and _hexEditMode == "return" )then
  1169.             if(_hexBuffer ~= "")then
  1170.                 if(writeMode == "hex")then
  1171.                     setByte(_hexSelected,_hexBuffer)
  1172.                 elseif(writeMode == "char")then
  1173.                     setChar(_hexSelected,_hexBuffer)
  1174.                 end
  1175.             else
  1176.                 if(writeMode == "hex")then
  1177.                     moveSelectedByte(1)
  1178.                 elseif(writeMode == "char")then
  1179.                     moveSelectedByte(1)
  1180.                 end
  1181.             end
  1182.         elseif(key == keys.f5)then
  1183.             -- Repeat search
  1184.             searchFile(_lastSearch.mode,_lastSearch.dir,_lastSearch.data)
  1185.         end
  1186.     elseif(ev[1] == "char")then
  1187.         local char = ev[2]
  1188.         if(writeMode == "hex")then
  1189.             if(char ~= "[" and char ~= "." and char ~= "/")then -- Special chars that string.find doesnt "like"
  1190.                 if(validHex:find(string.lower(char)))then
  1191.                     if(#_hexBuffer == 2 )then
  1192.                         if(_hexEditMode == "return")then
  1193.                             _hexBuffer = ""
  1194.                         end
  1195.                     end
  1196.                     _hexBuffer = _hexBuffer .. string.upper(char)
  1197.                     drawHexBuffer()
  1198.                     if(#_hexBuffer == 2 and _hexEditMode == "fill")then
  1199.                         setByte(_hexSelected,_hexBuffer)
  1200.                         _hexBuffer = ""
  1201.                     end
  1202.                 end
  1203.             end
  1204.         elseif(writeMode == "char")then
  1205.             if(#_hexBuffer == 1 )then
  1206.             -- Handles fill mode and for newline clears it.
  1207.                 if(_hexEditMode == "return")then
  1208.                     _hexBuffer = ""
  1209.                 end
  1210.             end
  1211.             _hexBuffer = _hexBuffer .. char
  1212.             drawHexBuffer()
  1213.             if(#_hexBuffer == 1 and _hexEditMode == "fill")then
  1214.                 setChar(_hexSelected,_hexBuffer)
  1215.                 _hexBuffer = ""
  1216.             end
  1217.         end
  1218.     elseif(ev[1] == "mouse_click" or ev[1] == "mouse_drag")then
  1219.         local mb, mx, my = ev[2], ev[3], ev[4]
  1220.         local memIndex = 0
  1221.         if(my == 1)then
  1222.             if(mx == w and my == 1)then exitHexIt() end
  1223.             for i = 1, #hexedit_menus do
  1224.                 if(mx >= hexedit_menus[i].x and mx <= hexedit_menus[i].x+#hexedit_menus[i].text)then
  1225.                     flashButton(colors.white,colors.blue,0.1,hexedit_menus[i].x,1,hexedit_menus[i].text,colors.white,colors.lightGray)
  1226.                     hexedit_menus[i].call()
  1227.                 end
  1228.             end
  1229.         elseif(my == 2)then
  1230.             for i = 1, #hexedit_buttons do
  1231.                 if(mx >= hexedit_buttons[i].x and mx <= hexedit_buttons[i].x+#hexedit_buttons[i].graphic)then
  1232.                     flashButton(colors.white,colors.blue,0.1,hexedit_buttons[i].x,2,hexedit_buttons[i].graphic,colors.white,colors.lightGray)
  1233.                     hexedit_buttons[i].call()
  1234.                 end
  1235.             end
  1236.         end
  1237.        
  1238.         if(mb == 1 and mx > barsize+2 and my > 2 and mx < view_w+barsize+2)then
  1239.             if( ((mx)-(barsize+2))%3 > 0)then
  1240.                 local newSelect = ((math.floor(mx/3)-1)+((my-3)*_hexLineSize)+_currentMemory)
  1241.                 if(getByte(newSelect) ~= nil)then
  1242.                     drawSelectedByte(1)
  1243.                     _hexSelected = newSelect
  1244.                     writeMode = "hex"
  1245.                     drawSelectedByte()
  1246.                 end
  1247.             end
  1248.         elseif(mb == 1 and mx >= view_w+barsize+1+baroffs and my > 2 and mx <= w)then
  1249.             local newSelect = (mx-(view_w+barsize+baroffs)+((my-3)*_hexLineSize)+_currentMemory)
  1250.             if(getByte(newSelect) ~= nil)then
  1251.                 drawSelectedByte(1)
  1252.                 _hexSelected = newSelect
  1253.                 writeMode = "char"
  1254.                 drawSelectedByte()
  1255.             end
  1256.         end
  1257.     end
  1258.  
  1259. end
  1260.  
  1261. local tArgs = { ... }
  1262. if(#tArgs == 0)then error("Ussage: " .. shell.resolveProgram(shell.getRunningProgram()) .. " <file>.") end
  1263.  
  1264. if(not fs.exists(tArgs[1]))then
  1265.     drawGUI()
  1266.     local size = tonumber(showBox("Welcome"," Enter size of \n new file. \n(in bytes)","input",21,10),16)
  1267.     if (size == nil or size <= 0 or size > tonumber("FFFFF",16)) then
  1268.         showBox("New File","Invalid file size.","key",21,9)
  1269.         refreshScreen()
  1270.         exitHexIt()
  1271.         return
  1272.     end
  1273.     newFile(tArgs[1],size)
  1274.     refreshScreen()
  1275. else
  1276.     showBox("File","Loading\n"..tArgs[1],"nomode",21,3)
  1277.     loadFile(tArgs[1])
  1278.     refreshScreen()
  1279. end
  1280.  
  1281. while running do
  1282.     local e = {os.pullEvent()}
  1283.     update(e)
  1284. end
RAW Paste Data