Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.






The building of caveman part 4 - The Z game library

Posted by Norman Barrows, 20 April 2014 · 743 views

The Building of Caveman - Part 4

Z3D - The low level generic game development library




So far i had a wrapper for the dx9 fixed function pipeline, and a
render queue and state manager desigend to feed data to the pipeline
in optimal order for fastest performance. The render queue allows
the game to make drawing callis in a more of less arbitrary order.

But it takes much more than a render queue and state manager to
build a game. additional componets required included:

* fonts
i went with d3dx fonts at first. later, i switched
to a custom font using faster d3dx sprites.

* materials
d3d lighting equations are complex and powerful.
i decided to control lighting primarily via materials to simplify things.
the game uses a database of about 8 materials. everything from dirt to
emissive beacon. Some materials such as plant specular and clouds vary
depending on time of day. A fair amount of time was spent tweaking the
lights and materials for the best lighting behavior possible with the
limited capabilites of dx9 fixed function.
A side benefit of controlling lighting
through materials is the ability to adjust brightness by simply scaling
material values. This avoids the "washed out" look of using gamma to
adjust brightness.

* textures
i created a textures database. a simple array of d3dx9 texture pointers.
it includes routines for creating, loading, and saving textures.
It supports solid and alpha tested textures with or without mipmaps,
as well as alpha blended textures with mipmaps.
textures are refereced via their array index (Texture ID).

* meshes
again, a simple database. d3dxmesh pointers at first, later replaced by
a struct with a vb, ib, numverts, and numtris. references are via
index # (Mesh ID).

* multi-mesh models
since the game uses one texture per mesh for speed, two textures means
two separate meshes. so a rigid body modeling system was created.
It was also required for the rigd body charater animation system.
Caveman uses rigid body animation instead of skinned meshes.
This allows it to draw about five times as many characters on
screen at once.
So a models database was required to hold the model data.
its an array of structs, obe for each type of model.
a struct contains info like the number of limbs, and the mesh, texture,
scale, location, parent, etc, of each limb.
As with all the content databases in the game, reference is via
array index # (model #).

* animations
animations are keyframe in style, and manipulate the limbs of
a multi-mesh model. the game has a database of animations (array
of structs). each struct contains info like number of keyframes,
limb rotations for each keyframe, number of frames between keyframes,
etc.

* animation players.
an animation player takes an animation, and a model, and an animation
frame counter, and tweens the model for drawing. animation players are
assigned to bandmemebrs, animals, and npc's when they start an animation.
the game contains an array of 200
animation players - an "animation manager".
a animation player is just a struct with info like an "active" field,
animation #, model #, and framecounter.

* sprites
d3dx sprites, with some wrapper routines to provide an api like:
drawsprite x,y, x scale, y scale
where x,y is the upper left corner, and the scale values are
0.0 through 1.0 inclusive. sprites use the textures database.

