The files needed for including the wlsg levels in your own C++ project are now available. See the website link on the first link for the downloads section.
The wlsg.h
#pragma once
#include "DarkGDK.h"
#define WLSGE wlsg_scene*
class wlsg
{
public:
int obj;
short flags;
//short oflags;
};
class wlsg_scene
{
public:
int count; // NB: Use 0 to count-1 (not 0 to count)
wlsg *list;
int camfog; // fog rgb
int backdrop; // backdrop rgb
short camviewdist;
short camfov;
short fogdist;
char checkfog;
char reserved1; // padding byte (4 byte aligned)
};
/*
The flags holds the important information about each object.
This makes it easier to load multiple scenes, hide and show each scene
when needed.
*/
// bit number identifiers
// bits 0-5 (0-31) identifies the collision group
#define WLSG_HIDDEN 5
// hide mask
#define WLSG_HIDDENMASK 32
// allow scaling flag
#define WLSG_SCALING 6
#define WLSG_SCALINGMASK 64
#define WLSG_COLLISION 7
// zone flag
#define WLSG_ZONEMASK 0x0200
// mask for the collision group flags
#define WLSG_COLLGROUPMASK 0x001f
#define WLSG_COLLISIONMASK 0x0180
// FUNCTION DECS
wlsg_scene* wlsg_loadscene(char *file);
void wlsg_freescene(wlsg_scene *list);
void wlsg_hidescene(wlsg_scene *list);
void wlsg_showscene(wlsg_scene *list);
int wlsg_getobject(wlsg_scene *list, int num);
/*
wlsg_loadscene(file)
loads in a complete scene and returns the pointer
wlsg_freescene(scene)
Delete all the objects and frees up memory used for data
wlsg_hidescene(scene)
Hides all object and removes them from the collision data
wlsg_showscene(scene)
Re-shows the scene and re-activates all collision data
*/
inline int free_obj() {register int c=1; while (dbObjectExist(c)) c++; return c;}
#define USE_DIFF 1
#define USE_AMB 2
#define USE_SPEC 4
#define USE_EMIS 8
#define USE_SPECPOW 16
#define USE_SMOOTH 32
#define USE_GHOST 64
#define USE_TRANSP 128
#define USE_FOG 256
#define USE_FILTER 512
#define USE_LIGHT 1024
#define USE_AMBIENT 2048
#define USE_CULL 4096
#define SUSE_DIFF 0
#define SUSE_AMB 1
#define SUSE_SPEC 2
#define SUSE_EMIS 3
#define SUSE_SPECPOW 4
#define SUSE_SMOOTH 5
#define SUSE_GHOST 6
#define SUSE_TRANSP 7
#define SUSE_FOG 8
#define SUSE_FILTER 9
#define SUSE_LIGHT 10
#define SUSE_AMBIENT 11
#define SUSE_CULL 12
/*
The flags are stored as:
0000 0000 0000 0000
|\ /||\ /
| | || \ /
| | || \coll_group
| | |`hide
| | `scaling
| `coll_type
`zone
*/
And the wlsg.cpp
#include "wlsg.h"
#include "SC_Collision.h"
#include "DarkGDK.h"
#include "stdio.h"
#include <list>
int wlsg_list_count;
// scene setup temp vars
int wlsg_scene_camfog; // fog color
int wlsg_scene_backdrop; // backdrop color
short wlsg_scene_camviewdist; // camera range
short wlsg_scene_camfov; // FOV
short wlsg_scene_fogdist; // fog distance
char wlsg_scene_checkfog; // 1 is fog on
wlsg* wlsg_loadscene_start(char *file)
{
FILE *fp;
int count,pos,curr,cg;
short flags;
bool b,zone;
char of[260];
// these are used to help not load duplicate files
std::list<int> lo;
std::list<int>::iterator it;
wlsg *list;
// used for reading pos, rot and scale quicker
struct {
float x,y,z; } fvals;
if ( (fp=fopen(file,"r"))!=0 )
{
// current object to process
curr=0;
// first int is number of objects to load
fread(&count,sizeof(int),1,fp);
// set global var to count for other function
wlsg_list_count=count;
//initialise a new object list then start to fill it
list=new wlsg[count];
// keep going until all objects read in from file
while (count!=0)
{
pos=0; zone=0;
// if the next character read is a '*' then duplicate an object
if ( ( of[pos++] = fgetc(fp) ) == '*' )
{
// process duplicate object
fread(&cg,sizeof(int),1,fp);
// set iterator to beginning of objects loaded
it=lo.begin();
// find the correct object to clone
while (cg-- != 0)
it++;
dbCloneObject(list[curr].obj=free_obj(),list[(*it)].obj);
}
else if ( of[pos-1]=='Z' )
{
zone=1; // Where setting up a zone
dbMakeObjectBox(list[curr].obj=free_obj(),100,100,100);
}
else
{
// read the rest of the text for the filename
while ( (of[pos]=fgetc(fp)) !=0 )
pos++;
// load the object from disk
dbLoadObject(of,list[curr].obj=free_obj());
// store this in the list (if needed to be cloned)
lo.push_back(curr);
}
// Load the position of the object
fread(&fvals,sizeof(float),3,fp);
dbPositionObject(list[curr].obj,fvals.x,fvals.y,fvals.z);
// load the rotation of the object
fread(&fvals,sizeof(float),3,fp);
dbRotateObject(list[curr].obj,fvals.x,fvals.y,fvals.z);
// load the scaling
fread(&fvals,sizeof(float),3,fp);
dbScaleObject(list[curr].obj,fvals.x,fvals.y,fvals.z);
if (zone)
{
// read the zones collision group
fread(&pos,sizeof(int),1,fp);
// setup flags
list[curr].flags=WLSG_HIDDENMASK | pos | (2<<WLSG_COLLISION) | WLSG_ZONEMASK;
SC_SetupObject(list[curr].obj,pos,2);
dbHideObject(list[curr].obj);
}
else
{
// check if any value is not 100 to set allow scaling flag
if (fvals.x!=100 || fvals.y!=100 || fvals.z!=100)
list[curr].flags=WLSG_SCALINGMASK;
else
list[curr].flags=0;
// read the hide flag
fread(&b,sizeof(bool),1,fp);
if (b)
{
list[curr].flags=list[curr].flags | WLSG_HIDDENMASK;
dbHideObject(list[curr].obj);
}
// read the collision type
fread(&pos,sizeof(int),1,fp); // pos = collision type
fread(&cg,sizeof(int),1,fp); // cg = collision group
// if coll group is 0 then don't setup
if ( cg != 0 )
{
if ( pos == 3 ) // complex
SC_SetupComplexObject(list[curr].obj,cg,2);
else
SC_SetupObject(list[curr].obj,cg,pos);
// check for scaling flag
if ( list[curr].flags & WLSG_SCALINGMASK )
SC_AllowObjectScaling(list[curr].obj);
}
// set the coll type and group in the correct bits in the flags
list[curr].flags=list[curr].flags | ( cg & 0x1f ) | ( ( pos & 3 ) << WLSG_COLLISION );
// now read the object setup flags
fread(&flags,sizeof(short),1,fp);
if (flags&USE_DIFF)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectDiffuse(list[curr].obj,pos);
}
if (flags&USE_AMB)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectAmbience(list[curr].obj,pos);
}
if (flags&USE_SPEC)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectSpecular(list[curr].obj,pos);
}
if (flags&USE_EMIS)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectEmissive(list[curr].obj,pos);
}
if (flags&USE_SPECPOW)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectSpecularPower(list[curr].obj,pos);
}
if (flags&USE_SMOOTH)
{
fread(&pos,sizeof(int),1,fp);
dbSetObjectSmoothing(list[curr].obj,pos);
}
if (flags&USE_GHOST)
dbGhostObjectOn(list[curr].obj);
dbSetObjectTransparency (list[curr].obj,(flags&USE_TRANSP )>>SUSE_TRANSP);
dbSetObjectFog (list[curr].obj,(flags&USE_FOG )>>SUSE_FOG);
dbSetObjectFilter (list[curr].obj,(flags&USE_FILTER )>>SUSE_FILTER);
dbSetObjectLight (list[curr].obj,(flags&USE_LIGHT )>>SUSE_LIGHT);
dbSetObjectAmbient (list[curr].obj,(flags&USE_AMBIENT)>>SUSE_AMBIENT);
dbSetObjectCull (list[curr].obj,(flags&USE_CULL )>>SUSE_CULL);
} // EO-if (zone)
curr++;
count--;
} // EO-while (count!=0)
// now read the scene set up info
fread(&wlsg_scene_camfog ,sizeof(int),1,fp);
fread(&wlsg_scene_backdrop ,sizeof(int),1,fp);
fread(&wlsg_scene_camviewdist ,sizeof(short),1,fp);
fread(&wlsg_scene_camfov ,sizeof(short),1,fp);
fread(&wlsg_scene_fogdist ,sizeof(short),1,fp);
fread(&wlsg_scene_checkfog ,sizeof(char),1,fp);
lo.clear();
fclose(fp);
} // EO if (fp=fopen
else
{
list=0;
wlsg_list_count=-1;
}
return list;
}
wlsg_scene* wlsg_loadscene(char *file)
{
wlsg_scene *scene=new wlsg_scene;
scene->list=wlsg_loadscene_start(file);
scene->count=wlsg_list_count;
dbFogColor (wlsg_scene_camfog);
dbColorBackdrop (wlsg_scene_backdrop);
dbSetCameraRange (1,wlsg_scene_camviewdist);
dbSetCameraFOV (wlsg_scene_camfov);
dbFogDistance (wlsg_scene_fogdist);
if (wlsg_scene_checkfog) dbFogOn(); else dbFogOff();
scene->camfog = wlsg_scene_camfog;
scene->backdrop = wlsg_scene_backdrop;
scene->camviewdist = wlsg_scene_camviewdist;
scene->camfov = wlsg_scene_camfov;
scene->fogdist = wlsg_scene_fogdist;
scene->checkfog = wlsg_scene_checkfog;
return scene;
}
void wlsg_freescene(wlsg_scene *list)
{
int c;
for (c=0; c<list->count; c++)
{
dbDeleteObject(list->list[c].obj);
}
delete list->list;
delete list;
}
void wlsg_hidescene(wlsg_scene *list)
{
int c;
for (c=0; c<list->count; c++)
{
dbHideObject(list->list[c].obj);
if (SC_CollisionStatus(list->list[c].obj))
SC_RemoveObject(list->list[c].obj);
}
}
void wlsg_showscene(wlsg_scene *list)
{
int c, a, b;
// setup the scene first
dbFogColor (list->camfog);
dbColorBackdrop (list->backdrop);
dbSetCameraRange (1,list->camviewdist);
dbSetCameraFOV (list->camfov);
dbFogDistance (list->fogdist);
if (list->checkfog) dbFogOn(); else dbFogOff();
for (c=0; c<list->count; c++) // That 'c++' thingy again!!!
{
// is it a zone?
if ( (list->list[c].flags & WLSG_ZONEMASK) )
SC_SetupObject(list->list[c].flags,list->list[c].flags & WLSG_COLLGROUPMASK,2);
else
{
// show the object
if ( ( list->list[c].flags & WLSG_HIDDENMASK ) == 0 )
dbShowObject(list->list[c].obj);
// setup collision if group is not 0
if ( ( a = list->list[c].flags & WLSG_COLLGROUPMASK ) != 0 )
{
// check collision type
if ( ( b = (list->list[c].flags & WLSG_COLLISIONMASK ) >> WLSG_COLLISION ) == 3 )
SC_SetupComplexObject(list->list[c].obj,a,2);
else
SC_SetupObject(list->list[c].obj,a,b);
}
// check the allow scaling flag
if ( ( list->list[c].flags & WLSG_SCALINGMASK ) )
SC_AllowObjectScaling(list->list[c].obj);
}
}
}
int wlsg_getobject(wlsg_scene *list, int num)
{
return list->list[num].obj;
}
There's also an example C++ project that you can tweak very easily that uses these files to load in example levels.
I'm working on the updated version of the DBP source file to work with the latest version...
Warning! May contain Nuts!