mat.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. package main
  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) {
  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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. panic(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. }
  401. func (b *BRLYTWriter) WriteMAT(data Root) {
  402. temp := bytes.NewBuffer(nil)
  403. header := SectionHeader{
  404. Type: SectionTypeMAT,
  405. Size: 0,
  406. }
  407. meta := MAT{NumOfMats: uint16(len(data.MAT.Entries))}
  408. offsets := make([]MATOffset, len(data.MAT.Entries))
  409. offsets[0].Offset = uint32(len(data.MAT.Entries)*4 + 12)
  410. count := 12 + (len(data.MAT.Entries) * 4)
  411. for i, entry := range data.MAT.Entries {
  412. if i != 0 {
  413. offsets[i].Offset = uint32(count)
  414. }
  415. var name [20]byte
  416. copy(name[:], entry.Name)
  417. material := MATMaterials{
  418. Name: name,
  419. ForeColor: [4]int16{entry.ForeColor.R, entry.ForeColor.G, entry.ForeColor.B, entry.ForeColor.A},
  420. BackColor: [4]int16{entry.BackColor.R, entry.BackColor.G, entry.BackColor.B, entry.BackColor.A},
  421. ColorReg3: [4]int16{entry.ColorReg3.R, entry.ColorReg3.G, entry.ColorReg3.B, entry.ColorReg3.A},
  422. TevColor1: [4]uint8{entry.TevColor1.R, entry.TevColor1.G, entry.TevColor1.B, entry.TevColor1.A},
  423. TevColor2: [4]uint8{entry.TevColor2.R, entry.TevColor2.G, entry.TevColor2.B, entry.TevColor2.A},
  424. TevColor3: [4]uint8{entry.TevColor3.R, entry.TevColor3.G, entry.TevColor3.B, entry.TevColor3.A},
  425. TevColor4: [4]uint8{entry.TevColor4.R, entry.TevColor4.G, entry.TevColor4.B, entry.TevColor4.A},
  426. BitFlag: entry.BitFlag,
  427. }
  428. write(temp, material)
  429. count += 64
  430. for _, texture := range entry.Textures {
  431. for i2, s := range data.TXL.TPLName {
  432. if texture.Name == s {
  433. tex := MATTextureEntry{
  434. TexIndex: uint16(i2),
  435. SWrap: texture.SWrap,
  436. TWrap: texture.TWrap,
  437. }
  438. write(temp, tex)
  439. count += 4
  440. }
  441. }
  442. }
  443. for _, srt := range entry.SRT {
  444. srtEntry := MATTextureSRTEntry{
  445. XTrans: srt.XTrans,
  446. YTrans: srt.YTrans,
  447. Rotation: srt.Rotation,
  448. XScale: srt.XScale,
  449. YScale: srt.YScale,
  450. }
  451. write(temp, srtEntry)
  452. count += 20
  453. }
  454. for _, gen := range entry.CoordGen {
  455. coorEntry := MATTexCoordGenEntry{
  456. Type: gen.Type,
  457. Source: gen.Source,
  458. MatrixSource: gen.MatrixSource,
  459. }
  460. write(temp, coorEntry)
  461. count += 4
  462. }
  463. if entry.ChanControl != nil {
  464. chanControl := MATChanControl{
  465. ColorMaterialSource: entry.ChanControl.ColorMaterialSource,
  466. AlphaMaterialSource: entry.ChanControl.AlphaMaterialSource,
  467. }
  468. write(temp, chanControl)
  469. count += 4
  470. }
  471. if entry.MatColor != nil {
  472. matColor := MATColor{
  473. R: entry.MatColor.R,
  474. G: entry.MatColor.B,
  475. B: entry.MatColor.G,
  476. A: entry.MatColor.A,
  477. }
  478. write(temp, matColor)
  479. count += 4
  480. }
  481. if entry.TevSwapMode != nil {
  482. var b1 uint8 = 0
  483. b1 |= (entry.TevSwapMode.AA & 0x3) << 6
  484. b1 |= (entry.TevSwapMode.AB & 0x3) << 4
  485. b1 |= (entry.TevSwapMode.AG & 0x3) << 2
  486. b1 |= (entry.TevSwapMode.AR & 0x3) << 0
  487. var b2 uint8 = 0
  488. b2 |= (entry.TevSwapMode.BA & 0x3) << 6
  489. b2 |= (entry.TevSwapMode.BB & 0x3) << 4
  490. b2 |= (entry.TevSwapMode.BG & 0x3) << 2
  491. b2 |= (entry.TevSwapMode.BR & 0x3) << 0
  492. var b3 uint8 = 0
  493. b3 |= (entry.TevSwapMode.CA & 0x3) << 6
  494. b3 |= (entry.TevSwapMode.CB & 0x3) << 4
  495. b3 |= (entry.TevSwapMode.CG & 0x3) << 2
  496. b3 |= (entry.TevSwapMode.CR & 0x3) << 0
  497. var b4 uint8 = 0
  498. b4 |= (entry.TevSwapMode.DA & 0x3) << 6
  499. b4 |= (entry.TevSwapMode.DB & 0x3) << 4
  500. b4 |= (entry.TevSwapMode.DG & 0x3) << 2
  501. b4 |= (entry.TevSwapMode.DR & 0x3) << 0
  502. tevSwap := TevSwapModeTable{
  503. B1: b1,
  504. B2: b2,
  505. B3: b3,
  506. B4: b4,
  507. }
  508. write(temp, tevSwap)
  509. count += 4
  510. }
  511. for _, matsrt := range entry.IndirectSRT {
  512. srt := MATSRT{
  513. XTrans: matsrt.XTrans,
  514. YTrans: matsrt.YTrans,
  515. Rotation: matsrt.Rotation,
  516. XScale: matsrt.XScale,
  517. YScale: matsrt.YScale,
  518. }
  519. write(temp, srt)
  520. count += 20
  521. }
  522. for _, tex := range entry.IndirectTextureOrder {
  523. indirectTex := MATIndirectTextureOrderEntry{
  524. TexCoord: tex.TexCoord,
  525. TexMap: tex.TexMap,
  526. ScaleS: tex.ScaleS,
  527. ScaleT: tex.ScaleT,
  528. }
  529. write(temp, indirectTex)
  530. count += 4
  531. }
  532. for _, stageEntry := range entry.TevStageEntry {
  533. var U16 uint16 = 0
  534. U16 |= uint16((stageEntry.TexSel & 0x3F) << 11)
  535. U16 |= uint16((stageEntry.RasSel & 0x7) << 9)
  536. U16 |= (stageEntry.TexMap & 0x1ff) << 0
  537. var B1 uint8 = 0
  538. B1 |= (stageEntry.ColorB & 0xf) << 4
  539. B1 |= (stageEntry.ColorA & 0xf) << 0
  540. var B2 uint8 = 0
  541. B2 |= (stageEntry.ColorD & 0xf) << 4
  542. B2 |= (stageEntry.ColorC & 0xf) << 0
  543. var B3 uint8 = 0
  544. B3 |= (stageEntry.ColorScale & 0x3) << 6
  545. B3 |= (stageEntry.ColorBias & 0x3) << 4
  546. B3 |= (stageEntry.ColorOP & 0xf) << 0
  547. var B4 uint8 = 0
  548. B4 |= (stageEntry.ColorConstantSel & 0x1F) << 3
  549. B4 |= (stageEntry.ColorRegID & 0x7) << 1
  550. B4 |= (stageEntry.ColorClamp) << 0
  551. var B5 uint8 = 0
  552. B5 |= (stageEntry.AlphaB & 0xf) << 4
  553. B5 |= (stageEntry.AlphaA & 0xf) << 0
  554. var B6 uint8 = 0
  555. B6 |= (stageEntry.AlphaD & 0xf) << 4
  556. B6 |= (stageEntry.AlphaC & 0xf) << 0
  557. var B7 uint8 = 0
  558. B7 |= (stageEntry.AlphaScale & 0x3) << 6
  559. B7 |= (stageEntry.AlphaBias & 0x3) << 4
  560. B7 |= (stageEntry.AlphaOP & 0xf) << 0
  561. var B8 uint8 = 0
  562. B8 |= (stageEntry.AlphaConstantSel & 0x1F) << 3
  563. B8 |= (stageEntry.AlphaRegID & 0x7) << 1
  564. B8 |= (stageEntry.AlphaClamp) << 0
  565. var B10 uint8 = 0
  566. B10 |= (stageEntry.Matrix & 0x1F) << 3
  567. B10 |= (stageEntry.Bias & 0x7) << 0
  568. var B11 uint8 = 0
  569. B11 |= (stageEntry.WrapT & 0x7) << 3
  570. B11 |= (stageEntry.WrapS & 0x7) << 0
  571. var B12 uint8 = 0
  572. B12 |= (stageEntry.Alpha & 0xF) << 4
  573. B12 |= (stageEntry.UTCLod & 0x1) << 3
  574. B12 |= (stageEntry.AddPrevious & 0x1) << 2
  575. B12 |= (stageEntry.Format & 0x3) << 0
  576. entry := MATTevStageEntry{
  577. TexCoor: stageEntry.TexCoor,
  578. Color: stageEntry.Color,
  579. U16: U16,
  580. B1: B1,
  581. B2: B2,
  582. B3: B3,
  583. B4: B4,
  584. B5: B5,
  585. B6: B6,
  586. B7: B7,
  587. B8: B8,
  588. B9: stageEntry.TexID & 0x3,
  589. B10: B10,
  590. B11: B11,
  591. B12: B12,
  592. }
  593. write(temp, entry)
  594. count += 16
  595. }
  596. if entry.AlphaCompare != nil {
  597. var tempValue uint8 = 0
  598. tempValue |= (entry.AlphaCompare.Comp1 & 0x7) << 4
  599. tempValue |= (entry.AlphaCompare.Comp0 & 0x7) << 0
  600. entry := MatAlphaCompare{
  601. Temp: tempValue,
  602. AlphaOP: entry.AlphaCompare.AlphaOP,
  603. Ref0: entry.AlphaCompare.Ref0,
  604. Ref1: entry.AlphaCompare.Ref1,
  605. }
  606. write(temp, entry)
  607. count += 4
  608. }
  609. if entry.BlendMode != nil {
  610. write(temp, entry.BlendMode)
  611. count += 4
  612. }
  613. }
  614. header.Size = uint32(count)
  615. write(b, header)
  616. write(b, meta)
  617. write(b, offsets)
  618. write(b, temp.Bytes())
  619. }
  620. func BitExtract(num uint32, start int, end int) int {
  621. if end == 100 {
  622. end = start
  623. }
  624. firstMask := 1
  625. for first := 0; first < 31-start+1; first++ {
  626. firstMask *= 2
  627. }
  628. firstMask -= 1
  629. secondMask := 1
  630. for first := 0; first < 31-end; first++ {
  631. secondMask *= 2
  632. }
  633. secondMask -= 1
  634. mask := firstMask - secondMask
  635. return (int(num) & mask) >> (31 - end)
  636. }