Author Topic: Quake 3 Level Loader - Work in progress  (Read 3656 times)

0 Members and 1 Guest are viewing this topic.

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Quake 3 Level Loader - Work in progress
« on: July 01, 2020, 07:34:37 am »
Hi Folks,

So i decided to attempt adding level support to GDK_GL. I looked into it and decided that i'd do Quake 3 levels first (if i can get this working then apparently Quake 2 and Quake 1 levels require just a few modifications to the loader code).

ID games use Binary Space Partitioning for their levels which is WAY over my understanding (at present) so i know i'll come across problems in trying to get this to work.

The resource : http://www.mralligator.com/q3/

So far all i've done is convert the structures to QB64 type defintions (cause we can't use arrays inside types i've had to make a few of my own custom types and WILL have to use _MEM for a few bits later on.

Code: QB64: [Select]
  1. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2. '//                                Quake 3 .BSP File loader v.01                              \\
  3. '//                             By John Onyon a.k.a Unseen Machine                            \\
  4. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  5.  
  6. SUB BSP_TYPE_DEFS
  7.  
  8.  '// BSP_Float2/3, BSP_Int2/3, BSP_RGBA, BSP_LM_VEC and BSP_Light are used where arrays inside types are needed.
  9.  TYPE BSP_Float2
  10.   Flt1 AS SINGLE
  11.   Flt2 AS SINGLE
  12.  
  13.  TYPE BSP_Float3
  14.   X AS SINGLE
  15.   Y AS SINGLE
  16.   Z AS SINGLE
  17.  
  18.  TYPE BSP_Int2
  19.   Int1 AS INTEGER
  20.   Int2 AS INTEGER
  21.  
  22.  TYPE BSP_Int3
  23.   Int1 AS INTEGER
  24.   Int2 AS INTEGER
  25.   Int3 AS INTEGER
  26.  
  27.  TYPE BSP_RGBA
  28.  
  29.  TYPE BSP_LM_Vec
  30.   Set1 AS BSP_Float3
  31.   Set2 AS BSP_Float3
  32.  
  33.  TYPE BSP_Light
  34.  
  35.  TYPE BSP_DirEntry
  36.   Start AS INTEGER '// Offset into file
  37.   Size AS INTEGER '// How big (number of bytes) it is
  38.  
  39.  TYPE BSP_HEADER
  40.   Magic AS STRING * 4 '// Magic number. Always "IBSP".
  41.   Version AS INTEGER '//  0x2e for the BSP files distributed with Quake 3.
  42.   DirEntries AS _MEM '// Lump directory, seventeen entrie of type BSP_DirEntry
  43.  
  44.  TYPE BSP_TEXTURE
  45.   Name AS STRING * 64
  46.   Flags AS INTEGER
  47.   Contents AS INTEGER
  48.  
  49.  TYPE BSP_Plane
  50.   Normal AS BSP_Float3
  51.   Distance AS SINGLE
  52.  
  53.  TYPE BSP_Node
  54.   Plane AS INTEGER '// Plane index.
  55.   Children AS BSP_Int2 '// Children indices. Negative numbers are leaf indices: -(leaf+1).
  56.   Mins AS BSP_Int3 '// Integer bounding box min coord.
  57.   Maxs AS BSP_Int3 '//
  58.  
  59.  TYPE BSP_Leaf
  60.   Cluster AS INTEGER '//  Visdata cluster index.
  61.   Area AS INTEGER '// Areaportal area.
  62.   Mins AS BSP_Int3 '// Integer bounding box min coord.
  63.   Maxs AS BSP_Int3 '// Integer bounding box max coord.
  64.   LeafFace AS INTEGER '// First leafface for leaf.
  65.   NumLeafFaces AS INTEGER '// Number of leaffaces for leaf.
  66.   LeafBrush AS INTEGER '// First leafbrush for leaf.
  67.   NumLeafBrushes AS INTEGER '// Number of leafbrushes for leaf.
  68.  
  69.  TYPE BSP_LeafFace
  70.   Face AS INTEGER '// Face index.
  71.  
  72.  TYPE BSP_LeafBrush
  73.   Brush AS INTEGER '// Brush index.
  74.  
  75.  TYPE BSP_Model
  76.   Mins AS BSP_Float3 '// Bounding box min coord.
  77.   Maxs AS BSP_Float3 '// Bounding box max coord.
  78.   Face AS INTEGER '// First face for model.
  79.   NumFaces AS INTEGER '//  Number of faces for model.
  80.   Brush AS INTEGER '// First brush for model.
  81.   NumBrushes AS INTEGER '// Number of brushes for model.
  82.  
  83.  TYPE BSP_Brush
  84.   BrushSide AS INTEGER '// First brushside for brush.
  85.   NumBrushSides AS INTEGER '// Number of brushsides for brush.
  86.   Texture AS INTEGER '// Texture index.
  87.  
  88.  TYPE BSP_BrushSide
  89.   Plane AS INTEGER '//  Plane index.
  90.   Texture AS INTEGER '// Texture index.
  91.  
  92.  TYPE BSP_Vertex
  93.   Position AS BSP_Float3 '// Vertex position.
  94.   TexCoord_Surface AS BSP_Float2 '//  Vertex texture coordinates. 0=surface, 1=lightmap.
  95.   TexCoord_Lightmap AS BSP_Float2
  96.   Normal AS BSP_Float3 '// Vertex normal.
  97.   Color AS BSP_RGBA '// Vertex color. RGBA.
  98.  
  99.  TYPE BSP_MeshVert
  100.   Offset AS INTEGER '// Vertex index offset, relative to first vertex of corresponding face.
  101.  
  102.  TYPE BSP_Effect
  103.   Name AS STRING * 64 '// Effect shader.
  104.   Brush AS INTEGER '// Brush that generated this effect.
  105.   Unknown AS INTEGER 'Always 5, except in q3dm8, which has one effect with -1.
  106.  
  107.  TYPE BSP_Face
  108.   Texture AS INTEGER '// Texture index.
  109.   Effect AS INTEGER '// Index into lump 12 (Effects), or -1.
  110.   FaceType AS INTEGER '// Face type. 1=polygon, 2=patch, 3=mesh, 4=billboard
  111.   Vertex AS INTEGER '// Index of first vertex.
  112.   NumVertexes AS INTEGER '// Number of vertices.
  113.   MeshVert AS INTEGER '// Index of first meshvert.
  114.   NumMeshVerts AS INTEGER '// Number of meshverts.
  115.   LMIndex AS INTEGER '// Lightmap index.
  116.   LMStart AS BSP_Int2 '// Corner of this face's lightmap image in lightmap.
  117.   LMSize AS BSP_Int2 '// Size of this face's lightmap image in lightmap.
  118.   LMOrigin AS BSP_Float3 '// World space origin of lightmap.
  119.   LMVecs AS BSP_LM_Vec '// World space lightmap s and t unit vectors.
  120.   Normal AS BSP_Float3 '// Surface normal.
  121.   Size AS BSP_Int2 '// Patch dimensions.
  122.  
  123.  TYPE BSP_LightVol
  124.   Ambient AS BSP_Light '// Ambient color component. RGB.
  125.   Directional AS BSP_Light '// Directional color component. RGB.
  126.   LightDirPhi AS _UNSIGNED _BYTE '//  Direction to light. 0=phi, 1=theta.
  127.   LightDirtheta AS _UNSIGNED _BYTE '//  Direction to light. 0=phi, 1=theta.
  128.  
  129.  TYPE BSP_VisData
  130.   NumVecs AS INTEGER '// Number of vectors.
  131.   SizeVecs AS INTEGER '// Size of each vector, in bytes.
  132.   Vecs AS _MEM 'ubyte[n_vecs * sz_vecs] vecs  Visibility data. One bit per cluster per vector.
  133.  
  134.  
  135.  
  136. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  137.  
  138.  

When you start with that many typedefs you know this project is gonna be a BIG one!

Anyone who would like to help me in getting this further down the road please speak up and we can discuss where to go from here...finding a quake 3 .bsp to load is the first step cause i'e not got one yet!

Thanks folks,

Unseen

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #1 on: July 02, 2020, 09:02:02 am »
Hi Folks,

Just an update, thanks to steve i've now got a (almost) complete .bsp loader. (I've ignored entities and light map textures for the time being)

Code: QB64: [Select]
  1. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2. '//                                Quake 3 .BSP File loader v.01                              \\
  3. '//                             By John Onyon a.k.a Unseen Machine                            \\
  4. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  5.  
  6. '// TEMP Consts
  7. CONST True = -1, False = 0
  8.  
  9. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  10. '// File path
  11. Root$ = "C:\qb64\3d Programs\bsp\MAPS" '// Level Directory
  12. CHDIR Root$ '// Change directory to where our stuff is
  13.  
  14. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  15. '// Load the level
  16. DIM Level AS Level '// DIM the memory for the level
  17. 'LoadState& = BSP_Load(Level, "q3Dead1.bsp") '// Load the level data
  18. LoadState& = BSP_Load(Level, "q3shw24.bsp") '// Load the level data
  19.  
  20. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  21.  
  22. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  23. '// GDK_GL - New type definition for handling levels.
  24.  
  25. SUB GDK_GL_TYPEDEFS
  26.  TYPE Level
  27.   ID AS _BYTE '// Signifies the type of level (currently irrelevant as we dont support any other level formats)
  28.   HeaderPntr AS _MEM '// Level information header
  29.   DataPntr AS _MEM '// Level data - verts, normals, textures etc...
  30.  
  31. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  32.  
  33. SUB BSP_TYPE_DEFS
  34.  
  35.  '// BSP_Float2/3, BSP_Int2/3, BSP_RGBA, BSP_LM_VEC and BSP_Light are used where arrays inside types are needed.
  36.  TYPE BSP_Float2
  37.   Flt1 AS SINGLE
  38.   Flt2 AS SINGLE
  39.  
  40.  TYPE BSP_Float3
  41.   X AS SINGLE
  42.   Y AS SINGLE
  43.   Z AS SINGLE
  44.  
  45.  TYPE BSP_Int2
  46.   Int1 AS LONG
  47.   Int2 AS LONG
  48.  
  49.  TYPE BSP_Int3
  50.   Int1 AS LONG
  51.   Int2 AS LONG
  52.   Int3 AS LONG
  53.  
  54.  TYPE BSP_RGBA
  55.  
  56.  TYPE BSP_LM_Vec
  57.   Set1 AS BSP_Float3
  58.   Set2 AS BSP_Float3
  59.  
  60.  TYPE BSP_Light
  61.  
  62.  TYPE BSP_DirEntry
  63.   Start AS LONG '// Offset into file
  64.   Size AS LONG '// How big (number of bytes) it is
  65.  
  66.  TYPE BSP_Header
  67.   Magic AS STRING * 4 '// Magic number. Always "IBSP".
  68.   Version AS LONG '//  0x2e for the BSP files distributed with Quake 3.
  69.   DirEntries AS _MEM '// Lump directory, seventeen entries of type BSP_DirEntry
  70.  
  71.  TYPE BSP_Texture
  72.   Name AS STRING * 64
  73.   Flags AS LONG
  74.   Contents AS LONG
  75.  
  76.  TYPE BSP_Plane
  77.   Normal AS BSP_Float3
  78.   Distance AS SINGLE
  79.  
  80.  TYPE BSP_Node
  81.   Plane AS LONG '// Plane index.
  82.   Children AS BSP_Int2 '// Children indices. Negative numbers are leaf indices: -(leaf+1).
  83.   Mins AS BSP_Int3 '// LONG bounding box min coord.
  84.   Maxs AS BSP_Int3 '//
  85.  
  86.  TYPE BSP_Leaf
  87.   Cluster AS LONG '//  Visdata cluster index.
  88.   Area AS LONG '// Areaportal area.
  89.   Mins AS BSP_Int3 '// LONG bounding box min coord.
  90.   Maxs AS BSP_Int3 '// LONG bounding box max coord.
  91.   LeafFace AS LONG '// First leafface for leaf.
  92.   NumLeafFaces AS LONG '// Number of leaffaces for leaf.
  93.   LeafBrush AS LONG '// First leafbrush for leaf.
  94.   NumLeafBrushes AS LONG '// Number of leafbrushes for leaf.
  95.  
  96.  TYPE BSP_LeafFace
  97.   Face AS LONG '// Face index.
  98.  
  99.  TYPE BSP_LeafBrush
  100.   Brush AS LONG '// Brush index.
  101.  
  102.  TYPE BSP_Model
  103.   Mins AS BSP_Float3 '// Bounding box min coord.
  104.   Maxs AS BSP_Float3 '// Bounding box max coord.
  105.   Face AS LONG '// First face for model.
  106.   NumFaces AS LONG '//  Number of faces for model.
  107.   Brush AS LONG '// First brush for model.
  108.   NumBrushes AS LONG '// Number of brushes for model.
  109.  
  110.  TYPE BSP_Brush
  111.   BrushSide AS LONG '// First brushside for brush.
  112.   NumBrushSides AS LONG '// Number of brushsides for brush.
  113.   Texture AS LONG '// Texture index.
  114.  
  115.  TYPE BSP_BrushSide
  116.   Plane AS LONG '//  Plane index.
  117.   Texture AS LONG '// Texture index.
  118.  
  119.  TYPE BSP_Vertex
  120.   Position AS BSP_Float3 '// Vertex position.
  121.   TexCoord_Surface AS BSP_Float2 '//  Vertex texture coordinates. 0=surface, 1=lightmap.
  122.   TexCoord_Lightmap AS BSP_Float2
  123.   Normal AS BSP_Float3 '// Vertex normal.
  124.   Color AS BSP_RGBA '// Vertex color. RGBA.
  125.  
  126.  TYPE BSP_MeshVert
  127.   Offset AS LONG '// Vertex index offset, relative to first vertex of corresponding face.
  128.  
  129.  TYPE BSP_Effect
  130.   Name AS STRING * 64 '// Effect shader.
  131.   Brush AS LONG '// Brush that generated this effect.
  132.   Unknown AS LONG 'Always 5, except in q3dm8, which has one effect with -1.
  133.  
  134.  TYPE BSP_Face
  135.   Texture AS LONG '// Texture index.
  136.   Effect AS LONG '// Index into lump 12 (Effects), or -1.
  137.   FaceType AS LONG '// Face type. 1=polygon, 2=patch, 3=mesh, 4=billboard
  138.   Vertex AS LONG '// Index of first vertex.
  139.   NumVertexes AS LONG '// Number of vertices.
  140.   MeshVert AS LONG '// Index of first meshvert.
  141.   NumMeshVerts AS LONG '// Number of meshverts.
  142.   LMIndex AS LONG '// Lightmap index.
  143.   LMStart AS BSP_Int2 '// Corner of this face's lightmap image in lightmap.
  144.   LMSize AS BSP_Int2 '// Size of this face's lightmap image in lightmap.
  145.   LMOrigin AS BSP_Float3 '// World space origin of lightmap.
  146.   LMVecs AS BSP_LM_Vec '// World space lightmap s and t unit vectors.
  147.   Normal AS BSP_Float3 '// Surface normal.
  148.   Size AS BSP_Int2 '// Patch dimensions.
  149.  
  150.  TYPE BSP_LightVol
  151.   Ambient AS BSP_Light '// Ambient color component. RGB.
  152.   Directional AS BSP_Light '// Directional color component. RGB.
  153.   LightDirPhi AS _UNSIGNED _BYTE '//  Phi - Direction to light.
  154.   LightDirTheta AS _UNSIGNED _BYTE '//  Teta - Direction to light.
  155.  
  156.  TYPE BSP_VisData
  157.   NumVecs AS LONG '// Number of vectors.
  158.   SizeVecs AS LONG '// Size of each vector, in bytes.
  159.   Vecs AS _MEM 'ubyte[numvecs * sizevecs] vecs  '// Visibility data. One bit per cluster per vector.
  160.  
  161.  
  162. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  163.  
  164. '// Master function returns true (-1) if all was ok, or false (0) if failiure.
  165. FUNCTION BSP_Load (Level AS Level, File$)
  166.  
  167.  InFile = FREEFILE '// Get a free file handle
  168.  OPEN File$ FOR BINARY AS #InFile '// Open the file
  169.  
  170.  BytePos& = 1 '// Byte position variable
  171.  
  172.  '// DIM header
  173.  DIM Header AS BSP_Header
  174.  GET #InFile, BytePos&, Header.Magic '// Get the id, if not "IBSP" then failiure
  175.  IF Header.Magic = "IBSP" THEN '// Valid file
  176.   BytePos& = BytePos& + LEN(Header.Magic) '// Byte position increment
  177.   GET #InFile, BytePos&, Header.Version '// Get the version id
  178.   IF Header.Version = 46 THEN '// Valid format (Quake 3 level)
  179.    BytePos& = BytePos& + LEN(Header.Version) '// Byte position increment
  180.  
  181.    DIM Entry(16) AS BSP_DirEntry
  182.    GET #InFile, BytePos&, Entry() '// Load all the offsets
  183.  
  184.    Level.HeaderPntr = _MEMNEW(LEN(Header.Magic) + LEN(Header.Version) + (LEN(Entry(0)) * 17)) '// Allocate memory
  185.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET, Header.Magic
  186.    MemOffset& = LEN(Header.Magic)
  187.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET + MemOffset&, Header.Version
  188.    MemOffset& = MemOffset& + LEN(Header.Version)
  189.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET + MemOffset&, Entry()
  190.  
  191.    '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  192.    '// We dont care about certain things in the file for now, we just want rendering and clipping data
  193.    '// Need to calculate required memory block and then load data
  194.    '// Create single defintions of each required type to use in caluation
  195.  
  196.    FOR Index& = 0 TO 16
  197.  
  198.     BytePos& = Entry(Index&).Start '// Offset of where data starts
  199.  
  200.     SELECT CASE Index&
  201.      CASE 0 '// Entities  Game-related object descriptions. - We are not gonna worry about these for now
  202.      CASE 1 '// Textures  Surface descriptions.
  203.  
  204.       DIM Tmp_Texture AS BSP_Texture
  205.       NumTXRecs& = Entry(Index&).Size / LEN(Tmp_Texture)
  206.       DIM Texture(NumTXRecs& - 1) AS BSP_Texture
  207.       GET #InFile, BytePos&, Texture()
  208.  
  209.      CASE 2 '// Planes  Planes used by map geometry.
  210.  
  211.       DIM TmpPlane AS BSP_Plane
  212.       NumPLRecs& = Entry(Index&).Size / LEN(TmpPlane)
  213.       DIM Plane(NumPLRecs& - 1) AS BSP_Plane
  214.       GET #InFile, BytePos&, Plane()
  215.  
  216.      CASE 3 '// Nodes  BSP tree nodes.
  217.  
  218.       DIM TmpNode AS BSP_Node
  219.       NumNodeRecs& = Entry(Index&).Size / LEN(TmpNode)
  220.       DIM Node(NumNodeRecs& - 1) AS BSP_Node
  221.       GET #InFile, BytePos&, Node()
  222.  
  223.      CASE 4 '// Leafs  BSP tree leaves.
  224.  
  225.       DIM TmpLeaf AS BSP_Leaf
  226.       NumLeafRecs& = Entry(Index&).Size / LEN(TmpLeaf)
  227.       DIM Leaf(NumLeafRecs& - 1) AS BSP_Leaf
  228.       GET #InFile, BytePos&, Leaf()
  229.  
  230.      CASE 5 '// Leaffaces  Lists of face indices, one list per leaf.
  231.  
  232.       DIM TmpLF AS BSP_LeafFace
  233.       NumLFRecs& = Entry(Index&).Size / LEN(TmpLF)
  234.       DIM LeafFace(NumLFRecs& - 1) AS BSP_LeafFace
  235.       GET #InFile, BytePos&, LeafFace()
  236.  
  237.      CASE 6 '// Leafbrushes  Lists of brush indices, one list per leaf.
  238.  
  239.       DIM TmpLB AS BSP_LeafBrush
  240.       NumLBRecs& = Entry(Index&).Size / LEN(TmpLB)
  241.       DIM LeafBrush(NumLBRecs& - 1) AS BSP_LeafBrush
  242.       GET #InFile, BytePos&, LeafBrush()
  243.  
  244.      CASE 7 '// Models  Descriptions of rigid world geometry in map.
  245.  
  246.       DIM TmpMDL AS BSP_Model
  247.       NumMDLRecs& = Entry(Index&).Size / LEN(TmpMDL)
  248.       DIM BSPMDL(NumMDLRecs& - 1) AS BSP_Model
  249.       GET #InFile, BytePos&, BSPMDL()
  250.  
  251.      CASE 8 '// Brushes  Convex polyhedra used to describe solid space.
  252.  
  253.       DIM TmpBrush AS BSP_Brush
  254.       NumBRecs& = Entry(Index&).Size / LEN(TmpBrush)
  255.       DIM Brush(NumBRecs& - 1) AS BSP_Brush
  256.       GET #InFile, BytePos&, Brush()
  257.  
  258.      CASE 9 '// Brushsides  Brush surfaces.
  259.  
  260.       DIM TmpBS AS BSP_BrushSide
  261.       NumBSRecs& = Entry(Index&).Size / LEN(TmpBS)
  262.       DIM BrushSide(NumBSRecs& - 1) AS BSP_BrushSide
  263.       GET #InFile, BytePos&, BrushSide()
  264.  
  265.      CASE 10 '// Vertexes  Vertices used to describe faces.
  266.  
  267.       DIM TmpVert AS BSP_Vertex
  268.       NumVRecs& = Entry(Index&).Size / LEN(TmpVert)
  269.       DIM Vertex(NumVRecs& - 1) AS BSP_Vertex
  270.       GET #InFile, BytePos&, Vertex()
  271.  
  272.      CASE 11 '// Meshverts  Lists of offsets, one list per mesh.
  273.  
  274.       DIM TmpMVert AS BSP_MeshVert
  275.       NumMVRecs& = Entry(Index&).Size / LEN(TmpMVert)
  276.       DIM MeshVertex(NumMVRecs& - 1) AS BSP_MeshVert
  277.       GET #InFile, BytePos&, MeshVertex()
  278.  
  279.      CASE 12 '// Effects  List of special map effects.
  280.  
  281.       DIM TmpEffect AS BSP_Effect
  282.       NumEFRecs& = Entry(Index&).Size / LEN(TmpEffect)
  283.       DIM Effect(NumEFRecs& - 1) AS BSP_Effect
  284.       GET #InFile, BytePos&, Effect()
  285.  
  286.      CASE 13 '// Faces  Surface geometry.
  287.  
  288.       DIM TmpFace AS BSP_Face
  289.       NumFaceRecs& = Entry(Index&).Size / LEN(TmpFace)
  290.       DIM Face(NumFaceRecs& - 1) AS BSP_Face
  291.       GET #InFile, BytePos&, Face()
  292.  
  293.      CASE 14 '// Lightmaps  Packed lightmap data.
  294.  
  295.       '// array of (127,127,3) Using RGB
  296.       '// Gonna ignore this for now
  297.  
  298.      CASE 15 '// Lightvols  Local illumination data.
  299.  
  300.       DIM TmpLVols AS BSP_LightVol
  301.       NumLVRecs& = Entry(Index&).Size / LEN(TmpLVols)
  302.       DIM LightVol(NumLVRecs& - 1) AS BSP_LightVol
  303.       GET #InFile, BytePos&, LightVol()
  304.  
  305.      CASE 16 '// Visdata  Cluster-cluster visibility data.
  306.  
  307.       DIM TmpVD AS BSP_VisData
  308.       NumVDRecs& = Entry(Index&).Size / LEN(TmpVD)
  309.       DIM VD(NumVDRecs& - 1) AS BSP_VisData
  310.       GET #InFile, BytePos&, VD()
  311.  
  312.     END SELECT
  313.  
  314.    NEXT
  315.  
  316.    '// Add up size of all the arrays and create _MEM block
  317.  
  318.    '// Put data in to _MEM
  319.  
  320.    BSP_Load = True '// All good!
  321.   ELSE
  322.    BSP_Load = False
  323.   END IF
  324.   BSP_Load = False
  325.  '// All done now so close the file
  326.  CLOSE #InFile
  327.  
  328.  
  329. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  330.  
  331.  
  332.  

