This fixes the Valve BSP loader's crash bug. As I suspected, it was a
64-bit issue. One of the structures made use of an unsigned long,
causing the reader to read too many bytes from the file.
I tested on a 64-bit FC9 box and it works fine there (several maps
loaded successfully).
--"J"
#ifndef __VBSP_READER_H_
#define __VBSP_READER_H_
#include <osg/Geometry>
#include <osg/Matrixd>
#include <osg/Node>
#include <osg/Object>
#include <osg/StateSet>
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osg/Referenced>
namespace bsp
{
// The magic number for a Valve BSP file is 'VBSP' in little-endian
// order
const int MAGIC_NUMBER = (('P'<<24)+('S'<<16)+('B'<<8)+'V');
enum LumpType
{
ENTITIES_LUMP,
PLANES_LUMP,
TEXDATA_LUMP,
VERTICES_LUMP,
VISIBILITY_LUMP,
NODES_LUMP,
TEXINFO_LUMP,
FACES_LUMP,
LIGHTING_LUMP,
OCCLUSION_LUMP,
LEAFS_LUMP,
UNUSED_LUMP_11,
EDGES_LUMP,
SURFEDGES_LUMP,
MODELS_LUMP,
WORLD_LIGHTS_LUMP,
LEAF_FACES_LUMP,
LEAF_BRUSHES_LUMP,
BRUSHES_LUMP,
BRUSH_SIDES_LUMP,
AREAS_LUMP,
AREA_PORTALS_LUMP,
PORTALS_LUMP,
CLUSTERS_LUMP,
PORTAL_VERTS_LUMP,
CLUSTER_PORTALS_LUMP,
DISPINFO_LUMP,
ORIGINAL_FACES_LUMP,
UNUSED_LUMP_28,
PHYS_COLLIDE_LUMP,
VERT_NORMALS_LUMP,
VERT_NORMAL_INDICES_LUMP,
DISP_LIGHTMAP_ALPHAS_LUMP,
DISP_VERTS_LUMP,
DISP_LIGHTMAP_SAMPLE_POS_LUMP,
GAME_LUMP,
LEAF_WATER_DATA_LUMP,
PRIMITIVES_LUMP,
PRIM_VERTS_LUMP,
PRIM_INDICES_LUMP,
PAK_FILE_LUMP,
CLIP_PORTAL_VERTS_LUMP,
CUBEMAPS_LUMP,
TEXDATA_STRING_DATA_LUMP,
TEXDATA_STRING_TABLE_LUMP,
OVERLAYS_LUMP,
LEAF_MIN_DIST_TO_WATER_LUMP,
FACE_MACRO_TEXTURE_INFO_LUMP,
DISP_TRIS_LUMP,
PHYS_COLLIDE_SURFACE_LUMP,
UNUSED_LUMP_50,
UNUSED_LUMP_51,
UNUSED_LUMP_52,
LIGHTING_HDR_LUMP,
WORLD_LIGHTS_HDR_LUMP,
LEAF_LIGHT_HDR_1_LUMP,
LEAF_LIGHT_HDR_2_LUMP,
UNUSED_LUMP_57,
UNUSED_LUMP_58,
UNUSED_LUMP_59,
UNUSED_LUMP_60,
UNUSED_LUMP_61,
UNUSED_LUMP_62,
UNUSED_LUMP_63,
MAX_LUMPS
};
const char LUMP_DESCRIPTION[][64] =
{
"ENTITIES_LUMP",
"PLANES_LUMP",
"TEXDATA_LUMP",
"VERTICES_LUMP",
"VISIBILITY_LUMP",
"NODES_LUMP",
"TEXINFO_LUMP",
"FACES_LUMP",
"LIGHTING_LUMP",
"OCCLUSION_LUMP",
"LEAFS_LUMP",
"UNUSED_LUMP_11",
"EDGES_LUMP",
"SURFEDGES_LUMP",
"MODELS_LUMP",
"WORLD_LIGHTS_LUMP",
"LEAF_FACES_LUMP",
"LEAF_BRUSHES_LUMP",
"BRUSHES_LUMP",
"BRUSH_SIDES_LUMP",
"AREAS_LUMP",
"AREA_PORTALS_LUMP",
"PORTALS_LUMP",
"CLUSTERS_LUMP",
"PORTAL_VERTS_LUMP",
"CLUSTER_PORTALS_LUMP",
"DISPINFO_LUMP",
"ORIGINAL_FACES_LUMP",
"UNUSED_LUMP_28",
"PHYS_COLLIDE_LUMP",
"VERT_NORMALS_LUMP",
"VERT_NORMAL_INDICES_LUMP",
"DISP_LIGHTMAP_ALPHAS_LUMP",
"DISP_VERTS_LUMP",
"DISP_LIGHTMAP_SAMPLE_POS_LUMP",
"GAME_LUMP",
"LEAF_WATER_DATA_LUMP",
"PRIMITIVES_LUMP",
"PRIM_VERTS_LUMP",
"PRIM_INDICES_LUMP",
"PAK_FILE_LUMP",
"CLIP_PORTAL_VERTS_LUMP",
"CUBEMAPS_LUMP",
"TEXDATA_STRING_DATA_LUMP",
"TEXDATA_STRING_TABLE_LUMP",
"OVERLAYS_LUMP",
"LEAF_MIN_DIST_TO_WATER_LUMP",
"FACE_MACRO_TEXTURE_INFO_LUMP",
"DISP_TRIS_LUMP",
"PHYS_COLLIDE_SURFACE_LUMP",
"UNUSED_LUMP_50",
"UNUSED_LUMP_51",
"UNUSED_LUMP_52",
"LIGHTING_HDR_LUMP",
"WORLD_LIGHTS_HDR_LUMP",
"LEAF_LIGHT_HDR_1_LUMP",
"LEAF_LIGHT_HDR_2_LUMP",
"UNUSED_LUMP_57",
"UNUSED_LUMP_58",
"UNUSED_LUMP_59",
"UNUSED_LUMP_60",
"UNUSED_LUMP_61",
"UNUSED_LUMP_62",
"UNUSED_LUMP_63"
};
struct LumpEntry
{
int file_offset;
int lump_length;
int lump_version;
char ident_code[4];
};
struct Header
{
int magic_number;
int bsp_version;
LumpEntry lump_table[MAX_LUMPS];
int map_revision;
};
struct Plane
{
osg::Vec3f plane_normal;
float origin_dist;
int type;
};
struct Edge
{
unsigned short vertex[2];
};
struct Face
{
unsigned short plane_index;
unsigned char plane_side;
unsigned char on_node;
int first_edge;
short num_edges;
short texinfo_index;
short dispinfo_index;
short surface_fog_volume_id;
unsigned char styles[4];
int light_offset;
float face_area;
int lightmap_texture_mins_in_luxels[2];
int lightmap_texture_size_in_luxels[2];
int original_face;
unsigned short num_primitives;
unsigned short first_primitive_id;
unsigned int smoothing_groups;
};
struct TexInfo
{
float texture_vecs[2][4];
float lightmap_vecs[2][4];
int texture_flags;
int texdata_index;
};
struct TexData
{
osg::Vec3f texture_reflectivity;
int name_string_table_id;
int texture_width;
int texture_height;
int view_width;
int view_height;
};
struct DisplaceSubNeighbor
{
unsigned short neighbor_index;
unsigned char neighbor_orient;
unsigned char local_span;
unsigned char neighbor_span;
};
struct DisplaceNeighbor
{
DisplaceSubNeighbor sub_neighbors[2];
};
struct DisplaceCornerNeighbor
{
unsigned short neighbor_indices[4];
unsigned char neighbor_count;
};
struct DisplaceInfo
{
osg::Vec3f start_position;
int disp_vert_start;
int disp_tri_start;
int power;
int min_tesselation;
float smooth_angle;
int surface_contents;
unsigned short map_face;
int lightmap_alpha_start;
int lightmap_sample_pos_start;
DisplaceNeighbor edge_neighbors[4];
DisplaceCornerNeighbor corner_neighbors[4];
unsigned int allowed_verts[10];
};
struct DisplacedVertex
{
osg::Vec3f displace_vec;
float displace_dist;
float alpha_blend;
};
class VBSPReader
{
protected:
std::string map_name;
osg::ref_ptr<osg::Node> root_node;
char ** entity_list;
int num_entities;
Plane * plane_list;
int num_planes;
osg::Vec3f * vertex_list;
int num_vertices;
Edge * edge_list;
int num_edges;
int * surface_edges;
int num_surf_edges;
Face * face_list;
int num_faces;
TexInfo * texinfo_list;
int num_texinfo_entries;
TexData * texdata_list;
int num_texdata_entries;
int * texdata_string_table;
int num_texdata_string_table_entries;
char ** texdata_string_data;
int num_texdata_strings;
DisplaceInfo * dispinfo_list;
int num_dispinfo_entries;
DisplacedVertex * displaced_vertex_list;
int num_displaced_vertices;
void writeBlanks(int count) const;
void processEntities(std::istream & str, int offset, int length);
void processPlanes(std::istream & str, int offset, int length);
void processVertices(std::istream & str, int offset, int length);
void processEdges(std::istream & str, int offset, int length);
void processSurfEdges(std::istream & str, int offset, int length);
void processFaces(std::istream & str, int offset, int length);
void processTexInfo(std::istream & str, int offset, int length);
void processTexData(std::istream & str, int offset, int length);
void processTexDataStringTable(std::istream & str, int offset,
int length);
void processTexDataStringData(std::istream & str, int offset,
int length);
void processDispInfo(std::istream & str, int offset, int length);
void processDispVerts(std::istream & str, int offset, int length);
std::string getToken(std::string str, const char * delim,
std::string::size_type & index);
std::string findFileIgnoreCase(std::string filePath);
osg::ref_ptr<osg::StateSet> createBlendShader(osg::Texture * tex1,
osg::Texture * tex2);
osg::ref_ptr<osg::Texture> readTextureFile(std::string file);
osg::ref_ptr<osg::StateSet> readMaterialFile(std::string file);
void createScene();
public:
VBSPReader();
virtual ~VBSPReader();
const char * getEntity(int index) const;
const Plane & getPlane(int index) const;
const osg::Vec3f & getVertex(int index) const;
const Edge & getEdge(int index) const;
const int getSurfaceEdge(int index) const;
const Face & getFace(int index) const;
const TexInfo & getTexInfo(int index) const;
const TexData & getTexData(int index) const;
const char * getTexDataString(int index) const;
const DisplaceInfo & getDispInfo(int index) const;
const DisplacedVertex & getDispVertex(int index) const;
bool readFile(const std::string & file);
osg::ref_ptr<osg::Node> getRootNode();
};
}
#endif
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org