diff --git a/BSP_FORMAT.md b/BSP_FORMAT.md deleted file mode 100644 index 4298870..0000000 --- a/BSP_FORMAT.md +++ /dev/null @@ -1,25 +0,0 @@ - - -#### Lump 22: Portals -Optional lump. Only included for visualising vis portals. Not useful for release maps. - -#### Lump 23: Clusters -Optional lump. Only included for visualising vis portals. Not useful for release maps. - -#### Lump 24: PortalVerts -Optional lump. Only included for visualising vis portals. Not useful for release maps. - -#### Lump 25: ClusterPortals -Optional lump. Only included for visualising vis portals. Not useful for release maps. - -#### Lump 28: Physcollide -Optional lump | May be empty - -#### Lump 29: PhysDisp -Optional lump | May be empty - -#### Lump 58: LumpFacesHDR -Optional lump | May be empty - - - diff --git a/README.md b/README.md index 191d56b..772ad8b 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ Go library for manipulating Source Engine .bsp map files. ### Features: -* Read support for (probably) all documented bsp formats -* Write support for (probably) all documented bsp formats. +* Read support for (most) non-xbox360 bsps. * Freely modify and resize any Lump data. +* Limited write support ##### Not all lumps are current supported, but can be freely read and modified, as they are treated as `[]byte` -The following lumps currently have a full implementation for v20 bsp's: +The following lumps currently have a full implementation for v20 bsp's (tested against CS:S & CS:GO): ``` 0: Entdata @@ -33,13 +33,16 @@ The following lumps currently have a full implementation for v20 bsp's: 19: Brushsides 20: Areas 21: AreaPortals +26: DispInfo 27: OriginalFaces 28: PhysDisp 30: VertNormals 31: VertNormalIndices 33: DispVerts 34: DispLightmapSamplePosition +35: Game lump (partial: sprp only) 36: LeafWaterData +37: Primitives 38: PrimVerts 39: PrimIndices 40: Pakfile @@ -66,7 +69,7 @@ The following lumps currently have a full implementation for v20 bsp's: # Usage Minimal example of obtaining entdata from a BSP. The following will print the entdata -blocks of a specified .bsp to terminal. +lump (entdata is a single json-like string) of a specified .bsp to console. ```go package main @@ -90,14 +93,15 @@ func main() { } f.Close() - lump := file.GetLump(bsp.LUMP_ENTITIES) - log.Println(lump.GetContents().GetData().(string)) + lump := file.GetLump(bsp.LUMP_ENTITIES).(*lump.Entities) + log.Println(lump.GetData()) } ``` ## Real World examples -Replace game_text newline placeholder characters (avoids Hammer crash) as a compile step: [https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang](https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang) +* Replace game_text newline placeholder characters (avoids Hammer crash) as a compile step: [https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang](https://github.com/Galaco/CS-GO-game_text-newline-inserter/tree/golang) +* Proof of concept BSP viewer: [https://github.com/Galaco/Gource-Engine](https://github.com/Galaco/Gource-Engine) # Contributing -If you want to contribute, feel free to fork and raise a Pull Request for new additions. \ No newline at end of file +All contributions welcome. Known unsupported games/maps are especially useful. diff --git a/bsp.go b/bsp.go index 382b87a..0f42688 100644 --- a/bsp.go +++ b/bsp.go @@ -1,27 +1,29 @@ package bsp +import "github.com/galaco/bsp/lumps" + // Root .bsp filetype container. // Consists of a 1036byte header and 64 lump blocks. type Bsp struct { header Header - lumps [64]Lump + lumps [64]Lump } // Bsp header. Contains format and lump layout data. // Do not trust lump information between import and export type Header struct { - Id int32 - Version int32 - Lumps [64]HeaderLump + Id int32 + Version int32 + Lumps [64]HeaderLump Revision int32 } // Layout information for a given lump, stored in the Header. type HeaderLump struct { - Offset int32 - Length int32 + Offset int32 + Length int32 Version int32 - Id [4]byte + Id [4]byte } // Get the header for a bsp. @@ -30,11 +32,16 @@ func (bsp *Bsp) GetHeader() Header { } // Get the lump for a given index. -func (bsp *Bsp) GetLump(index int) *Lump { +func (bsp *Bsp) GetLump(index int) lumps.ILump { + return bsp.GetLumpRaw(index).GetContents() +} + +// Get the lump for a given index. +func (bsp *Bsp) GetLumpRaw(index int) *Lump { return &bsp.lumps[index] } // Set the lump data for a given index. func (bsp *Bsp) SetLump(index int, lump Lump) { bsp.lumps[index] = lump -} \ No newline at end of file +} diff --git a/bsp_test.go b/bsp_test.go index 6582a9e..aa45daa 100644 --- a/bsp_test.go +++ b/bsp_test.go @@ -1,14 +1,14 @@ package bsp import ( - "testing" - "log" "bytes" + "log" + "testing" ) // Test that resultant lump data matches expected. func TestLumpExports(t *testing.T) { - file,err := ReadFromFile("maps/v20/de_dust2.bsp") + file, err := ReadFromFile("maps/v20/de_dust2.bsp") if err != nil { t.Error(err) } @@ -17,16 +17,17 @@ func TestLumpExports(t *testing.T) { lumpIndex := 0 for lumpIndex < 64 { lump := file.GetLump(lumpIndex) - lumpBytes := lump.GetContents().ToBytes() + rawLump := file.GetLumpRaw(lumpIndex) + lumpBytes := lump.ToBytes() if len(lumpBytes) != int(file.GetHeader().Lumps[lumpIndex].Length) { t.Errorf("Lump: %d length mismatch. Got: %dbytes, expected: %dbytes", lumpIndex, len(lumpBytes), file.header.Lumps[lumpIndex].Length) } else { - log.Printf("Index: %d, Expected: %d, Actual: %d\n", lumpIndex, len(lump.GetRawContents()), len(lumpBytes)) - if !bytes.Equal(lumpBytes, lump.GetRawContents()) { + log.Printf("Index: %d, Expected: %d, Actual: %d\n", lumpIndex, len(rawLump.GetRawContents()), len(lumpBytes)) + if !bytes.Equal(lumpBytes, rawLump.GetRawContents()) { t.Errorf("Lump: %d data mismatch", lumpIndex) } } lumpIndex += 1 } -} \ No newline at end of file +} diff --git a/flags/constants.go b/flags/constants.go index 5500fcd..03af418 100644 --- a/flags/constants.go +++ b/flags/constants.go @@ -1,18 +1,18 @@ package flags -const CONTENTS_EMPTY = 0 // No contents +const CONTENTS_EMPTY = 0 // No contents -const CONTENTS_SOLID = 0x1 // an eye is never valid in a solid -const CONTENTS_WINDOW = 0x2 // translucent, but not watery (glass) -const CONTENTS_AUX = 0x4 -const CONTENTS_GRATE = 0x8 // alpha-tested "grate" textures. Bullets/sight pass through, but solids don't -const CONTENTS_SLIME = 0x10 -const CONTENTS_WATER = 0x20 -const CONTENTS_BLOCKLOS = 0x40 // block AI line of sight -const CONTENTS_OPAQUE = 0x80 // things that cannot be seen through (may be non-solid though) -const LAST_VISIBLE_CONTENTS = 0x80 +const CONTENTS_SOLID = 0x1 // an eye is never valid in a solid +const CONTENTS_WINDOW = 0x2 // translucent, but not watery (glass) +const CONTENTS_AUX = 0x4 +const CONTENTS_GRATE = 0x8 // alpha-tested "grate" textures. Bullets/sight pass through, but solids don't +const CONTENTS_SLIME = 0x10 +const CONTENTS_WATER = 0x20 +const CONTENTS_BLOCKLOS = 0x40 // block AI line of sight +const CONTENTS_OPAQUE = 0x80 // things that cannot be seen through (may be non-solid though) +const LAST_VISIBLE_CONTENTS = 0x80 -const ALL_VISIBLE_CONTENTS = LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1) +const ALL_VISIBLE_CONTENTS = LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS - 1) const CONTENTS_TESTFOGVOLUME = 0x100 const CONTENTS_UNUSED = 0x200 @@ -20,108 +20,122 @@ const CONTENTS_UNUSED = 0x200 // unused // NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS // if not visible, then grab from the bottom. -const CONTENTS_UNUSED6 = 0x400 +const CONTENTS_UNUSED6 = 0x400 -const CONTENTS_TEAM1 = 0x800 // per team contents used to differentiate collisions -const CONTENTS_TEAM2 = 0x1000 // between players and objects on different teams +const CONTENTS_TEAM1 = 0x800 // per team contents used to differentiate collisions +const CONTENTS_TEAM2 = 0x1000 // between players and objects on different teams // ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW -const CONTENTS_IGNORE_NODRAW_OPAQUE = 0x2000 +const CONTENTS_IGNORE_NODRAW_OPAQUE = 0x2000 // hits entities which are MOVETYPE_PUSH (doors, plats, etc.) -const CONTENTS_MOVEABLE = 0x4000 +const CONTENTS_MOVEABLE = 0x4000 // remaining contents are non-visible, and don't eat brushes -const CONTENTS_AREAPORTAL = 0x8000 +const CONTENTS_AREAPORTAL = 0x8000 -const CONTENTS_PLAYERCLIP = 0x10000 -const CONTENTS_MONSTERCLIP = 0x20000 +const CONTENTS_PLAYERCLIP = 0x10000 +const CONTENTS_MONSTERCLIP = 0x20000 // currents can be added to any other contents, and may be mixed -const CONTENTS_CURRENT_0 = 0x40000 -const CONTENTS_CURRENT_90 = 0x80000 -const CONTENTS_CURRENT_180= 0x100000 -const CONTENTS_CURRENT_270= 0x200000 -const CONTENTS_CURRENT_UP = 0x400000 -const CONTENTS_CURRENT_DOWN= 0x800000 - -const CONTENTS_ORIGIN = 0x1000000 // removed before bsping an entity - -const CONTENTS_MONSTER= 0x2000000 // should never be on a brush, only in game -const CONTENTS_DEBRIS = 0x4000000 -const CONTENTS_DETAIL = 0x8000000 // brushes to be added after vis leafs -const CONTENTS_TRANSLUCENT= 0x10000000 // auto set if any surface has trans -const CONTENTS_LADDER = 0x20000000 -const CONTENTS_HITBOX = 0x40000000 // use accurate hitboxes on trace - +const CONTENTS_CURRENT_0 = 0x40000 +const CONTENTS_CURRENT_90 = 0x80000 +const CONTENTS_CURRENT_180 = 0x100000 +const CONTENTS_CURRENT_270 = 0x200000 +const CONTENTS_CURRENT_UP = 0x400000 +const CONTENTS_CURRENT_DOWN = 0x800000 + +const CONTENTS_ORIGIN = 0x1000000 // removed before bsping an entity + +const CONTENTS_MONSTER = 0x2000000 // should never be on a brush, only in game +const CONTENTS_DEBRIS = 0x4000000 +const CONTENTS_DETAIL = 0x8000000 // brushes to be added after vis leafs +const CONTENTS_TRANSLUCENT = 0x10000000 // auto set if any surface has trans +const CONTENTS_LADDER = 0x20000000 +const CONTENTS_HITBOX = 0x40000000 // use accurate hitboxes on trace // NOTE: These are stored in a short in the engine now. Don't use more than 16 bits -const SURF_LIGHT = 0x0001 // value will hold the light strength -const SURF_SKY2D = 0x0002 // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox -const SURF_SKY = 0x0004 // don't draw, but add to skybox -const SURF_WARP = 0x0008 // turbulent water warp -const SURF_TRANS = 0x0010 -const SURF_NOPORTAL =0x0020 // the surface can not have a portal placed on it -const SURF_TRIGGER= 0x0040 // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders -const SURF_NODRAW = 0x0080 // don't bother referencing the texture - -const SURF_HINT =0x0100 // make a primary bsp splitter - -const SURF_SKIP =0x0200 // completely ignore, allowing non-closed brushes -const SURF_NOLIGHT =0x0400 // Don't calculate light -const SURF_BUMPLIGHT =0x0800 // calculate three lightmaps for the surface for bumpmapping -const SURF_NOSHADOWS =0x1000 // Don't receive shadows -const SURF_NODECALS =0x2000 // Don't receive decals -const SURF_NOCHOP = 0x4000 // Don't subdivide patches on this surface -const SURF_HITBOX = 0x8000 // surface is part of a hitbox - - +const SURF_LIGHT = 0x0001 // value will hold the light strength +const SURF_SKY2D = 0x0002 // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox +const SURF_SKY = 0x0004 // don't draw, but add to skybox +const SURF_WARP = 0x0008 // turbulent water warp +const SURF_TRANS = 0x0010 +const SURF_NOPORTAL = 0x0020 // the surface can not have a portal placed on it +const SURF_TRIGGER = 0x0040 // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders +const SURF_NODRAW = 0x0080 // don't bother referencing the texture + +const SURF_HINT = 0x0100 // make a primary bsp splitter + +const SURF_SKIP = 0x0200 // completely ignore, allowing non-closed brushes +const SURF_NOLIGHT = 0x0400 // Don't calculate light +const SURF_BUMPLIGHT = 0x0800 // calculate three lightmaps for the surface for bumpmapping +const SURF_NOSHADOWS = 0x1000 // Don't receive shadows +const SURF_NODECALS = 0x2000 // Don't receive decals +const SURF_NOCHOP = 0x4000 // Don't subdivide patches on this surface +const SURF_HITBOX = 0x8000 // surface is part of a hitbox // ----------------------------------------------------- // spatial content masks - used for spatial queries (traceline,etc.) // ----------------------------------------------------- -const MASK_ALL = (0xFFFFFFFF) +const MASK_ALL = (0xFFFFFFFF) + // everything that is normally solid -const MASK_SOLID = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +const MASK_SOLID = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_GRATE) + // everything that blocks player movement -const MASK_PLAYERSOLID = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +const MASK_PLAYERSOLID = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_GRATE) + // blocks npc movement -const MASK_NPCSOLID = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE) +const MASK_NPCSOLID = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_MONSTERCLIP | CONTENTS_WINDOW | CONTENTS_MONSTER | CONTENTS_GRATE) + // water physics in these contents -const MASK_WATER = (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME) +const MASK_WATER = (CONTENTS_WATER | CONTENTS_MOVEABLE | CONTENTS_SLIME) + // everything that blocks lighting -const MASK_OPAQUE = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE) +const MASK_OPAQUE = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_OPAQUE) + // everything that blocks lighting, but with monsters added. -const MASK_OPAQUE_AND_NPCS = (MASK_OPAQUE|CONTENTS_MONSTER) +const MASK_OPAQUE_AND_NPCS = (MASK_OPAQUE | CONTENTS_MONSTER) + // everything that blocks line of sight for AI -const MASK_BLOCKLOS = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS) +const MASK_BLOCKLOS = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_BLOCKLOS) + // everything that blocks line of sight for AI plus NPCs -const MASK_BLOCKLOS_AND_NPCS = (MASK_BLOCKLOS|CONTENTS_MONSTER) +const MASK_BLOCKLOS_AND_NPCS = (MASK_BLOCKLOS | CONTENTS_MONSTER) + // everything that blocks line of sight for players -const MASK_VISIBLE = (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE) +const MASK_VISIBLE = (MASK_OPAQUE | CONTENTS_IGNORE_NODRAW_OPAQUE) + // everything that blocks line of sight for players, but with monsters added. -const MASK_VISIBLE_AND_NPCS = (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE) +const MASK_VISIBLE_AND_NPCS = (MASK_OPAQUE_AND_NPCS | CONTENTS_IGNORE_NODRAW_OPAQUE) + // bullets see these as solid -const MASK_SHOT = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX) +const MASK_SHOT = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_MONSTER | CONTENTS_WINDOW | CONTENTS_DEBRIS | CONTENTS_HITBOX) + // non-raycasted weapons see this as solid (includes grates) -const MASK_SHOT_HULL = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE) +const MASK_SHOT_HULL = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_MONSTER | CONTENTS_WINDOW | CONTENTS_DEBRIS | CONTENTS_GRATE) + // hits solids (not grates) and passes through everything else -const MASK_SHOT_PORTAL = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER) +const MASK_SHOT_PORTAL = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_WINDOW | CONTENTS_MONSTER) + // everything normally solid, except monsters (world+brush only) -const MASK_SOLID_BRUSHONLY = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE) +const MASK_SOLID_BRUSHONLY = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_WINDOW | CONTENTS_GRATE) + // everything normally solid for player movement, except monsters (world+brush only) -const MASK_PLAYERSOLID_BRUSHONLY =(CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE) +const MASK_PLAYERSOLID_BRUSHONLY = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_WINDOW | CONTENTS_PLAYERCLIP | CONTENTS_GRATE) + // everything normally solid for npc movement, except monsters (world+brush only) -const MASK_NPCSOLID_BRUSHONLY = (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) +const MASK_NPCSOLID_BRUSHONLY = (CONTENTS_SOLID | CONTENTS_MOVEABLE | CONTENTS_WINDOW | CONTENTS_MONSTERCLIP | CONTENTS_GRATE) + // just the world, used for route rebuilding -const MASK_NPCWORLDSTATIC = (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE) +const MASK_NPCWORLDSTATIC = (CONTENTS_SOLID | CONTENTS_WINDOW | CONTENTS_MONSTERCLIP | CONTENTS_GRATE) + // These are things that can split areaportals -const MASK_SPLITAREAPORTAL = (CONTENTS_WATER|CONTENTS_SLIME) +const MASK_SPLITAREAPORTAL = (CONTENTS_WATER | CONTENTS_SLIME) // UNDONE: This is untested, any moving water -const MASK_CURRENT = (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN) +const MASK_CURRENT = (CONTENTS_CURRENT_0 | CONTENTS_CURRENT_90 | CONTENTS_CURRENT_180 | CONTENTS_CURRENT_270 | CONTENTS_CURRENT_UP | CONTENTS_CURRENT_DOWN) // everything that blocks corpse movement // UNDONE: Not used yet / may be deleted -const MASK_DEADSOLID = (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE) - +const MASK_DEADSOLID = (CONTENTS_SOLID | CONTENTS_PLAYERCLIP | CONTENTS_WINDOW | CONTENTS_GRATE) diff --git a/lump.go b/lump.go index aa833f9..4268125 100644 --- a/lump.go +++ b/lump.go @@ -2,8 +2,8 @@ package bsp import ( "github.com/galaco/bsp/lumps" - "log" "github.com/galaco/bsp/versions" + "log" ) const LUMP_ENTITIES = 0 @@ -86,10 +86,10 @@ const LUMP_DISP_MULTIBLEND = 63 // N.B. Some information mirrors the header's lump descriptor, but header information should not be trusted after // import completion. type Lump struct { - raw []byte - data lumps.ILump + raw []byte + data lumps.ILump length int32 - index int + index int loaded bool } @@ -103,7 +103,7 @@ func (l *Lump) SetId(index int) { // NOTE: Will need to be cast to the relevant lumps func (l *Lump) GetContents() lumps.ILump { if l.loaded == false { - l.data = l.data.FromBytes(l.raw, int32(len(l.raw))) + l.data.FromBytes(l.raw, int32(len(l.raw))) l.loaded = true } return l.data @@ -132,10 +132,10 @@ func (l *Lump) GetLength() int32 { } // Return an instance of a Lump for a given offset. -func getReferenceLumpByIndex(index int, version int32) (lumps.ILump,error) { +func getReferenceLumpByIndex(index int, version int32) (lumps.ILump, error) { if index < 0 || index > 63 { log.Fatalf("Invalid lump index: %d provided\n", index) } return versions.GetLumpForVersion(int(version), index) -} \ No newline at end of file +} diff --git a/lump_test.go b/lump_test.go index f6dbbeb..ab231ad 100644 --- a/lump_test.go +++ b/lump_test.go @@ -7,7 +7,7 @@ import ( func TestgetReferenceLumpByIndex(t *testing.T) { for i := 0; i < 64; i++ { - lump,_ := getReferenceLumpByIndex(i, 20) + lump, _ := getReferenceLumpByIndex(i, 20) if lump != getExpectedLump(i) { t.Errorf("Lump type does not match expected for identifer: %i\n", i) } @@ -15,72 +15,72 @@ func TestgetReferenceLumpByIndex(t *testing.T) { } -func getExpectedLump(index int) lumps.ILump{ +func getExpectedLump(index int) lumps.ILump { lMap := [64]lumps.ILump{ - lumps.EntData{}, - lumps.Planes{}, - lumps.TexData{}, - lumps.Vertex{}, - lumps.Visibility{}, - lumps.Node{}, - lumps.TexInfo{}, - lumps.Face{}, - lumps.Lighting{}, - lumps.Occlusion{}, - lumps.Leaf{}, - lumps.FaceId{}, - lumps.Edge{}, - lumps.Surfedge{}, - lumps.Model{}, - lumps.WorldLight{}, - lumps.LeafFace{}, - lumps.LeafBrush{}, - lumps.Brush{}, - lumps.BrushSide{}, - lumps.Area{}, - lumps.AreaPortal{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.Face{}, - lumps.PhysDisp{}, - lumps.Unimplemented{}, - lumps.VertNormal{}, - lumps.VertNormalIndice{}, - lumps.Unimplemented{}, - lumps.DispVert{}, - lumps.DispLightmapSamplePosition{}, - lumps.Game{}, - lumps.LeafWaterData{}, - lumps.Unimplemented{}, - lumps.PrimVert{}, - lumps.PrimIndice{}, - lumps.Unimplemented{}, - lumps.ClipPortalVerts{}, - lumps.Cubemap{}, - lumps.TexdataStringData{}, - lumps.TexDataStringTable{}, - lumps.Overlay{}, - lumps.LeafMinDistToWater{}, - lumps.FaceMacroTextureInfo{}, - lumps.DispTris{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.LeafAmbientIndexHDR{}, - lumps.LeafAmbientIndex{}, - lumps.Unimplemented{}, - lumps.WorldLightHDR{}, - lumps.LeafAmbientLightingHDR{}, - lumps.LeafAmbientLighting{}, - lumps.Unimplemented{}, - lumps.FaceHDR{}, - lumps.MapFlags{}, - lumps.OverlayFade{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, - lumps.Unimplemented{}, //disp multiblend + &lumps.EntData{}, + &lumps.Planes{}, + &lumps.TexData{}, + &lumps.Vertex{}, + &lumps.Visibility{}, + &lumps.Node{}, + &lumps.TexInfo{}, + &lumps.Face{}, + &lumps.Lighting{}, + &lumps.Occlusion{}, + &lumps.Leaf{}, + &lumps.FaceId{}, + &lumps.Edge{}, + &lumps.Surfedge{}, + &lumps.Model{}, + &lumps.WorldLight{}, + &lumps.LeafFace{}, + &lumps.LeafBrush{}, + &lumps.Brush{}, + &lumps.BrushSide{}, + &lumps.Area{}, + &lumps.AreaPortal{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.Face{}, + &lumps.PhysDisp{}, + &lumps.Unimplemented{}, + &lumps.VertNormal{}, + &lumps.VertNormalIndice{}, + &lumps.Unimplemented{}, + &lumps.DispVert{}, + &lumps.DispLightmapSamplePosition{}, + &lumps.Game{}, + &lumps.LeafWaterData{}, + &lumps.Unimplemented{}, + &lumps.PrimVert{}, + &lumps.PrimIndice{}, + &lumps.Unimplemented{}, + &lumps.ClipPortalVerts{}, + &lumps.Cubemap{}, + &lumps.TexdataStringData{}, + &lumps.TexDataStringTable{}, + &lumps.Overlay{}, + &lumps.LeafMinDistToWater{}, + &lumps.FaceMacroTextureInfo{}, + &lumps.DispTris{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.LeafAmbientIndexHDR{}, + &lumps.LeafAmbientIndex{}, + &lumps.Unimplemented{}, + &lumps.WorldLightHDR{}, + &lumps.LeafAmbientLightingHDR{}, + &lumps.LeafAmbientLighting{}, + &lumps.Unimplemented{}, + &lumps.FaceHDR{}, + &lumps.MapFlags{}, + &lumps.OverlayFade{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, + &lumps.Unimplemented{}, //disp multiblend } return lMap[index] diff --git a/lumps/area.go b/lumps/area.go index 26f49fc..6fc7a3f 100644 --- a/lumps/area.go +++ b/lumps/area.go @@ -1,40 +1,40 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/area" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/area" "log" + "unsafe" ) + /** - Lump 20: Areas - */ +Lump 20: Areas +*/ type Area struct { - LumpInfo + LumpGeneric data []primitives.Area } -func (lump Area) FromBytes(raw []byte, length int32) ILump { +func (lump *Area) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.Area, length/int32(unsafe.Sizeof(primitives.Area{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Area) GetData() interface{} { - return &lump.data +func (lump *Area) GetData() []primitives.Area { + return lump.data } -func (lump Area) ToBytes() []byte { +func (lump *Area) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/areaportal.go b/lumps/areaportal.go index c0df65c..7919680 100644 --- a/lumps/areaportal.go +++ b/lumps/areaportal.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/areaportal" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/areaportal" "log" + "unsafe" ) + /** - Lump 21: Areaportals - */ +Lump 21: Areaportals +*/ type AreaPortal struct { - LumpInfo + LumpGeneric data []primitives.AreaPortal } -func (lump AreaPortal) FromBytes(raw []byte, length int32) ILump { +func (lump *AreaPortal) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.AreaPortal, length/int32(unsafe.Sizeof(primitives.AreaPortal{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump AreaPortal) GetData() interface{} { - return &lump.data +func (lump *AreaPortal) GetData() []primitives.AreaPortal { + return lump.data } -func (lump AreaPortal) ToBytes() []byte { +func (lump *AreaPortal) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/brush.go b/lumps/brush.go index 4cf9602..7ad4ffe 100644 --- a/lumps/brush.go +++ b/lumps/brush.go @@ -1,37 +1,35 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/brush" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/brush" "log" "unsafe" ) /** - Lump 18: Brush - */ +Lump 18: Brush +*/ type Brush struct { - LumpInfo + LumpGeneric data []primitives.Brush } -func (lump Brush) FromBytes(raw []byte, length int32) ILump { +func (lump *Brush) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Brush, length/int32(unsafe.Sizeof(primitives.Brush{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Brush) GetData() interface{} { - return &lump.data +func (lump *Brush) GetData() []primitives.Brush { + return lump.data } -func (lump Brush) ToBytes() []byte { +func (lump *Brush) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/brushside.go b/lumps/brushside.go index 7b92f5d..6116bd9 100644 --- a/lumps/brushside.go +++ b/lumps/brushside.go @@ -1,37 +1,35 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/brushside" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/brushside" "log" "unsafe" ) /** - Lump 19: BrushSide - */ +Lump 19: BrushSide +*/ type BrushSide struct { - LumpInfo + LumpGeneric data []primitives.BrushSide // MAX_MAP_BRUSHSIDES = 65536 } -func (lump BrushSide) FromBytes(raw []byte, length int32) ILump { +func (lump *BrushSide) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.BrushSide, length/int32(unsafe.Sizeof(primitives.BrushSide{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump BrushSide) GetData() interface{} { - return &lump.data +func (lump *BrushSide) GetData() []primitives.BrushSide { + return lump.data } -func (lump BrushSide) ToBytes() []byte { +func (lump *BrushSide) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/clipportalverts.go b/lumps/clipportalverts.go index b5b12ce..a95305c 100644 --- a/lumps/clipportalverts.go +++ b/lumps/clipportalverts.go @@ -1,38 +1,36 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" + "github.com/go-gl/mathgl/mgl32" "log" "unsafe" - "github.com/go-gl/mathgl/mgl32" ) /** - Lump 41: ClipPortalVerts - */ +Lump 41: ClipPortalVerts +*/ type ClipPortalVerts struct { - LumpInfo + LumpGeneric data []mgl32.Vec3 } -func (lump ClipPortalVerts) FromBytes(raw []byte, length int32) ILump { +func (lump *ClipPortalVerts) FromBytes(raw []byte, length int32) { lump.data = make([]mgl32.Vec3, length/int32(unsafe.Sizeof(mgl32.Vec3{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump ClipPortalVerts) GetData() interface{} { - return &lump.data +func (lump *ClipPortalVerts) GetData() []mgl32.Vec3 { + return lump.data } -func (lump ClipPortalVerts) ToBytes() []byte { +func (lump *ClipPortalVerts) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/cubemap.go b/lumps/cubemap.go index 17e57ee..383795a 100644 --- a/lumps/cubemap.go +++ b/lumps/cubemap.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/cubemap" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/cubemap" "log" + "unsafe" ) + /** - Lump 42: Cubemaps - */ +Lump 42: Cubemaps +*/ type Cubemap struct { - LumpInfo + LumpGeneric data []primitives.CubemapSample } -func (lump Cubemap) FromBytes(raw []byte, length int32) ILump { +func (lump *Cubemap) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.CubemapSample, length/int32(unsafe.Sizeof(primitives.CubemapSample{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Cubemap) GetData() interface{} { - return &lump.data +func (lump *Cubemap) GetData() []primitives.CubemapSample { + return lump.data } -func (lump Cubemap) ToBytes() []byte { +func (lump *Cubemap) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/dispinfo.go b/lumps/dispinfo.go index 27d0426..5b96373 100644 --- a/lumps/dispinfo.go +++ b/lumps/dispinfo.go @@ -1,38 +1,36 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/dispinfo" "log" "unsafe" - primitives "github.com/galaco/bsp/primitives/dispinfo" ) /** - Lump 26: DispInfo - */ +Lump 26: DispInfo +*/ type DispInfo struct { - LumpInfo + LumpGeneric data []primitives.DispInfo } -func (lump DispInfo) FromBytes(raw []byte, length int32) ILump { +func (lump *DispInfo) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.DispInfo, length/int32(unsafe.Sizeof(primitives.DispInfo{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump DispInfo) GetData() interface{} { - return &lump.data +func (lump *DispInfo) GetData() []primitives.DispInfo { + return lump.data } -func (lump DispInfo) ToBytes() []byte { +func (lump *DispInfo) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/displightmapsampleposition.go b/lumps/displightmapsampleposition.go index 9b40913..21fa13f 100644 --- a/lumps/displightmapsampleposition.go +++ b/lumps/displightmapsampleposition.go @@ -1,28 +1,22 @@ package lumps /** - Lump 34: DispLightmapSamplePosition - */ +Lump 34: DispLightmapSamplePosition +*/ type DispLightmapSamplePosition struct { - LumpInfo + LumpGeneric data []byte } -func (lump DispLightmapSamplePosition) FromBytes(raw []byte, length int32) ILump { - if length == 0 { - return lump - } - +func (lump *DispLightmapSamplePosition) FromBytes(raw []byte, length int32) { lump.data = raw lump.LumpInfo.SetLength(length) - - return lump } -func (lump DispLightmapSamplePosition) GetData() interface{} { - return &lump.data +func (lump *DispLightmapSamplePosition) GetData() []byte { + return lump.data } -func (lump DispLightmapSamplePosition) ToBytes() []byte { +func (lump *DispLightmapSamplePosition) ToBytes() []byte { return lump.data } diff --git a/lumps/disptris.go b/lumps/disptris.go index 54e7b32..bbbaf6e 100644 --- a/lumps/disptris.go +++ b/lumps/disptris.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/disptris" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/disptris" "log" + "unsafe" ) + /** - Lump 48: DispTris - */ +Lump 48: DispTris +*/ type DispTris struct { - LumpInfo + LumpGeneric data []primitives.DispTri } -func (lump DispTris) FromBytes(raw []byte, length int32) ILump { +func (lump *DispTris) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.DispTri, length/int32(unsafe.Sizeof(primitives.DispTri{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump DispTris) GetData() interface{} { - return &lump.data +func (lump *DispTris) GetData() []primitives.DispTri { + return lump.data } -func (lump DispTris) ToBytes() []byte { +func (lump *DispTris) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/dispvert.go b/lumps/dispvert.go index 28d0ab6..6d89adf 100644 --- a/lumps/dispvert.go +++ b/lumps/dispvert.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/dispvert" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/dispvert" "log" + "unsafe" ) + /** - Lump 33: DispVert - */ +Lump 33: DispVert +*/ type DispVert struct { - LumpInfo + LumpGeneric data []primitives.DispVert } -func (lump DispVert) FromBytes(raw []byte, length int32) ILump { +func (lump *DispVert) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.DispVert, length/int32(unsafe.Sizeof(primitives.DispVert{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump DispVert) GetData() interface{} { - return &lump.data +func (lump *DispVert) GetData() []primitives.DispVert { + return lump.data } -func (lump DispVert) ToBytes() []byte { +func (lump *DispVert) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/edge.go b/lumps/edge.go index fe7ae6c..b87fa89 100644 --- a/lumps/edge.go +++ b/lumps/edge.go @@ -1,35 +1,33 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 12: Edge - */ +Lump 12: Edge +*/ type Edge struct { - LumpInfo + LumpGeneric data [][2]uint16 // MAX_MAP_EDGES = 256000 } -func (lump Edge) FromBytes(raw []byte, length int32) ILump { +func (lump *Edge) FromBytes(raw []byte, length int32) { lump.data = make([][2]uint16, length/4) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Edge) GetData() interface{} { - return &lump.data +func (lump *Edge) GetData() [][2]uint16 { + return lump.data } -func (lump Edge) ToBytes() []byte { +func (lump *Edge) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/entdata.go b/lumps/entdata.go index 7888b26..f685336 100644 --- a/lumps/entdata.go +++ b/lumps/entdata.go @@ -1,24 +1,22 @@ package lumps /** - Lump 0: Entdata - */ +Lump 0: Entdata +*/ type EntData struct { - LumpInfo + LumpGeneric data string } -func (lump EntData) FromBytes(raw []byte, length int32) ILump { +func (lump *EntData) FromBytes(raw []byte, length int32) { lump.data = string(raw) lump.LumpInfo.SetLength(length) - - return lump } -func (lump EntData) GetData() interface{} { - return &lump.data +func (lump *EntData) GetData() string { + return lump.data } -func (lump EntData) ToBytes() []byte { +func (lump *EntData) ToBytes() []byte { return []byte(lump.data) } diff --git a/lumps/face.go b/lumps/face.go index 89c3ad9..cf31de3 100644 --- a/lumps/face.go +++ b/lumps/face.go @@ -1,38 +1,36 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/face" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/face" "log" "unsafe" ) /** - Lump 7: Face - */ +Lump 7: Face +*/ type Face struct { - LumpInfo + LumpGeneric data []primitives.Face } -func (lump Face) FromBytes(raw []byte, length int32) ILump { +func (lump *Face) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Face, length/int32(unsafe.Sizeof(primitives.Face{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Face) GetData() interface{} { - return &lump.data +func (lump *Face) GetData() []primitives.Face { + return lump.data } -func (lump Face) ToBytes() []byte { +func (lump *Face) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/facehdr.go b/lumps/facehdr.go index 7ec3b98..d9679fe 100644 --- a/lumps/facehdr.go +++ b/lumps/facehdr.go @@ -1,38 +1,36 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/face" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/face" "log" "unsafe" ) /** - Lump 58: FaceHDR - */ +Lump 58: FaceHDR +*/ type FaceHDR struct { - LumpInfo + LumpGeneric data []primitives.Face } -func (lump FaceHDR) FromBytes(raw []byte, length int32) ILump { +func (lump *FaceHDR) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Face, length/int32(unsafe.Sizeof(primitives.Face{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump FaceHDR) GetData() interface{} { - return &lump.data +func (lump *FaceHDR) GetData() []primitives.Face { + return lump.data } -func (lump FaceHDR) ToBytes() []byte { +func (lump *FaceHDR) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/faceid.go b/lumps/faceid.go index b97ba2a..da2d528 100644 --- a/lumps/faceid.go +++ b/lumps/faceid.go @@ -1,40 +1,38 @@ package lumps - import ( - primitives "github.com/galaco/bsp/primitives/faceid" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/faceid" "log" + "unsafe" ) + /** - Lump 11: FaceIds - */ +Lump 11: FaceIds +*/ type FaceId struct { - LumpInfo + LumpGeneric data []primitives.FaceId } -func (lump FaceId) FromBytes(raw []byte, length int32) ILump { +func (lump *FaceId) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.FaceId, length/int32(unsafe.Sizeof(primitives.FaceId{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump FaceId) GetData() interface{} { - return &lump.data +func (lump *FaceId) GetData() []primitives.FaceId { + return lump.data } -func (lump FaceId) ToBytes() []byte { +func (lump *FaceId) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/facemacrotextureinfo.go b/lumps/facemacrotextureinfo.go index 695555c..55ece38 100644 --- a/lumps/facemacrotextureinfo.go +++ b/lumps/facemacrotextureinfo.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/facemacrotextureinfo" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/facemacrotextureinfo" "log" + "unsafe" ) + /** - Lump 47: FaceMacroTextureInfo - */ +Lump 47: FaceMacroTextureInfo +*/ type FaceMacroTextureInfo struct { - LumpInfo + LumpGeneric data []primitives.FaceMacroTextureInfo } -func (lump FaceMacroTextureInfo) FromBytes(raw []byte, length int32) ILump { +func (lump *FaceMacroTextureInfo) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.FaceMacroTextureInfo, length/int32(unsafe.Sizeof(primitives.FaceMacroTextureInfo{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump FaceMacroTextureInfo) GetData() interface{} { - return &lump.data +func (lump *FaceMacroTextureInfo) GetData() []primitives.FaceMacroTextureInfo { + return lump.data } -func (lump FaceMacroTextureInfo) ToBytes() []byte { +func (lump *FaceMacroTextureInfo) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/game.go b/lumps/game.go index c7aa55c..70cd62b 100644 --- a/lumps/game.go +++ b/lumps/game.go @@ -1,30 +1,31 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/game" "log" + "strings" "unsafe" - primitives "github.com/galaco/bsp/primitives/game" ) - - /** - Lump 35. - @TODO NOTE: This really needs per-game implementations to be useful, otherwise we might as well skip reading this lump entirely - */ +Lump 35. +@TODO NOTE: This really needs per-game implementations to be useful, otherwise we might as well skip reading this lump entirely +*/ type Game struct { - LumpInfo - Header primitives.Header - GameLumps []byte + LumpGeneric + Header primitives.Header + GameLumps []primitives.GenericGameLump + LumpOffset int32 + areOffsetsCorrected bool } -func (lump Game) FromBytes(raw []byte, length int32) ILump { +func (lump *Game) FromBytes(raw []byte, length int32) { lump.LumpInfo.SetLength(length) if len(raw) == 0 { - return lump + return } // First reconstruct the header to be of the right size @@ -33,49 +34,198 @@ func (lump Game) FromBytes(raw []byte, length int32) ILump { // Read header lump.Header.GameLumps = make([]primitives.LumpDef, lumpCount) - headerSize := 4 + (int32(unsafe.Sizeof(primitives.LumpDef{}))*int32(lumpCount)) + headerSize := 4 + (int32(unsafe.Sizeof(primitives.LumpDef{})) * int32(lumpCount)) err := binary.Read(bytes.NewBuffer(raw[4:headerSize]), binary.LittleEndian, &lump.Header.GameLumps) if err != nil { log.Fatal(err) } - // Read gamelumps - // @TODO We dont care about the contents right now - // In future we should create a set of lumps based on file version - // For now implementation just copies all lumps to preserve the file, similar to Unimplemented lumps - payloadLength := length-headerSize - lump.GameLumps = make([]byte, payloadLength) - - err = binary.Read( - bytes.NewBuffer(raw[headerSize:length]), - binary.LittleEndian, &lump.GameLumps) + // Correct file offsets + if lump.areOffsetsCorrected == false { + for index := range lump.Header.GameLumps { + lump.Header.GameLumps[index].FileOffset -= lump.LumpOffset + } + lump.areOffsetsCorrected = true + } - return lump + // Read gamelumps + lump.GameLumps = make([]primitives.GenericGameLump, lumpCount) + for i, lumpHeader := range lump.Header.GameLumps { + lump.GameLumps[i].Length = lumpHeader.FileLength + lump.GameLumps[i].Data = raw[lumpHeader.FileOffset : lumpHeader.FileOffset+lumpHeader.FileLength] + } } -func (lump Game) GetData() interface{} { +func (lump *Game) GetData() *Game { return lump } -func (lump Game) ToBytes() []byte { +func (lump *Game) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.Header.LumpCount) - for _,lumpHeader := range lump.Header.GameLumps { + for _, lumpHeader := range lump.Header.GameLumps { binary.Write(&buf, binary.LittleEndian, lumpHeader) } - payload := append(buf.Bytes(), lump.GameLumps...) - return payload + for _, l := range lump.GameLumps { + binary.Write(&buf, binary.LittleEndian, l) + } + return buf.Bytes() } -func (lump Game) UpdateInternalOffsets(offsetAdjustment int32) Game { - if offsetAdjustment == 0 { - return lump - } +// This update the lumps offsets to be relative to the lump, rather +// than the bsp start +func (lump *Game) UpdateInternalOffsets(fileOffset int32) *Game { + lump.LumpOffset = fileOffset - for index,header := range lump.Header.GameLumps { - header.FileOffset += offsetAdjustment - lump.Header.GameLumps[index] = header + return lump +} + +func (lump *Game) GetStaticPropLump() *primitives.StaticPropLump { + for i, gameLump := range lump.Header.GameLumps { + if gameLump.Id == primitives.StaticPropLumpId { + sprpLump := lump.GameLumps[i] + + offset := 0 + + //dict + numDicts := int32(0) + err := binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+4]), binary.LittleEndian, &numDicts) + if err != nil { + return nil + } + offset += 4 + dicts := primitives.StaticPropDictLump{ + DictEntries: numDicts, + } + dictNames := make([]string, numDicts) + for i := int32(0); i < numDicts; i++ { + t := make([]byte, 128) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+128]), binary.LittleEndian, &t) + if err != nil { + return nil + } + dictNames[i] = strings.TrimRight(string(t), "\x00") + offset += 128 + } + dicts.Name = dictNames + + //leaf + numLeafs := int32(0) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+4]), binary.LittleEndian, &numLeafs) + if err != nil { + return nil + } + offset += 4 + leaf := primitives.StaticPropLeafLump{ + LeafEntries: numLeafs, + } + leafs := make([]uint16, numLeafs) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+int(2*numLeafs)]), binary.LittleEndian, &leafs) + if err != nil { + return nil + } + leaf.Leaf = leafs + offset += int(2 * numLeafs) + + //props + numProps := int32(0) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+4]), binary.LittleEndian, &numProps) + if err != nil { + return nil + } + offset += 4 + props := make([]primitives.IStaticPropDataLump, numProps) + propLumpSize := 0 + switch gameLump.Version { + case 4: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV4{})) * int(numProps) + vprops := make([]primitives.StaticPropV4, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 5: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV5{})) * int(numProps) + vprops := make([]primitives.StaticPropV5, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 6: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV6{})) * int(numProps) + vprops := make([]primitives.StaticPropV6, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 7: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV7{})) * int(numProps) + vprops := make([]primitives.StaticPropV7, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 8: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV8{})) * int(numProps) + vprops := make([]primitives.StaticPropV8, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 9: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV9{})) * int(numProps) + vprops := make([]primitives.StaticPropV9, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 10: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV10{})) * int(numProps) + vprops := make([]primitives.StaticPropV10, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + case 11: + propLumpSize = int(unsafe.Sizeof(primitives.StaticPropV11{})) * int(numProps) + vprops := make([]primitives.StaticPropV11, numProps) + err = binary.Read(bytes.NewBuffer(sprpLump.Data[offset:offset+propLumpSize]), binary.LittleEndian, &vprops) + if err != nil { + return nil + } + for idx := range vprops { + props[idx] = primitives.IStaticPropDataLump(&vprops[idx]) + } + } + + return &primitives.StaticPropLump{ + DictLump: dicts, + LeafLump: leaf, + PropLumps: props, + } + } } - return lump + return nil } diff --git a/lumps/leaf.go b/lumps/leaf.go index 9d21d2a..4f121ef 100644 --- a/lumps/leaf.go +++ b/lumps/leaf.go @@ -1,25 +1,25 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leaf" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leaf" "log" "unsafe" ) /** - Lump 10: Leaf - */ +Lump 10: Leaf +*/ - const MAX_MAP_LEAFS = 65536 +const MAX_MAP_LEAFS = 65536 type Leaf struct { - LumpInfo + LumpGeneric data []primitives.Leaf } -func (lump Leaf) FromBytes(raw []byte, length int32) ILump { +func (lump *Leaf) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Leaf, length/int32(unsafe.Sizeof(primitives.Leaf{}))) structSize := int(unsafe.Sizeof(primitives.Leaf{})) numLeafs := len(lump.data) @@ -35,15 +35,13 @@ func (lump Leaf) FromBytes(raw []byte, length int32) ILump { } } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Leaf) GetData() interface{} { - return &lump.data +func (lump *Leaf) GetData() []primitives.Leaf { + return lump.data } -func (lump Leaf) ToBytes() []byte { +func (lump *Leaf) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leaf_test.go b/lumps/leaf_test.go index 0e6bf4c..3065699 100644 --- a/lumps/leaf_test.go +++ b/lumps/leaf_test.go @@ -1,10 +1,10 @@ package lumps import ( - "testing" - "unsafe" primitives "github.com/galaco/bsp/primitives/leaf" "log" + "testing" + "unsafe" ) const C_STRUCT_SIZE = 32 @@ -18,10 +18,9 @@ func TestLeafDataFromBytes(t *testing.T) { } lump := Leaf{} - data := lump.FromBytes(GetTestDataBytes(), int32(len(GetTestDataBytes()))) + lump.FromBytes(GetTestDataBytes(), int32(len(GetTestDataBytes()))) expected := GetTestLeafData() - actual := (*(data.GetData().(*([]primitives.Leaf))))[0] - + actual := lump.GetData()[0] if actual != expected { log.Println("Expected: ") @@ -54,10 +53,9 @@ func GetTestLeafData() primitives.Leaf { return l } - -func GetTestDataBytes() []byte{ +func GetTestDataBytes() []byte { return []byte{ - 1, // contents + 1, // contents 0, 0, 0, @@ -90,4 +88,4 @@ func GetTestDataBytes() []byte{ 0, 0, } -} \ No newline at end of file +} diff --git a/lumps/leafambientindex.go b/lumps/leafambientindex.go index c8341c2..f336a6b 100644 --- a/lumps/leafambientindex.go +++ b/lumps/leafambientindex.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leafambientindex" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leafambientindex" "log" + "unsafe" ) + /** - Lump 52: Leaf Ambient Index - */ +Lump 52: Leaf Ambient Index +*/ type LeafAmbientIndex struct { - LumpInfo + LumpGeneric data []primitives.LeafAmbientIndex } -func (lump LeafAmbientIndex) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafAmbientIndex) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.LeafAmbientIndex, length/int32(unsafe.Sizeof(primitives.LeafAmbientIndex{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafAmbientIndex) GetData() interface{} { - return &lump.data +func (lump *LeafAmbientIndex) GetData() []primitives.LeafAmbientIndex { + return lump.data } -func (lump LeafAmbientIndex) ToBytes() []byte { +func (lump *LeafAmbientIndex) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafambientindexhdr.go b/lumps/leafambientindexhdr.go index 9d0eb50..9bdafa2 100644 --- a/lumps/leafambientindexhdr.go +++ b/lumps/leafambientindexhdr.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leafambientindex" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leafambientindex" "log" + "unsafe" ) + /** - Lump 51: Leaf Ambient Index HDR - */ +Lump 51: Leaf Ambient Index HDR +*/ type LeafAmbientIndexHDR struct { - LumpInfo + LumpGeneric data []primitives.LeafAmbientIndex } -func (lump LeafAmbientIndexHDR) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafAmbientIndexHDR) FromBytes(raw []byte, length int32) { if length == 0 { - return lump + return } lump.data = make([]primitives.LeafAmbientIndex, length/int32(unsafe.Sizeof(primitives.LeafAmbientIndex{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafAmbientIndexHDR) GetData() interface{} { - return &lump.data +func (lump *LeafAmbientIndexHDR) GetData() []primitives.LeafAmbientIndex { + return lump.data } -func (lump LeafAmbientIndexHDR) ToBytes() []byte { +func (lump *LeafAmbientIndexHDR) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafambientlighting.go b/lumps/leafambientlighting.go index 0199792..fce2f9b 100644 --- a/lumps/leafambientlighting.go +++ b/lumps/leafambientlighting.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leafambientlighting" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leafambientlighting" "log" + "unsafe" ) /** - Lump n: LeafAmbientLighting - */ +Lump n: LeafAmbientLighting +*/ type LeafAmbientLighting struct { - LumpInfo + LumpGeneric data []primitives.LeafAmbientLighting } -func (lump LeafAmbientLighting) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafAmbientLighting) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.LeafAmbientLighting, length/int32(unsafe.Sizeof(primitives.LeafAmbientLighting{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafAmbientLighting) GetData() interface{} { - return &lump.data +func (lump *LeafAmbientLighting) GetData() []primitives.LeafAmbientLighting { + return lump.data } -func (lump LeafAmbientLighting) ToBytes() []byte { +func (lump *LeafAmbientLighting) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafambientlightinghdr.go b/lumps/leafambientlightinghdr.go index a1230fa..050f6dd 100644 --- a/lumps/leafambientlightinghdr.go +++ b/lumps/leafambientlightinghdr.go @@ -1,40 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leafambientlighting" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leafambientlighting" "log" + "unsafe" ) /** - Lump n: LeafAmbientLightingHDR - */ +Lump n: LeafAmbientLightingHDR +*/ type LeafAmbientLightingHDR struct { - LumpInfo + LumpGeneric data []primitives.LeafAmbientLighting } -func (lump LeafAmbientLightingHDR) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafAmbientLightingHDR) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.LeafAmbientLighting, length/int32(unsafe.Sizeof(primitives.LeafAmbientLighting{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafAmbientLightingHDR) GetData() interface{} { - return &lump.data +func (lump *LeafAmbientLightingHDR) GetData() []primitives.LeafAmbientLighting { + return lump.data } -func (lump LeafAmbientLightingHDR) ToBytes() []byte { +func (lump *LeafAmbientLightingHDR) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafbrush.go b/lumps/leafbrush.go index 7f59558..2f21d90 100644 --- a/lumps/leafbrush.go +++ b/lumps/leafbrush.go @@ -1,36 +1,34 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 17: LeafBrush - */ +Lump 17: LeafBrush +*/ type LeafBrush struct { - LumpInfo + LumpGeneric data []uint16 // MAX_MAP_LEAFBRUSHES = 65536 } -func (lump LeafBrush) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafBrush) FromBytes(raw []byte, length int32) { lump.data = make([]uint16, length/2) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafBrush) GetData() interface{} { - return &lump.data +func (lump *LeafBrush) GetData() []uint16 { + return lump.data } -func (lump LeafBrush) ToBytes() []byte { +func (lump *LeafBrush) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() -} \ No newline at end of file +} diff --git a/lumps/leafface.go b/lumps/leafface.go index 59bf961..de5e03e 100644 --- a/lumps/leafface.go +++ b/lumps/leafface.go @@ -1,35 +1,33 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 16: LeafFace - */ +Lump 16: LeafFace +*/ type LeafFace struct { - LumpInfo + LumpGeneric data []uint16 // MAX_MAP_LEAFFACES = 65536 } -func (lump LeafFace) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafFace) FromBytes(raw []byte, length int32) { lump.data = make([]uint16, length/2) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafFace) GetData() interface{} { - return &lump.data +func (lump *LeafFace) GetData() []uint16 { + return lump.data } -func (lump LeafFace) ToBytes() []byte { +func (lump *LeafFace) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafmindisttowater.go b/lumps/leafmindisttowater.go index b54b7aa..8bb092a 100644 --- a/lumps/leafmindisttowater.go +++ b/lumps/leafmindisttowater.go @@ -1,36 +1,34 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 46: LeafMinDistToWater - */ +Lump 46: LeafMinDistToWater +*/ type LeafMinDistToWater struct { - LumpInfo + LumpGeneric data []uint16 } -func (lump LeafMinDistToWater) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafMinDistToWater) FromBytes(raw []byte, length int32) { lump.data = make([]uint16, length/int32(2)) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafMinDistToWater) GetData() interface{} { - return &lump.data +func (lump *LeafMinDistToWater) GetData() []uint16 { + return lump.data } -func (lump LeafMinDistToWater) ToBytes() []byte { +func (lump *LeafMinDistToWater) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/leafwaterdata.go b/lumps/leafwaterdata.go index 05e9511..acf1bc9 100644 --- a/lumps/leafwaterdata.go +++ b/lumps/leafwaterdata.go @@ -1,41 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/leafwaterdata" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/leafwaterdata" "log" "unsafe" ) /** - Lump 36: leafwaterdata - */ +Lump 36: leafwaterdata +*/ type LeafWaterData struct { - LumpInfo + LumpGeneric data []primitives.LeafWaterData } -func (lump LeafWaterData) FromBytes(raw []byte, length int32) ILump { +func (lump *LeafWaterData) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.LeafWaterData, length/int32(unsafe.Sizeof(primitives.LeafWaterData{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump LeafWaterData) GetData() interface{} { - return &lump.data +func (lump *LeafWaterData) GetData() []primitives.LeafWaterData { + return lump.data } -func (lump LeafWaterData) ToBytes() []byte { +func (lump *LeafWaterData) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/lighting.go b/lumps/lighting.go index 75cc96c..939fbc7 100644 --- a/lumps/lighting.go +++ b/lumps/lighting.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/common" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/common" "log" + "unsafe" ) + /** - Lump 8: Lighting - */ +Lump 8: Lighting +*/ type Lighting struct { - LumpInfo + LumpGeneric data []primitives.ColorRGBExponent32 } -func (lump Lighting) FromBytes(raw []byte, length int32) ILump { +func (lump *Lighting) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.ColorRGBExponent32, length/int32(unsafe.Sizeof(primitives.ColorRGBExponent32{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Lighting) GetData() interface{} { - return &lump.data +func (lump *Lighting) GetData() []primitives.ColorRGBExponent32 { + return lump.data } -func (lump Lighting) ToBytes() []byte { +func (lump *Lighting) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/lumps.go b/lumps/lumps.go index acaf5ed..cab4b0f 100644 --- a/lumps/lumps.go +++ b/lumps/lumps.go @@ -1,42 +1,52 @@ package lumps /** - Lump interface. - Organise Lump data in a cleaner and more accessible manner - */ +Lump interface. +Organise Lump data in a cleaner and more accessible manner +*/ type ILump interface { /** - Import a []byte to a defined lump structure(s). - */ - FromBytes([]byte, int32) ILump + Import a []byte to a defined lump structure(s). + */ + FromBytes([]byte, int32) /** - Return populated lump structure(s). - */ - GetData() interface{} - - /** - Export lump structure back to []byte. - */ + Export lump structure back to []byte. + */ ToBytes() []byte } +type LumpGeneric struct { + LumpInfo + data []byte +} + +func (lump *LumpGeneric) FromBytes(data []byte, length int32) { + lump.length = length + lump.data = data +} + +func (lump *LumpGeneric) ToBytes() []byte { + return lump.data +} + /** - Helper info for a lump - */ +Helper info for a lump +*/ type LumpInfo struct { length int32 } /** - Return lump import length in bytes. - */ +Return lump import length in bytes. +*/ func (info LumpInfo) GetLength() int32 { return info.length } + /** - Set lump import length in bytes - */ +Set lump import length in bytes +*/ func (info LumpInfo) SetLength(length int32) { info.length = length -} \ No newline at end of file +} diff --git a/lumps/mapflags.go b/lumps/mapflags.go index 051a2e9..db373f4 100644 --- a/lumps/mapflags.go +++ b/lumps/mapflags.go @@ -1,38 +1,37 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/mapflags" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/mapflags" "log" ) + /** - Lump 59: MapFlags - */ +Lump 59: MapFlags +*/ type MapFlags struct { - LumpInfo + LumpGeneric data primitives.MapFlags } -func (lump MapFlags) FromBytes(raw []byte, length int32) ILump { +func (lump *MapFlags) FromBytes(raw []byte, length int32) { if length == 0 { - return lump + return } - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump MapFlags) GetData() interface{} { +func (lump *MapFlags) GetData() *primitives.MapFlags { return &lump.data } -func (lump MapFlags) ToBytes() []byte { +func (lump *MapFlags) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/model.go b/lumps/model.go index 69dcd93..fbe501a 100644 --- a/lumps/model.go +++ b/lumps/model.go @@ -1,37 +1,35 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/model" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/model" "log" "unsafe" ) /** - Lump 14: Model - */ +Lump 14: Model +*/ type Model struct { - LumpInfo + LumpGeneric data []primitives.Model } -func (lump Model) FromBytes(raw []byte, length int32) ILump { +func (lump *Model) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Model, length/int32(unsafe.Sizeof(primitives.Model{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Model) GetData() interface{} { - return &lump.data +func (lump *Model) GetData() []primitives.Model { + return lump.data } -func (lump Model) ToBytes() []byte { +func (lump *Model) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/node.go b/lumps/node.go index 4ba57a3..2060434 100644 --- a/lumps/node.go +++ b/lumps/node.go @@ -1,37 +1,35 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/node" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/node" "log" "unsafe" ) /** - Lump 5: Node - */ +Lump 5: Node +*/ type Node struct { - LumpInfo + LumpGeneric data []primitives.Node // MAP_MAX_NODES = 65536 } -func (lump Node) FromBytes(raw []byte, length int32) ILump { +func (lump *Node) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Node, length/int32(unsafe.Sizeof(primitives.Node{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Node) GetData() interface{} { - return &lump.data +func (lump *Node) GetData() []primitives.Node { + return lump.data } -func (lump Node) ToBytes() []byte { +func (lump *Node) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/occlusion.go b/lumps/occlusion.go index 5faadd1..2e8d09d 100644 --- a/lumps/occlusion.go +++ b/lumps/occlusion.go @@ -1,33 +1,33 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/occlusion" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/occlusion" "log" + "unsafe" ) /** - Lump 9: Occlusion - */ +Lump 9: Occlusion +*/ type Occlusion struct { - LumpInfo - Count int32 - Data []primitives.OcclusionData // len(slice) = Count - PolyDataCount int32 - PolyData []primitives.OcclusionPolyData //len(slice) = PolyDataCount + LumpGeneric + Count int32 + Data []primitives.OcclusionData // len(slice) = Count + PolyDataCount int32 + PolyData []primitives.OcclusionPolyData //len(slice) = PolyDataCount VertexIndexCount int32 - VertexIndices []int32 //len(slice) = VertexIndexCount + VertexIndices []int32 //len(slice) = VertexIndexCount } -func (lump Occlusion) FromBytes(raw []byte, length int32) ILump { +func (lump *Occlusion) FromBytes(raw []byte, length int32) { if length == 0 { - return lump + return } offset := 0 // data - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.Count) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.Count) if err != nil { log.Fatal(err) } @@ -64,33 +64,30 @@ func (lump Occlusion) FromBytes(raw []byte, length int32) ILump { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Occlusion) GetData() interface{} { - return &lump +func (lump *Occlusion) GetData() *Occlusion { + return lump } -func (lump Occlusion) ToBytes() []byte { +func (lump *Occlusion) ToBytes() []byte { var buf bytes.Buffer // write data binary.Write(&buf, binary.LittleEndian, lump.Count) - for _,data := range lump.Data { + for _, data := range lump.Data { binary.Write(&buf, binary.LittleEndian, data) } // write polydata binary.Write(&buf, binary.LittleEndian, lump.PolyDataCount) - for _,data := range lump.PolyData { + for _, data := range lump.PolyData { binary.Write(&buf, binary.LittleEndian, data) } // write indices binary.Write(&buf, binary.LittleEndian, lump.VertexIndexCount) - for _,data := range lump.VertexIndices { + for _, data := range lump.VertexIndices { binary.Write(&buf, binary.LittleEndian, data) } return buf.Bytes() diff --git a/lumps/overlay.go b/lumps/overlay.go index 1407bcb..cc826a9 100644 --- a/lumps/overlay.go +++ b/lumps/overlay.go @@ -1,39 +1,37 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/overlay" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/overlay" "log" + "unsafe" ) // Lump 45: Overlay // Consists of an array of Overlay structs type Overlay struct { - LumpInfo + LumpGeneric data []primitives.Overlay } -func (lump Overlay) FromBytes(raw []byte, length int32) ILump { +func (lump *Overlay) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.Overlay, length/int32(unsafe.Sizeof(primitives.Overlay{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Overlay) GetData() interface{} { - return &lump.data +func (lump *Overlay) GetData() []primitives.Overlay { + return lump.data } -func (lump Overlay) ToBytes() []byte { +func (lump *Overlay) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/overlayfade.go b/lumps/overlayfade.go index b46dbe6..92958f3 100644 --- a/lumps/overlayfade.go +++ b/lumps/overlayfade.go @@ -1,39 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/overlayfade" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/overlayfade" "log" + "unsafe" ) + /** - Lump 60: Overlayfades - */ +Lump 60: Overlayfades +*/ type OverlayFade struct { - LumpInfo + LumpGeneric data []primitives.OverlayFade } -func (lump OverlayFade) FromBytes(raw []byte, length int32) ILump { +func (lump *OverlayFade) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.OverlayFade, length/int32(unsafe.Sizeof(primitives.OverlayFade{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump OverlayFade) GetData() interface{} { - return &lump.data +func (lump *OverlayFade) GetData() []primitives.OverlayFade { + return lump.data } -func (lump OverlayFade) ToBytes() []byte { +func (lump *OverlayFade) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/pakfile.go b/lumps/pakfile.go index fcae475..93da9b6 100644 --- a/lumps/pakfile.go +++ b/lumps/pakfile.go @@ -1,35 +1,62 @@ package lumps import ( - "encoding/binary" + "archive/zip" "bytes" - "log" + "encoding/binary" + "io/ioutil" + "strings" ) /** - Lump 40: Pakfile - */ +Lump 40: Pakfile +*/ type Pakfile struct { - LumpInfo - data []byte + LumpGeneric + zipReader *zip.Reader } -func (lump Pakfile) FromBytes(raw []byte, length int32) ILump { - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) - if err != nil { - log.Fatal(err) - } +func (lump *Pakfile) FromBytes(raw []byte, length int32) { + lump.data = raw lump.LumpInfo.SetLength(length) - return lump + b := bytes.NewReader(raw) + zipReader, err := zip.NewReader(b, int64(length)) + if err == nil { + lump.zipReader = zipReader + } } -func (lump Pakfile) GetData() interface{} { - return &lump.data +// Returns this lumps contents as whatever internal format this +// lump uses (requires casting) +func (lump *Pakfile) GetData() *zip.Reader { + return lump.zipReader } -func (lump Pakfile) ToBytes() []byte { +// Returns the contents of this lump as a []byte +func (lump *Pakfile) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() -} \ No newline at end of file +} + +// Get a specific file from the pak +func (lump *Pakfile) GetFile(filePath string) ([]byte, error) { + filePath = lump.sanitisePath(filePath) + for _, f := range lump.zipReader.File { + if strings.ToLower(f.Name) == filePath { + rc, err := f.Open() + if err != nil { + return nil, err + } + return ioutil.ReadAll(rc) + } + } + return []byte{}, nil +} + +func (lump *Pakfile) sanitisePath(filePath string) string { + filePath = strings.ToLower(filePath) + filePath = strings.Replace(filePath, "/", "\\", -1) + return filePath +} diff --git a/lumps/physcollide.go b/lumps/physcollide.go index 9f301db..09258a4 100644 --- a/lumps/physcollide.go +++ b/lumps/physcollide.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/physcollide" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/physcollide" "log" + "unsafe" ) + /** - Lump 20: PhysCollide - */ +Lump 20: PhysCollide +*/ type PhysCollide struct { - LumpInfo + LumpGeneric data []primitives.PhysCollideEntry } -func (lump PhysCollide) FromBytes(raw []byte, length int32) ILump { +func (lump *PhysCollide) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.PhysCollideEntry, length/int32(unsafe.Sizeof(primitives.PhysCollideEntry{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump PhysCollide) GetData() interface{} { - return &lump.data +func (lump *PhysCollide) GetData() []primitives.PhysCollideEntry { + return lump.data } -func (lump PhysCollide) ToBytes() []byte { +func (lump *PhysCollide) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/physdisp.go b/lumps/physdisp.go index 9e69989..146a0be 100644 --- a/lumps/physdisp.go +++ b/lumps/physdisp.go @@ -1,28 +1,22 @@ package lumps /** - Lump 28: PhysDisp - */ +Lump 28: PhysDisp +*/ type PhysDisp struct { - LumpInfo + LumpGeneric data []byte } -func (lump PhysDisp) FromBytes(raw []byte, length int32) ILump { - if length == 0 { - return lump - } - +func (lump *PhysDisp) FromBytes(raw []byte, length int32) { lump.data = raw lump.LumpInfo.SetLength(length) - - return lump } -func (lump PhysDisp) GetData() interface{} { - return &lump.data +func (lump *PhysDisp) GetData() []byte { + return lump.data } -func (lump PhysDisp) ToBytes() []byte { +func (lump *PhysDisp) ToBytes() []byte { return lump.data } diff --git a/lumps/planes.go b/lumps/planes.go index 4b457b9..bb8f0b6 100644 --- a/lumps/planes.go +++ b/lumps/planes.go @@ -1,39 +1,36 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/plane" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/plane" "log" "unsafe" ) /** - Lump 1: Planes - */ +Lump 1: Planes +*/ type Planes struct { - LumpInfo + LumpGeneric data []primitives.Plane // MAP_MAX_PLANES = 65536 } -func (lump Planes) FromBytes(raw []byte, length int32) ILump { +func (lump *Planes) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.Plane, length/int32(unsafe.Sizeof(primitives.Plane{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Planes) GetData() interface{} { +func (lump *Planes) GetData() []primitives.Plane { return lump.data } -func (lump Planes) ToBytes() []byte { +func (lump *Planes) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() } - diff --git a/lumps/primindice.go b/lumps/primindice.go index 0400ea0..943efa8 100644 --- a/lumps/primindice.go +++ b/lumps/primindice.go @@ -1,39 +1,37 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 39: PrimIndice - */ +Lump 39: PrimIndice +*/ type PrimIndice struct { - LumpInfo + LumpGeneric data []uint16 } -func (lump PrimIndice) FromBytes(raw []byte, length int32) ILump { +func (lump *PrimIndice) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]uint16, length/int32(2)) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump PrimIndice) GetData() interface{} { - return &lump.data +func (lump *PrimIndice) GetData() []uint16 { + return lump.data } -func (lump PrimIndice) ToBytes() []byte { +func (lump *PrimIndice) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/primitive.go b/lumps/primitive.go index 7fe967f..83d9ddd 100644 --- a/lumps/primitive.go +++ b/lumps/primitive.go @@ -1,40 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/primitive" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/primitive" "log" + "unsafe" ) + /** - Lump 36: Primitive - */ +Lump 36: Primitive +*/ type Primitive struct { - LumpInfo + LumpGeneric data []primitives.Primitive } -func (lump Primitive) FromBytes(raw []byte, length int32) ILump { +func (lump *Primitive) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.Primitive, length/int32(unsafe.Sizeof(primitives.Primitive{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Primitive) GetData() interface{} { - return &lump.data +func (lump *Primitive) GetData() []primitives.Primitive { + return lump.data } -func (lump Primitive) ToBytes() []byte { +func (lump *Primitive) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/primvert.go b/lumps/primvert.go index a479faa..7b2cc72 100644 --- a/lumps/primvert.go +++ b/lumps/primvert.go @@ -1,41 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/primvert" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/primvert" "log" + "unsafe" ) /** - Lump 37: PrimVert - */ +Lump 37: PrimVert +*/ type PrimVert struct { - LumpInfo + LumpGeneric data []primitives.PrimVert } -func (lump PrimVert) FromBytes(raw []byte, length int32) ILump { +func (lump *PrimVert) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.PrimVert, length/int32(unsafe.Sizeof(primitives.PrimVert{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump PrimVert) GetData() interface{} { - return &lump.data +func (lump *PrimVert) GetData() []primitives.PrimVert { + return lump.data } -func (lump PrimVert) ToBytes() []byte { +func (lump *PrimVert) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/surfedge.go b/lumps/surfedge.go index 25f1c5a..2aefdbe 100644 --- a/lumps/surfedge.go +++ b/lumps/surfedge.go @@ -1,35 +1,33 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 13: Surfedge - */ +Lump 13: Surfedge +*/ type Surfedge struct { - LumpInfo + LumpGeneric data []int32 // MAX_MAP_SURFEDGES = 512000 } -func (lump Surfedge) FromBytes(raw []byte, length int32) ILump { +func (lump *Surfedge) FromBytes(raw []byte, length int32) { lump.data = make([]int32, length/4) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump Surfedge) GetData() interface{} { - return &lump.data +func (lump *Surfedge) GetData() []int32 { + return lump.data } -func (lump Surfedge) ToBytes() []byte { +func (lump *Surfedge) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/texdata.go b/lumps/texdata.go index dd7f0bc..b35b3f7 100644 --- a/lumps/texdata.go +++ b/lumps/texdata.go @@ -1,36 +1,35 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/texdata" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/texdata" "log" "unsafe" ) /** - Lump 2: TexData - */ +Lump 2: TexData +*/ type TexData struct { - LumpInfo + LumpGeneric data []primitives.TexData } -func (lump TexData) FromBytes(raw []byte, length int32) ILump { + +func (lump *TexData) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.TexData, length/int32(unsafe.Sizeof(primitives.TexData{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump TexData) GetData() interface{} { - return &lump.data +func (lump *TexData) GetData() []primitives.TexData { + return lump.data } -func (lump TexData) ToBytes() []byte { +func (lump *TexData) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/texdatastringdata.go b/lumps/texdatastringdata.go index 9a25434..5b73187 100644 --- a/lumps/texdatastringdata.go +++ b/lumps/texdatastringdata.go @@ -1,25 +1,22 @@ package lumps /** - Lump 43: TexdataStringData - */ +Lump 43: TexdataStringData +*/ type TexdataStringData struct { - LumpInfo + LumpGeneric data string // MAX_MAP_TEXDATA_STRING_DATA = 256000, TEXTURE_NAME_LENGTH = 128 } -func (lump TexdataStringData) FromBytes(raw []byte, length int32) ILump { +func (lump *TexdataStringData) FromBytes(raw []byte, length int32) { lump.data = string(raw) lump.LumpInfo.SetLength(length) - - return lump } -func (lump TexdataStringData) GetData() interface{} { - return &lump.data +func (lump *TexdataStringData) GetData() string { + return lump.data } -func (lump TexdataStringData) ToBytes() []byte { +func (lump *TexdataStringData) ToBytes() []byte { return []byte(lump.data) } - diff --git a/lumps/texdatastringtable.go b/lumps/texdatastringtable.go index 6fc6451..ec4f527 100644 --- a/lumps/texdatastringtable.go +++ b/lumps/texdatastringtable.go @@ -1,36 +1,34 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 44: TexDataStringTable - */ +Lump 44: TexDataStringTable +*/ type TexDataStringTable struct { - LumpInfo + LumpGeneric data []int32 // MAX_MAP_TEXINFO = 2048 } -func (lump TexDataStringTable) FromBytes(raw []byte, length int32) ILump { +func (lump *TexDataStringTable) FromBytes(raw []byte, length int32) { lump.data = make([]int32, length/4) err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump TexDataStringTable) GetData() interface{} { - return &lump.data +func (lump *TexDataStringTable) GetData() []int32 { + return lump.data } -func (lump TexDataStringTable) ToBytes() []byte { +func (lump *TexDataStringTable) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() -} \ No newline at end of file +} diff --git a/lumps/texinfo.go b/lumps/texinfo.go index 37b5d67..27a342a 100644 --- a/lumps/texinfo.go +++ b/lumps/texinfo.go @@ -1,38 +1,36 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/texinfo" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/texinfo" "log" "unsafe" ) /** - Lump 6: TexInfo - */ +Lump 6: TexInfo +*/ type TexInfo struct { - LumpInfo + LumpGeneric data []primitives.TexInfo } -func (lump TexInfo) FromBytes(raw []byte, length int32) ILump { +func (lump *TexInfo) FromBytes(raw []byte, length int32) { lump.data = make([]primitives.TexInfo, length/int32(unsafe.Sizeof(primitives.TexInfo{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } -func (lump TexInfo) GetData() interface{} { - return &lump.data +func (lump *TexInfo) GetData() []primitives.TexInfo { + return lump.data } -func (lump TexInfo) ToBytes() []byte { +func (lump *TexInfo) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/unimplemented.go b/lumps/unimplemented.go index 3f77629..27c604f 100644 --- a/lumps/unimplemented.go +++ b/lumps/unimplemented.go @@ -1,28 +1,22 @@ package lumps - /** - Lump n: - */ +Lump n: +*/ type Unimplemented struct { - LumpInfo + LumpGeneric data []byte } -func (lump Unimplemented) FromBytes(raw []byte, length int32) ILump { - if length == 0 { - return lump - } +func (lump *Unimplemented) FromBytes(raw []byte, length int32) { lump.data = raw lump.LumpInfo.SetLength(length) - - return lump } -func (lump Unimplemented) GetData() interface{} { +func (lump *Unimplemented) GetData() []byte { return lump.data } -func (lump Unimplemented) ToBytes() []byte { +func (lump *Unimplemented) ToBytes() []byte { return lump.data } diff --git a/lumps/vertex.go b/lumps/vertex.go index 84f79ac..0d01dde 100644 --- a/lumps/vertex.go +++ b/lumps/vertex.go @@ -1,40 +1,39 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" + "github.com/go-gl/mathgl/mgl32" "log" "unsafe" - "github.com/go-gl/mathgl/mgl32" ) /** - Lump 3: Vertex - */ +Lump 3: Vertex +*/ type Vertex struct { - LumpInfo + LumpGeneric data []mgl32.Vec3 } -func (lump Vertex) FromBytes(raw []byte, length int32) ILump { + +func (lump *Vertex) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]mgl32.Vec3, length/int32(unsafe.Sizeof(mgl32.Vec3{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump Vertex) GetData() interface{} { - return &lump.data +func (lump *Vertex) GetData() []mgl32.Vec3 { + return lump.data } -func (lump Vertex) ToBytes() []byte { +func (lump *Vertex) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/vertnormal.go b/lumps/vertnormal.go index 62cd346..10d06d9 100644 --- a/lumps/vertnormal.go +++ b/lumps/vertnormal.go @@ -1,41 +1,39 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/vertnormal" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/vertnormal" "log" + "unsafe" ) /** - Lump 30: VertNormal - */ +Lump 30: VertNormal +*/ type VertNormal struct { - LumpInfo + LumpGeneric data []primitives.VertNormal } -func (lump VertNormal) FromBytes(raw []byte, length int32) ILump { +func (lump *VertNormal) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.VertNormal, length/int32(unsafe.Sizeof(primitives.VertNormal{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump VertNormal) GetData() interface{} { - return &lump.data +func (lump *VertNormal) GetData() []primitives.VertNormal { + return lump.data } -func (lump VertNormal) ToBytes() []byte { +func (lump *VertNormal) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/vertnormalindice.go b/lumps/vertnormalindice.go index bd6dc84..a8ad2d4 100644 --- a/lumps/vertnormalindice.go +++ b/lumps/vertnormalindice.go @@ -1,39 +1,37 @@ package lumps import ( - "encoding/binary" "bytes" + "encoding/binary" "log" ) /** - Lump 31: VertNormalIndice - */ +Lump 31: VertNormalIndice +*/ type VertNormalIndice struct { - LumpInfo + LumpGeneric data []uint16 } -func (lump VertNormalIndice) FromBytes(raw []byte, length int32) ILump { +func (lump *VertNormalIndice) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]uint16, length/int32(2)) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump VertNormalIndice) GetData() interface{} { - return &lump.data +func (lump *VertNormalIndice) GetData() []uint16 { + return lump.data } -func (lump VertNormalIndice) ToBytes() []byte { +func (lump *VertNormalIndice) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/visibility.go b/lumps/visibility.go index 7fc9876..f5cdcca 100644 --- a/lumps/visibility.go +++ b/lumps/visibility.go @@ -1,22 +1,22 @@ package lumps import ( - "encoding/binary" "bytes" - "log" + "encoding/binary" primitives "github.com/galaco/bsp/primitives/visibility" + "log" ) // Lump 4: Visibility type Visibility struct { - LumpInfo + LumpGeneric data primitives.Vis } // FromBytes // Populate receiver lump from byte slice -func (lump Visibility) FromBytes(raw []byte, length int32) ILump { - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data.NumClusters) +func (lump *Visibility) FromBytes(raw []byte, length int32) { + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data.NumClusters) if err != nil { log.Fatal(err) } @@ -25,122 +25,27 @@ func (lump Visibility) FromBytes(raw []byte, length int32) ILump { if err != nil { log.Fatal(err) } - bitVectorLength := (length - 4) - (8 * lump.data.NumClusters) - lump.data.BitVectors = make([]byte, bitVectorLength) - err = binary.Read(bytes.NewBuffer(raw[length-bitVectorLength:]), binary.LittleEndian, &lump.data.BitVectors) + lump.data.BitVectors = make([]byte, length) + err = binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data.BitVectors) if err != nil { log.Fatal(err) } lump.LumpInfo.SetLength(length) - - return lump } // GetData // Get internal lump data structure // Returns interface{} to fulfill interface // Should be typecasted to expected type -func (lump Visibility) GetData() interface{} { +func (lump *Visibility) GetData() *primitives.Vis { return &lump.data } // ToBytes // Convert internal data structure into a byte slice -func (lump Visibility) ToBytes() []byte { +func (lump *Visibility) ToBytes() []byte { var buf bytes.Buffer - binary.Write(&buf, binary.LittleEndian, lump.data.NumClusters) - for _, offset := range lump.data.ByteOffset { - binary.Write(&buf, binary.LittleEndian, offset) - } binary.Write(&buf, binary.LittleEndian, lump.data.BitVectors) return buf.Bytes() } - -// GetVisCache -// Determines the Potential Visible Set for a cluster? -func (lump *Visibility) GetVisCache(lastOffset int, cluster int, pvs []byte) int { - // get the PVS for the pos to limit the number of checks - if lump.data.NumClusters == 0 { - for i := range pvs { - if i < int((lump.data.NumClusters + 7) / 8) { - pvs[i] = 255 - } else { - break - } - } - lastOffset = -1 - } else { - if cluster < 0 { - // Error, point embedded in wall - // sampled[0][1] = 255; - for i := range pvs { - if i < int((lump.data.NumClusters + 7) / 8) { - pvs[i] = 255 - } else { - break - } - } - lastOffset = -1 - } else { - thisOffset := int(lump.data.ByteOffset[cluster][primitives.DVIS_PVS]) - if thisOffset != lastOffset { - if thisOffset == -1 { - log.Fatalf("visofs == -1\n") - } - - visRunlength := lump.ToBytes()[thisOffset:] - pvs = lump.DecompressVis(visRunlength, len(pvs)) - } - lastOffset = thisOffset - } - } - return lastOffset -} - -// DecompressVis -// Decompress Visibility BitVectors -// Note: Often we want to decompress only a subset of the compressed data the lump contains. As such, -// target compressed data is passed in rather than derived from the receiver. -func (lump *Visibility) DecompressVis(in []byte, length int) []byte { - var c int - var out = make([]byte, length) - var row int - var inOffset = 0 - var outOffset = 0 - - row = int(lump.data.NumClusters + 7) >> 3 - - hasSimulatedDoWhile := false - for (outOffset < len(out) && int(out[outOffset]) < row) || hasSimulatedDoWhile == false { - hasSimulatedDoWhile = true - - // @NOTE: The ++ operations may need to shift to the stop - // In this case, that will cause an out-of-bounds unless we compare to len()-1 - if inOffset < len(in) { - out[outOffset] = in[inOffset] - inOffset++ - outOffset++ - continue - } - - c = int(in[1]) - if c == 0 { - log.Fatalf("DecompressVis: 0 repeat") - } - - inOffset += 2 - if (int(out[outOffset])) + c > row { - c = row - int(out[outOffset]) - log.Printf("warning: Vis decompression overrun\n") - } - - for c > 0 { - outOffset++ - out[outOffset] = 0 - c-- - } - } - - return out -} diff --git a/lumps/worldlight.go b/lumps/worldlight.go index e11147f..1c1d78b 100644 --- a/lumps/worldlight.go +++ b/lumps/worldlight.go @@ -1,40 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/worldlight" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/worldlight" "log" + "unsafe" ) /** - Lump 15: Worldlight - */ +Lump 15: Worldlight +*/ type WorldLight struct { - LumpInfo + LumpGeneric data []primitives.WorldLight } -func (lump WorldLight) FromBytes(raw []byte, length int32) ILump { +func (lump *WorldLight) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.WorldLight, length/int32(unsafe.Sizeof(primitives.WorldLight{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump WorldLight) GetData() interface{} { - return &lump.data +func (lump *WorldLight) GetData() []primitives.WorldLight { + return lump.data } -func (lump WorldLight) ToBytes() []byte { +func (lump *WorldLight) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/lumps/worldlighthdr.go b/lumps/worldlighthdr.go index 3b0ddbc..1d25c08 100644 --- a/lumps/worldlighthdr.go +++ b/lumps/worldlighthdr.go @@ -1,40 +1,38 @@ package lumps import ( - primitives "github.com/galaco/bsp/primitives/worldlight" - "unsafe" - "encoding/binary" "bytes" + "encoding/binary" + primitives "github.com/galaco/bsp/primitives/worldlight" "log" + "unsafe" ) /** - Lump 15: Worldlight - */ +Lump 15: Worldlight +*/ type WorldLightHDR struct { - LumpInfo + LumpGeneric data []primitives.WorldLight } -func (lump WorldLightHDR) FromBytes(raw []byte, length int32) ILump { +func (lump *WorldLightHDR) FromBytes(raw []byte, length int32) { + lump.LumpInfo.SetLength(length) if length == 0 { - return lump + return } lump.data = make([]primitives.WorldLight, length/int32(unsafe.Sizeof(primitives.WorldLight{}))) - err := binary.Read(bytes.NewBuffer(raw[:]), binary.LittleEndian, &lump.data) + err := binary.Read(bytes.NewBuffer(raw), binary.LittleEndian, &lump.data) if err != nil { log.Fatal(err) } - lump.LumpInfo.SetLength(length) - - return lump } -func (lump WorldLightHDR) GetData() interface{} { - return &lump.data +func (lump *WorldLightHDR) GetData() []primitives.WorldLight { + return lump.data } -func (lump WorldLightHDR) ToBytes() []byte { +func (lump *WorldLightHDR) ToBytes() []byte { var buf bytes.Buffer binary.Write(&buf, binary.LittleEndian, lump.data) return buf.Bytes() diff --git a/primitives/area/area.go b/primitives/area/area.go index 21ec6b5..cd25b12 100644 --- a/primitives/area/area.go +++ b/primitives/area/area.go @@ -1,6 +1,6 @@ package area type Area struct { - NumAreaPortals int32 + NumAreaPortals int32 FirstAreaPortal int32 -} \ No newline at end of file +} diff --git a/primitives/areaportal/areaportal.go b/primitives/areaportal/areaportal.go index 12202f5..0363c8d 100644 --- a/primitives/areaportal/areaportal.go +++ b/primitives/areaportal/areaportal.go @@ -1,10 +1,10 @@ package areaportal type AreaPortal struct { - PortalKey uint16 // Entities have a key called portal number (and in vbsp a variable called areaportalnum) to bind them to the area portals by comparing this value - OtherArea uint16 // The area this portal looks into + PortalKey uint16 // Entities have a key called portal number (and in vbsp a variable called areaportalnum) to bind them to the area portals by comparing this value + OtherArea uint16 // The area this portal looks into FirstClipPortalVert uint16 // Portal geometry - NumClipPortalVerts uint16 + NumClipPortalVerts uint16 PlaneNum int32 -} \ No newline at end of file +} diff --git a/primitives/brush/brush.go b/primitives/brush/brush.go index a74d5a9..7e7e858 100644 --- a/primitives/brush/brush.go +++ b/primitives/brush/brush.go @@ -3,5 +3,5 @@ package brush type Brush struct { FirstSide int32 NumSides int32 - Contents int32 + Contents int32 } diff --git a/primitives/brushside/brushside.go b/primitives/brushside/brushside.go index 88e7ac2..6672f30 100644 --- a/primitives/brushside/brushside.go +++ b/primitives/brushside/brushside.go @@ -1,9 +1,8 @@ package brushside - type BrushSide struct { PlaneNum uint16 - TexInfo int16 + TexInfo int16 DispInfo int16 - Bevel int16 + Bevel int16 } diff --git a/primitives/common/common.go b/primitives/common/common.go index 918c63c..273f913 100644 --- a/primitives/common/common.go +++ b/primitives/common/common.go @@ -5,64 +5,63 @@ import ( "github.com/go-gl/mathgl/mgl32" ) - type ColorRGBExponent32 struct { - R byte - G byte - B byte + R byte + G byte + B byte Exponent byte } const MAX_POINTS_ON_FIXED_WINDING = 12 + //const MAX_DISPVERTS = 0 //const MAX_DISPTRIS = 0 - type Winding struct { - Original int32 // qboolean = int32 + Original int32 // qboolean = int32 NumPoints int32 - Points []mgl32.Vec3 + Points []mgl32.Vec3 } type Side struct { - PlaneNum int32 - TexInfo int32 - MapDisp *MapDispInfo - Winding *Winding - Original *Side - Contents int32 - Surf int32 - Visible int32 - Tested int32 - Bevel int32 - Next *Side - OrigIndex int32 - Id int32 - SmoothingGroups uint32 - AOverlayIds []int32 - AWaterOverlayIds []int32 + PlaneNum int32 + TexInfo int32 + MapDisp *MapDispInfo + Winding *Winding + Original *Side + Contents int32 + Surf int32 + Visible int32 + Tested int32 + Bevel int32 + Next *Side + OrigIndex int32 + Id int32 + SmoothingGroups uint32 + AOverlayIds []int32 + AWaterOverlayIds []int32 DynamicShadowsEnabled bool } type MapDispInfo struct { - Face face.Face - EntityNum int32 - Power int32 - MinTess int32 + Face face.Face + EntityNum int32 + Power int32 + MinTess int32 SmoothingAngle float32 - uAxis mgl32.Vec3 - vAxis mgl32.Vec3 - StartPosition mgl32.Vec3 - AlphaValues []float32 - MaxDispDist float32 - DispDists []float32 - VectorDisps []mgl32.Vec3 - VectorOffsets []mgl32.Vec3 - Contents int32 - BrushSideID int32 - Flags int32 + uAxis mgl32.Vec3 + vAxis mgl32.Vec3 + StartPosition mgl32.Vec3 + AlphaValues []float32 + MaxDispDist float32 + DispDists []float32 + VectorDisps []mgl32.Vec3 + VectorOffsets []mgl32.Vec3 + Contents int32 + BrushSideID int32 + Flags int32 // #ifdef VSVMFIO // Elevation float32 // OffsetNormals []Vector -} \ No newline at end of file +} diff --git a/primitives/cubemap/cubemap.go b/primitives/cubemap/cubemap.go index 0923168..8ad3c96 100644 --- a/primitives/cubemap/cubemap.go +++ b/primitives/cubemap/cubemap.go @@ -5,7 +5,7 @@ import ( ) type CubemapSample struct { - Origin mgl32.Vec3 - Size byte + Origin mgl32.Vec3 + Size byte AlignmentPadding [3]byte -} \ No newline at end of file +} diff --git a/primitives/dispinfo/dispinfo.go b/primitives/dispinfo/dispinfo.go index ee6ba71..cc737bd 100644 --- a/primitives/dispinfo/dispinfo.go +++ b/primitives/dispinfo/dispinfo.go @@ -4,20 +4,24 @@ import ( "github.com/go-gl/mathgl/mgl32" ) +const MaxDispCornerNeightbours = 4 + type DispInfo struct { - StartPosition mgl32.Vec3 - DispVertStart int32 - DispTriStart int32 - Power int32 - MinTess int32 - SmoothingAngle float32 - Contents int32 - MapFace uint16 - LightmapAlphaStart int32 + StartPosition mgl32.Vec3 + DispVertStart int32 + DispTriStart int32 + Power int32 + MinTess int32 + SmoothingAngle float32 + Contents int32 + MapFace uint16 + _ [2]byte + LightmapAlphaStart int32 LightmapSampleStartPosition int32 - EdgeNeighbors [4]DispNeighbor - CornerNeighbors [4]DispCornerNeighbors - AllowedVerts [10]uint32 + Ignore [32]uint32 + //EdgeNeighbors [4]DispNeighbor + //CornerNeighbors [4]DispCornerNeighbors + //AllowedVerts [8]uint32 } @@ -26,14 +30,13 @@ type DispNeighbor struct { } type DispSubNeighbor struct { - Index uint16 // 0xFFFF if no neighbor - NeighborOrientation byte - Span byte - NeighborSpan byte - + Index uint16 // 0xFFFF if no neighbor + NeighborOrientation uint8 + Span uint8 + NeighborSpan uint8 } type DispCornerNeighbors struct { - Neighbors uint16 - NumNeighbors byte -} \ No newline at end of file + Neighbors [MaxDispCornerNeightbours]uint16 + NumNeighbors uint8 +} diff --git a/primitives/dispvert/dispvert.go b/primitives/dispvert/dispvert.go index 79567f8..5920a9c 100644 --- a/primitives/dispvert/dispvert.go +++ b/primitives/dispvert/dispvert.go @@ -5,7 +5,7 @@ import ( ) type DispVert struct { - Vec mgl32.Vec3 - Dist float32 + Vec mgl32.Vec3 + Dist float32 Alpha float32 } diff --git a/primitives/face/face.go b/primitives/face/face.go index 010db16..53a4d1e 100644 --- a/primitives/face/face.go +++ b/primitives/face/face.go @@ -1,22 +1,21 @@ package face - type Face struct { - Planenum uint16 - Side byte - OnNode byte - FirstEdge int32 - NumEdges int16 - TexInfo int16 - DispInfo int16 - SurfaceFogVolumeID int16 - Styles [4]byte - Lightofs int32 - Area float32 + Planenum uint16 + Side byte + OnNode byte + FirstEdge int32 + NumEdges int16 + TexInfo int16 + DispInfo int16 + SurfaceFogVolumeID int16 + Styles [4]byte + Lightofs int32 + Area float32 LightmapTextureMinsInLuxels [2]int32 LightmapTextureSizeInLuxels [2]int32 - OrigFace int32 - NumPrims uint16 - FirstPrimID uint16 - SmoothingGroups uint32 + OrigFace int32 + NumPrims uint16 + FirstPrimID uint16 + SmoothingGroups uint32 } diff --git a/primitives/faceid/faceid.go b/primitives/faceid/faceid.go index 1617e07..190f699 100644 --- a/primitives/faceid/faceid.go +++ b/primitives/faceid/faceid.go @@ -1,6 +1,5 @@ package faceid - type FaceId struct { HammerFaceId uint16 } diff --git a/primitives/game/game.go b/primitives/game/game.go index ab9f5d9..8316636 100644 --- a/primitives/game/game.go +++ b/primitives/game/game.go @@ -4,53 +4,69 @@ import ( "github.com/go-gl/mathgl/mgl32" ) +const StaticPropLumpId = 1936749168 + type Header struct { LumpCount int32 GameLumps []LumpDef // Slice length must equal lumpCount. Validation to be added } -func (header Header) SetLumpCount(num int32) Header{ + +func (header Header) SetLumpCount(num int32) Header { header.LumpCount = num header.GameLumps = make([]LumpDef, header.LumpCount) return header } type LumpDef struct { - Id int32 - Flags uint16 - Version uint16 + Id int32 + Flags uint16 + Version uint16 FileOffset int32 FileLength int32 } +type GenericGameLump struct { + Length int32 + Data []byte +} + +type StaticPropLump struct { + DictLump StaticPropDictLump + LeafLump StaticPropLeafLump + PropLumps []IStaticPropDataLump +} + // Note: Nothing below here is actually implemented, as its primarily game/version specific data. type StaticPropDictLump struct { DictEntries int32 - Name []string // Slice length must equal dictEntries. Validation to be added + Name []string // Slice length must equal dictEntries. Validation to be added } type StaticPropLeafLump struct { LeafEntries int32 - Leaf []uint16 // Slice length must equal leafEntries. Validation to be added + Leaf []uint16 // Slice length must equal leafEntries. Validation to be added +} + +type IStaticPropDataLump interface { + GetOrigin() mgl32.Vec3 + GetAngles() mgl32.Vec3 + GetUniformScale() float32 //v11 onwards + GetPropType() uint16 + GetFirstLeaf() uint16 + GetLeafCount() uint16 + GetSolid() uint8 + GetFlags() uint8 + GetSkin() int32 + GetFadeMinDist() float32 + GetFadeMaxDist() float32 + GetLightingOrigin() mgl32.Vec3 + GetForcedFadeScale() float32 + GetMinDXLevel() uint16 + GetMaxDXLevel() uint16 + GetMinCPULevel() uint8 + GetMaxCPULevel() uint8 + GetMinGPULevel() uint8 + GetMaxGPULevel() uint8 + GetDiffuseModulation() float32 //v7 onwards + GetUnknown() float32 //v10 onwards + GetDisableXBox360() bool //v9 onwards } -type StaticPropLump struct { - Origin mgl32.Vec3 - Angles mgl32.Vec3 - PropType uint16 - FirstLeaf uint16 - LeafCount uint16 - Solid string //unsigned char - Flags string //unsigned char - Skin int32 - FadeMinDist float32 - FadeMaxDist float32 - LightingOrigin mgl32.Vec3 - ForcedFadeScale float32 - MinDXLevel uint16 - MaxDXLevel uint16 - MinCPULevel string //unsigned char - MaxCPULevel string //unsigned char - MinGPULevel string //unsigned char - MaxGPULevel string //unsigned char - //DiffuseModulation [2]float //dont know if this is correct? - //Unknown float32 - //DisableXbox360 bool -} \ No newline at end of file diff --git a/primitives/game/staticpropv10.go b/primitives/game/staticpropv10.go new file mode 100644 index 0000000..600dcc9 --- /dev/null +++ b/primitives/game/staticpropv10.go @@ -0,0 +1,116 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV10 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinCPULevel uint8 + MaxCPULevel uint8 + MinGPULevel uint8 + MaxGPULevel uint8 + DiffuseModulation float32 + Unknown float32 + DisableXBox360 bool + _ [3]byte +} + +func (l *StaticPropV10) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV10) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV10) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV10) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV10) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV10) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV10) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV10) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV10) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV10) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV10) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV10) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV10) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV10) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV10) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV10) GetMinCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV10) GetMaxCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV10) GetMinGPULevel() uint8 { + return l.MinGPULevel +} + +func (l *StaticPropV10) GetMaxGPULevel() uint8 { + return l.MaxGPULevel +} + +func (l *StaticPropV10) GetDiffuseModulation() float32 { + return l.DiffuseModulation +} + +func (l *StaticPropV10) GetUnknown() float32 { + return l.Unknown +} + +func (l *StaticPropV10) GetDisableXBox360() bool { + return l.DisableXBox360 +} diff --git a/primitives/game/staticpropv11.go b/primitives/game/staticpropv11.go new file mode 100644 index 0000000..004ef61 --- /dev/null +++ b/primitives/game/staticpropv11.go @@ -0,0 +1,116 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV11 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + UniformScale float32 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinCPULevel uint8 + MaxCPULevel uint8 + MinGPULevel uint8 + MaxGPULevel uint8 + DiffuseModulation float32 + Unknown float32 + DisableXBox360 bool +} + +func (l *StaticPropV11) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV11) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV11) GetUniformScale() float32 { + return l.UniformScale +} + +func (l *StaticPropV11) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV11) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV11) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV11) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV11) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV11) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV11) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV11) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV11) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV11) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV11) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV11) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV11) GetMinCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV11) GetMaxCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV11) GetMinGPULevel() uint8 { + return l.MinGPULevel +} + +func (l *StaticPropV11) GetMaxGPULevel() uint8 { + return l.MaxGPULevel +} + +func (l *StaticPropV11) GetDiffuseModulation() float32 { + return l.DiffuseModulation +} + +func (l *StaticPropV11) GetUnknown() float32 { + return l.Unknown +} + +func (l *StaticPropV11) GetDisableXBox360() bool { + return l.DisableXBox360 +} diff --git a/primitives/game/staticpropv4.go b/primitives/game/staticpropv4.go new file mode 100644 index 0000000..26316a7 --- /dev/null +++ b/primitives/game/staticpropv4.go @@ -0,0 +1,107 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV4 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 +} + +func (l *StaticPropV4) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV4) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV4) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV4) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV4) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV4) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV4) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV4) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV4) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV4) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV4) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV4) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV4) GetForcedFadeScale() float32 { + return 0 +} + +func (l *StaticPropV4) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV4) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV4) GetMinCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV4) GetMaxCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV4) GetMinGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV4) GetMaxGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV4) GetDiffuseModulation() float32 { + return 0 +} + +func (l *StaticPropV4) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV4) GetDisableXBox360() bool { + return false +} diff --git a/primitives/game/staticpropv5.go b/primitives/game/staticpropv5.go new file mode 100644 index 0000000..a0b6a7d --- /dev/null +++ b/primitives/game/staticpropv5.go @@ -0,0 +1,108 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV5 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 +} + +func (l *StaticPropV5) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV5) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV5) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV5) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV5) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV5) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV5) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV5) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV5) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV5) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV5) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV5) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV5) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV5) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV5) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV5) GetMinCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV5) GetMaxCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV5) GetMinGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV5) GetMaxGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV5) GetDiffuseModulation() float32 { + return 0 +} + +func (l *StaticPropV5) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV5) GetDisableXBox360() bool { + return false +} diff --git a/primitives/game/staticpropv6.go b/primitives/game/staticpropv6.go new file mode 100644 index 0000000..c09913a --- /dev/null +++ b/primitives/game/staticpropv6.go @@ -0,0 +1,110 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV6 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinDXLevel uint16 + MaxDXLevel uint16 +} + +func (l *StaticPropV6) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV6) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV6) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV6) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV6) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV6) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV6) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV6) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV6) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV6) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV6) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV6) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV6) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV6) GetMinDXLevel() uint16 { + return l.MinDXLevel +} + +func (l *StaticPropV6) GetMaxDXLevel() uint16 { + return l.MaxDXLevel +} + +func (l *StaticPropV6) GetMinCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV6) GetMaxCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV6) GetMinGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV6) GetMaxGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV6) GetDiffuseModulation() float32 { + return 0 +} + +func (l *StaticPropV6) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV6) GetDisableXBox360() bool { + return false +} diff --git a/primitives/game/staticpropv7.go b/primitives/game/staticpropv7.go new file mode 100644 index 0000000..73b0290 --- /dev/null +++ b/primitives/game/staticpropv7.go @@ -0,0 +1,111 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV7 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinDXLevel uint16 + MaxDXLevel uint16 + DiffuseModulation float32 +} + +func (l *StaticPropV7) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV7) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV7) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV7) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV7) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV7) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV7) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV7) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV7) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV7) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV7) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV7) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV7) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV7) GetMinDXLevel() uint16 { + return l.MinDXLevel +} + +func (l *StaticPropV7) GetMaxDXLevel() uint16 { + return l.MaxDXLevel +} + +func (l *StaticPropV7) GetMinCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV7) GetMaxCPULevel() uint8 { + return 0 +} + +func (l *StaticPropV7) GetMinGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV7) GetMaxGPULevel() uint8 { + return 0 +} + +func (l *StaticPropV7) GetDiffuseModulation() float32 { + return l.DiffuseModulation +} + +func (l *StaticPropV7) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV7) GetDisableXBox360() bool { + return false +} diff --git a/primitives/game/staticpropv8.go b/primitives/game/staticpropv8.go new file mode 100644 index 0000000..7d487a2 --- /dev/null +++ b/primitives/game/staticpropv8.go @@ -0,0 +1,113 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV8 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinCPULevel uint8 + MaxCPULevel uint8 + MinGPULevel uint8 + MaxGPULevel uint8 + DiffuseModulation float32 +} + +func (l *StaticPropV8) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV8) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV8) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV8) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV8) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV8) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV8) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV8) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV8) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV8) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV8) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV8) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV8) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV8) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV8) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV8) GetMinCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV8) GetMaxCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV8) GetMinGPULevel() uint8 { + return l.MinGPULevel +} + +func (l *StaticPropV8) GetMaxGPULevel() uint8 { + return l.MaxGPULevel +} + +func (l *StaticPropV8) GetDiffuseModulation() float32 { + return l.DiffuseModulation +} + +func (l *StaticPropV8) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV8) GetDisableXBox360() bool { + return false +} diff --git a/primitives/game/staticpropv9.go b/primitives/game/staticpropv9.go new file mode 100644 index 0000000..d04d4e4 --- /dev/null +++ b/primitives/game/staticpropv9.go @@ -0,0 +1,114 @@ +package game + +import ( + "github.com/go-gl/mathgl/mgl32" +) + +type StaticPropV9 struct { + Origin mgl32.Vec3 + Angles mgl32.Vec3 + PropType uint16 + FirstLeaf uint16 + LeafCount uint16 + Solid uint8 + Flags uint8 + Skin int32 + FadeMinDist float32 + FadeMaxDist float32 + LightingOrigin mgl32.Vec3 + ForcedFadeScale float32 + MinCPULevel uint8 + MaxCPULevel uint8 + MinGPULevel uint8 + MaxGPULevel uint8 + DiffuseModulation float32 + DisableXBox360 bool +} + +func (l *StaticPropV9) GetOrigin() mgl32.Vec3 { + return l.Origin +} + +func (l *StaticPropV9) GetAngles() mgl32.Vec3 { + return l.Angles +} + +func (l *StaticPropV9) GetUniformScale() float32 { + return 1 +} + +func (l *StaticPropV9) GetPropType() uint16 { + return l.PropType +} + +func (l *StaticPropV9) GetFirstLeaf() uint16 { + return l.FirstLeaf +} + +func (l *StaticPropV9) GetLeafCount() uint16 { + return l.LeafCount +} + +func (l *StaticPropV9) GetSolid() uint8 { + return l.Solid +} + +func (l *StaticPropV9) GetFlags() uint8 { + return l.Flags +} + +func (l *StaticPropV9) GetSkin() int32 { + return l.Skin +} + +func (l *StaticPropV9) GetFadeMinDist() float32 { + return l.FadeMinDist +} + +func (l *StaticPropV9) GetFadeMaxDist() float32 { + return l.FadeMaxDist +} + +func (l *StaticPropV9) GetLightingOrigin() mgl32.Vec3 { + return l.LightingOrigin +} + +func (l *StaticPropV9) GetForcedFadeScale() float32 { + return l.ForcedFadeScale +} + +func (l *StaticPropV9) GetMinDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV9) GetMaxDXLevel() uint16 { + return 0 +} + +func (l *StaticPropV9) GetMinCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV9) GetMaxCPULevel() uint8 { + return l.MaxCPULevel +} + +func (l *StaticPropV9) GetMinGPULevel() uint8 { + return l.MinGPULevel +} + +func (l *StaticPropV9) GetMaxGPULevel() uint8 { + return l.MaxGPULevel +} + +func (l *StaticPropV9) GetDiffuseModulation() float32 { + return l.DiffuseModulation +} + +func (l *StaticPropV9) GetUnknown() float32 { + return 0 +} + +func (l *StaticPropV9) GetDisableXBox360() bool { + return l.DisableXBox360 +} diff --git a/primitives/leaf/leaf.go b/primitives/leaf/leaf.go index 3b806fc..c4e79a5 100644 --- a/primitives/leaf/leaf.go +++ b/primitives/leaf/leaf.go @@ -1,31 +1,32 @@ package leaf const BITMASK_LOWER9 = 0x1FF // 511 (2^9 - 1) -const BITMASK_LOWER7 = 0x7F // 127 (2^7 - 1) +const BITMASK_LOWER7 = 0x7F // 127 (2^7 - 1) // NOTE: Only 7-bits stored!!! -const LEAF_FLAGS_SKY = 0x01 // This leaf has 3D sky in its PVS -const LEAF_FLAGS_RADIAL = 0x02 // This leaf culled away some portals due to radial vis -const LEAF_FLAGS_SKY2D = 0x04 // This leaf has 2D sky in its PVS +const LEAF_FLAGS_SKY = 0x01 // This leaf has 3D sky in its PVS +const LEAF_FLAGS_RADIAL = 0x02 // This leaf culled away some portals due to radial vis +const LEAF_FLAGS_SKY2D = 0x04 // This leaf has 2D sky in its PVS type Leaf struct { - Contents int32 - Cluster int16 - BitField int16 //C Union of char Name || Area:9 && Flags:7 - Mins [3]int16 - Maxs [3]int16 - FirstLeafFace uint16 - NumLeafFaces uint16 - FirstLeafBrush uint16 - NumLeafBrushes uint16 + Contents int32 + Cluster int16 + BitField int16 //C Union of char Name || Area:9 && Flags:7 + Mins [3]int16 + Maxs [3]int16 + FirstLeafFace uint16 + NumLeafFaces uint16 + FirstLeafBrush uint16 + NumLeafBrushes uint16 LeafWaterDataID int16 - _ [2]byte + _ [2]byte } // Get area (first 9 bits) -func (b *Leaf) Area() int16{ +func (b *Leaf) Area() int16 { return int16((b.BitField >> 9) & BITMASK_LOWER9) } + // Set area (first 9 bits) func (b *Leaf) SetArea(area int16) { v := b.BitField @@ -33,11 +34,12 @@ func (b *Leaf) SetArea(area int16) { } // Get flags (second 7 bits) -func (b *Leaf) Flags() int16{ +func (b *Leaf) Flags() int16 { return int16((b.BitField) & BITMASK_LOWER7) } + // Set flags (second 7 bits) func (b *Leaf) SetFlags(flags int16) { v := b.BitField b.BitField = int16((v & BITMASK_LOWER7) | (int16(flags) << 9)) -} \ No newline at end of file +} diff --git a/primitives/leafambientindex/leafambientindex.go b/primitives/leafambientindex/leafambientindex.go index 5af61a5..9f64a12 100644 --- a/primitives/leafambientindex/leafambientindex.go +++ b/primitives/leafambientindex/leafambientindex.go @@ -1,6 +1,5 @@ package leafambientindex - type LeafAmbientIndex struct { AmbientSampleCount uint16 FirstAmbientSample uint16 diff --git a/primitives/leafambientlighting/leafambientlighting.go b/primitives/leafambientlighting/leafambientlighting.go index 7421951..800d167 100644 --- a/primitives/leafambientlighting/leafambientlighting.go +++ b/primitives/leafambientlighting/leafambientlighting.go @@ -4,12 +4,12 @@ import primitives "github.com/galaco/bsp/primitives/common" type LeafAmbientLighting struct { Cube CompressedLightCube - X byte - Y byte - Z byte - Pad byte + X byte + Y byte + Z byte + Pad byte } type CompressedLightCube struct { Color [6]primitives.ColorRGBExponent32 -} \ No newline at end of file +} diff --git a/primitives/leafwaterdata/leafwaterdata.go b/primitives/leafwaterdata/leafwaterdata.go index d9f43b4..9d6c6c4 100644 --- a/primitives/leafwaterdata/leafwaterdata.go +++ b/primitives/leafwaterdata/leafwaterdata.go @@ -1,9 +1,8 @@ package leafwaterdata - type LeafWaterData struct { - SurfaceZ float32 - MinZ float32 + SurfaceZ float32 + MinZ float32 SurfaceTexInfoID int16 - _ int16 // Because struct is 4byte aligned -} \ No newline at end of file + _ int16 // Because struct is 4byte aligned +} diff --git a/primitives/mapflags/mapflags.go b/primitives/mapflags/mapflags.go index 845ca93..f2c9b5d 100644 --- a/primitives/mapflags/mapflags.go +++ b/primitives/mapflags/mapflags.go @@ -2,4 +2,4 @@ package mapflags type MapFlags struct { LevelFlags uint32 -} \ No newline at end of file +} diff --git a/primitives/model/model.go b/primitives/model/model.go index 9c1590a..af600a2 100644 --- a/primitives/model/model.go +++ b/primitives/model/model.go @@ -5,10 +5,10 @@ import ( ) type Model struct { - Mins mgl32.Vec3 - Maxs mgl32.Vec3 - Origin mgl32.Vec3 - HeadNode int32 + Mins mgl32.Vec3 + Maxs mgl32.Vec3 + Origin mgl32.Vec3 + HeadNode int32 FirstFace int32 - NumFaces int32 + NumFaces int32 } diff --git a/primitives/node/node.go b/primitives/node/node.go index 6001fbc..348bd42 100644 --- a/primitives/node/node.go +++ b/primitives/node/node.go @@ -1,13 +1,12 @@ package node - -type Node struct{ - PlaneNum int32 - Children [2]int32 - Mins [3]int16 - Maxs [3]int16 +type Node struct { + PlaneNum int32 + Children [2]int32 + Mins [3]int16 + Maxs [3]int16 FirstFace uint16 - NumFaces uint16 - Area int16 - Padding int16 + NumFaces uint16 + Area int16 + Padding int16 } diff --git a/primitives/occlusion/occlusion.go b/primitives/occlusion/occlusion.go index 90537ad..d521705 100644 --- a/primitives/occlusion/occlusion.go +++ b/primitives/occlusion/occlusion.go @@ -5,18 +5,18 @@ import ( ) type OcclusionData struct { - Flags int32 + Flags int32 FirstPoly int32 PolyCount int32 - Mins mgl32.Vec3 - Maxs mgl32.Vec3 - Area int32 + Mins mgl32.Vec3 + Maxs mgl32.Vec3 + Area int32 } type OcclusionPolyData struct { FirstVertexIndex int32 - VertexCount int32 - PlaneNum int32 + VertexCount int32 + PlaneNum int32 } //Implementation info @@ -26,4 +26,4 @@ num occlusions * size() + num occlusionPolyDatas * size() + num OccluderVertexIndices * size() + 3* sizeof(Int32) - */ \ No newline at end of file +*/ diff --git a/primitives/overlay/overlay.go b/primitives/overlay/overlay.go index 346d252..35f4a22 100644 --- a/primitives/overlay/overlay.go +++ b/primitives/overlay/overlay.go @@ -25,9 +25,9 @@ public: Vector vecOrigin; Vector vecBasisNormal; }; - */ +*/ type Overlay struct { - NId int32 - NTexInfo int16 + NId int32 + NTexInfo int16 AlignmentPadding int16 -} \ No newline at end of file +} diff --git a/primitives/overlayfade/overlayfade.go b/primitives/overlayfade/overlayfade.go index 9d53e6d..bb51e2d 100644 --- a/primitives/overlayfade/overlayfade.go +++ b/primitives/overlayfade/overlayfade.go @@ -3,4 +3,4 @@ package overlayfade type OverlayFade struct { FadeDistMinSq float32 FadeDistMaxSq float32 -} \ No newline at end of file +} diff --git a/primitives/physcollide/physcollide.go b/primitives/physcollide/physcollide.go index baf0699..6952a4f 100644 --- a/primitives/physcollide/physcollide.go +++ b/primitives/physcollide/physcollide.go @@ -2,18 +2,18 @@ package physcollide type PhysCollideEntry struct { ModelHeader PhysModel - Solids []Solid - TextBuffer string + Solids []Solid + TextBuffer string } type PhysModel struct { - ModelIndex int32 - DataSize int32 + ModelIndex int32 + DataSize int32 KeydataSize int32 - SolidCount int32 + SolidCount int32 } type Solid struct { - Size int32 + Size int32 CollisionBinary []int32 -} \ No newline at end of file +} diff --git a/primitives/plane/plane.go b/primitives/plane/plane.go index 4668baa..4ad2b79 100644 --- a/primitives/plane/plane.go +++ b/primitives/plane/plane.go @@ -5,8 +5,7 @@ import ( ) type Plane struct { - Normal mgl32.Vec3 // normal vector - Distance float32 // distance from origin - AxisType int32 // plane axis identifier + Normal mgl32.Vec3 // normal vector + Distance float32 // distance from origin + AxisType int32 // plane axis identifier } - diff --git a/primitives/portal/portal.go b/primitives/portal/portal.go index a81a986..d00e3c3 100644 --- a/primitives/portal/portal.go +++ b/primitives/portal/portal.go @@ -1,22 +1,22 @@ package portal import ( - "github.com/galaco/bsp/primitives/plane" - "github.com/galaco/bsp/primitives/node" - "github.com/galaco/bsp/primitives/face" "github.com/galaco/bsp/primitives/common" + "github.com/galaco/bsp/primitives/face" + "github.com/galaco/bsp/primitives/node" + "github.com/galaco/bsp/primitives/plane" ) const MAX_PORTALS = 65536 type Portal struct { - Id int32 - Plane plane.Plane - OnNode *node.Node - Nodes [2]*node.Node - Next [2]*Portal - Winding *common.Winding + Id int32 + Plane plane.Plane + OnNode *node.Node + Nodes [2]*node.Node + Next [2]*Portal + Winding *common.Winding SideFound int32 //qboolean = int32 - Side *common.Side - Face [2]*face.Face + Side *common.Side + Face [2]*face.Face } diff --git a/primitives/primitive/primitive.go b/primitives/primitive/primitive.go index 366f551..465f738 100644 --- a/primitives/primitive/primitive.go +++ b/primitives/primitive/primitive.go @@ -1,10 +1,9 @@ package primitive - type Primitive struct { - Type byte + Type byte FirstIndex uint16 IndexCount uint16 - FirstVert uint16 - VertCount uint16 -} \ No newline at end of file + FirstVert uint16 + VertCount uint16 +} diff --git a/primitives/texdata/texdata.go b/primitives/texdata/texdata.go index 3156a29..785b068 100644 --- a/primitives/texdata/texdata.go +++ b/primitives/texdata/texdata.go @@ -5,10 +5,10 @@ import ( ) type TexData struct { - Reflectivity mgl32.Vec3 + Reflectivity mgl32.Vec3 NameStringTableID int32 - Width int32 - Height int32 - ViewWidth int32 - ViewHeight int32 + Width int32 + Height int32 + ViewWidth int32 + ViewHeight int32 } diff --git a/primitives/texinfo/texinfo.go b/primitives/texinfo/texinfo.go index 74284bc..bb7df98 100644 --- a/primitives/texinfo/texinfo.go +++ b/primitives/texinfo/texinfo.go @@ -1,9 +1,8 @@ package texinfo - type TexInfo struct { - TextureVecsTexelsPerWorldUnits [2][4]float32 + TextureVecsTexelsPerWorldUnits [2][4]float32 LightmapVecsLuxelsPerWorldUnits [2][4]float32 - Flags int32 - TexData int32 + Flags int32 + TexData int32 } diff --git a/primitives/visibility/visibility.go b/primitives/visibility/visibility.go index 89d91c3..cd095a5 100644 --- a/primitives/visibility/visibility.go +++ b/primitives/visibility/visibility.go @@ -1,12 +1,47 @@ package visibility -const MAX_MAP_VISIBILITY= 0x1000000 +const MAX_MAP_VISIBILITY = 0x1000000 const DVIS_PVS = 0 const DVIS_PAS = 1 const MAX_CLUSTER_SIZE_PER_VIS = 8 type Vis struct { NumClusters int32 - ByteOffset [][2]int32 // Slice length = NumClusters [0]=offset to PVS bit array for cluster - BitVectors []byte // Compressed bit vectors, contains run-length compression PVS data + ByteOffset [][2]int32 // Slice length = NumClusters [0]=offset to PVS bit array for cluster + BitVectors []byte // Compressed bit vectors, contains run-length compression PVS data } + +func (vis *Vis) GetVisibleClusters(clusterId int16) (visibleClusters []int16) { + pvs := vis.GetPVSForCluster(clusterId) + + for id, visible := range pvs { + if visible == true { + visibleClusters = append(visibleClusters, int16(id)) + } + } + + return visibleClusters +} + +// Decompress vis data for a given cluster +// see https://developer.valvesoftware.com/wiki/Source_BSP_File_Format#Visibility for more +func (vis *Vis) GetPVSForCluster(clusterId int16) []bool { + visibleClusterIds := make([]bool, vis.NumClusters) + v := vis.ByteOffset[clusterId][0] // pvs offset for cluster + + for currentClusterIdx := int32(0); currentClusterIdx < vis.NumClusters; v++ { + if int(vis.BitVectors[v]) == 0 { + v++ + currentClusterIdx += (int32(vis.BitVectors[v]) << 3) + continue + } + for i := uint8(0); i < 8 && currentClusterIdx+int32(i) < vis.NumClusters; i++ { + if (vis.BitVectors[v] & (1 << i)) != 0 { + visibleClusterIds[currentClusterIdx+int32(i)] = true + } + } + currentClusterIdx += 8 + } + + return visibleClusterIds +} \ No newline at end of file diff --git a/primitives/wateroverlay/wateroverlay.go b/primitives/wateroverlay/wateroverlay.go index 5b3963f..33c02cb 100644 --- a/primitives/wateroverlay/wateroverlay.go +++ b/primitives/wateroverlay/wateroverlay.go @@ -31,8 +31,7 @@ public: Vector vecOrigin; Vector vecBasisNormal; }; - */ +*/ - type WaterOverlay struct { - - } \ No newline at end of file +type WaterOverlay struct { +} diff --git a/primitives/worldlight/worldlight.go b/primitives/worldlight/worldlight.go index 43f2c97..e915ff1 100644 --- a/primitives/worldlight/worldlight.go +++ b/primitives/worldlight/worldlight.go @@ -14,7 +14,7 @@ enum emittype_t emit_quakelight, // linear falloff, non-lambertian emit_skyambient, // spherical light source with no falloff (surface must trace to SKY texture) }; - */ +*/ type EmitType uint8 @@ -26,21 +26,21 @@ const EMIT_QUAKELIGHT EmitType = 4 const EMIT_SKYAMBIENT EmitType = 5 type WorldLight struct { - Origin mgl32.Vec3 - Intensity mgl32.Vec3 - Normal mgl32.Vec3 - Cluster int32 - Type EmitType //Think for alignments sake with is uint8. May be 3 bytes padding... - _ [3]byte - Style int32 - Stopdot float32 - Stopdot2 float32 - Exponent float32 - Radius float32 - ConstantAttenuation float32 - LinearAttenuation float32 + Origin mgl32.Vec3 + Intensity mgl32.Vec3 + Normal mgl32.Vec3 + Cluster int32 + Type EmitType //Think for alignments sake with is uint8. May be 3 bytes padding... + _ [3]byte + Style int32 + Stopdot float32 + Stopdot2 float32 + Exponent float32 + Radius float32 + ConstantAttenuation float32 + LinearAttenuation float32 QuadraticAttenuation float32 - Flags int32 - TexInfo int32 - Owner int32 -} \ No newline at end of file + Flags int32 + TexInfo int32 + Owner int32 +} diff --git a/reader.go b/reader.go index ba3d30c..cd210ac 100644 --- a/reader.go +++ b/reader.go @@ -2,10 +2,11 @@ package bsp import ( "bytes" - "unsafe" - "io" "encoding/binary" + "github.com/galaco/bsp/lumps" + "io" "os" + "unsafe" ) // Bsp File reader. @@ -17,39 +18,48 @@ type Reader struct { // Note that parsing is somewhat lazy. Proper data structures are only generated for // lumps that are requested at a later time. This generated the header, then []byte // data for each lump -func (r *Reader) Read() (*Bsp,error) { +func (r *Reader) Read() (*Bsp, error) { bsp := Bsp{} buf := bytes.Buffer{} - _,err := buf.ReadFrom(r.stream) + _, err := buf.ReadFrom(r.stream) if err != nil { - return nil,err + return nil, err } reader := bytes.NewReader(buf.Bytes()) //Create Header - h,err := r.readHeader(reader, bsp.header) + h, err := r.readHeader(reader, bsp.header) if err != nil { - return nil,err + return nil, err } bsp.header = *h // Create lumps from header data for index := range bsp.header.Lumps { - lp,err := r.readLump(reader, bsp.header, index) + lp, err := r.readLump(reader, bsp.header, index) if err != nil { - return nil,err + return nil, err } bsp.lumps[index].SetId(index) bsp.lumps[index].SetRawContents(lp) - refLump,err := getReferenceLumpByIndex(index, bsp.header.Version) + refLump, err := getReferenceLumpByIndex(index, bsp.header.Version) + + // There are specific rules for the game lump that requires some extra information + // Game lump lumps have offset data relative to file start, not lump start + // This will correct the offsets to the start of the lump. + // @NOTE: Portal2 console uses relative offsets. This game+platform are not supported currently + if index == LUMP_GAME_LUMP { + refLump.(*lumps.Game).UpdateInternalOffsets(bsp.header.Lumps[index].Offset) + } + if err != nil { - return nil,err + return nil, err } bsp.lumps[index].SetContents(refLump) } - return &bsp,err + return &bsp, err } // Parse header from the bsp file. @@ -63,12 +73,12 @@ func (r *Reader) readHeader(reader *bytes.Reader, header Header) (*Header, error return nil, err } - err = binary.Read(bytes.NewBuffer(headerBytes[:]), binary.LittleEndian, &header) + err = binary.Read(bytes.NewBuffer(headerBytes), binary.LittleEndian, &header) if err != nil { - return nil,err + return nil, err } - return &header,nil + return &header, nil } // Reads a single lumps data @@ -88,28 +98,28 @@ func (r *Reader) readLump(reader *bytes.Reader, header Header, index int) ([]byt } } - return raw,nil + return raw, nil } // Wraps ReadFromStream to control the file access as well. // Use ReadFromStream if you already have a file handle func ReadFromFile(filepath string) (*Bsp, error) { f, err := os.Open(filepath) + defer f.Close() if err != nil { - return nil,err + return nil, err } - b,err := ReadFromStream(f) + b, err := ReadFromStream(f) - f.Close() - return b,err + return b, err } // Read from any struct that implements io.Reader // handy for passing in a string/bytes/other stream func ReadFromStream(reader io.Reader) (*Bsp, error) { - r := &Reader { + r := &Reader{ reader, } return r.Read() -} \ No newline at end of file +} diff --git a/reader_test.go b/reader_test.go index 4ee90ce..1314816 100644 --- a/reader_test.go +++ b/reader_test.go @@ -1,12 +1,13 @@ package bsp import ( - "testing" + "github.com/galaco/bsp/lumps" "os" + "testing" ) func TestReadFromFile(t *testing.T) { - _,err := ReadFromFile("maps/v20/de_dust2.bsp") + _, err := ReadFromFile("maps/v20/de_dust2.bsp") if err != nil { t.Error(err) } @@ -18,8 +19,10 @@ func TestReadFromStream(t *testing.T) { t.Error(err) } - _,err = ReadFromStream(f) + r, err := ReadFromStream(f) if err != nil { t.Error(err) } + + r.GetLump(LUMP_GAME_LUMP).(*lumps.Game).GetStaticPropLump() } diff --git a/versions/v19.go b/versions/v19.go new file mode 100644 index 0000000..81601cf --- /dev/null +++ b/versions/v19.go @@ -0,0 +1,16 @@ +package versions + +import ( + "github.com/galaco/bsp/lumps" +) + +func Getv19Lump(index int) (lumps.ILump, error) { + var ret lumps.ILump + var err error + switch index { + default: + return Getv20Lump(index) + } + + return ret, err +} diff --git a/versions/v20.go b/versions/v20.go index 01c2cfc..b6f04cb 100644 --- a/versions/v20.go +++ b/versions/v20.go @@ -1,145 +1,145 @@ package versions import ( - "github.com/galaco/bsp/lumps" "errors" + "github.com/galaco/bsp/lumps" ) -func Getv20Lump(index int) (lumps.ILump,error) { +func Getv20Lump(index int) (lumps.ILump, error) { var ret lumps.ILump var err error switch index { case 0: - ret = lumps.EntData{} + ret = &lumps.EntData{} case 1: - ret = lumps.Planes{} + ret = &lumps.Planes{} case 2: - ret = lumps.TexData{} + ret = &lumps.TexData{} case 3: - ret = lumps.Vertex{} + ret = &lumps.Vertex{} case 4: - ret = lumps.Visibility{} + ret = &lumps.Visibility{} case 5: - ret = lumps.Node{} + ret = &lumps.Node{} case 6: - ret = lumps.TexInfo{} + ret = &lumps.TexInfo{} case 7: - ret = lumps.Face{} + ret = &lumps.Face{} case 8: - ret = lumps.Lighting{} + ret = &lumps.Lighting{} case 9: - ret = lumps.Occlusion{} + ret = &lumps.Occlusion{} case 10: - ret = lumps.Leaf{} + ret = &lumps.Leaf{} case 11: - ret = lumps.FaceId{} + ret = &lumps.FaceId{} case 12: - ret = lumps.Edge{} + ret = &lumps.Edge{} case 13: - ret = lumps.Surfedge{} + ret = &lumps.Surfedge{} case 14: - ret = lumps.Model{} + ret = &lumps.Model{} case 15: - ret = lumps.WorldLight{} + ret = &lumps.WorldLight{} case 16: - ret = lumps.LeafFace{} + ret = &lumps.LeafFace{} case 17: - ret = lumps.LeafBrush{} + ret = &lumps.LeafBrush{} case 18: - ret = lumps.Brush{} + ret = &lumps.Brush{} case 19: - ret = lumps.BrushSide{} + ret = &lumps.BrushSide{} case 20: - ret = lumps.Area{} + ret = &lumps.Area{} case 21: - ret = lumps.AreaPortal{} + ret = &lumps.AreaPortal{} case 22: - ret = lumps.Unimplemented{} //portals | unused0 | propcollision + ret = &lumps.Unimplemented{} //portals | unused0 | propcollision case 23: - ret = lumps.Unimplemented{} //clusters | unused1 | prophulls + ret = &lumps.Unimplemented{} //clusters | unused1 | prophulls case 24: - ret = lumps.Unimplemented{} //portalverts | unused2 | prophullverts + ret = &lumps.Unimplemented{} //portalverts | unused2 | prophullverts case 25: - ret = lumps.Unimplemented{} //clusterportals | unused3 | proptris + ret = &lumps.Unimplemented{} //clusterportals | unused3 | proptris case 26: - ret = lumps.Unimplemented{} + ret = &lumps.DispInfo{} case 27: - ret = lumps.Face{} + ret = &lumps.Face{} case 28: - ret = lumps.PhysDisp{} + ret = &lumps.PhysDisp{} case 29: - ret = lumps.Unimplemented{} //physcollide - IN PROGRESS + ret = &lumps.Unimplemented{} //physcollide - IN PROGRESS case 30: - ret = lumps.VertNormal{} + ret = &lumps.VertNormal{} case 31: - ret = lumps.VertNormalIndice{} + ret = &lumps.VertNormalIndice{} case 32: - ret = lumps.Unimplemented{} //disp lightmap alphas - IS STRIPPED ANYWAY? + ret = &lumps.Unimplemented{} //disp lightmap alphas - IS STRIPPED ANYWAY? case 33: - ret = lumps.DispVert{} + ret = &lumps.DispVert{} case 34: - ret = lumps.DispLightmapSamplePosition{} + ret = &lumps.DispLightmapSamplePosition{} case 35: - ret = lumps.Game{} + ret = &lumps.Game{} case 36: - ret = lumps.LeafWaterData{} + ret = &lumps.LeafWaterData{} case 37: - ret = lumps.Unimplemented{} //primitives FIXME - Appears to be 4bytes unaccounted for at end of lump? + ret = &lumps.Unimplemented{} //primitives FIXME - Appears to be 4bytes unaccounted for at end of lump? case 38: - ret = lumps.PrimVert{} + ret = &lumps.PrimVert{} case 39: - ret = lumps.PrimIndice{} + ret = &lumps.PrimIndice{} case 40: - ret = lumps.Unimplemented{} //pakfile + ret = &lumps.Pakfile{} //pakfile case 41: - ret = lumps.ClipPortalVerts{} + ret = &lumps.ClipPortalVerts{} case 42: - ret = lumps.Cubemap{} + ret = &lumps.Cubemap{} case 43: - ret = lumps.TexdataStringData{} + ret = &lumps.TexdataStringData{} case 44: - ret = lumps.TexDataStringTable{} + ret = &lumps.TexDataStringTable{} case 45: - ret = lumps.Overlay{} + ret = &lumps.Overlay{} case 46: - ret = lumps.LeafMinDistToWater{} + ret = &lumps.LeafMinDistToWater{} case 47: - ret = lumps.FaceMacroTextureInfo{} + ret = &lumps.FaceMacroTextureInfo{} case 48: - ret = lumps.DispTris{} + ret = &lumps.DispTris{} case 49: - ret = lumps.Unimplemented{} //physcollidesurface | prop blob + ret = &lumps.Unimplemented{} //physcollidesurface | prop blob case 50: - ret = lumps.Unimplemented{} //wateroverlays + ret = &lumps.Unimplemented{} //wateroverlays case 51: - ret = lumps.LeafAmbientIndexHDR{} + ret = &lumps.LeafAmbientIndexHDR{} case 52: - ret = lumps.LeafAmbientIndex{} + ret = &lumps.LeafAmbientIndex{} case 53: - ret = lumps.Unimplemented{} //lighting hdr + ret = &lumps.Unimplemented{} //lighting hdr case 54: - ret = lumps.WorldLightHDR{} //worldlights hdr + ret = &lumps.WorldLightHDR{} //worldlights hdr case 55: - ret = lumps.LeafAmbientLightingHDR{} + ret = &lumps.LeafAmbientLightingHDR{} case 56: - ret = lumps.LeafAmbientLighting{} //leaf ambient lighting + ret = &lumps.LeafAmbientLighting{} //leaf ambient lighting case 57: - ret = lumps.Unimplemented{} //xzippakfile + ret = &lumps.Unimplemented{} //xzippakfile case 58: - ret = lumps.FaceHDR{} + ret = &lumps.FaceHDR{} case 59: - ret = lumps.MapFlags{} + ret = &lumps.MapFlags{} case 60: - ret = lumps.OverlayFade{} + ret = &lumps.OverlayFade{} case 61: - ret = lumps.Unimplemented{} //overlay system levels + ret = &lumps.Unimplemented{} //overlay system levels case 62: - ret = lumps.Unimplemented{} //physlevel + ret = &lumps.Unimplemented{} //physlevel case 63: - ret = lumps.Unimplemented{} //disp multiblend + ret = &lumps.Unimplemented{} //disp multiblend default: err = errors.New("invalid lump id") } - return ret,err + return ret, err } diff --git a/versions/v20_test.go b/versions/v20_test.go index 774cc68..951431b 100644 --- a/versions/v20_test.go +++ b/versions/v20_test.go @@ -1,16 +1,16 @@ package versions import ( - "testing" "github.com/galaco/bsp/lumps" "reflect" + "testing" ) func TestLumpIndexReturnType(t *testing.T) { - l,_ :=Getv20Lump(4) - if reflect.TypeOf(l) != reflect.TypeOf(lumps.Visibility{}) { + l, _ := Getv20Lump(4) + if reflect.TypeOf(l) != reflect.TypeOf(&lumps.Visibility{}) { t.Errorf("Lump type mismatch. Got: %s, expected: %s, ", reflect.TypeOf(l), reflect.TypeOf(lumps.Visibility{})) } -} \ No newline at end of file +} diff --git a/versions/v21.go b/versions/v21.go index a5c9a19..af6fc0c 100644 --- a/versions/v21.go +++ b/versions/v21.go @@ -4,7 +4,7 @@ import ( "github.com/galaco/bsp/lumps" ) -func Getv21Lump(index int) (lumps.ILump,error) { +func Getv21Lump(index int) (lumps.ILump, error) { var ret lumps.ILump var err error switch index { @@ -12,5 +12,5 @@ func Getv21Lump(index int) (lumps.ILump,error) { return Getv20Lump(index) } - return ret,err + return ret, err } diff --git a/versions/versions.go b/versions/versions.go index 14324dc..082dbdb 100644 --- a/versions/versions.go +++ b/versions/versions.go @@ -2,13 +2,15 @@ package versions import "github.com/galaco/bsp/lumps" -func GetLumpForVersion(bspVersion int, lumpId int) (lumps.ILump,error) { +func GetLumpForVersion(bspVersion int, lumpId int) (lumps.ILump, error) { switch bspVersion { + case 19: + return Getv19Lump(lumpId) case 20: return Getv20Lump(lumpId) case 21: return Getv21Lump(lumpId) default: - return lumps.Unimplemented{},nil + return &lumps.Unimplemented{}, nil } } diff --git a/writer.go b/writer.go index 7530e88..1ae0d8f 100644 --- a/writer.go +++ b/writer.go @@ -1,6 +1,5 @@ package bsp - import ( "bytes" "encoding/binary" @@ -29,11 +28,11 @@ func (w *Writer) Write() []byte { lumpBytes := make([][]byte, 64) currentOffset := 1036 // Header always 1036bytes - for _,index := range getDefaultLumpOrdering() { + for _, index := range getDefaultLumpOrdering() { // We have to handle lump 35 (GameData differently) // Because valve mis-designed the file format and relatively positioned data contains absolute file offsets. if index == LUMP_GAME_LUMP { - gamelump := w.data.lumps[index].GetContents().(lumps.Game) + gamelump := w.data.lumps[index].GetContents().(*lumps.Game) w.data.lumps[index].SetContents( gamelump.UpdateInternalOffsets(int32(currentOffset) - w.data.header.Lumps[index].Offset)) } @@ -47,7 +46,7 @@ func (w *Writer) Write() []byte { currentOffset += lumpSize // Finally 4byte align each lump. - lumpBytes[index] = append(lumpBytes[index], make([]byte, currentOffset % 4)...) + lumpBytes[index] = append(lumpBytes[index], make([]byte, currentOffset%4)...) currentOffset += currentOffset % 4 } @@ -58,7 +57,7 @@ func (w *Writer) Write() []byte { binary.Write(&buf, binary.LittleEndian, w.data.header) //Write lumps - for _,lumpData := range lumpBytes { + for _, lumpData := range lumpBytes { binary.Write(&buf, binary.LittleEndian, lumpData) } @@ -67,23 +66,23 @@ func (w *Writer) Write() []byte { } /** - Export a single lump to []byte. - */ +Export a single lump to []byte. +*/ func (w *Writer) WriteLump(index int) []byte { lump := w.data.GetLump(index) - return lump.GetContents().ToBytes() + return lump.ToBytes() } /** - Return a new bsp writer instance. - */ +Return a new bsp writer instance. +*/ func NewWriter() Writer { w := Writer{} return w } func getDefaultLumpOrdering() [64]int { - return [64]int { + return [64]int{ LUMP_PLANES, LUMP_LEAFS, LUMP_LEAF_AMBIENT_LIGHTING, @@ -142,5 +141,5 @@ func getDefaultLumpOrdering() [64]int { LUMP_LEAFMINDISTTOWATER, LUMP_GAME_LUMP, LUMP_PAKFILE, - } -} \ No newline at end of file + } +}