Advertisement
Guest User

Untitled

a guest
Oct 2nd, 2016
405
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
BlitzMax 38.61 KB | None | 0 0
  1. SuperStrict
  2. Framework sidesign.minib3d 'https://github.com/si-design/minib3d
  3. Import brl.Stream
  4. Import brl.linkedlist
  5. Import brl.standardio
  6. Import brl.bmploader
  7. Import brl.pngloader
  8.  
  9. 'Data sizes
  10. Const B_BYTE:Int = 1
  11. Const B_SHORT:Int = 2
  12. Const B_INT:Int = 4
  13. Const B_FLOAT:Int = 4
  14.  
  15. SetGraphicsDriver GLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER
  16. Graphics3D(DesktopWidth() * 0.7, DesktopHeight() * 0.7, 0, 2)
  17. ClearTextureFilters()
  18.  
  19. Global camera:TCamera = CreateCamera()
  20. MoveEntity(camera, 0, 0, -10)
  21.  
  22. 'AmbientLight(255, 255, 255)
  23. 'Local light:TLight = CreateLight(1)
  24. 'RotateEntity(light, 45, 45, 0)
  25.  
  26. TQPalette.LoadPalette("palette.lmp")
  27. Global myBSP:TQBSP
  28. Global levelMesh:TMesh
  29. Global levelMeshAlpha:TMesh
  30.  
  31. 'Debug make a mesh
  32. Function GenerateBSPMesh(mesh:TMesh var, alphaMesh:TMesh var, myBSP:TQBSP)
  33.     If mesh Then FreeEntity(mesh)
  34.     If alphaMesh Then FreeEntity(alphaMesh)
  35.     'Local mesh:TMesh = CreateMesh()
  36.     'Local surf:TSurface[1024 * 10]
  37.    
  38.     GCCollect()
  39.    
  40.     mesh = CreateMesh()
  41.     alphaMesh = CreateMesh()
  42.    
  43.     Local face:TQFace
  44.     Local ledge:TQLedge
  45.     Local edge:TQEdge
  46.     Local plane:TQPlane
  47.     Local texInfo:TQSurface
  48.     Local mipTex:TQMipTex
  49.     Local vert:TQVertex
  50.     Local fNr:Int
  51.     Local eNr:Int
  52.     Local surf:TSurface
  53.     Local vertCount:Int
  54.     Local newVertCount:Int
  55.    
  56.     Local s:Float
  57.     Local t:Float
  58.     Local lightU:Float
  59.     Local lightV:Float
  60.    
  61.     For Local model:TQModel = EachIn myBSP.Models 'Go through models
  62.         For fNr = model.Face_ID Until model.Face_ID + model.Face_Num 'Go through faces
  63.             'Debug progress
  64.             'If fNr Mod 100 <= 0 Then Print "Generating: " + fNr + "/" + model.Face_Num
  65.             face = myBSP.Faces[fNr] 'Get current face
  66.             plane = myBSP.PLANES[face.Plane_ID]
  67.             texInfo = myBSP.texInfo[face.TexInfo_ID]
  68.             mipTex = myBSP.MipTexs[texInfo.Texture_ID]
  69.            
  70.             If mipTex.Name.StartsWith("trigger") Or mipTex.Name.StartsWith("sky") Then Continue
  71.            
  72.             If mipTex.Name.startswith("+") Then
  73.                 myBSP.AnimatedFaces = myBSP.AnimatedFaces[..myBSP.AnimatedFaces.Length + 1]
  74.                 myBSP.AnimatedFaces[myBSP.AnimatedFaces.Length - 1] = face
  75.             EndIf
  76.            
  77.            
  78.             'ERROR if we're using too many vertices
  79.             If mipTex.Surface And mipTex.Surface.CountVertices() > (10000 * 3) - 1 Then Print "TOO MANY VERTICES!!";End
  80.            
  81.             'If we don't have a surface to work with, create one
  82.             If Not mipTex.Surface Then
  83.                 If mipTex.Name.StartsWith("*") Then
  84.                     mipTex.Surface = CreateSurface(alphaMesh, Null)
  85.                 Else
  86.                     mipTex.Surface = CreateSurface(mesh, Null)
  87.                 EndIf
  88.             EndIf
  89.            
  90.             surf = mipTex.Surface
  91.            
  92.             'Get verts
  93.             newVertCount = 0
  94.             vertCount = surf.CountVertices()
  95.             For eNr = face.Ledge_ID Until face.Ledge_ID + face.Ledge_Num 'Go through edges
  96.                 ledge = myBSP.Ledges[eNr] 'Get ledge
  97.                 edge = myBSP.Edges[Abs(ledge.edge)] 'Get edge via ledge
  98.                
  99.                 If ledge.edge < 0 Then
  100.                     vert = myBSP.Vertices[edge.Vertex0]
  101.                 Else
  102.                     vert = myBSP.Vertices[edge.Vertex1]
  103.                 EndIf
  104.                
  105.                 AddVertex(surf, -vert.Y * 0.2, vert.Z * 0.2, vert.X * 0.2)
  106.                
  107.                 'Calculate UV
  108.                 s = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorS.X, texInfo.VectorS.Y, texInfo.VectorS.Z) + texInfo.DistS
  109.                 t = DotProduct(vert.X, vert.Y, vert.Z, texInfo.VectorT.X, texInfo.VectorT.Y, texInfo.VectorT.Z) + texInfo.DistT
  110.                
  111.                 'Lightmap UV
  112.                 If face.LightMap >= 0 Then
  113.                     lightU = (s - Floor(face.LightMinUV.x / 16) * 16) / (face.LightDist.x + 1)
  114.                     lightV = (t - Ceil(face.LightMinUV.y / 16) * 16) / (face.LightDist.y + 1)
  115.                    
  116.                     lightU = (face.LightMapPos.x + lightU * face.LightMapSize.x) / myBSP.LightMapTexture.width
  117.                     lightV = (face.LightMapPos.y + lightV * face.LightMapSize.y) / myBSP.LightMapTexture.Height
  118.                    
  119.                     VertexTexCoords(surf, vertCount, lightU, lightV, 0, 1)
  120.                 Else
  121.                     If Not mipTex.Name.StartsWith("*") Then VertexColor(surf, vertCount, 1, 1, 1)
  122.                 EndIf
  123.                
  124.                 'VertexColor(surf, vertCount, face.BaseLight, face.BaseLight, face.BaseLight)
  125.                
  126.                 'Texture UV
  127.                 s:/myBSP.MipTexs[texInfo.Texture_ID].width
  128.                 t:/myBSP.MipTexs[texInfo.Texture_ID].Height
  129.                
  130.                 VertexTexCoords(surf, vertCount, s, t, 0, 0) 'Real texture UV
  131.                 VertexNormal(surf, vertCount, plane.Normal.Z, plane.Normal.Y, plane.Normal.X)
  132.                
  133.                 vertCount:+1
  134.                 newVertCount:+1
  135.             Next
  136.            
  137.             'Make Tris
  138.             For Local i:Int = vertCount - newVertCount Until vertCount - 2
  139.                 AddTriangle(surf, vertCount - newVertCount, i + 1, i + 2)
  140.             Next
  141.            
  142.             If face.LightMap >= 0 Then
  143.                 Local tmpBrush:TBrush = CreateBrush()
  144.                 TextureCoords(myBSP.LightMapTexture, 1)
  145.                 TextureBlend(myBSP.LightMapTexture, 5)
  146.                
  147.                 'BrushTexture(tmpBrush, myBSP.MipTexs[texInfo.Texture_ID].Texture, 0, 0)
  148.                 BrushTexture(tmpBrush, myBSP.LightMapTexture, 0, 1)
  149.                 PaintSurface(surf, tmpBrush)
  150.                 FreeBrush(tmpBrush)
  151.             Else
  152.                 If mipTex.Name.StartsWith("*") Then PaintSurface(surf, myBSP.MipTexs[texInfo.Texture_ID].Brush)
  153.             EndIf
  154.         Next
  155.     Next
  156.    
  157.     EntityFX(mesh, 1 + 2)
  158.     EntityFX(alphaMesh, 1 + 2)
  159.    
  160.     EntityAlpha(alphaMesh, 0.9)
  161.     'EntityBlend(alphaMesh, 5)
  162.    
  163.     'Return mesh
  164.     GCCollect()
  165. EndFunction
  166.  
  167. 'Print mesh.CountSurfaces()
  168.  
  169. Function RequestBSP()
  170.     Local filter:String = "BSP Files:bsp;All Files:*"
  171.     Local file:String = RequestFile("Select BSP file to load", filter:String)
  172.    
  173.     If file Then
  174.         PositionEntity(camera, -2, 2.5, -10)
  175.         RotateEntity(camera, 0, 0, 0)
  176.        
  177.         If myBSP Then myBSP.Free()
  178.         myBSP = TQBSP.LoadFile(file)
  179.         GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  180.     EndIf
  181.    
  182.     FlushKeys()
  183.     FlushMouse()
  184. EndFunction
  185.  
  186. If FileSize(AppDir + "/start.bsp") > 0 Then
  187.     myBSP = TQBSP.LoadFile(AppDir + "/start.bsp")
  188.     GenerateBSPMesh(levelMesh, levelMeshAlpha, myBSP)
  189.    
  190.     PositionEntity(camera, -50, 35, 80)
  191.     'RotateEntity(camera, 15, 180 + 25, 0)
  192.     RotateEntity(camera, 0, 90, 0)
  193. Else
  194.     RequestBSP()
  195. EndIf
  196.  
  197. 'Main loop
  198. While Not AppTerminate() And Not KeyDown(KEY_ESCAPE)
  199.     'Cls()
  200.     'If KeyHit(KEY_O) Then Wireframe(False)
  201.     If KeyDown(KEY_P) Then Wireframe(True)
  202.    
  203.     If KeyHit(KEY_O) Then GCCollect()
  204.    
  205.     If KeyDown(KEY_LEFT) Then TurnEntity(camera, 0, 2, 0)
  206.     If KeyDown(KEY_RIGHT) Then TurnEntity(camera, 0, -2, 0)
  207.     If KeyDown(KEY_UP) Then TurnEntity(camera, -2, 0, 0)
  208.     If KeyDown(KEY_DOWN) Then TurnEntity(camera, 2, 0, 0)
  209.    
  210.     If KeyDown(KEY_W) Then MoveEntity(camera, 0, 0, 1.5)
  211.     If KeyDown(KEY_S) Then MoveEntity(camera, 0, 0, -1.5)
  212.     If KeyDown(KEY_A) Then MoveEntity(camera, -1.5, 0, 0)
  213.     If KeyDown(KEY_D) Then MoveEntity(camera, 1.5, 0, 0)
  214.    
  215.     If KeyDown(KEY_SPACE) Then MoveEntity(camera, 0, 1, 0)
  216.     If KeyDown(KEY_LCONTROL) Then MoveEntity(camera, 0, -1, 0)
  217.    
  218.     If KeyHit(KEY_TAB) Then RequestBSP()
  219.    
  220.     'If myBSP Then myBSP.Update()
  221.    
  222.     myBSP.PositionSkyBox(EntityX(camera), EntityY(camera), EntityZ(camera), EntityPitch(camera), EntityYaw(camera))
  223.    
  224.     RenderWorld()
  225.    
  226.     BeginMax2D()
  227.     DrawText("TAB: Open BSP", 0, 0)
  228.     EndMax2D()
  229.    
  230.     Flip(1)
  231. Wend
  232. End
  233.  
  234. Type TQBSP
  235.     Field File:String
  236.     Field Stream:TStream
  237.    
  238.     Field Header:TQHeader
  239.    
  240.     Field PLANES:TQPlane[]
  241.     Field Vertices:TQVertex[]
  242.     Field Nodes:TList = CreateList()
  243.     Field TexInfo:TQSurface[]
  244.     Field MipTexHeader:TQMipHeader
  245.     Field MipTexs:TQMipTex[]
  246.     Field LiquidMipTexs:TQMipTex[]
  247.     Field AnimatedMipTexs:TQMipTex[]
  248.     Field AnimatedFaces:TQFace[]
  249.     Field Faces:TQFace[]
  250.     Field ClipNodes:TList = CreateList()
  251.     Field Leaves:TList = CreateList()
  252.     Field Edges:TQEdge[]
  253.     Field Ledges:TQLedge[]
  254.     Field Models:TQModel[]
  255.    
  256.     Field LightMapBrighness:Byte = 0
  257.     Field LightMapMaxBright:Byte = 255
  258.     Field LightMapMinBright:Byte = 0
  259.     Field LightMapBaseStr:Float = 0
  260.     Field LightMapTexture:TTexture
  261.     Field LightMapPixmap:TPixmap
  262.     Field LightMapPreW:Int
  263.     Field LightMapPreH:Int
  264.     Field LightMapMaxH:Int
  265.    
  266.     Field SkyTexture:TTexture[2]
  267.     Field SkyBox:TMesh[2]
  268.    
  269.     Field AnimTime:Int
  270.     Field StartMS:Int
  271.    
  272.     Function LoadFile:TQBSP(url:String)
  273.         Local nB:TQBSP = New TQBSP
  274.         nB.File = url
  275.        
  276.         If nB.Process() Then
  277.             Return nB
  278.         Else
  279.             nB.StreamError("Map ~q" + nB.file + "~q NOT loaded")
  280.             Return Null
  281.         EndIf
  282.     EndFunction
  283.    
  284.     Method Free()
  285.         If SkyBox[0] Then FreeEntity(SkyBox[0])
  286.         If SkyBox[1] Then FreeEntity(SkyBox[1])
  287.     EndMethod
  288.    
  289.     Method PositionSkyBox(x:Float, y:Float, z:Float, Pitch:Float, Yaw:Float)
  290.         If Not SkyBox[0] Or Not SkyBox[1] Then Return
  291.        
  292.         PositionEntity(SkyBox[0], x, y, z)
  293.         PositionEntity(SkyBox[1], x, y, z)
  294.        
  295.         'RotateEntity(SkyBox[0], (Pitch - 90) / 2.0, 0, 0)
  296.         'RotateEntity(SkyBox[1], (Pitch - 90) / 2.0, 0, 0)
  297.        
  298.         'RotateTexture(Self.SkyTexture[0], Yaw)
  299.         'RotateTexture(Self.SkyTexture[1], Yaw)
  300.     EndMethod
  301.    
  302.     Method Update()
  303.         If Self.SkyTexture[0] Then PositionTexture(Self.SkyTexture[0], -(MilliSecs() - StartMS) * 0.00005, -(MilliSecs() - StartMS) * 0.00005)
  304.         If Self.SkyTexture[1] Then PositionTexture(Self.SkyTexture[1], -(MilliSecs() - StartMS) * 0.00005 * 2.5, -(MilliSecs() - StartMS) * 0.00005 * 2.5)
  305.        
  306.         For Local m:TQMipTex = EachIn Self.LiquidMipTexs
  307.             PositionTexture(GetBrushTexture(m.Brush), -(MilliSecs() - StartMS) * 0.000075, -(MilliSecs() - StartMS) * 0.0001)
  308.             'RotateTexture(GetBrushTexture(m.Brush), (MilliSecs() - StartMS) * 0.00075)
  309.         Next
  310.        
  311.         Local texInfo:TQSurface
  312.         Local mipTex:TQMipTex
  313.         Local newMipTex:TQMipTex
  314.         Local newMipTexName:String
  315.         While Self.AnimTime < (MilliSecs() - Self.StartMS) / 200
  316.             Self.AnimTime:+1
  317.            
  318.             For Local m:TQMipTex = EachIn Self.AnimatedMipTexs
  319.                 m.AnimStep:+1
  320.             Next
  321.            
  322.             For Local f:TQFace = EachIn Self.AnimatedFaces
  323.                 texInfo = myBSP.texInfo[f.TexInfo_ID]
  324.                 mipTex = myBSP.MipTexs[texInfo.Texture_ID]
  325.                 newMipTexName = "+" + (Int(Mid(mipTex.Name, 2, 1)) + mipTex.AnimStep)
  326.                 newMipTexName:+Right(mipTex.Name, Len(mipTex.Name) - 2)
  327.                
  328.                 'Find new image
  329.                 newMipTex = Null
  330.                 For Local nM:TQMipTex = EachIn Self.AnimatedMipTexs
  331.                     If nM.Name = newMipTexName Then
  332.                         newMipTex = nM
  333.                         'mipTex.AnimStep:+1
  334.                         Exit
  335.                     EndIf
  336.                 Next
  337.                 If Not newMipTex Then
  338.                     mipTex.AnimStep = 0
  339.                     newMipTex = mipTex
  340.                 EndIf
  341.                
  342.                 'Apply new image
  343.                 If f.LightMap >= 0 Then
  344.                     Local tmpBrush:TBrush = CreateBrush()
  345.                     TextureCoords(LightMapTexture, 1)
  346.                     TextureBlend(LightMapTexture, 5)
  347.                    
  348.                     BrushTexture(tmpBrush, newMipTex.Texture, 0, 0)
  349.                     BrushTexture(tmpBrush, LightMapTexture, 0, 1)
  350.                     PaintSurface(mipTex.Surface, tmpBrush)
  351.                     FreeBrush(tmpBrush)
  352.                 'Else
  353.                     'PaintSurface(mipTex.Surface, newMipTex.Brush)
  354.                 EndIf
  355.             Next
  356.         Wend
  357.     EndMethod
  358.    
  359.     Method StreamError(MSG:String)
  360.         If Stream Then CloseStream(Stream)
  361.         DebugLog "Read error: " + MSG
  362.     EndMethod
  363.    
  364.     Method Process:Int()
  365.         Stream = OpenStream(File)
  366.         If Not Stream Then
  367.             StreamError("Unable to read file ~q" + file + "~q")
  368.             Return False
  369.         EndIf
  370.        
  371.         Local num:Int 'For counting stuff
  372.         Local i:Int 'For loops
  373.        
  374.         'Make skybox
  375.         If Not SkyBox[0] Then
  376.             SkyBox[0] = CreateMesh()
  377.             Local surf:TSurface = CreateSurface(skybox[0])
  378.            
  379.             surf.AddVertex(-1.0, -1.0, 1.0)
  380.             surf.AddVertex(-1.0, 1.0, 1.0)
  381.             surf.AddVertex( 1.0, 1.0, 1.0)
  382.             surf.AddVertex( 1.0,-1.0, 1.0)
  383.            
  384.             surf.VertexTexCoords(0, 0.0, 1.0)
  385.             surf.VertexTexCoords(1, 0.0, 0.0)
  386.             surf.VertexTexCoords(2, 1.0, 0.0)
  387.             surf.VertexTexCoords(3, 1.0, 1.0)
  388.            
  389.             surf.AddTriangle(0, 1, 2)
  390.             surf.AddTriangle(0, 2, 3)
  391.            
  392.             SkyBox[1] = CopyMesh(SkyBox[0])
  393.            
  394.             For i = 0 Until SkyBox.Length
  395.                 'FlipMesh(SkyBox[i])
  396.                 ScaleMesh(SkyBox[i], 100, 100, 2)
  397.                 RotateMesh(SkyBox[i], -90, 180, 90)
  398.                 'PositionMesh(SkyBox[i], 0, 0, 2)
  399.                 EntityFX(SkyBox[i], 1)
  400.                 EntityOrder(SkyBox[i], 10000 - i)
  401.                 'ScaleEntity(SkyBox[i], 2, 2, 2)
  402.             Next
  403.         EndIf
  404.        
  405.         'Read header
  406.         Self.Header = TQHeader.Read(Stream)
  407.        
  408.         'Read planes
  409.         num = Self.Header.PLANES.Count(TQPlane.Size())
  410.         DebugLog "Planes: " + num
  411.         Self.PLANES = New TQPlane[num]
  412.         Self.Header.PLANES.JumpTo(Stream)
  413.         For i = 0 Until num
  414.             'ListAddLast(Self.PLANES, TQPlane.Read(Stream))
  415.             Self.PLANES[i] = TQPlane.Read(Stream)
  416.         Next
  417.        
  418.         'Read vertices
  419.         num = Self.Header.Vertices.Count(TQVertex.Size())
  420.         DebugLog "Vertices: " + num
  421.         Self.Vertices = New TQVertex[num]
  422.         Self.Header.Vertices.JumpTo(Stream)
  423.         For i = 0 Until num
  424.             'ListAddLast(Self.Vertices, TQVertex.Read(Stream))
  425.             Self.Vertices[i] = TQVertex.Read(Stream)
  426.         Next
  427.        
  428.         'Read nodes
  429.         'num = Self.Header.Nodes.Count(TQNode.Size())
  430.         'DebugLog "Nodes: " + num
  431.         'Self.Header.Nodes.JumpTo(Stream)
  432.         'For i = 0 Until num
  433.         '   ListAddLast(Self.Nodes, TQNode.Read(Stream))
  434.         'Next
  435.        
  436.         'Read texture info
  437.         num = Self.Header.TexInfo.Count(TQSurface.Size())
  438.         DebugLog "TexInfo: " + num
  439.         Self.TexInfo = New TQSurface[num]
  440.         Self.Header.TexInfo.JumpTo(Stream)
  441.         For i = 0 Until num
  442.             Self.TexInfo[i] = TQSurface.Read(Stream)
  443.         Next
  444.        
  445.         'Read mipmap header
  446.         Self.Header.MipTex.JumpTo(Stream)
  447.         Self.MipTexHeader = TQMipHeader.Read(Stream)
  448.         num = Self.MipTexHeader._count
  449.         DebugLog "MipMap Texs: " + num
  450.        
  451.         'Read miptexs from mipmap header
  452.         'CreateDir(AppDir + "/tex/", True) 'Debug for exporting
  453.        
  454.         MipTexs = New TQMipTex[num]
  455.         For i = 0 Until num
  456.             Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i])
  457.             Self.MipTexs[i] = TQMipTex.Read(Stream)
  458.            
  459.             If Self.MipTexs[i].width > 1 And Self.MipTexs[i].Height > 1 Then
  460.                 Local pix:TPixmap
  461.                 Local x:Int
  462.                 Local y:Int
  463.                 Local colorID:Byte
  464.                 Local palColor:TQColor32
  465.                
  466.                 Stream.Seek(Self.Header.MipTex.Offset + Self.MipTexHeader.Offset[i] + Self.MipTexs[i].Offset1)
  467.                 If Not Self.MipTexs[i].Name.StartsWith("sky") Then
  468.                     pix = CreatePixmap(Self.MipTexs[i].width, Self.MipTexs[i].Height, PF_RGB888)
  469.                    
  470.                     For Local bI:Int = 0 Until pix.width * pix.Height
  471.                         colorID = ReadByte(Stream)
  472.                         palColor = TQPalette.colors[colorID]
  473.                        
  474.                         pix.WritePixel(x, y, GenRGB(palColor.r, palColor.g, palColor.b))
  475.                        
  476.                         x:+1
  477.                         If x >= pix.width Then
  478.                             x = 0
  479.                             y:+1
  480.                         EndIf
  481.                     Next
  482.                    
  483.                     If pix Then
  484.                         'Print Self.MipTexs[i].Name
  485.                        
  486.                         Self.MipTexs[i].Brush = LoadBrushPixmap(pix, 0)
  487.                         Self.MipTexs[i].Texture = LoadTexturePixmap(pix, 0)
  488.                        
  489.                         'Liquids
  490.                         If Self.MipTexs[i].Name.StartsWith("*") Then
  491.                             LiquidMipTexs = LiquidMipTexs[..LiquidMipTexs.Length + 1]
  492.                             LiquidMipTexs[LiquidMipTexs.Length - 1] = Self.MipTexs[i]
  493.                         EndIf
  494.                        
  495.                         'Animated
  496.                         If Self.MipTexs[i].Name.StartsWith("+") Then
  497.                             AnimatedMipTexs = AnimatedMipTexs[..AnimatedMipTexs.Length + 1]
  498.                             AnimatedMipTexs[AnimatedMipTexs.Length - 1] = Self.MipTexs[i]
  499.                         EndIf
  500.                        
  501.                         pix = Null
  502.                     EndIf
  503.                 Else
  504.                     pix = CreatePixmap(Self.MipTexs[i].width / 2, Self.MipTexs[i].Height, PF_RGBA8888)
  505.                     Local pix2:TPixmap = CreatePixmap(Self.MipTexs[i].width / 2, Self.MipTexs[i].Height, PF_RGB888)
  506.                     Local blackness:Float
  507.                    
  508.                     For Local bI:Int = 0 Until Self.MipTexs[i].width * Self.MipTexs[i].Height
  509.                         colorID = ReadByte(Stream)
  510.                         palColor = TQPalette.colors[colorID]
  511.                        
  512.                         blackness = (palColor.r + palColor.g + palColor.b) / 2.0
  513.                         blackness:*2.5
  514.                         If blackness > 255 Then blackness = 255
  515.                        
  516.                         If x < pix.width Then
  517.                             pix.WritePixel(x, y, GenRGB(palColor.r, palColor.g, palColor.b, blackness))
  518.                         Else
  519.                             pix2.WritePixel(x - pix.width, y, GenRGB(palColor.r, palColor.g, palColor.b))
  520.                         EndIf
  521.                        
  522.                         x:+1
  523.                         If x >= Self.MipTexs[i].width Then
  524.                             x = 0
  525.                             y:+1
  526.                         EndIf
  527.                     Next
  528.                    
  529.                     Self.SkyTexture[0] = LoadTexturePixmap(pix2, 8)
  530.                     Self.SkyTexture[1] = LoadTexturePixmap(pix, 2 + 8)
  531.                    
  532.                     'TextureBlend(Self.SkyTexture[0], 5)
  533.                     'TextureBlend(Self.SkyTexture[1], 2)
  534.                    
  535.                     ScaleTexture(Self.SkyTexture[0], 0.0065, 0.0065)
  536.                     ScaleTexture(Self.SkyTexture[1], 0.0065, 0.0065)
  537.                    
  538.                     EntityTexture(Self.SkyBox[0], Self.SkyTexture[0], 0, 0)
  539.                     EntityTexture(Self.SkyBox[1], Self.SkyTexture[1], 0, 0)
  540.                    
  541.                     'SavePixmapPNG(pix, "sky1.png")
  542.                     'SavePixmapPNG(pix2, "sky2.png")
  543.                     pix = Null
  544.                     pix2 = Null
  545.                 EndIf
  546.             EndIf
  547.         Next
  548.        
  549.         'Read faces
  550.         num = Self.Header.Faces.Count(TQFace.Size())
  551.         DebugLog "Faces: " + num
  552.         Self.Faces = New TQFace[num]
  553.         Self.Header.Faces.JumpTo(Stream)
  554.         For i = 0 Until num
  555.             Self.Faces[i] = TQFace.Read(Stream)
  556.         Next
  557.        
  558.         'Read lightmaps
  559.         'Self.Header.LightMaps.JumpTo(Stream)
  560.         'LightMap = New Byte[Self.Header.LightMaps.Size]
  561.         'For i:Int = 0 Until LightMap.Length
  562.         '   LightMap[i] = ReadByte(Stream)
  563.         'Next
  564.         'Stream.ReadBytes(LightMap, LightMap.Length)
  565.        
  566.         'Read clipnodes
  567.         'num = Self.Header.ClipNodes.Count(TQClipNode.Size())
  568.         'DebugLog "ClipNodes: " + num
  569.         'Self.Header.ClipNodes.JumpTo(Stream)
  570.         'For i = 0 Until num
  571.         '   ListAddLast(Self.ClipNodes, TQClipNode.Read(Stream))
  572.         'Next
  573.        
  574.         'Read leaves
  575.         'num = Self.Header.Leaves.Count(TQDLeaf.Size())
  576.         'DebugLog "Leaves: " + num
  577.         'Self.Header.Leaves.JumpTo(Stream)
  578.         'For i = 0 Until num
  579.         '   ListAddLast(Self.Leaves, TQDLeaf.Read(Stream))
  580.         'Next
  581.        
  582.         'Read edges
  583.         num = Self.Header.Edges.Count(TQEdge.Size())
  584.         DebugLog "Edges: " + num
  585.         Self.Edges = New TQEdge[num]
  586.         Self.Header.Edges.JumpTo(Stream)
  587.         For i = 0 Until num
  588.             'ListAddLast(Self.Edges, TQEdge.Read(Stream))
  589.             Self.Edges[i] = TQEdge.Read(Stream)
  590.         Next
  591.        
  592.         'Read ledges
  593.         num = Self.Header.Ledges.Count(TQLedge.Size())
  594.         DebugLog "Ledges: " + num
  595.         Self.Ledges = New TQLedge[num]
  596.         Self.Header.Ledges.JumpTo(Stream)
  597.         For i = 0 Until num
  598.             'ListAddLast(Self.Ledges, TQLedge.Read(Stream))
  599.             Self.Ledges[i] = TQLedge.Read(Stream)
  600.         Next
  601.        
  602.         'Read models
  603.         num = Self.Header.Models.Count(TQModel.Size())
  604.         DebugLog "Models: " + num
  605.         Self.Models = New TQModel[num]
  606.         Self.Header.Models.JumpTo(Stream)
  607.         For i = 0 Until num
  608.             'ListAddLast(Self.Models, TQModel.Read(Stream))
  609.             Self.Models[i] = TQModel.Read(Stream)
  610.         Next
  611.        
  612.         'Read lightmaps from faces
  613.         For i = 0 Until Self.Faces.Length 'Calculate all lightmap part sizes and store them
  614.             Self.Faces[i].CalcLightmapSize(Self)
  615.         Next
  616.        
  617.         'Create a global lightmap image
  618.         Self.LightMapPreH = TQFace.LIGHT_PAD
  619.         Self.LightMapPreW = TQFace.LIGHT_PAD
  620.         Local pixSize:Int = Pow2Size(Sqr(Self.Header.LightMaps.Size) * 1.75)
  621.         LightMapPixmap = CreatePixmap(pixSize, pixSize, PF_RGB888)
  622.         For i = 0 Until Self.Faces.Length 'Store lightmap parts in big picture
  623.             Self.Faces[i].MakeLightmap(Self)
  624.         Next
  625.         LightMapTexture = LoadTexturePixmap(LightMapPixmap, 0)
  626.         'Debug save
  627.         'If LightMapPixmap Then SavePixmapPNG(LightMapPixmap, "lightmap.png", 0)
  628.         'End
  629.        
  630.         StartMS = MilliSecs()
  631.        
  632.         CloseStream(Stream)
  633.         Return True
  634.     EndMethod
  635. EndType
  636.  
  637. 'http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm
  638. 'char 8bit = negative byte
  639. 'u_char 8bit = byte
  640. 'short 16bit = negative short
  641. 'u_short 16bit = short
  642. 'long 32bit = int
  643. 'u_long 32bit = longer int
  644. 'float 32bit = float
  645. 'scalar_t 32bit = float
  646.  
  647. Type TQHeader
  648.     Field Version:Int
  649.     Field Entities:TQEntry
  650.     Field PLANES:TQEntry
  651.     Field MipTex:TQEntry
  652.     Field Vertices:TQEntry
  653.     Field VisiList:TQEntry
  654.     Field Nodes:TQEntry
  655.     Field TexInfo:TQEntry
  656.     Field Faces:TQEntry
  657.     Field LightMaps:TQEntry
  658.     Field ClipNodes:TQEntry
  659.     Field Leaves:TQEntry
  660.     Field LFace:TQEntry
  661.     Field Edges:TQEntry
  662.     Field Ledges:TQEntry
  663.     Field Models:TQEntry
  664.    
  665.     Function Read:TQHeader(Stream:TStream)
  666.         Local nH:TQHeader = New TQHeader
  667.        
  668.         nH.Version = ReadInt(Stream)
  669.         If nH.Version = "29" Then
  670.             DebugLog "BSP version: " + nH.Version + " (correct)"
  671.         Else
  672.             DebugLog "BSP version: " + nH.Version + " (incorrect)"
  673.         EndIf
  674.        
  675.         nH.Entities = TQEntry.Read(Stream)
  676.         nH.PLANES = TQEntry.Read(Stream)
  677.        
  678.         nH.MipTex = TQEntry.Read(Stream)
  679.         nH.Vertices = TQEntry.Read(Stream)
  680.        
  681.         nH.VisiList = TQEntry.Read(Stream)
  682.         nH.Nodes = TQEntry.Read(Stream)
  683.        
  684.         nH.TexInfo = TQEntry.Read(Stream)
  685.        
  686.         nH.Faces = TQEntry.Read(Stream)
  687.        
  688.         nH.LightMaps = TQEntry.Read(Stream)
  689.         DebugLog "Lightmap Size: " + nH.LightMaps.Size
  690.         nH.ClipNodes = TQEntry.Read(Stream)
  691.        
  692.         nH.Leaves = TQEntry.Read(Stream)
  693.        
  694.         nH.LFace = TQEntry.Read(Stream)
  695.         nH.Edges = TQEntry.Read(Stream)
  696.        
  697.         nH.Ledges = TQEntry.Read(Stream)
  698.         nH.Models = TQEntry.Read(Stream)
  699.        
  700.         Return nH
  701.     EndFunction
  702. EndType
  703.  
  704. Type TQModel
  705.     Field Bound:TQBoundBox
  706.     Field Origin:TQVec3
  707.     Field Node_ID0:Int
  708.     Field Node_ID1:Int
  709.     Field Node_ID2:Int
  710.     Field Node_ID3:Int
  711.     Field NumLeafs:Int
  712.     Field Face_ID:Int
  713.     Field Face_Num:Int
  714.    
  715.     Function Read:TQModel(Stream:TStream)
  716.         Local nM:TQModel = New TQModel
  717.         nM.Bound = TQBoundBox.Read(Stream)
  718.         nM.Origin = TQVec3.Read(Stream)
  719.         nM.Node_ID0 = ReadInt(Stream)
  720.         nM.Node_ID1 = ReadInt(Stream)
  721.         nM.Node_ID2 = ReadInt(Stream)
  722.         nM.Node_ID3 = ReadInt(Stream)
  723.         nM.NumLeafs = ReadInt(Stream)
  724.         nM.Face_ID = ReadInt(Stream)
  725.         nM.Face_Num = ReadInt(Stream)
  726.         Return nM
  727.     EndFunction
  728.    
  729.     Function Size:Int()
  730.         Return (B_INT * 7) + TQBoundBox.Size() + TQVec3.Size()
  731.     EndFunction
  732. EndType
  733.  
  734. Type TQVertex
  735.     Field X:Float
  736.     Field Y:Float
  737.     Field Z:Float
  738.    
  739.     Function Read:TQVertex(Stream:TStream)
  740.         Local nV:TQVertex = New TQVertex
  741.         nV.X = ReadFloat(Stream)
  742.         nV.Y = ReadFloat(Stream)
  743.         nV.Z = ReadFloat(Stream)
  744.        
  745.         Return nV
  746.     EndFunction
  747.    
  748.     Function Size:Int()
  749.         Return B_FLOAT * 3
  750.     EndFunction
  751. EndType
  752.  
  753. Type TQSurface
  754.     Field VectorS:TQVec3
  755.     Field DistS:Float
  756.     Field VectorT:TQVec3
  757.     Field DistT:Float
  758.     Field Texture_ID:Int
  759.    
  760.     Field Animated:Int
  761.    
  762.     Function Read:TQSurface(Stream:TStream)
  763.         Local nS:TQSurface = New TQSurface
  764.         nS.VectorS = TQVec3.Read(Stream)
  765.         nS.DistS = ReadFloat(Stream)
  766.         nS.VectorT = TQVec3.Read(Stream)
  767.         nS.DistT = ReadFloat(Stream)
  768.         nS.Texture_ID = ReadInt(Stream)
  769.         nS.Animated = ReadInt(Stream)
  770.         Return nS
  771.     EndFunction
  772.    
  773.     Function Size:Int()
  774.         Return (B_FLOAT * 2) + (B_INT * 2) + (TQVec3.Size() * 2)
  775.     EndFunction
  776. EndType
  777.  
  778. Type TQEdge
  779.     Field Vertex0:Short
  780.     Field Vertex1:Short
  781.    
  782.     Function Read:TQEdge(Stream:TStream)
  783.         Local nE:TQEdge = New TQEdge
  784.         nE.Vertex0 = ReadShort(Stream)
  785.         nE.Vertex1 = ReadShort(Stream)
  786.         Return nE
  787.     EndFunction
  788.    
  789.     Function Size:Int()
  790.         Return B_SHORT * 2
  791.     EndFunction
  792. EndType
  793.  
  794. Type TQLedge
  795.     Field Edge:Int
  796.    
  797.     Function Read:TQLedge(Stream:TStream)
  798.         Local nL:TQLedge = New TQLedge
  799.         nL.Edge = ReadInt(Stream)
  800.         Return nL
  801.     EndFunction
  802.    
  803.     Function Size:Int()
  804.         Return B_INT
  805.     EndFunction
  806. EndType
  807.  
  808. Type TQFace
  809.     Const LIGHT_PAD:Int = 1
  810.    
  811.     Field Plane_ID:Short
  812.    
  813.     Field Side:Short
  814.     Field Ledge_ID:Int
  815.    
  816.     Field Ledge_Num:Short
  817.     Field TexInfo_ID:Short
  818.    
  819.     Field TypeLight:Byte
  820.     Field BaseLight:Byte
  821.     Field Light:Byte[2]
  822.     Field LightMap:Int
  823.    
  824.     Field LightBrush:TBrush
  825.     Field LightDist:TQIntVec2
  826.     Field LightMinUV:TQVec2
  827.     Field LightMaxUV:TQVec2
  828.     Field LightS:Float
  829.     Field LightT:Float
  830.     Field LightMapSize:TQIntVec2
  831.     Field LightMapPos:TQVec2
  832.    
  833.     Function Read:TQFace(Stream:TStream)
  834.         Local nF:TQFace = New TQFace
  835.         nF.Plane_ID = ReadShort(Stream)
  836.         nF.Side = ReadShort(Stream)
  837.         nF.Ledge_ID = ReadInt(Stream)
  838.         nF.Ledge_Num = ReadShort(Stream)
  839.         nF.TexInfo_ID = ReadShort(Stream)
  840.         nF.TypeLight = ReadByte(Stream)
  841.         nF.BaseLight = ReadByte(Stream)
  842.         nF.Light[0] = ReadByte(Stream)
  843.         nF.Light[1] = ReadByte(Stream)
  844.         nF.LightMap = ReadInt(Stream)
  845.         Return nF
  846.     EndFunction
  847.    
  848.     Method GetLightmapSize:TQIntVec2(bsp:TQBSP)
  849.         If LightMapSize Then
  850.             Return LightMapSize
  851.         Else
  852.             Return CalcLightmapSize(bsp)
  853.         EndIf
  854.     EndMethod
  855.    
  856.     Method CalcLightmapSize:TQIntVec2(bsp:TQBSP)
  857.         If Self.LightMap < 0 Then Return New TQIntVec2
  858.        
  859.         If LightMapSize Then
  860.             Return LightMapSize
  861.         Else
  862.             LightMapSize = New TQIntVec2
  863.         EndIf
  864.        
  865.         'Get the vertex data from all edges
  866.         LightDist = New TQIntVec2
  867.         LightMinUV = New TQVec2
  868.         LightMaxUV = New TQVec2
  869.        
  870.         Local ledge:TQLedge
  871.         Local edge:TQEdge
  872.         Local vert:TQVertex
  873.         Local texInfo:TQSurface = bsp.texInfo[Self.TexInfo_ID]
  874.         For Local eNr:Int = Self.Ledge_ID Until Self.Ledge_ID + Self.Ledge_Num 'Go through edges
  875.             ledge = bsp.Ledges[eNr] 'Get ledge
  876.             edge = bsp.Edges[Abs(ledge.edge)] 'Get edge via ledge
  877.            
  878.             If ledge.edge < 0 Then
  879.                 vert = bsp.Vertices[edge.Vertex0]
  880.             Else
  881.                 vert = bsp.Vertices[edge.Vertex1]
  882.             EndIf
  883.            
  884.             LightS = DotProduct(vert.x, vert.y, vert.z, texInfo.VectorS.x, texInfo.VectorS.y, texInfo.VectorS.z) + texInfo.DistS
  885.             LightT = DotProduct(vert.x, vert.y, vert.z, texInfo.VectorT.x, texInfo.VectorT.y, texInfo.VectorT.z) + texInfo.DistT
  886.            
  887.             If (eNr = Self.Ledge_ID) Then
  888.                 'Starting point
  889.                 LightMinUV.x = LightS
  890.                 LightMinUV.y = LightT
  891.                 LightMaxUV.x = LightS
  892.                 LightMaxUV.y = LightT
  893.             Else
  894.                 'Is this a new minimum?
  895.                 If LightS < LightMinUV.x Then LightMinUV.x = LightS
  896.                 If LightT < LightMinUV.y Then LightMinUV.y = LightT
  897.                
  898.                 'Is this a new maximum
  899.                 If LightS > LightMaxUV.x Then LightMaxUV.x = LightS
  900.                 If LightT > LightMaxUV.y Then LightMaxUV.y = LightT
  901.             End If
  902.         Next
  903.        
  904.         'Get distances
  905.         LightDist.x = Ceil(LightMaxUV.x / 16) - Floor(LightMinUV.x / 16)
  906.         LightDist.y = Ceil(LightMaxUV.y / 16) - Floor(LightMinUV.y / 16)
  907.        
  908.         LightMapSize.x = LightDist.x + 1
  909.         LightMapSize.y = LightDist.y + 1
  910.        
  911.         LightDist.x:*16
  912.         LightDist.y:*16
  913.        
  914.         Return LightMapSize
  915.     EndMethod
  916.    
  917.     Method MakeLightmap(bsp:TQBSP)
  918.         If Self.LightMap < 0 Then Return
  919.        
  920.         bsp.Stream.Seek(bsp.Header.LightMaps.Offset + Self.LightMap)
  921.        
  922.         'Local pix:TPixmap = CreatePixmap(LightMapSize.x, LightMapSize.y, PF_RGB888)
  923.        
  924.         If LightMapSize.x <= 0 Or LightMapSize.y <= 0 Then
  925.         '   pix = Null
  926.             Return
  927.         EndIf
  928.        
  929.         If bsp.LightMapPreW + LightMapSize.x >= bsp.LightMapPixmap.width Then
  930.             bsp.LightMapPreW = LIGHT_PAD * 2
  931.             bsp.LightMapPreH:+bsp.LightMapMaxH
  932.             bsp.LightMapMaxH = 0
  933.         EndIf
  934.        
  935.         Self.LightMapPos = New TQVec2
  936.         Self.LightMapPos.x = bsp.LightMapPreW
  937.         Self.LightMapPos.y = bsp.LightMapPreH
  938.        
  939.         Local x:Int
  940.         Local y:Int
  941.         Local color:Int
  942.         For y = 0 Until LightMapSize.y
  943.         For x = 0 Until LightMapSize.x
  944.             color = bsp.Stream.ReadByte() - (Self.BaseLight * bsp.LightMapBaseStr)
  945.             color:+bsp.LightMapBrighness
  946.            
  947.             If color < bsp.LightMapMinBright Then color = bsp.LightMapMinBright
  948.             If color > bsp.LightMapMaxBright Then color = bsp.LightMapMaxBright
  949.            
  950.             'IF Not color Then Continue
  951.             'pix.WritePixel(x, y, GenRGB(color, color, color))
  952.            
  953.             'If x = 0 Or y = 0 Or x = LightMapSize.x - 1 Or y = LightMapSize.y - 1 Then
  954.             '   bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x, bsp.LightMapPreH + y, GenRGB(255, 0, 0))
  955.             'Else
  956.                 bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x, bsp.LightMapPreH + y, GenRGB(color, color, color))
  957.             'EndIf
  958.            
  959.             'Padding
  960.             If y = 0 And x = 0 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x - 1, bsp.LightMapPreH + y - 1, GenRGB(color, color, color))
  961.             If y = 0 And x = LightMapSize.x - 1 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x + 1, bsp.LightMapPreH + y - 1, GenRGB(color, color, color))
  962.            
  963.             If y = LightMapSize.y - 1 And x = 0 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x - 1, bsp.LightMapPreH + y + 1, GenRGB(color, color, color))
  964.             If y = LightMapSize.y - 1 And x = LightMapSize.x - 1 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x + 1, bsp.LightMapPreH + y + 1, GenRGB(color, color, color))
  965.            
  966.             If y = 0 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x, bsp.LightMapPreH + y - 1, GenRGB(color, color, color))
  967.             If x = 0 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x - 1, bsp.LightMapPreH + y, GenRGB(color, color, color))
  968.            
  969.             If y = LightMapSize.y - 1 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x, bsp.LightMapPreH + y + 1, GenRGB(color, color, color))
  970.             If x = LightMapSize.x - 1 Then bsp.LightMapPixmap.WritePixel(bsp.LightMapPreW + x + 1, bsp.LightMapPreH + y, GenRGB(color, color, color))
  971.         Next
  972.         Next
  973.        
  974.         bsp.LightMapPreW:+LightMapSize.x + LIGHT_PAD * 2
  975.         If bsp.LightMapMaxH < Self.LightMapSize.y + LIGHT_PAD Then bsp.LightMapMaxH = Self.LightMapSize.y + LIGHT_PAD
  976.        
  977.         'If FileType(AppDir + "/lightmaps") = FILETYPE_DIR Then SavePixmapPNG(pix, AppDir + "/lightmaps/" + Plane_ID + ".png", 0)
  978.        
  979.         'Self.LightBrush = LoadBrushPixmap(pix, 16 + 32)
  980.         'pix = Null
  981.     EndMethod
  982.    
  983.     Function Size:Int()
  984.         Return (B_SHORT * 4) + (B_INT * 2) + (B_BYTE * 4)
  985.     EndFunction
  986. EndType
  987.  
  988. Type TQMipHeader
  989.     Field NumTex:Int
  990.     Field Offset:Int[]
  991.    
  992.     Field _count:Int
  993.    
  994.     Function Read:TQMipHeader(Stream:TStream)
  995.         Local nM:TQMipHeader = New TQMipHeader
  996.         nM.NumTex = ReadInt(Stream)
  997.        
  998.         'Should I even read this?
  999.         nM.Offset = New Int[nM.NumTex]
  1000.         For Local i:Int = 0 Until nM.NumTex
  1001.             nM.Offset[i] = ReadInt(Stream)
  1002.             nM._count:+1
  1003.         Next
  1004.         Return nM
  1005.     EndFunction
  1006. EndType
  1007.  
  1008. Type TQMipTex
  1009.     Field Name:String
  1010.     Field width:Int
  1011.     Field Height:Int
  1012.     Field Offset1:Int
  1013.     Field Offset2:Int
  1014.     Field Offset4:Int
  1015.     Field Offset8:Int
  1016.    
  1017.     Field Surface:TSurface
  1018.    
  1019.     Field Texture:TTexture
  1020.     Field Brush:TBrush
  1021.    
  1022.     Field AnimStep:Int
  1023.    
  1024.     Function Read:TQMipTex(Stream:TStream)
  1025.         Local nM:TQMipTex = New TQMipTex
  1026.         For Local i:Int = 0 Until 16
  1027.             nM.Name:+Chr(ReadByte(Stream))
  1028.         Next
  1029.         nM.width = ReadInt(Stream)
  1030.         nM.Height = ReadInt(Stream)
  1031.         nM.Offset1 = ReadInt(Stream)
  1032.         nM.Offset2 = ReadInt(Stream)
  1033.         nM.Offset4 = ReadInt(Stream)
  1034.         nM.Offset8 = ReadInt(Stream)
  1035.         Return nM
  1036.     EndFunction
  1037.    
  1038.     Function Size:Int()
  1039.         Return (B_BYTE * 16) + (B_INT * 6)
  1040.     EndFunction
  1041. EndType
  1042.  
  1043. Type TQEntry
  1044.     Field Offset:Int
  1045.     Field Size:Int
  1046.    
  1047.     Function Read:TQEntry(Stream:TStream)
  1048.         Local nE:TQEntry = New TQEntry
  1049.         nE.Offset = ReadInt(Stream)
  1050.         nE.Size = ReadInt(Stream)
  1051.         Return nE
  1052.     EndFunction
  1053.    
  1054.     Method Count:Int(typeSize:Int)
  1055.         Return Size / typeSize
  1056.     EndMethod
  1057.    
  1058.     Method JumpTo(Stream:TStream)
  1059.         Stream.Seek(Self.Offset)
  1060.     EndMethod
  1061. EndType
  1062.  
  1063. Type TQNode
  1064.     Field Plane_ID:Int
  1065.    
  1066.     Field Front:Short
  1067.    
  1068.     Field Back:Short
  1069.    
  1070.     Field Box:TQBBoxShort
  1071.     Field Face_ID:Short
  1072.     Field Face_Num:Short
  1073.    
  1074.     Function Read:TQNode(Stream:TStream)
  1075.         Local nN:TQNode = New TQNode
  1076.         nN.Plane_ID = ReadInt(Stream)
  1077.         nN.Front = ReadShort(Stream)
  1078.         nN.Back = ReadShort(Stream)
  1079.         nN.Box = TQBBoxShort.Read(Stream)
  1080.         nN.Face_ID = ReadShort(Stream)
  1081.         nN.Face_Num = ReadShort(Stream)
  1082.         Return nN
  1083.     EndFunction
  1084. EndType
  1085.  
  1086. Type TQDLeaf
  1087.     Field Typ:Int
  1088.     Field VisList:Int
  1089.    
  1090.     Field Bound:TQBBoxShort
  1091.     Field LFace_ID:Short
  1092.    
  1093.     Field LFace_Num:Short
  1094.     Field SndWater:Byte
  1095.     Field SndSky:Byte
  1096.     Field SndSlime:Byte
  1097.     Field SndLava:Byte
  1098.    
  1099.     Function Read:TQDLeaf(Stream:TStream)
  1100.         Local nD:TQDLeaf = New TQDLeaf
  1101.         nD.Typ = ReadInt(Stream)
  1102.         nD.VisList = ReadInt(Stream)
  1103.        
  1104.         nD.Bound = TQBBoxShort.Read(Stream)
  1105.         nD.LFace_ID = ReadShort(Stream)
  1106.        
  1107.         nD.LFace_Num = ReadShort(Stream)
  1108.         nD.SndWater = ReadByte(Stream)
  1109.         nD.SndSky = ReadByte(Stream)
  1110.         nD.SndSlime = ReadByte(Stream)
  1111.         nD.SndLava = ReadByte(Stream)
  1112.         Return nD
  1113.     EndFunction
  1114. EndType
  1115.  
  1116. Type TQPlane
  1117.     Field Normal:TQVec3
  1118.    
  1119.     Field Dist:Float
  1120.    
  1121.     Field Typ:Int
  1122.    
  1123.     Function Read:TQPlane(Stream:TStream)
  1124.         Local nP:TQPlane = New TQPlane
  1125.         nP.Normal = TQVec3.Read(Stream)
  1126.         nP.Dist = ReadFloat(Stream)
  1127.         nP.Typ = ReadInt(Stream)
  1128.         Return nP
  1129.     EndFunction
  1130.    
  1131.     Function Size:Int()
  1132.         Return B_FLOAT + B_INT + TQVec3.Size()
  1133.     EndFunction
  1134. EndType
  1135.  
  1136. Type TQClipNode
  1137.     Field PlaneNum:Int
  1138.     Field Front:Short
  1139.    
  1140.     Field Back:Short
  1141.    
  1142.     Function Read:TQClipNode(Stream:TStream)
  1143.         Local nC:TQClipNode = New TQClipNode
  1144.         nC.PlaneNum = ReadInt(Stream)
  1145.         nC.Front = ReadShort(Stream)
  1146.         nC.Back = ReadShort(Stream)
  1147.         Return nC
  1148.     EndFunction
  1149. EndType
  1150.  
  1151. Type TQPalette
  1152.     Global colors:TQColor32[]
  1153.    
  1154.     Function LoadPalette(url:String)
  1155.         Local Stream:TStream = OpenStream(url, True, False)
  1156.         If Not Stream Then Print("Unable to load palette ~q" + url + "~q")
  1157.         colors = New TQColor32[Stream.Size() / 3]
  1158.        
  1159.         For Local i:Int = 0 Until colors.Length
  1160.             colors[i] = New TQColor32
  1161.             colors[i].r = Stream.ReadByte()
  1162.             colors[i].g = Stream.ReadByte()
  1163.             colors[i].b = Stream.ReadByte()
  1164.         Next
  1165.        
  1166.         'debug save palette
  1167.         Rem
  1168.         Local pix:TPixmap = CreatePixmap(colors.Length, 8, PF_RGB888)
  1169.         For Local i:Int = 0 Until colors.Length
  1170.             For Local y:Int = 0 Until pix.Height
  1171.                 pix.WritePixel(i, y, GenRGB(colors[i].r, colors[i].g, colors[i].b))
  1172.             Next
  1173.         Next
  1174.         SavePixmapPNG(pix, AppDir + "/palette.png", 9)
  1175.         endrem
  1176.        
  1177.         CloseStream(Stream)
  1178.         DebugLog "Palette: " + url + " @ " + colors.Length + " colors"
  1179.     EndFunction
  1180.    
  1181. EndType
  1182.  
  1183. Type TQColor32
  1184.     Field r:Byte
  1185.     Field g:Byte
  1186.     Field b:Byte
  1187. EndType
  1188.  
  1189. 'Basic types
  1190. Type TQVec3
  1191.     Field X:Float
  1192.     Field Y:Float
  1193.     Field Z:Float
  1194.    
  1195.     Function Read:TQVec3(Stream:TStream)
  1196.         Local nV:TQVec3 = New TQVec3
  1197.         nV.X = ReadFloat(Stream)
  1198.         nV.Y = ReadFloat(Stream)
  1199.         nV.Z = ReadFloat(Stream)
  1200.         Return nV
  1201.     EndFunction
  1202.    
  1203.     Function Size:Int()
  1204.         Return B_FLOAT * 3
  1205.     EndFunction
  1206. EndType
  1207.  
  1208. Type TQVec2
  1209.     Field X:Float
  1210.     Field Y:Float
  1211.    
  1212.     Function Read:TQVec2(Stream:TStream)
  1213.         Local nV:TQVec2 = New TQVec2
  1214.         nV.X = ReadFloat(Stream)
  1215.         nV.Y = ReadFloat(Stream)
  1216.         Return nV
  1217.     EndFunction
  1218.    
  1219.     Function Size:Int()
  1220.         Return B_FLOAT * 2
  1221.     EndFunction
  1222. EndType
  1223.  
  1224. Type TQIntVec2
  1225.     Field X:Int
  1226.     Field Y:Int
  1227.    
  1228.     Function Read:TQIntVec2(Stream:TStream)
  1229.         Local nV:TQIntVec2 = New TQIntVec2
  1230.         nV.X = ReadInt(Stream)
  1231.         nV.Y = ReadInt(Stream)
  1232.         Return nV
  1233.     EndFunction
  1234.    
  1235.     Function Size:Int()
  1236.         Return B_INT * 2
  1237.     EndFunction
  1238. EndType
  1239.  
  1240. Type TQBoundBox
  1241.     Field Minimum:TQVec3
  1242.     Field Maximum:TQVec3
  1243.    
  1244.     Function Read:TQBoundBox(Stream:TStream)
  1245.         Local nB:TQBoundBox = New TQBoundBox
  1246.         nB.Minimum = TQVec3.Read(Stream)
  1247.         nB.Maximum = TQVec3.Read(Stream)
  1248.         Return nB
  1249.     EndFunction
  1250.    
  1251.     Function Size:Int()
  1252.             Return TQVec3.Size() * 2
  1253.     EndFunction
  1254. EndType
  1255.  
  1256. Type TQBBoxShort
  1257.     Field Minimum:Short
  1258.     Field Maximum:Short
  1259.    
  1260.     Function Read:TQBBoxShort(Stream:TStream)
  1261.         Local nB:TQBBoxShort = New TQBBoxShort
  1262.         nB.Minimum = ReadShort(Stream)
  1263.         nB.Maximum = ReadShort(Stream)
  1264.         Return nB
  1265.     EndFunction
  1266.    
  1267.     Function Size:Int()
  1268.         Return B_SHORT * 2
  1269.     EndFunction
  1270. EndType
  1271.  
  1272. 'Common
  1273. Function CrossProduct:TQVec3(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  1274.     Local CProd:TQVec3 = New TQVec3
  1275.     CProd.x = (y1 * z2) - (z1 * y2)
  1276.     CProd.y = (z1 * x2) - (x1 * z2)
  1277.     CProd.z = (x1 * y2) - (y1 * x2)
  1278.     Return CProd
  1279. End Function
  1280. Function DotProduct:Float(x1:Float, y1:Float, z1:Float, x2:Float, y2:Float, z2:Float)
  1281.     Return ((x1 * x2) + (y1 * y2) + (z1 * z2))
  1282. EndFunction
  1283.  
  1284. Function GenRGB:Int(r:Byte, g:Byte, b:Byte, a:Byte = 255)
  1285.     Return (a Shl 24) | (r Shl 16) | (g Shl 8) | b
  1286. EndFunction
  1287.    
  1288. Function GetRGB:Int(argb:Int, a:byte Var, r:byte Var, g:byte Var, b:byte Var)
  1289.     a=(argb Shr 24) & $ff
  1290.     r=(argb Shr 16) & $ff
  1291.     g=(argb Shr 8) & $ff
  1292.     b=argb & $ff
  1293. EndFunction
  1294.  
  1295. Function Pow2Size:Int(n:Int)
  1296.     Local t:Int = 1
  1297.     While t<n
  1298.         t:*2
  1299.     Wend
  1300.     Return t
  1301. EndFunction
  1302.  
  1303. 'Custom brushes
  1304. Function LoadBrushPixmap:TBrush(pixmapin:TPixmap, Flags:Int = 1, u_scale:Float = 1.0, v_scale:Float = 1.0)
  1305.     Return PixTBrush.LoadBrushPixmap(pixmapin, Flags, u_scale, v_scale)
  1306. EndFunction
  1307.  
  1308. Function LoadTexturePixmap:TTexture(pixmapin:TPixmap,flags:Int=1)
  1309.     Return PixTTexture.LoadTexturePixmap(pixmapin, Flags)
  1310. EndFunction
  1311.  
  1312. Type PixTBrush Extends TBrush
  1313.  
  1314.     Function LoadBrushPixmap:TBrush(pixmapin:TPixmap,flags:Int=1,u_scale:Float=1.0,v_scale:Float=1.0)
  1315.    
  1316.         Local brush:TBrush=New TBrush
  1317.        
  1318.         brush.tex[0]=PixTTexture.LoadTexturePixmap:TTexture(pixmapin,flags)
  1319.         brush.no_texs=1
  1320.        
  1321.         'brush.tex[0].u_scale#=u_scale#
  1322.         'brush.tex[0].v_scale#=v_scale#
  1323.        
  1324.         pixmapin = Null
  1325.                
  1326.         Return brush
  1327.        
  1328.     EndFunction
  1329. EndType
  1330.  
  1331. Type PixTTexture Extends TTexture
  1332.  
  1333.     Function LoadTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int=1,tex:TTexture=Null)
  1334.    
  1335.         Return LoadAnimTexturePixMap:TTexture(pixmapin,flags,0,0,0,1,tex)
  1336.        
  1337.     End Function
  1338.  
  1339.     Function LoadAnimTexturePixMap:TTexture(pixmapin:TPixmap,flags:Int,frame_width:Int,frame_height:Int,first_frame:Int,frame_count:Int,tex:TTexture=Null)
  1340.    
  1341.         Local pixmapFileName:String="pixmap"+MilliSecs()+Rnd()
  1342.        
  1343.         If flags&128 Then Return LoadCubeMapTexture(pixmapFileName$,flags,tex)
  1344.    
  1345.         If tex=Null Then tex:TTexture=New TTexture
  1346.        
  1347.         tex.file:String=pixmapFileName
  1348.         tex.file_abs:String=pixmapFileName
  1349.        
  1350.         ' set tex.flags before TexInList
  1351.         tex.flags=flags
  1352.         tex.FilterFlags()
  1353.        
  1354.         ' check to see if texture with same properties exists already, if so return existing texture
  1355.         Local old_tex:TTexture
  1356.         old_tex=tex.TexInList()
  1357.         If old_tex<>Null And old_tex<>tex
  1358.             Return old_tex
  1359.         Else
  1360.             If old_tex<>tex
  1361.                 ListAddLast(tex_list,tex)
  1362.             EndIf
  1363.         EndIf
  1364.    
  1365.         ' load pixmap
  1366.         tex.pixmap = CopyPixmap(pixmapin)
  1367.        
  1368.         ' check to see if pixmap contain alpha layer, set alpha_present to true if so (do this before converting)
  1369.         Local alpha_present:Int=False
  1370.         If tex.pixmap.format=PF_RGBA8888 Or tex.pixmap.format=PF_BGRA8888 Or tex.pixmap.format=PF_A8 Then alpha_present=True
  1371.    
  1372.         ' convert pixmap to appropriate format
  1373.         If tex.pixmap.format<>PF_RGBA8888
  1374.             tex.pixmap=tex.pixmap.Convert(PF_RGBA8888)
  1375.         EndIf
  1376.        
  1377.         ' if alpha flag is true and pixmap doesn't contain alpha info, apply alpha based on color values
  1378.         If tex.flags&2 And alpha_present=False
  1379.             tex.pixmap=ApplyAlpha(tex.pixmap)
  1380.         EndIf      
  1381.    
  1382.         ' if mask flag is true, mask pixmap
  1383.         If tex.flags&4
  1384.             tex.pixmap=MaskPixmap(tex.pixmap,0,0,0)
  1385.         EndIf
  1386.        
  1387.         ' ---
  1388.        
  1389.         ' if tex not anim tex, get frame width and height
  1390.         If frame_width=0 And frame_height=0
  1391.             frame_width=tex.pixmap.width
  1392.             frame_height=tex.pixmap.height
  1393.         EndIf
  1394.    
  1395.         ' ---
  1396.        
  1397.         tex.no_frames=frame_count
  1398.         tex.gltex=tex.gltex[..tex.no_frames]
  1399.    
  1400.         ' ---
  1401.        
  1402.         ' pixmap -> tex
  1403.    
  1404.         Local xframes:Int=tex.pixmap.width/frame_width
  1405.         Local yframes:Int=tex.pixmap.height/frame_height
  1406.            
  1407.         Local startx:Int=first_frame Mod xframes
  1408.         Local starty:Int=(first_frame/yframes) Mod yframes
  1409.            
  1410.         Local x:Int=startx
  1411.         Local y:Int=starty
  1412.    
  1413.         Local pixmap:TPixmap
  1414.    
  1415.         For Local i:Int=0 To tex.no_frames-1
  1416.    
  1417.             ' get static pixmap window. when resize pixmap is called new pixmap will be returned.
  1418.             pixmap=tex.pixmap.Window(x*frame_width,y*frame_height,frame_width,frame_height)
  1419.             x=x+1
  1420.             If x>=xframes
  1421.                 x=0
  1422.                 y=y+1
  1423.             EndIf
  1424.        
  1425.             ' ---
  1426.        
  1427.             pixmap=AdjustPixmap(pixmap)
  1428.             tex.width=pixmap.width
  1429.             tex.height=pixmap.height
  1430.             Local width:Int=pixmap.width
  1431.             Local height:Int=pixmap.height
  1432.    
  1433.             Local name:Int
  1434.             glGenTextures 1,Varptr name
  1435.             glBindtexture GL_TEXTURE_2D,name
  1436.    
  1437.             Local mipmap:Int
  1438.             If tex.flags&8 Then mipmap=True
  1439.             Local mip_level:Int=0
  1440.             Repeat
  1441.                 glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
  1442.                 glTexImage2D GL_TEXTURE_2D,mip_level,GL_RGBA8,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
  1443.                 If Not mipmap Then Exit
  1444.                 If width=1 And height=1 Exit
  1445.                 If width>1 width:/2
  1446.                 If height>1 height:/2
  1447.    
  1448.                 pixmap=ResizePixmap(pixmap,width,height)
  1449.                 mip_level:+1
  1450.             Forever
  1451.             tex.no_mipmaps=mip_level
  1452.    
  1453.             tex.gltex[i]=name
  1454.    
  1455.         Next
  1456.                
  1457.         tex.pixmap = Null
  1458.                
  1459.         Return tex
  1460.        
  1461.     End Function
  1462. EndType
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement