Reading Thief Dark Engine Source Code It is based of the Ultimate Underworld engine. For example, refsys.h and refsys.c directly reference the Ultima Underworld engine. Yet now they have added the RefSystemID, for systems. Basically the game world is broken into bins (akin to the Doom engine sectors), each listing the entity ObjID. Now to draw the world the renderer will go through those "bins," picks up ObjID primary key, and joins them with the required tables. The physics system is disjoint from the renderer.
typedef int ObjID;
typedef uint ObjRefID;
typedef uint RefSystemID;
// Locations in the world are called `bins.' For example, in Terra
// Nova, each 6m-by-6m square of the world is a bin. We get to
// objects from the world by looking up what objects extend into a
// particular bin. Since any one object can extend into more than one
// bin at once, we need an extra data structure, called an `ObjRef',
// to represent the presence of a given object in a given bin.
// A bin is a black box to us, since we don't know anything a priori
// about the world representation.
typedef struct ObjRef
{
RefSystemID refsys; // What RefSystem I belong to
ObjID obj; // What object I refer to
ObjRefID next_in_bin; // The next ObjRef in this bin (non-circular)
ObjRefID next_of_obj; // The next ObjRef to refer to my obj (circular)
char bin[1]; // What bin am I in? Length depends on refsys
} ObjRef;
The RefSystemID is similar to the modern ECS system's id (i.e. a SQL table plus update functions), which can be attached to an object using ObjRefMake, after obtaining the ObjRefID by
// Gets a free ObjRef, assigns it to the given Obj,
// and puts in the world in the given place.
//
// Returns the ObjRefID, or 0 if it failed.
//
ObjRefID ObjRefMake (ObjID obj, RefSystemID refsys, void *bin)
{
ObjRefID ref;
BOOL ok;
if ((ref = ObjRefGrab (refsys)) == 0) return 0; //get the system's handle
ok = ObjLinkMake (obj, ref); if (!ok) return 0; //make object part of the system
ok = ObjRefAdd (ref, bin); if (!ok) return 0; //make object's bin part of the system
return ref;
}
The system itself is basically a
typedef struct ObjRefSystem
{
char ref_size; // size in bytes of an ObjRef
char bin_size; // size in bytes of a bin
RefListFunc ref_list_func; // function to provide head of ref list
RefListClearFunc ref_list_clear_func; // function to clear ref list
BinCompareFunc bin_compare_func; // function for comparing bins
BinUpdateFunc bin_update_func; // function for updating extent
BinPrintFunc bin_print_func; // function to print a bin (NULL is ok)
BinComputeFunc bin_compute_func; // compute bins for object
} ObjRefSystem;
// Although there may be many RefSystems, there should be one basic
// Cartesian coordinate system that they all understand. This is the
// coordinate system used for locations in the objects, and for
// physics.
//
// Each RefSystem has a function that enumerates the bins into which a
// given object extends. Since most of these functions (we imagine)
// would benefit from knowing the bounding prism around the object, we
// move that work out into a separate, global function.
// The 'pos' that is passed to your function is a pointer to a
// "Position" as currently defined in wrtype.h. We just call it a
// void * here because we don't know anything about the world
// representation.
// This is an aligned prism; all edges on it are parallel to one of
// the x, y, or z axes.
typedef struct
{
float xmin, xmax;
float ymin, ymax;
float zmin, zmax;
}
BoundingPrism;
// puts output into bound
// void FUNC (ObjID obj, void *pos, BoundingPrism *bound) {}
typedef void (* BoundingPrismFunc) (ObjID obj, void *pos, BoundingPrism *bound);
// Get the position of an object
typedef void* (* ObjPosFunc)(ObjID obj);
Current Mood: amused