## Contents

- Introduction / Disclaimer
- Basic informations
- Level .w file
- Instance .prm file
- .ncp file
- .por file
- .rim file
- Data structures
- structure
`World` - structure
`Mesh` - structure
`Polygon` - structure
`Vertex` - structure
`Vector` - structure
`UV` - structure
`FunnyBall` - structure
`WorldNCP` - structure
`Polyhedron` - structure
`Plane` - structure
`LookupGrid` - structure
`LookupList` - structure
`UnknownList` - structure
`EnvList` - structure
`Bounding Box` - structure
`RIM_Entry` - structure
`POR_Entry`

## Introduction / Disclaimer

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.

## Basic informations

- Files
- Levels are similar to “Instances”. They consist of two files:
`level.w`, which is similar to`instance.prm`. It contains the “look” of the level.`level.ncp`, which is similar to`instance.ncp`(but**not**equal). Contains the “feel” (What you cannot see but drive on).- Coordinate System
- The underlying coordinate system is right-handed: The positive X-Axis goes to the right, Y downwards and Z forwards.
- Basic data types
`rvfloat`is a 32-bit floating point number,`rvshort`a 16-bit integer and goes from -32768 to 32767, and`rvlong`a 32-bit floating point number. (Both`rvshort`and`rvlong`are signed unless explicit marked as unsigned)

## Level .w file

The .w file contains the look of your level. It is basically a sequence of

- .prm-stylish polygon meshes,
- a sequence of FunnyBalls, whose purpose is currently unknown,
- some completely unknown lists, and
- an env mapping list.

## Instance .prm file

A .prm consists of one mesh and nothing more. It has a slightly different header:

structPRM_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]; };

## .ncp file

.ncp files contain the “feel” of levels or instances. They start with a sequence of Polyhedra, which describe flat polygons. The .ncp of a level also consists of a LookupTable, where the game looks which polyhedra have to be tested for a given car position.

## Data structures

`World` (.w)

structWorld{ rvlong mesh_count; Mesh mesh[mesh_count]; rvlong funnyball_count; FunnyBall fball[funnyball_count]; UnknownList unkn_list; EnvList env_list; };

`Mesh` (.w)

structMesh{ 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)`).

`Polygon` (.w/.prm)

structPolygon{ 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 may have something to do with FunnyBalls (Like “Every transparent texture within a FunnyBall is mirroring and mirrors everything else inside the ball”).

`Vertex` (.w/.prm)

structVertex{ 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).

`Vector` (.w/.prm/.ncp-w/.ncp-i)

structVector{ rvfloat x; rvfloat y; rvfloat z; };

(Is equal to “`struct VEC`” from Balor Knight’s .prm/.m-breakdown)

`UV` (.w/.prm)

structUV{ rvfloat u; rvfloat v; };

(Is equal to “`struct UV`” from Balor Knight’s .prm/.m-breakdown)

`FunnyBall` (.w)

structFunnyBall{ 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.

`WorldNCP` (.ncp-w)

structWorldNCP{ rvshort polyhedron_count; Polyhedron polyhedra[polyhedron_count]; LookupGrid lookup; };

`Polyhedron` (.ncp-w/.ncp-i)

structPolyhedron{ 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.

`Plane` (.ncp-w/.ncp-i)

structPlane{ Vector normal; rvfloat distance; };

Is equal to POV-Ray’s

plane { normal, distance }

object.

`normal` has a length of 1.0.

`LookupGrid` (.ncp-w)

structLookupGrid{ 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]`.

`LookupList` (.ncp-w)

structLookupList{ rvlong length; rvlong polyhedron_indices[length]; };

`UnknownList` (.w)

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.

structUnknownList{ rvlong item_count; rvlong something[]; };

`EnvList` (.w)

Contains a color definition for every shiny polygon (bit #11 set) that defines the reflected color.

structEnvList{ unsigned rvlong env_color[number of bit-11-polys in file]; };

`Bounding Box`

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; };

### Portals file (.por)

Portal files (Editing mode “Erm – nothing to see here”) have no effect in Re-Volt. They look like follows:

structPOR_File{ rvlong entry_count; POR_Entry entries[entry_count]; };

### Portals entry structure (.por)

structPOR_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

### Mirrors file (.rim)

structRIM_File{ rvshort entry_count; RIM_Entry entries[entry_count]; };

### Mirrors entry structure (.rim)

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

ali, Last modified: Fri Sep 8 16:39:01 CEST 2000