* gui components
a popup menu, and a text entry dialog box. the popup menu can
double as a message dialog box, just make the last option "ok",
and repeat until they select "ok". everything else is custom
screens done with sprites and fonts. thankfully there are very
few custom screen required - less than a dozen. menu() and
getstring() handle all the rest. There is also a text file
viewer for help. the menu system uses an array of strings.
the game calls Znewmenu(title_string) to begin assigning text
to a menu to be displayed. it then calls Zaddmenu(option_text)
to add text for menu options it then calls pick=menu(num_options)
to get a menu pick (option #).

* lights
Caveman tries to do simple to implement and fast yet realitic
lighting within the limitations of DX9 fixed function. It uses
a single directional light for sunlight and moonlight. point
lights with a small radius are used for fires and torches. These
are the only lights used. sun and moon light are varied based
on time of day and cloud cover. Lighting is primarily controlled
via materials, with an overall lightness_factor() being the only
variation in actual light settings, and then only for the sun/moon
light. Light settings for rendering scenes were determined first,
then materials were adjusted to get the desired behavior, with
new materails added as new behaviors were required. Light settings
are heavy on the diffuse, and very light on the ambient for a more
realistic look.


many other low level genric routines are reqiured for games:
math functions
file i/o
high resolution timers
keyboard input
mouse input
etc.

in the past, i've collected such routines into a generic game
development library that i've both used in-house and sold publicly
(passes the dog food test! <g>).

so i proceeded to round out my graphics code with the additional
generic low level stuff required. The result is the latest
incarnation of Rockland Software Productions game development
library. This version is called the Z game library.

the Z3D module is the main module, containing the graphics and
generic game code. There's also an audio module, and a
modeler / animation editor module. The are also experimental
modules for fonts, gui components, a "game engine", an entities
list with AI routines, and a directx 11 version of the Z library.

here's the API for the Z3D module:
 
 
// Z3D.h
 
#ifndef z3d_h
#define z3d_h
 
 
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <d3dx9.h>
 
 
 
//####################### PUBLIC GLOBAL DEFINITIONS ##################################
 
#define pi D3DX_PI
 
 
 
//################## PUBLIC GLOBAL VARIABLES #####################################################
 
extern HWND Zprogram_window_handle;
 
extern int Zalphatestlvl;
 
extern int mousewheel;
 
// d3d font objects
extern ID3DXFont *pFont;
extern ID3DXFont *pFont2;
extern ID3DXFont *pFont3;
 
// d3d sprite obj
extern ID3DXSprite *Zsprite;
 
extern D3DPRESENT_PARAMETERS Zparams;
extern LARGE_INTEGER Ztimer_freq;
 
extern int Ztrace[20];
 
extern DWORD Znum_verts,Znum_primitives;
 
extern int Zcurrentmesh,Zcurrenttex;
 
extern int old_mousex,old_mousey;
 
 
 
//######################### MATERIALS #####################################
 
 
#define ZMAXMATERIALS 10
 
extern D3DMATERIAL9 Zmaterial[ZMAXMATERIALS];
 
void Zsetmaterial(int materialID);
 
void Zinit_materials();
 
void Zload_materials();      // load materials from materials.dat file
 
 
//############################# MENU STRINGS ###################################
 
#define MaxMenuStrings 50
#define MenuStringLength 100
 
extern char Zmenu[MaxMenuStrings][MenuStringLength];     // menu strings
extern int LastMenuOption;
 
void Zgetstring(char *s,char *s2);
int Zdomenu(int mousetex);
void Zclearmenu();
void Zaddmenu(char *s);
void Znewmenu(char *s);    // clear + add
int Zmenu_char_width(int i);   // returns menu width in chars
 
 
 
//############################# SPRITES ######################################
 
 
extern ID3DXSprite *Zsprite;   // d3d sprite obj
 
void Zbeginsprite();
void Zendsprite();
void Zdrawsprite(int texID,int x,int y,float sx,float sy);   // x,y are UL corner of sprite
void Zdrawsprite2(int texID,int x,int y,float sx,float sy,float rz);   // draw a rotated sprite. x,y are screen coords of the center.
void Zflushsprites();
 
 
//########################## tex DB ############################################
 
#define Zmaxtextures 400
 
struct Ztexrec
{
char name[100];
LPDIRECT3DTEXTURE9 tex;
};
 
extern Ztexrec Ztex[Zmaxtextures];
extern int numtextures;
 
void Zloadtex(char *s);
void Zloadbitmap(char *s);
void Zloadsprite(char *s);
void Zload_dynamic_bitmap(char *s);
void Zloadspritetex(char *s);    //   alpha  transparency
void Zloadspritetex2(char *s);   //   alpha  transparency, 5 mip lvls in dds file.
void Zloadspritetex3(char *s);    // colorkey transparency
void Zunload_last_bitmap();
 
void Zload_textures();
 
 
 
//########################### mesh DB ###########################################
 
#define maxmeshes 300
 
struct Zmesh
{
IDirect3DVertexBuffer9 *vb;
IDirect3DIndexBuffer9 *ib;
int numverts,numfaces;
};
 
 
// meshDB record
struct meshrec
{
char name[100];
//LPD3DXMESH mesh;
Zmesh mesh2;
};
 
// mesh DB
extern meshrec mesh[maxmeshes];
 
void Zloadmesh(char *s,int dynamic);    // dynamic = 0 or 1.
 
extern int DBnummeshes;
 
void Zload_meshes();      
 
void optimize_meshes();
 
 
 
//######################### DRAWLIST #################################################
 
struct Zdrawinfo
{
int type,         // 0=mesh, 1=model, 2=2d billboard, 3=3d billboard
meshID,       // for models: modelID 
texID,        // for models: aniID 
alphatest,cull,clamp,materialID,rad,cliprng,data[5];
float sx,sy,sz,x,y,z,rx,ry,rz,range;       // range is rng to camera. not currently used.
D3DXMATRIX mWorld;
};
 
extern int Znumdrawrecs;
//extern int alphatest_numdrawrecs;
 
void Zcleardrawlist();
 
void Zcdi(Zdrawinfo *a);    // "ZClearDrawInfo".   memset's a Zdrawinfo struct to 0.
 
void Zdraw(Zdrawinfo *info);
void Zdraw2(Zdrawinfo *info);
void Zd(Zdrawinfo *b);   // draw mesh, model, 2d billbaord, or 3d billboard
 
void Zdrawlist();
 
void Zpresent();
int Zshowscene(); // 1=success 0=failure
 
 
 
 
//############################# models ###################################################
 
 
 
#define maxlimbs 20
 
 
 
// limb record
struct limbrec
{
int parent,meshID,texID,alphatest;  // parent = index of parent limb. -1=no parent.
float x,y,z,xr,yr,zr,sx,sy,sz; // location of limbs origin (in parent's coords). current orientation of limb.
float xr0,yr0,zr0;   // "at rest" orientation of the limb
char name[20];
};
 
// model record
struct modelrec
{
int numlimbs;
limbrec limb[maxlimbs];
char name[20];
};
 
void Zdrawmodel(Zdrawinfo *info); // meshID=modelID. uses x,y,z,xr,yr,zr.
void Zdrawmodel2(Zdrawinfo *info); // meshID=modelID. uses mWorld.
 
 
 
 
//################################### models datatbase ##########################################
 
 
 
#define maxmodels 200
extern modelrec model[maxmodels];
extern int nummodels;
 
void loadmodel(char *s);
void savemodel(int modelID,char *s);
 
void Zload_models();     // load models from models.dat file
 
 
//####################### animations ################################################
 
 
#define maxkeyframes 20
 
 
// a 3d vector (position, orientation, etc)
struct xyzrec
{
float x,y,z;
};
 
// keyframe record
struct keyframerec
{
int numframes,numlimbs;
xyzrec rotation[maxlimbs];
};
 
// animation record
struct anirec
{
int numkeyframes;
keyframerec keyframe[maxkeyframes];
};
 
int startani(int aniID,int modelID);
void stopani(int playerID);
int set_animation_frame(int playerID);
 
 
// animation player record
struct aniplayerrec
{
int active,aniID,modelID,curkeyframe,curframe;
};
 
#define maxaniplayers 200
 
 
// animation player
extern aniplayerrec aniplayer[maxaniplayers];
 
 
 
//############################ animations DB ####################################
 
#define maxanimations 200
 
extern anirec animation[maxanimations];
extern int numanimations;
 
void loadani(char *s);
void saveani(int aniID,char *s);
 
void Zload_anis();         // load anis from anis.dat file
 
//########################## MATRIX MANIPULATOR ################################
 
extern D3DXMATRIX Mmat;
void Mstart();
void Mrotate(int axis,int degrees);
void MrotateRADS(int axis,float radians);
void Mmove(float x,float y,float z);
void Mscale(float x,float y,float z);
void Mtrans(float *x,float *y,float *z); // transform point x,y,z by matrix Mmat
 
 
//#################### STRING MANIPULATOR #################################
 
extern char S[1000];
void Ss(char *s2);
void Sa(char *s2);
 
// string add int
void Sai(int i);
 
// string add float
void Saf(float f);
 
 
//###################### GRAPHICS ENGINE #########################################
 
const DWORD ZFVF=(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0)  );          //   D3DFVF_DIFFUSE | D3DFVF_SPECULAR |
 
 
 
 
/*
struct Zvertexrec
{
float x,y,z;
float nx,ny,nz;
float tu,tv;  
DWORD diffuse,specular;
};
*/
 
 
struct Zvertexrec
{
D3DVECTOR position,normal;
//D3DCOLOR diffuse,specular;
float tu,tv;
};
    
 
extern IDirect3DDevice9 *Zd3d_device_ptr; 
extern D3DXMATRIX ZmView;  // view matrix
extern D3DXMATRIX Zprojection_matrix;  // projection matrix
extern float Zcamx,Zcamy,Zcamz,Zcamxr,Zcamyr,Zcamzr;   // camera position
 
 
 