Now comes the hard part, make the render bit!

Unseen

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #2 on: July 04, 2020, 02:58:46 am »
Well, after careful consideration i've decided that i'm going to do this a different way.

Currently i've gone about it the same way i have done with my model loaders, unpacking the data, sticking it into a custom type that utilises _MEM and then getting that data back out from _MEM each time i need to render it. Cause models are small files it's a fast enough method for the time being (until we get arrays inside type's), but these .bsp level's i'm working with! They aint so small and asking my cpu to unpack maybe 10meg of data 30 times a second to draw it is a bit of an ask!

So, after mulling it over i realised that as, unlike model files where there are often many in a level, there is only one level at a time! This means (i think) i can use a .bi file to store all the required arrays and stuff meaning it'll only need to be unpacked once! I'll be doing this thanks to REDIM SHARED!!!

So i'll be rewriting a lot of code over this weekend and i'll report back on my results, till then, here is where i'd got to with the loader in this form. Oh, and i just bought the quake pack of steam (£5) and got quake 1/2/3 and 6 different mission packs, what a deal!

Code: QB64: [Select]
  1. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  2. '//                                Quake 3 .BSP File loader v.01                              \\
  3. '//                             By John Onyon a.k.a Unseen Machine                            \\
  4. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  5.  
  6. REM $INCLUDE:'GDK_GL\GDK_GL.bi'
  7.  
  8. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  9. '// File path
  10. Root$ = "C:\qb64\3d Programs\bsp" '// BSP Directory
  11. CHDIR Root$ '// Change directory to where our stuff is
  12.  
  13. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  14. '// Load the level
  15. DIM SHARED Level AS Level '// DIM the memory for the level
  16.  
  17. DIM SHARED KB(1) AS KeyBoardState, Mouse(1) AS MouseState '// Input handlers
  18. DIM SHARED AllowGL AS _BYTE, InitGl AS _BYTE
  19.  
  20. SCREEN _NEWIMAGE(800, 600, 32)
  21. SLEEP 1 '// Give the screen time to be created
  22.  
  23. InitGl = True
  24. AllowGL = True
  25.  
  26.  
  27.  
  28.  _LIMIT 30
  29.  
  30.  'CLS
  31.  
  32.  '// Input
  33.  GDK_Keyboard_GetState KB(0)
  34.  GDK_Mouse_GetState Mouse(0)
  35.  
  36.  '// Logic
  37.  
  38.  
  39.  '_DISPLAY
  40.  
  41.  _DELAY .005 '// Give the CPU Breather
  42.  
  43.  '// Copy input handlers
  44.  Mouse(1) = Mouse(0)
  45.  KB(1) = KB(0)
  46.  
  47. LOOP UNTIL KB(0).ESC
  48.  
  49. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  50.  
  51. REM $INCLUDE:'UnseenGDK.bm'
  52.  
  53. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  54. '//                 GDK_GL - New type definition for handling .bsp levels.                    \\
  55.  
  56. SUB GDK_GL_TYPEDEFS
  57.  TYPE Level
  58.   ID AS _BYTE '// Signifies the type of level (currently irrelevant as we dont support any other level formats)
  59.   HeaderPntr AS _MEM '// Level information header
  60.   DataPntr AS _MEM '// Level data - verts, normals, texture names etc...
  61.   TexturePntr AS _MEM '// A series of _unsigned longs of loaded textures
  62.  
  63. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  64.  
  65. SUB BSP_TYPE_DEFS
  66.  
  67.  
  68.  '// BSP_Float2/3, BSP_Int2/3, BSP_RGBA, BSP_LM_VEC and BSP_Light are used where arrays inside types are needed.
  69.  TYPE BSP_Float2
  70.   Flt1 AS SINGLE
  71.   Flt2 AS SINGLE
  72.  
  73.  TYPE BSP_Float3
  74.   X AS SINGLE
  75.   Y AS SINGLE
  76.   Z AS SINGLE
  77.  
  78.  TYPE BSP_Int2
  79.   Int1 AS LONG
  80.   Int2 AS LONG
  81.  
  82.  TYPE BSP_Int3
  83.   Int1 AS LONG
  84.   Int2 AS LONG
  85.   Int3 AS LONG
  86.  
  87.  TYPE BSP_RGBA
  88.  
  89.  TYPE BSP_LM_Vec
  90.   Set1 AS BSP_Float3
  91.   Set2 AS BSP_Float3
  92.  
  93.  TYPE BSP_Light
  94.  
  95.  TYPE BSP_DirEntry
  96.   Start AS LONG '// Offset into file
  97.   Size AS LONG '// How big (number of bytes) it is
  98.  
  99.  TYPE BSP_Header
  100.   Magic AS STRING * 4 '// Magic number. Always "IBSP".
  101.   Version AS LONG '//  0x2e for the BSP files distributed with Quake 3.
  102.   DirEntries AS _MEM '// Lump directory, seventeen entries of type BSP_DirEntry
  103.  
  104.  TYPE BSP_Texture
  105.   Name AS STRING * 64
  106.   Flags AS LONG
  107.   Contents AS LONG
  108.  
  109.  TYPE BSP_Plane
  110.   Normal AS BSP_Float3
  111.   Distance AS SINGLE
  112.  
  113.  TYPE BSP_Node
  114.   Plane AS LONG '// Plane index.
  115.   Children AS BSP_Int2 '// Children indices. Negative numbers are leaf indices: -(leaf+1).
  116.   Mins AS BSP_Int3 '// LONG bounding box min coord.
  117.   Maxs AS BSP_Int3 '//
  118.  
  119.  TYPE BSP_Leaf
  120.   Cluster AS LONG '//  Visdata cluster index.
  121.   Area AS LONG '// Areaportal area.
  122.   Mins AS BSP_Int3 '// LONG bounding box min coord.
  123.   Maxs AS BSP_Int3 '// LONG bounding box max coord.
  124.   LeafFace AS LONG '// First leafface for leaf.
  125.   NumLeafFaces AS LONG '// Number of leaffaces for leaf.
  126.   LeafBrush AS LONG '// First leafbrush for leaf.
  127.   NumLeafBrushes AS LONG '// Number of leafbrushes for leaf.
  128.  
  129.  TYPE BSP_LeafFace
  130.   Face AS LONG '// Face index.
  131.  
  132.  TYPE BSP_LeafBrush
  133.   Brush AS LONG '// Brush index.
  134.  
  135.  TYPE BSP_Model
  136.   Mins AS BSP_Float3 '// Bounding box min coord.
  137.   Maxs AS BSP_Float3 '// Bounding box max coord.
  138.   Face AS LONG '// First face for model.
  139.   NumFaces AS LONG '//  Number of faces for model.
  140.   Brush AS LONG '// First brush for model.
  141.   NumBrushes AS LONG '// Number of brushes for model.
  142.  
  143.  TYPE BSP_Brush
  144.   BrushSide AS LONG '// First brushside for brush.
  145.   NumBrushSides AS LONG '// Number of brushsides for brush.
  146.   Texture AS LONG '// Texture index.
  147.  
  148.  TYPE BSP_BrushSide
  149.   Plane AS LONG '//  Plane index.
  150.   Texture AS LONG '// Texture index.
  151.  
  152.  TYPE BSP_Vertex
  153.   Position AS BSP_Float3 '// Vertex position.
  154.   TexCoord_Surface AS BSP_Float2 '//  Vertex texture coordinates. 0=surface, 1=lightmap.
  155.   TexCoord_Lightmap AS BSP_Float2
  156.   Normal AS BSP_Float3 '// Vertex normal.
  157.   Color AS BSP_RGBA '// Vertex color. RGBA.
  158.  
  159.  TYPE BSP_MeshVert
  160.   Offset AS LONG '// Vertex index offset, relative to first vertex of corresponding face.
  161.  
  162.  TYPE BSP_Effect
  163.   Name AS STRING * 64 '// Effect shader.
  164.   Brush AS LONG '// Brush that generated this effect.
  165.   Unknown AS LONG 'Always 5, except in q3dm8, which has one effect with -1.
  166.  
  167.  TYPE BSP_Face
  168.   Texture AS LONG '// Texture index.
  169.   Effect AS LONG '// Index into lump 12 (Effects), or -1.
  170.   FaceType AS LONG '// Face type. 1=polygon, 2=patch, 3=mesh, 4=billboard
  171.   Vertex AS LONG '// Index of first vertex.
  172.   NumVertexes AS LONG '// Number of vertices.
  173.   MeshVert AS LONG '// Index of first meshvert.
  174.   NumMeshVerts AS LONG '// Number of meshverts.
  175.   LMIndex AS LONG '// Lightmap index.
  176.   LMStart AS BSP_Int2 '// Corner of this face's lightmap image in lightmap.
  177.   LMSize AS BSP_Int2 '// Size of this face's lightmap image in lightmap.
  178.   LMOrigin AS BSP_Float3 '// World space origin of lightmap.
  179.   LMVecs AS BSP_LM_Vec '// World space lightmap s and t unit vectors.
  180.   Normal AS BSP_Float3 '// Surface normal.
  181.   Size AS BSP_Int2 '// Patch dimensions.
  182.  
  183.  TYPE BSP_LightVol
  184.   Ambient AS BSP_Light '// Ambient color component. RGB.
  185.   Directional AS BSP_Light '// Directional color component. RGB.
  186.   LightDirPhi AS _UNSIGNED _BYTE '//  Phi - Direction to light.
  187.   LightDirTheta AS _UNSIGNED _BYTE '//  Teta - Direction to light.
  188.  
  189.  TYPE BSP_VisData
  190.   NumVecs AS LONG '// Number of vectors.
  191.   SizeVecs AS LONG '// Size of each vector, in bytes.
  192.   Vecs AS _MEM 'ubyte[numvecs * sizevecs] vecs  '// Visibility data. One bit per cluster per vector.
  193.  
  194.  
  195. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  196.  
  197. '// Master function returns true (-1) if all was ok, or false (0) if failiure.
  198. FUNCTION BSP_Load (Level AS Level, File$)
  199.  
  200.  InFile = FREEFILE '// Get a free file handle
  201.  OPEN File$ FOR BINARY AS #InFile '// Open the file
  202.  
  203.  BytePos& = 1 '// Byte position variable
  204.  
  205.  
  206.  '// DIM header
  207.  DIM Header AS BSP_Header
  208.  GET #InFile, BytePos&, Header.Magic '// Get the id, if not "IBSP" then failiure
  209.  IF Header.Magic = "IBSP" THEN '// Valid file
  210.   BytePos& = BytePos& + LEN(Header.Magic) '// Byte position increment
  211.   GET #InFile, BytePos&, Header.Version '// Get the version id
  212.   IF Header.Version = 46 THEN '// Valid format (Quake 3 level)
  213.    BytePos& = BytePos& + LEN(Header.Version) '// Byte position increment
  214.  
  215.    DIM Entry(16) AS BSP_DirEntry
  216.    GET #InFile, BytePos&, Entry() '// Load all the offsets
  217.  
  218.    Level.HeaderPntr = _MEMNEW(LEN(Header.Magic) + LEN(Header.Version) + (LEN(Entry(0)) * 17)) '// Allocate memory
  219.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET, Header.Magic
  220.    MemOffset& = LEN(Header.Magic)
  221.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET + MemOffset&, Header.Version
  222.    MemOffset& = MemOffset& + LEN(Header.Version)
  223.    _MEMPUT Level.HeaderPntr, Level.HeaderPntr.OFFSET + MemOffset&, Entry()
  224.  
  225.    '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  226.    '// We dont care about certain things in the file for now, we just want rendering and clipping data
  227.    '// Need to calculate required memory block and then load data
  228.    '// Create single defintions of each required type to use in caluation
  229.  
  230.    '// Add up size of all the arrays and create _MEM block
  231.    DIM MemSize AS _UNSIGNED LONG, MemOffset AS _UNSIGNED LONG
  232.  
  233.    FOR i% = 0 TO 16
  234.     IF i% > 0 AND i% <> 14 THEN '// Ignore blocks we dont want to load
  235.      MemSize = MemSize + Entry(i%).Size '// Add up the size of all the memory blocks
  236.     END IF
  237.    NEXT
  238.    Level.DataPntr = _MEMNEW(MemSize)
  239.  
  240.    '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  241.    '// Load all the bits n pieces
  242.  
  243.    FOR Index& = 0 TO 16
  244.  
  245.     BytePos& = Entry(Index&).Start '// Offset of where data starts
  246.  
  247.     SELECT CASE Index&
  248.  
  249.      CASE 0 '// Entities  Game-related object descriptions. - We are not gonna worry about these for now
  250.      CASE 1 '// Textures  Surface descriptions.
  251.  
  252.       DIM Tmp_Texture AS BSP_Texture
  253.       NumTXRecs& = Entry(Index&).Size / LEN(Tmp_Texture)
  254.       DIM Texture(NumTXRecs& - 1) AS BSP_Texture
  255.       GET #InFile, BytePos&, Texture()
  256.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Texture()
  257.  
  258.  
  259.       FOR i& = 0 TO NumTXRecs& - 1
  260.        FName$ = BSP_File_Conform(Texture(i&).Name)
  261.        IF _FILEEXISTS(FName$ + ".jpg") THEN
  262.         NumTx% = NumTx% + 1
  263.        ELSEIF _FILEEXISTS(FName$ + ".tga") THEN
  264.         NumTx% = NumTx% + 1
  265.        ELSE
  266.         '        PRINT "File not found!"
  267.        END IF
  268.       NEXT
  269.  
  270.       '// Load all the texture files???
  271.       DIM TxtHnd(NumTx% - 1) AS _UNSIGNED LONG
  272.  
  273.       FOR i& = 0 TO NumTXRecs& - 1
  274.        FName$ = BSP_File_Conform(Texture(i&).Name)
  275.        IF _FILEEXISTS(FName$ + ".jpg") THEN
  276.         TxtHnd(FCnt%) = GDK_GL_LOAD_TEXTURE(FName$ + ".jpg")
  277.         FCnt% = FCnt% + 1
  278.        ELSEIF _FILEEXISTS(FName$ + ".tga") THEN
  279.  
  280.         FCnt% = FCnt% + 1
  281.        ELSE
  282.         '        PRINT "File not found!"
  283.        END IF
  284.       NEXT
  285.  
  286.  
  287.      CASE 2 '// Planes  Planes used by map geometry.
  288.  
  289.       DIM TmpPlane AS BSP_Plane
  290.       NumPLRecs& = Entry(Index&).Size / LEN(TmpPlane)
  291.       DIM Plane(NumPLRecs& - 1) AS BSP_Plane
  292.       GET #InFile, BytePos&, Plane()
  293.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Plane()
  294.  
  295.      CASE 3 '// Nodes  BSP tree nodes.
  296.  
  297.       DIM TmpNode AS BSP_Node
  298.       NumNodeRecs& = Entry(Index&).Size / LEN(TmpNode)
  299.       DIM Node(NumNodeRecs& - 1) AS BSP_Node
  300.       GET #InFile, BytePos&, Node()
  301.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Node()
  302.  
  303.      CASE 4 '// Leafs  BSP tree leaves.
  304.  
  305.       DIM TmpLeaf AS BSP_Leaf
  306.       NumLeafRecs& = Entry(Index&).Size / LEN(TmpLeaf)
  307.       DIM Leaf(NumLeafRecs& - 1) AS BSP_Leaf
  308.       GET #InFile, BytePos&, Leaf()
  309.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Leaf()
  310.  
  311.      CASE 5 '// Leaffaces  Lists of face indices, one list per leaf.
  312.  
  313.       DIM TmpLF AS BSP_LeafFace
  314.       NumLFRecs& = Entry(Index&).Size / LEN(TmpLF)
  315.       DIM LeafFace(NumLFRecs& - 1) AS BSP_LeafFace
  316.       GET #InFile, BytePos&, LeafFace()
  317.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, LeafFace()
  318.  
  319.      CASE 6 '// Leafbrushes  Lists of brush indices, one list per leaf.
  320.  
  321.       DIM TmpLB AS BSP_LeafBrush
  322.       NumLBRecs& = Entry(Index&).Size / LEN(TmpLB)
  323.       DIM LeafBrush(NumLBRecs& - 1) AS BSP_LeafBrush
  324.       GET #InFile, BytePos&, LeafBrush()
  325.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, LeafBrush()
  326.  
  327.      CASE 7 '// Models  Descriptions of rigid world geometry in map.
  328.  
  329.       DIM TmpMDL AS BSP_Model
  330.       NumMDLRecs& = Entry(Index&).Size / LEN(TmpMDL)
  331.       DIM BSPMDL(NumMDLRecs& - 1) AS BSP_Model
  332.       GET #InFile, BytePos&, BSPMDL()
  333.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, BSPMDL()
  334.  
  335.      CASE 8 '// Brushes  Convex polyhedra used to describe solid space.
  336.  
  337.       DIM TmpBrush AS BSP_Brush
  338.       NumBRecs& = Entry(Index&).Size / LEN(TmpBrush)
  339.       DIM Brush(NumBRecs& - 1) AS BSP_Brush
  340.       GET #InFile, BytePos&, Brush()
  341.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Brush()
  342.  
  343.      CASE 9 '// Brushsides  Brush surfaces.
  344.  
  345.       DIM TmpBS AS BSP_BrushSide
  346.       NumBSRecs& = Entry(Index&).Size / LEN(TmpBS)
  347.       DIM BrushSide(NumBSRecs& - 1) AS BSP_BrushSide
  348.       GET #InFile, BytePos&, BrushSide()
  349.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, BrushSide()
  350.  
  351.      CASE 10 '// Vertexes  Vertices used to describe faces.
  352.  
  353.       DIM TmpVert AS BSP_Vertex
  354.       NumVRecs& = Entry(Index&).Size / LEN(TmpVert)
  355.       DIM Vertex(NumVRecs& - 1) AS BSP_Vertex
  356.       GET #InFile, BytePos&, Vertex()
  357.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Vertex()
  358.  
  359.      CASE 11 '// Meshverts  Lists of offsets, one list per mesh.
  360.  
  361.       DIM TmpMVert AS BSP_MeshVert
  362.       NumMVRecs& = Entry(Index&).Size / LEN(TmpMVert)
  363.       DIM MeshVertex(NumMVRecs& - 1) AS BSP_MeshVert
  364.       GET #InFile, BytePos&, MeshVertex()
  365.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, MeshVertex()
  366.  
  367.      CASE 12 '// Effects  List of special map effects.
  368.  
  369.       DIM TmpEffect AS BSP_Effect
  370.       NumEFRecs& = Entry(Index&).Size / LEN(TmpEffect)
  371.       DIM Effect(NumEFRecs& - 1) AS BSP_Effect
  372.       GET #InFile, BytePos&, Effect()
  373.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Effect()
  374.  
  375.      CASE 13 '// Faces  Surface geometry.
  376.  
  377.       DIM TmpFace AS BSP_Face
  378.       NumFaceRecs& = Entry(Index&).Size / LEN(TmpFace)
  379.       DIM Face(NumFaceRecs& - 1) AS BSP_Face
  380.       GET #InFile, BytePos&, Face()
  381.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, Face()
  382.  
  383.      CASE 14 '// Lightmaps  Packed lightmap data.
  384.  
  385.       '// array of (127,127,3) Using RGB
  386.       '// Gonna ignore this for now
  387.  
  388.      CASE 15 '// Lightvols  Local illumination data.
  389.  
  390.       DIM TmpLVols AS BSP_LightVol
  391.       NumLVRecs& = Entry(Index&).Size / LEN(TmpLVols)
  392.       DIM LightVol(NumLVRecs& - 1) AS BSP_LightVol
  393.       GET #InFile, BytePos&, LightVol()
  394.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, LightVol()
  395.  
  396.      CASE 16 '// Visdata  Cluster-cluster visibility data.
  397.  
  398.       DIM TmpVD AS BSP_VisData
  399.       NumVDRecs& = Entry(Index&).Size / LEN(TmpVD)
  400.       DIM VD(NumVDRecs& - 1) AS BSP_VisData
  401.       GET #InFile, BytePos&, VD()
  402.       _MEMPUT Level.DataPntr, Level.DataPntr.OFFSET + MemOffset, VD()
  403.  
  404.     END SELECT
  405.  
  406.     IF Index& > 0 AND Index& <> 14 THEN '// Ignore blocks we dont use
  407.      MemOffset = MemOffset + Entry(Index&).Size '// increase memory offset
  408.     END IF
  409.  
  410.    NEXT
  411.  
  412.    BSP_Load = True '// All good!
  413.   ELSE
  414.    BSP_Load = False '// bad file or unsupported format
  415.   END IF
  416.   BSP_Load = False '// bad file or unsupported format
  417.  
  418.  '// All done now so close the file
  419.  CLOSE #InFile
  420.  
  421.  
  422. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  423.  
  424. FUNCTION BSP_File_Conform$ (File$) '// Changes file names so we can use them
  425.  
  426.  Allowed$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_\/"
  427.  
  428.  FOR i% = 1 TO LEN(File$)
  429.   Ltr$ = MID$(File$, i%, 1)
  430.   IF INSTR(Allowed$, Ltr$) OR INSTR(Allowed$, UCASE$(Ltr$)) THEN
  431.    IF Ltr$ = "/" THEN
  432.     FName$ = FName$ + "\"
  433.    ELSE
  434.     FName$ = FName$ + Ltr$
  435.    END IF
  436.   END IF
  437.  
  438.  BSP_File_Conform$ = FName$
  439.  
  440.  
  441.  
  442. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  443.  
  444. SUB BSP_Draw (Level AS Level)
  445.  
  446.  
  447.  
  448. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  449.  
  450. SUB _GL ()
  451.  
  452.  IF AllowGL THEN
  453.  
  454.   IF InitGl THEN
  455.    IF BSP_Load(Level, "maps\q3Dead1.bsp") = True THEN '// Load the level data, if it returns true then run renderer
  456.  
  457.     InitGl = False
  458.  
  459.    ELSE
  460.     '// It not work!
  461.    END IF
  462.   ELSE '// GL render
  463.    BSP_Draw Level
  464.  
  465.   END IF
  466.  
  467. '///////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
  468.  
  469. SUB GDK_GL_CLS
  470.  _glClear _GL_COLOR_BUFFER_BIT OR _GL_DEPTH_BUFFER_BIT '// Clear screen and depth buffers
  471.  
  472. '########################################################################################################################
  473. 'Texturing
  474. '########################################################################################################################
  475.  
  476. FUNCTION GDK_GL_MAKE_TEXTURE (File&)
  477.  Sx% = _WIDTH(File&)
  478.  Sy% = _HEIGHT(File&)
  479.  DIM h AS _UNSIGNED LONG, LoadTexture_Buffer(Sx% * Sy%) AS LONG, LoadTexture_Buffer2(Sx% * Sy%) AS LONG
  480.  OldSrc& = _SOURCE
  481.  _SOURCE File&
  482.  GET (0, 0)-(Sx% - 1, Sy% - 1), LoadTexture_Buffer(0)
  483.  _SOURCE OldSrc&
  484.  FOR y% = 0 TO Sy% - 1
  485.   FOR x% = 0 TO Sx% - 1
  486.    clr& = LoadTexture_Buffer(PXCnt&)
  487.    IF clr& >= _RGB32(245, 245, 245) THEN
  488.     LoadTexture_Buffer2(PXCnt&) = ((clr& \ 65536) + 255) + (clr& AND &HFF00&) + ((clr& AND 255) * 65536)
  489.    ELSE
  490.     LoadTexture_Buffer2(PXCnt&) = ((clr& \ 65536) AND 255) + (clr& AND &HFF00&) + ((clr& AND 255) * 65536)
  491.    END IF
  492.    PXCnt& = PXCnt& + 1
  493.   NEXT
  494.  _glBindTexture _GL_TEXTURE_2D, h
  495.  gluBuild2DMipmaps _GL_TEXTURE_2D, _GL_RGBA, Sx%, Sy%, _GL_RGBA, _GL_UNSIGNED_BYTE, LoadTexture_Buffer2(0)
  496.  _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  497.  _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR_MIPMAP_LINEAR
  498.  GDK_GL_MAKE_TEXTURE = h
  499.  
  500. '########################################################################################################################
  501.  
  502. FUNCTION GDK_GL_LOAD_TEXTURE (FileName$)
  503.  File& = _LOADIMAGE(FileName$)
  504.  IF File& < -1 THEN
  505.   Sx% = _WIDTH(File&)
  506.   Sy% = _HEIGHT(File&)
  507.   DIM h AS _UNSIGNED LONG, LoadTexture_Buffer(Sx% * Sy%) AS LONG, LoadTexture_Buffer2(Sx% * Sy%) AS LONG
  508.   OldSrc& = _SOURCE
  509.   _SOURCE File&
  510.   GET (0, 0)-(Sx% - 1, Sy% - 1), LoadTexture_Buffer(0)
  511.   _SOURCE OldSrc&
  512.   FOR y% = 0 TO Sy% - 1
  513.    FOR x% = 0 TO Sx% - 1
  514.     clr& = LoadTexture_Buffer(PXCnt&)
  515.     IF clr& >= _RGB32(245, 245, 245) THEN
  516.      LoadTexture_Buffer2(PXCnt&) = ((clr& \ 65536) + 255) + (clr& AND &HFF00&) + ((clr& AND 255) * 65536)
  517.     ELSE
  518.      LoadTexture_Buffer2(PXCnt&) = ((clr& \ 65536) AND 255) + (clr& AND &HFF00&) + ((clr& AND 255) * 65536)
  519.     END IF
  520.     PXCnt& = PXCnt& + 1
  521.    NEXT
  522.   NEXT
  523.   _glBindTexture _GL_TEXTURE_2D, h
  524.   gluBuild2DMipmaps _GL_TEXTURE_2D, _GL_RGBA, Sx%, Sy%, _GL_RGBA, _GL_UNSIGNED_BYTE, LoadTexture_Buffer2(0)
  525.   _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
  526.   _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR_MIPMAP_LINEAR
  527.   _FREEIMAGE File&
  528.   GDK_GL_LOAD_TEXTURE = h
  529.   GDK_GL_LOAD_TEXTURE = 0
  530.  

Happy coding

Unseen
« Last Edit: July 04, 2020, 03:00:20 am by Unseen Machine »

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #3 on: July 05, 2020, 04:09:25 am »
So, i've run across a problem with missing texture files and have had to reach outside to find out why!

In the interest of keeping everything in one place in case someone needs to reference it later on (doubtful but one can hope) thread is https://discourse.ioquake.org/t/missing-texture-files/1509

Unseen

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #4 on: July 05, 2020, 04:45:09 am »
Hi, I don't know the problem, I'm just asking. Can't the missing textures be part of the basic (default) package with Quake 3?

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #5 on: July 05, 2020, 04:50:05 am »
Quote
Can't the missing textures be part of the basic (default) package with Quake 3?

I thought that so i bought Quake 3 and Quake 3 Team arena and have all the files in the right place. I can find most of the required textures but some seem to be missing or i dont understand the linkage properly.

Thanks though,

Unseen

Offline Unseen Machine

  • Forum Regular
  • Posts: 158
  • Make the game not the engine!
    • View Profile
Re: Quake 3 Level Loader - Work in progress
« Reply #6 on: July 06, 2020, 02:51:17 am »
Hi folks,

So it turns out (thanks to a gent at ioquake forums) that the missing textures are actually shader references! I havent got as far as even reading much about them yet let alone loading/using them but i'm sure i'll get there eventually!

Unseen