wnd.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package brlyt
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "strings"
  6. )
  7. func (r *Root) ParseWND(data []byte) (*XMLWND, error) {
  8. var wnd Window
  9. err := binary.Read(bytes.NewReader(data), binary.BigEndian, &wnd)
  10. if err != nil {
  11. return nil, err
  12. }
  13. // Strip the null bytes from the strings
  14. name := strings.Replace(string(wnd.PaneName[:]), "\x00", "", -1)
  15. userData := strings.Replace(string(wnd.UserData[:]), "\x00", "", -1)
  16. // Get the UVSets
  17. uvSets := make([]XMLUVSet, wnd.NumOfUVSets)
  18. for i := 0; i < int(wnd.NumOfUVSets); i++ {
  19. offset := 116 + (i * 32)
  20. var uv UVSet
  21. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &uv)
  22. if err != nil {
  23. return nil, err
  24. }
  25. set := XMLUVSet{
  26. CoordTL: STCoordinates{
  27. T: uv.TopLeftT,
  28. S: uv.TopLeftS,
  29. },
  30. CoordTR: STCoordinates{
  31. T: uv.TopRightT,
  32. S: uv.TopRightS,
  33. },
  34. CoordBL: STCoordinates{
  35. T: uv.BottomLeftT,
  36. S: uv.BottomLeftS,
  37. },
  38. CoordBR: STCoordinates{
  39. T: uv.BottomRightT,
  40. S: uv.BottomRightS,
  41. },
  42. }
  43. uvSets[i] = set
  44. }
  45. // Parse Window Mat table
  46. mats := make([]XMLWindowMat, wnd.FrameCount)
  47. for i := 0; i < int(wnd.FrameCount); i++ {
  48. offset := 116 + (int(wnd.NumOfUVSets) * 32) + (i * 4)
  49. var actualOffset uint32
  50. err = binary.Read(bytes.NewReader(data[offset:]), binary.BigEndian, &actualOffset)
  51. if err != nil {
  52. return nil, err
  53. }
  54. var mat WindowMat
  55. err = binary.Read(bytes.NewReader(data[actualOffset-8:]), binary.BigEndian, &mat)
  56. if err != nil {
  57. return nil, err
  58. }
  59. material := XMLWindowMat{
  60. MatIndex: mat.MatIndex,
  61. Index: mat.Index,
  62. }
  63. mats[i] = material
  64. }
  65. xmlData := XMLWND{
  66. Name: name,
  67. UserData: userData,
  68. Visible: wnd.Flag & 0x1,
  69. Widescreen: (wnd.Flag & 0x2) >> 1,
  70. Flag: wnd.Flag,
  71. Origin: Coord2D{X: float32(wnd.Origin % 3), Y: float32(wnd.Origin / 3)},
  72. Alpha: wnd.Alpha,
  73. Padding: 0,
  74. Translate: Coord3D{X: wnd.XTranslation, Y: wnd.YTranslation, Z: wnd.ZTranslation},
  75. Rotate: Coord3D{X: wnd.XRotate, Y: wnd.YRotate, Z: wnd.ZRotate},
  76. Scale: Coord2D{X: wnd.XScale, Y: wnd.YScale},
  77. Width: wnd.Width,
  78. Height: wnd.Height,
  79. Coordinate1: wnd.Coordinate1,
  80. Coordinate2: wnd.Coordinate2,
  81. Coordinate3: wnd.Coordinate3,
  82. Coordinate4: wnd.Coordinate4,
  83. TopLeftColor: Color8{
  84. R: wnd.TopLeftColor[0],
  85. G: wnd.TopLeftColor[1],
  86. B: wnd.TopLeftColor[2],
  87. A: wnd.TopLeftColor[3],
  88. },
  89. TopRightColor: Color8{
  90. R: wnd.TopRightColor[0],
  91. G: wnd.TopRightColor[1],
  92. B: wnd.TopRightColor[2],
  93. A: wnd.TopRightColor[3],
  94. },
  95. BottomLeftColor: Color8{
  96. R: wnd.BottomLeftColor[0],
  97. G: wnd.BottomLeftColor[1],
  98. B: wnd.BottomLeftColor[2],
  99. A: wnd.BottomLeftColor[3],
  100. },
  101. BottomRightColor: Color8{
  102. R: wnd.BottomRightColor[0],
  103. G: wnd.BottomRightColor[1],
  104. B: wnd.BottomRightColor[2],
  105. A: wnd.BottomRightColor[3],
  106. },
  107. MatIndex: wnd.MatIndex,
  108. UVSets: &XMLUVSets{Set: uvSets},
  109. Materials: &XMLWindowMats{Mats: mats},
  110. }
  111. if r.HasChildren() {
  112. xmlData.Children, err = r.ParseChildren()
  113. if err != nil {
  114. return nil, err
  115. }
  116. }
  117. return &xmlData, nil
  118. }
  119. func (b *BRLYTWriter) WriteWND(data XMLWND) error {
  120. temp := bytes.NewBuffer(nil)
  121. header := SectionHeader{
  122. Type: SectionTypeWND,
  123. Size: 76,
  124. }
  125. var name [16]byte
  126. copy(name[:], data.Name)
  127. var userData [8]byte
  128. copy(userData[:], data.UserData)
  129. wnd := Window{
  130. Flag: data.Flag,
  131. Origin: uint8(data.Origin.X + (data.Origin.Y * 3)),
  132. Alpha: data.Alpha,
  133. PaneName: name,
  134. UserData: userData,
  135. XTranslation: data.Translate.X,
  136. YTranslation: data.Translate.Y,
  137. ZTranslation: data.Translate.Z,
  138. XRotate: data.Rotate.X,
  139. YRotate: data.Rotate.Y,
  140. ZRotate: data.Rotate.Z,
  141. XScale: data.Scale.X,
  142. YScale: data.Scale.Y,
  143. Width: data.Width,
  144. Height: data.Height,
  145. Coordinate1: data.Coordinate1,
  146. Coordinate2: data.Coordinate2,
  147. Coordinate3: data.Coordinate3,
  148. Coordinate4: data.Coordinate4,
  149. FrameCount: uint8(len(data.Materials.Mats)),
  150. WindowOffset: 104,
  151. WindowFrameOffset: uint32(124 + len(data.UVSets.Set)*32),
  152. TopLeftColor: [4]uint8{data.TopLeftColor.R, data.TopLeftColor.G, data.TopLeftColor.B, data.TopLeftColor.A},
  153. TopRightColor: [4]uint8{data.TopRightColor.R, data.TopRightColor.G, data.TopRightColor.B, data.TopRightColor.A},
  154. BottomLeftColor: [4]uint8{data.BottomLeftColor.R, data.BottomLeftColor.G, data.BottomLeftColor.B, data.BottomLeftColor.A},
  155. BottomRightColor: [4]uint8{data.BottomRightColor.R, data.BottomRightColor.G, data.BottomRightColor.B, data.BottomRightColor.A},
  156. MatIndex: data.MatIndex,
  157. NumOfUVSets: uint8(len(data.UVSets.Set)),
  158. }
  159. err := write(temp, header)
  160. if err != nil {
  161. return err
  162. }
  163. err = write(temp, wnd)
  164. if err != nil {
  165. return err
  166. }
  167. // Write the UV Sets
  168. for _, set := range data.UVSets.Set {
  169. uvSet := UVSet{
  170. TopLeftS: set.CoordTL.S,
  171. TopLeftT: set.CoordTL.T,
  172. TopRightS: set.CoordTR.S,
  173. TopRightT: set.CoordTR.T,
  174. BottomLeftS: set.CoordBL.S,
  175. BottomLeftT: set.CoordBL.T,
  176. BottomRightS: set.CoordBR.S,
  177. BottomRightT: set.CoordBR.T,
  178. }
  179. err = write(temp, uvSet)
  180. if err != nil {
  181. return err
  182. }
  183. }
  184. // Write the offsets to the Window Mats
  185. for i := 0; i < len(data.Materials.Mats); i++ {
  186. var offset uint32
  187. offset = uint32(temp.Len() + (len(data.Materials.Mats) * 4))
  188. err = write(temp, offset)
  189. if err != nil {
  190. return err
  191. }
  192. }
  193. // Write Window Mats
  194. for _, mat := range data.Materials.Mats {
  195. windowMat := WindowMat{
  196. MatIndex: mat.MatIndex,
  197. Index: mat.Index,
  198. }
  199. err = write(temp, windowMat)
  200. if err != nil {
  201. return err
  202. }
  203. }
  204. binary.BigEndian.PutUint32(temp.Bytes()[4:8], uint32(temp.Len()))
  205. return write(b, temp.Bytes())
  206. }