int Zinit(HINSTANCE program_instance_handle,int width,int height,char *progname,float nearplane,int farplane);      // ,int zbuf24bit);
void Zshutdown();
void Zsetlite(DWORD liteID,float x,float y,float z,float brightness);
void Zsetcam(float x,float y,float z,float rx,float ry,float rz);
void Zsetcam2(float x,float y,float z,D3DXMATRIX *m); // m is rot matrix
void Zclearscreen(int r,int g,int b);
void Zclearscreen2();                   // clears screen to z game engine default color (blacklight)
void Zclearzbuf();
void Zbeginscene();
void Zambient(int r,int g,int b);
void Zlighting(int onoff);
void Zalphablend(int onoff);
void zbuftest(int onoff);
void zbufwrite(int onoff);
void Zcull(int onoff);
void Znormalize(int onoff);
void Zlite(DWORD liteID,int onoff);
void Zalphatest(int onoff);
void Zmipmaps(int onoff);
void Zclamp(int onoff);
//void Zanisotropic(int onoff);
void Zminmagfilter(int filter_type);      // filter_type: 0=point, 1=linear, 2=anisotropic
void Zspecular(int onoff);
 
int Zsuperclip(int x,int y,int z,int rad,int cliprng);
 
void Zset_clip_planes(float nearplane,int farplane);
 
