mat.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. package brlyt
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "strings"
  6. )
  7. type MAT struct {
  8. NumOfMats uint16
  9. _ uint16
  10. }
  11. type MATOffset struct {
  12. Offset uint32
  13. }
  14. type MATMaterials struct {
  15. Name [20]byte
  16. ForeColor [4]int16
  17. BackColor [4]int16
  18. ColorReg3 [4]int16
  19. TevColor1 [4]uint8
  20. TevColor2 [4]uint8
  21. TevColor3 [4]uint8
  22. TevColor4 [4]uint8
  23. BitFlag uint32
  24. }
  25. type MATTextureEntry struct {
  26. TexIndex uint16
  27. SWrap uint8
  28. TWrap uint8
  29. }
  30. type MATTextureSRTEntry struct {
  31. XTrans float32
  32. YTrans float32
  33. Rotation float32
  34. XScale float32
  35. YScale float32
  36. }
  37. type MATTexCoordGenEntry struct {
  38. Type uint8
  39. Source uint8
  40. MatrixSource uint8
  41. _ uint8
  42. }
  43. type MATChanControl struct {
  44. ColorMaterialSource uint8
  45. AlphaMaterialSource uint8
  46. _ uint8
  47. _ uint8
  48. }
  49. type MATColor struct {
  50. R uint8
  51. G uint8
  52. B uint8
  53. A uint8
  54. }
  55. type TevSwapModeTable struct {
  56. B1 uint8
  57. B2 uint8
  58. B3 uint8
  59. B4 uint8
  60. }
  61. type MATIndirectTextureOrderEntry struct {
  62. TexCoord uint8
  63. TexMap uint8
  64. ScaleS uint8
  65. ScaleT uint8
  66. }
  67. type MATTevStageEntry struct {
  68. TexCoor uint8
  69. Color uint8
  70. U16 uint16
  71. B1 uint8
  72. B2 uint8
  73. B3 uint8
  74. B4 uint8
  75. B5 uint8
  76. B6 uint8
  77. B7 uint8
  78. B8 uint8
  79. B9 uint8
  80. B10 uint8
  81. B11 uint8
  82. B12 uint8
  83. }
  84. type MatAlphaCompare struct {
  85. Temp uint8
  86. AlphaOP uint8
  87. Ref0 uint8
  88. Ref1 uint8
  89. }
  90. func (r *Root) ParseMAT(data []byte, sectionSize uint32) error {
  91. var mat MAT
  92. var materialOffsets []uint32
  93. var matEntries []MATEntries
  94. err := binary.Read(bytes.NewReader(data), binary.BigEndian, &mat)
  95. if err != nil {
  96. return err
  97. }
  98. for i := 0; i < int(mat.NumOfMats); i++ {
  99. var matOffset MATOffset
  100. offset := 4 + (i * 4)
  101. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &matOffset)
  102. if err != nil {
  103. return err
  104. }
  105. materialOffsets = append(materialOffsets, matOffset.Offset-8)
  106. // If we have reached the last index, append the section size to the slice.
  107. if i == int(mat.NumOfMats)-1 {
  108. materialOffsets = append(materialOffsets, sectionSize-8)
  109. }
  110. }
  111. // Now that we have the offsets, parse the mat section.
  112. for i := 0; i < int(mat.NumOfMats); i++ {
  113. var matMaterials MATMaterials
  114. err = binary.Read(bytes.NewReader(data[materialOffsets[i]:materialOffsets[i+1]]), binary.BigEndian, &matMaterials)
  115. if err != nil {
  116. return err
  117. }
  118. // Read the bitfield
  119. offset := materialOffsets[i] + 64
  120. textureEntries := make([]MATTexture, BitExtract(matMaterials.BitFlag, 28, 31))
  121. for i := 0; i < BitExtract(matMaterials.BitFlag, 28, 31); i++ {
  122. var texEntry MATTextureEntry
  123. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &texEntry)
  124. if err != nil {
  125. return err
  126. }
  127. xmlTexture := MATTexture{
  128. Name: "nil",
  129. SWrap: texEntry.SWrap,
  130. TWrap: texEntry.TWrap,
  131. }
  132. if r.TXL.TPLName != nil {
  133. xmlTexture.Name = r.TXL.TPLName[texEntry.TexIndex]
  134. }
  135. offset += 4
  136. textureEntries[i] = xmlTexture
  137. }
  138. textureSRTEntries := make([]MATSRT, BitExtract(matMaterials.BitFlag, 24, 27))
  139. for i := 0; i < BitExtract(matMaterials.BitFlag, 24, 27); i++ {
  140. var texSRTEntry MATTextureSRTEntry
  141. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &texSRTEntry)
  142. if err != nil {
  143. return err
  144. }
  145. xmlSRT := MATSRT{
  146. XTrans: texSRTEntry.XTrans,
  147. YTrans: texSRTEntry.YTrans,
  148. Rotation: texSRTEntry.Rotation,
  149. XScale: texSRTEntry.XScale,
  150. YScale: texSRTEntry.YScale,
  151. }
  152. offset += 20
  153. textureSRTEntries[i] = xmlSRT
  154. }
  155. texCoorGenEntries := make([]MATCoordGen, BitExtract(matMaterials.BitFlag, 20, 23))
  156. for i := 0; i < BitExtract(matMaterials.BitFlag, 20, 23); i++ {
  157. var texCoorGenEntry MATTexCoordGenEntry
  158. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &texCoorGenEntry)
  159. if err != nil {
  160. return err
  161. }
  162. xmlCoorGen := MATCoordGen{
  163. Type: texCoorGenEntry.Type,
  164. Source: texCoorGenEntry.Source,
  165. MatrixSource: texCoorGenEntry.MatrixSource,
  166. }
  167. offset += 4
  168. texCoorGenEntries[i] = xmlCoorGen
  169. }
  170. var chanControlXML *ChanControlXML
  171. if BitExtract(matMaterials.BitFlag, 6, 100) == 1 {
  172. var chanControl MATChanControl
  173. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &chanControl)
  174. if err != nil {
  175. return err
  176. }
  177. chanControlXML = &ChanControlXML{
  178. ColorMaterialSource: chanControl.ColorMaterialSource,
  179. AlphaMaterialSource: chanControl.ColorMaterialSource,
  180. }
  181. offset += 4
  182. }
  183. var matColorXML *Color8
  184. if BitExtract(matMaterials.BitFlag, 4, 100) == 1 {
  185. var matColor MATColor
  186. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &matColor)
  187. if err != nil {
  188. return err
  189. }
  190. matColorXML = &Color8{
  191. R: matColor.R,
  192. G: matColor.G,
  193. B: matColor.B,
  194. A: matColor.A,
  195. }
  196. offset += 4
  197. }
  198. var tevSwapModeTableXML *TevSwapModeTableXML
  199. if BitExtract(matMaterials.BitFlag, 19, 100) == 1 {
  200. var tevSwapModeTable TevSwapModeTable
  201. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &tevSwapModeTable)
  202. if err != nil {
  203. return err
  204. }
  205. tevSwapModeTableXML = &TevSwapModeTableXML{
  206. AR: (tevSwapModeTable.B1 >> 0) & 0x3,
  207. AG: (tevSwapModeTable.B1 >> 2) & 0x3,
  208. AB: (tevSwapModeTable.B1 >> 4) & 0x3,
  209. AA: (tevSwapModeTable.B1 >> 6) & 0x3,
  210. BR: (tevSwapModeTable.B2 >> 0) & 0x3,
  211. BG: (tevSwapModeTable.B2 >> 2) & 0x3,
  212. BB: (tevSwapModeTable.B2 >> 4) & 0x3,
  213. BA: (tevSwapModeTable.B2 >> 6) & 0x3,
  214. CR: (tevSwapModeTable.B3 >> 0) & 0x3,
  215. CG: (tevSwapModeTable.B3 >> 2) & 0x3,
  216. CB: (tevSwapModeTable.B3 >> 4) & 0x3,
  217. CA: (tevSwapModeTable.B3 >> 6) & 0x3,
  218. DR: (tevSwapModeTable.B4 >> 0) & 0x3,
  219. DG: (tevSwapModeTable.B4 >> 2) & 0x3,
  220. DB: (tevSwapModeTable.B4 >> 4) & 0x3,
  221. DA: (tevSwapModeTable.B4 >> 6) & 0x3,
  222. }
  223. offset += 4
  224. }
  225. indirectTextureSRTEntries := make([]MATSRT, BitExtract(matMaterials.BitFlag, 17, 18))
  226. for i := 0; i < BitExtract(matMaterials.BitFlag, 17, 18); i++ {
  227. var texSRTEntry MATTextureSRTEntry
  228. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &texSRTEntry)
  229. if err != nil {
  230. return err
  231. }
  232. xmlSRT := MATSRT{
  233. XTrans: texSRTEntry.XTrans,
  234. YTrans: texSRTEntry.YTrans,
  235. Rotation: texSRTEntry.Rotation,
  236. XScale: texSRTEntry.XScale,
  237. YScale: texSRTEntry.YScale,
  238. }
  239. offset += 20
  240. indirectTextureSRTEntries[i] = xmlSRT
  241. }
  242. indirectTextureOrderEntries := make([]MATIndirectOrderEntryXML, BitExtract(matMaterials.BitFlag, 14, 16))
  243. for i := 0; i < BitExtract(matMaterials.BitFlag, 14, 16); i++ {
  244. var texOrderEntry MATIndirectTextureOrderEntry
  245. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &texOrderEntry)
  246. if err != nil {
  247. return err
  248. }
  249. xmlEntry := MATIndirectOrderEntryXML{
  250. TexCoord: texOrderEntry.TexCoord,
  251. TexMap: texOrderEntry.TexMap,
  252. ScaleS: texOrderEntry.ScaleS,
  253. ScaleT: texOrderEntry.ScaleT,
  254. }
  255. offset += 4
  256. indirectTextureOrderEntries[i] = xmlEntry
  257. }
  258. tevStageEntries := make([]MATTevStageEntryXML, BitExtract(matMaterials.BitFlag, 9, 13))
  259. for i := 0; i < BitExtract(matMaterials.BitFlag, 9, 13); i++ {
  260. var temp MATTevStageEntry
  261. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &temp)
  262. if err != nil {
  263. return err
  264. }
  265. colorClamp := 0
  266. if temp.B4&0x1 == 1 {
  267. colorClamp = 1
  268. }
  269. alphaClamp := 0
  270. if temp.B8&0x1 == 1 {
  271. alphaClamp = 1
  272. }
  273. entry := MATTevStageEntryXML{
  274. TexCoor: temp.TexCoor,
  275. Color: temp.Color,
  276. TexMap: temp.U16 & 0x1ff,
  277. RasSel: uint8((temp.U16 & 0x7ff) >> 9),
  278. TexSel: uint8(temp.U16 >> 11),
  279. ColorA: temp.B1 & 0xf,
  280. ColorB: temp.B1 >> 4,
  281. ColorC: temp.B2 & 0xf,
  282. ColorD: temp.B2 >> 4,
  283. ColorOP: temp.B3 & 0xf,
  284. ColorBias: (temp.B3 & 0x3f) >> 4,
  285. ColorScale: temp.B3 >> 6,
  286. ColorClamp: uint8(colorClamp),
  287. ColorRegID: (temp.B4 & 0x7) >> 1,
  288. ColorConstantSel: temp.B4 >> 3,
  289. AlphaA: temp.B5 & 0xf,
  290. AlphaB: temp.B5 >> 4,
  291. AlphaC: temp.B6 & 0xf,
  292. AlphaD: temp.B6 >> 4,
  293. AlphaOP: temp.B7 & 0xf,
  294. AlphaBias: (temp.B7 & 0x3f) >> 4,
  295. AlphaScale: temp.B7 >> 6,
  296. AlphaClamp: uint8(alphaClamp),
  297. AlphaRegID: (temp.B8 & 0x7) >> 1,
  298. AlphaConstantSel: temp.B8 >> 3,
  299. TexID: temp.B9 & 0x3,
  300. Bias: temp.B10 & 0x7,
  301. Matrix: (temp.B10 & 0x7F) >> 3,
  302. WrapS: temp.B11 & 0x7,
  303. WrapT: (temp.B11 & 0x3F) >> 3,
  304. Format: temp.B12 & 0x3,
  305. AddPrevious: (temp.B12 & 0x7) >> 2,
  306. UTCLod: (temp.B12 & 0xF) >> 3,
  307. Alpha: (temp.B12 & 0x3F) >> 4,
  308. }
  309. tevStageEntries[i] = entry
  310. offset += 16
  311. }
  312. var alphaCompareXML *MATAlphaCompareXML
  313. if BitExtract(matMaterials.BitFlag, 8, 8) == 1 {
  314. var alphaCompare MatAlphaCompare
  315. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &alphaCompare)
  316. if err != nil {
  317. return err
  318. }
  319. alphaCompareXML = &MATAlphaCompareXML{
  320. Comp0: alphaCompare.Temp & 0x7,
  321. Comp1: (alphaCompare.Temp >> 4) & 0x7,
  322. AlphaOP: alphaCompare.AlphaOP,
  323. Ref0: alphaCompare.Ref0,
  324. Ref1: alphaCompare.Ref1,
  325. }
  326. offset += 4
  327. }
  328. var blendModeXML *MATBlendMode
  329. if BitExtract(matMaterials.BitFlag, 7, 7) == 1 {
  330. var blendMode MATBlendMode
  331. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &blendMode)
  332. if err != nil {
  333. return err
  334. }
  335. blendModeXML = &blendMode
  336. offset += 4
  337. }
  338. matName := string(matMaterials.Name[:])
  339. matName = strings.Replace(matName, "\x00", "", -1)
  340. xmlData := MATEntries{
  341. Name: matName,
  342. ForeColor: Color16{
  343. R: matMaterials.ForeColor[0],
  344. G: matMaterials.ForeColor[1],
  345. B: matMaterials.ForeColor[2],
  346. A: matMaterials.ForeColor[3],
  347. },
  348. BackColor: Color16{
  349. R: matMaterials.BackColor[0],
  350. G: matMaterials.BackColor[1],
  351. B: matMaterials.BackColor[2],
  352. A: matMaterials.BackColor[3],
  353. },
  354. ColorReg3: Color16{
  355. R: matMaterials.ColorReg3[0],
  356. G: matMaterials.ColorReg3[1],
  357. B: matMaterials.ColorReg3[2],
  358. A: matMaterials.ColorReg3[3],
  359. },
  360. TevColor1: Color8{
  361. R: matMaterials.TevColor1[0],
  362. G: matMaterials.TevColor1[1],
  363. B: matMaterials.TevColor1[2],
  364. A: matMaterials.TevColor1[3],
  365. },
  366. TevColor2: Color8{
  367. R: matMaterials.TevColor2[0],
  368. G: matMaterials.TevColor2[1],
  369. B: matMaterials.TevColor2[2],
  370. A: matMaterials.TevColor2[3],
  371. },
  372. TevColor3: Color8{
  373. R: matMaterials.TevColor3[0],
  374. G: matMaterials.TevColor3[1],
  375. B: matMaterials.TevColor3[2],
  376. A: matMaterials.TevColor3[3],
  377. },
  378. TevColor4: Color8{
  379. R: matMaterials.TevColor4[0],
  380. G: matMaterials.TevColor4[1],
  381. B: matMaterials.TevColor4[2],
  382. A: matMaterials.TevColor4[3],
  383. },
  384. BitFlag: matMaterials.BitFlag,
  385. Textures: textureEntries,
  386. SRT: textureSRTEntries,
  387. CoordGen: texCoorGenEntries,
  388. ChanControl: chanControlXML,
  389. MatColor: matColorXML,
  390. TevSwapMode: tevSwapModeTableXML,
  391. IndirectSRT: indirectTextureSRTEntries,
  392. IndirectTextureOrder: indirectTextureOrderEntries,
  393. TevStageEntry: tevStageEntries,
  394. AlphaCompare: alphaCompareXML,
  395. BlendMode: blendModeXML,
  396. }
  397. matEntries = append(matEntries, xmlData)
  398. }
  399. r.MAT = MATNode{Entries: matEntries}
  400. return nil
  401. }
  402. func (b *BRLYTWriter) WriteMAT(data Root) error {
  403. temp := bytes.NewBuffer(nil)
  404. header := SectionHeader{
  405. Type: SectionTypeMAT,
  406. Size: 0,
  407. }
  408. meta := MAT{NumOfMats: uint16(len(data.MAT.Entries))}
  409. offsets := make([]MATOffset, len(data.MAT.Entries))
  410. offsets[0].Offset = uint32(len(data.MAT.Entries)*4 + 12)
  411. count := 12 + (len(data.MAT.Entries) * 4)
  412. for i, entry := range data.MAT.Entries {
  413. if i != 0 {
  414. offsets[i].Offset = uint32(count)
  415. }
  416. var name [20]byte
  417. copy(name[:], entry.Name)
  418. material := MATMaterials{
  419. Name: name,
  420. ForeColor: [4]int16{entry.ForeColor.R, entry.ForeColor.G, entry.ForeColor.B, entry.ForeColor.A},
  421. BackColor: [4]int16{entry.BackColor.R, entry.BackColor.G, entry.BackColor.B, entry.BackColor.A},
  422. ColorReg3: [4]int16{entry.ColorReg3.R, entry.ColorReg3.G, entry.ColorReg3.B, entry.ColorReg3.A},
  423. TevColor1: [4]uint8{entry.TevColor1.R, entry.TevColor1.G, entry.TevColor1.B, entry.TevColor1.A},
  424. TevColor2: [4]uint8{entry.TevColor2.R, entry.TevColor2.G, entry.TevColor2.B, entry.TevColor2.A},
  425. TevColor3: [4]uint8{entry.TevColor3.R, entry.TevColor3.G, entry.TevColor3.B, entry.TevColor3.A},
  426. TevColor4: [4]uint8{entry.TevColor4.R, entry.TevColor4.G, entry.TevColor4.B, entry.TevColor4.A},
  427. BitFlag: entry.BitFlag,
  428. }
  429. err := write(temp, material)
  430. if err != nil {
  431. return err
  432. }
  433. count += 64
  434. for _, texture := range entry.Textures {
  435. for i2, s := range data.TXL.TPLName {
  436. if texture.Name == s {
  437. tex := MATTextureEntry{
  438. TexIndex: uint16(i2),
  439. SWrap: texture.SWrap,
  440. TWrap: texture.TWrap,
  441. }
  442. err = write(temp, tex)
  443. if err != nil {
  444. return err
  445. }
  446. count += 4
  447. }
  448. }
  449. }
  450. for _, srt := range entry.SRT {
  451. srtEntry := MATTextureSRTEntry{
  452. XTrans: srt.XTrans,
  453. YTrans: srt.YTrans,
  454. Rotation: srt.Rotation,
  455. XScale: srt.XScale,
  456. YScale: srt.YScale,
  457. }
  458. err = write(temp, srtEntry)
  459. if err != nil {
  460. return err
  461. }
  462. count += 20
  463. }
  464. for _, gen := range entry.CoordGen {
  465. coorEntry := MATTexCoordGenEntry{
  466. Type: gen.Type,
  467. Source: gen.Source,
  468. MatrixSource: gen.MatrixSource,
  469. }
  470. err = write(temp, coorEntry)
  471. if err != nil {
  472. return err
  473. }
  474. count += 4
  475. }
  476. if entry.ChanControl != nil {
  477. chanControl := MATChanControl{
  478. ColorMaterialSource: entry.ChanControl.ColorMaterialSource,
  479. AlphaMaterialSource: entry.ChanControl.AlphaMaterialSource,
  480. }
  481. err = write(temp, chanControl)
  482. if err != nil {
  483. return err
  484. }
  485. count += 4
  486. }
  487. if entry.MatColor != nil {
  488. matColor := MATColor{
  489. R: entry.MatColor.R,
  490. G: entry.MatColor.B,
  491. B: entry.MatColor.G,
  492. A: entry.MatColor.A,
  493. }
  494. err = write(temp, matColor)
  495. if err != nil {
  496. return err
  497. }
  498. count += 4
  499. }
  500. if entry.TevSwapMode != nil {
  501. var b1 uint8 = 0
  502. b1 |= (entry.TevSwapMode.AA & 0x3) << 6
  503. b1 |= (entry.TevSwapMode.AB & 0x3) << 4
  504. b1 |= (entry.TevSwapMode.AG & 0x3) << 2
  505. b1 |= (entry.TevSwapMode.AR & 0x3) << 0
  506. var b2 uint8 = 0
  507. b2 |= (entry.TevSwapMode.BA & 0x3) << 6
  508. b2 |= (entry.TevSwapMode.BB & 0x3) << 4
  509. b2 |= (entry.TevSwapMode.BG & 0x3) << 2
  510. b2 |= (entry.TevSwapMode.BR & 0x3) << 0
  511. var b3 uint8 = 0
  512. b3 |= (entry.TevSwapMode.CA & 0x3) << 6
  513. b3 |= (entry.TevSwapMode.CB & 0x3) << 4
  514. b3 |= (entry.TevSwapMode.CG & 0x3) << 2
  515. b3 |= (entry.TevSwapMode.CR & 0x3) << 0
  516. var b4 uint8 = 0
  517. b4 |= (entry.TevSwapMode.DA & 0x3) << 6
  518. b4 |= (entry.TevSwapMode.DB & 0x3) << 4
  519. b4 |= (entry.TevSwapMode.DG & 0x3) << 2
  520. b4 |= (entry.TevSwapMode.DR & 0x3) << 0
  521. tevSwap := TevSwapModeTable{
  522. B1: b1,
  523. B2: b2,
  524. B3: b3,
  525. B4: b4,
  526. }
  527. err = write(temp, tevSwap)
  528. if err != nil {
  529. return err
  530. }
  531. count += 4
  532. }
  533. for _, matsrt := range entry.IndirectSRT {
  534. srt := MATSRT{
  535. XTrans: matsrt.XTrans,
  536. YTrans: matsrt.YTrans,
  537. Rotation: matsrt.Rotation,
  538. XScale: matsrt.XScale,
  539. YScale: matsrt.YScale,
  540. }
  541. err = write(temp, srt)
  542. if err != nil {
  543. return err
  544. }
  545. count += 20
  546. }
  547. for _, tex := range entry.IndirectTextureOrder {
  548. indirectTex := MATIndirectTextureOrderEntry{
  549. TexCoord: tex.TexCoord,
  550. TexMap: tex.TexMap,
  551. ScaleS: tex.ScaleS,
  552. ScaleT: tex.ScaleT,
  553. }
  554. err = write(temp, indirectTex)
  555. if err != nil {
  556. return err
  557. }
  558. count += 4
  559. }
  560. for _, stageEntry := range entry.TevStageEntry {
  561. var U16 uint16 = 0
  562. U16 |= uint16(stageEntry.TexSel&0x3F) << 11
  563. U16 |= uint16(stageEntry.RasSel&0x7) << 9
  564. U16 |= (stageEntry.TexMap & 0x1ff) << 0
  565. var B1 uint8 = 0
  566. B1 |= (stageEntry.ColorB & 0xf) << 4
  567. B1 |= (stageEntry.ColorA & 0xf) << 0
  568. var B2 uint8 = 0
  569. B2 |= (stageEntry.ColorD & 0xf) << 4
  570. B2 |= (stageEntry.ColorC & 0xf) << 0
  571. var B3 uint8 = 0
  572. B3 |= (stageEntry.ColorScale & 0x3) << 6
  573. B3 |= (stageEntry.ColorBias & 0x3) << 4
  574. B3 |= (stageEntry.ColorOP & 0xf) << 0
  575. var B4 uint8 = 0
  576. B4 |= (stageEntry.ColorConstantSel & 0x1F) << 3
  577. B4 |= (stageEntry.ColorRegID & 0x7) << 1
  578. B4 |= (stageEntry.ColorClamp) << 0
  579. var B5 uint8 = 0
  580. B5 |= (stageEntry.AlphaB & 0xf) << 4
  581. B5 |= (stageEntry.AlphaA & 0xf) << 0
  582. var B6 uint8 = 0
  583. B6 |= (stageEntry.AlphaD & 0xf) << 4
  584. B6 |= (stageEntry.AlphaC & 0xf) << 0
  585. var B7 uint8 = 0
  586. B7 |= (stageEntry.AlphaScale & 0x3) << 6
  587. B7 |= (stageEntry.AlphaBias & 0x3) << 4
  588. B7 |= (stageEntry.AlphaOP & 0xf) << 0
  589. var B8 uint8 = 0
  590. B8 |= (stageEntry.AlphaConstantSel & 0x1F) << 3
  591. B8 |= (stageEntry.AlphaRegID & 0x7) << 1
  592. B8 |= (stageEntry.AlphaClamp) << 0
  593. var B10 uint8 = 0
  594. B10 |= (stageEntry.Matrix & 0x1F) << 3
  595. B10 |= (stageEntry.Bias & 0x7) << 0
  596. var B11 uint8 = 0
  597. B11 |= (stageEntry.WrapT & 0x7) << 3
  598. B11 |= (stageEntry.WrapS & 0x7) << 0
  599. var B12 uint8 = 0
  600. B12 |= (stageEntry.Alpha & 0xF) << 4
  601. B12 |= (stageEntry.UTCLod & 0x1) << 3
  602. B12 |= (stageEntry.AddPrevious & 0x1) << 2
  603. B12 |= (stageEntry.Format & 0x3) << 0
  604. entry := MATTevStageEntry{
  605. TexCoor: stageEntry.TexCoor,
  606. Color: stageEntry.Color,
  607. U16: U16,
  608. B1: B1,
  609. B2: B2,
  610. B3: B3,
  611. B4: B4,
  612. B5: B5,
  613. B6: B6,
  614. B7: B7,
  615. B8: B8,
  616. B9: stageEntry.TexID & 0x3,
  617. B10: B10,
  618. B11: B11,
  619. B12: B12,
  620. }
  621. err = write(temp, entry)
  622. if err != nil {
  623. return err
  624. }
  625. count += 16
  626. }
  627. if entry.AlphaCompare != nil {
  628. var tempValue uint8 = 0
  629. tempValue |= (entry.AlphaCompare.Comp1 & 0x7) << 4
  630. tempValue |= (entry.AlphaCompare.Comp0 & 0x7) << 0
  631. entry := MatAlphaCompare{
  632. Temp: tempValue,
  633. AlphaOP: entry.AlphaCompare.AlphaOP,
  634. Ref0: entry.AlphaCompare.Ref0,
  635. Ref1: entry.AlphaCompare.Ref1,
  636. }
  637. err = write(temp, entry)
  638. if err != nil {
  639. return err
  640. }
  641. count += 4
  642. }
  643. if entry.BlendMode != nil {
  644. err = write(temp, entry.BlendMode)
  645. if err != nil {
  646. return err
  647. }
  648. count += 4
  649. }
  650. }
  651. header.Size = uint32(count)
  652. err := write(b, header)
  653. if err != nil {
  654. return err
  655. }
  656. err = write(b, meta)
  657. if err != nil {
  658. return err
  659. }
  660. err = write(b, offsets)
  661. if err != nil {
  662. return err
  663. }
  664. return write(b, temp.Bytes())
  665. }
  666. func BitExtract(num uint32, start int, end int) int {
  667. if end == 100 {
  668. end = start
  669. }
  670. firstMask := 1
  671. for first := 0; first < 31-start+1; first++ {
  672. firstMask *= 2
  673. }
  674. firstMask -= 1
  675. secondMask := 1
  676. for first := 0; first < 31-end; first++ {
  677. secondMask *= 2
  678. }
  679. secondMask -= 1
  680. mask := firstMask - secondMask
  681. return (int(num) & mask) >> (31 - end)
  682. }