private void ParseTerrainBlock(BinaryReader reader) { reader.BaseStream.Position = 0x1A4A8; long fileSize = reader.BaseStream.Length; long position = reader.BaseStream.Position; TerrainSegment last = null; while (true) { char[] trkd = reader.ReadChars(4); //"TRKD" if (trkd[0] == 'C') //Strange format un-used AL22.TRI { return; } int blockLength = reader.ReadInt32(); int blockNumber = reader.ReadInt32(); byte unk1 = reader.ReadByte(); byte fenceType = reader.ReadByte(); TerrainSegment terrainSegment = new TerrainSegment(); terrainSegment.Number = Segments.Count; terrainSegment.TextureIds = reader.ReadBytes(10); terrainSegment.Rows[0] = ReadTerrainRow(reader); terrainSegment.Rows[1] = ReadTerrainRow(reader); terrainSegment.Rows[2] = ReadTerrainRow(reader); terrainSegment.Rows[3] = ReadTerrainRow(reader); //fenceType stores the sides of the road the fence lives, and the textureId to use for it. // If the top bit is set, fence on the left exists, if next bit is set, fence is on the right. Both can also be set. //The other 6 bits seem to the texture number if (fenceType != 0) { bool bit7 = (fenceType & (0x1 << 7)) != 0; bool bit6 = (fenceType & (0x1 << 6)) != 0; terrainSegment.HasLeftFence = bit7; terrainSegment.HasRightFence = bit6; // Ignore the top 2 bits to find the texture to use terrainSegment.FenceTextureId = fenceType & (0xff >> 2); //Debug.WriteLine("fence: " + fenceType + ", texture: " + terrainSegment.FenceTextureId + ", " + terrainSegment.HasLeftFence + ", " + terrainSegment.HasRightFence); } //Debug.WriteLine("TRKD: " + i + ", " + terrainSegment.Rows[0].RightPoints[5] + ", fence: " + terrainSegment.FenceTextureId + " , " + terrainSegment.HasLeftFence + ", " + terrainSegment.HasRightFence); if (last != null) { last.Next = terrainSegment; terrainSegment.Prev = last; } last = terrainSegment; Segments.Add(terrainSegment); //skip to end of block (+12 to include block header) position += blockLength + 12; reader.BaseStream.Position = position; if (reader.BaseStream.Position >= fileSize) { break; } } // If this is a circuit track, hook the last segment up to the first if (!IsOpenRoad) { last.Next = Segments[0]; Segments[0].Prev = last; } }
private void RenderSegment(TerrainSegment segment) { int vertexIndex = segment.TerrainBufferIndex; DrawTerrainStrip(ref vertexIndex, 0, segment.Textures[0]); DrawTerrainStrip(ref vertexIndex, 1, segment.Textures[1]); DrawTerrainStrip(ref vertexIndex, 2, segment.Textures[2]); DrawTerrainStrip(ref vertexIndex, 3, segment.Textures[3]); DrawTerrainStrip(ref vertexIndex, 4, segment.Textures[4]); DrawTerrainStrip(ref vertexIndex, 5, segment.Textures[5]); DrawTerrainStrip(ref vertexIndex, 6, segment.Textures[6]); DrawTerrainStrip(ref vertexIndex, 7, segment.Textures[7]); DrawTerrainStrip(ref vertexIndex, 8, segment.Textures[8]); DrawTerrainStrip(ref vertexIndex, 9, segment.Textures[9]); }
void GetPointIndicesForRightSide(TerrainSegment segment, int terrainPointIndex, out int index1, out int index2) { // only care if this is the last terrain strip if (terrainPointIndex == TriFile.NbrTerrainPointsPerSide - 1) { var node = _tri.Nodes[segment.Number * TriFile.NbrRowsPerSegment]; if (node.NodeProperty == TrackNodeProperty.RIGHT_TUNNEL_A2_A9) { index1 = 2; index2 = 10; return; } } index1 = terrainPointIndex; index2 = terrainPointIndex - 1; }
private void DrawFenceStrips(TerrainSegment segment) { int offset = segment.FenceBufferIndex; if (segment.HasLeftFence) { Engine.Instance.Device.Textures[0] = segment.FenceTexture; Engine.Instance.Device.DrawPrimitives(PrimitiveType.TriangleStrip, offset, 4); offset += 6; } if (segment.HasRightFence) { Engine.Instance.Device.Textures[0] = segment.FenceTexture; Engine.Instance.Device.DrawPrimitives(PrimitiveType.TriangleStrip, offset, 4); } }
void GetPointIndicesForLeftSide(TerrainSegment segment, int terrainPointIndex, out int index1, out int index2) { // only care if this is the last terrain strip if (terrainPointIndex == TriFile.NbrTerrainPointsPerSide - 1) { var node = _tri.Nodes[segment.Number * TriFile.NbrRowsPerSegment]; if (node.NodeProperty == TrackNodeProperty.LEFT_TUNNEL_A9_A4) { index1 = 9; index2 = 4; return; } if (node.NodeProperty == TrackNodeProperty.LEFT_TUNNEL_A9_A5) { index1 = 9; index2 = 5; return; } } index1 = TriFile.NbrTerrainPointsPerSide + terrainPointIndex - 1; index2 = TriFile.NbrTerrainPointsPerSide + terrainPointIndex; }