void Zcalc_frustum_planes();  // must set proj and view mats first!
 
int Zsuperclip2(int x, int y, int z, int rad, int cliprng);   //  must call  Zcalc_frustum_planes first!
 
int Zarea_in_frustum(int x1,int z1,int x2,int z2);   //  must call  Zcalc_frustum_planes first!
 
void Zsetmesh(int meshID);
 
void Zcreate_mesh(int vbsize,int ibsize);
 
void Zsettex(int texID);
 
void Zdrawimmediate(Zdrawinfo *a);
 
void Zdrawimmediate2(Zdrawinfo *a);    // uses Zdrawinfo's mWorld mat
 
void Zcalc_frustum_planes2();          // rotation only
 
 
 
 
//############################ TEXT ########################################
 
 
void Ztextcolor(int r,int g,int b);
void Ztext(int x,int y,char *s);
void Ztext3d(int x,int y,char *s);
void Zsetfont(int font);  //    0=comic ms sans   1= ariel    2=times new roman
int textwidth(char *s);   // returns width of string s in pixels. uses current font setting.
 
 
 
 
//################################ MOUSE #########################################
 
void Zgetmouse(int *x,int *y,int *b);
void Zputmouse(int x,int y);
void nobutton();
void pause();
 
//########################## WINDOWS MESSAGE PROCESSOR ############################
 
void Zdomessages();
 
//########################### GENERIC GUI COMPONENTS ###################################
 
void Zmsg(char *s,char *title);
void Zmsg2(char *s);
 
 
//############################ KEYBOARD ##########################################
 
int Zkeypressed(int vkey);
 
//####################### STRING CONVERSION ROUTINES #############################
 
int s2i(char *s);
void i2s(int i, char *s);
void f2s(float f,char *s);
float s2f(char *s);
 
//############################ DICE ######################################
 
int dice(int a);
void initdice();
 
 
//####################### TIMERS ########################################
 
void Zstarttimer(int a);
int Zelapsedtime(int a);
int Zelapsedticks(int a);
 
 
//####################### FILEIO ##########################################
 
 
// general
 
int filefound(char *s);
int filesize(char *s);
time_t timestamp(char *s);     // returns file create time (UTC format: secs since 1970). returns -1 if file not found.
void closefile(FILE *f);
 
 
 
// text file i/o
 
 
 
FILE* infile(char *s);
 
FILE* outfile(char *s);
 
int readfile(FILE *f,char *s);   // returns: 0=fail 1=success
int readfileint(FILE *f);
float readfilefloat(FILE *f);
 
void writefile(FILE *f,char *s);
void writefileint(FILE *f,int i);
void writefilefloat(FILE *f,float i);
 
 
 
 
// binary file i/o
 
 
FILE* infilebin(char *s);
FILE* appendfilebin(char *s);
 
FILE* outfilebin(char *s);
 
 
 
int readfilebin(FILE *f,unsigned char *buf,int numbytes);   // returns numbytes read
int readFBint(FILE *f);
float readFBfloat(FILE *f);
 
 
 
void writefilebin(FILE *f,unsigned char *buf,int numbytes);
void writeFBint(FILE *f,int a);
void writeFBfloat(FILE *f,float a);
 
 
 
 
 
 
//####################### GENERIC MATH ROUTINES #############################
 
int isin(int x,int y,int x1,int y1,int x2,int y2);
int dist(int x1,int z1,int x2,int z2);                 // diamond bounding box dist
int dist3d(int x1,int y1,int z1,int x2,int y2,int z2);
int BBdist(int x1,int z1,int x2,int z2);            // sq bounding box dist
float deg2rad(float deg);
float rad2deg(float rad);
int heading(int x1,int z1,int x2,int z2);
int relheading(int x1,int z1,int h1,int x2,int z2);
void llim(int *a,int b);
void ulim(int *a,int b);
void limit(int *a,int b,int c);
 
// 0 degrees = up. 90 degrees = forward. 180 degrees = down. 
int angle(int x1,int y1,int z1,int x2,int y2,int z2);
int rng2D(int x1,int z1,int x2,int z2);
int BBdist3d(int x1,int y1,int z1,int x2,int y2,int z2); // 3d bounding box distance
void normangl(float *a);   // normalize angle to 0 to 2 pi
float rng3d(float x1,float y1,float z1,float x2,float y2,float z2);
 
 
//################################ TEXT COLORS ###############################
 
void redtext();
void greentext();
void bluetext();
void yellowtext();
void magentatext();
void cyantext();
void whitetext();
void blacktext();
void greytext();
 
 
 
 
// ################################### mouse aimed camera ###################################
 
void Zresetmouse();
 
extern float cam_xr;
extern float cam_yr;
 
int Zmouse_aim_camera();   // returns mouse button pressed: 0 none, 1 LB, 2 RB, etc.
 
 
// load meshes and textures using a list of filenames stored on disk in a text file
 
 
//################################## SCREEN DUMP ##############################################
 
void Zscreendump();
 
 
 
 
 
 
//############################ TARGET LIST #########################################################
 
 
 
 
 
// #################################################### TARGET LIST DATA STRUCTURES #####################################################
 
#define stepsize 0.1f
 
 
struct ttyperec                     // a target type record
{
float maxspd,turnrate;
int ai,rad,hp,mass,canfly,userID,value,animated,usefuel,maxfuel;
Zdrawinfo d;
};
 
 
 
struct tgtrec
{
float x,y,z,xr,yr,spd;
int type,dp,owner,fuel,alive,active,userID,aniplayerID,dontdraw;
};
 
 
 
#define maxttypes 50
#define maxtgts 200
 
extern ttyperec ttype[maxttypes];        // target types database
 
extern tgtrec tgt[maxtgts];             // targets database
 
 
 
extern int numtgts;         // index of last active tgt + 1.  
                            // max possible number of active tgts at the moment. 
                            // search tgt list using: for a=0 a<numtgts a++.
 
 
 
// ####################################################### INIT TARGETS SYSTEM #################################################################
 
void Zinit_targets_system();                     // initializes the z game library
 
void load_target_types();      // load ttypes from file ttypes.dat
 
void load_targets(char *s2);     // load targets from file s2
 
 
 
// ##################################################### TARGET ROUTINES ###############################################################
 
//                                                  new, del, turn, pitch, move
 
int get_inactive_tgt();        // returns index of 1st inactive tgt. adjusts numtgts accordingly. returns -1 if none available.
 
void deactivate_tgt(int a);       // deativates tgt a. adjusts numtgts accordingly.
 
void turntgt(int a,float amnt);      // turns a target around  y axis by amnt radians.  amnt is limited by ttype.turnrate
 
void pitchtgt(int a,float amnt);        // turns a target around  x axis by amnt radians.  amnt is limited by ttype.turnrate
 
// ##################################################### TARGET DRAWING ROUTINES ##############################################################
 
void Zdrawtgt(int a);     // draws target a
 
void Zdrawtgts();     // draws all targets
 
