Advertisement
FluttyProger

playe.lua

Mar 12th, 2017
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.61 KB | None | 0 0
  1. local image = require("image")
  2. --local buffer = require("doubleBuffering")
  3. local bit32 = require("bit32")
  4.  
  5. local args={...}
  6.  
  7. local constants = {
  8. OCIFSignature = "OCIF",
  9. OCIF2Elements = {
  10. alphaStart = "A",
  11. symbolStart = "S",
  12. backgroundStart = "B",
  13. foregroundStart = "F",
  14. },
  15. elementCount = 4,
  16. byteSize = 8,
  17. nullChar = 0,
  18. rawImageLoadStep = 19,
  19. compressedFileFormat = ".pic",
  20. pngFileFormat = ".png",
  21. }
  22.  
  23. local palette = {
  24. 0x000000, 0x000040, 0x000080, 0x0000BF, 0x0000FF, 0x002400, 0x002440, 0x002480, 0x0024BF, 0x0024FF, 0x004900, 0x004940, 0x004980, 0x0049BF, 0x0049FF, 0x006D00,
  25. 0x006D40, 0x006D80, 0x006DBF, 0x006DFF, 0x009200, 0x009240, 0x009280, 0x0092BF, 0x0092FF, 0x00B600, 0x00B640, 0x00B680, 0x00B6BF, 0x00B6FF, 0x00DB00, 0x00DB40,
  26. 0x00DB80, 0x00DBBF, 0x00DBFF, 0x00FF00, 0x00FF40, 0x00FF80, 0x00FFBF, 0x00FFFF, 0x0F0F0F, 0x1E1E1E, 0x2D2D2D, 0x330000, 0x330040, 0x330080, 0x3300BF, 0x3300FF,
  27. 0x332400, 0x332440, 0x332480, 0x3324BF, 0x3324FF, 0x334900, 0x334940, 0x334980, 0x3349BF, 0x3349FF, 0x336D00, 0x336D40, 0x336D80, 0x336DBF, 0x336DFF, 0x339200,
  28. 0x339240, 0x339280, 0x3392BF, 0x3392FF, 0x33B600, 0x33B640, 0x33B680, 0x33B6BF, 0x33B6FF, 0x33DB00, 0x33DB40, 0x33DB80, 0x33DBBF, 0x33DBFF, 0x33FF00, 0x33FF40,
  29. 0x33FF80, 0x33FFBF, 0x33FFFF, 0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x660000, 0x660040, 0x660080, 0x6600BF, 0x6600FF, 0x662400, 0x662440, 0x662480, 0x6624BF, 0x6624FF,
  30. 0x664900, 0x664940, 0x664980, 0x6649BF, 0x6649FF, 0x666D00, 0x666D40, 0x666D80, 0x666DBF, 0x666DFF, 0x669200, 0x669240, 0x669280, 0x6692BF, 0x6692FF, 0x66B600,
  31. 0x66B640, 0x66B680, 0x66B6BF, 0x66B6FF, 0x66DB00, 0x66DB40, 0x66DB80, 0x66DBBF, 0x66DBFF, 0x66FF00, 0x66FF40, 0x66FF80, 0x66FFBF, 0x66FFFF, 0x696969, 0x787878,
  32. 0x878787, 0x969696, 0x990000, 0x990040, 0x990080, 0x9900BF, 0x9900FF, 0x992400, 0x992440, 0x992480, 0x9924BF, 0x9924FF, 0x994900, 0x994940, 0x994980, 0x9949BF,
  33. 0x9949FF, 0x996D00, 0x996D40, 0x996D80, 0x996DBF, 0x996DFF, 0x999200, 0x999240, 0x999280, 0x9992BF, 0x9992FF, 0x99B600, 0x99B640, 0x99B680, 0x99B6BF, 0x99B6FF,
  34. 0x99DB00, 0x99DB40, 0x99DB80, 0x99DBBF, 0x99DBFF, 0x99FF00, 0x99FF40, 0x99FF80, 0x99FFBF, 0x99FFFF, 0xA5A5A5, 0xB4B4B4, 0xC3C3C3, 0xCC0000, 0xCC0040, 0xCC0080,
  35. 0xCC00BF, 0xCC00FF, 0xCC2400, 0xCC2440, 0xCC2480, 0xCC24BF, 0xCC24FF, 0xCC4900, 0xCC4940, 0xCC4980, 0xCC49BF, 0xCC49FF, 0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DBF,
  36. 0xCC6DFF, 0xCC9200, 0xCC9240, 0xCC9280, 0xCC92BF, 0xCC92FF, 0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6BF, 0xCCB6FF, 0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBBF, 0xCCDBFF,
  37. 0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFBF, 0xCCFFFF, 0xD2D2D2, 0xE1E1E1, 0xF0F0F0, 0xFF0000, 0xFF0040, 0xFF0080, 0xFF00BF, 0xFF00FF, 0xFF2400, 0xFF2440, 0xFF2480,
  38. 0xFF24BF, 0xFF24FF, 0xFF4900, 0xFF4940, 0xFF4980, 0xFF49BF, 0xFF49FF, 0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DBF, 0xFF6DFF, 0xFF9200, 0xFF9240, 0xFF9280, 0xFF92BF,
  39. 0xFF92FF, 0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6BF, 0xFFB6FF, 0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBBF, 0xFFDBFF, 0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFBF, 0xFFFFFF,
  40. }
  41.  
  42. function HEXtoRGB(color)
  43. return bit32.rshift(color, 16), bit32.band(bit32.rshift(color, 8), 0xFF), bit32.band(color, 0xFF)
  44. end
  45.  
  46. function RGBtoHEX(rr, gg, bb)
  47. return bit32.lshift(rr, 16) + bit32.lshift(gg, 8) + bb
  48. end
  49.  
  50. local function mergeBytesToNumber(...)
  51. local bytes = {...}
  52. local finalNumber = bytes[1]
  53. for i = 2, #bytes do
  54. finalNumber = bit32.bor(bit32.lshift(finalNumber, 8), bytes[i])
  55. end
  56. return finalNumber
  57. end
  58.  
  59. -- Сконвертировать все переданные байты в строку
  60. local function convertBytesToString(...)
  61. local bytes = {...}
  62. for i = 1, #bytes do
  63. bytes[i] = string.char(bytes[i])
  64. end
  65. return table.concat(bytes)
  66. end
  67.  
  68. --Выделить бит-терминатор в первом байте UTF-8 символа: 1100 0010 --> 0010 0000
  69. local function selectTerminateBit_l()
  70. local prevByte = nil
  71. local prevTerminateBit = nil
  72.  
  73. return function( byte )
  74. local x, terminateBit = nil
  75. if ( prevByte == byte ) then
  76. return prevTerminateBit
  77. end
  78.  
  79. x = bit32.band( bit32.bnot(byte), 0x000000FF )
  80. x = bit32.bor( x, bit32.rshift(x, 1) )
  81. x = bit32.bor( x, bit32.rshift(x, 2) )
  82. x = bit32.bor( x, bit32.rshift(x, 4) )
  83. x = bit32.bor( x, bit32.rshift(x, 8) )
  84. x = bit32.bor( x, bit32.rshift(x, 16) )
  85.  
  86. terminateBit = x - bit32.rshift(x, 1)
  87.  
  88. prevByte = byte
  89. prevTerminateBit = terminateBit
  90.  
  91. return terminateBit
  92. end
  93. end
  94. local selectTerminateBit = selectTerminateBit_l()
  95.  
  96. --Прочитать n байтов из файла, возвращает прочитанные байты как число, если не удалось прочитать, то возвращает 0
  97. local function readBytes(file, count)
  98. local readedBytes = file:read(count)
  99. return mergeBytesToNumber(string.byte(readedBytes, 1, count))
  100. end
  101.  
  102. --Подготавливает цвета и символ для записи в файл сжатого формата
  103. local function encodePixel(background, foreground, alpha, char)
  104. --Расхерачиваем жирные цвета в компактные цвета
  105. local ascii_background1, ascii_background2, ascii_background3 = HEXtoRGB(background)
  106. local ascii_foreground1, ascii_foreground2, ascii_foreground3 = HEXtoRGB(foreground)
  107. --Расхерачиваем жирный код юникод-символа в несколько миленьких ascii-кодов
  108. local ascii_char1, ascii_char2, ascii_char3, ascii_char4, ascii_char5, ascii_char6 = string.byte( char, 1, 6 )
  109. ascii_char1 = ascii_char1 or constants.nullChar
  110. --Возвращаем все расхераченное
  111. return ascii_background1, ascii_background2, ascii_background3, ascii_foreground1, ascii_foreground2, ascii_foreground3, alpha, ascii_char1, ascii_char2, ascii_char3, ascii_char4, ascii_char5, ascii_char6
  112. end
  113.  
  114. --Декодирование UTF-8 символа
  115. local function decodeChar(file)
  116. local first_byte = readBytes(file, 1)
  117. local charcode_array = {first_byte}
  118. local len = 1
  119.  
  120. local middle = selectTerminateBit(first_byte)
  121. if ( middle == 32 ) then
  122. len = 2
  123. elseif ( middle == 16 ) then
  124. len = 3
  125. elseif ( middle == 8 ) then
  126. len = 4
  127. elseif ( middle == 4 ) then
  128. len = 5
  129. elseif ( middle == 2 ) then
  130. len = 6
  131. end
  132.  
  133. for i = 1, len-1 do
  134. table.insert( charcode_array, readBytes(file, 1) )
  135. end
  136.  
  137. return string.char( table.unpack( charcode_array ) )
  138. end
  139.  
  140. local function convert8BitTo24Bit(hex8)
  141. return palette[hex8 + 1]
  142. end
  143.  
  144. local function convertCoordsToIndex(x, y, width)
  145. return (width * (y - 1) + x) * constants.elementCount - constants.elementCount + 1
  146. end
  147.  
  148. local function loadOCIF2(file, decompressColors, useOCIF4)
  149. local picture = {}
  150.  
  151. --Читаем размер изображения
  152. local readedWidth = string.byte(file:read(1))
  153. local readedHeight = string.byte(file:read(1))
  154. --local readednum = string.byte(file:read(1))
  155. picture.width = readedWidth
  156. picture.height = readedHeight
  157. --picture.num = readednum
  158.  
  159. local header, alpha, symbol, foreground, background, y, alphaSize, symbolSize, foregroundSize, backgroundSize, ySize = ""
  160. while true do
  161. header = file:read(1)
  162. if not header or header == "C" then break end
  163. -- print("----------------------")
  164. -- print("Заголовок: " .. header)
  165. if header == "A" then
  166. local countOfBytesForArraySize = string.byte(file:read(1))
  167. alphaSize = string.byte(file:read(countOfBytesForArraySize))
  168. alpha = string.byte(file:read(1))
  169. -- print("Количество байт под размер массива символов: " .. countOfBytesForArraySize)
  170. -- print("Размер массива символов: " .. alphaSize)
  171. -- print("Альфа: " .. alpha)
  172.  
  173. elseif header == "S" then
  174. if decompressColors then
  175. symbolSize = string.byte(file:read(1))
  176. else
  177. symbolSize = mergeBytesToNumber(string.byte(file:read(3), 1, 3))
  178. end
  179. symbol = decodeChar(file)
  180. -- print("Размер массива цвета текста: " .. symbolSize)
  181. -- print("Символ: \"" .. symbol .. "\"")
  182.  
  183. elseif header == "F" then
  184. if decompressColors then
  185. foregroundSize = string.byte(file:read(1))
  186. foreground = convert8BitTo24Bit(string.byte(file:read(1)))
  187. else
  188. foregroundSize = mergeBytesToNumber(string.byte(file:read(3), 1, 3))
  189. foreground = mergeBytesToNumber(string.byte(file:read(3), 1, 3))
  190. end
  191. -- print("Размер массива цвета фона: " .. foregroundSize)
  192. -- print("Цвет текста: " .. foreground)
  193.  
  194. elseif header == "B" then
  195. backgroundSize = mergeBytesToNumber(string.byte(file:read(2), 1, 2))
  196. if decompressColors then
  197. background = convert8BitTo24Bit(string.byte(file:read(1)))
  198. else
  199. background = mergeBytesToNumber(string.byte(file:read(3), 1, 3))
  200. end
  201. -- print("Размер массива координат: " .. backgroundSize)
  202. -- print("Цвет фона: " .. background)
  203.  
  204. --Поддержка загрузки формата OCIF3
  205. if not useOCIF4 then
  206. --Читаем координаты
  207. for i = 1, backgroundSize, 2 do
  208. local x = string.byte(file:read(1))
  209. local y = string.byte(file:read(1))
  210. local index = convertCoordsToIndex(x, y, readedWidth)
  211. -- print("Координата: " .. x .. "x" .. y .. ", индекс: "..index)
  212.  
  213. picture[index] = background
  214. picture[index + 1] = foreground
  215. picture[index + 2] = alpha
  216. picture[index + 3] = symbol
  217. end
  218. end
  219.  
  220. --Новый формат OCIF4
  221. elseif header == "Y" and useOCIF4 then
  222. ySize = string.byte(file:read(1))
  223. y = string.byte(file:read(1))
  224. -- print("Размер массива Y: " .. ySize)
  225. -- print("Текущий Y: " .. y)
  226.  
  227. for i = 1, ySize do
  228. local x = string.byte(file:read(1))
  229. local index = convertCoordsToIndex(x, y, readedWidth)
  230. -- print("Координата: " .. x .. "x" .. y .. ", индекс: "..index)
  231.  
  232. picture[index] = background
  233. picture[index + 1] = foreground
  234. picture[index + 2] = alpha
  235. picture[index + 3] = symbol
  236. end
  237. else
  238. error("Error while reading OCIFM format: unknown Header type (" .. header .. ")")
  239. end
  240. end
  241. return picture
  242. end
  243.  
  244. local file = io.open(args[1],"rb")
  245. --buffer.start()
  246. if file:read(5) ~= "OCIFM" then
  247. error("ЭТОТ ФОРМАТ НЕ ПОДДЕРЖИВАЕТСЯ!!!")
  248. end
  249.  
  250. while true do
  251. local chto=file:read(1)
  252. if chto == "O" then
  253. local imgdata=loadOCIF2(file, true, true)
  254. local arrnum = {1,14,27,40}
  255. image.draw(1, 1, imgdata)
  256. --buffer.image(1,arrnum[imgdata.num],imgdata)
  257. --buffer.draw()
  258. os.sleep(0)
  259. elseif not chto then
  260. break
  261. end
  262. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement