Wayback Machine
FEB MAY Jun
Previous capture 5 Next capture
2005 2006 2007
16 captures
11 Jul 01 - 5 May 06
sparklines
Close Help

Introduction to the Sourcecode

As discussed in the previous tutorial, the main features of the Half-Life SDK2 are the source code to the two Half-Life DLLs (client.dll, and hl.dll), that make up the bulk of the functionality of Half-Life.

Client DLL

The Client DLL (sdk\source code\cl_dll) contains all the user interface code (screen display, keyboard and mouse handling etc). If you have a copy of Visual C++ 6, open the cl_dll.dsw Workspace file in this directory.

The main classes here are:

 

CHud

hud.h, hud.cpp

The Main HUD Class. Contains member variables for everything you see on the HUD screen (Ammo, flashlight, weapons, train controls, geiger counter etc.)

CHudBase

hud.h

Parent class for anything that is "drawable" on the HUD (ammo, flashlight, etc). Has virtual methods for Initialisation routines and Draw(). If you want to add a new icon (beer-o-meter ?) to the HUD, then you should subclass it from here.

CHudBattery

battery.cpp

The Suit Battery HUD Class (Nice small example of a CHudBase derived class).

Init() initialises member variables, and uses gHUD:AddHudElem() to register itself with the HUD.
VidInit() sets up any sprites drawn by the class (in this case, the "fully charged suit" and the "empty suit")

HOOK_MESSAGE / DECLARE_MESSAGE is used to link an event handler into the message queue. In this case, it declares MsgFunc_Battery() as a method. I havent sussed out where this gets called from, yet. My guess is it's in the game code, when the player goes into the freezer (or whatever other conditions trigger a suit power drain).
MsgFunc_Battery() is called whenever the game kicks off a "start suit power drain" or "end suit power drain" event. It sets the timer on the suit (used by draw()).

Draw( fTime ) draws the sprite on the screen. Note that fTime (the "global time") is passed in to the function, so that you can use it for animated sprites. However, the battery class handles animation slightly differently. It has a member variable that stores fTime when the battery is switched on, and decrements this by gHUD:m_flTimeDelta every time that Draw() is called.

Button / Label / Panel / Handler

VGUI*.*

The VGUI classes are used for the in-game message handling and menu/window functions in Team Fortress (possibly the single-player code too). Seems like there's quite a bit of useful stuff in here, so I'll stick it in a a separate tutorial.

*Button / *Label / *Panel / *Handler

VGUI*.*

Derived classes from VGUI.

Vector

util_vector.h

3D Vector class. Used all over the place for keeping track of positions, movements etc.

Vector2D

util_vector.h

2D Vector class. Used in combat, nodes analysis etc.

*_t / *_s

various

Structures

 

 

 

Game DLL

The Game DLL (sdk\source code\dlls) contains all the code to handle all the game entites. This includes weapons behaviour, monster AI, entities, triggers etc.

If you have a copy of Visual C++ 6, open the hl.dsw Workspace file in this directory.

 

CBaseEntity

cbase.h

The mother of all entities. Contains virtual methods for:

Spawn() which is called when the entity is created in the map, and contains all the initialisation code (calls to precache sprites, set member variables.. all the usual stuff).
Keyvalue()
which handles all the entities parameters that are specified on the map (i.e. the values that pop up when you do Alt+Enter on an entity in Worldcraft).
Think()
the basic processing handler. Called when the entity is spawned, and then can be called automatically by setting the entities pev->nextthink member variable.
Touch()
is triggered when a player (or monster?) touches the entity.
Use()
is the default action for the entity and is triggered when a player uses the entity (presses the use key), or the entity is triggered by another entity.

And a whole load of methods like EarPosition(), TakeDamage(), StopSneaking() etc. that I reckon should be in a subclass. Oh well - I'm sure they know what they're doing.

CBaseDelay

cbase.h

Inherits from CBaseEntity, and is the parent class for all time-dependent entities, e.g. Multi Manager, anything with animation, breakable + pushable objects, etc.

Keyvalue() is overridden to automatically interpret "delay" and "killtarget" keys on the entity.

SUB_UseTargets() is overriden to run through the list of targets and trigger them with the correct delay.

CBaseAnimating

cbase.h

Inherits from CBaseDelay, and is the parent class for all Animating entities e.g. weapons, doors, xen lights, trains, etc.

Adds methods such as StudioFrameAdvance(), SetBodyGroup(), SetBoneController() etc. that are used on all animations.

CActAnimating

xen.cpp

Inherits from CBaseAnimating, and is the parent for all animated xen models (flower-lights etc.)

CBasePlayerItem / CBasePlayerWeapon

weapons.h

Inherits from CBaseAnimating, and is the parent of all of the useable weapons (gauss, crossbow etc.)

CBaseToggle

cbase.h

Inherits from CBaseAnimating, and is the parent of all entities that can be switched on/off including monsters, doors etc.

CBaseMonster

basemonster.h

Inherits from CBaseToggle and is the parent of all monster entities.

Has all the basic monster AI methods, which are worth a separate tutorial.

CDeadScientist

scientist.cpp

Nice easy example of a specific monster. Inherits from CBaseMonster, and overrides the following methods:

Classify() sets the monsters class for AI reactions (in this case, he's a Passive Human).

KeyValue() reads "pose", for specific dead scientist positions (lying face down, lying on back, legs tied behind back "american psycho" style mutilations etc).

Spawn() precaches the scientist model, gives the fellow red blood, not much health (this is the i-can-bash-the-model-until-it-explodes sort of health, rather than the scientist-running-around-full-of-the-joys-of-spring sort of health), selects the particular scientist model (luther, einstein etc.) and the pose (see keyvalue()), and calls CBaseMonster::MonsterInitDead() to kill the poor guy off before he's even finished spawning *sigh*.

CBaseTrigger

triggers.cpp

Inherits from CBaseToggle, and is the parent of various trigger entities, such as TriggerOnce/TriggerMultiple, Push, Teleport, Save, Change CD track etc.

Notation

There arent many coding conventions in the SDK, and those that are used are broken all over the place. But some are:

Most classes start with a C (like CBasePlayer etc.)

Most variables use "Hungarian Notation",  where variables are prefixed with an indicator of their type :

i<var> = int
p<var> = pointer
pfn<var> = function pointer
fl<var> = float
vec<var> = vector object
sz<var>, or psz<var> = char* (string)
b<var> = byte, or boolean ( true(!=0) / false(==0) )
f<var> = boolean ( TRUE(==1) / FALSE(==0) )

m_*<var> = member variable.
<var>_t = typedef structure
<var>_s = structure variable

Glossary

Here are a few terms that are used throughout the SDK that you may want to know about:

Edict = Entity dictionary (?)

PVS = Everything visible from the players position (Player Visible Set ?)

PAS = Everything audible from the players position (Player Audible Set?)

pev = pointer to the entvars_t data structure

 

Right.. thats it for now. If you'd like to see some specific info etc. drop me a line.

Steve.