// ########################################################### TARGET AI ROUTINES ##################################################################
 
 
 
float AI_turn_amount(int a,float x,float z);      // returns amount to turn tgt to face location x,z.    amnt=AI_turn_amount(a,x,z)   turntgt(a,amnt)    
 
float AI_turn_from_amount(int a,float x,float z);      // returns amount to turn tgt to face away from location x,z.    amnt=AI_turn_from_amount(a,x,z)   turntgt(a,amnt)    
 
void AI_turntgt(int a,float x,float z);                     // turn tgt towards x,z
 
void AI_turntgt_from(int a,float x,float z);                 // turn tgt away from x,z
 
void AI_turn_tgt_to_tgt(int a,int c);                         // turn tgt a towards tgt c
 
void AI_turn_tgt_from_tgt(int a,int c);                     // turn tgt a away from tgt c
 
void AI_turn_static_to_tgt(int a,int c);                   // turn static tgt a towards tgt c
 
void AI_turn_static_from_tgt(int a,int c);                 //    turn static tgt a away from tgt c
 
float AI_pitch_amount(int a,float x,float y,float z);     // returns amount (in rads) to pitch tgt a to face x,y,z
 
float AI_pitch_from_amount(int a,float x,float y,float z);     // returns amount (in rads) to pitch tgt a to face away from x,z,y.  
                                                                // assumes tgt is heading away from xyz. 
                                                                // returns 360 - AI_pitch_amount, not AI_pitch_amount + 180.
 
void AI_pitch_tgt_towards_xyz(int a,float x,float y,float z);     // pitches tgt a towards xyz
 
void AI_pitch_tgt_awayfrom_xyz(int a,float x,float y,float z);     // pitches tgt a away from xyz
 
void AI_pitch_tgt_towards_tgt(int a,int c);                 // pitches tgt a towards tgt c
 
void AI_pitch_tgt_awayfrom_tgt(int a,int c);               // pitches tgt a away from tgt c
 
 
 
 
//############################################################ FPS METER #############################################################
 
 
 
void Zinit_fps_meter();
 
void Zupdate_fps_meter();
 
float Zget_fps();
 
 
//################################################################### skybox ########################################################
 
 
void Zdrawskybox(int skybox_meshID,int skybox_texID);
 
 
//######################################## TGT LIST COLLISION TABLE #############################################################
 
void Zset_collision_table(int ttype1,int ttype2,int value);  // sets the "collision table" values for a pair of target types.  
 
int Zcan_collide(int ttype1,int ttype2);
 
int collided(int a,float x,float y,float z,int r);     // a is the target being moved
 
 
//##############################################################################################################################
 
 
 
int Zinitall(HINSTANCE hInstance);
 
float f_lerp(float x,float x1,float x2,float y1,float y2);
 
float frng2d(float x1,float z1,float x2,float z2);
 
void Zdrawground(float x,float z,int rad,int quadsize,int meshID,int texID,int cliprng);
 
 
 
 
//##################### BUTTONS  ########################################################################################
 
 
void Zinit_btns();
 
int Znewbtn();
 
void Zreleasebtn(int a);
 
void Zsetbtn(int index,int x,int y,int w,int h,int texID,char *text);
 
void Zgetbtn(int index,int *x,int *y,int *w,int *h,int *texID,char *text);
 
void Zdrawbtn(int index);  // must call zbeginsprite first!
 
int Zisinbtn(int x,int y,int index);
 
 
 
// ######################################## CHECKSUM ##########################################################
 
 
 
int calc_checksum(char*filename);
 
void append_checksum(int value,char *filename);
 
int file_checksum_ok(char *filename);
 
void remove_checksum(char *filename);
 
int calc_checksum_num(char *filename, int num, int interval);
 
 
#endif
 


Note that Caveman uses its own custom target list, AI,
skybox, mouse aimed camera, fonts, screen dump, FPS meter,
ground drawing code, and buttons. The genric GUI components
are only used for error messages during startup before going
fullscreen 3d.


part 3:
http://www.gamedev.net/blog/1730/entry-2259520-the-building-of-caveman-part-3-getting-a-handle-on-directx/




November 2014 »

S M T W T F S
      1
2345678
9101112131415
16171819202122
23 24 2526272829
30      
PARTNERS