717
sion spheres, simple animation state information (Hydro only supported rigid
hierarchical animation), physical properties like velocity, mass, and buoyancy,
and other data common to all of the dynamic objects in the game. In addi-
tion, each WorldOb_t contained three pointers: a void* “user data” pointer,
a pointer to a custom “update” function, and a pointer to a custom “draw”
function. So while Hydro Thunder was not object-oriented in the strictest sense,
the Hydro engine did extend its non-object-oriented language (C) to support
rudimentary implementations of two important OOP features: inheritance and
polymorphism. The user data pointer permitt ed each type of game object to
maintain custom state information specifi c to its type while inheriting the fea-
tures common to all world objects. For example, the Banshee boat had a dif-
ferent booster mechanism than the Rad Hazard, and each booster mechanism
required diff erent state information to manage its deployment and stowing
animations. The two function pointers acted like virtual functions, allowing
world objects to have polymorphic behaviors (via their “update” functions)
and polymorphic visual appearances (via their “draw” functions).
struct WorldOb_s
{
Orient_t m_transform; /* position/rotation */
Mesh3d* m_pMesh; /* 3D mesh */
/* ... */
void* m_pUserData; /* custom state */
void (*m_pUpdate)(); /* polymorphic update */
void (*m_pDraw)(); /* polymorphic draw */
Figure 14.1. Screen shots from the arcade smash Hydro Thunder, developed by Midway Home
Entertainment in San Diego.
14.2. Runtime Object Model Architectures