ref: 4a30ac49c9338a034b76363300cae13330327837
dir: /dat.h/
//#define PARANOID // speed sapping error checking //#define SMALL_FINALVERT typedef uchar byte; typedef float vec_t; typedef vec_t vec3_t[3]; typedef vec_t vec5_t[5]; typedef int fixed4_t; typedef int fixed8_t; typedef int fixed16_t; typedef uchar pixel_t; typedef enum qboolean {false, true} qboolean; typedef struct edict_t edict_t; typedef struct cvar_t cvar_t; typedef struct cplane_t cplane_t; typedef struct cmodel_t cmodel_t; typedef struct csurface_t csurface_t; typedef struct mapsurface_t mapsurface_t; typedef struct trace_t trace_t; typedef struct pmove_state_t pmove_state_t; typedef struct usercmd_t usercmd_t; typedef struct pmove_t pmove_t; typedef struct entity_state_t entity_state_t; typedef struct player_state_t player_state_t; typedef struct sizebuf_t sizebuf_t; typedef struct netadr_t netadr_t; typedef struct netchan_t netchan_t; typedef struct dpackfile_t dpackfile_t; typedef struct dpackheader_t dpackheader_t; typedef struct pcx_t pcx_t; typedef struct dstvert_t dstvert_t; typedef struct dtriangle_t dtriangle_t; typedef struct dtrivertx_t dtrivertx_t; typedef struct daliasframe_t daliasframe_t; typedef struct dmdl_t dmdl_t; typedef struct dsprframe_t dsprframe_t; typedef struct dsprite_t dsprite_t; typedef struct miptex_t miptex_t; typedef struct lump_t lump_t; typedef struct dheader_t dheader_t; typedef struct dmodel_t dmodel_t; typedef struct dvertex_t dvertex_t; typedef struct dplane_t dplane_t; typedef struct dnode_t dnode_t; typedef struct texinfo_t texinfo_t; typedef struct dedge_t dedge_t; typedef struct dface_t dface_t; typedef struct dleaf_t dleaf_t; typedef struct dbrushside_t dbrushside_t; typedef struct dbrush_t dbrush_t; typedef struct dvis_t dvis_t; typedef struct dareaportal_t dareaportal_t; typedef struct darea_t darea_t; typedef struct vrect_t vrect_t; typedef struct viddef_t viddef_t; typedef struct image_t image_t; typedef struct oldrefdef_t oldrefdef_t; typedef struct mvertex_t mvertex_t; typedef struct mplane_t mplane_t; typedef struct medge_t medge_t; typedef struct mtexinfo_t mtexinfo_t; typedef struct msurface_t msurface_t; typedef struct mnode_t mnode_t; typedef struct mleaf_t mleaf_t; typedef struct model_t model_t; typedef struct emitpoint_t emitpoint_t; typedef struct finalvert_t finalvert_t; typedef struct affinetridesc_t affinetridesc_t; typedef struct drawsurf_t drawsurf_t; typedef struct alight_t alight_t; typedef struct bedge_t bedge_t; typedef struct clipplane_t clipplane_t; typedef struct surfcache_t surfcache_t; typedef struct espan_t espan_t; typedef struct polydesc_t polydesc_t; typedef struct surf_t surf_t; typedef struct edge_t edge_t; typedef struct aliastriangleparms_t aliastriangleparms_t; typedef struct swstate_t swstate_t; typedef struct entity_t entity_t; typedef struct dlight_t dlight_t; typedef struct particle_t particle_t; typedef struct lightstyle_t lightstyle_t; typedef struct refdef_t refdef_t; typedef struct refexport_t refexport_t; typedef struct refimport_t refimport_t; typedef struct portable_samplepair_t portable_samplepair_t; typedef struct sfxcache_t sfxcache_t; typedef struct sfx_t sfx_t; typedef struct playsound_t playsound_t; typedef struct dma_t dma_t; typedef struct channel_t channel_t; typedef struct wavinfo_t wavinfo_t; typedef struct console_t console_t; typedef struct frame_t frame_t; typedef struct centity_t centity_t; typedef struct clientinfo_t clientinfo_t; typedef struct client_state_t client_state_t; typedef struct client_static_t client_static_t; typedef struct cdlight_t cdlight_t; typedef struct cl_sustain_t cl_sustain_t; typedef struct cparticle_t cparticle_t; typedef struct kbutton_t kbutton_t; typedef struct menuframework_t menuframework_t; typedef struct menucommon_t menucommon_t; typedef struct menufield_t menufield_t; typedef struct menuslider_t menuslider_t; typedef struct menulist_t menulist_t; typedef struct menuaction_t menuaction_t; typedef struct menuseparator_t menuseparator_t; typedef struct server_t server_t; typedef struct client_frame_t client_frame_t; typedef struct client_t client_t; typedef struct challenge_t challenge_t; typedef struct server_static_t server_static_t; typedef void (*xcommand_t)(void); typedef refexport_t (*GetRefAPI_t)(refimport_t); enum{ /* angle indexes */ PITCH = 0, YAW = 1, ROLL = 2, MAX_STRING_CHARS = 1024, // char* passed to Cmd_TokenizeString, max strlen MAX_STRING_TOKENS = 80, // max tokens resulting from Cmd_TokenizeString MAX_TOKEN_CHARS = 128, // max length of an individual token /* max length of quake game and fs pathname */ MAX_QPATH = 64, MAX_OSPATH = 128, /* per-level limits */ MAX_CLIENTS = 256, // absolute limit MAX_EDICTS = 1024, // must change protocol to increase more MAX_LIGHTSTYLES = 256, /* these are sent over the net as bytes so they cannot be blindly increased */ MAX_MODELS = 256, MAX_SOUNDS = 256, MAX_IMAGES = 256, MAX_ITEMS = 256, MAX_GENERAL = MAX_CLIENTS*2, // general config strings /* game print flags */ PRINT_LOW = 0, // pickup messages PRINT_MEDIUM = 1, // death messages PRINT_HIGH = 2, // critical messages PRINT_CHAT = 3, // chat messages /* key / value info strings */ MAX_INFO_KEY = 64, MAX_INFO_VALUE = 64, MAX_INFO_STRING = 512, MAX_PARSE_ENTITIES = 1024, }; /* destination class for gi.multicast() */ typedef enum multicast_t{ MULTICAST_ALL, MULTICAST_PHS, MULTICAST_PVS, MULTICAST_ALL_R, MULTICAST_PHS_R, MULTICAST_PVS_R }multicast_t; #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h extern vec3_t vec3_origin; #define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2]) #define VectorSubtract(a,b,c) (c[0]=a[0]-b[0],c[1]=a[1]-b[1],c[2]=a[2]-b[2]) #define VectorAdd(a,b,c) (c[0]=a[0]+b[0],c[1]=a[1]+b[1],c[2]=a[2]+b[2]) #define VectorCopy(a,b) (b[0]=a[0],b[1]=a[1],b[2]=a[2]) #define VectorClear(a) (a[0]=a[1]=a[2]=0) #define VectorNegate(a,b) (b[0]=-a[0],b[1]=-a[1],b[2]=-a[2]) #define VectorSet(v, x, y, z) (v[0]=(x), v[1]=(y), v[2]=(z)) #define BOX_ON_PLANE_SIDE(emins, emaxs, p) \ (((p)->type < 3)? \ ( \ ((p)->dist <= (emins)[(p)->type])? \ 1 \ : \ ( \ ((p)->dist >= (emaxs)[(p)->type])?\ 2 \ : \ 3 \ ) \ ) \ : \ BoxOnPlaneSide( (emins), (emaxs), (p))) extern int curtime; // current time in ms, from Sys_Milliseconds() enum{ CVAR_ARCHIVE = 1<<0, // save to vars.rc CVAR_USERINFO = 1<<1, // add to userinfo on change CVAR_SERVERINFO = 1<<2, // add to serverinfo on change CVAR_NOSET = 1<<3, // only allow setting from commandline CVAR_LATCH= 1<<4 // save changes until server restart }; /* nothing outside the Cvar_*() functions should modify these fields! */ struct cvar_t{ char *name; char *string; char *latched_string; // for CVAR_LATCH vars int flags; qboolean modified; // set each time the cvar is changed float value; cvar_t *next; }; extern cvar_t *cvar_vars; extern qboolean userinfo_modified; enum{ /* contents flags are separate bits. a given brush can contribute * multiple content bits. multiple brushes can be in a single leaf * lower bits are stronger, and will eat weaker brushes completely */ CONTENTS_SOLID = 1<<0, // an eye is never valid in a solid CONTENTS_WINDOW = 1<<1, // translucent, but not watery CONTENTS_AUX = 1<<2, CONTENTS_LAVA = 1<<3, CONTENTS_SLIME = 1<<4, CONTENTS_WATER = 1<<5, CONTENTS_MIST = 1<<6, LAST_VISIBLE_CONTENTS = 1<<6, /* remaining contents are non-visible, and don't eat brushes */ CONTENTS_AREAPORTAL = 1<<15, CONTENTS_PLAYERCLIP = 1<<16, CONTENTS_MONSTERCLIP = 1<<17, /* currents can be added to any other contents, and may be mixed */ CONTENTS_CURRENT_0 = 1<<18, CONTENTS_CURRENT_90 = 1<<19, CONTENTS_CURRENT_180 = 1<<20, CONTENTS_CURRENT_270 = 1<<21, CONTENTS_CURRENT_UP = 1<<22, CONTENTS_CURRENT_DOWN = 1<<23, CONTENTS_ORIGIN = 1<<24, // removed before bsping an entity CONTENTS_MONSTER = 1<<25, // should never be on a brush, only in game CONTENTS_DEADMONSTER = 1<<26, CONTENTS_DETAIL = 1<<27, // brushes to be added after vis leafs CONTENTS_TRANSLUCENT = 1<<28, // auto set if any surface has trans CONTENTS_LADDER = 1<<29, SURF_LIGHT = 1<<0, // value will hold the light strength SURF_SLICK = 1<<1, // effects game physics SURF_SKY = 1<<2, // don't draw, but add to skybox SURF_WARP = 1<<3, // turbulent water warp SURF_TRANS33 = 1<<4, SURF_TRANS66 = 1<<5, SURF_FLOWING = 1<<6, // scroll towards angle SURF_NODRAW = 1<<7, // don't bother referencing the texture /* content masks */ MASK_ALL = -1, MASK_SOLID = CONTENTS_SOLID|CONTENTS_WINDOW, MASK_PLAYERSOLID = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER, MASK_DEADSOLID = CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW, MASK_MONSTERSOLID = CONTENTS_SOLID|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER, MASK_WATER = CONTENTS_WATER|CONTENTS_LAVA|CONTENTS_SLIME, MASK_OPAQUE = CONTENTS_SOLID|CONTENTS_SLIME|CONTENTS_LAVA, MASK_SHOT = CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEADMONSTER, MASK_CURRENT = CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN, // FIXME: eliminate AREA_ distinction? /* SV_AreaEdicts() can return a list of either solid or trigger entities */ AREA_SOLID = 1<<0, AREA_TRIGGERS = 1<<1 }; /* !!! if this is changed, it must be changed in asm code too !!! */ struct cplane_t{ vec3_t normal; float dist; uchar type; // for fast side tests uchar signbits; // signx + (signy<<1) + (signz<<1) uchar pad[2]; }; struct cmodel_t{ vec3_t mins; vec3_t maxs; vec3_t origin; // for sounds or lights int headnode; }; struct csurface_t{ char name[16]; int flags; int value; }; /* used internally due to name len probs */ struct mapsurface_t{ csurface_t c; char rname[32]; }; /* a trace is returned when a box is swept through the world */ struct trace_t{ qboolean allsolid; // if true, plane is not valid qboolean startsolid; // if true, the initial point was in a solid area float fraction; // time completed, 1.0 = didn't hit anything vec3_t endpos; // final position cplane_t plane; // surface normal at impact csurface_t *surface; // surface hit int contents; // contents on other side of surface hit edict_t *ent; // not set by CM_*() functions }; /* information necessary for client side movement prediction */ typedef enum pmtype_t{ /* can accelerate and turn */ PM_NORMAL, PM_SPECTATOR, /* no acceleration or turning */ PM_DEAD, PM_GIB, // different bounding box PM_FREEZE }pmtype_t; enum{ PMF_DUCKED = 1<<0, PMF_JUMP_HELD = 1<<1, PMF_ON_GROUND = 1<<2, PMF_TIME_WATERJUMP = 1<<3, // pm_time is waterjump PMF_TIME_LAND = 1<<4, // pm_time is time before rejump PMF_TIME_TELEPORT = 1<<5, // pm_time is non-moving time /* temporarily disables prediction (used for grappling hook) */ PMF_NO_PREDICTION = 1<<6, }; /* this structure needs to be communicated bit-accurate from the server to the * client to guarantee that prediction stays in sync, so no floats are used. * if any part of the game code modifies this struct, it will result in a * prediction error of some degree. */ struct pmove_state_t{ pmtype_t pm_type; short origin[3]; // 12.3 short velocity[3]; // 12.3 uchar pm_flags; // ducked, jump_held, etc uchar pm_time; // each unit = 8 ms short gravity; /* add to command angles to get view direction changed by spawns, * rotating objects and teleporters */ short delta_angles[3]; }; enum{ BUTTON_ATTACK = 1<<0, BUTTON_USE = 1<<1, BUTTON_ANY = 1<<7, // any key whatsoever MAXTOUCH = 32 }; /* sent to the server each client frame */ struct usercmd_t{ uchar msec; uchar buttons; short angles[3]; short forwardmove; short sidemove; short upmove; uchar impulse; // remove? uchar lightlevel; // light level the player is standing on }; struct pmove_t{ pmove_state_t s; // state (in / out) /* command (in) */ usercmd_t cmd; qboolean snapinitial; // if s has been changed outside pmove /* results (out) */ int numtouch; edict_t *touchents[MAXTOUCH]; vec3_t viewangles; // clamped float viewheight; vec3_t mins; // bounding box size vec3_t maxs; edict_t *groundentity; int watertype; int waterlevel; /* callbacks to test the world */ trace_t (*trace)(vec3_t, vec3_t, vec3_t, vec3_t); int (*pointcontents)(vec3_t); }; enum{ /* entity_state_t->effects * Effects are things handled on the client side (lights, particles, frame * animations) that happen constantly on the given entity. An entity that has * effects will be sent to the client even if it has a zero index model. */ EF_ROTATE = 1<<0, // rotate (bonus items) EF_GIB = 1<<1, // leave a trail EF_BLASTER = 1<<3, // redlight + trail EF_ROCKET = 1<<4, // redlight + trail EF_GRENADE = 1<<5, EF_HYPERBLASTER = 1<<6, EF_BFG = 1<<7, EF_COLOR_SHELL = 1<<8, EF_POWERSCREEN = 1<<9, EF_ANIM01 = 1<<10, // automatically cycle between frames 0 and 1 at 2 hz EF_ANIM23 = 1<<11, // automatically cycle between frames 2 and 3 at 2 hz EF_ANIM_ALL = 1<<12, // automatically cycle through all frames at 2hz EF_ANIM_ALLFAST = 1<<13, // automatically cycle through all frames at 10hz EF_FLIES = 1<<14, EF_QUAD = 1<<15, EF_PENT = 1<<16, EF_TELEPORTER = 1<<17, // particle fountain EF_FLAG1 = 1<<18, EF_FLAG2 = 1<<19, EF_IONRIPPER = 1<<20, EF_GREENGIB = 1<<21, EF_BLUEHYPERBLASTER = 1<<22, EF_SPINNINGLIGHTS = 1<<23, EF_PLASMA = 1<<24, EF_TRAP = 1<<25, /* ROGUE */ EF_TRACKER = 1<<26, EF_DOUBLE = 1<<27, EF_SPHERETRANS = 1<<28, EF_TAGTRAIL = 1<<29, EF_HALF_DAMAGE = 1<<30, EF_TRACKERTRAIL = 1<<31, /* entity_state_t->renderfx */ RF_MINLIGHT = 1<<0, // allways have some light (viewmodel) RF_VIEWERMODEL = 1<<1, // don't draw through eyes, only mirrors RF_WEAPONMODEL = 1<<2, // only draw through eyes RF_FULLBRIGHT = 1<<3, // allways draw full intensity RF_DEPTHHACK = 1<<4, // for view weapon Z crunching RF_TRANSLUCENT = 1<<5, RF_FRAMELERP = 1<<6, RF_BEAM = 1<<7, RF_CUSTOMSKIN = 1<<8, // skin is an index in image_precache RF_GLOW = 1<<9, // pulse lighting for bonus items RF_SHELL_RED = 1<<10, RF_SHELL_GREEN = 1<<11, RF_SHELL_BLUE = 1<<12, /* ROGUE */ RF_IR_VISIBLE = 1<<15, RF_SHELL_DOUBLE = 1<<16, RF_SHELL_HALF_DAM = 1<<17, RF_USE_DISGUISE = 1<<18, /* player_state_t->refdef */ RDF_UNDERWATER = 1<<0, // warp the screen as apropriate RDF_NOWORLDMODEL = 1<<1, // used for player configuration screen /* ROGUE */ RDF_IRGOGGLES = 1<<2, RDF_UVGOGGLES = 1<<3, /* muzzle flashes, player effects */ MZ_BLASTER = 0, MZ_MACHINEGUN = 1, MZ_SHOTGUN = 2, MZ_CHAINGUN1 = 3, MZ_CHAINGUN2 = 4, MZ_CHAINGUN3 = 5, MZ_RAILGUN = 6, MZ_ROCKET = 7, MZ_GRENADE = 8, MZ_LOGIN = 9, MZ_LOGOUT = 10, MZ_RESPAWN = 11, MZ_BFG = 12, MZ_SSHOTGUN = 13, MZ_HYPERBLASTER = 14, MZ_ITEMRESPAWN = 15, MZ_IONRIPPER = 16, MZ_BLUEHYPERBLASTER = 17, MZ_PHALANX = 18, MZ_SILENCED = 128, // bit flag ORed with one of the above numbers /* ROGUE */ MZ_ETF_RIFLE = 30, MZ_UNUSED = 31, MZ_SHOTGUN2 = 32, MZ_HEATBEAM = 33, MZ_BLASTER2 = 34, MZ_TRACKER = 35, MZ_NUKE1 = 36, MZ_NUKE2 = 37, MZ_NUKE4 = 38, MZ_NUKE8 = 39, /* monster muzzle flashes */ MZ2_TANK_BLASTER_1 = 1, MZ2_TANK_BLASTER_2 = 2, MZ2_TANK_BLASTER_3 = 3, MZ2_TANK_MACHINEGUN_1 = 4, MZ2_TANK_MACHINEGUN_2 = 5, MZ2_TANK_MACHINEGUN_3 = 6, MZ2_TANK_MACHINEGUN_4 = 7, MZ2_TANK_MACHINEGUN_5 = 8, MZ2_TANK_MACHINEGUN_6 = 9, MZ2_TANK_MACHINEGUN_7 = 10, MZ2_TANK_MACHINEGUN_8 = 11, MZ2_TANK_MACHINEGUN_9 = 12, MZ2_TANK_MACHINEGUN_10 = 13, MZ2_TANK_MACHINEGUN_11 = 14, MZ2_TANK_MACHINEGUN_12 = 15, MZ2_TANK_MACHINEGUN_13 = 16, MZ2_TANK_MACHINEGUN_14 = 17, MZ2_TANK_MACHINEGUN_15 = 18, MZ2_TANK_MACHINEGUN_16 = 19, MZ2_TANK_MACHINEGUN_17 = 20, MZ2_TANK_MACHINEGUN_18 = 21, MZ2_TANK_MACHINEGUN_19 = 22, MZ2_TANK_ROCKET_1 = 23, MZ2_TANK_ROCKET_2 = 24, MZ2_TANK_ROCKET_3 = 25, MZ2_INFANTRY_MACHINEGUN_1 = 26, MZ2_INFANTRY_MACHINEGUN_2 = 27, MZ2_INFANTRY_MACHINEGUN_3 = 28, MZ2_INFANTRY_MACHINEGUN_4 = 29, MZ2_INFANTRY_MACHINEGUN_5 = 30, MZ2_INFANTRY_MACHINEGUN_6 = 31, MZ2_INFANTRY_MACHINEGUN_7 = 32, MZ2_INFANTRY_MACHINEGUN_8 = 33, MZ2_INFANTRY_MACHINEGUN_9 = 34, MZ2_INFANTRY_MACHINEGUN_10 = 35, MZ2_INFANTRY_MACHINEGUN_11 = 36, MZ2_INFANTRY_MACHINEGUN_12 = 37, MZ2_INFANTRY_MACHINEGUN_13 = 38, MZ2_SOLDIER_BLASTER_1 = 39, MZ2_SOLDIER_BLASTER_2 = 40, MZ2_SOLDIER_SHOTGUN_1 = 41, MZ2_SOLDIER_SHOTGUN_2 = 42, MZ2_SOLDIER_MACHINEGUN_1 = 43, MZ2_SOLDIER_MACHINEGUN_2 = 44, MZ2_GUNNER_MACHINEGUN_1 = 45, MZ2_GUNNER_MACHINEGUN_2 = 46, MZ2_GUNNER_MACHINEGUN_3 = 47, MZ2_GUNNER_MACHINEGUN_4 = 48, MZ2_GUNNER_MACHINEGUN_5 = 49, MZ2_GUNNER_MACHINEGUN_6 = 50, MZ2_GUNNER_MACHINEGUN_7 = 51, MZ2_GUNNER_MACHINEGUN_8 = 52, MZ2_GUNNER_GRENADE_1 = 53, MZ2_GUNNER_GRENADE_2 = 54, MZ2_GUNNER_GRENADE_3 = 55, MZ2_GUNNER_GRENADE_4 = 56, MZ2_CHICK_ROCKET_1 = 57, MZ2_FLYER_BLASTER_1 = 58, MZ2_FLYER_BLASTER_2 = 59, MZ2_MEDIC_BLASTER_1 = 60, MZ2_GLADIATOR_RAILGUN_1 = 61, MZ2_HOVER_BLASTER_1 = 62, MZ2_ACTOR_MACHINEGUN_1 = 63, MZ2_SUPERTANK_MACHINEGUN_1 = 64, MZ2_SUPERTANK_MACHINEGUN_2 = 65, MZ2_SUPERTANK_MACHINEGUN_3 = 66, MZ2_SUPERTANK_MACHINEGUN_4 = 67, MZ2_SUPERTANK_MACHINEGUN_5 = 68, MZ2_SUPERTANK_MACHINEGUN_6 = 69, MZ2_SUPERTANK_ROCKET_1 = 70, MZ2_SUPERTANK_ROCKET_2 = 71, MZ2_SUPERTANK_ROCKET_3 = 72, MZ2_BOSS2_MACHINEGUN_L1 = 73, MZ2_BOSS2_MACHINEGUN_L2 = 74, MZ2_BOSS2_MACHINEGUN_L3 = 75, MZ2_BOSS2_MACHINEGUN_L4 = 76, MZ2_BOSS2_MACHINEGUN_L5 = 77, MZ2_BOSS2_ROCKET_1 = 78, MZ2_BOSS2_ROCKET_2 = 79, MZ2_BOSS2_ROCKET_3 = 80, MZ2_BOSS2_ROCKET_4 = 81, MZ2_FLOAT_BLASTER_1 = 82, MZ2_SOLDIER_BLASTER_3 = 83, MZ2_SOLDIER_SHOTGUN_3 = 84, MZ2_SOLDIER_MACHINEGUN_3 = 85, MZ2_SOLDIER_BLASTER_4 = 86, MZ2_SOLDIER_SHOTGUN_4 = 87, MZ2_SOLDIER_MACHINEGUN_4 = 88, MZ2_SOLDIER_BLASTER_5 = 89, MZ2_SOLDIER_SHOTGUN_5 = 90, MZ2_SOLDIER_MACHINEGUN_5 = 91, MZ2_SOLDIER_BLASTER_6 = 92, MZ2_SOLDIER_SHOTGUN_6 = 93, MZ2_SOLDIER_MACHINEGUN_6 = 94, MZ2_SOLDIER_BLASTER_7 = 95, MZ2_SOLDIER_SHOTGUN_7 = 96, MZ2_SOLDIER_MACHINEGUN_7 = 97, MZ2_SOLDIER_BLASTER_8 = 98, MZ2_SOLDIER_SHOTGUN_8 = 99, MZ2_SOLDIER_MACHINEGUN_8 = 100, /* --- Xian shit below --- */ MZ2_MAKRON_BFG = 101, MZ2_MAKRON_BLASTER_1 = 102, MZ2_MAKRON_BLASTER_2 = 103, MZ2_MAKRON_BLASTER_3 = 104, MZ2_MAKRON_BLASTER_4 = 105, MZ2_MAKRON_BLASTER_5 = 106, MZ2_MAKRON_BLASTER_6 = 107, MZ2_MAKRON_BLASTER_7 = 108, MZ2_MAKRON_BLASTER_8 = 109, MZ2_MAKRON_BLASTER_9 = 110, MZ2_MAKRON_BLASTER_10 = 111, MZ2_MAKRON_BLASTER_11 = 112, MZ2_MAKRON_BLASTER_12 = 113, MZ2_MAKRON_BLASTER_13 = 114, MZ2_MAKRON_BLASTER_14 = 115, MZ2_MAKRON_BLASTER_15 = 116, MZ2_MAKRON_BLASTER_16 = 117, MZ2_MAKRON_BLASTER_17 = 118, MZ2_MAKRON_RAILGUN_1 = 119, MZ2_JORG_MACHINEGUN_L1 = 120, MZ2_JORG_MACHINEGUN_L2 = 121, MZ2_JORG_MACHINEGUN_L3 = 122, MZ2_JORG_MACHINEGUN_L4 = 123, MZ2_JORG_MACHINEGUN_L5 = 124, MZ2_JORG_MACHINEGUN_L6 = 125, MZ2_JORG_MACHINEGUN_R1 = 126, MZ2_JORG_MACHINEGUN_R2 = 127, MZ2_JORG_MACHINEGUN_R3 = 128, MZ2_JORG_MACHINEGUN_R4 = 129, MZ2_JORG_MACHINEGUN_R5 = 130, MZ2_JORG_MACHINEGUN_R6 = 131, MZ2_JORG_BFG_1 = 132, MZ2_BOSS2_MACHINEGUN_R1 = 133, MZ2_BOSS2_MACHINEGUN_R2 = 134, MZ2_BOSS2_MACHINEGUN_R3 = 135, MZ2_BOSS2_MACHINEGUN_R4 = 136, MZ2_BOSS2_MACHINEGUN_R5 = 137, /* ROGUE */ MZ2_CARRIER_MACHINEGUN_L1 = 138, MZ2_CARRIER_MACHINEGUN_R1 = 139, MZ2_CARRIER_GRENADE = 140, MZ2_TURRET_MACHINEGUN = 141, MZ2_TURRET_ROCKET = 142, MZ2_TURRET_BLASTER = 143, MZ2_STALKER_BLASTER = 144, MZ2_DAEDALUS_BLASTER = 145, MZ2_MEDIC_BLASTER_2 = 146, MZ2_CARRIER_RAILGUN = 147, MZ2_WIDOW_DISRUPTOR = 148, MZ2_WIDOW_BLASTER = 149, MZ2_WIDOW_RAIL = 150, MZ2_WIDOW_PLASMABEAM = 151, // PMM - not used MZ2_CARRIER_MACHINEGUN_L2 = 152, MZ2_CARRIER_MACHINEGUN_R2 = 153, MZ2_WIDOW_RAIL_LEFT = 154, MZ2_WIDOW_RAIL_RIGHT = 155, MZ2_WIDOW_BLASTER_SWEEP1 = 156, MZ2_WIDOW_BLASTER_SWEEP2 = 157, MZ2_WIDOW_BLASTER_SWEEP3 = 158, MZ2_WIDOW_BLASTER_SWEEP4 = 159, MZ2_WIDOW_BLASTER_SWEEP5 = 160, MZ2_WIDOW_BLASTER_SWEEP6 = 161, MZ2_WIDOW_BLASTER_SWEEP7 = 162, MZ2_WIDOW_BLASTER_SWEEP8 = 163, MZ2_WIDOW_BLASTER_SWEEP9 = 164, MZ2_WIDOW_BLASTER_100 = 165, MZ2_WIDOW_BLASTER_90 = 166, MZ2_WIDOW_BLASTER_80 = 167, MZ2_WIDOW_BLASTER_70 = 168, MZ2_WIDOW_BLASTER_60 = 169, MZ2_WIDOW_BLASTER_50 = 170, MZ2_WIDOW_BLASTER_40 = 171, MZ2_WIDOW_BLASTER_30 = 172, MZ2_WIDOW_BLASTER_20 = 173, MZ2_WIDOW_BLASTER_10 = 174, MZ2_WIDOW_BLASTER_0 = 175, MZ2_WIDOW_BLASTER_10L = 176, MZ2_WIDOW_BLASTER_20L = 177, MZ2_WIDOW_BLASTER_30L = 178, MZ2_WIDOW_BLASTER_40L = 179, MZ2_WIDOW_BLASTER_50L = 180, MZ2_WIDOW_BLASTER_60L = 181, MZ2_WIDOW_BLASTER_70L = 182, MZ2_WIDOW_RUN_1 = 183, MZ2_WIDOW_RUN_2 = 184, MZ2_WIDOW_RUN_3 = 185, MZ2_WIDOW_RUN_4 = 186, MZ2_WIDOW_RUN_5 = 187, MZ2_WIDOW_RUN_6 = 188, MZ2_WIDOW_RUN_7 = 189, MZ2_WIDOW_RUN_8 = 190, MZ2_CARRIER_ROCKET_1 = 191, MZ2_CARRIER_ROCKET_2 = 192, MZ2_CARRIER_ROCKET_3 = 193, MZ2_CARRIER_ROCKET_4 = 194, MZ2_WIDOW2_BEAMER_1 = 195, MZ2_WIDOW2_BEAMER_2 = 196, MZ2_WIDOW2_BEAMER_3 = 197, MZ2_WIDOW2_BEAMER_4 = 198, MZ2_WIDOW2_BEAMER_5 = 199, MZ2_WIDOW2_BEAM_SWEEP_1 = 200, MZ2_WIDOW2_BEAM_SWEEP_2 = 201, MZ2_WIDOW2_BEAM_SWEEP_3 = 202, MZ2_WIDOW2_BEAM_SWEEP_4 = 203, MZ2_WIDOW2_BEAM_SWEEP_5 = 204, MZ2_WIDOW2_BEAM_SWEEP_6 = 205, MZ2_WIDOW2_BEAM_SWEEP_7 = 206, MZ2_WIDOW2_BEAM_SWEEP_8 = 207, MZ2_WIDOW2_BEAM_SWEEP_9 = 208, MZ2_WIDOW2_BEAM_SWEEP_10 = 209, MZ2_WIDOW2_BEAM_SWEEP_11 = 210 }; extern vec3_t monster_flash_offset[]; /* Temp entity events are for things that happen at a location seperate from * any existing entity. Temporary entity messages are explicitly constructed * and broadcast. */ typedef enum temp_event_t{ TE_GUNSHOT, TE_BLOOD, TE_BLASTER, TE_RAILTRAIL, TE_SHOTGUN, TE_EXPLOSION1, TE_EXPLOSION2, TE_ROCKET_EXPLOSION, TE_GRENADE_EXPLOSION, TE_SPARKS, TE_SPLASH, TE_BUBBLETRAIL, TE_SCREEN_SPARKS, TE_SHIELD_SPARKS, TE_BULLET_SPARKS, TE_LASER_SPARKS, TE_PARASITE_ATTACK, TE_ROCKET_EXPLOSION_WATER, TE_GRENADE_EXPLOSION_WATER, TE_MEDIC_CABLE_ATTACK, TE_BFG_EXPLOSION, TE_BFG_BIGEXPLOSION, TE_BOSSTPORT, // used as '22' in a map, so DON'T RENUMBER!!! TE_BFG_LASER, TE_GRAPPLE_CABLE, TE_WELDING_SPARKS, TE_GREENBLOOD, TE_BLUEHYPERBLASTER, TE_PLASMA_EXPLOSION, TE_TUNNEL_SPARKS, /* ROGUE */ TE_BLASTER2, TE_RAILTRAIL2, TE_FLAME, TE_LIGHTNING, TE_DEBUGTRAIL, TE_PLAIN_EXPLOSION, TE_FLASHLIGHT, TE_FORCEWALL, TE_HEATBEAM, TE_MONSTER_HEATBEAM, TE_STEAM, TE_BUBBLETRAIL2, TE_MOREBLOOD, TE_HEATBEAM_SPARKS, TE_HEATBEAM_STEAM, TE_CHAINFIST_SMOKE, TE_ELECTRIC_SPARKS, TE_TRACKER_EXPLOSION, TE_TELEPORT_EFFECT, TE_DBALL_GOAL, TE_WIDOWBEAMOUT, TE_NUKEBLAST, TE_WIDOWSPLASH, TE_EXPLOSION1_BIG, TE_EXPLOSION1_NP, TE_FLECHETTE }temp_event_t; enum{ SPLASH_UNKNOWN = 0, SPLASH_SPARKS = 1, SPLASH_BLUE_WATER = 2, SPLASH_BROWN_WATER = 3, SPLASH_SLIME = 4, SPLASH_LAVA = 5, SPLASH_BLOOD = 6, /* sound channels * channel 0 never willingly overrides * other channels (1-7) allways override a playing sound on that channel */ CHAN_AUTO = 0, CHAN_WEAPON = 1, CHAN_VOICE = 2, CHAN_ITEM = 3, CHAN_BODY = 4, /* modifier flags */ CHAN_NO_PHS_ADD = 1<<3, // send to all clients, not just ones in PHS (ATTN 0 will also do this) CHAN_RELIABLE = 1<<4, // send by reliable message, not datagram /* sound attenuation values */ ATTN_NONE = 0, // full volume the entire level ATTN_NORM = 1, ATTN_IDLE = 2, ATTN_STATIC = 3, // diminish very rapidly with distance /* player_state->stats[] */ STAT_HEALTH_ICON = 0, STAT_HEALTH = 1, STAT_AMMO_ICON = 2, STAT_AMMO = 3, STAT_ARMOR_ICON = 4, STAT_ARMOR = 5, STAT_SELECTED_ICON = 6, STAT_PICKUP_ICON = 7, STAT_PICKUP_STRING = 8, STAT_TIMER_ICON = 9, STAT_TIMER = 10, STAT_HELPICON = 11, STAT_SELECTED_ITEM = 12, STAT_LAYOUTS = 13, STAT_FRAGS = 14, STAT_FLASHES = 15, // cleared each frame, 1 = health, 2 = armor STAT_CHASE = 16, STAT_SPECTATOR = 17, MAX_STATS = 32, /* dmflags->value */ DF_NO_HEALTH = 1<<0, DF_NO_ITEMS = 1<<1, DF_WEAPONS_STAY = 1<<2, DF_NO_FALLING = 1<<3, DF_INSTANT_ITEMS = 1<<4, DF_SAME_LEVEL = 1<<5, DF_SKINTEAMS = 1<<6, DF_MODELTEAMS = 1<<7, DF_NO_FRIENDLY_FIRE = 1<<8, DF_SPAWN_FARTHEST = 1<<9, DF_FORCE_RESPAWN = 1<<10, DF_NO_ARMOR = 1<<11, DF_ALLOW_EXIT = 1<<12, DF_INFINITE_AMMO = 1<<13, DF_QUAD_DROP = 1<<14, DF_FIXED_FOV = 1<<15, DF_QUADFIRE_DROP = 1<<16, /* ROGUE */ DF_NO_MINES = 1<<17, DF_NO_STACK_DOUBLE = 1<<18, DF_NO_NUKES = 1<<19, DF_NO_SPHERES = 1<<20, ROGUE_VERSION_ID = 1278 // probably bs }; /* communicated accross the net */ #define ANGLE2SHORT(x) ((int)((x)*65536/360) & 65535) #define SHORT2ANGLE(x) ((x)*(360.0/65536)) enum{ /* config strings are a general means of communication from the server * to all connected clients. each config string can be at most * MAX_QPATH characters. */ CS_NAME = 0, CS_CDTRACK = 1, CS_SKY = 2, CS_SKYAXIS = 3, // %f %f %f format CS_SKYROTATE = 4, CS_STATUSBAR = 5, // display program string CS_AIRACCEL = 29, // air acceleration control CS_MAXCLIENTS = 30, CS_MAPCHECKSUM = 31, // for catching cheater maps CS_MODELS = 32, CS_SOUNDS = CS_MODELS+MAX_MODELS, CS_IMAGES = CS_SOUNDS+MAX_SOUNDS, CS_LIGHTS = CS_IMAGES+MAX_IMAGES, CS_ITEMS = CS_LIGHTS+MAX_LIGHTSTYLES, CS_PLAYERSKINS = CS_ITEMS+MAX_ITEMS, CS_GENERAL = CS_PLAYERSKINS+MAX_CLIENTS, MAX_CONFIGSTRINGS = CS_GENERAL+MAX_GENERAL }; /* entity events are for effects that take place relative to an existing * entitiy origin. Very network efficient. All muzzle flashes really should be * converted to events... */ typedef enum entity_event_t{ EV_NONE, EV_ITEM_RESPAWN, EV_FOOTSTEP, EV_FALLSHORT, EV_FALL, EV_FALLFAR, EV_PLAYER_TELEPORT, EV_OTHER_TELEPORT }entity_event_t; /* information conveyed from the server in an update message about entities * that the client will need to render in some way */ struct entity_state_t{ int number; // edict index vec3_t origin; vec3_t angles; vec3_t old_origin; // for lerping int modelindex; int modelindex2; // weapons, CTF flags, etc int modelindex3; int modelindex4; int frame; int skinnum; uint effects; // PGM - we're filling it, so it needs to be unsigned int renderfx; /* for client side prediction; SV_LinkEdict() sets .solid properly: * 8*(bits 0-4) is x/y radius * 8*(bits 5-9) is z down distance * 8(bits10-15) is z up */ int solid; int sound; // for looping sounds, to guarantee shutoff /* impulse events: muzzle flashes, footsteps, etc. * events only go out for a single frame, they are automatically * cleared each frame */ int event; }; /* the cl_parse_entities must be large enough to hold UPDATE_BACKUP frames of * entities, so that when a delta compressed message arives from the server it * can be un-deltad from the original */ extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES]; /* information needed in addition to pmove_state_t to render a view. There will * only be 10 player_state_t sent each second, but the number of pmove_state_t * changes will be reletive to client frame rates */ struct player_state_t{ pmove_state_t pmove; // for prediction /* these fields do not need to be communicated bit-precise */ vec3_t viewangles; // for fixed views vec3_t viewoffset; // add to pmovestate->origin /* set by weapon kicks, pain effects, etc. */ vec3_t kick_angles; // add to view direction to get render angles vec3_t gunangles; vec3_t gunoffset; int gunindex; int gunframe; float blend[4]; // rgba full screen effect float fov; // horizontal field of view int rdflags; // refdef flags short stats[MAX_STATS]; // fast status bar updates }; enum{ VIDREF_GL = 1, VIDREF_SOFT = 2 }; extern int vidref_val; #include "game/game.h" // ugh extern game_export_t *ge; #define VERSION 3.19 #define BASEDIRNAME "baseq2" struct sizebuf_t{ qboolean allowoverflow; // if false, do a Com_Error qboolean overflowed; // set to true if the buffer size failed uchar *data; int maxsize; int cursize; int readcount; }; extern sizebuf_t net_message; #define DEFAULT_SOUND_PACKET_VOLUME 1.0 #define DEFAULT_SOUND_PACKET_ATTENUATION 1.0 enum{ PROTOCOL_VERSION = 34, PORT_MASTER = 27900, PORT_CLIENT = 27901, PORT_SERVER = 27910, UPDATE_BACKUP = 16, // buffered copies of entity_state_t; must be power of two UPDATE_MASK = UPDATE_BACKUP-1, /* server to client: protocol bytes that can be directly added to * messages; the svc_strings[] array in cl_parse.c should mirror this */ svc_bad = 0, /* these ops are known to the game dll */ svc_muzzleflash, svc_muzzleflash2, svc_temp_entity, svc_layout, svc_inventory, /* the rest are private to the client and server */ svc_nop, svc_disconnect, svc_reconnect, svc_sound, svc_print, // [byte] id [string] null terminated string svc_stufftext, // [string] stuffed into client's console buffer, should be \n terminated svc_serverdata, // [long] protocol ... svc_configstring, // [short] [string] svc_spawnbaseline, svc_centerprint, // [string] to put in center of the screen svc_download, // [short] size [size bytes] svc_playerinfo, // variable svc_packetentities, // [...] svc_deltapacketentities, // [...] svc_frame, /* client to server */ clc_bad = 0, clc_nop, clc_move, // [[usercmd_t] clc_userinfo, // [[userinfo string] clc_stringcmd, // [string] message /* player_state_t communication */ PS_M_TYPE = 1<<0, PS_M_ORIGIN = 1<<1, PS_M_VELOCITY = 1<<2, PS_M_TIME = 1<<3, PS_M_FLAGS = 1<<4, PS_M_GRAVITY = 1<<5, PS_M_DELTA_ANGLES = 1<<6, PS_VIEWOFFSET = 1<<7, PS_VIEWANGLES = 1<<8, PS_KICKANGLES = 1<<9, PS_BLEND = 1<<10, PS_FOV = 1<<11, PS_WEAPONINDEX = 1<<12, PS_WEAPONFRAME = 1<<13, PS_RDFLAGS = 1<<14, /* user_cmd_t communication: ms and light always sent, the others are * optional */ CM_ANGLE1 = 1<<0, CM_ANGLE2 = 1<<1, CM_ANGLE3 = 1<<2, CM_FORWARD = 1<<3, CM_SIDE = 1<<4, CM_UP = 1<<5, CM_BUTTONS = 1<<6, CM_IMPULSE = 1<<7, /* a sound without an ent or pos will be a local only sound */ SND_VOLUME = 1<<0, // a byte SND_ATTENUATION = 1<<1, // a byte SND_POS = 1<<2, // three coordinates SND_ENT = 1<<3, // a short 0-2: channel, 3-12: entity SND_OFFSET = 1<<4, // a byte, msec offset from frame start /* entity_state_t communication */ /* try to pack the common update flags into the first byte */ U_ORIGIN1 = 1<<0, U_ORIGIN2 = 1<<1, U_ANGLE2 = 1<<2, U_ANGLE3 = 1<<3, U_FRAME8 = 1<<4, // frame is a byte U_EVENT = 1<<5, U_REMOVE = 1<<6, // REMOVE this entity, don't add it U_MOREBITS1 = 1<<7, // read one additional byte U_NUMBER16 = 1<<8, // NUMBER8 is implicit if not set U_ORIGIN3 = 1<<9, U_ANGLE1 = 1<<10, U_MODEL = 1<<11, U_RENDERFX8 = 1<<12, // fullbright, etc U_EFFECTS8 = 1<<14, // autorotate, trails, etc U_MOREBITS2 = 1<<15, // read one additional byte U_SKIN8 = 1<<16, U_FRAME16 = 1<<17, // frame is a short U_RENDERFX16 = 1<<18, // 8 + 16 = 32 U_EFFECTS16 = 1<<19, // 8 + 16 = 32 U_MODEL2 = 1<<20, // weapons, flags, etc U_MODEL3 = 1<<21, U_MODEL4 = 1<<22, U_MOREBITS3 = 1<<23, // read one additional byte U_OLDORIGIN = 1<<24, // FIXME: get rid of this U_SKIN16 = 1<<25, U_SOUND = 1<<26, U_SOLID = 1<<27, }; extern char *svc_strings[256]; typedef enum netsrc_t{ NS_CLIENT, NS_SERVER }netsrc_t; typedef enum netadrtype_t{ NA_LOOPBACK, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX }netadrtype_t; #define OLD_AVG 0.99 // total = oldtotal*OLD_AVG + new*(1-OLD_AVG) enum{ PORT_ANY = -1, MAX_MSGLEN = 1400, // max length of a message PACKET_HEADER = 10, // two ints and a short MAX_LATENT = 32, MAX_MASTERS = 8 // max recipients for heartbeat packets }; struct netadr_t{ netadrtype_t type; uchar ip[4]; uchar ipx[10]; ushort port; }; extern netadr_t net_from; extern netadr_t master_adr[MAX_MASTERS]; // address of the master server struct netchan_t{ qboolean fatal_error; netsrc_t sock; int dropped; // between last packet and previous int last_received; // for timeouts int last_sent; // for retransmits netadr_t remote_address; int qport; // qport value to write when transmitting /* sequencing variables */ int incoming_sequence; int incoming_acknowledged; int incoming_reliable_acknowledged; // single bit int incoming_reliable_sequence; // single bit, maintained local int outgoing_sequence; int reliable_sequence; // single bit int last_reliable_sequence; // sequence number of last send /* reliable staging and holding areas */ sizebuf_t message; // writing buffer to send to server uchar message_buf[MAX_MSGLEN-16]; // leave space for header /* message is copied to this buffer when it is first transfered */ int reliable_length; uchar reliable_buf[MAX_MSGLEN-16]; // unacked reliable message }; extern uchar net_message_buffer[MAX_MSGLEN]; extern float pm_airaccelerate; extern cvar_t *developer; extern cvar_t *dedicated; extern cvar_t *host_speeds; extern cvar_t *log_stats; enum{ ERR_FATAL = 0, // exit the entire game with a popup window ERR_DROP = 1, // print to console and disconnect from game ERR_QUIT = 2, // not an error, just a normal exit ERR_DISCONNECT = 2, // don't kill server EXEC_NOW = 0, // don't return until completed EXEC_INSERT = 1, // insert at current position, but don't run yet EXEC_APPEND = 2, // add to end of the command buffer PRINT_ALL = 0, PRINT_DEVELOPER = 1, // only print when "developer 1" NUMVERTEXNORMALS = 162, /* thread groups */ THin = 1, THsnd = 2, THnet = 3 }; extern FILE *log_stats_file; /* host_speeds times */ extern int time_before_game; extern int time_after_game; extern int time_before_ref; extern int time_after_ref; extern vec3_t bytedirs[NUMVERTEXNORMALS]; extern uint sys_frame_time; #pragma pack on /* .pak files are just a linear collapse of a directory tree */ enum{ IDPAKHEADER = ('K'<<24)+('C'<<16)+('A'<<8)+'P', MAX_FILES_IN_PACK = 4096 }; struct dpackfile_t{ char name[56]; int filepos; int filelen; }; struct dpackheader_t{ int ident; // == IDPAKHEADER int dirofs; int dirlen; }; /* PCX images */ struct pcx_t{ char manufacturer; char version; char encoding; char bits_per_pixel; ushort xmin; ushort ymin; ushort xmax; ushort ymax; ushort hres; ushort vres; uchar palette[48]; char reserved; char color_planes; ushort bytes_per_line; ushort palette_type; char filler[58]; uchar data; // unbounded }; /* .md2 triangle model file format */ enum{ IDALIASHEADER = ('2'<<24)+('P'<<16)+('D'<<8)+'I', ALIAS_VERSION = 8, MAX_TRIANGLES = 4096, MAX_VERTS = 2048, MAX_FRAMES = 512, MAX_MD2SKINS = 32, MAX_SKINNAME = 64 }; struct dstvert_t{ short s; short t; }; struct dtriangle_t{ short index_xyz[3]; short index_st[3]; }; struct dtrivertx_t{ uchar v[3]; // scaled byte to fit in frame mins/maxs uchar lightnormalindex; }; struct daliasframe_t{ float scale[3]; // multiply byte verts by this float translate[3]; // then add this char name[16]; // frame name from grabbing dtrivertx_t verts[1]; // variable sized }; /* glcmd format * a positive integer starts a tristrip command, followed by that many vertex * structures. a negative integer starts a trifan command, followed by -x * vertexes a zero indicates the end of the command list. a vertex consists of * a floating point s, a floating point t, and an integer vertex index. */ struct dmdl_t{ int ident; int version; int skinwidth; int skinheight; int framesize; // byte size of each frame int num_skins; int num_xyz; int num_st; // greater than num_xyz for seams int num_tris; int num_glcmds; // dwords in strip/fan command lis int num_frames; int ofs_skins; // each skin is a MAX_SKINNAME string int ofs_st; // byte offset from start for stverts int ofs_tris; // offset for dtriangles int ofs_frames; // offset for first frame int ofs_glcmds; int ofs_end; // end of file }; /* .sp2 sprite file format */ enum{ IDSPRITEHEADER = ('2'<<24)+('S'<<16)+('D'<<8)+'I', SPRITE_VERSION = 2 }; struct dsprframe_t{ int width; int height; int origin_x; int origin_y; // raster coordinates inside pic char name[MAX_SKINNAME]; // name of pcx file }; struct dsprite_t{ int ident; int version; int numframes; dsprframe_t frames[1]; // variable sized }; /* .wal texture file format */ enum{ MIPLEVELS = 4 }; struct miptex_t{ char name[32]; uint width; uint height; uint offsets[MIPLEVELS]; // four mip maps stored char animname[32]; // next frame in animation chain int flags; int contents; int value; }; /* .bsp file format */ enum{ IDBSPHEADER = ('P'<<24)+('S'<<16)+('B'<<8)+'I', BSPVERSION = 38, /* upper design bounds; leaffaces, leafbrushes, planes, and verts are * still bounded by 16 bit short limits */ MAX_MAP_MODELS = 1024, MAX_MAP_BRUSHES = 8192, MAX_MAP_ENTITIES = 2048, MAX_MAP_ENTSTRING = 0x40000, MAX_MAP_TEXINFO = 8192, MAX_MAP_AREAS = 256, MAX_MAP_AREAPORTALS = 1024, MAX_MAP_PLANES = 65536, MAX_MAP_NODES = 65536, MAX_MAP_BRUSHSIDES = 65536, MAX_MAP_LEAFS = 65536, MAX_MAP_VERTS = 65536, MAX_MAP_FACES = 65536, MAX_MAP_LEAFFACES = 65536, MAX_MAP_LEAFBRUSHES = 65536, MAX_MAP_PORTALS = 65536, MAX_MAP_EDGES = 128000, MAX_MAP_SURFEDGES = 256000, MAX_MAP_LIGHTING = 0x200000, MAX_MAP_VISIBILITY = 0x100000, /* key / value pair sizes */ MAX_KEY = 32, MAX_VALUE = 1024, LUMP_ENTITIES = 0, LUMP_PLANES = 1, LUMP_VERTEXES = 2, LUMP_VISIBILITY = 3, LUMP_NODES = 4, LUMP_TEXINFO = 5, LUMP_FACES = 6, LUMP_LIGHTING = 7, LUMP_LEAFS = 8, LUMP_LEAFFACES = 9, LUMP_LEAFBRUSHES = 10, LUMP_EDGES = 11, LUMP_SURFEDGES = 12, LUMP_MODELS = 13, LUMP_BRUSHES = 14, LUMP_BRUSHSIDES = 15, LUMP_POP = 16, LUMP_AREAS = 17, LUMP_AREAPORTALS = 18, HEADER_LUMPS = 19, /* 0-2 are axial planes */ PLANE_X = 0, PLANE_Y = 1, PLANE_Z = 2, /* 3-5 are non-axial planes snapped to the nearest */ PLANE_ANYX = 3, PLANE_ANYY = 4, PLANE_ANYZ = 5 /* planes (x&~1) and (x&~1)+1 are always opposites */ }; struct lump_t{ int fileofs; int filelen; }; struct dheader_t{ int ident; int version; lump_t lumps[HEADER_LUMPS]; }; struct dmodel_t{ float mins[3]; float maxs[3]; float origin[3]; // for sounds or lights int headnode; int firstface; /* submodels just draw faces without walking the bsp tree */ int numfaces; }; struct dvertex_t{ float point[3]; }; struct dplane_t{ float normal[3]; float dist; int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate }; struct dnode_t{ int planenum; int children[2]; // negative numbers are -(leafs+1), not nodes short mins[3]; // for frustom culling short maxs[3]; ushort firstface; ushort numfaces; // counting both sides }; struct texinfo_t{ float vecs[2][4]; // [s/t][xyz offset] int flags; // miptex flags + overrides int value; // light emission, etc char texture[32]; // texture name (textures/*.wal) int nexttexinfo; // for animations, -1 = end of chain }; enum{ MAXLIGHTMAPS = 4, ANGLE_UP = -1, ANGLE_DOWN = -2 }; /* note that edge 0 is never used, because negative edge nums are used for * counterclockwise use of the edge in a face */ struct dedge_t{ ushort v[2]; // vertex numbers }; struct dface_t{ ushort planenum; short side; int firstedge; // we must support > 64k edges short numedges; short texinfo; /* lighting info */ uchar styles[MAXLIGHTMAPS]; int lightofs; // start of [numstyles*surfsize] samples }; struct dleaf_t{ int contents; // OR of all brushes (not needed?) short cluster; short area; short mins[3]; // for frustum culling short maxs[3]; ushort firstleafface; ushort numleaffaces; ushort firstleafbrush; ushort numleafbrushes; }; struct dbrushside_t{ ushort planenum; // facing out of the leaf short texinfo; }; struct dbrush_t{ int firstside; int numsides; int contents; }; /* the visibility lump consists of a header with a count, then byte offsets for * the PVS and PHS of each cluster, then the raw compressed bit vectors */ enum{ DVIS_PVS = 0, DVIS_PHS = 1 }; struct dvis_t{ int numclusters; int bitofs[8][2]; // bitofs[numclusters][2] }; /* each area has a list of portals that lead into other areas; when portals are * closed, other areas may not be visible or hearable even if the vis info says * that it should be */ struct dareaportal_t{ int portalnum; int otherarea; }; struct darea_t{ int numareaportals; int firstareaportal; }; #pragma pack off struct vrect_t{ int x; int y; int width; int height; vrect_t *pnext; }; struct viddef_t{ int width; int height; pixel_t *buffer; // invisible buffer pixel_t *colormap; // 256 * VID_GRADES size pixel_t *alphamap; // 256 * 256 translucency map int rowbytes; // may be > width if displayed in a window or <0 for stupid dibs }; extern viddef_t vid; #define REF_VERSION "SOFT 0.01" /* skins are outline flood filled and mip mapped; pics and sprites with alpha * will be outline flood filled pic won't be mip mapped */ extern cvar_t *sw_aliasstats; extern cvar_t *sw_clearcolor; extern cvar_t *sw_drawflat; extern cvar_t *sw_draworder; extern cvar_t *sw_maxedges; extern cvar_t *sw_maxsurfs; extern cvar_t *sw_mipcap; extern cvar_t *sw_mipscale; extern cvar_t *sw_mode; extern cvar_t *sw_reportsurfout; extern cvar_t *sw_reportedgeout; extern cvar_t *sw_stipplealpha; extern cvar_t *sw_surfcacheoverride; extern cvar_t *sw_waterwarp; extern cvar_t *r_fullbright; extern cvar_t *r_lefthand; extern cvar_t *r_drawentities; extern cvar_t *r_drawworld; extern cvar_t *r_dspeeds; extern cvar_t *r_lerpmodels; extern cvar_t *r_speeds; extern cvar_t *r_lightlevel; //FIXME HACK typedef enum imagetype_t{ it_skin, it_sprite, it_wall, it_pic, it_sky }imagetype_t; struct image_t{ char name[MAX_QPATH]; // game path, including extension imagetype_t type; int width; int height; qboolean transparent; // true if any 255 pixels in image int registration_sequence; // 0 = free uchar *pixels[4]; // mip levels }; typedef enum rserr_t{ rserr_ok, rserr_invalid_fullscreen, rserr_invalid_mode, rserr_unknown }rserr_t; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct oldrefdef_t{ vrect_t vrect; // subwindow in video for refresh // FIXME: not need vrect next field here? vrect_t aliasvrect; // scaled Alias version int vrectright; int vrectbottom; // right & bottom screen coords int aliasvrectright; int aliasvrectbottom; // scaled Alias versions /* rightmost right edge we care about, for use in edge list */ float vrectrightedge; float fvrectx; float fvrecty; // for floating-point compares float fvrectx_adj; float fvrecty_adj; // left and top edges, for clamping int vrect_x_adj_shift20; // vrect.x+0.5-epsilon << 20 int vrectright_adj_shift20; // vrectright+0.5-epsilon << 20 float fvrectright_adj; float fvrectbottom_adj; /* right and bottom edges, for clamping */ float fvrectright; // rightmost edge, for Alias clamping float fvrectbottom; // bottommost edge, for Alias clamping /* at Z = 1.0, this many X is visible; 2.0 = 90 degrees */ float horizontalFieldOfView; float xOrigin; // should probably always be 0.5 float yOrigin; // between be around 0.3 to 0.5 vec3_t vieworg; vec3_t viewangles; int ambientlight; }; extern oldrefdef_t r_refdef; /* d*_t structures are on-disk representations; m*_t structures are in-memory */ enum{ SIDE_FRONT = 0, SIDE_BACK = 1, SIDE_ON = 2, // FIXME: differentiate from texinfo SURF_ flags SURF_PLANEBACK = 1<<1, SURF_DRAWSKY = 1<<2, // sky brush face SURF_DRAWTURB = 1<<4, SURF_DRAWBACKGROUND = 1<<6, SURF_DRAWSKYBOX = 1<<7, // sky box SURF_FLOW = 1<<8, CONTENTS_NODE = -1 }; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct mvertex_t{ vec3_t position; }; /* !!! if this is changed, it must be changed in asm_i386.h too !!! */ struct mplane_t{ vec3_t normal; float dist; uchar type; // for texture axis selection and fast side tests uchar signbits; // signx + signy<<1 + signz<<1 uchar pad[2]; }; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct medge_t{ ushort v[2]; uint cachededgeoffset; }; struct mtexinfo_t{ float vecs[2][4]; float mipadjust; image_t *image; int flags; int numframes; mtexinfo_t *next; // animation chain }; struct msurface_t{ int visframe; // should be drawn when node is crossed int dlightframe; int dlightbits; mplane_t *plane; int flags; int firstedge; // look up in model->surfedges[], negative numbers int numedges; // are backwards edges /* surface generation data */ surfcache_t *cachespots[MIPLEVELS]; short texturemins[2]; short extents[2]; mtexinfo_t *texinfo; /* lighting info */ uchar styles[MAXLIGHTMAPS]; uchar *samples; // [numstyles*surfsize] msurface_t *nextalphasurface; }; struct mnode_t{ /* common with leaf */ int contents; // CONTENTS_NODE, to differentiate from leafs int visframe; // node needs to be traversed if current short minmaxs[6]; // for bounding box culling mnode_t *parent; /* node specific */ mplane_t *plane; mnode_t *children[2]; ushort firstsurface; ushort numsurfaces; }; struct mleaf_t{ /* common with node */ int contents; // wil be something other than CONTENTS_NODE int visframe; // node needs to be traversed if current short minmaxs[6]; // for bounding box culling mnode_t *parent; /* leaf specific */ int cluster; int area; msurface_t **firstmarksurface; int nummarksurfaces; int key; // BSP sequence number for leaf's contents }; typedef enum modtype_t{ mod_bad, mod_brush, mod_sprite, mod_alias }modtype_t; struct model_t{ char name[MAX_QPATH]; int registration_sequence; modtype_t type; int numframes; int flags; /* volume occupied by the model graphics */ vec3_t mins; vec3_t maxs; /* solid volume for clipping (sent from server) */ qboolean clipbox; vec3_t clipmins; vec3_t clipmaxs; /* brush model */ int firstmodelsurface; int nummodelsurfaces; int numsubmodels; dmodel_t *submodels; int numplanes; mplane_t *planes; int numleafs; // number of visible leafs, not counting 0 mleaf_t *leafs; int numvertexes; mvertex_t *vertexes; int numedges; medge_t *edges; int numnodes; int firstnode; mnode_t *nodes; int numtexinfo; mtexinfo_t *texinfo; int numsurfaces; msurface_t *surfaces; int numsurfedges; int *surfedges; int nummarksurfaces; msurface_t **marksurfaces; dvis_t *vis; uchar *lightdata; /* for alias models and sprites */ image_t *skins[MAX_MD2SKINS]; void *extradata; int extradatasize; }; extern int registration_sequence; #define PARTICLE_Z_CLIP 8.0 #define XCENTERING (1.0 / 2.0) #define YCENTERING (1.0 / 2.0) #define CLIP_EPSILON 0.001 #define BACKFACE_EPSILON 0.01 /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ #define NEAR_CLIP 0.01 enum{ CACHE_SIZE = 32, VID_CBITS = 6, VID_GRADES = 1<<VID_CBITS, MAXVERTS = 64, // max points in a surface polygon /* max points in an intermediate polygon (while processing) */ MAXWORKINGVERTS = MAXVERTS+4, /* !!! if this is changed, it must be changed in d_ifacea.h too !!! */ MAXHEIGHT = 4096, MAXWIDTH = 4096, /* distance that's always guaranteed to be farther away than anything * in the scene */ INFINITE_DISTANCE = 0x10000, WARP_WIDTH = 320, WARP_HEIGHT = 240, MAX_LBM_HEIGHT = 480, /* !!! must be kept the same as in quakeasm.h !!! */ TRANSPARENT_COLOR = 0xff, /* !!! if this is changed, it must be changed in d_ifacea.h too !!! */ TURB_TEX_SIZE = 64, // base turbulent texture size /* !!! if this is changed, it must be changed in d_ifacea.h too !!! */ CYCLE = 128, // turbulent cycle size SCANBUFFERPAD = 0x1000, DS_SPAN_LIST_END = -128, NUMSTACKEDGES = 2000, MINEDGES = NUMSTACKEDGES, NUMSTACKSURFACES = 1000, MINSURFACES = NUMSTACKSURFACES, MAXSPANS = 3000, /* finalvert_t.flags */ ALIAS_LEFT_CLIP = 1<<0, ALIAS_TOP_CLIP = 1<<1, ALIAS_RIGHT_CLIP = 1<<2, ALIAS_BOTTOM_CLIP = 1<<3, ALIAS_Z_CLIP = 1<<4, ALIAS_XY_CLIP_MASK = 0xf, SURFCACHE_SIZE_AT_320X240 = 1024*768, /* value returned by R_BmodelCheckBBox() if bbox is trivially rejected */ BMODEL_FULLY_CLIPPED = 1<<4, MAXALIASVERTS = 2000, // TODO: tune this ALIAS_Z_CLIP_PLANE = 4, /* turbulence stuff */ AMP = 0x80000, AMP2 = 3, SPEED = 20 }; struct emitpoint_t{ float u; float v; float s; float t; float zi; }; /* asm: if you modidify finalvert_t's definition, make sure to change the * associated offsets too! */ #ifdef SMALL_FINALVERT struct finalvert_t{ short u; short v; short s; short t; int l; int zi; int flags; float xyz[3]; // eye space }; #else // !SMALL_FINALVERT struct finalvert_t{ int u; int v; int s; int t; int l; int zi; int flags; float xyz[3]; // eye space }; #endif // SMALL_FINALVERT struct affinetridesc_t{ void *pskin; int pskindesc; int skinwidth; int skinheight; dtriangle_t *ptriangles; finalvert_t *pfinalverts; int numtriangles; int drawtype; int seamfixupX16; qboolean do_vis_thresh; int vis_thresh; }; extern affinetridesc_t r_affinetridesc; struct drawsurf_t{ uchar *surfdat; // destination for generated surface int rowbytes; // destination logical width in bytes msurface_t *surf; // description for surface to generate /* adjust for lightmap levels for dynamic lighting */ fixed8_t lightadj[MAXLIGHTMAPS]; image_t *image; int surfmip; // mipmapped ratio of surface texels / world pixels int surfwidth; // in mipmapped texels int surfheight; // in mipmapped texels }; extern drawsurf_t r_drawsurf; struct alight_t{ int ambientlight; int shadelight; float *plightvec; }; /* clipped bmodel edges */ struct bedge_t{ mvertex_t *v[2]; bedge_t *pnext; }; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct clipplane_t{ vec3_t normal; float dist; clipplane_t *next; uchar leftedge; uchar rightedge; uchar reserved[2]; }; struct surfcache_t{ surfcache_t *next; surfcache_t **owner; // nil is an empty chunk of memory int lightadj[MAXLIGHTMAPS]; // checked for strobe flush int dlight; int size; // including header uint width; uint height; // DEBUG only needed for debug float mipscale; image_t *image; uchar data[4]; // width*height elements }; extern surfcache_t *sc_rover; extern surfcache_t *d_initial_rover; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct espan_t{ int u; int v; int count; espan_t *pnext; }; /* used by the polygon drawer (R_POLY.C) and sprite setup code (R_SPRITE.C) */ struct polydesc_t{ int nump; emitpoint_t *pverts; uchar *pixels; // image int pixel_width; // image width int pixel_height; // image height vec3_t vup; vec3_t vright; vec3_t vpn; // in worldspace, for plane eq float dist; float s_offset; float t_offset; float viewer_position[3]; void (*drawspanlet)(void); int stipple_parity; }; // FIXME: compress, make a union if that will help // insubmodel is only 1, flags is fewer than 32, spanstate could be a byte struct surf_t{ surf_t *next; // active surface stack in r_edge.c surf_t *prev; // used in r_edge.c for active surf stack espan_t *spans; // pointer to linked list of spans to draw int key; // sorting key (BSP order) int last_u; // set during tracing int spanstate; // 0 = not in span; 1 = in span; -1 in inverted span (end before start) int flags; // currentface flags msurface_t *msurf; entity_t *entity; float nearzi; // nearest 1/z on surface, for mipmapping qboolean insubmodel; float d_ziorigin; float d_zistepu; float d_zistepv; int pad[2]; // to 64 bytes }; /* !!! if this is changed, it must be changed in asm_draw.h too !!! */ struct edge_t{ fixed16_t u; fixed16_t u_step; edge_t *prev; edge_t *next; ushort surfs[2]; edge_t *nextremove; float nearzi; medge_t *owner; }; struct aliastriangleparms_t{ finalvert_t *a; finalvert_t *b; finalvert_t *c; }; extern aliastriangleparms_t aliastriangleparms; struct swstate_t{ qboolean fullscreen; int prev_mode; // last valid SW mode uchar gammatable[256]; uchar currentpalette[1024]; }; extern swstate_t sw_state; extern int d_spanpixcount; extern int r_framecount; // sequence # of current frame since quake started /* scale-up factor for screen u and v on Alias vertices passed to driver */ extern float r_aliasuvscale; extern qboolean r_dowarp; extern vec3_t r_pright; extern vec3_t r_pup; extern vec3_t r_ppn; extern void *acolormap; // FIXME: should go away extern int c_surf; extern uchar r_warpbuffer[WARP_WIDTH*WARP_HEIGHT]; extern float scale_for_mip; extern qboolean d_roverwrapped; extern float d_sdivzstepu; extern float d_tdivzstepu; extern float d_zistepu; extern float d_sdivzstepv; extern float d_tdivzstepv; extern float d_zistepv; extern float d_sdivzorigin; extern float d_tdivzorigin; extern float d_ziorigin; extern fixed16_t sadjust; extern fixed16_t tadjust; extern fixed16_t bbextents; extern fixed16_t bbextentt; extern int d_vrectx; extern int d_vrecty; extern int d_vrectright_particle; extern int d_vrectbottom_particle; extern int d_pix_min; extern int d_pix_max; extern int d_pix_shift; extern pixel_t *d_viewbuffer; extern short *d_pzbuffer; extern uint d_zrowbytes; extern uint d_zwidth; extern short *zspantable[MAXHEIGHT]; extern int d_scantable[MAXHEIGHT]; extern int d_minmip; extern float d_scalemip[3]; /* surfaces are generated in back to front order by the bsp, so if a surf * pointer is greater than another one, it should be drawn in front. * surfaces[1] is the background, and is used as the active surface stack. * surfaces[0] is a dummy, because index 0 is used to indicate no surface * attached to an edge_t */ extern int cachewidth; extern pixel_t *cacheblock; extern int r_screenwidth; extern int r_drawnpolycount; extern int sintable[1280]; extern int intsintable[1280]; extern int blanktable[1280]; extern vec3_t vup; extern vec3_t base_vup; extern vec3_t vpn; extern vec3_t base_vpn; extern vec3_t vright; extern vec3_t base_vright; extern surf_t *surfaces; extern surf_t *surface_p; extern surf_t *surf_max; extern vec3_t sxformaxis[4]; // s axis transformed into viewspace extern vec3_t txformaxis[4]; // t axis transformed into viewspac extern float xcenter; extern float ycenter; extern float xscale; extern float yscale; extern float xscaleinv; extern float yscaleinv; extern float xscaleshrink; extern float yscaleshrink; extern int ubasestep; extern int errorterm; extern int erroradjustup; extern int erroradjustdown; extern clipplane_t view_clipplanes[4]; extern int *pfrustum_indexes[4]; extern mplane_t screenedge[4]; extern vec3_t r_origin; extern entity_t r_worldentity; extern model_t *currentmodel; extern entity_t *currententity; extern vec3_t modelorg; extern vec3_t r_entorigin; extern float verticalFieldOfView; extern float xOrigin; extern float yOrigin; extern int r_visframecount; extern msurface_t *r_alpha_surfaces; extern qboolean insubmodel; extern int c_faceclip; extern int r_polycount; extern int r_wholepolycount; extern int ubasestep; extern int errorterm; extern int erroradjustup; extern int erroradjustdown; extern fixed16_t sadjust; extern fixed16_t tadjust; extern fixed16_t bbextents; extern fixed16_t bbextentt; extern mvertex_t *r_ptverts; extern mvertex_t *r_ptvertsmax; extern float entity_rotation[3][3]; extern int r_currentkey; extern int r_currentbkey; extern int r_amodels_drawn; extern edge_t *auxedges; extern int r_numallocatededges; extern edge_t *r_edges; extern edge_t *edge_p; extern edge_t *edge_max; extern edge_t *newedges[MAXHEIGHT]; extern edge_t *removeedges[MAXHEIGHT]; extern edge_t edge_head; // FIXME: make stack vars when debugging done extern edge_t edge_tail; extern edge_t edge_aftertail; extern int r_aliasblendcolor; extern float aliasxscale; extern float aliasyscale; extern float aliasxcenter; extern float aliasycenter; extern int r_outofsurfaces; extern int r_outofedges; extern mvertex_t *r_pcurrentvertbase; extern int r_maxvalidedgeoffset; extern float r_time1; extern float da_time1; extern float da_time2; extern float dp_time1; extern float dp_time2; extern float db_time1; extern float db_time2; extern float rw_time1; extern float rw_time2; extern float se_time1; extern float se_time2; extern float de_time1; extern float de_time2; extern float dv_time1; extern float dv_time2; extern int r_frustum_indexes[4*6]; extern int r_maxsurfsseen; extern int r_maxedgesseen; extern int r_cnumsurfs; extern qboolean r_surfsonstack; extern mleaf_t *r_viewleaf; extern int r_viewcluster; extern int r_oldviewcluster; extern int r_clipflags; extern int r_dlightframecount; extern qboolean r_fov_greater_than_90; extern image_t *r_notexture_mip; extern model_t *r_worldmodel; extern refdef_t r_newrefdef; extern surfcache_t *sc_rover; extern surfcache_t *sc_base; extern void *colormap; extern unsigned d_8to24table[256]; // base extern mtexinfo_t *sky_texinfo[6]; extern cvar_t *vid_fullscreen; extern cvar_t *vid_gamma; extern cvar_t *scr_viewsize; extern cvar_t *crosshair; #define POWERSUIT_SCALE 4.0F enum{ API_VERSION = 3, MAX_DLIGHTS = 32, MAX_ENTITIES = 128, MAX_PARTICLES = 4096, SHELL_RED_COLOR = 0xf2, SHELL_GREEN_COLOR = 0xd0, SHELL_BLUE_COLOR = 0xf3, SHELL_RG_COLOR = 0xdc, SHELL_RB_COLOR = 0x68, SHELL_BG_COLOR = 0x78, SHELL_WHITE_COLOR = 0xd7, /* ROGUE */ SHELL_DOUBLE_COLOR = 0xdf, SHELL_HALF_DAM_COLOR = 0x90, SHELL_CYAN_COLOR = 0x72, ENTITY_FLAGS = 68 }; struct entity_t{ model_t *model; // opaque type outside refresh float angles[3]; /* most recent data */ float origin[3]; // also used as RF_BEAM's "from" int frame; // also used as RF_BEAM's diameter /* previous data for lerping */ float oldorigin[3]; // also used as RF_BEAM's "to" int oldframe; float backlerp; // 0.0 = current, 1.0 = old int skinnum; // also used as RF_BEAM's palette index int lightstyle; // for flashing entities float alpha; // ignore if RF_TRANSLUCENT isn't set image_t *skin; // nil for inline skin int flags; }; struct dlight_t{ vec3_t origin; vec3_t color; float intensity; }; struct particle_t{ vec3_t origin; int color; float alpha; }; struct lightstyle_t{ float rgb[3]; // 0.0 - 2.0 float white; // highest of rgb }; struct refdef_t{ int x; // in virtual screen coordinates int y; int width; int height; float fov_x; float fov_y; float vieworg[3]; float viewangles[3]; float blend[4]; // rgba 0-1 full screen blend float time; // time is uesed to auto animate int rdflags; // RDF_UNDERWATER, etc uchar *areabits; // if not nil, only areas with set bits will be drawn lightstyle_t *lightstyles; // [MAX_LIGHTSTYLES] int num_entities; entity_t *entities; int num_dlights; dlight_t *dlights; int num_particles; particle_t *particles; }; struct refexport_t{ int api_version; /* All data that will be used in a level should be registered before * rendering any frames to prevent disk hits, but they can still be * registered at a later time if necessary. * EndRegistration will free any remaining data that wasn't registered. * Any model_s or skin_s pointers from before the BeginRegistration are * no longer valid after EndRegistration. * Skins and images need to be differentiated, because skins are flood * filled to eliminate mip map edge errors, and pics have an implicit * "pics/" prepended to the name. (a pic name that starts with a slash * will not use the "pics/" prefix or the ".pcx" postfix) */ qboolean (*Init)(void *, void *); void (*Shutdown)(void); void (*BeginRegistration)(char *); model_t* (*RegisterModel)(char *); image_t* (*RegisterSkin)(char *); image_t* (*RegisterPic)(char *); void (*SetSky)(char *, float, vec3_t); void (*EndRegistration)(void); void (*RenderFrame)(refdef_t *); void (*DrawGetPicSize)(int *, int *, char *); void (*DrawPic)(int, int, char *); void (*DrawStretchPic)(int, int, int, int, char *); void (*DrawChar)(int, int, int); void (*DrawTileClear)(int, int, int, int, char *); void (*DrawFill)(int, int, int, int, int); void (*DrawFadeScreen)(void); void (*DrawStretchRaw)(int, int, int, int, int, int, uchar *); void (*CinematicSetPalette)(uchar *); void (*BeginFrame)(float); void (*EndFrame)(void); void (*AppActivate)(qboolean); }; extern refexport_t re; struct refimport_t{ void (*Sys_Error)(int, char *, ...); void (*Cmd_AddCommand)(char *, void(*)(void)); void (*Cmd_RemoveCommand)(char *); int (*Cmd_Argc)(void); char* (*Cmd_Argv)(int); void (*Cmd_ExecuteText)(int, char *); void (*Con_Printf)(int, char *, ...); /* files will be memory mapped read only; the returned buffer may be * part of a larger pak file, or a discrete file from anywhere in the * quake search path * a -1 return means the file does not exist * nil can be passed for buf to just determine existance */ int (*FS_LoadFile)(char *, void **); void (*FS_FreeFile)(void *); char* (*FS_Gamedir)(void); cvar_t* (*Cvar_Get)(char *, char *, int); cvar_t* (*Cvar_Set)(char *, char *); void (*Cvar_SetValue)(char *, float); qboolean (*Vid_GetModeInfo)(int *, int *, int); void (*Vid_MenuInit)(void); void (*Vid_NewWindow)(int, int); }; extern refimport_t ri; extern float scr_con_current; extern float scr_conlines; // lines of console to display extern int sb_lines; extern vrect_t scr_vrect; // position of render window extern char crosshair_pic[MAX_QPATH]; extern int crosshair_width; extern int crosshair_height; extern cvar_t *s_volume; extern cvar_t *s_loadas8bit; extern cvar_t *s_khz; extern cvar_t *s_mixahead; extern int soundtime; extern int sound_started, num_sfx; extern sfx_t known_sfx[]; enum{ Nsamp = 4096, Sampsz = 2, Rate = 44100, Nsbuf = Sampsz * Nsamp, MAX_CHANNELS = 32, MAX_RAW_SAMPLES = 8192 }; /* !!! if this is changed, the asm code must change !!! */ struct portable_samplepair_t{ int left; int right; }; extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES]; struct sfxcache_t{ int length; int loopstart; int speed; // not needed, because converted on load? int width; int stereo; uchar data[1]; // variable sized }; struct sfx_t{ char name[MAX_QPATH]; int registration_sequence; sfxcache_t *cache; char *truename; }; /* a playsound_t will be generated by each call to S_StartSound, when the mixer * reaches playsound->begin, the playsound will be assigned to a channel */ struct playsound_t{ playsound_t *prev; playsound_t *next; sfx_t *sfx; float volume; float attenuation; int entnum; int entchannel; qboolean fixed_origin; // use origin field instead of entnum's origin vec3_t origin; uint begin; // begin on this sample }; extern playsound_t s_pendingplays; struct dma_t{ int channels; int samples; // mono samples in buffer int submission_chunk; // don't mix less than this # int samplepos; // in mono samples int samplebits; int speed; uchar *buffer; }; extern dma_t dma; /* !!! if this is changed, the asm code must change !!! */ struct channel_t{ sfx_t *sfx; // sfx number int leftvol; // 0-255 volume int rightvol; // 0-255 volume int end; // end time in global paintsamples int pos; // sample position in sfx int looping; // where to loop, -1 = no looping OBSOLETE? int entnum; // to allow overriding a specific sound int entchannel; vec3_t origin; // only use if fixed_origin is set vec_t dist_mult; // distance multiplier (attenuation/clipK) int master_vol; // 0-255 master volume qboolean fixed_origin; // use origin instead of fetching entnum's origin qboolean autosound; // from an entity->sound, cleared each frame }; extern channel_t channels[MAX_CHANNELS]; struct wavinfo_t{ int rate; int width; int channels; int loopstart; int samples; int dataofs; // chunk starts this many bytes from file start }; extern int paintedtime; extern int s_rawend; extern vec3_t listener_origin; extern vec3_t listener_forward; extern vec3_t listener_right; extern vec3_t listener_up; extern cvar_t *in_joystick; extern cvar_t *lookspring; extern cvar_t *lookstrafe; extern cvar_t *sensitivity; extern cvar_t *freelook; extern cvar_t *m_pitch; /* key numbers passed to Key_Event() */ enum{ K_TAB = 9, K_ENTER = 13, K_ESCAPE = 27, K_SPACE = 32, /* normal keys should be passed as lowercased ascii */ K_BACKSPACE = 127, K_UPARROW = 128, K_DOWNARROW = 129, K_LEFTARROW = 130, K_RIGHTARROW = 131, K_ALT = 132, K_CTRL = 133, K_SHIFT = 134, K_F1 = 135, K_F2 = 136, K_F3 = 137, K_F4 = 138, K_F5 = 139, K_F6 = 140, K_F7 = 141, K_F8 = 142, K_F9 = 143, K_F10 = 144, K_F11 = 145, K_F12 = 146, K_INS = 147, K_DEL = 148, K_PGDN = 149, K_PGUP = 150, K_HOME = 151, K_END = 152, K_KP_HOME = 160, K_KP_UPARROW = 161, K_KP_PGUP = 162, K_KP_LEFTARROW = 163, K_KP_5 = 164, K_KP_RIGHTARROW = 165, K_KP_END = 166, K_KP_DOWNARROW = 167, K_KP_PGDN = 168, K_KP_ENTER = 169, K_KP_INS = 170, K_KP_DEL = 171, K_KP_SLASH = 172, K_KP_MINUS = 173, K_KP_PLUS = 174, /* mouse buttons generate virtual keys */ K_MOUSE1 = 200, K_MOUSE3 = 201, K_MOUSE2 = 202, K_MWHEELUP = 203, K_MWHEELDOWN = 204, /* joystick buttons */ K_JOY1 = 205, K_JOY2 = 206, K_JOY3 = 207, K_JOY4 = 208, /* aux keys are for multi-buttoned joysticks to generate so they can * use the normal binding process */ K_AUX1 = 209, K_AUX2 = 210, K_AUX3 = 211, K_AUX4 = 212, K_AUX5 = 213, K_AUX6 = 214, K_AUX7 = 215, K_AUX8 = 216, K_AUX9 = 217, K_AUX10 = 218, K_AUX11 = 219, K_AUX12 = 220, K_AUX13 = 221, K_AUX14 = 222, K_AUX15 = 223, K_AUX16 = 224, K_AUX17 = 225, K_AUX18 = 226, K_AUX19 = 227, K_AUX20 = 228, K_AUX21 = 229, K_AUX22 = 230, K_AUX23 = 231, K_AUX24 = 232, K_AUX25 = 233, K_AUX26 = 234, K_AUX27 = 235, K_AUX28 = 236, K_AUX29 = 237, K_AUX30 = 238, K_AUX31 = 239, K_AUX32 = 240, K_PAUSE = 255 }; extern char *keybindings[256]; extern int key_repeats[256]; extern int anykeydown; extern char chat_buffer[]; extern int chat_bufferlen; extern qboolean chat_team; enum{ NUM_CON_TIMES = 4, CON_TEXTSIZE = 32768 }; struct console_t{ qboolean initialized; char text[CON_TEXTSIZE]; int current; // line where next message will be printed int x; // offset in current line for next print int display; // bottom of console displays this line int ormask; // high bit mask for colored characters int linewidth; // characters across screen int totallines; // total lines in console scrollback float cursorspeed; int vislines; /* cls.realtime time the line was generated for transparent notify lines */ float times[NUM_CON_TIMES]; }; extern console_t con; extern cvar_t *cl_stereo_separation; extern cvar_t *cl_stereo; extern cvar_t *cl_gun; extern cvar_t *cl_add_blend; extern cvar_t *cl_add_lights; extern cvar_t *cl_add_particles; extern cvar_t *cl_add_entities; extern cvar_t *cl_predict; extern cvar_t *cl_footsteps; extern cvar_t *cl_noskins; extern cvar_t *cl_autoskins; extern cvar_t *cl_upspeed; extern cvar_t *cl_forwardspeed; extern cvar_t *cl_sidespeed; extern cvar_t *cl_yawspeed; extern cvar_t *cl_pitchspeed; extern cvar_t *cl_run; extern cvar_t *cl_anglespeedkey; extern cvar_t *cl_shownet; extern cvar_t *cl_showmiss; extern cvar_t *cl_showclamp; extern cvar_t *cl_lightlevel; // FIXME HACK extern cvar_t *cl_paused; extern cvar_t *cl_timedemo; extern cvar_t *cl_vwep; struct frame_t{ qboolean valid; // cleared if delta parsing was invalid int serverframe; int servertime; // server time the message is valid for (in msec) int deltaframe; uchar areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits player_state_t playerstate; int num_entities; int parse_entities; // non-masked index into cl_parse_entities array }; struct centity_t{ entity_state_t baseline; // delta from this if not from a previous frame entity_state_t current; entity_state_t prev; // will always be valid, but can be just a copy of current int serverframe; // if not current, this ent isn't in the frame int trailcount; // for diminishing grenade trails vec3_t lerp_origin; // for trails (variable hz) int fly_stoptime; }; extern centity_t cl_entities[MAX_EDICTS]; enum{ MAX_CLIENTWEAPONMODELS = 20 }; struct clientinfo_t{ char name[MAX_QPATH]; char cinfo[MAX_QPATH]; image_t *skin; image_t *icon; char iconname[MAX_QPATH]; model_t *model; model_t *weaponmodel[MAX_CLIENTWEAPONMODELS]; }; extern char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH]; extern int num_cl_weaponmodels; enum{ CMD_BACKUP = 64 // allow a lot of command backups for very fast systems }; /* client_state_t is wiped completely at every server map change */ struct client_state_t{ int timeoutcount; int timedemo_frames; int timedemo_start; qboolean refresh_prepped; // false if on new level or new ref dll qboolean sound_prepped; // ambient sounds can start qboolean force_refdef; // vid has changed, so we can't use a paused refdef int parse_entities; // index (not anded off) into cl_parse_entities[] usercmd_t cmd; usercmd_t cmds[CMD_BACKUP]; // each mesage will send several old cmds int cmd_time[CMD_BACKUP]; // time sent, for calculating pings short predicted_origins[CMD_BACKUP][3]; // for debug comparing against server float predicted_step; // for stair up smoothing uint predicted_step_time; vec3_t predicted_origin; // generated by CL_PredictMovement vec3_t predicted_angles; vec3_t prediction_error; frame_t frame; // received from server int surpressCount; // number of messages rate supressed frame_t frames[UPDATE_BACKUP]; /* the client maintains its own idea of view angles, which are sent to * the server each frame. it is cleared to 0 upon entering each level. * the server sends a delta each frame which is added to the locally * tracked view angles to account for standing on rotating objects, and * teleport direction changes. */ vec3_t viewangles; /* time that the client is rendering at. always <= cls.realtime */ int time; // this is the time value that the client float lerpfrac; // between oldframe and frame refdef_t refdef; vec3_t v_forward; vec3_t v_right; vec3_t v_up; // set when refdef.angles is set /* transient data from server */ char layout[1024]; // general 2D overlay int inventory[MAX_ITEMS]; // FIXME: move this cinematic stuff into the cin_t structure /* non-gameserver infornamtion */ FILE *cinematic_file; int cinematictime; // cls.realtime for first cinematic frame int cinematicframe; char cinematicpalette[768]; qboolean cinematicpalette_active; /* server state information */ qboolean attractloop; // running the attract loop, any key will menu int servercount; // server identification for prespawns char gamedir[MAX_QPATH]; int playernum; char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]; /* locally derived information from server state */ model_t *model_draw[MAX_MODELS]; cmodel_t *model_clip[MAX_MODELS]; sfx_t *sound_precache[MAX_SOUNDS]; image_t *image_precache[MAX_IMAGES]; clientinfo_t clientinfo[MAX_CLIENTS]; clientinfo_t baseclientinfo; }; extern client_state_t cl; typedef enum connstate_t{ ca_uninitialized, ca_disconnected, // not talking to a server ca_connecting, // sending request packets to the server ca_connected, // netchan_t established, waiting for svc_serverdata ca_active // game views should be displayed }connstate_t; typedef enum dltype_t{ dl_none, dl_model, dl_sound, dl_skin, dl_single }dltype_t; typedef enum keydest_t{ key_game, key_console, key_message, key_menu }keydest_t; /* the client_static_t structure is persistant through an arbitrary number of * server connections */ struct client_static_t{ connstate_t state; keydest_t key_dest; int framecount; int realtime; // always increasing, no clamping, etc float frametime; // seconds since last frame /* screen rendering information */ /* showing loading plaque between levels; if time gets >30 sec ahead, * break it */ float disable_screen; /* on receiving a frame and cl.servercount > cls.disable_servercount, * clear disable_screen */ int disable_servercount; /* connection information */ char servername[MAX_OSPATH]; // name of server from original connect float connect_time; // for connection retransmits /* ushort allowing servers to work around address translating routers */ int quakePort; netchan_t netchan; int serverProtocol; // in case we are doing some kind of version hack int challenge; // from the server to use for connecting FILE *download; // file transfer from server char downloadtempname[MAX_OSPATH]; char downloadname[MAX_OSPATH]; int downloadnumber; dltype_t downloadtype; int downloadpercent; /* demo recording info must be here, so it isn't cleared on level change */ qboolean demorecording; qboolean demowaiting; // don't record until a non-delta message is received FILE *demofile; }; extern client_static_t cls; struct cdlight_t{ int key; // so entities can reuse same entry vec3_t color; vec3_t origin; float radius; float die; // stop lighting after this time float decay; // drop this each second float minlight; // don't add when contributing less }; extern cdlight_t cl_dlights[MAX_DLIGHTS]; enum{ MAX_SUSTAINS = 32 }; struct cl_sustain_t{ int id; int type; int endtime; int nextthink; int thinkinterval; vec3_t org; vec3_t dir; int color; int count; int magnitude; void (*think)(cl_sustain_t *); }; #define INSTANT_PARTICLE -10000.0 enum{ PARTICLE_GRAVITY = 40, BLASTER_PARTICLE_COLOR = 0xe0 }; struct cparticle_t{ cparticle_t *next; float time; vec3_t org; vec3_t vel; vec3_t accel; float color; float colorvel; float alpha; float alphavel; }; struct kbutton_t{ int down[2]; // key nums holding it down uint downtime; // msec timestamp uint msec; // msec down this frame int state; }; extern kbutton_t in_mlook; extern kbutton_t in_klook; extern kbutton_t in_strafe; extern kbutton_t in_speed; extern int gun_frame; extern model_t *gun_model; enum{ MAXMENUITEMS = 64, MTYPE_SLIDER = 0, MTYPE_LIST = 1, MTYPE_ACTION = 2, MTYPE_SPINCONTROL = 3, MTYPE_SEPARATOR = 4, MTYPE_FIELD = 5, QMF_LEFT_JUSTIFY = 1<<0, QMF_GRAYED = 1<<1, QMF_NUMBERSONLY = 1<<2, }; struct menuframework_t{ int x; int y; int cursor; int nitems; int nslots; void *items[64]; char *statusbar; void (*cursordraw)(menuframework_t *); }; struct menucommon_t{ int type; char *name; int x; int y; menuframework_t *parent; int cursor_offset; int localdata[4]; uint flags; char *statusbar; void (*callback)(void *); void (*statusbarfunc)(void *); void (*ownerdraw)(void *); void (*cursordraw)(void *); }; struct menufield_t{ menucommon_t generic; char buffer[80]; int cursor; int length; int visible_length; int visible_offset; }; struct menuslider_t{ menucommon_t generic; float minvalue; float maxvalue; float curvalue; float range; }; struct menulist_t{ menucommon_t generic; int curvalue; char **itemnames; }; struct menuaction_t{ menucommon_t generic; }; struct menuseparator_t{ menucommon_t generic; }; extern cvar_t *sv_paused; extern cvar_t *maxclients; /* don't reload level state when reentering */ extern cvar_t *sv_noreload; /* don't reload level state when reentering development tool */ extern cvar_t *sv_airaccelerate; extern cvar_t *sv_enforcetime; typedef enum redirect_t{ RD_NONE, RD_CLIENT, RD_PACKET }redirect_t; typedef enum server_state_t{ ss_dead, // no map loaded ss_loading, // spawning level edicts ss_game, // actively running ss_cinematic, ss_demo, ss_pic }server_state_t; /* some qc commands are only valid before the server has finished initializing * (precache commands, static sounds / objects, etc) */ struct server_t{ server_state_t state; // precache commands are only valid during load qboolean attractloop; // running cinematics and demos for the local system only qboolean loadgame; // client begins should reuse existing entity uint time; // always sv.framenum * 100 msec int framenum; char name[MAX_QPATH]; // map name, or cinematic name cmodel_t *models[MAX_MODELS]; char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH]; entity_state_t baselines[MAX_EDICTS]; /* the multicast buffer is used to send a message to a set of clients * it is only used to marshall data until SV_Multicast is called */ sizebuf_t multicast; uchar multicast_buf[MAX_MSGLEN]; /* demo server information */ FILE *demofile; qboolean timedemo; // don't time sync }; extern server_t sv; // local server #define EDICT_NUM(n) ((edict_t *)((uchar *)ge->edicts + ge->edict_size*(n))) #define NUM_FOR_EDICT(e) ( ((uchar *)(e)-(uchar *)ge->edicts ) / ge->edict_size) struct client_frame_t{ int areabytes; uchar areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits player_state_t ps; int num_entities; int first_entity; // into the circular sv_packet_entities[] int senttime; // for ping calculations }; typedef enum clstate_t{ cs_free, // can be reused for a new connection cs_zombie, // client disconnected, don't reuse connection for a couple secs cs_connected, // has been assigned to a client_t, but not in game yet cs_spawned // client is fully in game }clstate_t; enum{ LATENCY_COUNTS = 16, RATE_MESSAGES = 10 }; struct client_t{ clstate_t state; char userinfo[MAX_INFO_STRING]; // name, etc int lastframe; // for delta compression usercmd_t lastcmd; // for filling in big drops /* every seconds this is reset, if user commands exhaust it, assume * time cheating */ int commandMsec; int frame_latency[LATENCY_COUNTS]; int ping; int message_size[RATE_MESSAGES]; // used to rate drop packets int rate; int surpressCount; // number of messages rate supressed edict_t *edict; // EDICT_NUM(clientnum+1) char name[32]; // extracted from userinfo, high bits masked int messagelevel; // for filtering printed messages /* the datagram is written to by sound calls, prints, temp ents, etc. * it can be harmlessly overflowed. */ sizebuf_t datagram; uchar datagram_buf[MAX_MSGLEN]; client_frame_t frames[UPDATE_BACKUP]; // updates can be delta'd from here uchar *download; // file being downloaded int downloadsize; // total bytes (can't use EOF because of paks) int downloadcount; // bytes sent int lastmessage; // sv.framenum when packet was last received int lastconnect; int challenge; // challenge of this user, randomly generated netchan_t netchan; }; extern client_t *sv_client; /* a client can leave the server in one of four ways: dropping properly by * quiting or disconnecting; timing out if no valid messages are received for * timeout.value seconds; getting kicked off by the server operator; a program * error, like an overflowed reliable buffer */ enum{ /* for preventing denial of service attacks that could cycle all of * them out before legitimate users connected */ MAX_CHALLENGES = 1024, SV_OUTPUTBUF_LENGTH = MAX_MSGLEN - 16 }; struct challenge_t{ netadr_t adr; int challenge; int time; }; struct server_static_t{ qboolean initialized; // sv_init has completed int realtime; // always increasing, no clamping, etc char mapcmd[MAX_TOKEN_CHARS]; // ie: *intro.cin+base int spawncount; // incremented each server start used to check late spawns client_t *clients; // [maxclients->value]; int num_client_entities; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES int next_client_entities; // next client_entity to use entity_state_t *client_entities; // [num_client_entities] int last_heartbeat; challenge_t challenges[MAX_CHALLENGES]; // to prevent invalid IPs from connecting /* serverrecord values */ FILE *demofile; sizebuf_t demo_multicast; uchar demo_multicast_buf[MAX_MSGLEN]; }; extern server_static_t svs; // persistant server info extern edict_t *sv_player; extern char sv_outputbuf[SV_OUTPUTBUF_LENGTH];