// Types
char: 8-bit ASCII character (uint8_t)
byte: unsigned 8-bit integer (uint8_t)
float: 32-bit single-precision floating point value
int32: signed 32-bit integer (int32_t)
int16: signed 16-bit integer (int16_t)
// Length-prefixed string
typedef struct {
int32 length; // The length of the string
char[length] string; // The ASCII-encoded string
} p_char;
// RGBA colour
typedef struct {
byte[4] rgba; // One byte each for red, green, blue and alpha channel
} Color;
// 3D Vector
typedef struct {
float x;
float y;
float z;
} Vector;
// Editor flags
enum JmfFlags
{
None = 0x00,
PointBased = 0x01, // Or maybe 'HasOrigin'?
Selected = 0x02,
Hidden = 0x08,
RenderMode = 0x10, // Any other render mode than 'normal'
}
typedef struct {
char[4] magic; // File format magic number, "JHMF" in ASCII encoding
int32 version; // File format version (only version 121 is documented here)
int32 ep_count; // Number of recent export paths
p_char[ep_count] export_paths; // Recent export paths
int32 group_count; // Number of groups in the map
Group[group_count] groups; // Group objects
int32 visgroup_count; // Number of VisGroups
VisGroup[visgroup_count] visgroups; // VisGroups objects
Vector cordon_min; // Minimum corner of the Cordon box
Vector cordon_max; // Maximum corner of the Cordon box
int32 camera_count; // Number of Camera objects
Camera[camera_count] cameras; // Camera objects
int32 path_count; // Number of path objects
Path[path_count] paths; // Path objects (created with the Path tool)
Entity[] entities; // All entities including worldspawn, read until the end of the file
} Jmf;
All world brushes are stored within the worldspawn entity. The entities
array is read until the end of file.
typedef struct {
int32 group_id; // The ID number of this group
int32 group_parent_id; // ID of the group this group is nested within
int32 flags; // Editor flags
int32 count; // Number of objects in the group
Color color; // Editor color of the object
} Group;
typedef struct {
p_char name; // VisGroup name
int32 visgroup_id; // VisGroup's ID number
Color color; // Editor color of the VisGroup
byte visible; // Whether the VisGroup is visible or not
} VisGroup;
typedef struct {
Vector eye_position; // The position of the camera in world coordinates
Vector lookat_position; // The target position in world coordinates the camera will look at
int32 flags; // Editor flags
Color color; // Editor color of the Camera
} Camera;
typedef struct {
p_char key; // Key of the property
p_char value; // Value of the property
} KeyValue;
path_
entities manually. It works similar to the Path tool in Hammer although can offer a "preview" in the 3D viewport of a camera travelling along the path with the speed specified by each node. One can read more about this in the J.A.C.K VDKManual.
typedef struct {
p_char classname; // Typically path_corner or path_track
p_char path_name; // The base name for this path
int32 path_type; // The direction of the path
int32 flags; // Editor flags
Color color; // Editor color of the Path
int32 node_count; // Number of nodes in the path
PathNode[node_count] nodes; // The nodes that make up the path
} Path;
The path_name
will be used as the base name for the nodes belonging to this path, i.e. for a path named my_path
each node will be named my_path
, my_path_1
, etc.path_type
can have one of three different values:0
: One way (from first to last node and stops there).1
: Circular (from first to last and back to first again, as an endless loop).2
: Ping pong (from first to last and reverse direction back to first, in an endless loop).
typedef struct {
p_char name_override; // Name to use instead of auto-generated one
p_char fire_on_pass; // Trigger this target when this node has been reached
Vector position; // The node's position in world coordinates
Vector angles; // The node's angles
int32 flags; // Entity spawnflags
int32 kv_count; // Number of node's key-value pairs
KeyValue[kv_count] keyvalues; // Node's key-value pairs (properties)
} Node;
typedef struct {
p_char[] classname; // The entity's classname
Vector origin; // The origin if it's a point entity
int32 flags; // Editor flags
int32 group_id; // ID of the group this entity belongs to
int32 root_group_id; // The top-most group this entity is nested within
Color color; // Editor color of the Path
p_char[13] special_keys; // The names of various special attributes used by J.A.C.K
int32 sp_spawnflags; // Entity spawnflags
Vector sp_angles;
int32 sp_rendering;
Color sp_fx_color;
int32 sp_rendermode;
int32 sp_render_fx;
int16 sp_body;
int16 sp_skin;
int32 sp_sequence;
float sp_framerate;
float sp_scale;
float sp_radius;
byte[28] unknown;
int32 kv_count; // Number of entity's key-value pairs
KeyValue[kv_count] keyvalues; // Entity's key-value pairs (properties)
int32 vg_count; // Number of VisGroups
KeyValue[vg_count] visgroup_ids; // The ID numbers of the VisGroups the entity belongs to
int32 brush_count; // Number of brushes
Solid[brush_count] brushes; // The brushes making up this entity (empty if point entity)
} Entity;
The special attributes section is a bit of a mystery. The fields and their data types here just reflect how they're described in MESS and should not be taken as a definite guide for parsing this part of the file. All these values are duplicated in the entity keyvalues, so it seems fairly safe to simply skip over these fields.
typedef struct {
int32 mesh_count; // Number of meshes (e.g. Quake III/Volatile patches)
int32 flags; // Editor flags
int32 group_id; // ID of the group this entity belongs to
int32 root_group_id; // The top-most group this entity is nested within
Color color; // Editor color of the Path
int32 vg_count; // Number of VisGroups
KeyValue[vg_count] visgroup_ids; // The ID numbers of the VisGroups the entity belongs to
int32 face_count; // Number of faces (polygons) making up the brush
Face[face_count] faces; // The brush's faces
Mesh[mesh_count] meshes; // The brush's meshes
} Brush;
typedef struct {
Vector right_axis; // The texture's projected right axis
float shift_x; // Horizontal shift of the texture
Vector down_axis; // The texture's projected down axis
float shift_y; // Vertical shift of the texture
float scale_x; // Horizontal scale multiplier
float scale_y; // Vertical scale multiplier
float angle; // The angle of the applied rotation
byte[16] unknown;
int32 surface_flags; // Content flags for Quake 2 maps
char[64] texture_name; // Name of the texture applied to the face
} SurfaceProperties;
typedef struct {
int32 render_flags; // I'm unsure what this does. Editor flags perhaps?
int32 vertex_count; // Number of vertices in the face
SurfaceProperties surface; // The texture information of the face
Vector normal; // Face plane normal
float distance; // Face plane distance from origin
byte[4] unknown;
Vertex[vertex_count] vertices; // The vertices that make up the face
} Face;
typedef struct {
Vector coordinates; // Vertex coordinates
Vector texture_uv; // The U/V coordinates of the texture on this vertex are stored in the X/Y values of this vector
} Vertex;
typedef struct {
int32 width; // Mesh width (number of points)
int32 height; // Mesh height (number of points)
SurfaceProperties surface; // The texture information of the mesh
byte[4] unknown;
MeshPoint[1024] points; // Yes, every curve stores 1024 points, regardless of width/height
} Mesh;
Mesh points are stored in rows - the first point is (0, 0), the second point is (0, 1), and so on up until (0, 31), before moving onto the next row - (1, 0). Only the points where x < width
and y < height
are actually parts of the mesh, the others are to be ignored.
typedef struct {
Vector position;
Vector normal;
Vector texture_uv;
} MeshPoint
You must log in to post a comment. You can login or register a new account.
From what I've found so far, the new structure looks like this: and for the background image struct: