Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.44 KB | None | 0 0
  1. import struct
  2. import os
  3.  
  4.  
  5. header = None
  6. supported_versions = [0xA, 0xB]
  7.  
  8.  
  9. class Header:
  10. def __init__(self, endianness='<'):
  11. self.format = '3I4xI'
  12. self.endianness = endianness
  13.  
  14. self.magic = 0x53484141 # SHAA
  15. self.version = 0xB
  16. self.fileSize = 0
  17. self.name = ''
  18.  
  19. def load(self, data, pos=0):
  20. (self.magic,
  21. self.version,
  22. self.fileSize,
  23. nameLen) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  24.  
  25. assert self.magic == 0x53484141
  26.  
  27. self.name = data[pos + 0x14:pos + 0x14 + nameLen].decode('utf-8').rstrip('\0')
  28. self.size = 0x14 + nameLen
  29.  
  30. assert self.version in supported_versions
  31.  
  32.  
  33. class ShaderProgram:
  34. class VariationMacro:
  35. def __init__(self, endianness='<'):
  36. self.format = '3I'
  37. self.endianness = endianness
  38.  
  39. self.size = 0
  40. self.name = ''
  41. self.value =''
  42.  
  43. def __str__(self):
  44. return 'Variation Macro'
  45.  
  46. def load(self, data, pos):
  47. (self.size,
  48. nameLen,
  49. valueLen) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  50.  
  51. pos += struct.calcsize(self.format)
  52. self.name = data[pos:pos + nameLen].decode('utf-8').rstrip('\0')
  53.  
  54. pos += nameLen
  55. self.value = data[pos:pos + valueLen].decode('utf-8').rstrip('\0')
  56.  
  57. class VariationSymbol:
  58. def __init__(self, endianness='<'):
  59. self.format = '4I'
  60. self.endianness = endianness
  61.  
  62. self.size = 0
  63.  
  64. def __str__(self):
  65. return 'Variation Symbol'
  66.  
  67. def load(self, data, pos):
  68. (self.size,
  69. _4,
  70. _8,
  71. _C) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  72.  
  73. assert self.size == 8 # Structure is incomplete
  74.  
  75. class ShaderSymbol:
  76. class Variable:
  77. def __init__(self, name='', default=b'', maxLen=-1):
  78. self.name = name
  79. self.default = default
  80. self.maxLen = maxLen
  81.  
  82. def __init__(self, endianness='<'):
  83. self.format = 'Ii4I'
  84. self.endianness = endianness
  85.  
  86. self.size = 0
  87.  
  88. self.name = ''
  89. self.variable = ShaderProgram.ShaderSymbol.Variable()
  90. self.variationFlags = []
  91.  
  92. def __str__(self):
  93. return 'Variation Symbol'
  94.  
  95. def load(self, data, pos):
  96. pos_ = pos
  97. (self.size,
  98. self.variable.maxLen,
  99. variableNameLen,
  100. nameLen,
  101. defaultValueLen,
  102. variationCount) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  103.  
  104. pos += struct.calcsize(self.format)
  105. self.variable.name = data[pos:pos + variableNameLen].decode('utf-8').rstrip('\0')
  106.  
  107. pos += variableNameLen
  108. self.name = data[pos:pos + nameLen].decode('utf-8').rstrip('\0')
  109.  
  110. pos += nameLen
  111. self.variable.default = data[pos:pos + defaultValueLen]
  112.  
  113. pos += defaultValueLen
  114. for _ in range(variationCount):
  115. self.variationFlags.append(bool(data[pos])); pos += 1
  116.  
  117. def __init__(self, endianness='<'):
  118. self.format = '2I3i'
  119. self.endianness = endianness
  120.  
  121. self.size = 0
  122. self.vtxShIdx = -1
  123. self.frgShIdx = -1
  124. self.geoShIdx = -1
  125.  
  126. self.vertexVariations = List(self.endianness)
  127. self.fragmentVariations = List(self.endianness)
  128. self.geometryVariations = List(self.endianness)
  129.  
  130. self.variationSymbols = List(self.endianness)
  131. self.variationSymbols2 = List(self.endianness)
  132.  
  133. self.uniformVariables = List(self.endianness)
  134. self.uniformBlocks = List(self.endianness)
  135. self.samplerVariables = List(self.endianness)
  136. self.attribVariables = List(self.endianness)
  137.  
  138. self.name = ''
  139.  
  140. def __str__(self):
  141. return 'Shader Program'
  142.  
  143. def load(self, data, pos):
  144. (self.size,
  145. nameLen,
  146. self.vtxShIdx,
  147. self.frgShIdx,
  148. self.geoShIdx) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  149.  
  150. pos += struct.calcsize(self.format)
  151. self.name = data[pos:pos + nameLen].decode('utf-8').rstrip('\0')
  152.  
  153. pos += nameLen
  154. self.vertexVariations.load(data, pos, ShaderProgram.VariationMacro)
  155.  
  156. pos += self.vertexVariations.size
  157. self.fragmentVariations.load(data, pos, ShaderProgram.VariationMacro)
  158.  
  159. pos += self.fragmentVariations.size
  160. self.geometryVariations.load(data, pos, ShaderProgram.VariationMacro)
  161.  
  162. pos += self.geometryVariations.size
  163. self.variationSymbols.load(data, pos, ShaderProgram.VariationSymbol)
  164. pos += self.variationSymbols.size
  165.  
  166. if header.version == 11:
  167. self.variationSymbols2.load(data, pos, ShaderProgram.VariationSymbol)
  168. pos += self.variationSymbols2.size
  169.  
  170. self.uniformVariables.load(data, pos, ShaderProgram.ShaderSymbol)
  171.  
  172. pos += self.uniformVariables.size
  173. self.uniformBlocks.load(data, pos, ShaderProgram.ShaderSymbol)
  174.  
  175. pos += self.uniformBlocks.size
  176. self.samplerVariables.load(data, pos, ShaderProgram.ShaderSymbol)
  177.  
  178. pos += self.samplerVariables.size
  179. self.attribVariables.load(data, pos, ShaderProgram.ShaderSymbol)
  180.  
  181.  
  182. class ShaderCode:
  183. def __init__(self, endianness='<'):
  184. self.format = '4I'
  185. self.endianness = endianness
  186.  
  187. self.size = 0
  188. self.name = ''
  189. self.code = ''
  190.  
  191. def __str__(self):
  192. return 'Shader Code'
  193.  
  194. def load(self, data, pos):
  195. (self.size,
  196. nameLen,
  197. codeLen,
  198. codeLen2) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  199.  
  200. pos += struct.calcsize(self.format)
  201. self.name = data[pos:pos + nameLen].decode('utf-8').rstrip('\0')
  202.  
  203. pos += nameLen; assert codeLen == codeLen2
  204. self.code = data[pos:pos + codeLen].decode('shift-jis')
  205.  
  206. #with open(self.name, 'wb+') as out:
  207. # out.write(self.code.encode('utf-8'))
  208.  
  209.  
  210. class List:
  211. def __init__(self, endianness='<'):
  212. self.format = '2I'
  213. self.endianness = endianness
  214.  
  215. self.size = 0
  216. self.count = 0
  217. self.items = []
  218.  
  219. def __getitem__(self, i):
  220. if not isinstance(i, int):
  221. raise TypeError("index must be an integer")
  222.  
  223. return self.items[i]
  224.  
  225. def append(self, item):
  226. self.items.append(item)
  227.  
  228. def extend(self, itemList):
  229. self.items.extend(itemList)
  230.  
  231. def index(self, item):
  232. for i, oItem in enumerate(self.items):
  233. if item == oItem:
  234. return i
  235.  
  236. return -1
  237.  
  238. def load(self, data, pos, ItemClass=None):
  239. (self.size,
  240. self.count) = struct.unpack_from('%s%s' % (self.endianness, self.format), data, pos)
  241.  
  242. pos += struct.calcsize(self.format)
  243. if ItemClass:
  244. for _ in range(self.count):
  245. item = ItemClass(self.endianness)
  246. item.load(data, pos)
  247.  
  248. pos += item.size
  249. self.append(item)
  250.  
  251.  
  252. def load(inb, pos=0):
  253. global header
  254. header = Header()
  255. header.load(inb, pos)
  256.  
  257. pos += header.size
  258.  
  259. progList = List()
  260. progList.load(inb, pos, ShaderProgram)
  261.  
  262. pos += progList.size
  263.  
  264. codeList = List()
  265. codeList.load(inb, pos, ShaderCode)
  266.  
  267. pos += codeList.size
  268.  
  269. return progList, codeList
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement