This document describes the contents of some data files "Re-Volt" uses. It is intended for those who are interested in creating Re-Volt levels of their own.
Re-Volt is a game by Acclaim (www.acclaim.com). This is no publication from Acclaim, so don't expect them to answer to questions.
If you have questions, corrections or additions, feel free to write an e-mail to ali. Updated versions of this document can be found here. If you are willing to correct my bad english, please do so.
Data structures are given in C++-stylish pseudo-syntax, and some explanations are given as POV-Ray source.
struct PRM_Mesh { /* * These members are only present in .w files: * Vector bound_ball_center; * rvfloat bound_ball_radius; * Vector bound_box[2]; */ rvshort polygon_count; rvshort vertex_count; Polygon polygons[polygon_count]; Vertex vertices[vertex_count]; };
struct World { rvlong mesh_count; Mesh mesh[mesh_count]; rvlong funnyball_count; FunnyBall fball[funnyball_count]; UnknownList unkn_list; EnvList env_list; };
struct Mesh { Vector bound_ball_center; rvfloat bound_ball_radius; BoundingBox bbox; rvshort polygon_count; rvshort vertex_count; Polygon polygons[polygon_count]; Vertex vertices[vertex_count]; };(Is equivalent, but not equal, to "struct MODEL_HEADER" from Balor Knight's .prm/.m-breakdown)
A mesh is a sequence of polygons (triangles or "quads") which are located close to each other.
bound_ball_center and bound_ball_radius define a sphere that surrounds the entire mesh, and bbox is an axis-parallel surrounding box. Both are likely used for "If you can't see the sphere, then you cannot see the mesh"-optimizations.
Polygons only contain vertex indices, and no coordinates. Those indices are for the vertices[] array (with indices 0 to (vertex_count - 1)).
struct Polygon { rvshort type; rvshort texture; rvshort vertex_indices[4]; unsigned rvlong colors[4]; UV texcoord[4]; };(Is equal to "struct MODEL_POLY" from Balor Knight's .prm/.m-breakdown)
type is a bit-field. Bit 0 is the most important: If it is set to 1, then the Polygon is a "quad", otherwise it is a triangle. In the latter case vertex_indices[3], colors[3] and texcoord[3] are unused resp. filled with zeroes. Other known flags include:
bit-# | value | purpose in .w | purpose in .prm |
---|---|---|---|
bit 0 | 0x001 | poly is quad | poly is quad |
bit 1 | 0x002 | poly is double-sided | poly is double-sided |
bit 2 | 0x004 | is translucent (or mirroring) | is translucent (or mirroring) |
bit 8 | 0x100 | translucency type* | translucency type* |
bit 10 | 0x400 | unused | Disable EnvMapping |
bit 11 | 0x800 | Enable EnvMapping | unused |
(*) translucency type: Set to 0 for alpha transparency (using the alpha channel in colors[]. Set to 1 for additive blending.
texture gives the texture's graphic image (0=levela.bmp, 1=levelb.bmp, ...). If set to -1, the poly is not textured, but color-filled.
vertex_indices is a list of three or four indices for the list in the mesh structure. If the polygon is not double-sided, the vertices have to be given in clockwise order. (if you look at it from its "behind", the points will be ordered ccw, and the poly is invisible)
A word about mirroring surfaces: I have no idea how they work. Every
mirror I looked at turned out to be transparent. (Look at the second museum level:
The starting position is on mirroring marble. If you look at it from above, you can
see that it is transparent: You can see through it into another room) It
struct Vertex { Vector position; Vector normal; };(Is equal to "struct MODEL_VERTEX" from Balor Knight's .prm/.m-breakdown) The normal vector (or "UVW") has to be normalized (have length 1.0).
struct Vector { rvfloat x; rvfloat y; rvfloat z; };(Is equal to "struct VEC" from Balor Knight's .prm/.m-breakdown)
struct UV { rvfloat u; rvfloat v; };(Is equal to "struct UV" from Balor Knight's .prm/.m-breakdown)
struct FunnyBall { Vector center; rvfloat radius; rvlong mesh_count; rvlong mesh_indices[mesh_count]; };
FunnyBalls are spheres that surround some (or all) meshes in the level. Their purpose is currently unknown. Having none in a .w file (and setting the fball_count to zero) crashes the game, but having one which surrounds the whole level works.
They may be used for mirroring surfaces (because mirrors are simply transparent polygons) and give the clue which meshes have to be mirrored, or they are used to define hidden parts of the level.
struct WorldNCP { rvshort polyhedron_count; Polyhedron polyhedra[polyhedron_count]; LookupGrid lookup; };
struct Polyhedron { rvlong type; rvlong surface; Plane plane[5]; BoundingBox bbox; };
A polyhedron is a infinit subset of the three-dimensional space that is bordered by four or five planes. Plane #0 gives the surface itself, and the other ones cut it at its edges. This is equivalent to (POV-Ray):
object { intersection { plane { plane[0] } plane { plane[1] } plane { plane[2] } ... } }
type is a bitfield. Bit 0 defines whether it has four or five planes (resp. is a triangle or quad). I've also seen bits 2 and 3 set, but haven't tested them yet.
bbox is a bounding box around the present part of plane[0].
surface gives the "feeling" of this surface. It may be a bit-field, but I cannot see regularities, and think that it is only a predefined list. Normal floor is value 0, most values between 1 and 25 lead to something useful. The documentation of rvglue lists their effects.
struct Plane { Vector normal; rvfloat distance; };
Is equal to POV-Ray's
plane { normal, distance }object.
normal has a length of 1.0.
struct LookupGrid { rvfloat x0; rvfloat z0; rvfloat x_size; rvfloat z_size; rvfloat raster_size; LookupList lists[z_size][x_size]; };
This is a grid that spans the X-Z-Plane, with origin at (x0,z0), squares that are raster_size*raster_size sized, x_size squares in +X-direction and z_size squares in +Z-direction. Notice that x_size and z_size are integers saved to floats.
The grid provides a list of polyhedra that are above or below a given grid square. The list is given as indices for WorldNCP.polyhedra[WorldNCP.polyhedron_count].
struct LookupList { rvlong length; rvlong polyhedron_indices[length]; };
This part of .w files is completely unknown. Even it's length isn't know. Fortunately, most .w files contain zero items here, in which case overreading it is easy.
struct UnknownList { rvlong item_count; rvlong something[]; };
Contains a color definition for every shiny polygon (bit #11 set) that defines the reflected color.
struct EnvList { unsigned rvlong env_color[number of bit-11-polys in file]; };
A bounding box is just some values to describe the lowest resp. highest values of the coordinates inside it.
struct BoundingBox { rvfloat xlo, xhi; rvfloat ylo, yhi; rvfloat zlo, zhi; };
Portal files (Editing mode "Erm - nothing to see here") have no effect in Re-Volt. They look like follows:
struct POR_File { rvlong entry_count; POR_Entry entries[entry_count]; };
struct POR_Entry { rvulong type; rvulong id[2]; Vector center; rvfloat rotation_matrix[3][3]; Vector size; rvfloat zeroes[4]; };
type is: 0, if the structure describes a portal, and 1 for a region
zeroes seem to be always 0, but that's just a suggestion
struct RIM_File { rvshort entry_count; RIM_Entry entries[entry_count]; };
struct RIM_Entry { rvulong flags; Vector plane_normal; rvfloat plane_distance; BoundingBox bbox; Vector vertices[4]; };
flags seem to be 0 or 1, where 0 is "three vertices" and 1 is "four vertices".
The vertices have to be on the mirroring plane